Skip to content

Commit 53ce9e2

Browse files
dutziworksmarkerikson
authored andcommittedSep 24, 2023
add option to update provided tags
1 parent 6274ec8 commit 53ce9e2

File tree

3 files changed

+87
-65
lines changed

3 files changed

+87
-65
lines changed
 

‎packages/toolkit/src/query/core/buildSlice.ts

+39-22
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import { calculateProvidedByThunk } from './buildThunks'
2929
import type {
3030
AssertTagTypes,
3131
EndpointDefinitions,
32+
FullTagDescription,
3233
QueryDefinition,
3334
} from '../endpointDefinitions'
3435
import type { Patch } from 'immer'
@@ -325,7 +326,36 @@ export function buildSlice({
325326
const invalidationSlice = createSlice({
326327
name: `${reducerPath}/invalidation`,
327328
initialState: initialState as InvalidationState<string>,
328-
reducers: {},
329+
reducers: {
330+
updateProvidedBy: (
331+
draft,
332+
action: PayloadAction<{
333+
queryCacheKey: QueryCacheKey
334+
providedTags: readonly FullTagDescription<string>[]
335+
}>
336+
) => {
337+
const { queryCacheKey, providedTags } = action.payload
338+
339+
for (const tagTypeSubscriptions of Object.values(draft)) {
340+
for (const idSubscriptions of Object.values(tagTypeSubscriptions)) {
341+
const foundAt = idSubscriptions.indexOf(queryCacheKey)
342+
if (foundAt !== -1) {
343+
idSubscriptions.splice(foundAt, 1)
344+
}
345+
}
346+
}
347+
348+
for (const { type, id } of providedTags) {
349+
const subscribedQueries = ((draft[type] ??= {})[
350+
id || '__internal_without_id'
351+
] ??= [])
352+
const alreadySubscribed = subscribedQueries.includes(queryCacheKey)
353+
if (!alreadySubscribed) {
354+
subscribedQueries.push(queryCacheKey)
355+
}
356+
}
357+
},
358+
},
329359
extraReducers(builder) {
330360
builder
331361
.addCase(
@@ -371,27 +401,13 @@ export function buildSlice({
371401
)
372402
const { queryCacheKey } = action.meta.arg
373403

374-
for (const tagTypeSubscriptions of Object.values(draft)) {
375-
for (const idSubscriptions of Object.values(
376-
tagTypeSubscriptions
377-
)) {
378-
const foundAt = idSubscriptions.indexOf(queryCacheKey)
379-
if (foundAt !== -1) {
380-
idSubscriptions.splice(foundAt, 1)
381-
}
382-
}
383-
}
384-
385-
for (const { type, id } of providedTags) {
386-
const subscribedQueries = ((draft[type] ??= {})[
387-
id || '__internal_without_id'
388-
] ??= [])
389-
const alreadySubscribed =
390-
subscribedQueries.includes(queryCacheKey)
391-
if (!alreadySubscribed) {
392-
subscribedQueries.push(queryCacheKey)
393-
}
394-
}
404+
invalidationSlice.caseReducers.updateProvidedBy(
405+
draft,
406+
invalidationSlice.actions.updateProvidedBy({
407+
queryCacheKey,
408+
providedTags,
409+
})
410+
)
395411
}
396412
)
397413
},
@@ -497,6 +513,7 @@ export function buildSlice({
497513
...subscriptionSlice.actions,
498514
...internalSubscriptionsSlice.actions,
499515
...mutationSlice.actions,
516+
...invalidationSlice.actions,
500517
/** @deprecated has been renamed to `removeMutationResult` */
501518
unsubscribeMutationResult: mutationSlice.actions.removeMutationResult,
502519
resetApiState,

‎packages/toolkit/src/query/core/buildThunks.ts

+47-43
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,8 @@ export type PatchQueryDataThunk<
165165
> = <EndpointName extends QueryKeys<Definitions>>(
166166
endpointName: EndpointName,
167167
args: QueryArgFrom<Definitions[EndpointName]>,
168-
patches: readonly Patch[]
168+
patches: readonly Patch[],
169+
updateProvided?: boolean
169170
) => ThunkAction<void, PartialState, any, AnyAction>
170171

171172
export type UpdateQueryDataThunk<
@@ -174,7 +175,8 @@ export type UpdateQueryDataThunk<
174175
> = <EndpointName extends QueryKeys<Definitions>>(
175176
endpointName: EndpointName,
176177
args: QueryArgFrom<Definitions[EndpointName]>,
177-
updateRecipe: Recipe<ResultTypeFrom<Definitions[EndpointName]>>
178+
updateRecipe: Recipe<ResultTypeFrom<Definitions[EndpointName]>>,
179+
updateProvided?: boolean
178180
) => ThunkAction<PatchCollection, PartialState, any, AnyAction>
179181

180182
export type UpsertQueryDataThunk<
@@ -211,7 +213,6 @@ export type PatchCollection = {
211213
* A function that will undo the cache update.
212214
*/
213215
undo: () => void
214-
provided: readonly FullTagDescription<string>[]
215216
}
216217

217218
export function buildThunks<
@@ -236,41 +237,58 @@ export function buildThunks<
236237
type State = RootState<any, string, ReducerPath>
237238

238239
const patchQueryData: PatchQueryDataThunk<EndpointDefinitions, State> =
239-
(endpointName, args, patches) => (dispatch) => {
240+
(endpointName, args, patches, updateProvided) => (dispatch, getState) => {
240241
const endpointDefinition = endpointDefinitions[endpointName]
242+
243+
const queryCacheKey = serializeQueryArgs({
244+
queryArgs: args,
245+
endpointDefinition,
246+
endpointName,
247+
})
248+
241249
dispatch(
242-
api.internalActions.queryResultPatched({
243-
queryCacheKey: serializeQueryArgs({
244-
queryArgs: args,
245-
endpointDefinition,
246-
endpointName,
247-
}),
248-
patches,
249-
})
250+
api.internalActions.queryResultPatched({ queryCacheKey, patches })
251+
)
252+
253+
if (!updateProvided) {
254+
return
255+
}
256+
257+
const newValue = api.endpoints[endpointName].select(args)(getState())
258+
259+
const providedTags = calculateProvidedBy(
260+
endpointDefinition.providesTags,
261+
newValue.data,
262+
undefined,
263+
args,
264+
{},
265+
assertTagType
266+
)
267+
268+
dispatch(
269+
api.internalActions.updateProvidedBy({ queryCacheKey, providedTags })
250270
)
251271
}
252272

253273
const updateQueryData: UpdateQueryDataThunk<EndpointDefinitions, State> =
254274
(endpointName, args, updateRecipe, updateProvided = true) =>
255275
(dispatch, getState) => {
256-
const currentState = (
257-
api.endpoints[endpointName] as ApiEndpointQuery<any, any>
258-
).select(args)(getState())
276+
const endpointDefinition = api.endpoints[endpointName]
277+
278+
const currentState = endpointDefinition.select(args)(getState())
279+
259280
let ret: PatchCollection = {
260281
patches: [],
261282
inversePatches: [],
262-
undo: () => {
263-
dispatch(
264-
api.util.patchQueryData(endpointName, args, ret.inversePatches)
265-
)
266-
// this needs to `getState` the current value after patching the `inversePatch`
267-
const oldValue = getState()
283+
undo: () =>
268284
dispatch(
269-
// `updateProvidedBy` needs to be implemented as a new reducer on `invalidationSlice`
270-
updateProvidedBy(endpointName, args, calculateNewProvided(oldValue))
271-
)
272-
},
273-
provided: [],
285+
api.util.patchQueryData(
286+
endpointName,
287+
args,
288+
ret.inversePatches,
289+
updateProvided
290+
)
291+
),
274292
}
275293
if (currentState.status === QueryStatus.uninitialized) {
276294
return ret
@@ -296,25 +314,11 @@ export function buildThunks<
296314
}
297315
}
298316

299-
if (updateProvided) {
300-
ret.provided = calculateNewProvided(newValue)
301-
}
302-
303-
// `patchQueryData` needs to be added as `extraReducer` on `invalidationSlice`
304-
dispatch(api.util.patchQueryData(endpointName, args, ret.patches))
317+
dispatch(
318+
api.util.patchQueryData(endpointName, args, ret.patches, updateProvided)
319+
)
305320

306321
return ret
307-
308-
function calculateNewProvided(newValue: unknown) {
309-
return calculateProvidedBy(
310-
endpointDefinitions[endpointName].providesTags,
311-
newValue,
312-
undefined,
313-
args,
314-
{},
315-
assertTagType
316-
)
317-
}
318322
}
319323

320324
const upsertQueryData: UpsertQueryDataThunk<Definitions, State> =

‎packages/toolkit/src/query/core/module.ts

+1
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,7 @@ export const coreModule = (): Module<CoreModule> => ({
518518
context,
519519
api,
520520
serializeQueryArgs,
521+
assertTagType,
521522
})
522523

523524
const { reducer, actions: sliceActions } = buildSlice({

0 commit comments

Comments
 (0)
Please sign in to comment.