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
|
@@ -137,17 +137,18 @@ export type LinkedRowIdsListener = (
|
|
|
137
137
|
*/
|
|
138
138
|
export type RelationshipsListenerStats = {
|
|
139
139
|
/**
|
|
140
|
-
* The number of
|
|
141
|
-
* object.
|
|
140
|
+
* The number of RemoteRowIdListener functions registered with the
|
|
141
|
+
* Relationships object.
|
|
142
142
|
*/
|
|
143
143
|
remoteRowId?: number;
|
|
144
144
|
/**
|
|
145
|
-
* The number of
|
|
146
|
-
* object.
|
|
145
|
+
* The number of LocalRowIdsListener functions registered with the
|
|
146
|
+
* Relationships object.
|
|
147
147
|
*/
|
|
148
148
|
localRowIds?: number;
|
|
149
149
|
/**
|
|
150
|
-
* The number of
|
|
150
|
+
* The number of LinkedRowId functions registered with the Relationships
|
|
151
|
+
* object.
|
|
151
152
|
*/
|
|
152
153
|
linkedRowIds?: number;
|
|
153
154
|
};
|
|
@@ -190,6 +191,7 @@ export type RelationshipsListenerStats = {
|
|
|
190
191
|
* });
|
|
191
192
|
*
|
|
192
193
|
* const relationships = createRelationships(store);
|
|
194
|
+
*
|
|
193
195
|
* // A local/remote table relationship:
|
|
194
196
|
* relationships.setRelationshipDefinition(
|
|
195
197
|
* 'petSpecies', // relationshipId
|
|
@@ -197,6 +199,11 @@ export type RelationshipsListenerStats = {
|
|
|
197
199
|
* 'species', // remoteTableId to link to
|
|
198
200
|
* 'species', // cellId containing remote key
|
|
199
201
|
* );
|
|
202
|
+
* console.log(relationships.getRemoteRowId('petSpecies', 'fido'));
|
|
203
|
+
* // -> 'dog'
|
|
204
|
+
* console.log(relationships.getLocalRowIds('petSpecies', 'dog'));
|
|
205
|
+
* // -> ['fido', 'cujo']
|
|
206
|
+
*
|
|
200
207
|
* // A linked list relationship:
|
|
201
208
|
* relationships.setRelationshipDefinition(
|
|
202
209
|
* 'petSequence', // relationshipId
|
|
@@ -204,11 +211,6 @@ export type RelationshipsListenerStats = {
|
|
|
204
211
|
* 'pets', // the same remoteTableId to link within
|
|
205
212
|
* 'next', // cellId containing link key
|
|
206
213
|
* );
|
|
207
|
-
*
|
|
208
|
-
* console.log(relationships.getRemoteRowId('petSpecies', 'fido'));
|
|
209
|
-
* // -> 'dog'
|
|
210
|
-
* console.log(relationships.getLocalRowIds('petSpecies', 'dog'));
|
|
211
|
-
* // -> ['fido', 'cujo']
|
|
212
214
|
* console.log(relationships.getLinkedRowIds('petSequence', 'fido'));
|
|
213
215
|
* // -> ['fido', 'felix', 'cujo']
|
|
214
216
|
*
|
|
@@ -2,12 +2,12 @@ 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 arrayForEach = (array, cb) => array.forEach(cb);
|
|
6
7
|
const arrayLength = (array) => array.length;
|
|
7
8
|
const arrayIsEmpty = (array) => arrayLength(array) == 0;
|
|
8
9
|
const arrayReduce = (array, cb, initial) => array.reduce(cb, initial);
|
|
9
|
-
const
|
|
10
|
-
const arrayPush = (array, value) => array.push(value);
|
|
10
|
+
const arrayPush = (array, ...values) => array.push(...values);
|
|
11
11
|
const arrayPop = (array) => array.pop();
|
|
12
12
|
|
|
13
13
|
const isUndefined = (thing) => thing == void 0;
|
|
@@ -40,6 +40,27 @@ const mapEnsure = (map, key, getDefaultValue) => {
|
|
|
40
40
|
}
|
|
41
41
|
return mapGet(map, key);
|
|
42
42
|
};
|
|
43
|
+
const visitTree = (node, path, ensureLeaf, pruneLeaf, p = 0) =>
|
|
44
|
+
ifNotUndefined(
|
|
45
|
+
(ensureLeaf ? mapEnsure : mapGet)(
|
|
46
|
+
node,
|
|
47
|
+
path[p],
|
|
48
|
+
p > arrayLength(path) - 2 ? ensureLeaf : mapNew,
|
|
49
|
+
),
|
|
50
|
+
(nodeOrLeaf) => {
|
|
51
|
+
if (p > arrayLength(path) - 2) {
|
|
52
|
+
if (pruneLeaf?.(nodeOrLeaf)) {
|
|
53
|
+
mapSet(node, path[p]);
|
|
54
|
+
}
|
|
55
|
+
return nodeOrLeaf;
|
|
56
|
+
}
|
|
57
|
+
const leaf = visitTree(nodeOrLeaf, path, ensureLeaf, pruneLeaf, p + 1);
|
|
58
|
+
if (collIsEmpty(nodeOrLeaf)) {
|
|
59
|
+
mapSet(node, path[p]);
|
|
60
|
+
}
|
|
61
|
+
return leaf;
|
|
62
|
+
},
|
|
63
|
+
);
|
|
43
64
|
|
|
44
65
|
const setNew = (entries) => new Set(entries);
|
|
45
66
|
const setAdd = (set, value) => set?.add(value);
|
|
@@ -58,20 +79,46 @@ const getDefinableFunctions = (store, getDefaultThing, validateRowValue) => {
|
|
|
58
79
|
const getTableId = (id) => mapGet(tableIds, id);
|
|
59
80
|
const getThing = (id) => mapGet(things, id);
|
|
60
81
|
const setThing = (id, thing) => mapSet(things, id, thing);
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
82
|
+
const addStoreListeners = (id, andCall, ...listenerIds) => {
|
|
83
|
+
const set = mapEnsure(storeListenerIds, id, setNew);
|
|
84
|
+
arrayForEach(
|
|
85
|
+
listenerIds,
|
|
86
|
+
(listenerId) =>
|
|
87
|
+
setAdd(set, listenerId) && andCall && store.callListener(listenerId),
|
|
88
|
+
);
|
|
89
|
+
return listenerIds;
|
|
90
|
+
};
|
|
91
|
+
const delStoreListeners = (id, ...listenerIds) =>
|
|
92
|
+
ifNotUndefined(mapGet(storeListenerIds, id), (allListenerIds) => {
|
|
93
|
+
arrayForEach(
|
|
94
|
+
arrayIsEmpty(listenerIds) ? collValues(allListenerIds) : listenerIds,
|
|
95
|
+
(listenerId) => {
|
|
96
|
+
store.delListener(listenerId);
|
|
97
|
+
collDel(allListenerIds, listenerId);
|
|
98
|
+
},
|
|
99
|
+
);
|
|
100
|
+
if (collIsEmpty(allListenerIds)) {
|
|
101
|
+
mapSet(storeListenerIds, id);
|
|
102
|
+
}
|
|
65
103
|
});
|
|
66
|
-
const setDefinition = (id, tableId
|
|
67
|
-
const changedRowValues = mapNew();
|
|
68
|
-
const changedSortKeys = mapNew();
|
|
104
|
+
const setDefinition = (id, tableId) => {
|
|
69
105
|
mapSet(tableIds, id, tableId);
|
|
70
106
|
if (!collHas(things, id)) {
|
|
71
107
|
mapSet(things, id, getDefaultThing());
|
|
72
108
|
mapSet(allRowValues, id, mapNew());
|
|
73
109
|
mapSet(allSortKeys, id, mapNew());
|
|
74
110
|
}
|
|
111
|
+
};
|
|
112
|
+
const setDefinitionAndListen = (
|
|
113
|
+
id,
|
|
114
|
+
tableId,
|
|
115
|
+
onChanged,
|
|
116
|
+
getRowValue,
|
|
117
|
+
getSortKey,
|
|
118
|
+
) => {
|
|
119
|
+
setDefinition(id, tableId);
|
|
120
|
+
const changedRowValues = mapNew();
|
|
121
|
+
const changedSortKeys = mapNew();
|
|
75
122
|
const rowValues = mapGet(allRowValues, id);
|
|
76
123
|
const sortKeys = mapGet(allSortKeys, id);
|
|
77
124
|
const processRow = (rowId) => {
|
|
@@ -121,16 +168,14 @@ const getDefinableFunctions = (store, getDefaultThing, validateRowValue) => {
|
|
|
121
168
|
});
|
|
122
169
|
}
|
|
123
170
|
processTable(true);
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
storeListenerIds,
|
|
171
|
+
delStoreListeners(id);
|
|
172
|
+
addStoreListeners(
|
|
127
173
|
id,
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
]),
|
|
174
|
+
0,
|
|
175
|
+
store.addRowListener(tableId, null, (_store, _tableId, rowId) =>
|
|
176
|
+
processRow(rowId),
|
|
177
|
+
),
|
|
178
|
+
store.addTableListener(tableId, () => processTable()),
|
|
134
179
|
);
|
|
135
180
|
};
|
|
136
181
|
const delDefinition = (id) => {
|
|
@@ -138,7 +183,7 @@ const getDefinableFunctions = (store, getDefaultThing, validateRowValue) => {
|
|
|
138
183
|
mapSet(things, id);
|
|
139
184
|
mapSet(allRowValues, id);
|
|
140
185
|
mapSet(allSortKeys, id);
|
|
141
|
-
|
|
186
|
+
delStoreListeners(id);
|
|
142
187
|
};
|
|
143
188
|
const destroy = () => mapForEach(storeListenerIds, delDefinition);
|
|
144
189
|
return [
|
|
@@ -150,8 +195,11 @@ const getDefinableFunctions = (store, getDefaultThing, validateRowValue) => {
|
|
|
150
195
|
getThing,
|
|
151
196
|
setThing,
|
|
152
197
|
setDefinition,
|
|
198
|
+
setDefinitionAndListen,
|
|
153
199
|
delDefinition,
|
|
154
200
|
destroy,
|
|
201
|
+
addStoreListeners,
|
|
202
|
+
delStoreListeners,
|
|
155
203
|
];
|
|
156
204
|
};
|
|
157
205
|
const getRowCellFunction = (getRowCell, defaultCellValue) =>
|
|
@@ -168,64 +216,51 @@ const getCreateFunction = (getFunction) => {
|
|
|
168
216
|
};
|
|
169
217
|
};
|
|
170
218
|
|
|
171
|
-
const
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
);
|
|
182
|
-
const forDeepSet = (valueDo) => {
|
|
183
|
-
const deep = (deepIdSet, arg, ...ids) =>
|
|
184
|
-
ifNotUndefined(deepIdSet, (deepIdSet2) =>
|
|
185
|
-
arrayIsEmpty(ids)
|
|
186
|
-
? valueDo(deepIdSet2, arg)
|
|
187
|
-
: arrayForEach([ids[0], null], (id) =>
|
|
188
|
-
deep(mapGet(deepIdSet2, id), arg, ...arrayFromSecond(ids)),
|
|
189
|
-
),
|
|
190
|
-
);
|
|
191
|
-
return deep;
|
|
219
|
+
const getWildcardedLeaves = (deepIdSet, path = [EMPTY_STRING]) => {
|
|
220
|
+
const leaves = [];
|
|
221
|
+
const deep = (node, p) =>
|
|
222
|
+
p == arrayLength(path)
|
|
223
|
+
? arrayPush(leaves, node)
|
|
224
|
+
: path[p] === null
|
|
225
|
+
? collForEach(node, (node2) => deep(node2, p + 1))
|
|
226
|
+
: arrayForEach([path[p], null], (id) => deep(mapGet(node, id), p + 1));
|
|
227
|
+
deep(deepIdSet, 0);
|
|
228
|
+
return leaves;
|
|
192
229
|
};
|
|
193
230
|
const getListenerFunctions = (getThing) => {
|
|
194
231
|
let thing;
|
|
195
232
|
let nextId = 0;
|
|
196
233
|
const listenerPool = [];
|
|
197
234
|
const allListeners = mapNew();
|
|
198
|
-
const addListener = (listener,
|
|
235
|
+
const addListener = (listener, idSetNode, path) => {
|
|
199
236
|
thing ??= getThing();
|
|
200
|
-
const id = arrayPop(listenerPool) ??
|
|
201
|
-
mapSet(allListeners, id, [listener,
|
|
202
|
-
|
|
237
|
+
const id = arrayPop(listenerPool) ?? EMPTY_STRING + nextId++;
|
|
238
|
+
mapSet(allListeners, id, [listener, idSetNode, path]);
|
|
239
|
+
setAdd(visitTree(idSetNode, path ?? [EMPTY_STRING], setNew), id);
|
|
203
240
|
return id;
|
|
204
241
|
};
|
|
205
|
-
const callListeners = (
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
listener(thing, ...ids, ...extraArgs),
|
|
211
|
-
),
|
|
212
|
-
...ids,
|
|
242
|
+
const callListeners = (idSetNode, ids, ...extraArgs) =>
|
|
243
|
+
arrayForEach(getWildcardedLeaves(idSetNode, ids), (set) =>
|
|
244
|
+
collForEach(set, (id) =>
|
|
245
|
+
mapGet(allListeners, id)[0](thing, ...(ids ?? []), ...extraArgs),
|
|
246
|
+
),
|
|
213
247
|
);
|
|
214
248
|
const delListener = (id) =>
|
|
215
|
-
ifNotUndefined(
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
249
|
+
ifNotUndefined(mapGet(allListeners, id), ([, idSetNode, idOrNulls]) => {
|
|
250
|
+
visitTree(idSetNode, idOrNulls ?? [EMPTY_STRING], void 0, (idSet) => {
|
|
251
|
+
collDel(idSet, id);
|
|
252
|
+
return collIsEmpty(idSet) ? 1 : 0;
|
|
253
|
+
});
|
|
254
|
+
mapSet(allListeners, id);
|
|
255
|
+
if (arrayLength(listenerPool) < 1e3) {
|
|
256
|
+
arrayPush(listenerPool, id);
|
|
257
|
+
}
|
|
258
|
+
return idOrNulls;
|
|
259
|
+
});
|
|
260
|
+
const hasListeners = (idSetNode, ids) =>
|
|
261
|
+
!arrayEvery(getWildcardedLeaves(idSetNode, ids), isUndefined);
|
|
227
262
|
const callListener = (id, idNullGetters, extraArgsGetter) =>
|
|
228
|
-
ifNotUndefined(mapGet(allListeners, id), ([listener, , idOrNulls]) => {
|
|
263
|
+
ifNotUndefined(mapGet(allListeners, id), ([listener, , idOrNulls = []]) => {
|
|
229
264
|
const callWithIds = (...ids) => {
|
|
230
265
|
const index = arrayLength(ids);
|
|
231
266
|
index == arrayLength(idOrNulls)
|
|
@@ -238,7 +273,7 @@ const getListenerFunctions = (getThing) => {
|
|
|
238
273
|
};
|
|
239
274
|
callWithIds();
|
|
240
275
|
});
|
|
241
|
-
return [addListener, callListeners, delListener, callListener];
|
|
276
|
+
return [addListener, callListeners, delListener, hasListeners, callListener];
|
|
242
277
|
};
|
|
243
278
|
|
|
244
279
|
const object = Object;
|
|
@@ -257,7 +292,8 @@ const createRelationships = getCreateFunction((store) => {
|
|
|
257
292
|
getLocalTableId,
|
|
258
293
|
getRelationship,
|
|
259
294
|
,
|
|
260
|
-
|
|
295
|
+
,
|
|
296
|
+
setDefinitionAndListen,
|
|
261
297
|
delDefinition,
|
|
262
298
|
destroy,
|
|
263
299
|
] = getDefinableFunctions(
|
|
@@ -304,7 +340,7 @@ const createRelationships = getCreateFunction((store) => {
|
|
|
304
340
|
getRemoteRowId2,
|
|
305
341
|
) => {
|
|
306
342
|
mapSet(remoteTableIds, relationshipId, remoteTableId);
|
|
307
|
-
|
|
343
|
+
setDefinitionAndListen(
|
|
308
344
|
relationshipId,
|
|
309
345
|
localTableId,
|
|
310
346
|
(change, changedRemoteRowIds) => {
|