tinybase 1.0.4 → 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 +44 -0
- package/lib/checkpoints.js +1 -1
- package/lib/checkpoints.js.gz +0 -0
- package/lib/debug/checkpoints.d.ts +44 -0
- package/lib/debug/checkpoints.js +5 -0
- package/lib/debug/indexes.d.ts +114 -1
- package/lib/debug/indexes.js +25 -0
- package/lib/debug/metrics.d.ts +46 -0
- package/lib/debug/metrics.js +4 -0
- package/lib/debug/relationships.d.ts +63 -1
- package/lib/debug/relationships.js +10 -0
- package/lib/debug/store.d.ts +8 -5
- package/lib/debug/tinybase.js +38 -0
- package/lib/indexes.d.ts +114 -1
- package/lib/indexes.js +1 -1
- package/lib/indexes.js.gz +0 -0
- package/lib/metrics.d.ts +46 -0
- package/lib/metrics.js +1 -1
- package/lib/metrics.js.gz +0 -0
- package/lib/relationships.d.ts +63 -1
- package/lib/relationships.js +1 -1
- package/lib/relationships.js.gz +0 -0
- package/lib/store.d.ts +8 -5
- 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/tinybase.js +1 -1
- package/lib/umd/tinybase.js.gz +0 -0
- package/package.json +7 -7
- package/readme.md +2 -2
package/lib/checkpoints.d.ts
CHANGED
|
@@ -33,6 +33,20 @@ import {Store} from './store.d';
|
|
|
33
33
|
*/
|
|
34
34
|
export type CheckpointIds = [Ids, Id | undefined, Ids];
|
|
35
35
|
|
|
36
|
+
/**
|
|
37
|
+
* The CheckpointCallback type describes a function that takes a Checkpoint's
|
|
38
|
+
* Id.
|
|
39
|
+
*
|
|
40
|
+
* A CheckpointCallback is provided when using the forEachCheckpoint method,
|
|
41
|
+
* so that you can do something based on every Checkpoint in the Checkpoints
|
|
42
|
+
* object. See that method for specific examples.
|
|
43
|
+
*
|
|
44
|
+
* @param checkpointId The Id of the Checkpoint that the callback can operate
|
|
45
|
+
* on.
|
|
46
|
+
* @category Callback
|
|
47
|
+
*/
|
|
48
|
+
export type CheckpointCallback = (checkpointId: Id, label?: string) => void;
|
|
49
|
+
|
|
36
50
|
/**
|
|
37
51
|
* The CheckpointIdsListener type describes a function that is used to listen to
|
|
38
52
|
* changes to the checkpoint Ids in a Checkpoints object.
|
|
@@ -353,6 +367,36 @@ export interface Checkpoints {
|
|
|
353
367
|
*/
|
|
354
368
|
getCheckpointIds(): CheckpointIds;
|
|
355
369
|
|
|
370
|
+
/**
|
|
371
|
+
* The forEachCheckpoint method takes a function that it will then call for
|
|
372
|
+
* each Checkpoint in a specified Checkpoints object.
|
|
373
|
+
*
|
|
374
|
+
* This method is useful for iterating over the structure of the Checkpoints
|
|
375
|
+
* object in a functional style. The `checkpointCallback` parameter is a
|
|
376
|
+
* CheckpointCallback function that will be called with the Id of each
|
|
377
|
+
* Checkpoint.
|
|
378
|
+
*
|
|
379
|
+
* @param checkpointCallback The function that should be called for every
|
|
380
|
+
* Checkpoint.
|
|
381
|
+
* @example
|
|
382
|
+
* This example iterates over each Checkpoint in a Checkpoints object.
|
|
383
|
+
*
|
|
384
|
+
* ```js
|
|
385
|
+
* const store = createStore().setTables({pets: {fido: {sold: false}}});
|
|
386
|
+
* const checkpoints = createCheckpoints(store);
|
|
387
|
+
* store.setCell('pets', 'fido', 'sold', true);
|
|
388
|
+
* checkpoints.addCheckpoint('sale');
|
|
389
|
+
*
|
|
390
|
+
* checkpoints.forEachCheckpoint((checkpointId, label) => {
|
|
391
|
+
* console.log(`${checkpointId}:${label}`);
|
|
392
|
+
* });
|
|
393
|
+
* // -> '0:'
|
|
394
|
+
* // -> '1:sale'
|
|
395
|
+
* ```
|
|
396
|
+
* @category Iterator
|
|
397
|
+
*/
|
|
398
|
+
forEachCheckpoint(checkpointCallback: CheckpointCallback): void;
|
|
399
|
+
|
|
356
400
|
/**
|
|
357
401
|
* The hasCheckpoint method returns a boolean indicating whether a given
|
|
358
402
|
* Checkpoint exists in the Checkpoints object.
|
package/lib/checkpoints.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const e=(e,t)=>e.includes(t),t=(e,t)=>e.forEach(t),n=e=>e.length,s=e=>0==n(e),o=e=>e.slice(1),r=e=>null==e,
|
|
1
|
+
const e=(e,t)=>e.includes(t),t=(e,t)=>e.forEach(t),n=e=>e.length,s=e=>0==n(e),o=e=>e.slice(1),r=e=>null==e,c=(e,t,n)=>r(e)?n?.():t(e),l=(e,t)=>e?.has(t)??!1,i=e=>r(e)||0==(e=>e.size)(e),d=(e,t)=>e?.forEach(t),a=(e,t)=>e?.delete(t),p=e=>new Map(e),h=(e,t)=>e?.get(t),u=(e,t,n)=>r(n)?(a(e,t),e):e?.set(t,n),C=(e,t,n,s)=>(l(e,t)||(s?.(n),e.set(t,n)),h(e,t)),g=e=>new Set(e),k=(e,t,r)=>n(r)<2?((e,t)=>e?.add(t))(s(r)?e:C(e,r[0],g()),t):k(C(e,r[0],p()),t,o(r)),f=e=>{const n=(r,l,...i)=>c(r,(r=>s(i)?e(r,l):t([i[0],null],(e=>n(h(r,e),l,...o(i))))));return n},L=Object.freeze,v=(e=>{const t=new WeakMap;return n=>(t.has(n)||t.set(n,e(n)),t.get(n))})((o=>{let v,w,S,z=100,E=p(),I=1;const M=g(),b=p(),[j,x,y]=(e=>{let s,o=0;const l=[],i=p();return[(t,n,r=[])=>{s??=e();const c=l.pop()??""+o++;return u(i,c,[t,n,r]),k(n,c,r),c},(e,t=[],...n)=>f(d)(e,(e=>c(h(i,e),(([e])=>e(s,...t,...n)))),...t),e=>c(h(i,e),(([,t,s])=>(f(a)(t,e,...s),u(i,e),n(l)<1e3&&l.push(e),s)),(()=>[])),(e,o,l)=>c(h(i,e),(([e,,c])=>{const i=(...d)=>{const a=n(d);a==n(c)?e(s,...d,...l(d)):r(c[a])?t(o[a](...d),(e=>i(...d,e))):i(...d,c[a])};i()}))]})((()=>R)),B=p(),F=p(),O=[],T=[],W=(e,t)=>{I=0,o.transaction((()=>d(h(B,t),((t,n)=>d(t,((t,s)=>d(t,((t,c)=>r(t[e])?o.delCell(n,s,c,!0):o.setCell(n,s,c,t[e]))))))))),I=1},m=e=>{u(B,e),u(F,e),x(b,[e])},q=(e,s)=>t(((e,t)=>e.splice(0,t))(e,s??n(e)),m),A=()=>q(O,n(O)-z),D=o.addCellListener(null,null,null,((e,t,n,s,o,r)=>{if(I){c(v,(()=>{O.push(v),A(),q(T),v=void 0,S=1}));const e=C(E,t,p()),l=C(e,n,p()),d=C(l,s,[void 0,void 0],(e=>e[0]=r));d[1]=o,d[0]===d[1]&&i(u(l,s))&&i(u(e,n))&&i(u(E,t))&&(v=O.pop(),S=1),K()}})),G=(e="")=>(r(v)&&(v=""+w++,u(B,v,E),P(v,e),E=p(),S=1),v),H=()=>{s(O)||(T.unshift(G()),W(0,v),v=O.pop(),S=1)},J=()=>{s(T)||(O.push(v),v=T.shift(),W(1,v),S=1)},K=()=>{S&&(x(M),S=0)},N=e=>{const t=G(e);return K(),t},P=(e,t)=>(Q(e)&&h(F,e)!==t&&(u(F,e,t),x(b,[e])),R),Q=e=>l(B,e),R={setSize:e=>(z=e,A(),R),addCheckpoint:N,setCheckpoint:P,getStore:()=>o,getCheckpointIds:()=>[[...O],v,[...T]],forEachCheckpoint:e=>{return t=e,d(F,((e,n)=>t(n,e)));var t},hasCheckpoint:Q,getCheckpoint:e=>h(F,e),goBackward:()=>(H(),K(),R),goForward:()=>(J(),K(),R),goTo:t=>{const n=e(O,t)?H:e(T,t)?J:null;for(;!r(n)&&t!=v;)n();return K(),R},addCheckpointIdsListener:e=>j(e,M),addCheckpointListener:(e,t)=>j(t,b,[e]),delListener:e=>(y(e),R),clear:()=>(q(O),q(T),r(v)||m(v),v=void 0,w=0,N(),R),destroy:()=>{o.delListener(D)},getListenerStats:()=>({})};return L(R.clear())}));export{v as createCheckpoints};
|
package/lib/checkpoints.js.gz
CHANGED
|
Binary file
|
|
@@ -33,6 +33,20 @@ import {Store} from './store.d';
|
|
|
33
33
|
*/
|
|
34
34
|
export type CheckpointIds = [Ids, Id | undefined, Ids];
|
|
35
35
|
|
|
36
|
+
/**
|
|
37
|
+
* The CheckpointCallback type describes a function that takes a Checkpoint's
|
|
38
|
+
* Id.
|
|
39
|
+
*
|
|
40
|
+
* A CheckpointCallback is provided when using the forEachCheckpoint method,
|
|
41
|
+
* so that you can do something based on every Checkpoint in the Checkpoints
|
|
42
|
+
* object. See that method for specific examples.
|
|
43
|
+
*
|
|
44
|
+
* @param checkpointId The Id of the Checkpoint that the callback can operate
|
|
45
|
+
* on.
|
|
46
|
+
* @category Callback
|
|
47
|
+
*/
|
|
48
|
+
export type CheckpointCallback = (checkpointId: Id, label?: string) => void;
|
|
49
|
+
|
|
36
50
|
/**
|
|
37
51
|
* The CheckpointIdsListener type describes a function that is used to listen to
|
|
38
52
|
* changes to the checkpoint Ids in a Checkpoints object.
|
|
@@ -353,6 +367,36 @@ export interface Checkpoints {
|
|
|
353
367
|
*/
|
|
354
368
|
getCheckpointIds(): CheckpointIds;
|
|
355
369
|
|
|
370
|
+
/**
|
|
371
|
+
* The forEachCheckpoint method takes a function that it will then call for
|
|
372
|
+
* each Checkpoint in a specified Checkpoints object.
|
|
373
|
+
*
|
|
374
|
+
* This method is useful for iterating over the structure of the Checkpoints
|
|
375
|
+
* object in a functional style. The `checkpointCallback` parameter is a
|
|
376
|
+
* CheckpointCallback function that will be called with the Id of each
|
|
377
|
+
* Checkpoint.
|
|
378
|
+
*
|
|
379
|
+
* @param checkpointCallback The function that should be called for every
|
|
380
|
+
* Checkpoint.
|
|
381
|
+
* @example
|
|
382
|
+
* This example iterates over each Checkpoint in a Checkpoints object.
|
|
383
|
+
*
|
|
384
|
+
* ```js
|
|
385
|
+
* const store = createStore().setTables({pets: {fido: {sold: false}}});
|
|
386
|
+
* const checkpoints = createCheckpoints(store);
|
|
387
|
+
* store.setCell('pets', 'fido', 'sold', true);
|
|
388
|
+
* checkpoints.addCheckpoint('sale');
|
|
389
|
+
*
|
|
390
|
+
* checkpoints.forEachCheckpoint((checkpointId, label) => {
|
|
391
|
+
* console.log(`${checkpointId}:${label}`);
|
|
392
|
+
* });
|
|
393
|
+
* // -> '0:'
|
|
394
|
+
* // -> '1:sale'
|
|
395
|
+
* ```
|
|
396
|
+
* @category Iterator
|
|
397
|
+
*/
|
|
398
|
+
forEachCheckpoint(checkpointCallback: CheckpointCallback): void;
|
|
399
|
+
|
|
356
400
|
/**
|
|
357
401
|
* The hasCheckpoint method returns a boolean indicating whether a given
|
|
358
402
|
* Checkpoint exists in the Checkpoints object.
|
package/lib/debug/checkpoints.js
CHANGED
|
@@ -22,6 +22,8 @@ const collDel = (coll, keyOrValue) => coll?.delete(keyOrValue);
|
|
|
22
22
|
|
|
23
23
|
const mapNew = (entries) => new Map(entries);
|
|
24
24
|
const mapGet = (map, key) => map?.get(key);
|
|
25
|
+
const mapForEach = (map, cb) =>
|
|
26
|
+
collForEach(map, (value, key) => cb(key, value));
|
|
25
27
|
const mapSet = (map, key, value) =>
|
|
26
28
|
isUndefined(value) ? (collDel(map, key), map) : map?.set(key, value);
|
|
27
29
|
const mapEnsure = (map, key, defaultValue, onWillAdd) => {
|
|
@@ -251,6 +253,8 @@ const createCheckpoints = getCreateFunction((store) => {
|
|
|
251
253
|
};
|
|
252
254
|
const getStore = () => store;
|
|
253
255
|
const getCheckpointIds = () => [[...backwardIds], currentId, [...forwardIds]];
|
|
256
|
+
const forEachCheckpoint = (checkpointCallback) =>
|
|
257
|
+
mapForEach(labels, checkpointCallback);
|
|
254
258
|
const hasCheckpoint = (checkpointId) => collHas(deltas, checkpointId);
|
|
255
259
|
const getCheckpoint = (checkpointId) => mapGet(labels, checkpointId);
|
|
256
260
|
const goBackward = () => {
|
|
@@ -307,6 +311,7 @@ const createCheckpoints = getCreateFunction((store) => {
|
|
|
307
311
|
setCheckpoint,
|
|
308
312
|
getStore,
|
|
309
313
|
getCheckpointIds,
|
|
314
|
+
forEachCheckpoint,
|
|
310
315
|
hasCheckpoint,
|
|
311
316
|
getCheckpoint,
|
|
312
317
|
goBackward,
|
package/lib/debug/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,83 @@ 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
|
+
|
|
365
478
|
/**
|
|
366
479
|
* The hasIndex method returns a boolean indicating whether a given Index
|
|
367
480
|
* exists in the Indexes object.
|
package/lib/debug/indexes.js
CHANGED
|
@@ -57,6 +57,7 @@ const getDefinableFunctions = (store, getDefaultThing, validateRowValue) => {
|
|
|
57
57
|
const storeListenerIds = mapNew();
|
|
58
58
|
const getStore = () => store;
|
|
59
59
|
const getThingIds = () => mapKeys(tableIds);
|
|
60
|
+
const forEachThing = (cb) => mapForEach(things, cb);
|
|
60
61
|
const hasThing = (id) => collHas(things, id);
|
|
61
62
|
const getTableId = (id) => mapGet(tableIds, id);
|
|
62
63
|
const getThing = (id) => mapGet(things, id);
|
|
@@ -147,6 +148,7 @@ const getDefinableFunctions = (store, getDefaultThing, validateRowValue) => {
|
|
|
147
148
|
return [
|
|
148
149
|
getStore,
|
|
149
150
|
getThingIds,
|
|
151
|
+
forEachThing,
|
|
150
152
|
hasThing,
|
|
151
153
|
getTableId,
|
|
152
154
|
getThing,
|
|
@@ -254,6 +256,7 @@ const createIndexes = getCreateFunction((store) => {
|
|
|
254
256
|
const [
|
|
255
257
|
getStore,
|
|
256
258
|
getIndexIds,
|
|
259
|
+
forEachIndexImpl,
|
|
257
260
|
hasIndex,
|
|
258
261
|
getTableId,
|
|
259
262
|
getIndex,
|
|
@@ -363,6 +366,26 @@ const createIndexes = getCreateFunction((store) => {
|
|
|
363
366
|
);
|
|
364
367
|
return indexes;
|
|
365
368
|
};
|
|
369
|
+
const forEachIndex = (indexCallback) =>
|
|
370
|
+
forEachIndexImpl((indexId, slices) =>
|
|
371
|
+
indexCallback(indexId, (sliceCallback) =>
|
|
372
|
+
forEachSliceImpl(indexId, sliceCallback, slices),
|
|
373
|
+
),
|
|
374
|
+
);
|
|
375
|
+
const forEachSlice = (indexId, sliceCallback) =>
|
|
376
|
+
forEachSliceImpl(indexId, sliceCallback, getIndex(indexId));
|
|
377
|
+
const forEachSliceImpl = (indexId, sliceCallback, slices) => {
|
|
378
|
+
const tableId = getTableId(indexId);
|
|
379
|
+
collForEach(slices, (rowIds, sliceId) =>
|
|
380
|
+
sliceCallback(sliceId, (rowCallback) =>
|
|
381
|
+
collForEach(rowIds, (rowId) =>
|
|
382
|
+
rowCallback(rowId, (cellCallback) =>
|
|
383
|
+
store.forEachCell(tableId, rowId, cellCallback),
|
|
384
|
+
),
|
|
385
|
+
),
|
|
386
|
+
),
|
|
387
|
+
);
|
|
388
|
+
};
|
|
366
389
|
const delIndexDefinition = (indexId) => {
|
|
367
390
|
delDefinition(indexId);
|
|
368
391
|
return indexes;
|
|
@@ -387,6 +410,8 @@ const createIndexes = getCreateFunction((store) => {
|
|
|
387
410
|
delIndexDefinition,
|
|
388
411
|
getStore,
|
|
389
412
|
getIndexIds,
|
|
413
|
+
forEachIndex,
|
|
414
|
+
forEachSlice,
|
|
390
415
|
hasIndex,
|
|
391
416
|
hasSlice,
|
|
392
417
|
getTableId,
|
package/lib/debug/metrics.d.ts
CHANGED
|
@@ -22,6 +22,20 @@ import {Id, IdOrNull, Ids} from './common.d';
|
|
|
22
22
|
*/
|
|
23
23
|
export type Metric = number;
|
|
24
24
|
|
|
25
|
+
/**
|
|
26
|
+
* The MetricCallback type describes a function that takes a Metric's Id and a
|
|
27
|
+
* callback to loop over each Row within it.
|
|
28
|
+
*
|
|
29
|
+
* A MetricCallback is provided when using the forEachMetric method, so that you
|
|
30
|
+
* can do something based on every Metric in the Metrics object. See that method
|
|
31
|
+
* for specific examples.
|
|
32
|
+
*
|
|
33
|
+
* @param metricId The Id of the Metric that the callback can operate on.
|
|
34
|
+
* @param metric The value of the Metric.
|
|
35
|
+
* @category Callback
|
|
36
|
+
*/
|
|
37
|
+
export type MetricCallback = (metricId: Id, metric?: Metric) => void;
|
|
38
|
+
|
|
25
39
|
/**
|
|
26
40
|
* The Aggregate type describes a custom function that takes an array or numbers
|
|
27
41
|
* and returns an aggregate that is used as a Metric.
|
|
@@ -478,6 +492,38 @@ export interface Metrics {
|
|
|
478
492
|
*/
|
|
479
493
|
getMetricIds(): Ids;
|
|
480
494
|
|
|
495
|
+
/**
|
|
496
|
+
* The forEachMetric method takes a function that it will then call for each
|
|
497
|
+
* Metric in the Metrics object.
|
|
498
|
+
*
|
|
499
|
+
* This method is useful for iterating over all the Metrics in a functional
|
|
500
|
+
* style. The `metricCallback` parameter is a MetricCallback function that
|
|
501
|
+
* will be called with the Id of each Metric and its value.
|
|
502
|
+
*
|
|
503
|
+
* @param metricCallback The function that should be called for every Metric.
|
|
504
|
+
* @example
|
|
505
|
+
* This example iterates over each Metric in a Metrics object.
|
|
506
|
+
*
|
|
507
|
+
* ```js
|
|
508
|
+
* const store = createStore().setTable('species', {
|
|
509
|
+
* dog: {price: 5},
|
|
510
|
+
* cat: {price: 4},
|
|
511
|
+
* worm: {price: 1},
|
|
512
|
+
* });
|
|
513
|
+
* const metrics = createMetrics(store)
|
|
514
|
+
* .setMetricDefinition('highestPrice', 'species', 'max', 'price')
|
|
515
|
+
* .setMetricDefinition('lowestPrice', 'species', 'min', 'price');
|
|
516
|
+
*
|
|
517
|
+
* metrics.forEachMetric((metricId, metric) => {
|
|
518
|
+
* console.log([metricId, metric]);
|
|
519
|
+
* });
|
|
520
|
+
* // -> ['highestPrice', 5]
|
|
521
|
+
* // -> ['lowestPrice', 1]
|
|
522
|
+
* ```
|
|
523
|
+
* @category Iterator
|
|
524
|
+
*/
|
|
525
|
+
forEachMetric(metricCallback: MetricCallback): void;
|
|
526
|
+
|
|
481
527
|
/**
|
|
482
528
|
* The hasMetric method returns a boolean indicating whether a given Metric
|
|
483
529
|
* exists in the Metrics object, and has a value.
|
package/lib/debug/metrics.js
CHANGED
|
@@ -62,6 +62,7 @@ const getDefinableFunctions = (store, getDefaultThing, validateRowValue) => {
|
|
|
62
62
|
const storeListenerIds = mapNew();
|
|
63
63
|
const getStore = () => store;
|
|
64
64
|
const getThingIds = () => mapKeys(tableIds);
|
|
65
|
+
const forEachThing = (cb) => mapForEach(things, cb);
|
|
65
66
|
const hasThing = (id) => collHas(things, id);
|
|
66
67
|
const getTableId = (id) => mapGet(tableIds, id);
|
|
67
68
|
const getThing = (id) => mapGet(things, id);
|
|
@@ -152,6 +153,7 @@ const getDefinableFunctions = (store, getDefaultThing, validateRowValue) => {
|
|
|
152
153
|
return [
|
|
153
154
|
getStore,
|
|
154
155
|
getThingIds,
|
|
156
|
+
forEachThing,
|
|
155
157
|
hasThing,
|
|
156
158
|
getTableId,
|
|
157
159
|
getThing,
|
|
@@ -296,6 +298,7 @@ const createMetrics = getCreateFunction((store) => {
|
|
|
296
298
|
const [
|
|
297
299
|
getStore,
|
|
298
300
|
getMetricIds,
|
|
301
|
+
forEachMetric,
|
|
299
302
|
hasMetric,
|
|
300
303
|
getTableId,
|
|
301
304
|
getMetric,
|
|
@@ -381,6 +384,7 @@ const createMetrics = getCreateFunction((store) => {
|
|
|
381
384
|
delMetricDefinition,
|
|
382
385
|
getStore,
|
|
383
386
|
getMetricIds,
|
|
387
|
+
forEachMetric,
|
|
384
388
|
hasMetric,
|
|
385
389
|
getTableId,
|
|
386
390
|
getMetric,
|
|
@@ -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,49 @@ 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
|
+
|
|
408
470
|
/**
|
|
409
471
|
* The hasRelationship method returns a boolean indicating whether a given
|
|
410
472
|
* Relationship exists in the Relationships object.
|
|
@@ -52,6 +52,7 @@ 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);
|
|
55
56
|
const hasThing = (id) => collHas(things, id);
|
|
56
57
|
const getTableId = (id) => mapGet(tableIds, id);
|
|
57
58
|
const getThing = (id) => mapGet(things, id);
|
|
@@ -142,6 +143,7 @@ const getDefinableFunctions = (store, getDefaultThing, validateRowValue) => {
|
|
|
142
143
|
return [
|
|
143
144
|
getStore,
|
|
144
145
|
getThingIds,
|
|
146
|
+
forEachThing,
|
|
145
147
|
hasThing,
|
|
146
148
|
getTableId,
|
|
147
149
|
getThing,
|
|
@@ -249,6 +251,7 @@ const createRelationships = getCreateFunction((store) => {
|
|
|
249
251
|
const [
|
|
250
252
|
getStore,
|
|
251
253
|
getRelationshipIds,
|
|
254
|
+
forEachRelationshipImpl,
|
|
252
255
|
hasRelationship,
|
|
253
256
|
getLocalTableId,
|
|
254
257
|
getRelationship,
|
|
@@ -363,6 +366,12 @@ const createRelationships = getCreateFunction((store) => {
|
|
|
363
366
|
);
|
|
364
367
|
return relationships;
|
|
365
368
|
};
|
|
369
|
+
const forEachRelationship = (relationshipCallback) =>
|
|
370
|
+
forEachRelationshipImpl((relationshipId) =>
|
|
371
|
+
relationshipCallback(relationshipId, (rowCallback) =>
|
|
372
|
+
store.forEachRow(getLocalTableId(relationshipId), rowCallback),
|
|
373
|
+
),
|
|
374
|
+
);
|
|
366
375
|
const delRelationshipDefinition = (relationshipId) => {
|
|
367
376
|
mapSet(remoteTableIds, relationshipId);
|
|
368
377
|
delDefinition(relationshipId);
|
|
@@ -403,6 +412,7 @@ const createRelationships = getCreateFunction((store) => {
|
|
|
403
412
|
delRelationshipDefinition,
|
|
404
413
|
getStore,
|
|
405
414
|
getRelationshipIds,
|
|
415
|
+
forEachRelationship,
|
|
406
416
|
hasRelationship,
|
|
407
417
|
getLocalTableId,
|
|
408
418
|
getRemoteTableId,
|
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
|
|
@@ -1631,7 +1631,7 @@ export interface Store {
|
|
|
1631
1631
|
*
|
|
1632
1632
|
* This method is useful for iterating over the Table structure of the Store
|
|
1633
1633
|
* in a functional style. The `tableCallback` parameter is a TableCallback
|
|
1634
|
-
* 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
|
|
1635
1635
|
* that can then be used to iterate over each Row of the Table, should you
|
|
1636
1636
|
* wish.
|
|
1637
1637
|
*
|
|
@@ -1664,9 +1664,10 @@ export interface Store {
|
|
|
1664
1664
|
*
|
|
1665
1665
|
* This method is useful for iterating over the Row structure of the Table in
|
|
1666
1666
|
* a functional style. The `rowCallback` parameter is a RowCallback function
|
|
1667
|
-
* that will called with the Id of each Row, and with a function that can
|
|
1668
|
-
* 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.
|
|
1669
1669
|
*
|
|
1670
|
+
* @param tableId The Id of the Table to iterate over.
|
|
1670
1671
|
* @param rowCallback The function that should be called for every Row.
|
|
1671
1672
|
* @example
|
|
1672
1673
|
* This example iterates over each Row in a Table, and lists each Cell Id
|
|
@@ -1698,8 +1699,10 @@ export interface Store {
|
|
|
1698
1699
|
*
|
|
1699
1700
|
* This method is useful for iterating over the Cell structure of the Row in a
|
|
1700
1701
|
* functional style. The `cellCallback` parameter is a CellCallback function
|
|
1701
|
-
* that will called with the Id and value of each Cell.
|
|
1702
|
+
* that will be called with the Id and value of each Cell.
|
|
1702
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.
|
|
1703
1706
|
* @param cellCallback The function that should be called for every Cell.
|
|
1704
1707
|
* @example
|
|
1705
1708
|
* This example iterates over each Cell in a Row, and lists its value.
|