tinybase 1.0.2 → 1.1.0-beta.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.
Files changed (60) hide show
  1. package/lib/checkpoints.d.ts +945 -0
  2. package/lib/checkpoints.js +1 -0
  3. package/lib/checkpoints.js.gz +0 -0
  4. package/lib/common.d.ts +115 -0
  5. package/lib/common.js +1 -0
  6. package/lib/common.js.gz +0 -0
  7. package/lib/debug/checkpoints.d.ts +66 -0
  8. package/lib/debug/checkpoints.js +332 -0
  9. package/lib/debug/common.js +3 -0
  10. package/lib/debug/indexes.d.ts +167 -6
  11. package/lib/debug/indexes.js +431 -0
  12. package/lib/debug/metrics.d.ts +72 -0
  13. package/lib/debug/metrics.js +401 -0
  14. package/lib/debug/persisters.js +191 -0
  15. package/lib/debug/relationships.d.ts +86 -1
  16. package/lib/debug/relationships.js +434 -0
  17. package/lib/debug/store.d.ts +187 -5
  18. package/lib/debug/store.js +783 -0
  19. package/lib/debug/tinybase.js +144 -39
  20. package/lib/indexes.d.ts +939 -0
  21. package/lib/indexes.js +1 -0
  22. package/lib/indexes.js.gz +0 -0
  23. package/lib/metrics.d.ts +829 -0
  24. package/lib/metrics.js +1 -0
  25. package/lib/metrics.js.gz +0 -0
  26. package/lib/persisters.d.ts +711 -0
  27. package/lib/persisters.js +1 -0
  28. package/lib/persisters.js.gz +0 -0
  29. package/lib/relationships.d.ts +1201 -0
  30. package/lib/relationships.js +1 -0
  31. package/lib/relationships.js.gz +0 -0
  32. package/lib/store.d.ts +2688 -0
  33. package/lib/store.js +1 -0
  34. package/lib/store.js.gz +0 -0
  35. package/lib/tinybase.d.ts +13 -0
  36. package/lib/tinybase.js +1 -0
  37. package/lib/tinybase.js.gz +0 -0
  38. package/lib/ui-react.d.ts +7185 -0
  39. package/lib/ui-react.js +1 -0
  40. package/lib/ui-react.js.gz +0 -0
  41. package/lib/umd/checkpoints.js +1 -0
  42. package/lib/umd/checkpoints.js.gz +0 -0
  43. package/lib/umd/common.js +1 -0
  44. package/lib/umd/common.js.gz +0 -0
  45. package/lib/umd/indexes.js +1 -0
  46. package/lib/umd/indexes.js.gz +0 -0
  47. package/lib/umd/metrics.js +1 -0
  48. package/lib/umd/metrics.js.gz +0 -0
  49. package/lib/umd/persisters.js +1 -0
  50. package/lib/umd/persisters.js.gz +0 -0
  51. package/lib/umd/relationships.js +1 -0
  52. package/lib/umd/relationships.js.gz +0 -0
  53. package/lib/umd/store.js +1 -0
  54. package/lib/umd/store.js.gz +0 -0
  55. package/lib/umd/tinybase.js +1 -0
  56. package/lib/umd/tinybase.js.gz +0 -0
  57. package/lib/umd/ui-react.js +1 -0
  58. package/lib/umd/ui-react.js.gz +0 -0
  59. package/package.json +14 -14
  60. package/readme.md +2 -2
@@ -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.pop() ?? '' + nextId++;
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.push(id);
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.push(currentId);
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.pop();
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.pop();
409
+ currentId = arrayPop(backwardIds);
404
410
  checkpointsChanged = 1;
405
411
  }
406
412
  };
