Skip to content

Commit 881db12

Browse files
committed
Extract reusable helpers for writing cache entries
1 parent c855b8b commit 881db12

File tree

1 file changed

+96
-75
lines changed

1 file changed

+96
-75
lines changed

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

Lines changed: 96 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,100 @@ export function buildSlice({
112112
>
113113
}) {
114114
const resetApiState = createAction(`${reducerPath}/resetApiState`)
115+
116+
function writePendingCacheEntry(
117+
draft: QueryState<any>,
118+
arg: QueryThunkArg,
119+
upserting: boolean,
120+
meta: {
121+
arg: QueryThunkArg
122+
requestId: string
123+
// requestStatus: 'pending'
124+
} & { startedTimeStamp: number },
125+
) {
126+
draft[arg.queryCacheKey] ??= {
127+
status: QueryStatus.uninitialized,
128+
endpointName: arg.endpointName,
129+
}
130+
131+
updateQuerySubstateIfExists(draft, arg.queryCacheKey, (substate) => {
132+
substate.status = QueryStatus.pending
133+
134+
substate.requestId =
135+
upserting && substate.requestId
136+
? // for `upsertQuery` **updates**, keep the current `requestId`
137+
substate.requestId
138+
: // for normal queries or `upsertQuery` **inserts** always update the `requestId`
139+
meta.requestId
140+
if (arg.originalArgs !== undefined) {
141+
substate.originalArgs = arg.originalArgs
142+
}
143+
substate.startedTimeStamp = meta.startedTimeStamp
144+
})
145+
}
146+
147+
function writeFulfilledCacheEntry(
148+
draft: QueryState<any>,
149+
meta: {
150+
arg: QueryThunkArg
151+
requestId: string
152+
// requestStatus: 'fulfilled'
153+
} & {
154+
fulfilledTimeStamp: number
155+
baseQueryMeta: unknown
156+
// RTK_autoBatch: true
157+
},
158+
payload: unknown,
159+
) {
160+
updateQuerySubstateIfExists(draft, meta.arg.queryCacheKey, (substate) => {
161+
if (substate.requestId !== meta.requestId && !isUpsertQuery(meta.arg))
162+
return
163+
const { merge } = definitions[meta.arg.endpointName] as QueryDefinition<
164+
any,
165+
any,
166+
any,
167+
any
168+
>
169+
substate.status = QueryStatus.fulfilled
170+
171+
if (merge) {
172+
if (substate.data !== undefined) {
173+
const { fulfilledTimeStamp, arg, baseQueryMeta, requestId } = meta
174+
// There's existing cache data. Let the user merge it in themselves.
175+
// We're already inside an Immer-powered reducer, and the user could just mutate `substate.data`
176+
// themselves inside of `merge()`. But, they might also want to return a new value.
177+
// Try to let Immer figure that part out, save the result, and assign it to `substate.data`.
178+
let newData = createNextState(substate.data, (draftSubstateData) => {
179+
// As usual with Immer, you can mutate _or_ return inside here, but not both
180+
return merge(draftSubstateData, payload, {
181+
arg: arg.originalArgs,
182+
baseQueryMeta,
183+
fulfilledTimeStamp,
184+
requestId,
185+
})
186+
})
187+
substate.data = newData
188+
} else {
189+
// Presumably a fresh request. Just cache the response data.
190+
substate.data = payload
191+
}
192+
} else {
193+
// Assign or safely update the cache data.
194+
substate.data =
195+
definitions[meta.arg.endpointName].structuralSharing ?? true
196+
? copyWithStructuralSharing(
197+
isDraft(substate.data)
198+
? original(substate.data)
199+
: substate.data,
200+
payload,
201+
)
202+
: payload
203+
}
204+
205+
delete substate.error
206+
substate.fulfilledTimeStamp = meta.fulfilledTimeStamp
207+
})
208+
}
115209
const querySlice = createSlice({
116210
name: `${reducerPath}/queries`,
117211
initialState: initialState as QueryState<any>,
@@ -149,83 +243,10 @@ export function buildSlice({
149243
builder
150244
.addCase(queryThunk.pending, (draft, { meta, meta: { arg } }) => {
151245
const upserting = isUpsertQuery(arg)
152-
draft[arg.queryCacheKey] ??= {
153-
status: QueryStatus.uninitialized,
154-
endpointName: arg.endpointName,
155-
}
156-
157-
updateQuerySubstateIfExists(draft, arg.queryCacheKey, (substate) => {
158-
substate.status = QueryStatus.pending
159-
160-
substate.requestId =
161-
upserting && substate.requestId
162-
? // for `upsertQuery` **updates**, keep the current `requestId`
163-
substate.requestId
164-
: // for normal queries or `upsertQuery` **inserts** always update the `requestId`
165-
meta.requestId
166-
if (arg.originalArgs !== undefined) {
167-
substate.originalArgs = arg.originalArgs
168-
}
169-
substate.startedTimeStamp = meta.startedTimeStamp
170-
})
246+
writePendingCacheEntry(draft, arg, upserting, meta)
171247
})
172248
.addCase(queryThunk.fulfilled, (draft, { meta, payload }) => {
173-
updateQuerySubstateIfExists(
174-
draft,
175-
meta.arg.queryCacheKey,
176-
(substate) => {
177-
if (
178-
substate.requestId !== meta.requestId &&
179-
!isUpsertQuery(meta.arg)
180-
)
181-
return
182-
const { merge } = definitions[
183-
meta.arg.endpointName
184-
] as QueryDefinition<any, any, any, any>
185-
substate.status = QueryStatus.fulfilled
186-
187-
if (merge) {
188-
if (substate.data !== undefined) {
189-
const { fulfilledTimeStamp, arg, baseQueryMeta, requestId } =
190-
meta
191-
// There's existing cache data. Let the user merge it in themselves.
192-
// We're already inside an Immer-powered reducer, and the user could just mutate `substate.data`
193-
// themselves inside of `merge()`. But, they might also want to return a new value.
194-
// Try to let Immer figure that part out, save the result, and assign it to `substate.data`.
195-
let newData = createNextState(
196-
substate.data,
197-
(draftSubstateData) => {
198-
// As usual with Immer, you can mutate _or_ return inside here, but not both
199-
return merge(draftSubstateData, payload, {
200-
arg: arg.originalArgs,
201-
baseQueryMeta,
202-
fulfilledTimeStamp,
203-
requestId,
204-
})
205-
},
206-
)
207-
substate.data = newData
208-
} else {
209-
// Presumably a fresh request. Just cache the response data.
210-
substate.data = payload
211-
}
212-
} else {
213-
// Assign or safely update the cache data.
214-
substate.data =
215-
definitions[meta.arg.endpointName].structuralSharing ?? true
216-
? copyWithStructuralSharing(
217-
isDraft(substate.data)
218-
? original(substate.data)
219-
: substate.data,
220-
payload,
221-
)
222-
: payload
223-
}
224-
225-
delete substate.error
226-
substate.fulfilledTimeStamp = meta.fulfilledTimeStamp
227-
},
228-
)
249+
writeFulfilledCacheEntry(draft, meta, payload)
229250
})
230251
.addCase(
231252
queryThunk.rejected,

0 commit comments

Comments
 (0)