tinybase 0.0.0 → 0.9.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 (61) hide show
  1. package/LICENSE +21 -0
  2. package/lib/checkpoints.d.ts +861 -0
  3. package/lib/checkpoints.js +1 -0
  4. package/lib/checkpoints.js.gz +0 -0
  5. package/lib/common.d.ts +59 -0
  6. package/lib/debug/checkpoints.d.ts +861 -0
  7. package/lib/debug/checkpoints.js +326 -0
  8. package/lib/debug/common.d.ts +59 -0
  9. package/lib/debug/indexes.d.ts +815 -0
  10. package/lib/debug/indexes.js +390 -0
  11. package/lib/debug/metrics.d.ts +728 -0
  12. package/lib/debug/metrics.js +391 -0
  13. package/lib/debug/persisters.d.ts +521 -0
  14. package/lib/debug/persisters.js +191 -0
  15. package/lib/debug/react.d.ts +7077 -0
  16. package/lib/debug/react.js +1037 -0
  17. package/lib/debug/relationships.d.ts +1091 -0
  18. package/lib/debug/relationships.js +418 -0
  19. package/lib/debug/store.d.ts +2424 -0
  20. package/lib/debug/store.js +725 -0
  21. package/lib/debug/tinybase.d.ts +14 -0
  22. package/lib/debug/tinybase.js +2727 -0
  23. package/lib/indexes.d.ts +815 -0
  24. package/lib/indexes.js +1 -0
  25. package/lib/indexes.js.gz +0 -0
  26. package/lib/metrics.d.ts +728 -0
  27. package/lib/metrics.js +1 -0
  28. package/lib/metrics.js.gz +0 -0
  29. package/lib/persisters.d.ts +521 -0
  30. package/lib/persisters.js +1 -0
  31. package/lib/persisters.js.gz +0 -0
  32. package/lib/react.d.ts +7077 -0
  33. package/lib/react.js +1 -0
  34. package/lib/react.js.gz +0 -0
  35. package/lib/relationships.d.ts +1091 -0
  36. package/lib/relationships.js +1 -0
  37. package/lib/relationships.js.gz +0 -0
  38. package/lib/store.d.ts +2424 -0
  39. package/lib/store.js +1 -0
  40. package/lib/store.js.gz +0 -0
  41. package/lib/tinybase.d.ts +14 -0
  42. package/lib/tinybase.js +1 -0
  43. package/lib/tinybase.js.gz +0 -0
  44. package/lib/umd/checkpoints.js +1 -0
  45. package/lib/umd/checkpoints.js.gz +0 -0
  46. package/lib/umd/indexes.js +1 -0
  47. package/lib/umd/indexes.js.gz +0 -0
  48. package/lib/umd/metrics.js +1 -0
  49. package/lib/umd/metrics.js.gz +0 -0
  50. package/lib/umd/persisters.js +1 -0
  51. package/lib/umd/persisters.js.gz +0 -0
  52. package/lib/umd/react.js +1 -0
  53. package/lib/umd/react.js.gz +0 -0
  54. package/lib/umd/relationships.js +1 -0
  55. package/lib/umd/relationships.js.gz +0 -0
  56. package/lib/umd/store.js +1 -0
  57. package/lib/umd/store.js.gz +0 -0
  58. package/lib/umd/tinybase.js +1 -0
  59. package/lib/umd/tinybase.js.gz +0 -0
  60. package/package.json +93 -2
  61. package/readme.md +195 -0
