Get new wasm implementation working in Chrome

This commit is contained in:
Simon Binder 2023-05-31 22:48:29 +02:00
parent d79633ee6b
commit ff41de2a6b
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
11 changed files with 52 additions and 48 deletions

View File

@ -11,6 +11,7 @@ import 'dart:async';
import 'dart:html';
import 'package:async/async.dart';
import 'package:drift/drift.dart';
import 'package:drift/remote.dart';
import 'package:drift/wasm.dart';
import 'package:js/js.dart';
@ -59,7 +60,7 @@ Future<WasmDatabaseResult> openWasmDatabase({
final port = sharedWorker.port!;
final sharedMessages =
StreamQueue(port.onMessage.map(WasmInitializationMessage.fromJs));
StreamQueue(port.onMessage.map(WasmInitializationMessage.read));
// First, the shared worker will tell us which features it supports.
final sharedFeatures = await sharedMessages.next as SharedWorkerStatus;
@ -82,7 +83,7 @@ Future<WasmDatabaseResult> openWasmDatabase({
DedicatedWorkerCompatibilityCheck().sendToWorker(dedicatedWorker);
final workerMessages = StreamQueue(
dedicatedWorker.onMessage.map(WasmInitializationMessage.fromJs));
dedicatedWorker.onMessage.map(WasmInitializationMessage.read));
final status =
await workerMessages.next as DedicatedWorkerCompatibilityResult;
@ -103,7 +104,9 @@ Future<WasmDatabaseResult> openWasmDatabase({
sqlite3.registerVirtualFileSystem(InMemoryFileSystem());
return WasmDatabaseResult(
WasmDatabase(sqlite3: sqlite3, path: '/app.db'),
DatabaseConnection(
WasmDatabase(sqlite3: sqlite3, path: '/app.db'),
),
WasmStorageImplementation.inMemory,
missingFeatures,
);

View File

@ -15,7 +15,7 @@ sealed class WasmInitializationMessage {
factory WasmInitializationMessage.fromJs(Object jsObject) {
final type = getProperty<String>(jsObject, 'type');
final payload = getProperty<String>(jsObject, 'payload');
final payload = getProperty<Object>(jsObject, 'payload');
return switch (type) {
SharedWorkerStatus.type => SharedWorkerStatus.fromJsPayload(payload),
@ -165,7 +165,7 @@ final class DedicatedWorkerCompatibilityCheck
@override
void _send(_PostMessage sender) {
sender.sendTyped(type, null);
sender.sendTyped(type, newObject());
}
}

View File

@ -11,12 +11,17 @@
@experimental
library drift.wasm;
import 'dart:html';
import 'package:meta/meta.dart';
import 'package:sqlite3/wasm.dart';
import 'backends.dart';
import 'drift.dart';
import 'src/sqlite3/database.dart';
import 'src/web/wasm_setup.dart';
import 'src/web/wasm_setup/dedicated_worker.dart';
import 'src/web/wasm_setup/shared_worker.dart';
/// Signature of a function that can perform setup work on a [database] before
/// drift is fully ready.
@ -76,6 +81,16 @@ class WasmDatabase extends DelegatedDatabase {
driftWorkerUri: driftWorkerUri,
);
}
static void workerMainForOpen() {
final self = WorkerGlobalScope.instance;
if (self is DedicatedWorkerGlobalScope) {
DedicatedDriftWorker(self).start();
} else if (self is SharedWorkerGlobalScope) {
SharedDriftWorker(self).start();
}
}
}
class _WasmDelegate extends Sqlite3Delegate<CommonDatabase> {
@ -225,7 +240,7 @@ enum MissingBrowserFeature {
}
class WasmDatabaseResult {
final QueryExecutor resolvedExecutor;
final DatabaseConnection resolvedExecutor;
final WasmStorageImplementation chosenImplementation;
final Set<MissingBrowserFeature> missingFeatures;

View File

@ -1,15 +1,5 @@
import 'dart:async';
import 'dart:html';
import 'package:drift/wasm.dart';
import 'package:drift/src/web/wasm_setup/dedicated_worker.dart';
import 'package:drift/src/web/wasm_setup/shared_worker.dart';
Future<void> main() async {
final self = WorkerGlobalScope.instance;
if (self is DedicatedWorkerGlobalScope) {
DedicatedDriftWorker(self).start();
} else if (self is SharedWorkerGlobalScope) {
SharedDriftWorker(self).start();
}
void main() {
WasmDatabase.workerMainForOpen();
}

View File

@ -30,7 +30,7 @@
.pub-cache/
.pub/
/build/
web/shared_worker.dart.js
web/drift_worker.js
# Web related

View File

@ -50,4 +50,4 @@ builders:
import: 'tool/builder.dart'
builder_factories: ["CopyCompiledJs.new"]
build_to: source
build_extensions: {'web/worker.dart.js': ['web/shared_worker.dart.js']}
build_extensions: {'web/worker.dart.js': ['web/drift_worker.js']}

View File

@ -2,31 +2,24 @@ import 'dart:async';
import 'package:drift/drift.dart';
import 'package:drift/wasm.dart';
import 'package:drift/web/worker.dart';
import 'package:sqlite3/wasm.dart';
const _useWorker = true;
import 'package:flutter/foundation.dart';
/// Obtains a database connection for running drift on the web.
DatabaseConnection connect({bool isInWebWorker = false}) {
if (_useWorker && !isInWebWorker) {
return DatabaseConnection.delayed(connectToDriftWorker(
'shared_worker.dart.js',
mode: DriftWorkerMode.shared));
} else {
return DatabaseConnection.delayed(
Future.sync(() async {
final fs = await IndexedDbFileSystem.open(dbName: 'my_app');
final sqlite3 = await WasmSqlite3.loadFromUrl(
Uri.parse('sqlite3.wasm'),
environment: SqliteEnvironment(fileSystem: fs),
);
final databaseImpl = WasmDatabase(sqlite3: sqlite3, path: 'app.db');
return DatabaseConnection(databaseImpl);
}),
DatabaseConnection connect() {
return DatabaseConnection.delayed(Future(() async {
final db = await WasmDatabase.open(
databaseName: 'todo-app',
sqlite3Uri: Uri.parse('/sqlite3.wasm'),
driftWorkerUri: Uri.parse('/drift_worker.js'),
);
}
if (db.missingFeatures.isNotEmpty) {
debugPrint('Using ${db.chosenImplementation} due to unsupported '
'browser features: ${db.missingFeatures}');
}
return db.resolvedExecutor;
}));
}
Future<void> validateDatabaseSchema(GeneratedDatabase database) async {

View File

@ -19,7 +19,7 @@ dependencies:
intl: ^0.18.0
http: ^0.13.4 # used to load sqlite3 wasm files on the web
sqlite3_flutter_libs: ^0.5.5
sqlite3: ^1.11.0
sqlite3: ^2.0.0-dev.0
path_provider: ^2.0.9
path: ^1.8.0
riverpod: ^2.3.0
@ -39,3 +39,7 @@ dev_dependencies:
flutter:
uses-material-design: true
dependency_overrides:
sqlite3:
path: /home/simon/src/sqlite3.dart/sqlite3

View File

@ -15,6 +15,6 @@ class CopyCompiledJs extends Builder {
@override
Map<String, List<String>> get buildExtensions => {
r'$package$': ['web/shared_worker.dart.js']
r'$package$': ['web/drift_worker.js']
};
}

View File

@ -1,10 +1,9 @@
import 'package:app/database/connection/web.dart';
import 'package:drift/web/worker.dart';
import 'package:drift/wasm.dart';
/// This Dart program is the entrypoint of a web worker that will be compiled to
/// JavaScript by running `build_runner build`. The resulting JavaScript file
/// (`shared_worker.dart.js`) is part of the build result and will be shipped
/// with the rest of the application when running or building a Flutter web app.
void main() {
return driftWorkerMain(() => connect(isInWebWorker: true));
return WasmDatabase.workerMainForOpen();
}

Binary file not shown.