Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,19 @@ jobs:
include:
- sqlite_version: "3440200"
sqlite_url: "https://www.sqlite.org/2023/sqlite-autoconf-3440200.tar.gz"
dart_sdk: 3.4.0
dart_sdk: 3.5.0
- sqlite_version: "3430200"
sqlite_url: "https://www.sqlite.org/2023/sqlite-autoconf-3430200.tar.gz"
dart_sdk: 3.4.0
dart_sdk: 3.5.0
- sqlite_version: "3420000"
sqlite_url: "https://www.sqlite.org/2023/sqlite-autoconf-3420000.tar.gz"
dart_sdk: 3.4.0
dart_sdk: 3.5.0
- sqlite_version: "3410100"
sqlite_url: "https://www.sqlite.org/2023/sqlite-autoconf-3410100.tar.gz"
dart_sdk: 3.4.0
dart_sdk: 3.5.0
- sqlite_version: "3380000"
sqlite_url: "https://www.sqlite.org/2022/sqlite-autoconf-3380000.tar.gz"
dart_sdk: 3.4.0
dart_sdk: 3.5.0
steps:
- uses: actions/checkout@v3
- uses: dart-lang/setup-dart@v1
Expand Down
5 changes: 5 additions & 0 deletions packages/sqlite_async/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 0.11.1

- Remove remaining `dart:js_util` imports in favor of new interop APIs.
- Add `WebSqliteOpenFactory` with web-specific behavior for open factories.

## 0.11.0

- Automatically flush IndexedDB storage to fix durability issues
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ export 'stub_isolate_connection_factory.dart'
// ignore: uri_does_not_exist
if (dart.library.io) '../native/native_isolate_connection_factory.dart'
// ignore: uri_does_not_exist
if (dart.library.html) '../web/web_isolate_connection_factory.dart';
if (dart.library.js_interop) '../web/web_isolate_connection_factory.dart';
2 changes: 1 addition & 1 deletion packages/sqlite_async/lib/src/impl/mutex_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ export 'stub_mutex.dart'
// ignore: uri_does_not_exist
if (dart.library.io) '../native/native_isolate_mutex.dart'
// ignore: uri_does_not_exist
if (dart.library.html) '../web/web_mutex.dart';
if (dart.library.js_interop) '../web/web_mutex.dart';
2 changes: 1 addition & 1 deletion packages/sqlite_async/lib/src/impl/open_factory_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ export 'stub_sqlite_open_factory.dart'
// ignore: uri_does_not_exist
if (dart.library.io) '../native/native_sqlite_open_factory.dart'
// ignore: uri_does_not_exist
if (dart.library.html) '../web/web_sqlite_open_factory.dart';
if (dart.library.js_interop) '../web/web_sqlite_open_factory.dart';
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ export 'stub_sqlite_database.dart'
// ignore: uri_does_not_exist
if (dart.library.io) '../native/database/native_sqlite_database.dart'
// ignore: uri_does_not_exist
if (dart.library.html) '../web/database/web_sqlite_database.dart';
if (dart.library.js_interop) '../web/database/web_sqlite_database.dart';
3 changes: 1 addition & 2 deletions packages/sqlite_async/lib/src/web/web_mutex.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import 'dart:math';
import 'package:meta/meta.dart';
import 'package:mutex/mutex.dart' as mutex;
import 'dart:js_interop';
import 'dart:js_util' as js_util;
// This allows for checking things like hasProperty without the need for depending on the `js` package
import 'dart:js_interop_unsafe';
import 'package:web/web.dart';
Expand Down Expand Up @@ -128,7 +127,7 @@ class MutexImpl implements Mutex {
.request(resolvedIdentifier, lockOptions, jsCallback.toJS);
// A timeout abort will throw an exception which needs to be handled.
// There should not be any other unhandled lock errors.
js_util.promiseToFuture(promise).catchError((error) {});
promise.toDart.catchError((error) => null);
return gotLock.future;
}

