UNPKG

farmbot-web-frontend

Version:
51 lines (39 loc) 1.7 kB
import { ReduxAction } from "./interfaces"; import { defensiveClone } from "./util"; const NOOP = (s: any, a: ReduxAction<{}>) => s; export function generateReducer<State>( initialState: State, /** Set "catch all" handler for unknown action names. Default is a no-op fn. * Useful for logging / debugging. */ DEFAULT = NOOP) { /** A function that responds to a particular action from within a generated reducer. */ interface ActionHandler { (state: State, action: ReduxAction<any>): State; } interface GenericActionHandler<T> { (state: State, action: ReduxAction<T>): State; } interface ActionHandlerDict { [actionHandler: string]: ActionHandler; DEFAULT: ActionHandler; } interface GeneratedReducer extends ActionHandler { /** Adds action handler for current reducer. */ add: <T>(name: string, fn: GenericActionHandler<T>) => GeneratedReducer; // Calms the type checker. } let actionHandlers: ActionHandlerDict = { DEFAULT }; let reducer: GeneratedReducer = function<T>(state = initialState, action: ReduxAction<T>): State { let handler = (actionHandlers[action.type] || actionHandlers["DEFAULT"]); let clonedState = defensiveClone<State>(state); let clonedAction = defensiveClone<ReduxAction<T>>(action); let result: State = handler(clonedState, clonedAction); return result; } as GeneratedReducer; reducer.add = function addHandler<T>(name: string, fn: GenericActionHandler<T>) { actionHandlers[name] = fn; return reducer; }; return reducer; }