@tanstack/db
Version:
A reactive client store for building super fast apps on sync
1 lines • 25.3 kB
Source Map (JSON)
{"version":3,"file":"bucket-facade-adapter.cjs","sources":["../../../../src/query/live/bucket-facade-adapter.ts"],"sourcesContent":["import { output, serializeValue } from '@tanstack/db-ivm'\nimport { createCollection } from '../../collection/index.js'\nimport { FN_SELECT_STATE, INCLUDES_ROUTING } from '../compiler/index.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\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 FacadeSnapshot = {\n activeBuckets: Map<string, Set<string>>\n entries: Map<string, Map<string, FacadeEntry>>\n rows: Map<\n FacadeEntry,\n Array<{\n key: string | number\n value: object\n order: string | undefined\n }>\n >\n}\n\nexport type FacadePublication = {\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 readonly pending = new Map<\n string,\n Map<string, Map<string, PendingRow>>\n >()\n private readonly 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\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 const snapshot = this.snapshot()\n const deferredEntries = new Set<FacadeEntry>()\n const publications: Array<PublicationDeferral> = []\n const deferPublication = (entry: FacadeEntry) => {\n if (deferredEntries.has(entry)) return\n deferredEntries.add(entry)\n publications.push(entry.collection._deferPublication())\n }\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 const newBaselines: Array<FacadeEntry> = []\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 deferPublication(entry)\n sync.begin()\n for (const change of changes.values()) {\n this.applyChange(entry, sync, change, compilation.hasOrderBy)\n }\n sync.commit()\n }\n for (const entry of newBaselines) entry.sync?.markReady()\n\n for (const [bucketKey, multiplicity] of activity ?? []) {\n if (multiplicity >= 0) continue\n active.delete(bucketKey)\n this.retireEntry(compilation.edgeId, bucketKey, deferPublication)\n }\n }\n } catch (error) {\n this.restore(snapshot, deferredEntries)\n this.retiredEntries.clear()\n for (const publication of publications) publication.discard()\n throw error\n }\n this.pending.clear()\n this.pendingActivity.clear()\n\n let closed = false\n return {\n publish: () => {\n if (closed) return\n closed = true\n for (const publication of publications) publication.publish()\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 },\n rollback: () => {\n if (closed) return\n closed = true\n this.restore(snapshot, deferredEntries)\n this.retiredEntries.clear()\n for (const publication of publications) publication.discard()\n },\n }\n }\n\n resolve<T>(value: T): T {\n return this.resolveValue(value) as T\n }\n\n cleanup(): void {\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 let buckets = this.pending.get(edgeId)\n if (!buckets) {\n buckets = new Map()\n this.pending.set(edgeId, buckets)\n }\n let rows = buckets.get(bucketKey)\n if (!rows) {\n rows = new Map()\n buckets.set(bucketKey, rows)\n }\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 snapshot(): FacadeSnapshot {\n const rows = new Map<\n FacadeEntry,\n Array<{\n key: string | number\n value: object\n order: string | undefined\n }>\n >()\n for (const byBucket of this.entries.values()) {\n for (const entry of byBucket.values()) {\n rows.set(\n entry,\n [...entry.collection._state.syncedData].map(([key, value]) => ({\n key,\n value,\n order: entry.currentOrder.get(key),\n })),\n )\n }\n }\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,\n }\n }\n\n private restore(\n snapshot: FacadeSnapshot,\n changedEntries: Set<FacadeEntry>,\n ): 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 of changedEntries) {\n if (!previousEntries.has(entry)) continue\n const sync = entry.sync\n if (!sync) continue\n sync.begin()\n sync.truncate()\n entry.currentOrder.clear()\n for (const row of snapshot.rows.get(entry) ?? []) {\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({ type: `insert`, value: row.value })\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 let activity = this.pendingActivity.get(edgeId)\n if (!activity) {\n activity = new Map()\n this.pendingActivity.set(edgeId, activity)\n }\n activity.set(bucketKey, (activity.get(bucketKey) ?? 0) + multiplicity)\n }\n\n private getActiveBuckets(edgeId: string): Set<string> {\n let active = this.activeBuckets.get(edgeId)\n if (!active) {\n active = new Set()\n this.activeBuckets.set(edgeId, active)\n }\n return active\n }\n\n private retireEntry(\n edgeId: string,\n bucketKey: string,\n deferPublication: (entry: FacadeEntry) => void,\n ): void {\n const byBucket = this.entries.get(edgeId)\n const entry = byBucket?.get(bucketKey)\n if (!entry) return\n\n const sync = entry.sync\n const keys = [...entry.collection.keys()]\n if (sync && keys.length > 0) {\n deferPublication(entry)\n sync.begin()\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 let retired = this.retiredEntries.get(edgeId)\n if (!retired) {\n retired = new Map()\n this.retiredEntries.set(edgeId, retired)\n }\n retired.set(bucketKey, entry)\n }\n\n private getEntry(edgeId: string, bucketKey: string): FacadeEntry {\n let byBucket = this.entries.get(edgeId)\n if (!byBucket) {\n byBucket = new Map()\n this.entries.set(edgeId, byBucket)\n }\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(`Bucket facade row has no public key`)\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 =\n orderChanged && sync.collection.get(key) === resolvedRow\n ? { ...resolvedRow }\n : 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`) {\n const cached = this.resolvedValues.get(value)\n if (cached !== undefined) return cached\n }\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)) {\n const result: Array<unknown> = []\n this.resolvedValues.set(value, result)\n result.push(...value.map((item) => this.resolveValue(item)))\n return result\n }\n if (!isPlainObject(value)) return value\n\n const result: Record<PropertyKey, unknown> = {}\n this.resolvedValues.set(value, result)\n for (const key of Reflect.ownKeys(value)) {\n if (key === INCLUDES_ROUTING || key === FN_SELECT_STATE) continue\n result[key] = this.resolveValue(value[key])\n }\n return result\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\nfunction isPlainObject(value: unknown): value is Record<PropertyKey, unknown> {\n if (value === null || typeof value !== `object`) return false\n const prototype = Object.getPrototypeOf(value)\n return prototype === Object.prototype || prototype === null\n}\n"],"names":["output","serializeValue","createCollection","BUCKET_FACADE_REF","result","INCLUDES_ROUTING","FN_SELECT_STATE"],"mappings":"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"}