Expand Down
46 changes: 29 additions & 17 deletions packages/sqlite_async/lib/src/web/web_sqlite_open_factory.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,45 @@ import 'package:sqlite3_web/sqlite3_web.dart';
import 'package:sqlite_async/sqlite_async.dart';
import 'package:sqlite_async/src/web/database/broadcast_updates.dart';
import 'package:sqlite_async/src/web/web_mutex.dart';
import 'package:sqlite_async/web.dart';

import 'database.dart';
import 'worker/worker_utils.dart';

Map<String, FutureOr<WebSqlite>> webSQLiteImplementations = {};

/// Web implementation of [AbstractDefaultSqliteOpenFactory]
class DefaultSqliteOpenFactory
extends AbstractDefaultSqliteOpenFactory<CommonDatabase> {
final Future<WebSqlite> _initialized;
extends AbstractDefaultSqliteOpenFactory<CommonDatabase>
implements WebSqliteOpenFactory {
late final Future<WebSqlite> _initialized = Future.sync(() {
final cacheKey = sqliteOptions.webSqliteOptions.wasmUri +
sqliteOptions.webSqliteOptions.workerUri;

if (webSQLiteImplementations.containsKey(cacheKey)) {
return webSQLiteImplementations[cacheKey]!;
}

webSQLiteImplementations[cacheKey] =
openWebSqlite(sqliteOptions.webSqliteOptions);
return webSQLiteImplementations[cacheKey]!;
});

DefaultSqliteOpenFactory(
{required super.path,
super.sqliteOptions = const SqliteOptions.defaults()})
: _initialized = Future.sync(() {
final cacheKey = sqliteOptions.webSqliteOptions.wasmUri +
sqliteOptions.webSqliteOptions.workerUri;

if (webSQLiteImplementations.containsKey(cacheKey)) {
return webSQLiteImplementations[cacheKey]!;
}

webSQLiteImplementations[cacheKey] = WebSqlite.open(
wasmModule: Uri.parse(sqliteOptions.webSqliteOptions.wasmUri),
worker: Uri.parse(sqliteOptions.webSqliteOptions.workerUri),
);
return webSQLiteImplementations[cacheKey]!;
});
super.sqliteOptions = const SqliteOptions.defaults()}) {
// Make sure initializer starts running immediately
_initialized;
}

@override
Future<WebSqlite> openWebSqlite(WebSqliteOptions options) async {
return WebSqlite.open(
wasmModule: Uri.parse(sqliteOptions.webSqliteOptions.wasmUri),
worker: Uri.parse(sqliteOptions.webSqliteOptions.workerUri),
controller: AsyncSqliteController(),
);
}

@override

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'dart:async';

import 'package:sqlite_async/sqlite3_common.dart';
import 'package:sqlite_async/sqlite3_wasm.dart';

/// Wrap a CommonDatabase to throttle its updates stream.
/// This is so that we can throttle the updates _within_
Expand Down Expand Up @@ -103,6 +103,17 @@ class ThrottledCommonDatabase extends CommonDatabase {
Stream<SqliteUpdate> get updates {
return throttledUpdates(_db, _transactionController.stream);
}

@override
VoidPredicate? get commitFilter => _db.commitFilter;

set commitFilter(VoidPredicate? filter) => _db.commitFilter = filter;

@override
Stream<void> get commits => _db.commits;

@override
Stream<void> get rollbacks => _db.rollbacks;
}

/// This throttles the database update stream to:
Expand Down
3 changes: 1 addition & 2 deletions packages/sqlite_async/lib/src/web/worker/worker_utils.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import 'dart:js_interop';
import 'dart:js_util' as js_util;

