diff --git a/dwds/CHANGELOG.md b/dwds/CHANGELOG.md index aa97c636b..d44f1a338 100644 --- a/dwds/CHANGELOG.md +++ b/dwds/CHANGELOG.md @@ -1,5 +1,8 @@ -## 24.4.1-wip +## 24.4.1 +- Implemented a WebSocket-based communication protocol that provides essential developer tooling (hot reload, service extensions) when Chrome debugger access is unavailable. - [#2605](https://github.com/dart-lang/webdev/issues/2605) +- Added WebSocket-based hot reload and service extension support via new `WebSocketProxyService` class that implements VM service protocol over WebSockets. +- Enhanced `DevHandler` with `useWebSocketConnection` flag to toggle between Chrome-based and WebSocket-based communication protocols. - Fixed an issue where we didn't wait until all scripts were parsed before recomputing metadata on a hot reload. diff --git a/dwds/lib/dart_web_debug_service.dart b/dwds/lib/dart_web_debug_service.dart index ff960f0f0..587e8af43 100644 --- a/dwds/lib/dart_web_debug_service.dart +++ b/dwds/lib/dart_web_debug_service.dart @@ -31,6 +31,7 @@ class Dwds { final DevHandler _devHandler; final AssetReader _assetReader; final bool _enableDebugging; + final bool _useDwdsWebSocketConnection; Dwds._( this.middleware, @@ -38,6 +39,7 @@ class Dwds { this._devHandler, this._assetReader, this._enableDebugging, + this._useDwdsWebSocketConnection, ) : handler = _devHandler.handler; Stream get connectedApps => _devHandler.connectedApps; @@ -53,12 +55,18 @@ class Dwds { await _assetReader.close(); } + /// Creates a debug connection for the given app connection. + /// + /// Returns a [DebugConnection] that wraps the appropriate debug services + /// based on the connection type (WebSocket or Chrome-based). Future debugConnection(AppConnection appConnection) async { if (!_enableDebugging) throw StateError('Debugging is not enabled.'); - final appDebugServices = await _devHandler.loadAppServices(appConnection); - final chromeProxyService = appDebugServices.chromeProxyService; - await chromeProxyService.isInitialized; - return DebugConnection(appDebugServices); + + if (_useDwdsWebSocketConnection) { + return await _devHandler.createDebugConnectionForWebSocket(appConnection); + } else { + return await _devHandler.createDebugConnectionForChrome(appConnection); + } } static Future start({ @@ -123,10 +131,7 @@ class Dwds { _logger.info('Serving DevTools at $uri\n'); } - final injected = DwdsInjector( - extensionUri: extensionUri, - useDwdsWebSocketConnection: useDwdsWebSocketConnection, - ); + final injected = DwdsInjector(extensionUri: extensionUri); final devHandler = DevHandler( chromeConnection, @@ -143,6 +148,7 @@ class Dwds { debugSettings.spawnDds, debugSettings.ddsPort, debugSettings.launchDevToolsInNewWindow, + useWebSocketConnection: useDwdsWebSocketConnection, ); return Dwds._( @@ -151,6 +157,7 @@ class Dwds { devHandler, assetReader, debugSettings.enableDebugging, + useDwdsWebSocketConnection, ); } } diff --git a/dwds/lib/data/serializers.dart b/dwds/lib/data/serializers.dart index 11755912f..4d6614f85 100644 --- a/dwds/lib/data/serializers.dart +++ b/dwds/lib/data/serializers.dart @@ -14,6 +14,8 @@ import 'error_response.dart'; import 'extension_request.dart'; import 'hot_reload_request.dart'; import 'hot_reload_response.dart'; +import 'service_extension_request.dart'; +import 'service_extension_response.dart'; import 'isolate_events.dart'; import 'register_event.dart'; import 'run_request.dart'; @@ -40,5 +42,7 @@ part 'serializers.g.dart'; ErrorResponse, RegisterEvent, RunRequest, + ServiceExtensionRequest, + ServiceExtensionResponse, ]) final Serializers serializers = _$serializers; diff --git a/dwds/lib/data/serializers.g.dart b/dwds/lib/data/serializers.g.dart index 3f229a323..a061bae9e 100644 --- a/dwds/lib/data/serializers.g.dart +++ b/dwds/lib/data/serializers.g.dart @@ -27,6 +27,8 @@ Serializers _$serializers = ..add(IsolateStart.serializer) ..add(RegisterEvent.serializer) ..add(RunRequest.serializer) + ..add(ServiceExtensionRequest.serializer) + ..add(ServiceExtensionResponse.serializer) ..addBuilderFactory( const FullType(BuiltList, const [const FullType(DebugEvent)]), () => new ListBuilder(), diff --git a/dwds/lib/data/service_extension_request.dart b/dwds/lib/data/service_extension_request.dart new file mode 100644 index 000000000..7539a9b3b --- /dev/null +++ b/dwds/lib/data/service_extension_request.dart @@ -0,0 +1,43 @@ +// Copyright (c) 2025, the Dart project authors. All rights reserved. +// Defines the request for service extension calls over WebSocket. + +import 'dart:convert'; +import 'package:built_value/built_value.dart'; +import 'package:built_value/serializer.dart'; + +part 'service_extension_request.g.dart'; + +abstract class ServiceExtensionRequest + implements Built { + String get id; + String get method; + String + get argsJson; // Store args as JSON string for built_value compatibility + + // Helper method to get args as Map + Map get args => + argsJson.isEmpty + ? {} + : json.decode(argsJson) as Map; + + ServiceExtensionRequest._(); + factory ServiceExtensionRequest([ + void Function(ServiceExtensionRequestBuilder) updates, + ]) = _$ServiceExtensionRequest; + + // Convenient factory method to create with args Map + factory ServiceExtensionRequest.fromArgs({ + required String id, + required String method, + required Map args, + }) => ServiceExtensionRequest( + (b) => + b + ..id = id + ..method = method + ..argsJson = json.encode(args), + ); + + static Serializer get serializer => + _$serviceExtensionRequestSerializer; +} diff --git a/dwds/lib/data/service_extension_request.g.dart b/dwds/lib/data/service_extension_request.g.dart new file mode 100644 index 000000000..94379fd36 --- /dev/null +++ b/dwds/lib/data/service_extension_request.g.dart @@ -0,0 +1,228 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'service_extension_request.dart'; + +// ************************************************************************** +// BuiltValueGenerator +// ************************************************************************** + +Serializer _$serviceExtensionRequestSerializer = + new _$ServiceExtensionRequestSerializer(); + +class _$ServiceExtensionRequestSerializer + implements StructuredSerializer { + @override + final Iterable types = const [ + ServiceExtensionRequest, + _$ServiceExtensionRequest, + ]; + @override + final String wireName = 'ServiceExtensionRequest'; + + @override + Iterable serialize( + Serializers serializers, + ServiceExtensionRequest object, { + FullType specifiedType = FullType.unspecified, + }) { + final result = [ + 'id', + serializers.serialize(object.id, specifiedType: const FullType(String)), + 'method', + serializers.serialize( + object.method, + specifiedType: const FullType(String), + ), + 'argsJson', + serializers.serialize( + object.argsJson, + specifiedType: const FullType(String), + ), + ]; + + return result; + } + + @override + ServiceExtensionRequest deserialize( + Serializers serializers, + Iterable serialized, { + FullType specifiedType = FullType.unspecified, + }) { + final result = new ServiceExtensionRequestBuilder(); + + final iterator = serialized.iterator; + while (iterator.moveNext()) { + final key = iterator.current! as String; + iterator.moveNext(); + final Object? value = iterator.current; + switch (key) { + case 'id': + result.id = + serializers.deserialize( + value, + specifiedType: const FullType(String), + )! + as String; + break; + case 'method': + result.method = + serializers.deserialize( + value, + specifiedType: const FullType(String), + )! + as String; + break; + case 'argsJson': + result.argsJson = + serializers.deserialize( + value, + specifiedType: const FullType(String), + )! + as String; + break; + } + } + + return result.build(); + } +} + +class _$ServiceExtensionRequest extends ServiceExtensionRequest { + @override + final String id; + @override + final String method; + @override + final String argsJson; + + factory _$ServiceExtensionRequest([ + void Function(ServiceExtensionRequestBuilder)? updates, + ]) => (new ServiceExtensionRequestBuilder()..update(updates))._build(); + + _$ServiceExtensionRequest._({ + required this.id, + required this.method, + required this.argsJson, + }) : super._() { + BuiltValueNullFieldError.checkNotNull(id, r'ServiceExtensionRequest', 'id'); + BuiltValueNullFieldError.checkNotNull( + method, + r'ServiceExtensionRequest', + 'method', + ); + BuiltValueNullFieldError.checkNotNull( + argsJson, + r'ServiceExtensionRequest', + 'argsJson', + ); + } + + @override + ServiceExtensionRequest rebuild( + void Function(ServiceExtensionRequestBuilder) updates, + ) => (toBuilder()..update(updates)).build(); + + @override + ServiceExtensionRequestBuilder toBuilder() => + new ServiceExtensionRequestBuilder()..replace(this); + + @override + bool operator ==(Object other) { + if (identical(other, this)) return true; + return other is ServiceExtensionRequest && + id == other.id && + method == other.method && + argsJson == other.argsJson; + } + + @override + int get hashCode { + var _$hash = 0; + _$hash = $jc(_$hash, id.hashCode); + _$hash = $jc(_$hash, method.hashCode); + _$hash = $jc(_$hash, argsJson.hashCode); + _$hash = $jf(_$hash); + return _$hash; + } + + @override + String toString() { + return (newBuiltValueToStringHelper(r'ServiceExtensionRequest') + ..add('id', id) + ..add('method', method) + ..add('argsJson', argsJson)) + .toString(); + } +} + +class ServiceExtensionRequestBuilder + implements + Builder { + _$ServiceExtensionRequest? _$v; + + String? _id; + String? get id => _$this._id; + set id(String? id) => _$this._id = id; + + String? _method; + String? get method => _$this._method; + set method(String? method) => _$this._method = method; + + String? _argsJson; + String? get argsJson => _$this._argsJson; + set argsJson(String? argsJson) => _$this._argsJson = argsJson; + + ServiceExtensionRequestBuilder(); + + ServiceExtensionRequestBuilder get _$this { + final $v = _$v; + if ($v != null) { + _id = $v.id; + _method = $v.method; + _argsJson = $v.argsJson; + _$v = null; + } + return this; + } + + @override + void replace(ServiceExtensionRequest other) { + ArgumentError.checkNotNull(other, 'other'); + _$v = other as _$ServiceExtensionRequest; + } + + @override + void update(void Function(ServiceExtensionRequestBuilder)? updates) { + if (updates != null) updates(this); + } + + @override + ServiceExtensionRequest build() => _build(); + + _$ServiceExtensionRequest _build() { + final _$result = + _$v ?? + new _$ServiceExtensionRequest._( + id: BuiltValueNullFieldError.checkNotNull( + id, + r'ServiceExtensionRequest', + 'id', + ), + method: BuiltValueNullFieldError.checkNotNull( + method, + r'ServiceExtensionRequest', + 'method', + ), + argsJson: BuiltValueNullFieldError.checkNotNull( + argsJson, + r'ServiceExtensionRequest', + 'argsJson', + ), + ); + replace(_$result); + return _$result; + } +} + +// ignore_for_file: deprecated_member_use_from_same_package,type=lint diff --git a/dwds/lib/data/service_extension_response.dart b/dwds/lib/data/service_extension_response.dart new file mode 100644 index 000000000..854526951 --- /dev/null +++ b/dwds/lib/data/service_extension_response.dart @@ -0,0 +1,50 @@ +// Copyright (c) 2025, the Dart project authors. All rights reserved. +// Defines the response for service extension calls over WebSocket. + +import 'dart:convert'; +import 'package:built_value/built_value.dart'; +import 'package:built_value/serializer.dart'; + +part 'service_extension_response.g.dart'; + +abstract class ServiceExtensionResponse + implements + Built { + String get id; + String? + get resultJson; // Store result as JSON string for built_value compatibility + bool get success; + int? get errorCode; + String? get errorMessage; + + // Helper method to get result as Map + Map? get result => + resultJson == null || resultJson!.isEmpty + ? null + : json.decode(resultJson!) as Map; + + ServiceExtensionResponse._(); + factory ServiceExtensionResponse([ + void Function(ServiceExtensionResponseBuilder) updates, + ]) = _$ServiceExtensionResponse; + + // Convenient factory method to create with result Map + factory ServiceExtensionResponse.fromResult({ + required String id, + required bool success, + Map? result, + int? errorCode, + String? errorMessage, + }) => ServiceExtensionResponse( + (b) => + b + ..id = id + ..success = success + ..resultJson = result != null ? json.encode(result) : null + ..errorCode = errorCode + ..errorMessage = errorMessage, + ); + + static Serializer get serializer => + _$serviceExtensionResponseSerializer; +} diff --git a/dwds/lib/data/service_extension_response.g.dart b/dwds/lib/data/service_extension_response.g.dart new file mode 100644 index 000000000..e840cf2b4 --- /dev/null +++ b/dwds/lib/data/service_extension_response.g.dart @@ -0,0 +1,277 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'service_extension_response.dart'; + +// ************************************************************************** +// BuiltValueGenerator +// ************************************************************************** + +Serializer _$serviceExtensionResponseSerializer = + new _$ServiceExtensionResponseSerializer(); + +class _$ServiceExtensionResponseSerializer + implements StructuredSerializer { + @override + final Iterable types = const [ + ServiceExtensionResponse, + _$ServiceExtensionResponse, + ]; + @override + final String wireName = 'ServiceExtensionResponse'; + + @override + Iterable serialize( + Serializers serializers, + ServiceExtensionResponse object, { + FullType specifiedType = FullType.unspecified, + }) { + final result = [ + 'id', + serializers.serialize(object.id, specifiedType: const FullType(String)), + 'success', + serializers.serialize( + object.success, + specifiedType: const FullType(bool), + ), + ]; + Object? value; + value = object.resultJson; + if (value != null) { + result + ..add('resultJson') + ..add( + serializers.serialize(value, specifiedType: const FullType(String)), + ); + } + value = object.errorCode; + if (value != null) { + result + ..add('errorCode') + ..add(serializers.serialize(value, specifiedType: const FullType(int))); + } + value = object.errorMessage; + if (value != null) { + result + ..add('errorMessage') + ..add( + serializers.serialize(value, specifiedType: const FullType(String)), + ); + } + return result; + } + + @override + ServiceExtensionResponse deserialize( + Serializers serializers, + Iterable serialized, { + FullType specifiedType = FullType.unspecified, + }) { + final result = new ServiceExtensionResponseBuilder(); + + final iterator = serialized.iterator; + while (iterator.moveNext()) { + final key = iterator.current! as String; + iterator.moveNext(); + final Object? value = iterator.current; + switch (key) { + case 'id': + result.id = + serializers.deserialize( + value, + specifiedType: const FullType(String), + )! + as String; + break; + case 'resultJson': + result.resultJson = + serializers.deserialize( + value, + specifiedType: const FullType(String), + ) + as String?; + break; + case 'success': + result.success = + serializers.deserialize( + value, + specifiedType: const FullType(bool), + )! + as bool; + break; + case 'errorCode': + result.errorCode = + serializers.deserialize(value, specifiedType: const FullType(int)) + as int?; + break; + case 'errorMessage': + result.errorMessage = + serializers.deserialize( + value, + specifiedType: const FullType(String), + ) + as String?; + break; + } + } + + return result.build(); + } +} + +class _$ServiceExtensionResponse extends ServiceExtensionResponse { + @override + final String id; + @override + final String? resultJson; + @override + final bool success; + @override + final int? errorCode; + @override + final String? errorMessage; + + factory _$ServiceExtensionResponse([ + void Function(ServiceExtensionResponseBuilder)? updates, + ]) => (new ServiceExtensionResponseBuilder()..update(updates))._build(); + + _$ServiceExtensionResponse._({ + required this.id, + this.resultJson, + required this.success, + this.errorCode, + this.errorMessage, + }) : super._() { + BuiltValueNullFieldError.checkNotNull( + id, + r'ServiceExtensionResponse', + 'id', + ); + BuiltValueNullFieldError.checkNotNull( + success, + r'ServiceExtensionResponse', + 'success', + ); + } + + @override + ServiceExtensionResponse rebuild( + void Function(ServiceExtensionResponseBuilder) updates, + ) => (toBuilder()..update(updates)).build(); + + @override + ServiceExtensionResponseBuilder toBuilder() => + new ServiceExtensionResponseBuilder()..replace(this); + + @override + bool operator ==(Object other) { + if (identical(other, this)) return true; + return other is ServiceExtensionResponse && + id == other.id && + resultJson == other.resultJson && + success == other.success && + errorCode == other.errorCode && + errorMessage == other.errorMessage; + } + + @override + int get hashCode { + var _$hash = 0; + _$hash = $jc(_$hash, id.hashCode); + _$hash = $jc(_$hash, resultJson.hashCode); + _$hash = $jc(_$hash, success.hashCode); + _$hash = $jc(_$hash, errorCode.hashCode); + _$hash = $jc(_$hash, errorMessage.hashCode); + _$hash = $jf(_$hash); + return _$hash; + } + + @override + String toString() { + return (newBuiltValueToStringHelper(r'ServiceExtensionResponse') + ..add('id', id) + ..add('resultJson', resultJson) + ..add('success', success) + ..add('errorCode', errorCode) + ..add('errorMessage', errorMessage)) + .toString(); + } +} + +class ServiceExtensionResponseBuilder + implements + Builder { + _$ServiceExtensionResponse? _$v; + + String? _id; + String? get id => _$this._id; + set id(String? id) => _$this._id = id; + + String? _resultJson; + String? get resultJson => _$this._resultJson; + set resultJson(String? resultJson) => _$this._resultJson = resultJson; + + bool? _success; + bool? get success => _$this._success; + set success(bool? success) => _$this._success = success; + + int? _errorCode; + int? get errorCode => _$this._errorCode; + set errorCode(int? errorCode) => _$this._errorCode = errorCode; + + String? _errorMessage; + String? get errorMessage => _$this._errorMessage; + set errorMessage(String? errorMessage) => _$this._errorMessage = errorMessage; + + ServiceExtensionResponseBuilder(); + + ServiceExtensionResponseBuilder get _$this { + final $v = _$v; + if ($v != null) { + _id = $v.id; + _resultJson = $v.resultJson; + _success = $v.success; + _errorCode = $v.errorCode; + _errorMessage = $v.errorMessage; + _$v = null; + } + return this; + } + + @override + void replace(ServiceExtensionResponse other) { + ArgumentError.checkNotNull(other, 'other'); + _$v = other as _$ServiceExtensionResponse; + } + + @override + void update(void Function(ServiceExtensionResponseBuilder)? updates) { + if (updates != null) updates(this); + } + + @override + ServiceExtensionResponse build() => _build(); + + _$ServiceExtensionResponse _build() { + final _$result = + _$v ?? + new _$ServiceExtensionResponse._( + id: BuiltValueNullFieldError.checkNotNull( + id, + r'ServiceExtensionResponse', + 'id', + ), + resultJson: resultJson, + success: BuiltValueNullFieldError.checkNotNull( + success, + r'ServiceExtensionResponse', + 'success', + ), + errorCode: errorCode, + errorMessage: errorMessage, + ); + replace(_$result); + return _$result; + } +} + +// ignore_for_file: deprecated_member_use_from_same_package,type=lint diff --git a/dwds/lib/src/connections/debug_connection.dart b/dwds/lib/src/connections/debug_connection.dart index 271331eb3..06efd932c 100644 --- a/dwds/lib/src/connections/debug_connection.dart +++ b/dwds/lib/src/connections/debug_connection.dart @@ -22,9 +22,11 @@ class DebugConnection { Future? _closed; DebugConnection(this._appDebugServices) { - _appDebugServices.chromeProxyService.remoteDebugger.onClose.first.then((_) { - close(); - }); + // Only setup Chrome-specific close handling if we have a ChromeProxyService + final proxyService = _appDebugServices.proxyService; + if (proxyService is ChromeProxyService) { + proxyService.remoteDebugger.onClose.first.then((_) => close()); + } } /// The port of the host Dart VM Service. @@ -41,7 +43,10 @@ class DebugConnection { Future close() => _closed ??= () async { - await _appDebugServices.chromeProxyService.remoteDebugger.close(); + final proxyService = _appDebugServices.proxyService; + if (proxyService is ChromeProxyService) { + await proxyService.remoteDebugger.close(); + } await _appDebugServices.close(); _onDoneCompleter.complete(); }(); @@ -50,5 +55,10 @@ class DebugConnection { } /// [ChromeProxyService] of a [DebugConnection] for internal use only. -ChromeProxyService fetchChromeProxyService(DebugConnection debugConnection) => - debugConnection._appDebugServices.chromeProxyService; +ChromeProxyService fetchChromeProxyService(DebugConnection debugConnection) { + final service = debugConnection._appDebugServices.proxyService; + if (service is ChromeProxyService) { + return service; + } + throw StateError('ChromeProxyService not available in this debug connection'); +} diff --git a/dwds/lib/src/dwds_vm_client.dart b/dwds/lib/src/dwds_vm_client.dart index 34285c718..815e51e3d 100644 --- a/dwds/lib/src/dwds_vm_client.dart +++ b/dwds/lib/src/dwds_vm_client.dart @@ -9,6 +9,8 @@ import 'package:dwds/src/events.dart'; import 'package:dwds/src/services/chrome_debug_exception.dart'; import 'package:dwds/src/services/chrome_proxy_service.dart'; import 'package:dwds/src/services/debug_service.dart'; +import 'package:dwds/src/services/proxy_service.dart'; +import 'package:dwds/src/services/web_socket_proxy_service.dart'; import 'package:dwds/src/utilities/synchronized.dart'; import 'package:logging/logging.dart'; import 'package:uuid/uuid.dart'; @@ -17,8 +19,6 @@ import 'package:vm_service/vm_service_io.dart'; import 'package:vm_service_interface/vm_service_interface.dart'; import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart'; -final _logger = Logger('DwdsVmClient'); - /// Type of requests added to the request controller. typedef VmRequest = Map; @@ -38,9 +38,22 @@ enum _NamespacedServiceExtension { final String method; } +/// Common interface for DWDS VM clients. +abstract class DwdsVmClient { + /// The VM service client. + VmService get client; + + /// Closes the VM client and releases resources. + Future close(); +} + +// Chrome-based DWDS VM client logger. +final _chromeLogger = Logger('DwdsVmClient'); + // A client of the vm service that registers some custom extensions like // hotRestart. -class DwdsVmClient { +class ChromeDwdsVmClient implements DwdsVmClient { + @override final VmService client; final StreamController> _requestController; final StreamController> _responseController; @@ -53,8 +66,13 @@ class DwdsVmClient { /// Synchronizes hot restarts to avoid races. final _hotRestartQueue = AtomicQueue(); - DwdsVmClient(this.client, this._requestController, this._responseController); + ChromeDwdsVmClient( + this.client, + this._requestController, + this._responseController, + ); + @override Future close() => _closed ??= () async { await _requestController.close(); @@ -62,13 +80,12 @@ class DwdsVmClient { await client.dispose(); }(); - static Future create( - DebugService debugService, + static Future create( + ChromeDebugService debugService, DwdsStats dwdsStats, Uri? ddsUri, ) async { - final chromeProxyService = - debugService.chromeProxyService as ChromeProxyService; + final chromeProxyService = debugService.chromeProxyService; final responseController = StreamController(); final responseSink = responseController.sink; // Response stream must be a broadcast stream so that it can have multiple @@ -104,7 +121,7 @@ class DwdsVmClient { clientCompleter.complete(client); } - final dwdsVmClient = DwdsVmClient( + final dwdsVmClient = ChromeDwdsVmClient( client, requestController, responseController, @@ -137,7 +154,7 @@ class DwdsVmClient { }) { final client = VmService(responseStream.map(jsonEncode), (request) { if (requestController.isClosed) { - _logger.warning( + _chromeLogger.warning( 'Attempted to send a request but the connection is closed:\n\n' '$request', ); @@ -162,7 +179,7 @@ class DwdsVmClient { static void _setUpVmServerConnection({ required ChromeProxyService chromeProxyService, required DwdsStats dwdsStats, - required DebugService debugService, + required ChromeDebugService debugService, required Stream responseStream, required StreamSink responseSink, required Stream requestStream, @@ -205,16 +222,20 @@ class DwdsVmClient { VmRequest? response; final method = request['method']; if (method == _NamespacedServiceExtension.flutterListViews.method) { - response = await _flutterListViewsHandler(chromeProxyService); + response = await flutterListViewsHandler(chromeProxyService); } else if (method == _NamespacedServiceExtension.extDwdsEmitEvent.method) { - response = _extDwdsEmitEventHandler(request); + response = extDwdsEmitEventHandler(request, _chromeLogger); } else if (method == _NamespacedServiceExtension.extDwdsReload.method) { response = await _extDwdsReloadHandler(chromeProxyService); } else if (method == _NamespacedServiceExtension.extDwdsRestart.method) { final client = await clientFuture; response = await _extDwdsRestartHandler(chromeProxyService, client); } else if (method == _NamespacedServiceExtension.extDwdsSendEvent.method) { - response = await _extDwdsSendEventHandler(request, dwdsStats); + response = await extDwdsSendEventHandler( + request, + dwdsStats, + _chromeLogger, + ); } else if (method == _NamespacedServiceExtension.extDwdsScreenshot.method) { response = await _extDwdsScreenshotHandler(chromeProxyService); } @@ -230,21 +251,6 @@ class DwdsVmClient { return response; } - static Future> _flutterListViewsHandler( - ChromeProxyService chromeProxyService, - ) async { - final vm = await chromeProxyService.getVM(); - final isolates = vm.isolates; - return { - 'result': { - 'views': [ - for (final isolate in isolates ?? []) - {'id': isolate.id, 'isolate': isolate.toJson()}, - ], - }, - }; - } - static Future> _extDwdsScreenshotHandler( ChromeProxyService chromeProxyService, ) async { @@ -255,27 +261,6 @@ class DwdsVmClient { return {'result': response.result as Object}; } - static Future> _extDwdsSendEventHandler( - VmResponse request, - DwdsStats dwdsStats, - ) async { - _processSendEvent(request, dwdsStats); - return {'result': Success().toJson()}; - } - - static Map _extDwdsEmitEventHandler(VmResponse request) { - final event = request['params'] as Map?; - if (event != null) { - final type = event['type'] as String?; - final payload = event['payload'] as Map?; - if (type != null && payload != null) { - emitEvent(DwdsEvent(type, payload)); - } - } - - return {'result': Success().toJson()}; - } - static Future> _extDwdsReloadHandler( ChromeProxyService chromeProxyService, ) async { @@ -294,7 +279,7 @@ class DwdsVmClient { static Future _registerServiceExtensions({ required VmService client, required ChromeProxyService chromeProxyService, - required DwdsVmClient dwdsVmClient, + required ChromeDwdsVmClient dwdsVmClient, }) async { client.registerServiceCallback( 'hotRestart', @@ -323,6 +308,188 @@ class DwdsVmClient { } } +// WebSocket-based DWDS VM client logger. +final _webSocketLogger = Logger('WebSocketDwdsVmClient'); + +/// WebSocket-based DWDS VM client. +class WebSocketDwdsVmClient implements DwdsVmClient { + @override + final VmService client; + final StreamController _requestController; + final StreamController _responseController; + Future? _closed; + + WebSocketDwdsVmClient( + this.client, + this._requestController, + this._responseController, + ); + + @override + Future close() => + _closed ??= () async { + await _requestController.close(); + await _responseController.close(); + await client.dispose(); + }(); + + static Future create( + WebSocketDebugService debugService, + ) async { + _webSocketLogger.fine('Creating WebSocket DWDS VM client'); + final webSocketProxyService = debugService.webSocketProxyService; + final responseController = StreamController(); + final responseSink = responseController.sink; + final responseStream = responseController.stream.asBroadcastStream(); + final requestController = StreamController(); + final requestSink = requestController.sink; + final requestStream = requestController.stream; + + _setUpWebSocketVmServerConnection( + webSocketProxyService: webSocketProxyService, + debugService: debugService, + responseStream: responseStream, + responseSink: responseSink, + requestStream: requestStream, + requestSink: requestSink, + ); + + final client = _setUpWebSocketVmClient( + responseStream: responseStream, + requestController: requestController, + requestSink: requestSink, + ); + + _webSocketLogger.fine('WebSocket DWDS VM client created successfully'); + return WebSocketDwdsVmClient(client, requestController, responseController); + } + + static VmService _setUpWebSocketVmClient({ + required Stream responseStream, + required StreamSink requestSink, + required StreamController requestController, + }) { + final client = VmService(responseStream.map(jsonEncode), (request) { + if (requestController.isClosed) { + _webSocketLogger.warning( + 'Attempted to send a request but the connection is closed:\n\n$request', + ); + return; + } + requestSink.add(Map.from(jsonDecode(request))); + }); + return client; + } + + static void _setUpWebSocketVmServerConnection({ + required WebSocketProxyService webSocketProxyService, + required WebSocketDebugService debugService, + required Stream responseStream, + required StreamSink responseSink, + required Stream requestStream, + required StreamSink requestSink, + }) { + responseStream.listen((request) async { + final response = await _maybeHandleWebSocketServiceExtensionRequest( + request, + webSocketProxyService: webSocketProxyService, + ); + if (response != null) { + requestSink.add(response); + } + }); + + final vmServerConnection = VmServerConnection( + requestStream, + responseSink, + debugService.serviceExtensionRegistry, + webSocketProxyService, + ); + + // Register service extensions + for (final extension in _NamespacedServiceExtension.values) { + _webSocketLogger.finest( + 'Registering service extension: ${extension.method}', + ); + debugService.serviceExtensionRegistry.registerExtension( + extension.method, + vmServerConnection, + ); + } + } + + static Future _maybeHandleWebSocketServiceExtensionRequest( + VmResponse request, { + required WebSocketProxyService webSocketProxyService, + }) async { + VmRequest? response; + final method = request['method']; + + _webSocketLogger.finest('Processing service extension method: $method'); + + if (method == _NamespacedServiceExtension.flutterListViews.method) { + response = await flutterListViewsHandler(webSocketProxyService); + } else if (method == _NamespacedServiceExtension.extDwdsEmitEvent.method) { + response = extDwdsEmitEventHandler(request, _webSocketLogger); + } else if (method == _NamespacedServiceExtension.extDwdsReload.method) { + response = {'result': 'Reload not implemented'}; + } else if (method == _NamespacedServiceExtension.extDwdsSendEvent.method) { + response = await extDwdsSendEventHandler(request, null, _webSocketLogger); + } else if (method == _NamespacedServiceExtension.extDwdsScreenshot.method) { + response = {'result': 'Screenshot not implemented'}; + } + + if (response != null) { + response['id'] = request['id'] as String; + response['jsonrpc'] = '2.0'; + } + return response; + } +} + +/// Shared handler for Flutter list views service extension. +Future> flutterListViewsHandler( + ProxyService proxyService, +) async { + final vm = await proxyService.getVM(); + final isolates = vm.isolates; + return { + 'result': { + 'views': [ + for (final isolate in isolates ?? []) + {'id': isolate.id, 'isolate': isolate.toJson()}, + ], + }, + }; +} + +/// Shared handler for DWDS emit event service extension. +Map extDwdsEmitEventHandler(VmResponse request, Logger logger) { + final event = request['params'] as Map?; + if (event != null) { + final type = event['type'] as String?; + final payload = event['payload'] as Map?; + if (type != null && payload != null) { + logger.fine('EmitEvent: $type $payload'); + emitEvent(DwdsEvent(type, payload)); + } + } + return {'result': Success().toJson()}; +} + +/// Shared handler for DWDS send event service extension. +Future> extDwdsSendEventHandler( + VmResponse request, + DwdsStats? dwdsStats, + Logger logger, +) async { + logger.fine('SendEvent: $request'); + if (dwdsStats != null) { + _processSendEvent(request, dwdsStats); + } + return {'result': Success().toJson()}; +} + void _processSendEvent(Map request, DwdsStats dwdsStats) { final event = request['params'] as Map?; if (event == null) return; @@ -331,13 +498,13 @@ void _processSendEvent(Map request, DwdsStats dwdsStats) { switch (type) { case 'DevtoolsEvent': { - _logger.finest('Received DevTools event: $event'); + _chromeLogger.finest('Received DevTools event: $event'); final action = payload?['action'] as String?; final screen = payload?['screen'] as String?; if (screen != null && action == 'pageReady') { _recordDwdsStats(dwdsStats, screen); } else { - _logger.finest('Ignoring unknown event: $event'); + _chromeLogger.finest('Ignoring unknown event: $event'); } } } @@ -351,16 +518,16 @@ void _recordDwdsStats(DwdsStats dwdsStats, String screen) { final devToolLoadTime = DateTime.now().difference(devToolsStart).inMilliseconds; emitEvent(DwdsEvent.devToolsLoad(devToolLoadTime, screen)); - _logger.fine('DevTools load time: $devToolLoadTime ms'); + _chromeLogger.fine('DevTools load time: $devToolLoadTime ms'); } if (debuggerStart != null) { final debuggerReadyTime = DateTime.now().difference(debuggerStart).inMilliseconds; emitEvent(DwdsEvent.debuggerReady(debuggerReadyTime, screen)); - _logger.fine('Debugger ready time: $debuggerReadyTime ms'); + _chromeLogger.fine('Debugger ready time: $debuggerReadyTime ms'); } } else { - _logger.finest('Debugger and DevTools stats are already recorded.'); + _chromeLogger.finest('Debugger and DevTools stats are already recorded.'); } } @@ -381,14 +548,14 @@ Future> _hotRestart( ChromeProxyService chromeProxyService, VmService client, ) async { - _logger.info('Attempting a hot restart'); + _chromeLogger.info('Attempting a hot restart'); chromeProxyService.terminatingIsolates = true; await _disableBreakpointsAndResume(client, chromeProxyService); try { - _logger.info('Attempting to get execution context ID.'); + _chromeLogger.info('Attempting to get execution context ID.'); await tryGetContextId(chromeProxyService); - _logger.info('Got execution context ID.'); + _chromeLogger.info('Got execution context ID.'); } on StateError catch (e) { // We couldn't find the execution context. `hotRestart` may have been // triggered in the middle of a full reload. @@ -408,12 +575,12 @@ Future> _hotRestart( } // Generate run id to hot restart all apps loaded into the tab. final runId = const Uuid().v4().toString(); - _logger.info('Issuing \$dartHotRestartDwds request'); + _chromeLogger.info('Issuing \$dartHotRestartDwds request'); await chromeProxyService.inspector.jsEvaluate( '\$dartHotRestartDwds(\'$runId\', $pauseIsolatesOnStart);', awaitPromise: true, ); - _logger.info('\$dartHotRestartDwds request complete.'); + _chromeLogger.info('\$dartHotRestartDwds request complete.'); } on WipError catch (exception) { final code = exception.error?['code']; final message = exception.error?['message']; @@ -433,11 +600,11 @@ Future> _hotRestart( }, }; } - _logger.info('Waiting for Isolate Start event.'); + _chromeLogger.info('Waiting for Isolate Start event.'); await stream.firstWhere((event) => event.kind == EventKind.kIsolateStart); chromeProxyService.terminatingIsolates = false; - _logger.info('Successful hot restart'); + _chromeLogger.info('Successful hot restart'); return {'result': Success().toJson()}; } @@ -455,10 +622,10 @@ void _waitForResumeEventToRunMain(ChromeProxyService chromeProxyService) { Future> _fullReload( ChromeProxyService chromeProxyService, ) async { - _logger.info('Attempting a full reload'); + _chromeLogger.info('Attempting a full reload'); await chromeProxyService.remoteDebugger.enablePage(); await chromeProxyService.remoteDebugger.pageReload(); - _logger.info('Successful full reload'); + _chromeLogger.info('Successful full reload'); return {'result': Success().toJson()}; } @@ -466,7 +633,9 @@ Future _disableBreakpointsAndResume( VmService client, ChromeProxyService chromeProxyService, ) async { - _logger.info('Attempting to disable breakpoints and resume the isolate'); + _chromeLogger.info( + 'Attempting to disable breakpoints and resume the isolate', + ); final vm = await client.getVM(); final isolates = vm.isolates; if (isolates == null || isolates.isEmpty) { @@ -495,9 +664,15 @@ Future _disableBreakpointsAndResume( await client.resume(isolateId); } on RPCError catch (e, s) { if (!e.message.contains('Can only perform operation while paused')) { - _logger.severe('Hot restart failed to resume exiting isolate', e, s); + _chromeLogger.severe( + 'Hot restart failed to resume exiting isolate', + e, + s, + ); rethrow; } } - _logger.info('Successfully disabled breakpoints and resumed the isolate'); + _chromeLogger.info( + 'Successfully disabled breakpoints and resumed the isolate', + ); } diff --git a/dwds/lib/src/handlers/dev_handler.dart b/dwds/lib/src/handlers/dev_handler.dart index 329777540..c93e16719 100644 --- a/dwds/lib/src/handlers/dev_handler.dart +++ b/dwds/lib/src/handlers/dev_handler.dart @@ -15,6 +15,7 @@ import 'package:dwds/data/hot_reload_response.dart'; import 'package:dwds/data/isolate_events.dart'; import 'package:dwds/data/register_event.dart'; import 'package:dwds/data/serializers.dart'; +import 'package:dwds/data/service_extension_response.dart'; import 'package:dwds/src/config/tool_configuration.dart'; import 'package:dwds/src/connections/app_connection.dart'; import 'package:dwds/src/connections/debug_connection.dart'; @@ -30,8 +31,10 @@ import 'package:dwds/src/servers/devtools.dart'; import 'package:dwds/src/servers/extension_backend.dart'; import 'package:dwds/src/servers/extension_debugger.dart'; import 'package:dwds/src/services/app_debug_services.dart'; +import 'package:dwds/src/services/chrome_proxy_service.dart'; import 'package:dwds/src/services/debug_service.dart'; import 'package:dwds/src/services/expression_compiler.dart'; +import 'package:dwds/src/services/web_socket_proxy_service.dart'; import 'package:dwds/src/utilities/shared.dart'; import 'package:logging/logging.dart'; import 'package:shelf/shelf.dart'; @@ -79,6 +82,8 @@ class DevHandler { Stream get connectedApps => _connectedApps.stream; + final bool useWebSocketConnection; + DevHandler( this._chromeConnection, this.buildResults, @@ -93,8 +98,9 @@ class DevHandler { this._injected, this._spawnDds, this._ddsPort, - this._launchDevToolsInNewWindow, - ) { + this._launchDevToolsInNewWindow, { + this.useWebSocketConnection = false, + }) { _subs.add(buildResults.listen(_emitBuildResults)); _listen(); if (_extensionBackend != null) { @@ -133,11 +139,14 @@ class DevHandler { } /// Sends the provided [request] to all connected injected clients. - void _sendRequestToClients(Object request) { + /// Returns the number of clients the request was successfully sent to. + int _sendRequestToClients(Object request) { _logger.finest('Sending request to injected clients: $request'); + var successfulSends = 0; for (final injectedConnection in _injectedConnections) { try { injectedConnection.sink.add(jsonEncode(serializers.serialize(request))); + successfulSends++; } on StateError catch (e) { // The sink has already closed (app is disconnected), or another StateError occurred. _logger.warning( @@ -148,10 +157,14 @@ class DevHandler { _logger.severe('Error sending request to client: $e', e, s); } } + _logger.fine( + 'Sent request to $successfulSends clients out of ${_injectedConnections.length} total connections', + ); + return successfulSends; } - /// Starts a [DebugService] for local debugging. - Future _startLocalDebugService( + /// Starts a [ChromeDebugService] for local debugging. + Future _startLocalDebugService( ChromeConnection chromeConnection, AppConnection appConnection, ) async { @@ -211,7 +224,7 @@ class DevHandler { final webkitDebugger = WebkitDebugger(WipDebugger(tabConnection)); - return DebugService.start( + return ChromeDebugService.start( // We assume the user will connect to the debug service on the same // machine. This allows consumers of DWDS to provide a `hostname` for // debugging through the Dart Debug Extension without impacting the local @@ -239,7 +252,6 @@ class DevHandler { expressionCompiler: _expressionCompiler, spawnDds: _spawnDds, ddsPort: _ddsPort, - sendClientRequest: _sendRequestToClients, ); } @@ -256,27 +268,64 @@ class DevHandler { final appId = appConnection.request.appId; var appServices = _servicesByAppId[appId]; if (appServices == null) { - final debugService = await _startLocalDebugService( - await _chromeConnection(), - appConnection, - ); - appServices = await _createAppDebugServices(debugService); - safeUnawaited( - appServices.chromeProxyService.remoteDebugger.onClose.first - .whenComplete(() async { - await appServices?.close(); - _servicesByAppId.remove(appConnection.request.appId); - _logger.info( - 'Stopped debug service on ' - 'ws://${debugService.hostname}:${debugService.port}\n', - ); - }), - ); + if (useWebSocketConnection) { + appServices = await _createWebSocketAppServices(appConnection); + } else { + appServices = await _createChromeAppServices(appConnection); + _setupChromeServiceCleanup(appServices, appConnection); + } _servicesByAppId[appId] = appServices; } + return appServices; } + /// Creates WebSocket-based app services for hot reload functionality. + Future _createWebSocketAppServices( + AppConnection appConnection, + ) async { + final webSocketDebugService = await WebSocketDebugService.start( + 'localhost', + appConnection, + sendClientRequest: _sendRequestToClients, + ); + return _createAppDebugServicesWebSocketMode( + webSocketDebugService, + appConnection, + ); + } + + /// Creates Chrome-based app services for full debugging capabilities. + Future _createChromeAppServices( + AppConnection appConnection, + ) async { + final debugService = await _startLocalDebugService( + await _chromeConnection(), + appConnection, + ); + return _createAppDebugServices(debugService); + } + + /// Sets up cleanup handling for Chrome-based services. + void _setupChromeServiceCleanup( + AppDebugServices appServices, + AppConnection appConnection, + ) { + final chromeProxy = appServices.proxyService; + if (chromeProxy is ChromeProxyService) { + safeUnawaited( + chromeProxy.remoteDebugger.onClose.first.whenComplete(() async { + await appServices.close(); + _servicesByAppId.remove(appConnection.request.appId); + _logger.info( + 'Stopped debug service on ' + 'ws://${appServices.debugService.hostname}:${appServices.debugService.port}\n', + ); + }), + ); + } + } + void _handleConnection(SocketConnection injectedConnection) { _injectedConnections.add(injectedConnection); AppConnection? appConnection; @@ -291,10 +340,13 @@ class DevHandler { 'https://github.com/dart-lang/webdev/issues/new.', ); } - appConnection = await _handleConnectRequest( - message, - injectedConnection, - ); + appConnection = + useWebSocketConnection + ? await _handleWebSocketConnectRequest( + message, + injectedConnection, + ) + : await _handleConnectRequest(message, injectedConnection); } else { final connection = appConnection; if (connection == null) { @@ -302,23 +354,9 @@ class DevHandler { } if (message is DevToolsRequest) { await _handleDebugRequest(connection, injectedConnection); - } else if (message is HotReloadResponse) { - // The app reload operation has completed. Mark the completer as done. - _servicesByAppId[connection.request.appId]?.chromeProxyService - .completeHotReload(message); - } else if (message is IsolateExit) { - _handleIsolateExit(connection); - } else if (message is IsolateStart) { - await _handleIsolateStart(connection); - } else if (message is BatchedDebugEvents) { - _servicesByAppId[connection.request.appId]?.chromeProxyService - .parseBatchedDebugEvents(message); - } else if (message is DebugEvent) { - _servicesByAppId[connection.request.appId]?.chromeProxyService - .parseDebugEvent(message); - } else if (message is RegisterEvent) { - _servicesByAppId[connection.request.appId]?.chromeProxyService - .parseRegisterEvent(message); + } else { + // Handle messages for both WebSocket and Chrome proxy services + await _handleMessage(connection, message); } } } catch (e, s) { @@ -350,13 +388,17 @@ class DevHandler { _injectedConnections.remove(injectedConnection); final connection = appConnection; if (connection != null) { - _appConnectionByAppId.remove(connection.request.appId); - final services = _servicesByAppId[connection.request.appId]; + final appId = connection.request.appId; + final services = _servicesByAppId[appId]; + // WebSocket mode doesn't need this because WebSocketProxyService handles connection tracking and cleanup + if (!useWebSocketConnection) { + _appConnectionByAppId.remove(appId); + } if (services != null) { if (services.connectedInstanceId == null || services.connectedInstanceId == connection.request.instanceId) { services.connectedInstanceId = null; - services.chromeProxyService.destroyIsolate(); + _handleIsolateExit(connection); } } } @@ -364,6 +406,44 @@ class DevHandler { ); } + /// Handles messages for both WebSocket and Chrome proxy services. + Future _handleMessage(AppConnection connection, Object? message) async { + if (message == null) return; + + final appId = connection.request.appId; + final proxyService = _servicesByAppId[appId]?.proxyService; + + if (proxyService == null) { + _logger.warning( + 'No proxy service found for appId: $appId to process $message', + ); + return; + } + + // Handle messages that are specific to certain proxy service types + if (message is HotReloadResponse) { + proxyService.completeHotReload(message); + } else if (message is ServiceExtensionResponse) { + proxyService.completeServiceExtension(message); + } else if (message is IsolateExit) { + _handleIsolateExit(connection); + } else if (message is IsolateStart) { + await _handleIsolateStart(connection); + } else if (message is BatchedDebugEvents) { + proxyService.parseBatchedDebugEvents(message); + } else if (message is DebugEvent) { + proxyService.parseDebugEvent(message); + } else if (message is RegisterEvent) { + proxyService.parseRegisterEvent(message); + } else { + final serviceType = + proxyService is WebSocketProxyService ? 'WebSocket' : 'Chrome'; + throw UnsupportedError( + 'Message type ${message.runtimeType} is not supported in $serviceType mode', + ); + } + } + Future _handleDebugRequest( AppConnection appConnection, SocketConnection sseConnection, @@ -456,17 +536,68 @@ class DevHandler { ); appServices.connectedInstanceId = appConnection.request.instanceId; - appServices.dwdsStats.updateLoadTime( + appServices.dwdsStats!.updateLoadTime( debuggerStart: debuggerStart, devToolsStart: DateTime.now(), ); - await _launchDevTools( - appServices.chromeProxyService.remoteDebugger, - _constructDevToolsUri( - appServices.debugService.uri, - ideQueryParam: 'Dwds', - ), - ); + final chromeProxy = appServices.proxyService; + if (chromeProxy is ChromeProxyService) { + await _launchDevTools( + chromeProxy.remoteDebugger, + _constructDevToolsUri( + appServices.debugService.uri, + ideQueryParam: 'Dwds', + ), + ); + } + } + + /// Creates a debug connection for WebSocket mode. + Future createDebugConnectionForWebSocket( + AppConnection appConnection, + ) async { + final appDebugServices = await loadAppServices(appConnection); + + // Initialize WebSocket proxy service + try { + final proxyService = appDebugServices.proxyService; + if (proxyService is! WebSocketProxyService) { + throw StateError( + 'Expected WebSocketProxyService but got ${proxyService.runtimeType}. ', + ); + } + await proxyService.isInitialized; + _logger.fine('WebSocket proxy service initialized successfully'); + } catch (e) { + _logger.severe('Failed to initialize WebSocket proxy service: $e'); + rethrow; + } + + return DebugConnection(appDebugServices); + } + + /// Creates a debug connection for Chrome mode. + Future createDebugConnectionForChrome( + AppConnection appConnection, + ) async { + final appDebugServices = await loadAppServices(appConnection); + + // Initialize Chrome proxy service + try { + final proxyService = appDebugServices.proxyService; + if (proxyService is! ChromeProxyService) { + throw StateError( + 'Expected ChromeProxyService but got ${proxyService.runtimeType}. ', + ); + } + await proxyService.isInitialized; + _logger.fine('Chrome proxy service initialized successfully'); + } catch (e) { + _logger.severe('Failed to initialize Chrome proxy service: $e'); + rethrow; + } + + return DebugConnection(appDebugServices); } Future _handleConnectRequest( @@ -492,33 +623,39 @@ class DevHandler { // AppConnection is in the KeepAlive state (this means it disconnected but // is still waiting for a possible reconnect - this happens during a page // reload). - final canReuseConnection = + final canReconnect = services != null && (services.connectedInstanceId == null || existingConnection?.isInKeepAlivePeriod == true); - if (canReuseConnection) { + if (canReconnect) { // Disconnect any old connection (eg. those in the keep-alive waiting // state when reloading the page). existingConnection?.shutDown(); - services.chromeProxyService.destroyIsolate(); + final chromeProxy = services.proxyService; + if (chromeProxy is ChromeProxyService) { + chromeProxy.destroyIsolate(); + } // Reconnect to existing service. services.connectedInstanceId = message.instanceId; - if (services.chromeProxyService.pauseIsolatesOnStart) { - // If the pause-isolates-on-start flag is set, we need to wait for - // the resume event to run the app's main() method. - _waitForResumeEventToRunMain( - services.chromeProxyService.resumeAfterRestartEventsStream, - readyToRunMainCompleter, - ); - } else { - // Otherwise, we can run the app's main() method immediately. - readyToRunMainCompleter.complete(); - } + final chromeService = services.proxyService; + if (chromeService is ChromeProxyService) { + if (chromeService.pauseIsolatesOnStart) { + // If the pause-isolates-on-start flag is set, we need to wait for + // the resume event to run the app's main() method. + _waitForResumeEventToRunMain( + chromeService.resumeAfterRestartEventsStream, + readyToRunMainCompleter, + ); + } else { + // Otherwise, we can run the app's main() method immediately. + readyToRunMainCompleter.complete(); + } - await services.chromeProxyService.createIsolate(connection); + await chromeService.createIsolate(connection); + } } else { // If this is the initial app connection, we can run the app's main() // method immediately. @@ -529,6 +666,112 @@ class DevHandler { return connection; } + /// Handles WebSocket mode connection requests with multi-window support. + Future _handleWebSocketConnectRequest( + ConnectRequest message, + SocketConnection sseConnection, + ) async { + // After a page refresh, reconnect to the same app services if they + // were previously launched and create the new isolate. + final services = _servicesByAppId[message.appId]; + final existingConnection = _appConnectionByAppId[message.appId]; + // Completer to indicate when the app's main() method is ready to be run. + // Its future is passed to the AppConnection so that it can be awaited on + // before running the app's main() method: + final readyToRunMainCompleter = Completer(); + final connection = AppConnection( + message, + sseConnection, + readyToRunMainCompleter.future, + ); + + // Allow connection reuse for page refreshes and same instance reconnections + final isSameInstance = + existingConnection?.request.instanceId == message.instanceId; + final isKeepAliveReconnect = + existingConnection?.isInKeepAlivePeriod == true; + final hasNoActiveConnection = services?.connectedInstanceId == null; + final noExistingConnection = existingConnection == null; + + final canReconnect = + services != null && + (isSameInstance || + (isKeepAliveReconnect && hasNoActiveConnection) || + (noExistingConnection && hasNoActiveConnection)); + + if (canReconnect) { + // Reconnect to existing service. + await _reconnectToService( + services, + existingConnection, + connection, + message, + readyToRunMainCompleter, + ); + } else { + // New browser window or initial connection: run main() immediately + readyToRunMainCompleter.complete(); + + // For WebSocket mode, we need to proactively create and emit a debug connection + try { + // Initialize the WebSocket service and create debug connection + final debugConnection = await createDebugConnectionForWebSocket( + connection, + ); + + // Emit the debug connection through the extension stream + extensionDebugConnections.add(debugConnection); + } catch (e, s) { + _logger.warning('Failed to create WebSocket debug connection: $e\n$s'); + } + } + _appConnectionByAppId[message.appId] = connection; + _connectedApps.add(connection); + _logger.fine('App connection established for: ${message.appId}'); + return connection; + } + + /// Handles reconnection to existing services for web-socket mode. + Future _reconnectToService( + AppDebugServices services, + AppConnection? existingConnection, + AppConnection newConnection, + ConnectRequest message, + Completer readyToRunMainCompleter, + ) async { + // Disconnect old connection + existingConnection?.shutDown(); + services.connectedInstanceId = message.instanceId; + + _logger.finest('WebSocket service reconnected for app: ${message.appId}'); + + final wsService = services.proxyService; + if (wsService is WebSocketProxyService) { + _setupMainExecution( + wsService.pauseIsolatesOnStart, + wsService.resumeAfterRestartEventsStream, + readyToRunMainCompleter, + ); + } else { + readyToRunMainCompleter.complete(); + } + + await _handleIsolateStart(newConnection); + } + + /// Sets up main() execution timing based on pause settings. + void _setupMainExecution( + bool pauseIsolatesOnStart, + Stream? resumeEventsStream, + Completer readyToRunMainCompleter, + ) { + if (pauseIsolatesOnStart && resumeEventsStream != null) { + _waitForResumeEventToRunMain(resumeEventsStream, readyToRunMainCompleter); + } else { + readyToRunMainCompleter.complete(); + } + } + /// Waits for a resume event to trigger the app's main() method. /// /// The [readyToRunMainCompleter]'s future will be passed to the @@ -545,14 +788,37 @@ class DevHandler { }); } + /// Handles isolate exit events for both WebSocket and Chrome-based debugging. void _handleIsolateExit(AppConnection appConnection) { - _servicesByAppId[appConnection.request.appId]?.chromeProxyService - .destroyIsolate(); + final appId = appConnection.request.appId; + + if (useWebSocketConnection) { + _logger.fine( + 'Isolate exit handled by WebSocket proxy service for app: $appId', + ); + } else { + final proxyService = _servicesByAppId[appId]?.proxyService; + if (proxyService is ChromeProxyService) { + proxyService.destroyIsolate(); + } + } } + /// Handles isolate start events for both WebSocket and Chrome-based debugging. Future _handleIsolateStart(AppConnection appConnection) async { - await _servicesByAppId[appConnection.request.appId]?.chromeProxyService - .createIsolate(appConnection); + final appId = appConnection.request.appId; + + if (useWebSocketConnection) { + final proxyService = _servicesByAppId[appId]?.proxyService; + if (proxyService is WebSocketProxyService) { + await proxyService.createIsolate(appConnection); + } + } else { + final proxyService = _servicesByAppId[appId]?.proxyService; + if (proxyService is ChromeProxyService) { + await proxyService.createIsolate(appConnection); + } + } } void _listen() { @@ -581,7 +847,7 @@ class DevHandler { } Future _createAppDebugServices( - DebugService debugService, + ChromeDebugService debugService, ) async { final dwdsStats = DwdsStats(); Uri? ddsUri; @@ -589,8 +855,12 @@ class DevHandler { final dds = await debugService.startDartDevelopmentService(); ddsUri = dds.wsUri; } - final vmClient = await DwdsVmClient.create(debugService, dwdsStats, ddsUri); - final appDebugService = AppDebugServices( + final vmClient = await ChromeDwdsVmClient.create( + debugService, + dwdsStats, + ddsUri, + ); + final appDebugService = ChromeAppDebugServices( debugService, vmClient, dwdsStats, @@ -598,15 +868,18 @@ class DevHandler { ); final encodedUri = await debugService.encodedUri; _logger.info('Debug service listening on $encodedUri\n'); - await appDebugService.chromeProxyService.remoteDebugger.sendCommand( - 'Runtime.evaluate', - params: { - 'expression': - 'console.log(' - '"This app is linked to the debug service: $encodedUri"' - ');', - }, - ); + final chromeProxy = appDebugService.proxyService; + if (chromeProxy is ChromeProxyService) { + await chromeProxy.remoteDebugger.sendCommand( + 'Runtime.evaluate', + params: { + 'expression': + 'console.log(' + '"This app is linked to the debug service: $encodedUri"' + ');', + }, + ); + } // Notify that DWDS has been launched and a debug connection has been made: _maybeEmitDwdsLaunchEvent(); @@ -614,6 +887,28 @@ class DevHandler { return appDebugService; } + Future _createAppDebugServicesWebSocketMode( + WebSocketDebugService webSocketDebugService, + AppConnection appConnection, + ) async { + final wsVmClient = await WebSocketDwdsVmClient.create( + webSocketDebugService, + ); + final wsAppDebugService = WebSocketAppDebugServices( + webSocketDebugService, + wsVmClient, + ); + + safeUnawaited(_handleIsolateStart(appConnection)); + final debugServiceUri = webSocketDebugService.uri; + _logger.info('Debug service listening on $debugServiceUri\n'); + + // Notify that DWDS has been launched and a debug connection has been made: + _maybeEmitDwdsLaunchEvent(); + + return wsAppDebugService; + } + Future _listenForDebugExtension() async { final extensionBackend = _extensionBackend; if (extensionBackend == null) { @@ -627,13 +922,14 @@ class DevHandler { } } - /// Starts a [DebugService] for Dart Debug Extension. + /// Starts a [ChromeProxyService] for Dart Debug Extension. void _startExtensionDebugService(ExtensionDebugger extensionDebugger) { // Waits for a `DevToolsRequest` to be sent from the extension background // when the extension is clicked. extensionDebugger.devToolsRequestStream.listen((devToolsRequest) async { try { await _handleDevToolsRequest(extensionDebugger, devToolsRequest); + _logger.finest('DevTools request processed successfully'); } catch (error) { _logger.severe('Encountered error handling DevTools request.'); extensionDebugger.closeWithError(error); @@ -673,7 +969,7 @@ class DevHandler { final debuggerStart = DateTime.now(); var appServices = _servicesByAppId[appId]; if (appServices == null) { - final debugService = await DebugService.start( + final debugService = await ChromeDebugService.start( _hostname, extensionDebugger, executionContext, @@ -688,24 +984,25 @@ class DevHandler { expressionCompiler: _expressionCompiler, spawnDds: _spawnDds, ddsPort: _ddsPort, - sendClientRequest: _sendRequestToClients, ); appServices = await _createAppDebugServices(debugService); extensionDebugger.sendEvent('dwds.debugUri', debugService.uri); final encodedUri = await debugService.encodedUri; extensionDebugger.sendEvent('dwds.encodedUri', encodedUri); - safeUnawaited( - appServices.chromeProxyService.remoteDebugger.onClose.first - .whenComplete(() async { - appServices?.chromeProxyService.destroyIsolate(); - await appServices?.close(); - _servicesByAppId.remove(devToolsRequest.appId); - _logger.info( - 'Stopped debug service on ' - '${await appServices?.debugService.encodedUri}\n', - ); - }), - ); + final chromeProxy = appServices.proxyService; + if (chromeProxy is ChromeProxyService) { + safeUnawaited( + chromeProxy.remoteDebugger.onClose.first.whenComplete(() async { + chromeProxy.destroyIsolate(); + await appServices?.close(); + _servicesByAppId.remove(devToolsRequest.appId); + _logger.info( + 'Stopped debug service on ' + '${await appServices?.debugService.encodedUri}\n', + ); + }), + ); + } extensionDebugConnections.add(DebugConnection(appServices)); _servicesByAppId[appId] = appServices; } @@ -718,7 +1015,7 @@ class DevHandler { final encodedUri = await appServices.debugService.encodedUri; - appServices.dwdsStats.updateLoadTime( + appServices.dwdsStats!.updateLoadTime( debuggerStart: debuggerStart, devToolsStart: DateTime.now(), ); diff --git a/dwds/lib/src/handlers/injector.dart b/dwds/lib/src/handlers/injector.dart index d55494944..121c3628a 100644 --- a/dwds/lib/src/handlers/injector.dart +++ b/dwds/lib/src/handlers/injector.dart @@ -29,22 +29,12 @@ const _clientScript = 'dwds/src/injected/client'; /// This class is responsible for modifying the served JavaScript files /// to include the injected DWDS client, enabling debugging capabilities /// and source mapping when running in a browser environment. -/// -/// TODO(yjessy): Remove this when the DWDS WebSocket connection is implemented. -/// The `_useDwdsWebSocketConnection` flag determines the communication protocol: -/// - When `true`, uses a socket-based implementation. -/// - When `false`, uses Chrome-based communication protocol. class DwdsInjector { final Future? _extensionUri; final _devHandlerPaths = StreamController(); final _logger = Logger('DwdsInjector'); - final bool _useDwdsWebSocketConnection; - DwdsInjector({ - Future? extensionUri, - bool useDwdsWebSocketConnection = false, - }) : _extensionUri = extensionUri, - _useDwdsWebSocketConnection = useDwdsWebSocketConnection; + DwdsInjector({Future? extensionUri}) : _extensionUri = extensionUri; /// Returns the embedded dev handler paths. /// @@ -111,7 +101,6 @@ class DwdsInjector { devHandlerPath, entrypoint, await _extensionUri, - _useDwdsWebSocketConnection, ); body += await globalToolConfiguration.loadStrategy.bootstrapFor( entrypoint, @@ -148,7 +137,6 @@ Future _injectClientAndHoistMain( String devHandlerPath, String entrypointPath, String? extensionUri, - bool useDwdsWebSocketConnection, ) async { final bodyLines = body.split('\n'); final extensionIndex = bodyLines.indexWhere( @@ -167,7 +155,6 @@ Future _injectClientAndHoistMain( devHandlerPath, entrypointPath, extensionUri, - useDwdsWebSocketConnection, ); result += ''' // Injected by dwds for debugging support. @@ -199,7 +186,6 @@ Future _injectedClientSnippet( String devHandlerPath, String entrypointPath, String? extensionUri, - bool useDwdsWebSocketConnection, ) async { final loadStrategy = globalToolConfiguration.loadStrategy; final buildSettings = loadStrategy.buildSettings; @@ -218,7 +204,6 @@ Future _injectedClientSnippet( 'window.\$dartEmitDebugEvents = ${debugSettings.emitDebugEvents};\n' 'window.\$isInternalBuild = ${appMetadata.isInternalBuild};\n' 'window.\$isFlutterApp = ${buildSettings.isFlutterApp};\n' - 'window.\$useDwdsWebSocketConnection = $useDwdsWebSocketConnection;\n' '${loadStrategy is DdcLibraryBundleStrategy ? 'window.\$hotReloadSourcesPath = "${loadStrategy.hotReloadSourcesUri.toString()}";\n' : ''}' '${loadStrategy.loadClientSnippet(_clientScript)}'; diff --git a/dwds/lib/src/injected/client.js b/dwds/lib/src/injected/client.js index 85c394005..a41260ec1 100644 --- a/dwds/lib/src/injected/client.js +++ b/dwds/lib/src/injected/client.js @@ -1,4 +1,4 @@ -// Generated by dart2js (, csp, intern-composite-values), the Dart to JavaScript compiler version: 3.9.0-152.0.dev. +// Generated by dart2js (, csp, intern-composite-values), the Dart to JavaScript compiler version: 3.9.0-edge. // The code supports the following hooks: // dartPrint(message): // if this function is defined it is called instead of the Dart [print] @@ -125,9 +125,7 @@ return finalValue; }; } - function makeConstList(list, rti) { - if (rti != null) - A._setArrayType(list, rti); + function makeConstList(list) { list.$flags = 7; return list; } @@ -388,6 +386,22 @@ return J.UnknownJavaScriptObject.prototype; return receiver; }, + getInterceptor$x(receiver) { + if (receiver == null) + return receiver; + if (typeof receiver != "object") { + if (typeof receiver == "function") + return J.JavaScriptFunction.prototype; + if (typeof receiver == "symbol") + return J.JavaScriptSymbol.prototype; + if (typeof receiver == "bigint") + return J.JavaScriptBigInt.prototype; + return receiver; + } + if (receiver instanceof A.Object) + return receiver; + return J.getNativeInterceptor(receiver); + }, set$length$asx(receiver, value) { return J.getInterceptor$asx(receiver).set$length(receiver, value); }, @@ -438,6 +452,9 @@ allMatches$2$s(receiver, a0, a1) { return J.getInterceptor$s(receiver).allMatches$2(receiver, a0, a1); }, + asUint8List$2$x(receiver, a0, a1) { + return J.getInterceptor$x(receiver).asUint8List$2(receiver, a0, a1); + }, cast$1$0$ax(receiver, $T1) { return J.getInterceptor$ax(receiver).cast$1$0(receiver, $T1); }, @@ -503,8 +520,6 @@ JSArray: function JSArray(t0) { this.$ti = t0; }, - JSArraySafeToStringHook: function JSArraySafeToStringHook() { - }, JSUnmodifiableArray: function JSUnmodifiableArray(t0) { this.$ti = t0; }, @@ -1106,7 +1121,6 @@ return A._rtiToString(A.instanceType(object), null); }, Primitives_safeToString(object) { - var hooks, i, hookResult; if (object == null || typeof object == "number" || A._isBool(object)) return J.toString$0$(object); if (typeof object == "string") @@ -1115,12 +1129,6 @@ return object.toString$0(0); if (object instanceof A._Record) return object._toString$1(true); - hooks = $.$get$_safeToStringHooks(); - for (i = 0; i < 1; ++i) { - hookResult = hooks[i].tryFormat$1(object); - if (hookResult != null) - return hookResult; - } return "Instance of '" + A.Primitives_objectTypeName(object) + "'"; }, Primitives_currentUri() { @@ -1961,7 +1969,8 @@ if (receiver === "") return replacement; $length = receiver.length; - for (t1 = replacement, i = 0; i < $length; ++i) + t1 = "" + replacement; + for (i = 0; i < $length; ++i) t1 = t1 + receiver[i] + replacement; return t1.charCodeAt(0) == 0 ? t1 : t1; } @@ -2038,8 +2047,6 @@ this._genericClosure = t0; this.$ti = t1; }, - SafeToStringHook: function SafeToStringHook() { - }, TypeErrorDecoder: function TypeErrorDecoder(t0, t1, t2, t3, t4, t5) { var _ = this; _._pattern = t0; @@ -2211,6 +2218,9 @@ this._name = t0; this.__late_helper$_value = null; }, + _checkLength($length) { + return $length; + }, _ensureNativeList(list) { var t1, result, i; if (type$.JSIndexable_dynamic._is(list)) @@ -2253,6 +2263,9 @@ }, NativeTypedData: function NativeTypedData() { }, + _UnmodifiableNativeByteBufferView: function _UnmodifiableNativeByteBufferView(t0) { + this.__native_typed_data$_data = t0; + }, NativeByteData: function NativeByteData() { }, NativeTypedArray: function NativeTypedArray() { @@ -2546,56 +2559,45 @@ return A.createRuntimeType(A._Universe_eval(init.typeUniverse, recipe, false)); }, _installSpecializedIsTest(object) { - var testRti = this; - testRti._is = A._specializedIsTest(testRti); - return testRti._is(object); - }, - _specializedIsTest(testRti) { - var kind, simpleIsFn, $name, predicate, t2, - t1 = type$.Object; - if (testRti === t1) - return A._isObject; + var kind, isFn, $name, predicate, testRti = this; + if (testRti === type$.Object) + return A._finishIsFn(testRti, object, A._isObject); if (A.isTopType(testRti)) - return A._isTop; + return A._finishIsFn(testRti, object, A._isTop); kind = testRti._kind; if (kind === 6) - return A._generalNullableIsTestImplementation; + return A._finishIsFn(testRti, object, A._generalNullableIsTestImplementation); if (kind === 1) - return A._isNever; + return A._finishIsFn(testRti, object, A._isNever); if (kind === 7) - return A._isFutureOr; - simpleIsFn = A._simpleSpecializedIsTest(testRti); - if (simpleIsFn != null) - return simpleIsFn; + return A._finishIsFn(testRti, object, A._isFutureOr); + if (testRti === type$.int) + isFn = A._isInt; + else if (testRti === type$.double || testRti === type$.num) + isFn = A._isNum; + else if (testRti === type$.String) + isFn = A._isString; + else + isFn = testRti === type$.bool ? A._isBool : null; + if (isFn != null) + return A._finishIsFn(testRti, object, isFn); if (kind === 8) { $name = testRti._primary; if (testRti._rest.every(A.isTopType)) { testRti._specializedTestResource = "$is" + $name; if ($name === "List") - return A._isListTestViaProperty; - if (testRti === type$.JSObject) - return A._isJSObject; - return A._isTestViaProperty; + return A._finishIsFn(testRti, object, A._isListTestViaProperty); + return A._finishIsFn(testRti, object, A._isTestViaProperty); } } else if (kind === 10) { predicate = A.createRecordTypePredicate(testRti._primary, testRti._rest); - t2 = predicate == null ? A._isNever : predicate; - return t2 == null ? t1._as(t2) : t2; - } - return A._generalIsTestImplementation; - }, - _simpleSpecializedIsTest(testRti) { - if (testRti._kind === 8) { - if (testRti === type$.int) - return A._isInt; - if (testRti === type$.double || testRti === type$.num) - return A._isNum; - if (testRti === type$.String) - return A._isString; - if (testRti === type$.bool) - return A._isBool; + return A._finishIsFn(testRti, object, predicate == null ? A._isNever : predicate); } - return null; + return A._finishIsFn(testRti, object, A._generalIsTestImplementation); + }, + _finishIsFn(testRti, object, isFn) { + testRti._is = isFn; + return testRti._is(object); }, _installSpecializedAsCheck(object) { var testRti = this, @@ -2604,28 +2606,28 @@ asFn = A._asTop; else if (testRti === type$.Object) asFn = A._asObject; - else if (A.isNullable(testRti)) { + else if (A.isNullable(testRti)) asFn = A._generalNullableAsCheckImplementation; - if (testRti === type$.nullable_int) - asFn = A._asIntQ; - else if (testRti === type$.nullable_String) - asFn = A._asStringQ; - else if (testRti === type$.nullable_bool) - asFn = A._asBoolQ; - else if (testRti === type$.nullable_num) - asFn = A._asNumQ; - else if (testRti === type$.nullable_double) - asFn = A._asDoubleQ; - } else if (testRti === type$.int) + if (testRti === type$.int) asFn = A._asInt; + else if (testRti === type$.nullable_int) + asFn = A._asIntQ; else if (testRti === type$.String) asFn = A._asString; + else if (testRti === type$.nullable_String) + asFn = A._asStringQ; else if (testRti === type$.bool) asFn = A._asBool; + else if (testRti === type$.nullable_bool) + asFn = A._asBoolQ; else if (testRti === type$.num) asFn = A._asNum; + else if (testRti === type$.nullable_num) + asFn = A._asNumQ; else if (testRti === type$.double) asFn = A._asDouble; + else if (testRti === type$.nullable_double) + asFn = A._asDoubleQ; testRti._as = asFn; return testRti._as(object); }, @@ -2662,19 +2664,6 @@ return !!object[tag]; return !!J.getInterceptor$(object)[tag]; }, - _isJSObject(object) { - var t1 = this; - if (object == null) - return false; - if (typeof object == "object") { - if (object instanceof A.Object) - return !!object[t1._specializedTestResource]; - return true; - } - if (typeof object == "function") - return true; - return false; - }, _generalAsCheckImplementation(object) { var testRti = this; if (object == null) { @@ -2944,8 +2933,8 @@ }, _Universe_findErasedType(universe, cls) { var $length, erased, $arguments, i, $interface, - metadata = universe.eT, - probe = metadata[cls]; + t1 = universe.eT, + probe = t1[cls]; if (probe == null) return A._Universe_eval(universe, cls, false); else if (typeof probe == "number") { @@ -2955,7 +2944,7 @@ for (i = 0; i < $length; ++i) $arguments[i] = erased; $interface = A._Universe__lookupInterfaceRti(universe, cls, $arguments); - metadata[cls] = $interface; + t1[cls] = $interface; return $interface; } else return probe; @@ -2968,12 +2957,12 @@ }, _Universe_eval(universe, recipe, normalize) { var rti, - cache = universe.eC, - probe = cache.get(recipe); + t1 = universe.eC, + probe = t1.get(recipe); if (probe != null) return probe; rti = A._Parser_parse(A._Parser_create(universe, null, recipe, false)); - cache.set(recipe, rti); + t1.set(recipe, rti); return rti; }, _Universe_evalInEnvironment(universe, environment, recipe) { @@ -3232,97 +3221,97 @@ return {u: universe, e: environment, r: recipe, s: [], p: 0, n: normalize}; }, _Parser_parse(parser) { - var t1, i, ch, u, array, end, item, + var t2, i, ch, t3, array, end, item, source = parser.r, - stack = parser.s; - for (t1 = source.length, i = 0; i < t1;) { + t1 = parser.s; + for (t2 = source.length, i = 0; i < t2;) { ch = source.charCodeAt(i); if (ch >= 48 && ch <= 57) - i = A._Parser_handleDigit(i + 1, ch, source, stack); + i = A._Parser_handleDigit(i + 1, ch, source, t1); else if ((((ch | 32) >>> 0) - 97 & 65535) < 26 || ch === 95 || ch === 36 || ch === 124) - i = A._Parser_handleIdentifier(parser, i, source, stack, false); + i = A._Parser_handleIdentifier(parser, i, source, t1, false); else if (ch === 46) - i = A._Parser_handleIdentifier(parser, i, source, stack, true); + i = A._Parser_handleIdentifier(parser, i, source, t1, true); else { ++i; switch (ch) { case 44: break; case 58: - stack.push(false); + t1.push(false); break; case 33: - stack.push(true); + t1.push(true); break; case 59: - stack.push(A._Parser_toType(parser.u, parser.e, stack.pop())); + t1.push(A._Parser_toType(parser.u, parser.e, t1.pop())); break; case 94: - stack.push(A._Universe__lookupGenericFunctionParameterRti(parser.u, stack.pop())); + t1.push(A._Universe__lookupGenericFunctionParameterRti(parser.u, t1.pop())); break; case 35: - stack.push(A._Universe__lookupTerminalRti(parser.u, 5, "#")); + t1.push(A._Universe__lookupTerminalRti(parser.u, 5, "#")); break; case 64: - stack.push(A._Universe__lookupTerminalRti(parser.u, 2, "@")); + t1.push(A._Universe__lookupTerminalRti(parser.u, 2, "@")); break; case 126: - stack.push(A._Universe__lookupTerminalRti(parser.u, 3, "~")); + t1.push(A._Universe__lookupTerminalRti(parser.u, 3, "~")); break; case 60: - stack.push(parser.p); - parser.p = stack.length; + t1.push(parser.p); + parser.p = t1.length; break; case 62: - A._Parser_handleTypeArguments(parser, stack); + A._Parser_handleTypeArguments(parser, t1); break; case 38: - A._Parser_handleExtendedOperations(parser, stack); + A._Parser_handleExtendedOperations(parser, t1); break; case 63: - u = parser.u; - stack.push(A._Universe__lookupQuestionRti(u, A._Parser_toType(u, parser.e, stack.pop()), parser.n)); + t3 = parser.u; + t1.push(A._Universe__lookupQuestionRti(t3, A._Parser_toType(t3, parser.e, t1.pop()), parser.n)); break; case 47: - u = parser.u; - stack.push(A._Universe__lookupFutureOrRti(u, A._Parser_toType(u, parser.e, stack.pop()), parser.n)); + t3 = parser.u; + t1.push(A._Universe__lookupFutureOrRti(t3, A._Parser_toType(t3, parser.e, t1.pop()), parser.n)); break; case 40: - stack.push(-3); - stack.push(parser.p); - parser.p = stack.length; + t1.push(-3); + t1.push(parser.p); + parser.p = t1.length; break; case 41: - A._Parser_handleArguments(parser, stack); + A._Parser_handleArguments(parser, t1); break; case 91: - stack.push(parser.p); - parser.p = stack.length; + t1.push(parser.p); + parser.p = t1.length; break; case 93: - array = stack.splice(parser.p); + array = t1.splice(parser.p); A._Parser_toTypes(parser.u, parser.e, array); - parser.p = stack.pop(); - stack.push(array); - stack.push(-1); + parser.p = t1.pop(); + t1.push(array); + t1.push(-1); break; case 123: - stack.push(parser.p); - parser.p = stack.length; + t1.push(parser.p); + parser.p = t1.length; break; case 125: - array = stack.splice(parser.p); + array = t1.splice(parser.p); A._Parser_toTypesNamed(parser.u, parser.e, array); - parser.p = stack.pop(); - stack.push(array); - stack.push(-2); + parser.p = t1.pop(); + t1.push(array); + t1.push(-2); break; case 43: end = source.indexOf("(", i); - stack.push(source.substring(i, end)); - stack.push(-4); - stack.push(parser.p); - parser.p = stack.length; + t1.push(source.substring(i, end)); + t1.push(-4); + t1.push(parser.p); + parser.p = t1.length; i = end + 1; break; default: @@ -3330,7 +3319,7 @@ } } } - item = stack.pop(); + item = t1.pop(); return A._Parser_toType(parser.u, parser.e, item); }, _Parser_handleDigit(i, digit, source, stack) { @@ -3379,26 +3368,26 @@ }, _Parser_handleTypeArguments(parser, stack) { var base, - universe = parser.u, + t1 = parser.u, $arguments = A._Parser_collectArray(parser, stack), head = stack.pop(); if (typeof head == "string") - stack.push(A._Universe__lookupInterfaceRti(universe, head, $arguments)); + stack.push(A._Universe__lookupInterfaceRti(t1, head, $arguments)); else { - base = A._Parser_toType(universe, parser.e, head); + base = A._Parser_toType(t1, parser.e, head); switch (base._kind) { case 11: - stack.push(A._Universe__lookupGenericFunctionRti(universe, base, $arguments, parser.n)); + stack.push(A._Universe__lookupGenericFunctionRti(t1, base, $arguments, parser.n)); break; default: - stack.push(A._Universe__lookupBindingRti(universe, base, $arguments)); + stack.push(A._Universe__lookupBindingRti(t1, base, $arguments)); break; } } }, _Parser_handleArguments(parser, stack) { var requiredPositional, returnType, parameters, - universe = parser.u, + t1 = parser.u, head = stack.pop(), optionalPositional = null, named = null; if (typeof head == "number") @@ -3421,18 +3410,18 @@ case -3: head = stack.pop(); if (optionalPositional == null) - optionalPositional = universe.sEA; + optionalPositional = t1.sEA; if (named == null) - named = universe.sEA; - returnType = A._Parser_toType(universe, parser.e, head); + named = t1.sEA; + returnType = A._Parser_toType(t1, parser.e, head); parameters = new A._FunctionParameters(); parameters._requiredPositional = requiredPositional; parameters._optionalPositional = optionalPositional; parameters._named = named; - stack.push(A._Universe__lookupFunctionRti(universe, returnType, parameters)); + stack.push(A._Universe__lookupFunctionRti(t1, returnType, parameters)); return; case -4: - stack.push(A._Universe__lookupRecordRti(universe, stack.pop(), requiredPositional)); + stack.push(A._Universe__lookupRecordRti(t1, stack.pop(), requiredPositional)); return; default: throw A.wrapException(A.AssertionError$("Unexpected state under `()`: " + A.S(head))); @@ -3803,6 +3792,7 @@ return completer._future; }, _asyncAwait(object, bodyFunction) { + bodyFunction.toString; A._awaitOnObject(object, bodyFunction); }, _asyncReturn(object, completer) { @@ -7521,15 +7511,15 @@ _.___Uri_hashCode_FI = _.___Uri_pathSegments_FI = _.___Uri__text_FI = $; }, JSAnyUtilityExtension_instanceOfString(_this, constructorName) { - var parts, $constructor, t1, t2, _i, t3; + var parts, $constructor, t1, t2, _i, part; if (constructorName.length === 0) return false; parts = constructorName.split("."); $constructor = init.G; - for (t1 = parts.length, t2 = type$.nullable_JSObject, _i = 0; _i < t1; ++_i, $constructor = t3) { - t3 = $constructor[parts[_i]]; - t2._as(t3); - if (t3 == null) + for (t1 = parts.length, t2 = type$.nullable_JSObject, _i = 0; _i < t1; ++_i) { + part = parts[_i]; + $constructor = t2._as($constructor[part]); + if ($constructor == null) return false; } return _this instanceof type$.JavaScriptFunction._as($constructor); @@ -7680,11 +7670,11 @@ A.checkTypeBound($T, type$.num, "T", "max"); return Math.max($T._as(a), $T._as(b)); }, - Random_Random(seed) { - return B.C__JSRandom; - }, _JSRandom: function _JSRandom() { }, + _JSSecureRandom: function _JSSecureRandom(t0) { + this._math$_buffer = t0; + }, AsyncMemoizer: function AsyncMemoizer(t0, t1) { this._async_memoizer$_completer = t0; this.$ti = t1; @@ -7978,10 +7968,7 @@ t2 = new A.BuiltJsonSerializersBuilder(A.MapBuilder_MapBuilder(t1, t2), A.MapBuilder_MapBuilder(t3, t2), A.MapBuilder_MapBuilder(t3, t2), A.MapBuilder_MapBuilder(type$.FullType, type$.Function), A.ListBuilder_ListBuilder(B.List_empty0, type$.SerializerPlugin)); t2.add$1(0, new A.BigIntSerializer(A.BuiltList_BuiltList$from([B.Type_BigInt_DZK, A.getRuntimeTypeOfDartObject($.$get$_BigIntImpl_zero())], t1))); t2.add$1(0, new A.BoolSerializer(A.BuiltList_BuiltList$from([B.Type_bool_wF1], t1))); - t2.add$1(0, new A.ListSerializer(A.BuiltList_BuiltList$from([B.Type_List_hc9, A.createRuntimeType(A._arrayInstanceType(A._setArrayType([], type$.JSArray_Object)))], t1))); t3 = type$.Object; - t2.add$1(0, new A.MapSerializer(A.BuiltList_BuiltList$from([B.Type_Map_9Aj, A.getRuntimeTypeOfDartObject(A.LinkedHashMap_LinkedHashMap$_empty(t3, t3))], t1))); - t2.add$1(0, new A.SetSerializer(A.BuiltSet_BuiltSet$from([B.Type_Set_tZi, A.getRuntimeTypeOfDartObject(A.LinkedHashSet_LinkedHashSet$_empty(t3))], t1))); t2.add$1(0, new A.BuiltListSerializer(A.BuiltList_BuiltList$from([B.Type_BuiltList_fj6, A.getRuntimeTypeOfDartObject(A.BuiltList_BuiltList$from(B.List_empty0, t3))], t1))); t2.add$1(0, new A.BuiltListMultimapSerializer(A.BuiltList_BuiltList$from([B.Type_BuiltListMultimap_HQW, A.getRuntimeTypeOfDartObject(A.BuiltListMultimap_BuiltListMultimap(t3, t3))], t1))); t2.add$1(0, new A.BuiltMapSerializer(A.BuiltList_BuiltList$from([B.Type_BuiltMap_TeX, A.getRuntimeTypeOfDartObject(A.BuiltMap_BuiltMap(t3, t3))], t1))); @@ -8140,16 +8127,6 @@ JsonObjectSerializer: function JsonObjectSerializer(t0) { this.types = t0; }, - ListSerializer: function ListSerializer(t0) { - this.types = t0; - }, - ListSerializer_serialize_closure: function ListSerializer_serialize_closure(t0, t1) { - this.serializers = t0; - this.elementType = t1; - }, - MapSerializer: function MapSerializer(t0) { - this.types = t0; - }, NullSerializer: function NullSerializer(t0) { this.types = t0; }, @@ -8159,13 +8136,6 @@ RegExpSerializer: function RegExpSerializer(t0) { this.types = t0; }, - SetSerializer: function SetSerializer(t0) { - this.types = t0; - }, - SetSerializer_serialize_closure: function SetSerializer_serialize_closure(t0, t1) { - this.serializers = t0; - this.elementType = t1; - }, StringSerializer: function StringSerializer(t0) { this.types = t0; }, @@ -8495,6 +8465,48 @@ }, _$serializers_closure0: function _$serializers_closure0() { }, + ServiceExtensionRequest: function ServiceExtensionRequest() { + }, + _$ServiceExtensionRequestSerializer: function _$ServiceExtensionRequestSerializer() { + }, + _$ServiceExtensionRequest: function _$ServiceExtensionRequest(t0, t1, t2) { + this.id = t0; + this.method = t1; + this.argsJson = t2; + }, + ServiceExtensionRequestBuilder: function ServiceExtensionRequestBuilder() { + var _ = this; + _._argsJson = _._service_extension_request$_method = _._service_extension_request$_id = _._service_extension_request$_$v = null; + }, + ServiceExtensionResponse_ServiceExtensionResponse$fromResult(errorCode, errorMessage, id, result, success) { + var t1 = new A.ServiceExtensionResponseBuilder(); + type$.nullable_void_Function_ServiceExtensionResponseBuilder._as(new A.ServiceExtensionResponse_ServiceExtensionResponse$fromResult_closure(id, success, result, errorCode, errorMessage)).call$1(t1); + return t1._service_extension_response$_build$0(); + }, + ServiceExtensionResponse: function ServiceExtensionResponse() { + }, + ServiceExtensionResponse_ServiceExtensionResponse$fromResult_closure: function ServiceExtensionResponse_ServiceExtensionResponse$fromResult_closure(t0, t1, t2, t3, t4) { + var _ = this; + _.id = t0; + _.success = t1; + _.result = t2; + _.errorCode = t3; + _.errorMessage = t4; + }, + _$ServiceExtensionResponseSerializer: function _$ServiceExtensionResponseSerializer() { + }, + _$ServiceExtensionResponse: function _$ServiceExtensionResponse(t0, t1, t2, t3, t4) { + var _ = this; + _.id = t0; + _.resultJson = t1; + _.success = t2; + _.errorCode = t3; + _.errorMessage = t4; + }, + ServiceExtensionResponseBuilder: function ServiceExtensionResponseBuilder() { + var _ = this; + _._service_extension_response$_errorMessage = _._errorCode = _._service_extension_response$_success = _._resultJson = _._service_extension_response$_id = _._service_extension_response$_$v = null; + }, BatchedStreamController: function BatchedStreamController(t0, t1, t2, t3, t4, t5) { var _ = this; _._checkDelayMilliseconds = t0; @@ -8769,6 +8781,9 @@ _._finalized = false; }, Response_fromStream(response) { + return A.Response_fromStream$body(response); + }, + Response_fromStream$body(response) { var $async$goto = 0, $async$completer = A._makeAsyncAwaitCompleter(type$.Response), $async$returnValue, body, t1, t2, t3, t4, t5, t6; @@ -8911,7 +8926,7 @@ break; } message = new A.StringBuffer(""); - t1 = method + "("; + t1 = "" + (method + "("); message._contents = t1; t2 = A._arrayInstanceType(args); t3 = t2._eval$1("SubListIterable<1>"); @@ -9432,8 +9447,7 @@ }, RNG: function RNG() { }, - MathRNG: function MathRNG(t0) { - this._rnd = t0; + CryptoRNG: function CryptoRNG() { }, UuidV1: function UuidV1(t0) { this.goptions = t0; @@ -9483,6 +9497,9 @@ this.handleData = t0; }, BrowserWebSocket_connect(url, protocols) { + return A.BrowserWebSocket_connect$body(url, protocols); + }, + BrowserWebSocket_connect$body(url, protocols) { var $async$goto = 0, $async$completer = A._makeAsyncAwaitCompleter(type$.BrowserWebSocket), $async$returnValue, t1, t2, t3, t4, webSocket, browserSocket, webSocketConnected; @@ -9498,8 +9515,7 @@ t1 = init.G; t2 = t1.WebSocket; t3 = url.toString$0(0); - t1 = t1.Array; - t1 = type$.JSArray_nullable_Object._as(new t1()); + t1 = type$.JSArray_nullable_Object._as(new t1.Array()); t4 = type$.JSObject; webSocket = t4._as(new t2(t3, t1)); webSocket.binaryType = "arraybuffer"; @@ -9660,6 +9676,9 @@ } }, _authenticateUser(authUrl) { + return A._authenticateUser$body(authUrl); + }, + _authenticateUser$body(authUrl) { var $async$goto = 0, $async$completer = A._makeAsyncAwaitCompleter(type$.bool), $async$returnValue, response, client; @@ -9691,6 +9710,9 @@ _sendResponse(clientSink, builder, requestId, errorMessage, success, $T) { A._trySendEvent(clientSink, B.C_JsonCodec.encode$2$toEncodable($.$get$serializers().serialize$1(builder.call$1(new A._sendResponse_closure(requestId, success, errorMessage))), null), type$.dynamic); }, + _sendServiceExtensionResponse(clientSink, requestId, errorCode, errorMessage, result, success) { + A._trySendEvent(clientSink, B.C_JsonCodec.encode$2$toEncodable($.$get$serializers().serialize$1(A.ServiceExtensionResponse_ServiceExtensionResponse$fromResult(errorCode, errorMessage, requestId, result, success)), null), type$.dynamic); + }, handleWebSocketHotReloadRequest($event, manager, clientSink) { return A.handleWebSocketHotReloadRequest$body($event, manager, clientSink); }, @@ -9748,6 +9770,64 @@ }); return A._asyncStartSync($async$handleWebSocketHotReloadRequest, $async$completer); }, + handleServiceExtensionRequest(request, clientSink, manager) { + return A.handleServiceExtensionRequest$body(request, clientSink, manager); + }, + handleServiceExtensionRequest$body(request, clientSink, manager) { + var $async$goto = 0, + $async$completer = A._makeAsyncAwaitCompleter(type$.void), + $async$handler = 1, $async$errorStack = [], result, e, t1, exception, $async$exception; + var $async$handleServiceExtensionRequest = A._wrapJsFunctionForAsync(function($async$errorCode, $async$result) { + if ($async$errorCode === 1) { + $async$errorStack.push($async$result); + $async$goto = $async$handler; + } + while (true) + switch ($async$goto) { + case 0: + // Function start + $async$handler = 3; + t1 = request.argsJson; + t1 = t1.length === 0 ? A.LinkedHashMap_LinkedHashMap$_empty(type$.String, type$.dynamic) : type$.Map_String_dynamic._as(B.C_JsonCodec.decode$1(t1)); + $async$goto = 6; + return A._asyncAwait(manager.handleServiceExtension$2(request.method, t1), $async$handleServiceExtensionRequest); + case 6: + // returning from await. + result = $async$result; + t1 = request.id; + if (result != null) + A._sendServiceExtensionResponse(clientSink, t1, null, null, result, true); + else + A._sendServiceExtensionResponse(clientSink, t1, -32601, "Service extension not supported", null, false); + $async$handler = 1; + // goto after finally + $async$goto = 5; + break; + case 3: + // catch + $async$handler = 2; + $async$exception = $async$errorStack.pop(); + e = A.unwrapException($async$exception); + A._sendServiceExtensionResponse(clientSink, request.id, null, J.toString$0$(e), null, false); + // goto after finally + $async$goto = 5; + break; + case 2: + // uncaught + // goto rethrow + $async$goto = 1; + break; + case 5: + // after finally + // implicit return + return A._asyncReturn(null, $async$completer); + case 1: + // rethrow + return A._asyncRethrow($async$errorStack.at(-1), $async$completer); + } + }); + return A._asyncStartSync($async$handleServiceExtensionRequest, $async$completer); + }, hotReloadSourcesPath() { var path = A._asStringQ(init.G.$hotReloadSourcesPath); if (path == null) @@ -9834,6 +9914,9 @@ this.errorMessage = t2; }, _Debugger_maybeInvokeFlutterDisassemble(_this) { + return A._Debugger_maybeInvokeFlutterDisassemble$body(_this); + }, + _Debugger_maybeInvokeFlutterDisassemble$body(_this) { var $async$goto = 0, $async$completer = A._makeAsyncAwaitCompleter(type$.void), t1; @@ -9861,6 +9944,37 @@ }); return A._asyncStartSync($async$_Debugger_maybeInvokeFlutterDisassemble, $async$completer); }, + _Debugger_maybeInvokeFlutterReassemble(_this) { + return A._Debugger_maybeInvokeFlutterReassemble$body(_this); + }, + _Debugger_maybeInvokeFlutterReassemble$body(_this) { + var $async$goto = 0, + $async$completer = A._makeAsyncAwaitCompleter(type$.void), + t1; + var $async$_Debugger_maybeInvokeFlutterReassemble = A._wrapJsFunctionForAsync(function($async$errorCode, $async$result) { + if ($async$errorCode === 1) + return A._asyncRethrow($async$result, $async$completer); + while (true) + switch ($async$goto) { + case 0: + // Function start + t1 = type$.JSArray_nullable_Object._as(_this.extensionNames); + $async$goto = J.contains$1$asx(type$.List_String._is(t1) ? t1 : new A.CastList(t1, A._arrayInstanceType(t1)._eval$1("CastList<1,String>")), "ext.flutter.reassemble") ? 2 : 3; + break; + case 2: + // then + $async$goto = 4; + return A._asyncAwait(A.promiseToFuture(type$.JSObject._as(_this.invokeExtension("ext.flutter.reassemble", "{}")), type$.String), $async$_Debugger_maybeInvokeFlutterReassemble); + case 4: + // returning from await. + case 3: + // join + // implicit return + return A._asyncReturn(null, $async$completer); + } + }); + return A._asyncStartSync($async$_Debugger_maybeInvokeFlutterReassemble, $async$completer); + }, DdcLibraryBundleRestarter: function DdcLibraryBundleRestarter() { this._capturedHotReloadEndCallback = null; }, @@ -9888,6 +10002,9 @@ this._restarter = t1; }, SdkDeveloperExtension_maybeInvokeFlutterDisassemble(_this) { + return A.SdkDeveloperExtension_maybeInvokeFlutterDisassemble$body(_this); + }, + SdkDeveloperExtension_maybeInvokeFlutterDisassemble$body(_this) { var $async$goto = 0, $async$completer = A._makeAsyncAwaitCompleter(type$.void); var $async$SdkDeveloperExtension_maybeInvokeFlutterDisassemble = A._wrapJsFunctionForAsync(function($async$errorCode, $async$result) { @@ -10024,7 +10141,8 @@ throw "Unable to print message: " + String(string); }, JSFunctionUnsafeUtilExtension_callAsConstructor(_this, arg1, $R) { - return $R._as(A.callConstructor(_this, [arg1], type$.JSObject)); + var t1 = [arg1]; + return $R._as(A.callConstructor(_this, t1, type$.JSObject)); }, groupBy(values, key, $S, $T) { var t1, _i, element, t2, t3, @@ -10385,6 +10503,7 @@ return new A.MappedListIterable(receiver, t1._bind$1($T)._eval$1("1(2)")._as(f), t1._eval$1("@<1>")._bind$1($T)._eval$1("MappedListIterable<1,2>")); }, map$1(receiver, f) { + f.toString; return this.map$1$1(receiver, f, type$.dynamic); }, join$1(receiver, separator) { @@ -10606,6 +10725,7 @@ return -1; }, indexWhere$1(receiver, test) { + test.toString; return this.indexWhere$2(receiver, test, 0); }, get$runtimeType(receiver) { @@ -10616,24 +10736,6 @@ $isIterable: 1, $isList: 1 }; - J.JSArraySafeToStringHook.prototype = { - tryFormat$1(array) { - var flags, info, base; - if (!Array.isArray(array)) - return null; - flags = array.$flags | 0; - if ((flags & 4) !== 0) - info = "const, "; - else if ((flags & 2) !== 0) - info = "unmodifiable, "; - else - info = (flags & 1) !== 0 ? "fixed, " : ""; - base = "Instance of '" + A.Primitives_objectTypeName(array) + "'"; - if (info === "") - return base; - return base + " (" + info + "length: " + array.length + ")"; - } - }; J.JSUnmodifiableArray.prototype = {}; J.ArrayIterator.prototype = { get$current() { @@ -11156,6 +11258,10 @@ get$isEmpty(_) { var t1 = this.__internal$_source; return t1.get$isEmpty(t1); + }, + get$isNotEmpty(_) { + var t1 = this.__internal$_source; + return t1.get$isNotEmpty(t1); } }; A.CastMap_forEach_closure.prototype = { @@ -11189,7 +11295,7 @@ call$0() { return A.Future_Future$value(null, type$.void); }, - $signature: 19 + $signature: 16 }; A.SentinelValue.prototype = {}; A.EfficientLengthIterable.prototype = {}; @@ -11249,6 +11355,7 @@ return new A.MappedListIterable(this, t1._bind$1($T)._eval$1("1(ListIterable.E)")._as(toElement), t1._eval$1("@")._bind$1($T)._eval$1("MappedListIterable<1,2>")); }, map$1(_, toElement) { + toElement.toString; return this.map$1$1(0, toElement, type$.dynamic); }, reduce$1(_, combine) { @@ -11444,6 +11551,7 @@ return new A.MappedIterable(this, t1._bind$1($T)._eval$1("1(2)")._as(toElement), t1._eval$1("@<1>")._bind$1($T)._eval$1("MappedIterable<1,2>")); }, map$1(_, toElement) { + toElement.toString; return this.map$1$1(0, toElement, type$.dynamic); } }; @@ -11581,6 +11689,7 @@ return new A.EmptyIterable($T._eval$1("EmptyIterable<0>")); }, map$1(_, toElement) { + toElement.toString; return this.map$1$1(0, toElement, type$.dynamic); }, skip$1(_, count) { @@ -11592,11 +11701,8 @@ return this; }, toList$1$growable(_, growable) { - var t1 = this.$ti._precomputed1; - return growable ? J.JSArray_JSArray$growable(0, t1) : J.JSArray_JSArray$fixed(0, t1); - }, - toList$0(_) { - return this.toList$1$growable(0, true); + var t1 = J.JSArray_JSArray$fixed(0, this.$ti._precomputed1); + return t1; } }; A.EmptyIterator.prototype = { @@ -11675,6 +11781,9 @@ get$isEmpty(_) { return this.get$length(this) === 0; }, + get$isNotEmpty(_) { + return this.get$length(this) !== 0; + }, toString$0(_) { return A.MapBase_mapToString(this); }, @@ -11691,6 +11800,7 @@ }, map$1(_, transform) { var t1 = type$.dynamic; + transform.toString; return this.map$2$1(0, transform, t1, t1); }, $isMap: 1 @@ -11799,7 +11909,6 @@ return A.instantiatedGenericFunctionType(A.closureFunctionType(this._genericClosure), this.$ti); } }; - A.SafeToStringHook.prototype = {}; A.TypeErrorDecoder.prototype = { matchTypeError$1(message) { var result, t1, _this = this, @@ -11926,6 +12035,9 @@ get$isEmpty(_) { return this.__js_helper$_length === 0; }, + get$isNotEmpty(_) { + return this.__js_helper$_length !== 0; + }, get$keys() { return new A.LinkedHashMapKeysIterable(this, A._instanceType(this)._eval$1("LinkedHashMapKeysIterable<1>")); }, @@ -12289,13 +12401,13 @@ call$2(o, tag) { return this.getUnknownTag(o, tag); }, - $signature: 83 + $signature: 91 }; A.initHooks_closure1.prototype = { call$1(tag) { return this.prototypeForTag(A._asString(tag)); }, - $signature: 90 + $signature: 49 }; A._Record.prototype = {}; A.JSSyntaxRegExp.prototype = { @@ -12514,11 +12626,20 @@ get$runtimeType(receiver) { return B.Type_ByteBuffer_rqD; }, + asUint8List$2(receiver, offsetInBytes, $length) { + return $length == null ? new Uint8Array(receiver, offsetInBytes) : new Uint8Array(receiver, offsetInBytes, $length); + }, $isTrustedGetRuntimeType: 1, $isNativeByteBuffer: 1, $isByteBuffer: 1 }; A.NativeTypedData.prototype = { + get$buffer(receiver) { + if (((receiver.$flags | 0) & 2) !== 0) + return new A._UnmodifiableNativeByteBufferView(receiver.buffer); + else + return receiver.buffer; + }, _invalidPosition$3(receiver, position, $length, $name) { var t1 = A.RangeError$range(position, 0, $length, $name, null); throw A.wrapException(t1); @@ -12528,6 +12649,14 @@ this._invalidPosition$3(receiver, position, $length, $name); } }; + A._UnmodifiableNativeByteBufferView.prototype = { + asUint8List$2(_, offsetInBytes, $length) { + var result = A.NativeUint8List_NativeUint8List$view(this.__native_typed_data$_data, offsetInBytes, $length); + result.$flags = 3; + return result; + }, + $isByteBuffer: 1 + }; A.NativeByteData.prototype = { get$runtimeType(receiver) { return B.Type_ByteData_9dB; @@ -12791,7 +12920,7 @@ t2 = this.span; t1.firstChild ? t1.removeChild(t2) : t1.appendChild(t2); }, - $signature: 63 + $signature: 37 }; A._AsyncRun__scheduleImmediateJsOverride_internalCallback.prototype = { call$0() { @@ -12897,13 +13026,13 @@ call$2(error, stackTrace) { this.bodyFunction.call$2(1, new A.ExceptionAndStackTrace(error, type$.StackTrace._as(stackTrace))); }, - $signature: 53 + $signature: 47 }; A._wrapJsFunctionForAsync_closure.prototype = { call$2(errorCode, result) { this.$protected(A._asInt(errorCode), result); }, - $signature: 37 + $signature: 57 }; A.AsyncError.prototype = { toString$0(_) { @@ -13032,6 +13161,7 @@ return result; }, then$1$1(f, $R) { + f.toString; return this.then$1$2$onError(f, null, $R); }, _thenAwait$1$2(f, onError, $E) { @@ -13410,6 +13540,7 @@ return new A._MapStream(t1._bind$1($S)._eval$1("1(Stream.T)")._as(convert), this, t1._eval$1("@")._bind$1($S)._eval$1("_MapStream<1,2>")); }, map$1(_, convert) { + convert.toString; return this.map$1$1(0, convert, type$.dynamic); }, get$length(_) { @@ -14712,7 +14843,7 @@ t2._processUncaughtError$3(zone, type$.Object._as(e), t1._as(s)); } }, - $signature: 66 + $signature: 39 }; A._HashMap.prototype = { get$length(_) { @@ -14721,6 +14852,9 @@ get$isEmpty(_) { return this._collection$_length === 0; }, + get$isNotEmpty(_) { + return this._collection$_length !== 0; + }, get$keys() { return new A._HashMapKeyIterable(this, A._instanceType(this)._eval$1("_HashMapKeyIterable<1>")); }, @@ -14934,7 +15068,7 @@ call$1(v) { return this.K._is(v); }, - $signature: 12 + $signature: 14 }; A._HashMapKeyIterable.prototype = { get$length(_) { @@ -15015,7 +15149,7 @@ call$1(v) { return this.K._is(v); }, - $signature: 12 + $signature: 14 }; A._HashSet.prototype = { get$iterator(_) { @@ -15383,7 +15517,7 @@ call$2(k, v) { this.result.$indexSet(0, this.K._as(k), this.V._as(v)); }, - $signature: 23 + $signature: 29 }; A.ListBase.prototype = { get$iterator(receiver) { @@ -15419,6 +15553,7 @@ return new A.MappedListIterable(receiver, t1._bind$1($T)._eval$1("1(ListBase.E)")._as(f), t1._eval$1("@")._bind$1($T)._eval$1("MappedListIterable<1,2>")); }, map$1(receiver, f) { + f.toString; return this.map$1$1(receiver, f, type$.dynamic); }, skip$1(receiver, count) { @@ -15544,6 +15679,7 @@ }, map$1(_, transform) { var t1 = type$.dynamic; + transform.toString; return this.map$2$1(0, transform, t1, t1); }, containsKey$1(key) { @@ -15557,6 +15693,10 @@ var t1 = this.get$keys(); return t1.get$isEmpty(t1); }, + get$isNotEmpty(_) { + var t1 = this.get$keys(); + return t1.get$isNotEmpty(t1); + }, toString$0(_) { return A.MapBase_mapToString(this); }, @@ -15575,7 +15715,7 @@ t2 = A.S(v); t1._contents += t2; }, - $signature: 24 + $signature: 31 }; A._UnmodifiableMapMixin.prototype = { $indexSet(_, key, value) { @@ -15606,6 +15746,10 @@ var t1 = this._collection$_map; return t1.get$isEmpty(t1); }, + get$isNotEmpty(_) { + var t1 = this._collection$_map; + return t1.get$isNotEmpty(t1); + }, get$length(_) { var t1 = this._collection$_map; return t1.get$length(t1); @@ -15621,6 +15765,7 @@ }, map$1(_, transform) { var t1 = type$.dynamic; + transform.toString; return this.map$2$1(0, transform, t1, t1); }, $isMap: 1 @@ -15779,6 +15924,7 @@ return new A.EfficientLengthMappedIterable(this, t1._bind$1($T)._eval$1("1(2)")._as(f), t1._eval$1("@<1>")._bind$1($T)._eval$1("EfficientLengthMappedIterable<1,2>")); }, map$1(_, f) { + f.toString; return this.map$1$1(0, f, type$.dynamic); }, toString$0(_) { @@ -16108,6 +16254,9 @@ get$isEmpty(_) { return this.get$length(0) === 0; }, + get$isNotEmpty(_) { + return this.get$length(0) > 0; + }, get$keys() { if (this._processed == null) { var t1 = this._data; @@ -16226,7 +16375,7 @@ } return null; }, - $signature: 25 + $signature: 21 }; A._Utf8Decoder__decoderNonfatal_closure.prototype = { call$0() { @@ -16238,7 +16387,7 @@ } return null; }, - $signature: 25 + $signature: 21 }; A.AsciiCodec.prototype = { encode$1(source) { @@ -16529,6 +16678,9 @@ var t1 = A._JsonStringStringifier_stringify(value, this.get$encoder()._toEncodable, null); return t1; }, + encode$1(value) { + return this.encode$2$toEncodable(value, null); + }, get$encoder() { return B.JsonEncoder_null; }, @@ -16741,7 +16893,7 @@ B.JSArray_methods.$indexSet(t1, t2.i++, key); B.JSArray_methods.$indexSet(t1, t2.i++, value); }, - $signature: 24 + $signature: 31 }; A._JsonStringStringifier.prototype = { get$_partialResult() { @@ -17423,7 +17575,7 @@ hash = hash + ((hash & 524287) << 10) & 536870911; return hash ^ hash >>> 6; }, - $signature: 26 + $signature: 27 }; A._BigIntImpl_hashCode_finish.prototype = { call$1(hash) { @@ -17431,7 +17583,7 @@ hash ^= hash >>> 11; return hash + ((hash & 16383) << 15) & 536870911; }, - $signature: 27 + $signature: 22 }; A.DateTime.prototype = { $eq(_, other) { @@ -17728,6 +17880,7 @@ return A.MappedIterable_MappedIterable(this, t1._bind$1($T)._eval$1("1(Iterable.E)")._as(toElement), t1._eval$1("Iterable.E"), $T); }, map$1(_, toElement) { + toElement.toString; return this.map$1$1(0, toElement, type$.dynamic); }, contains$1(_, element) { @@ -17849,13 +18002,13 @@ call$2(msg, position) { throw A.wrapException(A.FormatException$("Illegal IPv4 address, " + msg, this.host, position)); }, - $signature: 61 + $signature: 38 }; A.Uri_parseIPv6Address_error.prototype = { call$2(msg, position) { throw A.wrapException(A.FormatException$("Illegal IPv6 address, " + msg, this.host, position)); }, - $signature: 56 + $signature: 43 }; A.Uri_parseIPv6Address_parseHex.prototype = { call$2(start, end) { @@ -17867,7 +18020,7 @@ this.error.call$2("each part must be in the range of `0x0..0xFFFF`", start); return value; }, - $signature: 26 + $signature: 27 }; A._Uri.prototype = { get$_text() { @@ -17875,7 +18028,7 @@ value = _this.___Uri__text_FI; if (value === $) { t1 = _this.scheme; - t2 = t1.length !== 0 ? t1 + ":" : ""; + t2 = t1.length !== 0 ? "" + t1 + ":" : ""; t3 = _this._host; t4 = t3 == null; if (!t4 || t1 === "file") { @@ -18118,7 +18271,7 @@ A.throwExpression(A.UnsupportedError$(string$.Cannotn)); pathSegments = _this.get$pathSegments(); A._Uri__checkNonWindowsPathReservedCharacters(pathSegments, false); - t1 = A.StringBuffer__writeAll(B.JSString_methods.startsWith$1(_this.path, "/") ? "/" : "", pathSegments, "/"); + t1 = A.StringBuffer__writeAll(B.JSString_methods.startsWith$1(_this.path, "/") ? "" + "/" : "", pathSegments, "/"); t1 = t1.charCodeAt(0) == 0 ? t1 : t1; return t1; }, @@ -18168,7 +18321,7 @@ call$1(s) { return A._Uri__uriEncode(64, A._asString(s), B.C_Utf8Codec, false); }, - $signature: 13 + $signature: 15 }; A.UriData.prototype = { get$uri() { @@ -18494,7 +18647,7 @@ var t1 = type$.JavaScriptFunction; this._this.then$1$2$onError(new A.FutureOfJSAnyToJSPromise_get_toJS__closure(t1._as(resolve)), new A.FutureOfJSAnyToJSPromise_get_toJS__closure0(t1._as(reject)), type$.nullable_Object); }, - $signature: 29 + $signature: 24 }; A.FutureOfJSAnyToJSPromise_get_toJS__closure.prototype = { call$1(value) { @@ -18520,21 +18673,21 @@ t1.call(t1, wrapper); return wrapper; }, - $signature: 52 + $signature: 51 }; A.FutureOfVoidToJSPromise_get_toJS_closure.prototype = { call$2(resolve, reject) { var t1 = type$.JavaScriptFunction; this._this.then$1$2$onError(new A.FutureOfVoidToJSPromise_get_toJS__closure(t1._as(resolve)), new A.FutureOfVoidToJSPromise_get_toJS__closure0(t1._as(reject)), type$.nullable_Object); }, - $signature: 29 + $signature: 24 }; A.FutureOfVoidToJSPromise_get_toJS__closure.prototype = { call$1(__wc0_formal) { var t1 = this.resolve; return t1.call(t1); }, - $signature: 50 + $signature: 53 }; A.FutureOfVoidToJSPromise_get_toJS__closure0.prototype = { call$2(error, stackTrace) { @@ -18654,10 +18807,44 @@ A._JSRandom.prototype = { nextInt$1(max) { if (max <= 0 || max > 4294967296) - throw A.wrapException(A.RangeError$("max must be in range 0 < max \u2264 2^32, was " + max)); + throw A.wrapException(A.RangeError$(string$.max_mu + max)); return Math.random() * max >>> 0; + } + }; + A._JSSecureRandom.prototype = { + _JSSecureRandom$0() { + var $crypto = self.crypto; + if ($crypto != null) + if ($crypto.getRandomValues != null) + return; + throw A.wrapException(A.UnsupportedError$("No source of cryptographically secure random numbers available.")); }, - $isRandom: 1 + nextInt$1(max) { + var byteCount, t1, start, randomLimit, t2, t3, random, result; + if (max <= 0 || max > 4294967296) + throw A.wrapException(A.RangeError$(string$.max_mu + max)); + if (max > 255) + if (max > 65535) + byteCount = max > 16777215 ? 4 : 3; + else + byteCount = 2; + else + byteCount = 1; + t1 = this._math$_buffer; + t1.$flags & 2 && A.throwUnsupportedOperation(t1, 11); + t1.setUint32(0, 0, false); + start = 4 - byteCount; + randomLimit = A._asInt(Math.pow(256, byteCount)); + for (t2 = max - 1, t3 = (max & t2) >>> 0 === 0; true;) { + crypto.getRandomValues(J.asUint8List$2$x(B.NativeByteData_methods.get$buffer(t1), start, byteCount)); + random = t1.getUint32(0, false); + if (t3) + return (random & t2) >>> 0; + result = random % max; + if (random - result + max < randomLimit) + return result; + } + } }; A.AsyncMemoizer.prototype = {}; A.DelegatingStreamSink.prototype = { @@ -18820,7 +19007,7 @@ call$2(h, i) { return A._combine(A._asInt(h), J.get$hashCode$(i)); }, - $signature: 46 + $signature: 62 }; A.BuiltList.prototype = { toBuilder$0() { @@ -18871,6 +19058,7 @@ return new A.MappedListIterable(t1, t2._bind$1($T)._eval$1("1(2)")._as(this.$ti._bind$1($T)._eval$1("1(2)")._as(f)), t2._eval$1("@<1>")._bind$1($T)._eval$1("MappedListIterable<1,2>")); }, map$1(_, f) { + f.toString; return this.map$1$1(0, f, type$.dynamic); }, contains$1(_, element) { @@ -19372,7 +19560,7 @@ var t1 = this.$this.$ti; this.replacement.$indexSet(0, t1._precomputed1._as(key), t1._rest[1]._as(value)); }, - $signature: 23 + $signature: 29 }; A.BuiltSet.prototype = { get$hashCode(_) { @@ -19421,6 +19609,7 @@ return new A.EfficientLengthMappedIterable(t1, t2._bind$1($T)._eval$1("1(2)")._as(this.$ti._bind$1($T)._eval$1("1(2)")._as(f)), t2._eval$1("@<1>")._bind$1($T)._eval$1("EfficientLengthMappedIterable<1,2>")); }, map$1(_, f) { + f.toString; return this.map$1$1(0, f, type$.dynamic); }, contains$1(_, element) { @@ -19745,13 +19934,14 @@ }; A.newBuiltValueToStringHelper_closure.prototype = { call$1(className) { - var t1 = new A.StringBuffer(""); - t1._contents = className; - t1._contents = className + " {\n"; + var t1 = new A.StringBuffer(""), + t2 = "" + className; + t1._contents = t2; + t1._contents = t2 + " {\n"; $._indentingBuiltValueToStringHelperIndent = $._indentingBuiltValueToStringHelperIndent + 2; return new A.IndentingBuiltValueToStringHelper(t1); }, - $signature: 42 + $signature: 64 }; A.IndentingBuiltValueToStringHelper.prototype = { add$2(_, field, value) { @@ -19884,34 +20074,34 @@ call$0() { return A.ListBuilder_ListBuilder(B.List_empty0, type$.Object); }, - $signature: 39 + $signature: 67 }; A.Serializers_Serializers_closure0.prototype = { call$0() { var t1 = type$.Object; return A.ListMultimapBuilder_ListMultimapBuilder(t1, t1); }, - $signature: 38 + $signature: 84 }; A.Serializers_Serializers_closure1.prototype = { call$0() { var t1 = type$.Object; return A.MapBuilder_MapBuilder(t1, t1); }, - $signature: 36 + $signature: 90 }; A.Serializers_Serializers_closure2.prototype = { call$0() { return A.SetBuilder_SetBuilder(type$.Object); }, - $signature: 35 + $signature: 107 }; A.Serializers_Serializers_closure3.prototype = { call$0() { var t1 = type$.Object; return A.SetMultimapBuilder_SetMultimapBuilder(t1, t1); }, - $signature: 89 + $signature: 36 }; A.FullType.prototype = { $eq(_, other) { @@ -20558,7 +20748,7 @@ throw A.wrapException(A.ArgumentError$("odd length", null)); for (t3 = result.$ti, t4 = t3._precomputed1, t5 = t3._rest[1], t6 = t3._eval$1("BuiltSet<2>"), t3 = t3._eval$1("Map<1,BuiltSet<2>>"), i = 0; i !== t2.get$length(serialized); i += 2) { key = serializers.deserialize$2$specifiedType(t2.elementAt$1(serialized, i), keyType); - for (t7 = t1._as(J.map$1$ax(t2.elementAt$1(serialized, i + 1), new A.BuiltSetMultimapSerializer_deserialize_closure(serializers, valueType))), t7 = t7.get$iterator(t7); t7.moveNext$0();) { + for (t7 = J.get$iterator$ax(t1._as(J.map$1$ax(t2.elementAt$1(serialized, i + 1), new A.BuiltSetMultimapSerializer_deserialize_closure(serializers, valueType)))); t7.moveNext$0();) { value = t7.get$current(); t4._as(key); t5._as(value); @@ -20852,143 +21042,6 @@ return "JsonObject"; } }; - A.ListSerializer.prototype = { - serialize$3$specifiedType(serializers, list, specifiedType) { - var t1, t2, elementType; - type$.List_dynamic._as(list); - if (!(specifiedType.root == null || specifiedType.parameters.length === 0)) - if (!serializers.builderFactories._map$_map.containsKey$1(specifiedType)) - serializers._throwMissingBuilderFactory$1(specifiedType); - t1 = specifiedType.parameters; - t2 = t1.length; - if (t2 === 0) - elementType = B.FullType_null_List_empty_false; - else { - if (0 >= t2) - return A.ioore(t1, 0); - elementType = t1[0]; - } - return J.map$1$1$ax(list, new A.ListSerializer_serialize_closure(serializers, elementType), type$.nullable_Object); - }, - serialize$2(serializers, list) { - return this.serialize$3$specifiedType(serializers, list, B.FullType_null_List_empty_false); - }, - deserialize$3$specifiedType(serializers, serialized, specifiedType) { - var isUnderspecified, t1, t2, elementType, result; - type$.Iterable_dynamic._as(serialized); - isUnderspecified = specifiedType.root == null || specifiedType.parameters.length === 0; - t1 = specifiedType.parameters; - t2 = t1.length; - if (t2 === 0) - elementType = B.FullType_null_List_empty_false; - else { - if (0 >= t2) - return A.ioore(t1, 0); - elementType = t1[0]; - } - result = isUnderspecified ? A._setArrayType([], type$.JSArray_Object) : type$.List_dynamic._as(serializers.newBuilder$1(specifiedType)); - for (t1 = J.get$iterator$ax(serialized), t2 = J.getInterceptor$ax(result); t1.moveNext$0();) - t2.add$1(result, serializers.deserialize$2$specifiedType(t1.get$current(), elementType)); - return result; - }, - deserialize$2(serializers, serialized) { - return this.deserialize$3$specifiedType(serializers, serialized, B.FullType_null_List_empty_false); - }, - $isSerializer: 1, - $isStructuredSerializer: 1, - get$types() { - return this.types; - }, - get$wireName() { - return "List"; - } - }; - A.ListSerializer_serialize_closure.prototype = { - call$1(item) { - return this.serializers.serialize$2$specifiedType(item, this.elementType); - }, - $signature: 3 - }; - A.MapSerializer.prototype = { - serialize$3$specifiedType(serializers, $Map, specifiedType) { - var t1, t2, t3, keyType, valueType, result, key; - type$.Map_dynamic_dynamic._as($Map); - if (!(specifiedType.root == null || specifiedType.parameters.length === 0)) - if (!serializers.builderFactories._map$_map.containsKey$1(specifiedType)) - serializers._throwMissingBuilderFactory$1(specifiedType); - t1 = specifiedType.parameters; - t2 = t1.length; - t3 = t2 === 0; - if (t3) - keyType = B.FullType_null_List_empty_false; - else { - if (0 >= t2) - return A.ioore(t1, 0); - keyType = t1[0]; - } - if (t3) - valueType = B.FullType_null_List_empty_false; - else { - if (1 >= t2) - return A.ioore(t1, 1); - valueType = t1[1]; - } - result = []; - for (t1 = $Map.get$keys(), t1 = t1.get$iterator(t1); t1.moveNext$0();) { - key = t1.get$current(); - result.push(serializers.serialize$2$specifiedType(key, keyType)); - result.push(serializers.serialize$2$specifiedType($Map.$index(0, key), valueType)); - } - return result; - }, - serialize$2(serializers, $Map) { - return this.serialize$3$specifiedType(serializers, $Map, B.FullType_null_List_empty_false); - }, - deserialize$3$specifiedType(serializers, serialized, specifiedType) { - var isUnderspecified, t1, t2, t3, keyType, valueType, result, i; - type$.Iterable_dynamic._as(serialized); - isUnderspecified = specifiedType.root == null || specifiedType.parameters.length === 0; - t1 = specifiedType.parameters; - t2 = t1.length; - t3 = t2 === 0; - if (t3) - keyType = B.FullType_null_List_empty_false; - else { - if (0 >= t2) - return A.ioore(t1, 0); - keyType = t1[0]; - } - if (t3) - valueType = B.FullType_null_List_empty_false; - else { - if (1 >= t2) - return A.ioore(t1, 1); - valueType = t1[1]; - } - if (isUnderspecified) { - t1 = type$.Object; - result = A.LinkedHashMap_LinkedHashMap$_empty(t1, t1); - } else - result = type$.Map_dynamic_dynamic._as(serializers.newBuilder$1(specifiedType)); - t1 = J.getInterceptor$asx(serialized); - if (B.JSInt_methods.$mod(t1.get$length(serialized), 2) === 1) - throw A.wrapException(A.ArgumentError$("odd length", null)); - for (i = 0; i !== t1.get$length(serialized); i += 2) - result.$indexSet(0, serializers.deserialize$2$specifiedType(t1.elementAt$1(serialized, i), keyType), serializers.deserialize$2$specifiedType(t1.elementAt$1(serialized, i + 1), valueType)); - return result; - }, - deserialize$2(serializers, serialized) { - return this.deserialize$3$specifiedType(serializers, serialized, B.FullType_null_List_empty_false); - }, - $isSerializer: 1, - $isStructuredSerializer: 1, - get$types() { - return this.types; - }, - get$wireName() { - return "Map"; - } - }; A.NullSerializer.prototype = { serialize$3$specifiedType(serializers, value, specifiedType) { type$.Null._as(value); @@ -21070,63 +21123,6 @@ return "RegExp"; } }; - A.SetSerializer.prototype = { - serialize$3$specifiedType(serializers, set, specifiedType) { - var t1, t2, elementType; - type$.Set_dynamic._as(set); - if (!(specifiedType.root == null || specifiedType.parameters.length === 0)) - if (!serializers.builderFactories._map$_map.containsKey$1(specifiedType)) - serializers._throwMissingBuilderFactory$1(specifiedType); - t1 = specifiedType.parameters; - t2 = t1.length; - if (t2 === 0) - elementType = B.FullType_null_List_empty_false; - else { - if (0 >= t2) - return A.ioore(t1, 0); - elementType = t1[0]; - } - return set.map$1$1(0, new A.SetSerializer_serialize_closure(serializers, elementType), type$.nullable_Object); - }, - serialize$2(serializers, set) { - return this.serialize$3$specifiedType(serializers, set, B.FullType_null_List_empty_false); - }, - deserialize$3$specifiedType(serializers, serialized, specifiedType) { - var isUnderspecified, t1, t2, elementType, result; - type$.Iterable_dynamic._as(serialized); - isUnderspecified = specifiedType.root == null || specifiedType.parameters.length === 0; - t1 = specifiedType.parameters; - t2 = t1.length; - if (t2 === 0) - elementType = B.FullType_null_List_empty_false; - else { - if (0 >= t2) - return A.ioore(t1, 0); - elementType = t1[0]; - } - result = isUnderspecified ? A.LinkedHashSet_LinkedHashSet$_empty(type$.Object) : type$.Set_dynamic._as(serializers.newBuilder$1(specifiedType)); - for (t1 = J.get$iterator$ax(serialized); t1.moveNext$0();) - result.add$1(0, serializers.deserialize$2$specifiedType(t1.get$current(), elementType)); - return result; - }, - deserialize$2(serializers, serialized) { - return this.deserialize$3$specifiedType(serializers, serialized, B.FullType_null_List_empty_false); - }, - $isSerializer: 1, - $isStructuredSerializer: 1, - get$types() { - return this.types; - }, - get$wireName() { - return "Set"; - } - }; - A.SetSerializer_serialize_closure.prototype = { - call$1(item) { - return this.serializers.serialize$2$specifiedType(item, this.elementType); - }, - $signature: 3 - }; A.StringSerializer.prototype = { serialize$3$specifiedType(serializers, string, specifiedType) { return A._asString(string); @@ -21229,6 +21225,9 @@ get$isEmpty(_) { return this._base.__js_helper$_length === 0; }, + get$isNotEmpty(_) { + return this._base.__js_helper$_length !== 0; + }, get$keys() { var t1 = this._base, t2 = A._instanceType(t1)._eval$1("LinkedHashMapValuesIterable<2>"), @@ -21243,6 +21242,7 @@ }, map$1(_, transform) { var t1 = type$.dynamic; + transform.toString; return this.map$2$1(0, transform, t1, t1); }, toString$0(_) { @@ -23571,38 +23571,300 @@ $isSerializer: 1, $isStructuredSerializer: 1, get$types() { - return B.List_RlA; + return B.List_RlA; + }, + get$wireName() { + return "RunRequest"; + } + }; + A._$RunRequest.prototype = { + $eq(_, other) { + if (other == null) + return false; + if (other === this) + return true; + return other instanceof A._$RunRequest; + }, + get$hashCode(_) { + return 248087772; + }, + toString$0(_) { + return J.toString$0$($.$get$newBuiltValueToStringHelper().call$1("RunRequest")); + } + }; + A._$serializers_closure.prototype = { + call$0() { + return A.ListBuilder_ListBuilder(B.List_empty0, type$.DebugEvent); + }, + $signature: 40 + }; + A._$serializers_closure0.prototype = { + call$0() { + return A.ListBuilder_ListBuilder(B.List_empty0, type$.ExtensionEvent); + }, + $signature: 41 + }; + A.ServiceExtensionRequest.prototype = {}; + A._$ServiceExtensionRequestSerializer.prototype = { + serialize$3$specifiedType(serializers, object, specifiedType) { + type$.ServiceExtensionRequest._as(object); + return ["id", serializers.serialize$2$specifiedType(object.id, B.FullType_PT1), "method", serializers.serialize$2$specifiedType(object.method, B.FullType_PT1), "argsJson", serializers.serialize$2$specifiedType(object.argsJson, B.FullType_PT1)]; + }, + serialize$2(serializers, object) { + return this.serialize$3$specifiedType(serializers, object, B.FullType_null_List_empty_false); + }, + deserialize$3$specifiedType(serializers, serialized, specifiedType) { + var t1, value, _$result, t2, t3, t4, + _s8_ = "argsJson", + _s23_ = "ServiceExtensionRequest", + result = new A.ServiceExtensionRequestBuilder(), + iterator = J.get$iterator$ax(type$.Iterable_nullable_Object._as(serialized)); + for (; iterator.moveNext$0();) { + t1 = iterator.get$current(); + t1.toString; + A._asString(t1); + iterator.moveNext$0(); + value = iterator.get$current(); + switch (t1) { + case "id": + t1 = serializers.deserialize$2$specifiedType(value, B.FullType_PT1); + t1.toString; + A._asString(t1); + result.get$_service_extension_request$_$this()._service_extension_request$_id = t1; + break; + case "method": + t1 = serializers.deserialize$2$specifiedType(value, B.FullType_PT1); + t1.toString; + A._asString(t1); + result.get$_service_extension_request$_$this()._service_extension_request$_method = t1; + break; + case "argsJson": + t1 = serializers.deserialize$2$specifiedType(value, B.FullType_PT1); + t1.toString; + A._asString(t1); + result.get$_service_extension_request$_$this()._argsJson = t1; + break; + } + } + _$result = result._service_extension_request$_$v; + if (_$result == null) { + t1 = type$.String; + t2 = A.BuiltValueNullFieldError_checkNotNull(result.get$_service_extension_request$_$this()._service_extension_request$_id, _s23_, "id", t1); + t3 = A.BuiltValueNullFieldError_checkNotNull(result.get$_service_extension_request$_$this()._service_extension_request$_method, _s23_, "method", t1); + t4 = A.BuiltValueNullFieldError_checkNotNull(result.get$_service_extension_request$_$this()._argsJson, _s23_, _s8_, t1); + _$result = new A._$ServiceExtensionRequest(t2, t3, t4); + A.BuiltValueNullFieldError_checkNotNull(t2, _s23_, "id", t1); + A.BuiltValueNullFieldError_checkNotNull(t3, _s23_, "method", t1); + A.BuiltValueNullFieldError_checkNotNull(t4, _s23_, _s8_, t1); + } + A.ArgumentError_checkNotNull(_$result, "other", type$.ServiceExtensionRequest); + return result._service_extension_request$_$v = _$result; + }, + deserialize$2(serializers, serialized) { + return this.deserialize$3$specifiedType(serializers, serialized, B.FullType_null_List_empty_false); + }, + $isSerializer: 1, + $isStructuredSerializer: 1, + get$types() { + return B.List_4i4; + }, + get$wireName() { + return "ServiceExtensionRequest"; + } + }; + A._$ServiceExtensionRequest.prototype = { + $eq(_, other) { + var _this = this; + if (other == null) + return false; + if (other === _this) + return true; + return other instanceof A._$ServiceExtensionRequest && _this.id === other.id && _this.method === other.method && _this.argsJson === other.argsJson; + }, + get$hashCode(_) { + return A.$jf(A.$jc(A.$jc(A.$jc(0, B.JSString_methods.get$hashCode(this.id)), B.JSString_methods.get$hashCode(this.method)), B.JSString_methods.get$hashCode(this.argsJson))); + }, + toString$0(_) { + var t1 = $.$get$newBuiltValueToStringHelper().call$1("ServiceExtensionRequest"), + t2 = J.getInterceptor$ax(t1); + t2.add$2(t1, "id", this.id); + t2.add$2(t1, "method", this.method); + t2.add$2(t1, "argsJson", this.argsJson); + return t2.toString$0(t1); + } + }; + A.ServiceExtensionRequestBuilder.prototype = { + set$id(id) { + this.get$_service_extension_request$_$this()._service_extension_request$_id = id; + }, + get$_service_extension_request$_$this() { + var _this = this, + $$v = _this._service_extension_request$_$v; + if ($$v != null) { + _this._service_extension_request$_id = $$v.id; + _this._service_extension_request$_method = $$v.method; + _this._argsJson = $$v.argsJson; + _this._service_extension_request$_$v = null; + } + return _this; + } + }; + A.ServiceExtensionResponse.prototype = {}; + A.ServiceExtensionResponse_ServiceExtensionResponse$fromResult_closure.prototype = { + call$1(b) { + var t1, _this = this; + b.get$_service_extension_response$_$this()._service_extension_response$_id = _this.id; + b.get$_service_extension_response$_$this()._service_extension_response$_success = _this.success; + t1 = _this.result; + t1 = t1 != null ? B.C_JsonCodec.encode$1(t1) : null; + b.get$_service_extension_response$_$this()._resultJson = t1; + b.get$_service_extension_response$_$this()._errorCode = _this.errorCode; + b.get$_service_extension_response$_$this()._service_extension_response$_errorMessage = _this.errorMessage; + return b; + }, + $signature: 42 + }; + A._$ServiceExtensionResponseSerializer.prototype = { + serialize$3$specifiedType(serializers, object, specifiedType) { + var result, value; + type$.ServiceExtensionResponse._as(object); + result = ["id", serializers.serialize$2$specifiedType(object.id, B.FullType_PT1), "success", serializers.serialize$2$specifiedType(object.success, B.FullType_R6B)]; + value = object.resultJson; + if (value != null) { + result.push("resultJson"); + result.push(serializers.serialize$2$specifiedType(value, B.FullType_PT1)); + } + value = object.errorCode; + if (value != null) { + result.push("errorCode"); + result.push(serializers.serialize$2$specifiedType(value, B.FullType_rTD)); + } + value = object.errorMessage; + if (value != null) { + result.push("errorMessage"); + result.push(serializers.serialize$2$specifiedType(value, B.FullType_PT1)); + } + return result; + }, + serialize$2(serializers, object) { + return this.serialize$3$specifiedType(serializers, object, B.FullType_null_List_empty_false); + }, + deserialize$3$specifiedType(serializers, serialized, specifiedType) { + var t1, value, + result = new A.ServiceExtensionResponseBuilder(), + iterator = J.get$iterator$ax(type$.Iterable_nullable_Object._as(serialized)); + for (; iterator.moveNext$0();) { + t1 = iterator.get$current(); + t1.toString; + A._asString(t1); + iterator.moveNext$0(); + value = iterator.get$current(); + switch (t1) { + case "id": + t1 = serializers.deserialize$2$specifiedType(value, B.FullType_PT1); + t1.toString; + A._asString(t1); + result.get$_service_extension_response$_$this()._service_extension_response$_id = t1; + break; + case "resultJson": + t1 = A._asStringQ(serializers.deserialize$2$specifiedType(value, B.FullType_PT1)); + result.get$_service_extension_response$_$this()._resultJson = t1; + break; + case "success": + t1 = serializers.deserialize$2$specifiedType(value, B.FullType_R6B); + t1.toString; + A._asBool(t1); + result.get$_service_extension_response$_$this()._service_extension_response$_success = t1; + break; + case "errorCode": + t1 = A._asIntQ(serializers.deserialize$2$specifiedType(value, B.FullType_rTD)); + result.get$_service_extension_response$_$this()._errorCode = t1; + break; + case "errorMessage": + t1 = A._asStringQ(serializers.deserialize$2$specifiedType(value, B.FullType_PT1)); + result.get$_service_extension_response$_$this()._service_extension_response$_errorMessage = t1; + break; + } + } + return result._service_extension_response$_build$0(); + }, + deserialize$2(serializers, serialized) { + return this.deserialize$3$specifiedType(serializers, serialized, B.FullType_null_List_empty_false); + }, + $isSerializer: 1, + $isStructuredSerializer: 1, + get$types() { + return B.List_5rA; }, get$wireName() { - return "RunRequest"; + return "ServiceExtensionResponse"; } }; - A._$RunRequest.prototype = { + A._$ServiceExtensionResponse.prototype = { $eq(_, other) { + var _this = this; if (other == null) return false; - if (other === this) + if (other === _this) return true; - return other instanceof A._$RunRequest; + return other instanceof A._$ServiceExtensionResponse && _this.id === other.id && _this.resultJson == other.resultJson && _this.success === other.success && _this.errorCode == other.errorCode && _this.errorMessage == other.errorMessage; }, get$hashCode(_) { - return 248087772; + var _this = this; + return A.$jf(A.$jc(A.$jc(A.$jc(A.$jc(A.$jc(0, B.JSString_methods.get$hashCode(_this.id)), J.get$hashCode$(_this.resultJson)), B.JSBool_methods.get$hashCode(_this.success)), J.get$hashCode$(_this.errorCode)), J.get$hashCode$(_this.errorMessage))); }, toString$0(_) { - return J.toString$0$($.$get$newBuiltValueToStringHelper().call$1("RunRequest")); + var _this = this, + t1 = $.$get$newBuiltValueToStringHelper().call$1("ServiceExtensionResponse"), + t2 = J.getInterceptor$ax(t1); + t2.add$2(t1, "id", _this.id); + t2.add$2(t1, "resultJson", _this.resultJson); + t2.add$2(t1, "success", _this.success); + t2.add$2(t1, "errorCode", _this.errorCode); + t2.add$2(t1, "errorMessage", _this.errorMessage); + return t2.toString$0(t1); } }; - A._$serializers_closure.prototype = { - call$0() { - return A.ListBuilder_ListBuilder(B.List_empty0, type$.DebugEvent); + A.ServiceExtensionResponseBuilder.prototype = { + set$id(id) { + this.get$_service_extension_response$_$this()._service_extension_response$_id = id; }, - $signature: 40 - }; - A._$serializers_closure0.prototype = { - call$0() { - return A.ListBuilder_ListBuilder(B.List_empty0, type$.ExtensionEvent); + set$success(success) { + this.get$_service_extension_response$_$this()._service_extension_response$_success = success; }, - $signature: 41 + set$errorMessage(errorMessage) { + this.get$_service_extension_response$_$this()._service_extension_response$_errorMessage = errorMessage; + }, + get$_service_extension_response$_$this() { + var _this = this, + $$v = _this._service_extension_response$_$v; + if ($$v != null) { + _this._service_extension_response$_id = $$v.id; + _this._resultJson = $$v.resultJson; + _this._service_extension_response$_success = $$v.success; + _this._errorCode = $$v.errorCode; + _this._service_extension_response$_errorMessage = $$v.errorMessage; + _this._service_extension_response$_$v = null; + } + return _this; + }, + _service_extension_response$_build$0() { + var t1, t2, t3, t4, t5, _this = this, + _s24_ = "ServiceExtensionResponse", + _$result = _this._service_extension_response$_$v; + if (_$result == null) { + t1 = type$.String; + t2 = A.BuiltValueNullFieldError_checkNotNull(_this.get$_service_extension_response$_$this()._service_extension_response$_id, _s24_, "id", t1); + t3 = _this.get$_service_extension_response$_$this()._resultJson; + t4 = type$.bool; + t5 = A.BuiltValueNullFieldError_checkNotNull(_this.get$_service_extension_response$_$this()._service_extension_response$_success, _s24_, "success", t4); + _$result = new A._$ServiceExtensionResponse(t2, t3, t5, _this.get$_service_extension_response$_$this()._errorCode, _this.get$_service_extension_response$_$this()._service_extension_response$_errorMessage); + A.BuiltValueNullFieldError_checkNotNull(t2, _s24_, "id", t1); + A.BuiltValueNullFieldError_checkNotNull(t5, _s24_, "success", t4); + } + A.ArgumentError_checkNotNull(_$result, "other", type$.ServiceExtensionResponse); + return _this._service_extension_response$_$v = _$result; + } }; A.BatchedStreamController.prototype = { _batchAndSendEvents$0() { @@ -23710,13 +23972,13 @@ call$0() { return true; }, - $signature: 34 + $signature: 26 }; A.BatchedStreamController__hasEventDuring_closure.prototype = { call$0() { return false; }, - $signature: 34 + $signature: 26 }; A.SocketClient.prototype = {}; A.SseSocketClient.prototype = { @@ -23758,14 +24020,14 @@ call$1(o) { return J.toString$0$(o); }, - $signature: 43 + $signature: 44 }; A.safeUnawaited_closure.prototype = { call$2(error, stackTrace) { type$.StackTrace._as(stackTrace); return $.$get$_logger().log$4(B.Level_WARNING_900, "Error in unawaited Future:", error, stackTrace); }, - $signature: 21 + $signature: 25 }; A.Int32.prototype = { _toInt$1(val) { @@ -23891,6 +24153,9 @@ A._StackState.prototype = {}; A.BaseClient.prototype = { _sendUnstreamed$3(method, url, headers) { + return this._sendUnstreamed$body$BaseClient(method, url, headers); + }, + _sendUnstreamed$body$BaseClient(method, url, headers) { var $async$goto = 0, $async$completer = A._makeAsyncAwaitCompleter(type$.Response), $async$returnValue, $async$self = this, request, $async$temp1; @@ -23934,13 +24199,13 @@ call$2(key1, key2) { return A._asString(key1).toLowerCase() === A._asString(key2).toLowerCase(); }, - $signature: 44 + $signature: 45 }; A.BaseRequest_closure0.prototype = { call$1(key) { return B.JSString_methods.get$hashCode(A._asString(key).toLowerCase()); }, - $signature: 45 + $signature: 46 }; A.BaseResponse.prototype = { BaseResponse$7$contentLength$headers$isRedirect$persistentConnection$reasonPhrase$request(statusCode, contentLength, headers, isRedirect, persistentConnection, reasonPhrase, request) { @@ -23951,6 +24216,9 @@ }; A.BrowserClient.prototype = { send$1(request) { + return this.send$body$BrowserClient(request); + }, + send$body$BrowserClient(request) { var $async$goto = 0, $async$completer = A._makeAsyncAwaitCompleter(type$.StreamedResponse), $async$returnValue, $async$handler = 2, $async$errorStack = [], $async$next = [], $async$self = this, xhr, completer, bytes, t1, t2, header, t3; @@ -24075,7 +24343,7 @@ call$1(bytes) { return this.completer.complete$1(new Uint8Array(A._ensureNativeList(type$.List_int._as(bytes)))); }, - $signature: 47 + $signature: 48 }; A.ClientException.prototype = { toString$0(_) { @@ -24092,7 +24360,7 @@ A.MediaType.prototype = { toString$0(_) { var buffer = new A.StringBuffer(""), - t1 = this.type; + t1 = "" + this.type; buffer._contents = t1; t1 += "/"; buffer._contents = t1; @@ -24163,7 +24431,7 @@ scanner.expectDone$0(); return A.MediaType$(t4, t5, parameters); }, - $signature: 48 + $signature: 35 }; A.MediaType_toString_closure.prototype = { call$2(attribute, value) { @@ -24182,13 +24450,13 @@ } else t1._contents = t3 + value; }, - $signature: 49 + $signature: 50 }; A.MediaType_toString__closure.prototype = { call$1(match) { return "\\" + A.S(match.$index(0, 0)); }, - $signature: 32 + $signature: 28 }; A.expectQuotedString_closure.prototype = { call$1(match) { @@ -24196,7 +24464,7 @@ t1.toString; return t1; }, - $signature: 32 + $signature: 28 }; A.Level.prototype = { $eq(_, other) { @@ -24244,7 +24512,7 @@ var record, _this = this, t1 = logLevel.value; if (t1 >= _this.get$level().value) { - if (stackTrace == null && t1 >= 2000) { + if ((stackTrace == null || stackTrace === B._StringStackTrace_OdL) && t1 >= 2000) { A.StackTrace_current(); if (error == null) logLevel.toString$0(0); @@ -24285,7 +24553,7 @@ $parent._children.$indexSet(0, thisName, t1); return t1; }, - $signature: 51 + $signature: 52 }; A.Context.prototype = { absolute$15(part1, part2, part3, part4, part5, part6, part7, part8, part9, part10, part11, part12, part13, part14, part15) { @@ -24319,10 +24587,10 @@ parsed.root = t4; if (t2.needsSeparator$1(t4)) B.JSArray_methods.$indexSet(parsed.separators, 0, t2.get$separator()); - t4 = parsed.toString$0(0); + t4 = "" + parsed.toString$0(0); } else if (t2.rootLength$1(t5) > 0) { isAbsoluteAndNotRootRelative = !t2.isRootRelative$1(t5); - t4 = t5; + t4 = "" + t5; } else { t6 = t5.length; if (t6 !== 0) { @@ -24488,7 +24756,7 @@ t2 = t1.length; if (t2 === 0) return "."; - if (t2 > 1 && B.JSArray_methods.get$last(t1) === ".") { + if (t2 > 1 && J.$eq$(B.JSArray_methods.get$last(t1), ".")) { B.JSArray_methods.removeLast$0(pathParsed.parts); t1 = pathParsed.separators; if (0 >= t1.length) @@ -24519,20 +24787,20 @@ call$1(part) { return A._asString(part) !== ""; }, - $signature: 31 + $signature: 20 }; A.Context_split_closure.prototype = { call$1(part) { return A._asString(part).length !== 0; }, - $signature: 31 + $signature: 20 }; A._validateArgList_closure.prototype = { call$1(arg) { A._asStringQ(arg); return arg == null ? "null" : '"' + arg + '"'; }, - $signature: 106 + $signature: 54 }; A.InternalStyle.prototype = { getRoot$1(path) { @@ -24557,7 +24825,7 @@ var t1, t2, _this = this; while (true) { t1 = _this.parts; - if (!(t1.length !== 0 && B.JSArray_methods.get$last(t1) === "")) + if (!(t1.length !== 0 && J.$eq$(B.JSArray_methods.get$last(t1), ""))) break; B.JSArray_methods.removeLast$0(_this.parts); t1 = _this.separators; @@ -24605,13 +24873,13 @@ toString$0(_) { var t2, t3, t4, t5, i, t1 = this.root; - t1 = t1 != null ? t1 : ""; + t1 = t1 != null ? "" + t1 : ""; for (t2 = this.parts, t3 = t2.length, t4 = this.separators, t5 = t4.length, i = 0; i < t3; ++i) { if (!(i < t5)) return A.ioore(t4, i); t1 = t1 + t4[i] + t2[i]; } - t1 += B.JSArray_methods.get$last(t4); + t1 += A.S(B.JSArray_methods.get$last(t4)); return t1.charCodeAt(0) == 0 ? t1 : t1; }, set$parts(parts) { @@ -25427,7 +25695,7 @@ call$0() { return this.color; }, - $signature: 54 + $signature: 55 }; A.Highlighter$__closure.prototype = { call$1(line) { @@ -25435,34 +25703,34 @@ t2 = A._arrayInstanceType(t1); return new A.WhereIterable(t1, t2._eval$1("bool(1)")._as(new A.Highlighter$___closure()), t2._eval$1("WhereIterable<1>")).get$length(0); }, - $signature: 55 + $signature: 56 }; A.Highlighter$___closure.prototype = { call$1(highlight) { var t1 = type$._Highlight._as(highlight).span; return t1.get$start().get$line() !== t1.get$end().get$line(); }, - $signature: 15 + $signature: 19 }; A.Highlighter$__closure0.prototype = { call$1(line) { return type$._Line._as(line).url; }, - $signature: 57 + $signature: 58 }; A.Highlighter__collateLines_closure.prototype = { call$1(highlight) { var t1 = type$._Highlight._as(highlight).span.get$sourceUrl(); return t1 == null ? new A.Object() : t1; }, - $signature: 58 + $signature: 59 }; A.Highlighter__collateLines_closure0.prototype = { call$2(highlight1, highlight2) { var t1 = type$._Highlight; return t1._as(highlight1).span.compareTo$1(0, t1._as(highlight2).span); }, - $signature: 59 + $signature: 60 }; A.Highlighter__collateLines_closure1.prototype = { call$1(entry) { @@ -25505,20 +25773,20 @@ } return lines; }, - $signature: 60 + $signature: 61 }; A.Highlighter__collateLines__closure.prototype = { call$1(highlight) { return type$._Highlight._as(highlight).span.get$end().get$line() < this.line.number; }, - $signature: 15 + $signature: 19 }; A.Highlighter_highlight_closure.prototype = { call$1(highlight) { type$._Highlight._as(highlight); return true; }, - $signature: 15 + $signature: 19 }; A.Highlighter__writeFileStart_closure.prototype = { call$0() { @@ -25619,7 +25887,7 @@ t4 = B.JSString_methods.$mul("^", Math.max(endColumn + (tabsBefore + tabsInside) * 3 - startColumn, 1)); return (t2._contents += t4).length - t3.length; }, - $signature: 28 + $signature: 30 }; A.Highlighter__writeIndicator_closure0.prototype = { call$0() { @@ -25640,7 +25908,7 @@ t1._writeArrow$3$beginning(_this.line, Math.max(_this.highlight.span.get$end().get$column() - 1, 0), false); return t2._contents.length - t3.length; }, - $signature: 28 + $signature: 30 }; A.Highlighter__writeSidebar_closure.prototype = { call$0() { @@ -25659,7 +25927,7 @@ A._Highlight.prototype = { toString$0(_) { var t1 = this.span; - t1 = "primary " + ("" + t1.get$start().get$line() + ":" + t1.get$start().get$column() + "-" + t1.get$end().get$line() + ":" + t1.get$end().get$column()); + t1 = "" + "primary " + ("" + t1.get$start().get$line() + ":" + t1.get$start().get$column() + "-" + t1.get$end().get$line() + ":" + t1.get$end().get$column()); return t1.charCodeAt(0) == 0 ? t1 : t1; } }; @@ -25676,7 +25944,7 @@ } return A._Highlight__normalizeEndOfLine(A._Highlight__normalizeTrailingNewline(A._Highlight__normalizeNewlines(newSpan))); }, - $signature: 62 + $signature: 63 }; A._Line.prototype = { toString$0(_) { @@ -25796,7 +26064,7 @@ toString$0(_) { var t3, t4, highlight, t1 = this._span, - t2 = "line " + (t1.get$start().get$line() + 1) + ", column " + (t1.get$start().get$column() + 1); + t2 = "" + ("line " + (t1.get$start().get$line() + 1) + ", column " + (t1.get$start().get$column() + 1)); if (t1.get$sourceUrl() != null) { t3 = t1.get$sourceUrl(); t4 = $.$get$context(); @@ -26045,31 +26313,31 @@ }); return A._asyncStartSync($async$call$0, $async$completer); }, - $signature: 65 + $signature: 66 }; A.generateUuidV4_generateBits.prototype = { call$1(bitCount) { return this.random.nextInt$1(B.JSInt_methods._shlPositive$1(1, bitCount)); }, - $signature: 27 + $signature: 22 }; A.generateUuidV4_printDigits.prototype = { call$2(value, count) { return B.JSString_methods.padLeft$2(B.JSInt_methods.toRadixString$1(value, 16), count, "0"); }, - $signature: 22 + $signature: 32 }; A.generateUuidV4_bitsDigits.prototype = { call$2(bitCount, digitCount) { return this.printDigits.call$2(this.generateBits.call$1(bitCount), digitCount); }, - $signature: 22 + $signature: 32 }; A.GuaranteeChannel.prototype = { GuaranteeChannel$3$allowSinkErrors(innerSink, allowSinkErrors, _box_0, $T) { var _this = this, t1 = _this.$ti, - t2 = t1._eval$1("_GuaranteeSink<1>")._as(new A._GuaranteeSink(innerSink, _this, new A._AsyncCompleter(new A._Future($.Zone__current, type$._Future_dynamic), type$._AsyncCompleter_dynamic), allowSinkErrors, $T._eval$1("_GuaranteeSink<0>"))); + t2 = t1._eval$1("_GuaranteeSink<1>")._as(new A._GuaranteeSink(innerSink, _this, new A._AsyncCompleter(new A._Future($.Zone__current, type$._Future_void), type$._AsyncCompleter_void), allowSinkErrors, $T._eval$1("_GuaranteeSink<0>"))); _this.__GuaranteeChannel__sink_F !== $ && A.throwLateFieldAI("_sink"); _this.__GuaranteeChannel__sink_F = t2; t1 = t1._eval$1("StreamController<1>")._as(A.StreamController_StreamController(null, new A.GuaranteeChannel_closure(_box_0, _this, $T), true, $T)); @@ -26242,30 +26510,30 @@ } }; A.RNG.prototype = {}; - A.MathRNG.prototype = { + A.CryptoRNG.prototype = { _generateInternal$0() { - var t1, i, k, t2, t3, + var i, k, t1, t2, b = new Uint8Array(16); - for (t1 = this._rnd, i = 0; i < 16; i += 4) { - k = t1.nextInt$1(B.JSNumber_methods.toInt$0(Math.pow(2, 32))); + for (i = 0; i < 16; i += 4) { + k = $.$get$CryptoRNG__secureRandom().nextInt$1(B.JSNumber_methods.toInt$0(Math.pow(2, 32))); if (!(i < 16)) return A.ioore(b, i); b[i] = k; - t2 = i + 1; - t3 = B.JSInt_methods._shrOtherPositive$1(k, 8); - if (!(t2 < 16)) - return A.ioore(b, t2); - b[t2] = t3; - t3 = i + 2; - t2 = B.JSInt_methods._shrOtherPositive$1(k, 16); - if (!(t3 < 16)) - return A.ioore(b, t3); - b[t3] = t2; - t2 = i + 3; - t3 = B.JSInt_methods._shrOtherPositive$1(k, 24); + t1 = i + 1; + t2 = B.JSInt_methods._shrOtherPositive$1(k, 8); + if (!(t1 < 16)) + return A.ioore(b, t1); + b[t1] = t2; + t2 = i + 2; + t1 = B.JSInt_methods._shrOtherPositive$1(k, 16); if (!(t2 < 16)) return A.ioore(b, t2); - b[t2] = t3; + b[t2] = t1; + t1 = i + 3; + t2 = B.JSInt_methods._shrOtherPositive$1(k, 24); + if (!(t1 < 16)) + return A.ioore(b, t1); + b[t1] = t2; } return b; } @@ -26617,7 +26885,7 @@ A._asString(webSocket._webSocket.protocol); t2._readyCompleter.complete$0(); }, - $signature: 67 + $signature: 68 }; A.AdapterWebSocketChannel__closure.prototype = { call$1($event) { @@ -26653,7 +26921,7 @@ } } }, - $signature: 68 + $signature: 69 }; A.AdapterWebSocketChannel__closure0.prototype = { call$1(obj) { @@ -26750,7 +27018,7 @@ }); return A._asyncStartSync($async$call$0, $async$completer); }, - $signature: 19 + $signature: 16 }; A.AdapterWebSocketChannel_closure0.prototype = { call$1(e) { @@ -26768,7 +27036,7 @@ t1 === $ && A.throwLateFieldNI("_sink"); t1.close$0(); }, - $signature: 69 + $signature: 70 }; A._WebSocketSink.prototype = {$isWebSocketSink: 1}; A.WebSocketChannelException.prototype = { @@ -26863,11 +27131,8 @@ A._sendConnectRequest(client.get$sink()); else A.runMain(); - else { + else A._sendConnectRequest(client.get$sink()); - if (A._asBool(t1.$useDwdsWebSocketConnection)) - A.runMain(); - } A._launchCommunicationWithDebugExtension(); // implicit return return A._asyncReturn(null, $async$completer); @@ -26875,7 +27140,7 @@ }); return A._asyncStartSync($async$call$0, $async$completer); }, - $signature: 19 + $signature: 16 }; A.main__closure.prototype = { call$0() { @@ -26905,7 +27170,7 @@ call$1(runId) { return this.call$2(runId, null); }, - $signature: 71 + $signature: 72 }; A.main__closure2.prototype = { call$0() { @@ -26932,7 +27197,7 @@ A._trySendEvent(t1, B.C_JsonCodec.encode$2$toEncodable(t2.serialize$1(t3._debug_event$_build$0()), null), type$.dynamic); } }, - $signature: 72 + $signature: 73 }; A.main___closure2.prototype = { call$1(b) { @@ -26941,7 +27206,7 @@ b.get$_debug_event$_$this().set$_events(t1); return t1; }, - $signature: 73 + $signature: 74 }; A.main__closure4.prototype = { call$2(kind, eventData) { @@ -26955,7 +27220,7 @@ A._trySendEvent(new A._StreamSinkWrapper(t1, A._instanceType(t1)._eval$1("_StreamSinkWrapper<1>")), t2._debug_event$_build$0(), type$.DebugEvent); } }, - $signature: 74 + $signature: 75 }; A.main___closure1.prototype = { call$1(b) { @@ -26965,7 +27230,7 @@ b.get$_debug_event$_$this()._eventData = this.eventData; return b; }, - $signature: 75 + $signature: 76 }; A.main__closure5.prototype = { call$1(eventData) { @@ -26977,7 +27242,7 @@ type$.nullable_void_Function_RegisterEventBuilder._as(new A.main___closure0(eventData)).call$1(t3); A._trySendEvent(t1, B.C_JsonCodec.encode$2$toEncodable(t2.serialize$1(t3._register_event$_build$0()), null), type$.dynamic); }, - $signature: 76 + $signature: 106 }; A.main___closure0.prototype = { call$1(b) { @@ -26986,7 +27251,7 @@ b.get$_register_event$_$this()._register_event$_eventData = this.eventData; return b; }, - $signature: 77 + $signature: 78 }; A.main__closure6.prototype = { call$0() { @@ -27012,7 +27277,7 @@ b.get$_devtools_request$_$this()._devtools_request$_instanceId = t1; return b; }, - $signature: 78 + $signature: 79 }; A.main__closure7.prototype = { call$1(serialized) { @@ -27122,14 +27387,29 @@ break; case 24: // else - $async$goto = $event instanceof A._$HotReloadRequest ? 25 : 26; + $async$goto = $event instanceof A._$HotReloadRequest ? 25 : 27; break; case 25: // then - $async$goto = 27; + $async$goto = 28; return A._asyncAwait(A.handleWebSocketHotReloadRequest($event, $async$self.manager, $async$self.client.get$sink()), $async$call$1); + case 28: + // returning from await. + // goto join + $async$goto = 26; + break; case 27: + // else + $async$goto = $event instanceof A._$ServiceExtensionRequest ? 29 : 30; + break; + case 29: + // then + $async$goto = 31; + return A._asyncAwait(A.handleServiceExtensionRequest($event, $async$self.client.get$sink(), $async$self.manager), $async$call$1); + case 31: // returning from await. + case 30: + // join case 26: // join case 23: @@ -27146,7 +27426,7 @@ }); return A._asyncStartSync($async$call$1, $async$completer); }, - $signature: 79 + $signature: 80 }; A.main__closure8.prototype = { call$1(error) { @@ -27170,7 +27450,7 @@ type$.StackTrace._as(stackTrace); A.print("Unhandled error detected in the injected client.js script.\n\nYou can disable this script in webdev by passing --no-injected-client if it\nis preventing your app from loading, but note that this will also prevent\nall debugging and hot reload/restart functionality from working.\n\nThe original error is below, please file an issue at\nhttps://github.com/dart-lang/webdev/issues/new and attach this output:\n\n" + A.S(error) + "\n" + stackTrace.toString$0(0) + "\n"); }, - $signature: 14 + $signature: 13 }; A._sendConnectRequest_closure.prototype = { call$1(b) { @@ -27183,7 +27463,7 @@ b.get$_connect_request$_$this()._entrypointPath = t1; return b; }, - $signature: 80 + $signature: 81 }; A._launchCommunicationWithDebugExtension_closure.prototype = { call$1(b) { @@ -27213,13 +27493,13 @@ b.get$_$this()._workspaceName = t1; return b; }, - $signature: 81 + $signature: 82 }; A._handleAuthRequest_closure.prototype = { call$1(isAuthenticated) { return A._dispatchEvent("dart-auth-response", "" + A._asBool(isAuthenticated)); }, - $signature: 82 + $signature: 83 }; A._sendResponse_closure.prototype = { call$1(b) { @@ -27234,6 +27514,9 @@ }; A.DdcLibraryBundleRestarter.prototype = { _runMainWhenReady$2(readyToRunMain, runMain) { + return this._runMainWhenReady$body$DdcLibraryBundleRestarter(readyToRunMain, runMain); + }, + _runMainWhenReady$body$DdcLibraryBundleRestarter(readyToRunMain, runMain) { var $async$goto = 0, $async$completer = A._makeAsyncAwaitCompleter(type$.void); var $async$_runMainWhenReady$2 = A._wrapJsFunctionForAsync(function($async$errorCode, $async$result) { @@ -27295,6 +27578,9 @@ return A._asyncStartSync($async$restart$2$readyToRunMain$runId, $async$completer); }, hotReloadStart$1(hotReloadSourcesPath) { + return this.hotReloadStart$body$DdcLibraryBundleRestarter(hotReloadSourcesPath); + }, + hotReloadStart$body$DdcLibraryBundleRestarter(hotReloadSourcesPath) { var $async$goto = 0, $async$completer = A._makeAsyncAwaitCompleter(type$.JSArray_nullable_Object), $async$returnValue, $async$self = this, t4, srcModuleLibraries, filesToLoad, librariesToReload, t5, t6, t7, srcModuleLibraryCast, src, libraries, t8, t1, t2, t3, xhr, $async$temp1, $async$temp2, $async$temp3; @@ -27325,12 +27611,12 @@ t1 = type$.JSArray_nullable_Object; filesToLoad = t1._as(new t2.Array()); librariesToReload = t1._as(new t2.Array()); - for (t5 = srcModuleLibraries.get$iterator(srcModuleLibraries), t6 = type$.String, t7 = type$.Object; t5.moveNext$0();) { + for (t5 = J.get$iterator$ax(srcModuleLibraries), t6 = type$.String, t7 = type$.Object; t5.moveNext$0();) { srcModuleLibraryCast = t5.get$current().cast$2$0(0, t6, t7); src = A._asString(srcModuleLibraryCast.$index(0, "src")); libraries = J.cast$1$0$ax(t4._as(srcModuleLibraryCast.$index(0, "libraries")), t6); filesToLoad.push(src); - for (t8 = libraries.get$iterator(libraries); t8.moveNext$0();) + for (t8 = J.get$iterator$ax(libraries); t8.moveNext$0();) librariesToReload.push(t8.get$current()); } t3._as(t3._as(t2.dartDevEmbedder).config).capturedHotReloadEndHandler = A._functionToJS1(new A.DdcLibraryBundleRestarter_hotReloadStart_closure0($async$self)); @@ -27370,6 +27656,78 @@ }); return A._asyncStartSync($async$hotReloadEnd$0, $async$completer); }, + handleServiceExtension$2(method, args) { + return this.handleServiceExtension$body$DdcLibraryBundleRestarter(method, type$.Map_String_dynamic._as(args)); + }, + handleServiceExtension$body$DdcLibraryBundleRestarter(method, args) { + var $async$goto = 0, + $async$completer = A._makeAsyncAwaitCompleter(type$.nullable_Map_String_dynamic), + $async$returnValue, t1, t2, params, $async$temp1, $async$temp2; + var $async$handleServiceExtension$2 = A._wrapJsFunctionForAsync(function($async$errorCode, $async$result) { + if ($async$errorCode === 1) + return A._asyncRethrow($async$result, $async$completer); + while (true) + switch ($async$goto) { + case 0: + // Function start + $async$goto = method === "ext.flutter.reassemble" ? 3 : 5; + break; + case 3: + // then + t1 = type$.JSObject; + $async$goto = 6; + return A._asyncAwait(A._Debugger_maybeInvokeFlutterReassemble(t1._as(t1._as(init.G.dartDevEmbedder).debugger)), $async$handleServiceExtension$2); + case 6: + // returning from await. + $async$returnValue = A.LinkedHashMap_LinkedHashMap$_literal(["status", "reassemble invoked"], type$.String, type$.dynamic); + // goto return + $async$goto = 1; + break; + // goto join + $async$goto = 4; + break; + case 5: + // else + $async$goto = method === "getExtensionRpcs" ? 7 : 9; + break; + case 7: + // then + t1 = type$.JSObject; + t1 = type$.JSArray_nullable_Object._as(t1._as(t1._as(init.G.dartDevEmbedder).debugger).extensionNames); + t1 = type$.List_String._is(t1) ? t1 : new A.CastList(t1, A._arrayInstanceType(t1)._eval$1("CastList<1,String>")); + t2 = type$.String; + $async$returnValue = A.LinkedHashMap_LinkedHashMap$_literal(["rpcs", J.cast$1$0$ax(t1, t2)], t2, type$.dynamic); + // goto return + $async$goto = 1; + break; + // goto join + $async$goto = 8; + break; + case 9: + // else + params = args.get$isNotEmpty(args) ? B.C_JsonCodec.encode$2$toEncodable(args, null) : "{}"; + t1 = type$.JSObject; + $async$temp1 = type$.Map_String_dynamic; + $async$temp2 = B.C_JsonCodec; + $async$goto = 10; + return A._asyncAwait(A.promiseToFuture(t1._as(t1._as(t1._as(init.G.dartDevEmbedder).debugger).invokeExtension(method, params)), type$.String), $async$handleServiceExtension$2); + case 10: + // returning from await. + $async$returnValue = $async$temp1._as($async$temp2.decode$2$reviver($async$result, null)); + // goto return + $async$goto = 1; + break; + case 8: + // join + case 4: + // join + case 1: + // return + return A._asyncReturn($async$returnValue, $async$completer); + } + }); + return A._asyncStartSync($async$handleServiceExtension$2, $async$completer); + }, $isRestarter: 1 }; A.DdcLibraryBundleRestarter_restart_closure.prototype = { @@ -27380,7 +27738,7 @@ t1._as(t1._as(init.G.dartDevEmbedder).config).capturedMainHandler = null; A.safeUnawaited(this.$this._runMainWhenReady$2(this.readyToRunMain, runMain)); }, - $signature: 20 + $signature: 33 }; A.DdcLibraryBundleRestarter_hotReloadStart_closure.prototype = { call$0() { @@ -27394,7 +27752,7 @@ call$1(hotReloadEndCallback) { this.$this._capturedHotReloadEndCallback = type$.JavaScriptFunction._as(hotReloadEndCallback); }, - $signature: 20 + $signature: 33 }; A.DdcRestarter.prototype = { restart$2$readyToRunMain$runId(readyToRunMain, runId) { @@ -27448,7 +27806,7 @@ this.sub.cancel$0(); return value; }, - $signature: 84 + $signature: 85 }; A.ReloadingManager.prototype = { hotRestart$2$readyToRunMain$runId(readyToRunMain, runId) { @@ -27509,6 +27867,46 @@ }); return A._asyncStartSync($async$hotReloadEnd$0, $async$completer); }, + handleServiceExtension$2(method, args) { + return this.handleServiceExtension$body$ReloadingManager(method, type$.Map_String_dynamic._as(args)); + }, + handleServiceExtension$body$ReloadingManager(method, args) { + var $async$goto = 0, + $async$completer = A._makeAsyncAwaitCompleter(type$.nullable_Map_String_dynamic), + $async$returnValue, $async$self = this, restarter; + var $async$handleServiceExtension$2 = A._wrapJsFunctionForAsync(function($async$errorCode, $async$result) { + if ($async$errorCode === 1) + return A._asyncRethrow($async$result, $async$completer); + while (true) + switch ($async$goto) { + case 0: + // Function start + restarter = $async$self._restarter; + $async$goto = restarter instanceof A.DdcLibraryBundleRestarter ? 3 : 4; + break; + case 3: + // then + $async$goto = 5; + return A._asyncAwait(restarter.handleServiceExtension$2(method, args), $async$handleServiceExtension$2); + case 5: + // returning from await. + $async$returnValue = $async$result; + // goto return + $async$goto = 1; + break; + case 4: + // join + $async$returnValue = null; + // goto return + $async$goto = 1; + break; + case 1: + // return + return A._asyncReturn($async$returnValue, $async$completer); + } + }); + return A._asyncStartSync($async$handleServiceExtension$2, $async$completer); + }, _afterRestart$1(succeeded) { var t1, t2; if (!succeeded) @@ -27915,7 +28313,7 @@ call$1(e) { this.completer.completeError$2(new A.HotReloadFailedException(A._asString(type$.JavaScriptObject._as(e).message)), this.stackTrace); }, - $signature: 87 + $signature: 88 }; A._createScript_closure.prototype = { call$0() { @@ -27924,7 +28322,7 @@ return new A._createScript__closure(); return new A._createScript__closure0(nonce); }, - $signature: 88 + $signature: 89 }; A._createScript__closure.prototype = { call$0() { @@ -27989,46 +28387,51 @@ _instance_1_i = hunkHelpers._instance_1i, _instance_0_u = hunkHelpers._instance_0u, _instance_1_u = hunkHelpers._instance_1u; - _static_2(J, "_interceptors_JSArray__compareAny$closure", "JSArray__compareAny", 30); - _static_1(A, "async__AsyncRun__scheduleImmediateJsOverride$closure", "_AsyncRun__scheduleImmediateJsOverride", 16); - _static_1(A, "async__AsyncRun__scheduleImmediateWithSetImmediate$closure", "_AsyncRun__scheduleImmediateWithSetImmediate", 16); - _static_1(A, "async__AsyncRun__scheduleImmediateWithTimer$closure", "_AsyncRun__scheduleImmediateWithTimer", 16); + _static_2(J, "_interceptors_JSArray__compareAny$closure", "JSArray__compareAny", 34); + _static_1(A, "async__AsyncRun__scheduleImmediateJsOverride$closure", "_AsyncRun__scheduleImmediateJsOverride", 12); + _static_1(A, "async__AsyncRun__scheduleImmediateWithSetImmediate$closure", "_AsyncRun__scheduleImmediateWithSetImmediate", 12); + _static_1(A, "async__AsyncRun__scheduleImmediateWithTimer$closure", "_AsyncRun__scheduleImmediateWithTimer", 12); _static_0(A, "async___startMicrotaskLoop$closure", "_startMicrotaskLoop", 0); _static_1(A, "async___nullDataHandler$closure", "_nullDataHandler", 7); - _static_2(A, "async___nullErrorHandler$closure", "_nullErrorHandler", 14); + _static_2(A, "async___nullErrorHandler$closure", "_nullErrorHandler", 13); _static_0(A, "async___nullDoneHandler$closure", "_nullDoneHandler", 0); - _static(A, "async___rootHandleUncaughtError$closure", 5, null, ["call$5"], ["_rootHandleUncaughtError"], 91, 0); + _static(A, "async___rootHandleUncaughtError$closure", 5, null, ["call$5"], ["_rootHandleUncaughtError"], 92, 0); _static(A, "async___rootRun$closure", 4, null, ["call$1$4", "call$4"], ["_rootRun", function($self, $parent, zone, f) { + f.toString; return A._rootRun($self, $parent, zone, f, type$.dynamic); - }], 92, 0); + }], 93, 0); _static(A, "async___rootRunUnary$closure", 5, null, ["call$2$5", "call$5"], ["_rootRunUnary", function($self, $parent, zone, f, arg) { var t1 = type$.dynamic; + f.toString; return A._rootRunUnary($self, $parent, zone, f, arg, t1, t1); - }], 93, 0); - _static(A, "async___rootRunBinary$closure", 6, null, ["call$3$6"], ["_rootRunBinary"], 94, 0); + }], 94, 0); + _static(A, "async___rootRunBinary$closure", 6, null, ["call$3$6"], ["_rootRunBinary"], 95, 0); _static(A, "async___rootRegisterCallback$closure", 4, null, ["call$1$4", "call$4"], ["_rootRegisterCallback", function($self, $parent, zone, f) { + f.toString; return A._rootRegisterCallback($self, $parent, zone, f, type$.dynamic); - }], 95, 0); + }], 96, 0); _static(A, "async___rootRegisterUnaryCallback$closure", 4, null, ["call$2$4", "call$4"], ["_rootRegisterUnaryCallback", function($self, $parent, zone, f) { var t1 = type$.dynamic; + f.toString; return A._rootRegisterUnaryCallback($self, $parent, zone, f, t1, t1); - }], 96, 0); + }], 97, 0); _static(A, "async___rootRegisterBinaryCallback$closure", 4, null, ["call$3$4", "call$4"], ["_rootRegisterBinaryCallback", function($self, $parent, zone, f) { var t1 = type$.dynamic; + f.toString; return A._rootRegisterBinaryCallback($self, $parent, zone, f, t1, t1, t1); - }], 97, 0); - _static(A, "async___rootErrorCallback$closure", 5, null, ["call$5"], ["_rootErrorCallback"], 98, 0); - _static(A, "async___rootScheduleMicrotask$closure", 4, null, ["call$4"], ["_rootScheduleMicrotask"], 99, 0); - _static(A, "async___rootCreateTimer$closure", 5, null, ["call$5"], ["_rootCreateTimer"], 100, 0); - _static(A, "async___rootCreatePeriodicTimer$closure", 5, null, ["call$5"], ["_rootCreatePeriodicTimer"], 101, 0); - _static(A, "async___rootPrint$closure", 4, null, ["call$4"], ["_rootPrint"], 102, 0); - _static_1(A, "async___printToZone$closure", "_printToZone", 103); - _static(A, "async___rootFork$closure", 5, null, ["call$5"], ["_rootFork"], 104, 0); - _instance(A._Completer.prototype, "get$completeError", 0, 1, null, ["call$2", "call$1"], ["completeError$2", "completeError$1"], 33, 0, 0); - _instance_2_u(A._Future.prototype, "get$_completeError", "_completeError$2", 14); + }], 98, 0); + _static(A, "async___rootErrorCallback$closure", 5, null, ["call$5"], ["_rootErrorCallback"], 99, 0); + _static(A, "async___rootScheduleMicrotask$closure", 4, null, ["call$4"], ["_rootScheduleMicrotask"], 100, 0); + _static(A, "async___rootCreateTimer$closure", 5, null, ["call$5"], ["_rootCreateTimer"], 101, 0); + _static(A, "async___rootCreatePeriodicTimer$closure", 5, null, ["call$5"], ["_rootCreatePeriodicTimer"], 102, 0); + _static(A, "async___rootPrint$closure", 4, null, ["call$4"], ["_rootPrint"], 103, 0); + _static_1(A, "async___printToZone$closure", "_printToZone", 104); + _static(A, "async___rootFork$closure", 5, null, ["call$5"], ["_rootFork"], 105, 0); + _instance(A._Completer.prototype, "get$completeError", 0, 1, null, ["call$2", "call$1"], ["completeError$2", "completeError$1"], 23, 0, 0); + _instance_2_u(A._Future.prototype, "get$_completeError", "_completeError$2", 13); var _; _instance_1_i(_ = A._StreamController.prototype, "get$add", "add$1", 9); - _instance(_, "get$addError", 0, 1, null, ["call$2", "call$1"], ["addError$2", "addError$1"], 33, 0, 0); + _instance(_, "get$addError", 0, 1, null, ["call$2", "call$1"], ["addError$2", "addError$1"], 23, 0, 0); _instance_0_u(_ = A._ControllerSubscription.prototype, "get$_onPause", "_onPause$0", 0); _instance_0_u(_, "get$_onResume", "_onResume$0", 0); _instance_0_u(_ = A._BufferingStreamSubscription.prototype, "get$_onPause", "_onPause$0", 0); @@ -28037,52 +28440,53 @@ _instance_0_u(_ = A._ForwardingStreamSubscription.prototype, "get$_onPause", "_onPause$0", 0); _instance_0_u(_, "get$_onResume", "_onResume$0", 0); _instance_1_u(_, "get$_handleData", "_handleData$1", 9); - _instance_2_u(_, "get$_handleError", "_handleError$2", 21); + _instance_2_u(_, "get$_handleError", "_handleError$2", 25); _instance_0_u(_, "get$_handleDone", "_handleDone$0", 0); - _static_2(A, "collection___defaultEquals$closure", "_defaultEquals0", 18); - _static_1(A, "collection___defaultHashCode$closure", "_defaultHashCode", 17); - _static_2(A, "collection_ListBase__compareAny$closure", "ListBase__compareAny", 30); + _static_2(A, "collection___defaultEquals$closure", "_defaultEquals0", 17); + _static_1(A, "collection___defaultHashCode$closure", "_defaultHashCode", 18); + _static_2(A, "collection_ListBase__compareAny$closure", "ListBase__compareAny", 34); _static_1(A, "convert___defaultToEncodable$closure", "_defaultToEncodable", 4); _instance_1_i(_ = A._ByteCallbackSink.prototype, "get$add", "add$1", 9); _instance_0_u(_, "get$close", "close$0", 0); - _static_1(A, "core__identityHashCode$closure", "identityHashCode", 17); - _static_2(A, "core__identical$closure", "identical", 18); - _static_1(A, "core_Uri_decodeComponent$closure", "Uri_decodeComponent", 13); + _static_1(A, "core__identityHashCode$closure", "identityHashCode", 18); + _static_2(A, "core__identical$closure", "identical", 17); + _static_1(A, "core_Uri_decodeComponent$closure", "Uri_decodeComponent", 15); _static(A, "math__max$closure", 2, null, ["call$1$2", "call$2"], ["max", function(a, b) { + a.toString; + b.toString; return A.max(a, b, type$.num); - }], 105, 0); - _instance_2_u(_ = A.DeepCollectionEquality.prototype, "get$equals", "equals$2", 18); - _instance_1_u(_, "get$hash", "hash$1", 17); - _instance_1_u(_, "get$isValidKey", "isValidKey$1", 12); + }], 77, 0); + _instance_2_u(_ = A.DeepCollectionEquality.prototype, "get$equals", "equals$2", 17); + _instance_1_u(_, "get$hash", "hash$1", 18); + _instance_1_u(_, "get$isValidKey", "isValidKey$1", 14); _static(A, "hot_reload_response_HotReloadResponse___new_tearOff$closure", 0, null, ["call$1", "call$0"], ["HotReloadResponse___new_tearOff", function() { return A.HotReloadResponse___new_tearOff(null); - }], 70, 0); - _static_1(A, "case_insensitive_map_CaseInsensitiveMap__canonicalizer$closure", "CaseInsensitiveMap__canonicalizer", 13); + }], 71, 0); + _static_1(A, "case_insensitive_map_CaseInsensitiveMap__canonicalizer$closure", "CaseInsensitiveMap__canonicalizer", 15); _instance_1_u(_ = A.SseClient.prototype, "get$_onIncomingControlMessage", "_onIncomingControlMessage$1", 2); _instance_1_u(_, "get$_onIncomingMessage", "_onIncomingMessage$1", 2); _instance_0_u(_, "get$_onOutgoingDone", "_onOutgoingDone$0", 0); - _instance_1_u(_, "get$_onOutgoingMessage", "_onOutgoingMessage$1", 64); + _instance_1_u(_, "get$_onOutgoingMessage", "_onOutgoingMessage$1", 65); _static_1(A, "client___handleAuthRequest$closure", "_handleAuthRequest", 2); - _instance_1_u(_ = A.RequireRestarter.prototype, "get$_moduleParents", "_moduleParents$1", 85); - _instance_2_u(_, "get$_moduleTopologicalCompare", "_moduleTopologicalCompare$2", 86); + _instance_1_u(_ = A.RequireRestarter.prototype, "get$_moduleParents", "_moduleParents$1", 86); + _instance_2_u(_, "get$_moduleTopologicalCompare", "_moduleTopologicalCompare$2", 87); })(); (function inheritance() { var _mixin = hunkHelpers.mixin, _inherit = hunkHelpers.inherit, _inheritMany = hunkHelpers.inheritMany; _inherit(A.Object, null); - _inheritMany(A.Object, [A.JS_CONST, J.Interceptor, A.SafeToStringHook, J.ArrayIterator, A.Iterable, A.CastIterator, A.Closure, A.MapBase, A.Error, A.ListBase, A.SentinelValue, A.ListIterator, A.MappedIterator, A.WhereIterator, A.ExpandIterator, A.TakeIterator, A.SkipIterator, A.EmptyIterator, A.WhereTypeIterator, A.FixedLengthListMixin, A.UnmodifiableListMixin, A.ConstantMap, A._KeysOrValuesOrElementsIterator, A.TypeErrorDecoder, A.NullThrownFromJavaScriptException, A.ExceptionAndStackTrace, A._StackTrace, A.LinkedHashMapCell, A.LinkedHashMapKeyIterator, A.LinkedHashMapValueIterator, A.LinkedHashMapEntryIterator, A._Record, A.JSSyntaxRegExp, A._MatchImplementation, A._AllMatchesIterator, A.StringMatch, A._StringAllMatchesIterator, A._Cell, A.Rti, A._FunctionParameters, A._Type, A._TimerImpl, A._AsyncAwaitCompleter, A.AsyncError, A.TimeoutException, A._Completer, A._FutureListener, A._Future, A._AsyncCallbackEntry, A.Stream, A._StreamController, A._SyncStreamControllerDispatch, A._AsyncStreamControllerDispatch, A._BufferingStreamSubscription, A._StreamSinkWrapper, A._DelayedEvent, A._DelayedDone, A._PendingEvents, A._DoneStreamSubscription, A._StreamIterator, A._ZoneFunction, A._ZoneSpecification, A._ZoneDelegate, A._Zone, A._HashMapKeyIterator, A.SetBase, A._HashSetIterator, A._LinkedHashSetCell, A._LinkedHashSetIterator, A._UnmodifiableMapMixin, A.MapView, A._ListQueueIterator, A._SplayTreeNode, A._SplayTree, A._SplayTreeIterator, A.Codec, A.Converter, A._Base64Encoder, A._Base64Decoder, A.ByteConversionSink, A._JsonStringifier, A._Utf8Encoder, A._Utf8Decoder, A._BigIntImpl, A.DateTime, A.Duration, A.OutOfMemoryError, A.StackOverflowError, A._Exception, A.FormatException, A.IntegerDivisionByZeroException, A.MapEntry, A.Null, A._StringStackTrace, A.StringBuffer, A._Uri, A.UriData, A._SimpleUri, A.NullRejectionException, A._JSRandom, A.AsyncMemoizer, A.DelegatingStreamSink, A.ErrorResult, A.ValueResult, A.StreamQueue, A._NextRequest, A._HasNextRequest, A.BuiltList, A.ListBuilder, A.BuiltListMultimap, A.ListMultimapBuilder, A.BuiltMap, A.MapBuilder, A.BuiltSet, A.SetBuilder, A.BuiltSetMultimap, A.SetMultimapBuilder, A.EnumClass, A.IndentingBuiltValueToStringHelper, A.JsonObject, A.FullType, A.BigIntSerializer, A.BoolSerializer, A.BuiltJsonSerializers, A.BuiltJsonSerializersBuilder, A.BuiltListMultimapSerializer, A.BuiltListSerializer, A.BuiltMapSerializer, A.BuiltSetMultimapSerializer, A.BuiltSetSerializer, A.DateTimeSerializer, A.DoubleSerializer, A.DurationSerializer, A.Int32Serializer, A.Int64Serializer, A.IntSerializer, A.JsonObjectSerializer, A.ListSerializer, A.MapSerializer, A.NullSerializer, A.NumSerializer, A.RegExpSerializer, A.SetSerializer, A.StringSerializer, A.Uint8ListSerializer, A.UriSerializer, A.CanonicalizedMap, A.DefaultEquality, A.IterableEquality, A.ListEquality, A._UnorderedEquality, A._MapEntry, A.MapEquality, A.DeepCollectionEquality, A._QueueList_Object_ListMixin, A.BuildResult, A._$BuildStatusSerializer, A._$BuildResultSerializer, A.BuildResultBuilder, A.ConnectRequest, A._$ConnectRequestSerializer, A.ConnectRequestBuilder, A.DebugEvent, A.BatchedDebugEvents, A._$DebugEventSerializer, A._$BatchedDebugEventsSerializer, A.DebugEventBuilder, A.BatchedDebugEventsBuilder, A.DebugInfo, A._$DebugInfoSerializer, A.DebugInfoBuilder, A.DevToolsRequest, A.DevToolsResponse, A._$DevToolsRequestSerializer, A._$DevToolsResponseSerializer, A.DevToolsRequestBuilder, A.DevToolsResponseBuilder, A.ErrorResponse, A._$ErrorResponseSerializer, A.ErrorResponseBuilder, A.ExtensionRequest, A.ExtensionResponse, A.ExtensionEvent, A.BatchedEvents, A._$ExtensionRequestSerializer, A._$ExtensionResponseSerializer, A._$ExtensionEventSerializer, A._$BatchedEventsSerializer, A.ExtensionRequestBuilder, A.ExtensionResponseBuilder, A.ExtensionEventBuilder, A.BatchedEventsBuilder, A.HotReloadRequest, A._$HotReloadRequestSerializer, A.HotReloadRequestBuilder, A.HotReloadResponse, A._$HotReloadResponseSerializer, A.HotReloadResponseBuilder, A.IsolateExit, A.IsolateStart, A._$IsolateExitSerializer, A._$IsolateStartSerializer, A.IsolateExitBuilder, A.IsolateStartBuilder, A.RegisterEvent, A._$RegisterEventSerializer, A.RegisterEventBuilder, A.RunRequest, A._$RunRequestSerializer, A.BatchedStreamController, A.SocketClient, A.Int32, A.Int64, A._StackState, A.BaseClient, A.BaseRequest, A.BaseResponse, A.ClientException, A.MediaType, A.Level, A.LogRecord, A.Logger, A.Context, A.Style, A.ParsedPath, A.PathException, A.Pool, A.PoolResource, A.SourceFile, A.SourceLocationMixin, A.SourceSpanMixin, A.Highlighter, A._Highlight, A._Line, A.SourceLocation, A.SourceSpanException, A.StreamChannelMixin, A._GuaranteeSink, A.StreamChannelController, A.StringScanner, A.RNG, A.UuidV1, A.EventStreamProvider, A._EventStreamSubscription, A.BrowserWebSocket, A.WebSocketEvent, A.WebSocketException, A.WebSocketChannelException, A.DdcLibraryBundleRestarter, A.DdcRestarter, A.ReloadingManager, A.HotReloadFailedException, A.RequireRestarter]); + _inheritMany(A.Object, [A.JS_CONST, J.Interceptor, J.ArrayIterator, A.Iterable, A.CastIterator, A.Closure, A.MapBase, A.Error, A.ListBase, A.SentinelValue, A.ListIterator, A.MappedIterator, A.WhereIterator, A.ExpandIterator, A.TakeIterator, A.SkipIterator, A.EmptyIterator, A.WhereTypeIterator, A.FixedLengthListMixin, A.UnmodifiableListMixin, A.ConstantMap, A._KeysOrValuesOrElementsIterator, A.TypeErrorDecoder, A.NullThrownFromJavaScriptException, A.ExceptionAndStackTrace, A._StackTrace, A.LinkedHashMapCell, A.LinkedHashMapKeyIterator, A.LinkedHashMapValueIterator, A.LinkedHashMapEntryIterator, A._Record, A.JSSyntaxRegExp, A._MatchImplementation, A._AllMatchesIterator, A.StringMatch, A._StringAllMatchesIterator, A._Cell, A._UnmodifiableNativeByteBufferView, A.Rti, A._FunctionParameters, A._Type, A._TimerImpl, A._AsyncAwaitCompleter, A.AsyncError, A.TimeoutException, A._Completer, A._FutureListener, A._Future, A._AsyncCallbackEntry, A.Stream, A._StreamController, A._SyncStreamControllerDispatch, A._AsyncStreamControllerDispatch, A._BufferingStreamSubscription, A._StreamSinkWrapper, A._DelayedEvent, A._DelayedDone, A._PendingEvents, A._DoneStreamSubscription, A._StreamIterator, A._ZoneFunction, A._ZoneSpecification, A._ZoneDelegate, A._Zone, A._HashMapKeyIterator, A.SetBase, A._HashSetIterator, A._LinkedHashSetCell, A._LinkedHashSetIterator, A._UnmodifiableMapMixin, A.MapView, A._ListQueueIterator, A._SplayTreeNode, A._SplayTree, A._SplayTreeIterator, A.Codec, A.Converter, A._Base64Encoder, A._Base64Decoder, A.ByteConversionSink, A._JsonStringifier, A._Utf8Encoder, A._Utf8Decoder, A._BigIntImpl, A.DateTime, A.Duration, A.OutOfMemoryError, A.StackOverflowError, A._Exception, A.FormatException, A.IntegerDivisionByZeroException, A.MapEntry, A.Null, A._StringStackTrace, A.StringBuffer, A._Uri, A.UriData, A._SimpleUri, A.NullRejectionException, A._JSRandom, A._JSSecureRandom, A.AsyncMemoizer, A.DelegatingStreamSink, A.ErrorResult, A.ValueResult, A.StreamQueue, A._NextRequest, A._HasNextRequest, A.BuiltList, A.ListBuilder, A.BuiltListMultimap, A.ListMultimapBuilder, A.BuiltMap, A.MapBuilder, A.BuiltSet, A.SetBuilder, A.BuiltSetMultimap, A.SetMultimapBuilder, A.EnumClass, A.IndentingBuiltValueToStringHelper, A.JsonObject, A.FullType, A.BigIntSerializer, A.BoolSerializer, A.BuiltJsonSerializers, A.BuiltJsonSerializersBuilder, A.BuiltListMultimapSerializer, A.BuiltListSerializer, A.BuiltMapSerializer, A.BuiltSetMultimapSerializer, A.BuiltSetSerializer, A.DateTimeSerializer, A.DoubleSerializer, A.DurationSerializer, A.Int32Serializer, A.Int64Serializer, A.IntSerializer, A.JsonObjectSerializer, A.NullSerializer, A.NumSerializer, A.RegExpSerializer, A.StringSerializer, A.Uint8ListSerializer, A.UriSerializer, A.CanonicalizedMap, A.DefaultEquality, A.IterableEquality, A.ListEquality, A._UnorderedEquality, A._MapEntry, A.MapEquality, A.DeepCollectionEquality, A._QueueList_Object_ListMixin, A.BuildResult, A._$BuildStatusSerializer, A._$BuildResultSerializer, A.BuildResultBuilder, A.ConnectRequest, A._$ConnectRequestSerializer, A.ConnectRequestBuilder, A.DebugEvent, A.BatchedDebugEvents, A._$DebugEventSerializer, A._$BatchedDebugEventsSerializer, A.DebugEventBuilder, A.BatchedDebugEventsBuilder, A.DebugInfo, A._$DebugInfoSerializer, A.DebugInfoBuilder, A.DevToolsRequest, A.DevToolsResponse, A._$DevToolsRequestSerializer, A._$DevToolsResponseSerializer, A.DevToolsRequestBuilder, A.DevToolsResponseBuilder, A.ErrorResponse, A._$ErrorResponseSerializer, A.ErrorResponseBuilder, A.ExtensionRequest, A.ExtensionResponse, A.ExtensionEvent, A.BatchedEvents, A._$ExtensionRequestSerializer, A._$ExtensionResponseSerializer, A._$ExtensionEventSerializer, A._$BatchedEventsSerializer, A.ExtensionRequestBuilder, A.ExtensionResponseBuilder, A.ExtensionEventBuilder, A.BatchedEventsBuilder, A.HotReloadRequest, A._$HotReloadRequestSerializer, A.HotReloadRequestBuilder, A.HotReloadResponse, A._$HotReloadResponseSerializer, A.HotReloadResponseBuilder, A.IsolateExit, A.IsolateStart, A._$IsolateExitSerializer, A._$IsolateStartSerializer, A.IsolateExitBuilder, A.IsolateStartBuilder, A.RegisterEvent, A._$RegisterEventSerializer, A.RegisterEventBuilder, A.RunRequest, A._$RunRequestSerializer, A.ServiceExtensionRequest, A._$ServiceExtensionRequestSerializer, A.ServiceExtensionRequestBuilder, A.ServiceExtensionResponse, A._$ServiceExtensionResponseSerializer, A.ServiceExtensionResponseBuilder, A.BatchedStreamController, A.SocketClient, A.Int32, A.Int64, A._StackState, A.BaseClient, A.BaseRequest, A.BaseResponse, A.ClientException, A.MediaType, A.Level, A.LogRecord, A.Logger, A.Context, A.Style, A.ParsedPath, A.PathException, A.Pool, A.PoolResource, A.SourceFile, A.SourceLocationMixin, A.SourceSpanMixin, A.Highlighter, A._Highlight, A._Line, A.SourceLocation, A.SourceSpanException, A.StreamChannelMixin, A._GuaranteeSink, A.StreamChannelController, A.StringScanner, A.RNG, A.UuidV1, A.EventStreamProvider, A._EventStreamSubscription, A.BrowserWebSocket, A.WebSocketEvent, A.WebSocketException, A.WebSocketChannelException, A.DdcLibraryBundleRestarter, A.DdcRestarter, A.ReloadingManager, A.HotReloadFailedException, A.RequireRestarter]); _inheritMany(J.Interceptor, [J.JSBool, J.JSNull, J.JavaScriptObject, J.JavaScriptBigInt, J.JavaScriptSymbol, J.JSNumber, J.JSString]); _inheritMany(J.JavaScriptObject, [J.LegacyJavaScriptObject, J.JSArray, A.NativeByteBuffer, A.NativeTypedData]); _inheritMany(J.LegacyJavaScriptObject, [J.PlainJavaScriptObject, J.UnknownJavaScriptObject, J.JavaScriptFunction]); - _inherit(J.JSArraySafeToStringHook, A.SafeToStringHook); _inherit(J.JSUnmodifiableArray, J.JSArray); _inheritMany(J.JSNumber, [J.JSInt, J.JSNumNotInt]); _inheritMany(A.Iterable, [A._CastIterableBase, A.EfficientLengthIterable, A.MappedIterable, A.WhereIterable, A.ExpandIterable, A.TakeIterable, A.SkipIterable, A.WhereTypeIterable, A._KeysOrValues, A._AllMatchesIterable, A._StringAllMatchesIterable]); _inheritMany(A._CastIterableBase, [A.CastIterable, A.__CastListBase__CastIterableBase_ListMixin]); _inherit(A._EfficientLengthCastIterable, A.CastIterable); _inherit(A._CastListBase, A.__CastListBase__CastIterableBase_ListMixin); - _inheritMany(A.Closure, [A.Closure2Args, A.Closure0Args, A.Instantiation, A.TearOffClosure, A.initHooks_closure, A.initHooks_closure1, A._AsyncRun__initializeScheduleImmediate_internalCallback, A._AsyncRun__initializeScheduleImmediate_closure, A._awaitOnObject_closure, A._Future__propagateToListeners_handleWhenCompleteCallback_closure, A._Future_timeout_closure0, A.Stream_length_closure, A.Stream_first_closure0, A._CustomZone_bindUnaryCallback_closure, A._CustomZone_bindUnaryCallbackGuarded_closure, A._RootZone_bindUnaryCallback_closure, A._RootZone_bindUnaryCallbackGuarded_closure, A.runZonedGuarded_closure, A._CustomHashMap_closure, A._LinkedCustomHashMap_closure, A._BigIntImpl_hashCode_finish, A._Uri__makePath_closure, A.FutureOfJSAnyToJSPromise_get_toJS__closure, A.FutureOfVoidToJSPromise_get_toJS__closure, A.jsify__convert, A.promiseToFuture_closure, A.promiseToFuture_closure0, A.dartify_convert, A.StreamQueue__ensureListening_closure, A.BuiltListMultimap_BuiltListMultimap_closure, A.BuiltListMultimap_hashCode_closure, A.ListMultimapBuilder_replace_closure, A.BuiltMap_BuiltMap_closure, A.BuiltMap_hashCode_closure, A.BuiltSet_hashCode_closure, A.BuiltSetMultimap_hashCode_closure, A.SetMultimapBuilder_replace_closure, A.newBuiltValueToStringHelper_closure, A.BuiltListMultimapSerializer_serialize_closure, A.BuiltListMultimapSerializer_deserialize_closure, A.BuiltListSerializer_serialize_closure, A.BuiltListSerializer_deserialize_closure, A.BuiltSetMultimapSerializer_serialize_closure, A.BuiltSetMultimapSerializer_deserialize_closure, A.BuiltSetSerializer_serialize_closure, A.BuiltSetSerializer_deserialize_closure, A.ListSerializer_serialize_closure, A.SetSerializer_serialize_closure, A.CanonicalizedMap_keys_closure, A.WebSocketClient_stream_closure, A.BaseRequest_closure0, A.BrowserClient_send_closure, A.BrowserClient_send_closure0, A.ByteStream_toBytes_closure, A.MediaType_toString__closure, A.expectQuotedString_closure, A.Context_joinAll_closure, A.Context_split_closure, A._validateArgList_closure, A.Pool__runOnRelease_closure, A.Highlighter$__closure, A.Highlighter$___closure, A.Highlighter$__closure0, A.Highlighter__collateLines_closure, A.Highlighter__collateLines_closure1, A.Highlighter__collateLines__closure, A.Highlighter_highlight_closure, A.SseClient_closure0, A.SseClient_closure1, A.generateUuidV4_generateBits, A._GuaranteeSink__addError_closure, A._EventStreamSubscription_closure, A._EventStreamSubscription_onData_closure, A.BrowserWebSocket_connect_closure, A.BrowserWebSocket_connect_closure0, A.BrowserWebSocket_connect_closure1, A.BrowserWebSocket_connect_closure2, A.AdapterWebSocketChannel_closure, A.AdapterWebSocketChannel__closure, A.AdapterWebSocketChannel__closure0, A.AdapterWebSocketChannel_closure0, A.main__closure1, A.main__closure3, A.main___closure2, A.main___closure1, A.main__closure5, A.main___closure0, A.main___closure, A.main__closure7, A.main__closure8, A.main__closure9, A._sendConnectRequest_closure, A._launchCommunicationWithDebugExtension_closure, A._handleAuthRequest_closure, A._sendResponse_closure, A.DdcLibraryBundleRestarter_restart_closure, A.DdcLibraryBundleRestarter_hotReloadStart_closure0, A.DdcRestarter_restart_closure0, A.DdcRestarter_restart_closure, A.RequireRestarter__reloadModule_closure0, A.JSArrayExtension_toDartIterable_closure]); + _inheritMany(A.Closure, [A.Closure2Args, A.Closure0Args, A.Instantiation, A.TearOffClosure, A.initHooks_closure, A.initHooks_closure1, A._AsyncRun__initializeScheduleImmediate_internalCallback, A._AsyncRun__initializeScheduleImmediate_closure, A._awaitOnObject_closure, A._Future__propagateToListeners_handleWhenCompleteCallback_closure, A._Future_timeout_closure0, A.Stream_length_closure, A.Stream_first_closure0, A._CustomZone_bindUnaryCallback_closure, A._CustomZone_bindUnaryCallbackGuarded_closure, A._RootZone_bindUnaryCallback_closure, A._RootZone_bindUnaryCallbackGuarded_closure, A.runZonedGuarded_closure, A._CustomHashMap_closure, A._LinkedCustomHashMap_closure, A._BigIntImpl_hashCode_finish, A._Uri__makePath_closure, A.FutureOfJSAnyToJSPromise_get_toJS__closure, A.FutureOfVoidToJSPromise_get_toJS__closure, A.jsify__convert, A.promiseToFuture_closure, A.promiseToFuture_closure0, A.dartify_convert, A.StreamQueue__ensureListening_closure, A.BuiltListMultimap_BuiltListMultimap_closure, A.BuiltListMultimap_hashCode_closure, A.ListMultimapBuilder_replace_closure, A.BuiltMap_BuiltMap_closure, A.BuiltMap_hashCode_closure, A.BuiltSet_hashCode_closure, A.BuiltSetMultimap_hashCode_closure, A.SetMultimapBuilder_replace_closure, A.newBuiltValueToStringHelper_closure, A.BuiltListMultimapSerializer_serialize_closure, A.BuiltListMultimapSerializer_deserialize_closure, A.BuiltListSerializer_serialize_closure, A.BuiltListSerializer_deserialize_closure, A.BuiltSetMultimapSerializer_serialize_closure, A.BuiltSetMultimapSerializer_deserialize_closure, A.BuiltSetSerializer_serialize_closure, A.BuiltSetSerializer_deserialize_closure, A.CanonicalizedMap_keys_closure, A.ServiceExtensionResponse_ServiceExtensionResponse$fromResult_closure, A.WebSocketClient_stream_closure, A.BaseRequest_closure0, A.BrowserClient_send_closure, A.BrowserClient_send_closure0, A.ByteStream_toBytes_closure, A.MediaType_toString__closure, A.expectQuotedString_closure, A.Context_joinAll_closure, A.Context_split_closure, A._validateArgList_closure, A.Pool__runOnRelease_closure, A.Highlighter$__closure, A.Highlighter$___closure, A.Highlighter$__closure0, A.Highlighter__collateLines_closure, A.Highlighter__collateLines_closure1, A.Highlighter__collateLines__closure, A.Highlighter_highlight_closure, A.SseClient_closure0, A.SseClient_closure1, A.generateUuidV4_generateBits, A._GuaranteeSink__addError_closure, A._EventStreamSubscription_closure, A._EventStreamSubscription_onData_closure, A.BrowserWebSocket_connect_closure, A.BrowserWebSocket_connect_closure0, A.BrowserWebSocket_connect_closure1, A.BrowserWebSocket_connect_closure2, A.AdapterWebSocketChannel_closure, A.AdapterWebSocketChannel__closure, A.AdapterWebSocketChannel__closure0, A.AdapterWebSocketChannel_closure0, A.main__closure1, A.main__closure3, A.main___closure2, A.main___closure1, A.main__closure5, A.main___closure0, A.main___closure, A.main__closure7, A.main__closure8, A.main__closure9, A._sendConnectRequest_closure, A._launchCommunicationWithDebugExtension_closure, A._handleAuthRequest_closure, A._sendResponse_closure, A.DdcLibraryBundleRestarter_restart_closure, A.DdcLibraryBundleRestarter_hotReloadStart_closure0, A.DdcRestarter_restart_closure0, A.DdcRestarter_restart_closure, A.RequireRestarter__reloadModule_closure0, A.JSArrayExtension_toDartIterable_closure]); _inheritMany(A.Closure2Args, [A._CastListBase_sort_closure, A.CastMap_forEach_closure, A.ConstantMap_map_closure, A.JsLinkedHashMap_addAll_closure, A.initHooks_closure0, A._awaitOnObject_closure0, A._wrapJsFunctionForAsync_closure, A._Future__propagateToListeners_handleWhenCompleteCallback_closure0, A._Future_timeout_closure1, A._BufferingStreamSubscription_asFuture_closure0, A.LinkedHashMap_LinkedHashMap$from_closure, A.MapBase_mapToString_closure, A._JsonStringifier_writeMap_closure, A._BigIntImpl_hashCode_combine, A.Uri__parseIPv4Address_error, A.Uri_parseIPv6Address_error, A.Uri_parseIPv6Address_parseHex, A.FutureOfJSAnyToJSPromise_get_toJS_closure, A.FutureOfJSAnyToJSPromise_get_toJS__closure0, A.FutureOfVoidToJSPromise_get_toJS_closure, A.FutureOfVoidToJSPromise_get_toJS__closure0, A.StreamQueue__ensureListening_closure1, A.hashObjects_closure, A.MapBuilder_replace_closure, A.CanonicalizedMap_addAll_closure, A.CanonicalizedMap_forEach_closure, A.CanonicalizedMap_map_closure, A.safeUnawaited_closure, A.BaseRequest_closure, A.MediaType_toString_closure, A.Pool__runOnRelease_closure0, A.Highlighter__collateLines_closure0, A.generateUuidV4_printDigits, A.generateUuidV4_bitsDigits, A.main__closure4, A.main_closure0]); _inherit(A.CastList, A._CastListBase); _inheritMany(A.MapBase, [A.CastMap, A.JsLinkedHashMap, A._HashMap, A._JsonMap]); @@ -28165,6 +28569,8 @@ _inherit(A._$IsolateStart, A.IsolateStart); _inherit(A._$RegisterEvent, A.RegisterEvent); _inherit(A._$RunRequest, A.RunRequest); + _inherit(A._$ServiceExtensionRequest, A.ServiceExtensionRequest); + _inherit(A._$ServiceExtensionResponse, A.ServiceExtensionResponse); _inheritMany(A.SocketClient, [A.SseSocketClient, A.WebSocketClient]); _inherit(A.BrowserClient, A.BaseClient); _inherit(A.ByteStream, A.StreamView); @@ -28180,7 +28586,7 @@ _inherit(A.SourceSpanWithContext, A.SourceSpanBase); _inheritMany(A.StreamChannelMixin, [A.SseClient, A.GuaranteeChannel, A.AdapterWebSocketChannel]); _inherit(A.StringScannerException, A.SourceSpanFormatException); - _inherit(A.MathRNG, A.RNG); + _inherit(A.CryptoRNG, A.RNG); _inheritMany(A.WebSocketEvent, [A.TextDataReceived, A.BinaryDataReceived, A.CloseReceived]); _inherit(A.WebSocketConnectionClosed, A.WebSocketException); _inherit(A._WebSocketSink, A.DelegatingStreamSink); @@ -28202,13 +28608,13 @@ typeUniverse: {eC: new Map(), tR: {}, eT: {}, tPV: {}, sEA: []}, mangledGlobalNames: {int: "int", double: "double", num: "num", String: "String", bool: "bool", Null: "Null", List: "List", Object: "Object", Map: "Map"}, mangledNames: {}, - types: ["~()", "Null()", "~(JSObject)", "Object?(@)", "@(@)", "Null(Object,StackTrace)", "Null(@)", "~(@)", "Null(JSObject)", "~(Object?)", "JSObject()", "Object?(Object?)", "bool(Object?)", "String(String)", "~(Object,StackTrace)", "bool(_Highlight)", "~(~())", "int(Object?)", "bool(Object?,Object?)", "Future<~>()", "Null(JavaScriptFunction)", "~(@,StackTrace)", "String(int,int)", "~(@,@)", "~(Object?,Object?)", "@()", "int(int,int)", "int(int)", "int()", "Null(JavaScriptFunction,JavaScriptFunction)", "int(@,@)", "bool(String)", "String(Match)", "~(Object[StackTrace?])", "bool()", "SetBuilder()", "MapBuilder()", "~(int,@)", "ListMultimapBuilder()", "ListBuilder()", "ListBuilder()", "ListBuilder()", "IndentingBuiltValueToStringHelper(String)", "String(@)", "bool(String,String)", "int(String)", "int(int,@)", "~(List)", "MediaType()", "~(String,String)", "Object?(~)", "Logger()", "JSObject(Object,StackTrace)", "Null(@,StackTrace)", "String?()", "int(_Line)", "~(String,int?)", "Object(_Line)", "Object(_Highlight)", "int(_Highlight,_Highlight)", "List<_Line>(MapEntry>)", "~(String,int)", "SourceSpanWithContext()", "Null(~())", "~(String?)", "Future()", "~(Zone,ZoneDelegate,Zone,Object,StackTrace)", "Null(WebSocket)", "~(WebSocketEvent)", "Null(Object)", "HotReloadResponse([~(HotReloadResponseBuilder)])", "JSObject(String[bool?])", "~(List)", "ListBuilder(BatchedDebugEventsBuilder)", "Null(String,String)", "DebugEventBuilder(DebugEventBuilder)", "Null(String)", "RegisterEventBuilder(RegisterEventBuilder)", "DevToolsRequestBuilder(DevToolsRequestBuilder)", "Future<~>(String)", "ConnectRequestBuilder(ConnectRequestBuilder)", "DebugInfoBuilder(DebugInfoBuilder)", "~(bool)", "@(@,String)", "bool(bool)", "List(String)", "int(String,String)", "Null(JavaScriptObject)", "JSObject()()", "SetMultimapBuilder()", "@(String)", "~(Zone?,ZoneDelegate?,Zone,Object,StackTrace)", "0^(Zone?,ZoneDelegate?,Zone,0^())", "0^(Zone?,ZoneDelegate?,Zone,0^(1^),1^)", "0^(Zone?,ZoneDelegate?,Zone,0^(1^,2^),1^,2^)", "0^()(Zone,ZoneDelegate,Zone,0^())", "0^(1^)(Zone,ZoneDelegate,Zone,0^(1^))", "0^(1^,2^)(Zone,ZoneDelegate,Zone,0^(1^,2^))", "AsyncError?(Zone,ZoneDelegate,Zone,Object,StackTrace?)", "~(Zone?,ZoneDelegate?,Zone,~())", "Timer(Zone,ZoneDelegate,Zone,Duration,~())", "Timer(Zone,ZoneDelegate,Zone,Duration,~(Timer))", "~(Zone,ZoneDelegate,Zone,String)", "~(String)", "Zone(Zone?,ZoneDelegate?,Zone,ZoneSpecification?,Map?)", "0^(0^,0^)", "String(String?)"], + types: ["~()", "Null()", "~(JSObject)", "Object?(@)", "@(@)", "Null(Object,StackTrace)", "Null(@)", "~(@)", "Null(JSObject)", "~(Object?)", "JSObject()", "Object?(Object?)", "~(~())", "~(Object,StackTrace)", "bool(Object?)", "String(String)", "Future<~>()", "bool(Object?,Object?)", "int(Object?)", "bool(_Highlight)", "bool(String)", "@()", "int(int)", "~(Object[StackTrace?])", "Null(JavaScriptFunction,JavaScriptFunction)", "~(@,StackTrace)", "bool()", "int(int,int)", "String(Match)", "~(@,@)", "int()", "~(Object?,Object?)", "String(int,int)", "Null(JavaScriptFunction)", "int(@,@)", "MediaType()", "SetMultimapBuilder()", "Null(~())", "~(String,int)", "~(Zone,ZoneDelegate,Zone,Object,StackTrace)", "ListBuilder()", "ListBuilder()", "~(ServiceExtensionResponseBuilder)", "~(String,int?)", "String(@)", "bool(String,String)", "int(String)", "Null(@,StackTrace)", "~(List)", "@(String)", "~(String,String)", "JSObject(Object,StackTrace)", "Logger()", "Object?(~)", "String(String?)", "String?()", "int(_Line)", "~(int,@)", "Object(_Line)", "Object(_Highlight)", "int(_Highlight,_Highlight)", "List<_Line>(MapEntry>)", "int(int,@)", "SourceSpanWithContext()", "IndentingBuiltValueToStringHelper(String)", "~(String?)", "Future()", "ListBuilder()", "Null(WebSocket)", "~(WebSocketEvent)", "Null(Object)", "HotReloadResponse([~(HotReloadResponseBuilder)])", "JSObject(String[bool?])", "~(List)", "ListBuilder(BatchedDebugEventsBuilder)", "Null(String,String)", "DebugEventBuilder(DebugEventBuilder)", "0^(0^,0^)", "RegisterEventBuilder(RegisterEventBuilder)", "DevToolsRequestBuilder(DevToolsRequestBuilder)", "Future<~>(String)", "ConnectRequestBuilder(ConnectRequestBuilder)", "DebugInfoBuilder(DebugInfoBuilder)", "~(bool)", "ListMultimapBuilder()", "bool(bool)", "List(String)", "int(String,String)", "Null(JavaScriptObject)", "JSObject()()", "MapBuilder()", "@(@,String)", "~(Zone?,ZoneDelegate?,Zone,Object,StackTrace)", "0^(Zone?,ZoneDelegate?,Zone,0^())", "0^(Zone?,ZoneDelegate?,Zone,0^(1^),1^)", "0^(Zone?,ZoneDelegate?,Zone,0^(1^,2^),1^,2^)", "0^()(Zone,ZoneDelegate,Zone,0^())", "0^(1^)(Zone,ZoneDelegate,Zone,0^(1^))", "0^(1^,2^)(Zone,ZoneDelegate,Zone,0^(1^,2^))", "AsyncError?(Zone,ZoneDelegate,Zone,Object,StackTrace?)", "~(Zone?,ZoneDelegate?,Zone,~())", "Timer(Zone,ZoneDelegate,Zone,Duration,~())", "Timer(Zone,ZoneDelegate,Zone,Duration,~(Timer))", "~(Zone,ZoneDelegate,Zone,String)", "~(String)", "Zone(Zone?,ZoneDelegate?,Zone,ZoneSpecification?,Map?)", "Null(String)", "SetBuilder()"], interceptorsByTag: null, leafTags: null, arrayRti: Symbol("$ti"), rttc: {} }; - A._Universe_addRules(init.typeUniverse, JSON.parse('{"JavaScriptFunction":"LegacyJavaScriptObject","PlainJavaScriptObject":"LegacyJavaScriptObject","UnknownJavaScriptObject":"LegacyJavaScriptObject","JavaScriptObject":{"JSObject":[]},"JSArray":{"List":["1"],"JavaScriptObject":[],"EfficientLengthIterable":["1"],"JSObject":[],"Iterable":["1"],"JSIndexable":["1"],"Iterable.E":"1"},"JSBool":{"bool":[],"TrustedGetRuntimeType":[]},"JSNull":{"Null":[],"TrustedGetRuntimeType":[]},"LegacyJavaScriptObject":{"JavaScriptObject":[],"JSObject":[]},"JSArraySafeToStringHook":{"SafeToStringHook":[]},"JSUnmodifiableArray":{"JSArray":["1"],"List":["1"],"JavaScriptObject":[],"EfficientLengthIterable":["1"],"JSObject":[],"Iterable":["1"],"JSIndexable":["1"],"Iterable.E":"1"},"ArrayIterator":{"Iterator":["1"]},"JSNumber":{"double":[],"num":[],"Comparable":["num"]},"JSInt":{"double":[],"int":[],"num":[],"Comparable":["num"],"TrustedGetRuntimeType":[]},"JSNumNotInt":{"double":[],"num":[],"Comparable":["num"],"TrustedGetRuntimeType":[]},"JSString":{"String":[],"Comparable":["String"],"Pattern":[],"JSIndexable":["@"],"TrustedGetRuntimeType":[]},"_CastIterableBase":{"Iterable":["2"]},"CastIterator":{"Iterator":["2"]},"CastIterable":{"_CastIterableBase":["1","2"],"Iterable":["2"],"Iterable.E":"2"},"_EfficientLengthCastIterable":{"CastIterable":["1","2"],"_CastIterableBase":["1","2"],"EfficientLengthIterable":["2"],"Iterable":["2"],"Iterable.E":"2"},"_CastListBase":{"ListBase":["2"],"List":["2"],"_CastIterableBase":["1","2"],"EfficientLengthIterable":["2"],"Iterable":["2"]},"CastList":{"_CastListBase":["1","2"],"ListBase":["2"],"List":["2"],"_CastIterableBase":["1","2"],"EfficientLengthIterable":["2"],"Iterable":["2"],"ListBase.E":"2","Iterable.E":"2"},"CastMap":{"MapBase":["3","4"],"Map":["3","4"],"MapBase.K":"3","MapBase.V":"4"},"LateError":{"Error":[]},"CodeUnits":{"ListBase":["int"],"UnmodifiableListMixin":["int"],"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"],"ListBase.E":"int","Iterable.E":"int","UnmodifiableListMixin.E":"int"},"EfficientLengthIterable":{"Iterable":["1"]},"ListIterable":{"EfficientLengthIterable":["1"],"Iterable":["1"]},"SubListIterable":{"ListIterable":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"],"ListIterable.E":"1","Iterable.E":"1"},"ListIterator":{"Iterator":["1"]},"MappedIterable":{"Iterable":["2"],"Iterable.E":"2"},"EfficientLengthMappedIterable":{"MappedIterable":["1","2"],"EfficientLengthIterable":["2"],"Iterable":["2"],"Iterable.E":"2"},"MappedIterator":{"Iterator":["2"]},"MappedListIterable":{"ListIterable":["2"],"EfficientLengthIterable":["2"],"Iterable":["2"],"ListIterable.E":"2","Iterable.E":"2"},"WhereIterable":{"Iterable":["1"],"Iterable.E":"1"},"WhereIterator":{"Iterator":["1"]},"ExpandIterable":{"Iterable":["2"],"Iterable.E":"2"},"ExpandIterator":{"Iterator":["2"]},"TakeIterable":{"Iterable":["1"],"Iterable.E":"1"},"EfficientLengthTakeIterable":{"TakeIterable":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"],"Iterable.E":"1"},"TakeIterator":{"Iterator":["1"]},"SkipIterable":{"Iterable":["1"],"Iterable.E":"1"},"EfficientLengthSkipIterable":{"SkipIterable":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"],"Iterable.E":"1"},"SkipIterator":{"Iterator":["1"]},"EmptyIterable":{"EfficientLengthIterable":["1"],"Iterable":["1"],"Iterable.E":"1"},"EmptyIterator":{"Iterator":["1"]},"WhereTypeIterable":{"Iterable":["1"],"Iterable.E":"1"},"WhereTypeIterator":{"Iterator":["1"]},"UnmodifiableListBase":{"ListBase":["1"],"UnmodifiableListMixin":["1"],"List":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"]},"ReversedListIterable":{"ListIterable":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"],"ListIterable.E":"1","Iterable.E":"1"},"ConstantMap":{"Map":["1","2"]},"ConstantStringMap":{"ConstantMap":["1","2"],"Map":["1","2"]},"_KeysOrValues":{"Iterable":["1"],"Iterable.E":"1"},"_KeysOrValuesOrElementsIterator":{"Iterator":["1"]},"Instantiation":{"Closure":[],"Function":[]},"Instantiation1":{"Closure":[],"Function":[]},"NullError":{"TypeError":[],"Error":[]},"JsNoSuchMethodError":{"Error":[]},"UnknownJsTypeError":{"Error":[]},"NullThrownFromJavaScriptException":{"Exception":[]},"_StackTrace":{"StackTrace":[]},"Closure":{"Function":[]},"Closure0Args":{"Closure":[],"Function":[]},"Closure2Args":{"Closure":[],"Function":[]},"TearOffClosure":{"Closure":[],"Function":[]},"StaticClosure":{"Closure":[],"Function":[]},"BoundClosure":{"Closure":[],"Function":[]},"RuntimeError":{"Error":[]},"JsLinkedHashMap":{"MapBase":["1","2"],"LinkedHashMap":["1","2"],"Map":["1","2"],"MapBase.K":"1","MapBase.V":"2"},"LinkedHashMapKeysIterable":{"EfficientLengthIterable":["1"],"Iterable":["1"],"Iterable.E":"1"},"LinkedHashMapKeyIterator":{"Iterator":["1"]},"LinkedHashMapValuesIterable":{"EfficientLengthIterable":["1"],"Iterable":["1"],"Iterable.E":"1"},"LinkedHashMapValueIterator":{"Iterator":["1"]},"LinkedHashMapEntriesIterable":{"EfficientLengthIterable":["MapEntry<1,2>"],"Iterable":["MapEntry<1,2>"],"Iterable.E":"MapEntry<1,2>"},"LinkedHashMapEntryIterator":{"Iterator":["MapEntry<1,2>"]},"JsIdentityLinkedHashMap":{"JsLinkedHashMap":["1","2"],"MapBase":["1","2"],"LinkedHashMap":["1","2"],"Map":["1","2"],"MapBase.K":"1","MapBase.V":"2"},"JSSyntaxRegExp":{"RegExp":[],"Pattern":[]},"_MatchImplementation":{"RegExpMatch":[],"Match":[]},"_AllMatchesIterable":{"Iterable":["RegExpMatch"],"Iterable.E":"RegExpMatch"},"_AllMatchesIterator":{"Iterator":["RegExpMatch"]},"StringMatch":{"Match":[]},"_StringAllMatchesIterable":{"Iterable":["Match"],"Iterable.E":"Match"},"_StringAllMatchesIterator":{"Iterator":["Match"]},"NativeByteBuffer":{"JavaScriptObject":[],"JSObject":[],"ByteBuffer":[],"TrustedGetRuntimeType":[]},"NativeTypedData":{"JavaScriptObject":[],"JSObject":[]},"NativeByteData":{"JavaScriptObject":[],"ByteData":[],"JSObject":[],"TrustedGetRuntimeType":[]},"NativeTypedArray":{"JavaScriptIndexingBehavior":["1"],"JavaScriptObject":[],"JSObject":[],"JSIndexable":["1"]},"NativeTypedArrayOfDouble":{"ListBase":["double"],"NativeTypedArray":["double"],"List":["double"],"JavaScriptIndexingBehavior":["double"],"JavaScriptObject":[],"EfficientLengthIterable":["double"],"JSObject":[],"JSIndexable":["double"],"Iterable":["double"],"FixedLengthListMixin":["double"]},"NativeTypedArrayOfInt":{"ListBase":["int"],"NativeTypedArray":["int"],"List":["int"],"JavaScriptIndexingBehavior":["int"],"JavaScriptObject":[],"EfficientLengthIterable":["int"],"JSObject":[],"JSIndexable":["int"],"Iterable":["int"],"FixedLengthListMixin":["int"]},"NativeFloat32List":{"Float32List":[],"ListBase":["double"],"NativeTypedArray":["double"],"List":["double"],"JavaScriptIndexingBehavior":["double"],"JavaScriptObject":[],"EfficientLengthIterable":["double"],"JSObject":[],"JSIndexable":["double"],"Iterable":["double"],"FixedLengthListMixin":["double"],"TrustedGetRuntimeType":[],"ListBase.E":"double","Iterable.E":"double","FixedLengthListMixin.E":"double"},"NativeFloat64List":{"Float64List":[],"ListBase":["double"],"NativeTypedArray":["double"],"List":["double"],"JavaScriptIndexingBehavior":["double"],"JavaScriptObject":[],"EfficientLengthIterable":["double"],"JSObject":[],"JSIndexable":["double"],"Iterable":["double"],"FixedLengthListMixin":["double"],"TrustedGetRuntimeType":[],"ListBase.E":"double","Iterable.E":"double","FixedLengthListMixin.E":"double"},"NativeInt16List":{"NativeTypedArrayOfInt":[],"Int16List":[],"ListBase":["int"],"NativeTypedArray":["int"],"List":["int"],"JavaScriptIndexingBehavior":["int"],"JavaScriptObject":[],"EfficientLengthIterable":["int"],"JSObject":[],"JSIndexable":["int"],"Iterable":["int"],"FixedLengthListMixin":["int"],"TrustedGetRuntimeType":[],"ListBase.E":"int","Iterable.E":"int","FixedLengthListMixin.E":"int"},"NativeInt32List":{"NativeTypedArrayOfInt":[],"Int32List":[],"ListBase":["int"],"NativeTypedArray":["int"],"List":["int"],"JavaScriptIndexingBehavior":["int"],"JavaScriptObject":[],"EfficientLengthIterable":["int"],"JSObject":[],"JSIndexable":["int"],"Iterable":["int"],"FixedLengthListMixin":["int"],"TrustedGetRuntimeType":[],"ListBase.E":"int","Iterable.E":"int","FixedLengthListMixin.E":"int"},"NativeInt8List":{"NativeTypedArrayOfInt":[],"Int8List":[],"ListBase":["int"],"NativeTypedArray":["int"],"List":["int"],"JavaScriptIndexingBehavior":["int"],"JavaScriptObject":[],"EfficientLengthIterable":["int"],"JSObject":[],"JSIndexable":["int"],"Iterable":["int"],"FixedLengthListMixin":["int"],"TrustedGetRuntimeType":[],"ListBase.E":"int","Iterable.E":"int","FixedLengthListMixin.E":"int"},"NativeUint16List":{"NativeTypedArrayOfInt":[],"Uint16List":[],"ListBase":["int"],"NativeTypedArray":["int"],"List":["int"],"JavaScriptIndexingBehavior":["int"],"JavaScriptObject":[],"EfficientLengthIterable":["int"],"JSObject":[],"JSIndexable":["int"],"Iterable":["int"],"FixedLengthListMixin":["int"],"TrustedGetRuntimeType":[],"ListBase.E":"int","Iterable.E":"int","FixedLengthListMixin.E":"int"},"NativeUint32List":{"NativeTypedArrayOfInt":[],"Uint32List":[],"ListBase":["int"],"NativeTypedArray":["int"],"List":["int"],"JavaScriptIndexingBehavior":["int"],"JavaScriptObject":[],"EfficientLengthIterable":["int"],"JSObject":[],"JSIndexable":["int"],"Iterable":["int"],"FixedLengthListMixin":["int"],"TrustedGetRuntimeType":[],"ListBase.E":"int","Iterable.E":"int","FixedLengthListMixin.E":"int"},"NativeUint8ClampedList":{"NativeTypedArrayOfInt":[],"Uint8ClampedList":[],"ListBase":["int"],"NativeTypedArray":["int"],"List":["int"],"JavaScriptIndexingBehavior":["int"],"JavaScriptObject":[],"EfficientLengthIterable":["int"],"JSObject":[],"JSIndexable":["int"],"Iterable":["int"],"FixedLengthListMixin":["int"],"TrustedGetRuntimeType":[],"ListBase.E":"int","Iterable.E":"int","FixedLengthListMixin.E":"int"},"NativeUint8List":{"NativeTypedArrayOfInt":[],"Uint8List":[],"ListBase":["int"],"NativeTypedArray":["int"],"List":["int"],"JavaScriptIndexingBehavior":["int"],"JavaScriptObject":[],"EfficientLengthIterable":["int"],"JSObject":[],"JSIndexable":["int"],"Iterable":["int"],"FixedLengthListMixin":["int"],"TrustedGetRuntimeType":[],"ListBase.E":"int","Iterable.E":"int","FixedLengthListMixin.E":"int"},"_Type":{"Type":[]},"_Error":{"Error":[]},"_TypeError":{"TypeError":[],"Error":[]},"AsyncError":{"Error":[]},"_TimerImpl":{"Timer":[]},"_AsyncAwaitCompleter":{"Completer":["1"]},"_Completer":{"Completer":["1"]},"_AsyncCompleter":{"_Completer":["1"],"Completer":["1"]},"_SyncCompleter":{"_Completer":["1"],"Completer":["1"]},"_Future":{"Future":["1"]},"StreamView":{"Stream":["1"]},"_StreamController":{"StreamController":["1"],"StreamSink":["1"],"_StreamControllerLifecycle":["1"],"_EventSink":["1"],"_EventDispatch":["1"]},"_AsyncStreamController":{"_AsyncStreamControllerDispatch":["1"],"_StreamController":["1"],"StreamController":["1"],"StreamSink":["1"],"_StreamControllerLifecycle":["1"],"_EventSink":["1"],"_EventDispatch":["1"]},"_SyncStreamController":{"_SyncStreamControllerDispatch":["1"],"_StreamController":["1"],"StreamController":["1"],"StreamSink":["1"],"_StreamControllerLifecycle":["1"],"_EventSink":["1"],"_EventDispatch":["1"]},"_ControllerStream":{"_StreamImpl":["1"],"Stream":["1"],"Stream.T":"1"},"_ControllerSubscription":{"_BufferingStreamSubscription":["1"],"StreamSubscription":["1"],"_EventSink":["1"],"_EventDispatch":["1"],"_BufferingStreamSubscription.T":"1"},"_StreamSinkWrapper":{"StreamSink":["1"]},"_BufferingStreamSubscription":{"StreamSubscription":["1"],"_EventSink":["1"],"_EventDispatch":["1"],"_BufferingStreamSubscription.T":"1"},"_StreamImpl":{"Stream":["1"]},"_DelayedData":{"_DelayedEvent":["1"]},"_DelayedError":{"_DelayedEvent":["@"]},"_DelayedDone":{"_DelayedEvent":["@"]},"_DoneStreamSubscription":{"StreamSubscription":["1"]},"_EmptyStream":{"Stream":["1"],"Stream.T":"1"},"_ForwardingStream":{"Stream":["2"]},"_ForwardingStreamSubscription":{"_BufferingStreamSubscription":["2"],"StreamSubscription":["2"],"_EventSink":["2"],"_EventDispatch":["2"],"_BufferingStreamSubscription.T":"2"},"_MapStream":{"_ForwardingStream":["1","2"],"Stream":["2"],"Stream.T":"2"},"_ZoneSpecification":{"ZoneSpecification":[]},"_ZoneDelegate":{"ZoneDelegate":[]},"_Zone":{"Zone":[]},"_CustomZone":{"_Zone":[],"Zone":[]},"_RootZone":{"_Zone":[],"Zone":[]},"_SplayTreeSetNode":{"_SplayTreeNode":["1","_SplayTreeSetNode<1>"],"_SplayTreeNode.K":"1","_SplayTreeNode.1":"_SplayTreeSetNode<1>"},"_HashMap":{"MapBase":["1","2"],"HashMap":["1","2"],"Map":["1","2"],"MapBase.K":"1","MapBase.V":"2"},"_IdentityHashMap":{"_HashMap":["1","2"],"MapBase":["1","2"],"HashMap":["1","2"],"Map":["1","2"],"MapBase.K":"1","MapBase.V":"2"},"_CustomHashMap":{"_HashMap":["1","2"],"MapBase":["1","2"],"HashMap":["1","2"],"Map":["1","2"],"MapBase.K":"1","MapBase.V":"2"},"_HashMapKeyIterable":{"EfficientLengthIterable":["1"],"Iterable":["1"],"Iterable.E":"1"},"_HashMapKeyIterator":{"Iterator":["1"]},"_LinkedCustomHashMap":{"JsLinkedHashMap":["1","2"],"MapBase":["1","2"],"LinkedHashMap":["1","2"],"Map":["1","2"],"MapBase.K":"1","MapBase.V":"2"},"_HashSet":{"_SetBase":["1"],"SetBase":["1"],"Set":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"],"Iterable.E":"1"},"_HashSetIterator":{"Iterator":["1"]},"_LinkedHashSet":{"_SetBase":["1"],"SetBase":["1"],"Set":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"],"Iterable.E":"1"},"_LinkedHashSetIterator":{"Iterator":["1"]},"UnmodifiableListView":{"ListBase":["1"],"UnmodifiableListMixin":["1"],"List":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"],"ListBase.E":"1","Iterable.E":"1","UnmodifiableListMixin.E":"1"},"ListBase":{"List":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"]},"MapBase":{"Map":["1","2"]},"MapView":{"Map":["1","2"]},"UnmodifiableMapView":{"_UnmodifiableMapView_MapView__UnmodifiableMapMixin":["1","2"],"MapView":["1","2"],"_UnmodifiableMapMixin":["1","2"],"Map":["1","2"]},"ListQueue":{"Queue":["1"],"ListIterable":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"],"ListIterable.E":"1","Iterable.E":"1"},"_ListQueueIterator":{"Iterator":["1"]},"SetBase":{"Set":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"]},"_SetBase":{"SetBase":["1"],"Set":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"]},"_SplayTreeIterator":{"Iterator":["3"]},"_SplayTreeKeyIterator":{"_SplayTreeIterator":["1","2","1"],"Iterator":["1"],"_SplayTreeIterator.K":"1","_SplayTreeIterator.T":"1","_SplayTreeIterator.1":"2"},"SplayTreeSet":{"SetBase":["1"],"Set":["1"],"EfficientLengthIterable":["1"],"_SplayTree":["1","_SplayTreeSetNode<1>"],"Iterable":["1"],"Iterable.E":"1","_SplayTree.1":"_SplayTreeSetNode<1>","_SplayTree.K":"1"},"Encoding":{"Codec":["String","List"]},"_JsonMap":{"MapBase":["String","@"],"Map":["String","@"],"MapBase.K":"String","MapBase.V":"@"},"_JsonMapKeyIterable":{"ListIterable":["String"],"EfficientLengthIterable":["String"],"Iterable":["String"],"ListIterable.E":"String","Iterable.E":"String"},"AsciiCodec":{"Encoding":[],"Codec":["String","List"],"Codec.S":"String"},"_UnicodeSubsetEncoder":{"Converter":["String","List"],"StreamTransformer":["String","List"]},"AsciiEncoder":{"Converter":["String","List"],"StreamTransformer":["String","List"]},"_UnicodeSubsetDecoder":{"Converter":["List","String"],"StreamTransformer":["List","String"]},"AsciiDecoder":{"Converter":["List","String"],"StreamTransformer":["List","String"]},"Base64Codec":{"Codec":["List","String"],"Codec.S":"List"},"Base64Encoder":{"Converter":["List","String"],"StreamTransformer":["List","String"]},"Base64Decoder":{"Converter":["String","List"],"StreamTransformer":["String","List"]},"Converter":{"StreamTransformer":["1","2"]},"JsonUnsupportedObjectError":{"Error":[]},"JsonCyclicError":{"Error":[]},"JsonCodec":{"Codec":["Object?","String"],"Codec.S":"Object?"},"JsonEncoder":{"Converter":["Object?","String"],"StreamTransformer":["Object?","String"]},"JsonDecoder":{"Converter":["String","Object?"],"StreamTransformer":["String","Object?"]},"Latin1Codec":{"Encoding":[],"Codec":["String","List"],"Codec.S":"String"},"Latin1Encoder":{"Converter":["String","List"],"StreamTransformer":["String","List"]},"Latin1Decoder":{"Converter":["List","String"],"StreamTransformer":["List","String"]},"Utf8Codec":{"Encoding":[],"Codec":["String","List"],"Codec.S":"String"},"Utf8Encoder":{"Converter":["String","List"],"StreamTransformer":["String","List"]},"Utf8Decoder":{"Converter":["List","String"],"StreamTransformer":["List","String"]},"BigInt":{"Comparable":["BigInt"]},"DateTime":{"Comparable":["DateTime"]},"double":{"num":[],"Comparable":["num"]},"Duration":{"Comparable":["Duration"]},"int":{"num":[],"Comparable":["num"]},"List":{"EfficientLengthIterable":["1"],"Iterable":["1"]},"num":{"Comparable":["num"]},"RegExp":{"Pattern":[]},"RegExpMatch":{"Match":[]},"Set":{"EfficientLengthIterable":["1"],"Iterable":["1"]},"String":{"Comparable":["String"],"Pattern":[]},"_BigIntImpl":{"BigInt":[],"Comparable":["BigInt"]},"AssertionError":{"Error":[]},"TypeError":{"Error":[]},"ArgumentError":{"Error":[]},"RangeError":{"Error":[]},"IndexError":{"Error":[]},"UnsupportedError":{"Error":[]},"UnimplementedError":{"Error":[]},"StateError":{"Error":[]},"ConcurrentModificationError":{"Error":[]},"OutOfMemoryError":{"Error":[]},"StackOverflowError":{"Error":[]},"_Exception":{"Exception":[]},"FormatException":{"Exception":[]},"IntegerDivisionByZeroException":{"Exception":[],"Error":[]},"_StringStackTrace":{"StackTrace":[]},"StringBuffer":{"StringSink":[]},"_Uri":{"Uri":[]},"_SimpleUri":{"Uri":[]},"_DataUri":{"Uri":[]},"NullRejectionException":{"Exception":[]},"_JSRandom":{"Random":[]},"DelegatingStreamSink":{"StreamSink":["1"]},"ErrorResult":{"Result":["0&"]},"ValueResult":{"Result":["1"]},"_NextRequest":{"_EventRequest":["1"]},"_HasNextRequest":{"_EventRequest":["1"]},"BuiltList":{"Iterable":["1"]},"_BuiltList":{"BuiltList":["1"],"Iterable":["1"],"Iterable.E":"1"},"_BuiltListMultimap":{"BuiltListMultimap":["1","2"]},"_BuiltMap":{"BuiltMap":["1","2"]},"BuiltSet":{"Iterable":["1"]},"_BuiltSet":{"BuiltSet":["1"],"Iterable":["1"],"Iterable.E":"1"},"_BuiltSetMultimap":{"BuiltSetMultimap":["1","2"]},"BuiltValueNullFieldError":{"Error":[]},"BuiltValueNestedFieldError":{"Error":[]},"BoolJsonObject":{"JsonObject":[]},"ListJsonObject":{"JsonObject":[]},"MapJsonObject":{"JsonObject":[]},"NumJsonObject":{"JsonObject":[]},"StringJsonObject":{"JsonObject":[]},"DeserializationError":{"Error":[]},"BigIntSerializer":{"PrimitiveSerializer":["BigInt"],"Serializer":["BigInt"]},"BoolSerializer":{"PrimitiveSerializer":["bool"],"Serializer":["bool"]},"BuiltJsonSerializers":{"Serializers":[]},"BuiltListMultimapSerializer":{"StructuredSerializer":["BuiltListMultimap<@,@>"],"Serializer":["BuiltListMultimap<@,@>"]},"BuiltListSerializer":{"StructuredSerializer":["BuiltList<@>"],"Serializer":["BuiltList<@>"]},"BuiltMapSerializer":{"StructuredSerializer":["BuiltMap<@,@>"],"Serializer":["BuiltMap<@,@>"]},"BuiltSetMultimapSerializer":{"StructuredSerializer":["BuiltSetMultimap<@,@>"],"Serializer":["BuiltSetMultimap<@,@>"]},"BuiltSetSerializer":{"StructuredSerializer":["BuiltSet<@>"],"Serializer":["BuiltSet<@>"]},"DateTimeSerializer":{"PrimitiveSerializer":["DateTime"],"Serializer":["DateTime"]},"DoubleSerializer":{"PrimitiveSerializer":["double"],"Serializer":["double"]},"DurationSerializer":{"PrimitiveSerializer":["Duration"],"Serializer":["Duration"]},"Int32Serializer":{"PrimitiveSerializer":["Int32"],"Serializer":["Int32"]},"Int64Serializer":{"PrimitiveSerializer":["Int64"],"Serializer":["Int64"]},"IntSerializer":{"PrimitiveSerializer":["int"],"Serializer":["int"]},"JsonObjectSerializer":{"PrimitiveSerializer":["JsonObject"],"Serializer":["JsonObject"]},"ListSerializer":{"StructuredSerializer":["List<@>"],"Serializer":["List<@>"]},"MapSerializer":{"StructuredSerializer":["Map<@,@>"],"Serializer":["Map<@,@>"]},"NullSerializer":{"PrimitiveSerializer":["Null"],"Serializer":["Null"]},"NumSerializer":{"PrimitiveSerializer":["num"],"Serializer":["num"]},"RegExpSerializer":{"PrimitiveSerializer":["RegExp"],"Serializer":["RegExp"]},"SetSerializer":{"StructuredSerializer":["Set<@>"],"Serializer":["Set<@>"]},"StringSerializer":{"PrimitiveSerializer":["String"],"Serializer":["String"]},"Uint8ListSerializer":{"PrimitiveSerializer":["Uint8List"],"Serializer":["Uint8List"]},"UriSerializer":{"PrimitiveSerializer":["Uri"],"Serializer":["Uri"]},"CanonicalizedMap":{"Map":["2","3"]},"DefaultEquality":{"Equality":["1"]},"IterableEquality":{"Equality":["Iterable<1>"]},"ListEquality":{"Equality":["List<1>"]},"_UnorderedEquality":{"Equality":["2"]},"SetEquality":{"_UnorderedEquality":["1","Set<1>"],"Equality":["Set<1>"],"_UnorderedEquality.E":"1","_UnorderedEquality.T":"Set<1>"},"MapEquality":{"Equality":["Map<1,2>"]},"DeepCollectionEquality":{"Equality":["@"]},"QueueList":{"ListBase":["1"],"List":["1"],"Queue":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"],"ListBase.E":"1","QueueList.E":"1","Iterable.E":"1"},"_CastQueueList":{"QueueList":["2"],"ListBase":["2"],"List":["2"],"Queue":["2"],"EfficientLengthIterable":["2"],"Iterable":["2"],"ListBase.E":"2","QueueList.E":"2","Iterable.E":"2"},"_$BuildStatusSerializer":{"PrimitiveSerializer":["BuildStatus"],"Serializer":["BuildStatus"]},"_$BuildResultSerializer":{"StructuredSerializer":["BuildResult"],"Serializer":["BuildResult"]},"_$BuildResult":{"BuildResult":[]},"_$ConnectRequestSerializer":{"StructuredSerializer":["ConnectRequest"],"Serializer":["ConnectRequest"]},"_$ConnectRequest":{"ConnectRequest":[]},"_$DebugEventSerializer":{"StructuredSerializer":["DebugEvent"],"Serializer":["DebugEvent"]},"_$BatchedDebugEventsSerializer":{"StructuredSerializer":["BatchedDebugEvents"],"Serializer":["BatchedDebugEvents"]},"_$DebugEvent":{"DebugEvent":[]},"_$BatchedDebugEvents":{"BatchedDebugEvents":[]},"_$DebugInfoSerializer":{"StructuredSerializer":["DebugInfo"],"Serializer":["DebugInfo"]},"_$DebugInfo":{"DebugInfo":[]},"_$DevToolsRequestSerializer":{"StructuredSerializer":["DevToolsRequest"],"Serializer":["DevToolsRequest"]},"_$DevToolsResponseSerializer":{"StructuredSerializer":["DevToolsResponse"],"Serializer":["DevToolsResponse"]},"_$DevToolsRequest":{"DevToolsRequest":[]},"_$DevToolsResponse":{"DevToolsResponse":[]},"_$ErrorResponseSerializer":{"StructuredSerializer":["ErrorResponse"],"Serializer":["ErrorResponse"]},"_$ErrorResponse":{"ErrorResponse":[]},"_$ExtensionRequestSerializer":{"StructuredSerializer":["ExtensionRequest"],"Serializer":["ExtensionRequest"]},"_$ExtensionResponseSerializer":{"StructuredSerializer":["ExtensionResponse"],"Serializer":["ExtensionResponse"]},"_$ExtensionEventSerializer":{"StructuredSerializer":["ExtensionEvent"],"Serializer":["ExtensionEvent"]},"_$BatchedEventsSerializer":{"StructuredSerializer":["BatchedEvents"],"Serializer":["BatchedEvents"]},"_$ExtensionRequest":{"ExtensionRequest":[]},"_$ExtensionResponse":{"ExtensionResponse":[]},"_$ExtensionEvent":{"ExtensionEvent":[]},"_$BatchedEvents":{"BatchedEvents":[]},"_$HotReloadRequestSerializer":{"StructuredSerializer":["HotReloadRequest"],"Serializer":["HotReloadRequest"]},"_$HotReloadRequest":{"HotReloadRequest":[]},"_$HotReloadResponseSerializer":{"StructuredSerializer":["HotReloadResponse"],"Serializer":["HotReloadResponse"]},"_$HotReloadResponse":{"HotReloadResponse":[]},"_$IsolateExitSerializer":{"StructuredSerializer":["IsolateExit"],"Serializer":["IsolateExit"]},"_$IsolateStartSerializer":{"StructuredSerializer":["IsolateStart"],"Serializer":["IsolateStart"]},"_$IsolateExit":{"IsolateExit":[]},"_$IsolateStart":{"IsolateStart":[]},"_$RegisterEventSerializer":{"StructuredSerializer":["RegisterEvent"],"Serializer":["RegisterEvent"]},"_$RegisterEvent":{"RegisterEvent":[]},"_$RunRequestSerializer":{"StructuredSerializer":["RunRequest"],"Serializer":["RunRequest"]},"_$RunRequest":{"RunRequest":[]},"SseSocketClient":{"SocketClient":[]},"WebSocketClient":{"SocketClient":[]},"Int32":{"Comparable":["Object"]},"Int64":{"Comparable":["Object"]},"ByteStream":{"StreamView":["List"],"Stream":["List"],"Stream.T":"List","StreamView.T":"List"},"ClientException":{"Exception":[]},"Request":{"BaseRequest":[]},"StreamedResponseV2":{"StreamedResponse":[]},"CaseInsensitiveMap":{"CanonicalizedMap":["String","String","1"],"Map":["String","1"],"CanonicalizedMap.K":"String","CanonicalizedMap.V":"1","CanonicalizedMap.C":"String"},"Level":{"Comparable":["Level"]},"PathException":{"Exception":[]},"PosixStyle":{"InternalStyle":[]},"UrlStyle":{"InternalStyle":[]},"WindowsStyle":{"InternalStyle":[]},"FileLocation":{"SourceLocation":[],"Comparable":["SourceLocation"]},"_FileSpan":{"SourceSpanWithContext":[],"SourceSpan":[],"Comparable":["SourceSpan"]},"SourceLocation":{"Comparable":["SourceLocation"]},"SourceLocationMixin":{"SourceLocation":[],"Comparable":["SourceLocation"]},"SourceSpan":{"Comparable":["SourceSpan"]},"SourceSpanBase":{"SourceSpan":[],"Comparable":["SourceSpan"]},"SourceSpanException":{"Exception":[]},"SourceSpanFormatException":{"FormatException":[],"Exception":[]},"SourceSpanMixin":{"SourceSpan":[],"Comparable":["SourceSpan"]},"SourceSpanWithContext":{"SourceSpan":[],"Comparable":["SourceSpan"]},"SseClient":{"StreamChannel":["String?"]},"GuaranteeChannel":{"StreamChannel":["1"]},"_GuaranteeSink":{"StreamSink":["1"]},"StreamChannelMixin":{"StreamChannel":["1"]},"StringScannerException":{"FormatException":[],"Exception":[]},"_EventStream":{"Stream":["1"],"Stream.T":"1"},"_EventStreamSubscription":{"StreamSubscription":["1"]},"BrowserWebSocket":{"WebSocket":[]},"TextDataReceived":{"WebSocketEvent":[]},"BinaryDataReceived":{"WebSocketEvent":[]},"CloseReceived":{"WebSocketEvent":[]},"WebSocketException":{"Exception":[]},"WebSocketConnectionClosed":{"Exception":[]},"AdapterWebSocketChannel":{"WebSocketChannel":[],"StreamChannel":["@"]},"_WebSocketSink":{"WebSocketSink":[],"DelegatingStreamSink":["@"],"StreamSink":["@"],"DelegatingStreamSink.T":"@"},"WebSocketChannelException":{"Exception":[]},"DdcLibraryBundleRestarter":{"Restarter":[]},"DdcRestarter":{"Restarter":[]},"RequireRestarter":{"Restarter":[]},"HotReloadFailedException":{"Exception":[]},"Int8List":{"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"]},"Uint8List":{"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"]},"Uint8ClampedList":{"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"]},"Int16List":{"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"]},"Uint16List":{"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"]},"Int32List":{"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"]},"Uint32List":{"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"]},"Float32List":{"List":["double"],"EfficientLengthIterable":["double"],"Iterable":["double"]},"Float64List":{"List":["double"],"EfficientLengthIterable":["double"],"Iterable":["double"]}}')); + A._Universe_addRules(init.typeUniverse, JSON.parse('{"JavaScriptFunction":"LegacyJavaScriptObject","PlainJavaScriptObject":"LegacyJavaScriptObject","UnknownJavaScriptObject":"LegacyJavaScriptObject","JavaScriptObject":{"JSObject":[]},"JSArray":{"List":["1"],"JavaScriptObject":[],"EfficientLengthIterable":["1"],"JSObject":[],"Iterable":["1"],"JSIndexable":["1"],"Iterable.E":"1"},"JSBool":{"bool":[],"TrustedGetRuntimeType":[]},"JSNull":{"Null":[],"TrustedGetRuntimeType":[]},"LegacyJavaScriptObject":{"JavaScriptObject":[],"JSObject":[]},"JSUnmodifiableArray":{"JSArray":["1"],"List":["1"],"JavaScriptObject":[],"EfficientLengthIterable":["1"],"JSObject":[],"Iterable":["1"],"JSIndexable":["1"],"Iterable.E":"1"},"ArrayIterator":{"Iterator":["1"]},"JSNumber":{"double":[],"num":[],"Comparable":["num"]},"JSInt":{"double":[],"int":[],"num":[],"Comparable":["num"],"TrustedGetRuntimeType":[]},"JSNumNotInt":{"double":[],"num":[],"Comparable":["num"],"TrustedGetRuntimeType":[]},"JSString":{"String":[],"Comparable":["String"],"Pattern":[],"JSIndexable":["@"],"TrustedGetRuntimeType":[]},"_CastIterableBase":{"Iterable":["2"]},"CastIterator":{"Iterator":["2"]},"CastIterable":{"_CastIterableBase":["1","2"],"Iterable":["2"],"Iterable.E":"2"},"_EfficientLengthCastIterable":{"CastIterable":["1","2"],"_CastIterableBase":["1","2"],"EfficientLengthIterable":["2"],"Iterable":["2"],"Iterable.E":"2"},"_CastListBase":{"ListBase":["2"],"List":["2"],"_CastIterableBase":["1","2"],"EfficientLengthIterable":["2"],"Iterable":["2"]},"CastList":{"_CastListBase":["1","2"],"ListBase":["2"],"List":["2"],"_CastIterableBase":["1","2"],"EfficientLengthIterable":["2"],"Iterable":["2"],"ListBase.E":"2","Iterable.E":"2"},"CastMap":{"MapBase":["3","4"],"Map":["3","4"],"MapBase.K":"3","MapBase.V":"4"},"LateError":{"Error":[]},"CodeUnits":{"ListBase":["int"],"UnmodifiableListMixin":["int"],"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"],"ListBase.E":"int","Iterable.E":"int","UnmodifiableListMixin.E":"int"},"EfficientLengthIterable":{"Iterable":["1"]},"ListIterable":{"EfficientLengthIterable":["1"],"Iterable":["1"]},"SubListIterable":{"ListIterable":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"],"ListIterable.E":"1","Iterable.E":"1"},"ListIterator":{"Iterator":["1"]},"MappedIterable":{"Iterable":["2"],"Iterable.E":"2"},"EfficientLengthMappedIterable":{"MappedIterable":["1","2"],"EfficientLengthIterable":["2"],"Iterable":["2"],"Iterable.E":"2"},"MappedIterator":{"Iterator":["2"]},"MappedListIterable":{"ListIterable":["2"],"EfficientLengthIterable":["2"],"Iterable":["2"],"ListIterable.E":"2","Iterable.E":"2"},"WhereIterable":{"Iterable":["1"],"Iterable.E":"1"},"WhereIterator":{"Iterator":["1"]},"ExpandIterable":{"Iterable":["2"],"Iterable.E":"2"},"ExpandIterator":{"Iterator":["2"]},"TakeIterable":{"Iterable":["1"],"Iterable.E":"1"},"EfficientLengthTakeIterable":{"TakeIterable":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"],"Iterable.E":"1"},"TakeIterator":{"Iterator":["1"]},"SkipIterable":{"Iterable":["1"],"Iterable.E":"1"},"EfficientLengthSkipIterable":{"SkipIterable":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"],"Iterable.E":"1"},"SkipIterator":{"Iterator":["1"]},"EmptyIterable":{"EfficientLengthIterable":["1"],"Iterable":["1"],"Iterable.E":"1"},"EmptyIterator":{"Iterator":["1"]},"WhereTypeIterable":{"Iterable":["1"],"Iterable.E":"1"},"WhereTypeIterator":{"Iterator":["1"]},"UnmodifiableListBase":{"ListBase":["1"],"UnmodifiableListMixin":["1"],"List":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"]},"ReversedListIterable":{"ListIterable":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"],"ListIterable.E":"1","Iterable.E":"1"},"ConstantMap":{"Map":["1","2"]},"ConstantStringMap":{"ConstantMap":["1","2"],"Map":["1","2"]},"_KeysOrValues":{"Iterable":["1"],"Iterable.E":"1"},"_KeysOrValuesOrElementsIterator":{"Iterator":["1"]},"Instantiation":{"Closure":[],"Function":[]},"Instantiation1":{"Closure":[],"Function":[]},"NullError":{"TypeError":[],"Error":[]},"JsNoSuchMethodError":{"Error":[]},"UnknownJsTypeError":{"Error":[]},"NullThrownFromJavaScriptException":{"Exception":[]},"_StackTrace":{"StackTrace":[]},"Closure":{"Function":[]},"Closure0Args":{"Closure":[],"Function":[]},"Closure2Args":{"Closure":[],"Function":[]},"TearOffClosure":{"Closure":[],"Function":[]},"StaticClosure":{"Closure":[],"Function":[]},"BoundClosure":{"Closure":[],"Function":[]},"RuntimeError":{"Error":[]},"JsLinkedHashMap":{"MapBase":["1","2"],"LinkedHashMap":["1","2"],"Map":["1","2"],"MapBase.K":"1","MapBase.V":"2"},"LinkedHashMapKeysIterable":{"EfficientLengthIterable":["1"],"Iterable":["1"],"Iterable.E":"1"},"LinkedHashMapKeyIterator":{"Iterator":["1"]},"LinkedHashMapValuesIterable":{"EfficientLengthIterable":["1"],"Iterable":["1"],"Iterable.E":"1"},"LinkedHashMapValueIterator":{"Iterator":["1"]},"LinkedHashMapEntriesIterable":{"EfficientLengthIterable":["MapEntry<1,2>"],"Iterable":["MapEntry<1,2>"],"Iterable.E":"MapEntry<1,2>"},"LinkedHashMapEntryIterator":{"Iterator":["MapEntry<1,2>"]},"JsIdentityLinkedHashMap":{"JsLinkedHashMap":["1","2"],"MapBase":["1","2"],"LinkedHashMap":["1","2"],"Map":["1","2"],"MapBase.K":"1","MapBase.V":"2"},"JSSyntaxRegExp":{"RegExp":[],"Pattern":[]},"_MatchImplementation":{"RegExpMatch":[],"Match":[]},"_AllMatchesIterable":{"Iterable":["RegExpMatch"],"Iterable.E":"RegExpMatch"},"_AllMatchesIterator":{"Iterator":["RegExpMatch"]},"StringMatch":{"Match":[]},"_StringAllMatchesIterable":{"Iterable":["Match"],"Iterable.E":"Match"},"_StringAllMatchesIterator":{"Iterator":["Match"]},"NativeByteBuffer":{"JavaScriptObject":[],"JSObject":[],"ByteBuffer":[],"TrustedGetRuntimeType":[]},"NativeTypedData":{"JavaScriptObject":[],"JSObject":[]},"_UnmodifiableNativeByteBufferView":{"ByteBuffer":[]},"NativeByteData":{"JavaScriptObject":[],"ByteData":[],"JSObject":[],"TrustedGetRuntimeType":[]},"NativeTypedArray":{"JavaScriptIndexingBehavior":["1"],"JavaScriptObject":[],"JSObject":[],"JSIndexable":["1"]},"NativeTypedArrayOfDouble":{"ListBase":["double"],"NativeTypedArray":["double"],"List":["double"],"JavaScriptIndexingBehavior":["double"],"JavaScriptObject":[],"EfficientLengthIterable":["double"],"JSObject":[],"JSIndexable":["double"],"Iterable":["double"],"FixedLengthListMixin":["double"]},"NativeTypedArrayOfInt":{"ListBase":["int"],"NativeTypedArray":["int"],"List":["int"],"JavaScriptIndexingBehavior":["int"],"JavaScriptObject":[],"EfficientLengthIterable":["int"],"JSObject":[],"JSIndexable":["int"],"Iterable":["int"],"FixedLengthListMixin":["int"]},"NativeFloat32List":{"Float32List":[],"ListBase":["double"],"NativeTypedArray":["double"],"List":["double"],"JavaScriptIndexingBehavior":["double"],"JavaScriptObject":[],"EfficientLengthIterable":["double"],"JSObject":[],"JSIndexable":["double"],"Iterable":["double"],"FixedLengthListMixin":["double"],"TrustedGetRuntimeType":[],"ListBase.E":"double","Iterable.E":"double","FixedLengthListMixin.E":"double"},"NativeFloat64List":{"Float64List":[],"ListBase":["double"],"NativeTypedArray":["double"],"List":["double"],"JavaScriptIndexingBehavior":["double"],"JavaScriptObject":[],"EfficientLengthIterable":["double"],"JSObject":[],"JSIndexable":["double"],"Iterable":["double"],"FixedLengthListMixin":["double"],"TrustedGetRuntimeType":[],"ListBase.E":"double","Iterable.E":"double","FixedLengthListMixin.E":"double"},"NativeInt16List":{"NativeTypedArrayOfInt":[],"Int16List":[],"ListBase":["int"],"NativeTypedArray":["int"],"List":["int"],"JavaScriptIndexingBehavior":["int"],"JavaScriptObject":[],"EfficientLengthIterable":["int"],"JSObject":[],"JSIndexable":["int"],"Iterable":["int"],"FixedLengthListMixin":["int"],"TrustedGetRuntimeType":[],"ListBase.E":"int","Iterable.E":"int","FixedLengthListMixin.E":"int"},"NativeInt32List":{"NativeTypedArrayOfInt":[],"Int32List":[],"ListBase":["int"],"NativeTypedArray":["int"],"List":["int"],"JavaScriptIndexingBehavior":["int"],"JavaScriptObject":[],"EfficientLengthIterable":["int"],"JSObject":[],"JSIndexable":["int"],"Iterable":["int"],"FixedLengthListMixin":["int"],"TrustedGetRuntimeType":[],"ListBase.E":"int","Iterable.E":"int","FixedLengthListMixin.E":"int"},"NativeInt8List":{"NativeTypedArrayOfInt":[],"Int8List":[],"ListBase":["int"],"NativeTypedArray":["int"],"List":["int"],"JavaScriptIndexingBehavior":["int"],"JavaScriptObject":[],"EfficientLengthIterable":["int"],"JSObject":[],"JSIndexable":["int"],"Iterable":["int"],"FixedLengthListMixin":["int"],"TrustedGetRuntimeType":[],"ListBase.E":"int","Iterable.E":"int","FixedLengthListMixin.E":"int"},"NativeUint16List":{"NativeTypedArrayOfInt":[],"Uint16List":[],"ListBase":["int"],"NativeTypedArray":["int"],"List":["int"],"JavaScriptIndexingBehavior":["int"],"JavaScriptObject":[],"EfficientLengthIterable":["int"],"JSObject":[],"JSIndexable":["int"],"Iterable":["int"],"FixedLengthListMixin":["int"],"TrustedGetRuntimeType":[],"ListBase.E":"int","Iterable.E":"int","FixedLengthListMixin.E":"int"},"NativeUint32List":{"NativeTypedArrayOfInt":[],"Uint32List":[],"ListBase":["int"],"NativeTypedArray":["int"],"List":["int"],"JavaScriptIndexingBehavior":["int"],"JavaScriptObject":[],"EfficientLengthIterable":["int"],"JSObject":[],"JSIndexable":["int"],"Iterable":["int"],"FixedLengthListMixin":["int"],"TrustedGetRuntimeType":[],"ListBase.E":"int","Iterable.E":"int","FixedLengthListMixin.E":"int"},"NativeUint8ClampedList":{"NativeTypedArrayOfInt":[],"Uint8ClampedList":[],"ListBase":["int"],"NativeTypedArray":["int"],"List":["int"],"JavaScriptIndexingBehavior":["int"],"JavaScriptObject":[],"EfficientLengthIterable":["int"],"JSObject":[],"JSIndexable":["int"],"Iterable":["int"],"FixedLengthListMixin":["int"],"TrustedGetRuntimeType":[],"ListBase.E":"int","Iterable.E":"int","FixedLengthListMixin.E":"int"},"NativeUint8List":{"NativeTypedArrayOfInt":[],"Uint8List":[],"ListBase":["int"],"NativeTypedArray":["int"],"List":["int"],"JavaScriptIndexingBehavior":["int"],"JavaScriptObject":[],"EfficientLengthIterable":["int"],"JSObject":[],"JSIndexable":["int"],"Iterable":["int"],"FixedLengthListMixin":["int"],"TrustedGetRuntimeType":[],"ListBase.E":"int","Iterable.E":"int","FixedLengthListMixin.E":"int"},"_Type":{"Type":[]},"_Error":{"Error":[]},"_TypeError":{"TypeError":[],"Error":[]},"AsyncError":{"Error":[]},"_TimerImpl":{"Timer":[]},"_AsyncAwaitCompleter":{"Completer":["1"]},"_Completer":{"Completer":["1"]},"_AsyncCompleter":{"_Completer":["1"],"Completer":["1"]},"_SyncCompleter":{"_Completer":["1"],"Completer":["1"]},"_Future":{"Future":["1"]},"StreamView":{"Stream":["1"]},"_StreamController":{"StreamController":["1"],"StreamSink":["1"],"_StreamControllerLifecycle":["1"],"_EventSink":["1"],"_EventDispatch":["1"]},"_AsyncStreamController":{"_AsyncStreamControllerDispatch":["1"],"_StreamController":["1"],"StreamController":["1"],"StreamSink":["1"],"_StreamControllerLifecycle":["1"],"_EventSink":["1"],"_EventDispatch":["1"]},"_SyncStreamController":{"_SyncStreamControllerDispatch":["1"],"_StreamController":["1"],"StreamController":["1"],"StreamSink":["1"],"_StreamControllerLifecycle":["1"],"_EventSink":["1"],"_EventDispatch":["1"]},"_ControllerStream":{"_StreamImpl":["1"],"Stream":["1"],"Stream.T":"1"},"_ControllerSubscription":{"_BufferingStreamSubscription":["1"],"StreamSubscription":["1"],"_EventSink":["1"],"_EventDispatch":["1"],"_BufferingStreamSubscription.T":"1"},"_StreamSinkWrapper":{"StreamSink":["1"]},"_BufferingStreamSubscription":{"StreamSubscription":["1"],"_EventSink":["1"],"_EventDispatch":["1"],"_BufferingStreamSubscription.T":"1"},"_StreamImpl":{"Stream":["1"]},"_DelayedData":{"_DelayedEvent":["1"]},"_DelayedError":{"_DelayedEvent":["@"]},"_DelayedDone":{"_DelayedEvent":["@"]},"_DoneStreamSubscription":{"StreamSubscription":["1"]},"_EmptyStream":{"Stream":["1"],"Stream.T":"1"},"_ForwardingStream":{"Stream":["2"]},"_ForwardingStreamSubscription":{"_BufferingStreamSubscription":["2"],"StreamSubscription":["2"],"_EventSink":["2"],"_EventDispatch":["2"],"_BufferingStreamSubscription.T":"2"},"_MapStream":{"_ForwardingStream":["1","2"],"Stream":["2"],"Stream.T":"2"},"_ZoneSpecification":{"ZoneSpecification":[]},"_ZoneDelegate":{"ZoneDelegate":[]},"_Zone":{"Zone":[]},"_CustomZone":{"_Zone":[],"Zone":[]},"_RootZone":{"_Zone":[],"Zone":[]},"_SplayTreeSetNode":{"_SplayTreeNode":["1","_SplayTreeSetNode<1>"],"_SplayTreeNode.K":"1","_SplayTreeNode.1":"_SplayTreeSetNode<1>"},"_HashMap":{"MapBase":["1","2"],"HashMap":["1","2"],"Map":["1","2"],"MapBase.K":"1","MapBase.V":"2"},"_IdentityHashMap":{"_HashMap":["1","2"],"MapBase":["1","2"],"HashMap":["1","2"],"Map":["1","2"],"MapBase.K":"1","MapBase.V":"2"},"_CustomHashMap":{"_HashMap":["1","2"],"MapBase":["1","2"],"HashMap":["1","2"],"Map":["1","2"],"MapBase.K":"1","MapBase.V":"2"},"_HashMapKeyIterable":{"EfficientLengthIterable":["1"],"Iterable":["1"],"Iterable.E":"1"},"_HashMapKeyIterator":{"Iterator":["1"]},"_LinkedCustomHashMap":{"JsLinkedHashMap":["1","2"],"MapBase":["1","2"],"LinkedHashMap":["1","2"],"Map":["1","2"],"MapBase.K":"1","MapBase.V":"2"},"_HashSet":{"_SetBase":["1"],"SetBase":["1"],"Set":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"],"Iterable.E":"1"},"_HashSetIterator":{"Iterator":["1"]},"_LinkedHashSet":{"_SetBase":["1"],"SetBase":["1"],"Set":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"],"Iterable.E":"1"},"_LinkedHashSetIterator":{"Iterator":["1"]},"UnmodifiableListView":{"ListBase":["1"],"UnmodifiableListMixin":["1"],"List":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"],"ListBase.E":"1","Iterable.E":"1","UnmodifiableListMixin.E":"1"},"ListBase":{"List":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"]},"MapBase":{"Map":["1","2"]},"MapView":{"Map":["1","2"]},"UnmodifiableMapView":{"_UnmodifiableMapView_MapView__UnmodifiableMapMixin":["1","2"],"MapView":["1","2"],"_UnmodifiableMapMixin":["1","2"],"Map":["1","2"]},"ListQueue":{"Queue":["1"],"ListIterable":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"],"ListIterable.E":"1","Iterable.E":"1"},"_ListQueueIterator":{"Iterator":["1"]},"SetBase":{"Set":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"]},"_SetBase":{"SetBase":["1"],"Set":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"]},"_SplayTreeIterator":{"Iterator":["3"]},"_SplayTreeKeyIterator":{"_SplayTreeIterator":["1","2","1"],"Iterator":["1"],"_SplayTreeIterator.K":"1","_SplayTreeIterator.T":"1","_SplayTreeIterator.1":"2"},"SplayTreeSet":{"SetBase":["1"],"Set":["1"],"EfficientLengthIterable":["1"],"_SplayTree":["1","_SplayTreeSetNode<1>"],"Iterable":["1"],"Iterable.E":"1","_SplayTree.1":"_SplayTreeSetNode<1>","_SplayTree.K":"1"},"Encoding":{"Codec":["String","List"]},"_JsonMap":{"MapBase":["String","@"],"Map":["String","@"],"MapBase.K":"String","MapBase.V":"@"},"_JsonMapKeyIterable":{"ListIterable":["String"],"EfficientLengthIterable":["String"],"Iterable":["String"],"ListIterable.E":"String","Iterable.E":"String"},"AsciiCodec":{"Encoding":[],"Codec":["String","List"],"Codec.S":"String"},"_UnicodeSubsetEncoder":{"Converter":["String","List"],"StreamTransformer":["String","List"]},"AsciiEncoder":{"Converter":["String","List"],"StreamTransformer":["String","List"]},"_UnicodeSubsetDecoder":{"Converter":["List","String"],"StreamTransformer":["List","String"]},"AsciiDecoder":{"Converter":["List","String"],"StreamTransformer":["List","String"]},"Base64Codec":{"Codec":["List","String"],"Codec.S":"List"},"Base64Encoder":{"Converter":["List","String"],"StreamTransformer":["List","String"]},"Base64Decoder":{"Converter":["String","List"],"StreamTransformer":["String","List"]},"Converter":{"StreamTransformer":["1","2"]},"JsonUnsupportedObjectError":{"Error":[]},"JsonCyclicError":{"Error":[]},"JsonCodec":{"Codec":["Object?","String"],"Codec.S":"Object?"},"JsonEncoder":{"Converter":["Object?","String"],"StreamTransformer":["Object?","String"]},"JsonDecoder":{"Converter":["String","Object?"],"StreamTransformer":["String","Object?"]},"Latin1Codec":{"Encoding":[],"Codec":["String","List"],"Codec.S":"String"},"Latin1Encoder":{"Converter":["String","List"],"StreamTransformer":["String","List"]},"Latin1Decoder":{"Converter":["List","String"],"StreamTransformer":["List","String"]},"Utf8Codec":{"Encoding":[],"Codec":["String","List"],"Codec.S":"String"},"Utf8Encoder":{"Converter":["String","List"],"StreamTransformer":["String","List"]},"Utf8Decoder":{"Converter":["List","String"],"StreamTransformer":["List","String"]},"BigInt":{"Comparable":["BigInt"]},"DateTime":{"Comparable":["DateTime"]},"double":{"num":[],"Comparable":["num"]},"Duration":{"Comparable":["Duration"]},"int":{"num":[],"Comparable":["num"]},"List":{"EfficientLengthIterable":["1"],"Iterable":["1"]},"num":{"Comparable":["num"]},"RegExp":{"Pattern":[]},"RegExpMatch":{"Match":[]},"Set":{"EfficientLengthIterable":["1"],"Iterable":["1"]},"String":{"Comparable":["String"],"Pattern":[]},"_BigIntImpl":{"BigInt":[],"Comparable":["BigInt"]},"AssertionError":{"Error":[]},"TypeError":{"Error":[]},"ArgumentError":{"Error":[]},"RangeError":{"Error":[]},"IndexError":{"Error":[]},"UnsupportedError":{"Error":[]},"UnimplementedError":{"Error":[]},"StateError":{"Error":[]},"ConcurrentModificationError":{"Error":[]},"OutOfMemoryError":{"Error":[]},"StackOverflowError":{"Error":[]},"_Exception":{"Exception":[]},"FormatException":{"Exception":[]},"IntegerDivisionByZeroException":{"Exception":[],"Error":[]},"_StringStackTrace":{"StackTrace":[]},"StringBuffer":{"StringSink":[]},"_Uri":{"Uri":[]},"_SimpleUri":{"Uri":[]},"_DataUri":{"Uri":[]},"NullRejectionException":{"Exception":[]},"DelegatingStreamSink":{"StreamSink":["1"]},"ErrorResult":{"Result":["0&"]},"ValueResult":{"Result":["1"]},"_NextRequest":{"_EventRequest":["1"]},"_HasNextRequest":{"_EventRequest":["1"]},"BuiltList":{"Iterable":["1"]},"_BuiltList":{"BuiltList":["1"],"Iterable":["1"],"Iterable.E":"1"},"_BuiltListMultimap":{"BuiltListMultimap":["1","2"]},"_BuiltMap":{"BuiltMap":["1","2"]},"BuiltSet":{"Iterable":["1"]},"_BuiltSet":{"BuiltSet":["1"],"Iterable":["1"],"Iterable.E":"1"},"_BuiltSetMultimap":{"BuiltSetMultimap":["1","2"]},"BuiltValueNullFieldError":{"Error":[]},"BuiltValueNestedFieldError":{"Error":[]},"BoolJsonObject":{"JsonObject":[]},"ListJsonObject":{"JsonObject":[]},"MapJsonObject":{"JsonObject":[]},"NumJsonObject":{"JsonObject":[]},"StringJsonObject":{"JsonObject":[]},"DeserializationError":{"Error":[]},"BigIntSerializer":{"PrimitiveSerializer":["BigInt"],"Serializer":["BigInt"]},"BoolSerializer":{"PrimitiveSerializer":["bool"],"Serializer":["bool"]},"BuiltJsonSerializers":{"Serializers":[]},"BuiltListMultimapSerializer":{"StructuredSerializer":["BuiltListMultimap<@,@>"],"Serializer":["BuiltListMultimap<@,@>"]},"BuiltListSerializer":{"StructuredSerializer":["BuiltList<@>"],"Serializer":["BuiltList<@>"]},"BuiltMapSerializer":{"StructuredSerializer":["BuiltMap<@,@>"],"Serializer":["BuiltMap<@,@>"]},"BuiltSetMultimapSerializer":{"StructuredSerializer":["BuiltSetMultimap<@,@>"],"Serializer":["BuiltSetMultimap<@,@>"]},"BuiltSetSerializer":{"StructuredSerializer":["BuiltSet<@>"],"Serializer":["BuiltSet<@>"]},"DateTimeSerializer":{"PrimitiveSerializer":["DateTime"],"Serializer":["DateTime"]},"DoubleSerializer":{"PrimitiveSerializer":["double"],"Serializer":["double"]},"DurationSerializer":{"PrimitiveSerializer":["Duration"],"Serializer":["Duration"]},"Int32Serializer":{"PrimitiveSerializer":["Int32"],"Serializer":["Int32"]},"Int64Serializer":{"PrimitiveSerializer":["Int64"],"Serializer":["Int64"]},"IntSerializer":{"PrimitiveSerializer":["int"],"Serializer":["int"]},"JsonObjectSerializer":{"PrimitiveSerializer":["JsonObject"],"Serializer":["JsonObject"]},"NullSerializer":{"PrimitiveSerializer":["Null"],"Serializer":["Null"]},"NumSerializer":{"PrimitiveSerializer":["num"],"Serializer":["num"]},"RegExpSerializer":{"PrimitiveSerializer":["RegExp"],"Serializer":["RegExp"]},"StringSerializer":{"PrimitiveSerializer":["String"],"Serializer":["String"]},"Uint8ListSerializer":{"PrimitiveSerializer":["Uint8List"],"Serializer":["Uint8List"]},"UriSerializer":{"PrimitiveSerializer":["Uri"],"Serializer":["Uri"]},"CanonicalizedMap":{"Map":["2","3"]},"DefaultEquality":{"Equality":["1"]},"IterableEquality":{"Equality":["Iterable<1>"]},"ListEquality":{"Equality":["List<1>"]},"_UnorderedEquality":{"Equality":["2"]},"SetEquality":{"_UnorderedEquality":["1","Set<1>"],"Equality":["Set<1>"],"_UnorderedEquality.E":"1","_UnorderedEquality.T":"Set<1>"},"MapEquality":{"Equality":["Map<1,2>"]},"DeepCollectionEquality":{"Equality":["@"]},"QueueList":{"ListBase":["1"],"List":["1"],"Queue":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"],"ListBase.E":"1","QueueList.E":"1","Iterable.E":"1"},"_CastQueueList":{"QueueList":["2"],"ListBase":["2"],"List":["2"],"Queue":["2"],"EfficientLengthIterable":["2"],"Iterable":["2"],"ListBase.E":"2","QueueList.E":"2","Iterable.E":"2"},"_$BuildStatusSerializer":{"PrimitiveSerializer":["BuildStatus"],"Serializer":["BuildStatus"]},"_$BuildResultSerializer":{"StructuredSerializer":["BuildResult"],"Serializer":["BuildResult"]},"_$BuildResult":{"BuildResult":[]},"_$ConnectRequestSerializer":{"StructuredSerializer":["ConnectRequest"],"Serializer":["ConnectRequest"]},"_$ConnectRequest":{"ConnectRequest":[]},"_$DebugEventSerializer":{"StructuredSerializer":["DebugEvent"],"Serializer":["DebugEvent"]},"_$BatchedDebugEventsSerializer":{"StructuredSerializer":["BatchedDebugEvents"],"Serializer":["BatchedDebugEvents"]},"_$DebugEvent":{"DebugEvent":[]},"_$BatchedDebugEvents":{"BatchedDebugEvents":[]},"_$DebugInfoSerializer":{"StructuredSerializer":["DebugInfo"],"Serializer":["DebugInfo"]},"_$DebugInfo":{"DebugInfo":[]},"_$DevToolsRequestSerializer":{"StructuredSerializer":["DevToolsRequest"],"Serializer":["DevToolsRequest"]},"_$DevToolsResponseSerializer":{"StructuredSerializer":["DevToolsResponse"],"Serializer":["DevToolsResponse"]},"_$DevToolsRequest":{"DevToolsRequest":[]},"_$DevToolsResponse":{"DevToolsResponse":[]},"_$ErrorResponseSerializer":{"StructuredSerializer":["ErrorResponse"],"Serializer":["ErrorResponse"]},"_$ErrorResponse":{"ErrorResponse":[]},"_$ExtensionRequestSerializer":{"StructuredSerializer":["ExtensionRequest"],"Serializer":["ExtensionRequest"]},"_$ExtensionResponseSerializer":{"StructuredSerializer":["ExtensionResponse"],"Serializer":["ExtensionResponse"]},"_$ExtensionEventSerializer":{"StructuredSerializer":["ExtensionEvent"],"Serializer":["ExtensionEvent"]},"_$BatchedEventsSerializer":{"StructuredSerializer":["BatchedEvents"],"Serializer":["BatchedEvents"]},"_$ExtensionRequest":{"ExtensionRequest":[]},"_$ExtensionResponse":{"ExtensionResponse":[]},"_$ExtensionEvent":{"ExtensionEvent":[]},"_$BatchedEvents":{"BatchedEvents":[]},"_$HotReloadRequestSerializer":{"StructuredSerializer":["HotReloadRequest"],"Serializer":["HotReloadRequest"]},"_$HotReloadRequest":{"HotReloadRequest":[]},"_$HotReloadResponseSerializer":{"StructuredSerializer":["HotReloadResponse"],"Serializer":["HotReloadResponse"]},"_$HotReloadResponse":{"HotReloadResponse":[]},"_$IsolateExitSerializer":{"StructuredSerializer":["IsolateExit"],"Serializer":["IsolateExit"]},"_$IsolateStartSerializer":{"StructuredSerializer":["IsolateStart"],"Serializer":["IsolateStart"]},"_$IsolateExit":{"IsolateExit":[]},"_$IsolateStart":{"IsolateStart":[]},"_$RegisterEventSerializer":{"StructuredSerializer":["RegisterEvent"],"Serializer":["RegisterEvent"]},"_$RegisterEvent":{"RegisterEvent":[]},"_$RunRequestSerializer":{"StructuredSerializer":["RunRequest"],"Serializer":["RunRequest"]},"_$RunRequest":{"RunRequest":[]},"_$ServiceExtensionRequestSerializer":{"StructuredSerializer":["ServiceExtensionRequest"],"Serializer":["ServiceExtensionRequest"]},"_$ServiceExtensionRequest":{"ServiceExtensionRequest":[]},"_$ServiceExtensionResponseSerializer":{"StructuredSerializer":["ServiceExtensionResponse"],"Serializer":["ServiceExtensionResponse"]},"_$ServiceExtensionResponse":{"ServiceExtensionResponse":[]},"SseSocketClient":{"SocketClient":[]},"WebSocketClient":{"SocketClient":[]},"Int32":{"Comparable":["Object"]},"Int64":{"Comparable":["Object"]},"ByteStream":{"StreamView":["List"],"Stream":["List"],"Stream.T":"List","StreamView.T":"List"},"ClientException":{"Exception":[]},"Request":{"BaseRequest":[]},"StreamedResponseV2":{"StreamedResponse":[]},"CaseInsensitiveMap":{"CanonicalizedMap":["String","String","1"],"Map":["String","1"],"CanonicalizedMap.K":"String","CanonicalizedMap.V":"1","CanonicalizedMap.C":"String"},"Level":{"Comparable":["Level"]},"PathException":{"Exception":[]},"PosixStyle":{"InternalStyle":[]},"UrlStyle":{"InternalStyle":[]},"WindowsStyle":{"InternalStyle":[]},"FileLocation":{"SourceLocation":[],"Comparable":["SourceLocation"]},"_FileSpan":{"SourceSpanWithContext":[],"SourceSpan":[],"Comparable":["SourceSpan"]},"SourceLocation":{"Comparable":["SourceLocation"]},"SourceLocationMixin":{"SourceLocation":[],"Comparable":["SourceLocation"]},"SourceSpan":{"Comparable":["SourceSpan"]},"SourceSpanBase":{"SourceSpan":[],"Comparable":["SourceSpan"]},"SourceSpanException":{"Exception":[]},"SourceSpanFormatException":{"FormatException":[],"Exception":[]},"SourceSpanMixin":{"SourceSpan":[],"Comparable":["SourceSpan"]},"SourceSpanWithContext":{"SourceSpan":[],"Comparable":["SourceSpan"]},"SseClient":{"StreamChannel":["String?"]},"GuaranteeChannel":{"StreamChannel":["1"]},"_GuaranteeSink":{"StreamSink":["1"]},"StreamChannelMixin":{"StreamChannel":["1"]},"StringScannerException":{"FormatException":[],"Exception":[]},"_EventStream":{"Stream":["1"],"Stream.T":"1"},"_EventStreamSubscription":{"StreamSubscription":["1"]},"BrowserWebSocket":{"WebSocket":[]},"TextDataReceived":{"WebSocketEvent":[]},"BinaryDataReceived":{"WebSocketEvent":[]},"CloseReceived":{"WebSocketEvent":[]},"WebSocketException":{"Exception":[]},"WebSocketConnectionClosed":{"Exception":[]},"AdapterWebSocketChannel":{"WebSocketChannel":[],"StreamChannel":["@"]},"_WebSocketSink":{"WebSocketSink":[],"DelegatingStreamSink":["@"],"StreamSink":["@"],"DelegatingStreamSink.T":"@"},"WebSocketChannelException":{"Exception":[]},"DdcLibraryBundleRestarter":{"Restarter":[]},"DdcRestarter":{"Restarter":[]},"RequireRestarter":{"Restarter":[]},"HotReloadFailedException":{"Exception":[]},"Int8List":{"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"]},"Uint8List":{"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"]},"Uint8ClampedList":{"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"]},"Int16List":{"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"]},"Uint16List":{"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"]},"Int32List":{"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"]},"Uint32List":{"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"]},"Float32List":{"List":["double"],"EfficientLengthIterable":["double"],"Iterable":["double"]},"Float64List":{"List":["double"],"EfficientLengthIterable":["double"],"Iterable":["double"]}}')); A._Universe_addErasedTypes(init.typeUniverse, JSON.parse('{"UnmodifiableListBase":1,"__CastListBase__CastIterableBase_ListMixin":2,"NativeTypedArray":1,"_DelayedEvent":1,"_SplayTreeSet__SplayTree_Iterable":1,"_SplayTreeSet__SplayTree_Iterable_SetMixin":1,"_QueueList_Object_ListMixin":1,"StreamChannelMixin":1}')); var string$ = { x00_____: "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\u03f6\x00\u0404\u03f4 \u03f4\u03f6\u01f6\u01f6\u03f6\u03fc\u01f4\u03ff\u03ff\u0584\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u05d4\u01f4\x00\u01f4\x00\u0504\u05c4\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u0400\x00\u0400\u0200\u03f7\u0200\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u0200\u0200\u0200\u03f7\x00", @@ -28221,6 +28627,7 @@ Error_: "Error handler must accept one Object or one Object and a StackTrace as arguments, and return a value of the returned future's type", Hot_reA: "Hot reload is not supported for the AMD module format.", Hot_reD: "Hot reload is not supported for the DDC module format.", + max_mu: "max must be in range 0 < max \u2264 2^32, was ", serial: "serializer must be StructuredSerializer or PrimitiveSerializer" }; var type$ = (function rtii() { @@ -28318,6 +28725,7 @@ MapEntry_of_Object_and_List__Highlight: findType("MapEntry>"), MapEquality_dynamic_dynamic: findType("MapEquality<@,@>"), Map_String_String: findType("Map"), + Map_String_dynamic: findType("Map"), Map_dynamic_dynamic: findType("Map<@,@>"), Map_of_String_and_nullable_Object: findType("Map"), MappedListIterable_String_dynamic: findType("MappedListIterable"), @@ -28341,6 +28749,8 @@ RunRequest: findType("RunRequest"), SerializerPlugin: findType("SerializerPlugin"), Serializer_dynamic: findType("Serializer<@>"), + ServiceExtensionRequest: findType("ServiceExtensionRequest"), + ServiceExtensionResponse: findType("ServiceExtensionResponse"), SetBuilder_dynamic: findType("SetBuilder<@>"), SetEquality_dynamic: findType("SetEquality<@>"), SetMultimapBuilder_dynamic_dynamic: findType("SetMultimapBuilder<@,@>"), @@ -28417,6 +28827,7 @@ nullable_ListBuilder_DebugEvent: findType("ListBuilder?"), nullable_ListBuilder_ExtensionEvent: findType("ListBuilder?"), nullable_List_dynamic: findType("List<@>?"), + nullable_Map_String_dynamic: findType("Map?"), nullable_Map_of_nullable_Object_and_nullable_Object: findType("Map?"), nullable_Object: findType("Object?"), nullable_Result_DebugEvent: findType("Result?"), @@ -28443,6 +28854,7 @@ nullable_void_Function_HotReloadResponseBuilder: findType("~(HotReloadResponseBuilder)?"), nullable_void_Function_JSObject: findType("~(JSObject)?"), nullable_void_Function_RegisterEventBuilder: findType("~(RegisterEventBuilder)?"), + nullable_void_Function_ServiceExtensionResponseBuilder: findType("~(ServiceExtensionResponseBuilder)?"), num: findType("num"), void: findType("~"), void_Function: findType("~()"), @@ -28464,6 +28876,7 @@ B.JSString_methods = J.JSString.prototype; B.JavaScriptFunction_methods = J.JavaScriptFunction.prototype; B.JavaScriptObject_methods = J.JavaScriptObject.prototype; + B.NativeByteData_methods = A.NativeByteData.prototype; B.NativeUint32List_methods = A.NativeUint32List.prototype; B.NativeUint8List_methods = A.NativeUint8List.prototype; B.PlainJavaScriptObject_methods = J.PlainJavaScriptObject.prototype; @@ -28622,9 +29035,9 @@ B.Duration_5000000 = new A.Duration(5000000); B.Type_BuiltList_fj6 = A.typeLiteral("BuiltList<@>"); B.Type_DebugEvent_gLJ = A.typeLiteral("DebugEvent"); - B.List_empty1 = makeConstList([], type$.JSArray_FullType); + B.List_empty1 = A._setArrayType(makeConstList([]), type$.JSArray_FullType); B.FullType_np4 = new A.FullType(B.Type_DebugEvent_gLJ, B.List_empty1, false); - B.List_njn = makeConstList([B.FullType_np4], type$.JSArray_FullType); + B.List_njn = A._setArrayType(makeConstList([B.FullType_np4]), type$.JSArray_FullType); B.FullType_3Xm = new A.FullType(B.Type_BuiltList_fj6, B.List_njn, false); B.Type_String_AXU = A.typeLiteral("String"); B.FullType_PT1 = new A.FullType(B.Type_String_AXU, B.List_empty1, false); @@ -28633,15 +29046,15 @@ B.Type_BuiltSetMultimap_yT7 = A.typeLiteral("BuiltSetMultimap<@,@>"); B.Type_Object_A4p = A.typeLiteral("Object"); B.FullType_kV7 = new A.FullType(B.Type_Object_A4p, B.List_empty1, false); - B.List_03P = makeConstList([B.FullType_kV7, B.FullType_kV7], type$.JSArray_FullType); + B.List_03P = A._setArrayType(makeConstList([B.FullType_kV7, B.FullType_kV7]), type$.JSArray_FullType); B.FullType_SWR = new A.FullType(B.Type_BuiltSetMultimap_yT7, B.List_03P, false); B.Type_BuiltListMultimap_HQW = A.typeLiteral("BuiltListMultimap<@,@>"); B.FullType_WP0 = new A.FullType(B.Type_BuiltListMultimap_HQW, B.List_03P, false); B.Type_ExtensionEvent_T8C = A.typeLiteral("ExtensionEvent"); B.FullType_I4i = new A.FullType(B.Type_ExtensionEvent_T8C, B.List_empty1, false); - B.List_O9J = makeConstList([B.FullType_I4i], type$.JSArray_FullType); + B.List_O9J = A._setArrayType(makeConstList([B.FullType_I4i]), type$.JSArray_FullType); B.FullType_ahP = new A.FullType(B.Type_BuiltList_fj6, B.List_O9J, false); - B.List_LtY = makeConstList([B.FullType_kV7], type$.JSArray_FullType); + B.List_LtY = A._setArrayType(makeConstList([B.FullType_kV7]), type$.JSArray_FullType); B.FullType_hm4 = new A.FullType(B.Type_BuiltList_fj6, B.List_LtY, false); B.Type_BuildStatus_8KJ = A.typeLiteral("BuildStatus"); B.FullType_k5M = new A.FullType(B.Type_BuildStatus_8KJ, B.List_empty1, false); @@ -28661,61 +29074,67 @@ B.Level_WARNING_900 = new A.Level("WARNING", 900); B.Type_ExtensionRequest_9GR = A.typeLiteral("ExtensionRequest"); B.Type__$ExtensionRequest_o1C = A.typeLiteral("_$ExtensionRequest"); - B.List_2dD = makeConstList([B.Type_ExtensionRequest_9GR, B.Type__$ExtensionRequest_o1C], type$.JSArray_Type); + B.List_2dD = A._setArrayType(makeConstList([B.Type_ExtensionRequest_9GR, B.Type__$ExtensionRequest_o1C]), type$.JSArray_Type); + B.Type_ServiceExtensionRequest_K8g = A.typeLiteral("ServiceExtensionRequest"); + B.Type__$ServiceExtensionRequest_n9i = A.typeLiteral("_$ServiceExtensionRequest"); + B.List_4i4 = A._setArrayType(makeConstList([B.Type_ServiceExtensionRequest_K8g, B.Type__$ServiceExtensionRequest_n9i]), type$.JSArray_Type); B.Type_DebugInfo_ua9 = A.typeLiteral("DebugInfo"); B.Type__$DebugInfo_ywz = A.typeLiteral("_$DebugInfo"); - B.List_55I = makeConstList([B.Type_DebugInfo_ua9, B.Type__$DebugInfo_ywz], type$.JSArray_Type); + B.List_55I = A._setArrayType(makeConstList([B.Type_DebugInfo_ua9, B.Type__$DebugInfo_ywz]), type$.JSArray_Type); B.Type_ErrorResponse_WMn = A.typeLiteral("ErrorResponse"); B.Type__$ErrorResponse_9Ps = A.typeLiteral("_$ErrorResponse"); - B.List_5LV = makeConstList([B.Type_ErrorResponse_WMn, B.Type__$ErrorResponse_9Ps], type$.JSArray_Type); + B.List_5LV = A._setArrayType(makeConstList([B.Type_ErrorResponse_WMn, B.Type__$ErrorResponse_9Ps]), type$.JSArray_Type); + B.Type_ServiceExtensionResponse_84R = A.typeLiteral("ServiceExtensionResponse"); + B.Type__$ServiceExtensionResponse_UiR = A.typeLiteral("_$ServiceExtensionResponse"); + B.List_5rA = A._setArrayType(makeConstList([B.Type_ServiceExtensionResponse_84R, B.Type__$ServiceExtensionResponse_UiR]), type$.JSArray_Type); B.Type_HotReloadResponse_Gqc = A.typeLiteral("HotReloadResponse"); B.Type__$HotReloadResponse_56g = A.typeLiteral("_$HotReloadResponse"); - B.List_DqJ = makeConstList([B.Type_HotReloadResponse_Gqc, B.Type__$HotReloadResponse_56g], type$.JSArray_Type); + B.List_DqJ = A._setArrayType(makeConstList([B.Type_HotReloadResponse_Gqc, B.Type__$HotReloadResponse_56g]), type$.JSArray_Type); B.Type_RegisterEvent_0Yw = A.typeLiteral("RegisterEvent"); B.Type__$RegisterEvent_Ks1 = A.typeLiteral("_$RegisterEvent"); - B.List_EMv = makeConstList([B.Type_RegisterEvent_0Yw, B.Type__$RegisterEvent_Ks1], type$.JSArray_Type); + B.List_EMv = A._setArrayType(makeConstList([B.Type_RegisterEvent_0Yw, B.Type__$RegisterEvent_Ks1]), type$.JSArray_Type); B.Type_DevToolsRequest_DxE = A.typeLiteral("DevToolsRequest"); B.Type__$DevToolsRequest_Rak = A.typeLiteral("_$DevToolsRequest"); - B.List_G46 = makeConstList([B.Type_DevToolsRequest_DxE, B.Type__$DevToolsRequest_Rak], type$.JSArray_Type); + B.List_G46 = A._setArrayType(makeConstList([B.Type_DevToolsRequest_DxE, B.Type__$DevToolsRequest_Rak]), type$.JSArray_Type); B.Type_IsolateStart_nRT = A.typeLiteral("IsolateStart"); B.Type__$IsolateStart_Pnq = A.typeLiteral("_$IsolateStart"); - B.List_KpG = makeConstList([B.Type_IsolateStart_nRT, B.Type__$IsolateStart_Pnq], type$.JSArray_Type); + B.List_KpG = A._setArrayType(makeConstList([B.Type_IsolateStart_nRT, B.Type__$IsolateStart_Pnq]), type$.JSArray_Type); B.Type_IsolateExit_QVA = A.typeLiteral("IsolateExit"); B.Type__$IsolateExit_4XE = A.typeLiteral("_$IsolateExit"); - B.List_MJN = makeConstList([B.Type_IsolateExit_QVA, B.Type__$IsolateExit_4XE], type$.JSArray_Type); + B.List_MJN = A._setArrayType(makeConstList([B.Type_IsolateExit_QVA, B.Type__$IsolateExit_4XE]), type$.JSArray_Type); B.Type_ExtensionResponse_0Oi = A.typeLiteral("ExtensionResponse"); B.Type__$ExtensionResponse_46G = A.typeLiteral("_$ExtensionResponse"); - B.List_RWp = makeConstList([B.Type_ExtensionResponse_0Oi, B.Type__$ExtensionResponse_46G], type$.JSArray_Type); + B.List_RWp = A._setArrayType(makeConstList([B.Type_ExtensionResponse_0Oi, B.Type__$ExtensionResponse_46G]), type$.JSArray_Type); B.Type_RunRequest_Hfm = A.typeLiteral("RunRequest"); B.Type__$RunRequest_3ad = A.typeLiteral("_$RunRequest"); - B.List_RlA = makeConstList([B.Type_RunRequest_Hfm, B.Type__$RunRequest_3ad], type$.JSArray_Type); + B.List_RlA = A._setArrayType(makeConstList([B.Type_RunRequest_Hfm, B.Type__$RunRequest_3ad]), type$.JSArray_Type); B.Type_DevToolsResponse_gVs = A.typeLiteral("DevToolsResponse"); B.Type__$DevToolsResponse_dcs = A.typeLiteral("_$DevToolsResponse"); - B.List_TEH = makeConstList([B.Type_DevToolsResponse_gVs, B.Type__$DevToolsResponse_dcs], type$.JSArray_Type); - B.List_Type_BuildStatus_8KJ = makeConstList([B.Type_BuildStatus_8KJ], type$.JSArray_Type); + B.List_TEH = A._setArrayType(makeConstList([B.Type_DevToolsResponse_gVs, B.Type__$DevToolsResponse_dcs]), type$.JSArray_Type); + B.List_Type_BuildStatus_8KJ = A._setArrayType(makeConstList([B.Type_BuildStatus_8KJ]), type$.JSArray_Type); B.Type_BatchedDebugEvents_v7B = A.typeLiteral("BatchedDebugEvents"); B.Type__$BatchedDebugEvents_LFV = A.typeLiteral("_$BatchedDebugEvents"); - B.List_WAE = makeConstList([B.Type_BatchedDebugEvents_v7B, B.Type__$BatchedDebugEvents_LFV], type$.JSArray_Type); - B.List_ZNA = makeConstList([0, 0, 1048576, 531441, 1048576, 390625, 279936, 823543, 262144, 531441, 1000000, 161051, 248832, 371293, 537824, 759375, 1048576, 83521, 104976, 130321, 160000, 194481, 234256, 279841, 331776, 390625, 456976, 531441, 614656, 707281, 810000, 923521, 1048576, 35937, 39304, 42875, 46656], type$.JSArray_int); + B.List_WAE = A._setArrayType(makeConstList([B.Type_BatchedDebugEvents_v7B, B.Type__$BatchedDebugEvents_LFV]), type$.JSArray_Type); + B.List_ZNA = A._setArrayType(makeConstList([0, 0, 1048576, 531441, 1048576, 390625, 279936, 823543, 262144, 531441, 1000000, 161051, 248832, 371293, 537824, 759375, 1048576, 83521, 104976, 130321, 160000, 194481, 234256, 279841, 331776, 390625, 456976, 531441, 614656, 707281, 810000, 923521, 1048576, 35937, 39304, 42875, 46656]), type$.JSArray_int); B.Type_HotReloadRequest_EsW = A.typeLiteral("HotReloadRequest"); B.Type__$HotReloadRequest_ynq = A.typeLiteral("_$HotReloadRequest"); - B.List_dz9 = makeConstList([B.Type_HotReloadRequest_EsW, B.Type__$HotReloadRequest_ynq], type$.JSArray_Type); - B.List_empty = makeConstList([], type$.JSArray_String); - B.List_empty0 = makeConstList([], type$.JSArray_dynamic); - B.List_fAJ = makeConstList(["d", "D", "\u2202", "\xce"], type$.JSArray_String); + B.List_dz9 = A._setArrayType(makeConstList([B.Type_HotReloadRequest_EsW, B.Type__$HotReloadRequest_ynq]), type$.JSArray_Type); + B.List_empty = A._setArrayType(makeConstList([]), type$.JSArray_String); + B.List_empty0 = A._setArrayType(makeConstList([]), type$.JSArray_dynamic); + B.List_fAJ = A._setArrayType(makeConstList(["d", "D", "\u2202", "\xce"]), type$.JSArray_String); B.Type__$DebugEvent_YX4 = A.typeLiteral("_$DebugEvent"); - B.List_fK8 = makeConstList([B.Type_DebugEvent_gLJ, B.Type__$DebugEvent_YX4], type$.JSArray_Type); + B.List_fK8 = A._setArrayType(makeConstList([B.Type_DebugEvent_gLJ, B.Type__$DebugEvent_YX4]), type$.JSArray_Type); B.Type_BatchedEvents_ABc = A.typeLiteral("BatchedEvents"); B.Type__$BatchedEvents_jAA = A.typeLiteral("_$BatchedEvents"); - B.List_oDF = makeConstList([B.Type_BatchedEvents_ABc, B.Type__$BatchedEvents_jAA], type$.JSArray_Type); + B.List_oDF = A._setArrayType(makeConstList([B.Type_BatchedEvents_ABc, B.Type__$BatchedEvents_jAA]), type$.JSArray_Type); B.Type_BuildResult_SAR = A.typeLiteral("BuildResult"); B.Type__$BuildResult_Iwz = A.typeLiteral("_$BuildResult"); - B.List_pLn = makeConstList([B.Type_BuildResult_SAR, B.Type__$BuildResult_Iwz], type$.JSArray_Type); + B.List_pLn = A._setArrayType(makeConstList([B.Type_BuildResult_SAR, B.Type__$BuildResult_Iwz]), type$.JSArray_Type); B.Type_ConnectRequest_8Nv = A.typeLiteral("ConnectRequest"); B.Type__$ConnectRequest_3Qd = A.typeLiteral("_$ConnectRequest"); - B.List_xmd = makeConstList([B.Type_ConnectRequest_8Nv, B.Type__$ConnectRequest_3Qd], type$.JSArray_Type); + B.List_xmd = A._setArrayType(makeConstList([B.Type_ConnectRequest_8Nv, B.Type__$ConnectRequest_3Qd]), type$.JSArray_Type); B.Type__$ExtensionEvent_WzR = A.typeLiteral("_$ExtensionEvent"); - B.List_yvR = makeConstList([B.Type_ExtensionEvent_T8C, B.Type__$ExtensionEvent_WzR], type$.JSArray_Type); + B.List_yvR = A._setArrayType(makeConstList([B.Type_ExtensionEvent_T8C, B.Type__$ExtensionEvent_WzR]), type$.JSArray_Type); B.Object_empty = {}; B.Map_empty0 = new A.ConstantStringMap(B.Object_empty, [], A.findType("ConstantStringMap")); B.Map_empty = new A.ConstantStringMap(B.Object_empty, [], A.findType("ConstantStringMap<@,@>")); @@ -28735,13 +29154,10 @@ B.Type_JSObject_ttY = A.typeLiteral("JSObject"); B.Type_JsonObject_5jQ = A.typeLiteral("JsonObject"); B.Type_ListJsonObject_qcV = A.typeLiteral("ListJsonObject"); - B.Type_List_hc9 = A.typeLiteral("List<@>"); B.Type_MapJsonObject_VMr = A.typeLiteral("MapJsonObject"); - B.Type_Map_9Aj = A.typeLiteral("Map<@,@>"); B.Type_Null_0Rm = A.typeLiteral("Null"); B.Type_NumJsonObject_hYY = A.typeLiteral("NumJsonObject"); B.Type_RegExp_w5l = A.typeLiteral("RegExp"); - B.Type_Set_tZi = A.typeLiteral("Set<@>"); B.Type_StringJsonObject_NL7 = A.typeLiteral("StringJsonObject"); B.Type_Uint16List_kmP = A.typeLiteral("Uint16List"); B.Type_Uint32List_kmP = A.typeLiteral("Uint32List"); @@ -28813,7 +29229,6 @@ _lazy = hunkHelpers.lazy; _lazyFinal($, "DART_CLOSURE_PROPERTY_NAME", "$get$DART_CLOSURE_PROPERTY_NAME", () => A.getIsolateAffinityTag("_$dart_dartClosure")); _lazyFinal($, "nullFuture", "$get$nullFuture", () => B.C__RootZone.run$1$1(new A.nullFuture_closure(), type$.Future_void)); - _lazyFinal($, "_safeToStringHooks", "$get$_safeToStringHooks", () => A._setArrayType([new J.JSArraySafeToStringHook()], A.findType("JSArray"))); _lazyFinal($, "TypeErrorDecoder_noSuchMethodPattern", "$get$TypeErrorDecoder_noSuchMethodPattern", () => A.TypeErrorDecoder_extractPattern(A.TypeErrorDecoder_provokeCallErrorOn({ toString: function() { return "$receiver$"; @@ -28878,6 +29293,11 @@ _lazyFinal($, "_Uri__needsNoEncoding", "$get$_Uri__needsNoEncoding", () => A.RegExp_RegExp("^[\\-\\.0-9A-Z_a-z~]*$", true, false)); _lazyFinal($, "_hashSeed", "$get$_hashSeed", () => A.objectHashCode(B.Type_Object_A4p)); _lazyFinal($, "_jsBoxedDartObjectProperty", "$get$_jsBoxedDartObjectProperty", () => Symbol("jsBoxedDartObjectProperty")); + _lazyFinal($, "Random__secureRandom", "$get$Random__secureRandom", () => { + var t1 = new A._JSSecureRandom(new DataView(new ArrayBuffer(A._checkLength(8)))); + t1._JSSecureRandom$0(); + return t1; + }); _lazyFinal($, "isSoundMode", "$get$isSoundMode", () => !type$.List_int._is(A._setArrayType([], A.findType("JSArray")))); _lazy($, "newBuiltValueToStringHelper", "$get$newBuiltValueToStringHelper", () => new A.newBuiltValueToStringHelper_closure()); _lazyFinal($, "_runtimeType", "$get$_runtimeType", () => A.getRuntimeTypeOfDartObject(A.RegExp_RegExp("", true, false))); @@ -28923,17 +29343,21 @@ t1.add$1(0, $.$get$_$isolateStartSerializer()); t1.add$1(0, $.$get$_$registerEventSerializer()); t1.add$1(0, $.$get$_$runRequestSerializer()); + t1.add$1(0, $.$get$_$serviceExtensionRequestSerializer()); + t1.add$1(0, $.$get$_$serviceExtensionResponseSerializer()); t1.addBuilderFactory$2(B.FullType_3Xm, new A._$serializers_closure()); t1.addBuilderFactory$2(B.FullType_ahP, new A._$serializers_closure0()); return t1.build$0(); }); + _lazy($, "_$serviceExtensionRequestSerializer", "$get$_$serviceExtensionRequestSerializer", () => new A._$ServiceExtensionRequestSerializer()); + _lazy($, "_$serviceExtensionResponseSerializer", "$get$_$serviceExtensionResponseSerializer", () => new A._$ServiceExtensionResponseSerializer()); _lazyFinal($, "_logger", "$get$_logger", () => A.Logger_Logger("Utilities")); _lazyFinal($, "BaseRequest__tokenRE", "$get$BaseRequest__tokenRE", () => A.RegExp_RegExp("^[\\w!#%&'*+\\-.^`|~]+$", true, false)); _lazyFinal($, "_digitRegex", "$get$_digitRegex", () => A.RegExp_RegExp("^\\d+$", true, false)); _lazyFinal($, "_escapedChar", "$get$_escapedChar", () => A.RegExp_RegExp('["\\x00-\\x1F\\x7F]', true, false)); _lazyFinal($, "token", "$get$token", () => A.RegExp_RegExp('[^()<>@,;:"\\\\/[\\]?={} \\t\\x00-\\x1F\\x7F]+', true, false)); _lazyFinal($, "_lws", "$get$_lws", () => A.RegExp_RegExp("(?:\\r\\n)?[ \\t]+", true, false)); - _lazyFinal($, "_quotedString", "$get$_quotedString", () => A.RegExp_RegExp('"(?:[^"\\x00-\\x1F\\x7F]|\\\\.)*"', true, false)); + _lazyFinal($, "_quotedString", "$get$_quotedString", () => A.RegExp_RegExp('"(?:[^"\\x00-\\x1F\\x7F\\\\]|\\\\.)*"', true, false)); _lazyFinal($, "_quotedPair", "$get$_quotedPair", () => A.RegExp_RegExp("\\\\(.)", true, false)); _lazyFinal($, "nonToken", "$get$nonToken", () => A.RegExp_RegExp('[()<>@,;:"\\\\/\\[\\]?={} \\t\\x00-\\x1F\\x7F]', true, false)); _lazyFinal($, "whitespace", "$get$whitespace", () => A.RegExp_RegExp("(?:" + $.$get$_lws().pattern + ")*", true, false)); @@ -28952,10 +29376,7 @@ t4 = A.Completer_Completer(type$.dynamic); return new A.Pool(t2, t3, t1, 1000, new A.AsyncMemoizer(t4, A.findType("AsyncMemoizer<@>"))); }); - _lazy($, "V1State_random", "$get$V1State_random", () => { - var t1 = A.Random_Random(null); - return new A.MathRNG(t1); - }); + _lazy($, "V1State_random", "$get$V1State_random", () => new A.CryptoRNG()); _lazyFinal($, "UuidParsing__byteToHex", "$get$UuidParsing__byteToHex", () => { var i, _list = J.JSArray_JSArray$allocateGrowable(256, type$.String); @@ -28963,6 +29384,7 @@ _list[i] = B.JSString_methods.padLeft$2(B.JSInt_methods.toRadixString$1(i, 16), 2, "0"); return _list; }); + _lazyFinal($, "CryptoRNG__secureRandom", "$get$CryptoRNG__secureRandom", () => $.$get$Random__secureRandom()); _lazyFinal($, "_noncePattern", "$get$_noncePattern", () => A.RegExp_RegExp("^[\\w+/_-]+[=]{0,2}$", true, false)); _lazyFinal($, "_createScript", "$get$_createScript", () => new A._createScript_closure().call$0()); })(); diff --git a/dwds/lib/src/services/app_debug_services.dart b/dwds/lib/src/services/app_debug_services.dart index fb9d18667..4d262281b 100644 --- a/dwds/lib/src/services/app_debug_services.dart +++ b/dwds/lib/src/services/app_debug_services.dart @@ -4,37 +4,93 @@ import 'package:dwds/src/dwds_vm_client.dart'; import 'package:dwds/src/events.dart'; -import 'package:dwds/src/services/chrome_proxy_service.dart' - show ChromeProxyService; import 'package:dwds/src/services/debug_service.dart'; +import 'package:dwds/src/services/proxy_service.dart'; -/// A container for all the services required for debugging an application. -class AppDebugServices { - final DebugService debugService; - final DwdsVmClient dwdsVmClient; - final DwdsStats dwdsStats; - final Uri? ddsUri; - - ChromeProxyService get chromeProxyService => - debugService.chromeProxyService as ChromeProxyService; +/// Common interface for debug service containers. +abstract class AppDebugServices { + DebugService get debugService; + DwdsVmClient get dwdsVmClient; + DwdsStats? get dwdsStats; + Uri? get ddsUri; + String? get connectedInstanceId; + set connectedInstanceId(String? id); + Future close(); + ProxyService get proxyService; +} - /// Null until [close] is called. - /// - /// All subsequent calls to [close] will return this future. +/// Chrome-based debug services container. +class ChromeAppDebugServices implements AppDebugServices { + final ChromeDebugService _debugService; + final ChromeDwdsVmClient _dwdsVmClient; + final DwdsStats _dwdsStats; + final Uri? _ddsUri; Future? _closed; + String? _connectedInstanceId; - /// The instance ID for the currently connected application, if there is one. - /// - /// We only allow a given app to be debugged in a single tab at a time. - String? connectedInstanceId; - - AppDebugServices( - this.debugService, - this.dwdsVmClient, - this.dwdsStats, - this.ddsUri, + ChromeAppDebugServices( + this._debugService, + this._dwdsVmClient, + this._dwdsStats, + this._ddsUri, ); + @override + ChromeDebugService get debugService => _debugService; + + @override + DwdsVmClient get dwdsVmClient => _dwdsVmClient; + + @override + DwdsStats get dwdsStats => _dwdsStats; + + @override + Uri? get ddsUri => _ddsUri; + + @override + String? get connectedInstanceId => _connectedInstanceId; + + @override + set connectedInstanceId(String? id) => _connectedInstanceId = id; + + @override + ProxyService get proxyService => debugService.chromeProxyService; + + @override Future close() => _closed ??= Future.wait([debugService.close(), dwdsVmClient.close()]); } + +/// WebSocket-based implementation of app debug services. +class WebSocketAppDebugServices implements AppDebugServices { + final WebSocketDebugService _debugService; + final WebSocketDwdsVmClient _dwdsVmClient; + Future? _closed; + @override + String? connectedInstanceId; + + WebSocketAppDebugServices(this._debugService, this._dwdsVmClient); + + @override + WebSocketDebugService get debugService => _debugService; + + @override + DwdsVmClient get dwdsVmClient => _dwdsVmClient; + + // WebSocket-only service - Chrome/DDS features not available + @override + DwdsStats? get dwdsStats => null; + @override + Uri? get ddsUri => null; + + @override + ProxyService get proxyService => _debugService.webSocketProxyService; + + @override + Future close() { + return _closed ??= Future.wait([ + debugService.close(), + dwdsVmClient.close(), + ]); + } +} diff --git a/dwds/lib/src/services/chrome_proxy_service.dart b/dwds/lib/src/services/chrome_proxy_service.dart index 37c50be82..27080471c 100644 --- a/dwds/lib/src/services/chrome_proxy_service.dart +++ b/dwds/lib/src/services/chrome_proxy_service.dart @@ -7,8 +7,6 @@ import 'dart:convert'; import 'dart:io'; import 'package:dwds/data/debug_event.dart'; -import 'package:dwds/data/hot_reload_request.dart'; -import 'package:dwds/data/hot_reload_response.dart'; import 'package:dwds/data/register_event.dart'; import 'package:dwds/src/config/tool_configuration.dart'; import 'package:dwds/src/connections/app_connection.dart'; @@ -27,34 +25,16 @@ import 'package:dwds/src/services/batched_expression_evaluator.dart'; import 'package:dwds/src/services/debug_service.dart'; import 'package:dwds/src/services/expression_compiler.dart'; import 'package:dwds/src/services/expression_evaluator.dart'; +import 'package:dwds/src/services/proxy_service.dart'; import 'package:dwds/src/utilities/dart_uri.dart'; import 'package:dwds/src/utilities/shared.dart'; import 'package:logging/logging.dart' hide LogRecord; -import 'package:pub_semver/pub_semver.dart' as semver; import 'package:vm_service/vm_service.dart' hide vmServiceVersion; import 'package:vm_service_interface/vm_service_interface.dart'; import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart'; -/// Defines callbacks for sending messages to the connected client application. -typedef SendClientRequest = void Function(Object request); - /// A proxy from the chrome debug protocol to the dart vm service protocol. -class ChromeProxyService implements VmServiceInterface { - final bool useWebSocket; - - /// Cache of all existing StreamControllers. - /// - /// These are all created through [onEvent]. - final _streamControllers = >{}; - - /// The root `VM` instance. There can only be one of these, but its isolates - /// are dynamic and roughly map to chrome tabs. - final VM _vm; - - /// Signals when isolate is initialized. - Future get isInitialized => _initializedCompleter.future; - Completer _initializedCompleter = Completer(); - +class ChromeProxyService extends ProxyService { /// Signals when isolate starts. Future get isStarted => _startedCompleter.future; Completer _startedCompleter = Completer(); @@ -100,34 +80,6 @@ class ChromeProxyService implements VmServiceInterface { StreamSubscription? _consoleSubscription; - /// The flags that can be set at runtime via [setFlag] and their respective - /// values. - final Map _currentVmServiceFlags = { - _pauseIsolatesOnStartFlag: false, - }; - - /// The value of the [_pauseIsolatesOnStartFlag]. - /// - /// This value can be updated at runtime via [setFlag]. - bool get pauseIsolatesOnStart => - _currentVmServiceFlags[_pauseIsolatesOnStartFlag] ?? false; - - /// Whether or not the connected app has a pending restart. - bool get hasPendingRestart => _resumeAfterRestartEventsController.hasListener; - - final _resumeAfterRestartEventsController = - StreamController.broadcast(); - - /// A global stream of resume events for hot restart. - /// - /// The values in the stream are the isolates IDs for the resume event. - /// - /// IMPORTANT: This should only be listened to during a hot-restart or page - /// refresh. The debugger ignores any resume events as long as there is a - /// subscriber to this stream. - Stream get resumeAfterRestartEventsStream => - _resumeAfterRestartEventsController.stream; - /// If non-null, a resume event should await the result of this after resuming /// execution. /// @@ -141,14 +93,8 @@ class ChromeProxyService implements VmServiceInterface { bool terminatingIsolates = false; - /// Callback function to send messages to the connected client application. - final SendClientRequest sendClientRequest; - - /// Pending hot reload request waiting for a response from the client. - Completer? _pendingHotReload; - ChromeProxyService._( - this._vm, + super.vm, this.root, this._assetReader, this.remoteDebugger, @@ -157,12 +103,10 @@ class ChromeProxyService implements VmServiceInterface { this._skipLists, this.executionContext, this._compiler, - this.sendClientRequest, { - this.useWebSocket = false, - }) { + ) { final debugger = Debugger.create( remoteDebugger, - _streamNotify, + streamNotify, _locations, _skipLists, root, @@ -177,9 +121,7 @@ class ChromeProxyService implements VmServiceInterface { AppConnection appConnection, ExecutionContext executionContext, ExpressionCompiler? expressionCompiler, - SendClientRequest sendClientRequest, { - bool useWebSocket = false, - }) async { + ) async { final vm = VM( name: 'ChromeDebugProxy', operatingSystem: Platform.operatingSystem, @@ -208,32 +150,11 @@ class ChromeProxyService implements VmServiceInterface { skipLists, executionContext, expressionCompiler, - sendClientRequest, - useWebSocket: useWebSocket, ); safeUnawaited(service.createIsolate(appConnection, newConnection: true)); return service; } - /// Completes the hot reload completer associated with the response ID. - void completeHotReload(HotReloadResponse response) { - final completer = _pendingHotReload; - _pendingHotReload = null; - if (completer != null) { - if (response.success) { - completer.complete(response); - } else { - completer.completeError( - response.errorMessage ?? 'Unknown client error during hot reload', - ); - } - } else { - _logger.warning( - 'Received hot reload response but no pending completer was found (id: ${response.id})', - ); - } - } - /// Reinitializes any caches so that they can be recomputed across hot reload. /// /// We use the [ModifiedModuleReport] to more efficiently invalidate caches. @@ -341,6 +262,7 @@ class ChromeProxyService implements VmServiceInterface { /// /// If [newConnection] is true, this method does not recompute metadata /// information as the metadata couldn't have changed. + @override Future createIsolate( AppConnection appConnection, { bool newConnection = false, @@ -406,9 +328,9 @@ class ChromeProxyService implements VmServiceInterface { // Listen for `registerExtension` and `postEvent` calls. _setUpChromeConsoleListeners(isolateRef); - _vm.isolates?.add(isolateRef); + vm.isolates?.add(isolateRef); - _streamNotify( + streamNotify( 'Isolate', Event( kind: EventKind.kIsolateStart, @@ -416,7 +338,7 @@ class ChromeProxyService implements VmServiceInterface { isolate: isolateRef, ), ); - _streamNotify( + streamNotify( 'Isolate', Event( kind: EventKind.kIsolateRunnable, @@ -429,7 +351,7 @@ class ChromeProxyService implements VmServiceInterface { // isolate, but devtools doesn't recognize extensions after a page refresh // otherwise. for (final extensionRpc in await inspector.getExtensionRpcs()) { - _streamNotify( + streamNotify( 'Isolate', Event( kind: EventKind.kServiceExtensionAdded, @@ -443,7 +365,7 @@ class ChromeProxyService implements VmServiceInterface { // kPausePostRequest event to notify client that the app is paused so that // it can resume: if (hasPendingRestart) { - _streamNotify( + streamNotify( 'Debug', Event( kind: EventKind.kPausePostRequest, @@ -454,12 +376,13 @@ class ChromeProxyService implements VmServiceInterface { } // The service is considered initialized when the first isolate is created. - if (!_initializedCompleter.isCompleted) _initializedCompleter.complete(); + if (!initializedCompleter.isCompleted) initializedCompleter.complete(); } /// Should be called when there is a hot restart or full page refresh. /// /// Clears out the [_inspector] and all related cached information. + @override void destroyIsolate() { _logger.fine('Destroying isolate'); if (!_isIsolateRunning) return; @@ -467,10 +390,10 @@ class ChromeProxyService implements VmServiceInterface { final isolate = inspector.isolate; final isolateRef = inspector.isolateRef; - _initializedCompleter = Completer(); + initializedCompleter = Completer(); _startedCompleter = Completer(); _compilerCompleter = Completer(); - _streamNotify( + streamNotify( 'Isolate', Event( kind: EventKind.kIsolateExit, @@ -478,7 +401,7 @@ class ChromeProxyService implements VmServiceInterface { isolate: isolateRef, ), ); - _vm.isolates?.removeWhere((ref) => ref.id == isolate.id); + vm.isolates?.removeWhere((ref) => ref.id == isolate.id); _inspector = null; _expressionEvaluator?.close(); _consoleSubscription?.cancel(); @@ -523,7 +446,7 @@ class ChromeProxyService implements VmServiceInterface { @override Future addBreakpointAtEntry(String isolateId, String functionId) { - return _rpcNotSupportedFuture('addBreakpointAtEntry'); + return rpcNotSupportedFuture('addBreakpointAtEntry'); } @override @@ -625,11 +548,6 @@ class ChromeProxyService implements VmServiceInterface { } } - @override - Future clearVMTimeline() { - return _rpcNotSupportedFuture('clearVMTimeline'); - } - Future _getEvaluationResult( String isolateId, Future Function() evaluation, @@ -842,46 +760,6 @@ class ChromeProxyService implements VmServiceInterface { }, (result) => DwdsEvent.evaluateInFrame(expression, result)); } - @override - Future getAllocationProfile( - String isolateId, { - bool? gc, - bool? reset, - }) { - return _rpcNotSupportedFuture('getAllocationProfile'); - } - - @override - Future getClassList(String isolateId) { - // See dart-lang/webdev/issues/971. - return _rpcNotSupportedFuture('getClassList'); - } - - @override - Future getFlagList() { - return wrapInErrorHandlerAsync('getFlagList', _getFlagList); - } - - Future _getFlagList() { - final flags = _currentVmServiceFlags.entries.map( - (entry) => Flag(name: entry.key, valueAsString: '${entry.value}'), - ); - - return Future.value(FlagList(flags: flags.toList())); - } - - @override - Future getInstances( - String isolateId, - String classId, - int limit, { - bool? includeImplementers, - bool? includeSubclasses, - String? idZoneId, - }) { - return _rpcNotSupportedFuture('getInstances'); - } - @override Future getIsolate(String isolateId) => wrapInErrorHandlerAsync('getIsolate', () => _getIsolate(isolateId)); @@ -1030,32 +908,10 @@ class ChromeProxyService implements VmServiceInterface { Future _getVM() { return captureElapsedTime(() async { await isInitialized; - return _vm; + return vm; }, (result) => DwdsEvent.getVM()); } - @override - Future getVMTimeline({ - int? timeOriginMicros, - int? timeExtentMicros, - }) { - return _rpcNotSupportedFuture('getVMTimeline'); - } - - @override - Future getVMTimelineFlags() { - return _rpcNotSupportedFuture('getVMTimelineFlags'); - } - - @override - Future getVersion() => - wrapInErrorHandlerAsync('getVersion', _getVersion); - - Future _getVersion() async { - final version = semver.Version.parse(vmServiceVersion); - return Version(major: version.major, minor: version.minor); - } - @override Future invoke( String isolateId, @@ -1086,14 +942,9 @@ class ChromeProxyService implements VmServiceInterface { return _instanceRef(remote); } - @override - Future kill(String isolateId) { - return _rpcNotSupportedFuture('kill'); - } - @override Stream onEvent(String streamId) { - return _streamControllers.putIfAbsent(streamId, () { + return streamControllers.putIfAbsent(streamId, () { switch (streamId) { case EventStreams.kExtension: return StreamController.broadcast(); @@ -1181,7 +1032,7 @@ class ChromeProxyService implements VmServiceInterface { @override Future registerService(String service, String alias) { - return _rpcNotSupportedFuture('registerService'); + return rpcNotSupportedFuture('registerService'); } @override @@ -1203,11 +1054,7 @@ class ChromeProxyService implements VmServiceInterface { ], }; try { - if (useWebSocket) { - await _performWebSocketHotReload(); - } else { - await _performClientSideHotReload(isolateId); - } + await _performClientSideHotReload(isolateId); } catch (e) { _logger.info('Hot reload failed: $e'); return getFailedReloadReport(e.toString()); @@ -1295,7 +1142,7 @@ class ChromeProxyService implements VmServiceInterface { // This lets the client know that we're ready for breakpoint management // and a resume. - _streamNotify( + streamNotify( 'Debug', Event( kind: EventKind.kPausePostRequest, @@ -1305,37 +1152,6 @@ class ChromeProxyService implements VmServiceInterface { ); } - /// Performs a WebSocket-based hot reload by sending a request and waiting for a response. - /// If [requestId] is provided, it will be used for the request; otherwise, a new one is generated. - Future _performWebSocketHotReload({String? requestId}) async { - final id = requestId ?? createId(); - if (_pendingHotReload != null) { - throw StateError('A hot reload is already pending.'); - } - final completer = Completer(); - _pendingHotReload = completer; - const timeout = Duration(seconds: 10); - - _logger.info('Issuing HotReloadRequest with ID ($id) to client.'); - sendClientRequest(HotReloadRequest((b) => b.id = id)); - - final response = await completer.future.timeout( - timeout, - onTimeout: - () => - throw TimeoutException( - 'Client did not respond to hot reload request', - timeout, - ), - ); - - if (!response.success) { - throw Exception( - response.errorMessage ?? 'Client reported hot reload failure.', - ); - } - } - @override Future removeBreakpoint(String isolateId, String breakpointId) => wrapInErrorHandlerAsync( @@ -1366,8 +1182,8 @@ class ChromeProxyService implements VmServiceInterface { }) async { // If there is a subscriber listening for a resume event after hot-restart, // then add the event to the stream and skip processing it. - if (_resumeAfterRestartEventsController.hasListener) { - _resumeAfterRestartEventsController.add(isolateId); + if (resumeAfterRestartEventsController.hasListener) { + resumeAfterRestartEventsController.add(isolateId); return Success(); } @@ -1431,12 +1247,12 @@ class ChromeProxyService implements VmServiceInterface { wrapInErrorHandlerAsync('setFlag', () => _setFlag(name, value)); Future _setFlag(String name, String value) async { - if (!_currentVmServiceFlags.containsKey(name)) { - return _rpcNotSupportedFuture('setFlag'); + if (!currentVmServiceFlags.containsKey(name)) { + return rpcNotSupportedFuture('setFlag'); } assert(value == 'true' || value == 'false'); - _currentVmServiceFlags[name] = value == 'true'; + currentVmServiceFlags[name] = value == 'true'; return Success(); } @@ -1447,7 +1263,7 @@ class ChromeProxyService implements VmServiceInterface { String libraryId, bool isDebuggable, ) { - return _rpcNotSupportedFuture('setLibraryDebuggable'); + return rpcNotSupportedFuture('setLibraryDebuggable'); } @override @@ -1466,31 +1282,19 @@ class ChromeProxyService implements VmServiceInterface { wrapInErrorHandlerAsync('setVMName', () => _setVMName(name)); Future _setVMName(String name) async { - _vm.name = name; - _streamNotify( + vm.name = name; + streamNotify( 'VM', Event( kind: EventKind.kVMUpdate, timestamp: DateTime.now().millisecondsSinceEpoch, // We are not guaranteed to have an isolate at this point in time. isolate: null, - )..vm = toVMRef(_vm), + )..vm = toVMRef(vm), ); return Success(); } - @override - Future setVMTimelineFlags(List recordedStreams) { - return _rpcNotSupportedFuture('setVMTimelineFlags'); - } - - @override - Future streamCancel(String streamId) { - // TODO: We should implement this (as we've already implemented - // streamListen). - return _rpcNotSupportedFuture('streamCancel'); - } - @override Future streamListen(String streamId) => wrapInErrorHandlerAsync('streamListen', () => _streamListen(streamId)); @@ -1502,20 +1306,6 @@ class ChromeProxyService implements VmServiceInterface { return Success(); } - @override - Future clearCpuSamples(String isolateId) { - return _rpcNotSupportedFuture('clearCpuSamples'); - } - - @override - Future getCpuSamples( - String isolateId, - int timeOriginMicros, - int timeExtentMicros, - ) { - return _rpcNotSupportedFuture('getCpuSamples'); - } - /// Returns a streamController that listens for console logs from chrome and /// adds all events passing [filter] to the stream. StreamController _chromeConsoleStreamController( @@ -1580,6 +1370,7 @@ class ChromeProxyService implements VmServiceInterface { /// Parses the [BatchedDebugEvents] and emits corresponding Dart VM Service /// protocol [Event]s. + @override void parseBatchedDebugEvents(BatchedDebugEvents debugEvents) { for (final debugEvent in debugEvents.events) { parseDebugEvent(debugEvent); @@ -1588,12 +1379,13 @@ class ChromeProxyService implements VmServiceInterface { /// Parses the [DebugEvent] and emits a corresponding Dart VM Service /// protocol [Event]. + @override void parseDebugEvent(DebugEvent debugEvent) { if (terminatingIsolates) return; if (!_isIsolateRunning) return; final isolateRef = inspector.isolateRef; - _streamNotify( + streamNotify( EventStreams.kExtension, Event( kind: EventKind.kExtension, @@ -1609,6 +1401,7 @@ class ChromeProxyService implements VmServiceInterface { /// Parses the [RegisterEvent] and emits a corresponding Dart VM Service /// protocol [Event]. + @override void parseRegisterEvent(RegisterEvent registerEvent) { if (terminatingIsolates) return; if (!_isIsolateRunning) return; @@ -1618,7 +1411,7 @@ class ChromeProxyService implements VmServiceInterface { final service = registerEvent.eventData; isolate.extensionRPCs?.add(service); - _streamNotify( + streamNotify( EventStreams.kIsolate, Event( kind: EventKind.kServiceExtensionAdded, @@ -1648,7 +1441,7 @@ class ChromeProxyService implements VmServiceInterface { if (event.args[1].type != 'object') break; final inspectee = await _instanceRef(event.args[1]); - _streamNotify( + streamNotify( EventStreams.kDebug, Event( kind: EventKind.kInspect, @@ -1674,14 +1467,8 @@ class ChromeProxyService implements VmServiceInterface { }); } - void _streamNotify(String streamId, Event event) { - final controller = _streamControllers[streamId]; - if (controller == null) return; - controller.add(event); - } - Future _firstStreamEvent(String streamId, String eventKind) { - final controller = _streamControllers[streamId]!; + final controller = streamControllers[streamId]!; return controller.stream.firstWhere((event) => event.kind == eventKind); } @@ -1716,7 +1503,7 @@ class ChromeProxyService implements VmServiceInterface { zone: await _instanceRef(logParams['zone']), ); - _streamNotify( + streamNotify( EventStreams.kLogging, Event( kind: EventKind.kLogging, @@ -1759,14 +1546,9 @@ class ChromeProxyService implements VmServiceInterface { return logParams; } - @override - Future getVMTimelineMicros() { - return _rpcNotSupportedFuture('getVMTimelineMicros'); - } - @override Future yieldControlToDDS(String uri) async { - final canYield = DebugService.yieldControlToDDS(uri); + final canYield = ChromeDebugService.yieldControlToDDS(uri); if (!canYield) { throw RPCError( @@ -1777,115 +1559,11 @@ class ChromeProxyService implements VmServiceInterface { } } - @override - Future getInboundReferences( - String isolateId, - String targetId, - int limit, { - String? idZoneId, - }) { - return _rpcNotSupportedFuture('getInboundReferences'); - } - - @override - Future getRetainingPath( - String isolateId, - String targetId, - int limit, { - String? idZoneId, - }) { - return _rpcNotSupportedFuture('getRetainingPath'); - } - - @override - Future requestHeapSnapshot(String isolateId) { - return _rpcNotSupportedFuture('requestHeapSnapshot'); - } - - @override - Future getIsolateGroup(String isolateGroupId) { - return _rpcNotSupportedFuture('getIsolateGroup'); - } - - @override - Future getIsolateGroupMemoryUsage(String isolateGroupId) { - return _rpcNotSupportedFuture('getIsolateGroupMemoryUsage'); - } - - @override - Future getSupportedProtocols() => - wrapInErrorHandlerAsync('getSupportedProtocols', _getSupportedProtocols); - - Future _getSupportedProtocols() async { - final version = semver.Version.parse(vmServiceVersion); - return ProtocolList( - protocols: [ - Protocol( - protocolName: 'VM Service', - major: version.major, - minor: version.minor, - ), - ], - ); - } - Future _instanceRef(RemoteObject? obj) async { final instance = obj == null ? null : await inspector.instanceRefFor(obj); return instance ?? InstanceHelper.kNullInstanceRef; } - static RPCError _rpcNotSupported(String method) { - return RPCError( - method, - RPCErrorKind.kMethodNotFound.code, - '$method: Not supported on web devices', - ); - } - - static Future _rpcNotSupportedFuture(String method) { - return Future.error(_rpcNotSupported(method)); - } - - @override - Future getProcessMemoryUsage() => - _rpcNotSupportedFuture('getProcessMemoryUsage'); - - @override - Future getPorts(String isolateId) => throw UnimplementedError(); - - @override - Future getAllocationTraces( - String isolateId, { - int? timeOriginMicros, - int? timeExtentMicros, - String? classId, - }) => throw UnimplementedError(); - - @override - Future setTraceClassAllocation( - String isolateId, - String classId, - bool enable, - ) => throw UnimplementedError(); - - @override - Future setBreakpointState( - String isolateId, - String breakpointId, - bool enable, - ) => throw UnimplementedError(); - - @override - Future streamCpuSamplesWithUserTag(List userTags) => - _rpcNotSupportedFuture('streamCpuSamplesWithUserTag'); - - /// Prevent DWDS from blocking Dart SDK rolls if changes in package:vm_service - /// are unimplemented in DWDS. - @override - dynamic noSuchMethod(Invocation invocation) { - return super.noSuchMethod(invocation); - } - /// Validate that isolateId matches the current isolate we're connected to and /// return that isolate. /// @@ -1939,5 +1617,3 @@ const _stderrTypes = ['error']; /// The `type`s of [ConsoleAPIEvent]s that are treated as `stdout` logs. const _stdoutTypes = ['log', 'info', 'warning']; - -const _pauseIsolatesOnStartFlag = 'pause_isolates_on_start'; diff --git a/dwds/lib/src/services/debug_service.dart b/dwds/lib/src/services/debug_service.dart index ac90a0e17..a9c2537e2 100644 --- a/dwds/lib/src/services/debug_service.dart +++ b/dwds/lib/src/services/debug_service.dart @@ -17,6 +17,7 @@ import 'package:dwds/src/events.dart'; import 'package:dwds/src/readers/asset_reader.dart'; import 'package:dwds/src/services/chrome_proxy_service.dart'; import 'package:dwds/src/services/expression_compiler.dart'; +import 'package:dwds/src/services/web_socket_proxy_service.dart'; import 'package:dwds/src/utilities/server.dart'; import 'package:dwds/src/utilities/shared.dart'; import 'package:logging/logging.dart'; @@ -126,15 +127,28 @@ Future _handleSseConnections( } } +/// Common interface for debug services (Chrome or WebSocket based). +abstract class DebugService { + String get hostname; + int get port; + String get uri; + Future get encodedUri; + ServiceExtensionRegistry get serviceExtensionRegistry; + Future close(); +} + /// A Dart Web Debug Service. /// /// Creates a [ChromeProxyService] from an existing Chrome instance. -class DebugService { +class ChromeDebugService implements DebugService { static String? _ddsUri; - final VmServiceInterface chromeProxyService; + final ChromeProxyService chromeProxyService; + @override final String hostname; + @override final ServiceExtensionRegistry serviceExtensionRegistry; + @override final int port; final String authToken; final HttpServer _server; @@ -149,7 +163,7 @@ class DebugService { /// All subsequent calls to [close] will return this future. Future? _closed; - DebugService._( + ChromeDebugService._( this.chromeProxyService, this.hostname, this.port, @@ -162,6 +176,7 @@ class DebugService { this._urlEncoder, ); + @override Future close() => _closed ??= Future.wait([ _server.close(), @@ -183,6 +198,7 @@ class DebugService { return _dds!; } + @override String get uri { final dds = _dds; if (_spawnDds && dds != null) { @@ -200,6 +216,7 @@ class DebugService { } String? _encodedUri; + @override Future get encodedUri async { if (_encodedUri != null) return _encodedUri!; var encoded = uri; @@ -218,7 +235,7 @@ class DebugService { return true; } - static Future start( + static Future start( String hostname, RemoteDebugger remoteDebugger, ExecutionContext executionContext, @@ -231,7 +248,6 @@ class DebugService { int? ddsPort, bool useSse = false, ExpressionCompiler? expressionCompiler, - required SendClientRequest sendClientRequest, }) async { final root = assetReader.basePath; final chromeProxyService = await ChromeProxyService.create( @@ -241,7 +257,6 @@ class DebugService { appConnection, executionContext, expressionCompiler, - sendClientRequest, ); final authToken = _makeAuthToken(); final serviceExtensionRegistry = ServiceExtensionRegistry(); @@ -290,7 +305,7 @@ class DebugService { _logger.warning('Error serving requests', e); emitEvent(DwdsEvent.httpRequestException('DebugService', '$e:$s')); }); - return DebugService._( + return ChromeDebugService._( chromeProxyService, server.address.host, server.port, @@ -305,6 +320,154 @@ class DebugService { } } +/// Defines callbacks for sending messages to the connected client. +/// Returns the number of clients the request was successfully sent to. +typedef SendClientRequest = int Function(Object request); + +/// WebSocket-based debug service for web debugging. +class WebSocketDebugService implements DebugService { + @override + final String hostname; + @override + final int port; + final String authToken; + final HttpServer _server; + final WebSocketProxyService _webSocketProxyService; + final ServiceExtensionRegistry _serviceExtensionRegistry; + final UrlEncoder? _urlEncoder; + + Future? _closed; + DartDevelopmentServiceLauncher? _dds; + String? _encodedUri; + + WebSocketDebugService._( + this.hostname, + this.port, + this.authToken, + this._webSocketProxyService, + this._serviceExtensionRegistry, + this._server, + this._urlEncoder, + ); + + /// Returns the WebSocketProxyService instance. + WebSocketProxyService get webSocketProxyService => _webSocketProxyService; + + /// Returns the ServiceExtensionRegistry instance. + @override + ServiceExtensionRegistry get serviceExtensionRegistry => + _serviceExtensionRegistry; + + /// Closes the debug service and associated resources. + @override + Future close() => + _closed ??= Future.wait([ + _server.close(), + if (_dds != null) _dds!.shutdown(), + ]); + + /// Starts DDS (Dart Development Service). + Future startDartDevelopmentService({ + int? ddsPort, + }) async { + const timeout = Duration(seconds: 10); + + try { + _dds = await DartDevelopmentServiceLauncher.start( + remoteVmServiceUri: Uri( + scheme: 'http', + host: hostname, + port: port, + path: authToken, + ), + serviceUri: Uri(scheme: 'http', host: hostname, port: ddsPort ?? 0), + ).timeout(timeout); + } catch (e) { + throw Exception('Failed to start DDS: $e'); + } + return _dds!; + } + + @override + String get uri => + Uri(scheme: 'ws', host: hostname, port: port, path: authToken).toString(); + + @override + Future get encodedUri async { + if (_encodedUri != null) return _encodedUri!; + var encoded = uri; + if (_urlEncoder != null) encoded = await _urlEncoder(encoded); + return _encodedUri = encoded; + } + + static Future start( + String hostname, + AppConnection appConnection, { + required SendClientRequest sendClientRequest, + UrlEncoder? urlEncoder, + }) async { + final authToken = _makeAuthToken(); + final serviceExtensionRegistry = ServiceExtensionRegistry(); + + final webSocketProxyService = await WebSocketProxyService.create( + sendClientRequest, + appConnection, + ); + + final handler = _createWebSocketHandler( + serviceExtensionRegistry, + webSocketProxyService, + ); + + final server = await startHttpServer(hostname, port: 44456); + serveHttpRequests(server, handler, (e, s) { + Logger('WebSocketDebugService').warning('Error serving requests', e); + }); + + return WebSocketDebugService._( + server.address.host, + server.port, + authToken, + webSocketProxyService, + serviceExtensionRegistry, + server, + urlEncoder, + ); + } + + /// Creates the WebSocket handler for incoming connections. + static dynamic _createWebSocketHandler( + ServiceExtensionRegistry serviceExtensionRegistry, + WebSocketProxyService webSocketProxyService, + ) { + return webSocketHandler((WebSocketChannel webSocket) { + final responseController = StreamController>(); + webSocket.sink.addStream(responseController.stream.map(jsonEncode)); + + final inputStream = webSocket.stream.map((value) { + if (value is List) { + value = utf8.decode(value); + } else if (value is! String) { + throw StateError( + 'Unexpected value type from web socket: ${value.runtimeType}', + ); + } + return Map.from(jsonDecode(value)); + }); + + ++_clientsConnected; + VmServerConnection( + inputStream, + responseController.sink, + serviceExtensionRegistry, + webSocketProxyService, + ).done.whenComplete(() { + --_clientsConnected; + }); + }); + } +} + // Creates a random auth token for more secure connections. String _makeAuthToken() { final tokenBytes = 8; diff --git a/dwds/lib/src/services/proxy_service.dart b/dwds/lib/src/services/proxy_service.dart new file mode 100644 index 000000000..7af76f08e --- /dev/null +++ b/dwds/lib/src/services/proxy_service.dart @@ -0,0 +1,387 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:async'; + +import 'package:dwds/data/debug_event.dart'; +import 'package:dwds/data/hot_reload_response.dart'; +import 'package:dwds/data/register_event.dart'; +import 'package:dwds/data/service_extension_response.dart'; +import 'package:dwds/src/connections/app_connection.dart'; +import 'package:dwds/src/events.dart'; +import 'package:dwds/src/utilities/shared.dart'; +import 'package:pub_semver/pub_semver.dart' as semver; +import 'package:vm_service/vm_service.dart' as vm_service; +import 'package:vm_service_interface/vm_service_interface.dart'; + +const pauseIsolatesOnStartFlag = 'pause_isolates_on_start'; + +/// Abstract base class for VM service proxy implementations. +abstract class ProxyService implements VmServiceInterface { + /// Cache of all existing StreamControllers. + /// + /// These are all created through [onEvent]. + final Map> _streamControllers = {}; + + /// The root `VM` instance. + final vm_service.VM _vm; + + /// Signals when isolate is initialized. + Future get isInitialized => initializedCompleter.future; + Completer initializedCompleter = Completer(); + + /// The flags that can be set at runtime via [setFlag] and their respective + /// values. + final Map _currentVmServiceFlags = { + pauseIsolatesOnStartFlag: false, + }; + + /// The value of the [pauseIsolatesOnStartFlag]. + /// + /// This value can be updated at runtime via [setFlag]. + bool get pauseIsolatesOnStart => + _currentVmServiceFlags[pauseIsolatesOnStartFlag] ?? false; + + /// Stream controller for resume events after restart. + final _resumeAfterRestartEventsController = + StreamController.broadcast(); + + /// A global stream of resume events for hot restart. + /// + /// The values in the stream are the isolates IDs for the resume event. + /// + /// IMPORTANT: This should only be listened to during a hot-restart or page + /// refresh. The debugger ignores any resume events as long as there is a + /// subscriber to this stream. + Stream get resumeAfterRestartEventsStream => + _resumeAfterRestartEventsController.stream; + + /// Whether or not the connected app has a pending restart. + bool get hasPendingRestart => _resumeAfterRestartEventsController.hasListener; + + // Protected accessors for subclasses + vm_service.VM get vm => _vm; + Map> get streamControllers => + _streamControllers; + StreamController get resumeAfterRestartEventsController => + _resumeAfterRestartEventsController; + Map get currentVmServiceFlags => _currentVmServiceFlags; + + ProxyService(this._vm); + + /// Sends events to stream controllers. + void streamNotify(String streamId, vm_service.Event event) { + final controller = _streamControllers[streamId]; + if (controller == null) return; + controller.add(event); + } + + /// Returns a broadcast stream for the given streamId. + @override + Stream onEvent(String streamId) { + return _streamControllers.putIfAbsent(streamId, () { + return StreamController.broadcast(); + }).stream; + } + + @override + Future streamListen(String streamId) => + wrapInErrorHandlerAsync('streamListen', () => _streamListen(streamId)); + + Future _streamListen(String streamId) async { + onEvent(streamId); + return vm_service.Success(); + } + + @override + Future streamCancel(String streamId) { + // TODO: We should implement this (as we've already implemented + // streamListen). + return _rpcNotSupportedFuture('streamCancel'); + } + + @override + Future getVM() => wrapInErrorHandlerAsync('getVM', _getVM); + + Future _getVM() { + return captureElapsedTime(() async { + return _vm; + }, (result) => DwdsEvent.getVM()); + } + + @override + Future getFlagList() => + wrapInErrorHandlerAsync('getFlagList', _getFlagList); + + Future _getFlagList() async { + final flags = _currentVmServiceFlags.entries.map( + (entry) => + vm_service.Flag(name: entry.key, valueAsString: '${entry.value}'), + ); + return vm_service.FlagList(flags: flags.toList()); + } + + @override + Future setFlag(String name, String value) => + wrapInErrorHandlerAsync('setFlag', () => _setFlag(name, value)); + + Future _setFlag(String name, String value) async { + if (!_currentVmServiceFlags.containsKey(name)) { + throw vm_service.RPCError( + 'setFlag', + vm_service.RPCErrorKind.kInvalidRequest.code, + 'Cannot set flag "$name" (invalid flag)', + ); + } + + assert(value == 'true' || value == 'false'); + _currentVmServiceFlags[name] = value == 'true'; + return vm_service.Success(); + } + + @override + Future getSupportedProtocols() => + wrapInErrorHandlerAsync('getSupportedProtocols', _getSupportedProtocols); + + Future _getSupportedProtocols() async { + final version = semver.Version.parse(vm_service.vmServiceVersion); + return vm_service.ProtocolList( + protocols: [ + vm_service.Protocol( + protocolName: 'VM Service', + major: version.major, + minor: version.minor, + ), + ], + ); + } + + @override + Future getVersion() => + wrapInErrorHandlerAsync('getVersion', _getVersion); + + Future _getVersion() async { + final version = semver.Version.parse(vm_service.vmServiceVersion); + return vm_service.Version(major: version.major, minor: version.minor); + } + + /// Parses the [BatchedDebugEvents] and emits corresponding Dart VM Service + /// protocol [Event]s. + void parseBatchedDebugEvents(BatchedDebugEvents debugEvents) { + for (final debugEvent in debugEvents.events) { + parseDebugEvent(debugEvent); + } + } + + /// Parses the [DebugEvent] and emits a corresponding Dart VM Service + /// protocol [Event]. + void parseDebugEvent(DebugEvent debugEvent); + + /// Parses the [RegisterEvent] and emits a corresponding Dart VM Service + /// protocol [Event]. + void parseRegisterEvent(RegisterEvent registerEvent); + + /// Completes hot reload with response from client. + /// + /// Default implementation throws UnimplementedError. + /// Override in subclasses that support hot reload completion. + void completeHotReload(HotReloadResponse response) { + throw UnimplementedError('completeHotReload not supported'); + } + + /// Completes service extension with response from client. + /// + /// Default implementation throws UnimplementedError. + /// Override in subclasses that support service extension completion. + void completeServiceExtension(ServiceExtensionResponse response) { + throw UnimplementedError('completeServiceExtension not supported'); + } + + /// Standard RPC error for unsupported methods. + static vm_service.RPCError _rpcNotSupported(String method) { + return vm_service.RPCError( + method, + vm_service.RPCErrorKind.kMethodNotFound.code, + '$method: Not supported on web devices', + ); + } + + /// Standard future error for unsupported methods. + static Future _rpcNotSupportedFuture(String method) { + return Future.error(_rpcNotSupported(method)); + } + + /// Protected accessor for _rpcNotSupportedFuture for subclasses + Future rpcNotSupportedFuture(String method) { + return _rpcNotSupportedFuture(method); + } + + // Default implementations for unsupported methods + @override + Future getAllocationProfile( + String isolateId, { + bool? gc, + bool? reset, + }) { + return _rpcNotSupportedFuture('getAllocationProfile'); + } + + @override + Future getClassList(String isolateId) { + return _rpcNotSupportedFuture('getClassList'); + } + + @override + Future getInstances( + String isolateId, + String classId, + int limit, { + bool? includeImplementers, + bool? includeSubclasses, + String? idZoneId, + }) { + return _rpcNotSupportedFuture('getInstances'); + } + + @override + Future kill(String isolateId) { + return _rpcNotSupportedFuture('kill'); + } + + @override + Future clearVMTimeline() { + return _rpcNotSupportedFuture('clearVMTimeline'); + } + + @override + Future getVMTimeline({ + int? timeOriginMicros, + int? timeExtentMicros, + }) { + return _rpcNotSupportedFuture('getVMTimeline'); + } + + @override + Future getVMTimelineFlags() { + return _rpcNotSupportedFuture('getVMTimelineFlags'); + } + + @override + Future setVMTimelineFlags(List recordedStreams) { + return _rpcNotSupportedFuture('setVMTimelineFlags'); + } + + @override + Future getVMTimelineMicros() { + return _rpcNotSupportedFuture('getVMTimelineMicros'); + } + + @override + Future getInboundReferences( + String isolateId, + String targetId, + int limit, { + String? idZoneId, + }) { + return _rpcNotSupportedFuture('getInboundReferences'); + } + + @override + Future getRetainingPath( + String isolateId, + String targetId, + int limit, { + String? idZoneId, + }) { + return _rpcNotSupportedFuture('getRetainingPath'); + } + + @override + Future requestHeapSnapshot(String isolateId) { + return _rpcNotSupportedFuture('requestHeapSnapshot'); + } + + @override + Future getIsolateGroup(String isolateGroupId) { + return _rpcNotSupportedFuture('getIsolateGroup'); + } + + @override + Future getIsolateGroupMemoryUsage( + String isolateGroupId, + ) { + return _rpcNotSupportedFuture('getIsolateGroupMemoryUsage'); + } + + @override + Future getProcessMemoryUsage() => + _rpcNotSupportedFuture('getProcessMemoryUsage'); + + @override + Future getPorts(String isolateId) => + throw UnimplementedError(); + + @override + Future getAllocationTraces( + String isolateId, { + int? timeOriginMicros, + int? timeExtentMicros, + String? classId, + }) => throw UnimplementedError(); + + @override + Future setTraceClassAllocation( + String isolateId, + String classId, + bool enable, + ) => throw UnimplementedError(); + + @override + Future setBreakpointState( + String isolateId, + String breakpointId, + bool enable, + ) => throw UnimplementedError(); + + @override + Future streamCpuSamplesWithUserTag( + List userTags, + ) => _rpcNotSupportedFuture('streamCpuSamplesWithUserTag'); + + @override + Future getCpuSamples( + String isolateId, + int timeOriginMicros, + int timeExtentMicros, + ) { + return _rpcNotSupportedFuture('getCpuSamples'); + } + + @override + Future clearCpuSamples(String isolateId) { + return _rpcNotSupportedFuture('clearCpuSamples'); + } + + /// Creates a new isolate for debugging. + /// + /// Implementations should handle isolate lifecycle management according to + /// their specific debugging mode (Chrome vs WebSocket). + Future createIsolate( + AppConnection appConnection, { + bool newConnection = false, + }); + + /// Destroys the isolate and cleans up debugging state. + /// + /// Implementations should handle cleanup according to their specific + /// debugging mode and connection management strategy. + void destroyIsolate(); + + /// Prevent DWDS from blocking Dart SDK rolls if changes in package:vm_service + /// are unimplemented in DWDS. + @override + dynamic noSuchMethod(Invocation invocation) { + return super.noSuchMethod(invocation); + } +} diff --git a/dwds/lib/src/services/web_socket_proxy_service.dart b/dwds/lib/src/services/web_socket_proxy_service.dart new file mode 100644 index 000000000..4d5503e7c --- /dev/null +++ b/dwds/lib/src/services/web_socket_proxy_service.dart @@ -0,0 +1,914 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:async'; +import 'dart:convert'; + +import 'package:dwds/data/debug_event.dart'; +import 'package:dwds/data/hot_reload_request.dart'; +import 'package:dwds/data/hot_reload_response.dart'; +import 'package:dwds/data/register_event.dart'; +import 'package:dwds/data/service_extension_request.dart'; +import 'package:dwds/data/service_extension_response.dart'; +import 'package:dwds/src/connections/app_connection.dart'; +import 'package:dwds/src/events.dart'; +import 'package:dwds/src/services/proxy_service.dart'; +import 'package:dwds/src/utilities/dart_uri.dart'; +import 'package:dwds/src/utilities/shared.dart'; +import 'package:logging/logging.dart'; +import 'package:vm_service/vm_service.dart' as vm_service; +import 'package:vm_service/vm_service.dart'; + +/// Defines callbacks for sending messages to the connected client. +/// Returns the number of clients the request was successfully sent to. +typedef SendClientRequest = int Function(Object request); + +const _pauseIsolatesOnStartFlag = 'pause_isolates_on_start'; + +/// Tracks hot reload responses from multiple browser windows/tabs. +class _HotReloadTracker { + final String requestId; + final Completer completer; + final int expectedResponses; + final List responses = []; + final Timer timeoutTimer; + + _HotReloadTracker({ + required this.requestId, + required this.completer, + required this.expectedResponses, + required this.timeoutTimer, + }); + + bool get isComplete => responses.length >= expectedResponses; + + void addResponse(HotReloadResponse response) { + responses.add(response); + } + + bool get allSuccessful => responses.every((r) => r.success); + + void dispose() { + timeoutTimer.cancel(); + } +} + +/// Tracks service extension responses from multiple browser windows/tabs. +class _ServiceExtensionTracker { + final String requestId; + final Completer completer; + final int expectedResponses; + final List responses = []; + final Timer timeoutTimer; + + _ServiceExtensionTracker({ + required this.requestId, + required this.completer, + required this.expectedResponses, + required this.timeoutTimer, + }); + + bool get isComplete => responses.length >= expectedResponses; + + void addResponse(ServiceExtensionResponse response) { + responses.add(response); + } + + bool get allSuccessful => responses.every((r) => r.success); + + void dispose() { + timeoutTimer.cancel(); + } +} + +/// WebSocket-based VM service proxy for web debugging. +class WebSocketProxyService extends ProxyService { + final _logger = Logger('WebSocketProxyService'); + + /// Active service extension trackers by request ID. + final Map _pendingServiceExtensionTrackers = + {}; + + /// Sends messages to the client. + final SendClientRequest sendClientRequest; + + /// App connection for this service. + AppConnection appConnection; + + /// Active hot reload trackers by request ID. + final Map _pendingHotReloads = {}; + + /// App connection cleanup subscriptions by connection instance ID. + final Map> _appConnectionDoneSubscriptions = + {}; + + /// Active connection count for this service. + int _activeConnectionCount = 0; + + /// Counter for generating unique isolate IDs across page refreshes + static int _globalIsolateIdCounter = 0; + + bool get _isIsolateRunning => _isolateRunning; + + WebSocketProxyService._( + this.sendClientRequest, + vm_service.VM vm, + this.appConnection, + ) : super(vm); // Isolate state + vm_service.IsolateRef? _isolateRef; + bool _isolateRunning = false; + vm_service.Event? _currentPauseEvent; + bool _mainHasStarted = false; + + /// Creates a new isolate for WebSocket debugging. + @override + Future createIsolate( + AppConnection appConnection, { + bool newConnection = false, + }) async { + // Update app connection + this.appConnection = appConnection; + + // Track this connection + final connectionId = appConnection.request.instanceId; + + // Check if this connection is already being tracked + final isNewConnection = + newConnection || + !_appConnectionDoneSubscriptions.containsKey(connectionId); + + if (isNewConnection) { + _activeConnectionCount++; + _logger.fine( + 'Adding new connection: $connectionId (total: $_activeConnectionCount)', + ); + } else { + _logger.fine( + 'Reconnecting existing connection: $connectionId (total: $_activeConnectionCount)', + ); + } + + // Auto-cleanup on connection close + final existingSubscription = _appConnectionDoneSubscriptions[connectionId]; + await existingSubscription?.cancel(); + _appConnectionDoneSubscriptions[connectionId] = appConnection.onDone + .asStream() + .listen((_) { + _handleConnectionClosed(connectionId); + }); + + // If we already have a running isolate, just update the connection and return + if (_isIsolateRunning && _isolateRef != null) { + _logger.fine( + 'Reusing existing isolate ${_isolateRef!.id} for connection: $connectionId', + ); + return; + } + + // Create isolate reference with unique ID + final isolateId = '${++_globalIsolateIdCounter}'; + final isolateRef = vm_service.IsolateRef( + id: isolateId, + name: 'main()', + number: isolateId, + isSystemIsolate: false, + ); + + _isolateRef = isolateRef; + _isolateRunning = true; + vm.isolates?.add(isolateRef); + final timestamp = DateTime.now().millisecondsSinceEpoch; + + _logger.fine( + 'Created new isolate: $isolateId for connection: $connectionId', + ); + + // Send lifecycle events + _streamNotify( + vm_service.EventStreams.kIsolate, + vm_service.Event( + kind: vm_service.EventKind.kIsolateStart, + timestamp: timestamp, + isolate: isolateRef, + ), + ); + _streamNotify( + vm_service.EventStreams.kIsolate, + vm_service.Event( + kind: vm_service.EventKind.kIsolateRunnable, + timestamp: timestamp, + isolate: isolateRef, + ), + ); + + // Send pause event if enabled + if (pauseIsolatesOnStart) { + final pauseEvent = vm_service.Event( + kind: vm_service.EventKind.kPauseStart, + timestamp: timestamp, + isolate: isolateRef, + ); + _currentPauseEvent = pauseEvent; + _streamNotify(vm_service.EventStreams.kDebug, pauseEvent); + } + + // Complete initialization after isolate is set up + if (!initializedCompleter.isCompleted) initializedCompleter.complete(); + } + + /// Handles a connection being closed. + void _handleConnectionClosed(String connectionId) { + _logger.fine('Connection closed: $connectionId'); + + // Only decrement if this connection was actually being tracked + if (_appConnectionDoneSubscriptions.containsKey(connectionId)) { + // Remove the subscription for this connection + _appConnectionDoneSubscriptions[connectionId]?.cancel(); + _appConnectionDoneSubscriptions.remove(connectionId); + + // Decrease active connection count + _activeConnectionCount--; + _logger.fine( + 'Removed connection: $connectionId (remaining: $_activeConnectionCount)', + ); + _logger.fine( + 'Current tracked connections: ${_appConnectionDoneSubscriptions.keys.toList()}', + ); + + // Instead of destroying the isolate immediately, check if there are still + // clients that can receive hot reload requests + if (_activeConnectionCount <= 0) { + // Double-check by asking the sendClientRequest callback how many clients are available + final actualClientCount = sendClientRequest({'type': 'ping'}); + _logger.fine( + 'Actual client count from sendClientRequest: $actualClientCount', + ); + + if (actualClientCount == 0) { + _logger.fine( + 'No clients available for hot reload, destroying isolate', + ); + destroyIsolate(); + } else { + _logger.fine( + 'Still have $actualClientCount clients available, keeping isolate alive', + ); + // Update our internal counter to match reality + _activeConnectionCount = actualClientCount; + } + } else { + _logger.fine( + 'Still have $_activeConnectionCount active connections, keeping isolate alive', + ); + } + } else { + _logger.warning( + 'Attempted to close connection that was not tracked: $connectionId', + ); + } + } + + /// Destroys the isolate and cleans up state. + @override + void destroyIsolate() { + _logger.fine('Destroying isolate'); + + if (!_isIsolateRunning) { + _logger.fine('Isolate already destroyed, ignoring'); + return; + } + + final isolateRef = _isolateRef; + + // Cancel all connection subscriptions + for (final subscription in _appConnectionDoneSubscriptions.values) { + subscription.cancel(); + } + _appConnectionDoneSubscriptions.clear(); + _activeConnectionCount = 0; + + // Send exit event + if (isolateRef != null) { + _streamNotify( + vm_service.EventStreams.kIsolate, + vm_service.Event( + kind: vm_service.EventKind.kIsolateExit, + timestamp: DateTime.now().millisecondsSinceEpoch, + isolate: isolateRef, + ), + ); + } + + vm.isolates?.removeWhere((ref) => ref.id == isolateRef?.id); + + // Reset state + _isolateRef = null; + _isolateRunning = false; + _currentPauseEvent = null; + _mainHasStarted = false; + + if (initializedCompleter.isCompleted) { + initializedCompleter = Completer(); + } + } + + /// Sends events to stream controllers. + void _streamNotify(String streamId, vm_service.Event event) { + final controller = streamControllers[streamId]; + if (controller == null) return; + controller.add(event); + } + + @override + Future setLibraryDebuggable( + String isolateId, + String libraryId, + bool isDebuggable, + ) { + return rpcNotSupportedFuture('setLibraryDebuggable'); + } + + @override + Future setIsolatePauseMode( + String isolateId, { + String? exceptionPauseMode, + bool? shouldPauseOnExit, + }) async { + // Not supported in WebSocket mode - return success for compatibility + return Success(); + } + + @override + Future getIsolate(String isolateId) => + wrapInErrorHandlerAsync('getIsolate', () => _getIsolate(isolateId)); + + Future _getIsolate(String isolateId) async { + if (!_isIsolateRunning || _isolateRef == null) { + throw vm_service.RPCError( + 'getIsolate', + vm_service.RPCErrorKind.kInvalidParams.code, + 'No running isolate found for id: $isolateId', + ); + } + if (_isolateRef!.id != isolateId) { + throw vm_service.RPCError( + 'getIsolate', + vm_service.RPCErrorKind.kInvalidParams.code, + 'Isolate with id $isolateId not found.', + ); + } + + return vm_service.Isolate( + id: _isolateRef!.id!, + name: _isolateRef!.name, + number: _isolateRef!.number, + startTime: DateTime.now().millisecondsSinceEpoch, + isSystemIsolate: _isolateRef!.isSystemIsolate, + runnable: true, + pauseEvent: _currentPauseEvent, + ); + } + + /// Adds events to stream controllers. + void addEvent(String streamId, vm_service.Event event) { + final controller = streamControllers[streamId]; + if (controller != null && !controller.isClosed) { + controller.add(event); + } else { + _logger.warning('Cannot add event to closed/missing stream: $streamId'); + } + } + + static Future create( + SendClientRequest sendClientRequest, + AppConnection appConnection, + ) async { + final vm = vm_service.VM( + name: 'WebSocketDebugProxy', + operatingSystem: 'web', + startTime: DateTime.now().millisecondsSinceEpoch, + version: 'unknown', + isolates: [], + isolateGroups: [], + systemIsolates: [], + systemIsolateGroups: [], + targetCPU: 'Web', + hostCPU: 'DWDS', + architectureBits: -1, + pid: -1, + ); + final service = WebSocketProxyService._( + sendClientRequest, + vm, + appConnection, + ); + safeUnawaited(service.createIsolate(appConnection)); + return service; + } + + /// Returns the root VM object. + @override + Future getVM() => wrapInErrorHandlerAsync('getVM', _getVM); + + Future _getVM() { + return captureElapsedTime(() async { + // Ensure the VM's isolate list is synchronized with our actual state + if (_isIsolateRunning && _isolateRef != null) { + // Make sure our isolate is in the VM's isolate list + final isolateExists = + vm.isolates?.any((ref) => ref.id == _isolateRef!.id) ?? false; + if (!isolateExists) { + vm.isolates?.add(_isolateRef!); + } + } else { + // If no isolate is running, make sure the list is empty + vm.isolates?.clear(); + } + + return vm; + }, (result) => DwdsEvent.getVM()); + } + + /// Not available in WebSocket mode. + dynamic get remoteDebugger { + throw UnsupportedError( + 'remoteDebugger not available in WebSocketProxyService.\n' + 'Called from:\n${StackTrace.current}', + ); + } + + @override + Future reloadSources( + String isolateId, { + bool? force, + bool? pause, + String? rootLibUri, + String? packagesUri, + }) async { + _logger.info('Attempting a hot reload'); + try { + await _performWebSocketHotReload(); + _logger.info('Hot reload completed successfully'); + return _ReloadReportWithMetadata(success: true); + } catch (e) { + _logger.warning('Hot reload failed: $e'); + return _ReloadReportWithMetadata(success: false, notices: [e.toString()]); + } + } + + /// Completes hot reload with response from client. + @override + void completeHotReload(HotReloadResponse response) { + final tracker = _pendingHotReloads[response.id]; + + if (tracker == null) { + _logger.warning( + 'Received hot reload response but no pending tracker found (id: ${response.id})', + ); + return; + } + + tracker.addResponse(response); + + if (tracker.isComplete) { + _pendingHotReloads.remove(response.id); + tracker.dispose(); + + if (tracker.allSuccessful) { + tracker.completer.complete(response); + } else { + final failedResponses = tracker.responses.where((r) => !r.success); + final errorMessages = failedResponses + .map((r) => r.errorMessage ?? 'Unknown error') + .join('; '); + tracker.completer.completeError( + 'Hot reload failed in some clients: $errorMessages', + ); + } + } + } + + /// Performs WebSocket-based hot reload. + Future _performWebSocketHotReload({String? requestId}) async { + final id = requestId ?? createId(); + + // Check if there's already a pending hot reload with this ID + if (_pendingHotReloads.containsKey(id)) { + throw StateError('Hot reload already pending for ID: $id'); + } + + const timeout = Duration(seconds: 10); + _logger.info('Sending HotReloadRequest with ID ($id) to client'); + + // Send the request and get the number of connected clients + final clientCount = await Future.microtask(() { + return sendClientRequest(HotReloadRequest((b) => b.id = id)); + }); + + if (clientCount == 0) { + throw StateError('No clients available for hot reload'); + } + + // Create tracker for this hot reload request + final completer = Completer(); + final timeoutTimer = Timer(timeout, () { + final tracker = _pendingHotReloads.remove(id); + if (tracker != null) { + tracker.dispose(); + if (!completer.isCompleted) { + completer.completeError( + TimeoutException( + 'Hot reload timed out - received ${tracker.responses.length}/$clientCount responses', + timeout, + ), + ); + } + } + }); + + final tracker = _HotReloadTracker( + requestId: id, + completer: completer, + expectedResponses: clientCount, + timeoutTimer: timeoutTimer, + ); + + _pendingHotReloads[id] = tracker; + + try { + final response = await completer.future; + if (!response.success) { + throw Exception(response.errorMessage ?? 'Client reported failure'); + } + } catch (e) { + // Clean up tracker if still present + final remainingTracker = _pendingHotReloads.remove(id); + remainingTracker?.dispose(); + rethrow; + } + } + + @override + Future callServiceExtension( + String method, { + String? isolateId, + Map? args, + }) => wrapInErrorHandlerAsync( + 'callServiceExtension', + () => _callServiceExtension(method, args: args), + ); + + /// Calls a service extension on the client. + Future _callServiceExtension(String method, {Map? args}) async { + final requestId = createId(); + + // Check if there's already a pending service extension with this ID + if (_pendingServiceExtensionTrackers.containsKey(requestId)) { + throw StateError( + 'Service extension call already pending for ID: $requestId', + ); + } + + final request = ServiceExtensionRequest.fromArgs( + id: requestId, + method: method, + args: + args != null ? Map.from(args) : {}, + ); + + // Send the request and get the number of connected clients + final clientCount = sendClientRequest(request); + + if (clientCount == 0) { + throw StateError('No clients available for service extension'); + } + + // Create tracker for this service extension request + const timeout = Duration(seconds: 10); + final completer = Completer(); + final timeoutTimer = Timer(timeout, () { + final tracker = _pendingServiceExtensionTrackers.remove(requestId); + if (tracker != null) { + tracker.dispose(); + if (!completer.isCompleted) { + completer.completeError( + TimeoutException( + 'Service extension $method timed out - received ${tracker.responses.length}/$clientCount responses', + timeout, + ), + ); + } + } + }); + + final tracker = _ServiceExtensionTracker( + requestId: requestId, + completer: completer, + expectedResponses: clientCount, + timeoutTimer: timeoutTimer, + ); + + _pendingServiceExtensionTrackers[requestId] = tracker; + + try { + final response = await completer.future; + + if (response.errorMessage != null) { + throw RPCError( + method, + response.errorCode ?? RPCErrorKind.kServerError.code, + response.errorMessage!, + ); + } + return Response()..json = response.result; + } catch (e) { + // Clean up tracker if still present + final remainingTracker = _pendingServiceExtensionTrackers.remove( + requestId, + ); + remainingTracker?.dispose(); + rethrow; + } + } + + /// Completes service extension with response. + @override + void completeServiceExtension(ServiceExtensionResponse response) { + final id = response.id; + + final tracker = _pendingServiceExtensionTrackers[id]; + + if (tracker == null) { + _logger.warning( + 'No pending tracker found for service extension (id: $id)', + ); + return; + } + + tracker.addResponse(response); + + if (tracker.isComplete) { + _pendingServiceExtensionTrackers.remove(id); + tracker.dispose(); + + if (tracker.allSuccessful) { + tracker.completer.complete(response); + } else { + final failedResponses = tracker.responses.where((r) => !r.success); + final errorMessages = failedResponses + .map((r) => r.errorMessage ?? 'Unknown error') + .join('; '); + tracker.completer.completeError( + 'Service extension failed in some clients: $errorMessages', + ); + } + } + } + + /// Parses the [RegisterEvent] and emits a corresponding Dart VM Service + /// protocol [Event]. + @override + void parseRegisterEvent(RegisterEvent registerEvent) { + if (!_isIsolateRunning || _isolateRef == null) { + _logger.warning('Cannot register service extension - no isolate running'); + return; + } + + final service = registerEvent.eventData; + + // Emit ServiceExtensionAdded event for tooling + final event = vm_service.Event( + kind: vm_service.EventKind.kServiceExtensionAdded, + timestamp: DateTime.now().millisecondsSinceEpoch, + isolate: _isolateRef!, + ); + event.extensionRPC = service; + + _streamNotify(vm_service.EventStreams.kIsolate, event); + } + + /// Parses the [BatchedDebugEvents] and emits corresponding Dart VM Service + /// protocol [Event]s. + @override + void parseBatchedDebugEvents(BatchedDebugEvents debugEvents) { + for (final debugEvent in debugEvents.events) { + parseDebugEvent(debugEvent); + } + } + + /// Parses the [DebugEvent] and emits a corresponding Dart VM Service + /// protocol [Event]. + @override + void parseDebugEvent(DebugEvent debugEvent) { + if (!_isIsolateRunning || _isolateRef == null) { + _logger.warning('Cannot parse debug event - no isolate running'); + return; + } + + _streamNotify( + vm_service.EventStreams.kExtension, + vm_service.Event( + kind: vm_service.EventKind.kExtension, + timestamp: DateTime.now().millisecondsSinceEpoch, + isolate: _isolateRef!, + ) + ..extensionKind = debugEvent.kind + ..extensionData = vm_service.ExtensionData.parse( + jsonDecode(debugEvent.eventData) as Map, + ), + ); + } + + @override + Future setFlag(String name, String value) => + wrapInErrorHandlerAsync('setFlag', () => _setFlag(name, value)); + + Future _setFlag(String name, String value) async { + if (!currentVmServiceFlags.containsKey(name)) { + return rpcNotSupportedFuture('setFlag'); + } + + assert(value == 'true' || value == 'false'); + final oldValue = currentVmServiceFlags[name]; + currentVmServiceFlags[name] = value == 'true'; + + // Handle pause_isolates_on_start flag changes + if (name == _pauseIsolatesOnStartFlag && + value == 'true' && + oldValue == false) { + // Send pause event for existing isolate if not already paused + if (_isIsolateRunning && + _isolateRef != null && + _currentPauseEvent == null) { + final pauseEvent = vm_service.Event( + kind: vm_service.EventKind.kPauseStart, + timestamp: DateTime.now().millisecondsSinceEpoch, + isolate: _isolateRef!, + ); + _currentPauseEvent = pauseEvent; + _streamNotify(vm_service.EventStreams.kDebug, pauseEvent); + } + } + + return Success(); + } + + @override + Future lookupResolvedPackageUris( + String isolateId, + List uris, { + bool? local, + }) => wrapInErrorHandlerAsync( + 'lookupResolvedPackageUris', + () => _lookupResolvedPackageUris(isolateId, uris), + ); + + Future _lookupResolvedPackageUris( + String _, + List uris, + ) async { + await isInitialized; + return UriList(uris: uris.map(DartUri.toResolvedUri).toList()); + } + + /// Pauses execution of the isolate. + @override + Future pause(String isolateId) => + wrapInErrorHandlerAsync('pause', () => _pause(isolateId)); + + Future _pause(String _) async { + // Create a pause event and store it + if (_isolateRef != null) { + final pauseEvent = vm_service.Event( + kind: vm_service.EventKind.kPauseInterrupted, + timestamp: DateTime.now().millisecondsSinceEpoch, + isolate: _isolateRef!, + ); + _currentPauseEvent = pauseEvent; + _streamNotify(vm_service.EventStreams.kDebug, pauseEvent); + } + + return Success(); + } + + /// Resumes execution of the isolate. + @override + Future resume(String isolateId, {String? step, int? frameIndex}) => + wrapInErrorHandlerAsync('resume', () => _resume(isolateId)); + + Future _resume(String isolateId) async { + if (hasPendingRestart && !resumeAfterRestartEventsController.isClosed) { + resumeAfterRestartEventsController.add(isolateId); + } else { + if (!_mainHasStarted) { + try { + appConnection.runMain(); + _mainHasStarted = true; + } catch (e) { + if (e.toString().contains('Main has already started')) { + _mainHasStarted = true; + } else { + rethrow; + } + } + } + } + + // Clear pause state and send resume event to notify debugging tools + if (_currentPauseEvent != null && _isolateRef != null) { + _currentPauseEvent = null; + final resumeEvent = vm_service.Event( + kind: vm_service.EventKind.kResume, + timestamp: DateTime.now().millisecondsSinceEpoch, + isolate: _isolateRef!, + ); + _streamNotify(vm_service.EventStreams.kDebug, resumeEvent); + } + + return Success(); + } + + @override + Future lookupPackageUris(String isolateId, List uris) => + wrapInErrorHandlerAsync( + 'lookupPackageUris', + () => _lookupPackageUris(isolateId, uris), + ); + + Future _lookupPackageUris(String _, List uris) async { + await isInitialized; + return UriList(uris: uris.map(DartUri.toPackageUri).toList()); + } + + @override + Future registerService(String service, String alias) { + return rpcNotSupportedFuture('registerService'); + } + + @override + Future getFlagList() => + wrapInErrorHandlerAsync('getFlagList', _getFlagList); + + Future _getFlagList() async { + // Return basic flag list for WebSocket mode + return FlagList( + flags: [ + Flag( + name: _pauseIsolatesOnStartFlag, + comment: 'If enabled, isolates are paused on start', + valueAsString: pauseIsolatesOnStart.toString(), + ), + ], + ); + } + + @override + Future getStack( + String isolateId, { + String? idZoneId, + int? limit, + }) => wrapInErrorHandlerAsync('getStack', () => _getStack(isolateId)); + + Future _getStack(String isolateId) async { + if (!_isIsolateRunning || _isolateRef == null) { + throw vm_service.RPCError( + 'getStack', + vm_service.RPCErrorKind.kInvalidParams.code, + 'No running isolate found for id: $isolateId', + ); + } + if (_isolateRef!.id != isolateId) { + throw vm_service.RPCError( + 'getStack', + vm_service.RPCErrorKind.kInvalidParams.code, + 'Isolate with id $isolateId not found.', + ); + } + + // Return empty stack since we're in WebSocket mode without Chrome debugging + return vm_service.Stack( + frames: [], + asyncCausalFrames: [], + awaiterFrames: [], + ); + } +} + +/// Extended ReloadReport that includes additional metadata in JSON output. +class _ReloadReportWithMetadata extends vm_service.ReloadReport { + final List? notices; + _ReloadReportWithMetadata({super.success, this.notices}); + + @override + Map toJson() { + final jsonified = { + 'type': 'ReloadReport', + 'success': success ?? false, + }; + if (notices != null) { + jsonified['notices'] = notices!.map((e) => {'message': e}).toList(); + } + return jsonified; + } +} diff --git a/dwds/lib/src/version.dart b/dwds/lib/src/version.dart index c8bd103ab..056d15cd2 100644 --- a/dwds/lib/src/version.dart +++ b/dwds/lib/src/version.dart @@ -1,2 +1,2 @@ // Generated code. Do not modify. -const packageVersion = '24.4.1-wip'; +const packageVersion = '24.4.1'; diff --git a/dwds/pubspec.yaml b/dwds/pubspec.yaml index da11ad7f1..b487f3f98 100644 --- a/dwds/pubspec.yaml +++ b/dwds/pubspec.yaml @@ -1,6 +1,6 @@ name: dwds # Every time this changes you need to run `dart run build_runner build`. -version: 24.4.1-wip +version: 24.4.1 description: >- A service that proxies between the Chrome debug protocol and the Dart VM diff --git a/dwds/web/client.dart b/dwds/web/client.dart index b824cf5e9..2aefcdfd9 100644 --- a/dwds/web/client.dart +++ b/dwds/web/client.dart @@ -19,6 +19,8 @@ import 'package:dwds/data/hot_reload_response.dart'; import 'package:dwds/data/register_event.dart'; import 'package:dwds/data/run_request.dart'; import 'package:dwds/data/serializers.dart'; +import 'package:dwds/data/service_extension_request.dart'; +import 'package:dwds/data/service_extension_response.dart'; import 'package:dwds/shared/batched_stream.dart'; import 'package:dwds/src/sockets.dart'; import 'package:http/browser_client.dart'; @@ -208,6 +210,8 @@ Future? main() { ); } else if (event is HotReloadRequest) { await handleWebSocketHotReloadRequest(event, manager, client.sink); + } else if (event is ServiceExtensionRequest) { + await handleServiceExtensionRequest(event, client.sink, manager); } }, onError: (error) { @@ -247,10 +251,6 @@ Future? main() { } } else { _sendConnectRequest(client.sink); - // TODO(yjessy): Remove this when the DWDS WebSocket connection is implemented. - if (useDwdsWebSocketConnection) { - runMain(); - } } _launchCommunicationWithDebugExtension(); }, @@ -416,6 +416,30 @@ void _sendHotReloadResponse( ); } +void _sendServiceExtensionResponse( + StreamSink clientSink, + String requestId, { + bool success = true, + String? errorMessage, + int? errorCode, + Map? result, +}) { + _trySendEvent( + clientSink, + jsonEncode( + serializers.serialize( + ServiceExtensionResponse.fromResult( + id: requestId, + success: success, + errorMessage: errorMessage, + errorCode: errorCode, + result: result, + ), + ), + ), + ); +} + Future handleWebSocketHotReloadRequest( HotReloadRequest event, ReloadingManager manager, @@ -436,6 +460,44 @@ Future handleWebSocketHotReloadRequest( } } +Future handleServiceExtensionRequest( + ServiceExtensionRequest request, + StreamSink clientSink, + ReloadingManager manager, +) async { + try { + final result = await manager.handleServiceExtension( + request.method, + request.args, + ); + + if (result != null) { + _sendServiceExtensionResponse( + clientSink, + request.id, + success: true, + result: result, + ); + } else { + // Service extension not supported by this restarter type + _sendServiceExtensionResponse( + clientSink, + request.id, + success: false, + errorMessage: 'Service extension not supported', + errorCode: -32601, // Method not found + ); + } + } catch (e) { + _sendServiceExtensionResponse( + clientSink, + request.id, + success: false, + errorMessage: e.toString(), + ); + } +} + @JS(r'$dartAppId') external String get dartAppId; @@ -488,10 +550,6 @@ external String get reloadConfiguration; @JS(r'$dartEntrypointPath') external String get dartEntrypointPath; -// TODO(yjessy): Remove this when the DWDS WebSocket connection is implemented. -@JS(r'$useDwdsWebSocketConnection') -external bool get useDwdsWebSocketConnection; - @JS(r'$dwdsEnableDevToolsLaunch') external bool get dwdsEnableDevToolsLaunch; diff --git a/dwds/web/reloader/ddc_library_bundle_restarter.dart b/dwds/web/reloader/ddc_library_bundle_restarter.dart index 5752cb983..0f4ee3021 100644 --- a/dwds/web/reloader/ddc_library_bundle_restarter.dart +++ b/dwds/web/reloader/ddc_library_bundle_restarter.dart @@ -38,6 +38,13 @@ extension type _Debugger._(JSObject _) implements JSObject { await invokeExtension(method, '{}').toDart; } } + + Future maybeInvokeFlutterReassemble() async { + final method = 'ext.flutter.reassemble'; + if (extensionNames.toDart.contains(method.toJS)) { + await invokeExtension(method, '{}').toDart; + } + } } @JS('XMLHttpRequest') @@ -129,4 +136,27 @@ class DdcLibraryBundleRestarter implements Restarter { _dartDevEmbedder.config.capturedHotReloadEndHandler = null; _capturedHotReloadEndCallback = null; } + + /// Handles service extension requests using the dart dev embedder + Future?> handleServiceExtension( + String method, + Map args, + ) async { + if (method == 'ext.flutter.reassemble') { + await _dartDevEmbedder.debugger.maybeInvokeFlutterReassemble(); + return {'status': 'reassemble invoked'}; + } else if (method == 'getExtensionRpcs') { + final rpcs = + _dartDevEmbedder.debugger.extensionNames.toDart.cast(); + return {'rpcs': rpcs}; + } else { + // For other extension methods, delegate to the debugger + final params = args.isNotEmpty ? jsonEncode(args) : '{}'; + final resultJson = + await _dartDevEmbedder.debugger + .invokeExtension(method, params) + .toDart; + return jsonDecode(resultJson.toDart) as Map; + } + } } diff --git a/dwds/web/reloader/manager.dart b/dwds/web/reloader/manager.dart index 52ee179b5..d6ace566b 100644 --- a/dwds/web/reloader/manager.dart +++ b/dwds/web/reloader/manager.dart @@ -10,6 +10,7 @@ import 'package:dwds/data/serializers.dart'; import 'package:dwds/src/sockets.dart'; import 'package:web/web.dart'; +import 'ddc_library_bundle_restarter.dart'; import 'restarter.dart'; class ReloadingManager { @@ -71,6 +72,19 @@ class ReloadingManager { window.location.reload(); } + /// Handles service extension requests by delegating to the appropriate restarter + Future?> handleServiceExtension( + String method, + Map args, + ) async { + final restarter = _restarter; + if (restarter is DdcLibraryBundleRestarter) { + return await restarter.handleServiceExtension(method, args); + } + // For other restarter types, return null to indicate not supported + return null; + } + void _afterRestart(bool succeeded) { if (!succeeded) return; // Notify package:dwds that the isolate has been created.