updux => ts
This commit is contained in:
parent
76a75c9120
commit
f0e3b15fa4
@ -1,5 +1,5 @@
|
|||||||
import fp from 'lodash/fp';
|
import fp from 'lodash/fp';
|
||||||
import { Action } from '../types';
|
import { Action, ActionPayloadGenerator, Dictionary } from '../types';
|
||||||
|
|
||||||
interface ActionCreator {
|
interface ActionCreator {
|
||||||
( ...args: any[] ): Action;
|
( ...args: any[] ): Action;
|
||||||
@ -16,27 +16,25 @@ function actionFor(type:string) {
|
|||||||
return creator;
|
return creator;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function buildActions(
|
type ActionPair = [ string, ActionCreator ];
|
||||||
creators : { [action: string]: Function } = {},
|
|
||||||
mutations = {},
|
function buildActions(
|
||||||
effects = {},
|
generators : Dictionary<ActionPayloadGenerator> = {},
|
||||||
subActions = [],
|
actionNames: string[] = [],
|
||||||
) {
|
subActions : ActionPair[] = [],
|
||||||
|
):Dictionary<ActionCreator> {
|
||||||
|
|
||||||
// priority => generics => generic subs => craft subs => creators
|
// priority => generics => generic subs => craft subs => creators
|
||||||
|
|
||||||
const [ crafted, generic ] = fp.partition(
|
const [ crafted, generic ] = fp.partition(
|
||||||
([type,f]) => !f._genericAction
|
([type,f]) => !f._genericAction
|
||||||
)( fp.flatten( subActions.map( x => Object.entries(x) ) ).filter(
|
)( subActions );
|
||||||
([_,f]) => f
|
|
||||||
) )
|
|
||||||
|
|
||||||
const actions = [
|
const actions = [
|
||||||
...([ ...Object.keys(mutations), ...Object.keys(effects) ]
|
...(actionNames.map( type => [ type, actionFor(type) ] )),
|
||||||
.map( type => [ type, actionFor(type) ] )),
|
|
||||||
...generic,
|
...generic,
|
||||||
...crafted,
|
...crafted,
|
||||||
...Object.entries(creators).map(
|
...Object.entries(generators).map(
|
||||||
([type, payload]: [ string, Function ]) => [type, (...args: any) => ({ type, payload: payload(...args) })]
|
([type, payload]: [ string, Function ]) => [type, (...args: any) => ({ type, payload: payload(...args) })]
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
@ -44,3 +42,5 @@ export default function buildActions(
|
|||||||
return fp.fromPairs(actions);
|
return fp.fromPairs(actions);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default buildActions;
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
import fp from 'lodash/fp';
|
import fp from 'lodash/fp';
|
||||||
|
import { Dictionary } from '../types';
|
||||||
|
|
||||||
function buildInitial<S extends object>( initial?: Partial<S>, subduxes?: Partial<S> ): S;
|
function buildInitial<S extends number|string|boolean>( initial: S, subduxes?: Dictionary<undefined> ): S;
|
||||||
|
function buildInitial<S extends object>( initial?: Partial<S>, subduxes?: Partial<S> ): S extends object ? S : never;
|
||||||
function buildInitial(
|
function buildInitial(
|
||||||
initial = {},
|
initial : any = {},
|
||||||
subduxes = {} ,
|
subduxes : any = {} ,
|
||||||
) {
|
) {
|
||||||
return fp.isPlainObject(initial) ? fp.mergeAll([subduxes, initial]) : initial;
|
return fp.isPlainObject(initial) ? fp.mergeAll([subduxes, initial]) : initial;
|
||||||
}
|
}
|
||||||
|
@ -12,14 +12,9 @@ const MiddlewareFor = (type: any, mw: Middleware ): Middleware => api => next =>
|
|||||||
type Next = (action: Action) => any;
|
type Next = (action: Action) => any;
|
||||||
|
|
||||||
function buildMiddleware(
|
function buildMiddleware(
|
||||||
effects: Dictionary<Middleware>,
|
effects : Dictionary<Middleware>= {},
|
||||||
actions: Dictionary<ActionCreator>,
|
actions : Dictionary<ActionCreator>= {},
|
||||||
subMiddlewares: Middleware[],
|
subMiddlewares :Middleware[] = [],
|
||||||
): Middleware
|
|
||||||
function buildMiddleware(
|
|
||||||
effects = {},
|
|
||||||
actions = {},
|
|
||||||
subduxes = {},
|
|
||||||
) {
|
) {
|
||||||
return (api: any) => {
|
return (api: any) => {
|
||||||
for (let type in actions) {
|
for (let type in actions) {
|
||||||
@ -31,7 +26,7 @@ function buildMiddleware(
|
|||||||
...fp.toPairs(effects).map(([type, effect]) =>
|
...fp.toPairs(effects).map(([type, effect]) =>
|
||||||
MiddlewareFor(type,effect as Middleware)
|
MiddlewareFor(type,effect as Middleware)
|
||||||
),
|
),
|
||||||
...fp.map('middleware', subduxes),
|
...subMiddlewares
|
||||||
]
|
]
|
||||||
.filter(x => x)
|
.filter(x => x)
|
||||||
.reduceRight((next, mw) => mw(api)(next), original_next);
|
.reduceRight((next, mw) => mw(api)(next), original_next);
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import fp from 'lodash/fp';
|
import fp from 'lodash/fp';
|
||||||
|
|
||||||
import { Dictionary, Mutation, Action } from '../types';
|
import { Dictionary, Mutation, Action, Upreducer } from '../types';
|
||||||
|
|
||||||
function buildUpreducer<S>(initial: S, mutations: Dictionary<Mutation<S>> ) {
|
function buildUpreducer<S>(initial: S, mutations: Dictionary<Mutation<S>> ): Upreducer<S> {
|
||||||
return (action :Action) => (state: S) => {
|
return (action :Action) => (state: S) => {
|
||||||
if (state === null) state = initial;
|
if (state === null) state = initial;
|
||||||
|
|
||||||
|
@ -9,11 +9,12 @@ export type Dictionary<T> = { [key: string]: T };
|
|||||||
|
|
||||||
export type Mutation<S=any> = (payload: any, action: Action) => (state: S) => S ;
|
export type Mutation<S=any> = (payload: any, action: Action) => (state: S) => S ;
|
||||||
|
|
||||||
type ActionPayloadGenerator = (...args:any[]) => any;
|
export type ActionPayloadGenerator = (...args:any[]) => any;
|
||||||
|
|
||||||
export type ActionCreator = (...args: any[] ) => Action;
|
export type ActionCreator = (...args: any[] ) => Action;
|
||||||
|
|
||||||
export type UpduxConfig = Partial<{
|
export type UpduxConfig<S=any> = Partial<{
|
||||||
|
initial: S,
|
||||||
subduxes: {},
|
subduxes: {},
|
||||||
actions: {
|
actions: {
|
||||||
[ type: string ]: ActionPayloadGenerator
|
[ type: string ]: ActionPayloadGenerator
|
||||||
@ -21,3 +22,5 @@ export type UpduxConfig = Partial<{
|
|||||||
mutations: any,
|
mutations: any,
|
||||||
effects: any,
|
effects: any,
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
export type Upreducer<S=any> = (action:Action) => (state:S) => S;
|
||||||
|
30
src/updux.ts
30
src/updux.ts
@ -6,15 +6,28 @@ 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 } from './types';
|
import { UpduxConfig, Dictionary, Action, ActionCreator, Mutation, Upreducer } from './types';
|
||||||
|
|
||||||
|
import { Middleware } from 'redux';
|
||||||
|
|
||||||
export class Updux {
|
export class Updux<S=any> {
|
||||||
|
|
||||||
subduxes: Dictionary<Updux>;
|
subduxes: Dictionary<Updux>;
|
||||||
|
|
||||||
actions: Dictionary<ActionCreator>
|
actions: Dictionary<ActionCreator>
|
||||||
|
|
||||||
|
initial: S;
|
||||||
|
|
||||||
|
mutations: Dictionary<Mutation>;
|
||||||
|
|
||||||
|
upreducer: Upreducer<S>;
|
||||||
|
|
||||||
|
reducer: (state:S|undefined,action:Action) => S;
|
||||||
|
|
||||||
|
middleware: Middleware;
|
||||||
|
|
||||||
|
createStore: Function;
|
||||||
|
|
||||||
constructor(config: UpduxConfig) {
|
constructor(config: UpduxConfig) {
|
||||||
|
|
||||||
this.subduxes = fp.mapValues(
|
this.subduxes = fp.mapValues(
|
||||||
@ -24,12 +37,11 @@ export class Updux {
|
|||||||
|
|
||||||
this.actions = buildActions(
|
this.actions = buildActions(
|
||||||
config.actions,
|
config.actions,
|
||||||
config.mutations,
|
[ ...Object.keys(config.mutations||{}), ...Object.keys(config.effects||{} ) ],
|
||||||
config.effects,
|
fp.flatten( Object.values( this.subduxes ).map( ({actions}:Updux) => Object.entries(actions) ) ),
|
||||||
Object.values( this.subduxes ).map( ({actions}) => actions ),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
this.initial = buildInitial(
|
this.initial = buildInitial<any>(
|
||||||
config.initial, fp.mapValues( ({initial}) => initial )(this.subduxes)
|
config.initial, fp.mapValues( ({initial}) => initial )(this.subduxes)
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -42,16 +54,16 @@ export class Updux {
|
|||||||
);
|
);
|
||||||
|
|
||||||
this.reducer = (state,action) => {
|
this.reducer = (state,action) => {
|
||||||
return this.upreducer(action)(state);
|
return this.upreducer(action)(state as S);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.middleware = buildMiddleware(
|
this.middleware = buildMiddleware(
|
||||||
config.effects,
|
config.effects,
|
||||||
this.actions,
|
this.actions,
|
||||||
config.subduxes,
|
Object.values(this.subduxes).map( sd => sd.middleware )
|
||||||
);
|
);
|
||||||
|
|
||||||
this.createStore = buildCreateStore(this.reducer,this.initial,this.middleware,this.actions);
|
this.createStore = buildCreateStore<S>(this.reducer,this.initial,this.middleware,this.actions);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user