tinybase 1.1.0-beta.1 → 1.2.0-beta.1
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/debug/metrics.d.ts +1 -1
- package/lib/debug/store.d.ts +220 -8
- package/lib/debug/store.js +137 -96
- package/lib/debug/tinybase.js +137 -96
- package/lib/metrics.d.ts +1 -1
- package/lib/store.d.ts +220 -8
- package/lib/store.js +1 -1
- package/lib/store.js.gz +0 -0
- package/lib/tinybase.js +1 -1
- package/lib/tinybase.js.gz +0 -0
- package/lib/umd/store.js +1 -1
- package/lib/umd/store.js.gz +0 -0
- package/lib/umd/tinybase.js +1 -1
- package/lib/umd/tinybase.js.gz +0 -0
- package/package.json +18 -17
- package/readme.md +2 -2
package/lib/debug/metrics.d.ts
CHANGED
|
@@ -37,7 +37,7 @@ export type Metric = number;
|
|
|
37
37
|
export type MetricCallback = (metricId: Id, metric?: Metric) => void;
|
|
38
38
|
|
|
39
39
|
/**
|
|
40
|
-
* The Aggregate type describes a custom function that takes an array
|
|
40
|
+
* The Aggregate type describes a custom function that takes an array of numbers
|
|
41
41
|
* and returns an aggregate that is used as a Metric.
|
|
42
42
|
*
|
|
43
43
|
* There are a number of common predefined aggregators, such as for counting,
|
package/lib/debug/store.d.ts
CHANGED
|
@@ -88,6 +88,18 @@ export type Row = {[cellId: Id]: Cell};
|
|
|
88
88
|
*/
|
|
89
89
|
export type Cell = string | number | boolean;
|
|
90
90
|
|
|
91
|
+
/**
|
|
92
|
+
* The CellOrUndefined type is a data structure representing the data in a
|
|
93
|
+
* single cell or the value `undefined`.
|
|
94
|
+
*
|
|
95
|
+
* This is used when describing a Cell that is present _or_ that is not present
|
|
96
|
+
* - such as when it has been deleted, or when describing a previous state where
|
|
97
|
+
* the Cell value has since been added.
|
|
98
|
+
*
|
|
99
|
+
* @category Store
|
|
100
|
+
*/
|
|
101
|
+
export type CellOrUndefined = Cell | undefined;
|
|
102
|
+
|
|
91
103
|
/**
|
|
92
104
|
* The TableCallback type describes a function that takes a Table's Id and a
|
|
93
105
|
* callback to loop over each Row within it.
|
|
@@ -149,7 +161,7 @@ export type CellCallback = (cellId: Id, cell: Cell) => void;
|
|
|
149
161
|
* @param cell The current value of the Cell to map to a new value.
|
|
150
162
|
* @category Callback
|
|
151
163
|
*/
|
|
152
|
-
export type MapCell = (cell:
|
|
164
|
+
export type MapCell = (cell: CellOrUndefined) => Cell;
|
|
153
165
|
|
|
154
166
|
/**
|
|
155
167
|
* The GetCell type describes a function that takes a Id and returns the Cell
|
|
@@ -162,7 +174,7 @@ export type MapCell = (cell: Cell | undefined) => Cell;
|
|
|
162
174
|
* @param cellId The Id of the Cell to fetch the value for.
|
|
163
175
|
* @category Callback
|
|
164
176
|
*/
|
|
165
|
-
export type GetCell = (cellId: Id) =>
|
|
177
|
+
export type GetCell = (cellId: Id) => CellOrUndefined;
|
|
166
178
|
|
|
167
179
|
/**
|
|
168
180
|
* The TablesListener type describes a function that is used to listen to
|
|
@@ -390,8 +402,8 @@ export type GetCellChange = (tableId: Id, rowId: Id, cellId: Id) => CellChange;
|
|
|
390
402
|
*/
|
|
391
403
|
export type CellChange = [
|
|
392
404
|
changed: boolean,
|
|
393
|
-
oldCell:
|
|
394
|
-
newCell:
|
|
405
|
+
oldCell: CellOrUndefined,
|
|
406
|
+
newCell: CellOrUndefined,
|
|
395
407
|
];
|
|
396
408
|
|
|
397
409
|
/**
|
|
@@ -461,6 +473,59 @@ export type CellSchema =
|
|
|
461
473
|
default?: boolean;
|
|
462
474
|
};
|
|
463
475
|
|
|
476
|
+
/**
|
|
477
|
+
* The ChangedCells type describes the Cell values that have been changed during
|
|
478
|
+
* a transaction, primarily used so that you can indicate whether the
|
|
479
|
+
* transaction should be rolled back.
|
|
480
|
+
*
|
|
481
|
+
* A ChangedCells object is provided to the `doRollback` callback when using the
|
|
482
|
+
* transaction method. See that method for specific examples.
|
|
483
|
+
*
|
|
484
|
+
* This type is a nested structure of Table, Row, and Cell objects, much like
|
|
485
|
+
* the Tables object, but one which provides both the old and new Cell values in
|
|
486
|
+
* a two-part array. These are describing the state of each changed Cell in
|
|
487
|
+
* Store at the _start_ of the transaction, and by the _end_ of the transaction.
|
|
488
|
+
*
|
|
489
|
+
* Hence, an `undefined` value for the first item in the array means that the
|
|
490
|
+
* Cell was added during the transaction. An `undefined` value for the second
|
|
491
|
+
* item in the array means that the Cell was removed during the transaction. An
|
|
492
|
+
* array with two different Cell values indicates that it was changed. The
|
|
493
|
+
* two-part array will never contain two items of the same value (including two
|
|
494
|
+
* `undefined` values), even if, during the transaction, a Cell was changed to a
|
|
495
|
+
* different value and then changed back.
|
|
496
|
+
*
|
|
497
|
+
* @category Transaction
|
|
498
|
+
*/
|
|
499
|
+
export type ChangedCells = {
|
|
500
|
+
[tableId: Id]: {
|
|
501
|
+
[rowId: Id]: {
|
|
502
|
+
[cellId: Id]: [CellOrUndefined, CellOrUndefined];
|
|
503
|
+
};
|
|
504
|
+
};
|
|
505
|
+
};
|
|
506
|
+
/**
|
|
507
|
+
* The InvalidCells type describes the invalid Cell values that have been
|
|
508
|
+
* attempted during a transaction, primarily used so that you can indicate
|
|
509
|
+
* whether the transaction should be rolled back.
|
|
510
|
+
*
|
|
511
|
+
* An InvalidCells object is provided to the `doRollback` callback when using
|
|
512
|
+
* the transaction method. See that method for specific examples.
|
|
513
|
+
*
|
|
514
|
+
* This type is a nested structure of Table, Row, and Cell objects, much like
|
|
515
|
+
* the Tables object, but one for which Cell values are listed in array
|
|
516
|
+
* (much like the InvalidCellListener type) so that multiple failed attempts to
|
|
517
|
+
* change a Cell during the transaction are described.
|
|
518
|
+
*
|
|
519
|
+
* @category Transaction
|
|
520
|
+
*/
|
|
521
|
+
export type InvalidCells = {
|
|
522
|
+
[tableId: Id]: {
|
|
523
|
+
[rowId: Id]: {
|
|
524
|
+
[cellId: Id]: any[];
|
|
525
|
+
};
|
|
526
|
+
};
|
|
527
|
+
};
|
|
528
|
+
|
|
464
529
|
/**
|
|
465
530
|
* The StoreListenerStats type describes the number of listeners registered with
|
|
466
531
|
* the Store, and can be used for debugging purposes.
|
|
@@ -897,7 +962,7 @@ export interface Store {
|
|
|
897
962
|
* ```
|
|
898
963
|
* @category Getter
|
|
899
964
|
*/
|
|
900
|
-
getCell(tableId: Id, rowId: Id, cellId: Id):
|
|
965
|
+
getCell(tableId: Id, rowId: Id, cellId: Id): CellOrUndefined;
|
|
901
966
|
|
|
902
967
|
/**
|
|
903
968
|
* The hasTables method returns a boolean indicating whether any Table objects
|
|
@@ -1603,7 +1668,15 @@ export interface Store {
|
|
|
1603
1668
|
* Transactions can be nested. Relevant listeners will be called only when the
|
|
1604
1669
|
* outermost one completes.
|
|
1605
1670
|
*
|
|
1671
|
+
* The second, optional parameter, `doRollback` is a callback that you can use
|
|
1672
|
+
* to rollback the transaction if it did not complete to your satisfaction. It
|
|
1673
|
+
* is called with `changedCells` and `invalidCells` parameters, which inform
|
|
1674
|
+
* you of the net changes that have been made during the transaction, and any
|
|
1675
|
+
* invalid attempts to do so, respectively.
|
|
1676
|
+
*
|
|
1606
1677
|
* @param actions The function to be executed as a transaction.
|
|
1678
|
+
* @param doRollback An optional callback that should return `true` if you
|
|
1679
|
+
* want to rollback the transaction at the end.
|
|
1607
1680
|
* @returns Whatever value the provided transaction function returns.
|
|
1608
1681
|
* @example
|
|
1609
1682
|
* This example makes changes to two Cells, first outside, and secondly
|
|
@@ -1653,9 +1726,46 @@ export interface Store {
|
|
|
1653
1726
|
* // -> undefined
|
|
1654
1727
|
* // No net change during the transaction, so the listener is not called.
|
|
1655
1728
|
* ```
|
|
1656
|
-
* @
|
|
1729
|
+
* @example
|
|
1730
|
+
* This example makes multiple changes to the Store, including some attempts
|
|
1731
|
+
* to update a Cell with invalid values. The `doRollback` callback receives
|
|
1732
|
+
* information about the changes and invalid attempts, and then judges that
|
|
1733
|
+
* the transaction should be rolled back to its original state.
|
|
1734
|
+
*
|
|
1735
|
+
* ```js
|
|
1736
|
+
* const store = createStore().setTables({
|
|
1737
|
+
* pets: {fido: {species: 'dog', color: 'brown'}},
|
|
1738
|
+
* });
|
|
1739
|
+
*
|
|
1740
|
+
* store.transaction(
|
|
1741
|
+
* () => {
|
|
1742
|
+
* store.setCell('pets', 'fido', 'color', 'black');
|
|
1743
|
+
* store.setCell('pets', 'fido', 'eyes', ['left', 'right']);
|
|
1744
|
+
* store.setCell('pets', 'fido', 'info', {sold: null});
|
|
1745
|
+
* },
|
|
1746
|
+
* (changedCells, invalidCells) => {
|
|
1747
|
+
* console.log(store.getTables());
|
|
1748
|
+
* // -> {pets: {fido: {species: 'dog', color: 'black'}}}
|
|
1749
|
+
* console.log(changedCells);
|
|
1750
|
+
* // -> {pets: {fido: {color: ['brown', 'black']}}}
|
|
1751
|
+
* console.log(invalidCells);
|
|
1752
|
+
* // -> {pets: {fido: {eyes: [['left', 'right']], info: [{sold: null}]}}}
|
|
1753
|
+
* return invalidCells['pets'] != null;
|
|
1754
|
+
* },
|
|
1755
|
+
* );
|
|
1756
|
+
*
|
|
1757
|
+
* console.log(store.getTables());
|
|
1758
|
+
* // -> {pets: {fido: {species: 'dog', color: 'brown'}}}
|
|
1759
|
+
* ```
|
|
1760
|
+
* @category Transaction
|
|
1657
1761
|
*/
|
|
1658
|
-
transaction<Return>(
|
|
1762
|
+
transaction<Return>(
|
|
1763
|
+
actions: () => Return,
|
|
1764
|
+
doRollback?: (
|
|
1765
|
+
changedCells: ChangedCells,
|
|
1766
|
+
invalidCells: InvalidCells,
|
|
1767
|
+
) => boolean,
|
|
1768
|
+
): Return;
|
|
1659
1769
|
|
|
1660
1770
|
/**
|
|
1661
1771
|
* The forEachTable method takes a function that it will then call for each
|
|
@@ -2433,6 +2543,21 @@ export interface Store {
|
|
|
2433
2543
|
* The changes made by mutator listeners do not fire other mutating listeners,
|
|
2434
2544
|
* though they will fire non-mutator listeners.
|
|
2435
2545
|
*
|
|
2546
|
+
* Special note should be made for how the listener will be called when a
|
|
2547
|
+
* Schema is present. The listener will be called:
|
|
2548
|
+
*
|
|
2549
|
+
* - if a Table is being updated that is not specified in the Schema
|
|
2550
|
+
* - if a Cell is of the wrong type specified in the Schema
|
|
2551
|
+
* - if a Cell is omitted and is not defaulted in the Schema
|
|
2552
|
+
* - if an empty Row is provided and there are no Cell defaults in the Schema
|
|
2553
|
+
*
|
|
2554
|
+
* The listener will not be called if Cell that is defaulted in the Schema is
|
|
2555
|
+
* not provided, as long as all of the Cells that are _not_ defaulted _are_
|
|
2556
|
+
* provided.
|
|
2557
|
+
*
|
|
2558
|
+
* To help understand all of these schema-based conditions, please see the
|
|
2559
|
+
* Schema example below.
|
|
2560
|
+
*
|
|
2436
2561
|
* @param tableId The Id of the Table to listen to, or `null` as a wildcard.
|
|
2437
2562
|
* @param rowId The Id of the Row to listen to, or `null` as a wildcard.
|
|
2438
2563
|
* @param cellId The Id of the Cell to listen to, or `null` as a wildcard.
|
|
@@ -2468,7 +2593,9 @@ export interface Store {
|
|
|
2468
2593
|
* ```
|
|
2469
2594
|
* @example
|
|
2470
2595
|
* This example registers a listener that responds to any invalid changes to
|
|
2471
|
-
* any Cell.
|
|
2596
|
+
* any Cell - in a Store _without_ a Schema. Note also how it then responds to
|
|
2597
|
+
* cases where an empty or invalid Row objects, or Table objects, or Tables
|
|
2598
|
+
* objects are provided.
|
|
2472
2599
|
*
|
|
2473
2600
|
* ```js
|
|
2474
2601
|
* const store = createStore().setTables({
|
|
@@ -2490,6 +2617,91 @@ export interface Store {
|
|
|
2490
2617
|
* store.setTable('sales', {fido: {date: new Date()}});
|
|
2491
2618
|
* // -> 'Invalid date cell in fido row in sales table'
|
|
2492
2619
|
*
|
|
2620
|
+
* store.setRow('pets', 'felix', {});
|
|
2621
|
+
* // -> 'Invalid undefined cell in felix row in pets table'
|
|
2622
|
+
*
|
|
2623
|
+
* store.setRow('filter', 'name', /[a-z]?/);
|
|
2624
|
+
* // -> 'Invalid undefined cell in name row in filter table'
|
|
2625
|
+
*
|
|
2626
|
+
* store.setRow('sales', '2021', {forecast: undefined});
|
|
2627
|
+
* // -> 'Invalid forecast cell in 2021 row in sales table'
|
|
2628
|
+
*
|
|
2629
|
+
* store.addRow('filter', /[0-9]?/);
|
|
2630
|
+
* // -> 'Invalid undefined cell in undefined row in filter table'
|
|
2631
|
+
*
|
|
2632
|
+
* store.setTable('raw', {});
|
|
2633
|
+
* // -> 'Invalid undefined cell in undefined row in raw table'
|
|
2634
|
+
*
|
|
2635
|
+
* store.setTable('raw', ['row1', 'row2']);
|
|
2636
|
+
* // -> 'Invalid undefined cell in undefined row in raw table'
|
|
2637
|
+
*
|
|
2638
|
+
* store.setTables(['table1', 'table2']);
|
|
2639
|
+
* // -> 'Invalid undefined cell in undefined row in undefined table'
|
|
2640
|
+
*
|
|
2641
|
+
* store.delListener(listenerId);
|
|
2642
|
+
* ```
|
|
2643
|
+
* @example
|
|
2644
|
+
* This example registers a listener that responds to any invalid changes to
|
|
2645
|
+
* any Cell - in a Store _with_ a Schema. Note how it responds to cases where
|
|
2646
|
+
* missing parameters are provided for optional, and defaulted Cell values in
|
|
2647
|
+
* a Row.
|
|
2648
|
+
*
|
|
2649
|
+
* ```js
|
|
2650
|
+
* const store = createStore().setSchema({
|
|
2651
|
+
* pets: {
|
|
2652
|
+
* species: {type: 'string'},
|
|
2653
|
+
* color: {type: 'string', default: 'unknown'},
|
|
2654
|
+
* },
|
|
2655
|
+
* });
|
|
2656
|
+
*
|
|
2657
|
+
* const listenerId = store.addInvalidCellListener(
|
|
2658
|
+
* null,
|
|
2659
|
+
* null,
|
|
2660
|
+
* null,
|
|
2661
|
+
* (store, tableId, rowId, cellId) => {
|
|
2662
|
+
* console.log(
|
|
2663
|
+
* `Invalid ${cellId} cell in ${rowId} row in ${tableId} table`,
|
|
2664
|
+
* );
|
|
2665
|
+
* },
|
|
2666
|
+
* );
|
|
2667
|
+
*
|
|
2668
|
+
* store.setRow('sales', 'fido', {price: 5});
|
|
2669
|
+
* // -> 'Invalid price cell in fido row in sales table'
|
|
2670
|
+
* // The listener is called, because the sales Table is not in the schema
|
|
2671
|
+
*
|
|
2672
|
+
* store.setRow('pets', 'felix', {species: true});
|
|
2673
|
+
* // -> 'Invalid species cell in felix row in pets table'
|
|
2674
|
+
* // The listener is called, because species is invalid...
|
|
2675
|
+
* console.log(store.getRow('pets', 'felix'));
|
|
2676
|
+
* // -> {color: 'unknown'}
|
|
2677
|
+
* // ...even though a Row was set with the default value
|
|
2678
|
+
*
|
|
2679
|
+
* store.setRow('pets', 'fido', {color: 'brown'});
|
|
2680
|
+
* // -> 'Invalid species cell in fido row in pets table'
|
|
2681
|
+
* // The listener is called, because species is missing and not defaulted...
|
|
2682
|
+
* console.log(store.getRow('pets', 'fido'));
|
|
2683
|
+
* // -> {color: 'brown'}
|
|
2684
|
+
* // ...even though a Row was set
|
|
2685
|
+
*
|
|
2686
|
+
* store.setRow('pets', 'rex', {species: 'dog'});
|
|
2687
|
+
* console.log(store.getRow('pets', 'rex'));
|
|
2688
|
+
* // -> {species: 'dog', color: 'unknown'}
|
|
2689
|
+
* // The listener is not called, because color is defaulted
|
|
2690
|
+
*
|
|
2691
|
+
* store.delTables().setSchema({
|
|
2692
|
+
* pets: {
|
|
2693
|
+
* species: {type: 'string'},
|
|
2694
|
+
* color: {type: 'string'},
|
|
2695
|
+
* },
|
|
2696
|
+
* });
|
|
2697
|
+
*
|
|
2698
|
+
* store.setRow('pets', 'cujo', {});
|
|
2699
|
+
* // -> 'Invalid species cell in cujo row in pets table'
|
|
2700
|
+
* // -> 'Invalid color cell in cujo row in pets table'
|
|
2701
|
+
* // -> 'Invalid undefined cell in cujo row in pets table'
|
|
2702
|
+
* // The listener is called multiple times, because neither Cell is defaulted
|
|
2703
|
+
* // and the Row as a whole is empty
|
|
2704
|
+
*
|
|
2493
2705
|
* store.delListener(listenerId);
|
|
2494
2706
|
* ```
|
|
2495
2707
|
* @example
|