tinybase 8.6.0-beta.0 → 9.0.0-beta.1
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/_internal/queries/with-schemas/index.d.ts +1 -2
- package/@types/_internal/ui/with-schemas/index.d.ts +8 -16
- package/@types/mergeable-store/index.d.ts +4 -4
- package/@types/mergeable-store/with-schemas/index.d.ts +41 -17
- package/@types/persisters/index.d.ts +34 -13
- package/@types/persisters/persister-durable-object-sql-storage/index.d.ts +9 -8
- package/@types/persisters/persister-durable-object-sql-storage/with-schemas/index.d.ts +10 -10
- package/@types/persisters/with-schemas/index.d.ts +72 -30
- package/@types/queries/index.d.ts +5 -7
- package/@types/queries/with-schemas/index.d.ts +9 -15
- package/@types/store/index.d.ts +1 -2
- package/@types/store/with-schemas/index.d.ts +19 -29
- package/@types/synchronizers/synchronizer-ws-client/index.d.ts +9 -3
- package/@types/synchronizers/synchronizer-ws-client/with-schemas/index.d.ts +10 -3
- package/@types/synchronizers/synchronizer-ws-server/index.d.ts +15 -2
- package/@types/synchronizers/synchronizer-ws-server/with-schemas/index.d.ts +17 -2
- package/@types/synchronizers/synchronizer-ws-server-durable-object/index.d.ts +51 -0
- package/@types/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.d.ts +51 -0
- package/@types/ui-react/with-schemas/index.d.ts +3 -6
- package/@types/ui-react-dom/with-schemas/index.d.ts +6 -12
- package/@types/ui-react-dom-charts/with-schemas/index.d.ts +3 -4
- package/@types/ui-solid/with-schemas/index.d.ts +4 -8
- package/@types/ui-solid-dom/with-schemas/index.d.ts +6 -12
- package/@types/ui-svelte-dom/with-schemas/index.d.ts +6 -12
- package/index.js +67 -25
- package/indexes/index.js +6 -8
- package/indexes/with-schemas/index.js +6 -8
- package/mergeable-store/index.js +46 -6
- package/mergeable-store/with-schemas/index.js +46 -6
- package/metrics/index.js +6 -8
- package/metrics/with-schemas/index.js +6 -8
- package/min/index.js +1 -1
- package/min/index.js.gz +0 -0
- package/min/mergeable-store/index.js +1 -1
- package/min/mergeable-store/index.js.gz +0 -0
- package/min/mergeable-store/with-schemas/index.js +1 -1
- package/min/mergeable-store/with-schemas/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/store/index.js +1 -1
- package/min/store/index.js.gz +0 -0
- package/min/store/with-schemas/index.js +1 -1
- package/min/store/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/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 +364 -155
- package/omni/with-schemas/index.js +364 -155
- package/package.json +8 -8
- package/persisters/index.js +133 -40
- package/persisters/persister-automerge/index.js +4 -3
- package/persisters/persister-automerge/with-schemas/index.js +4 -3
- package/persisters/persister-browser/index.js +4 -3
- package/persisters/persister-browser/with-schemas/index.js +4 -3
- package/persisters/persister-cr-sqlite-wasm/index.js +133 -40
- package/persisters/persister-cr-sqlite-wasm/with-schemas/index.js +133 -40
- package/persisters/persister-durable-object-sql-storage/index.js +275 -113
- package/persisters/persister-durable-object-sql-storage/with-schemas/index.js +275 -113
- package/persisters/persister-durable-object-storage/index.js +4 -3
- package/persisters/persister-durable-object-storage/with-schemas/index.js +4 -3
- package/persisters/persister-electric-sql/index.js +133 -40
- package/persisters/persister-electric-sql/with-schemas/index.js +133 -40
- package/persisters/persister-expo-sqlite/index.js +133 -40
- package/persisters/persister-expo-sqlite/with-schemas/index.js +133 -40
- package/persisters/persister-file/index.js +4 -3
- package/persisters/persister-file/with-schemas/index.js +4 -3
- package/persisters/persister-indexed-db/index.js +4 -3
- package/persisters/persister-indexed-db/with-schemas/index.js +4 -3
- package/persisters/persister-libsql/index.js +133 -40
- package/persisters/persister-libsql/with-schemas/index.js +133 -40
- package/persisters/persister-partykit-client/index.js +4 -3
- package/persisters/persister-partykit-client/with-schemas/index.js +4 -3
- package/persisters/persister-pglite/index.js +134 -40
- package/persisters/persister-pglite/with-schemas/index.js +134 -40
- package/persisters/persister-postgres/index.js +134 -40
- package/persisters/persister-postgres/with-schemas/index.js +134 -40
- package/persisters/persister-powersync/index.js +186 -120
- package/persisters/persister-powersync/with-schemas/index.js +186 -120
- package/persisters/persister-react-native-mmkv/index.js +4 -3
- package/persisters/persister-react-native-mmkv/with-schemas/index.js +4 -3
- package/persisters/persister-react-native-sqlite/index.js +133 -40
- package/persisters/persister-react-native-sqlite/with-schemas/index.js +133 -40
- package/persisters/persister-remote/index.js +4 -3
- package/persisters/persister-remote/with-schemas/index.js +4 -3
- package/persisters/persister-sqlite-bun/index.js +133 -40
- package/persisters/persister-sqlite-bun/with-schemas/index.js +133 -40
- package/persisters/persister-sqlite-wasm/index.js +133 -40
- package/persisters/persister-sqlite-wasm/with-schemas/index.js +133 -40
- package/persisters/persister-sqlite3/index.js +133 -40
- package/persisters/persister-sqlite3/with-schemas/index.js +133 -40
- package/persisters/persister-yjs/index.js +4 -3
- package/persisters/persister-yjs/with-schemas/index.js +4 -3
- package/persisters/with-schemas/index.js +133 -40
- package/queries/index.js +21 -19
- package/queries/with-schemas/index.js +21 -19
- package/readme.md +14 -14
- package/relationships/index.js +6 -8
- package/relationships/with-schemas/index.js +6 -8
- package/releases.md +72 -57
- package/store/index.js +33 -2
- package/store/with-schemas/index.js +33 -2
- package/synchronizers/index.js +4 -3
- package/synchronizers/synchronizer-broadcast-channel/index.js +4 -3
- package/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js +4 -3
- package/synchronizers/synchronizer-local/index.js +4 -3
- package/synchronizers/synchronizer-local/with-schemas/index.js +4 -3
- package/synchronizers/synchronizer-ws-client/index.js +120 -45
- package/synchronizers/synchronizer-ws-client/with-schemas/index.js +120 -45
- package/synchronizers/synchronizer-ws-server/index.js +116 -36
- package/synchronizers/synchronizer-ws-server/with-schemas/index.js +116 -36
- package/synchronizers/synchronizer-ws-server-durable-object/index.js +125 -41
- package/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js +125 -41
- package/synchronizers/with-schemas/index.js +4 -3
- package/ui-react-inspector/index.js +36 -5
- package/ui-react-inspector/with-schemas/index.js +36 -5
- package/ui-solid-inspector/index.js +36 -5
- package/ui-solid-inspector/with-schemas/index.js +36 -5
- package/ui-svelte/index.js +1 -1
- package/ui-svelte/with-schemas/index.js +1 -1
- package/ui-svelte-dom/index.js +2 -2
- package/ui-svelte-dom/with-schemas/index.js +2 -2
- package/ui-svelte-inspector/index.js +38 -7
- package/ui-svelte-inspector/with-schemas/index.js +38 -7
- package/with-schemas/index.js +67 -25
|
@@ -5,6 +5,7 @@ const OPEN = 'open';
|
|
|
5
5
|
const MESSAGE = 'message';
|
|
6
6
|
const ERROR = 'error';
|
|
7
7
|
const UNDEFINED = '\uFFFC';
|
|
8
|
+
const strMatch = (str, regex) => str?.match(regex);
|
|
8
9
|
const strSplit = (str, separator = EMPTY_STRING, limit) =>
|
|
9
10
|
str.split(separator, limit);
|
|
10
11
|
|
|
@@ -19,6 +20,7 @@ const GLOBAL = globalThis;
|
|
|
19
20
|
const THOUSAND = 1e3;
|
|
20
21
|
const startTimeout = (callback, sec = 0) =>
|
|
21
22
|
setTimeout(callback, sec * THOUSAND);
|
|
23
|
+
const stopTimeout = clearTimeout;
|
|
22
24
|
const mathFloor = math.floor;
|
|
23
25
|
const mathRandom = math.random;
|
|
24
26
|
const isNullish = (thing) => thing == null;
|
|
@@ -44,12 +46,19 @@ const tryCatch = async (action, then1, then2) => {
|
|
|
44
46
|
};
|
|
45
47
|
|
|
46
48
|
const arrayForEach = (array, cb) => array.forEach(cb);
|
|
49
|
+
const arrayJoin = (array, sep = EMPTY_STRING) => array.join(sep);
|
|
47
50
|
const arrayMap = (array, cb) => array.map(cb);
|
|
48
51
|
const arrayReduce = (array, cb, initial) => array.reduce(cb, initial);
|
|
49
52
|
const arrayClear = (array, to) => array.splice(0, to);
|
|
50
53
|
const arrayPush = (array, ...values) => array.push(...values);
|
|
51
54
|
const arrayShift = (array) => array.shift();
|
|
52
55
|
|
|
56
|
+
const collSize = (coll) => coll?.size ?? 0;
|
|
57
|
+
const collHas = (coll, keyOrValue) => coll?.has(keyOrValue) ?? false;
|
|
58
|
+
const collIsEmpty = (coll) => isUndefined(coll) || collSize(coll) == 0;
|
|
59
|
+
const collForEach = (coll, cb) => coll?.forEach(cb);
|
|
60
|
+
const collDel = (coll, keyOrValue) => coll?.delete(keyOrValue);
|
|
61
|
+
|
|
53
62
|
const object = Object;
|
|
54
63
|
const getPrototypeOf = (obj) => object.getPrototypeOf(obj);
|
|
55
64
|
const objEntries = object.entries;
|
|
@@ -83,44 +92,6 @@ const objEnsure = (obj, id, getDefaultValue) => {
|
|
|
83
92
|
return obj[id];
|
|
84
93
|
};
|
|
85
94
|
|
|
86
|
-
const jsonString = JSON.stringify;
|
|
87
|
-
const jsonParse = JSON.parse;
|
|
88
|
-
const jsonStringWithUndefined = (obj) =>
|
|
89
|
-
jsonString(obj, (_key, value) => (isUndefined(value) ? UNDEFINED : value));
|
|
90
|
-
const jsonParseWithUndefined = (str) =>
|
|
91
|
-
// JSON.parse reviver removes properties with undefined values
|
|
92
|
-
replaceUndefinedString(jsonParse(str));
|
|
93
|
-
const replaceUndefinedString = (obj) =>
|
|
94
|
-
obj === UNDEFINED
|
|
95
|
-
? void 0
|
|
96
|
-
: isArray(obj)
|
|
97
|
-
? arrayMap(obj, replaceUndefinedString)
|
|
98
|
-
: isObject(obj)
|
|
99
|
-
? objMap(obj, replaceUndefinedString)
|
|
100
|
-
: obj;
|
|
101
|
-
|
|
102
|
-
const MESSAGE_SEPARATOR = '\n';
|
|
103
|
-
const ifPayloadValid = (payload, then) => {
|
|
104
|
-
const splitAt = payload.indexOf(MESSAGE_SEPARATOR);
|
|
105
|
-
if (splitAt !== -1) {
|
|
106
|
-
then(slice(payload, 0, splitAt), slice(payload, splitAt + 1));
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
const receivePayload = (payload, receive) =>
|
|
110
|
-
ifPayloadValid(payload, (fromClientId, remainder) =>
|
|
111
|
-
receive(fromClientId, ...jsonParseWithUndefined(remainder)),
|
|
112
|
-
);
|
|
113
|
-
const createPayload = (toClientId, ...args) =>
|
|
114
|
-
createRawPayload(toClientId ?? EMPTY_STRING, jsonStringWithUndefined(args));
|
|
115
|
-
const createRawPayload = (clientId, remainder) =>
|
|
116
|
-
clientId + MESSAGE_SEPARATOR + remainder;
|
|
117
|
-
|
|
118
|
-
const collSize = (coll) => coll?.size ?? 0;
|
|
119
|
-
const collHas = (coll, keyOrValue) => coll?.has(keyOrValue) ?? false;
|
|
120
|
-
const collIsEmpty = (coll) => isUndefined(coll) || collSize(coll) == 0;
|
|
121
|
-
const collForEach = (coll, cb) => coll?.forEach(cb);
|
|
122
|
-
const collDel = (coll, keyOrValue) => coll?.delete(keyOrValue);
|
|
123
|
-
|
|
124
95
|
const map = Map;
|
|
125
96
|
const mapNew = (entries) => new map(entries);
|
|
126
97
|
const mapGet = (map2, key) => map2?.get(key);
|
|
@@ -172,6 +143,103 @@ const getUniqueId = (length = 16) =>
|
|
|
172
143
|
EMPTY_STRING,
|
|
173
144
|
);
|
|
174
145
|
|
|
146
|
+
const jsonString = JSON.stringify;
|
|
147
|
+
const jsonParse = JSON.parse;
|
|
148
|
+
const jsonStringWithUndefined = (obj) =>
|
|
149
|
+
jsonString(obj, (_key, value) => (isUndefined(value) ? UNDEFINED : value));
|
|
150
|
+
const jsonParseWithUndefined = (str) =>
|
|
151
|
+
// JSON.parse reviver removes properties with undefined values
|
|
152
|
+
replaceUndefinedString(jsonParse(str));
|
|
153
|
+
const replaceUndefinedString = (obj) =>
|
|
154
|
+
obj === UNDEFINED
|
|
155
|
+
? void 0
|
|
156
|
+
: isArray(obj)
|
|
157
|
+
? arrayMap(obj, replaceUndefinedString)
|
|
158
|
+
: isObject(obj)
|
|
159
|
+
? objMap(obj, replaceUndefinedString)
|
|
160
|
+
: obj;
|
|
161
|
+
|
|
162
|
+
const MESSAGE_SEPARATOR = '\n';
|
|
163
|
+
const FRAGMENT = /^(.+)\n(\d+)\n(\d+)\n([\s\S]*)$/;
|
|
164
|
+
const ifPayloadValid = (payload, then) => {
|
|
165
|
+
const splitAt = payload.indexOf(MESSAGE_SEPARATOR);
|
|
166
|
+
if (splitAt !== -1) {
|
|
167
|
+
then(slice(payload, 0, splitAt), slice(payload, splitAt + 1));
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
const receivePayloadRemainder = (fromClientId, remainder, receive) =>
|
|
171
|
+
receive(fromClientId, ...jsonParseWithUndefined(remainder));
|
|
172
|
+
const createPayloadReceiver = (receive, fragmentTimeoutSeconds = 1) => {
|
|
173
|
+
const buffer = mapNew();
|
|
174
|
+
const setPendingTimeout = (bufferKey) =>
|
|
175
|
+
startTimeout(() => collDel(buffer, bufferKey), fragmentTimeoutSeconds);
|
|
176
|
+
const delPending = (bufferKey, pending) => {
|
|
177
|
+
stopTimeout(pending[3]);
|
|
178
|
+
collDel(buffer, bufferKey);
|
|
179
|
+
};
|
|
180
|
+
return (payload) =>
|
|
181
|
+
ifPayloadValid(payload, (fromClientId, remainder) => {
|
|
182
|
+
const [, messageId, indexStr, totalStr, fragment] =
|
|
183
|
+
strMatch(remainder, FRAGMENT) ?? [];
|
|
184
|
+
if (messageId) {
|
|
185
|
+
const index = parseInt(indexStr);
|
|
186
|
+
const total = parseInt(totalStr);
|
|
187
|
+
if (total > 0 && index >= 0 && index < total) {
|
|
188
|
+
const bufferKey = fromClientId + MESSAGE_SEPARATOR + messageId;
|
|
189
|
+
const pending = mapEnsure(buffer, bufferKey, () => [
|
|
190
|
+
[],
|
|
191
|
+
total,
|
|
192
|
+
total,
|
|
193
|
+
setPendingTimeout(bufferKey),
|
|
194
|
+
]);
|
|
195
|
+
const [fragments] = pending;
|
|
196
|
+
if (total == pending[2] && isUndefined(fragments[index])) {
|
|
197
|
+
stopTimeout(pending[3]);
|
|
198
|
+
pending[3] = setPendingTimeout(bufferKey);
|
|
199
|
+
fragments[index] = fragment;
|
|
200
|
+
pending[1]--;
|
|
201
|
+
}
|
|
202
|
+
if (pending[1] == 0) {
|
|
203
|
+
delPending(bufferKey, pending);
|
|
204
|
+
receivePayloadRemainder(
|
|
205
|
+
fromClientId,
|
|
206
|
+
arrayJoin(fragments),
|
|
207
|
+
receive,
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
} else {
|
|
212
|
+
receivePayloadRemainder(fromClientId, remainder, receive);
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
};
|
|
216
|
+
const createRawPayload = (clientId, remainder) =>
|
|
217
|
+
clientId + MESSAGE_SEPARATOR + remainder;
|
|
218
|
+
const createPayloads = (toClientId, requestId, message, body, fragmentSize) => {
|
|
219
|
+
const clientId = toClientId ?? EMPTY_STRING;
|
|
220
|
+
const remainder = jsonStringWithUndefined([requestId, message, body]);
|
|
221
|
+
const maxFragmentSize = mathFloor(fragmentSize ?? 0);
|
|
222
|
+
if (
|
|
223
|
+
isUndefined(fragmentSize) ||
|
|
224
|
+
maxFragmentSize < 1 ||
|
|
225
|
+
size(remainder) <= maxFragmentSize
|
|
226
|
+
) {
|
|
227
|
+
return [createRawPayload(clientId, remainder)];
|
|
228
|
+
}
|
|
229
|
+
const fragments = strMatch(
|
|
230
|
+
remainder,
|
|
231
|
+
new RegExp(`.{1,${maxFragmentSize}}`, 'g'),
|
|
232
|
+
);
|
|
233
|
+
const total = size(fragments ?? []);
|
|
234
|
+
const messageId = getUniqueId();
|
|
235
|
+
return arrayMap(fragments ?? [], (fragment, index) =>
|
|
236
|
+
createRawPayload(
|
|
237
|
+
clientId,
|
|
238
|
+
arrayJoin([messageId, index, total, fragment], MESSAGE_SEPARATOR),
|
|
239
|
+
),
|
|
240
|
+
);
|
|
241
|
+
};
|
|
242
|
+
|
|
175
243
|
const stampNew = (value, hlc) => (hlc ? [value, hlc] : [value]);
|
|
176
244
|
const getLatestHlc = (hlc1, hlc2) =>
|
|
177
245
|
/* istanbul ignore next */
|
|
@@ -373,13 +441,14 @@ const createCustomPersister = (
|
|
|
373
441
|
const content = await getPersisted();
|
|
374
442
|
if (isArray(content)) {
|
|
375
443
|
setContentOrChanges(content);
|
|
376
|
-
} else if (initialContent) {
|
|
444
|
+
} else if (isUndefined(content) && initialContent) {
|
|
377
445
|
setDefaultContent(initialContent);
|
|
378
|
-
} else {
|
|
446
|
+
} else if (!isUndefined(content)) {
|
|
379
447
|
errorNew(`Content is not an array: ${content}`);
|
|
380
448
|
}
|
|
381
449
|
},
|
|
382
|
-
() => {
|
|
450
|
+
(error) => {
|
|
451
|
+
onIgnoredError?.(error);
|
|
383
452
|
if (initialContent) {
|
|
384
453
|
setDefaultContent(initialContent);
|
|
385
454
|
}
|
|
@@ -745,17 +814,23 @@ const createWsSynchronizer = async (
|
|
|
745
814
|
onSend,
|
|
746
815
|
onReceive,
|
|
747
816
|
onIgnoredError,
|
|
817
|
+
fragmentSize,
|
|
748
818
|
) => {
|
|
749
819
|
const addEventListener = (event, handler) => {
|
|
750
820
|
webSocket.addEventListener(event, handler);
|
|
751
821
|
return () => webSocket.removeEventListener(event, handler);
|
|
752
822
|
};
|
|
753
|
-
const registerReceive = (receive) =>
|
|
754
|
-
|
|
755
|
-
|
|
823
|
+
const registerReceive = (receive) => {
|
|
824
|
+
const receivePayload = createPayloadReceiver(
|
|
825
|
+
receive,
|
|
826
|
+
requestTimeoutSeconds,
|
|
756
827
|
);
|
|
828
|
+
addEventListener(MESSAGE, ({data}) => receivePayload(data.toString(UTF8)));
|
|
829
|
+
};
|
|
757
830
|
const send = (toClientId, ...args) =>
|
|
758
|
-
|
|
831
|
+
arrayForEach(createPayloads(toClientId, ...args, fragmentSize), (payload) =>
|
|
832
|
+
webSocket.send(payload),
|
|
833
|
+
);
|
|
759
834
|
const destroy = () => {
|
|
760
835
|
webSocket.close();
|
|
761
836
|
};
|
|
@@ -19,6 +19,7 @@ const GLOBAL = globalThis;
|
|
|
19
19
|
const THOUSAND = 1e3;
|
|
20
20
|
const startTimeout = (callback, sec = 0) =>
|
|
21
21
|
setTimeout(callback, sec * THOUSAND);
|
|
22
|
+
const stopTimeout = clearTimeout;
|
|
22
23
|
const mathFloor = math.floor;
|
|
23
24
|
const mathRandom = math.random;
|
|
24
25
|
const isNullish = (thing) => thing == null;
|
|
@@ -46,6 +47,7 @@ const tryCatch = async (action, then1, then2) => {
|
|
|
46
47
|
};
|
|
47
48
|
|
|
48
49
|
const arrayForEach = (array, cb) => array.forEach(cb);
|
|
50
|
+
const arrayJoin = (array, sep = EMPTY_STRING) => array.join(sep);
|
|
49
51
|
const arrayMap = (array, cb) => array.map(cb);
|
|
50
52
|
const arrayReduce = (array, cb, initial) => array.reduce(cb, initial);
|
|
51
53
|
const arrayClear = (array, to) => array.splice(0, to);
|
|
@@ -230,6 +232,22 @@ const getListenerFunctions = (getThing) => {
|
|
|
230
232
|
return [addListener, callListeners, delListener, callListener];
|
|
231
233
|
};
|
|
232
234
|
|
|
235
|
+
const MASK6 = 63;
|
|
236
|
+
const ENCODE = /* @__PURE__ */ strSplit(
|
|
237
|
+
'-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz',
|
|
238
|
+
);
|
|
239
|
+
const encode = (num) => ENCODE[num & MASK6];
|
|
240
|
+
const getRandomValues = GLOBAL.crypto
|
|
241
|
+
? (array) => GLOBAL.crypto.getRandomValues(array)
|
|
242
|
+
: /* istanbul ignore next */
|
|
243
|
+
(array) => arrayMap(array, () => mathFloor(mathRandom() * 256));
|
|
244
|
+
const getUniqueId = (length = 16) =>
|
|
245
|
+
arrayReduce(
|
|
246
|
+
getRandomValues(new Uint8Array(length)),
|
|
247
|
+
(uniqueId, number) => uniqueId + encode(number),
|
|
248
|
+
EMPTY_STRING,
|
|
249
|
+
);
|
|
250
|
+
|
|
233
251
|
const jsonString = JSON.stringify;
|
|
234
252
|
const jsonParse = JSON.parse;
|
|
235
253
|
const jsonStringWithUndefined = (obj) =>
|
|
@@ -247,36 +265,85 @@ const replaceUndefinedString = (obj) =>
|
|
|
247
265
|
: obj;
|
|
248
266
|
|
|
249
267
|
const MESSAGE_SEPARATOR = '\n';
|
|
268
|
+
const FRAGMENT = /^(.+)\n(\d+)\n(\d+)\n([\s\S]*)$/;
|
|
250
269
|
const ifPayloadValid = (payload, then) => {
|
|
251
270
|
const splitAt = payload.indexOf(MESSAGE_SEPARATOR);
|
|
252
271
|
if (splitAt !== -1) {
|
|
253
272
|
then(slice(payload, 0, splitAt), slice(payload, splitAt + 1));
|
|
254
273
|
}
|
|
255
274
|
};
|
|
256
|
-
const
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
);
|
|
260
|
-
const
|
|
261
|
-
|
|
275
|
+
const receivePayloadRemainder = (fromClientId, remainder, receive) =>
|
|
276
|
+
receive(fromClientId, ...jsonParseWithUndefined(remainder));
|
|
277
|
+
const createPayloadReceiver = (receive, fragmentTimeoutSeconds = 1) => {
|
|
278
|
+
const buffer = mapNew();
|
|
279
|
+
const setPendingTimeout = (bufferKey) =>
|
|
280
|
+
startTimeout(() => collDel(buffer, bufferKey), fragmentTimeoutSeconds);
|
|
281
|
+
const delPending = (bufferKey, pending) => {
|
|
282
|
+
stopTimeout(pending[3]);
|
|
283
|
+
collDel(buffer, bufferKey);
|
|
284
|
+
};
|
|
285
|
+
return (payload) =>
|
|
286
|
+
ifPayloadValid(payload, (fromClientId, remainder) => {
|
|
287
|
+
const [, messageId, indexStr, totalStr, fragment] =
|
|
288
|
+
strMatch(remainder, FRAGMENT) ?? [];
|
|
289
|
+
if (messageId) {
|
|
290
|
+
const index = parseInt(indexStr);
|
|
291
|
+
const total = parseInt(totalStr);
|
|
292
|
+
if (total > 0 && index >= 0 && index < total) {
|
|
293
|
+
const bufferKey = fromClientId + MESSAGE_SEPARATOR + messageId;
|
|
294
|
+
const pending = mapEnsure(buffer, bufferKey, () => [
|
|
295
|
+
[],
|
|
296
|
+
total,
|
|
297
|
+
total,
|
|
298
|
+
setPendingTimeout(bufferKey),
|
|
299
|
+
]);
|
|
300
|
+
const [fragments] = pending;
|
|
301
|
+
if (total == pending[2] && isUndefined(fragments[index])) {
|
|
302
|
+
stopTimeout(pending[3]);
|
|
303
|
+
pending[3] = setPendingTimeout(bufferKey);
|
|
304
|
+
fragments[index] = fragment;
|
|
305
|
+
pending[1]--;
|
|
306
|
+
}
|
|
307
|
+
if (pending[1] == 0) {
|
|
308
|
+
delPending(bufferKey, pending);
|
|
309
|
+
receivePayloadRemainder(
|
|
310
|
+
fromClientId,
|
|
311
|
+
arrayJoin(fragments),
|
|
312
|
+
receive,
|
|
313
|
+
);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
} else {
|
|
317
|
+
receivePayloadRemainder(fromClientId, remainder, receive);
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
};
|
|
262
321
|
const createRawPayload = (clientId, remainder) =>
|
|
263
322
|
clientId + MESSAGE_SEPARATOR + remainder;
|
|
264
|
-
|
|
265
|
-
const
|
|
266
|
-
const
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
(
|
|
278
|
-
|
|
323
|
+
const createPayloads = (toClientId, requestId, message, body, fragmentSize) => {
|
|
324
|
+
const clientId = toClientId ?? EMPTY_STRING;
|
|
325
|
+
const remainder = jsonStringWithUndefined([requestId, message, body]);
|
|
326
|
+
const maxFragmentSize = mathFloor(fragmentSize ?? 0);
|
|
327
|
+
if (
|
|
328
|
+
isUndefined(fragmentSize) ||
|
|
329
|
+
maxFragmentSize < 1 ||
|
|
330
|
+
size(remainder) <= maxFragmentSize
|
|
331
|
+
) {
|
|
332
|
+
return [createRawPayload(clientId, remainder)];
|
|
333
|
+
}
|
|
334
|
+
const fragments = strMatch(
|
|
335
|
+
remainder,
|
|
336
|
+
new RegExp(`.{1,${maxFragmentSize}}`, 'g'),
|
|
337
|
+
);
|
|
338
|
+
const total = size(fragments ?? []);
|
|
339
|
+
const messageId = getUniqueId();
|
|
340
|
+
return arrayMap(fragments ?? [], (fragment, index) =>
|
|
341
|
+
createRawPayload(
|
|
342
|
+
clientId,
|
|
343
|
+
arrayJoin([messageId, index, total, fragment], MESSAGE_SEPARATOR),
|
|
344
|
+
),
|
|
279
345
|
);
|
|
346
|
+
};
|
|
280
347
|
|
|
281
348
|
const stampNew = (value, hlc) => (hlc ? [value, hlc] : [value]);
|
|
282
349
|
const getLatestHlc = (hlc1, hlc2) =>
|
|
@@ -385,13 +452,14 @@ const createCustomPersister = (
|
|
|
385
452
|
const content = await getPersisted();
|
|
386
453
|
if (isArray(content)) {
|
|
387
454
|
setContentOrChanges(content);
|
|
388
|
-
} else if (initialContent) {
|
|
455
|
+
} else if (isUndefined(content) && initialContent) {
|
|
389
456
|
setDefaultContent(initialContent);
|
|
390
|
-
} else {
|
|
457
|
+
} else if (!isUndefined(content)) {
|
|
391
458
|
errorNew(`Content is not an array: ${content}`);
|
|
392
459
|
}
|
|
393
460
|
},
|
|
394
|
-
() => {
|
|
461
|
+
(error) => {
|
|
462
|
+
onIgnoredError?.(error);
|
|
395
463
|
if (initialContent) {
|
|
396
464
|
setDefaultContent(initialContent);
|
|
397
465
|
}
|
|
@@ -753,6 +821,8 @@ const createWsServer = (
|
|
|
753
821
|
webSocketServer,
|
|
754
822
|
createPersisterForPath,
|
|
755
823
|
onIgnoredError,
|
|
824
|
+
requestTimeoutSeconds = 1,
|
|
825
|
+
fragmentSize,
|
|
756
826
|
) => {
|
|
757
827
|
const pathIdListeners = mapNew();
|
|
758
828
|
const clientIdListeners = mapNew();
|
|
@@ -777,12 +847,24 @@ const createWsServer = (
|
|
|
777
847
|
serverClient[2 /* Synchronizer */] = createCustomSynchronizer(
|
|
778
848
|
serverClient[1 /* Persister */].getStore(),
|
|
779
849
|
(toClientId, requestId, message, body) =>
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
850
|
+
arrayForEach(
|
|
851
|
+
createPayloads(
|
|
852
|
+
toClientId,
|
|
853
|
+
requestId,
|
|
854
|
+
message,
|
|
855
|
+
body,
|
|
856
|
+
fragmentSize,
|
|
857
|
+
),
|
|
858
|
+
messageHandler,
|
|
859
|
+
),
|
|
860
|
+
(receive) => {
|
|
861
|
+
serverClient[3 /* Send */] = createPayloadReceiver(
|
|
862
|
+
receive,
|
|
863
|
+
requestTimeoutSeconds,
|
|
864
|
+
);
|
|
865
|
+
},
|
|
784
866
|
noop,
|
|
785
|
-
|
|
867
|
+
requestTimeoutSeconds,
|
|
786
868
|
void 0,
|
|
787
869
|
void 0,
|
|
788
870
|
onIgnoredError,
|
|
@@ -794,14 +876,12 @@ const createWsServer = (
|
|
|
794
876
|
},
|
|
795
877
|
);
|
|
796
878
|
const startServerClient = async (serverClient) => {
|
|
797
|
-
serverClient[0 /* State */] = 2 /* Starting
|
|
798
|
-
await serverClient[1 /* Persister */].
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
serverClient[2 /* Synchronizer */].startSync,
|
|
802
|
-
);
|
|
879
|
+
serverClient[0 /* State */] = 2; /* Starting */
|
|
880
|
+
await serverClient[1 /* Persister */].startAutoLoad();
|
|
881
|
+
await serverClient[1 /* Persister */].startAutoSave();
|
|
882
|
+
await serverClient[2 /* Synchronizer */].startSync();
|
|
803
883
|
serverClient[5 /* Then */](serverClient[1 /* Persister */].getStore());
|
|
804
|
-
serverClient[0 /* State */] = 0 /* Ready
|
|
884
|
+
serverClient[0 /* State */] = 0; /* Ready */
|
|
805
885
|
};
|
|
806
886
|
const stopServerClient = async (serverClient) => {
|
|
807
887
|
await serverClient[1 /* Persister */]?.destroy();
|
|
@@ -19,6 +19,7 @@ const GLOBAL = globalThis;
|
|
|
19
19
|
const THOUSAND = 1e3;
|
|
20
20
|
const startTimeout = (callback, sec = 0) =>
|
|
21
21
|
setTimeout(callback, sec * THOUSAND);
|
|
22
|
+
const stopTimeout = clearTimeout;
|
|
22
23
|
const mathFloor = math.floor;
|
|
23
24
|
const mathRandom = math.random;
|
|
24
25
|
const isNullish = (thing) => thing == null;
|
|
@@ -46,6 +47,7 @@ const tryCatch = async (action, then1, then2) => {
|
|
|
46
47
|
};
|
|
47
48
|
|
|
48
49
|
const arrayForEach = (array, cb) => array.forEach(cb);
|
|
50
|
+
const arrayJoin = (array, sep = EMPTY_STRING) => array.join(sep);
|
|
49
51
|
const arrayMap = (array, cb) => array.map(cb);
|
|
50
52
|
const arrayReduce = (array, cb, initial) => array.reduce(cb, initial);
|
|
51
53
|
const arrayClear = (array, to) => array.splice(0, to);
|
|
@@ -230,6 +232,22 @@ const getListenerFunctions = (getThing) => {
|
|
|
230
232
|
return [addListener, callListeners, delListener, callListener];
|
|
231
233
|
};
|
|
232
234
|
|
|
235
|
+
const MASK6 = 63;
|
|
236
|
+
const ENCODE = /* @__PURE__ */ strSplit(
|
|
237
|
+
'-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz',
|
|
238
|
+
);
|
|
239
|
+
const encode = (num) => ENCODE[num & MASK6];
|
|
240
|
+
const getRandomValues = GLOBAL.crypto
|
|
241
|
+
? (array) => GLOBAL.crypto.getRandomValues(array)
|
|
242
|
+
: /* istanbul ignore next */
|
|
243
|
+
(array) => arrayMap(array, () => mathFloor(mathRandom() * 256));
|
|
244
|
+
const getUniqueId = (length = 16) =>
|
|
245
|
+
arrayReduce(
|
|
246
|
+
getRandomValues(new Uint8Array(length)),
|
|
247
|
+
(uniqueId, number) => uniqueId + encode(number),
|
|
248
|
+
EMPTY_STRING,
|
|
249
|
+
);
|
|
250
|
+
|
|
233
251
|
const jsonString = JSON.stringify;
|
|
234
252
|
const jsonParse = JSON.parse;
|
|
235
253
|
const jsonStringWithUndefined = (obj) =>
|
|
@@ -247,36 +265,85 @@ const replaceUndefinedString = (obj) =>
|
|
|
247
265
|
: obj;
|
|
248
266
|
|
|
249
267
|
const MESSAGE_SEPARATOR = '\n';
|
|
268
|
+
const FRAGMENT = /^(.+)\n(\d+)\n(\d+)\n([\s\S]*)$/;
|
|
250
269
|
const ifPayloadValid = (payload, then) => {
|
|
251
270
|
const splitAt = payload.indexOf(MESSAGE_SEPARATOR);
|
|
252
271
|
if (splitAt !== -1) {
|
|
253
272
|
then(slice(payload, 0, splitAt), slice(payload, splitAt + 1));
|
|
254
273
|
}
|
|
255
274
|
};
|
|
256
|
-
const
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
);
|
|
260
|
-
const
|
|
261
|
-
|
|
275
|
+
const receivePayloadRemainder = (fromClientId, remainder, receive) =>
|
|
276
|
+
receive(fromClientId, ...jsonParseWithUndefined(remainder));
|
|
277
|
+
const createPayloadReceiver = (receive, fragmentTimeoutSeconds = 1) => {
|
|
278
|
+
const buffer = mapNew();
|
|
279
|
+
const setPendingTimeout = (bufferKey) =>
|
|
280
|
+
startTimeout(() => collDel(buffer, bufferKey), fragmentTimeoutSeconds);
|
|
281
|
+
const delPending = (bufferKey, pending) => {
|
|
282
|
+
stopTimeout(pending[3]);
|
|
283
|
+
collDel(buffer, bufferKey);
|
|
284
|
+
};
|
|
285
|
+
return (payload) =>
|
|
286
|
+
ifPayloadValid(payload, (fromClientId, remainder) => {
|
|
287
|
+
const [, messageId, indexStr, totalStr, fragment] =
|
|
288
|
+
strMatch(remainder, FRAGMENT) ?? [];
|
|
289
|
+
if (messageId) {
|
|
290
|
+
const index = parseInt(indexStr);
|
|
291
|
+
const total = parseInt(totalStr);
|
|
292
|
+
if (total > 0 && index >= 0 && index < total) {
|
|
293
|
+
const bufferKey = fromClientId + MESSAGE_SEPARATOR + messageId;
|
|
294
|
+
const pending = mapEnsure(buffer, bufferKey, () => [
|
|
295
|
+
[],
|
|
296
|
+
total,
|
|
297
|
+
total,
|
|
298
|
+
setPendingTimeout(bufferKey),
|
|
299
|
+
]);
|
|
300
|
+
const [fragments] = pending;
|
|
301
|
+
if (total == pending[2] && isUndefined(fragments[index])) {
|
|
302
|
+
stopTimeout(pending[3]);
|
|
303
|
+
pending[3] = setPendingTimeout(bufferKey);
|
|
304
|
+
fragments[index] = fragment;
|
|
305
|
+
pending[1]--;
|
|
306
|
+
}
|
|
307
|
+
if (pending[1] == 0) {
|
|
308
|
+
delPending(bufferKey, pending);
|
|
309
|
+
receivePayloadRemainder(
|
|
310
|
+
fromClientId,
|
|
311
|
+
arrayJoin(fragments),
|
|
312
|
+
receive,
|
|
313
|
+
);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
} else {
|
|
317
|
+
receivePayloadRemainder(fromClientId, remainder, receive);
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
};
|
|
262
321
|
const createRawPayload = (clientId, remainder) =>
|
|
263
322
|
clientId + MESSAGE_SEPARATOR + remainder;
|
|
264
|
-
|
|
265
|
-
const
|
|
266
|
-
const
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
(
|
|
278
|
-
|
|
323
|
+
const createPayloads = (toClientId, requestId, message, body, fragmentSize) => {
|
|
324
|
+
const clientId = toClientId ?? EMPTY_STRING;
|
|
325
|
+
const remainder = jsonStringWithUndefined([requestId, message, body]);
|
|
326
|
+
const maxFragmentSize = mathFloor(fragmentSize ?? 0);
|
|
327
|
+
if (
|
|
328
|
+
isUndefined(fragmentSize) ||
|
|
329
|
+
maxFragmentSize < 1 ||
|
|
330
|
+
size(remainder) <= maxFragmentSize
|
|
331
|
+
) {
|
|
332
|
+
return [createRawPayload(clientId, remainder)];
|
|
333
|
+
}
|
|
334
|
+
const fragments = strMatch(
|
|
335
|
+
remainder,
|
|
336
|
+
new RegExp(`.{1,${maxFragmentSize}}`, 'g'),
|
|
337
|
+
);
|
|
338
|
+
const total = size(fragments ?? []);
|
|
339
|
+
const messageId = getUniqueId();
|
|
340
|
+
return arrayMap(fragments ?? [], (fragment, index) =>
|
|
341
|
+
createRawPayload(
|
|
342
|
+
clientId,
|
|
343
|
+
arrayJoin([messageId, index, total, fragment], MESSAGE_SEPARATOR),
|
|
344
|
+
),
|
|
279
345
|
);
|
|
346
|
+
};
|
|
280
347
|
|
|
281
348
|
const stampNew = (value, hlc) => (hlc ? [value, hlc] : [value]);
|
|
282
349
|
const getLatestHlc = (hlc1, hlc2) =>
|
|
@@ -385,13 +452,14 @@ const createCustomPersister = (
|
|
|
385
452
|
const content = await getPersisted();
|
|
386
453
|
if (isArray(content)) {
|
|
387
454
|
setContentOrChanges(content);
|
|
388
|
-
} else if (initialContent) {
|
|
455
|
+
} else if (isUndefined(content) && initialContent) {
|
|
389
456
|
setDefaultContent(initialContent);
|
|
390
|
-
} else {
|
|
457
|
+
} else if (!isUndefined(content)) {
|
|
391
458
|
errorNew(`Content is not an array: ${content}`);
|
|
392
459
|
}
|
|
393
460
|
},
|
|
394
|
-
() => {
|
|
461
|
+
(error) => {
|
|
462
|
+
onIgnoredError?.(error);
|
|
395
463
|
if (initialContent) {
|
|
396
464
|
setDefaultContent(initialContent);
|
|
397
465
|
}
|
|
@@ -753,6 +821,8 @@ const createWsServer = (
|
|
|
753
821
|
webSocketServer,
|
|
754
822
|
createPersisterForPath,
|
|
755
823
|
onIgnoredError,
|
|
824
|
+
requestTimeoutSeconds = 1,
|
|
825
|
+
fragmentSize,
|
|
756
826
|
) => {
|
|
757
827
|
const pathIdListeners = mapNew();
|
|
758
828
|
const clientIdListeners = mapNew();
|
|
@@ -777,12 +847,24 @@ const createWsServer = (
|
|
|
777
847
|
serverClient[2 /* Synchronizer */] = createCustomSynchronizer(
|
|
778
848
|
serverClient[1 /* Persister */].getStore(),
|
|
779
849
|
(toClientId, requestId, message, body) =>
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
850
|
+
arrayForEach(
|
|
851
|
+
createPayloads(
|
|
852
|
+
toClientId,
|
|
853
|
+
requestId,
|
|
854
|
+
message,
|
|
855
|
+
body,
|
|
856
|
+
fragmentSize,
|
|
857
|
+
),
|
|
858
|
+
messageHandler,
|
|
859
|
+
),
|
|
860
|
+
(receive) => {
|
|
861
|
+
serverClient[3 /* Send */] = createPayloadReceiver(
|
|
862
|
+
receive,
|
|
863
|
+
requestTimeoutSeconds,
|
|
864
|
+
);
|
|
865
|
+
},
|
|
784
866
|
noop,
|
|
785
|
-
|
|
867
|
+
requestTimeoutSeconds,
|
|
786
868
|
void 0,
|
|
787
869
|
void 0,
|
|
788
870
|
onIgnoredError,
|
|
@@ -794,14 +876,12 @@ const createWsServer = (
|
|
|
794
876
|
},
|
|
795
877
|
);
|
|
796
878
|
const startServerClient = async (serverClient) => {
|
|
797
|
-
serverClient[0 /* State */] = 2 /* Starting
|
|
798
|
-
await serverClient[1 /* Persister */].
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
serverClient[2 /* Synchronizer */].startSync,
|
|
802
|
-
);
|
|
879
|
+
serverClient[0 /* State */] = 2; /* Starting */
|
|
880
|
+
await serverClient[1 /* Persister */].startAutoLoad();
|
|
881
|
+
await serverClient[1 /* Persister */].startAutoSave();
|
|
882
|
+
await serverClient[2 /* Synchronizer */].startSync();
|
|
803
883
|
serverClient[5 /* Then */](serverClient[1 /* Persister */].getStore());
|
|
804
|
-
serverClient[0 /* State */] = 0 /* Ready
|
|
884
|
+
serverClient[0 /* State */] = 0; /* Ready */
|
|
805
885
|
};
|
|
806
886
|
const stopServerClient = async (serverClient) => {
|
|
807
887
|
await serverClient[1 /* Persister */]?.destroy();
|