@@ -8,34 +8,27 @@ import type {
8
8
Store ,
9
9
Dispatch ,
10
10
} from 'redux'
11
- import { createStore , compose , applyMiddleware , combineReducers } from 'redux'
11
+ import { applyMiddleware , createStore , compose , combineReducers } from 'redux'
12
12
import type { DevToolsEnhancerOptions as DevToolsOptions } from './devtoolsExtension'
13
13
import { composeWithDevTools } from './devtoolsExtension'
14
14
15
15
import isPlainObject from './isPlainObject'
16
16
import type {
17
17
ThunkMiddlewareFor ,
18
- CurriedGetDefaultMiddleware ,
18
+ GetDefaultMiddleware ,
19
19
} from './getDefaultMiddleware'
20
- import { curryGetDefaultMiddleware } from './getDefaultMiddleware'
20
+ import { buildGetDefaultMiddleware } from './getDefaultMiddleware'
21
21
import type {
22
22
ExtractDispatchExtensions ,
23
23
ExtractStoreExtensions ,
24
24
ExtractStateExtensions ,
25
25
} from './tsHelpers'
26
- import { EnhancerArray } from './utils'
26
+ import type { EnhancerArray , MiddlewareArray } from './utils'
27
+ import type { GetDefaultEnhancers } from './getDefaultEnhancers'
28
+ import { buildGetDefaultEnhancers } from './getDefaultEnhancers'
27
29
28
30
const IS_PRODUCTION = process . env . NODE_ENV === 'production'
29
31
30
- /**
31
- * Callback function type, to be used in `ConfigureStoreOptions.enhancers`
32
- *
33
- * @public
34
- */
35
- export type ConfigureEnhancersCallback < E extends Enhancers = Enhancers > = (
36
- defaultEnhancers : EnhancerArray < [ StoreEnhancer < { } , { } > ] >
37
- ) => E
38
-
39
32
/**
40
33
* Options for `configureStore()`.
41
34
*
@@ -61,7 +54,7 @@ export interface ConfigureStoreOptions<
61
54
* @example `middleware: (gDM) => gDM().concat(logger, apiMiddleware, yourCustomMiddleware)`
62
55
* @see https://redux-toolkit.js.org/api/getDefaultMiddleware#intended-usage
63
56
*/
64
- middleware ?: ( ( getDefaultMiddleware : CurriedGetDefaultMiddleware < S > ) => M ) | M
57
+ middleware ?: ( ( getDefaultMiddleware : GetDefaultMiddleware < S > ) => M ) | M
65
58
66
59
/**
67
60
* Whether to enable Redux DevTools integration. Defaults to `true`.
@@ -85,30 +78,17 @@ export interface ConfigureStoreOptions<
85
78
* The store enhancers to apply. See Redux's `createStore()`.
86
79
* All enhancers will be included before the DevTools Extension enhancer.
87
80
* If you need to customize the order of enhancers, supply a callback
88
- * function that will receive the original array (ie, `[applyMiddleware]`) ,
89
- * and should return a new array (such as `[applyMiddleware, offline] `).
81
+ * function that will receive a `getDefaultEnhancers` function that returns an EnhancerArray ,
82
+ * and should return a new array (such as `getDefaultEnhancers().concat( offline) `).
90
83
* If you only need to add middleware, you can use the `middleware` parameter instead.
91
84
*/
92
- enhancers ?: E | ConfigureEnhancersCallback < E >
85
+ enhancers ?: ( ( getDefaultEnhancers : GetDefaultEnhancers < M > ) => E ) | E
93
86
}
94
87
95
- type Middlewares < S > = ReadonlyArray < Middleware < { } , S > >
88
+ export type Middlewares < S > = ReadonlyArray < Middleware < { } , S > >
96
89
97
90
type Enhancers = ReadonlyArray < StoreEnhancer >
98
91
99
- export interface ToolkitStore <
100
- S = any ,
101
- A extends Action = AnyAction ,
102
- M extends Middlewares < S > = Middlewares < S >
103
- > extends Store < S , A > {
104
- /**
105
- * The `dispatch` method of your store, enhanced by all its middlewares.
106
- *
107
- * @inheritdoc
108
- */
109
- dispatch : ExtractDispatchExtensions < M > & Dispatch < A >
110
- }
111
-
112
92
/**
113
93
* A Redux store returned by `configureStore()`. Supports dispatching
114
94
* side-effectful _thunks_ in addition to plain actions.
@@ -118,10 +98,8 @@ export interface ToolkitStore<
118
98
export type EnhancedStore <
119
99
S = any ,
120
100
A extends Action = AnyAction ,
121
- M extends Middlewares < S > = Middlewares < S > ,
122
101
E extends Enhancers = Enhancers
123
- > = ToolkitStore < S & ExtractStateExtensions < E > , A , M > &
124
- ExtractStoreExtensions < E >
102
+ > = ExtractStoreExtensions < E > & Store < S & ExtractStateExtensions < E > , A >
125
103
126
104
/**
127
105
* A friendly abstraction over the standard Redux `createStore()` function.
@@ -134,15 +112,17 @@ export type EnhancedStore<
134
112
export function configureStore <
135
113
S = any ,
136
114
A extends Action = AnyAction ,
137
- M extends Middlewares < S > = [ ThunkMiddlewareFor < S > ] ,
138
- E extends Enhancers = [ StoreEnhancer ] ,
115
+ M extends Middlewares < S > = MiddlewareArray < [ ThunkMiddlewareFor < S > ] > ,
116
+ E extends Enhancers = EnhancerArray <
117
+ [ StoreEnhancer < { dispatch : ExtractDispatchExtensions < M > } > , StoreEnhancer ]
118
+ > ,
139
119
P = S
140
- > ( options : ConfigureStoreOptions < S , A , M , E , P > ) : EnhancedStore < S , A , M , E > {
141
- const curriedGetDefaultMiddleware = curryGetDefaultMiddleware < S > ( )
120
+ > ( options : ConfigureStoreOptions < S , A , M , E , P > ) : EnhancedStore < S , A , E > {
121
+ const getDefaultMiddleware = buildGetDefaultMiddleware < S > ( )
142
122
143
123
const {
144
124
reducer = undefined ,
145
- middleware = curriedGetDefaultMiddleware ( ) ,
125
+ middleware = getDefaultMiddleware ( ) ,
146
126
devTools = true ,
147
127
preloadedState = undefined ,
148
128
enhancers = undefined ,
@@ -162,7 +142,7 @@ export function configureStore<
162
142
163
143
let finalMiddleware = middleware
164
144
if ( typeof finalMiddleware === 'function' ) {
165
- finalMiddleware = finalMiddleware ( curriedGetDefaultMiddleware )
145
+ finalMiddleware = finalMiddleware ( getDefaultMiddleware )
166
146
167
147
if ( ! IS_PRODUCTION && ! Array . isArray ( finalMiddleware ) ) {
168
148
throw new Error (
@@ -179,8 +159,6 @@ export function configureStore<
179
159
)
180
160
}
181
161
182
- const middlewareEnhancer : StoreEnhancer = applyMiddleware ( ...finalMiddleware )
183
-
184
162
let finalCompose = compose
185
163
186
164
if ( devTools ) {
@@ -191,16 +169,36 @@ export function configureStore<
191
169
} )
192
170
}
193
171
194
- const defaultEnhancers = new EnhancerArray ( middlewareEnhancer )
195
- let storeEnhancers : Enhancers = defaultEnhancers
172
+ const middlewareEnhancer = applyMiddleware ( ...finalMiddleware )
173
+
174
+ const getDefaultEnhancers = buildGetDefaultEnhancers < M > ( middlewareEnhancer )
175
+ let storeEnhancers =
176
+ ( typeof enhancers === 'function'
177
+ ? enhancers ( getDefaultEnhancers )
178
+ : enhancers ) ?? getDefaultEnhancers ( )
196
179
197
- if ( Array . isArray ( enhancers ) ) {
198
- storeEnhancers = [ middlewareEnhancer , ...enhancers ]
199
- } else if ( typeof enhancers === 'function' ) {
200
- storeEnhancers = enhancers ( defaultEnhancers )
180
+ if ( ! IS_PRODUCTION && ! Array . isArray ( storeEnhancers ) ) {
181
+ throw new Error ( 'enhancers must be an array' )
182
+ }
183
+ if (
184
+ ! IS_PRODUCTION &&
185
+ storeEnhancers . some ( ( item : any ) => typeof item !== 'function' )
186
+ ) {
187
+ throw new Error (
188
+ 'each enhancer provided to configureStore must be a function'
189
+ )
190
+ }
191
+ if (
192
+ ! IS_PRODUCTION &&
193
+ finalMiddleware . length &&
194
+ ! storeEnhancers . includes ( middlewareEnhancer )
195
+ ) {
196
+ console . error (
197
+ 'middlewares were provided, but middleware enhancer was not included in final enhancers'
198
+ )
201
199
}
202
200
203
- const composedEnhancer = finalCompose ( ...storeEnhancers ) as StoreEnhancer < any >
201
+ const composedEnhancer : StoreEnhancer < any > = finalCompose ( ...storeEnhancers )
204
202
205
203
return createStore ( rootReducer , preloadedState , composedEnhancer )
206
204
}
0 commit comments