Skip to content

Commit 1e1fa85

Browse files
Chriztiaanbenitav
andauthored
Initial OPFS docs. (#66)
* Initial OPFS docs. * Added example covering OPFS storage clearing. * Refactor connection methods and SQLite VFS documentation for clarity --------- Co-authored-by: benitav <benita@journeyapps.com>
1 parent 8132b8e commit 1e1fa85

File tree

2 files changed

+112
-25
lines changed

2 files changed

+112
-25
lines changed

client-sdk-references/javascript-web.mdx

Lines changed: 98 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -285,26 +285,113 @@ See [Usage Examples](/client-sdk-references/javascript-web/usage-examples) for f
285285
286286
## Developer Notes
287287
288-
### Connecting via WebSocket or HTTP Stream
288+
### Connection Methods
289289
290-
This SDK connects to a PowerSync instance and streams sync commands via WebSockets (enabled by default since @powersync/web@1.6.0) or HTTP streaming.
290+
This SDK supports two methods for streaming sync commands:
291291
292-
The WebSocket implementation uses reactive socket streams from the cross-platform [RSocket](https://github.com/powersync-ja/powersync-js/pull/rsocket.io) library. This allows the client to request commands from the server after processing existing events, alleviating any back-pressure build-up of commands. Sync commands are transmitted as BSON (binary) documents.
292+
1. **WebSocket (Default)**
293+
- The implementation leverages RSocket for handling reactive socket streams.
294+
- Back-pressure is effectively managed through client-controlled command requests.
295+
- Sync commands are transmitted efficiently as BSON (binary) documents.
296+
- This method is **recommended** since it will support the future [BLOB column support](https://roadmap.powersync.com/c/88-support-for-blob-column-types) feature.
293297
294-
#### Benefits of using the WebSocket Method
298+
2. **HTTP Streaming (Legacy)**
299+
- This is the original implementation method.
300+
- This method will not support the future BLOB column feature.
295301
296-
* BLOB column support will be added on top of the WebSocket implementation (the HTTP streaming method will not support this).
302+
By default, the `PowerSyncDatabase.connect()` method uses WebSocket. You can optionally specify the `connectionMethod` to override this:
297303
298-
#### Selecting Connection Method
304+
```js
305+
// WebSocket (default)
306+
powerSync.connect(connector);
307+
308+
// HTTP Streaming
309+
powerSync.connect(connector, { connectionMethod: SyncStreamConnectionMethod.HTTP });
310+
```
311+
312+
### SQLite Virtual File Systems
313+
314+
This SDK supports multiple Virtual File Systems (VFS), responsible for storing the local SQLite database:
315+
316+
#### 1. IDBBatchAtomicVFS (Default)
317+
- This system utilizes IndexedDB as its underlying storage mechanism.
318+
- Multiple tabs are fully supported across most modern browsers.
319+
- Users may experience stability issues when using Safari.
299320
300-
The `PowerSyncDatabase` client's `connect` method supports a `connectionMethod` option. This is not required, as the WebSocket method is used by default.
321+
#### 2. OPFS-based Alternatives
322+
PowerSync supports two OPFS (Origin Private File System) implementations that generally offer improved performance:
323+
324+
##### OPFSCoopSyncVFS (Recommended)
325+
- This implementation provides comprehensive multi-tab support across all major browsers.
326+
- It offers the most reliable compatibility with Safari and Safari iOS.
327+
- Example configuration:
301328
302329
```js
303-
// For WebSocket
304-
powerSync.connect(connector)
330+
import { PowerSyncDatabase, WASQLiteOpenFactory, WASQLiteVFS } from '@powersync/web';
305331

306-
// For HTTP Streaming
307-
powerSync.connect(connector, { connectionMethod: SyncStreamConnectionMethod.HTTP });
332+
export const db = new PowerSyncDatabase({
333+
schema: AppSchema,
334+
database: new WASQLiteOpenFactory({
335+
dbFilename: 'exampleVFS.db',
336+
vfs: WASQLiteVFS.OPFSCoopSyncVFS,
337+
flags: {
338+
enableMultiTabs: typeof SharedWorker !== 'undefined'
339+
}
340+
}),
341+
flags: {
342+
enableMultiTabs: typeof SharedWorker !== 'undefined'
343+
}
344+
});
345+
```
346+
347+
##### AccessHandlePoolVFS
348+
- This implementation delivers optimal performance for single-tab applications.
349+
- The system is not designed to handle multiple tab scenarios.
350+
- The configuration is similar to `OPFSCoopSyncVFS`, but requires using `WASQLiteVFS.AccessHandlePoolVFS`.
351+
352+
#### VFS Compatibility Matrix
353+
354+
| VFS Type | Multi-Tab Support (Standard Browsers) | Multi-Tab Support (Safari/iOS) | Notes |
355+
|----------|---------------------------|---------------------|--------|
356+
| IDBBatchAtomicVFS | ✅ | ❌ | Default, some Safari stability issues |
357+
| OPFSCoopSyncVFS | ✅ | ✅ | Recommended for multi-tab support |
358+
| AccessHandlePoolVFS | ❌ | ❌ | Best for single-tab applications |
359+
360+
**Note**: There are known issues with OPFS when using Safari's incognito mode.
361+
362+
### Managing OPFS Storage
363+
364+
Unlike IndexedDB, OPFS storage cannot be managed through browser developer tools. The following utility functions can help you manage OPFS storage programmatically:
365+
366+
```js
367+
// Clear all OPFS storage
368+
async function purgeVFS() {
369+
await powerSync.disconnect();
370+
await powerSync.close();
371+
372+
const root = await navigator.storage.getDirectory();
373+
await new Promise(resolve => setTimeout(resolve, 1)); // Allow .db-wal to become deletable
374+
375+
for await (const [name, entry] of root.entries!()) {
376+
try {
377+
if (entry.kind === 'file') {
378+
await root.removeEntry(name);
379+
} else if (entry.kind === 'directory') {
380+
await root.removeEntry(name, { recursive: true });
381+
}
382+
} catch (err) {
383+
console.error(`Failed to delete ${entry.kind}: ${name}`, err);
384+
}
385+
}
386+
}
387+
388+
// List OPFS entries
389+
async function listVfsEntries() {
390+
const root = await navigator.storage.getDirectory();
391+
for await (const [name, entry] of root.entries()) {
392+
console.log(`${entry.kind}: ${name}`);
393+
}
394+
}
308395
```
309396
310397
## ORM Support

client-sdk-references/react-native-and-expo.mdx

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -370,27 +370,27 @@ See [Usage Examples](/client-sdk-references/react-native-and-expo/usage-examples
370370
371371
## Developer Notes
372372
373-
### Connecting via WebSockets or HTTP Streams
373+
### Connection Methods
374374
375-
This SDK connects to a PowerSync instance and streams sync commands via WebSockets (enabled by default since @powersync/react-native@1.11.0) or HTTP streams.
375+
This SDK supports two methods for streaming sync commands:
376376
377-
The WebSocket implementation (available since version 1.4.6 of the SDK) uses reactive socket streams using the cross-platform [RSocket](https://github.com/powersync-ja/powersync-js/pull/rsocket.io) library. This allows the client to request commands from the server after processing existing events, alleviating any back-pressure build-up of commands. Sync commands are transmitted as BSON (binary) documents.
377+
1. **WebSocket (Default)**
378+
- The implementation leverages RSocket for handling reactive socket streams.
379+
- Back-pressure is effectively managed through client-controlled command requests.
380+
- Sync commands are transmitted efficiently as BSON (binary) documents.
381+
- This method is **recommended** since it will support the future [BLOB column support](https://roadmap.powersync.com/c/88-support-for-blob-column-types) feature.
378382
379-
#### Benefits of using the WebSocket Method
383+
2. **HTTP Streaming (Legacy)**
384+
- This is the original implementation method.
385+
- This method will not support the future BLOB column feature.
380386
381-
* BLOB column support will be added on top of the WebSocket implementation (the HTTP streaming method will not support this).
382-
* If you are using Expo \<v51, then you no longer need to disable the [Flipper debug tools](/client-sdk-references/react-native-and-expo#android-flipper-network-plugin-for-http-streams) (this is required for HTTP streaming to work in debug Android builds).
383-
* In internal testing, the WebSocket method was slightly faster than the HTTP streaming method on React Native.
384-
385-
#### Selecting Connection Method
386-
387-
The `PowerSyncDatabase` client's `connect` method supports a `connectionMethod` option. This is not required, as the WebSocket method is used by default.
387+
By default, the `PowerSyncDatabase.connect()` method uses WebSocket. You can optionally specify the `connectionMethod` to override this:
388388
389389
```js
390-
// For WebSocket
391-
powerSync.connect(connector)
390+
// WebSocket (default)
391+
powerSync.connect(connector);
392392

393-
// For HTTP Stream
393+
// HTTP Streaming
394394
powerSync.connect(connector, { connectionMethod: SyncStreamConnectionMethod.HTTP });
395395
```
396396

0 commit comments

Comments
 (0)