import 'package:mutex/mutex.dart';
import 'package:sqlite3/wasm.dart';
Expand Down Expand Up @@ -73,7 +72,7 @@ class AsyncSqliteDatabase extends WorkerDatabase {

var dartMap = resultSetToMap(res);

var jsObject = js_util.jsify(dartMap);
var jsObject = dartMap.jsify();

return jsObject;
case CustomDatabaseMessageKind.executeBatchInTransaction:
Expand Down
18 changes: 18 additions & 0 deletions packages/sqlite_async/lib/web.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ library sqlite_async.web;

import 'package:sqlite3_web/sqlite3_web.dart';
import 'package:web/web.dart';

import 'sqlite3_common.dart';
import 'sqlite_async.dart';
import 'src/web/database.dart';

Expand All @@ -24,6 +26,22 @@ typedef WebDatabaseEndpoint = ({
String? lockName,
});

/// An additional interface for [SqliteOpenFactory] exposing additional
/// functionality that is only relevant when compiling to the web.
///
/// The [DefaultSqliteOpenFactory] class implements this interface only when
/// compiling for the web.
abstract interface class WebSqliteOpenFactory
implements SqliteOpenFactory<CommonDatabase> {
/// Opens a [WebSqlite] instance for the given [options].
///
/// This method can be overriden in scenarios where the way [WebSqlite] is
/// opened needs to be customized. Implementers should be aware that the
/// result of this method is cached and will be re-used by the open factory
/// when provided with the same [options] again.
Future<WebSqlite> openWebSqlite(WebSqliteOptions options);
}

/// A [SqliteConnection] interface implemented by opened connections when
/// running on the web.
///
Expand Down
9 changes: 4 additions & 5 deletions packages/sqlite_async/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
name: sqlite_async
description: High-performance asynchronous interface for SQLite on Dart and Flutter.
version: 0.11.0
version: 0.11.1
repository: https://github.com/powersync-ja/sqlite_async.dart
environment:
sdk: ">=3.4.0 <4.0.0"
sdk: ">=3.5.0 <4.0.0"

topics:
- sqlite
Expand All @@ -12,8 +12,8 @@ topics:
- flutter

dependencies:
sqlite3: "^2.4.7"
sqlite3_web: ^0.2.0
sqlite3: ^2.7.2
sqlite3_web: ^0.2.2
async: ^2.10.0
collection: ^1.17.0
mutex: ^3.1.0
Expand All @@ -22,7 +22,6 @@ dependencies:

dev_dependencies:
dcli: ^4.0.0
js: ^0.6.7
lints: ^3.0.0
test: ^1.21.0
test_api: ^0.7.0
Expand Down
2 changes: 1 addition & 1 deletion packages/sqlite_async/test/utils/test_utils_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ export 'stub_test_utils.dart'
// ignore: uri_does_not_exist
if (dart.library.io) 'native_test_utils.dart'
// ignore: uri_does_not_exist
if (dart.library.html) 'web_test_utils.dart';
if (dart.library.js_interop) 'web_test_utils.dart';
8 changes: 4 additions & 4 deletions packages/sqlite_async/test/utils/web_test_utils.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import 'dart:async';
import 'dart:html';
import 'dart:js_interop';

import 'package:js/js.dart';
import 'package:sqlite_async/sqlite_async.dart';
import 'package:test/test.dart';
import 'package:web/web.dart' show Blob, BlobPart, BlobPropertyBag;
import 'abstract_test_utils.dart';

@JS('URL.createObjectURL')
Expand All @@ -24,8 +24,8 @@ class TestUtils extends AbstractTestUtils {
// Cross origin workers are not supported, but we can supply a Blob
var sqliteUri = 'http://localhost:$port/db_worker.js';

final blob = Blob(
<String>['importScripts("$sqliteUri");'], 'application/javascript');
final blob = Blob(<BlobPart>['importScripts("$sqliteUri");'.toJS].toJS,
BlobPropertyBag(type: 'application/javascript'));
sqliteUri = _createObjectURL(blob);

webOptions = SqliteOptions(
Expand Down
Loading