tinybase 0.9.3 → 0.9.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/common.d.ts CHANGED
@@ -57,3 +57,59 @@ export type ParameterizedCallback<Parameter> = (parameter?: Parameter) => void;
57
57
  * @category Callback
58
58
  */
59
59
  export type Callback = () => void;
60
+
61
+ /**
62
+ * The SortKey type represents a value that can be used by a sort function.
63
+ *
64
+ * @category Parameter
65
+ */
66
+ export type SortKey = string | number | boolean;
67
+
68
+ /**
69
+ * The defaultSorter function is provided as a convenience to sort keys
70
+ * alphanumerically, and can be provided to the `sliceIdSorter` and
71
+ * `rowIdSorter` parameters of the setIndexDefinition method in the indexes
72
+ * module, for example.
73
+ *
74
+ * @param sortKey1 The first item of the pair to compare.
75
+ * @param sortKey2 The second item of the pair to compare.
76
+ * @returns A number indicating how to sort the pair.
77
+ * @example
78
+ * This example creates an Indexes object.
79
+ *
80
+ * ```js
81
+ * const store = createStore();
82
+ * const indexes = createIndexes(store);
83
+ * console.log(indexes.getIndexIds());
84
+ * // -> []
85
+ * ```
86
+ * @example
87
+ * This example creates a Store, creates an Indexes object, and defines an
88
+ * Index based on the first letter of the pets' names. The Slice Ids (and Row
89
+ * Ids within them) are alphabetically sorted using the defaultSorter function.
90
+ *
91
+ * ```js
92
+ * const store = createStore().setTable('pets', {
93
+ * fido: {species: 'dog'},
94
+ * felix: {species: 'cat'},
95
+ * cujo: {species: 'dog'},
96
+ * });
97
+ *
98
+ * const indexes = createIndexes(store);
99
+ * indexes.setIndexDefinition(
100
+ * 'byFirst', // indexId
101
+ * 'pets', // tableId
102
+ * (_, rowId) => rowId[0], // each Row's Slice Id
103
+ * (_, rowId) => rowId, // each Row's sort key
104
+ * defaultSorter, // sort Slice Ids
105
+ * defaultSorter, // sort Row Ids by sort key
106
+ * );
107
+ *
108
+ * console.log(indexes.getSliceIds('byFirst'));
109
+ * // -> ['c', 'f']
110
+ * console.log(indexes.getSliceRowIds('byFirst', 'f'));
111
+ * // -> ['felix', 'fido']
112
+ * ```
113
+ * @category Convenience
114
+ */
115
+ export function defaultSorter(sortKey1: SortKey, sortKey2: SortKey): number;
package/lib/common.js ADDED
@@ -0,0 +1 @@
1
+ const o=(o,t)=>o<t?-1:1;export{o as defaultSorter};
Binary file
@@ -57,3 +57,59 @@ export type ParameterizedCallback<Parameter> = (parameter?: Parameter) => void;
57
57
  * @category Callback
58
58
  */
59
59
  export type Callback = () => void;
60
+
61
+ /**
62
+ * The SortKey type represents a value that can be used by a sort function.
63
+ *
64
+ * @category Parameter
65
+ */
66
+ export type SortKey = string | number | boolean;
67
+
68
+ /**
69
+ * The defaultSorter function is provided as a convenience to sort keys
70
+ * alphanumerically, and can be provided to the `sliceIdSorter` and
71
+ * `rowIdSorter` parameters of the setIndexDefinition method in the indexes
72
+ * module, for example.
73
+ *
74
+ * @param sortKey1 The first item of the pair to compare.
75
+ * @param sortKey2 The second item of the pair to compare.
76
+ * @returns A number indicating how to sort the pair.
77
+ * @example
78
+ * This example creates an Indexes object.
79
+ *
80
+ * ```js
81
+ * const store = createStore();
82
+ * const indexes = createIndexes(store);
83
+ * console.log(indexes.getIndexIds());
84
+ * // -> []
85
+ * ```
86
+ * @example
87
+ * This example creates a Store, creates an Indexes object, and defines an
88
+ * Index based on the first letter of the pets' names. The Slice Ids (and Row
89
+ * Ids within them) are alphabetically sorted using the defaultSorter function.
90
+ *
91
+ * ```js
92
+ * const store = createStore().setTable('pets', {
93
+ * fido: {species: 'dog'},
94
+ * felix: {species: 'cat'},
95
+ * cujo: {species: 'dog'},
96
+ * });
97
+ *
98
+ * const indexes = createIndexes(store);
99
+ * indexes.setIndexDefinition(
100
+ * 'byFirst', // indexId
101
+ * 'pets', // tableId
102
+ * (_, rowId) => rowId[0], // each Row's Slice Id
103
+ * (_, rowId) => rowId, // each Row's sort key
104
+ * defaultSorter, // sort Slice Ids
105
+ * defaultSorter, // sort Row Ids by sort key
106
+ * );
107
+ *
108
+ * console.log(indexes.getSliceIds('byFirst'));
109
+ * // -> ['c', 'f']
110
+ * console.log(indexes.getSliceRowIds('byFirst', 'f'));
111
+ * // -> ['felix', 'fido']
112
+ * ```
113
+ * @category Convenience
114
+ */
115
+ export function defaultSorter(sortKey1: SortKey, sortKey2: SortKey): number;
@@ -0,0 +1,3 @@
1
+ const defaultSorter = (sortKey1, sortKey2) => (sortKey1 < sortKey2 ? -1 : 1);
2
+
3
+ export {defaultSorter};
@@ -3,8 +3,8 @@
3
3
  * and track indexes of the data in Store objects.
