tinybase 1.0.1 → 1.0.5
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/checkpoints.d.ts +66 -0
- package/lib/checkpoints.js +1 -1
- package/lib/checkpoints.js.gz +0 -0
- package/lib/debug/checkpoints.d.ts +66 -0
- package/lib/debug/checkpoints.js +8 -4
- package/lib/debug/indexes.d.ts +167 -6
- package/lib/debug/indexes.js +31 -0
- package/lib/debug/metrics.d.ts +72 -0
- package/lib/debug/metrics.js +8 -0
- package/lib/debug/relationships.d.ts +86 -1
- package/lib/debug/relationships.js +14 -0
- package/lib/debug/store.d.ts +28 -5
- package/lib/debug/store.js +2 -0
- package/lib/debug/tinybase.js +53 -4
- package/lib/indexes.d.ts +167 -6
- package/lib/indexes.js +1 -1
- package/lib/indexes.js.gz +0 -0
- package/lib/metrics.d.ts +72 -0
- package/lib/metrics.js +1 -1
- package/lib/metrics.js.gz +0 -0
- package/lib/relationships.d.ts +86 -1
- package/lib/relationships.js +1 -1
- package/lib/relationships.js.gz +0 -0
- package/lib/store.d.ts +28 -5
- 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/checkpoints.js +1 -1
- package/lib/umd/checkpoints.js.gz +0 -0
- package/lib/umd/indexes.js +1 -1
- package/lib/umd/indexes.js.gz +0 -0
- package/lib/umd/metrics.js +1 -1
- package/lib/umd/metrics.js.gz +0 -0
- package/lib/umd/relationships.js +1 -1
- package/lib/umd/relationships.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 -11
- package/readme.md +2 -2
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* @module relationships
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
import {GetCell, Store} from './store.d';
|
|
14
|
+
import {GetCell, RowCallback, Store} from './store.d';
|
|
15
15
|
import {Id, IdOrNull, Ids} from './common.d';
|
|
16
16
|
|
|
17
17
|
/**
|
|
@@ -39,6 +39,25 @@ export type Relationship = {
|
|
|
39
39
|
linkedRowIds: {[firstRowId: Id]: Ids};
|
|
40
40
|
};
|
|
41
41
|
|
|
42
|
+
/**
|
|
43
|
+
* The RelationshipCallback type describes a function that takes a
|
|
44
|
+
* Relationship's Id and a callback to loop over each local Row within it.
|
|
45
|
+
*
|
|
46
|
+
* A RelationshipCallback is provided when using the forEachRelationship method,
|
|
47
|
+
* so that you can do something based on every Relationship in the Relationships
|
|
48
|
+
* object. See that method for specific examples.
|
|
49
|
+
*
|
|
50
|
+
* @param relationshipId The Id of the Relationship that the callback can
|
|
51
|
+
* operate on.
|
|
52
|
+
* @param forEachRow A function that will let you iterate over the local Row
|
|
53
|
+
* objects in this Relationship.
|
|
54
|
+
* @category Callback
|
|
55
|
+
*/
|
|
56
|
+
export type RelationshipCallback = (
|
|
57
|
+
relationshipId: Id,
|
|
58
|
+
forEachRow: (rowCallback: RowCallback) => void,
|
|
59
|
+
) => void;
|
|
60
|
+
|
|
42
61
|
/**
|
|
43
62
|
* The RemoteRowIdListener type describes a function that is used to listen to
|
|
44
63
|
* changes to the remote Row Id end of a Relationship.
|
|
@@ -405,6 +424,72 @@ export interface Relationships {
|
|
|
405
424
|
*/
|
|
406
425
|
getRelationshipIds(): Ids;
|
|
407
426
|
|
|
427
|
+
/**
|
|
428
|
+
* The forEachRelationship method takes a function that it will then call for
|
|
429
|
+
* each Relationship in a specified Relationships object.
|
|
430
|
+
*
|
|
431
|
+
* This method is useful for iterating over the structure of the Relationships
|
|
432
|
+
* object in a functional style. The `relationshipCallback` parameter is a
|
|
433
|
+
* RelationshipCallback function that will be called with the Id of each
|
|
434
|
+
* Relationship, and with a function that can then be used to iterate over
|
|
435
|
+
* each local Row involved in the Relationship.
|
|
436
|
+
*
|
|
437
|
+
* @param relationshipCallback The function that should be called for every
|
|
438
|
+
* Relationship.
|
|
439
|
+
* @example
|
|
440
|
+
* This example iterates over each Relationship in a Relationships object, and
|
|
441
|
+
* lists each Row Id within them.
|
|
442
|
+
*
|
|
443
|
+
* ```js
|
|
444
|
+
* const store = createStore().setTable('pets', {
|
|
445
|
+
* fido: {species: 'dog', next: 'felix'},
|
|
446
|
+
* felix: {species: 'cat', next: 'cujo'},
|
|
447
|
+
* cujo: {species: 'dog'},
|
|
448
|
+
* });
|
|
449
|
+
* const relationships = createRelationships(store)
|
|
450
|
+
* .setRelationshipDefinition('petSpecies', 'pets', 'species', 'species')
|
|
451
|
+
* .setRelationshipDefinition('petSequence', 'pets', 'pets', 'next');
|
|
452
|
+
*
|
|
453
|
+
* relationships.forEachRelationship((relationshipId, forEachRow) => {
|
|
454
|
+
* console.log(relationshipId);
|
|
455
|
+
* forEachRow((rowId) => console.log(`- ${rowId}`));
|
|
456
|
+
* });
|
|
457
|
+
* // -> 'petSpecies'
|
|
458
|
+
* // -> '- fido'
|
|
459
|
+
* // -> '- felix'
|
|
460
|
+
* // -> '- cujo'
|
|
461
|
+
* // -> 'petSequence'
|
|
462
|
+
* // -> '- fido'
|
|
463
|
+
* // -> '- felix'
|
|
464
|
+
* // -> '- cujo'
|
|
465
|
+
* ```
|
|
466
|
+
* @category Iterator
|
|
467
|
+
*/
|
|
468
|
+
forEachRelationship(relationshipCallback: RelationshipCallback): void;
|
|
469
|
+
|
|
470
|
+
/**
|
|
471
|
+
* The hasRelationship method returns a boolean indicating whether a given
|
|
472
|
+
* Relationship exists in the Relationships object.
|
|
473
|
+
*
|
|
474
|
+
* @param relationshipId The Id of a possible Relationship in the
|
|
475
|
+
* Relationships object.
|
|
476
|
+
* @returns Whether a Relationship with that Id exists.
|
|
477
|
+
* @example
|
|
478
|
+
* This example shows two simple Relationship existence checks.
|
|
479
|
+
*
|
|
480
|
+
* ```js
|
|
481
|
+
* const relationships = createRelationships(
|
|
482
|
+
* createStore(),
|
|
483
|
+
* ).setRelationshipDefinition('petSpecies', 'pets', 'species', 'species');
|
|
484
|
+
* console.log(relationships.hasRelationship('petSpecies'));
|
|
485
|
+
* // -> true
|
|
486
|
+
* console.log(relationships.hasRelationship('petColor'));
|
|
487
|
+
* // -> false
|
|
488
|
+
* ```
|
|
489
|
+
* @category Getter
|
|
490
|
+
*/
|
|
491
|
+
hasRelationship(indexId: Id): boolean;
|
|
492
|
+
|
|
408
493
|
/**
|
|
409
494
|
* The getLocalTableId method returns the Id of the underlying local Table
|
|
410
495
|
* that is used in the Relationship.
|
|
@@ -52,6 +52,8 @@ const getDefinableFunctions = (store, getDefaultThing, validateRowValue) => {
|
|
|
52
52
|
const storeListenerIds = mapNew();
|
|
53
53
|
const getStore = () => store;
|
|
54
54
|
const getThingIds = () => mapKeys(tableIds);
|
|
55
|
+
const forEachThing = (cb) => mapForEach(things, cb);
|
|
56
|
+
const hasThing = (id) => collHas(things, id);
|
|
55
57
|
const getTableId = (id) => mapGet(tableIds, id);
|
|
56
58
|
const getThing = (id) => mapGet(things, id);
|
|
57
59
|
const setThing = (id, thing) => mapSet(things, id, thing);
|
|
@@ -141,6 +143,8 @@ const getDefinableFunctions = (store, getDefaultThing, validateRowValue) => {
|
|
|
141
143
|
return [
|
|
142
144
|
getStore,
|
|
143
145
|
getThingIds,
|
|
146
|
+
forEachThing,
|
|
147
|
+
hasThing,
|
|
144
148
|
getTableId,
|
|
145
149
|
getThing,
|
|
146
150
|
setThing,
|
|
@@ -247,6 +251,8 @@ const createRelationships = getCreateFunction((store) => {
|
|
|
247
251
|
const [
|
|
248
252
|
getStore,
|
|
249
253
|
getRelationshipIds,
|
|
254
|
+
forEachRelationshipImpl,
|
|
255
|
+
hasRelationship,
|
|
250
256
|
getLocalTableId,
|
|
251
257
|
getRelationship,
|
|
252
258
|
_setRelationship,
|
|
@@ -360,6 +366,12 @@ const createRelationships = getCreateFunction((store) => {
|
|
|
360
366
|
);
|
|
361
367
|
return relationships;
|
|
362
368
|
};
|
|
369
|
+
const forEachRelationship = (relationshipCallback) =>
|
|
370
|
+
forEachRelationshipImpl((relationshipId) =>
|
|
371
|
+
relationshipCallback(relationshipId, (rowCallback) =>
|
|
372
|
+
store.forEachRow(getLocalTableId(relationshipId), rowCallback),
|
|
373
|
+
),
|
|
374
|
+
);
|
|
363
375
|
const delRelationshipDefinition = (relationshipId) => {
|
|
364
376
|
mapSet(remoteTableIds, relationshipId);
|
|
365
377
|
delDefinition(relationshipId);
|
|
@@ -400,6 +412,8 @@ const createRelationships = getCreateFunction((store) => {
|
|
|
400
412
|
delRelationshipDefinition,
|
|
401
413
|
getStore,
|
|
402
414
|
getRelationshipIds,
|
|
415
|
+
forEachRelationship,
|
|
416
|
+
hasRelationship,
|
|
403
417
|
getLocalTableId,
|
|
404
418
|
getRemoteTableId,
|
|
405
419
|
getRemoteRowId,
|
package/lib/debug/store.d.ts
CHANGED
|
@@ -89,7 +89,7 @@ export type Row = {[cellId: Id]: Cell};
|
|
|
89
89
|
export type Cell = string | number | boolean;
|
|
90
90
|
|
|
91
91
|
/**
|
|
92
|
-
* The TableCallback type describes a function that takes a
|
|
92
|
+
* The TableCallback type describes a function that takes a Table's Id and a
|
|
93
93
|
* callback to loop over each Row within it.
|
|
94
94
|
*
|
|
95
95
|
* A TableCallback is provided when using the forEachTable method, so that you
|
|
@@ -867,6 +867,26 @@ export interface Store {
|
|
|
867
867
|
*/
|
|
868
868
|
getCell(tableId: Id, rowId: Id, cellId: Id): Cell | undefined;
|
|
869
869
|
|
|
870
|
+
/**
|
|
871
|
+
* The hasTables method returns a boolean indicating whether any Table objects
|
|
872
|
+
* exist in the Store.
|
|
873
|
+
*
|
|
874
|
+
* @returns Whether any Tables exist.
|
|
875
|
+
* @example
|
|
876
|
+
* This example shows simple existence checks.
|
|
877
|
+
*
|
|
878
|
+
* ```js
|
|
879
|
+
* const store = createStore();
|
|
880
|
+
* console.log(store.hasTables());
|
|
881
|
+
* // -> false
|
|
882
|
+
* store.setTables({pets: {fido: {species: 'dog'}}});
|
|
883
|
+
* console.log(store.hasTables());
|
|
884
|
+
* // -> true
|
|
885
|
+
* ```
|
|
886
|
+
* @category Getter
|
|
887
|
+
*/
|
|
888
|
+
hasTables(): boolean;
|
|
889
|
+
|
|
870
890
|
/**
|
|
871
891
|
* The hasTable method returns a boolean indicating whether a given Table
|
|
872
892
|
* exists in the Store.
|
|
@@ -1611,7 +1631,7 @@ export interface Store {
|
|
|
1611
1631
|
*
|
|
1612
1632
|
* This method is useful for iterating over the Table structure of the Store
|
|
1613
1633
|
* in a functional style. The `tableCallback` parameter is a TableCallback
|
|
1614
|
-
* function that will called with the Id of each Table, and with a function
|
|
1634
|
+
* function that will be called with the Id of each Table, and with a function
|
|
1615
1635
|
* that can then be used to iterate over each Row of the Table, should you
|
|
1616
1636
|
* wish.
|
|
1617
1637
|
*
|
|
@@ -1644,9 +1664,10 @@ export interface Store {
|
|
|
1644
1664
|
*
|
|
1645
1665
|
* This method is useful for iterating over the Row structure of the Table in
|
|
1646
1666
|
* a functional style. The `rowCallback` parameter is a RowCallback function
|
|
1647
|
-
* that will called with the Id of each Row, and with a function that can
|
|
1648
|
-
* be used to iterate over each Cell of the Row, should you wish.
|
|
1667
|
+
* that will be called with the Id of each Row, and with a function that can
|
|
1668
|
+
* then be used to iterate over each Cell of the Row, should you wish.
|
|
1649
1669
|
*
|
|
1670
|
+
* @param tableId The Id of the Table to iterate over.
|
|
1650
1671
|
* @param rowCallback The function that should be called for every Row.
|
|
1651
1672
|
* @example
|
|
1652
1673
|
* This example iterates over each Row in a Table, and lists each Cell Id
|
|
@@ -1678,8 +1699,10 @@ export interface Store {
|
|
|
1678
1699
|
*
|
|
1679
1700
|
* This method is useful for iterating over the Cell structure of the Row in a
|
|
1680
1701
|
* functional style. The `cellCallback` parameter is a CellCallback function
|
|
1681
|
-
* that will called with the Id and value of each Cell.
|
|
1702
|
+
* that will be called with the Id and value of each Cell.
|
|
1682
1703
|
*
|
|
1704
|
+
* @param tableId The Id of the Table containing the Row to iterate over.
|
|
1705
|
+
* @param rowId The Id of the Row to iterate over.
|
|
1683
1706
|
* @param cellCallback The function that should be called for every Cell.
|
|
1684
1707
|
* @example
|
|
1685
1708
|
* This example iterates over each Cell in a Row, and lists its value.
|
package/lib/debug/store.js
CHANGED
|
@@ -490,6 +490,7 @@ const createStore = () => {
|
|
|
490
490
|
mapKeys(mapGet(mapGet(tablesMap, tableId), rowId));
|
|
491
491
|
const getCell = (tableId, rowId, cellId) =>
|
|
492
492
|
mapGet(mapGet(mapGet(tablesMap, tableId), rowId), cellId);
|
|
493
|
+
const hasTables = () => !collIsEmpty(tablesMap);
|
|
493
494
|
const hasTable = (tableId) => collHas(tablesMap, tableId);
|
|
494
495
|
const hasRow = (tableId, rowId) => collHas(mapGet(tablesMap, tableId), rowId);
|
|
495
496
|
const hasCell = (tableId, rowId, cellId) =>
|
|
@@ -686,6 +687,7 @@ const createStore = () => {
|
|
|
686
687
|
getRow,
|
|
687
688
|
getCellIds,
|
|
688
689
|
getCell,
|
|
690
|
+
hasTables,
|
|
689
691
|
hasTable,
|
|
690
692
|
hasRow,
|
|
691
693
|
hasCell,
|
package/lib/debug/tinybase.js
CHANGED
|
@@ -110,6 +110,8 @@ const getDefinableFunctions = (store, getDefaultThing, validateRowValue) => {
|
|
|
110
110
|
const storeListenerIds = mapNew();
|
|
111
111
|
const getStore = () => store;
|
|
112
112
|
const getThingIds = () => mapKeys(tableIds);
|
|
113
|
+
const forEachThing = (cb) => mapForEach(things, cb);
|
|
114
|
+
const hasThing = (id) => collHas(things, id);
|
|
113
115
|
const getTableId = (id) => mapGet(tableIds, id);
|
|
114
116
|
const getThing = (id) => mapGet(things, id);
|
|
115
117
|
const setThing = (id, thing) => mapSet(things, id, thing);
|
|
@@ -199,6 +201,8 @@ const getDefinableFunctions = (store, getDefaultThing, validateRowValue) => {
|
|
|
199
201
|
return [
|
|
200
202
|
getStore,
|
|
201
203
|
getThingIds,
|
|
204
|
+
forEachThing,
|
|
205
|
+
hasThing,
|
|
202
206
|
getTableId,
|
|
203
207
|
getThing,
|
|
204
208
|
setThing,
|
|
@@ -429,10 +433,7 @@ const createCheckpoints = getCreateFunction((store) => {
|
|
|
429
433
|
return id;
|
|
430
434
|
};
|
|
431
435
|
const setCheckpoint = (checkpointId, label) => {
|
|
432
|
-
if (
|
|
433
|
-
collHas(deltas, checkpointId) &&
|
|
434
|
-
mapGet(labels, checkpointId) !== label
|
|
435
|
-
) {
|
|
436
|
+
if (hasCheckpoint(checkpointId) && mapGet(labels, checkpointId) !== label) {
|
|
436
437
|
mapSet(labels, checkpointId, label);
|
|
437
438
|
callListeners(checkpointListeners, [checkpointId]);
|
|
438
439
|
}
|
|
@@ -440,6 +441,9 @@ const createCheckpoints = getCreateFunction((store) => {
|
|
|
440
441
|
};
|
|
441
442
|
const getStore = () => store;
|
|
442
443
|
const getCheckpointIds = () => [[...backwardIds], currentId, [...forwardIds]];
|
|
444
|
+
const forEachCheckpoint = (checkpointCallback) =>
|
|
445
|
+
mapForEach(labels, checkpointCallback);
|
|
446
|
+
const hasCheckpoint = (checkpointId) => collHas(deltas, checkpointId);
|
|
443
447
|
const getCheckpoint = (checkpointId) => mapGet(labels, checkpointId);
|
|
444
448
|
const goBackward = () => {
|
|
445
449
|
goBackwardImpl();
|
|
@@ -495,6 +499,8 @@ const createCheckpoints = getCreateFunction((store) => {
|
|
|
495
499
|
setCheckpoint,
|
|
496
500
|
getStore,
|
|
497
501
|
getCheckpointIds,
|
|
502
|
+
forEachCheckpoint,
|
|
503
|
+
hasCheckpoint,
|
|
498
504
|
getCheckpoint,
|
|
499
505
|
goBackward,
|
|
500
506
|
goForward,
|
|
@@ -517,6 +523,8 @@ const createIndexes = getCreateFunction((store) => {
|
|
|
517
523
|
const [
|
|
518
524
|
getStore,
|
|
519
525
|
getIndexIds,
|
|
526
|
+
forEachIndexImpl,
|
|
527
|
+
hasIndex,
|
|
520
528
|
getTableId,
|
|
521
529
|
getIndex,
|
|
522
530
|
setIndex,
|
|
@@ -529,6 +537,7 @@ const createIndexes = getCreateFunction((store) => {
|
|
|
529
537
|
const [addListener, callListeners, delListenerImpl] = getListenerFunctions(
|
|
530
538
|
() => indexes,
|
|
531
539
|
);
|
|
540
|
+
const hasSlice = (indexId, sliceId) => collHas(getIndex(indexId), sliceId);
|
|
532
541
|
const setIndexDefinition = (
|
|
533
542
|
indexId,
|
|
534
543
|
tableId,
|
|
@@ -624,6 +633,26 @@ const createIndexes = getCreateFunction((store) => {
|
|
|
624
633
|
);
|
|
625
634
|
return indexes;
|
|
626
635
|
};
|
|
636
|
+
const forEachIndex = (indexCallback) =>
|
|
637
|
+
forEachIndexImpl((indexId, slices) =>
|
|
638
|
+
indexCallback(indexId, (sliceCallback) =>
|
|
639
|
+
forEachSliceImpl(indexId, sliceCallback, slices),
|
|
640
|
+
),
|
|
641
|
+
);
|
|
642
|
+
const forEachSlice = (indexId, sliceCallback) =>
|
|
643
|
+
forEachSliceImpl(indexId, sliceCallback, getIndex(indexId));
|
|
644
|
+
const forEachSliceImpl = (indexId, sliceCallback, slices) => {
|
|
645
|
+
const tableId = getTableId(indexId);
|
|
646
|
+
collForEach(slices, (rowIds, sliceId) =>
|
|
647
|
+
sliceCallback(sliceId, (rowCallback) =>
|
|
648
|
+
collForEach(rowIds, (rowId) =>
|
|
649
|
+
rowCallback(rowId, (cellCallback) =>
|
|
650
|
+
store.forEachCell(tableId, rowId, cellCallback),
|
|
651
|
+
),
|
|
652
|
+
),
|
|
653
|
+
),
|
|
654
|
+
);
|
|
655
|
+
};
|
|
627
656
|
const delIndexDefinition = (indexId) => {
|
|
628
657
|
delDefinition(indexId);
|
|
629
658
|
return indexes;
|
|
@@ -648,6 +677,10 @@ const createIndexes = getCreateFunction((store) => {
|
|
|
648
677
|
delIndexDefinition,
|
|
649
678
|
getStore,
|
|
650
679
|
getIndexIds,
|
|
680
|
+
forEachIndex,
|
|
681
|
+
forEachSlice,
|
|
682
|
+
hasIndex,
|
|
683
|
+
hasSlice,
|
|
651
684
|
getTableId,
|
|
652
685
|
getSliceIds,
|
|
653
686
|
getSliceRowIds,
|
|
@@ -705,6 +738,8 @@ const createMetrics = getCreateFunction((store) => {
|
|
|
705
738
|
const [
|
|
706
739
|
getStore,
|
|
707
740
|
getMetricIds,
|
|
741
|
+
forEachMetric,
|
|
742
|
+
hasMetric,
|
|
708
743
|
getTableId,
|
|
709
744
|
getMetric,
|
|
710
745
|
setMetric,
|
|
@@ -789,6 +824,8 @@ const createMetrics = getCreateFunction((store) => {
|
|
|
789
824
|
delMetricDefinition,
|
|
790
825
|
getStore,
|
|
791
826
|
getMetricIds,
|
|
827
|
+
forEachMetric,
|
|
828
|
+
hasMetric,
|
|
792
829
|
getTableId,
|
|
793
830
|
getMetric,
|
|
794
831
|
addMetricListener,
|
|
@@ -980,6 +1017,8 @@ const createRelationships = getCreateFunction((store) => {
|
|
|
980
1017
|
const [
|
|
981
1018
|
getStore,
|
|
982
1019
|
getRelationshipIds,
|
|
1020
|
+
forEachRelationshipImpl,
|
|
1021
|
+
hasRelationship,
|
|
983
1022
|
getLocalTableId,
|
|
984
1023
|
getRelationship,
|
|
985
1024
|
_setRelationship,
|
|
@@ -1093,6 +1132,12 @@ const createRelationships = getCreateFunction((store) => {
|
|
|
1093
1132
|
);
|
|
1094
1133
|
return relationships;
|
|
1095
1134
|
};
|
|
1135
|
+
const forEachRelationship = (relationshipCallback) =>
|
|
1136
|
+
forEachRelationshipImpl((relationshipId) =>
|
|
1137
|
+
relationshipCallback(relationshipId, (rowCallback) =>
|
|
1138
|
+
store.forEachRow(getLocalTableId(relationshipId), rowCallback),
|
|
1139
|
+
),
|
|
1140
|
+
);
|
|
1096
1141
|
const delRelationshipDefinition = (relationshipId) => {
|
|
1097
1142
|
mapSet(remoteTableIds, relationshipId);
|
|
1098
1143
|
delDefinition(relationshipId);
|
|
@@ -1133,6 +1178,8 @@ const createRelationships = getCreateFunction((store) => {
|
|
|
1133
1178
|
delRelationshipDefinition,
|
|
1134
1179
|
getStore,
|
|
1135
1180
|
getRelationshipIds,
|
|
1181
|
+
forEachRelationship,
|
|
1182
|
+
hasRelationship,
|
|
1136
1183
|
getLocalTableId,
|
|
1137
1184
|
getRemoteTableId,
|
|
1138
1185
|
getRemoteRowId,
|
|
@@ -1469,6 +1516,7 @@ const createStore = () => {
|
|
|
1469
1516
|
mapKeys(mapGet(mapGet(tablesMap, tableId), rowId));
|
|
1470
1517
|
const getCell = (tableId, rowId, cellId) =>
|
|
1471
1518
|
mapGet(mapGet(mapGet(tablesMap, tableId), rowId), cellId);
|
|
1519
|
+
const hasTables = () => !collIsEmpty(tablesMap);
|
|
1472
1520
|
const hasTable = (tableId) => collHas(tablesMap, tableId);
|
|
1473
1521
|
const hasRow = (tableId, rowId) => collHas(mapGet(tablesMap, tableId), rowId);
|
|
1474
1522
|
const hasCell = (tableId, rowId, cellId) =>
|
|
@@ -1665,6 +1713,7 @@ const createStore = () => {
|
|
|
1665
1713
|
getRow,
|
|
1666
1714
|
getCellIds,
|
|
1667
1715
|
getCell,
|
|
1716
|
+
hasTables,
|
|
1668
1717
|
hasTable,
|
|
1669
1718
|
hasRow,
|
|
1670
1719
|
hasCell,
|
package/lib/indexes.d.ts
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* @module indexes
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
import {GetCell, Store} from './store.d';
|
|
14
|
+
import {GetCell, RowCallback, Store} from './store.d';
|
|
15
15
|
import {Id, IdOrNull, Ids, SortKey} from './common.d';
|
|
16
16
|
|
|
17
17
|
/**
|
|
@@ -43,6 +43,42 @@ export type Index = {[sliceId: Id]: Slice};
|
|
|
43
43
|
*/
|
|
44
44
|
export type Slice = Ids;
|
|
45
45
|
|
|
46
|
+
/**
|
|
47
|
+
* The IndexCallback type describes a function that takes an Index's Id and a
|
|
48
|
+
* callback to loop over each Slice within it.
|
|
49
|
+
*
|
|
50
|
+
* A IndexCallback is provided when using the forEachIndex method, so that you
|
|
51
|
+
* can do something based on every Index in the Indexes object. See that method
|
|
52
|
+
* for specific examples.
|
|
53
|
+
*
|
|
54
|
+
* @param indexId The Id of the Index that the callback can operate on.
|
|
55
|
+
* @param forEachRow A function that will let you iterate over the Slice objects
|
|
56
|
+
* in this Index.
|
|
57
|
+
* @category Callback
|
|
58
|
+
*/
|
|
59
|
+
export type IndexCallback = (
|
|
60
|
+
indexId: Id,
|
|
61
|
+
forEachSlice: (sliceCallback: SliceCallback) => void,
|
|
62
|
+
) => void;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* The SliceCallback type describes a function that takes a Slice's Id and a
|
|
66
|
+
* callback to loop over each Row within it.
|
|
67
|
+
*
|
|
68
|
+
* A SliceCallback is provided when using the forEachSlice method, so that you
|
|
69
|
+
* can do something based on every Slice in an Index. See that method for
|
|
70
|
+
* specific examples.
|
|
71
|
+
*
|
|
72
|
+
* @param sliceId The Id of the Slice that the callback can operate on.
|
|
73
|
+
* @param forEachRow A function that will let you iterate over the Row objects
|
|
74
|
+
* in this Slice.
|
|
75
|
+
* @category Callback
|
|
76
|
+
*/
|
|
77
|
+
export type SliceCallback = (
|
|
78
|
+
sliceId: Id,
|
|
79
|
+
forEachRow: (rowCallback: RowCallback) => void,
|
|
80
|
+
) => void;
|
|
81
|
+
|
|
46
82
|
/**
|
|
47
83
|
* The SliceIdsListener type describes a function that is used to listen to
|
|
48
84
|
* changes to the Slice Ids in an Index.
|
|
@@ -362,6 +398,131 @@ export interface Indexes {
|
|
|
362
398
|
*/
|
|
363
399
|
getIndexIds(): Ids;
|
|
364
400
|
|
|
401
|
+
/**
|
|
402
|
+
* The forEachIndex method takes a function that it will then call for each
|
|
403
|
+
* Index in a specified Indexes object.
|
|
404
|
+
*
|
|
405
|
+
* This method is useful for iterating over the structure of the Indexes
|
|
406
|
+
* object in a functional style. The `indexCallback` parameter is a
|
|
407
|
+
* IndexCallback function that will be called with the Id of each Index, and
|
|
408
|
+
* with a function that can then be used to iterate over each Slice of the
|
|
409
|
+
* Index, should you wish.
|
|
410
|
+
*
|
|
411
|
+
* @param indexCallback The function that should be called for every Index.
|
|
412
|
+
* @example
|
|
413
|
+
* This example iterates over each Index in an Indexes object, and lists each
|
|
414
|
+
* Slice Id within them.
|
|
415
|
+
*
|
|
416
|
+
* ```js
|
|
417
|
+
* const store = createStore().setTable('pets', {
|
|
418
|
+
* fido: {species: 'dog', color: 'brown'},
|
|
419
|
+
* felix: {species: 'cat', color: 'black'},
|
|
420
|
+
* cujo: {species: 'dog', color: 'black'},
|
|
421
|
+
* });
|
|
422
|
+
* const indexes = createIndexes(store)
|
|
423
|
+
* .setIndexDefinition('bySpecies', 'pets', 'species')
|
|
424
|
+
* .setIndexDefinition('byColor', 'pets', 'color');
|
|
425
|
+
*
|
|
426
|
+
* indexes.forEachIndex((indexId, forEachSlice) => {
|
|
427
|
+
* console.log(indexId);
|
|
428
|
+
* forEachSlice((sliceId) => console.log(`- ${sliceId}`));
|
|
429
|
+
* });
|
|
430
|
+
* // -> 'bySpecies'
|
|
431
|
+
* // -> '- dog'
|
|
432
|
+
* // -> '- cat'
|
|
433
|
+
* // -> 'byColor'
|
|
434
|
+
* // -> '- brown'
|
|
435
|
+
* // -> '- black'
|
|
436
|
+
* ```
|
|
437
|
+
* @category Iterator
|
|
438
|
+
*/
|
|
439
|
+
forEachIndex(indexCallback: IndexCallback): void;
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* The forEachSlice method takes a function that it will then call for each
|
|
443
|
+
* Slice in a specified Index.
|
|
444
|
+
*
|
|
445
|
+
* This method is useful for iterating over the Slice structure of the Index
|
|
446
|
+
* in a functional style. The `rowCallback` parameter is a RowCallback
|
|
447
|
+
* function that will be called with the Id and value of each Row in the
|
|
448
|
+
* Slice.
|
|
449
|
+
*
|
|
450
|
+
* @param indexId The Id of the Index to iterate over.
|
|
451
|
+
* @param sliceCallback The function that should be called for every Slice.
|
|
452
|
+
* @example
|
|
453
|
+
* This example iterates over each Row in a Slice, and lists its Id.
|
|
454
|
+
*
|
|
455
|
+
* ```js
|
|
456
|
+
* const store = createStore().setTable('pets', {
|
|
457
|
+
* fido: {species: 'dog'},
|
|
458
|
+
* felix: {species: 'cat'},
|
|
459
|
+
* cujo: {species: 'dog'},
|
|
460
|
+
* });
|
|
461
|
+
* const indexes = createIndexes(store);
|
|
462
|
+
* indexes.setIndexDefinition('bySpecies', 'pets', 'species');
|
|
463
|
+
*
|
|
464
|
+
* indexes.forEachSlice('bySpecies', (sliceId, forEachRow) => {
|
|
465
|
+
* console.log(sliceId);
|
|
466
|
+
* forEachRow((rowId) => console.log(`- ${rowId}`));
|
|
467
|
+
* });
|
|
468
|
+
* // -> 'dog'
|
|
469
|
+
* // -> '- fido'
|
|
470
|
+
* // -> '- cujo'
|
|
471
|
+
* // -> 'cat'
|
|
472
|
+
* // -> '- felix'
|
|
473
|
+
* ```
|
|
474
|
+
* @category Iterator
|
|
475
|
+
*/
|
|
476
|
+
forEachSlice(indexId: Id, sliceCallback: SliceCallback): void;
|
|
477
|
+
|
|
478
|
+
/**
|
|
479
|
+
* The hasIndex method returns a boolean indicating whether a given Index
|
|
480
|
+
* exists in the Indexes object.
|
|
481
|
+
*
|
|
482
|
+
* @param indexId The Id of a possible Index in the Indexes object.
|
|
483
|
+
* @returns Whether an Index with that Id exists.
|
|
484
|
+
* @example
|
|
485
|
+
* This example shows two simple Index existence checks.
|
|
486
|
+
*
|
|
487
|
+
* ```js
|
|
488
|
+
* const indexes = createIndexes(createStore());
|
|
489
|
+
* indexes.setIndexDefinition('bySpecies', 'pets', 'species');
|
|
490
|
+
* console.log(indexes.hasIndex('bySpecies'));
|
|
491
|
+
* // -> true
|
|
492
|
+
* console.log(indexes.hasIndex('byColor'));
|
|
493
|
+
* // -> false
|
|
494
|
+
* ```
|
|
495
|
+
* @category Getter
|
|
496
|
+
*/
|
|
497
|
+
hasIndex(indexId: Id): boolean;
|
|
498
|
+
|
|
499
|
+
/**
|
|
500
|
+
* The hasSlice method returns a boolean indicating whether a given Slice
|
|
501
|
+
* exists in the Indexes object.
|
|
502
|
+
*
|
|
503
|
+
* @param indexId The Id of a possible Index in the Indexes object.
|
|
504
|
+
* @param sliceId The Id of a possible Slice in the Index.
|
|
505
|
+
* @returns Whether a Slice with that Id exists.
|
|
506
|
+
* @example
|
|
507
|
+
* This example shows two simple Index existence checks.
|
|
508
|
+
*
|
|
509
|
+
* ```js
|
|
510
|
+
* const store = createStore().setTable('pets', {
|
|
511
|
+
* fido: {species: 'dog'},
|
|
512
|
+
* felix: {species: 'cat'},
|
|
513
|
+
* cujo: {species: 'dog'},
|
|
514
|
+
* });
|
|
515
|
+
* const indexes = createIndexes(store);
|
|
516
|
+
* indexes.setIndexDefinition('bySpecies', 'pets', 'species');
|
|
517
|
+
* console.log(indexes.hasSlice('bySpecies', 'dog'));
|
|
518
|
+
* // -> true
|
|
519
|
+
* console.log(indexes.hasSlice('bySpecies', 'worm'));
|
|
520
|
+
* // -> false
|
|
521
|
+
* ```
|
|
522
|
+
* @category Getter
|
|
523
|
+
*/
|
|
524
|
+
hasSlice(indexId: Id, sliceId: Id): boolean;
|
|
525
|
+
|
|
365
526
|
/**
|
|
366
527
|
* The getTableId method returns the Id of the underlying Table that is
|
|
367
528
|
* backing an Index.
|
|
@@ -473,7 +634,7 @@ export interface Indexes {
|
|
|
473
634
|
* the Index change.
|
|
474
635
|
* @returns A unique Id for the listener that can later be used to remove it.
|
|
475
636
|
* @example
|
|
476
|
-
* This example creates a Store,
|
|
637
|
+
* This example creates a Store, an Indexes object, and then registers a
|
|
477
638
|
* listener that responds to any changes to a specific Index.
|
|
478
639
|
*
|
|
479
640
|
* ```js
|
|
@@ -501,7 +662,7 @@ export interface Indexes {
|
|
|
501
662
|
* indexes.delListener(listenerId);
|
|
502
663
|
* ```
|
|
503
664
|
* @example
|
|
504
|
-
* This example creates a Store,
|
|
665
|
+
* This example creates a Store, an Indexes object, and then registers a
|
|
505
666
|
* listener that responds to any changes to any Index.
|
|
506
667
|
*
|
|
507
668
|
* ```js
|
|
@@ -558,7 +719,7 @@ export interface Indexes {
|
|
|
558
719
|
* the Slice change.
|
|
559
720
|
* @returns A unique Id for the listener that can later be used to remove it.
|
|
560
721
|
* @example
|
|
561
|
-
* This example creates a Store,
|
|
722
|
+
* This example creates a Store, an Indexes object, and then registers a
|
|
562
723
|
* listener that responds to any changes to a specific Slice.
|
|
563
724
|
*
|
|
564
725
|
* ```js
|
|
@@ -587,7 +748,7 @@ export interface Indexes {
|
|
|
587
748
|
* indexes.delListener(listenerId);
|
|
588
749
|
* ```
|
|
589
750
|
* @example
|
|
590
|
-
* This example creates a Store,
|
|
751
|
+
* This example creates a Store, an Indexes object, and then registers a
|
|
591
752
|
* listener that responds to any changes to any Slice.
|
|
592
753
|
*
|
|
593
754
|
* ```js
|
|
@@ -639,7 +800,7 @@ export interface Indexes {
|
|
|
639
800
|
* @param listenerId The Id of the listener to remove.
|
|
640
801
|
* @returns A reference to the Indexes object.
|
|
641
802
|
* @example
|
|
642
|
-
* This example creates a Store,
|
|
803
|
+
* This example creates a Store, an Indexes object, registers a listener, and
|
|
643
804
|
* then removes it.
|
|
644
805
|
*
|
|
645
806
|
* ```js
|
package/lib/indexes.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const e=e=>typeof e,t=e(""),s=(e,t)=>e.every(((s,n)=>0==n||t(e[n-1],s)<=0)),n=(e,t)=>e.sort(t),o=(e,t)=>e.forEach(t),r=e=>e.length,
|
|
1
|
+
const e=e=>typeof e,t=e(""),s=(e,t)=>e.every(((s,n)=>0==n||t(e[n-1],s)<=0)),n=(e,t)=>e.sort(t),o=(e,t)=>e.forEach(t),r=e=>e.length,c=e=>0==r(e),d=e=>e.slice(1),l=e=>null==e,i=(e,t,s)=>l(e)?s?.():t(e),a=(e,t)=>e?.has(t)??!1,h=e=>l(e)||0==(e=>e.size)(e),u=e=>e.clear(),I=(e,t)=>e?.forEach(t),f=(e,t)=>e?.delete(t),g=e=>new Map(e),S=e=>[...e?.keys()??[]],w=(e,t)=>e?.get(t),p=(e,t)=>I(e,((e,s)=>t(s,e))),L=(e,t,s)=>l(s)?(f(e,t),e):e?.set(t,s),x=(e,t,s,n)=>(a(e,t)||(n?.(s),e.set(t,s)),w(e,t)),v=e=>new Set(e),E=(e,t)=>e?.add(t),R=(s,n)=>e(s)==t?e=>e(s):s??(()=>n??""),b=(e,t)=>e<t?-1:1,y=(e,t,s)=>r(s)<2?E(c(s)?e:x(e,s[0],v()),t):y(x(e,s[0],g()),t,d(s)),T=e=>{const t=(s,n,...r)=>i(s,(s=>c(r)?e(s,n):o([r[0],null],(e=>t(w(s,e),n,...d(r))))));return t},k=Object.freeze,z=(e=>{const t=new WeakMap;return s=>(t.has(s)||t.set(s,e(s)),t.get(s))})((e=>{const t=g(),c=g(),[d,x,z,C,D,M,j,O,W,m]=((e,t,s)=>{const n=e.hasRow,r=g(),c=g(),d=g(),h=g(),f=g(),x=t=>i(w(f,t),(s=>{I(s,e.delListener),L(f,t)})),E=e=>{L(r,e),L(c,e),L(d,e),L(h,e),x(e)};return[()=>e,()=>S(r),e=>p(c,e),e=>a(c,e),e=>w(r,e),e=>w(c,e),(e,t)=>L(c,e,t),(i,S,E,R,b)=>{const y=g(),T=g();L(r,i,S),a(c,i)||(L(c,i,t()),L(d,i,g()),L(h,i,g()));const k=w(d,i),z=w(h,i),C=t=>{const o=s=>e.getCell(S,t,s),r=w(k,t),c=n(S,t)?s(R(o,t)):void 0;if(r!=c&&L(y,t,[r,c]),!l(b)){const e=w(z,t),s=n(S,t)?b(o,t):void 0;e!=s&&L(T,t,s)}},D=e=>{E((()=>{I(y,(([,e],t)=>L(k,t,e))),I(T,((e,t)=>L(z,t,e)))}),y,T,k,z,e),u(y),u(T)};p(k,C),e.hasTable(S)&&o(e.getRowIds(S),(e=>{a(k,e)||C(e)})),D(!0),x(i),L(f,i,v([e.addRowListener(S,null,((e,t,s)=>C(s))),e.addTableListener(S,(()=>D()))]))},E,()=>p(f,E)]})(e,g,(e=>l(e)?"":e+"")),[q,A,B]=(e=>{let t,s=0;const n=[],c=g();return[(o,r,d=[])=>{t??=e();const l=n.pop()??""+s++;return L(c,l,[o,r,d]),y(r,l,d),l},(e,s=[],...n)=>T(I)(e,(e=>i(w(c,e),(([e])=>e(t,...s,...n)))),...s),e=>i(w(c,e),(([,t,s])=>(T(f)(t,e,...s),L(c,e),r(n)<1e3&&n.push(e),s)),(()=>[])),(e,s,n)=>i(w(c,e),(([e,,c])=>{const d=(...i)=>{const a=r(i);a==r(c)?e(t,...i,...n(i)):l(c[a])?o(s[a](...i),(e=>d(...i,e))):d(...i,c[a])};d()}))]})((()=>G)),F=(t,s,n)=>{const o=D(t);I(n,((t,n)=>s(n,(s=>I(t,(t=>s(t,(s=>e.forEachCell(o,t,s)))))))))},G={setIndexDefinition:(e,o,r,d,u,S=b)=>{const x=l(u)?void 0:([e],[t])=>u(e,t);return O(e,o,((o,r,u,R,b,y)=>{let T=0;const k=v(),z=v(),C=M(e);if(I(r,(([e,t],s)=>{l(e)||(E(k,e),i(w(C,e),(t=>{f(t,s),h(t)&&(L(C,e),T=1)}))),l(t)||(E(k,t),a(C,t)||(L(C,t,v()),T=1),E(w(C,t),s),l(d)||E(z,t))})),o(),h(b)||(y?p(C,(e=>E(z,e))):p(u,(e=>i(w(R,e),(e=>E(z,e))))),I(z,(e=>{const t=(t,s)=>S(w(b,t),w(b,s),e),o=[...w(C,e)];s(o,t)||(L(C,e,v(n(o,t))),E(k,e))}))),(T||y)&&!l(x)){const t=[...C];s(t,x)||(j(e,g(n(t,x))),T=1)}T&&A(t,[e]),I(k,(t=>A(c,[e,t])))}),R(r),i(d,R)),G},delIndexDefinition:e=>(W(e),G),getStore:d,getIndexIds:x,forEachIndex:e=>z(((t,s)=>e(t,(e=>F(t,e,s))))),forEachSlice:(e,t)=>F(e,t,M(e)),hasIndex:C,hasSlice:(e,t)=>a(M(e),t),getTableId:D,getSliceIds:e=>S(M(e)),getSliceRowIds:(e,t)=>[...w(M(e),t)?.values()??[]],addSliceIdsListener:(e,s)=>q(s,t,[e]),addSliceRowIdsListener:(e,t,s)=>q(s,c,[e,t]),delListener:e=>(B(e),G),destroy:m,getListenerStats:()=>({})};return k(G)}));export{z as createIndexes};
|
package/lib/indexes.js.gz
CHANGED
|
Binary file
|