tinybase 3.0.0-beta.0 → 3.0.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.
Files changed (110) hide show
  1. package/bin/cli.js +1 -1
  2. package/lib/checkpoints.d.ts +18 -3
  3. package/lib/checkpoints.js +1 -1
  4. package/lib/checkpoints.js.gz +0 -0
  5. package/lib/debug/checkpoints.d.ts +18 -3
  6. package/lib/debug/checkpoints.js +97 -49
  7. package/lib/debug/indexes.js +31 -16
  8. package/lib/debug/metrics.js +31 -16
  9. package/lib/debug/persisters.d.ts +33 -23
  10. package/lib/debug/persisters.js +10 -5
  11. package/lib/debug/queries.js +2 -2
  12. package/lib/debug/relationships.js +31 -16
  13. package/lib/debug/store.d.ts +2053 -381
  14. package/lib/debug/store.js +444 -106
  15. package/lib/debug/tinybase.js +512 -138
  16. package/lib/debug/tools.d.ts +109 -38
  17. package/lib/debug/tools.js +759 -453
  18. package/lib/debug/ui-react.d.ts +1218 -138
  19. package/lib/debug/ui-react.js +163 -12
  20. package/lib/es6/checkpoints.d.ts +18 -3
  21. package/lib/es6/checkpoints.js +1 -1
  22. package/lib/es6/checkpoints.js.gz +0 -0
  23. package/lib/es6/indexes.js +1 -1
  24. package/lib/es6/indexes.js.gz +0 -0
  25. package/lib/es6/metrics.js +1 -1
  26. package/lib/es6/metrics.js.gz +0 -0
  27. package/lib/es6/persisters.d.ts +33 -23
  28. package/lib/es6/persisters.js +1 -1
  29. package/lib/es6/persisters.js.gz +0 -0
  30. package/lib/es6/relationships.js +1 -1
  31. package/lib/es6/relationships.js.gz +0 -0
  32. package/lib/es6/store.d.ts +2053 -381
  33. package/lib/es6/store.js +1 -1
  34. package/lib/es6/store.js.gz +0 -0
  35. package/lib/es6/tinybase.js +1 -1
  36. package/lib/es6/tinybase.js.gz +0 -0
  37. package/lib/es6/tools.d.ts +109 -38
  38. package/lib/es6/tools.js +1 -1
  39. package/lib/es6/tools.js.gz +0 -0
  40. package/lib/es6/ui-react.d.ts +1218 -138
  41. package/lib/es6/ui-react.js +1 -1
  42. package/lib/es6/ui-react.js.gz +0 -0
  43. package/lib/indexes.js +1 -1
  44. package/lib/indexes.js.gz +0 -0
  45. package/lib/metrics.js +1 -1
  46. package/lib/metrics.js.gz +0 -0
  47. package/lib/persisters.d.ts +33 -23
  48. package/lib/persisters.js +1 -1
  49. package/lib/persisters.js.gz +0 -0
  50. package/lib/relationships.js +1 -1
  51. package/lib/relationships.js.gz +0 -0
  52. package/lib/store.d.ts +2053 -381
  53. package/lib/store.js +1 -1
  54. package/lib/store.js.gz +0 -0
  55. package/lib/tinybase.js +1 -1
  56. package/lib/tinybase.js.gz +0 -0
  57. package/lib/tools.d.ts +109 -38
  58. package/lib/tools.js +1 -1
  59. package/lib/tools.js.gz +0 -0
  60. package/lib/ui-react.d.ts +1218 -138
  61. package/lib/ui-react.js +1 -1
  62. package/lib/ui-react.js.gz +0 -0
  63. package/lib/umd/checkpoints.d.ts +18 -3
  64. package/lib/umd/checkpoints.js +1 -1
  65. package/lib/umd/checkpoints.js.gz +0 -0
  66. package/lib/umd/indexes.js +1 -1
  67. package/lib/umd/indexes.js.gz +0 -0
  68. package/lib/umd/metrics.js +1 -1
  69. package/lib/umd/metrics.js.gz +0 -0
  70. package/lib/umd/persisters.d.ts +33 -23
  71. package/lib/umd/persisters.js +1 -1
  72. package/lib/umd/persisters.js.gz +0 -0
  73. package/lib/umd/relationships.js +1 -1
  74. package/lib/umd/relationships.js.gz +0 -0
  75. package/lib/umd/store.d.ts +2053 -381
  76. package/lib/umd/store.js +1 -1
  77. package/lib/umd/store.js.gz +0 -0
  78. package/lib/umd/tinybase.js +1 -1
  79. package/lib/umd/tinybase.js.gz +0 -0
  80. package/lib/umd/tools.d.ts +109 -38
  81. package/lib/umd/tools.js +1 -1
  82. package/lib/umd/tools.js.gz +0 -0
  83. package/lib/umd/ui-react.d.ts +1218 -138
  84. package/lib/umd/ui-react.js +1 -1
  85. package/lib/umd/ui-react.js.gz +0 -0
  86. package/lib/umd-es6/checkpoints.d.ts +18 -3
  87. package/lib/umd-es6/checkpoints.js +1 -1
  88. package/lib/umd-es6/checkpoints.js.gz +0 -0
  89. package/lib/umd-es6/indexes.js +1 -1
  90. package/lib/umd-es6/indexes.js.gz +0 -0
  91. package/lib/umd-es6/metrics.js +1 -1
  92. package/lib/umd-es6/metrics.js.gz +0 -0
  93. package/lib/umd-es6/persisters.d.ts +33 -23
  94. package/lib/umd-es6/persisters.js +1 -1
  95. package/lib/umd-es6/persisters.js.gz +0 -0
  96. package/lib/umd-es6/relationships.js +1 -1
  97. package/lib/umd-es6/relationships.js.gz +0 -0
  98. package/lib/umd-es6/store.d.ts +2053 -381
  99. package/lib/umd-es6/store.js +1 -1
  100. package/lib/umd-es6/store.js.gz +0 -0
  101. package/lib/umd-es6/tinybase.js +1 -1
  102. package/lib/umd-es6/tinybase.js.gz +0 -0
  103. package/lib/umd-es6/tools.d.ts +109 -38
  104. package/lib/umd-es6/tools.js +1 -1
  105. package/lib/umd-es6/tools.js.gz +0 -0
  106. package/lib/umd-es6/ui-react.d.ts +1218 -138
  107. package/lib/umd-es6/ui-react.js +1 -1
  108. package/lib/umd-es6/ui-react.js.gz +0 -0
  109. package/package.json +20 -20
  110. package/readme.md +27 -16
