diff --git a/packages_web/sqflite_common_ffi_web/example/main.dart b/packages_web/sqflite_common_ffi_web/example/main.dart index 586491f2..428fd95f 100644 --- a/packages_web/sqflite_common_ffi_web/example/main.dart +++ b/packages_web/sqflite_common_ffi_web/example/main.dart @@ -22,7 +22,10 @@ var swOptions = SqfliteFfiWebOptions( sharedWorkerUri: Uri.parse('sw.dart.js'), // ignore: invalid_use_of_visible_for_testing_member forceAsBasicWorker: _useBasicWebWorker); - +var swBasicOptions = SqfliteFfiWebOptions( + sharedWorkerUri: Uri.parse('sw.dart.js'), + // ignore: invalid_use_of_visible_for_testing_member + forceAsBasicWorker: true); Future incrementPrebuilt() async { await incrementSqfliteValueInDatabaseFactory(databaseFactoryWebPrebuilt, tag: 'prebuilt'); @@ -130,15 +133,22 @@ Future main() async { var _webContextRegisterAndReady = sqfliteFfiWebStartSharedWorker(swOptions); +var _webBasicContextRegisterAndReady = + sqfliteFfiWebStartSharedWorker(swBasicOptions); + Future sharedWorkerRegisterAndReady() async => (await _webContextRegisterAndReady).sharedWorker!; Future webContextRegisterAndReady() async => (await _webContextRegisterAndReady); +Future webBasicContextRegisterAndReady() async => + (await _webBasicContextRegisterAndReady); var databaseFactoryWebPrebuilt = databaseFactoryFfiWeb; var databaseFactoryWebNoWebWorkerLocal = databaseFactoryFfiWebNoWebWorker; var databaseFactoryWebLocal = createDatabaseFactoryFfiWeb(options: swOptions); +var databaseFactoryWebBasicWorkerLocal = + createDatabaseFactoryFfiWeb(options: swBasicOptions); var key = 'testValue'; @@ -171,6 +181,20 @@ Future incrementVarInSharedWorker() async { write('var after $value'); } +Future incrementVarInBasicdWorker() async { + var context = await webBasicContextRegisterAndReady(); + write('basic worker ready'); + var value = await getTestValue(context); + write('var before $value'); + if (value is! int) { + value = 0; + } + + await setTestValue(context, value + 1); + value = await getTestValue(context); + write('var after $value'); +} + Future incrementSqfliteValueInDatabaseFactory(DatabaseFactory factory, {String? tag}) async { tag ??= 'db'; @@ -221,6 +245,9 @@ void initUi() { addButton('increment var in shared worker', () async { await incrementVarInSharedWorker(); }); + addButton('increment var in basic worker', () async { + await incrementVarInBasicdWorker(); + }); addButton('increment sqflite value in main thread', () async { await incrementNoWebWorker(); }); diff --git a/packages_web/sqflite_common_ffi_web/lib/sqflite_ffi_web.dart b/packages_web/sqflite_common_ffi_web/lib/sqflite_ffi_web.dart index 4a4545ce..0b620086 100644 --- a/packages_web/sqflite_common_ffi_web/lib/sqflite_ffi_web.dart +++ b/packages_web/sqflite_common_ffi_web/lib/sqflite_ffi_web.dart @@ -1,7 +1,10 @@ export 'src/database_factory.dart' show createDatabaseFactoryFfiWeb; export 'src/debug/debug.dart' show sqliteFfiWebDebugWebWorker; export 'src/sqflite_ffi.dart' - show databaseFactoryFfiWeb, databaseFactoryFfiWebNoWebWorker; + show + databaseFactoryFfiWeb, + databaseFactoryFfiWebNoWebWorker, + databaseFactoryFfiWebBasicWebWorker; export 'src/web/load_sqlite.dart' show SqfliteFfiWebContext, diff --git a/packages_web/sqflite_common_ffi_web/lib/src/database_factory_web.dart b/packages_web/sqflite_common_ffi_web/lib/src/database_factory_web.dart index 692e094a..7623eba9 100644 --- a/packages_web/sqflite_common_ffi_web/lib/src/database_factory_web.dart +++ b/packages_web/sqflite_common_ffi_web/lib/src/database_factory_web.dart @@ -20,6 +20,13 @@ var databaseFactoryFfiWebNoWebWorkerImpl = () { return createDatabaseFactoryFfiWeb(noWebWorker: true); }(); +/// The Ffi database factory with basic worker +var databaseFactoryFfiWebBasicWorkerImpl = () { + return createDatabaseFactoryFfiWeb( + // ignore: invalid_use_of_visible_for_testing_member + options: SqfliteFfiWebOptions(forceAsBasicWorker: true)); +}(); + /// The Ffi database factory. var databaseFactoryFfiWebImpl = () { return createDatabaseFactoryFfiWeb(); diff --git a/packages_web/sqflite_common_ffi_web/lib/src/sqflite_ffi_io.dart b/packages_web/sqflite_common_ffi_web/lib/src/sqflite_ffi_io.dart index a7f672ab..168e1996 100644 --- a/packages_web/sqflite_common_ffi_web/lib/src/sqflite_ffi_io.dart +++ b/packages_web/sqflite_common_ffi_web/lib/src/sqflite_ffi_io.dart @@ -7,3 +7,8 @@ DatabaseFactory get databaseFactoryFfiWeb => throw UnsupportedError( /// The database factory to use for ffi web. not supported on io DatabaseFactory get databaseFactoryFfiWebNoWebWorker => throw UnsupportedError( 'databaseFactoryFfiWebNoWebWorker only supported on io'); + +/// The database factory to use for ffi web. not supported on io +DatabaseFactory get databaseFactoryFfiWebBasicWebWorker => + throw UnsupportedError( + 'databaseFactoryFfiWebBasicWebWorker only supported on io'); diff --git a/packages_web/sqflite_common_ffi_web/lib/src/sqflite_ffi_web.dart b/packages_web/sqflite_common_ffi_web/lib/src/sqflite_ffi_web.dart index 4a0154a7..b5f9a31b 100644 --- a/packages_web/sqflite_common_ffi_web/lib/src/sqflite_ffi_web.dart +++ b/packages_web/sqflite_common_ffi_web/lib/src/sqflite_ffi_web.dart @@ -18,3 +18,7 @@ DatabaseFactory get databaseFactoryFfiWeb => databaseFactoryFfiWebImpl; /// Run in the main ui thread so long query could potentially hang. DatabaseFactory get databaseFactoryFfiWebNoWebWorker => databaseFactoryFfiWebNoWebWorkerImpl; + +/// Testing only. +DatabaseFactory get databaseFactoryFfiWebBasicWebWorker => + databaseFactoryFfiWebBasicWorkerImpl; diff --git a/packages_web/sqflite_common_ffi_web/lib/src/sw/shared_worker.dart b/packages_web/sqflite_common_ffi_web/lib/src/sw/shared_worker.dart index 1bc0fae5..6a49622c 100644 --- a/packages_web/sqflite_common_ffi_web/lib/src/sw/shared_worker.dart +++ b/packages_web/sqflite_common_ffi_web/lib/src/sw/shared_worker.dart @@ -116,6 +116,16 @@ void mainSharedWorker(List args) { var zone = Zone.current; try { final scope = (globalContext as web.SharedWorkerGlobalScope); + try { + var scopeName = scope.name; + if (_debug) { + _log('$_shw scopeName: $scopeName'); + } + } catch (e) { + if (_debug) { + _log('$_shw scope.name error $e'); + } + } scope.onconnect = (web.Event event) { zone.run(() { @@ -133,23 +143,30 @@ void mainSharedWorker(List args) { }); }.toJS; } catch (e) { - final scope = (globalContext as web.DedicatedWorkerGlobalScope); if (_debug) { _log('$_shw not in shared worker, trying basic worker'); } + } - try { - scope.onmessage = (web.MessageEvent event) { - zone.run(() { - _handleMessageEvent(event); - }); - }.toJS; - } catch (e) { - if (_debug) { - _log('$_shw not in shared worker error $e'); - } + final scope = (globalContext as web.DedicatedWorkerGlobalScope); + if (_debug) { + _log('$_shw basic worker support'); + } + + /// Handle basic web workers + /// dirty hack + try { + scope.onmessage = (web.MessageEvent event) { + zone.run(() { + _handleMessageEvent(event); + }); + }.toJS; + } catch (e) { + if (_debug) { + _log('$_shw not in shared worker error $e'); } } + if (_debug) { _log('$_shw main done ($_debugVersion)'); } diff --git a/packages_web/sqflite_common_ffi_web/lib/src/web/load_sqlite_common.dart b/packages_web/sqflite_common_ffi_web/lib/src/web/load_sqlite_common.dart index d523d018..7a0d8d23 100644 --- a/packages_web/sqflite_common_ffi_web/lib/src/web/load_sqlite_common.dart +++ b/packages_web/sqflite_common_ffi_web/lib/src/web/load_sqlite_common.dart @@ -25,6 +25,11 @@ class SqfliteFfiWebOptions { this.indexedDbName, this.sharedWorkerUri, @visibleForTesting this.forceAsBasicWorker}); + + @override + String toString() { + return 'SqfliteFfiWebOptions(inMemory: $inMemory, sqlite3WasmUri: $sqlite3WasmUri, indexedDbName: $indexedDbName, sharedWorkerUri: $sharedWorkerUri, forceAsBasicWorker: $forceAsBasicWorker)'; + } } /// Abstract context for the web (holder file system and wasm) diff --git a/packages_web/sqflite_common_ffi_web_test/test/sqflite_ffi_web_basic_web_worker_test.dart b/packages_web/sqflite_common_ffi_web_test/test/sqflite_ffi_web_basic_web_worker_test.dart new file mode 100644 index 00000000..3310b07e --- /dev/null +++ b/packages_web/sqflite_common_ffi_web_test/test/sqflite_ffi_web_basic_web_worker_test.dart @@ -0,0 +1,32 @@ +@TestOn('browser') +import 'package:sqflite_common_ffi/sqflite_ffi.dart'; +import 'package:sqflite_common_ffi_web/sqflite_ffi_web.dart'; +import 'package:sqflite_common_test/all_test.dart' as all; +import 'package:sqflite_common_test/sqflite_test.dart'; +import 'package:test/test.dart'; + +var _factory = createDatabaseFactoryFfiWeb( + options: SqfliteFfiWebOptions( + forceAsBasicWorker: true, + sharedWorkerUri: Uri.parse('sqflite_sw_v1.js'))); + +class SqfliteFfiWebTestContext extends SqfliteLocalTestContext { + SqfliteFfiWebTestContext() : super(databaseFactory: _factory); +} + +var ffiTestContext = SqfliteFfiWebTestContext(); + +Future main() async { + /// Initialize ffi loader + // sqliteFfiWebDebugWebWorker = true; + sqfliteFfiInit(); + try { + var dbsPath = await _factory.getDatabasesPath(); + await _factory.setDatabasesPath('${dbsPath}_web_basic_worker'); + + all.run(ffiTestContext); + } catch (e) { + print('Please run setup_web_tests first'); + test('Please run setup_web_tests first', () {}, skip: true); + } +} diff --git a/packages_web/sqflite_common_ffi_web_test/test/sqflite_ffi_web_test.dart b/packages_web/sqflite_common_ffi_web_test/test/sqflite_ffi_web_test.dart index 840f3cc2..26717435 100644 --- a/packages_web/sqflite_common_ffi_web_test/test/sqflite_ffi_web_test.dart +++ b/packages_web/sqflite_common_ffi_web_test/test/sqflite_ffi_web_test.dart @@ -19,7 +19,6 @@ Future main() async { /// Initialize ffi loader // sqliteFfiWebDebugWebWorker = true; sqfliteFfiInit(); - print('1'); try { var dbsPath = await _factory.getDatabasesPath(); await _factory.setDatabasesPath('${dbsPath}_web'); diff --git a/packages_web/sqflite_common_ffi_web_test/web/main.dart b/packages_web/sqflite_common_ffi_web_test/web/main.dart index 8b40bc02..c542b761 100644 --- a/packages_web/sqflite_common_ffi_web_test/web/main.dart +++ b/packages_web/sqflite_common_ffi_web_test/web/main.dart @@ -19,6 +19,14 @@ Future main() async { options: SqfliteFfiWebOptions( sharedWorkerUri: Uri.parse('sqflite_sw_v2.js'))); } + if (true) { + // devWarning(true)) { + factory = createDatabaseFactoryFfiWeb( + options: SqfliteFfiWebOptions( + // ignore: invalid_use_of_visible_for_testing_member + forceAsBasicWorker: true, + sharedWorkerUri: Uri.parse('sqflite_sw_v1.js'))); + } var db = await factory.openDatabase(inMemoryDatabasePath); var sqliteVersion = diff --git a/sqflite_test_app/lib/main_ffi.dart b/sqflite_test_app/lib/main_ffi.dart index 2ce3f2c1..fb17bcfb 100644 --- a/sqflite_test_app/lib/main_ffi.dart +++ b/sqflite_test_app/lib/main_ffi.dart @@ -14,15 +14,15 @@ Future main() async { } /// Run using ffi (io or web) -Future mainFfi() async { - await initFfi(); +Future mainFfi({bool? webBasicWorker}) async { + await initFfi(webBasicWorker: webBasicWorker); await runFfi(); } /// Init Ffi for io or web /// /// if [noWorker] is true, no isolate is used on io and no web worker is used on the web. -Future initFfi({bool? noWorker}) async { +Future initFfi({bool? noWorker, bool? webBasicWorker}) async { noWorker ??= false; // getDatabasesPath implementation is lame, use the default one // but we could also use path_provider @@ -35,7 +35,13 @@ Future initFfi({bool? noWorker}) async { if (noWorker) { databaseFactoryOrNull = databaseFactoryFfiWebNoWebWorker; } else { - databaseFactoryOrNull = databaseFactoryFfiWeb; + webBasicWorker ??= false; + if (webBasicWorker) { + databaseFactoryOrNull = databaseFactoryFfiWebBasicWebWorker; + } else { + // default (not supported on io + databaseFactoryOrNull = databaseFactoryFfiWeb; + } } // Platform handler for the example app platformHandler = platformHandlerWeb; diff --git a/sqflite_test_app/lib/main_web_simple_worker.dart b/sqflite_test_app/lib/main_web_simple_worker.dart new file mode 100644 index 00000000..28421ccb --- /dev/null +++ b/sqflite_test_app/lib/main_web_simple_worker.dart @@ -0,0 +1,16 @@ +// ignore_for_file: unused_import + +import 'package:flutter/foundation.dart'; +import 'package:sqflite_common_ffi_web/sqflite_ffi_web.dart'; + +import 'main_ffi.dart'; + +void main() { + if (kIsWeb) { + // sqliteFfiWebDebugWebWorker = true; + // ignore: avoid_print + print('running on the web basic worker'); + } + mainFfi(webBasicWorker: true); + //mainFfi(); +} diff --git a/sqflite_test_app/tool/flutter_build_and_serve_basic_worker.dart b/sqflite_test_app/tool/flutter_build_and_serve_basic_worker.dart new file mode 100644 index 00000000..cc08d368 --- /dev/null +++ b/sqflite_test_app/tool/flutter_build_and_serve_basic_worker.dart @@ -0,0 +1,16 @@ +import 'package:dev_build/build_support.dart'; +import 'package:path/path.dart'; +import 'package:process_run/shell.dart'; + +Future main() async { + await checkAndActivatePackage('dhttpd'); + var shell = Shell(); + await shell.run(''' + flutter build web -t lib/main_web_simple_worker.dart'''); + shell = shell.cd(join('build', 'web')); + // ignore: avoid_print + print('http://localhost:8080'); + + await shell.run( + 'dart pub global run dhttpd:dhttpd . --headers=Cross-Origin-Embedder-Policy=credentialless;Cross-Origin-Opener-Policy=same-origin'); +} diff --git a/sqflite_test_app/tool/setup_web_force.dart b/sqflite_test_app/tool/setup_web_force.dart new file mode 100644 index 00000000..a7c9418f --- /dev/null +++ b/sqflite_test_app/tool/setup_web_force.dart @@ -0,0 +1,5 @@ +import 'package:sqflite_common_ffi_web/src/setup/setup.dart'; + +Future main() async { + await setupBinaries(options: SetupOptions(force: true, verbose: true)); +}