Skip to content

Commit 032ac02

Browse files
committed
null_safety!
1 parent 5859efe commit 032ac02

File tree

6 files changed

+58
-64
lines changed

6 files changed

+58
-64
lines changed

lib/src/reducer_exception.dart

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import 'package:meta/meta.dart';
2-
31
/// Exception thrown by reducer
42
class ReducerException<A, S> implements Exception {
53
/// Action passed into reducer
@@ -16,10 +14,10 @@ class ReducerException<A, S> implements Exception {
1614

1715
/// Construct a [ReducerException]
1816
const ReducerException({
19-
@required this.action,
20-
@required this.state,
21-
@required this.error,
22-
this.stackTrace,
17+
required this.action,
18+
required this.state,
19+
required this.error,
20+
required this.stackTrace,
2321
});
2422

2523
@override

lib/src/redux_store_stream_transformer.dart

Lines changed: 34 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import 'dart:async';
22

3-
import 'package:meta/meta.dart';
4-
53
import 'logger.dart';
64
import 'reducer.dart';
75
import 'reducer_exception.dart';
@@ -34,10 +32,10 @@ extension ReduxStoreExt<Action> on Stream<Action> {
3432
/// * Param [State] The type of the State
3533
/// * Param [Action] The type of the Actions
3634
Stream<State> reduxStore<State>({
37-
@required State Function() initialStateSupplier,
38-
@required Iterable<SideEffect<Action, State>> sideEffects,
39-
@required Reducer<Action, State> reducer,
40-
RxReduxLogger logger,
35+
required State Function() initialStateSupplier,
36+
required Iterable<SideEffect<Action, State>> sideEffects,
37+
required Reducer<Action, State> reducer,
38+
RxReduxLogger? logger,
4139
}) =>
4240
transform(
4341
ReduxStoreStreamTransformer(
@@ -66,7 +64,7 @@ class ReduxStoreStreamTransformer<A, S> extends StreamTransformerBase<A, S> {
6664
final S Function() _initialStateSupplier;
6765
final Iterable<SideEffect<A, S>> _sideEffects;
6866
final Reducer<A, S> _reducer;
69-
final RxReduxLogger _logger;
67+
final RxReduxLogger? _logger;
7068

7169
/// * Param [initialStateSupplier] A function that computes the initial state. The computation is
7270
/// * done lazily once an observer subscribes. The computed initial state will be emitted directly
@@ -77,26 +75,20 @@ class ReduxStoreStreamTransformer<A, S> extends StreamTransformerBase<A, S> {
7775
/// * Param [S] The type of the State
7876
/// * Param [A] The type of the Actions
7977
ReduxStoreStreamTransformer({
80-
@required S Function() initialStateSupplier,
81-
@required Iterable<SideEffect<A, S>> sideEffects,
82-
@required Reducer<A, S> reducer,
83-
RxReduxLogger logger,
84-
}) : assert(initialStateSupplier != null,
85-
'initialStateSupplier cannot be null'),
86-
assert(sideEffects != null, 'sideEffects cannot be null'),
87-
assert(sideEffects.every((sideEffect) => sideEffect != null),
88-
'All sideEffects must be not null'),
89-
assert(reducer != null, 'reducer cannot be null'),
90-
_initialStateSupplier = initialStateSupplier,
78+
required S Function() initialStateSupplier,
79+
required Iterable<SideEffect<A, S>> sideEffects,
80+
required Reducer<A, S> reducer,
81+
RxReduxLogger? logger,
82+
}) : _initialStateSupplier = initialStateSupplier,
9183
_sideEffects = sideEffects,
9284
_reducer = reducer,
9385
_logger = logger;
9486

9587
@override
9688
Stream<S> bind(Stream<A> stream) {
97-
StreamController<S> controller;
98-
List<StreamSubscription<dynamic>> subscriptions;
99-
StreamController<WrapperAction<A>> actionController;
89+
late StreamController<S> controller;
90+
List<StreamSubscription<dynamic>>? subscriptions;
91+
StreamController<WrapperAction<A>>? _actionController;
10092

10193
void onListen() {
10294
S state;
@@ -110,7 +102,6 @@ class ReduxStoreStreamTransformer<A, S> extends StreamTransformerBase<A, S> {
110102
}
111103

112104
void onDataActually(WrapperAction<A> wrapper) {
113-
final action = wrapper.action;
114105
final type = wrapper.type;
115106
final currentState = state;
116107

@@ -123,6 +114,7 @@ class ReduxStoreStreamTransformer<A, S> extends StreamTransformerBase<A, S> {
123114
return controller.add(currentState);
124115
}
125116

117+
final action = wrapper.action!;
126118
try {
127119
final newState = _reducer(currentState, action);
128120
controller.add(newState);
@@ -151,7 +143,8 @@ class ReduxStoreStreamTransformer<A, S> extends StreamTransformerBase<A, S> {
151143
}
152144
}
153145

154-
actionController = StreamController<WrapperAction<A>>.broadcast();
146+
final actionController =
147+
_actionController = StreamController<WrapperAction<A>>.broadcast();
155148

156149
// Call reducer on each action.
157150
final subscriptionActionController =
@@ -170,16 +163,24 @@ class ReduxStoreStreamTransformer<A, S> extends StreamTransformerBase<A, S> {
170163
);
171164

172165
final getState = () => state;
166+
final actionStream = actionController.stream
167+
.map((wrapper) => wrapper.action!)
168+
.asBroadcastStream(onCancel: (s) => s.cancel());
173169

174170
subscriptions = [
175-
..._listenSideEffects(actionController, getState, controller),
171+
..._listenSideEffects(
172+
actionController,
173+
getState,
174+
controller,
175+
actionStream,
176+
),
176177
subscriptionUpstream,
177178
subscriptionActionController
178179
];
179180
}
180181

181182
Future<void> onCancel() async {
182-
final future = actionController?.close();
183+
final future = _actionController?.close();
183184
final cancelFutures = subscriptions?.map((s) => s.cancel());
184185
final futures = [...?cancelFutures, if (future != null) future];
185186

@@ -199,8 +200,8 @@ class ReduxStoreStreamTransformer<A, S> extends StreamTransformerBase<A, S> {
199200
controller = StreamController<S>(
200201
sync: true,
201202
onListen: onListen,
202-
onPause: () => subscriptions.forEach((s) => s.pause()),
203-
onResume: () => subscriptions.forEach((s) => s.resume()),
203+
onPause: () => subscriptions?.forEach((s) => s.pause()),
204+
onResume: () => subscriptions?.forEach((s) => s.resume()),
204205
onCancel: onCancel,
205206
);
206207
}
@@ -211,26 +212,24 @@ class ReduxStoreStreamTransformer<A, S> extends StreamTransformerBase<A, S> {
211212
Iterable<StreamSubscription<dynamic>> _listenSideEffects(
212213
StreamController<WrapperAction<A>> actionController,
213214
GetState<S> getState,
214-
StreamController<S> controller,
215+
StreamController<S> stateController,
216+
Stream<A> actionStream,
215217
) {
216218
return _sideEffects.mapIndexed(
217219
(index, sideEffect) {
218220
Stream<A> actions;
219221
try {
220-
actions = sideEffect(
221-
actionController.stream.map((wrapper) => wrapper.action),
222-
getState,
223-
);
222+
actions = sideEffect(actionStream, getState);
224223
} catch (e, s) {
225224
actions = Stream.error(e, s);
226225
}
227226

227+
final sideEffectAction = ActionType.sideEffect(index);
228228
return actions
229-
.map(
230-
(action) => WrapperAction(action, ActionType.sideEffect(index)))
229+
.map((action) => WrapperAction(action, sideEffectAction))
231230
.listen(
232231
actionController.add,
233-
onError: controller.addError,
232+
onError: stateController.addError,
234233
// Swallow onDone because just if one SideEffect reaches onDone
235234
// we don't want to make everything incl. ReduxStore and other SideEffects reach onDone
236235
);

lib/src/store.dart

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import 'dart:async';
22

3-
import 'package:meta/meta.dart';
4-
53
import 'logger.dart';
64
import 'reducer.dart';
75
import 'redux_store_stream_transformer.dart';
@@ -12,7 +10,7 @@ import 'side_effect.dart';
1210
SideEffect<A, S> _onEachActionSideEffect<A, S>(StreamSink<A> outputSink) {
1311
return (actions, _) {
1412
final neverController = StreamController<A>();
15-
StreamSubscription<A> subscription;
13+
late StreamSubscription<A> subscription;
1614

1715
neverController.onListen =
1816
() => subscription = actions.listen(outputSink.add);
@@ -57,12 +55,12 @@ class RxReduxStore<A, S> {
5755
/// If calling it returns true, the new state will not be emitted.
5856
/// If [equals] is omitted, the '==' operator is used.
5957
factory RxReduxStore({
60-
@required S initialState,
61-
@required List<SideEffect<A, S>> sideEffects,
62-
@required Reducer<A, S> reducer,
63-
void Function(Object, StackTrace) errorHandler,
64-
bool Function(S previous, S next) equals,
65-
RxReduxLogger logger,
58+
required S initialState,
59+
required List<SideEffect<A, S>> sideEffects,
60+
required Reducer<A, S> reducer,
61+
void Function(Object, StackTrace)? errorHandler,
62+
bool Function(S previous, S next)? equals,
63+
RxReduxLogger? logger,
6664
}) {
6765
final actionController = StreamController<A>(sync: true);
6866
final actionOutputController = StreamController<A>.broadcast(sync: true);
@@ -82,7 +80,7 @@ class RxReduxStore<A, S> {
8280
.asBroadcastStream(onCancel: (subscription) => subscription.cancel());
8381

8482
var currentState = initialState;
85-
final subscriptions = <StreamSubscription<Object>>[
83+
final subscriptions = <StreamSubscription<dynamic>>[
8684
stateStream.listen(
8785
(newState) => currentState = newState,
8886
onError: errorHandler,

lib/src/utils.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
// ignore_for_file: public_member_api_docs
22

33
extension MapIndexedIterableExtensison<T> on Iterable<T> {
4-
Iterable<R> mapIndexed<R>(R Function(int, T) mapper) {
4+
Iterable<R> mapIndexed<R>(R Function(int, T) mapper) sync* {
55
var index = 0;
6-
return map((t) => mapper(index++, t));
6+
for (final t in this) {
7+
yield mapper(index++, t);
8+
}
79
}
810
}

lib/src/wrapper_action.dart

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import 'package:meta/meta.dart';
22

3-
// ignore_for_file: public_member_api_docs, missing_return
3+
// ignore_for_file: public_member_api_docs
44

55
@sealed
66
abstract class ActionType {
@@ -14,14 +14,15 @@ abstract class ActionType {
1414
@override
1515
String toString() {
1616
if (this is _Initial) {
17-
return '';
17+
return '';
1818
}
1919
if (this is _External) {
2020
return '↓';
2121
}
2222
if (this is _SideEffect) {
2323
return '⟳${(this as _SideEffect).index}';
2424
}
25+
throw StateError('What is $this');
2526
}
2627
}
2728

@@ -40,7 +41,7 @@ class _SideEffect extends ActionType {
4041
}
4142

4243
class WrapperAction<A> {
43-
final A action;
44+
final A? action;
4445
final ActionType type;
4546

4647
WrapperAction(this.action, this.type);

pubspec.yaml

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,11 @@ repository: https://github.com/hoc081098/rx_redux.git
77
issue_tracker: https://github.com/hoc081098/rx_redux/issues
88

99
environment:
10-
sdk: '>=2.7.0 <3.0.0'
10+
sdk: '>=2.12.0-0 <3.0.0'
1111

1212
dependencies:
13-
meta: ^1.1.8
1413

1514
dev_dependencies:
16-
pedantic: ^1.9.0
17-
test: ^1.15.3
18-
rxdart:
19-
git:
20-
url: "https://github.com/ReactiveX/rxdart.git"
21-
ref: "master"
15+
pedantic: ^1.10.0-nullsafety.3
16+
test: ^1.16.0-nullsafety.12
17+
rxdart: ^0.26.0-nullsafety.0

0 commit comments

Comments
 (0)