Skip to content

Commit e76eb88

Browse files
authored
Merge pull request #41 from davidmarne/strong_mode_rules
Strong mode rules & Action stream
2 parents 5719469 + 82ffc80 commit e76eb88

20 files changed

+129
-206
lines changed

Diff for: analysis_options.yaml

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
analyzer:
2-
strong-mode: true
3-
implicit-dynamic: false
4-
implicit-casts: false
2+
strong-mode:
3+
implicit-casts: false
4+
implicit-dynamic: false

Diff for: lib/built_redux.dart

-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ library built_redux;
33
export 'src/action.dart';
44
export 'src/reducer_builder.dart';
55
export 'src/middleware.dart';
6-
export 'src/state_transformer.dart';
76
export 'src/store.dart';
87
export 'src/store_change.dart';
98
export 'src/typedefs.dart';

Diff for: lib/src/action.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class ActionDispatcher<P> {
3030

3131
ActionDispatcher(this._name);
3232

33-
void setDispatcher(dispatcher) {
33+
void setDispatcher(Dispatcher dispatcher) {
3434
_dispatcher = dispatcher;
3535
}
3636
}

Diff for: lib/src/middleware.dart

+5-3
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,11 @@ class MiddlewareBuilder<
3131
var _map = new Map<String,
3232
MiddlewareHandler<State, StateBuilder, Actions, dynamic>>();
3333

34-
void add<T>(ActionName<T> aMgr,
35-
MiddlewareHandler<State, StateBuilder, Actions, T> handler) {
36-
_map[aMgr.name] = handler;
34+
void add<Payload>(ActionName<Payload> aMgr,
35+
MiddlewareHandler<State, StateBuilder, Actions, Payload> handler) {
36+
_map[aMgr.name] = (api, next, action) {
37+
handler(api, next, action as Action<Payload>);
38+
};
3739
}
3840

3941
/// [build] returns a [Middleware] function that handles all actions added with [add]

Diff for: lib/src/reducer_builder.dart

+12-8
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ class ReducerBuilder<State extends Built<State, StateBuilder>,
1717
/// Registers [reducer] function to the given [actionName]
1818
void add<Payload>(ActionName<Payload> actionName,
1919
Reducer<State, StateBuilder, Payload> reducer) {
20-
_map[actionName.name] = reducer;
20+
_map[actionName.name] = (state, action, builder) {
21+
reducer(state, action as Action<Payload>, builder);
22+
};
2123
}
2224

2325
/// [combine] combines this ReducerBuilder with another ReducerBuilder
@@ -127,7 +129,7 @@ class NestedReducerBuilder<
127129
Reducer<NestedState, NestedStateBuilder, Payload> reducer) {
128130
_map[actionName.name] = (state, action, builder) => reducer(
129131
_stateMapper(state),
130-
action,
132+
action as Action<Payload>,
131133
_builderMapper(builder),
132134
);
133135
}
@@ -144,7 +146,9 @@ class AbstractReducerBuilder<AState, AStateBuilder> {
144146
/// Registers [reducer] function to the given [actionName]
145147
void add<Payload>(ActionName<Payload> actionName,
146148
CReducer<AState, AStateBuilder, Payload> reducer) {
147-
_map[actionName.name] = reducer;
149+
_map[actionName.name] = (state, action, builder) {
150+
reducer(state, action as Action<Payload>, builder);
151+
};
148152
}
149153

150154
Map<String, CReducer<AState, AStateBuilder, dynamic>> build() => _map;
@@ -171,7 +175,7 @@ class ListReducerBuilder<State extends Built<State, StateBuilder>,
171175
CReducer<BuiltList<T>, ListBuilder<T>, Payload> reducer) {
172176
_map[actionName.name] = (state, action, builder) => reducer(
173177
_stateMapper(state),
174-
action,
178+
action as Action<Payload>,
175179
_builderMapper(builder),
176180
);
177181
}
@@ -194,7 +198,7 @@ class ListMultimapReducerBuilder<State extends Built<State, StateBuilder>,
194198
reducer) {
195199
_map[actionName.name] = (state, action, builder) => reducer(
196200
_stateMapper(state),
197-
action,
201+
action as Action<Payload>,
198202
_builderMapper(builder),
199203
);
200204
}
@@ -215,7 +219,7 @@ class MapReducerBuilder<State extends Built<State, StateBuilder>,
215219
CReducer<BuiltMap<K, V>, MapBuilder<K, V>, Payload> reducer) {
216220
_map[actionName.name] = (state, action, builder) => reducer(
217221
_stateMapper(state),
218-
action,
222+
action as Action<Payload>,
219223
_builderMapper(builder),
220224
);
221225
}
@@ -236,7 +240,7 @@ class SetReducerBuilder<State extends Built<State, StateBuilder>,
236240
CReducer<BuiltSet<T>, SetBuilder<T>, Payload> reducer) {
237241
_map[actionName.name] = (state, action, builder) => reducer(
238242
_stateMapper(state),
239-
action,
243+
action as Action<Payload>,
240244
_builderMapper(builder),
241245
);
242246
}
@@ -259,7 +263,7 @@ class SetMultimapReducerBuilder<State extends Built<State, StateBuilder>,
259263
reducer) {
260264
_map[actionName.name] = (state, action, builder) => reducer(
261265
_stateMapper(state),
262-
action,
266+
action as Action<Payload>,
263267
_builderMapper(builder),
264268
);
265269
}

