tinybase 3.2.0-beta.0 → 3.3.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 (139) hide show
  1. package/bin/cli.js +1 -1
  2. package/lib/checkpoints.js +1 -1
  3. package/lib/checkpoints.js.gz +0 -0
  4. package/lib/cjs/checkpoints.cjs +1 -1
  5. package/lib/cjs/checkpoints.cjs.gz +0 -0
  6. package/lib/cjs/indexes.cjs +1 -1
  7. package/lib/cjs/indexes.cjs.gz +0 -0
  8. package/lib/cjs/metrics.cjs +1 -1
  9. package/lib/cjs/metrics.cjs.gz +0 -0
  10. package/lib/cjs/persisters.cjs +1 -1
  11. package/lib/cjs/persisters.cjs.gz +0 -0
  12. package/lib/cjs/queries.cjs +1 -1
  13. package/lib/cjs/queries.cjs.gz +0 -0
  14. package/lib/cjs/relationships.cjs +1 -1
  15. package/lib/cjs/relationships.cjs.gz +0 -0
  16. package/lib/cjs/store.cjs +1 -1
  17. package/lib/cjs/store.cjs.gz +0 -0
  18. package/lib/cjs/tinybase.cjs +1 -1
  19. package/lib/cjs/tinybase.cjs.gz +0 -0
  20. package/lib/cjs/tools.cjs +1 -1
  21. package/lib/cjs/tools.cjs.gz +0 -0
  22. package/lib/cjs/ui-react.cjs +1 -1
  23. package/lib/cjs/ui-react.cjs.gz +0 -0
  24. package/lib/cjs-es6/checkpoints.cjs +1 -1
  25. package/lib/cjs-es6/checkpoints.cjs.gz +0 -0
  26. package/lib/cjs-es6/indexes.cjs +1 -1
  27. package/lib/cjs-es6/indexes.cjs.gz +0 -0
  28. package/lib/cjs-es6/metrics.cjs +1 -1
  29. package/lib/cjs-es6/metrics.cjs.gz +0 -0
  30. package/lib/cjs-es6/persisters.cjs +1 -1
  31. package/lib/cjs-es6/persisters.cjs.gz +0 -0
  32. package/lib/cjs-es6/queries.cjs +1 -1
  33. package/lib/cjs-es6/queries.cjs.gz +0 -0
  34. package/lib/cjs-es6/relationships.cjs +1 -1
  35. package/lib/cjs-es6/relationships.cjs.gz +0 -0
  36. package/lib/cjs-es6/store.cjs +1 -1
  37. package/lib/cjs-es6/store.cjs.gz +0 -0
  38. package/lib/cjs-es6/tinybase.cjs +1 -1
  39. package/lib/cjs-es6/tinybase.cjs.gz +0 -0
  40. package/lib/cjs-es6/tools.cjs +1 -1
  41. package/lib/cjs-es6/tools.cjs.gz +0 -0
  42. package/lib/cjs-es6/ui-react.cjs +1 -1
  43. package/lib/cjs-es6/ui-react.cjs.gz +0 -0
  44. package/lib/debug/checkpoints.js +2 -2
  45. package/lib/debug/indexes.js +2 -2
  46. package/lib/debug/metrics.js +2 -2
  47. package/lib/debug/persisters.js +2 -2
  48. package/lib/debug/queries.js +1 -1
  49. package/lib/debug/relationships.js +2 -2
  50. package/lib/debug/store.js +89 -48
  51. package/lib/debug/tinybase.js +92 -51
  52. package/lib/debug/tools.js +106 -5
  53. package/lib/debug/ui-react.js +27 -2
  54. package/lib/es6/checkpoints.js +1 -1
  55. package/lib/es6/checkpoints.js.gz +0 -0
  56. package/lib/es6/indexes.js +1 -1
  57. package/lib/es6/indexes.js.gz +0 -0
  58. package/lib/es6/metrics.js +1 -1
  59. package/lib/es6/metrics.js.gz +0 -0
  60. package/lib/es6/persisters.js +1 -1
  61. package/lib/es6/persisters.js.gz +0 -0
  62. package/lib/es6/queries.js +1 -1
  63. package/lib/es6/queries.js.gz +0 -0
  64. package/lib/es6/relationships.js +1 -1
  65. package/lib/es6/relationships.js.gz +0 -0
  66. package/lib/es6/store.js +1 -1
  67. package/lib/es6/store.js.gz +0 -0
  68. package/lib/es6/tinybase.js +1 -1
  69. package/lib/es6/tinybase.js.gz +0 -0
  70. package/lib/es6/tools.js +1 -1
  71. package/lib/es6/tools.js.gz +0 -0
  72. package/lib/es6/ui-react.js +1 -1
  73. package/lib/es6/ui-react.js.gz +0 -0
  74. package/lib/indexes.js +1 -1
  75. package/lib/indexes.js.gz +0 -0
  76. package/lib/metrics.js +1 -1
  77. package/lib/metrics.js.gz +0 -0
  78. package/lib/persisters.js +1 -1
  79. package/lib/persisters.js.gz +0 -0
  80. package/lib/queries.js +1 -1
  81. package/lib/queries.js.gz +0 -0
  82. package/lib/relationships.js +1 -1
  83. package/lib/relationships.js.gz +0 -0
  84. package/lib/store.js +1 -1
  85. package/lib/store.js.gz +0 -0
  86. package/lib/tinybase.js +1 -1
  87. package/lib/tinybase.js.gz +0 -0
  88. package/lib/tools.js +1 -1
  89. package/lib/tools.js.gz +0 -0
  90. package/lib/types/store.d.ts +386 -30
  91. package/lib/types/tools.d.ts +2 -2
  92. package/lib/types/ui-react.d.ts +167 -0
  93. package/lib/types/with-schemas/store.d.ts +496 -37
  94. package/lib/types/with-schemas/tools.d.ts +2 -2
  95. package/lib/types/with-schemas/ui-react.d.ts +193 -5
  96. package/lib/ui-react.js +1 -1
  97. package/lib/ui-react.js.gz +0 -0
  98. package/lib/umd/checkpoints.js +1 -1
  99. package/lib/umd/checkpoints.js.gz +0 -0
  100. package/lib/umd/indexes.js +1 -1
  101. package/lib/umd/indexes.js.gz +0 -0
  102. package/lib/umd/metrics.js +1 -1
  103. package/lib/umd/metrics.js.gz +0 -0
  104. package/lib/umd/persisters.js +1 -1
  105. package/lib/umd/persisters.js.gz +0 -0
  106. package/lib/umd/queries.js +1 -1
  107. package/lib/umd/queries.js.gz +0 -0
  108. package/lib/umd/relationships.js +1 -1
  109. package/lib/umd/relationships.js.gz +0 -0
  110. package/lib/umd/store.js +1 -1
  111. package/lib/umd/store.js.gz +0 -0
  112. package/lib/umd/tinybase.js +1 -1
  113. package/lib/umd/tinybase.js.gz +0 -0
  114. package/lib/umd/tools.js +1 -1
  115. package/lib/umd/tools.js.gz +0 -0
  116. package/lib/umd/ui-react.js +1 -1
  117. package/lib/umd/ui-react.js.gz +0 -0
  118. package/lib/umd-es6/checkpoints.js +1 -1
  119. package/lib/umd-es6/checkpoints.js.gz +0 -0
  120. package/lib/umd-es6/indexes.js +1 -1
  121. package/lib/umd-es6/indexes.js.gz +0 -0
  122. package/lib/umd-es6/metrics.js +1 -1
  123. package/lib/umd-es6/metrics.js.gz +0 -0
  124. package/lib/umd-es6/persisters.js +1 -1
  125. package/lib/umd-es6/persisters.js.gz +0 -0
  126. package/lib/umd-es6/queries.js +1 -1
  127. package/lib/umd-es6/queries.js.gz +0 -0
  128. package/lib/umd-es6/relationships.js +1 -1
  129. package/lib/umd-es6/relationships.js.gz +0 -0
  130. package/lib/umd-es6/store.js +1 -1
  131. package/lib/umd-es6/store.js.gz +0 -0
  132. package/lib/umd-es6/tinybase.js +1 -1
  133. package/lib/umd-es6/tinybase.js.gz +0 -0
  134. package/lib/umd-es6/tools.js +1 -1
  135. package/lib/umd-es6/tools.js.gz +0 -0
  136. package/lib/umd-es6/ui-react.js +1 -1
  137. package/lib/umd-es6/ui-react.js.gz +0 -0
  138. package/package.json +52 -28
  139. package/readme.md +14 -14
