{"version":3,"file":"OutboxManager.cjs","sources":["../../../src/outbox/OutboxManager.ts"],"sourcesContent":["import { withSpan } from '../telemetry/tracer'\nimport { TransactionSerializer } from './TransactionSerializer'\nimport type { OfflineTransaction, StorageAdapter } from '../types'\nimport type { Collection } from '@tanstack/db'\n\nexport class OutboxManager {\n  private storage: StorageAdapter\n  private serializer: TransactionSerializer\n  private keyPrefix = `tx:`\n\n  constructor(\n    storage: StorageAdapter,\n\n    collections: Record<string, Collection<any, any, any, any, any>>,\n  ) {\n    this.storage = storage\n    this.serializer = new TransactionSerializer(collections)\n  }\n\n  private getStorageKey(id: string): string {\n    return `${this.keyPrefix}${id}`\n  }\n\n  async add(transaction: OfflineTransaction): Promise<void> {\n    return withSpan(\n      `outbox.add`,\n      {\n        'transaction.id': transaction.id,\n        'transaction.mutationFnName': transaction.mutationFnName,\n        'transaction.keyCount': transaction.keys.length,\n      },\n      async () => {\n        const key = this.getStorageKey(transaction.id)\n        const serialized = this.serializer.serialize(transaction)\n        await this.storage.set(key, serialized)\n      },\n    )\n  }\n\n  async get(id: string): Promise<OfflineTransaction | null> {\n    return withSpan(`outbox.get`, { 'transaction.id': id }, async (span) => {\n      const key = this.getStorageKey(id)\n      const data = await this.storage.get(key)\n\n      if (!data) {\n        span.setAttribute(`result`, `not_found`)\n        return null\n      }\n\n      try {\n        const transaction = this.serializer.deserialize(data)\n        span.setAttribute(`result`, `found`)\n        return transaction\n      } catch (error) {\n        console.warn(`Failed to deserialize transaction ${id}:`, error)\n        span.setAttribute(`result`, `deserialize_error`)\n        return null\n      }\n    })\n  }\n\n  async getAll(): Promise<Array<OfflineTransaction>> {\n    return withSpan(`outbox.getAll`, {}, async (span) => {\n      const keys = await this.storage.keys()\n      const transactionKeys = keys.filter((key) =>\n        key.startsWith(this.keyPrefix),\n      )\n\n      span.setAttribute(`transactionCount`, transactionKeys.length)\n\n      const transactions: Array<OfflineTransaction> = []\n\n      for (const key of transactionKeys) {\n        const data = await this.storage.get(key)\n        if (data) {\n          try {\n            const transaction = this.serializer.deserialize(data)\n            transactions.push(transaction)\n          } catch (error) {\n            console.warn(\n              `Failed to deserialize transaction from key ${key}:`,\n              error,\n            )\n          }\n        }\n      }\n\n      return transactions.sort(\n        (a, b) => a.createdAt.getTime() - b.createdAt.getTime(),\n      )\n    })\n  }\n\n  async getByKeys(keys: Array<string>): Promise<Array<OfflineTransaction>> {\n    const allTransactions = await this.getAll()\n    const keySet = new Set(keys)\n\n    return allTransactions.filter((transaction) =>\n      transaction.keys.some((key) => keySet.has(key)),\n    )\n  }\n\n  async update(\n    id: string,\n    updates: Partial<OfflineTransaction>,\n  ): Promise<void> {\n    return withSpan(`outbox.update`, { 'transaction.id': id }, async () => {\n      const existing = await this.get(id)\n      if (!existing) {\n        throw new Error(`Transaction ${id} not found`)\n      }\n\n      const updated = { ...existing, ...updates }\n      await this.add(updated)\n    })\n  }\n\n  async remove(id: string): Promise<void> {\n    return withSpan(`outbox.remove`, { 'transaction.id': id }, async () => {\n      const key = this.getStorageKey(id)\n      await this.storage.delete(key)\n    })\n  }\n\n  async removeMany(ids: Array<string>): Promise<void> {\n    return withSpan(`outbox.removeMany`, { count: ids.length }, async () => {\n      await Promise.all(ids.map((id) => this.remove(id)))\n    })\n  }\n\n  async clear(): Promise<void> {\n    const keys = await this.storage.keys()\n    const transactionKeys = keys.filter((key) => key.startsWith(this.keyPrefix))\n\n    await Promise.all(transactionKeys.map((key) => this.storage.delete(key)))\n  }\n\n  async count(): Promise<number> {\n    const keys = await this.storage.keys()\n    return keys.filter((key) => key.startsWith(this.keyPrefix)).length\n  }\n}\n"],"names":["TransactionSerializer","withSpan"],"mappings":"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"}