churning things around

This commit is contained in:
Yanick Champoux 2019-11-04 20:34:14 -05:00
parent 122ff71260
commit 82373634ed
57 changed files with 5579 additions and 502 deletions

View File

@ -1,8 +1,8 @@
# Revision history for Updux # Revision history for Updux
NEXT 1.0.0 2019-11-04
- point types to right file. - Pretty big rework.
- add state to updux type. - Better documentation.
0.2.0 2019-10-24 0.2.0 2019-10-24
- Converted everything to Typescript. - Converted everything to Typescript.

362
README.md
View File

@ -6,18 +6,34 @@ So, I'm a fan of [Redux](https://redux.js.org). Two days ago I discovered
It has a couple of pretty good ideas that removes some of the It has a couple of pretty good ideas that removes some of the
boilerplate. Keeping mutations and asynchronous effects close to the boilerplate. Keeping mutations and asynchronous effects close to the
reducer definition, à la [VueX][]? Nice. Automatically infering the reducer definition? Nice. Automatically infering the
actions from the said mutations and effects? Genius! actions from the said mutations and effects? Genius!
But it also enforces a flat hierarchy of reducers -- where But it also enforces a flat hierarchy of reducers -- where
is the fun in that? And I'm also having a strong love for 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. [Updeep](https://github.com/substantial/updeep), so I want reducer state updates to leverage the heck out of it.
All that to say, I had some fun yesterday and hacked a proto-lovechild All that to say, say hello to `Updux`. Heavily inspired by `rematch`, but twisted
of `Rematch` and `Updeep`, with a dash of [VueX](https://vuex.vuejs.org/) inspiration. to work with `updeep` and to fit my peculiar needs. It offers features such as
I call it... `Updux`.
* 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.
* Also, the mutation signature auto-unwrap the payload of the actions for you.
* TypeScript types.
Fair warning: this package is still very new, probably very buggy,
definitively very badly documented, and very subject to changes. Caveat
Maxima Emptor.
# Synopsis # Synopsis
``` ```
import updux from 'updux'; import updux from 'updux';
@ -29,7 +45,7 @@ const {
actions, actions,
middleware, middleware,
createStore, createStore,
} = updux({ } = new Updux({
initial: { initial: {
counter: 0, counter: 0,
}, },
@ -46,7 +62,10 @@ const {
}; };
}, },
actions: { actions: {
customAction: ( someArg ) => ({ someProp: someArg }), customAction: ( someArg ) => ({
type: "custom",
payload: { someProp: someArg }
}),
}, },
}); });
@ -58,329 +77,104 @@ store.dispatch.inc(3);
# Description # Description
`Updux` exports one function, `updux`, both as a named export and as The formal documentation of the class Updux and its associated functions and
its default export. types can be found over [here](./docs/classes/updux.html).
## helpers = updux(config); ## Exporting upduxes
`updux` is a way to minimize and simplify the boilerplate associated with the If you are creating upduxes that will be used as subduxes
creation of a `Redux` store. It takes a shorthand configuration by other upduxes, or as
object, and generates the appropriate reducer, actions, middleware, etc. [ducks](https://github.com/erikras/ducks-modular-redux)-like containers, I
In true `Redux`-like fashion, just like reducers can be composed recommend that you export the Updux instance as the default export:
of sub-reducers, upduxs can be made of sub-upduxs.
### config
The config object recognize following properties.
#### initial
The default initial state of the reducer. Can be anything your
heart desires.
#### subduxes
Object mapping slices of the state to sub-upduxs.
For example, if in plain Redux you would do
``` ```
import { combineReducers } from 'redux'; import Updux from 'updux';
import todosReducer from './todos';
import statisticsReducer from './statistics';
const rootReducer = combineReducers({ const updux = new Updux({ ... });
todos: todosReducer,
stats: statisticsReducer, export default updux;
});
``` ```
then with Updux you'd do
Then you can use them as subduxes like this:
``` ```
import { updux } from 'updux'; import Updux from 'updux';
import todos from './todos'; import foo from './foo'; // foo is an Updux
import statistics from './statistics'; import bar from './bar'; // bar is an Updux as well
const rootUpdux = updux({ const updux = new Updux({
subduxes: { subduxes: {
todos, statistics foo, bar
} }
}); });
``` ```
#### mutations Or if you want to use it:
Object mapping actions to the associated state mutation.
For example, in `Redux` you'd do
``` ```
function todosReducer(state=[],action) { import updux from './myUpdux';
switch(action.type) { const {
case 'ADD': return [ ...state, action.payload ]; reducer,
actions: { doTheThing },
case 'DONE': return state.map( todo => todo.id === action.payload createStore,
? { ...todo, done: true } : todo ) middleware,
} = updux;
default: return state;
}
}
``` ```
With Updux: ## Usage with Immer
While Updux was created with Updeep in mind, it also plays very
well with [Immer](https://immerjs.github.io/immer/docs/introduction).
For example, taking this basic updux:
``` ```
const todosUpdux = updux({ import Updux from 'updux';
const updux = new Updux({
initial: { counter: 0 },
mutations: { mutations: {
add: todo => state => [ ...state, todo ], add: (inc=1) => state => { counter: counter + inc }
done: done_id => u.map( u.if( ({id} => id === done_id), {done: true} ) )
} }
}); });
```
The signature of the mutations is `(payload,action) => state => newState`.
It is designed to play well with `Updeep`. This way, instead of doing
```
mutation: {
renameTodo: newName => state => { ...state, name: newName }
}
``` ```
we can do Converting it to Immer would look like:
``` ```
mutation: { import Updux from 'updux';
renameTodo: newName => u({ name: newName }) import { produce } from 'Immer';
}
```
Also, the special key `*` can be used to match any const updux = new Updux({
action not explicitly matched by other mutations. initial: { counter: 0 },
```
const todosUpdux = updux({
mutations: { mutations: {
add: todo => state => [ ...state, todo ], add: (inc=1) => produce( draft => draft.counter += inc ) }
done: done_id => u.map( u.if( ({id} => id === done_id), {done: true} ) ),
'*' (payload,action) => state => {
console.warn( "unexpected action ", action.type );
return state;
},
} }
}); });
```
#### effects
Plain object defining asynchronous actions and side-effects triggered by actions.
The effects themselves are Redux middleware, expect with the `dispatch`
property of the first argument augmented with all the available actions.
``` ```
updux({
effects: {
fetch: ({dispatch}) => next => async (action) => {
next(action);
let result = await fetch(action.payload.url).then( result => result.json() ); But since typing `produce` over and over is no fun, `groomMutations`
dispatch.fetchSuccess(result); can be used to wrap all mutations with it:
}
}
});
```
### actions
Generic action creations are automatically created from the mutations and effects, but you can
also define custom action creator here. The object's values are function that
transform the arguments of the creator to the action's payload.
``` ```
const { actions } = updox({ import Updux from 'updux';
import { produce } from 'Immer';
const updux = new Updux({
initial: { counter: 0 },
groomMutations: mutation => (...args) => produce( mutation(...args) ),
mutations: { mutations: {
foo: () => state => state, add: (inc=1) => draft => draft.counter += inc
}
actions: {
bar: (x,y) => ({x,y})
} }
}); });
actions.foo({ x: 1, y: 2 }); // => { type: foo, payload: { x:1, y:2 } }
actions.bar(1,2); // => { type: bar, payload: { x:1, y:2 } }
```
## return value
`updux` returns an object with the following properties:
### initial
Default initial state of the reducer. If applicable, merge
the initial states of `config` and `subduxes`, with
`config` having precedence over `subduxes`.
If nothing was given, defaults to an empty object.
### reducer
A Redux reducer generated using the computed initial state and
mutations.
### mutations
Merge of the config and subduxes mutations. If an action trigger
mutations in both the main updux and its subduxes, the subduxes
mutations will be performed first.
### actions
Action creators for all actions defined or used in the actions, mutations, effects and subduxes
of the updox config.
Non-custom action creators defined in `actions` have the signature `(payload={},meta={}) => ({type,
payload,meta})` (with the extra sugar that if `meta` or `payload` are not
specified, the key is not present in the produced action).
If the same action appears in multiple locations, the precedence order
determining which one will prevail is
actions generated from mutations/effects < non-custom subduxes actions <
custom subduxes actions < custom actions
### middleware
A middleware aggregating all the effects defined in the
updox and its subduxes. Effects of the updox itself are
done before the subdoxes effects.
### createStore
Same as doing
```
import { createStore, applyMiddleware } from 'redux';
const { initial, reducer, middleware, actions } = updox(...);
const store = createStore( initial, reducer, applyMiddleware(middleware) );
for ( let type in actions ) {
store.dispatch[type] = (...args) => {
store.dispatch(actions[type](...args))
};
}
```
So that later on you can do
```
store.dispatch.addTodo(...);
// still work
store.dispatch( actions.addTodo(...) );
```
# Example
#### battle.js
```
import { updux } from 'updux';
import game from './game';
import log from './log';
import bogeys from './bogeys';
const { createStore } = updux({
subduxes: { game, log, bogeys }
})
export default createStore;
```
#### game.js
```
import { updux } from 'updux';
import _ from 'lodash';
import u from 'updeep';
import { calculateMovement } from 'game/rules';
export default updux({
initial: { game: "", players: [], turn: 0, },
mutations: {
init_game: ({game: { name, players }}) => {name, players},
play_turn: () => u({ turn: x => x+1 }),
},
effects: {
play_turn: ({getState,dispatch}) => next => action => {
const bogeys = api.getState().bogeys;
// only allow the turn to be played if
// all ships have their orders in
if( bogeys.any( bogey => ! bogey.orders ) ) return;
bogeys.forEach( bogey => {
dispatch.move( calculateMovement(bogey) )
} );
next(action);
},
}
});
``` ```
#### log.js
```
import { updux } from 'updux';
export default updux({
initial: [],
mutations: {
'*': (payload,action) => state => [ ...state, action ],
},
});
```
#### bogeys.js
```
import { updux } from 'updux';
import _ from 'lodash';
export default updux({
initial: [],
mutations: {
init_game: ({bogeys}) => () => _.keyBy( bogeys, 'id' ),
move: ({position}) => u({ position }),
},
});
```
#### myGame.js
```
import Battle from './battle';
const battle = Battle();
battle.dispatch.init_game({
name: 'Gemini Prime',
players: [ 'yenzie' ],
bogeys: [ { id: 'Enkidu' } ]
});
battle.dispatch.play_game();
....
```

7
TODO Normal file
View File

@ -0,0 +1,7 @@
[ ] Warn if one tries to define the same action twice
[ ] Middleware of subduxes get sub-states and getRootState
[ ] add `addAction` method
[ ] can do .addMutation( 'foo', ... );, which either
use the action already existing or create a boring one (should I?)

View File

