Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion client-sdk-references/javascript-web.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ This SDK supports multiple Virtual File Systems (VFS), responsible for storing t

- This system utilizes IndexedDB as its underlying storage mechanism.
- Multiple tabs are fully supported across most modern browsers.
- Users may experience stability issues when using Safari.
- Users may experience stability issues when using Safari. For example, the `RangeError: Maximum call stack size exceeded` error. See [Troubleshooting](/resources/troubleshooting#rangeerror-maximum-call-stack-size-exceeded-on-ios-or-safari) for more details.

#### 2. OPFS-based Alternatives

Expand Down
1 change: 1 addition & 0 deletions client-sdk-references/javascript-web/usage-examples.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import JavaScriptCallbackWatch from '/snippets/basic-watch-query-javascript-call
<Warning>
* Multiple tab support is not currently available on Android.
* For Safari, use the [`OPFSCoopSyncVFS`](/client-sdk-references/javascript-web#sqlite-virtual-file-systems) virtual file system to ensure stable multi-tab functionality.
* If you encounter a `RangeError: Maximum call stack size exceeded` error, see [Troubleshooting](/resources/troubleshooting#rangeerror-maximum-call-stack-size-exceeded-on-ios-or-safari) for solutions.
</Warning>

Using PowerSync between multiple tabs is supported on some web browsers. Multiple tab support relies on shared web workers for database and sync streaming operations. When enabled, shared web workers named `shared-DB-worker-[dbFileName]` and `shared-sync-[dbFileName]` will be created.
Expand Down
46 changes: 43 additions & 3 deletions resources/troubleshooting.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,53 @@ sidebarTitle: "Overview"

## Common issues

<Tip>
**Tip**: Asking the AI bot on this page, or on the [#gpt-help](https://discord.com/channels/1138230179878154300/1304118313093173329) channel on our [Discord server](https://discord.com/invite/powersync), is a good way to troubleshoot common issues.
</Tip>

### `SqliteException: Could not load extension` or similar

This client-side error or similar typically occurs when PowerSync is used in conjunction with either another SQLite library or the standard system SQLite library. PowerSync is generally not compatible with multiple SQLite sources. If another SQLite library exists in your project dependencies, remove it if it is not required. In some cases, there might be other workarounds. For example, in Flutter projects, we've seen this issue with `sqflite 2.2.6`, but `sqflite 2.3.3+1` does not throw the same exception.

<Note>
Tip: Asking the AI bot on the [#gpt-help](https://discord.com/channels/1138230179878154300/1304118313093173329) channel on our [Discord server](https://discord.com/invite/powersync) is a good way to troubleshoot common issues.
</Note>
### `RangeError: Maximum call stack size exceeded` on iOS or Safari

This client-side error commonly occurs when using the PowerSync Web SDK on Safari or iOS (including iOS simulator).

**Solutions:**

1. **Use OPFSCoopSyncVFS (Recommended)**: Switch to the `OPFSCoopSyncVFS` virtual file system, which provides better Safari compatibility and multi-tab support:

```js
import { PowerSyncDatabase, WASQLiteOpenFactory, WASQLiteVFS } from '@powersync/web';

export const db = new PowerSyncDatabase({
schema: AppSchema,
database: new WASQLiteOpenFactory({
dbFilename: 'exampleVFS.db',
vfs: WASQLiteVFS.OPFSCoopSyncVFS,
flags: {
enableMultiTabs: typeof SharedWorker !== 'undefined'
}
}),
flags: {
enableMultiTabs: typeof SharedWorker !== 'undefined'
}
});
```

2. **Disable Web Workers (Alternative)**: Set the `useWebWorker` flag to `false`, but note that this disables multi-tab support:

```js
export const db = new PowerSyncDatabase({
schema: AppSchema,
database: {
dbFilename: 'powersync.db'
},
flags: {
useWebWorker: false
}
});
```

## Tools

Expand Down
2 changes: 1 addition & 1 deletion usage/use-case-examples/high-performance-diffs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@

# Overview

While [basic/incremental watch queries](/usage/use-case-examples/watch-queries) enable reactive UIs by automatically re‑running queries when underlying data changes and returning updated results, they don't specify which individual rows were modified. To get these details, you can use [**differential watch queries**](/usage/use-case-examples/watch-queries#differential-watch-queries), which return a structured diff between successive query results. However, on large result sets they can be slow because they re‑run the query and compare full results (e.g., scanning ~1,000 rows to detect 1 new item). That’s why we introduced **trigger‑based table diffs**: a more performant approach that uses SQLite triggers to record changes on a table as they happen. This means that the overhead associated with tracking these changes overhead is more proportional to the number of rows inserted, updated, or deleted.

Check warning on line 9 in usage/use-case-examples/high-performance-diffs.mdx

View check run for this annotation

Mintlify / Mintlify Validation (powersync) - vale-spellcheck

usage/use-case-examples/high-performance-diffs.mdx#L9

Did you really mean 'UIs'?

Check warning on line 9 in usage/use-case-examples/high-performance-diffs.mdx

View check run for this annotation

Mintlify / Mintlify Validation (powersync) - vale-spellcheck

usage/use-case-examples/high-performance-diffs.mdx#L9

Did you really mean 'performant'?

<Note>
**JavaScript Only**: Trigger-based table diffs are available in the JavaScript SDKs starting from:
**JavaScript Only**: Trigger-based table diffs are currently only supported in our JavaScript SDKs, starting from:
* Web v1.26.0
* React Native v1.24.0
* Node.js v0.10.0
Expand Down Expand Up @@ -110,12 +110,12 @@
```

<Warning>
The strings in `when` are embedded directly into the SQLite trigger creation SQL. Sanitize any user‑derived values. The `sanitizeSQL` helper performs some basic sanitization; additional sanitization is recommended.

Check warning on line 113 in usage/use-case-examples/high-performance-diffs.mdx

View check run for this annotation

Mintlify / Mintlify Validation (powersync) - vale-spellcheck

usage/use-case-examples/high-performance-diffs.mdx#L113

Did you really mean 'sanitization'?

Check warning on line 113 in usage/use-case-examples/high-performance-diffs.mdx

View check run for this annotation

Mintlify / Mintlify Validation (powersync) - vale-spellcheck

usage/use-case-examples/high-performance-diffs.mdx#L113

Did you really mean 'sanitization'?
</Warning>

## Lower-level: createDiffTrigger (advanced)

Set up temporary triggers that write change operations into a temporary table you control. Prefer `trackTableDiff` unless you need to manage lifecycle and locking manually (e.g., buffer diffs to process them later). Note that since the table is created as a temporary table on the SQLite write connection, it can only be accessed within operations performed inside a writeLock.

Check warning on line 118 in usage/use-case-examples/high-performance-diffs.mdx

View check run for this annotation

Mintlify / Mintlify Validation (powersync) - vale-spellcheck

usage/use-case-examples/high-performance-diffs.mdx#L118

Did you really mean 'writeLock'?

```javascript
// Define the temporary table to store the diff
Expand Down