Skip to content

Commit

Permalink
[sqflite_common_ffi_web] remove dependency on dart.html
Browse files Browse the repository at this point in the history
  • Loading branch information
alextekartik committed Mar 16, 2024
1 parent 4f84ab0 commit 930f764
Show file tree
Hide file tree
Showing 27 changed files with 345 additions and 421 deletions.
7 changes: 4 additions & 3 deletions packages_web/sqflite_common_ffi_web/example/main.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import 'dart:async';
import 'dart:html' as html;
import 'dart:math';
import 'dart:typed_data';

Expand All @@ -9,6 +8,7 @@ import 'package:sqflite_common_ffi_web/sqflite_ffi_web.dart';
import 'package:sqflite_common_ffi_web/src/sw/constants.dart';
import 'package:sqflite_common_ffi_web/src/web/load_sqlite_web.dart'
show SqfliteFfiWebContextExt;
import 'package:web/web.dart' as web;

import 'ui.dart';

Expand Down Expand Up @@ -111,8 +111,9 @@ Future incrementNoWebWorker() async {
}

Future<void> main() async {
// sqliteFfiWebDebugWebWorker = true;
initUi();
// sqliteFfiWebDebugWebWorker = devWarning(true);

write('$_shc running $_debugVersion');
// devWarning(incrementVarInSharedWorker());
// await devWarning(bigInt());
Expand All @@ -129,7 +130,7 @@ Future<void> main() async {

var _webContextRegisterAndReady = sqfliteFfiWebStartSharedWorker(swOptions);

Future<html.SharedWorker> sharedWorkerRegisterAndReady() async =>
Future<web.SharedWorker> sharedWorkerRegisterAndReady() async =>
(await _webContextRegisterAndReady).sharedWorker!;

Future<SqfliteFfiWebContext> webContextRegisterAndReady() async =>
Expand Down
2 changes: 0 additions & 2 deletions packages_web/sqflite_common_ffi_web/example/sw.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import 'package:sqflite_common_ffi_web/src/debug/debug.dart';
import 'package:sqflite_common_ffi_web/src/sw/shared_worker.dart';

void main(List<String> args) {
sqliteFfiWebDebugWebWorker = true; // devWarning(true);
mainSharedWorker(args);
}
8 changes: 4 additions & 4 deletions packages_web/sqflite_common_ffi_web/example/ui.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import 'dart:async';
import 'dart:html' as html;
import 'package:web/web.dart' as web;

var lines = <String>[];
var countLineMax = 100;
var _output = html.querySelector('#output')!;
var _input = html.querySelector('#input')!;
var _output = web.document.querySelector('#output')!;
var _input = web.document.querySelector('#input')!;
void write(String message) {
print(message);
lines.add(message);
Expand All @@ -15,7 +15,7 @@ void write(String message) {
}

void addButton(String text, FutureOr<void> Function() action) {
_input.append(html.ButtonElement()
_input.append((web.document.createElement('button') as web.HTMLButtonElement)
..innerText = text
..onClick.listen((event) async {
await action();
Expand Down
2 changes: 2 additions & 0 deletions packages_web/sqflite_common_ffi_web/lib/sqflite_ffi_web.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export 'src/database_factory.dart' show createDatabaseFactoryFfiWeb;
/// Debug only
export 'src/debug/debug.dart' show sqliteFfiWebDebugWebWorker;
export 'src/sqflite_ffi.dart'
show databaseFactoryFfiWeb, databaseFactoryFfiWebNoWebWorker;
export 'src/web/load_sqlite.dart'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import 'dart:html' as html;
import 'dart:js_interop';

import 'package:sqflite_common/sqlite_api.dart';
import 'package:sqflite_common_ffi_web/sqflite_ffi_web.dart';
import 'package:sqflite_common_ffi_web/src/debug/debug.dart';
import 'package:sqflite_common_ffi_web/src/sqflite_ffi_impl_web.dart'
show SqfliteFfiHandlerWeb;
import 'package:sqflite_common_ffi_web/src/utils.dart';
Expand All @@ -12,6 +11,7 @@ import 'package:sqflite_common_ffi_web/src/web/load_sqlite_web.dart'
SqfliteFfiWebWorkerException,
defaultSharedWorkerUri;
import 'package:synchronized/synchronized.dart';
import 'package:web/web.dart' as web;

import 'import.dart';

Expand Down Expand Up @@ -81,12 +81,13 @@ Future<dynamic> ffiMethodCallSendToWebWorker(
_log(st);
}
if (e is SqfliteFfiWebWorkerException) {
html.window.console.error('''
web.console.error('''
An error occurred while initializing the web worker.
This is likely due to a failure to find the worker javascript file at ${context.options.sharedWorkerUri ?? defaultSharedWorkerUri}
Please check the documentation at https://github.com/tekartik/sqflite/tree/master/packages_web/sqflite_common_ffi_web#setup-binaries to setup the needed binaries.
''');
'''
.toJS);
}
rethrow;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
import 'dart:async';
import 'dart:html' as html;
import 'dart:js_interop';
import 'dart:typed_data';

// ignore: implementation_imports
import 'package:sqflite_common/src/mixin/platform.dart';
import 'package:sqflite_common_ffi_web/sqflite_ffi_web.dart';
import 'package:sqflite_common_ffi_web/src/debug/debug.dart';
import 'package:sqflite_common_ffi_web/src/web/js_converter.dart';
import 'package:sqflite_common_ffi_web/src/web/load_sqlite_web.dart';
import 'package:sqlite3/wasm.dart';
import 'package:web/web.dart' as web;

import 'import.dart';

var _log = print;
import 'web/worker_message_utils.dart';

/// Database file system on sqlite virtual file system.
class SqfliteDatabaseFileSystemFfiWeb implements DatabaseFileSystem {
Expand All @@ -21,6 +19,7 @@ class SqfliteDatabaseFileSystemFfiWeb implements DatabaseFileSystem {

/// Database file system on sqlite virtual file system.
SqfliteDatabaseFileSystemFfiWeb(this.fs);

@override
Future<bool> databaseExists(String path) async {
var fs = this.fs;
Expand Down Expand Up @@ -93,12 +92,6 @@ class SqfliteDatabaseFileSystemFfiWeb implements DatabaseFileSystem {
}
}

bool get _debug => sqliteFfiWebDebugWebWorker;

/// Worker client log prefix for debug mode.
var workerClientLogPrefix = '/sw_client'; // Log prefix
var _swc = workerClientLogPrefix; // Log prefix

/// Ffi web handler for custom open/delete operation
class SqfliteFfiHandlerWeb extends SqfliteFfiHandler
with SqfliteFfiHandlerNonImplementedMixin {
Expand Down Expand Up @@ -174,88 +167,36 @@ class SqfliteFfiHandlerWeb extends SqfliteFfiHandler
}
}

/// Genereric Post message handler
abstract class RawMessageSender {
var _firstMessage = true;

/// Post message to implement
void postMessage(Object message, List<Object> transfer);

/// Returns response
Future<Object?> sendRawMessage(Object message) {
var completer = Completer<Object?>();
// This wraps the message posting/response in a promise, which will resolve if the response doesn't
// contain an error, and reject with the error if it does. If you'd prefer, it's possible to call
// controller.postMessage() and set up the onmessage handler independently of a promise, but this is
// a convenient wrapper.
var messageChannel = html.MessageChannel();
//var receivePort =ReceivePort();

if (_debug) {
_log('$_swc sending $message');
}
messageChannel.port1.onMessage.listen((event) {
if (_debug) {
_log('$_swc recv ${event.data}');
}
completer.complete(event.data);
});
// Let's handle initialization error on the first message.
if (_firstMessage) {
_firstMessage = false;
onError.listen((event) {
if (_debug) {
_log('$_swc error ${jsObjectAsMap(event)}');
}

if (!completer.isCompleted) {
completer.completeError(SqfliteFfiWebWorkerException());
}
});
}

// This sends the message data as well as transferring messageChannel.port2 to the shared worker.
// The shared worker can then use the transferred port to reply via postMessage(), which
// will in turn trigger the onmessage handler on messageChannel.port1.
// See https://html.spec.whatwg.org/multipage/workers.html#dom-worker-postmessage
postMessage(message, [messageChannel.port2]);
return completer.future;
}

/// Basic error handling, likely at initialization.
Stream<Object> get onError;
}

/// Post message sender to shared worker.
class RawMessageSenderSharedWorker extends RawMessageSender {
final html.SharedWorker _sharedWorker;

html.MessagePort get _port => _sharedWorker.port as html.MessagePort;

/// Post message sender to shared worker.
RawMessageSenderSharedWorker(this._sharedWorker);

@override
void postMessage(Object message, List<Object> transfer) {
_port.postMessage(message, transfer);
}

@override
Stream<Object> get onError => _sharedWorker.onError;
}

/// Post message sender to worker.
class RawMessageSenderToWorker extends RawMessageSender {
final html.Worker _worker;

@override
Stream<Object> get onError => _worker.onError;
final web.Worker _worker;

/// Post message sender to worker.
RawMessageSenderToWorker(this._worker);

@override
void postMessage(Object message, List<Object> transfer) {
_worker.postMessage(message, transfer);
void postMessage(Object message, web.MessagePort responsePort) {
_worker.postMessage(
message.jsify(), messagePortToPortMessageOption(responsePort));
}

StreamController<Object>? _errorController;

@override
Stream<Object> get onError {
if (_errorController == null) {
var zone = Zone.current;
_errorController = StreamController<Object>.broadcast(onListen: () {
_worker.onerror = (web.Event event) {
zone.run(() {
_errorController!.add(event);
});
}.toJS;
}, onCancel: () {
_errorController = null;
_worker.onerror = null;
});
}
return _errorController!.stream;
}
}
11 changes: 10 additions & 1 deletion packages_web/sqflite_common_ffi_web/lib/src/debug/debug.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,13 @@
import 'package:sqflite_common_ffi_web/src/import.dart';

/// For testing.
var sqliteFfiWebDebugWebWorker = false; // devWarning(true);
var _sqliteFfiWebDebugWebWorker = false; // devWarning(true);

/// Testing only.
bool get sqliteFfiWebDebugWebWorker => _sqliteFfiWebDebugWebWorker;

/// Testing only.
@Deprecated('testing only')
set sqliteFfiWebDebugWebWorker(bool value) {
_sqliteFfiWebDebugWebWorker = value;
}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export 'platform_io.dart' if (dart.library.js) 'platform_web.dart';
export 'platform_io.dart' if (dart.library.js_interop) 'platform_web.dart';
Original file line number Diff line number Diff line change
@@ -1,23 +1,13 @@
import 'dart:async';
import 'dart:html' as html;
import 'dart:typed_data';

import 'package:sqflite_common_ffi_web/sqflite_ffi_web.dart';
import 'package:sqflite_common_ffi_web/src/debug/debug.dart';
import 'package:sqflite_common_ffi_web/src/web/js_converter.dart';
import 'package:sqflite_common_ffi_web/src/web/load_sqlite_web.dart';
import 'package:sqlite3/wasm.dart';

import 'database_file_system_web.dart';
import 'import.dart';

var _log = print;
bool get _debug => sqliteFfiWebDebugWebWorker;

/// Worker client log prefix for debug mode.
var workerClientLogPrefix = '/sw_client'; // Log prefix
var _swc = workerClientLogPrefix; // Log prefix

/// Ffi web handler for custom open/delete operation
class SqfliteFfiHandlerWeb extends SqfliteFfiHandler
with SqfliteFfiHandlerNonImplementedMixin {
Expand Down Expand Up @@ -86,89 +76,3 @@ class SqfliteFfiHandlerWeb extends SqfliteFfiHandler
// No op
}
}

/// Genereric Post message handler
abstract class RawMessageSender {
var _firstMessage = true;

/// Post message to implement
void postMessage(Object message, List<Object> transfer);

/// Returns response
Future<Object?> sendRawMessage(Object message) {
var completer = Completer<Object?>();
// This wraps the message posting/response in a promise, which will resolve if the response doesn't
// contain an error, and reject with the error if it does. If you'd prefer, it's possible to call
// controller.postMessage() and set up the onmessage handler independently of a promise, but this is
// a convenient wrapper.
var messageChannel = html.MessageChannel();
//var receivePort =ReceivePort();

if (_debug) {
_log('$_swc sending $message');
}
messageChannel.port1.onMessage.listen((event) {
if (_debug) {
_log('$_swc recv ${event.data}');
}
completer.complete(event.data);
});
// Let's handle initialization error on the first message.
if (_firstMessage) {
_firstMessage = false;
onError.listen((event) {
if (_debug) {
_log('$_swc error ${jsObjectAsMap(event)}');
}

if (!completer.isCompleted) {
completer.completeError(SqfliteFfiWebWorkerException());
}
});
}

// This sends the message data as well as transferring messageChannel.port2 to the shared worker.
// The shared worker can then use the transferred port to reply via postMessage(), which
// will in turn trigger the onmessage handler on messageChannel.port1.
// See https://html.spec.whatwg.org/multipage/workers.html#dom-worker-postmessage
postMessage(message, [messageChannel.port2]);
return completer.future;
}

/// Basic error handling, likely at initialization.
Stream<Object> get onError;
}

/// Post message sender to shared worker.
class RawMessageSenderSharedWorker extends RawMessageSender {
final html.SharedWorker _sharedWorker;

html.MessagePort get _port => _sharedWorker.port as html.MessagePort;

/// Post message sender to shared worker.
RawMessageSenderSharedWorker(this._sharedWorker);

@override
void postMessage(Object message, List<Object> transfer) {
_port.postMessage(message, transfer);
}

@override
Stream<Object> get onError => _sharedWorker.onError;
}

/// Post message sender to worker.
class RawMessageSenderToWorker extends RawMessageSender {
final html.Worker _worker;

@override
Stream<Object> get onError => _worker.onError;

/// Post message sender to worker.
RawMessageSenderToWorker(this._worker);

@override
void postMessage(Object message, List<Object> transfer) {
_worker.postMessage(message, transfer);
}
}
Loading

0 comments on commit 930f764

Please sign in to comment.