tinybase 8.2.0 → 8.3.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/@types/queries/index.d.ts +141 -0
  2. package/@types/queries/with-schemas/index.d.ts +184 -0
  3. package/@types/ui-react-dom/index.d.ts +10 -10
  4. package/@types/ui-react-dom/with-schemas/index.d.ts +10 -10
  5. package/@types/ui-react-inspector/index.d.ts +1 -1
  6. package/@types/ui-react-inspector/with-schemas/index.d.ts +1 -1
  7. package/@types/ui-svelte-dom/index.d.ts +10 -10
  8. package/@types/ui-svelte-dom/with-schemas/index.d.ts +10 -10
  9. package/@types/ui-svelte-inspector/index.d.ts +1 -1
  10. package/@types/ui-svelte-inspector/with-schemas/index.d.ts +1 -1
  11. package/index.js +594 -418
  12. package/indexes/index.js +8 -22
  13. package/indexes/with-schemas/index.js +8 -22
  14. package/metrics/index.js +8 -22
  15. package/metrics/with-schemas/index.js +8 -22
  16. package/min/index.js +1 -1
  17. package/min/index.js.gz +0 -0
  18. package/min/indexes/index.js +1 -1
  19. package/min/indexes/index.js.gz +0 -0
  20. package/min/indexes/with-schemas/index.js +1 -1
  21. package/min/indexes/with-schemas/index.js.gz +0 -0
  22. package/min/metrics/index.js +1 -1
  23. package/min/metrics/index.js.gz +0 -0
  24. package/min/metrics/with-schemas/index.js +1 -1
  25. package/min/metrics/with-schemas/index.js.gz +0 -0
  26. package/min/omni/index.js +1 -1
  27. package/min/omni/index.js.gz +0 -0
  28. package/min/omni/with-schemas/index.js +1 -1
  29. package/min/omni/with-schemas/index.js.gz +0 -0
  30. package/min/queries/index.js +1 -1
  31. package/min/queries/index.js.gz +0 -0
  32. package/min/queries/with-schemas/index.js +1 -1
  33. package/min/queries/with-schemas/index.js.gz +0 -0
  34. package/min/relationships/index.js +1 -1
  35. package/min/relationships/index.js.gz +0 -0
  36. package/min/relationships/with-schemas/index.js +1 -1
  37. package/min/relationships/with-schemas/index.js.gz +0 -0
  38. package/min/with-schemas/index.js +1 -1
  39. package/min/with-schemas/index.js.gz +0 -0
  40. package/omni/index.js +594 -418
  41. package/omni/with-schemas/index.js +594 -418
  42. package/package.json +10 -10
  43. package/queries/index.js +596 -454
  44. package/queries/with-schemas/index.js +596 -454
  45. package/readme.md +14 -14
  46. package/relationships/index.js +8 -22
  47. package/relationships/with-schemas/index.js +8 -22
  48. package/releases.md +51 -51
  49. package/ui-svelte/index.js +1 -1
  50. package/ui-svelte/with-schemas/index.js +1 -1
  51. package/ui-svelte-dom/index.js +2 -2
  52. package/ui-svelte-dom/with-schemas/index.js +2 -2
  53. package/ui-svelte-inspector/index.js +2 -2
  54. package/ui-svelte-inspector/with-schemas/index.js +2 -2
  55. package/with-schemas/index.js +594 -418
package/queries/index.js CHANGED
@@ -36,6 +36,7 @@ const isFiniteNumber = isFinite;
36
36
  const isNullish = (thing) => thing == null;
37
37
  const isUndefined = (thing) => thing === void 0;
38
38
  const isNull = (thing) => thing === null;
39
+ const isTrue = (thing) => thing === true;
39
40
  const ifNotNullish = getIfNotFunction(isNullish);
40
41
  const ifNotUndefined = getIfNotFunction(isUndefined);
41
42
  const isTypeStringOrBoolean = (type) => type == STRING || type == BOOLEAN;
@@ -49,10 +50,6 @@ const arrayEvery = (array, cb) => array.every(cb);
49
50
  const arrayIsEqual = (array1, array2) =>
50
51
  size(array1) === size(array2) &&
51
52
  arrayEvery(array1, (value1, index) => array2[index] === value1);
52
- const arrayOrValueEqual = (value1, value2) =>
53
- isArray(value1) && isArray(value2)
54
- ? arrayIsEqual(value1, value2)
55
- : value1 === value2;
56
53
  const arrayForEach = (array, cb) => array.forEach(cb);
57
54
  const arrayMap = (array, cb) => array.map(cb);
58
55
  const arraySum = (array) => arrayReduce(array, (i, j) => i + j, 0);
@@ -60,11 +57,7 @@ const arrayIsEmpty = (array) => size(array) == 0;
60
57
  const arrayReduce = (array, cb, initial) => array.reduce(cb, initial);
61
58
  const arrayPush = (array, ...values) => array.push(...values);
62
59
 
63
- const collSizeN = (collSizer) => (coll) =>
64
- arrayReduce(collValues(coll), (total, coll2) => total + collSizer(coll2), 0);
65
60
  const collSize = (coll) => coll?.size ?? 0;
66
- const collSize2 = collSizeN(collSize);
67
- const collSize3 = collSizeN(collSize2);
68
61
  const collHas = (coll, keyOrValue) => coll?.has(keyOrValue) ?? false;
69
62
  const collIsEmpty = (coll) => isUndefined(coll) || collSize(coll) == 0;
70
63
  const collValues = (coll) => [...(coll?.values() ?? [])];
@@ -90,32 +83,12 @@ const objIds = object.keys;
90
83
  const objFreeze = object.freeze;
91
84
  const objNew = (entries = []) => object.fromEntries(entries);
92
85
  const objGet = (obj, id) => ifNotUndefined(obj, (obj2) => obj2[id]);
93
- const objToMap = (obj) => new Map(objEntries(obj));
94
86
  const objToArray = (obj, cb) =>
95
87
  arrayMap(objEntries(obj), ([id, value]) => cb(value, id));
96
88
  const objMap = (obj, cb) =>
97
89
  objNew(objToArray(obj, (value, id) => [id, cb(value, id)]));
98
90
  const objSize = (obj) => size(objIds(obj));
99
-
100
- /* istanbul ignore next */
101
- const objIsEqual = (
102
- obj1,
103
- obj2,
104
- isEqual = (value1, value2) => value1 === value2,
105
- ) => {
106
- const entries1 = objEntries(obj1);
107
- return (
108
- size(entries1) === objSize(obj2) &&
109
- arrayEvery(entries1, ([index, value1]) =>
110
- isObject(value1)
111
- ? /* istanbul ignore next */
112
- isObject(obj2[index])
113
- ? objIsEqual(obj2[index], value1, isEqual)
114
- : false
115
- : isEqual(value1, obj2[index]),
116
- )
117
- );
118
- };
91
+ const objIsEmpty = (obj) => isObject(obj) && objSize(obj) == 0;
119
92
 
