diff --git a/docs/docs/Platforms/web.md b/docs/docs/Platforms/web.md index 568101fbf..74e44efd8 100644 --- a/docs/docs/Platforms/web.md +++ b/docs/docs/Platforms/web.md @@ -17,7 +17,7 @@ description: Drift support in Flutter and Dart web apps. Using modern browser APIs such as WebAssembly and the Origin-Private File System API, you can use drift databases for the web version of your Flutter and Dart applications. Just like the core drift APIs, web support is platform-agnostic: -Drift web supports Flutter Web, AngularDart, plain `dart:html` or any other Dart web framework. +Drift web supports Flutter Web, AngularDart, jaspr, plain `package:web/` or any other Dart web framework. While an official sqlite3 build for the web exists, it is fairly large and doesn't support most browsers. Drift uses a custom sqlite3 build with a Dart interface sharing a lot of code with the existing native @@ -145,34 +145,48 @@ Also, note that the `sqlite3.wasm` file needs to be served with a `Content-Type` If the headers break your app, you should not enable them - drift will fall back to another (potentially slower) implementation in that case. - - - ### Setup in Dart From a perspective of the Dart code used, drift on the web is similar to drift on other platforms. You can follow the [getting started guide](../setup.md) as a general setup guide. -Instead of using a `NativeDatabase` in your database classes, you can use the `WasmDatabase` optimized for -the web: +=== "Flutter (sqlite3)" + + If you're using `package:drift_flutter` to setup your database, you enable web support by passing + `DriftWebOptions` with URIs to the WebAssembly module and the drift worker: + + {{ load_snippet('flutter','lib/snippets/platforms/web.dart.excerpt.json',indent=4) }} + + If you need more control on how you're opening web databases (e.g. to prefer certain storage + APIs, see the manual setup for Dart in the next tab). + +=== "Dart (sqlite3)" -{{ load_snippet('connect','lib/snippets/platforms/web.dart.excerpt.json') }} + Instead of using a `NativeDatabase` in your database classes, you can use the `WasmDatabase` optimized + for the web: -When you call `WasmDatabase.open`, drift will automatically find a suitable persistence implementation -supported by the current browser. + {{ load_snippet('connect','lib/snippets/platforms/web.dart.excerpt.json',indent=4) }} + + When you call `WasmDatabase.open`, drift will automatically find a suitable persistence implementation + supported by the current browser. A full example that works on the web (and all other platforms supported by drift) is available [here](https://github.com/simolus3/drift/tree/develop/examples/app). -## Sharing code between native apps and web +## Manual code sharing between native apps and web + +`package:drift_flutter` provides a single method to open databases that works both for native and +web apps. -If you want to share your database code between native applications and web apps, import only the +If you're not using that package, e.g. because you need more control on how you're opening databases, +you can still support all platforms with a single codebase. +To share your database code between native applications and web apps, import only the core `package:drift/drift.dart` library into your database file. -And instead of passing a `NativeDatabase` or `WebDatabase` to the `super` constructor, make the -`QueryExecutor` customizable: +And instead of passing a `NativeDatabase` or `WasmDatabase` to the `super` constructor of the generated +database class, ensure that the `QueryExecutor` is customizable, like shown here: ```dart -// don't import drift/web.dart or drift/native.dart in shared code +// don't import drift/wasm.dart or drift/native.dart in shared code import 'package:drift/drift.dart'; @DriftDatabase(/* ... */) @@ -181,7 +195,15 @@ class SharedDatabase extends _$SharedDatabase { } ``` -In native Flutter apps, you can create an instance of your database with +Next, set up conditional exports to open your database by creating the following files: + +1. `native.dart`, which will contain the native implementation. +2. `web.dart`, for web support. +3. `unsupported.dart`, as a stub library to set up conditional exports. +4. `shared.dart`, which will contain the conditional exports. + +In native Flutter apps, you can create an instance of your database with a snippet like this +(also explained further in [the setup guide](../setup.md#open)): ```dart // native.dart @@ -197,15 +219,35 @@ SharedDatabase constructDb() { } ``` -On the web, you can use +On the web, you can use: ```dart // web.dart -import 'package:drift/web.dart'; +import 'package:drift/wasm.dart'; SharedDatabase constructDb() { return SharedDatabase(connectOnWeb()); } + +DatabaseConnection connectOnWeb() { + return DatabaseConnection.delayed(Future(() async { + final result = await WasmDatabase.open( + databaseName: 'my_app_db', // prefer to only use valid identifiers here + sqlite3Uri: Uri.parse('sqlite3.wasm'), + driftWorkerUri: Uri.parse('drift_worker.dart.js'), + ); + + if (result.missingFeatures.isNotEmpty) { + // Depending how central local persistence is to your app, you may want + // to show a warning to the user if only unrealiable implemetentations + // are available. + print('Using ${result.chosenImplementation} due to missing browser ' + 'features: ${result.missingFeatures}'); + } + + return result.resolvedExecutor; + })); +} ``` Finally, we can use [conditional imports](https://dart.dev/guides/libraries/create-library-packages#conditionally-importing-and-exporting-library-files) diff --git a/docs/lib/snippets/platforms/web.dart b/docs/lib/snippets/platforms/web.dart index 1e137c8b8..059a0b2ad 100644 --- a/docs/lib/snippets/platforms/web.dart +++ b/docs/lib/snippets/platforms/web.dart @@ -2,6 +2,7 @@ import 'package:drift/drift.dart'; import 'package:drift/wasm.dart'; // ignore: deprecated_member_use import 'package:drift/web.dart'; +import 'package:drift_flutter/drift_flutter.dart'; import 'package:flutter/services.dart'; import 'package:sqlite3/wasm.dart'; @@ -46,6 +47,18 @@ class MyWebDatabase extends _$MyWebDatabase { } // #enddocregion connect +// #docregion flutter +QueryExecutor connectWithDriftFlutter() { + return driftDatabase( + name: 'my_app_db', + web: DriftWebOptions( + sqlite3Wasm: Uri.parse('sqlite3.wasm'), + driftWorker: Uri.parse('drift_worker.dart.js'), + ), + ); +} +// #enddocregion flutter + DatabaseConnection connectWithExisting() { // #docregion existing return DatabaseConnection.delayed(Future(() async {