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
4 changes: 2 additions & 2 deletions client-sdks/advanced/attachments.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ We provide attachment helpers for multiple platforms:
| **Flutter** | [Built-in attachments (alpha)](https://pub.dev/documentation/powersync_core/latest/topics/attachments-topic.html) | v1.16.0 | [Flutter Todo](https://github.com/powersync-ja/powersync.dart/tree/main/demos/supabase-todolist) |
| **Swift** | [Built-in attachments (alpha)](https://github.com/powersync-ja/powersync-swift/blob/main/Sources/PowerSync/attachments/README.md) | v1.0.0 | [iOS Demo](https://github.com/powersync-ja/powersync-swift/tree/main/Demos/PowerSyncExample) |
| **Kotlin** | [Built-in attachments (alpha)](https://github.com/powersync-ja/powersync-kotlin/tree/main/common/src/commonMain/kotlin/com/powersync/attachments) | v1.0.0 | [Android Todo](https://github.com/powersync-ja/powersync-kotlin/tree/main/demos/android-supabase-todolist) |
| **.NET** | [Built-in attachments (alpha)](https://github.com/powersync-ja/powersync-dotnet/tree/main/PowerSync/PowerSync.Common/Attachments) | v0.1.2 | [MAUI Todo](https://github.com/powersync-ja/powersync-dotnet/tree/main/demos/MAUITodo) |
| **.NET** | [Built-in attachments (alpha)](https://github.com/powersync-ja/powersync-dotnet/tree/main/PowerSync/PowerSync.Common/Attachments/README.md) | v0.1.2 | [MAUI Todo](https://github.com/powersync-ja/powersync-dotnet/tree/main/demos/MAUITodo) |

<Note>
Most demo applications use Supabase Storage as the storage provider, but the patterns are adaptable to any storage system.
Expand Down Expand Up @@ -2501,4 +2501,4 @@ If you are migrating from the now deprecated attachment helpers for Dart or Java

- **[An Implementation Walkthrough Using The Flutter/Dart Attachment Helpers](https://www.powersync.com/blog/building-offline-first-file-uploads-with-powersync-attachments-helper)** - Blog post on building offline-first uploads

---
---
4 changes: 2 additions & 2 deletions client-sdks/advanced/sqlite-extensions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
---

SQLite can be extended with [Run-Time Loadable Extensions](https://sqlite.org/loadext.html) contributing
new functions, virtual tables, full-text search tokenizers and more. Since PowerSync SDKs are built on top

Check warning on line 7 in client-sdks/advanced/sqlite-extensions.mdx

View check run for this annotation

Mintlify / Mintlify Validation (powersync) - vale-spellcheck

client-sdks/advanced/sqlite-extensions.mdx#L7

Did you really mean 'tokenizers'?
of SQLite connections, most SQLite extensions also work with PowerSync.

Including custom SQLite extensions in your app is possible, but requires SDK and platform-specific setup steps.
Expand All @@ -30,7 +30,7 @@
<Warning>This is an advanced topic, and not directly supported by PowerSync.</Warning>

The `sqlite3` package provides [instructions](https://github.com/simolus3/sqlite3.dart/tree/main/sqlite3_wasm_build)
and cmake build scripts to compile `sqlite3.wasm`.

Check warning on line 33 in client-sdks/advanced/sqlite-extensions.mdx

View check run for this annotation

Mintlify / Mintlify Validation (powersync) - vale-spellcheck

client-sdks/advanced/sqlite-extensions.mdx#L33

Did you really mean 'cmake'?

The PowerSync Dart SDK [adopts that](https://github.com/powersync-ja/powersync.dart/tree/main/packages/sqlite3_wasm_build)
with [a patch](https://github.com/powersync-ja/powersync.dart/blob/main/packages/sqlite3_wasm_build/patches/0001-Link-PowerSync-core-extension.patch)
Expand Down Expand Up @@ -151,9 +151,9 @@
This entrypoint can then be called via [`sqlite3_auto_extension`](https://github.com/powersync-ja/powersync-kotlin/blob/cd8c6aede9f59f5c19fa2473798c1b2ccb035c3f/common/src/nativeMain/kotlin/com/powersync/ConnectionFactory.native.kt#L8-L14)
before opening PowerSync databases.

## .Net
## .NET

The PowerSync .NET SDK has builtin support for loading custom extensions by setting the `MDSQLiteOptions.Extensions` field to an array of `SqliteExtension` objects.
The PowerSync .NET SDK has builtin support for loading custom extensions by setting the [`MDSQLiteOptions.Extensions`](https://powersync-ja.github.io/powersync-dotnet/api/PowerSync.Common.MDSQLite.MDSQLiteOptions.Extensions.html) field to an array of [`SqliteExtension`](https://powersync-ja.github.io/powersync-dotnet/api/PowerSync.Common.MDSQLite.SqliteExtension.html) objects.

You can also disable loading the [core PowerSync SQLite extension](https://github.com/powersync-ja/powersync-sqlite-core) by setting `MDSQLiteOptions.LoadPowerSyncExtension` to false. When doing so, you must ensure that one of the extensions passed in `MDSQLiteOptions.Extensions` contains a build of the PowerSync core extension.

Expand Down
6 changes: 6 additions & 0 deletions client-sdks/reference/dotnet-api.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
title: ".NET SDK API Reference"
sidebarTitle: "API Reference"
description: "Full API reference for the PowerSync .NET SDK."
url: https://powersync-ja.github.io/powersync-dotnet/api/PowerSync.html
---
20 changes: 10 additions & 10 deletions client-sdks/reference/dotnet.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ import LocalOnly from '/snippets/local-only-escape.mdx';
Refer to the `powersync-dotnet` repo on GitHub
</Card>

<Card title="API Reference (Coming soon)" icon="book">
A full API Reference for this SDK is not yet available. This is planned for a future release.
<Card title="API Reference" icon="book" href="https://powersync-ja.github.io/powersync-dotnet/api/PowerSync.html">
Full API reference for the SDK
</Card>

<Card title="Example Projects" icon="code" href="/intro/examples">
Expand Down Expand Up @@ -78,7 +78,7 @@ The types available are `text`, `integer` and `real`. These should map directly

There are two supported syntaxes for defining the schema:

**Attribute-based (recommended)** — Annotate a C# class with `[Table]`, `[Column]`, and `[Index]` attributes. The same class can then be used directly as the result type in queries, so you define your data structure once:
**Attribute-based (recommended)** — Annotate a C# class with [`[Table]`](https://powersync-ja.github.io/powersync-dotnet/api/PowerSync.Common.DB.Schema.Attributes.TableAttribute.html), [`[Column]`](https://powersync-ja.github.io/powersync-dotnet/api/PowerSync.Common.DB.Schema.Attributes.ColumnAttribute.html), and [`[Index]`](https://powersync-ja.github.io/powersync-dotnet/api/PowerSync.Common.DB.Schema.Attributes.IndexAttribute.html) attributes. The same class can then be used directly as the result type in queries, so you define your data structure once:

```cs
using PowerSync.Common.DB.Schema;
Expand Down Expand Up @@ -206,8 +206,8 @@ The PowerSync backend connector provides the connection between your application

Accordingly, the connector must implement two methods:

1. [PowerSyncBackendConnector.FetchCredentials](https://github.com/powersync-ja/powersync-dotnet/blob/main/demos/CommandLine/NodeConnector.cs#L50) - This method is automatically invoked by the PowerSync Client SDK to obtain authentication credentials. The SDK caches credentials internally and only calls this method when needed (e.g. on initial connection or when the token is near expiry). See [When `fetchCredentials()` is Called](/configuration/app-backend/client-side-integration#when-fetchcredentials-is-called) for details, and [Authentication Setup](/configuration/auth/overview) for instructions on how the credentials should be generated.
2. [PowerSyncBackendConnector.UploadData](https://github.com/powersync-ja/powersync-dotnet/blob/main/demos/CommandLine/NodeConnector.cs#L72) - This method will be automatically invoked by the PowerSync Client SDK whenever it needs to upload client-side writes to your app's backend API. You need to implement how those writes are processed and uploaded in this method. See [When `uploadData()` is Called](/configuration/app-backend/client-side-integration#when-uploaddata-is-called) for details on triggers, throttling, and retry behavior, and [Writing Client Changes](/handling-writes/writing-client-changes) for considerations on the app backend implementation.
1. [IPowerSyncBackendConnector.FetchCredentials](https://powersync-ja.github.io/powersync-dotnet/api/PowerSync.Common.Client.Connection.IPowerSyncBackendConnector.FetchCredentials.html) - This method is automatically invoked by the PowerSync Client SDK to obtain authentication credentials. The SDK caches credentials internally and only calls this method when needed (e.g. on initial connection or when the token is near expiry). See [When `fetchCredentials()` is Called](/configuration/app-backend/client-side-integration#when-fetchcredentials-is-called) for details, and [Authentication Setup](/configuration/auth/overview) for instructions on how the credentials should be generated.
2. [IPowerSyncBackendConnector.UploadData](https://powersync-ja.github.io/powersync-dotnet/api/PowerSync.Common.Client.Connection.IPowerSyncBackendConnector.UploadData.html) - This method will be automatically invoked by the PowerSync Client SDK whenever it needs to upload client-side writes to your app's backend API. You need to implement how those writes are processed and uploaded in this method. See [When `uploadData()` is Called](/configuration/app-backend/client-side-integration#when-uploaddata-is-called) for details on triggers, throttling, and retry behavior, and [Writing Client Changes](/handling-writes/writing-client-changes) for considerations on the app backend implementation.

**Example**:

Expand Down Expand Up @@ -322,7 +322,7 @@ public class MyConnector : IPowerSyncBackendConnector
}
```

With your database instantiated and your connector ready, call `connect` to start syncing data with your backend:
With your database instantiated and your connector ready, call [`Connect`](https://powersync-ja.github.io/powersync-dotnet/api/PowerSync.Common.Client.PowerSyncDatabase.Connect.html) to start syncing data with your backend:

```cs
await db.Connect(new MyConnector());
Expand All @@ -337,10 +337,10 @@ Once the PowerSync instance is configured you can start using the SQLite DB func

The most commonly used CRUD functions to interact with your SQLite data are:

- `PowerSyncDatabase.Get` - get (SELECT) a single row from a table.
- `PowerSyncDatabase.GetAll` - get (SELECT) a set of rows from a table.
- `PowerSyncDatabase.Watch` - execute a read query every time source tables are modified.
- `PowerSyncDatabase.Execute` - execute a write (INSERT/UPDATE/DELETE) query.
- [`PowerSyncDatabase.Get`](https://powersync-ja.github.io/powersync-dotnet/api/PowerSync.Common.Client.PowerSyncDatabase.Get.html) - get (SELECT) a single row from a table.
- [`PowerSyncDatabase.GetAll`](https://powersync-ja.github.io/powersync-dotnet/api/PowerSync.Common.Client.PowerSyncDatabase.GetAll.html) - get (SELECT) a set of rows from a table.
- [`PowerSyncDatabase.Watch`](https://powersync-ja.github.io/powersync-dotnet/api/PowerSync.Common.Client.PowerSyncDatabase.Watch.html) - execute a read query every time source tables are modified.
- [`PowerSyncDatabase.Execute`](https://powersync-ja.github.io/powersync-dotnet/api/PowerSync.Common.Client.PowerSyncDatabase.Execute.html) - execute a write (INSERT/UPDATE/DELETE) query.

### Fetching a Single Item

Expand Down
32 changes: 13 additions & 19 deletions client-sdks/usage-examples.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ description: "Code examples and common patterns for the PowerSync Client SDKs."

import FlutterWatch from '/snippets/flutter/basic-watch-query.mdx';
import SwiftWatch from '/snippets/swift/basic-watch-query.mdx';
import DotNetWatch from '/snippets/dotnet/basic-watch-query.mdx';
import KotlinWatch from '/snippets/kotlin/basic-watch-query.mdx';
import RustWatch from '/snippets/rust/basic-watch-query.mdx';
import JavaScriptAsyncWatch from '/snippets/basic-watch-query-javascript-async.mdx';
Expand Down Expand Up @@ -222,6 +223,8 @@ import JavaScriptCallbackWatch from '/snippets/basic-watch-query-javascript-call
}
}
```

Also see [`ReadTransaction`](https://powersync-ja.github.io/powersync-dotnet/api/PowerSync.Common.Client.PowerSyncDatabase.ReadTransaction.html).
</Tab>
<Tab title="Rust">
Example not yet available.
Expand Down Expand Up @@ -313,21 +316,7 @@ import JavaScriptCallbackWatch from '/snippets/basic-watch-query-javascript-call
<Tab title=".NET">
Use `db.Watch()` to watch queries for changes. `Watch` returns an `IAsyncEnumerable` (since v0.0.11-alpha.1).

```cs
using PowerSync.Common.Client;

// Watch for changes (define a result type matching your query, e.g. ListResult)
var cts = new CancellationTokenSource();
var listener = db.Watch<ListResult>("SELECT * FROM lists", [], new SQLWatchOptions { Signal = cts.Token });

await foreach (var results in listener)
{
// Update UI when data changes
Console.WriteLine($"Result count: {results.Length}");
}

// To cancel watching: cts.Cancel();
```
<DotNetWatch />
</Tab>

<Tab title="Rust">
Expand Down Expand Up @@ -944,7 +933,7 @@ import JavaScriptCallbackWatch from '/snippets/basic-watch-query-javascript-call
</Tab>

<Tab title=".NET">
Use [SyncStatus](https://github.com/powersync-ja/powersync-dotnet/blob/main/PowerSync/PowerSync.Common/DB/Crud/SyncStatus.cs) and `db.Events.OnStatusChanged.ListenAsync` (since v0.0.11-alpha.1) to listen for status changes to your PowerSync instance.
Use [SyncStatus](https://powersync-ja.github.io/powersync-dotnet/api/PowerSync.Common.DB.Crud.SyncStatus.html) and `db.Events.OnStatusChanged.ListenAsync` (since v0.0.11-alpha.1) to listen for status changes to your PowerSync instance.

```cs
using PowerSync.Common.Client;
Expand Down Expand Up @@ -1166,7 +1155,7 @@ import JavaScriptCallbackWatch from '/snippets/basic-watch-query-javascript-call
</Tab>

<Tab title=".NET">
Use the [HasSynced](https://github.com/powersync-ja/powersync-dotnet/blob/main/PowerSync/PowerSync.Common/DB/Crud/SyncStatus.cs) property (available since version 0.0.6-alpha.1 of the SDK) to indicate to the user whether the initial sync is in progress.
Use the [HasSynced](https://powersync-ja.github.io/powersync-dotnet/api/PowerSync.Common.DB.Crud.SyncStatus.HasSynced.html) property (available since version 0.0.6-alpha.1 of the SDK) to indicate to the user whether the initial sync is in progress.

```cs
using PowerSync.Common.Client;
Expand Down Expand Up @@ -1463,11 +1452,11 @@ import JavaScriptCallbackWatch from '/snippets/basic-watch-query-javascript-call
Also see:
- [SyncStatusData API](https://powersync-ja.github.io/powersync-swift/documentation/powersync/syncstatusdata/)
- [SyncDownloadProgress API](https://powersync-ja.github.io/powersync-swift/documentation/powersync/syncdownloadprogress/)
- [Demo component](https://github.com/powersync-ja/powersync-swift/blob/main/Demo/PowerSyncExample/Components/ListView.swift)
- [Demo component](https://github.com/powersync-ja/powersync-swift/blob/main/Demos/PowerSyncExample/PowerSyncExample/Components/ListView.swift)
</Tab>

<Tab title=".NET">
You can show users a progress bar when data downloads using the `DownloadProgress()` method from the [SyncStatus](https://github.com/powersync-ja/powersync-dotnet/blob/main/PowerSync/PowerSync.Common/DB/Crud/SyncStatus.cs) class. `DownloadProgress().DownloadedFraction` gives you a value from 0.0 to 1.0 representing the total sync progress. This is especially useful for long-running initial syncs.
You can show users a progress bar when data downloads using the `DownloadProgress()` method from the [SyncStatus](https://powersync-ja.github.io/powersync-dotnet/api/PowerSync.Common.DB.Crud.SyncStatus.html) class. `DownloadProgress().DownloadedFraction` gives you a value from 0.0 to 1.0 representing the total sync progress. This is especially useful for long-running initial syncs.

<Note>
**Version compatibility**: The `DownloadProgress()` method is available since version 0.0.6-alpha.1 of the SDK. The event listener uses `db.Events.OnStatusChanged.ListenAsync` (since v0.0.11-alpha.1).
Expand Down Expand Up @@ -1530,6 +1519,11 @@ import JavaScriptCallbackWatch from '/snippets/basic-watch-query-javascript-call
}
}
```

Also see:
- [SyncStatus API](https://powersync-ja.github.io/powersync-dotnet/api/PowerSync.Common.DB.Crud.SyncStatus.html)
- [SyncProgress API](https://powersync-ja.github.io/powersync-dotnet/api/PowerSync.Common.DB.Crud.SyncProgress.html)
- [Demo component](https://github.com/powersync-ja/powersync-dotnet/blob/main/demos/MAUITodo/Views/ListsPage.xaml.cs)
</Tab>
<Tab title="Rust">
Example not yet available.
Expand Down
5 changes: 4 additions & 1 deletion docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,10 @@
{
"group": ".NET",
"icon": "microsoft",
"pages": ["client-sdks/reference/dotnet"]
"pages": [
"client-sdks/reference/dotnet",
"client-sdks/reference/dotnet-api"
]
},
{
"group": "Rust",
Expand Down
28 changes: 21 additions & 7 deletions intro/setup-guide.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -1201,15 +1201,29 @@ Read data using SQL queries. The data comes from your client-side SQLite databas
// Use db.GetAll() to fetch all rows:
var lists = await db.GetAll<ListResult>("SELECT * FROM lists");

// Watch for changes to query results
var query = await db.Watch("SELECT * FROM lists", null, new WatchHandler<ListResult>
// Watch for changes to query results:
// Register listener synchronously on the calling thread...
var cts = new CancellationTokenSource();
var listener = db.Watch<ListResult>("SELECT * FROM lists", null, new SQLWatchOptions { Signal = cts.Token });

// ...then listen to changes on another thread (or await foreach directly if already in an async context)
_ = Task.Run(async () =>
{
OnResult = (results) => Console.WriteLine($"Lists updated: {results.Length} items"),
OnError = (error) => Console.WriteLine($"Error: {error.Message}")
});
try
{
await foreach (var results in listener)
{
Console.WriteLine($"Lists updated: {results.Length} items");
}
}
catch (Exception e)
{
Console.WriteLine($"Error: {e.Message}");
}
}, cts.Token);

// Call query.Dispose() to stop watching for updates
query.Dispose();
// To stop watching, cancel the token:
cts.Cancel();
```

```rust Rust
Expand Down