@@ -144,6 +144,7 @@ function defaultTransformResponse(baseQueryReturnValue: unknown) {
144
144
145
145
export type MaybeDrafted < T > = T | Draft < T >
146
146
export type Recipe < T > = ( data : MaybeDrafted < T > ) => void | MaybeDrafted < T >
147
+ export type UpsertRecipe < T > = ( data : MaybeDrafted < T > | undefined ) => void | MaybeDrafted < T >
147
148
148
149
export type PatchQueryDataThunk <
149
150
Definitions extends EndpointDefinitions ,
@@ -163,6 +164,15 @@ export type UpdateQueryDataThunk<
163
164
updateRecipe : Recipe < ResultTypeFrom < Definitions [ EndpointName ] > >
164
165
) => ThunkAction < PatchCollection , PartialState , any , AnyAction >
165
166
167
+ export type UpsertQueryDataThunk <
168
+ Definitions extends EndpointDefinitions ,
169
+ PartialState
170
+ > = < EndpointName extends QueryKeys < Definitions > > (
171
+ endpointName : EndpointName ,
172
+ args : QueryArgFrom < Definitions [ EndpointName ] > ,
173
+ upsertRecipe : UpsertRecipe < ResultTypeFrom < Definitions [ EndpointName ] > >
174
+ ) => ThunkAction < PatchCollection , PartialState , any , AnyAction >
175
+
166
176
/**
167
177
* An object returned from dispatching a `api.util.updateQueryData` call.
168
178
*/
@@ -252,6 +262,53 @@ export function buildThunks<
252
262
253
263
dispatch ( api . util . patchQueryData ( endpointName , args , ret . patches ) )
254
264
265
+ return ret
266
+ }
267
+
268
+ const upsertQueryData : UpsertQueryDataThunk < EndpointDefinitions , State > =
269
+ ( endpointName , args , upsertRecipe ) => ( dispatch , getState ) => {
270
+ const currentState = (
271
+ api . endpoints [ endpointName ] as ApiEndpointQuery < any , any >
272
+ ) . select ( args ) ( getState ( ) )
273
+ let ret : PatchCollection = {
274
+ patches : [ ] ,
275
+ inversePatches : [ ] ,
276
+ undo : ( ) =>
277
+ dispatch (
278
+ api . util . patchQueryData ( endpointName , args , ret . inversePatches )
279
+ ) ,
280
+ }
281
+ if ( currentState . status === QueryStatus . uninitialized ) {
282
+ return ret
283
+ }
284
+ if ( 'data' in currentState ) {
285
+ if ( isDraftable ( currentState . data ) ) {
286
+ const [ , patches , inversePatches ] = produceWithPatches (
287
+ currentState . data ,
288
+ upsertRecipe
289
+ )
290
+ ret . patches . push ( ...patches )
291
+ ret . inversePatches . push ( ...inversePatches )
292
+ } else {
293
+ const value = upsertRecipe ( currentState . data )
294
+ ret . patches . push ( { op : 'replace' , path : [ ] , value } )
295
+ ret . inversePatches . push ( {
296
+ op : 'replace' ,
297
+ path : [ ] ,
298
+ value : currentState . data ,
299
+ } )
300
+ }
301
+ dispatch ( api . util . patchQueryData ( endpointName , args , ret . patches ) )
302
+ } else {
303
+ ret . inversePatches . push ( {
304
+ op : 'replace' ,
305
+ path : [ ] ,
306
+ value : undefined ,
307
+ } )
308
+ dispatch ( api . endpoints [ endpointName ] . initiate ( args , { subscribe : false , forceRefetch : true , } ) )
309
+ }
310
+
311
+
255
312
return ret
256
313
}
257
314
@@ -291,7 +348,10 @@ export function buildThunks<
291
348
forced :
292
349
arg . type === 'query' ? isForcedQuery ( arg , getState ( ) ) : undefined ,
293
350
}
294
- if ( endpointDefinition . query ) {
351
+ if ( 'forceQueryFn' in arg && arg . forceQueryFn ) {
352
+ result = arg . forceQueryFn ( )
353
+
354
+ } else if ( endpointDefinition . query ) {
295
355
result = await baseQuery (
296
356
endpointDefinition . query ( arg . originalArgs ) ,
297
357
baseQueryApi ,
@@ -527,6 +587,7 @@ In the case of an unhandled error, no tags will be "provided" or "invalidated".`
527
587
mutationThunk,
528
588
prefetch,
529
589
updateQueryData,
590
+ upsertQueryData,
530
591
patchQueryData,
531
592
buildMatchThunkActions,
532
593
}
0 commit comments