tinybase 1.3.5 → 2.0.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/debug/checkpoints.js +67 -54
- package/lib/debug/indexes.js +104 -67
- package/lib/debug/metrics.js +185 -129
- package/lib/debug/persisters.js +2 -1
- package/lib/debug/queries.d.ts +3066 -0
- package/lib/debug/queries.js +883 -0
- package/lib/debug/relationships.d.ts +6 -5
- package/lib/debug/relationships.js +102 -66
- package/lib/debug/store.d.ts +128 -65
- package/lib/debug/store.js +215 -119
- package/lib/debug/tinybase.d.ts +1 -0
- package/lib/debug/tinybase.js +895 -175
- package/lib/debug/ui-react.d.ts +49 -2
- package/lib/debug/ui-react.js +85 -74
- package/lib/indexes.js +1 -1
- package/lib/indexes.js.gz +0 -0
- package/lib/metrics.js +1 -1
- package/lib/metrics.js.gz +0 -0
- package/lib/queries.d.ts +3066 -0
- package/lib/queries.js +1 -0
- package/lib/queries.js.gz +0 -0
- package/lib/relationships.d.ts +6 -5
- package/lib/relationships.js +1 -1
- package/lib/relationships.js.gz +0 -0
- package/lib/store.d.ts +128 -65
- 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 +49 -2
- 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 +1 -1
- package/readme.md +2 -2
|
@@ -190,6 +190,7 @@ export type RelationshipsListenerStats = {
|
|
|
190
190
|
* });
|
|
191
191
|
*
|
|
192
192
|
* const relationships = createRelationships(store);
|
|
193
|
+
*
|
|
193
194
|
* // A local/remote table relationship:
|
|
194
195
|
* relationships.setRelationshipDefinition(
|
|
195
196
|
* 'petSpecies', // relationshipId
|
|
@@ -197,6 +198,11 @@ export type RelationshipsListenerStats = {
|
|
|
197
198
|
* 'species', // remoteTableId to link to
|
|
198
199
|
* 'species', // cellId containing remote key
|
|
199
200
|
* );
|
|
201
|
+
* console.log(relationships.getRemoteRowId('petSpecies', 'fido'));
|
|
202
|
+
* // -> 'dog'
|
|
203
|
+
* console.log(relationships.getLocalRowIds('petSpecies', 'dog'));
|
|
204
|
+
* // -> ['fido', 'cujo']
|
|
205
|
+
*
|
|
200
206
|
* // A linked list relationship:
|
|
201
207
|
* relationships.setRelationshipDefinition(
|
|
202
208
|
* 'petSequence', // relationshipId
|
|
@@ -204,11 +210,6 @@ export type RelationshipsListenerStats = {
|
|
|
204
210
|
* 'pets', // the same remoteTableId to link within
|
|
205
211
|
* 'next', // cellId containing link key
|
|
206
212
|
* );
|
|
207
|
-
*
|
|
208
|
-
* console.log(relationships.getRemoteRowId('petSpecies', 'fido'));
|
|
209
|
-
* // -> 'dog'
|
|
210
|
-
* console.log(relationships.getLocalRowIds('petSpecies', 'dog'));
|
|
211
|
-
* // -> ['fido', 'cujo']
|
|
212
213
|
* console.log(relationships.getLinkedRowIds('petSequence', 'fido'));
|
|
213
214
|
* // -> ['fido', 'felix', 'cujo']
|
|
214
215
|
*
|
|
@@ -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
|
-
value,
|
|
180
|
-
arrayFromSecond(ids),
|
|
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 sets = [];
|
|
221
|
+
const deep = (set, p) =>
|
|
222
|
+
p == arrayLength(path)
|
|
223
|
+
? arrayPush(sets, set)
|
|
224
|
+
: arrayForEach([path[p], null], (id) => deep(mapGet(set, id), p + 1));
|
|
225
|
+
deep(deepIdSet, 0);
|
|
226
|
+
return sets;
|
|
192
227
|
};
|
|
193
228
|
const getListenerFunctions = (getThing) => {
|
|
194
229
|
let thing;
|
|
195
230
|
let nextId = 0;
|
|
196
231
|
const listenerPool = [];
|
|
197
232
|
const allListeners = mapNew();
|
|
198
|
-
const addListener = (listener,
|
|
233
|
+
const addListener = (listener, idSetNode, idOrNulls) => {
|
|
199
234
|
thing ??= getThing();
|
|
200
|
-
const id = arrayPop(listenerPool) ??
|
|
201
|
-
mapSet(allListeners, id, [listener,
|
|
202
|
-
|
|
235
|
+
const id = arrayPop(listenerPool) ?? EMPTY_STRING + nextId++;
|
|
236
|
+
mapSet(allListeners, id, [listener, idSetNode, idOrNulls]);
|
|
237
|
+
setAdd(visitTree(idSetNode, idOrNulls ?? [EMPTY_STRING], setNew), id);
|
|
203
238
|
return id;
|
|
204
239
|
};
|
|
205
|
-
const callListeners = (
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
(id) =>
|
|
240
|
+
const callListeners = (idSetNode, ids, ...extraArgs) =>
|
|
241
|
+
arrayForEach(getWildcardedLeaves(idSetNode, ids), (set) =>
|
|
242
|
+
collForEach(set, (id) =>
|
|
209
243
|
ifNotUndefined(mapGet(allListeners, id), ([listener]) =>
|
|
210
|
-
listener(thing, ...ids, ...extraArgs),
|
|
244
|
+
listener(thing, ...(ids ?? []), ...extraArgs),
|
|
211
245
|
),
|
|
212
|
-
|
|
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) => {
|