LCOV - code coverage report

Current view
top level - src/_impl/web - _worker_channel.dart
Test
lcov.info
Date
2024-11-13
Legend
Lines
hit
not hit
Branches
taken
not taken
# not executed
HitTotalCoverage
Lines102638.5%
Functions00-
Branches00-
Each row represents a line of source code
LineBranchHitsSource code
1import 'dart:async';
2import 'dart:js_interop';
3
4import 'package:logger/web.dart';
5import 'package:meta/meta.dart';
6import 'package:web/web.dart' as web;
7
8import '../../exceptions/squadron_error.dart';
9import '../../exceptions/squadron_exception.dart';
10import '../../typedefs.dart';
11import '../../worker/worker_channel.dart';
12import '../../worker/worker_response.dart';
13import '../xplat/_transferables.dart';
14
15/// [WorkerChannel] implementation for the JavaScript world.
16final class _WebWorkerChannel implements WorkerChannel {
17 _WebWorkerChannel._(this._sendPort, this._logger);
18
19 /// [web.MessagePort] to communicate with the [web.Worker] if the channel is
20 /// owned by the worker owner. Otherwise, [web.MessagePort] to return values
21 /// to the client.
22 final web.MessagePort _sendPort;
23
24 final Logger? _logger;
25
261 void _postResponse(WorkerResponse res) {
271 try {
281 _sendPort.postMessage(res.wrapInPlace().jsify());
290 } catch (ex, st) {
301 _logger?.e(() => 'Failed to post response $res: $ex');
310 throw SquadronErrorExt.create('Failed to post response: $ex', st);
32 }
331 }
34
350 void _inspectAndPostResponse(WorkerResponse res) {
360 try {
370 final data = res.wrapInPlace();
380 final transfer = Transferables.get(data);
390 if (transfer == null || transfer.isEmpty) {
400 _sendPort.postMessage(data.jsify());
41 } else {
420 _sendPort.postMessage(data.jsify(), transfer.jsify() as JSArray);
43 }
440 } catch (ex, st) {
451 _logger?.e(() => 'Failed to post response $res: $ex');
460 throw SquadronErrorExt.create('Failed to post response: $ex', st);
47 }
480 }
49
50 /// Sends the [web.MessagePort] to communicate with the [web.Worker]. This
51 /// method must be called by the [web.Worker] upon startup.
52 @override
53 void connect(PlatformChannel channelInfo) => inspectAndReply(channelInfo);
54
55 /// Sends a [WorkerResponse] with the specified data to the worker client.
56 /// This method must be called from the [web.Worker] only. On Web patforms,
57 /// this version does not check arguments for transferable objects.
58 @override
591 void reply(dynamic data) => _postResponse(WorkerResponse.withResult(data));
60
61 /// Sends a [WorkerResponse] with the specified data to the worker client.
62 /// This method must be called from the [web.Worker] only. On Web patforms,
63 /// this version (tentatively) checks arguments for transferable objects.
64 @override
650 void inspectAndReply(dynamic data) =>
660 _inspectAndPostResponse(WorkerResponse.withResult(data));
67
68 @override
69 void log(LogEvent message) => _postResponse(WorkerResponse.log(message));
70
71 /// Checks if [stream] can be streamed back to the worker client. Returns
72 /// `true` for browser platforms.
73 @override
74 bool canStream(Stream<dynamic> stream) => true;
75
76 /// Sends a [WorkerResponse.closeStream] to the worker client. This method
77 /// must be called from the [web.Worker] only.
78 @override
791 void closeStream() => _postResponse(WorkerResponse.closeStream());
80
81 /// Sends the [WorkerResponse] to the worker client. This method must be
82 /// called from the [web.Worker] only.
83 @override
840 void error(Object err, [StackTrace? stackTrace, int? command]) {
851 final ex = SquadronException.from(err, stackTrace, command);
861 _postResponse(WorkerResponse.withError(ex));
870 }
88}
89
90/// Creates a [WorkerChannel] from a [web.MessagePort].
91@internal
92WorkerChannel? deserialize(PlatformChannel? channelInfo, [Logger? logger]) =>
93 (channelInfo == null) ? null : _WebWorkerChannel._(channelInfo, logger);
Choose Features