{"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 { getLiveQueryStatusFlags } from './live-query-adapter.js'\nimport { createLiveQueryObserver } from './live-query-observer.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'\n\nconst DEFAULT_PAGE_SIZE = 20\n\ntype WindowResult = true | Promise<void>\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 readonly initialWindow: { offset: number; limit: number } | undefined\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    this.initialWindow = target.utils?.getWindow?.()\n  }\n\n  request(lease: symbol, limit: number): WindowResult {\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      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  isLeaseSatisfied(lease: symbol, minimumLimit: number): boolean {\n    const limit = this.leases.get(lease)\n    if (limit === undefined || limit < minimumLimit) return false\n    const desiredLimit = this.getDesiredLimit()\n    const currentWindow = this.target.utils?.getWindow?.()\n    return (\n      currentWindow === undefined ||\n      (currentWindow.offset === 0 && currentWindow.limit === desiredLimit)\n    )\n  }\n\n  release(lease: symbol): 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      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    if (!this.initialWindow || typeof setWindow !== `function`) return\n    try {\n      const result = setWindow.call(this.target.utils, this.initialWindow)\n      if (result !== true) void result.catch(() => {})\n    } catch {\n      // Release has no error channel. A future lease will retry its own window.\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/**\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  /** The last pagination failure, cleared when a retry 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  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). Non-positive 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\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 windowGeneration = 0\n  private pendingWindowGeneration: number | undefined\n  private leaseActive = false\n  private leaseGeneration = 0\n  private inFlightLeaseHolders = 0\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 =\n      options.pageSize !== undefined && options.pageSize > 0\n        ? options.pageSize\n        : DEFAULT_PAGE_SIZE\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    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      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.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.onObserverNotify())\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()\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.observerUnsub?.()\n        this.observerUnsub = null\n        if (this.inFlightLeaseHolders === 0) this.deactivateLease()\n      }\n    }\n  }\n\n  fetchNextPage(): Promise<void> {\n    if (this.disposed || this.isFetchingNextPage) return Promise.resolve()\n    if (!this.getSnapshot().hasNextPage) return Promise.resolve()\n    return this.requestPageCount(this.committedPageCount + 1, true)\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.pendingWindowGeneration === undefined\n    ) {\n      return Promise.resolve()\n    }\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()\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.failedHasNextPage = 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 = false\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()\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 (\n      this.leaseActive &&\n      this.coordinator?.isLeaseSatisfied(this.lease, minimumLimit)\n    ) {\n      return true\n    }\n    return this.activateLease(pageCount)\n  }\n\n  private deactivateLease(): void {\n    if (!this.leaseActive || !this.coordinator) return\n    this.leaseGeneration++\n    this.leaseActive = false\n    this.coordinator.release(this.lease)\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(): boolean {\n    const snapshot: LiveQuerySnapshot<T, TKey> = this.observer.getSnapshot()\n    return (\n      snapshot.isEnabled &&\n      Array.isArray(snapshot.data) &&\n      snapshot.data.length > this.committedPageCount * this.pageSize\n    )\n  }\n\n  private onObserverNotify(): void {\n    this.notify()\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":["SetWindowRequiresOrderByError","createLiveQueryObserver","getLiveQueryStatusFlags","LiveQueryWindowControllerDisposedError"],"mappings":"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"}