Diff for: lib/src/state_transformer.dart

-79
This file was deleted.

Diff for: lib/src/store.dart

+18-6
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import 'action.dart';
77
import 'middleware.dart';
88
import 'typedefs.dart';
99
import 'store_change.dart';
10-
import 'state_transformer.dart';
1110

1211
/// [Store] is the container of your state. It listens for actions, invokes reducers,
1312
/// and publishes changes to the state
@@ -34,8 +33,7 @@ class Store<
3433

3534
_actions = actions;
3635

37-
final MiddlewareApi api =
38-
new MiddlewareApi<State, StateBuilder, Actions>(this);
36+
final api = new MiddlewareApi<State, StateBuilder, Actions>(this);
3937

4038
// setup the dispatch chain
4139
ActionHandler handler = (action) {
@@ -68,7 +66,7 @@ class Store<
6866
}
6967

7068
/// [dispose] removes closes both the dispatch and subscription stream
71-
dispose() {
69+
void dispose() {
7270
_stateController.close();
7371
_state = null;
7472
_actions = null;
@@ -79,7 +77,7 @@ class Store<
7977
void replaceState(State state) {
8078
if (_state != state) {
8179
_stateController.add(new StoreChange<State, StateBuilder, dynamic>(
82-
state, _state, new Action('replaceState', null)));
80+
state, _state, new Action<Null>('replaceState', null)));
8381
_state = state;
8482
}
8583
}
@@ -104,12 +102,26 @@ class Store<
104102
Stream<SubstateChange<Substate>> substateStream<Substate>(
105103
StateMapper<State, StateBuilder, Substate> mapper,
106104
) =>
107-
_stateController.stream.transform(new StateChangeTransformer(mapper));
105+
stream
106+
.map((c) => new SubstateChange<Substate>(
107+
mapper(c.prev),
108+
mapper(c.next),
109+
))
110+
.where((c) => c.prev != c.next);
108111

109112
/// [nextSubstate] is a stream which has a payload of the next subState value, rather than the SubstateChange event
110113
Stream<Substate> nextSubstate<Substate>(
111114
StateMapper<State, StateBuilder, Substate> mapper,
112115
) =>
113116
substateStream(mapper)
114117
.map((SubstateChange<Substate> change) => change.next);
118+
119+
/// [actionStream] returns a stream the fires when a state change is caused by the action
120+
/// with the name provided. Check out built_redux_rx if you are looking for streams to actions that do not
121+
/// necessarily result in state changes.
122+
Stream<StoreChange<State, StateBuilder, Payload>> actionStream<Payload>(
123+
ActionName<Payload> actionName) =>
124+
stream
125+
.where((c) => c.action.name == actionName.name)
126+
.map((c) => c as StoreChange<State, StateBuilder, Payload>);
115127
}

Diff for: lib/src/store_change.dart

+5-3
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,13 @@ class StoreChangeHandlerBuilder<
3939
/// Registers [handler] function to the given [actionName]
4040
void add<Payload>(ActionName<Payload> actionName,
4141
StoreChangeHandler<Payload, State, StateBuilder> handler) {
42-
_map[actionName.name] = handler;
42+
_map[actionName.name] = (change) {
43+
handler(change as StoreChange<State, StateBuilder, Payload>);
44+
};
4345
}
4446

