tinybase 1.0.3 → 1.1.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/checkpoints.d.ts +66 -0
- package/lib/checkpoints.js +1 -1
- package/lib/checkpoints.js.gz +0 -0
- package/lib/debug/checkpoints.d.ts +66 -0
- package/lib/debug/checkpoints.js +16 -10
- package/lib/debug/indexes.d.ts +167 -6
- package/lib/debug/indexes.js +35 -2
- package/lib/debug/metrics.d.ts +72 -0
- package/lib/debug/metrics.js +12 -2
- package/lib/debug/relationships.d.ts +86 -1
- package/lib/debug/relationships.js +18 -2
- package/lib/debug/store.d.ts +187 -5
- package/lib/debug/store.js +217 -164
- package/lib/debug/tinybase.js +272 -172
- package/lib/indexes.d.ts +167 -6
- package/lib/indexes.js +1 -1
- package/lib/indexes.js.gz +0 -0
- package/lib/metrics.d.ts +72 -0
- package/lib/metrics.js +1 -1
- package/lib/metrics.js.gz +0 -0
- package/lib/relationships.d.ts +86 -1
- package/lib/relationships.js +1 -1
- package/lib/relationships.js.gz +0 -0
- package/lib/store.d.ts +187 -5
- 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/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/relationships.js +1 -1
- package/lib/umd/relationships.js.gz +0 -0
- package/lib/umd/store.js +1 -1
- package/lib/umd/store.js.gz +0 -0
- package/lib/umd/tinybase.js +1 -1
- package/lib/umd/tinybase.js.gz +0 -0
- package/package.json +14 -14
- package/readme.md +2 -2
package/lib/debug/tinybase.js
CHANGED
|
@@ -29,6 +29,8 @@ const arrayReduce = (array, cb, initial) => array.reduce(cb, initial);
|
|
|
29
29
|
const arrayFilter = (array, cb) => array.filter(cb);
|
|
30
30
|
const arrayFromSecond = (ids) => ids.slice(1);
|
|
31
31
|
const arrayClear = (array, to) => array.splice(0, to);
|
|
32
|
+
const arrayPush = (array, value) => array.push(value);
|
|
33
|
+
const arrayPop = (array) => array.pop();
|
|
32
34
|
|
|
33
35
|
const jsonString = (obj) =>
|
|
34
36
|
JSON.stringify(obj, (_key, value) =>
|
|
@@ -110,6 +112,8 @@ const getDefinableFunctions = (store, getDefaultThing, validateRowValue) => {
|
|
|
110
112
|
const storeListenerIds = mapNew();
|
|
111
113
|
const getStore = () => store;
|
|
112
114
|
const getThingIds = () => mapKeys(tableIds);
|
|
115
|
+
const forEachThing = (cb) => mapForEach(things, cb);
|
|
116
|
+
const hasThing = (id) => collHas(things, id);
|
|
113
117
|
const getTableId = (id) => mapGet(tableIds, id);
|
|
114
118
|
const getThing = (id) => mapGet(things, id);
|
|
115
119
|
const setThing = (id, thing) => mapSet(things, id, thing);
|
|
@@ -199,6 +203,8 @@ const getDefinableFunctions = (store, getDefaultThing, validateRowValue) => {
|
|
|
199
203
|
return [
|
|
200
204
|
getStore,
|
|
201
205
|
getThingIds,
|
|
206
|
+
forEachThing,
|
|
207
|
+
hasThing,
|
|
202
208
|
getTableId,
|
|
203
209
|
getThing,
|
|
204
210
|
setThing,
|
|
@@ -250,7 +256,7 @@ const getListenerFunctions = (getThing) => {
|
|
|
250
256
|
const allListeners = mapNew();
|
|
251
257
|
const addListener = (listener, deepSet, idOrNulls = []) => {
|
|
252
258
|
thing ??= getThing();
|
|
253
|
-
const id = listenerPool
|
|
259
|
+
const id = arrayPop(listenerPool) ?? '' + nextId++;
|
|
254
260
|
mapSet(allListeners, id, [listener, deepSet, idOrNulls]);
|
|
255
261
|
addDeepSet(deepSet, id, idOrNulls);
|
|
256
262
|
return id;
|
|
@@ -271,7 +277,7 @@ const getListenerFunctions = (getThing) => {
|
|
|
271
277
|
forDeepSet(collDel)(deepSet, id, ...idOrNulls);
|
|
272
278
|
mapSet(allListeners, id);
|
|
273
279
|
if (arrayLength(listenerPool) < 1e3) {
|
|
274
|
-
listenerPool
|
|
280
|
+
arrayPush(listenerPool, id);
|
|
275
281
|
}
|
|
276
282
|
return idOrNulls;
|
|
277
283
|
},
|
|
@@ -357,7 +363,7 @@ const createCheckpoints = getCreateFunction((store) => {
|
|
|
357
363
|
(_store, tableId, rowId, cellId, newCell, oldCell) => {
|
|
358
364
|
if (listening) {
|
|
359
365
|
ifNotUndefined(currentId, () => {
|
|
360
|
-
backwardIds
|
|
366
|
+
arrayPush(backwardIds, currentId);
|
|
361
367
|
trimBackwardsIds();
|
|
362
368
|
clearCheckpointIds(forwardIds);
|
|
363
369
|
currentId = void 0;
|
|
@@ -376,7 +382,7 @@ const createCheckpoints = getCreateFunction((store) => {
|
|
|
376
382
|
if (collIsEmpty(mapSet(row, cellId))) {
|
|
377
383
|
if (collIsEmpty(mapSet(table, rowId))) {
|
|
378
384
|
if (collIsEmpty(mapSet(delta, tableId))) {
|
|
379
|
-
currentId = backwardIds
|
|
385
|
+
currentId = arrayPop(backwardIds);
|
|
380
386
|
checkpointsChanged = 1;
|
|
381
387
|
}
|
|
382
388
|
}
|
|
@@ -400,13 +406,13 @@ const createCheckpoints = getCreateFunction((store) => {
|
|
|
400
406
|
if (!arrayIsEmpty(backwardIds)) {
|
|
401
407
|
forwardIds.unshift(addCheckpointImpl());
|
|
402
408
|
updateStore(0, currentId);
|
|
403
|
-
currentId = backwardIds
|
|
409
|
+
currentId = arrayPop(backwardIds);
|
|
404
410
|
checkpointsChanged = 1;
|
|
405
411
|
}
|
|
406
412
|
};
|
|
407
413
|
const goForwardImpl = () => {
|
|
408
414
|
if (!arrayIsEmpty(forwardIds)) {
|
|
409
|
-
backwardIds
|
|
415
|
+
arrayPush(backwardIds, currentId);
|
|
410
416
|
currentId = forwardIds.shift();
|
|
411
417
|
updateStore(1, currentId);
|
|
412
418
|
checkpointsChanged = 1;
|
|
@@ -429,10 +435,7 @@ const createCheckpoints = getCreateFunction((store) => {
|
|
|
429
435
|
return id;
|
|
430
436
|
};
|
|
431
437
|
const setCheckpoint = (checkpointId, label) => {
|
|
432
|
-
if (
|
|
433
|
-
collHas(deltas, checkpointId) &&
|
|
434
|
-
mapGet(labels, checkpointId) !== label
|
|
435
|
-
) {
|
|
438
|
+
if (hasCheckpoint(checkpointId) && mapGet(labels, checkpointId) !== label) {
|
|
436
439
|
mapSet(labels, checkpointId, label);
|
|
437
440
|
callListeners(checkpointListeners, [checkpointId]);
|
|
438
441
|
}
|
|
@@ -440,6 +443,9 @@ const createCheckpoints = getCreateFunction((store) => {
|
|
|
440
443
|
};
|
|
441
444
|
const getStore = () => store;
|
|
442
445
|
const getCheckpointIds = () => [[...backwardIds], currentId, [...forwardIds]];
|
|
446
|
+
const forEachCheckpoint = (checkpointCallback) =>
|
|
447
|
+
mapForEach(labels, checkpointCallback);
|
|
448
|
+
const hasCheckpoint = (checkpointId) => collHas(deltas, checkpointId);
|
|
443
449
|
const getCheckpoint = (checkpointId) => mapGet(labels, checkpointId);
|
|
444
450
|
const goBackward = () => {
|
|
445
451
|
goBackwardImpl();
|
|
@@ -495,6 +501,8 @@ const createCheckpoints = getCreateFunction((store) => {
|
|
|
495
501
|
setCheckpoint,
|
|
496
502
|
getStore,
|
|
497
503
|
getCheckpointIds,
|
|
504
|
+
forEachCheckpoint,
|
|
505
|
+
hasCheckpoint,
|
|
498
506
|
getCheckpoint,
|
|
499
507
|
goBackward,
|
|
500
508
|
goForward,
|
|
@@ -517,6 +525,8 @@ const createIndexes = getCreateFunction((store) => {
|
|
|
517
525
|
const [
|
|
518
526
|
getStore,
|
|
519
527
|
getIndexIds,
|
|
528
|
+
forEachIndexImpl,
|
|
529
|
+
hasIndex,
|
|
520
530
|
getTableId,
|
|
521
531
|
getIndex,
|
|
522
532
|
setIndex,
|
|
@@ -529,6 +539,7 @@ const createIndexes = getCreateFunction((store) => {
|
|
|
529
539
|
const [addListener, callListeners, delListenerImpl] = getListenerFunctions(
|
|
530
540
|
() => indexes,
|
|
531
541
|
);
|
|
542
|
+
const hasSlice = (indexId, sliceId) => collHas(getIndex(indexId), sliceId);
|
|
532
543
|
const setIndexDefinition = (
|
|
533
544
|
indexId,
|
|
534
545
|
tableId,
|
|
@@ -624,6 +635,26 @@ const createIndexes = getCreateFunction((store) => {
|
|
|
624
635
|
);
|
|
625
636
|
return indexes;
|
|
626
637
|
};
|
|
638
|
+
const forEachIndex = (indexCallback) =>
|
|
639
|
+
forEachIndexImpl((indexId, slices) =>
|
|
640
|
+
indexCallback(indexId, (sliceCallback) =>
|
|
641
|
+
forEachSliceImpl(indexId, sliceCallback, slices),
|
|
642
|
+
),
|
|
643
|
+
);
|
|
644
|
+
const forEachSlice = (indexId, sliceCallback) =>
|
|
645
|
+
forEachSliceImpl(indexId, sliceCallback, getIndex(indexId));
|
|
646
|
+
const forEachSliceImpl = (indexId, sliceCallback, slices) => {
|
|
647
|
+
const tableId = getTableId(indexId);
|
|
648
|
+
collForEach(slices, (rowIds, sliceId) =>
|
|
649
|
+
sliceCallback(sliceId, (rowCallback) =>
|
|
650
|
+
collForEach(rowIds, (rowId) =>
|
|
651
|
+
rowCallback(rowId, (cellCallback) =>
|
|
652
|
+
store.forEachCell(tableId, rowId, cellCallback),
|
|
653
|
+
),
|
|
654
|
+
),
|
|
655
|
+
),
|
|
656
|
+
);
|
|
657
|
+
};
|
|
627
658
|
const delIndexDefinition = (indexId) => {
|
|
628
659
|
delDefinition(indexId);
|
|
629
660
|
return indexes;
|
|
@@ -648,6 +679,10 @@ const createIndexes = getCreateFunction((store) => {
|
|
|
648
679
|
delIndexDefinition,
|
|
649
680
|
getStore,
|
|
650
681
|
getIndexIds,
|
|
682
|
+
forEachIndex,
|
|
683
|
+
forEachSlice,
|
|
684
|
+
hasIndex,
|
|
685
|
+
hasSlice,
|
|
651
686
|
getTableId,
|
|
652
687
|
getSliceIds,
|
|
653
688
|
getSliceRowIds,
|
|
@@ -705,6 +740,8 @@ const createMetrics = getCreateFunction((store) => {
|
|
|
705
740
|
const [
|
|
706
741
|
getStore,
|
|
707
742
|
getMetricIds,
|
|
743
|
+
forEachMetric,
|
|
744
|
+
hasMetric,
|
|
708
745
|
getTableId,
|
|
709
746
|
getMetric,
|
|
710
747
|
setMetric,
|
|
@@ -789,6 +826,8 @@ const createMetrics = getCreateFunction((store) => {
|
|
|
789
826
|
delMetricDefinition,
|
|
790
827
|
getStore,
|
|
791
828
|
getMetricIds,
|
|
829
|
+
forEachMetric,
|
|
830
|
+
hasMetric,
|
|
792
831
|
getTableId,
|
|
793
832
|
getMetric,
|
|
794
833
|
addMetricListener,
|
|
@@ -980,6 +1019,8 @@ const createRelationships = getCreateFunction((store) => {
|
|
|
980
1019
|
const [
|
|
981
1020
|
getStore,
|
|
982
1021
|
getRelationshipIds,
|
|
1022
|
+
forEachRelationshipImpl,
|
|
1023
|
+
hasRelationship,
|
|
983
1024
|
getLocalTableId,
|
|
984
1025
|
getRelationship,
|
|
985
1026
|
_setRelationship,
|
|
@@ -1093,6 +1134,12 @@ const createRelationships = getCreateFunction((store) => {
|
|
|
1093
1134
|
);
|
|
1094
1135
|
return relationships;
|
|
1095
1136
|
};
|
|
1137
|
+
const forEachRelationship = (relationshipCallback) =>
|
|
1138
|
+
forEachRelationshipImpl((relationshipId) =>
|
|
1139
|
+
relationshipCallback(relationshipId, (rowCallback) =>
|
|
1140
|
+
store.forEachRow(getLocalTableId(relationshipId), rowCallback),
|
|
1141
|
+
),
|
|
1142
|
+
);
|
|
1096
1143
|
const delRelationshipDefinition = (relationshipId) => {
|
|
1097
1144
|
mapSet(remoteTableIds, relationshipId);
|
|
1098
1145
|
delDefinition(relationshipId);
|
|
@@ -1133,6 +1180,8 @@ const createRelationships = getCreateFunction((store) => {
|
|
|
1133
1180
|
delRelationshipDefinition,
|
|
1134
1181
|
getStore,
|
|
1135
1182
|
getRelationshipIds,
|
|
1183
|
+
forEachRelationship,
|
|
1184
|
+
hasRelationship,
|
|
1136
1185
|
getLocalTableId,
|
|
1137
1186
|
getRemoteTableId,
|
|
1138
1187
|
getRemoteRowId,
|
|
@@ -1165,8 +1214,9 @@ const getCellType = (cell) => {
|
|
|
1165
1214
|
? type
|
|
1166
1215
|
: void 0;
|
|
1167
1216
|
};
|
|
1168
|
-
const validate = (obj, validateChild) => {
|
|
1169
|
-
if (isUndefined(obj) || !isObject(obj) || objFrozen(obj)) {
|
|
1217
|
+
const validate = (obj, validateChild, onInvalidObj) => {
|
|
1218
|
+
if (isUndefined(obj) || !isObject(obj) || objIsEmpty(obj) || objFrozen(obj)) {
|
|
1219
|
+
onInvalidObj?.();
|
|
1170
1220
|
return false;
|
|
1171
1221
|
}
|
|
1172
1222
|
objForEach(obj, (child, id) => {
|
|
@@ -1186,6 +1236,7 @@ const createStore = () => {
|
|
|
1186
1236
|
const changedRowIds = mapNew();
|
|
1187
1237
|
const changedCellIds = mapNew();
|
|
1188
1238
|
const changedCells = mapNew();
|
|
1239
|
+
const invalidCells = mapNew();
|
|
1189
1240
|
const schemaMap = mapNew();
|
|
1190
1241
|
const schemaDefaultRows = mapNew();
|
|
1191
1242
|
const tablesMap = mapNew();
|
|
@@ -1196,6 +1247,7 @@ const createStore = () => {
|
|
|
1196
1247
|
const rowListeners = mapNewPair();
|
|
1197
1248
|
const cellIdsListeners = mapNewPair();
|
|
1198
1249
|
const cellListeners = mapNewPair();
|
|
1250
|
+
const invalidCellListeners = mapNewPair();
|
|
1199
1251
|
const [addListener, callListeners, delListenerImpl, callListenerImpl] =
|
|
1200
1252
|
getListenerFunctions(() => store);
|
|
1201
1253
|
const validateSchema = (schema) =>
|
|
@@ -1216,32 +1268,41 @@ const createStore = () => {
|
|
|
1216
1268
|
return true;
|
|
1217
1269
|
}),
|
|
1218
1270
|
);
|
|
1219
|
-
const validateTables = (tables) =>
|
|
1271
|
+
const validateTables = (tables) =>
|
|
1272
|
+
validate(tables, validateTable, cellInvalid);
|
|
1220
1273
|
const validateTable = (table, tableId) =>
|
|
1221
|
-
(!hasSchema || collHas(schemaMap, tableId)) &&
|
|
1222
|
-
validate(
|
|
1223
|
-
|
|
1274
|
+
(!hasSchema || collHas(schemaMap, tableId) || cellInvalid(tableId)) &&
|
|
1275
|
+
validate(
|
|
1276
|
+
table,
|
|
1277
|
+
(row, rowId) => validateRow(tableId, rowId, row),
|
|
1278
|
+
() => cellInvalid(tableId),
|
|
1279
|
+
);
|
|
1280
|
+
const validateRow = (tableId, rowId, row, skipDefaults) =>
|
|
1224
1281
|
validate(
|
|
1225
1282
|
skipDefaults ? row : addDefaultsToRow(row, tableId),
|
|
1226
1283
|
(cell, cellId) =>
|
|
1227
1284
|
ifNotUndefined(
|
|
1228
|
-
getValidatedCell(tableId, cellId, cell),
|
|
1285
|
+
getValidatedCell(tableId, rowId, cellId, cell),
|
|
1229
1286
|
(validCell) => {
|
|
1230
1287
|
row[cellId] = validCell;
|
|
1231
1288
|
return true;
|
|
1232
1289
|
},
|
|
1233
1290
|
() => false,
|
|
1234
1291
|
),
|
|
1292
|
+
() => cellInvalid(tableId, rowId),
|
|
1235
1293
|
);
|
|
1236
|
-
const getValidatedCell = (tableId, cellId, cell) =>
|
|
1294
|
+
const getValidatedCell = (tableId, rowId, cellId, cell) =>
|
|
1237
1295
|
hasSchema
|
|
1238
1296
|
? ifNotUndefined(
|
|
1239
1297
|
mapGet(mapGet(schemaMap, tableId), cellId),
|
|
1240
1298
|
(cellSchema) =>
|
|
1241
|
-
getCellType(cell) != cellSchema[TYPE]
|
|
1299
|
+
getCellType(cell) != cellSchema[TYPE]
|
|
1300
|
+
? cellInvalid(tableId, rowId, cellId, cell, cellSchema[DEFAULT])
|
|
1301
|
+
: cell,
|
|
1302
|
+
() => cellInvalid(tableId, rowId, cellId, cell),
|
|
1242
1303
|
)
|
|
1243
1304
|
: isUndefined(getCellType(cell))
|
|
1244
|
-
?
|
|
1305
|
+
? cellInvalid(tableId, rowId, cellId, cell)
|
|
1245
1306
|
: cell;
|
|
1246
1307
|
const addDefaultsToRow = (row, tableId) => {
|
|
1247
1308
|
ifNotUndefined(mapGet(schemaDefaultRows, tableId), (defaultRow) =>
|
|
@@ -1314,10 +1375,6 @@ const createStore = () => {
|
|
|
1314
1375
|
mapSet(rowMap, cellId, newCell);
|
|
1315
1376
|
}
|
|
1316
1377
|
};
|
|
1317
|
-
const setValidRowTransaction = (tableId, rowId, row) =>
|
|
1318
|
-
transaction(() =>
|
|
1319
|
-
setValidRow(tableId, getOrCreateTable(tableId), rowId, row),
|
|
1320
|
-
);
|
|
1321
1378
|
const setCellIntoDefaultRow = (tableId, tableMap, rowId, cellId, validCell) =>
|
|
1322
1379
|
ifNotUndefined(
|
|
1323
1380
|
mapGet(tableMap, rowId),
|
|
@@ -1377,6 +1434,17 @@ const createStore = () => {
|
|
|
1377
1434
|
cellId,
|
|
1378
1435
|
oldCell,
|
|
1379
1436
|
);
|
|
1437
|
+
const cellInvalid = (tableId, rowId, cellId, invalidCell, defaultedCell) => {
|
|
1438
|
+
arrayPush(
|
|
1439
|
+
mapEnsure(
|
|
1440
|
+
mapEnsure(mapEnsure(invalidCells, tableId, mapNew()), rowId, mapNew()),
|
|
1441
|
+
cellId,
|
|
1442
|
+
[],
|
|
1443
|
+
),
|
|
1444
|
+
invalidCell,
|
|
1445
|
+
);
|
|
1446
|
+
return defaultedCell;
|
|
1447
|
+
};
|
|
1380
1448
|
const getCellChange = (tableId, rowId, cellId) => {
|
|
1381
1449
|
const changedRow = mapGet(mapGet(changedCells, tableId), rowId);
|
|
1382
1450
|
const newCell = getCell(tableId, rowId, cellId);
|
|
@@ -1384,80 +1452,106 @@ const createStore = () => {
|
|
|
1384
1452
|
? [true, mapGet(changedRow, cellId), newCell]
|
|
1385
1453
|
: [false, newCell, newCell];
|
|
1386
1454
|
};
|
|
1455
|
+
const callInvalidCellListeners = (mutator) =>
|
|
1456
|
+
!collIsEmpty(invalidCells) && !collIsEmpty(invalidCellListeners[mutator])
|
|
1457
|
+
? collForEach(
|
|
1458
|
+
mutator
|
|
1459
|
+
? mapClone(invalidCells, (table) => mapClone(table, mapClone))
|
|
1460
|
+
: invalidCells,
|
|
1461
|
+
(rows, tableId) =>
|
|
1462
|
+
collForEach(rows, (cells, rowId) =>
|
|
1463
|
+
collForEach(cells, (invalidCell, cellId) =>
|
|
1464
|
+
callListeners(
|
|
1465
|
+
invalidCellListeners[mutator],
|
|
1466
|
+
[tableId, rowId, cellId],
|
|
1467
|
+
invalidCell,
|
|
1468
|
+
),
|
|
1469
|
+
),
|
|
1470
|
+
),
|
|
1471
|
+
)
|
|
1472
|
+
: 0;
|
|
1387
1473
|
const callListenersForChanges = (mutator) => {
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
collIsEmpty(
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1474
|
+
let emptyIdListeners, emptyOtherListeners;
|
|
1475
|
+
if (
|
|
1476
|
+
!collIsEmpty(changedCells) &&
|
|
1477
|
+
!(
|
|
1478
|
+
(emptyIdListeners =
|
|
1479
|
+
collIsEmpty(cellIdsListeners[mutator]) &&
|
|
1480
|
+
collIsEmpty(rowIdsListeners[mutator]) &&
|
|
1481
|
+
collIsEmpty(tableIdsListeners[mutator])) &&
|
|
1482
|
+
(emptyOtherListeners =
|
|
1483
|
+
collIsEmpty(cellListeners[mutator]) &&
|
|
1484
|
+
collIsEmpty(rowListeners[mutator]) &&
|
|
1485
|
+
collIsEmpty(tableListeners[mutator]) &&
|
|
1486
|
+
collIsEmpty(tablesListeners[mutator]))
|
|
1487
|
+
)
|
|
1488
|
+
) {
|
|
1489
|
+
const changes = mutator
|
|
1490
|
+
? [
|
|
1491
|
+
mapClone(changedTableIds),
|
|
1492
|
+
mapClone(changedRowIds, mapClone),
|
|
1493
|
+
mapClone(changedCellIds, (table) => mapClone(table, mapClone)),
|
|
1494
|
+
mapClone(changedCells, (table) => mapClone(table, mapClone)),
|
|
1495
|
+
]
|
|
1496
|
+
: [changedTableIds, changedRowIds, changedCellIds, changedCells];
|
|
1497
|
+
if (!emptyIdListeners) {
|
|
1498
|
+
collForEach(changes[2], (rowCellIds, tableId) =>
|
|
1499
|
+
collForEach(rowCellIds, (changedIds, rowId) => {
|
|
1500
|
+
if (!collIsEmpty(changedIds)) {
|
|
1501
|
+
callListeners(cellIdsListeners[mutator], [tableId, rowId]);
|
|
1502
|
+
}
|
|
1503
|
+
}),
|
|
1504
|
+
);
|
|
1505
|
+
collForEach(changes[1], (changedIds, tableId) => {
|
|
1411
1506
|
if (!collIsEmpty(changedIds)) {
|
|
1412
|
-
callListeners(
|
|
1507
|
+
callListeners(rowIdsListeners[mutator], [tableId]);
|
|
1413
1508
|
}
|
|
1414
|
-
})
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
if (!collIsEmpty(changedIds)) {
|
|
1418
|
-
callListeners(rowIdsListeners[mutator], [tableId]);
|
|
1509
|
+
});
|
|
1510
|
+
if (!collIsEmpty(changes[0])) {
|
|
1511
|
+
callListeners(tableIdsListeners[mutator]);
|
|
1419
1512
|
}
|
|
1420
|
-
});
|
|
1421
|
-
if (!collIsEmpty(changes[0])) {
|
|
1422
|
-
callListeners(tableIdsListeners[mutator]);
|
|
1423
1513
|
}
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1514
|
+
if (!emptyOtherListeners) {
|
|
1515
|
+
let tablesChanged;
|
|
1516
|
+
collForEach(changes[3], (rows, tableId) => {
|
|
1517
|
+
let tableChanged;
|
|
1518
|
+
collForEach(rows, (cells, rowId) => {
|
|
1519
|
+
let rowChanged;
|
|
1520
|
+
collForEach(cells, (oldCell, cellId) => {
|
|
1521
|
+
const newCell = getCell(tableId, rowId, cellId);
|
|
1522
|
+
if (newCell !== oldCell) {
|
|
1523
|
+
callListeners(
|
|
1524
|
+
cellListeners[mutator],
|
|
1525
|
+
[tableId, rowId, cellId],
|
|
1526
|
+
newCell,
|
|
1527
|
+
oldCell,
|
|
1528
|
+
getCellChange,
|
|
1529
|
+
);
|
|
1530
|
+
tablesChanged = tableChanged = rowChanged = 1;
|
|
1531
|
+
}
|
|
1532
|
+
});
|
|
1533
|
+
if (rowChanged) {
|
|
1434
1534
|
callListeners(
|
|
1435
|
-
|
|
1436
|
-
[tableId, rowId
|
|
1437
|
-
newCell,
|
|
1438
|
-
oldCell,
|
|
1535
|
+
rowListeners[mutator],
|
|
1536
|
+
[tableId, rowId],
|
|
1439
1537
|
getCellChange,
|
|
1440
1538
|
);
|
|
1441
|
-
tablesChanged = tableChanged = rowChanged = 1;
|
|
1442
1539
|
}
|
|
1443
1540
|
});
|
|
1444
|
-
if (
|
|
1445
|
-
callListeners(
|
|
1446
|
-
rowListeners[mutator],
|
|
1447
|
-
[tableId, rowId],
|
|
1448
|
-
getCellChange,
|
|
1449
|
-
);
|
|
1541
|
+
if (tableChanged) {
|
|
1542
|
+
callListeners(tableListeners[mutator], [tableId], getCellChange);
|
|
1450
1543
|
}
|
|
1451
1544
|
});
|
|
1452
|
-
if (
|
|
1453
|
-
callListeners(
|
|
1545
|
+
if (tablesChanged) {
|
|
1546
|
+
callListeners(tablesListeners[mutator], [], getCellChange);
|
|
1454
1547
|
}
|
|
1455
|
-
});
|
|
1456
|
-
if (tablesChanged) {
|
|
1457
|
-
callListeners(tablesListeners[mutator], [], getCellChange);
|
|
1458
1548
|
}
|
|
1459
1549
|
}
|
|
1460
1550
|
};
|
|
1551
|
+
const fluentTransaction = (actions) => {
|
|
1552
|
+
transaction(actions);
|
|
1553
|
+
return store;
|
|
1554
|
+
};
|
|
1461
1555
|
const getTables = () =>
|
|
1462
1556
|
mapToObj(tablesMap, (tableMap) => mapToObj(tableMap, mapToObj));
|
|
1463
1557
|
const getTableIds = () => mapKeys(tablesMap);
|
|
@@ -1469,58 +1563,59 @@ const createStore = () => {
|
|
|
1469
1563
|
mapKeys(mapGet(mapGet(tablesMap, tableId), rowId));
|
|
1470
1564
|
const getCell = (tableId, rowId, cellId) =>
|
|
1471
1565
|
mapGet(mapGet(mapGet(tablesMap, tableId), rowId), cellId);
|
|
1566
|
+
const hasTables = () => !collIsEmpty(tablesMap);
|
|
1472
1567
|
const hasTable = (tableId) => collHas(tablesMap, tableId);
|
|
1473
1568
|
const hasRow = (tableId, rowId) => collHas(mapGet(tablesMap, tableId), rowId);
|
|
1474
1569
|
const hasCell = (tableId, rowId, cellId) =>
|
|
1475
1570
|
collHas(mapGet(mapGet(tablesMap, tableId), rowId), cellId);
|
|
1476
1571
|
const getJson = () => jsonString(tablesMap);
|
|
1477
1572
|
const getSchemaJson = () => jsonString(schemaMap);
|
|
1478
|
-
const setTables = (tables) =>
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1573
|
+
const setTables = (tables) =>
|
|
1574
|
+
fluentTransaction(() =>
|
|
1575
|
+
validateTables(tables) ? setValidTables(tables) : 0,
|
|
1576
|
+
);
|
|
1577
|
+
const setTable = (tableId, table) =>
|
|
1578
|
+
fluentTransaction(() =>
|
|
1579
|
+
validateTable(table, tableId) ? setValidTable(tableId, table) : 0,
|
|
1580
|
+
);
|
|
1581
|
+
const setRow = (tableId, rowId, row) =>
|
|
1582
|
+
fluentTransaction(() =>
|
|
1583
|
+
validateRow(tableId, rowId, row)
|
|
1584
|
+
? setValidRow(tableId, getOrCreateTable(tableId), rowId, row)
|
|
1585
|
+
: 0,
|
|
1586
|
+
);
|
|
1587
|
+
const addRow = (tableId, row) =>
|
|
1588
|
+
transaction(() => {
|
|
1589
|
+
let rowId = void 0;
|
|
1590
|
+
if (validateRow(tableId, rowId, row)) {
|
|
1591
|
+
setValidRow(
|
|
1592
|
+
tableId,
|
|
1593
|
+
getOrCreateTable(tableId),
|
|
1594
|
+
(rowId = getNewRowId(mapGet(tablesMap, tableId))),
|
|
1595
|
+
row,
|
|
1596
|
+
);
|
|
1597
|
+
}
|
|
1598
|
+
return rowId;
|
|
1599
|
+
});
|
|
1600
|
+
const setPartialRow = (tableId, rowId, partialRow) =>
|
|
1601
|
+
fluentTransaction(() => {
|
|
1602
|
+
if (validateRow(tableId, rowId, partialRow, 1)) {
|
|
1507
1603
|
const table = getOrCreateTable(tableId);
|
|
1508
1604
|
objForEach(partialRow, (cell, cellId) =>
|
|
1509
1605
|
setCellIntoDefaultRow(tableId, table, rowId, cellId, cell),
|
|
1510
1606
|
);
|
|
1511
|
-
}
|
|
1512
|
-
}
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
transaction(() =>
|
|
1607
|
+
}
|
|
1608
|
+
});
|
|
1609
|
+
const setCell = (tableId, rowId, cellId, cell) =>
|
|
1610
|
+
fluentTransaction(() =>
|
|
1611
|
+
ifNotUndefined(
|
|
1612
|
+
getValidatedCell(
|
|
1613
|
+
tableId,
|
|
1614
|
+
rowId,
|
|
1615
|
+
cellId,
|
|
1616
|
+
isFunction(cell) ? cell(getCell(tableId, rowId, cellId)) : cell,
|
|
1617
|
+
),
|
|
1618
|
+
(validCell) =>
|
|
1524
1619
|
setCellIntoDefaultRow(
|
|
1525
1620
|
tableId,
|
|
1526
1621
|
getOrCreateTable(tableId),
|
|
@@ -1528,77 +1623,74 @@ const createStore = () => {
|
|
|
1528
1623
|
cellId,
|
|
1529
1624
|
validCell,
|
|
1530
1625
|
),
|
|
1531
|
-
|
|
1626
|
+
),
|
|
1532
1627
|
);
|
|
1533
|
-
return store;
|
|
1534
|
-
};
|
|
1535
1628
|
const setJson = (json) => {
|
|
1536
1629
|
try {
|
|
1537
1630
|
json === EMPTY_OBJECT ? delTables() : setTables(jsonParse(json));
|
|
1538
1631
|
} catch {}
|
|
1539
1632
|
return store;
|
|
1540
1633
|
};
|
|
1541
|
-
const setSchema = (schema) =>
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
return store;
|
|
1551
|
-
};
|
|
1552
|
-
const delTables = () => {
|
|
1553
|
-
transaction(() => setValidTables({}));
|
|
1554
|
-
return store;
|
|
1555
|
-
};
|
|
1556
|
-
const delTable = (tableId) => {
|
|
1557
|
-
if (collHas(tablesMap, tableId)) {
|
|
1558
|
-
transaction(() => delValidTable(tableId));
|
|
1559
|
-
}
|
|
1560
|
-
return store;
|
|
1561
|
-
};
|
|
1562
|
-
const delRow = (tableId, rowId) => {
|
|
1563
|
-
ifNotUndefined(mapGet(tablesMap, tableId), (tableMap) => {
|
|
1564
|
-
if (collHas(tableMap, rowId)) {
|
|
1565
|
-
transaction(() => delValidRow(tableId, tableMap, rowId));
|
|
1634
|
+
const setSchema = (schema) =>
|
|
1635
|
+
fluentTransaction(() => {
|
|
1636
|
+
if ((hasSchema = validateSchema(schema))) {
|
|
1637
|
+
setValidSchema(schema);
|
|
1638
|
+
if (!collIsEmpty(tablesMap)) {
|
|
1639
|
+
const tables = getTables();
|
|
1640
|
+
delTables();
|
|
1641
|
+
setTables(tables);
|
|
1642
|
+
}
|
|
1566
1643
|
}
|
|
1567
1644
|
});
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
ifNotUndefined(mapGet(tableMap, rowId), (rowMap) => {
|
|
1573
|
-
if (collHas(rowMap, cellId)) {
|
|
1574
|
-
transaction(() =>
|
|
1575
|
-
delValidCell(tableId, tableMap, rowId, rowMap, cellId, forceDel),
|
|
1576
|
-
);
|
|
1577
|
-
}
|
|
1578
|
-
}),
|
|
1645
|
+
const delTables = () => fluentTransaction(() => setValidTables({}));
|
|
1646
|
+
const delTable = (tableId) =>
|
|
1647
|
+
fluentTransaction(() =>
|
|
1648
|
+
collHas(tablesMap, tableId) ? delValidTable(tableId) : 0,
|
|
1579
1649
|
);
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1650
|
+
const delRow = (tableId, rowId) =>
|
|
1651
|
+
fluentTransaction(() =>
|
|
1652
|
+
ifNotUndefined(mapGet(tablesMap, tableId), (tableMap) =>
|
|
1653
|
+
collHas(tableMap, rowId) ? delValidRow(tableId, tableMap, rowId) : 0,
|
|
1654
|
+
),
|
|
1655
|
+
);
|
|
1656
|
+
const delCell = (tableId, rowId, cellId, forceDel) =>
|
|
1657
|
+
fluentTransaction(() =>
|
|
1658
|
+
ifNotUndefined(mapGet(tablesMap, tableId), (tableMap) =>
|
|
1659
|
+
ifNotUndefined(mapGet(tableMap, rowId), (rowMap) =>
|
|
1660
|
+
collHas(rowMap, cellId)
|
|
1661
|
+
? delValidCell(tableId, tableMap, rowId, rowMap, cellId, forceDel)
|
|
1662
|
+
: 0,
|
|
1663
|
+
),
|
|
1664
|
+
),
|
|
1665
|
+
);
|
|
1666
|
+
const delSchema = () =>
|
|
1667
|
+
fluentTransaction(() => {
|
|
1668
|
+
setValidSchema({});
|
|
1669
|
+
hasSchema = false;
|
|
1670
|
+
});
|
|
1587
1671
|
const transaction = (actions) => {
|
|
1588
1672
|
if (transactions == -1) {
|
|
1589
1673
|
return;
|
|
1590
1674
|
}
|
|
1591
1675
|
transactions++;
|
|
1592
|
-
const result = actions();
|
|
1676
|
+
const result = actions?.();
|
|
1593
1677
|
transactions--;
|
|
1594
1678
|
if (transactions == 0) {
|
|
1595
1679
|
transactions = 1;
|
|
1680
|
+
callInvalidCellListeners(1);
|
|
1596
1681
|
callListenersForChanges(1);
|
|
1597
1682
|
transactions = -1;
|
|
1683
|
+
callInvalidCellListeners(0);
|
|
1598
1684
|
callListenersForChanges(0);
|
|
1599
1685
|
transactions = 0;
|
|
1600
1686
|
arrayForEach(
|
|
1601
|
-
[
|
|
1687
|
+
[
|
|
1688
|
+
changedCells,
|
|
1689
|
+
invalidCells,
|
|
1690
|
+
changedTableIds,
|
|
1691
|
+
changedRowIds,
|
|
1692
|
+
changedCellIds,
|
|
1693
|
+
],
|
|
1602
1694
|
collClear,
|
|
1603
1695
|
);
|
|
1604
1696
|
}
|
|
@@ -1638,6 +1730,12 @@ const createStore = () => {
|
|
|
1638
1730
|
rowId,
|
|
1639
1731
|
cellId,
|
|
1640
1732
|
]);
|
|
1733
|
+
const addInvalidCellListener = (tableId, rowId, cellId, listener, mutator) =>
|
|
1734
|
+
addListener(listener, invalidCellListeners[mutator ? 1 : 0], [
|
|
1735
|
+
tableId,
|
|
1736
|
+
rowId,
|
|
1737
|
+
cellId,
|
|
1738
|
+
]);
|
|
1641
1739
|
const callListener = (listenerId) => {
|
|
1642
1740
|
callListenerImpl(listenerId, [getTableIds, getRowIds, getCellIds], (ids) =>
|
|
1643
1741
|
isUndefined(ids[2]) ? [] : Array(2).fill(getCell(...ids)),
|
|
@@ -1665,6 +1763,7 @@ const createStore = () => {
|
|
|
1665
1763
|
getRow,
|
|
1666
1764
|
getCellIds,
|
|
1667
1765
|
getCell,
|
|
1766
|
+
hasTables,
|
|
1668
1767
|
hasTable,
|
|
1669
1768
|
hasRow,
|
|
1670
1769
|
hasCell,
|
|
@@ -1694,6 +1793,7 @@ const createStore = () => {
|
|
|
1694
1793
|
addRowListener,
|
|
1695
1794
|
addCellIdsListener,
|
|
1696
1795
|
addCellListener,
|
|
1796
|
+
addInvalidCellListener,
|
|
1697
1797
|
callListener,
|
|
1698
1798
|
delListener,
|
|
1699
1799
|
getListenerStats,
|