UNPKG

@tanstack/db

Version:

A reactive client store for building super fast apps on sync

122 lines (121 loc) • 4.36 kB
"use strict"; Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); const transactions = require("./transactions.cjs"); const error = require("./utils/error.cjs"); const errors = require("./errors.cjs"); function createPacedMutations(config) { const { onMutate, mutationFn, strategy, ...transactionConfig } = config; let activeTransaction = null; const strategyCommits = /* @__PURE__ */ new WeakMap(); let optimisticFrame; function getTransaction(isolated = false) { if (!isolated && activeTransaction?.state === `pending`) return activeTransaction; const transaction = transactions.createTransaction({ ...transactionConfig, mutationFn, autoCommit: false }); strategyCommits.set(transaction, transaction.commit.bind(transaction)); transaction.commit = () => { throw new errors.PacedTransactionManualCommitError(); }; if (!isolated) activeTransaction = transaction; return transaction; } function commit(transaction, onStarted) { if (activeTransaction === transaction) activeTransaction = null; if (transaction.state === `failed`) return transaction; if (transaction.state !== `pending`) { throw new Error( `Strategy callback called but transaction is in state "${transaction.state}". Expected "pending".` ); } const strategyCommit = strategyCommits.get(transaction); if (!strategyCommit) throw new Error(`Paced transaction has no strategy-owned commit`); const completion = strategyCommit(); onStarted?.(completion); completion.catch(() => { }); return transaction; } function applyOptimistic(transaction, variables, newlyCreated) { const parent = optimisticFrame; if (parent?.transaction === transaction) parent.admittedNestedCall = true; const frame = { transaction, admittedNestedCall: false }; optimisticFrame = frame; try { transaction.mutate(() => onMutate(variables)); } catch (error$1) { if (newlyCreated || frame.admittedNestedCall) { void transaction.isPersisted.promise.catch(() => { }); transaction.rollback({ error: error.normalizeError(error$1), isSecondaryRollback: !frame.admittedNestedCall }); if (activeTransaction === transaction) activeTransaction = null; } throw error$1; } finally { optimisticFrame = parent; } } function mutate(variables) { if (strategy._type === `debounce` || strategy._type === `throttle`) { let transaction2; let completion; const onAdmit = () => { if (transaction2) return transaction2; const previous2 = activeTransaction; transaction2 = getTransaction(); applyOptimistic(transaction2, variables, transaction2 !== previous2); return transaction2; }; const admitted = strategy.execute( () => { return commit(onAdmit(), (started) => { completion = started; }); }, onAdmit, () => completion ); if (admitted !== false) return onAdmit(); const dropped = getTransaction(true); applyOptimistic(dropped, variables, true); dropped.rollback({ error: strategy._type === `debounce` ? new errors.DebounceCallDroppedError() : new errors.ThrottleCallDroppedError(), isSecondaryRollback: true }); return dropped; } const previous = activeTransaction; const transaction = getTransaction(strategy._type === `queue`); applyOptimistic(transaction, variables, transaction !== previous); try { let completion; const admitted = strategy.execute( () => commit(transaction, (started) => { completion = started; }), void 0, () => completion ); if (strategy._type === `queue` && admitted === false) { transaction.rollback({ error: new errors.QueueCapacityExceededError(), isSecondaryRollback: true }); } } catch (error2) { if (!(error2 instanceof errors.QueueDisposedError)) throw error2; transaction.rollback({ error: error2, isSecondaryRollback: true }); } return transaction; } return mutate; } exports.createPacedMutations = createPacedMutations; //# sourceMappingURL=paced-mutations.cjs.map