@@ -319,6 +319,20 @@ export type TableCallback = (
319
319
  forEachRow: (rowCallback: RowCallback) => void,
320
320
  ) => void;
321
321
 
322
+ /**
323
+ * The TableCellCallback type describes a function that takes a Cell's Id and
324
+ * the count of times it appears across a whole Table.
325
+ *
326
+ * A TableCellCallback is provided when using the forEachTableCell method, so
327
+ * that you can do something based on every Cell used across a Table. See that
328
+ * method for specific examples.
329
+ *
330
+ * @param cellId The Id of the Cell that the callback can operate on.
331
+ * @param count The number of times this Cell is used across a whole Table.
332
+ * @category Callback
333
+ */
334
+ export type TableCellCallback = (cellId: Id, count: number) => void;
335
+
322
336
  /**
323
337
  * The RowCallback type describes a function that takes a Row's Id and a
324
338
  * callback to loop over each Cell within it.
@@ -498,10 +512,18 @@ export type TablesListener = (
498
512
  *
499
513
  * When called, a TableIdsListener is given a reference to the Store.
500
514
  *
515
+ * Since v3.3, the listener is also passed a GetIdChanges function that can be
516
+ * used to query which Ids changed during the transaction.
517
+ *
501
518
  * @param store A reference to the Store that changed.
519
+ * @param getIdChanges A function that returns information about the Id changes,
520
+ * since v3.3.
502
521
  * @category Listener
503
522
  */
504
- export type TableIdsListener = (store: Store) => void;
523
+ export type TableIdsListener = (
524
+ store: Store,
525
+ getIdChanges: GetIdChanges | undefined,
526
+ ) => void;
505
527
 
