make StreamChannelMixin an abstract mixin class
diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md
index 30f7d32..9dd3990 100644
--- a/pkgs/stream_channel/CHANGELOG.md
+++ b/pkgs/stream_channel/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 2.1.4
+
+* Fix `StreamChannelMixin` so that it can be used as a mixin again.
+
 ## 2.1.3
 
 * Require Dart 3.3
diff --git a/pkgs/stream_channel/lib/stream_channel.dart b/pkgs/stream_channel/lib/stream_channel.dart
index 85f9a97..8e53096 100644
--- a/pkgs/stream_channel/lib/stream_channel.dart
+++ b/pkgs/stream_channel/lib/stream_channel.dart
@@ -148,7 +148,7 @@
 
 /// A mixin that implements the instance methods of [StreamChannel] in terms of
 /// [stream] and [sink].
-abstract class StreamChannelMixin<T> implements StreamChannel<T> {
+abstract mixin class StreamChannelMixin<T> implements StreamChannel<T> {
   @override
   void pipe(StreamChannel<T> other) {
     stream.pipe(other.sink);
diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml
index eec8c1b..f050fca 100644
--- a/pkgs/stream_channel/pubspec.yaml
+++ b/pkgs/stream_channel/pubspec.yaml
@@ -1,5 +1,5 @@
 name: stream_channel
-version: 2.1.3
+version: 2.1.4
 description: >-
   An abstraction for two-way communication channels based on the Dart Stream
   class.
diff --git a/pkgs/stream_channel/test/stream_channel_test.dart b/pkgs/stream_channel/test/stream_channel_test.dart
index c44b6ab..166671d 100644
--- a/pkgs/stream_channel/test/stream_channel_test.dart
+++ b/pkgs/stream_channel/test/stream_channel_test.dart
@@ -135,4 +135,46 @@
     changed.sink.add(10);
     changed.sink.close();
   });
+
+  group('StreamChannelMixin', () {
+    test('can be used as a mixin', () async {
+      var channel = StreamChannelMixinAsMixin<int>();
+      expect(channel.stream, emitsInOrder([1, 2, 3]));
+      channel.sink
+        ..add(1)
+        ..add(2)
+        ..add(3);
+      await channel.controller.close();
+    });
+
+    test('can be extended', () async {
+      var channel = StreamChannelMixinAsSuperclass<int>();
+      expect(channel.stream, emitsInOrder([1, 2, 3]));
+      channel.sink
+        ..add(1)
+        ..add(2)
+        ..add(3);
+      await channel.controller.close();
+    });
+  });
+}
+
+class StreamChannelMixinAsMixin<T> with StreamChannelMixin<T> {
+  final controller = StreamController<T>();
+
+  @override
+  StreamSink<T> get sink => controller.sink;
+
+  @override
+  Stream<T> get stream => controller.stream;
+}
+
+class StreamChannelMixinAsSuperclass<T> extends StreamChannelMixin<T> {
+  final controller = StreamController<T>();
+
+  @override
+  StreamSink<T> get sink => controller.sink;
+
+  @override
+  Stream<T> get stream => controller.stream;
 }