{"version":3,"file":"live-query-observer-client.cjs","sources":["../../src/live-query-observer-client.ts"],"sourcesContent":["import { getLiveQueryRowOptions } from './live-query-options.js'\nimport { codedMessage, devBuild } from './error-message.js'\nimport { getBuilderFromConfig } from './query/live/collection-registry.js'\nimport { getPooledLiveQuerySource } from './query/pooled-source.js'\nimport { isFailedStatus } from './live-query-primitives.js'\nimport type { Collection } from './collection/index.js'\nimport type { DbClient, DehydratedLiveQueryResult } from './client.js'\nimport type {\n  LiveQueryObserver,\n  LiveQuerySnapshot,\n} from './live-query-observer.js'\nimport type { ChangeMessage } from './types.js'\n\n/**\n * DbClient supplies transport behavior to the shared observer. Keeping this\n * implementation behind the client means ordinary framework queries do not\n * import server admission, hydration reconciliation, or streaming machinery.\n */\nexport interface LiveQueryObserverClientHost<\n  T extends object,\n  TKey extends string | number,\n> {\n  observer: LiveQueryObserver<T, TKey>\n  read: (forServerSnapshot: boolean) => LiveQuerySnapshot<T, TKey>\n  entries: () => Array<[TKey, T]>\n  isAttached: () => boolean\n  isDisposed: () => boolean\n  dirty: () => void\n  publish: (\n    changes: Array<ChangeMessage<T, TKey>>,\n    entries?: Array<[TKey, T]>,\n  ) => void\n  preload: () => Promise<void>\n}\n\nexport class LiveQueryObserverClient<\n  T extends object,\n  TKey extends string | number,\n> {\n  private hydrationSeed:\n    | {\n        dehydratedAt: number\n        entries: Array<[TKey, T]>\n        snapshot: DehydratedLiveQueryResult\n      }\n    | undefined\n  error: unknown\n  failed = false\n  private authoritative = false\n  private handoffScheduled = false\n  private unregisterResource: (() => void) | undefined\n  private preloadPromise: Promise<void> | undefined\n\n  constructor(\n    private readonly client: DbClient,\n    private readonly collection: Collection<T, TKey, any> | null,\n    private readonly queryHash: string | undefined,\n    private readonly usesSettledHydration: boolean,\n    private readonly host: LiveQueryObserverClientHost<T, TKey>,\n  ) {}\n\n  get seed() {\n    return this.authoritative ? undefined : this.hydrationSeed\n  }\n\n  get query() {\n    return this.queryHash\n      ? this.client._getLiveQuery(this.queryHash)\n      : undefined\n  }\n\n  sync(forServerSnapshot = false): boolean {\n    if (!this.queryHash || this.authoritative) return false\n    this.client._waitForSsrLiveQuery(this.queryHash)\n    const query = this.client._getLiveQuery(this.queryHash, forServerSnapshot)\n    if (!query) return false\n    if (\n      this.host.isAttached() &&\n      !this.hydrationSeed &&\n      this.collection?.status === `ready` &&\n      !this.collection.isLoadingSubset\n    ) {\n      return this.markAuthoritative(query.dehydratedAt)\n    }\n    if (\n      query.status === `error` &&\n      (this.usesSettledHydration ||\n        !forServerSnapshot ||\n        !query.initialSnapshot)\n    ) {\n      const changed = !this.failed || this.error !== query.error\n      this.error = query.error\n      this.failed = true\n      if (changed) this.host.dirty()\n      return changed\n    }\n    const snapshot =\n      (!this.usesSettledHydration && query.initialSnapshot) || query.snapshot\n    if (!snapshot || this.hydrationSeed?.snapshot === snapshot) return false\n    this.hydrationSeed = {\n      dehydratedAt: query.dehydratedAt,\n      snapshot,\n      entries: snapshot.rows.map((row) => [row.key as TKey, row.value as T]),\n    }\n    this.error = undefined\n    this.failed = false\n    this.host.dirty()\n    return true\n  }\n\n  getServerSnapshot(preloadRequested: boolean): LiveQuerySnapshot<T, TKey> {\n    preloadRequested &&= this.client._isSsrStreamingEnabled()\n    if (\n      typeof window !== `undefined` &&\n      !this.authoritative &&\n      this.queryHash\n    ) {\n      const waiting = this.client._waitForSsrLiveQuery(this.queryHash, true)\n      if (waiting) throw waiting\n      const query = this.client._getLiveQuery(this.queryHash, true)\n      const snapshot = this.usesSettledHydration\n        ? query?.snapshot\n        : (query?.initialSnapshot ?? query?.snapshot)\n      // A later boundary may hydrate before its result promise arrives.\n      // Local rows cannot substitute for the missing server-rendered view.\n      if (query?.status === `pending` && !snapshot) {\n        if (this.usesSettledHydration)\n          void this.host.observer.preload().catch(() => {})\n        throw query.promise\n      }\n    }\n    if (preloadRequested) {\n      void this.host.observer.preload().catch(() => {})\n    }\n    if (typeof window === `undefined`) this.assertSources()\n    const snapshot = this.host.read(true)\n    const collection = this.collection\n    if (!collection || this.seed) return snapshot\n    // React also calls this getter in the browser during hydration. Only\n    // server reads perform admission; transported seeds win over local activity.\n    if (typeof window !== `undefined`) return snapshot\n    // A suspended component has not rendered this loading view. Its settled\n    // stream will supply the first rendered result.\n    if (preloadRequested && !snapshot.isReady) return snapshot\n\n    const { sources } = this.getSourceInfo()\n    const entries = this.host.entries()\n    if (\n      !this.queryHash ||\n      (!preloadRequested &&\n        (entries.length > 0 || snapshot.isReady) &&\n        !(sources ?? [collection]).every((source) =>\n          this.client._hasSsrCollectionSnapshot(source),\n        ))\n    ) {\n      throw new Error(\n        devBuild() && process.env.NODE_ENV !== `production`\n          ? `SSR cannot render server-only live-query rows or readiness. Await DbClient.preloadLiveQuery() for this query, or explicitly preload its source Collections for hydration. Opaque queries require an explicit serializable queryKey.`\n          : codedMessage(252),\n      )\n    }\n    // Capture at render, rather than sampling mutable source rows at dehydrate.\n    // Loading views transfer rows without answering a later data preload.\n    this.client._captureServerQuery(\n      this.queryHash,\n      {\n        rows: entries.map(([key, value]) => ({ key, value })),\n        ...(snapshot.isReady\n          ? {}\n          : {\n              status:\n                snapshot.isLoadingError || snapshot.isCrashed\n                  ? (`error` as const)\n                  : (`loading` as const),\n            }),\n      },\n      sources,\n      getLiveQueryRowOptions(collection),\n    )\n    return this.host.read(true)\n  }\n\n  private diffEntries(\n    previous: Array<[TKey, T]>,\n    next: Array<[TKey, T]>,\n  ): Array<ChangeMessage<T, TKey>> {\n    const previousByKey = new Map(previous)\n    const nextByKey = new Map(next)\n    const changes: Array<ChangeMessage<T, TKey>> = []\n    for (const [key, value] of previous) {\n      if (!nextByKey.has(key)) changes.push({ type: `delete`, key, value })\n    }\n    for (const [key, value] of next) {\n      const previousValue = previousByKey.get(key)\n      if (previousValue === undefined)\n        changes.push({ type: `insert`, key, value })\n      else if (previousValue !== value)\n        changes.push({ type: `update`, key, value, previousValue })\n    }\n    return changes\n  }\n\n  markAuthoritative(dehydratedAt?: number): boolean {\n    if (this.authoritative) return false\n    dehydratedAt ??= this.query?.dehydratedAt\n    const changed = this.failed\n    this.error = undefined\n    this.failed = false\n    this.authoritative = true\n    if (dehydratedAt !== undefined && this.queryHash)\n      this.client._consumeLiveQueryResult(this.queryHash, dehydratedAt)\n    if (changed) this.host.dirty()\n    return changed\n  }\n\n  scheduleHandoff(): void {\n    if (this.handoffScheduled) return\n    this.handoffScheduled = true\n    queueMicrotask(() => {\n      this.handoffScheduled = false\n      this.handoff()\n    })\n  }\n\n  handoff(): void {\n    const collection = this.collection\n    if (\n      this.host.isDisposed() ||\n      !this.host.isAttached() ||\n      !collection ||\n      !this.seed ||\n      // A failure ends the sync run whose result the seed stood in for.\n      (!isFailedStatus(collection.status) &&\n        (collection.status !== `ready` || collection.isLoadingSubset))\n    )\n      return\n    const previous = this.seed.entries\n    const dehydratedAt = this.seed.dehydratedAt\n    const entries = Array.from(collection.entries()) as Array<[TKey, T]>\n    this.hydrationSeed = undefined\n    this.markAuthoritative(dehydratedAt)\n    this.host.publish(this.diffEntries(previous, entries), entries)\n  }\n\n  assertSources(): void {\n    const { sources } = this.getSourceInfo()\n    if (this.queryHash && sources)\n      this.client._assertLiveQuerySources(\n        this.queryHash,\n        sources,\n        getLiveQueryRowOptions(this.collection),\n      )\n  }\n\n  subscribe(): () => void {\n    if (!this.queryHash) return () => {}\n    return this.client.subscribe((event) => {\n      if (\n        event.type === `liveQueryStreamError` ||\n        event.query.queryHash !== this.queryHash\n      )\n        return\n      const previous = this.host.entries()\n      if (this.sync())\n        this.host.publish(this.diffEntries(previous, this.host.entries()))\n    })\n  }\n\n  registerResource(): void {\n    const config: object | undefined = this.collection?.config\n    if (\n      this.unregisterResource ||\n      !this.client._isSsrServerCleanupEnabled() ||\n      !config ||\n      !getBuilderFromConfig(config)\n    )\n      return\n    this.unregisterResource = this.client._registerLiveQueryResource(\n      this.host.observer,\n      async () => {\n        this.host.observer.dispose()\n        await this.collection?.cleanup({ dependents: true })\n      },\n    )\n  }\n\n  takeResourceRelease(): (() => void) | undefined {\n    const release = this.unregisterResource\n    this.unregisterResource = undefined\n    return release\n  }\n\n  private getSourceInfo() {\n    const collection = this.collection\n    const config = collection?.config\n    const pooledSource = collection && getPooledLiveQuerySource(collection)\n    const sources = config\n      ? getBuilderFromConfig(config)?.getSourceCollections()\n      : pooledSource\n        ? [pooledSource]\n        : undefined\n    return { sources, pooledSource: pooledSource || undefined }\n  }\n\n  preload(): Promise<void> {\n    if (this.preloadPromise) return this.preloadPromise\n    const { sources, pooledSource } = this.getSourceInfo()\n    if (this.queryHash) {\n      const query = this.query\n      try {\n        this.client._waitForSsrLiveQuery(this.queryHash)\n        if (sources)\n          this.client._assertLiveQuerySources(\n            this.queryHash,\n            sources,\n            getLiveQueryRowOptions(this.collection),\n          )\n        if (\n          query?.status === `pending` ||\n          (query?.status === `success` && query.snapshot?.status === undefined)\n        ) {\n          if (pooledSource && this.collection)\n            return Promise.all([query.promise, this.collection.preload()]).then(\n              () => {},\n            )\n          // Stream reuse remains explicit demand for the local Collection.\n          this.collection?._markPreload()\n          return query.status === `pending` ? query.promise : Promise.resolve()\n        }\n      } catch (error) {\n        return Promise.reject(error)\n      }\n    }\n    this.registerResource()\n    const collectionPromise = this.host.preload()\n    const promise =\n      this.client._isSsrStreamingEnabled() && this.queryHash\n        ? this.client._registerLiveQuery(\n            this.queryHash,\n            collectionPromise.then(() => this.host.observer.dehydrate()),\n            sources,\n            getLiveQueryRowOptions(this.collection),\n          )\n        : collectionPromise\n    this.preloadPromise = promise\n    const clear = () => {\n      if (this.preloadPromise === promise) this.preloadPromise = undefined\n    }\n    void promise.then(clear, clear)\n    return promise\n  }\n}\n"],"names":["usesSettledHydration","handoffScheduled","hydrationSeed","snapshot","getSourceInfo","devBuild","codedMessage","getLiveQueryRowOptions","diffEntries","isFailedStatus","unregisterResource","getBuilderFromConfig","pooledSource","getPooledLiveQuerySource"],"mappings":"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"}