migrate to pkg web (dart-lang/web_socket_channel#294)
diff --git a/pkgs/web_socket_channel/CHANGELOG.md b/pkgs/web_socket_channel/CHANGELOG.md index 02e4630..011eed1 100644 --- a/pkgs/web_socket_channel/CHANGELOG.md +++ b/pkgs/web_socket_channel/CHANGELOG.md
@@ -1,10 +1,11 @@ ## 2.4.1-wip -- Bump minimum Dart version to 3.2.0 - Update the examples to use `WebSocketChannel.ready` and clarify that `WebSocketChannel.ready` should be awaited before sending data over the `WebSocketChannel`. - Mention `ready` in the docs for `connect`. +- Bump minimum Dart version to 3.2.0 +- Move to `pkg:web` to support WebAssembly compilation. ## 2.4.0
diff --git a/pkgs/web_socket_channel/lib/html.dart b/pkgs/web_socket_channel/lib/html.dart index 0cb7ffd..2263e6e 100644 --- a/pkgs/web_socket_channel/lib/html.dart +++ b/pkgs/web_socket_channel/lib/html.dart
@@ -3,14 +3,16 @@ // BSD-style license that can be found in the LICENSE file. import 'dart:async'; -import 'dart:html'; +import 'dart:js_interop'; import 'dart:typed_data'; import 'package:async/async.dart'; import 'package:stream_channel/stream_channel.dart'; +import 'package:web/helpers.dart'; import 'src/channel.dart'; import 'src/exception.dart'; +import 'src/web_helpers.dart'; /// A [WebSocketChannel] that communicates using a `dart:html` [WebSocket]. class HtmlWebSocketChannel extends StreamChannelMixin @@ -73,8 +75,15 @@ /// [BinaryType.blob], they're delivered as [Blob]s instead. HtmlWebSocketChannel.connect(Object url, {Iterable<String>? protocols, BinaryType? binaryType}) - : this(WebSocket(url.toString(), protocols) - ..binaryType = (binaryType ?? BinaryType.list).value); + : this( + WebSocket( + url.toString(), + (protocols?.toList() ?? const <String>[]) + .map((e) => e.toJS) + .toList() + .toJS, + )..binaryType = (binaryType ?? BinaryType.list).value, + ); /// Creates a channel wrapping [innerWebSocket]. HtmlWebSocketChannel(this.innerWebSocket) { @@ -109,11 +118,7 @@ _controller.local.sink.close(); }); - innerWebSocket.onMessage.listen((event) { - var data = event.data; - if (data is ByteBuffer) data = data.asUint8List(); - _controller.local.sink.add(data); - }); + innerWebSocket.onMessage.listen(_innerListen); // The socket API guarantees that only a single error event will be emitted, // and that once it is no other events will be emitted. @@ -124,16 +129,29 @@ }); } + void _innerListen(MessageEvent event) { + final eventData = event.data; + Object? data; + if (eventData.typeofEquals('object') && + (eventData as JSObject).instanceOfString('ArrayBuffer')) { + data = (eventData as JSArrayBuffer).toDart.asUint8List(); + } else { + data = event.data; + } + _controller.local.sink.add(data); + } + /// Pipes user events to [innerWebSocket]. void _listen() { - _controller.local.stream.listen(innerWebSocket.send, onDone: () { + _controller.local.stream.listen((obj) => innerWebSocket.send(obj!.jsify()!), + onDone: () { // On Chrome and possibly other browsers, `null` can't be passed as the // default here. The actual arity of the function call must be correct or // it will fail. if (_localCloseCode != null && _localCloseReason != null) { - innerWebSocket.close(_localCloseCode, _localCloseReason); + innerWebSocket.close(_localCloseCode!, _localCloseReason!); } else if (_localCloseCode != null) { - innerWebSocket.close(_localCloseCode); + innerWebSocket.close(_localCloseCode!); } else { innerWebSocket.close(); }
diff --git a/pkgs/web_socket_channel/lib/src/web_helpers.dart b/pkgs/web_socket_channel/lib/src/web_helpers.dart new file mode 100644 index 0000000..7ef46e5 --- /dev/null +++ b/pkgs/web_socket_channel/lib/src/web_helpers.dart
@@ -0,0 +1,17 @@ +// Copyright (c) 2023, 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 'package:web/helpers.dart'; + +// TODO(kevmoo): remove when https://github.com/dart-lang/web/commit/4cb5811ed06 +// is in a published release and the min constraint on pkg:web is updated +extension WebSocketEvents on WebSocket { + Stream<Event> get onOpen => EventStreamProviders.openEvent.forTarget(this); + Stream<MessageEvent> get onMessage => + EventStreamProviders.messageEvent.forTarget(this); + Stream<CloseEvent> get onClose => + EventStreamProviders.closeEvent.forTarget(this); + Stream<Event> get onError => + EventStreamProviders.errorEventSourceEvent.forTarget(this); +}
diff --git a/pkgs/web_socket_channel/pubspec.yaml b/pkgs/web_socket_channel/pubspec.yaml index c772f4d..5c3b9cf 100644 --- a/pkgs/web_socket_channel/pubspec.yaml +++ b/pkgs/web_socket_channel/pubspec.yaml
@@ -14,6 +14,7 @@ async: ^2.5.0 crypto: ^3.0.0 stream_channel: ^2.1.0 + web: ^0.4.0 dev_dependencies: dart_flutter_team_lints: ^2.0.0
diff --git a/pkgs/web_socket_channel/test/html_test.dart b/pkgs/web_socket_channel/test/html_test.dart index d444d7c..9d91025 100644 --- a/pkgs/web_socket_channel/test/html_test.dart +++ b/pkgs/web_socket_channel/test/html_test.dart
@@ -6,12 +6,14 @@ library; import 'dart:async'; -import 'dart:html'; +import 'dart:js_interop'; import 'dart:typed_data'; import 'package:async/async.dart'; import 'package:test/test.dart'; +import 'package:web/helpers.dart' hide BinaryType; import 'package:web_socket_channel/html.dart'; +import 'package:web_socket_channel/src/web_helpers.dart'; import 'package:web_socket_channel/web_socket_channel.dart'; void main() { @@ -176,6 +178,6 @@ Future<List<int>> _decodeBlob(Blob blob) async { final reader = FileReader(); reader.readAsArrayBuffer(blob); - await reader.onLoad.first; - return reader.result as Uint8List; + await reader.onLoadEnd.first; + return (reader.result as JSArrayBuffer).toDart.asUint8List(); }