UNPKG

@tanstack/offline-transactions

Version:

Offline-first transaction capabilities for TanStack DB

89 lines (88 loc) 2.67 kB
import { createTransaction } from "@tanstack/db"; import { NonRetriableError } from "../types.js"; class OfflineTransaction { // Will be typed properly - reference to OfflineExecutor constructor(options, mutationFn, persistTransaction, executor) { this.transaction = null; this.offlineId = crypto.randomUUID(); this.mutationFnName = options.mutationFnName; this.autoCommit = options.autoCommit ?? true; this.idempotencyKey = options.idempotencyKey ?? crypto.randomUUID(); this.metadata = options.metadata ?? {}; this.persistTransaction = persistTransaction; this.executor = executor; } mutate(callback) { this.transaction = createTransaction({ id: this.offlineId, autoCommit: false, mutationFn: async () => { const offlineTransaction = { id: this.offlineId, mutationFnName: this.mutationFnName, mutations: this.transaction.mutations, keys: this.extractKeys(this.transaction.mutations), idempotencyKey: this.idempotencyKey, createdAt: /* @__PURE__ */ new Date(), retryCount: 0, nextAttemptAt: Date.now(), metadata: this.metadata, spanContext: void 0, version: 1 }; const completionPromise = this.executor.waitForTransactionCompletion( this.offlineId ); try { await this.persistTransaction(offlineTransaction); await completionPromise; } catch (error) { const normalizedError = error instanceof Error ? error : new Error(String(error)); this.executor.rejectTransaction(this.offlineId, normalizedError); throw error; } return; }, metadata: this.metadata }); this.transaction.mutate(() => { callback(); }); if (this.autoCommit) { this.commit().catch((error) => { console.error(`Auto-commit failed:`, error); throw error; }); } return this.transaction; } async commit() { if (!this.transaction) { throw new Error(`No mutations to commit. Call mutate() first.`); } try { await this.transaction.commit(); return this.transaction; } catch (error) { if (error instanceof NonRetriableError) { this.transaction.rollback(); } throw error; } } rollback() { if (this.transaction) { this.transaction.rollback(); } } extractKeys(mutations) { return mutations.map((mutation) => mutation.globalKey); } get id() { return this.offlineId; } } export { OfflineTransaction }; //# sourceMappingURL=OfflineTransaction.js.map