import React from 'react' ; import thunkMiddleware from 'redux-thunk' ; import Icestore from './icestore' ; import * as T from './types' ; import mergeConfig from './utils/mergeConfig' ; import createProviderPlugin from './plugins/provider' ; import createReduxHooksPlugin from './plugins/reduxHooks' ; import createModelApisPlugin from './plugins/modelApis' ; import createImmerPlugin from './plugins/immer' ; import createLoadingPlugin from './plugins/loading' ; import createErrorPlugin from './plugins/error' ; import { convertEffects , convertActions } from './utils/converter' ; import appendReducers from './utils/appendReducers' ; let count = 0 ; param config const init = < M extends T . Models > ( initConfig = { } ) : T . Icestore < M > => { const name = initConfig . name || count . toString ( ) ; count += 1 ; const config = mergeConfig ( { ... initConfig , name } ) ; return new Icestore ( config ) . init ( ) ; } ; param models param initConfig export const createStore = < M extends T . Models , C extends T . CreateStoreConfig < M > > ( models , initConfig ? ) : T . PresetIcestore < M > => { const { disableImmer , disableLoading , disableError , plugins = [ ] , redux = { } , } = initConfig || { } ; const middlewares = redux . middlewares || [ ] ; const context = React . createContext ( null ) ; middlewares . push ( thunkMiddleware ) ; plugins . push ( createProviderPlugin ( { context } ) ) ; plugins . push ( createReduxHooksPlugin ( { context } ) ) ; plugins . push ( createModelApisPlugin ( ) ) ; const immerBlacklist = [ ] ; if ( ! disableLoading ) { plugins . push ( createLoadingPlugin ( ) ) ; immerBlacklist . push ( 'loading' ) ; } if ( ! disableError ) { plugins . push ( createErrorPlugin ( ) ) ; immerBlacklist . push ( 'error' ) ; } if ( ! disableImmer ) { plugins . push ( createImmerPlugin ( { blacklist : immerBlacklist } ) ) ; } const wrappedModels = appendReducers ( convertEffects ( convertActions ( models ) ) ) ; const store = init ( { models : wrappedModels , plugins , redux : { ... redux , middlewares , } , } ) ; return store as T . PresetIcestore < M > ; } ; interface MapModelToProps < M extends T . ModelConfig > { ( model ) : Record < string , any > ; } export const withModel = < M extends T . ModelConfig , F extends MapModelToProps < M > , C extends T . CreateStoreConfig < { model : M ; } > > ( model , mapModelToProps ? , initConfig ? ) => { const modelName = 'model' ; mapModelToProps = ( mapModelToProps || ( ( modelApis ) => ( { [ modelName ] : modelApis } ) ) ) as F ; const store = createStore ( { [ modelName ] : model } , initConfig ) ; const { Provider , getModelAPIs } = store ; const modelApis = getModelAPIs ( modelName ) ; const withProps = mapModelToProps ( modelApis ) ; return < R extends ReturnType < F > , P extends R > ( Component ) => { return ( props ) : React . ReactElement => { return ( < Provider > < Component { ... withProps } { ... props as P } /> < /Provider>); } ; } ; } ; export default createStore ; export * from './types' ;