@absolutejs/sync 1.18.2 → 1.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/testing.js CHANGED
@@ -625,6 +625,15 @@ class CdcConsumerSlowError extends Error {
625
625
  this.lastDeliveredVersion = lastDeliveredVersion;
626
626
  }
627
627
  }
628
+
629
+ class MutationQueueOverflowError extends Error {
630
+ queueLimit;
631
+ constructor(queueLimit) {
632
+ super(`Mutation queue overflowed (limit ${queueLimit}); the engine is at ` + `its mutationConcurrency cap and the waiting queue is full. ` + `Retry later or shed load at the gateway.`);
633
+ this.name = "MutationQueueOverflowError";
634
+ this.queueLimit = queueLimit;
635
+ }
636
+ }
628
637
  var defaultKey = (row) => row.id;
629
638
  var shallowEqual3 = (a, b) => {
630
639
  if (a === b) {
@@ -741,6 +750,40 @@ var createSyncEngine = (options = {}) => {
741
750
  let mutationsFailed = 0;
742
751
  let mutationsRetried = 0;
743
752
  let mutationsInFlight = 0;
753
+ const mutationWaiters = [];
754
+ let mutationsQueued = 0;
755
+ const acquireMutationSlot = async () => {
756
+ const limit = options.mutationConcurrency;
757
+ if (limit === undefined) {
758
+ mutationsInFlight += 1;
759
+ return;
760
+ }
761
+ if (mutationsInFlight < limit && mutationWaiters.length === 0) {
762
+ mutationsInFlight += 1;
763
+ return;
764
+ }
765
+ const queueLimit = options.mutationQueueLimit;
766
+ if (queueLimit !== undefined && mutationsQueued >= queueLimit) {
767
+ throw new MutationQueueOverflowError(queueLimit);
768
+ }
769
+ mutationsQueued += 1;
770
+ try {
771
+ await new Promise((resolve) => {
772
+ mutationWaiters.push(resolve);
773
+ });
774
+ } finally {
775
+ mutationsQueued -= 1;
776
+ }
777
+ mutationsInFlight += 1;
778
+ };
779
+ const releaseMutationSlot = () => {
780
+ mutationsInFlight -= 1;
781
+ if (options.mutationConcurrency === undefined)
782
+ return;
783
+ const next = mutationWaiters.shift();
784
+ if (next !== undefined)
785
+ next();
786
+ };
744
787
  const reactiveCacheMax = options.reactiveCache?.max ?? 256;
745
788
  const reactiveCacheTtlMs = options.reactiveCache?.ttlMs ?? 60000;
746
789
  const cachedReruns = new Map;
@@ -782,6 +825,31 @@ var createSyncEngine = (options = {}) => {
782
825
  const runInTransaction = options.transaction;
783
826
  const instanceId = options.instanceId ?? globalThis.crypto?.randomUUID?.() ?? `i${Math.random()}`;
784
827
  let clusterBus;
828
+ const importChangeLog = (snapshot) => {
829
+ if (version !== 0) {
830
+ throw new Error(`[sync] importChangeLog: engine already has version ${version}; ` + `restore must happen before any local writes commit.`);
831
+ }
832
+ if (snapshot.instanceId !== instanceId) {
833
+ throw new Error(`[sync] importChangeLog: snapshot instanceId "${snapshot.instanceId}" ` + `does not match this engine's instanceId "${instanceId}". ` + `Pass options.instanceId = "${snapshot.instanceId}" to createSyncEngine.`);
834
+ }
835
+ version = snapshot.version;
836
+ for (const entry of snapshot.entries) {
837
+ changeLog.push(entry);
838
+ }
839
+ while (changeLog.length > changeLogSize) {
840
+ changeLog.shift();
841
+ }
842
+ if (changeLogRetainMs !== null && changeLogRetainMs > 0) {
843
+ const cutoff = Date.now() - changeLogRetainMs;
844
+ while (changeLog.length > 0 && changeLog[0].at < cutoff) {
845
+ changeLog.shift();
846
+ }
847
+ }
848
+ return snapshot.entries.length;
849
+ };
850
+ if (options.initialChangeLog !== undefined) {
851
+ importChangeLog(options.initialChangeLog);
852
+ }
785
853
  const broadcast = (changes, originVersion) => {
786
854
  if (clusterBus !== undefined && changes.length > 0) {
787
855
  clusterBus.publish({ changes, origin: instanceId, originVersion });
@@ -1743,6 +1811,7 @@ var createSyncEngine = (options = {}) => {
1743
1811
  throw new UnauthorizedError(`run mutation "${name}"`);
1744
1812
  }
1745
1813
  }
1814
+ await acquireMutationSlot();
1746
1815
  const sandboxRunner = sandboxRunners.get(name);
1747
1816
  const invokeHandler = sandboxRunner !== undefined ? sandboxRunner : (a, c, actions) => Promise.resolve(mutation.handler(a, c, actions));
1748
1817
  const runHandler = async (tx) => {
@@ -1758,7 +1827,6 @@ var createSyncEngine = (options = {}) => {
1758
1827
  const startedAt = Date.now();
1759
1828
  let lastError;
1760
1829
  let attemptsMade = 0;
1761
- mutationsInFlight += 1;
1762
1830
  try {
1763
1831
  for (let attempt = 1;attempt <= maxAttempts; attempt++) {
1764
1832
  attemptsMade = attempt;
@@ -1811,7 +1879,7 @@ var createSyncEngine = (options = {}) => {
1811
1879
  }
1812
1880
  throw lastError;
1813
1881
  } finally {
1814
- mutationsInFlight -= 1;
1882
+ releaseMutationSlot();
1815
1883
  }
1816
1884
  },
1817
1885
  runMutations: async (specs, ctx) => {
@@ -1824,6 +1892,7 @@ var createSyncEngine = (options = {}) => {
1824
1892
  }
1825
1893
  return { args: spec.args, mutation, name: spec.name };
1826
1894
  });
1895
+ await acquireMutationSlot();
1827
1896
  const runBatch = async (tx) => {
1828
1897
  const results = [];
1829
1898
  const accumulated = [];
@@ -1861,6 +1930,8 @@ var createSyncEngine = (options = {}) => {
1861
1930
  status: "error"
1862
1931
  });
1863
1932
  throw error;
1933
+ } finally {
1934
+ releaseMutationSlot();
1864
1935
  }
1865
1936
  },
1866
1937
  registerSchedule: (schedule) => {
@@ -2051,6 +2122,13 @@ var createSyncEngine = (options = {}) => {
2051
2122
  }))
2052
2123
  };
2053
2124
  },
2125
+ exportChangeLog: () => ({
2126
+ entries: changeLog.slice(),
2127
+ exportedAt: Date.now(),
2128
+ instanceId,
2129
+ version
2130
+ }),
2131
+ importChangeLog,
2054
2132
  metrics: () => {
2055
2133
  const now = Date.now();
2056
2134
  const byCollection = {};
@@ -2073,6 +2151,7 @@ var createSyncEngine = (options = {}) => {
2073
2151
  completed: mutationsCompleted,
2074
2152
  failed: mutationsFailed,
2075
2153
  inFlight: mutationsInFlight,
2154
+ queued: mutationsQueued,
2076
2155
  retried: mutationsRetried
2077
2156
  },
2078
2157
  reactiveCache: {
@@ -2193,5 +2272,5 @@ export {
2193
2272
  createTestEngine
2194
2273
  };
2195
2274
 
2196
- //# debugId=89F275CAA65D1FFC64756E2164756E21
2275
+ //# debugId=261DFADB673FBB5664756E2164756E21
2197
2276
  //# sourceMappingURL=testing.js.map