tinybase 1.0.5 → 1.1.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/lib/checkpoints.js +1 -1
- package/lib/checkpoints.js.gz +0 -0
- package/lib/debug/checkpoints.js +8 -6
- package/lib/debug/indexes.js +4 -2
- package/lib/debug/metrics.d.ts +1 -1
- package/lib/debug/metrics.js +4 -2
- package/lib/debug/relationships.js +4 -2
- package/lib/debug/store.d.ts +261 -0
- package/lib/debug/store.js +243 -185
- package/lib/debug/tinybase.js +247 -189
- package/lib/metrics.d.ts +1 -1
- package/lib/store.d.ts +261 -0
- 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/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 +18 -17
- 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) =>
|
|
@@ -254,7 +256,7 @@ const getListenerFunctions = (getThing) => {
|
|
|
254
256
|
const allListeners = mapNew();
|
|
255
257
|
const addListener = (listener, deepSet, idOrNulls = []) => {
|
|
256
258
|
thing ??= getThing();
|
|
257
|
-
const id = listenerPool
|
|
259
|
+
const id = arrayPop(listenerPool) ?? '' + nextId++;
|
|
258
260
|
mapSet(allListeners, id, [listener, deepSet, idOrNulls]);
|
|
259
261
|
addDeepSet(deepSet, id, idOrNulls);
|
|
260
262
|
return id;
|
|
@@ -275,7 +277,7 @@ const getListenerFunctions = (getThing) => {
|
|
|
275
277
|
forDeepSet(collDel)(deepSet, id, ...idOrNulls);
|
|
276
278
|
mapSet(allListeners, id);
|
|
277
279
|
if (arrayLength(listenerPool) < 1e3) {
|
|
278
|
-
listenerPool
|
|
280
|
+
arrayPush(listenerPool, id);
|
|
279
281
|
}
|
|
280
282
|
return idOrNulls;
|
|
281
283
|
},
|
|
@@ -361,7 +363,7 @@ const createCheckpoints = getCreateFunction((store) => {
|
|
|
361
363
|
(_store, tableId, rowId, cellId, newCell, oldCell) => {
|
|
362
364
|
if (listening) {
|
|
363
365
|
ifNotUndefined(currentId, () => {
|
|
364
|
-
backwardIds
|
|
366
|
+
arrayPush(backwardIds, currentId);
|
|
365
367
|
trimBackwardsIds();
|
|
366
368
|
clearCheckpointIds(forwardIds);
|
|
367
369
|
currentId = void 0;
|
|
@@ -380,7 +382,7 @@ const createCheckpoints = getCreateFunction((store) => {
|
|
|
380
382
|
if (collIsEmpty(mapSet(row, cellId))) {
|
|
381
383
|
if (collIsEmpty(mapSet(table, rowId))) {
|
|
382
384
|
if (collIsEmpty(mapSet(delta, tableId))) {
|
|
383
|
-
currentId = backwardIds
|
|
385
|
+
currentId = arrayPop(backwardIds);
|
|
384
386
|
checkpointsChanged = 1;
|
|
385
387
|
}
|
|
386
388
|
}
|
|
@@ -404,13 +406,13 @@ const createCheckpoints = getCreateFunction((store) => {
|
|
|
404
406
|
if (!arrayIsEmpty(backwardIds)) {
|
|
405
407
|
forwardIds.unshift(addCheckpointImpl());
|
|
406
408
|
updateStore(0, currentId);
|
|
407
|
-
currentId = backwardIds
|
|
409
|
+
currentId = arrayPop(backwardIds);
|
|
408
410
|
checkpointsChanged = 1;
|
|
409
411
|
}
|
|
410
412
|
};
|
|
411
413
|
const goForwardImpl = () => {
|
|
412
414
|
if (!arrayIsEmpty(forwardIds)) {
|
|
413
|
-
backwardIds
|
|
415
|
+
arrayPush(backwardIds, currentId);
|
|
414
416
|
currentId = forwardIds.shift();
|
|
415
417
|
updateStore(1, currentId);
|
|
416
418
|
checkpointsChanged = 1;
|
|
@@ -1212,8 +1214,9 @@ const getCellType = (cell) => {
|
|
|
1212
1214
|
? type
|
|
1213
1215
|
: void 0;
|
|
1214
1216
|
};
|
|
1215
|
-
const validate = (obj, validateChild) => {
|
|
1216
|
-
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?.();
|
|
1217
1220
|
return false;
|
|
1218
1221
|
}
|
|
1219
1222
|
objForEach(obj, (child, id) => {
|
|
@@ -1233,8 +1236,9 @@ const createStore = () => {
|
|
|
1233
1236
|
const changedRowIds = mapNew();
|
|
1234
1237
|
const changedCellIds = mapNew();
|
|
1235
1238
|
const changedCells = mapNew();
|
|
1239
|
+
const invalidCells = mapNew();
|
|
1236
1240
|
const schemaMap = mapNew();
|
|
1237
|
-
const
|
|
1241
|
+
const schemaRowCache = mapNew();
|
|
1238
1242
|
const tablesMap = mapNew();
|
|
1239
1243
|
const tablesListeners = mapNewPair(setNew);
|
|
1240
1244
|
const tableIdsListeners = mapNewPair(setNew);
|
|
@@ -1243,6 +1247,7 @@ const createStore = () => {
|
|
|
1243
1247
|
const rowListeners = mapNewPair();
|
|
1244
1248
|
const cellIdsListeners = mapNewPair();
|
|
1245
1249
|
const cellListeners = mapNewPair();
|
|
1250
|
+
const invalidCellListeners = mapNewPair();
|
|
1246
1251
|
const [addListener, callListeners, delListenerImpl, callListenerImpl] =
|
|
1247
1252
|
getListenerFunctions(() => store);
|
|
1248
1253
|
const validateSchema = (schema) =>
|
|
@@ -1263,40 +1268,57 @@ const createStore = () => {
|
|
|
1263
1268
|
return true;
|
|
1264
1269
|
}),
|
|
1265
1270
|
);
|
|
1266
|
-
const validateTables = (tables) =>
|
|
1271
|
+
const validateTables = (tables) =>
|
|
1272
|
+
validate(tables, validateTable, cellInvalid);
|
|
1267
1273
|
const validateTable = (table, tableId) =>
|
|
1268
|
-
(!hasSchema || collHas(schemaMap, tableId)) &&
|
|
1269
|
-
validate(table, (row) => validateRow(tableId, row));
|
|
1270
|
-
const validateRow = (tableId, row, skipDefaults) =>
|
|
1274
|
+
(!hasSchema || collHas(schemaMap, tableId) || cellInvalid(tableId)) &&
|
|
1271
1275
|
validate(
|
|
1272
|
-
|
|
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),
|
|
1273
1283
|
(cell, cellId) =>
|
|
1274
1284
|
ifNotUndefined(
|
|
1275
|
-
getValidatedCell(tableId, cellId, cell),
|
|
1285
|
+
getValidatedCell(tableId, rowId, cellId, cell),
|
|
1276
1286
|
(validCell) => {
|
|
1277
1287
|
row[cellId] = validCell;
|
|
1278
1288
|
return true;
|
|
1279
1289
|
},
|
|
1280
1290
|
() => false,
|
|
1281
1291
|
),
|
|
1292
|
+
() => cellInvalid(tableId, rowId),
|
|
1282
1293
|
);
|
|
1283
|
-
const getValidatedCell = (tableId, cellId, cell) =>
|
|
1294
|
+
const getValidatedCell = (tableId, rowId, cellId, cell) =>
|
|
1284
1295
|
hasSchema
|
|
1285
1296
|
? ifNotUndefined(
|
|
1286
1297
|
mapGet(mapGet(schemaMap, tableId), cellId),
|
|
1287
1298
|
(cellSchema) =>
|
|
1288
|
-
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),
|
|
1289
1303
|
)
|
|
1290
1304
|
: isUndefined(getCellType(cell))
|
|
1291
|
-
?
|
|
1305
|
+
? cellInvalid(tableId, rowId, cellId, cell)
|
|
1292
1306
|
: cell;
|
|
1293
|
-
const addDefaultsToRow = (row, tableId) => {
|
|
1294
|
-
ifNotUndefined(
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
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
|
+
},
|
|
1300
1322
|
);
|
|
1301
1323
|
return row;
|
|
1302
1324
|
};
|
|
@@ -1305,7 +1327,8 @@ const createStore = () => {
|
|
|
1305
1327
|
schemaMap,
|
|
1306
1328
|
schema,
|
|
1307
1329
|
(_schema, tableId, tableSchema) => {
|
|
1308
|
-
const
|
|
1330
|
+
const rowDefaulted = mapNew();
|
|
1331
|
+
const rowNonDefaulted = setNew();
|
|
1309
1332
|
transformMap(
|
|
1310
1333
|
mapEnsure(schemaMap, tableId, mapNew()),
|
|
1311
1334
|
tableSchema,
|
|
@@ -1313,15 +1336,16 @@ const createStore = () => {
|
|
|
1313
1336
|
mapSet(tableSchemaMap, cellId, cellSchema);
|
|
1314
1337
|
ifNotUndefined(
|
|
1315
1338
|
cellSchema[DEFAULT],
|
|
1316
|
-
(def) => (
|
|
1339
|
+
(def) => mapSet(rowDefaulted, cellId, def),
|
|
1340
|
+
() => setAdd(rowNonDefaulted, cellId),
|
|
1317
1341
|
);
|
|
1318
1342
|
},
|
|
1319
1343
|
);
|
|
1320
|
-
mapSet(
|
|
1344
|
+
mapSet(schemaRowCache, tableId, [rowDefaulted, rowNonDefaulted]);
|
|
1321
1345
|
},
|
|
1322
1346
|
(_schema, tableId) => {
|
|
1323
1347
|
mapSet(schemaMap, tableId);
|
|
1324
|
-
mapSet(
|
|
1348
|
+
mapSet(schemaRowCache, tableId);
|
|
1325
1349
|
},
|
|
1326
1350
|
);
|
|
1327
1351
|
const setValidTables = (tables) =>
|
|
@@ -1361,10 +1385,6 @@ const createStore = () => {
|
|
|
1361
1385
|
mapSet(rowMap, cellId, newCell);
|
|
1362
1386
|
}
|
|
1363
1387
|
};
|
|
1364
|
-
const setValidRowTransaction = (tableId, rowId, row) =>
|
|
1365
|
-
transaction(() =>
|
|
1366
|
-
setValidRow(tableId, getOrCreateTable(tableId), rowId, row),
|
|
1367
|
-
);
|
|
1368
1388
|
const setCellIntoDefaultRow = (tableId, tableMap, rowId, cellId, validCell) =>
|
|
1369
1389
|
ifNotUndefined(
|
|
1370
1390
|
mapGet(tableMap, rowId),
|
|
@@ -1374,7 +1394,7 @@ const createStore = () => {
|
|
|
1374
1394
|
tableId,
|
|
1375
1395
|
tableMap,
|
|
1376
1396
|
rowId,
|
|
1377
|
-
addDefaultsToRow({[cellId]: validCell}, tableId),
|
|
1397
|
+
addDefaultsToRow({[cellId]: validCell}, tableId, rowId),
|
|
1378
1398
|
),
|
|
1379
1399
|
);
|
|
1380
1400
|
const getNewRowId = (tableMap) => {
|
|
@@ -1390,7 +1410,7 @@ const createStore = () => {
|
|
|
1390
1410
|
const delValidRow = (tableId, tableMap, rowId) =>
|
|
1391
1411
|
setValidRow(tableId, tableMap, rowId, {}, true);
|
|
1392
1412
|
const delValidCell = (tableId, table, rowId, row, cellId, forceDel) => {
|
|
1393
|
-
const defaultCell = mapGet(
|
|
1413
|
+
const defaultCell = mapGet(mapGet(schemaRowCache, tableId)?.[0], cellId);
|
|
1394
1414
|
if (!isUndefined(defaultCell) && !forceDel) {
|
|
1395
1415
|
return setValidCell(tableId, rowId, row, cellId, defaultCell);
|
|
1396
1416
|
}
|
|
@@ -1424,6 +1444,17 @@ const createStore = () => {
|
|
|
1424
1444
|
cellId,
|
|
1425
1445
|
oldCell,
|
|
1426
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
|
+
};
|
|
1427
1458
|
const getCellChange = (tableId, rowId, cellId) => {
|
|
1428
1459
|
const changedRow = mapGet(mapGet(changedCells, tableId), rowId);
|
|
1429
1460
|
const newCell = getCell(tableId, rowId, cellId);
|
|
@@ -1431,80 +1462,103 @@ const createStore = () => {
|
|
|
1431
1462
|
? [true, mapGet(changedRow, cellId), newCell]
|
|
1432
1463
|
: [false, newCell, newCell];
|
|
1433
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;
|
|
1434
1483
|
const callListenersForChanges = (mutator) => {
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
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]);
|
|
1460
1518
|
}
|
|
1461
|
-
}),
|
|
1462
|
-
);
|
|
1463
|
-
collForEach(changes[1], (changedIds, tableId) => {
|
|
1464
|
-
if (!collIsEmpty(changedIds)) {
|
|
1465
|
-
callListeners(rowIdsListeners[mutator], [tableId]);
|
|
1466
1519
|
}
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
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);
|
|
1489
1549
|
}
|
|
1490
1550
|
});
|
|
1491
|
-
if (
|
|
1492
|
-
callListeners(
|
|
1493
|
-
rowListeners[mutator],
|
|
1494
|
-
[tableId, rowId],
|
|
1495
|
-
getCellChange,
|
|
1496
|
-
);
|
|
1551
|
+
if (tablesChanged) {
|
|
1552
|
+
callListeners(tablesListeners[mutator], [], getCellChange);
|
|
1497
1553
|
}
|
|
1498
|
-
});
|
|
1499
|
-
if (tableChanged) {
|
|
1500
|
-
callListeners(tableListeners[mutator], [tableId], getCellChange);
|
|
1501
1554
|
}
|
|
1502
|
-
});
|
|
1503
|
-
if (tablesChanged) {
|
|
1504
|
-
callListeners(tablesListeners[mutator], [], getCellChange);
|
|
1505
1555
|
}
|
|
1506
1556
|
}
|
|
1507
1557
|
};
|
|
1558
|
+
const fluentTransaction = (actions) => {
|
|
1559
|
+
transaction(actions);
|
|
1560
|
+
return store;
|
|
1561
|
+
};
|
|
1508
1562
|
const getTables = () =>
|
|
1509
1563
|
mapToObj(tablesMap, (tableMap) => mapToObj(tableMap, mapToObj));
|
|
1510
1564
|
const getTableIds = () => mapKeys(tablesMap);
|
|
@@ -1523,52 +1577,52 @@ const createStore = () => {
|
|
|
1523
1577
|
collHas(mapGet(mapGet(tablesMap, tableId), rowId), cellId);
|
|
1524
1578
|
const getJson = () => jsonString(tablesMap);
|
|
1525
1579
|
const getSchemaJson = () => jsonString(schemaMap);
|
|
1526
|
-
const setTables = (tables) =>
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
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)) {
|
|
1555
1610
|
const table = getOrCreateTable(tableId);
|
|
1556
1611
|
objForEach(partialRow, (cell, cellId) =>
|
|
1557
1612
|
setCellIntoDefaultRow(tableId, table, rowId, cellId, cell),
|
|
1558
1613
|
);
|
|
1559
|
-
}
|
|
1560
|
-
}
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
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) =>
|
|
1572
1626
|
setCellIntoDefaultRow(
|
|
1573
1627
|
tableId,
|
|
1574
1628
|
getOrCreateTable(tableId),
|
|
@@ -1576,77 +1630,74 @@ const createStore = () => {
|
|
|
1576
1630
|
cellId,
|
|
1577
1631
|
validCell,
|
|
1578
1632
|
),
|
|
1579
|
-
|
|
1633
|
+
),
|
|
1580
1634
|
);
|
|
1581
|
-
return store;
|
|
1582
|
-
};
|
|
1583
1635
|
const setJson = (json) => {
|
|
1584
1636
|
try {
|
|
1585
1637
|
json === EMPTY_OBJECT ? delTables() : setTables(jsonParse(json));
|
|
1586
1638
|
} catch {}
|
|
1587
1639
|
return store;
|
|
1588
1640
|
};
|
|
1589
|
-
const setSchema = (schema) =>
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
return store;
|
|
1599
|
-
};
|
|
1600
|
-
const delTables = () => {
|
|
1601
|
-
transaction(() => setValidTables({}));
|
|
1602
|
-
return store;
|
|
1603
|
-
};
|
|
1604
|
-
const delTable = (tableId) => {
|
|
1605
|
-
if (collHas(tablesMap, tableId)) {
|
|
1606
|
-
transaction(() => delValidTable(tableId));
|
|
1607
|
-
}
|
|
1608
|
-
return store;
|
|
1609
|
-
};
|
|
1610
|
-
const delRow = (tableId, rowId) => {
|
|
1611
|
-
ifNotUndefined(mapGet(tablesMap, tableId), (tableMap) => {
|
|
1612
|
-
if (collHas(tableMap, rowId)) {
|
|
1613
|
-
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
|
+
}
|
|
1614
1650
|
}
|
|
1615
1651
|
});
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
ifNotUndefined(mapGet(tableMap, rowId), (rowMap) => {
|
|
1621
|
-
if (collHas(rowMap, cellId)) {
|
|
1622
|
-
transaction(() =>
|
|
1623
|
-
delValidCell(tableId, tableMap, rowId, rowMap, cellId, forceDel),
|
|
1624
|
-
);
|
|
1625
|
-
}
|
|
1626
|
-
}),
|
|
1652
|
+
const delTables = () => fluentTransaction(() => setValidTables({}));
|
|
1653
|
+
const delTable = (tableId) =>
|
|
1654
|
+
fluentTransaction(() =>
|
|
1655
|
+
collHas(tablesMap, tableId) ? delValidTable(tableId) : 0,
|
|
1627
1656
|
);
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
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
|
+
});
|
|
1635
1678
|
const transaction = (actions) => {
|
|
1636
1679
|
if (transactions == -1) {
|
|
1637
1680
|
return;
|
|
1638
1681
|
}
|
|
1639
1682
|
transactions++;
|
|
1640
|
-
const result = actions();
|
|
1683
|
+
const result = actions?.();
|
|
1641
1684
|
transactions--;
|
|
1642
1685
|
if (transactions == 0) {
|
|
1643
1686
|
transactions = 1;
|
|
1687
|
+
callInvalidCellListeners(1);
|
|
1644
1688
|
callListenersForChanges(1);
|
|
1645
1689
|
transactions = -1;
|
|
1690
|
+
callInvalidCellListeners(0);
|
|
1646
1691
|
callListenersForChanges(0);
|
|
1647
1692
|
transactions = 0;
|
|
1648
1693
|
arrayForEach(
|
|
1649
|
-
[
|
|
1694
|
+
[
|
|
1695
|
+
changedCells,
|
|
1696
|
+
invalidCells,
|
|
1697
|
+
changedTableIds,
|
|
1698
|
+
changedRowIds,
|
|
1699
|
+
changedCellIds,
|
|
1700
|
+
],
|
|
1650
1701
|
collClear,
|
|
1651
1702
|
);
|
|
1652
1703
|
}
|
|
@@ -1686,6 +1737,12 @@ const createStore = () => {
|
|
|
1686
1737
|
rowId,
|
|
1687
1738
|
cellId,
|
|
1688
1739
|
]);
|
|
1740
|
+
const addInvalidCellListener = (tableId, rowId, cellId, listener, mutator) =>
|
|
1741
|
+
addListener(listener, invalidCellListeners[mutator ? 1 : 0], [
|
|
1742
|
+
tableId,
|
|
1743
|
+
rowId,
|
|
1744
|
+
cellId,
|
|
1745
|
+
]);
|
|
1689
1746
|
const callListener = (listenerId) => {
|
|
1690
1747
|
callListenerImpl(listenerId, [getTableIds, getRowIds, getCellIds], (ids) =>
|
|
1691
1748
|
isUndefined(ids[2]) ? [] : Array(2).fill(getCell(...ids)),
|
|
@@ -1743,6 +1800,7 @@ const createStore = () => {
|
|
|
1743
1800
|
addRowListener,
|
|
1744
1801
|
addCellIdsListener,
|
|
1745
1802
|
addCellListener,
|
|
1803
|
+
addInvalidCellListener,
|
|
1746
1804
|
callListener,
|
|
1747
1805
|
delListener,
|
|
1748
1806
|
getListenerStats,
|
package/lib/metrics.d.ts
CHANGED
|
@@ -37,7 +37,7 @@ export type Metric = number;
|
|
|
37
37
|
export type MetricCallback = (metricId: Id, metric?: Metric) => void;
|
|
38
38
|
|
|
39
39
|
/**
|
|
40
|
-
* The Aggregate type describes a custom function that takes an array
|
|
40
|
+
* The Aggregate type describes a custom function that takes an array of numbers
|
|
41
41
|
* and returns an aggregate that is used as a Metric.
|
|
42
42
|
*
|
|
43
43
|
* There are a number of common predefined aggregators, such as for counting,
|