tinybase 6.6.1 → 6.7.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.
@@ -13,6 +13,7 @@
13
13
  * |-|-|-|-|
14
14
  * |SessionPersister|Browser session storage|Yes|Yes
15
15
  * |LocalPersister|Browser local storage|Yes|Yes
16
+ * |OpfsPersister|Browser origin private file system (OPFS)|Yes|Yes
16
17
  * |FilePersister|Local file (where possible)|Yes|Yes
17
18
  * |IndexedDbPersister|Browser IndexedDB|Yes|No
18
19
  * |RemotePersister|Remote server|Yes|No
@@ -1,14 +1,17 @@
1
1
  /**
2
2
  * The persister-browser module of the TinyBase project lets you save and load
3
- * Store data to and from browser storage.
3
+ * Store data to and from browser storage, including the origin private file
4
+ * system (OPFS).
4
5
  *
5
- * Two entry points are provided, each of which returns a new Persister object
6
+ * Three entry points are provided, each of which returns a new Persister object
6
7
  * that can load and save a Store:
7
8
  *
8
9
  * - The createSessionPersister function returns a Persister that uses the
9
10
  * browser's session storage.
10
11
  * - The createLocalPersister function returns a Persister that uses the
11
12
  * browser's local storage.
13
+ * - The createOpfsPersister function returns a Persister that uses a file in
14
+ * an origin private file system (OPFS).
12
15
  * @see Persistence guides
13
16
  * @packageDocumentation
14
17
  * @module persister-browser
@@ -185,3 +188,92 @@ export function createLocalPersister(
185
188
  storageName: string,
186
189
  onIgnoredError?: (error: any) => void,
187
190
  ): LocalPersister;
191
+
192
+ /**
193
+ * The OpfsPersister interface represents a Persister that lets you save and
194
+ * load Store data to and from a file in an origin private file system (OPFS).
195
+ *
196
+ * You should use the createOpfsPersister function to create an OpfsPersister
197
+ * object.
198
+ *
199
+ * It is a minor extension to the Persister interface and simply provides an
200
+ * extra getHandle method for accessing the file the Store is being
201
+ * persisted to.
202
+ * @category Persister
203
+ * @since v6.7.0
204
+ */
205
+ export interface OpfsPersister
206
+ extends Persister<Persists.StoreOrMergeableStore> {
207
+ /**
208
+ * The getHandle method returns the handle of the file the Store is being
209
+ * persisted to.
210
+ * @returns The handle of the file.
211
+ * @example
212
+ * This example creates a Persister object against a newly-created Store and
213
+ * then gets the file handle back out again.
214
+ *
215
+ * ```js
216
+ * import {createStore} from 'tinybase';
217
+ * import {createOpfsPersister} from 'tinybase/persisters/persister-browser';
218
+ *
219
+ * const opfs = await navigator.storage.getDirectory();
220
+ * const handle = await opfs.getFileHandle('tinybase.json', {create: true});
221
+ *
222
+ * const store = createStore().setTables({pets: {fido: {species: 'dog'}}});
223
+ * const persister = createOpfsPersister(store, handle);
224
+ *
225
+ * console.log(persister.getHandle().name);
226
+ * // -> 'tinybase.json'
227
+ *
228
+ * await persister.destroy();
229
+ * ```
230
+ * @category Getter
231
+ * @since v6.7.0
232
+ */
233
+ getHandle(): FileSystemFileHandle;
234
+ }
235
+
236
+ /**
237
+ * The createOpfsPersister function creates an OpfsPersister object that can
238
+ * persist the Store to a file in an origin private file system (OPFS).
239
+ *
240
+ * An OpfsPersister supports both regular Store and MergeableStore objects.
241
+ *
242
+ * As well as providing a reference to the Store to persist, you must provide a
243
+ * `handle` parameter which identifies an existing OPFS file to persist it to.
244
+ * @param store The Store or MergeableStore to persist.
245
+ * @param handle The handle of an existing OPFS file to persist the Store to.
246
+ * @param onIgnoredError An optional handler for the errors that the Persister
247
+ * would otherwise ignore when trying to save or load data. This is suitable for
248
+ * debugging persistence issues in a development environment.
249
+ * @returns A reference to the new OpfsPersister object.
250
+ * @example
251
+ * This example creates an OpfsPersister object and persists the Store to a
252
+ * local file.
253
+ *
254
+ * ```js
255
+ * import {createStore} from 'tinybase';
256
+ * import {createOpfsPersister} from 'tinybase/persisters/persister-browser';
257
+ *
258
+ * const opfs = await navigator.storage.getDirectory();
259
+ * const handle = await opfs.getFileHandle('tinybase.json', {create: true});
260
+ *
261
+ * const store = createStore().setTables({pets: {fido: {species: 'dog'}}});
262
+ * const persister = createOpfsPersister(store, handle);
263
+ *
264
+ * await persister.save();
265
+ * // Store JSON will be saved to the file.
266
+ *
267
+ * await persister.load();
268
+ * // Store JSON will be loaded from the file.
269
+ *
270
+ * await persister.destroy();
271
+ * ```
272
+ * @category Creation
273
+ * @since v6.7.0
274
+ */
275
+ export function createOpfsPersister(
276
+ store: Store | MergeableStore,
277
+ handle: FileSystemFileHandle,
278
+ onIgnoredError?: (error: any) => void,
279
+ ): OpfsPersister;
@@ -1,14 +1,17 @@
1
1
  /**
2
2
  * The persister-browser module of the TinyBase project lets you save and load
3
- * Store data to and from browser storage.
3
+ * Store data to and from browser storage, including the origin private file
4
+ * system (OPFS).
4
5
  *
5
- * Two entry points are provided, each of which returns a new Persister object
6
+ * Three entry points are provided, each of which returns a new Persister object
6
7
  * that can load and save a Store:
7
8
  *
8
9
  * - The createSessionPersister function returns a Persister that uses the
9
10
  * browser's session storage.
10
11
  * - The createLocalPersister function returns a Persister that uses the
11
12
  * browser's local storage.
13
+ * - The createOpfsPersister function returns a Persister that uses a file in
14
+ * an origin private file system (OPFS).
12
15
  * @see Persistence guides
13
16
  * @packageDocumentation
14
17
  * @module persister-browser
@@ -103,6 +106,50 @@ export interface LocalPersister<Schemas extends OptionalSchemas>
103
106
  getStorageName(): string;
104
107
  }
105
108
 
109
+ /**
110
+ * The OpfsPersister interface represents a Persister that lets you save and
111
+ * load Store data to and from a file in an origin private file system (OPFS).
112
+ *
113
+ * You should use the createOpfsPersister function to create an OpfsPersister
114
+ * object.
115
+ *
116
+ * It is a minor extension to the Persister interface and simply provides an
117
+ * extra getHandle method for accessing the file the Store is being
118
+ * persisted to.
119
+ * @category Persister
120
+ * @since v6.7.0
121
+ */
122
+ export interface OpfsPersister<Schemas extends OptionalSchemas>
123
+ extends Persister<Schemas, Persists.StoreOrMergeableStore> {
124
+ /**
125
+ * The getHandle method returns the handle of the file the Store is being
126
+ * persisted to.
127
+ * @returns The handle of the file.
128
+ * @example
129
+ * This example creates a Persister object against a newly-created Store and
130
+ * then gets the file handle back out again.
131
+ *
132
+ * ```js
133
+ * import {createStore} from 'tinybase';
134
+ * import {createOpfsPersister} from 'tinybase/persisters/persister-browser';
135
+ *
136
+ * const opfs = await navigator.storage.getDirectory();
137
+ * const handle = await opfs.getFileHandle('tinybase.json', {create: true});
138
+ *
139
+ * const store = createStore().setTables({pets: {fido: {species: 'dog'}}});
140
+ * const persister = createOpfsPersister(store, handle);
141
+ *
142
+ * console.log(persister.getHandle().name);
143
+ * // -> 'tinybase.json'
144
+ *
145
+ * await persister.destroy();
146
+ * ```
147
+ * @category Getter
148
+ * @since v6.7.0
149
+ */
150
+ getHandle(): string;
151
+ }
152
+
106
153
  /**
107
154
  * The createSessionPersister function creates a SessionPersister object that
108
155
  * can persist the Store to the browser's session storage.
@@ -208,3 +255,58 @@ export function createLocalPersister<Schemas extends OptionalSchemas>(
208
255
  storageName: string,
209
256
  onIgnoredError?: (error: any) => void,
210
257
  ): LocalPersister<Schemas>;
258
+
259
+ /**
260
+ * The createOpfsPersister function creates an OpfsPersister object that can
261
+ * persist the Store to a file in an origin private file system (OPFS).
262
+ *
263
+ * This has schema-based typing. The following is a simplified representation:
264
+ *
265
+ * ```ts override
266
+ * createOpfsPersister(
267
+ * store: Store | MergeableStore,
268
+ * handle: FileSystemFileHandle,
269
+ * onIgnoredError?: (error: any) => void,
270
+ * ): OpfsPersister;
271
+ * ```
272
+ *
273
+ * An OpfsPersister supports both regular Store and MergeableStore objects.
274
+ *
275
+ * As well as providing a reference to the Store to persist, you must provide a
276
+ * `handle` parameter which identifies an existing OPFS file to persist it to.
277
+ * @param store The Store or MergeableStore to persist.
278
+ * @param handle The handle of an existing OPFS file to persist the Store to.
279
+ * @param onIgnoredError An optional handler for the errors that the Persister
280
+ * would otherwise ignore when trying to save or load data. This is suitable for
281
+ * debugging persistence issues in a development environment.
282
+ * @returns A reference to the new OpfsPersister object.
283
+ * @example
284
+ * This example creates an OpfsPersister object and persists the Store to a
285
+ * local file.
286
+ *
287
+ * ```js
288
+ * import {createStore} from 'tinybase';
289
+ * import {createOpfsPersister} from 'tinybase/persisters/persister-browser';
290
+ *
291
+ * const opfs = await navigator.storage.getDirectory();
292
+ * const handle = await opfs.getFileHandle('tinybase.json', {create: true});
293
+ *
294
+ * const store = createStore().setTables({pets: {fido: {species: 'dog'}}});
295
+ * const persister = createOpfsPersister(store, handle);
296
+ *
297
+ * await persister.save();
298
+ * // Store JSON will be saved to the file.
299
+ *
300
+ * await persister.load();
301
+ * // Store JSON will be loaded from the file.
302
+ *
303
+ * await persister.destroy();
304
+ * ```
305
+ * @category Creation
306
+ * @since v6.7.0
307
+ */
308
+ export function createOpfsPersister<Schemas extends OptionalSchemas>(
309
+ store: Store<Schemas> | MergeableStore<Schemas>,
310
+ handle: FileSystemFileHandle,
311
+ onIgnoredError?: (error: any) => void,
312
+ ): OpfsPersister<Schemas>;
@@ -13,6 +13,7 @@
13
13
  * |-|-|-|-|
