import type { Reducer , ReducersMapObject , Middleware , Action , AnyAction , StoreEnhancer , Store , Dispatch , PreloadedState , CombinedState , } from 'redux' ; import { createStore , compose , applyMiddleware , combineReducers } from 'redux' ; import type { EnhancerOptions as DevToolsOptions } from './devtoolsExtension' ; import { composeWithDevTools } from './devtoolsExtension' ; import isPlainObject from './isPlainObject' ; import type { ThunkMiddlewareFor , CurriedGetDefaultMiddleware , } from './getDefaultMiddleware' ; import { curryGetDefaultMiddleware } from './getDefaultMiddleware' ; import type { DispatchForMiddlewares , NoInfer } from './tsHelpers' ; const IS_PRODUCTION = process . env . NODE_ENV === 'production' ; public export type ConfigureEnhancersCallback = ( defaultEnhancers : readonly StoreEnhancer [ ] ) => StoreEnhancer [ ] ; public export interface ConfigureStoreOptions < S = any , A extends Action = AnyAction , M extends Middlewares < S > = Middlewares < S > > { /**
     * A single reducer function that will be used as the root reducer, or an
     * object of slice reducers that will be passed to `combineReducers()`.
     */ reducer : Reducer < S , A > | ReducersMapObject < S , A > ; /**
     * An array of Redux middleware to install. If not supplied, defaults to
     * the set of middleware returned by `getDefaultMiddleware()`.
     */ middleware ? : ( ( getDefaultMiddleware : CurriedGetDefaultMiddleware < S > ) => M ) | M ; /**
     * Whether to enable Redux DevTools integration. Defaults to `true`.
     *
     * Additional configuration can be done by passing Redux DevTools options
     */ devTools ? : boolean | DevToolsOptions ; /**
     * The initial state, same as Redux's createStore.
     * You may optionally specify it to hydrate the state
     * from the server in universal apps, or to restore a previously serialized
     * user session. If you use `combineReducers()` to produce the root reducer
     * function (either directly or indirectly by passing an object as `reducer`),
     * this must be an object with the same shape as the reducer map keys.
     */ preloadedState ? : PreloadedState < CombinedState < NoInfer < S > > > ; /**
     * The store enhancers to apply. See Redux's `createStore()`.
     * All enhancers will be included before the DevTools Extension enhancer.
     * If you need to customize the order of enhancers, supply a callback
     * function that will receive the original array (ie, `[applyMiddleware]`),
     * and should return a new array (such as `[applyMiddleware, offline]`).
     * If you only need to add middleware, you can use the `middleware` parameter instead.
     */ enhancers ? : StoreEnhancer [ ] | ConfigureEnhancersCallback ; } type Middlewares < S > = ReadonlyArray < Middleware < { } , S > > ; public export interface EnhancedStore < S = any , A extends Action = AnyAction , M extends Middlewares < S > = Middlewares < S > > extends Store < S , A > { inheritdoc dispatch : Dispatch < A > & DispatchForMiddlewares < M > ; } param config returns public export function configureStore < S = any , A extends Action = AnyAction , M extends Middlewares < S > = [ ThunkMiddlewareFor < S > ] > ( options ) { const curriedGetDefaultMiddleware = curryGetDefaultMiddleware < S > ( ) ; const { reducer = undefined , middleware = curriedGetDefaultMiddleware ( ) , devTools = true , preloadedState = undefined , enhancers = undefined , } = options || { } ; let rootReducer ; if ( typeof reducer === 'function' ) { rootReducer = reducer ; } else if ( isPlainObject ( reducer ) ) { rootReducer = combineReducers ( reducer ) ; } else { throw new Error ( '"reducer" is a required argument, and must be a function or an object of functions that can be passed to combineReducers' ) ; } let finalMiddleware = middleware ; if ( typeof finalMiddleware === 'function' ) { finalMiddleware = finalMiddleware ( curriedGetDefaultMiddleware ) ; if ( ! IS_PRODUCTION && ! Array . isArray ( finalMiddleware ) ) { throw new Error ( 'when using a middleware builder function, an array of middleware must be returned' ) ; } } if ( ! IS_PRODUCTION && finalMiddleware . some ( ( item ) => typeof item !== 'function' ) ) { throw new Error ( 'each middleware provided to configureStore must be a function' ) ; } const middlewareEnhancer = applyMiddleware ( ... finalMiddleware ) ; let finalCompose = compose ; if ( devTools ) { finalCompose = composeWithDevTools ( { trace : ! IS_PRODUCTION , ... ( typeof devTools === 'object' && devTools ) , } ) ; } let storeEnhancers = [ middlewareEnhancer ] ; if ( Array . isArray ( enhancers ) ) { storeEnhancers = [ middlewareEnhancer , ... enhancers ] ; } else if ( typeof enhancers === 'function' ) { storeEnhancers = enhancers ( storeEnhancers ) ; } const composedEnhancer = finalCompose ( ... storeEnhancers ) as any ; return createStore ( rootReducer , preloadedState , composedEnhancer ) ; }