@@ -27,7 +27,7 @@
27
27
  * @module persisters
28
28
  */
29
29
 
30
- import {Store, Tables} from './store.d';
30
+ import {Store, Tables, Values} from './store.d';
31
31
  import {Callback} from './common.d';
32
32
 
33
33
  /**
@@ -105,9 +105,9 @@ export type PersisterStats = {
105
105
  *
106
106
  * await persister.save();
107
107
  * console.log(sessionStorage.getItem('pets'));
108
- * // -> '{"pets":{"fido":{"species":"dog"}}}'
108
+ * // -> '[{"pets":{"fido":{"species":"dog"}}},{}]'
109
109
  *
110
- * sessionStorage.setItem('pets', '{"pets":{"toto":{"species":"dog"}}}');
110
+ * sessionStorage.setItem('pets', '[{"pets":{"toto":{"species":"dog"}}},{}]');
111
111
  * await persister.load();
112
112
  * console.log(store.getTables());
113
113
  * // -> {pets: {toto: {species: 'dog'}}}
@@ -130,10 +130,10 @@ export type PersisterStats = {
130
130
  * store.setTables({pets: {felix: {species: 'cat'}}});
131
131
  * // ...
132
132
  * console.log(sessionStorage.getItem('pets'));
133
- * // -> '{"pets":{"felix":{"species":"cat"}}}'
133
+ * // -> '[{"pets":{"felix":{"species":"cat"}}},{}]'
134
134
  *
135
135
  * // In another browser tab:
136
- * sessionStorage.setItem('pets', '{"pets":{"toto":{"species":"dog"}}}');
136
+ * sessionStorage.setItem('pets', '[{"pets":{"toto":{"species":"dog"}}},{}]');
137
137
  * // -> StorageEvent('storage', {storageArea: sessionStorage, key: 'pets'})
138
138
  *
139
139
  * // ...
@@ -163,6 +163,8 @@ export interface Persister {
163
163
  *
164
164
  * @param initialTables An optional Tables object used when the underlying
165
165
  * storage has not previously been populated.
166
+ * @param initialValues An optional Values object used when the underlying
167
+ * storage has not previously been populated, since v3.0.0.
166
168
  * @returns A Promise containing a reference to the Persister object.
167
169
  * @example
168
170
  * This example creates an empty Store, and loads data into it from the
@@ -170,7 +172,7 @@ export interface Persister {
170
172
  * previously populated.
171
173
  *
172
174
  * ```js
173
- * sessionStorage.setItem('pets', '{"pets":{"fido":{"species":"dog"}}}');
175
+ * sessionStorage.setItem('pets', '[{"pets":{"fido":{"species":"dog"}}},{}]');
174
176
  *
175
177
  * const store = createStore();
176
178
  * const persister = createSessionPersister(store, 'pets');
@@ -195,7 +197,7 @@ export interface Persister {
195
197
  * console.log(store.getTables());
196
198
  * // -> {pets: {fido: {species: 'dog'}}}
197
199
  *
198
- * sessionStorage.setItem('pets', '{"pets":{"toto":{"species":"dog"}}}');
200
+ * sessionStorage.setItem('pets', '[{"pets":{"toto":{"species":"dog"}}},{}]');
199
201
  * await persister.load({pets: {fido: {species: 'dog'}}});
200
202
  * console.log(store.getTables());
201
203
  * // -> {pets: {toto: {species: 'dog'}}}
@@ -204,7 +206,7 @@ export interface Persister {
204
206
  * ```
205
207
  * @category Load
206
208
  */
