tinybase 1.3.3 → 2.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/checkpoints.js +1 -1
- package/lib/checkpoints.js.gz +0 -0
- package/lib/debug/checkpoints.js +67 -54
- package/lib/debug/indexes.js +104 -67
- package/lib/debug/metrics.js +185 -129
- package/lib/debug/persisters.js +2 -1
- package/lib/debug/queries.d.ts +3066 -0
- package/lib/debug/queries.js +883 -0
- package/lib/debug/relationships.d.ts +6 -5
- package/lib/debug/relationships.js +103 -67
- package/lib/debug/store.d.ts +137 -66
- package/lib/debug/store.js +215 -119
- package/lib/debug/tinybase.d.ts +1 -0
- package/lib/debug/tinybase.js +896 -176
- package/lib/debug/ui-react.d.ts +49 -2
- package/lib/debug/ui-react.js +85 -74
- package/lib/indexes.js +1 -1
- package/lib/indexes.js.gz +0 -0
- package/lib/metrics.js +1 -1
- package/lib/metrics.js.gz +0 -0
- package/lib/queries.d.ts +3066 -0
- package/lib/queries.js +1 -0
- package/lib/queries.js.gz +0 -0
- package/lib/relationships.d.ts +6 -5
- package/lib/relationships.js +1 -1
- package/lib/relationships.js.gz +0 -0
- package/lib/store.d.ts +137 -66
- package/lib/store.js +1 -1
- package/lib/store.js.gz +0 -0
- package/lib/tinybase.d.ts +1 -0
- package/lib/tinybase.js +1 -1
- package/lib/tinybase.js.gz +0 -0
- package/lib/ui-react.d.ts +49 -2
- package/lib/ui-react.js +1 -1
- package/lib/ui-react.js.gz +0 -0
- package/lib/umd/checkpoints.js +1 -1
- package/lib/umd/checkpoints.js.gz +0 -0
- package/lib/umd/indexes.js +1 -1
- package/lib/umd/indexes.js.gz +0 -0
- package/lib/umd/metrics.js +1 -1
- package/lib/umd/metrics.js.gz +0 -0
- package/lib/umd/queries.js +1 -0
- package/lib/umd/queries.js.gz +0 -0
- package/lib/umd/relationships.js +1 -1
- package/lib/umd/relationships.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/ui-react.js +1 -1
- package/lib/umd/ui-react.js.gz +0 -0
- package/package.json +24 -24
- package/readme.md +2 -2
package/lib/debug/tinybase.js
CHANGED
|
@@ -15,22 +15,27 @@ const AVG = 'avg';
|
|
|
15
15
|
const MIN = 'min';
|
|
16
16
|
const MAX = 'max';
|
|
17
17
|
|
|
18
|
-
const arrayPair = (value) => [value, value];
|
|
19
18
|
const arrayHas = (array, value) => array.includes(value);
|
|
19
|
+
const arrayEvery = (array, cb) => array.every(cb);
|
|
20
|
+
const arrayIsEqual = (array1, array2) =>
|
|
21
|
+
arrayLength(array1) === arrayLength(array2) &&
|
|
22
|
+
arrayEvery(array1, (value1, index) => array2[index] === value1);
|
|
20
23
|
const arrayIsSorted = (array, sorter) =>
|
|
21
|
-
|
|
24
|
+
arrayEvery(
|
|
25
|
+
array,
|
|
22
26
|
(value, index) => index == 0 || sorter(array[index - 1], value) <= 0,
|
|
23
27
|
);
|
|
24
28
|
const arraySort = (array, sorter) => array.sort(sorter);
|
|
25
29
|
const arrayForEach = (array, cb) => array.forEach(cb);
|
|
30
|
+
const arrayMap = (array, cb) => array.map(cb);
|
|
26
31
|
const arraySum = (array) => arrayReduce(array, (i, j) => i + j, 0);
|
|
27
32
|
const arrayLength = (array) => array.length;
|
|
28
33
|
const arrayIsEmpty = (array) => arrayLength(array) == 0;
|
|
29
34
|
const arrayReduce = (array, cb, initial) => array.reduce(cb, initial);
|
|
30
35
|
const arrayFilter = (array, cb) => array.filter(cb);
|
|
31
|
-
const
|
|
36
|
+
const arraySlice = (array, start, end) => array.slice(start, end);
|
|
32
37
|
const arrayClear = (array, to) => array.splice(0, to);
|
|
33
|
-
const arrayPush = (array,
|
|
38
|
+
const arrayPush = (array, ...values) => array.push(...values);
|
|
34
39
|
const arrayPop = (array) => array.pop();
|
|
35
40
|
|
|
36
41
|
const jsonString = (obj) =>
|
|
@@ -65,7 +70,6 @@ const collSize = (coll) => coll.size;
|
|
|
65
70
|
const collSize2 = collSizeN(collSize);
|
|
66
71
|
const collSize3 = collSizeN(collSize2);
|
|
67
72
|
const collSize4 = collSizeN(collSize3);
|
|
68
|
-
const collPairSize = (pair, func = collSize) => func(pair[0]) + func(pair[1]);
|
|
69
73
|
const collHas = (coll, keyOrValue) => coll?.has(keyOrValue) ?? false;
|
|
70
74
|
const collIsEmpty = (coll) => isUndefined(coll) || collSize(coll) == 0;
|
|
71
75
|
const collValues = (coll) => [...(coll?.values() ?? [])];
|
|
@@ -74,7 +78,6 @@ const collForEach = (coll, cb) => coll?.forEach(cb);
|
|
|
74
78
|
const collDel = (coll, keyOrValue) => coll?.delete(keyOrValue);
|
|
75
79
|
|
|
76
80
|
const mapNew = (entries) => new Map(entries);
|
|
77
|
-
const mapNewPair = (newFunction = mapNew) => [newFunction(), newFunction()];
|
|
78
81
|
const mapKeys = (map) => [...(map?.keys() ?? [])];
|
|
79
82
|
const mapGet = (map, key) => map?.get(key);
|
|
80
83
|
const mapForEach = (map, cb) =>
|
|
@@ -104,6 +107,27 @@ const mapClone = (map, childMapper) => {
|
|
|
104
107
|
return map2;
|
|
105
108
|
};
|
|
106
109
|
const mapClone2 = (map) => mapClone(map, mapClone);
|
|
110
|
+
const visitTree = (node, path, ensureLeaf, pruneLeaf, p = 0) =>
|
|
111
|
+
ifNotUndefined(
|
|
112
|
+
(ensureLeaf ? mapEnsure : mapGet)(
|
|
113
|
+
node,
|
|
114
|
+
path[p],
|
|
115
|
+
p > arrayLength(path) - 2 ? ensureLeaf : mapNew,
|
|
116
|
+
),
|
|
117
|
+
(nodeOrLeaf) => {
|
|
118
|
+
if (p > arrayLength(path) - 2) {
|
|
119
|
+
if (pruneLeaf?.(nodeOrLeaf)) {
|
|
120
|
+
mapSet(node, path[p]);
|
|
121
|
+
}
|
|
122
|
+
return nodeOrLeaf;
|
|
123
|
+
}
|
|
124
|
+
const leaf = visitTree(nodeOrLeaf, path, ensureLeaf, pruneLeaf, p + 1);
|
|
125
|
+
if (collIsEmpty(nodeOrLeaf)) {
|
|
126
|
+
mapSet(node, path[p]);
|
|
127
|
+
}
|
|
128
|
+
return leaf;
|
|
129
|
+
},
|
|
130
|
+
);
|
|
107
131
|
|
|
108
132
|
const setNew = (entries) => new Set(entries);
|
|
109
133
|
const setAdd = (set, value) => set?.add(value);
|
|
@@ -122,20 +146,46 @@ const getDefinableFunctions = (store, getDefaultThing, validateRowValue) => {
|
|
|
122
146
|
const getTableId = (id) => mapGet(tableIds, id);
|
|
123
147
|
const getThing = (id) => mapGet(things, id);
|
|
124
148
|
const setThing = (id, thing) => mapSet(things, id, thing);
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
149
|
+
const addStoreListeners = (id, andCall, ...listenerIds) => {
|
|
150
|
+
const set = mapEnsure(storeListenerIds, id, setNew);
|
|
151
|
+
arrayForEach(
|
|
152
|
+
listenerIds,
|
|
153
|
+
(listenerId) =>
|
|
154
|
+
setAdd(set, listenerId) && andCall && store.callListener(listenerId),
|
|
155
|
+
);
|
|
156
|
+
return listenerIds;
|
|
157
|
+
};
|
|
158
|
+
const delStoreListeners = (id, ...listenerIds) =>
|
|
159
|
+
ifNotUndefined(mapGet(storeListenerIds, id), (allListenerIds) => {
|
|
160
|
+
arrayForEach(
|
|
161
|
+
arrayIsEmpty(listenerIds) ? collValues(allListenerIds) : listenerIds,
|
|
162
|
+
(listenerId) => {
|
|
163
|
+
store.delListener(listenerId);
|
|
164
|
+
collDel(allListenerIds, listenerId);
|
|
165
|
+
},
|
|
166
|
+
);
|
|
167
|
+
if (collIsEmpty(allListenerIds)) {
|
|
168
|
+
mapSet(storeListenerIds, id);
|
|
169
|
+
}
|
|
129
170
|
});
|
|
130
|
-
const setDefinition = (id, tableId
|
|
131
|
-
const changedRowValues = mapNew();
|
|
132
|
-
const changedSortKeys = mapNew();
|
|
171
|
+
const setDefinition = (id, tableId) => {
|
|
133
172
|
mapSet(tableIds, id, tableId);
|
|
134
173
|
if (!collHas(things, id)) {
|
|
135
174
|
mapSet(things, id, getDefaultThing());
|
|
136
175
|
mapSet(allRowValues, id, mapNew());
|
|
137
176
|
mapSet(allSortKeys, id, mapNew());
|
|
138
177
|
}
|
|
178
|
+
};
|
|
179
|
+
const setDefinitionAndListen = (
|
|
180
|
+
id,
|
|
181
|
+
tableId,
|
|
182
|
+
onChanged,
|
|
183
|
+
getRowValue,
|
|
184
|
+
getSortKey,
|
|
185
|
+
) => {
|
|
186
|
+
setDefinition(id, tableId);
|
|
187
|
+
const changedRowValues = mapNew();
|
|
188
|
+
const changedSortKeys = mapNew();
|
|
139
189
|
const rowValues = mapGet(allRowValues, id);
|
|
140
190
|
const sortKeys = mapGet(allSortKeys, id);
|
|
141
191
|
const processRow = (rowId) => {
|
|
@@ -185,16 +235,14 @@ const getDefinableFunctions = (store, getDefaultThing, validateRowValue) => {
|
|
|
185
235
|
});
|
|
186
236
|
}
|
|
187
237
|
processTable(true);
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
storeListenerIds,
|
|
238
|
+
delStoreListeners(id);
|
|
239
|
+
addStoreListeners(
|
|
191
240
|
id,
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
]),
|
|
241
|
+
0,
|
|
242
|
+
store.addRowListener(tableId, null, (_store, _tableId, rowId) =>
|
|
243
|
+
processRow(rowId),
|
|
244
|
+
),
|
|
245
|
+
store.addTableListener(tableId, () => processTable()),
|
|
198
246
|
);
|
|
199
247
|
};
|
|
200
248
|
const delDefinition = (id) => {
|
|
@@ -202,7 +250,7 @@ const getDefinableFunctions = (store, getDefaultThing, validateRowValue) => {
|
|
|
202
250
|
mapSet(things, id);
|
|
203
251
|
mapSet(allRowValues, id);
|
|
204
252
|
mapSet(allSortKeys, id);
|
|
205
|
-
|
|
253
|
+
delStoreListeners(id);
|
|
206
254
|
};
|
|
207
255
|
const destroy = () => mapForEach(storeListenerIds, delDefinition);
|
|
208
256
|
return [
|
|
@@ -214,8 +262,11 @@ const getDefinableFunctions = (store, getDefaultThing, validateRowValue) => {
|
|
|
214
262
|
getThing,
|
|
215
263
|
setThing,
|
|
216
264
|
setDefinition,
|
|
265
|
+
setDefinitionAndListen,
|
|
217
266
|
delDefinition,
|
|
218
267
|
destroy,
|
|
268
|
+
addStoreListeners,
|
|
269
|
+
delStoreListeners,
|
|
219
270
|
];
|
|
220
271
|
};
|
|
221
272
|
const getRowCellFunction = (getRowCell, defaultCellValue) =>
|
|
@@ -232,64 +283,51 @@ const getCreateFunction = (getFunction) => {
|
|
|
232
283
|
};
|
|
233
284
|
};
|
|
234
285
|
|
|
235
|
-
const
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
)
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
value,
|
|
244
|
-
arrayFromSecond(ids),
|
|
245
|
-
);
|
|
246
|
-
const forDeepSet = (valueDo) => {
|
|
247
|
-
const deep = (deepIdSet, arg, ...ids) =>
|
|
248
|
-
ifNotUndefined(deepIdSet, (deepIdSet2) =>
|
|
249
|
-
arrayIsEmpty(ids)
|
|
250
|
-
? valueDo(deepIdSet2, arg)
|
|
251
|
-
: arrayForEach([ids[0], null], (id) =>
|
|
252
|
-
deep(mapGet(deepIdSet2, id), arg, ...arrayFromSecond(ids)),
|
|
253
|
-
),
|
|
254
|
-
);
|
|
255
|
-
return deep;
|
|
286
|
+
const getWildcardedLeaves = (deepIdSet, path = [EMPTY_STRING]) => {
|
|
287
|
+
const sets = [];
|
|
288
|
+
const deep = (set, p) =>
|
|
289
|
+
p == arrayLength(path)
|
|
290
|
+
? arrayPush(sets, set)
|
|
291
|
+
: arrayForEach([path[p], null], (id) => deep(mapGet(set, id), p + 1));
|
|
292
|
+
deep(deepIdSet, 0);
|
|
293
|
+
return sets;
|
|
256
294
|
};
|
|
257
295
|
const getListenerFunctions = (getThing) => {
|
|
258
296
|
let thing;
|
|
259
297
|
let nextId = 0;
|
|
260
298
|
const listenerPool = [];
|
|
261
299
|
const allListeners = mapNew();
|
|
262
|
-
const addListener = (listener,
|
|
300
|
+
const addListener = (listener, idSetNode, idOrNulls) => {
|
|
263
301
|
thing ??= getThing();
|
|
264
|
-
const id = arrayPop(listenerPool) ??
|
|
265
|
-
mapSet(allListeners, id, [listener,
|
|
266
|
-
|
|
302
|
+
const id = arrayPop(listenerPool) ?? EMPTY_STRING + nextId++;
|
|
303
|
+
mapSet(allListeners, id, [listener, idSetNode, idOrNulls]);
|
|
304
|
+
setAdd(visitTree(idSetNode, idOrNulls ?? [EMPTY_STRING], setNew), id);
|
|
267
305
|
return id;
|
|
268
306
|
};
|
|
269
|
-
const callListeners = (
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
(id) =>
|
|
307
|
+
const callListeners = (idSetNode, ids, ...extraArgs) =>
|
|
308
|
+
arrayForEach(getWildcardedLeaves(idSetNode, ids), (set) =>
|
|
309
|
+
collForEach(set, (id) =>
|
|
273
310
|
ifNotUndefined(mapGet(allListeners, id), ([listener]) =>
|
|
274
|
-
listener(thing, ...ids, ...extraArgs),
|
|
311
|
+
listener(thing, ...(ids ?? []), ...extraArgs),
|
|
275
312
|
),
|
|
276
|
-
|
|
313
|
+
),
|
|
277
314
|
);
|
|
278
315
|
const delListener = (id) =>
|
|
279
|
-
ifNotUndefined(
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
316
|
+
ifNotUndefined(mapGet(allListeners, id), ([, idSetNode, idOrNulls]) => {
|
|
317
|
+
visitTree(idSetNode, idOrNulls ?? [EMPTY_STRING], void 0, (idSet) => {
|
|
318
|
+
collDel(idSet, id);
|
|
319
|
+
return collIsEmpty(idSet) ? 1 : 0;
|
|
320
|
+
});
|
|
321
|
+
mapSet(allListeners, id);
|
|
322
|
+
if (arrayLength(listenerPool) < 1e3) {
|
|
323
|
+
arrayPush(listenerPool, id);
|
|
324
|
+
}
|
|
325
|
+
return idOrNulls;
|
|
326
|
+
});
|
|
327
|
+
const hasListeners = (idSetNode, ids) =>
|
|
328
|
+
!arrayEvery(getWildcardedLeaves(idSetNode, ids), isUndefined);
|
|
291
329
|
const callListener = (id, idNullGetters, extraArgsGetter) =>
|
|
292
|
-
ifNotUndefined(mapGet(allListeners, id), ([listener, , idOrNulls]) => {
|
|
330
|
+
ifNotUndefined(mapGet(allListeners, id), ([listener, , idOrNulls = []]) => {
|
|
293
331
|
const callWithIds = (...ids) => {
|
|
294
332
|
const index = arrayLength(ids);
|
|
295
333
|
index == arrayLength(idOrNulls)
|
|
@@ -302,7 +340,7 @@ const getListenerFunctions = (getThing) => {
|
|
|
302
340
|
};
|
|
303
341
|
callWithIds();
|
|
304
342
|
});
|
|
305
|
-
return [addListener, callListeners, delListener, callListener];
|
|
343
|
+
return [addListener, callListeners, delListener, hasListeners, callListener];
|
|
306
344
|
};
|
|
307
345
|
|
|
308
346
|
const object = Object;
|
|
@@ -318,6 +356,17 @@ const objForEach = (obj, cb) =>
|
|
|
318
356
|
arrayForEach(object.entries(obj), ([id, value]) => cb(value, id));
|
|
319
357
|
const objIsEmpty = (obj) => arrayIsEmpty(objIds(obj));
|
|
320
358
|
|
|
359
|
+
const getCellType = (cell) => {
|
|
360
|
+
const type = getTypeOf(cell);
|
|
361
|
+
return isTypeStringOrBoolean(type) || (type == NUMBER && isFiniteNumber(cell))
|
|
362
|
+
? type
|
|
363
|
+
: void 0;
|
|
364
|
+
};
|
|
365
|
+
const setOrDelCell = (store, tableId, rowId, cellId, cell) =>
|
|
366
|
+
isUndefined(cell)
|
|
367
|
+
? store.delCell(tableId, rowId, cellId, true)
|
|
368
|
+
: store.setCell(tableId, rowId, cellId, cell);
|
|
369
|
+
|
|
321
370
|
const createCheckpoints = getCreateFunction((store) => {
|
|
322
371
|
let backwardIdsSize = 100;
|
|
323
372
|
let currentId;
|
|
@@ -325,7 +374,7 @@ const createCheckpoints = getCreateFunction((store) => {
|
|
|
325
374
|
let listening = 1;
|
|
326
375
|
let nextCheckpointId;
|
|
327
376
|
let checkpointsChanged;
|
|
328
|
-
const checkpointIdsListeners =
|
|
377
|
+
const checkpointIdsListeners = mapNew();
|
|
329
378
|
const checkpointListeners = mapNew();
|
|
330
379
|
const [addListener, callListeners, delListenerImpl] = getListenerFunctions(
|
|
331
380
|
() => checkpoints,
|
|
@@ -340,9 +389,7 @@ const createCheckpoints = getCreateFunction((store) => {
|
|
|
340
389
|
collForEach(mapGet(deltas, checkpointId), (table, tableId) =>
|
|
341
390
|
collForEach(table, (row, rowId) =>
|
|
342
391
|
collForEach(row, (oldNew, cellId) =>
|
|
343
|
-
|
|
344
|
-
? store.delCell(tableId, rowId, cellId, true)
|
|
345
|
-
: store.setCell(tableId, rowId, cellId, oldNew[oldOrNew]),
|
|
392
|
+
setOrDelCell(store, tableId, rowId, cellId, oldNew[oldOrNew]),
|
|
346
393
|
),
|
|
347
394
|
),
|
|
348
395
|
),
|
|
@@ -392,9 +439,9 @@ const createCheckpoints = getCreateFunction((store) => {
|
|
|
392
439
|
}
|
|
393
440
|
},
|
|
394
441
|
);
|
|
395
|
-
const addCheckpointImpl = (label =
|
|
442
|
+
const addCheckpointImpl = (label = EMPTY_STRING) => {
|
|
396
443
|
if (isUndefined(currentId)) {
|
|
397
|
-
currentId =
|
|
444
|
+
currentId = EMPTY_STRING + nextCheckpointId++;
|
|
398
445
|
mapSet(deltas, currentId, delta);
|
|
399
446
|
setCheckpoint(currentId, label);
|
|
400
447
|
delta = mapNew();
|
|
@@ -492,7 +539,7 @@ const createCheckpoints = getCreateFunction((store) => {
|
|
|
492
539
|
store.delListener(listenerId);
|
|
493
540
|
};
|
|
494
541
|
const getListenerStats = () => ({
|
|
495
|
-
checkpointIds:
|
|
542
|
+
checkpointIds: collSize2(checkpointIdsListeners),
|
|
496
543
|
checkpoint: collSize2(checkpointListeners),
|
|
497
544
|
});
|
|
498
545
|
const checkpoints = {
|
|
@@ -530,7 +577,8 @@ const createIndexes = getCreateFunction((store) => {
|
|
|
530
577
|
getTableId,
|
|
531
578
|
getIndex,
|
|
532
579
|
setIndex,
|
|
533
|
-
|
|
580
|
+
,
|
|
581
|
+
setDefinitionAndListen,
|
|
534
582
|
delDefinition,
|
|
535
583
|
destroy,
|
|
536
584
|
] = getDefinableFunctions(store, mapNew, (value) =>
|
|
@@ -551,7 +599,7 @@ const createIndexes = getCreateFunction((store) => {
|
|
|
551
599
|
const sliceIdArraySorter = isUndefined(sliceIdSorter)
|
|
552
600
|
? void 0
|
|
553
601
|
: ([id1], [id2]) => sliceIdSorter(id1, id2);
|
|
554
|
-
|
|
602
|
+
setDefinitionAndListen(
|
|
555
603
|
indexId,
|
|
556
604
|
tableId,
|
|
557
605
|
(change, changedSliceIds, changedSortKeys, sliceIds, sortKeys, force) => {
|
|
@@ -695,7 +743,7 @@ const createIndexes = getCreateFunction((store) => {
|
|
|
695
743
|
return objFreeze(indexes);
|
|
696
744
|
});
|
|
697
745
|
|
|
698
|
-
const
|
|
746
|
+
const numericAggregators = mapNew([
|
|
699
747
|
[
|
|
700
748
|
AVG,
|
|
701
749
|
[
|
|
@@ -735,6 +783,35 @@ const aggregators = mapNew([
|
|
|
735
783
|
],
|
|
736
784
|
],
|
|
737
785
|
]);
|
|
786
|
+
const getAggregateValue = (
|
|
787
|
+
aggregateValue,
|
|
788
|
+
oldLength,
|
|
789
|
+
newValues,
|
|
790
|
+
changedValues,
|
|
791
|
+
aggregators,
|
|
792
|
+
force = false,
|
|
793
|
+
) => {
|
|
794
|
+
if (collIsEmpty(newValues)) {
|
|
795
|
+
return void 0;
|
|
796
|
+
}
|
|
797
|
+
const [aggregate, aggregateAdd, aggregateRemove, aggregateReplace] =
|
|
798
|
+
aggregators;
|
|
799
|
+
force ||= isUndefined(aggregateValue);
|
|
800
|
+
collForEach(changedValues, ([oldValue, newValue]) => {
|
|
801
|
+
if (!force) {
|
|
802
|
+
aggregateValue = isUndefined(oldValue)
|
|
803
|
+
? aggregateAdd?.(aggregateValue, newValue, oldLength++)
|
|
804
|
+
: isUndefined(newValue)
|
|
805
|
+
? aggregateRemove?.(aggregateValue, oldValue, oldLength--)
|
|
806
|
+
: aggregateReplace?.(aggregateValue, newValue, oldValue, oldLength);
|
|
807
|
+
force ||= isUndefined(aggregateValue);
|
|
808
|
+
}
|
|
809
|
+
});
|
|
810
|
+
return force
|
|
811
|
+
? aggregate(collValues(newValues), collSize(newValues))
|
|
812
|
+
: aggregateValue;
|
|
813
|
+
};
|
|
814
|
+
|
|
738
815
|
const createMetrics = getCreateFunction((store) => {
|
|
739
816
|
const metricListeners = mapNew();
|
|
740
817
|
const [
|
|
@@ -745,7 +822,8 @@ const createMetrics = getCreateFunction((store) => {
|
|
|
745
822
|
getTableId,
|
|
746
823
|
getMetric,
|
|
747
824
|
setMetric,
|
|
748
|
-
|
|
825
|
+
,
|
|
826
|
+
setDefinitionAndListen,
|
|
749
827
|
delDefinition,
|
|
750
828
|
destroy,
|
|
751
829
|
] = getDefinableFunctions(store, getUndefined, (value) =>
|
|
@@ -769,38 +847,29 @@ const createMetrics = getCreateFunction((store) => {
|
|
|
769
847
|
aggregateRemove,
|
|
770
848
|
aggregateReplace,
|
|
771
849
|
) => {
|
|
772
|
-
const
|
|
850
|
+
const aggregators = isFunction(aggregate)
|
|
773
851
|
? [aggregate, aggregateAdd, aggregateRemove, aggregateReplace]
|
|
774
|
-
: mapGet(
|
|
775
|
-
|
|
852
|
+
: mapGet(numericAggregators, aggregate) ??
|
|
853
|
+
mapGet(numericAggregators, SUM);
|
|
854
|
+
setDefinitionAndListen(
|
|
776
855
|
metricId,
|
|
777
856
|
tableId,
|
|
778
857
|
(change, changedNumbers, _changedSortKeys, numbers, _sortKeys, force) => {
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
metricAggregators;
|
|
783
|
-
force = force || isUndefined(newMetric);
|
|
784
|
-
collForEach(changedNumbers, ([oldNumber, newNumber]) => {
|
|
785
|
-
if (!force) {
|
|
786
|
-
newMetric = isUndefined(oldNumber)
|
|
787
|
-
? aggregateAdd2?.(newMetric, newNumber, length++)
|
|
788
|
-
: isUndefined(newNumber)
|
|
789
|
-
? aggregateRemove2?.(newMetric, oldNumber, length--)
|
|
790
|
-
: aggregateReplace2?.(newMetric, newNumber, oldNumber, length);
|
|
791
|
-
}
|
|
792
|
-
force = force || isUndefined(newMetric);
|
|
793
|
-
});
|
|
858
|
+
const oldMetric = getMetric(metricId);
|
|
859
|
+
const oldLength = collSize(numbers);
|
|
860
|
+
force ||= isUndefined(oldMetric);
|
|
794
861
|
change();
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
862
|
+
let newMetric = getAggregateValue(
|
|
863
|
+
oldMetric,
|
|
864
|
+
oldLength,
|
|
865
|
+
numbers,
|
|
866
|
+
changedNumbers,
|
|
867
|
+
aggregators,
|
|
868
|
+
force,
|
|
869
|
+
);
|
|
800
870
|
if (!isFiniteNumber(newMetric)) {
|
|
801
871
|
newMetric = void 0;
|
|
802
872
|
}
|
|
803
|
-
const oldMetric = getMetric(metricId);
|
|
804
873
|
if (newMetric != oldMetric) {
|
|
805
874
|
setMetric(metricId, newMetric);
|
|
806
875
|
callListeners(metricListeners, [metricId], newMetric, oldMetric);
|
|
@@ -858,7 +927,7 @@ const createCustomPersister = (
|
|
|
858
927
|
loads++;
|
|
859
928
|
}
|
|
860
929
|
const body = await getPersisted();
|
|
861
|
-
if (!isUndefined(body) && body !=
|
|
930
|
+
if (!isUndefined(body) && body != EMPTY_STRING) {
|
|
862
931
|
store.setJson(body);
|
|
863
932
|
} else {
|
|
864
933
|
store.setTables(initialTables);
|
|
@@ -1011,6 +1080,574 @@ const createRemotePersister = (
|
|
|
1011
1080
|
);
|
|
1012
1081
|
};
|
|
1013
1082
|
|
|
1083
|
+
const createQueries = getCreateFunction((store) => {
|
|
1084
|
+
const [
|
|
1085
|
+
getStore,
|
|
1086
|
+
getQueryIds,
|
|
1087
|
+
forEachQuery,
|
|
1088
|
+
hasQuery,
|
|
1089
|
+
getTableId,
|
|
1090
|
+
,
|
|
1091
|
+
,
|
|
1092
|
+
setDefinition,
|
|
1093
|
+
,
|
|
1094
|
+
delDefinition,
|
|
1095
|
+
destroy,
|
|
1096
|
+
addStoreListeners,
|
|
1097
|
+
delStoreListeners,
|
|
1098
|
+
] = getDefinableFunctions(store, () => true, getUndefined);
|
|
1099
|
+
const preStore1 = store.createStore();
|
|
1100
|
+
const preStore2 = store.createStore();
|
|
1101
|
+
const resultStore = store.createStore();
|
|
1102
|
+
const preStoreListenerIds = mapNew();
|
|
1103
|
+
const addPreStoreListener = (preStore, queryId, ...listenerIds) =>
|
|
1104
|
+
arrayForEach(listenerIds, (listenerId) =>
|
|
1105
|
+
setAdd(
|
|
1106
|
+
mapEnsure(
|
|
1107
|
+
mapEnsure(preStoreListenerIds, queryId, mapNew),
|
|
1108
|
+
preStore,
|
|
1109
|
+
setNew,
|
|
1110
|
+
),
|
|
1111
|
+
listenerId,
|
|
1112
|
+
),
|
|
1113
|
+
);
|
|
1114
|
+
const synchronizeTransactions = (queryId, fromStore, toStore) =>
|
|
1115
|
+
addStoreListeners(
|
|
1116
|
+
queryId,
|
|
1117
|
+
0,
|
|
1118
|
+
fromStore.addWillFinishTransactionListener(toStore.startTransaction),
|
|
1119
|
+
fromStore.addDidFinishTransactionListener(() =>
|
|
1120
|
+
toStore.finishTransaction(),
|
|
1121
|
+
),
|
|
1122
|
+
);
|
|
1123
|
+
const setQueryDefinition = (queryId, tableId, build) => {
|
|
1124
|
+
setDefinition(queryId, tableId);
|
|
1125
|
+
preStore1.delTable(queryId);
|
|
1126
|
+
preStore2.delTable(queryId);
|
|
1127
|
+
resultStore.delTable(queryId);
|
|
1128
|
+
let offsetLimit;
|
|
1129
|
+
const selectEntries = [];
|
|
1130
|
+
const joinEntries = [[null, [tableId, null, null, [], mapNew()]]];
|
|
1131
|
+
const wheres = [];
|
|
1132
|
+
const groupEntries = [];
|
|
1133
|
+
const havings = [];
|
|
1134
|
+
const orders = [];
|
|
1135
|
+
const select = (arg1, arg2) => {
|
|
1136
|
+
const selectEntry = isFunction(arg1)
|
|
1137
|
+
? [arrayLength(selectEntries) + EMPTY_STRING, arg1]
|
|
1138
|
+
: [
|
|
1139
|
+
isUndefined(arg2) ? arg1 : arg2,
|
|
1140
|
+
(getTableCell) => getTableCell(arg1, arg2),
|
|
1141
|
+
];
|
|
1142
|
+
arrayPush(selectEntries, selectEntry);
|
|
1143
|
+
return {as: (selectedCellId) => (selectEntry[0] = selectedCellId)};
|
|
1144
|
+
};
|
|
1145
|
+
const join = (joinedTableId, arg1, arg2) => {
|
|
1146
|
+
const fromIntermediateJoinedTableId =
|
|
1147
|
+
isUndefined(arg2) || isFunction(arg1) ? null : arg1;
|
|
1148
|
+
const onArg = isUndefined(fromIntermediateJoinedTableId) ? arg1 : arg2;
|
|
1149
|
+
const joinEntry = [
|
|
1150
|
+
joinedTableId,
|
|
1151
|
+
[
|
|
1152
|
+
joinedTableId,
|
|
1153
|
+
fromIntermediateJoinedTableId,
|
|
1154
|
+
isFunction(onArg) ? onArg : (getCell) => getCell(onArg),
|
|
1155
|
+
[],
|
|
1156
|
+
mapNew(),
|
|
1157
|
+
],
|
|
1158
|
+
];
|
|
1159
|
+
arrayPush(joinEntries, joinEntry);
|
|
1160
|
+
return {as: (joinedTableId2) => (joinEntry[0] = joinedTableId2)};
|
|
1161
|
+
};
|
|
1162
|
+
const where = (arg1, arg2, arg3) =>
|
|
1163
|
+
arrayPush(
|
|
1164
|
+
wheres,
|
|
1165
|
+
isFunction(arg1)
|
|
1166
|
+
? arg1
|
|
1167
|
+
: isUndefined(arg3)
|
|
1168
|
+
? (getTableCell) => getTableCell(arg1) === arg2
|
|
1169
|
+
: (getTableCell) => getTableCell(arg1, arg2) === arg3,
|
|
1170
|
+
);
|
|
1171
|
+
const group = (
|
|
1172
|
+
selectedCellId,
|
|
1173
|
+
aggregate,
|
|
1174
|
+
aggregateAdd,
|
|
1175
|
+
aggregateRemove,
|
|
1176
|
+
aggregateReplace,
|
|
1177
|
+
) => {
|
|
1178
|
+
const groupEntry = [
|
|
1179
|
+
selectedCellId,
|
|
1180
|
+
[
|
|
1181
|
+
selectedCellId,
|
|
1182
|
+
isFunction(aggregate)
|
|
1183
|
+
? [aggregate, aggregateAdd, aggregateRemove, aggregateReplace]
|
|
1184
|
+
: mapGet(numericAggregators, aggregate) ?? [
|
|
1185
|
+
(_cells, length) => length,
|
|
1186
|
+
],
|
|
1187
|
+
],
|
|
1188
|
+
];
|
|
1189
|
+
arrayPush(groupEntries, groupEntry);
|
|
1190
|
+
return {as: (groupedCellId) => (groupEntry[0] = groupedCellId)};
|
|
1191
|
+
};
|
|
1192
|
+
const having = (arg1, arg2) =>
|
|
1193
|
+
arrayPush(
|
|
1194
|
+
havings,
|
|
1195
|
+
isFunction(arg1)
|
|
1196
|
+
? arg1
|
|
1197
|
+
: (getSelectedOrGroupedCell) =>
|
|
1198
|
+
getSelectedOrGroupedCell(arg1) === arg2,
|
|
1199
|
+
);
|
|
1200
|
+
const order = (arg1, descending) =>
|
|
1201
|
+
arrayPush(orders, [
|
|
1202
|
+
isFunction(arg1)
|
|
1203
|
+
? arg1
|
|
1204
|
+
: (getSelectedOrGroupedCell) => getSelectedOrGroupedCell(arg1) ?? 0,
|
|
1205
|
+
descending,
|
|
1206
|
+
]);
|
|
1207
|
+
const limit = (arg1, arg2) => {
|
|
1208
|
+
offsetLimit = isUndefined(arg2) ? [0, arg1] : [arg1, arg2];
|
|
1209
|
+
};
|
|
1210
|
+
build({select, join, where, group, having, order, limit});
|
|
1211
|
+
const selects = mapNew(selectEntries);
|
|
1212
|
+
if (collIsEmpty(selects)) {
|
|
1213
|
+
return queries;
|
|
1214
|
+
}
|
|
1215
|
+
const joins = mapNew(joinEntries);
|
|
1216
|
+
mapForEach(joins, (asTableId, [, fromAsTableId]) =>
|
|
1217
|
+
ifNotUndefined(mapGet(joins, fromAsTableId), ({3: toAsTableIds}) =>
|
|
1218
|
+
isUndefined(asTableId) ? 0 : arrayPush(toAsTableIds, asTableId),
|
|
1219
|
+
),
|
|
1220
|
+
);
|
|
1221
|
+
const groups = mapNew(groupEntries);
|
|
1222
|
+
let selectJoinWhereStore = preStore1;
|
|
1223
|
+
let groupHavingStore = preStore2;
|
|
1224
|
+
if (arrayIsEmpty(orders) && isUndefined(offsetLimit)) {
|
|
1225
|
+
groupHavingStore = resultStore;
|
|
1226
|
+
} else {
|
|
1227
|
+
synchronizeTransactions(queryId, groupHavingStore, resultStore);
|
|
1228
|
+
const groupRowIdSorter = (rowId1, rowId2) => {
|
|
1229
|
+
const sortKeys1 = mapGet(sortKeysByGroupRowId, rowId1) ?? [];
|
|
1230
|
+
const sortKeys2 = mapGet(sortKeysByGroupRowId, rowId2) ?? [];
|
|
1231
|
+
const orderIndex = orders.findIndex(
|
|
1232
|
+
(_order, index) => sortKeys1[index] !== sortKeys2[index],
|
|
1233
|
+
);
|
|
1234
|
+
return orderIndex < 0
|
|
1235
|
+
? 0
|
|
1236
|
+
: defaultSorter(sortKeys1[orderIndex], sortKeys2[orderIndex]) *
|
|
1237
|
+
(orders[orderIndex][1] ? -1 : 1);
|
|
1238
|
+
};
|
|
1239
|
+
const sortKeysByGroupRowId = mapNew();
|
|
1240
|
+
const sortedGroupRowIds = mapNew();
|
|
1241
|
+
addPreStoreListener(
|
|
1242
|
+
groupHavingStore,
|
|
1243
|
+
queryId,
|
|
1244
|
+
arrayIsEmpty(orders)
|
|
1245
|
+
? groupHavingStore.addRowIdsListener(queryId, () =>
|
|
1246
|
+
collClear(sortedGroupRowIds),
|
|
1247
|
+
)
|
|
1248
|
+
: groupHavingStore.addRowListener(
|
|
1249
|
+
queryId,
|
|
1250
|
+
null,
|
|
1251
|
+
(_store, _tableId, groupRowId) => {
|
|
1252
|
+
let newSortKeys = null;
|
|
1253
|
+
if (groupHavingStore.hasRow(queryId, groupRowId)) {
|
|
1254
|
+
const oldSortKeys =
|
|
1255
|
+
mapGet(sortKeysByGroupRowId, groupRowId) ?? [];
|
|
1256
|
+
const groupRow = groupHavingStore.getRow(queryId, groupRowId);
|
|
1257
|
+
const getCell = (getSelectedOrGroupedCell) =>
|
|
1258
|
+
groupRow[getSelectedOrGroupedCell];
|
|
1259
|
+
newSortKeys = arrayMap(orders, ([getSortKey]) =>
|
|
1260
|
+
getSortKey(getCell, groupRowId),
|
|
1261
|
+
);
|
|
1262
|
+
if (arrayIsEqual(oldSortKeys, newSortKeys)) {
|
|
1263
|
+
if (mapGet(sortedGroupRowIds, groupRowId)) {
|
|
1264
|
+
resultStore.setRow(queryId, groupRowId, groupRow);
|
|
1265
|
+
}
|
|
1266
|
+
return;
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
mapSet(sortKeysByGroupRowId, groupRowId, newSortKeys);
|
|
1270
|
+
collClear(sortedGroupRowIds);
|
|
1271
|
+
},
|
|
1272
|
+
),
|
|
1273
|
+
groupHavingStore.addTableListener(queryId, () => {
|
|
1274
|
+
if (collIsEmpty(sortedGroupRowIds)) {
|
|
1275
|
+
resultStore.delTable(queryId);
|
|
1276
|
+
if (groupHavingStore.hasTable(queryId)) {
|
|
1277
|
+
const groupTable = groupHavingStore.getTable(queryId);
|
|
1278
|
+
arrayForEach(
|
|
1279
|
+
arraySort(objIds(groupTable), groupRowIdSorter),
|
|
1280
|
+
(id) => mapSet(sortedGroupRowIds, id, 0),
|
|
1281
|
+
);
|
|
1282
|
+
arrayForEach(
|
|
1283
|
+
ifNotUndefined(
|
|
1284
|
+
offsetLimit,
|
|
1285
|
+
([offset, limit2]) =>
|
|
1286
|
+
arraySlice(
|
|
1287
|
+
mapKeys(sortedGroupRowIds),
|
|
1288
|
+
offset,
|
|
1289
|
+
offset + limit2,
|
|
1290
|
+
),
|
|
1291
|
+
() => mapKeys(sortedGroupRowIds),
|
|
1292
|
+
),
|
|
1293
|
+
(groupRowId) => {
|
|
1294
|
+
resultStore.setRow(
|
|
1295
|
+
queryId,
|
|
1296
|
+
groupRowId,
|
|
1297
|
+
groupTable[groupRowId],
|
|
1298
|
+
);
|
|
1299
|
+
mapSet(sortedGroupRowIds, groupRowId, 1);
|
|
1300
|
+
},
|
|
1301
|
+
);
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
}),
|
|
1305
|
+
);
|
|
1306
|
+
}
|
|
1307
|
+
if (collIsEmpty(groups) && arrayIsEmpty(havings)) {
|
|
1308
|
+
selectJoinWhereStore = groupHavingStore;
|
|
1309
|
+
} else {
|
|
1310
|
+
synchronizeTransactions(queryId, selectJoinWhereStore, groupHavingStore);
|
|
1311
|
+
const groupedSelectedCellIds = mapNew();
|
|
1312
|
+
mapForEach(groups, (groupedCellId, [selectedCellId, aggregators]) =>
|
|
1313
|
+
setAdd(mapEnsure(groupedSelectedCellIds, selectedCellId, setNew), [
|
|
1314
|
+
groupedCellId,
|
|
1315
|
+
aggregators,
|
|
1316
|
+
]),
|
|
1317
|
+
);
|
|
1318
|
+
const groupBySelectedCellIds = setNew();
|
|
1319
|
+
mapForEach(selects, (selectedCellId) =>
|
|
1320
|
+
collHas(groupedSelectedCellIds, selectedCellId)
|
|
1321
|
+
? 0
|
|
1322
|
+
: setAdd(groupBySelectedCellIds, selectedCellId),
|
|
1323
|
+
);
|
|
1324
|
+
const tree = mapNew();
|
|
1325
|
+
const writeGroupRow = (
|
|
1326
|
+
leaf,
|
|
1327
|
+
changedGroupedSelectedCells,
|
|
1328
|
+
selectedRowId,
|
|
1329
|
+
forceRemove,
|
|
1330
|
+
) =>
|
|
1331
|
+
ifNotUndefined(
|
|
1332
|
+
leaf,
|
|
1333
|
+
([selectedCells, selectedRowIds, groupRowId, groupRow]) => {
|
|
1334
|
+
mapForEach(
|
|
1335
|
+
changedGroupedSelectedCells,
|
|
1336
|
+
(selectedCellId, [newCell]) => {
|
|
1337
|
+
const selectedCell = mapEnsure(
|
|
1338
|
+
selectedCells,
|
|
1339
|
+
selectedCellId,
|
|
1340
|
+
mapNew,
|
|
1341
|
+
);
|
|
1342
|
+
const oldLeafCell = mapGet(selectedCell, selectedRowId);
|
|
1343
|
+
const newLeafCell = forceRemove ? void 0 : newCell;
|
|
1344
|
+
if (oldLeafCell !== newLeafCell) {
|
|
1345
|
+
const oldNewSet = setNew([[oldLeafCell, newLeafCell]]);
|
|
1346
|
+
const oldLength = collSize(selectedCell);
|
|
1347
|
+
mapSet(selectedCell, selectedRowId, newLeafCell);
|
|
1348
|
+
collForEach(
|
|
1349
|
+
mapGet(groupedSelectedCellIds, selectedCellId),
|
|
1350
|
+
([groupedCellId, aggregators]) => {
|
|
1351
|
+
const aggregateValue = getAggregateValue(
|
|
1352
|
+
groupRow[groupedCellId],
|
|
1353
|
+
oldLength,
|
|
1354
|
+
selectedCell,
|
|
1355
|
+
oldNewSet,
|
|
1356
|
+
aggregators,
|
|
1357
|
+
);
|
|
1358
|
+
groupRow[groupedCellId] = isUndefined(
|
|
1359
|
+
getCellType(aggregateValue),
|
|
1360
|
+
)
|
|
1361
|
+
? null
|
|
1362
|
+
: aggregateValue;
|
|
1363
|
+
},
|
|
1364
|
+
);
|
|
1365
|
+
}
|
|
1366
|
+
},
|
|
1367
|
+
);
|
|
1368
|
+
(collIsEmpty(selectedRowIds) ||
|
|
1369
|
+
!arrayEvery(havings, (having2) =>
|
|
1370
|
+
having2((cellId) => groupRow[cellId]),
|
|
1371
|
+
)
|
|
1372
|
+
? groupHavingStore.delRow
|
|
1373
|
+
: groupHavingStore.setRow)(queryId, groupRowId, groupRow);
|
|
1374
|
+
},
|
|
1375
|
+
);
|
|
1376
|
+
addPreStoreListener(
|
|
1377
|
+
selectJoinWhereStore,
|
|
1378
|
+
queryId,
|
|
1379
|
+
selectJoinWhereStore.addRowListener(
|
|
1380
|
+
queryId,
|
|
1381
|
+
null,
|
|
1382
|
+
(_store, _tableId, selectedRowId, getCellChange) => {
|
|
1383
|
+
const oldPath = [];
|
|
1384
|
+
const newPath = [];
|
|
1385
|
+
const changedGroupedSelectedCells = mapNew();
|
|
1386
|
+
const rowExists = selectJoinWhereStore.hasRow(
|
|
1387
|
+
queryId,
|
|
1388
|
+
selectedRowId,
|
|
1389
|
+
);
|
|
1390
|
+
let changedLeaf = !rowExists;
|
|
1391
|
+
collForEach(groupBySelectedCellIds, (selectedCellId) => {
|
|
1392
|
+
const [changed, oldCell, newCell] = getCellChange(
|
|
1393
|
+
queryId,
|
|
1394
|
+
selectedRowId,
|
|
1395
|
+
selectedCellId,
|
|
1396
|
+
);
|
|
1397
|
+
arrayPush(oldPath, oldCell);
|
|
1398
|
+
arrayPush(newPath, newCell);
|
|
1399
|
+
changedLeaf ||= changed;
|
|
1400
|
+
});
|
|
1401
|
+
mapForEach(groupedSelectedCellIds, (selectedCellId) => {
|
|
1402
|
+
const [changed, , newCell] = getCellChange(
|
|
1403
|
+
queryId,
|
|
1404
|
+
selectedRowId,
|
|
1405
|
+
selectedCellId,
|
|
1406
|
+
);
|
|
1407
|
+
if (changedLeaf || changed) {
|
|
1408
|
+
mapSet(changedGroupedSelectedCells, selectedCellId, [newCell]);
|
|
1409
|
+
}
|
|
1410
|
+
});
|
|
1411
|
+
if (changedLeaf) {
|
|
1412
|
+
writeGroupRow(
|
|
1413
|
+
visitTree(
|
|
1414
|
+
tree,
|
|
1415
|
+
oldPath,
|
|
1416
|
+
void 0,
|
|
1417
|
+
([, selectedRowIds, groupRowId]) => {
|
|
1418
|
+
collDel(selectedRowIds, selectedRowId);
|
|
1419
|
+
if (collIsEmpty(selectedRowIds)) {
|
|
1420
|
+
groupHavingStore.delRow(queryId, groupRowId);
|
|
1421
|
+
return 1;
|
|
1422
|
+
}
|
|
1423
|
+
},
|
|
1424
|
+
),
|
|
1425
|
+
changedGroupedSelectedCells,
|
|
1426
|
+
selectedRowId,
|
|
1427
|
+
1,
|
|
1428
|
+
);
|
|
1429
|
+
}
|
|
1430
|
+
if (rowExists) {
|
|
1431
|
+
writeGroupRow(
|
|
1432
|
+
visitTree(
|
|
1433
|
+
tree,
|
|
1434
|
+
newPath,
|
|
1435
|
+
() => {
|
|
1436
|
+
const groupRow = {};
|
|
1437
|
+
collForEach(
|
|
1438
|
+
groupBySelectedCellIds,
|
|
1439
|
+
(selectedCellId) =>
|
|
1440
|
+
(groupRow[selectedCellId] =
|
|
1441
|
+
selectJoinWhereStore.getCell(
|
|
1442
|
+
queryId,
|
|
1443
|
+
selectedRowId,
|
|
1444
|
+
selectedCellId,
|
|
1445
|
+
)),
|
|
1446
|
+
);
|
|
1447
|
+
return [
|
|
1448
|
+
mapNew(),
|
|
1449
|
+
setNew(),
|
|
1450
|
+
groupHavingStore.addRow(queryId, groupRow, 1),
|
|
1451
|
+
groupRow,
|
|
1452
|
+
];
|
|
1453
|
+
},
|
|
1454
|
+
([, selectedRowIds]) => {
|
|
1455
|
+
setAdd(selectedRowIds, selectedRowId);
|
|
1456
|
+
},
|
|
1457
|
+
),
|
|
1458
|
+
changedGroupedSelectedCells,
|
|
1459
|
+
selectedRowId,
|
|
1460
|
+
);
|
|
1461
|
+
}
|
|
1462
|
+
},
|
|
1463
|
+
),
|
|
1464
|
+
);
|
|
1465
|
+
}
|
|
1466
|
+
synchronizeTransactions(queryId, store, selectJoinWhereStore);
|
|
1467
|
+
const writeSelectRow = (rootRowId) => {
|
|
1468
|
+
const getTableCell = (arg1, arg2) =>
|
|
1469
|
+
store.getCell(
|
|
1470
|
+
...(isUndefined(arg2)
|
|
1471
|
+
? [tableId, rootRowId, arg1]
|
|
1472
|
+
: arg1 === tableId
|
|
1473
|
+
? [tableId, rootRowId, arg2]
|
|
1474
|
+
: [
|
|
1475
|
+
mapGet(joins, arg1)?.[0],
|
|
1476
|
+
mapGet(mapGet(joins, arg1)?.[4], rootRowId)?.[0],
|
|
1477
|
+
arg2,
|
|
1478
|
+
]),
|
|
1479
|
+
);
|
|
1480
|
+
selectJoinWhereStore.transaction(() =>
|
|
1481
|
+
arrayEvery(wheres, (where2) => where2(getTableCell))
|
|
1482
|
+
? mapForEach(selects, (asCellId, tableCellGetter) =>
|
|
1483
|
+
setOrDelCell(
|
|
1484
|
+
selectJoinWhereStore,
|
|
1485
|
+
queryId,
|
|
1486
|
+
rootRowId,
|
|
1487
|
+
asCellId,
|
|
1488
|
+
tableCellGetter(getTableCell, rootRowId),
|
|
1489
|
+
),
|
|
1490
|
+
)
|
|
1491
|
+
: selectJoinWhereStore.delRow(queryId, rootRowId),
|
|
1492
|
+
);
|
|
1493
|
+
};
|
|
1494
|
+
const listenToTable = (rootRowId, tableId2, rowId, joinedTableIds2) => {
|
|
1495
|
+
const getCell = (cellId) => store.getCell(tableId2, rowId, cellId);
|
|
1496
|
+
arrayForEach(joinedTableIds2, (remoteAsTableId) => {
|
|
1497
|
+
const [realJoinedTableId, , on, nextJoinedTableIds, remoteIdPair] =
|
|
1498
|
+
mapGet(joins, remoteAsTableId);
|
|
1499
|
+
const remoteRowId = on?.(getCell, rootRowId);
|
|
1500
|
+
const [previousRemoteRowId, previousRemoteListenerId] =
|
|
1501
|
+
mapGet(remoteIdPair, rootRowId) ?? [];
|
|
1502
|
+
if (remoteRowId != previousRemoteRowId) {
|
|
1503
|
+
if (!isUndefined(previousRemoteListenerId)) {
|
|
1504
|
+
delStoreListeners(queryId, previousRemoteListenerId);
|
|
1505
|
+
}
|
|
1506
|
+
mapSet(
|
|
1507
|
+
remoteIdPair,
|
|
1508
|
+
rootRowId,
|
|
1509
|
+
isUndefined(remoteRowId)
|
|
1510
|
+
? null
|
|
1511
|
+
: [
|
|
1512
|
+
remoteRowId,
|
|
1513
|
+
...addStoreListeners(
|
|
1514
|
+
queryId,
|
|
1515
|
+
1,
|
|
1516
|
+
store.addRowListener(realJoinedTableId, remoteRowId, () =>
|
|
1517
|
+
listenToTable(
|
|
1518
|
+
rootRowId,
|
|
1519
|
+
realJoinedTableId,
|
|
1520
|
+
remoteRowId,
|
|
1521
|
+
nextJoinedTableIds,
|
|
1522
|
+
),
|
|
1523
|
+
),
|
|
1524
|
+
),
|
|
1525
|
+
],
|
|
1526
|
+
);
|
|
1527
|
+
}
|
|
1528
|
+
});
|
|
1529
|
+
writeSelectRow(rootRowId);
|
|
1530
|
+
};
|
|
1531
|
+
const {3: joinedTableIds} = mapGet(joins, null);
|
|
1532
|
+
selectJoinWhereStore.transaction(() =>
|
|
1533
|
+
addStoreListeners(
|
|
1534
|
+
queryId,
|
|
1535
|
+
1,
|
|
1536
|
+
store.addRowListener(tableId, null, (_store, _tableId, rootRowId) => {
|
|
1537
|
+
if (store.hasRow(tableId, rootRowId)) {
|
|
1538
|
+
listenToTable(rootRowId, tableId, rootRowId, joinedTableIds);
|
|
1539
|
+
} else {
|
|
1540
|
+
selectJoinWhereStore.delRow(queryId, rootRowId);
|
|
1541
|
+
collForEach(joins, ({4: idsByRootRowId}) =>
|
|
1542
|
+
ifNotUndefined(
|
|
1543
|
+
mapGet(idsByRootRowId, rootRowId),
|
|
1544
|
+
([, listenerId]) => {
|
|
1545
|
+
delStoreListeners(queryId, listenerId);
|
|
1546
|
+
mapSet(idsByRootRowId, rootRowId);
|
|
1547
|
+
},
|
|
1548
|
+
),
|
|
1549
|
+
);
|
|
1550
|
+
}
|
|
1551
|
+
}),
|
|
1552
|
+
),
|
|
1553
|
+
);
|
|
1554
|
+
return queries;
|
|
1555
|
+
};
|
|
1556
|
+
const delQueryDefinition = (queryId) => {
|
|
1557
|
+
mapForEach(mapGet(preStoreListenerIds, queryId), (preStore, listenerIds) =>
|
|
1558
|
+
collForEach(listenerIds, (listenerId) =>
|
|
1559
|
+
preStore.delListener(listenerId),
|
|
1560
|
+
),
|
|
1561
|
+
);
|
|
1562
|
+
delDefinition(queryId);
|
|
1563
|
+
return queries;
|
|
1564
|
+
};
|
|
1565
|
+
const getResultTable = (queryId) => resultStore.getTable(queryId);
|
|
1566
|
+
const getResultRowIds = (queryId) => resultStore.getRowIds(queryId);
|
|
1567
|
+
const getResultRow = (queryId, rowId) => resultStore.getRow(queryId, rowId);
|
|
1568
|
+
const getResultCellIds = (queryId, rowId) =>
|
|
1569
|
+
resultStore.getCellIds(queryId, rowId);
|
|
1570
|
+
const getResultCell = (queryId, rowId, cellId) =>
|
|
1571
|
+
resultStore.getCell(queryId, rowId, cellId);
|
|
1572
|
+
const hasResultTable = (queryId) => resultStore.hasTable(queryId);
|
|
1573
|
+
const hasResultRow = (queryId, rowId) => resultStore.hasRow(queryId, rowId);
|
|
1574
|
+
const hasResultCell = (queryId, rowId, cellId) =>
|
|
1575
|
+
resultStore.hasCell(queryId, rowId, cellId);
|
|
1576
|
+
const forEachResultTable = (tableCallback) =>
|
|
1577
|
+
resultStore.forEachTable(tableCallback);
|
|
1578
|
+
const forEachResultRow = (queryId, rowCallback) =>
|
|
1579
|
+
resultStore.forEachRow(queryId, rowCallback);
|
|
1580
|
+
const forEachResultCell = (queryId, rowId, cellCallback) =>
|
|
1581
|
+
resultStore.forEachCell(queryId, rowId, cellCallback);
|
|
1582
|
+
const addResultTableListener = (queryId, listener) =>
|
|
1583
|
+
resultStore.addTableListener(queryId, (_store, ...args) =>
|
|
1584
|
+
listener(queries, ...args),
|
|
1585
|
+
);
|
|
1586
|
+
const addResultRowIdsListener = (queryId, listener, trackReorder) =>
|
|
1587
|
+
resultStore.addRowIdsListener(
|
|
1588
|
+
queryId,
|
|
1589
|
+
(_store, ...args) => listener(queries, ...args),
|
|
1590
|
+
trackReorder,
|
|
1591
|
+
);
|
|
1592
|
+
const addResultRowListener = (queryId, rowId, listener) =>
|
|
1593
|
+
resultStore.addRowListener(queryId, rowId, (_store, ...args) =>
|
|
1594
|
+
listener(queries, ...args),
|
|
1595
|
+
);
|
|
1596
|
+
const addResultCellIdsListener = (queryId, rowId, listener, trackReorder) =>
|
|
1597
|
+
resultStore.addCellIdsListener(
|
|
1598
|
+
queryId,
|
|
1599
|
+
rowId,
|
|
1600
|
+
(_store, ...args) => listener(queries, ...args),
|
|
1601
|
+
trackReorder,
|
|
1602
|
+
);
|
|
1603
|
+
const addResultCellListener = (queryId, rowId, cellId, listener) =>
|
|
1604
|
+
resultStore.addCellListener(queryId, rowId, cellId, (_store, ...args) =>
|
|
1605
|
+
listener(queries, ...args),
|
|
1606
|
+
);
|
|
1607
|
+
const delListener = (listenerId) => {
|
|
1608
|
+
resultStore.delListener(listenerId);
|
|
1609
|
+
return queries;
|
|
1610
|
+
};
|
|
1611
|
+
const getListenerStats = () => {
|
|
1612
|
+
const {
|
|
1613
|
+
tables: _1,
|
|
1614
|
+
tableIds: _2,
|
|
1615
|
+
transaction: _3,
|
|
1616
|
+
...stats
|
|
1617
|
+
} = resultStore.getListenerStats();
|
|
1618
|
+
return stats;
|
|
1619
|
+
};
|
|
1620
|
+
const queries = {
|
|
1621
|
+
setQueryDefinition,
|
|
1622
|
+
delQueryDefinition,
|
|
1623
|
+
getStore,
|
|
1624
|
+
getQueryIds,
|
|
1625
|
+
forEachQuery,
|
|
1626
|
+
hasQuery,
|
|
1627
|
+
getTableId,
|
|
1628
|
+
getResultTable,
|
|
1629
|
+
getResultRowIds,
|
|
1630
|
+
getResultRow,
|
|
1631
|
+
getResultCellIds,
|
|
1632
|
+
getResultCell,
|
|
1633
|
+
hasResultTable,
|
|
1634
|
+
hasResultRow,
|
|
1635
|
+
hasResultCell,
|
|
1636
|
+
forEachResultTable,
|
|
1637
|
+
forEachResultRow,
|
|
1638
|
+
forEachResultCell,
|
|
1639
|
+
addResultTableListener,
|
|
1640
|
+
addResultRowIdsListener,
|
|
1641
|
+
addResultRowListener,
|
|
1642
|
+
addResultCellIdsListener,
|
|
1643
|
+
addResultCellListener,
|
|
1644
|
+
delListener,
|
|
1645
|
+
destroy,
|
|
1646
|
+
getListenerStats,
|
|
1647
|
+
};
|
|
1648
|
+
return objFreeze(queries);
|
|
1649
|
+
});
|
|
1650
|
+
|
|
1014
1651
|
const createRelationships = getCreateFunction((store) => {
|
|
1015
1652
|
const remoteTableIds = mapNew();
|
|
1016
1653
|
const remoteRowIdListeners = mapNew();
|
|
@@ -1023,8 +1660,9 @@ const createRelationships = getCreateFunction((store) => {
|
|
|
1023
1660
|
hasRelationship,
|
|
1024
1661
|
getLocalTableId,
|
|
1025
1662
|
getRelationship,
|
|
1026
|
-
|
|
1027
|
-
|
|
1663
|
+
,
|
|
1664
|
+
,
|
|
1665
|
+
setDefinitionAndListen,
|
|
1028
1666
|
delDefinition,
|
|
1029
1667
|
destroy,
|
|
1030
1668
|
] = getDefinableFunctions(
|
|
@@ -1071,7 +1709,7 @@ const createRelationships = getCreateFunction((store) => {
|
|
|
1071
1709
|
getRemoteRowId2,
|
|
1072
1710
|
) => {
|
|
1073
1711
|
mapSet(remoteTableIds, relationshipId, remoteTableId);
|
|
1074
|
-
|
|
1712
|
+
setDefinitionAndListen(
|
|
1075
1713
|
relationshipId,
|
|
1076
1714
|
localTableId,
|
|
1077
1715
|
(change, changedRemoteRowIds) => {
|
|
@@ -1197,6 +1835,14 @@ const createRelationships = getCreateFunction((store) => {
|
|
|
1197
1835
|
return objFreeze(relationships);
|
|
1198
1836
|
});
|
|
1199
1837
|
|
|
1838
|
+
const pairNew = (value) => [value, value];
|
|
1839
|
+
const pairCollSize2 = (pair, func = collSize2) => func(pair[0]) + func(pair[1]);
|
|
1840
|
+
const pairCollIsEmpty = (pair) => pairCollSize2(pair) == 0;
|
|
1841
|
+
const pairNewMap = () => [mapNew(), mapNew()];
|
|
1842
|
+
const pair2CollSize2 = (pair2, func = collSize2) =>
|
|
1843
|
+
pairCollSize2(pair2[0], func) + pairCollSize2(pair2[1], func);
|
|
1844
|
+
const pair2NewMap = () => [pairNewMap(), pairNewMap()];
|
|
1845
|
+
|
|
1200
1846
|
const transformMap = (map, toBeLikeObject, setId, delId = mapSet) => {
|
|
1201
1847
|
const idsToDelete = arrayFilter(
|
|
1202
1848
|
mapKeys(map),
|
|
@@ -1208,12 +1854,6 @@ const transformMap = (map, toBeLikeObject, setId, delId = mapSet) => {
|
|
|
1208
1854
|
arrayForEach(idsToDelete, (id) => delId(map, id));
|
|
1209
1855
|
return map;
|
|
1210
1856
|
};
|
|
1211
|
-
const getCellType = (cell) => {
|
|
1212
|
-
const type = getTypeOf(cell);
|
|
1213
|
-
return isTypeStringOrBoolean(type) || (type == NUMBER && isFiniteNumber(cell))
|
|
1214
|
-
? type
|
|
1215
|
-
: void 0;
|
|
1216
|
-
};
|
|
1217
1857
|
const validate = (obj, validateChild, onInvalidObj) => {
|
|
1218
1858
|
if (isUndefined(obj) || !isObject(obj) || objIsEmpty(obj) || objFrozen(obj)) {
|
|
1219
1859
|
onInvalidObj?.();
|
|
@@ -1226,8 +1866,8 @@ const validate = (obj, validateChild, onInvalidObj) => {
|
|
|
1226
1866
|
});
|
|
1227
1867
|
return !objIsEmpty(obj);
|
|
1228
1868
|
};
|
|
1229
|
-
const idsChanged = (
|
|
1230
|
-
mapSet(
|
|
1869
|
+
const idsChanged = (changedIds, id, added) =>
|
|
1870
|
+
mapSet(changedIds, id, mapGet(changedIds, id) == -added ? void 0 : added);
|
|
1231
1871
|
const createStore = () => {
|
|
1232
1872
|
let hasSchema;
|
|
1233
1873
|
let cellsTouched;
|
|
@@ -1241,17 +1881,22 @@ const createStore = () => {
|
|
|
1241
1881
|
const schemaMap = mapNew();
|
|
1242
1882
|
const schemaRowCache = mapNew();
|
|
1243
1883
|
const tablesMap = mapNew();
|
|
1244
|
-
const tablesListeners =
|
|
1245
|
-
const tableIdsListeners =
|
|
1246
|
-
const tableListeners =
|
|
1247
|
-
const rowIdsListeners =
|
|
1248
|
-
const rowListeners =
|
|
1249
|
-
const cellIdsListeners =
|
|
1250
|
-
const cellListeners =
|
|
1251
|
-
const invalidCellListeners =
|
|
1252
|
-
const finishTransactionListeners =
|
|
1253
|
-
const [
|
|
1254
|
-
|
|
1884
|
+
const tablesListeners = pairNewMap();
|
|
1885
|
+
const tableIdsListeners = pair2NewMap();
|
|
1886
|
+
const tableListeners = pairNewMap();
|
|
1887
|
+
const rowIdsListeners = pair2NewMap();
|
|
1888
|
+
const rowListeners = pairNewMap();
|
|
1889
|
+
const cellIdsListeners = pair2NewMap();
|
|
1890
|
+
const cellListeners = pairNewMap();
|
|
1891
|
+
const invalidCellListeners = pairNewMap();
|
|
1892
|
+
const finishTransactionListeners = pairNewMap();
|
|
1893
|
+
const [
|
|
1894
|
+
addListener,
|
|
1895
|
+
callListeners,
|
|
1896
|
+
delListenerImpl,
|
|
1897
|
+
hasListeners,
|
|
1898
|
+
callListenerImpl,
|
|
1899
|
+
] = getListenerFunctions(() => store);
|
|
1255
1900
|
const validateSchema = (schema) =>
|
|
1256
1901
|
validate(schema, (tableSchema) =>
|
|
1257
1902
|
validate(tableSchema, (cellSchema) => {
|
|
@@ -1402,7 +2047,7 @@ const createStore = () => {
|
|
|
1402
2047
|
),
|
|
1403
2048
|
);
|
|
1404
2049
|
const getNewRowId = (tableMap) => {
|
|
1405
|
-
const rowId =
|
|
2050
|
+
const rowId = EMPTY_STRING + nextRowId++;
|
|
1406
2051
|
if (!collHas(tableMap, rowId)) {
|
|
1407
2052
|
return rowId;
|
|
1408
2053
|
}
|
|
@@ -1433,12 +2078,49 @@ const createStore = () => {
|
|
|
1433
2078
|
}
|
|
1434
2079
|
};
|
|
1435
2080
|
const tableIdsChanged = (tableId, added) =>
|
|
1436
|
-
idsChanged(
|
|
2081
|
+
idsChanged(
|
|
2082
|
+
collIsEmpty(changedTableIds)
|
|
2083
|
+
? mapSet(
|
|
2084
|
+
changedTableIds,
|
|
2085
|
+
null,
|
|
2086
|
+
hasListeners(tableIdsListeners[0][1]) ||
|
|
2087
|
+
hasListeners(tableIdsListeners[1][1])
|
|
2088
|
+
? getTableIds()
|
|
2089
|
+
: 0,
|
|
2090
|
+
)
|
|
2091
|
+
: changedTableIds,
|
|
2092
|
+
tableId,
|
|
2093
|
+
added,
|
|
2094
|
+
);
|
|
1437
2095
|
const rowIdsChanged = (tableId, rowId, added) =>
|
|
1438
|
-
idsChanged(
|
|
2096
|
+
idsChanged(
|
|
2097
|
+
mapEnsure(changedRowIds, tableId, () =>
|
|
2098
|
+
mapNew([
|
|
2099
|
+
[
|
|
2100
|
+
null,
|
|
2101
|
+
hasListeners(rowIdsListeners[0][1], [tableId]) ||
|
|
2102
|
+
hasListeners(rowIdsListeners[1][1], [tableId])
|
|
2103
|
+
? getRowIds(tableId)
|
|
2104
|
+
: 0,
|
|
2105
|
+
],
|
|
2106
|
+
]),
|
|
2107
|
+
),
|
|
2108
|
+
rowId,
|
|
2109
|
+
added,
|
|
2110
|
+
);
|
|
1439
2111
|
const cellIdsChanged = (tableId, rowId, cellId, added) =>
|
|
1440
2112
|
idsChanged(
|
|
1441
|
-
mapEnsure(mapEnsure(changedCellIds, tableId, mapNew), rowId,
|
|
2113
|
+
mapEnsure(mapEnsure(changedCellIds, tableId, mapNew), rowId, () =>
|
|
2114
|
+
mapNew([
|
|
2115
|
+
[
|
|
2116
|
+
null,
|
|
2117
|
+
hasListeners(cellIdsListeners[0][1], [tableId, rowId]) ||
|
|
2118
|
+
hasListeners(cellIdsListeners[1][1], [tableId, rowId])
|
|
2119
|
+
? getCellIds(tableId, rowId)
|
|
2120
|
+
: 0,
|
|
2121
|
+
],
|
|
2122
|
+
]),
|
|
2123
|
+
),
|
|
1442
2124
|
cellId,
|
|
1443
2125
|
added,
|
|
1444
2126
|
);
|
|
@@ -1463,7 +2145,7 @@ const createStore = () => {
|
|
|
1463
2145
|
ifNotUndefined(
|
|
1464
2146
|
mapGet(mapGet(mapGet(changedCells, tableId), rowId), cellId),
|
|
1465
2147
|
([oldCell, newCell]) => [true, oldCell, newCell],
|
|
1466
|
-
() => [false, ...
|
|
2148
|
+
() => [false, ...pairNew(getCell(tableId, rowId, cellId))],
|
|
1467
2149
|
);
|
|
1468
2150
|
const callInvalidCellListeners = (mutator) =>
|
|
1469
2151
|
!collIsEmpty(invalidCells) && !collIsEmpty(invalidCellListeners[mutator])
|
|
@@ -1481,17 +2163,29 @@ const createStore = () => {
|
|
|
1481
2163
|
),
|
|
1482
2164
|
)
|
|
1483
2165
|
: 0;
|
|
2166
|
+
const callIdsListenersIfChanged = (listeners, changedIds, getIds, ids) => {
|
|
2167
|
+
if (collSize(changedIds) > 1) {
|
|
2168
|
+
callListeners(listeners[0], ids);
|
|
2169
|
+
callListeners(listeners[1], ids);
|
|
2170
|
+
} else if (
|
|
2171
|
+
!collIsEmpty(changedIds) &&
|
|
2172
|
+
mapGet(changedIds, null) != 0 &&
|
|
2173
|
+
!arrayIsEqual(mapGet(changedIds, null), getIds(...(ids ?? [])))
|
|
2174
|
+
) {
|
|
2175
|
+
callListeners(listeners[1], ids);
|
|
2176
|
+
}
|
|
2177
|
+
};
|
|
1484
2178
|
const callListenersForChanges = (mutator) => {
|
|
1485
2179
|
const emptyIdListeners =
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
2180
|
+
pairCollIsEmpty(cellIdsListeners[mutator]) &&
|
|
2181
|
+
pairCollIsEmpty(rowIdsListeners[mutator]) &&
|
|
2182
|
+
pairCollIsEmpty(tableIdsListeners[mutator]);
|
|
1489
2183
|
const emptyOtherListeners =
|
|
1490
2184
|
collIsEmpty(cellListeners[mutator]) &&
|
|
1491
2185
|
collIsEmpty(rowListeners[mutator]) &&
|
|
1492
2186
|
collIsEmpty(tableListeners[mutator]) &&
|
|
1493
2187
|
collIsEmpty(tablesListeners[mutator]);
|
|
1494
|
-
if (!
|
|
2188
|
+
if (!emptyIdListeners || !emptyOtherListeners) {
|
|
1495
2189
|
const changes = mutator
|
|
1496
2190
|
? [
|
|
1497
2191
|
mapClone(changedTableIds),
|
|
@@ -1502,20 +2196,28 @@ const createStore = () => {
|
|
|
1502
2196
|
: [changedTableIds, changedRowIds, changedCellIds, changedCells];
|
|
1503
2197
|
if (!emptyIdListeners) {
|
|
1504
2198
|
collForEach(changes[2], (rowCellIds, tableId) =>
|
|
1505
|
-
collForEach(rowCellIds, (changedIds, rowId) =>
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
2199
|
+
collForEach(rowCellIds, (changedIds, rowId) =>
|
|
2200
|
+
callIdsListenersIfChanged(
|
|
2201
|
+
cellIdsListeners[mutator],
|
|
2202
|
+
changedIds,
|
|
2203
|
+
getCellIds,
|
|
2204
|
+
[tableId, rowId],
|
|
2205
|
+
),
|
|
2206
|
+
),
|
|
2207
|
+
);
|
|
2208
|
+
collForEach(changes[1], (changedIds, tableId) =>
|
|
2209
|
+
callIdsListenersIfChanged(
|
|
2210
|
+
rowIdsListeners[mutator],
|
|
2211
|
+
changedIds,
|
|
2212
|
+
getRowIds,
|
|
2213
|
+
[tableId],
|
|
2214
|
+
),
|
|
2215
|
+
);
|
|
2216
|
+
callIdsListenersIfChanged(
|
|
2217
|
+
tableIdsListeners[mutator],
|
|
2218
|
+
changes[0],
|
|
2219
|
+
getTableIds,
|
|
1510
2220
|
);
|
|
1511
|
-
collForEach(changes[1], (changedIds, tableId) => {
|
|
1512
|
-
if (!collIsEmpty(changedIds)) {
|
|
1513
|
-
callListeners(rowIdsListeners[mutator], [tableId]);
|
|
1514
|
-
}
|
|
1515
|
-
});
|
|
1516
|
-
if (!collIsEmpty(changes[0])) {
|
|
1517
|
-
callListeners(tableIdsListeners[mutator]);
|
|
1518
|
-
}
|
|
1519
2221
|
}
|
|
1520
2222
|
if (!emptyOtherListeners) {
|
|
1521
2223
|
let tablesChanged;
|
|
@@ -1548,7 +2250,7 @@ const createStore = () => {
|
|
|
1548
2250
|
}
|
|
1549
2251
|
});
|
|
1550
2252
|
if (tablesChanged) {
|
|
1551
|
-
callListeners(tablesListeners[mutator],
|
|
2253
|
+
callListeners(tablesListeners[mutator], void 0, getCellChange);
|
|
1552
2254
|
}
|
|
1553
2255
|
}
|
|
1554
2256
|
}
|
|
@@ -1589,16 +2291,15 @@ const createStore = () => {
|
|
|
1589
2291
|
? setValidRow(tableId, getOrCreateTable(tableId), rowId, row)
|
|
1590
2292
|
: 0,
|
|
1591
2293
|
);
|
|
1592
|
-
const addRow = (tableId, row) =>
|
|
2294
|
+
const addRow = (tableId, row, forceId) =>
|
|
1593
2295
|
transaction(() => {
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
tableId
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
);
|
|
2296
|
+
const isValidRow = validateRow(tableId, void 0, row);
|
|
2297
|
+
const rowId =
|
|
2298
|
+
isValidRow || forceId
|
|
2299
|
+
? getNewRowId(mapGet(tablesMap, tableId))
|
|
2300
|
+
: void 0;
|
|
2301
|
+
if (isValidRow) {
|
|
2302
|
+
setValidRow(tableId, getOrCreateTable(tableId), rowId, row);
|
|
1602
2303
|
}
|
|
1603
2304
|
return rowId;
|
|
1604
2305
|
});
|
|
@@ -1730,12 +2431,12 @@ const createStore = () => {
|
|
|
1730
2431
|
transactions = -1;
|
|
1731
2432
|
cellsTouched = false;
|
|
1732
2433
|
}
|
|
1733
|
-
callListeners(finishTransactionListeners[0],
|
|
2434
|
+
callListeners(finishTransactionListeners[0], void 0, cellsTouched);
|
|
1734
2435
|
callInvalidCellListeners(0);
|
|
1735
2436
|
if (cellsTouched) {
|
|
1736
2437
|
callListenersForChanges(0);
|
|
1737
2438
|
}
|
|
1738
|
-
callListeners(finishTransactionListeners[1],
|
|
2439
|
+
callListeners(finishTransactionListeners[1], void 0, cellsTouched);
|
|
1739
2440
|
transactions = 0;
|
|
1740
2441
|
arrayForEach(
|
|
1741
2442
|
[
|
|
@@ -1769,16 +2470,33 @@ const createStore = () => {
|
|
|
1769
2470
|
mapForEach(mapGet(mapGet(tablesMap, tableId), rowId), cellCallback);
|
|
1770
2471
|
const addTablesListener = (listener, mutator) =>
|
|
1771
2472
|
addListener(listener, tablesListeners[mutator ? 1 : 0]);
|
|
1772
|
-
const addTableIdsListener = (listener, mutator) =>
|
|
1773
|
-
addListener(
|
|
2473
|
+
const addTableIdsListener = (listener, trackReorder, mutator) =>
|
|
2474
|
+
addListener(
|
|
2475
|
+
listener,
|
|
2476
|
+
tableIdsListeners[mutator ? 1 : 0][trackReorder ? 1 : 0],
|
|
2477
|
+
);
|
|
1774
2478
|
const addTableListener = (tableId, listener, mutator) =>
|
|
1775
2479
|
addListener(listener, tableListeners[mutator ? 1 : 0], [tableId]);
|
|
1776
|
-
const addRowIdsListener = (tableId, listener, mutator) =>
|
|
1777
|
-
addListener(
|
|
2480
|
+
const addRowIdsListener = (tableId, listener, trackReorder, mutator) =>
|
|
2481
|
+
addListener(
|
|
2482
|
+
listener,
|
|
2483
|
+
rowIdsListeners[mutator ? 1 : 0][trackReorder ? 1 : 0],
|
|
2484
|
+
[tableId],
|
|
2485
|
+
);
|
|
1778
2486
|
const addRowListener = (tableId, rowId, listener, mutator) =>
|
|
1779
2487
|
addListener(listener, rowListeners[mutator ? 1 : 0], [tableId, rowId]);
|
|
1780
|
-
const addCellIdsListener = (
|
|
1781
|
-
|
|
2488
|
+
const addCellIdsListener = (
|
|
2489
|
+
tableId,
|
|
2490
|
+
rowId,
|
|
2491
|
+
listener,
|
|
2492
|
+
trackReorder,
|
|
2493
|
+
mutator,
|
|
2494
|
+
) =>
|
|
2495
|
+
addListener(
|
|
2496
|
+
listener,
|
|
2497
|
+
cellIdsListeners[mutator ? 1 : 0][trackReorder ? 1 : 0],
|
|
2498
|
+
[tableId, rowId],
|
|
2499
|
+
);
|
|
1782
2500
|
const addCellListener = (tableId, rowId, cellId, listener, mutator) =>
|
|
1783
2501
|
addListener(listener, cellListeners[mutator ? 1 : 0], [
|
|
1784
2502
|
tableId,
|
|
@@ -1797,7 +2515,7 @@ const createStore = () => {
|
|
|
1797
2515
|
addListener(listener, finishTransactionListeners[1]);
|
|
1798
2516
|
const callListener = (listenerId) => {
|
|
1799
2517
|
callListenerImpl(listenerId, [getTableIds, getRowIds, getCellIds], (ids) =>
|
|
1800
|
-
isUndefined(ids[2]) ? [] :
|
|
2518
|
+
isUndefined(ids[2]) ? [] : pairNew(getCell(...ids)),
|
|
1801
2519
|
);
|
|
1802
2520
|
return store;
|
|
1803
2521
|
};
|
|
@@ -1806,15 +2524,15 @@ const createStore = () => {
|
|
|
1806
2524
|
return store;
|
|
1807
2525
|
};
|
|
1808
2526
|
const getListenerStats = () => ({
|
|
1809
|
-
tables:
|
|
1810
|
-
tableIds:
|
|
1811
|
-
table:
|
|
1812
|
-
rowIds:
|
|
1813
|
-
row:
|
|
1814
|
-
cellIds:
|
|
1815
|
-
cell:
|
|
1816
|
-
invalidCell:
|
|
1817
|
-
transaction:
|
|
2527
|
+
tables: pairCollSize2(tablesListeners),
|
|
2528
|
+
tableIds: pair2CollSize2(tableIdsListeners),
|
|
2529
|
+
table: pairCollSize2(tableListeners),
|
|
2530
|
+
rowIds: pair2CollSize2(rowIdsListeners),
|
|
2531
|
+
row: pairCollSize2(rowListeners, collSize3),
|
|
2532
|
+
cellIds: pair2CollSize2(cellIdsListeners, collSize3),
|
|
2533
|
+
cell: pairCollSize2(cellListeners, collSize4),
|
|
2534
|
+
invalidCell: pairCollSize2(invalidCellListeners, collSize4),
|
|
2535
|
+
transaction: pairCollSize2(finishTransactionListeners),
|
|
1818
2536
|
});
|
|
1819
2537
|
const store = {
|
|
1820
2538
|
getTables,
|
|
@@ -1862,6 +2580,7 @@ const createStore = () => {
|
|
|
1862
2580
|
callListener,
|
|
1863
2581
|
delListener,
|
|
1864
2582
|
getListenerStats,
|
|
2583
|
+
createStore,
|
|
1865
2584
|
};
|
|
1866
2585
|
return objFreeze(store);
|
|
1867
2586
|
};
|
|
@@ -1873,6 +2592,7 @@ export {
|
|
|
1873
2592
|
createIndexes,
|
|
1874
2593
|
createLocalPersister,
|
|
1875
2594
|
createMetrics,
|
|
2595
|
+
createQueries,
|
|
1876
2596
|
createRelationships,
|
|
1877
2597
|
createRemotePersister,
|
|
1878
2598
|
createSessionPersister,
|