tinybase 7.3.5 → 8.0.0-beta.1

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 (59) hide show
  1. package/@types/index.d.ts +1 -0
  2. package/@types/middleware/index.d.ts +1064 -0
  3. package/@types/middleware/with-schemas/index.d.ts +1355 -0
  4. package/@types/omni/index.d.ts +1 -0
  5. package/@types/omni/with-schemas/index.d.ts +1 -0
  6. package/@types/store/index.d.ts +0 -1
  7. package/@types/with-schemas/index.d.ts +1 -0
  8. package/agents.md +33 -11
  9. package/checkpoints/index.js +8 -9
  10. package/checkpoints/with-schemas/index.js +8 -9
  11. package/index.js +484 -153
  12. package/mergeable-store/index.js +371 -135
  13. package/mergeable-store/with-schemas/index.js +371 -135
  14. package/middleware/index.js +130 -0
  15. package/middleware/with-schemas/index.js +130 -0
  16. package/min/checkpoints/index.js +1 -1
  17. package/min/checkpoints/index.js.gz +0 -0
  18. package/min/checkpoints/with-schemas/index.js +1 -1
  19. package/min/checkpoints/with-schemas/index.js.gz +0 -0
  20. package/min/index.js +1 -1
  21. package/min/index.js.gz +0 -0
  22. package/min/mergeable-store/index.js +1 -1
  23. package/min/mergeable-store/index.js.gz +0 -0
  24. package/min/mergeable-store/with-schemas/index.js +1 -1
  25. package/min/mergeable-store/with-schemas/index.js.gz +0 -0
  26. package/min/middleware/index.js +1 -0
  27. package/min/middleware/index.js.gz +0 -0
  28. package/min/middleware/with-schemas/index.js +1 -0
  29. package/min/middleware/with-schemas/index.js.gz +0 -0
  30. package/min/omni/index.js +1 -1
  31. package/min/omni/index.js.gz +0 -0
  32. package/min/omni/with-schemas/index.js +1 -1
  33. package/min/omni/with-schemas/index.js.gz +0 -0
  34. package/min/queries/index.js +1 -1
  35. package/min/queries/index.js.gz +0 -0
  36. package/min/queries/with-schemas/index.js +1 -1
  37. package/min/queries/with-schemas/index.js.gz +0 -0
  38. package/min/store/index.js +1 -1
  39. package/min/store/index.js.gz +0 -0
  40. package/min/store/with-schemas/index.js +1 -1
  41. package/min/store/with-schemas/index.js.gz +0 -0
  42. package/min/ui-react-inspector/index.js +1 -1
  43. package/min/ui-react-inspector/index.js.gz +0 -0
  44. package/min/ui-react-inspector/with-schemas/index.js +1 -1
  45. package/min/ui-react-inspector/with-schemas/index.js.gz +0 -0
  46. package/min/with-schemas/index.js +1 -1
  47. package/min/with-schemas/index.js.gz +0 -0
  48. package/omni/index.js +492 -161
  49. package/omni/with-schemas/index.js +492 -161
  50. package/package.json +37 -1
  51. package/queries/index.js +1 -6
  52. package/queries/with-schemas/index.js +1 -6
  53. package/readme.md +14 -14
  54. package/releases.md +41 -41
  55. package/store/index.js +370 -134
  56. package/store/with-schemas/index.js +370 -134
  57. package/ui-react-inspector/index.js +349 -134
  58. package/ui-react-inspector/with-schemas/index.js +349 -134
  59. package/with-schemas/index.js +484 -153