207
- load(initialTables?: Tables): Promise<Persister>;
209
+ load(initialTables?: Tables, initialValues?: Values): Promise<Persister>;
208
210
 
209
211
  /**
210
212
  * The startAutoLoad method gets persisted data from storage, and loads it
@@ -229,6 +231,8 @@ export interface Persister {
229
231
  *
230
232
  * @param initialTables An optional Tables object used when the underlying
231
233
  * storage has not previously been populated.
234
+ * @param initialValues An optional Values object used when the underlying
235
+ * storage has not previously been populated, since v3.0.0.
232
236
  * @returns A Promise containing a reference to the Persister object.
233
237
  * @example
234
238
  * This example creates an empty Store, and loads data into it from the
@@ -246,7 +250,7 @@ export interface Persister {
246
250
  * // -> {pets: {fido: {species: 'dog'}}}
247
251
  *
248
252
  * // In another browser tab:
249
- * sessionStorage.setItem('pets', '{"pets":{"toto":{"species":"dog"}}}');
253
+ * sessionStorage.setItem('pets', '[{"pets":{"toto":{"species":"dog"}}},{}]');
250
254
  * // -> StorageEvent('storage', {storageArea: sessionStorage, key: 'pets'})
251
255
  *
252
256
  * // ...
@@ -258,7 +262,10 @@ export interface Persister {
258
262
  * ```
259
263
  * @category Load
260
264
  */
