Skip to content

Commit 78d427e

Browse files
committed
Byte-shave cache middleware
1 parent dddb8ce commit 78d427e

File tree

4 files changed

+55
-33
lines changed

4 files changed

+55
-33
lines changed

packages/toolkit/src/query/core/buildMiddleware/cacheCollection.ts

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ export const buildCacheCollectionHandler: InternalHandlerBuilder = ({
4343
queryThunk,
4444
context,
4545
internalState,
46+
selectors: { selectQueryEntry, selectConfig },
4647
}) => {
4748
const { removeQueryResult, unsubscribeQueryResult, cacheEntriesUpserted } =
4849
api.internalActions
@@ -66,8 +67,9 @@ export const buildCacheCollectionHandler: InternalHandlerBuilder = ({
6667
mwApi,
6768
internalState,
6869
) => {
70+
const state = mwApi.getState()
71+
const config = selectConfig(state)
6972
if (canTriggerUnsubscribe(action)) {
70-
const state = mwApi.getState()[reducerPath]
7173
let queryCacheKeys: QueryCacheKey[]
7274

7375
if (cacheEntriesUpserted.match(action)) {
@@ -81,14 +83,7 @@ export const buildCacheCollectionHandler: InternalHandlerBuilder = ({
8183
queryCacheKeys = [queryCacheKey]
8284
}
8385

84-
for (const queryCacheKey of queryCacheKeys) {
85-
handleUnsubscribe(
86-
queryCacheKey,
87-
state.queries[queryCacheKey]?.endpointName,
88-
mwApi,
89-
state.config,
90-
)
91-
}
86+
handleUnsubscribeMany(queryCacheKeys, mwApi, config)
9287
}
9388

9489
if (api.util.resetApiState.match(action)) {
@@ -99,19 +94,27 @@ export const buildCacheCollectionHandler: InternalHandlerBuilder = ({
9994
}
10095

10196
if (context.hasRehydrationInfo(action)) {
102-
const state = mwApi.getState()[reducerPath]
10397
const { queries } = context.extractRehydrationInfo(action)!
104-
for (const [queryCacheKey, queryState] of Object.entries(queries)) {
105-
// Gotcha:
106-
// If rehydrating before the endpoint has been injected,the global `keepUnusedDataFor`
107-
// will be used instead of the endpoint-specific one.
108-
handleUnsubscribe(
109-
queryCacheKey as QueryCacheKey,
110-
queryState?.endpointName,
111-
mwApi,
112-
state.config,
113-
)
114-
}
98+
// Gotcha:
99+
// If rehydrating before the endpoint has been injected,the global `keepUnusedDataFor`
100+
// will be used instead of the endpoint-specific one.
101+
handleUnsubscribeMany(
102+
Object.keys(queries) as QueryCacheKey[],
103+
mwApi,
104+
config,
105+
)
106+
}
107+
}
108+
109+
function handleUnsubscribeMany(
110+
cacheKeys: QueryCacheKey[],
111+
api: SubMiddlewareApi,
112+
config: ConfigState<string>,
113+
) {
114+
const state = api.getState()
115+
for (const queryCacheKey of cacheKeys) {
116+
const entry = selectQueryEntry(state, queryCacheKey)
117+
handleUnsubscribe(queryCacheKey, entry?.endpointName, api, config)
115118
}
116119
}
117120

packages/toolkit/src/query/core/buildMiddleware/cacheLifecycle.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { ThunkDispatch, UnknownAction } from '@reduxjs/toolkit'
22
import type { BaseQueryFn, BaseQueryMeta } from '../../baseQueryTypes'
33
import type { BaseEndpointDefinition } from '../../endpointDefinitions'
44
import { DefinitionType } from '../../endpointDefinitions'
5-
import type { RootState } from '../apiState'
5+
import type { QueryCacheKey, RootState } from '../apiState'
66
import type {
77
MutationResultSelectorResult,
88
QueryResultSelectorResult,
@@ -185,6 +185,7 @@ export const buildCacheLifecycleHandler: InternalHandlerBuilder = ({
185185
queryThunk,
186186
mutationThunk,
187187
internalState,
188+
selectors: { selectQueryEntry, selectApiState },
188189
}) => {
189190
const isQueryThunk = isAsyncThunkAction(queryThunk)
190191
const isMutationThunk = isAsyncThunkAction(mutationThunk)
@@ -225,17 +226,17 @@ export const buildCacheLifecycleHandler: InternalHandlerBuilder = ({
225226
mwApi,
226227
stateBefore,
227228
) => {
228-
const cacheKey = getCacheKey(action)
229+
const cacheKey = getCacheKey(action) as QueryCacheKey
229230

230231
function checkForNewCacheKey(
231232
endpointName: string,
232-
cacheKey: string,
233+
cacheKey: QueryCacheKey,
233234
requestId: string,
234235
originalArgs: unknown,
235236
) {
236-
const oldState = stateBefore[reducerPath].queries[cacheKey]
237-
const state = mwApi.getState()[reducerPath].queries[cacheKey]
238-
if (!oldState && state) {
237+
const oldEntry = selectQueryEntry(stateBefore, cacheKey)
238+
const newEntry = selectQueryEntry(mwApi.getState(), cacheKey)
239+
if (!oldEntry && newEntry) {
239240
handleNewKey(endpointName, originalArgs, cacheKey, mwApi, requestId)
240241
}
241242
}

packages/toolkit/src/query/core/buildMiddleware/invalidationByTags.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,11 @@ export const buildInvalidationByTagsHandler: InternalHandlerBuilder = ({
7676
function hasPendingRequests(
7777
state: CombinedState<EndpointDefinitions, string, string>,
7878
) {
79-
for (const key in state.queries) {
80-
if (state.queries[key]?.status === QueryStatus.pending) return true
81-
}
82-
for (const key in state.mutations) {
83-
if (state.mutations[key]?.status === QueryStatus.pending) return true
79+
const { queries, mutations } = state
80+
for (const cacheRecord of [queries, mutations]) {
81+
for (const key in cacheRecord) {
82+
if (cacheRecord[key]?.status === QueryStatus.pending) return true
83+
}
8484
}
8585
return false
8686
}

packages/toolkit/src/query/core/buildMiddleware/polling.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
import type { QuerySubstateIdentifier, Subscribers } from '../apiState'
1+
import type {
2+
QueryCacheKey,
3+
QuerySubstateIdentifier,
4+
Subscribers,
5+
} from '../apiState'
26
import { QueryStatus } from '../apiState'
37
import type {
48
QueryStateMeta,
@@ -49,6 +53,20 @@ export const buildPollingHandler: InternalHandlerBuilder = ({
4953
}
5054
}
5155

56+
function getCacheEntrySubscriptions(
57+
queryCacheKey: QueryCacheKey,
58+
api: SubMiddlewareApi,
59+
) {
60+
const state = api.getState()[reducerPath]
61+
const querySubState = state.queries[queryCacheKey]
62+
const subscriptions = internalState.currentSubscriptions[queryCacheKey]
63+
64+
if (!querySubState || querySubState.status === QueryStatus.uninitialized)
65+
return
66+
67+
return subscriptions
68+
}
69+
5270
function startNextPoll(
5371
{ queryCacheKey }: QuerySubstateIdentifier,
5472
api: SubMiddlewareApi,

0 commit comments

Comments
 (0)