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

140 lines
3.5 KiB
Plaintext

import {
isAnyOf,
isFulfilled,
isRejected,
isRejectedWithValue,
} from '../rtkImports'
import type {
EndpointDefinitions,
FullTagDescription,
} from '../../endpointDefinitions'
import { calculateProvidedBy } from '../../endpointDefinitions'
import type { CombinedState, QueryCacheKey } from '../apiState'
import { QueryStatus, STATUS_UNINITIALIZED } from '../apiState'
import { calculateProvidedByThunk } from '../buildThunks'
import type {
SubMiddlewareApi,
InternalHandlerBuilder,
ApiMiddlewareInternalHandler,
} from './types'
import { getOrInsertComputed, createNewMap } from '../../utils/getOrInsert'
export const buildInvalidationByTagsHandler: InternalHandlerBuilder = ({
reducerPath,
context,
context: { endpointDefinitions },
mutationThunk,
queryThunk,
api,
assertTagType,
refetchQuery,
internalState,
}) => {
const { removeQueryResult } = api.internalActions
const isThunkActionWithTags = isAnyOf(
isFulfilled(mutationThunk),
isRejectedWithValue(mutationThunk),
)
const isQueryEnd = isAnyOf(
isFulfilled(queryThunk, mutationThunk),
isRejected(queryThunk, mutationThunk),
)
let pendingTagInvalidations: FullTagDescription<string>[] = []
// Track via counter so we can avoid iterating over state every time
let pendingRequestCount = 0
const handler: ApiMiddlewareInternalHandler = (action, mwApi) => {
if (
queryThunk.pending.match(action) ||
mutationThunk.pending.match(action)
) {
pendingRequestCount++
}
if (isQueryEnd(action)) {
pendingRequestCount = Math.max(0, pendingRequestCount - 1)
}
if (isThunkActionWithTags(action)) {
invalidateTags(
calculateProvidedByThunk(
action,
'invalidatesTags',
endpointDefinitions,
assertTagType,
),
mwApi,
)
} else if (isQueryEnd(action)) {
invalidateTags([], mwApi)
} else if (api.util.invalidateTags.match(action)) {
invalidateTags(
calculateProvidedBy(
action.payload,
undefined,
undefined,
undefined,
undefined,
assertTagType,
),
mwApi,
)
}
}
function hasPendingRequests() {
return pendingRequestCount > 0
}
function invalidateTags(
newTags: readonly FullTagDescription<string>[],
mwApi: SubMiddlewareApi,
) {
const rootState = mwApi.getState()
const state = rootState[reducerPath]
pendingTagInvalidations.push(...newTags)
if (
state.config.invalidationBehavior === 'delayed' &&
hasPendingRequests()
) {
return
}
const tags = pendingTagInvalidations
pendingTagInvalidations = []
if (tags.length === 0) return
const toInvalidate = api.util.selectInvalidatedBy(rootState, tags)
context.batch(() => {
const valuesArray = Array.from(toInvalidate.values())
for (const { queryCacheKey } of valuesArray) {
const querySubState = state.queries[queryCacheKey]
const subscriptionSubState = getOrInsertComputed(
internalState.currentSubscriptions,
queryCacheKey,
createNewMap,
)
if (querySubState) {
if (subscriptionSubState.size === 0) {
mwApi.dispatch(
removeQueryResult({
queryCacheKey: queryCacheKey as QueryCacheKey,
}),
)
} else if (querySubState.status !== STATUS_UNINITIALIZED) {
mwApi.dispatch(refetchQuery(querySubState))
}
}
}
})
}
return handler
}