UNPKG

@tanstack/offline-transactions

Version:

Offline-first transaction capabilities for TanStack DB

115 lines (114 loc) 3.78 kB
"use strict"; Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); const tracer = require("../telemetry/tracer.cjs"); const TransactionSerializer = require("./TransactionSerializer.cjs"); class OutboxManager { constructor(storage, collections) { this.keyPrefix = `tx:`; this.storage = storage; this.serializer = new TransactionSerializer.TransactionSerializer(collections); } getStorageKey(id) { return `${this.keyPrefix}${id}`; } async add(transaction) { return tracer.withSpan( `outbox.add`, { "transaction.id": transaction.id, "transaction.mutationFnName": transaction.mutationFnName, "transaction.keyCount": transaction.keys.length }, async () => { const key = this.getStorageKey(transaction.id); const serialized = this.serializer.serialize(transaction); await this.storage.set(key, serialized); } ); } async get(id) { return tracer.withSpan(`outbox.get`, {}, async (span) => { const key = this.getStorageKey(id); const data = await this.storage.get(key); if (!data) { span.setAttribute(`result`, `not_found`); return null; } try { const transaction = this.serializer.deserialize(data); span.setAttribute(`result`, `found`); return transaction; } catch (error) { console.warn(`Failed to deserialize transaction ${id}:`, error); span.setAttribute(`result`, `deserialize_error`); return null; } }); } async getAll() { return tracer.withSpan(`outbox.getAll`, {}, async (span) => { const keys = await this.storage.keys(); const transactionKeys = keys.filter( (key) => key.startsWith(this.keyPrefix) ); span.setAttribute(`transactionCount`, transactionKeys.length); const transactions = []; for (const key of transactionKeys) { const data = await this.storage.get(key); if (data) { try { const transaction = this.serializer.deserialize(data); transactions.push(transaction); } catch (error) { console.warn( `Failed to deserialize transaction from key ${key}:`, error ); } } } return transactions.sort( (a, b) => a.createdAt.getTime() - b.createdAt.getTime() ); }); } async getByKeys(keys) { const allTransactions = await this.getAll(); const keySet = new Set(keys); return allTransactions.filter( (transaction) => transaction.keys.some((key) => keySet.has(key)) ); } async update(id, updates) { return tracer.withSpan(`outbox.update`, {}, async () => { const existing = await this.get(id); if (!existing) { throw new Error(`Transaction ${id} not found`); } const updated = { ...existing, ...updates }; await this.add(updated); }); } async remove(id) { return tracer.withSpan(`outbox.remove`, {}, async () => { const key = this.getStorageKey(id); await this.storage.delete(key); }); } async removeMany(ids) { return tracer.withSpan(`outbox.removeMany`, { count: ids.length }, async () => { await Promise.all(ids.map((id) => this.remove(id))); }); } async clear() { const keys = await this.storage.keys(); const transactionKeys = keys.filter((key) => key.startsWith(this.keyPrefix)); await Promise.all(transactionKeys.map((key) => this.storage.delete(key))); } async count() { const keys = await this.storage.keys(); return keys.filter((key) => key.startsWith(this.keyPrefix)).length; } } exports.OutboxManager = OutboxManager; //# sourceMappingURL=OutboxManager.cjs.map