@tanstack/offline-transactions
Version:
Offline-first transaction capabilities for TanStack DB
89 lines (88 loc) • 2.76 kB
JavaScript
"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const db = require("@tanstack/db");
const types = require("../types.cjs");
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 = db.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 types.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;
}
}
exports.OfflineTransaction = OfflineTransaction;
//# sourceMappingURL=OfflineTransaction.cjs.map