Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions example/lib/middleware/creation_middleware.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,20 @@ abstract class CreatorActions extends ReduxActions {
factory CreatorActions() => new _$CreatorActions();
}

var creatorMiddeware = (new MiddlwareBuilder<AppState, AppStateActions>()
var creatorMiddeware = (new MiddlwareBuilder<AppState, AppStateBuilder, AppStateActions>()
..add<String>(CreatorActionsNames.createGroup, _createGroup)
..add<String>(CreatorActionsNames.createTodo, _createTodo))
.build();

_createGroup(
MiddlewareApi<AppState, AppStateActions> api, ActionHandler next, Action<String> action) {
_createGroup(MiddlewareApi<AppState, AppStateBuilder, AppStateActions> api, ActionHandler next,
Action<String> action) {
var newGroup = _newGroup(action.payload);
api.actions.groupActions.addGroup(newGroup);
api.actions.setCurrentGroup(newGroup.id);
}

_createTodo(
MiddlewareApi<AppState, AppStateActions> api, ActionHandler next, Action<String> action) {
_createTodo(MiddlewareApi<AppState, AppStateBuilder, AppStateActions> api, ActionHandler next,
Action<String> action) {
var newTodo = _newTodo(action.payload);
api.actions.todosActions.addTodo(newTodo);
api.actions.groupActions.addTodoToGroup(new AddTodoToGroupPayload()
Expand Down
19 changes: 13 additions & 6 deletions example/lib/reducers/app_state.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion example/web/index.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import 'package:example/example.dart';
Future main() async {
react_client.setClientConfiguration();

var reduxStore = new Store<AppState, AppStateActions>(
var reduxStore = new Store<AppState, AppStateBuilder, AppStateActions>(
new AppState(),
new AppStateActions(),
middleware: [creatorMiddeware],
Expand Down
2 changes: 1 addition & 1 deletion lib/src/built_reducer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ abstract class BuiltReducer<V extends Built<V, B>, B extends Builder<V, B>> impl
/// with many different payload types, while maintaining type safety.
/// Each [Reducer] added with add<T> must take a state of type V, an Action of type
/// Action<T>, and a builder of type B
class ReducerBuilder<V extends Built<V, B>, B extends Builder<V, B>> {
class ReducerBuilder<V extends BuiltReducer<V, B>, B extends Builder<V, B>> {
var _map = new Map<String, Reducer<dynamic, V, B>>();

add<T>(ActionName<T> aName, Reducer<T, V, B> reducer) => _map[aName.name] = reducer;
Expand Down
43 changes: 25 additions & 18 deletions lib/src/middleware.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import 'package:built_value/built_value.dart';

import 'action.dart';
import 'built_reducer.dart';
import 'store.dart';
import 'typedefs.dart';

/// [MiddlewareApi] put in scope to your [Middleware] function by redux.
/// When using [MiddlwareBuilder] (recommended) [MiddlewareApi] is passed to your [MiddlewareHandler]
class MiddlewareApi<State extends BuiltReducer, Actions extends ReduxActions> {
Store<State, Actions> _store;
class MiddlewareApi<State extends BuiltReducer<State, StateBuilder>,
StateBuilder extends Builder<State, StateBuilder>, Actions extends ReduxActions> {
Store<State, StateBuilder, Actions> _store;
MiddlewareApi(this._store);

/// [state] returns the current state
Expand All @@ -18,28 +21,32 @@ class MiddlewareApi<State extends BuiltReducer, Actions extends ReduxActions> {

/// [MiddlwareBuilder] allows you to build a reducer that handles many different actions
/// with many different payload types, while maintaining type safety.
/// Each [MiddlewareHandler] added with add<T> must take a state of type V, an Action of type
/// Each [MiddlewareHandler] added with add<T> must take a state of type State, an Action of type
/// Action<T>, and a builder of type B
class MiddlwareBuilder<State extends BuiltReducer, Actions extends ReduxActions> {
var _map = new Map<String, MiddlewareHandler<State, Actions>>();
class MiddlwareBuilder<State extends BuiltReducer<State, StateBuilder>,
StateBuilder extends Builder<State, StateBuilder>, Actions extends ReduxActions> {
var _map = new Map<String, MiddlewareHandler<State, StateBuilder, Actions>>();

add<T>(ActionName<T> aMgr, MiddlewareHandler<State, Actions> handler) => _map[aMgr.name] =
handler;
add<T>(ActionName<T> aMgr, MiddlewareHandler<State, StateBuilder, Actions> handler) =>
_map[aMgr.name] = handler;

/// build returns a [Middlware] function that handles all actions added with [add]
build() => (MiddlewareApi<State, Actions> api) => (ActionHandler next) => (Action action) {
var handler = _map[action.name];
if (handler != null) {
handler(api, next, action);
return;
}

next(action);
};
build() =>
(MiddlewareApi<State, StateBuilder, Actions> api) => (ActionHandler next) => (Action action) {
var handler = _map[action.name];
if (handler != null) {
handler(api, next, action);
return;
}

next(action);
};
}

/// [MiddlewareHandler] is a function that handles an action in a middleware. Its is only for
/// use with [MiddlwareBuilder]. If you are not using [MiddlwareBuilder] middleware must be
/// decalred as a [Middleware] function.
typedef MiddlewareHandler<State extends BuiltReducer, Actions extends ReduxActions>(
MiddlewareApi<State, Actions> api, ActionHandler next, Action action);
typedef MiddlewareHandler<
State extends BuiltReducer<State, StateBuilder>,
StateBuilder extends Builder<State, StateBuilder>,
Actions extends ReduxActions>(MiddlewareApi<State, StateBuilder, Actions> api, ActionHandler next, Action action);
18 changes: 10 additions & 8 deletions lib/src/store.dart
Original file line number Diff line number Diff line change
@@ -1,34 +1,36 @@
import 'dart:async';
import 'dart:core';

import 'package:built_value/built_value.dart';

import 'action.dart';
import 'built_reducer.dart';
import 'middleware.dart';
import 'typedefs.dart';

// TODO: extend disposable
class Store<State extends BuiltReducer, Actions extends ReduxActions> {
class Store<V extends BuiltReducer<V, B>, B extends Builder<V, B>, Actions extends ReduxActions> {
// stream used for dispatching actions
final StreamController<Action<dynamic>> _dispatch = new StreamController.broadcast();

// stream used to dispatch changes to the state
final StreamController<State> _stateController = new StreamController.broadcast();
final StreamController<V> _stateController = new StreamController.broadcast();

// the current state
State _state;
V _state;
Actions _actions;

Store(
State defaultState,
V defaultState,
Actions actions, {
Iterable<Middleware<State>> middleware: const [],
Iterable<Middleware<V, B, Actions>> middleware: const [],
}) {
// set the initial state
_state = defaultState;
_actions = actions;
_actions.syncWithStore(_dispatch.add);

final MiddlewareApi api = new MiddlewareApi<State, Actions>(this);
final MiddlewareApi api = new MiddlewareApi<V, B, Actions>(this);

// setup the middleware dispatch chain
ActionHandler handler = (action) {
Expand Down Expand Up @@ -67,10 +69,10 @@ class Store<State extends BuiltReducer, Actions extends ReduxActions> {
}

/// [subscribe] returns a stream that will be dispatched whenever the state changes
Stream<State> get subscribe => _stateController.stream;
Stream<V> get subscribe => _stateController.stream;

/// [state] returns the current state
State get state => _state;
V get state => _state;

/// [actions] returns the synced actions
Actions get actions => _actions;
Expand Down
4 changes: 3 additions & 1 deletion lib/src/typedefs.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:built_value/built_value.dart';

import 'action.dart';
import 'built_reducer.dart';
import 'middleware.dart';

/// [Reducer] is a function that given a state of type V, an Action of type Action<P>, and a
Expand All @@ -16,4 +17,5 @@ typedef ActionHandler(Action a);
typedef ActionHandler NextActionHandler(ActionHandler next);

/// [Middleware] is a function that given the store's [MiddlewareApi] returns a [NextActionHandler].
typedef NextActionHandler Middleware<State>(MiddlewareApi api);
typedef NextActionHandler Middleware<V extends BuiltReducer<V, B>, B extends Builder<V, B>,
Actions extends ReduxActions>(MiddlewareApi<V, B, Actions> api);
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: built_redux
version: 0.0.7
version: 0.1.0
description:
A state management library written in dart that enforces immutability
authors:
Expand Down
2 changes: 1 addition & 1 deletion test/unit/redux_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import 'test_counter.dart';

main() {
group('redux', () {
Store<BaseCounter, BaseCounterActions> store;
Store<BaseCounter, BaseCounterBuilder, BaseCounterActions> store;

setup({int numMiddleware: 1}) {
var actions = new BaseCounterActions();
Expand Down
11 changes: 6 additions & 5 deletions test/unit/test_counter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,13 @@ abstract class MiddlewareActions extends ReduxActions {
factory MiddlewareActions() => new _$MiddlewareActions();
}

var createCounterMiddleware = (new MiddlwareBuilder<BaseCounter, BaseCounterActions>()
..add<int>(MiddlewareActionsNames.increment, _doubleIt))
.build();
var createCounterMiddleware =
(new MiddlwareBuilder<BaseCounter, BaseCounterBuilder, BaseCounterActions>()
..add<int>(MiddlewareActionsNames.increment, _doubleIt))
.build();

_doubleIt(
MiddlewareApi<BaseCounter, BaseCounterActions> api, ActionHandler next, Action<int> action) {
_doubleIt(MiddlewareApi<BaseCounter, BaseCounterBuilder, BaseCounterActions> api,
ActionHandler next, Action<int> action) {
api.actions.increment(api.state.count * 2);
next(action);
}
3 changes: 2 additions & 1 deletion tool/dev.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ main(List<String> args) async {
config.format..lineLength = 100;

config.analyze
..strong = false
..strong = true
..fatalWarnings = false
..entryPoints = directories;

config.test
Expand Down