14
14
  * |SessionPersister|Browser session storage|Yes|Yes
15
15
  * |LocalPersister|Browser local storage|Yes|Yes
16
+ * |OpfsPersister|Browser origin private file system (OPFS)|Yes|Yes
16
17
  * |FilePersister|Local file (where possible)|Yes|Yes
17
18
  * |IndexedDbPersister|Browser IndexedDB|Yes|No
18
19
  * |RemotePersister|Remote server|Yes|No
@@ -537,7 +537,7 @@ export interface WsServer {
537
537
  * import {createMergeableStore} from 'tinybase';
538
538
  * import {createWsSynchronizer} from 'tinybase/synchronizers/synchronizer-ws-client';
539
539
  * import {createWsServer} from 'tinybase/synchronizers/synchronizer-ws-server';
540
- * import {WebSocketServer} from 'ws';
540
+ * import {WebSocket, WebSocketServer} from 'ws';
541
541
  *
542
542
  * // Server
543
543
  * const server = createWsServer(new WebSocketServer({port: 8047}));
@@ -583,7 +583,7 @@ export interface WsServer {
583
583
  * import {createFilePersister} from 'tinybase/persisters/persister-file';
584
584
  * import {createWsSynchronizer} from 'tinybase/synchronizers/synchronizer-ws-client';
585
585
  * import {createWsServer} from 'tinybase/synchronizers/synchronizer-ws-server';
586
- * import {WebSocketServer} from 'ws';
586
+ * import {WebSocket, WebSocketServer} from 'ws';
587
587
  *
588
588
  * // Server
589
589
  * const server = createWsServer(
@@ -591,7 +591,7 @@ export interface WsServer {
591
591
  * (pathId) =>
592
592
  * createFilePersister(
593
593
  * createMergeableStore(),
594
- * pathId.replace(/[^a-zA-Z0-9]/g, '-') + '.json',
594
+ * './tmp/' + pathId.replace(/[^a-zA-Z0-9]/g, '-') + '.json',
595
595
  * ),
596
596
  * );
597
597
  *
@@ -641,7 +641,7 @@ export interface WsServer {
641
641
  * await server.destroy();
642
642
  *
643
643
  * // Remove file for the purposes of this demo.
644
- * rmSync('petShop.json');
644
+ * rmSync('./tmp/petShop.json');
645
645
  * ```
646
646
  * @example
647
647
  * This example creates a WsServer that persists a MergeableStore to file that
@@ -654,7 +654,7 @@ export interface WsServer {
654
654
  * import {createFilePersister} from 'tinybase/persisters/persister-file';
655
655
  * import {createWsSynchronizer} from 'tinybase/synchronizers/synchronizer-ws-client';
656
656
  * import {createWsServer} from 'tinybase/synchronizers/synchronizer-ws-server';
657
- * import {WebSocketServer} from 'ws';
657
+ * import {WebSocket, WebSocketServer} from 'ws';
658
658
  *
659
659
  * // Server
660
660
  * const server = createWsServer(
@@ -662,7 +662,7 @@ export interface WsServer {
662
662
  * (pathId) => [
663
663
  * createFilePersister(
664
664
  * createMergeableStore(),
665
- * pathId.replace(/[^a-zA-Z0-9]/g, '-') + '.json',
665
+ * './tmp/' + pathId.replace(/[^a-zA-Z0-9]/g, '-') + '.json',
666
666
  * ),
667
667
  * (store) => store.setValue('pathId', pathId),
668
668
  * ],
@@ -684,7 +684,7 @@ export interface WsServer {
684
684
  * await server.destroy();
685
685
  *
686
686
  * // Remove file for the purposes of this demo.
687
- * rmSync('petShop.json');
687
+ * rmSync('./tmp/petShop.json');
688
688
  * ```
689
689
  * @example
690
690
  * This example creates a WsServer with a custom listener that displays
@@ -564,7 +564,7 @@ export interface WsServer {
564
564
  * import {createMergeableStore} from 'tinybase';
565
565
  * import {createWsSynchronizer} from 'tinybase/synchronizers/synchronizer-ws-client';
566
566
  * import {createWsServer} from 'tinybase/synchronizers/synchronizer-ws-server';
567
- * import {WebSocketServer} from 'ws';
567
+ * import {WebSocket, WebSocketServer} from 'ws';
568
568
  *
569
569
  * // Server
570
570
  * const server = createWsServer(new WebSocketServer({port: 8047}));
@@ -610,7 +610,7 @@ export interface WsServer {
610
610
  * import {createFilePersister} from 'tinybase/persisters/persister-file';
611
611
  * import {createWsSynchronizer} from 'tinybase/synchronizers/synchronizer-ws-client';
612
612
  * import {createWsServer} from 'tinybase/synchronizers/synchronizer-ws-server';
613
- * import {WebSocketServer} from 'ws';
613
+ * import {WebSocket, WebSocketServer} from 'ws';
614
614
  *
615
615
  * // Server
616
616
  * const server = createWsServer(
@@ -618,7 +618,7 @@ export interface WsServer {
618
618
  * (pathId) =>
619
619
  * createFilePersister(
620
620
  * createMergeableStore(),
621
- * pathId.replace(/[^a-zA-Z0-9]/g, '-') + '.json',
621
+ * './tmp/' + pathId.replace(/[^a-zA-Z0-9]/g, '-') + '.json',
622
622
  * ),
623
623
  * );
624
624
  *
@@ -668,7 +668,7 @@ export interface WsServer {
668
668
  * await server.destroy();
669
669
  *
670
670
  * // Remove file for the purposes of this demo.
671
- * rmSync('petShop.json');
671
+ * rmSync('./tmp/petShop.json');
672
672
  * ```
673
673
  * @example
674
674
  * This example creates a WsServer that persists a MergeableStore to file that
@@ -681,7 +681,7 @@ export interface WsServer {
681
681
  * import {createFilePersister} from 'tinybase/persisters/persister-file';
682
682
  * import {createWsSynchronizer} from 'tinybase/synchronizers/synchronizer-ws-client';
683
683
  * import {createWsServer} from 'tinybase/synchronizers/synchronizer-ws-server';
684
- * import {WebSocketServer} from 'ws';
684
+ * import {WebSocket, WebSocketServer} from 'ws';
685
685
  *
686
686
  * // Server
687
687
  * const server = createWsServer(
@@ -689,7 +689,7 @@ export interface WsServer {
689
689
  * (pathId) => [
690
690
  * createFilePersister(
691
691
  * createMergeableStore(),
692
- * pathId.replace(/[^a-zA-Z0-9]/g, '-') + '.json',
692
+ * './tmp/' + pathId.replace(/[^a-zA-Z0-9]/g, '-') + '.json',
693
693
  * ),
694
694
  * (store) => store.setValue('pathId', pathId),
695
695
  * ],
@@ -711,7 +711,7 @@ export interface WsServer {
711
711
  * await server.destroy();
712
712
  *
713
713
  * // Remove file for the purposes of this demo.
714
- * rmSync('petShop.json');
714
+ * rmSync('./tmp/petShop.json');
715
715
  * ```
716
716
  * @example
717
717
  * This example creates a WsServer with a custom listener that displays
@@ -101,7 +101,7 @@ export interface WsServerSimple {
101
101
  * import {createMergeableStore} from 'tinybase';
102
102
  * import {createWsSynchronizer} from 'tinybase/synchronizers/synchronizer-ws-client';
103
103
  * import {createWsServerSimple} from 'tinybase/synchronizers/synchronizer-ws-server-simple';
104
- * import {WebSocketServer} from 'ws';
104
+ * import {WebSocket, WebSocketServer} from 'ws';
105
105
  *
106
106
  * // Server
107
107
  * const server = createWsServerSimple(new WebSocketServer({port: 8053}));
@@ -101,7 +101,7 @@ export interface WsServerSimple {
101
101
  * import {createMergeableStore} from 'tinybase';
102
102
  * import {createWsSynchronizer} from 'tinybase/synchronizers/synchronizer-ws-client';
103
103
  * import {createWsServerSimple} from 'tinybase/synchronizers/synchronizer-ws-server-simple';
104
- * import {WebSocketServer} from 'ws';
104
+ * import {WebSocket, WebSocketServer} from 'ws';
105
105
  *
106
106
  * // Server
107
107
  * const server = createWsServerSimple(new WebSocketServer({port: 8053}));
@@ -12562,6 +12562,7 @@ export function usePersisterStatusListener(
12562
12562
  *
12563
12563
  * ```jsx
12564
12564
  * import React from 'react';
12565
+ * import {WebSocket, WebSocketServer} from 'ws';
12565
12566
  * import {createRoot} from 'react-dom/client';
12566
12567
  * import {createMergeableStore} from 'tinybase';
12567
12568
  * import {createWsSynchronizer} from 'tinybase/synchronizers/synchronizer-ws-client';
@@ -12571,7 +12572,6 @@ export function usePersisterStatusListener(
12571
12572
  * useCreateSynchronizer,
12572
12573
  * useTables,
12573
12574
  * } from 'tinybase/ui-react';
12574
- * import {WebSocketServer} from 'ws';
12575
12575
  *
12576
12576
  * const server1 = createWsServer(new WebSocketServer({port: 8044}));
12577
12577
  * const server2 = createWsServer(new WebSocketServer({port: 8045}));
@@ -13654,6 +13654,7 @@ export type WithSchemas<Schemas extends OptionalSchemas> = {
13654
13654
  *
13655
13655
  * ```jsx
13656
13656
  * import React from 'react';
13657
+ * import {WebSocket, WebSocketServer} from 'ws';
13657
13658
  * import {createRoot} from 'react-dom/client';
13658
13659
  * import {createMergeableStore} from 'tinybase';
13659
13660
  * import {createWsSynchronizer} from 'tinybase/synchronizers/synchronizer-ws-client';
@@ -13663,7 +13664,6 @@ export type WithSchemas<Schemas extends OptionalSchemas> = {
13663
13664
  * useCreateSynchronizer,
13664
13665
  * useTables,
13665
13666
  * } from 'tinybase/ui-react';
13666
- * import {WebSocketServer} from 'ws';
13667
13667
  *
13668
13668
  * const server1 = createWsServer(new WebSocketServer({port: 8044}));
13669
13669
  * const server2 = createWsServer(new WebSocketServer({port: 8045}));