UNPKG

@tanstack/db

Version:

A reactive client store for building super fast apps on sync

1 lines • 110 kB
{"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 { SyncTransactionAbortedError } from '../errors.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  PendingMutation,\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'\nimport type { Deferred } from '../deferred'\nimport type { DuplicateKeySyncError } from '../errors.js'\n\ntype PendingSyncOperation<\n  T extends object,\n  TKey extends string | number,\n> = OptimisticChangeMessage<T, TKey> & {\n  /** Preserve adapter intent when queue changes require reclassification. */\n  originalSyncType?: `insert`\n  /** A partial update admitted against a row must not become an upsert. */\n  admittedAgainstExistingRow?: boolean\n}\n\ntype PendingSyncedKeyState<T extends object> = {\n  exists: boolean\n  value: T | undefined\n}\n\ntype PendingSyncedProjection<T extends object, TKey extends string | number> = {\n  states: Map<TKey, PendingSyncedKeyState<T>>\n  truncated: boolean\n}\n\ntype PendingInsertDisposition = `insert` | `update` | `duplicate`\n\ninterface PendingSyncedTransaction<\n  T extends object = Record<string, unknown>,\n  TKey extends string | number = string | number,\n> {\n  committed: boolean\n  applicationStarted: boolean\n  layoutChanged: boolean\n  operations: Array<PendingSyncOperation<T, TKey>>\n  truncate?: boolean\n  rowMetadataWrites: Map<TKey, PendingMetadataWrite>\n  explicitRowMetadataWriteKeys?: Set<TKey>\n  collectionMetadataWrites: Map<string, PendingMetadataWrite>\n  /** Resolves after application and rejects if canceled before application. */\n  applied: Deferred<void>\n  optimisticSnapshot?: {\n    upserts: Map<TKey, T>\n    deletes: Set<TKey>\n    ownership: Map<\n      TKey,\n      Array<\n        | { type: `upsert`; value: T; transaction?: Transaction<any> }\n        | { type: `delete`; transaction?: Transaction<any> }\n      >\n    >\n  }\n  preserveHydrationSeedKeys?: boolean\n  /** Present on adapter transactions that can be revalidated after cancel. */\n  duplicateKeyError?: (key: TKey) => DuplicateKeySyncError\n  /** Retained until commit so an invalidated active transaction stays addressable. */\n  invalidationError?: Error\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 InsertDependency = { mutation: object; transaction: Transaction<any> }\n\ntype OptimisticUpsert<T extends object> = Pick<\n  PendingMutation<T>,\n  `key` | `modified`\n> & { insertDependency?: InsertDependency }\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}\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, any>\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  private pendingSyncedProjection: PendingSyncedProjection<TOutput, TKey> = {\n    states: new Map(),\n    truncated: false,\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  // DbClient may receive a stale hydration chunk after an adapter delete.\n  // Only DbClient collections retain these absences until cleanup because\n  // hydration has no completion boundary.\n  private appliedAdapterDeletedKeys?: Set<TKey>\n  private hasAppliedAdapterTruncate = false\n\n  // Optimistic state tracking - make public for testing\n  public optimisticUpserts = new Map<TKey, TOutput>()\n  public optimisticDeletes = new Set<TKey>()\n\n  public pendingOptimisticUpserts = new Map<TKey, OptimisticUpsert<TOutput>>()\n  public pendingOptimisticDeletes = new Set<TKey>()\n  public pendingOptimisticDirectUpserts = new Set<TKey>()\n  public pendingOptimisticDirectDeletes = new Set<TKey>()\n  private acknowledgedInserts = new WeakSet<object>()\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  // Successful mutations retain attribution until sync applies. Active or\n  // failed mutations must not add to, or erase a sibling's entry in, this set.\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  // Hidden keys are captured as undefined so a later recompute cannot become\n  // the baseline for a sync commit that must publish that key's change.\n  public preSyncVisibleState = new Map<TKey, TOutput | undefined>()\n  public preSyncVirtualState = new Map<TKey, VirtualRowProps<TKey>>()\n  public recentlySyncedKeys = new Set<TKey>()\n  public hasReceivedFirstCommit = false\n  public isCommittingSyncTransactions = false\n  private isDrainingSyncTransactions = false\n  private syncRunGeneration = 0\n  public isLocalOnly = false\n\n  /**\n   * Creates a new CollectionState manager\n   */\n  constructor(config: CollectionConfig<TOutput, TKey, TSchema, any>) {\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    // A retained update can depend on an unconfirmed insert, not just its key.\n    // Keep that exact dependency so settlement and key reuse cannot conflate rows.\n    const pendingInserts = new Map<TKey, InsertDependency>()\n    // Retain successful contributions; failed/active work is recomputed below.\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          // Only a sync write during this insertion acknowledges it. A stale\n          // base row can also exist after an optimistic delete and reinsert.\n          if (\n            isDirectTransaction &&\n            mutation.type === `insert` &&\n            this.acknowledgedInserts.has(mutation)\n          ) {\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              // Retain whole snapshots, not fields rebased over newer synced\n              // values. A slow insert must not replace its accepted dependent\n              // update with the older insertion snapshot.\n              const previous = this.pendingOptimisticUpserts.get(mutation.key)\n              const confirmsInsert =\n                previous?.insertDependency?.mutation === mutation\n              const insertDependency =\n                mutation.type === `update`\n                  ? (previous?.insertDependency ??\n                    pendingInserts.get(mutation.key))\n                  : undefined\n              this.pendingOptimisticUpserts.set(mutation.key, {\n                key: mutation.key,\n                modified: confirmsInsert\n                  ? previous.modified\n                  : mutation.modified,\n                insertDependency,\n              })\n              // This accepted edit is conditional on the unconfirmed insert.\n              // It cannot retire the accepted delete underneath that insert.\n              if (!insertDependency) {\n                this.pendingOptimisticDeletes.delete(mutation.key)\n                this.pendingOptimisticDirectDeletes.delete(mutation.key)\n              }\n              if (isDirectTransaction) {\n                this.pendingOptimisticDirectUpserts.add(mutation.key)\n              } else {\n                this.pendingOptimisticDirectUpserts.delete(mutation.key)\n              }\n              break\n            }\n            case `delete`: {\n              // An accepted edit of a still-active reinsert belongs after this\n              // older delete. Keep both layers so failure of the insert still\n              // reveals the accepted delete.\n              const hasDependentEdit =\n                this.pendingOptimisticUpserts.get(mutation.key)\n                  ?.insertDependency !== undefined\n              if (!hasDependentEdit) {\n                this.pendingOptimisticUpserts.delete(mutation.key)\n                this.pendingOptimisticDirectUpserts.delete(mutation.key)\n              }\n              this.pendingOptimisticDeletes.add(mutation.key)\n              if (isDirectTransaction) {\n                this.pendingOptimisticDirectDeletes.add(mutation.key)\n              } else {\n                this.pendingOptimisticDirectDeletes.delete(mutation.key)\n              }\n              break\n            }\n          }\n        }\n      } else {\n        for (const mutation of transaction.mutations) {\n          if (\n            !this.isThisCollection(mutation.collection) ||\n            mutation.type !== `insert` ||\n            !mutation.optimistic\n          )\n            continue\n          if (\n            transaction.state !== `failed` &&\n            !this.acknowledgedInserts.has(mutation)\n          ) {\n            pendingInserts.set(mutation.key, { mutation, transaction })\n          } else if (\n            this.pendingOptimisticUpserts.get(mutation.key)?.insertDependency\n              ?.mutation === mutation\n          ) {\n            // Drop only the dependent row, never a later same-key insertion or\n            // successful sibling attribution. Failed transactions remain listed.\n            this.pendingOptimisticUpserts.delete(mutation.key)\n            this.pendingOptimisticDirectUpserts.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, this.resolveOptimisticUpsert(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                this.resolveOptimisticUpsert(mutation),\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.changes.shouldBatchEvents && !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        (!deepEquals(previousValue, currentValue) ||\n          previousVirtualProps.$origin !== nextVirtualProps.$origin ||\n          previousVirtualProps.$synced !== nextVirtualProps.$synced)\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  // Optimistic mutations keep their full validated snapshot. Mixing in newer\n  // synced fields could produce a row neither the user nor the server created.\n  private resolveOptimisticUpsert(\n    mutation: OptimisticUpsert<TOutput>,\n  ): TOutput {\n    const key = mutation.key as TKey\n    const dependent = this.pendingOptimisticUpserts.get(key)\n    return dependent?.insertDependency?.mutation === mutation\n      ? dependent.modified\n      : mutation.modified\n  }\n\n  /**\n   * Capture the optimistic layers that exist when a truncate is authored.\n   * Keeping their exact owners lets application discard a later rollback\n   * without reviving a failed same-key winner or retaining post-capture work.\n   */\n  public captureTruncateOptimisticSnapshot(): NonNullable<\n    PendingSyncedTransaction<TOutput, TKey>[`optimisticSnapshot`]\n  > {\n    const upserts = new Map(this.optimisticUpserts)\n    const deletes = new Set(this.optimisticDeletes)\n    const ownership = new Map<\n      TKey,\n      Array<\n        | {\n            type: `upsert`\n            value: TOutput\n            transaction?: Transaction<any>\n          }\n        | { type: `delete`; transaction?: Transaction<any> }\n      >\n    >()\n    const capturedKeys = new Set([...upserts.keys(), ...deletes])\n    const addLayer = (\n      key: TKey,\n      layer:\n        | {\n            type: `upsert`\n            value: TOutput\n            transaction?: Transaction<any>\n          }\n        | { type: `delete`; transaction?: Transaction<any> },\n    ) => {\n      if (!capturedKeys.has(key)) return\n      const layers = ownership.get(key) ?? []\n      layers.push(layer)\n      ownership.set(key, layers)\n    }\n\n    for (const key of capturedKeys) {\n      const acceptedUpsert = this.pendingOptimisticUpserts.get(key)\n      // A later accepted edit can depend on an active insert above an older\n      // accepted delete. Capture both so the delete survives insert rollback.\n      if (this.pendingOptimisticDeletes.has(key)) {\n        addLayer(key, { type: `delete` })\n      }\n      if (acceptedUpsert) {\n        addLayer(key, {\n          type: `upsert`,\n          value: this.resolveOptimisticUpsert(acceptedUpsert),\n          transaction: acceptedUpsert.insertDependency?.transaction,\n        })\n      }\n    }\n\n    for (const transaction of this.transactions.values()) {\n      if ([`completed`, `failed`].includes(transaction.state)) continue\n      for (const mutation of transaction.mutations) {\n        if (\n          !mutation.optimistic ||\n          !this.isThisCollection(mutation.collection) ||\n          !capturedKeys.has(mutation.key as TKey)\n        )\n          continue\n        if (mutation.type === `delete`) {\n          addLayer(mutation.key as TKey, { type: `delete`, transaction })\n        } else {\n          addLayer(mutation.key as TKey, {\n            type: `upsert`,\n            value: this.resolveOptimisticUpsert(mutation),\n            transaction,\n          })\n        }\n      }\n    }\n\n    return { upserts, deletes, ownership }\n  }\n\n  /** Build once per output flush; queued membership excludes optimistic edits. */\n  createSyncedKeyLookup(): (key: TKey) => boolean {\n    if (this.pendingSyncedTransactions.length === 0)\n      return (key) => this.syncedData.has(key)\n    const queued = new Map<TKey, boolean>()\n    let truncated = false\n    for (const transaction of this.pendingSyncedTransactions) {\n      if (!transaction.committed) continue\n      if (transaction.truncate) {\n        queued.clear()\n        truncated = true\n      }\n      for (const operation of transaction.operations) {\n        queued.set(operation.key as TKey, operation.type !== `delete`)\n      }\n    }\n    return (key) => queued.get(key) ?? (!truncated && this.syncedData.has(key))\n  }\n\n  enableHydrationAuthorityTracking(): void {\n    this.appliedAdapterDeletedKeys ??= new Set<TKey>()\n  }\n\n  /** A late hydration seed cannot supersede committed adapter work. */\n  createAdapterAuthorityLookup(): (key: TKey) => boolean {\n    const queuedKeys = new Set<TKey>()\n    let queuedTruncate = false\n    for (const transaction of this.pendingSyncedTransactions) {\n      if (!transaction.committed || transaction.preserveHydrationSeedKeys)\n        continue\n      if (transaction.truncate) queuedTruncate = true\n      for (const operation of transaction.operations) {\n        queuedKeys.add(operation.key as TKey)\n      }\n    }\n    return (key) =>\n      this.hasAppliedAdapterTruncate ||\n      queuedTruncate ||\n      queuedKeys.has(key) ||\n      this.appliedAdapterDeletedKeys?.has(key) === true ||\n      (this.syncedData.has(key) && !this.hydrationSeedKeys.has(key))\n  }\n\n  private getProjectedSyncedKeyState(\n    projection: PendingSyncedProjection<TOutput, TKey>,\n    key: TKey,\n  ): PendingSyncedKeyState<TOutput> {\n    const state = projection.states.get(key)\n    if (state !== undefined) return state\n    if (projection.truncated) return { exists: false, value: undefined }\n    return {\n      exists: this.syncedData.has(key),\n      value: this.syncedData.get(key),\n    }\n  }\n\n  private classifyProjectedInsert(\n    projection: PendingSyncedProjection<TOutput, TKey>,\n    key: TKey,\n    value: TOutput,\n  ): PendingInsertDisposition {\n    const current = this.getProjectedSyncedKeyState(projection, key)\n    if (!current.exists) return `insert`\n    if (\n      (current.value !== undefined && deepEquals(current.value, value)) ||\n      this.hydrationSeedKeys.has(key)\n    ) {\n      return `update`\n    }\n    return `duplicate`\n  }\n\n  /** Classify an adapter insert against retained and queued source state. */\n  classifyPendingSyncedInsert(\n    key: TKey,\n    value: TOutput,\n  ): PendingInsertDisposition {\n    return this.classifyProjectedInsert(\n      this.pendingSyncedProjection,\n      key,\n      value,\n    )\n  }\n\n  private applyPendingSyncOperation(\n    projection: PendingSyncedProjection<TOutput, TKey>,\n    operation: PendingSyncOperation<TOutput, TKey>,\n  ): void {\n    const key = operation.key as TKey\n    const rowUpdateMode = this.config.sync.rowUpdateMode || `partial`\n    if (operation.type === `delete`) {\n      projection.states.set(key, { exists: false, value: undefined })\n    } else if (operation.type === `update` && rowUpdateMode === `partial`) {\n      const current = this.getProjectedSyncedKeyState(projection, key)\n      projection.states.set(key, {\n        exists: true,\n        value: Object.assign({}, current.value, operation.value),\n      })\n    } else {\n      projection.states.set(key, { exists: true, value: operation.value })\n    }\n  }\n\n  /** Extend the queued projection after admitting one sync operation. */\n  stagePendingSyncOperation(\n    operation: PendingSyncOperation<TOutput, TKey>,\n  ): void {\n    if (\n      operation.type === `update` &&\n      operation.originalSyncType !== `insert` &&\n      this.config.sync.rowUpdateMode !== `full`\n    ) {\n      operation.admittedAgainstExistingRow = this.getProjectedSyncedKeyState(\n        this.pendingSyncedProjection,\n        operation.key as TKey,\n      ).exists\n    }\n    this.applyPendingSyncOperation(this.pendingSyncedProjection, operation)\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  private rebuildAutomaticRowMetadataWrites(\n    transaction: PendingSyncedTransaction<TOutput, TKey>,\n  ): void {\n    const explicitKeys = transaction.explicitRowMetadataWriteKeys ?? new Set()\n    const operationKeys = new Set(\n      transaction.operations.map((operation) => operation.key as TKey),\n    )\n    for (const key of operationKeys) {\n      if (!explicitKeys.has(key)) transaction.rowMetadataWrites.delete(key)\n    }\n    for (const operation of transaction.operations) {\n      const key = operation.key as TKey\n      if (explicitKeys.has(key)) continue\n      if (operation.type === `delete`) {\n        transaction.rowMetadataWrites.set(key, { type: `delete` })\n      } else if (operation.metadata !== undefined) {\n        transaction.rowMetadataWrites.set(key, {\n          type: `set`,\n          value: operation.metadata,\n        })\n      } else if (operation.type === `insert`) {\n        transaction.rowMetadataWrites.set(key, { type: `delete` })\n      }\n    }\n  }\n\n  private rebuildPendingSyncedProjection(): Array<{\n    transaction: PendingSyncedTransaction<TOutput, TKey>\n    key: TKey\n    error: Error\n  }> {\n    const projection: PendingSyncedProjection<TOutput, TKey> = {\n      states: new Map(),\n      truncated: false,\n    }\n    const invalidCommitted: Array<{\n      transaction: PendingSyncedTransaction<TOutput, TKey>\n      key: TKey\n      error: Error\n    }> = []\n\n    for (const transaction of this.pendingSyncedTransactions) {\n      // An open transaction invalidated by cancellation remains doomed until\n      // its commit returns the rejected applied receipt. truncate() can reset\n      // it explicitly after clearing its operations.\n      if (transaction.invalidationError !== undefined) continue\n      const wasTruncated = projection.truncated\n      const statesBeforeTruncate = transaction.truncate\n        ? projection.states\n        : undefined\n      const previousStates = new Map<\n        TKey,\n        PendingSyncedKeyState<TOutput> | undefined\n      >()\n      if (transaction.truncate) {\n        projection.states = new Map()\n        projection.truncated = true\n      }\n\n      let invalidKey: TKey | undefined\n      let invalidReason: Error | undefined\n      for (const operation of transaction.operations) {\n        const key = operation.key as TKey\n        if (!previousStates.has(key)) {\n          previousStates.set(key, projection.states.get(key))\n        }\n        if (\n          operation.originalSyncType === `insert` &&\n          operation.type !== `delete`\n        ) {\n          const disposition = this.classifyProjectedInsert(\n            projection,\n            key,\n            operation.value,\n          )\n          if (disposition === `duplicate`) {\n            invalidKey = key\n            break\n          }\n          operation.type = disposition\n        }\n        if (\n          operation.admittedAgainstExistingRow === true &&\n          !this.getProjectedSyncedKeyState(projection, key).exists\n        ) {\n          // Cancellation must not turn an admitted dependent update into an\n          // independent missing-key upsert during queue replay.\n          invalidKey = key\n          invalidReason = new SyncTransactionAbortedError()\n          break\n        }\n        this.applyPendingSyncOperation(projection, operation)\n      }\n\n      if (invalidKey !== undefined) {\n        if (statesBeforeTruncate !== undefined) {\n          projection.states = statesBeforeTruncate\n        } else {\n          for (const [key, previous] of previousStates) {\n            if (previous === undefined) projection.states.delete(key)\n            else projection.states.set(key, previous)\n          }\n        }\n        projection.truncated = wasTruncated\n        const error =\n          invalidReason ??\n          transaction.duplicateKeyError?.(invalidKey) ??\n          new SyncTransactionAbortedError()\n        if (transaction.committed) {\n          invalidCommitted.push({ transaction, key: invalidKey, error })\n          continue\n        }\n        transaction.invalidationError = error\n        continue\n      }\n      this.rebuildAutomaticRowMetadataWrites(transaction)\n    }\n\n    this.pendingSyncedProjection = projection\n    return invalidCommitted\n  }\n\n  private rejectInvalidCommittedTransactions(\n    invalid: ReturnType<typeof this.rebuildPendingSyncedProjection>,\n  ): Set<TKey> {\n    const rejected = new Set(invalid.map(({ transaction }) => transaction))\n    this.pendingSyncedTransactions = this.pendingSyncedTransactions.filter(\n      (transaction) => !rejected.has(transaction),\n    )\n    const canceledKeys = new Set<TKey>()\n    for (const { transaction, error } of invalid) {\n      for (const operation of transaction.operations) {\n        canceledKeys.add(operation.key as TKey)\n      }\n      transaction.applied.reject(error)\n    }\n    return canceledKeys\n  }\n\n  /** Rebuild after truncate or application changes queue history. */\n  refreshPendingSyncedProjection(): void {\n    const invalid = this.rebuildPendingSyncedProjection()\n    if (invalid.length === 0) return\n    this.rejectInvalidCommittedTransactions(invalid)\n    throw invalid[0]!.error\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    if (this.isDrainingSyncTransactions) return\n    this.isDrainingSyncTransactions = true\n    let failed = false\n    let firstError: unknown\n    try {\n      let result: { processed: boolean; failure?: { error: unknown } }\n      do {\n        result = this.commitNextPendingTransactionBatch()\n        if (result.failure && !failed) {\n          failed = true\n          firstError = result.failure.error\n        }\n      } while (result.processed)\n    } finally {\n      this.isDrainingSyncTransactions = false\n    }\n    if (failed) throw firstError\n  }\n\n  private commitNextPendingTransactionBatch(): {\n    processed: boolean\n    failure?: { error: unknown }\n  } {\n    const syncRunGeneration = this.syncRunGeneration\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    if (committedSyncedTransactions.length === 0) {\n      return { processed: false }\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      const previousLayout = layoutChanged ? [...this.keys()] : undefined\n      this.pendingSyncedTransactions = uncommittedSyncedTransactions\n\n      // Application is now the point of no return. Event listeners run before\n      // the receipts resolve, so a signal aborted from one of those listeners\n      // must not cancel writes that are already becoming visible.\n      const deferOrder =\n        committedSyncedTransactions.reduce(\n          (count, transaction) => count + transaction.operations.length,\n          0,\n        ) >= 512\n      for (const transaction of committedSyncedTransactions) {\n        transaction.applicationStarted = true\n      }\n\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      // Snapshot capture and application can be separated by mutation\n      // settlement. Freeze ownership at the application boundary: a rolled\n      // back row is no longer owned, while an accepted non-direct mutation can\n      // be cleared from the live pending maps by its source confirmation later\n      // in this same atomic batch.\n      const retainedTruncateLayer = (key: TKey) => {\n        const layers = truncateOptimisticSnapshot?.ownership.get(key) ?? []\n        for (let index = layers.length - 1; index >= 0; index--) {\n          const layer = layers[index]!\n          if (\n            layer.transaction === undefined ||\n            layer.transaction.state !== `failed`\n          ) {\n            return layer\n          }\n        }\n        return undefined\n      }\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      const syncedInsertedOrUpdatedKeys = new Set<TKey>()\n      const firstSyncOperations = new Map<\n        TKey,\n        OptimisticChangeMessage<TOutput>\n      >()\n      for (const transaction of committedSyncedTransactions) {\n        for (const operation of transaction.operations) {\n          const key = operation.key as TKey\n          changedKeys.add(key)\n          if (!firstSyncOperations.has(key))\n            firstSyncOperations.set(key, operation)\n          if (operation.type !== `delete`) syncedInsertedOrUpdatedKeys.add(key)\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      const completedDirectUpserts = new Set(\n        this.pendingOptimisticDirectUpserts,\n      )\n      const completedDirectDeletes = new Set(\n        this.pendingOptimisticDirectDeletes,\n      )\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 | undefined>()\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      if (hasTruncateSync) {\n        // All queued transactions publish as one batch. Its clear prefix must\n        // describe the prior visible rows, not intermediate queued writes.\n        // Freeze metadata before replacement writes change row attribution.\n        for (const [key, value] of this.entries()) {\n          events.push({\n            type: `delete`,\n            key,\n            value: this.enrichWithVirtualPropsSnapshot(\n              value,\n              this.getVirtualPropsSnapshotForState(key),\n            ),\n          })\n        }\n      }\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          // 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.hydrationSeedKeys.clear()\n          this.hydratedKeys.clear()\n          if (\n            !transaction.preserveHydrationSeedKeys &&\n            this.appliedAdapterDeletedKeys\n          ) {\n            this.hasAppliedAdapterTruncate = true\n            this.appliedAdapterDeletedKeys.clear()\n          }\n          this.clearOriginTrackingState()\n\n          // 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          // 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        // Attribution belongs to the whole atomic batch. A repeated write must\n        // not forget the local acknowledgement consumed by its first operation.\n        const localKeys = new Set<TKey>()\n        for (const operation of transaction.operations) {\n          const key = operation.key as TKey\n\n          // Determine origin: 'local' for local-only collections or pending local changes\n          const retainedLocalOrigin =\n            truncatePendingLocalChanges?.has(key) === true ||\n            (truncatePendingLocalOrigins?.has(key) === true &&\n              !completedDirectUpserts.has(key) &&\n              !completedDirectDeletes.has(key))\n          const origin: VirtualOrigin =\n            this.isLocalOnly ||\n            this.pendingLocalChanges.has(key) ||\n            this.pendingLocalOrigins.has(key) ||\n            localKeys.has(key) ||\n            retainedLocalOrigin\n              ? 'local'\n              : 'remote'\n          if (origin === `local`) localKeys.add(key)\n\n          // A sync source may reuse a live-reading row object, making an\n          // enriched snapshot cached for an earlier publication stale.\n          if (operation.type !== `delete`)\n            this.virtualPropsCache.delete(operation.value)\n\n          // Update synced data\n          switch (operation.type) {\n            case `insert`:\n              this.syncedData.set(key, operation.value, deferOrder)\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, deferOrder)\n              } else {\n                this.syncedData.set(key, operation.value, deferOrder)\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, deferOrder)\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            if (operation.type === `delete`)\n              this.appliedAdapterDeletedKeys?.add(key)\n            else this.appliedAdapterDeletedKeys?.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      this.syncedData.restoreOrder()\n\n      // The retained base now includes every removed committed transaction.\n      // Rebuild only the projection for still-open transactions.\n      this.refreshPendingSyncedProjection()\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        // An active delete can hide an accepted snapshot. Retain it through\n        // truncate so rollback can restore it. A direct insert completed after\n        // snapshot capture has no support in the replacement and must retire.\n        if (\n          hasTruncateSync &&\n          this.pendingOptimisticUpserts.has(key) &&\n          (truncateOptimisticSnapshot?.upserts.has(key) === true ||\n            truncateOptimisticSnapshot?.deletes.has(key) === true) &&\n          !changedKeys.has(key)\n        )\n          continue\n        if (!changedKeys.has(key)) {\n          changedKeys.add(key)\n          // Truncate already emitted the prior visible rows as its clear\n          // prefix. Reconstructing one here would publish a duplicate delete.\n          if (!hasTruncateSync && !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        this.pendingOptimisticDirectUpserts.delete(key)\n      }\n      for (const key of this.pendingOptimisticDirectDeletes) {\n        if (\n          hasTruncateSync &&\n          (truncateOptimisticSnapshot?.deletes.has(key) ||\n            truncateOptimisticSnapshot?.ownership\n              .get(key)\n              ?.some(\n                (layer) => layer.type === `delete` && !layer.transaction,\n              )) &&\n          !changedKeys.has(key)\n        )\n          continue\n        if (!changedKeys.has(key)) {\n          changedKeys.add(key)\n        }\n        this.pendingOptimisticDeletes.delete(key)\n        this.pendingLocalOrigins.delete(key)\n        this.pendingOptimisticDirectDeletes.delete(key)\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 of truncateOptimisticSnapshot.ownership.keys()) {\n          const layer = retainedTruncateLayer(key)\n          if (!layer) continue\n          if (layer.type === `upsert`) {\n            if (completedDirectUpserts.has(key) && changedKeys.has(key))\n              continue\n            this.optimisticUpserts.set(key, layer.value)\n          } else {\n            if (completedDirectDeletes.has(key) && changedKeys.has(key))\n              continue\n            this.optimisticDeletes.add(key)\n          }\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            // Truncate clears attribution with the old base, not the still-live\n            // local requests. Preserve them for later source acknowledgements.\n            if (this.isThisCollection(mutation.collection))\n              this.pendingLocalChanges.add(mutation.key)\n            if (\n              this.isThisCollection(mutation.collection) &&\n              mutation.type === `insert` &&\n              syncedInsertedOrUpdatedKeys.has(mutation.key)\n            ) {\n              this.acknowledgedInserts.add(mutation)\n            }\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                    this.resolveOptimisticUpsert(mutation),\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      // 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        // Events use the same rebuilt overlay as synchronous reads.\n        const reapplyUpserts = this.optimisticUpserts\n        const reapplyDeletes = this.optimisticDeletes\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      // Now check what actually changed in the final visible state\n      for (const key of changedKeys) {\n        const firstSyncOperation = firstSyncOperations.get(key)\n        // A live-reading source can change a reused row before this commit\n        // captures it. Later writes must not substitute an intermediate value.\n        const syncPreviousValue =\n          firstSyncOperation?.type === `update` &&\n          currentVisibleState.get(key) === firstSyncOperation.value\n            ? firstSyncOperation.previousValue\n            : undefined\n        const previousVisibleValue =\n          !hasTruncateSync &&\n          !previousOptimisticUpserts.has(key) &&\n          !previousOptimisticDeletes.has(key) &&\n          syncPreviousValue !== undefined\n            ? syncPreviousValue\n            : currentVisibleState.get(key)\n        const newVisibleValue = this.get(key) // This returns the new derived state\n        const previousVirtualProps =\n          this.preSyncVirtualState.get(key) ??\n          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        const shouldEmitVirtualUpdate =\n          virtualChanged &&\n          previousVisibleValue !== undefined &&\n          newVisibleValue !== undefined &&\n          deepEquals(previousVisibleValue, newVisibleValue)\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      let failure: { error: unknown } | undefined\n      try {\n        const visibleLayoutChanged =\n          previousLayout !== undefined &&\n          (previousLayout.length !== this.size ||\n            [...this.keys()].some(\n              (key, index) => key !== previousLayout[index],\n            ))\n        this.changes.emitEvents(events, true, visibleLayoutChanged)\n      } catch (error) {\n        failure = { error }\n      }\n\n      if (this.syncRunGeneration === syncRunGeneration) {\n        this.preSyncVisibleState.clear()\n        this.preSyncVirtualState.clear()\n        Promise.resolve().then(() => {\n          if (this.syncRunGeneration === syncRunGeneration) {\n            this.recentlySyncedKeys.clear()\n          }\n        })\n        if (!this.hasReceivedFirstCommit) this.hasReceivedFirstCommit = true\n      }\n\n      for (const transaction of committedSyncedTransactions) {\n        transaction.applied.resolve()\n      }\n\n      return { processed: true, failure }\n    }\n\n    return { processed: false }\n  }\n\n  /** Abandons a queued transaction and invalidated dependents before visibility. */\n  public cancelPendingSyncedTransaction(\n    transaction: PendingSyncedTransaction<TOutput, TKey>,\n    reason: Error = new SyncTransactionAbortedError(),\n  ): void {\n    if (transaction.applicationStarted) return\n\n    const index = this.pendingSyncedTransactions.indexOf(transaction)\n    if (index === -1) return\n\n    const canceledKeys = new Set<TKey>()\n    const cancel = (\n      pending: PendingSyncedTransaction<TOutput, TKey>,\n      error: Error,\n    ) => {\n      const pendingIndex = this.pendingSyncedTransactions.indexOf(pending)\n      if (pendingIndex === -1 || pending.applicationStarted) return\n      this.pendingSyncedTransactions.splice(pendingIndex, 1)\n      for (const operation of pending.operations) {\n        canceledKeys.add(operation.key as TKey)\n      }\n      pending.applied.reject(error)\n    }\n\n    cancel(transaction, reason)\n\n    // Admission can depend on earlier queued writes. After cancellation,\n    // replay the queue with the same classifier used by normal admission.\n    // Committed invalid dependents are rejected now. An active invalidated\n    // transaction stays addressable until its caller invokes commit().\n    const invalid = this.rebuildPendingSyncedProjection()\n    for (const key of this.rejectInvalidCommittedTransactions(invalid)) {\n      canceledKeys.add(key)\n    }\n\n    const remainingPendingKeys = new Set<TKey>()\n    for (const pending of this.pendingSyncedTransactions) {\n      if (pending.invalidationError !== undefined) continue\n      for (const operation of pending.operations) {\n        remainingPendingKeys.add(operation.key as TKey)\n      }\n    }\n    for (const key of canceledKeys) {\n      if (!remainingPendingKeys.has(key)) {\n        this.recentlySyncedKeys.delete(key)\n        this.preSyncVisibleState.delete(key)\n        this.preSyncVirtualState.delete(key)\n      }\n    }\n\n    if (this.pendingSyncedTransactions.length === 0) {\n      this.preSyncVisibleState.clear()\n      this.preSyncVirtualState.clear()\n      this.recentlySyncedKeys.clear()\n      this.changes.emitEvents([], true)\n    } else {\n      // Recompute after removing the canceled keys so optimistic cleanup is\n      // no longer suppressed by a sync transaction that will never publish.\n      this.recomputeOptimisticState(false)\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        this.preSyncVisibleState.set(key, currentValue)\n        if (currentValue !== undefined) {\n          this.preSyncVirtualState.set(\n            key,\n            this.getVirtualPropsSnapshotForState(key),\n          )\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    // Batch only when the next sync drain can actually publish. A persisting\n    // sibling can keep normal sync queued; it must not hide this rollback.\n    const hasPersistingTransaction = [...this.transactions.values()].some(\n      (transaction) => transaction.state === `persisting`,\n    )\n    this.changes.shouldBatchEvents = this.pendingSyncedTransactions.some(\n      (transaction) =>\n        transaction.committed &&\n        (!hasPersistingTransaction ||\n          transaction.immediate ||\n          transaction.truncate),\n    )\n\n    // CRITICAL: Capture visible state BEFORE clearing optimistic state\n    if (this.changes.shouldBatchEvents) 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.syncRunGeneration++\n    for (const transaction of this.pendingSyncedTransactions) {\n      transaction.applied.reject(new SyncTransactionAbortedError())\n    }\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.appliedAdapterDeletedKeys?.clear()\n    this.hasAppliedAdapterTruncate = false\n    this.clearOriginTrackingState()\n    this.isLocalOnly = false\n    this.size = 0\n    this.pendingSyncedTransactions = []\n    this.pendingSyncedProjection = { states: new Map(), truncated: false }\n    this.preSyncVisibleState.clear()\n    this.preSyncVirtualState.clear()\n    this.recentlySyncedKeys.clear()\n    this.hasReceivedFirstCommit = false\n  }\n}\n"],"names":["SortedMap","virtualProps","DIRECT_TRANSACTION_METADATA_KEY","deepEquals","SyncTransactionAbortedError","enrichRowWithVirtualProps"],"mappings":"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"}