diff --git a/CHANGELOG.md b/CHANGELOG.md index b9886c5..f5c9c0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,34 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## 2024-11-06 + +### Changes + +--- + +Packages with breaking changes: + + - There are no breaking changes in this release. + +Packages with other changes: + + - [`sqlite_async` - `v0.11.0`](#sqlite_async---v0110) + - [`drift_sqlite_async` - `v0.2.0-alpha.4`](#drift_sqlite_async---v020-alpha4) + +Packages with dependency updates only: + +> Packages listed below depend on other packages in this workspace that have had changes. Their versions have been incremented to bump the minimum dependency versions of the packages they depend upon in this project. + + - `drift_sqlite_async` - `v0.2.0-alpha.4` + +--- + +#### `sqlite_async` - `v0.11.0` + + - Automatically flush IndexedDB storage to fix durability issues + + ## 2024-11-01 ### Changes diff --git a/packages/drift_sqlite_async/CHANGELOG.md b/packages/drift_sqlite_async/CHANGELOG.md index de46be7..23f501b 100644 --- a/packages/drift_sqlite_async/CHANGELOG.md +++ b/packages/drift_sqlite_async/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.0-alpha.4 + + - Update a dependency to the latest release. + ## 0.2.0-alpha.3 - Bump `sqlite_async` to v0.10.1 diff --git a/packages/drift_sqlite_async/pubspec.yaml b/packages/drift_sqlite_async/pubspec.yaml index 109314d..a2e8c99 100644 --- a/packages/drift_sqlite_async/pubspec.yaml +++ b/packages/drift_sqlite_async/pubspec.yaml @@ -1,5 +1,5 @@ name: drift_sqlite_async -version: 0.2.0-alpha.3 +version: 0.2.0-alpha.4 homepage: https://github.com/powersync-ja/sqlite_async.dart repository: https://github.com/powersync-ja/sqlite_async.dart description: Use Drift with a sqlite_async database, allowing both to be used in the same application. @@ -15,7 +15,7 @@ environment: sdk: ">=3.0.0 <4.0.0" dependencies: drift: ">=2.19.0 <3.0.0" - sqlite_async: ^0.10.1 + sqlite_async: ^0.11.0 dev_dependencies: build_runner: ^2.4.8 drift_dev: ">=2.19.0 <3.0.0" diff --git a/packages/sqlite_async/CHANGELOG.md b/packages/sqlite_async/CHANGELOG.md index 88f9875..ab91443 100644 --- a/packages/sqlite_async/CHANGELOG.md +++ b/packages/sqlite_async/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.11.0 + + - Automatically flush IndexedDB storage to fix durability issues + ## 0.10.1 - For database setups not using a shared worker, use a `BroadcastChannel` to share updates across different tabs. diff --git a/packages/sqlite_async/lib/src/web/database.dart b/packages/sqlite_async/lib/src/web/database.dart index 3e3233b..a4f0ddf 100644 --- a/packages/sqlite_async/lib/src/web/database.dart +++ b/packages/sqlite_async/lib/src/web/database.dart @@ -113,7 +113,8 @@ class WebDatabase @override Future writeTransaction( Future Function(SqliteWriteContext tx) callback, - {Duration? lockTimeout}) { + {Duration? lockTimeout, + bool? flush}) { return writeLock( (writeContext) => internalWriteTransaction(writeContext, (context) async { @@ -122,14 +123,15 @@ class WebDatabase return callback(_ExclusiveTransactionContext(this, writeContext)); }), debugContext: 'writeTransaction()', - lockTimeout: lockTimeout); + lockTimeout: lockTimeout, + flush: flush); } @override /// Internal writeLock which intercepts transaction context's to verify auto commit is not active Future writeLock(Future Function(SqliteWriteContext tx) callback, - {Duration? lockTimeout, String? debugContext}) async { + {Duration? lockTimeout, String? debugContext, bool? flush}) async { if (_mutex case var mutex?) { return await mutex.lock(() async { final context = _ExclusiveContext(this); @@ -137,6 +139,9 @@ class WebDatabase return await callback(context); } finally { context.markClosed(); + if (flush != false) { + await this.flush(); + } } }); } else { @@ -148,11 +153,20 @@ class WebDatabase return await callback(context); } finally { context.markClosed(); + if (flush != false) { + await this.flush(); + } await _database.customRequest( CustomDatabaseMessage(CustomDatabaseMessageKind.releaseLock)); } } } + + @override + Future flush() async { + await isInitialized; + return _database.fileSystem.flush(); + } } class _SharedContext implements SqliteReadContext { diff --git a/packages/sqlite_async/lib/src/web/database/web_sqlite_database.dart b/packages/sqlite_async/lib/src/web/database/web_sqlite_database.dart index c00377c..0f38b1c 100644 --- a/packages/sqlite_async/lib/src/web/database/web_sqlite_database.dart +++ b/packages/sqlite_async/lib/src/web/database/web_sqlite_database.dart @@ -131,24 +131,32 @@ class SqliteDatabaseImpl @override Future writeLock(Future Function(SqliteWriteContext tx) callback, - {Duration? lockTimeout, String? debugContext}) async { + {Duration? lockTimeout, String? debugContext, bool? flush}) async { await isInitialized; return _runZoned(() { return _connection.writeLock(callback, - lockTimeout: lockTimeout, debugContext: debugContext); + lockTimeout: lockTimeout, debugContext: debugContext, flush: flush); }, debugContext: debugContext ?? 'execute()'); } @override Future writeTransaction( Future Function(SqliteWriteContext tx) callback, - {Duration? lockTimeout}) async { + {Duration? lockTimeout, + bool? flush}) async { await isInitialized; return _runZoned( - () => _connection.writeTransaction(callback, lockTimeout: lockTimeout), + () => _connection.writeTransaction(callback, + lockTimeout: lockTimeout, flush: flush), debugContext: 'writeTransaction()'); } + @override + Future flush() async { + await isInitialized; + return _connection.flush(); + } + @override Future close() async { await isInitialized; diff --git a/packages/sqlite_async/lib/web.dart b/packages/sqlite_async/lib/web.dart index 7c49737..a4005e1 100644 --- a/packages/sqlite_async/lib/web.dart +++ b/packages/sqlite_async/lib/web.dart @@ -65,4 +65,34 @@ abstract class WebSqliteConnection implements SqliteConnection { ); return database; } + + /// Same as [SqliteConnection.writeLock]. + /// + /// Has an additional [flush] (defaults to true). This can be set to false + /// to delay flushing changes to the database file, losing durability guarantees. + /// This only has an effect when IndexedDB storage is used. + /// + /// See [flush] for details. + Future writeLock(Future Function(SqliteWriteContext tx) callback, + {Duration? lockTimeout, String? debugContext, bool? flush}); + + /// Same as [SqliteConnection.writeTransaction]. + /// + /// Has an additional [flush] (defaults to true). This can be set to false + /// to delay flushing changes to the database file, losing durability guarantees. + /// This only has an effect when IndexedDB storage is used. + /// + /// See [flush] for details. + Future writeTransaction( + Future Function(SqliteWriteContext tx) callback, + {Duration? lockTimeout, + bool? flush}); + + /// Flush changes to the underlying storage. + /// + /// When this returns, all changes previously written will be persisted + /// to storage. + /// + /// This only has an effect when IndexedDB storage is used. + Future flush(); } diff --git a/packages/sqlite_async/pubspec.yaml b/packages/sqlite_async/pubspec.yaml index 453f154..09adc13 100644 --- a/packages/sqlite_async/pubspec.yaml +++ b/packages/sqlite_async/pubspec.yaml @@ -1,6 +1,6 @@ name: sqlite_async description: High-performance asynchronous interface for SQLite on Dart and Flutter. -version: 0.10.1 +version: 0.11.0 repository: https://github.com/powersync-ja/sqlite_async.dart environment: sdk: ">=3.4.0 <4.0.0"