import * as Redux from 'redux' ; import * as T from './types' ; import isListener from './utils/isListener' ; const composeEnhancersWithDevtools = ( devtoolOptions = { } ) : any => { const { disabled , ... options } = devtoolOptions ; return ! disabled && typeof window === 'object' && window . __REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window . __REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ( options ) : Redux . compose ; } ; export default function ( { redux , models , } ) { const combineReducers = redux . combineReducers || Redux . combineReducers ; const createStore = redux . createStore || Redux . createStore ; const initialStates = typeof redux . initialStates !== 'undefined' ? redux . initialStates : { } ; this . reducers = redux . reducers ; this . mergeReducers = ( nextReducers = { } ) => { this . reducers = { ... this . reducers , ... nextReducers } ; if ( ! Object . keys ( this . reducers ) . length ) { return ( state ) => state ; } return combineReducers ( this . reducers ) ; } ; this . createModelReducer = ( model ) => { const modelBaseReducer = model . baseReducer ; const modelReducers = { } ; for ( const modelReducer of Object . keys ( model . reducers || { } ) ) { const action = isListener ( modelReducer ) ? modelReducer : `${ model . name }/${ modelReducer }` ; modelReducers [ action ] = model . reducers [ modelReducer ] ; } const combinedReducer = ( state = model . state , action ) => { if ( typeof modelReducers [ action . type ] === 'function' ) { return modelReducers [ action . type ] ( state , action . payload , action . meta ) ; } return state ; } ; this . reducers [ model . name ] = ! modelBaseReducer ? combinedReducer : ( state , action ) => combinedReducer ( modelBaseReducer ( state , action ) , action ) ; } ; for ( const model of models ) { this . createModelReducer ( model ) ; } this . createRootReducer = ( rootReducers = { } ) : Redux . Reducer < any , T . Action > => { const mergedReducers = this . mergeReducers ( ) ; if ( Object . keys ( rootReducers ) . length ) { return ( state , action ) => { const rootReducerAction = rootReducers [ action . type ] ; if ( rootReducerAction ) { return mergedReducers ( rootReducerAction ( state , action ) , action ) ; } return mergedReducers ( state , action ) ; } ; } return mergedReducers ; } ; const rootReducer = this . createRootReducer ( redux . rootReducers ) ; const middlewares = Redux . applyMiddleware ( ... redux . middlewares ) ; const enhancers = composeEnhancersWithDevtools ( redux . devtoolOptions ) ( ... redux . enhancers , middlewares ) ; this . store = createStore ( rootReducer , initialStates , enhancers ) ; return this ; }