{"version":3,"file":"lifecycle.cjs","sources":["../../../src/collection/lifecycle.ts"],"sourcesContent":["import {\n  CollectionInErrorStateError,\n  CollectionPreloadAbortedError,\n  CollectionStateError,\n  InvalidCollectionStatusTransitionError,\n} from '../errors'\nimport {\n  safeCancelIdleCallback,\n  safeRequestIdleCallback,\n} from '../utils/browser-polyfills'\nimport { runAllCallbacks } from '../utils/callbacks'\nimport { createDeferred } from '../deferred'\nimport { codedMessage, devBuild } from '../error-message'\nimport { isFailedStatus } from '../live-query-primitives.js'\nimport { CleanupQueue, cleanupNow } from './cleanup-queue'\nimport type { Deferred } from '../deferred'\nimport type { StandardSchemaV1 } from '@standard-schema/spec'\nimport type {\n  CollectionConfig,\n  CollectionErrorInfo,\n  CollectionStatus,\n  HealthProblem,\n} from '../types'\nimport type { CollectionEventsManager } from './events'\nimport type { CollectionIndexesManager } from './indexes'\nimport type { CollectionChangesManager } from './changes'\nimport type { CollectionSyncManager } from './sync'\nimport type { CollectionStateManager } from './state'\n\n/**\n * Floor applied to the GC delay of a collection that started syncing before\n * anything subscribed. Adapters build their live query while rendering and\n * subscribe when that render commits. This grace period reduces cleanup\n * during that gap; a later subscriber can still restart sync. Adapters pass\n * a near-zero `gcTime` to make teardown on unmount immediate. Does not apply\n * to the timer armed when the last subscriber leaves, which still honours\n * `gcTime` exactly.\n */\nexport const UNSUBSCRIBED_GC_FLOOR_MS = 50\n\n/** A Collection's gcTime when its config names none (5 minutes). */\nexport const DEFAULT_GC_TIME_MS = 300000\n\nexport class CollectionLifecycleManager<\n  TOutput extends object = Record<string, unknown>,\n  TKey extends string | number = string | number,\n  TSchema extends StandardSchemaV1 = StandardSchemaV1,\n  TInput extends object = TOutput,\n> {\n  private config: CollectionConfig<TOutput, TKey, TSchema, any>\n  private id: string\n  private indexes!: CollectionIndexesManager<TOutput, TKey, TSchema, TInput>\n  private events!: CollectionEventsManager\n  private changes!: CollectionChangesManager<TOutput, TKey, TSchema, TInput>\n  private sync!: CollectionSyncManager<TOutput, TKey, TSchema, TInput>\n  private state!: CollectionStateManager<TOutput, TKey, TSchema, TInput>\n\n  public status: CollectionStatus = `idle`\n  public hasBeenReady = false\n  public hasReceivedFirstCommit = false\n  private readyFailureSink: ((failure: { error: unknown }) => void) | undefined\n  public onFirstReadyCallbacks: Array<() => void> = []\n  private idleCallbackId: number | null = null\n  // After the first ready, the sync adapter's problem is health tree detail:\n  // `failureReason` while it still tries, `stoppedError` once it called fail().\n  // A live query's request failures are kept apart, so settling a request\n  // cannot clear the sync adapter's problem. The failure reason lists every\n  // reportError() of its sync run since it began.\n  private failureReason: HealthProblem | null = null\n  // A reload's new run reported the failure reason, so its completion keeps it.\n  private failureReasonFromReload = false\n  private stoppedError: HealthProblem | null = null\n  // The cause of status `error` or `crashed`, kept so readers see the same\n  // object until the sync run ends.\n  private statusError: HealthProblem | null = null\n  private requestErrors = new RequestErrors()\n  // A reload's new run reported the request errors, so its completion keeps\n  // them.\n  private requestErrorsFromReload = false\n  // fail() ends the sync adapter's reporting for its sync run; a reload or\n  // cleanup starts a new one.\n  private adapterStopped = false\n  // A reload's new sync run, until it completes or fails.\n  private reloadRun: Deferred<void> | undefined\n  // A reload is moving the Collection out of `error`.\n  private recovering = false\n  private gcGraceUntil = 0\n  private cleanupConfig: () => void\n  private statusRevision = 0\n  private cleaningUp = false\n  private cleanupPromise: Promise<void> | null = null\n  private readonly cleanupStartCallbacks = new Set<() => void>()\n\n  /**\n   * Creates a new CollectionLifecycleManager instance\n   */\n  constructor(\n    config: CollectionConfig<TOutput, TKey, TSchema, any>,\n    id: string,\n    cleanupConfig: () => void = () => {},\n  ) {\n    this.config = config\n    this.id = id\n    this.cleanupConfig = cleanupConfig\n  }\n\n  setDeps(deps: {\n    indexes: CollectionIndexesManager<TOutput, TKey, TSchema, TInput>\n    events: CollectionEventsManager\n    changes: CollectionChangesManager<TOutput, TKey, TSchema, TInput>\n    sync: CollectionSyncManager<TOutput, TKey, TSchema, TInput>\n    state: CollectionStateManager<TOutput, TKey, TSchema, TInput>\n  }) {\n    this.indexes = deps.indexes\n    this.events = deps.events\n    this.changes = deps.changes\n    this.sync = deps.sync\n    this.state = deps.state\n  }\n\n  /**\n   * Validates state transitions to prevent invalid status changes\n   */\n  public validateStatusTransition(\n    from: CollectionStatus,\n    to: CollectionStatus,\n  ): void {\n    if (from === to) {\n      // Allow same state transitions\n      return\n    }\n    const validTransitions: Record<\n      CollectionStatus,\n      Array<CollectionStatus>\n    > = {\n      idle: [`loading`, `error`, `crashed`, `cleaned-up`],\n      loading: [`ready`, `error`, `crashed`, `cleaned-up`],\n      // After the first ready only a crash changes the status; a sync\n      // problem is health tree detail.\n      ready: [`cleaned-up`, `crashed`],\n      // A failed first load is final for its sync run. Only a reload leaves\n      // it for `ready` (see `recovering`).\n      error: [`cleaned-up`, `idle`, `crashed`],\n      // Nothing recovers a crash in place; only cleanup leaves it.\n      crashed: [`cleaned-up`],\n      'cleaned-up': [`loading`, `error`, `crashed`],\n    }\n\n    if (\n      !validTransitions[from].includes(to) &&\n      !(this.recovering && from === `error` && to === `ready`)\n    ) {\n      throw new InvalidCollectionStatusTransitionError(from, to, this.id)\n    }\n  }\n\n  /**\n   * Safely update the collection status with validation\n   * @private\n   */\n  public setStatus(\n    newStatus: CollectionStatus,\n    allowReady: boolean = false,\n    beforeEmit?: () => void,\n  ): void {\n    if (newStatus === `ready` && !allowReady) {\n      // setStatus('ready') is an internal method that should not be called directly\n      // Instead, use markReady to transition to ready triggering the necessary events\n      // and side effects.\n      throw new CollectionStateError(\n        devBuild() && process.env.NODE_ENV !== `production`\n          ? `You can't directly call \"setStatus('ready'). You must use markReady instead.`\n          : codedMessage(208),\n      )\n    }\n    this.validateStatusTransition(this.status, newStatus)\n    // Only an actual replacement run transfers later cleanup to a new run.\n    // Validation, deferred requests and failed admission retain the old promise.\n    if (newStatus === `loading`) this.cleanupPromise = null\n    const revision = ++this.statusRevision\n    const previousStatus = this.status\n    this.status = newStatus\n    beforeEmit?.()\n\n    // Emit event\n    const isCurrent = () => this.statusRevision === revision\n    this.events.emitStatusChange(newStatus, previousStatus, isCurrent)\n    // The status is part of the health tree. status:change fires first, and\n    // the tree is already current when either event fires.\n    if (isCurrent()) this.events.emitHealthChange()\n  }\n\n  /**\n   * Validates that the collection is in a usable state for data operations\n   * @private\n   */\n  public validateCollectionUsable(operation: string): void {\n    switch (this.status) {\n      case `error`:\n      case `crashed`:\n        throw new CollectionInErrorStateError(operation, this.id)\n      case `cleaned-up`:\n        // Automatically restart the collection when operations are called on cleaned-up collections\n        this.sync.startSync()\n        break\n    }\n  }\n\n  /**\n   * Mark the collection as ready for use\n   * This is called by sync implementations to explicitly signal that the collection is ready,\n   * providing a more intuitive alternative to using commits for readiness signaling\n   * @private - Should only be called by sync implementations\n   *\n   * `beforeEffects` runs after the status reads `ready` and before status\n   * listeners and ready callbacks, so their writes follow it.\n   */\n  public markReady(beforeEffects?: () => void): void {\n    // A crash ended the sync run from core's side, and fail() from the\n    // adapter's: after either, and once the run is ready, markReady() does\n    // nothing.\n    if (this.status === `crashed` || this.adapterStopped) return\n    // A reload's new run is ready: the reload completes.\n    if (this.reloadRun) {\n      this.completeReload(beforeEffects)\n      return\n    }\n    const failure = this.applyReadyTransition(beforeEffects)\n    if (!failure) return\n    if (this.readyFailureSink) this.readyFailureSink(failure)\n    else throw failure.error\n  }\n\n  /**\n   * @internal Hold ready-effect failures while a sync function runs, whether\n   * it calls markReady or commits a truncate. The returned function stops\n   * holding them and returns the first one.\n   */\n  public deferReadyFailures(): () => { error: unknown } | undefined {\n    let first: { error: unknown } | undefined\n    this.readyFailureSink = (failure) => {\n      first ??= failure\n    }\n    return () => {\n      this.readyFailureSink = undefined\n      return first\n    }\n  }\n\n  private applyReadyTransition(\n    beforeEffects?: () => void,\n  ): { error: unknown } | undefined {\n    this.validateStatusTransition(this.status, `ready`)\n    // A successful initial sync establishes a ready snapshot, as does a\n    // reload of a failed first load.\n    if (this.status === `loading` || this.status === `error`) {\n      const readyRevision = this.statusRevision + 1\n      this.setStatus(`ready`, true, beforeEffects)\n\n      // A status listener can synchronously supersede this transition, even\n      // when it restarts the Collection back to ready before returning.\n      if (\n        (this.status as CollectionStatus) !== `ready` ||\n        this.statusRevision !== readyRevision\n      ) {\n        return undefined\n      }\n\n      const readyEffects: Array<() => void> = []\n\n      // Call any registered first ready callbacks (only on first time becoming ready)\n      if (!this.hasBeenReady) {\n        this.hasBeenReady = true\n\n        // Also mark as having received first commit for backwards compatibility\n        this.hasReceivedFirstCommit = true\n\n        readyEffects.push(...this.onFirstReadyCallbacks)\n        this.onFirstReadyCallbacks = []\n      }\n      // Notify dependents when markReady is called, after status is set\n      // This ensures live queries get notified when their dependencies become ready\n      readyEffects.push(() => this.changes.emitEmptyReadyEvent())\n      try {\n        runAllCallbacks(readyEffects)\n      } catch (error) {\n        return { error }\n      }\n    }\n    return undefined\n  }\n\n  /**\n   * The sync adapter stopped. Before the first ready this fails the sync\n   * run's first load; after it, the rows stay and the error shows until a\n   * reload. A second fail() in the same sync run changes nothing: the adapter\n   * already stopped, and the first error stays.\n   */\n  public fail(error: unknown): void {\n    if (this.status === `crashed` || this.adapterStopped) return\n    this.adapterStopped = true\n    const reload = this.reloadRun\n    this.reloadRun = undefined\n    if (this.status === `ready`) {\n      // The rows stay; a reload that failed shows its new error instead.\n      this.failureReason = null\n      this.stoppedError = problemOf([describeProblem(error)])\n      this.events.emitHealthChange()\n    } else if (reload && this.status === `error`) {\n      // A reload of a failed first load keeps status `error` with the new\n      // cause.\n      this.statusError = problemOf([describeProblem(error)])\n      this.events.emitHealthChange()\n    } else {\n      this.validateStatusTransition(this.status, `error`)\n      this.statusError = problemOf([describeProblem(error)])\n      this.setStatus(`error`)\n    }\n    reload?.reject(error)\n  }\n\n  /** Whether the current sync run's adapter called `fail()`. */\n  public get stoppedThisRun(): boolean {\n    return this.adapterStopped\n  }\n\n  /**\n   * Whether the current sync run is in its first load: `loading`, or a reload\n   * of a failed first load that is not ready yet. A failure now fails that\n   * first load.\n   */\n  public get inFirstLoad(): boolean {\n    return (\n      this.status === `loading` || (this.reloading && this.status === `error`)\n    )\n  }\n\n  /** Whether a reload's new sync run is in flight. */\n  public get reloading(): boolean {\n    return this.reloadRun !== undefined\n  }\n\n  /**\n   * A reload starts a new sync run while everything visible stays: the rows,\n   * the status, and the current problem. The node shows `reloading`.\n   */\n  public beginReload(): Promise<void> {\n    if (this.reloadRun) return this.reloadRun.promise\n    const run = createDeferred<void>()\n    void run.promise.catch(() => undefined)\n    this.reloadRun = run\n    this.failureReasonFromReload = false\n    this.requestErrorsFromReload = false\n    this.adapterStopped = false\n    this.events.emitHealthChange()\n    return run.promise\n  }\n\n  /**\n   * The reload's new run replaced the rows with a snapshot or a truncate, or\n   * marked ready: the retired run's problems clear, the new run's stay, and a\n   * failed first load becomes ready.\n   */\n  public completeReload(beforeEffects?: () => void): void {\n    const run = this.reloadRun\n    if (!run) return\n    this.reloadRun = undefined\n    if (!this.failureReasonFromReload) this.failureReason = null\n    this.stoppedError = null\n    if (!this.requestErrorsFromReload) this.requestErrors = new RequestErrors()\n    if (this.status === `ready`) this.events.emitHealthChange()\n    else {\n      // A failed first load, or a reload during the first load, becomes\n      // ready with the new run's rows.\n      this.statusError = null\n      this.recovering = true\n      try {\n        this.markReady(beforeEffects)\n      } catch (error) {\n        // A ready callback that throws reaches the adapter's markReady(); the\n        // reload succeeded once the status is ready.\n        if ((this.status as CollectionStatus) === `ready`) run.resolve()\n        else run.reject(error)\n        throw error\n      } finally {\n        this.recovering = false\n      }\n    }\n    run.resolve()\n  }\n\n  /** A reload retired the sync run; subscriptions detach its demand. */\n  public retireSubscriptionDemand(): void {\n    for (const subscription of [...this.changes.changeSubscriptions])\n      subscription.retireSyncRun()\n  }\n\n  /** The reload ended without a commit, for example by cleanup. */\n  public abandonReload(error: unknown): void {\n    if (!this.endReload(error)) return\n    if (this.status !== `cleaned-up`) this.events.emitHealthChange()\n  }\n\n  private endReload(error: unknown): boolean {\n    const run = this.reloadRun\n    if (!run) return false\n    this.reloadRun = undefined\n    run.reject(error)\n    return true\n  }\n\n  /**\n   * Local storage or an internal invariant broke. The Collection can no\n   * longer serve reads or accept writes, from any active status. Nothing\n   * recovers a crash in place: only cleanup, which discards all state, leaves\n   * it.\n   */\n  public crash(error?: unknown): void {\n    if (this.status === `crashed`) return\n    this.validateStatusTransition(this.status, `crashed`)\n    // A crash ends a reload in flight with it; its status change announces\n    // the tree.\n    this.endReload(error)\n    this.statusError = problemOf([describeProblem(error)])\n    this.setStatus(`crashed`)\n  }\n\n  /** The Collection's own problems, as health tree detail. */\n  public get problems(): {\n    failureReason: HealthProblem | null\n    error: HealthProblem | null\n  } {\n    const error = isFailedStatus(this.status)\n      ? this.statusError\n      : (this.stoppedError ?? this.requestErrors.problem)\n    return { failureReason: error ? null : this.failureReason, error }\n  }\n\n  /** The cause of status `error` or `crashed`, as health tree detail. */\n  public get statusProblem(): HealthProblem | null {\n    return isFailedStatus(this.status) ? this.statusError : null\n  }\n\n  /** The sync adapter still tries after a problem. Status and rows do not change. */\n  public reportError(error: unknown): void {\n    if (this.status === `crashed`) return\n    this.assertAdapterActive(`reportError`)\n    this.assertReady(`reportError`)\n    // A reload's new run that reports starts its own list: the retired run's\n    // failures leave with that run.\n    const kept =\n      this.reloading && !this.failureReasonFromReload\n        ? []\n        : (this.failureReason?.errors ?? [])\n    // One error value is one failure: one already listed is still open, so\n    // it keeps its place and its `at`, and nothing changes.\n    if (kept.some((failure) => failure.cause === error)) return\n    this.failureReason = problemOf([...kept, describeProblem(error)])\n    this.failureReasonFromReload = this.reloading\n    this.events.emitHealthChange()\n  }\n\n  /**\n   * The source synced successfully again. With no error it clears the\n   * failure reason; with one it removes the failure whose cause is that\n   * value, and the failure reason clears once none is left. With nothing to\n   * remove it does nothing. `undefined` is no error: it clears every\n   * failure, also one that `reportError(undefined)` listed.\n   */\n  public reportHealthy(error?: unknown): void {\n    if (this.status === `crashed`) return\n    this.assertAdapterActive(`reportHealthy`)\n    this.assertReady(`reportHealthy`)\n    const listed = this.failureReason?.errors ?? []\n    const open =\n      error === undefined\n        ? []\n        : listed.filter((failure) => failure.cause !== error)\n    if (open.length === listed.length) return\n    this.failureReason = open.length > 0 ? problemOf(open) : null\n    this.events.emitHealthChange()\n  }\n\n  /**\n   * @internal A live query's request failed after initial-query readiness,\n   * with each of its failures in failure order.\n   */\n  public reportRequestError(key: string, errors: Array<unknown>): void {\n    // A reload's new run that reports starts its own list: the retired run's\n    // request errors leave with that run.\n    if (this.reloading && !this.requestErrorsFromReload) {\n      this.requestErrors = new RequestErrors()\n      this.requestErrorsFromReload = true\n    }\n    if (this.requestErrors.fail(key, errors)) this.events.emitHealthChange()\n  }\n\n  /** @internal The failed request settled or was released. */\n  public clearRequestError(key: string): void {\n    if (this.requestErrors.settle(key)) this.events.emitHealthChange()\n  }\n\n  /** fail() ends the sync adapter's reporting for its sync run. */\n  private assertAdapterActive(operation: string): void {\n    if (this.adapterStopped) {\n      throw new CollectionStateError(\n        devBuild() && process.env.NODE_ENV !== `production`\n          ? `${operation}() was called after fail() in the same sync run of Collection \"${this.id}\". fail() means the sync adapter stopped; a reload starts a new sync run.`\n          : codedMessage(259, { operation, id: this.id }),\n      )\n    }\n  }\n\n  private assertReady(operation: string): void {\n    if (this.status !== `ready`) {\n      throw new CollectionStateError(\n        devBuild() && process.env.NODE_ENV !== `production`\n          ? `${operation}() reports on sync after the first ready, but Collection \"${this.id}\" is ${this.status}. Before the first ready, retry without reporting, or call fail() when the sync adapter stops.`\n          : codedMessage(257, { operation, id: this.id, status: this.status }),\n      )\n    }\n  }\n\n  /** Return the cause of status `error` or `crashed` in this sync run, if any. */\n  public getSyncError(): unknown {\n    return this.statusError?.cause\n  }\n\n  /** Cleanup discards the current projection until a new sync run starts. */\n  public hasStartedCleanup(): boolean {\n    return this.cleaningUp || this.status === `cleaned-up`\n  }\n\n  public assertCanStartSync(): void {\n    if (this.cleaningUp) {\n      throw new CollectionStateError(\n        devBuild() && process.env.NODE_ENV !== `production`\n          ? `Cannot start collection \"${this.id}\" during cleanup. Restart after cleanup() completes.`\n          : codedMessage(209, { id: this.id }),\n      )\n    }\n  }\n\n  public isCleaningUp(): boolean {\n    return this.cleaningUp\n  }\n\n  /**\n   * Observe the synchronous start of cleanup without treating it as terminal\n   * resource settlement. Internal dependents use this to retire work before\n   * an asynchronous adapter cleanup publishes `cleaned-up`.\n   */\n  public onCleanupStart(callback: () => void): () => void {\n    this.cleanupStartCallbacks.add(callback)\n    if (this.cleaningUp) {\n      try {\n        callback()\n      } catch (error) {\n        // Registration did not return its ownership handle. Do not retain an\n        // observer that its caller has no way to unsubscribe.\n        this.cleanupStartCallbacks.delete(callback)\n        throw error\n      }\n    }\n    return () => this.cleanupStartCallbacks.delete(callback)\n  }\n\n  /**\n   * Start the garbage collection timer for a collection with no subscribers\n   * Called when sync starts outside a subscription\n   */\n  public startGCTimerIfUnsubscribed(): void {\n    this.gcGraceUntil = cleanupNow() + UNSUBSCRIBED_GC_FLOOR_MS\n    this.startGCTimer(true)\n  }\n\n  // A persisting transaction holds the Collection: collecting it would drop\n  // the rows the transaction shows and end the sync run its handler may wait on.\n  private canGarbageCollect(): boolean {\n    return (\n      !this.cleaningUp &&\n      this.changes.activeSubscribersCount === 0 &&\n      !this.sync.hasPendingPreload &&\n      !this.state.hasPersistingTransaction()\n    )\n  }\n\n  /**\n   * Renew inactive retention. Settlement keeps the remaining startup/preload\n   * handoff; a real last unsubscribe clears it and uses gcTime exactly.\n   */\n  public startGCTimer(preserveHandoff = false): void {\n    if (!preserveHandoff) this.gcGraceUntil = 0\n    if (this.status === `idle` || this.status === `cleaned-up`) return\n    this.cancelGCTimer()\n    if (!this.canGarbageCollect()) return\n\n    const gcTime = this.config.gcTime ?? DEFAULT_GC_TIME_MS\n\n    // If gcTime is 0, negative, or non-finite (Infinity, -Infinity, NaN), GC is disabled.\n    // Note: setTimeout with Infinity coerces to 0 via ToInt32, causing immediate GC,\n    // so we must explicitly check for non-finite values here.\n    if (gcTime <= 0 || !Number.isFinite(gcTime)) {\n      return\n    }\n\n    CleanupQueue.getInstance().schedule(\n      this,\n      Math.max(gcTime, this.gcGraceUntil - cleanupNow()),\n      () => {\n        if (this.canGarbageCollect()) {\n          // Schedule cleanup during idle time to avoid blocking the UI thread\n          this.scheduleIdleCleanup()\n        }\n      },\n    )\n  }\n\n  /**\n   * Cancel the garbage collection timer\n   * Called when the collection becomes active again\n   */\n  public cancelGCTimer(): void {\n    CleanupQueue.getInstance().cancel(this)\n    // Also cancel any pending idle cleanup\n    if (this.idleCallbackId !== null) {\n      safeCancelIdleCallback(this.idleCallbackId)\n      this.idleCallbackId = null\n    }\n  }\n\n  /**\n   * Schedule cleanup to run during browser idle time\n   * This prevents blocking the UI thread during cleanup operations\n   */\n  private scheduleIdleCleanup(): void {\n    // Cancel any existing idle callback\n    if (this.idleCallbackId !== null) {\n      safeCancelIdleCallback(this.idleCallbackId)\n    }\n\n    // Schedule cleanup with a timeout of 1 second\n    // This ensures cleanup happens even if the browser is busy\n    this.idleCallbackId = safeRequestIdleCallback(\n      (deadline) => {\n        // Keep the callback ID only when cleanup schedules another idle period.\n        if (this.canGarbageCollect()) {\n          if (!(deadline.timeRemaining() > 0 || deadline.didTimeout)) {\n            this.scheduleIdleCleanup()\n            return\n          }\n          // Automatic GC has no caller to receive cleanup rejection. Core still\n          // finalizes the lifecycle; explicit cleanup returns adapter diagnostics.\n          void this.beginCleanup().catch(() => undefined)\n        }\n        this.idleCallbackId = null\n      },\n      { timeout: 1000 },\n    )\n  }\n\n  private beginCleanup(): Promise<void> {\n    if (this.cleanupPromise) return this.cleanupPromise\n\n    const completion = createDeferred<void>()\n    this.cleanupPromise = completion.promise\n    this.cleaningUp = true\n    const localFailures: Array<unknown> = []\n    let synchronousSyncFailure: { error: unknown } | undefined\n    let syncCleanupComplete = true\n\n    const attempt = (callback: () => void): void => {\n      try {\n        callback()\n      } catch (error) {\n        localFailures.push(error)\n      }\n    }\n\n    // Dependents must stop using the discarded sync run immediately, while\n    // the public status and cleanup promise still wait for adapter settlement.\n    for (const callback of [...this.cleanupStartCallbacks]) {\n      attempt(callback)\n    }\n\n    const finish = (syncFailure?: { error: unknown }) => {\n      // Sync cleanup either completes synchronously or calls this once after\n      // its promise settles. Reentrant callers share cleanupPromise above.\n      this.cleaningUp = false\n      this.statusError = null\n      attempt(() => this.setStatus(`cleaned-up`))\n\n      // Active collection subscriptions still depend on lifecycle events.\n      // Once the last subscriber leaves, its GC cleanup clears the handlers.\n      if (this.changes.activeSubscribersCount === 0) {\n        attempt(() => this.events.cleanup())\n      }\n\n      // Keep cleanup observably asynchronous even when every release is\n      // synchronous. Existing callers may use this turn to let optimistic\n      // settlement finish before starting the next operation.\n      const failures = syncFailure\n        ? [syncFailure.error, ...localFailures]\n        : localFailures\n      const failure =\n        failures.length === 0\n          ? undefined\n          : {\n              error:\n                failures.length === 1\n                  ? failures[0]\n                  : new AggregateError(\n                      failures,\n                      devBuild() && process.env.NODE_ENV !== `production`\n                        ? syncFailure\n                          ? `Adapter cleanup and local teardown both failed`\n                          : `Multiple local teardown steps failed`\n                        : codedMessage(173, {\n                            syncFailure: syncFailure !== undefined,\n                          }),\n                      { cause: failures[0] },\n                    ),\n            }\n      void Promise.resolve()\n        .then(() => Promise.resolve())\n        .then(() => {\n          if (this.cleanupPromise === completion.promise) {\n            this.cleanupPromise = null\n          }\n          if (failure) completion.reject(failure.error)\n          else completion.resolve()\n        })\n    }\n\n    // Sync cleanup invalidates the sync run before invoking the adapter. The\n    // remaining managers retire their local state synchronously while the\n    // adapter's resource-release promise is pending.\n    attempt(() => this.cleanupConfig())\n    try {\n      syncCleanupComplete = this.sync.cleanup(finish)\n    } catch (error) {\n      synchronousSyncFailure = { error }\n    }\n\n    attempt(() => this.state.cleanup())\n    attempt(() => this.changes.cleanup())\n    attempt(() => this.indexes.cleanup())\n    this.hasBeenReady = false\n    // Problems belong to the discarded sync run. The cause of a `crashed` or\n    // `error` status stays while that status shows; finish() clears it.\n    const before = this.problems\n    const reloading = this.reloading\n    this.adapterStopped = false\n    this.failureReason = null\n    this.stoppedError = null\n    this.requestErrors = new RequestErrors()\n    // An abandoned reload announces the tree; otherwise announce dropped\n    // problems here, since the status changes only when cleanup settles.\n    this.abandonReload(new CollectionPreloadAbortedError())\n    const after = this.problems\n    if (\n      !reloading &&\n      (before.error !== after.error ||\n        before.failureReason !== after.failureReason)\n    )\n      this.events.emitHealthChange()\n    // Cleanup is not readiness. Sync cleanup rejects pending preload callers;\n    // first-ready listeners belong to the discarded run.\n    this.onFirstReadyCallbacks = []\n\n    if (syncCleanupComplete) finish(synchronousSyncFailure)\n    return completion.promise\n  }\n\n  /**\n   * Register a callback to be executed when the collection first becomes ready\n   * Useful for preloading collections\n   * @param callback Function to call when the collection first becomes ready\n   */\n  public onFirstReady(callback: () => void): () => void {\n    // If already ready, call immediately\n    if (this.hasBeenReady) {\n      callback()\n      return () => {}\n    }\n\n    this.onFirstReadyCallbacks.push(callback)\n    return () => {\n      const index = this.onFirstReadyCallbacks.indexOf(callback)\n      if (index !== -1) {\n        this.onFirstReadyCallbacks.splice(index, 1)\n      }\n    }\n  }\n\n  public cleanup(): Promise<void> {\n    this.cancelGCTimer()\n\n    // Return this exact retirement operation even if an event listener starts\n    // a replacement run and cleanup while the first promise is still pending.\n    return this.beginCleanup()\n  }\n}\n\n/** @internal Requests that failed after initial-query readiness, by issuer. */\nexport class RequestErrors {\n  // Each failed request's errors.\n  private readonly failed = new Map<string, Array<unknown>>()\n  // Each failure still failing, by its error, with how many failed requests\n  // list it. Two requests that failed with one error share one failure, and\n  // it keeps its place among the failures: insertion order is failure order.\n  private readonly open = new Map<\n    unknown,\n    { failure: CollectionErrorInfo; requests: number }\n  >()\n  problem: HealthProblem | null = null\n\n  /** Returns whether the problem changed. */\n  fail(key: string, errors: Array<unknown>): boolean {\n    // The request's failures count before its earlier ones leave, so a\n    // failure it lists again stays open: it keeps its place and its `at`.\n    let changed = false\n    for (const error of errors) {\n      const entry = this.open.get(error)\n      if (entry) entry.requests++\n      else {\n        this.open.set(error, { failure: describeProblem(error), requests: 1 })\n        changed = true\n      }\n    }\n    changed = this.release(key) || changed\n    this.failed.set(key, errors)\n    return changed && this.show()\n  }\n\n  /** Returns whether the problem changed. */\n  settle(key: string): boolean {\n    return this.release(key) && this.show()\n  }\n\n  // Removes a request's failures; returns whether one stopped failing.\n  private release(key: string): boolean {\n    let changed = false\n    for (const error of this.failed.get(key) ?? []) {\n      const entry = this.open.get(error)!\n      if (--entry.requests === 0) changed = this.open.delete(error)\n    }\n    this.failed.delete(key)\n    return changed\n  }\n\n  // The newest failure still failing shows, and the problem lists every\n  // failure still failing, oldest first. It is a new object only when that\n  // list changed.\n  private show(): true {\n    const errors = Array.from(this.open.values(), ({ failure }) => failure)\n    this.problem = errors.length > 0 ? problemOf(errors) : null\n    return true\n  }\n}\n\n/**\n * @internal A health problem: its newest failure's fields, with every\n * failure of its frame listed, oldest first.\n */\nexport function problemOf(\n  errors: ReadonlyArray<CollectionErrorInfo>,\n): HealthProblem {\n  const newest = errors[errors.length - 1]!\n  return withCause({ ...newest, errors }, newest.cause)\n}\n\n// The original value stays available but out of JSON.\nfunction withCause<T extends object>(\n  info: T,\n  cause: unknown,\n): T & { cause: unknown } {\n  return Object.defineProperty(info, `cause`, {\n    value: cause,\n    enumerable: false,\n  }) as T & { cause: unknown }\n}\n\n/** @internal Health tree detail for a problem value. */\nexport function describeProblem(error: unknown): CollectionErrorInfo {\n  // Any value can be a problem. One that cannot describe itself, such as an\n  // object without a prototype or a throwing getter, keeps what was read.\n  let name = `Error`\n  let message = `Collection is in an error state`\n  let code: unknown\n  try {\n    if (error instanceof Error) {\n      name = error.name\n      message = error.message\n    } else if (error !== undefined) message = String(error)\n    code = (error as { code?: unknown } | null)?.code\n  } catch {\n    // The problem still shows, with the generic parts.\n  }\n  return withCause(\n    {\n      name,\n      message,\n      ...(typeof code === `string` ? { code } : {}),\n      at: Date.now(),\n    },\n    error,\n  )\n}\n"],"names":["idleCallbackId","failureReasonFromReload","stoppedError","statusError","requestErrors","requestErrorsFromReload","adapterStopped","recovering","gcGraceUntil","statusRevision","cleaningUp","cleanupPromise","cleanupStartCallbacks","cleanupConfig","InvalidCollectionStatusTransitionError","CollectionStateError","devBuild","codedMessage","CollectionInErrorStateError","reloadRun","applyReadyTransition","readyFailureSink","runAllCallbacks","createDeferred","endReload","isFailedStatus","assertAdapterActive","assertReady","errors","cleanupNow","canGarbageCollect","CleanupQueue","scheduleIdleCleanup","safeCancelIdleCallback","safeRequestIdleCallback","beginCleanup","CollectionPreloadAbortedError","show"],"mappings":"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"}