import { createAction, createActions, handleActions, ActionMap, ReduxCompatibleReducer, ReduxCompatibleReducerMeta, ReducerMapMeta, ReducerMap, ActionFunctionAny } from 'redux-actions' import isPlainObject from 'lodash/isPlainObject' import { AeruxStore } from './store' import { Action } from 'redux' declare type Payload = any declare type State = any declare type Meta = any export interface ModelConfig { namespace: string state: State actions?: ActionMap reducers?: | ReducerMapMeta | ReducerMap | ReducerMap } export interface CreateActionMap { [actionName: string]: ActionFunctionAny> } export interface AeruxModel { namespace: string actions: CreateActionMap reducer: | ReduxCompatibleReducer | ReduxCompatibleReducerMeta } function createModel( model: ModelConfig, store?: AeruxStore ): AeruxModel { if (!isPlainObject(model)) { throw new TypeError('Invalid `model` present') } let { namespace, state, actions = {}, reducers = {} } = model if (!isPlainObject(reducers)) { reducers = {} } const options = { prefix: namespace } const createdActions = createActions(actions, options) const reducer = handleActions(reducers, state, options) if (namespace && store) { store.injectReducer(namespace, reducer) // create initial state action const initialStateAction = createAction(`${namespace}/@@INIT`) // initial state store.dispatch(initialStateAction()) } return { namespace, actions: createdActions, reducer } } export default createModel