- Behaviour change: Initialize
Store
before initializingMiddleware
s. Fixes the issue of having uninitialized store/state oncreate
method, making it crash if action is dispatched inMiddleware.create
.
- Fixed lost state update when listener dispatches an action on
Cursors.forEach
. - Fixed processor to fail on projects without AutoValue in classpath.
- Rebuilt libraries with latest version of Retrolambda (2.4.0). No need to add retrolambda-related proguard rules anymore.
- For processor, made dependency to auto-value compile only.
Added ReductorObservable module that mimics redux-observable. This allows to dispatch async actions and do side-effects in composable way using RxJava.
Introduced two interfaces, both implemented by Store
:
public interface Dispatcher {
void dispatch(Object action);
}
public interface Cursor<State> {
State getState();
Cancelable subscribe(StateChangeListener<State> listener);
}
Cursor
responsible for retrieving the state and observing updates.Dispatcher
responsible for dispatching actions.
That allows you to expose Store
functionality as interfaces to your components.
Having Cursor
interface, it is possible now to have map
operation similar to rx.Observable.map(func)
.
For that purpose new helper class Cursors
with map
function was introduced.
Usage example:
Store<AppState> store = ...;
Cursor<User> userCursor = Cursors.map(store, state -> state.getUser());
//use mapped cursor in component
UserPresenter presenter = new UserPresenter(userCursor);
Mapped cursors allow your components to depend only on specific substate they need, instead of depending on the whole state, knowing on how to get to particular substate.
Current implementation of map
will only propagate unique values, so it's more efficient to pass mapped Cursor
to upper levels of application.
store.forEach(listener)
was moved as static function toCursors.forEach(cursor, listeners)
;action.getValue(index)
now returns generic parameter instead of Object.
Replaced @Generated
annotation with just a comment
Now Middleware
is split into two functional interfaces.
So if old middleware signature was (store, action, nextDisaptcher) => ()
,
the new one will be (store, nextDispatcher) => (action) => ()
.
This middleware structure is much closer to original Redux middleware.
If @AutoReducer.Action(generateActionCreators = true)
,
reductor will generate ActionCreator interface.
The interface will have the same name as reducer with 'Actions' suffix.
Old generated static nested ActionCreator
classes in reducer implementations are no longer supported.
As you may use generated action creators directly, explicitly defining action creator interface is recommended. However generated action creators can be used to prototype your reducer faster, and then generated interface can be copied to the source code.
Added Generated
annotation to all emitted code.
This feature allows defining action creators as interface separately from reducer. This allows:
- Separate action definition and reducer handler.
- Get rid of direct usage of some of the generated code (action creators generated in
AutoReducer
reducers). - Per-action validation for
AutoReducer
reducers to have the same values as in corresponding action creator. - Actions can be "shared" between multiple reducers.
- One reducer can handle actions from multiple Action creators.
To create an instance of Action creator Actions.from(class)
can be used.
Example: interface,
usage.
"Old" action creators in AutoReducer
is deprecated but still supported (will be removed in next version).
- Action class now has multiple values (
Object[] values
instead ofObject value
). - New
Store
methodforEach
: similar tosubscribe
but propagate initial value immediately. - New module
reductor-rxjava2
to observeStore
as RxJava2Observable
orFlowable
.
- Fix reducer code generation for
@CombinedState
class with no properties
- Big update on
@CombinedState
. Now@AutoValue
value classes are supported as combined state! Interfaces as combined state are still supported.
Update code generator for @CombinedState
reducers.
- Remove unnecessary state object allocation if all sub-states are the same.
- Use boxed version of sub-state types in reducer, to remove boxing/unboxing when passing to sub-reducers.
- Rename
reductor-rx
maven artifact toreductor-rxjava
- Updated
rxjava
version to 1.2.1
Major update aimed to improve and simplify initial state population.
- Every
Reducer
now is responsible to populate initial state ifnull
is received as current state inreduce
method; @CombinedState
reducers now initialize state automatically with empty values (null
for objects,false
for booleans,0
for numbers,\u0000
for char);@AutoReducer
annotated reducers now can specify how initial state can be created by introducing method with@AutoReducer.InitialState
annotation (See@AutoReducer.InitialState
javadoc or example);- Added
Store.create
overload withoutinialState
argument; - Now before
Store
is created, special internal action is dispatched to populate initial state;
- Simplify generated code for
@CombinedState
reducers; - Add more compile-time checks and tests;
- Support primitives as state return and argument types for
@AutoReducer.Action
methods.
- @CombinedState: Exclude static and default methods from processing as substates. Allowing to use default methods as selectors
- Cover library and processors with tests
- Added more compile time validation for @AutoReducer and @CombinedState processors
- Processor code cleanup