tinybase 2.0.0 → 2.1.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/checkpoints.js +1 -1
- package/lib/checkpoints.js.gz +0 -0
- package/lib/common.js +1 -1
- package/lib/common.js.gz +0 -0
- package/lib/debug/checkpoints.js +7 -1
- package/lib/debug/common.js +1 -4
- package/lib/debug/indexes.d.ts +36 -10
- package/lib/debug/indexes.js +57 -25
- package/lib/debug/metrics.d.ts +1 -1
- package/lib/debug/metrics.js +19 -2
- package/lib/debug/persisters.d.ts +5 -5
- package/lib/debug/queries.js +18 -2
- package/lib/debug/relationships.d.ts +3 -3
- package/lib/debug/relationships.js +19 -2
- package/lib/debug/store.js +8 -2
- package/lib/debug/tinybase.js +53 -27
- package/lib/debug/ui-react.d.ts +17 -17
- package/lib/debug/ui-react.js +2 -1
- package/lib/es6/checkpoints.d.ts +946 -0
- package/lib/es6/checkpoints.js +1 -0
- package/lib/es6/checkpoints.js.gz +0 -0
- package/lib/es6/common.d.ts +115 -0
- package/lib/es6/common.js +1 -0
- package/lib/es6/common.js.gz +0 -0
- package/lib/es6/indexes.d.ts +967 -0
- package/lib/es6/indexes.js +1 -0
- package/lib/es6/indexes.js.gz +0 -0
- package/lib/es6/metrics.d.ts +829 -0
- package/lib/es6/metrics.js +1 -0
- package/lib/es6/metrics.js.gz +0 -0
- package/lib/es6/persisters.d.ts +717 -0
- package/lib/es6/persisters.js +1 -0
- package/lib/es6/persisters.js.gz +0 -0
- package/lib/es6/queries.d.ts +3026 -0
- package/lib/es6/queries.js +1 -0
- package/lib/es6/queries.js.gz +0 -0
- package/lib/es6/relationships.d.ts +1203 -0
- package/lib/es6/relationships.js +1 -0
- package/lib/es6/relationships.js.gz +0 -0
- package/lib/es6/store.d.ts +3572 -0
- package/lib/es6/store.js +1 -0
- package/lib/es6/store.js.gz +0 -0
- package/lib/es6/tinybase.d.ts +14 -0
- package/lib/es6/tinybase.js +1 -0
- package/lib/es6/tinybase.js.gz +0 -0
- package/lib/es6/ui-react.d.ts +9777 -0
- package/lib/es6/ui-react.js +1 -0
- package/lib/es6/ui-react.js.gz +0 -0
- package/lib/indexes.d.ts +36 -10
- package/lib/indexes.js +1 -1
- package/lib/indexes.js.gz +0 -0
- package/lib/metrics.d.ts +1 -1
- package/lib/metrics.js +1 -1
- package/lib/metrics.js.gz +0 -0
- package/lib/persisters.d.ts +5 -5
- package/lib/queries.js +1 -1
- package/lib/queries.js.gz +0 -0
- package/lib/relationships.d.ts +3 -3
- package/lib/relationships.js +1 -1
- package/lib/relationships.js.gz +0 -0
- 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/ui-react.d.ts +17 -17
- package/lib/umd/checkpoints.d.ts +946 -0
- package/lib/umd/checkpoints.js +1 -1
- package/lib/umd/checkpoints.js.gz +0 -0
- package/lib/umd/common.d.ts +115 -0
- package/lib/umd/common.js +1 -1
- package/lib/umd/common.js.gz +0 -0
- package/lib/umd/indexes.d.ts +967 -0
- package/lib/umd/indexes.js +1 -1
- package/lib/umd/indexes.js.gz +0 -0
- package/lib/umd/metrics.d.ts +829 -0
- package/lib/umd/metrics.js +1 -1
- package/lib/umd/metrics.js.gz +0 -0
- package/lib/umd/persisters.d.ts +717 -0
- package/lib/umd/queries.d.ts +3026 -0
- package/lib/umd/queries.js +1 -1
- package/lib/umd/queries.js.gz +0 -0
- package/lib/umd/relationships.d.ts +1203 -0
- package/lib/umd/relationships.js +1 -1
- package/lib/umd/relationships.js.gz +0 -0
- package/lib/umd/store.d.ts +3572 -0
- package/lib/umd/store.js +1 -1
- package/lib/umd/store.js.gz +0 -0
- package/lib/umd/tinybase.d.ts +14 -0
- package/lib/umd/tinybase.js +1 -1
- package/lib/umd/tinybase.js.gz +0 -0
- package/lib/umd/ui-react.d.ts +9777 -0
- package/lib/umd-es6/checkpoints.d.ts +946 -0
- package/lib/umd-es6/checkpoints.js +1 -0
- package/lib/umd-es6/checkpoints.js.gz +0 -0
- package/lib/umd-es6/common.d.ts +115 -0
- package/lib/umd-es6/common.js +1 -0
- package/lib/umd-es6/common.js.gz +0 -0
- package/lib/umd-es6/indexes.d.ts +967 -0
- package/lib/umd-es6/indexes.js +1 -0
- package/lib/umd-es6/indexes.js.gz +0 -0
- package/lib/umd-es6/metrics.d.ts +829 -0
- package/lib/umd-es6/metrics.js +1 -0
- package/lib/umd-es6/metrics.js.gz +0 -0
- package/lib/umd-es6/persisters.d.ts +717 -0
- package/lib/umd-es6/persisters.js +1 -0
- package/lib/umd-es6/persisters.js.gz +0 -0
- package/lib/umd-es6/queries.d.ts +3026 -0
- package/lib/umd-es6/queries.js +1 -0
- package/lib/umd-es6/queries.js.gz +0 -0
- package/lib/umd-es6/relationships.d.ts +1203 -0
- package/lib/umd-es6/relationships.js +1 -0
- package/lib/umd-es6/relationships.js.gz +0 -0
- package/lib/umd-es6/store.d.ts +3572 -0
- package/lib/umd-es6/store.js +1 -0
- package/lib/umd-es6/store.js.gz +0 -0
- package/lib/umd-es6/tinybase.d.ts +14 -0
- package/lib/umd-es6/tinybase.js +1 -0
- package/lib/umd-es6/tinybase.js.gz +0 -0
- package/lib/umd-es6/ui-react.d.ts +9777 -0
- package/lib/umd-es6/ui-react.js +1 -0
- package/lib/umd-es6/ui-react.js.gz +0 -0
- package/package.json +2 -1
- package/readme.md +12 -12
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,r=e=>0==n(e),
|
|
1
|
+
const e=(e,t)=>e.includes(t),t=(e,t)=>e.forEach(t),n=e=>e.length,r=e=>0==n(e),s=(e,...t)=>e.push(...t),o=e=>e.pop(),l=e=>e.shift(),c=e=>null==e,i=(e,t,n)=>c(e)?n?.():t(e),a=(e,t)=>e?.has(t)??!1,d=e=>c(e)||0==(e=>e.size)(e),u=(e,t)=>e?.forEach(t),h=(e,t)=>e?.delete(t),p=e=>new Map(e),C=(e,t)=>e?.get(t),g=(e,t,n)=>c(n)?(h(e,t),e):e?.set(t,n),k=(e,t,n)=>(a(e,t)||g(e,t,n()),C(e,t)),f=(e,t,r,s,o=0)=>i((r?k:C)(e,t[o],o>n(t)-2?r:p),(l=>{if(o>n(t)-2)return s?.(l)&&g(e,t[o]),l;const c=f(l,t,r,s,o+1);return d(l)&&g(e,t[o]),c})),v=e=>new Set(Array.isArray(e)||c(e)?e:[e]),L=/^\d+$/,w=e=>{let r;const[o,a]=(()=>{const e=[];let t=0;return[()=>l(e)??""+t++,t=>{L.test(t)&&n(e)<1e3&&s(e,t)}]})(),k=p();return[(t,n,s)=>{r??=e();const l=o();var c,i;return g(k,l,[t,n,s]),c=f(n,s??[""],v),i=l,c?.add(i),l},(e,o,...l)=>t(((e,r=[""])=>{const o=[],l=(e,c)=>c==n(r)?s(o,e):null===r[c]?u(e,(e=>l(e,c+1))):t([r[c],null],(t=>l(C(e,t),c+1)));return l(e,0),o})(e,o),(e=>u(e,(e=>C(k,e)[0](r,...o??[],...l))))),e=>i(C(k,e),(([,t,n])=>(f(t,n??[""],void 0,(t=>(h(t,e),d(t)?1:0))),g(k,e),a(e),n))),(e,s,o)=>i(C(k,e),(([e,,l=[]])=>{const i=(...a)=>{const d=n(a);d==n(l)?e(r,...a,...o(a)):c(l[d])?t(s[d](...a),(e=>i(...a,e))):i(...a,l[d])};i()}))]},S=Object.freeze,y=(e=>{const t=new WeakMap;return n=>(t.has(n)||t.set(n,e(n)),t.get(n))})((h=>{let f,v,L,y=100,z=p(),E=1;const A=p(),I=p(),[M,b,j]=w((()=>Q)),x=p(),B=p(),F=[],O=[],T=(e,t)=>{E=0,h.transaction((()=>u(C(x,t),((t,n)=>u(t,((t,r)=>u(t,((t,s)=>((e,t,n,r,s)=>c(s)?e.delCell(t,n,r,!0):e.setCell(t,n,r,s))(h,n,r,s,t[e]))))))))),E=1},W=e=>{g(x,e),g(B,e),b(I,[e])},$=(e,r)=>t(((e,t)=>e.splice(0,t))(e,r??n(e)),W),m=()=>$(F,n(F)-y),q=h.addCellListener(null,null,null,((e,t,n,r,l,c)=>{if(E){i(f,(()=>{s(F,f),m(),$(O),f=void 0,L=1}));const e=k(z,t,p),a=k(e,n,p),u=k(a,r,(()=>[c,void 0]));u[1]=l,u[0]===l&&d(g(a,r))&&d(g(e,n))&&d(g(z,t))&&(f=o(F),L=1),J()}})),D=(e="")=>(c(f)&&(f=""+v++,g(x,f,z),N(f,e),z=p(),L=1),f),G=()=>{r(F)||(O.unshift(D()),T(0,f),f=o(F),L=1)},H=()=>{r(O)||(s(F,f),f=l(O),T(1,f),L=1)},J=()=>{L&&(b(A),L=0)},K=e=>{const t=D(e);return J(),t},N=(e,t)=>(P(e)&&C(B,e)!==t&&(g(B,e,t),b(I,[e])),Q),P=e=>a(x,e),Q={setSize:e=>(y=e,m(),Q),addCheckpoint:K,setCheckpoint:N,getStore:()=>h,getCheckpointIds:()=>[[...F],f,[...O]],forEachCheckpoint:e=>{return t=e,u(B,((e,n)=>t(n,e)));var t},hasCheckpoint:P,getCheckpoint:e=>C(B,e),goBackward:()=>(G(),J(),Q),goForward:()=>(H(),J(),Q),goTo:t=>{const n=e(F,t)?G:e(O,t)?H:null;for(;!c(n)&&t!=f;)n();return J(),Q},addCheckpointIdsListener:e=>M(e,A),addCheckpointListener:(e,t)=>M(t,I,[e]),delListener:e=>(j(e),Q),clear:()=>($(F),$(O),c(f)||W(f),f=void 0,v=0,K(),Q),destroy:()=>{h.delListener(q)},getListenerStats:()=>({})};return S(Q.clear())}));export{y as createCheckpoints};
|
package/lib/checkpoints.js.gz
CHANGED
|
Binary file
|
package/lib/common.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const o=(o,t)=>o<t?-1:1
|
|
1
|
+
const o=(o,t)=>o<t?-1:1;export{o as defaultSorter};
|
package/lib/common.js.gz
CHANGED
|
Binary file
|
package/lib/debug/checkpoints.js
CHANGED
|
@@ -13,6 +13,7 @@ const arrayShift = (array) => array.shift();
|
|
|
13
13
|
const isUndefined = (thing) => thing == void 0;
|
|
14
14
|
const ifNotUndefined = (value, then, otherwise) =>
|
|
15
15
|
isUndefined(value) ? otherwise?.() : then(value);
|
|
16
|
+
const isArray = (thing) => Array.isArray(thing);
|
|
16
17
|
|
|
17
18
|
const collSizeN = (collSizer) => (coll) =>
|
|
18
19
|
arrayReduce(collValues(coll), (total, coll2) => total + collSizer(coll2), 0);
|
|
@@ -58,7 +59,12 @@ const visitTree = (node, path, ensureLeaf, pruneLeaf, p = 0) =>
|
|
|
58
59
|
},
|
|
59
60
|
);
|
|
60
61
|
|
|
61
|
-
const setNew = (
|
|
62
|
+
const setNew = (entryOrEntries) =>
|
|
63
|
+
new Set(
|
|
64
|
+
isArray(entryOrEntries) || isUndefined(entryOrEntries)
|
|
65
|
+
? entryOrEntries
|
|
66
|
+
: [entryOrEntries],
|
|
67
|
+
);
|
|
62
68
|
const setAdd = (set, value) => set?.add(value);
|
|
63
69
|
|
|
64
70
|
const getCreateFunction = (getFunction) => {
|
package/lib/debug/common.js
CHANGED
package/lib/debug/indexes.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The indexes module of the TinyBase project provides the ability to create
|
|
3
|
-
*
|
|
2
|
+
* The indexes module of the TinyBase project provides the ability to create and
|
|
3
|
+
* 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
6
|
* returns a new Indexes object. From there, you can create new Index
|
|
@@ -209,11 +209,12 @@ export interface Indexes {
|
|
|
209
209
|
* derived string value in common, as described by this method. Those values
|
|
210
210
|
* are used as the key for each Slice in the overall Index object.
|
|
211
211
|
*
|
|
212
|
-
* Without the third `
|
|
212
|
+
* Without the third `getSliceIdOrIds` parameter, the Index will simply have a
|
|
213
213
|
* single Slice, keyed by an empty string. But more often you will specify a
|
|
214
214
|
* Cell value containing the Slice Id that the Row should belong to.
|
|
215
215
|
* Alternatively, a custom function can be provided that produces your own
|
|
216
|
-
* Slice Id from the local Row as a whole.
|
|
216
|
+
* Slice Id from the local Row as a whole. Since v2.1, the custom function can
|
|
217
|
+
* return an array of Slice Ids, each of which the Row will then belong to.
|
|
217
218
|
*
|
|
218
219
|
* The fourth `getSortKey` parameter specifies a Cell Id to get a value (or a
|
|
219
220
|
* function that processes a whole Row to get a value) that is used to sort
|
|
@@ -241,11 +242,13 @@ export interface Indexes {
|
|
|
241
242
|
*
|
|
242
243
|
* @param indexId The Id of the Index to define.
|
|
243
244
|
* @param tableId The Id of the Table the Index will be generated from.
|
|
244
|
-
* @param
|
|
245
|
-
* produces, the Id that is used to indicate which Slice in the Index the
|
|
246
|
-
* Id should be in. Defaults to a function that returns `''` (meaning that
|
|
247
|
-
* this `
|
|
248
|
-
* single Slice containing all the Row Ids in the Table).
|
|
245
|
+
* @param getSliceIdOrIds Either the Id of the Cell containing, or a function
|
|
246
|
+
* that produces, the Id that is used to indicate which Slice in the Index the
|
|
247
|
+
* Row Id should be in. Defaults to a function that returns `''` (meaning that
|
|
248
|
+
* if this `getSliceIdOrIds` parameter is omitted, the Index will simply
|
|
249
|
+
* contain a single Slice containing all the Row Ids in the Table). Since
|
|
250
|
+
* v2.1, this can return an array of Slice Ids, each of which the Row will
|
|
251
|
+
* then belong to.
|
|
249
252
|
* @param getSortKey Either the Id of the Cell containing, or a function that
|
|
250
253
|
* produces, the value that is used to sort the Row Ids in each Slice.
|
|
251
254
|
* @param sliceIdSorter A function that takes two Slice Id values and returns
|
|
@@ -294,6 +297,29 @@ export interface Indexes {
|
|
|
294
297
|
* ```
|
|
295
298
|
* @example
|
|
296
299
|
* This example creates a Store, creates an Indexes object, and defines an
|
|
300
|
+
* Index based on each of the letters present in the pets' names.
|
|
301
|
+
*
|
|
302
|
+
* ```js
|
|
303
|
+
* const store = createStore().setTable('pets', {
|
|
304
|
+
* fido: {species: 'dog'},
|
|
305
|
+
* felix: {species: 'cat'},
|
|
306
|
+
* rex: {species: 'dog'},
|
|
307
|
+
* });
|
|
308
|
+
*
|
|
309
|
+
* const indexes = createIndexes(store);
|
|
310
|
+
* indexes.setIndexDefinition('containsLetter', 'pets', (_, rowId) =>
|
|
311
|
+
* rowId.split(''),
|
|
312
|
+
* );
|
|
313
|
+
*
|
|
314
|
+
* console.log(indexes.getSliceIds('containsLetter'));
|
|
315
|
+
* // -> ['f', 'i', 'd', 'o', 'e', 'l', 'x', 'r']
|
|
316
|
+
* console.log(indexes.getSliceRowIds('containsLetter', 'i'));
|
|
317
|
+
* // -> ['fido', 'felix']
|
|
318
|
+
* console.log(indexes.getSliceRowIds('containsLetter', 'x'));
|
|
319
|
+
* // -> ['felix', 'rex']
|
|
320
|
+
* ```
|
|
321
|
+
* @example
|
|
322
|
+
* This example creates a Store, creates an Indexes object, and defines an
|
|
297
323
|
* Index based on the first letter of the pets' names. The Slice Ids (and Row
|
|
298
324
|
* Ids within them) are alphabetically sorted.
|
|
299
325
|
*
|
|
@@ -324,7 +350,7 @@ export interface Indexes {
|
|
|
324
350
|
setIndexDefinition(
|
|
325
351
|
indexId: Id,
|
|
326
352
|
tableId: Id,
|
|
327
|
-
|
|
353
|
+
getSliceIdOrIds?: Id | ((getCell: GetCell, rowId: Id) => Id | Ids),
|
|
328
354
|
getSortKey?: Id | ((getCell: GetCell, rowId: Id) => SortKey),
|
|
329
355
|
sliceIdSorter?: (sliceId1: Id, sliceId2: Id) => number,
|
|
330
356
|
rowIdSorter?: (sortKey1: SortKey, sortKey2: SortKey, sliceId: Id) => number,
|
package/lib/debug/indexes.js
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
const getTypeOf = (thing) => typeof thing;
|
|
2
2
|
const EMPTY_STRING = '';
|
|
3
3
|
const STRING = getTypeOf(EMPTY_STRING);
|
|
4
|
+
const id = (key) => EMPTY_STRING + key;
|
|
4
5
|
|
|
5
6
|
const arrayEvery = (array, cb) => array.every(cb);
|
|
7
|
+
const arrayIsEqual = (array1, array2) =>
|
|
8
|
+
arrayLength(array1) === arrayLength(array2) &&
|
|
9
|
+
arrayEvery(array1, (value1, index) => array2[index] === value1);
|
|
6
10
|
const arrayIsSorted = (array, sorter) =>
|
|
7
11
|
arrayEvery(
|
|
8
12
|
array,
|
|
@@ -10,6 +14,7 @@ const arrayIsSorted = (array, sorter) =>
|
|
|
10
14
|
);
|
|
11
15
|
const arraySort = (array, sorter) => array.sort(sorter);
|
|
12
16
|
const arrayForEach = (array, cb) => array.forEach(cb);
|
|
17
|
+
const arrayMap = (array, cb) => array.map(cb);
|
|
13
18
|
const arrayLength = (array) => array.length;
|
|
14
19
|
const arrayIsEmpty = (array) => arrayLength(array) == 0;
|
|
15
20
|
const arrayReduce = (array, cb, initial) => array.reduce(cb, initial);
|
|
@@ -20,6 +25,7 @@ const isUndefined = (thing) => thing == void 0;
|
|
|
20
25
|
const ifNotUndefined = (value, then, otherwise) =>
|
|
21
26
|
isUndefined(value) ? otherwise?.() : then(value);
|
|
22
27
|
const isString = (thing) => getTypeOf(thing) == STRING;
|
|
28
|
+
const isArray = (thing) => Array.isArray(thing);
|
|
23
29
|
|
|
24
30
|
const collSizeN = (collSizer) => (coll) =>
|
|
25
31
|
arrayReduce(collValues(coll), (total, coll2) => total + collSizer(coll2), 0);
|
|
@@ -68,7 +74,12 @@ const visitTree = (node, path, ensureLeaf, pruneLeaf, p = 0) =>
|
|
|
68
74
|
},
|
|
69
75
|
);
|
|
70
76
|
|
|
71
|
-
const setNew = (
|
|
77
|
+
const setNew = (entryOrEntries) =>
|
|
78
|
+
new Set(
|
|
79
|
+
isArray(entryOrEntries) || isUndefined(entryOrEntries)
|
|
80
|
+
? entryOrEntries
|
|
81
|
+
: [entryOrEntries],
|
|
82
|
+
);
|
|
72
83
|
const setAdd = (set, value) => set?.add(value);
|
|
73
84
|
|
|
74
85
|
const getDefinableFunctions = (store, getDefaultThing, validateRowValue) => {
|
|
@@ -133,7 +144,14 @@ const getDefinableFunctions = (store, getDefaultThing, validateRowValue) => {
|
|
|
133
144
|
const newRowValue = hasRow(tableId, rowId)
|
|
134
145
|
? validateRowValue(getRowValue(getCell, rowId))
|
|
135
146
|
: void 0;
|
|
136
|
-
if (
|
|
147
|
+
if (
|
|
148
|
+
!(
|
|
149
|
+
oldRowValue === newRowValue ||
|
|
150
|
+
(isArray(oldRowValue) &&
|
|
151
|
+
isArray(newRowValue) &&
|
|
152
|
+
arrayIsEqual(oldRowValue, newRowValue))
|
|
153
|
+
)
|
|
154
|
+
) {
|
|
137
155
|
mapSet(changedRowValues, rowId, [oldRowValue, newRowValue]);
|
|
138
156
|
}
|
|
139
157
|
if (!isUndefined(getSortKey)) {
|
|
@@ -312,7 +330,11 @@ const createIndexes = getCreateFunction((store) => {
|
|
|
312
330
|
delDefinition,
|
|
313
331
|
destroy,
|
|
314
332
|
] = getDefinableFunctions(store, mapNew, (value) =>
|
|
315
|
-
isUndefined(value)
|
|
333
|
+
isUndefined(value)
|
|
334
|
+
? EMPTY_STRING
|
|
335
|
+
: isArray(value)
|
|
336
|
+
? arrayMap(value, id)
|
|
337
|
+
: id(value),
|
|
316
338
|
);
|
|
317
339
|
const [addListener, callListeners, delListenerImpl] = getListenerFunctions(
|
|
318
340
|
() => indexes,
|
|
@@ -321,7 +343,7 @@ const createIndexes = getCreateFunction((store) => {
|
|
|
321
343
|
const setIndexDefinition = (
|
|
322
344
|
indexId,
|
|
323
345
|
tableId,
|
|
324
|
-
|
|
346
|
+
getSliceIdOrIds,
|
|
325
347
|
getSortKey,
|
|
326
348
|
sliceIdSorter,
|
|
327
349
|
rowIdSorter = defaultSorter,
|
|
@@ -337,29 +359,39 @@ const createIndexes = getCreateFunction((store) => {
|
|
|
337
359
|
const changedSlices = setNew();
|
|
338
360
|
const unsortedSlices = setNew();
|
|
339
361
|
const index = getIndex(indexId);
|
|
340
|
-
collForEach(
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
362
|
+
collForEach(
|
|
363
|
+
changedSliceIds,
|
|
364
|
+
([oldSliceIdOrIds, newSliceIdOrIds], rowId) => {
|
|
365
|
+
const oldSliceIds = setNew(oldSliceIdOrIds);
|
|
366
|
+
const newSliceIds = setNew(newSliceIdOrIds);
|
|
367
|
+
collForEach(oldSliceIds, (oldSliceId) =>
|
|
368
|
+
collDel(newSliceIds, oldSliceId)
|
|
369
|
+
? collDel(oldSliceIds, oldSliceId)
|
|
370
|
+
: 0,
|
|
371
|
+
);
|
|
372
|
+
collForEach(oldSliceIds, (oldSliceId) => {
|
|
373
|
+
setAdd(changedSlices, oldSliceId);
|
|
374
|
+
ifNotUndefined(mapGet(index, oldSliceId), (oldSlice) => {
|
|
375
|
+
collDel(oldSlice, rowId);
|
|
376
|
+
if (collIsEmpty(oldSlice)) {
|
|
377
|
+
mapSet(index, oldSliceId);
|
|
378
|
+
sliceIdsChanged = 1;
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
|
+
});
|
|
382
|
+
collForEach(newSliceIds, (newSliceId) => {
|
|
383
|
+
setAdd(changedSlices, newSliceId);
|
|
384
|
+
if (!collHas(index, newSliceId)) {
|
|
385
|
+
mapSet(index, newSliceId, setNew());
|
|
347
386
|
sliceIdsChanged = 1;
|
|
348
387
|
}
|
|
388
|
+
setAdd(mapGet(index, newSliceId), rowId);
|
|
389
|
+
if (!isUndefined(getSortKey)) {
|
|
390
|
+
setAdd(unsortedSlices, newSliceId);
|
|
391
|
+
}
|
|
349
392
|
});
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
setAdd(changedSlices, newSliceId);
|
|
353
|
-
if (!collHas(index, newSliceId)) {
|
|
354
|
-
mapSet(index, newSliceId, setNew());
|
|
355
|
-
sliceIdsChanged = 1;
|
|
356
|
-
}
|
|
357
|
-
setAdd(mapGet(index, newSliceId), rowId);
|
|
358
|
-
if (!isUndefined(getSortKey)) {
|
|
359
|
-
setAdd(unsortedSlices, newSliceId);
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
});
|
|
393
|
+
},
|
|
394
|
+
);
|
|
363
395
|
change();
|
|
364
396
|
if (!collIsEmpty(sortKeys)) {
|
|
365
397
|
if (force) {
|
|
@@ -408,7 +440,7 @@ const createIndexes = getCreateFunction((store) => {
|
|
|
408
440
|
callListeners(sliceRowIdsListeners, [indexId, sliceId]),
|
|
409
441
|
);
|
|
410
442
|
},
|
|
411
|
-
getRowCellFunction(
|
|
443
|
+
getRowCellFunction(getSliceIdOrIds),
|
|
412
444
|
ifNotUndefined(getSortKey, getRowCellFunction),
|
|
413
445
|
);
|
|
414
446
|
return indexes;
|
package/lib/debug/metrics.d.ts
CHANGED
|
@@ -210,7 +210,7 @@ export type MetricsListenerStats = {
|
|
|
210
210
|
*
|
|
211
211
|
* @example
|
|
212
212
|
* This example shows a very simple lifecycle of a Metrics object: from
|
|
213
|
-
* creation, to adding a definition, getting
|
|
213
|
+
* creation, to adding a definition, getting a Metric, and then registering and
|
|
214
214
|
* removing a listener for it.
|
|
215
215
|
*
|
|
216
216
|
* ```js
|
package/lib/debug/metrics.js
CHANGED
|
@@ -7,6 +7,10 @@ const AVG = 'avg';
|
|
|
7
7
|
const MIN = 'min';
|
|
8
8
|
const MAX = 'max';
|
|
9
9
|
|
|
10
|
+
const arrayEvery = (array, cb) => array.every(cb);
|
|
11
|
+
const arrayIsEqual = (array1, array2) =>
|
|
12
|
+
arrayLength(array1) === arrayLength(array2) &&
|
|
13
|
+
arrayEvery(array1, (value1, index) => array2[index] === value1);
|
|
10
14
|
const arrayForEach = (array, cb) => array.forEach(cb);
|
|
11
15
|
const arraySum = (array) => arrayReduce(array, (i, j) => i + j, 0);
|
|
12
16
|
const arrayLength = (array) => array.length;
|
|
@@ -23,6 +27,7 @@ const ifNotUndefined = (value, then, otherwise) =>
|
|
|
23
27
|
isUndefined(value) ? otherwise?.() : then(value);
|
|
24
28
|
const isString = (thing) => getTypeOf(thing) == STRING;
|
|
25
29
|
const isFunction = (thing) => getTypeOf(thing) == FUNCTION;
|
|
30
|
+
const isArray = (thing) => Array.isArray(thing);
|
|
26
31
|
const getUndefined = () => void 0;
|
|
27
32
|
|
|
28
33
|
const collSizeN = (collSizer) => (coll) =>
|
|
@@ -140,7 +145,12 @@ const getAggregateValue = (
|
|
|
140
145
|
: aggregateValue;
|
|
141
146
|
};
|
|
142
147
|
|
|
143
|
-
const setNew = (
|
|
148
|
+
const setNew = (entryOrEntries) =>
|
|
149
|
+
new Set(
|
|
150
|
+
isArray(entryOrEntries) || isUndefined(entryOrEntries)
|
|
151
|
+
? entryOrEntries
|
|
152
|
+
: [entryOrEntries],
|
|
153
|
+
);
|
|
144
154
|
const setAdd = (set, value) => set?.add(value);
|
|
145
155
|
|
|
146
156
|
const getDefinableFunctions = (store, getDefaultThing, validateRowValue) => {
|
|
@@ -205,7 +215,14 @@ const getDefinableFunctions = (store, getDefaultThing, validateRowValue) => {
|
|
|
205
215
|
const newRowValue = hasRow(tableId, rowId)
|
|
206
216
|
? validateRowValue(getRowValue(getCell, rowId))
|
|
207
217
|
: void 0;
|
|
208
|
-
if (
|
|
218
|
+
if (
|
|
219
|
+
!(
|
|
220
|
+
oldRowValue === newRowValue ||
|
|
221
|
+
(isArray(oldRowValue) &&
|
|
222
|
+
isArray(newRowValue) &&
|
|
223
|
+
arrayIsEqual(oldRowValue, newRowValue))
|
|
224
|
+
)
|
|
225
|
+
) {
|
|
209
226
|
mapSet(changedRowValues, rowId, [oldRowValue, newRowValue]);
|
|
210
227
|
}
|
|
211
228
|
if (!isUndefined(getSortKey)) {
|
|
@@ -509,7 +509,7 @@ export interface Persister {
|
|
|
509
509
|
}
|
|
510
510
|
|
|
511
511
|
/**
|
|
512
|
-
* The createSessionPersister function creates
|
|
512
|
+
* The createSessionPersister function creates a Persister object that can
|
|
513
513
|
* persist the Store to the browser's session storage.
|
|
514
514
|
*
|
|
515
515
|
* As well as providing a reference to the Store to persist, you must provide a
|
|
@@ -542,7 +542,7 @@ export function createSessionPersister(
|
|
|
542
542
|
): Persister;
|
|
543
543
|
|
|
544
544
|
/**
|
|
545
|
-
* The createLocalPersister function creates
|
|
545
|
+
* The createLocalPersister function creates a Persister object that can
|
|
546
546
|
* persist the Store to the browser's local storage.
|
|
547
547
|
*
|
|
548
548
|
* As well as providing a reference to the Store to persist, you must provide a
|
|
@@ -575,7 +575,7 @@ export function createLocalPersister(
|
|
|
575
575
|
): Persister;
|
|
576
576
|
|
|
577
577
|
/**
|
|
578
|
-
* The createRemotePersister function creates
|
|
578
|
+
* The createRemotePersister function creates a Persister object that can
|
|
579
579
|
* persist the Store to a remote server.
|
|
580
580
|
*
|
|
581
581
|
* As well as providing a reference to the Store to persist, you must provide
|
|
@@ -624,7 +624,7 @@ export function createRemotePersister(
|
|
|
624
624
|
): Persister;
|
|
625
625
|
|
|
626
626
|
/**
|
|
627
|
-
* The createFilePersister function creates
|
|
627
|
+
* The createFilePersister function creates a Persister object that can persist
|
|
628
628
|
* the Store to a local file (in an appropriate environment).
|
|
629
629
|
*
|
|
630
630
|
* As well as providing a reference to the Store to persist, you must provide
|
|
@@ -654,7 +654,7 @@ export function createRemotePersister(
|
|
|
654
654
|
export function createFilePersister(store: Store, filePath: string): Persister;
|
|
655
655
|
|
|
656
656
|
/**
|
|
657
|
-
* The createCustomPersister function creates
|
|
657
|
+
* The createCustomPersister function creates a Persister object that you can
|
|
658
658
|
* configure to persist the Store in any way you wish.
|
|
659
659
|
*
|
|
660
660
|
* As well as providing a reference to the Store to persist, you must provide
|
package/lib/debug/queries.js
CHANGED
|
@@ -20,6 +20,9 @@ const CELL_IDS = 'CellIds';
|
|
|
20
20
|
const CELL = 'Cell';
|
|
21
21
|
|
|
22
22
|
const arrayEvery = (array, cb) => array.every(cb);
|
|
23
|
+
const arrayIsEqual = (array1, array2) =>
|
|
24
|
+
arrayLength(array1) === arrayLength(array2) &&
|
|
25
|
+
arrayEvery(array1, (value1, index) => array2[index] === value1);
|
|
23
26
|
const arrayForEach = (array, cb) => array.forEach(cb);
|
|
24
27
|
const arraySum = (array) => arrayReduce(array, (i, j) => i + j, 0);
|
|
25
28
|
const arrayLength = (array) => array.length;
|
|
@@ -36,6 +39,7 @@ const ifNotUndefined = (value, then, otherwise) =>
|
|
|
36
39
|
isUndefined(value) ? otherwise?.() : then(value);
|
|
37
40
|
const isTypeStringOrBoolean = (type) => type == STRING || type == BOOLEAN;
|
|
38
41
|
const isFunction = (thing) => getTypeOf(thing) == FUNCTION;
|
|
42
|
+
const isArray = (thing) => Array.isArray(thing);
|
|
39
43
|
const getUndefined = () => void 0;
|
|
40
44
|
|
|
41
45
|
const collSize = (coll) => coll.size;
|
|
@@ -81,7 +85,12 @@ const visitTree = (node, path, ensureLeaf, pruneLeaf, p = 0) =>
|
|
|
81
85
|
},
|
|
82
86
|
);
|
|
83
87
|
|
|
84
|
-
const setNew = (
|
|
88
|
+
const setNew = (entryOrEntries) =>
|
|
89
|
+
new Set(
|
|
90
|
+
isArray(entryOrEntries) || isUndefined(entryOrEntries)
|
|
91
|
+
? entryOrEntries
|
|
92
|
+
: [entryOrEntries],
|
|
93
|
+
);
|
|
85
94
|
const setAdd = (set, value) => set?.add(value);
|
|
86
95
|
|
|
87
96
|
const numericAggregators = mapNew([
|
|
@@ -226,7 +235,14 @@ const getDefinableFunctions = (store, getDefaultThing, validateRowValue) => {
|
|
|
226
235
|
const newRowValue = hasRow(tableId, rowId)
|
|
227
236
|
? validateRowValue(getRowValue(getCell, rowId))
|
|
228
237
|
: void 0;
|
|
229
|
-
if (
|
|
238
|
+
if (
|
|
239
|
+
!(
|
|
240
|
+
oldRowValue === newRowValue ||
|
|
241
|
+
(isArray(oldRowValue) &&
|
|
242
|
+
isArray(newRowValue) &&
|
|
243
|
+
arrayIsEqual(oldRowValue, newRowValue))
|
|
244
|
+
)
|
|
245
|
+
) {
|
|
230
246
|
mapSet(changedRowValues, rowId, [oldRowValue, newRowValue]);
|
|
231
247
|
}
|
|
232
248
|
if (!isUndefined(getSortKey)) {
|
|
@@ -1091,7 +1091,7 @@ export interface Relationships {
|
|
|
1091
1091
|
* the underlying Store are removed and it can be correctly garbage collected.
|
|
1092
1092
|
*
|
|
1093
1093
|
* @example
|
|
1094
|
-
* This example creates a Store, adds
|
|
1094
|
+
* This example creates a Store, adds a Relationships object with a
|
|
1095
1095
|
* definition (that registers a RowListener with the underlying Store),
|
|
1096
1096
|
* and then destroys it again, removing the listener.
|
|
1097
1097
|
*
|
|
@@ -1167,7 +1167,7 @@ export interface Relationships {
|
|
|
1167
1167
|
}
|
|
1168
1168
|
|
|
1169
1169
|
/**
|
|
1170
|
-
* The createRelationships function creates
|
|
1170
|
+
* The createRelationships function creates a Relationships object, and is the
|
|
1171
1171
|
* main entry point into the relationships module.
|
|
1172
1172
|
*
|
|
1173
1173
|
* It is trivially simple.
|
|
@@ -1179,7 +1179,7 @@ export interface Relationships {
|
|
|
1179
1179
|
* @param store The Store for which to register Relationships.
|
|
1180
1180
|
* @returns A reference to the new Relationships object.
|
|
1181
1181
|
* @example
|
|
1182
|
-
* This example creates
|
|
1182
|
+
* This example creates a Relationships object.
|
|
1183
1183
|
*
|
|
1184
1184
|
* ```js
|
|
1185
1185
|
* const store = createStore();
|
|
@@ -2,6 +2,10 @@ const getTypeOf = (thing) => typeof thing;
|
|
|
2
2
|
const EMPTY_STRING = '';
|
|
3
3
|
const STRING = getTypeOf(EMPTY_STRING);
|
|
4
4
|
|
|
5
|
+
const arrayEvery = (array, cb) => array.every(cb);
|
|
6
|
+
const arrayIsEqual = (array1, array2) =>
|
|
7
|
+
arrayLength(array1) === arrayLength(array2) &&
|
|
8
|
+
arrayEvery(array1, (value1, index) => array2[index] === value1);
|
|
5
9
|
const arrayForEach = (array, cb) => array.forEach(cb);
|
|
6
10
|
const arrayLength = (array) => array.length;
|
|
7
11
|
const arrayIsEmpty = (array) => arrayLength(array) == 0;
|
|
@@ -13,6 +17,7 @@ const isUndefined = (thing) => thing == void 0;
|
|
|
13
17
|
const ifNotUndefined = (value, then, otherwise) =>
|
|
14
18
|
isUndefined(value) ? otherwise?.() : then(value);
|
|
15
19
|
const isString = (thing) => getTypeOf(thing) == STRING;
|
|
20
|
+
const isArray = (thing) => Array.isArray(thing);
|
|
16
21
|
|
|
17
22
|
const collSizeN = (collSizer) => (coll) =>
|
|
18
23
|
arrayReduce(collValues(coll), (total, coll2) => total + collSizer(coll2), 0);
|
|
@@ -61,7 +66,12 @@ const visitTree = (node, path, ensureLeaf, pruneLeaf, p = 0) =>
|
|
|
61
66
|
},
|
|
62
67
|
);
|
|
63
68
|
|
|
64
|
-
const setNew = (
|
|
69
|
+
const setNew = (entryOrEntries) =>
|
|
70
|
+
new Set(
|
|
71
|
+
isArray(entryOrEntries) || isUndefined(entryOrEntries)
|
|
72
|
+
? entryOrEntries
|
|
73
|
+
: [entryOrEntries],
|
|
74
|
+
);
|
|
65
75
|
const setAdd = (set, value) => set?.add(value);
|
|
66
76
|
|
|
67
77
|
const getDefinableFunctions = (store, getDefaultThing, validateRowValue) => {
|
|
@@ -126,7 +136,14 @@ const getDefinableFunctions = (store, getDefaultThing, validateRowValue) => {
|
|
|
126
136
|
const newRowValue = hasRow(tableId, rowId)
|
|
127
137
|
? validateRowValue(getRowValue(getCell, rowId))
|
|
128
138
|
: void 0;
|
|
129
|
-
if (
|
|
139
|
+
if (
|
|
140
|
+
!(
|
|
141
|
+
oldRowValue === newRowValue ||
|
|
142
|
+
(isArray(oldRowValue) &&
|
|
143
|
+
isArray(newRowValue) &&
|
|
144
|
+
arrayIsEqual(oldRowValue, newRowValue))
|
|
145
|
+
)
|
|
146
|
+
) {
|
|
130
147
|
mapSet(changedRowValues, rowId, [oldRowValue, newRowValue]);
|
|
131
148
|
}
|
|
132
149
|
if (!isUndefined(getSortKey)) {
|
package/lib/debug/store.js
CHANGED
|
@@ -16,6 +16,7 @@ const ROW_IDS = 'RowIds';
|
|
|
16
16
|
const ROW = 'Row';
|
|
17
17
|
const CELL_IDS = 'CellIds';
|
|
18
18
|
const CELL = 'Cell';
|
|
19
|
+
const id = (key) => EMPTY_STRING + key;
|
|
19
20
|
|
|
20
21
|
const arrayHas = (array, value) => array.includes(value);
|
|
21
22
|
const arrayEvery = (array, cb) => array.every(cb);
|
|
@@ -54,6 +55,7 @@ const ifNotUndefined = (value, then, otherwise) =>
|
|
|
54
55
|
isUndefined(value) ? otherwise?.() : then(value);
|
|
55
56
|
const isTypeStringOrBoolean = (type) => type == STRING || type == BOOLEAN;
|
|
56
57
|
const isFunction = (thing) => getTypeOf(thing) == FUNCTION;
|
|
58
|
+
const isArray = (thing) => Array.isArray(thing);
|
|
57
59
|
|
|
58
60
|
const collSizeN = (collSizer) => (coll) =>
|
|
59
61
|
arrayReduce(collValues(coll), (total, coll2) => total + collSizer(coll2), 0);
|
|
@@ -133,7 +135,12 @@ const objForEach = (obj, cb) =>
|
|
|
133
135
|
arrayForEach(object.entries(obj), ([id, value]) => cb(value, id));
|
|
134
136
|
const objIsEmpty = (obj) => arrayIsEmpty(objIds(obj));
|
|
135
137
|
|
|
136
|
-
const setNew = (
|
|
138
|
+
const setNew = (entryOrEntries) =>
|
|
139
|
+
new Set(
|
|
140
|
+
isArray(entryOrEntries) || isUndefined(entryOrEntries)
|
|
141
|
+
? entryOrEntries
|
|
142
|
+
: [entryOrEntries],
|
|
143
|
+
);
|
|
137
144
|
const setAdd = (set, value) => set?.add(value);
|
|
138
145
|
|
|
139
146
|
const INTEGER = /^\d+$/;
|
|
@@ -221,7 +228,6 @@ const setOrDelCell = (store, tableId, rowId, cellId, cell) =>
|
|
|
221
228
|
: store.setCell(tableId, rowId, cellId, cell);
|
|
222
229
|
|
|
223
230
|
const defaultSorter = (sortKey1, sortKey2) => (sortKey1 < sortKey2 ? -1 : 1);
|
|
224
|
-
const id = (key) => EMPTY_STRING + key;
|
|
225
231
|
|
|
226
232
|
const transformMap = (map, toBeLikeObject, setId, delId = mapSet) => {
|
|
227
233
|
const idsToDelete = arrayFilter(
|