506
528
  /**
507
529
  * The TableListener type describes a function that is used to listen to changes
@@ -530,6 +552,29 @@ export type TableListener = (
530
552
  getCellChange: GetCellChange | undefined,
531
553
  ) => void;
532
554
 
555
+ /**
556
+ * The TableCellIdsListener type describes a function that is used to listen to
557
+ * changes to the Cell Ids that appear anywhere in a Table.
558
+ *
559
+ * A TableCellIdsListener is provided when using the addTableCellIdsListener
560
+ * method. See that method for specific examples.
561
+ *
562
+ * When called, a TableCellIdsListener is given a reference to the Store, the Id
563
+ * of the Table whose Cell Ids changed, and a GetIdChanges function that can be
564
+ * used to query which Ids changed during the transaction.
565
+ *
566
+ * @param store A reference to the Store that changed.
567
+ * @param tableId The Id of the Table that changed.
568
+ * @param getIdChanges A function that returns information about the Id changes.
569
+ * @category Listener
570
+ * @since v3.3
571
+ */
572
+ export type TableCellIdsListener = (
573
+ store: Store,
574
+ tableId: Id,
575
+ getIdChanges: GetIdChanges | undefined,
576
+ ) => void;
577
+
533
578
  /**
534
579
  * The RowIdsListener type describes a function that is used to listen to
535
580
  * changes to the Row Ids in a Table.
@@ -540,11 +585,20 @@ export type TableListener = (
540
585
  * When called, a RowIdsListener is given a reference to the Store, and the Id
541
586
  * of the Table whose Row Ids changed.
542
587
  *
588
+ * Since v3.3, the listener is also passed a GetIdChanges function that can be
589
+ * used to query which Ids changed during the transaction.
590
+ *
543
591
  * @param store A reference to the Store that changed.
544
592
  * @param tableId The Id of the Table that changed.
593
+ * @param getIdChanges A function that returns information about the Id changes,
594
+ * since v3.3.
545
595
  * @category Listener
546
596
  */
547
- export type RowIdsListener = (store: Store, tableId: Id) => void;
597
+ export type RowIdsListener = (
598
+ store: Store,
599
+ tableId: Id,
600
+ getIdChanges: GetIdChanges | undefined,
601
+ ) => void;
548
602
 
549
603
  /**
550
604
  * The SortedRowIdsListener type describes a function that is used to listen to
@@ -620,12 +674,22 @@ export type RowListener = (
620
674
  * When called, a CellIdsListener is given a reference to the Store, the Id of
621
675
  * the Table that changed, and the Id of the Row whose Cell Ids changed.
622
676
  *
677
+ * Since v3.3, the listener is also passed a GetIdChanges function that can be
678
+ * used to query which Ids changed during the transaction.
679
+ *
623
680
  * @param store A reference to the Store that changed.
624
681
  * @param tableId The Id of the Table that changed.
625
682
  * @param rowId The Id of the Row that changed.
683
+ * @param getIdChanges A function that returns information about the Id changes,
684
+ * since v3.3.
626
685
  * @category Listener
627
686
  */
628
- export type CellIdsListener = (store: Store, tableId: Id, rowId: Id) => void;
687
+ export type CellIdsListener = (
688
+ store: Store,
689
+ tableId: Id,
690
+ rowId: Id,
691
+ getIdChanges: GetIdChanges | undefined,
692
+ ) => void;
629
693
 
630
694
  /**
631
695
  * The CellListener type describes a function that is used to listen to changes
@@ -699,10 +763,18 @@ export type ValuesListener = (
699
763
  *
700
764
  * When called, a ValueIdsListener is given a reference to the Store.
701
765
  *
766
+ * Since v3.3, the listener is also passed a GetIdChanges function that can be
767
+ * used to query which Ids changed during the transaction.
768
+ *
702
769
  * @param store A reference to the Store that changed.
770
+ * @param getIdChanges A function that returns information about the Id changes,
771
+ * since v3.3.
703
772
  * @category Listener
704
773
  */
705
- export type ValueIdsListener = (store: Store) => void;
774
+ export type ValueIdsListener = (
775
+ store: Store,
776
+ getIdChanges: GetIdChanges | undefined,
777
+ ) => void;
706
778
 