@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
const _1 = __importDefault(require(".")); const _1 = __importDefault(require("."));
const noopEffect = () => () => () => { }; const noopEffect = () => () => () => { };
test('actions defined in effects and mutations, multi-level', () => { test('actions defined in effects and mutations, multi-level', () => {
const { actions } = _1.default({ const { actions } = new _1.default({
effects: { effects: {
foo: noopEffect, foo: noopEffect,
}, },

View File

@ -1 +1 @@
{"version":3,"file":"actions.test.js","sourceRoot":"","sources":["../src/actions.test.ts"],"names":[],"mappings":";;;;;AAAA,yCAAsB;AAGtB,MAAM,UAAU,GAAG,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC;AAExC,IAAI,CAAC,uDAAuD,EAAE,GAAG,EAAE;IACjE,MAAM,EAAC,OAAO,EAAC,GAAG,UAAK,CAAC;QACtB,OAAO,EAAE;YACP,GAAG,EAAE,UAAU;SAChB;QACD,SAAS,EAAE,EAAC,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,EAAC;QAClC,QAAQ,EAAE;YACR,KAAK,EAAE;gBACL,OAAO,EAAE,EAAC,GAAG,EAAE,UAAU,EAAE;gBAC3B,SAAS,EAAE,EAAC,IAAI,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,EAAC;gBACnC,OAAO,EAAE;oBACP,GAAG,EAAE,CAAC,KAAY,EAAE,EAAE,CAAC,CAAC,EAAC,KAAK,EAAC,CAAC;iBACjC;aACF;YACD,UAAU,EAAE;gBACV,OAAO,EAAE;oBACP,GAAG,EAAE,UAAU;iBAChB;aACF;SACF;KACF,CAAC,CAAC;IAEH,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACnC,KAAK,CAAC,IAAI,EAAE,CAAC;IAEb,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;IAErD,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,EAAC,IAAI,EAAE,KAAK,EAAC,CAAC,CAAC;IAC7C,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,EAAC,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAC,CAAC,CAAC;IAClE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,EAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAC,CAAC,CAAC;IAE1E,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAC,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,EAAC,KAAK,EAAE,EAAE,EAAC,EAAC,CAAC,CAAC;AACvE,CAAC,CAAC,CAAC"} {"version":3,"file":"actions.test.js","sourceRoot":"","sources":["../src/actions.test.ts"],"names":[],"mappings":";;;;;AAAA,yCAAsB;AAGtB,MAAM,UAAU,GAAG,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC;AAExC,IAAI,CAAC,uDAAuD,EAAE,GAAG,EAAE;IACjE,MAAM,EAAC,OAAO,EAAC,GAAG,IAAI,UAAK,CAAC;QAC1B,OAAO,EAAE;YACP,GAAG,EAAE,UAAU;SAChB;QACD,SAAS,EAAE,EAAC,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,EAAC;QAClC,QAAQ,EAAE;YACR,KAAK,EAAE;gBACL,OAAO,EAAE,EAAC,GAAG,EAAE,UAAU,EAAE;gBAC3B,SAAS,EAAE,EAAC,IAAI,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,EAAC;gBACnC,OAAO,EAAE;oBACP,GAAG,EAAE,CAAC,KAAY,EAAE,EAAE,CAAC,CAAC,EAAC,KAAK,EAAC,CAAC;iBACjC;aACF;YACD,UAAU,EAAE;gBACV,OAAO,EAAE;oBACP,GAAG,EAAE,UAAU;iBAChB;aACF;SACF;KACF,CAAC,CAAC;IAEH,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACnC,KAAK,CAAC,IAAI,EAAE,CAAC;IAEb,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;IAErD,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,EAAC,IAAI,EAAE,KAAK,EAAC,CAAC,CAAC;IAC7C,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,EAAC,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAC,CAAC,CAAC;IAClE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,EAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAC,CAAC,CAAC;IAE1E,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAC,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,EAAC,KAAK,EAAE,EAAE,EAAC,EAAC,CAAC,CAAC;AACvE,CAAC,CAAC,CAAC"}

2
dist/addMutations.test.d.ts vendored Normal file
View File

@ -0,0 +1,2 @@
export {};
//# sourceMappingURL=addMutations.test.d.ts.map

1
dist/addMutations.test.d.ts.map vendored Normal file
View File

@ -0,0 +1 @@
{"version":3,"file":"addMutations.test.d.ts","sourceRoot":"","sources":["../src/addMutations.test.ts"],"names":[],"mappings":""}

22
dist/addMutations.test.js vendored Normal file
View File

@ -0,0 +1,22 @@
"use strict";
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const updux_1 = __importStar(require("./updux"));
test('added mutation is present', () => {
const updux = new updux_1.default({
initial: { sum: 0 },
});
const add = updux_1.actionCreator('add', (n) => ({ n }));
updux.addMutation(add, ({ n }, action) => ({ sum }) => ({ sum: sum + n }));
updux.mutations;
const store = updux.createStore();
store.dispatch.add(3);
expect(store.getState()).toEqual({ sum: 3 });
});
//# sourceMappingURL=addMutations.test.js.map

1
dist/addMutations.test.js.map vendored Normal file
View File

@ -0,0 +1 @@
{"version":3,"file":"addMutations.test.js","sourceRoot":"","sources":["../src/addMutations.test.ts"],"names":[],"mappings":";;;;;;;;;AAAA,iDAA+C;AAM/C,IAAI,CAAE,2BAA2B,EAAE,GAAG,EAAE;IACpC,MAAM,KAAK,GAAG,IAAI,eAAK,CAAU;QAC7B,OAAO,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE;KACtB,CAAC,CAAC;IAEH,MAAM,GAAG,GAAG,qBAAa,CAAC,KAAK,EAAE,CAAC,CAAU,EAAE,EAAE,CAAC,CAAC,EAAC,CAAC,EAAC,CAAC,CAAE,CAAA;IAGxD,KAAK,CAAC,WAAW,CACb,GAAG,EAAE,CAAC,EAAC,CAAC,EAAC,EAAC,MAAM,EAAE,EAAE,CAAC,CAAC,EAAC,GAAG,EAAC,EAAE,EAAE,CAAC,CAAC,EAAC,GAAG,EAAE,GAAG,GAAG,CAAC,EAAC,CAAC,CACnD,CAAC;IACF,KAAK,CAAC,SAAS,CAAC;IAChB,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IAClC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAEtB,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;AACjD,CAAC,CAAC,CAAC"}

View File

@ -1,8 +1,7 @@
import { Action, ActionPayloadGenerator, Dictionary } from '../types'; import { ActionCreator, ActionPayloadGenerator, Dictionary } from '../types';
interface ActionCreator { export declare function actionCreator<T extends string, P extends any>(type: T, transform: (...args: any[]) => P): ActionCreator<T, P>;
(...args: any[]): Action; export declare function actionCreator<T extends string>(type: T, transform: never): ActionCreator<T, undefined>;
_genericAction?: boolean; export declare function actionCreator<T extends string>(type: T, transform: null): ActionCreator<T, null>;
}
declare type ActionPair = [string, ActionCreator]; declare type ActionPair = [string, ActionCreator];
declare function buildActions(generators?: Dictionary<ActionPayloadGenerator>, actionNames?: string[], subActions?: ActionPair[]): Dictionary<ActionCreator>; declare function buildActions(generators?: Dictionary<ActionPayloadGenerator>, actionNames?: string[], subActions?: ActionPair[]): Dictionary<ActionCreator>;
export default buildActions; export default buildActions;

View File

@ -1 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/buildActions/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,sBAAsB,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtE,UAAU,aAAa;IACnB,CAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAI,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,OAAO,CAAA;CAC3B;AAYD,aAAK,UAAU,GAAG,CAAE,MAAM,EAAE,aAAa,CAAE,CAAC;AAE5C,iBAAS,YAAY,CACnB,UAAU,GAAG,UAAU,CAAC,sBAAsB,CAAM,EACpD,WAAW,GAAE,MAAM,EAAO,EAC1B,UAAU,GAAG,UAAU,EAAO,GAC9B,UAAU,CAAC,aAAa,CAAC,CAmB1B;AAED,eAAe,YAAY,CAAC"} {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/buildActions/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAU,aAAa,EAAE,sBAAsB,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAErF,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,EAAC,CAAC,SAAS,GAAG,EAAG,IAAI,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,GAAI,aAAa,CAAC,CAAC,EAAC,CAAC,CAAC,CAAA;AAC9H,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,EAAG,IAAI,EAAE,CAAC,EAAE,SAAS,EAAE,KAAK,GAAI,aAAa,CAAC,CAAC,EAAC,SAAS,CAAC,CAAA;AACxG,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,EAAG,IAAI,EAAE,CAAC,EAAE,SAAS,EAAE,IAAI,GAAI,aAAa,CAAC,CAAC,EAAC,IAAI,CAAC,CAAA;AA2BlG,aAAK,UAAU,GAAG,CAAE,MAAM,EAAE,aAAa,CAAE,CAAC;AAE5C,iBAAS,YAAY,CACnB,UAAU,GAAG,UAAU,CAAC,sBAAsB,CAAM,EACpD,WAAW,GAAE,MAAM,EAAO,EAC1B,UAAU,GAAG,UAAU,EAAO,GAC9B,UAAU,CAAC,aAAa,CAAC,CAkB1B;AAED,eAAe,YAAY,CAAC"}

View File

@ -4,10 +4,22 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
}; };
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
const fp_1 = __importDefault(require("lodash/fp")); const fp_1 = __importDefault(require("lodash/fp"));
function actionCreator(type, transform) {
if (transform) {
return Object.assign((...args) => ({ type, payload: transform(...args) }), { type });
}
if (transform === null) {
return Object.assign(() => ({ type }), { type });
}
return Object.assign((payload) => ({ type, payload }));
}
exports.actionCreator = actionCreator;
function actionFor(type) { function actionFor(type) {
const creator = ((payload = undefined, meta = undefined) => fp_1.default.pickBy(v => v !== undefined)({ type, payload, meta })); const f = ((payload = undefined, meta = undefined) => fp_1.default.pickBy(v => v !== undefined)({ type, payload, meta }));
creator._genericAction = true; return Object.assign(f, {
return creator; _genericAction: true,
type
});
} }
function buildActions(generators = {}, actionNames = [], subActions = []) { function buildActions(generators = {}, actionNames = [], subActions = []) {
const [crafted, generic] = fp_1.default.partition(([type, f]) => !f._genericAction)(subActions); const [crafted, generic] = fp_1.default.partition(([type, f]) => !f._genericAction)(subActions);
@ -15,7 +27,7 @@ function buildActions(generators = {}, actionNames = [], subActions = []) {
...(actionNames.map(type => [type, actionFor(type)])), ...(actionNames.map(type => [type, actionFor(type)])),
...generic, ...generic,
...crafted, ...crafted,
...Object.entries(generators).map(([type, payload]) => [type, (...args) => ({ type, payload: payload(...args) })]), ...Object.entries(generators).map(([type, payload]) => [type, payload.type ? payload : (...args) => ({ type, payload: payload(...args) })]),
]; ];
return fp_1.default.fromPairs(actions); return fp_1.default.fromPairs(actions);
} }

View File

@ -1 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/buildActions/index.ts"],"names":[],"mappings":";;;;;AAAA,mDAA2B;AAQ3B,SAAS,SAAS,CAAC,IAAW;IAC5B,MAAM,OAAO,GAAmB,CAAE,CAAC,OAAO,GAAG,SAAS,EAAE,IAAI,GAAG,SAAS,EAAE,EAAE,CAC1E,YAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,EAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAC,CAAW,CACjE,CAAC;IAEF,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAE9B,OAAO,OAAO,CAAC;AACjB,CAAC;AAID,SAAS,YAAY,CACnB,aAAkD,EAAE,EACpD,cAAwB,EAAE,EAC1B,aAA4B,EAAE;IAK9B,MAAM,CAAE,OAAO,EAAE,OAAO,CAAE,GAAG,YAAE,CAAC,SAAS,CACrC,CAAC,CAAC,IAAI,EAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,cAAc,CAClC,CAAE,UAAU,CAAE,CAAC;IAEd,MAAM,OAAO,GAAG;QACZ,GAAG,CAAC,WAAW,CAAC,GAAG,CAAE,IAAI,CAAC,EAAE,CAAC,CAAE,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,CAAE,CAAE,CAAC;QACzD,GAAG,OAAO;QACV,GAAG,OAAO;QACV,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,CAC7B,CAAC,CAAC,IAAI,EAAE,OAAO,CAAuB,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,IAAS,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAC7G;KACJ,CAAC;IAEF,OAAO,YAAE,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;AAEjC,CAAC;AAED,kBAAe,YAAY,CAAC"} {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/buildActions/index.ts"],"names":[],"mappings":";;;;;AAAA,mDAA2B;AAM3B,SAAgB,aAAa,CAAC,IAAQ,EAAE,SAAa;IAEjD,IAAI,SAAS,EAAG;QACZ,OAAO,MAAM,CAAC,MAAM,CAChB,CAAC,GAAG,IAAW,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,EACvD,EAAE,IAAI,EAAE,CAAE,CAAA;KACrB;IAED,IAAI,SAAS,KAAK,IAAI,EAAG;QACrB,OAAO,MAAM,CAAC,MAAM,CAAE,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,CAAE,CAAA;KACrD;IAED,OAAO,MAAM,CAAC,MAAM,CAAE,CAAC,OAAgB,EAAE,EAAE,CAAC,CAAC,EAAC,IAAI,EAAE,OAAO,EAAC,CAAC,CAAE,CAAC;AACpE,CAAC;AAbD,sCAaC;AAED,SAAS,SAAS,CAAC,IAAW;IAC5B,MAAM,CAAC,GAAG,CAAE,CAAC,OAAO,GAAG,SAAS,EAAE,IAAI,GAAG,SAAS,EAAE,EAAE,CACpD,YAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,EAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAC,CAAW,CACjE,CAAC;IAEF,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE;QACpB,cAAc,EAAE,IAAI;QACpB,IAAI;KACP,CAAC,CAAC;AACL,CAAC;AAID,SAAS,YAAY,CACnB,aAAkD,EAAE,EACpD,cAAwB,EAAE,EAC1B,aAA4B,EAAE;IAK9B,MAAM,CAAE,OAAO,EAAE,OAAO,CAAE,GAAG,YAAE,CAAC,SAAS,CACrC,CAAC,CAAC,IAAI,EAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,cAAc,CAClC,CAAE,UAAU,CAAE,CAAC;IAEd,MAAM,OAAO,GAAS;QAClB,GAAG,CAAC,WAAW,CAAC,GAAG,CAAE,IAAI,CAAC,EAAE,CAAC,CAAE,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,CAAE,CAAE,CAAC;QACzD,GAAG,OAAO;QACV,GAAG,OAAO;QACV,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,CAC7B,CAAC,CAAC,IAAI,EAAE,OAAO,CAAuB,EAAO,EAAE,CAAC,CAAC,IAAI,EAAG,OAAe,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,IAAS,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CACpJ;KACJ,CAAC;IAEF,OAAO,YAAE,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;AACjC,CAAC;AAED,kBAAe,YAAY,CAAC"}

View File

@ -1 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/buildMiddleware/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAA2B,MAAM,OAAO,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,aAAa,EAAU,aAAa,EAAE,MAAM,UAAU,CAAC;AAU5E,iBAAS,eAAe,CAAC,CAAC,GAAC,GAAG,EAC1B,OAAO,GAAG,UAAU,CAAC,UAAU,CAAC,EAAE,EAAC,CAAC,EAAC,aAAa,CAAC,CAAK,EACxD,OAAO,GAAG,UAAU,CAAC,aAAa,CAAK,EACvC,cAAc,GAAE,UAAU,CAAC,EAAE,EAAC,CAAC,EAAC,aAAa,CAAC,EAAO,GACtD,UAAU,CAAC,EAAE,EAAC,CAAC,EAAC,aAAa,CAAC,CAkBhC;AAED,eAAe,eAAe,CAAC"} {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/buildMiddleware/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAA2B,MAAM,OAAO,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,aAAa,EAAU,aAAa,EAAE,MAAM,UAAU,CAAC;AAU5E,iBAAS,eAAe,CAAC,CAAC,GAAC,GAAG,EAC1B,OAAO,GAAG,UAAU,CAAC,UAAU,CAAC,EAAE,EAAC,CAAC,EAAC,aAAa,CAAC,CAAK,EACxD,OAAO,GAAG,UAAU,CAAC,aAAa,CAAK,EACvC,cAAc,GAAE,UAAU,CAAC,EAAE,EAAC,CAAC,EAAC,aAAa,CAAC,EAAO,GACtD,UAAU,CAAC,EAAE,EAAC,CAAC,EAAC,aAAa,CAAC,CAoBhC;AAED,eAAe,eAAe,CAAC"}

View File

@ -12,7 +12,8 @@ const MiddlewareFor = (type, mw) => api => next => action => {
function buildMiddleware(effects = {}, actions = {}, subMiddlewares = []) { function buildMiddleware(effects = {}, actions = {}, subMiddlewares = []) {
return (api) => { return (api) => {
for (let type in actions) { for (let type in actions) {
api.dispatch[type] = (...args) => api.dispatch(actions[type](...args)); const ac = actions[type];
api.dispatch[type] = (...args) => api.dispatch(ac(...args));
} }
return (original_next) => { return (original_next) => {
return [ return [

View File

@ -1 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/buildMiddleware/index.ts"],"names":[],"mappings":";;;;;AAAA,mDAA2B;AAK3B,MAAM,aAAa,GAAG,CAAC,IAAS,EAAE,EAAc,EAAe,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;IACtF,IAAI,IAAI,KAAK,GAAG,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC;IAE9D,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC;AACjC,CAAC,CAAC;AAIF,SAAS,eAAe,CACpB,UAAsD,EAAE,EACxD,UAAqC,EAAE,EACvC,iBAAmD,EAAE;IAGvD,OAAO,CAAC,GAAmC,EAAE,EAAE;QAC7C,KAAK,IAAI,IAAI,IAAI,OAAO,EAAE;YACxB,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAU,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAG,OAAe,CAAC,IAAI,CAAS,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;SAChG;QAED,OAAO,CAAC,aAAmB,EAAC,EAAE;YAC5B,OAAO;gBACL,GAAG,YAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,CAC1C,aAAa,CAAC,IAAI,EAAC,MAAoB,CAAC,CAC3C;gBACD,GAAG,cAAc;aAClB;iBACE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;iBACd,WAAW,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC,CAAC;QAC7D,CAAC,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAED,kBAAe,eAAe,CAAC"} {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/buildMiddleware/index.ts"],"names":[],"mappings":";;;;;AAAA,mDAA2B;AAK3B,MAAM,aAAa,GAAG,CAAC,IAAS,EAAE,EAAc,EAAe,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;IACtF,IAAI,IAAI,KAAK,GAAG,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC;IAE9D,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC;AACjC,CAAC,CAAC;AAIF,SAAS,eAAe,CACpB,UAAsD,EAAE,EACxD,UAAqC,EAAE,EACvC,iBAAmD,EAAE;IAGvD,OAAO,CAAC,GAAmC,EAAE,EAAE;QAE7C,KAAK,IAAI,IAAI,IAAI,OAAO,EAAE;YACxB,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;YACzB,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAU,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;SACnE;QAED,OAAO,CAAC,aAAmB,EAAC,EAAE;YAC5B,OAAO;gBACL,GAAG,YAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,CAC1C,aAAa,CAAC,IAAI,EAAC,MAAoB,CAAC,CAC3C;gBACD,GAAG,cAAc;aAClB;iBACE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;iBACd,WAAW,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC,CAAC;QAC7D,CAAC,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAED,kBAAe,eAAe,CAAC"}

View File

@ -1,5 +1,5 @@
/// <reference types="lodash" /> /// <reference types="lodash" />
import { Mutation, Dictionary } from '../types'; import { Mutation, Action, Dictionary } from '../types';
declare function buildMutations(mutations?: Dictionary<Mutation>, subduxes?: {}): import("lodash").Dictionary<Mutation<any>>; declare function buildMutations(mutations?: Dictionary<Mutation>, subduxes?: {}): import("lodash").Dictionary<Mutation<any, Action<string, any>>>;
export default buildMutations; export default buildMutations;
//# sourceMappingURL=index.d.ts.map //# sourceMappingURL=index.d.ts.map

View File

@ -1 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/buildMutations/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAC,QAAQ,EAAU,UAAU,EAAC,MAAM,UAAU,CAAC;AAWtD,iBAAS,cAAc,CACnB,SAAS,GAAE,UAAU,CAAC,QAAQ,CAAM,EACpC,QAAQ,KAAK,8CAgDhB;AAED,eAAe,cAAc,CAAC"} {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/buildMutations/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAC,MAAM,UAAU,CAAC;AAWtD,iBAAS,cAAc,CACnB,SAAS,GAAE,UAAU,CAAC,QAAQ,CAAM,EACpC,QAAQ,KAAK,mEAgDhB;AAED,eAAe,cAAc,CAAC"}

5
dist/index.d.ts vendored
View File

@ -1,4 +1,5 @@
import Updux from './updux'; import Updux from './updux';
import { UpduxConfig } from './types'; export { default as Updux } from './updux';
export default function updux<S = any>(config: UpduxConfig<S>): Updux<S>; export { UpduxConfig } from './types';
export default Updux;
//# sourceMappingURL=index.d.ts.map //# sourceMappingURL=index.d.ts.map

2
dist/index.d.ts.map vendored
View File

@ -1 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,SAAS,CAAC;AAE5B,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEtC,MAAM,CAAC,OAAO,UAAU,KAAK,CAAC,CAAC,GAAC,GAAG,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,YAE1D"} {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,SAAS,CAAC;AAE5B,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EACH,WAAW,EACd,MAAM,SAAS,CAAC;AAEjB,eAAe,KAAK,CAAC"}

7
dist/index.js vendored
View File

@ -4,8 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
}; };
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
const updux_1 = __importDefault(require("./updux")); const updux_1 = __importDefault(require("./updux"));
function updux(config) { var updux_2 = require("./updux");
return new updux_1.default(config); exports.Updux = updux_2.default;
} exports.default = updux_1.default;
exports.default = updux;
//# sourceMappingURL=index.js.map //# sourceMappingURL=index.js.map

2
dist/index.js.map vendored
View File

@ -1 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;AAGA,oDAA4B;AAI5B,SAAwB,KAAK,CAAQ,MAAsB;IACzD,OAAO,IAAI,eAAK,CAAI,MAAM,CAAC,CAAC;AAC9B,CAAC;AAFD,wBAEC"} {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;AAAA,oDAA4B;AAE5B,iCAA2C;AAAlC,wBAAA,OAAO,CAAS;AAKzB,kBAAe,eAAK,CAAC"}

View File

@ -6,14 +6,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
const _1 = __importDefault(require(".")); const _1 = __importDefault(require("."));
test('simple effect', () => { test('simple effect', () => {
const tracer = jest.fn(); const tracer = jest.fn();
const store = _1.default({ const store = (new _1.default({
effects: { effects: {
foo: (api) => (next) => (action) => { foo: (api) => (next) => (action) => {
tracer(); tracer();
next(action); next(action);
}, },
}, },
}).createStore(); })).createStore();
expect(tracer).not.toHaveBeenCalled(); expect(tracer).not.toHaveBeenCalled();
store.dispatch({ type: 'bar' }); store.dispatch({ type: 'bar' });
expect(tracer).not.toHaveBeenCalled(); expect(tracer).not.toHaveBeenCalled();
@ -26,16 +26,17 @@ test('effect and sub-effect', () => {
tracer(signature); tracer(signature);
next(action); next(action);
}; };
const store = _1.default({ const store = (new _1.default({
effects: { effects: {
foo: tracerEffect('root'), foo: tracerEffect('root'),
}, },
subduxes: { subduxes: {
zzz: _1.default({ effects: { zzz: { effects: {
foo: tracerEffect('child'), foo: tracerEffect('child'),
} }) }
}
}, },
}).createStore(); })).createStore();
expect(tracer).not.toHaveBeenCalled(); expect(tracer).not.toHaveBeenCalled();
store.dispatch({ type: 'bar' }); store.dispatch({ type: 'bar' });
expect(tracer).not.toHaveBeenCalled(); expect(tracer).not.toHaveBeenCalled();
@ -45,14 +46,14 @@ test('effect and sub-effect', () => {
}); });
test('"*" effect', () => { test('"*" effect', () => {
const tracer = jest.fn(); const tracer = jest.fn();
const store = _1.default({ const store = (new _1.default({
effects: { effects: {
'*': api => next => action => { '*': api => next => action => {
tracer(); tracer();
next(action); next(action);
}, },
}, },
}).createStore(); })).createStore();
expect(tracer).not.toHaveBeenCalled(); expect(tracer).not.toHaveBeenCalled();
store.dispatch({ type: 'bar' }); store.dispatch({ type: 'bar' });
expect(tracer).toHaveBeenCalled(); expect(tracer).toHaveBeenCalled();
@ -62,7 +63,7 @@ test('async effect', async () => {
return new Promise(resolve => setTimeout(resolve, ms)); return new Promise(resolve => setTimeout(resolve, ms));
} }
const tracer = jest.fn(); const tracer = jest.fn();
const store = _1.default({ const store = (new _1.default({
effects: { effects: {
foo: api => next => async (action) => { foo: api => next => async (action) => {
next(action); next(action);
@ -70,7 +71,7 @@ test('async effect', async () => {
tracer(); tracer();
}, },
}, },
}).createStore(); })).createStore();
expect(tracer).not.toHaveBeenCalled(); expect(tracer).not.toHaveBeenCalled();
store.dispatch.foo(); store.dispatch.foo();
expect(tracer).not.toHaveBeenCalled(); expect(tracer).not.toHaveBeenCalled();

View File

@ -1 +1 @@
{"version":3,"file":"middleware.test.js","sourceRoot":"","sources":["../src/middleware.test.ts"],"names":[],"mappings":"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"} {"version":3,"file":"middleware.test.js","sourceRoot":"","sources":["../src/middleware.test.ts"],"names":[],"mappings":"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"}

8
dist/splat.test.js vendored
View File

@ -7,7 +7,7 @@ const _1 = __importDefault(require("."));
const updeep_1 = __importDefault(require("updeep")); const updeep_1 = __importDefault(require("updeep"));
const tracer = (chr) => updeep_1.default({ tracer: (s = '') => s + chr }); const tracer = (chr) => updeep_1.default({ tracer: (s = '') => s + chr });
test('mutations, simple', () => { test('mutations, simple', () => {
const dux = _1.default({ const dux = new _1.default({
mutations: { mutations: {
foo: () => tracer('a'), foo: () => tracer('a'),
'*': () => tracer('b'), '*': () => tracer('b'),
@ -21,19 +21,19 @@ test('mutations, simple', () => {
expect(store.getState()).toEqual({ tracer: 'bab', }); expect(store.getState()).toEqual({ tracer: 'bab', });
}); });
test('with subduxes', () => { test('with subduxes', () => {
const dux = _1.default({ const dux = new _1.default({
mutations: { mutations: {
foo: () => tracer('a'), foo: () => tracer('a'),
'*': () => tracer('b'), '*': () => tracer('b'),
bar: () => ({ bar }) => ({ bar, tracer: bar.tracer }) bar: () => ({ bar }) => ({ bar, tracer: bar.tracer })
}, },
subduxes: { subduxes: {
bar: _1.default({ bar: {
mutations: { mutations: {
foo: () => tracer('d'), foo: () => tracer('d'),
'*': () => tracer('e'), '*': () => tracer('e'),
}, },
}), },
}, },
}); });
const store = dux.createStore(); const store = dux.createStore();

View File

@ -1 +1 @@
{"version":3,"file":"splat.test.js","sourceRoot":"","sources":["../src/splat.test.ts"],"names":[],"mappings":";;;;;AAAA,yCAAsB;AACtB,oDAAuB;AAEvB,MAAM,MAAM,GAAG,CAAC,GAAU,EAAE,EAAE,CAAC,gBAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,GAAC,EAAE,EAAE,EAAE,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC;AAEhE,IAAI,CAAE,mBAAmB,EAAE,GAAG,EAAE;IAC5B,MAAM,GAAG,GAAG,UAAK,CAAC;QACd,SAAS,EAAE;YACP,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC;YACtB,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC;SACzB;KACJ,CAAC,CAAC;IAEJ,MAAM,KAAK,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;IAE/B,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,EAAC,CAAC,CAAC;IAEjD,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC;IAErB,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,GAAG,CAAC,CAAC;IAEpD,KAAK,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAEhC,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,GAAG,CAAC,CAAC;AACzD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAE,eAAe,EAAE,GAAG,EAAE;IACxB,MAAM,GAAG,GAAG,UAAK,CAAC;QACd,SAAS,EAAE;YACP,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC;YACtB,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC;YACtB,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,EAAC,GAAG,EAAK,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;SAC1D;QACD,QAAQ,EAAE;YACN,GAAG,EAAE,UAAK,CAAC;gBACP,SAAS,EAAE;oBACP,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC;oBACtB,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC;iBACzB;aACJ,CAAC;SACL;KACJ,CAAC,CAAC;IAEJ,MAAM,KAAK,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;IAE/B,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC;QAC7B,MAAM,EAAE,GAAG;QACX,GAAG,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE;KAAE,CAAC,CAAC;IAE5B,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC;IAErB,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC;QAC7B,MAAM,EAAE,IAAI;QACZ,GAAG,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;KAAE,CAAC,CAAC;IAE7B,KAAK,CAAC,QAAQ,CAAC,EAAC,IAAI,EAAE,KAAK,EAAC,CAAC,CAAC;IAE9B,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC;QAC7B,MAAM,EAAE,KAAK;QACb,GAAG,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;KAAE,CAAC,CAAC;AAGlC,CAAC,CAAC,CAAC"} {"version":3,"file":"splat.test.js","sourceRoot":"","sources":["../src/splat.test.ts"],"names":[],"mappings":";;;;;AAAA,yCAAsB;AACtB,oDAAuB;AAEvB,MAAM,MAAM,GAAG,CAAC,GAAU,EAAE,EAAE,CAAC,gBAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,GAAC,EAAE,EAAE,EAAE,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC;AAEhE,IAAI,CAAE,mBAAmB,EAAE,GAAG,EAAE;IAC5B,MAAM,GAAG,GAAG,IAAI,UAAK,CAAC;QAClB,SAAS,EAAE;YACP,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC;YACtB,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC;SACzB;KACJ,CAAC,CAAC;IAEJ,MAAM,KAAK,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;IAE/B,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,EAAC,CAAC,CAAC;IAEjD,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC;IAErB,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,GAAG,CAAC,CAAC;IAEpD,KAAK,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAEhC,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,GAAG,CAAC,CAAC;AACzD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAE,eAAe,EAAE,GAAG,EAAE;IACxB,MAAM,GAAG,GAAG,IAAI,UAAK,CAAC;QAClB,SAAS,EAAE;YACP,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC;YACtB,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC;YACtB,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,EAAC,GAAG,EAAK,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;SAC1D;QACD,QAAQ,EAAE;YACN,GAAG,EAAE;gBACD,SAAS,EAAE;oBACP,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC;oBAClB,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC;iBAC7B;aACJ;SACJ;KACJ,CAAC,CAAC;IAEJ,MAAM,KAAK,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;IAE/B,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC;QAC7B,MAAM,EAAE,GAAG;QACX,GAAG,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE;KAAE,CAAC,CAAC;IAE5B,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC;IAErB,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC;QAC7B,MAAM,EAAE,IAAI;QACZ,GAAG,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;KAAE,CAAC,CAAC;IAE7B,KAAK,CAAC,QAAQ,CAAC,EAAC,IAAI,EAAE,KAAK,EAAC,CAAC,CAAC;IAE9B,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC;QAC7B,MAAM,EAAE,KAAK;QACb,GAAG,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;KAAE,CAAC,CAAC;AAGlC,CAAC,CAAC,CAAC"}

44
dist/test.js vendored
View File

@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
const _1 = __importDefault(require(".")); const _1 = __importDefault(require("."));
test('actions from mutations', () => { test('actions from mutations', () => {
const { actions: { foo, bar }, } = _1.default({ const { actions: { foo, bar }, } = new _1.default({
mutations: { mutations: {
foo: () => (x) => x, foo: () => (x) => x,
}, },
@ -19,7 +19,7 @@ test('actions from mutations', () => {
}); });
}); });
test('reducer', () => { test('reducer', () => {
const { actions, reducer } = _1.default({ const { actions, reducer } = new _1.default({
initial: { counter: 1 }, initial: { counter: 1 },
mutations: { mutations: {
inc: () => ({ counter }) => ({ counter: counter + 1 }), inc: () => ({ counter }) => ({ counter: counter + 1 }),
@ -31,21 +31,21 @@ test('reducer', () => {
expect(state).toEqual({ counter: 2 }); expect(state).toEqual({ counter: 2 });
}); });
test('sub reducers', () => { test('sub reducers', () => {
const foo = _1.default({ const foo = new _1.default({
initial: 1, initial: 1,
mutations: { mutations: {
doFoo: () => (x) => x + 1, doFoo: () => (x) => x + 1,
doAll: () => (x) => x + 10, doAll: () => (x) => x + 10,
}, },
}); });
const bar = _1.default({ const bar = new _1.default({
initial: 'a', initial: 'a',
mutations: { mutations: {
doBar: () => (x) => x + 'a', doBar: () => (x) => x + 'a',
doAll: () => (x) => x + 'b', doAll: () => (x) => x + 'b',
} }
}); });
const { initial, actions, reducer } = _1.default({ const { initial, actions, reducer } = new _1.default({
subduxes: { subduxes: {
foo, bar foo, bar
} }
@ -62,7 +62,7 @@ test('sub reducers', () => {
expect(state).toEqual({ foo: 12, bar: 'aab' }); expect(state).toEqual({ foo: 12, bar: 'aab' });
}); });
test('precedence between root and sub-reducers', () => { test('precedence between root and sub-reducers', () => {
const { initial, reducer, actions, } = _1.default({ const { initial, reducer, actions, } = new _1.default({
initial: { initial: {
foo: { bar: 4 }, foo: { bar: 4 },
}, },
@ -75,7 +75,7 @@ test('precedence between root and sub-reducers', () => {
} }
}, },
subduxes: { subduxes: {
foo: _1.default({ foo: {
initial: { initial: {
bar: 2, bar: 2,
quux: 3, quux: 3,
@ -83,7 +83,7 @@ test('precedence between root and sub-reducers', () => {
mutations: { mutations: {
inc: () => (state) => ({ ...state, bar: state.bar + 1 }) inc: () => (state) => ({ ...state, bar: state.bar + 1 })
}, },
}), },
} }
}); });
expect(initial).toEqual({ expect(initial).toEqual({
@ -97,7 +97,7 @@ function timeout(ms) {
return new Promise(resolve => setTimeout(resolve, ms)); return new Promise(resolve => setTimeout(resolve, ms));
} }
test('middleware', async () => { test('middleware', async () => {
const { middleware, createStore } = _1.default({ const { middleware, createStore } = new _1.default({
initial: "", initial: "",
mutations: { mutations: {
inc: (addition) => (state) => state + addition, inc: (addition) => (state) => state + addition,
@ -114,14 +114,14 @@ test('middleware', async () => {
} }
}, },
subduxes: { subduxes: {
foo: _1.default({ foo: {
effects: { effects: {
doEeet: (api) => next => action => { doEeet: (api) => (next) => (action) => {
api.dispatch({ type: 'inc', payload: 'b' }); api.dispatch({ type: 'inc', payload: 'b' });
next(action); next(action);
} }
} }
}), },
} }
}); });
const store = createStore(); const store = createStore();
@ -130,4 +130,24 @@ test('middleware', async () => {
await timeout(1000); await timeout(1000);
expect(store.getState()).toEqual('abZc'); expect(store.getState()).toEqual('abZc');
}); });
test("subduxes and mutations", () => {
const foo = new _1.default({ mutations: {
quux: () => () => 'x',
blart: () => () => 'a',
} });
const bar = new _1.default({ mutations: {
quux: () => () => 'y'
} });
const baz = new _1.default({
mutations: {
quux: () => (state) => ({ ...state, "baz": "z" })
}, subduxes: { foo, bar }
});
let state = baz.reducer(undefined, baz.actions.quux());
expect(state).toEqual({
foo: "x",
bar: "y",
baz: "z",
});
});
//# sourceMappingURL=test.js.map //# sourceMappingURL=test.js.map

2
dist/test.js.map vendored

File diff suppressed because one or more lines are too long

38
dist/types.d.ts vendored
View File

@ -1,24 +1,32 @@
import { Dispatch, Middleware } from 'redux'; import { Dispatch, Middleware } from 'redux';
export declare type Action = { declare type MaybePayload<P> = P extends object | string | boolean | number ? {
type: string; payload: P;
payload?: any; } : {
meta?: any; payload?: P;
}; };
export declare type Action<T extends string = string, P = any> = {
type: T;
} & MaybePayload<P>;
export declare type Dictionary<T> = { export declare type Dictionary<T> = {
[key: string]: T; [key: string]: T;
}; };
export declare type Mutation<S = any> = (payload: any, action: Action) => (state: S) => S; export declare type Mutation<S = any, A extends Action = Action> = (payload: A['payload'], action: A) => (state: S) => S;
export declare type ActionPayloadGenerator = (...args: any[]) => any; export declare type ActionPayloadGenerator = (...args: any[]) => any;
export declare type ActionCreator = (...args: any[]) => Action; export declare type ActionCreator<T extends string = string, P = any> = {
export declare type UpduxDispatch = Dispatch & Dictionary<ActionCreator>; type: T;
export declare type UpduxConfig<S = any> = Partial<{ _genericAction?: boolean;
initial: S; } & ((...args: any[]) => Action<T, P>);
subduxes: {}; export declare type UpduxDispatch = Dispatch & Dictionary<Function>;
actions: { export declare type UpduxConfig<S = any> = {
[type: string]: ActionPayloadGenerator; initial?: S;
subduxes?: {};
actions?: {
[type: string]: ActionCreator;
};
mutations?: any;
groomMutations?: (m: Mutation<S>) => Mutation<S>;
effects?: Dictionary<Middleware<{}, S, UpduxDispatch>>;
}; };
mutations: any;
effects: Dictionary<Middleware<{}, S, UpduxDispatch>>;
}>;
export declare type Upreducer<S = any> = (action: Action) => (state: S) => S; export declare type Upreducer<S = any> = (action: Action) => (state: S) => S;
export {};
//# sourceMappingURL=types.d.ts.map //# sourceMappingURL=types.d.ts.map

2
dist/types.d.ts.map vendored
View File

@ -1 +1 @@
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAE7C,oBAAY,MAAM,GAAG;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,IAAI,CAAC,EAAE,GAAG,CAAC;CACd,CAAA;AAED,oBAAY,UAAU,CAAC,CAAC,IAAI;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,CAAA;CAAE,CAAC;AAEjD,oBAAY,QAAQ,CAAC,CAAC,GAAC,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAE;AAEjF,oBAAY,sBAAsB,GAAG,CAAC,GAAG,IAAI,EAAC,GAAG,EAAE,KAAK,GAAG,CAAC;AAE5D,oBAAY,aAAa,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAM,MAAM,CAAC;AAExD,oBAAY,aAAa,GAAG,QAAQ,GAAG,UAAU,CAAC,aAAa,CAAC,CAAC;AAEjE,oBAAY,WAAW,CAAC,CAAC,GAAC,GAAG,IAAI,OAAO,CAAC;IACrC,OAAO,EAAE,CAAC,CAAC;IACX,QAAQ,EAAE,EAAE,CAAC;IACb,OAAO,EAAE;QACL,CAAE,IAAI,EAAE,MAAM,GAAI,sBAAsB,CAAA;KAC3C,CAAC;IACF,SAAS,EAAE,GAAG,CAAC;IACf,OAAO,EAAE,UAAU,CAAC,UAAU,CAAC,EAAE,EAAC,CAAC,EAAC,aAAa,CAAC,CAAC,CAAC;CACvD,CAAC,CAAC;AAEH,oBAAY,SAAS,CAAC,CAAC,GAAC,GAAG,IAAI,CAAC,MAAM,EAAC,MAAM,KAAK,CAAC,KAAK,EAAC,CAAC,KAAK,CAAC,CAAC"} {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAE,UAAU,EAAC,MAAM,OAAO,CAAC;AAE3C,aAAK,YAAY,CAAC,CAAC,IAAI,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAC/D;IACE,OAAO,EAAE,CAAC,CAAC;CACZ,GACD;IAAC,OAAO,CAAC,EAAE,CAAC,CAAA;CAAC,CAAC;AAElB,oBAAY,MAAM,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,GAAG,IAAI;IACvD,IAAI,EAAE,CAAC,CAAC;CACT,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;AAEpB,oBAAY,UAAU,CAAC,CAAC,IAAI;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,CAAA;CAAC,CAAC;AAE/C,oBAAY,QAAQ,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI,CACzD,OAAO,EAAE,CAAC,CAAC,SAAS,CAAC,EACrB,MAAM,EAAE,CAAC,KACN,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC;AAErB,oBAAY,sBAAsB,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC;AAE7D,oBAAY,aAAa,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,GAAG,IAAI;IAC9D,IAAI,EAAE,CAAC,CAAC;IACR,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,GAAG,CAAC,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAEvC,oBAAY,aAAa,GAAG,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;AAO5D,oBAAY,WAAW,CAAC,CAAC,GAAC,GAAG,IAAI;IAK/B,OAAO,CAAC,EAAE,CAAC,CAAC;IA+BZ,QAAQ,CAAC,EAAE,EAAE,CAAC;IAsBd,OAAO,CAAC,EAAE;QACR,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CAAC;KAC/B,CAAC;IAgEF,SAAS,CAAC,EAAE,GAAG,CAAC;IAEhB,cAAc,CAAC,EAAE,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC;IAqBjD,OAAO,CAAC,EAAE,UAAU,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC;CACxD,CAAC;AAEF,oBAAY,SAAS,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC"}

22
dist/updux.d.ts vendored
View File

@ -1,5 +1,6 @@
import { UpduxConfig, Dictionary, Action, ActionCreator, Mutation, Upreducer, UpduxDispatch } from './types'; import { UpduxConfig, Dictionary, Action, ActionCreator, Mutation, Upreducer, UpduxDispatch } from './types';
import { Middleware, Store } from 'redux'; import { Middleware, Store } from 'redux';
export { actionCreator } from './buildActions';
declare type StoreWithDispatchActions<S = any, Actions = { declare type StoreWithDispatchActions<S = any, Actions = {
[action: string]: (...args: any) => Action; [action: string]: (...args: any) => Action;
}> = Store<S> & { }> = Store<S> & {
@ -7,16 +8,23 @@ declare type StoreWithDispatchActions<S = any, Actions = {
[type in keyof Actions]: (...args: any) => void; [type in keyof Actions]: (...args: any) => void;
}; };
}; };
export declare type Dux<S> = Pick<Updux<S>, 'subduxes' | 'actions' | 'initial' | 'mutations' | 'reducer' | 'middleware' | 'createStore' | 'upreducer'>;
export declare class Updux<S = any> { export declare class Updux<S = any> {
subduxes: Dictionary<Updux>; subduxes: Dictionary<Updux>;
actions: Dictionary<ActionCreator>;
initial: S; initial: S;
mutations: Dictionary<Mutation>; groomMutations: (mutation: Mutation<S>) => Mutation<S>;
upreducer: Upreducer<S>; private localEffects;
reducer: (state: S | undefined, action: Action) => S; private localActions;
middleware: Middleware<{}, S, UpduxDispatch>; private localMutations;
createStore: () => StoreWithDispatchActions<S>; constructor(config?: UpduxConfig);
constructor(config: UpduxConfig); readonly middleware: Middleware<{}, S, UpduxDispatch>;
readonly actions: Dictionary<ActionCreator>;
readonly upreducer: Upreducer<S>;
readonly reducer: (state: S | undefined, action: Action) => S;
readonly mutations: Dictionary<Mutation<S>>;
readonly createStore: () => StoreWithDispatchActions<S>;
readonly asDux: Dux<S>;
addMutation<A extends ActionCreator>(creator: A, mutation: Mutation<S, A extends (...args: any[]) => infer R ? R : never>): void;
} }
export default Updux; export default Updux;
//# sourceMappingURL=updux.d.ts.map //# sourceMappingURL=updux.d.ts.map

2
dist/updux.d.ts.map vendored
View File

@ -1 +1 @@
{"version":3,"file":"updux.d.ts","sourceRoot":"","sources":["../src/updux.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7G,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAE1C,aAAK,wBAAwB,CAAC,CAAC,GAAC,GAAG,EAAC,OAAO,GAAC;IAAE,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,EAAC,GAAG,KAAK,MAAM,CAAA;CAAE,IAAI,KAAK,CAAC,CAAC,CAAC,GAAG;IACpG,QAAQ,EAAE;SAAI,IAAI,IAAI,MAAM,OAAO,GAAI,CAAC,GAAG,IAAI,EAAC,GAAG,KAAK,IAAI;KAAE,CAAA;CACjE,CAAC;AAEF,qBAAa,KAAK,CAAC,CAAC,GAAC,GAAG;IAEpB,QAAQ,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC;IAE5B,OAAO,EAAE,UAAU,CAAC,aAAa,CAAC,CAAA;IAElC,OAAO,EAAE,CAAC,CAAC;IAEX,SAAS,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC;IAEhC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;IAExB,OAAO,EAAE,CAAC,KAAK,EAAC,CAAC,GAAC,SAAS,EAAC,MAAM,EAAC,MAAM,KAAK,CAAC,CAAC;IAEhD,UAAU,EAAE,UAAU,CAAC,EAAE,EAAC,CAAC,EAAC,aAAa,CAAC,CAAC;IAE3C,WAAW,EAAE,MAAM,wBAAwB,CAAC,CAAC,CAAC,CAAC;gBAEnC,MAAM,EAAE,WAAW;CAwClC;AAED,eAAe,KAAK,CAAC"} {"version":3,"file":"updux.d.ts","sourceRoot":"","sources":["../src/updux.ts"],"names":[],"mappings":"AAWA,OAAO,EACL,WAAW,EACX,UAAU,EACV,MAAM,EACN,aAAa,EACb,QAAQ,EACR,SAAS,EACT,aAAa,EACd,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAC,UAAU,EAAE,KAAK,EAAC,MAAM,OAAO,CAAC;AACxC,OAAO,EAAC,aAAa,EAAC,MAAM,gBAAgB,CAAC;AAE7C,aAAK,wBAAwB,CAC3B,CAAC,GAAG,GAAG,EACP,OAAO,GAAG;IAAC,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,KAAK,MAAM,CAAA;CAAC,IACpD,KAAK,CAAC,CAAC,CAAC,GAAG;IACb,QAAQ,EAAE;SAAE,IAAI,IAAI,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,KAAK,IAAI;KAAC,CAAC;CAC7D,CAAC;AAEF,oBAAY,GAAG,CAAC,CAAC,IAAI,IAAI,CACvB,KAAK,CAAC,CAAC,CAAC,EACN,UAAU,GACV,SAAS,GACT,SAAS,GACT,WAAW,GACX,SAAS,GACT,YAAY,GACZ,aAAa,GACb,WAAW,CACd,CAAC;AASF,qBAAa,KAAK,CAAC,CAAC,GAAG,GAAG;IACxB,QAAQ,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC;IAS5B,OAAO,EAAE,CAAC,CAAC;IAqCX,cAAc,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC;IAE3C,OAAO,CAAC,YAAY,CAE9B;IAEU,OAAO,CAAC,YAAY,CAA4B;IAEhD,OAAO,CAAC,cAAc,CAA0B;gBAEhD,MAAM,GAAE,WAAgB;aA0BtB,UAAU,EAAI,UAAU,CAAC,EAAE,EAAE,CAAC,EAAE,aAAa,CAAC;aAsB9C,OAAO,EAAI,UAAU,CAAC,aAAa,CAAC;aAYpC,SAAS,EAAI,SAAS,CAAC,CAAC,CAAC;aAQzB,OAAO,EAAI,CAAC,KAAK,EAAE,CAAC,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;aAStD,SAAS,EAAI,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;aA6BpC,WAAW,EAAI,MAAM,wBAAwB,CAAC,CAAC,CAAC;aAiB1D,KAAK,EAAI,GAAG,CAAC,CAAC,CAAC;IAsBnB,WAAW,CAAC,CAAC,SAAS,aAAa,EACjC,OAAO,EAAE,CAAC,EACV,QAAQ,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;CAO3E;AAED,eAAe,KAAK,CAAC"}

84
dist/updux.js vendored
View File

@ -1,30 +1,96 @@
"use strict"; "use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __importDefault = (this && this.__importDefault) || function (mod) { var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod }; return (mod && mod.__esModule) ? mod : { "default": mod };
}; };
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
const fp_1 = __importDefault(require("lodash/fp")); const fp_1 = __importDefault(require("lodash/fp"));
const mobx_1 = require("mobx");
const buildActions_1 = __importDefault(require("./buildActions")); const buildActions_1 = __importDefault(require("./buildActions"));
const buildInitial_1 = __importDefault(require("./buildInitial")); const buildInitial_1 = __importDefault(require("./buildInitial"));
const buildMutations_1 = __importDefault(require("./buildMutations")); const buildMutations_1 = __importDefault(require("./buildMutations"));
const buildCreateStore_1 = __importDefault(require("./buildCreateStore")); const buildCreateStore_1 = __importDefault(require("./buildCreateStore"));
const buildMiddleware_1 = __importDefault(require("./buildMiddleware")); const buildMiddleware_1 = __importDefault(require("./buildMiddleware"));
const buildUpreducer_1 = __importDefault(require("./buildUpreducer")); const buildUpreducer_1 = __importDefault(require("./buildUpreducer"));
var buildActions_2 = require("./buildActions");
exports.actionCreator = buildActions_2.actionCreator;
class Updux { class Updux {
constructor(config) { constructor(config = {}) {
this.groomMutations = config.groomMutations || ((x) => x);
this.subduxes = fp_1.default.mapValues((value) => fp_1.default.isPlainObject(value) ? new Updux(value) : value)(fp_1.default.getOr({}, 'subduxes', config)); this.subduxes = fp_1.default.mapValues((value) => fp_1.default.isPlainObject(value) ? new Updux(value) : value)(fp_1.default.getOr({}, 'subduxes', config));
this.actions = buildActions_1.default(config.actions, [...Object.keys(config.mutations || {}), ...Object.keys(config.effects || {})], fp_1.default.flatten(Object.values(this.subduxes).map(({ actions }) => Object.entries(actions)))); this.localActions = fp_1.default.getOr({}, 'actions', config);
this.localEffects = fp_1.default.getOr({}, 'effects', config);
this.initial = buildInitial_1.default(config.initial, fp_1.default.mapValues(({ initial }) => initial)(this.subduxes)); this.initial = buildInitial_1.default(config.initial, fp_1.default.mapValues(({ initial }) => initial)(this.subduxes));
this.mutations = buildMutations_1.default(config.mutations, this.subduxes); this.localMutations = fp_1.default.mapValues((m) => this.groomMutations(m))(fp_1.default.getOr({}, 'mutations', config));
this.upreducer = buildUpreducer_1.default(this.initial, this.mutations); }
this.reducer = (state, action) => { get middleware() {
return this.upreducer(action)(state); return buildMiddleware_1.default(this.localEffects, this.actions, Object.values(this.subduxes).map(sd => sd.middleware));
}; }
this.middleware = buildMiddleware_1.default(config.effects, this.actions, Object.values(this.subduxes).map(sd => sd.middleware)); get actions() {
return buildActions_1.default(this.localActions, [...Object.keys(this.localMutations), ...Object.keys(this.localEffects)], fp_1.default.flatten(Object.values(this.subduxes).map(({ actions }) => Object.entries(actions))));
}
get upreducer() {
return buildUpreducer_1.default(this.initial, this.mutations);
}
get reducer() {
return (state, action) => this.upreducer(action)(state);
}
get mutations() {
return buildMutations_1.default(this.localMutations, this.subduxes);
}
get createStore() {
const actions = this.actions; const actions = this.actions;
this.createStore = buildCreateStore_1.default(this.reducer, this.initial, this.middleware, this.actions); return buildCreateStore_1.default(this.reducer, this.initial, this.middleware, this.actions);
}
get asDux() {
return {
createStore: this.createStore,
upreducer: this.upreducer,
subduxes: this.subduxes,
middleware: this.middleware,
actions: this.actions,
reducer: this.reducer,
mutations: this.mutations,
initial: this.initial,
};
}
addMutation(creator, mutation) {
this.localActions[creator.type] = creator;
this.localMutations[creator.type] = this.groomMutations(mutation);
} }
} }
__decorate([
mobx_1.observable
], Updux.prototype, "localEffects", void 0);
__decorate([
mobx_1.observable
], Updux.prototype, "localActions", void 0);
__decorate([
mobx_1.observable
], Updux.prototype, "localMutations", void 0);
__decorate([
mobx_1.computed
], Updux.prototype, "middleware", null);
__decorate([
mobx_1.computed
], Updux.prototype, "actions", null);
__decorate([
mobx_1.computed
], Updux.prototype, "upreducer", null);
__decorate([
mobx_1.computed
], Updux.prototype, "reducer", null);
__decorate([
mobx_1.computed
], Updux.prototype, "mutations", null);
__decorate([
mobx_1.computed
], Updux.prototype, "createStore", null);
exports.Updux = Updux; exports.Updux = Updux;
exports.default = Updux; exports.default = Updux;
//# sourceMappingURL=updux.js.map //# sourceMappingURL=updux.js.map

2
dist/updux.js.map vendored
View File

@ -1 +1 @@
{"version":3,"file":"updux.js","sourceRoot":"","sources":["../src/updux.ts"],"names":[],"mappings":";;;;;AAAA,mDAA2B;AAC3B,kEAA0C;AAC1C,kEAA0C;AAC1C,sEAA8C;AAE9C,0EAAkD;AAClD,wEAAgD;AAChD,sEAA8C;AAS9C,MAAa,KAAK;IAkBd,YAAY,MAAmB;QAE3B,IAAI,CAAC,QAAQ,GAAG,YAAE,CAAC,SAAS,CACxB,CAAC,KAAuB,EAAE,EAAE,CAAC,YAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAE,CAAC,YAAE,CAAC,KAAK,CAAC,EAAE,EAAC,UAAU,EAAC,MAAM,CAAC,CAC9F,CAAC;QAGvB,IAAI,CAAC,OAAO,GAAG,sBAAY,CACvB,MAAM,CAAC,OAAO,EACd,CAAE,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,IAAE,EAAE,CAAC,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,IAAE,EAAE,CAAE,CAAE,EAC7E,YAAE,CAAC,OAAO,CAAE,MAAM,CAAC,MAAM,CAAE,IAAI,CAAC,QAAQ,CAAE,CAAC,GAAG,CAAE,CAAC,EAAC,OAAO,EAAO,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAE,CAAE,CACnG,CAAA;QAED,IAAI,CAAC,OAAO,GAAG,sBAAY,CACvB,MAAM,CAAC,OAAO,EAAE,YAAE,CAAC,SAAS,CAAE,CAAC,EAAC,OAAO,EAAC,EAAE,EAAE,CAAC,OAAO,CAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CACxE,CAAC;QAEF,IAAI,CAAC,SAAS,GAAG,wBAAc,CAC3B,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,QAAQ,CAClC,CAAC;QAEF,IAAI,CAAC,SAAS,GAAG,wBAAc,CAC3B,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAC/B,CAAC;QAEF,IAAI,CAAC,OAAO,GAAG,CAAC,KAAK,EAAC,MAAM,EAAE,EAAE;YAC5B,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,KAAU,CAAC,CAAC;QAC9C,CAAC,CAAA;QAED,IAAI,CAAC,UAAU,GAAG,yBAAe,CAC7B,MAAM,CAAC,OAAO,EACd,IAAI,CAAC,OAAO,EACZ,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAE,CAC1D,CAAC;QAEF,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QAC7B,IAAI,CAAC,WAAW,GAAG,0BAAgB,CAAI,IAAI,CAAC,OAAO,EAAC,IAAI,CAAC,OAAO,EAAC,IAAI,CAAC,UAAwB,EAAC,IAAI,CAAC,OAAO,CACvD,CAAC;IACzD,CAAC;CAEJ;AA1DD,sBA0DC;AAED,kBAAe,KAAK,CAAC"} {"version":3,"file":"updux.js","sourceRoot":"","sources":["../src/updux.ts"],"names":[],"mappings":"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"}

2333
docs/assets/css/main.css Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 480 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 855 B

1
docs/assets/js/main.js Normal file

File diff suppressed because one or more lines are too long

3
docs/assets/js/search.js Normal file

File diff suppressed because one or more lines are too long

729
docs/classes/updux.html Normal file
View File

@ -0,0 +1,729 @@
<!doctype html>
<html class="default no-js">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Updux | updux</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="../assets/css/main.css">
</head>
<body>
<header>
<div class="tsd-page-toolbar">
<div class="container">
<div class="table-wrap">
<div class="table-cell" id="tsd-search" data-index="../assets/js/search.js" data-base="..">
<div class="field">
<label for="tsd-search-field" class="tsd-widget search no-caption">Search</label>
<input id="tsd-search-field" type="text" />
</div>
<ul class="results">
<li class="state loading">Preparing search index...</li>
<li class="state failure">The search index is not available</li>
</ul>
<a href="../index.html" class="title">updux</a>
</div>
<div class="table-cell" id="tsd-widgets">
<div id="tsd-filter">
<a href="#" class="tsd-widget options no-caption" data-toggle="options">Options</a>
<div class="tsd-filter-group">
<div class="tsd-select" id="tsd-filter-visibility">
<span class="tsd-select-label">All</span>
<ul class="tsd-select-list">
<li data-value="public">Public</li>
<li data-value="protected">Public/Protected</li>
<li data-value="private" class="selected">All</li>
</ul>
</div>
<input type="checkbox" id="tsd-filter-inherited" checked />
<label class="tsd-widget" for="tsd-filter-inherited">Inherited</label>
<input type="checkbox" id="tsd-filter-externals" checked />
<label class="tsd-widget" for="tsd-filter-externals">Externals</label>
<input type="checkbox" id="tsd-filter-only-exported" />
<label class="tsd-widget" for="tsd-filter-only-exported">Only exported</label>
</div>
</div>
<a href="#" class="tsd-widget menu no-caption" data-toggle="menu">Menu</a>
</div>
</div>
</div>
</div>
<div class="tsd-page-title">
<div class="container">
<ul class="tsd-breadcrumb">
<li>
<a href="../globals.html">Globals</a>
</li>
<li>
<a href="updux.html">Updux</a>
</li>
</ul>
<h1>Class Updux&lt;S&gt;</h1>
</div>
</div>
</header>
<div class="container container-main">
<div class="row">
<div class="col-8 col-content">
<section class="tsd-panel tsd-comment">
<div class="tsd-comment tsd-typography">
<div class="lead">
<p><code>Updux</code> is a way to minimize and simplify the boilerplate associated with the
creation of a <code>Redux</code> store. It takes a shorthand configuration
object, and generates the appropriate reducer, actions, middleware, etc.
In true <code>Redux</code>-like fashion, upduxes can be made of sub-upduxes (<code>subduxes</code> for short) for different slices of the root state.</p>
</div>
</div>
</section>
<section class="tsd-panel tsd-type-parameters">
<h3>Type parameters</h3>
<ul class="tsd-type-parameters">
<li>
<h4>S</h4>
<div class="tsd-comment tsd-typography">
<div class="lead">
<p>Store&#39;s state type. Defaults to <code>any</code>.</p>
</div>
</div>
</li>
</ul>
</section>
<section class="tsd-panel tsd-hierarchy">
<h3>Hierarchy</h3>
<ul class="tsd-hierarchy">
<li>
<span class="target">Updux</span>
</li>
</ul>
</section>
<section class="tsd-panel-group tsd-index-group">
<h2>Index</h2>
<section class="tsd-panel tsd-index-panel">
<div class="tsd-index-content">
<section class="tsd-index-section ">
<h3>Constructors</h3>
<ul class="tsd-index-list">
<li class="tsd-kind-constructor tsd-parent-kind-class"><a href="updux.html#constructor" class="tsd-kind-icon">constructor</a></li>
</ul>
</section>
<section class="tsd-index-section ">
<h3>Properties</h3>
<ul class="tsd-index-list">
<li class="tsd-kind-property tsd-parent-kind-class"><a href="updux.html#groommutations" class="tsd-kind-icon">groom<wbr>Mutations</a></li>
<li class="tsd-kind-property tsd-parent-kind-class"><a href="updux.html#initial" class="tsd-kind-icon">initial</a></li>
<li class="tsd-kind-property tsd-parent-kind-class"><a href="updux.html#subduxes" class="tsd-kind-icon">subduxes</a></li>
</ul>
</section>
<section class="tsd-index-section ">
<h3>Accessors</h3>
<ul class="tsd-index-list">
<li class="tsd-kind-get-signature tsd-parent-kind-class"><a href="updux.html#actions" class="tsd-kind-icon">actions</a></li>
<li class="tsd-kind-get-signature tsd-parent-kind-class"><a href="updux.html#asdux" class="tsd-kind-icon">as<wbr>Dux</a></li>
<li class="tsd-kind-get-signature tsd-parent-kind-class"><a href="updux.html#createstore" class="tsd-kind-icon">create<wbr>Store</a></li>
<li class="tsd-kind-get-signature tsd-parent-kind-class"><a href="updux.html#middleware" class="tsd-kind-icon">middleware</a></li>
<li class="tsd-kind-get-signature tsd-parent-kind-class"><a href="updux.html#mutations" class="tsd-kind-icon">mutations</a></li>
<li class="tsd-kind-get-signature tsd-parent-kind-class"><a href="updux.html#reducer" class="tsd-kind-icon">reducer</a></li>
<li class="tsd-kind-get-signature tsd-parent-kind-class"><a href="updux.html#upreducer" class="tsd-kind-icon">upreducer</a></li>
</ul>
</section>
<section class="tsd-index-section ">
<h3>Methods</h3>
<ul class="tsd-index-list">
<li class="tsd-kind-method tsd-parent-kind-class tsd-has-type-parameter"><a href="updux.html#addmutation" class="tsd-kind-icon">add<wbr>Mutation</a></li>
</ul>
</section>
</div>
</section>
</section>
<section class="tsd-panel-group tsd-member-group ">
<h2>Constructors</h2>
<section class="tsd-panel tsd-member tsd-kind-constructor tsd-parent-kind-class">
<a name="constructor" class="tsd-anchor"></a>
<h3>constructor</h3>
<ul class="tsd-signatures tsd-kind-constructor tsd-parent-kind-class">
<li class="tsd-signature tsd-kind-icon">new <wbr>Updux<span class="tsd-signature-symbol">(</span>config<span class="tsd-signature-symbol">?: </span><a href="../globals.html#upduxconfig" class="tsd-signature-type">UpduxConfig</a><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><a href="updux.html" class="tsd-signature-type">Updux</a></li>
</ul>
<ul class="tsd-descriptions">
<li class="tsd-description">
<aside class="tsd-sources">
<ul>
<li>Defined in updux.ts:106</li>
</ul>
</aside>
<h4 class="tsd-parameters-title">Parameters</h4>
<ul class="tsd-parameters">
<li>
<h5><span class="tsd-flag ts-flagDefault value">Default value</span> config: <a href="../globals.html#upduxconfig" class="tsd-signature-type">UpduxConfig</a><span class="tsd-signature-symbol"> =&nbsp;{}</span></h5>
</li>
</ul>
<h4 class="tsd-returns-title">Returns <a href="updux.html" class="tsd-signature-type">Updux</a></h4>
</li>
</ul>
</section>
</section>
<section class="tsd-panel-group tsd-member-group ">
<h2>Properties</h2>
<section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-class">
<a name="groommutations" class="tsd-anchor"></a>
<h3>groom<wbr>Mutations</h3>
<div class="tsd-signature tsd-kind-icon">groom<wbr>Mutations<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">function</span></div>
<aside class="tsd-sources">
<ul>
<li>Defined in updux.ts:98</li>
</ul>
</aside>
<div class="tsd-comment tsd-typography">
<div class="lead">
<p>Function that can be provided to alter all local mutations of the updux
(the mutations of subduxes are left untouched).</p>
</div>
<p>Can be used, for example, for Immer integration:</p>
<pre><code><span class="hljs-keyword">import</span> Updux <span class="hljs-keyword">from</span> <span class="hljs-string">'updux'</span>;
<span class="hljs-keyword">import</span> { produce } <span class="hljs-keyword">from</span> <span class="hljs-string">'Immer'</span>;
<span class="hljs-keyword">const</span> updux = <span class="hljs-keyword">new</span> Updux({
<span class="hljs-attr">initial</span>: { <span class="hljs-attr">counter</span>: <span class="hljs-number">0</span> },
<span class="hljs-attr">groomMutations</span>: <span class="hljs-function"><span class="hljs-params">mutation</span> =&gt;</span> <span class="hljs-function">(<span class="hljs-params">...args</span>) =&gt;</span> produce( mutation(...args) ),
<span class="hljs-attr">mutations</span>: {
<span class="hljs-attr">add</span>: <span class="hljs-function">(<span class="hljs-params">inc=<span class="hljs-number">1</span></span>) =&gt;</span> <span class="hljs-function"><span class="hljs-params">draft</span> =&gt;</span> draft.counter += inc
}
});
</code></pre><p>Or perhaps for debugging:</p>
<pre><code><span class="hljs-keyword">import</span> Updux <span class="hljs-keyword">from</span> <span class="hljs-string">'updux'</span>;
<span class="hljs-keyword">const</span> updux = <span class="hljs-keyword">new</span> Updux({
<span class="hljs-attr">initial</span>: { <span class="hljs-attr">counter</span>: <span class="hljs-number">0</span> },
<span class="hljs-attr">groomMutations</span>: <span class="hljs-function"><span class="hljs-params">mutation</span> =&gt;</span> <span class="hljs-function">(<span class="hljs-params">...args</span>) =&gt;</span> <span class="hljs-function"><span class="hljs-params">state</span> =&gt;</span> {
<span class="hljs-built_in">console</span>.log( <span class="hljs-string">"got action "</span>, args[<span class="hljs-number">1</span>] );
<span class="hljs-keyword">return</span> mutation(...args)(state);
}
});
</code></pre>
</div>
<div class="tsd-type-declaration">
<h4>Type declaration</h4>
<ul class="tsd-parameters">
<li class="tsd-parameter-siganture">
<ul class="tsd-signatures tsd-kind-type-literal tsd-parent-kind-property">
<li class="tsd-signature tsd-kind-icon"><span class="tsd-signature-symbol">(</span>mutation<span class="tsd-signature-symbol">: </span><a href="../globals.html#mutation" class="tsd-signature-type">Mutation</a><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">S</span><span class="tsd-signature-symbol">&gt;</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><a href="../globals.html#mutation" class="tsd-signature-type">Mutation</a><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">S</span><span class="tsd-signature-symbol">&gt;</span></li>
</ul>
<ul class="tsd-descriptions">
<li class="tsd-description">
<h4 class="tsd-parameters-title">Parameters</h4>
<ul class="tsd-parameters">
<li>
<h5>mutation: <a href="../globals.html#mutation" class="tsd-signature-type">Mutation</a><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">S</span><span class="tsd-signature-symbol">&gt;</span></h5>
</li>
</ul>
<h4 class="tsd-returns-title">Returns <a href="../globals.html#mutation" class="tsd-signature-type">Mutation</a><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">S</span><span class="tsd-signature-symbol">&gt;</span></h4>
</li>
</ul>
</li>
</ul>
</div>
</section>
<section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-class">
<a name="initial" class="tsd-anchor"></a>
<h3>initial</h3>
<div class="tsd-signature tsd-kind-icon">initial<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">S</span></div>
<aside class="tsd-sources">
<ul>
<li>Defined in updux.ts:61</li>
</ul>
</aside>
<div class="tsd-comment tsd-typography">
<div class="lead">
<p>Default initial state of the reducer. If applicable, merges the
initial states of <code>config</code> and <code>subduxes</code>, with <code>config</code> having
precedence.</p>
</div>
<p>If nothing was provided, defaults to an empty object.</p>
</div>
</section>
<section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-class">
<a name="subduxes" class="tsd-anchor"></a>
<h3>subduxes</h3>
<div class="tsd-signature tsd-kind-icon">subduxes<span class="tsd-signature-symbol">:</span> <a href="../globals.html#dictionary" class="tsd-signature-type">Dictionary</a><span class="tsd-signature-symbol">&lt;</span><a href="updux.html" class="tsd-signature-type">Updux</a><span class="tsd-signature-symbol">&gt;</span></div>
<aside class="tsd-sources">
<ul>
<li>Defined in updux.ts:52</li>
</ul>
</aside>
</section>
</section>
<section class="tsd-panel-group tsd-member-group ">
<h2>Accessors</h2>
<section class="tsd-panel tsd-member tsd-kind-get-signature tsd-parent-kind-class">
<a name="actions" class="tsd-anchor"></a>
<h3>actions</h3>
<ul class="tsd-signatures tsd-kind-get-signature tsd-parent-kind-class">
<li class="tsd-signature tsd-kind-icon"><span class="tsd-signature-symbol">get</span> actions<span class="tsd-signature-symbol">(</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><a href="../globals.html#dictionary" class="tsd-signature-type">Dictionary</a><span class="tsd-signature-symbol">&lt;</span><a href="../globals.html#actioncreator" class="tsd-signature-type">ActionCreator</a><span class="tsd-signature-symbol">&gt;</span></li>
</ul>
<ul class="tsd-descriptions">
<li class="tsd-description">
<aside class="tsd-sources">
<ul>
<li>Defined in updux.ts:156</li>
</ul>
</aside>
<div class="tsd-comment tsd-typography">
<div class="lead">
<p>Action creators for all actions defined or used in the actions, mutations, effects and subduxes
of the updux config.</p>
</div>
<p>Non-custom action creators defined in <code>actions</code> have the signature <code>(payload={},meta={}) =&gt; ({type,
payload,meta})</code> (with the extra sugar that if <code>meta</code> or <code>payload</code> are not
specified, the key is not present in the produced action).</p>
<p>If the same action appears in multiple locations, the precedence order
determining which one will prevail is</p>
<pre><code>actions generated <span class="hljs-keyword">from</span> mutations/effects &lt; non-<span class="hljs-keyword">custom</span> subduxes actions &lt;
<span class="hljs-keyword">custom</span> subduxes actions &lt; <span class="hljs-keyword">custom</span> actions</code></pre>
</div>
<h4 class="tsd-returns-title">Returns <a href="../globals.html#dictionary" class="tsd-signature-type">Dictionary</a><span class="tsd-signature-symbol">&lt;</span><a href="../globals.html#actioncreator" class="tsd-signature-type">ActionCreator</a><span class="tsd-signature-symbol">&gt;</span></h4>
</li>
</ul>
</section>
<section class="tsd-panel tsd-member tsd-kind-get-signature tsd-parent-kind-class">
<a name="asdux" class="tsd-anchor"></a>
<h3>as<wbr>Dux</h3>
<ul class="tsd-signatures tsd-kind-get-signature tsd-parent-kind-class">
<li class="tsd-signature tsd-kind-icon"><span class="tsd-signature-symbol">get</span> asDux<span class="tsd-signature-symbol">(</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><a href="../globals.html#dux" class="tsd-signature-type">Dux</a><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">S</span><span class="tsd-signature-symbol">&gt;</span></li>
</ul>
<ul class="tsd-descriptions">
<li class="tsd-description">
<aside class="tsd-sources">
<ul>
<li>Defined in updux.ts:231</li>
</ul>
</aside>
<div class="tsd-comment tsd-typography">
<div class="lead">
<p>Returns a
<a href="https://github.com/erikras/ducks-modular-redux">ducks</a>-like
plain object holding the reducer from the Updux object and all
its trimmings.</p>
</div>
</div>
<h4 class="tsd-returns-title">Returns <a href="../globals.html#dux" class="tsd-signature-type">Dux</a><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">S</span><span class="tsd-signature-symbol">&gt;</span></h4>
</li>
</ul>
</section>
<section class="tsd-panel tsd-member tsd-kind-get-signature tsd-parent-kind-class">
<a name="createstore" class="tsd-anchor"></a>
<h3>create<wbr>Store</h3>
<ul class="tsd-signatures tsd-kind-get-signature tsd-parent-kind-class">
<li class="tsd-signature tsd-kind-icon"><span class="tsd-signature-symbol">get</span> createStore<span class="tsd-signature-symbol">(</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">function</span></li>
</ul>
<ul class="tsd-descriptions">
<li class="tsd-description">
<aside class="tsd-sources">
<ul>
<li>Defined in updux.ts:214</li>
</ul>
</aside>
<div class="tsd-comment tsd-typography">
<div class="lead">
<p>Same as doing</p>
</div>
<pre><code>import { createStore, applyMiddleware } <span class="hljs-keyword">from</span> <span class="hljs-string">'redux'</span>;
const { initial, reducer, middleware, actions } = updox(<span class="hljs-built_in">..</span>.);
const store = createStore( initial, reducer, applyMiddleware(middleware) );
<span class="hljs-keyword">for</span> ( let<span class="hljs-built_in"> type </span><span class="hljs-keyword">in</span> actions ) {
store.dispatch[type] = (<span class="hljs-built_in">..</span>.args) =&gt; {
store.dispatch(actions[type](<span class="hljs-built_in">..</span>.args))
};
}</code></pre><p>So that later on you can do</p>
<pre><code>store.dispatch.addTodo<span class="hljs-comment">(...)</span>;
<span class="hljs-comment">// still work</span>
store.dispatch<span class="hljs-comment">( actions.addTodo(...)</span> );</code></pre>
</div>
<h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">function</span></h4>
<ul class="tsd-parameters">
<li class="tsd-parameter-siganture">
<ul class="tsd-signatures tsd-kind-type-literal">
<li class="tsd-signature tsd-kind-icon"><span class="tsd-signature-symbol">(</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><a href="../globals.html#storewithdispatchactions" class="tsd-signature-type">StoreWithDispatchActions</a><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">S</span><span class="tsd-signature-symbol">&gt;</span></li>
</ul>
<ul class="tsd-descriptions">
<li class="tsd-description">
<h4 class="tsd-returns-title">Returns <a href="../globals.html#storewithdispatchactions" class="tsd-signature-type">StoreWithDispatchActions</a><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">S</span><span class="tsd-signature-symbol">&gt;</span></h4>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</section>
<section class="tsd-panel tsd-member tsd-kind-get-signature tsd-parent-kind-class">
<a name="middleware" class="tsd-anchor"></a>
<h3>middleware</h3>
<ul class="tsd-signatures tsd-kind-get-signature tsd-parent-kind-class">
<li class="tsd-signature tsd-kind-icon"><span class="tsd-signature-symbol">get</span> middleware<span class="tsd-signature-symbol">(</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">Middleware</span><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">__type</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">S</span><span class="tsd-signature-symbol">, </span><a href="../globals.html#upduxdispatch" class="tsd-signature-type">UpduxDispatch</a><span class="tsd-signature-symbol">&gt;</span></li>
</ul>
<ul class="tsd-descriptions">
<li class="tsd-description">
<aside class="tsd-sources">
<ul>
<li>Defined in updux.ts:134</li>
</ul>
</aside>
<div class="tsd-comment tsd-typography">
<div class="lead">
<p>A middleware aggregating all the effects defined in the
updux and its subduxes. Effects of the updux itself are
done before the subduxes effects.</p>
</div>
</div>
<h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">Middleware</span><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">__type</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">S</span><span class="tsd-signature-symbol">, </span><a href="../globals.html#upduxdispatch" class="tsd-signature-type">UpduxDispatch</a><span class="tsd-signature-symbol">&gt;</span></h4>
</li>
</ul>
</section>
<section class="tsd-panel tsd-member tsd-kind-get-signature tsd-parent-kind-class">
<a name="mutations" class="tsd-anchor"></a>
<h3>mutations</h3>
<ul class="tsd-signatures tsd-kind-get-signature tsd-parent-kind-class">
<li class="tsd-signature tsd-kind-icon"><span class="tsd-signature-symbol">get</span> mutations<span class="tsd-signature-symbol">(</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><a href="../globals.html#dictionary" class="tsd-signature-type">Dictionary</a><span class="tsd-signature-symbol">&lt;</span><a href="../globals.html#mutation" class="tsd-signature-type">Mutation</a><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">S</span><span class="tsd-signature-symbol">&gt;</span><span class="tsd-signature-symbol">&gt;</span></li>
</ul>
<ul class="tsd-descriptions">
<li class="tsd-description">
<aside class="tsd-sources">
<ul>
<li>Defined in updux.ts:185</li>
</ul>
</aside>
<div class="tsd-comment tsd-typography">
<div class="lead">
<p>Merge of the updux and subduxes mutations. If an action triggers
mutations in both the main updux and its subduxes, the subduxes
mutations will be performed first.</p>
</div>
</div>
<h4 class="tsd-returns-title">Returns <a href="../globals.html#dictionary" class="tsd-signature-type">Dictionary</a><span class="tsd-signature-symbol">&lt;</span><a href="../globals.html#mutation" class="tsd-signature-type">Mutation</a><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">S</span><span class="tsd-signature-symbol">&gt;</span><span class="tsd-signature-symbol">&gt;</span></h4>
</li>
</ul>
</section>
<section class="tsd-panel tsd-member tsd-kind-get-signature tsd-parent-kind-class">
<a name="reducer" class="tsd-anchor"></a>
<h3>reducer</h3>
<ul class="tsd-signatures tsd-kind-get-signature tsd-parent-kind-class">
<li class="tsd-signature tsd-kind-icon"><span class="tsd-signature-symbol">get</span> reducer<span class="tsd-signature-symbol">(</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">function</span></li>
</ul>
<ul class="tsd-descriptions">
<li class="tsd-description">
<aside class="tsd-sources">
<ul>
<li>Defined in updux.ts:176</li>
</ul>
</aside>
<div class="tsd-comment tsd-typography">
<div class="lead">
<p>A Redux reducer generated using the computed initial state and
mutations.</p>
</div>
</div>
<h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">function</span></h4>
<ul class="tsd-parameters">
<li class="tsd-parameter-siganture">
<ul class="tsd-signatures tsd-kind-type-literal">
<li class="tsd-signature tsd-kind-icon"><span class="tsd-signature-symbol">(</span>state<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">S</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">undefined</span>, action<span class="tsd-signature-symbol">: </span><a href="../globals.html#action" class="tsd-signature-type">Action</a><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">S</span></li>
</ul>
<ul class="tsd-descriptions">
<li class="tsd-description">
<h4 class="tsd-parameters-title">Parameters</h4>
<ul class="tsd-parameters">
<li>
<h5>state: <span class="tsd-signature-type">S</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">undefined</span></h5>
</li>
<li>
<h5>action: <a href="../globals.html#action" class="tsd-signature-type">Action</a></h5>
</li>
</ul>
<h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">S</span></h4>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</section>
<section class="tsd-panel tsd-member tsd-kind-get-signature tsd-parent-kind-class">
<a name="upreducer" class="tsd-anchor"></a>
<h3>upreducer</h3>
<ul class="tsd-signatures tsd-kind-get-signature tsd-parent-kind-class">
<li class="tsd-signature tsd-kind-icon"><span class="tsd-signature-symbol">get</span> upreducer<span class="tsd-signature-symbol">(</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><a href="../globals.html#upreducer" class="tsd-signature-type">Upreducer</a><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">S</span><span class="tsd-signature-symbol">&gt;</span></li>
</ul>
<ul class="tsd-descriptions">
<li class="tsd-description">
<aside class="tsd-sources">
<ul>
<li>Defined in updux.ts:168</li>
</ul>
</aside>
<h4 class="tsd-returns-title">Returns <a href="../globals.html#upreducer" class="tsd-signature-type">Upreducer</a><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">S</span><span class="tsd-signature-symbol">&gt;</span></h4>
</li>
</ul>
</section>
</section>
<section class="tsd-panel-group tsd-member-group ">
<h2>Methods</h2>
<section class="tsd-panel tsd-member tsd-kind-method tsd-parent-kind-class tsd-has-type-parameter">
<a name="addmutation" class="tsd-anchor"></a>
<h3>add<wbr>Mutation</h3>
<ul class="tsd-signatures tsd-kind-method tsd-parent-kind-class tsd-has-type-parameter">
<li class="tsd-signature tsd-kind-icon">add<wbr>Mutation&lt;A&gt;<span class="tsd-signature-symbol">(</span>creator<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">A</span>, mutation<span class="tsd-signature-symbol">: </span><a href="../globals.html#mutation" class="tsd-signature-type">Mutation</a><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">S</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">A extends (...args: any[]) &#x3D;&gt; infer R ? R : never</span><span class="tsd-signature-symbol">&gt;</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">void</span></li>
</ul>
<ul class="tsd-descriptions">
<li class="tsd-description">
<aside class="tsd-sources">
<ul>
<li>Defined in updux.ts:253</li>
</ul>
</aside>
<div class="tsd-comment tsd-typography">
<div class="lead">
<p>Adds a mutation and its associated action to the updux.
If a local mutation was already associated to the action,
it will be replaced by the new one.</p>
</div>
<dl class="tsd-comment-tags">
<dt>example</dt>
<dd><pre><code>updux.addMutation( add, inc =&gt; <span class="hljs-keyword">state</span> =&gt; <span class="hljs-keyword">state</span> + inc );</code></pre></dd>
</dl>
</div>
<h4 class="tsd-type-parameters-title">Type parameters</h4>
<ul class="tsd-type-parameters">
<li>
<h4>A<span class="tsd-signature-symbol">: </span><a href="../globals.html#actioncreator" class="tsd-signature-type">ActionCreator</a></h4>
</li>
</ul>
<h4 class="tsd-parameters-title">Parameters</h4>
<ul class="tsd-parameters">
<li>
<h5>creator: <span class="tsd-signature-type">A</span></h5>
</li>
<li>
<h5>mutation: <a href="../globals.html#mutation" class="tsd-signature-type">Mutation</a><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">S</span><span class="tsd-signature-symbol">, </span><span class="tsd-signature-type">A extends (...args: any[]) &#x3D;&gt; infer R ? R : never</span><span class="tsd-signature-symbol">&gt;</span></h5>
</li>
</ul>
<h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">void</span></h4>
</li>
</ul>
</section>
</section>
</div>
<div class="col-4 col-menu menu-sticky-wrap menu-highlight">
<nav class="tsd-navigation primary">
<ul>
<li class="globals ">
<a href="../globals.html"><em>Globals</em></a>
</li>
</ul>
</nav>
<nav class="tsd-navigation secondary menu-sticky">
<ul class="before-current">
</ul>
<ul class="current">
<li class="current tsd-kind-class tsd-has-type-parameter">
<a href="updux.html" class="tsd-kind-icon">Updux</a>
<ul>
<li class=" tsd-kind-constructor tsd-parent-kind-class">
<a href="updux.html#constructor" class="tsd-kind-icon">constructor</a>
</li>
<li class=" tsd-kind-property tsd-parent-kind-class">
<a href="updux.html#groommutations" class="tsd-kind-icon">groom<wbr>Mutations</a>
</li>
<li class=" tsd-kind-property tsd-parent-kind-class">
<a href="updux.html#initial" class="tsd-kind-icon">initial</a>
</li>
<li class=" tsd-kind-property tsd-parent-kind-class">
<a href="updux.html#subduxes" class="tsd-kind-icon">subduxes</a>
</li>
<li class=" tsd-kind-get-signature tsd-parent-kind-class">
<a href="updux.html#actions" class="tsd-kind-icon">actions</a>
</li>
<li class=" tsd-kind-get-signature tsd-parent-kind-class">
<a href="updux.html#asdux" class="tsd-kind-icon">as<wbr>Dux</a>
</li>
<li class=" tsd-kind-get-signature tsd-parent-kind-class">
<a href="updux.html#createstore" class="tsd-kind-icon">create<wbr>Store</a>
</li>
<li class=" tsd-kind-get-signature tsd-parent-kind-class">
<a href="updux.html#middleware" class="tsd-kind-icon">middleware</a>
</li>
<li class=" tsd-kind-get-signature tsd-parent-kind-class">
<a href="updux.html#mutations" class="tsd-kind-icon">mutations</a>
</li>
<li class=" tsd-kind-get-signature tsd-parent-kind-class">
<a href="updux.html#reducer" class="tsd-kind-icon">reducer</a>
</li>
<li class=" tsd-kind-get-signature tsd-parent-kind-class">
<a href="updux.html#upreducer" class="tsd-kind-icon">upreducer</a>
</li>
<li class=" tsd-kind-method tsd-parent-kind-class tsd-has-type-parameter">
<a href="updux.html#addmutation" class="tsd-kind-icon">add<wbr>Mutation</a>
</li>
</ul>
</li>
</ul>
<ul class="after-current">
<li class=" tsd-kind-type-alias tsd-has-type-parameter">
<a href="../globals.html#action" class="tsd-kind-icon">Action</a>
</li>
<li class=" tsd-kind-type-alias tsd-has-type-parameter">
<a href="../globals.html#actioncreator" class="tsd-kind-icon">Action<wbr>Creator</a>
</li>
<li class=" tsd-kind-type-alias tsd-is-not-exported">
<a href="../globals.html#actionpair" class="tsd-kind-icon">Action<wbr>Pair</a>
</li>
<li class=" tsd-kind-type-alias">
<a href="../globals.html#actionpayloadgenerator" class="tsd-kind-icon">Action<wbr>Payload<wbr>Generator</a>
</li>
<li class=" tsd-kind-type-alias tsd-has-type-parameter">
<a href="../globals.html#dictionary" class="tsd-kind-icon">Dictionary</a>
</li>
<li class=" tsd-kind-type-alias tsd-has-type-parameter">
<a href="../globals.html#dux" class="tsd-kind-icon">Dux</a>
</li>
<li class=" tsd-kind-type-alias tsd-has-type-parameter tsd-is-not-exported">
<a href="../globals.html#maybepayload" class="tsd-kind-icon">Maybe<wbr>Payload</a>
</li>
<li class=" tsd-kind-type-alias tsd-has-type-parameter">
<a href="../globals.html#mutation" class="tsd-kind-icon">Mutation</a>
</li>
<li class=" tsd-kind-type-alias tsd-is-not-exported">
<a href="../globals.html#mystate" class="tsd-kind-icon">My<wbr>State</a>
</li>
<li class=" tsd-kind-type-alias tsd-is-not-exported">
<a href="../globals.html#next" class="tsd-kind-icon">Next</a>
</li>
<li class=" tsd-kind-type-alias tsd-has-type-parameter tsd-is-not-exported">
<a href="../globals.html#storewithdispatchactions" class="tsd-kind-icon">Store<wbr>With<wbr>Dispatch<wbr>Actions</a>
</li>
<li class=" tsd-kind-type-alias tsd-is-not-exported">
<a href="../globals.html#submutations" class="tsd-kind-icon">Sub<wbr>Mutations</a>
</li>
<li class=" tsd-kind-type-alias tsd-has-type-parameter">
<a href="../globals.html#upduxconfig" class="tsd-kind-icon">Updux<wbr>Config</a>
</li>
<li class=" tsd-kind-type-alias">
<a href="../globals.html#upduxdispatch" class="tsd-kind-icon">Updux<wbr>Dispatch</a>
</li>
<li class=" tsd-kind-type-alias tsd-has-type-parameter">
<a href="../globals.html#upreducer" class="tsd-kind-icon">Upreducer</a>
</li>
<li class=" tsd-kind-function tsd-is-not-exported">
<a href="../globals.html#middlewarefor" class="tsd-kind-icon">Middleware<wbr>For</a>
</li>
<li class=" tsd-kind-function tsd-has-type-parameter">
<a href="../globals.html#actioncreator" class="tsd-kind-icon">action<wbr>Creator</a>
</li>
<li class=" tsd-kind-function tsd-is-not-exported">
<a href="../globals.html#actionfor" class="tsd-kind-icon">action<wbr>For</a>
</li>
<li class=" tsd-kind-function">
<a href="../globals.html#buildactions" class="tsd-kind-icon">build<wbr>Actions</a>
</li>
<li class=" tsd-kind-function tsd-has-type-parameter">
<a href="../globals.html#buildcreatestore" class="tsd-kind-icon">build<wbr>Create<wbr>Store</a>
</li>
<li class=" tsd-kind-function tsd-has-type-parameter">
<a href="../globals.html#buildinitial" class="tsd-kind-icon">build<wbr>Initial</a>
</li>
<li class=" tsd-kind-function tsd-has-type-parameter">
<a href="../globals.html#buildmiddleware" class="tsd-kind-icon">build<wbr>Middleware</a>
</li>
<li class=" tsd-kind-function">
<a href="../globals.html#buildmutations" class="tsd-kind-icon">build<wbr>Mutations</a>
</li>
<li class=" tsd-kind-function tsd-has-type-parameter">
<a href="../globals.html#buildupreducer" class="tsd-kind-icon">build<wbr>Upreducer</a>
</li>
<li class=" tsd-kind-function tsd-is-not-exported">
<a href="../globals.html#composemutations" class="tsd-kind-icon">compose<wbr>Mutations</a>
</li>
<li class=" tsd-kind-function tsd-is-not-exported">
<a href="../globals.html#noopeffect" class="tsd-kind-icon">noop<wbr>Effect</a>
</li>
<li class=" tsd-kind-function tsd-is-not-exported">
<a href="../globals.html#timeout" class="tsd-kind-icon">timeout</a>
</li>
<li class=" tsd-kind-function tsd-is-not-exported">
<a href="../globals.html#tracer" class="tsd-kind-icon">tracer</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<footer class="with-border-bottom">
<div class="container">
<h2>Legend</h2>
<div class="tsd-legend-group">
<ul class="tsd-legend">
<li class="tsd-kind-module"><span class="tsd-kind-icon">Module</span></li>
<li class="tsd-kind-object-literal"><span class="tsd-kind-icon">Object literal</span></li>
<li class="tsd-kind-variable"><span class="tsd-kind-icon">Variable</span></li>
<li class="tsd-kind-function"><span class="tsd-kind-icon">Function</span></li>
<li class="tsd-kind-function tsd-has-type-parameter"><span class="tsd-kind-icon">Function with type parameter</span></li>
<li class="tsd-kind-index-signature"><span class="tsd-kind-icon">Index signature</span></li>
<li class="tsd-kind-type-alias"><span class="tsd-kind-icon">Type alias</span></li>
<li class="tsd-kind-type-alias tsd-has-type-parameter"><span class="tsd-kind-icon">Type alias with type parameter</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-enum"><span class="tsd-kind-icon">Enumeration</span></li>
<li class="tsd-kind-enum-member"><span class="tsd-kind-icon">Enumeration member</span></li>
<li class="tsd-kind-property tsd-parent-kind-enum"><span class="tsd-kind-icon">Property</span></li>
<li class="tsd-kind-method tsd-parent-kind-enum"><span class="tsd-kind-icon">Method</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-interface"><span class="tsd-kind-icon">Interface</span></li>
<li class="tsd-kind-interface tsd-has-type-parameter"><span class="tsd-kind-icon">Interface with type parameter</span></li>
<li class="tsd-kind-constructor tsd-parent-kind-interface"><span class="tsd-kind-icon">Constructor</span></li>
<li class="tsd-kind-property tsd-parent-kind-interface"><span class="tsd-kind-icon">Property</span></li>
<li class="tsd-kind-method tsd-parent-kind-interface"><span class="tsd-kind-icon">Method</span></li>
<li class="tsd-kind-index-signature tsd-parent-kind-interface"><span class="tsd-kind-icon">Index signature</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-class"><span class="tsd-kind-icon">Class</span></li>
<li class="tsd-kind-class tsd-has-type-parameter"><span class="tsd-kind-icon">Class with type parameter</span></li>
<li class="tsd-kind-constructor tsd-parent-kind-class"><span class="tsd-kind-icon">Constructor</span></li>
<li class="tsd-kind-property tsd-parent-kind-class"><span class="tsd-kind-icon">Property</span></li>
<li class="tsd-kind-method tsd-parent-kind-class"><span class="tsd-kind-icon">Method</span></li>
<li class="tsd-kind-accessor tsd-parent-kind-class"><span class="tsd-kind-icon">Accessor</span></li>
<li class="tsd-kind-index-signature tsd-parent-kind-class"><span class="tsd-kind-icon">Index signature</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-constructor tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited constructor</span></li>
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited property</span></li>
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited method</span></li>
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited accessor</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected property</span></li>
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected method</span></li>
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected accessor</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private property</span></li>
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private method</span></li>
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private accessor</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-static"><span class="tsd-kind-icon">Static property</span></li>
<li class="tsd-kind-call-signature tsd-parent-kind-class tsd-is-static"><span class="tsd-kind-icon">Static method</span></li>
</ul>
</div>
</div>
</footer>
<div class="container tsd-generator">
<p>Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p>
</div>
<div class="overlay"></div>
<script src="../assets/js/main.js"></script>
<script>if (location.protocol == 'file:') document.write('<script src="../assets/js/search.js"><' + '/script>');</script>
</body>
</html>

1287
docs/globals.html Normal file

File diff suppressed because it is too large Load Diff

379
docs/index.html Normal file
View File

@ -0,0 +1,379 @@
<!doctype html>
<html class="default no-js">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>updux</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="assets/css/main.css">
</head>
<body>
<header>
<div class="tsd-page-toolbar">
<div class="container">
<div class="table-wrap">
<div class="table-cell" id="tsd-search" data-index="assets/js/search.js" data-base=".">
<div class="field">
<label for="tsd-search-field" class="tsd-widget search no-caption">Search</label>
<input id="tsd-search-field" type="text" />
</div>
<ul class="results">
<li class="state loading">Preparing search index...</li>
<li class="state failure">The search index is not available</li>
</ul>
<a href="index.html" class="title">updux</a>
</div>
<div class="table-cell" id="tsd-widgets">
<div id="tsd-filter">
<a href="#" class="tsd-widget options no-caption" data-toggle="options">Options</a>
<div class="tsd-filter-group">
<div class="tsd-select" id="tsd-filter-visibility">
<span class="tsd-select-label">All</span>
<ul class="tsd-select-list">
<li data-value="public">Public</li>
<li data-value="protected">Public/Protected</li>
<li data-value="private" class="selected">All</li>
</ul>
</div>
<input type="checkbox" id="tsd-filter-inherited" checked />
<label class="tsd-widget" for="tsd-filter-inherited">Inherited</label>
<input type="checkbox" id="tsd-filter-externals" checked />
<label class="tsd-widget" for="tsd-filter-externals">Externals</label>
<input type="checkbox" id="tsd-filter-only-exported" />
<label class="tsd-widget" for="tsd-filter-only-exported">Only exported</label>
</div>
</div>
<a href="#" class="tsd-widget menu no-caption" data-toggle="menu">Menu</a>
</div>
</div>
</div>
</div>
<div class="tsd-page-title">
<div class="container">
<ul class="tsd-breadcrumb">
<li>
<a href="globals.html">Globals</a>
</li>
</ul>
<h1> updux</h1>
</div>
</div>
</header>
<div class="container container-main">
<div class="row">
<div class="col-8 col-content">
<div class="tsd-panel tsd-typography">
<a href="#what39s-updux" id="what39s-updux" style="color: inherit; text-decoration: none;">
<h1>What&#39;s Updux?</h1>
</a>
<p>So, I&#39;m a fan of <a href="https://redux.js.org">Redux</a>. Two days ago I discovered
<a href="https://rematch.github.io/rematch">rematch</a> alonside a few other frameworks built atop Redux. </p>
<p>It has a couple of pretty good ideas that removes some of the
boilerplate. Keeping mutations and asynchronous effects close to the
reducer definition? Nice. Automatically infering the
actions from the said mutations and effects? Genius!</p>
<p>But it also enforces a flat hierarchy of reducers -- where
is the fun in that? And I&#39;m also having a strong love for
<a href="https://github.com/substantial/updeep">Updeep</a>, so I want reducer state updates to leverage the heck out of it.</p>
<p>All that to say, say hello to <code>Updux</code>. Heavily inspired by <code>rematch</code>, but twisted
to work with <code>updeep</code> and to fit my peculiar needs. It offers features such as</p>
<ul>
<li>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.</li>
<li>Automatically gather all actions used by the updux&#39;s effects and mutations,
and makes then accessible as attributes to the <code>dispatch</code> object of the
store.</li>
<li>Mutations have a signature that is friendly to Updux and Immer.</li>
<li>Also, the mutation signature auto-unwrap the payload of the actions for you.</li>
<li>TypeScript types.</li>
</ul>
<p>Fair warning: this package is still very new, probably very buggy,
definitively very badly documented, and very subject to changes. Caveat
Maxima Emptor.</p>
<a href="#synopsis" id="synopsis" style="color: inherit; text-decoration: none;">
<h1>Synopsis</h1>
</a>
<pre><code><span class="hljs-keyword">import</span> updux <span class="hljs-keyword">from</span> <span class="hljs-string">'updux'</span>;
<span class="hljs-keyword">import</span> otherUpdux <span class="hljs-keyword">from</span> <span class="hljs-string">'./otherUpdux'</span>;
<span class="hljs-keyword">const</span> {
initial,
reducer,
actions,
middleware,
createStore,
} = <span class="hljs-keyword">new</span> Updux({
<span class="hljs-attr">initial</span>: {
<span class="hljs-attr">counter</span>: <span class="hljs-number">0</span>,
},
<span class="hljs-attr">subduxes</span>: {
otherUpdux,
},
<span class="hljs-attr">mutations</span>: {
<span class="hljs-attr">inc</span>: <span class="hljs-function">(<span class="hljs-params"> increment = <span class="hljs-number">1</span> </span>) =&gt;</span> u({<span class="hljs-attr">counter</span>: <span class="hljs-function"><span class="hljs-params">s</span> =&gt;</span> s + increment })
},
<span class="hljs-attr">effects</span>: {
<span class="hljs-string">'*'</span> =&gt; <span class="hljs-function"><span class="hljs-params">api</span> =&gt;</span> <span class="hljs-function"><span class="hljs-params">next</span> =&gt;</span> <span class="hljs-function"><span class="hljs-params">action</span> =&gt;</span> {
<span class="hljs-built_in">console</span>.log( <span class="hljs-string">"hey, look, an action zoomed by!"</span>, action );
next(action);
};
},
<span class="hljs-attr">actions</span>: {
<span class="hljs-attr">customAction</span>: <span class="hljs-function">(<span class="hljs-params"> someArg </span>) =&gt;</span> ({
<span class="hljs-attr">type</span>: <span class="hljs-string">"custom"</span>,
<span class="hljs-attr">payload</span>: { <span class="hljs-attr">someProp</span>: someArg }
}),
},
});
<span class="hljs-keyword">const</span> store = createStore();
store.dispatch.inc(<span class="hljs-number">3</span>);</code></pre>
<a href="#description" id="description" style="color: inherit; text-decoration: none;">
<h1>Description</h1>
</a>
<p>The formal documentation of the class Updux and its associated functions and
types can be found over <a href="./docs/classes/updux.html">here</a>.</p>
<a href="#exporting-upduxes" id="exporting-upduxes" style="color: inherit; text-decoration: none;">
<h2>Exporting upduxes</h2>
</a>
<p>If you are creating upduxes that will be used as subduxes
by other upduxes, or as
<a href="https://github.com/erikras/ducks-modular-redux">ducks</a>-like containers, I
recommend that you export the Updux instance as the default export:</p>
<pre><code>import Updux <span class="hljs-keyword">from</span> <span class="hljs-string">'updux'</span>;
const updux = new Updux({ <span class="hljs-built_in">..</span>. });
<span class="hljs-builtin-name">export</span><span class="hljs-built_in"> default </span>updux;</code></pre><p>Then you can use them as subduxes like this:</p>
<pre><code><span class="hljs-keyword">import</span> Updux <span class="hljs-keyword">from</span> <span class="hljs-string">'updux'</span>;
<span class="hljs-keyword">import</span> foo <span class="hljs-keyword">from</span> <span class="hljs-string">'./foo'</span>; <span class="hljs-comment">// foo is an Updux</span>
<span class="hljs-keyword">import</span> bar <span class="hljs-keyword">from</span> <span class="hljs-string">'./bar'</span>; <span class="hljs-comment">// bar is an Updux as well</span>
<span class="hljs-keyword">const</span> updux = <span class="hljs-keyword">new</span> Updux({
<span class="hljs-attr">subduxes</span>: {
foo, bar
}
});</code></pre><p>Or if you want to use it:</p>
<pre><code><span class="hljs-keyword">import</span> updux <span class="hljs-keyword">from</span> <span class="hljs-string">'./myUpdux'</span>;
<span class="hljs-keyword">const</span> {
reducer,
<span class="hljs-attr">actions</span>: { doTheThing },
createStore,
middleware,
} = updux;</code></pre>
<a href="#usage-with-immer" id="usage-with-immer" style="color: inherit; text-decoration: none;">
<h2>Usage with Immer</h2>
</a>
<p>While Updux was created with Updeep in mind, it also plays very
well with <a href="https://immerjs.github.io/immer/docs/introduction">Immer</a>.</p>
<p>For example, taking this basic updux:</p>
<pre><code><span class="hljs-keyword">import</span> Updux <span class="hljs-keyword">from</span> <span class="hljs-string">'updux'</span>;
<span class="hljs-keyword">const</span> updux = <span class="hljs-keyword">new</span> Updux({
<span class="hljs-attr">initial</span>: { <span class="hljs-attr">counter</span>: <span class="hljs-number">0</span> },
<span class="hljs-attr">mutations</span>: {
<span class="hljs-attr">add</span>: <span class="hljs-function">(<span class="hljs-params">inc=<span class="hljs-number">1</span></span>) =&gt;</span> <span class="hljs-function"><span class="hljs-params">state</span> =&gt;</span> { <span class="hljs-attr">counter</span>: counter + inc }
}
});
</code></pre><p>Converting it to Immer would look like:</p>
<pre><code><span class="hljs-keyword">import</span> Updux <span class="hljs-keyword">from</span> <span class="hljs-string">'updux'</span>;
<span class="hljs-keyword">import</span> { produce } <span class="hljs-keyword">from</span> <span class="hljs-string">'Immer'</span>;
<span class="hljs-keyword">const</span> updux = <span class="hljs-keyword">new</span> Updux({
<span class="hljs-attr">initial</span>: { <span class="hljs-attr">counter</span>: <span class="hljs-number">0</span> },
<span class="hljs-attr">mutations</span>: {
<span class="hljs-attr">add</span>: <span class="hljs-function">(<span class="hljs-params">inc=<span class="hljs-number">1</span></span>) =&gt;</span> produce( <span class="hljs-function"><span class="hljs-params">draft</span> =&gt;</span> draft.counter += inc ) }
}
});
</code></pre><p>But since typing <code>produce</code> over and over is no fun, <code>groomMutations</code>
can be used to wrap all mutations with it:</p>
<pre><code><span class="hljs-keyword">import</span> Updux <span class="hljs-keyword">from</span> <span class="hljs-string">'updux'</span>;
<span class="hljs-keyword">import</span> { produce } <span class="hljs-keyword">from</span> <span class="hljs-string">'Immer'</span>;
<span class="hljs-keyword">const</span> updux = <span class="hljs-keyword">new</span> Updux({
<span class="hljs-attr">initial</span>: { <span class="hljs-attr">counter</span>: <span class="hljs-number">0</span> },
<span class="hljs-attr">groomMutations</span>: <span class="hljs-function"><span class="hljs-params">mutation</span> =&gt;</span> <span class="hljs-function">(<span class="hljs-params">...args</span>) =&gt;</span> produce( mutation(...args) ),
<span class="hljs-attr">mutations</span>: {
<span class="hljs-attr">add</span>: <span class="hljs-function">(<span class="hljs-params">inc=<span class="hljs-number">1</span></span>) =&gt;</span> <span class="hljs-function"><span class="hljs-params">draft</span> =&gt;</span> draft.counter += inc
}
});
</code></pre>
</div>
</div>
<div class="col-4 col-menu menu-sticky-wrap menu-highlight">
<nav class="tsd-navigation primary">
<ul>
<li class="globals ">
<a href="globals.html"><em>Globals</em></a>
</li>
</ul>
</nav>
<nav class="tsd-navigation secondary menu-sticky">
<ul class="before-current">
<li class=" tsd-kind-class tsd-has-type-parameter">
<a href="classes/updux.html" class="tsd-kind-icon">Updux</a>
</li>
<li class=" tsd-kind-type-alias tsd-has-type-parameter">
<a href="globals.html#action" class="tsd-kind-icon">Action</a>
</li>
<li class=" tsd-kind-type-alias tsd-has-type-parameter">
<a href="globals.html#actioncreator" class="tsd-kind-icon">Action<wbr>Creator</a>
</li>
<li class=" tsd-kind-type-alias tsd-is-not-exported">
<a href="globals.html#actionpair" class="tsd-kind-icon">Action<wbr>Pair</a>
</li>
<li class=" tsd-kind-type-alias">
<a href="globals.html#actionpayloadgenerator" class="tsd-kind-icon">Action<wbr>Payload<wbr>Generator</a>
</li>
<li class=" tsd-kind-type-alias tsd-has-type-parameter">
<a href="globals.html#dictionary" class="tsd-kind-icon">Dictionary</a>
</li>
<li class=" tsd-kind-type-alias tsd-has-type-parameter">
<a href="globals.html#dux" class="tsd-kind-icon">Dux</a>
</li>
<li class=" tsd-kind-type-alias tsd-has-type-parameter tsd-is-not-exported">
<a href="globals.html#maybepayload" class="tsd-kind-icon">Maybe<wbr>Payload</a>
</li>
<li class=" tsd-kind-type-alias tsd-has-type-parameter">
<a href="globals.html#mutation" class="tsd-kind-icon">Mutation</a>
</li>
<li class=" tsd-kind-type-alias tsd-is-not-exported">
<a href="globals.html#mystate" class="tsd-kind-icon">My<wbr>State</a>
</li>
<li class=" tsd-kind-type-alias tsd-is-not-exported">
<a href="globals.html#next" class="tsd-kind-icon">Next</a>
</li>
<li class=" tsd-kind-type-alias tsd-has-type-parameter tsd-is-not-exported">
<a href="globals.html#storewithdispatchactions" class="tsd-kind-icon">Store<wbr>With<wbr>Dispatch<wbr>Actions</a>
</li>
<li class=" tsd-kind-type-alias tsd-is-not-exported">
<a href="globals.html#submutations" class="tsd-kind-icon">Sub<wbr>Mutations</a>
</li>
<li class=" tsd-kind-type-alias tsd-has-type-parameter">
<a href="globals.html#upduxconfig" class="tsd-kind-icon">Updux<wbr>Config</a>
</li>
<li class=" tsd-kind-type-alias">
<a href="globals.html#upduxdispatch" class="tsd-kind-icon">Updux<wbr>Dispatch</a>
</li>
<li class=" tsd-kind-type-alias tsd-has-type-parameter">
<a href="globals.html#upreducer" class="tsd-kind-icon">Upreducer</a>
</li>
<li class=" tsd-kind-function tsd-is-not-exported">
<a href="globals.html#middlewarefor" class="tsd-kind-icon">Middleware<wbr>For</a>
</li>
<li class=" tsd-kind-function tsd-has-type-parameter">
<a href="globals.html#actioncreator" class="tsd-kind-icon">action<wbr>Creator</a>
</li>
<li class=" tsd-kind-function tsd-is-not-exported">
<a href="globals.html#actionfor" class="tsd-kind-icon">action<wbr>For</a>
</li>
<li class=" tsd-kind-function">
<a href="globals.html#buildactions" class="tsd-kind-icon">build<wbr>Actions</a>
</li>
<li class=" tsd-kind-function tsd-has-type-parameter">
<a href="globals.html#buildcreatestore" class="tsd-kind-icon">build<wbr>Create<wbr>Store</a>
</li>
<li class=" tsd-kind-function tsd-has-type-parameter">
<a href="globals.html#buildinitial" class="tsd-kind-icon">build<wbr>Initial</a>
</li>
<li class=" tsd-kind-function tsd-has-type-parameter">
<a href="globals.html#buildmiddleware" class="tsd-kind-icon">build<wbr>Middleware</a>
</li>
<li class=" tsd-kind-function">
<a href="globals.html#buildmutations" class="tsd-kind-icon">build<wbr>Mutations</a>
</li>
<li class=" tsd-kind-function tsd-has-type-parameter">
<a href="globals.html#buildupreducer" class="tsd-kind-icon">build<wbr>Upreducer</a>
</li>
<li class=" tsd-kind-function tsd-is-not-exported">
<a href="globals.html#composemutations" class="tsd-kind-icon">compose<wbr>Mutations</a>
</li>
<li class=" tsd-kind-function tsd-is-not-exported">
<a href="globals.html#noopeffect" class="tsd-kind-icon">noop<wbr>Effect</a>
</li>
<li class=" tsd-kind-function tsd-is-not-exported">
<a href="globals.html#timeout" class="tsd-kind-icon">timeout</a>
</li>
<li class=" tsd-kind-function tsd-is-not-exported">
<a href="globals.html#tracer" class="tsd-kind-icon">tracer</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<footer class="with-border-bottom">
<div class="container">
<h2>Legend</h2>
<div class="tsd-legend-group">
<ul class="tsd-legend">
<li class="tsd-kind-module"><span class="tsd-kind-icon">Module</span></li>
<li class="tsd-kind-object-literal"><span class="tsd-kind-icon">Object literal</span></li>
<li class="tsd-kind-variable"><span class="tsd-kind-icon">Variable</span></li>
<li class="tsd-kind-function"><span class="tsd-kind-icon">Function</span></li>
<li class="tsd-kind-function tsd-has-type-parameter"><span class="tsd-kind-icon">Function with type parameter</span></li>
<li class="tsd-kind-index-signature"><span class="tsd-kind-icon">Index signature</span></li>
<li class="tsd-kind-type-alias"><span class="tsd-kind-icon">Type alias</span></li>
<li class="tsd-kind-type-alias tsd-has-type-parameter"><span class="tsd-kind-icon">Type alias with type parameter</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-enum"><span class="tsd-kind-icon">Enumeration</span></li>
<li class="tsd-kind-enum-member"><span class="tsd-kind-icon">Enumeration member</span></li>
<li class="tsd-kind-property tsd-parent-kind-enum"><span class="tsd-kind-icon">Property</span></li>
<li class="tsd-kind-method tsd-parent-kind-enum"><span class="tsd-kind-icon">Method</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-interface"><span class="tsd-kind-icon">Interface</span></li>
<li class="tsd-kind-interface tsd-has-type-parameter"><span class="tsd-kind-icon">Interface with type parameter</span></li>
<li class="tsd-kind-constructor tsd-parent-kind-interface"><span class="tsd-kind-icon">Constructor</span></li>
<li class="tsd-kind-property tsd-parent-kind-interface"><span class="tsd-kind-icon">Property</span></li>
<li class="tsd-kind-method tsd-parent-kind-interface"><span class="tsd-kind-icon">Method</span></li>
<li class="tsd-kind-index-signature tsd-parent-kind-interface"><span class="tsd-kind-icon">Index signature</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-class"><span class="tsd-kind-icon">Class</span></li>
<li class="tsd-kind-class tsd-has-type-parameter"><span class="tsd-kind-icon">Class with type parameter</span></li>
<li class="tsd-kind-constructor tsd-parent-kind-class"><span class="tsd-kind-icon">Constructor</span></li>
<li class="tsd-kind-property tsd-parent-kind-class"><span class="tsd-kind-icon">Property</span></li>
<li class="tsd-kind-method tsd-parent-kind-class"><span class="tsd-kind-icon">Method</span></li>
<li class="tsd-kind-accessor tsd-parent-kind-class"><span class="tsd-kind-icon">Accessor</span></li>
<li class="tsd-kind-index-signature tsd-parent-kind-class"><span class="tsd-kind-icon">Index signature</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-constructor tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited constructor</span></li>
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited property</span></li>
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited method</span></li>
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited accessor</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected property</span></li>
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected method</span></li>
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected accessor</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private property</span></li>
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private method</span></li>
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private accessor</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-static"><span class="tsd-kind-icon">Static property</span></li>
<li class="tsd-kind-call-signature tsd-parent-kind-class tsd-is-static"><span class="tsd-kind-icon">Static method</span></li>
</ul>
</div>
</div>
</footer>
<div class="container tsd-generator">
<p>Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p>
</div>
<div class="overlay"></div>
<script src="assets/js/main.js"></script>
<script>if (location.protocol == 'file:') document.write('<script src="assets/js/search.js"><' + '/script>');</script>
</body>
</html>

View File

@ -1,6 +1,7 @@
{ {
"dependencies": { "dependencies": {
"lodash": "^4.17.15", "lodash": "^4.17.15",
"mobx": "^5.14.2",
"redux": "^4.0.4" "redux": "^4.0.4"
}, },
"devDependencies": { "devDependencies": {
@ -13,6 +14,7 @@
"jest": "^24.9.0", "jest": "^24.9.0",
"ts-jest": "^24.1.0", "ts-jest": "^24.1.0",
"tsd": "^0.10.0", "tsd": "^0.10.0",
"typedoc": "^0.15.0",
"typescript": "^3.6.4", "typescript": "^3.6.4",
"updeep": "^1.2.0" "updeep": "^1.2.0"
}, },
@ -21,10 +23,10 @@
"name": "updux", "name": "updux",
"description": "Updeep-friendly Redux helper framework", "description": "Updeep-friendly Redux helper framework",
"scripts": { "scripts": {
"build": "tsc", "build": "tsc && typedoc",
"test": "jest" "test": "jest"
}, },
"version": "0.2.0", "version": "1.0.0",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git+https://github.com/yanick/updux.git" "url": "git+https://github.com/yanick/updux.git"

View File

@ -1,10 +1,10 @@
import updux from '.'; import Updux from '.';
import u from 'updeep'; import u from 'updeep';
const noopEffect = () => () => () => {}; const noopEffect = () => () => () => {};
test('actions defined in effects and mutations, multi-level', () => { test('actions defined in effects and mutations, multi-level', () => {
const {actions} = updux({ const {actions} = new Updux({
effects: { effects: {
foo: noopEffect, foo: noopEffect,
}, },

23
src/addMutations.test.ts Normal file
View File

@ -0,0 +1,23 @@
import Updux, { actionCreator } from './updux';
type MyState = {
sum: number
}
test( 'added mutation is present', () => {
const updux = new Updux<MyState>({
initial: { sum: 0 },
});
const add = actionCreator('add', (n : number) => ({n}) )
// must add 'add' in the actions 9.9
updux.addMutation(
add, ({n},action) => ({sum}) => ({sum: sum + n})
);
updux.mutations;
const store = updux.createStore();
store.dispatch.add(3);
expect(store.getState()).toEqual({ sum: 3 });
});

View File

@ -1,19 +1,33 @@
import fp from 'lodash/fp'; import fp from 'lodash/fp';
import { Action, ActionPayloadGenerator, Dictionary } from '../types'; import { Action, ActionCreator, ActionPayloadGenerator, Dictionary } from '../types';
interface ActionCreator { export function actionCreator<T extends string,P extends any>( type: T, transform: (...args: any[]) => P ): ActionCreator<T,P>
( ...args: any[] ): Action; export function actionCreator<T extends string>( type: T, transform: never ): ActionCreator<T,undefined>
_genericAction?: boolean export function actionCreator<T extends string>( type: T, transform: null ): ActionCreator<T,null>
export function actionCreator(type:any, transform:any ) {
if( transform ) {
return Object.assign(
(...args: any[]) => ({ type, payload: transform(...args) }),
{ type } )
} }
function actionFor(type:string) { if( transform === null ) {
const creator : ActionCreator = ( (payload = undefined, meta = undefined) => return Object.assign( () => ({ type }), { type } )
}
return Object.assign( (payload: unknown) => ({type, payload}) );
}
function actionFor(type:string): ActionCreator {
const f = ( (payload = undefined, meta = undefined) =>
fp.pickBy(v => v !== undefined)({type, payload, meta}) as Action fp.pickBy(v => v !== undefined)({type, payload, meta}) as Action
); );
creator._genericAction = true; return Object.assign(f, {
_genericAction: true,
return creator; type
});
} }
type ActionPair = [ string, ActionCreator ]; type ActionPair = [ string, ActionCreator ];
@ -30,17 +44,16 @@ function buildActions(
([type,f]) => !f._genericAction ([type,f]) => !f._genericAction
)( subActions ); )( subActions );
const actions = [ const actions : any = [
...(actionNames.map( type => [ type, actionFor(type) ] )), ...(actionNames.map( type => [ type, actionFor(type) ] )),
...generic, ...generic,
...crafted, ...crafted,
...Object.entries(generators).map( ...Object.entries(generators).map(
([type, payload]: [ string, Function ]) => [type, (...args: any) => ({ type, payload: payload(...args) })] ([type, payload]: [ string, Function ]): any => [type, (payload as any).type ? payload : (...args: any) => ({ type, payload: payload(...args) })]
), ),
]; ];
return fp.fromPairs(actions); return fp.fromPairs(actions);
} }
export default buildActions; export default buildActions;

View File

@ -18,8 +18,10 @@ function buildMiddleware<S=any>(
): Middleware<{},S,UpduxDispatch> ): Middleware<{},S,UpduxDispatch>
{ {
return (api: MiddlewareAPI<UpduxDispatch,S>) => { return (api: MiddlewareAPI<UpduxDispatch,S>) => {
for (let type in actions) { for (let type in actions) {
api.dispatch[type] = (...args:any[]) => api.dispatch(((actions as any)[type] as any)(...args)); const ac = actions[type];
api.dispatch[type] = (...args:any[]) => api.dispatch(ac(...args));
} }
return (original_next: Next)=> { return (original_next: Next)=> {

View File

@ -1,10 +1,8 @@
import fp from 'lodash/fp';
import u from 'updeep';
import Updux from './updux'; import Updux from './updux';
import { UpduxConfig } from './types'; export { default as Updux } from './updux';
export {
UpduxConfig
} from './types';
export default function updux<S=any>(config: UpduxConfig<S>) { export default Updux;
return new Updux<S>(config);
}

View File

@ -1,18 +1,18 @@
import updux from '.'; import Updux from '.';
import u from 'updeep'; import u from 'updeep';
test( 'simple effect', () => { test( 'simple effect', () => {
const tracer = jest.fn(); const tracer = jest.fn();
const store = updux({ const store = (new Updux({
effects: { effects: {
foo: (api:any) => (next:any) => (action:any) => { foo: (api:any) => (next:any) => (action:any) => {
tracer(); tracer();
next(action); next(action);
}, },
}, },
}).createStore(); })).createStore();
expect(tracer).not.toHaveBeenCalled(); expect(tracer).not.toHaveBeenCalled();
@ -35,16 +35,17 @@ test( 'effect and sub-effect', () => {
next(action); next(action);
}; };
const store = updux({ const store = (new Updux({
effects: { effects: {
foo: tracerEffect('root'), foo: tracerEffect('root'),
}, },
subduxes: { subduxes: {
zzz: updux({effects: { zzz: {effects: {
foo: tracerEffect('child'), foo: tracerEffect('child'),
}}) }
}
}, },
}).createStore(); })).createStore();
expect(tracer).not.toHaveBeenCalled(); expect(tracer).not.toHaveBeenCalled();
@ -57,22 +58,20 @@ test( 'effect and sub-effect', () => {
expect(tracer).toHaveBeenNthCalledWith(1,'root'); expect(tracer).toHaveBeenNthCalledWith(1,'root');
expect(tracer).toHaveBeenNthCalledWith(2,'child'); expect(tracer).toHaveBeenNthCalledWith(2,'child');
}); });
test( '"*" effect', () => { test( '"*" effect', () => {
const tracer = jest.fn(); const tracer = jest.fn();
const store = updux({ const store = (new Updux({
effects: { effects: {
'*': api => next => action => { '*': api => next => action => {
tracer(); tracer();
next(action); next(action);
}, },
}, },
}).createStore(); })).createStore();
expect(tracer).not.toHaveBeenCalled(); expect(tracer).not.toHaveBeenCalled();
@ -89,7 +88,7 @@ test( 'async effect', async () => {
const tracer = jest.fn(); const tracer = jest.fn();
const store = updux({ const store = (new Updux({
effects: { effects: {
foo: api => next => async action => { foo: api => next => async action => {
next(action); next(action);
@ -97,7 +96,7 @@ test( 'async effect', async () => {
tracer(); tracer();
}, },
}, },
}).createStore(); })).createStore();
expect(tracer).not.toHaveBeenCalled(); expect(tracer).not.toHaveBeenCalled();

View File

@ -1,10 +1,10 @@
import updux from '.'; import Updux from '.';
import u from 'updeep'; import u from 'updeep';
const tracer = (chr:string) => u({ tracer: (s='') => s + chr }); const tracer = (chr:string) => u({ tracer: (s='') => s + chr });
test( 'mutations, simple', () => { test( 'mutations, simple', () => {
const dux = updux({ const dux = new Updux({
mutations: { mutations: {
foo: () => tracer('a'), foo: () => tracer('a'),
'*': () => tracer('b'), '*': () => tracer('b'),
@ -25,19 +25,19 @@ test( 'mutations, simple', () => {
}); });
test( 'with subduxes', () => { test( 'with subduxes', () => {
const dux = updux({ const dux = new Updux({
mutations: { mutations: {
foo: () => tracer('a'), foo: () => tracer('a'),
'*': () => tracer('b'), '*': () => tracer('b'),
bar: () => ({bar}:any) => ({ bar, tracer: bar.tracer }) bar: () => ({bar}:any) => ({ bar, tracer: bar.tracer })
}, },
subduxes: { subduxes: {
bar: updux({ bar: {
mutations: { mutations: {
foo: () => tracer('d'), foo: () => tracer('d'),
'*': () => tracer('e'), '*': () => tracer('e'),
}, },
}), },
}, },
}); });

View File

@ -1,9 +1,9 @@
import updux from '.'; import Updux from '.';
test('actions from mutations', () => { test('actions from mutations', () => {
const { const {
actions: {foo, bar}, actions: {foo, bar},
} = updux({ } = new Updux({
mutations: { mutations: {
foo: () => (x:any) => x, foo: () => (x:any) => x,
}, },
@ -21,7 +21,7 @@ test('actions from mutations', () => {
}); });
test('reducer', () => { test('reducer', () => {
const {actions, reducer} = updux({ const {actions, reducer} = new Updux({
initial: {counter: 1}, initial: {counter: 1},
mutations: { mutations: {
inc: () => ({counter}:{counter:number}) => ({counter: counter + 1}), inc: () => ({counter}:{counter:number}) => ({counter: counter + 1}),
@ -38,7 +38,7 @@ test('reducer', () => {
}); });
test( 'sub reducers', () => { test( 'sub reducers', () => {
const foo = updux({ const foo = new Updux({
initial: 1, initial: 1,
mutations: { mutations: {
doFoo: () => (x:number) => x + 1, doFoo: () => (x:number) => x + 1,
@ -46,7 +46,7 @@ test( 'sub reducers', () => {
}, },
}); });
const bar = updux({ const bar = new Updux({
initial: 'a', initial: 'a',
mutations: { mutations: {
doBar: () => (x:string) => x + 'a', doBar: () => (x:string) => x + 'a',
@ -54,7 +54,7 @@ test( 'sub reducers', () => {
} }
}); });
const { initial, actions, reducer } = updux({ const { initial, actions, reducer } = new Updux({
subduxes: { subduxes: {
foo, bar foo, bar
} }
@ -87,7 +87,7 @@ test('precedence between root and sub-reducers', () => {
initial, initial,
reducer, reducer,
actions, actions,
} = updux({ } = new Updux({
initial: { initial: {
foo: { bar: 4 }, foo: { bar: 4 },
}, },
@ -100,7 +100,7 @@ test('precedence between root and sub-reducers', () => {
} }
}, },
subduxes: { subduxes: {
foo: updux({ foo: {
initial: { initial: {
bar: 2, bar: 2,
quux: 3, quux: 3,
@ -108,7 +108,7 @@ test('precedence between root and sub-reducers', () => {
mutations: { mutations: {
inc: () => (state:any) => ({...state, bar: state.bar + 1 }) inc: () => (state:any) => ({...state, bar: state.bar + 1 })
}, },
}), },
} }
}); });
@ -130,7 +130,7 @@ test( 'middleware', async () => {
const { const {
middleware, middleware,
createStore createStore
} = updux({ } = new Updux({
initial: "", initial: "",
mutations: { mutations: {
inc: (addition:number) => (state:number) => state + addition, inc: (addition:number) => (state:number) => state + addition,
@ -147,14 +147,14 @@ test( 'middleware', async () => {
} }
}, },
subduxes: { subduxes: {
foo: updux({ foo: {
effects: { effects: {
doEeet: (api) => next => action => { doEeet: (api:any) => ( next:any ) => ( action: any ) => {
api.dispatch({ type: 'inc', payload: 'b'}); api.dispatch({ type: 'inc', payload: 'b'});
next(action); next(action);
} }
} }
}), },
} }
}); });
@ -169,3 +169,27 @@ test( 'middleware', async () => {
expect(store.getState()).toEqual( 'abZc' ); expect(store.getState()).toEqual( 'abZc' );
}); });
test( "subduxes and mutations", () => {
const foo = new Updux({ mutations: {
quux: () => () => 'x',
blart: () => () => 'a',
}});
const bar = new Updux({ mutations: {
quux: () => () => 'y'
}});
const baz = new Updux({
mutations: {
quux: () => (state:any) => ({...state, "baz": "z" })
}, subduxes: { foo, bar } });
let state = baz.reducer(undefined, baz.actions.quux() );
expect(state).toEqual({
foo: "x",
bar: "y",
baz: "z",
});
});

View File

@ -1,29 +1,184 @@
import {Dispatch, Middleware} from 'redux'; import {Dispatch, Middleware} from 'redux';
export type Action = { type MaybePayload<P> = P extends object | string | boolean | number
type: string, ? {
payload?: any, payload: P;
meta?: any,
} }
: {payload?: P};
export type Action<T extends string = string, P = any> = {
type: T;
} & MaybePayload<P>;
export type Dictionary<T> = {[key: string]: T}; export type Dictionary<T> = {[key: string]: T};
export type Mutation<S=any> = (payload: any, action: Action) => (state: S) => S ; export type Mutation<S = any, A extends Action = Action> = (
payload: A['payload'],
action: A,
) => (state: S) => S;
export type ActionPayloadGenerator = (...args: any[]) => any; export type ActionPayloadGenerator = (...args: any[]) => any;
export type ActionCreator = (...args: any[] ) => Action; export type ActionCreator<T extends string = string, P = any> = {
type: T;
_genericAction?: boolean;
} & ((...args: any[]) => Action<T, P>);
export type UpduxDispatch = Dispatch & Dictionary<ActionCreator>; export type UpduxDispatch = Dispatch & Dictionary<Function>;
export type UpduxConfig<S=any> = Partial<{
initial: S, /**
subduxes: {}, * Configuration object given to Updux's constructor.
actions: { * @typeparam S Type of the Updux's state. Defaults to `any`.
[ type: string ]: ActionPayloadGenerator */
}, export type UpduxConfig<S=any> = {
mutations: any, /**
effects: Dictionary<Middleware<{},S,UpduxDispatch>>, * The default initial state of the reducer. Can be anything your
}>; * heart desires.
*/
initial?: S;
/**
* Object mapping slices of the state to sub-upduxes.
*
* For example, if in plain Redux you would do
*
* ```
* import { combineReducers } from 'redux';
* import todosReducer from './todos';
* import statisticsReducer from './statistics';
*
* const rootReducer = combineReducers({
* todos: todosReducer,
* stats: statisticsReducer,
* });
* ```
*
* then with Updux you'd do
*
* ```
* import { updux } from 'updux';
* import todos from './todos';
* import statistics from './statistics';
*
* const rootUpdux = updux({
* subduxes: {
* todos, statistics
* }
* });
*/
subduxes?: {};
/**
* Generic action creations are automatically created from the mutations and effects, but you can
* also define custom action creator here. The object's values are function that
* transform the arguments of the creator to the action's payload.
*
* ```
* const { actions } = updox({
* mutations: {
* foo: () => state => state,
* }
* actions: {
* bar: (x,y) => ({x,y})
* }
* });
*
* actions.foo({ x: 1, y: 2 }); // => { type: foo, payload: { x:1, y:2 } }
* actions.bar(1,2); // => { type: bar, payload: { x:1, y:2 } }
* ```
*/
actions?: {
[type: string]: ActionCreator;
};
/**
* Object mapping actions to the associated state mutation.
*
* For example, in `Redux` you'd do
*
* ```
* function todosReducer(state=[],action) {
*
* switch(action.type) {
* case 'ADD': return [ ...state, action.payload ];
*
* case 'DONE': return state.map( todo => todo.id === action.payload
* ? { ...todo, done: true } : todo )
*
* default: return state;
* }
* }
* ```
*
* With Updux:
*
* ```
* const todosUpdux = updux({
* mutations: {
* add: todo => state => [ ...state, todo ],
* done: done_id => u.map( u.if( ({id} => id === done_id), {done: true} ) )
* }
* });
* ```
*
* The signature of the mutations is `(payload,action) => state => newState`.
* It is designed to play well with `Updeep` (and [Immer](https://immerjs.github.io/immer/docs/introduction)). This way, instead of doing
*
* ```
* mutation: {
* renameTodo: newName => state => { ...state, name: newName }
* }
* ```
*
* we can do
*
* ```
* mutation: {
* renameTodo: newName => u({ name: newName })
* }
* ```
*
* Also, the special key `*` can be used to match any
* action not explicitly matched by other mutations.
*
* ```
* const todosUpdux = updux({
* mutations: {
* add: todo => state => [ ...state, todo ],
* done: done_id => u.map( u.if( ({id} => id === done_id), {done: true} ) ),
* '*' (payload,action) => state => {
* console.warn( "unexpected action ", action.type );
* return state;
* },
* }
* });
*/
mutations?: any;
groomMutations?: (m: Mutation<S>) => Mutation<S>;
/**
* Plain object defining asynchronous actions and side-effects triggered by actions.
* The effects themselves are Redux middleware, expect with the `dispatch`
* property of the first argument augmented with all the available actions.
*
* ```
* updux({
* effects: {
* fetch: ({dispatch}) => next => async (action) => {
* next(action);
*
* let result = await fetch(action.payload.url).then( result => result.json() );
* dispatch.fetchSuccess(result);
* }
* }
* });
* ```
*
*/
effects?: Dictionary<Middleware<{}, S, UpduxDispatch>>;
};
export type Upreducer<S = any> = (action: Action) => (state: S) => S; export type Upreducer<S = any> = (action: Action) => (state: S) => S;

View File

@ -1,4 +1,7 @@
import fp from 'lodash/fp'; import fp from 'lodash/fp';
import u from 'updeep';
import {observable, computed, toJS} from 'mobx';
import buildActions from './buildActions'; import buildActions from './buildActions';
import buildInitial from './buildInitial'; import buildInitial from './buildInitial';
import buildMutations from './buildMutations'; import buildMutations from './buildMutations';
@ -6,72 +9,256 @@ import buildMutations from './buildMutations';
import buildCreateStore from './buildCreateStore'; import buildCreateStore from './buildCreateStore';
import buildMiddleware from './buildMiddleware'; import buildMiddleware from './buildMiddleware';
import buildUpreducer from './buildUpreducer'; import buildUpreducer from './buildUpreducer';
import { UpduxConfig, Dictionary, Action, ActionCreator, Mutation, Upreducer, UpduxDispatch } from './types'; import {
UpduxConfig,
Dictionary,
Action,
ActionCreator,
Mutation,
Upreducer,
UpduxDispatch,
} from './types';
import {Middleware, Store} from 'redux'; import {Middleware, Store} from 'redux';
export {actionCreator} from './buildActions';
type StoreWithDispatchActions<S=any,Actions={ [action: string]: (...args:any) => Action }> = Store<S> & { type StoreWithDispatchActions<
dispatch: { [ type in keyof Actions ]: (...args:any) => void } S = any,
Actions = {[action: string]: (...args: any) => Action}
> = Store<S> & {
dispatch: {[type in keyof Actions]: (...args: any) => void};
}; };
export class Updux<S=any> { export type Dux<S> = Pick<
Updux<S>,
| 'subduxes'
| 'actions'
| 'initial'
| 'mutations'
| 'reducer'
| 'middleware'
| 'createStore'
| 'upreducer'
>;
/**
* `Updux` is a way to minimize and simplify the boilerplate associated with the
* creation of a `Redux` store. It takes a shorthand configuration
* object, and generates the appropriate reducer, actions, middleware, etc.
* In true `Redux`-like fashion, upduxes can be made of sub-upduxes (`subduxes` for short) for different slices of the root state.
* @typeparam S Store's state type. Defaults to `any`.
*/
export class Updux<S = any> {
subduxes: Dictionary<Updux>; subduxes: Dictionary<Updux>;
actions: Dictionary<ActionCreator> /**
* Default initial state of the reducer. If applicable, merges the
* initial states of `config` and `subduxes`, with `config` having
* precedence.
*
* If nothing was provided, defaults to an empty object.
*/
initial: S; initial: S;
mutations: Dictionary<Mutation>; /**
* Function that can be provided to alter all local mutations of the updux
* (the mutations of subduxes are left untouched).
*
* Can be used, for example, for Immer integration:
*
* ```
* import Updux from 'updux';
* import { produce } from 'Immer';
*
* const updux = new Updux({
* initial: { counter: 0 },
* groomMutations: mutation => (...args) => produce( mutation(...args) ),
* mutations: {
* add: (inc=1) => draft => draft.counter += inc
* }
* });
*
* ```
*
* Or perhaps for debugging:
*
* ```
* import Updux from 'updux';
*
* const updux = new Updux({
* initial: { counter: 0 },
* groomMutations: mutation => (...args) => state => {
* console.log( "got action ", args[1] );
* return mutation(...args)(state);
* }
* });
*
* ```
*/
groomMutations: (mutation: Mutation<S>) => Mutation<S>;
upreducer: Upreducer<S>; @observable private localEffects: Dictionary<
Middleware<{}, S, UpduxDispatch>
>;
reducer: (state:S|undefined,action:Action) => S; @observable private localActions: Dictionary<ActionCreator>;
middleware: Middleware<{},S,UpduxDispatch>; @observable private localMutations: Dictionary<Mutation<S>>;
createStore: () => StoreWithDispatchActions<S>; constructor(config: UpduxConfig = {}) {
this.groomMutations = config.groomMutations || ((x: Mutation<S>) => x);
constructor(config: UpduxConfig) { this.subduxes = fp.mapValues((value: UpduxConfig | Updux) =>
fp.isPlainObject(value) ? new Updux(value) : value,
)(fp.getOr({}, 'subduxes', config)) as Dictionary<Updux>;
this.subduxes = fp.mapValues( this.localActions = fp.getOr({}, 'actions', config);
(value:UpduxConfig|Updux) => fp.isPlainObject(value) ? new Updux(value) : value )(fp.getOr({},'subduxes',config)
) as Dictionary<Updux>;
this.localEffects = fp.getOr({}, 'effects', config);
this.actions = buildActions(
config.actions,
[ ...Object.keys(config.mutations||{}), ...Object.keys(config.effects||{} ) ],
fp.flatten( Object.values( this.subduxes ).map( ({actions}:Updux) => Object.entries(actions) ) ),
)
this.initial = buildInitial<any>( this.initial = buildInitial<any>(
config.initial, fp.mapValues( ({initial}) => initial )(this.subduxes) config.initial,
fp.mapValues(({initial}) => initial)(this.subduxes),
); );
this.mutations = buildMutations( this.localMutations = fp.mapValues((m: Mutation<S>) =>
config.mutations, this.subduxes this.groomMutations(m),
); )(fp.getOr({}, 'mutations', config));
this.upreducer = buildUpreducer(
this.initial, this.mutations
);
this.reducer = (state,action) => {
return this.upreducer(action)(state as S);
} }
this.middleware = buildMiddleware( /**
config.effects, * A middleware aggregating all the effects defined in the
* updux and its subduxes. Effects of the updux itself are
* done before the subduxes effects.
*/
@computed get middleware(): Middleware<{}, S, UpduxDispatch> {
return buildMiddleware(
this.localEffects,
this.actions, this.actions,
Object.values(this.subduxes).map( sd => sd.middleware ) Object.values(this.subduxes).map(sd => sd.middleware),
); );
const actions = this.actions;
this.createStore = buildCreateStore<S>(this.reducer,this.initial,this.middleware as Middleware,this.actions) as
() => StoreWithDispatchActions< S, typeof actions >;
} }
/**
* Action creators for all actions defined or used in the actions, mutations, effects and subduxes
* of the updux config.
*
* Non-custom action creators defined in `actions` have the signature `(payload={},meta={}) => ({type,
* payload,meta})` (with the extra sugar that if `meta` or `payload` are not
* specified, the key is not present in the produced action).
*
* If the same action appears in multiple locations, the precedence order
* determining which one will prevail is
*
* actions generated from mutations/effects < non-custom subduxes actions <
* custom subduxes actions < custom actions
*/
@computed get actions(): Dictionary<ActionCreator> {
return buildActions(
this.localActions,
[...Object.keys(this.localMutations), ...Object.keys(this.localEffects)],
fp.flatten(
Object.values(this.subduxes).map(({actions}: Updux) =>
Object.entries(actions),
),
),
);
}
@computed get upreducer(): Upreducer<S> {
return buildUpreducer(this.initial, this.mutations);
}
/**
* A Redux reducer generated using the computed initial state and
* mutations.
*/
@computed get reducer(): (state: S | undefined, action: Action) => S {
return (state, action) => this.upreducer(action)(state as S);
}
/**
* Merge of the updux and subduxes mutations. If an action triggers
* mutations in both the main updux and its subduxes, the subduxes
* mutations will be performed first.
*/
@computed get mutations(): Dictionary<Mutation<S>> {
return buildMutations(this.localMutations, this.subduxes);
}
/**
* Same as doing
*
* ```
* import { createStore, applyMiddleware } from 'redux';
*
* const { initial, reducer, middleware, actions } = updox(...);
*
* const store = createStore( initial, reducer, applyMiddleware(middleware) );
*
* for ( let type in actions ) {
* store.dispatch[type] = (...args) => {
* store.dispatch(actions[type](...args))
* };
* }
* ```
*
* So that later on you can do
*
* ```
* store.dispatch.addTodo(...);
*
* // still work
* store.dispatch( actions.addTodo(...) );
*/
@computed get createStore(): () => StoreWithDispatchActions<S> {
const actions = this.actions;
return buildCreateStore<S>(
this.reducer,
this.initial,
this.middleware as Middleware,
this.actions,
) as () => StoreWithDispatchActions<S, typeof actions>;
}
/**
* Returns a
* [ducks](https://github.com/erikras/ducks-modular-redux)-like
* plain object holding the reducer from the Updux object and all
* its trimmings.
*/
get asDux(): Dux<S> {
return {
createStore: this.createStore,
upreducer: this.upreducer,
subduxes: this.subduxes,
middleware: this.middleware,
actions: this.actions,
reducer: this.reducer,
mutations: this.mutations,
initial: this.initial,
};
}
/**
* Adds a mutation and its associated action to the updux.
* If a local mutation was already associated to the action,
* it will be replaced by the new one.
* @example
* ```
* updux.addMutation( add, inc => state => state + inc );
* ```
*/
addMutation<A extends ActionCreator>(
creator: A,
mutation: Mutation<S, A extends (...args: any[]) => infer R ? R : never>,
) {
this.localActions[creator.type] = creator;
this.localMutations[creator.type] = this.groomMutations(
mutation as any,
) as Mutation<S>;
}
} }
export default Updux; export default Updux;

View File

@ -49,7 +49,7 @@
// "typeRoots": [], /* List of folders to include type definitions from. */ // "typeRoots": [], /* List of folders to include type definitions from. */
// "types": [], /* Type declaration files to be included in compilation. */ // "types": [], /* Type declaration files to be included in compilation. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
@ -60,7 +60,7 @@
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
/* Experimental Options */ /* Experimental Options */
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
} }
} }

View File

@ -1,5 +1,5 @@
{ {
"theme": "minimal", "theme": "default",
"tsBuildInfoFile": true, "tsBuildInfoFile": true,
"out": "docs", "out": "docs",
"mode": "file", "mode": "file",