120
93
  const map = Map;
121
94
  const mapNew = (entries) => new map(entries);
@@ -133,18 +106,6 @@ const mapEnsure = (map2, key, getDefaultValue, hadExistingValue) => {
133
106
  }
134
107
  return mapGet(map2, key);
135
108
  };
136
- const mapToObj = (map2, valueMapper, excludeMapValue, excludeObjValue) => {
137
- const obj = {};
138
- collForEach(map2, (mapValue, id) => {
139
- {
140
- const objValue = mapValue;
141
- {
142
- obj[id] = objValue;
143
- }
144
- }
145
- });
146
- return obj;
147
- };
148
109
  const visitTree = (node, path, ensureLeaf, pruneLeaf, p = 0) =>
149
110
  ifNotUndefined(
150
111
  (ensureLeaf ? mapEnsure : mapGet)(
@@ -282,27 +243,17 @@ const getDefinableFunctions = (
282
243
  const getTableId = (id) => mapGet(tableIds, id);
283
244
  const getThing = (id) => mapGet(things, id);
284
245
  const setThing = (id, thing) => mapSet(things, id, thing);
285
- const addStoreListeners = (id, andCall, ...listenerIds) => {
246
+ const addStoreListeners = (id, ...listenerIds) => {
286
247
  const set = mapEnsure(storeListenerIds, id, setNew);
287
- arrayForEach(
288
- listenerIds,
289
- (listenerId) =>
290
- setAdd(set, listenerId) && andCall && store.callListener(listenerId),
291
- );
292
- return listenerIds;
248
+ arrayForEach(listenerIds, (listenerId) => setAdd(set, listenerId));
293
249
  };
294
- const delStoreListeners = (id, ...listenerIds) =>
250
+ const delStoreListeners = (id) =>
295
251
  ifNotUndefined(mapGet(storeListenerIds, id), (allListenerIds) => {
296
- arrayForEach(
297
- arrayIsEmpty(listenerIds) ? collValues(allListenerIds) : listenerIds,
298
- (listenerId) => {
299
- store.delListener(listenerId);
300
- collDel(allListenerIds, listenerId);
301
- },
302
- );
303
- if (collIsEmpty(allListenerIds)) {
304
- mapSet(storeListenerIds, id);
305
- }
252
+ arrayForEach(collValues(allListenerIds), (listenerId) => {
253
+ store.delListener(listenerId);
254
+ collDel(allListenerIds, listenerId);
255
+ });
256
+ mapSet(storeListenerIds, id);
306
257
  });
307
258
  const setDefinition = (id, tableId) => {
308
259
  mapSet(tableIds, id, tableId);
@@ -382,7 +333,6 @@ const getDefinableFunctions = (
382
333
  delStoreListeners(id);
383
334
  addStoreListeners(
384
335
  id,
385
- 0,
386
336
  store.addRowListener(tableId, null, (_store, _tableId, rowId) =>
387
337
  processRow(rowId),
388
338
  ),
@@ -413,8 +363,6 @@ const getDefinableFunctions = (
413
363
  delDefinition,
414
364
  addThingIdsListener,
415
365
  destroy,
416
- addStoreListeners,
417
- delStoreListeners,
418
366
  ];
419
367
  };
420
368
  const getCreateFunction = (getFunction, initFunction) => {
@@ -428,13 +376,29 @@ const getCreateFunction = (getFunction, initFunction) => {
428
376
  };
429
377
  };
430
378
 
379
+ const PARAMS_TABLE = '_';
380
+ const PARAM_LISTENER_PREFIX = 'p';
431
381
  const createQueries = getCreateFunction((store) => {
432
382
  const createStore = store._[0];
433
383
  const preStore = createStore();
384
+ const paramStore = createStore();
434
385
  const resultStore = createStore();
386
+ const resultStores = mapNew();
387
+ const redefiningQueryIds = setNew();
388
+ const routedResultListeners = mapNew();
389
+ const routedResultListenerIds = mapNew();
390
+ const resultListenerStats = {
391
+ table: 0,
392
+ tableCellIds: 0,
393
+ rowCount: 0,
394
+ rowIds: 0,
395
+ sortedRowIds: 0,
396
+ row: 0,
397
+ cellIds: 0,
398
+ cell: 0,
399
+ };
435
400
  const preStoreListenerIds = mapNew();
436
- const paramValuesListeners = mapNew();
437
- const paramValueListeners = mapNew();
401
+ const sourceStoreListenerIds = mapNew();
438
402
  const {
439
403
  _: [, addListener, callListeners],
440
404
  delListener: delListenerImpl,
@@ -451,9 +415,7 @@ const createQueries = getCreateFunction((store) => {
451
415
  ,
452
416
  delDefinition,
453
417
  addQueryIdsListenerImpl,
454
- destroy,
455
- addStoreListeners,
456
- delStoreListeners,
418
+ destroyImpl,
457
419
  ] = getDefinableFunctions(
458
420
  store,
459
421
  () => [],
@@ -461,6 +423,8 @@ const createQueries = getCreateFunction((store) => {
461
423
  addListener,
462
424
  callListeners,
463
425
  );
426
+ const getResultStore = (queryId) =>
427
+ mapEnsure(resultStores, queryId, createStore);
464
428
  const addPreStoreListener = (preStore2, queryId, ...listenerIds) =>
465
429
  arrayForEach(listenerIds, (listenerId) =>
466
430
  setAdd(
@@ -484,8 +448,49 @@ const createQueries = getCreateFunction((store) => {
484
448
  collClear(queryPreStoreListenerIds);
485
449
  },
486
450
  );
487
- arrayForEach([resultStore, preStore], (store2) => store2.delTable(queryId));
451
+ arrayForEach([getResultStore(queryId), preStore], (store2) =>
452
+ store2.delTable(queryId),
453
+ );
488
454
  };
455
+ const addSourceStoreListeners = (
456
+ sourceStore,
457
+ queryId,
458
+ andCall,
459
+ ...listenerIds
460
+ ) => {
461
+ const listenerIdSet = mapEnsure(
462
+ mapEnsure(sourceStoreListenerIds, queryId, mapNew),
463
+ sourceStore,
464
+ setNew,
465
+ );
466
+ arrayForEach(listenerIds, (listenerId) => {
467
+ setAdd(listenerIdSet, listenerId);
468
+ if (andCall) {
469
+ sourceStore.callListener(listenerId);
470
+ }
471
+ });
472
+ return listenerIds;
473
+ };
474
+ const delSourceStoreListeners = (queryId, sourceStore, listenerId) =>
475
+ ifNotUndefined(
476
+ mapGet(mapGet(sourceStoreListenerIds, queryId), sourceStore),
477
+ (allListenerIds) => {
478
+ sourceStore.delListener(listenerId);
479
+ collDel(allListenerIds, listenerId);
480
+ if (collIsEmpty(allListenerIds)) {
481
+ mapSet(mapGet(sourceStoreListenerIds, queryId), sourceStore);
482
+ }
483
+ },
484
+ );
485
+ const resetSourceStores = (queryId) =>
486
+ ifNotUndefined(mapGet(sourceStoreListenerIds, queryId), (queryStoreIds) => {
487
+ mapForEach(queryStoreIds, (sourceStore, listenerIds) =>
488
+ collForEach(listenerIds, (listenerId) =>
489
+ sourceStore.delListener(listenerId),
490
+ ),
491
+ );
492
+ collClear(queryStoreIds);
493
+ });
489
494
  const synchronizeTransactions = (queryId, fromStore, toStore) =>
490
495
  addPreStoreListener(
491
496
  fromStore,
@@ -495,424 +500,549 @@ const createQueries = getCreateFunction((store) => {
495
500
  toStore.finishTransaction(),
496
501
  ),
497
502
  );
498
- const setQueryDefinition = (queryId, tableId, build, paramValues = {}) => {
499
- const oldParamValues = getParamValues(queryId);
500
- setDefinition(queryId, tableId);
501
- setQueryArgs(queryId, [build, objToMap(paramValues)]);
502
- callParamListeners(queryId, oldParamValues, paramValues);
503
- resetPreStores(queryId);
504
- const [, paramsMap] = getQueryArgs(queryId);
505
- const selectEntries = [];
506
- const joinEntries = [[void 0, [tableId, void 0, void 0, [], mapNew()]]];
507
- const wheres = [];
508
- const groupEntries = [];
509
- const havings = [];
510
- const param = (paramId) => mapGet(paramsMap, paramId);
511
- const select = (arg1, arg2) => {
512
- const selectEntry = isFunction(arg1)
513
- ? [size(selectEntries) + EMPTY_STRING, arg1]
514
- : [
515
- isUndefined(arg2) ? arg1 : arg2,
516
- (getTableCell) => getTableCell(arg1, arg2),
517
- ];
518
- arrayPush(selectEntries, selectEntry);
519
- return {as: (selectedCellId) => (selectEntry[0] = selectedCellId)};
520
- };
521
- const join = (joinedTableId, arg1, arg2) => {
522
- const fromIntermediateJoinedTableId =
523
- isUndefined(arg2) || isFunction(arg1) ? void 0 : arg1;
524
- const onArg = isUndefined(fromIntermediateJoinedTableId) ? arg1 : arg2;
525
- const joinEntry = [
526
- joinedTableId,
527
- [
528
- joinedTableId,
529
- fromIntermediateJoinedTableId,
530
- isFunction(onArg) ? onArg : (getCell) => getCell(onArg),
531
- [],
532
- mapNew(),
533
- ],
534
- ];
535
- arrayPush(joinEntries, joinEntry);
536
- return {as: (joinedTableId2) => (joinEntry[0] = joinedTableId2)};
537
- };
538
- const where = (arg1, arg2, arg3) =>
539
- arrayPush(
540
- wheres,
541
- isFunction(arg1)
542
- ? arg1
543
- : isUndefined(arg3)
544
- ? (getTableCell) => getTableCell(arg1) === arg2
545
- : (getTableCell) => getTableCell(arg1, arg2) === arg3,
546
- );
547
- const group = (
548
- selectedCellId,
549
- aggregate,
550
- aggregateAdd,
551
- aggregateRemove,
552
- aggregateReplace,
553
- ) => {
554
- const groupEntry = [
555
- selectedCellId,
556
- [
557
- selectedCellId,
558
- isFunction(aggregate)
559
- ? [aggregate, aggregateAdd, aggregateRemove, aggregateReplace]
560
- : (mapGet(numericAggregators, aggregate) ?? [
561
- (_cells, length) => length,
562
- ]),
563
- ],
564
- ];
565
- arrayPush(groupEntries, groupEntry);
566
- return {as: (groupedCellId) => (groupEntry[0] = groupedCellId)};
567
- };
568
- const having = (arg1, arg2) =>
569
- arrayPush(
570
- havings,
571
- isFunction(arg1)
572
- ? arg1
573
- : (getSelectedOrGroupedCell) =>
574
- getSelectedOrGroupedCell(arg1) === arg2,
575
- );
576
- build({select, join, where, group, having, param});
577
- const selects = mapNew(selectEntries);
578
- if (collIsEmpty(selects)) {
579
- return queries;
580
- }
581
- const joins = mapNew(joinEntries);
582
- mapForEach(joins, (asTableId, [, fromAsTableId]) =>
583
- ifNotUndefined(mapGet(joins, fromAsTableId), ({3: toAsTableIds}) =>
584
- isUndefined(asTableId) ? 0 : arrayPush(toAsTableIds, asTableId),
585
- ),
503
+ const setOrDelParamValues = (queryId, paramValues) =>
504
+ (objIsEmpty(paramValues) ? paramStore.delRow : paramStore.setRow)(
505
+ PARAMS_TABLE,
506
+ queryId,
507
+ {...paramValues},
586
508
  );
587
- const groups = mapNew(groupEntries);
588
- let selectJoinWhereStore = preStore;
589
- if (collIsEmpty(groups) && arrayIsEmpty(havings)) {
590
- selectJoinWhereStore = resultStore;
591
- } else {
592
- synchronizeTransactions(queryId, selectJoinWhereStore, resultStore);
593
- const groupedSelectedCellIds = mapNew();
594
- mapForEach(groups, (groupedCellId, [selectedCellId, aggregators]) =>
595
- setAdd(mapEnsure(groupedSelectedCellIds, selectedCellId, setNew), [
596
- groupedCellId,
597
- aggregators,
598
- ]),
509
+ const addRoutedResultListener = (stat, queryId, addStoreListener) => {
510
+ const listenerId = addListener(getUndefined, routedResultListenerIds);
511
+ const storeListenerIds = mapNew();
512
+ const syncStoreListeners = () => {
513
+ const queryIds = queryId == null ? getQueryIds() : [queryId];
514
+ arrayForEach(queryIds, (queryId2) =>
515
+ collHas(storeListenerIds, queryId2)
516
+ ? 0
517
+ : mapSet(storeListenerIds, queryId2, [
518
+ getResultStore(queryId2),
519
+ addStoreListener(getResultStore(queryId2), queryId2),
520
+ ]),
599
521
  );
600
- const groupBySelectedCellIds = setNew();
601
- mapForEach(selects, (selectedCellId) =>
602
- collHas(groupedSelectedCellIds, selectedCellId)
522
+ mapForEach(storeListenerIds, (storeQueryId, [store2, storeListenerId]) =>
523
+ (queryId == null && hasQuery(storeQueryId)) || storeQueryId == queryId
603
524
  ? 0
604
- : setAdd(groupBySelectedCellIds, selectedCellId),
525
+ : (() => {
526
+ store2.delListener(storeListenerId);
527
+ mapSet(storeListenerIds, storeQueryId);
528
+ })(),
605
529
  );
606
- const tree = mapNew();
607
- const writeGroupRow = (
608
- leaf,
609
- changedGroupedSelectedCells,
610
- selectedRowId,
611
- forceRemove,
612
- ) =>
613
- ifNotUndefined(
614
- leaf,
615
- ([selectedCells, selectedRowIds, groupRowId, groupRow]) => {
616
- mapForEach(
617
- changedGroupedSelectedCells,
618
- (selectedCellId, [newCell]) => {
619
- const selectedCell = mapEnsure(
620
- selectedCells,
621
- selectedCellId,
622
- mapNew,
623
- );
624
- const oldLeafCell = mapGet(selectedCell, selectedRowId);
625
- const newLeafCell = forceRemove ? void 0 : newCell;
626
- if (oldLeafCell !== newLeafCell) {
627
- const oldNewSet = setNew([[oldLeafCell, newLeafCell]]);
628
- const oldLength = collSize(selectedCell);
629
- mapSet(selectedCell, selectedRowId, newLeafCell);
630
- collForEach(
631
- mapGet(groupedSelectedCellIds, selectedCellId),
632
- ([groupedCellId, aggregators]) => {
633
- const aggregateValue = getAggregateValue(
634
- groupRow[groupedCellId],
635
- oldLength,
636
- selectedCell,
637
- oldNewSet,
638
- aggregators,
530
+ };
531
+ syncStoreListeners();
532
+ mapSet(routedResultListeners, listenerId, [
533
+ stat,
534
+ storeListenerIds,
535
+ queryId == null ? addQueryIdsListenerImpl(syncStoreListeners) : void 0,
536
+ ]);
537
+ resultListenerStats[stat]++;
538
+ return listenerId;
539
+ };
540
+ const setQueryDefinition = (
541
+ queryId,
542
+ tableIdOrAsQuery,
543
+ tableIdOrBuild,
544
+ buildOrParamValues,
545
+ paramValuesIfSourceIsQuery = {},
546
+ ) => {
547
+ const [tableId, build, sourceIsQuery, paramValues] = isTrue(
548
+ tableIdOrAsQuery,
549
+ )
550
+ ? [tableIdOrBuild, buildOrParamValues, 1, paramValuesIfSourceIsQuery]
551
+ : [tableIdOrAsQuery, tableIdOrBuild, 0, buildOrParamValues ?? {}];
552
+ ifNotUndefined(getQueryArgs(queryId), ([, listenerId]) =>
553
+ paramStore.delListener(listenerId),
554
+ );
555
+ setDefinition(queryId, tableId);
556
+ setQueryArgs(queryId, [
557
+ build,
558
+ paramStore.addRowListener(PARAMS_TABLE, queryId, () =>
559
+ setQueryDefinitionImpl(queryId),
560
+ ),
561
+ sourceIsQuery,
562
+ ]);
563
+ setOrDelParamValues(queryId, paramValues);
564
+ setQueryDefinitionImpl(queryId);
565
+ return queries;
566
+ };
567
+ const setQueryDefinitionImpl = (queryId) =>
568
+ getResultStore(queryId).transaction(() =>
569
+ ifNotUndefined(getQueryArgs(queryId), ([build, , sourceIsQuery]) => {
570
+ const tableId = getTableId(queryId);
571
+ const rootStore = sourceIsQuery ? getResultStore(tableId) : store;
572
+ const resultStore2 = getResultStore(queryId);
573
+ const paramValues = getParamValues(queryId);
574
+ setAdd(redefiningQueryIds, queryId);
575
+ resetPreStores(queryId);
576
+ resetSourceStores(queryId);
577
+ const selectEntries = [];
578
+ const joinEntries = [
579
+ [void 0, [tableId, void 0, void 0, [], mapNew(), rootStore]],
580
+ ];
581
+ const wheres = [];
582
+ const groupEntries = [];
583
+ const havings = [];
584
+ const param = (paramId) => objGet(paramValues, paramId);
585
+ const select = (arg1, arg2, arg3) => {
586
+ const joinedTableId = isTrue(arg1) ? arg2 : arg1;
587
+ const joinedCellId = isTrue(arg1) ? arg3 : arg2;
588
+ const selectEntry = isFunction(arg1)
589
+ ? [size(selectEntries) + EMPTY_STRING, arg1]
590
+ : isUndefined(joinedCellId)
591
+ ? [arg1, (getTableCell) => getTableCell(arg1)]
592
+ : [
593
+ joinedCellId,
594
+ (getTableCell) =>
595
+ isTrue(arg1)
596
+ ? getTableCell(true, joinedTableId, joinedCellId)
597
+ : getTableCell(joinedTableId, joinedCellId),
598
+ ];
599
+ arrayPush(selectEntries, selectEntry);
600
+ return {
601
+ as: (selectedCellId) => (selectEntry[0] = selectedCellId),
602
+ };
603
+ };
604
+ const join = (arg1, arg2, arg3, arg4) => {
605
+ const joinedTableId = isTrue(arg1) ? arg2 : arg1;
606
+ const [fromJoinAlias, onArg] = isTrue(arg1)
607
+ ? isUndefined(arg4) || isFunction(arg3)
608
+ ? [void 0, arg3]
609
+ : [arg3, arg4]
610
+ : isUndefined(arg3) || isFunction(arg2)
611
+ ? [void 0, arg2]
612
+ : [arg2, arg3];
613
+ const joinEntry = [
614
+ joinedTableId,
615
+ [
616
+ joinedTableId,
617
+ fromJoinAlias,
618
+ isFunction(onArg) ? onArg : (getCell) => getCell(onArg),
619
+ [],
620
+ mapNew(),
621
+ isTrue(arg1) ? getResultStore(joinedTableId) : store,
622
+ ],
623
+ ];
624
+ arrayPush(joinEntries, joinEntry);
625
+ return {as: (joinedTableId2) => (joinEntry[0] = joinedTableId2)};
626
+ };
627
+ const where = (arg1, arg2, arg3, arg4) =>
628
+ arrayPush(
629
+ wheres,
630
+ isFunction(arg1)
631
+ ? arg1
632
+ : isTrue(arg1)
633
+ ? (getTableCell) => getTableCell(true, arg2, arg3) === arg4
634
+ : isUndefined(arg3)
635
+ ? (getTableCell) => getTableCell(arg1) === arg2
636
+ : (getTableCell) => getTableCell(arg1, arg2) === arg3,
637
+ );
638
+ const group = (
639
+ selectedCellId,
640
+ aggregate,
641
+ aggregateAdd,
642
+ aggregateRemove,
643
+ aggregateReplace,
644
+ ) => {
645
+ const groupEntry = [
646
+ selectedCellId,
647
+ [
648
+ selectedCellId,
649
+ isFunction(aggregate)
650
+ ? [aggregate, aggregateAdd, aggregateRemove, aggregateReplace]
651
+ : (mapGet(numericAggregators, aggregate) ?? [
652
+ (_cells, length) => length,
653
+ ]),
654
+ ],
655
+ ];
656
+ arrayPush(groupEntries, groupEntry);
657
+ return {as: (groupedCellId) => (groupEntry[0] = groupedCellId)};
658
+ };
659
+ const having = (arg1, arg2) =>
660
+ arrayPush(
661
+ havings,
662
+ isFunction(arg1)
663
+ ? arg1
664
+ : (getSelectedOrGroupedCell) =>
665
+ getSelectedOrGroupedCell(arg1) === arg2,
666
+ );
667
+ build({select, join, where, group, having, param});
668
+ const selects = mapNew(selectEntries);
669
+ if (collIsEmpty(selects)) {
670
+ collDel(redefiningQueryIds, queryId);
671
+ return queries;
672
+ }
673
+ const joins = mapNew(joinEntries);
674
+ mapForEach(joins, (joinAlias, [, fromJoinAlias]) =>
675
+ ifNotUndefined(mapGet(joins, fromJoinAlias), ({3: toJoinAliases2}) =>
676
+ isUndefined(joinAlias) ? 0 : arrayPush(toJoinAliases2, joinAlias),
677
+ ),
678
+ );
679
+ const groups = mapNew(groupEntries);
680
+ let selectJoinWhereStore = preStore;
681
+ if (collIsEmpty(groups) && arrayIsEmpty(havings)) {
682
+ selectJoinWhereStore = resultStore2;
683
+ } else {
684
+ synchronizeTransactions(queryId, selectJoinWhereStore, resultStore2);
685
+ const groupedSelectedCellIds = mapNew();
686
+ mapForEach(groups, (groupedCellId, [selectedCellId, aggregators]) =>
687
+ setAdd(mapEnsure(groupedSelectedCellIds, selectedCellId, setNew), [
688
+ groupedCellId,
689
+ aggregators,
690
+ ]),
691
+ );
692
+ const groupBySelectedCellIds = setNew();
693
+ mapForEach(selects, (selectedCellId) =>
694
+ collHas(groupedSelectedCellIds, selectedCellId)
695
+ ? 0
696
+ : setAdd(groupBySelectedCellIds, selectedCellId),
697
+ );
698
+ const tree = mapNew();
699
+ const writeGroupRow = (
700
+ leaf,
701
+ changedGroupedSelectedCells,
702
+ selectedRowId,
703
+ forceRemove,
704
+ ) =>
705
+ ifNotUndefined(
706
+ leaf,
707
+ ([selectedCells, selectedRowIds, groupRowId, groupRow]) => {
708
+ mapForEach(
709
+ changedGroupedSelectedCells,
710
+ (selectedCellId, [newCell]) => {
711
+ const selectedCell = mapEnsure(
712
+ selectedCells,
713
+ selectedCellId,
714
+ mapNew,
715
+ );
716
+ const oldLeafCell = mapGet(selectedCell, selectedRowId);
717
+ const newLeafCell = forceRemove ? void 0 : newCell;
718
+ if (oldLeafCell !== newLeafCell) {
719
+ const oldNewSet = setNew([[oldLeafCell, newLeafCell]]);
720
+ const oldLength = collSize(selectedCell);
721
+ mapSet(selectedCell, selectedRowId, newLeafCell);
722
+ collForEach(
723
+ mapGet(groupedSelectedCellIds, selectedCellId),
724
+ ([groupedCellId, aggregators]) => {
725
+ const aggregateValue = getAggregateValue(
726
+ groupRow[groupedCellId],
727
+ oldLength,
728
+ selectedCell,
729
+ oldNewSet,
730
+ aggregators,
731
+ );
732
+ groupRow[groupedCellId] = isUndefined(
733
+ getCellOrValueType(aggregateValue),
734
+ )
735
+ ? void 0
736
+ : aggregateValue;
737
+ },
639
738
  );
640
- groupRow[groupedCellId] = isUndefined(
641
- getCellOrValueType(aggregateValue),
642
- )
643
- ? void 0
644
- : aggregateValue;
645
- },
646
- );
739
+ }
740
+ },
741
+ );
742
+ if (
743
+ collIsEmpty(selectedRowIds) ||
744
+ !arrayEvery(havings, (having2) =>
745
+ having2((cellId) => groupRow[cellId]),
746
+ )
747
+ ) {
748
+ resultStore2.delRow(queryId, groupRowId);
749
+ } else if (isUndefined(groupRowId)) {
750
+ leaf[2] = resultStore2.addRow(queryId, groupRow);
751
+ } else {
752
+ resultStore2.setRow(queryId, groupRowId, groupRow);
647
753
  }
648
754
  },
649
755
  );
650
- if (
651
- collIsEmpty(selectedRowIds) ||
652
- !arrayEvery(havings, (having2) =>
653
- having2((cellId) => groupRow[cellId]),
654
- )
655
- ) {
656
- resultStore.delRow(queryId, groupRowId);
657
- } else if (isUndefined(groupRowId)) {
658
- leaf[2] = resultStore.addRow(queryId, groupRow);
659
- } else {
660
- resultStore.setRow(queryId, groupRowId, groupRow);
661
- }
662
- },
663
- );
664
- addPreStoreListener(
665
- selectJoinWhereStore,
666
- queryId,
667
- selectJoinWhereStore.addRowListener(
668
- queryId,
669
- null,
670
- (_store, _tableId, selectedRowId, getCellChange) => {
671
- const oldPath = [];
672
- const newPath = [];
673
- const changedGroupedSelectedCells = mapNew();
674
- const rowExists = selectJoinWhereStore.hasRow(
756
+ addPreStoreListener(
757
+ selectJoinWhereStore,
758
+ queryId,
759
+ selectJoinWhereStore.addRowListener(
675
760
  queryId,
676
- selectedRowId,
677
- );
678
- let changedLeaf = !rowExists;
679
- collForEach(groupBySelectedCellIds, (selectedCellId) => {
680
- const [changed, oldCell, newCell] = getCellChange(
681
- queryId,
682
- selectedRowId,
683
- selectedCellId,
684
- );
685
- arrayPush(oldPath, oldCell);
686
- arrayPush(newPath, newCell);
687
- changedLeaf ||= changed;
688
- });
689
- mapForEach(groupedSelectedCellIds, (selectedCellId) => {
690
- const [changed, , newCell] = getCellChange(
691
- queryId,
692
- selectedRowId,
693
- selectedCellId,
694
- );
695
- if (changedLeaf || changed) {
696
- mapSet(changedGroupedSelectedCells, selectedCellId, [newCell]);
697
- }
698
- });
699
- if (changedLeaf) {
700
- writeGroupRow(
701
- visitTree(tree, oldPath, void 0, ([, selectedRowIds]) => {
702
- collDel(selectedRowIds, selectedRowId);
703
- return collIsEmpty(selectedRowIds);
704
- }),
705
- changedGroupedSelectedCells,
706
- selectedRowId,
707
- 1,
708
- );
761
+ null,
762
+ (_store, _tableId, selectedRowId, getCellChange) => {
763
+ const oldPath = [];
764
+ const newPath = [];
765
+ const changedGroupedSelectedCells = mapNew();
766
+ const rowExists = selectJoinWhereStore.hasRow(
767
+ queryId,
768
+ selectedRowId,
769
+ );
770
+ let changedLeaf = !rowExists;
771
+ collForEach(groupBySelectedCellIds, (selectedCellId) => {
772
+ const [changed, oldCell, newCell] = getCellChange(
773
+ queryId,
774
+ selectedRowId,
775
+ selectedCellId,
776
+ );
777
+ arrayPush(oldPath, oldCell);
778
+ arrayPush(newPath, newCell);
779
+ changedLeaf ||= changed;
780
+ });
781
+ mapForEach(groupedSelectedCellIds, (selectedCellId) => {
782
+ const [changed, , newCell] = getCellChange(
783
+ queryId,
784
+ selectedRowId,
785
+ selectedCellId,
786
+ );
787
+ if (changedLeaf || changed) {
788
+ mapSet(changedGroupedSelectedCells, selectedCellId, [
789
+ newCell,
790
+ ]);
791
+ }
792
+ });
793
+ if (changedLeaf) {
794
+ writeGroupRow(
795
+ visitTree(tree, oldPath, void 0, ([, selectedRowIds]) => {
796
+ collDel(selectedRowIds, selectedRowId);
797
+ return collIsEmpty(selectedRowIds);
798
+ }),
799
+ changedGroupedSelectedCells,
800
+ selectedRowId,
801
+ 1,
802
+ );
803
+ }
804
+ if (rowExists) {
805
+ writeGroupRow(
806
+ visitTree(
807
+ tree,
808
+ newPath,
809
+ () => {
810
+ const groupRow = {};
811
+ collForEach(
812
+ groupBySelectedCellIds,
813
+ (selectedCellId) =>
814
+ (groupRow[selectedCellId] =
815
+ selectJoinWhereStore.getCell(
816
+ queryId,
817
+ selectedRowId,
818
+ selectedCellId,
819
+ )),
820
+ );
821
+ return [mapNew(), setNew(), void 0, groupRow];
822
+ },
823
+ ([, selectedRowIds]) => {
824
+ setAdd(selectedRowIds, selectedRowId);
825
+ },
826
+ ),
827
+ changedGroupedSelectedCells,
828
+ selectedRowId,
829
+ );
830
+ }
831
+ },
832
+ ),
833
+ );
834
+ }
835
+ synchronizeTransactions(queryId, rootStore, selectJoinWhereStore);
836
+ const writeSelectRow = (rootRowId) => {
837
+ const getJoinCell = (arg1, arg2, arg3) => {
838
+ const joinedTableId = isTrue(arg1) ? arg2 : arg1;
839
+ const joinedCellId = isTrue(arg1) ? arg3 : arg2;
840
+ if (isUndefined(joinedCellId)) {
841
+ return rootStore.getCell(tableId, rootRowId, arg1);
709
842
  }
710
- if (rowExists) {
711
- writeGroupRow(
712
- visitTree(
713
- tree,
714
- newPath,
715
- () => {
716
- const groupRow = {};
717
- collForEach(
718
- groupBySelectedCellIds,
719
- (selectedCellId) =>
720
- (groupRow[selectedCellId] =
721
- selectJoinWhereStore.getCell(
722
- queryId,
723
- selectedRowId,
724
- selectedCellId,
725
- )),
726
- );
727
- return [mapNew(), setNew(), void 0, groupRow];
728
- },
729
- ([, selectedRowIds]) => {
730
- setAdd(selectedRowIds, selectedRowId);
731
- },
732
- ),
733
- changedGroupedSelectedCells,
734
- selectedRowId,
735
- );
843
+ if (joinedTableId === tableId && !isTrue(arg1)) {
844
+ return rootStore.getCell(tableId, rootRowId, joinedCellId);
736
845
  }
737
- },
738
- ),
739
- );
740
- }
741
- synchronizeTransactions(queryId, store, selectJoinWhereStore);
742
- const writeSelectRow = (rootRowId) => {
743
- const getTableCell = (arg1, arg2) =>
744
- store.getCell(
745
- ...(isUndefined(arg2)
746
- ? [tableId, rootRowId, arg1]
747
- : arg1 === tableId
748
- ? [tableId, rootRowId, arg2]
749
- : [
750
- mapGet(joins, arg1)?.[0],
751
- mapGet(mapGet(joins, arg1)?.[4], rootRowId)?.[0],
752
- arg2,
753
- ]),
754
- );
755
- selectJoinWhereStore.transaction(() =>
756
- arrayEvery(wheres, (where2) => where2(getTableCell))
757
- ? mapForEach(selects, (asCellId, tableCellGetter) =>
758
- selectJoinWhereStore._[5](
759
- queryId,
760
- rootRowId,
761
- asCellId,
762
- tableCellGetter(getTableCell, rootRowId),
763
- ),
764
- )
765
- : selectJoinWhereStore.delRow(queryId, rootRowId),
766
- );
767
- };
768
- const listenToTable = (rootRowId, tableId2, rowId, joinedTableIds2) => {
769
- const getCell = (cellId) => store.getCell(tableId2, rowId, cellId);
770
- arrayForEach(joinedTableIds2, (remoteAsTableId) => {
771
- const [realJoinedTableId, , on, nextJoinedTableIds, remoteIdPairs] =
772
- mapGet(joins, remoteAsTableId);
773
- const remoteRowId = on?.(getCell, rootRowId);
774
- const [previousRemoteRowId, previousRemoteListenerId] =
775
- mapGet(remoteIdPairs, rootRowId) ?? [];
776
- if (remoteRowId != previousRemoteRowId) {
777
- if (!isUndefined(previousRemoteListenerId)) {
778
- delStoreListeners(queryId, previousRemoteListenerId);
779
- }
780
- mapSet(
781
- remoteIdPairs,
782
- rootRowId,
783
- isUndefined(remoteRowId)
846
+ const join2 = mapGet(joins, joinedTableId);
847
+ return isUndefined(join2)
784
848
  ? void 0
785
- : [
786
- remoteRowId,
787
- ...addStoreListeners(
849
+ : join2[5].getCell(
850
+ join2[0],
851
+ mapGet(join2[4], rootRowId)?.[0],
852
+ joinedCellId,
853
+ );
854
+ };
855
+ selectJoinWhereStore.transaction(() =>
856
+ arrayEvery(wheres, (where2) => where2(getJoinCell))
857
+ ? mapForEach(selects, (asCellId, tableCellGetter) =>
858
+ selectJoinWhereStore._[5](
788
859
  queryId,
789
- 1,
790
- store.addRowListener(realJoinedTableId, remoteRowId, () =>
791
- listenToTable(
792
- rootRowId,
793
- realJoinedTableId,
794
- remoteRowId,
795
- nextJoinedTableIds,
796
- ),
797
- ),
860
+ rootRowId,
861
+ asCellId,
862
+ tableCellGetter(getJoinCell, rootRowId),
798
863
  ),
799
- ],
864
+ )
865
+ : selectJoinWhereStore.delRow(queryId, rootRowId),
800
866
  );
801
- }
802
- });
803
- writeSelectRow(rootRowId);
804
- };
805
- const {3: joinedTableIds} = mapGet(joins, void 0);
806
- selectJoinWhereStore.transaction(() =>
807
- addStoreListeners(
808
- queryId,
809
- 1,
810
- store.addRowListener(tableId, null, (_store, _tableId, rootRowId) => {
811
- if (store.hasRow(tableId, rootRowId)) {
812
- listenToTable(rootRowId, tableId, rootRowId, joinedTableIds);
867
+ };
868
+ const listenToTable = (
869
+ rootRowId,
870
+ sourceStore,
871
+ tableId2,
872
+ rowId,
873
+ toJoinAliases2,
874
+ ) => {
875
+ const getCell = (cellId) =>
876
+ sourceStore.getCell(tableId2, rowId, cellId);
877
+ arrayForEach(toJoinAliases2, (joinAlias) => {
878
+ const [
879
+ realJoinedTableId,
880
+ ,
881
+ on,
882
+ nextJoinAliases,
883
+ remoteIdPairs,
884
+ remoteSourceStore,
885
+ ] = mapGet(joins, joinAlias);
886
+ const remoteRowId = on?.(getCell, rootRowId);
887
+ const previousRemote = mapGet(remoteIdPairs, rootRowId);
888
+ const previousRemoteRowId = previousRemote?.[0];
889
+ if (remoteRowId != previousRemoteRowId) {
890
+ ifNotUndefined(
891
+ previousRemote,
892
+ ([, previousRemoteSourceStore, previousRemoteListenerId]) =>
893
+ delSourceStoreListeners(
894
+ queryId,
895
+ previousRemoteSourceStore,
896
+ previousRemoteListenerId,
897
+ ),
898
+ );
899
+ mapSet(
900
+ remoteIdPairs,
901
+ rootRowId,
902
+ isUndefined(remoteRowId)
903
+ ? void 0
904
+ : [
905
+ remoteRowId,
906
+ remoteSourceStore,
907
+ ...addSourceStoreListeners(
908
+ remoteSourceStore,
909
+ queryId,
910
+ 1,
911
+ remoteSourceStore.addRowListener(
912
+ realJoinedTableId,
913
+ remoteRowId,
914
+ () =>
915
+ listenToTable(
916
+ rootRowId,
917
+ remoteSourceStore,
918
+ realJoinedTableId,
919
+ remoteRowId,
920
+ nextJoinAliases,
921
+ ),
922
+ ),
923
+ ),
924
+ ],
925
+ );
926
+ }
927
+ });
928
+ writeSelectRow(rootRowId);
929
+ };
930
+ const {3: toJoinAliases} = mapGet(joins, void 0);
931
+ const rootRowChanged = (sourceStore, _tableId, rootRowId) => {
932
+ if (rootStore.hasRow(tableId, rootRowId)) {
933
+ listenToTable(
934
+ rootRowId,
935
+ rootStore,
936
+ tableId,
937
+ rootRowId,
938
+ toJoinAliases,
939
+ );
813
940
  } else {
814
941
  selectJoinWhereStore.delRow(queryId, rootRowId);
815
942
  collForEach(joins, ({4: idsByRootRowId}) =>
816
943
  ifNotUndefined(
817
944
  mapGet(idsByRootRowId, rootRowId),
818
- ([, listenerId]) => {
819
- delStoreListeners(queryId, listenerId);
945
+ ([, sourceStore2, listenerId]) => {
946
+ delSourceStoreListeners(queryId, sourceStore2, listenerId);
820
947
  mapSet(idsByRootRowId, rootRowId);
821
948
  },
822
949
  ),
823
950
  );
824
951
  }
825
- }),
826
- ),
952
+ };
953
+ selectJoinWhereStore.transaction(() => {
954
+ arrayForEach(rootStore.getRowIds(tableId), (rootRowId) =>
955
+ rootRowChanged(rootStore, tableId, rootRowId),
956
+ );
957
+ addSourceStoreListeners(
958
+ rootStore,
959
+ queryId,
960
+ 0,
961
+ rootStore.addRowListener(tableId, null, rootRowChanged),
962
+ );
963
+ });
964
+ collDel(redefiningQueryIds, queryId);
965
+ return queries;
966
+ }),
827
967
  );
828
- return queries;
829
- };
830
- const callParamListeners = (queryId, oldParamValues, newParamValues) => {
831
- const allParamIds = setNew([
832
- ...objIds(oldParamValues),
833
- ...objIds(newParamValues),
834
- ]);
835
- let changed = 0;
836
- collForEach(allParamIds, (paramId) => {
837
- const newParamValue = objGet(newParamValues, paramId);
838
- if (!arrayOrValueEqual(objGet(oldParamValues, paramId), newParamValue)) {
839
- changed = 1;
840
- callListeners(paramValueListeners, [queryId, paramId], newParamValue);
841
- }
842
- });
843
- if (changed) {
844
- callListeners(paramValuesListeners, [queryId], newParamValues);
845
- }
846
- };
847
968
  const delQueryDefinition = (queryId) => {
848
- const oldParamValues = getParamValues(queryId);
969
+ ifNotUndefined(getQueryArgs(queryId), ([, listenerId]) =>
970
+ paramStore.delListener(listenerId),
971
+ );
972
+ paramStore.delRow(PARAMS_TABLE, queryId);
849
973
  resetPreStores(queryId);
974
+ resetSourceStores(queryId);
850
975
  delDefinition(queryId);
851
- callParamListeners(queryId, oldParamValues, {});
852
976
  return queries;
853
977
  };
854
- const setParamValues = (queryId, paramValues, force = 0) => {
855
- ifNotUndefined(getQueryArgs(queryId), ([definition, oldParamValues]) => {
856
- if (
857
- force ||
858
- !objIsEqual(mapToObj(oldParamValues), paramValues, arrayOrValueEqual)
859
- ) {
860
- resultStore.transaction(() =>
861
- setQueryDefinition(
862
- queryId,
863
- getTableId(queryId),
864
- definition,
865
- paramValues,
866
- ),
867
- );
868
- }
869
- });
978
+ const setParamValues = (queryId, paramValues) => {
979
+ if (hasQuery(queryId)) {
980
+ setOrDelParamValues(queryId, paramValues);
981
+ }
870
982
  return queries;
871
983
  };
872
984
  const setParamValue = (queryId, paramId, value) => {
873
- if (!arrayOrValueEqual(getParamValue(queryId, paramId), value)) {
874
- setParamValues(
875
- queryId,
876
- {...getParamValues(queryId), [paramId]: value},
877
- 1,
878
- );
985
+ if (hasQuery(queryId)) {
986
+ paramStore.setCell(PARAMS_TABLE, queryId, paramId, value);
879
987
  }
880
988
  return queries;
881
989
  };
882
- const getParamValues = (queryId) => mapToObj(getQueryArgs(queryId)?.[1]);
990
+ const getParamValues = (queryId) => paramStore.getRow(PARAMS_TABLE, queryId);
883
991
  const getParamValue = (queryId, paramId) =>
884
- mapGet(getQueryArgs(queryId)?.[1], paramId);
992
+ paramStore.getCell(PARAMS_TABLE, queryId, paramId);
885
993
  const addQueryIdsListener = (listener) =>
886
994
  addQueryIdsListenerImpl(() => listener(queries));
995
+ const forEachResultTable = (tableCallback) =>
996
+ forEachQuery((queryId) =>
997
+ getResultStore(queryId).hasTable(queryId)
998
+ ? tableCallback(queryId, (rowCallback) =>
999
+ queries.forEachResultRow(queryId, rowCallback),
1000
+ )
1001
+ : 0,
1002
+ );
887
1003
  const addParamValuesListener = (queryId, listener) =>
888
- addListener(
889
- (_, queryId2, paramValues) => listener(queries, queryId2, paramValues),
890
- paramValuesListeners,
891
- [queryId],
1004
+ PARAM_LISTENER_PREFIX +
1005
+ paramStore.addRowListener(
1006
+ PARAMS_TABLE,
1007
+ queryId,
1008
+ (_store, _tableId, queryId2) =>
1009
+ listener(queries, queryId2, getParamValues(queryId2)),
892
1010
  );
893
1011
  const addParamValueListener = (queryId, paramId, listener) =>
894
- addListener(
895
- (_, queryId2, paramId2, paramValue) =>
1012
+ PARAM_LISTENER_PREFIX +
1013
+ paramStore.addCellListener(
1014
+ PARAMS_TABLE,
1015
+ queryId,
1016
+ paramId,
1017
+ (_store, _tableId, queryId2, paramId2, paramValue) =>
896
1018
  listener(queries, queryId2, paramId2, paramValue),
897
- paramValueListeners,
898
- [queryId, paramId],
899
1019
  );
900
1020
  const delListener = (listenerId) => {
901
- delListenerImpl(listenerId);
1021
+ const routedResultListener = mapGet(routedResultListeners, listenerId);
1022
+ if (listenerId[0] == PARAM_LISTENER_PREFIX) {
1023
+ paramStore.delListener(slice(listenerId, 1));
1024
+ } else if (!isUndefined(routedResultListener)) {
1025
+ const [stat, storeListenerIds, queryIdsListenerId] = routedResultListener;
1026
+ mapForEach(storeListenerIds, (_queryId, [store2, storeListenerId]) =>
1027
+ store2.delListener(storeListenerId),
1028
+ );
1029
+ ifNotUndefined(queryIdsListenerId, delListenerImpl);
1030
+ mapSet(routedResultListeners, listenerId);
1031
+ delListenerImpl(listenerId);
1032
+ resultListenerStats[stat]--;
1033
+ } else {
1034
+ delListenerImpl(listenerId);
1035
+ }
902
1036
  return queries;
903
1037
  };
904
- const getListenerStats = () => {
905
- const {
906
- tables: _1,
907
- tableIds: _2,
908
- transaction: _3,
909
- ...stats
910
- } = resultStore.getListenerStats();
911
- return {
912
- ...stats,
913
- paramValues: collSize2(paramValuesListeners),
914
- paramValue: collSize3(paramValueListeners),
915
- };
1038
+ const getListenerStats = () => ({
1039
+ ...resultListenerStats,
1040
+ paramValues: paramStore.getListenerStats().row - size(getQueryIds()),
1041
+ paramValue: paramStore.getListenerStats().cell,
1042
+ });
1043
+ const destroy = () => {
1044
+ arrayForEach(getQueryIds(), delQueryDefinition);
1045
+ destroyImpl();
916
1046
  };
917
1047
  const queries = {
918
1048
  setQueryDefinition,
@@ -926,6 +1056,7 @@ const createQueries = getCreateFunction((store) => {
926
1056
  forEachQuery,
927
1057
  hasQuery,
928
1058
  getTableId,
1059
+ forEachResultTable,
929
1060
  addQueryIdsListener,
930
1061
  addParamValuesListener,
931
1062
  addParamValueListener,
@@ -933,30 +1064,41 @@ const createQueries = getCreateFunction((store) => {
933
1064
  destroy,
934
1065
  getListenerStats,
935
1066
  };
1067
+ const getListenerArgs = (args, argumentCount) =>
1068
+ argumentCount == 5
1069
+ ? [args[0], args[1] ?? void 0, args[2], args[3], args[4]]
1070
+ : slice(args, 0, argumentCount);
1071
+ const getResultListenerStat = (gettable) =>
1072
+ gettable[0].toLowerCase() + slice(gettable, 1);
936
1073
  objMap(
937
1074
  {
938
- [TABLE]: [1, 1],
939
- [TABLE + CELL_IDS]: [0, 1],
940
- [ROW_COUNT]: [0, 1],
941
- [ROW_IDS]: [0, 1],
942
- [SORTED_ROW_IDS]: [0, 5],
943
- [ROW]: [1, 2],
944
- [CELL_IDS]: [0, 2],
945
- [CELL]: [1, 3],
1075
+ [TABLE]: [2, 1],
1076
+ [TABLE + CELL_IDS]: [1, 1],
1077
+ [ROW_COUNT]: [1, 1],
1078
+ [ROW_IDS]: [1, 1],
1079
+ [SORTED_ROW_IDS]: [1, 5],
1080
+ [ROW]: [3, 2],
1081
+ [CELL_IDS]: [1, 2],
1082
+ [CELL]: [3, 3],
946
1083
  },
947
- ([hasAndForEach, argumentCount], gettable) => {
1084
+ ([prefixCount, argumentCount], gettable) => {
948
1085
  arrayForEach(
949
- hasAndForEach ? [GET, 'has', 'forEach'] : [GET],
1086
+ slice([GET, 'has', 'forEach'], 0, prefixCount),
950
1087
  (prefix) =>
951
1088
  (queries[prefix + RESULT + gettable] = (...args) =>
952
- resultStore[prefix + gettable](...args)),
1089
+ getResultStore(args[0])[prefix + gettable](...args)),
953
1090
  );
954
1091
  queries[ADD + RESULT + gettable + LISTENER] = (...args) =>
955
- resultStore[ADD + gettable + LISTENER](
956
- ...slice(args, 0, argumentCount),
957
- (_store, ...listenerArgs) =>
958
- args[argumentCount](queries, ...listenerArgs),
959
- true,
1092
+ addRoutedResultListener(
1093
+ getResultListenerStat(gettable),
1094
+ args[0],
1095
+ (store2) =>
1096
+ store2[ADD + gettable + LISTENER](
1097
+ ...getListenerArgs(args, argumentCount),
1098
+ (_store, ...listenerArgs) =>
1099
+ args[argumentCount](queries, ...listenerArgs),
1100
+ true,
1101
+ ),
960
1102
  );
961
1103
  },
962
1104
  );