tinybase 4.4.0-beta.1 → 4.4.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 (71) hide show
  1. package/lib/cjs/store.cjs +1 -1
  2. package/lib/cjs/store.cjs.gz +0 -0
  3. package/lib/cjs/tinybase.cjs +1 -1
  4. package/lib/cjs/tinybase.cjs.gz +0 -0
  5. package/lib/cjs/tools.cjs +1 -1
  6. package/lib/cjs/tools.cjs.gz +0 -0
  7. package/lib/cjs/ui-react-dom-debug.cjs +1 -1
  8. package/lib/cjs/ui-react-dom-debug.cjs.gz +0 -0
  9. package/lib/cjs/ui-react.cjs +1 -1
  10. package/lib/cjs/ui-react.cjs.gz +0 -0
  11. package/lib/cjs-es6/store.cjs +1 -1
  12. package/lib/cjs-es6/store.cjs.gz +0 -0
  13. package/lib/cjs-es6/tinybase.cjs +1 -1
  14. package/lib/cjs-es6/tinybase.cjs.gz +0 -0
  15. package/lib/cjs-es6/tools.cjs +1 -1
  16. package/lib/cjs-es6/tools.cjs.gz +0 -0
  17. package/lib/cjs-es6/ui-react-dom-debug.cjs +1 -1
  18. package/lib/cjs-es6/ui-react-dom-debug.cjs.gz +0 -0
  19. package/lib/cjs-es6/ui-react.cjs +1 -1
  20. package/lib/cjs-es6/ui-react.cjs.gz +0 -0
  21. package/lib/debug/store.js +1 -1
  22. package/lib/debug/tinybase.js +1 -1
  23. package/lib/debug/tools.js +355 -14
  24. package/lib/debug/ui-react-dom.js +1 -1
  25. package/lib/debug/ui-react.js +284 -71
  26. package/lib/es6/store.js +1 -1
  27. package/lib/es6/store.js.gz +0 -0
  28. package/lib/es6/tinybase.js +1 -1
  29. package/lib/es6/tinybase.js.gz +0 -0
  30. package/lib/es6/tools.js +1 -1
  31. package/lib/es6/tools.js.gz +0 -0
  32. package/lib/es6/ui-react-dom-debug.js +1 -1
  33. package/lib/es6/ui-react-dom-debug.js.gz +0 -0
  34. package/lib/es6/ui-react.js +1 -1
  35. package/lib/es6/ui-react.js.gz +0 -0
  36. package/lib/store.js +1 -1
  37. package/lib/store.js.gz +0 -0
  38. package/lib/tinybase.js +1 -1
  39. package/lib/tinybase.js.gz +0 -0
  40. package/lib/tools.js +1 -1
  41. package/lib/tools.js.gz +0 -0
  42. package/lib/types/store.d.ts +1 -1
  43. package/lib/types/tools.d.ts +2 -2
  44. package/lib/types/ui-react.d.ts +1163 -52
  45. package/lib/types/with-schemas/store.d.ts +1 -1
  46. package/lib/types/with-schemas/tools.d.ts +2 -2
  47. package/lib/types/with-schemas/ui-react.d.ts +1353 -65
  48. package/lib/ui-react.js +1 -1
  49. package/lib/ui-react.js.gz +0 -0
  50. package/lib/umd/store.js +1 -1
  51. package/lib/umd/store.js.gz +0 -0
  52. package/lib/umd/tinybase.js +1 -1
  53. package/lib/umd/tinybase.js.gz +0 -0
  54. package/lib/umd/tools.js +1 -1
  55. package/lib/umd/tools.js.gz +0 -0
  56. package/lib/umd/ui-react-dom-debug.js +1 -1
  57. package/lib/umd/ui-react-dom-debug.js.gz +0 -0
  58. package/lib/umd/ui-react.js +1 -1
  59. package/lib/umd/ui-react.js.gz +0 -0
  60. package/lib/umd-es6/store.js +1 -1
  61. package/lib/umd-es6/store.js.gz +0 -0
  62. package/lib/umd-es6/tinybase.js +1 -1
  63. package/lib/umd-es6/tinybase.js.gz +0 -0
  64. package/lib/umd-es6/tools.js +1 -1
  65. package/lib/umd-es6/tools.js.gz +0 -0
  66. package/lib/umd-es6/ui-react-dom-debug.js +1 -1
  67. package/lib/umd-es6/ui-react-dom-debug.js.gz +0 -0
  68. package/lib/umd-es6/ui-react.js +1 -1
  69. package/lib/umd-es6/ui-react.js.gz +0 -0
  70. package/package.json +20 -20
  71. package/readme.md +13 -13