261
- startAutoLoad(initialTables?: Tables): Promise<Persister>;
265
+ startAutoLoad(
266
+ initialTables?: Tables,
267
+ initialValues?: Values,
268
+ ): Promise<Persister>;
262
269
 
263
270
  /**
264
271
  * The stopAutoLoad method stops the automatic loading of data from storage
@@ -279,7 +286,7 @@ export interface Persister {
279
286
  * await persister.startAutoLoad();
280
287
  *
281
288
  * // In another browser tab:
282
- * sessionStorage.setItem('pets', '{"pets":{"toto":{"species":"dog"}}}');
289
+ * sessionStorage.setItem('pets', '[{"pets":{"toto":{"species":"dog"}}},{}]');
283
290
  * // -> StorageEvent('storage', {storageArea: sessionStorage, key: 'pets'})
284
291
  * // ...
285
292
  * console.log(store.getTables());
@@ -288,7 +295,10 @@ export interface Persister {
288
295
  * persister.stopAutoLoad();
289
296
  *
290
297
  * // In another browser tab:
291
- * sessionStorage.setItem('pets', '{"pets":{"felix":{"species":"cat"}}}');
298
+ * sessionStorage.setItem(
299
+ * 'pets',
300
+ * '[{"pets":{"felix":{"species":"cat"}}},{}]',
301
+ * );
292
302
  * // -> StorageEvent('storage', {storageArea: sessionStorage, key: 'pets'})
293
303
  * // ...
294
304
  * console.log(store.getTables());
@@ -322,7 +332,7 @@ export interface Persister {
322
332
  *
323
333
  * await persister.save();
324
334
  * console.log(sessionStorage.getItem('pets'));
325
- * // -> '{"pets":{"fido":{"species":"dog"}}}'
335
+ * // -> '[{"pets":{"fido":{"species":"dog"}}},{}]'
326
336
  *
327
337
  * persister.destroy();
328
338
  * sessionStorage.clear();
@@ -356,12 +366,12 @@ export interface Persister {
356
366
  *
357
367
  * await persister.startAutoSave();
358
368
  * console.log(sessionStorage.getItem('pets'));
359
- * // -> '{"pets":{"fido":{"species":"dog"}}}'
369
+ * // -> '[{"pets":{"fido":{"species":"dog"}}},{}]'
360
370
  *
361
371
  * store.setTables({pets: {toto: {species: 'dog'}}});
362
372
  * // ...
363
373
  * console.log(sessionStorage.getItem('pets'));
364
- * // -> '{"pets":{"toto":{"species":"dog"}}}'
374
+ * // -> '[{"pets":{"toto":{"species":"dog"}}},{}]'
365
375
  *
366
376
  * sessionStorage.clear();
367
377
  * ```
@@ -391,14 +401,14 @@ export interface Persister {
391
401
  * store.setTables({pets: {toto: {species: 'dog'}}});
392
402
  * // ...
393
403
  * console.log(sessionStorage.getItem('pets'));
394
- * // -> '{"pets":{"toto":{"species":"dog"}}}'
404
+ * // -> '[{"pets":{"toto":{"species":"dog"}}},{}]'
395
405
  *
396
406
  * persister.stopAutoSave();
397
407
  *
398
408
  * store.setTables({pets: {felix: {species: 'cat'}}});
399
409
  * // ...
400
410
  * console.log(sessionStorage.getItem('pets'));
401
- * // -> '{"pets":{"toto":{"species":"dog"}}}'
411
+ * // -> '[{"pets":{"toto":{"species":"dog"}}},{}]'
402
412
  * // Store change has not been automatically saved.
403
413
  *
404
414
  * sessionStorage.clear();
@@ -423,7 +433,7 @@ export interface Persister {
423
433
  * persister.getStore().setTables({pets: {fido: {species: 'dog'}}});
424
434
  * // ...
425
435
  * console.log(sessionStorage.getItem('pets'));
426
- * // -> '{"pets":{"fido":{"species":"dog"}}}'
436
+ * // -> '[{"pets":{"fido":{"species":"dog"}}},{}]'
427
437
  *
428
438
  * sessionStorage.clear();
429
439
  * ```
@@ -493,7 +503,7 @@ export interface Persister {
493
503
  * store.setTables({pets: {felix: {species: 'cat'}}});
494
504
  * // ...
495
505
  *
496
- * sessionStorage.setItem('pets', '{"pets":{"toto":{"species":"dog"}}}');
506
+ * sessionStorage.setItem('pets', '[{"pets":{"toto":{"species":"dog"}}},{}]');
497
507
  * // -> StorageEvent('storage', {storageArea: sessionStorage, key: 'pets'})
498
508
  * // ...
499
509
  *
@@ -529,7 +539,7 @@ export interface Persister {
529
539
  *
530
540
  * await persister.save();
531
541
  * console.log(sessionStorage.getItem('pets'));
532
- * // -> '{"pets":{"fido":{"species":"dog"}}}'
542
+ * // -> '[{"pets":{"fido":{"species":"dog"}}},{}]'
533
543
  *
534
544
  * persister.destroy();
535
545
  * sessionStorage.clear();
@@ -562,7 +572,7 @@ export function createSessionPersister(
562
572
  *
563
573
  * await persister.save();
564
574
  * console.log(localStorage.getItem('pets'));
565
- * // -> '{"pets":{"fido":{"species":"dog"}}}'
575
+ * // -> '[{"pets":{"fido":{"species":"dog"}}},{}]'
566
576
  *
567
577
  * persister.destroy();
568
578
  * localStorage.clear();
@@ -696,9 +706,9 @@ export function createFilePersister(store: Store, filePath: string): Persister;
696
706
  *
697
707
  * await persister.save();
698
708
  * console.log(storeJson);
699
- * // -> '{"pets":{"fido":{"species":"dog"}}}'
709
+ * // -> '[{"pets":{"fido":{"species":"dog"}}},{}]'
700
710
  *
701
- * storeJson = '{"pets":{"fido":{"species":"dog","color":"brown"}}}';
711
+ * storeJson = '[{"pets":{"fido":{"species":"dog","color":"brown"}}},{}]';
702
712
  * await persister.load();
703
713
  *
704
714
  * console.log(store.getTables());
@@ -18,11 +18,12 @@ const createCustomPersister = (
18
18
  stopListeningToPersisted,
19
19
  ) => {
20
20
  let tablesListenerId;
21
+ let valuesListenerId;
21
22
  let loadSave = 0;
22
23
  let loads = 0;
23
24
  let saves = 0;
24
25
  const persister = {
25
- load: async (initialTables) => {
26
+ load: async (initialTables, initialValues) => {
26
27
  /* istanbul ignore else */
