source: node_modules/@reduxjs/toolkit/src/dynamicMiddleware/index.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: 2.6 KB
Line 
1import type { Dispatch, Middleware, UnknownAction } from 'redux'
2import { compose } from '../reduxImports'
3import { createAction } from '../createAction'
4import { isAllOf } from '../matchers'
5import { nanoid } from '../nanoid'
6import { getOrInsertComputed } from '../utils'
7import type {
8 AddMiddleware,
9 DynamicMiddleware,
10 DynamicMiddlewareInstance,
11 MiddlewareEntry,
12 WithMiddleware,
13} from './types'
14export type {
15 DynamicMiddlewareInstance,
16 GetDispatchType as GetDispatch,
17 MiddlewareApiConfig,
18} from './types'
19
20const createMiddlewareEntry = <
21 State = any,
22 DispatchType extends Dispatch<UnknownAction> = Dispatch<UnknownAction>,
23>(
24 middleware: Middleware<any, State, DispatchType>,
25): MiddlewareEntry<State, DispatchType> => ({
26 middleware,
27 applied: new Map(),
28})
29
30const matchInstance =
31 (instanceId: string) =>
32 (action: any): action is { meta: { instanceId: string } } =>
33 action?.meta?.instanceId === instanceId
34
35export const createDynamicMiddleware = <
36 State = any,
37 DispatchType extends Dispatch<UnknownAction> = Dispatch<UnknownAction>,
38>(): DynamicMiddlewareInstance<State, DispatchType> => {
39 const instanceId = nanoid()
40 const middlewareMap = new Map<
41 Middleware<any, State, DispatchType>,
42 MiddlewareEntry<State, DispatchType>
43 >()
44
45 const withMiddleware = Object.assign(
46 createAction(
47 'dynamicMiddleware/add',
48 (...middlewares: Middleware<any, State, DispatchType>[]) => ({
49 payload: middlewares,
50 meta: {
51 instanceId,
52 },
53 }),
54 ),
55 { withTypes: () => withMiddleware },
56 ) as WithMiddleware<State, DispatchType>
57
58 const addMiddleware = Object.assign(
59 function addMiddleware(
60 ...middlewares: Middleware<any, State, DispatchType>[]
61 ) {
62 middlewares.forEach((middleware) => {
63 getOrInsertComputed(middlewareMap, middleware, createMiddlewareEntry)
64 })
65 },
66 { withTypes: () => addMiddleware },
67 ) as AddMiddleware<State, DispatchType>
68
69 const getFinalMiddleware: Middleware<{}, State, DispatchType> = (api) => {
70 const appliedMiddleware = Array.from(middlewareMap.values()).map((entry) =>
71 getOrInsertComputed(entry.applied, api, entry.middleware),
72 )
73 return compose(...appliedMiddleware)
74 }
75
76 const isWithMiddleware = isAllOf(withMiddleware, matchInstance(instanceId))
77
78 const middleware: DynamicMiddleware<State, DispatchType> =
79 (api) => (next) => (action) => {
80 if (isWithMiddleware(action)) {
81 addMiddleware(...action.payload)
82 return api.dispatch
83 }
84 return getFinalMiddleware(api)(next)(action)
85 }
86
87 return {
88 middleware,
89 addMiddleware,
90 withMiddleware,
91 instanceId,
92 }
93}
Note: See TracBrowser for help on using the repository browser.