Skip to content

Commit 81bb049

Browse files
committed
Merge remote-tracking branch 'origin/main' into get_all_connections
2 parents e11f506 + 8d65840 commit 81bb049

20 files changed

+558
-101
lines changed

CHANGELOG.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,45 @@
33
All notable changes to this project will be documented in this file.
44
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
55

6+
## 2025-06-03
7+
8+
---
9+
10+
Packages with breaking changes:
11+
12+
- There are no breaking changes in this release.
13+
14+
Packages with other changes:
15+
16+
- [`sqlite_async` - `v0.11.7`](#sqlite_async---v0117)
17+
18+
---
19+
20+
#### `sqlite_async` - `v0.11.7`
21+
22+
- Shared worker: Release locks owned by connected client tab when it closes.
23+
- Fix web concurrency issues: Consistently apply a shared mutex or let a shared
24+
worker coordinate access.
25+
26+
## 2025-05-28
27+
28+
---
29+
30+
Packages with breaking changes:
31+
32+
- There are no breaking changes in this release.
33+
34+
Packages with other changes:
35+
36+
- [`sqlite_async` - `v0.11.6`](#sqlite_async---v0116)
37+
38+
---
39+
40+
#### `sqlite_async` - `v0.11.6`
41+
42+
- Native: Consistently report errors when opening the database instead of
43+
causing unhandled exceptions.
44+
645
## 2025-05-22
746

847
---

packages/sqlite_async/CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
## 0.11.7
2+
3+
- Shared worker: Release locks owned by connected client tab when it closes.
4+
- Fix web concurrency issues: Consistently apply a shared mutex or let a shared
5+
worker coordinate access.
6+
7+
## 0.11.6
8+
9+
- Native: Consistently report errors when opening the database instead of
10+
causing unhandled exceptions.
11+
112
## 0.11.5
213

314
- Allow profiling queries. Queries are profiled by default in debug and profile builds, the runtime

packages/sqlite_async/build.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
targets:
2+
$default:
3+
builders:
4+
build_web_compilers:entrypoint:
5+
options:
6+
# Workers can't be compiled with dartdevc, so use dart2js for the example
7+
compiler: dart2js
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<!DOCTYPE html>
2+
3+
<html>
4+
<head>
5+
<meta charset="utf-8">
6+
<title>sqlite_async web demo</title>
7+
<script defer src="main.dart.js"></script>
8+
</head>
9+
10+
<body>
11+
12+
<h1>sqlite_async demo</h1>
13+
14+
<main>
15+
This page is used to test the sqlite_async package on the web.
16+
Use the console to open and interact with databases.
17+
18+
<pre>
19+
<code>
20+
const db = await open('test.db');
21+
const lock = await write_lock(db);
22+
release_lock(lock);
23+
</code>
24+
</pre>
25+
</main>
26+
27+
28+
</body>
29+
</html>
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import 'dart:async';
2+
import 'dart:js_interop';
3+
import 'dart:js_interop_unsafe';
4+
5+
import 'package:sqlite_async/sqlite_async.dart';
6+
7+
void main() {
8+
globalContext['open'] = (String path) {
9+
return Future(() async {
10+
final db = SqliteDatabase(
11+
path: path,
12+
options: SqliteOptions(
13+
webSqliteOptions: WebSqliteOptions(
14+
wasmUri:
15+
'https://cdn.jsdelivr.net/npm/@powersync/dart-wasm-bundles@latest/dist/sqlite3.wasm',
16+
workerUri: 'worker.dart.js',
17+
),
18+
),
19+
);
20+
await db.initialize();
21+
return db.toJSBox;
22+
}).toJS;
23+
}.toJS;
24+
25+
globalContext['write_lock'] = (JSBoxedDartObject db) {
26+
final hasLock = Completer<void>();
27+
final completer = Completer<void>();
28+
29+
(db.toDart as SqliteDatabase).writeLock((_) async {
30+
print('has write lock!');
31+
hasLock.complete();
32+
await completer.future;
33+
});
34+
35+
return hasLock.future.then((_) => completer.toJSBox).toJS;
36+
}.toJS;
37+
38+
globalContext['release_lock'] = (JSBoxedDartObject db) {
39+
(db.toDart as Completer<void>).complete();
40+
}.toJS;
41+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import 'package:sqlite_async/sqlite3_web.dart';
2+
import 'package:sqlite_async/sqlite3_web_worker.dart';
3+
4+
void main() {
5+
WebSqlite.workerEntrypoint(controller: AsyncSqliteController());
6+
}

packages/sqlite_async/lib/src/common/connection/sync_sqlite_connection.dart

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@ import 'package:sqlite_async/src/sqlite_queries.dart';
88
import 'package:sqlite_async/src/update_notification.dart';
99
import 'package:sqlite_async/src/utils/profiler.dart';
1010

11+
import '../../impl/context.dart';
12+
1113
/// A simple "synchronous" connection which provides the async SqliteConnection
1214
/// implementation using a synchronous SQLite connection
13-
class SyncSqliteConnection extends SqliteConnection with SqliteQueries {
15+
class SyncSqliteConnection with SqliteQueries implements SqliteConnection {
1416
final CommonDatabase db;
1517
late Mutex mutex;
1618
@override
@@ -44,7 +46,10 @@ class SyncSqliteConnection extends SqliteConnection with SqliteQueries {
4446
return mutex.lock(
4547
() {
4648
task?.finish();
47-
return callback(SyncReadContext(db, parent: task));
49+
return ScopedReadContext.assumeReadLock(
50+
_UnsafeSyncContext(db, parent: task),
51+
callback,
52+
);
4853
},
4954
timeout: lockTimeout,
5055
);
@@ -59,7 +64,10 @@ class SyncSqliteConnection extends SqliteConnection with SqliteQueries {
5964
return mutex.lock(
6065
() {
6166
task?.finish();
62-
return callback(SyncWriteContext(db, parent: task));
67+
return ScopedWriteContext.assumeWriteLock(
68+
_UnsafeSyncContext(db, parent: task),
69+
callback,
70+
);
6371
},
6472
timeout: lockTimeout,
6573
);
@@ -80,12 +88,12 @@ class SyncSqliteConnection extends SqliteConnection with SqliteQueries {
8088
}
8189
}
8290

83-
class SyncReadContext implements SqliteReadContext {
91+
final class _UnsafeSyncContext extends UnscopedContext {
8492
final TimelineTask? task;
8593

8694
CommonDatabase db;
8795

88-
SyncReadContext(this.db, {TimelineTask? parent})
96+
_UnsafeSyncContext(this.db, {TimelineTask? parent})
8997
: task = TimelineTask(parent: parent);
9098

9199
@override
@@ -129,10 +137,6 @@ class SyncReadContext implements SqliteReadContext {
129137
Future<bool> getAutoCommit() async {
130138
return db.autocommit;
131139
}
132-
}
133-
134-
class SyncWriteContext extends SyncReadContext implements SqliteWriteContext {
135-
SyncWriteContext(super.db, {super.parent});
136140

137141
@override
138142
Future<ResultSet> execute(String sql,

packages/sqlite_async/lib/src/common/port_channel_native.dart

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,10 @@ class ParentPortClient implements PortClient {
3030
ParentPortClient() {
3131
final initCompleter = Completer<SendPort>.sync();
3232
sendPortFuture = initCompleter.future;
33-
sendPortFuture.then((value) {
34-
sendPort = value;
35-
});
3633
_receivePort.listen((message) {
3734
if (message is _InitMessage) {
3835
assert(!initCompleter.isCompleted);
36+
sendPort = message.port;
3937
initCompleter.complete(message.port);
4038
} else if (message is _PortChannelResult) {
4139
final handler = handlers.remove(message.requestId);

0 commit comments

Comments
 (0)