1import type { Middleware, AnyAction } from 'redux' 2import type { ThunkMiddleware } from 'redux-thunk' 3import thunkMiddleware from 'redux-thunk' 4import type { ImmutableStateInvariantMiddlewareOptions } from './immutableStateInvariantMiddleware' 5/* PROD_START_REMOVE_UMD */ 6import { createImmutableStateInvariantMiddleware } from './immutableStateInvariantMiddleware' 7/* PROD_STOP_REMOVE_UMD */ 8 9import type { SerializableStateInvariantMiddlewareOptions } from './serializableStateInvariantMiddleware' 10import { createSerializableStateInvariantMiddleware } from './serializableStateInvariantMiddleware' 11import { MiddlewareArray } from './utils' 12 13function isBoolean(x: any): x is boolean { 14 return typeof x === 'boolean' 15} 16 17interface ThunkOptions<E = any> { 18 extraArgument: E 19} 20 21interface GetDefaultMiddlewareOptions { 22 thunk?: boolean | ThunkOptions 23 immutableCheck?: boolean | ImmutableStateInvariantMiddlewareOptions 24 serializableCheck?: boolean | SerializableStateInvariantMiddlewareOptions 25} 26 27export type ThunkMiddlewareFor< 28 S, 29 O extends GetDefaultMiddlewareOptions = {} 30> = O extends { 31 thunk: false 32} 33 ? never 34 : O extends { thunk: { extraArgument: infer E } } 35 ? ThunkMiddleware<S, AnyAction, E> 36 : 37 | ThunkMiddleware<S, AnyAction, null> //The ThunkMiddleware with a `null` ExtraArgument is here to provide backwards-compatibility. 38 | ThunkMiddleware<S, AnyAction> 39 40export type CurriedGetDefaultMiddleware<S = any> = < 41 O extends Partial<GetDefaultMiddlewareOptions> = { 42 thunk: true 43 immutableCheck: true 44 serializableCheck: true 45 } 46>( 47 options?: O 48) => MiddlewareArray<Middleware<{}, S> | ThunkMiddlewareFor<S, O>> 49 50export function curryGetDefaultMiddleware< 51 S = any 52>(): CurriedGetDefaultMiddleware<S> { 53 return function curriedGetDefaultMiddleware(options) { 54 return getDefaultMiddleware(options) 55 } 56} 57 58/** 59 * Returns any array containing the default middleware installed by 60 * `configureStore()`. Useful if you want to configure your store with a custom 61 * `middleware` array but still keep the default set. 62 * 63 * @return The default middleware used by `configureStore()`. 64 * 65 * @public 66 * 67 * @deprecated Prefer to use the callback notation for the `middleware` option in `configureStore` 68 * to access a pre-typed `getDefaultMiddleware` instead. 69 */ 70export function getDefaultMiddleware< 71 S = any, 72 O extends Partial<GetDefaultMiddlewareOptions> = { 73 thunk: true 74 immutableCheck: true 75 serializableCheck: true 76 } 77>( 78 options: O = {} as O 79): MiddlewareArray<Middleware<{}, S> | ThunkMiddlewareFor<S, O>> { 80 const { 81 thunk = true, 82 immutableCheck = true, 83 serializableCheck = true, 84 } = options 85 86 let middlewareArray: Middleware<{}, S>[] = new MiddlewareArray() 87 88 if (thunk) { 89 if (isBoolean(thunk)) { 90 middlewareArray.push(thunkMiddleware) 91 } else { 92 middlewareArray.push( 93 thunkMiddleware.withExtraArgument(thunk.extraArgument) 94 ) 95 } 96 } 97 98 if (process.env.NODE_ENV !== 'production') { 99 if (immutableCheck) { 100 /* PROD_START_REMOVE_UMD */ 101 let immutableOptions: ImmutableStateInvariantMiddlewareOptions = {} 102 103 if (!isBoolean(immutableCheck)) { 104 immutableOptions = immutableCheck 105 } 106 107 middlewareArray.unshift( 108 createImmutableStateInvariantMiddleware(immutableOptions) 109 ) 110 /* PROD_STOP_REMOVE_UMD */ 111 } 112 113 if (serializableCheck) { 114 let serializableOptions: SerializableStateInvariantMiddlewareOptions = {} 115 116 if (!isBoolean(serializableCheck)) { 117 serializableOptions = serializableCheck 118 } 119 120 middlewareArray.push( 121 createSerializableStateInvariantMiddleware(serializableOptions) 122 ) 123 } 124 } 125 126 return middlewareArray as any 127} 128