8
8
isRejectedWithValue ,
9
9
createNextState ,
10
10
prepareAutoBatched ,
11
+ SHOULD_AUTOBATCH ,
12
+ nanoid ,
11
13
} from './rtkImports'
12
14
import type {
13
15
QuerySubstateIdentifier ,
@@ -21,15 +23,24 @@ import type {
21
23
QueryCacheKey ,
22
24
SubscriptionState ,
23
25
ConfigState ,
26
+ QueryKeys ,
24
27
} from './apiState'
25
28
import { QueryStatus } from './apiState'
26
- import type { MutationThunk , QueryThunk , RejectedAction } from './buildThunks'
29
+ import type {
30
+ MutationThunk ,
31
+ QueryThunk ,
32
+ QueryThunkArg ,
33
+ RejectedAction ,
34
+ } from './buildThunks'
27
35
import { calculateProvidedByThunk } from './buildThunks'
28
36
import type {
29
37
AssertTagTypes ,
38
+ DefinitionType ,
30
39
EndpointDefinitions ,
31
40
FullTagDescription ,
41
+ QueryArgFrom ,
32
42
QueryDefinition ,
43
+ ResultTypeFrom ,
33
44
} from '../endpointDefinitions'
34
45
import type { Patch } from 'immer'
35
46
import { isDraft } from 'immer'
@@ -42,6 +53,44 @@ import {
42
53
} from '../utils'
43
54
import type { ApiContext } from '../apiTypes'
44
55
import { isUpsertQuery } from './buildInitiate'
56
+ import type { InternalSerializeQueryArgs } from '../defaultSerializeQueryArgs'
57
+
58
+ /**
59
+ * A typesafe single entry to be upserted into the cache
60
+ */
61
+ export type NormalizedQueryUpsertEntry <
62
+ Definitions extends EndpointDefinitions ,
63
+ EndpointName extends QueryKeys < Definitions > ,
64
+ > = {
65
+ endpointName : EndpointName
66
+ args : QueryArgFrom < Definitions [ EndpointName ] >
67
+ value : ResultTypeFrom < Definitions [ EndpointName ] >
68
+ }
69
+
70
+ /**
71
+ * The internal version that is not typesafe since we can't carry the generics through `createSlice`
72
+ */
73
+ type NormalizedQueryUpsertEntryPayload = {
74
+ endpointName : string
75
+ args : any
76
+ value : any
77
+ }
78
+
79
+ /**
80
+ * A typesafe representation of a util action creator that accepts cache entry descriptions to upsert
81
+ */
82
+ export type UpsertEntries < Definitions extends EndpointDefinitions > = <
83
+ EndpointNames extends Array < QueryKeys < Definitions > > ,
84
+ > (
85
+ entries : [
86
+ ...{
87
+ [ I in keyof EndpointNames ] : NormalizedQueryUpsertEntry <
88
+ Definitions ,
89
+ EndpointNames [ I ]
90
+ >
91
+ } ,
92
+ ] ,
93
+ ) => PayloadAction < NormalizedQueryUpsertEntryPayload >
45
94
46
95
function updateQuerySubstateIfExists (
47
96
state : QueryState < any > ,
@@ -92,6 +141,7 @@ export function buildSlice({
92
141
reducerPath,
93
142
queryThunk,
94
143
mutationThunk,
144
+ serializeQueryArgs,
95
145
context : {
96
146
endpointDefinitions : definitions ,
97
147
apiUid,
@@ -104,6 +154,7 @@ export function buildSlice({
104
154
reducerPath : string
105
155
queryThunk : QueryThunk
106
156
mutationThunk : MutationThunk
157
+ serializeQueryArgs : InternalSerializeQueryArgs
107
158
context : ApiContext < EndpointDefinitions >
108
159
assertTagType : AssertTagTypes
109
160
config : Omit <
@@ -221,6 +272,63 @@ export function buildSlice({
221
272
} ,
222
273
prepare : prepareAutoBatched < QuerySubstateIdentifier > ( ) ,
223
274
} ,
275
+ cacheEntriesUpserted : {
276
+ reducer (
277
+ draft ,
278
+ action : PayloadAction <
279
+ NormalizedQueryUpsertEntryPayload [ ] ,
280
+ string ,
281
+ {
282
+ RTK_autoBatch : boolean
283
+ requestId : string
284
+ timestamp : number
285
+ }
286
+ > ,
287
+ ) {
288
+ for ( const entry of action . payload ) {
289
+ const { endpointName, args, value } = entry
290
+ const endpointDefinition = definitions [ endpointName ]
291
+
292
+ const arg : QueryThunkArg = {
293
+ type : 'query' ,
294
+ endpointName : endpointName ,
295
+ originalArgs : entry . args ,
296
+ queryCacheKey : serializeQueryArgs ( {
297
+ queryArgs : args ,
298
+ endpointDefinition,
299
+ endpointName,
300
+ } ) ,
301
+ }
302
+ writePendingCacheEntry ( draft , arg , true , {
303
+ arg,
304
+ requestId : action . meta . requestId ,
305
+ startedTimeStamp : action . meta . timestamp ,
306
+ } )
307
+
308
+ writeFulfilledCacheEntry (
309
+ draft ,
310
+ {
311
+ arg,
312
+ requestId : action . meta . requestId ,
313
+ fulfilledTimeStamp : action . meta . timestamp ,
314
+ baseQueryMeta : { } ,
315
+ } ,
316
+ entry . value ,
317
+ )
318
+ }
319
+ } ,
320
+ prepare : ( payload : NormalizedQueryUpsertEntryPayload [ ] ) => {
321
+ const result = {
322
+ payload,
323
+ meta : {
324
+ [ SHOULD_AUTOBATCH ] : true ,
325
+ requestId : nanoid ( ) ,
326
+ timestamp : Date . now ( ) ,
327
+ } ,
328
+ }
329
+ return result
330
+ } ,
331
+ } ,
224
332
queryResultPatched : {
225
333
reducer (
226
334
draft ,
0 commit comments