tinybase 1.3.6 → 2.0.0-beta.2
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 +4 -3
- package/lib/checkpoints.js +1 -1
- package/lib/checkpoints.js.gz +0 -0
- package/lib/debug/checkpoints.d.ts +4 -3
- package/lib/debug/checkpoints.js +69 -56
- package/lib/debug/indexes.d.ts +4 -2
- package/lib/debug/indexes.js +106 -69
- package/lib/debug/metrics.d.ts +1 -1
- package/lib/debug/metrics.js +187 -131
- package/lib/debug/persisters.d.ts +6 -0
- package/lib/debug/persisters.js +2 -1
- package/lib/debug/queries.d.ts +3251 -0
- package/lib/debug/queries.js +900 -0
- package/lib/debug/relationships.d.ts +12 -10
- package/lib/debug/relationships.js +104 -68
- package/lib/debug/store.d.ts +415 -74
- package/lib/debug/store.js +295 -120
- package/lib/debug/tinybase.d.ts +1 -0
- package/lib/debug/tinybase.js +985 -176
- package/lib/debug/ui-react.d.ts +4325 -1754
- package/lib/debug/ui-react.js +413 -85
- package/lib/indexes.d.ts +4 -2
- 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 +6 -0
- package/lib/queries.d.ts +3251 -0
- package/lib/queries.js +1 -0
- package/lib/queries.js.gz +0 -0
- package/lib/relationships.d.ts +12 -10
- package/lib/relationships.js +1 -1
- package/lib/relationships.js.gz +0 -0
- package/lib/store.d.ts +415 -74
- package/lib/store.js +1 -1
- package/lib/store.js.gz +0 -0
- package/lib/tinybase.d.ts +1 -0
- package/lib/tinybase.js +1 -1
- package/lib/tinybase.js.gz +0 -0
- package/lib/ui-react.d.ts +4325 -1754
- package/lib/ui-react.js +1 -1
- package/lib/ui-react.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/queries.js +1 -0
- package/lib/umd/queries.js.gz +0 -0
- package/lib/umd/relationships.js +1 -1
- package/lib/umd/relationships.js.gz +0 -0
- package/lib/umd/store.js +1 -1
- package/lib/umd/store.js.gz +0 -0
- package/lib/umd/tinybase.js +1 -1
- package/lib/umd/tinybase.js.gz +0 -0
- package/lib/umd/ui-react.js +1 -1
- package/lib/umd/ui-react.js.gz +0 -0
- package/package.json +4 -4
- package/readme.md +2 -2
package/lib/checkpoints.d.ts
CHANGED
|
@@ -93,12 +93,13 @@ export type CheckpointListener = (
|
|
|
93
93
|
*/
|
|
94
94
|
export type CheckpointsListenerStats = {
|
|
95
95
|
/**
|
|
96
|
-
* The number of
|
|
97
|
-
* object.
|
|
96
|
+
* The number of CheckpointIdsListener functions registered with the
|
|
97
|
+
* Checkpoints object.
|
|
98
98
|
*/
|
|
99
99
|
checkpointIds?: number;
|
|
100
100
|
/**
|
|
101
|
-
* The number of
|
|
101
|
+
* The number of CheckpointListener functions registered with the Checkpoints
|
|
102
|
+
* object.
|
|
102
103
|
*/
|
|
103
104
|
checkpoint?: number;
|
|
104
105
|
};
|
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),o=(e,...t)=>e.push(...t),s=e=>e.pop(),l=e=>null==e,c=(e,t,n)=>l(e)?n?.():t(e),i=(e,t)=>e?.has(t)??!1,a=e=>l(e)||0==(e=>e.size)(e),d=(e,t)=>e?.forEach(t),u=(e,t)=>e?.delete(t),h=e=>new Map(e),p=(e,t)=>e?.get(t),C=(e,t,n)=>l(n)?(u(e,t),e):e?.set(t,n),g=(e,t,n)=>(i(e,t)||C(e,t,n()),p(e,t)),k=(e,t,r,o,s=0)=>c((r?g:p)(e,t[s],s>n(t)-2?r:h),(l=>{if(s>n(t)-2)return o?.(l)&&C(e,t[s]),l;const c=k(l,t,r,o,s+1);return a(l)&&C(e,t[s]),c})),f=e=>new Set(e),v=(e,r=[""])=>{const s=[],l=(e,c)=>c==n(r)?o(s,e):null===r[c]?d(e,(e=>l(e,c+1))):t([r[c],null],(t=>l(p(e,t),c+1)));return l(e,0),s},L=Object.freeze,w=(e=>{const t=new WeakMap;return n=>(t.has(n)||t.set(n,e(n)),t.get(n))})((w=>{let S,z,E,y=100,I=h(),M=1;const b=h(),j=h(),[x,B,F]=(e=>{let r,i=0;const g=[],L=h();return[(t,n,o)=>{r??=e();const l=s(g)??""+i++;var c;return C(L,l,[t,n,o]),c=l,k(n,o??[""],f)?.add(c),l},(e,n,...o)=>t(v(e,n),(e=>d(e,(e=>p(L,e)[0](r,...n??[],...o))))),e=>c(p(L,e),(([,t,r])=>(k(t,r??[""],void 0,(t=>(u(t,e),a(t)?1:0))),C(L,e),n(g)<1e3&&o(g,e),r))),(e,t)=>{return n=v(e,t),r=l,!n.every(r);var n,r},(e,o,s)=>c(p(L,e),(([e,,c=[]])=>{const i=(...a)=>{const d=n(a);d==n(c)?e(r,...a,...s(a)):l(c[d])?t(o[d](...a),(e=>i(...a,e))):i(...a,c[d])};i()}))]})((()=>V)),O=h(),T=h(),W=[],m=[],q=(e,t)=>{M=0,w.transaction((()=>d(p(O,t),((t,n)=>d(t,((t,r)=>d(t,((t,o)=>((e,t,n,r,o)=>l(o)?e.delCell(t,n,r,!0):e.setCell(t,n,r,o))(w,n,r,o,t[e]))))))))),M=1},A=e=>{C(O,e),C(T,e),B(j,[e])},D=(e,r)=>t(((e,t)=>e.splice(0,t))(e,r??n(e)),A),G=()=>D(W,n(W)-y),H=w.addCellListener(null,null,null,((e,t,n,r,l,i)=>{if(M){c(S,(()=>{o(W,S),G(),D(m),S=void 0,E=1}));const e=g(I,t,h),d=g(e,n,h),u=g(d,r,(()=>[i,void 0]));u[1]=l,u[0]===l&&a(C(d,r))&&a(C(e,n))&&a(C(I,t))&&(S=s(W),E=1),P()}})),J=(e="")=>(l(S)&&(S=""+z++,C(O,S,I),R(S,e),I=h(),E=1),S),K=()=>{r(W)||(m.unshift(J()),q(0,S),S=s(W),E=1)},N=()=>{r(m)||(o(W,S),S=m.shift(),q(1,S),E=1)},P=()=>{E&&(B(b),E=0)},Q=e=>{const t=J(e);return P(),t},R=(e,t)=>(U(e)&&p(T,e)!==t&&(C(T,e,t),B(j,[e])),V),U=e=>i(O,e),V={setSize:e=>(y=e,G(),V),addCheckpoint:Q,setCheckpoint:R,getStore:()=>w,getCheckpointIds:()=>[[...W],S,[...m]],forEachCheckpoint:e=>{return t=e,d(T,((e,n)=>t(n,e)));var t},hasCheckpoint:U,getCheckpoint:e=>p(T,e),goBackward:()=>(K(),P(),V),goForward:()=>(N(),P(),V),goTo:t=>{const n=e(W,t)?K:e(m,t)?N:null;for(;!l(n)&&t!=S;)n();return P(),V},addCheckpointIdsListener:e=>x(e,b),addCheckpointListener:(e,t)=>x(t,j,[e]),delListener:e=>(F(e),V),clear:()=>(D(W),D(m),l(S)||A(S),S=void 0,z=0,Q(),V),destroy:()=>{w.delListener(H)},getListenerStats:()=>({})};return L(V.clear())}));export{w as createCheckpoints};
|
package/lib/checkpoints.js.gz
CHANGED
|
Binary file
|
|
@@ -93,12 +93,13 @@ export type CheckpointListener = (
|
|
|
93
93
|
*/
|
|
94
94
|
export type CheckpointsListenerStats = {
|
|
95
95
|
/**
|
|
96
|
-
* The number of
|
|
97
|
-
* object.
|
|
96
|
+
* The number of CheckpointIdsListener functions registered with the
|
|
97
|
+
* Checkpoints object.
|
|
98
98
|
*/
|
|
99
99
|
checkpointIds?: number;
|
|
100
100
|
/**
|
|
101
|
-
* The number of
|
|
101
|
+
* The number of CheckpointListener functions registered with the Checkpoints
|
|
102
|
+
* object.
|
|
102
103
|
*/
|
|
103
104
|
checkpoint?: number;
|
|
104
105
|
};
|
package/lib/debug/checkpoints.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
|
+
const EMPTY_STRING = '';
|
|
2
|
+
|
|
1
3
|
const arrayHas = (array, value) => array.includes(value);
|
|
4
|
+
const arrayEvery = (array, cb) => array.every(cb);
|
|
2
5
|
const arrayForEach = (array, cb) => array.forEach(cb);
|
|
3
6
|
const arrayLength = (array) => array.length;
|
|
4
7
|
const arrayIsEmpty = (array) => arrayLength(array) == 0;
|
|
5
8
|
const arrayReduce = (array, cb, initial) => array.reduce(cb, initial);
|
|
6
|
-
const arrayFromSecond = (ids) => ids.slice(1);
|
|
7
9
|
const arrayClear = (array, to) => array.splice(0, to);
|
|
8
|
-
const arrayPush = (array,
|
|
10
|
+
const arrayPush = (array, ...values) => array.push(...values);
|
|
9
11
|
const arrayPop = (array) => array.pop();
|
|
10
12
|
|
|
11
13
|
const isUndefined = (thing) => thing == void 0;
|
|
@@ -34,6 +36,27 @@ const mapEnsure = (map, key, getDefaultValue) => {
|
|
|
34
36
|
}
|
|
35
37
|
return mapGet(map, key);
|
|
36
38
|
};
|
|
39
|
+
const visitTree = (node, path, ensureLeaf, pruneLeaf, p = 0) =>
|
|
40
|
+
ifNotUndefined(
|
|
41
|
+
(ensureLeaf ? mapEnsure : mapGet)(
|
|
42
|
+
node,
|
|
43
|
+
path[p],
|
|
44
|
+
p > arrayLength(path) - 2 ? ensureLeaf : mapNew,
|
|
45
|
+
),
|
|
46
|
+
(nodeOrLeaf) => {
|
|
47
|
+
if (p > arrayLength(path) - 2) {
|
|
48
|
+
if (pruneLeaf?.(nodeOrLeaf)) {
|
|
49
|
+
mapSet(node, path[p]);
|
|
50
|
+
}
|
|
51
|
+
return nodeOrLeaf;
|
|
52
|
+
}
|
|
53
|
+
const leaf = visitTree(nodeOrLeaf, path, ensureLeaf, pruneLeaf, p + 1);
|
|
54
|
+
if (collIsEmpty(nodeOrLeaf)) {
|
|
55
|
+
mapSet(node, path[p]);
|
|
56
|
+
}
|
|
57
|
+
return leaf;
|
|
58
|
+
},
|
|
59
|
+
);
|
|
37
60
|
|
|
38
61
|
const setNew = (entries) => new Set(entries);
|
|
39
62
|
const setAdd = (set, value) => set?.add(value);
|
|
@@ -48,64 +71,51 @@ const getCreateFunction = (getFunction) => {
|
|
|
48
71
|
};
|
|
49
72
|
};
|
|
50
73
|
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
);
|
|
62
|
-
const forDeepSet = (valueDo) => {
|
|
63
|
-
const deep = (deepIdSet, arg, ...ids) =>
|
|
64
|
-
ifNotUndefined(deepIdSet, (deepIdSet2) =>
|
|
65
|
-
arrayIsEmpty(ids)
|
|
66
|
-
? valueDo(deepIdSet2, arg)
|
|
67
|
-
: arrayForEach([ids[0], null], (id) =>
|
|
68
|
-
deep(mapGet(deepIdSet2, id), arg, ...arrayFromSecond(ids)),
|
|
69
|
-
),
|
|
70
|
-
);
|
|
71
|
-
return deep;
|
|
74
|
+
const getWildcardedLeaves = (deepIdSet, path = [EMPTY_STRING]) => {
|
|
75
|
+
const leaves = [];
|
|
76
|
+
const deep = (node, p) =>
|
|
77
|
+
p == arrayLength(path)
|
|
78
|
+
? arrayPush(leaves, node)
|
|
79
|
+
: path[p] === null
|
|
80
|
+
? collForEach(node, (node2) => deep(node2, p + 1))
|
|
81
|
+
: arrayForEach([path[p], null], (id) => deep(mapGet(node, id), p + 1));
|
|
82
|
+
deep(deepIdSet, 0);
|
|
83
|
+
return leaves;
|
|
72
84
|
};
|
|
73
85
|
const getListenerFunctions = (getThing) => {
|
|
74
86
|
let thing;
|
|
75
87
|
let nextId = 0;
|
|
76
88
|
const listenerPool = [];
|
|
77
89
|
const allListeners = mapNew();
|
|
78
|
-
const addListener = (listener,
|
|
90
|
+
const addListener = (listener, idSetNode, path) => {
|
|
79
91
|
thing ??= getThing();
|
|
80
|
-
const id = arrayPop(listenerPool) ??
|
|
81
|
-
mapSet(allListeners, id, [listener,
|
|
82
|
-
|
|
92
|
+
const id = arrayPop(listenerPool) ?? EMPTY_STRING + nextId++;
|
|
93
|
+
mapSet(allListeners, id, [listener, idSetNode, path]);
|
|
94
|
+
setAdd(visitTree(idSetNode, path ?? [EMPTY_STRING], setNew), id);
|
|
83
95
|
return id;
|
|
84
96
|
};
|
|
85
|
-
const callListeners = (
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
listener(thing, ...ids, ...extraArgs),
|
|
91
|
-
),
|
|
92
|
-
...ids,
|
|
97
|
+
const callListeners = (idSetNode, ids, ...extraArgs) =>
|
|
98
|
+
arrayForEach(getWildcardedLeaves(idSetNode, ids), (set) =>
|
|
99
|
+
collForEach(set, (id) =>
|
|
100
|
+
mapGet(allListeners, id)[0](thing, ...(ids ?? []), ...extraArgs),
|
|
101
|
+
),
|
|
93
102
|
);
|
|
94
103
|
const delListener = (id) =>
|
|
95
|
-
ifNotUndefined(
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
104
|
+
ifNotUndefined(mapGet(allListeners, id), ([, idSetNode, idOrNulls]) => {
|
|
105
|
+
visitTree(idSetNode, idOrNulls ?? [EMPTY_STRING], void 0, (idSet) => {
|
|
106
|
+
collDel(idSet, id);
|
|
107
|
+
return collIsEmpty(idSet) ? 1 : 0;
|
|
108
|
+
});
|
|
109
|
+
mapSet(allListeners, id);
|
|
110
|
+
if (arrayLength(listenerPool) < 1e3) {
|
|
111
|
+
arrayPush(listenerPool, id);
|
|
112
|
+
}
|
|
113
|
+
return idOrNulls;
|
|
114
|
+
});
|
|
115
|
+
const hasListeners = (idSetNode, ids) =>
|
|
116
|
+
!arrayEvery(getWildcardedLeaves(idSetNode, ids), isUndefined);
|
|
107
117
|
const callListener = (id, idNullGetters, extraArgsGetter) =>
|
|
108
|
-
ifNotUndefined(mapGet(allListeners, id), ([listener, , idOrNulls]) => {
|
|
118
|
+
ifNotUndefined(mapGet(allListeners, id), ([listener, , idOrNulls = []]) => {
|
|
109
119
|
const callWithIds = (...ids) => {
|
|
110
120
|
const index = arrayLength(ids);
|
|
111
121
|
index == arrayLength(idOrNulls)
|
|
@@ -118,12 +128,17 @@ const getListenerFunctions = (getThing) => {
|
|
|
118
128
|
};
|
|
119
129
|
callWithIds();
|
|
120
130
|
});
|
|
121
|
-
return [addListener, callListeners, delListener, callListener];
|
|
131
|
+
return [addListener, callListeners, delListener, hasListeners, callListener];
|
|
122
132
|
};
|
|
123
133
|
|
|
124
134
|
const object = Object;
|
|
125
135
|
const objFreeze = object.freeze;
|
|
126
136
|
|
|
137
|
+
const setOrDelCell = (store, tableId, rowId, cellId, cell) =>
|
|
138
|
+
isUndefined(cell)
|
|
139
|
+
? store.delCell(tableId, rowId, cellId, true)
|
|
140
|
+
: store.setCell(tableId, rowId, cellId, cell);
|
|
141
|
+
|
|
127
142
|
const createCheckpoints = getCreateFunction((store) => {
|
|
128
143
|
let backwardIdsSize = 100;
|
|
129
144
|
let currentId;
|
|
@@ -131,7 +146,7 @@ const createCheckpoints = getCreateFunction((store) => {
|
|
|
131
146
|
let listening = 1;
|
|
132
147
|
let nextCheckpointId;
|
|
133
148
|
let checkpointsChanged;
|
|
134
|
-
const checkpointIdsListeners =
|
|
149
|
+
const checkpointIdsListeners = mapNew();
|
|
135
150
|
const checkpointListeners = mapNew();
|
|
136
151
|
const [addListener, callListeners, delListenerImpl] = getListenerFunctions(
|
|
137
152
|
() => checkpoints,
|
|
@@ -146,9 +161,7 @@ const createCheckpoints = getCreateFunction((store) => {
|
|
|
146
161
|
collForEach(mapGet(deltas, checkpointId), (table, tableId) =>
|
|
147
162
|
collForEach(table, (row, rowId) =>
|
|
148
163
|
collForEach(row, (oldNew, cellId) =>
|
|
149
|
-
|
|
150
|
-
? store.delCell(tableId, rowId, cellId, true)
|
|
151
|
-
: store.setCell(tableId, rowId, cellId, oldNew[oldOrNew]),
|
|
164
|
+
setOrDelCell(store, tableId, rowId, cellId, oldNew[oldOrNew]),
|
|
152
165
|
),
|
|
153
166
|
),
|
|
154
167
|
),
|
|
@@ -198,9 +211,9 @@ const createCheckpoints = getCreateFunction((store) => {
|
|
|
198
211
|
}
|
|
199
212
|
},
|
|
200
213
|
);
|
|
201
|
-
const addCheckpointImpl = (label =
|
|
214
|
+
const addCheckpointImpl = (label = EMPTY_STRING) => {
|
|
202
215
|
if (isUndefined(currentId)) {
|
|
203
|
-
currentId =
|
|
216
|
+
currentId = EMPTY_STRING + nextCheckpointId++;
|
|
204
217
|
mapSet(deltas, currentId, delta);
|
|
205
218
|
setCheckpoint(currentId, label);
|
|
206
219
|
delta = mapNew();
|
|
@@ -298,7 +311,7 @@ const createCheckpoints = getCreateFunction((store) => {
|
|
|
298
311
|
store.delListener(listenerId);
|
|
299
312
|
};
|
|
300
313
|
const getListenerStats = () => ({
|
|
301
|
-
checkpointIds:
|
|
314
|
+
checkpointIds: collSize2(checkpointIdsListeners),
|
|
302
315
|
checkpoint: collSize2(checkpointListeners),
|
|
303
316
|
});
|
|
304
317
|
const checkpoints = {
|
package/lib/debug/indexes.d.ts
CHANGED
|
@@ -128,11 +128,13 @@ export type SliceRowIdsListener = (
|
|
|
128
128
|
*/
|
|
129
129
|
export type IndexesListenerStats = {
|
|
130
130
|
/**
|
|
131
|
-
* The number of
|
|
131
|
+
* The number of SlideIdsListener functions registered with the Indexes
|
|
132
|
+
* object.
|
|
132
133
|
*/
|
|
133
134
|
sliceIds?: number;
|
|
134
135
|
/**
|
|
135
|
-
* The number of
|
|
136
|
+
* The number of SliceRowIdsListener functions registered with the Indexes
|
|
137
|
+
* object.
|
|
136
138
|
*/
|
|
137
139
|
sliceRowIds?: number;
|
|
138
140
|
};
|
package/lib/debug/indexes.js
CHANGED
|
@@ -2,8 +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);
|
|
5
6
|
const arrayIsSorted = (array, sorter) =>
|
|
6
|
-
|
|
7
|
+
arrayEvery(
|
|
8
|
+
array,
|
|
7
9
|
(value, index) => index == 0 || sorter(array[index - 1], value) <= 0,
|
|
8
10
|
);
|
|
9
11
|
const arraySort = (array, sorter) => array.sort(sorter);
|
|
@@ -11,8 +13,7 @@ const arrayForEach = (array, cb) => array.forEach(cb);
|
|
|
11
13
|
const arrayLength = (array) => array.length;
|
|
12
14
|
const arrayIsEmpty = (array) => arrayLength(array) == 0;
|
|
13
15
|
const arrayReduce = (array, cb, initial) => array.reduce(cb, initial);
|
|
14
|
-
const
|
|
15
|
-
const arrayPush = (array, value) => array.push(value);
|
|
16
|
+
const arrayPush = (array, ...values) => array.push(...values);
|
|
16
17
|
const arrayPop = (array) => array.pop();
|
|
17
18
|
|
|
18
19
|
const isUndefined = (thing) => thing == void 0;
|
|
@@ -45,6 +46,27 @@ const mapEnsure = (map, key, getDefaultValue) => {
|
|
|
45
46
|
}
|
|
46
47
|
return mapGet(map, key);
|
|
47
48
|
};
|
|
49
|
+
const visitTree = (node, path, ensureLeaf, pruneLeaf, p = 0) =>
|
|
50
|
+
ifNotUndefined(
|
|
51
|
+
(ensureLeaf ? mapEnsure : mapGet)(
|
|
52
|
+
node,
|
|
53
|
+
path[p],
|
|
54
|
+
p > arrayLength(path) - 2 ? ensureLeaf : mapNew,
|
|
55
|
+
),
|
|
56
|
+
(nodeOrLeaf) => {
|
|
57
|
+
if (p > arrayLength(path) - 2) {
|
|
58
|
+
if (pruneLeaf?.(nodeOrLeaf)) {
|
|
59
|
+
mapSet(node, path[p]);
|
|
60
|
+
}
|
|
61
|
+
return nodeOrLeaf;
|
|
62
|
+
}
|
|
63
|
+
const leaf = visitTree(nodeOrLeaf, path, ensureLeaf, pruneLeaf, p + 1);
|
|
64
|
+
if (collIsEmpty(nodeOrLeaf)) {
|
|
65
|
+
mapSet(node, path[p]);
|
|
66
|
+
}
|
|
67
|
+
return leaf;
|
|
68
|
+
},
|
|
69
|
+
);
|
|
48
70
|
|
|
49
71
|
const setNew = (entries) => new Set(entries);
|
|
50
72
|
const setAdd = (set, value) => set?.add(value);
|
|
@@ -63,20 +85,46 @@ const getDefinableFunctions = (store, getDefaultThing, validateRowValue) => {
|
|
|
63
85
|
const getTableId = (id) => mapGet(tableIds, id);
|
|
64
86
|
const getThing = (id) => mapGet(things, id);
|
|
65
87
|
const setThing = (id, thing) => mapSet(things, id, thing);
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
88
|
+
const addStoreListeners = (id, andCall, ...listenerIds) => {
|
|
89
|
+
const set = mapEnsure(storeListenerIds, id, setNew);
|
|
90
|
+
arrayForEach(
|
|
91
|
+
listenerIds,
|
|
92
|
+
(listenerId) =>
|
|
93
|
+
setAdd(set, listenerId) && andCall && store.callListener(listenerId),
|
|
94
|
+
);
|
|
95
|
+
return listenerIds;
|
|
96
|
+
};
|
|
97
|
+
const delStoreListeners = (id, ...listenerIds) =>
|
|
98
|
+
ifNotUndefined(mapGet(storeListenerIds, id), (allListenerIds) => {
|
|
99
|
+
arrayForEach(
|
|
100
|
+
arrayIsEmpty(listenerIds) ? collValues(allListenerIds) : listenerIds,
|
|
101
|
+
(listenerId) => {
|
|
102
|
+
store.delListener(listenerId);
|
|
103
|
+
collDel(allListenerIds, listenerId);
|
|
104
|
+
},
|
|
105
|
+
);
|
|
106
|
+
if (collIsEmpty(allListenerIds)) {
|
|
107
|
+
mapSet(storeListenerIds, id);
|
|
108
|
+
}
|
|
70
109
|
});
|
|
71
|
-
const setDefinition = (id, tableId
|
|
72
|
-
const changedRowValues = mapNew();
|
|
73
|
-
const changedSortKeys = mapNew();
|
|
110
|
+
const setDefinition = (id, tableId) => {
|
|
74
111
|
mapSet(tableIds, id, tableId);
|
|
75
112
|
if (!collHas(things, id)) {
|
|
76
113
|
mapSet(things, id, getDefaultThing());
|
|
77
114
|
mapSet(allRowValues, id, mapNew());
|
|
78
115
|
mapSet(allSortKeys, id, mapNew());
|
|
79
116
|
}
|
|
117
|
+
};
|
|
118
|
+
const setDefinitionAndListen = (
|
|
119
|
+
id,
|
|
120
|
+
tableId,
|
|
121
|
+
onChanged,
|
|
122
|
+
getRowValue,
|
|
123
|
+
getSortKey,
|
|
124
|
+
) => {
|
|
125
|
+
setDefinition(id, tableId);
|
|
126
|
+
const changedRowValues = mapNew();
|
|
127
|
+
const changedSortKeys = mapNew();
|
|
80
128
|
const rowValues = mapGet(allRowValues, id);
|
|
81
129
|
const sortKeys = mapGet(allSortKeys, id);
|
|
82
130
|
const processRow = (rowId) => {
|
|
@@ -126,16 +174,14 @@ const getDefinableFunctions = (store, getDefaultThing, validateRowValue) => {
|
|
|
126
174
|
});
|
|
127
175
|
}
|
|
128
176
|
processTable(true);
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
storeListenerIds,
|
|
177
|
+
delStoreListeners(id);
|
|
178
|
+
addStoreListeners(
|
|
132
179
|
id,
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
]),
|
|
180
|
+
0,
|
|
181
|
+
store.addRowListener(tableId, null, (_store, _tableId, rowId) =>
|
|
182
|
+
processRow(rowId),
|
|
183
|
+
),
|
|
184
|
+
store.addTableListener(tableId, () => processTable()),
|
|
139
185
|
);
|
|
140
186
|
};
|
|
141
187
|
const delDefinition = (id) => {
|
|
@@ -143,7 +189,7 @@ const getDefinableFunctions = (store, getDefaultThing, validateRowValue) => {
|
|
|
143
189
|
mapSet(things, id);
|
|
144
190
|
mapSet(allRowValues, id);
|
|
145
191
|
mapSet(allSortKeys, id);
|
|
146
|
-
|
|
192
|
+
delStoreListeners(id);
|
|
147
193
|
};
|
|
148
194
|
const destroy = () => mapForEach(storeListenerIds, delDefinition);
|
|
149
195
|
return [
|
|
@@ -155,8 +201,11 @@ const getDefinableFunctions = (store, getDefaultThing, validateRowValue) => {
|
|
|
155
201
|
getThing,
|
|
156
202
|
setThing,
|
|
157
203
|
setDefinition,
|
|
204
|
+
setDefinitionAndListen,
|
|
158
205
|
delDefinition,
|
|
159
206
|
destroy,
|
|
207
|
+
addStoreListeners,
|
|
208
|
+
delStoreListeners,
|
|
160
209
|
];
|
|
161
210
|
};
|
|
162
211
|
const getRowCellFunction = (getRowCell, defaultCellValue) =>
|
|
@@ -175,64 +224,51 @@ const getCreateFunction = (getFunction) => {
|
|
|
175
224
|
|
|
176
225
|
const defaultSorter = (sortKey1, sortKey2) => (sortKey1 < sortKey2 ? -1 : 1);
|
|
177
226
|
|
|
178
|
-
const
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
);
|
|
189
|
-
const forDeepSet = (valueDo) => {
|
|
190
|
-
const deep = (deepIdSet, arg, ...ids) =>
|
|
191
|
-
ifNotUndefined(deepIdSet, (deepIdSet2) =>
|
|
192
|
-
arrayIsEmpty(ids)
|
|
193
|
-
? valueDo(deepIdSet2, arg)
|
|
194
|
-
: arrayForEach([ids[0], null], (id) =>
|
|
195
|
-
deep(mapGet(deepIdSet2, id), arg, ...arrayFromSecond(ids)),
|
|
196
|
-
),
|
|
197
|
-
);
|
|
198
|
-
return deep;
|
|
227
|
+
const getWildcardedLeaves = (deepIdSet, path = [EMPTY_STRING]) => {
|
|
228
|
+
const leaves = [];
|
|
229
|
+
const deep = (node, p) =>
|
|
230
|
+
p == arrayLength(path)
|
|
231
|
+
? arrayPush(leaves, node)
|
|
232
|
+
: path[p] === null
|
|
233
|
+
? collForEach(node, (node2) => deep(node2, p + 1))
|
|
234
|
+
: arrayForEach([path[p], null], (id) => deep(mapGet(node, id), p + 1));
|
|
235
|
+
deep(deepIdSet, 0);
|
|
236
|
+
return leaves;
|
|
199
237
|
};
|
|
200
238
|
const getListenerFunctions = (getThing) => {
|
|
201
239
|
let thing;
|
|
202
240
|
let nextId = 0;
|
|
203
241
|
const listenerPool = [];
|
|
204
242
|
const allListeners = mapNew();
|
|
205
|
-
const addListener = (listener,
|
|
243
|
+
const addListener = (listener, idSetNode, path) => {
|
|
206
244
|
thing ??= getThing();
|
|
207
|
-
const id = arrayPop(listenerPool) ??
|
|
208
|
-
mapSet(allListeners, id, [listener,
|
|
209
|
-
|
|
245
|
+
const id = arrayPop(listenerPool) ?? EMPTY_STRING + nextId++;
|
|
246
|
+
mapSet(allListeners, id, [listener, idSetNode, path]);
|
|
247
|
+
setAdd(visitTree(idSetNode, path ?? [EMPTY_STRING], setNew), id);
|
|
210
248
|
return id;
|
|
211
249
|
};
|
|
212
|
-
const callListeners = (
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
listener(thing, ...ids, ...extraArgs),
|
|
218
|
-
),
|
|
219
|
-
...ids,
|
|
250
|
+
const callListeners = (idSetNode, ids, ...extraArgs) =>
|
|
251
|
+
arrayForEach(getWildcardedLeaves(idSetNode, ids), (set) =>
|
|
252
|
+
collForEach(set, (id) =>
|
|
253
|
+
mapGet(allListeners, id)[0](thing, ...(ids ?? []), ...extraArgs),
|
|
254
|
+
),
|
|
220
255
|
);
|
|
221
256
|
const delListener = (id) =>
|
|
222
|
-
ifNotUndefined(
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
257
|
+
ifNotUndefined(mapGet(allListeners, id), ([, idSetNode, idOrNulls]) => {
|
|
258
|
+
visitTree(idSetNode, idOrNulls ?? [EMPTY_STRING], void 0, (idSet) => {
|
|
259
|
+
collDel(idSet, id);
|
|
260
|
+
return collIsEmpty(idSet) ? 1 : 0;
|
|
261
|
+
});
|
|
262
|
+
mapSet(allListeners, id);
|
|
263
|
+
if (arrayLength(listenerPool) < 1e3) {
|
|
264
|
+
arrayPush(listenerPool, id);
|
|
265
|
+
}
|
|
266
|
+
return idOrNulls;
|
|
267
|
+
});
|
|
268
|
+
const hasListeners = (idSetNode, ids) =>
|
|
269
|
+
!arrayEvery(getWildcardedLeaves(idSetNode, ids), isUndefined);
|
|
234
270
|
const callListener = (id, idNullGetters, extraArgsGetter) =>
|
|
235
|
-
ifNotUndefined(mapGet(allListeners, id), ([listener, , idOrNulls]) => {
|
|
271
|
+
ifNotUndefined(mapGet(allListeners, id), ([listener, , idOrNulls = []]) => {
|
|
236
272
|
const callWithIds = (...ids) => {
|
|
237
273
|
const index = arrayLength(ids);
|
|
238
274
|
index == arrayLength(idOrNulls)
|
|
@@ -245,7 +281,7 @@ const getListenerFunctions = (getThing) => {
|
|
|
245
281
|
};
|
|
246
282
|
callWithIds();
|
|
247
283
|
});
|
|
248
|
-
return [addListener, callListeners, delListener, callListener];
|
|
284
|
+
return [addListener, callListeners, delListener, hasListeners, callListener];
|
|
249
285
|
};
|
|
250
286
|
|
|
251
287
|
const object = Object;
|
|
@@ -262,7 +298,8 @@ const createIndexes = getCreateFunction((store) => {
|
|
|
262
298
|
getTableId,
|
|
263
299
|
getIndex,
|
|
264
300
|
setIndex,
|
|
265
|
-
|
|
301
|
+
,
|
|
302
|
+
setDefinitionAndListen,
|
|
266
303
|
delDefinition,
|
|
267
304
|
destroy,
|
|
268
305
|
] = getDefinableFunctions(store, mapNew, (value) =>
|
|
@@ -283,7 +320,7 @@ const createIndexes = getCreateFunction((store) => {
|
|
|
283
320
|
const sliceIdArraySorter = isUndefined(sliceIdSorter)
|
|
284
321
|
? void 0
|
|
285
322
|
: ([id1], [id2]) => sliceIdSorter(id1, id2);
|
|
286
|
-
|
|
323
|
+
setDefinitionAndListen(
|
|
287
324
|
indexId,
|
|
288
325
|
tableId,
|
|
289
326
|
(change, changedSliceIds, changedSortKeys, sliceIds, sortKeys, force) => {
|
package/lib/debug/metrics.d.ts
CHANGED
|
@@ -186,7 +186,7 @@ export type MetricListener = (
|
|
|
186
186
|
*/
|
|
187
187
|
export type MetricsListenerStats = {
|
|
188
188
|
/**
|
|
189
|
-
* The number of
|
|
189
|
+
* The number of MetricListener functions registered with the Metrics object.
|
|
190
190
|
*/
|
|
191
191
|
metric?: number;
|
|
192
192
|
};
|