strip the types away

This commit is contained in:
Yanick Champoux 2019-10-22 10:55:54 -04:00
parent 78696efcbb
commit 5c75b7ffdb
12 changed files with 24 additions and 110 deletions

View File

@ -1,16 +1,15 @@
import fp from 'lodash/fp'; import fp from 'lodash/fp';
import { ActionEffects, ActionCreator, ActionCreators, ActionMutations } from '../types';
function actionFor(type: string) { function actionFor(type) {
return ( (payload = undefined, meta = undefined) => return ( (payload = undefined, meta = undefined) =>
fp.pickBy(v => v !== null)({type, payload, meta}) fp.pickBy(v => v !== null)({type, payload, meta})
) as ActionCreator; );
} }
export default function buildActions( export default function buildActions(
mutations : ActionMutations = {}, mutations = {},
effects : ActionEffects = {}, effects = {},
subActions : ActionCreators = {}, subActions = {},
) { ) {
return { ...subActions, return { ...subActions,

View File

@ -12,6 +12,6 @@ export default function buildCreateStore( reducer, initial, middleware,
}; };
} }
return store as any; return store;
} }
}; };

View File

@ -1,8 +1,8 @@
import fp from 'lodash/fp'; import fp from 'lodash/fp';
export default function buildInitial<S = any>( export default function buildInitial(
initial: any = {}, initial= {},
subduxes = {}, subduxes = {},
): S { ) {
return fp.isPlainObject(initial) ? fp.mergeAll([subduxes, initial]) : initial; return fp.isPlainObject(initial) ? fp.mergeAll([subduxes, initial]) : initial;
} }

View File

@ -1,6 +0,0 @@
// TypeScript Version: 3.4
import buildInitial from '.';
// $ExpectType any
const x = buildInitial();

View File

@ -1,14 +0,0 @@
import buildInitial from '.';
import {expectType} from 'tsd';
type MyState = {
foo: number,
bar: string,
};
const x = buildInitial<MyState>({
initial: {
glug: 3,
}
});
expectType<MyState>(x);

View File

@ -1,6 +0,0 @@
import buildMiddleware from '../buildMiddleware';
import {expectType} from 'tsd';
expectType<any>( buildMiddleware );

View File

@ -1,25 +1,23 @@
import fp from 'lodash/fp'; import fp from 'lodash/fp';
import u from 'updeep'; import u from 'updeep';
import { Mutation, Mutations } from '../types'; const composeMutations = (mutations) =>
const composeMutations = (mutations:Mutation[]) =>
mutations.reduce( (m1,m2) => mutations.reduce( (m1,m2) =>
(payload=null,action={}) => state => m2(payload,action)( (payload=null,action={}) => state => m2(payload,action)(
m1(payload,action)(state) )); m1(payload,action)(state) ));
export default function buildMutations(mutations = {}, subduxes= {}) :Mutations{ export default function buildMutations(mutations = {}, subduxes= {}) {
// we have to differentiate the subduxes with '*' than those // we have to differentiate the subduxes with '*' than those
// without, as the root '*' is not the same as any sub-'*' // without, as the root '*' is not the same as any sub-'*'
const actions = fp.uniq( Object.keys(mutations).concat( const actions = fp.uniq( Object.keys(mutations).concat(
...Object.values( subduxes ).map( ({mutations = {}}:any) => Object.keys(mutations) ) ...Object.values( subduxes ).map( ({mutations = {}}) => Object.keys(mutations) )
) ); ) );
let mergedMutations = {}; let mergedMutations = {};
let [ globby, nonGlobby ] = fp.partition( let [ globby, nonGlobby ] = fp.partition(
([_,{mutations={}}]:any) => mutations['*'], ([_,{mutations={}}]) => mutations['*'],
Object.entries(subduxes) Object.entries(subduxes)
); );
@ -32,16 +30,16 @@ export default function buildMutations(mutations = {}, subduxes= {}) :Mutations{
])(globby); ])(globby);
const globbyMutation = (payload,action) => u( const globbyMutation = (payload,action) => u(
fp.mapValues( (mut:any) => mut(payload,action) )(globby) fp.mapValues( (mut) => mut(payload,action) )(globby)
); );
actions.forEach( action => { actions.forEach( action => {
mergedMutations[action] = [ globbyMutation ] mergedMutations[action] = [ globbyMutation ]
}); });
nonGlobby.forEach( ([slice, {mutations={},reducer={}}]:any) => { nonGlobby.forEach( ([slice, {mutations={},reducer={}}]) => {
Object.entries(mutations).forEach(([type,mutation]) => { Object.entries(mutations).forEach(([type,mutation]) => {
const localized = (payload=null,action={}) => u.updateIn( slice )( (mutation as any)(payload,action) ); const localized = (payload=null,action={}) => u.updateIn( slice )( (mutation)(payload,action) );
mergedMutations[type].push(localized); mergedMutations[type].push(localized);
}) })
@ -51,5 +49,5 @@ export default function buildMutations(mutations = {}, subduxes= {}) :Mutations{
mergedMutations[type].push(mutation); mergedMutations[type].push(mutation);
}); });
return fp.mapValues( composeMutations )(mergedMutations) as Mutations; return fp.mapValues( composeMutations )(mergedMutations);
} }

