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();
 }