tinybase 2.2.6 → 3.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/bin/cli.js +1 -1
- package/lib/checkpoints.d.ts +18 -3
- package/lib/checkpoints.js +1 -1
- package/lib/checkpoints.js.gz +0 -0
- package/lib/debug/checkpoints.d.ts +18 -3
- package/lib/debug/checkpoints.js +97 -49
- package/lib/debug/indexes.js +31 -16
- package/lib/debug/metrics.js +31 -16
- package/lib/debug/persisters.d.ts +33 -23
- package/lib/debug/persisters.js +10 -5
- package/lib/debug/queries.js +2 -2
- package/lib/debug/relationships.js +31 -16
- package/lib/debug/store.d.ts +2022 -383
- package/lib/debug/store.js +440 -108
- package/lib/debug/tinybase.js +508 -140
- package/lib/debug/tools.d.ts +89 -38
- package/lib/debug/tools.js +757 -453
- package/lib/debug/ui-react.d.ts +1525 -381
- package/lib/debug/ui-react.js +163 -12
- package/lib/es6/checkpoints.d.ts +18 -3
- package/lib/es6/checkpoints.js +1 -1
- package/lib/es6/checkpoints.js.gz +0 -0
- package/lib/es6/indexes.js +1 -1
- package/lib/es6/indexes.js.gz +0 -0
- package/lib/es6/metrics.js +1 -1
- package/lib/es6/metrics.js.gz +0 -0
- package/lib/es6/persisters.d.ts +33 -23
- package/lib/es6/persisters.js +1 -1
- package/lib/es6/persisters.js.gz +0 -0
- package/lib/es6/relationships.js +1 -1
- package/lib/es6/relationships.js.gz +0 -0
- package/lib/es6/store.d.ts +2022 -383
- package/lib/es6/store.js +1 -1
- package/lib/es6/store.js.gz +0 -0
- package/lib/es6/tinybase.js +1 -1
- package/lib/es6/tinybase.js.gz +0 -0
- package/lib/es6/tools.d.ts +89 -38
- package/lib/es6/tools.js +1 -1
- package/lib/es6/tools.js.gz +0 -0
- package/lib/es6/ui-react.d.ts +1525 -381
- package/lib/es6/ui-react.js +1 -1
- package/lib/es6/ui-react.js.gz +0 -0
- 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/persisters.d.ts +33 -23
- package/lib/persisters.js +1 -1
- package/lib/persisters.js.gz +0 -0
- package/lib/relationships.js +1 -1
- package/lib/relationships.js.gz +0 -0
- package/lib/store.d.ts +2022 -383
- package/lib/store.js +1 -1
- package/lib/store.js.gz +0 -0
- package/lib/tinybase.js +1 -1
- package/lib/tinybase.js.gz +0 -0
- package/lib/tools.d.ts +89 -38
- package/lib/tools.js +1 -1
- package/lib/tools.js.gz +0 -0
- package/lib/ui-react.d.ts +1525 -381
- package/lib/ui-react.js +1 -1
- package/lib/ui-react.js.gz +0 -0
- package/lib/umd/checkpoints.d.ts +18 -3
- 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/persisters.d.ts +33 -23
- package/lib/umd/persisters.js +1 -1
- package/lib/umd/persisters.js.gz +0 -0
- package/lib/umd/relationships.js +1 -1
- package/lib/umd/relationships.js.gz +0 -0
- package/lib/umd/store.d.ts +2022 -383
- package/lib/umd/store.js +1 -1
- package/lib/umd/store.js.gz +0 -0
- package/lib/umd/tinybase.js +1 -1
- package/lib/umd/tinybase.js.gz +0 -0
- package/lib/umd/tools.d.ts +89 -38
- package/lib/umd/tools.js +1 -1
- package/lib/umd/tools.js.gz +0 -0
- package/lib/umd/ui-react.d.ts +1525 -381
- package/lib/umd/ui-react.js +1 -1
- package/lib/umd/ui-react.js.gz +0 -0
- package/lib/umd-es6/checkpoints.d.ts +18 -3
- package/lib/umd-es6/checkpoints.js +1 -1
- package/lib/umd-es6/checkpoints.js.gz +0 -0
- package/lib/umd-es6/indexes.js +1 -1
- package/lib/umd-es6/indexes.js.gz +0 -0
- package/lib/umd-es6/metrics.js +1 -1
- package/lib/umd-es6/metrics.js.gz +0 -0
- package/lib/umd-es6/persisters.d.ts +33 -23
- package/lib/umd-es6/persisters.js +1 -1
- package/lib/umd-es6/persisters.js.gz +0 -0
- package/lib/umd-es6/relationships.js +1 -1
- package/lib/umd-es6/relationships.js.gz +0 -0
- package/lib/umd-es6/store.d.ts +2022 -383
- package/lib/umd-es6/store.js +1 -1
- package/lib/umd-es6/store.js.gz +0 -0
- package/lib/umd-es6/tinybase.js +1 -1
- package/lib/umd-es6/tinybase.js.gz +0 -0
- package/lib/umd-es6/tools.d.ts +89 -38
- package/lib/umd-es6/tools.js +1 -1
- package/lib/umd-es6/tools.js.gz +0 -0
- package/lib/umd-es6/ui-react.d.ts +1525 -381
- package/lib/umd-es6/ui-react.js +1 -1
- package/lib/umd-es6/ui-react.js.gz +0 -0
- package/package.json +26 -26
- package/readme.md +20 -19
package/lib/debug/tinybase.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import {promises, watch} from 'fs';
|
|
2
2
|
|
|
3
3
|
const getTypeOf = (thing) => typeof thing;
|
|
4
|
-
const EMPTY_OBJECT = '{}';
|
|
5
4
|
const EMPTY_STRING = '';
|
|
6
5
|
const STRING = getTypeOf(EMPTY_STRING);
|
|
7
6
|
const BOOLEAN = getTypeOf(true);
|
|
@@ -26,6 +25,9 @@ const SORTED_ROW_IDS = 'SortedRowIds';
|
|
|
26
25
|
const ROW = 'Row';
|
|
27
26
|
const CELL_IDS = 'CellIds';
|
|
28
27
|
const CELL = 'Cell';
|
|
28
|
+
const VALUES = 'Values';
|
|
29
|
+
const VALUE_IDS = 'ValueIds';
|
|
30
|
+
const VALUE = 'Value';
|
|
29
31
|
const id = (key) => EMPTY_STRING + key;
|
|
30
32
|
|
|
31
33
|
const arrayHas = (array, value) => array.includes(value);
|
|
@@ -148,6 +150,19 @@ const visitTree = (node, path, ensureLeaf, pruneLeaf, p = 0) =>
|
|
|
148
150
|
},
|
|
149
151
|
);
|
|
150
152
|
|
|
153
|
+
const getCellOrValueType = (cell) => {
|
|
154
|
+
const type = getTypeOf(cell);
|
|
155
|
+
return isTypeStringOrBoolean(type) || (type == NUMBER && isFiniteNumber(cell))
|
|
156
|
+
? type
|
|
157
|
+
: void 0;
|
|
158
|
+
};
|
|
159
|
+
const setOrDelCell = (store, tableId, rowId, cellId, cell) =>
|
|
160
|
+
isUndefined(cell)
|
|
161
|
+
? store.delCell(tableId, rowId, cellId, true)
|
|
162
|
+
: store.setCell(tableId, rowId, cellId, cell);
|
|
163
|
+
const setOrDelValue = (store, valueId, value) =>
|
|
164
|
+
isUndefined(value) ? store.delValue(valueId) : store.setValue(valueId, value);
|
|
165
|
+
|
|
151
166
|
const setNew = (entryOrEntries) =>
|
|
152
167
|
new Set(
|
|
153
168
|
isArray(entryOrEntries) || isUndefined(entryOrEntries)
|
|
@@ -343,10 +358,22 @@ const getListenerFunctions = (getThing) => {
|
|
|
343
358
|
let thing;
|
|
344
359
|
const [getId, releaseId] = getPoolFunctions();
|
|
345
360
|
const allListeners = mapNew();
|
|
346
|
-
const addListener = (
|
|
361
|
+
const addListener = (
|
|
362
|
+
listener,
|
|
363
|
+
idSetNode,
|
|
364
|
+
path,
|
|
365
|
+
pathGetters = [],
|
|
366
|
+
extraArgsGetter = () => [],
|
|
367
|
+
) => {
|
|
347
368
|
thing ??= getThing();
|
|
348
369
|
const id = getId();
|
|
349
|
-
mapSet(allListeners, id, [
|
|
370
|
+
mapSet(allListeners, id, [
|
|
371
|
+
listener,
|
|
372
|
+
idSetNode,
|
|
373
|
+
path,
|
|
374
|
+
pathGetters,
|
|
375
|
+
extraArgsGetter,
|
|
376
|
+
]);
|
|
350
377
|
setAdd(visitTree(idSetNode, path ?? [EMPTY_STRING], setNew), id);
|
|
351
378
|
return id;
|
|
352
379
|
};
|
|
@@ -366,20 +393,23 @@ const getListenerFunctions = (getThing) => {
|
|
|
366
393
|
releaseId(id);
|
|
367
394
|
return idOrNulls;
|
|
368
395
|
});
|
|
369
|
-
const callListener = (id
|
|
370
|
-
ifNotUndefined(
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
)
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
396
|
+
const callListener = (id) =>
|
|
397
|
+
ifNotUndefined(
|
|
398
|
+
mapGet(allListeners, id),
|
|
399
|
+
([listener, , path = [], pathGetters, extraArgsGetter]) => {
|
|
400
|
+
const callWithIds = (...ids) => {
|
|
401
|
+
const index = arrayLength(ids);
|
|
402
|
+
index == arrayLength(path)
|
|
403
|
+
? listener(thing, ...ids, ...extraArgsGetter(ids))
|
|
404
|
+
: isUndefined(path[index])
|
|
405
|
+
? arrayForEach(pathGetters[index]?.(...ids) ?? [], (id2) =>
|
|
406
|
+
callWithIds(...ids, id2),
|
|
407
|
+
)
|
|
408
|
+
: callWithIds(...ids, path[index]);
|
|
409
|
+
};
|
|
410
|
+
callWithIds();
|
|
411
|
+
},
|
|
412
|
+
);
|
|
383
413
|
return [addListener, callListeners, delListener, callListener];
|
|
384
414
|
};
|
|
385
415
|
|
|
@@ -394,23 +424,13 @@ const objHas = (obj, id) => !isUndefined(objGet(obj, id));
|
|
|
394
424
|
const objDel = (obj, id) => delete obj[id];
|
|
395
425
|
const objMap = (obj, cb) =>
|
|
396
426
|
arrayMap(object.entries(obj), ([id, value]) => cb(value, id));
|
|
397
|
-
const objIsEmpty = (obj) => arrayIsEmpty(objIds(obj));
|
|
398
|
-
|
|
399
|
-
const getCellType = (cell) => {
|
|
400
|
-
const type = getTypeOf(cell);
|
|
401
|
-
return isTypeStringOrBoolean(type) || (type == NUMBER && isFiniteNumber(cell))
|
|
402
|
-
? type
|
|
403
|
-
: void 0;
|
|
404
|
-
};
|
|
405
|
-
const setOrDelCell = (store, tableId, rowId, cellId, cell) =>
|
|
406
|
-
isUndefined(cell)
|
|
407
|
-
? store.delCell(tableId, rowId, cellId, true)
|
|
408
|
-
: store.setCell(tableId, rowId, cellId, cell);
|
|
427
|
+
const objIsEmpty = (obj) => isObject(obj) && arrayIsEmpty(objIds(obj));
|
|
409
428
|
|
|
410
429
|
const createCheckpoints = getCreateFunction((store) => {
|
|
411
430
|
let backwardIdsSize = 100;
|
|
412
431
|
let currentId;
|
|
413
|
-
let
|
|
432
|
+
let cellsDelta = mapNew();
|
|
433
|
+
let valuesDelta = mapNew();
|
|
414
434
|
let listening = 1;
|
|
415
435
|
let nextCheckpointId;
|
|
416
436
|
let checkpointsChanged;
|
|
@@ -425,15 +445,19 @@ const createCheckpoints = getCreateFunction((store) => {
|
|
|
425
445
|
const forwardIds = [];
|
|
426
446
|
const updateStore = (oldOrNew, checkpointId) => {
|
|
427
447
|
listening = 0;
|
|
428
|
-
store.transaction(() =>
|
|
429
|
-
|
|
448
|
+
store.transaction(() => {
|
|
449
|
+
const [cellsDelta2, valuesDelta2] = mapGet(deltas, checkpointId);
|
|
450
|
+
collForEach(cellsDelta2, (table, tableId) =>
|
|
430
451
|
collForEach(table, (row, rowId) =>
|
|
431
452
|
collForEach(row, (oldNew, cellId) =>
|
|
432
453
|
setOrDelCell(store, tableId, rowId, cellId, oldNew[oldOrNew]),
|
|
433
454
|
),
|
|
434
455
|
),
|
|
435
|
-
)
|
|
436
|
-
|
|
456
|
+
);
|
|
457
|
+
collForEach(valuesDelta2, (oldNew, valueId) =>
|
|
458
|
+
setOrDelValue(store, valueId, oldNew[oldOrNew]),
|
|
459
|
+
);
|
|
460
|
+
});
|
|
437
461
|
listening = 1;
|
|
438
462
|
};
|
|
439
463
|
const clearCheckpointId = (checkpointId) => {
|
|
@@ -448,32 +472,56 @@ const createCheckpoints = getCreateFunction((store) => {
|
|
|
448
472
|
);
|
|
449
473
|
const trimBackwardsIds = () =>
|
|
450
474
|
clearCheckpointIds(backwardIds, arrayLength(backwardIds) - backwardIdsSize);
|
|
451
|
-
const
|
|
475
|
+
const storeChanged = () =>
|
|
476
|
+
ifNotUndefined(currentId, () => {
|
|
477
|
+
arrayPush(backwardIds, currentId);
|
|
478
|
+
trimBackwardsIds();
|
|
479
|
+
clearCheckpointIds(forwardIds);
|
|
480
|
+
currentId = void 0;
|
|
481
|
+
checkpointsChanged = 1;
|
|
482
|
+
});
|
|
483
|
+
const storeUnchanged = () => {
|
|
484
|
+
currentId = arrayPop(backwardIds);
|
|
485
|
+
checkpointsChanged = 1;
|
|
486
|
+
};
|
|
487
|
+
const cellListenerId = store.addCellListener(
|
|
452
488
|
null,
|
|
453
489
|
null,
|
|
454
490
|
null,
|
|
455
491
|
(_store, tableId, rowId, cellId, newCell, oldCell) => {
|
|
456
492
|
if (listening) {
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
trimBackwardsIds();
|
|
460
|
-
clearCheckpointIds(forwardIds);
|
|
461
|
-
currentId = void 0;
|
|
462
|
-
checkpointsChanged = 1;
|
|
463
|
-
});
|
|
464
|
-
const table = mapEnsure(delta, tableId, mapNew);
|
|
493
|
+
storeChanged();
|
|
494
|
+
const table = mapEnsure(cellsDelta, tableId, mapNew);
|
|
465
495
|
const row = mapEnsure(table, rowId, mapNew);
|
|
466
496
|
const oldNew = mapEnsure(row, cellId, () => [oldCell, void 0]);
|
|
467
497
|
oldNew[1] = newCell;
|
|
468
|
-
if (
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
498
|
+
if (
|
|
499
|
+
oldNew[0] === newCell &&
|
|
500
|
+
collIsEmpty(mapSet(row, cellId)) &&
|
|
501
|
+
collIsEmpty(mapSet(table, rowId)) &&
|
|
502
|
+
collIsEmpty(mapSet(cellsDelta, tableId))
|
|
503
|
+
) {
|
|
504
|
+
storeUnchanged();
|
|
505
|
+
}
|
|
506
|
+
callListenersIfChanged();
|
|
507
|
+
}
|
|
508
|
+
},
|
|
509
|
+
);
|
|
510
|
+
const valueListenerId = store.addValueListener(
|
|
511
|
+
null,
|
|
512
|
+
(_store, valueId, newValue, oldValue) => {
|
|
513
|
+
if (listening) {
|
|
514
|
+
storeChanged();
|
|
515
|
+
const oldNew = mapEnsure(valuesDelta, valueId, () => [
|
|
516
|
+
oldValue,
|
|
517
|
+
void 0,
|
|
518
|
+
]);
|
|
519
|
+
oldNew[1] = newValue;
|
|
520
|
+
if (
|
|
521
|
+
oldNew[0] === newValue &&
|
|
522
|
+
collIsEmpty(mapSet(valuesDelta, valueId))
|
|
523
|
+
) {
|
|
524
|
+
storeUnchanged();
|
|
477
525
|
}
|
|
478
526
|
callListenersIfChanged();
|
|
479
527
|
}
|
|
@@ -482,9 +530,10 @@ const createCheckpoints = getCreateFunction((store) => {
|
|
|
482
530
|
const addCheckpointImpl = (label = EMPTY_STRING) => {
|
|
483
531
|
if (isUndefined(currentId)) {
|
|
484
532
|
currentId = EMPTY_STRING + nextCheckpointId++;
|
|
485
|
-
mapSet(deltas, currentId,
|
|
533
|
+
mapSet(deltas, currentId, [cellsDelta, valuesDelta]);
|
|
486
534
|
setCheckpoint(currentId, label);
|
|
487
|
-
|
|
535
|
+
cellsDelta = mapNew();
|
|
536
|
+
valuesDelta = mapNew();
|
|
488
537
|
checkpointsChanged = 1;
|
|
489
538
|
}
|
|
490
539
|
return currentId;
|
|
@@ -560,8 +609,8 @@ const createCheckpoints = getCreateFunction((store) => {
|
|
|
560
609
|
addListener(listener, checkpointIdsListeners);
|
|
561
610
|
const addCheckpointListener = (checkpointId, listener) =>
|
|
562
611
|
addListener(listener, checkpointListeners, [checkpointId]);
|
|
563
|
-
const delListener = (
|
|
564
|
-
delListenerImpl(
|
|
612
|
+
const delListener = (listenerId) => {
|
|
613
|
+
delListenerImpl(listenerId);
|
|
565
614
|
return checkpoints;
|
|
566
615
|
};
|
|
567
616
|
const clear = () => {
|
|
@@ -576,7 +625,8 @@ const createCheckpoints = getCreateFunction((store) => {
|
|
|
576
625
|
return checkpoints;
|
|
577
626
|
};
|
|
578
627
|
const destroy = () => {
|
|
579
|
-
store.delListener(
|
|
628
|
+
store.delListener(cellListenerId);
|
|
629
|
+
store.delListener(valueListenerId);
|
|
580
630
|
};
|
|
581
631
|
const getListenerStats = () => ({
|
|
582
632
|
checkpointIds: collSize2(checkpointIdsListeners),
|
|
@@ -969,11 +1019,12 @@ const createCustomPersister = (
|
|
|
969
1019
|
stopListeningToPersisted,
|
|
970
1020
|
) => {
|
|
971
1021
|
let tablesListenerId;
|
|
1022
|
+
let valuesListenerId;
|
|
972
1023
|
let loadSave = 0;
|
|
973
1024
|
let loads = 0;
|
|
974
1025
|
let saves = 0;
|
|
975
1026
|
const persister = {
|
|
976
|
-
load: async (initialTables) => {
|
|
1027
|
+
load: async (initialTables, initialValues) => {
|
|
977
1028
|
/* istanbul ignore else */
|
|
978
1029
|
if (loadSave != 2) {
|
|
979
1030
|
loadSave = 1;
|
|
@@ -984,15 +1035,17 @@ const createCustomPersister = (
|
|
|
984
1035
|
if (!isUndefined(body) && body != EMPTY_STRING) {
|
|
985
1036
|
store.setJson(body);
|
|
986
1037
|
} else {
|
|
987
|
-
store.
|
|
1038
|
+
store.transaction(() =>
|
|
1039
|
+
store.setTables(initialTables).setValues(initialValues),
|
|
1040
|
+
);
|
|
988
1041
|
}
|
|
989
1042
|
loadSave = 0;
|
|
990
1043
|
}
|
|
991
1044
|
return persister;
|
|
992
1045
|
},
|
|
993
|
-
startAutoLoad: async (initialTables) => {
|
|
1046
|
+
startAutoLoad: async (initialTables, initialValues) => {
|
|
994
1047
|
persister.stopAutoLoad();
|
|
995
|
-
await persister.load(initialTables);
|
|
1048
|
+
await persister.load(initialTables, initialValues);
|
|
996
1049
|
startListeningToPersisted(persister.load);
|
|
997
1050
|
return persister;
|
|
998
1051
|
},
|
|
@@ -1014,11 +1067,13 @@ const createCustomPersister = (
|
|
|
1014
1067
|
},
|
|
1015
1068
|
startAutoSave: async () => {
|
|
1016
1069
|
await persister.stopAutoSave().save();
|
|
1017
|
-
tablesListenerId = store.addTablesListener(
|
|
1070
|
+
tablesListenerId = store.addTablesListener(persister.save);
|
|
1071
|
+
valuesListenerId = store.addValuesListener(persister.save);
|
|
1018
1072
|
return persister;
|
|
1019
1073
|
},
|
|
1020
1074
|
stopAutoSave: () => {
|
|
1021
1075
|
ifNotUndefined(tablesListenerId, store.delListener);
|
|
1076
|
+
ifNotUndefined(valuesListenerId, store.delListener);
|
|
1022
1077
|
return persister;
|
|
1023
1078
|
},
|
|
1024
1079
|
getStore: () => store,
|
|
@@ -1326,7 +1381,7 @@ const createQueries = getCreateFunction((store) => {
|
|
|
1326
1381
|
aggregators,
|
|
1327
1382
|
);
|
|
1328
1383
|
groupRow[groupedCellId] = isUndefined(
|
|
1329
|
-
|
|
1384
|
+
getCellOrValueType(aggregateValue),
|
|
1330
1385
|
)
|
|
1331
1386
|
? null
|
|
1332
1387
|
: aggregateValue;
|
|
@@ -1790,18 +1845,27 @@ const validate = (obj, validateChild, onInvalidObj) => {
|
|
|
1790
1845
|
const idsChanged = (changedIds, id2, added) =>
|
|
1791
1846
|
mapSet(changedIds, id2, mapGet(changedIds, id2) == -added ? void 0 : added);
|
|
1792
1847
|
const createStore = () => {
|
|
1793
|
-
let
|
|
1848
|
+
let hasTablesSchema;
|
|
1849
|
+
let hasValuesSchema;
|
|
1794
1850
|
let cellsTouched;
|
|
1851
|
+
let valuesTouched;
|
|
1795
1852
|
let transactions = 0;
|
|
1796
1853
|
const changedTableIds = mapNew();
|
|
1797
1854
|
const changedRowIds = mapNew();
|
|
1798
1855
|
const changedCellIds = mapNew();
|
|
1799
1856
|
const changedCells = mapNew();
|
|
1857
|
+
const changedValueIds = mapNew();
|
|
1858
|
+
const changedValues = mapNew();
|
|
1800
1859
|
const invalidCells = mapNew();
|
|
1801
|
-
const
|
|
1802
|
-
const
|
|
1860
|
+
const invalidValues = mapNew();
|
|
1861
|
+
const tablesSchemaMap = mapNew();
|
|
1862
|
+
const tablesSchemaRowCache = mapNew();
|
|
1863
|
+
const valuesSchemaMap = mapNew();
|
|
1864
|
+
const valuesDefaulted = mapNew();
|
|
1865
|
+
const valuesNonDefaulted = setNew();
|
|
1803
1866
|
const tablePoolFunctions = mapNew();
|
|
1804
1867
|
const tablesMap = mapNew();
|
|
1868
|
+
const valuesMap = mapNew();
|
|
1805
1869
|
const tablesListeners = pairNewMap();
|
|
1806
1870
|
const tableIdsListeners = pairNewMap();
|
|
1807
1871
|
const tableListeners = pairNewMap();
|
|
@@ -1811,31 +1875,38 @@ const createStore = () => {
|
|
|
1811
1875
|
const cellIdsListeners = pairNewMap();
|
|
1812
1876
|
const cellListeners = pairNewMap();
|
|
1813
1877
|
const invalidCellListeners = pairNewMap();
|
|
1878
|
+
const invalidValueListeners = pairNewMap();
|
|
1879
|
+
const valuesListeners = pairNewMap();
|
|
1880
|
+
const valueIdsListeners = pairNewMap();
|
|
1881
|
+
const valueListeners = pairNewMap();
|
|
1814
1882
|
const finishTransactionListeners = pairNewMap();
|
|
1815
1883
|
const [addListener, callListeners, delListenerImpl, callListenerImpl] =
|
|
1816
1884
|
getListenerFunctions(() => store);
|
|
1817
|
-
const
|
|
1818
|
-
validate(
|
|
1819
|
-
validate(
|
|
1820
|
-
if (
|
|
1821
|
-
!validate(cellSchema, (_child, id2) => arrayHas([TYPE, DEFAULT], id2))
|
|
1822
|
-
) {
|
|
1823
|
-
return false;
|
|
1824
|
-
}
|
|
1825
|
-
const type = cellSchema[TYPE];
|
|
1826
|
-
if (!isTypeStringOrBoolean(type) && type != NUMBER) {
|
|
1827
|
-
return false;
|
|
1828
|
-
}
|
|
1829
|
-
if (getCellType(cellSchema[DEFAULT]) != type) {
|
|
1830
|
-
objDel(cellSchema, DEFAULT);
|
|
1831
|
-
}
|
|
1832
|
-
return true;
|
|
1833
|
-
}),
|
|
1885
|
+
const validateTablesSchema = (tableSchema) =>
|
|
1886
|
+
validate(tableSchema, (tableSchema2) =>
|
|
1887
|
+
validate(tableSchema2, validateCellOrValueSchema),
|
|
1834
1888
|
);
|
|
1889
|
+
const validateValuesSchema = (valuesSchema) =>
|
|
1890
|
+
validate(valuesSchema, validateCellOrValueSchema);
|
|
1891
|
+
const validateCellOrValueSchema = (schema) => {
|
|
1892
|
+
if (!validate(schema, (_child, id2) => arrayHas([TYPE, DEFAULT], id2))) {
|
|
1893
|
+
return false;
|
|
1894
|
+
}
|
|
1895
|
+
const type = schema[TYPE];
|
|
1896
|
+
if (!isTypeStringOrBoolean(type) && type != NUMBER) {
|
|
1897
|
+
return false;
|
|
1898
|
+
}
|
|
1899
|
+
if (getCellOrValueType(schema[DEFAULT]) != type) {
|
|
1900
|
+
objDel(schema, DEFAULT);
|
|
1901
|
+
}
|
|
1902
|
+
return true;
|
|
1903
|
+
};
|
|
1835
1904
|
const validateTables = (tables) =>
|
|
1836
1905
|
validate(tables, validateTable, cellInvalid);
|
|
1837
1906
|
const validateTable = (table, tableId) =>
|
|
1838
|
-
(!
|
|
1907
|
+
(!hasTablesSchema ||
|
|
1908
|
+
collHas(tablesSchemaMap, tableId) ||
|
|
1909
|
+
cellInvalid(tableId)) &&
|
|
1839
1910
|
validate(
|
|
1840
1911
|
table,
|
|
1841
1912
|
(row, rowId) => validateRow(tableId, rowId, row),
|
|
@@ -1856,21 +1927,48 @@ const createStore = () => {
|
|
|
1856
1927
|
() => cellInvalid(tableId, rowId),
|
|
1857
1928
|
);
|
|
1858
1929
|
const getValidatedCell = (tableId, rowId, cellId, cell) =>
|
|
1859
|
-
|
|
1930
|
+
hasTablesSchema
|
|
1860
1931
|
? ifNotUndefined(
|
|
1861
|
-
mapGet(mapGet(
|
|
1932
|
+
mapGet(mapGet(tablesSchemaMap, tableId), cellId),
|
|
1862
1933
|
(cellSchema) =>
|
|
1863
|
-
|
|
1934
|
+
getCellOrValueType(cell) != cellSchema[TYPE]
|
|
1864
1935
|
? cellInvalid(tableId, rowId, cellId, cell, cellSchema[DEFAULT])
|
|
1865
1936
|
: cell,
|
|
1866
1937
|
() => cellInvalid(tableId, rowId, cellId, cell),
|
|
1867
1938
|
)
|
|
1868
|
-
: isUndefined(
|
|
1939
|
+
: isUndefined(getCellOrValueType(cell))
|
|
1869
1940
|
? cellInvalid(tableId, rowId, cellId, cell)
|
|
1870
1941
|
: cell;
|
|
1942
|
+
const validateValues = (values, skipDefaults) =>
|
|
1943
|
+
validate(
|
|
1944
|
+
skipDefaults ? values : addDefaultsToValues(values),
|
|
1945
|
+
(value, valueId) =>
|
|
1946
|
+
ifNotUndefined(
|
|
1947
|
+
getValidatedValue(valueId, value),
|
|
1948
|
+
(validValue) => {
|
|
1949
|
+
values[valueId] = validValue;
|
|
1950
|
+
return true;
|
|
1951
|
+
},
|
|
1952
|
+
() => false,
|
|
1953
|
+
),
|
|
1954
|
+
() => valueInvalid(),
|
|
1955
|
+
);
|
|
1956
|
+
const getValidatedValue = (valueId, value) =>
|
|
1957
|
+
hasValuesSchema
|
|
1958
|
+
? ifNotUndefined(
|
|
1959
|
+
mapGet(valuesSchemaMap, valueId),
|
|
1960
|
+
(valueSchema) =>
|
|
1961
|
+
getCellOrValueType(value) != valueSchema[TYPE]
|
|
1962
|
+
? valueInvalid(valueId, value, valueSchema[DEFAULT])
|
|
1963
|
+
: value,
|
|
1964
|
+
() => valueInvalid(valueId, value),
|
|
1965
|
+
)
|
|
1966
|
+
: isUndefined(getCellOrValueType(value))
|
|
1967
|
+
? valueInvalid(valueId, value)
|
|
1968
|
+
: value;
|
|
1871
1969
|
const addDefaultsToRow = (row, tableId, rowId) => {
|
|
1872
1970
|
ifNotUndefined(
|
|
1873
|
-
mapGet(
|
|
1971
|
+
mapGet(tablesSchemaRowCache, tableId),
|
|
1874
1972
|
([rowDefaulted, rowNonDefaulted]) => {
|
|
1875
1973
|
collForEach(rowDefaulted, (cell, cellId) => {
|
|
1876
1974
|
if (!objHas(row, cellId)) {
|
|
@@ -1886,15 +1984,30 @@ const createStore = () => {
|
|
|
1886
1984
|
);
|
|
1887
1985
|
return row;
|
|
1888
1986
|
};
|
|
1889
|
-
const
|
|
1987
|
+
const addDefaultsToValues = (values) => {
|
|
1988
|
+
if (hasValuesSchema) {
|
|
1989
|
+
collForEach(valuesDefaulted, (value, valueId) => {
|
|
1990
|
+
if (!objHas(values, valueId)) {
|
|
1991
|
+
values[valueId] = value;
|
|
1992
|
+
}
|
|
1993
|
+
});
|
|
1994
|
+
collForEach(valuesNonDefaulted, (valueId) => {
|
|
1995
|
+
if (!objHas(values, valueId)) {
|
|
1996
|
+
valueInvalid(valueId);
|
|
1997
|
+
}
|
|
1998
|
+
});
|
|
1999
|
+
}
|
|
2000
|
+
return values;
|
|
2001
|
+
};
|
|
2002
|
+
const setValidTablesSchema = (tablesSchema) =>
|
|
1890
2003
|
transformMap(
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
(
|
|
2004
|
+
tablesSchemaMap,
|
|
2005
|
+
tablesSchema,
|
|
2006
|
+
(_tablesSchema, tableId, tableSchema) => {
|
|
1894
2007
|
const rowDefaulted = mapNew();
|
|
1895
2008
|
const rowNonDefaulted = setNew();
|
|
1896
2009
|
transformMap(
|
|
1897
|
-
mapEnsure(
|
|
2010
|
+
mapEnsure(tablesSchemaMap, tableId, mapNew),
|
|
1898
2011
|
tableSchema,
|
|
1899
2012
|
(tableSchemaMap, cellId, cellSchema) => {
|
|
1900
2013
|
mapSet(tableSchemaMap, cellId, cellSchema);
|
|
@@ -1905,13 +2018,33 @@ const createStore = () => {
|
|
|
1905
2018
|
);
|
|
1906
2019
|
},
|
|
1907
2020
|
);
|
|
1908
|
-
mapSet(
|
|
2021
|
+
mapSet(tablesSchemaRowCache, tableId, [rowDefaulted, rowNonDefaulted]);
|
|
2022
|
+
},
|
|
2023
|
+
(_tablesSchema, tableId) => {
|
|
2024
|
+
mapSet(tablesSchemaMap, tableId);
|
|
2025
|
+
mapSet(tablesSchemaRowCache, tableId);
|
|
2026
|
+
},
|
|
2027
|
+
);
|
|
2028
|
+
const setValidValuesSchema = (valuesSchema) =>
|
|
2029
|
+
transformMap(
|
|
2030
|
+
valuesSchemaMap,
|
|
2031
|
+
valuesSchema,
|
|
2032
|
+
(_valuesSchema, valueId, valueSchema) => {
|
|
2033
|
+
mapSet(valuesSchemaMap, valueId, valueSchema);
|
|
2034
|
+
ifNotUndefined(
|
|
2035
|
+
valueSchema[DEFAULT],
|
|
2036
|
+
(def) => mapSet(valuesDefaulted, valueId, def),
|
|
2037
|
+
() => setAdd(valuesNonDefaulted, valueId),
|
|
2038
|
+
);
|
|
1909
2039
|
},
|
|
1910
|
-
(
|
|
1911
|
-
mapSet(
|
|
1912
|
-
mapSet(
|
|
2040
|
+
(_valuesSchema, valueId) => {
|
|
2041
|
+
mapSet(valuesSchemaMap, valueId);
|
|
2042
|
+
mapSet(valuesDefaulted, valueId);
|
|
2043
|
+
collDel(valuesNonDefaulted, valueId);
|
|
1913
2044
|
},
|
|
1914
2045
|
);
|
|
2046
|
+
const setOrDelTables = (tables) =>
|
|
2047
|
+
objIsEmpty(tables) ? delTables() : setTables(tables);
|
|
1915
2048
|
const setValidTables = (tables) =>
|
|
1916
2049
|
transformMap(
|
|
1917
2050
|
tablesMap,
|
|
@@ -1929,26 +2062,26 @@ const createStore = () => {
|
|
|
1929
2062
|
(tableMap, rowId, row) => setValidRow(tableId, tableMap, rowId, row),
|
|
1930
2063
|
(tableMap, rowId) => delValidRow(tableId, tableMap, rowId),
|
|
1931
2064
|
);
|
|
1932
|
-
const setValidRow = (tableId, tableMap, rowId,
|
|
2065
|
+
const setValidRow = (tableId, tableMap, rowId, row, forceDel) =>
|
|
1933
2066
|
transformMap(
|
|
1934
2067
|
mapEnsure(tableMap, rowId, () => {
|
|
1935
2068
|
rowIdsChanged(tableId, rowId, 1);
|
|
1936
2069
|
return mapNew();
|
|
1937
2070
|
}),
|
|
1938
|
-
|
|
2071
|
+
row,
|
|
1939
2072
|
(rowMap, cellId, cell) =>
|
|
1940
2073
|
setValidCell(tableId, rowId, rowMap, cellId, cell),
|
|
1941
2074
|
(rowMap, cellId) =>
|
|
1942
2075
|
delValidCell(tableId, tableMap, rowId, rowMap, cellId, forceDel),
|
|
1943
2076
|
);
|
|
1944
|
-
const setValidCell = (tableId, rowId, rowMap, cellId,
|
|
2077
|
+
const setValidCell = (tableId, rowId, rowMap, cellId, cell) => {
|
|
1945
2078
|
if (!collHas(rowMap, cellId)) {
|
|
1946
2079
|
cellIdsChanged(tableId, rowId, cellId, 1);
|
|
1947
2080
|
}
|
|
1948
2081
|
const oldCell = mapGet(rowMap, cellId);
|
|
1949
|
-
if (
|
|
1950
|
-
cellChanged(tableId, rowId, cellId, oldCell,
|
|
1951
|
-
mapSet(rowMap, cellId,
|
|
2082
|
+
if (cell !== oldCell) {
|
|
2083
|
+
cellChanged(tableId, rowId, cellId, oldCell, cell);
|
|
2084
|
+
mapSet(rowMap, cellId, cell);
|
|
1952
2085
|
}
|
|
1953
2086
|
};
|
|
1954
2087
|
const setCellIntoDefaultRow = (tableId, tableMap, rowId, cellId, validCell) =>
|
|
@@ -1963,6 +2096,25 @@ const createStore = () => {
|
|
|
1963
2096
|
addDefaultsToRow({[cellId]: validCell}, tableId, rowId),
|
|
1964
2097
|
),
|
|
1965
2098
|
);
|
|
2099
|
+
const setOrDelValues = (values) =>
|
|
2100
|
+
objIsEmpty(values) ? delValues() : setValues(values);
|
|
2101
|
+
const setValidValues = (values) =>
|
|
2102
|
+
transformMap(
|
|
2103
|
+
valuesMap,
|
|
2104
|
+
values,
|
|
2105
|
+
(_valuesMap, valueId, value) => setValidValue(valueId, value),
|
|
2106
|
+
(_valuesMap, valueId) => delValidValue(valueId),
|
|
2107
|
+
);
|
|
2108
|
+
const setValidValue = (valueId, value) => {
|
|
2109
|
+
if (!collHas(valuesMap, valueId)) {
|
|
2110
|
+
valueIdsChanged(valueId, 1);
|
|
2111
|
+
}
|
|
2112
|
+
const oldValue = mapGet(valuesMap, valueId);
|
|
2113
|
+
if (value !== oldValue) {
|
|
2114
|
+
valueChanged(valueId, oldValue, value);
|
|
2115
|
+
mapSet(valuesMap, valueId, value);
|
|
2116
|
+
}
|
|
2117
|
+
};
|
|
1966
2118
|
const getNewRowId = (tableId) => {
|
|
1967
2119
|
const [getId] = mapEnsure(tablePoolFunctions, tableId, getPoolFunctions);
|
|
1968
2120
|
const rowId = getId();
|
|
@@ -1984,7 +2136,10 @@ const createStore = () => {
|
|
|
1984
2136
|
setValidRow(tableId, tableMap, rowId, {}, true);
|
|
1985
2137
|
};
|
|
1986
2138
|
const delValidCell = (tableId, table, rowId, row, cellId, forceDel) => {
|
|
1987
|
-
const defaultCell = mapGet(
|
|
2139
|
+
const defaultCell = mapGet(
|
|
2140
|
+
mapGet(tablesSchemaRowCache, tableId)?.[0],
|
|
2141
|
+
cellId,
|
|
2142
|
+
);
|
|
1988
2143
|
if (!isUndefined(defaultCell) && !forceDel) {
|
|
1989
2144
|
return setValidCell(tableId, rowId, row, cellId, defaultCell);
|
|
1990
2145
|
}
|
|
@@ -2003,6 +2158,15 @@ const createStore = () => {
|
|
|
2003
2158
|
}
|
|
2004
2159
|
}
|
|
2005
2160
|
};
|
|
2161
|
+
const delValidValue = (valueId) => {
|
|
2162
|
+
const defaultValue = mapGet(valuesDefaulted, valueId);
|
|
2163
|
+
if (!isUndefined(defaultValue)) {
|
|
2164
|
+
return setValidValue(valueId, defaultValue);
|
|
2165
|
+
}
|
|
2166
|
+
valueChanged(valueId, mapGet(valuesMap, valueId));
|
|
2167
|
+
valueIdsChanged(valueId, -1);
|
|
2168
|
+
mapSet(valuesMap, valueId);
|
|
2169
|
+
};
|
|
2006
2170
|
const tableIdsChanged = (tableId, added) =>
|
|
2007
2171
|
idsChanged(changedTableIds, tableId, added);
|
|
2008
2172
|
const rowIdsChanged = (tableId, rowId, added) =>
|
|
@@ -2019,6 +2183,10 @@ const createStore = () => {
|
|
|
2019
2183
|
cellId,
|
|
2020
2184
|
() => [oldCell, 0],
|
|
2021
2185
|
)[1] = newCell);
|
|
2186
|
+
const valueIdsChanged = (valueId, added) =>
|
|
2187
|
+
idsChanged(changedValueIds, valueId, added);
|
|
2188
|
+
const valueChanged = (valueId, oldValue, newValue) =>
|
|
2189
|
+
(mapEnsure(changedValues, valueId, () => [oldValue, 0])[1] = newValue);
|
|
2022
2190
|
const cellInvalid = (tableId, rowId, cellId, invalidCell, defaultedCell) => {
|
|
2023
2191
|
arrayPush(
|
|
2024
2192
|
mapEnsure(
|
|
@@ -2030,12 +2198,25 @@ const createStore = () => {
|
|
|
2030
2198
|
);
|
|
2031
2199
|
return defaultedCell;
|
|
2032
2200
|
};
|
|
2201
|
+
const valueInvalid = (valueId, invalidValue, defaultedValue) => {
|
|
2202
|
+
arrayPush(
|
|
2203
|
+
mapEnsure(invalidValues, valueId, () => []),
|
|
2204
|
+
invalidValue,
|
|
2205
|
+
);
|
|
2206
|
+
return defaultedValue;
|
|
2207
|
+
};
|
|
2033
2208
|
const getCellChange = (tableId, rowId, cellId) =>
|
|
2034
2209
|
ifNotUndefined(
|
|
2035
2210
|
mapGet(mapGet(mapGet(changedCells, tableId), rowId), cellId),
|
|
2036
2211
|
([oldCell, newCell]) => [true, oldCell, newCell],
|
|
2037
2212
|
() => [false, ...pairNew(getCell(tableId, rowId, cellId))],
|
|
2038
2213
|
);
|
|
2214
|
+
const getValueChange = (valueId) =>
|
|
2215
|
+
ifNotUndefined(
|
|
2216
|
+
mapGet(changedValues, valueId),
|
|
2217
|
+
([oldValue, newValue]) => [true, oldValue, newValue],
|
|
2218
|
+
() => [false, ...pairNew(getValue(valueId))],
|
|
2219
|
+
);
|
|
2039
2220
|
const callInvalidCellListeners = (mutator) =>
|
|
2040
2221
|
!collIsEmpty(invalidCells) && !collIsEmpty(invalidCellListeners[mutator])
|
|
2041
2222
|
? collForEach(
|
|
@@ -2052,13 +2233,25 @@ const createStore = () => {
|
|
|
2052
2233
|
),
|
|
2053
2234
|
)
|
|
2054
2235
|
: 0;
|
|
2236
|
+
const callInvalidValueListeners = (mutator) =>
|
|
2237
|
+
!collIsEmpty(invalidValues) && !collIsEmpty(invalidValueListeners[mutator])
|
|
2238
|
+
? collForEach(
|
|
2239
|
+
mutator ? mapClone(invalidValues) : invalidValues,
|
|
2240
|
+
(invalidValue, valueId) =>
|
|
2241
|
+
callListeners(
|
|
2242
|
+
invalidValueListeners[mutator],
|
|
2243
|
+
[valueId],
|
|
2244
|
+
invalidValue,
|
|
2245
|
+
),
|
|
2246
|
+
)
|
|
2247
|
+
: 0;
|
|
2055
2248
|
const callIdsListenersIfChanged = (listeners, changedIds, ids) => {
|
|
2056
2249
|
if (!collIsEmpty(changedIds)) {
|
|
2057
2250
|
callListeners(listeners, ids);
|
|
2058
2251
|
return 1;
|
|
2059
2252
|
}
|
|
2060
2253
|
};
|
|
2061
|
-
const
|
|
2254
|
+
const callTabularListenersForChanges = (mutator) => {
|
|
2062
2255
|
const emptySortedRowIdListeners = collIsEmpty(
|
|
2063
2256
|
sortedRowIdsListeners[mutator],
|
|
2064
2257
|
);
|
|
@@ -2160,6 +2353,38 @@ const createStore = () => {
|
|
|
2160
2353
|
}
|
|
2161
2354
|
}
|
|
2162
2355
|
};
|
|
2356
|
+
const callKeyedValuesListenersForChanges = (mutator) => {
|
|
2357
|
+
const emptyIdListeners = collIsEmpty(valueIdsListeners[mutator]);
|
|
2358
|
+
const emptyOtherListeners =
|
|
2359
|
+
collIsEmpty(valueListeners[mutator]) &&
|
|
2360
|
+
collIsEmpty(valuesListeners[mutator]);
|
|
2361
|
+
if (!emptyIdListeners || !emptyOtherListeners) {
|
|
2362
|
+
const changes = mutator
|
|
2363
|
+
? [mapClone(changedValueIds), mapClone(changedValues)]
|
|
2364
|
+
: [changedValueIds, changedValues];
|
|
2365
|
+
if (!emptyIdListeners) {
|
|
2366
|
+
callIdsListenersIfChanged(valueIdsListeners[mutator], changes[0]);
|
|
2367
|
+
}
|
|
2368
|
+
if (!emptyOtherListeners) {
|
|
2369
|
+
let valuesChanged;
|
|
2370
|
+
collForEach(changes[1], ([oldValue, newValue], valueId) => {
|
|
2371
|
+
if (newValue !== oldValue) {
|
|
2372
|
+
callListeners(
|
|
2373
|
+
valueListeners[mutator],
|
|
2374
|
+
[valueId],
|
|
2375
|
+
newValue,
|
|
2376
|
+
oldValue,
|
|
2377
|
+
getValueChange,
|
|
2378
|
+
);
|
|
2379
|
+
valuesChanged = 1;
|
|
2380
|
+
}
|
|
2381
|
+
});
|
|
2382
|
+
if (valuesChanged) {
|
|
2383
|
+
callListeners(valuesListeners[mutator], void 0, getValueChange);
|
|
2384
|
+
}
|
|
2385
|
+
}
|
|
2386
|
+
}
|
|
2387
|
+
};
|
|
2163
2388
|
const fluentTransaction = (actions, ...args) => {
|
|
2164
2389
|
transaction(() => actions(...arrayMap(args, id)));
|
|
2165
2390
|
return store;
|
|
@@ -2192,14 +2417,23 @@ const createStore = () => {
|
|
|
2192
2417
|
mapKeys(mapGet(mapGet(tablesMap, id(tableId)), id(rowId)));
|
|
2193
2418
|
const getCell = (tableId, rowId, cellId) =>
|
|
2194
2419
|
mapGet(mapGet(mapGet(tablesMap, id(tableId)), id(rowId)), id(cellId));
|
|
2420
|
+
const getValues = () => mapToObj(valuesMap);
|
|
2421
|
+
const getValueIds = () => mapKeys(valuesMap);
|
|
2422
|
+
const getValue = (valueId) => mapGet(valuesMap, id(valueId));
|
|
2195
2423
|
const hasTables = () => !collIsEmpty(tablesMap);
|
|
2196
2424
|
const hasTable = (tableId) => collHas(tablesMap, id(tableId));
|
|
2197
2425
|
const hasRow = (tableId, rowId) =>
|
|
2198
2426
|
collHas(mapGet(tablesMap, id(tableId)), id(rowId));
|
|
2199
2427
|
const hasCell = (tableId, rowId, cellId) =>
|
|
2200
2428
|
collHas(mapGet(mapGet(tablesMap, id(tableId)), id(rowId)), id(cellId));
|
|
2201
|
-
const
|
|
2202
|
-
const
|
|
2429
|
+
const hasValues = () => !collIsEmpty(valuesMap);
|
|
2430
|
+
const hasValue = (valueId) => collHas(valuesMap, id(valueId));
|
|
2431
|
+
const getTablesJson = () => jsonString(tablesMap);
|
|
2432
|
+
const getValuesJson = () => jsonString(valuesMap);
|
|
2433
|
+
const getJson = () => jsonString([tablesMap, valuesMap]);
|
|
2434
|
+
const getTablesSchemaJson = () => jsonString(tablesSchemaMap);
|
|
2435
|
+
const getValuesSchemaJson = () => jsonString(valuesSchemaMap);
|
|
2436
|
+
const getSchemaJson = () => jsonString([tablesSchemaMap, valuesSchemaMap]);
|
|
2203
2437
|
const setTables = (tables) =>
|
|
2204
2438
|
fluentTransaction(() =>
|
|
2205
2439
|
validateTables(tables) ? setValidTables(tables) : 0,
|
|
@@ -2213,13 +2447,8 @@ const createStore = () => {
|
|
|
2213
2447
|
const setRow = (tableId, rowId, row) =>
|
|
2214
2448
|
fluentTransaction(
|
|
2215
2449
|
(tableId2, rowId2) =>
|
|
2216
|
-
validateRow(
|
|
2217
|
-
? setValidRow(
|
|
2218
|
-
id(tableId2),
|
|
2219
|
-
getOrCreateTable(id(tableId2)),
|
|
2220
|
-
id(rowId2),
|
|
2221
|
-
row,
|
|
2222
|
-
)
|
|
2450
|
+
validateRow(tableId2, rowId2, row)
|
|
2451
|
+
? setValidRow(tableId2, getOrCreateTable(tableId2), rowId2, row)
|
|
2223
2452
|
: 0,
|
|
2224
2453
|
tableId,
|
|
2225
2454
|
rowId,
|
|
@@ -2274,16 +2503,56 @@ const createStore = () => {
|
|
|
2274
2503
|
rowId,
|
|
2275
2504
|
cellId,
|
|
2276
2505
|
);
|
|
2277
|
-
const
|
|
2506
|
+
const setValues = (values) =>
|
|
2507
|
+
fluentTransaction(() =>
|
|
2508
|
+
validateValues(values) ? setValidValues(values) : 0,
|
|
2509
|
+
);
|
|
2510
|
+
const setPartialValues = (partialValues) =>
|
|
2511
|
+
fluentTransaction(() =>
|
|
2512
|
+
validateValues(partialValues, 1)
|
|
2513
|
+
? objMap(partialValues, (value, valueId) =>
|
|
2514
|
+
setValidValue(valueId, value),
|
|
2515
|
+
)
|
|
2516
|
+
: 0,
|
|
2517
|
+
);
|
|
2518
|
+
const setValue = (valueId, value) =>
|
|
2519
|
+
fluentTransaction(
|
|
2520
|
+
(valueId2) =>
|
|
2521
|
+
ifNotUndefined(
|
|
2522
|
+
getValidatedValue(
|
|
2523
|
+
valueId2,
|
|
2524
|
+
isFunction(value) ? value(getValue(valueId2)) : value,
|
|
2525
|
+
),
|
|
2526
|
+
(validValue) => setValidValue(valueId2, validValue),
|
|
2527
|
+
),
|
|
2528
|
+
valueId,
|
|
2529
|
+
);
|
|
2530
|
+
const setTablesJson = (tablesJson) => {
|
|
2531
|
+
try {
|
|
2532
|
+
setOrDelTables(jsonParse(tablesJson));
|
|
2533
|
+
} catch {}
|
|
2534
|
+
return store;
|
|
2535
|
+
};
|
|
2536
|
+
const setValuesJson = (valuesJson) => {
|
|
2278
2537
|
try {
|
|
2279
|
-
|
|
2538
|
+
setOrDelValues(jsonParse(valuesJson));
|
|
2280
2539
|
} catch {}
|
|
2281
2540
|
return store;
|
|
2282
2541
|
};
|
|
2283
|
-
const
|
|
2542
|
+
const setJson = (tablesAndValuesJson) => {
|
|
2543
|
+
try {
|
|
2544
|
+
const [tables, values] = jsonParse(tablesAndValuesJson);
|
|
2545
|
+
setOrDelTables(tables);
|
|
2546
|
+
setOrDelValues(values);
|
|
2547
|
+
} catch {
|
|
2548
|
+
setTablesJson(tablesAndValuesJson);
|
|
2549
|
+
}
|
|
2550
|
+
return store;
|
|
2551
|
+
};
|
|
2552
|
+
const setTablesSchema = (tablesSchema) =>
|
|
2284
2553
|
fluentTransaction(() => {
|
|
2285
|
-
if ((
|
|
2286
|
-
|
|
2554
|
+
if ((hasTablesSchema = validateTablesSchema(tablesSchema))) {
|
|
2555
|
+
setValidTablesSchema(tablesSchema);
|
|
2287
2556
|
if (!collIsEmpty(tablesMap)) {
|
|
2288
2557
|
const tables = getTables();
|
|
2289
2558
|
delTables();
|
|
@@ -2291,6 +2560,22 @@ const createStore = () => {
|
|
|
2291
2560
|
}
|
|
2292
2561
|
}
|
|
2293
2562
|
});
|
|
2563
|
+
const setValuesSchema = (valuesSchema) =>
|
|
2564
|
+
fluentTransaction(() => {
|
|
2565
|
+
if ((hasValuesSchema = validateValuesSchema(valuesSchema))) {
|
|
2566
|
+
const values = getValues();
|
|
2567
|
+
delValuesSchema();
|
|
2568
|
+
delValues();
|
|
2569
|
+
hasValuesSchema = true;
|
|
2570
|
+
setValidValuesSchema(valuesSchema);
|
|
2571
|
+
setValues(values);
|
|
2572
|
+
}
|
|
2573
|
+
});
|
|
2574
|
+
const setSchema = (tablesSchema, valuesSchema) =>
|
|
2575
|
+
fluentTransaction(() => {
|
|
2576
|
+
setTablesSchema(tablesSchema);
|
|
2577
|
+
setValuesSchema(valuesSchema);
|
|
2578
|
+
});
|
|
2294
2579
|
const delTables = () => fluentTransaction(() => setValidTables({}));
|
|
2295
2580
|
const delTable = (tableId) =>
|
|
2296
2581
|
fluentTransaction(
|
|
@@ -2330,10 +2615,22 @@ const createStore = () => {
|
|
|
2330
2615
|
rowId,
|
|
2331
2616
|
cellId,
|
|
2332
2617
|
);
|
|
2333
|
-
const
|
|
2618
|
+
const delValues = () => fluentTransaction(() => setValidValues({}));
|
|
2619
|
+
const delValue = (valueId) =>
|
|
2620
|
+
fluentTransaction(
|
|
2621
|
+
(valueId2) =>
|
|
2622
|
+
collHas(valuesMap, valueId2) ? delValidValue(valueId2) : 0,
|
|
2623
|
+
valueId,
|
|
2624
|
+
);
|
|
2625
|
+
const delTablesSchema = () =>
|
|
2626
|
+
fluentTransaction(() => {
|
|
2627
|
+
setValidTablesSchema({});
|
|
2628
|
+
hasTablesSchema = false;
|
|
2629
|
+
});
|
|
2630
|
+
const delValuesSchema = () =>
|
|
2334
2631
|
fluentTransaction(() => {
|
|
2335
|
-
|
|
2336
|
-
|
|
2632
|
+
setValidValuesSchema({});
|
|
2633
|
+
hasValuesSchema = false;
|
|
2337
2634
|
});
|
|
2338
2635
|
const transaction = (actions, doRollback) => {
|
|
2339
2636
|
if (transactions == -1) {
|
|
@@ -2353,10 +2650,15 @@ const createStore = () => {
|
|
|
2353
2650
|
transactions--;
|
|
2354
2651
|
if (transactions == 0) {
|
|
2355
2652
|
cellsTouched = !collIsEmpty(changedCells);
|
|
2653
|
+
valuesTouched = !collIsEmpty(changedValues);
|
|
2356
2654
|
transactions = 1;
|
|
2357
2655
|
callInvalidCellListeners(1);
|
|
2358
2656
|
if (cellsTouched) {
|
|
2359
|
-
|
|
2657
|
+
callTabularListenersForChanges(1);
|
|
2658
|
+
}
|
|
2659
|
+
callInvalidValueListeners(1);
|
|
2660
|
+
if (valuesTouched) {
|
|
2661
|
+
callKeyedValuesListenersForChanges(1);
|
|
2360
2662
|
}
|
|
2361
2663
|
transactions = -1;
|
|
2362
2664
|
if (
|
|
@@ -2377,6 +2679,12 @@ const createStore = () => {
|
|
|
2377
2679
|
objIsEmpty,
|
|
2378
2680
|
),
|
|
2379
2681
|
mapToObj(invalidCells, (map) => mapToObj(map, mapToObj)),
|
|
2682
|
+
mapToObj(
|
|
2683
|
+
changedValues,
|
|
2684
|
+
(values) => [...values],
|
|
2685
|
+
([oldValue, newValue]) => oldValue === newValue,
|
|
2686
|
+
),
|
|
2687
|
+
mapToObj(invalidValues),
|
|
2380
2688
|
)
|
|
2381
2689
|
) {
|
|
2382
2690
|
transactions = 1;
|
|
@@ -2387,23 +2695,43 @@ const createStore = () => {
|
|
|
2387
2695
|
),
|
|
2388
2696
|
),
|
|
2389
2697
|
);
|
|
2698
|
+
collForEach(changedValues, ([oldValue], valueId) =>
|
|
2699
|
+
setOrDelValue(store, valueId, oldValue),
|
|
2700
|
+
);
|
|
2390
2701
|
transactions = -1;
|
|
2391
|
-
cellsTouched = false;
|
|
2702
|
+
cellsTouched = valuesTouched = false;
|
|
2392
2703
|
}
|
|
2393
|
-
callListeners(
|
|
2704
|
+
callListeners(
|
|
2705
|
+
finishTransactionListeners[0],
|
|
2706
|
+
void 0,
|
|
2707
|
+
cellsTouched,
|
|
2708
|
+
valuesTouched,
|
|
2709
|
+
);
|
|
2394
2710
|
callInvalidCellListeners(0);
|
|
2395
2711
|
if (cellsTouched) {
|
|
2396
|
-
|
|
2712
|
+
callTabularListenersForChanges(0);
|
|
2713
|
+
}
|
|
2714
|
+
callInvalidValueListeners(0);
|
|
2715
|
+
if (valuesTouched) {
|
|
2716
|
+
callKeyedValuesListenersForChanges(0);
|
|
2397
2717
|
}
|
|
2398
|
-
callListeners(
|
|
2718
|
+
callListeners(
|
|
2719
|
+
finishTransactionListeners[1],
|
|
2720
|
+
void 0,
|
|
2721
|
+
cellsTouched,
|
|
2722
|
+
valuesTouched,
|
|
2723
|
+
);
|
|
2399
2724
|
transactions = 0;
|
|
2400
2725
|
arrayForEach(
|
|
2401
2726
|
[
|
|
2402
|
-
changedCells,
|
|
2403
|
-
invalidCells,
|
|
2404
2727
|
changedTableIds,
|
|
2405
2728
|
changedRowIds,
|
|
2406
2729
|
changedCellIds,
|
|
2730
|
+
changedCells,
|
|
2731
|
+
invalidCells,
|
|
2732
|
+
changedValueIds,
|
|
2733
|
+
changedValues,
|
|
2734
|
+
invalidValues,
|
|
2407
2735
|
],
|
|
2408
2736
|
collClear,
|
|
2409
2737
|
);
|
|
@@ -2427,6 +2755,7 @@ const createStore = () => {
|
|
|
2427
2755
|
);
|
|
2428
2756
|
const forEachCell = (tableId, rowId, cellCallback) =>
|
|
2429
2757
|
mapForEach(mapGet(mapGet(tablesMap, id(tableId)), id(rowId)), cellCallback);
|
|
2758
|
+
const forEachValue = (valueCallback) => mapForEach(valuesMap, valueCallback);
|
|
2430
2759
|
const addSortedRowIdsListener = (
|
|
2431
2760
|
tableId,
|
|
2432
2761
|
cellId,
|
|
@@ -2467,6 +2796,7 @@ const createStore = () => {
|
|
|
2467
2796
|
},
|
|
2468
2797
|
sortedRowIdsListeners[mutator ? 1 : 0],
|
|
2469
2798
|
[tableId, cellId],
|
|
2799
|
+
[getTableIds],
|
|
2470
2800
|
);
|
|
2471
2801
|
};
|
|
2472
2802
|
const addWillFinishTransactionListener = (listener) =>
|
|
@@ -2474,9 +2804,7 @@ const createStore = () => {
|
|
|
2474
2804
|
const addDidFinishTransactionListener = (listener) =>
|
|
2475
2805
|
addListener(listener, finishTransactionListeners[1]);
|
|
2476
2806
|
const callListener = (listenerId) => {
|
|
2477
|
-
callListenerImpl(listenerId
|
|
2478
|
-
isUndefined(ids[2]) ? [] : pairNew(getCell(...ids)),
|
|
2479
|
-
);
|
|
2807
|
+
callListenerImpl(listenerId);
|
|
2480
2808
|
return store;
|
|
2481
2809
|
};
|
|
2482
2810
|
const delListener = (listenerId) => {
|
|
@@ -2493,6 +2821,10 @@ const createStore = () => {
|
|
|
2493
2821
|
cellIds: pairCollSize2(cellIdsListeners, collSize3),
|
|
2494
2822
|
cell: pairCollSize2(cellListeners, collSize4),
|
|
2495
2823
|
invalidCell: pairCollSize2(invalidCellListeners, collSize4),
|
|
2824
|
+
values: pairCollSize2(valuesListeners),
|
|
2825
|
+
valueIds: pairCollSize2(valueIdsListeners),
|
|
2826
|
+
value: pairCollSize2(valueListeners),
|
|
2827
|
+
invalidValue: pairCollSize2(invalidValueListeners),
|
|
2496
2828
|
transaction: pairCollSize2(finishTransactionListeners),
|
|
2497
2829
|
});
|
|
2498
2830
|
const store = {
|
|
@@ -2504,11 +2836,20 @@ const createStore = () => {
|
|
|
2504
2836
|
getRow,
|
|
2505
2837
|
getCellIds,
|
|
2506
2838
|
getCell,
|
|
2839
|
+
getValues,
|
|
2840
|
+
getValueIds,
|
|
2841
|
+
getValue,
|
|
2507
2842
|
hasTables,
|
|
2508
2843
|
hasTable,
|
|
2509
2844
|
hasRow,
|
|
2510
2845
|
hasCell,
|
|
2846
|
+
hasValues,
|
|
2847
|
+
hasValue,
|
|
2848
|
+
getTablesJson,
|
|
2849
|
+
getValuesJson,
|
|
2511
2850
|
getJson,
|
|
2851
|
+
getTablesSchemaJson,
|
|
2852
|
+
getValuesSchemaJson,
|
|
2512
2853
|
getSchemaJson,
|
|
2513
2854
|
setTables,
|
|
2514
2855
|
setTable,
|
|
@@ -2516,19 +2857,30 @@ const createStore = () => {
|
|
|
2516
2857
|
addRow,
|
|
2517
2858
|
setPartialRow,
|
|
2518
2859
|
setCell,
|
|
2860
|
+
setValues,
|
|
2861
|
+
setPartialValues,
|
|
2862
|
+
setValue,
|
|
2863
|
+
setTablesJson,
|
|
2864
|
+
setValuesJson,
|
|
2519
2865
|
setJson,
|
|
2866
|
+
setTablesSchema,
|
|
2867
|
+
setValuesSchema,
|
|
2520
2868
|
setSchema,
|
|
2521
2869
|
delTables,
|
|
2522
2870
|
delTable,
|
|
2523
2871
|
delRow,
|
|
2524
2872
|
delCell,
|
|
2525
|
-
|
|
2873
|
+
delValues,
|
|
2874
|
+
delValue,
|
|
2875
|
+
delTablesSchema,
|
|
2876
|
+
delValuesSchema,
|
|
2526
2877
|
transaction,
|
|
2527
2878
|
startTransaction,
|
|
2528
2879
|
finishTransaction,
|
|
2529
2880
|
forEachTable,
|
|
2530
2881
|
forEachRow,
|
|
2531
2882
|
forEachCell,
|
|
2883
|
+
forEachValue,
|
|
2532
2884
|
addSortedRowIdsListener,
|
|
2533
2885
|
addWillFinishTransactionListener,
|
|
2534
2886
|
addDidFinishTransactionListener,
|
|
@@ -2541,19 +2893,35 @@ const createStore = () => {
|
|
|
2541
2893
|
{
|
|
2542
2894
|
[TABLES]: [0, tablesListeners],
|
|
2543
2895
|
[TABLE_IDS]: [0, tableIdsListeners],
|
|
2544
|
-
[TABLE]: [1, tableListeners],
|
|
2545
|
-
[ROW_IDS]: [1, rowIdsListeners],
|
|
2546
|
-
[ROW]: [2, rowListeners],
|
|
2547
|
-
[CELL_IDS]: [2, cellIdsListeners],
|
|
2548
|
-
[CELL]: [
|
|
2896
|
+
[TABLE]: [1, tableListeners, [getTableIds]],
|
|
2897
|
+
[ROW_IDS]: [1, rowIdsListeners, [getTableIds]],
|
|
2898
|
+
[ROW]: [2, rowListeners, [getTableIds, getRowIds]],
|
|
2899
|
+
[CELL_IDS]: [2, cellIdsListeners, [getTableIds, getRowIds]],
|
|
2900
|
+
[CELL]: [
|
|
2901
|
+
3,
|
|
2902
|
+
cellListeners,
|
|
2903
|
+
[getTableIds, getRowIds, getCellIds],
|
|
2904
|
+
(ids) => pairNew(getCell(...ids)),
|
|
2905
|
+
],
|
|
2549
2906
|
InvalidCell: [3, invalidCellListeners],
|
|
2907
|
+
[VALUES]: [0, valuesListeners],
|
|
2908
|
+
[VALUE_IDS]: [0, valueIdsListeners],
|
|
2909
|
+
[VALUE]: [
|
|
2910
|
+
1,
|
|
2911
|
+
valueListeners,
|
|
2912
|
+
[getValueIds],
|
|
2913
|
+
(ids) => pairNew(getValue(ids[0])),
|
|
2914
|
+
],
|
|
2915
|
+
InvalidValue: [1, invalidValueListeners],
|
|
2550
2916
|
},
|
|
2551
|
-
([argumentCount, idSetNode], listenable) => {
|
|
2917
|
+
([argumentCount, idSetNode, pathGetters, extraArgsGetter], listenable) => {
|
|
2552
2918
|
store[ADD + listenable + LISTENER] = (...args) =>
|
|
2553
2919
|
addListener(
|
|
2554
2920
|
args[argumentCount],
|
|
2555
2921
|
idSetNode[args[argumentCount + 1] ? 1 : 0],
|
|
2556
2922
|
argumentCount > 0 ? arraySlice(args, 0, argumentCount) : void 0,
|
|
2923
|
+
pathGetters,
|
|
2924
|
+
extraArgsGetter,
|
|
2557
2925
|
);
|
|
2558
2926
|
},
|
|
2559
2927
|
);
|