UNPKG

@tanstack/db

Version:

A reactive client store for building super fast apps on sync

1 lines • 90.1 kB
{"version":3,"file":"collection-config-builder.cjs","sources":["../../../../src/query/live/collection-config-builder.ts"],"sourcesContent":["import { D2, output } from '@tanstack/db-ivm'\nimport { compileCollectionQuery } from '../compiler/index.js'\nimport {\n  LoadSubsetOperationAbortedError,\n  MissingAliasInputsError,\n  SetWindowFindOneLimitError,\n  SetWindowReentrancyError,\n  SetWindowRequiresOrderByError,\n} from '../../errors.js'\nimport { withPublicationContext } from '../../scheduler.js'\nimport { createDeferred } from '../../deferred.js'\nimport { deepEquals } from '../../utils.js'\nimport { runAllCallbacks } from '../../utils/callbacks.js'\nimport { normalizeError } from '../../utils/error.js'\nimport { createSourceRecord } from '../../utils/source-record.js'\nimport { codedMessage, devBuild } from '../../error-message.js'\nimport { collectSourceRefs } from '../ir.js'\nimport { findProblems } from '../../collection/health-tree.js'\nimport { isFailedStatus } from '../../live-query-primitives.js'\nimport { reducePublicKeys } from './public-key-reduction.js'\nimport { CollectionSubscriber } from './collection-subscriber.js'\nimport { getCollectionBuilder } from './collection-registry.js'\nimport { LIVE_QUERY_INTERNAL } from './internal.js'\nimport { scheduleQueryGraphRun } from './graph-scheduler.js'\nimport { hasPendingJoinedWork as hasPendingJoinedSourceWork } from './subset-demand-controller.js'\nimport {\n  buildQueryFromConfig,\n  extractCollectionFromSource,\n  extractCollectionSources,\n  extractCollectionsFromQuery,\n  sourcePermitsInitialReadiness,\n} from './utils.js'\nimport type { LiveQueryInternalUtils } from './internal.js'\nimport type { IncludesRuntime } from './includes-runtime.js'\nimport type { BucketFacadeAdapter } from './bucket-facade-adapter.js'\nimport type { materializeCompilation } from './materialized-pipeline.js'\nimport type { WindowOptions } from '../compiler/index.js'\nimport type { SchedulerContextId } from '../../scheduler.js'\nimport type { CollectionSubscription } from '../../collection/subscription.js'\nimport type { RootStreamBuilder } from '@tanstack/db-ivm'\nimport type { OrderByOptimizationInfo } from '../compiler/order-by.js'\nimport type { Collection } from '../../collection/index.js'\nimport type { HealthSource } from '../../collection/health-tree.js'\nimport type {\n  CollectionConfigSingleRowOption,\n  CollectionDependent,\n  KeyedStream,\n  ResultStream,\n  StringCollationConfig,\n  SyncConfig,\n  UtilsRecord,\n} from '../../types.js'\nimport type { Context, GetResult } from '../builder/types.js'\nimport type { BasicExpression, QueryIR } from '../ir.js'\nimport type { LazyCollectionCallbacks } from '../compiler/joins.js'\nimport type { Deferred } from '../../deferred.js'\nimport type {\n  Changes,\n  FullSyncState,\n  LiveQueryCollectionConfig,\n  SyncState,\n} from './types.js'\nimport type { AllCollectionEvents } from '../../collection/events.js'\n\nexport type LiveQueryCollectionUtils = UtilsRecord & {\n  /** Most recent subset-load failure observed by this live query. */\n  readonly lastSubsetError: unknown | undefined\n  /**\n   * Sets the offset and limit of the query's window, its ordered view. A\n   * windowed query has an `orderBy`. A `findOne` keeps its compiled limit (1,\n   * or 0 for `.limit(0).findOne()`); an ordered `findOne` has a movable window,\n   * and an unordered one is a fixed one-row result that accepts only its\n   * compiled limit at offset 0.\n   *\n   * @throws `SetWindowRequiresOrderByError` if the query is neither windowed\n   * nor a `findOne`, or an unordered `findOne` would move its offset.\n   * @throws `SetWindowFindOneLimitError` if a `findOne` would change its limit.\n   * @returns `true` if no subset loading was triggered, or `Promise<void>` that resolves when the subset has been loaded\n   */\n  setWindow: (options: WindowOptions) => true | Promise<void>\n  /**\n   * Gets the current window (offset and limit) for an ordered query.\n   *\n   * @returns The current window settings, or `undefined` if the query is not windowed\n   */\n  getWindow: () => { offset: number; limit: number } | undefined\n  [LIVE_QUERY_INTERNAL]: LiveQueryInternalUtils\n}\n\n// Global counter for auto-generated collection IDs\nlet liveQueryCollectionCounter = 0\n\ntype SyncMethods<TResult extends object> = Parameters<\n  SyncConfig<TResult>[`sync`]\n>[0]\n\nexport class CollectionConfigBuilder<\n  TContext extends Context,\n  TResult extends object = GetResult<TContext>,\n> {\n  private readonly id: string\n  readonly query: QueryIR\n  private readonly collections: Record<string, Collection<any, any, any>>\n  private readonly collectionSources: ReturnType<\n    typeof extractCollectionSources\n  >\n\n  // WeakMap to store the keys of the results\n  // so that we can retrieve them in the getKey function\n  private readonly resultKeys = new WeakMap<object, unknown>()\n\n  // WeakMap to store the orderBy index for each result\n  private readonly orderByIndices = new WeakMap<object, string>()\n\n  private readonly compare?: (val1: TResult, val2: TResult) => number\n  private readonly compareOptions: StringCollationConfig\n  readonly queryCompareOptions: StringCollationConfig\n\n  private isGraphRunning = false\n  private graphInputRevision = 0\n\n  // Current sync run state (set when sync starts, cleared when it stops)\n  // Public for testing purposes (CollectionConfigBuilder is internal, not public API)\n  public currentSyncConfig:\n    Parameters<SyncConfig<TResult>[`sync`]>[0] | undefined\n  public currentSyncState: FullSyncState | undefined\n\n  // Error state tracking\n  private fatalQueryError = false\n  private lastSubsetError: unknown | undefined\n  // The query's own reload: its new run publishes nothing until its graph\n  // result is complete (law 9), then commits that result as the snapshot\n  // that replaces the kept rows and completes the reload.\n  private reloadSnapshotPending = false\n\n  // Reference to the live query collection for error state transitions\n  public liveQueryCollection?: Collection<TResult, any, any>\n  private dependentEntry: CollectionDependent | undefined\n\n  /**\n   * Reload each source with an error anywhere in its tree, then this query if\n   * its own node shows an error. A nested live query passes the reload down the\n   * same way. A source's reload keeps this query's status until it commits.\n   * A query that is not running starts once its sources reloaded, as any\n   * Collection's reload starts one; `query` is the live-query Collection,\n   * which a query that never started has not given this builder yet.\n   */\n  async reload(\n    query: Collection<any, any, any> | undefined = this.liveQueryCollection,\n  ): Promise<void> {\n    // A crashed query rejects without touching its sources.\n    if (query?.status === `crashed`) return query._sync.reload()\n    const failed = this.collectionSources\n      .map(({ collection }) => collection)\n      .filter(\n        (collection, index, all) =>\n          all.indexOf(collection) === index &&\n          findProblems(collection.health).some((node) => node.error !== null),\n      )\n    // Only a query that was not running starts: a cleanup that ends it during\n    // the reload cancels the reload, as the app ended it.\n    const ended = query?.status === `idle` || query?.status === `cleaned-up`\n    await Promise.all(failed.map((collection) => collection.reload()))\n    // Its preload is what lets a live query start its sources.\n    if (ended) return query.preload()\n    // The query reloads itself after its sources when its own node shows an\n    // error (a failed first load or a request error); a reload of it already\n    // in flight settles with that run.\n    if (query?._lifecycle.problems.error || query?._lifecycle.reloading)\n      await query._sync.reload()\n  }\n\n  /** This live query as its sources' `subscribers` list it. */\n  dependent(): CollectionDependent | undefined {\n    const collection = this.liveQueryCollection\n    if (!collection) return undefined\n    return (this.dependentEntry ??= {\n      kind: `live-query`,\n      collection,\n      get active() {\n        return collection.subscribers.length > 0\n      },\n      end: () => collection.cleanup({ dependents: true }),\n    })\n  }\n\n  /**\n   * Whether this live-query Collection had a subscriber or a preload in its\n   * current sync run. Until then it reads its source Collections without\n   * starting provider work.\n   */\n  hasSubscriberOrPreload(): boolean {\n    // A builder driven without its Collection, as its own tests do, has no\n    // subscriber state to defer on.\n    return this.liveQueryCollection?._hasSubscriberOrPreload() ?? true\n  }\n\n  private windowFn: ((options: WindowOptions) => void) | undefined\n  private readonly initialWindow: WindowOptions | undefined\n  private currentWindow: WindowOptions | undefined\n  private settledWindow: WindowOptions | undefined\n  private activeWindowOperation:\n    { generation: number; failed: boolean; error?: unknown } | undefined\n\n  private maybeRunGraphFn: (() => void) | undefined\n  private loadMoreFn: (() => void) | undefined\n  private readonly builderDependencies = new Set<\n    CollectionConfigBuilder<any, any>\n  >()\n\n  private graphCache: D2 | undefined\n  private inputsCache: Record<string, RootStreamBuilder<unknown>> | undefined\n  private pipelineCache: ResultStream | undefined\n  public sourceWhereClausesCache:\n    Map<string, BasicExpression<boolean>> | undefined\n  private includesRuntimeCache: IncludesRuntime | undefined\n  private bucketFacadesCache:\n    ReturnType<typeof materializeCompilation>[`facades`] | undefined\n  private readonly includeSourceIds = new Set<string>()\n\n  // Map of opaque source ID to subscription\n  readonly subscriptions = createSourceRecord<CollectionSubscription>()\n  // Map of opaque source ID to demand callbacks for that lazy source\n  lazySourcesCallbacks = createSourceRecord<LazyCollectionCallbacks>()\n  // Set of opaque source IDs that are lazy (don't load initial state)\n  readonly lazySources = new Set<string>()\n  private readonly activeDemands = new Map<\n    string,\n    {\n      generation: number\n      settled: boolean\n      participant?: Deferred<void>\n    }\n  >()\n  private demandGeneration = 0\n  private readonly pendingOrderedLoads = new Set<Promise<unknown>>()\n  private orderedLoadFailed = false\n  // Source replay cannot settle a failed imperative window operation.\n  private windowFailed = false\n  private syncRunGeneration = 0\n  private windowOperationGeneration = 0\n  // Counts setWindow calls, deferred or not. A separate count from window\n  // operations, so a deferred call does not drop the settlement of a move\n  // that already applied.\n  private windowRequestGeneration = 0\n  // The newest call's settlement. An older call that a newer one superseded\n  // resolves only once it settles, so an awaited call reflects the window\n  // that won. A superseded call that fails still rejects with its own error.\n  private latestWindowRequest: Promise<void> | undefined\n  // Map of lexical source IDs to optimizable ORDER BY state\n  optimizableOrderByCollections = createSourceRecord<OrderByOptimizationInfo>()\n\n  constructor(\n    private readonly config: LiveQueryCollectionConfig<TContext, TResult>,\n  ) {\n    // Generate a unique ID if not provided\n    this.id = config.id || `live-query-${++liveQueryCollectionCounter}`\n\n    this.query = buildQueryFromConfig({\n      query: config.query,\n      requireObjectResult: true,\n    })\n    this.initialWindow =\n      this.query.orderBy?.length || this.query.singleResult\n        ? {\n            offset: this.query.offset ?? 0,\n            limit: this.query.singleResult\n              ? Math.min(this.query.limit ?? 1, 1)\n              : (this.query.limit ?? Infinity),\n          }\n        : undefined\n    this.settledWindow = this.initialWindow\n    this.collections = extractCollectionsFromQuery(this.query)\n    this.collectionSources = extractCollectionSources(this.query)\n    collectSourceRefs(this.query, this.includeSourceIds)\n\n    // Create compare function for ordering if the query has orderBy\n    if (this.query.orderBy && this.query.orderBy.length > 0) {\n      this.compare = createOrderByComparator<TResult>(this.orderByIndices)\n    }\n\n    // Query ordering inherits from the leading source. The live-query Collection\n    // may independently override the collation it exposes to downstream queries.\n    this.queryCompareOptions = extractCollectionFromSource(\n      this.query,\n    ).compareOptions\n    this.compareOptions =\n      this.config.defaultStringCollation ?? this.queryCompareOptions\n\n    // Compile the base pipeline once initially\n    // This is done to ensure that any errors are thrown immediately and synchronously\n    this.compileBasePipeline()\n  }\n\n  /** Direct lexical source Collections, including joins, unions, and includes. */\n  getSourceCollections(): ReadonlyArray<Collection<any, any, any>> {\n    return this.collectionSources.map(({ collection }) => collection)\n  }\n\n  /**\n   * Recursively checks if a query or any of its subqueries contains joins\n   */\n  private hasJoins(query: QueryIR): boolean {\n    // Check if this query has joins\n    if (query.join && query.join.length > 0) {\n      return true\n    }\n\n    // Recursively check subqueries in the from clause\n    if (query.from.type === `queryRef`) {\n      if (this.hasJoins(query.from.query)) {\n        return true\n      }\n    } else if (query.from.type === `unionFrom`) {\n      for (const source of query.from.sources) {\n        if (source.type === `queryRef` && this.hasJoins(source.query)) {\n          return true\n        }\n      }\n    } else if (query.from.type === `unionAll`) {\n      for (const branch of query.from.queries) {\n        if (this.hasJoins(branch)) {\n          return true\n        }\n      }\n    }\n\n    return false\n  }\n\n  getConfig(): CollectionConfigSingleRowOption<TResult> & {\n    utils: LiveQueryCollectionUtils\n  } {\n    const builder = this\n    return {\n      id: this.id,\n      getKey:\n        this.config.getKey ||\n        ((item: any) =>\n          (this.resultKeys.get(item) ?? item.$key) as string | number),\n      sync: this.getSyncConfig(),\n      compare: this.compare,\n      defaultStringCollation: this.compareOptions,\n      gcTime: this.config.gcTime ?? 5000, // 5 seconds by default for live queries\n      schema: this.config.schema,\n      onInsert: this.config.onInsert,\n      onUpdate: this.config.onUpdate,\n      onDelete: this.config.onDelete,\n      startSync: this.config.startSync,\n      singleResult: this.query.singleResult,\n      utils: {\n        get lastSubsetError() {\n          return builder.lastSubsetError\n        },\n        setWindow: this.setWindow.bind(this),\n        getWindow: this.getWindow.bind(this),\n        [LIVE_QUERY_INTERNAL]: {\n          getBuilder: () => this,\n          hasCustomGetKey: !!this.config.getKey,\n          hasJoins: this.hasJoins(this.query),\n          hasDistinct: !!this.query.distinct,\n        },\n      },\n    }\n  }\n\n  setWindow(options: WindowOptions): true | Promise<void> {\n    const windowFn = this.windowFn\n    if (!windowFn) {\n      throw new SetWindowRequiresOrderByError()\n    }\n    // A findOne keeps its compiled limit, and only an ordered one moves.\n    if (this.query.singleResult) {\n      if (!this.query.orderBy?.length && (options.offset ?? 0) !== 0)\n        throw new SetWindowRequiresOrderByError()\n      if (\n        (options.limit ?? this.initialWindow!.limit) !==\n        this.initialWindow!.limit\n      )\n        throw new SetWindowFindOneLimitError()\n    }\n    if (\n      this.activeWindowOperation ||\n      this.isGraphRunning ||\n      Object.values(this.optimizableOrderByCollections).some((info) =>\n        info.isRequesting?.(),\n      )\n    ) {\n      throw new SetWindowReentrancyError()\n    }\n\n    // Keep caller-owned objects out of the long-lived query state. A caller may\n    // reuse and mutate its options object after this operation settles.\n    const baseWindow =\n      this.currentWindow ?? this.settledWindow ?? this.initialWindow\n    const requestedWindow: WindowOptions = {\n      offset: options.offset ?? baseWindow?.offset,\n      limit: options.limit ?? baseWindow?.limit,\n    }\n    const request = ++this.windowRequestGeneration\n    const sourceRecovery = this.pendingSourceRecovery()\n    if (sourceRecovery) {\n      const syncRuns = this.syncRuns()\n      const resume = async (): Promise<void> => {\n        // Wait for every replay that holds publication, including one a\n        // newer truncate starts meanwhile. A replay that a newer truncate or\n        // a retired demand discards rejects its completion with an\n        // AbortError, but it did not fail. Cleanup and a reload end the sync\n        // run the move waits in, and the move rejects with that error.\n        for (\n          let recovery: Promise<void> | undefined = sourceRecovery;\n          recovery;\n          recovery = this.pendingSourceRecovery()\n        ) {\n          try {\n            await recovery\n          } catch (error) {\n            if (\n              !(error instanceof LoadSubsetOperationAbortedError) ||\n              syncRuns !== this.syncRuns()\n            )\n              throw error\n          }\n        }\n        // A newer call wins, even if this deferred one resumes after it.\n        if (request !== this.windowRequestGeneration) {\n          await this.latestWindowRequest\n          return\n        }\n        // A failed replay rejects the call. Otherwise it applies the window.\n        const settlement = this.setWindow(requestedWindow)\n        // The resumed call settles on behalf of this one.\n        this.latestWindowRequest = deferred\n        if (settlement !== true) await settlement\n      }\n      const deferred = resume()\n      return (this.latestWindowRequest = deferred)\n    }\n    if (this.hasFailedSourceRecovery()) {\n      return (this.latestWindowRequest = Promise.reject(\n        this.lastSubsetError ??\n          new Error(\n            devBuild() && process.env.NODE_ENV !== `production`\n              ? `Source recovery failed`\n              : codedMessage(147),\n          ),\n      ))\n    }\n    const windowOperationGeneration = ++this.windowOperationGeneration\n    const loadOperation =\n      this.liveQueryCollection?._sync.beginLoadSubsetOperation()\n    for (const info of Object.values(this.optimizableOrderByCollections)) {\n      if (!info.joinedFilterSourceId) continue\n      for (const plan of this.lazySourcesCallbacks[info.joinedFilterSourceId]\n        ?.plans ?? []) {\n        const participant = this.activeDemands.get(plan.id)?.participant\n        if (participant?.isPending()) {\n          this.trackSubsetLoadOperationPromise(participant.promise)\n        }\n      }\n    }\n    const previousOperation = this.activeWindowOperation\n    const operation: {\n      generation: number\n      failed: boolean\n      error?: unknown\n    } = { generation: windowOperationGeneration, failed: false }\n    this.activeWindowOperation = operation\n    this.windowFailed = false\n    if (this.pendingOrderedLoads.size === 0) this.orderedLoadFailed = false\n    try {\n      // The window and all source work it causes form one synchronous\n      // publication. This makes operation tracking see requests scheduled by\n      // the graph rather than declaring the window settled too early.\n      this.currentWindow = requestedWindow\n      withPublicationContext(() => {\n        windowFn(requestedWindow)\n        this.maybeRunGraphFn?.()\n      })\n      if (operation.failed) throw operation.error\n    } catch (error) {\n      if (windowOperationGeneration === this.windowOperationGeneration) {\n        this.windowFailed = true\n        this.currentWindow = this.settledWindow\n      }\n      loadOperation?.cancel()\n      throw error\n    } finally {\n      this.activeWindowOperation = previousOperation\n    }\n\n    const settlement = loadOperation?.wait() ?? true\n    if (settlement === true) {\n      this.settledWindow = requestedWindow\n      this.latestWindowRequest = undefined\n      return true\n    }\n    return (this.latestWindowRequest = settlement.then(\n      () => {\n        if (windowOperationGeneration === this.windowOperationGeneration) {\n          this.settledWindow = requestedWindow\n        }\n        return request === this.windowRequestGeneration\n          ? undefined\n          : this.latestWindowRequest\n      },\n      (error) => {\n        if (windowOperationGeneration === this.windowOperationGeneration) {\n          this.windowFailed = true\n          this.currentWindow = this.settledWindow\n        }\n        throw error\n      },\n    ))\n  }\n\n  getWindow(): { offset: number; limit: number } | undefined {\n    // A windowed query or an ordered findOne returns its window. An unordered\n    // findOne returns its fixed result: offset 0 and its compiled limit.\n    const window = this.settledWindow ?? this.initialWindow\n    if (!this.windowFn || !window) {\n      return undefined\n    }\n    return {\n      offset: window.offset ?? 0,\n      limit: window.limit ?? 0,\n    }\n  }\n\n  isLazySource(sourceId: string): boolean {\n    return this.lazySources.has(sourceId)\n  }\n\n  beginDemand(planId: string, pending = false): number {\n    const generation = ++this.demandGeneration\n    const previous = this.activeDemands.get(planId)\n    const participant = pending ? createDeferred<void>() : undefined\n    if (participant) {\n      void participant.promise.catch(() => {})\n      this.trackSubsetLoadOperationPromise(participant.promise)\n    }\n    this.activeDemands.set(planId, {\n      generation,\n      settled: false,\n      participant,\n    })\n    previous?.participant?.resolve()\n    return generation\n  }\n\n  /** The source aliases of this query, in query order, for its health tree. */\n  healthSources(): ReadonlyArray<HealthSource> {\n    return this.collectionSources.map(({ sourceId, alias, collection }) => ({\n      id: sourceId,\n      alias,\n      collection,\n      ...(this.includeSourceIds.has(sourceId)\n        ? { kind: `include` as const }\n        : {}),\n    }))\n  }\n\n  settleDemand(planId: string, generation: number): void {\n    const demand = this.activeDemands.get(planId)\n    if (!demand || demand.generation !== generation || demand.settled) return\n    demand.settled = true\n    try {\n      this.maybeRunGraphFn?.()\n      demand.participant?.resolve()\n    } catch (error) {\n      demand.participant?.reject(error)\n      throw error\n    }\n  }\n\n  hasPendingJoinedWork(joinedSourceId: string): boolean {\n    return hasPendingJoinedSourceWork(\n      joinedSourceId,\n      this.lazySourcesCallbacks,\n      this.subscriptions,\n      (planId) => this.activeDemands.get(planId)?.settled === false,\n    )\n  }\n\n  failDemand(\n    subscription: CollectionSubscription,\n    collection: Collection,\n    planId: string,\n    generation: number,\n    error: unknown,\n  ): void {\n    const demand = this.activeDemands.get(planId)\n    if (!demand || demand.generation !== generation) return\n    const normalized = this.recordSubsetError(error)\n    demand.participant?.reject(normalized)\n    if (this.liveQueryCollection?._lifecycle.status === `ready`) {\n      // The failure settles the demand: the request errors of its keys show\n      // it, and ordered work must not wait for a load that already ended.\n      // Output held for this demand publishes now, unless a failed replay of\n      // this source holds publication: the failure then holds this\n      // subscription's publication too, so retiring the other replay's\n      // failed demand cannot publish without this demand's rows.\n      demand.settled = true\n      if (\n        this.collectionSources.some(\n          (source) =>\n            source.collection === collection &&\n            this.subscriptions[source.sourceId]?.hasFailedTruncateReplacement,\n        )\n      )\n        subscription.failReplacement(normalized)\n      this.maybeRunGraphFn?.()\n      return\n    }\n    this.failQuery(\n      devBuild() && process.env.NODE_ENV !== `production`\n        ? `Subset demand '${planId}' failed: ${normalized.message}`\n        : codedMessage(228, { planId, cause: normalized.message }),\n      normalized,\n    )\n  }\n\n  recordSubsetError(error: unknown, fatalBeforeReady = false): Error {\n    const normalized = normalizeError(error)\n    this.lastSubsetError = normalized\n    if (this.activeWindowOperation) {\n      this.activeWindowOperation.failed = true\n      this.activeWindowOperation.error = normalized\n      // A synchronous adapter failure can arrive before it returns a promise\n      // for the ordered-load tracker. Keep any private graph changes hidden.\n      this.orderedLoadFailed = true\n    }\n    if (fatalBeforeReady) {\n      this.failQuery(\n        devBuild() && process.env.NODE_ENV !== `production`\n          ? `Initial subset load failed: ${normalized.message}`\n          : codedMessage(229, { cause: normalized.message }),\n        normalized,\n      )\n    }\n    return normalized\n  }\n\n  trackSubsetLoadPromise(promise: Promise<unknown>): void {\n    this.liveQueryCollection!._sync.trackLoadPromise(promise)\n  }\n\n  trackSubsetLoadOperationPromise(promise: Promise<unknown>): void {\n    this.liveQueryCollection!._sync.trackLoadSubsetOperationPromise(promise)\n  }\n\n  hasActiveWindowOperation(): boolean {\n    return this.activeWindowOperation !== undefined\n  }\n\n  getActiveWindowOperationGeneration(): number | undefined {\n    return this.activeWindowOperation?.generation\n  }\n\n  scheduleGraphRunIfSyncRunCurrent(syncRunGeneration: number): void {\n    if (\n      syncRunGeneration !== this.syncRunGeneration ||\n      !this.currentSyncConfig ||\n      !this.currentSyncState\n    ) {\n      return\n    }\n    this.scheduleGraphRun()\n  }\n\n  trackOrderedLoadPromise(\n    promise: Promise<unknown>,\n    holdPublication = false,\n  ): void {\n    // Hold the last complete public snapshot during an initial load or an\n    // imperative window move. Source changes that arrive during the move join\n    // its private graph state and publish with the completed replacement.\n    if (\n      !holdPublication &&\n      !this.activeWindowOperation &&\n      this.liveQueryCollection?._lifecycle.inFirstLoad !== true &&\n      this.pendingOrderedLoads.size === 0\n    ) {\n      return\n    }\n    const syncRunGeneration = this.syncRunGeneration\n    if (this.pendingOrderedLoads.size === 0) this.orderedLoadFailed = false\n    this.pendingOrderedLoads.add(promise)\n    const finish = (succeeded: boolean) => {\n      // Admission precedes mutation: cleanup retires this sync run's participants.\n      if (\n        syncRunGeneration !== this.syncRunGeneration ||\n        !this.pendingOrderedLoads.delete(promise)\n      ) {\n        return\n      }\n      if (!succeeded) this.orderedLoadFailed = true\n      if (!this.orderedLoadFailed && this.pendingOrderedLoads.size === 0) {\n        // The ordered chain already drove its source graph to quiescence.\n        // Flush the retained result without invoking the source loaders again.\n        this.scheduleGraphRun()\n      }\n    }\n    void promise.then(\n      () => finish(true),\n      () => finish(false),\n    )\n  }\n\n  retireDemand(planId: string): void {\n    const demand = this.activeDemands.get(planId)\n    this.activeDemands.delete(planId)\n    demand?.participant?.resolve()\n  }\n\n  /** A root load of an eager source failed. */\n  failRootLoad(sourceId: string, error: Error): void {\n    this.reportFailedRequest(`root:${sourceId}`, [error])\n  }\n\n  /** A later root load of the source succeeded. */\n  settleRootLoad(sourceId: string): void {\n    this.clearFailedRequest(`root:${sourceId}`)\n  }\n\n  /** A source's truncate replay loaded the query's demand again. */\n  settleReplayedRequests(sourceId: string): void {\n    this.settleRootLoad(sourceId)\n    this.clearFailedRequest(`replay:${sourceId}`)\n  }\n\n  /**\n   * A source's truncate replay could not load the query's data again: each\n   * of its failures, in failure order. Before the first ready the earliest\n   * fails the query.\n   */\n  failReplay(sourceId: string, errors: Array<Error>): void {\n    if (this.reportFailedRequest(`replay:${sourceId}`, errors)) return\n    this.failQuery(errors[0]!.message, errors[0])\n  }\n\n  // After the first ready, a failed load is a request error on this query's\n  // node. It clears when the failed request settles later or is released.\n  reportFailedRequest(key: string, errors: Array<Error>): boolean {\n    const lifecycle = this.liveQueryCollection?._lifecycle\n    if (lifecycle?.status !== `ready`) return false\n    lifecycle.reportRequestError(key, errors)\n    return true\n  }\n\n  /** A request settled later, or the query no longer needs its data. */\n  clearFailedRequest(key: string): void {\n    this.liveQueryCollection?._lifecycle.clearRequestError(key)\n  }\n\n  /** This query's sync run and its sources' sync runs. */\n  private syncRuns(): string {\n    return [\n      this.syncRunGeneration,\n      ...this.collectionSources.map(({ collection }) =>\n        collection._sync.getSyncRunGeneration(),\n      ),\n    ].join()\n  }\n\n  /** Replays of other subscriptions to a source's collection that still load. */\n  siblingReplays(\n    collection: Collection,\n    sourceId: string,\n  ): Promise<unknown> | undefined {\n    const pending = this.collectionSources.flatMap((source) => {\n      const subscription = this.subscriptions[source.sourceId]\n      // A replay whose completion already settled cannot be waited on.\n      return source.sourceId !== sourceId &&\n        source.collection === collection &&\n        subscription?.hasTruncateReplayWork &&\n        subscription.pendingTruncateReplacement\n        ? [subscription.pendingTruncateReplacement]\n        : []\n    })\n    return pending.length > 0 ? Promise.allSettled(pending) : undefined\n  }\n\n  hasPendingSourceRecovery(): boolean {\n    return Object.values(this.subscriptions).some(\n      (subscription) => subscription.hasPendingTruncateReplacement,\n    )\n  }\n\n  private pendingSourceRecovery(): Promise<void> | undefined {\n    const pending = Object.values(this.subscriptions).flatMap((subscription) =>\n      subscription.pendingTruncateReplacement\n        ? [subscription.pendingTruncateReplacement]\n        : [],\n    )\n    return pending.length > 0\n      ? Promise.all(pending).then(() => undefined)\n      : undefined\n  }\n\n  private hasFailedSourceRecovery(): boolean {\n    return Object.values(this.subscriptions).some(\n      (subscription) => subscription.hasFailedTruncateReplacement,\n    )\n  }\n\n  getSyncRunGeneration(): number {\n    return this.syncRunGeneration\n  }\n\n  advanceGraphInputRevision(): void {\n    this.graphInputRevision++\n  }\n\n  getGraphInputRevision(): number {\n    return this.graphInputRevision\n  }\n\n  // Every graph turn checks ordered demand after D2 reaches a checkpoint.\n  // The source loader owns the fixed-point latches that prevent repeat requests.\n  maybeRunGraph() {\n    if (this.isGraphRunning) {\n      // no nested runs of the graph\n      // which is possible if a loader synchronously sends more source rows\n      return\n    }\n\n    // Should only be called when sync is active\n    if (!this.currentSyncConfig || !this.currentSyncState) {\n      throw new Error(\n        devBuild() && process.env.NODE_ENV !== `production`\n          ? `maybeRunGraph called without active sync run. This should not happen.`\n          : codedMessage(148),\n      )\n    }\n\n    this.isGraphRunning = true\n\n    try {\n      const syncRunGeneration = this.syncRunGeneration\n      const config = this.currentSyncConfig\n      const { begin, commit } = config\n      const syncState = this.currentSyncState\n      const isCurrentSyncRun = () =>\n        syncRunGeneration === this.syncRunGeneration &&\n        this.currentSyncConfig === config &&\n        this.currentSyncState === syncState\n\n      // Don't run if the live query is in an error state\n      if (this.fatalQueryError) {\n        return\n      }\n\n      // Always run the graph if subscribed (eager execution)\n      if (syncState.subscribedToAllCollections) {\n        let checkedLoaders = false\n        while (syncState.graph.pendingWork() || !checkedLoaders) {\n          if (syncState.graph.pendingWork()) {\n            try {\n              syncState.graph.run()\n            } catch (error) {\n              // A first load that already failed in this run reported its\n              // error.\n              if (\n                isCurrentSyncRun() &&\n                this.liveQueryCollection?._lifecycle.stoppedThisRun !== true\n              ) {\n                this.crashQuery(\n                  devBuild() && process.env.NODE_ENV !== `production`\n                    ? `Live query graph failed`\n                    : codedMessage(212),\n                  error,\n                )\n              }\n              throw error\n            }\n            if (!isCurrentSyncRun()) return\n          }\n          // A synchronous loader can write while this graph run is active.\n          // Process that input before publishing, even if this turn began empty.\n          this.loadMoreFn?.()\n          if (!isCurrentSyncRun()) return\n          checkedLoaders = true\n        }\n\n        // Publish only after every operator has reached quiescence. A source\n        // change can reach sibling materializations in different graph steps;\n        // flushing between those steps would expose a mixed root snapshot.\n        syncState.flushPendingChanges?.()\n        if (!isCurrentSyncRun()) return\n\n        // On the initial run, we may need to do an empty commit to ensure that\n        // the collection is initialized. A reload's run commits its snapshot\n        // instead.\n        if (syncState.messagesCount === 0 && !this.reloadSnapshotPending) {\n          begin()\n          commit()\n        }\n\n        // After graph processing completes, check if we should mark ready.\n        // This is the canonical place to transition to ready state because:\n        // 1. All data has been processed through the graph\n        // 2. All source collections have had a chance to send their initial data\n        // This prevents marking ready before data is processed (fixes isReady=true with empty data)\n        this.updateLiveQueryStatus(config)\n      }\n    } finally {\n      this.isGraphRunning = false\n    }\n  }\n\n  /**\n   * Schedules a graph run with the transaction-scoped scheduler.\n   * Ensures each builder runs at most once per transaction, with automatic dependency tracking\n   * to run parent queries before child queries. Outside a transaction, runs immediately.\n   *\n   * Multiple calls during a transaction are coalesced into a single execution.\n   * Dependencies are discovered from subscribed live queries.\n   *\n   * Uses the current sync run's config and syncState from instance properties.\n   *\n   * @param options - Optional scheduling configuration\n   * @param options.contextId - Transaction ID to group work; defaults to active transaction\n   */\n  scheduleGraphRun(options?: { contextId?: SchedulerContextId }) {\n    if (!this.currentSyncConfig || !this.currentSyncState) {\n      throw new Error(\n        devBuild() && process.env.NODE_ENV !== `production`\n          ? `scheduleGraphRun called without active sync run. This should not happen.`\n          : codedMessage(149),\n      )\n    }\n\n    const syncRunGeneration = this.syncRunGeneration\n    scheduleQueryGraphRun(\n      this,\n      this.builderDependencies,\n      () => {\n        if (\n          syncRunGeneration === this.syncRunGeneration &&\n          this.currentSyncConfig &&\n          this.currentSyncState\n        ) {\n          this.maybeRunGraph()\n        }\n      },\n      options?.contextId,\n    )\n  }\n\n  private getSyncConfig(): SyncConfig<TResult> {\n    return {\n      rowUpdateMode: `full`,\n      sync: this.syncFn.bind(this),\n    }\n  }\n\n  private syncFn(config: SyncMethods<TResult>) {\n    const syncRunGeneration = ++this.syncRunGeneration\n    // Store reference to the live query collection for error state transitions\n    this.liveQueryCollection = config.collection\n    this.reloadSnapshotPending = config.collection._lifecycle.reloading\n    // Reset error state from any previous sync run so a restarted sync can become ready again.\n    this.fatalQueryError = false\n    this.lastSubsetError = undefined\n    // Store config and syncState as instance properties for the duration of this sync run\n    this.currentSyncConfig = config\n\n    const syncState: SyncState = {\n      messagesCount: 0,\n      subscribedToAllCollections: false,\n      unsubscribeCallbacks: new Set<() => void>(),\n    }\n\n    let tornDown = false\n    const teardown = () => {\n      if (tornDown) return\n      tornDown = true\n      if (this.syncRunGeneration === syncRunGeneration) {\n        this.syncRunGeneration++\n      }\n\n      // Release every source in one attempt; the first failure wins after the\n      // peers finish. Each subscription release is itself one-shot, so the\n      // Collection's cleanup retry has nothing left to repeat here.\n      try {\n        runAllCallbacks(syncState.unsubscribeCallbacks)\n      } finally {\n        syncState.unsubscribeCallbacks.clear()\n        this.clearSyncRunState()\n      }\n    }\n\n    try {\n      // Extend the pipeline such that it applies the incoming changes to the collection\n      const fullSyncState = this.extendPipelineWithChangeProcessing(\n        config,\n        syncState,\n      )\n      this.currentSyncState = fullSyncState\n\n      // Listen for loadingSubset changes on the live query collection BEFORE subscribing.\n      // This ensures we don't miss the event if subset loading completes synchronously.\n      // When isLoadingSubset becomes false, we may need to mark the collection as ready\n      // (if all source collections are already ready but we were waiting for subset load to complete)\n      const loadingSubsetUnsubscribe = config.collection.on(\n        `loadingSubset:change`,\n        (event) => {\n          if (!event.isLoadingSubset) {\n            // Subset loading finished, check if we can now mark ready\n            this.updateLiveQueryStatus(config)\n            if (this.hasPendingSourceRecovery()) this.maybeRunGraphFn?.()\n          }\n        },\n      )\n      syncState.unsubscribeCallbacks.add(loadingSubsetUnsubscribe)\n\n      this.loadMoreFn = this.subscribeToAllCollections(config, fullSyncState)\n\n      this.maybeRunGraphFn = () => this.scheduleGraphRun()\n\n      this.scheduleGraphRun()\n    } catch (error) {\n      try {\n        teardown()\n      } catch {\n        // Preserve the setup failure. It is the error the caller can act on.\n      }\n      throw error\n    }\n\n    return teardown\n  }\n\n  private clearSyncRunState(): void {\n    // Late window settlement belongs to the discarded graph, not its restart.\n    this.windowOperationGeneration++\n    // Clear current sync run state\n    this.currentSyncConfig = undefined\n    this.currentSyncState = undefined\n    this.maybeRunGraphFn = undefined\n    this.loadMoreFn = undefined\n    // The query's own reload retries its data, not the window the app chose:\n    // the new run starts from the settled window, and a pending move ends\n    // with the retired run. Cleanup discards the window, also during the\n    // reload: it tears the run down before it ends the reload.\n    const lifecycle = this.liveQueryCollection?._lifecycle\n    if (lifecycle?.reloading && !lifecycle.hasStartedCleanup())\n      this.currentWindow = this.settledWindow\n    else {\n      this.currentWindow = undefined\n      this.settledWindow = this.initialWindow\n    }\n    this.fatalQueryError = false\n    this.reloadSnapshotPending = false\n\n    // Reset caches so a fresh graph/pipeline is compiled on next start\n    // This avoids reusing a finalized D2 graph across GC restarts\n    this.graphCache = undefined\n    this.inputsCache = undefined\n    this.pipelineCache = undefined\n    this.sourceWhereClausesCache = undefined\n    this.bucketFacadesCache = undefined\n    this.includesRuntimeCache = undefined\n\n    // Reset lazy source alias state\n    this.lazySources.clear()\n    for (const demand of this.activeDemands.values()) {\n      demand.participant?.reject(new LoadSubsetOperationAbortedError())\n    }\n    this.activeDemands.clear()\n    this.pendingOrderedLoads.clear()\n    this.orderedLoadFailed = false\n    this.windowFailed = false\n    this.optimizableOrderByCollections = createSourceRecord()\n    this.lazySourcesCallbacks = createSourceRecord()\n\n    // Clear subscription references to prevent memory leaks\n    // Note: Individual subscriptions are already unsubscribed via unsubscribeCallbacks\n    Object.keys(this.subscriptions).forEach(\n      (key) => delete this.subscriptions[key],\n    )\n  }\n\n  /**\n   * Compiles the query pipeline with all declared aliases.\n   */\n  private compileBasePipeline() {\n    this.graphCache = new D2()\n    const inputs = createSourceRecord<RootStreamBuilder<unknown>>()\n    for (const source of this.collectionSources) {\n      inputs[source.sourceId] = this.graphCache.newInput<any>()\n    }\n    this.inputsCache = inputs\n\n    const compilation = compileCollectionQuery(\n      this.query,\n      this.inputsCache as Record<string, KeyedStream>,\n      this.collections,\n      this.subscriptions,\n      this.lazySourcesCallbacks,\n      this.lazySources,\n      this.optimizableOrderByCollections,\n      (windowFn: (options: WindowOptions) => void) => {\n        this.windowFn = windowFn\n        // `setWindow` mutates the compiled top-K operator, which is replaced\n        // whenever a cleaned-up live query compiles a fresh pipeline. Keep the\n        // desired window on the builder and replay it into each new operator.\n        if (this.currentWindow) {\n          windowFn(this.currentWindow)\n        }\n      },\n    )\n\n    // Includes bring the materializer. A joined query with a custom key\n    // reduces its public keys without it.\n    const includesRuntime = compilation.includes?.[0]?.runtime\n    const getKey = this.config.getKey\n    const materialized = includesRuntime\n      ? includesRuntime.materializeCompilation(compilation, getKey)\n      : getKey && this.hasJoins(this.query)\n        ? reducePublicKeys(compilation, getKey)\n        : { pipeline: compilation.pipeline, facades: undefined }\n    this.pipelineCache = materialized.pipeline\n    this.sourceWhereClausesCache = compilation.sourceWhereClauses\n    this.bucketFacadesCache = materialized.facades\n    this.includesRuntimeCache = includesRuntime\n\n    const missingSources = this.collectionSources\n      .map((source) => source.sourceId)\n      .filter((sourceId) => !Object.hasOwn(this.inputsCache!, sourceId))\n    if (missingSources.length > 0) {\n      throw new MissingAliasInputsError(missingSources)\n    }\n  }\n\n  private maybeCompileBasePipeline() {\n    if (!this.graphCache || !this.inputsCache || !this.pipelineCache) {\n      this.compileBasePipeline()\n    }\n    return {\n      graph: this.graphCache!,\n      inputs: this.inputsCache!,\n      pipeline: this.pipelineCache!,\n    }\n  }\n\n  private extendPipelineWithChangeProcessing(\n    config: SyncMethods<TResult>,\n    syncState: SyncState,\n  ): FullSyncState {\n    const { begin, commit } = config\n    const { graph, inputs, pipeline } = this.maybeCompileBasePipeline()\n\n    // Accumulator for changes across all output callbacks within a single graph run.\n    // This allows us to batch all changes from intermediate join states into a single\n    // transaction, avoiding duplicate key errors when joins produce multiple outputs\n    // for the same key (e.g., first output with null, then output with joined data).\n    let pendingChanges: Map<unknown, Changes<TResult>> = new Map()\n\n    pipeline.pipe(\n      output((data) => {\n        const messages = data.getInner()\n        syncState.messagesCount += messages.length\n\n        // Accumulate changes from this output callback into the pending changes map.\n        // Changes for the same key are merged (inserts/deletes are added together).\n        messages.reduce(accumulateChanges<TResult>, pendingChanges)\n      }),\n    )\n\n    // A query without includes publishes its rows directly and pays for no\n    // facade state. With includes, the adapter also strips private route\n    // state at publication, even when every include is inline. A joined\n    // query with a custom key is materialized for key reduction only.\n    const facadeCompilations = this.bucketFacadesCache\n    const includesRuntime = this.includesRuntimeCache\n    const bucketFacades =\n      facadeCompilations && includesRuntime\n        ? includesRuntime.createBucketFacades(\n            this.id,\n            facadeCompilations,\n            (count) => {\n              syncState.messagesCount += count\n            },\n          )\n        : undefined\n    if (bucketFacades) {\n      syncState.unsubscribeCallbacks.add(() => bucketFacades.cleanup())\n    }\n\n    // Flush pending changes and reset the accumulator.\n    // Called at the end of each graph run to commit all accumulated changes.\n    syncState.flushPendingChanges = () => {\n      const hasParentChanges = pendingChanges.size > 0\n      const hasChildChanges = bucketFacades?.hasPendingChanges() ?? false\n      // A reload's run holds its result until it is complete, then commits\n      // it as a snapshot, also an empty one.\n      const snapshot = this.reloadSnapshotPending\n      if (snapshot && !this.isResultComplete()) return\n      const writesRoot = hasParentChanges || snapshot\n\n      if (!writesRoot && !hasChildChanges) {\n        return\n      }\n\n      if (\n        this.windowFailed ||\n        this.orderedLoadFailed ||\n        this.hasPendingSourceRecovery() ||\n        this.pendingOrderedLoads.size > 0 ||\n        Object.values(this.optimizableOrderByCollections).some(\n          (info) =>\n            info.joinedFilterSourceId !== undefined &&\n            this.hasPendingJoinedWork(info.joinedFilterSourceId),\n        )\n      ) {\n        return\n      }\n\n      // A key has at most one result row, so one flush can add or remove at\n      // most one. Check before any state changes: anything else means an\n      // upstream operator broke multiplicity.\n      for (const [key, { inserts, deletes }] of pendingChanges) {\n        if (Math.abs(inserts - deletes) > 1) {\n          throw new Error(\n            devBuild() && process.env.NODE_ENV !== `production`\n              ? `Live query result key ${String(key)} changed by ${inserts - deletes} rows in one flush; a key has at most one result row.`\n              : codedMessage(150, { key, change: inserts - deletes }),\n          )\n        }\n      }\n\n      let facadePublication:\n        ReturnType<BucketFacadeAdapter[`flush`]> | undefined\n      let rootPublication:\n        ReturnType<Collection[`_deferPublication`]> | undefined\n      try {\n        facadePublication = bucketFacades?.flush()\n        rootPublication = writesRoot\n          ? config.collection._deferPublication()\n          : undefined\n        const changesToApply: Map<unknown, Changes<TResult>> = bucketFacades\n          ? new Map(\n              [...pendingChanges].map(([key, changes]) => {\n                const resolved: Changes<TResult> = {\n                  ...changes,\n                  value: bucketFacades.resolve(changes.value),\n                }\n                if (changes.previousValue !== undefined) {\n                  resolved.previousValue = bucketFacades.resolve(\n                    changes.previousValue,\n                  )\n                }\n                return [key, resolved]\n              }),\n            )\n          : pendingChanges\n        // New facades are not reachable until their root row is installed, so\n        // make them ready first. A facade failure then leaves the root intact,\n        // and the root commit is the final state change before publication.\n        facadePublication?.prepare()\n        if (writesRoot) {\n          begin(snapshot ? { snapshot } : undefined)\n          let lookup: ((key: string | number) => boolean) | undefined\n          const hasSyncedKey = (key: string | number) => {\n            // A snapshot replaces every row, so no earlier row exists for\n            // the batch it holds.\n            if (snapshot) return false\n            lookup ??= config.collection._state.createSyncedKeyLookup()\n            return lookup(key)\n          }\n          changesToApply.forEach(\n            this.applyChanges.bind(this, config, hasSyncedKey),\n          )\n          if (hasOrderOnlyMove(changesToApply)) {\n            markLayoutChange(config.collection)\n          }\n          commit()\n          this.reloadSnapshotPending = false\n        }\n      } catch (error) {\n        rootPublication?.discard()\n        facadePublication?.rollback()\n        throw error\n      }\n      pendingChanges = new Map()\n\n      let publicationError: unknown\n      for (const publish of [\n        rootPublication?.publish,\n        facadePublication?.publish,\n      ]) {\n        if (!publish) continue\n        try {\n          publish()\n        } catch (error) {\n          publicationError ??= error\n        }\n      }\n      if (publicationError !== undefined) throw publicationError\n    }\n    graph.finalize()\n\n    // Extend the sync state with the graph, inputs, and pipeline\n    syncState.graph = graph\n    syncState.inputs = inputs\n    syncState.pipeline = pipeline\n\n    return syncState as FullSyncState\n  }\n\n  private applyChanges(\n    config: SyncMethods<TResult>,\n    hasSyncedKey: (key: string | number) => boolean,\n    changes: {\n      deletes: number\n      inserts: number\n      value: TResult\n      orderByIndex: string | undefined\n    },\n    key: unknown,\n  ) {\n    const { write, collection } = config\n    const { deletes, inserts, value, orderByIndex } = changes\n    // Store the key of the result so that we can retrieve it in the\n    // getKey function\n    this.resultKeys.set(value, key)\n\n    // Store the orderBy index if it exists\n    if (orderByIndex !== undefined) {\n      this.orderByIndices.set(value, orderByIndex)\n    }\n\n    // Simple singular insert.\n    if (inserts && deletes === 0) {\n      write({\n        value,\n        type: `insert`,\n      })\n    } else if (\n      // Insert & update(s) (updates are a delete & insert)\n      inserts > deletes ||\n      // A balanced delta updates an existing authoritative row, even if an\n      // optimistic delete hides it or its earlier insert is still queued.\n      (inserts === deletes && hasSyncedKey(collection.getKeyFromItem(value)))\n    ) {\n      write({\n        value,\n        type: `update`,\n      })\n      // Only delete is left as an option\n    } else if (deletes > 0) {\n      write({\n        value,\n        type: `delete`,\n      })\n    } else {\n      throw new Error(\n        devBuild() && process.env.NODE_ENV !== `production`\n          ? `Could not apply changes: ${JSON.stringify(changes)}. This should never happen.`\n          : codedMessage(151),\n      )\n    }\n  }\n\n  /**\n   * Handle status changes from source collections\n   */\n  private handleSourceStatusChange(\n    config: SyncMethods<TResult>,\n    sourceId: string,\n    collectionId: string,\n    event: AllCollectionEvents[`status:change`],\n  ) {\n    const { status } = event\n\n    // A crashed source cannot serve reads, so it ends this query at any time.\n    if (status === `crashed`) {\n      this.crashQuery(\n        devBuild() && process.env.NODE_ENV !== `production`\n          ? `Source collection '${collectionId}' crashed`\n          : codedMessage(172, { collectionId }),\n        event.collection._lifecycle.getSyncError(),\n      )\n      return\n    }\n\n    // A source whose first load failed fails this query's first load. Once\n    // the query has shown data, the failure is a sync problem on the source's\n    // node: the query keeps its status and rows.\n    if (status === `error`) {\n      if (this.liveQueryCollection?.status === `ready`) return\n      this.failQuery(\n        devBuild() && process.env.NODE_ENV !== `production`\n          ? `Source collection '${collectionId}' failed its first load`\n          : codedMessage(260, { collectionId }),\n        event.collection._lifecycle.getSyncError(),\n      )\n      return\n    }\n\n    // Handle manual cleanup - this should not happen due to GC prevention,\n    // but could happen if user manually calls cleanup()\n    if (status === `cleaned-up`) {\n      this.handleSourceCleanupStart(collectionId)\n      return\n    }\n\n    if (status === `ready`) {\n      if (\n        Object.values(this.optimizableOrderByCollections).some(\n          (info) => info.joinedFilterSourceId === sourceId,\n        )\n      ) {\n        this.maybeRunGraphFn?.()\n      }\n    }\n\n    // Update ready status based on all source collections\n    this.updateLiveQueryStatus(config)\n  }\n\n  private handleSourceCleanupStart(collectionId: string): Error | undefined {\n    if (this.fatalQueryError) return\n    const error = new Error(\n      devBuild() && process.env.NODE_ENV !== `production`\n        ? `Source collection '${collectionId}' was manually cleaned up while live query '${this.id}' depends on it. ` +\n            `Live queries prevent automatic GC, so this was likely a manual cleanup() call.`\n        : codedMessage(152, { collectionId, id: this.id }),\n    )\n    this.crashQuery(error.message, error)\n    return error\n  }\n\n  /**\n   * Update the live query status based on source collection statuses\n   */\n  private updateLiveQueryStatus(config: SyncMethods<TResult>) {\n    // Don't update status if already in error\n    if (this.fatalQueryError || !this.isResultComplete()) return\n    // A reload's run commits its complete result as its snapshot first. The\n    // snapshot completes the reload, so a run that keeps its result private\n    // (after a failed window move or ordered load) does not mark ready.\n    if (this.reloadSnapshotPending)\n      this.currentSyncState?.flushPendingChanges?.()\n    if (!this.reloadSnapshotPending) config.markReady()\n  }\n\n  /** Whether the current run's graph result is complete. */\n  private isResultComplete(): boolean {\n    const syncState = this.currentSyncState\n    const allReady = this.allRequiredSourcesReady()\n    const allDemandsSettled = [...this.activeDemands.values()].every(\n      (demand) => demand.settled,\n    )\n    const isLoading = this.liveQueryCollection?.isLoadingSubset\n    // Mark ready when:\n    // 1. All subscriptions are set up (subscribedToAllCollections)\n    // 2. The graph processed all its input: a source can announce its\n    //    readiness while its last batch still waits in this graph's\n    //    scheduled run, and that run marks ready when it ends\n    // 3. All source collections are ready\n    // 4. Every active route demand has settled\n    // 5. The live query collection is not loading subset data\n    // 6. No source reload's replay is still loading the demand again\n    // This prevents marking the live query ready before its data is processed\n    // (fixes issue where useLiveQuery returns isReady=true with empty data)\n    return (\n      syncState?.subscribedToAllCollections === true &&\n      !syncState.graph.pendingWork() &&\n      allReady &&\n      allDemandsSettled &&\n      isLoading !== true &&\n      !this.hasPendingSourceRecovery()\n    )\n  }\n\n  /**\n   * The query's first load failed: status `error`. A sync problem or a\n   * request error after the first ready never reaches here.\n   */\n  private failQuery(message: string, error?: unknown) {\n    if (!this.enterErrorState(message)) return\n    this.liveQueryCollection?._lifecycle.fail(error ?? new Error(message))\n  }\n\n  /**\n   * The query can no longer serve reads: a crashed source, a graph failure,\n   * or a contract violation such as a source cleaned up under this query.\n   */\n  private crashQuery(message: string, error?: unknown) {\n    this.enterErrorState(message)\n    this.liveQueryCollection?._lifecycle.crash(error ?? new Error(message))\n  }\n\n  /** Returns false when the query already ended. */\n  private enterErrorState(message: string): boolean {\n    if (this.fatalQueryError) return false\n    this.fatalQueryError = true\n    console.error(\n      devBuild() && process.env.NODE_ENV !== `production`\n        ? `[Live Query Error] ${message}`\n        : message,\n    )\n    return true\n  }\n\n  private allRequiredSourcesReady() {\n    return this.collectionSources.every(({ collection }) =>\n      sourcePermitsInitialReadiness(collection),\n    )\n  }\n\n  /**\n   * Creates one subscription per lexical collection source.\n   * Each source gets independent filters, even when aliases or collections repeat.\n   * Example: `{ employee: col, manager: col }` creates two separate subscriptions.\n   */\n  private subscribeToAllCollections(\n    config: SyncMethods<TResult>,\n    syncState: FullSyncState,\n  ) {\n    if (this.collectionSources.length === 0) {\n      throw new Error(\n        devBuild() && process.env.NODE_ENV !== `production`\n          ? `Query '${this.id}' has no collection sources. This should not happen; please report.`\n          : codedMessage(153, { id: this.id }),\n      )\n    }\n\n    // A Collection read under several aliases changes this query's tree once\n    // per change, so its relay is registered once.\n    const relayed = new Set<object>()\n    const loaders = this.collectionSources.map((source) => {\n      const { sourceId, alias, collection } = source\n      const collectionId = collection.id\n\n      const dependencyBuilder = getCollectionBuilder(collection)\n      if (dependencyBuilder && dependencyBuilder !== this) {\n        this.builderDependencies.add(dependencyBuilder)\n      }\n\n      // CollectionSubscriber handles the actual subscription to the source collection\n      // and feeds data into the D2 graph inputs for this specific alias\n      const collectionSubscriber = new CollectionSubscriber(\n        sourceId,\n        alias,\n        collection,\n        this,\n      )\n\n      // Subscribe to status changes for status flow\n      const statusUnsubscribe = collection.on(`status:change`, (event) => {\n        this.handleSourceStatusChange(config, sourceId, collectionId, event)\n      })\n      // Relay health tree changes so this query's tree stays current.\n      if (!relayed.has(collection)) {\n        relayed.add(collection)\n        syncState.unsubscribeCallbacks.add(\n          collection.on(`health:change`, () =>\n            this.liveQueryCollection?._emitHealthChange(),\n          ),\n        )\n      }\n      let cleanupStartError: Error | undefined\n      const cleanupStartUnsubscribe = collection._onCleanupStart(() => {\n        cleanupStartError = this.handleSourceCleanupStart(collectionId)\n      })\n      // Registration reports an already-active cleanup synchronously. That\n      // terminal transition must roll back earlier source ownership and stop\n      // this source and later aliases from acquiring any.\n      if (cleanupStartError) {\n        cleanupStartUnsubscribe()\n        statusUnsubscribe()\n        throw cleanupStartError\n      }\n      syncState.unsubscribeCallbacks.add(statusUnsubscribe)\n      syncState.unsubscribeCallbacks.add(cleanupStartUnsubscribe)\n\n      // The source may have failed before this live query subscribed. Register\n      // the listener first, then reconcile that current state so no transition\n      // can be missed between observation and subscription.\n      if (isFailedStatus(collection.status)) {\n        this.handleSourceStatusChange(config, sourceId, collectionId, {\n          type: `status:change`,\n          collection,\n          status: collection.status,\n          previousStatus: collection.status,\n        })\n      }\n\n      const subscription = collectionSubscriber.subscribe()\n      this.subscriptions[sourceId] = subscription\n      if (subscription.isDeferringAcquisition()) {\n        // No subscriber or preload yet: source reads stay local, and the\n        // deferred provider work starts when the first one arrives.\n        syncState.unsubscribeCallbacks.add(\n          this.liveQueryCollection!._onFirstSubscriberOrPreload(() =>\n            subscription.resumeDeferredAcquisition(),\n          ),\n        )\n        // Creating the subscription can run user code, such as an inner live\n        // query's status handler, that already requested this one's data.\n        if (this.hasSubscriberOrPreload()) {\n          subscription.resumeDeferredAcquisition()\n        }\n      }\n\n      const lazyCallbacks = this.lazySourcesCallbacks[sourceId]\n      if (lazyCallbacks) {\n        lazyCallbacks.setDemand = (plan, keys) =>\n          collectionSubscriber.setDemand(subscription, plan, keys)\n        for (const plan of lazyCallbacks.plans ?? []) {\n          // A window requested before start with a nonzero offset can drop\n          // the rows a static filter names, so it gets no static demand.\n          if (plan.initialKeys.size > 0 && !this.currentWindow?.offset) {\n            lazyCallbacks.setDemand(plan, plan.initialKeys)\n          }\n        }\n      }\n\n      // Create a callback for loading more data if needed (used by OrderBy optimization)\n      const loadMore = collectionSubscriber.loadMoreIfNeeded.bind(\n        collectionSubscriber,\n        subscription,\n      )\n\n      return loadMore\n    })\n\n    // Mark as subscribed so the graph can start running\n    // (graph only runs when all collections are subscribed)\n    syncState.subscribedToAllCollections = true\n\n    // Note: We intentionally don't call updateLiveQueryStatus() here.\n    // The graph hasn't run yet, so marking ready would be premature.\n    // The canonical place to mark ready is after the graph processes data\n    // in maybeRunGraph(), which ensures data has been processed first.\n\n    return () => runAllCallbacks(loaders)\n  }\n}\n\nfunction createOrderByComparator<T extends object>(\n  orderByIndices: WeakMap<object, string>,\n) {\n  return (val1: T, val2: T): number => {\n    // Use the orderBy index stored in the WeakMap\n    const index1 = orderByIndices.get(val1)\n    const index2 = orderByIndices.get(val2)\n\n    // Compare fractional indices lexicographically\n    if (index1 && index2) {\n      if (index1 < index2) {\n        return -1\n      } else if (index1 > index2) {\n        return 1\n      } else {\n        return 0\n      }\n    }\n\n    // Fallback to no ordering if indices are missing\n    return 0\n  }\n}\n\nfunction accumulateChanges<T>(\n  acc: Map<unknown, Changes<T>>,\n  [[key, tupleData], multiplicity]: [\n    [unknown, [any, string | undefined]],\n    number,\n  ],\n) {\n  // All queries now consistently return [value, orderByIndex] format\n  // where orderByIndex is undefined for queries without ORDER BY\n  const [value, orderByIndex] = tupleData as [T, string | undefined]\n\n  const changes = acc.get(key) || {\n    deletes: 0,\n    inserts: 0,\n    value,\n    orderByIndex,\n  }\n  if (multiplicity < 0) {\n    // Keep the first retraction so order-only moves compare with the last publication.\n    if (changes.deletes === 0) {\n      changes.previousValue = value\n      changes.previousOrderByIndex = orderByIndex\n    }\n    changes.deletes += Math.abs(multiplicity)\n  } else if (multiplicity > 0) {\n    changes.inserts += multiplicity\n    // Update value to the latest version for this key\n    changes.value = value\n    if (orderByIndex !== undefined) {\n      changes.orderByIndex = orderByIndex\n    }\n  }\n  acc.set(key, changes)\n  return acc\n}\n\n/**\n * Decide whether a flush contains an order-only move.\n *\n * An \"order-only move\" — a row updated in place whose `orderByIndex` moved but\n * whose projected value is deep-equal to before — is swallowed by the value-diff\n * and needs an explicit layout notification. The collection coalesces that\n * signal with any ordinary row publication per subscriber.\n */\nfunction hasOrderOnlyMove<T>(\n  changesToApply: Map<unknown, Changes<T>>,\n): boolean {\n  for (const changes of changesToApply.values()) {\n    const isUpdate = changes.inserts > 0 && changes.deletes > 0\n    if (\n      isUpdate &&\n      changes.previousValue !== undefined &&\n      deepEquals(changes.previousValue, changes.value) &&\n      changes.orderByIndex !== changes.previousOrderByIndex\n    ) {\n      return true\n    }\n  }\n  return false\n}\n\n/** Mark the collection's next commit as layout-changing. */\nfunction markLayoutChange(collection: { _markLayoutChange: () => void }): void {\n  collection._markLayoutChange()\n}\n"],"names":["resultKeys","orderByIndices","isGraphRunning","graphInputRevision","fatalQueryError","reloadSnapshotPending","builderDependencies","includeSourceIds","createSourceRecord","activeDemands","demandGeneration","pendingOrderedLoads","orderedLoadFailed","windowFailed","windowRequestGeneration","buildQueryFromConfig","initialWindow","settledWindow","extractCollectionsFromQuery","collectionSources","extractCollectionSources","collectSourceRefs","extractCollectionFromSource","compileBasePipeline","index","findProblems","dependentEntry","getSyncConfig","LIVE_QUERY_INTERNAL","windowFn","SetWindowRequiresOrderByError","SetWindowFindOneLimitError","activeWindowOperation","SetWindowReentrancyError","currentWindow","pendingSourceRecovery","error","LoadSubsetOperationAbortedError","latestWindowRequest","settlement","deferred","hasFailedSourceRecovery","devBuild","codedMessage","withPublicationContext","maybeRunGraphFn","createDeferred","hasPendingJoinedSourceWork","normalizeError","errors","crashQuery","loadMoreFn","updateLiveQueryStatus","scheduleQueryGraphRun","syncFn","runAllCallbacks","clearSyncRunState","extendPipelineWithChangeProcessing","subscribeToAllCollections","graphCache","inputsCache","pipelineCache","bucketFacadesCache","includesRuntimeCache","D2","compileCollectionQuery","reducePublicKeys","MissingAliasInputsError","maybeCompileBasePipeline","output","isResultComplete","applyChanges","handleSourceStatusChange","handleSourceCleanupStart","allRequiredSourcesReady","enterErrorState","sourcePermitsInitialReadiness","getCollectionBuilder","collectionSubscriber","CollectionSubscriber","isFailedStatus","deepEquals"],"mappings":"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"}