707
779
  /**
708
780
  * The ValueListener type describes a function that is used to listen to changes
@@ -742,10 +814,10 @@ export type ValueListener = (
742
814
  * The InvalidCellListener type describes a function that is used to listen to
743
815
  * attempts to set invalid data to a Cell.
744
816
  *
745
- * A InvalidCellListener is provided when using the addInvalidCellListener
817
+ * An InvalidCellListener is provided when using the addInvalidCellListener
746
818
  * method. See that method for specific examples.
747
819
  *
748
- * When called, a InvalidCellListener is given a reference to the Store, the Id
820
+ * When called, an InvalidCellListener is given a reference to the Store, the Id
749
821
  * of the Table, the Id of the Row, and the Id of Cell that was being attempted
750
822
  * to be changed. It is also given the invalid value of the Cell, which could
751
823
  * have been of absolutely any type. Since there could have been multiple failed
@@ -772,11 +844,11 @@ export type InvalidCellListener = (
772
844
  * The InvalidValueListener type describes a function that is used to listen to
773
845
  * attempts to set invalid data to a Value.
774
846
  *
775
- * A InvalidValueListener is provided when using the addInvalidValueListener
847
+ * An InvalidValueListener is provided when using the addInvalidValueListener
776
848
  * method. See that method for specific examples.
777
849
  *
778
- * When called, a InvalidValueListener is given a reference to the Store and the
779
- * Id of Value that was being attempted to be changed. It is also given the
850
+ * When called, an InvalidValueListener is given a reference to the Store and
851
+ * the Id of Value that was being attempted to be changed. It is also given the
780
852
  * invalid value of the Value, which could have been of absolutely any type.
781
853
  * Since there could have been multiple failed attempts to set the Value within
782
854
  * a single transaction, this is an array containing each attempt,
@@ -794,6 +866,23 @@ export type InvalidValueListener = (
794
866
  invalidValues: any[],
795
867
  ) => void;
796
868
 
869
+ /**
870
+ * The GetIdChanges type describes a function that returns information about the
871
+ * changes to a set of Ids during a transaction.
872
+ *
873
+ * A GetIdChanges function is provided to every listener when called due Ids in
874
+ * the Store changing. It returns an object where each key is an Id that
875
+ * changed. The listener can then easily identify which Ids have been added
876
+ * (those with the value `1`), and which have been removed (those with the value
877
+ * `-1`).
878
+ *
879
+ * @returns An object keyed by Id with a numerical value. 1 means the Id was
880
+ * added, and 1 means it was removed.
881
+ * @category Listener
882
+ * @since v3.3
883
+ */
884
+ export type GetIdChanges = () => {[id: Id]: 1 | -1};
885
+
797
886
  /**
798
887
  * The GetCellChange type describes a function that returns information about
799
888
  * any Cell's changes during a transaction.
@@ -989,6 +1078,11 @@ export type StoreListenerStats = {
989
1078
  * The number of TableListener functions registered with the Store.
990
1079
  */
991
1080
  table?: number;
1081
+ /**
1082
+ * The number of TableCellIdsListener functions registered with the Store,
1083
+ * since v3.3.
1084
+ */
1085
+ tableCellIds?: number;
992
1086
  /**
993
1087
  * The number of RowIdsListener functions registered with the Store.
994
1088
  */
