tinybase 1.0.4 → 1.1.0-beta.2
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 +44 -0
- package/lib/checkpoints.js +1 -1
- package/lib/checkpoints.js.gz +0 -0
- package/lib/debug/checkpoints.d.ts +44 -0
- package/lib/debug/checkpoints.js +13 -6
- package/lib/debug/indexes.d.ts +114 -1
- package/lib/debug/indexes.js +29 -2
- package/lib/debug/metrics.d.ts +46 -0
- package/lib/debug/metrics.js +8 -2
- package/lib/debug/relationships.d.ts +63 -1
- package/lib/debug/relationships.js +14 -2
- package/lib/debug/store.d.ts +269 -5
- package/lib/debug/store.js +243 -185
- package/lib/debug/tinybase.js +285 -189
- package/lib/indexes.d.ts +114 -1
- package/lib/indexes.js +1 -1
- package/lib/indexes.js.gz +0 -0
- package/lib/metrics.d.ts +46 -0
- package/lib/metrics.js +1 -1
- package/lib/metrics.js.gz +0 -0
- package/lib/relationships.d.ts +63 -1
- package/lib/relationships.js +1 -1
- package/lib/relationships.js.gz +0 -0
- package/lib/store.d.ts +269 -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 +20 -19
- 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,7 @@ 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);
|
|
113
116
|
const hasThing = (id) => collHas(things, id);
|
|
114
117
|
const getTableId = (id) => mapGet(tableIds, id);
|
|
115
118
|
const getThing = (id) => mapGet(things, id);
|
|
@@ -200,6 +203,7 @@ const getDefinableFunctions = (store, getDefaultThing, validateRowValue) => {
|
|
|
200
203
|
return [
|
|
201
204
|
getStore,
|
|
202
205
|
getThingIds,
|
|
206
|
+
forEachThing,
|
|
203
207
|
hasThing,
|
|
204
208
|
getTableId,
|
|
205
209
|
getThing,
|
|
@@ -252,7 +256,7 @@ const getListenerFunctions = (getThing) => {
|
|
|
252
256
|
const allListeners = mapNew();
|
|
253
257
|
const addListener = (listener, deepSet, idOrNulls = []) => {
|
|
254
258
|
thing ??= getThing();
|
|
255
|
-
const id = listenerPool
|
|
259
|
+
const id = arrayPop(listenerPool) ?? '' + nextId++;
|
|
256
260
|
mapSet(allListeners, id, [listener, deepSet, idOrNulls]);
|
|
257
261
|
addDeepSet(deepSet, id, idOrNulls);
|
|
258
262
|
return id;
|
|
@@ -273,7 +277,7 @@ const getListenerFunctions = (getThing) => {
|
|
|
273
277
|
forDeepSet(collDel)(deepSet, id, ...idOrNulls);
|
|
274
278
|
mapSet(allListeners, id);
|
|
275
279
|
if (arrayLength(listenerPool) < 1e3) {
|
|
276
|
-
listenerPool
|
|
280
|
+
arrayPush(listenerPool, id);
|
|
277
281
|
}
|
|
278
282
|
return idOrNulls;
|
|
279
283
|
},
|
|
@@ -359,7 +363,7 @@ const createCheckpoints = getCreateFunction((store) => {
|
|
|
359
363
|
(_store, tableId, rowId, cellId, newCell, oldCell) => {
|
|
360
364
|
if (listening) {
|
|
361
365
|
ifNotUndefined(currentId, () => {
|
|
362
|
-
backwardIds
|
|
366
|
+
arrayPush(backwardIds, currentId);
|
|
363
367
|
trimBackwardsIds();
|
|
364
368
|
clearCheckpointIds(forwardIds);
|
|
365
369
|
currentId = void 0;
|
|
@@ -378,7 +382,7 @@ const createCheckpoints = getCreateFunction((store) => {
|
|
|
378
382
|
if (collIsEmpty(mapSet(row, cellId))) {
|
|
379
383
|
if (collIsEmpty(mapSet(table, rowId))) {
|
|
380
384
|
if (collIsEmpty(mapSet(delta, tableId))) {
|
|
381
|
-
currentId = backwardIds
|
|
385
|
+
currentId = arrayPop(backwardIds);
|
|
382
386
|
checkpointsChanged = 1;
|
|
383
387
|
}
|
|
384
388
|
}
|
|
@@ -402,13 +406,13 @@ const createCheckpoints = getCreateFunction((store) => {
|
|
|
402
406
|
if (!arrayIsEmpty(backwardIds)) {
|
|
403
407
|
forwardIds.unshift(addCheckpointImpl());
|
|
404
408
|
updateStore(0, currentId);
|
|
405
|
-
currentId = backwardIds
|
|
409
|
+
currentId = arrayPop(backwardIds);
|
|
406
410
|
checkpointsChanged = 1;
|
|
407
411
|
}
|
|
408
412
|
};
|
|
409
413
|
const goForwardImpl = () => {
|
|
410
414
|
if (!arrayIsEmpty(forwardIds)) {
|
|
411
|
-
backwardIds
|
|
415
|
+
arrayPush(backwardIds, currentId);
|
|
412
416
|
currentId = forwardIds.shift();
|
|
413
417
|
updateStore(1, currentId);
|
|
414
418
|
checkpointsChanged = 1;
|
|
@@ -439,6 +443,8 @@ const createCheckpoints = getCreateFunction((store) => {
|
|
|
439
443
|
};
|
|
440
444
|
const getStore = () => store;
|
|
441
445
|
const getCheckpointIds = () => [[...backwardIds], currentId, [...forwardIds]];
|
|
446
|
+
const forEachCheckpoint = (checkpointCallback) =>
|
|
447
|
+
mapForEach(labels, checkpointCallback);
|
|
442
448
|
const hasCheckpoint = (checkpointId) => collHas(deltas, checkpointId);
|
|
443
449
|
const getCheckpoint = (checkpointId) => mapGet(labels, checkpointId);
|
|
444
450
|
const goBackward = () => {
|
|
@@ -495,6 +501,7 @@ const createCheckpoints = getCreateFunction((store) => {
|
|
|
495
501
|
setCheckpoint,
|
|
496
502
|
getStore,
|
|
497
503
|
getCheckpointIds,
|
|
504
|
+
forEachCheckpoint,
|
|
498
505
|
hasCheckpoint,
|
|
499
506
|
getCheckpoint,
|
|
500
507
|
goBackward,
|
|
@@ -518,6 +525,7 @@ const createIndexes = getCreateFunction((store) => {
|
|
|
518
525
|
const [
|
|
519
526
|
getStore,
|
|
520
527
|
getIndexIds,
|
|
528
|
+
forEachIndexImpl,
|
|
521
529
|
hasIndex,
|
|
522
530
|
getTableId,
|
|
523
531
|
getIndex,
|
|
@@ -627,6 +635,26 @@ const createIndexes = getCreateFunction((store) => {
|
|
|
627
635
|
);
|
|
628
636
|
return indexes;
|
|
629
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
|
+
};
|
|
630
658
|
const delIndexDefinition = (indexId) => {
|
|
631
659
|
delDefinition(indexId);
|
|
632
660
|
return indexes;
|
|
@@ -651,6 +679,8 @@ const createIndexes = getCreateFunction((store) => {
|
|
|
651
679
|
delIndexDefinition,
|
|
652
680
|
getStore,
|
|
653
681
|
getIndexIds,
|
|
682
|
+
forEachIndex,
|
|
683
|
+
forEachSlice,
|
|
654
684
|
hasIndex,
|
|
655
685
|
hasSlice,
|
|
656
686
|
getTableId,
|
|
@@ -710,6 +740,7 @@ const createMetrics = getCreateFunction((store) => {
|
|
|
710
740
|
const [
|
|
711
741
|
getStore,
|
|
712
742
|
getMetricIds,
|
|
743
|
+
forEachMetric,
|
|
713
744
|
hasMetric,
|
|
714
745
|
getTableId,
|
|
715
746
|
getMetric,
|
|
@@ -795,6 +826,7 @@ const createMetrics = getCreateFunction((store) => {
|
|
|
795
826
|
delMetricDefinition,
|
|
796
827
|
getStore,
|
|
797
828
|
getMetricIds,
|
|
829
|
+
forEachMetric,
|
|
798
830
|
hasMetric,
|
|
799
831
|
getTableId,
|
|
800
832
|
getMetric,
|
|
@@ -987,6 +1019,7 @@ const createRelationships = getCreateFunction((store) => {
|
|
|
987
1019
|
const [
|
|
988
1020
|
getStore,
|
|
989
1021
|
getRelationshipIds,
|
|
1022
|
+
forEachRelationshipImpl,
|
|
990
1023
|
hasRelationship,
|
|
991
1024
|
getLocalTableId,
|
|
992
1025
|
getRelationship,
|
|
@@ -1101,6 +1134,12 @@ const createRelationships = getCreateFunction((store) => {
|
|
|
1101
1134
|
);
|
|
1102
1135
|
return relationships;
|
|
1103
1136
|
};
|
|
1137
|
+
const forEachRelationship = (relationshipCallback) =>
|
|
1138
|
+
forEachRelationshipImpl((relationshipId) =>
|
|
1139
|
+
relationshipCallback(relationshipId, (rowCallback) =>
|
|
1140
|
+
store.forEachRow(getLocalTableId(relationshipId), rowCallback),
|
|
1141
|
+
),
|
|
1142
|
+
);
|
|
1104
1143
|
const delRelationshipDefinition = (relationshipId) => {
|
|
1105
1144
|
mapSet(remoteTableIds, relationshipId);
|
|
1106
1145
|
delDefinition(relationshipId);
|
|
@@ -1141,6 +1180,7 @@ const createRelationships = getCreateFunction((store) => {
|
|
|
1141
1180
|
delRelationshipDefinition,
|
|
1142
1181
|
getStore,
|
|
1143
1182
|
getRelationshipIds,
|
|
1183
|
+
forEachRelationship,
|
|
1144
1184
|
hasRelationship,
|
|
1145
1185
|
getLocalTableId,
|
|
1146
1186
|
getRemoteTableId,
|
|
@@ -1174,8 +1214,9 @@ const getCellType = (cell) => {
|
|
|
1174
1214
|
? type
|
|
1175
1215
|
: void 0;
|
|
1176
1216
|
};
|
|
1177
|
-
const validate = (obj, validateChild) => {
|
|
1178
|
-
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?.();
|
|
1179
1220
|
return false;
|
|
1180
1221
|
}
|
|
1181
1222
|
objForEach(obj, (child, id) => {
|
|
@@ -1195,8 +1236,9 @@ const createStore = () => {
|
|
|
1195
1236
|
const changedRowIds = mapNew();
|
|
1196
1237
|
const changedCellIds = mapNew();
|
|
1197
1238
|
const changedCells = mapNew();
|
|
1239
|
+
const invalidCells = mapNew();
|
|
1198
1240
|
const schemaMap = mapNew();
|
|
1199
|
-
const
|
|
1241
|
+
const schemaRowCache = mapNew();
|
|
1200
1242
|
const tablesMap = mapNew();
|
|
1201
1243
|
const tablesListeners = mapNewPair(setNew);
|
|
1202
1244
|
const tableIdsListeners = mapNewPair(setNew);
|
|
@@ -1205,6 +1247,7 @@ const createStore = () => {
|
|
|
1205
1247
|
const rowListeners = mapNewPair();
|
|
1206
1248
|
const cellIdsListeners = mapNewPair();
|
|
1207
1249
|
const cellListeners = mapNewPair();
|
|
1250
|
+
const invalidCellListeners = mapNewPair();
|
|
1208
1251
|
const [addListener, callListeners, delListenerImpl, callListenerImpl] =
|
|
1209
1252
|
getListenerFunctions(() => store);
|
|
1210
1253
|
const validateSchema = (schema) =>
|
|
@@ -1225,40 +1268,57 @@ const createStore = () => {
|
|
|
1225
1268
|
return true;
|
|
1226
1269
|
}),
|
|
1227
1270
|
);
|
|
1228
|
-
const validateTables = (tables) =>
|
|
1271
|
+
const validateTables = (tables) =>
|
|
1272
|
+
validate(tables, validateTable, cellInvalid);
|
|
1229
1273
|
const validateTable = (table, tableId) =>
|
|
1230
|
-
(!hasSchema || collHas(schemaMap, tableId)) &&
|
|
1231
|
-
validate(table, (row) => validateRow(tableId, row));
|
|
1232
|
-
const validateRow = (tableId, row, skipDefaults) =>
|
|
1274
|
+
(!hasSchema || collHas(schemaMap, tableId) || cellInvalid(tableId)) &&
|
|
1233
1275
|
validate(
|
|
1234
|
-
|
|
1276
|
+
table,
|
|
1277
|
+
(row, rowId) => validateRow(tableId, rowId, row),
|
|
1278
|
+
() => cellInvalid(tableId),
|
|
1279
|
+
);
|
|
1280
|
+
const validateRow = (tableId, rowId, row, skipDefaults) =>
|
|
1281
|
+
validate(
|
|
1282
|
+
skipDefaults ? row : addDefaultsToRow(row, tableId, rowId),
|
|
1235
1283
|
(cell, cellId) =>
|
|
1236
1284
|
ifNotUndefined(
|
|
1237
|
-
getValidatedCell(tableId, cellId, cell),
|
|
1285
|
+
getValidatedCell(tableId, rowId, cellId, cell),
|
|
1238
1286
|
(validCell) => {
|
|
1239
1287
|
row[cellId] = validCell;
|
|
1240
1288
|
return true;
|
|
1241
1289
|
},
|
|
1242
1290
|
() => false,
|
|
1243
1291
|
),
|
|
1292
|
+
() => cellInvalid(tableId, rowId),
|
|
1244
1293
|
);
|
|
1245
|
-
const getValidatedCell = (tableId, cellId, cell) =>
|
|
1294
|
+
const getValidatedCell = (tableId, rowId, cellId, cell) =>
|
|
1246
1295
|
hasSchema
|
|
1247
1296
|
? ifNotUndefined(
|
|
1248
1297
|
mapGet(mapGet(schemaMap, tableId), cellId),
|
|
1249
1298
|
(cellSchema) =>
|
|
1250
|
-
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),
|
|
1251
1303
|
)
|
|
1252
1304
|
: isUndefined(getCellType(cell))
|
|
1253
|
-
?
|
|
1305
|
+
? cellInvalid(tableId, rowId, cellId, cell)
|
|
1254
1306
|
: cell;
|
|
1255
|
-
const addDefaultsToRow = (row, tableId) => {
|
|
1256
|
-
ifNotUndefined(
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1307
|
+
const addDefaultsToRow = (row, tableId, rowId) => {
|
|
1308
|
+
ifNotUndefined(
|
|
1309
|
+
mapGet(schemaRowCache, tableId),
|
|
1310
|
+
([rowDefaulted, rowNonDefaulted]) => {
|
|
1311
|
+
collForEach(rowDefaulted, (cell, cellId) => {
|
|
1312
|
+
if (!objHas(row, cellId)) {
|
|
1313
|
+
row[cellId] = cell;
|
|
1314
|
+
}
|
|
1315
|
+
});
|
|
1316
|
+
collForEach(rowNonDefaulted, (cellId) => {
|
|
1317
|
+
if (!objHas(row, cellId)) {
|
|
1318
|
+
cellInvalid(tableId, rowId, cellId);
|
|
1319
|
+
}
|
|
1320
|
+
});
|
|
1321
|
+
},
|
|
1262
1322
|
);
|
|
1263
1323
|
return row;
|
|
1264
1324
|
};
|
|
@@ -1267,7 +1327,8 @@ const createStore = () => {
|
|
|
1267
1327
|
schemaMap,
|
|
1268
1328
|
schema,
|
|
1269
1329
|
(_schema, tableId, tableSchema) => {
|
|
1270
|
-
const
|
|
1330
|
+
const rowDefaulted = mapNew();
|
|
1331
|
+
const rowNonDefaulted = setNew();
|
|
1271
1332
|
transformMap(
|
|
1272
1333
|
mapEnsure(schemaMap, tableId, mapNew()),
|
|
1273
1334
|
tableSchema,
|
|
@@ -1275,15 +1336,16 @@ const createStore = () => {
|
|
|
1275
1336
|
mapSet(tableSchemaMap, cellId, cellSchema);
|
|
1276
1337
|
ifNotUndefined(
|
|
1277
1338
|
cellSchema[DEFAULT],
|
|
1278
|
-
(def) => (
|
|
1339
|
+
(def) => mapSet(rowDefaulted, cellId, def),
|
|
1340
|
+
() => setAdd(rowNonDefaulted, cellId),
|
|
1279
1341
|
);
|
|
1280
1342
|
},
|
|
1281
1343
|
);
|
|
1282
|
-
mapSet(
|
|
1344
|
+
mapSet(schemaRowCache, tableId, [rowDefaulted, rowNonDefaulted]);
|
|
1283
1345
|
},
|
|
1284
1346
|
(_schema, tableId) => {
|
|
1285
1347
|
mapSet(schemaMap, tableId);
|
|
1286
|
-
mapSet(
|
|
1348
|
+
mapSet(schemaRowCache, tableId);
|
|
1287
1349
|
},
|
|
1288
1350
|
);
|
|
1289
1351
|
const setValidTables = (tables) =>
|
|
@@ -1323,10 +1385,6 @@ const createStore = () => {
|
|
|
1323
1385
|
mapSet(rowMap, cellId, newCell);
|
|
1324
1386
|
}
|
|
1325
1387
|
};
|
|
1326
|
-
const setValidRowTransaction = (tableId, rowId, row) =>
|
|
1327
|
-
transaction(() =>
|
|
1328
|
-
setValidRow(tableId, getOrCreateTable(tableId), rowId, row),
|
|
1329
|
-
);
|
|
1330
1388
|
const setCellIntoDefaultRow = (tableId, tableMap, rowId, cellId, validCell) =>
|
|
1331
1389
|
ifNotUndefined(
|
|
1332
1390
|
mapGet(tableMap, rowId),
|
|
@@ -1336,7 +1394,7 @@ const createStore = () => {
|
|
|
1336
1394
|
tableId,
|
|
1337
1395
|
tableMap,
|
|
1338
1396
|
rowId,
|
|
1339
|
-
addDefaultsToRow({[cellId]: validCell}, tableId),
|
|
1397
|
+
addDefaultsToRow({[cellId]: validCell}, tableId, rowId),
|
|
1340
1398
|
),
|
|
1341
1399
|
);
|
|
1342
1400
|
const getNewRowId = (tableMap) => {
|
|
@@ -1352,7 +1410,7 @@ const createStore = () => {
|
|
|
1352
1410
|
const delValidRow = (tableId, tableMap, rowId) =>
|
|
1353
1411
|
setValidRow(tableId, tableMap, rowId, {}, true);
|
|
1354
1412
|
const delValidCell = (tableId, table, rowId, row, cellId, forceDel) => {
|
|
1355
|
-
const defaultCell = mapGet(
|
|
1413
|
+
const defaultCell = mapGet(mapGet(schemaRowCache, tableId)?.[0], cellId);
|
|
1356
1414
|
if (!isUndefined(defaultCell) && !forceDel) {
|
|
1357
1415
|
return setValidCell(tableId, rowId, row, cellId, defaultCell);
|
|
1358
1416
|
}
|
|
@@ -1386,6 +1444,17 @@ const createStore = () => {
|
|
|
1386
1444
|
cellId,
|
|
1387
1445
|
oldCell,
|
|
1388
1446
|
);
|
|
1447
|
+
const cellInvalid = (tableId, rowId, cellId, invalidCell, defaultedCell) => {
|
|
1448
|
+
arrayPush(
|
|
1449
|
+
mapEnsure(
|
|
1450
|
+
mapEnsure(mapEnsure(invalidCells, tableId, mapNew()), rowId, mapNew()),
|
|
1451
|
+
cellId,
|
|
1452
|
+
[],
|
|
1453
|
+
),
|
|
1454
|
+
invalidCell,
|
|
1455
|
+
);
|
|
1456
|
+
return defaultedCell;
|
|
1457
|
+
};
|
|
1389
1458
|
const getCellChange = (tableId, rowId, cellId) => {
|
|
1390
1459
|
const changedRow = mapGet(mapGet(changedCells, tableId), rowId);
|
|
1391
1460
|
const newCell = getCell(tableId, rowId, cellId);
|
|
@@ -1393,80 +1462,103 @@ const createStore = () => {
|
|
|
1393
1462
|
? [true, mapGet(changedRow, cellId), newCell]
|
|
1394
1463
|
: [false, newCell, newCell];
|
|
1395
1464
|
};
|
|
1465
|
+
const callInvalidCellListeners = (mutator) =>
|
|
1466
|
+
!collIsEmpty(invalidCells) && !collIsEmpty(invalidCellListeners[mutator])
|
|
1467
|
+
? collForEach(
|
|
1468
|
+
mutator
|
|
1469
|
+
? mapClone(invalidCells, (table) => mapClone(table, mapClone))
|
|
1470
|
+
: invalidCells,
|
|
1471
|
+
(rows, tableId) =>
|
|
1472
|
+
collForEach(rows, (cells, rowId) =>
|
|
1473
|
+
collForEach(cells, (invalidCell, cellId) =>
|
|
1474
|
+
callListeners(
|
|
1475
|
+
invalidCellListeners[mutator],
|
|
1476
|
+
[tableId, rowId, cellId],
|
|
1477
|
+
invalidCell,
|
|
1478
|
+
),
|
|
1479
|
+
),
|
|
1480
|
+
),
|
|
1481
|
+
)
|
|
1482
|
+
: 0;
|
|
1396
1483
|
const callListenersForChanges = (mutator) => {
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1484
|
+
if (!collIsEmpty(changedCells)) {
|
|
1485
|
+
const emptyIdListeners =
|
|
1486
|
+
collIsEmpty(cellIdsListeners[mutator]) &&
|
|
1487
|
+
collIsEmpty(rowIdsListeners[mutator]) &&
|
|
1488
|
+
collIsEmpty(tableIdsListeners[mutator]);
|
|
1489
|
+
const emptyOtherListeners =
|
|
1490
|
+
collIsEmpty(cellListeners[mutator]) &&
|
|
1491
|
+
collIsEmpty(rowListeners[mutator]) &&
|
|
1492
|
+
collIsEmpty(tableListeners[mutator]) &&
|
|
1493
|
+
collIsEmpty(tablesListeners[mutator]);
|
|
1494
|
+
if (!(emptyIdListeners && emptyOtherListeners)) {
|
|
1495
|
+
const changes = mutator
|
|
1496
|
+
? [
|
|
1497
|
+
mapClone(changedTableIds),
|
|
1498
|
+
mapClone(changedRowIds, mapClone),
|
|
1499
|
+
mapClone(changedCellIds, (table) => mapClone(table, mapClone)),
|
|
1500
|
+
mapClone(changedCells, (table) => mapClone(table, mapClone)),
|
|
1501
|
+
]
|
|
1502
|
+
: [changedTableIds, changedRowIds, changedCellIds, changedCells];
|
|
1503
|
+
if (!emptyIdListeners) {
|
|
1504
|
+
collForEach(changes[2], (rowCellIds, tableId) =>
|
|
1505
|
+
collForEach(rowCellIds, (changedIds, rowId) => {
|
|
1506
|
+
if (!collIsEmpty(changedIds)) {
|
|
1507
|
+
callListeners(cellIdsListeners[mutator], [tableId, rowId]);
|
|
1508
|
+
}
|
|
1509
|
+
}),
|
|
1510
|
+
);
|
|
1511
|
+
collForEach(changes[1], (changedIds, tableId) => {
|
|
1512
|
+
if (!collIsEmpty(changedIds)) {
|
|
1513
|
+
callListeners(rowIdsListeners[mutator], [tableId]);
|
|
1514
|
+
}
|
|
1515
|
+
});
|
|
1516
|
+
if (!collIsEmpty(changes[0])) {
|
|
1517
|
+
callListeners(tableIdsListeners[mutator]);
|
|
1422
1518
|
}
|
|
1423
|
-
}),
|
|
1424
|
-
);
|
|
1425
|
-
collForEach(changes[1], (changedIds, tableId) => {
|
|
1426
|
-
if (!collIsEmpty(changedIds)) {
|
|
1427
|
-
callListeners(rowIdsListeners[mutator], [tableId]);
|
|
1428
1519
|
}
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1520
|
+
if (!emptyOtherListeners) {
|
|
1521
|
+
let tablesChanged;
|
|
1522
|
+
collForEach(changes[3], (rows, tableId) => {
|
|
1523
|
+
let tableChanged;
|
|
1524
|
+
collForEach(rows, (cells, rowId) => {
|
|
1525
|
+
let rowChanged;
|
|
1526
|
+
collForEach(cells, (oldCell, cellId) => {
|
|
1527
|
+
const newCell = getCell(tableId, rowId, cellId);
|
|
1528
|
+
if (newCell !== oldCell) {
|
|
1529
|
+
callListeners(
|
|
1530
|
+
cellListeners[mutator],
|
|
1531
|
+
[tableId, rowId, cellId],
|
|
1532
|
+
newCell,
|
|
1533
|
+
oldCell,
|
|
1534
|
+
getCellChange,
|
|
1535
|
+
);
|
|
1536
|
+
tablesChanged = tableChanged = rowChanged = 1;
|
|
1537
|
+
}
|
|
1538
|
+
});
|
|
1539
|
+
if (rowChanged) {
|
|
1540
|
+
callListeners(
|
|
1541
|
+
rowListeners[mutator],
|
|
1542
|
+
[tableId, rowId],
|
|
1543
|
+
getCellChange,
|
|
1544
|
+
);
|
|
1545
|
+
}
|
|
1546
|
+
});
|
|
1547
|
+
if (tableChanged) {
|
|
1548
|
+
callListeners(tableListeners[mutator], [tableId], getCellChange);
|
|
1451
1549
|
}
|
|
1452
1550
|
});
|
|
1453
|
-
if (
|
|
1454
|
-
callListeners(
|
|
1455
|
-
rowListeners[mutator],
|
|
1456
|
-
[tableId, rowId],
|
|
1457
|
-
getCellChange,
|
|
1458
|
-
);
|
|
1551
|
+
if (tablesChanged) {
|
|
1552
|
+
callListeners(tablesListeners[mutator], [], getCellChange);
|
|
1459
1553
|
}
|
|
1460
|
-
});
|
|
1461
|
-
if (tableChanged) {
|
|
1462
|
-
callListeners(tableListeners[mutator], [tableId], getCellChange);
|
|
1463
1554
|
}
|
|
1464
|
-
});
|
|
1465
|
-
if (tablesChanged) {
|
|
1466
|
-
callListeners(tablesListeners[mutator], [], getCellChange);
|
|
1467
1555
|
}
|
|
1468
1556
|
}
|
|
1469
1557
|
};
|
|
1558
|
+
const fluentTransaction = (actions) => {
|
|
1559
|
+
transaction(actions);
|
|
1560
|
+
return store;
|
|
1561
|
+
};
|
|
1470
1562
|
const getTables = () =>
|
|
1471
1563
|
mapToObj(tablesMap, (tableMap) => mapToObj(tableMap, mapToObj));
|
|
1472
1564
|
const getTableIds = () => mapKeys(tablesMap);
|
|
@@ -1485,52 +1577,52 @@ const createStore = () => {
|
|
|
1485
1577
|
collHas(mapGet(mapGet(tablesMap, tableId), rowId), cellId);
|
|
1486
1578
|
const getJson = () => jsonString(tablesMap);
|
|
1487
1579
|
const getSchemaJson = () => jsonString(schemaMap);
|
|
1488
|
-
const setTables = (tables) =>
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1580
|
+
const setTables = (tables) =>
|
|
1581
|
+
fluentTransaction(() =>
|
|
1582
|
+
validateTables(tables) ? setValidTables(tables) : 0,
|
|
1583
|
+
);
|
|
1584
|
+
const setTable = (tableId, table) =>
|
|
1585
|
+
fluentTransaction(() =>
|
|
1586
|
+
validateTable(table, tableId) ? setValidTable(tableId, table) : 0,
|
|
1587
|
+
);
|
|
1588
|
+
const setRow = (tableId, rowId, row) =>
|
|
1589
|
+
fluentTransaction(() =>
|
|
1590
|
+
validateRow(tableId, rowId, row)
|
|
1591
|
+
? setValidRow(tableId, getOrCreateTable(tableId), rowId, row)
|
|
1592
|
+
: 0,
|
|
1593
|
+
);
|
|
1594
|
+
const addRow = (tableId, row) =>
|
|
1595
|
+
transaction(() => {
|
|
1596
|
+
let rowId = void 0;
|
|
1597
|
+
if (validateRow(tableId, rowId, row)) {
|
|
1598
|
+
setValidRow(
|
|
1599
|
+
tableId,
|
|
1600
|
+
getOrCreateTable(tableId),
|
|
1601
|
+
(rowId = getNewRowId(mapGet(tablesMap, tableId))),
|
|
1602
|
+
row,
|
|
1603
|
+
);
|
|
1604
|
+
}
|
|
1605
|
+
return rowId;
|
|
1606
|
+
});
|
|
1607
|
+
const setPartialRow = (tableId, rowId, partialRow) =>
|
|
1608
|
+
fluentTransaction(() => {
|
|
1609
|
+
if (validateRow(tableId, rowId, partialRow, 1)) {
|
|
1517
1610
|
const table = getOrCreateTable(tableId);
|
|
1518
1611
|
objForEach(partialRow, (cell, cellId) =>
|
|
1519
1612
|
setCellIntoDefaultRow(tableId, table, rowId, cellId, cell),
|
|
1520
1613
|
);
|
|
1521
|
-
}
|
|
1522
|
-
}
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
transaction(() =>
|
|
1614
|
+
}
|
|
1615
|
+
});
|
|
1616
|
+
const setCell = (tableId, rowId, cellId, cell) =>
|
|
1617
|
+
fluentTransaction(() =>
|
|
1618
|
+
ifNotUndefined(
|
|
1619
|
+
getValidatedCell(
|
|
1620
|
+
tableId,
|
|
1621
|
+
rowId,
|
|
1622
|
+
cellId,
|
|
1623
|
+
isFunction(cell) ? cell(getCell(tableId, rowId, cellId)) : cell,
|
|
1624
|
+
),
|
|
1625
|
+
(validCell) =>
|
|
1534
1626
|
setCellIntoDefaultRow(
|
|
1535
1627
|
tableId,
|
|
1536
1628
|
getOrCreateTable(tableId),
|
|
@@ -1538,77 +1630,74 @@ const createStore = () => {
|
|
|
1538
1630
|
cellId,
|
|
1539
1631
|
validCell,
|
|
1540
1632
|
),
|
|
1541
|
-
|
|
1633
|
+
),
|
|
1542
1634
|
);
|
|
1543
|
-
return store;
|
|
1544
|
-
};
|
|
1545
1635
|
const setJson = (json) => {
|
|
1546
1636
|
try {
|
|
1547
1637
|
json === EMPTY_OBJECT ? delTables() : setTables(jsonParse(json));
|
|
1548
1638
|
} catch {}
|
|
1549
1639
|
return store;
|
|
1550
1640
|
};
|
|
1551
|
-
const setSchema = (schema) =>
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
return store;
|
|
1561
|
-
};
|
|
1562
|
-
const delTables = () => {
|
|
1563
|
-
transaction(() => setValidTables({}));
|
|
1564
|
-
return store;
|
|
1565
|
-
};
|
|
1566
|
-
const delTable = (tableId) => {
|
|
1567
|
-
if (collHas(tablesMap, tableId)) {
|
|
1568
|
-
transaction(() => delValidTable(tableId));
|
|
1569
|
-
}
|
|
1570
|
-
return store;
|
|
1571
|
-
};
|
|
1572
|
-
const delRow = (tableId, rowId) => {
|
|
1573
|
-
ifNotUndefined(mapGet(tablesMap, tableId), (tableMap) => {
|
|
1574
|
-
if (collHas(tableMap, rowId)) {
|
|
1575
|
-
transaction(() => delValidRow(tableId, tableMap, rowId));
|
|
1641
|
+
const setSchema = (schema) =>
|
|
1642
|
+
fluentTransaction(() => {
|
|
1643
|
+
if ((hasSchema = validateSchema(schema))) {
|
|
1644
|
+
setValidSchema(schema);
|
|
1645
|
+
if (!collIsEmpty(tablesMap)) {
|
|
1646
|
+
const tables = getTables();
|
|
1647
|
+
delTables();
|
|
1648
|
+
setTables(tables);
|
|
1649
|
+
}
|
|
1576
1650
|
}
|
|
1577
1651
|
});
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
ifNotUndefined(mapGet(tableMap, rowId), (rowMap) => {
|
|
1583
|
-
if (collHas(rowMap, cellId)) {
|
|
1584
|
-
transaction(() =>
|
|
1585
|
-
delValidCell(tableId, tableMap, rowId, rowMap, cellId, forceDel),
|
|
1586
|
-
);
|
|
1587
|
-
}
|
|
1588
|
-
}),
|
|
1652
|
+
const delTables = () => fluentTransaction(() => setValidTables({}));
|
|
1653
|
+
const delTable = (tableId) =>
|
|
1654
|
+
fluentTransaction(() =>
|
|
1655
|
+
collHas(tablesMap, tableId) ? delValidTable(tableId) : 0,
|
|
1589
1656
|
);
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1657
|
+
const delRow = (tableId, rowId) =>
|
|
1658
|
+
fluentTransaction(() =>
|
|
1659
|
+
ifNotUndefined(mapGet(tablesMap, tableId), (tableMap) =>
|
|
1660
|
+
collHas(tableMap, rowId) ? delValidRow(tableId, tableMap, rowId) : 0,
|
|
1661
|
+
),
|
|
1662
|
+
);
|
|
1663
|
+
const delCell = (tableId, rowId, cellId, forceDel) =>
|
|
1664
|
+
fluentTransaction(() =>
|
|
1665
|
+
ifNotUndefined(mapGet(tablesMap, tableId), (tableMap) =>
|
|
1666
|
+
ifNotUndefined(mapGet(tableMap, rowId), (rowMap) =>
|
|
1667
|
+
collHas(rowMap, cellId)
|
|
1668
|
+
? delValidCell(tableId, tableMap, rowId, rowMap, cellId, forceDel)
|
|
1669
|
+
: 0,
|
|
1670
|
+
),
|
|
1671
|
+
),
|
|
1672
|
+
);
|
|
1673
|
+
const delSchema = () =>
|
|
1674
|
+
fluentTransaction(() => {
|
|
1675
|
+
setValidSchema({});
|
|
1676
|
+
hasSchema = false;
|
|
1677
|
+
});
|
|
1597
1678
|
const transaction = (actions) => {
|
|
1598
1679
|
if (transactions == -1) {
|
|
1599
1680
|
return;
|
|
1600
1681
|
}
|
|
1601
1682
|
transactions++;
|
|
1602
|
-
const result = actions();
|
|
1683
|
+
const result = actions?.();
|
|
1603
1684
|
transactions--;
|
|
1604
1685
|
if (transactions == 0) {
|
|
1605
1686
|
transactions = 1;
|
|
1687
|
+
callInvalidCellListeners(1);
|
|
1606
1688
|
callListenersForChanges(1);
|
|
1607
1689
|
transactions = -1;
|
|
1690
|
+
callInvalidCellListeners(0);
|
|
1608
1691
|
callListenersForChanges(0);
|
|
1609
1692
|
transactions = 0;
|
|
1610
1693
|
arrayForEach(
|
|
1611
|
-
[
|
|
1694
|
+
[
|
|
1695
|
+
changedCells,
|
|
1696
|
+
invalidCells,
|
|
1697
|
+
changedTableIds,
|
|
1698
|
+
changedRowIds,
|
|
1699
|
+
changedCellIds,
|
|
1700
|
+
],
|
|
1612
1701
|
collClear,
|
|
1613
1702
|
);
|
|
1614
1703
|
}
|
|
@@ -1648,6 +1737,12 @@ const createStore = () => {
|
|
|
1648
1737
|
rowId,
|
|
1649
1738
|
cellId,
|
|
1650
1739
|
]);
|
|
1740
|
+
const addInvalidCellListener = (tableId, rowId, cellId, listener, mutator) =>
|
|
1741
|
+
addListener(listener, invalidCellListeners[mutator ? 1 : 0], [
|
|
1742
|
+
tableId,
|
|
1743
|
+
rowId,
|
|
1744
|
+
cellId,
|
|
1745
|
+
]);
|
|
1651
1746
|
const callListener = (listenerId) => {
|
|
1652
1747
|
callListenerImpl(listenerId, [getTableIds, getRowIds, getCellIds], (ids) =>
|
|
1653
1748
|
isUndefined(ids[2]) ? [] : Array(2).fill(getCell(...ids)),
|
|
@@ -1705,6 +1800,7 @@ const createStore = () => {
|
|
|
1705
1800
|
addRowListener,
|
|
1706
1801
|
addCellIdsListener,
|
|
1707
1802
|
addCellListener,
|
|
1803
|
+
addInvalidCellListener,
|
|
1708
1804
|
callListener,
|
|
1709
1805
|
delListener,
|
|
1710
1806
|
getListenerStats,
|