27
28
  if (loadSave != 2) {
28
29
  loadSave = 1;
@@ -33,15 +34,17 @@ const createCustomPersister = (
33
34
  if (!isUndefined(body) && body != EMPTY_STRING) {
34
35
  store.setJson(body);
35
36
  } else {
36
- store.setTables(initialTables);
37
+ store.transaction(() =>
38
+ store.setTables(initialTables).setValues(initialValues),
39
+ );
37
40
  }
38
41
  loadSave = 0;
39
42
  }
40
43
  return persister;
41
44
  },
42
- startAutoLoad: async (initialTables) => {
45
+ startAutoLoad: async (initialTables, initialValues) => {
43
46
  persister.stopAutoLoad();
44
- await persister.load(initialTables);
47
+ await persister.load(initialTables, initialValues);
45
48
  startListeningToPersisted(persister.load);
46
49
  return persister;
47
50
  },
@@ -63,11 +66,13 @@ const createCustomPersister = (
63
66
  },
64
67
  startAutoSave: async () => {
65
68
  await persister.stopAutoSave().save();
66
- tablesListenerId = store.addTablesListener(() => persister.save());
69
+ tablesListenerId = store.addTablesListener(persister.save);
70
+ valuesListenerId = store.addValuesListener(persister.save);
67
71
  return persister;
68
72
  },
69
73
  stopAutoSave: () => {
70
74
  ifNotUndefined(tablesListenerId, store.delListener);
75
+ ifNotUndefined(valuesListenerId, store.delListener);
71
76
  return persister;
72
77
  },
73
78
  getStore: () => store,
@@ -163,7 +163,7 @@ const getAggregateValue = (
163
163
  : aggregateValue;
164
164
  };
165
165
 
166
- const getCellType = (cell) => {
166
+ const getCellOrValueType = (cell) => {
167
167
  const type = getTypeOf(cell);
168
168
  return isTypeStringOrBoolean(type) || (type == NUMBER && isFiniteNumber(cell))
169
169
  ? type
@@ -525,7 +525,7 @@ const createQueries = getCreateFunction((store) => {
525
525
  aggregators,
526
526
  );
527
527
  groupRow[groupedCellId] = isUndefined(
528
- getCellType(aggregateValue),
528
+ getCellOrValueType(aggregateValue),
529
529
  )
530
530
  ? null
531
531
  : aggregateValue;
@@ -262,10 +262,22 @@ const getListenerFunctions = (getThing) => {
262
262
  let thing;
263
263
  const [getId, releaseId] = getPoolFunctions();
264
264
  const allListeners = mapNew();
265
- const addListener = (listener, idSetNode, path) => {
265
+ const addListener = (
266
+ listener,
267
+ idSetNode,
268
+ path,
269
+ pathGetters = [],
270
+ extraArgsGetter = () => [],
271
+ ) => {
266
272
  thing ??= getThing();
267
273
  const id = getId();
268
- mapSet(allListeners, id, [listener, idSetNode, path]);
274
+ mapSet(allListeners, id, [
275
+ listener,
276
+ idSetNode,
277
+ path,
278
+ pathGetters,
279
+ extraArgsGetter,
280
+ ]);
269
281
  setAdd(visitTree(idSetNode, path ?? [EMPTY_STRING], setNew), id);
270
282
  return id;
271
283
  };
@@ -285,20 +297,23 @@ const getListenerFunctions = (getThing) => {
285
297
  releaseId(id);
286
298
  return idOrNulls;
287
299
  });
288
- const callListener = (id, idNullGetters, extraArgsGetter) =>
289
- ifNotUndefined(mapGet(allListeners, id), ([listener, , idOrNulls = []]) => {
290
- const callWithIds = (...ids) => {
291
- const index = arrayLength(ids);
292
- index == arrayLength(idOrNulls)
293
- ? listener(thing, ...ids, ...extraArgsGetter(ids))
294
- : isUndefined(idOrNulls[index])
295
- ? arrayForEach(idNullGetters[index](...ids), (id2) =>
296
- callWithIds(...ids, id2),
297
- )
298
- : callWithIds(...ids, idOrNulls[index]);
299
- };
300
- callWithIds();
301
- });
300
+ const callListener = (id) =>
301
+ ifNotUndefined(
302
+ mapGet(allListeners, id),
303
+ ([listener, , path = [], pathGetters, extraArgsGetter]) => {
304
+ const callWithIds = (...ids) => {
305
+ const index = arrayLength(ids);
306
+ index == arrayLength(path)
307
+ ? listener(thing, ...ids, ...extraArgsGetter(ids))
308
+ : isUndefined(path[index])
309
+ ? arrayForEach(pathGetters[index]?.(...ids) ?? [], (id2) =>
310
+ callWithIds(...ids, id2),
311
+ )
312
+ : callWithIds(...ids, path[index]);
313
+ };
314
+ callWithIds();
315
+ },
316
+ );
302
317
  return [addListener, callListeners, delListener, callListener];
303
318
  };
304
319