4
4
  *
5
5
  * The main entry point to this module is the createIndexes function, which
6
- * returns a new Indexes object. From there, you can create new index
7
- * definitions, access the contents of those indexes directly, and register
6
+ * returns a new Indexes object. From there, you can create new Index
7
+ * definitions, access the contents of those Indexes directly, and register
8
8
  * listeners for when they change.
9
9
  *
10
10
  * @packageDocumentation
@@ -12,7 +12,7 @@
12
12
  */
13
13
 
14
14
  import {GetCell, Store} from './store.d';
15
- import {Id, IdOrNull, Ids} from './common.d';
15
+ import {Id, IdOrNull, Ids, SortKey} from './common.d';
16
16
 
17
17
  /**
18
18
  * The Index type represents the concept of a map of Slice objects, keyed by Id.
@@ -43,13 +43,6 @@ export type Index = {[sliceId: Id]: Slice};
43
43
  */
44
44
  export type Slice = Ids;
45
45
 
46
- /**
47
- * The SortKey type represents a value that can be used by a sort function.
48
- *
49
- * @category Parameter
50
- */
51
- export type SortKey = string | number | boolean;
52
-
53
46
  /**
54
47
  * The SliceIdsListener type describes a function that is used to listen to
55
48
  * changes to the Slice Ids in an Index.
@@ -779,51 +772,3 @@ export interface Indexes {
779
772
  * @category Creation
780
773
  */
781
774
  export function createIndexes(store: Store): Indexes;
782
-
783
- /**
784
- * The defaultSorter function is provided as a convenience to sort keys
785
- * alphanumerically, and can be provided to the `sliceIdSorter` and
786
- * `rowIdSorter` parameters of the setIndexDefinition method, for example.
787
- *
788
- * @param sortKey1 The first item of the pair to compare.
789
- * @param sortKey2 The second item of the pair to compare.
790
- * @returns A number indicating how to sort the pair.
791
- * @example
792
- * This example creates an Indexes object.
793
- *
794
- * ```js
795
- * const store = createStore();
796
- * const indexes = createIndexes(store);
797
- * console.log(indexes.getIndexIds());
798
- * // -> []
799
- * ```
800
- * @example
801
- * This example creates a Store, creates an Indexes object, and defines an
802
- * Index based on the first letter of the pets' names. The Slice Ids (and Row
803
- * Ids within them) are alphabetically sorted using the defaultSorter function.
804
- *
805
- * ```js
806
- * const store = createStore().setTable('pets', {
807
- * fido: {species: 'dog'},
808
- * felix: {species: 'cat'},
809
- * cujo: {species: 'dog'},
810
- * });
811
- *
812
- * const indexes = createIndexes(store);
813
- * indexes.setIndexDefinition(
814
- * 'byFirst', // indexId
815
- * 'pets', // tableId
816
- * (_, rowId) => rowId[0], // each Row's Slice Id
817
- * (_, rowId) => rowId, // each Row's sort key
818
- * defaultSorter, // sort Slice Ids
819
- * defaultSorter, // sort Row Ids by sort key
820
- * );
821
- *
822
- * console.log(indexes.getSliceIds('byFirst'));
823
- * // -> ['c', 'f']
824
- * console.log(indexes.getSliceRowIds('byFirst', 'f'));
825
- * // -> ['felix', 'fido']
826
- * ```
827
- * @category Convenience
828
- */
829
- export function defaultSorter(sortKey1: SortKey, sortKey2: SortKey): number;
@@ -168,6 +168,8 @@ const getCreateFunction = (getFunction) => {
168
168
  };
