tinybase 3.0.0-beta.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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 +2053 -381
- package/lib/debug/store.js +444 -106
- package/lib/debug/tinybase.js +512 -138
- package/lib/debug/tools.d.ts +109 -38
- package/lib/debug/tools.js +759 -453
- package/lib/debug/ui-react.d.ts +1218 -138
- 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 +2053 -381
- 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 +109 -38
- package/lib/es6/tools.js +1 -1
- package/lib/es6/tools.js.gz +0 -0
- package/lib/es6/ui-react.d.ts +1218 -138
- 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 +2053 -381
- 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 +109 -38
- package/lib/tools.js +1 -1
- package/lib/tools.js.gz +0 -0
- package/lib/ui-react.d.ts +1218 -138
- 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 +2053 -381
- 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 +109 -38
- package/lib/umd/tools.js +1 -1
- package/lib/umd/tools.js.gz +0 -0
- package/lib/umd/ui-react.d.ts +1218 -138
- 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 +2053 -381
- 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 +109 -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 +1218 -138
- package/lib/umd-es6/ui-react.js +1 -1
- package/lib/umd-es6/ui-react.js.gz +0 -0
- package/package.json +20 -20
- package/readme.md +27 -16
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]);
|
|
1909
2022
|
},
|
|
1910
|
-
(
|
|
1911
|
-
mapSet(
|
|
1912
|
-
mapSet(
|
|
2023
|
+
(_tablesSchema, tableId) => {
|
|
2024
|
+
mapSet(tablesSchemaMap, tableId);
|
|
2025
|
+
mapSet(tablesSchemaRowCache, tableId);
|
|
1913
2026
|
},
|
|
1914
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
|
+
);
|
|
2039
|
+
},
|
|
2040
|
+
(_valuesSchema, valueId) => {
|
|
2041
|
+
mapSet(valuesSchemaMap, valueId);
|
|
2042
|
+
mapSet(valuesDefaulted, valueId);
|
|
2043
|
+
collDel(valuesNonDefaulted, valueId);
|
|
2044
|
+
},
|
|
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,27 @@ const createStore = () => {
|
|
|
2330
2615
|
rowId,
|
|
2331
2616
|
cellId,
|
|
2332
2617
|
);
|
|
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 = () =>
|
|
2631
|
+
fluentTransaction(() => {
|
|
2632
|
+
setValidValuesSchema({});
|
|
2633
|
+
hasValuesSchema = false;
|
|
2634
|
+
});
|
|
2333
2635
|
const delSchema = () =>
|
|
2334
2636
|
fluentTransaction(() => {
|
|
2335
|
-
|
|
2336
|
-
|
|
2637
|
+
delTablesSchema();
|
|
2638
|
+
delValuesSchema();
|
|
2337
2639
|
});
|
|
2338
2640
|
const transaction = (actions, doRollback) => {
|
|
2339
2641
|
if (transactions == -1) {
|
|
@@ -2353,10 +2655,15 @@ const createStore = () => {
|
|
|
2353
2655
|
transactions--;
|
|
2354
2656
|
if (transactions == 0) {
|
|
2355
2657
|
cellsTouched = !collIsEmpty(changedCells);
|
|
2658
|
+
valuesTouched = !collIsEmpty(changedValues);
|
|
2356
2659
|
transactions = 1;
|
|
2357
2660
|
callInvalidCellListeners(1);
|
|
2358
2661
|
if (cellsTouched) {
|
|
2359
|
-
|
|
2662
|
+
callTabularListenersForChanges(1);
|
|
2663
|
+
}
|
|
2664
|
+
callInvalidValueListeners(1);
|
|
2665
|
+
if (valuesTouched) {
|
|
2666
|
+
callKeyedValuesListenersForChanges(1);
|
|
2360
2667
|
}
|
|
2361
2668
|
transactions = -1;
|
|
2362
2669
|
if (
|
|
@@ -2377,6 +2684,12 @@ const createStore = () => {
|
|
|
2377
2684
|
objIsEmpty,
|
|
2378
2685
|
),
|
|
2379
2686
|
mapToObj(invalidCells, (map) => mapToObj(map, mapToObj)),
|
|
2687
|
+
mapToObj(
|
|
2688
|
+
changedValues,
|
|
2689
|
+
(values) => [...values],
|
|
2690
|
+
([oldValue, newValue]) => oldValue === newValue,
|
|
2691
|
+
),
|
|
2692
|
+
mapToObj(invalidValues),
|
|
2380
2693
|
)
|
|
2381
2694
|
) {
|
|
2382
2695
|
transactions = 1;
|
|
@@ -2387,23 +2700,43 @@ const createStore = () => {
|
|
|
2387
2700
|
),
|
|
2388
2701
|
),
|
|
2389
2702
|
);
|
|
2703
|
+
collForEach(changedValues, ([oldValue], valueId) =>
|
|
2704
|
+
setOrDelValue(store, valueId, oldValue),
|
|
2705
|
+
);
|
|
2390
2706
|
transactions = -1;
|
|
2391
|
-
cellsTouched = false;
|
|
2707
|
+
cellsTouched = valuesTouched = false;
|
|
2392
2708
|
}
|
|
2393
|
-
callListeners(
|
|
2709
|
+
callListeners(
|
|
2710
|
+
finishTransactionListeners[0],
|
|
2711
|
+
void 0,
|
|
2712
|
+
cellsTouched,
|
|
2713
|
+
valuesTouched,
|
|
2714
|
+
);
|
|
2394
2715
|
callInvalidCellListeners(0);
|
|
2395
2716
|
if (cellsTouched) {
|
|
2396
|
-
|
|
2717
|
+
callTabularListenersForChanges(0);
|
|
2718
|
+
}
|
|
2719
|
+
callInvalidValueListeners(0);
|
|
2720
|
+
if (valuesTouched) {
|
|
2721
|
+
callKeyedValuesListenersForChanges(0);
|
|
2397
2722
|
}
|
|
2398
|
-
callListeners(
|
|
2723
|
+
callListeners(
|
|
2724
|
+
finishTransactionListeners[1],
|
|
2725
|
+
void 0,
|
|
2726
|
+
cellsTouched,
|
|
2727
|
+
valuesTouched,
|
|
2728
|
+
);
|
|
2399
2729
|
transactions = 0;
|
|
2400
2730
|
arrayForEach(
|
|
2401
2731
|
[
|
|
2402
|
-
changedCells,
|
|
2403
|
-
invalidCells,
|
|
2404
2732
|
changedTableIds,
|
|
2405
2733
|
changedRowIds,
|
|
2406
2734
|
changedCellIds,
|
|
2735
|
+
changedCells,
|
|
2736
|
+
invalidCells,
|
|
2737
|
+
changedValueIds,
|
|
2738
|
+
changedValues,
|
|
2739
|
+
invalidValues,
|
|
2407
2740
|
],
|
|
2408
2741
|
collClear,
|
|
2409
2742
|
);
|
|
@@ -2427,6 +2760,7 @@ const createStore = () => {
|
|
|
2427
2760
|
);
|
|
2428
2761
|
const forEachCell = (tableId, rowId, cellCallback) =>
|
|
2429
2762
|
mapForEach(mapGet(mapGet(tablesMap, id(tableId)), id(rowId)), cellCallback);
|
|
2763
|
+
const forEachValue = (valueCallback) => mapForEach(valuesMap, valueCallback);
|
|
2430
2764
|
const addSortedRowIdsListener = (
|
|
2431
2765
|
tableId,
|
|
2432
2766
|
cellId,
|
|
@@ -2467,6 +2801,7 @@ const createStore = () => {
|
|
|
2467
2801
|
},
|
|
2468
2802
|
sortedRowIdsListeners[mutator ? 1 : 0],
|
|
2469
2803
|
[tableId, cellId],
|
|
2804
|
+
[getTableIds],
|
|
2470
2805
|
);
|
|
2471
2806
|
};
|
|
2472
2807
|
const addWillFinishTransactionListener = (listener) =>
|
|
@@ -2474,9 +2809,7 @@ const createStore = () => {
|
|
|
2474
2809
|
const addDidFinishTransactionListener = (listener) =>
|
|
2475
2810
|
addListener(listener, finishTransactionListeners[1]);
|
|
2476
2811
|
const callListener = (listenerId) => {
|
|
2477
|
-
callListenerImpl(listenerId
|
|
2478
|
-
isUndefined(ids[2]) ? [] : pairNew(getCell(...ids)),
|
|
2479
|
-
);
|
|
2812
|
+
callListenerImpl(listenerId);
|
|
2480
2813
|
return store;
|
|
2481
2814
|
};
|
|
2482
2815
|
const delListener = (listenerId) => {
|
|
@@ -2493,6 +2826,10 @@ const createStore = () => {
|
|
|
2493
2826
|
cellIds: pairCollSize2(cellIdsListeners, collSize3),
|
|
2494
2827
|
cell: pairCollSize2(cellListeners, collSize4),
|
|
2495
2828
|
invalidCell: pairCollSize2(invalidCellListeners, collSize4),
|
|
2829
|
+
values: pairCollSize2(valuesListeners),
|
|
2830
|
+
valueIds: pairCollSize2(valueIdsListeners),
|
|
2831
|
+
value: pairCollSize2(valueListeners),
|
|
2832
|
+
invalidValue: pairCollSize2(invalidValueListeners),
|
|
2496
2833
|
transaction: pairCollSize2(finishTransactionListeners),
|
|
2497
2834
|
});
|
|
2498
2835
|
const store = {
|
|
@@ -2504,11 +2841,20 @@ const createStore = () => {
|
|
|
2504
2841
|
getRow,
|
|
2505
2842
|
getCellIds,
|
|
2506
2843
|
getCell,
|
|
2844
|
+
getValues,
|
|
2845
|
+
getValueIds,
|
|
2846
|
+
getValue,
|
|
2507
2847
|
hasTables,
|
|
2508
2848
|
hasTable,
|
|
2509
2849
|
hasRow,
|
|
2510
2850
|
hasCell,
|
|
2851
|
+
hasValues,
|
|
2852
|
+
hasValue,
|
|
2853
|
+
getTablesJson,
|
|
2854
|
+
getValuesJson,
|
|
2511
2855
|
getJson,
|
|
2856
|
+
getTablesSchemaJson,
|
|
2857
|
+
getValuesSchemaJson,
|
|
2512
2858
|
getSchemaJson,
|
|
2513
2859
|
setTables,
|
|
2514
2860
|
setTable,
|
|
@@ -2516,12 +2862,23 @@ const createStore = () => {
|
|
|
2516
2862
|
addRow,
|
|
2517
2863
|
setPartialRow,
|
|
2518
2864
|
setCell,
|
|
2865
|
+
setValues,
|
|
2866
|
+
setPartialValues,
|
|
2867
|
+
setValue,
|
|
2868
|
+
setTablesJson,
|
|
2869
|
+
setValuesJson,
|
|
2519
2870
|
setJson,
|
|
2871
|
+
setTablesSchema,
|
|
2872
|
+
setValuesSchema,
|
|
2520
2873
|
setSchema,
|
|
2521
2874
|
delTables,
|
|
2522
2875
|
delTable,
|
|
2523
2876
|
delRow,
|
|
2524
2877
|
delCell,
|
|
2878
|
+
delValues,
|
|
2879
|
+
delValue,
|
|
2880
|
+
delTablesSchema,
|
|
2881
|
+
delValuesSchema,
|
|
2525
2882
|
delSchema,
|
|
2526
2883
|
transaction,
|
|
2527
2884
|
startTransaction,
|
|
@@ -2529,6 +2886,7 @@ const createStore = () => {
|
|
|
2529
2886
|
forEachTable,
|
|
2530
2887
|
forEachRow,
|
|
2531
2888
|
forEachCell,
|
|
2889
|
+
forEachValue,
|
|
2532
2890
|
addSortedRowIdsListener,
|
|
2533
2891
|
addWillFinishTransactionListener,
|
|
2534
2892
|
addDidFinishTransactionListener,
|
|
@@ -2541,19 +2899,35 @@ const createStore = () => {
|
|
|
2541
2899
|
{
|
|
2542
2900
|
[TABLES]: [0, tablesListeners],
|
|
2543
2901
|
[TABLE_IDS]: [0, tableIdsListeners],
|
|
2544
|
-
[TABLE]: [1, tableListeners],
|
|
2545
|
-
[ROW_IDS]: [1, rowIdsListeners],
|
|
2546
|
-
[ROW]: [2, rowListeners],
|
|
2547
|
-
[CELL_IDS]: [2, cellIdsListeners],
|
|
2548
|
-
[CELL]: [
|
|
2902
|
+
[TABLE]: [1, tableListeners, [getTableIds]],
|
|
2903
|
+
[ROW_IDS]: [1, rowIdsListeners, [getTableIds]],
|
|
2904
|
+
[ROW]: [2, rowListeners, [getTableIds, getRowIds]],
|
|
2905
|
+
[CELL_IDS]: [2, cellIdsListeners, [getTableIds, getRowIds]],
|
|
2906
|
+
[CELL]: [
|
|
2907
|
+
3,
|
|
2908
|
+
cellListeners,
|
|
2909
|
+
[getTableIds, getRowIds, getCellIds],
|
|
2910
|
+
(ids) => pairNew(getCell(...ids)),
|
|
2911
|
+
],
|
|
2549
2912
|
InvalidCell: [3, invalidCellListeners],
|
|
2913
|
+
[VALUES]: [0, valuesListeners],
|
|
2914
|
+
[VALUE_IDS]: [0, valueIdsListeners],
|
|
2915
|
+
[VALUE]: [
|
|
2916
|
+
1,
|
|
2917
|
+
valueListeners,
|
|
2918
|
+
[getValueIds],
|
|
2919
|
+
(ids) => pairNew(getValue(ids[0])),
|
|
2920
|
+
],
|
|
2921
|
+
InvalidValue: [1, invalidValueListeners],
|
|
2550
2922
|
},
|
|
2551
|
-
([argumentCount, idSetNode], listenable) => {
|
|
2923
|
+
([argumentCount, idSetNode, pathGetters, extraArgsGetter], listenable) => {
|
|
2552
2924
|
store[ADD + listenable + LISTENER] = (...args) =>
|
|
2553
2925
|
addListener(
|
|
2554
2926
|
args[argumentCount],
|
|
2555
2927
|
idSetNode[args[argumentCount + 1] ? 1 : 0],
|
|
2556
2928
|
argumentCount > 0 ? arraySlice(args, 0, argumentCount) : void 0,
|
|
2929
|
+
pathGetters,
|
|
2930
|
+
extraArgsGetter,
|
|
2557
2931
|
);
|
|
2558
2932
|
},
|
|
2559
2933
|
);
|