407
413
  const goForwardImpl = () => {
408
414
  if (!arrayIsEmpty(forwardIds)) {
409
- backwardIds.push(currentId);
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,
@@ -1186,6 +1235,7 @@ const createStore = () => {
1186
1235
  const changedRowIds = mapNew();
1187
1236
  const changedCellIds = mapNew();
1188
1237
  const changedCells = mapNew();
1238
+ const invalidCells = mapNew();
1189
1239
  const schemaMap = mapNew();
1190
1240
  const schemaDefaultRows = mapNew();
1191
1241
  const tablesMap = mapNew();
@@ -1196,6 +1246,7 @@ const createStore = () => {
1196
1246
  const rowListeners = mapNewPair();
1197
1247
  const cellIdsListeners = mapNewPair();
1198
1248
  const cellListeners = mapNewPair();
1249
+ const invalidCellListeners = mapNewPair();
1199
1250
  const [addListener, callListeners, delListenerImpl, callListenerImpl] =
1200
1251
  getListenerFunctions(() => store);
1201
1252
  const validateSchema = (schema) =>
@@ -1219,13 +1270,13 @@ const createStore = () => {
1219
1270
  const validateTables = (tables) => validate(tables, validateTable);
1220
1271
  const validateTable = (table, tableId) =>
1221
1272
  (!hasSchema || collHas(schemaMap, tableId)) &&
1222
- validate(table, (row) => validateRow(tableId, row));
1223
- const validateRow = (tableId, row, skipDefaults) =>
1273
+ validate(table, (row, rowId) => validateRow(tableId, rowId, row));
1274
+ const validateRow = (tableId, rowId, row, skipDefaults) =>
1224
1275
  validate(
1225
1276
  skipDefaults ? row : addDefaultsToRow(row, tableId),
1226
1277
  (cell, cellId) =>
1227
1278
  ifNotUndefined(
1228
- getValidatedCell(tableId, cellId, cell),
1279
+ getValidatedCell(tableId, rowId, cellId, cell),
1229
1280
  (validCell) => {
1230
1281
  row[cellId] = validCell;
1231
1282
  return true;
@@ -1233,15 +1284,17 @@ const createStore = () => {
1233
1284
  () => false,
1234
1285
  ),
1235
1286
  );
1236
- const getValidatedCell = (tableId, cellId, cell) =>
1287
+ const getValidatedCell = (tableId, rowId, cellId, cell) =>
1237
1288
  hasSchema
1238
1289
  ? ifNotUndefined(
1239
1290
  mapGet(mapGet(schemaMap, tableId), cellId),
1240
1291
  (cellSchema) =>
1241
- getCellType(cell) != cellSchema[TYPE] ? cellSchema[DEFAULT] : cell,
1292
+ getCellType(cell) != cellSchema[TYPE]
1293
+ ? cellInvalid(tableId, rowId, cellId, cell, cellSchema[DEFAULT])
1294
+ : cell,
1242
1295
  )
1243
1296
  : isUndefined(getCellType(cell))
1244
- ? void 0
1297
+ ? cellInvalid(tableId, rowId, cellId, cell)
1245
1298
  : cell;
1246
1299
  const addDefaultsToRow = (row, tableId) => {
1247
1300
  ifNotUndefined(mapGet(schemaDefaultRows, tableId), (defaultRow) =>
@@ -1377,6 +1430,17 @@ const createStore = () => {
1377
1430
  cellId,
1378
1431
  oldCell,
1379
1432
  );
1433
+ const cellInvalid = (tableId, rowId, cellId, invalidCell, defaultedCell) => {
1434
+ arrayPush(
1435
+ mapEnsure(
1436
+ mapEnsure(mapEnsure(invalidCells, tableId, mapNew()), rowId, mapNew()),
1437
+ cellId,
1438
+ [],
1439
+ ),
1440
+ invalidCell,
1441
+ );
1442
+ return defaultedCell;
1443
+ };
1380
1444
  const getCellChange = (tableId, rowId, cellId) => {
1381
1445
  const changedRow = mapGet(mapGet(changedCells, tableId), rowId);
1382
1446
  const newCell = getCell(tableId, rowId, cellId);
@@ -1384,6 +1448,25 @@ const createStore = () => {
1384
1448
  ? [true, mapGet(changedRow, cellId), newCell]
1385
1449
  : [false, newCell, newCell];
1386
1450
  };
1451
+ const callInvalidCellListeners = (mutator) => {
1452
+ if (!collIsEmpty(invalidCellListeners[mutator])) {
1453
+ collForEach(
1454
+ mutator
1455
+ ? mapClone(invalidCells, (table) => mapClone(table, mapClone))
1456
+ : invalidCells,
1457
+ (rows, tableId) =>
1458
+ collForEach(rows, (cells, rowId) =>
1459
+ collForEach(cells, (invalidCell, cellId) =>
1460
+ callListeners(
1461
+ invalidCellListeners[mutator],
1462
+ [tableId, rowId, cellId],
1463
+ invalidCell,
1464
+ ),
1465
+ ),
1466
+ ),
1467
+ );
1468
+ }
1469
+ };
1387
1470
  const callListenersForChanges = (mutator) => {
1388
1471
  const emptyIdListeners =
1389
1472
  collIsEmpty(cellIdsListeners[mutator]) &&
@@ -1469,6 +1552,7 @@ const createStore = () => {
1469
1552
  mapKeys(mapGet(mapGet(tablesMap, tableId), rowId));
1470
1553
  const getCell = (tableId, rowId, cellId) =>
1471
1554
  mapGet(mapGet(mapGet(tablesMap, tableId), rowId), cellId);
1555
+ const hasTables = () => !collIsEmpty(tablesMap);
1472
1556
  const hasTable = (tableId) => collHas(tablesMap, tableId);
1473
1557
  const hasRow = (tableId, rowId) => collHas(mapGet(tablesMap, tableId), rowId);
1474
1558
  const hasCell = (tableId, rowId, cellId) =>
@@ -1476,46 +1560,50 @@ const createStore = () => {
1476
1560
  const getJson = () => jsonString(tablesMap);
1477
1561
  const getSchemaJson = () => jsonString(schemaMap);
1478
1562
  const setTables = (tables) => {
1479
- if (validateTables(tables)) {
1480
- transaction(() => setValidTables(tables));
1481
- }
1563
+ validateTables(tables)
1564
+ ? transaction(() => setValidTables(tables))
1565
+ : transaction();
1482
1566
  return store;
1483
1567
  };
1484
1568
  const setTable = (tableId, table) => {
1485
- if (validateTable(table, tableId)) {
1486
- transaction(() => setValidTable(tableId, table));
1487
- }
1569
+ validateTable(table, tableId)
1570
+ ? transaction(() => setValidTable(tableId, table))
1571
+ : transaction();
1488
1572
  return store;
1489
1573
  };
1490
1574
  const setRow = (tableId, rowId, row) => {
1491
- if (validateRow(tableId, row)) {
1492
- setValidRowTransaction(tableId, rowId, row);
1493
- }
1575
+ validateRow(tableId, rowId, row)
1576
+ ? setValidRowTransaction(tableId, rowId, row)
1577
+ : transaction();
1494
1578
  return store;
1495
1579
  };
1496
1580
  const addRow = (tableId, row) => {
1497
1581
  let rowId = void 0;
1498
- if (validateRow(tableId, row)) {
1499
- rowId = getNewRowId(mapGet(tablesMap, tableId));
1500
- setValidRowTransaction(tableId, rowId, row);
1501
- }
1582
+ validateRow(tableId, rowId, row)
1583
+ ? setValidRowTransaction(
1584
+ tableId,
1585
+ (rowId = getNewRowId(mapGet(tablesMap, tableId))),
1586
+ row,
1587
+ )
1588
+ : transaction();
1502
1589
  return rowId;
1503
1590
  };
1504
1591
  const setPartialRow = (tableId, rowId, partialRow) => {
1505
- if (validateRow(tableId, partialRow, 1)) {
1506
- transaction(() => {
1507
- const table = getOrCreateTable(tableId);
1508
- objForEach(partialRow, (cell, cellId) =>
1509
- setCellIntoDefaultRow(tableId, table, rowId, cellId, cell),
1510
- );
1511
- });
1512
- }
1592
+ validateRow(tableId, rowId, partialRow, 1)
1593
+ ? transaction(() => {
1594
+ const table = getOrCreateTable(tableId);
1595
+ objForEach(partialRow, (cell, cellId) =>
1596
+ setCellIntoDefaultRow(tableId, table, rowId, cellId, cell),
1597
+ );
1598
+ })
1599
+ : transaction();
1513
1600
  return store;
1514
1601
  };
1515
1602
  const setCell = (tableId, rowId, cellId, cell) => {
1516
1603
  ifNotUndefined(
1517
1604
  getValidatedCell(
1518
1605
  tableId,
1606
+ rowId,
1519
1607
  cellId,
1520
1608
  isFunction(cell) ? cell(getCell(tableId, rowId, cellId)) : cell,
1521
1609
  ),
@@ -1529,6 +1617,7 @@ const createStore = () => {
1529
1617
  validCell,
1530
1618
  ),
1531
1619
  ),
1620
+ transaction,
1532
1621
  );
1533
1622
  return store;
1534
1623
  };
@@ -1589,16 +1678,24 @@ const createStore = () => {
1589
1678
  return;
1590
1679
  }
1591
1680
  transactions++;
1592
- const result = actions();
1681
+ const result = actions?.();
1593
1682
  transactions--;
1594
1683
  if (transactions == 0) {
1595
1684
  transactions = 1;
1685
+ callInvalidCellListeners(1);
1596
1686
  callListenersForChanges(1);
1597
1687
  transactions = -1;
1688
+ callInvalidCellListeners(0);
1598
1689
  callListenersForChanges(0);
1599
1690
  transactions = 0;
1600
1691
  arrayForEach(
1601
- [changedCells, changedTableIds, changedRowIds, changedCellIds],
1692
+ [
1693
+ changedCells,
1694
+ invalidCells,
1695
+ changedTableIds,
1696
+ changedRowIds,
1697
+ changedCellIds,
1698
+ ],
1602
1699
  collClear,
1603
1700
  );
1604
1701
  }
@@ -1638,6 +1735,12 @@ const createStore = () => {
1638
1735
  rowId,
1639
1736
  cellId,
1640
1737
  ]);
1738
+ const addInvalidCellListener = (tableId, rowId, cellId, listener, mutator) =>
1739
+ addListener(listener, invalidCellListeners[mutator ? 1 : 0], [
1740
+ tableId,
1741
+ rowId,
1742
+ cellId,
1743
+ ]);
1641
1744
  const callListener = (listenerId) => {
1642
1745
  callListenerImpl(listenerId, [getTableIds, getRowIds, getCellIds], (ids) =>
1643
1746
  isUndefined(ids[2]) ? [] : Array(2).fill(getCell(...ids)),
@@ -1665,6 +1768,7 @@ const createStore = () => {
1665
1768
  getRow,
1666
1769
  getCellIds,
1667
1770
  getCell,
1771
+ hasTables,
1668
1772
  hasTable,
1669
1773
  hasRow,
1670
1774
  hasCell,
@@ -1694,6 +1798,7 @@ const createStore = () => {
1694
1798
  addRowListener,
1695
1799
  addCellIdsListener,
1696
1800
  addCellListener,
1801
+ addInvalidCellListener,
1697
1802
  callListener,
1698
1803
  delListener,
1699
1804
  getListenerStats,