diff --git a/CHANGELOG.md b/CHANGELOG.md index a48b296..0f50c4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.3.0 - May 9, 2021 + +- Update `rxdart` to `0.27.0`. + ## 1.2.0 - Mar 27, 2021 - Update dependencies. diff --git a/example/distinct_value_connectable_stream_example.dart b/example/distinct_value_connectable_stream_example.dart index 702b01c..40c6f7a 100644 --- a/example/distinct_value_connectable_stream_example.dart +++ b/example/distinct_value_connectable_stream_example.dart @@ -30,7 +30,7 @@ class CounterBloc { decrementController.stream.map((i) => -i), ]; final state$ = Rx.merge(streams) - .scan((acc, e, _) => acc! + e, 0) + .scan((acc, e, _) => acc + e, 0) .publishValueDistinct(0); final subscription = state$.connect(); diff --git a/lib/src/as_broadcast.dart b/lib/src/as_broadcast.dart index 45cc6ce..bd4a76d 100644 --- a/lib/src/as_broadcast.dart +++ b/lib/src/as_broadcast.dart @@ -1,9 +1,8 @@ import 'dart:async'; -import 'package:rxdart_ext/rxdart_ext.dart' show ValueWrapper; - import 'distinct_value_connectable_stream.dart'; import 'distinct_value_stream.dart'; +import 'distinct_value_stream_mixin.dart'; /// Convert a [DistinctValueStream] to a broadcast [DistinctValueStream]. extension BroadcastDistinctValueStreamExtensions on DistinctValueStream { @@ -19,7 +18,7 @@ extension BroadcastDistinctValueStreamExtensions on DistinctValueStream { final self = this; return self is DistinctValueConnectableStream ? self - : DistinctValueConnectableStream(this, requireValue, + : DistinctValueConnectableStream(this, value, equals: equals, sync: sync); } @@ -36,6 +35,7 @@ extension BroadcastDistinctValueStreamExtensions on DistinctValueStream { } class _AsBroadcastStream extends StreamView + with DistinctValueStreamMixin implements DistinctValueStream { final DistinctValueStream source; @@ -46,8 +46,5 @@ class _AsBroadcastStream extends StreamView bool Function(T p1, T p2) get equals => source.equals; @override - Null get errorAndStackTrace => null; - - @override - ValueWrapper get valueWrapper => source.valueWrapper; + T get value => source.value; } diff --git a/lib/src/distinct_value_connectable_stream.dart b/lib/src/distinct_value_connectable_stream.dart index e765faa..5f7f42c 100644 --- a/lib/src/distinct_value_connectable_stream.dart +++ b/lib/src/distinct_value_connectable_stream.dart @@ -6,10 +6,10 @@ import 'package:rxdart_ext/rxdart_ext.dart' ConnectableStream, ConnectableStreamSubscription, ValueStream, - ValueSubject, - ValueWrapper; + ValueSubject; import 'distinct_value_stream.dart'; +import 'distinct_value_stream_mixin.dart'; import 'distinct_value_subject.dart'; /// A [ConnectableStream] that converts a single-subscription Stream into @@ -52,7 +52,7 @@ abstract class DistinctValueConnectableStream extends ConnectableStream } class _DistinctValueConnectableStream - extends DistinctValueConnectableStream { + extends DistinctValueConnectableStream with DistinctValueStreamMixin { final Stream _source; final DistinctValueSubject _subject; var _used = false; @@ -119,10 +119,7 @@ class _DistinctValueConnectableStream } @override - Null get errorAndStackTrace => null; - - @override - ValueWrapper get valueWrapper => _subject.valueWrapper; + T get value => _subject.value; } /// Provide two extension methods for [Stream]: diff --git a/lib/src/distinct_value_stream.dart b/lib/src/distinct_value_stream.dart index f280f3a..f3c2f2d 100644 --- a/lib/src/distinct_value_stream.dart +++ b/lib/src/distinct_value_stream.dart @@ -1,7 +1,8 @@ import 'dart:async'; +import 'package:distinct_value_connectable_stream/src/distinct_value_stream_mixin.dart'; import 'package:rxdart_ext/rxdart_ext.dart' - show NotReplayValueStream, ValueStreamController, ValueWrapper; + show NotReplayValueStream, ValueStreamController; /// An [Stream] that provides synchronous access to the last emitted item, /// and two consecutive values are not equal. @@ -15,36 +16,25 @@ abstract class DistinctValueStream extends NotReplayValueStream { static bool defaultEquals(Object? lhs, Object? rhs) => lhs == rhs; @override - Null get errorAndStackTrace; + T get value; @override - ValueWrapper get valueWrapper; -} - -/// Extensions to easily access value and error. -extension DistinctValueStreamExtensions on DistinctValueStream { - /// A flag that turns true as soon as at least one event has been emitted. - /// Always returns `true`. - bool get hasValue => true; + T get valueOrNull; - /// Returns latest value. - T get value => valueWrapper.value; + @override + bool get hasValue; - /// Returns latest value. - T get requireValue => valueWrapper.value; + @override + Never get error; - /// A flag that turns true as soon as at an error event has been emitted. - /// Always returns `false`. - bool get hasError => false; + @override + Null get errorOrNull; - /// Last emitted error. - /// Always returns `null`. - Null get error => null; + @override + bool get hasError; - /// Last emitted error. - /// Always throws. - Never get requireError => - throw StateError('DistinctValueStream always has no error!'); + @override + Null get stackTrace; } /// Convert this [Stream] to a [DistinctValueStream]. @@ -77,6 +67,7 @@ extension ToDistinctValueStreamExtension on Stream { /// /// This stream is a single-subscription stream. class _DistinctValueStream extends Stream + with DistinctValueStreamMixin implements DistinctValueStream { @override final bool Function(T p1, T p2) equals; @@ -89,15 +80,15 @@ class _DistinctValueStream extends Stream /// Construct a [_DistinctValueStream] with source stream, seed value. _DistinctValueStream( Stream source, - T value, + T seedValue, this.equals, - ) : controller = ValueStreamController(value, sync: true) { + ) : controller = ValueStreamController(seedValue, sync: true) { late StreamSubscription subscription; controller.onListen = () { subscription = source.listen( (data) { - if (!equals(valueWrapper.value, data)) { + if (!equals(value, data)) { controller.add(data); } }, @@ -113,12 +104,6 @@ class _DistinctValueStream extends Stream controller.onCancel = () => subscription.cancel(); } - @override - Null get errorAndStackTrace => null; - - @override - ValueWrapper get valueWrapper => controller.stream.valueWrapper!; - @override StreamSubscription listen( void Function(T event)? onData, { @@ -132,4 +117,7 @@ class _DistinctValueStream extends Stream onDone: onDone, cancelOnError: cancelOnError, ); + + @override + T get value => controller.stream.value; } diff --git a/lib/src/distinct_value_stream_mixin.dart b/lib/src/distinct_value_stream_mixin.dart new file mode 100644 index 0000000..59faa1a --- /dev/null +++ b/lib/src/distinct_value_stream_mixin.dart @@ -0,0 +1,24 @@ +import 'package:rxdart_ext/rxdart_ext.dart' show ValueStreamError; + +import 'distinct_value_stream.dart'; + +/// This mixin implements all [DistinctValueStream] members except [DistinctValueStream.value]. +mixin DistinctValueStreamMixin implements DistinctValueStream { + @override + Never get error => throw ValueStreamError.hasNoError(); + + @override + Null get errorOrNull => null; + + @override + bool get hasError => false; + + @override + Null get stackTrace => null; + + @override + bool get hasValue => true; + + @override + T get valueOrNull => value; +} diff --git a/lib/src/distinct_value_subject.dart b/lib/src/distinct_value_subject.dart index b330b2d..3285f8b 100644 --- a/lib/src/distinct_value_subject.dart +++ b/lib/src/distinct_value_subject.dart @@ -1,8 +1,9 @@ import 'dart:async'; +import 'package:distinct_value_connectable_stream/src/distinct_value_stream_mixin.dart'; import 'package:meta/meta.dart'; import 'package:rxdart_ext/rxdart_ext.dart' - show PublishSubject, Subject, ValueSubject, ValueWrapper; + show PublishSubject, Subject, ValueSubject; import 'distinct_value_stream.dart'; @@ -38,6 +39,7 @@ import 'distinct_value_stream.dart'; /// subject.close(); @sealed class DistinctValueSubject extends Subject + with DistinctValueStreamMixin implements DistinctValueStream { final ValueSubject _subject; @@ -73,16 +75,10 @@ class DistinctValueSubject extends Subject equals ?? DistinctValueStream.defaultEquals, subject); } - @override - Null get errorAndStackTrace => null; - - @override - ValueWrapper get valueWrapper => _subject.valueWrapper!; - @nonVirtual @override void add(T event) { - if (!equals(valueWrapper.value, event)) { + if (!equals(value, event)) { _subject.add(event); } } @@ -91,7 +87,7 @@ class DistinctValueSubject extends Subject Future close() => _subject.close(); @override - void addError(Object error, [StackTrace? stackTrace]) => + Never addError(Object error, [StackTrace? stackTrace]) => throw StateError('Cannot add error to DistinctValueSubject'); @override @@ -117,4 +113,7 @@ class DistinctValueSubject extends Subject onCancel: onCancel, sync: sync, ); + + @override + T get value => _subject.value; } diff --git a/pubspec.yaml b/pubspec.yaml index 7a0a9d4..512a9c9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: distinct_value_connectable_stream description: Distinct value connectable stream for RxDart, useful for BLoC pattern author: Petrus Nguyen Thai Hoc -version: 1.2.0 +version: 1.3.0 homepage: https://github.com/hoc081098/distinct_value_connectable_stream.git repository: https://github.com/hoc081098/distinct_value_connectable_stream.git issue_tracker: https://github.com/hoc081098/distinct_value_connectable_stream/issues @@ -10,9 +10,9 @@ environment: sdk: '>=2.12.0 <3.0.0' dependencies: - rxdart_ext: ^0.0.1 + rxdart_ext: ^0.1.0 meta: ^1.3.0 dev_dependencies: pedantic: ^1.11.0 - test: ^1.16.8 + test: ^1.17.3 diff --git a/test/distinct_value_connectable_stream_test.dart b/test/distinct_value_connectable_stream_test.dart index f8e640d..6755a35 100644 --- a/test/distinct_value_connectable_stream_test.dart +++ b/test/distinct_value_connectable_stream_test.dart @@ -278,15 +278,14 @@ void main() { test('extensions', () { final distinctValue = Stream.value(1).shareValueDistinct(0); - expect(distinctValue.valueWrapper, ValueWrapper(0)); + expect(distinctValue.valueOrNull, 0); expect(distinctValue.hasValue, true); expect(distinctValue.value, 0); - expect(distinctValue.requireValue, 0); - expect(distinctValue.errorAndStackTrace, isNull); + expect(distinctValue.stackTrace, isNull); expect(distinctValue.hasError, false); - expect(distinctValue.error, null); - expect(() => distinctValue.requireError, throwsStateError); + expect(distinctValue.errorOrNull, null); + expect(() => distinctValue.error, throwsA(isA())); }); }); } diff --git a/test/distinct_value_subject_test.dart b/test/distinct_value_subject_test.dart index 871b2f4..b03eff5 100644 --- a/test/distinct_value_subject_test.dart +++ b/test/distinct_value_subject_test.dart @@ -77,7 +77,8 @@ void main() { }); test('get error', () { - expect(DistinctValueSubject(0).errorAndStackTrace, isNull); + expect(DistinctValueSubject(0).errorOrNull, isNull); + expect(DistinctValueSubject(0).stackTrace, isNull); }); test('Rx', () { diff --git a/test/distinct_value_test.dart b/test/distinct_value_test.dart index 403db2c..1ad9199 100644 --- a/test/distinct_value_test.dart +++ b/test/distinct_value_test.dart @@ -14,7 +14,7 @@ void main() { for (var i = 0; i < 10; i++) { controller.add(i); expect(stream.value, i); - expect(stream.error, isNull); + expect(stream.errorOrNull, isNull); } }); @@ -118,15 +118,14 @@ void main() { test('extensions', () { final distinctValue = Stream.value(1).distinctValue(0); - expect(distinctValue.valueWrapper, ValueWrapper(0)); + expect(distinctValue.valueOrNull, 0); expect(distinctValue.hasValue, true); expect(distinctValue.value, 0); - expect(distinctValue.requireValue, 0); - expect(distinctValue.errorAndStackTrace, isNull); + expect(distinctValue.stackTrace, isNull); expect(distinctValue.hasError, false); - expect(distinctValue.error, null); - expect(() => distinctValue.requireError, throwsStateError); + expect(distinctValue.errorOrNull, null); + expect(() => distinctValue.error, throwsA(isA())); }); }); } diff --git a/test/single_subscription_to_broadcast_test.dart b/test/single_subscription_to_broadcast_test.dart index fd23033..6b8cecf 100644 --- a/test/single_subscription_to_broadcast_test.dart +++ b/test/single_subscription_to_broadcast_test.dart @@ -22,7 +22,8 @@ void main() { final stream = source.asBroadcastDistinctValueStream(); expect(identical(stream.equals, source.equals), true); - expect(stream.errorAndStackTrace, null); + expect(stream.errorOrNull, null); + expect(stream.stackTrace, null); await _test(stream); });