tinybase 2.1.0 → 2.2.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/bin/cli.js +2 -0
- package/lib/checkpoints.d.ts +0 -2
- package/lib/checkpoints.js +1 -1
- package/lib/checkpoints.js.gz +0 -0
- package/lib/debug/checkpoints.d.ts +0 -2
- package/lib/debug/checkpoints.js +4 -2
- package/lib/debug/indexes.d.ts +0 -2
- package/lib/debug/indexes.js +2 -1
- package/lib/debug/metrics.d.ts +0 -2
- package/lib/debug/metrics.js +2 -1
- package/lib/debug/queries.d.ts +0 -2
- package/lib/debug/relationships.d.ts +0 -2
- package/lib/debug/relationships.js +2 -1
- package/lib/debug/store.d.ts +1 -1
- package/lib/debug/store.js +12 -13
- package/lib/debug/tinybase.js +14 -14
- package/lib/debug/tools.d.ts +290 -0
- package/lib/debug/tools.js +955 -0
- package/lib/es6/checkpoints.d.ts +0 -2
- package/lib/es6/checkpoints.js +1 -1
- package/lib/es6/checkpoints.js.gz +0 -0
- package/lib/es6/indexes.d.ts +0 -2
- package/lib/es6/metrics.d.ts +0 -2
- package/lib/es6/queries.d.ts +0 -2
- package/lib/es6/relationships.d.ts +0 -2
- package/lib/es6/store.d.ts +1 -1
- package/lib/es6/store.js +1 -1
- package/lib/es6/store.js.gz +0 -0
- package/lib/es6/tinybase.js +1 -1
- package/lib/es6/tinybase.js.gz +0 -0
- package/lib/es6/tools.d.ts +290 -0
- package/lib/es6/tools.js +1 -0
- package/lib/es6/tools.js.gz +0 -0
- package/lib/indexes.d.ts +0 -2
- package/lib/metrics.d.ts +0 -2
- package/lib/queries.d.ts +0 -2
- package/lib/relationships.d.ts +0 -2
- package/lib/store.d.ts +1 -1
- 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/tools.d.ts +290 -0
- package/lib/tools.js +1 -0
- package/lib/tools.js.gz +0 -0
- package/lib/umd/checkpoints.d.ts +0 -2
- package/lib/umd/checkpoints.js +1 -1
- package/lib/umd/checkpoints.js.gz +0 -0
- package/lib/umd/common.js +1 -1
- package/lib/umd/common.js.gz +0 -0
- package/lib/umd/indexes.d.ts +0 -2
- package/lib/umd/indexes.js +1 -1
- package/lib/umd/indexes.js.gz +0 -0
- package/lib/umd/metrics.d.ts +0 -2
- package/lib/umd/metrics.js +1 -1
- package/lib/umd/metrics.js.gz +0 -0
- package/lib/umd/persisters.js +1 -1
- package/lib/umd/persisters.js.gz +0 -0
- package/lib/umd/queries.d.ts +0 -2
- package/lib/umd/queries.js +1 -1
- package/lib/umd/queries.js.gz +0 -0
- package/lib/umd/relationships.d.ts +0 -2
- package/lib/umd/relationships.js +1 -1
- package/lib/umd/relationships.js.gz +0 -0
- package/lib/umd/store.d.ts +1 -1
- 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/lib/umd/tools.d.ts +290 -0
- package/lib/umd/tools.js +1 -0
- package/lib/umd/tools.js.gz +0 -0
- package/lib/umd/ui-react.js +1 -1
- package/lib/umd/ui-react.js.gz +0 -0
- package/lib/umd-es6/checkpoints.d.ts +0 -2
- package/lib/umd-es6/checkpoints.js +1 -1
- package/lib/umd-es6/checkpoints.js.gz +0 -0
- package/lib/umd-es6/common.js +1 -1
- package/lib/umd-es6/common.js.gz +0 -0
- package/lib/umd-es6/indexes.d.ts +0 -2
- package/lib/umd-es6/indexes.js +1 -1
- package/lib/umd-es6/indexes.js.gz +0 -0
- package/lib/umd-es6/metrics.d.ts +0 -2
- package/lib/umd-es6/metrics.js +1 -1
- package/lib/umd-es6/metrics.js.gz +0 -0
- package/lib/umd-es6/persisters.js +1 -1
- package/lib/umd-es6/persisters.js.gz +0 -0
- package/lib/umd-es6/queries.d.ts +0 -2
- package/lib/umd-es6/queries.js +1 -1
- package/lib/umd-es6/queries.js.gz +0 -0
- package/lib/umd-es6/relationships.d.ts +0 -2
- package/lib/umd-es6/relationships.js +1 -1
- package/lib/umd-es6/relationships.js.gz +0 -0
- package/lib/umd-es6/store.d.ts +1 -1
- package/lib/umd-es6/store.js +1 -1
- package/lib/umd-es6/store.js.gz +0 -0
- package/lib/umd-es6/tinybase.js +1 -1
- package/lib/umd-es6/tinybase.js.gz +0 -0
- package/lib/umd-es6/tools.d.ts +290 -0
- package/lib/umd-es6/tools.js +1 -0
- package/lib/umd-es6/tools.js.gz +0 -0
- package/lib/umd-es6/ui-react.js +1 -1
- package/lib/umd-es6/ui-react.js.gz +0 -0
- package/package.json +36 -27
- package/readme.md +12 -12
package/bin/cli.js
ADDED
package/lib/checkpoints.d.ts
CHANGED
|
@@ -913,8 +913,6 @@ export interface Checkpoints {
|
|
|
913
913
|
* The createCheckpoints function creates a Checkpoints object, and is the main
|
|
914
914
|
* entry point into the checkpoints module.
|
|
915
915
|
*
|
|
916
|
-
* It is trivially simple.
|
|
917
|
-
*
|
|
918
916
|
* A given Store can only have one Checkpoints object associated with it. If you
|
|
919
917
|
* call this function twice on the same Store, your second call will return a
|
|
920
918
|
* reference to the Checkpoints object created by the first.
|
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),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)||(
|
|
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)||(((e,...t)=>{e.unshift(...t)})(O,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
|
|
@@ -913,8 +913,6 @@ export interface Checkpoints {
|
|
|
913
913
|
* The createCheckpoints function creates a Checkpoints object, and is the main
|
|
914
914
|
* entry point into the checkpoints module.
|
|
915
915
|
*
|
|
916
|
-
* It is trivially simple.
|
|
917
|
-
*
|
|
918
916
|
* A given Store can only have one Checkpoints object associated with it. If you
|
|
919
917
|
* call this function twice on the same Store, your second call will return a
|
|
920
918
|
* reference to the Checkpoints object created by the first.
|
package/lib/debug/checkpoints.js
CHANGED
|
@@ -8,12 +8,14 @@ const arrayReduce = (array, cb, initial) => array.reduce(cb, initial);
|
|
|
8
8
|
const arrayClear = (array, to) => array.splice(0, to);
|
|
9
9
|
const arrayPush = (array, ...values) => array.push(...values);
|
|
10
10
|
const arrayPop = (array) => array.pop();
|
|
11
|
+
const arrayUnshift = (array, ...values) => array.unshift(...values);
|
|
11
12
|
const arrayShift = (array) => array.shift();
|
|
12
13
|
|
|
13
14
|
const isUndefined = (thing) => thing == void 0;
|
|
14
15
|
const ifNotUndefined = (value, then, otherwise) =>
|
|
15
16
|
isUndefined(value) ? otherwise?.() : then(value);
|
|
16
17
|
const isArray = (thing) => Array.isArray(thing);
|
|
18
|
+
const test = (regex, subject) => regex.test(subject);
|
|
17
19
|
|
|
18
20
|
const collSizeN = (collSizer) => (coll) =>
|
|
19
21
|
arrayReduce(collValues(coll), (total, coll2) => total + collSizer(coll2), 0);
|
|
@@ -84,7 +86,7 @@ const getPoolFunctions = () => {
|
|
|
84
86
|
return [
|
|
85
87
|
() => arrayShift(pool) ?? EMPTY_STRING + nextId++,
|
|
86
88
|
(id) => {
|
|
87
|
-
if (
|
|
89
|
+
if (test(INTEGER, id) && arrayLength(pool) < 1e3) {
|
|
88
90
|
arrayPush(pool, id);
|
|
89
91
|
}
|
|
90
92
|
},
|
|
@@ -238,7 +240,7 @@ const createCheckpoints = getCreateFunction((store) => {
|
|
|
238
240
|
};
|
|
239
241
|
const goBackwardImpl = () => {
|
|
240
242
|
if (!arrayIsEmpty(backwardIds)) {
|
|
241
|
-
forwardIds
|
|
243
|
+
arrayUnshift(forwardIds, addCheckpointImpl());
|
|
242
244
|
updateStore(0, currentId);
|
|
243
245
|
currentId = arrayPop(backwardIds);
|
|
244
246
|
checkpointsChanged = 1;
|
package/lib/debug/indexes.d.ts
CHANGED
|
@@ -935,8 +935,6 @@ export interface Indexes {
|
|
|
935
935
|
* The createIndexes function creates an Indexes object, and is the main entry
|
|
936
936
|
* point into the indexes module.
|
|
937
937
|
*
|
|
938
|
-
* It is trivially simple.
|
|
939
|
-
*
|
|
940
938
|
* A given Store can only have one Indexes object associated with it. If you
|
|
941
939
|
* call this function twice on the same Store, your second call will return a
|
|
942
940
|
* reference to the Indexes object created by the first.
|
package/lib/debug/indexes.js
CHANGED
|
@@ -26,6 +26,7 @@ const ifNotUndefined = (value, then, otherwise) =>
|
|
|
26
26
|
isUndefined(value) ? otherwise?.() : then(value);
|
|
27
27
|
const isString = (thing) => getTypeOf(thing) == STRING;
|
|
28
28
|
const isArray = (thing) => Array.isArray(thing);
|
|
29
|
+
const test = (regex, subject) => regex.test(subject);
|
|
29
30
|
|
|
30
31
|
const collSizeN = (collSizer) => (coll) =>
|
|
31
32
|
arrayReduce(collValues(coll), (total, coll2) => total + collSizer(coll2), 0);
|
|
@@ -249,7 +250,7 @@ const getPoolFunctions = () => {
|
|
|
249
250
|
return [
|
|
250
251
|
() => arrayShift(pool) ?? EMPTY_STRING + nextId++,
|
|
251
252
|
(id) => {
|
|
252
|
-
if (
|
|
253
|
+
if (test(INTEGER, id) && arrayLength(pool) < 1e3) {
|
|
253
254
|
arrayPush(pool, id);
|
|
254
255
|
}
|
|
255
256
|
},
|
package/lib/debug/metrics.d.ts
CHANGED
|
@@ -796,8 +796,6 @@ export interface Metrics {
|
|
|
796
796
|
* The createMetrics function creates a Metrics object, and is the main entry
|
|
797
797
|
* point into the metrics module.
|
|
798
798
|
*
|
|
799
|
-
* It is trivially simple.
|
|
800
|
-
*
|
|
801
799
|
* A given Store can only have one Metrics object associated with it. If you
|
|
802
800
|
* call this function twice on the same Store, your second call will return a
|
|
803
801
|
* reference to the Metrics object created by the first.
|
package/lib/debug/metrics.js
CHANGED
|
@@ -28,6 +28,7 @@ const ifNotUndefined = (value, then, otherwise) =>
|
|
|
28
28
|
const isString = (thing) => getTypeOf(thing) == STRING;
|
|
29
29
|
const isFunction = (thing) => getTypeOf(thing) == FUNCTION;
|
|
30
30
|
const isArray = (thing) => Array.isArray(thing);
|
|
31
|
+
const test = (regex, subject) => regex.test(subject);
|
|
31
32
|
const getUndefined = () => void 0;
|
|
32
33
|
|
|
33
34
|
const collSizeN = (collSizer) => (coll) =>
|
|
@@ -318,7 +319,7 @@ const getPoolFunctions = () => {
|
|
|
318
319
|
return [
|
|
319
320
|
() => arrayShift(pool) ?? EMPTY_STRING + nextId++,
|
|
320
321
|
(id) => {
|
|
321
|
-
if (
|
|
322
|
+
if (test(INTEGER, id) && arrayLength(pool) < 1e3) {
|
|
322
323
|
arrayPush(pool, id);
|
|
323
324
|
}
|
|
324
325
|
},
|
package/lib/debug/queries.d.ts
CHANGED
|
@@ -2992,8 +2992,6 @@ export interface Queries {
|
|
|
2992
2992
|
* The createQueries function creates a Queries object, and is the main entry
|
|
2993
2993
|
* point into the queries module.
|
|
2994
2994
|
*
|
|
2995
|
-
* It is trivially simple.
|
|
2996
|
-
*
|
|
2997
2995
|
* A given Store can only have one Queries object associated with it. If you
|
|
2998
2996
|
* call this function twice on the same Store, your second call will return a
|
|
2999
2997
|
* reference to the Queries object created by the first.
|
|
@@ -1170,8 +1170,6 @@ export interface Relationships {
|
|
|
1170
1170
|
* The createRelationships function creates a Relationships object, and is the
|
|
1171
1171
|
* main entry point into the relationships module.
|
|
1172
1172
|
*
|
|
1173
|
-
* It is trivially simple.
|
|
1174
|
-
*
|
|
1175
1173
|
* A given Store can only have one Relationships object associated with it. If
|
|
1176
1174
|
* you call this function twice on the same Store, your second call will return
|
|
1177
1175
|
* a reference to the Relationships object created by the first.
|
|
@@ -18,6 +18,7 @@ const ifNotUndefined = (value, then, otherwise) =>
|
|
|
18
18
|
isUndefined(value) ? otherwise?.() : then(value);
|
|
19
19
|
const isString = (thing) => getTypeOf(thing) == STRING;
|
|
20
20
|
const isArray = (thing) => Array.isArray(thing);
|
|
21
|
+
const test = (regex, subject) => regex.test(subject);
|
|
21
22
|
|
|
22
23
|
const collSizeN = (collSizer) => (coll) =>
|
|
23
24
|
arrayReduce(collValues(coll), (total, coll2) => total + collSizer(coll2), 0);
|
|
@@ -239,7 +240,7 @@ const getPoolFunctions = () => {
|
|
|
239
240
|
return [
|
|
240
241
|
() => arrayShift(pool) ?? EMPTY_STRING + nextId++,
|
|
241
242
|
(id) => {
|
|
242
|
-
if (
|
|
243
|
+
if (test(INTEGER, id) && arrayLength(pool) < 1e3) {
|
|
243
244
|
arrayPush(pool, id);
|
|
244
245
|
}
|
|
245
246
|
},
|
package/lib/debug/store.d.ts
CHANGED
package/lib/debug/store.js
CHANGED
|
@@ -56,6 +56,7 @@ const ifNotUndefined = (value, then, otherwise) =>
|
|
|
56
56
|
const isTypeStringOrBoolean = (type) => type == STRING || type == BOOLEAN;
|
|
57
57
|
const isFunction = (thing) => getTypeOf(thing) == FUNCTION;
|
|
58
58
|
const isArray = (thing) => Array.isArray(thing);
|
|
59
|
+
const test = (regex, subject) => regex.test(subject);
|
|
59
60
|
|
|
60
61
|
const collSizeN = (collSizer) => (coll) =>
|
|
61
62
|
arrayReduce(collValues(coll), (total, coll2) => total + collSizer(coll2), 0);
|
|
@@ -75,6 +76,8 @@ const mapKeys = (map) => [...(map?.keys() ?? [])];
|
|
|
75
76
|
const mapGet = (map, key) => map?.get(key);
|
|
76
77
|
const mapForEach = (map, cb) =>
|
|
77
78
|
collForEach(map, (value, key) => cb(key, value));
|
|
79
|
+
const mapMap = (coll, cb) =>
|
|
80
|
+
arrayMap([...(coll?.entries() ?? [])], ([key, value]) => cb(value, key));
|
|
78
81
|
const mapSet = (map, key, value) =>
|
|
79
82
|
isUndefined(value) ? (collDel(map, key), map) : map?.set(key, value);
|
|
80
83
|
const mapEnsure = (map, key, getDefaultValue) => {
|
|
@@ -150,7 +153,7 @@ const getPoolFunctions = () => {
|
|
|
150
153
|
return [
|
|
151
154
|
() => arrayShift(pool) ?? EMPTY_STRING + nextId++,
|
|
152
155
|
(id) => {
|
|
153
|
-
if (
|
|
156
|
+
if (test(INTEGER, id) && arrayLength(pool) < 1e3) {
|
|
154
157
|
arrayPush(pool, id);
|
|
155
158
|
}
|
|
156
159
|
},
|
|
@@ -464,6 +467,7 @@ const createStore = () => {
|
|
|
464
467
|
if (collIsEmpty(mapSet(table, rowId))) {
|
|
465
468
|
tableIdsChanged(tableId, -1);
|
|
466
469
|
mapSet(tablesMap, tableId);
|
|
470
|
+
mapSet(tablePoolFunctions, tableId);
|
|
467
471
|
}
|
|
468
472
|
}
|
|
469
473
|
};
|
|
@@ -634,18 +638,14 @@ const createStore = () => {
|
|
|
634
638
|
const getTable = (tableId) =>
|
|
635
639
|
mapToObj(mapGet(tablesMap, id(tableId)), mapToObj);
|
|
636
640
|
const getRowIds = (tableId) => mapKeys(mapGet(tablesMap, id(tableId)));
|
|
637
|
-
const getSortedRowIds = (tableId, cellId, descending, offset = 0, limit) =>
|
|
638
|
-
|
|
639
|
-
mapForEach(mapGet(tablesMap, id(tableId)), (rowId, row) =>
|
|
640
|
-
arrayPush(cells, [
|
|
641
|
-
isUndefined(cellId) ? rowId : mapGet(row, id(cellId)),
|
|
642
|
-
rowId,
|
|
643
|
-
]),
|
|
644
|
-
);
|
|
645
|
-
return arrayMap(
|
|
641
|
+
const getSortedRowIds = (tableId, cellId, descending, offset = 0, limit) =>
|
|
642
|
+
arrayMap(
|
|
646
643
|
arraySlice(
|
|
647
644
|
arraySort(
|
|
648
|
-
|
|
645
|
+
mapMap(mapGet(tablesMap, id(tableId)), (row, rowId) => [
|
|
646
|
+
isUndefined(cellId) ? rowId : mapGet(row, id(cellId)),
|
|
647
|
+
rowId,
|
|
648
|
+
]),
|
|
649
649
|
([cell1], [cell2]) =>
|
|
650
650
|
defaultSorter(cell1, cell2) * (descending ? -1 : 1),
|
|
651
651
|
),
|
|
@@ -654,7 +654,6 @@ const createStore = () => {
|
|
|
654
654
|
),
|
|
655
655
|
([, rowId]) => rowId,
|
|
656
656
|
);
|
|
657
|
-
};
|
|
658
657
|
const getRow = (tableId, rowId) =>
|
|
659
658
|
mapToObj(mapGet(mapGet(tablesMap, id(tableId)), id(rowId)));
|
|
660
659
|
const getCellIds = (tableId, rowId) =>
|
|
@@ -809,7 +808,7 @@ const createStore = () => {
|
|
|
809
808
|
return;
|
|
810
809
|
}
|
|
811
810
|
startTransaction();
|
|
812
|
-
const result = actions
|
|
811
|
+
const result = actions();
|
|
813
812
|
finishTransaction(doRollback);
|
|
814
813
|
return result;
|
|
815
814
|
};
|
package/lib/debug/tinybase.js
CHANGED
|
@@ -50,6 +50,7 @@ const arraySlice = (array, start, end) => array.slice(start, end);
|
|
|
50
50
|
const arrayClear = (array, to) => array.splice(0, to);
|
|
51
51
|
const arrayPush = (array, ...values) => array.push(...values);
|
|
52
52
|
const arrayPop = (array) => array.pop();
|
|
53
|
+
const arrayUnshift = (array, ...values) => array.unshift(...values);
|
|
53
54
|
const arrayShift = (array) => array.shift();
|
|
54
55
|
|
|
55
56
|
const jsonString = (obj) =>
|
|
@@ -77,6 +78,7 @@ const isTypeStringOrBoolean = (type) => type == STRING || type == BOOLEAN;
|
|
|
77
78
|
const isString = (thing) => getTypeOf(thing) == STRING;
|
|
78
79
|
const isFunction = (thing) => getTypeOf(thing) == FUNCTION;
|
|
79
80
|
const isArray = (thing) => Array.isArray(thing);
|
|
81
|
+
const test = (regex, subject) => regex.test(subject);
|
|
80
82
|
const getUndefined = () => void 0;
|
|
81
83
|
|
|
82
84
|
const collSizeN = (collSizer) => (coll) =>
|
|
@@ -97,6 +99,8 @@ const mapKeys = (map) => [...(map?.keys() ?? [])];
|
|
|
97
99
|
const mapGet = (map, key) => map?.get(key);
|
|
98
100
|
const mapForEach = (map, cb) =>
|
|
99
101
|
collForEach(map, (value, key) => cb(key, value));
|
|
102
|
+
const mapMap = (coll, cb) =>
|
|
103
|
+
arrayMap([...(coll?.entries() ?? [])], ([key, value]) => cb(value, key));
|
|
100
104
|
const mapSet = (map, key, value) =>
|
|
101
105
|
isUndefined(value) ? (collDel(map, key), map) : map?.set(key, value);
|
|
102
106
|
const mapEnsure = (map, key, getDefaultValue) => {
|
|
@@ -317,7 +321,7 @@ const getPoolFunctions = () => {
|
|
|
317
321
|
return [
|
|
318
322
|
() => arrayShift(pool) ?? EMPTY_STRING + nextId++,
|
|
319
323
|
(id) => {
|
|
320
|
-
if (
|
|
324
|
+
if (test(INTEGER, id) && arrayLength(pool) < 1e3) {
|
|
321
325
|
arrayPush(pool, id);
|
|
322
326
|
}
|
|
323
327
|
},
|
|
@@ -487,7 +491,7 @@ const createCheckpoints = getCreateFunction((store) => {
|
|
|
487
491
|
};
|
|
488
492
|
const goBackwardImpl = () => {
|
|
489
493
|
if (!arrayIsEmpty(backwardIds)) {
|
|
490
|
-
forwardIds
|
|
494
|
+
arrayUnshift(forwardIds, addCheckpointImpl());
|
|
491
495
|
updateStore(0, currentId);
|
|
492
496
|
currentId = arrayPop(backwardIds);
|
|
493
497
|
checkpointsChanged = 1;
|
|
@@ -1995,6 +1999,7 @@ const createStore = () => {
|
|
|
1995
1999
|
if (collIsEmpty(mapSet(table, rowId))) {
|
|
1996
2000
|
tableIdsChanged(tableId, -1);
|
|
1997
2001
|
mapSet(tablesMap, tableId);
|
|
2002
|
+
mapSet(tablePoolFunctions, tableId);
|
|
1998
2003
|
}
|
|
1999
2004
|
}
|
|
2000
2005
|
};
|
|
@@ -2165,18 +2170,14 @@ const createStore = () => {
|
|
|
2165
2170
|
const getTable = (tableId) =>
|
|
2166
2171
|
mapToObj(mapGet(tablesMap, id(tableId)), mapToObj);
|
|
2167
2172
|
const getRowIds = (tableId) => mapKeys(mapGet(tablesMap, id(tableId)));
|
|
2168
|
-
const getSortedRowIds = (tableId, cellId, descending, offset = 0, limit) =>
|
|
2169
|
-
|
|
2170
|
-
mapForEach(mapGet(tablesMap, id(tableId)), (rowId, row) =>
|
|
2171
|
-
arrayPush(cells, [
|
|
2172
|
-
isUndefined(cellId) ? rowId : mapGet(row, id(cellId)),
|
|
2173
|
-
rowId,
|
|
2174
|
-
]),
|
|
2175
|
-
);
|
|
2176
|
-
return arrayMap(
|
|
2173
|
+
const getSortedRowIds = (tableId, cellId, descending, offset = 0, limit) =>
|
|
2174
|
+
arrayMap(
|
|
2177
2175
|
arraySlice(
|
|
2178
2176
|
arraySort(
|
|
2179
|
-
|
|
2177
|
+
mapMap(mapGet(tablesMap, id(tableId)), (row, rowId) => [
|
|
2178
|
+
isUndefined(cellId) ? rowId : mapGet(row, id(cellId)),
|
|
2179
|
+
rowId,
|
|
2180
|
+
]),
|
|
2180
2181
|
([cell1], [cell2]) =>
|
|
2181
2182
|
defaultSorter(cell1, cell2) * (descending ? -1 : 1),
|
|
2182
2183
|
),
|
|
@@ -2185,7 +2186,6 @@ const createStore = () => {
|
|
|
2185
2186
|
),
|
|
2186
2187
|
([, rowId]) => rowId,
|
|
2187
2188
|
);
|
|
2188
|
-
};
|
|
2189
2189
|
const getRow = (tableId, rowId) =>
|
|
2190
2190
|
mapToObj(mapGet(mapGet(tablesMap, id(tableId)), id(rowId)));
|
|
2191
2191
|
const getCellIds = (tableId, rowId) =>
|
|
@@ -2340,7 +2340,7 @@ const createStore = () => {
|
|
|
2340
2340
|
return;
|
|
2341
2341
|
}
|
|
2342
2342
|
startTransaction();
|
|
2343
|
-
const result = actions
|
|
2343
|
+
const result = actions();
|
|
2344
2344
|
finishTransaction(doRollback);
|
|
2345
2345
|
return result;
|
|
2346
2346
|
};
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The tools module of the TinyBase project provides utilities for working with
|
|
3
|
+
* TinyBase during development.
|
|
4
|
+
*
|
|
5
|
+
* This module is not intended to be directly used at runtime in a production
|
|
6
|
+
* environment.
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
* @module tools
|
|
10
|
+
* @since v2.2.0
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import {Schema, Store} from './store.d';
|
|
14
|
+
import {Id} from './common.d';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The StoreStats type describes a set of statistics about the Store, and
|
|
18
|
+
* is used for debugging purposes.
|
|
19
|
+
*
|
|
20
|
+
* A StoreStats object is returned from the getStoreStats method.
|
|
21
|
+
*
|
|
22
|
+
* @category Statistics
|
|
23
|
+
* @since v2.2.0
|
|
24
|
+
*/
|
|
25
|
+
export type StoreStats = {
|
|
26
|
+
/**
|
|
27
|
+
* The number of Table objects in the Store.
|
|
28
|
+
*/
|
|
29
|
+
totalTables: number;
|
|
30
|
+
/**
|
|
31
|
+
* The number of Row objects in the Store, across all Table objects.
|
|
32
|
+
*/
|
|
33
|
+
totalRows: number;
|
|
34
|
+
/**
|
|
35
|
+
* The number of Cell objects in the Store, across all Row objects, across all
|
|
36
|
+
* Table objects.
|
|
37
|
+
*/
|
|
38
|
+
totalCells: number;
|
|
39
|
+
/**
|
|
40
|
+
* The string length of the Store when serialized to JSON.
|
|
41
|
+
*/
|
|
42
|
+
jsonLength: number;
|
|
43
|
+
/**
|
|
44
|
+
* Additional detailed statistics about the Store if the `detail` flag is
|
|
45
|
+
* specified in the getStoreStats method.
|
|
46
|
+
*/
|
|
47
|
+
detail?: StoreStatsDetail;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* The StoreStatsDetail type describes a more detailed set of statistics about
|
|
52
|
+
* the Store, and is used for debugging purposes.
|
|
53
|
+
*
|
|
54
|
+
* A StoreStatsDetail object is added to the StoreStats object (returned from
|
|
55
|
+
* the getStoreStats method) when the `detail` flag is specified.
|
|
56
|
+
*
|
|
57
|
+
* @category Statistics
|
|
58
|
+
* @since v2.2.0
|
|
59
|
+
*/
|
|
60
|
+
export type StoreStatsDetail = {
|
|
61
|
+
/**
|
|
62
|
+
* Information about each Table in the Store.
|
|
63
|
+
*/
|
|
64
|
+
tables: {[tableId: Id]: StoreStatsTableDetail};
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* The StoreStatsTableDetail type describes a detailed set of statistics about a
|
|
69
|
+
* single Table in the Store, and is used for debugging purposes.
|
|
70
|
+
*
|
|
71
|
+
* @category Statistics
|
|
72
|
+
* @since v2.2.0
|
|
73
|
+
*/
|
|
74
|
+
export type StoreStatsTableDetail = {
|
|
75
|
+
/**
|
|
76
|
+
* The number of Row objects in the Table.
|
|
77
|
+
*/
|
|
78
|
+
tableRows: number;
|
|
79
|
+
/**
|
|
80
|
+
* The number of Cell objects in the Table, across all Row objects.
|
|
81
|
+
*/
|
|
82
|
+
tableCells: number;
|
|
83
|
+
rows: {[rowId: Id]: StoreStatsRowDetail};
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* The StoreStatsRowDetail type describes statistics about a single Row in the
|
|
88
|
+
* Store, and is used for debugging purposes.
|
|
89
|
+
*
|
|
90
|
+
* @category Statistics
|
|
91
|
+
* @since v2.2.0
|
|
92
|
+
*/
|
|
93
|
+
export type StoreStatsRowDetail = {
|
|
94
|
+
/**
|
|
95
|
+
* The number of Cell objects in the Row.
|
|
96
|
+
*/
|
|
97
|
+
rowCells: number;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* A Tools object lets you run various utilities on, and get certain information
|
|
102
|
+
* about, Store objects in development.
|
|
103
|
+
*
|
|
104
|
+
* @category Tools
|
|
105
|
+
* @since v2.2.0
|
|
106
|
+
*/
|
|
107
|
+
export interface Tools {
|
|
108
|
+
/**
|
|
109
|
+
* The getStoreStats method provides a set of statistics about the Store, and
|
|
110
|
+
* is used for debugging purposes.
|
|
111
|
+
*
|
|
112
|
+
* @param detail An optional boolean that indicates more detailed stats about
|
|
113
|
+
* the inner structure of the Store should be returned.
|
|
114
|
+
* @returns A StoreStats object containing statistics about the Store.
|
|
115
|
+
* @example
|
|
116
|
+
* This example creates a Tools object and gets basic statistics about it.
|
|
117
|
+
* ```js
|
|
118
|
+
* const store = createStore()
|
|
119
|
+
* .setTable('pets', {
|
|
120
|
+
* fido: {species: 'dog', color: 'brown'},
|
|
121
|
+
* felix: {species: 'cat', color: 'black'},
|
|
122
|
+
* cujo: {species: 'dog', color: 'black'},
|
|
123
|
+
* })
|
|
124
|
+
* .setTable('species', {
|
|
125
|
+
* dog: {price: 5},
|
|
126
|
+
* cat: {price: 4},
|
|
127
|
+
* });
|
|
128
|
+
* const tools = createTools(store);
|
|
129
|
+
* console.log(tools.getStoreStats());
|
|
130
|
+
* // -> {totalTables: 2, totalRows: 5, totalCells: 8, jsonLength: 182}
|
|
131
|
+
* ```
|
|
132
|
+
* @example
|
|
133
|
+
* This example creates a Tools object and gets detailed statistics about it.
|
|
134
|
+
* ```js
|
|
135
|
+
* const store = createStore()
|
|
136
|
+
* .setTable('pets', {
|
|
137
|
+
* fido: {species: 'dog', color: 'brown'},
|
|
138
|
+
* felix: {species: 'cat', color: 'black'},
|
|
139
|
+
* cujo: {species: 'dog', color: 'black'},
|
|
140
|
+
* })
|
|
141
|
+
* .setTable('species', {
|
|
142
|
+
* dog: {price: 5},
|
|
143
|
+
* cat: {price: 4},
|
|
144
|
+
* });
|
|
145
|
+
* const stats = createTools(store).getStoreStats(true);
|
|
146
|
+
*
|
|
147
|
+
* console.log(stats.totalTables);
|
|
148
|
+
* // -> 2
|
|
149
|
+
* console.log(stats.totalRows);
|
|
150
|
+
* // -> 5
|
|
151
|
+
* console.log(stats.totalCells);
|
|
152
|
+
* // -> 8
|
|
153
|
+
* console.log(stats.detail.tables.pets.tableRows);
|
|
154
|
+
* // -> 3
|
|
155
|
+
* console.log(stats.detail.tables.pets.tableCells);
|
|
156
|
+
* // -> 6
|
|
157
|
+
* console.log(stats.detail.tables.pets.rows);
|
|
158
|
+
* // -> {fido: {rowCells: 2}, felix: {rowCells: 2}, cujo: {rowCells: 2}}
|
|
159
|
+
* ```
|
|
160
|
+
* @category Statistics
|
|
161
|
+
* @since v2.2.0
|
|
162
|
+
*/
|
|
163
|
+
getStoreStats(detail?: boolean): StoreStats;
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* The getStoreSchema method returns the Schema of the Store as an object.
|
|
167
|
+
*
|
|
168
|
+
* If the Store does not already have an explicit Schema associated with it,
|
|
169
|
+
* the data in the Store will be scanned to attempt to infer a new Schema.
|
|
170
|
+
*
|
|
171
|
+
* To be successful, this requires all the values of a given Cell across a
|
|
172
|
+
* Table object's Row objects to have a consistent type. If a given Cell Id
|
|
173
|
+
* appears in every Row, then a `default` for that Cell is specified in the
|
|
174
|
+
* Schema, based on the most common value found.
|
|
175
|
+
*
|
|
176
|
+
* @returns A Schema object for the Store.
|
|
177
|
+
* @example
|
|
178
|
+
* This example creates a Tools object and gets basic statistics about a Store
|
|
179
|
+
* that already has a Schema.
|
|
180
|
+
* ```js
|
|
181
|
+
* const store = createStore().setSchema({
|
|
182
|
+
* pets: {
|
|
183
|
+
* species: {type: 'string'},
|
|
184
|
+
* color: {type: 'string'},
|
|
185
|
+
* },
|
|
186
|
+
* species: {
|
|
187
|
+
* price: {type: 'number'},
|
|
188
|
+
* },
|
|
189
|
+
* });
|
|
190
|
+
* const schema = createTools(store).getStoreSchema();
|
|
191
|
+
* console.log(schema.pets);
|
|
192
|
+
* // -> {species: {type: 'string'}, color: {type: 'string'}}
|
|
193
|
+
* ```
|
|
194
|
+
* @example
|
|
195
|
+
* This example creates a Tools object and gets basic statistics about a Store
|
|
196
|
+
* that doesn't already have a Schema.
|
|
197
|
+
* ```js
|
|
198
|
+
* const store = createStore()
|
|
199
|
+
* .setTable('pets', {
|
|
200
|
+
* fido: {species: 'dog', color: 'brown'},
|
|
201
|
+
* felix: {species: 'cat', color: 'black'},
|
|
202
|
+
* cujo: {species: 'dog', color: 'black'},
|
|
203
|
+
* })
|
|
204
|
+
* .setTable('species', {
|
|
205
|
+
* dog: {price: 5, barks: true},
|
|
206
|
+
* cat: {price: 4, purrs: true},
|
|
207
|
+
* });
|
|
208
|
+
* const schema = createTools(store).getStoreSchema();
|
|
209
|
+
* console.log(schema.pets.species);
|
|
210
|
+
* // -> {type: 'string', default: 'dog'}
|
|
211
|
+
* console.log(schema.pets.color);
|
|
212
|
+
* // -> {type: 'string', default: 'black'}
|
|
213
|
+
* console.log(schema.species.price);
|
|
214
|
+
* // -> {type: 'number', default: 5}
|
|
215
|
+
* console.log(schema.species.barks);
|
|
216
|
+
* // -> {type: 'boolean'}
|
|
217
|
+
* console.log(schema.species.purrs);
|
|
218
|
+
* // -> {type: 'boolean'}
|
|
219
|
+
* ```
|
|
220
|
+
* @category Modelling
|
|
221
|
+
* @since v2.2.0
|
|
222
|
+
*/
|
|
223
|
+
getStoreSchema(): Schema;
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* The getStoreApi method returns a code-generated .d.ts file and a .ts file
|
|
227
|
+
* that wraps the schema of a Store.
|
|
228
|
+
*
|
|
229
|
+
* This is currently in development, and further documentation is to come.
|
|
230
|
+
*
|
|
231
|
+
* @category Modelling
|
|
232
|
+
* @since v2.2.0
|
|
233
|
+
*/
|
|
234
|
+
getStoreApi(storeName: string): [string, string];
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* The getStoreApi method attempts to return a prettified code-generated .d.ts
|
|
238
|
+
* file and a .ts file that wraps the schema of a Store.
|
|
239
|
+
*
|
|
240
|
+
* This is currently in development, and further documentation is to come.
|
|
241
|
+
*
|
|
242
|
+
* @category Modelling
|
|
243
|
+
* @since v2.2.0
|
|
244
|
+
*/
|
|
245
|
+
getPrettyStoreApi(storeName: string): Promise<[string, string]>;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* The createTools function creates a Tools object, and is the main entry point
|
|
250
|
+
* into the tools module.
|
|
251
|
+
*
|
|
252
|
+
* A given Store can only have one Tools object associated with it. If you call
|
|
253
|
+
* this function twice on the same Store, your second call will return a
|
|
254
|
+
* reference to the Tools object created by the first.
|
|
255
|
+
*
|
|
256
|
+
* @param store The Store for which to register tools.
|
|
257
|
+
* @returns A reference to the new Tools object.
|
|
258
|
+
* @example
|
|
259
|
+
* This example creates a Tools object.
|
|
260
|
+
*
|
|
261
|
+
* ```js
|
|
262
|
+
* const store = createStore()
|
|
263
|
+
* .setTable('pets', {
|
|
264
|
+
* fido: {species: 'dog', color: 'brown'},
|
|
265
|
+
* felix: {species: 'cat', color: 'black'},
|
|
266
|
+
* cujo: {species: 'dog', color: 'black'},
|
|
267
|
+
* })
|
|
268
|
+
* .setTable('species', {
|
|
269
|
+
* dog: {price: 5},
|
|
270
|
+
* cat: {price: 4},
|
|
271
|
+
* });
|
|
272
|
+
* const tools = createTools(store);
|
|
273
|
+
* console.log(tools.getStoreStats());
|
|
274
|
+
* // -> {totalTables: 2, totalRows: 5, totalCells: 8, jsonLength: 182}
|
|
275
|
+
* ```
|
|
276
|
+
* @example
|
|
277
|
+
* This example creates a Tools object, and calls the method a second time
|
|
278
|
+
* for the same Store to return the same object.
|
|
279
|
+
*
|
|
280
|
+
* ```js
|
|
281
|
+
* const store = createStore();
|
|
282
|
+
* const tools1 = createTools(store);
|
|
283
|
+
* const tools2 = createTools(store);
|
|
284
|
+
* console.log(tools1 === tools2);
|
|
285
|
+
* // -> true
|
|
286
|
+
* ```
|
|
287
|
+
* @category Creation
|
|
288
|
+
* @since v2.2.0
|
|
289
|
+
*/
|
|
290
|
+
export function createTools(store: Store): Tools;
|