@@ -0,0 +1,861 @@
1
+ /**
2
+ * The checkpoints module of the TinyBase project provides the ability to
3
+ * create and track checkpoints made to the data in Store objects.
4
+ *
5
+ * The main entry point to this module is the createCheckpoints function, which
6
+ * returns a new Checkpoints object. From there, you can create new checkpoints,
7
+ * go forwards or backwards to others, and register listeners for when the list
8
+ * of checkpoints change.
9
+ *
10
+ * @packageDocumentation
11
+ * @module checkpoints
12
+ */
13
+
14
+ import {Id, IdOrNull, Ids} from './common.d';
15
+ import {Store} from './store.d';
16
+
17
+ /**
18
+ * The CheckpointIds type is a representation of the list of checkpoint Ids
19
+ * stored in a Checkpoints object.
20
+ *
21
+ * There are three parts to a CheckpointsIds array:
22
+ *
23
+ * - The 'backward' checkpoint Ids that can be rolled backward to (in other
24
+ * words, the checkpoints in the undo stack for this Store). They are in
25
+ * chronological order with the oldest checkpoint at the start of the array.
26
+ * - The current checkpoint Id of the Store's state, or `undefined` if the
27
+ * current state has not been checkpointed.
28
+ * - The 'forward' checkpoint Ids that can be rolled forward to (in other words,
29
+ * the checkpoints in the redo stack for this Store). They are in
30
+ * chronological order with the newest checkpoint at the end of the array.
31
+ *
32
+ * @category Identity
33
+ */
34
+ export type CheckpointIds = [Ids, Id | undefined, Ids];
35
+
36
+ /**
37
+ * The CheckpointIdsListener type describes a function that is used to listen to
38
+ * changes to the checkpoint Ids in a Checkpoints object.
39
+ *
40
+ * A CheckpointIdsListener is provided when using the addCheckpointIdsListener
41
+ * method. See that method for specific examples.
42
+ *
43
+ * When called, a CheckpointIdsListener is given a reference to the Checkpoints
44
+ * object.
45
+ *
46
+ * @category Listener
47
+ */
48
+ export type CheckpointIdsListener = (checkpoints: Checkpoints) => void;
49
+
50
+ /**
51
+ * The CheckpointListener type describes a function that is used to listen to
52
+ * changes to a checkpoint's label in a Checkpoints object.
53
+ *
54
+ * A CheckpointListener is provided when using the addCheckpointListener method.
55
+ * See that method for specific examples.
56
+ *
57
+ * When called, a CheckpointListener is given a reference to the Checkpoints
58
+ * object, and the Id of the checkpoint whose label changed.
59
+ *
60
+ * @category Listener
61
+ */
62
+ export type CheckpointListener = (
63
+ checkpoints: Checkpoints,
64
+ checkpointId: Id,
65
+ ) => void;
66
+
67
+ /**
68
+ * The CheckpointsListenerStats type describes the number of listeners
69
+ * registered with the Checkpoints object, and can be used for debugging
70
+ * purposes.
71
+ *
72
+ * A CheckpointsListenerStats object is returned from the getListenerStats
73
+ * method, and is only populated in a debug build.
74
+ *
75
+ * @category Development
76
+ */
77
+ export type CheckpointsListenerStats = {
78
+ checkpointIds?: number;
79
+ checkpoint?: number;
80
+ };
81
+
82
+ /**
83
+ * A Checkpoints object lets you set checkpoints on a Store, and move forward
84
+ * and backward through them to create undo and redo functionality.
85
+ *
86
+ * Create a Checkpoints object easily with the createCheckpoints function. From
87
+ * there, you can set checkpoints (with the addCheckpoint method), query the
88
+ * checkpoints available (with the getCheckpointIds method), move forward and
89
+ * backward through them (with the goBackward method, goForward method, and goTo
90
+ * method), and add listeners for when the list checkpoints changes (with the
91
+ * addCheckpointIdsListener method).
92
+ *
93
+ * Every checkpoint can be given a label which can be used to describe the
94
+ * actions that changed the Store before this checkpoint. This can be useful for
95
+ * interfaces that let users 'Undo [last action]'.
96
+ *
97
+ * You
98
+ *
99
+ * @example
100
+ * This example shows a simple lifecycle of a Checkpoints object: from creation,
101
+ * to adding a checkpoint, getting the list of available checkpoints, and then
102
+ * registering and removing a listener for them.
103
+ *
104
+ * ```tsx
105
+ * const store = createStore().setTables({pets: {fido: {sold: false}}});
106
+ *
107
+ * const checkpoints = createCheckpoints(store);
108
+ * checkpoints.setSize(200);
109
+ * console.log(checkpoints.getCheckpointIds());
110
+ * // -> [[], '0', []]
111
+ *
112
+ * store.setCell('pets', 'fido', 'sold', true);
113
+ * checkpoints.addCheckpoint('sale');
114
+ * console.log(checkpoints.getCheckpointIds());
115
+ * // -> [['0'], '1', []]
116
+ *
117
+ * checkpoints.goBackward();
118
+ * console.log(store.getCell('pets', 'fido', 'sold'));
119
+ * // -> false
120
+ * console.log(checkpoints.getCheckpointIds());
121
+ * // -> [[], '0', ['1']]
122
+ *
123
+ * const listenerId = checkpoints.addCheckpointIdsListener(() => {
124
+ * console.log(checkpoints.getCheckpointIds());
125
+ * });
126
+ * store.setCell('pets', 'fido', 'species', 'dog');
127
+ * // -> [['0'], undefined, []]
128
+ * checkpoints.addCheckpoint();
129
+ * // -> [['0'], '2', []]
130
+ * // Previous redo of checkpoint '1' is now not possible.
131
+ *
132
+ * checkpoints.delListener(listenerId);
133
+ * checkpoints.destroy();
134
+ * ```
135
+ */
136
+ export interface Checkpoints {
137
+ /**
138
+ * The setSize method lets you specify how many checkpoints the Checkpoints
139
+ * object will store.
140
+ *
141
+ * If you set more checkpoints than this size, the oldest checkpoints will be
142
+ * pruned to make room for more recent ones.
143
+ *
144
+ * The default size for a newly-created Checkpoints object is 100.
145
+ *
146
+ * @param size The number of checkpoints that this Checkpoints object should
147
+ * hold.
148
+ * @returns A reference to the Checkpoints object.
149
+ * @example
150
+ * This example creates a Store, adds a Checkpoints object, reduces the size
151
+ * of the Checkpoints object dramatically and then creates more than that
152
+ * number of checkpoints to demonstrate the oldest being pruned.
153
+ *
154
+ * ```tsx
155
+ * const store = createStore().setTables({pets: {fido: {views: 0}}});
156
+ *
157
+ * const checkpoints = createCheckpoints(store);
158
+ * checkpoints.setSize(2);
159
+ * console.log(checkpoints.getCheckpointIds());
160
+ * // -> [[], '0', []]
161
+ *
162
+ * store.setCell('pets', 'fido', 'views', 1);
163
+ * checkpoints.addCheckpoint();
164
+ * console.log(checkpoints.getCheckpointIds());
165
+ * // -> [['0'], '1', []]
166
+ *
167
+ * store.setCell('pets', 'fido', 'views', 2);
168
+ * checkpoints.addCheckpoint();
169
+ * console.log(checkpoints.getCheckpointIds());
170
+ * // -> [['0', '1'], '2', []]
171
+ *
172
+ * store.setCell('pets', 'fido', 'views', 3);
173
+ * checkpoints.addCheckpoint();
174
+ * console.log(checkpoints.getCheckpointIds());
175
+ * // -> [['1', '2'], '3', []]
176
+ * ```
177
+ * @category Configuration
178
+ */
179
+ setSize(size: number): Checkpoints;
180
+
181
+ /**
182
+ * The addCheckpoint method records a checkpoint of the Store into the
183
+ * Checkpoints object that can be reverted to in the future.
184
+ *
185
+ * If no changes have been made to the Store since the last time a checkpoint
186
+ * was made, this method will have no effect.
187
+ *
188
+ * The optional `label` parameter can be used to describe the actions that
189
+ * changed the Store before this checkpoint. This can be useful for interfaces
190
+ * that let users 'Undo [last action]'.
191
+ *
192
+ * @param label An optional label to describe the actions leading up to this
193
+ * checkpoint.
194
+ * @returns The Id of the newly-created checkpoint.
195
+ * @example
196
+ * This example creates a Store, adds a Checkpoints object, and adds two
197
+ * checkpoints, one with a label.
198
+ *
199
+ * ```tsx
200
+ * const store = createStore().setTables({pets: {fido: {sold: false}}});
201
+ *
202
+ * const checkpoints = createCheckpoints(store);
203
+ * console.log(checkpoints.getCheckpointIds());
204
+ * // -> [[], '0', []]
205
+ *
206
+ * store.setCell('pets', 'fido', 'species', 'dog');
207
+ * const checkpointId1 = checkpoints.addCheckpoint();
208
+ * console.log(checkpointId1);
209
+ * // -> '1'
210
+ *
211
+ * console.log(checkpoints.getCheckpointIds());
212
+ * // -> [['0'], '1', []]
213
+ *
214
+ * store.setCell('pets', 'fido', 'sold', true);
215
+ * checkpoints.addCheckpoint('sale');
216
+ * console.log(checkpoints.getCheckpointIds());
217
+ * // -> [['0', '1'], '2', []]
218
+ *
219
+ * console.log(checkpoints.getCheckpoint('2'));
220
+ * // -> 'sale'
221
+ * ```
222
+ * @category Setter
223
+ */
224
+ addCheckpoint(label?: string): Id;
225
+
226
+ /**
227
+ * The setCheckpoint method updates the label for a checkpoint in the
228
+ * Checkpoints object after it has been created
229
+ *
230
+ * The `label` parameter can be used to describe the actions that changed the
231
+ * Store before the given checkpoint. This can be useful for interfaces that
232
+ * let users 'Undo [last action]'.
233
+ *
234
+ * Generally you will provide the `label` parameter when the addCheckpoint
235
+ * method is called. Use this setCheckpoint method only when you need to
236
+ * change the label at a later point.
237
+ *
238
+ * You cannot add a label to a checkpoint that does not yet exist.
239
+ *
240
+ * @param checkpointId The Id of the checkpoint to set the label for.
241
+ * @param label A label to describe the actions leading up to this checkpoint
242
+ * or left undefined if you want to clear the current label.
243
+ * @returns A reference to the Checkpoints object.
244
+ * @example
245
+ * This example creates a Store, adds a Checkpoints object, and sets two
246
+ * checkpoints, one with a label, which are both then re-labelled.
247
+ *
248
+ * ```tsx
249
+ * const store = createStore().setTables({pets: {fido: {sold: false}}});
250
+ *
251
+ * const checkpoints = createCheckpoints(store);
252
+ * console.log(checkpoints.getCheckpointIds());
253
+ * // -> [[], '0', []]
254
+ *
255
+ * store.setCell('pets', 'fido', 'species', 'dog');
256
+ * checkpoints.addCheckpoint();
257
+ * store.setCell('pets', 'fido', 'sold', true);
258
+ * checkpoints.addCheckpoint('sale');
259
+ *
260
+ * console.log(checkpoints.getCheckpoint('1'));
261
+ * // -> ''
262
+ * console.log(checkpoints.getCheckpoint('2'));
263
+ * // -> 'sale'
264
+ *
265
+ * checkpoints.setCheckpoint('1', 'identified');
266
+ * checkpoints.setCheckpoint('2', '');
267
+ *
268
+ * console.log(checkpoints.getCheckpoint('1'));
269
+ * // -> 'identified'
270
+ * console.log(checkpoints.getCheckpoint('2'));
271
+ * // -> ''
272
+ *
273
+ * checkpoints.setCheckpoint('3', 'unknown');
274
+ * console.log(checkpoints.getCheckpoint('3'));
275
+ * // -> undefined
276
+ * ```
277
+ * @category Setter
278
+ */
279
+ setCheckpoint(checkpointId: Id, label: string): Checkpoints;
280
+
281
+ /**
282
+ * The getStore method returns a reference to the underlying Store that is
283
+ * backing this Checkpoints object.
284
+ *
285
+ * @returns A reference to the Store.
286
+ * @example
287
+ * This example creates a Checkpoints object against a newly-created Store
288
+ * and then gets its reference in order to update its data and set a
289
+ * checkpoint.
290
+ *
291
+ * ```tsx
292
+ * const checkpoints = createCheckpoints(createStore());
293
+ * checkpoints.getStore().setCell('pets', 'fido', 'species', 'dog');
294
+ * checkpoints.addCheckpoint();
295
+ * console.log(checkpoints.getCheckpointIds());
296
+ * // -> [['0'], '1', []]
297
+ * ```
298
+ * @category Getter
299
+ */
300
+ getStore(): Store;
301
+
302
+ /**
303
+ * The getCheckpointIds method returns an array of the checkpoint Ids being
304
+ * managed by this Checkpoints object.
305
+ *
306
+ * The returned CheckpointIds array contains 'backward' checkpoint Ids, the
307
+ * current checkpoint Id (if present), and the 'forward' checkpointIds.
308
+ * Together, these are sufficient to understand the state of the Checkpoints
309
+ * object and what movement is possible backward or forward through the
310
+ * checkpoint stack.
311
+ *
312
+ * @returns A CheckpointIds array, containing the checkpoint Ids managed by
313
+ * this Checkpoints object.
314
+ * @example
315
+ * This example creates a Store, adds a Checkpoints object, and then gets the
316
+ * Ids of the checkpoints as it sets them and moves around the stack.
317
+ *
318
+ * ```tsx
319
+ * const store = createStore().setTables({pets: {fido: {sold: false}}});
320
+ *
321
+ * const checkpoints = createCheckpoints(store);
322
+ * console.log(checkpoints.getCheckpointIds());
323
+ * // -> [[], '0', []]
324
+ *
325
+ * store.setCell('pets', 'fido', 'sold', true);
326
+ * checkpoints.addCheckpoint('sale');
327
+ * console.log(checkpoints.getCheckpointIds());
328
+ * // -> [['0'], '1', []]
329
+ *
330
+ * checkpoints.goBackward();
331
+ * console.log(checkpoints.getCheckpointIds());
332
+ * // -> [[], '0', ['1']]
333
+ *
334
+ * checkpoints.goForward();
335
+ * console.log(checkpoints.getCheckpointIds());
336
+ * // -> [['0'], '1', []]
337
+ * ```
338
+ * @category Getter
339
+ */
340
+ getCheckpointIds(): CheckpointIds;
341
+
342
+ /**
343
+ * The getCheckpoint method fetches the label for a checkpoint, if it had been
344
+ * provided at the time of the addCheckpoint method or set subsequently with
345
+ * the setCheckpoint method.
346
+ *
347
+ * If the checkpoint has had no label provided, this method will return an
348
+ * empty string.
349
+ *
350
+ * @param checkpointId The Id of the checkpoint to get the label for.
351
+ * @returns A string label for the requested checkpoint, an empty string if it
352
+ * was never set, or `undefined` if the checkpoint does not exist.
353
+ * @example
354
+ * This example creates a Store, adds a Checkpoints object, and sets a
355
+ * checkpoint with a label, before retrieving it again.
356
+ *
357
+ * ```tsx
358
+ * const store = createStore().setTables({pets: {fido: {sold: false}}});
359
+ *
360
+ * const checkpoints = createCheckpoints(store);
361
+ * store.setCell('pets', 'fido', 'sold', true);
362
+ * console.log(checkpoints.addCheckpoint('sale'));
363
+ * // -> '1'
364
+ *
365
+ * console.log(checkpoints.getCheckpoint('1'));
366
+ * // -> 'sale'
367
+ * ```
368
+ * @example
369
+ * This example creates a Store, adds a Checkpoints object, and sets a
370
+ * checkpoint without a label, setting it subsequently. A non-existent
371
+ * checkpoint return an `undefined` label.
372
+ *
373
+ * ```tsx
374
+ * const store = createStore().setTables({pets: {fido: {sold: false}}});
375
+ *
376
+ * const checkpoints = createCheckpoints(store);
377
+ * store.setCell('pets', 'fido', 'sold', true);
378
+ * checkpoints.addCheckpoint();
379
+ * console.log(checkpoints.getCheckpoint('1'));
380
+ * // -> ''
381
+ *
382
+ * checkpoints.setCheckpoint('1', 'sold');
383
+ * console.log(checkpoints.getCheckpoint('1'));
384
+ * // -> 'sold'
385
+ *
386
+ * console.log(checkpoints.getCheckpoint('2'));
387
+ * // -> undefined
388
+ * ```
389
+ * @category Getter
390
+ */
391
+ getCheckpoint(checkpointId: Id): string | undefined;
392
+
393
+ /**
394
+ * The addCheckpointIdsListener method registers a listener function with the
395
+ * Checkpoints object that will be called whenever its set of checkpoints
396
+ * changes.
397
+ *
398
+ * The provided listener is a CheckpointIdsListener function, and will be
399
+ * called with a reference to the Checkpoints object.
400
+ *
401
+ * @param listener The function that will be called whenever the checkpoints
402
+ * change.
403
+ * @returns A unique Id for the listener that can later be used to remove it.
404
+ * @example
405
+ * This example creates a Store, a Checkpoints object, and then registers a
406
+ * listener that responds to any changes to the checkpoints.
407
+ *
408
+ * ```tsx
409
+ * const store = createStore().setTables({pets: {fido: {sold: false}}});
410
+ *
411
+ * const checkpoints = createCheckpoints(store);
412
+ * console.log(checkpoints.getCheckpointIds());
413
+ * // -> [[], '0', []]
414
+ *
415
+ * const listenerId = checkpoints.addCheckpointIdsListener(() => {
416
+ * console.log('Checkpoint Ids changed');
417
+ * console.log(checkpoints.getCheckpointIds());
418
+ * });
419
+ *
420
+ * store.setCell('pets', 'fido', 'species', 'dog');
421
+ * // -> 'Checkpoint Ids changed'
422
+ * // -> [['0'], undefined, []]
423
+ *
424
+ * checkpoints.addCheckpoint();
425
+ * // -> 'Checkpoint Ids changed'
426
+ * // -> [['0'], '1', []]
427
+ *
428
+ * checkpoints.goBackward();
429
+ * // -> 'Checkpoint Ids changed'
430
+ * // -> [[], '0', ['1']]
431
+ *
432
+ * checkpoints.goForward();
433
+ * // -> 'Checkpoint Ids changed'
434
+ * // -> [['0'], '1', []]
435
+ *
436
+ * checkpoints.delListener(listenerId);
437
+ * checkpoints.destroy();
438
+ * ```
439
+ * @category Listener
440
+ */
441
+ addCheckpointIdsListener(listener: CheckpointIdsListener): Id;
442
+
443
+ /**
444
+ * The addCheckpointListener method registers a listener function with the
445
+ * Checkpoints object that will be called whenever the label of a checkpoint
446
+ * changes.
447
+ *
448
+ * You can either listen to a single checkpoint label (by specifying the
449
+ * checkpoint Id as the method's first parameter), or changes to any
450
+ * checkpoint label (by providing a `null` wildcard).
451
+ *
452
+ * The provided listener is a CheckpointListener function, and will be called
453
+ * with a reference to the Checkpoints object, and the Id of the checkpoint
454
+ * whose label changed.
455
+ *
456
+ * @param checkpointId The Id of the checkpoint to listen to, or `null` as a
457
+ * wildcard.
458
+ * @param listener The function that will be called whenever the checkpoint
459
+ * label changes.
460
+ * @returns A unique Id for the listener that can later be used to remove it.
461
+ * @example
462
+ * This example creates a Store, a Checkpoints object, and then registers a
463
+ * listener that responds to any changes to a specific checkpoint label,
464
+ * including when the checkpoint no longer exists.
465
+ *
466
+ * ```tsx
467
+ * const store = createStore().setTables({pets: {fido: {species: 'dog'}}});
468
+ *
469
+ * const checkpoints = createCheckpoints(store);
470
+ * console.log(checkpoints.getCheckpointIds());
471
+ * // -> [[], '0', []]
472
+ *
473
+ * const listenerId = checkpoints.addCheckpointListener('1', () => {
474
+ * console.log('Checkpoint 1 label changed');
475
+ * console.log(checkpoints.getCheckpoint('1'));
476
+ * });
477
+ *
478
+ * store.setCell('pets', 'fido', 'sold', true);
479
+ * checkpoints.addCheckpoint('sale');
480
+ * // -> 'Checkpoint 1 label changed'
481
+ * // -> 'sale'
482
+ *
483
+ * checkpoints.setCheckpoint('1', 'sold');
484
+ * // -> 'Checkpoint 1 label changed'
485
+ * // -> 'sold'
486
+ *
487
+ * checkpoints.setCheckpoint('1', 'sold');
488
+ * // The listener is not called when the label does not change.
489
+ *
490
+ * checkpoints.goTo('0');
491
+ * store.setCell('pets', 'fido', 'sold', false);
492
+ * // -> 'Checkpoint 1 label changed'
493
+ * // -> undefined
494
+ * // The checkpoint no longer exists.
495
+ *
496
+ * checkpoints.delListener(listenerId);
497
+ * checkpoints.destroy();
498
+ * ```
499
+ * @category Listener
500
+ */
501
+ addCheckpointListener(
502
+ checkpointId: IdOrNull,
503
+ listener: CheckpointListener,
504
+ ): Id;
505
+
506
+ /**
507
+ * The delListener method removes a listener that was previously added to the
508
+ * Checkpoints object.
509
+ *
510
+ * Use the Id returned by the addCheckpointIdsListener method. Note that the
511
+ * Checkpoints object may re-use this Id for future listeners added to it.
512
+ *
513
+ * @param listenerId The Id of the listener to remove.
514
+ * @returns A reference to the Checkpoints object.
515
+ * @example
516
+ * This example creates a Store, a Checkpoints object, registers a listener,
517
+ * and then removes it.
518
+ *
519
+ * ```tsx
520
+ * const store = createStore().setTables({pets: {fido: {sold: false}}});
521
+ *
522
+ * const checkpoints = createCheckpoints(store);
523
+ * console.log(checkpoints.getCheckpointIds());
524
+ * // -> [[], '0', []]
525
+ *
526
+ * const listenerId = checkpoints.addCheckpointIdsListener(() => {
527
+ * console.log('checkpoints changed');
528
+ * });
529
+ *
530
+ * store.setCell('pets', 'fido', 'species', 'dog');
531
+ * // -> 'checkpoints changed'
532
+ *
533
+ * checkpoints.addCheckpoint();
534
+ * // -> 'checkpoints changed'
535
+ *
536
+ * checkpoints.delListener(listenerId);
537
+ *
538
+ * store.setCell('pets', 'fido', 'sold', 'true');
539
+ * // -> undefined
540
+ * // The listener is not called.
541
+ * ```
542
+ * @category Listener
543
+ */
544
+ delListener(listenerId: Id): Checkpoints;
545
+
546
+ /**
547
+ * The goBackward method moves the state of the underlying Store back to the
548
+ * previous checkpoint, effectively performing an 'undo' on the Store data.
549
+ *
550
+ * If there is no previous checkpoint to return to, this method has no effect.
551
+ *
552
+ * @returns A reference to the Checkpoints object.
553
+ * @example
554
+ * This example creates a Store, a Checkpoints object, makes a change and then
555
+ * goes backward to the state of the Store before the change.
556
+ *
557
+ * ```tsx
558
+ * const store = createStore().setTables({pets: {fido: {sold: false}}});
559
+ *
560
+ * const checkpoints = createCheckpoints(store);
561
+ * console.log(checkpoints.getCheckpointIds());
562
+ * // -> [[], '0', []]
563
+ *
564
+ * store.setCell('pets', 'fido', 'sold', true);
565
+ * checkpoints.addCheckpoint('sale');
566
+ * console.log(checkpoints.getCheckpointIds());
567
+ * // -> [['0'], '1', []]
568
+ *
569
+ * checkpoints.goBackward();
570
+ * console.log(store.getCell('pets', 'fido', 'sold'));
571
+ * // -> false
572
+ * console.log(checkpoints.getCheckpointIds());
573
+ * // -> [[], '0', ['1']]
574
+ * ```
575
+ */
576
+ goBackward(): Checkpoints;
577
+
578
+ /**
579
+ * The goForward method moves the state of the underlying Store forwards to a
580
+ * future checkpoint, effectively performing an 'redo' on the Store data.
581
+ *
582
+ * If there is no future checkpoint to return to, this method has no effect.
583
+ *
584
+ * Note that if you have previously used the goBackward method to undo
585
+ * changes, the forwards 'redo' stack will only exist while you do not make
586
+ * changes to the Store. In general the goForward method is expected to be
587
+ * used to redo changes that were just undone.
588
+ *
589
+ * @returns A reference to the Checkpoints object.
590
+ * @example
591
+ * This example creates a Store, a Checkpoints object, makes a change and then
592
+ * goes backward to the state of the Store before the change. It then goes
593
+ * forward again to restore the state with the changes.
594
+ *
595
+ * ```tsx
596
+ * const store = createStore().setTables({pets: {fido: {sold: false}}});
597
+ *
598
+ * const checkpoints = createCheckpoints(store);
599
+ * console.log(checkpoints.getCheckpointIds());
600
+ * // -> [[], '0', []]
601
+ *
602
+ * store.setCell('pets', 'fido', 'sold', true);
603
+ * checkpoints.addCheckpoint('sale');
604
+ * console.log(checkpoints.getCheckpointIds());
605
+ * // -> [['0'], '1', []]
606
+ *
607
+ * checkpoints.goBackward();
608
+ * console.log(store.getCell('pets', 'fido', 'sold'));
609
+ * // -> false
610
+ * console.log(checkpoints.getCheckpointIds());
611
+ * // -> [[], '0', ['1']]
612
+ *
613
+ * checkpoints.goForward();
614
+ * console.log(store.getCell('pets', 'fido', 'sold'));
615
+ * // -> true
616
+ * console.log(checkpoints.getCheckpointIds());
617
+ * // -> [['0'], '1', []]
618
+ * ```
619
+ * @example
620
+ * This example creates a Store, a Checkpoints object, makes a change and then
621
+ * goes backward to the state of the Store before the change. It makes a new
622
+ * change, the redo stack disappears, and then the attempt to forward again
623
+ * has no effect.
624
+ *
625
+ * ```tsx
626
+ * const store = createStore().setTables({pets: {fido: {sold: false}}});
627
+ *
628
+ * const checkpoints = createCheckpoints(store);
629
+ * console.log(checkpoints.getCheckpointIds());
630
+ * // -> [[], '0', []]
631
+ *
632
+ * store.setCell('pets', 'fido', 'sold', true);
633
+ * checkpoints.addCheckpoint('sale');
634
+ * console.log(checkpoints.getCheckpointIds());
635
+ * // -> [['0'], '1', []]
636
+ *
637
+ * checkpoints.goBackward();
638
+ * console.log(store.getCell('pets', 'fido', 'sold'));
639
+ * // -> false
640
+ * console.log(checkpoints.getCheckpointIds());
641
+ * // -> [[], '0', ['1']]
642
+ *
643
+ * store.setCell('pets', 'fido', 'color', 'brown');
644
+ * console.log(checkpoints.getCheckpointIds());
645
+ * // -> [['0'], undefined, []]
646
+ *
647
+ * checkpoints.goForward();
648
+ * console.log(store.getCell('pets', 'fido', 'sold'));
649
+ * // -> false
650
+ * console.log(checkpoints.getCheckpointIds());
651
+ * // -> [['0'], undefined, []]
652
+ * // The original change cannot be redone.
653
+ * ```
654
+ */
655
+ goForward(): Checkpoints;
656
+
657
+ /**
658
+ * The goTo method moves the state of the underlying Store backwards or
659
+ * forwards to a specified checkpoint.
660
+ *
661
+ * If there is no checkpoint with the Id specified, this method has no effect.
662
+ *
663
+ * @param checkpointId The Id of the checkpoint to move to.
664
+ * @returns A reference to the Checkpoints object.
665
+ * @example
666
+ * This example creates a Store, a Checkpoints object, makes two changes and
667
+ * then goes directly to the state of the Store before the two changes. It
668
+ * then goes forward again one change, also using the goTo method. Finally it
669
+ * tries to go to a checkpoint that does not exist.
670
+ *
671
+ * ```tsx
672
+ * const store = createStore().setTables({pets: {fido: {sold: false}}});
673
+ *
674
+ * const checkpoints = createCheckpoints(store);
675
+ * console.log(checkpoints.getCheckpointIds());
676
+ * // -> [[], '0', []]
677
+ *
678
+ * store.setCell('pets', 'fido', 'color', 'brown');
679
+ * checkpoints.addCheckpoint('identification');
680
+ * store.setCell('pets', 'fido', 'sold', true);
681
+ * checkpoints.addCheckpoint('sale');
682
+ * console.log(checkpoints.getCheckpointIds());
683
+ * // -> [['0', '1'], '2', []]
684
+ *
685
+ * checkpoints.goTo('0');
686
+ * console.log(store.getTables());
687
+ * // -> {pets: {fido: {sold: false}}}
688
+ * console.log(checkpoints.getCheckpointIds());
689
+ * // -> [[], '0', ['1', '2']]
690
+ *
691
+ * checkpoints.goTo('1');
692
+ * console.log(store.getTables());
693
+ * // -> {pets: {fido: {sold: false, color: 'brown'}}}
694
+ * console.log(checkpoints.getCheckpointIds());
695
+ * // -> [['0'], '1', ['2']]
696
+ *
697
+ * checkpoints.goTo('3');
698
+ * console.log(store.getTables());
699
+ * // -> {pets: {fido: {sold: false, color: 'brown'}}}
700
+ * console.log(checkpoints.getCheckpointIds());
701
+ * // -> [['0'], '1', ['2']]
702
+ * ```
703
+ */
704
+ goTo(checkpointId: Id): Checkpoints;
705
+
706
+ /**
707
+ * The clear method resets this Checkpoints object to its initial state,
708
+ * removing all the checkpoints it has been managing.
709
+ *
710
+ * Obviously this method should be used with caution as it destroys the
711
+ * ability to undo recent changes to the Store (though of course the Store
712
+ * itself is not reset by this method).
713
+ *
714
+ * This method can be useful when a Store is being loaded via a Persister
715
+ * asynchronously after the Checkpoints object has been attached, and you
716
+ * don't want users to be able to undo the initial load of the data. In this
717
+ * you could call the clear method immediately after the initial load so that
718
+ * that is the baseline from which all subsequent changes are tracked.
719
+ *
720
+ * If you are listening to
721
+ *
722
+ * @returns A reference to the Checkpoints object.
723
+ * @example
724
+ * This example creates a Store, a Checkpoints object, adds a listener, makes
725
+ * a change and then clears the checkpoints.
726
+ *
727
+ * ```tsx
728
+ * const store = createStore().setTables({pets: {fido: {sold: false}}});
729
+ *
730
+ * const checkpoints = createCheckpoints(store);
731
+ * console.log(checkpoints.getCheckpointIds());
732
+ * // -> [[], '0', []]
733
+ *
734
+ * const listenerId = checkpoints.addCheckpointIdsListener(() => {
735
+ * console.log('checkpoints changed');
736
+ * });
737
+ *
738
+ * store.setCell('pets', 'fido', 'color', 'brown');
739
+ * // -> 'checkpoints changed'
740
+ * checkpoints.addCheckpoint();
741
+ * // -> 'checkpoints changed'
742
+ * store.setCell('pets', 'fido', 'sold', true);
743
+ * // -> 'checkpoints changed'
744
+ * checkpoints.addCheckpoint();
745
+ * // -> 'checkpoints changed'
746
+ *
747
+ * console.log(store.getTables());
748
+ * // -> {pets: {fido: {sold: true, color: 'brown'}}}
749
+ * console.log(checkpoints.getCheckpointIds());
750
+ * // -> [['0', '1'], '2', []]
751
+ *
752
+ * checkpoints.clear();
753
+ * // -> 'checkpoints changed'
754
+ *
755
+ * console.log(store.getTables());
756
+ * // -> {pets: {fido: {sold: true, color: 'brown'}}}
757
+ * console.log(checkpoints.getCheckpointIds());
758
+ * // -> [[], '0', []]
759
+ * ```
760
+ * @category Lifecycle
761
+ */
762
+ clear(): Checkpoints;
763
+
764
+ /**
765
+ * The destroy method should be called when this Checkpoints object is no
766
+ * longer used.
767
+ *
768
+ * This guarantees that all of the listeners that the object registered with
769
+ * the underlying Store are removed and it can be correctly garbage collected.
770
+ *
771
+ * @example
772
+ * This example creates a Store, adds a Checkpoints object (that registers a
773
+ * CellListener with the underlying Store), and then destroys it again,
774
+ * removing the listener.
775
+ *
776
+ * ```tsx
777
+ * const store = createStore().setTables({pets: {fido: {sold: false}}});
778
+ *
779
+ * const checkpoints = createCheckpoints(store);
780
+ * console.log(store.getListenerStats().cell);
781
+ * // -> 1
782
+ *
783
+ * checkpoints.destroy();
784
+ *
785
+ * console.log(store.getListenerStats().cell);
786
+ * // -> 0
787
+ * ```
788
+ * @category Lifecycle
789
+ */
790
+ destroy(): void;
791
+
792
+ /**
793
+ * The getListenerStats method provides a set of statistics about the
794
+ * listeners registered with the Checkpoints object, and is used for debugging
795
+ * purposes.
796
+ *
797
+ * The CheckpointsListenerStats object contains a breakdown of the different
798
+ * types of listener.
799
+ *
800
+ * The statistics are only populated in a debug build: production builds
801
+ * return an empty object. The method is intended to be used during
802
+ * development to ensure your application is not leaking listener
803
+ * registrations, for example.
804
+ *
805
+ * @returns A CheckpointsListenerStats object containing Checkpoints listener
806
+ * statistics.
807
+ * @example
808
+ * This example gets the listener statistics of a Checkpoints object.
809
+ *
810
+ * ```tsx
811
+ * const store = createStore();
812
+ * const checkpoints = createCheckpoints(store);
813
+ * checkpoints.addCheckpointIdsListener(() => {
814
+ * console.log('Checkpoint Ids changed');
815
+ * });
816
+ * checkpoints.addCheckpointListener(null, () => {
817
+ * console.log('Checkpoint label changed');
818
+ * });
819
+ *
820
+ * console.log(checkpoints.getListenerStats());
821
+ * // -> {checkpointIds: 1, checkpoint: 1}
822
+ * ```
823
+ * @category Development
824
+ */
825
+ getListenerStats(): CheckpointsListenerStats;
826
+ }
827
+
828
+ /**
829
+ * The createCheckpoints function creates a Checkpoints object, and is the main
830
+ * entry point into the checkpoints module.
831
+ *
832
+ * It is trivially simple.
833
+ *
834
+ * A given Store can only have one Checkpoints object associated with it. If you
835
+ * call this function twice on the same Store, your second call will return a
836
+ * reference to the Checkpoints object created by the first.
837
+ *
838
+ * @param store The Store for which to set Checkpoints.
839
+ * @returns A reference to the new Checkpoints object.
840
+ * @example
841
+ * This example creates a Checkpoints object.
842
+ *
843
+ * ```tsx
844
+ * const store = createStore();
845
+ * const checkpoints = createCheckpoints(store);
846
+ * console.log(checkpoints.getCheckpointIds());
847
+ * // -> [[], '0', []]
848
+ * ```
849
+ * @example
850
+ * This example creates a Checkpoints object, and calls the method a second
851
+ * time for the same Store to return the same object.
852
+ *
853
+ * ```tsx
854
+ * const store = createStore();
855
+ * const checkpoints1 = createCheckpoints(store);
856
+ * const checkpoints2 = createCheckpoints(store);
857
+ * console.log(checkpoints1 === checkpoints2);
858
+ * // -> true
859
+ * ```
860
+ */
861
+ export function createCheckpoints(store: Store): Checkpoints;