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,521 @@
1
+ /**
2
+ * The persisters module of the TinyBase project provides a simple framework
3
+ * for saving and loading Store data, to and from different destinations, or
4
+ * underlying storage types.
5
+ *
6
+ * Several entry points are provided, each of which returns a new Persister
7
+ * object that can load and save a Store:
8
+ *
9
+ * - The createSessionPersister function returns a Persister that uses the
10
+ * browser's session storage.
11
+ * - The createLocalPersister function returns a Persister that uses the
12
+ * browser's local storage.
13
+ * - The createRemotePersister function returns a Persister that uses a remote
14
+ * endpoint
15
+ * - The createFilePersister function returns a Persister that uses a local file
16
+ * (in an appropriate environment)
17
+ *
18
+ * Since persistence requirements can be different for every app, the
19
+ * createCustomPersister function can also be used to easily create a fully
20
+ * customized way to save and load Store data.
21
+ *
22
+ * @packageDocumentation
23
+ * @module persisters
24
+ */
25
+
26
+ import {Store, Tables} from './store.d';
27
+ import {Callback} from './common';
28
+
29
+ /**
30
+ * The PersisterStats type describes the number of times a Persister object has
31
+ * loaded or saved data.
32
+ *
33
+ * A PersisterStats object is returned from the getStats method, and is only
34
+ * populated in a debug build.
35
+ *
36
+ * @category Development
37
+ */
38
+ export type PersisterStats = {
39
+ loads?: number;
40
+ saves?: number;
41
+ };
42
+
43
+ /**
44
+ * A Persister object lets you save and load Store data to and from different
45
+ * locations, or underlying storage types.
46
+ *
47
+ * This is useful for preserving Store data between browser sessions or reloads,
48
+ * saving or loading browser state to or from a server, or saving Store data to
49
+ * disk in a environment with filesystem access.
50
+ *
51
+ * Creating a Persister depends on the choice of underlying storage where the
52
+ * data is to be stored. Options include the createSessionPersister function,
53
+ * the createLocalPersister, the createRemotePersister function, and the
54
+ * createFilePersister function. The createCustomPersister function can also be
55
+ * used to easily create a fully customized way to save and load Store data.
56
+ *
57
+ * A Persister lets you explicit save or load data, with the save method and the
58
+ * load method respectively. These methods are both asynchronous (since the
59
+ * underlying data storage may also be) and return promises. As a result you
60
+ * should use the `await` keyword to call them in a way that guarantees
61
+ * subsequent execution order.
62
+ *
63
+ * When you don't want to deal with explicit persistence operations, a Persister
64
+ * object also provides automatic saving and loading. Automatic saving listens
65
+ * for changes to the Store and persists the data immediately. Automatic loading
66
+ * listens (or polls) for changes to the persisted data and reflects those
67
+ * changes in the Store.
68
+ *
69
+ * You can start automatic saving or loading with the startAutoSave method and
70
+ * startAutoLoad method. Both are asynchronous since they will do an immediate
71
+ * save and load before starting to listen for subsequent changes. You can stop
72
+ * the behavior with the stopAutoSave method and stopAutoLoad method (which are
73
+ * synchronous).
74
+ *
75
+ * You may often want to have both automatic saving and loading of a Store so
76
+ * that changes are constantly synchronized (allowing basic state preservation
77
+ * between browser tabs, for example). The framework has some basic provisions
78
+ * to prevent race conditions - for example it will not attempt to save data if
79
+ * it is currently loading it and vice-versa.
80
+ *
81
+ * Be aware, however, that the default implementations do not provide complex
82
+ * synchronization heuristics and you should comprehensively test your
83
+ * persistence strategy to understand the opportunity for data loss (in the case
84
+ * of trying to save data to a server under poor network conditions, for
85
+ * example).
86
+ *
87
+ * @example
88
+ * This example creates a Store, persists it to the browser's session storage as
89
+ * a JSON string, changes the persisted data, updates the Store from it, and
90
+ * finally destroys the Persister again.
91
+ *
92
+ * ```tsx
93
+ * const store = createStore().setTables({pets: {fido: {species: 'dog'}}});
94
+ * const persister = createSessionPersister(store, 'pets');
95
+ *
96
+ * await persister.save();
97
+ * console.log(sessionStorage.getItem('pets'));
98
+ * // -> '{"pets":{"fido":{"species":"dog"}}}'
99
+ *
100
+ * sessionStorage.setItem('pets', '{"pets":{"toto":{"species":"dog"}}}');
101
+ * await persister.load();
102
+ * console.log(store.getTables());
103
+ * // -> {pets: {toto: {species: 'dog'}}}
104
+ *
105
+ * persister.destroy();
106
+ * sessionStorage.clear();
107
+ * ```
108
+ * @example
109
+ * This example creates a Store, and automatically saves and loads it to the
110
+ * browser's session storage as a JSON string. Changes to the Store data, or the
111
+ * persisted data (implicitly firing a StorageEvent), are reflected accordingly.
112
+ *
113
+ * ```tsx
114
+ * const store = createStore();
115
+ * const persister = createSessionPersister(store, 'pets');
116
+ *
117
+ * await persister.startAutoLoad({pets: {fido: {species: 'dog'}}});
118
+ * await persister.startAutoSave();
119
+ *
120
+ * store.setTables({pets: {felix: {species: 'cat'}}});
121
+ * // ...
122
+ * console.log(sessionStorage.getItem('pets'));
123
+ * // -> '{"pets":{"felix":{"species":"cat"}}}'
124
+ *
125
+ * // In another browser tab:
126
+ * sessionStorage.setItem('pets', '{"pets":{"toto":{"species":"dog"}}}');
127
+ * // -> StorageEvent('storage', {storageArea: sessionStorage, key: 'pets'})
128
+ *
129
+ * // ...
130
+ * console.log(store.getTables());
131
+ * // -> {pets: {toto: {species: 'dog'}}}
132
+ *
133
+ * persister.destroy();
134
+ * sessionStorage.clear();
135
+ * ```
136
+ */
137
+ export interface Persister {
138
+ /**
139
+ * The load method gets persisted data from storage, and loads it into the
140
+ * Store with which the Persister is associated, once.
141
+ *
142
+ * The optional parameter allows you to specify what the initial Tables object
143
+ * for the Store will be if there is nothing currently persisted. Using this
144
+ * instead of the `initialTables` parameter in the regular createStore
145
+ * function allows you to easily instantiate a Store whether it's loading from
146
+ * previously persisted storage or being run for the first time.
147
+ *
148
+ * This method is asynchronous because the persisted data may be on a remote
149
+ * machine or a filesystem. Even for those storage types that are synchronous
150
+ * (like browser storage) it is still recommended that you `await` calls to
151
+ * this method or handle the return type natively as a Promise.
152
+ *
153
+ * @param initialTables An optional Tables object used when the underlying
154
+ * storage has not previously been populated.
155
+ * @returns A Promise containing a reference to the Persister object.
156
+ * @example
157
+ * This example creates an empty Store, and loads data into it from the
158
+ * browser's session storage, which for the purposes of this example has been
159
+ * previously populated.
160
+ *
161
+ * ```tsx
162
+ * sessionStorage.setItem('pets', '{"pets":{"fido":{"species":"dog"}}}');
163
+ *
164
+ * const store = createStore();
165
+ * const persister = createSessionPersister(store, 'pets');
166
+ *
167
+ * await persister.load();
168
+ * console.log(store.getTables());
169
+ * // -> {pets: {fido: {species: 'dog'}}}
170
+ *
171
+ * sessionStorage.clear();
172
+ * ```
173
+ * @example
174
+ * This example creates an empty Store, and loads data into it from the
175
+ * browser's session storage, which is at first empty, so the optional
176
+ * parameter is used. The second time the load method is called, data has
177
+ * previously been persisted and instead, that is loaded.
178
+ *
179
+ * ```tsx
180
+ * const store = createStore();
181
+ * const persister = createSessionPersister(store, 'pets');
182
+ *
183
+ * await persister.load({pets: {fido: {species: 'dog'}}});
184
+ * console.log(store.getTables());
185
+ * // -> {pets: {fido: {species: 'dog'}}}
186
+ *
187
+ * sessionStorage.setItem('pets', '{"pets":{"toto":{"species":"dog"}}}');
188
+ * await persister.load({pets: {fido: {species: 'dog'}}});
189
+ * console.log(store.getTables());
190
+ * // -> {pets: {toto: {species: 'dog'}}}
191
+ *
192
+ * sessionStorage.clear();
193
+ * ```
194
+ * @category Load
195
+ */
196
+ load(initialTables?: Tables): Promise<Persister>;
197
+
198
+ /**
199
+ * The startAutoLoad method gets persisted data from storage, and loads it
200
+ * into the Store with which the Persister is associated, once, and then
201
+ * continuously.
202
+ *
203
+ * The optional parameter allows you to specify what the initial Tables object
204
+ * for the Store will be if there is nothing at first persisted. Using this
205
+ * instead of the `initialTables` parameter in the regular createStore
206
+ * function allows you to easily instantiate a Store whether it's loading from
207
+ * previously persisted storage or being run for the first time.
208
+ *
209
+ * This method first runs a single call to the load method to ensure the data
210
+ * is in sync with the persisted storage. It then continues to watch for
211
+ * changes to the underlying data (either through events or polling, depending
212
+ * on the storage type), automatically loading the data into the Store.
213
+ *
214
+ * This method is asynchronous because it starts by making a single call to
215
+ * the asynchronous load method. Even for those storage types that are
216
+ * synchronous (like browser storage) it is still recommended that you `await`
217
+ * calls to this method or handle the return type natively as a Promise.
218
+ *
219
+ * @param initialTables An optional Tables object used when the underlying
220
+ * storage has not previously been populated.
221
+ * @returns A Promise containing a reference to the Persister object.
222
+ * @example
223
+ * This example creates an empty Store, and loads data into it from the
224
+ * browser's session storage, which at first is empty (so the `initialTables`
225
+ * parameter is used). Subsequent changes to the underlying storage are then
226
+ * reflected in the Store (in this case through detection of StorageEvents
227
+ * from session storage changes made in another browser tab).
228
+ *
229
+ * ```tsx
230
+ * const store = createStore();
231
+ * const persister = createSessionPersister(store, 'pets');
232
+ *
233
+ * await persister.startAutoLoad({pets: {fido: {species: 'dog'}}});
234
+ * console.log(store.getTables());
235
+ * // -> {pets: {fido: {species: 'dog'}}}
236
+ *
237
+ * // In another browser tab:
238
+ * sessionStorage.setItem('pets', '{"pets":{"toto":{"species":"dog"}}}');
239
+ * // -> StorageEvent('storage', {storageArea: sessionStorage, key: 'pets'})
240
+ *
241
+ * // ...
242
+ * console.log(store.getTables());
243
+ * // -> {pets: {toto: {species: 'dog'}}}
244
+ *
245
+ * sessionStorage.clear();
246
+ * ```
247
+ * @category Load
248
+ */
249
+ startAutoLoad(initialTables?: Tables): Promise<Persister>;
250
+
251
+ /**
252
+ * The stopAutoLoad method stops the automatic loading of data from storage
253
+ * previously started with the startAutoLoad method.
254
+ *
255
+ * If the Persister is not currently set to automatically load, this method
256
+ * has no effect.
257
+ *
258
+ * @returns A reference to the Persister object.
259
+ * @example
260
+ * This example creates an empty Store, and starts automatically loading data
261
+ * into it from the browser's session storage. Once the automatic loading is
262
+ * stopped, subsequent changes are not reflected in the Store.
263
+ *
264
+ * ```tsx
265
+ * const store = createStore();
266
+ * const persister = createSessionPersister(store, 'pets');
267
+ * await persister.startAutoLoad();
268
+ *
269
+ * // In another browser tab:
270
+ * sessionStorage.setItem('pets', '{"pets":{"toto":{"species":"dog"}}}');
271
+ * // -> StorageEvent('storage', {storageArea: sessionStorage, key: 'pets'})
272
+ * // ...
273
+ * console.log(store.getTables());
274
+ * // -> {pets: {toto: {species: 'dog'}}}
275
+ *
276
+ * persister.stopAutoLoad();
277
+ *
278
+ * // In another browser tab:
279
+ * sessionStorage.setItem('pets', '{"pets":{"felix":{"species":"cat"}}}');
280
+ * // -> StorageEvent('storage', {storageArea: sessionStorage, key: 'pets'})
281
+ * // ...
282
+ * console.log(store.getTables());
283
+ * // -> {pets: {toto: {species: 'dog'}}}
284
+ * // Storage change has not been automatically loaded.
285
+ *
286
+ * sessionStorage.clear();
287
+ * ```
288
+ * @category Load
289
+ */
290
+ stopAutoLoad(): Persister;
291
+
292
+ /**
293
+ * The save method takes data from the Store with which the Persister is
294
+ * associated and persists it into storage, once.
295
+ *
296
+ * This method is asynchronous because the persisted data may be on a remote
297
+ * machine or a filesystem. Even for those storage types that are synchronous
298
+ * (like browser storage) it is still recommended that you `await` calls to
299
+ * this method or handle the return type natively as a Promise.
300
+ *
301
+ * @returns A Promise containing a reference to the Persister object.
302
+ * @example
303
+ * This example creates a Store with some data, and saves into the browser's
304
+ * session storage.
305
+ *
306
+ * ```tsx
307
+ * const store = createStore().setTables({pets: {fido: {species: 'dog'}}});
308
+ * const persister = createSessionPersister(store, 'pets');
309
+ *
310
+ * await persister.save();
311
+ * console.log(sessionStorage.getItem('pets'));
312
+ * // -> '{"pets":{"fido":{"species":"dog"}}}'
313
+ *
314
+ * persister.destroy();
315
+ * sessionStorage.clear();
316
+ * ```
317
+ */
318
+ save(): Promise<Persister>;
319
+
320
+ /**
321
+ * The save method takes data from the Store with which the Persister is
322
+ * associated and persists it into storage, once, and then continuously.
323
+ *
324
+ * This method first runs a single call to the save method to ensure the data
325
+ * is in sync with the persisted storage. It then continues to watch for
326
+ * changes to the Store, automatically saving the data to storage.
327
+ *
328
+ * This method is asynchronous because it starts by making a single call to
329
+ * the asynchronous save method. Even for those storage types that are
330
+ * synchronous (like browser storage) it is still recommended that you `await`
331
+ * calls to this method or handle the return type natively as a Promise.
332
+ *
333
+ * @returns A Promise containing a reference to the Persister object.
334
+ * @example
335
+ * This example creates a Store with some data, and saves into the browser's
336
+ * session storage. Subsequent changes to the Store are then automatically
337
+ * saved to the underlying storage.
338
+ *
339
+ * ```tsx
340
+ * const store = createStore().setTables({pets: {fido: {species: 'dog'}}});
341
+ * const persister = createSessionPersister(store, 'pets');
342
+ *
343
+ * await persister.startAutoSave();
344
+ * console.log(sessionStorage.getItem('pets'));
345
+ * // -> '{"pets":{"fido":{"species":"dog"}}}'
346
+ *
347
+ * store.setTables({pets: {toto: {species: 'dog'}}});
348
+ * // ...
349
+ * console.log(sessionStorage.getItem('pets'));
350
+ * // -> '{"pets":{"toto":{"species":"dog"}}}'
351
+ *
352
+ * sessionStorage.clear();
353
+ * ```
354
+ */
355
+ startAutoSave(): Promise<Persister>;
356
+
357
+ /**
358
+ * The stopAutoSave method stops the automatic save of data to storage
359
+ * previously started with the startAutoSave method.
360
+ *
361
+ * If the Persister is not currently set to automatically save, this method
362
+ * has no effect.
363
+ *
364
+ * @returns A reference to the Persister object.
365
+ * @example
366
+ * This example creates a Store with some data, and saves into the browser's
367
+ * session storage. Subsequent changes to the Store are then automatically
368
+ * saved to the underlying storage. Once the automatic saving is
369
+ * stopped, subsequent changes are not reflected.
370
+ *
371
+ * ```tsx
372
+ * const store = createStore().setTables({pets: {fido: {species: 'dog'}}});
373
+ * const persister = createSessionPersister(store, 'pets');
374
+ * await persister.startAutoSave();
375
+ *
376
+ * store.setTables({pets: {toto: {species: 'dog'}}});
377
+ * // ...
378
+ * console.log(sessionStorage.getItem('pets'));
379
+ * // -> '{"pets":{"toto":{"species":"dog"}}}'
380
+ *
381
+ * persister.stopAutoSave();
382
+ *
383
+ * store.setTables({pets: {felix: {species: 'cat'}}});
384
+ * // ...
385
+ * console.log(sessionStorage.getItem('pets'));
386
+ * // -> '{"pets":{"toto":{"species":"dog"}}}'
387
+ * // Store change has not been automatically saved.
388
+ *
389
+ * sessionStorage.clear();
390
+ * ```
391
+ * @category Save
392
+ */
393
+ stopAutoSave(): Persister;
394
+
395
+ /**
396
+ * The getStore method returns a reference to the underlying Store that is
397
+ * backing this Persister object.
398
+ *
399
+ * @returns A reference to the Store.
400
+ * @example
401
+ * This example creates a Persister object against a newly-created Store and
402
+ * then gets its reference in order to update its data.
403
+ *
404
+ * ```tsx
405
+ * const persister = createSessionPersister(createStore(), 'pets');
406
+ * await persister.startAutoSave();
407
+ *
408
+ * persister.getStore().setTables({pets: {fido: {species: 'dog'}}});
409
+ * // ...
410
+ * console.log(sessionStorage.getItem('pets'));
411
+ * // -> '{"pets":{"fido":{"species":"dog"}}}'
412
+ *
413
+ * sessionStorage.clear();
414
+ * ```
415
+ * @category Getter
416
+ */
417
+ getStore(): Store;
418
+
419
+ /**
420
+ * The destroy method should be called when this Persister object is no longer
421
+ * used.
422
+ *
423
+ * This guarantees that all of the listeners that the object registered with
424
+ * the underlying Store and storage are removed and it can be correctly
425
+ * garbage collected. It is equivalent to running the stopAutoLoad method and
426
+ * the stopAutoSave method in succession.
427
+ *
428
+ * @example
429
+ * This example creates a Store, associates a Persister object with it (that
430
+ * registers a TablesListener with the underlying Store), and then destroys it
431
+ * again, removing the listener.
432
+ *
433
+ * ```tsx
434
+ * const store = createStore();
435
+ * const persister = createSessionPersister(store, 'pets');
436
+ * await persister.startAutoSave();
437
+ *
438
+ * console.log(store.getListenerStats().tables);
439
+ * // -> 1
440
+ *
441
+ * persister.destroy();
442
+ *
443
+ * console.log(store.getListenerStats().tables);
444
+ * // -> 0
445
+ * ```
446
+ * @category Lifecycle
447
+ */
448
+ destroy(): Persister;
449
+
450
+ /**
451
+ * The getStats method provides a set of statistics about the Persister, and
452
+ * is used for debugging purposes.
453
+ *
454
+ * The PersisterStats object contains a count of the number of times the
455
+ * Persister has loaded and saved data.
456
+ *
457
+ * The statistics are only populated in a debug build: production builds
458
+ * return an empty object. The method is intended to be used during
459
+ * development to ensure your persistence layer is acting as expected, for
460
+ * example.
461
+ *
462
+ * @returns A PersisterStats object containing Persister load and save
463
+ * statistics.
464
+ * @example
465
+ * This example gets the load and save statistics of a Persister object.
466
+ * Remember that the startAutoLoad method invokes an explicit load when it
467
+ * starts, and the startAutoSave method invokes an explicit save when it
468
+ * starts - so those numbers are included in addition to the loads and saves
469
+ * invoked by changes to the Store and to the underlying storage.
470
+ *
471
+ * ```tsx
472
+ * const store = createStore();
473
+ * const persister = createSessionPersister(store, 'pets');
474
+ *
475
+ * await persister.startAutoLoad({pets: {fido: {species: 'dog'}}});
476
+ * await persister.startAutoSave();
477
+ *
478
+ * store.setTables({pets: {felix: {species: 'cat'}}});
479
+ * // ...
480
+ *
481
+ * sessionStorage.setItem('pets', '{"pets":{"toto":{"species":"dog"}}}');
482
+ * // -> StorageEvent('storage', {storageArea: sessionStorage, key: 'pets'})
483
+ * // ...
484
+ *
485
+ * console.log(persister.getStats());
486
+ * // -> {loads: 2, saves: 2}
487
+ *
488
+ * persister.destroy();
489
+ * sessionStorage.clear();
490
+ * ```
491
+ * @category Development
492
+ */
493
+ getStats(): PersisterStats;
494
+ }
495
+
496
+ export function createSessionPersister(
497
+ store: Store,
498
+ storageName: string,
499
+ ): Persister;
500
+
501
+ export function createLocalPersister(
502
+ store: Store,
503
+ storageName: string,
504
+ ): Persister;
505
+
506
+ export function createRemotePersister(
507
+ store: Store,
508
+ loadUrl: string,
509
+ saveUrl: string,
510
+ autoLoadIntervalSeconds: number,
511
+ ): Persister;
512
+
513
+ export function createFilePersister(store: Store, filePath: string): Persister;
514
+
515
+ export function createCustomPersister(
516
+ store: Store,
517
+ getPersisted: () => Promise<string | null | undefined>,
518
+ setPersisted: (json: string) => Promise<void>,
519
+ startListeningToPersisted: (didChange: Callback) => void,
520
+ stopListeningToPersisted: Callback,
521
+ ): Persister;