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
|
@@ -18,6 +18,7 @@ const GLOBAL = globalThis;
|
|
|
18
18
|
const THOUSAND = 1e3;
|
|
19
19
|
const startTimeout = (callback, sec = 0) =>
|
|
20
20
|
setTimeout(callback, sec * THOUSAND);
|
|
21
|
+
const stopTimeout = clearTimeout;
|
|
21
22
|
const mathFloor = math.floor;
|
|
22
23
|
const mathRandom = math.random;
|
|
23
24
|
const isNullish = (thing) => thing == null;
|
|
@@ -44,6 +45,7 @@ const tryCatch = async (action, then1, then2) => {
|
|
|
44
45
|
};
|
|
45
46
|
|
|
46
47
|
const arrayForEach = (array, cb) => array.forEach(cb);
|
|
48
|
+
const arrayJoin = (array, sep = EMPTY_STRING) => array.join(sep);
|
|
47
49
|
const arrayMap = (array, cb) => array.map(cb);
|
|
48
50
|
const arrayIsEmpty = (array) => size(array) == 0;
|
|
49
51
|
const arrayReduce = (array, cb, initial) => array.reduce(cb, initial);
|
|
@@ -85,38 +87,6 @@ const objEnsure = (obj, id, getDefaultValue) => {
|
|
|
85
87
|
return obj[id];
|
|
86
88
|
};
|
|
87
89
|
|
|
88
|
-
const jsonString = JSON.stringify;
|
|
89
|
-
const jsonParse = JSON.parse;
|
|
90
|
-
const jsonStringWithUndefined = (obj) =>
|
|
91
|
-
jsonString(obj, (_key, value) => (isUndefined(value) ? UNDEFINED : value));
|
|
92
|
-
const jsonParseWithUndefined = (str) =>
|
|
93
|
-
// JSON.parse reviver removes properties with undefined values
|
|
94
|
-
replaceUndefinedString(jsonParse(str));
|
|
95
|
-
const replaceUndefinedString = (obj) =>
|
|
96
|
-
obj === UNDEFINED
|
|
97
|
-
? void 0
|
|
98
|
-
: isArray(obj)
|
|
99
|
-
? arrayMap(obj, replaceUndefinedString)
|
|
100
|
-
: isObject(obj)
|
|
101
|
-
? objMap(obj, replaceUndefinedString)
|
|
102
|
-
: obj;
|
|
103
|
-
|
|
104
|
-
const MESSAGE_SEPARATOR = '\n';
|
|
105
|
-
const ifPayloadValid = (payload, then) => {
|
|
106
|
-
const splitAt = payload.indexOf(MESSAGE_SEPARATOR);
|
|
107
|
-
if (splitAt !== -1) {
|
|
108
|
-
then(slice(payload, 0, splitAt), slice(payload, splitAt + 1));
|
|
109
|
-
}
|
|
110
|
-
};
|
|
111
|
-
const receivePayload = (payload, receive) =>
|
|
112
|
-
ifPayloadValid(payload, (fromClientId, remainder) =>
|
|
113
|
-
receive(fromClientId, ...jsonParseWithUndefined(remainder)),
|
|
114
|
-
);
|
|
115
|
-
const createPayload = (toClientId, ...args) =>
|
|
116
|
-
createRawPayload(toClientId ?? EMPTY_STRING, jsonStringWithUndefined(args));
|
|
117
|
-
const createRawPayload = (clientId, remainder) =>
|
|
118
|
-
clientId + MESSAGE_SEPARATOR + remainder;
|
|
119
|
-
|
|
120
90
|
const collSize = (coll) => coll?.size ?? 0;
|
|
121
91
|
const collHas = (coll, keyOrValue) => coll?.has(keyOrValue) ?? false;
|
|
122
92
|
const collIsEmpty = (coll) => isUndefined(coll) || collSize(coll) == 0;
|
|
@@ -174,6 +144,105 @@ const getUniqueId = (length = 16) =>
|
|
|
174
144
|
EMPTY_STRING,
|
|
175
145
|
);
|
|
176
146
|
|
|
147
|
+
const jsonString = JSON.stringify;
|
|
148
|
+
const jsonParse = JSON.parse;
|
|
149
|
+
const jsonStringWithUndefined = (obj) =>
|
|
150
|
+
jsonString(obj, (_key, value) => (isUndefined(value) ? UNDEFINED : value));
|
|
151
|
+
const jsonParseWithUndefined = (str) =>
|
|
152
|
+
// JSON.parse reviver removes properties with undefined values
|
|
153
|
+
replaceUndefinedString(jsonParse(str));
|
|
154
|
+
const replaceUndefinedString = (obj) =>
|
|
155
|
+
obj === UNDEFINED
|
|
156
|
+
? void 0
|
|
157
|
+
: isArray(obj)
|
|
158
|
+
? arrayMap(obj, replaceUndefinedString)
|
|
159
|
+
: isObject(obj)
|
|
160
|
+
? objMap(obj, replaceUndefinedString)
|
|
161
|
+
: obj;
|
|
162
|
+
|
|
163
|
+
const MESSAGE_SEPARATOR = '\n';
|
|
164
|
+
const FRAGMENT = /^(.+)\n(\d+)\n(\d+)\n([\s\S]*)$/;
|
|
165
|
+
const ifPayloadValid = (payload, then) => {
|
|
166
|
+
const splitAt = payload.indexOf(MESSAGE_SEPARATOR);
|
|
167
|
+
if (splitAt !== -1) {
|
|
168
|
+
then(slice(payload, 0, splitAt), slice(payload, splitAt + 1));
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
const receivePayloadRemainder = (fromClientId, remainder, receive) =>
|
|
172
|
+
receive(fromClientId, ...jsonParseWithUndefined(remainder));
|
|
173
|
+
const createPayloadReceiver = (receive, fragmentTimeoutSeconds = 1) => {
|
|
174
|
+
const buffer = mapNew();
|
|
175
|
+
const setPendingTimeout = (bufferKey) =>
|
|
176
|
+
startTimeout(() => collDel(buffer, bufferKey), fragmentTimeoutSeconds);
|
|
177
|
+
const delPending = (bufferKey, pending) => {
|
|
178
|
+
stopTimeout(pending[3]);
|
|
179
|
+
collDel(buffer, bufferKey);
|
|
180
|
+
};
|
|
181
|
+
return (payload) =>
|
|
182
|
+
ifPayloadValid(payload, (fromClientId, remainder) => {
|
|
183
|
+
const [, messageId, indexStr, totalStr, fragment] =
|
|
184
|
+
strMatch(remainder, FRAGMENT) ?? [];
|
|
185
|
+
if (messageId) {
|
|
186
|
+
const index = parseInt(indexStr);
|
|
187
|
+
const total = parseInt(totalStr);
|
|
188
|
+
if (total > 0 && index >= 0 && index < total) {
|
|
189
|
+
const bufferKey = fromClientId + MESSAGE_SEPARATOR + messageId;
|
|
190
|
+
const pending = mapEnsure(buffer, bufferKey, () => [
|
|
191
|
+
[],
|
|
192
|
+
total,
|
|
193
|
+
total,
|
|
194
|
+
setPendingTimeout(bufferKey),
|
|
195
|
+
]);
|
|
196
|
+
const [fragments] = pending;
|
|
197
|
+
if (total == pending[2] && isUndefined(fragments[index])) {
|
|
198
|
+
stopTimeout(pending[3]);
|
|
199
|
+
pending[3] = setPendingTimeout(bufferKey);
|
|
200
|
+
fragments[index] = fragment;
|
|
201
|
+
pending[1]--;
|
|
202
|
+
}
|
|
203
|
+
if (pending[1] == 0) {
|
|
204
|
+
delPending(bufferKey, pending);
|
|
205
|
+
receivePayloadRemainder(
|
|
206
|
+
fromClientId,
|
|
207
|
+
arrayJoin(fragments),
|
|
208
|
+
receive,
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
} else {
|
|
213
|
+
receivePayloadRemainder(fromClientId, remainder, receive);
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
};
|
|
217
|
+
const createPayload = (toClientId, ...args) =>
|
|
218
|
+
createRawPayload(toClientId, jsonStringWithUndefined(args));
|
|
219
|
+
const createRawPayload = (clientId, remainder) =>
|
|
220
|
+
clientId + MESSAGE_SEPARATOR + remainder;
|
|
221
|
+
const createPayloads = (toClientId, requestId, message, body, fragmentSize) => {
|
|
222
|
+
const clientId = toClientId ?? EMPTY_STRING;
|
|
223
|
+
const remainder = jsonStringWithUndefined([requestId, message, body]);
|
|
224
|
+
const maxFragmentSize = mathFloor(fragmentSize ?? 0);
|
|
225
|
+
if (
|
|
226
|
+
isUndefined(fragmentSize) ||
|
|
227
|
+
maxFragmentSize < 1 ||
|
|
228
|
+
size(remainder) <= maxFragmentSize
|
|
229
|
+
) {
|
|
230
|
+
return [createRawPayload(clientId, remainder)];
|
|
231
|
+
}
|
|
232
|
+
const fragments = strMatch(
|
|
233
|
+
remainder,
|
|
234
|
+
new RegExp(`.{1,${maxFragmentSize}}`, 'g'),
|
|
235
|
+
);
|
|
236
|
+
const total = size(fragments ?? []);
|
|
237
|
+
const messageId = getUniqueId();
|
|
238
|
+
return arrayMap(fragments ?? [], (fragment, index) =>
|
|
239
|
+
createRawPayload(
|
|
240
|
+
clientId,
|
|
241
|
+
arrayJoin([messageId, index, total, fragment], MESSAGE_SEPARATOR),
|
|
242
|
+
),
|
|
243
|
+
);
|
|
244
|
+
};
|
|
245
|
+
|
|
177
246
|
const stampNew = (value, hlc) => (hlc ? [value, hlc] : [value]);
|
|
178
247
|
const getLatestHlc = (hlc1, hlc2) =>
|
|
179
248
|
/* istanbul ignore next */
|
|
@@ -375,13 +444,13 @@ const createCustomPersister = (
|
|
|
375
444
|
const content = await getPersisted();
|
|
376
445
|
if (isArray(content)) {
|
|
377
446
|
setContentOrChanges(content);
|
|
378
|
-
} else if (initialContent) {
|
|
447
|
+
} else if (isUndefined(content) && initialContent) {
|
|
379
448
|
setDefaultContent(initialContent);
|
|
380
|
-
} else {
|
|
449
|
+
} else if (!isUndefined(content)) {
|
|
381
450
|
errorNew(`Content is not an array: ${content}`);
|
|
382
451
|
}
|
|
383
452
|
},
|
|
384
|
-
() => {
|
|
453
|
+
(error) => {
|
|
385
454
|
if (initialContent) {
|
|
386
455
|
setDefaultContent(initialContent);
|
|
387
456
|
}
|
|
@@ -759,18 +828,27 @@ class WsServerDurableObject extends DurableObject {
|
|
|
759
828
|
await ifNotUndefined(
|
|
760
829
|
await this.createPersister(),
|
|
761
830
|
async (persister) => {
|
|
831
|
+
const requestTimeoutSeconds = this.getRequestTimeoutSeconds();
|
|
762
832
|
const synchronizer = createCustomSynchronizer(
|
|
763
833
|
persister.getStore(),
|
|
764
834
|
(toClientId, requestId, message, body) =>
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
835
|
+
arrayForEach(
|
|
836
|
+
createPayloads(
|
|
837
|
+
toClientId,
|
|
838
|
+
requestId,
|
|
839
|
+
message,
|
|
840
|
+
body,
|
|
841
|
+
this.getFragmentSize(),
|
|
842
|
+
),
|
|
843
|
+
(payload) => this.#handleMessage(SERVER_CLIENT_ID, payload),
|
|
768
844
|
),
|
|
769
845
|
(receive) =>
|
|
770
|
-
(this.#serverClientSend = (
|
|
771
|
-
|
|
846
|
+
(this.#serverClientSend = createPayloadReceiver(
|
|
847
|
+
receive,
|
|
848
|
+
requestTimeoutSeconds,
|
|
849
|
+
)),
|
|
772
850
|
noop,
|
|
773
|
-
|
|
851
|
+
requestTimeoutSeconds,
|
|
774
852
|
);
|
|
775
853
|
await persister.load();
|
|
776
854
|
await persister.startAutoSave();
|
|
@@ -845,6 +923,12 @@ class WsServerDurableObject extends DurableObject {
|
|
|
845
923
|
(client) => this.ctx.getTags(client)[0],
|
|
846
924
|
);
|
|
847
925
|
}
|
|
926
|
+
getFragmentSize() {
|
|
927
|
+
return void 0;
|
|
928
|
+
}
|
|
929
|
+
getRequestTimeoutSeconds() {
|
|
930
|
+
return 1;
|
|
931
|
+
}
|
|
848
932
|
onPathId(_pathId, _addedOrRemoved) {}
|
|
849
933
|
onClientId(_pathId, _clientId, _addedOrRemoved) {}
|
|
850
934
|
onMessage(_fromClientId, _toClientId, _remainder) {}
|
|
@@ -18,6 +18,7 @@ const GLOBAL = globalThis;
|
|
|
18
18
|
const THOUSAND = 1e3;
|
|
19
19
|
const startTimeout = (callback, sec = 0) =>
|
|
20
20
|
setTimeout(callback, sec * THOUSAND);
|
|
21
|
+
const stopTimeout = clearTimeout;
|
|
21
22
|
const mathFloor = math.floor;
|
|
22
23
|
const mathRandom = math.random;
|
|
23
24
|
const isNullish = (thing) => thing == null;
|
|
@@ -44,6 +45,7 @@ const tryCatch = async (action, then1, then2) => {
|
|
|
44
45
|
};
|
|
45
46
|
|
|
46
47
|
const arrayForEach = (array, cb) => array.forEach(cb);
|
|
48
|
+
const arrayJoin = (array, sep = EMPTY_STRING) => array.join(sep);
|
|
47
49
|
const arrayMap = (array, cb) => array.map(cb);
|
|
48
50
|
const arrayIsEmpty = (array) => size(array) == 0;
|
|
49
51
|
const arrayReduce = (array, cb, initial) => array.reduce(cb, initial);
|
|
@@ -85,38 +87,6 @@ const objEnsure = (obj, id, getDefaultValue) => {
|
|
|
85
87
|
return obj[id];
|
|
86
88
|
};
|
|
87
89
|
|
|
88
|
-
const jsonString = JSON.stringify;
|
|
89
|
-
const jsonParse = JSON.parse;
|
|
90
|
-
const jsonStringWithUndefined = (obj) =>
|
|
91
|
-
jsonString(obj, (_key, value) => (isUndefined(value) ? UNDEFINED : value));
|
|
92
|
-
const jsonParseWithUndefined = (str) =>
|
|
93
|
-
// JSON.parse reviver removes properties with undefined values
|
|
94
|
-
replaceUndefinedString(jsonParse(str));
|
|
95
|
-
const replaceUndefinedString = (obj) =>
|
|
96
|
-
obj === UNDEFINED
|
|
97
|
-
? void 0
|
|
98
|
-
: isArray(obj)
|
|
99
|
-
? arrayMap(obj, replaceUndefinedString)
|
|
100
|
-
: isObject(obj)
|
|
101
|
-
? objMap(obj, replaceUndefinedString)
|
|
102
|
-
: obj;
|
|
103
|
-
|
|
104
|
-
const MESSAGE_SEPARATOR = '\n';
|
|
105
|
-
const ifPayloadValid = (payload, then) => {
|
|
106
|
-
const splitAt = payload.indexOf(MESSAGE_SEPARATOR);
|
|
107
|
-
if (splitAt !== -1) {
|
|
108
|
-
then(slice(payload, 0, splitAt), slice(payload, splitAt + 1));
|
|
109
|
-
}
|
|
110
|
-
};
|
|
111
|
-
const receivePayload = (payload, receive) =>
|
|
112
|
-
ifPayloadValid(payload, (fromClientId, remainder) =>
|
|
113
|
-
receive(fromClientId, ...jsonParseWithUndefined(remainder)),
|
|
114
|
-
);
|
|
115
|
-
const createPayload = (toClientId, ...args) =>
|
|
116
|
-
createRawPayload(toClientId ?? EMPTY_STRING, jsonStringWithUndefined(args));
|
|
117
|
-
const createRawPayload = (clientId, remainder) =>
|
|
118
|
-
clientId + MESSAGE_SEPARATOR + remainder;
|
|
119
|
-
|
|
120
90
|
const collSize = (coll) => coll?.size ?? 0;
|
|
121
91
|
const collHas = (coll, keyOrValue) => coll?.has(keyOrValue) ?? false;
|
|
122
92
|
const collIsEmpty = (coll) => isUndefined(coll) || collSize(coll) == 0;
|
|
@@ -174,6 +144,105 @@ const getUniqueId = (length = 16) =>
|
|
|
174
144
|
EMPTY_STRING,
|
|
175
145
|
);
|
|
176
146
|
|
|
147
|
+
const jsonString = JSON.stringify;
|
|
148
|
+
const jsonParse = JSON.parse;
|
|
149
|
+
const jsonStringWithUndefined = (obj) =>
|
|
150
|
+
jsonString(obj, (_key, value) => (isUndefined(value) ? UNDEFINED : value));
|
|
151
|
+
const jsonParseWithUndefined = (str) =>
|
|
152
|
+
// JSON.parse reviver removes properties with undefined values
|
|
153
|
+
replaceUndefinedString(jsonParse(str));
|
|
154
|
+
const replaceUndefinedString = (obj) =>
|
|
155
|
+
obj === UNDEFINED
|
|
156
|
+
? void 0
|
|
157
|
+
: isArray(obj)
|
|
158
|
+
? arrayMap(obj, replaceUndefinedString)
|
|
159
|
+
: isObject(obj)
|
|
160
|
+
? objMap(obj, replaceUndefinedString)
|
|
161
|
+
: obj;
|
|
162
|
+
|
|
163
|
+
const MESSAGE_SEPARATOR = '\n';
|
|
164
|
+
const FRAGMENT = /^(.+)\n(\d+)\n(\d+)\n([\s\S]*)$/;
|
|
165
|
+
const ifPayloadValid = (payload, then) => {
|
|
166
|
+
const splitAt = payload.indexOf(MESSAGE_SEPARATOR);
|
|
167
|
+
if (splitAt !== -1) {
|
|
168
|
+
then(slice(payload, 0, splitAt), slice(payload, splitAt + 1));
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
const receivePayloadRemainder = (fromClientId, remainder, receive) =>
|
|
172
|
+
receive(fromClientId, ...jsonParseWithUndefined(remainder));
|
|
173
|
+
const createPayloadReceiver = (receive, fragmentTimeoutSeconds = 1) => {
|
|
174
|
+
const buffer = mapNew();
|
|
175
|
+
const setPendingTimeout = (bufferKey) =>
|
|
176
|
+
startTimeout(() => collDel(buffer, bufferKey), fragmentTimeoutSeconds);
|
|
177
|
+
const delPending = (bufferKey, pending) => {
|
|
178
|
+
stopTimeout(pending[3]);
|
|
179
|
+
collDel(buffer, bufferKey);
|
|
180
|
+
};
|
|
181
|
+
return (payload) =>
|
|
182
|
+
ifPayloadValid(payload, (fromClientId, remainder) => {
|
|
183
|
+
const [, messageId, indexStr, totalStr, fragment] =
|
|
184
|
+
strMatch(remainder, FRAGMENT) ?? [];
|
|
185
|
+
if (messageId) {
|
|
186
|
+
const index = parseInt(indexStr);
|
|
187
|
+
const total = parseInt(totalStr);
|
|
188
|
+
if (total > 0 && index >= 0 && index < total) {
|
|
189
|
+
const bufferKey = fromClientId + MESSAGE_SEPARATOR + messageId;
|
|
190
|
+
const pending = mapEnsure(buffer, bufferKey, () => [
|
|
191
|
+
[],
|
|
192
|
+
total,
|
|
193
|
+
total,
|
|
194
|
+
setPendingTimeout(bufferKey),
|
|
195
|
+
]);
|
|
196
|
+
const [fragments] = pending;
|
|
197
|
+
if (total == pending[2] && isUndefined(fragments[index])) {
|
|
198
|
+
stopTimeout(pending[3]);
|
|
199
|
+
pending[3] = setPendingTimeout(bufferKey);
|
|
200
|
+
fragments[index] = fragment;
|
|
201
|
+
pending[1]--;
|
|
202
|
+
}
|
|
203
|
+
if (pending[1] == 0) {
|
|
204
|
+
delPending(bufferKey, pending);
|
|
205
|
+
receivePayloadRemainder(
|
|
206
|
+
fromClientId,
|
|
207
|
+
arrayJoin(fragments),
|
|
208
|
+
receive,
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
} else {
|
|
213
|
+
receivePayloadRemainder(fromClientId, remainder, receive);
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
};
|
|
217
|
+
const createPayload = (toClientId, ...args) =>
|
|
218
|
+
createRawPayload(toClientId, jsonStringWithUndefined(args));
|
|
219
|
+
const createRawPayload = (clientId, remainder) =>
|
|
220
|
+
clientId + MESSAGE_SEPARATOR + remainder;
|
|
221
|
+
const createPayloads = (toClientId, requestId, message, body, fragmentSize) => {
|
|
222
|
+
const clientId = toClientId ?? EMPTY_STRING;
|
|
223
|
+
const remainder = jsonStringWithUndefined([requestId, message, body]);
|
|
224
|
+
const maxFragmentSize = mathFloor(fragmentSize ?? 0);
|
|
225
|
+
if (
|
|
226
|
+
isUndefined(fragmentSize) ||
|
|
227
|
+
maxFragmentSize < 1 ||
|
|
228
|
+
size(remainder) <= maxFragmentSize
|
|
229
|
+
) {
|
|
230
|
+
return [createRawPayload(clientId, remainder)];
|
|
231
|
+
}
|
|
232
|
+
const fragments = strMatch(
|
|
233
|
+
remainder,
|
|
234
|
+
new RegExp(`.{1,${maxFragmentSize}}`, 'g'),
|
|
235
|
+
);
|
|
236
|
+
const total = size(fragments ?? []);
|
|
237
|
+
const messageId = getUniqueId();
|
|
238
|
+
return arrayMap(fragments ?? [], (fragment, index) =>
|
|
239
|
+
createRawPayload(
|
|
240
|
+
clientId,
|
|
241
|
+
arrayJoin([messageId, index, total, fragment], MESSAGE_SEPARATOR),
|
|
242
|
+
),
|
|
243
|
+
);
|
|
244
|
+
};
|
|
245
|
+
|
|
177
246
|
const stampNew = (value, hlc) => (hlc ? [value, hlc] : [value]);
|
|
178
247
|
const getLatestHlc = (hlc1, hlc2) =>
|
|
179
248
|
/* istanbul ignore next */
|
|
@@ -375,13 +444,13 @@ const createCustomPersister = (
|
|
|
375
444
|
const content = await getPersisted();
|
|
376
445
|
if (isArray(content)) {
|
|
377
446
|
setContentOrChanges(content);
|
|
378
|
-
} else if (initialContent) {
|
|
447
|
+
} else if (isUndefined(content) && initialContent) {
|
|
379
448
|
setDefaultContent(initialContent);
|
|
380
|
-
} else {
|
|
449
|
+
} else if (!isUndefined(content)) {
|
|
381
450
|
errorNew(`Content is not an array: ${content}`);
|
|
382
451
|
}
|
|
383
452
|
},
|
|
384
|
-
() => {
|
|
453
|
+
(error) => {
|
|
385
454
|
if (initialContent) {
|
|
386
455
|
setDefaultContent(initialContent);
|
|
387
456
|
}
|
|
@@ -759,18 +828,27 @@ class WsServerDurableObject extends DurableObject {
|
|
|
759
828
|
await ifNotUndefined(
|
|
760
829
|
await this.createPersister(),
|
|
761
830
|
async (persister) => {
|
|
831
|
+
const requestTimeoutSeconds = this.getRequestTimeoutSeconds();
|
|
762
832
|
const synchronizer = createCustomSynchronizer(
|
|
763
833
|
persister.getStore(),
|
|
764
834
|
(toClientId, requestId, message, body) =>
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
835
|
+
arrayForEach(
|
|
836
|
+
createPayloads(
|
|
837
|
+
toClientId,
|
|
838
|
+
requestId,
|
|
839
|
+
message,
|
|
840
|
+
body,
|
|
841
|
+
this.getFragmentSize(),
|
|
842
|
+
),
|
|
843
|
+
(payload) => this.#handleMessage(SERVER_CLIENT_ID, payload),
|
|
768
844
|
),
|
|
769
845
|
(receive) =>
|
|
770
|
-
(this.#serverClientSend = (
|
|
771
|
-
|
|
846
|
+
(this.#serverClientSend = createPayloadReceiver(
|
|
847
|
+
receive,
|
|
848
|
+
requestTimeoutSeconds,
|
|
849
|
+
)),
|
|
772
850
|
noop,
|
|
773
|
-
|
|
851
|
+
requestTimeoutSeconds,
|
|
774
852
|
);
|
|
775
853
|
await persister.load();
|
|
776
854
|
await persister.startAutoSave();
|
|
@@ -845,6 +923,12 @@ class WsServerDurableObject extends DurableObject {
|
|
|
845
923
|
(client) => this.ctx.getTags(client)[0],
|
|
846
924
|
);
|
|
847
925
|
}
|
|
926
|
+
getFragmentSize() {
|
|
927
|
+
return void 0;
|
|
928
|
+
}
|
|
929
|
+
getRequestTimeoutSeconds() {
|
|
930
|
+
return 1;
|
|
931
|
+
}
|
|
848
932
|
onPathId(_pathId, _addedOrRemoved) {}
|
|
849
933
|
onClientId(_pathId, _clientId, _addedOrRemoved) {}
|
|
850
934
|
onMessage(_fromClientId, _toClientId, _remainder) {}
|
|
@@ -331,13 +331,14 @@ const createCustomPersister = (
|
|
|
331
331
|
const content = await getPersisted();
|
|
332
332
|
if (isArray(content)) {
|
|
333
333
|
setContentOrChanges(content);
|
|
334
|
-
} else if (initialContent) {
|
|
334
|
+
} else if (isUndefined(content) && initialContent) {
|
|
335
335
|
setDefaultContent(initialContent);
|
|
336
|
-
} else {
|
|
336
|
+
} else if (!isUndefined(content)) {
|
|
337
337
|
errorNew(`Content is not an array: ${content}`);
|
|
338
338
|
}
|
|
339
339
|
},
|
|
340
|
-
() => {
|
|
340
|
+
(error) => {
|
|
341
|
+
onIgnoredError?.(error);
|
|
341
342
|
if (initialContent) {
|
|
342
343
|
setDefaultContent(initialContent);
|
|
343
344
|
}
|
|
@@ -930,13 +930,13 @@ const createCustomPersister = (
|
|
|
930
930
|
const content = await getPersisted();
|
|
931
931
|
if (isArray(content)) {
|
|
932
932
|
setContentOrChanges(content);
|
|
933
|
-
} else if (initialContent) {
|
|
933
|
+
} else if (isUndefined(content) && initialContent) {
|
|
934
934
|
setDefaultContent(initialContent);
|
|
935
|
-
} else {
|
|
935
|
+
} else if (!isUndefined(content)) {
|
|
936
936
|
errorNew(`Content is not an array: ${content}`);
|
|
937
937
|
}
|
|
938
938
|
},
|
|
939
|
-
() => {
|
|
939
|
+
(error) => {
|
|
940
940
|
if (initialContent) {
|
|
941
941
|
setDefaultContent(initialContent);
|
|
942
942
|
}
|
|
@@ -1189,8 +1189,10 @@ const createStore = () => {
|
|
|
1189
1189
|
const changedRowIds = mapNew();
|
|
1190
1190
|
const changedCellIds = mapNew();
|
|
1191
1191
|
const changedCells = mapNew();
|
|
1192
|
+
const defaultedCells = mapNew();
|
|
1192
1193
|
const changedValueIds = mapNew();
|
|
1193
1194
|
const changedValues = mapNew();
|
|
1195
|
+
const defaultedValues = setNew();
|
|
1194
1196
|
const invalidCells = mapNew();
|
|
1195
1197
|
const invalidValues = mapNew();
|
|
1196
1198
|
const tablesSchemaMap = mapNew();
|
|
@@ -1364,6 +1366,16 @@ const createStore = () => {
|
|
|
1364
1366
|
collForEach(rowDefaulted, (cell, cellId) => {
|
|
1365
1367
|
if (!objHas(row, cellId)) {
|
|
1366
1368
|
row[cellId] = cell;
|
|
1369
|
+
ifNotUndefined(rowId, (rowId2) =>
|
|
1370
|
+
setAdd(
|
|
1371
|
+
mapEnsure(
|
|
1372
|
+
mapEnsure(defaultedCells, tableId, mapNew),
|
|
1373
|
+
rowId2,
|
|
1374
|
+
setNew,
|
|
1375
|
+
),
|
|
1376
|
+
cellId,
|
|
1377
|
+
),
|
|
1378
|
+
);
|
|
1367
1379
|
}
|
|
1368
1380
|
});
|
|
1369
1381
|
collForEach(rowNonDefaulted, (cellId) => {
|
|
@@ -1380,6 +1392,7 @@ const createStore = () => {
|
|
|
1380
1392
|
collForEach(valuesDefaulted, (value, valueId) => {
|
|
1381
1393
|
if (!objHas(values, valueId)) {
|
|
1382
1394
|
values[valueId] = value;
|
|
1395
|
+
setAdd(defaultedValues, valueId);
|
|
1383
1396
|
}
|
|
1384
1397
|
});
|
|
1385
1398
|
collForEach(valuesNonDefaulted, (valueId) => {
|
|
@@ -1783,18 +1796,34 @@ const createStore = () => {
|
|
|
1783
1796
|
);
|
|
1784
1797
|
};
|
|
1785
1798
|
const cellChanged = (tableId, rowId, cellId, oldCell, newCell) => {
|
|
1799
|
+
const defaulted =
|
|
1800
|
+
collHas(mapGet(mapGet(defaultedCells, tableId), rowId), cellId) &&
|
|
1801
|
+
isUndefined(oldCell)
|
|
1802
|
+
? 1
|
|
1803
|
+
: 0;
|
|
1786
1804
|
mapEnsure(
|
|
1787
1805
|
mapEnsure(mapEnsure(changedCells, tableId, mapNew), rowId, mapNew),
|
|
1788
1806
|
cellId,
|
|
1789
1807
|
() => [oldCell, 0],
|
|
1790
1808
|
)[1] = newCell;
|
|
1791
|
-
internalListeners[3]?.(
|
|
1809
|
+
internalListeners[3]?.(
|
|
1810
|
+
tableId,
|
|
1811
|
+
rowId,
|
|
1812
|
+
cellId,
|
|
1813
|
+
newCell,
|
|
1814
|
+
mutating,
|
|
1815
|
+
defaulted,
|
|
1816
|
+
);
|
|
1817
|
+
collDel(mapGet(mapGet(defaultedCells, tableId), rowId), cellId);
|
|
1792
1818
|
};
|
|
1793
1819
|
const valueIdsChanged = (valueId, addedOrRemoved) =>
|
|
1794
1820
|
idsChanged(changedValueIds, valueId, addedOrRemoved);
|
|
1795
1821
|
const valueChanged = (valueId, oldValue, newValue) => {
|
|
1822
|
+
const defaulted =
|
|
1823
|
+
collHas(defaultedValues, valueId) && isUndefined(oldValue) ? 1 : 0;
|
|
1796
1824
|
mapEnsure(changedValues, valueId, () => [oldValue, 0])[1] = newValue;
|
|
1797
|
-
internalListeners[4]?.(valueId, newValue, mutating);
|
|
1825
|
+
internalListeners[4]?.(valueId, newValue, mutating, defaulted);
|
|
1826
|
+
collDel(defaultedValues, valueId);
|
|
1798
1827
|
};
|
|
1799
1828
|
const cellInvalid = (tableId, rowId, cellId, invalidCell, defaultedCell) => {
|
|
1800
1829
|
arrayPush(
|
|
@@ -2582,9 +2611,11 @@ const createStore = () => {
|
|
|
2582
2611
|
changedRowIds,
|
|
2583
2612
|
changedCellIds,
|
|
2584
2613
|
changedCells,
|
|
2614
|
+
defaultedCells,
|
|
2585
2615
|
invalidCells,
|
|
2586
2616
|
changedValueIds,
|
|
2587
2617
|
changedValues,
|
|
2618
|
+
defaultedValues,
|
|
2588
2619
|
invalidValues,
|
|
2589
2620
|
],
|
|
2590
2621
|
collClear,
|
|
@@ -930,13 +930,13 @@ const createCustomPersister = (
|
|
|
930
930
|
const content = await getPersisted();
|
|
931
931
|
if (isArray(content)) {
|
|
932
932
|
setContentOrChanges(content);
|
|
933
|
-
} else if (initialContent) {
|
|
933
|
+
} else if (isUndefined(content) && initialContent) {
|
|
934
934
|
setDefaultContent(initialContent);
|
|
935
|
-
} else {
|
|
935
|
+
} else if (!isUndefined(content)) {
|
|
936
936
|
errorNew(`Content is not an array: ${content}`);
|
|
937
937
|
}
|
|
938
938
|
},
|
|
939
|
-
() => {
|
|
939
|
+
(error) => {
|
|
940
940
|
if (initialContent) {
|
|
941
941
|
setDefaultContent(initialContent);
|
|
942
942
|
}
|
|
@@ -1189,8 +1189,10 @@ const createStore = () => {
|
|
|
1189
1189
|
const changedRowIds = mapNew();
|
|
1190
1190
|
const changedCellIds = mapNew();
|
|
1191
1191
|
const changedCells = mapNew();
|
|
1192
|
+
const defaultedCells = mapNew();
|
|
1192
1193
|
const changedValueIds = mapNew();
|
|
1193
1194
|
const changedValues = mapNew();
|
|
1195
|
+
const defaultedValues = setNew();
|
|
1194
1196
|
const invalidCells = mapNew();
|
|
1195
1197
|
const invalidValues = mapNew();
|
|
1196
1198
|
const tablesSchemaMap = mapNew();
|
|
@@ -1364,6 +1366,16 @@ const createStore = () => {
|
|
|
1364
1366
|
collForEach(rowDefaulted, (cell, cellId) => {
|
|
1365
1367
|
if (!objHas(row, cellId)) {
|
|
1366
1368
|
row[cellId] = cell;
|
|
1369
|
+
ifNotUndefined(rowId, (rowId2) =>
|
|
1370
|
+
setAdd(
|
|
1371
|
+
mapEnsure(
|
|
1372
|
+
mapEnsure(defaultedCells, tableId, mapNew),
|
|
1373
|
+
rowId2,
|
|
1374
|
+
setNew,
|
|
1375
|
+
),
|
|
1376
|
+
cellId,
|
|
1377
|
+
),
|
|
1378
|
+
);
|
|
1367
1379
|
}
|
|
1368
1380
|
});
|
|
1369
1381
|
collForEach(rowNonDefaulted, (cellId) => {
|
|
@@ -1380,6 +1392,7 @@ const createStore = () => {
|
|
|
1380
1392
|
collForEach(valuesDefaulted, (value, valueId) => {
|
|
1381
1393
|
if (!objHas(values, valueId)) {
|
|
1382
1394
|
values[valueId] = value;
|
|
1395
|
+
setAdd(defaultedValues, valueId);
|
|
1383
1396
|
}
|
|
1384
1397
|
});
|
|
1385
1398
|
collForEach(valuesNonDefaulted, (valueId) => {
|
|
@@ -1783,18 +1796,34 @@ const createStore = () => {
|
|
|
1783
1796
|
);
|
|
1784
1797
|
};
|
|
1785
1798
|
const cellChanged = (tableId, rowId, cellId, oldCell, newCell) => {
|
|
1799
|
+
const defaulted =
|
|
1800
|
+
collHas(mapGet(mapGet(defaultedCells, tableId), rowId), cellId) &&
|
|
1801
|
+
isUndefined(oldCell)
|
|
1802
|
+
? 1
|
|
1803
|
+
: 0;
|
|
1786
1804
|
mapEnsure(
|
|
1787
1805
|
mapEnsure(mapEnsure(changedCells, tableId, mapNew), rowId, mapNew),
|
|
1788
1806
|
cellId,
|
|
1789
1807
|
() => [oldCell, 0],
|
|
1790
1808
|
)[1] = newCell;
|
|
1791
|
-
internalListeners[3]?.(
|
|
1809
|
+
internalListeners[3]?.(
|
|
1810
|
+
tableId,
|
|
1811
|
+
rowId,
|
|
1812
|
+
cellId,
|
|
1813
|
+
newCell,
|
|
1814
|
+
mutating,
|
|
1815
|
+
defaulted,
|
|
1816
|
+
);
|
|
1817
|
+
collDel(mapGet(mapGet(defaultedCells, tableId), rowId), cellId);
|
|
1792
1818
|
};
|
|
1793
1819
|
const valueIdsChanged = (valueId, addedOrRemoved) =>
|
|
1794
1820
|
idsChanged(changedValueIds, valueId, addedOrRemoved);
|
|
1795
1821
|
const valueChanged = (valueId, oldValue, newValue) => {
|
|
1822
|
+
const defaulted =
|
|
1823
|
+
collHas(defaultedValues, valueId) && isUndefined(oldValue) ? 1 : 0;
|
|
1796
1824
|
mapEnsure(changedValues, valueId, () => [oldValue, 0])[1] = newValue;
|
|
1797
|
-
internalListeners[4]?.(valueId, newValue, mutating);
|
|
1825
|
+
internalListeners[4]?.(valueId, newValue, mutating, defaulted);
|
|
1826
|
+
collDel(defaultedValues, valueId);
|
|
1798
1827
|
};
|
|
1799
1828
|
const cellInvalid = (tableId, rowId, cellId, invalidCell, defaultedCell) => {
|
|
1800
1829
|
arrayPush(
|
|
@@ -2582,9 +2611,11 @@ const createStore = () => {
|
|
|
2582
2611
|
changedRowIds,
|
|
2583
2612
|
changedCellIds,
|
|
2584
2613
|
changedCells,
|
|
2614
|
+
defaultedCells,
|
|
2585
2615
|
invalidCells,
|
|
2586
2616
|
changedValueIds,
|
|
2587
2617
|
changedValues,
|
|
2618
|
+
defaultedValues,
|
|
2588
2619
|
invalidValues,
|
|
2589
2620
|
],
|
|
2590
2621
|
collClear,
|