tinybase 1.3.4 → 2.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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 +3054 -0
- package/lib/debug/queries.js +880 -0
- package/lib/debug/relationships.d.ts +6 -5
- package/lib/debug/relationships.js +102 -66
- 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 +892 -175
- package/lib/debug/ui-react.d.ts +2004 -195
- package/lib/debug/ui-react.js +273 -77
- 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 +3054 -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 +2004 -195
- 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 +22 -22
- 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,571 @@ 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) =>
|
|
1597
|
+
resultStore.addCellIdsListener(queryId, rowId, (_store, ...args) =>
|
|
1598
|
+
listener(queries, ...args),
|
|
1599
|
+
);
|
|
1600
|
+
const addResultCellListener = (queryId, rowId, cellId, listener) =>
|
|
1601
|
+
resultStore.addCellListener(queryId, rowId, cellId, (_store, ...args) =>
|
|
1602
|
+
listener(queries, ...args),
|
|
1603
|
+
);
|
|
1604
|
+
const delListener = (listenerId) => {
|
|
1605
|
+
resultStore.delListener(listenerId);
|
|
1606
|
+
return queries;
|
|
1607
|
+
};
|
|
1608
|
+
const getListenerStats = () => {
|
|
1609
|
+
const {
|
|
1610
|
+
tables: _1,
|
|
1611
|
+
tableIds: _2,
|
|
1612
|
+
transaction: _3,
|
|
1613
|
+
...stats
|
|
1614
|
+
} = resultStore.getListenerStats();
|
|
1615
|
+
return stats;
|
|
1616
|
+
};
|
|
1617
|
+
const queries = {
|
|
1618
|
+
setQueryDefinition,
|
|
1619
|
+
delQueryDefinition,
|
|
1620
|
+
getStore,
|
|
1621
|
+
getQueryIds,
|
|
1622
|
+
forEachQuery,
|
|
1623
|
+
hasQuery,
|
|
1624
|
+
getTableId,
|
|
1625
|
+
getResultTable,
|
|
1626
|
+
getResultRowIds,
|
|
1627
|
+
getResultRow,
|
|
1628
|
+
getResultCellIds,
|
|
1629
|
+
getResultCell,
|
|
1630
|
+
hasResultTable,
|
|
1631
|
+
hasResultRow,
|
|
1632
|
+
hasResultCell,
|
|
1633
|
+
forEachResultTable,
|
|
1634
|
+
forEachResultRow,
|
|
1635
|
+
forEachResultCell,
|
|
1636
|
+
addResultTableListener,
|
|
1637
|
+
addResultRowIdsListener,
|
|
1638
|
+
addResultRowListener,
|
|
1639
|
+
addResultCellIdsListener,
|
|
1640
|
+
addResultCellListener,
|
|
1641
|
+
delListener,
|
|
1642
|
+
destroy,
|
|
1643
|
+
getListenerStats,
|
|
1644
|
+
};
|
|
1645
|
+
return objFreeze(queries);
|
|
1646
|
+
});
|
|
1647
|
+
|
|
1014
1648
|
const createRelationships = getCreateFunction((store) => {
|
|
1015
1649
|
const remoteTableIds = mapNew();
|
|
1016
1650
|
const remoteRowIdListeners = mapNew();
|
|
@@ -1024,7 +1658,8 @@ const createRelationships = getCreateFunction((store) => {
|
|
|
1024
1658
|
getLocalTableId,
|
|
1025
1659
|
getRelationship,
|
|
1026
1660
|
,
|
|
1027
|
-
|
|
1661
|
+
,
|
|
1662
|
+
setDefinitionAndListen,
|
|
1028
1663
|
delDefinition,
|
|
1029
1664
|
destroy,
|
|
1030
1665
|
] = getDefinableFunctions(
|
|
@@ -1071,7 +1706,7 @@ const createRelationships = getCreateFunction((store) => {
|
|
|
1071
1706
|
getRemoteRowId2,
|
|
1072
1707
|
) => {
|
|
1073
1708
|
mapSet(remoteTableIds, relationshipId, remoteTableId);
|
|
1074
|
-
|
|
1709
|
+
setDefinitionAndListen(
|
|
1075
1710
|
relationshipId,
|
|
1076
1711
|
localTableId,
|
|
1077
1712
|
(change, changedRemoteRowIds) => {
|
|
@@ -1197,6 +1832,14 @@ const createRelationships = getCreateFunction((store) => {
|
|
|
1197
1832
|
return objFreeze(relationships);
|
|
1198
1833
|
});
|
|
1199
1834
|
|
|
1835
|
+
const pairNew = (value) => [value, value];
|
|
1836
|
+
const pairCollSize2 = (pair, func = collSize2) => func(pair[0]) + func(pair[1]);
|
|
1837
|
+
const pairCollIsEmpty = (pair) => pairCollSize2(pair) == 0;
|
|
1838
|
+
const pairNewMap = () => [mapNew(), mapNew()];
|
|
1839
|
+
const pair2CollSize2 = (pair2, func = collSize2) =>
|
|
1840
|
+
pairCollSize2(pair2[0], func) + pairCollSize2(pair2[1], func);
|
|
1841
|
+
const pair2NewMap = () => [pairNewMap(), pairNewMap()];
|
|
1842
|
+
|
|
1200
1843
|
const transformMap = (map, toBeLikeObject, setId, delId = mapSet) => {
|
|
1201
1844
|
const idsToDelete = arrayFilter(
|
|
1202
1845
|
mapKeys(map),
|
|
@@ -1208,12 +1851,6 @@ const transformMap = (map, toBeLikeObject, setId, delId = mapSet) => {
|
|
|
1208
1851
|
arrayForEach(idsToDelete, (id) => delId(map, id));
|
|
1209
1852
|
return map;
|
|
1210
1853
|
};
|
|
1211
|
-
const getCellType = (cell) => {
|
|
1212
|
-
const type = getTypeOf(cell);
|
|
1213
|
-
return isTypeStringOrBoolean(type) || (type == NUMBER && isFiniteNumber(cell))
|
|
1214
|
-
? type
|
|
1215
|
-
: void 0;
|
|
1216
|
-
};
|
|
1217
1854
|
const validate = (obj, validateChild, onInvalidObj) => {
|
|
1218
1855
|
if (isUndefined(obj) || !isObject(obj) || objIsEmpty(obj) || objFrozen(obj)) {
|
|
1219
1856
|
onInvalidObj?.();
|
|
@@ -1226,8 +1863,8 @@ const validate = (obj, validateChild, onInvalidObj) => {
|
|
|
1226
1863
|
});
|
|
1227
1864
|
return !objIsEmpty(obj);
|
|
1228
1865
|
};
|
|
1229
|
-
const idsChanged = (
|
|
1230
|
-
mapSet(
|
|
1866
|
+
const idsChanged = (changedIds, id, added) =>
|
|
1867
|
+
mapSet(changedIds, id, mapGet(changedIds, id) == -added ? void 0 : added);
|
|
1231
1868
|
const createStore = () => {
|
|
1232
1869
|
let hasSchema;
|
|
1233
1870
|
let cellsTouched;
|
|
@@ -1241,17 +1878,22 @@ const createStore = () => {
|
|
|
1241
1878
|
const schemaMap = mapNew();
|
|
1242
1879
|
const schemaRowCache = mapNew();
|
|
1243
1880
|
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
|
-
|
|
1881
|
+
const tablesListeners = pairNewMap();
|
|
1882
|
+
const tableIdsListeners = pair2NewMap();
|
|
1883
|
+
const tableListeners = pairNewMap();
|
|
1884
|
+
const rowIdsListeners = pair2NewMap();
|
|
1885
|
+
const rowListeners = pairNewMap();
|
|
1886
|
+
const cellIdsListeners = pair2NewMap();
|
|
1887
|
+
const cellListeners = pairNewMap();
|
|
1888
|
+
const invalidCellListeners = pairNewMap();
|
|
1889
|
+
const finishTransactionListeners = pairNewMap();
|
|
1890
|
+
const [
|
|
1891
|
+
addListener,
|
|
1892
|
+
callListeners,
|
|
1893
|
+
delListenerImpl,
|
|
1894
|
+
hasListeners,
|
|
1895
|
+
callListenerImpl,
|
|
1896
|
+
] = getListenerFunctions(() => store);
|
|
1255
1897
|
const validateSchema = (schema) =>
|
|
1256
1898
|
validate(schema, (tableSchema) =>
|
|
1257
1899
|
validate(tableSchema, (cellSchema) => {
|
|
@@ -1402,7 +2044,7 @@ const createStore = () => {
|
|
|
1402
2044
|
),
|
|
1403
2045
|
);
|
|
1404
2046
|
const getNewRowId = (tableMap) => {
|
|
1405
|
-
const rowId =
|
|
2047
|
+
const rowId = EMPTY_STRING + nextRowId++;
|
|
1406
2048
|
if (!collHas(tableMap, rowId)) {
|
|
1407
2049
|
return rowId;
|
|
1408
2050
|
}
|
|
@@ -1433,12 +2075,49 @@ const createStore = () => {
|
|
|
1433
2075
|
}
|
|
1434
2076
|
};
|
|
1435
2077
|
const tableIdsChanged = (tableId, added) =>
|
|
1436
|
-
idsChanged(
|
|
2078
|
+
idsChanged(
|
|
2079
|
+
collIsEmpty(changedTableIds)
|
|
2080
|
+
? mapSet(
|
|
2081
|
+
changedTableIds,
|
|
2082
|
+
null,
|
|
2083
|
+
hasListeners(tableIdsListeners[0][1]) ||
|
|
2084
|
+
hasListeners(tableIdsListeners[1][1])
|
|
2085
|
+
? getTableIds()
|
|
2086
|
+
: 0,
|
|
2087
|
+
)
|
|
2088
|
+
: changedTableIds,
|
|
2089
|
+
tableId,
|
|
2090
|
+
added,
|
|
2091
|
+
);
|
|
1437
2092
|
const rowIdsChanged = (tableId, rowId, added) =>
|
|
1438
|
-
idsChanged(
|
|
2093
|
+
idsChanged(
|
|
2094
|
+
mapEnsure(changedRowIds, tableId, () =>
|
|
2095
|
+
mapNew([
|
|
2096
|
+
[
|
|
2097
|
+
null,
|
|
2098
|
+
hasListeners(rowIdsListeners[0][1], [tableId]) ||
|
|
2099
|
+
hasListeners(rowIdsListeners[1][1], [tableId])
|
|
2100
|
+
? getRowIds(tableId)
|
|
2101
|
+
: 0,
|
|
2102
|
+
],
|
|
2103
|
+
]),
|
|
2104
|
+
),
|
|
2105
|
+
rowId,
|
|
2106
|
+
added,
|
|
2107
|
+
);
|
|
1439
2108
|
const cellIdsChanged = (tableId, rowId, cellId, added) =>
|
|
1440
2109
|
idsChanged(
|
|
1441
|
-
mapEnsure(mapEnsure(changedCellIds, tableId, mapNew), rowId,
|
|
2110
|
+
mapEnsure(mapEnsure(changedCellIds, tableId, mapNew), rowId, () =>
|
|
2111
|
+
mapNew([
|
|
2112
|
+
[
|
|
2113
|
+
null,
|
|
2114
|
+
hasListeners(cellIdsListeners[0][1], [tableId, rowId]) ||
|
|
2115
|
+
hasListeners(cellIdsListeners[1][1], [tableId, rowId])
|
|
2116
|
+
? getCellIds(tableId, rowId)
|
|
2117
|
+
: 0,
|
|
2118
|
+
],
|
|
2119
|
+
]),
|
|
2120
|
+
),
|
|
1442
2121
|
cellId,
|
|
1443
2122
|
added,
|
|
1444
2123
|
);
|
|
@@ -1463,7 +2142,7 @@ const createStore = () => {
|
|
|
1463
2142
|
ifNotUndefined(
|
|
1464
2143
|
mapGet(mapGet(mapGet(changedCells, tableId), rowId), cellId),
|
|
1465
2144
|
([oldCell, newCell]) => [true, oldCell, newCell],
|
|
1466
|
-
() => [false, ...
|
|
2145
|
+
() => [false, ...pairNew(getCell(tableId, rowId, cellId))],
|
|
1467
2146
|
);
|
|
1468
2147
|
const callInvalidCellListeners = (mutator) =>
|
|
1469
2148
|
!collIsEmpty(invalidCells) && !collIsEmpty(invalidCellListeners[mutator])
|
|
@@ -1481,17 +2160,29 @@ const createStore = () => {
|
|
|
1481
2160
|
),
|
|
1482
2161
|
)
|
|
1483
2162
|
: 0;
|
|
2163
|
+
const callIdsListenersIfChanged = (listeners, changedIds, getIds, ids) => {
|
|
2164
|
+
if (collSize(changedIds) > 1) {
|
|
2165
|
+
callListeners(listeners[0], ids);
|
|
2166
|
+
callListeners(listeners[1], ids);
|
|
2167
|
+
} else if (
|
|
2168
|
+
!collIsEmpty(changedIds) &&
|
|
2169
|
+
mapGet(changedIds, null) != 0 &&
|
|
2170
|
+
!arrayIsEqual(mapGet(changedIds, null), getIds(...(ids ?? [])))
|
|
2171
|
+
) {
|
|
2172
|
+
callListeners(listeners[1], ids);
|
|
2173
|
+
}
|
|
2174
|
+
};
|
|
1484
2175
|
const callListenersForChanges = (mutator) => {
|
|
1485
2176
|
const emptyIdListeners =
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
2177
|
+
pairCollIsEmpty(cellIdsListeners[mutator]) &&
|
|
2178
|
+
pairCollIsEmpty(rowIdsListeners[mutator]) &&
|
|
2179
|
+
pairCollIsEmpty(tableIdsListeners[mutator]);
|
|
1489
2180
|
const emptyOtherListeners =
|
|
1490
2181
|
collIsEmpty(cellListeners[mutator]) &&
|
|
1491
2182
|
collIsEmpty(rowListeners[mutator]) &&
|
|
1492
2183
|
collIsEmpty(tableListeners[mutator]) &&
|
|
1493
2184
|
collIsEmpty(tablesListeners[mutator]);
|
|
1494
|
-
if (!
|
|
2185
|
+
if (!emptyIdListeners || !emptyOtherListeners) {
|
|
1495
2186
|
const changes = mutator
|
|
1496
2187
|
? [
|
|
1497
2188
|
mapClone(changedTableIds),
|
|
@@ -1502,20 +2193,28 @@ const createStore = () => {
|
|
|
1502
2193
|
: [changedTableIds, changedRowIds, changedCellIds, changedCells];
|
|
1503
2194
|
if (!emptyIdListeners) {
|
|
1504
2195
|
collForEach(changes[2], (rowCellIds, tableId) =>
|
|
1505
|
-
collForEach(rowCellIds, (changedIds, rowId) =>
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
2196
|
+
collForEach(rowCellIds, (changedIds, rowId) =>
|
|
2197
|
+
callIdsListenersIfChanged(
|
|
2198
|
+
cellIdsListeners[mutator],
|
|
2199
|
+
changedIds,
|
|
2200
|
+
getCellIds,
|
|
2201
|
+
[tableId, rowId],
|
|
2202
|
+
),
|
|
2203
|
+
),
|
|
2204
|
+
);
|
|
2205
|
+
collForEach(changes[1], (changedIds, tableId) =>
|
|
2206
|
+
callIdsListenersIfChanged(
|
|
2207
|
+
rowIdsListeners[mutator],
|
|
2208
|
+
changedIds,
|
|
2209
|
+
getRowIds,
|
|
2210
|
+
[tableId],
|
|
2211
|
+
),
|
|
2212
|
+
);
|
|
2213
|
+
callIdsListenersIfChanged(
|
|
2214
|
+
tableIdsListeners[mutator],
|
|
2215
|
+
changes[0],
|
|
2216
|
+
getTableIds,
|
|
1510
2217
|
);
|
|
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
2218
|
}
|
|
1520
2219
|
if (!emptyOtherListeners) {
|
|
1521
2220
|
let tablesChanged;
|
|
@@ -1548,7 +2247,7 @@ const createStore = () => {
|
|
|
1548
2247
|
}
|
|
1549
2248
|
});
|
|
1550
2249
|
if (tablesChanged) {
|
|
1551
|
-
callListeners(tablesListeners[mutator],
|
|
2250
|
+
callListeners(tablesListeners[mutator], void 0, getCellChange);
|
|
1552
2251
|
}
|
|
1553
2252
|
}
|
|
1554
2253
|
}
|
|
@@ -1589,16 +2288,15 @@ const createStore = () => {
|
|
|
1589
2288
|
? setValidRow(tableId, getOrCreateTable(tableId), rowId, row)
|
|
1590
2289
|
: 0,
|
|
1591
2290
|
);
|
|
1592
|
-
const addRow = (tableId, row) =>
|
|
2291
|
+
const addRow = (tableId, row, forceId) =>
|
|
1593
2292
|
transaction(() => {
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
tableId
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
);
|
|
2293
|
+
const isValidRow = validateRow(tableId, void 0, row);
|
|
2294
|
+
const rowId =
|
|
2295
|
+
isValidRow || forceId
|
|
2296
|
+
? getNewRowId(mapGet(tablesMap, tableId))
|
|
2297
|
+
: void 0;
|
|
2298
|
+
if (isValidRow) {
|
|
2299
|
+
setValidRow(tableId, getOrCreateTable(tableId), rowId, row);
|
|
1602
2300
|
}
|
|
1603
2301
|
return rowId;
|
|
1604
2302
|
});
|
|
@@ -1730,12 +2428,12 @@ const createStore = () => {
|
|
|
1730
2428
|
transactions = -1;
|
|
1731
2429
|
cellsTouched = false;
|
|
1732
2430
|
}
|
|
1733
|
-
callListeners(finishTransactionListeners[0],
|
|
2431
|
+
callListeners(finishTransactionListeners[0], void 0, cellsTouched);
|
|
1734
2432
|
callInvalidCellListeners(0);
|
|
1735
2433
|
if (cellsTouched) {
|
|
1736
2434
|
callListenersForChanges(0);
|
|
1737
2435
|
}
|
|
1738
|
-
callListeners(finishTransactionListeners[1],
|
|
2436
|
+
callListeners(finishTransactionListeners[1], void 0, cellsTouched);
|
|
1739
2437
|
transactions = 0;
|
|
1740
2438
|
arrayForEach(
|
|
1741
2439
|
[
|
|
@@ -1769,16 +2467,33 @@ const createStore = () => {
|
|
|
1769
2467
|
mapForEach(mapGet(mapGet(tablesMap, tableId), rowId), cellCallback);
|
|
1770
2468
|
const addTablesListener = (listener, mutator) =>
|
|
1771
2469
|
addListener(listener, tablesListeners[mutator ? 1 : 0]);
|
|
1772
|
-
const addTableIdsListener = (listener, mutator) =>
|
|
1773
|
-
addListener(
|
|
2470
|
+
const addTableIdsListener = (listener, trackReorder, mutator) =>
|
|
2471
|
+
addListener(
|
|
2472
|
+
listener,
|
|
2473
|
+
tableIdsListeners[mutator ? 1 : 0][trackReorder ? 1 : 0],
|
|
2474
|
+
);
|
|
1774
2475
|
const addTableListener = (tableId, listener, mutator) =>
|
|
1775
2476
|
addListener(listener, tableListeners[mutator ? 1 : 0], [tableId]);
|
|
1776
|
-
const addRowIdsListener = (tableId, listener, mutator) =>
|
|
1777
|
-
addListener(
|
|
2477
|
+
const addRowIdsListener = (tableId, listener, trackReorder, mutator) =>
|
|
2478
|
+
addListener(
|
|
2479
|
+
listener,
|
|
2480
|
+
rowIdsListeners[mutator ? 1 : 0][trackReorder ? 1 : 0],
|
|
2481
|
+
[tableId],
|
|
2482
|
+
);
|
|
1778
2483
|
const addRowListener = (tableId, rowId, listener, mutator) =>
|
|
1779
2484
|
addListener(listener, rowListeners[mutator ? 1 : 0], [tableId, rowId]);
|
|
1780
|
-
const addCellIdsListener = (
|
|
1781
|
-
|
|
2485
|
+
const addCellIdsListener = (
|
|
2486
|
+
tableId,
|
|
2487
|
+
rowId,
|
|
2488
|
+
listener,
|
|
2489
|
+
trackReorder,
|
|
2490
|
+
mutator,
|
|
2491
|
+
) =>
|
|
2492
|
+
addListener(
|
|
2493
|
+
listener,
|
|
2494
|
+
cellIdsListeners[mutator ? 1 : 0][trackReorder ? 1 : 0],
|
|
2495
|
+
[tableId, rowId],
|
|
2496
|
+
);
|
|
1782
2497
|
const addCellListener = (tableId, rowId, cellId, listener, mutator) =>
|
|
1783
2498
|
addListener(listener, cellListeners[mutator ? 1 : 0], [
|
|
1784
2499
|
tableId,
|
|
@@ -1797,7 +2512,7 @@ const createStore = () => {
|
|
|
1797
2512
|
addListener(listener, finishTransactionListeners[1]);
|
|
1798
2513
|
const callListener = (listenerId) => {
|
|
1799
2514
|
callListenerImpl(listenerId, [getTableIds, getRowIds, getCellIds], (ids) =>
|
|
1800
|
-
isUndefined(ids[2]) ? [] :
|
|
2515
|
+
isUndefined(ids[2]) ? [] : pairNew(getCell(...ids)),
|
|
1801
2516
|
);
|
|
1802
2517
|
return store;
|
|
1803
2518
|
};
|
|
@@ -1806,15 +2521,15 @@ const createStore = () => {
|
|
|
1806
2521
|
return store;
|
|
1807
2522
|
};
|
|
1808
2523
|
const getListenerStats = () => ({
|
|
1809
|
-
tables:
|
|
1810
|
-
tableIds:
|
|
1811
|
-
table:
|
|
1812
|
-
rowIds:
|
|
1813
|
-
row:
|
|
1814
|
-
cellIds:
|
|
1815
|
-
cell:
|
|
1816
|
-
invalidCell:
|
|
1817
|
-
transaction:
|
|
2524
|
+
tables: pairCollSize2(tablesListeners),
|
|
2525
|
+
tableIds: pair2CollSize2(tableIdsListeners),
|
|
2526
|
+
table: pairCollSize2(tableListeners),
|
|
2527
|
+
rowIds: pair2CollSize2(rowIdsListeners),
|
|
2528
|
+
row: pairCollSize2(rowListeners, collSize3),
|
|
2529
|
+
cellIds: pair2CollSize2(cellIdsListeners, collSize3),
|
|
2530
|
+
cell: pairCollSize2(cellListeners, collSize4),
|
|
2531
|
+
invalidCell: pairCollSize2(invalidCellListeners, collSize4),
|
|
2532
|
+
transaction: pairCollSize2(finishTransactionListeners),
|
|
1818
2533
|
});
|
|
1819
2534
|
const store = {
|
|
1820
2535
|
getTables,
|
|
@@ -1862,6 +2577,7 @@ const createStore = () => {
|
|
|
1862
2577
|
callListener,
|
|
1863
2578
|
delListener,
|
|
1864
2579
|
getListenerStats,
|
|
2580
|
+
createStore,
|
|
1865
2581
|
};
|
|
1866
2582
|
return objFreeze(store);
|
|
1867
2583
|
};
|
|
@@ -1873,6 +2589,7 @@ export {
|
|
|
1873
2589
|
createIndexes,
|
|
1874
2590
|
createLocalPersister,
|
|
1875
2591
|
createMetrics,
|
|
2592
|
+
createQueries,
|
|
1876
2593
|
createRelationships,
|
|
1877
2594
|
createRemotePersister,
|
|
1878
2595
|
createSessionPersister,
|