Skip to content

Commit bc3416c

Browse files
authored
Merge pull request #84 from powersync-ja/feat/support-build-web-compilers
Support being compiled with `build_web_compilers`
2 parents 1c039a3 + 7ff4bfe commit bc3416c

File tree

7 files changed

+520
-353
lines changed

7 files changed

+520
-353
lines changed

.github/workflows/test.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,4 @@ jobs:
6868
run: |
6969
export LD_LIBRARY_PATH=$(pwd)/sqlite-autoconf-${{ matrix.sqlite_version }}/.libs
7070
melos test
71+
melos test_build

melos.yaml

+8
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,11 @@ scripts:
5151
# as they could change the behaviour of how tests filter packages.
5252
env:
5353
MELOS_TEST: true
54+
55+
test_build:
56+
description: Runs tests with build_test
57+
run: dart run build_runner test -- -p chrome
58+
exec:
59+
concurrency: 1
60+
packageFilters:
61+
dependsOn: build_test

packages/sqlite_async/CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 0.11.3
2+
3+
- Support being compiled with `package:build_web_compilers`.
4+
15
## 0.11.2
26

37
- Support latest version of `package:sqlite3_web`.
Original file line numberDiff line numberDiff line change
@@ -1,352 +1,2 @@
1-
import 'dart:async';
2-
import 'dart:collection';
3-
import 'dart:isolate';
4-
5-
abstract class PortClient {
6-
Future<T> post<T>(Object message);
7-
void fire(Object message);
8-
9-
factory PortClient.parent() {
10-
return ParentPortClient();
11-
}
12-
13-
factory PortClient.child(SendPort upstream) {
14-
return ChildPortClient(upstream);
15-
}
16-
}
17-
18-
class ParentPortClient implements PortClient {
19-
late Future<SendPort> sendPortFuture;
20-
SendPort? sendPort;
21-
final ReceivePort _receivePort = ReceivePort();
22-
final ReceivePort _errorPort = ReceivePort();
23-
bool closed = false;
24-
Object? _closeError;
25-
String? _isolateDebugName;
26-
int _nextId = 1;
27-
28-
Map<int, Completer<Object?>> handlers = HashMap();
29-
30-
ParentPortClient() {
31-
final initCompleter = Completer<SendPort>.sync();
32-
sendPortFuture = initCompleter.future;
33-
sendPortFuture.then((value) {
34-
sendPort = value;
35-
});
36-
_receivePort.listen((message) {
37-
if (message is _InitMessage) {
38-
assert(!initCompleter.isCompleted);
39-
initCompleter.complete(message.port);
40-
} else if (message is _PortChannelResult) {
41-
final handler = handlers.remove(message.requestId);
42-
assert(handler != null);
43-
if (message.success) {
44-
handler!.complete(message.result);
45-
} else {
46-
handler!.completeError(message.error, message.stackTrace);
47-
}
48-
} else if (message == _closeMessage) {
49-
close();
50-
}
51-
}, onError: (e) {
52-
if (!initCompleter.isCompleted) {
53-
initCompleter.completeError(e);
54-
}
55-
56-
close();
57-
}, onDone: () {
58-
if (!initCompleter.isCompleted) {
59-
initCompleter.completeError(ClosedException());
60-
}
61-
close();
62-
});
63-
_errorPort.listen((message) {
64-
final [error, stackTraceString] = message;
65-
final stackTrace = stackTraceString == null
66-
? null
67-
: StackTrace.fromString(stackTraceString);
68-
if (!initCompleter.isCompleted) {
69-
initCompleter.completeError(error, stackTrace);
70-
}
71-
_close(IsolateError(cause: error, isolateDebugName: _isolateDebugName),
72-
stackTrace);
73-
});
74-
}
75-
76-
Future<void> get ready async {
77-
await sendPortFuture;
78-
}
79-
80-
void _cancelAll(Object error, [StackTrace? stackTrace]) {
81-
var handlers = this.handlers;
82-
this.handlers = {};
83-
for (var message in handlers.values) {
84-
message.completeError(error, stackTrace);
85-
}
86-
}
87-
88-
@override
89-
Future<T> post<T>(Object message) async {
90-
if (closed) {
91-
throw _closeError ?? const ClosedException();
92-
}
93-
var completer = Completer<T>.sync();
94-
var id = _nextId++;
95-
handlers[id] = completer;
96-
final port = sendPort ?? await sendPortFuture;
97-
port.send(_RequestMessage(id, message, null));
98-
return await completer.future;
99-
}
100-
101-
@override
102-
void fire(Object message) async {
103-
if (closed) {
104-
throw _closeError ?? ClosedException();
105-
}
106-
final port = sendPort ?? await sendPortFuture;
107-
port.send(_FireMessage(message));
108-
}
109-
110-
RequestPortServer server() {
111-
return RequestPortServer(_receivePort.sendPort);
112-
}
113-
114-
void _close([Object? error, StackTrace? stackTrace]) {
115-
if (!closed) {
116-
closed = true;
117-
118-
_receivePort.close();
119-
_errorPort.close();
120-
if (error == null) {
121-
_cancelAll(const ClosedException());
122-
} else {
123-
_closeError = error;
124-
_cancelAll(error, stackTrace);
125-
}
126-
}
127-
}
128-
129-
void close() {
130-
_close();
131-
}
132-
133-
tieToIsolate(Isolate isolate) {
134-
_isolateDebugName = isolate.debugName;
135-
isolate.addErrorListener(_errorPort.sendPort);
136-
isolate.addOnExitListener(_receivePort.sendPort, response: _closeMessage);
137-
}
138-
}
139-
140-
class SerializedPortClient {
141-
final SendPort sendPort;
142-
143-
SerializedPortClient(this.sendPort);
144-
145-
ChildPortClient open() {
146-
return ChildPortClient(sendPort);
147-
}
148-
}
149-
150-
class ChildPortClient implements PortClient {
151-
final SendPort sendPort;
152-
final ReceivePort receivePort = ReceivePort();
153-
int _nextId = 1;
154-
bool closed = false;
155-
156-
final Map<int, Completer<Object?>> handlers = HashMap();
157-
158-
ChildPortClient(this.sendPort) {
159-
receivePort.listen((message) {
160-
if (message is _PortChannelResult) {
161-
final handler = handlers.remove(message.requestId);
162-
assert(handler != null);
163-
if (message.success) {
164-
handler!.complete(message.result);
165-
} else {
166-
handler!.completeError(message.error, message.stackTrace);
167-
}
168-
}
169-
});
170-
}
171-
172-
@override
173-
Future<T> post<T>(Object message) async {
174-
if (closed) {
175-
throw const ClosedException();
176-
}
177-
var completer = Completer<T>.sync();
178-
var id = _nextId++;
179-
handlers[id] = completer;
180-
sendPort.send(_RequestMessage(id, message, receivePort.sendPort));
181-
return await completer.future;
182-
}
183-
184-
@override
185-
void fire(Object message) {
186-
if (closed) {
187-
throw ClosedException();
188-
}
189-
sendPort.send(_FireMessage(message));
190-
}
191-
192-
void _cancelAll(Object error) {
193-
var handlers = HashMap<int, Completer<Object?>>.from(this.handlers);
194-
this.handlers.clear();
195-
for (var message in handlers.values) {
196-
message.completeError(error);
197-
}
198-
}
199-
200-
void close() {
201-
closed = true;
202-
_cancelAll(const ClosedException());
203-
receivePort.close();
204-
}
205-
}
206-
207-
class RequestPortServer {
208-
final SendPort port;
209-
210-
RequestPortServer(this.port);
211-
212-
open(Future<Object?> Function(Object? message) handle) {
213-
return PortServer.forSendPort(port, handle);
214-
}
215-
}
216-
217-
class PortServer {
218-
final ReceivePort _receivePort = ReceivePort();
219-
final Future<Object?> Function(Object? message) handle;
220-
final SendPort? replyPort;
221-
222-
PortServer(this.handle) : replyPort = null {
223-
_init();
224-
}
225-
226-
PortServer.forSendPort(SendPort port, this.handle) : replyPort = port {
227-
port.send(_InitMessage(_receivePort.sendPort));
228-
_init();
229-
}
230-
231-
SendPort get sendPort {
232-
return _receivePort.sendPort;
233-
}
234-
235-
SerializedPortClient client() {
236-
return SerializedPortClient(sendPort);
237-
}
238-
239-
void close() {
240-
_receivePort.close();
241-
}
242-
243-
void _init() {
244-
_receivePort.listen((request) async {
245-
if (request is _FireMessage) {
246-
handle(request.message);
247-
} else if (request is _RequestMessage) {
248-
if (request.id == 0) {
249-
// Fire and forget
250-
handle(request.message);
251-
} else {
252-
final replyPort = request.reply ?? this.replyPort;
253-
try {
254-
var result = await handle(request.message);
255-
replyPort!.send(_PortChannelResult.success(request.id, result));
256-
} catch (e, stacktrace) {
257-
replyPort!
258-
.send(_PortChannelResult.error(request.id, e, stacktrace));
259-
}
260-
}
261-
}
262-
});
263-
}
264-
}
265-
266-
const _closeMessage = '_Close';
267-
268-
class _InitMessage {
269-
final SendPort port;
270-
271-
_InitMessage(this.port);
272-
}
273-
274-
class _FireMessage {
275-
final Object message;
276-
277-
const _FireMessage(this.message);
278-
}
279-
280-
class _RequestMessage {
281-
final int id;
282-
final Object message;
283-
final SendPort? reply;
284-
285-
_RequestMessage(this.id, this.message, this.reply);
286-
}
287-
288-
class ClosedException implements Exception {
289-
const ClosedException();
290-
291-
@override
292-
String toString() {
293-
return 'ClosedException';
294-
}
295-
}
296-
297-
class IsolateError extends Error {
298-
final Object cause;
299-
final String? isolateDebugName;
300-
301-
IsolateError({required this.cause, this.isolateDebugName});
302-
303-
@override
304-
String toString() {
305-
if (isolateDebugName != null) {
306-
return 'IsolateError in $isolateDebugName: $cause';
307-
} else {
308-
return 'IsolateError: $cause';
309-
}
310-
}
311-
}
312-
313-
class _PortChannelResult<T> {
314-
final int requestId;
315-
final bool success;
316-
final T? _result;
317-
final Object? _error;
318-
final StackTrace? stackTrace;
319-
320-
const _PortChannelResult.success(this.requestId, T result)
321-
: success = true,
322-
_error = null,
323-
stackTrace = null,
324-
_result = result;
325-
const _PortChannelResult.error(this.requestId, Object error,
326-
[this.stackTrace])
327-
: success = false,
328-
_result = null,
329-
_error = error;
330-
331-
T get value {
332-
if (success) {
333-
return _result as T;
334-
} else {
335-
if (_error != null && stackTrace != null) {
336-
Error.throwWithStackTrace(_error, stackTrace!);
337-
} else {
338-
throw _error!;
339-
}
340-
}
341-
}
342-
343-
T get result {
344-
assert(success);
345-
return _result as T;
346-
}
347-
348-
Object get error {
349-
assert(!success);
350-
return _error!;
351-
}
352-
}
1+
export 'port_channel_native.dart'
2+
if (dart.library.js_interop) 'port_channel_stub.dart';

0 commit comments

Comments
 (0)