UNPKG

@tanstack/offline-transactions

Version:

Offline-first transaction capabilities for TanStack DB

95 lines (94 loc) • 3.08 kB
"use strict"; Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); const db = require("@tanstack/db"); class OfflineTransaction { // Will be typed properly - reference to OfflineExecutor constructor(options, mutationFn, persistTransaction, executor) { this.transaction = null; this.persisting = false; this.offlineId = db.safeRandomUUID(); this.mutationFnName = options.mutationFnName; this.autoCommit = options.autoCommit; this.idempotencyKey = options.idempotencyKey ?? db.safeRandomUUID(); this.metadata = options.metadata ?? {}; this.persistTransaction = persistTransaction; this.executor = executor; } mutate(callback) { if (!this.transaction) { this.transaction = db.createTransaction({ id: this.offlineId, autoCommit: this.autoCommit, mutationFn: async () => { this.persisting = true; 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 Promise.race([ this.persistTransaction(offlineTransaction), completionPromise ]); 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 }); void this.transaction.when(`settled`).then( () => { if (!this.persisting) this.executor.resolveTransaction(this.offlineId, void 0); }, (error) => { if (!this.persisting) this.executor.rejectTransaction( this.offlineId, error instanceof Error ? error : new Error(`Offline transaction was rolled back`) ); } ); } this.transaction.mutate(() => { callback(); }); return this.transaction; } async commit() { if (!this.transaction) { throw new Error(`No mutations to commit. Call mutate() first.`); } await this.transaction.commit(); return this.transaction; } rollback() { if (this.transaction) { this.transaction.rollback(); } } extractKeys(mutations) { return mutations.map((mutation) => mutation.globalKey); } get id() { return this.offlineId; } } exports.OfflineTransaction = OfflineTransaction; //# sourceMappingURL=OfflineTransaction.cjs.map