tinybase 9.4.0-beta.1 → 9.4.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/@types/persisters/index.d.ts +4 -0
- package/@types/persisters/persister-durable-object-sql-storage/index.d.ts +9 -2
- package/@types/persisters/persister-durable-object-sql-storage/with-schemas/index.d.ts +9 -2
- package/@types/persisters/with-schemas/index.d.ts +4 -0
- package/@types/queries/index.d.ts +4 -0
- package/@types/queries/with-schemas/index.d.ts +4 -0
- package/@types/synchronizers/synchronizer-ws-client/index.d.ts +7 -3
- package/@types/synchronizers/synchronizer-ws-client/with-schemas/index.d.ts +7 -3
- package/@types/synchronizers/synchronizer-ws-server/index.d.ts +9 -3
- package/@types/synchronizers/synchronizer-ws-server/with-schemas/index.d.ts +9 -3
- package/@types/synchronizers/synchronizer-ws-server-simple/index.d.ts +6 -3
- package/@types/synchronizers/synchronizer-ws-server-simple/with-schemas/index.d.ts +6 -3
- package/@types/ui-react-dom/index.d.ts +10 -10
- package/@types/ui-react-dom/with-schemas/index.d.ts +10 -10
- package/@types/ui-react-dom-charts/index.d.ts +7 -7
- package/@types/ui-react-dom-charts/with-schemas/index.d.ts +7 -7
- package/@types/ui-react-inspector/index.d.ts +1 -1
- package/@types/ui-react-inspector/with-schemas/index.d.ts +1 -1
- package/@types/ui-solid-dom/index.d.ts +10 -10
- package/@types/ui-solid-dom/with-schemas/index.d.ts +10 -10
- package/@types/ui-solid-inspector/index.d.ts +1 -1
- package/@types/ui-solid-inspector/with-schemas/index.d.ts +1 -1
- package/@types/ui-svelte-dom/index.d.ts +10 -10
- package/@types/ui-svelte-dom/with-schemas/index.d.ts +10 -10
- package/@types/ui-svelte-inspector/index.d.ts +1 -1
- package/@types/ui-svelte-inspector/with-schemas/index.d.ts +1 -1
- package/index.js +191 -74
- package/min/index.js +1 -1
- package/min/index.js.gz +0 -0
- package/min/omni/index.js +1 -1
- package/min/omni/index.js.gz +0 -0
- package/min/omni/with-schemas/index.js +1 -1
- package/min/omni/with-schemas/index.js.gz +0 -0
- package/min/persisters/index.js +1 -1
- package/min/persisters/index.js.gz +0 -0
- package/min/persisters/persister-automerge/index.js +1 -1
- package/min/persisters/persister-automerge/index.js.gz +0 -0
- package/min/persisters/persister-automerge/with-schemas/index.js +1 -1
- package/min/persisters/persister-automerge/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-browser/index.js +1 -1
- package/min/persisters/persister-browser/index.js.gz +0 -0
- package/min/persisters/persister-browser/with-schemas/index.js +1 -1
- package/min/persisters/persister-browser/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-cr-sqlite-wasm/index.js +1 -1
- package/min/persisters/persister-cr-sqlite-wasm/index.js.gz +0 -0
- package/min/persisters/persister-cr-sqlite-wasm/with-schemas/index.js +1 -1
- package/min/persisters/persister-cr-sqlite-wasm/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-durable-object-sql-storage/index.js +1 -1
- package/min/persisters/persister-durable-object-sql-storage/index.js.gz +0 -0
- package/min/persisters/persister-durable-object-sql-storage/with-schemas/index.js +1 -1
- package/min/persisters/persister-durable-object-sql-storage/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-durable-object-storage/index.js +1 -1
- package/min/persisters/persister-durable-object-storage/index.js.gz +0 -0
- package/min/persisters/persister-durable-object-storage/with-schemas/index.js +1 -1
- package/min/persisters/persister-durable-object-storage/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-electric-sql/index.js +1 -1
- package/min/persisters/persister-electric-sql/index.js.gz +0 -0
- package/min/persisters/persister-electric-sql/with-schemas/index.js +1 -1
- package/min/persisters/persister-electric-sql/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-expo-sqlite/index.js +1 -1
- package/min/persisters/persister-expo-sqlite/index.js.gz +0 -0
- package/min/persisters/persister-expo-sqlite/with-schemas/index.js +1 -1
- package/min/persisters/persister-expo-sqlite/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-file/index.js +1 -1
- package/min/persisters/persister-file/index.js.gz +0 -0
- package/min/persisters/persister-file/with-schemas/index.js +1 -1
- package/min/persisters/persister-file/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-indexed-db/index.js +1 -1
- package/min/persisters/persister-indexed-db/index.js.gz +0 -0
- package/min/persisters/persister-indexed-db/with-schemas/index.js +1 -1
- package/min/persisters/persister-indexed-db/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-libsql/index.js +1 -1
- package/min/persisters/persister-libsql/index.js.gz +0 -0
- package/min/persisters/persister-libsql/with-schemas/index.js +1 -1
- package/min/persisters/persister-libsql/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-partykit-client/index.js +1 -1
- package/min/persisters/persister-partykit-client/index.js.gz +0 -0
- package/min/persisters/persister-partykit-client/with-schemas/index.js +1 -1
- package/min/persisters/persister-partykit-client/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-pglite/index.js +1 -1
- package/min/persisters/persister-pglite/index.js.gz +0 -0
- package/min/persisters/persister-pglite/with-schemas/index.js +1 -1
- package/min/persisters/persister-pglite/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-postgres/index.js +1 -1
- package/min/persisters/persister-postgres/index.js.gz +0 -0
- package/min/persisters/persister-postgres/with-schemas/index.js +1 -1
- package/min/persisters/persister-postgres/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-powersync/index.js +1 -1
- package/min/persisters/persister-powersync/index.js.gz +0 -0
- package/min/persisters/persister-powersync/with-schemas/index.js +1 -1
- package/min/persisters/persister-powersync/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-react-native-mmkv/index.js +1 -1
- package/min/persisters/persister-react-native-mmkv/index.js.gz +0 -0
- package/min/persisters/persister-react-native-mmkv/with-schemas/index.js +1 -1
- package/min/persisters/persister-react-native-mmkv/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-react-native-sqlite/index.js +1 -1
- package/min/persisters/persister-react-native-sqlite/index.js.gz +0 -0
- package/min/persisters/persister-react-native-sqlite/with-schemas/index.js +1 -1
- package/min/persisters/persister-react-native-sqlite/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-remote/index.js +1 -1
- package/min/persisters/persister-remote/index.js.gz +0 -0
- package/min/persisters/persister-remote/with-schemas/index.js +1 -1
- package/min/persisters/persister-remote/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-sqlite-bun/index.js +1 -1
- package/min/persisters/persister-sqlite-bun/index.js.gz +0 -0
- package/min/persisters/persister-sqlite-bun/with-schemas/index.js +1 -1
- package/min/persisters/persister-sqlite-bun/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-sqlite-wasm/index.js +1 -1
- package/min/persisters/persister-sqlite-wasm/index.js.gz +0 -0
- package/min/persisters/persister-sqlite-wasm/with-schemas/index.js +1 -1
- package/min/persisters/persister-sqlite-wasm/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-sqlite3/index.js +1 -1
- package/min/persisters/persister-sqlite3/index.js.gz +0 -0
- package/min/persisters/persister-sqlite3/with-schemas/index.js +1 -1
- package/min/persisters/persister-sqlite3/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-yjs/index.js +1 -1
- package/min/persisters/persister-yjs/index.js.gz +0 -0
- package/min/persisters/persister-yjs/with-schemas/index.js +1 -1
- package/min/persisters/persister-yjs/with-schemas/index.js.gz +0 -0
- package/min/persisters/with-schemas/index.js +1 -1
- package/min/persisters/with-schemas/index.js.gz +0 -0
- package/min/queries/index.js +1 -1
- package/min/queries/index.js.gz +0 -0
- package/min/queries/with-schemas/index.js +1 -1
- package/min/queries/with-schemas/index.js.gz +0 -0
- package/min/synchronizers/index.js +1 -1
- package/min/synchronizers/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-broadcast-channel/index.js +1 -1
- package/min/synchronizers/synchronizer-broadcast-channel/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js +1 -1
- package/min/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-local/index.js +1 -1
- package/min/synchronizers/synchronizer-local/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-local/with-schemas/index.js +1 -1
- package/min/synchronizers/synchronizer-local/with-schemas/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-ws-client/index.js +1 -1
- package/min/synchronizers/synchronizer-ws-client/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-ws-client/with-schemas/index.js +1 -1
- package/min/synchronizers/synchronizer-ws-client/with-schemas/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-ws-server/index.js +1 -1
- package/min/synchronizers/synchronizer-ws-server/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-ws-server/with-schemas/index.js +1 -1
- package/min/synchronizers/synchronizer-ws-server/with-schemas/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-ws-server-durable-object/index.js +1 -1
- package/min/synchronizers/synchronizer-ws-server-durable-object/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js +1 -1
- package/min/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-ws-server-simple/index.js +1 -1
- package/min/synchronizers/synchronizer-ws-server-simple/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-ws-server-simple/with-schemas/index.js +1 -1
- package/min/synchronizers/synchronizer-ws-server-simple/with-schemas/index.js.gz +0 -0
- package/min/synchronizers/with-schemas/index.js +1 -1
- package/min/synchronizers/with-schemas/index.js.gz +0 -0
- package/min/ui-react-inspector/index.js +1 -1
- package/min/ui-react-inspector/index.js.gz +0 -0
- package/min/ui-react-inspector/with-schemas/index.js +1 -1
- package/min/ui-react-inspector/with-schemas/index.js.gz +0 -0
- package/min/ui-solid-inspector/index.js +1 -1
- package/min/ui-solid-inspector/index.js.gz +0 -0
- package/min/ui-solid-inspector/with-schemas/index.js +1 -1
- package/min/ui-solid-inspector/with-schemas/index.js.gz +0 -0
- package/min/ui-svelte-inspector/index.js +1 -1
- package/min/ui-svelte-inspector/index.js.gz +0 -0
- package/min/ui-svelte-inspector/with-schemas/index.js +1 -1
- package/min/ui-svelte-inspector/with-schemas/index.js.gz +0 -0
- package/min/with-schemas/index.js +1 -1
- package/min/with-schemas/index.js.gz +0 -0
- package/omni/index.js +606 -179
- package/omni/with-schemas/index.js +606 -179
- package/package.json +12 -8
- package/persisters/index.js +49 -10
- package/persisters/persister-automerge/index.js +29 -5
- package/persisters/persister-automerge/with-schemas/index.js +29 -5
- package/persisters/persister-browser/index.js +29 -5
- package/persisters/persister-browser/with-schemas/index.js +29 -5
- package/persisters/persister-cr-sqlite-wasm/index.js +29 -5
- package/persisters/persister-cr-sqlite-wasm/with-schemas/index.js +29 -5
- package/persisters/persister-durable-object-sql-storage/index.js +44 -8
- package/persisters/persister-durable-object-sql-storage/with-schemas/index.js +44 -8
- package/persisters/persister-durable-object-storage/index.js +31 -5
- package/persisters/persister-durable-object-storage/with-schemas/index.js +31 -5
- package/persisters/persister-electric-sql/index.js +29 -5
- package/persisters/persister-electric-sql/with-schemas/index.js +29 -5
- package/persisters/persister-expo-sqlite/index.js +29 -5
- package/persisters/persister-expo-sqlite/with-schemas/index.js +29 -5
- package/persisters/persister-file/index.js +31 -5
- package/persisters/persister-file/with-schemas/index.js +31 -5
- package/persisters/persister-indexed-db/index.js +29 -5
- package/persisters/persister-indexed-db/with-schemas/index.js +29 -5
- package/persisters/persister-libsql/index.js +29 -5
- package/persisters/persister-libsql/with-schemas/index.js +29 -5
- package/persisters/persister-partykit-client/index.js +31 -5
- package/persisters/persister-partykit-client/with-schemas/index.js +31 -5
- package/persisters/persister-pglite/index.js +49 -10
- package/persisters/persister-pglite/with-schemas/index.js +49 -10
- package/persisters/persister-postgres/index.js +49 -10
- package/persisters/persister-postgres/with-schemas/index.js +49 -10
- package/persisters/persister-powersync/index.js +29 -5
- package/persisters/persister-powersync/with-schemas/index.js +29 -5
- package/persisters/persister-react-native-mmkv/index.js +31 -5
- package/persisters/persister-react-native-mmkv/with-schemas/index.js +31 -5
- package/persisters/persister-react-native-sqlite/index.js +29 -5
- package/persisters/persister-react-native-sqlite/with-schemas/index.js +29 -5
- package/persisters/persister-remote/index.js +31 -5
- package/persisters/persister-remote/with-schemas/index.js +31 -5
- package/persisters/persister-sqlite-bun/index.js +29 -5
- package/persisters/persister-sqlite-bun/with-schemas/index.js +29 -5
- package/persisters/persister-sqlite-wasm/index.js +29 -5
- package/persisters/persister-sqlite-wasm/with-schemas/index.js +29 -5
- package/persisters/persister-sqlite3/index.js +29 -5
- package/persisters/persister-sqlite3/with-schemas/index.js +29 -5
- package/persisters/persister-yjs/index.js +29 -5
- package/persisters/persister-yjs/with-schemas/index.js +29 -5
- package/persisters/with-schemas/index.js +49 -10
- package/queries/index.js +205 -74
- package/queries/with-schemas/index.js +205 -74
- package/readme.md +14 -14
- package/releases.md +84 -67
- package/synchronizers/index.js +31 -5
- package/synchronizers/synchronizer-broadcast-channel/index.js +39 -13
- package/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js +39 -13
- package/synchronizers/synchronizer-local/index.js +31 -5
- package/synchronizers/synchronizer-local/with-schemas/index.js +31 -5
- package/synchronizers/synchronizer-ws-client/index.js +220 -61
- package/synchronizers/synchronizer-ws-client/with-schemas/index.js +220 -61
- package/synchronizers/synchronizer-ws-server/index.js +253 -73
- package/synchronizers/synchronizer-ws-server/with-schemas/index.js +253 -73
- package/synchronizers/synchronizer-ws-server-durable-object/index.js +88 -40
- package/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js +88 -40
- package/synchronizers/synchronizer-ws-server-simple/index.js +184 -60
- package/synchronizers/synchronizer-ws-server-simple/with-schemas/index.js +184 -60
- package/synchronizers/with-schemas/index.js +31 -5
- package/ui-react-inspector/index.js +29 -5
- package/ui-react-inspector/with-schemas/index.js +29 -5
- package/ui-solid-inspector/index.js +29 -5
- package/ui-solid-inspector/with-schemas/index.js +29 -5
- package/ui-svelte-inspector/index.js +29 -5
- package/ui-svelte-inspector/with-schemas/index.js +29 -5
- package/with-schemas/index.js +191 -74
|
@@ -248,6 +248,8 @@ const tryCatch = async (action, onError) => {
|
|
|
248
248
|
onError?.(error);
|
|
249
249
|
}
|
|
250
250
|
};
|
|
251
|
+
const tryCatchIgnore = (action, onIgnoredError) =>
|
|
252
|
+
tryCatch(action, (error) => void tryCatch(() => onIgnoredError?.(error)));
|
|
251
253
|
const tryCatchSync = (action, onError) => {
|
|
252
254
|
try {
|
|
253
255
|
return action();
|
|
@@ -291,6 +293,14 @@ const isHlc = (hlc, maxLogicalTime) =>
|
|
|
291
293
|
hlc == EMPTY_STRING ||
|
|
292
294
|
(isString(hlc) && test(HLC, hlc) && decodeHlcTime(hlc) <= maxLogicalTime);
|
|
293
295
|
|
|
296
|
+
const setNew = (entryOrEntries) =>
|
|
297
|
+
new Set(
|
|
298
|
+
isArray(entryOrEntries) || isUndefined(entryOrEntries)
|
|
299
|
+
? entryOrEntries
|
|
300
|
+
: [entryOrEntries],
|
|
301
|
+
);
|
|
302
|
+
const setAdd = (set, value) => set?.add(value);
|
|
303
|
+
|
|
294
304
|
const MESSAGE_SEPARATOR = '\n';
|
|
295
305
|
const FRAGMENT = /^([-0-9A-Z_a-z]{16})\n(\d+)\n(\d+)\n([\s\S]*)$/;
|
|
296
306
|
const FRAGMENT_PAYLOAD = /^[^\n]*\n[-0-9A-Z_a-z]{16}\n\d+\n\d+\n/;
|
|
@@ -423,21 +433,30 @@ const createPayloadDecoder = (
|
|
|
423
433
|
receive,
|
|
424
434
|
fragmentTimeoutSeconds = 1,
|
|
425
435
|
onInvalid,
|
|
436
|
+
sharedBuffer,
|
|
426
437
|
) => {
|
|
427
438
|
const buffer = mapNew();
|
|
439
|
+
const payloadBuffer = [0, 0];
|
|
428
440
|
let bufferedSize = 0;
|
|
429
441
|
let valid = true;
|
|
430
442
|
const delPending = (bufferKey, pending) => {
|
|
431
443
|
stopTimeout(pending[4]);
|
|
432
444
|
bufferedSize -= pending[5];
|
|
445
|
+
payloadBuffer[0]--;
|
|
446
|
+
payloadBuffer[1] -= pending[5];
|
|
433
447
|
collDel(buffer, bufferKey);
|
|
434
448
|
};
|
|
449
|
+
const clear = () => {
|
|
450
|
+
mapForEach(buffer, (_bufferKey, pending) => stopTimeout(pending[4]));
|
|
451
|
+
payloadBuffer[0] -= collSize(buffer);
|
|
452
|
+
payloadBuffer[1] -= bufferedSize;
|
|
453
|
+
collClear(buffer);
|
|
454
|
+
bufferedSize = 0;
|
|
455
|
+
};
|
|
435
456
|
const invalid = (error = errorNew(ERROR_SYNC_MESSAGE)) => {
|
|
436
457
|
if (valid) {
|
|
437
458
|
valid = false;
|
|
438
|
-
|
|
439
|
-
collClear(buffer);
|
|
440
|
-
bufferedSize = 0;
|
|
459
|
+
clear();
|
|
441
460
|
onInvalid?.(error);
|
|
442
461
|
}
|
|
443
462
|
};
|
|
@@ -449,7 +468,7 @@ const createPayloadDecoder = (
|
|
|
449
468
|
invalid();
|
|
450
469
|
}
|
|
451
470
|
};
|
|
452
|
-
|
|
471
|
+
const decode = (payload) => {
|
|
453
472
|
if (!valid) {
|
|
454
473
|
return;
|
|
455
474
|
}
|
|
@@ -482,42 +501,52 @@ const createPayloadDecoder = (
|
|
|
482
501
|
const bufferKey = clientId + MESSAGE_SEPARATOR + messageId;
|
|
483
502
|
let pending = mapGet(buffer, bufferKey);
|
|
484
503
|
if (!pending) {
|
|
485
|
-
if (
|
|
504
|
+
if (payloadBuffer[0] >= MAX_FRAGMENT_BUFFERS) {
|
|
486
505
|
invalid(errorNew(ERROR_SYNC_OVERFLOW, 'fragments'));
|
|
487
506
|
return;
|
|
488
507
|
}
|
|
489
|
-
pending = [
|
|
490
|
-
[],
|
|
491
|
-
[],
|
|
492
|
-
total,
|
|
493
|
-
total,
|
|
494
|
-
startTimeout(() => {
|
|
495
|
-
const timedOut = mapGet(buffer, bufferKey);
|
|
496
|
-
if (timedOut) {
|
|
497
|
-
delPending(bufferKey, timedOut);
|
|
498
|
-
}
|
|
499
|
-
}, fragmentTimeoutSeconds),
|
|
500
|
-
0,
|
|
501
|
-
];
|
|
502
|
-
mapSet(buffer, bufferKey, pending);
|
|
503
508
|
}
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
509
|
+
if (
|
|
510
|
+
(isUndefined(pending) || total == pending[3]) &&
|
|
511
|
+
isUndefined(pending?.[0][index])
|
|
512
|
+
) {
|
|
513
|
+
const retainedSize =
|
|
514
|
+
getWebSocketPayloadSize(remainder) +
|
|
515
|
+
(pending ? 0 : getWebSocketPayloadSize(bufferKey));
|
|
516
|
+
if (payloadBuffer[1] + retainedSize > MAX_WEBSOCKET_BUFFER_SIZE) {
|
|
508
517
|
invalid(errorNew(ERROR_SYNC_OVERFLOW, 'fragments'));
|
|
509
518
|
return;
|
|
510
519
|
}
|
|
520
|
+
if (!pending) {
|
|
521
|
+
pending = [
|
|
522
|
+
[],
|
|
523
|
+
[],
|
|
524
|
+
total,
|
|
525
|
+
total,
|
|
526
|
+
startTimeout(() => {
|
|
527
|
+
const timedOut = mapGet(buffer, bufferKey);
|
|
528
|
+
if (timedOut) {
|
|
529
|
+
delPending(bufferKey, timedOut);
|
|
530
|
+
}
|
|
531
|
+
}, fragmentTimeoutSeconds),
|
|
532
|
+
0,
|
|
533
|
+
];
|
|
534
|
+
mapSet(buffer, bufferKey, pending);
|
|
535
|
+
payloadBuffer[0]++;
|
|
536
|
+
}
|
|
537
|
+
const [fragments, remainders] = pending;
|
|
511
538
|
fragments[index] = fragment;
|
|
512
539
|
remainders[index] = remainder;
|
|
513
540
|
pending[2]--;
|
|
514
|
-
pending[5] +=
|
|
515
|
-
bufferedSize +=
|
|
541
|
+
pending[5] += retainedSize;
|
|
542
|
+
bufferedSize += retainedSize;
|
|
543
|
+
payloadBuffer[1] += retainedSize;
|
|
516
544
|
} else {
|
|
517
545
|
invalid();
|
|
518
546
|
return;
|
|
519
547
|
}
|
|
520
548
|
if (pending[2] == 0) {
|
|
549
|
+
const [fragments, remainders] = pending;
|
|
521
550
|
delPending(bufferKey, pending);
|
|
522
551
|
receiveRemainder(clientId, remainders, arrayJoin(fragments));
|
|
523
552
|
}
|
|
@@ -530,11 +559,13 @@ const createPayloadDecoder = (
|
|
|
530
559
|
invalid();
|
|
531
560
|
}
|
|
532
561
|
};
|
|
562
|
+
return [decode, clear];
|
|
533
563
|
};
|
|
534
564
|
const createPayloadReceiver = (
|
|
535
565
|
receive,
|
|
536
566
|
fragmentTimeoutSeconds = 1,
|
|
537
567
|
onInvalid,
|
|
568
|
+
sharedBuffer,
|
|
538
569
|
) =>
|
|
539
570
|
createPayloadDecoder(
|
|
540
571
|
(fromClientId, _remainders, requestId, message, body) =>
|
|
@@ -621,14 +652,6 @@ const getPoolFunctions = () => {
|
|
|
621
652
|
];
|
|
622
653
|
};
|
|
623
654
|
|
|
624
|
-
const setNew = (entryOrEntries) =>
|
|
625
|
-
new Set(
|
|
626
|
-
isArray(entryOrEntries) || isUndefined(entryOrEntries)
|
|
627
|
-
? entryOrEntries
|
|
628
|
-
: [entryOrEntries],
|
|
629
|
-
);
|
|
630
|
-
const setAdd = (set, value) => set?.add(value);
|
|
631
|
-
|
|
632
655
|
const getWildcardedLeaves = (deepIdSet, path = [EMPTY_STRING]) => {
|
|
633
656
|
const leaves = [];
|
|
634
657
|
const deep = (node, p) =>
|
|
@@ -1053,11 +1076,35 @@ const createCustomPersister = (
|
|
|
1053
1076
|
initialContent,
|
|
1054
1077
|
startSaveFirst = false,
|
|
1055
1078
|
) => {
|
|
1056
|
-
const [call1, call2] = startSaveFirst
|
|
1057
|
-
? [startAutoSave, startAutoLoad]
|
|
1058
|
-
: [startAutoLoad, startAutoSave];
|
|
1059
|
-
|
|
1060
|
-
|
|
1079
|
+
const [call1, call2, stop1, stop2] = startSaveFirst
|
|
1080
|
+
? [startAutoSave, startAutoLoad, stopAutoSave, stopAutoLoad]
|
|
1081
|
+
: [startAutoLoad, startAutoSave, stopAutoLoad, stopAutoSave];
|
|
1082
|
+
const start1 = call1(initialContent);
|
|
1083
|
+
const generation1 = startSaveFirst
|
|
1084
|
+
? autoSaveGeneration
|
|
1085
|
+
: autoLoadGeneration;
|
|
1086
|
+
await start1;
|
|
1087
|
+
const start2 = call2(initialContent);
|
|
1088
|
+
const generation2 = startSaveFirst
|
|
1089
|
+
? autoLoadGeneration
|
|
1090
|
+
: autoSaveGeneration;
|
|
1091
|
+
try {
|
|
1092
|
+
await start2;
|
|
1093
|
+
} catch (error) {
|
|
1094
|
+
if (
|
|
1095
|
+
generation2 ==
|
|
1096
|
+
(startSaveFirst ? autoLoadGeneration : autoSaveGeneration)
|
|
1097
|
+
) {
|
|
1098
|
+
await tryCatchIgnore(stop2);
|
|
1099
|
+
}
|
|
1100
|
+
if (
|
|
1101
|
+
generation1 ==
|
|
1102
|
+
(startSaveFirst ? autoSaveGeneration : autoLoadGeneration)
|
|
1103
|
+
) {
|
|
1104
|
+
await tryCatchIgnore(stop1);
|
|
1105
|
+
}
|
|
1106
|
+
throw error;
|
|
1107
|
+
}
|
|
1061
1108
|
return persister;
|
|
1062
1109
|
};
|
|
1063
1110
|
const stopAutoPersisting = async (stopSaveFirst = false) => {
|
|
@@ -1478,7 +1525,7 @@ class WsServerDurableObject extends DurableObject {
|
|
|
1478
1525
|
(this.#serverClientSend = createPayloadReceiver(
|
|
1479
1526
|
receive,
|
|
1480
1527
|
requestTimeoutSeconds,
|
|
1481
|
-
)),
|
|
1528
|
+
)[0]),
|
|
1482
1529
|
noop,
|
|
1483
1530
|
requestTimeoutSeconds,
|
|
1484
1531
|
);
|
|
@@ -1526,10 +1573,11 @@ class WsServerDurableObject extends DurableObject {
|
|
|
1526
1573
|
);
|
|
1527
1574
|
this.#payloadDecoders.set(client, decode);
|
|
1528
1575
|
}
|
|
1529
|
-
decode(message.toString());
|
|
1576
|
+
decode[0](message.toString());
|
|
1530
1577
|
});
|
|
1531
1578
|
}
|
|
1532
1579
|
webSocketClose(client) {
|
|
1580
|
+
this.#payloadDecoders.get(client)?.[1]();
|
|
1533
1581
|
this.#payloadDecoders.delete(client);
|
|
1534
1582
|
const [clientId, pathId] = this.ctx.getTags(client);
|
|
1535
1583
|
this.onClientId(pathId, clientId, -1);
|
|
@@ -248,6 +248,8 @@ const tryCatch = async (action, onError) => {
|
|
|
248
248
|
onError?.(error);
|
|
249
249
|
}
|
|
250
250
|
};
|
|
251
|
+
const tryCatchIgnore = (action, onIgnoredError) =>
|
|
252
|
+
tryCatch(action, (error) => void tryCatch(() => onIgnoredError?.(error)));
|
|
251
253
|
const tryCatchSync = (action, onError) => {
|
|
252
254
|
try {
|
|
253
255
|
return action();
|
|
@@ -291,6 +293,14 @@ const isHlc = (hlc, maxLogicalTime) =>
|
|
|
291
293
|
hlc == EMPTY_STRING ||
|
|
292
294
|
(isString(hlc) && test(HLC, hlc) && decodeHlcTime(hlc) <= maxLogicalTime);
|
|
293
295
|
|
|
296
|
+
const setNew = (entryOrEntries) =>
|
|
297
|
+
new Set(
|
|
298
|
+
isArray(entryOrEntries) || isUndefined(entryOrEntries)
|
|
299
|
+
? entryOrEntries
|
|
300
|
+
: [entryOrEntries],
|
|
301
|
+
);
|
|
302
|
+
const setAdd = (set, value) => set?.add(value);
|
|
303
|
+
|
|
294
304
|
const MESSAGE_SEPARATOR = '\n';
|
|
295
305
|
const FRAGMENT = /^([-0-9A-Z_a-z]{16})\n(\d+)\n(\d+)\n([\s\S]*)$/;
|
|
296
306
|
const FRAGMENT_PAYLOAD = /^[^\n]*\n[-0-9A-Z_a-z]{16}\n\d+\n\d+\n/;
|
|
@@ -423,21 +433,30 @@ const createPayloadDecoder = (
|
|
|
423
433
|
receive,
|
|
424
434
|
fragmentTimeoutSeconds = 1,
|
|
425
435
|
onInvalid,
|
|
436
|
+
sharedBuffer,
|
|
426
437
|
) => {
|
|
427
438
|
const buffer = mapNew();
|
|
439
|
+
const payloadBuffer = [0, 0];
|
|
428
440
|
let bufferedSize = 0;
|
|
429
441
|
let valid = true;
|
|
430
442
|
const delPending = (bufferKey, pending) => {
|
|
431
443
|
stopTimeout(pending[4]);
|
|
432
444
|
bufferedSize -= pending[5];
|
|
445
|
+
payloadBuffer[0]--;
|
|
446
|
+
payloadBuffer[1] -= pending[5];
|
|
433
447
|
collDel(buffer, bufferKey);
|
|
434
448
|
};
|
|
449
|
+
const clear = () => {
|
|
450
|
+
mapForEach(buffer, (_bufferKey, pending) => stopTimeout(pending[4]));
|
|
451
|
+
payloadBuffer[0] -= collSize(buffer);
|
|
452
|
+
payloadBuffer[1] -= bufferedSize;
|
|
453
|
+
collClear(buffer);
|
|
454
|
+
bufferedSize = 0;
|
|
455
|
+
};
|
|
435
456
|
const invalid = (error = errorNew(ERROR_SYNC_MESSAGE)) => {
|
|
436
457
|
if (valid) {
|
|
437
458
|
valid = false;
|
|
438
|
-
|
|
439
|
-
collClear(buffer);
|
|
440
|
-
bufferedSize = 0;
|
|
459
|
+
clear();
|
|
441
460
|
onInvalid?.(error);
|
|
442
461
|
}
|
|
443
462
|
};
|
|
@@ -449,7 +468,7 @@ const createPayloadDecoder = (
|
|
|
449
468
|
invalid();
|
|
450
469
|
}
|
|
451
470
|
};
|
|
452
|
-
|
|
471
|
+
const decode = (payload) => {
|
|
453
472
|
if (!valid) {
|
|
454
473
|
return;
|
|
455
474
|
}
|
|
@@ -482,42 +501,52 @@ const createPayloadDecoder = (
|
|
|
482
501
|
const bufferKey = clientId + MESSAGE_SEPARATOR + messageId;
|
|
483
502
|
let pending = mapGet(buffer, bufferKey);
|
|
484
503
|
if (!pending) {
|
|
485
|
-
if (
|
|
504
|
+
if (payloadBuffer[0] >= MAX_FRAGMENT_BUFFERS) {
|
|
486
505
|
invalid(errorNew(ERROR_SYNC_OVERFLOW, 'fragments'));
|
|
487
506
|
return;
|
|
488
507
|
}
|
|
489
|
-
pending = [
|
|
490
|
-
[],
|
|
491
|
-
[],
|
|
492
|
-
total,
|
|
493
|
-
total,
|
|
494
|
-
startTimeout(() => {
|
|
495
|
-
const timedOut = mapGet(buffer, bufferKey);
|
|
496
|
-
if (timedOut) {
|
|
497
|
-
delPending(bufferKey, timedOut);
|
|
498
|
-
}
|
|
499
|
-
}, fragmentTimeoutSeconds),
|
|
500
|
-
0,
|
|
501
|
-
];
|
|
502
|
-
mapSet(buffer, bufferKey, pending);
|
|
503
508
|
}
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
509
|
+
if (
|
|
510
|
+
(isUndefined(pending) || total == pending[3]) &&
|
|
511
|
+
isUndefined(pending?.[0][index])
|
|
512
|
+
) {
|
|
513
|
+
const retainedSize =
|
|
514
|
+
getWebSocketPayloadSize(remainder) +
|
|
515
|
+
(pending ? 0 : getWebSocketPayloadSize(bufferKey));
|
|
516
|
+
if (payloadBuffer[1] + retainedSize > MAX_WEBSOCKET_BUFFER_SIZE) {
|
|
508
517
|
invalid(errorNew(ERROR_SYNC_OVERFLOW, 'fragments'));
|
|
509
518
|
return;
|
|
510
519
|
}
|
|
520
|
+
if (!pending) {
|
|
521
|
+
pending = [
|
|
522
|
+
[],
|
|
523
|
+
[],
|
|
524
|
+
total,
|
|
525
|
+
total,
|
|
526
|
+
startTimeout(() => {
|
|
527
|
+
const timedOut = mapGet(buffer, bufferKey);
|
|
528
|
+
if (timedOut) {
|
|
529
|
+
delPending(bufferKey, timedOut);
|
|
530
|
+
}
|
|
531
|
+
}, fragmentTimeoutSeconds),
|
|
532
|
+
0,
|
|
533
|
+
];
|
|
534
|
+
mapSet(buffer, bufferKey, pending);
|
|
535
|
+
payloadBuffer[0]++;
|
|
536
|
+
}
|
|
537
|
+
const [fragments, remainders] = pending;
|
|
511
538
|
fragments[index] = fragment;
|
|
512
539
|
remainders[index] = remainder;
|
|
513
540
|
pending[2]--;
|
|
514
|
-
pending[5] +=
|
|
515
|
-
bufferedSize +=
|
|
541
|
+
pending[5] += retainedSize;
|
|
542
|
+
bufferedSize += retainedSize;
|
|
543
|
+
payloadBuffer[1] += retainedSize;
|
|
516
544
|
} else {
|
|
517
545
|
invalid();
|
|
518
546
|
return;
|
|
519
547
|
}
|
|
520
548
|
if (pending[2] == 0) {
|
|
549
|
+
const [fragments, remainders] = pending;
|
|
521
550
|
delPending(bufferKey, pending);
|
|
522
551
|
receiveRemainder(clientId, remainders, arrayJoin(fragments));
|
|
523
552
|
}
|
|
@@ -530,11 +559,13 @@ const createPayloadDecoder = (
|
|
|
530
559
|
invalid();
|
|
531
560
|
}
|
|
532
561
|
};
|
|
562
|
+
return [decode, clear];
|
|
533
563
|
};
|
|
534
564
|
const createPayloadReceiver = (
|
|
535
565
|
receive,
|
|
536
566
|
fragmentTimeoutSeconds = 1,
|
|
537
567
|
onInvalid,
|
|
568
|
+
sharedBuffer,
|
|
538
569
|
) =>
|
|
539
570
|
createPayloadDecoder(
|
|
540
571
|
(fromClientId, _remainders, requestId, message, body) =>
|
|
@@ -621,14 +652,6 @@ const getPoolFunctions = () => {
|
|
|
621
652
|
];
|
|
622
653
|
};
|
|
623
654
|
|
|
624
|
-
const setNew = (entryOrEntries) =>
|
|
625
|
-
new Set(
|
|
626
|
-
isArray(entryOrEntries) || isUndefined(entryOrEntries)
|
|
627
|
-
? entryOrEntries
|
|
628
|
-
: [entryOrEntries],
|
|
629
|
-
);
|
|
630
|
-
const setAdd = (set, value) => set?.add(value);
|
|
631
|
-
|
|
632
655
|
const getWildcardedLeaves = (deepIdSet, path = [EMPTY_STRING]) => {
|
|
633
656
|
const leaves = [];
|
|
634
657
|
const deep = (node, p) =>
|
|
@@ -1053,11 +1076,35 @@ const createCustomPersister = (
|
|
|
1053
1076
|
initialContent,
|
|
1054
1077
|
startSaveFirst = false,
|
|
1055
1078
|
) => {
|
|
1056
|
-
const [call1, call2] = startSaveFirst
|
|
1057
|
-
? [startAutoSave, startAutoLoad]
|
|
1058
|
-
: [startAutoLoad, startAutoSave];
|
|
1059
|
-
|
|
1060
|
-
|
|
1079
|
+
const [call1, call2, stop1, stop2] = startSaveFirst
|
|
1080
|
+
? [startAutoSave, startAutoLoad, stopAutoSave, stopAutoLoad]
|
|
1081
|
+
: [startAutoLoad, startAutoSave, stopAutoLoad, stopAutoSave];
|
|
1082
|
+
const start1 = call1(initialContent);
|
|
1083
|
+
const generation1 = startSaveFirst
|
|
1084
|
+
? autoSaveGeneration
|
|
1085
|
+
: autoLoadGeneration;
|
|
1086
|
+
await start1;
|
|
1087
|
+
const start2 = call2(initialContent);
|
|
1088
|
+
const generation2 = startSaveFirst
|
|
1089
|
+
? autoLoadGeneration
|
|
1090
|
+
: autoSaveGeneration;
|
|
1091
|
+
try {
|
|
1092
|
+
await start2;
|
|
1093
|
+
} catch (error) {
|
|
1094
|
+
if (
|
|
1095
|
+
generation2 ==
|
|
1096
|
+
(startSaveFirst ? autoLoadGeneration : autoSaveGeneration)
|
|
1097
|
+
) {
|
|
1098
|
+
await tryCatchIgnore(stop2);
|
|
1099
|
+
}
|
|
1100
|
+
if (
|
|
1101
|
+
generation1 ==
|
|
1102
|
+
(startSaveFirst ? autoSaveGeneration : autoLoadGeneration)
|
|
1103
|
+
) {
|
|
1104
|
+
await tryCatchIgnore(stop1);
|
|
1105
|
+
}
|
|
1106
|
+
throw error;
|
|
1107
|
+
}
|
|
1061
1108
|
return persister;
|
|
1062
1109
|
};
|
|
1063
1110
|
const stopAutoPersisting = async (stopSaveFirst = false) => {
|
|
@@ -1478,7 +1525,7 @@ class WsServerDurableObject extends DurableObject {
|
|
|
1478
1525
|
(this.#serverClientSend = createPayloadReceiver(
|
|
1479
1526
|
receive,
|
|
1480
1527
|
requestTimeoutSeconds,
|
|
1481
|
-
)),
|
|
1528
|
+
)[0]),
|
|
1482
1529
|
noop,
|
|
1483
1530
|
requestTimeoutSeconds,
|
|
1484
1531
|
);
|
|
@@ -1526,10 +1573,11 @@ class WsServerDurableObject extends DurableObject {
|
|
|
1526
1573
|
);
|
|
1527
1574
|
this.#payloadDecoders.set(client, decode);
|
|
1528
1575
|
}
|
|
1529
|
-
decode(message.toString());
|
|
1576
|
+
decode[0](message.toString());
|
|
1530
1577
|
});
|
|
1531
1578
|
}
|
|
1532
1579
|
webSocketClose(client) {
|
|
1580
|
+
this.#payloadDecoders.get(client)?.[1]();
|
|
1533
1581
|
this.#payloadDecoders.delete(client);
|
|
1534
1582
|
const [clientId, pathId] = this.ctx.getTags(client);
|
|
1535
1583
|
this.onClientId(pathId, clientId, -1);
|