{"version":3,"file":"effect.cjs","sources":["../../../src/query/effect.ts"],"sourcesContent":["import { D2, output } from '@tanstack/db-ivm'\nimport { createSourceRecord } from '../utils/source-record.js'\nimport { createDeferred } from '../deferred.js'\nimport { runAllCallbacks } from '../utils/callbacks.js'\nimport { normalizeError } from '../utils/error.js'\nimport { deepEquals } from '../utils.js'\nimport { codedMessage, devBuild } from '../error-message.js'\nimport { buildHealthTree, healthNode } from '../collection/health-tree.js'\nimport { isFailedStatus } from '../live-query-primitives.js'\nimport { compileQuery } from './compiler/index.js'\nimport { normalizeExpressionPaths } from './compiler/expressions.js'\nimport { getCollectionBuilder } from './live/collection-registry.js'\nimport { scheduleQueryGraphRun } from './live/graph-scheduler.js'\nimport {\n  SubsetDemandController,\n  hasPendingJoinedWork as hasPendingJoinedSourceWork,\n} from './live/subset-demand-controller.js'\nimport { OrderedSourceLoader } from './live/ordered-source-loader.js'\nimport {\n  buildQueryFromConfig,\n  computeSubscriptionOrderByHints,\n  extractCollectionFromSource,\n  extractCollectionSources,\n  extractCollectionsFromQuery,\n  reconcileChangesForD2,\n  sendChangesToInput,\n  sourcePermitsInitialReadiness,\n  splitUpdates,\n} from './live/utils.js'\nimport type { RootStreamBuilder } from '@tanstack/db-ivm'\nimport type { Collection } from '../collection/index.js'\nimport type { CollectionSubscription } from '../collection/subscription.js'\nimport type { InitialQueryBuilder, QueryBuilder } from './builder/index.js'\nimport type { Context } from './builder/types.js'\nimport type { BasicExpression, QueryIR } from './ir.js'\nimport type { OrderByOptimizationInfo } from './compiler/order-by.js'\nimport type { GraphDependency } from './live/graph-scheduler.js'\nimport type {\n  LazyCollectionCallbacks,\n  LazyDemandPlan,\n} from './compiler/joins.js'\nimport type {\n  ChangeMessage,\n  CollectionDependent,\n  CollectionStatus,\n  HealthNode,\n  KeyedStream,\n  StringCollationConfig,\n} from '../types.js'\n\n// ---------------------------------------------------------------------------\n// Public Types\n// ---------------------------------------------------------------------------\n\n/** Event types for query result deltas */\nexport type DeltaType = 'enter' | 'exit' | 'update'\n\n/** Delta event emitted when a row enters, exits, or updates within a query result */\nexport type DeltaEvent<\n  TRow extends object = Record<string, unknown>,\n  TKey extends string | number = string | number,\n> =\n  | {\n      type: 'enter'\n      key: TKey\n      /** Current value for the entering row */\n      value: TRow\n      metadata?: Record<string, unknown>\n    }\n  | {\n      type: 'exit'\n      key: TKey\n      /** Current value for the exiting row */\n      value: TRow\n      metadata?: Record<string, unknown>\n    }\n  | {\n      type: 'update'\n      key: TKey\n      /** Current value after the update */\n      value: TRow\n      /** Previous value before the batch */\n      previousValue: TRow\n      metadata?: Record<string, unknown>\n    }\n\n/** Context passed to effect handlers */\nexport interface EffectContext {\n  /** ID of this effect (auto-generated if not provided) */\n  effectId: string\n  /** Aborted when effect.dispose() is called */\n  signal: AbortSignal\n}\n\n/** Query input - can be a builder function or a prebuilt query */\nexport type EffectQueryInput<TContext extends Context> =\n  ((q: InitialQueryBuilder) => QueryBuilder<TContext>) | QueryBuilder<TContext>\n\ntype EffectEventHandler<\n  TRow extends object = Record<string, unknown>,\n  TKey extends string | number = string | number,\n> = (event: DeltaEvent<TRow, TKey>, ctx: EffectContext) => void | Promise<void>\n\ntype EffectBatchHandler<\n  TRow extends object = Record<string, unknown>,\n  TKey extends string | number = string | number,\n> = (\n  events: Array<DeltaEvent<TRow, TKey>>,\n  ctx: EffectContext,\n) => void | Promise<void>\n\n/** Effect configuration */\nexport interface EffectConfig<\n  TRow extends object = Record<string, unknown>,\n  TKey extends string | number = string | number,\n> {\n  /** Optional ID for debugging/tracing */\n  id?: string\n\n  /** Query to watch for deltas */\n  query: EffectQueryInput<any>\n\n  /** Called once for each row entering the query result */\n  onEnter?: EffectEventHandler<TRow, TKey>\n\n  /** Called once for each row updating within the query result */\n  onUpdate?: EffectEventHandler<TRow, TKey>\n\n  /** Called once for each row exiting the query result */\n  onExit?: EffectEventHandler<TRow, TKey>\n\n  /** Called once per graph run with all delta events from that batch */\n  onBatch?: EffectBatchHandler<TRow, TKey>\n\n  /** Error handler for exceptions thrown by effect callbacks */\n  onError?: (error: Error, event: DeltaEvent<TRow, TKey>) => void\n\n  /**\n   * Called when a source crashes, fails its first load before the effect's\n   * initial-query readiness, or is cleaned up while the effect reads it, and\n   * when a subset load the effect requests from a source, or its release,\n   * fails, before or after that readiness. A cascade cleanup that ends the\n   * effect does not call it.\n   * The effect is automatically disposed after this callback fires. If not\n   * provided, the error is logged to console.error.\n   */\n  onSourceError?: (error: Error) => void\n\n  /**\n   * Called after the effect's initial-query readiness whenever its health tree\n   * changes. A sync problem after initial-query readiness does not dispose the\n   * effect; read the health tree to decide what to do.\n   */\n  onHealthChange?: (health: HealthNode) => void\n\n  /**\n   * Skip deltas during initial collection load.\n   * Defaults to false (process all deltas including initial sync).\n   * Set to true for effects that should only process new changes.\n   */\n  skipInitial?: boolean\n}\n\n/** Handle returned by createEffect */\nexport interface Effect {\n  /**\n   * Dispose the effect and await in-flight handlers. Calls during one cleanup\n   * attempt, including calls from abort/release callbacks, share its outcome.\n   */\n  dispose: () => Promise<void>\n  /** Whether this effect has been disposed */\n  readonly disposed: boolean\n}\n\n// ---------------------------------------------------------------------------\n// Internal Types\n// ---------------------------------------------------------------------------\n\n/** Accumulated changes for a single key within a graph run */\ninterface EffectChanges<T> {\n  deletes: number\n  inserts: number\n  /** Value from the latest insert (the newest/current value) */\n  insertValue?: T\n  /** Value from the first delete (the oldest/previous value before the batch) */\n  deleteValue?: T\n}\n\n// ---------------------------------------------------------------------------\n// Global Counter\n// ---------------------------------------------------------------------------\n\nlet effectCounter = 0\n\n// ---------------------------------------------------------------------------\n// createEffect\n// ---------------------------------------------------------------------------\n\n/**\n * Creates a reactive effect that fires handlers when rows enter, exit, or\n * update within a query result. Effects process deltas only — they do not\n * maintain or require the full materialised query result.\n *\n * @example\n * ```typescript\n * const effect = createEffect({\n *   query: (q) => q.from({ msg: messagesCollection })\n *     .where(({ msg }) => eq(msg.role, 'user')),\n *   onEnter: async (event) => {\n *     await generateResponse(event.value)\n *   },\n * })\n *\n * // Later: stop the effect\n * await effect.dispose()\n * ```\n */\n/** The error that ends an Effect whose source crashed or failed its first load. */\nfunction stoppedSourceError(collectionId: string, status: CollectionStatus) {\n  return new Error(\n    devBuild() && process.env.NODE_ENV !== `production`\n      ? `Source collection '${collectionId}' entered ${status} state`\n      : codedMessage(135, { collectionId, status }),\n  )\n}\n\nexport function createEffect<\n  TRow extends object = Record<string, unknown>,\n  TKey extends string | number = string | number,\n>(config: EffectConfig<TRow, TKey>): Effect {\n  const id = config.id ?? `live-query-effect-${++effectCounter}`\n\n  // AbortController for signalling disposal to handlers\n  const abortController = new AbortController()\n\n  const ctx: EffectContext = {\n    effectId: id,\n    signal: abortController.signal,\n  }\n\n  // Track in-flight async handler promises so dispose() can await them\n  const inFlightHandlers = new Set<Promise<void>>()\n  let disposed = false\n\n  // Callback invoked by the pipeline runner with each batch of delta events\n  const onBatchProcessed = (events: Array<DeltaEvent<TRow, TKey>>) => {\n    if (disposed) return\n    if (events.length === 0) return\n\n    // Batch handler\n    if (config.onBatch) {\n      try {\n        const result = config.onBatch(events, ctx)\n        if (result instanceof Promise) {\n          const tracked = result.catch((error) => {\n            reportError(error, events[0]!, config.onError)\n          })\n          trackPromise(tracked, inFlightHandlers)\n        }\n      } catch (error) {\n        // For batch handler errors, report with first event as context\n        reportError(error, events[0]!, config.onError)\n      }\n    }\n\n    for (const event of events) {\n      if (abortController.signal.aborted) break\n\n      const handler = getHandlerForEvent(event, config)\n      if (!handler) continue\n\n      try {\n        const result = handler(event, ctx)\n        if (result instanceof Promise) {\n          const tracked = result.catch((error) => {\n            reportError(error, event, config.onError)\n          })\n          trackPromise(tracked, inFlightHandlers)\n        }\n      } catch (error) {\n        reportError(error, event, config.onError)\n      }\n    }\n  }\n\n  // The dispose function is referenced by both the returned Effect object\n  // and the onSourceError callback, so we define it first.\n  let disposalPromise: Promise<void> | undefined\n  const dispose = (): Promise<void> => {\n    if (disposalPromise) return disposalPromise\n    // Abort and source-release callbacks may synchronously call dispose again.\n    // Publish the shared result before entering either user callback boundary.\n    const completion = createDeferred<void>()\n    const attempt = completion.promise\n    disposalPromise = attempt\n    disposed = true\n\n    // Abort signal for in-flight handlers\n    abortController.abort()\n\n    void (async () => {\n      // Tear down the pipeline (unsubscribe from sources, etc.)\n      let cleanupFailed = false\n      let cleanupError: unknown\n      try {\n        runner.dispose()\n      } catch (error) {\n        cleanupFailed = true\n        cleanupError = error\n      }\n\n      // Wait for any in-flight async handlers to settle\n      if (inFlightHandlers.size > 0) {\n        await Promise.allSettled([...inFlightHandlers])\n      }\n\n      if (cleanupFailed) throw cleanupError\n    })().then(completion.resolve, completion.reject)\n    void attempt.then(\n      () => {},\n      () => {\n        if (disposalPromise === attempt) disposalPromise = undefined\n      },\n    )\n    return attempt\n  }\n\n  const effect: Effect = {\n    dispose,\n    get disposed() {\n      return disposed\n    },\n  }\n\n  // Create and start the pipeline\n  const runner = new EffectPipelineRunner<TRow, TKey>({\n    effect,\n    query: config.query,\n    skipInitial: config.skipInitial ?? false,\n    onBatchProcessed,\n    onHealthChange: config.onHealthChange,\n    onSourceError: (error: Error) => {\n      if (disposed) return\n\n      if (config.onSourceError) {\n        try {\n          config.onSourceError(error)\n        } catch (callbackError) {\n          console.error(\n            devBuild() && process.env.NODE_ENV !== `production`\n              ? `[Effect '${id}'] onSourceError callback threw:`\n              : codedMessage(220, { id }),\n            callbackError,\n          )\n        }\n      } else {\n        console.error(\n          devBuild() && process.env.NODE_ENV !== `production`\n            ? `[Effect '${id}'] ${error.message}. Disposing effect.`\n            : codedMessage(221, { id, message: error.message }),\n        )\n      }\n\n      // Auto-dispose — the effect can no longer function\n      void dispose().catch((cleanupError) => {\n        console.error(\n          devBuild() && process.env.NODE_ENV !== `production`\n            ? `[Effect '${id}'] failed to dispose after a source error:`\n            : codedMessage(222, { id }),\n          cleanupError,\n        )\n      })\n    },\n  })\n  try {\n    runner.start()\n  } catch (error) {\n    try {\n      runner.dispose()\n    } catch (cleanupError) {\n      console.error(\n        devBuild() && process.env.NODE_ENV !== `production`\n          ? `[Effect '${id}'] failed to dispose after a startup error:`\n          : codedMessage(223, { id }),\n        cleanupError,\n      )\n    }\n    throw error\n  }\n\n  return effect\n}\n\n// ---------------------------------------------------------------------------\n// EffectPipelineRunner\n// ---------------------------------------------------------------------------\n\ninterface EffectPipelineRunnerConfig<\n  TRow extends object,\n  TKey extends string | number,\n> {\n  query: EffectQueryInput<any>\n  skipInitial: boolean\n  onBatchProcessed: (events: Array<DeltaEvent<TRow, TKey>>) => void\n  /** Called when a source collection enters error or cleaned-up state */\n  onSourceError: (error: Error) => void\n  onHealthChange?: (health: HealthNode) => void\n  /** The Effect's handle, so its source subscriptions can name it. */\n  effect: Effect\n}\n\n/**\n * Report how a held acquisition ends. A truncate replay rejects the\n * acquisition it supersedes and starts a replacement, which inherits the hold.\n */\nfunction followHeldAcquisition(\n  acquisition: Promise<unknown>,\n  replacementAfterFailure: () => Promise<void> | undefined,\n  handlers: {\n    settled: (succeeded: boolean) => void\n    replaced: (replacement: Promise<void>) => void\n  },\n): void {\n  void acquisition.then(\n    () => handlers.settled(true),\n    () => {\n      const replacement = replacementAfterFailure()\n      if (replacement) handlers.replaced(replacement)\n      else handlers.settled(false)\n    },\n  )\n}\n\n/**\n * Internal class that manages a D2 pipeline for effect delta processing.\n *\n * Sets up the IVM graph, subscribes to source collections, runs the graph\n * when changes arrive, and classifies output multiplicities into DeltaEvents.\n *\n * Unlike CollectionConfigBuilder, this does not publish results to a\n * Collection.\n */\nclass EffectPipelineRunner<TRow extends object, TKey extends string | number> {\n  private readonly query: QueryIR\n  private readonly queryCompareOptions: StringCollationConfig\n  private readonly collections: Record<string, Collection<any, any, any>>\n  private readonly collectionSources: ReturnType<\n    typeof extractCollectionSources\n  >\n\n  private graph: D2 | undefined\n  private inputs: Record<string, RootStreamBuilder<unknown>> | undefined\n  private sourceWhereClauses: Map<string, BasicExpression<boolean>> | undefined\n\n  // Mutable objects passed to compileQuery by reference.\n  // The join compiler captures these references and reads them later when\n  // the graph runs, so they must be populated before the first graph run.\n  private readonly subscriptions = createSourceRecord<CollectionSubscription>()\n  private readonly lazySourcesCallbacks =\n    createSourceRecord<LazyCollectionCallbacks>()\n  private readonly lazySources = new Set<string>()\n  private readonly demand = new SubsetDemandController()\n  // OrderBy optimization info populated by the compiler when limit is present\n  private readonly optimizableOrderByCollections =\n    createSourceRecord<OrderByOptimizationInfo>()\n\n  // Ordered subscription state for cursor-based loading\n  private readonly orderedLoaders = new Map<string, OrderedSourceLoader>()\n  // An asynchronous authoritative repair may update the private D2 state in\n  // several prefix/tie/refill steps. Keep their net Effect delta private until\n  // the final participant settles, matching live-query Collection publication.\n  private readonly pendingOrderedPublications = new Set<Promise<unknown>>()\n  private readonly pendingInitialLoads = new Set<Promise<unknown>>()\n  private orderedPublicationFailed = false\n\n  // Subscription management\n  private readonly unsubscribeCallbacks = new Set<() => void>()\n  // Exact row last contributed to D2 per lexical source key.\n  private readonly sentToD2RowsBySource = new Map<\n    string,\n    Map<string | number, Record<string, unknown>>\n  >()\n\n  // Output accumulator\n  private pendingChanges: Map<unknown, EffectChanges<TRow>> = new Map()\n  // Callback-visible result. Held repair deltas are classified against this\n  // last coherent membership rather than their net multiplicity alone.\n  private readonly publishedRows = new Map<unknown, TRow>()\n\n  // skipInitial state\n  private readonly skipInitial: boolean\n  private initialLoadComplete = false\n  // The Effect's initial gate: latched when every\n  // initial load has settled, with or without skipInitial. After it,\n  // a sync problem does not dispose the Effect.\n  private reachedReady = false\n  private reportedTree: HealthNode | undefined\n  private readonly onHealthChange: ((health: HealthNode) => void) | undefined\n  // This Effect as its sources' `subscribers` list it.\n  private readonly dependent: CollectionDependent\n\n  // Scheduler integration\n  private subscribedToAllCollections = false\n  private readonly builderDependencies = new Set<GraphDependency>()\n\n  // Reentrance guard\n  private isGraphRunning = false\n  private disposed = false\n\n  private readonly onBatchProcessed: (\n    events: Array<DeltaEvent<TRow, TKey>>,\n  ) => void\n  private readonly onSourceError: (error: Error) => void\n\n  constructor(config: EffectPipelineRunnerConfig<TRow, TKey>) {\n    this.skipInitial = config.skipInitial\n    this.onBatchProcessed = config.onBatchProcessed\n    this.onSourceError = config.onSourceError\n    this.onHealthChange = config.onHealthChange\n    this.dependent = {\n      kind: `effect`,\n      active: true,\n      end: () => config.effect.dispose(),\n    }\n\n    // Parse query\n    this.query = buildQueryFromConfig({ query: config.query })\n    this.queryCompareOptions = extractCollectionFromSource(\n      this.query,\n    ).compareOptions\n\n    // Extract source collections\n    this.collections = extractCollectionsFromQuery(this.query)\n    this.collectionSources = extractCollectionSources(this.query)\n\n    // Compile the pipeline\n    this.compilePipeline()\n  }\n\n  /** Compile the D2 graph and query pipeline */\n  private compilePipeline(): void {\n    this.graph = new D2()\n    const inputs = createSourceRecord<RootStreamBuilder<unknown>>()\n    for (const source of this.collectionSources) {\n      inputs[source.sourceId] = this.graph.newInput<any>()\n    }\n    this.inputs = inputs\n\n    const compilation = compileQuery(\n      this.query,\n      this.inputs as Record<string, KeyedStream>,\n      this.collections,\n      // These mutable objects are captured by reference. The join compiler\n      // reads them later when the graph runs, so they must be populated\n      // (in start()) before the first graph run.\n      this.subscriptions,\n      this.lazySourcesCallbacks,\n      this.lazySources,\n      this.optimizableOrderByCollections,\n      () => {}, // setWindowFn (no-op — effects don't paginate)\n    )\n\n    this.sourceWhereClauses = compilation.sourceWhereClauses\n\n    // Attach the output operator that accumulates changes\n    compilation.pipeline.pipe(\n      output((data) => {\n        const messages = data.getInner()\n        messages.reduce(accumulateEffectChanges<TRow>, this.pendingChanges)\n      }),\n    )\n\n    this.graph.finalize()\n  }\n\n  private isDisposed(): boolean {\n    return this.disposed\n  }\n\n  /** Subscribe to source collections and start processing */\n  start(): void {\n    if (this.collectionSources.length === 0) {\n      // Nothing to subscribe to\n      return\n    }\n\n    // When not skipping initial, we always process events immediately\n    if (!this.skipInitial) {\n      this.initialLoadComplete = true\n    }\n\n    // We need to defer initial data processing until ALL subscriptions are\n    // created, because join pipelines look up subscriptions by alias during\n    // the graph run. If we run the graph while some aliases are still missing,\n    // the join tap operator will throw.\n    //\n    // Strategy: subscribe to each collection but buffer incoming changes.\n    // After all subscriptions are in place, flush the buffers and switch to\n    // direct processing mode.\n\n    const pendingBuffers = new Map<\n      string,\n      Array<Array<ChangeMessage<any, string | number>>>\n    >()\n\n    for (const source of this.collectionSources) {\n      if (this.isDisposed()) {\n        return\n      }\n\n      const { sourceId, alias, collection } = source\n      const collectionId = collection.id\n\n      const handleSourceCleanup = () => {\n        if (this.disposed) return\n        this.onSourceError(\n          new Error(\n            devBuild() && process.env.NODE_ENV !== `production`\n              ? `Source collection '${collectionId}' was cleaned up while effect depends on it`\n              : codedMessage(134, { collectionId }),\n          ),\n        )\n      }\n      // Observe cleanup before subscription admission, which rejects while\n      // cleanup is active. A late Effect still returns its disposed handle.\n      const cleanupStartUnsubscribe =\n        collection._onCleanupStart(handleSourceCleanup)\n      // Registration can dispose the runner before its handle is available.\n      if (this.isDisposed()) {\n        cleanupStartUnsubscribe()\n        return\n      }\n      this.unsubscribeCallbacks.add(cleanupStartUnsubscribe)\n\n      this.sentToD2RowsBySource.set(sourceId, new Map())\n\n      // Discover dependencies: if source collection is itself a live query\n      // collection, its builder must run first during transaction flushes.\n      const dependencyBuilder = getCollectionBuilder(collection)\n      if (dependencyBuilder) {\n        this.builderDependencies.add(dependencyBuilder)\n      }\n\n      // Get where clause for this alias (for predicate push-down)\n      const whereClause = this.sourceWhereClauses?.get(sourceId)\n      const whereExpression = whereClause\n        ? normalizeExpressionPaths(whereClause, alias)\n        : undefined\n\n      // Initialise buffer for this alias\n      const buffer: Array<Array<ChangeMessage<any, string | number>>> = []\n      pendingBuffers.set(sourceId, buffer)\n\n      // Lazy aliases (marked by the join compiler) should NOT load initial state\n      // eagerly — the join tap operator will load exactly the rows it needs on demand.\n      // For on-demand collections, eager loading would trigger a full server fetch\n      // for data that should be lazily loaded based on join keys.\n      const isLazy = this.lazySources.has(sourceId)\n\n      // Check if this alias has orderBy optimization (cursor-based loading)\n      const orderByInfo = this.optimizableOrderByCollections[sourceId]\n\n      const changeCallback = (\n        changes: Array<ChangeMessage<any, string | number>>,\n      ) => {\n        const bufferedChanges = pendingBuffers.get(sourceId)\n        if (bufferedChanges) bufferedChanges.push(changes)\n        else this.handleSourceChanges(sourceId, changes)\n      }\n\n      // A source that stopped before this Effect sends no status change. End\n      // the Effect before any subscription or load reaches that source.\n      if (isFailedStatus(collection.status)) {\n        this.onSourceError(stoppedSourceError(collectionId, collection.status))\n        return\n      }\n\n      // Subscribe to source changes\n      const subscription = collection.subscribeChanges(changeCallback, {\n        ...this.buildSubscriptionOptions(\n          alias,\n          isLazy,\n          orderByInfo,\n          whereExpression,\n        ),\n        owner: this.dependent,\n        onLoadSubsetError: ({ error }) =>\n          this.onSourceError(normalizeError(error)),\n        // subscribeChanges can report a result before it returns the\n        // subscription, so read it from the record when a load fails.\n        onLoadSubsetResult: (result) => {\n          this.trackInitialLoad(\n            result,\n            () => this.subscriptions[sourceId]?.pendingTruncateReplacement,\n          )\n        },\n      })\n\n      // Store subscription immediately so the join compiler can find it\n      this.subscriptions[sourceId] = subscription\n\n      const unsubscribe = () => {\n        delete this.subscriptions[sourceId]\n        subscription.unsubscribe()\n      }\n\n      // subscribeChanges can synchronously report a source error and dispose\n      // the runner before returning the subscription.\n      if (this.isDisposed()) {\n        unsubscribe()\n        return\n      }\n\n      // Own the subscription before any ordered snapshot or lazy demand can\n      // throw. A partially started effect has no handle for its caller to\n      // dispose, so start() must be able to release every acquired source.\n      this.unsubscribeCallbacks.add(unsubscribe)\n\n      if (\n        Object.values(this.optimizableOrderByCollections).some(\n          (info) => info.joinedFilterSourceId === sourceId,\n        )\n      ) {\n        this.unsubscribeCallbacks.add(\n          subscription.on(`status:ready`, () => {\n            if (!this.disposed) this.scheduleGraphRun()\n          }),\n        )\n      }\n\n      const lazyCallbacks = this.lazySourcesCallbacks[sourceId]\n      if (lazyCallbacks) {\n        lazyCallbacks.setDemand = (plan: LazyDemandPlan, keys: Set<unknown>) =>\n          this.setDemand(subscription, plan, keys)\n        for (const plan of lazyCallbacks.plans ?? []) {\n          if (plan.initialKeys.size > 0) {\n            lazyCallbacks.setDemand(plan, plan.initialKeys)\n          }\n        }\n      }\n\n      // For ordered aliases with an index, trigger the initial limited snapshot.\n      // This loads only the top N rows rather than the entire collection.\n      if (orderByInfo) {\n        const loader = new OrderedSourceLoader(\n          orderByInfo,\n          subscription,\n          alias,\n          (result, holdPublication) => {\n            this.trackInitialLoad(\n              result,\n              () => subscription.pendingTruncateReplacement,\n            )\n            const holdsInitialPublication =\n              this.skipInitial && !this.initialLoadComplete\n            if (holdPublication || holdsInitialPublication) {\n              this.trackOrderedPublication(\n                Promise.resolve(result),\n                () => subscription.pendingTruncateReplacement,\n              )\n            }\n          },\n          () => false,\n          undefined,\n          () =>\n            orderByInfo.joinedFilterSourceId !== undefined &&\n            this.hasPendingJoinedWork(orderByInfo.joinedFilterSourceId),\n        )\n        this.orderedLoaders.set(sourceId, loader)\n        loader.start()\n        // The sync adapter reports that served pages may have shifted after\n        // its own refetch. Re-establish the window with a bounded repair.\n        this.unsubscribeCallbacks.add(\n          collection.on(`loadedSubsets:invalidated`, () => {\n            if (this.disposed) return\n            loader.revalidateLoadedCoverage()\n            this.scheduleGraphRun()\n          }),\n        )\n      }\n\n      // Listen for status changes on source collections\n      const handleSourceStatus = (status: CollectionStatus) => {\n        if (this.disposed) return\n\n        // A crash ends the effect at any time. A failed first load ends it\n        // before its gate; after the gate it is a sync problem in the tree.\n        if (\n          status === `crashed` ||\n          (status === `error` && !this.reachedReady)\n        ) {\n          this.onSourceError(stoppedSourceError(collectionId, status))\n          return\n        }\n\n        // Source was manually cleaned up — effect can no longer function\n        if (status === `cleaned-up`) {\n          handleSourceCleanup()\n          return\n        }\n\n        // Track source readiness for skipInitial\n        if (\n          this.skipInitial &&\n          !this.initialLoadComplete &&\n          this.canCompleteInitialLoad()\n        ) {\n          this.initialLoadComplete = true\n        }\n        // health:change follows every status change and reports the tree.\n        this.latchReady()\n      }\n      const statusUnsubscribe = collection.on(`status:change`, ({ status }) =>\n        handleSourceStatus(status),\n      )\n      this.unsubscribeCallbacks.add(statusUnsubscribe)\n      this.unsubscribeCallbacks.add(\n        collection.on(`health:change`, () => this.reportHealth()),\n      )\n    }\n\n    // Mark as subscribed so the graph can start running\n    this.subscribedToAllCollections = true\n\n    // All subscriptions are now in place. Flush buffered changes by sending\n    // data to D2 inputs first (without running the graph), then run the graph\n    // once. This prevents intermediate join states from producing duplicates.\n    //\n    // We remove each alias from pendingBuffers *before* draining, which\n    // switches that alias to direct-processing mode. Any new callbacks that\n    // fire during the drain (e.g. from requestLimitedSnapshot) will go\n    // through handleSourceChanges directly instead of being lost.\n    for (const [sourceId, buffer] of pendingBuffers) {\n      pendingBuffers.delete(sourceId)\n\n      // Drain all buffered batches. Since we deleted the alias from\n      // pendingBuffers above, any new changes arriving during drain go\n      // through handleSourceChanges directly (not back into this buffer).\n      for (const changes of buffer) {\n        this.handleSourceChanges(sourceId, changes, false)\n      }\n    }\n\n    // Initial graph run to process any synchronously-available data.\n    // For skipInitial, this run's output is discarded (initialLoadComplete is still false).\n    this.runGraph()\n    this.latchReady()\n\n    // After the initial graph run, if all sources are ready,\n    // mark initial load as complete so future events are processed.\n    if (\n      this.skipInitial &&\n      !this.initialLoadComplete &&\n      this.canCompleteInitialLoad()\n    ) {\n      this.initialLoadComplete = true\n    }\n  }\n\n  /** Handle incoming changes from a source collection */\n  private handleSourceChanges(\n    sourceId: string,\n    changes: Array<ChangeMessage<any, string | number>>,\n    scheduleGraph = true,\n  ): void {\n    if (this.optimizableOrderByCollections[sourceId]) {\n      const source = this.collectionSources.find(\n        (candidate) => candidate.sourceId === sourceId,\n      )!\n      this.orderedLoaders\n        .get(sourceId)\n        ?.onSourceChanges(\n          changes,\n          this.sentToD2RowsBySource.get(sourceId),\n          (key) => source.collection._hasOptimisticOverlay(key),\n        )\n      changes = [...splitUpdates(changes)]\n    }\n    this.sendChangesToD2(sourceId, changes)\n    if (scheduleGraph) this.scheduleGraphRun()\n  }\n\n  private setDemand(\n    subscription: CollectionSubscription,\n    plan: LazyDemandPlan,\n    keys: Set<unknown>,\n  ): void {\n    const update = this.demand.setDemand(subscription, plan, keys)\n    if (update.ready instanceof Promise) {\n      this.trackInitialLoad(\n        update.ready,\n        () => subscription.pendingTruncateReplacement,\n      )\n      // Each segment reports its own failure through the subscription. Consume\n      // the aggregate rejection so Promise.all does not create a second,\n      // detached error channel.\n      void update.ready.then(\n        () => {\n          if (!this.disposed) this.scheduleGraphRun()\n        },\n        () => {},\n      )\n    }\n  }\n\n  /**\n   * Schedule a graph run via the transaction-scoped scheduler.\n   *\n   * When called within a transaction, the run is deferred until the\n   * transaction flushes, coalescing multiple changes into a single graph\n   * execution. Without a transaction, the graph runs immediately.\n   *\n   * Dependencies are discovered from source collections that are themselves\n   * live query collections, ensuring parent queries run before effects.\n   */\n  private scheduleGraphRun(): void {\n    scheduleQueryGraphRun(this, this.builderDependencies, () => {\n      if (!this.disposed && this.subscribedToAllCollections) this.runGraph()\n    })\n  }\n\n  /** Keep the Effect's gate, and `skipInitial` suppression, open until a pending initial load settles. */\n  private trackInitialLoad(\n    result: true | Promise<unknown>,\n    replacementAfterFailure: () => Promise<void> | undefined,\n  ): void {\n    if (!(result instanceof Promise) || this.reachedReady || this.disposed)\n      return\n    this.pendingInitialLoads.add(result)\n    const release = () => {\n      if (this.pendingInitialLoads.delete(result) && !this.disposed)\n        this.scheduleGraphRun()\n    }\n    // A load failure disposes the Effect through onLoadSubsetError, so a\n    // rejection releases one microtask later, after that event, as a live\n    // query's tracked rejection does. Any other rejection comes from an\n    // obsolete or aborted acquisition, so the hold fails open: it releases\n    // unless a truncate replacement takes it over.\n    followHeldAcquisition(result, replacementAfterFailure, {\n      settled: (succeeded) =>\n        succeeded ? release() : void Promise.resolve().then(release),\n      replaced: (replacement) => {\n        this.trackInitialLoad(replacement, replacementAfterFailure)\n        release()\n      },\n    })\n  }\n\n  /** Hold Effect callback publication across one authoritative repair chain. */\n  private trackOrderedPublication(\n    promise: Promise<unknown>,\n    replacementAfterFailure: () => Promise<void> | undefined,\n  ): void {\n    if (this.disposed) return\n    if (this.pendingOrderedPublications.size === 0) {\n      this.orderedPublicationFailed = false\n    }\n    this.pendingOrderedPublications.add(promise)\n    const finish = (succeeded: boolean) => {\n      if (!this.pendingOrderedPublications.delete(promise)) return\n      if (!succeeded) this.orderedPublicationFailed = true\n      if (\n        succeeded &&\n        !this.orderedPublicationFailed &&\n        this.pendingOrderedPublications.size === 0 &&\n        !this.disposed\n      ) {\n        // The repair chain already drove its private D2 state to quiescence.\n        // Run once more to publish the accumulated net delta.\n        this.scheduleGraphRun()\n      }\n    }\n    // A failed repair chain fails closed until a fresh chain starts. A\n    // replacement settles after replay rows reach this Effect's private D2\n    // state, so it takes over the same publication hold.\n    followHeldAcquisition(promise, replacementAfterFailure, {\n      settled: finish,\n      replaced: (replacement) => {\n        if (this.pendingOrderedPublications.delete(promise) && !this.disposed)\n          this.trackOrderedPublication(replacement, replacementAfterFailure)\n      },\n    })\n  }\n\n  /**\n   * Send changes to the D2 input for the given lexical source.\n   * Returns the number of multiset entries sent.\n   */\n  private sendChangesToD2(\n    sourceId: string,\n    changes: Array<ChangeMessage<any, string | number>>,\n  ): number {\n    if (this.disposed || !this.inputs || !this.graph) return 0\n\n    const input = this.inputs[sourceId]\n    if (!input) return 0\n\n    const sentRows = this.sentToD2RowsBySource.get(sourceId)!\n    const reconciled = reconcileChangesForD2(changes, sentRows)\n\n    return sendChangesToInput(input, reconciled)\n  }\n\n  /**\n   * Run the D2 graph until quiescence, then emit accumulated events once.\n   *\n   * All output across the entire while-loop is accumulated into a single\n   * batch so that users see one `onBatchProcessed` invocation per scheduler\n   * run, even when ordered loading causes multiple graph steps.\n   */\n  private runGraph(): void {\n    if (this.isGraphRunning || this.disposed || !this.graph) return\n\n    this.isGraphRunning = true\n    try {\n      if (!this.graph.pendingWork()) this.loadMoreIfNeeded()\n      // Ordered refill can also dispose the runner between graph steps.\n      while (!this.isDisposed() && this.graph.pendingWork()) {\n        this.graph.run()\n        // A handler (via onBatchProcessed) or source error callback may have\n        // called dispose() during graph.run(). Stop early to avoid operating\n        // on stale state. TS narrows disposed to false from the guard above\n        // but it can change during graph.run() via callbacks.\n        // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n        if (this.disposed) break\n        // After each step, check if ordered queries need more data.\n        // loadMoreIfNeeded may send data to D2 inputs (via requestLimitedSnapshot),\n        // causing pendingWork() to return true for the next iteration.\n        this.loadMoreIfNeeded()\n      }\n      // Emit all accumulated events once the graph reaches quiescence\n      this.flushPendingChanges()\n      this.latchReady()\n      if (\n        this.skipInitial &&\n        !this.initialLoadComplete &&\n        this.canCompleteInitialLoad()\n      ) {\n        this.initialLoadComplete = true\n      }\n    } finally {\n      this.isGraphRunning = false\n    }\n  }\n\n  /** Classify accumulated changes into DeltaEvents and invoke the callback */\n  private flushPendingChanges(): void {\n    if (this.pendingChanges.size === 0) return\n\n    if (\n      this.orderedPublicationFailed ||\n      this.pendingOrderedPublications.size > 0\n    ) {\n      return\n    }\n\n    if (this.hasPendingJoinedFilterWork()) {\n      return\n    }\n\n    const shouldPublish = !this.skipInitial || this.initialLoadComplete\n    const tracksPublishedRows = this.orderedLoaders.size > 0\n\n    const events: Array<DeltaEvent<TRow, TKey>> = []\n\n    for (const [key, changes] of this.pendingChanges) {\n      const event = classifyDelta<TRow, TKey>(\n        key as TKey,\n        changes,\n        tracksPublishedRows ? this.publishedRows : undefined,\n      )\n      if (event) {\n        if (tracksPublishedRows) {\n          if (event.type === `exit`) this.publishedRows.delete(key)\n          else this.publishedRows.set(key, event.value)\n        }\n        if (shouldPublish) events.push(event)\n      }\n    }\n\n    this.pendingChanges = new Map()\n\n    if (events.length > 0) {\n      this.onBatchProcessed(events)\n    }\n  }\n\n  /** Check the source-readiness part of initial readiness for every source. */\n  private sourcesPermitInitialReadiness(): boolean {\n    return this.collectionSources.every(({ collection }) =>\n      sourcePermitsInitialReadiness(collection),\n    )\n  }\n\n  /** Latch the Effect's initial gate and report whether it has been reached. */\n  private latchReady(): boolean {\n    if (!this.reachedReady && this.canCompleteInitialLoad()) {\n      this.reachedReady = true\n      // A problem the sources already show when the gate opens is the first\n      // change the app hears of. A healthy gate's tree is known without an\n      // announcement, so a health:change for the status change that opened\n      // the gate repeats nothing.\n      const tree = this.healthTree()\n      if (tree.hasErrors) this.reportHealth()\n      else this.reportedTree = tree\n    }\n    return this.reachedReady\n  }\n\n  /** The health tree for this effect's sources, in query order. */\n  private healthTree(): HealthNode {\n    return healthNode(this, undefined, {\n      alias: `root`,\n      collectionId: `effect`,\n      kind: `live-query`,\n      status: this.reachedReady ? `ready` : `loading`,\n      failureReason: null,\n      error: null,\n      reloading: false,\n      sources: this.collectionSources.map(({ sourceId, alias, collection }) =>\n        buildHealthTree(collection, { alias, id: sourceId }, this),\n      ),\n    })\n  }\n\n  private reportHealth(): void {\n    if (this.disposed || !this.reachedReady || !this.onHealthChange) return\n    // An unchanged tree keeps its identity; report each change once.\n    const tree = this.healthTree()\n    if (tree === this.reportedTree) return\n    this.reportedTree = tree\n    this.onHealthChange(tree)\n  }\n\n  private canCompleteInitialLoad(): boolean {\n    return (\n      !this.orderedPublicationFailed &&\n      this.pendingOrderedPublications.size === 0 &&\n      this.pendingInitialLoads.size === 0 &&\n      !this.hasPendingJoinedFilterWork() &&\n      this.sourcesPermitInitialReadiness()\n    )\n  }\n\n  private hasPendingJoinedFilterWork(): boolean {\n    return Object.values(this.optimizableOrderByCollections).some(\n      (info) =>\n        info.joinedFilterSourceId !== undefined &&\n        this.hasPendingJoinedWork(info.joinedFilterSourceId),\n    )\n  }\n\n  /**\n   * Build subscription options for an alias based on whether it uses ordered\n   * loading, is lazy, or should pass orderBy/limit hints.\n   */\n  private buildSubscriptionOptions(\n    alias: string,\n    isLazy: boolean,\n    orderByInfo: OrderByOptimizationInfo | undefined,\n    whereExpression: BasicExpression<boolean> | undefined,\n  ): {\n    includeInitialState?: boolean\n    whereExpression?: BasicExpression<boolean>\n    orderBy?: any\n    limit?: number\n  } {\n    if (this.query.limit === 0) {\n      return { includeInitialState: false, whereExpression }\n    }\n\n    // Ordered aliases explicitly disable initial state — data is loaded\n    // via requestLimitedSnapshot/requestSnapshot after subscription setup.\n    if (orderByInfo) {\n      return { includeInitialState: false, whereExpression }\n    }\n\n    const includeInitialState = !isLazy\n\n    // For unordered subscriptions, pass orderBy/limit hints so on-demand\n    // collections can optimise server-side fetching.\n    const hints = computeSubscriptionOrderByHints(\n      this.query,\n      alias,\n      this.queryCompareOptions,\n    )\n\n    return {\n      includeInitialState,\n      whereExpression,\n      ...(hints.orderBy ? { orderBy: hints.orderBy } : {}),\n      ...(hints.limit !== undefined ? { limit: hints.limit } : {}),\n    }\n  }\n\n  /**\n   * After each graph run step, check if any ordered query's topK operator\n   * needs more data. If so, load more rows via requestLimitedSnapshot.\n   */\n  private loadMoreIfNeeded(): void {\n    for (const loader of this.orderedLoaders.values()) {\n      try {\n        loader.loadMore()\n      } catch (error) {\n        if (\n          !this.disposed &&\n          !Object.values(this.subscriptions).some((subscription) =>\n            Object.is(subscription.lastError, error),\n          )\n        )\n          throw error\n      }\n    }\n  }\n\n  private hasPendingJoinedWork(joinedSourceId: string): boolean {\n    return hasPendingJoinedSourceWork(\n      joinedSourceId,\n      this.lazySourcesCallbacks,\n      this.subscriptions,\n      (planId) => this.demand.hasPendingDemand(planId),\n    )\n  }\n\n  /** Tear down subscriptions and clear state */\n  dispose(): void {\n    if (this.disposed) return\n    this.disposed = true\n    this.subscribedToAllCollections = false\n\n    // Release every source in one pass; the first failure wins after the\n    // peers finish. A reentrant dispose returns at the guard above, so this\n    // call still owns each release exactly once.\n    try {\n      runAllCallbacks(this.unsubscribeCallbacks)\n    } finally {\n      this.unsubscribeCallbacks.clear()\n      this.clearPipelineState()\n    }\n  }\n\n  private clearPipelineState(): void {\n    this.sentToD2RowsBySource.clear()\n    this.pendingChanges.clear()\n    this.publishedRows.clear()\n    this.pendingOrderedPublications.clear()\n    this.pendingInitialLoads.clear()\n    this.orderedPublicationFailed = false\n    this.lazySources.clear()\n    this.demand.clear()\n    this.builderDependencies.clear()\n    for (const loader of this.orderedLoaders.values()) loader.dispose()\n    this.orderedLoaders.clear()\n\n    // Clear mutable objects\n    for (const key of Object.keys(this.lazySourcesCallbacks)) {\n      delete this.lazySourcesCallbacks[key]\n    }\n    for (const key of Object.keys(this.optimizableOrderByCollections)) {\n      delete this.optimizableOrderByCollections[key]\n    }\n\n    // graph.run() keeps its own stack reference. The disposed guard prevents\n    // another step or new input; clearing our references does not destroy it.\n    this.graph = undefined\n    this.inputs = undefined\n    this.sourceWhereClauses = undefined\n  }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction getHandlerForEvent<TRow extends object, TKey extends string | number>(\n  event: DeltaEvent<TRow, TKey>,\n  config: EffectConfig<TRow, TKey>,\n): EffectEventHandler<TRow, TKey> | undefined {\n  switch (event.type) {\n    case `enter`:\n      return config.onEnter\n    case `exit`:\n      return config.onExit\n    case `update`:\n      return config.onUpdate\n  }\n}\n\n/**\n * Accumulate D2 output multiplicities into per-key effect changes.\n * Tracks both insert values (new) and delete values (old) separately\n * so that update and exit events can include previousValue.\n */\nfunction accumulateEffectChanges<T>(\n  acc: Map<unknown, EffectChanges<T>>,\n  [[key, tupleData], multiplicity]: [\n    [unknown, [any, string | undefined]],\n    number,\n  ],\n): Map<unknown, EffectChanges<T>> {\n  const [value] = tupleData as [T, string | undefined]\n\n  const changes: EffectChanges<T> = acc.get(key) || {\n    deletes: 0,\n    inserts: 0,\n  }\n\n  if (multiplicity < 0) {\n    changes.deletes += Math.abs(multiplicity)\n    // Keep only the first delete value — this is the pre-batch state\n    changes.deleteValue ??= value\n  } else if (multiplicity > 0) {\n    changes.inserts += multiplicity\n    // Always overwrite with the latest insert — this is the post-batch state\n    changes.insertValue = value\n  }\n\n  acc.set(key, changes)\n  return acc\n}\n\n/** Interpret a D2 batch against callback-visible state when a window holds it. */\nfunction classifyDelta<TRow extends object, TKey extends string | number>(\n  key: TKey,\n  changes: EffectChanges<TRow>,\n  publishedRows?: ReadonlyMap<unknown, TRow>,\n): DeltaEvent<TRow, TKey> | undefined {\n  const { inserts, deletes, insertValue, deleteValue } = changes\n  const wasPresent = publishedRows ? publishedRows.has(key) : deletes > 0\n  const previousValue = publishedRows?.get(key) ?? deleteValue\n  const isPresent = publishedRows\n    ? Number(wasPresent) + inserts - deletes > 0\n    : inserts > 0\n\n  if (!wasPresent && isPresent) {\n    // Row entered the query result\n    return { type: `enter`, key, value: insertValue! }\n  }\n\n  if (wasPresent && !isPresent) {\n    // Row exited the query result — value is the exiting value,\n    // previousValue is omitted (it would be identical to value)\n    return { type: `exit`, key, value: previousValue ?? deleteValue! }\n  }\n\n  if (\n    wasPresent &&\n    isPresent &&\n    insertValue !== undefined &&\n    (!publishedRows || !deepEquals(previousValue, insertValue))\n  ) {\n    // Row updated within the query result\n    return {\n      type: `update`,\n      key,\n      value: insertValue,\n      previousValue: previousValue!,\n    }\n  }\n\n  // The row was absent both before and after the held delta, or its final\n  // value is equal to the last callback-visible value.\n  return undefined\n}\n\n/** Track a promise in the in-flight set, automatically removing on settlement */\nfunction trackPromise(\n  promise: Promise<void>,\n  inFlightHandlers: Set<Promise<void>>,\n): void {\n  inFlightHandlers.add(promise)\n  const finish = () => {\n    inFlightHandlers.delete(promise)\n  }\n  void promise.then(finish, finish)\n}\n\n/** Report an error to the onError callback or console */\nfunction reportError<TRow extends object, TKey extends string | number>(\n  error: unknown,\n  event: DeltaEvent<TRow, TKey>,\n  onError?: (error: Error, event: DeltaEvent<TRow, TKey>) => void,\n): void {\n  const normalised = normalizeError(error)\n  if (onError) {\n    try {\n      onError(normalised, event)\n    } catch (onErrorError) {\n      // Don't let onError errors propagate\n      console.error(\n        devBuild() && process.env.NODE_ENV !== `production`\n          ? `[Effect] Error in onError handler:`\n          : codedMessage(224),\n        onErrorError,\n      )\n      console.error(\n        devBuild() && process.env.NODE_ENV !== `production`\n          ? `[Effect] Original error:`\n          : codedMessage(225),\n        normalised,\n      )\n    }\n  } else {\n    console.error(\n      devBuild() && process.env.NODE_ENV !== `production`\n        ? `[Effect] Unhandled error in handler:`\n        : codedMessage(226),\n      normalised,\n    )\n  }\n}\n"],"names":["devBuild","codedMessage","error","createDeferred","createSourceRecord","SubsetDemandController","orderedLoaders","pendingOrderedPublications","pendingInitialLoads","orderedPublicationFailed","sentToD2RowsBySource","pendingChanges","publishedRows","initialLoadComplete","reachedReady","builderDependencies","isGraphRunning","buildQueryFromConfig","extractCollectionFromSource","extractCollectionsFromQuery","collectionSources","extractCollectionSources","compilePipeline","D2","compileQuery","output","getCollectionBuilder","normalizeExpressionPaths","handleSourceChanges","isFailedStatus","buildSubscriptionOptions","normalizeError","trackInitialLoad","OrderedSourceLoader","trackOrderedPublication","canCompleteInitialLoad","latchReady","reportHealth","runGraph","splitUpdates","sendChangesToD2","scheduleQueryGraphRun","reconcileChangesForD2","sendChangesToInput","hasPendingJoinedFilterWork","sourcesPermitInitialReadiness","sourcePermitsInitialReadiness","healthTree","reportedTree","healthNode","buildHealthTree","computeSubscriptionOrderByHints","hasPendingJoinedSourceWork","runAllCallbacks","clearPipelineState","deepEquals"],"mappings":"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"}