tinybase 4.2.3 → 4.3.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/lib/cjs/persisters/persister-cr-sqlite-wasm.cjs +1 -1
- package/lib/cjs/persisters/persister-cr-sqlite-wasm.cjs.gz +0 -0
- package/lib/cjs/persisters/persister-expo-sqlite.cjs +1 -1
- package/lib/cjs/persisters/persister-expo-sqlite.cjs.gz +0 -0
- package/lib/cjs/persisters/persister-partykit-client.cjs +1 -0
- package/lib/cjs/persisters/persister-partykit-client.cjs.gz +0 -0
- package/lib/cjs/persisters/persister-partykit-server.cjs +1 -0
- package/lib/cjs/persisters/persister-partykit-server.cjs.gz +0 -0
- package/lib/cjs/persisters/persister-sqlite-wasm.cjs +1 -1
- package/lib/cjs/persisters/persister-sqlite-wasm.cjs.gz +0 -0
- package/lib/cjs/persisters/persister-sqlite3.cjs +1 -1
- package/lib/cjs/persisters/persister-sqlite3.cjs.gz +0 -0
- package/lib/cjs/store.cjs +1 -1
- package/lib/cjs/store.cjs.gz +0 -0
- package/lib/cjs/tinybase.cjs +1 -1
- package/lib/cjs/tinybase.cjs.gz +0 -0
- package/lib/cjs/tools.cjs +1 -1
- package/lib/cjs/tools.cjs.gz +0 -0
- package/lib/cjs/ui-react-dom-debug.cjs +1 -1
- package/lib/cjs/ui-react-dom-debug.cjs.gz +0 -0
- package/lib/cjs/ui-react.cjs +1 -1
- package/lib/cjs/ui-react.cjs.gz +0 -0
- package/lib/cjs-es6/persisters/persister-cr-sqlite-wasm.cjs +1 -1
- package/lib/cjs-es6/persisters/persister-cr-sqlite-wasm.cjs.gz +0 -0
- package/lib/cjs-es6/persisters/persister-expo-sqlite.cjs +1 -1
- package/lib/cjs-es6/persisters/persister-expo-sqlite.cjs.gz +0 -0
- package/lib/cjs-es6/persisters/persister-partykit-client.cjs +1 -0
- package/lib/cjs-es6/persisters/persister-partykit-client.cjs.gz +0 -0
- package/lib/cjs-es6/persisters/persister-partykit-server.cjs +1 -0
- package/lib/cjs-es6/persisters/persister-partykit-server.cjs.gz +0 -0
- package/lib/cjs-es6/persisters/persister-sqlite-wasm.cjs +1 -1
- package/lib/cjs-es6/persisters/persister-sqlite-wasm.cjs.gz +0 -0
- package/lib/cjs-es6/persisters/persister-sqlite3.cjs +1 -1
- package/lib/cjs-es6/persisters/persister-sqlite3.cjs.gz +0 -0
- package/lib/cjs-es6/store.cjs +1 -1
- package/lib/cjs-es6/store.cjs.gz +0 -0
- package/lib/cjs-es6/tinybase.cjs +1 -1
- package/lib/cjs-es6/tinybase.cjs.gz +0 -0
- package/lib/cjs-es6/tools.cjs +1 -1
- package/lib/cjs-es6/tools.cjs.gz +0 -0
- package/lib/cjs-es6/ui-react-dom-debug.cjs +1 -1
- package/lib/cjs-es6/ui-react-dom-debug.cjs.gz +0 -0
- package/lib/cjs-es6/ui-react.cjs +1 -1
- package/lib/cjs-es6/ui-react.cjs.gz +0 -0
- package/lib/debug/persisters/persister-cr-sqlite-wasm.js +10 -7
- package/lib/debug/persisters/persister-expo-sqlite.js +10 -7
- package/lib/debug/persisters/persister-partykit-client.js +249 -0
- package/lib/debug/persisters/persister-partykit-server.js +161 -0
- package/lib/debug/persisters/persister-sqlite-wasm.js +10 -7
- package/lib/debug/persisters/persister-sqlite3.js +10 -7
- package/lib/debug/queries.js +2 -2
- package/lib/debug/store.js +3 -3
- package/lib/debug/tinybase.js +4 -4
- package/lib/debug/tools.js +3 -4
- package/lib/debug/ui-react-dom.js +3 -3
- package/lib/debug/ui-react.js +1 -1
- package/lib/es6/persisters/persister-cr-sqlite-wasm.js +1 -1
- package/lib/es6/persisters/persister-cr-sqlite-wasm.js.gz +0 -0
- package/lib/es6/persisters/persister-expo-sqlite.js +1 -1
- package/lib/es6/persisters/persister-expo-sqlite.js.gz +0 -0
- package/lib/es6/persisters/persister-partykit-client.js +1 -0
- package/lib/es6/persisters/persister-partykit-client.js.gz +0 -0
- package/lib/es6/persisters/persister-partykit-server.js +1 -0
- package/lib/es6/persisters/persister-partykit-server.js.gz +0 -0
- package/lib/es6/persisters/persister-sqlite-wasm.js +1 -1
- package/lib/es6/persisters/persister-sqlite-wasm.js.gz +0 -0
- package/lib/es6/persisters/persister-sqlite3.js +1 -1
- package/lib/es6/persisters/persister-sqlite3.js.gz +0 -0
- package/lib/es6/store.js +1 -1
- package/lib/es6/store.js.gz +0 -0
- package/lib/es6/tinybase.js +1 -1
- package/lib/es6/tinybase.js.gz +0 -0
- package/lib/es6/tools.js +1 -1
- package/lib/es6/tools.js.gz +0 -0
- package/lib/es6/ui-react-dom-debug.js +1 -1
- package/lib/es6/ui-react-dom-debug.js.gz +0 -0
- package/lib/es6/ui-react.js +1 -1
- package/lib/es6/ui-react.js.gz +0 -0
- package/lib/persisters/persister-cr-sqlite-wasm.js +1 -1
- package/lib/persisters/persister-cr-sqlite-wasm.js.gz +0 -0
- package/lib/persisters/persister-expo-sqlite.js +1 -1
- package/lib/persisters/persister-expo-sqlite.js.gz +0 -0
- package/lib/persisters/persister-partykit-client.js +1 -0
- package/lib/persisters/persister-partykit-client.js.gz +0 -0
- package/lib/persisters/persister-partykit-server.js +1 -0
- package/lib/persisters/persister-partykit-server.js.gz +0 -0
- package/lib/persisters/persister-sqlite-wasm.js +1 -1
- package/lib/persisters/persister-sqlite-wasm.js.gz +0 -0
- package/lib/persisters/persister-sqlite3.js +1 -1
- package/lib/persisters/persister-sqlite3.js.gz +0 -0
- package/lib/store.js +1 -1
- package/lib/store.js.gz +0 -0
- package/lib/tinybase.js +1 -1
- package/lib/tinybase.js.gz +0 -0
- package/lib/tools.js +1 -1
- package/lib/tools.js.gz +0 -0
- package/lib/types/persisters/persister-cr-sqlite-wasm.d.ts +2 -0
- package/lib/types/persisters/persister-expo-sqlite.d.ts +2 -0
- package/lib/types/persisters/persister-partykit-client.d.ts +87 -0
- package/lib/types/persisters/persister-partykit-server.d.ts +113 -0
- package/lib/types/persisters/persister-sqlite-wasm.d.ts +2 -0
- package/lib/types/persisters/persister-sqlite3.d.ts +2 -0
- package/lib/types/ui-react.d.ts +12 -4
- package/lib/types/with-schemas/persisters/persister-cr-sqlite-wasm.d.ts +2 -0
- package/lib/types/with-schemas/persisters/persister-expo-sqlite.d.ts +2 -0
- package/lib/types/with-schemas/persisters/persister-partykit-client.d.ts +98 -0
- package/lib/types/with-schemas/persisters/persister-partykit-server.d.ts +113 -0
- package/lib/types/with-schemas/persisters/persister-sqlite-wasm.d.ts +2 -0
- package/lib/types/with-schemas/persisters/persister-sqlite3.d.ts +2 -0
- package/lib/types/with-schemas/ui-react.d.ts +18 -8
- package/lib/ui-react.js +1 -1
- package/lib/ui-react.js.gz +0 -0
- package/lib/umd/persisters/persister-cr-sqlite-wasm.js +1 -1
- package/lib/umd/persisters/persister-cr-sqlite-wasm.js.gz +0 -0
- package/lib/umd/persisters/persister-expo-sqlite.js +1 -1
- package/lib/umd/persisters/persister-expo-sqlite.js.gz +0 -0
- package/lib/umd/persisters/persister-partykit-client.js +1 -0
- package/lib/umd/persisters/persister-partykit-client.js.gz +0 -0
- package/lib/umd/persisters/persister-partykit-server.js +1 -0
- package/lib/umd/persisters/persister-partykit-server.js.gz +0 -0
- package/lib/umd/persisters/persister-sqlite-wasm.js +1 -1
- package/lib/umd/persisters/persister-sqlite-wasm.js.gz +0 -0
- package/lib/umd/persisters/persister-sqlite3.js +1 -1
- package/lib/umd/persisters/persister-sqlite3.js.gz +0 -0
- package/lib/umd/store.js +1 -1
- package/lib/umd/store.js.gz +0 -0
- package/lib/umd/tinybase.js +1 -1
- package/lib/umd/tinybase.js.gz +0 -0
- package/lib/umd/tools.js +1 -1
- package/lib/umd/tools.js.gz +0 -0
- package/lib/umd/ui-react-dom-debug.js +1 -1
- package/lib/umd/ui-react-dom-debug.js.gz +0 -0
- package/lib/umd/ui-react.js +1 -1
- package/lib/umd/ui-react.js.gz +0 -0
- package/lib/umd-es6/persisters/persister-cr-sqlite-wasm.js +1 -1
- package/lib/umd-es6/persisters/persister-cr-sqlite-wasm.js.gz +0 -0
- package/lib/umd-es6/persisters/persister-expo-sqlite.js +1 -1
- package/lib/umd-es6/persisters/persister-expo-sqlite.js.gz +0 -0
- package/lib/umd-es6/persisters/persister-partykit-client.js +1 -0
- package/lib/umd-es6/persisters/persister-partykit-client.js.gz +0 -0
- package/lib/umd-es6/persisters/persister-partykit-server.js +1 -0
- package/lib/umd-es6/persisters/persister-partykit-server.js.gz +0 -0
- package/lib/umd-es6/persisters/persister-sqlite-wasm.js +1 -1
- package/lib/umd-es6/persisters/persister-sqlite-wasm.js.gz +0 -0
- package/lib/umd-es6/persisters/persister-sqlite3.js +1 -1
- package/lib/umd-es6/persisters/persister-sqlite3.js.gz +0 -0
- package/lib/umd-es6/store.js +1 -1
- package/lib/umd-es6/store.js.gz +0 -0
- package/lib/umd-es6/tinybase.js +1 -1
- package/lib/umd-es6/tinybase.js.gz +0 -0
- package/lib/umd-es6/tools.js +1 -1
- package/lib/umd-es6/tools.js.gz +0 -0
- package/lib/umd-es6/ui-react-dom-debug.js +1 -1
- package/lib/umd-es6/ui-react-dom-debug.js.gz +0 -0
- package/lib/umd-es6/ui-react.js +1 -1
- package/lib/umd-es6/ui-react.js.gz +0 -0
- package/package.json +23 -13
- package/readme.md +13 -13
|
@@ -14,6 +14,7 @@ const ifNotUndefined = (value, then, otherwise) =>
|
|
|
14
14
|
isUndefined(value) ? otherwise?.() : then(value);
|
|
15
15
|
const isString = (thing) => getTypeOf(thing) == STRING;
|
|
16
16
|
const isArray = (thing) => Array.isArray(thing);
|
|
17
|
+
const slice = (arrayOrString, start, end) => arrayOrString.slice(start, end);
|
|
17
18
|
const promiseAll = async (promises) => promise.all(promises);
|
|
18
19
|
|
|
19
20
|
const arrayJoin = (array, sep = EMPTY_STRING) => array.join(sep);
|
|
@@ -21,7 +22,6 @@ const arrayMap = (array, cb) => array.map(cb);
|
|
|
21
22
|
const arrayLength = (array) => array.length;
|
|
22
23
|
const arrayIsEmpty = (array) => arrayLength(array) == 0;
|
|
23
24
|
const arrayFilter = (array, cb) => array.filter(cb);
|
|
24
|
-
const arraySlice = (array, start, end) => array.slice(start, end);
|
|
25
25
|
const arrayPush = (array, ...values) => array.push(...values);
|
|
26
26
|
const arrayShift = (array) => array.shift();
|
|
27
27
|
|
|
@@ -315,10 +315,13 @@ const upsert = async (
|
|
|
315
315
|
),
|
|
316
316
|
) +
|
|
317
317
|
')VALUES' +
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
318
|
+
slice(
|
|
319
|
+
strRepeat(
|
|
320
|
+
`,(?${strRepeat(',?', arrayLength(changingColumnNames))})`,
|
|
321
|
+
arrayLength(args) / (arrayLength(changingColumnNames) + 1),
|
|
322
|
+
),
|
|
323
|
+
1,
|
|
324
|
+
) +
|
|
322
325
|
'ON CONFLICT(' +
|
|
323
326
|
escapeId(rowIdColumnName) +
|
|
324
327
|
')DO UPDATE SET' +
|
|
@@ -666,7 +669,7 @@ const getDefaultedTabularConfigMap = (
|
|
|
666
669
|
) => {
|
|
667
670
|
const configMap = mapNew();
|
|
668
671
|
objMap(configsObj, (configObj, id) => {
|
|
669
|
-
const defaultedConfig =
|
|
672
|
+
const defaultedConfig = slice(
|
|
670
673
|
objValues(
|
|
671
674
|
objMerge(
|
|
672
675
|
defaultObj,
|
|
@@ -695,7 +698,7 @@ const getConfigStructures = (configOrStoreTableName) => {
|
|
|
695
698
|
];
|
|
696
699
|
}
|
|
697
700
|
const {tables: {load = {}, save = {}} = {}, values = {}} = config;
|
|
698
|
-
const valuesConfig =
|
|
701
|
+
const valuesConfig = slice(
|
|
699
702
|
objValues(objMerge(DEFAULT_TABULAR_VALUES_CONFIG, values)),
|
|
700
703
|
0,
|
|
701
704
|
objSize(DEFAULT_TABULAR_VALUES_CONFIG),
|
|
@@ -14,6 +14,7 @@ const ifNotUndefined = (value, then, otherwise) =>
|
|
|
14
14
|
isUndefined(value) ? otherwise?.() : then(value);
|
|
15
15
|
const isString = (thing) => getTypeOf(thing) == STRING;
|
|
16
16
|
const isArray = (thing) => Array.isArray(thing);
|
|
17
|
+
const slice = (arrayOrString, start, end) => arrayOrString.slice(start, end);
|
|
17
18
|
const promiseAll = async (promises) => promise.all(promises);
|
|
18
19
|
|
|
19
20
|
const arrayJoin = (array, sep = EMPTY_STRING) => array.join(sep);
|
|
@@ -21,7 +22,6 @@ const arrayMap = (array, cb) => array.map(cb);
|
|
|
21
22
|
const arrayLength = (array) => array.length;
|
|
22
23
|
const arrayIsEmpty = (array) => arrayLength(array) == 0;
|
|
23
24
|
const arrayFilter = (array, cb) => array.filter(cb);
|
|
24
|
-
const arraySlice = (array, start, end) => array.slice(start, end);
|
|
25
25
|
const arrayPush = (array, ...values) => array.push(...values);
|
|
26
26
|
const arrayShift = (array) => array.shift();
|
|
27
27
|
|
|
@@ -315,10 +315,13 @@ const upsert = async (
|
|
|
315
315
|
),
|
|
316
316
|
) +
|
|
317
317
|
')VALUES' +
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
318
|
+
slice(
|
|
319
|
+
strRepeat(
|
|
320
|
+
`,(?${strRepeat(',?', arrayLength(changingColumnNames))})`,
|
|
321
|
+
arrayLength(args) / (arrayLength(changingColumnNames) + 1),
|
|
322
|
+
),
|
|
323
|
+
1,
|
|
324
|
+
) +
|
|
322
325
|
'ON CONFLICT(' +
|
|
323
326
|
escapeId(rowIdColumnName) +
|
|
324
327
|
')DO UPDATE SET' +
|
|
@@ -666,7 +669,7 @@ const getDefaultedTabularConfigMap = (
|
|
|
666
669
|
) => {
|
|
667
670
|
const configMap = mapNew();
|
|
668
671
|
objMap(configsObj, (configObj, id) => {
|
|
669
|
-
const defaultedConfig =
|
|
672
|
+
const defaultedConfig = slice(
|
|
670
673
|
objValues(
|
|
671
674
|
objMerge(
|
|
672
675
|
defaultObj,
|
|
@@ -695,7 +698,7 @@ const getConfigStructures = (configOrStoreTableName) => {
|
|
|
695
698
|
];
|
|
696
699
|
}
|
|
697
700
|
const {tables: {load = {}, save = {}} = {}, values = {}} = config;
|
|
698
|
-
const valuesConfig =
|
|
701
|
+
const valuesConfig = slice(
|
|
699
702
|
objValues(objMerge(DEFAULT_TABULAR_VALUES_CONFIG, values)),
|
|
700
703
|
0,
|
|
701
704
|
objSize(DEFAULT_TABULAR_VALUES_CONFIG),
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
const getTypeOf = (thing) => typeof thing;
|
|
2
|
+
const EMPTY_STRING = '';
|
|
3
|
+
const STRING = getTypeOf(EMPTY_STRING);
|
|
4
|
+
|
|
5
|
+
const isInstanceOf = (thing, cls) => thing instanceof cls;
|
|
6
|
+
const isUndefined = (thing) => thing == void 0;
|
|
7
|
+
const ifNotUndefined = (value, then, otherwise) =>
|
|
8
|
+
isUndefined(value) ? otherwise?.() : then(value);
|
|
9
|
+
const isString = (thing) => getTypeOf(thing) == STRING;
|
|
10
|
+
const slice = (arrayOrString, start, end) => arrayOrString.slice(start, end);
|
|
11
|
+
|
|
12
|
+
const arrayLength = (array) => array.length;
|
|
13
|
+
const arrayPush = (array, ...values) => array.push(...values);
|
|
14
|
+
const arrayShift = (array) => array.shift();
|
|
15
|
+
|
|
16
|
+
const object = Object;
|
|
17
|
+
const objIds = object.keys;
|
|
18
|
+
const objFreeze = object.freeze;
|
|
19
|
+
const isObject = (obj) =>
|
|
20
|
+
isInstanceOf(obj, object) && obj.constructor == object;
|
|
21
|
+
const objSize = (obj) => arrayLength(objIds(obj));
|
|
22
|
+
const objIsEmpty = (obj) => isObject(obj) && objSize(obj) == 0;
|
|
23
|
+
|
|
24
|
+
const jsonString = (obj) =>
|
|
25
|
+
JSON.stringify(obj, (_key, value) =>
|
|
26
|
+
isInstanceOf(value, Map) ? object.fromEntries([...value]) : value,
|
|
27
|
+
);
|
|
28
|
+
const jsonParse = JSON.parse;
|
|
29
|
+
|
|
30
|
+
const SET_CHANGES = 's';
|
|
31
|
+
const STORE_PATH = '/store';
|
|
32
|
+
const PUT = 'PUT';
|
|
33
|
+
const constructMessage = (type, payload) =>
|
|
34
|
+
type + (isString(payload) ? payload : jsonString(payload));
|
|
35
|
+
const deconstructMessage = (message, stringified) => [
|
|
36
|
+
message[0],
|
|
37
|
+
stringified ? jsonParse(slice(message, 1)) : slice(message, 1),
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
const collHas = (coll, keyOrValue) => coll?.has(keyOrValue) ?? false;
|
|
41
|
+
const collDel = (coll, keyOrValue) => coll?.delete(keyOrValue);
|
|
42
|
+
|
|
43
|
+
const mapNew = (entries) => new Map(entries);
|
|
44
|
+
const mapGet = (map, key) => map?.get(key);
|
|
45
|
+
const mapSet = (map, key, value) =>
|
|
46
|
+
isUndefined(value) ? (collDel(map, key), map) : map?.set(key, value);
|
|
47
|
+
const mapEnsure = (map, key, getDefaultValue) => {
|
|
48
|
+
if (!collHas(map, key)) {
|
|
49
|
+
mapSet(map, key, getDefaultValue());
|
|
50
|
+
}
|
|
51
|
+
return mapGet(map, key);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const scheduleRunning = mapNew();
|
|
55
|
+
const scheduleActions = mapNew();
|
|
56
|
+
const createCustomPersister = (
|
|
57
|
+
store,
|
|
58
|
+
getPersisted,
|
|
59
|
+
setPersisted,
|
|
60
|
+
addPersisterListener,
|
|
61
|
+
delPersisterListener,
|
|
62
|
+
onIgnoredError,
|
|
63
|
+
scheduleId = [],
|
|
64
|
+
) => {
|
|
65
|
+
let listenerId;
|
|
66
|
+
let loadSave = 0;
|
|
67
|
+
let loads = 0;
|
|
68
|
+
let saves = 0;
|
|
69
|
+
let listening = 0;
|
|
70
|
+
let action;
|
|
71
|
+
let listeningHandle;
|
|
72
|
+
mapEnsure(scheduleRunning, scheduleId, () => 0);
|
|
73
|
+
mapEnsure(scheduleActions, scheduleId, () => []);
|
|
74
|
+
const run = async () => {
|
|
75
|
+
/* istanbul ignore else */
|
|
76
|
+
if (!mapGet(scheduleRunning, scheduleId)) {
|
|
77
|
+
mapSet(scheduleRunning, scheduleId, 1);
|
|
78
|
+
while (
|
|
79
|
+
!isUndefined((action = arrayShift(mapGet(scheduleActions, scheduleId))))
|
|
80
|
+
) {
|
|
81
|
+
try {
|
|
82
|
+
await action();
|
|
83
|
+
} catch (error) {
|
|
84
|
+
/* istanbul ignore next */
|
|
85
|
+
onIgnoredError?.(error);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
mapSet(scheduleRunning, scheduleId, 0);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
const loadLock = async (actions) => {
|
|
92
|
+
/* istanbul ignore else */
|
|
93
|
+
if (loadSave != 2) {
|
|
94
|
+
loadSave = 1;
|
|
95
|
+
{
|
|
96
|
+
loads++;
|
|
97
|
+
}
|
|
98
|
+
await persister.schedule(async () => {
|
|
99
|
+
await actions();
|
|
100
|
+
loadSave = 0;
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
return persister;
|
|
104
|
+
};
|
|
105
|
+
const persister = {
|
|
106
|
+
load: async (initialTables, initialValues) =>
|
|
107
|
+
await loadLock(async () => {
|
|
108
|
+
try {
|
|
109
|
+
store.setContent(await getPersisted());
|
|
110
|
+
} catch {
|
|
111
|
+
store.setContent([initialTables, initialValues]);
|
|
112
|
+
}
|
|
113
|
+
}),
|
|
114
|
+
startAutoLoad: async (initialTables = {}, initialValues = {}) => {
|
|
115
|
+
persister.stopAutoLoad();
|
|
116
|
+
await persister.load(initialTables, initialValues);
|
|
117
|
+
listening = 1;
|
|
118
|
+
listeningHandle = addPersisterListener(
|
|
119
|
+
async (getContent, getTransactionChanges) => {
|
|
120
|
+
if (getTransactionChanges) {
|
|
121
|
+
const transactionChanges = getTransactionChanges();
|
|
122
|
+
await loadLock(async () =>
|
|
123
|
+
store.setTransactionChanges(transactionChanges),
|
|
124
|
+
);
|
|
125
|
+
} else {
|
|
126
|
+
await loadLock(async () => {
|
|
127
|
+
try {
|
|
128
|
+
store.setContent(getContent?.() ?? (await getPersisted()));
|
|
129
|
+
} catch (error) {
|
|
130
|
+
onIgnoredError?.(error);
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
);
|
|
136
|
+
return persister;
|
|
137
|
+
},
|
|
138
|
+
stopAutoLoad: () => {
|
|
139
|
+
if (listening) {
|
|
140
|
+
delPersisterListener(listeningHandle);
|
|
141
|
+
listeningHandle = void 0;
|
|
142
|
+
listening = 0;
|
|
143
|
+
}
|
|
144
|
+
return persister;
|
|
145
|
+
},
|
|
146
|
+
save: async (getTransactionChanges) => {
|
|
147
|
+
/* istanbul ignore else */
|
|
148
|
+
if (loadSave != 1) {
|
|
149
|
+
loadSave = 2;
|
|
150
|
+
{
|
|
151
|
+
saves++;
|
|
152
|
+
}
|
|
153
|
+
await persister.schedule(async () => {
|
|
154
|
+
try {
|
|
155
|
+
await setPersisted(store.getContent, getTransactionChanges);
|
|
156
|
+
} catch (error) {
|
|
157
|
+
/* istanbul ignore next */
|
|
158
|
+
onIgnoredError?.(error);
|
|
159
|
+
}
|
|
160
|
+
loadSave = 0;
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
return persister;
|
|
164
|
+
},
|
|
165
|
+
startAutoSave: async () => {
|
|
166
|
+
await persister.stopAutoSave().save();
|
|
167
|
+
listenerId = store.addDidFinishTransactionListener(
|
|
168
|
+
(_store, getTransactionChanges) => {
|
|
169
|
+
const [tableChanges, valueChanges] = getTransactionChanges();
|
|
170
|
+
if (!objIsEmpty(tableChanges) || !objIsEmpty(valueChanges)) {
|
|
171
|
+
persister.save(() => [tableChanges, valueChanges]);
|
|
172
|
+
}
|
|
173
|
+
},
|
|
174
|
+
);
|
|
175
|
+
return persister;
|
|
176
|
+
},
|
|
177
|
+
stopAutoSave: () => {
|
|
178
|
+
ifNotUndefined(listenerId, store.delListener);
|
|
179
|
+
return persister;
|
|
180
|
+
},
|
|
181
|
+
schedule: async (...actions) => {
|
|
182
|
+
arrayPush(mapGet(scheduleActions, scheduleId), ...actions);
|
|
183
|
+
await run();
|
|
184
|
+
return persister;
|
|
185
|
+
},
|
|
186
|
+
getStore: () => store,
|
|
187
|
+
destroy: () => persister.stopAutoLoad().stopAutoSave(),
|
|
188
|
+
getStats: () => ({loads, saves}),
|
|
189
|
+
};
|
|
190
|
+
return objFreeze(persister);
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
const MESSAGE = 'message';
|
|
194
|
+
const createPartyKitPersister = (
|
|
195
|
+
store,
|
|
196
|
+
connection,
|
|
197
|
+
storeUrlProtocol = 'https',
|
|
198
|
+
onIgnoredError,
|
|
199
|
+
) => {
|
|
200
|
+
const {host, room} = connection.partySocketOptions;
|
|
201
|
+
const storeUrl =
|
|
202
|
+
storeUrlProtocol +
|
|
203
|
+
'://' +
|
|
204
|
+
host +
|
|
205
|
+
'/parties/' +
|
|
206
|
+
(connection.name ?? 'main') +
|
|
207
|
+
'/' +
|
|
208
|
+
room +
|
|
209
|
+
STORE_PATH;
|
|
210
|
+
const getOrSetStore = async (content) =>
|
|
211
|
+
await (
|
|
212
|
+
await fetch(storeUrl, {
|
|
213
|
+
...(content ? {method: PUT, body: jsonString(content)} : {}),
|
|
214
|
+
mode: 'cors',
|
|
215
|
+
cache: 'no-store',
|
|
216
|
+
})
|
|
217
|
+
).json();
|
|
218
|
+
const getPersisted = async () => await getOrSetStore();
|
|
219
|
+
const setPersisted = async (getContent, getTransactionChanges) => {
|
|
220
|
+
if (getTransactionChanges) {
|
|
221
|
+
connection.send(constructMessage(SET_CHANGES, getTransactionChanges()));
|
|
222
|
+
} else {
|
|
223
|
+
await getOrSetStore(getContent());
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
const addPersisterListener = (listener) => {
|
|
227
|
+
const messageListener = (event) => {
|
|
228
|
+
const [type, payload] = deconstructMessage(event.data, 1);
|
|
229
|
+
if (type == SET_CHANGES) {
|
|
230
|
+
listener(void 0, () => payload);
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
connection.addEventListener(MESSAGE, messageListener);
|
|
234
|
+
return messageListener;
|
|
235
|
+
};
|
|
236
|
+
const delPersisterListener = (messageListener) => {
|
|
237
|
+
connection.removeEventListener(MESSAGE, messageListener);
|
|
238
|
+
};
|
|
239
|
+
return createCustomPersister(
|
|
240
|
+
store,
|
|
241
|
+
getPersisted,
|
|
242
|
+
setPersisted,
|
|
243
|
+
addPersisterListener,
|
|
244
|
+
delPersisterListener,
|
|
245
|
+
onIgnoredError,
|
|
246
|
+
);
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
export {createPartyKitPersister};
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
const getTypeOf = (thing) => typeof thing;
|
|
2
|
+
const EMPTY_STRING = '';
|
|
3
|
+
const STRING = getTypeOf(EMPTY_STRING);
|
|
4
|
+
const T = 't';
|
|
5
|
+
const V = 'v';
|
|
6
|
+
|
|
7
|
+
const promise = Promise;
|
|
8
|
+
const isInstanceOf = (thing, cls) => thing instanceof cls;
|
|
9
|
+
const isUndefined = (thing) => thing == void 0;
|
|
10
|
+
const ifNotUndefined = (value, then, otherwise) =>
|
|
11
|
+
isUndefined(value) ? otherwise?.() : then(value);
|
|
12
|
+
const isString = (thing) => getTypeOf(thing) == STRING;
|
|
13
|
+
const slice = (arrayOrString, start, end) => arrayOrString.slice(start, end);
|
|
14
|
+
const promiseAll = async (promises) => promise.all(promises);
|
|
15
|
+
|
|
16
|
+
const arrayEvery = (array, cb) => array.every(cb);
|
|
17
|
+
const arrayMap = (array, cb) => array.map(cb);
|
|
18
|
+
const arrayLength = (array) => array.length;
|
|
19
|
+
const arrayIsEmpty = (array) => arrayLength(array) == 0;
|
|
20
|
+
const arrayPush = (array, ...values) => array.push(...values);
|
|
21
|
+
const arrayUnshift = (array, ...values) => array.unshift(...values);
|
|
22
|
+
|
|
23
|
+
const object = Object;
|
|
24
|
+
const objNew = (entries = []) => object.fromEntries(entries);
|
|
25
|
+
const objGet = (obj, id) => ifNotUndefined(obj, (obj2) => obj2[id]);
|
|
26
|
+
const objHas = (obj, id) => !isUndefined(objGet(obj, id));
|
|
27
|
+
const objMap = (obj, cb) =>
|
|
28
|
+
arrayMap(object.entries(obj), ([id, value]) => cb(value, id));
|
|
29
|
+
const objEnsure = (obj, id, getDefaultValue) => {
|
|
30
|
+
if (!objHas(obj, id)) {
|
|
31
|
+
obj[id] = getDefaultValue();
|
|
32
|
+
}
|
|
33
|
+
return obj[id];
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const jsonString = (obj) =>
|
|
37
|
+
JSON.stringify(obj, (_key, value) =>
|
|
38
|
+
isInstanceOf(value, Map) ? object.fromEntries([...value]) : value,
|
|
39
|
+
);
|
|
40
|
+
const jsonParse = JSON.parse;
|
|
41
|
+
|
|
42
|
+
const SET_CHANGES = 's';
|
|
43
|
+
const STORE_PATH = '/store';
|
|
44
|
+
const PUT = 'PUT';
|
|
45
|
+
const constructMessage = (type, payload) =>
|
|
46
|
+
type + (isString(payload) ? payload : jsonString(payload));
|
|
47
|
+
const deconstructMessage = (message, stringified) => [
|
|
48
|
+
message[0],
|
|
49
|
+
stringified ? jsonParse(slice(message, 1)) : slice(message, 1),
|
|
50
|
+
];
|
|
51
|
+
|
|
52
|
+
const collForEach = (coll, cb) => coll?.forEach(cb);
|
|
53
|
+
|
|
54
|
+
const mapForEach = (map, cb) =>
|
|
55
|
+
collForEach(map, (value, key) => cb(key, value));
|
|
56
|
+
|
|
57
|
+
const HAS_STORE = 'hasStore';
|
|
58
|
+
const CORS_HEADERS = objNew(
|
|
59
|
+
arrayMap(['Origin', 'Methods', 'Headers'], (suffix) => [
|
|
60
|
+
'Access-Control-Allow-' + suffix,
|
|
61
|
+
'*',
|
|
62
|
+
]),
|
|
63
|
+
);
|
|
64
|
+
const hasStoreInStorage = async (storage) => await storage.get(HAS_STORE);
|
|
65
|
+
const loadStoreFromStorage = async (storage) => {
|
|
66
|
+
const tables = {};
|
|
67
|
+
const values = {};
|
|
68
|
+
mapForEach(await storage.list(), (key, cellOrValue) => {
|
|
69
|
+
const [type, ids] = deconstructMessage(key);
|
|
70
|
+
if (type == T) {
|
|
71
|
+
const [tableId, rowId, cellId] = jsonParse('[' + ids + ']');
|
|
72
|
+
objEnsure(objEnsure(tables, tableId, objNew), rowId, objNew)[cellId] =
|
|
73
|
+
cellOrValue;
|
|
74
|
+
} else if (type == V) {
|
|
75
|
+
values[ids] = cellOrValue;
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
return [tables, values];
|
|
79
|
+
};
|
|
80
|
+
const saveStoreToStorage = async (storage, transactionChanges) => {
|
|
81
|
+
const promises = [storage.put(HAS_STORE, 1)];
|
|
82
|
+
const keyPrefixesToDelete = [];
|
|
83
|
+
objMap(transactionChanges[0], (table, tableId) =>
|
|
84
|
+
isUndefined(table)
|
|
85
|
+
? arrayUnshift(keyPrefixesToDelete, getStoreStorageKey(T, tableId))
|
|
86
|
+
: objMap(table, (row, rowId) =>
|
|
87
|
+
isUndefined(row)
|
|
88
|
+
? arrayPush(
|
|
89
|
+
keyPrefixesToDelete,
|
|
90
|
+
getStoreStorageKey(T, tableId, rowId),
|
|
91
|
+
)
|
|
92
|
+
: objMap(row, (cell, cellId) =>
|
|
93
|
+
promiseToSetOrDelStorage(
|
|
94
|
+
promises,
|
|
95
|
+
storage,
|
|
96
|
+
getStoreStorageKey(T, tableId, rowId, cellId),
|
|
97
|
+
cell,
|
|
98
|
+
),
|
|
99
|
+
),
|
|
100
|
+
),
|
|
101
|
+
);
|
|
102
|
+
objMap(transactionChanges[1], (value, valueId) =>
|
|
103
|
+
promiseToSetOrDelStorage(promises, storage, V + valueId, value),
|
|
104
|
+
);
|
|
105
|
+
if (!arrayIsEmpty(keyPrefixesToDelete)) {
|
|
106
|
+
mapForEach(await storage.list(), (key) =>
|
|
107
|
+
arrayEvery(
|
|
108
|
+
keyPrefixesToDelete,
|
|
109
|
+
(keyPrefixToDelete) =>
|
|
110
|
+
!key.startsWith(keyPrefixToDelete) ||
|
|
111
|
+
(promiseToSetOrDelStorage(promises, storage, key) && false),
|
|
112
|
+
),
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
await promiseAll(promises);
|
|
116
|
+
};
|
|
117
|
+
const getStoreStorageKey = (type, ...ids) =>
|
|
118
|
+
type + slice(jsonString(ids), 1, -1);
|
|
119
|
+
const promiseToSetOrDelStorage = (promises, storage, key, value) =>
|
|
120
|
+
arrayPush(
|
|
121
|
+
promises,
|
|
122
|
+
isUndefined(value) ? storage.delete(key) : storage.put(key, value),
|
|
123
|
+
);
|
|
124
|
+
const getResponse = (status, body = null) =>
|
|
125
|
+
new Response(body, {status, headers: CORS_HEADERS});
|
|
126
|
+
class TinyBasePartyKitServer {
|
|
127
|
+
constructor(party) {
|
|
128
|
+
this.party = party;
|
|
129
|
+
}
|
|
130
|
+
async onRequest(request) {
|
|
131
|
+
const storage = this.party.storage;
|
|
132
|
+
if (request.url.endsWith(STORE_PATH)) {
|
|
133
|
+
const hasStore = await hasStoreInStorage(storage);
|
|
134
|
+
const text = await request.text();
|
|
135
|
+
if (request.method == PUT) {
|
|
136
|
+
if (hasStore) {
|
|
137
|
+
return getResponse(205);
|
|
138
|
+
}
|
|
139
|
+
await saveStoreToStorage(this.party.storage, jsonParse(text));
|
|
140
|
+
return getResponse(201);
|
|
141
|
+
}
|
|
142
|
+
return getResponse(
|
|
143
|
+
200,
|
|
144
|
+
hasStore
|
|
145
|
+
? jsonString(await loadStoreFromStorage(storage))
|
|
146
|
+
: EMPTY_STRING,
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
return getResponse(404);
|
|
150
|
+
}
|
|
151
|
+
async onMessage(message, client) {
|
|
152
|
+
const storage = this.party.storage;
|
|
153
|
+
const [type, payload] = deconstructMessage(message, 1);
|
|
154
|
+
if (type == SET_CHANGES && (await hasStoreInStorage(storage))) {
|
|
155
|
+
await saveStoreToStorage(storage, payload);
|
|
156
|
+
this.party.broadcast(constructMessage(SET_CHANGES, payload), [client.id]);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export {TinyBasePartyKitServer};
|
|
@@ -14,6 +14,7 @@ const ifNotUndefined = (value, then, otherwise) =>
|
|
|
14
14
|
isUndefined(value) ? otherwise?.() : then(value);
|
|
15
15
|
const isString = (thing) => getTypeOf(thing) == STRING;
|
|
16
16
|
const isArray = (thing) => Array.isArray(thing);
|
|
17
|
+
const slice = (arrayOrString, start, end) => arrayOrString.slice(start, end);
|
|
17
18
|
const promiseAll = async (promises) => promise.all(promises);
|
|
18
19
|
|
|
19
20
|
const arrayJoin = (array, sep = EMPTY_STRING) => array.join(sep);
|
|
@@ -21,7 +22,6 @@ const arrayMap = (array, cb) => array.map(cb);
|
|
|
21
22
|
const arrayLength = (array) => array.length;
|
|
22
23
|
const arrayIsEmpty = (array) => arrayLength(array) == 0;
|
|
23
24
|
const arrayFilter = (array, cb) => array.filter(cb);
|
|
24
|
-
const arraySlice = (array, start, end) => array.slice(start, end);
|
|
25
25
|
const arrayPush = (array, ...values) => array.push(...values);
|
|
26
26
|
const arrayShift = (array) => array.shift();
|
|
27
27
|
|
|
@@ -315,10 +315,13 @@ const upsert = async (
|
|
|
315
315
|
),
|
|
316
316
|
) +
|
|
317
317
|
')VALUES' +
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
318
|
+
slice(
|
|
319
|
+
strRepeat(
|
|
320
|
+
`,(?${strRepeat(',?', arrayLength(changingColumnNames))})`,
|
|
321
|
+
arrayLength(args) / (arrayLength(changingColumnNames) + 1),
|
|
322
|
+
),
|
|
323
|
+
1,
|
|
324
|
+
) +
|
|
322
325
|
'ON CONFLICT(' +
|
|
323
326
|
escapeId(rowIdColumnName) +
|
|
324
327
|
')DO UPDATE SET' +
|
|
@@ -666,7 +669,7 @@ const getDefaultedTabularConfigMap = (
|
|
|
666
669
|
) => {
|
|
667
670
|
const configMap = mapNew();
|
|
668
671
|
objMap(configsObj, (configObj, id) => {
|
|
669
|
-
const defaultedConfig =
|
|
672
|
+
const defaultedConfig = slice(
|
|
670
673
|
objValues(
|
|
671
674
|
objMerge(
|
|
672
675
|
defaultObj,
|
|
@@ -695,7 +698,7 @@ const getConfigStructures = (configOrStoreTableName) => {
|
|
|
695
698
|
];
|
|
696
699
|
}
|
|
697
700
|
const {tables: {load = {}, save = {}} = {}, values = {}} = config;
|
|
698
|
-
const valuesConfig =
|
|
701
|
+
const valuesConfig = slice(
|
|
699
702
|
objValues(objMerge(DEFAULT_TABULAR_VALUES_CONFIG, values)),
|
|
700
703
|
0,
|
|
701
704
|
objSize(DEFAULT_TABULAR_VALUES_CONFIG),
|
|
@@ -14,6 +14,7 @@ const ifNotUndefined = (value, then, otherwise) =>
|
|
|
14
14
|
isUndefined(value) ? otherwise?.() : then(value);
|
|
15
15
|
const isString = (thing) => getTypeOf(thing) == STRING;
|
|
16
16
|
const isArray = (thing) => Array.isArray(thing);
|
|
17
|
+
const slice = (arrayOrString, start, end) => arrayOrString.slice(start, end);
|
|
17
18
|
const promiseNew = (resolver) => new promise(resolver);
|
|
18
19
|
const promiseAll = async (promises) => promise.all(promises);
|
|
19
20
|
|
|
@@ -22,7 +23,6 @@ const arrayMap = (array, cb) => array.map(cb);
|
|
|
22
23
|
const arrayLength = (array) => array.length;
|
|
23
24
|
const arrayIsEmpty = (array) => arrayLength(array) == 0;
|
|
24
25
|
const arrayFilter = (array, cb) => array.filter(cb);
|
|
25
|
-
const arraySlice = (array, start, end) => array.slice(start, end);
|
|
26
26
|
const arrayPush = (array, ...values) => array.push(...values);
|
|
27
27
|
const arrayShift = (array) => array.shift();
|
|
28
28
|
|
|
@@ -316,10 +316,13 @@ const upsert = async (
|
|
|
316
316
|
),
|
|
317
317
|
) +
|
|
318
318
|
')VALUES' +
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
319
|
+
slice(
|
|
320
|
+
strRepeat(
|
|
321
|
+
`,(?${strRepeat(',?', arrayLength(changingColumnNames))})`,
|
|
322
|
+
arrayLength(args) / (arrayLength(changingColumnNames) + 1),
|
|
323
|
+
),
|
|
324
|
+
1,
|
|
325
|
+
) +
|
|
323
326
|
'ON CONFLICT(' +
|
|
324
327
|
escapeId(rowIdColumnName) +
|
|
325
328
|
')DO UPDATE SET' +
|
|
@@ -667,7 +670,7 @@ const getDefaultedTabularConfigMap = (
|
|
|
667
670
|
) => {
|
|
668
671
|
const configMap = mapNew();
|
|
669
672
|
objMap(configsObj, (configObj, id) => {
|
|
670
|
-
const defaultedConfig =
|
|
673
|
+
const defaultedConfig = slice(
|
|
671
674
|
objValues(
|
|
672
675
|
objMerge(
|
|
673
676
|
defaultObj,
|
|
@@ -696,7 +699,7 @@ const getConfigStructures = (configOrStoreTableName) => {
|
|
|
696
699
|
];
|
|
697
700
|
}
|
|
698
701
|
const {tables: {load = {}, save = {}} = {}, values = {}} = config;
|
|
699
|
-
const valuesConfig =
|
|
702
|
+
const valuesConfig = slice(
|
|
700
703
|
objValues(objMerge(DEFAULT_TABULAR_VALUES_CONFIG, values)),
|
|
701
704
|
0,
|
|
702
705
|
objSize(DEFAULT_TABULAR_VALUES_CONFIG),
|
package/lib/debug/queries.js
CHANGED
|
@@ -31,7 +31,6 @@ const arraySum = (array) => arrayReduce(array, (i, j) => i + j, 0);
|
|
|
31
31
|
const arrayLength = (array) => array.length;
|
|
32
32
|
const arrayIsEmpty = (array) => arrayLength(array) == 0;
|
|
33
33
|
const arrayReduce = (array, cb, initial) => array.reduce(cb, initial);
|
|
34
|
-
const arraySlice = (array, start, end) => array.slice(start, end);
|
|
35
34
|
const arrayPush = (array, ...values) => array.push(...values);
|
|
36
35
|
|
|
37
36
|
const mathMax = Math.max;
|
|
@@ -43,6 +42,7 @@ const ifNotUndefined = (value, then, otherwise) =>
|
|
|
43
42
|
const isTypeStringOrBoolean = (type) => type == STRING || type == BOOLEAN;
|
|
44
43
|
const isFunction = (thing) => getTypeOf(thing) == FUNCTION;
|
|
45
44
|
const isArray = (thing) => Array.isArray(thing);
|
|
45
|
+
const slice = (arrayOrString, start, end) => arrayOrString.slice(start, end);
|
|
46
46
|
const getUndefined = () => void 0;
|
|
47
47
|
|
|
48
48
|
const object = Object;
|
|
@@ -794,7 +794,7 @@ const createQueries = getCreateFunction((store) => {
|
|
|
794
794
|
);
|
|
795
795
|
queries[ADD + RESULT + gettable + LISTENER] = (...args) =>
|
|
796
796
|
resultStore[ADD + gettable + LISTENER](
|
|
797
|
-
...
|
|
797
|
+
...slice(args, 0, argumentCount),
|
|
798
798
|
(_store, ...listenerArgs) =>
|
|
799
799
|
args[argumentCount](queries, ...listenerArgs),
|
|
800
800
|
);
|
package/lib/debug/store.js
CHANGED
|
@@ -30,6 +30,7 @@ const ifNotUndefined = (value, then, otherwise) =>
|
|
|
30
30
|
const isTypeStringOrBoolean = (type) => type == STRING || type == BOOLEAN;
|
|
31
31
|
const isFunction = (thing) => getTypeOf(thing) == FUNCTION;
|
|
32
32
|
const isArray = (thing) => Array.isArray(thing);
|
|
33
|
+
const slice = (arrayOrString, start, end) => arrayOrString.slice(start, end);
|
|
33
34
|
const test = (regex, subject) => regex.test(subject);
|
|
34
35
|
|
|
35
36
|
const arrayHas = (array, value) => array.includes(value);
|
|
@@ -42,7 +43,6 @@ const arrayForEach = (array, cb) => array.forEach(cb);
|
|
|
42
43
|
const arrayMap = (array, cb) => array.map(cb);
|
|
43
44
|
const arrayLength = (array) => array.length;
|
|
44
45
|
const arrayReduce = (array, cb, initial) => array.reduce(cb, initial);
|
|
45
|
-
const arraySlice = (array, start, end) => array.slice(start, end);
|
|
46
46
|
const arrayPush = (array, ...values) => array.push(...values);
|
|
47
47
|
const arrayShift = (array) => array.shift();
|
|
48
48
|
|
|
@@ -935,7 +935,7 @@ const createStore = () => {
|
|
|
935
935
|
const getRowIds = (tableId) => mapKeys(mapGet(tablesMap, id(tableId)));
|
|
936
936
|
const getSortedRowIds = (tableId, cellId, descending, offset = 0, limit) =>
|
|
937
937
|
arrayMap(
|
|
938
|
-
|
|
938
|
+
slice(
|
|
939
939
|
arraySort(
|
|
940
940
|
mapMap(mapGet(tablesMap, id(tableId)), (row, rowId) => [
|
|
941
941
|
isUndefined(cellId) ? rowId : mapGet(row, id(cellId)),
|
|
@@ -1495,7 +1495,7 @@ const createStore = () => {
|
|
|
1495
1495
|
addListener(
|
|
1496
1496
|
args[argumentCount],
|
|
1497
1497
|
idSetNode[args[argumentCount + 1] ? 1 : 0],
|
|
1498
|
-
argumentCount > 0 ?
|
|
1498
|
+
argumentCount > 0 ? slice(args, 0, argumentCount) : void 0,
|
|
1499
1499
|
pathGetters,
|
|
1500
1500
|
extraArgsGetter,
|
|
1501
1501
|
);
|