@tanstack/db
Version:
A reactive client store for building super fast apps on sync
1 lines • 73.8 kB
Source Map (JSON)
{"version":3,"file":"state.cjs","sources":["../../../src/collection/state.ts"],"sourcesContent":["import { deepEquals } from '../utils'\nimport { SortedMap } from '../SortedMap'\nimport { enrichRowWithVirtualProps } from '../virtual-props.js'\nimport { DIRECT_TRANSACTION_METADATA_KEY } from './transaction-metadata.js'\nimport type {\n VirtualOrigin,\n VirtualRowProps,\n WithVirtualProps,\n} from '../virtual-props.js'\nimport type { Transaction } from '../transactions'\nimport type { StandardSchemaV1 } from '@standard-schema/spec'\nimport type {\n ChangeMessage,\n CollectionConfig,\n OptimisticChangeMessage,\n} from '../types'\nimport type { CollectionImpl } from './index.js'\nimport type { CollectionLifecycleManager } from './lifecycle'\nimport type { CollectionChangesManager } from './changes'\nimport type { CollectionIndexesManager } from './indexes'\nimport type { CollectionEventsManager } from './events'\n\ninterface PendingSyncedTransaction<\n T extends object = Record<string, unknown>,\n TKey extends string | number = string | number,\n> {\n committed: boolean\n layoutChanged: boolean\n operations: Array<OptimisticChangeMessage<T>>\n truncate?: boolean\n deletedKeys: Set<string | number>\n rowMetadataWrites: Map<TKey, PendingMetadataWrite>\n collectionMetadataWrites: Map<string, PendingMetadataWrite>\n optimisticSnapshot?: {\n upserts: Map<TKey, T>\n deletes: Set<TKey>\n }\n preserveHydrationSeedKeys?: boolean\n /**\n * When true, this transaction should be processed immediately even if there\n * are persisting user transactions. Used by manual write operations (writeInsert,\n * writeUpdate, writeDelete, writeUpsert) which need synchronous updates to syncedData.\n */\n immediate?: boolean\n}\n\ntype PendingMetadataWrite = { type: `set`; value: unknown } | { type: `delete` }\n\ntype InternalChangeMessage<\n T extends object = Record<string, unknown>,\n TKey extends string | number = string | number,\n> = ChangeMessage<T, TKey> & {\n __virtualProps?: {\n value?: VirtualRowProps<TKey>\n previousValue?: VirtualRowProps<TKey>\n }\n}\n\nexport class CollectionStateManager<\n TOutput extends object = Record<string, unknown>,\n TKey extends string | number = string | number,\n TSchema extends StandardSchemaV1 = StandardSchemaV1,\n TInput extends object = TOutput,\n> {\n public config!: CollectionConfig<TOutput, TKey, TSchema>\n public collection!: CollectionImpl<TOutput, TKey, any, TSchema, TInput>\n public lifecycle!: CollectionLifecycleManager<TOutput, TKey, TSchema, TInput>\n public changes!: CollectionChangesManager<TOutput, TKey, TSchema, TInput>\n public indexes!: CollectionIndexesManager<TOutput, TKey, TSchema, TInput>\n private _events!: CollectionEventsManager\n\n // Core state - make public for testing\n public transactions: SortedMap<string, Transaction<any>>\n public pendingSyncedTransactions: Array<\n PendingSyncedTransaction<TOutput, TKey>\n > = []\n public syncedData: SortedMap<TKey, TOutput>\n public syncedMetadata = new Map<TKey, unknown>()\n public syncedCollectionMetadata = new Map<string, unknown>()\n public hydrationSeedKeys = new Set<TKey>()\n public hydratedKeys = new Set<TKey>()\n\n // Optimistic state tracking - make public for testing\n public optimisticUpserts = new Map<TKey, TOutput>()\n public optimisticDeletes = new Set<TKey>()\n public pendingOptimisticUpserts = new Map<TKey, TOutput>()\n public pendingOptimisticDeletes = new Set<TKey>()\n public pendingOptimisticDirectUpserts = new Set<TKey>()\n public pendingOptimisticDirectDeletes = new Set<TKey>()\n\n /**\n * Tracks the origin of confirmed changes for each row.\n * 'local' = change originated from this client\n * 'remote' = change was received via sync\n *\n * This is used for the $origin virtual property.\n * Note: This only tracks *confirmed* changes, not optimistic ones.\n * Optimistic changes are always considered 'local' for $origin.\n */\n public rowOrigins = new Map<TKey, VirtualOrigin>()\n\n /**\n * Tracks keys that have pending local changes.\n * Used to determine whether sync-confirmed data should have 'local' or 'remote' origin.\n * When sync confirms data for a key with pending local changes, it keeps 'local' origin.\n */\n public pendingLocalChanges = new Set<TKey>()\n public pendingLocalOrigins = new Set<TKey>()\n\n private virtualPropsCache = new WeakMap<\n object,\n {\n synced: boolean\n origin: VirtualOrigin\n key: TKey\n collectionId: string\n enriched: WithVirtualProps<TOutput, TKey>\n }\n >()\n\n // Cached size for performance\n public size = 0\n\n // State used for computing the change events\n public syncedKeys = new Set<TKey>()\n public preSyncVisibleState = new Map<TKey, TOutput>()\n public recentlySyncedKeys = new Set<TKey>()\n public hasReceivedFirstCommit = false\n public isCommittingSyncTransactions = false\n public isLocalOnly = false\n\n /**\n * Creates a new CollectionState manager\n */\n constructor(config: CollectionConfig<TOutput, TKey, TSchema>) {\n this.config = config\n this.transactions = new SortedMap<string, Transaction<any>>((a, b) =>\n a.compareCreatedAt(b),\n )\n\n // Set up data storage - always use SortedMap for deterministic iteration.\n // If a custom compare function is provided, use it; otherwise entries are sorted by key only.\n this.syncedData = new SortedMap<TKey, TOutput>(config.compare)\n }\n\n setDeps(deps: {\n collection: CollectionImpl<TOutput, TKey, any, TSchema, TInput>\n lifecycle: CollectionLifecycleManager<TOutput, TKey, TSchema, TInput>\n changes: CollectionChangesManager<TOutput, TKey, TSchema, TInput>\n indexes: CollectionIndexesManager<TOutput, TKey, TSchema, TInput>\n events: CollectionEventsManager\n }) {\n this.collection = deps.collection\n this.lifecycle = deps.lifecycle\n this.changes = deps.changes\n this.indexes = deps.indexes\n this._events = deps.events\n }\n\n /**\n * Checks whether this row currently has no pending local optimistic writes.\n *\n * This is local mutation status, not backend confirmation: `true` means the\n * row is not currently affected by an optimistic transaction in this\n * collection's visible state.\n *\n * Used to compute the $synced virtual property.\n */\n public isRowSynced(key: TKey): boolean {\n if (this.isLocalOnly) {\n return true\n }\n return !this.optimisticUpserts.has(key) && !this.optimisticDeletes.has(key)\n }\n\n /**\n * Gets the origin of the last confirmed change to a row.\n * Returns 'local' if the row has optimistic mutations (optimistic changes are local).\n * Used to compute the $origin virtual property.\n */\n public getRowOrigin(key: TKey): VirtualOrigin {\n if (this.isLocalOnly) {\n return 'local'\n }\n // If there are optimistic changes, they're local\n if (this.optimisticUpserts.has(key) || this.optimisticDeletes.has(key)) {\n return 'local'\n }\n // Otherwise, return the confirmed origin (defaults to 'remote' for synced data)\n return this.rowOrigins.get(key) ?? 'remote'\n }\n\n private createVirtualPropsSnapshot(\n key: TKey,\n overrides?: Partial<VirtualRowProps<TKey>>,\n ): VirtualRowProps<TKey> {\n return {\n $synced: overrides?.$synced ?? this.isRowSynced(key),\n $origin: overrides?.$origin ?? this.getRowOrigin(key),\n $key: overrides?.$key ?? key,\n $collectionId: overrides?.$collectionId ?? this.collection.id,\n }\n }\n\n private getVirtualPropsSnapshotForState(\n key: TKey,\n options?: {\n rowOrigins?: ReadonlyMap<TKey, VirtualOrigin>\n optimisticUpserts?: Pick<Map<TKey, unknown>, 'has'>\n optimisticDeletes?: Pick<Set<TKey>, 'has'>\n completedOptimisticKeys?: Pick<Map<TKey, unknown>, 'has'>\n },\n ): VirtualRowProps<TKey> {\n if (this.isLocalOnly) {\n return this.createVirtualPropsSnapshot(key, {\n $synced: true,\n $origin: 'local',\n })\n }\n\n const optimisticUpserts =\n options?.optimisticUpserts ?? this.optimisticUpserts\n const optimisticDeletes =\n options?.optimisticDeletes ?? this.optimisticDeletes\n const hasOptimisticChange =\n optimisticUpserts.has(key) ||\n optimisticDeletes.has(key) ||\n options?.completedOptimisticKeys?.has(key) === true\n\n return this.createVirtualPropsSnapshot(key, {\n $synced: !hasOptimisticChange,\n $origin: hasOptimisticChange\n ? 'local'\n : ((options?.rowOrigins ?? this.rowOrigins).get(key) ?? 'remote'),\n })\n }\n\n private snapshotRowOriginsForKeys(\n keys: Iterable<TKey>,\n ): Map<TKey, VirtualOrigin> {\n const rowOrigins = new Map<TKey, VirtualOrigin>()\n\n for (const key of keys) {\n const origin = this.rowOrigins.get(key)\n if (origin !== undefined) {\n rowOrigins.set(key, origin)\n }\n }\n\n return rowOrigins\n }\n\n private enrichWithVirtualPropsSnapshot(\n row: TOutput,\n virtualProps: VirtualRowProps<TKey>,\n ): WithVirtualProps<TOutput, TKey> {\n const existingRow = row as Partial<WithVirtualProps<TOutput, TKey>>\n const synced = existingRow.$synced ?? virtualProps.$synced\n const origin = existingRow.$origin ?? virtualProps.$origin\n const resolvedKey = existingRow.$key ?? virtualProps.$key\n const collectionId = existingRow.$collectionId ?? virtualProps.$collectionId\n\n const cached = this.virtualPropsCache.get(row as object)\n if (\n cached &&\n cached.synced === synced &&\n cached.origin === origin &&\n cached.key === resolvedKey &&\n cached.collectionId === collectionId\n ) {\n return cached.enriched\n }\n\n const enriched = {\n ...row,\n $synced: synced,\n $origin: origin,\n $key: resolvedKey,\n $collectionId: collectionId,\n } as WithVirtualProps<TOutput, TKey>\n\n this.virtualPropsCache.set(row as object, {\n synced,\n origin,\n key: resolvedKey,\n collectionId,\n enriched,\n })\n\n return enriched\n }\n\n private clearOriginTrackingState(): void {\n this.rowOrigins.clear()\n this.pendingLocalChanges.clear()\n this.pendingLocalOrigins.clear()\n }\n\n /**\n * Enriches a row with virtual properties using the \"add-if-missing\" pattern.\n * If the row already has virtual properties (from an upstream collection),\n * they are preserved. Otherwise, new values are computed.\n */\n public enrichWithVirtualProps(\n row: TOutput,\n key: TKey,\n ): WithVirtualProps<TOutput, TKey> {\n return this.enrichWithVirtualPropsSnapshot(\n row,\n this.createVirtualPropsSnapshot(key),\n )\n }\n\n /**\n * Creates a change message with virtual properties.\n * Uses the \"add-if-missing\" pattern so that pass-through from upstream\n * collections works correctly.\n */\n public enrichChangeMessage(\n change: ChangeMessage<TOutput, TKey>,\n ): ChangeMessage<WithVirtualProps<TOutput, TKey>, TKey> {\n const { __virtualProps } = change as InternalChangeMessage<TOutput, TKey>\n const enrichedValue = __virtualProps?.value\n ? this.enrichWithVirtualPropsSnapshot(change.value, __virtualProps.value)\n : this.enrichWithVirtualProps(change.value, change.key)\n const enrichedPreviousValue = change.previousValue\n ? __virtualProps?.previousValue\n ? this.enrichWithVirtualPropsSnapshot(\n change.previousValue,\n __virtualProps.previousValue,\n )\n : this.enrichWithVirtualProps(change.previousValue, change.key)\n : undefined\n\n return {\n key: change.key,\n type: change.type,\n value: enrichedValue,\n previousValue: enrichedPreviousValue,\n metadata: change.metadata,\n } as ChangeMessage<WithVirtualProps<TOutput, TKey>, TKey>\n }\n\n /**\n * Get the current value for a key enriched with virtual properties.\n */\n public getWithVirtualProps(\n key: TKey,\n ): WithVirtualProps<TOutput, TKey> | undefined {\n const value = this.get(key)\n if (value === undefined) {\n return undefined\n }\n return this.enrichWithVirtualProps(value, key)\n }\n\n /**\n * Get the current value for a key (virtual derived state)\n */\n public get(key: TKey): TOutput | undefined {\n const { optimisticDeletes, optimisticUpserts, syncedData } = this\n // Check if optimistically deleted\n if (optimisticDeletes.has(key)) {\n return undefined\n }\n\n // Check optimistic upserts first\n if (optimisticUpserts.has(key)) {\n return optimisticUpserts.get(key)\n }\n\n // Fall back to synced data\n return syncedData.get(key)\n }\n\n /**\n * Check if a key exists in the collection (virtual derived state)\n */\n public has(key: TKey): boolean {\n const { optimisticDeletes, optimisticUpserts, syncedData } = this\n // Check if optimistically deleted\n if (optimisticDeletes.has(key)) {\n return false\n }\n\n // Check optimistic upserts first\n if (optimisticUpserts.has(key)) {\n return true\n }\n\n // Fall back to synced data\n return syncedData.has(key)\n }\n\n /**\n * Get all keys (virtual derived state)\n */\n public *keys(): IterableIterator<TKey> {\n const { syncedData, optimisticDeletes, optimisticUpserts } = this\n // Yield keys from synced data, skipping any that are deleted.\n for (const key of syncedData.keys()) {\n if (!optimisticDeletes.has(key)) {\n yield key\n }\n }\n // Yield keys from upserts that were not already in synced data.\n for (const key of optimisticUpserts.keys()) {\n if (!syncedData.has(key) && !optimisticDeletes.has(key)) {\n // The optimisticDeletes check is technically redundant if inserts/updates always remove from deletes,\n // but it's safer to keep it.\n yield key\n }\n }\n }\n\n /**\n * Get all values (virtual derived state)\n */\n public *values(): IterableIterator<TOutput> {\n for (const key of this.keys()) {\n const value = this.get(key)\n if (value !== undefined) {\n yield value\n }\n }\n }\n\n /**\n * Get all entries (virtual derived state)\n */\n public *entries(): IterableIterator<[TKey, TOutput]> {\n for (const key of this.keys()) {\n const value = this.get(key)\n if (value !== undefined) {\n yield [key, value]\n }\n }\n }\n\n /**\n * Get all entries (virtual derived state)\n */\n public *[Symbol.iterator](): IterableIterator<[TKey, TOutput]> {\n for (const [key, value] of this.entries()) {\n yield [key, value]\n }\n }\n\n /**\n * Execute a callback for each entry in the collection\n */\n public forEach(\n callbackfn: (value: TOutput, key: TKey, index: number) => void,\n ): void {\n let index = 0\n for (const [key, value] of this.entries()) {\n callbackfn(value, key, index++)\n }\n }\n\n /**\n * Create a new array with the results of calling a function for each entry in the collection\n */\n public map<U>(\n callbackfn: (value: TOutput, key: TKey, index: number) => U,\n ): Array<U> {\n const result: Array<U> = []\n let index = 0\n for (const [key, value] of this.entries()) {\n result.push(callbackfn(value, key, index++))\n }\n return result\n }\n\n /**\n * Check if the given collection is this collection\n * @param collection The collection to check\n * @returns True if the given collection is this collection, false otherwise\n */\n private isThisCollection(\n collection: CollectionImpl<any, any, any, any, any>,\n ): boolean {\n return collection === this.collection\n }\n\n /**\n * Recompute optimistic state from active transactions\n */\n public recomputeOptimisticState(\n triggeredByUserAction: boolean = false,\n ): void {\n // Skip redundant recalculations when we're in the middle of committing sync transactions\n // While the sync pipeline is replaying a large batch we still want to honour\n // fresh optimistic mutations from the UI. Only skip recompute for the\n // internal sync-driven redraws; user-triggered work (triggeredByUserAction)\n // must run so live queries stay responsive during long commits.\n if (this.isCommittingSyncTransactions && !triggeredByUserAction) {\n return\n }\n\n const previousState = new Map(this.optimisticUpserts)\n const previousDeletes = new Set(this.optimisticDeletes)\n const previousRowOrigins = this.rowOrigins\n\n // Update pending optimistic state for completed/failed transactions\n for (const transaction of this.transactions.values()) {\n const isDirectTransaction =\n transaction.metadata[DIRECT_TRANSACTION_METADATA_KEY] === true\n if (transaction.state === `completed`) {\n for (const mutation of transaction.mutations) {\n if (!this.isThisCollection(mutation.collection)) {\n continue\n }\n this.pendingLocalOrigins.add(mutation.key)\n if (!mutation.optimistic) {\n continue\n }\n switch (mutation.type) {\n case `insert`:\n case `update`:\n this.pendingOptimisticUpserts.set(\n mutation.key,\n mutation.modified as TOutput,\n )\n this.pendingOptimisticDeletes.delete(mutation.key)\n if (isDirectTransaction) {\n this.pendingOptimisticDirectUpserts.add(mutation.key)\n this.pendingOptimisticDirectDeletes.delete(mutation.key)\n } else {\n this.pendingOptimisticDirectUpserts.delete(mutation.key)\n this.pendingOptimisticDirectDeletes.delete(mutation.key)\n }\n break\n case `delete`:\n this.pendingOptimisticUpserts.delete(mutation.key)\n this.pendingOptimisticDeletes.add(mutation.key)\n if (isDirectTransaction) {\n this.pendingOptimisticDirectUpserts.delete(mutation.key)\n this.pendingOptimisticDirectDeletes.add(mutation.key)\n } else {\n this.pendingOptimisticDirectUpserts.delete(mutation.key)\n this.pendingOptimisticDirectDeletes.delete(mutation.key)\n }\n break\n }\n }\n } else if (transaction.state === `failed`) {\n for (const mutation of transaction.mutations) {\n if (!this.isThisCollection(mutation.collection)) {\n continue\n }\n this.pendingLocalOrigins.delete(mutation.key)\n if (mutation.optimistic) {\n this.pendingOptimisticUpserts.delete(mutation.key)\n this.pendingOptimisticDeletes.delete(mutation.key)\n this.pendingOptimisticDirectUpserts.delete(mutation.key)\n this.pendingOptimisticDirectDeletes.delete(mutation.key)\n }\n }\n }\n }\n\n // Clear current optimistic state\n this.optimisticUpserts.clear()\n this.optimisticDeletes.clear()\n this.pendingLocalChanges.clear()\n\n // Seed optimistic state with pending optimistic mutations only when a sync is pending\n const pendingSyncKeys = new Set<TKey>()\n for (const transaction of this.pendingSyncedTransactions) {\n for (const operation of transaction.operations) {\n pendingSyncKeys.add(operation.key as TKey)\n }\n }\n const staleOptimisticUpserts: Array<TKey> = []\n for (const [key, value] of this.pendingOptimisticUpserts) {\n if (\n pendingSyncKeys.has(key) ||\n this.pendingOptimisticDirectUpserts.has(key)\n ) {\n this.optimisticUpserts.set(key, value)\n } else {\n staleOptimisticUpserts.push(key)\n }\n }\n for (const key of staleOptimisticUpserts) {\n this.pendingOptimisticUpserts.delete(key)\n this.pendingLocalOrigins.delete(key)\n }\n const staleOptimisticDeletes: Array<TKey> = []\n for (const key of this.pendingOptimisticDeletes) {\n if (\n pendingSyncKeys.has(key) ||\n this.pendingOptimisticDirectDeletes.has(key)\n ) {\n this.optimisticDeletes.add(key)\n } else {\n staleOptimisticDeletes.push(key)\n }\n }\n for (const key of staleOptimisticDeletes) {\n this.pendingOptimisticDeletes.delete(key)\n this.pendingLocalOrigins.delete(key)\n }\n\n const activeTransactions: Array<Transaction<any>> = []\n\n for (const transaction of this.transactions.values()) {\n if (![`completed`, `failed`].includes(transaction.state)) {\n activeTransactions.push(transaction)\n }\n }\n\n // Apply active transactions only (completed transactions are handled by sync operations)\n for (const transaction of activeTransactions) {\n for (const mutation of transaction.mutations) {\n if (!this.isThisCollection(mutation.collection)) {\n continue\n }\n\n // Track that this key has pending local changes for $origin tracking\n this.pendingLocalChanges.add(mutation.key)\n\n if (mutation.optimistic) {\n switch (mutation.type) {\n case `insert`:\n case `update`:\n this.optimisticUpserts.set(\n mutation.key,\n mutation.modified as TOutput,\n )\n this.optimisticDeletes.delete(mutation.key)\n break\n case `delete`:\n this.optimisticUpserts.delete(mutation.key)\n this.optimisticDeletes.add(mutation.key)\n break\n }\n }\n }\n }\n\n // Update cached size\n this.size = this.calculateSize()\n\n // Collect events for changes\n const events: Array<InternalChangeMessage<TOutput, TKey>> = []\n this.collectOptimisticChanges(\n previousState,\n previousDeletes,\n previousRowOrigins,\n events,\n )\n\n // Filter out events for recently synced keys to prevent duplicates\n // BUT: Only filter out events that are actually from sync operations\n // New user transactions should NOT be filtered even if the key was recently synced\n const filteredEventsBySyncStatus = events.filter((event) => {\n if (!this.recentlySyncedKeys.has(event.key)) {\n return true // Key not recently synced, allow event through\n }\n\n // Key was recently synced - allow if this is a user-triggered action\n if (triggeredByUserAction) {\n return true\n }\n\n // Otherwise filter out duplicate sync events\n return false\n })\n\n // Filter out redundant delete events if there are pending sync transactions\n // that will immediately restore the same data, but only for completed transactions\n // IMPORTANT: Skip complex filtering for user-triggered actions to prevent UI blocking\n if (this.pendingSyncedTransactions.length > 0 && !triggeredByUserAction) {\n const pendingSyncKeysForFilter = new Set<TKey>()\n\n // Collect keys from pending sync operations\n for (const transaction of this.pendingSyncedTransactions) {\n for (const operation of transaction.operations) {\n pendingSyncKeysForFilter.add(operation.key as TKey)\n }\n }\n\n // Only filter out delete events for keys that:\n // 1. Have pending sync operations AND\n // 2. Are from completed transactions (being cleaned up)\n const filteredEvents = filteredEventsBySyncStatus.filter((event) => {\n if (\n event.type === `delete` &&\n pendingSyncKeysForFilter.has(event.key)\n ) {\n // Check if this delete is from clearing optimistic state of completed transactions\n // We can infer this by checking if we have no remaining optimistic mutations for this key\n const hasActiveOptimisticMutation = activeTransactions.some((tx) =>\n tx.mutations.some(\n (m) => this.isThisCollection(m.collection) && m.key === event.key,\n ),\n )\n\n if (!hasActiveOptimisticMutation) {\n return false // Skip this delete event as sync will restore the data\n }\n }\n return true\n })\n\n // Update indexes for the filtered events\n if (filteredEvents.length > 0) {\n this.indexes.updateIndexes(filteredEvents)\n }\n this.changes.emitEvents(filteredEvents, triggeredByUserAction)\n } else {\n // Update indexes for all events\n if (filteredEventsBySyncStatus.length > 0) {\n this.indexes.updateIndexes(filteredEventsBySyncStatus)\n }\n // Emit all events if no pending sync transactions\n this.changes.emitEvents(filteredEventsBySyncStatus, triggeredByUserAction)\n }\n }\n\n /**\n * Calculate the current size based on synced data and optimistic changes\n */\n private calculateSize(): number {\n const syncedSize = this.syncedData.size\n const deletesFromSynced = Array.from(this.optimisticDeletes).filter(\n (key) => this.syncedData.has(key) && !this.optimisticUpserts.has(key),\n ).length\n const upsertsNotInSynced = Array.from(this.optimisticUpserts.keys()).filter(\n (key) => !this.syncedData.has(key),\n ).length\n\n return syncedSize - deletesFromSynced + upsertsNotInSynced\n }\n\n /**\n * Collect events for optimistic changes\n */\n private collectOptimisticChanges(\n previousUpserts: Map<TKey, TOutput>,\n previousDeletes: Set<TKey>,\n previousRowOrigins: ReadonlyMap<TKey, VirtualOrigin>,\n events: Array<InternalChangeMessage<TOutput, TKey>>,\n ): void {\n const allKeys = new Set([\n ...previousUpserts.keys(),\n ...this.optimisticUpserts.keys(),\n ...previousDeletes,\n ...this.optimisticDeletes,\n ])\n\n for (const key of allKeys) {\n const currentValue = this.get(key)\n const previousValue = this.getPreviousValue(\n key,\n previousUpserts,\n previousDeletes,\n )\n const previousVirtualProps = this.getVirtualPropsSnapshotForState(key, {\n rowOrigins: previousRowOrigins,\n optimisticUpserts: previousUpserts,\n optimisticDeletes: previousDeletes,\n })\n const nextVirtualProps = this.getVirtualPropsSnapshotForState(key)\n\n if (previousValue !== undefined && currentValue === undefined) {\n events.push({\n type: `delete`,\n key,\n value: previousValue,\n __virtualProps: {\n value: previousVirtualProps,\n },\n })\n } else if (previousValue === undefined && currentValue !== undefined) {\n events.push({\n type: `insert`,\n key,\n value: currentValue,\n __virtualProps: {\n value: nextVirtualProps,\n },\n })\n } else if (\n previousValue !== undefined &&\n currentValue !== undefined &&\n previousValue !== currentValue\n ) {\n events.push({\n type: `update`,\n key,\n value: currentValue,\n previousValue,\n __virtualProps: {\n value: nextVirtualProps,\n previousValue: previousVirtualProps,\n },\n })\n }\n }\n }\n\n /**\n * Get the previous value for a key given previous optimistic state\n */\n private getPreviousValue(\n key: TKey,\n previousUpserts: Map<TKey, TOutput>,\n previousDeletes: Set<TKey>,\n ): TOutput | undefined {\n if (previousDeletes.has(key)) {\n return undefined\n }\n if (previousUpserts.has(key)) {\n return previousUpserts.get(key)\n }\n return this.syncedData.get(key)\n }\n\n /**\n * Attempts to commit pending synced transactions if there are no active transactions\n * This method processes operations from pending transactions and applies them to the synced data\n */\n commitPendingTransactions = () => {\n // Check if there are any persisting transaction\n let hasPersistingTransaction = false\n for (const transaction of this.transactions.values()) {\n if (transaction.state === `persisting`) {\n hasPersistingTransaction = true\n break\n }\n }\n\n // pending synced transactions could be either `committed` or still open.\n // we only want to process `committed` transactions here\n const {\n committedSyncedTransactions,\n uncommittedSyncedTransactions,\n hasTruncateSync,\n hasImmediateSync,\n layoutChanged,\n } = this.pendingSyncedTransactions.reduce(\n (acc, t) => {\n if (t.committed) {\n acc.committedSyncedTransactions.push(t)\n acc.layoutChanged ||= t.layoutChanged\n if (t.truncate) {\n acc.hasTruncateSync = true\n }\n if (t.immediate) {\n acc.hasImmediateSync = true\n }\n } else {\n acc.uncommittedSyncedTransactions.push(t)\n }\n return acc\n },\n {\n committedSyncedTransactions: [] as Array<\n PendingSyncedTransaction<TOutput, TKey>\n >,\n uncommittedSyncedTransactions: [] as Array<\n PendingSyncedTransaction<TOutput, TKey>\n >,\n hasTruncateSync: false,\n hasImmediateSync: false,\n layoutChanged: false,\n },\n )\n\n // Process committed transactions if:\n // 1. No persisting user transaction (normal sync flow), OR\n // 2. There's a truncate operation (must be processed immediately), OR\n // 3. There's an immediate transaction (manual writes must be processed synchronously)\n //\n // Note: When hasImmediateSync or hasTruncateSync is true, we process ALL committed\n // sync transactions (not just the immediate/truncate ones). This is intentional for\n // ordering correctness: if we only processed the immediate transaction, earlier\n // non-immediate transactions would be applied later and could overwrite newer state.\n // Processing all committed transactions together preserves causal ordering.\n if (!hasPersistingTransaction || hasTruncateSync || hasImmediateSync) {\n // Set flag to prevent redundant optimistic state recalculations\n this.isCommittingSyncTransactions = true\n\n // Get the optimistic snapshot from the truncate transaction (captured when truncate() was called)\n const truncateOptimisticSnapshot = hasTruncateSync\n ? committedSyncedTransactions.find((t) => t.truncate)\n ?.optimisticSnapshot\n : null\n let truncatePendingLocalChanges: Set<TKey> | undefined\n let truncatePendingLocalOrigins: Set<TKey> | undefined\n\n // First collect all keys that will be affected by sync operations\n const changedKeys = new Set<TKey>()\n for (const transaction of committedSyncedTransactions) {\n for (const operation of transaction.operations) {\n changedKeys.add(operation.key as TKey)\n }\n for (const [key] of transaction.rowMetadataWrites) {\n changedKeys.add(key)\n }\n }\n\n const virtualSnapshotKeys = new Set(changedKeys)\n for (const key of this.pendingOptimisticDirectUpserts) {\n virtualSnapshotKeys.add(key)\n }\n for (const key of this.pendingOptimisticDirectDeletes) {\n virtualSnapshotKeys.add(key)\n }\n const previousRowOrigins =\n this.snapshotRowOriginsForKeys(virtualSnapshotKeys)\n const previousOptimisticUpserts = new Map(this.optimisticUpserts)\n const previousOptimisticDeletes = new Set(this.optimisticDeletes)\n\n // Use pre-captured state if available (from optimistic scenarios),\n // otherwise capture current state (for pure sync scenarios)\n let currentVisibleState = this.preSyncVisibleState\n if (currentVisibleState.size === 0) {\n // No pre-captured state, capture it now for pure sync operations\n currentVisibleState = new Map<TKey, TOutput>()\n for (const key of changedKeys) {\n const currentValue = this.get(key)\n if (currentValue !== undefined) {\n currentVisibleState.set(key, currentValue)\n }\n }\n }\n\n const events: Array<ChangeMessage<TOutput, TKey>> = []\n const rowUpdateMode = this.config.sync.rowUpdateMode || `partial`\n const completedOptimisticOps = new Map<\n TKey,\n { type: string; value: TOutput }\n >()\n\n for (const transaction of this.transactions.values()) {\n if (transaction.state === `completed`) {\n for (const mutation of transaction.mutations) {\n if (this.isThisCollection(mutation.collection)) {\n if (mutation.optimistic) {\n completedOptimisticOps.set(mutation.key, {\n type: mutation.type,\n value: mutation.modified as TOutput,\n })\n }\n }\n }\n }\n }\n\n for (const transaction of committedSyncedTransactions) {\n // Handle truncate operations first\n if (transaction.truncate) {\n // TRUNCATE PHASE\n // 1) Emit a delete for every visible key (synced + optimistic) so downstream listeners/indexes\n // observe a clear-before-rebuild. We intentionally skip keys already in\n // optimisticDeletes because their delete was previously emitted by the user.\n // Use the snapshot to ensure we emit deletes for all items that existed at truncate start.\n const visibleKeys = new Set([\n ...this.syncedData.keys(),\n ...(truncateOptimisticSnapshot?.upserts.keys() || []),\n ])\n for (const key of visibleKeys) {\n if (truncateOptimisticSnapshot?.deletes.has(key)) continue\n const previousValue =\n truncateOptimisticSnapshot?.upserts.get(key) ||\n this.syncedData.get(key)\n if (previousValue !== undefined) {\n events.push({ type: `delete`, key, value: previousValue })\n }\n }\n\n // 2) Clear the authoritative synced base. Subsequent server ops in this\n // same commit will rebuild the base atomically.\n // Preserve pending local tracking just long enough for operations in this\n // truncate batch to retain correct local origin semantics.\n truncatePendingLocalChanges = new Set(this.pendingLocalChanges)\n truncatePendingLocalOrigins = new Set(this.pendingLocalOrigins)\n this.syncedData.clear()\n this.syncedMetadata.clear()\n this.syncedKeys.clear()\n this.hydrationSeedKeys.clear()\n this.hydratedKeys.clear()\n this.clearOriginTrackingState()\n\n // 3) Clear currentVisibleState for truncated keys to ensure subsequent operations\n // are compared against the post-truncate state (undefined) rather than pre-truncate state\n // This ensures that re-inserted keys are emitted as INSERT events, not UPDATE events\n for (const key of changedKeys) {\n currentVisibleState.delete(key)\n }\n\n // 4) Emit truncate event so subscriptions can reset their cursor tracking state\n this._events.emit(`truncate`, {\n type: `truncate`,\n collection: this.collection,\n })\n }\n\n for (const operation of transaction.operations) {\n const key = operation.key as TKey\n this.syncedKeys.add(key)\n\n // Determine origin: 'local' for local-only collections or pending local changes\n const origin: VirtualOrigin =\n this.isLocalOnly ||\n this.pendingLocalChanges.has(key) ||\n this.pendingLocalOrigins.has(key) ||\n truncatePendingLocalChanges?.has(key) === true ||\n truncatePendingLocalOrigins?.has(key) === true\n ? 'local'\n : 'remote'\n\n // Update synced data\n switch (operation.type) {\n case `insert`:\n this.syncedData.set(key, operation.value)\n this.rowOrigins.set(key, origin)\n // Clear pending local changes now that sync has confirmed\n this.pendingLocalChanges.delete(key)\n this.pendingLocalOrigins.delete(key)\n this.pendingOptimisticUpserts.delete(key)\n this.pendingOptimisticDeletes.delete(key)\n this.pendingOptimisticDirectUpserts.delete(key)\n this.pendingOptimisticDirectDeletes.delete(key)\n break\n case `update`: {\n if (rowUpdateMode === `partial`) {\n const updatedValue = Object.assign(\n {},\n this.syncedData.get(key),\n operation.value,\n )\n this.syncedData.set(key, updatedValue)\n } else {\n this.syncedData.set(key, operation.value)\n }\n this.rowOrigins.set(key, origin)\n // Clear pending local changes now that sync has confirmed\n this.pendingLocalChanges.delete(key)\n this.pendingLocalOrigins.delete(key)\n this.pendingOptimisticUpserts.delete(key)\n this.pendingOptimisticDeletes.delete(key)\n this.pendingOptimisticDirectUpserts.delete(key)\n this.pendingOptimisticDirectDeletes.delete(key)\n break\n }\n case `delete`:\n this.syncedData.delete(key)\n this.syncedMetadata.delete(key)\n // Clean up origin and pending tracking for deleted rows\n this.rowOrigins.delete(key)\n this.pendingLocalChanges.delete(key)\n this.pendingLocalOrigins.delete(key)\n this.pendingOptimisticUpserts.delete(key)\n this.pendingOptimisticDeletes.delete(key)\n this.pendingOptimisticDirectUpserts.delete(key)\n this.pendingOptimisticDirectDeletes.delete(key)\n break\n }\n if (!transaction.preserveHydrationSeedKeys) {\n this.hydrationSeedKeys.delete(key)\n this.hydratedKeys.delete(key)\n }\n }\n\n for (const [key, metadataWrite] of transaction.rowMetadataWrites) {\n if (metadataWrite.type === `delete`) {\n this.syncedMetadata.delete(key)\n continue\n }\n this.syncedMetadata.set(key, metadataWrite.value)\n }\n\n for (const [\n key,\n metadataWrite,\n ] of transaction.collectionMetadataWrites) {\n if (metadataWrite.type === `delete`) {\n this.syncedCollectionMetadata.delete(key)\n continue\n }\n this.syncedCollectionMetadata.set(key, metadataWrite.value)\n }\n }\n\n // After applying synced operations, if this commit included a truncate,\n // re-apply optimistic mutations on top of the fresh synced base. This ensures\n // the UI preserves local intent while respecting server rebuild semantics.\n // Ordering: deletes (above) -> server ops (just applied) -> optimistic upserts.\n if (hasTruncateSync) {\n // Avoid duplicating keys that were inserted/updated by synced operations in this commit\n const syncedInsertedOrUpdatedKeys = new Set<TKey>()\n for (const t of committedSyncedTransactions) {\n for (const op of t.operations) {\n if (op.type === `insert` || op.type === `update`) {\n syncedInsertedOrUpdatedKeys.add(op.key as TKey)\n }\n }\n }\n\n // Build re-apply sets from the snapshot taken at the start of this function.\n // This prevents losing optimistic state if transactions complete during truncate processing.\n const reapplyUpserts = new Map<TKey, TOutput>(\n truncateOptimisticSnapshot!.upserts,\n )\n const reapplyDeletes = new Set<TKey>(\n truncateOptimisticSnapshot!.deletes,\n )\n\n // Emit inserts for re-applied upserts, skipping any keys that have an optimistic delete.\n // If the server also inserted/updated the same key in this batch, override that value\n // with the optimistic value to preserve local intent.\n for (const [key, value] of reapplyUpserts) {\n if (reapplyDeletes.has(key)) continue\n if (syncedInsertedOrUpdatedKeys.has(key)) {\n let foundInsert = false\n for (let i = events.length - 1; i >= 0; i--) {\n const evt = events[i]!\n if (evt.key === key && evt.type === `insert`) {\n evt.value = value\n foundInsert = true\n break\n }\n }\n if (!foundInsert) {\n events.push({ type: `insert`, key, value })\n }\n } else {\n events.push({ type: `insert`, key, value })\n }\n }\n\n // Finally, ensure we do NOT insert keys that have an outstanding optimistic delete.\n if (events.length > 0 && reapplyDeletes.size > 0) {\n const filtered: Array<ChangeMessage<TOutput, TKey>> = []\n for (const evt of events) {\n if (evt.type === `insert` && reapplyDeletes.has(evt.key)) {\n continue\n }\n filtered.push(evt)\n }\n events.length = 0\n events.push(...filtered)\n }\n\n // Ensure listeners are active before emitting this critical batch\n if (this.lifecycle.status !== `ready`) {\n this.lifecycle.markReady()\n }\n }\n\n // Maintain optimistic state appropriately\n // Clear optimistic state since sync operations will now provide the authoritative data.\n // Any still-active user transactions will be re-applied below in recompute.\n this.optimisticUpserts.clear()\n this.optimisticDeletes.clear()\n\n // Reset flag and recompute optimistic state for any remaining active transactions\n this.isCommittingSyncTransactions = false\n\n // If we had a truncate, restore the preserved optimistic state from the snapshot\n // This includes items from transactions that may have completed during processing\n if (hasTruncateSync && truncateOptimisticSnapshot) {\n for (const [key, value] of truncateOptimisticSnapshot.upserts) {\n this.optimisticUpserts.set(key, value)\n }\n for (const key of truncateOptimisticSnapshot.deletes) {\n this.optimisticDeletes.add(key)\n }\n }\n\n // Always overlay any still-active optimistic transactions so mutations that started\n // after the truncate snapshot are preserved.\n for (const transaction of this.transactions.values()) {\n if (![`completed`, `failed`].includes(transaction.state)) {\n for (const mutation of transaction.mutations) {\n if (\n this.isThisCollection(mutation.collection) &&\n mutation.optimistic\n ) {\n switch (mutation.type) {\n case `insert`:\n case `update`:\n this.optimisticUpserts.set(\n mutation.key,\n mutation.modified as TOutput,\n )\n this.optimisticDeletes.delete(mutation.key)\n break\n case `delete`:\n this.optimisticUpserts.delete(mutation.key)\n this.optimisticDeletes.add(mutation.key)\n break\n }\n }\n }\n }\n }\n\n // A completed optimistic insert may have used a temporary client key while\n // the sync confirmation used a different server-generated key. Once a\n // sync commit has been applied, stop retaining completed optimistic keys\n // that were not confirmed by this commit so the temporary row is removed.\n for (const key of this.pendingOptimisticDirectUpserts) {\n if (!changedKeys.has(key)) {\n changedKeys.add(key)\n if (!currentVisibleState.has(key)) {\n const previousValue = previousOptimisticUpserts.get(key)\n if (previousValue !== undefined) {\n currentVisibleState.set(key, previousValue)\n }\n }\n this.pendingOptimisticUpserts.delete(key)\n this.pendingLocalOrigins.delete(key)\n }\n }\n for (const key of this.pendingOptimisticDirectDeletes) {\n if (!changedKeys.has(key)) {\n changedKeys.add(key)\n }\n this.pendingOptimisticDeletes.delete(key)\n this.pendingLocalOrigins.delete(key)\n }\n this.pendingOptimisticDirectUpserts.clear()\n this.pendingOptimisticDirectDeletes.clear()\n\n // Now check what actually changed in the final visible state\n for (const key of changedKeys) {\n const previousVisibleValue = currentVisibleState.get(key)\n const newVisibleValue = this.get(key) // This returns the new derived state\n const previousVirtualProps = this.getVirtualPropsSnapshotForState(key, {\n rowOrigins: previousRowOrigins,\n optimisticUpserts: previousOptimisticUpserts,\n optimisticDeletes: previousOptimisticDeletes,\n completedOptimisticKeys: completedOptimisticOps,\n })\n const nextVirtualProps = this.getVirtualPropsSnapshotForState(key)\n const virtualChanged =\n previousVirtualProps.$synced !== nextVirtualProps.$synced ||\n previousVirtualProps.$origin !== nextVirtualProps.$origin\n const previousValueWithVirtual =\n previousVisibleValue !== undefined\n ? enrichRowWithVirtualProps(\n previousVisibleValue,\n key,\n this.collection.id,\n () => previousVirtualProps.$synced,\n () => previousVirtualProps.$origin,\n )\n : undefined\n\n // Check if this sync operation is redundant with a completed optimistic operation\n const completedOp = completedOptimisticOps.get(key)\n let isRedundantSync = false\n\n if (completedOp) {\n if (\n completedOp.type === `delete` &&\n previousVisibleValue !== undefined &&\n newVisibleValue === undefined &&\n deepEquals(completedOp.value, previousVisibleValue)\n ) {\n isRedundantSync = true\n } else if (\n newVisibleValue !== undefined &&\n deepEquals(completedOp.value, newVisibleValue)\n ) {\n isRedundantSync = true\n }\n }\n\n const shouldEmitVirtualUpdate =\n virtualChanged &&\n previousVisibleValue !== undefined &&\n newVisibleValue !== undefined &&\n deepEquals(previousVisibleValue, newVisibleValue)\n\n if (isRedundantSync && !shouldEmitVirtualUpdate) {\n continue\n }\n\n if (\n previousVisibleValue === undefined &&\n newVisibleValue !== undefined\n ) {\n const completedOptimisticOp = completedOptimisticOps.get(key)\n if (completedOptimisticOp) {\n const previousValueFromCompleted = completedOptimisticOp.value\n const previousValueWithVirtualFromCompleted =\n enrichRowWithVirtualProps(\n previousValueFromCompleted,\n key,\n this.collection.id,\n () => previousVirtualProps.$synced,\n () => previousVirtualProps.$origin,\n )\n events.push({\n type: `update`,\n key,\n value: newVisibleValue,\n previousValue: previousValueWithVirtualFromCompleted,\n })\n } else {\n events.push({\n type: `insert`,\n key,\n value: newVisibleValue,\n })\n }\n } else if (\n previousVisibleValue !== undefined &&\n newVisibleValue === undefined\n ) {\n events.push({\n type: `delete`,\n key,\n value: previousValueWithVirtual ?? previousVisibleValue,\n })\n } else if (\n previousVisibleValue !== undefined &&\n newVisibleValue !== undefined &&\n (!deepEquals(previousVisibleValue, newVisibleValue) ||\n shouldEmitVirtualUpdate)\n ) {\n events.push({\n type: `update`,\n key,\n value: newVisibleValue,\n previousValue: previousValueWithVirtual ?? previousVisibleValue,\n })\n }\n }\n\n // Update cached size after synced data changes\n this.size = this.calculateSize()\n\n // Update indexes for all events before emitting\n if (events.length > 0) {\n this.indexes.updateIndexes(events)\n }\n\n // End batching and emit all events (combines any batched events with sync events)\n this.changes.emitEvents(events, true, layoutChanged)\n\n this.pendingSyncedTransactions = uncommittedSyncedTransactions\n\n // Clear the pre-sync state since sync operations are complete\n this.preSyncVisibleState.clear()\n\n // Clear recently synced keys after a microtask to allow recomputeOptimisticState to see them\n Promise.resolve().then(() => {\n this.recentlySyncedKeys.clear()\n })\n\n // Mark that we've received the first commit (for tracking purposes)\n if (!this.hasReceivedFirstCommit) {\n this.hasReceivedFirstCommit = true\n }\n }\n }\n\n /**\n * Schedule cleanup of a transaction when it completes\n */\n public scheduleTransactionCleanup(transaction: Transaction<any>): void {\n // Only schedule cleanup for transactions that aren't already completed\n if (transaction.state === `completed`) {\n this.transactions.delete(transaction.id)\n return\n }\n\n // Schedule cleanup when the transaction completes\n transaction.isPersisted.promise\n .then(() => {\n // Transaction completed successfully, remove it immediately\n this.transactions.delete(transaction.id)\n })\n .catch(() => {\n // Transaction failed, but we want to keep failed transactions for reference\n // so don't remove it.\n // Rollback already triggers state recomputation via touchCollection().\n })\n }\n\n /**\n * Capture visible state for keys that will be affected by pending sync operations\n * This must be called BEFORE onTransactionStateChange clears optimistic state\n */\n public capturePreSyncVisibleState(): void {\n if (this.pendingSyncedTransactions.length === 0) return\n\n // Get all keys that will be affected by sync operations\n const syncedKeys = new Set<TKey>()\n for (const transaction of this.pendingSyncedTransactions) {\n for (const operation of transaction.operations) {\n syncedKeys.add(operation.key as TKey)\n }\n }\n\n // Mark keys as about to be synced to suppress intermediate events from recomputeOptimisticState\n for (const key of syncedKeys) {\n this.recentlySyncedKeys.add(key)\n }\n\n // Only capture current visible state for keys that will be affected by sync operations\n // This is much more efficient than capturing the entire collection state\n // Only capture keys that haven't been captured yet to preserve earlier captures\n for (const key of syncedKeys) {\n if (!this.preSyncVisibleState.has(key)) {\n const currentValue = this.get(key)\n if (currentValue !== undefined) {\n this.preSyncVisibleState.set(key, currentValue)\n }\n }\n }\n }\n\n /**\n * Trigger a recomputation when transactions change\n * This method should be called by the Transaction class when state changes\n */\n public onTransactionStateChange(): void {\n // Check if commitPendingTransactions will be called after this\n // by checking if there are pending sync transactions (same logic as in transactions.ts)\n this.changes.shouldBatchEvents = this.pendingSyncedTransactions.length > 0\n\n // CRITICAL: Capture visible state BEFORE clearing optimistic state\n this.capturePreSyncVisibleState()\n\n this.recomputeOptimisticState(false)\n }\n\n /**\n * Clean up the collection by stopping sync and clearing data\n * This can be called manually or automatically by garbage collection\n */\n public cleanup(): void {\n this.syncedData.clear()\n this.syncedMetadata.clear()\n this.syncedCollectionMetadata.clear()\n this.optimisticUpserts.clear()\n this.optimisticDeletes.clear()\n this.pendingOptimisticUpserts.clear()\n this.pendingOptimisticDeletes.clear()\n this.pendingOptimisticDirectUpserts.clear()\n this.pendingOptimisticDirectDeletes.clear()\n this.hydrationSeedKeys.clear()\n this.hydratedKeys.clear()\n this.clearOriginTrackingState()\n this.isLocalOnly = false\n this.size = 0\n this.pendingSyncedTransactions = []\n this.syncedKeys.clear()\n this.hasReceivedFirstCommit = false\n }\n}\n"],"names":["enrichRowWithVirtualProps","deepEquals","SortedMap","virtualProps","DIRECT_TRANSACTION_METADATA_KEY"],"mappings":"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"}