Skip to content

Commit

Permalink
Update docs on code sharing between native and web
Browse files Browse the repository at this point in the history
Closes #3447
  • Loading branch information
simolus3 committed Feb 2, 2025
1 parent bda5276 commit 35e16a5
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 17 deletions.
76 changes: 59 additions & 17 deletions docs/docs/Platforms/web.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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(/* ... */)
Expand All @@ -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
Expand All @@ -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)
Expand Down
13 changes: 13 additions & 0 deletions docs/lib/snippets/platforms/web.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -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 {
Expand Down

0 comments on commit 35e16a5

Please sign in to comment.