4547
/// [build] sets up a subscription to the registered actions
46-
build(Store<State, StateBuilder, Actions> store) {
48+
void build(Store<State, StateBuilder, Actions> store) {
4749
_subscription = store.stream
4850
.listen((StoreChange<State, StateBuilder, dynamic> storeChange) {
4951
var handler = _map[storeChange.action.name];
@@ -52,7 +54,7 @@ class StoreChangeHandlerBuilder<
5254
}
5355

5456
/// [dispose] cancels the subscription to the store
55-
dispose() {
57+
void dispose() {
5658
_subscription.cancel();
5759
}
5860
}

Diff for: lib/src/typedefs.dart

+12
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,15 @@ typedef NextActionHandler Middleware<
2222
State extends Built<State, StateBuilder>,
2323
StateBuilder extends Builder<State, StateBuilder>,
2424
Actions extends ReduxActions>(MiddlewareApi<State, StateBuilder, Actions> api);
25+
26+
/// [SubstateChange] is the payload for `StateChangeTransformer`'s stream. It contains
27+
/// the previous and next value of the state resulting from the mapper provided to `StateChangeTransformer`
28+
class SubstateChange<Substate> {
29+
Substate prev;
30+
Substate next;
31+
SubstateChange(this.prev, this.next);
32+
}
33+
34+
/// [StateMapper] takes a state model and maps it to the values one cares about
35+
typedef Substate StateMapper<State extends Built<State, StateBuilder>,
36+
StateBuilder extends Builder<State, StateBuilder>, Substate>(State state);

Diff for: pubspec.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: built_redux
2-
version: 7.1.0
2+
version: 7.2.0
33
description:
44
A state management library written in dart that enforces immutability
55
authors:

Diff for: test/unit/action_generics_models.dart

+5-3
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,14 @@ Reducer<ActionGenerics, ActionGenericsBuilder, dynamic>
3636
(s, a, b) => b.count = s.count + a.payload)
3737
..add<Null>(
3838
ActionGenericsActionsNames.nullAction, (s, a, b) => b.count++)
39-
..add<List<int>>(ActionGenericsActionsNames.listIntAction,
40-
(s, a, b) => b.count += a.payload.fold(0, (c, n) => c + n))
39+
..add<List<int>>(
40+
ActionGenericsActionsNames.listIntAction,
41+
(s, a, b) =>
42+
b.count += a.payload.fold<int>(0, (c, n) => c + n))
4143
..add<Map<String, List<int>>>(
4244
ActionGenericsActionsNames.mapStringToListIntAction,
4345
(s, a, b) =>
44-
b.count += a.payload['k'].fold(0, (c, n) => c + n)))
46+
b.count += a.payload['k'].fold<int>(0, (c, n) => c + n)))
4547
.build();
4648

4749
/// Used to test code generation when the generic type of an action is a

Diff for: test/unit/action_generics_test.dart

+3-2
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ import 'package:test/test.dart';
33

44
import 'action_generics_models.dart';
55

6-
main() {
6+
void main() {
77
group('action generics', () {
88
Store<ActionGenerics, ActionGenericsBuilder, ActionGenericsActions> store;
99

1010
setUp(() {
11-
store = new Store(
11+
store = new Store<ActionGenerics, ActionGenericsBuilder,
12+
ActionGenericsActions>(
1213
getActionGenericsReducer(),
1314
new ActionGenerics(),
1415
new ActionGenericsActions(),

Diff for: test/unit/collection_reducer_builders_test.dart

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ import 'package:test/test.dart';
33

44
import 'collection_models.dart';
55

6-
main() {
6+
void main() {
77
group('collection reducer builders', () {
88
Store<Collection, CollectionBuilder, CollectionActions> store;
99

1010
setUp(() {
11-
store = new Store(
11+
store = new Store<Collection, CollectionBuilder, CollectionActions>(
1212
getCollectionReducer(),
1313
new Collection(),
1414
new CollectionActions(),

Diff for: test/unit/inheritance_test.dart

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ import 'package:test/test.dart';
33

44
import 'inheritance_test_models.dart';
55

6-
main() {
6+
void main() {
77
group('inheritence', () {
88
Store<Child, ChildBuilder, ChildActions> store;
99

1010
setUp(() {
11-
store =
12-
new Store(getInheritanceReducer(), new Child(), new ChildActions());
11+
store = new Store<Child, ChildBuilder, ChildActions>(
12+
getInheritanceReducer(), new Child(), new ChildActions());
1313
});
1414

1515
tearDown(() {

0 commit comments

Comments
 (0)