Files
NapCatQQ/.pnpm-store/v3/files/60/5fe40b3b77fc74af9ea4cf6659ca9001f31c2872ec06de2ec46c151d808375fa2569b89be7b0cb3a9fd7253a389d1911000b25deb245f0b4ea605c7fad19aa
T
TanTan e311ca3275
Build NapCat Artifacts / Type Check & Test (push) Waiting to run
docs: 仓库链接指向本镜像仓库
2026-11-13 09:25:58 +08:00

94 lines
2.6 KiB
Plaintext

import type { Dispatch, Middleware, UnknownAction } from 'redux'
import { compose } from '../reduxImports'
import { createAction } from '../createAction'
import { isAllOf } from '../matchers'
import { nanoid } from '../nanoid'
import { getOrInsertComputed } from '../utils'
import type {
AddMiddleware,
DynamicMiddleware,
DynamicMiddlewareInstance,
MiddlewareEntry,
WithMiddleware,
} from './types'
export type {
DynamicMiddlewareInstance,
GetDispatchType as GetDispatch,
MiddlewareApiConfig,
} from './types'
const createMiddlewareEntry = <
State = any,
DispatchType extends Dispatch<UnknownAction> = Dispatch<UnknownAction>,
>(
middleware: Middleware<any, State, DispatchType>,
): MiddlewareEntry<State, DispatchType> => ({
middleware,
applied: new Map(),
})
const matchInstance =
(instanceId: string) =>
(action: any): action is { meta: { instanceId: string } } =>
action?.meta?.instanceId === instanceId
export const createDynamicMiddleware = <
State = any,
DispatchType extends Dispatch<UnknownAction> = Dispatch<UnknownAction>,
>(): DynamicMiddlewareInstance<State, DispatchType> => {
const instanceId = nanoid()
const middlewareMap = new Map<
Middleware<any, State, DispatchType>,
MiddlewareEntry<State, DispatchType>
>()
const withMiddleware = Object.assign(
createAction(
'dynamicMiddleware/add',
(...middlewares: Middleware<any, State, DispatchType>[]) => ({
payload: middlewares,
meta: {
instanceId,
},
}),
),
{ withTypes: () => withMiddleware },
) as WithMiddleware<State, DispatchType>
const addMiddleware = Object.assign(
function addMiddleware(
...middlewares: Middleware<any, State, DispatchType>[]
) {
middlewares.forEach((middleware) => {
getOrInsertComputed(middlewareMap, middleware, createMiddlewareEntry)
})
},
{ withTypes: () => addMiddleware },
) as AddMiddleware<State, DispatchType>
const getFinalMiddleware: Middleware<{}, State, DispatchType> = (api) => {
const appliedMiddleware = Array.from(middlewareMap.values()).map((entry) =>
getOrInsertComputed(entry.applied, api, entry.middleware),
)
return compose(...appliedMiddleware)
}
const isWithMiddleware = isAllOf(withMiddleware, matchInstance(instanceId))
const middleware: DynamicMiddleware<State, DispatchType> =
(api) => (next) => (action) => {
if (isWithMiddleware(action)) {
addMiddleware(...action.payload)
return api.dispatch
}
return getFinalMiddleware(api)(next)(action)
}
return {
middleware,
addMiddleware,
withMiddleware,
instanceId,
}
}