@@ -0,0 +1,1064 @@
1
+ /**
2
+ * The middleware module of the TinyBase project provides the ability to
3
+ * intercept and validate incoming writes to Store objects.
4
+ *
5
+ * The main entry point to this module is the createMiddleware function, which
6
+ * returns a new Middleware object. From there, you can register hooks that are
7
+ * called before data is written to the Store.
8
+ * @packageDocumentation
9
+ * @module middleware
10
+ * @since v8.0.0
11
+ */
12
+ import type {Id} from '../common/index.d.ts';
13
+ import type {
14
+ Cell,
15
+ CellOrUndefined,
16
+ Changes,
17
+ Content,
18
+ Row,
19
+ Store,
20
+ Table,
21
+ Tables,
22
+ Value,
23
+ ValueOrUndefined,
24
+ Values,
25
+ } from '../store/index.d.ts';
26
+
27
+ /**
28
+ * The WillSetContentCallback type describes a function that is called before
29
+ * Content is set in the Store.
30
+ *
31
+ * The callback receives the Content (a [Tables, Values] tuple) that is about
32
+ * to be set. It can return the Content (possibly transformed) to allow the
33
+ * write, or `undefined` to prevent the Content from being set.
34
+ *
35
+ * Multiple WillSetContentCallback functions can be registered and they will be
36
+ * called sequentially, the Content being updated successively. If any callback
37
+ * returns `undefined`, the chain short-circuits and the Content will not be
38
+ * set.
39
+ * @param content The Content about to be set.
40
+ * @returns The Content to use (possibly transformed), or `undefined` to
41
+ * prevent the write.
42
+ * @category Callback
43
+ * @since v8.0.0
44
+ */
45
+ export type WillSetContentCallback = (content: Content) => Content | undefined;
46
+
47
+ /**
48
+ * The WillSetTablesCallback type describes a function that is called before
49
+ * Tables are set in the Store.
50
+ *
51
+ * The callback receives the Tables object that is about to be set. It can
52
+ * return the Tables (possibly transformed) to allow the write, or `undefined`
53
+ * to prevent the Tables from being set.
54
+ *
55
+ * Multiple WillSetTablesCallback functions can be registered and they will be
56
+ * called sequentially, the Tables being updated successively. If any callback
57
+ * returns `undefined`, the chain short-circuits and the Tables will not be
58
+ * set.
59
+ * @param tables The Tables object about to be set.
60
+ * @returns The Tables to use (possibly transformed), or `undefined` to prevent
61
+ * the write.
62
+ * @category Callback
63
+ * @since v8.0.0
64
+ */
65
+ export type WillSetTablesCallback = (tables: Tables) => Tables | undefined;
66
+
67
+ /**
68
+ * The WillSetTableCallback type describes a function that is called before a
69
+ * Table is set in the Store.
70
+ *
71
+ * The callback receives the table Id and the Table object that is about to be
72
+ * set. It can return the Table (possibly transformed) to allow the write, or
73
+ * `undefined` to prevent the Table from being set.
74
+ *
75
+ * Multiple WillSetTableCallback functions can be registered and they will be
76
+ * called sequentially, the Table being updated successively. If any callback
77
+ * returns `undefined`, the chain short-circuits and the Table will not be set.
78
+ * @param tableId The Id of the Table being set.
79
+ * @param table The Table object about to be set.
80
+ * @returns The Table to use (possibly transformed), or `undefined` to prevent
81
+ * the write.
82
+ * @category Callback
83
+ * @since v8.0.0
84
+ */
85
+ export type WillSetTableCallback = (
86
+ tableId: Id,
87
+ table: Table,
88
+ ) => Table | undefined;
89
+
90
+ /**
91
+ * The WillSetRowCallback type describes a function that is called before a Row
92
+ * is set in the Store.
93
+ *
94
+ * The callback receives the table Id, row Id, and the Row object that is about
95
+ * to be set. It can return the Row (possibly transformed) to allow the write,
96
+ * or `undefined` to prevent the Row from being set.
97
+ *
98
+ * Multiple WillSetRowCallback functions can be registered and they will be
99
+ * called sequentially, the Row being updated successively. If any callback
100
+ * returns `undefined`, the chain short-circuits and the Row will not be set.
101
+ * @param tableId The Id of the Table being written to.
102
+ * @param rowId The Id of the Row being set.
103
+ * @param row The Row object about to be set.
104
+ * @returns The Row to use (possibly transformed), or `undefined` to prevent the
105
+ * write.
106
+ * @category Callback
107
+ * @since v8.0.0
108
+ */
109
+ export type WillSetRowCallback = (
110
+ tableId: Id,
111
+ rowId: Id,
112
+ row: Row,
113
+ ) => Row | undefined;
114
+
115
+ /**
116
+ * The WillSetCellCallback type describes a function that is called before a
117
+ * Cell is set in the Store.
118
+ *
119
+ * The callback receives the table Id, row Id, cell Id, and the Cell value that
120
+ * is about to be set. It can return the Cell value (possibly transformed) to
121
+ * allow the write, or `undefined` to prevent the Cell from being set.
122
+ *
123
+ * Multiple WillSetCellCallback functions can be registered and they will be
124
+ * called sequentially, the Cell value being updated successively. If any
125
+ * callback returns `undefined`, the chain short-circuits and the Cell will not
126
+ * be set.
127
+ * @param tableId The Id of the Table being written to.
128
+ * @param rowId The Id of the Row being written to.
129
+ * @param cellId The Id of the Cell being set.
130
+ * @param cell The Cell value about to be set.
131
+ * @returns The Cell value to use (possibly transformed), or `undefined` to
132
+ * prevent the write.
133
+ * @category Callback
134
+ * @since v8.0.0
135
+ */
136
+ export type WillSetCellCallback = (
137
+ tableId: Id,
138
+ rowId: Id,
139
+ cellId: Id,
140
+ cell: Cell,
141
+ ) => CellOrUndefined;
142
+
143
+ /**
144
+ * The WillSetValuesCallback type describes a function that is called before
145
+ * Values are set in the Store.
146
+ *
147
+ * The callback receives the Values object that is about to be set. It can
148
+ * return the Values (possibly transformed) to allow the write, or `undefined`
149
+ * to prevent the Values from being set.
150
+ *
151
+ * Multiple WillSetValuesCallback functions can be registered and they will be
152
+ * called sequentially, the Values being updated successively. If any callback
153
+ * returns `undefined`, the chain short-circuits and the Values will not be set.
154
+ * @param values The Values object about to be set.
155
+ * @returns The Values to use (possibly transformed), or `undefined` to prevent
156
+ * the write.
157
+ * @category Callback
158
+ * @since v8.0.0
159
+ */
160
+ export type WillSetValuesCallback = (values: Values) => Values | undefined;
161
+
162
+ /**
163
+ * The WillSetValueCallback type describes a function that is called before a
164
+ * Value is set in the Store.
165
+ *
166
+ * The callback receives the value Id and the Value that is about to be set. It
167
+ * can return the Value (possibly transformed) to allow the write, or
168
+ * `undefined` to prevent the Value from being set.
169
+ *
170
+ * Multiple WillSetValueCallback functions can be registered and they will be
171
+ * called sequentially, the Value being updated successively. If any callback
172
+ * returns `undefined`, the chain short-circuits and the Value will not be set.
173
+ * @param valueId The Id of the Value being set.
174
+ * @param value The Value about to be set.
175
+ * @returns The Value to use (possibly transformed), or `undefined` to prevent
176
+ * the write.
177
+ * @category Callback
178
+ * @since v8.0.0
179
+ */
180
+ export type WillSetValueCallback = (
181
+ valueId: Id,
182
+ value: Value,
183
+ ) => ValueOrUndefined;
184
+
185
+ /**
186
+ * The WillDelTablesCallback type describes a function that is called before all
187
+ * Tables are deleted from the Store.
188
+ *
189
+ * The callback takes no parameters. It returns `true` to allow the deletion, or
190
+ * `false` to prevent it.
191
+ *
192
+ * Multiple WillDelTablesCallback functions can be registered and they will be
193
+ * called sequentially. If any callback returns `false`, the chain
194
+ * short-circuits and the Tables will not be deleted.
195
+ * @returns `true` to allow the deletion, `false` to prevent it.
196
+ * @category Callback
197
+ * @since v8.0.0
198
+ */
199
+ export type WillDelTablesCallback = () => boolean;
200
+
201
+ /**
202
+ * The WillDelTableCallback type describes a function that is called before a
203
+ * Table is deleted from the Store.
204
+ *
205
+ * The callback receives the table Id of the Table about to be deleted. It
206
+ * returns `true` to allow the deletion, or `false` to prevent it.
207
+ *
208
+ * Multiple WillDelTableCallback functions can be registered and they will be
209
+ * called sequentially. If any callback returns `false`, the chain
210
+ * short-circuits and the Table will not be deleted.
211
+ * @param tableId The Id of the Table being deleted.
212
+ * @returns `true` to allow the deletion, `false` to prevent it.
213
+ * @category Callback
214
+ * @since v8.0.0
215
+ */
216
+ export type WillDelTableCallback = (tableId: Id) => boolean;
217
+
218
+ /**
219
+ * The WillDelRowCallback type describes a function that is called before a
220
+ * Row is deleted from the Store.
221
+ *
222
+ * The callback receives the table Id and row Id of the Row about to be
223
+ * deleted. It returns `true` to allow the deletion, or `false` to prevent it.
224
+ *
225
+ * Multiple WillDelRowCallback functions can be registered and they will be
226
+ * called sequentially. If any callback returns `false`, the chain
227
+ * short-circuits and the Row will not be deleted.
228
+ * @param tableId The Id of the Table containing the Row.
229
+ * @param rowId The Id of the Row being deleted.
230
+ * @returns `true` to allow the deletion, `false` to prevent it.
231
+ * @category Callback
232
+ * @since v8.0.0
233
+ */
234
+ export type WillDelRowCallback = (tableId: Id, rowId: Id) => boolean;
235
+
236
+ /**
237
+ * The WillDelCellCallback type describes a function that is called before a
238
+ * Cell is deleted from the Store.
239
+ *
240
+ * The callback receives the table Id, row Id, and cell Id of the Cell about to
241
+ * be deleted. It returns `true` to allow the deletion, or `false` to prevent
242
+ * it.
243
+ *
244
+ * Multiple WillDelCellCallback functions can be registered and they will be
245
+ * called sequentially. If any callback returns `false`, the chain
246
+ * short-circuits and the Cell will not be deleted.
247
+ * @param tableId The Id of the Table containing the Cell.
248
+ * @param rowId The Id of the Row containing the Cell.
249
+ * @param cellId The Id of the Cell being deleted.
250
+ * @returns `true` to allow the deletion, `false` to prevent it.
251
+ * @category Callback
252
+ * @since v8.0.0
253
+ */
254
+ export type WillDelCellCallback = (
255
+ tableId: Id,
256
+ rowId: Id,
257
+ cellId: Id,
258
+ ) => boolean;
259
+
260
+ /**
261
+ * The WillDelValuesCallback type describes a function that is called before all
262
+ * Values are deleted from the Store.
263
+ *
264
+ * The callback takes no parameters. It returns `true` to allow the deletion, or
265
+ * `false` to prevent it.
266
+ *
267
+ * Multiple WillDelValuesCallback functions can be registered and they will be
268
+ * called sequentially. If any callback returns `false`, the chain
269
+ * short-circuits and the Values will not be deleted.
270
+ * @returns `true` to allow the deletion, `false` to prevent it.
271
+ * @category Callback
272
+ * @since v8.0.0
273
+ */
274
+ export type WillDelValuesCallback = () => boolean;
275
+
276
+ /**
277
+ * The WillDelValueCallback type describes a function that is called before a
278
+ * Value is deleted from the Store.
279
+ *
280
+ * The callback receives the value Id of the Value about to be deleted. It
281
+ * returns `true` to allow the deletion, or `false` to prevent it.
282
+ *
283
+ * Multiple WillDelValueCallback functions can be registered and they will be
284
+ * called sequentially. If any callback returns `false`, the chain
285
+ * short-circuits and the Value will not be deleted.
286
+ * @param valueId The Id of the Value being deleted.
287
+ * @returns `true` to allow the deletion, `false` to prevent it.
288
+ * @category Callback
289
+ * @since v8.0.0
290
+ */
291
+ export type WillDelValueCallback = (valueId: Id) => boolean;
292
+
293
+ /**
294
+ * The WillApplyChangesCallback type describes a function that is called before
295
+ * Changes are applied to the Store.
296
+ *
297
+ * The callback receives the Changes object that is about to be applied. It can
298
+ * return the Changes (possibly transformed) to allow the write, or `undefined`
299
+ * to prevent the Changes from being applied.
300
+ *
301
+ * Multiple WillApplyChangesCallback functions can be registered and they will
302
+ * be called sequentially, the Changes being updated successively. If any
303
+ * callback returns `undefined`, the chain short-circuits and the Changes will
304
+ * not be applied.
305
+ * @param changes The Changes about to be applied.
306
+ * @returns The Changes to use (possibly transformed), or `undefined` to
307
+ * prevent the write.
308
+ * @category Callback
309
+ * @since v8.0.0
310
+ */
311
+ export type WillApplyChangesCallback = (
312
+ changes: Changes,
313
+ ) => Changes | undefined;
314
+
315
+ /**
316
+ * A Middleware object lets you intercept and validate writes to a Store.
317
+ *
318
+ * This is useful for enforcing business rules, data validation, or
319
+ * transformation logic before data is persisted in the Store.
320
+ *
321
+ * Create a Middleware object easily with the createMiddleware function.
322
+ * @example
323
+ * This example shows a very simple lifecycle of a Middleware object: from
324
+ * creation, to getting the Store reference, and then destroying it.
325
+ *
326
+ * ```js
327
+ * import {createMiddleware, createStore} from 'tinybase';
328
+ *
329
+ * const store = createStore();
330
+ * const middleware = createMiddleware(store);
331
+ *
332
+ * console.log(middleware.getStore() == store);
333
+ * // -> true
334
+ *
335
+ * middleware.destroy();
336
+ * ```
337
+ * @category Middleware
338
+ * @since v8.0.0
339
+ */
340
+ export interface Middleware {
341
+ /**
342
+ * The getStore method returns a reference to the underlying Store that is
343
+ * backing this Middleware object.
344
+ * @returns A reference to the Store.
345
+ * @example
346
+ * This example creates a Middleware object against a newly-created Store and
347
+ * then gets its reference in order to update its data.
348
+ *
349
+ * ```js
350
+ * import {createMiddleware, createStore} from 'tinybase';
351
+ *
352
+ * const middleware = createMiddleware(createStore());
353
+ * console.log(middleware.getStore().getTables());
354
+ * // -> {}
355
+ * middleware.destroy();
356
+ * ```
357
+ * @category Getter
358
+ * @since v8.0.0
359
+ */
360
+ getStore(): Store;
361
+
362
+ /**
363
+ * The addWillSetContentCallback method registers a
364
+ * WillSetContentCallback that will be called before Content is set in the
365
+ * Store.
366
+ *
367
+ * The callback can transform the Content or return `undefined` to prevent
368
+ * the write. Multiple callbacks can be registered and they are called
369
+ * sequentially, each receiving the (possibly transformed) Content from
370
+ * the previous callback.
371
+ * @param callback The WillSetContentCallback to register.
372
+ * @returns A reference to the Middleware object, for chaining.
373
+ * @example
374
+ * This example registers a callback that prevents setting Content with
375
+ * empty Tables in the pet store.
376
+ *
377
+ * ```js
378
+ * import {createMiddleware, createStore} from 'tinybase';
379
+ *
380
+ * const store = createStore();
381
+ * const middleware = createMiddleware(store);
382
+ *
383
+ * middleware.addWillSetContentCallback(([tables, values]) =>
384
+ * Object.keys(tables).length > 0 ? [tables, values] : undefined,
385
+ * );
386
+ *
387
+ * store.setContent([{}, {open: true}]);
388
+ * console.log(store.getContent());
389
+ * // -> [{}, {}]
390
+ *
391
+ * store.setContent([{pets: {fido: {species: 'dog'}}}, {}]);
392
+ * console.log(store.getContent());
393
+ * // -> [{pets: {fido: {species: 'dog'}}}, {}]
394
+ *
395
+ * middleware.destroy();
396
+ * ```
397
+ * @category Configuration
398
+ * @since v8.0.0
399
+ */
400
+ addWillSetContentCallback(callback: WillSetContentCallback): Middleware;
401
+
402
+ /**
403
+ * The addWillSetTablesCallback method registers a WillSetTablesCallback that
404
+ * will be called before Tables are set in the Store.
405
+ *
406
+ * The callback can transform the Tables or return `undefined` to prevent the
407
+ * write. Multiple callbacks can be registered and they are called
408
+ * sequentially, each receiving the (possibly transformed) tables from the
409
+ * previous callback.
410
+ * @param callback The WillSetTablesCallback to register.
411
+ * @returns A reference to the Middleware object, for chaining.
412
+ * @example
413
+ * This example registers a callback that upper-cases all string Cell values
414
+ * when entire Tables are set in the pet store.
415
+ *
416
+ * ```js
417
+ * import {createMiddleware, createStore} from 'tinybase';
418
+ *
419
+ * const store = createStore();
420
+ * const middleware = createMiddleware(store);
421
+ *
422
+ * middleware.addWillSetTablesCallback((tables) =>
423
+ * Object.fromEntries(
424
+ * Object.entries(tables).map(([tableId, table]) => [
425
+ * tableId,
426
+ * Object.fromEntries(
427
+ * Object.entries(table).map(([rowId, row]) => [
428
+ * rowId,
429
+ * Object.fromEntries(
430
+ * Object.entries(row).map(([k, v]) => [
431
+ * k,
432
+ * typeof v === 'string' ? v.toUpperCase() : v,
433
+ * ]),
434
+ * ),
435
+ * ]),
436
+ * ),
437
+ * ]),
438
+ * ),
439
+ * );
440
+ *
441
+ * store.setTables({pets: {fido: {species: 'dog'}, felix: {species: 'cat'}}});
442
+ * console.log(store.getTables());
443
+ * // -> {pets: {fido: {species: 'DOG'}, felix: {species: 'CAT'}}}
444
+ *
445
+ * middleware.destroy();
446
+ * ```
447
+ * @example
448
+ * This example registers a callback that prevents setting any Tables that
449
+ * include a 'banned' table.
450
+ *
451
+ * ```js
452
+ * import {createMiddleware, createStore} from 'tinybase';
453
+ *
454
+ * const store = createStore();
455
+ * const middleware = createMiddleware(store);
456
+ *
457
+ * middleware.addWillSetTablesCallback((tables) =>
458
+ * 'banned' in tables ? undefined : tables,
459
+ * );
460
+ *
461
+ * store.setTables({banned: {r1: {c1: 1}}, pets: {fido: {species: 'dog'}}});
462
+ * console.log(store.getTables());
463
+ * // -> {}
464
+ *
465
+ * middleware.destroy();
466
+ * ```
467
+ * @category Configuration
468
+ * @since v8.0.0
469
+ */
470
+ addWillSetTablesCallback(callback: WillSetTablesCallback): Middleware;
471
+
472
+ /**
473
+ * The addWillSetTableCallback method registers a WillSetTableCallback that
474
+ * will be called before any Table is set in the Store.
475
+ *
476
+ * The callback can transform the Table or return `undefined` to prevent the
477
+ * write. Multiple callbacks can be registered and they are called
478
+ * sequentially, each receiving the (possibly transformed) table from the
479
+ * previous callback.
480
+ * @param callback The WillSetTableCallback to register.
481
+ * @returns A reference to the Middleware object, for chaining.
482
+ * @example
483
+ * This example registers a callback that upper-cases string Cell values in
484
+ * rows set to the 'pets' table.
485
+ *
486
+ * ```js
487
+ * import {createMiddleware, createStore} from 'tinybase';
488
+ *
489
+ * const store = createStore();
490
+ * const middleware = createMiddleware(store);
491
+ *
492
+ * middleware.addWillSetTableCallback((tableId, table) =>
493
+ * tableId === 'pets'
494
+ * ? Object.fromEntries(
495
+ * Object.entries(table).map(([rowId, row]) => [
496
+ * rowId,
497
+ * Object.fromEntries(
498
+ * Object.entries(row).map(([k, v]) => [
499
+ * k,
500
+ * typeof v === 'string' ? v.toUpperCase() : v,
501
+ * ]),
502
+ * ),
503
+ * ]),
504
+ * )
505
+ * : table,
506
+ * );
507
+ *
508
+ * store.setTable('pets', {fido: {species: 'dog'}, felix: {species: 'cat'}});
509
+ * console.log(store.getTable('pets'));
510
+ * // -> {fido: {species: 'DOG'}, felix: {species: 'CAT'}}
511
+ *
512
+ * middleware.destroy();
513
+ * ```
514
+ * @example
515
+ * This example registers a callback that prevents writes to the 'species'
516
+ * table.
517
+ *
518
+ * ```js
519
+ * import {createMiddleware, createStore} from 'tinybase';
520
+ *
521
+ * const store = createStore();
522
+ * const middleware = createMiddleware(store);
523
+ *
524
+ * middleware.addWillSetTableCallback((tableId, table) =>
525
+ * tableId === 'species' ? undefined : table,
526
+ * );
527
+ *
528
+ * store.setTable('species', {dog: {legs: 4, sound: 'woof'}});
529
+ * console.log(store.getTables());
530
+ * // -> {}
531
+ *
532
+ * middleware.destroy();
533
+ * ```
534
+ * @category Configuration
535
+ * @since v8.0.0
536
+ */
537
+ addWillSetTableCallback(callback: WillSetTableCallback): Middleware;
538
+
539
+ /**
540
+ * The addWillSetRowCallback method registers a WillSetRowCallback that will
541
+ * be called before any Row is set in the Store.
542
+ *
543
+ * The callback can transform the Row or return `undefined` to prevent the
544
+ * write. Multiple callbacks can be registered and they are called
545
+ * sequentially, each receiving the (possibly transformed) row from the
546
+ * previous callback.
547
+ * @param callback The WillSetRowCallback to register.
548
+ * @returns A reference to the Middleware object, for chaining.
549
+ * @example
550
+ * This example registers a callback that upper-cases string Cell values in
551
+ * rows set to the 'pets' table.
552
+ *
553
+ * ```js
554
+ * import {createMiddleware, createStore} from 'tinybase';
555
+ *
556
+ * const store = createStore();
557
+ * const middleware = createMiddleware(store);
558
+ *
559
+ * middleware.addWillSetRowCallback((tableId, _rowId, row) =>
560
+ * tableId === 'pets'
561
+ * ? Object.fromEntries(
562
+ * Object.entries(row).map(([k, v]) => [
563
+ * k,
564
+ * typeof v === 'string' ? v.toUpperCase() : v,
565
+ * ]),
566
+ * )
567
+ * : row,
568
+ * );
569
+ *
570
+ * store.setRow('pets', 'fido', {species: 'dog', legs: 4});
571
+ * console.log(store.getRow('pets', 'fido'));
572
+ * // -> {species: 'DOG', legs: 4}
573
+ *
574
+ * middleware.destroy();
575
+ * ```
576
+ * @example
577
+ * This example registers a callback that prevents writes to the 'species'
578
+ * table.
579
+ *
580
+ * ```js
581
+ * import {createMiddleware, createStore} from 'tinybase';
582
+ *
583
+ * const store = createStore();
584
+ * const middleware = createMiddleware(store);
585
+ *
586
+ * middleware.addWillSetRowCallback((tableId, _rowId, row) =>
587
+ * tableId === 'species' ? undefined : row,
588
+ * );
589
+ *
590
+ * store.setRow('species', 'dog', {legs: 4, sound: 'woof'});
591
+ * console.log(store.getTables());
592
+ * // -> {}
593
+ *
594
+ * middleware.destroy();
595
+ * ```
596
+ * @category Configuration
597
+ * @since v8.0.0
598
+ */
599
+ addWillSetRowCallback(callback: WillSetRowCallback): Middleware;
600
+
601
+ /**
602
+ * The addWillSetCellCallback method registers a WillSetCellCallback that will
603
+ * be called before any Cell is set in the Store.
604
+ *
605
+ * The callback can transform the Cell value or return `undefined` to prevent
606
+ * the write. Multiple callbacks can be registered and they are called
607
+ * sequentially, each receiving the (possibly transformed) value from the
608
+ * previous callback.
609
+ * @param callback The WillSetCellCallback to register.
610
+ * @returns A reference to the Middleware object, for chaining.
611
+ * @example
612
+ * This example registers a callback that upper-cases string Cell values in
613
+ * the 'pets' table.
614
+ *
615
+ * ```js
616
+ * import {createMiddleware, createStore} from 'tinybase';
617
+ *
618
+ * const store = createStore();
619
+ * const middleware = createMiddleware(store);
620
+ *
621
+ * middleware.addWillSetCellCallback((tableId, rowId, cellId, cell) =>
622
+ * tableId === 'pets' && typeof cell === 'string'
623
+ * ? cell.toUpperCase()
624
+ * : cell,
625
+ * );
626
+ *
627
+ * store.setCell('pets', 'fido', 'species', 'dog');
628
+ * console.log(store.getCell('pets', 'fido', 'species'));
629
+ * // -> 'DOG'
630
+ *
631
+ * middleware.destroy();
632
+ * ```
633
+ * @example
634
+ * This example registers a callback that prevents writes to the 'species'
635
+ * table.
636
+ *
637
+ * ```js
638
+ * import {createMiddleware, createStore} from 'tinybase';
639
+ *
640
+ * const store = createStore();
641
+ * const middleware = createMiddleware(store);
642
+ *
643
+ * middleware.addWillSetCellCallback((tableId, _rowId, _cellId, cell) =>
644
+ * tableId === 'species' ? undefined : cell,
645
+ * );
646
+ *
647
+ * store.setCell('species', 'dog', 'legs', 4);
648
+ * console.log(store.getTables());
649
+ * // -> {}
650
+ *
651
+ * middleware.destroy();
652
+ * ```
653
+ * @category Configuration
654
+ * @since v8.0.0
655
+ */
656
+ addWillSetCellCallback(callback: WillSetCellCallback): Middleware;
657
+
658
+ /**
659
+ * The addWillSetValuesCallback method registers a WillSetValuesCallback that
660
+ * will be called before Values are set in the Store.
661
+ *
662
+ * The callback can transform the Values or return `undefined` to prevent the
663
+ * write. Multiple callbacks can be registered and they are called
664
+ * sequentially, each receiving the (possibly transformed) values from the
665
+ * previous callback.
666
+ * @param callback The WillSetValuesCallback to register.
667
+ * @returns A reference to the Middleware object, for chaining.
668
+ * @example
669
+ * This example registers a callback that upper-cases all string Values in the
670
+ * pet store's settings.
671
+ *
672
+ * ```js
673
+ * import {createMiddleware, createStore} from 'tinybase';
674
+ *
675
+ * const store = createStore();
676
+ * const middleware = createMiddleware(store);
677
+ *
678
+ * middleware.addWillSetValuesCallback((values) =>
679
+ * Object.fromEntries(
680
+ * Object.entries(values).map(([k, v]) => [
681
+ * k,
682
+ * typeof v === 'string' ? v.toUpperCase() : v,
683
+ * ]),
684
+ * ),
685
+ * );
686
+ *
687
+ * store.setValues({storeName: 'happy pets', limit: 50});
688
+ * console.log(store.getValues());
689
+ * // -> {storeName: 'HAPPY PETS', limit: 50}
690
+ *
691
+ * middleware.destroy();
692
+ * ```
693
+ * @example
694
+ * This example registers a callback that prevents setting Values when the pet
695
+ * store is 'closed'.
696
+ *
697
+ * ```js
698
+ * import {createMiddleware, createStore} from 'tinybase';
699
+ *
700
+ * const store = createStore();
701
+ * const middleware = createMiddleware(store);
702
+ *
703
+ * middleware.addWillSetValuesCallback((values) =>
704
+ * 'closed' in values ? undefined : values,
705
+ * );
706
+ *
707
+ * store.setValues({closed: true, storeName: 'happy pets'});
708
+ * console.log(store.getValues());
709
+ * // -> {}
710
+ *
711
+ * middleware.destroy();
712
+ * ```
713
+ * @category Configuration
714
+ * @since v8.0.0
715
+ */
716
+ addWillSetValuesCallback(callback: WillSetValuesCallback): Middleware;
717
+
718
+ /**
719
+ * The addWillSetValueCallback method registers a WillSetValueCallback that
720
+ * will be called before any Value is set in the Store.
721
+ *
722
+ * The callback can transform the Value or return `undefined` to prevent the
723
+ * write. Multiple callbacks can be registered and they are called
724
+ * sequentially, each receiving the (possibly transformed) value from the
725
+ * previous callback.
726
+ * @param callback The WillSetValueCallback to register.
727
+ * @returns A reference to the Middleware object, for chaining.
728
+ * @example
729
+ * This example registers a callback that clamps the 'limit' Value to the
730
+ * maximum capacity of the pet store.
731
+ *
732
+ * ```js
733
+ * import {createMiddleware, createStore} from 'tinybase';
734
+ *
735
+ * const store = createStore();
736
+ * const middleware = createMiddleware(store);
737
+ *
738
+ * middleware.addWillSetValueCallback((valueId, value) =>
739
+ * valueId === 'limit' && typeof value === 'number'
740
+ * ? Math.min(50, Math.max(0, value))
741
+ * : value,
742
+ * );
743
+ *
744
+ * store.setValue('limit', 100);
745
+ * console.log(store.getValue('limit'));
746
+ * // -> 50
747
+ *
748
+ * middleware.destroy();
749
+ * ```
750
+ * @category Configuration
751
+ * @since v8.0.0
752
+ */
753
+ addWillSetValueCallback(callback: WillSetValueCallback): Middleware;
754
+
755
+ /**
756
+ * The addWillDelTablesCallback method registers a WillDelTablesCallback that
757
+ * will be called before all Tables are deleted from the Store.
758
+ *
759
+ * The callback returns `true` to allow the deletion or `false` to prevent
760
+ * it. Multiple callbacks can be registered and they are called sequentially.
761
+ * If any callback returns `false`, the deletion is prevented.
762
+ * @param callback The WillDelTablesCallback to register.
763
+ * @returns A reference to the Middleware object, for chaining.
764
+ * @example
765
+ * This example registers a callback that prevents deleting all Tables from
766
+ * the pet store.
767
+ *
768
+ * ```js
769
+ * import {createMiddleware, createStore} from 'tinybase';
770
+ *
771
+ * const store = createStore();
772
+ * const middleware = createMiddleware(store);
773
+ *
774
+ * store.setTables({pets: {fido: {species: 'dog'}, felix: {species: 'cat'}}});
775
+ *
776
+ * middleware.addWillDelTablesCallback(() => false);
777
+ *
778
+ * store.delTables();
779
+ * console.log(store.getTables());
780
+ * // -> {pets: {fido: {species: 'dog'}, felix: {species: 'cat'}}}
781
+ *
782
+ * middleware.destroy();
783
+ * ```
784
+ * @category Configuration
785
+ * @since v8.0.0
786
+ */
787
+ addWillDelTablesCallback(callback: WillDelTablesCallback): Middleware;
788
+
789
+ /**
790
+ * The addWillDelTableCallback method registers a WillDelTableCallback that
791
+ * will be called before any Table is deleted from the Store.
792
+ *
793
+ * The callback returns `true` to allow the deletion or `false` to prevent
794
+ * it. Multiple callbacks can be registered and they are called sequentially.
795
+ * If any callback returns `false`, the deletion is prevented.
796
+ * @param callback The WillDelTableCallback to register.
797
+ * @returns A reference to the Middleware object, for chaining.
798
+ * @example
799
+ * This example registers a callback that prevents deleting the 'pets' table
800
+ * from the pet store.
801
+ *
802
+ * ```js
803
+ * import {createMiddleware, createStore} from 'tinybase';
804
+ *
805
+ * const store = createStore();
806
+ * const middleware = createMiddleware(store);
807
+ *
808
+ * store.setTable('pets', {fido: {species: 'dog'}, felix: {species: 'cat'}});
809
+ *
810
+ * middleware.addWillDelTableCallback((tableId) => tableId !== 'pets');
811
+ *
812
+ * store.delTable('pets');
813
+ * console.log(store.getTable('pets'));
814
+ * // -> {fido: {species: 'dog'}, felix: {species: 'cat'}}
815
+ *
816
+ * middleware.destroy();
817
+ * ```
818
+ * @category Configuration
819
+ * @since v8.0.0
820
+ */
821
+ addWillDelTableCallback(callback: WillDelTableCallback): Middleware;
822
+
823
+ /**
824
+ * The addWillDelRowCallback method registers a WillDelRowCallback that will
825
+ * be called before any Row is deleted from the Store.
826
+ *
827
+ * The callback returns `true` to allow the deletion or `false` to prevent it.
828
+ * Multiple callbacks can be registered and they are called sequentially. If
829
+ * any callback returns `false`, the deletion is prevented.
830
+ * @param callback The WillDelRowCallback to register.
831
+ * @returns A reference to the Middleware object, for chaining.
832
+ * @example
833
+ * This example registers a callback that prevents deleting rows from the
834
+ * 'pets' table.
835
+ *
836
+ * ```js
837
+ * import {createMiddleware, createStore} from 'tinybase';
838
+ *
839
+ * const store = createStore();
840
+ * const middleware = createMiddleware(store);
841
+ *
842
+ * store.setRow('pets', 'fido', {species: 'dog', legs: 4});
843
+ *
844
+ * middleware.addWillDelRowCallback((tableId) => tableId !== 'pets');
845
+ *
846
+ * store.delRow('pets', 'fido');
847
+ * console.log(store.getRow('pets', 'fido'));
848
+ * // -> {species: 'dog', legs: 4}
849
+ *
850
+ * middleware.destroy();
851
+ * ```
852
+ * @category Configuration
853
+ * @since v8.0.0
854
+ */
855
+ addWillDelRowCallback(callback: WillDelRowCallback): Middleware;
856
+
857
+ /**
858
+ * The addWillDelCellCallback method registers a WillDelCellCallback that will
859
+ * be called before any Cell is deleted from the Store.
860
+ *
861
+ * The callback returns `true` to allow the deletion or `false` to prevent it.
862
+ * Multiple callbacks can be registered and they are called sequentially. If
863
+ * any callback returns `false`, the deletion is prevented.
864
+ * @param callback The WillDelCellCallback to register.
865
+ * @returns A reference to the Middleware object, for chaining.
866
+ * @example
867
+ * This example registers a callback that prevents deleting cells from the
868
+ * 'pets' table.
869
+ *
870
+ * ```js
871
+ * import {createMiddleware, createStore} from 'tinybase';
872
+ *
873
+ * const store = createStore();
874
+ * const middleware = createMiddleware(store);
875
+ *
876
+ * store.setCell('pets', 'fido', 'species', 'dog');
877
+ *
878
+ * middleware.addWillDelCellCallback((tableId) => tableId !== 'pets');
879
+ *
880
+ * store.delCell('pets', 'fido', 'species', true);
881
+ * console.log(store.getCell('pets', 'fido', 'species'));
882
+ * // -> 'dog'
883
+ *
884
+ * middleware.destroy();
885
+ * ```
886
+ * @category Configuration
887
+ * @since v8.0.0
888
+ */
889
+ addWillDelCellCallback(callback: WillDelCellCallback): Middleware;
890
+
891
+ /**
892
+ * The addWillDelValuesCallback method registers a WillDelValuesCallback that
893
+ * will be called before all Values are deleted from the Store.
894
+ *
895
+ * The callback returns `true` to allow the deletion or `false` to prevent it.
896
+ * Multiple callbacks can be registered and they are called sequentially. If
897
+ * any callback returns `false`, the deletion is prevented.
898
+ * @param callback The WillDelValuesCallback to register.
899
+ * @returns A reference to the Middleware object, for chaining.
900
+ * @example
901
+ * This example registers a callback that prevents deleting all Values from
902
+ * the pet store.
903
+ *
904
+ * ```js
905
+ * import {createMiddleware, createStore} from 'tinybase';
906
+ *
907
+ * const store = createStore();
908
+ * const middleware = createMiddleware(store);
909
+ *
910
+ * store.setValues({storeName: 'happy pets', limit: 50});
911
+ *
912
+ * middleware.addWillDelValuesCallback(() => false);
913
+ *
914
+ * store.delValues();
915
+ * console.log(store.getValues());
916
+ * // -> {storeName: 'happy pets', limit: 50}
917
+ *
918
+ * middleware.destroy();
919
+ * ```
920
+ * @category Configuration
921
+ * @since v8.0.0
922
+ */
923
+ addWillDelValuesCallback(callback: WillDelValuesCallback): Middleware;
924
+
925
+ /**
926
+ * The addWillDelValueCallback method registers a WillDelValueCallback that
927
+ * will be called before any Value is deleted from the Store.
928
+ *
929
+ * The callback returns `true` to allow the deletion or `false` to prevent it.
930
+ * Multiple callbacks can be registered and they are called sequentially. If
931
+ * any callback returns `false`, the deletion is prevented.
932
+ * @param callback The WillDelValueCallback to register.
933
+ * @returns A reference to the Middleware object, for chaining.
934
+ * @example
935
+ * This example registers a callback that prevents deleting the 'storeName'
936
+ * Value from the pet store.
937
+ *
938
+ * ```js
939
+ * import {createMiddleware, createStore} from 'tinybase';
940
+ *
941
+ * const store = createStore();
942
+ * const middleware = createMiddleware(store);
943
+ *
944
+ * store.setValue('storeName', 'happy pets');
945
+ *
946
+ * middleware.addWillDelValueCallback((valueId) => valueId !== 'storeName');
947
+ *
948
+ * store.delValue('storeName');
949
+ * console.log(store.getValue('storeName'));
950
+ * // -> 'happy pets'
951
+ *
952
+ * middleware.destroy();
953
+ * ```
954
+ * @category Configuration
955
+ * @since v8.0.0
956
+ */
957
+ addWillDelValueCallback(callback: WillDelValueCallback): Middleware;
958
+
959
+ /**
960
+ * The addWillApplyChangesCallback method registers a
961
+ * WillApplyChangesCallback that will be called before Changes are applied to
962
+ * the Store via the applyChanges method.
963
+ *
964
+ * This callback receives the Changes object and can return it (to allow),
965
+ * return a modified Changes object (to transform), or return `undefined` (to
966
+ * reject). Multiple callbacks can be registered and they are called
967
+ * sequentially, each receiving the output of the previous. If any callback
968
+ * returns `undefined`, all remaining callbacks are skipped and the changes
969
+ * are rejected.
970
+ *
971
+ * This fires when applyChanges is called directly, or indirectly via
972
+ * applyMergeableChanges, setMergeableContent, or merge on a MergeableStore.
973
+ * @param callback The WillApplyChangesCallback to register.
974
+ * @returns A reference to the Middleware object, for chaining.
975
+ * @example
976
+ * This example registers a callback that rejects changes containing a
977
+ * 'secret' table.
978
+ *
979
+ * ```js
980
+ * import {createMiddleware, createStore} from 'tinybase';
981
+ *
982
+ * const store = createStore();
983
+ * const middleware = createMiddleware(store);
984
+ *
985
+ * middleware.addWillApplyChangesCallback(([changedTables, changedValues]) =>
986
+ * changedTables['secret'] != null
987
+ * ? undefined
988
+ * : [changedTables, changedValues, 1],
989
+ * );
990
+ *
991
+ * store.applyChanges([{pets: {fido: {species: 'dog'}}}, {}, 1]);
992
+ * console.log(store.getRow('pets', 'fido'));
993
+ * // -> {species: 'dog'}
994
+ *
995
+ * store.applyChanges([{secret: {r1: {c1: 'v1'}}}, {}, 1]);
996
+ * console.log(store.getTable('secret'));
997
+ * // -> {}
998
+ *
999
+ * middleware.destroy();
1000
+ * ```
1001
+ * @category Configuration
1002
+ * @since v8.0.0
1003
+ */
1004
+ addWillApplyChangesCallback(callback: WillApplyChangesCallback): Middleware;
1005
+
1006
+ /**
1007
+ * The destroy method should be called when this Middleware object is no
1008
+ * longer used. It removes all hooks and listeners from the Store, and
1009
+ * unregisters the Middleware from the Store.
1010
+ * @example
1011
+ * This example creates a Middleware object against a newly-created Store and
1012
+ * then destroys it.
1013
+ *
1014
+ * ```js
1015
+ * import {createMiddleware, createStore} from 'tinybase';
1016
+ *
1017
+ * const store = createStore();
1018
+ * const middleware = createMiddleware(store);
1019
+ * middleware.destroy();
1020
+ * ```
1021
+ * @category Lifecycle
1022
+ * @since v8.0.0
1023
+ */
1024
+ destroy(): void;
1025
+ }
1026
+
1027
+ /**
1028
+ * The createMiddleware function creates a Middleware object, and is the main
1029
+ * entry point into the middleware module.
1030
+ *
1031
+ * A given Store can only have one Middleware object associated with it. If you
1032
+ * call this function twice on the same Store, your second call will return a
1033
+ * reference to the Middleware object created by the first.
1034
+ * @param store The Store for which to register the Middleware.
1035
+ * @returns A reference to the new Middleware object.
1036
+ * @example
1037
+ * This example creates a Middleware object.
1038
+ *
1039
+ * ```js
1040
+ * import {createMiddleware, createStore} from 'tinybase';
1041
+ *
1042
+ * const store = createStore();
1043
+ * const middleware = createMiddleware(store);
1044
+ * console.log(middleware.getStore() == store);
1045
+ * // -> true
1046
+ * middleware.destroy();
1047
+ * ```
1048
+ * @example
1049
+ * This example creates a Middleware object, and calls the method a second time
1050
+ * for the same Store to return the same object.
1051
+ *
1052
+ * ```js
1053
+ * import {createMiddleware, createStore} from 'tinybase';
1054
+ *
1055
+ * const store = createStore();
1056
+ * const middleware = createMiddleware(store);
1057
+ * console.log(middleware === createMiddleware(store));
1058
+ * // -> true
1059
+ * middleware.destroy();
1060
+ * ```
1061
+ * @category Creation
1062
+ * @since v8.0.0
1063
+ */
1064
+ export function createMiddleware(store: Store): Middleware;