Skip to content

Commit 045382a

Browse files
authored
Merge pull request #29 from davidmarne/remove_generated_mixin
6.0.0 - Remove BuiltReducer class and the generated mixin
2 parents 8ea8550 + 44fd82d commit 045382a

15 files changed

+363
-326
lines changed

Diff for: README.md

+91-69
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,24 @@
1+
# built_redux
2+
13
[![Pub](https://img.shields.io/pub/v/built_redux.svg)](https://pub.dartlang.org/packages/built_redux)
24
[![codecov.io](http://codecov.io/github/davidmarne/built_redux/coverage.svg?branch=master)](http://codecov.io/github/davidmarne/built_redux?branch=master)
35

4-
### built_redux
5-
66
built_redux is a state management library written in dart that enforces immutability.
7-
built_redux stores can be built with middleware and nested reducers.
7+
built_redux is not only an implementation of [redux][redux_git], but also a framework for building middleware and reducers in a type safe manner.
88

99
Inspired by [redux][redux_git]
1010

1111
Built using [built_value][built_value_git]
1212

13-
### Framework bindings & examples
14-
15-
[react-dart][react-dart]
13+
## Framework bindings & examples
1614

1715
[flutter][flutter]
1816

19-
[angular2][angular2]
17+
[react-dart][react-dart]
2018

19+
[angular2][angular2]
2120

22-
### Using it in your project
21+
## Using it in your project
2322

2423
> __If you are not familiar with Redux or built_value__
2524
>
@@ -31,33 +30,36 @@ Built using [built_value][built_value_git]
3130
3231
1. Add the `built_redux` package as a dependency in your `pubspec.yaml`.
3332

34-
```yaml
35-
dependencies:
36-
built_redux: "^5.0.0"
37-
```
38-
39-
2. Create a script to run generators for generating built_values and additional built_redux classes.
40-
```dart
41-
import 'dart:async';
42-
43-
import 'package:build_runner/build_runner.dart';
44-
import 'package:built_value_generator/built_value_generator.dart';
45-
import 'package:source_gen/source_gen.dart';
46-
import 'package:built_redux/generator.dart';
47-
48-
/// Build the generated files in the built_value chat example.
49-
Future main(List<String> args) async {
50-
await build([
51-
new BuildAction(
52-
new PartBuilder([
53-
new BuiltValueGenerator(),
54-
new BuiltReduxGenerator(),
55-
]),
56-
'built_redux',
57-
inputs: const ['test/unit/test_counter.dart'])
58-
], deleteFilesByDefault: true);
59-
}
60-
```
33+
```yaml
34+
dependencies:
35+
built_redux: "^6.0.0"
36+
```
37+
38+
2. Create a script to run generators for generating built_values and built_redux action classes.
39+
```dart
40+
import 'dart:async';
41+
42+
import 'package:build_runner/build_runner.dart';
43+
import 'package:built_value_generator/built_value_generator.dart';
44+
import 'package:source_gen/source_gen.dart';
45+
import 'package:built_redux/generator.dart';
46+
47+
/// Build the generated files in the built_value chat example.
48+
Future main(List<String> args) async {
49+
await build([
50+
new BuildAction(
51+
new PartBuilder([
52+
new BuiltValueGenerator(),
53+
new BuiltReduxGenerator(),
54+
]),
55+
'built_redux',
56+
inputs: const ['test/unit/test_counter.dart'])
57+
], deleteFilesByDefault: true);
58+
}
59+
```
60+
61+
3. Run the build script from the command line to generate your built_values and built_redux action classes
62+
```dart tool/build.dart```
6163

6264
### Writing a built_redux store
6365

@@ -77,19 +79,12 @@ import 'package:built_redux/built_redux.dart';
7779
factory CounterActions() => new _$CounterActions();
7880
}
7981
80-
// This is a BuiltReducer. It is an implementation of the Built and BuiltReducer
81-
// interfaces.
82-
abstract class Counter extends Object
83-
with CounterReducer
84-
implements Built<Counter, CounterBuilder> {
82+
// This is a built value. It is an immutable model that implements the Built interface.
83+
// All of the state in your redux store is contained in a single built value model.
84+
abstract class Counter implements Built<Counter, CounterBuilder> {
8585
/// [count] value of the counter
8686
int get count;
8787
88-
/// reducer returns a map of actions to reducer functions.
89-
/// the generated implementation of reduce will find a reducer function for an action in this map
90-
/// then call the reducer function to rebuild the state.
91-
get reducer => _reducer;
92-
9388
// Built value constructor. The factory is returning the default state
9489
Counter._();
9590
factory BaseCounter() => new _$BaseCounter._(count: 1);
@@ -98,25 +93,26 @@ import 'package:built_redux/built_redux.dart';
9893
9994
// These are reducer functions. They have a (state, action, builder) => void signature.
10095
// They describes how an action transforms the state into the next state by applying changes to the builder supplied.
101-
// You are required to builder passed, calling state.rebuild will NOT update the state in your redux store.
96+
// You are required to use the builder passed, calling state.rebuild will NOT update the state in your redux store.
10297
increment(Counter state, Action<int> action, CounterBuilder builder) =>
103-
builder..count = state.count + action.payload;
98+
builder.count = state.count + action.payload;
10499
105100
decrement(Counter state, Action<int> action, CounterBuilder builder) =>
106-
builder..count = state.count - action.payload;
101+
builder.count = state.count - action.payload;
107102
108103
// This is a reducer builder. Use of ReducerBuilder is not required, however it
109104
// is strongly recommended as it gives you static type checking to make sure
110105
// the payload for action name provided is the same as the expected payload
111-
// for the action provided to your reducer. Calling .build() returns the map
112-
// of action names to reducer functions.
113-
var _reducer = (new ReducerBuilder<Counter, CounterBuilder>()
106+
// for the action provided to your reducer. Calling .build() returns a reducer function
107+
// that can be passed to the store's constructor.
108+
var reducer = (new ReducerBuilder<Counter, CounterBuilder>()
114109
..add(CounterActionsNames.increment, increment)
115110
..add(CounterActionsNames.decrement, decrement)).build();
116111
117112
// Create a Redux store holding the state of your app.
118113
// Its API contains three getters: stream, state, and actions.
119114
var store = new Store<Counter, CounterBuilder, CounterActions>(
115+
reducer,
120116
new Counter(),
121117
new CounterActions(),
122118
);
@@ -133,30 +129,19 @@ store.actions.decrement(1);
133129
// 2
134130
```
135131

136-
### Generated Reducer Mixin
137-
138-
A generated implementation of the BuiltReducer interface will be created for every built value that includes
139-
an extends clause that mixes in a class with the naming scheme {ModelName}Reducer.
140-
(For now this must be the first mixin after the extends clause).
141-
Once the generator is run you can check the .g.dart files for a mixin called {ModelName}Reducer.
142-
In the example above CounterReducer is generated.
143-
144132
### Nested Reducers
145133

146-
A reducer can include vaules that also implement BuiltReducer. In this case NestedCounter
147-
also implements BuiltReducer. This means BaseCounter can handle a different set of actions
148-
than NestedCounter.
134+
Nested reducers can be built to handle rebuilding built values that are
135+
nested within the state tree. This is nice for organization and scoping actions to a specific piece of your application's state.
149136

150137
```dart
151-
abstract class BaseCounter extends Object
152-
with BaseCounterReducer
153-
implements Built<BaseCounter, BaseCounterBuilder> {
138+
// the state model
139+
abstract class BaseCounter implements Built<BaseCounter, BaseCounterBuilder> {
154140
int get count;
155141
142+
// Also a built_value
156143
NestedCounter get nestedCounter;
157144
158-
get reducer => _baseReducer;
159-
160145
// Built value constructor. The factory is returning the default state
161146
BaseCounter._();
162147
factory BaseCounter() => new _$BaseCounter._(
@@ -165,9 +150,38 @@ abstract class BaseCounter extends Object
165150
);
166151
}
167152
153+
// the nested model
154+
abstract class NestedCounter implements Built<NestedCounter, NestedCounterBuilder> {
155+
int get count;
156+
157+
// Built value constructor. The factory is returning the default state
158+
NestedCounter._();
159+
factory NestedCounter() => new _$NestedCounter._(
160+
count: 1,
161+
);
162+
}
163+
164+
// create a nested reducer builder
165+
final nestedReducer = new NestedReducerBuilder<BaseCounter, BaseCounterBuilder,
166+
NestedCounter, NestedCounterBuilder>(
167+
(state) => state.nestedCounter, // maps the app state to the nested state
168+
(builder) => builder.nestedCounter, // maps the app builder to the nested builder
169+
)..add(NestedCounterActionsNames.increment, _nestedIncrement);
170+
171+
// actions registered only rebuild the nested state
172+
// notice the state and builder types are of NestedCounter and NestedCounterBuilder
173+
_nestedIncrement(NestedCounter state, Action<int> action, NestedCounterBuilder builder) =>
174+
builder.count = state.count + action.payload;
175+
176+
// now use ReducerBuilder.combineNested to add it to your main reducer
177+
var reducer = (new ReducerBuilder<Counter, CounterBuilder>()
178+
..add(CounterActionsNames.increment, increment)
179+
..add(CounterActionsNames.decrement, decrement)
180+
..combineNested(nestedReducer)).build();
181+
168182
```
169183

170-
Nested actions can also be used to help organize actions for given reducers. First define your actions:
184+
Nested actions can also be used to help organize actions for nested reducers. First define your actions:
171185

172186
```dart
173187
abstract class NestedActions extends ReduxActions {
@@ -179,7 +193,9 @@ abstract class NestedActions extends ReduxActions {
179193
factory NestedActions() => new _$NestedActions();
180194
}
181195
```
196+
182197
Then add them to your main action class like so:
198+
183199
```dart
184200
abstract class CounterActions extends ReduxActions {
185201
ActionDispatcher<int> increment;
@@ -194,7 +210,9 @@ abstract class CounterActions extends ReduxActions {
194210
```
195211

196212
Check the usage:
213+
197214
```dart
215+
// only print the nested counter's count
198216
store.stream.listen((_) => print(store.state.nestedCounter.count));
199217
200218
// The only way to mutate the internal state is to dispatch an action.
@@ -205,6 +223,7 @@ store.actions.increment(2);
205223
```
206224

207225
### Writing middleware
226+
208227
```dart
209228
// Define specific actions to be handled by this middleware
210229
// A middleware can also listen to and perform side effects on any actions defined elsewhere
@@ -248,6 +267,7 @@ abstract class CounterActions extends ReduxActions {
248267
```
249268

250269
Check the usage after adding this middleware
270+
251271
```dart
252272
// Create a Redux store holding the state of your app.
253273
// Its API is subscribe, state, actions.
@@ -269,6 +289,7 @@ store.actions.decrement(1);
269289
```
270290

271291
A middleware can also be defined without using a MiddlewareBuilder to execute a function for all actions. For example, the following middleware logs every action dispatched as well the the state after the action was handled:
292+
272293
```dart
273294
NextActionHandler loggingMiddleware(MiddlewareApi<Counter, CounterBuilder, CounterActions> api) =>
274295
(ActionHandler next) => (Action action) {
@@ -280,10 +301,12 @@ NextActionHandler loggingMiddleware(MiddlewareApi<Counter, CounterBuilder, Count
280301
```
281302

282303
### Observing substate
304+
283305
Streams can easily be accessed to observe any piece of your state tree by passing a mapper the store's
284306
substateStream function. For example, say I only care about BaseCounter.count
285307
in the previous example and I do not want to be notified when BaseCounter.nestedCounter changes.
286308
I can create a stream that will only emit an event when BaseCounter.count changes, as so:
309+
287310
```dart
288311
final countStream = store.substateStream<int>((BaseCounter state) => state.count);
289312
@@ -296,7 +319,6 @@ store.actions.nestedCounter.increment(2);
296319
297320
```
298321

299-
300322
[built_value_blog]: https://medium.com/dartlang/darts-built-value-for-immutable-object-models-83e2497922d4
301323

302324
[built_value_git]: https://github.com/google/built_value.dart/

Diff for: lib/built_redux.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
library built_redux;
22

33
export 'src/action.dart';
4-
export 'src/built_reducer.dart';
4+
export 'src/reducer_builder.dart';
55
export 'src/middleware.dart';
66
export 'src/state_transformer.dart';
77
export 'src/store.dart';

0 commit comments

Comments
 (0)