{"version":3,"file":"live-query-options.cjs","sources":["../../src/live-query-options.ts"],"sourcesContent":["import { BaseQueryBuilder } from './query/builder/index.js'\nimport { collectSourceRefs, requireCollectionSource } from './query/ir.js'\nimport { isCollection } from './live-query-adapter.js'\nimport { createLiveQueryCollection } from './query/live-query-collection.js'\nimport {\n  createPooledLiveQuery,\n  getPooledQueryIdentity,\n} from './query/pooled-live-query.js'\nimport {\n  getStableQueryBuilderHash,\n  getStableValueHash,\n} from './query/ir-stable-identity.js'\nimport { getStringCollationIdentity } from './query/runtime-reference-identity.js'\nimport { codedMessage, devBuild } from './error-message.js'\nimport type { Collection, CollectionImpl } from './collection/index.js'\nimport type { CollectionOptionsIdentity } from './collection-options.js'\nimport type { CollectionOptions, DbClient } from './client.js'\nimport type {\n  Context,\n  InitialQueryBuilder,\n  LiveQueryCollectionConfig,\n  QueryBuilder,\n} from './query/index.js'\n\nexport type LiveQueryKey = ReadonlyArray<unknown>\n\nexport type LiveQueryOptions = LiveQueryCollectionConfig<any> & {\n  queryKey?: LiveQueryKey\n}\n\nexport type DeferredLiveQueryCollections = Set<\n  CollectionImpl<any, string | number, any, any, any>\n>\n\n/** Release every deferred source, then report the first startup failure. */\nexport function resumeDeferredLiveQueryCollections(\n  collections: DeferredLiveQueryCollections,\n): void {\n  const pending = Array.from(collections)\n  collections.clear()\n  let firstFailure: { error: unknown } | undefined\n  for (const collection of pending) {\n    try {\n      collection._resumeSyncStart()\n    } catch (error) {\n      firstFailure ??= { error }\n    }\n  }\n  if (firstFailure) throw firstFailure.error\n}\n\ntype PreparedLiveQueryConfigInput = Omit<\n  LiveQueryCollectionConfig<Context>,\n  `query`\n> & {\n  query:\n    | QueryBuilder<Context>\n    | ((q: InitialQueryBuilder) => QueryBuilder<Context> | undefined | null)\n  queryKey?: LiveQueryKey\n  client?: DbClient\n}\n\nfunction createInitialQueryBuilder(): InitialQueryBuilder {\n  // Query construction does not materialize descriptor Collections.\n  return new BaseQueryBuilder() as InitialQueryBuilder\n}\n\nfunction createCollectionResolver(\n  dbClient: DbClient | undefined,\n  deferredCollections?: DeferredLiveQueryCollections,\n) {\n  if (!dbClient) return undefined\n  return (\n    options: CollectionOptionsIdentity<any, string | number, any, any, any>,\n  ): CollectionImpl<any, string | number, any, any, any> => {\n    if (!deferredCollections) {\n      return dbClient.collection(\n        options as CollectionOptions<any, string | number, any, any>,\n      ) as CollectionImpl<any, string | number, any, any, any>\n    }\n    const collection = dbClient._materializeCollectionForRender(\n      options as CollectionOptions<any, string | number, any, any>,\n    ) as CollectionImpl<any, string | number, any, any, any>\n    if (collection._deferSyncStart()) deferredCollections.add(collection)\n    return collection\n  }\n}\n\nexport function prepareLiveQueryValue(\n  value: unknown,\n  dbClient: DbClient | undefined,\n  deferredCollections?: DeferredLiveQueryCollections,\n): unknown {\n  if (typeof value === `function`) {\n    return prepareLiveQueryValue(\n      value(createInitialQueryBuilder()),\n      dbClient,\n      deferredCollections,\n    )\n  }\n\n  if (value instanceof BaseQueryBuilder) {\n    return value._bindCollectionSources(\n      createCollectionResolver(dbClient, deferredCollections),\n    )\n  }\n\n  if (\n    value &&\n    typeof value === `object` &&\n    !isCollection(value) &&\n    !(value instanceof BaseQueryBuilder) &&\n    `query` in value\n  ) {\n    const {\n      query,\n      queryKey: _queryKey,\n      client: _client,\n      ...config\n    } = value as PreparedLiveQueryConfigInput\n\n    const preparedQuery = prepareLiveQueryValue(\n      query,\n      dbClient,\n      deferredCollections,\n    )\n\n    if (preparedQuery === undefined || preparedQuery === null) {\n      return preparedQuery\n    }\n\n    return {\n      ...config,\n      query: preparedQuery,\n    }\n  }\n\n  return value\n}\n\n/** Concrete source objects in query-position order for a prepared value. */\nexport function getPreparedLiveQuerySources(\n  value: unknown,\n  onUnboundDescriptor?: (alias: string) => never,\n): Array<Collection> {\n  if (isCollection(value)) return [value]\n  const query =\n    value instanceof BaseQueryBuilder\n      ? value\n      : value && typeof value === `object` && `query` in value\n        ? value.query\n        : value\n  if (query instanceof BaseQueryBuilder) {\n    return collectSourceRefs(query._getQuery()).map((source) =>\n      source.type === `descriptorRef`\n        ? onUnboundDescriptor\n          ? onUnboundDescriptor(source.alias)\n          : requireCollectionSource(source)\n        : source.collection,\n    )\n  }\n  return isCollection(query) ? [query] : []\n}\n\nexport function getPreparedLiveQueryIdentity(value: unknown): unknown {\n  if (isCollection(value)) return [`collection`, value.id]\n  if (value instanceof BaseQueryBuilder) {\n    // A pooled query's fields and literals identify its rows without\n    // canonicalizing its whole IR on every render.\n    const pooled = getPooledQueryIdentity(value)\n    return pooled === undefined\n      ? [`query`, getStableQueryBuilderHash(value)]\n      : [`pooled`, pooled]\n  }\n  if (value && typeof value === `object` && `query` in value) {\n    const config = value as LiveQueryCollectionConfig<any>\n    return [\n      `config`,\n      getPreparedLiveQueryIdentity(config.query),\n      [`getKey`, config.getKey],\n      [`schema`, config.schema],\n      [`singleResult`, config.singleResult === true],\n      [\n        `defaultStringCollation`,\n        getStringCollationIdentity(config.defaultStringCollation),\n      ],\n    ]\n  }\n  if (value === undefined || value === null) return [`disabled`]\n  return [`value`, value]\n}\n\nexport function getLiveQueryHash(\n  preparedValue: unknown,\n  queryKey?: LiveQueryKey,\n): string {\n  const identity = queryKey?.length\n    ? [`queryKey`, queryKey]\n    : isCollection(preparedValue)\n      ? [`collection`, preparedValue.id]\n      : [`derived`, getPreparedLiveQueryIdentity(preparedValue)]\n\n  return getStableValueHash(identity, `queryKey`)\n}\n\n/**\n * Resolve an adapter's query value to what its observer watches: `null` for a\n * disabled query, an existing Collection with sync started, or a live query.\n * A query builder whose shape a shared partition can serve gets a pooled view\n * instead of its own live-query Collection.\n */\n// A config that names only its query and lifetime describes the same live\n// query as its builder. Any other option shapes its Collection, so compiles.\nfunction poolConfig(\n  config: LiveQueryCollectionConfig<any>,\n  gcTime: number | undefined,\n): Collection<any, any, any> | undefined {\n  if (\n    !(config.query instanceof BaseQueryBuilder) ||\n    !Object.keys(config).every((key) => key === `query` || key === `gcTime`)\n  ) {\n    return undefined\n  }\n  return createPooledLiveQuery(config.query, {\n    gcTime: config.gcTime ?? gcTime,\n  })\n}\n\nexport function resolveLiveQueryValue(\n  value: unknown,\n  {\n    gcTime,\n    pool = true,\n    startSync = true,\n  }: { gcTime?: number; pool?: boolean; startSync?: boolean } = {},\n): Collection<any, any, any> | null {\n  if (value === undefined || value === null) return null\n  if (isCollection(value)) {\n    value.startSyncImmediate()\n    return value\n  }\n  if (value instanceof BaseQueryBuilder) {\n    return (\n      (pool ? createPooledLiveQuery(value, { gcTime }) : undefined) ??\n      createLiveQueryCollection({ query: value, startSync, gcTime })\n    )\n  }\n  if (typeof value === `object`) {\n    const config = value as LiveQueryCollectionConfig<any>\n    return (\n      (pool ? poolConfig(config, gcTime) : undefined) ??\n      createLiveQueryCollection({ startSync, gcTime, ...config })\n    )\n  }\n  throw new Error(\n    devBuild() && process.env.NODE_ENV !== `production`\n      ? `A live query must be a QueryBuilder, LiveQueryCollectionConfig, Collection, undefined, or null. Got: ${typeof value}`\n      : codedMessage(102, { type: typeof value }),\n  )\n}\n"],"names":["BaseQueryBuilder","isCollection","collectSourceRefs","requireCollectionSource","getPooledQueryIdentity","getStableQueryBuilderHash","getStringCollationIdentity","getStableValueHash","createPooledLiveQuery","createLiveQueryCollection","devBuild","codedMessage"],"mappings":"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"}