Skip to content

Commit af8c17c

Browse files
committed
Refactor connection methods and SQLite VFS documentation for clarity
1 parent 16fc278 commit af8c17c

File tree

2 files changed

+64
-72
lines changed

2 files changed

+64
-72
lines changed

client-sdk-references/javascript-web.mdx

Lines changed: 50 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -285,62 +285,55 @@ 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/[email protected]) 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).
297-
298-
#### Selecting Connection Method
299-
300-
The `PowerSyncDatabase` client's `connect` method supports a `connectionMethod` option. This is not required, as the WebSocket method is used by default.
302+
By default, the `PowerSyncDatabase.connect()` method uses WebSocket. You can optionally specify the `connectionMethod` to override this:
301303
302304
```js
303-
// For WebSocket
304-
powerSync.connect(connector)
305+
// WebSocket (default)
306+
powerSync.connect(connector);
305307

306-
// For HTTP Streaming
308+
// HTTP Streaming
307309
powerSync.connect(connector, { connectionMethod: SyncStreamConnectionMethod.HTTP });
308310
```
309311
310-
### Configuring Different SQLite Virtual Filesystems for Web
311-
The default SQLite VFS (`IDBBatchAtomicVFS`) can be replaced by supported [OPFS](https://developer.mozilla.org/en-US/docs/Web/API/File_System_API/Origin_private_file_system) alternatives.
312-
`IDBBatchAtomicVFS` uses `IndexedDB` as the underlying storage which may have worse performance and stability issues with browsers such as Safari when compared with `OPFS` based VFSs.
313-
See the [WA-SQLite README](https://github.com/powersync-ja/wa-sqlite/blob/1bb58d3619b96a2708e0320e1c22d0f2b9db35c6/src/examples/README.md#L28) for more details on each option.
312+
### SQLite Virtual File Systems
314313
315-
`OPFS` can be configured with a `WASQLiteOpenFactory`.
314+
This SDK supports multiple Virtual File Systems (VFS), responsible for storing the local SQLite database:
316315
317-
<CodeGroup>
318-
```js OPFSCoopSyncVFS (Safari Multiple Tabs Support)
319-
import { PowerSyncDatabase, WASQLiteOpenFactory, WASQLiteVFS } from '@powersync/web';
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.
320320
321-
export const db = new PowerSyncDatabase({
322-
schema: AppSchema,
323-
database: new WASQLiteOpenFactory({
324-
dbFilename: 'exampleVFS.db',
325-
vfs: WASQLiteVFS.OPFSCoopSyncVFS,
326-
flags: {
327-
enableMultiTabs: typeof SharedWorker !== 'undefined'
328-
}
329-
}),
330-
flags: {
331-
enableMultiTabs: typeof SharedWorker !== 'undefined'
332-
}
333-
});
334-
```
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:
335328
336-
```js AccessHandlePoolVFS
329+
```js
337330
import { PowerSyncDatabase, WASQLiteOpenFactory, WASQLiteVFS } from '@powersync/web';
338331

339332
export const db = new PowerSyncDatabase({
340333
schema: AppSchema,
341334
database: new WASQLiteOpenFactory({
342335
dbFilename: 'exampleVFS.db',
343-
vfs: WASQLiteVFS.AccessHandlePoolVFS,
336+
vfs: WASQLiteVFS.OPFSCoopSyncVFS,
344337
flags: {
345338
enableMultiTabs: typeof SharedWorker !== 'undefined'
346339
}
@@ -350,58 +343,57 @@ export const db = new PowerSyncDatabase({
350343
}
351344
});
352345
```
353-
</CodeGroup>
354346
355-
**Note**: The `AccessHandlePoolVFS` does not to work correctly in the multiple tabs use case. `OPFSCoopSyncVFS` works with multiple tabs, and adds multiple tab support for both Safari and Safari iOS.
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
356353
357-
**Note**: There are known limitations with `OPFS` in Safari’s incognito mode, which may cause it to not function properly.
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 |
358359
359-
| VFS Type | Multi-Tab Support on Normal Browsers | Multi-Tab Support on Safari/Safari iOS | Notes |
360-
|-------------------------|-------------------------------------|----------------------------------------|-------------------------------------------------------------------|
361-
| **IDBBatchAtomicVFS** | Supported | Not supported | May have stability issues on Safari. |
362-
| **AccessHandlePoolVFS**| Not supported | Not supported | Does not work correctly in multi-tab scenarios. |
363-
| **OPFSCoopSyncVFS** | Supported | Supported | Works with multiple tabs on all browsers, including Safari. |
360+
**Note**: There are known issues with OPFS when using Safari's incognito mode.
364361
365-
### Clearing OPFS Storage
362+
### Managing OPFS Storage
366363
367-
Clearing `OPFS` storage isn’t as straightforward as clearing `IndexedDB` which can be done through browser developer tools.
368-
This requires developers to manually iterate through and delete files and directories.
364+
Unlike IndexedDB, OPFS storage cannot be managed through browser developer tools. The following utility functions can help you manage OPFS storage programmatically:
369365
370-
```js
366+
```js
367+
// Clear all OPFS storage
371368
async function purgeVFS() {
372369
await powerSync.disconnect();
373370
await powerSync.close();
374-
371+
375372
const root = await navigator.storage.getDirectory();
376-
377-
// .db-wal needs a moment to become deletable
378-
await new Promise((resolve) => setTimeout(resolve, 1));
379-
373+
await new Promise(resolve => setTimeout(resolve, 1)); // Allow .db-wal to become deletable
374+
380375
for await (const [name, entry] of root.entries!()) {
381376
try {
382377
if (entry.kind === 'file') {
383-
console.log(`Deleted file: ${name}`);
384378
await root.removeEntry(name);
385379
} else if (entry.kind === 'directory') {
386380
await root.removeEntry(name, { recursive: true });
387-
console.log(`Deleted directory: ${name}`);
388381
}
389382
} catch (err) {
390383
console.error(`Failed to delete ${entry.kind}: ${name}`, err);
391384
}
392385
}
393386
}
394387

388+
// List OPFS entries
395389
async function listVfsEntries() {
396390
const root = await navigator.storage.getDirectory();
397-
398391
for await (const [name, entry] of root.entries()) {
399-
console.log(`Entry ${entry.kind}: ${name}`);
392+
console.log(`${entry.kind}: ${name}`);
400393
}
401394
}
402395
```
403396
404-
405397
## ORM Support
406398
407399
See [JavaScript ORM Support](/client-sdk-references/javascript-web/javascript-orm/overview) for details.

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/[email protected]) 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)