{"version":3,"file":"live-query-window-controller.cjs","sources":["../../src/live-query-window-controller.ts"],"sourcesContent":["import {\n  LiveQueryWindowControllerDisposedError,\n  SetWindowRequiresOrderByError,\n} from './errors.js'\nimport {\n  getLiveQueryStatusFlags,\n  isCollection,\n  isSingleResultCollection,\n} from './live-query-adapter.js'\nimport { createLiveQueryObserver } from './live-query-observer.js'\nimport { BaseQueryBuilder } from './query/builder/index.js'\nimport { deepEquals } from './utils.js'\nimport type {\n  LiveQueryObserver,\n  LiveQuerySnapshot,\n} from './live-query-observer.js'\nimport type { Collection } from './collection/index.js'\nimport type { CollectionStatus } from './types.js'\nimport type {\n  Context,\n  InitialQueryBuilder,\n  QueryBuilder,\n} from './query/builder/index.js'\n\nconst DEFAULT_PAGE_SIZE = 20\n\nexport type LiveQueryWindowInputKind = `collection` | `query`\n\n/** @internal The supported, enabled input forms for infinite-query adapters. */\nexport type ResolvedLiveQueryWindowInput<TContext extends Context> =\n  | { kind: `collection`; collection: Collection<any, any, any> }\n  | { kind: `query`; query: QueryBuilder<TContext> }\n\n/**\n * Classify an infinite-query input without invoking its query callback.\n * Frameworks use this during lifecycle comparison so unchanged React renders\n * do not execute the callback again.\n *\n * @internal This contract is unstable while RFC #1623 is being implemented.\n */\nexport function getLiveQueryWindowInputKind(\n  input: unknown,\n): LiveQueryWindowInputKind {\n  if (isCollection(input)) return `collection`\n  if (typeof input === `function`) return `query`\n  throw new Error(\n    `useLiveInfiniteQuery: First argument must be either a pre-created live query collection or a query function. ` +\n      `Received: ${typeof input}`,\n  )\n}\n\n/**\n * Resolve a supported infinite-query input and invoke a query callback once.\n * A function may resolve to a collection for framework getter compatibility.\n * Nullable/disabled and config-object inputs are intentionally not supported.\n *\n * @internal This contract is unstable while RFC #1623 is being implemented.\n */\nexport function resolveLiveQueryWindowInput<TContext extends Context>(\n  input: unknown,\n): ResolvedLiveQueryWindowInput<TContext> {\n  if (getLiveQueryWindowInputKind(input) === `collection`) {\n    return {\n      kind: `collection`,\n      collection: input as Collection<any, any, any>,\n    }\n  }\n\n  const value = (\n    input as (q: InitialQueryBuilder) => QueryBuilder<TContext> | unknown\n  )(new BaseQueryBuilder() as InitialQueryBuilder)\n  if (isCollection(value)) {\n    return { kind: `collection`, collection: value }\n  }\n  if (\n    typeof value !== `object` ||\n    value === null ||\n    typeof (value as { limit?: unknown }).limit !== `function` ||\n    typeof (value as { offset?: unknown }).offset !== `function`\n  ) {\n    throw new Error(\n      `useLiveInfiniteQuery: Query function must return a query builder. ` +\n        `Disabled null or undefined queries are not supported.`,\n    )\n  }\n  return { kind: `query`, query: value as QueryBuilder<TContext> }\n}\n\n/** @internal This contract is unstable while RFC #1623 is being implemented. */\nexport function normalizeLiveQueryWindowPageSize(\n  pageSize: number | undefined,\n): number {\n  if (\n    pageSize === undefined ||\n    !Number.isSafeInteger(pageSize) ||\n    pageSize <= 0 ||\n    pageSize >= Number.MAX_SAFE_INTEGER\n  ) {\n    return DEFAULT_PAGE_SIZE\n  }\n  return pageSize\n}\n\ntype WindowResult = true | Promise<void>\n\ntype LiveQueryWindow = { offset: number; limit: number }\n\n/** @internal Shared adapter view of a collection with an ordered window. */\nexport type LiveQueryWindowCollection = Collection<any, any, any> & {\n  utils: {\n    setWindow: (options: LiveQueryWindow) => WindowResult\n    getWindow: () => LiveQueryWindow | undefined\n  }\n}\n\ntype WindowTarget = object & {\n  utils?: {\n    setWindow?: (options: { offset: number; limit: number }) => WindowResult\n    getWindow?: () => { offset: number; limit: number } | undefined\n  }\n}\n\ntype PendingWindow = {\n  generation: number\n  limit: number\n  promise: Promise<void>\n}\n\nclass WindowCoordinator {\n  private readonly leases = new Map<symbol, number>()\n  private readonly leaseVersions = new Map<symbol, number>()\n  private baselineWindow: { offset: number; limit: number } | undefined\n  private retainedWindow: { offset: number; limit: number } | undefined\n  private shouldCaptureBaseline = true\n  private appliedLimit: number | undefined\n  private pending: PendingWindow | undefined\n  private generation = 0\n  private leaseVersion = 0\n\n  constructor(private readonly target: WindowTarget) {}\n\n  request(lease: symbol, limit: number): WindowResult {\n    if (this.leases.size === 0) {\n      const currentWindow = this.target.utils?.getWindow?.()\n      const retainedWindowChanged =\n        this.retainedWindow !== undefined &&\n        (currentWindow?.offset !== this.retainedWindow.offset ||\n          currentWindow.limit !== this.retainedWindow.limit)\n      if (this.shouldCaptureBaseline || retainedWindowChanged) {\n        this.baselineWindow = currentWindow\n        this.shouldCaptureBaseline = false\n      }\n      this.retainedWindow = undefined\n    }\n    const previousLimit = this.leases.get(lease)\n    const previousVersion = this.leaseVersions.get(lease)\n    const version = ++this.leaseVersion\n    this.leases.set(lease, limit)\n    this.leaseVersions.set(lease, version)\n\n    let result: WindowResult\n    try {\n      result = this.applyDesiredWindow()\n    } catch (error) {\n      this.rollbackLease(lease, version, previousLimit, previousVersion)\n      this.appliedLimit = undefined\n      if (this.leases.size === 0) this.shouldCaptureBaseline = true\n      throw error\n    }\n\n    if (result === true) return true\n    return result.catch(async (error: unknown) => {\n      if (this.rollbackLease(lease, version, previousLimit, previousVersion)) {\n        this.generation++\n        this.pending = undefined\n        this.appliedLimit = undefined\n        try {\n          if (this.leases.size === 0) {\n            this.restoreInitialWindow()\n          } else {\n            const rollback = this.applyDesiredWindow()\n            if (rollback !== true) await rollback\n          }\n        } catch {\n          // Preserve the failure from the requested window.\n        }\n      }\n      throw error\n    })\n  }\n\n  getLeaseResult(lease: symbol, minimumLimit: number): WindowResult | false {\n    const limit = this.leases.get(lease)\n    if (limit === undefined || limit < minimumLimit) return false\n    const desiredLimit = this.getDesiredLimit()\n    // getWindow reports settled state; the current lease may still be loading.\n    if (this.pending && this.pending.limit === desiredLimit)\n      return this.pending.promise\n    const currentWindow = this.target.utils?.getWindow?.()\n    return (\n      currentWindow === undefined ||\n      (currentWindow.offset === 0 && currentWindow.limit === desiredLimit)\n    )\n  }\n\n  hasLeases(): boolean {\n    return this.leases.size > 0\n  }\n\n  release(lease: symbol, restoreWhenEmpty: boolean): void {\n    if (!this.leases.delete(lease)) return\n    this.leaseVersions.delete(lease)\n\n    // A pending request may still mutate the physical operator, but it no longer\n    // establishes the accepted window for the remaining lease set.\n    this.generation++\n    this.pending = undefined\n    this.appliedLimit = undefined\n\n    if (this.leases.size === 0) {\n      if (restoreWhenEmpty) {\n        this.restoreInitialWindow()\n      } else {\n        this.retainedWindow = this.target.utils?.getWindow?.()\n      }\n      return\n    }\n\n    try {\n      const result = this.applyDesiredWindow()\n      if (result !== true) {\n        void result.catch(() => {\n          // Unsubscribe has no async error channel. Leave the physical window\n          // unaccepted so the next request retries it.\n          this.appliedLimit = undefined\n        })\n      }\n    } catch {\n      // The remaining controller will retry on its next request.\n      this.appliedLimit = undefined\n    }\n  }\n\n  private getDesiredLimit(): number | undefined {\n    let desired: number | undefined\n    for (const limit of this.leases.values()) {\n      desired = desired === undefined ? limit : Math.max(desired, limit)\n    }\n    return desired\n  }\n\n  private rollbackLease(\n    lease: symbol,\n    version: number,\n    previousLimit: number | undefined,\n    previousVersion: number | undefined,\n  ): boolean {\n    if (this.leaseVersions.get(lease) !== version) return false\n    if (previousLimit === undefined) {\n      this.leases.delete(lease)\n      this.leaseVersions.delete(lease)\n    } else {\n      this.leases.set(lease, previousLimit)\n      if (previousVersion === undefined) {\n        this.leaseVersions.delete(lease)\n      } else {\n        this.leaseVersions.set(lease, previousVersion)\n      }\n    }\n    return true\n  }\n\n  private restoreInitialWindow(): void {\n    const setWindow = this.target.utils?.setWindow\n    const baselineWindow = this.baselineWindow\n    this.retainedWindow = undefined\n    this.shouldCaptureBaseline = false\n    if (!baselineWindow || typeof setWindow !== `function`) {\n      this.shouldCaptureBaseline = true\n      return\n    }\n    const generation = this.generation\n    const markRestored = () => {\n      if (generation === this.generation && this.leases.size === 0) {\n        this.shouldCaptureBaseline = true\n      }\n    }\n    try {\n      const result = setWindow.call(this.target.utils, baselineWindow)\n      if (result === true) {\n        markRestored()\n      } else {\n        void result.then(markRestored, () => {\n          // Keep the original baseline so a later release can retry it.\n        })\n      }\n    } catch {\n      // Release has no error channel. Keep the baseline for a later retry.\n    }\n  }\n\n  private applyDesiredWindow(): WindowResult {\n    const limit = this.getDesiredLimit()\n    if (limit === undefined) return true\n    if (this.pending?.limit === limit) return this.pending.promise\n    if (this.pending) {\n      // `setWindow` mutates the physical operator before its load promise\n      // settles. A different desired window must therefore be applied again,\n      // even when it matches the last settled limit.\n      this.generation++\n      this.pending = undefined\n      this.appliedLimit = undefined\n    }\n    const currentWindow = this.target.utils?.getWindow?.()\n    if (\n      limit === this.appliedLimit &&\n      currentWindow?.offset === 0 &&\n      currentWindow.limit === limit\n    ) {\n      return true\n    }\n\n    const setWindow = this.target.utils?.setWindow\n    if (typeof setWindow !== `function`) {\n      throw new SetWindowRequiresOrderByError()\n    }\n\n    const generation = ++this.generation\n    const result = setWindow.call(this.target.utils, { offset: 0, limit })\n    if (result === true) {\n      if (generation === this.generation && this.getDesiredLimit() === limit) {\n        this.appliedLimit = limit\n      }\n      return true\n    }\n\n    const promise = result.then(\n      () => {\n        if (\n          generation === this.generation &&\n          this.getDesiredLimit() === limit\n        ) {\n          this.appliedLimit = limit\n        }\n        if (this.pending?.generation === generation) {\n          this.pending = undefined\n        }\n      },\n      (error: unknown) => {\n        if (this.pending?.generation === generation) {\n          this.pending = undefined\n        }\n        throw error\n      },\n    )\n    this.pending = { generation, limit, promise }\n    return promise\n  }\n}\n\nconst windowCoordinators = new WeakMap<object, WindowCoordinator>()\n\nfunction getWindowCoordinator(target: WindowTarget): WindowCoordinator {\n  let coordinator = windowCoordinators.get(target)\n  if (!coordinator) {\n    coordinator = new WindowCoordinator(target)\n    windowCoordinators.set(target, coordinator)\n  }\n  return coordinator\n}\n\n/** @internal Whether an infinite-query controller currently owns this window. */\nexport function hasLiveQueryWindowLeases(target: object): boolean {\n  return windowCoordinators.get(target)?.hasLeases() ?? false\n}\n\n/** @internal Shared validation for infinite-query adapters. */\nexport function assertLiveQueryWindowManyResult(\n  collection: Collection<any, any, any>,\n): void {\n  if (isSingleResultCollection(collection)) {\n    throw new Error(\n      `useLiveInfiniteQuery: Infinite queries do not support single-result queries. Remove .findOne().`,\n    )\n  }\n}\n\n/** @internal Whether a collection exposes an active ordered window. */\nexport function isLiveQueryWindowCollection(\n  collection: Collection<any, any, any>,\n): collection is LiveQueryWindowCollection {\n  return (\n    typeof collection.utils?.setWindow === `function` &&\n    collection.utils.getWindow?.() !== undefined\n  )\n}\n\n/**\n * Validate a pre-created infinite-query collection and describe any window\n * adjustment the adapter should warn about.\n *\n * @internal Shared validation for infinite-query adapters.\n */\nexport function getLiveQueryWindowCollectionWarning(\n  collection: Collection<any, any, any>,\n  expectedLimit: number,\n): string | undefined {\n  assertLiveQueryWindowManyResult(collection)\n  if (!isLiveQueryWindowCollection(collection)) {\n    throw new Error(\n      `useLiveInfiniteQuery: Pre-created live query collection must have an ORDER BY (orderBy) clause for infinite pagination to work. ` +\n        `Please add .orderBy() to your createLiveQueryCollection query.`,\n    )\n  }\n\n  const currentWindow = collection.utils.getWindow()\n  if (\n    !currentWindow ||\n    hasLiveQueryWindowLeases(collection) ||\n    (currentWindow.offset === 0 && currentWindow.limit === expectedLimit)\n  ) {\n    return undefined\n  }\n\n  return (\n    `useLiveInfiniteQuery: Pre-created collection has window {offset: ${currentWindow.offset}, limit: ${currentWindow.limit}} ` +\n    `but the hook expects {offset: 0, limit: ${expectedLimit}}. Adjusting window now.`\n  )\n}\n\n/** @internal Compare adapter dependencies by identity and structure. */\nexport function compareLiveQueryWindowDependencies(\n  previous: ReadonlyArray<unknown> | null | undefined,\n  current: ReadonlyArray<unknown>,\n): { changed: boolean; structurallyEqual: boolean } {\n  const changed =\n    previous === null ||\n    previous === undefined ||\n    previous.length !== current.length ||\n    previous.some((dependency, index) => dependency !== current[index])\n  return {\n    changed,\n    structurallyEqual:\n      previous !== null &&\n      previous !== undefined &&\n      deepEquals(previous, current),\n  }\n}\n\n/** @internal Shared page-depth preservation policy for framework adapters. */\nexport function shouldPreserveLiveQueryWindowPageCount(options: {\n  hasPreviousController: boolean\n  previousInputKind: `collection` | `query` | undefined\n  inputKind: `collection` | `query`\n  sameCollection: boolean\n  dependenciesChanged: boolean\n  dependenciesStructurallyEqual: boolean\n  pageShapeChanged: boolean\n}): boolean {\n  if (\n    !options.hasPreviousController ||\n    options.previousInputKind !== options.inputKind\n  ) {\n    return false\n  }\n  if (options.inputKind === `collection`) return options.sameCollection\n  return options.dependenciesChanged\n    ? options.dependenciesStructurallyEqual\n    : options.pageShapeChanged\n}\n\n/**\n * A page-windowed view of a live query at a point in time.\n *\n * @internal This contract is unstable while RFC #1623 is being implemented.\n */\nexport interface LiveQueryWindowSnapshot<\n  T extends object,\n  TKey extends string | number,\n> {\n  /** Rows across all committed pages, with the peek-ahead row removed. */\n  data: ReadonlyArray<T>\n  /** Rows grouped into committed pages of `pageSize`. */\n  pages: ReadonlyArray<ReadonlyArray<T>>\n  /** `initialPageParam + i` for each committed page. */\n  pageParams: ReadonlyArray<number>\n  hasNextPage: boolean\n  isFetchingNextPage: boolean\n  /** Last pagination failure, retained through an earlier-started success until recovery begins. */\n  error: unknown\n  /** Keyed results for the physical window, or `undefined` when disabled. */\n  state: ReadonlyMap<TKey, T> | undefined\n  collection: Collection<T, TKey, any> | undefined\n  status: CollectionStatus | `disabled`\n  isLoading: boolean\n  isReady: boolean\n  persistedStatus: LiveQuerySnapshot<T, TKey>[`persistedStatus`]\n  isPersistedReady: boolean\n  persistedError: unknown | undefined\n  isIdle: boolean\n  isError: boolean\n  isCleanedUp: boolean\n  isEnabled: boolean\n}\n\n/** @internal This contract is unstable while RFC #1623 is being implemented. */\nexport interface CreateLiveQueryWindowControllerOptions {\n  /** Rows per page (default 20). Invalid values use the default. */\n  pageSize?: number\n  /** Value of the first page's `pageParam` (default 0). */\n  initialPageParam?: number\n  /** Committed pages to preserve when a framework binding changes page shape. */\n  initialPageCount?: number\n}\n\n/** @internal This contract is unstable while RFC #1623 is being implemented. */\nexport interface LiveQueryWindowController<\n  T extends object,\n  TKey extends string | number,\n> {\n  getSnapshot: () => LiveQueryWindowSnapshot<T, TKey>\n  subscribe: (listener: () => void) => () => void\n  /** Load one more page, resolving only after that page is committed. */\n  fetchNextPage: () => Promise<void>\n  /** Reset to the first page, resolving after the smaller window is accepted. */\n  reset: () => Promise<void>\n  preload: () => Promise<void>\n  dispose: () => void\n}\n\n/**\n * Run an adapter-facing page fetch. The controller records failures in its\n * snapshot; consuming the rejection here keeps event handlers safe while the\n * returned promise still settles with the request.\n *\n * @internal This contract is unstable while RFC #1623 is being implemented.\n */\nexport function fetchNextLiveQueryWindowPage(\n  controller: Pick<\n    LiveQueryWindowController<object, string | number>,\n    `fetchNextPage`\n  >,\n): Promise<void> {\n  return controller.fetchNextPage().catch(() => {})\n}\n\ninterface CachedFrom {\n  observerSnapshot: unknown\n  committedPageCount: number\n  isFetchingNextPage: boolean\n  hasPaginationError: boolean\n  paginationError: unknown\n  failedHasNextPage: boolean\n}\n\ninterface SubscriptionRecord {\n  listener: () => void\n  active: boolean\n}\n\ninterface Publication {\n  targets: Array<SubscriptionRecord>\n}\n\nclass LiveQueryWindowControllerImpl<\n  T extends object,\n  TKey extends string | number,\n> implements LiveQueryWindowController<T, TKey> {\n  private readonly observer: LiveQueryObserver<T, TKey>\n  private readonly collection: Collection<T, TKey, any> | null\n  private readonly coordinator: WindowCoordinator | null\n  private readonly lease = Symbol(`liveQueryWindowLease`)\n  private readonly pageSize: number\n  private readonly initialPageParam: number\n\n  private committedPageCount: number\n  private isFetchingNextPage = false\n  private hasPaginationError = false\n  private paginationError: unknown\n  private failedHasNextPage = false\n  private activeFetchPromise: Promise<void> | null = null\n  private windowGeneration = 0\n  private pendingWindowGeneration: number | undefined\n  private leaseActive = false\n  private leaseGeneration = 0\n  private inFlightLeaseHolders = 0\n  private restoreInitialWindowOnRelease = false\n\n  private readonly subscriptions = new Set<SubscriptionRecord>()\n  private readonly publicationQueue: Array<Publication> = []\n  private dispatching = false\n  private blockDelivery = false\n  private transitionDepth = 0\n  private transitionNeedsNotify = false\n  private observerUnsub: (() => void) | null = null\n  private cachedSnapshot: LiveQueryWindowSnapshot<T, TKey> | null = null\n  private cachedFrom: CachedFrom | null = null\n  private disposed = false\n\n  constructor(\n    collection: Collection<T, TKey, any> | null,\n    options: CreateLiveQueryWindowControllerOptions,\n  ) {\n    this.collection = collection\n    this.coordinator = collection\n      ? getWindowCoordinator(collection as unknown as WindowTarget)\n      : null\n    this.pageSize = normalizeLiveQueryWindowPageSize(options.pageSize)\n    this.initialPageParam = options.initialPageParam ?? 0\n    const initialPageCount = Math.floor(options.initialPageCount ?? 1)\n    this.committedPageCount = Number.isFinite(initialPageCount)\n      ? Math.max(1, initialPageCount)\n      : 1\n    // The controller listener carries no delta payload, so wholesale is the\n    // only coherent observer contract and guarantees non-reentrant subscribe.\n    this.observer = createLiveQueryObserver<T, TKey>(collection, {\n      mode: `wholesale`,\n    })\n  }\n\n  getSnapshot(): LiveQueryWindowSnapshot<T, TKey> {\n    const observerSnapshot = this.observer.getSnapshot()\n    if (this.hasPaginationError && observerSnapshot.status === `ready`) {\n      this.failedHasNextPage = this.getComputedHasNextPage(observerSnapshot)\n    }\n    const cached = this.cachedSnapshot\n    if (\n      cached &&\n      this.cachedFrom &&\n      this.cachedFrom.observerSnapshot === observerSnapshot &&\n      this.cachedFrom.committedPageCount === this.committedPageCount &&\n      this.cachedFrom.isFetchingNextPage === this.isFetchingNextPage &&\n      this.cachedFrom.hasPaginationError === this.hasPaginationError &&\n      this.cachedFrom.paginationError === this.paginationError &&\n      this.cachedFrom.failedHasNextPage === this.failedHasNextPage\n    ) {\n      return cached\n    }\n\n    const enabled = observerSnapshot.isEnabled\n    const rows =\n      enabled && Array.isArray(observerSnapshot.data)\n        ? (observerSnapshot.data as ReadonlyArray<T>)\n        : []\n    const totalRequested = this.committedPageCount * this.pageSize\n    const computedHasNextPage = enabled && rows.length > totalRequested\n    const hasNextPage = this.hasPaginationError\n      ? this.failedHasNextPage\n      : computedHasNextPage\n\n    const pageCount = enabled ? this.committedPageCount : 0\n    const pages: Array<ReadonlyArray<T>> = []\n    const pageParams: Array<number> = []\n    for (let i = 0; i < pageCount; i++) {\n      pages.push(rows.slice(i * this.pageSize, (i + 1) * this.pageSize))\n      pageParams.push(this.initialPageParam + i)\n    }\n\n    const status = this.hasPaginationError ? `error` : observerSnapshot.status\n    const statusFlags = this.hasPaginationError\n      ? getLiveQueryStatusFlags(`error`)\n      : observerSnapshot\n    this.cachedSnapshot = {\n      data: rows.slice(0, totalRequested),\n      pages,\n      pageParams,\n      hasNextPage,\n      isFetchingNextPage: this.isFetchingNextPage,\n      error: this.hasPaginationError ? this.paginationError : undefined,\n      state: observerSnapshot.state,\n      collection: observerSnapshot.collection,\n      status,\n      isLoading: statusFlags.isLoading,\n      isReady: statusFlags.isReady,\n      persistedStatus: observerSnapshot.persistedStatus,\n      isPersistedReady: observerSnapshot.isPersistedReady,\n      persistedError: observerSnapshot.persistedError,\n      isIdle: statusFlags.isIdle,\n      isError: statusFlags.isError,\n      isCleanedUp: observerSnapshot.isCleanedUp,\n      isEnabled: observerSnapshot.isEnabled,\n    }\n    this.cachedFrom = {\n      observerSnapshot,\n      committedPageCount: this.committedPageCount,\n      isFetchingNextPage: this.isFetchingNextPage,\n      hasPaginationError: this.hasPaginationError,\n      paginationError: this.paginationError,\n      failedHasNextPage: this.failedHasNextPage,\n    }\n    return this.cachedSnapshot\n  }\n\n  subscribe(listener: () => void): () => void {\n    if (this.disposed) throw new LiveQueryWindowControllerDisposedError()\n\n    const record: SubscriptionRecord = { listener, active: true }\n    this.subscriptions.add(record)\n    if (this.subscriptions.size === 1) {\n      this.restoreInitialWindowOnRelease = false\n      this.blockDelivery = true\n      let observerUnsub: (() => void) | null = null\n      try {\n        // Store the desired physical window before observer activation can\n        // compile or restart the live-query pipeline.\n        const windowResult = this.ensureLeaseActive(this.committedPageCount)\n        const leaseGeneration = this.leaseGeneration\n        observerUnsub = this.observer.subscribe(() => this.notify())\n        this.observerUnsub = observerUnsub\n        if (windowResult !== true) {\n          this.trackAttachmentFailure(windowResult, leaseGeneration)\n        }\n      } catch (error) {\n        observerUnsub?.()\n        this.observerUnsub = null\n        this.deactivateLease(true)\n        record.active = false\n        this.subscriptions.delete(record)\n        throw error\n      } finally {\n        this.blockDelivery = false\n      }\n    }\n\n    return () => {\n      if (!record.active) return\n      record.active = false\n      this.subscriptions.delete(record)\n      if (this.subscriptions.size === 0) {\n        this.restoreInitialWindowOnRelease = true\n        this.observerUnsub?.()\n        this.observerUnsub = null\n        if (this.inFlightLeaseHolders === 0) this.deactivateLease(true)\n      }\n    }\n  }\n\n  fetchNextPage(): Promise<void> {\n    if (this.disposed) return Promise.resolve()\n    if (this.activeFetchPromise) {\n      return this.activeFetchPromise\n    }\n    const snapshot = this.getSnapshot()\n    const awaitingInitialLoad = snapshot.isLoading || snapshot.isIdle\n    if (!snapshot.hasNextPage && !awaitingInitialLoad) return Promise.resolve()\n\n    let resolveFetch!: () => void\n    let rejectFetch!: (error: unknown) => void\n    const activeFetchPromise = new Promise<void>((resolve, reject) => {\n      resolveFetch = resolve\n      rejectFetch = reject\n    })\n    this.activeFetchPromise = activeFetchPromise\n\n    let request: Promise<void>\n    try {\n      const generation = this.windowGeneration\n      // An unpublished initial snapshot cannot establish that there is no next\n      // page. Keep one fetch pending, then decide from the settled first page.\n      request = awaitingInitialLoad\n        ? this.preload().then(() => {\n            if (\n              this.disposed ||\n              generation !== this.windowGeneration ||\n              !this.getSnapshot().hasNextPage\n            ) {\n              return\n            }\n            return this.requestPageCount(this.committedPageCount + 1, true)\n          })\n        : this.requestPageCount(this.committedPageCount + 1, true)\n    } catch (error) {\n      this.activeFetchPromise = null\n      rejectFetch(error)\n      return activeFetchPromise\n    }\n    void request.then(\n      () => {\n        if (this.activeFetchPromise === activeFetchPromise) {\n          this.activeFetchPromise = null\n        }\n        resolveFetch()\n      },\n      (error: unknown) => {\n        if (this.activeFetchPromise === activeFetchPromise) {\n          this.activeFetchPromise = null\n        }\n        rejectFetch(error)\n      },\n    )\n    return activeFetchPromise\n  }\n\n  reset(): Promise<void> {\n    if (this.disposed) return Promise.resolve()\n    if (\n      this.committedPageCount === 1 &&\n      !this.hasPaginationError &&\n      !this.isFetchingNextPage &&\n      !this.activeFetchPromise &&\n      this.pendingWindowGeneration === undefined\n    ) {\n      return Promise.resolve()\n    }\n    this.activeFetchPromise = null\n    return this.requestPageCount(1, false)\n  }\n\n  async preload(): Promise<void> {\n    if (this.disposed) throw new LiveQueryWindowControllerDisposedError()\n\n    const hadPaginationError = this.hasPaginationError\n    this.hasPaginationError = false\n    this.paginationError = undefined\n    this.acquireInFlightLease()\n    try {\n      const result = this.ensureLeaseActive(this.committedPageCount)\n      if (result !== true) await result\n      await this.observer.preload()\n      this.failedHasNextPage = false\n      if (hadPaginationError) this.notify()\n    } catch (error) {\n      this.hasPaginationError = true\n      this.paginationError = error\n      this.failedHasNextPage = this.getComputedHasNextPage()\n      this.notify()\n      throw error\n    } finally {\n      this.releaseInFlightLease()\n    }\n  }\n\n  dispose(): void {\n    if (this.disposed) return\n    this.disposed = true\n    this.windowGeneration++\n    this.pendingWindowGeneration = undefined\n    this.observerUnsub?.()\n    this.observerUnsub = null\n    this.deactivateLease(true)\n    this.observer.dispose()\n    for (const record of this.subscriptions) record.active = false\n    this.subscriptions.clear()\n    this.publicationQueue.length = 0\n  }\n\n  private requestPageCount(\n    requestedPageCount: number,\n    fetchingNextPage: boolean,\n  ): Promise<void> {\n    const generation = ++this.windowGeneration\n    const previousHasNextPage = this.getSnapshot().hasNextPage\n    this.pendingWindowGeneration = undefined\n    this.acquireInFlightLease()\n\n    this.beginTransition()\n    this.isFetchingNextPage = fetchingNextPage\n    this.hasPaginationError = false\n    this.paginationError = undefined\n    if (fetchingNextPage) this.notify()\n\n    let result: WindowResult\n    try {\n      result = this.activateLease(requestedPageCount)\n    } catch (error) {\n      this.isFetchingNextPage = false\n      this.hasPaginationError = true\n      this.paginationError = error\n      this.failedHasNextPage = previousHasNextPage\n      this.notify()\n      this.endTransition()\n      this.releaseInFlightLease()\n      return Promise.reject(error)\n    }\n\n    if (result === true) {\n      if (!this.disposed && generation === this.windowGeneration) {\n        this.committedPageCount = requestedPageCount\n        this.isFetchingNextPage = false\n        this.notify()\n      }\n      this.endTransition()\n      this.releaseInFlightLease()\n      return Promise.resolve()\n    }\n\n    this.pendingWindowGeneration = generation\n    this.endTransition()\n\n    return result\n      .then(\n        () => {\n          if (this.disposed || generation !== this.windowGeneration) return\n          this.beginTransition()\n          this.pendingWindowGeneration = undefined\n          this.committedPageCount = requestedPageCount\n          this.isFetchingNextPage = false\n          this.failedHasNextPage = this.getComputedHasNextPage()\n          this.notify()\n          this.endTransition()\n        },\n        (error: unknown) => {\n          if (!this.disposed && generation === this.windowGeneration) {\n            this.beginTransition()\n            this.pendingWindowGeneration = undefined\n            this.isFetchingNextPage = false\n            this.hasPaginationError = true\n            this.paginationError = error\n            this.failedHasNextPage = previousHasNextPage\n            this.notify()\n            this.endTransition()\n          }\n          throw error\n        },\n      )\n      .finally(() => {\n        this.releaseInFlightLease()\n      })\n  }\n\n  private acquireInFlightLease(): void {\n    this.inFlightLeaseHolders++\n  }\n\n  private releaseInFlightLease(): void {\n    this.inFlightLeaseHolders--\n    if (this.inFlightLeaseHolders === 0 && this.subscriptions.size === 0) {\n      this.deactivateLease(this.restoreInitialWindowOnRelease)\n    }\n  }\n\n  private activateLease(pageCount: number): WindowResult {\n    this.leaseGeneration++\n    if (!this.coordinator || !this.collection) return true\n    this.leaseActive = true\n    return this.coordinator.request(this.lease, pageCount * this.pageSize + 1)\n  }\n\n  private ensureLeaseActive(pageCount: number): WindowResult {\n    const minimumLimit = pageCount * this.pageSize + 1\n    if (this.leaseActive) {\n      const result = this.coordinator?.getLeaseResult(this.lease, minimumLimit)\n      if (result) return result\n    }\n    return this.activateLease(pageCount)\n  }\n\n  private deactivateLease(restoreWhenEmpty = false): void {\n    if (!this.leaseActive || !this.coordinator) return\n    this.leaseGeneration++\n    this.leaseActive = false\n    this.restoreInitialWindowOnRelease = false\n    this.coordinator.release(this.lease, restoreWhenEmpty)\n  }\n\n  private trackAttachmentFailure(\n    result: Promise<void>,\n    leaseGeneration: number,\n  ): void {\n    void result.catch((error: unknown) => {\n      if (\n        this.disposed ||\n        !this.leaseActive ||\n        leaseGeneration !== this.leaseGeneration\n      ) {\n        return\n      }\n      this.beginTransition()\n      this.hasPaginationError = true\n      this.paginationError = error\n      this.failedHasNextPage = this.getComputedHasNextPage()\n      this.notify()\n      this.endTransition()\n    })\n  }\n\n  private getComputedHasNextPage(\n    snapshot: LiveQuerySnapshot<T, TKey> = this.observer.getSnapshot(),\n  ): boolean {\n    return (\n      snapshot.isEnabled &&\n      Array.isArray(snapshot.data) &&\n      snapshot.data.length > this.committedPageCount * this.pageSize\n    )\n  }\n\n  private beginTransition(): void {\n    this.transitionDepth++\n  }\n\n  private endTransition(): void {\n    this.transitionDepth--\n    if (this.transitionDepth === 0 && this.transitionNeedsNotify) {\n      this.transitionNeedsNotify = false\n      this.publish()\n    }\n  }\n\n  private notify(): void {\n    if (this.transitionDepth > 0) {\n      this.transitionNeedsNotify = true\n      return\n    }\n    this.publish()\n  }\n\n  private publish(): void {\n    if (this.disposed || this.blockDelivery || this.subscriptions.size === 0) {\n      return\n    }\n\n    this.publicationQueue.push({ targets: [...this.subscriptions] })\n    if (this.dispatching) return\n\n    this.dispatching = true\n    try {\n      while (this.publicationQueue.length > 0) {\n        const publication = this.publicationQueue.shift()!\n        for (const record of publication.targets) {\n          if (this.hasBeenDisposed()) return\n          if (!record.active) continue\n          record.listener()\n        }\n      }\n    } finally {\n      this.dispatching = false\n    }\n  }\n\n  private hasBeenDisposed(): boolean {\n    return this.disposed\n  }\n}\n\n/**\n * Create an internal forward-window controller for an ordered live query.\n *\n * @internal This factory is unstable while RFC #1623 is being implemented.\n */\nexport function createLiveQueryWindowController<\n  T extends object,\n  TKey extends string | number,\n>(\n  collection: Collection<T, TKey, any> | null | undefined,\n  options: CreateLiveQueryWindowControllerOptions = {},\n): LiveQueryWindowController<T, TKey> {\n  return new LiveQueryWindowControllerImpl<T, TKey>(collection ?? null, options)\n}\n"],"names":["isCollection","BaseQueryBuilder","leases","leaseVersions","shouldCaptureBaseline","leaseVersion","retainedWindow","baselineWindow","applyDesiredWindow","rollbackLease","appliedLimit","restoreInitialWindow","getDesiredLimit","SetWindowRequiresOrderByError","isSingleResultCollection","index","deepEquals","lease","activeFetchPromise","windowGeneration","leaseActive","leaseGeneration","inFlightLeaseHolders","restoreInitialWindowOnRelease","publicationQueue","dispatching","blockDelivery","transitionDepth","transitionNeedsNotify","observerUnsub","cachedSnapshot","cachedFrom","createLiveQueryObserver","getComputedHasNextPage","getLiveQueryStatusFlags","LiveQueryWindowControllerDisposedError","ensureLeaseActive","trackAttachmentFailure","deactivateLease","requestPageCount","pendingWindowGeneration","acquireInFlightLease","releaseInFlightLease","beginTransition","activateLease","endTransition","hasBeenDisposed"],"mappings":"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"}