@@ -1129,6 +1223,7 @@ export type StoreListenerStats = {
1129
1223
  * |Tables|getTables|setTables|delTables|addTablesListener|
1130
1224
  * |Table Ids|getTableIds|-|-|addTableIdsListener|
1131
1225
  * |Table|getTable|setTable|delTable|addTableListener|
1226
+ * |Table Cell Ids|getTableCellIds|-|-|addTableCellIdsListener|
1132
1227
  * |Row Ids|getRowIds|-|-|addRowIdsListener|
1133
1228
  * |Row Ids (sorted)|getSortedRowIds|-|-|addSortedRowIdsListener|
1134
1229
  * |Row|getRow|setRow|delRow|addRowListener|
@@ -1221,16 +1316,16 @@ export type StoreListenerStats = {
1221
1316
  export interface Store {
1222
1317
  //
1223
1318
  /**
1224
- * The getTables method returns a Tables object containing the entire data of
1225
- * the Store.
1319
+ * The getTables method returns a Tables object containing the entire tabular
1320
+ * data of the Store.
1226
1321
  *
1227
1322
  * Note that this returns a copy of, rather than a reference to the underlying
1228
1323
  * data, so changes made to the returned object are not made to the Store
1229
1324
  * itself.
1230
1325
  *
1231
- * @returns A Tables object containing the entire data of the Store.
1326
+ * @returns A Tables object containing the tabular data of the Store.
1232
1327
  * @example
1233
- * This example retrieves the data in a Store.
1328
+ * This example retrieves the tabular data in a Store.
1234
1329
  *
1235
1330
  * ```js
1236
1331
  * const store = createStore().setTables({
@@ -1318,6 +1413,43 @@ export interface Store {
1318
1413
  */
1319
1414
  getTable(tableId: Id): Table;
1320
1415
 
1416
+ /**
1417
+ * The getTableCellIds method returns the Ids of every Cell used across the
1418
+ * whole Table.
1419
+ *
1420
+ * Note that this returns a copy of, rather than a reference, to the list of
1421
+ * Ids, so changes made to the list are not made to the Store itself.
1422
+ *
1423
+ * @param tableId The Id of the Table in the Store.
1424
+ * @returns An array of the Ids of every Cell used across the whole Table.
1425
+ * @example
1426
+ * This example retrieves the Cell Ids used across a whole Table.
1427
+ *
1428
+ * ```js
1429
+ * const store = createStore().setTables({
1430
+ * pets: {
1431
+ * fido: {species: 'dog', color: 'brown'},
1432
+ * felix: {species: 'cat', legs: 4},
1433
+ * cujo: {dangerous: true},
1434
+ * },
1435
+ * });
1436
+ * console.log(store.getTableCellIds('pets'));
1437
+ * // -> ['species', 'color', 'legs', 'dangerous']
1438
+ * ```
1439
+ * @example
1440
+ * This example retrieves the Cell Ids used across a Table that does not
1441
+ * exist, returning an empty array.
1442
+ *
1443
+ * ```js
1444
+ * const store = createStore().setTables({pets: {fido: {species: 'dog'}}});
1445
+ * console.log(store.getTableCellIds('species'));
1446
+ * // -> []
1447
+ * ```
1448
+ * @category Getter
1449
+ * @since v3.3
1450
+ */
1451
+ getTableCellIds(tableId: Id): Ids;
1452
+
1321
1453
  /**
1322
1454
  * The getRowIds method returns the Ids of every Row in a given Table.
1323
1455
  *
@@ -1371,7 +1503,7 @@ export interface Store {
1371
1503
  *
1372
1504
  * @param tableId The Id of the Table in the Store.
1373
1505
  * @param cellId The Id of the Cell whose values are used for the sorting, or
1374
- * `undefined` to by sort the Row Id itself.
1506
+ * `undefined` to sort by the Row Id itself.
1375
1507
  * @param descending Whether the sorting should be in descending order.
1376
1508
  * @param offset The number of Row Ids to skip for pagination purposes, if
1377
1509
  * any.
@@ -1497,7 +1629,7 @@ export interface Store {
1497
1629
  getRow(tableId: Id, rowId: Id): Row;
1498
1630
 
1499
1631
  /**
1500
- * The getCellIds method returns the Ids of every Cell in a given Row, in a
1632
+ * The getCellIds method returns the Ids of every Cell in a given Row in a
1501
1633
  * given Table.
1502
1634
  *
1503
1635
  * Note that this returns a copy of, rather than a reference, to the list of
@@ -1519,8 +1651,8 @@ export interface Store {
1519
1651
  * // -> ['species', 'color']
1520
1652
  * ```
1521
1653
  * @example
1522
- * This example retrieves the Cell Ids of a Cell that does not exist,
1523
- * returning an empty array.
1654
+ * This example retrieves the Cell Ids of a Row that does not exist, returning
1655
+ * an empty array.
1524
1656
  *
1525
1657
  * ```js
1526
1658
  * const store = createStore().setTables({pets: {fido: {species: 'dog'}}});
@@ -1569,9 +1701,9 @@ export interface Store {
1569
1701
  * data, so changes made to the returned object are not made to the Store
1570
1702
  * itself.
1571
1703
  *
1572
- * @returns An object containing the entire data of the Values.
1704
+ * @returns An object containing the set of keyed Values in the Store.
1573
1705
  * @example
1574
- * This example retrieves the keyed Values data in a Store.
1706
+ * This example retrieves the set of keyed Values in the Store.
1575
1707
  *
1576
1708
  * ```js
1577
1709
  * const store = createStore().setValues({open: true, employees: 3});
@@ -1579,7 +1711,7 @@ export interface Store {
1579
1711
  * // -> {open: true, employees: 3}
1580
1712
  * ```
1581
1713
  * @example
1582
- * This example retrieves a Values from a Store that has none, returning an
1714
+ * This example retrieves Values from a Store that has none, returning an
1583
1715
  * empty object.
1584
1716
  *
1585
1717
  * ```js
@@ -1687,6 +1819,32 @@ export interface Store {
1687
1819
  */
1688
1820
  hasTable(tableId: Id): boolean;
1689
1821
 
1822
+ /**
1823
+ * The hasTableCell method returns a boolean indicating whether a given Cell
1824
+ * exists anywhere in a Table, not just in a specific Row.
1825
+ *
1826
+ * @param tableId The Id of a possible Table in the Store.
1827
+ * @param cellId The Id of a possible Cell in the Table.
1828
+ * @returns Whether a Cell with that Id exists anywhere in that Table.
1829
+ * @example
1830
+ * This example shows two simple Cell existence checks.
1831
+ *
1832
+ * ```js
1833
+ * const store = createStore().setTables({
1834
+ * pets: {fido: {species: 'dog'}, felix: {legs: 4}},
1835
+ * });
1836
+ * console.log(store.hasTableCell('pets', 'species'));
1837
+ * // -> true
1838
+ * console.log(store.hasTableCell('pets', 'legs'));
1839
+ * // -> true
1840
+ * console.log(store.hasTableCell('pets', 'color'));
1841
+ * // -> false
1842
+ * ```
1843
+ * @category Getter
1844
+ * @since v3.3
1845
+ */
1846
+ hasTableCell(tableId: Id, cellId: Id): boolean;
1847
+
1690
1848
  /**
1691
1849
  * The hasRow method returns a boolean indicating whether a given Row exists
1692
1850
  * in the Store.
@@ -1710,7 +1868,7 @@ export interface Store {
1710
1868
 
1711
1869
  /**
1712
1870
  * The hasCell method returns a boolean indicating whether a given Cell exists
1713
- * in the Store.
1871
+ * in a given Row in a given Table.
1714
1872
  *
1715
1873
  * @param tableId The Id of a possible Table in the Store.
1716
1874
  * @param rowId The Id of a possible Row in the Table.
@@ -1964,7 +2122,8 @@ export interface Store {
1964
2122
  getSchemaJson(): Json;
1965
2123
 
1966
2124
  /**
1967
- * The setTables method takes an object and sets the entire data of the Store.
2125
+ * The setTables method takes an object and sets the entire tabular data of
2126
+ * the Store.
1968
2127
  *
1969
2128
  * This method will cause listeners to be called for any Table, Row, Cell, or
1970
2129
  * Id changes resulting from it.
@@ -1982,7 +2141,7 @@ export interface Store {
1982
2141
  *
1983
2142
  * @param tables The data of the Store to be set.
1984
2143
  * @example
1985
- * This example sets the data of a Store.
2144
+ * This example sets the tabular data of a Store.
1986
2145
  *
1987
2146
  * ```js
1988
2147
  * const store = createStore().setTables({
@@ -1993,8 +2152,8 @@ export interface Store {
1993
2152
  * // -> {pets: {fido: {species: 'dog'}}, species: {dog: {price: 5}}}
1994
2153
  * ```
1995
2154
  * @example
1996
- * This example attempts to set the data of an existing Store with partly
1997
- * invalid, and then completely invalid, Tables objects.
2155
+ * This example attempts to set the tabular data of an existing Store with
2156
+ * partly invalid, and then completely invalid, Tables objects.
1998
2157
  *
1999
2158
  * ```js
2000
2159
  * const store = createStore().setTables({pets: {fido: {species: 'dog'}}});
@@ -2131,8 +2290,17 @@ export interface Store {
2131
2290
  * Row is added to the Table. However it is likely to be a string
2132
2291
  * representation of an increasing integer.
2133
2292
  *
2293
+ * The `reuseRowIds` parameter defaults to `true`, which means that if you
2294
+ * delete a Row and then add another, the Id will be re-used - unless you
2295
+ * delete the entire Table, in which case all Row Ids will reset. Otherwise,
2296
+ * if you specify `reuseRowIds` to be `false`, then the Id will be a
2297
+ * monotonically increasing string representation of an increasing integer,
2298
+ * regardless of any you may have previously deleted.
2299
+ *
2134
2300
  * @param tableId The Id of the Table in the Store.
2135
2301
  * @param row The data of a single Row to be added.
2302
+ * @param reuseRowIds Whether Ids should be recycled from previously deleted
2303
+ * Row objects, defaulting to `true`.
2136
2304
  * @returns A reference to the Store.
2137
2305
  * @example
2138
2306
  * This example adds a single Row.
@@ -2163,7 +2331,7 @@ export interface Store {
2163
2331
  * ```
2164
2332
  * @category Setter
2165
2333
  */
2166
- addRow(tableId: Id, row: Row): Id | undefined;
2334
+ addRow(tableId: Id, row: Row, reuseRowIds?: boolean): Id | undefined;
2167
2335
 
2168
2336
  /**
2169
2337
  * The setPartialRow method takes an object and sets partial data of a single
@@ -2541,7 +2709,7 @@ export interface Store {
2541
2709
  * // -> {}
2542
2710
  * ```
2543
2711
  * @example
2544
- * This example attempts to set the the tabular and keyed value contents of a
2712
+ * This example attempts to set both the tabular and keyed value contents of a
2545
2713
  * Store from an invalid serialization.
2546
2714
  *
2547
2715
  * ```js
@@ -3281,6 +3449,36 @@ export interface Store {
3281
3449
  */
3282
3450
  forEachTable(tableCallback: TableCallback): void;
3283
3451
 
3452
+ /**
3453
+ * The forEachTableCell method takes a function that it will then call for
3454
+ * each Cell used across the whole Table.
3455
+ *
3456
+ * This method is useful for iterating over the Cell structure of the Table in
3457
+ * a functional style. The `tableCellCallback` parameter is a
3458
+ * TableCellCallback function that will be called with the Id of each Cell and
3459
+ * the count of Rows in the Table in which it appears.
3460
+ *
3461
+ * @param tableId The Id of the Table containing the Cells to iterate over.
3462
+ * @param tableCellCallback The function that should be called for every Cell
3463
+ * Id used across the whole Table.
3464
+ * @example
3465
+ * This example iterates over each Cell Id used across the whole Table.
3466
+ *
3467
+ * ```js
3468
+ * const store = createStore().setTables({
3469
+ * pets: {fido: {species: 'dog'}, felix: {species: 'cat', legs: 4}},
3470
+ * });
3471
+ * store.forEachTableCell('pets', (cellId, count) => {
3472
+ * console.log(`${cellId}: ${count}`);
3473
+ * });
3474
+ * // -> 'species: 2'
3475
+ * // -> 'legs: 1'
3476
+ * ```
3477
+ * @category Iterator
3478
+ * @since v3.3
3479
+ */
3480
+ forEachTableCell(tableId: Id, tableCellCallback: TableCellCallback): void;
3481
+
3284
3482
  /**
3285
3483
  * The forEachRow method takes a function that it will then call for each Row
3286
3484
  * in a specified Table.
@@ -3593,6 +3791,111 @@ export interface Store {
3593
3791
  mutator?: boolean,
3594
3792
  ): Id;
3595
3793
 
3794
+ /**
3795
+ * The addTableCellIdsListener method registers a listener function with the
3796
+ * Store that will be called whenever the Cell Ids that appear anywhere in a
3797
+ * Table change.
3798
+ *
3799
+ * The provided listener is a TableCellIdsListener function, and will be
3800
+ * called with a reference to the Store and the Id of the Table that changed.
3801
+ *
3802
+ * By default, such a listener is only called when a Cell Id is added or
3803
+ * removed from the whole of the Table. To listen to all changes in the Table,
3804
+ * use the addTableListener method.
3805
+ *
3806
+ * You can either listen to a single Table (by specifying its Id as the
3807
+ * method's first parameter) or changes to any Table (by providing a `null`
3808
+ * wildcard).
3809
+ *
3810
+ * Use the optional mutator parameter to indicate that there is code in the
3811
+ * listener that will mutate Store data. If set to `false` (or omitted), such
3812
+ * mutations will be silently ignored. All relevant mutator listeners (with
3813
+ * this flag set to `true`) are called _before_ any non-mutator listeners
3814
+ * (since the latter may become relevant due to changes made in the former).
3815
+ * The changes made by mutator listeners do not fire other mutating listeners,
3816
+ * though they will fire non-mutator listeners.
3817
+ *
3818
+ * @param tableId The Id of the Table to listen to, or `null` as a wildcard.
3819
+ * @param listener The function that will be called whenever the Cell Ids that
3820
+ * appear anywhere in a Table change.
3821
+ * @param mutator An optional boolean that indicates that the listener mutates
3822
+ * Store data.
3823
+ * @returns A unique Id for the listener that can later be used to call it
3824
+ * explicitly, or to remove it.
3825
+ * @example
3826
+ * This example registers a listener that responds to any change to the Cell
3827
+ * Ids that appear anywhere in a Table.
3828
+ *
3829
+ * ```js
3830
+ * const store = createStore().setTables({
3831
+ * pets: {fido: {species: 'dog', color: 'brown'}},
3832
+ * });
3833
+ * const listenerId = store.addTableCellIdsListener('pets', (store) => {
3834
+ * console.log('Cell Ids in pets table changed');
3835
+ * console.log(store.getTableCellIds('pets'));
3836
+ * });
3837
+ *
3838
+ * store.setRow('pets', 'felix', {species: 'cat', legs: 4});
3839
+ * // -> 'Cell Ids in pets table changed'
3840
+ * // -> ['species', 'color', 'legs']
3841
+ *
3842
+ * store.delListener(listenerId);
3843
+ * ```
3844
+ * @example
3845
+ * This example registers a listener that responds to any change to the Cell
3846
+ * Ids that appear anywhere in any Table.
3847
+ *
3848
+ * ```js
3849
+ * const store = createStore().setTables({
3850
+ * pets: {fido: {species: 'dog', color: 'brown'}},
3851
+ * species: {dog: {price: 5}},
3852
+ * });
3853
+ * const listenerId = store.addTableCellIdsListener(
3854
+ * null,
3855
+ * (store, tableId) => {
3856
+ * console.log(`Cell Ids in ${tableId} table changed`);
3857
+ * console.log(store.getTableCellIds(tableId));
3858
+ * },
3859
+ * );
3860
+ *
3861
+ * store.setRow('pets', 'felix', {species: 'cat', legs: 4});
3862
+ * // -> 'Cell Ids in pets table changed'
3863
+ * // -> ['species', 'color', 'legs']
3864
+ *
3865
+ * store.setRow('species', 'cat', {price: 4, friendly: true});
3866
+ * // -> 'Cell Ids in species table changed'
3867
+ * // -> ['price', 'friendly']
3868
+ *
3869
+ * store.delListener(listenerId);
3870
+ * ```
3871
+ * @example
3872
+ * This example registers a listener that responds to the Cell Ids that appear
3873
+ * anywhere in a Table, and which also mutates the Store itself.
3874
+ *
3875
+ * ```js
3876
+ * const store = createStore().setTables({
3877
+ * pets: {fido: {species: 'dog', color: 'brown'}},
3878
+ * });
3879
+ * const listenerId = store.addTableCellIdsListener(
3880
+ * 'pets',
3881
+ * (store, tableId) => store.setCell('meta', 'update', tableId, true),
3882
+ * true, // mutator
3883
+ * );
3884
+ *
3885
+ * store.setRow('pets', 'felix', {species: 'cat', legs: 4});
3886
+ * console.log(store.getTable('meta'));
3887
+ * // -> {update: {pets: true}}
3888
+ *
3889
+ * store.delListener(listenerId);
3890
+ * ```
3891
+ * @category Listener
3892
+ */
3893
+ addTableCellIdsListener(
3894
+ tableId: IdOrNull,
3895
+ listener: TableCellIdsListener,
3896
+ mutator?: boolean,
3897
+ ): Id;
3898
+
3596
3899
  /**
3597
3900
  * The addRowIdsListener method registers a listener function with the Store
3598
3901
  * that will be called whenever the Row Ids in a Table change.
@@ -3721,7 +4024,7 @@ export interface Store {
3721
4024
  *
3722
4025
  * @param tableId The Id of the Table to listen to.
3723
4026
  * @param cellId The Id of the Cell whose values are used for the sorting, or
3724
- * `undefined` to by sort the Row Id itself.
4027
+ * `undefined` to sort by the Row Id itself.
3725
4028
  * @param descending Whether the sorting should be in descending order.
3726
4029
  * @param offset The number of Row Ids to skip for pagination purposes, if
3727
4030
  * any.
@@ -3767,7 +4070,7 @@ export interface Store {
3767
4070
  * store.delListener(listenerId);
3768
4071
  * ```
3769
4072
  * @example
3770
- * This 111example registers a listener that responds to any change to a
4073
+ * This example registers a listener that responds to any change to a
3771
4074
  * paginated section of the sorted Row Ids of a specific Table.
3772
4075
  *
3773
4076
  * ```js
@@ -4872,6 +5175,51 @@ export interface Store {
4872
5175
  mutator?: boolean,
4873
5176
  ): Id;
4874
5177
 
5178
+ /**
5179
+ * The addStartTransactionListener method registers a listener function with
5180
+ * the Store that will be called at the start of a transaction.
5181
+ *
5182
+ * The provided TransactionListener will receive a reference to the Store and
5183
+ * two booleans to indicate whether Cell or Value data has been touched during
5184
+ * the transaction. Since this is called at the start, they will both be
5185
+ * `false`!
5186
+ *
5187
+ * Note that a TransactionListener added to the Store with this method can
5188
+ * mutate the Store, and its changes will be treated as part of the
5189
+ * transaction that is starting.
5190
+ *
5191
+ * @returns A unique Id for the listener that can later be used to remove it.
5192
+ * @example
5193
+ * This example registers a listener that is called at start end of the
5194
+ * transaction, just before its listeners will be called.
5195
+ *
5196
+ * ```js
5197
+ * const store = createStore()
5198
+ * .setTables({
5199
+ * pets: {fido: {species: 'dog', color: 'brown'}},
5200
+ * })
5201
+ * .setValues({open: true, employees: 3});
5202
+ * const listenerId = store.addStartTransactionListener(
5203
+ * (store, cellsTouched, valuesTouched) => {
5204
+ * console.log('Transaction started');
5205
+ * },
5206
+ * );
5207
+ *
5208
+ * store.transaction(() =>
5209
+ * store.setCell('pets', 'fido', 'color', 'brown').setValue('employees', 3),
5210
+ * );
5211
+ * // -> 'Transaction started'
5212
+ *
5213
+ * store.callListener(listenerId);
5214
+ * // -> 'Transaction started'
5215
+ *
5216
+ * store.delListener(listenerId);
5217
+ * ```
5218
+ * @category Listener
5219
+ * @since v3.2.0
5220
+ */
5221
+ addStartTransactionListener(listener: TransactionListener): Id;
5222
+
4875
5223
  /**
4876
5224
  * The addWillFinishTransactionListener method registers a listener function
4877
5225
  * with the Store that will be called just before other non-mutating listeners
@@ -4892,6 +5240,11 @@ export interface Store {
4892
5240
  * value of `cellsTouched` and `valuesTouched` in the listener will be `false`
4893
5241
  * because all changes have been reverted.
4894
5242
  *
5243
+ * Note that a TransactionListener added to the Store with this method can
5244
+ * mutate the Store itself, and its changes will be treated as part of the
5245
+ * transaction that is starting (and may fire non-mutating listeners after
5246
+ * this).
5247
+ *
4895
5248
  * @returns A unique Id for the listener that can later be used to remove it.
4896
5249
  * @example
4897
5250
  * This example registers a listener that is called at the end of the
@@ -4985,6 +5338,9 @@ export interface Store {
4985
5338
  * value of `cellsTouched` and `valuesTouched` in the listener will be `false`
4986
5339
  * because all changes have been reverted.
4987
5340
  *
5341
+ * Note that a TransactionListener added to the Store with this method
5342
+ * _cannot_ mutate the Store itself, and attempts to do so will fail silently.
5343
+ *
4988
5344
  * @returns A unique Id for the listener that can later be used to remove it.
4989
5345
  * @example
4990
5346
  * This example registers a listener that is called at the end of the
@@ -5143,7 +5499,7 @@ export interface Store {
5143
5499
  * ```
5144
5500
  * @example
5145
5501
  * This example registers listeners for the end of transactions, and for
5146
- * invalid Cells. The are explicitly called, meaninglessly. The former
5502
+ * invalid Cells. They are explicitly called, meaninglessly. The former
5147
5503
  * receives empty arguments. The latter is not called at all.
5148
5504
  *
5149
5505
  * ```js
@@ -433,7 +433,7 @@ export interface Tools {
433
433
  * // -> `export type Tables = {pets?: {[rowId: Id]: {price?: number}}};`
434
434
  *
435
435
  * const tsLines = ts.split('\n');
436
- * console.log(tsLines[79]);
436
+ * console.log(tsLines[81]);
437
437
  * // -> ' hasPetsTable: (): boolean => store.hasTable(PETS),'
438
438
  * ```
439
439
  * @example
@@ -454,7 +454,7 @@ export interface Tools {
454
454
  * // -> 'export type Tables = {pets?: {[rowId: Id]: {price: number}}};'
455
455
  *
456
456
  * const tsLines = ts.split('\n');
457
- * console.log(tsLines[81]);
457
+ * console.log(tsLines[83]);
458
458
  * // -> ' hasPetsTable: (): boolean => store.hasTable(PETS),'
459
459
  * ```
460
460
  * @category Modelling