diff --git a/client-sdks/advanced/attachments.mdx b/client-sdks/advanced/attachments.mdx index 6490d829..10c809d7 100644 --- a/client-sdks/advanced/attachments.mdx +++ b/client-sdks/advanced/attachments.mdx @@ -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) | Most demo applications use Supabase Storage as the storage provider, but the patterns are adaptable to any storage system. @@ -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 ---- \ No newline at end of file +--- diff --git a/client-sdks/advanced/sqlite-extensions.mdx b/client-sdks/advanced/sqlite-extensions.mdx index ce95c3f9..6652842b 100644 --- a/client-sdks/advanced/sqlite-extensions.mdx +++ b/client-sdks/advanced/sqlite-extensions.mdx @@ -151,9 +151,9 @@ building the extension as a library and making its entrypoint available from Kot 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. diff --git a/client-sdks/reference/dotnet-api.mdx b/client-sdks/reference/dotnet-api.mdx new file mode 100644 index 00000000..388fd57d --- /dev/null +++ b/client-sdks/reference/dotnet-api.mdx @@ -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 +--- diff --git a/client-sdks/reference/dotnet.mdx b/client-sdks/reference/dotnet.mdx index 5242b38d..2468045e 100644 --- a/client-sdks/reference/dotnet.mdx +++ b/client-sdks/reference/dotnet.mdx @@ -19,8 +19,8 @@ import LocalOnly from '/snippets/local-only-escape.mdx'; Refer to the `powersync-dotnet` repo on GitHub - - A full API Reference for this SDK is not yet available. This is planned for a future release. + + Full API reference for the SDK @@ -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; @@ -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**: @@ -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()); @@ -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 diff --git a/client-sdks/usage-examples.mdx b/client-sdks/usage-examples.mdx index 330cbc9f..f512eafa 100644 --- a/client-sdks/usage-examples.mdx +++ b/client-sdks/usage-examples.mdx @@ -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'; @@ -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). Example not yet available. @@ -313,21 +316,7 @@ import JavaScriptCallbackWatch from '/snippets/basic-watch-query-javascript-call 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("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(); - ``` + @@ -944,7 +933,7 @@ import JavaScriptCallbackWatch from '/snippets/basic-watch-query-javascript-call - 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; @@ -1166,7 +1155,7 @@ import JavaScriptCallbackWatch from '/snippets/basic-watch-query-javascript-call - 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; @@ -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) - 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. **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). @@ -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) Example not yet available. diff --git a/docs.json b/docs.json index 889dcd9b..e2f1037b 100644 --- a/docs.json +++ b/docs.json @@ -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", diff --git a/intro/setup-guide.mdx b/intro/setup-guide.mdx index a8e6aca5..9967aaab 100644 --- a/intro/setup-guide.mdx +++ b/intro/setup-guide.mdx @@ -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("SELECT * FROM lists"); - // Watch for changes to query results - var query = await db.Watch("SELECT * FROM lists", null, new WatchHandler + // Watch for changes to query results: + // Register listener synchronously on the calling thread... + var cts = new CancellationTokenSource(); + var listener = db.Watch("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