{"version":3,"file":"indexed-db.cjs","sources":["../../src/indexed-db.ts"],"sourcesContent":["/**\n * IndexedDB Collection for TanStack DB\n *\n * This module provides a factory function that creates IndexedDB-backed collections\n * compatible with TanStack DB's collection system.\n */\n\nimport { SchemaMustBeSynchronousError, SchemaValidationError } from './errors'\nimport { safeRandomUUID } from './utils/uuid'\nimport { withCollectionConfigFactory } from './client.js'\nimport {\n  clear,\n  executeTransaction,\n  getAll,\n  getByKey,\n  openDatabase,\n} from './indexed-db-wrapper'\nimport { codedMessage, devBuild } from './error-message.js'\nimport type {\n  BaseCollectionConfig,\n  ChangeMessageOrDeleteKeyMessage,\n  CollectionConfig,\n  DeleteMutationFnParams,\n  InsertMutationFnParams,\n  OperationType,\n  PendingMutation,\n  SyncConfig,\n  UpdateMutationFnParams,\n  UtilsRecord,\n} from './types'\nimport type { StandardSchemaV1 } from '@standard-schema/spec'\n\nexport class DatabaseRequiredError extends Error {\n  constructor() {\n    super(\n      devBuild() && process.env.NODE_ENV !== `production`\n        ? `IndexedDB collection requires a \"db\" configuration option. ` +\n            `Create a database instance using createIndexedDB() and pass it to the collection.`\n        : codedMessage(175),\n    )\n    this.name = `DatabaseRequiredError`\n  }\n}\n\n/**\n * Thrown when the specified object store doesn't exist in the database\n */\nexport class ObjectStoreNotFoundError extends Error {\n  constructor(\n    storeName: string,\n    databaseName: string,\n    availableStores: ReadonlyArray<string>,\n  ) {\n    super(\n      devBuild() && process.env.NODE_ENV !== `production`\n        ? `Object store \"${storeName}\" not found in database \"${databaseName}\". ` +\n            `Available stores: [${availableStores.join(', ')}]. ` +\n            `Add \"${storeName}\" to the stores array when calling createIndexedDB().`\n        : codedMessage(176, { storeName, databaseName, availableStores }),\n    )\n    this.name = 'ObjectStoreNotFoundError'\n  }\n}\n\n/**\n * Thrown when the name (object store) configuration is missing\n */\nexport class NameRequiredError extends Error {\n  constructor() {\n    super(\n      devBuild() && process.env.NODE_ENV !== `production`\n        ? `IndexedDB collection requires a \"name\" configuration option. ` +\n            `This is the name of the object store within the database.`\n        : codedMessage(177),\n    )\n    this.name = `NameRequiredError`\n  }\n}\n\n/**\n * Thrown when the getKey function is missing\n */\nexport class GetKeyRequiredError extends Error {\n  constructor() {\n    super(\n      devBuild() && process.env.NODE_ENV !== `production`\n        ? `IndexedDB collection requires a \"getKey\" configuration option. ` +\n            `This function extracts the unique key from each item.`\n        : codedMessage(178),\n    )\n    this.name = `GetKeyRequiredError`\n  }\n}\n\nexport interface CreateIndexedDBOptions {\n  /** Database name */\n  name: string\n  /** Schema version (increment when adding stores) */\n  version: number\n  /** Object store names to create */\n  stores: ReadonlyArray<string>\n  /** Custom IDBFactory for testing/mocking */\n  idbFactory?: IDBFactory\n  /** Reports a native blocker without settling the open request. */\n  onBlocked?: (event: IDBVersionChangeEvent) => void\n}\n\n/**\n * A shared IndexedDB database instance.\n * Create with createIndexedDB() and pass to collections.\n */\nexport interface IndexedDBInstance {\n  /** The underlying IDBDatabase connection */\n  readonly db: IDBDatabase\n  /** Database name */\n  readonly name: string\n  /** Database version */\n  readonly version: number\n  /** Requested object store names (frozen); omissions do not remove stores */\n  readonly stores: ReadonlyArray<string>\n  /** IDBFactory used to create this database (for testing) */\n  readonly idbFactory?: IDBFactory\n  /** Close the connection and mark its managed Collections as errored. */\n  close: () => void\n}\n\ntype InferSchemaOutput<T> = T extends StandardSchemaV1\n  ? StandardSchemaV1.InferOutput<T> extends object\n    ? StandardSchemaV1.InferOutput<T>\n    : Record<string, unknown>\n  : Record<string, unknown>\n\n/**\n * Schema input type inference helper\n */\ntype InferSchemaInput<T> = T extends StandardSchemaV1\n  ? StandardSchemaV1.InferInput<T> extends object\n    ? StandardSchemaV1.InferInput<T>\n    : Record<string, unknown>\n  : Record<string, unknown>\n\n/**\n * Configuration options for creating an IndexedDB Collection\n */\nexport interface IndexedDBCollectionConfig<\n  T extends object = object,\n  TSchema extends StandardSchemaV1 = never,\n  TKey extends string | number = string | number,\n> extends BaseCollectionConfig<T, TKey, TSchema> {\n  /**\n   * IndexedDB instance from createIndexedDB()\n   * REQUIRED - must create database before collections\n   */\n  db: IndexedDBInstance\n\n  /**\n   * Name of the object store within the database\n   * Must exist in the underlying database\n   */\n  name: string\n}\n\n/**\n * Version entry stored in the shared _versions object store\n * Key is a tuple: [name, itemKey]\n */\ninterface VersionEntry {\n  versionKey: string // UUID for change detection\n}\n\n/**\n * Cross-tab message format via BroadcastChannel\n */\ninterface CrossTabMessage {\n  type: 'data-changed' | 'database-cleared'\n  database: string\n  name: string // Object store name\n  changedKeys: Array<string | number> // Keys that changed (for targeted loading)\n  tabId: string // To avoid processing own messages\n}\n\n// BroadcastChannel is shared transport. Admit only this protocol before reading\n// its routing fields or issuing storage work. Invalid messages carry no writes.\nfunction isCrossTabMessage(value: unknown): value is CrossTabMessage {\n  if (!value || typeof value !== 'object') return false\n  const message = value as Record<string, unknown>\n  return (\n    (message.type === 'data-changed' || message.type === 'database-cleared') &&\n    typeof message.database === 'string' &&\n    typeof message.name === 'string' &&\n    typeof message.tabId === 'string' &&\n    Array.isArray(message.changedKeys) &&\n    message.changedKeys.every(\n      (key: unknown) =>\n        typeof key === 'string' ||\n        (typeof key === 'number' && !Number.isNaN(key)),\n    )\n  )\n}\n\n/**\n * Database information returned by getDatabaseInfo()\n */\nexport interface DatabaseInfo {\n  name: string\n  version: number\n  objectStores: Array<string>\n  /** Origin-wide storage usage in bytes, including other databases and caches. */\n  estimatedSize?: number\n}\n\n/**\n * Utility functions exposed on collection.utils\n */\nexport interface IndexedDBCollectionUtils<\n  TItem extends object = Record<string, unknown>,\n  TInsertInput extends object = TItem,\n> extends UtilsRecord {\n  /**\n   * Removes all data from the object store\n   * Does NOT delete the database itself\n   */\n  clearObjectStore: () => Promise<void>\n\n  /**\n   * Returns database information for debugging\n   */\n  getDatabaseInfo: () => Promise<DatabaseInfo>\n\n  /**\n   * Accepts mutations from a manual transaction and persists to IndexedDB\n   */\n  acceptMutations: (transaction: {\n    mutations: Array<PendingMutation>\n  }) => Promise<void>\n\n  /**\n   * Exports all data from the object store as an array\n   * Useful for backup/debugging\n   */\n  exportData: () => Promise<Array<TItem>>\n\n  /**\n   * Validates input rows and atomically replaces the object store.\n   * Failure preserves the previous rows and versions.\n   */\n  importData: (items: Array<TInsertInput>) => Promise<void>\n}\n\nconst VERSIONS_STORE_NAME = '_versions'\n// Connection closure is sticky, including Collections started after close.\n// Keep core's sync run alive: admitted writes and accepted sync transactions\n// still owe their confirmations, while new reads have no publication authority.\nconst connections = new WeakMap<\n  IDBDatabase,\n  {\n    error?: Error\n    listeners: Set<() => void>\n  }\n>()\n\n/**\n * Creates or opens an IndexedDB database with the specified stores.\n * Call this once at app startup, then pass the instance to collections.\n * The connection closes on versionchange so another context can upgrade or\n * delete the database. Affected Collections enter error and retain their rows.\n * Recreate affected Collections with a new instance before\n * further persistence.\n *\n * All stores are created in a single upgrade transaction, avoiding\n * version race conditions when multiple collections share a database.\n *\n * @example\n * ```typescript\n * const db = await createIndexedDB({\n *   name: 'myApp',\n *   version: 1,\n *   stores: ['todos', 'users', 'settings'],\n * })\n *\n * const todosCollection = createCollection(\n *   indexedDBCollectionOptions({\n *     db,\n *     name: 'todos',\n *     getKey: (item: { id: string }) => item.id,\n *   })\n * )\n * ```\n */\nexport async function createIndexedDB(\n  options: CreateIndexedDBOptions,\n): Promise<IndexedDBInstance> {\n  const { name, version, stores, idbFactory, onBlocked } = options\n\n  // Validate options\n  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- runtime safety for JS consumers\n  if (!stores || stores.length === 0) {\n    throw new Error(\n      devBuild() && process.env.NODE_ENV !== `production`\n        ? 'createIndexedDB requires at least one store in the stores array.'\n        : codedMessage(193),\n    )\n  }\n\n  const storeSet = new Set(stores)\n  if (storeSet.size !== stores.length) {\n    throw new Error(\n      devBuild() && process.env.NODE_ENV !== `production`\n        ? 'createIndexedDB stores array contains duplicate store names.'\n        : codedMessage(194),\n    )\n  }\n\n  for (const storeName of stores) {\n    if (storeName === VERSIONS_STORE_NAME) {\n      throw new Error(\n        devBuild() && process.env.NODE_ENV !== `production`\n          ? 'The \"_versions\" store is reserved for IndexedDB Collection metadata.'\n          : codedMessage(195),\n      )\n    }\n    if (!storeName || typeof storeName !== 'string') {\n      throw new Error(\n        devBuild() && process.env.NODE_ENV !== `production`\n          ? 'createIndexedDB stores array contains invalid store names. ' +\n              'Each store name must be a non-empty string.'\n          : codedMessage(196),\n      )\n    }\n  }\n\n  const db = await openDatabase(\n    name,\n    version,\n    (database) => {\n      // Always create _versions store for cross-tab sync\n      if (!database.objectStoreNames.contains(VERSIONS_STORE_NAME)) {\n        database.createObjectStore(VERSIONS_STORE_NAME)\n      }\n\n      // Create each requested store\n      for (const storeName of stores) {\n        if (!database.objectStoreNames.contains(storeName)) {\n          database.createObjectStore(storeName)\n        }\n      }\n    },\n    idbFactory,\n    onBlocked,\n  )\n\n  const connection: { error?: Error; listeners: Set<() => void> } = {\n    listeners: new Set(),\n  }\n  connections.set(db, connection)\n  const close = () => {\n    db.close()\n    if (connection.error) return\n    connection.error = new Error(\n      devBuild() && process.env.NODE_ENV !== `production`\n        ? `IndexedDB connection \"${name}\" closed. Recreate its Collections with a new database instance.`\n        : codedMessage(197, { name }),\n    )\n    // Record closure before reentrant listeners can request more work. Core\n    // reports user event-listener failures asynchronously and notifies siblings.\n    for (const notify of [...connection.listeners]) notify()\n  }\n  db.addEventListener('versionchange', close)\n  db.addEventListener('close', close)\n\n  // Create frozen stores array for immutability\n  const frozenStores = Object.freeze([...stores])\n\n  return Object.freeze({\n    db,\n    name,\n    version: db.version,\n    stores: frozenStores,\n    idbFactory,\n    close,\n  })\n}\n\n/**\n * Creates IndexedDB collection options for use with a standard Collection.\n * This provides persistent local storage with cross-tab synchronization.\n *\n * IMPORTANT: You must first create the database with createIndexedDB() and\n * pass the instance to this function. This ensures all stores are created\n * upfront in a single upgrade transaction.\n *\n * @example\n * // Step 1: Create database with all stores\n * const db = await createIndexedDB({\n *   name: 'myApp',\n *   version: 1,\n *   stores: ['todos', 'users'],\n * })\n *\n * // Step 2: Create collections using the shared database\n * const todosCollection = createCollection(\n *   indexedDBCollectionOptions({\n *     db,\n *     name: 'todos',\n *     schema: todoSchema,\n *     getKey: (item: { id: string }) => item.id,\n *   })\n * )\n *\n * @example\n * // Without schema (explicit type)\n * const todosCollection = createCollection(\n *   indexedDBCollectionOptions<Todo>({\n *     db,\n *     name: 'todos',\n *     getKey: (item: { id: string }) => item.id,\n *   })\n * )\n */\n\n// Overload for when schema is provided\nexport function indexedDBCollectionOptions<\n  T extends StandardSchemaV1,\n  TKey extends string | number = string | number,\n>(\n  config: IndexedDBCollectionConfig<InferSchemaOutput<T>, T, TKey> & {\n    schema: T\n  },\n): CollectionConfig<\n  InferSchemaOutput<T>,\n  TKey,\n  T,\n  IndexedDBCollectionUtils<InferSchemaOutput<T>, InferSchemaInput<T>>\n> & {\n  schema: T\n  utils: IndexedDBCollectionUtils<InferSchemaOutput<T>, InferSchemaInput<T>>\n}\n\n// Overload for when no schema is provided\nexport function indexedDBCollectionOptions<\n  T extends object,\n  TKey extends string | number = string | number,\n>(\n  config: IndexedDBCollectionConfig<T, never, TKey> & {\n    schema?: never\n  },\n): CollectionConfig<T, TKey, never, IndexedDBCollectionUtils<T>> & {\n  schema?: never\n  utils: IndexedDBCollectionUtils<T>\n}\n\nexport function indexedDBCollectionOptions(\n  config: IndexedDBCollectionConfig<Record<string, unknown>, StandardSchemaV1>,\n): CollectionConfig<\n  Record<string, unknown>,\n  string | number,\n  StandardSchemaV1,\n  IndexedDBCollectionUtils\n> & {\n  utils: IndexedDBCollectionUtils\n} {\n  const {\n    db: dbInstance,\n    name,\n    getKey,\n    onInsert,\n    onUpdate,\n    onDelete,\n    ...baseCollectionConfig\n  } = config\n\n  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- runtime safety for JS consumers\n  if (!dbInstance) {\n    throw new DatabaseRequiredError()\n  }\n\n  if (!name) {\n    throw new NameRequiredError()\n  }\n  if (name === VERSIONS_STORE_NAME) {\n    throw new Error(\n      devBuild() && process.env.NODE_ENV !== `production`\n        ? 'The \"_versions\" store is reserved for IndexedDB Collection metadata.'\n        : codedMessage(198),\n    )\n  }\n\n  // Validate that the store exists in the database (sync check)\n  for (const storeName of [name, VERSIONS_STORE_NAME]) {\n    if (!dbInstance.db.objectStoreNames.contains(storeName)) {\n      throw new ObjectStoreNotFoundError(\n        storeName,\n        dbInstance.name,\n        Array.from(dbInstance.db.objectStoreNames),\n      )\n    }\n  }\n\n  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n  if (!getKey) {\n    throw new GetKeyRequiredError()\n  }\n\n  type Item = Record<string, unknown>\n  type Mutation = {\n    type: OperationType\n    key: string | number\n    modified: Item\n  }\n  type Sync = Parameters<SyncConfig<Item>['sync']>[0]\n  const collectionId =\n    baseCollectionConfig.id ??\n    `indexed-db-collection:${dbInstance.name}:${name}`\n  const connection = connections.get(dbInstance.db)\n  const tabId = safeRandomUUID()\n  const versionCache = new Map<string | number, string>()\n  let collection: Sync['collection'] | undefined\n  let acceptance: Promise<void> = Promise.resolve()\n  let activeSync: Sync | undefined\n  let broadcastChannel: BroadcastChannel | undefined\n\n  function broadcastChange(\n    changedKeys: Array<string | number>,\n    type: CrossTabMessage['type'] = 'data-changed',\n  ): void {\n    let channel = broadcastChannel\n    if (!channel) {\n      try {\n        channel = new BroadcastChannel(`tanstack-db:${dbInstance.name}`)\n      } catch {\n        return // Local persistence does not require BroadcastChannel.\n      }\n    }\n    try {\n      channel.postMessage({\n        type,\n        database: dbInstance.name,\n        name,\n        changedKeys,\n        tabId,\n      } satisfies CrossTabMessage)\n    } finally {\n      // Utility writes are legal before startup and after cleanup. Their\n      // send-only channel owns no subscription and ends with the send.\n      if (channel !== broadcastChannel) channel.close()\n    }\n  }\n\n  // Jump to this store's compound-key prefix without ambient IDBKeyRange.\n  // Stop after its last key; sibling rows are never visited. Request errors must\n  // reject the surrounding transaction, including failures while deleting.\n  function visitVersions(\n    store: IDBObjectStore,\n    visit: (cursor: IDBCursorWithValue) => void,\n  ): Promise<void> {\n    return new Promise((resolve, reject) => {\n      const request = store.openCursor()\n      request.onerror = () => reject(request.error)\n      request.onsuccess = () => {\n        const cursor = request.result\n        if (!cursor) {\n          resolve()\n          return\n        }\n        try {\n          const [storeName] = cursor.key as [string, string | number]\n          if (storeName < name) {\n            cursor.continue([name])\n          } else if (storeName === name) {\n            visit(cursor)\n            cursor.continue()\n          } else {\n            resolve()\n          }\n        } catch (error) {\n          reject(error)\n        }\n      }\n    })\n  }\n\n  // Stage cache changes until the ONE data-and-version transaction completes.\n  // A failed request, including synchronous structured-clone failure, aborts\n  // every mutation in this Collection's batch.\n  async function persist(\n    mutations: Array<Mutation>,\n    replace = false,\n  ): Promise<void> {\n    const versions = new Map<string | number, string>()\n    await executeTransaction(\n      dbInstance.db,\n      [name, VERSIONS_STORE_NAME],\n      'readwrite',\n      async (_, stores) => {\n        if (replace) {\n          await clear(stores[name]!)\n          await visitVersions(stores[VERSIONS_STORE_NAME]!, (cursor) => {\n            cursor.delete()\n          })\n        }\n        for (const mutation of mutations) {\n          const { key } = mutation\n          if (mutation.type === 'delete') {\n            stores[name]!.delete(key)\n            stores[VERSIONS_STORE_NAME]!.delete([name, key])\n          } else {\n            const versionKey = safeRandomUUID()\n            stores[name]!.put(mutation.modified, key)\n            stores[VERSIONS_STORE_NAME]!.put(\n              {\n                versionKey,\n              } satisfies VersionEntry,\n              [name, key],\n            )\n            versions.set(key, versionKey)\n          }\n        }\n      },\n    )\n    if (replace) versionCache.clear()\n    for (const mutation of mutations) {\n      const version = versions.get(mutation.key)\n      if (version === undefined) versionCache.delete(mutation.key)\n      else versionCache.set(mutation.key, version)\n    }\n  }\n\n  function confirm(mutations: Array<Mutation>, replace = false): void {\n    if (!activeSync) return\n    // Core queues ordinary confirmation until optimistic settlement.\n    // Full-row update confirms put even if a peer inserted during the handler.\n    // A replacement's truncate already supplies its own publication boundary.\n    activeSync.begin()\n    if (replace) activeSync.truncate({ markReady: !connection?.error })\n    for (const mutation of mutations) {\n      activeSync.write(\n        mutation.type === 'delete'\n          ? { type: 'delete', key: mutation.key }\n          : { type: 'update', value: mutation.modified },\n      )\n    }\n    activeSync.commit()\n  }\n\n  // Startup and replacement notifications read rows and versions from one\n  // native snapshot, then publish only into the sync run that requested it.\n  async function restore(params: Sync, replace: boolean): Promise<void> {\n    const snapshot = await executeTransaction(\n      dbInstance.db,\n      [name, VERSIONS_STORE_NAME],\n      'readonly',\n      async (_, stores) => {\n        const items = await getAll<Item>(stores[name]!)\n        const versions = new Map<string | number, string>()\n        await visitVersions(stores[VERSIONS_STORE_NAME]!, (cursor) => {\n          const [, key] = cursor.key as [string, string | number]\n          versions.set(key, (cursor.value as VersionEntry).versionKey)\n        })\n        return { items, versions }\n      },\n    )\n    if (activeSync !== params || connection?.error) return\n    versionCache.clear()\n    for (const [key, version] of snapshot.versions)\n      versionCache.set(key, version)\n    params.begin()\n    if (replace) params.truncate()\n    for (const item of snapshot.items)\n      params.write({ type: 'insert', value: item })\n    params.commit()\n    if (!replace) params.markReady()\n  }\n\n  const internalSync: SyncConfig<Item>['sync'] = (params) => {\n    const { begin, write, commit, markError } = params\n    activeSync = params\n    collection = params.collection\n    let channel: BroadcastChannel | undefined\n    const retire = () => {\n      channel?.close()\n      if (activeSync === params) {\n        broadcastChannel = undefined\n        markError(connection?.error)\n      }\n    }\n    if (connection?.error) {\n      retire()\n      return\n    }\n    connection?.listeners.add(retire)\n\n    try {\n      channel = new BroadcastChannel(`tanstack-db:${dbInstance.name}`)\n      broadcastChannel = channel\n      channel.onmessage = async (event: MessageEvent<CrossTabMessage>) => {\n        const message: unknown = event.data\n        if (!isCrossTabMessage(message)) return\n        if (\n          activeSync !== params ||\n          connection?.error ||\n          message.tabId === tabId ||\n          message.database !== dbInstance.name ||\n          message.name !== name\n        )\n          return\n        try {\n          if (message.type === 'database-cleared') {\n            // The notification describes an earlier replacement. Current\n            // durable rows may also contain later accepted writes.\n            await restore(params, true)\n            return\n          }\n          if (!message.changedKeys.length) return\n          const rows = await executeTransaction(\n            dbInstance.db,\n            [name, VERSIONS_STORE_NAME],\n            'readonly',\n            async (_, stores) => {\n              const result = []\n              for (const key of message.changedKeys) {\n                const [version, value] = await Promise.all([\n                  getByKey<VersionEntry>(stores[VERSIONS_STORE_NAME]!, [\n                    name,\n                    key,\n                  ]),\n                  getByKey<Item>(stores[name]!, key),\n                ])\n                result.push({ key, version, value })\n              }\n              return result\n            },\n          )\n          if (activeSync !== params || connection?.error) return\n          const changes: Array<ChangeMessageOrDeleteKeyMessage<Item>> = []\n          for (const { key, version, value } of rows) {\n            const cached = versionCache.get(key)\n            if (value) {\n              if (!version || cached !== version.versionKey) {\n                changes.push({\n                  type: 'update',\n                  value,\n                })\n                if (version) versionCache.set(key, version.versionKey)\n                else versionCache.delete(key)\n              }\n            } else {\n              // Source deletion is independent of the optimistic public view.\n              changes.push({ type: 'delete', key })\n              versionCache.delete(key)\n            }\n          }\n          if (changes.length) {\n            begin()\n            for (const change of changes) write(change)\n            commit()\n          }\n        } catch (error) {\n          if (activeSync === params) markError(error)\n        }\n      }\n    } catch {\n      // Persistence also works in environments without BroadcastChannel.\n    }\n\n    void restore(params, false).catch((error: unknown) => {\n      if (activeSync === params) markError(error)\n    })\n\n    return {\n      cleanup: () => {\n        connection?.listeners.delete(retire)\n        channel?.close()\n        if (activeSync === params) {\n          activeSync = undefined\n          broadcastChannel = undefined\n          versionCache.clear()\n        }\n      },\n    }\n  }\n\n  const acceptMutations = async (transaction: {\n    mutations: Array<PendingMutation<Item>>\n  }): Promise<void> => {\n    const mutations = transaction.mutations\n      .filter((m) => m.collection === collection)\n      .map((m) => ({\n        type: m.type,\n        key: getKey(m.modified),\n        modified: m.modified,\n      }))\n    if (!mutations.length) return\n    await persist(mutations)\n    confirm(mutations)\n    broadcastChange(mutations.map((m) => m.key))\n  }\n\n  // Start handlers immediately, but accept successful automatic writes in\n  // invocation order. Observe rejection immediately even while a predecessor\n  // is held. Each rejected decision releases its place without persisting.\n  function persistInOrder(\n    transaction: { mutations: Array<PendingMutation<Item>> },\n    handler: () => unknown,\n  ): Promise<unknown> {\n    const result = acceptance.then(async () => {\n      const outcome = await decision\n      if (!outcome.accepted) throw outcome.error\n      await acceptMutations(transaction)\n      return outcome.value\n    })\n    acceptance = result.then(\n      () => undefined,\n      () => undefined,\n    )\n    // Reserve the position before application code can author another write.\n    const decision = new Promise<unknown>((resolve) => resolve(handler())).then(\n      (value) => ({ accepted: true as const, value }),\n      (error: unknown) => ({ accepted: false as const, error }),\n    )\n    return result\n  }\n\n  const wrappedOnInsert = (params: InsertMutationFnParams<Item>) =>\n    persistInOrder(params.transaction, () => onInsert?.(params))\n  const wrappedOnUpdate = (params: UpdateMutationFnParams<Item>) =>\n    persistInOrder(params.transaction, () => onUpdate?.(params))\n  const wrappedOnDelete = (params: DeleteMutationFnParams<Item>) =>\n    persistInOrder(params.transaction, () => onDelete?.(params))\n\n  const clearObjectStore = async (): Promise<void> => {\n    await persist([], true)\n    confirm([], true)\n    broadcastChange([], 'database-cleared')\n  }\n\n  const getDatabaseInfo = async (): Promise<DatabaseInfo> => {\n    const db = dbInstance.db\n    const info: DatabaseInfo = {\n      name: db.name,\n      version: db.version,\n      objectStores: Array.from(db.objectStoreNames),\n    }\n    // Storage estimates are optional diagnostics, not a persistence prerequisite.\n    // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- optional browser API at runtime\n    if (typeof navigator !== 'undefined' && navigator.storage?.estimate) {\n      try {\n        info.estimatedSize = (await navigator.storage.estimate()).usage\n      } catch {}\n    }\n    return info\n  }\n\n  const exportData = (): Promise<Array<Item>> =>\n    executeTransaction(dbInstance.db, name, 'readonly', (_, stores) =>\n      getAll<Item>(stores[name]!),\n    )\n\n  const importData = async (items: Array<Item>): Promise<void> => {\n    const keys = new Set<string | number>()\n    const mutations = items.map((input) => {\n      let item = input\n      if (config.schema) {\n        const result = config.schema['~standard'].validate(input)\n        if (result instanceof Promise) throw new SchemaMustBeSynchronousError()\n        if (result.issues) {\n          throw new SchemaValidationError(\n            'insert',\n            result.issues.map((issue) => ({\n              message: issue.message,\n              path: issue.path?.map(String),\n            })),\n          )\n        }\n        item = result.value as Item\n      }\n      const key = getKey(item)\n      if (keys.has(key))\n        throw new Error(\n          devBuild() && process.env.NODE_ENV !== `production`\n            ? `Duplicate imported key: ${key}`\n            : codedMessage(199, { key }),\n        )\n      keys.add(key)\n      return { type: 'insert' as const, key, modified: structuredClone(item) }\n    })\n    await persist(mutations, true)\n    confirm(mutations, true)\n    broadcastChange([], 'database-cleared')\n  }\n\n  const utils: IndexedDBCollectionUtils = {\n    clearObjectStore,\n    getDatabaseInfo,\n    acceptMutations,\n    exportData,\n    importData,\n  }\n  const options = {\n    ...baseCollectionConfig,\n    id: collectionId,\n    getKey,\n    sync: { sync: internalSync, rowUpdateMode: 'full' as const },\n    onInsert: wrappedOnInsert,\n    onUpdate: wrappedOnUpdate,\n    onDelete: wrappedOnDelete,\n    utils,\n  }\n  return withCollectionConfigFactory(options, () =>\n    (\n      indexedDBCollectionOptions as (\n        nextConfig: IndexedDBCollectionConfig<Item, StandardSchemaV1>,\n      ) => typeof options\n    )({ ...config, id: collectionId }),\n  )\n}\n"],"names":["devBuild","codedMessage","openDatabase","safeRandomUUID","executeTransaction","clear","getAll","getByKey","SchemaMustBeSynchronousError","SchemaValidationError","withCollectionConfigFactory"],"mappings":"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"}