View File

@ -1,18 +1,15 @@
import fp from 'lodash/fp'; import fp from 'lodash/fp';
import {Mutations} from '../types';
type Upreducer = <S>(action:any) => (state:S) => S; export default function buildUpreducer(initial, mutations) {
return (action = {}) => (state) => {
export default function buildUpreducer<S>(initial: S, mutations: Mutations): Upreducer {
return (action = {}) => (state:any) => {
if (state === null) state = initial; if (state === null) state = initial;
const a = const a =
mutations[(action as any).type] || mutations[(action).type] ||
mutations['*']; mutations['*'];
if(!a) return state; if(!a) return state;
return a((action as any).payload, action)(state) as S; return a((action).payload, action)(state);
}; };
} }

View File

@ -1,7 +1,6 @@
import fp from 'lodash/fp'; import fp from 'lodash/fp';
import u from 'updeep'; import u from 'updeep';
export { Updux } from './updux';
import Updux from './updux'; import Updux from './updux';
export default function updux(config) { export default function updux(config) {

View File

@ -1,5 +0,0 @@
import updux, {Updux } from '.';
import {expectType} from 'tsd';
const x = updux({});
expectType<Updux>(x);

View File

@ -1,23 +0,0 @@
export type Dictionary<T> = { [key: string]: T };
export type Mutation = (payload: any, action: any) => (state:any) => any;
export type Mutations = Dictionary<Mutation>;
export type ActionMutations = Dictionary<Mutation>;
export type Effect = (api:any) => (next: Function) => (action: any) => any;
export type ActionEffects = Dictionary<Effect>;
export type Action<T = string, P = any, M = any> = {
type: T,
payload: P,
meta: M,
}
export type ActionCreator = <P,M>(payload?: P, meta?: M ) => Action<string,P,M>;
export type ActionCreators = Dictionary<ActionCreator>;

View File

@ -3,42 +3,17 @@ import buildActions from './buildActions';
import buildInitial from './buildInitial'; import buildInitial from './buildInitial';
import buildMutations from './buildMutations'; import buildMutations from './buildMutations';
import { Dictionary, Mutation, ActionCreators } from './types';
import buildCreateStore from './buildCreateStore'; import buildCreateStore from './buildCreateStore';
import buildMiddleware from './buildMiddleware'; import buildMiddleware from './buildMiddleware';
import buildUpreducer from './buildUpreducer'; import buildUpreducer from './buildUpreducer';
type UpduxConfig = {
initial?: any,
mutations?: any,
effects?: any,
subduxes?: {
[ slice: string ]: UpduxConfig | Updux
}
};
export class Updux { export class Updux {
actions: ActionCreators;
subduxes: Dictionary<Updux>; constructor(config) {
initial: any;
mutations: Dictionary<Mutation>;
createStore: Function;
upreducer: (action:any)=>(state:any)=>any;
reducer: <S>(state:S,action:any) => S;
middleware: (api:any) => (next: Function) => (action: any) => any;
constructor(config: UpduxConfig) {
this.subduxes = fp.mapValues( this.subduxes = fp.mapValues(
value => fp.isPlainObject(value) ? new Updux(value as UpduxConfig) : value )(fp.getOr({},'subduxes',config) value => fp.isPlainObject(value) ? new Updux(value ) : value )(fp.getOr({},'subduxes',config)
) as Dictionary<Updux>; );
this.actions = buildActions( this.actions = buildActions(