Skip to content
Draft
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
7 changes: 4 additions & 3 deletions client-sdks/advanced/data-encryption.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
1. [SQLite3MultipleCiphers](https://utelle.github.io/SQLite3MultipleCiphers), which is available both on native platforms and the web.
2. [SQLCipher Community Edition](https://www.zetetic.net/sqlcipher/), available on native platforms only.

<Note>Setting up encryption has changed in version 2.0 of the PowerSync SDK. When upgrading, follow these steps and remove dependencies on `powersync_sqlcipher`.</Note>

Check warning on line 21 in client-sdks/advanced/data-encryption.mdx

View check run for this annotation

Mintlify / Mintlify Validation (powersync) - vale-spellcheck

client-sdks/advanced/data-encryption.mdx#L21

Did you really mean 'powersync_sqlcipher'?

To enable encryption, pass an instance of `EncryptionOptions` to a `PowerSyncDatabase` constructor:

Expand Down Expand Up @@ -63,12 +63,13 @@
</Accordion>

<Accordion title="React Native & Expo" icon="react">
[SQLCipher](https://www.zetetic.net/sqlcipher/) support is available for PowerSync's React Native SDK through the `@powersync/op-sqlite` package. See usage details in the package README:
The React Native SDK uses OP-SQLite, which [supports encryption](https://op-engineering.github.io/op-sqlite/docs/installation/) through [SQLCipher](https://www.zetetic.net/sqlcipher/).
For usage details, see the readme of `@powersync/react-native`.

Check warning on line 67 in client-sdks/advanced/data-encryption.mdx

View check run for this annotation

Mintlify / Mintlify Validation (powersync) - vale-spellcheck

client-sdks/advanced/data-encryption.mdx#L67

Did you really mean 'readme'?

<Card
title="npm: @powersync/op-sqlite"
title="npm: @powersync/react-native"
icon="npm"
href="https://www.npmjs.com/package/@powersync/op-sqlite"
href="https://www.npmjs.com/package/@powersync/react-native"
horizontal
/>
</Accordion>
Expand Down
52 changes: 26 additions & 26 deletions client-sdks/advanced/gis-data-postgis.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
--SQL command to update the todos table with 3 additional columns:

ALTER TABLE todos
ADD COLUMN address location_address null,

Check warning on line 28 in client-sdks/advanced/gis-data-postgis.mdx

View check run for this annotation

Mintlify / Mintlify Validation (powersync) - vale-spellcheck

client-sdks/advanced/gis-data-postgis.mdx#L28

Did you really mean 'location_address'?
ADD COLUMN contact_numbers text [] null,
ADD COLUMN location geography (point) null
```
Expand Down Expand Up @@ -65,32 +65,32 @@
### AppSchema Example

```js
export const AppSchema = new Schema([
new Table({
name: 'todos',
columns: [
new Column({ name: 'list_id', type: ColumnType.TEXT }),
new Column({ name: 'created_at', type: ColumnType.TEXT }),
new Column({ name: 'completed_at', type: ColumnType.TEXT }),
new Column({ name: 'description', type: ColumnType.TEXT }),
new Column({ name: 'completed', type: ColumnType.INTEGER }),
new Column({ name: 'created_by', type: ColumnType.TEXT }),
new Column({ name: 'completed_by', type: ColumnType.TEXT }),
new Column({name: 'address', type: ColumnType.TEXT}),
new Column({name: 'contact_numbers', type: ColumnType.TEXT})
new Column({name: 'location', type: ColumnType.TEXT}),
],
indexes: [new Index({ name: 'list', columns: [new IndexedColumn({ name: 'list_id' })] })]
}),
new Table({
name: 'lists',
columns: [
new Column({ name: 'created_at', type: ColumnType.TEXT }),
new Column({ name: 'name', type: ColumnType.TEXT }),
new Column({ name: 'owner_id', type: ColumnType.TEXT })
]
})
]);
const todos = new Table(
{
list_id: column.text,
created_at: column.text,
completed_at: column.text,
description: column.text,
completed: column.integer,
created_by: column.text,
completed_by: column.text,
address: column.text,
contact_numbers: column.text,
location: column.text
},
{ indexes: { list: ['list_id'] } }
);

const lists = new Table({
created_at: column.text,
name: column.text,
owner_id: column.text
});

export const AppSchema = new Schema({
todos,
lists
});
```

Note:
Expand Down
14 changes: 4 additions & 10 deletions client-sdks/advanced/pre-seeded-sqlite.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -143,20 +143,17 @@ export const downloadFile = async (storeId: string) => {
Once the database is downloaded, initialize the `PowerSyncDatabase` class with the file path and connect to the PowerSync instance.

```typescript
import { OPSqliteOpenFactory } from '@powersync/op-sqlite';
import { PowerSyncDatabase } from '@powersync/react-native';
import { AppSchema } from './Schema';

// databasePath is the path to the pre-seeded SQLite database file on the device.
export const configureDatabase = async (storeId: string) => {
const opSqlite = new OPSqliteOpenFactory({
dbFilename: `${storeId}.sqlite`,
dbLocation: FilePath.replace('file://', '')
});

const powersync = new PowerSyncDatabase({
schema: AppSchema,
database: opSqlite,
database: {
dbFilename: `${storeId}.sqlite`,
dbLocation: FilePath.replace('file://', '')
},
});

// Call init() first, this will ensure the database is initialized, but not connected to the PowerSync instance.
Expand All @@ -173,6 +170,3 @@ export const configureDatabase = async (storeId: string) => {
</Tip>

At this point the client would connect to the PowerSync instance and sync the data from where the pre-seeded snapshot was created, bypassing the initial sync process.



28 changes: 12 additions & 16 deletions client-sdks/frameworks/expo-go-support.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ import { Text } from "react-native";

export const powerSync = new PowerSyncDatabase({
schema: new Schema({}), // todo: define the schema - see Next Steps below
database: new SQLJSOpenFactory({
factory: new SQLJSOpenFactory({
dbFilename: "example.db",
}),
});
Expand Down Expand Up @@ -84,7 +84,7 @@ import { Text } from "react-native";

export const powerSync = new PowerSyncDatabase({
schema: new Schema({}), // todo: define the schema - see Next Steps below
database: new SQLJSOpenFactory({
factory: new SQLJSOpenFactory({
dbFilename: "example.db",
}),
});
Expand Down Expand Up @@ -120,36 +120,32 @@ See an example in the package [README](https://www.npmjs.com/package/@powersync/

## Moving Beyond Expo Go

When you're ready to move beyond the Expo Go sandbox environment - whether for native development builds or production deployment - we recommend switching to our native database adapters:

- [OP-SQLite](https://www.npmjs.com/package/@powersync/op-sqlite) (Recommended) - Offers built-in encryption support and better React Native New Architecture compatibility
- [React Native Quick SQLite](https://www.npmjs.com/package/@journeyapps/react-native-quick-sqlite) - Our original native adapter
When you're ready to move beyond the Expo Go sandbox environment - whether for native development builds or production deployment - we recommend switching to our recommended native database adapter,
based on [OP-SQLite](https://www.npmjs.com/package/@op-engineering/op-sqlite).

<Note>
These database adapters cannot run in Expo Go because they require native code compilation. Specifically, PowerSync needs a SQLite implementation that can load the PowerSync SQLite core extension, which isn't possible in Expo Go's prebuilt app container.
OP-SQLite cannot run in Expo Go because it require native code compilation. Specifically, PowerSync needs a SQLite implementation that can load the PowerSync SQLite core extension, which isn't possible in Expo Go's prebuilt app container.
</Note>

These adapters provide better performance, full SQLite consistency guarantees, and are suitable for both development builds and production deployment. See the SDKs [Installation](/client-sdks/reference/react-native-and-expo#install-peer-dependencies) details for setup instructions.
This adapter provides better performance, full SQLite consistency guarantees, and are suitable for both development builds and production deployment. See the SDKs [Installation](/client-sdks/reference/react-native-and-expo#install-peer-dependencies) details for setup instructions.

### Switching Between Adapters - Example

If you want to keep using Expo Go alongside development and production builds, you can switch between different adapters based on the Expo `executionEnvironment`:

```js SystemProvider.tsx
import { SQLJSOpenFactory } from "@powersync/adapter-sql-js";
import { PowerSyncDatabase } from "@powersync/react-native";
import { DatabaseSource, PowerSyncDatabase } from "@powersync/react-native";
import Constants from "expo-constants";

const isExpoGo = Constants.executionEnvironment === "storeClient";

const source: DatabaseSource = isExpoGo ?
{ factory: new SQLJSOpenFactory({ dbFilename: "app.db" }) }
: { database: { dbFilename: "sqlite.db" } };

export const powerSync = new PowerSyncDatabase({
schema: AppSchema,
database: isExpoGo
? new SQLJSOpenFactory({
dbFilename: "app.db",
})
: {
dbFilename: "sqlite.db",
},
...source,
});
```
15 changes: 6 additions & 9 deletions client-sdks/frameworks/next-js.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -278,29 +278,26 @@
import { AppSchema } from '@/lib/powersync/AppSchema';
import { BackendConnector } from '@/lib/powersync/BackendConnector';
import { PowerSyncContext } from '@powersync/react';
import { PowerSyncDatabase, WASQLiteOpenFactory, createBaseLogger, LogLevel } from '@powersync/web';
import { PowerSyncDatabase, WASQLiteOpenFactory, createConsoleLogger, LogLevels } from '@powersync/web';
import React, { Suspense } from 'react';

const logger = createBaseLogger();
logger.useDefaults();
logger.setLevel(LogLevel.DEBUG);
const logger = createConsoleLogger({ minLevel: LogLevels.debug });

let dbInstance: PowerSyncDatabase | null = null;

function getDB(): PowerSyncDatabase {
if (dbInstance) return dbInstance;

dbInstance = new PowerSyncDatabase({
database: new WASQLiteOpenFactory({
database: {
dbFilename: 'powersync.db',
// Use the pre-bundled worker from public/@powersync/
// This is required since Turbopack doesn't support dynamic imports of workers yet
worker: '/@powersync/worker/WASQLiteDB.umd.js'
}),
worker: '/@powersync/worker.js'
},
schema: AppSchema,
flags: { disableSSRWarning: true },
// Use the pre-bundled sync worker from public/@powersync/
sync: { worker: '/@powersync/worker/SharedSyncImplementation.umd.js' },
sync: { worker: '/@powersync/worker.js' },
logger
});

Expand All @@ -323,7 +320,7 @@

#### Update `layout.tsx`

Update `RootLayout` to wrap `children` with the `PowerSyncProvider`. Importantly, **the root layout should remain a Server Component** — do not add `'use client'` here. This is the standard Next.js App Router convention and is required if you want to export `metadata` (or use `generateMetadata`) from the layout. The client boundary is drawn at `PowerSyncProvider`, which is all that's needed to get PowerSync running in the browser.

Check warning on line 323 in client-sdks/frameworks/next-js.mdx

View check run for this annotation

Mintlify / Mintlify Validation (powersync) - vale-spellcheck

client-sdks/frameworks/next-js.mdx#L323

Did you really mean 'generateMetadata'?

```typescript app/layout.tsx
import type { Metadata } from 'next';
Expand Down
52 changes: 18 additions & 34 deletions client-sdks/frameworks/react-native-web-support.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ See installation instructions [here](https://www.npmjs.com/package/@powersync/we

For React Native for Web, workers need to be configured when instantiating `PowerSyncDatabase`. An example of this is available [here](https://github.com/powersync-ja/powersync-js/blob/main/demos/react-native-web-supabase-todolist/library/powersync/system.ts).

To do this, copy the contents of `node_modules/@powersync/web/dist` to the root of your project (typically in the `public `directory). To make it easier to manage these files in the `public` directory, it is recommended to place the contents in a nested directory like `@powersync`.
To do this, copy the contents of `node_modules/@powersync/web/dist/worker` to the root of your project (typically in the `public `directory). To make it easier to manage these files in the `public` directory, it is recommended to place the contents in a nested directory like `@powersync`.

The [`@powersync/web`](https://github.com/powersync-ja/powersync-js/tree/main/packages/web) package includes a CLI utility which can copy the required assets to the `public` directory (configurable with the `--output` option).

Expand All @@ -49,34 +49,28 @@ const factory = new WASQLiteOpenFactory({
dbFilename: 'sqlite.db',

// Option 1: Specify a path to the database worker
worker: '/@powersync/worker/WASQLiteDB.umd.js'
worker: '/@powersync/worker.js'

// Option 2: Or provide a factory function to create the worker.
// The worker name should be unique for the database filename to avoid conflicts if multiple clients with different databases are present.
// worker: (options) => {
// if (options?.flags?.enableMultiTabs) {
// return new SharedWorker(`/@powersync/worker/WASQLiteDB.umd.js`, {
// name: `shared-DB-worker-${options?.dbFilename}`
// });
// } else {
// return new Worker(`/@powersync/worker/WASQLiteDB.umd.js`, {
// name: `DB-worker-${options?.dbFilename}`
// });
// }
// return new SharedWorker(`/@powersync/worker.js`, {
// name: `shared-DB-worker-${options?.dbFilename}`
// });
// }
});

this.powersync = new PowerSyncDatabaseWeb({
schema: AppSchema,
database: factory,
factory: factory,
sync: {
// Option 1: You can specify a path to the sync worker
worker: '/@powersync/worker/SharedSyncImplementation.umd.js'
worker: '/@powersync/worker.js'

//Option 2: Or provide a factory function to create the worker.
// The worker name should be unique for the database filename to avoid conflicts if multiple clients with different databases are present.
// worker: (options) => {
// return new SharedWorker(`/@powersync/worker/SharedSyncImplementation.umd.js`, {
// return new SharedWorker(`/@powersync/worker.js`, {
// name: `shared-sync-${options?.dbFilename}`
// });
// }
Expand All @@ -95,6 +89,10 @@ To target both mobile and web platforms, you need to adjust the Metro configurat
Refer to the example [here](https://github.com/powersync-ja/powersync-js/blob/main/demos/react-native-web-supabase-todolist/metro.config.js). Setting `config.resolver.resolveRequest` allows Metro to behave differently based on the platform.

```js
// Expo removes the react-native export condition for React Native web: https://github.com/expo/expo/blob/874ddfc86c0bdaeeb43f56b4386d271ba869ad47/packages/%40expo/metro-config/src/ExpoMetroConfig.ts#L309
// The PowerSync web SKD needs to be resolved with an RN-specific export condition to work with Metro.
config.resolver.unstable_conditionsByPlatform.web.push('react-native-web');

config.resolver.resolveRequest = (context, moduleName, platform) => {
if (platform === 'web') {
// Depending on `@powersync/web` for functionality, ignore mobile specific dependencies.
Expand All @@ -103,7 +101,7 @@ config.resolver.resolveRequest = (context, moduleName, platform) => {
type: 'empty'
};
}
const mapping = { 'react-native': 'react-native-web', '@powersync/web': '@powersync/web/dist/index.umd.js' };
const mapping = { 'react-native': 'react-native-web' };
if (mapping[moduleName]) {
console.log('remapping', moduleName);
return context.resolveRequest(context, mapping[moduleName], platform);
Expand Down Expand Up @@ -143,15 +141,14 @@ if (PowerSyncDatabaseNative) {
}
});
} else {
const factory = new WASQLiteOpenFactory({
dbFilename: 'sqlite.db',
worker: '/@powersync/worker/WASQLiteDB.umd.js'
});
this.powersync = new PowerSyncDatabaseWeb({
schema: AppSchema,
database: factory,
database: {
dbFilename: 'sqlite.db',
worker: '/@powersync/worker.js'
},
sync: {
worker: '/@powersync/worker/SharedSyncImplementation.umd.js'
worker: '/@powersync/worker.js'
}
});
}
Expand Down Expand Up @@ -220,16 +217,3 @@ import { prompt } from 'util/prompt';
/>;
```

### 5. Configure UMD Target

React Native Web requires the UMD target of `@powersync/web` (available at `@powersync/web/umd`). To fully support this target version, configure the following in your project:

1. Add `config.resolver.unstable_enablePackageExports = true;` to your `metro.config.js` file.

2. TypeScript projects: In the `tsconfig.json` file specify the `moduleResolution` to be `Bundler`.

```json
"compilerOptions": {
"moduleResolution": "Bundler"
}
```
2 changes: 1 addition & 1 deletion client-sdks/full-text-search.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@

Full-text search has been demonstrated in the following SDKs:

- [**Dart/Flutter SDK**](/client-sdks/reference/flutter): Uses the [sqlite_async](https://pub.dev/documentation/sqlite_async/latest/) package for migrations

Check warning on line 12 in client-sdks/full-text-search.mdx

View check run for this annotation

Mintlify / Mintlify Validation (powersync) - vale-spellcheck

client-sdks/full-text-search.mdx#L12

Did you really mean 'sqlite'?
- [**JavaScript Web SDK**](/client-sdks/reference/javascript-web): Requires version 0.5.0 or greater (including [wa-sqlite](https://github.com/powersync-ja/wa-sqlite) 0.2.0+)
- [**React Native SDK**](/client-sdks/reference/react-native-and-expo): Requires version 1.16.0 or greater (including [@powersync/react-native-quick-sqlite](https://github.com/powersync-ja/react-native-quick-sqlite) 2.2.1+)
- [**React Native SDK**](/client-sdks/reference/react-native-and-expo): Requires additional configuration to enable FTS5, see [the readme](https://www.npmjs.com/package/@powersync/react-native).
- [**Swift SDK**](/client-sdks/reference/swift)

Note that the availability of FTS in our SDKs is dependent on the underlying `sqlite` package used. It may be supported in our other SDKs, especially if the `FTS5` extension is available, but would be untested. Check with us on [Discord](https://discord.gg/powersync) if you have a use case and need help getting started.
Expand Down
17 changes: 6 additions & 11 deletions client-sdks/reference/capacitor.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -158,13 +158,13 @@ import { Schema } from '@powersync/web';

const db = new PowerSyncDatabase({
schema: AppSchema,
database: isWeb
factory: isWeb
? new WASQLiteOpenFactory({ dbFilename: "mydb.sqlite" })
: new CapacitorSQLiteOpenFactory({ dbFilename: "mydb.sqlite" })
});
```

Once you've instantiated your PowerSync database, call the [connect()](https://powersync-ja.github.io/powersync-js/web-sdk/classes/AbstractPowerSyncDatabase#connect) method to sync data with your backend.
Once you've instantiated your PowerSync database, call the [connect()](https://powersync-ja.github.io/powersync-js/web-sdk/classes/PowerSyncDatabase#connect) method to sync data with your backend.

<LocalOnly />

Expand Down Expand Up @@ -297,16 +297,11 @@ const deleteList = async (id) => {
## Configure Logging

```js
import { createBaseLogger, LogLevel } from '@powersync/web';
import { createConsoleLogger, LogLevels } from '@powersync/web';

const logger = createBaseLogger();

// Configure the logger to use the default console output
logger.useDefaults();

// Set the minimum log level to DEBUG to see all log messages
// Available levels: DEBUG, INFO, WARN, ERROR, TRACE, OFF
logger.setLevel(LogLevel.DEBUG);
// Create a logger with trace minimum level to see all log messages
// Available levels: trace, debug, info, warn, error
const logger = createConsoleLogger({ minLevel: LogLevels.trace });
```

<Tip>
Expand Down
Loading