@@ -28,6 +28,13 @@ import {
28
28
  CellIdsListener,
29
29
  CellListener,
30
30
  CellOrUndefined,
31
+ HasCellListener,
32
+ HasRowListener,
33
+ HasTableCellListener,
34
+ HasTableListener,
35
+ HasTablesListener,
36
+ HasValueListener,
37
+ HasValuesListener,
31
38
  MapCell,
32
39
  MapValue,
33
40
  Row,
@@ -420,6 +427,84 @@ export function useStoreOrStoreById(
420
427
  storeOrStoreId?: StoreOrStoreId,
421
428
  ): Store | undefined;
422
429
 
430
+ /**
431
+ * The useHasTables hook returns a boolean indicating whether any Table objects
432
+ * exist in the Store, and registers a listener so that any changes to that
433
+ * result will cause a re-render.
434
+ *
435
+ * A Provider component is used to wrap part of an application in a context, and
436
+ * it can contain a default Store or a set of Store objects named by Id. The
437
+ * useHasTables hook lets you indicate which Store to get data for: omit the
438
+ * optional parameter for the default context Store, provide an Id for a named
439
+ * context Store, or provide a Store explicitly by reference.
440
+ *
441
+ * When first rendered, this hook will create a listener so that changes to the
442
+ * Tables will cause a re-render. When the component containing this hook is
443
+ * unmounted, the listener will be automatically removed.
444
+ * @param storeOrStoreId The Store to be accessed: omit for the default context
445
+ * Store, provide an Id for a named context Store, or provide an explicit
446
+ * reference.
447
+ * @returns Whether any Tables exist.
448
+ * @example
449
+ * This example creates a Store outside the application, which is used in the
450
+ * useHasTables hook by reference. A change to the data in the Store re-renders
451
+ * the component.
452
+ *
453
+ * ```jsx
454
+ * const store = createStore().setCell('pets', 'fido', 'color', 'brown');
455
+ * const App = () => <span>{JSON.stringify(useHasTables(store))}</span>;
456
+ *
457
+ * const app = document.createElement('div');
458
+ * const root = ReactDOMClient.createRoot(app);
459
+ * root.render(<App />); // !act
460
+ * console.log(app.innerHTML);
461
+ * // -> '<span>true</span>'
462
+ *
463
+ * store.delTable('pets'); // !act
464
+ * console.log(app.innerHTML);
465
+ * // -> '<span>false</span>'
466
+ * ```
467
+ * @example
468
+ * This example creates a Provider context into which a default Store is
469
+ * provided. A component within it then uses the useHasTables hook.
470
+ *
471
+ * ```jsx
472
+ * const App = ({store}) => (
473
+ * <Provider store={store}>
474
+ * <Pane />
475
+ * </Provider>
476
+ * );
477
+ * const Pane = () => <span>{JSON.stringify(useHasTables())}</span>;
478
+ *
479
+ * const store = createStore().setCell('pets', 'fido', 'color', 'brown');
480
+ * const app = document.createElement('div');
481
+ * ReactDOMClient.createRoot(app).render(<App store={store} />); // !act
482
+ * console.log(app.innerHTML);
483
+ * // -> '<span>true</span>'
484
+ * ```
485
+ * @example
486
+ * This example creates a Provider context into which a Store is provided, named
487
+ * by Id. A component within it then uses the useHasTables hook.
488
+ *
489
+ * ```jsx
490
+ * const App = ({store}) => (
491
+ * <Provider storesById={{petStore: store}}>
492
+ * <Pane />
493
+ * </Provider>
494
+ * );
495
+ * const Pane = () => <span>{JSON.stringify(useHasTables('petStore'))}</span>;
496
+ *
497
+ * const store = createStore().setCell('pets', 'fido', 'color', 'brown');
498
+ * const app = document.createElement('div');
499
+ * ReactDOMClient.createRoot(app).render(<App store={store} />); // !act
500
+ * console.log(app.innerHTML);
501
+ * // -> '<span>true</span>'
502
+ * ```
503
+ * @category Store hooks
504
+ * @since v4.4.0
505
+ */
506
+ export function useHasTables(storeOrStoreId?: StoreOrStoreId): boolean;
507
+
423
508
  /**
424
509
  * The useTables hook returns a Tables object containing the tabular data of a
425
510
  * Store, and registers a listener so that any changes to that result will cause
@@ -572,6 +657,92 @@ export function useTables(storeOrStoreId?: StoreOrStoreId): Tables;
572
657
  */
573
658
  export function useTableIds(storeOrStoreId?: StoreOrStoreId): Ids;
574
659
 
660
+ /**
661
+ * The useHasTable hook returns a boolean indicating whether a given Table
662
+ * exists in the Store, and registers a listener so that any changes to that
663
+ * result will cause a re-render.
664
+ *
665
+ * A Provider component is used to wrap part of an application in a context, and
666
+ * it can contain a default Store or a set of Store objects named by Id. The
667
+ * useHasTable hook lets you indicate which Store to get data for: omit the
668
+ * optional parameter for the default context Store, provide an Id for a named
669
+ * context Store, or provide a Store explicitly by reference.
670
+ *
671
+ * When first rendered, this hook will create a listener so that changes to the
672
+ * Table will cause a re-render. When the component containing this hook is
673
+ * unmounted, the listener will be automatically removed.
674
+ * @param tableId The Id of the Table in the Store.
675
+ * @param storeOrStoreId The Store to be accessed: omit for the default context
676
+ * Store, provide an Id for a named context Store, or provide an explicit
677
+ * reference.
678
+ * @returns Whether a Table with that Id exists.
679
+ * @example
680
+ * This example creates a Store outside the application, which is used in the
681
+ * useHasTable hook by reference. A change to the data in the Store re-renders
682
+ * the component.
683
+ *
684
+ * ```jsx
685
+ * const store = createStore().setCell('pets', 'fido', 'color', 'brown');
686
+ * const App = () => (
687
+ * <span>{JSON.stringify(useHasTable('pets', store))}</span>
688
+ * );
689
+ *
690
+ * const app = document.createElement('div');
691
+ * const root = ReactDOMClient.createRoot(app);
692
+ * root.render(<App />); // !act
693
+ * console.log(app.innerHTML);
694
+ * // -> '<span>true</span>'
695
+ *
696
+ * store.delTable('pets'); // !act
697
+ * console.log(app.innerHTML);
698
+ * // -> '<span>false</span>'
699
+ * ```
700
+ * @example
701
+ * This example creates a Provider context into which a default Store is
702
+ * provided. A component within it then uses the useHasTable hook.
703
+ *
704
+ * ```jsx
705
+ * const App = ({store}) => (
706
+ * <Provider store={store}>
707
+ * <Pane />
708
+ * </Provider>
709
+ * );
710
+ * const Pane = () => <span>{JSON.stringify(useHasTable('pets'))}</span>;
711
+ *
712
+ * const store = createStore().setCell('pets', 'fido', 'color', 'brown');
713
+ * const app = document.createElement('div');
714
+ * ReactDOMClient.createRoot(app).render(<App store={store} />); // !act
715
+ * console.log(app.innerHTML);
716
+ * // -> '<span>true</span>'
717
+ * ```
718
+ * @example
719
+ * This example creates a Provider context into which a Store is provided, named
720
+ * by Id. A component within it then uses the useHasTable hook.
721
+ *
722
+ * ```jsx
723
+ * const App = ({store}) => (
724
+ * <Provider storesById={{petStore: store}}>
725
+ * <Pane />
726
+ * </Provider>
727
+ * );
728
+ * const Pane = () => (
729
+ * <span>{JSON.stringify(useHasTable('pets', 'petStore'))}</span>
730
+ * );
731
+ *
732
+ * const store = createStore().setCell('pets', 'fido', 'color', 'brown');
733
+ * const app = document.createElement('div');
734
+ * ReactDOMClient.createRoot(app).render(<App store={store} />); // !act
735
+ * console.log(app.innerHTML);
736
+ * // -> '<span>true</span>'
737
+ * ```
738
+ * @category Store hooks
739
+ * @since v4.4.0
740
+ */
741
+ export function useHasTable(
742
+ tableId: Id,
743
+ storeOrStoreId?: StoreOrStoreId,
744
+ ): boolean;
745
+
575
746
  /**
576
747
  * The useTable hook returns an object containing the data of a single Table in
577
748
  * a Store, and registers a listener so that any changes to that result will
@@ -736,6 +907,98 @@ export function useTableCellIds(
736
907
  storeOrStoreId?: StoreOrStoreId,
737
908
  ): Ids;
738
909
 
910
+ /**
911
+ * The useHasTableCell hook returns a boolean indicating whether a given Cell
912
+ * exists anywhere in a Table, not just in a specific Row, and registers a
913
+ * listener so that any changes to that result will cause a re-render.
914
+ *
915
+ * A Provider component is used to wrap part of an application in a context, and
916
+ * it can contain a default Store or a set of Store objects named by Id. The
917
+ * useHasTableCell hook lets you indicate which Store to get data for: omit the
918
+ * optional parameter for the default context Store, provide an Id for a named
919
+ * context Store, or provide a Store explicitly by reference.
920
+ *
921
+ * When first rendered, this hook will create a listener so that changes to the
922
+ * Table will cause a re-render. When the component containing this hook is
923
+ * unmounted, the listener will be automatically removed.
924
+ * @param tableId The Id of the Table in the Store.
925
+ * @param cellId The Id of the Cell in the Table.
926
+ * @param storeOrStoreId The Store to be accessed: omit for the default context
927
+ * Store, provide an Id for a named context Store, or provide an explicit
928
+ * reference.
929
+ * @returns Whether a Cell with that Id exists anywhere in that Table.
930
+ * @example
931
+ * This example creates a Store outside the application, which is used in the
932
+ * useHasTableCell hook by reference. A change to the data in the Store
933
+ * re-renders the component.
934
+ *
935
+ * ```jsx
936
+ * const store = createStore().setCell('pets', 'fido', 'color', 'brown');
937
+ * const App = () => (
938
+ * <span>{JSON.stringify(useHasTableCell('pets', 'legs', store))}</span>
939
+ * );
940
+ *
941
+ * const app = document.createElement('div');
942
+ * const root = ReactDOMClient.createRoot(app);
943
+ * root.render(<App />); // !act
944
+ * console.log(app.innerHTML);
945
+ * // -> '<span>false</span>'
946
+ *
947
+ * store.setRow('pets', 'felix', {color: 'black', legs: 4}); // !act
948
+ * console.log(app.innerHTML);
949
+ * // -> '<span>true</span>'
950
+ * ```
951
+ * @example
952
+ * This example creates a Provider context into which a default Store is
953
+ * provided. A component within it then uses the useHasTableCell hook.
954
+ *
955
+ * ```jsx
956
+ * const App = ({store}) => (
957
+ * <Provider store={store}>
958
+ * <Pane />
959
+ * </Provider>
960
+ * );
961
+ * const Pane = () => (
962
+ * <span>{JSON.stringify(useHasTableCell('pets', 'legs'))}</span>
963
+ * );
964
+ *
965
+ * const store = createStore().setCell('pets', 'fido', 'color', 'brown');
966
+ * const app = document.createElement('div');
967
+ * ReactDOMClient.createRoot(app).render(<App store={store} />); // !act
968
+ * console.log(app.innerHTML);
969
+ * // -> '<span>false</span>'
970
+ * ```
971
+ * @example
972
+ * This example creates a Provider context into which a Store is provided, named
973
+ * by Id. A component within it then uses the useHasTableCell hook.
974
+ *
975
+ * ```jsx
976
+ * const App = ({store}) => (
977
+ * <Provider storesById={{petStore: store}}>
978
+ * <Pane />
979
+ * </Provider>
980
+ * );
981
+ * const Pane = () => (
982
+ * <span>
983
+ * {JSON.stringify(useHasTableCell('pets', 'legs', 'petStore'))}
984
+ * </span>
985
+ * );
986
+ *
987
+ * const store = createStore().setCell('pets', 'fido', 'color', 'brown');
988
+ * const app = document.createElement('div');
989
+ * ReactDOMClient.createRoot(app).render(<App store={store} />); // !act
990
+ * console.log(app.innerHTML);
991
+ * // -> '<span>false</span>'
992
+ * ```
993
+ * @category Store hooks
994
+ * @since v4.4.0
995
+ */
996
+ export function useHasTableCell(
997
+ tableId: Id,
998
+ cellId: Id,
999
+ storeOrStoreId?: StoreOrStoreId,
1000
+ ): boolean;
1001
+
739
1002
  /**
740
1003
  * The useRowCount hook returns the count of the Row objects in a given Table,
741
1004
  * and registers a listener so that any changes to that result will cause a
@@ -1014,15 +1277,15 @@ export function useSortedRowIds(
1014
1277
  ): Ids;
1015
1278
 
1016
1279
  /**
1017
- * The useRow hook returns an object containing the data of a single Row in a
1018
- * given Table, and registers a listener so that any changes to that result will
1280
+ * The useHasRow hook returns a boolean indicating whether a given Row exists in
1281
+ * the Store, and registers a listener so that any changes to that result will
1019
1282
  * cause a re-render.
1020
1283
  *
1021
1284
  * A Provider component is used to wrap part of an application in a context, and
1022
1285
  * it can contain a default Store or a set of Store objects named by Id. The
1023
- * useRow hook lets you indicate which Store to get data for: omit the final
1024
- * optional final parameter for the default context Store, provide an Id for a
1025
- * named context Store, or provide a Store explicitly by reference.
1286
+ * useHasRow hook lets you indicate which Store to get data for: omit the
1287
+ * optional parameter for the default context Store, provide an Id for a named
1288
+ * context Store, or provide a Store explicitly by reference.
1026
1289
  *
1027
1290
  * When first rendered, this hook will create a listener so that changes to the
1028
1291
  * Row will cause a re-render. When the component containing this hook is
@@ -1032,30 +1295,31 @@ export function useSortedRowIds(
1032
1295
  * @param storeOrStoreId The Store to be accessed: omit for the default context
1033
1296
  * Store, provide an Id for a named context Store, or provide an explicit
1034
1297
  * reference.
1035
- * @returns An object containing the entire data of the Row.
1298
+ * @returns Whether a Row with that Id exists in that Table.
1036
1299
  * @example
1037
1300
  * This example creates a Store outside the application, which is used in the
1038
- * useRow hook by reference. A change to the data in the Store re-renders the
1039
- * component.
1301
+ * useHasRow hook by reference. A change to the data in the Store re-renders
1302
+ * the component.
1040
1303
  *
1041
1304
  * ```jsx
1042
1305
  * const store = createStore().setCell('pets', 'fido', 'color', 'brown');
1043
1306
  * const App = () => (
1044
- * <span>{JSON.stringify(useRow('pets', 'fido', store))}</span>
1307
+ * <span>{JSON.stringify(useHasRow('pets', 'felix', store))}</span>
1045
1308
  * );
1046
1309
  *
1047
1310
  * const app = document.createElement('div');
1048
- * ReactDOMClient.createRoot(app).render(<App />); // !act
1311
+ * const root = ReactDOMClient.createRoot(app);
1312
+ * root.render(<App />); // !act
1049
1313
  * console.log(app.innerHTML);
1050
- * // -> '<span>{"color":"brown"}</span>'
1314
+ * // -> '<span>false</span>'
1051
1315
  *
1052
- * store.setCell('pets', 'fido', 'color', 'walnut'); // !act
1316
+ * store.setCell('pets', 'felix', 'color', 'black'); // !act
1053
1317
  * console.log(app.innerHTML);
1054
- * // -> '<span>{"color":"walnut"}</span>'
1318
+ * // -> '<span>true</span>'
1055
1319
  * ```
1056
1320
  * @example
1057
1321
  * This example creates a Provider context into which a default Store is
1058
- * provided. A component within it then uses the useRow hook.
1322
+ * provided. A component within it then uses the useHasRow hook.
1059
1323
  *
1060
1324
  * ```jsx
1061
1325
  * const App = ({store}) => (
@@ -1063,17 +1327,19 @@ export function useSortedRowIds(
1063
1327
  * <Pane />
1064
1328
  * </Provider>
1065
1329
  * );
1066
- * const Pane = () => <span>{JSON.stringify(useRow('pets', 'fido'))}</span>;
1330
+ * const Pane = () => (
1331
+ * <span>{JSON.stringify(useHasRow('pets', 'felix'))}</span>
1332
+ * );
1067
1333
  *
1068
1334
  * const store = createStore().setCell('pets', 'fido', 'color', 'brown');
1069
1335
  * const app = document.createElement('div');
1070
1336
  * ReactDOMClient.createRoot(app).render(<App store={store} />); // !act
1071
1337
  * console.log(app.innerHTML);
1072
- * // -> '<span>{"color":"brown"}</span>'
1338
+ * // -> '<span>false</span>'
1073
1339
  * ```
1074
1340
  * @example
1075
1341
  * This example creates a Provider context into which a Store is provided, named
1076
- * by Id. A component within it then uses the useRow hook.
1342
+ * by Id. A component within it then uses the useHasRow hook.
1077
1343
  *
1078
1344
  * ```jsx
1079
1345
  * const App = ({store}) => (
@@ -1082,36 +1348,123 @@ export function useSortedRowIds(
1082
1348
  * </Provider>
1083
1349
  * );
1084
1350
  * const Pane = () => (
1085
- * <span>{JSON.stringify(useRow('pets', 'fido', 'petStore'))}</span>
1351
+ * <span>{JSON.stringify(useHasRow('pets', 'felix', 'petStore'))}</span>
1086
1352
  * );
1087
1353
  *
1088
1354
  * const store = createStore().setCell('pets', 'fido', 'color', 'brown');
1089
1355
  * const app = document.createElement('div');
1090
1356
  * ReactDOMClient.createRoot(app).render(<App store={store} />); // !act
1091
1357
  * console.log(app.innerHTML);
1092
- * // -> '<span>{"color":"brown"}</span>'
1358
+ * // -> '<span>false</span>'
1093
1359
  * ```
1094
1360
  * @category Store hooks
1361
+ * @since v4.4.0
1095
1362
  */
1096
- export function useRow(
1363
+ export function useHasRow(
1097
1364
  tableId: Id,
1098
1365
  rowId: Id,
1099
1366
  storeOrStoreId?: StoreOrStoreId,
1100
- ): Row;
1367
+ ): boolean;
1101
1368
 
1102
1369
  /**
1103
- * The useCellIds hook returns the Ids of every Cell in a given Row, in a given
1104
- * Table, and registers a listener so that any changes to that result will cause
1105
- * a re-render.
1370
+ * The useRow hook returns an object containing the data of a single Row in a
1371
+ * given Table, and registers a listener so that any changes to that result will
1372
+ * cause a re-render.
1106
1373
  *
1107
1374
  * A Provider component is used to wrap part of an application in a context, and
1108
1375
  * it can contain a default Store or a set of Store objects named by Id. The
1109
- * useCellIds hook lets you indicate which Store to get data for: omit the
1376
+ * useRow hook lets you indicate which Store to get data for: omit the final
1110
1377
  * optional final parameter for the default context Store, provide an Id for a
1111
1378
  * named context Store, or provide a Store explicitly by reference.
1112
1379
  *
1113
1380
  * When first rendered, this hook will create a listener so that changes to the
1114
- * Cell Ids will cause a re-render. When the component containing this hook is
1381
+ * Row will cause a re-render. When the component containing this hook is
1382
+ * unmounted, the listener will be automatically removed.
1383
+ * @param tableId The Id of the Table in the Store.
1384
+ * @param rowId The Id of the Row in the Table.
1385
+ * @param storeOrStoreId The Store to be accessed: omit for the default context
1386
+ * Store, provide an Id for a named context Store, or provide an explicit
1387
+ * reference.
1388
+ * @returns An object containing the entire data of the Row.
1389
+ * @example
1390
+ * This example creates a Store outside the application, which is used in the
1391
+ * useRow hook by reference. A change to the data in the Store re-renders the
1392
+ * component.
1393
+ *
1394
+ * ```jsx
1395
+ * const store = createStore().setCell('pets', 'fido', 'color', 'brown');
1396
+ * const App = () => (
1397
+ * <span>{JSON.stringify(useRow('pets', 'fido', store))}</span>
1398
+ * );
1399
+ *
1400
+ * const app = document.createElement('div');
1401
+ * ReactDOMClient.createRoot(app).render(<App />); // !act
1402
+ * console.log(app.innerHTML);
1403
+ * // -> '<span>{"color":"brown"}</span>'
1404
+ *
1405
+ * store.setCell('pets', 'fido', 'color', 'walnut'); // !act
1406
+ * console.log(app.innerHTML);
1407
+ * // -> '<span>{"color":"walnut"}</span>'
1408
+ * ```
1409
+ * @example
1410
+ * This example creates a Provider context into which a default Store is
1411
+ * provided. A component within it then uses the useRow hook.
1412
+ *
1413
+ * ```jsx
1414
+ * const App = ({store}) => (
1415
+ * <Provider store={store}>
1416
+ * <Pane />
1417
+ * </Provider>
1418
+ * );
1419
+ * const Pane = () => <span>{JSON.stringify(useRow('pets', 'fido'))}</span>;
1420
+ *
1421
+ * const store = createStore().setCell('pets', 'fido', 'color', 'brown');
1422
+ * const app = document.createElement('div');
1423
+ * ReactDOMClient.createRoot(app).render(<App store={store} />); // !act
1424
+ * console.log(app.innerHTML);
1425
+ * // -> '<span>{"color":"brown"}</span>'
1426
+ * ```
1427
+ * @example
1428
+ * This example creates a Provider context into which a Store is provided, named
1429
+ * by Id. A component within it then uses the useRow hook.
1430
+ *
1431
+ * ```jsx
1432
+ * const App = ({store}) => (
1433
+ * <Provider storesById={{petStore: store}}>
1434
+ * <Pane />
1435
+ * </Provider>
1436
+ * );
1437
+ * const Pane = () => (
1438
+ * <span>{JSON.stringify(useRow('pets', 'fido', 'petStore'))}</span>
1439
+ * );
1440
+ *
1441
+ * const store = createStore().setCell('pets', 'fido', 'color', 'brown');
1442
+ * const app = document.createElement('div');
1443
+ * ReactDOMClient.createRoot(app).render(<App store={store} />); // !act
1444
+ * console.log(app.innerHTML);
1445
+ * // -> '<span>{"color":"brown"}</span>'
1446
+ * ```
1447
+ * @category Store hooks
1448
+ */
1449
+ export function useRow(
1450
+ tableId: Id,
1451
+ rowId: Id,
1452
+ storeOrStoreId?: StoreOrStoreId,
1453
+ ): Row;
1454
+
1455
+ /**
1456
+ * The useCellIds hook returns the Ids of every Cell in a given Row, in a given
1457
+ * Table, and registers a listener so that any changes to that result will cause
1458
+ * a re-render.
1459
+ *
1460
+ * A Provider component is used to wrap part of an application in a context, and
1461
+ * it can contain a default Store or a set of Store objects named by Id. The
1462
+ * useCellIds hook lets you indicate which Store to get data for: omit the
1463
+ * optional final parameter for the default context Store, provide an Id for a
1464
+ * named context Store, or provide a Store explicitly by reference.
1465
+ *
1466
+ * When first rendered, this hook will create a listener so that changes to the
1467
+ * Cell Ids will cause a re-render. When the component containing this hook is
1115
1468
  * unmounted, the listener will be automatically removed.
1116
1469
  * @param tableId The Id of the Table in the Store.
1117
1470
  * @param rowId The Id of the Row in the Table.
@@ -1187,6 +1540,100 @@ export function useCellIds(
1187
1540
  storeOrStoreId?: StoreOrStoreId,
1188
1541
  ): Ids;
1189
1542
 
1543
+ /**
1544
+ * The useHasCell hook returns a boolean indicating whether a given Cell exists
1545
+ * in a given Row in a given Table, and registers a listener so that any changes
1546
+ * to that result will cause a re-render.
1547
+ *
1548
+ * A Provider component is used to wrap part of an application in a context, and
1549
+ * it can contain a default Store or a set of Store objects named by Id. The
1550
+ * useHasCell hook lets you indicate which Store to get data for: omit the
1551
+ * optional parameter for the default context Store, provide an Id for a named
1552
+ * context Store, or provide a Store explicitly by reference.
1553
+ *
1554
+ * When first rendered, this hook will create a listener so that changes to the
1555
+ * Cell will cause a re-render. When the component containing this hook is
1556
+ * unmounted, the listener will be automatically removed.
1557
+ * @param tableId The Id of the Table in the Store.
1558
+ * @param rowId The Id of the Row in the Table.
1559
+ * @param cellId The Id of the Cell in the Row.
1560
+ * @param storeOrStoreId The Store to be accessed: omit for the default context
1561
+ * Store, provide an Id for a named context Store, or provide an explicit
1562
+ * reference.
1563
+ * @returns Whether a Cell with that Id exists in that Row in that Table.
1564
+ * @example
1565
+ * This example creates a Store outside the application, which is used in the
1566
+ * useHasCell hook by reference. A change to the data in the Store re-renders
1567
+ * the component.
1568
+ *
1569
+ * ```jsx
1570
+ * const store = createStore().setCell('pets', 'fido', 'color', 'brown');
1571
+ * const App = () => (
1572
+ * <span>{JSON.stringify(useHasCell('pets', 'fido', 'legs', store))}</span>
1573
+ * );
1574
+ *
1575
+ * const app = document.createElement('div');
1576
+ * const root = ReactDOMClient.createRoot(app);
1577
+ * root.render(<App />); // !act
1578
+ * console.log(app.innerHTML);
1579
+ * // -> '<span>false</span>'
1580
+ *
1581
+ * store.setCell('pets', 'fido', 'legs', 4); // !act
1582
+ * console.log(app.innerHTML);
1583
+ * // -> '<span>true</span>'
1584
+ * ```
1585
+ * @example
1586
+ * This example creates a Provider context into which a default Store is
1587
+ * provided. A component within it then uses the useHasCell hook.
1588
+ *
1589
+ * ```jsx
1590
+ * const App = ({store}) => (
1591
+ * <Provider store={store}>
1592
+ * <Pane />
1593
+ * </Provider>
1594
+ * );
1595
+ * const Pane = () => (
1596
+ * <span>{JSON.stringify(useHasCell('pets', 'fido', 'legs'))}</span>
1597
+ * );
1598
+ *
1599
+ * const store = createStore().setCell('pets', 'fido', 'color', 'brown');
1600
+ * const app = document.createElement('div');
1601
+ * ReactDOMClient.createRoot(app).render(<App store={store} />); // !act
1602
+ * console.log(app.innerHTML);
1603
+ * // -> '<span>false</span>'
1604
+ * ```
1605
+ * @example
1606
+ * This example creates a Provider context into which a Store is provided, named
1607
+ * by Id. A component within it then uses the useHasCell hook.
1608
+ *
1609
+ * ```jsx
1610
+ * const App = ({store}) => (
1611
+ * <Provider storesById={{petStore: store}}>
1612
+ * <Pane />
1613
+ * </Provider>
1614
+ * );
1615
+ * const Pane = () => (
1616
+ * <span>
1617
+ * {JSON.stringify(useHasCell('pets', 'fido', 'legs', 'petStore'))}
1618
+ * </span>
1619
+ * );
1620
+ *
1621
+ * const store = createStore().setCell('pets', 'fido', 'color', 'brown');
1622
+ * const app = document.createElement('div');
1623
+ * ReactDOMClient.createRoot(app).render(<App store={store} />); // !act
1624
+ * console.log(app.innerHTML);
1625
+ * // -> '<span>false</span>'
1626
+ * ```
1627
+ * @category Store hooks
1628
+ * @since v4.4.0
1629
+ */
1630
+ export function useHasCell(
1631
+ tableId: Id,
1632
+ rowId: Id,
1633
+ cellId: Id,
1634
+ storeOrStoreId?: StoreOrStoreId,
1635
+ ): boolean;
1636
+
1190
1637
  /**
1191
1638
  * The useCell hook returns an object containing the value of a single Cell in a
1192
1639
  * given Row, in a given Table, and registers a listener so that any changes to
@@ -1273,6 +1720,84 @@ export function useCell(
1273
1720
  storeOrStoreId?: StoreOrStoreId,
1274
1721
  ): CellOrUndefined;
1275
1722
 
1723
+ /**
1724
+ * The useHasValues hook returns a boolean indicating whether any Values exist
1725
+ * in the Store, and registers a listener so that any changes to that result
1726
+ * will cause a re-render.
1727
+ *
1728
+ * A Provider component is used to wrap part of an application in a context, and
1729
+ * it can contain a default Store or a set of Store objects named by Id. The
1730
+ * useHasValues hook lets you indicate which Store to get data for: omit the
1731
+ * optional parameter for the default context Store, provide an Id for a named
1732
+ * context Store, or provide a Store explicitly by reference.
1733
+ *
1734
+ * When first rendered, this hook will create a listener so that changes to the
1735
+ * Values will cause a re-render. When the component containing this hook is
1736
+ * unmounted, the listener will be automatically removed.
1737
+ * @param storeOrStoreId The Store to be accessed: omit for the default context
1738
+ * Store, provide an Id for a named context Store, or provide an explicit
1739
+ * reference.
1740
+ * @returns Whether any Values exist.
1741
+ * @example
1742
+ * This example creates a Store outside the application, which is used in the
1743
+ * useHasValues hook by reference. A change to the data in the Store re-renders
1744
+ * the component.
1745
+ *
1746
+ * ```jsx
1747
+ * const store = createStore().setValue('open', true);
1748
+ * const App = () => <span>{JSON.stringify(useHasValues(store))}</span>;
1749
+ *
1750
+ * const app = document.createElement('div');
1751
+ * const root = ReactDOMClient.createRoot(app);
1752
+ * root.render(<App />); // !act
1753
+ * console.log(app.innerHTML);
1754
+ * // -> '<span>true</span>'
1755
+ *
1756
+ * store.delValue('open'); // !act
1757
+ * console.log(app.innerHTML);
1758
+ * // -> '<span>false</span>'
1759
+ * ```
1760
+ * @example
1761
+ * This example creates a Provider context into which a default Store is
1762
+ * provided. A component within it then uses the useHasValues hook.
1763
+ *
1764
+ * ```jsx
1765
+ * const App = ({store}) => (
1766
+ * <Provider store={store}>
1767
+ * <Pane />
1768
+ * </Provider>
1769
+ * );
1770
+ * const Pane = () => <span>{JSON.stringify(useHasValues())}</span>;
1771
+ *
1772
+ * const store = createStore().setValue('open', true);
1773
+ * const app = document.createElement('div');
1774
+ * ReactDOMClient.createRoot(app).render(<App store={store} />); // !act
1775
+ * console.log(app.innerHTML);
1776
+ * // -> '<span>true</span>'
1777
+ * ```
1778
+ * @example
1779
+ * This example creates a Provider context into which a Store is provided, named
1780
+ * by Id. A component within it then uses the useHasValues hook.
1781
+ *
1782
+ * ```jsx
1783
+ * const App = ({store}) => (
1784
+ * <Provider storesById={{petStore: store}}>
1785
+ * <Pane />
1786
+ * </Provider>
1787
+ * );
1788
+ * const Pane = () => <span>{JSON.stringify(useHasValues('petStore'))}</span>;
1789
+ *
1790
+ * const store = createStore().setValue('open', true);
1791
+ * const app = document.createElement('div');
1792
+ * ReactDOMClient.createRoot(app).render(<App store={store} />); // !act
1793
+ * console.log(app.innerHTML);
1794
+ * // -> '<span>true</span>'
1795
+ * ```
1796
+ * @category Store hooks
1797
+ * @since v4.4.0
1798
+ */
1799
+ export function useHasValues(storeOrStoreId?: StoreOrStoreId): boolean;
1800
+
1276
1801
  /**
1277
1802
  * The useValues hook returns a Values object containing the keyed value data of
1278
1803
  * a Store, and registers a listener so that any changes to that result will
@@ -1426,6 +1951,92 @@ export function useValues(storeOrStoreId?: StoreOrStoreId): Values;
1426
1951
  */
1427
1952
  export function useValueIds(storeOrStoreId?: StoreOrStoreId): Ids;
1428
1953
 
1954
+ /**
1955
+ * The useHasValue hook returns a boolean indicating whether a given Value
1956
+ * exists in the Store, and registers a listener so that any changes to that
1957
+ * result will cause a re-render.
1958
+ *
1959
+ * A Provider component is used to wrap part of an application in a context, and
1960
+ * it can contain a default Store or a set of Store objects named by Id. The
1961
+ * useHasValue hook lets you indicate which Store to get data for: omit the
1962
+ * optional parameter for the default context Store, provide an Id for a named
1963
+ * context Store, or provide a Store explicitly by reference.
1964
+ *
1965
+ * When first rendered, this hook will create a listener so that changes to the
1966
+ * Value will cause a re-render. When the component containing this hook is
1967
+ * unmounted, the listener will be automatically removed.
1968
+ * @param valueId The Id of the Value in the Store.
1969
+ * @param storeOrStoreId The Store to be accessed: omit for the default context
1970
+ * Store, provide an Id for a named context Store, or provide an explicit
1971
+ * reference.
1972
+ * @returns Whether a Value with that Id exists in the Store.
1973
+ * @example
1974
+ * This example creates a Store outside the application, which is used in the
1975
+ * useHasValue hook by reference. A change to the data in the Store re-renders
1976
+ * the component.
1977
+ *
1978
+ * ```jsx
1979
+ * const store = createStore().setValue('open', true);
1980
+ * const App = () => (
1981
+ * <span>{JSON.stringify(useHasValue('employees', store))}</span>
1982
+ * );
1983
+ *
1984
+ * const app = document.createElement('div');
1985
+ * const root = ReactDOMClient.createRoot(app);
1986
+ * root.render(<App />); // !act
1987
+ * console.log(app.innerHTML);
1988
+ * // -> '<span>false</span>'
1989
+ *
1990
+ * store.setValue('employees', 3); // !act
1991
+ * console.log(app.innerHTML);
1992
+ * // -> '<span>true</span>'
1993
+ * ```
1994
+ * @example
1995
+ * This example creates a Provider context into which a default Store is
1996
+ * provided. A component within it then uses the useHasValue hook.
1997
+ *
1998
+ * ```jsx
1999
+ * const App = ({store}) => (
2000
+ * <Provider store={store}>
2001
+ * <Pane />
2002
+ * </Provider>
2003
+ * );
2004
+ * const Pane = () => <span>{JSON.stringify(useHasValue('employees'))}</span>;
2005
+ *
2006
+ * const store = createStore().setValue('open', true);
2007
+ * const app = document.createElement('div');
2008
+ * ReactDOMClient.createRoot(app).render(<App store={store} />); // !act
2009
+ * console.log(app.innerHTML);
2010
+ * // -> '<span>false</span>'
2011
+ * ```
2012
+ * @example
2013
+ * This example creates a Provider context into which a Store is provided, named
2014
+ * by Id. A component within it then uses the useHasValue hook.
2015
+ *
2016
+ * ```jsx
2017
+ * const App = ({store}) => (
2018
+ * <Provider storesById={{petStore: store}}>
2019
+ * <Pane />
2020
+ * </Provider>
2021
+ * );
2022
+ * const Pane = () => (
2023
+ * <span>{JSON.stringify(useHasValue('employees', 'petStore'))}</span>
2024
+ * );
2025
+ *
2026
+ * const store = createStore().setValue('open', true);
2027
+ * const app = document.createElement('div');
2028
+ * ReactDOMClient.createRoot(app).render(<App store={store} />); // !act
2029
+ * console.log(app.innerHTML);
2030
+ * // -> '<span>false</span>'
2031
+ * ```
2032
+ * @category Store hooks
2033
+ * @since v4.4.0
2034
+ */
2035
+ export function useHasValue(
2036
+ valueId: Id,
2037
+ storeOrStoreId?: StoreOrStoreId,
2038
+ ): boolean;
2039
+
1429
2040
  /**
1430
2041
  * The useValue hook returns an object containing the data of a single Value in
1431
2042
  * a Store, and registers a listener so that any changes to that result will
@@ -2728,6 +3339,70 @@ export function useDelValueCallback(
2728
3339
  thenDeps?: React.DependencyList,
2729
3340
  ): Callback;
2730
3341
 
3342
+ /**
3343
+ * The useHasTablesListener hook registers a listener function with the Store
3344
+ * that will be called when Tables as a whole are added to or removed from the
3345
+ * Store.
3346
+ *
3347
+ * This hook is useful for situations where a component needs to register its
3348
+ * own specific listener to do more than simply tracking the value (which is
3349
+ * more easily done with the useHasTables hook).
3350
+ *
3351
+ * Unlike the addHasTablesListener method, which returns a listener Id and
3352
+ * requires you to remove it manually, the useHasTablesListener hook manages
3353
+ * this lifecycle for you: when the listener changes (per its `listenerDeps`
3354
+ * dependencies) or the component unmounts, the listener on the underlying Store
3355
+ * will be deleted.
3356
+ * @param listener The function that will be called whenever Tables as a whole
3357
+ * are added or removed.
3358
+ * @param listenerDeps An optional array of dependencies for the `listener`
3359
+ * function, which, if any change, result in the re-registration of the
3360
+ * listener. This parameter defaults to an empty array.
3361
+ * @param mutator An optional boolean that indicates that the listener mutates
3362
+ * Store data.
3363
+ * @param storeOrStoreId The Store to register the listener with: omit for the
3364
+ * default context Store, provide an Id for a named context Store, or provide an
3365
+ * explicit reference.
3366
+ * @example
3367
+ * This example uses the useHasTablesListener hook to create a listener that is
3368
+ * scoped to a single component. When the component is unmounted, the listener
3369
+ * is removed from the Store.
3370
+ *
3371
+ * ```jsx
3372
+ * const App = ({store}) => (
3373
+ * <Provider store={store}>
3374
+ * <Pane />
3375
+ * </Provider>
3376
+ * );
3377
+ * const Pane = () => {
3378
+ * useHasTablesListener(() => console.log('Tables existence changed'));
3379
+ * return <span>App</span>;
3380
+ * };
3381
+ *
3382
+ * const store = createStore();
3383
+ * const app = document.createElement('div');
3384
+ * const root = ReactDOMClient.createRoot(app);
3385
+ * root.render(<App store={store} />); // !act
3386
+ * console.log(store.getListenerStats().hasTables);
3387
+ * // -> 1
3388
+ *
3389
+ * store.setCell('pets', 'fido', 'color', 'brown'); // !act
3390
+ * // -> 'Tables existence changed'
3391
+ *
3392
+ * root.unmount(); // !act
3393
+ * console.log(store.getListenerStats().hasTables);
3394
+ * // -> 0
3395
+ * ```
3396
+ * @category Store hooks
3397
+ * @since v4.4.0
3398
+ */
3399
+ export function useHasTablesListener(
3400
+ listener: HasTablesListener,
3401
+ listenerDeps?: React.DependencyList,
3402
+ mutator?: boolean,
3403
+ storeOrStoreId?: StoreOrStoreId,
3404
+ ): void;
3405
+
2731
3406
  /**
2732
3407
  * The useTablesListener hook registers a listener function with a Store that
2733
3408
  * will be called whenever tabular data in it changes.
@@ -2851,6 +3526,76 @@ export function useTableIdsListener(
2851
3526
  storeOrStoreId?: StoreOrStoreId,
2852
3527
  ): void;
2853
3528
 
3529
+ /**
3530
+ * The useHasTableListener hook registers a listener function with the Store
3531
+ * that will be called when a Table is added to or removed from the Store.
3532
+ *
3533
+ * This hook is useful for situations where a component needs to register its
3534
+ * own specific listener to do more than simply tracking the value (which is
3535
+ * more easily done with the useHasTable hook).
3536
+ *
3537
+ * You can either listen to a single Table (by specifying its Id as the method's
3538
+ * first parameter) or changes to any Table (by providing a `null` wildcard).
3539
+ *
3540
+ * Unlike the addHasTableListener method, which returns a listener Id and
3541
+ * requires you to remove it manually, the useHasTableListener hook manages this
3542
+ * lifecycle for you: when the listener changes (per its `listenerDeps`
3543
+ * dependencies) or the component unmounts, the listener on the underlying Store
3544
+ * will be deleted.
3545
+ * @param tableId The Id of the Table to listen to, or `null` as a wildcard.
3546
+ * @param listener The function that will be called whenever the matching
3547
+ * Table is added or removed.
3548
+ * @param listenerDeps An optional array of dependencies for the `listener`
3549
+ * function, which, if any change, result in the re-registration of the
3550
+ * listener. This parameter defaults to an empty array.
3551
+ * @param mutator An optional boolean that indicates that the listener mutates
3552
+ * Store data.
3553
+ * @param storeOrStoreId The Store to register the listener with: omit for the
3554
+ * default context Store, provide an Id for a named context Store, or provide an
3555
+ * explicit reference.
3556
+ * @example
3557
+ * This example uses the useHasTableListener hook to create a listener that is
3558
+ * scoped to a single component. When the component is unmounted, the listener
3559
+ * is removed from the Store.
3560
+ *
3561
+ * ```jsx
3562
+ * const App = ({store}) => (
3563
+ * <Provider store={store}>
3564
+ * <Pane />
3565
+ * </Provider>
3566
+ * );
3567
+ * const Pane = () => {
3568
+ * useHasTableListener('pets', () =>
3569
+ * console.log('Table existence changed'),
3570
+ * );
3571
+ * return <span>App</span>;
3572
+ * };
3573
+ *
3574
+ * const store = createStore();
3575
+ * const app = document.createElement('div');
3576
+ * const root = ReactDOMClient.createRoot(app);
3577
+ * root.render(<App store={store} />); // !act
3578
+ * console.log(store.getListenerStats().hasTable);
3579
+ * // -> 1
3580
+ *
3581
+ * store.setCell('pets', 'fido', 'color', 'walnut'); // !act
3582
+ * // -> 'Table existence changed'
3583
+ *
3584
+ * root.unmount(); // !act
3585
+ * console.log(store.getListenerStats().hasTable);
3586
+ * // -> 0
3587
+ * ```
3588
+ * @category Store hooks
3589
+ * @since v4.4.0
3590
+ */
3591
+ export function useHasTableListener(
3592
+ tableId: IdOrNull,
3593
+ listener: HasTableListener,
3594
+ listenerDeps?: React.DependencyList,
3595
+ mutator?: boolean,
3596
+ storeOrStoreId?: StoreOrStoreId,
3597
+ ): void;
3598
+
2854
3599
  /**
2855
3600
  * The useTableListener hook registers a listener function with a Store that
2856
3601
  * will be called whenever data in a Table changes.
@@ -2889,7 +3634,75 @@ export function useTableIdsListener(
2889
3634
  * </Provider>
2890
3635
  * );
2891
3636
  * const Pane = () => {
2892
- * useTableListener('pets', () => console.log('Table changed'));
3637
+ * useTableListener('pets', () => console.log('Table changed'));
3638
+ * return <span>App</span>;
3639
+ * };
3640
+ *
3641
+ * const store = createStore().setTables({pets: {fido: {color: 'brown'}}});
3642
+ * const app = document.createElement('div');
3643
+ * const root = ReactDOMClient.createRoot(app);
3644
+ * root.render(<App store={store} />); // !act
3645
+ * console.log(store.getListenerStats().table);
3646
+ * // -> 1
3647
+ *
3648
+ * store.setCell('pets', 'fido', 'color', 'walnut'); // !act
3649
+ * // -> 'Table changed'
3650
+ *
3651
+ * root.unmount(); // !act
3652
+ * console.log(store.getListenerStats().table);
3653
+ * // -> 0
3654
+ * ```
3655
+ * @category Store hooks
3656
+ */
3657
+ export function useTableListener(
3658
+ tableId: IdOrNull,
3659
+ listener: TableListener,
3660
+ listenerDeps?: React.DependencyList,
3661
+ mutator?: boolean,
3662
+ storeOrStoreId?: StoreOrStoreId,
3663
+ ): void;
3664
+
3665
+ /**
3666
+ * The useTableCellIdsListener hook registers a listener function with a Store
3667
+ * that will be called whenever the Cell Ids that appear anywhere in a Table
3668
+ * change.
3669
+ *
3670
+ * This hook is useful for situations where a component needs to register its
3671
+ * own specific listener to do more than simply tracking the value (which is
3672
+ * more easily done with the useTableCellIds hook).
3673
+ *
3674
+ * You can either listen to a single Table (by specifying its Id as the method's
3675
+ * first parameter) or changes to any Table (by providing `null`).
3676
+ *
3677
+ * Unlike the addTableCellIdsListener method, which returns a listener Id and
3678
+ * requires you to remove it manually, the useTableCellIdsListener hook manages
3679
+ * this lifecycle for you: when the listener changes (per its `listenerDeps`
3680
+ * dependencies) or the component unmounts, the listener on the underlying Store
3681
+ * will be deleted.
3682
+ * @param tableId The Id of the Table to listen to, or `null` as a wildcard.
3683
+ * @param listener The function that will be called whenever the Cell Ids that
3684
+ * appear anywhere in a Table change.
3685
+ * @param listenerDeps An optional array of dependencies for the `listener`
3686
+ * function, which, if any change, result in the re-registration of the
3687
+ * listener. This parameter defaults to an empty array.
3688
+ * @param mutator An optional boolean that indicates that the listener mutates
3689
+ * Store data.
3690
+ * @param storeOrStoreId The Store to register the listener with: omit for the
3691
+ * default context Store, provide an Id for a named context Store, or provide an
3692
+ * explicit reference.
3693
+ * @example
3694
+ * This example uses the useTableCellIdsListener hook to create a listener that
3695
+ * is scoped to a single component. When the component is unmounted, the
3696
+ * listener is removed from the Store.
3697
+ *
3698
+ * ```jsx
3699
+ * const App = ({store}) => (
3700
+ * <Provider store={store}>
3701
+ * <Pane />
3702
+ * </Provider>
3703
+ * );
3704
+ * const Pane = () => {
3705
+ * useTableCellIdsListener('pets', () => console.log('Cell Ids changed'));
2893
3706
  * return <span>App</span>;
2894
3707
  * };
2895
3708
  *
@@ -2897,46 +3710,48 @@ export function useTableIdsListener(
2897
3710
  * const app = document.createElement('div');
2898
3711
  * const root = ReactDOMClient.createRoot(app);
2899
3712
  * root.render(<App store={store} />); // !act
2900
- * console.log(store.getListenerStats().table);
3713
+ * console.log(store.getListenerStats().tableCellIds);
2901
3714
  * // -> 1
2902
3715
  *
2903
- * store.setCell('pets', 'fido', 'color', 'walnut'); // !act
2904
- * // -> 'Table changed'
3716
+ * store.setRow('pets', 'felix', {species: 'cat'}); // !act
3717
+ * // -> 'Cell Ids changed'
2905
3718
  *
2906
3719
  * root.unmount(); // !act
2907
- * console.log(store.getListenerStats().table);
3720
+ * console.log(store.getListenerStats().rowIds);
2908
3721
  * // -> 0
2909
3722
  * ```
2910
3723
  * @category Store hooks
2911
3724
  */
2912
- export function useTableListener(
3725
+ export function useTableCellIdsListener(
2913
3726
  tableId: IdOrNull,
2914
- listener: TableListener,
3727
+ listener: TableCellIdsListener,
2915
3728
  listenerDeps?: React.DependencyList,
2916
3729
  mutator?: boolean,
2917
3730
  storeOrStoreId?: StoreOrStoreId,
2918
3731
  ): void;
2919
3732
 
2920
3733
  /**
2921
- * The useTableCellIdsListener hook registers a listener function with a Store
2922
- * that will be called whenever the Cell Ids that appear anywhere in a Table
2923
- * change.
3734
+ * The useHasTableCellListener hook registers a listener function with the Store
3735
+ * that will be called when a Cell is added to or removed from anywhere in a
3736
+ * Table as a whole.
2924
3737
  *
2925
3738
  * This hook is useful for situations where a component needs to register its
2926
3739
  * own specific listener to do more than simply tracking the value (which is
2927
- * more easily done with the useTableCellIds hook).
3740
+ * more easily done with the useHasTableCell hook).
2928
3741
  *
2929
- * You can either listen to a single Table (by specifying its Id as the method's
2930
- * first parameter) or changes to any Table (by providing `null`).
3742
+ * You can either listen to a single Table Cell being added or removed (by
3743
+ * specifying the Table Id and Cell Id, as the method's first two parameters) or
3744
+ * changes to any Table Cell (by providing `null` wildcards).
2931
3745
  *
2932
- * Unlike the addTableCellIdsListener method, which returns a listener Id and
2933
- * requires you to remove it manually, the useTableCellIdsListener hook manages
3746
+ * Unlike the addHasTableCellIds method, which returns a listener Id and
3747
+ * requires you to remove it manually, the useHasTableCellListener hook manages
2934
3748
  * this lifecycle for you: when the listener changes (per its `listenerDeps`
2935
3749
  * dependencies) or the component unmounts, the listener on the underlying Store
2936
3750
  * will be deleted.
2937
3751
  * @param tableId The Id of the Table to listen to, or `null` as a wildcard.
2938
- * @param listener The function that will be called whenever the Cell Ids that
2939
- * appear anywhere in a Table change.
3752
+ * @param cellId The Id of the Cell to listen to, or `null` as a wildcard.
3753
+ * @param listener The function that will be called whenever the matching Cell
3754
+ * is added to or removed from anywhere in the Table.
2940
3755
  * @param listenerDeps An optional array of dependencies for the `listener`
2941
3756
  * function, which, if any change, result in the re-registration of the
2942
3757
  * listener. This parameter defaults to an empty array.
@@ -2946,7 +3761,7 @@ export function useTableListener(
2946
3761
  * default context Store, provide an Id for a named context Store, or provide an
2947
3762
  * explicit reference.
2948
3763
  * @example
2949
- * This example uses the useTableCellIdsListener hook to create a listener that
3764
+ * This example uses the useHasTableCellListener hook to create a listener that
2950
3765
  * is scoped to a single component. When the component is unmounted, the
2951
3766
  * listener is removed from the Store.
2952
3767
  *
@@ -2957,29 +3772,33 @@ export function useTableListener(
2957
3772
  * </Provider>
2958
3773
  * );
2959
3774
  * const Pane = () => {
2960
- * useTableCellIdsListener('pets', () => console.log('Cell Ids changed'));
3775
+ * useHasTableCellListener('pets', 'color', () =>
3776
+ * console.log('Table Cell existence changed'),
3777
+ * );
2961
3778
  * return <span>App</span>;
2962
3779
  * };
2963
3780
  *
2964
- * const store = createStore().setTables({pets: {fido: {color: 'brown'}}});
3781
+ * const store = createStore();
2965
3782
  * const app = document.createElement('div');
2966
3783
  * const root = ReactDOMClient.createRoot(app);
2967
3784
  * root.render(<App store={store} />); // !act
2968
- * console.log(store.getListenerStats().tableCellIds);
3785
+ * console.log(store.getListenerStats().hasTableCell);
2969
3786
  * // -> 1
2970
3787
  *
2971
- * store.setRow('pets', 'felix', {species: 'cat'}); // !act
2972
- * // -> 'Cell Ids changed'
3788
+ * store.setRow('pets', 'fido', {color: 'brown'}); // !act
3789
+ * // -> 'Table Cell existence changed'
2973
3790
  *
2974
3791
  * root.unmount(); // !act
2975
- * console.log(store.getListenerStats().rowIds);
3792
+ * console.log(store.getListenerStats().hasTableCell);
2976
3793
  * // -> 0
2977
3794
  * ```
2978
3795
  * @category Store hooks
3796
+ * @since v4.4.0
2979
3797
  */
2980
- export function useTableCellIdsListener(
3798
+ export function useHasTableCellListener(
2981
3799
  tableId: IdOrNull,
2982
- listener: TableCellIdsListener,
3800
+ cellId: IdOrNull,
3801
+ listener: HasTableCellListener,
2983
3802
  listenerDeps?: React.DependencyList,
2984
3803
  mutator?: boolean,
2985
3804
  storeOrStoreId?: StoreOrStoreId,
@@ -3201,6 +4020,83 @@ export function useSortedRowIdsListener(
3201
4020
  storeOrStoreId?: StoreOrStoreId,
3202
4021
  ): void;
3203
4022
 
4023
+ /**
4024
+ * The useHasRowListener hook registers a listener function with the Store that
4025
+ * will be called when a Row is added to or removed from the Store.
4026
+ *
4027
+ * This hook is useful for situations where a component needs to register its
4028
+ * own specific listener to do more than simply tracking the value (which is
4029
+ * more easily done with the useHasRow hook).
4030
+ *
4031
+ * You can either listen to a single Row being added or removed (by specifying
4032
+ * the Table Id and Row Id, as the method's first two parameters) or changes
4033
+ * to any Row (by providing `null` wildcards).
4034
+ *
4035
+ * Both, either, or neither of the `tableId` and `rowId` parameters can be
4036
+ * wildcarded with `null`. You can listen to a specific Row in a specific Table,
4037
+ * any Row in a specific Table, a specific Row in any Table, or any Row in any
4038
+ * Table.
4039
+ *
4040
+ * Unlike the addHasRowListener method, which returns a listener Id and requires
4041
+ * you to remove it manually, the useHasRowListener hook manages this lifecycle
4042
+ * for you: when the listener changes (per its `listenerDeps` dependencies) or
4043
+ * the component unmounts, the listener on the underlying Store will be deleted.
4044
+ * @param tableId The Id of the Table to listen to, or `null` as a wildcard.
4045
+ * @param rowId The Id of the Row to listen to, or `null` as a wildcard.
4046
+ * @param listener The function that will be called whenever the matching Row
4047
+ * is added or removed.
4048
+ * @param listenerDeps An optional array of dependencies for the `listener`
4049
+ * function, which, if any change, result in the re-registration of the
4050
+ * listener. This parameter defaults to an empty array.
4051
+ * @param mutator An optional boolean that indicates that the listener mutates
4052
+ * Store data.
4053
+ * @param storeOrStoreId The Store to register the listener with: omit for the
4054
+ * default context Store, provide an Id for a named context Store, or provide an
4055
+ * explicit reference.
4056
+ * @example
4057
+ * This example uses the useHasRowListener hook to create a listener that is
4058
+ * scoped to a single component. When the component is unmounted, the listener
4059
+ * is removed from the Store.
4060
+ *
4061
+ * ```jsx
4062
+ * const App = ({store}) => (
4063
+ * <Provider store={store}>
4064
+ * <Pane />
4065
+ * </Provider>
4066
+ * );
4067
+ * const Pane = () => {
4068
+ * useHasRowListener('pets', 'fido', () =>
4069
+ * console.log('Row existence changed'),
4070
+ * );
4071
+ * return <span>App</span>;
4072
+ * };
4073
+ *
4074
+ * const store = createStore();
4075
+ * const app = document.createElement('div');
4076
+ * const root = ReactDOMClient.createRoot(app);
4077
+ * root.render(<App store={store} />); // !act
4078
+ * console.log(store.getListenerStats().hasRow);
4079
+ * // -> 1
4080
+ *
4081
+ * store.setCell('pets', 'fido', 'color', 'walnut'); // !act
4082
+ * // -> 'Row existence changed'
4083
+ *
4084
+ * root.unmount(); // !act
4085
+ * console.log(store.getListenerStats().hasRow);
4086
+ * // -> 0
4087
+ * ```
4088
+ * @category Store hooks
4089
+ * @since v4.4.0
4090
+ */
4091
+ export function useHasRowListener(
4092
+ tableId: IdOrNull,
4093
+ rowId: IdOrNull,
4094
+ listener: HasRowListener,
4095
+ listenerDeps?: React.DependencyList,
4096
+ mutator?: boolean,
4097
+ storeOrStoreId?: StoreOrStoreId,
4098
+ ): void;
4099
+
3204
4100
  /**
3205
4101
  * The useRowListener hook registers a listener function with a Store that will
3206
4102
  * be called whenever data in a Row changes.
@@ -3352,6 +4248,86 @@ export function useCellIdsListener(
3352
4248
  storeOrStoreId?: StoreOrStoreId,
3353
4249
  ): void;
3354
4250
 
4251
+ /**
4252
+ * The useHasCellListener hook registers a listener function with the Store that
4253
+ * will be called when a Cell is added to or removed from the Store.
4254
+ *
4255
+ * This hook is useful for situations where a component needs to register its
4256
+ * own specific listener to do more than simply tracking the value (which is
4257
+ * more easily done with the useHasCell hook).
4258
+ *
4259
+ * You can either listen to a single Cell being added or removed (by
4260
+ * specifying the Table Id, Row Id, and Cell Id as the method's first three
4261
+ * parameters) or changes to any Cell (by providing `null` wildcards).
4262
+ *
4263
+ * All, some, or none of the `tableId`, `rowId`, and `cellId` parameters can
4264
+ * be wildcarded with `null`. You can listen to a specific Cell in a specific
4265
+ * Row in a specific Table, any Cell in any Row in any Table, for example - or
4266
+ * every other combination of wildcards.
4267
+ *
4268
+ * Unlike the addHasCellListener method, which returns a listener Id and
4269
+ * requires you to remove it manually, the useHasCellListener hook manages this
4270
+ * lifecycle for you: when the listener changes (per its `listenerDeps`
4271
+ * dependencies) or the component unmounts, the listener on the underlying Store
4272
+ * will be deleted.
4273
+ * @param tableId The Id of the Table to listen to, or `null` as a wildcard.
4274
+ * @param rowId The Id of the Row to listen to, or `null` as a wildcard.
4275
+ * @param cellId The Id of the Cell to listen to, or `null` as a wildcard.
4276
+ * @param listener The function that will be called whenever the matching Cell
4277
+ * is added or removed.
4278
+ * @param listenerDeps An optional array of dependencies for the `listener`
4279
+ * function, which, if any change, result in the re-registration of the
4280
+ * listener. This parameter defaults to an empty array.
4281
+ * @param mutator An optional boolean that indicates that the listener mutates
4282
+ * Store data.
4283
+ * @param storeOrStoreId The Store to register the listener with: omit for the
4284
+ * default context Store, provide an Id for a named context Store, or provide an
4285
+ * explicit reference.
4286
+ * @example
4287
+ * This example uses the useHasCellListener hook to create a listener that is
4288
+ * scoped to a single component. When the component is unmounted, the listener
4289
+ * is removed from the Store.
4290
+ *
4291
+ * ```jsx
4292
+ * const App = ({store}) => (
4293
+ * <Provider store={store}>
4294
+ * <Pane />
4295
+ * </Provider>
4296
+ * );
4297
+ * const Pane = () => {
4298
+ * useHasCellListener('pets', 'fido', 'color', () =>
4299
+ * console.log('Cell existence changed'),
4300
+ * );
4301
+ * return <span>App</span>;
4302
+ * };
4303
+ *
4304
+ * const store = createStore();
4305
+ * const app = document.createElement('div');
4306
+ * const root = ReactDOMClient.createRoot(app);
4307
+ * root.render(<App store={store} />); // !act
4308
+ * console.log(store.getListenerStats().hasCell);
4309
+ * // -> 1
4310
+ *
4311
+ * store.setCell('pets', 'fido', 'color', 'brown'); // !act
4312
+ * // -> 'Cell existence changed'
4313
+ *
4314
+ * root.unmount(); // !act
4315
+ * console.log(store.getListenerStats().hasCell);
4316
+ * // -> 0
4317
+ * ```
4318
+ * @category Store hooks
4319
+ * @since v4.4.0
4320
+ */
4321
+ export function useHasCellListener(
4322
+ tableId: IdOrNull,
4323
+ rowId: IdOrNull,
4324
+ cellId: IdOrNull,
4325
+ listener: HasCellListener,
4326
+ listenerDeps?: React.DependencyList,
4327
+ mutator?: boolean,
4328
+ storeOrStoreId?: StoreOrStoreId,
4329
+ ): void;
4330
+
3355
4331
  /**
3356
4332
  * The useCellListener hook registers a listener function with a Store that will
3357
4333
  * be called whenever data in a Cell changes.
@@ -3430,6 +4406,70 @@ export function useCellListener(
3430
4406
  storeOrStoreId?: StoreOrStoreId,
3431
4407
  ): void;
3432
4408
 
4409
+ /**
4410
+ * The useHasValuesListener hook registers a listener function with the Store
4411
+ * that will be called when Values as a whole are added to or removed from the
4412
+ * Store.
4413
+ *
4414
+ * This hook is useful for situations where a component needs to register its
4415
+ * own specific listener to do more than simply tracking the value (which is
4416
+ * more easily done with the useHasValues hook).
4417
+ *
4418
+ * Unlike the addHasValuesListener method, which returns a listener Id and
4419
+ * requires you to remove it manually, the useHasValuesListener hook manages
4420
+ * this lifecycle for you: when the listener changes (per its `listenerDeps`
4421
+ * dependencies) or the component unmounts, the listener on the underlying Store
4422
+ * will be deleted.
4423
+ * @param listener The function that will be called whenever Values as a whole
4424
+ * are added or removed.
4425
+ * @param listenerDeps An optional array of dependencies for the `listener`
4426
+ * function, which, if any change, result in the re-registration of the
4427
+ * listener. This parameter defaults to an empty array.
4428
+ * @param mutator An optional boolean that indicates that the listener mutates
4429
+ * Store data.
4430
+ * @param storeOrStoreId The Store to register the listener with: omit for the
4431
+ * default context Store, provide an Id for a named context Store, or provide an
4432
+ * explicit reference.
4433
+ * @example
4434
+ * This example uses the useHasValuesListener hook to create a listener that is
4435
+ * scoped to a single component. When the component is unmounted, the listener
4436
+ * is removed from the Store.
4437
+ *
4438
+ * ```jsx
4439
+ * const App = ({store}) => (
4440
+ * <Provider store={store}>
4441
+ * <Pane />
4442
+ * </Provider>
4443
+ * );
4444
+ * const Pane = () => {
4445
+ * useHasValuesListener(() => console.log('Values existence changed'));
4446
+ * return <span>App</span>;
4447
+ * };
4448
+ *
4449
+ * const store = createStore();
4450
+ * const app = document.createElement('div');
4451
+ * const root = ReactDOMClient.createRoot(app);
4452
+ * root.render(<App store={store} />); // !act
4453
+ * console.log(store.getListenerStats().hasValues);
4454
+ * // -> 1
4455
+ *
4456
+ * store.setValue('open', true); // !act
4457
+ * // -> 'Values existence changed'
4458
+ *
4459
+ * root.unmount(); // !act
4460
+ * console.log(store.getListenerStats().hasValues);
4461
+ * // -> 0
4462
+ * ```
4463
+ * @category Store hooks
4464
+ * @since v4.4.0
4465
+ */
4466
+ export function useHasValuesListener(
4467
+ listener: HasValuesListener,
4468
+ listenerDeps?: React.DependencyList,
4469
+ mutator?: boolean,
4470
+ storeOrStoreId?: StoreOrStoreId,
4471
+ ): void;
4472
+
3433
4473
  /**
3434
4474
  * The useValuesListener hook registers a listener function with a Store that
3435
4475
  * will be called whenever keyed value data in it changes.
@@ -3555,6 +4595,77 @@ export function useValueIdsListener(
3555
4595
  storeOrStoreId?: StoreOrStoreId,
3556
4596
  ): void;
3557
4597
 
4598
+ /**
4599
+ * The useHasValueListener hook registers a listener function with the Store
4600
+ * that will be called when a Value is added to or removed from the Store.
4601
+ *
4602
+ * This hook is useful for situations where a component needs to register its
4603
+ * own specific listener to do more than simply tracking the value (which is
4604
+ * more easily done with the useHasValue hook).
4605
+ *
4606
+ * You can either listen to a single Value being added or removed (by specifying
4607
+ * the Value Id) or any Value being added or removed (by providing a `null`
4608
+ * wildcard).
4609
+ *
4610
+ * Unlike the addHasValueListener method, which returns a listener Id and
4611
+ * requires you to remove it manually, the useHasValueListener hook manages this
4612
+ * lifecycle for you: when the listener changes (per its `listenerDeps`
4613
+ * dependencies) or the component unmounts, the listener on the underlying Store
4614
+ * will be deleted.
4615
+ * @param valueId The Id of the Value to listen to, or `null` as a wildcard.
4616
+ * @param listener The function that will be called whenever the matching
4617
+ * Value is added or removed.
4618
+ * @param listenerDeps An optional array of dependencies for the `listener`
4619
+ * function, which, if any change, result in the re-registration of the
4620
+ * listener. This parameter defaults to an empty array.
4621
+ * @param mutator An optional boolean that indicates that the listener mutates
4622
+ * Store data.
4623
+ * @param storeOrStoreId The Store to register the listener with: omit for the
4624
+ * default context Store, provide an Id for a named context Store, or provide an
4625
+ * explicit reference.
4626
+ * @example
4627
+ * This example uses the useHasValueListener hook to create a listener that is
4628
+ * scoped to a single component. When the component is unmounted, the listener
4629
+ * is removed from the Store.
4630
+ *
4631
+ * ```jsx
4632
+ * const App = ({store}) => (
4633
+ * <Provider store={store}>
4634
+ * <Pane />
4635
+ * </Provider>
4636
+ * );
4637
+ * const Pane = () => {
4638
+ * useHasValueListener('open', () =>
4639
+ * console.log('Value existence changed'),
4640
+ * );
4641
+ * return <span>App</span>;
4642
+ * };
4643
+ *
4644
+ * const store = createStore();
4645
+ * const app = document.createElement('div');
4646
+ * const root = ReactDOMClient.createRoot(app);
4647
+ * root.render(<App store={store} />); // !act
4648
+ * console.log(store.getListenerStats().hasValue);
4649
+ * // -> 1
4650
+ *
4651
+ * store.setValue('open', false); // !act
4652
+ * // -> 'Value existence changed'
4653
+ *
4654
+ * root.unmount(); // !act
4655
+ * console.log(store.getListenerStats().hasValue);
4656
+ * // -> 0
4657
+ * ```
4658
+ * @category Store hooks
4659
+ * @since v4.4.0
4660
+ */
4661
+ export function useHasValueListener(
4662
+ valueId: IdOrNull,
4663
+ listener: HasValueListener,
4664
+ listenerDeps?: React.DependencyList,
4665
+ mutator?: boolean,
4666
+ storeOrStoreId?: StoreOrStoreId,
4667
+ ): void;
4668
+
3558
4669
  /**
3559
4670
  * The useValueListener hook registers a listener function with a Store that
3560
4671
  * will be called whenever data in a Value changes.