source: node_modules/@reduxjs/toolkit/src/configureStore.ts@ a762898

Last change on this file since a762898 was a762898, checked in by istevanoska <ilinastevanoska@…>, 5 months ago

Added visualizations

  • Property mode set to 100644
File size: 7.6 KB
Line 
1import type {
2 Reducer,
3 ReducersMapObject,
4 Middleware,
5 Action,
6 StoreEnhancer,
7 Store,
8 UnknownAction,
9} from 'redux'
10import {
11 applyMiddleware,
12 createStore,
13 compose,
14 combineReducers,
15 isPlainObject,
16} from './reduxImports'
17import type { DevToolsEnhancerOptions as DevToolsOptions } from './devtoolsExtension'
18import { composeWithDevTools } from './devtoolsExtension'
19
20import type {
21 ThunkMiddlewareFor,
22 GetDefaultMiddleware,
23} from './getDefaultMiddleware'
24import { buildGetDefaultMiddleware } from './getDefaultMiddleware'
25import type {
26 ExtractDispatchExtensions,
27 ExtractStoreExtensions,
28 ExtractStateExtensions,
29 UnknownIfNonSpecific,
30} from './tsHelpers'
31import type { Tuple } from './utils'
32import type { GetDefaultEnhancers } from './getDefaultEnhancers'
33import { buildGetDefaultEnhancers } from './getDefaultEnhancers'
34
35/**
36 * Options for `configureStore()`.
37 *
38 * @public
39 */
40export interface ConfigureStoreOptions<
41 S = any,
42 A extends Action = UnknownAction,
43 M extends Tuple<Middlewares<S>> = Tuple<Middlewares<S>>,
44 E extends Tuple<Enhancers> = Tuple<Enhancers>,
45 P = S,
46> {
47 /**
48 * A single reducer function that will be used as the root reducer, or an
49 * object of slice reducers that will be passed to `combineReducers()`.
50 */
51 reducer: Reducer<S, A, P> | ReducersMapObject<S, A, P>
52
53 /**
54 * An array of Redux middleware to install, or a callback receiving `getDefaultMiddleware` and returning a Tuple of middleware.
55 * If not supplied, defaults to the set of middleware returned by `getDefaultMiddleware()`.
56 *
57 * @example `middleware: (gDM) => gDM().concat(logger, apiMiddleware, yourCustomMiddleware)`
58 * @see https://redux-toolkit.js.org/api/getDefaultMiddleware#intended-usage
59 */
60 middleware?: (getDefaultMiddleware: GetDefaultMiddleware<S>) => M
61
62 /**
63 * Whether to enable Redux DevTools integration. Defaults to `true`.
64 *
65 * Additional configuration can be done by passing Redux DevTools options
66 */
67 devTools?: boolean | DevToolsOptions
68
69 /**
70 * Whether to check for duplicate middleware instances. Defaults to `true`.
71 */
72 duplicateMiddlewareCheck?: boolean
73
74 /**
75 * The initial state, same as Redux's createStore.
76 * You may optionally specify it to hydrate the state
77 * from the server in universal apps, or to restore a previously serialized
78 * user session. If you use `combineReducers()` to produce the root reducer
79 * function (either directly or indirectly by passing an object as `reducer`),
80 * this must be an object with the same shape as the reducer map keys.
81 */
82 // we infer here, and instead complain if the reducer doesn't match
83 preloadedState?: P
84
85 /**
86 * The store enhancers to apply. See Redux's `createStore()`.
87 * All enhancers will be included before the DevTools Extension enhancer.
88 * If you need to customize the order of enhancers, supply a callback
89 * function that will receive a `getDefaultEnhancers` function that returns a Tuple,
90 * and should return a Tuple of enhancers (such as `getDefaultEnhancers().concat(offline)`).
91 * If you only need to add middleware, you can use the `middleware` parameter instead.
92 */
93 enhancers?: (getDefaultEnhancers: GetDefaultEnhancers<M>) => E
94}
95
96export type Middlewares<S> = ReadonlyArray<Middleware<{}, S>>
97
98type Enhancers = ReadonlyArray<StoreEnhancer>
99
100/**
101 * A Redux store returned by `configureStore()`. Supports dispatching
102 * side-effectful _thunks_ in addition to plain actions.
103 *
104 * @public
105 */
106export type EnhancedStore<
107 S = any,
108 A extends Action = UnknownAction,
109 E extends Enhancers = Enhancers,
110> = ExtractStoreExtensions<E> &
111 Store<S, A, UnknownIfNonSpecific<ExtractStateExtensions<E>>>
112
113/**
114 * A friendly abstraction over the standard Redux `createStore()` function.
115 *
116 * @param options The store configuration.
117 * @returns A configured Redux store.
118 *
119 * @public
120 */
121export function configureStore<
122 S = any,
123 A extends Action = UnknownAction,
124 M extends Tuple<Middlewares<S>> = Tuple<[ThunkMiddlewareFor<S>]>,
125 E extends Tuple<Enhancers> = Tuple<
126 [StoreEnhancer<{ dispatch: ExtractDispatchExtensions<M> }>, StoreEnhancer]
127 >,
128 P = S,
129>(options: ConfigureStoreOptions<S, A, M, E, P>): EnhancedStore<S, A, E> {
130 const getDefaultMiddleware = buildGetDefaultMiddleware<S>()
131
132 const {
133 reducer = undefined,
134 middleware,
135 devTools = true,
136 duplicateMiddlewareCheck = true,
137 preloadedState = undefined,
138 enhancers = undefined,
139 } = options || {}
140
141 let rootReducer: Reducer<S, A, P>
142
143 if (typeof reducer === 'function') {
144 rootReducer = reducer
145 } else if (isPlainObject(reducer)) {
146 rootReducer = combineReducers(reducer) as unknown as Reducer<S, A, P>
147 } else {
148 throw new Error(
149 '`reducer` is a required argument, and must be a function or an object of functions that can be passed to combineReducers',
150 )
151 }
152
153 if (
154 process.env.NODE_ENV !== 'production' &&
155 middleware &&
156 typeof middleware !== 'function'
157 ) {
158 throw new Error('`middleware` field must be a callback')
159 }
160
161 let finalMiddleware: Tuple<Middlewares<S>>
162 if (typeof middleware === 'function') {
163 finalMiddleware = middleware(getDefaultMiddleware)
164
165 if (
166 process.env.NODE_ENV !== 'production' &&
167 !Array.isArray(finalMiddleware)
168 ) {
169 throw new Error(
170 'when using a middleware builder function, an array of middleware must be returned',
171 )
172 }
173 } else {
174 finalMiddleware = getDefaultMiddleware()
175 }
176 if (
177 process.env.NODE_ENV !== 'production' &&
178 finalMiddleware.some((item: any) => typeof item !== 'function')
179 ) {
180 throw new Error(
181 'each middleware provided to configureStore must be a function',
182 )
183 }
184
185 if (process.env.NODE_ENV !== 'production' && duplicateMiddlewareCheck) {
186 let middlewareReferences = new Set<Middleware<any, S>>()
187 finalMiddleware.forEach((middleware) => {
188 if (middlewareReferences.has(middleware)) {
189 throw new Error(
190 'Duplicate middleware references found when creating the store. Ensure that each middleware is only included once.',
191 )
192 }
193 middlewareReferences.add(middleware)
194 })
195 }
196
197 let finalCompose = compose
198
199 if (devTools) {
200 finalCompose = composeWithDevTools({
201 // Enable capture of stack traces for dispatched Redux actions
202 trace: process.env.NODE_ENV !== 'production',
203 ...(typeof devTools === 'object' && devTools),
204 })
205 }
206
207 const middlewareEnhancer = applyMiddleware(...finalMiddleware)
208
209 const getDefaultEnhancers = buildGetDefaultEnhancers<M>(middlewareEnhancer)
210
211 if (
212 process.env.NODE_ENV !== 'production' &&
213 enhancers &&
214 typeof enhancers !== 'function'
215 ) {
216 throw new Error('`enhancers` field must be a callback')
217 }
218
219 let storeEnhancers =
220 typeof enhancers === 'function'
221 ? enhancers(getDefaultEnhancers)
222 : getDefaultEnhancers()
223
224 if (process.env.NODE_ENV !== 'production' && !Array.isArray(storeEnhancers)) {
225 throw new Error('`enhancers` callback must return an array')
226 }
227 if (
228 process.env.NODE_ENV !== 'production' &&
229 storeEnhancers.some((item: any) => typeof item !== 'function')
230 ) {
231 throw new Error(
232 'each enhancer provided to configureStore must be a function',
233 )
234 }
235 if (
236 process.env.NODE_ENV !== 'production' &&
237 finalMiddleware.length &&
238 !storeEnhancers.includes(middlewareEnhancer)
239 ) {
240 console.error(
241 'middlewares were provided, but middleware enhancer was not included in final enhancers - make sure to call `getDefaultEnhancers`',
242 )
243 }
244
245 const composedEnhancer: StoreEnhancer<any> = finalCompose(...storeEnhancers)
246
247 return createStore(rootReducer, preloadedState as P, composedEnhancer)
248}
Note: See TracBrowser for help on using the repository browser.