2020-01-28 15:51:20 +00:00
# What's Updux?
2020-06-02 20:00:48 +00:00
So, I'm a fan of [Redux ](https://redux.js.org ).
2020-01-28 15:51:20 +00:00
2020-06-02 20:00:48 +00:00
As I was looking into tools to help cut on its boilerplate,
I came across [rematch ](https://rematch.github.io/rematch ).
It has a few pretty darn good ideas.
Keeping mutations and asynchronous effects close to the
2020-01-28 15:51:20 +00:00
reducer definition? Nice. Automatically infering the
actions from the said mutations and effects? Genius!
But it also enforces a flat hierarchy of reducers -- where
is the fun in that? And I'm also having a strong love for
[Updeep ](https://github.com/substantial/updeep ), so I want reducer state updates to leverage the heck out of it.
2020-06-02 20:00:48 +00:00
Hence: `Updux` . Heavily inspired by `rematch` , but twisted
2020-01-28 15:51:20 +00:00
to work with `updeep` and to fit my peculiar needs. It offers features such as
* Mimic the way VueX has mutations (reducer reactions to specific actions) and
effects (middleware reacting to actions that can be asynchronous and/or
have side-effects), so everything pertaining to a store are all defined
in the space place.
* Automatically gather all actions used by the updux's effects and mutations,
and makes then accessible as attributes to the `dispatch` object of the
store.
* Mutations have a signature that is friendly to Updux and Immer.
2020-06-02 20:00:48 +00:00
* Mutations auto-unwrapping the payload of actions for you.
2020-01-28 15:51:20 +00:00
* TypeScript types.
2020-06-02 20:00:48 +00:00
* Leverage [ts-action ](https://www.npmjs.com/package/ts-action ) for action
creation.
2020-01-28 15:51:20 +00:00
2020-06-02 20:00:48 +00:00
**Fair warning**: this package is still very new, likely to go through
big changes before I find the perfect balance between ease of use and sanity.
Caveat Emptor.
2020-01-28 15:51:20 +00:00
# Synopsis
```
2020-06-02 20:00:48 +00:00
import Updux from 'updux';
import { action, payload } from 'ts-action';
import otherDux from './otherUpdux';
2020-01-28 15:51:20 +00:00
2020-06-02 20:00:48 +00:00
const inc = action( 'INC', payload< int > () );
2020-01-28 15:51:20 +00:00
2020-06-02 20:00:48 +00:00
const updux = new Updux({
2020-01-28 15:51:20 +00:00
initial: {
counter: 0,
},
actions: {
2020-06-02 20:00:48 +00:00
inc
2020-01-28 15:51:20 +00:00
},
2020-06-02 20:00:48 +00:00
subduxes: {
otherDux,
}
2020-01-28 15:51:20 +00:00
});
2020-06-02 20:00:48 +00:00
updux.addMutation( inc, increment => u({counter: s => s + increment }));
updux.addEffect( '*', api => next => action => {
console.log( "hey, look, an action zoomed by!", action );
next(action);
} );
const myDux = updux.asDux;
2020-01-28 15:51:20 +00:00
2020-06-02 20:00:48 +00:00
const store = myDux.createStore();
store.dispatch( myDux.actions.inc(3) );
2020-01-28 15:51:20 +00:00
```
# Description
The formal documentation of the class Updux and its associated functions and
types can be found over [here ](https://yanick.github.io/updux/docs/classes/updux.html ).
## Exporting upduxes
If you are creating upduxes that will be used as subduxes
by other upduxes, or as
[ducks ](https://github.com/erikras/ducks-modular-redux )-like containers, I
2020-06-02 20:00:48 +00:00
recommend that you export the "compiled" (as in, no more editable and with all its properties resolved) output of the Updux instance via its `asDux()` getter:
2020-01-28 15:51:20 +00:00
```
import Updux from 'updux';
const updux = new Updux({ ... });
2020-06-02 20:00:48 +00:00
export default updux.asDux;
2020-01-28 15:51:20 +00:00
```
Then you can use them as subduxes like this:
```
import Updux from 'updux';
2020-06-02 20:00:48 +00:00
import foo from './foo'; // foo is a dux
import bar from './bar'; // bar is a dux as well
2020-01-28 15:51:20 +00:00
const updux = new Updux({
subduxes: {
foo, bar
}
});
```