diff --git a/coverage.json b/coverage.json index f19e3e64..097bbe39 100644 --- a/coverage.json +++ b/coverage.json @@ -1 +1 @@ -{"linesValid":1891,"lineRate":83.7} \ No newline at end of file +{"linesValid":2139,"lineRate":75.7} \ No newline at end of file diff --git a/doc/coverage/html/_impl/native/_bootstrapper.dart.gcov.html b/doc/coverage/html/_impl/native/_bootstrapper.dart.gcov.html index d308c3d2..47f7212e 100644 --- a/doc/coverage/html/_impl/native/_bootstrapper.dart.gcov.html +++ b/doc/coverage/html/_impl/native/_bootstrapper.dart.gcov.html @@ -18,7 +18,7 @@
@override
FutureOr close() {
FutureOr<void> close() {
if (!_closed) {
@override
FutureOr cancelStream(int streamId) {
FutureOr<void> cancelStream(int streamId) {
if (!_closed) {
@override
FutureOr cancelToken(SquadronCancelationToken? token) {
FutureOr<void> cancelToken(SquadronCancelationToken? token) {
if (token != null && !_closed) {
SquadronPlatformType getPlatformType() => SquadronPlatformType.vm;
Uri mapUrl(String url) => Uri.parse(url);
void fail(SquadronException ex) {
void fail(SquadronException ex) {
if (!ready.isCompleted) ready.completeError(ex);
if (!ready.isCompleted) ready.completeError(ex);
if (!completer.isCompleted) completer.completeError(ex);
if (!completer.isCompleted) completer.completeError(ex);
}
}
try {
try {
worker = web.Worker(webEntryPoint.uri.toJS);
setDbgId(worker, '${webEntryPoint.uri}#');
void $errorHandler(web.ErrorEvent? e) {
void $errorHandler(web.ErrorEvent? e) {
final err = getErrorEventError(e)?.toString() ??
final err = getErrorEventError(e)?.toString() ??
getErrorEventMessage(e) ??
getErrorEventMessage(e) ??
'Unknown error';
'Unknown error';
var error = SquadronErrorExt.create(err);
var error = SquadronErrorExt.create(err);
logger?.e(() => 'Connection to Web Worker failed: $error');
logger?.e(() => 'Connection to Web Worker failed: $error');
fail(error);
fail(error);
UriChecker.exists(entryPoint).then((found) {
UriChecker.exists(entryPoint).then((found) {
try {
try {
final msg = (e != null)
final msg = (e != null)
? '$entryPoint => ${err.runtimeType} $err [${e.filename}(${e.lineno})]'
? '$entryPoint => ${err.runtimeType} $err [${e.filename}(${e.lineno})]'
: '$entryPoint => ${err.runtimeType} $err';
: '$entryPoint => ${err.runtimeType} $err';
logger?.e(() => 'Unhandled error from Web Worker: $msg.');
logger?.e(() => 'Unhandled error from Web Worker: $msg.');
if (!found) {
if (!found) {
logger?.e(() => 'It seems no Web Worker lives at $entryPoint.');
logger?.e(() => 'It seems no Web Worker lives at $entryPoint.');
}
}
} catch (_) {
} catch (_) {
// ignore
// ignore
}
}
});
});
}
}
worker.onerror = $errorHandler.toJS;
worker.onerror = $errorHandler.toJS;
worker.onmessageerror = $errorHandler.toJS;
worker.onmessageerror = $errorHandler.toJS;
final disconnected = DisconnectedChannel(exceptionManager, logger);
final disconnected = DisconnectedChannel(exceptionManager, logger);
worker.onmessage = (web.MessageEvent? e) {
worker.onmessage = (web.MessageEvent? e) {
try {
try {
final response = WorkerResponseExt.from(getMessageEventData(e) as List);
final response = WorkerResponseExt.from(getMessageEventData(e) as List);
if (!response.unwrapInPlace(disconnected)) {
if (!response.unwrapInPlace(disconnected)) {
return;
return;
}
}
final error = response.error;
final error = response.error;
if (error != null) {
if (error != null) {
logger?.e(() => 'Connection to Web Worker failed: $error');
logger?.e(() => 'Connection to Web Worker failed: $error');
fail(error);
fail(error);
} else if (!ready.isCompleted) {
} else if (!ready.isCompleted) {
logger?.t('Web Worker is ready');
logger?.t('Web Worker is ready');
ready.complete(response.result);
ready.complete(response.result);
}
}
} catch (ex, st) {
} catch (ex, st) {
return fail(SquadronException.from(ex, st));
return fail(SquadronException.from(ex, st));
}
}
}.toJS;
}.toJS;
final res = await ready.future;
final res = await ready.future;
if (!res) {
if (!res) {
throw SquadronErrorExt.create('Web Worker is not ready');
throw SquadronErrorExt.create('Web Worker is not ready');
}
}
final startRequest = WorkerRequest.start(com.port2, startArguments);
final startRequest = WorkerRequest.start(com.port2, startArguments);
com.port1.onmessage = (web.MessageEvent e) {
com.port1.onmessage = (web.MessageEvent e) {
final response = WorkerResponseExt.from(getMessageEventData(e) as List);
final response = WorkerResponseExt.from(getMessageEventData(e) as List);
if (!response.unwrapInPlace(disconnected)) {
if (!response.unwrapInPlace(disconnected)) {
return;
return;
}
}
final error = response.error;
final error = response.error;
if (error != null) {
if (error != null) {
logger?.e(() => 'Connection to Web Worker failed: $error');
logger?.e(() => 'Connection to Web Worker failed: $error');
fail(error);
fail(error);
} else if (!completer.isCompleted) {
} else if (!completer.isCompleted) {
logger?.t('Connected to Web Worker');
logger?.t('Connected to Web Worker');
success(_WebChannel._(response.result, logger, exceptionManager));
success(_WebChannel._(response.result, logger, exceptionManager));
} else {
} else {
logger?.d(() => 'Unexpected response: $response');
logger?.d(() => 'Unexpected response: $response');
}
}
}.toJS;
}.toJS;
try {
try {
final data = startRequest.wrapInPlace();
final data = startRequest.wrapInPlace();
final msg = data.jsify();
final msg = data.jsify();
final transfer = Transferables.get(data);
final transfer = Transferables.get(data);
if (transfer == null || transfer.isEmpty) {
if (transfer == null || transfer.isEmpty) {
worker.postMessage(msg);
worker.postMessage(msg);
} else {
} else {
final jsTransfer = transfer.jsify() as JSArray;
final jsTransfer = transfer.jsify() as JSArray;
worker.postMessage(msg, jsTransfer);
worker.postMessage(msg, jsTransfer);
}
}
} catch (ex, st) {
} catch (ex, st) {
logger?.e(() => 'Failed to post connection request $startRequest: $ex');
logger?.e(() => 'Failed to post connection request $startRequest: $ex');
throw SquadronErrorExt.create(
throw SquadronErrorExt.create(
'Failed to post connection request: $ex', st);
'Failed to post connection request: $ex', st);
}
}
final channel = await completer.future;
final channel = await completer.future;
await hook?.call(worker);
await hook?.call(worker);
logger?.t('Created Web Worker for $entryPoint');
logger?.t('Created Web Worker for $entryPoint');
return channel;
return channel;
} catch (ex, st) {
} catch (ex, st) {
ready.future.ignore();
ready.future.ignore();
completer.future.ignore();
completer.future.ignore();
logger?.t('Failed to create Web Worker for $entryPoint');
logger?.t('Failed to create Web Worker for $entryPoint');
com.port1.close();
com.port1.close();
com.port2.close();
com.port2.close();
worker.terminate();
worker.terminate();
throw SquadronException.from(ex, st);
throw SquadronException.from(ex, st);
} finally {
} finally {
webEntryPoint.release();
webEntryPoint.release();
}
}
}
}
/// Creates a [_WebChannel] from a [web.MessagePort].
/// Creates a [_WebChannel] from a [web.MessagePort].
Channel? deserialize(PlatformChannel? channelInfo,
Channel? deserialize(PlatformChannel? channelInfo,
[Logger? logger, ExceptionManager? exceptionManager]) =>
[Logger? logger, ExceptionManager? exceptionManager]) =>
(channelInfo == null)
(channelInfo == null)
? null
? null
: _WebChannel._(
: _WebChannel._(
channelInfo,
channelInfo,
logger,
logger,
exceptionManager ?? ExceptionManager(),
exceptionManager ?? ExceptionManager(),
);
);
@override
PlatformChannel serialize() => _sendPort;
PlatformChannel serialize() => _sendPort;
@override
Channel share() => _WebForwardChannel._(
Channel share() => _WebForwardChannel._(
_sendPort, web.MessageChannel(), logger, exceptionManager);
@override
FutureOr close() {
FutureOr<void> close() {
if (!_closed) {
@override
FutureOr cancelStream(int streamId) {
FutureOr<void> cancelStream(int streamId) {
if (!_closed) {
@override
FutureOr cancelToken(SquadronCancelationToken? token) {
FutureOr<void> cancelToken(SquadronCancelationToken? token) {
if (token != null && !_closed) {
import '../../exceptions/squadron_error.dart';
import '_patch.dart';
class EntryPointUri with Releasable {
class EntryPointUri with Releasable {
EntryPointUri._(this.uri, {required bool revoke}) : _revoke = revoke;
EntryPointUri._(this.uri, {required bool revoke}) : _revoke = revoke;
final String uri;
final String uri;
final bool _revoke;
final bool _revoke;
@override
@override
void release() {
void release() {
if (_revoke) {
if (_revoke) {
web.URL.revokeObjectURL(uri);
web.URL.revokeObjectURL(uri);
}
}
super.release();
super.release();
}
}
factory EntryPointUri.from(Uri workerEntrypoint) {
static String _getUrl(Uri uri) {
final fileName =
var url = uri.toString();
workerEntrypoint.pathSegments.lastOrNull?.toString().toLowerCase() ??
if (url.startsWith('~')) {
'';
final root = getHome();
if (root != null) {
if (fileName.endsWith('.js') || fileName.endsWith('.mjs')) {
url = '$root${url.substring(1)}';
// a JavaScript worker
}
return EntryPointUri._(workerEntrypoint.toString(), revoke: false);
}
} else if (fileName.endsWith('.wasm')) {
return url;
// blob containing the JavaScript code to load and invoke the Web Assembly worker
}
final blob = web.Blob(
[wasmLoaderScript(workerEntrypoint.toString()).toJS].toJS,
factory EntryPointUri.from(Uri workerEntrypoint) {
web.BlobPropertyBag(type: 'application/javascript'),
final fileName =
);
workerEntrypoint.pathSegments.lastOrNull?.toString().toLowerCase() ??
return EntryPointUri._(web.URL.createObjectURL(blob), revoke: true);
'';
} else if (workerEntrypoint.isScheme('data') ||
workerEntrypoint.isScheme('javascript')) {
if (fileName.endsWith('.js') || fileName.endsWith('.mjs')) {
// something else, eg. inline JavaScript
// a JavaScript worker
return EntryPointUri._(workerEntrypoint.toString(), revoke: false);
return EntryPointUri._(_getUrl(workerEntrypoint), revoke: false);
} else {
} else if (fileName.endsWith('.wasm')) {
throw SquadronErrorExt.create('Invalid entry point URI');
// blob containing the JavaScript code to load and invoke the Web Assembly worker
}
final blob = web.Blob(
}
[wasmLoaderScript(_getUrl(workerEntrypoint)).toJS].toJS,
web.BlobPropertyBag(type: 'application/javascript'),
static String wasmLoaderScript(String url) => '''(async function() {
);
const workerUri = new URL("${url.replaceAll('"', '\\"')}", self.location.origin).href;
return EntryPointUri._(web.URL.createObjectURL(blob), revoke: true);
try {
} else if (workerEntrypoint.isScheme('data') ||
let dart2wasm_runtime; let moduleInstance;
workerEntrypoint.isScheme('javascript')) {
const runtimeUri = workerUri.replaceAll('.unopt', '').replaceAll('.wasm', '.mjs');
// something else, eg. inline JavaScript
try {
return EntryPointUri._(workerEntrypoint.toString(), revoke: false);
const dartModule = WebAssembly.compileStreaming(fetch(workerUri));
} else {
dart2wasm_runtime = await import(runtimeUri);
throw SquadronErrorExt.create('Invalid entry point URI');
moduleInstance = await dart2wasm_runtime.instantiate(dartModule, {});
}
} catch (exception) {
}
console.error(`Failed to fetch and instantiate wasm module \${workerUri}: \${exception}`);
console.error('See https://dart.dev/web/wasm for more information.');
static String wasmLoaderScript(String url) => '''(async function() {
throw new Error(exception.message ?? 'Unknown error when instantiating worker module');
const workerUri = new URL("${url.replaceAll('"', '\\"')}", self.location.origin).href;
}
try {
try {
let dart2wasm_runtime; let moduleInstance;
await dart2wasm_runtime.invoke(moduleInstance);
const runtimeUri = workerUri.replaceAll('.unopt', '').replaceAll('.wasm', '.mjs');
console.log(`Succesfully loaded and invoked \${workerUri}`);
try {
} catch (exception) {
const dartModule = WebAssembly.compileStreaming(fetch(workerUri));
console.error(`Exception while invoking wasm module \${workerUri}: \${exception}`);
dart2wasm_runtime = await import(runtimeUri);
throw new Error(exception.message ?? 'Unknown error when invoking worker module');
moduleInstance = await dart2wasm_runtime.instantiate(dartModule, {});
}
} catch (exception) {
} catch (ex) {
console.error(`Failed to fetch and instantiate wasm module \${workerUri}: \${exception}`);
const ts = (Date.now() - Date.UTC(2020, 1, 2)) * 1000;
console.error('See https://dart.dev/web/wasm for more information.');
postMessage([ts, null, ["\$sqdrn", `Failed to load Web Worker from \${workerUri}: \${ex}`, null], null, null]);
throw new Error(exception.message ?? 'Unknown error when instantiating worker module');
}
}
})()''';
try {
await dart2wasm_runtime.invoke(moduleInstance);
console.log(`Succesfully loaded and invoked \${workerUri}`);
} catch (exception) {
console.error(`Exception while invoking wasm module \${workerUri}: \${exception}`);
throw new Error(exception.message ?? 'Unknown error when invoking worker module');
}
} catch (ex) {
const ts = (Date.now() - Date.UTC(2020, 1, 2)) * 1000;
postMessage([ts, null, ["\$sqdrn", `Failed to load Web Worker from \${workerUri}: \${ex}`, null], null, null]);
}
})()''';
}
}
@JS()
String? getHome() {
external DedicatedWorkerGlobalScope get self;
if (window.isUndefinedOrNull) return null;
final components = window.location.pathname.split('/');
String? getHome() {
return components.take(components.length - 1).join('/');
if (window.isUndefinedOrNull) return null;
}
final components = window.location.pathname.split('/');
return components.take(components.length - 1).join('/');
String? getErrorEventMessage(JSObject? obj) {
}
if (obj != null && obj.has('message')) {
return obj['message']?.toString();
const _dbgIdProp = '@@dbgid';
} else {
return null;
void setDbgId(JSObject obj, String id) {
}
obj[_dbgIdProp] = id.toJS;
}
}
Object? getErrorEventError(JSObject? obj) {
String getDbgId(JSObject obj) {
if (obj != null && obj.has('error')) {
return obj.has(_dbgIdProp)
return obj['error'].dartify();
? obj[_dbgIdProp].dartify().toString()
} else {
: '($_dbgIdProp not set)';
return null;
}
}
}
String? getErrorEventMessage(JSObject? obj) {
if (obj != null && obj.has('message')) {
List? getMessageEventData(JSObject? obj) {
return obj['message']?.toString();
if (obj != null && obj.has('data')) {
} else {
final data = obj['data'].dartify();
return null;
return (data == null) ? null : (data as List);
}
} else {
}
return null;
}
Object? getErrorEventError(JSObject? obj) {
if (obj != null && obj.has('error')) {
return obj['error'].dartify();
} else {
return null;
}
}
List? getMessageEventData(JSObject? obj) {
if (obj != null && obj.has('data')) {
final data = obj['data'].dartify();
return (data == null) ? null : (data as List);
} else {
return null;
}
}
}
import '../../squadron_platform_type.dart';
import '_patch.dart';
CastConverter getPlatformConverter() => (1.toDouble() is int)
? CastConverter.instance // JavaScript
CastConverter getPlatformConverter() => (1.toDouble() is int)
: NumConverter.instance; // Web Assembly
? CastConverter.instance // JavaScript
: NumConverter.instance; // Web Assembly
SquadronPlatformType getPlatformType() => (1.toDouble() is int)
? SquadronPlatformType.js // JavaScript
SquadronPlatformType getPlatformType() => (1.toDouble() is int)
: SquadronPlatformType.wasm; // Web Assembly
? SquadronPlatformType.js // JavaScript
: SquadronPlatformType.wasm; // Web Assembly
Uri mapUrl(String url) {
if (url.startsWith('~')) {
final root = getHome();
if (root != null) {
url = '$root${url.substring(1)}';
}
}
return Uri.parse(url);
}
static Future<bool> exists(Uri url) async {
static Future<bool> exists(Uri url) async {
if (url.isScheme('data')) return true;
if (url.isScheme('data')) return true;
try {
final res =
await fetch(url.toString().toJS, {'method': 'HEAD'}.jsify()).toDart;
await fetch(url.toString().toJS, {'method': 'HEAD'}.jsify()).toDart;
return res.ok && (200 <= res.status) && (res.status < 300);
return res.ok && (200 <= res.status) && (res.status < 300);
} catch (_) {
}
}
}
}
Hit | Total | Coverage | -|
---|---|---|---|
Lines | 5 | 6 | 83.3% | -
Functions | 0 | 0 | - | -
Branches | 0 | 0 | - | -
Line | Branch | Hits | Source code | -
---|---|---|---|
1 | 41 | final _latestUPDEpoch = DateTime.utc(2020, 02, 02); // universal palindrome date |
- |
2 |
|
- ||
3 | 20 | int microsecTimeStamp([DateTime? time]) => |
- |
4 | 61 | (time ?? DateTime.now()).toUtc().difference(_latestUPDEpoch).inMicroseconds; |
- |
5 |
|
- ||
6 | 9 | DateTime? fromMicrosecTimeStamp(int? microsecs) => (microsecs == null) |
- |
7 | ? null |
- ||
8 | 36 | : _latestUPDEpoch.add(Duration(microseconds: microsecs)); |
- |
9 |
|
- ||
10 | extension FutureExt on Future { |
- ||
11 | 0 | Future<void> ignore() async { |
- |
12 | try { |
- ||
13 | final _ = await this; |
- ||
14 | } catch (_) { |
- ||
15 | /* ignore */ |
- ||
16 | } |
- ||
17 | } |
- ||
18 | } |
-
- Generated by: JGENHTML version 1.5 -
-import 'dart:typed_data';
import '../../squadron.dart';
import 'converter.dart';
class CastConverter extends Converter {
const CastConverter();
class CastConverter implements Converter {
const CastConverter();
static const instance = CastConverter();
static const instance = CastConverter();
@override
Cast<T> value<T>() => Converter.identity<T>;
@override
Cast<T> v<T>() => Converter.identity<T>;
@override
Cast<T?> nv<T>() => Converter.identity<T?>;
static ByteBuffer? _buffer<T>(dynamic x) => (x == null)
? null
: (x is ByteBuffer)
? x
: ((x as T) as TypedData).buffer;
static Cast<T> _td<T>(T Function(ByteBuffer) b) =>
(x) => Converter.tryCast<T>(x) ?? b(_buffer<T>(x)!);
static Cast<T?> _ntd<T>(T Function(ByteBuffer) b) => (x) =>
(x == null) ? null : (Converter.tryCast<T>(x) ?? b(_buffer<T>(x)!));
static final Map<Type, Cast> _typeDataCastors = {
ByteData: _td<ByteData>(ByteData.view),
Uint8ClampedList: _td<Uint8ClampedList>(Uint8ClampedList.view),
Uint8List: _td<Uint8List>(Uint8List.view),
Int8List: _td<Int8List>(Int8List.view),
Uint16List: _td<Uint16List>(Uint16List.view),
Int16List: _td<Int16List>(Int16List.view),
Uint32List: _td<Uint32List>(Uint32List.view),
Int32List: _td<Int32List>(Int32List.view),
Int32x4List: _td<Int32x4List>(Int32x4List.view),
Uint64List: _td<Uint64List>(Uint64List.view),
Int64List: _td<Int64List>(Int64List.view),
Float32List: _td<Float32List>(Float32List.view),
Float32x4List: _td<Float32x4List>(Float32x4List.view),
Float64List: _td<Float64List>(Float64List.view),
Float64x2List: _td<Float64x2List>(Float64x2List.view),
};
static final Map<Type, Cast> _nullableTypeDataCastors = {
ByteData: _ntd<ByteData>(ByteData.view),
Uint8ClampedList: _ntd<Uint8ClampedList>(Uint8ClampedList.view),
Uint8List: _ntd<Uint8List>(Uint8List.view),
Int8List: _ntd<Int8List>(Int8List.view),
Uint16List: _ntd<Uint16List>(Uint16List.view),
Int16List: _ntd<Int16List>(Int16List.view),
Uint32List: _ntd<Uint32List>(Uint32List.view),
Int32List: _ntd<Int32List>(Int32List.view),
Int32x4List: _ntd<Int32x4List>(Int32x4List.view),
Uint64List: _ntd<Uint64List>(Uint64List.view),
Int64List: _ntd<Int64List>(Int64List.view),
Float32List: _ntd<Float32List>(Float32List.view),
Float32x4List: _ntd<Float32x4List>(Float32x4List.view),
Float64List: _ntd<Float64List>(Float64List.view),
Float64x2List: _ntd<Float64x2List>(Float64x2List.view),
};
@override
Cast<T> td<T>() => _typeDataCastors[T] as Cast<T>;
@override
Cast<T?> ntd<T>() => _nullableTypeDataCastors[T] as Cast<T?>;
@override
Cast<Iterable<T>> i<T>([Cast<T>? cast]) => Converter.isIdentity<T>(cast)
? ((x) => (x as Iterable).cast<T>())
: ((x) => (x as Iterable).map<T>(cast!));
@override
Cast<Iterable<T?>> ni<T>([Cast<T?>? cast]) => Converter.isIdentity<T?>(cast)
? ((x) => (x as Iterable).cast<T?>())
: ((x) => (x as Iterable).map<T?>(cast!));
@override
Cast<List<T>> l<T>([Cast<T>? cast]) => Converter.isIdentity<T>(cast)
? ((x) => (x as List).cast<T>())
: ((x) => (x as List).map<T>(cast!).toList());
@override
Cast<List<T?>> nl<T>([Cast<T?>? cast]) => Converter.isIdentity<T?>(cast)
? ((x) => (x as List).cast<T?>())
: ((x) => (x as List).map<T?>(cast!).toList());
@override
Cast<Map<K, V>> m<K, V>({Cast<K>? kcast, Cast<V>? vcast}) {
if (Converter.isIdentity<K>(kcast) && Converter.isIdentity<V>(vcast)) {
return ((x) => (x as Map).cast<K, V>());
} else {
final key = kcast ?? v<K>(), value = vcast ?? v<V>();
return ((x) => (x as Map).map((k, v) => MapEntry(key(k), value(v))));
}
}
@override
Cast<Map<K, V?>> nm<K, V>({Cast<K>? kcast, Cast<V?>? vcast}) {
if (Converter.isIdentity<K>(kcast) && Converter.isIdentity<V?>(vcast)) {
return ((x) => (x as Map).cast<K, V?>());
} else {
final key = kcast ?? v<K>(), value = vcast ?? v<V>();
return ((x) => (x as Map).map((k, v) => MapEntry(key(k), value(v))));
}
}
}
}
typedef Cast<T> = T Function(dynamic);
import 'dart:typed_data';
abstract class Converter {
typedef Cast<T> = T Function(dynamic);
static bool isIdentity<T>(Cast<T>? cast) =>
(cast == null) || (cast == identity<T>);
abstract class Converter {
const Converter();
static T identity<T>(dynamic x) => x as T;
static bool isIdentity<T>(Cast<T>? cast) =>
static T? tryCast<T>(dynamic x) => (x is T) ? x : null;
(cast == null) || (cast == identity<T>);
// single value
static T identity<T>(dynamic x) => x as T;
Cast<T> v<T>();
Cast<T?> nv<T>();
static T? tryCast<T>(dynamic x) => (x is T) ? x : null;
// for typed data
static List<dynamic> toList(dynamic x) =>
Cast<T> td<T>();
(x is List) ? x : (x as Iterable).toList();
Cast<T?> ntd<T>();
static Set<dynamic> toSet(dynamic x) =>
// iterable
(x is Set) ? x : (x as Iterable).toSet();
Cast<Iterable<T>> i<T>([Cast<T>? cast]);
Cast<Iterable<T?>> ni<T>([Cast<T?>? cast]);
// non-nullable value
Cast<T> value<T>();
// list
Cast<List<T>> l<T>([Cast<T>? cast]);
// nullable value
Cast<List<T?>> nl<T>([Cast<T?>? cast]);
Cast<T?> nullable<T>([Cast<T>? cast]) {
final op = cast ?? value<T>();
// map
return Converter.isIdentity<T>(op)
Cast<Map<K, V>> m<K, V>({Cast<K>? kcast, Cast<V>? vcast});
? value<T?>()
Cast<Map<K, V?>> nm<K, V>({Cast<K>? kcast, Cast<V?>? vcast});
: (($) => ($ == null) ? null : op($));
}
}
// list
Cast<List<T>> list<T>([Cast<T>? cast]) {
final op = cast ?? value<T>();
return Converter.isIdentity<T>(op)
? ((x) => Converter.toList(x).cast<T>())
: ((x) => Converter.toList(x).map<T>(op).toList());
}
// set
Cast<Set<T>> set<T>([Cast<T>? cast]) {
final op = list<T>();
return (x) => op(x).toSet();
}
// map
Cast<Map<K, V>> map<K, V>({Cast<K>? kcast, Cast<V>? vcast}) {
final kop = kcast ?? value<K>(), vop = vcast ?? value<V>();
if (Converter.isIdentity<K>(kop) && Converter.isIdentity<V>(vop)) {
return ((x) => (x as Map).cast<K, V>());
} else {
return ((x) => (x as Map).map((k, v) => MapEntry(kop(k), vop(v))));
}
}
// typed data
Cast<T> typedData<T>() => _typeDataCastors[T] as Cast<T>;
static ByteBuffer? _buffer<T>(dynamic x) => (x == null)
? null
: (x is ByteBuffer)
? x
: ((x as T) as TypedData).buffer;
static Cast<T> _td<T>(T Function(ByteBuffer) view) =>
(x) => Converter.tryCast<T>(x) ?? view(_buffer<T>(x)!);
static final Map<Type, Cast> _typeDataCastors = {
ByteData: _td<ByteData>(ByteData.view),
Uint8ClampedList: _td<Uint8ClampedList>(Uint8ClampedList.view),
Uint8List: _td<Uint8List>(Uint8List.view),
Int8List: _td<Int8List>(Int8List.view),
Uint16List: _td<Uint16List>(Uint16List.view),
Int16List: _td<Int16List>(Int16List.view),
Uint32List: _td<Uint32List>(Uint32List.view),
Int32List: _td<Int32List>(Int32List.view),
Int32x4List: _td<Int32x4List>(Int32x4List.view),
Uint64List: _td<Uint64List>(Uint64List.view),
Int64List: _td<Int64List>(Int64List.view),
Float32List: _td<Float32List>(Float32List.view),
Float32x4List: _td<Float32x4List>(Float32x4List.view),
Float64List: _td<Float64List>(Float64List.view),
Float64x2List: _td<Float64x2List>(Float64x2List.view),
};
}
static int _toInt(dynamic x) {
@override
if (x is int && x.isFinite) return x;
Cast<T> value<T>() => _numCastors[T] as Cast<T>? ?? super.value<T>();
final y = (x as num).toDouble();
if (!y.isFinite) return double.minPositive as int; // intended type error
static int _toInt(dynamic x) {
final z = y.toInt(), d = y - z;
if (x is int && x.isFinite) return x;
if (d != 0) return double.minPositive as int; // intended type error
final y = (x as num).toDouble();
return z;
if (!y.isFinite) return double.minPositive as int; // intended type error
}
final z = y.toInt(), d = y - z;
if (d != 0) return double.minPositive as int; // intended type error
static double _toDbl(dynamic x) => (x as num).toDouble();
return z;
}
static final Map<Type, Cast> _numCastors = {
int: _toInt,
static double _toDbl(dynamic x) => (x as num).toDouble();
double: _toDbl,
};
static final Map<Type, Cast> _numCastors = {
int: _toInt,
static int? _toNullableInt(dynamic x) => (x == null) ? null : _toInt(x);
double: _toDbl,
};
static double? _toNullableDbl(dynamic x) => (x as num?)?.toDouble();
static final Map<Type, Cast> _nullableNumCastors = {
int: _toNullableInt,
double: _toNullableDbl,
};
@override
Cast<T> v<T>() => _numCastors[T] as Cast<T>? ?? super.v<T>();
@override
Cast<T?> nv<T>() => _nullableNumCastors[T] as Cast<T?>? ?? super.nv<T>();
@override
Cast<Iterable<T>> i<T>([Cast<T>? cast]) =>
super.i<T>(cast ?? _numCastors[T] as Cast<T>);
@override
Cast<Iterable<T?>> ni<T>([Cast<T?>? cast]) =>
super.ni<T>(cast ?? _nullableNumCastors[T] as Cast<T?>);
@override
Cast<List<T>> l<T>([Cast<T>? cast]) =>
super.l<T>(cast ?? _numCastors[T] as Cast<T>);
@override
Cast<List<T?>> nl<T>([Cast<T?>? cast]) =>
super.nl<T>(cast ?? _nullableNumCastors[T] as Cast<T?>);
@override
Cast<Map<K, V>> m<K, V>({Cast<K>? kcast, Cast<V>? vcast}) => super.m<K, V>(
kcast: kcast ?? _numCastors[K] as Cast<K>?,
vcast: vcast ?? _numCastors[V] as Cast<V>?,
);
@override
Cast<Map<K, V?>> nm<K, V>({Cast<K>? kcast, Cast<V?>? vcast}) =>
super.nm<K, V>(
kcast: kcast ?? _numCastors[K] as Cast<K>?,
vcast: vcast ?? _nullableNumCastors[V] as Cast<V?>?,
);
}
}
/// Deserializes a [List] that was produced by [serialize].
SquadronException? deserialize(List? data) {
SquadronException? deserialize(List? data) {
if (data == null || data.isEmpty) {
if (data == null || data.isEmpty) {
return null;
try {
final exceptionType = data[0];
final exceptionType = data[0];
final deserializer = _deserializers[exceptionType];
final deserializer = _deserializers[exceptionType];
return deserializer?.call(data) ??
return deserializer?.call(data) ??
WorkerException(
}
}
}
}
class SquadronError extends SquadronException {
SquadronError._(super.message, [super.stackTrace]) : super.init();
SquadronError._(super.message, [super.stackTrace]) : super.init();
static SquadronError create(String message, [StackTrace? stackTrace]) =>
SquadronError._(message, stackTrace);
SquadronError._(message, stackTrace);
static SquadronException? deserialize(List exceptionInfo) =>
static SquadronException? deserialize(List exceptionInfo) =>
(exceptionInfo[_$type] == $squadronErrorType)
(exceptionInfo[_$type] == $squadronErrorType)
? SquadronError._(
? SquadronError._(
exceptionInfo[_$message],
exceptionInfo[_$message],
SquadronException.loadStackTrace(exceptionInfo[_$stackTrace]),
SquadronException.loadStackTrace(exceptionInfo[_$stackTrace]),
)
: null;
: null;
}
abstract class SquadronException implements Exception {
SquadronException.init(this.message, [this._stackTrace]) {
SquadronException.init(this.message, [this._stackTrace]) {
if (_stackTrace == null) {
if (_stackTrace == null) {
try {
_stackTrace = StackTrace.current;
_stackTrace = StackTrace.current;
} catch (_, st) {
}
}
}
/// [WorkerException] wrapping [error] and [stackTrace].
static SquadronException from(Object error,
static SquadronException from(Object error,
[StackTrace? stackTrace, int? command]) {
if (error is WorkerException) {
if (error is WorkerException) {
if (command != null) error.setCommand(command);
return error;
} else if (error is SquadronException) {
} else if (error is SquadronException) {
return error;
return error;
} else if (error is CanceledException) {
}
}
}
FutureOr start() {}
FutureOr<void> start() {}
FutureOr stop() {}
FutureOr<void> stop() {}
}
static final platformType = impl.getPlatformType();
}
static Uri uri(String url) => impl.mapUrl(url);
}
@override
FutureOr start();
FutureOr<void> start();
import 'package:cancelation_token/cancelation_token.dart';
import 'package:using/using.dart';
import '../channel.dart';
import '../tokens/_squadron_cancelation_token.dart';
import '../channel.dart';
import '../worker/worker_request.dart';
import '../tokens/_squadron_cancelation_token.dart';
import '../worker_service.dart';
import '../worker/worker_request.dart';
import 'local_worker.dart';
import '../worker_service.dart';
import 'local_worker.dart';
/// Base class used to communicate with a [LocalWorker].
///
/// Base class used to communicate with a [LocalWorker].
/// Typically, derived classes should add proxy methods sending [WorkerRequest]s to the worker.
///
class LocalWorkerClient implements WorkerService {
/// Typically, derived classes should add proxy methods sending [WorkerRequest]s to the worker.
/// Create a client for a [LocalWorker]. The [channel] passed to this client must have been obtained by
class LocalWorkerClient with Releasable implements WorkerService {
/// calling [Channel.share] on the [LocalWorker.channel].
/// Create a client for a [LocalWorker]. The [channel] passed to this client must have been obtained by
LocalWorkerClient(this.channel);
/// calling [Channel.share] on the [LocalWorker.channel].
LocalWorkerClient(this.channel);
/// The [Channel] to communicate with the [LocalWorker].
final Channel channel;
/// The [Channel] to communicate with the [LocalWorker].
final Channel channel;
/// Sends a command to the [LocalWorker].
Future<dynamic> send(int command,
@override
{List args = const [],
void release() {
SquadronCancelationToken? token,
channel.close();
bool inspectRequest = false,
super.release();
bool inspectResponse = false}) =>
}
channel.sendRequest(command, args,
token: token?.wrap(),
/// Sends a command to the [LocalWorker].
inspectRequest: inspectRequest,
Future<dynamic> send(int command,
inspectResponse: inspectResponse);
{List args = const [],
SquadronCancelationToken? token,
/// Sends a streaming command to the [LocalWorker].
bool inspectRequest = false,
Stream<dynamic> stream(int command,
bool inspectResponse = false}) =>
{List args = const [],
channel.sendRequest(command, args,
CancelationToken? token,
token: token?.wrap(),
bool inspectRequest = false,
inspectRequest: inspectRequest,
bool inspectResponse = false}) =>
inspectResponse: inspectResponse);
channel.sendStreamingRequest(command, args,
token: token?.wrap(),
/// Sends a streaming command to the [LocalWorker].
inspectRequest: inspectRequest,
Stream<dynamic> stream(int command,
inspectResponse: inspectResponse);
{List args = const [],
CancelationToken? token,
/// Local worker clients do not need an [operations] map.
bool inspectRequest = false,
@override
bool inspectResponse = false}) =>
final Map<int, CommandHandler> operations = WorkerService.noOperations;
channel.sendStreamingRequest(command, args,
}
token: token?.wrap(),
inspectRequest: inspectRequest,
inspectResponse: inspectResponse);
/// Local worker clients do not need an [operations] map.
@override
final Map<int, CommandHandler> operations = WorkerService.noOperations;
}
import '../converters/converter.dart';
/// Base class to serialize/deserialize data of type [T] to a transferable type [S].
import '../squadron_singleton.dart';
abstract class SquadronMarshaler<T, S> {
const SquadronMarshaler();
/// Base class to serialize/deserialize data of type [T] to a transferable type [S].
abstract class SquadronMarshaler<T, S> {
/// Serialize [data] of type [T] to type [S], eg. a `String` or some binary representation.
const SquadronMarshaler();
/// `unmarshal(marshal(data))` must produce an instance of [T] that is equivalent to
/// original instance [data].
/// Serialize [data] of type [T] to type [S], eg. a `String` or some binary representation.
S marshal(T data);
/// `unmarshal(marshal(data))` must produce an instance of [T] that is equivalent to
/// original instance [data].
/// Deserialize a representation of type [S] back to the original data of type [T].
S marshal(T data);
/// `unmarshal(marshal(data))` must produce an instance of [T] that is equivalent to
/// original instance [data].
/// Deserialize a representation of type [S] back to the original data of type [T].
T unmarshal(S data);
/// `unmarshal(marshal(data))` must produce an instance of [T] that is equivalent to
/// original instance [data].
T unmarshal(S data);
}
extension SquadronMarshalerExt<T, S> on SquadronMarshaler<T, S> {
Cast<S> marshaler([Cast<T>? cast]) =>
(x) => marshal((cast ?? Squadron.converter.v<T>())(x));
Cast<T> unmarshaler([Cast<S>? cast]) =>
(x) => unmarshal((cast ?? Squadron.converter.v<S>())(x));
}
}
/// Run the specified [task] in the [worker].
Future run(WorkerTask task) {
Future<void> run(WorkerTask task) {
_lastStart = DateTime.now().millisecondsSinceEpoch;
import '../_impl/xplat/_helpers.dart';
import '../_impl/xplat/_time_stamp.dart';
import '../exceptions/task_canceled_exception.dart';
/// Maximum workload.
int get maxWorkload => fullStats.fold<int>(
int get maxWorkload => fullStats.fold<int>(
0, (p, s) => (p >= s.maxWorkload) ? p : s.maxWorkload);
0, (p, s) => (p >= s.maxWorkload) ? p : s.maxWorkload);
/// Full worker statistics.
Iterable<WorkerStat> get fullStats => _deadWorkerStats.followedBy(stats);
Iterable<WorkerStat> get fullStats => _deadWorkerStats.followedBy(stats);
import '../_impl/xplat/_forward_stream_controller.dart';
import '../_impl/xplat/_helpers.dart';
import '../_impl/xplat/_time_stamp.dart';
import '../channel.dart';
import '../_impl/xplat/_helpers.dart';
import '../_impl/xplat/_time_stamp.dart';
void unwrapTravelTime() {
final ts = (data[_$traveltime] as num?)?.toInt();
final ts = (data[_$traveltime] as num?)?.toInt();
if (ts != null) {
if (ts != null) {
data[_$traveltime] = microsecTimeStamp() - ts;
data[_$traveltime] = microsecTimeStamp() - ts;
}
import '../_impl/xplat/_helpers.dart';
import '../_impl/xplat/_internal_logger.dart';
import '../_impl/xplat/_internal_logger.dart';
import '../_impl/xplat/_time_stamp.dart';
import '../exceptions/squadron_error.dart';
import '../_impl/xplat/_helpers.dart';
import '../_impl/xplat/_time_stamp.dart';
import '../channel.dart';
/// The [WorkerResponse] exception, if any.
SquadronException? get error => data[_$error];
SquadronException? get error => data[_$error];
/// used for log messages only).
bool unwrapInPlace(Channel channel) {
bool unwrapInPlace(Channel channel) {
unwrapTravelTime();
final log = LogEventSerialization.deserialize(data[_$log]);
final log = LogEventSerialization.deserialize(data[_$log]);
if (log != null) {
if (log != null) {
channel.logger?.log(log.level, log.message,
} else {
data[_$error] = channel.exceptionManager.deserialize(data[_$error]);
data[_$error] = channel.exceptionManager.deserialize(data[_$error]);
data[_$endOfStream] ??= false;
data[_$endOfStream] ??= false;
return true;
return true;
}
}
}
static WorkerResponse from(List data) {
static WorkerResponse from(List data) {
if (data.length != 5) {
if (data.length != 5) {
throw SquadronErrorExt.create('Invalid worker response');
}
return WorkerResponse._(data);
return WorkerResponse._(data);
}
}
}
import 'dart:isolate';
diff --git a/doc/coverage/xml/_impl/native/_channel.dart.gcov.xml b/doc/coverage/xml/_impl/native/_channel.dart.gcov.xml
index a56b9e92..c6664432 100644
--- a/doc/coverage/xml/_impl/native/_channel.dart.gcov.xml
+++ b/doc/coverage/xml/_impl/native/_channel.dart.gcov.xml
@@ -1,5 +1,5 @@
-import 'dart:async';
diff --git a/doc/coverage/xml/_impl/native/_channel_impl.dart.gcov.xml b/doc/coverage/xml/_impl/native/_channel_impl.dart.gcov.xml
index a7ae1a50..95adccac 100644
--- a/doc/coverage/xml/_impl/native/_channel_impl.dart.gcov.xml
+++ b/doc/coverage/xml/_impl/native/_channel_impl.dart.gcov.xml
@@ -1,5 +1,5 @@
-part of '_channel.dart';
@@ -136,7 +136,7 @@
FutureOr close() {
+ FutureOr<void> close() {
if (!_closed) {
@@ -167,7 +167,7 @@
FutureOr cancelStream(int streamId) {
+ FutureOr<void> cancelStream(int streamId) {
if (!_closed) {
@@ -194,7 +194,7 @@
FutureOr cancelToken(SquadronCancelationToken? token) {
+ FutureOr<void> cancelToken(SquadronCancelationToken? token) {
if (token != null && !_closed) {
diff --git a/doc/coverage/xml/_impl/native/_local_worker.dart.gcov.xml b/doc/coverage/xml/_impl/native/_local_worker.dart.gcov.xml
index d745d20f..0d2994ad 100644
--- a/doc/coverage/xml/_impl/native/_local_worker.dart.gcov.xml
+++ b/doc/coverage/xml/_impl/native/_local_worker.dart.gcov.xml
@@ -1,5 +1,5 @@
-import 'dart:async';
diff --git a/doc/coverage/xml/_impl/native/_platform.dart.gcov.xml b/doc/coverage/xml/_impl/native/_platform.dart.gcov.xml
index e6d1a41e..bcaef746 100644
--- a/doc/coverage/xml/_impl/native/_platform.dart.gcov.xml
+++ b/doc/coverage/xml/_impl/native/_platform.dart.gcov.xml
@@ -1,5 +1,5 @@
-import '../../converters/cast_converter.dart';
@@ -21,6 +21,12 @@
SquadronPlatformType getPlatformType() => SquadronPlatformType.vm;
+ Uri mapUrl(String url) => Uri.parse(url);
+ import 'dart:async';
diff --git a/doc/coverage/xml/_impl/native/_worker_channel.dart.gcov.xml b/doc/coverage/xml/_impl/native/_worker_channel.dart.gcov.xml
index 9c731aa1..10902e4e 100644
--- a/doc/coverage/xml/_impl/native/_worker_channel.dart.gcov.xml
+++ b/doc/coverage/xml/_impl/native/_worker_channel.dart.gcov.xml
@@ -1,5 +1,5 @@
-import 'dart:async';
diff --git a/doc/coverage/xml/_impl/native/_worker_runner.dart.gcov.xml b/doc/coverage/xml/_impl/native/_worker_runner.dart.gcov.xml
index 723b2281..0f6a52f0 100644
--- a/doc/coverage/xml/_impl/native/_worker_runner.dart.gcov.xml
+++ b/doc/coverage/xml/_impl/native/_worker_runner.dart.gcov.xml
@@ -1,5 +1,5 @@
-import '../../worker/worker_request.dart';
diff --git a/doc/coverage/xml/_impl/native/index.xml b/doc/coverage/xml/_impl/native/index.xml
index 6919f3ca..1911262f 100644
--- a/doc/coverage/xml/_impl/native/index.xml
+++ b/doc/coverage/xml/_impl/native/index.xml
@@ -1,5 +1,5 @@
-import 'dart:async';
@@ -143,21 +143,21 @@
void fail(SquadronException ex) {
- if (!ready.isCompleted) ready.completeError(ex);
- if (!completer.isCompleted) completer.completeError(ex);
- }
-
@@ -187,32 +187,28 @@
try {
- worker = web.Worker(webEntryPoint.uri.toJS);
setDbgId(worker, '${webEntryPoint.uri}#');
-
void $errorHandler(web.ErrorEvent? e) {
- final err = getErrorEventError(e)?.toString() ??
- getErrorEventMessage(e) ??
- 'Unknown error';
@@ -227,28 +223,28 @@
logger?.e(() => 'Connection to Web Worker failed: $error');
fail(error);
-
UriChecker.exists(entryPoint).then((found) {
- try {
- final msg = (e != null)
- ? '$entryPoint => ${err.runtimeType} $err [${e.filename}(${e.lineno})]'
- : '$entryPoint => ${err.runtimeType} $err';
@@ -276,13 +272,13 @@
}
});
- }
-
@@ -304,21 +300,21 @@
worker.onmessage = (web.MessageEvent? e) {
- try {
- final response = WorkerResponseExt.from(getMessageEventData(e) as List);
- if (!response.unwrapInPlace(disconnected)) {
- return;
@@ -332,17 +328,17 @@
final error = response.error;
if (error != null) {
- logger?.e(() => 'Connection to Web Worker failed: $error');
fail(error);
- } else if (!ready.isCompleted) {
@@ -534,17 +530,17 @@
return channel;
} catch (ex, st) {
- ready.future.ignore();
- completer.future.ignore();
- logger?.t('Failed to create Web Worker for $entryPoint');
@@ -559,9 +555,9 @@
worker.terminate();
throw SquadronException.from(ex, st);
- } finally {
diff --git a/doc/coverage/xml/_impl/web/_channel_impl.dart.gcov.xml b/doc/coverage/xml/_impl/web/_channel_impl.dart.gcov.xml
index 674a08d6..b5b6466f 100644
--- a/doc/coverage/xml/_impl/web/_channel_impl.dart.gcov.xml
+++ b/doc/coverage/xml/_impl/web/_channel_impl.dart.gcov.xml
@@ -1,5 +1,5 @@
-part of '_channel.dart';
@@ -62,9 +62,8 @@
@override
PlatformChannel serialize() => _sendPort;
-
@@ -75,9 +74,9 @@
@override
Channel share() => _WebForwardChannel._(
- _sendPort, web.MessageChannel(), logger, exceptionManager);
@@ -246,7 +245,7 @@
@override
FutureOr close() {
+ FutureOr<void> close() {
@override
FutureOr cancelStream(int streamId) {
+ FutureOr<void> cancelStream(int streamId) {
if (!_closed) {
@@ -304,7 +303,7 @@
@override
FutureOr cancelToken(SquadronCancelationToken? token) {
+ FutureOr<void> cancelToken(SquadronCancelationToken? token) {
import 'dart:js_interop';
@@ -19,9 +19,6 @@
import '../../exceptions/squadron_error.dart';
import '_patch.dart';
-
void release() {
if (_revoke) {
- web.URL.revokeObjectURL(uri);
- }
- super.release();
- }
-
- static String _getUrl(Uri uri) {
- var url = uri.toString();
- if (url.startsWith('~')) {
- final root = getHome();
- if (root != null) {
+ if (_revoke) {
url = '$root${url.substring(1)}';
+ web.URL.revokeObjectURL(uri);
}
- }
return url;
+ super.release();
}
-
@@ -139,7 +95,7 @@
// a JavaScript worker
return EntryPointUri._(_getUrl(workerEntrypoint), revoke: false);
+ return EntryPointUri._(workerEntrypoint.toString(), revoke: false);
final blob = web.Blob(
[wasmLoaderScript(_getUrl(workerEntrypoint)).toJS].toJS,
+ [wasmLoaderScript(workerEntrypoint.toString()).toJS].toJS,
import 'dart:async';
diff --git a/doc/coverage/xml/_impl/web/_local_worker.dart.gcov.xml b/doc/coverage/xml/_impl/web/_local_worker.dart.gcov.xml
index 61147250..2a8da50b 100644
--- a/doc/coverage/xml/_impl/web/_local_worker.dart.gcov.xml
+++ b/doc/coverage/xml/_impl/web/_local_worker.dart.gcov.xml
@@ -1,5 +1,5 @@
-import 'dart:async';
diff --git a/doc/coverage/xml/_impl/web/_patch.dart.gcov.xml b/doc/coverage/xml/_impl/web/_patch.dart.gcov.xml
index 1df1d83f..e0349f78 100644
--- a/doc/coverage/xml/_impl/web/_patch.dart.gcov.xml
+++ b/doc/coverage/xml/_impl/web/_patch.dart.gcov.xml
@@ -1,5 +1,5 @@
-import 'dart:js_interop';
@@ -16,80 +16,35 @@
@JS()
- external DedicatedWorkerGlobalScope get self;
-
- String? getHome() {
- if (window.isUndefinedOrNull) return null;
final components = window.location.pathname.split('/');
- return components.take(components.length - 1).join('/');
- }
-
- const _dbgIdProp = '@@dbgid';
-
- void setDbgId(JSObject obj, String id) {
- obj[_dbgIdProp] = id.toJS;
- }
-
+ String getDbgId(JSObject obj) {
- return obj.has(_dbgIdProp)
- ? obj[_dbgIdProp].dartify().toString()
- : '($_dbgIdProp not set)';
- }
+
String? getErrorEventMessage(JSObject? obj) {
- if (obj != null && obj.has('message')) {
- return obj['message']?.toString();
@@ -97,27 +52,27 @@
} else {
return null;
- }
}
-
Object? getErrorEventError(JSObject? obj) {
- if (obj != null && obj.has('error')) {
- return obj['error'].dartify();
@@ -125,34 +80,34 @@
} else {
return null;
- }
}
-
List? getMessageEventData(JSObject? obj) {
- if (obj != null && obj.has('data')) {
- final data = obj['data'].dartify();
return (data == null) ? null : (data as List);
- } else {
@@ -163,9 +118,9 @@
}
}
- import '../../converters/cast_converter.dart';
@@ -10,6 +10,9 @@
import '../../squadron_platform_type.dart';
import '_patch.dart';
+
: SquadronPlatformType.wasm; // Web Assembly
+ Uri mapUrl(String url) {
+ if (url.startsWith('~')) {
+ final root = getHome();
+ if (root != null) {
+ url = '$root${url.substring(1)}';
+ }
+ }
+ return Uri.parse(url);
+ }
+ import 'dart:async';
diff --git a/doc/coverage/xml/_impl/web/_uri_checker.dart.gcov.xml b/doc/coverage/xml/_impl/web/_uri_checker.dart.gcov.xml
index 4bc21a28..cead20c4 100644
--- a/doc/coverage/xml/_impl/web/_uri_checker.dart.gcov.xml
+++ b/doc/coverage/xml/_impl/web/_uri_checker.dart.gcov.xml
@@ -1,5 +1,5 @@
-import 'dart:js_interop';
@@ -31,13 +31,13 @@
static Future<bool> exists(Uri url) async {
- if (url.isScheme('data')) return true;
- try {
@@ -45,13 +45,13 @@
final res =
await fetch(url.toString().toJS, {'method': 'HEAD'}.jsify()).toDart;
- return res.ok && (200 <= res.status) && (res.status < 300);
- } catch (_) {
@@ -62,9 +62,9 @@
}
}
- }
diff --git a/doc/coverage/xml/_impl/web/_worker_channel.dart.gcov.xml b/doc/coverage/xml/_impl/web/_worker_channel.dart.gcov.xml
index fe0af35f..7f4681e8 100644
--- a/doc/coverage/xml/_impl/web/_worker_channel.dart.gcov.xml
+++ b/doc/coverage/xml/_impl/web/_worker_channel.dart.gcov.xml
@@ -1,5 +1,5 @@
-import 'dart:async';
diff --git a/doc/coverage/xml/_impl/web/_worker_runner.dart.gcov.xml b/doc/coverage/xml/_impl/web/_worker_runner.dart.gcov.xml
index 5b31c280..a0fdaa79 100644
--- a/doc/coverage/xml/_impl/web/_worker_runner.dart.gcov.xml
+++ b/doc/coverage/xml/_impl/web/_worker_runner.dart.gcov.xml
@@ -1,5 +1,5 @@
-import 'package:web/web.dart' as web;
diff --git a/doc/coverage/xml/_impl/web/index.xml b/doc/coverage/xml/_impl/web/index.xml
index f90546b5..9e28d7e0 100644
--- a/doc/coverage/xml/_impl/web/index.xml
+++ b/doc/coverage/xml/_impl/web/index.xml
@@ -1,14 +1,14 @@
-import 'dart:async';
diff --git a/doc/coverage/xml/_impl/xplat/_forward_completer.dart.gcov.xml b/doc/coverage/xml/_impl/xplat/_forward_completer.dart.gcov.xml
index d0cc678b..4d1afd8c 100644
--- a/doc/coverage/xml/_impl/xplat/_forward_completer.dart.gcov.xml
+++ b/doc/coverage/xml/_impl/xplat/_forward_completer.dart.gcov.xml
@@ -1,5 +1,5 @@
-import 'dart:async';
diff --git a/doc/coverage/xml/_impl/xplat/_forward_stream_controller.dart.gcov.xml b/doc/coverage/xml/_impl/xplat/_forward_stream_controller.dart.gcov.xml
index 713d2779..d57c8150 100644
--- a/doc/coverage/xml/_impl/xplat/_forward_stream_controller.dart.gcov.xml
+++ b/doc/coverage/xml/_impl/xplat/_forward_stream_controller.dart.gcov.xml
@@ -1,5 +1,5 @@
-import 'dart:async';
diff --git a/doc/coverage/xml/_impl/xplat/_helpers.dart.gcov.xml b/doc/coverage/xml/_impl/xplat/_helpers.dart.gcov.xml
deleted file mode 100644
index 8089d863..00000000
--- a/doc/coverage/xml/_impl/xplat/_helpers.dart.gcov.xml
+++ /dev/null
@@ -1,67 +0,0 @@
-
-final _latestUPDEpoch = DateTime.utc(2020, 02, 02); // universal palindrome date
-
- int microsecTimeStamp([DateTime? time]) =>
- (time ?? DateTime.now()).toUtc().difference(_latestUPDEpoch).inMicroseconds;
-
- DateTime? fromMicrosecTimeStamp(int? microsecs) => (microsecs == null)
- ? null
- : _latestUPDEpoch.add(Duration(microseconds: microsecs));
-
- extension FutureExt on Future {
- Future<void> ignore() async {
- try {
- final _ = await this;
- } catch (_) {
- /* ignore */
- }
- }
- }
- import 'package:logger/logger.dart';
diff --git a/doc/coverage/xml/_impl/xplat/_result_stream.dart.gcov.xml b/doc/coverage/xml/_impl/xplat/_result_stream.dart.gcov.xml
index 5b984abb..7c5e30b0 100644
--- a/doc/coverage/xml/_impl/xplat/_result_stream.dart.gcov.xml
+++ b/doc/coverage/xml/_impl/xplat/_result_stream.dart.gcov.xml
@@ -1,5 +1,5 @@
-import 'dart:async';
diff --git a/doc/coverage/xml/_impl/xplat/_token_id.dart.gcov.xml b/doc/coverage/xml/_impl/xplat/_token_id.dart.gcov.xml
index 3a9f5157..78244228 100644
--- a/doc/coverage/xml/_impl/xplat/_token_id.dart.gcov.xml
+++ b/doc/coverage/xml/_impl/xplat/_token_id.dart.gcov.xml
@@ -1,5 +1,5 @@
-import '../../typedefs.dart';
diff --git a/doc/coverage/xml/_impl/xplat/_transferables.dart.gcov.xml b/doc/coverage/xml/_impl/xplat/_transferables.dart.gcov.xml
index e02e04dd..9762bf54 100644
--- a/doc/coverage/xml/_impl/xplat/_transferables.dart.gcov.xml
+++ b/doc/coverage/xml/_impl/xplat/_transferables.dart.gcov.xml
@@ -1,5 +1,5 @@
-import '../../exceptions/squadron_error.dart';
diff --git a/doc/coverage/xml/_impl/xplat/_worker_runner.dart.gcov.xml b/doc/coverage/xml/_impl/xplat/_worker_runner.dart.gcov.xml
index c0d022ab..6a6641cc 100644
--- a/doc/coverage/xml/_impl/xplat/_worker_runner.dart.gcov.xml
+++ b/doc/coverage/xml/_impl/xplat/_worker_runner.dart.gcov.xml
@@ -1,5 +1,5 @@
-import 'dart:async';
diff --git a/doc/coverage/xml/_impl/xplat/index.xml b/doc/coverage/xml/_impl/xplat/index.xml
index c3b724b9..865befdf 100644
--- a/doc/coverage/xml/_impl/xplat/index.xml
+++ b/doc/coverage/xml/_impl/xplat/index.xml
@@ -1,9 +1,12 @@
-import '../channel.dart';
diff --git a/doc/coverage/xml/annotations/squadron_service.dart.gcov.xml b/doc/coverage/xml/annotations/squadron_service.dart.gcov.xml
index 0f823223..6480af8f 100644
--- a/doc/coverage/xml/annotations/squadron_service.dart.gcov.xml
+++ b/doc/coverage/xml/annotations/squadron_service.dart.gcov.xml
@@ -1,5 +1,5 @@
-