{"version":3,"file":"bucket-facade-adapter.cjs","sources":["../../../../src/query/live/bucket-facade-adapter.ts"],"sourcesContent":["import { output, serializeValue } from '@tanstack/db-ivm'\nimport { isPlainObject } from '../../utils/type-guards.js'\nimport { getOrCreate } from '../../utils/get-or-create.js'\nimport { createCollection } from '../../collection/index.js'\nimport {\n  INCLUDES_ROUTING,\n  transformPublicContainers,\n} from '../compiler/route-metadata.js'\nimport { codedMessage, devBuild } from '../../error-message.js'\nimport { BUCKET_FACADE_REF } from './materialized-pipeline.js'\nimport type { Collection } from '../../collection/index.js'\nimport type { SyncConfig } from '../../types.js'\nimport type { PublicationDeferral } from '../../collection/changes.js'\nimport type {\n  BucketFacadeCompilation,\n  BucketFacadeRef,\n  BucketRow,\n} from './materialized-pipeline.js'\n\nconst PRIVATE_RESULT_KEYS = new Set<PropertyKey>([INCLUDES_ROUTING])\n\ntype FacadeSync = Parameters<SyncConfig<any>[`sync`]>[0]\n\ntype PendingRow = {\n  deletes: number\n  inserts: number\n  value: BucketRow\n}\n\ntype FacadeEntry = {\n  collection: Collection<any, any, any>\n  sync: FacadeSync | undefined\n  keys: WeakMap<object, string | number>\n  order: WeakMap<object, string>\n  currentOrder: Map<string | number, string | undefined>\n}\n\ntype SnapshotRow = {\n  key: string | number\n  value: object\n  order: string | undefined\n}\n\ntype FacadeSnapshot = {\n  activeBuckets: Map<string, Set<string>>\n  entries: Map<string, Map<string, FacadeEntry>>\n  rows: Map<FacadeEntry, Array<SnapshotRow>>\n  /** Keys the flush wrote to each facade, including writes a facade holds. */\n  written: Map<FacadeEntry, Set<string | number>>\n}\n\nconst NO_FACADE_CHANGES: FacadePublication = {\n  prepare: () => {},\n  publish: () => {},\n  rollback: () => {},\n}\n\nexport type FacadePublication = {\n  prepare: () => void\n  publish: () => void\n  rollback: () => void\n}\n\n/**\n * The only stateful boundary outside the materialization graph. It turns inert\n * bucket references into stable public Collection facades and applies the\n * graph's canonical bucket-row deltas to those facades.\n */\nexport class BucketFacadeAdapter {\n  private pending = new Map<string, Map<string, Map<string, PendingRow>>>()\n  private pendingActivity = new Map<string, Map<string, number>>()\n  private readonly activeBuckets = new Map<string, Set<string>>()\n  private readonly entries = new Map<string, Map<string, FacadeEntry>>()\n  private readonly retiredEntries = new Map<string, Map<string, FacadeEntry>>()\n  private resolvedValues = new WeakMap<object, unknown>()\n  private cleanedUp = false\n\n  constructor(\n    private readonly parentId: string,\n    private readonly compilations: Array<BucketFacadeCompilation>,\n    onMessages: (count: number) => void,\n  ) {\n    for (const compilation of compilations) {\n      compilation.rows.pipe(\n        output((data) => {\n          const messages = data.getInner()\n          onMessages(messages.length)\n          for (const [[bucketKey, row], multiplicity] of messages) {\n            this.accumulate(compilation.edgeId, bucketKey, row, multiplicity)\n          }\n        }),\n      )\n      compilation.activeBuckets.pipe(\n        output((data) => {\n          const messages = data.getInner()\n          onMessages(messages.length)\n          for (const [[bucketKey], multiplicity] of messages) {\n            this.accumulateActivity(compilation.edgeId, bucketKey, multiplicity)\n          }\n        }),\n      )\n    }\n  }\n\n  hasPendingChanges(): boolean {\n    return this.pending.size > 0 || this.pendingActivity.size > 0\n  }\n\n  flush(): FacadePublication {\n    if (!this.hasPendingChanges()) return NO_FACADE_CHANGES\n    const snapshot = this.snapshot()\n    const publications: Array<PublicationDeferral> = []\n    const newBaselines: Array<FacadeEntry> = []\n\n    // Compilations are child-first, so nested facade references resolve before\n    // their containing rows are written to the next facade.\n    try {\n      for (const compilation of this.compilations) {\n        const activity = this.pendingActivity.get(compilation.edgeId)\n        const active = this.getActiveBuckets(compilation.edgeId)\n        for (const [bucketKey, multiplicity] of activity ?? []) {\n          if (multiplicity > 0 && !active.has(bucketKey)) {\n            active.add(bucketKey)\n            newBaselines.push(this.getEntry(compilation.edgeId, bucketKey))\n          }\n        }\n\n        const buckets = this.pending.get(compilation.edgeId)\n        for (const [bucketKey, changes] of buckets ?? []) {\n          const existing = this.entries.get(compilation.edgeId)?.get(bucketKey)\n          if (!active.has(bucketKey) && !existing) continue\n          const entry = this.getEntry(compilation.edgeId, bucketKey)\n          const sync = entry.sync\n          if (!sync || changes.size === 0) continue\n\n          for (const change of changes.values()) {\n            this.prepareChange(entry, change)\n          }\n          this.beginWrite(\n            entry,\n            sync,\n            snapshot,\n            publications,\n            [...changes.values()].map(\n              (change) => change.value.publicKey as string | number,\n            ),\n          )\n          for (const change of changes.values()) {\n            this.applyChange(entry, sync, change, compilation.hasOrderBy)\n          }\n          sync.commit()\n        }\n        for (const [bucketKey, multiplicity] of activity ?? []) {\n          if (multiplicity >= 0) continue\n          active.delete(bucketKey)\n          this.retireEntry(\n            compilation.edgeId,\n            bucketKey,\n            snapshot,\n            publications,\n          )\n        }\n      }\n    } catch (error) {\n      this.abort(snapshot, publications)\n      throw error\n    }\n    // A failed root commit keeps the builder's pending root rows, so keep the\n    // facade rows they refer to: a rollback puts them back for the next flush.\n    const pending = this.pending\n    const pendingActivity = this.pendingActivity\n    this.pending = new Map()\n    this.pendingActivity = new Map()\n\n    let closed = false\n    let prepared = false\n    const prepare = () => {\n      if (closed || prepared) return\n      prepared = true\n      for (const entry of newBaselines) entry.sync?.markReady()\n    }\n    return {\n      prepare,\n      publish: () => {\n        if (closed) return\n        prepare()\n        closed = true\n        // A throwing subscriber of one facade must not hold back the others.\n        let publicationError: { error: unknown } | undefined\n        for (const publication of publications) {\n          try {\n            publication.publish()\n          } catch (error) {\n            publicationError ??= { error }\n          }\n        }\n        // Drop only the adapter's strong reference. External holders keep an\n        // empty, ready facade; a later active interval receives a new one.\n        this.retiredEntries.clear()\n        if (publicationError) throw publicationError.error\n      },\n      rollback: () => {\n        if (closed || this.cleanedUp) return\n        closed = true\n        this.abort(snapshot, publications)\n        // The flush runs inside the graph run, so no graph output can reach\n        // the adapter before its rollback. Restoring the consumed deltas over\n        // new ones would lose them, so keep the new ones and fail instead.\n        if (this.hasPendingChanges()) {\n          throw new Error(\n            devBuild() && process.env.NODE_ENV !== `production`\n              ? `Bucket facade received graph output between a flush and its rollback`\n              : codedMessage(235),\n          )\n        }\n        this.pending = pending\n        this.pendingActivity = pendingActivity\n      },\n    }\n  }\n\n  resolve<T>(value: T): T {\n    return this.resolveValue(value) as T\n  }\n\n  cleanup(): void {\n    this.cleanedUp = true\n    for (const byBucket of this.entries.values()) {\n      for (const entry of byBucket.values()) {\n        void entry.collection.cleanup()\n      }\n    }\n    this.entries.clear()\n    this.cleanupRetiredEntries()\n    this.pending.clear()\n    this.pendingActivity.clear()\n    this.activeBuckets.clear()\n  }\n\n  private accumulate(\n    edgeId: string,\n    bucketKey: string,\n    row: BucketRow,\n    multiplicity: number,\n  ): void {\n    const buckets = getOrCreate(this.pending, edgeId, () => new Map())\n    const rows = getOrCreate(buckets, bucketKey, () => new Map())\n\n    const key = serializeValue(row.publicKey)\n    const change = rows.get(key) ?? {\n      deletes: 0,\n      inserts: 0,\n      value: row,\n    }\n    if (multiplicity < 0) {\n      change.deletes += -multiplicity\n    } else if (multiplicity > 0) {\n      change.inserts += multiplicity\n      change.value = row\n    }\n    rows.set(key, change)\n  }\n\n  private copyRows(entry: FacadeEntry): Array<SnapshotRow> {\n    return [...entry.collection._state.syncedData].map(([key, value]) => ({\n      key,\n      value,\n      order: entry.currentOrder.get(key),\n    }))\n  }\n\n  private snapshot(): FacadeSnapshot {\n    return {\n      activeBuckets: new Map(\n        [...this.activeBuckets].map(([edgeId, buckets]) => [\n          edgeId,\n          new Set(buckets),\n        ]),\n      ),\n      entries: new Map(\n        [...this.entries].map(([edgeId, byBucket]) => [\n          edgeId,\n          new Map(byBucket),\n        ]),\n      ),\n      rows: new Map(),\n      written: new Map(),\n    }\n  }\n\n  /** Restore the facades, then discard their events even if restore throws. */\n  private abort(\n    snapshot: FacadeSnapshot,\n    publications: Array<PublicationDeferral>,\n  ): void {\n    try {\n      this.restore(snapshot)\n    } finally {\n      this.retiredEntries.clear()\n      for (const publication of publications) publication.discard()\n    }\n  }\n\n  private restore(snapshot: FacadeSnapshot): void {\n    const previousEntries = new Set(\n      [...snapshot.entries.values()].flatMap((byBucket) => [\n        ...byBucket.values(),\n      ]),\n    )\n    const currentEntries = new Set(\n      [...this.entries.values()].flatMap((byBucket) => [...byBucket.values()]),\n    )\n\n    for (const [entry, rows] of snapshot.rows) {\n      if (!previousEntries.has(entry)) continue\n      const sync = entry.sync\n      if (!sync) continue\n      const restoredKeys = new Set(rows.map((row) => row.key))\n      const synced = entry.collection._state.syncedData\n      sync.begin()\n      // A write held behind a persisting transaction is not yet in the synced\n      // rows, so delete every key the flush wrote as well.\n      for (const key of new Set([\n        ...synced.keys(),\n        ...snapshot.written.get(entry)!,\n      ])) {\n        if (!restoredKeys.has(key)) sync.write({ type: `delete`, key })\n      }\n      entry.currentOrder.clear()\n      for (const row of rows) {\n        entry.keys.set(row.value, row.key)\n        if (row.order !== undefined) entry.order.set(row.value, row.order)\n        entry.currentOrder.set(row.key, row.order)\n        sync.write({\n          type: synced.has(row.key) ? `update` : `insert`,\n          value: row.value,\n        })\n      }\n      sync.commit()\n    }\n\n    this.entries.clear()\n    for (const [edgeId, byBucket] of snapshot.entries) {\n      this.entries.set(edgeId, new Map(byBucket))\n    }\n    this.activeBuckets.clear()\n    for (const [edgeId, buckets] of snapshot.activeBuckets) {\n      this.activeBuckets.set(edgeId, new Set(buckets))\n    }\n    this.resolvedValues = new WeakMap()\n\n    for (const entry of currentEntries) {\n      if (!previousEntries.has(entry)) void entry.collection.cleanup()\n    }\n  }\n\n  private accumulateActivity(\n    edgeId: string,\n    bucketKey: string,\n    multiplicity: number,\n  ): void {\n    const activity = getOrCreate(this.pendingActivity, edgeId, () => new Map())\n    activity.set(bucketKey, (activity.get(bucketKey) ?? 0) + multiplicity)\n  }\n\n  private getActiveBuckets(edgeId: string): Set<string> {\n    return getOrCreate(this.activeBuckets, edgeId, () => new Set())\n  }\n\n  /**\n   * Begin a facade write. Copy the facade's rows and defer its events before\n   * its first write in the flush, so a rollback reads only the facades the\n   * flush wrote. A bucket written and then retired in one flush copies once.\n   */\n  private beginWrite(\n    entry: FacadeEntry,\n    sync: FacadeSync,\n    snapshot: FacadeSnapshot,\n    publications: Array<PublicationDeferral>,\n    keys: Array<string | number>,\n  ): void {\n    if (!snapshot.rows.has(entry)) {\n      snapshot.rows.set(entry, this.copyRows(entry))\n      snapshot.written.set(entry, new Set())\n      publications.push(entry.collection._deferPublication())\n    }\n    for (const key of keys) snapshot.written.get(entry)!.add(key)\n    sync.begin()\n  }\n\n  private retireEntry(\n    edgeId: string,\n    bucketKey: string,\n    snapshot: FacadeSnapshot,\n    publications: Array<PublicationDeferral>,\n  ): void {\n    const byBucket = this.entries.get(edgeId)\n    const entry = byBucket?.get(bucketKey)\n    if (!entry) return\n\n    // The graph retracts a bucket's rows when it retires it, but the facade\n    // can still show rows it never sent: an optimistic row from a pending\n    // transaction, or a sync commit held behind a persisting one. Retract\n    // whatever it still holds.\n    const sync = entry.sync\n    const keys = [...entry.collection.keys()]\n    if (sync && keys.length > 0) {\n      this.beginWrite(entry, sync, snapshot, publications, keys)\n      for (const key of keys) sync.write({ type: `delete`, key })\n      sync.commit()\n    }\n    byBucket!.delete(bucketKey)\n    if (byBucket!.size === 0) this.entries.delete(edgeId)\n    const retired = getOrCreate(this.retiredEntries, edgeId, () => new Map())\n    retired.set(bucketKey, entry)\n  }\n\n  private getEntry(edgeId: string, bucketKey: string): FacadeEntry {\n    const byBucket = getOrCreate(this.entries, edgeId, () => new Map())\n    const existing = byBucket.get(bucketKey)\n    if (existing) return existing\n\n    const keys = new WeakMap<object, string | number>()\n    const order = new WeakMap<object, string>()\n    let sync: FacadeSync | undefined\n    const collection = createCollection<any, string | number>({\n      id: `__bucket-facade:${this.parentId}:${edgeId}:${bucketKey}`,\n      getKey: (row) => {\n        const key = keys.get(row) ?? row?.$key\n        if (typeof key !== `string` && typeof key !== `number`) {\n          throw new Error(\n            devBuild() && process.env.NODE_ENV !== `production`\n              ? `Bucket facade row has no public key`\n              : codedMessage(146),\n          )\n        }\n        return key\n      },\n      compare: (left, right) => {\n        const leftOrder = order.get(left)\n        const rightOrder = order.get(right)\n        if (leftOrder === rightOrder) return 0\n        if (leftOrder === undefined) return 1\n        if (rightOrder === undefined) return -1\n        return leftOrder < rightOrder ? -1 : 1\n      },\n      sync: {\n        rowUpdateMode: `full`,\n        sync: (methods) => {\n          sync = methods\n          return () => {\n            sync = undefined\n          }\n        },\n      },\n      startSync: true,\n      gcTime: 0,\n    })\n    const entry: FacadeEntry = {\n      collection,\n      get sync() {\n        return sync\n      },\n      keys,\n      order,\n      currentOrder: new Map(),\n    }\n    byBucket.set(bucketKey, entry)\n    return entry\n  }\n\n  private applyChange(\n    entry: FacadeEntry,\n    sync: FacadeSync,\n    change: PendingRow,\n    hasOrderBy: boolean,\n  ): void {\n    const key = change.value.publicKey as string | number\n    const previousOrder = entry.currentOrder.get(key)\n    const nextOrder = change.value.order\n    const orderChanged = sync.collection.has(key) && previousOrder !== nextOrder\n    const resolvedRow = this.resolve(change.value.value)\n    const row = orderChanged ? { ...resolvedRow } : resolvedRow\n    entry.keys.set(row, key)\n    if (nextOrder !== undefined) {\n      entry.order.set(row, nextOrder)\n    }\n\n    if (change.inserts > change.deletes) {\n      sync.write({\n        type: sync.collection.has(key) ? `update` : `insert`,\n        value: row,\n      })\n    } else if (change.inserts === change.deletes && sync.collection.has(key)) {\n      sync.write({ type: `update`, value: row })\n    } else if (change.deletes > 0) {\n      sync.write({ type: `delete`, key })\n      entry.currentOrder.delete(key)\n      return\n    }\n\n    entry.currentOrder.set(key, nextOrder)\n    if (hasOrderBy && orderChanged) sync.collection._markLayoutChange()\n  }\n\n  /** Resolve and validate every public key before opening a sync transaction. */\n  private prepareChange(entry: FacadeEntry, change: PendingRow): void {\n    const key = change.value.publicKey as string | number\n    const row = this.resolve(change.value.value)\n    entry.keys.set(row, key)\n    entry.collection.getKeyFromItem(row)\n  }\n\n  private resolveValue(value: unknown): unknown {\n    if (value === null || typeof value !== `object`) return value\n    const cached = this.resolvedValues.get(value)\n    if (cached !== undefined) return cached\n    if (isBucketFacadeRef(value)) {\n      const { edgeId, bucketKey } = value[BUCKET_FACADE_REF]\n      const facade =\n        this.entries.get(edgeId)?.get(bucketKey)?.collection ??\n        this.retiredEntries.get(edgeId)?.get(bucketKey)?.collection ??\n        this.getEntry(edgeId, bucketKey).collection\n      this.resolvedValues.set(value, facade)\n      return facade\n    }\n    if (Array.isArray(value) || isPlainObject(value)) {\n      const result = transformPublicContainers(\n        value,\n        (leaf) => (isBucketFacadeRef(leaf) ? this.resolveValue(leaf) : leaf),\n        PRIVATE_RESULT_KEYS,\n      )\n      this.resolvedValues.set(value, result)\n      return result\n    }\n    return value\n  }\n\n  private cleanupRetiredEntries(): void {\n    for (const byBucket of this.retiredEntries.values()) {\n      for (const entry of byBucket.values()) {\n        void entry.collection.cleanup()\n      }\n    }\n    this.retiredEntries.clear()\n  }\n}\n\nfunction isBucketFacadeRef(value: unknown): value is BucketFacadeRef {\n  return (\n    value !== null && typeof value === `object` && BUCKET_FACADE_REF in value\n  )\n}\n"],"names":["INCLUDES_ROUTING","compilations","pendingActivity","retiredEntries","resolvedValues","output","accumulate","accumulateActivity","getActiveBuckets","getEntry","prepareChange","applyChange","retireEntry","devBuild","codedMessage","resolveValue","cleanupRetiredEntries","getOrCreate","serializeValue","createCollection","BUCKET_FACADE_REF","isPlainObject","transformPublicContainers"],"mappings":"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"}