169
169
  };
170
170
 
171
+ const defaultSorter = (sortKey1, sortKey2) => (sortKey1 < sortKey2 ? -1 : 1);
172
+
171
173
  const addDeepSet = (deepSet, value, ids) =>
172
174
  arrayLength(ids) < 2
173
175
  ? setAdd(
@@ -276,7 +278,7 @@ const createIndexes = getCreateFunction((store) => {
276
278
  setDefinition(
277
279
  indexId,
278
280
  tableId,
279
- (change, changedSliceIds, changedSortKeys, sliceIds, sortKeys) => {
281
+ (change, changedSliceIds, changedSortKeys, sliceIds, sortKeys, force) => {
280
282
  let sliceIdsChanged = 0;
281
283
  const changedSlices = setNew();
282
284
  const unsortedSlices = setNew();
@@ -305,12 +307,16 @@ const createIndexes = getCreateFunction((store) => {
305
307
  }
306
308
  });
307
309
  change();
308
- mapForEach(changedSortKeys, (rowId) =>
309
- ifNotUndefined(mapGet(sliceIds, rowId), (sliceId) =>
310
- setAdd(unsortedSlices, sliceId),
311
- ),
312
- );
313
310
  if (!collIsEmpty(sortKeys)) {
311
+ if (force) {
312
+ mapForEach(index, (sliceId) => setAdd(unsortedSlices, sliceId));
313
+ } else {
314
+ mapForEach(changedSortKeys, (rowId) =>
315
+ ifNotUndefined(mapGet(sliceIds, rowId), (sliceId) =>
316
+ setAdd(unsortedSlices, sliceId),
317
+ ),
318
+ );
319
+ }
314
320
  collForEach(unsortedSlices, (sliceId) => {
315
321
  const rowIdArraySorter = (rowId1, rowId2) =>
316
322
  rowIdSorter(
@@ -329,7 +335,7 @@ const createIndexes = getCreateFunction((store) => {
329
335
  }
330
336
  });
331
337
  }
332
- if (sliceIdsChanged) {
338
+ if (sliceIdsChanged || force) {
333
339
  if (!isUndefined(sliceIdArraySorter)) {
334
340
  const indexArray = [...index];
335
341
  if (!arrayIsSorted(indexArray, sliceIdArraySorter)) {
@@ -337,8 +343,11 @@ const createIndexes = getCreateFunction((store) => {
337
343
  indexId,
338
344
  mapNew(arraySort(indexArray, sliceIdArraySorter)),
339
345
  );
346
+ sliceIdsChanged = 1;
340
347
  }
341
348
  }
349
+ }
350
+ if (sliceIdsChanged) {
342
351
  callListeners(sliceIdsListeners, [indexId]);
343
352
  }
344
353
  collForEach(changedSlices, (sliceId) =>
@@ -385,6 +394,5 @@ const createIndexes = getCreateFunction((store) => {
385
394
  };
386
395
  return objFreeze(indexes);
387
396
  });
388
- const defaultSorter = (sortKey1, sortKey2) => (sortKey1 < sortKey2 ? -1 : 1);
389
397
 
390
- export {createIndexes, defaultSorter};
398
+ export {createIndexes};
@@ -3,8 +3,8 @@
3
3
  * and track metrics and aggregates of the data in Store objects.
4
4
  *
5
5
  * The main entry point to this module is the createMetrics function, which
6
- * returns a new Metrics object. From there, you can create new metric
7
- * definitions, access the values of those metrics directly, and register
6
+ * returns a new Metrics object. From there, you can create new Metric
7
+ * definitions, access the values of those Metrics directly, and register
8
8
  * listeners for when they change.
9
9
  *
10
10
  * @packageDocumentation
@@ -1,6 +1,6 @@
1
1
  /**
2
- * The persisters module of the TinyBase project provides a simple framework
3
- * for saving and loading Store data, to and from different destinations, or
2
+ * The persisters module of the TinyBase project provides a simple framework for
3
+ * saving and loading Store data, to and from different destinations, or
4
4
  * underlying storage types.
5
5
  *
6
6
  * Several entry points are provided, each of which returns a new Persister
@@ -24,7 +24,7 @@
24
24
  */
25
25
 
26
26
  import {Store, Tables} from './store.d';
27
- import {Callback} from './common';
27
+ import {Callback} from './common.d';
28
28
 
29
29
  /**
30
30
  * The PersisterStats type describes the number of times a Persister object has
@@ -243,6 +243,7 @@ export interface Persister {
243
243
  * console.log(store.getTables());
244
244
  * // -> {pets: {toto: {species: 'dog'}}}
245
245
  *
246
+ * persister.destroy();
246
247
  * sessionStorage.clear();
247
248
  * ```
248
249
  * @category Load
@@ -284,6 +285,7 @@ export interface Persister {
284
285
  * // -> {pets: {toto: {species: 'dog'}}}
285
286
  * // Storage change has not been automatically loaded.
286
287
  *
288
+ * persister.destroy();
287
289
  * sessionStorage.clear();
288
290
  * ```
289
291
  * @category Load
@@ -650,8 +652,9 @@ export function createFilePersister(store: Store, filePath: string): Persister;
650
652
  * layer.
651
653
  *
652
654
  * The other creation functions (such as the createSessionPersister function and
653
- * createFilePersister function, for example) all use this under the covers. See
654
- * those implementations for ideas on how to implement your own Persister types.
655
+ * createFilePersister function, for example) all use this function under the
656
+ * covers. See those implementations for ideas on how to implement your own
657
+ * Persister types.
655
658
  *
656
659
  * @param store The Store to persist.
657
660
  * @param getPersisted An asynchronous function which will fetch JSON from the
@@ -664,9 +667,9 @@ export function createFilePersister(store: Store, filePath: string): Persister;
664
667
  * from the underlying changes to the persistence layer.
665
668
  * @returns A reference to the new Persister object.
666
669
  * @example
667
- * This example creates a Persister object and persists the Store to a local
668
- * string called `storeJson` and would automatically load by polling for changes
669
- * every second.
670
+ * This example creates a custom Persister object and persists the Store to a
671
+ * local string called `storeJson` and which would automatically load by polling
672
+ * for changes every second.
670
673
  *
671
674
  * ```js
672
675
  * const store = createStore().setTables({pets: {fido: {species: 'dog'}}});
@@ -4,7 +4,7 @@
4
4
  *
5
5
  * The main entry point to this module is the createRelationships function,
6
6
  * which returns a new Relationships object. From there, you can create new
7
- * relationship definitions, access the associations within those relationships
7
+ * Relationship definitions, access the associations within those Relationships
8
8
  * directly, and register listeners for when they change.
9
9
  *
10
10
  * @packageDocumentation
@@ -17,11 +17,10 @@ import {Id, IdOrNull, Ids, Json} from './common.d';
17
17
  * The Tables type is the data structure representing all of the data in a
18
18
  * Store.
19
19
  *
20
- * A Tables object can be provided to the createStore function when first
21
- * creating the Store. It is also used when setting all of the tables together
22
- * with the setTables method, and when getting them back out again with the
23
- * getTables method. A Tables object is a regular JavaScript object containing
24
- * individual Table objects, keyed by their Id.
20
+ * A Tables object is used when setting all of the tables together with the
21
+ * setTables method, and when getting them back out again with the getTables
22
+ * method. A Tables object is a regular JavaScript object containing individual
23
+ * Table objects, keyed by their Id.
25
24
  *
26
25
  * @example
27
26
  * ```js
@@ -371,8 +370,8 @@ export type CellChange = [
371
370
  * Ids and the types of Cell that can exist within them.
372
371
  *
373
372
  * A Schema comprises a JavaScript object describing each Table, in turn a
374
- * nested JavaScript object containing the each Cell and its CellSchema. It is
375
- * provided to the createStore function or to the setSchema method.
373
+ * nested JavaScript object containing information about each Cell and its
374
+ * CellSchema. It is provided to the setSchema method.
376
375
  *
377
376
  * @example
378
377
  * When applied to a Store, this Schema only allows one Table called `pets`, in
@@ -1339,9 +1338,8 @@ export interface Store {
1339
1338
  * applied or as invalid Table, Row, or Cell objects are removed. These
1340
1339
  * changes will fire any listeners to that data, as expected.
1341
1340
  *
1342
- * You can also specify the Schema at the time of creation, as the second
1343
- * parameter of the createStore function. When no longer needed, you can also
1344
- * completely remove an existing Schema with the delSchema method.
1341
+ * When no longer needed, you can also completely remove an existing Schema
1342
+ * with the delSchema method.
1345
1343
  *
1346
1344
  * @param schema The Schema to be set for the Store.
1347
1345
  * @returns A reference to the Store.
@@ -509,6 +509,8 @@ const createCheckpoints = getCreateFunction((store) => {
509
509
  return objFreeze(checkpoints.clear());
510
510
  });
511
511
 
512
+ const defaultSorter = (sortKey1, sortKey2) => (sortKey1 < sortKey2 ? -1 : 1);
513
+
512
514
  const createIndexes = getCreateFunction((store) => {
513
515
  const sliceIdsListeners = mapNew();
514
516
  const sliceRowIdsListeners = mapNew();
@@ -541,7 +543,7 @@ const createIndexes = getCreateFunction((store) => {
541
543
  setDefinition(
542
544
  indexId,
543
545
  tableId,
544
- (change, changedSliceIds, changedSortKeys, sliceIds, sortKeys) => {
546
+ (change, changedSliceIds, changedSortKeys, sliceIds, sortKeys, force) => {
545
547
  let sliceIdsChanged = 0;
546
548
  const changedSlices = setNew();
547
549
  const unsortedSlices = setNew();
@@ -570,12 +572,16 @@ const createIndexes = getCreateFunction((store) => {
570
572
  }
571
573
  });
572
574
  change();
573
- mapForEach(changedSortKeys, (rowId) =>
574
- ifNotUndefined(mapGet(sliceIds, rowId), (sliceId) =>
575
- setAdd(unsortedSlices, sliceId),
576
- ),
577
- );
578
575
  if (!collIsEmpty(sortKeys)) {
576
+ if (force) {
577
+ mapForEach(index, (sliceId) => setAdd(unsortedSlices, sliceId));
578
+ } else {
579
+ mapForEach(changedSortKeys, (rowId) =>
580
+ ifNotUndefined(mapGet(sliceIds, rowId), (sliceId) =>
581
+ setAdd(unsortedSlices, sliceId),
582
+ ),
583
+ );
584
+ }
579
585
  collForEach(unsortedSlices, (sliceId) => {
580
586
  const rowIdArraySorter = (rowId1, rowId2) =>
581
587
  rowIdSorter(
@@ -594,7 +600,7 @@ const createIndexes = getCreateFunction((store) => {
594
600
  }
595
601
  });
596
602
  }
597
- if (sliceIdsChanged) {
603
+ if (sliceIdsChanged || force) {
598
604
  if (!isUndefined(sliceIdArraySorter)) {
599
605
  const indexArray = [...index];
600
606
  if (!arrayIsSorted(indexArray, sliceIdArraySorter)) {
@@ -602,8 +608,11 @@ const createIndexes = getCreateFunction((store) => {
602
608
  indexId,
603
609
  mapNew(arraySort(indexArray, sliceIdArraySorter)),
604
610
  );
611
+ sliceIdsChanged = 1;
605
612
  }
606
613
  }
614
+ }
615
+ if (sliceIdsChanged) {
607
616
  callListeners(sliceIdsListeners, [indexId]);
608
617
  }
609
618
  collForEach(changedSlices, (sliceId) =>
@@ -650,7 +659,6 @@ const createIndexes = getCreateFunction((store) => {
650
659
  };
651
660
  return objFreeze(indexes);
652
661
  });
653
- const defaultSorter = (sortKey1, sortKey2) => (sortKey1 < sortKey2 ? -1 : 1);
654
662
 
655
663
  const aggregators = mapNew([
656
664
  [
@@ -14,7 +14,7 @@
14
14
  * @module ui-react
15
15
  */
16
16
 
17
- import {Callback, Id, IdOrNull, Ids, ParameterizedCallback} from './common';
17
+ import {Callback, Id, IdOrNull, Ids, ParameterizedCallback} from './common.d';
18
18
  import {
19
19
  Cell,
20
20
  CellIdsListener,
@@ -2213,6 +2213,9 @@ export function useCellListener(
2213
2213
  * an array in the optional second parameter, just as you would for any React
2214
2214
  * hook with dependencies.
2215
2215
  *
2216
+ * This hook ensures the Metrics object is destroyed whenever a new one is
2217
+ * created or the component is unmounted.
2218
+ *
2216
2219
  * @param store A reference to the Store for which to create a new Metrics
2217
2220
  * object.
2218
2221
  * @param create A function for performing the creation steps of the Metrics
@@ -2554,6 +2557,9 @@ export function useMetricListener(
2554
2557
  * an array in the optional second parameter, just as you would for any React
2555
2558
  * hook with dependencies.
2556
2559
  *
2560
+ * This hook ensures the Indexes object is destroyed whenever a new one is
2561
+ * created or the component is unmounted.
2562
+ *
2557
2563
  * @param store A reference to the Store for which to create a new Indexes
2558
2564
  * object.
2559
2565
  * @param create A function for performing the creation steps of the Indexes
@@ -3104,6 +3110,9 @@ export function useSliceRowIdsListener(
3104
3110
  * them in an array in the optional second parameter, just as you would for any
3105
3111
  * React hook with dependencies.
3106
3112
  *
3113
+ * This hook ensures the Relationships object is destroyed whenever a new one is
3114
+ * created or the component is unmounted.
3115
+ *
3107
3116
  * @param store A reference to the Store for which to create a new Relationships
3108
3117
  * object.
3109
3118
  * @param create An optional callback for performing post-creation steps on the
@@ -3900,6 +3909,9 @@ export function useLinkedRowIdsListener(
3900
3909
  * them in an array in the optional second parameter, just as you would for any
3901
3910
  * React hook with dependencies.
3902
3911
  *
3912
+ * This hook ensures the Checkpoints object is destroyed whenever a new one is
3913
+ * created or the component is unmounted.
3914
+ *
3903
3915
  * @param store A reference to the Store for which to create a new Checkpoints
3904
3916
  * object.
3905
3917
  * @param create A function for performing the creation steps of the Checkpoints
@@ -4751,6 +4763,9 @@ export function useCheckpointListener(
4751
4763
  * an array in the fifth parameter. The Persister itself is used as a dependency
4752
4764
  * by default.
4753
4765
  *
4766
+ * This hook ensures the Persister object is destroyed whenever a new one is
4767
+ * created or the component is unmounted.
4768
+ *
4754
4769
  * @param store A reference to the Store for which to create a new Persister
4755
4770
  * object.
4756
4771
  * @param create A function for performing the creation steps of the Persister
@@ -4795,10 +4810,12 @@ export function useCheckpointListener(
4795
4810
  *
4796
4811
  * // ... // !act
4797
4812
  * ReactDOM.render(<App />, app); // !act
4798
- * // No second Checkpoints creation
4813
+ * // No second Persister creation
4799
4814
  *
4800
4815
  * console.log(app.innerHTML);
4801
4816
  * // -> '<span>{\"pets\":{\"fido\":{\"species\":\"dog\"}}}</span>'
4817
+ *
4818
+ * ReactDOM.unmountComponentAtNode(app); // !act
4802
4819
  * ```
4803
4820
  * @example
4804
4821
  * This example creates a Persister at the top level of a React application. The
@@ -4841,6 +4858,8 @@ export function useCheckpointListener(
4841
4858
  * // ... // !act
4842
4859
  * console.log(app.innerHTML);
4843
4860
  * // -> '<span>{\"pets\":{\"cujo\":{\"species\":\"dog\"}}}</span>'
4861
+ *
4862
+ * ReactDOM.unmountComponentAtNode(app); // !act
4844
4863
  * ```
4845
4864
  * @category Persister hooks
4846
4865
  */
@@ -48,8 +48,11 @@ const useCheckpointsOrCheckpointsId = (checkpointsOrCheckpointsId) =>
48
48
  useThingOrThingId(checkpointsOrCheckpointsId, 8);
49
49
 
50
50
  const {useCallback, useEffect, useMemo: useMemo$1, useState} = React;
51
- const useCreate = (store, create, createDeps = []) =>
52
- useMemo$1(() => create(store), [store, ...createDeps]);
51
+ const useCreate = (store, create, createDeps = []) => {
52
+ const thing = useMemo$1(() => create(store), [store, ...createDeps]);
53
+ useEffect(() => () => thing.destroy(), [thing]);
54
+ return thing;
55
+ };
53
56
  const useListenable = (listenable, thing, defaulted, ...args) => {
54
57
  const getListenable = thing?.['get' + listenable] ?? (() => defaulted);
55
58
  const immediateListenable = getListenable(...args);
@@ -654,6 +657,9 @@ const useCreatePersister = (
654
657
  setDone(1);
655
658
  return;
656
659
  })();
660
+ return () => {
661
+ persister.destroy();
662
+ };
657
663
  }, [persister, ...thenDeps]);
658
664
  return persister;
659
665
  };
package/lib/indexes.d.ts CHANGED
@@ -3,8 +3,8 @@
3
3
  * and track indexes of the data in Store objects.
4
4
  *
5
5
  * The main entry point to this module is the createIndexes function, which
6
- * returns a new Indexes object. From there, you can create new index
7
- * definitions, access the contents of those indexes directly, and register
6
+ * returns a new Indexes object. From there, you can create new Index
7
+ * definitions, access the contents of those Indexes directly, and register
8
8
  * listeners for when they change.
9
9
  *
10
10
  * @packageDocumentation
@@ -12,7 +12,7 @@
12
12
  */
13
13
 
14
14
  import {GetCell, Store} from './store.d';
15
- import {Id, IdOrNull, Ids} from './common.d';
15
+ import {Id, IdOrNull, Ids, SortKey} from './common.d';
16
16
 
17
17
  /**
18
18
  * The Index type represents the concept of a map of Slice objects, keyed by Id.
@@ -43,13 +43,6 @@ export type Index = {[sliceId: Id]: Slice};
43
43
  */
44
44
  export type Slice = Ids;
45
45
 
46
- /**
47
- * The SortKey type represents a value that can be used by a sort function.
48
- *
49
- * @category Parameter
50
- */
51
- export type SortKey = string | number | boolean;
52
-
53
46
  /**
54
47
  * The SliceIdsListener type describes a function that is used to listen to
55
48
  * changes to the Slice Ids in an Index.
@@ -779,51 +772,3 @@ export interface Indexes {
779
772
  * @category Creation
780
773
  */
781
774
  export function createIndexes(store: Store): Indexes;
782
-
783
- /**
784
- * The defaultSorter function is provided as a convenience to sort keys
785
- * alphanumerically, and can be provided to the `sliceIdSorter` and
786
- * `rowIdSorter` parameters of the setIndexDefinition method, for example.
787
- *
788
- * @param sortKey1 The first item of the pair to compare.
789
- * @param sortKey2 The second item of the pair to compare.
790
- * @returns A number indicating how to sort the pair.
791
- * @example
792
- * This example creates an Indexes object.
793
- *
794
- * ```js
795
- * const store = createStore();
796
- * const indexes = createIndexes(store);
797
- * console.log(indexes.getIndexIds());
798
- * // -> []
799
- * ```
800
- * @example
801
- * This example creates a Store, creates an Indexes object, and defines an
802
- * Index based on the first letter of the pets' names. The Slice Ids (and Row
803
- * Ids within them) are alphabetically sorted using the defaultSorter function.
804
- *
805
- * ```js
806
- * const store = createStore().setTable('pets', {
807
- * fido: {species: 'dog'},
808
- * felix: {species: 'cat'},
809
- * cujo: {species: 'dog'},
810
- * });
811
- *
812
- * const indexes = createIndexes(store);
813
- * indexes.setIndexDefinition(
814
- * 'byFirst', // indexId
815
- * 'pets', // tableId
816
- * (_, rowId) => rowId[0], // each Row's Slice Id
817
- * (_, rowId) => rowId, // each Row's sort key
818
- * defaultSorter, // sort Slice Ids
819
- * defaultSorter, // sort Row Ids by sort key
820
- * );
821
- *
822
- * console.log(indexes.getSliceIds('byFirst'));
823
- * // -> ['c', 'f']
824
- * console.log(indexes.getSliceRowIds('byFirst', 'f'));
825
- * // -> ['felix', 'fido']
826
- * ```
827
- * @category Convenience
828
- */
829
- export function defaultSorter(sortKey1: SortKey, sortKey2: SortKey): number;