diff --git a/client-sdk-references/node.mdx b/client-sdk-references/node.mdx index 08eae55e..5c5234f8 100644 --- a/client-sdk-references/node.mdx +++ b/client-sdk-references/node.mdx @@ -204,4 +204,96 @@ logger.setLevel(LogLevel.DEBUG); ## Supported Platforms -See [Supported Platforms -> Node.js SDK](/resources/supported-platforms#node-js-sdk). \ No newline at end of file +See [Supported Platforms -> Node.js SDK](/resources/supported-platforms#node-js-sdk). + +## Encryption and custom SQLite drivers + +The SDK has an optional dependency on `better-sqlite3` which is used as the default SQLite +driver for that package. +Because that dependency is optional, it can be replaced or removed to customize how SQLite +gets loaded. This section lists common options. + +### Encryption + +To encrypt databases managed by the PowerSync SDK for Node.js, replace the `better-sqlite3` +dependency with the [`better-sqlite3-multiple-ciphers`](https://www.npmjs.com/package/better-sqlite3-multiple-ciphers) fork. +That package has the same API as `better-sqlite3` while bundling [SQLite3MultipleCiphers](https://github.com/utelle/SQLite3MultipleCiphers) +instead of upstream SQLite. + + +The [node example](https://github.com/powersync-ja/powersync-js/tree/main/demos/example-node) in the PowerSync +repository can use both `better-sqlite3` and `better-sqlite3-multiple-ciphers` and may be a useful example here. + + +Because PowerSync attempts to dynamically load `better-sqlite3` at runtime, using a different package +requires patching the database worker. To do that, create a file (say `database.worker.js`) with the following +contents: + +```Typescript +// This worker uses bindings to sqlite3 multiple ciphers instead of the original better-sqlite3 worker. +import Database from 'better-sqlite3-multiple-ciphers'; + +import { startPowerSyncWorker } from '@powersync/node/worker.js'; + +async function resolveBetterSqlite3() { + return Database; +} + +startPowerSyncWorker({ loadBetterSqlite3: resolveBetterSqlite3 }); +``` + +When opening the database, instruct PowerSync to use the custom worker. +Also use the `initializeConnection` option to install an ecryption key: + +```Typescript +const encryptionKey = 'todo: generate encryption key and store it safely'; + +const db = new PowerSyncDatabase({ + schema: AppSchema, + database: { + dbFilename: 'app.db', + openWorker: (_, options) => { + return new Worker(new URL('./database.worker.js', import.meta.url), options); + }, + initializeConnection: async (db) => { + if (encryptionKey.length) { + const escapedKey = encryptionKey.replace("'", "''"); + await db.execute(`pragma key = '${escapedKey}'`); + } + + // Make sure the database is readable, this fails early if the key is wrong. + await db.execute('pragma user_version'); + } + }, + logger +}); +``` + + +If you're using a custom compilation toolchain, for instance because you're compiling from TypeScript +or are applying a bundler to your project, loading workers may require additional configuration on that +toolchain. + + +### `node:sqlite` + +Recent versions of Node.js contain an [experimental SQLite API](https://nodejs.org/api/sqlite.html). +Using the builtin SQLite API can reduce code size and external native dependencies. To enable it, +remove your dependency on `better-sqlite3` and configure PowerSync to use the builtin APIs: + +```JavaScript +const database = new PowerSyncDatabase({ + schema: AppSchema, + database: { + dbFilename: 'app.db', + dbLocation: directory, + // Use node:sqlite instead of better-sqlite3 + implementation: { type: 'node:sqlite' } + } +}); +``` + + +There are stability issues when using PowerSync with this API, and it's not recommended outside of +testing purposes at the moment. + diff --git a/snippets/node/installation.mdx b/snippets/node/installation.mdx index d9480037..2347ab0f 100644 --- a/snippets/node/installation.mdx +++ b/snippets/node/installation.mdx @@ -20,32 +20,43 @@ Add the [PowerSync Node NPM package](https://www.npmjs.com/package/@powersync/no -**Required peer dependencies** - -This SDK requires [`@powersync/better-sqlite3`](https://www.npmjs.com/package/@powersync/better-sqlite3) as a peer dependency: +**Peer dependencies** + +The PowerSync SDK for Node.js supports multiple drivers. More details are available under [encryption and custom drivers](/client-sdk-references/node#encryption-and-custom-sqlite-drivers), +we currently recommend the `better-sqlite3` package for most users: ```bash - npm install @powersync/better-sqlite3 + npm install better-sqlite3 ``` ```bash - yarn add @powersync/better-sqlite3 + yarn add better-sqlite3 ``` ```bash - pnpm install @powersync/better-sqlite3 + pnpm install better-sqlite3 ``` + +Previous versions of the PowerSync SDK for Node.js used the `@powersync/better-sqlite3` fork as a +required peer dependency. +This is no longer recommended. After upgrading to `@powersync/node` version `0.12.0` or later, ensure +the old package is no longer installed by running `@powersync/better-sqlite3`. + + **Common installation issues** -The `@powersync/better-sqlite` package requires native compilation, which depends on certain system tools. This compilation process is handled by `node-gyp` and may fail if required dependencies are missing or misconfigured. +The `better-sqlite` package requires native compilation, which depends on certain system tools. +Prebuilt assets are available and used by default, but a custom compilation may be started depending on the Node.js +or Electron version used. +This compilation process is handled by `node-gyp` and may fail if required dependencies are missing or misconfigured. Refer to the [PowerSync Node package README](https://www.npmjs.com/package/@powersync/node) for more details. \ No newline at end of file