@@ -5,22 +5,12 @@ import type {
5
5
QueryArgFrom ,
6
6
ResultTypeFrom ,
7
7
} from '../endpointDefinitions'
8
- import type {
9
- QueryThunkArg ,
10
- MutationThunkArg ,
11
- QueryThunk ,
12
- MutationThunk ,
13
- } from './buildThunks'
14
- import type {
15
- AnyAction ,
16
- AsyncThunk ,
17
- ThunkAction ,
18
- SerializedError ,
19
- } from '@reduxjs/toolkit'
20
- import { unwrapResult } from '@reduxjs/toolkit'
8
+ import { DefinitionType } from '../endpointDefinitions'
9
+ import type { QueryThunk , MutationThunk } from './buildThunks'
10
+ import type { AnyAction , ThunkAction , SerializedError } from '@reduxjs/toolkit'
21
11
import type { QuerySubState , SubscriptionOptions , RootState } from './apiState'
22
12
import type { InternalSerializeQueryArgs } from '../defaultSerializeQueryArgs'
23
- import type { Api } from '../apiTypes'
13
+ import type { Api , ApiContext } from '../apiTypes'
24
14
import type { ApiEndpointQuery } from './module'
25
15
import type { BaseQueryError } from '../baseQueryTypes'
26
16
@@ -120,6 +110,7 @@ export type MutationActionCreatorResult<
120
110
* A unique string generated for the request sequence
121
111
*/
122
112
requestId : string
113
+
123
114
/**
124
115
* A method to cancel the mutation promise. Note that this is not intended to prevent the mutation
125
116
* that was fired off from reaching the server, but only to assist in handling the response.
@@ -189,18 +180,58 @@ export function buildInitiate({
189
180
queryThunk,
190
181
mutationThunk,
191
182
api,
183
+ context,
192
184
} : {
193
185
serializeQueryArgs : InternalSerializeQueryArgs
194
186
queryThunk : QueryThunk
195
187
mutationThunk : MutationThunk
196
188
api : Api < any , EndpointDefinitions , any , any >
189
+ context : ApiContext < EndpointDefinitions >
197
190
} ) {
191
+ const runningQueries : Record <
192
+ string ,
193
+ QueryActionCreatorResult < any > | undefined
194
+ > = { }
195
+ const runningMutations : Record <
196
+ string ,
197
+ MutationActionCreatorResult < any > | undefined
198
+ > = { }
199
+
198
200
const {
199
201
unsubscribeQueryResult,
200
202
removeMutationResult,
201
203
updateSubscriptionOptions,
202
204
} = api . internalActions
203
- return { buildInitiateQuery, buildInitiateMutation }
205
+ return {
206
+ buildInitiateQuery,
207
+ buildInitiateMutation,
208
+ getRunningOperationPromises,
209
+ getRunningOperationPromise,
210
+ }
211
+
212
+ function getRunningOperationPromise (
213
+ endpointName : string ,
214
+ argOrRequestId : any
215
+ ) : any {
216
+ const endpointDefinition = context . endpointDefinitions [ endpointName ]
217
+ if ( endpointDefinition . type === DefinitionType . query ) {
218
+ const queryCacheKey = serializeQueryArgs ( {
219
+ queryArgs : argOrRequestId ,
220
+ endpointDefinition,
221
+ endpointName,
222
+ } )
223
+ return runningQueries [ queryCacheKey ]
224
+ } else {
225
+ return runningMutations [ argOrRequestId ]
226
+ }
227
+ }
228
+
229
+ function getRunningOperationPromises ( ) {
230
+ return [
231
+ ...Object . values ( runningQueries ) ,
232
+ ...Object . values ( runningMutations ) ,
233
+ ] . filter ( < T > ( t : T | undefined ) : t is T => ! ! t )
234
+ }
204
235
205
236
function middlewareWarning ( getState : ( ) => RootState < { } , string , string > ) {
206
237
if ( process . env . NODE_ENV !== 'production' ) {
@@ -242,8 +273,8 @@ Features like automatic cache collection, automatic refetching etc. will not be
242
273
const thunkResult = dispatch ( thunk )
243
274
middlewareWarning ( getState )
244
275
const { requestId, abort } = thunkResult
245
- const statePromise = Object . assign (
246
- thunkResult . then ( ( ) =>
276
+ const statePromise : QueryActionCreatorResult < any > = Object . assign (
277
+ Promise . all ( [ runningQueries [ queryCacheKey ] , thunkResult ] ) . then ( ( ) =>
247
278
( api . endpoints [ endpointName ] as ApiEndpointQuery < any , any > ) . select (
248
279
arg
249
280
) ( getState ( ) )
@@ -280,14 +311,21 @@ Features like automatic cache collection, automatic refetching etc. will not be
280
311
} ,
281
312
}
282
313
)
314
+
315
+ if ( ! runningQueries [ queryCacheKey ] ) {
316
+ runningQueries [ queryCacheKey ] = statePromise
317
+ statePromise . then ( ( ) => {
318
+ delete runningQueries [ queryCacheKey ]
319
+ } )
320
+ }
321
+
283
322
return statePromise
284
323
}
285
324
return queryAction
286
325
}
287
326
288
327
function buildInitiateMutation (
289
- endpointName : string ,
290
- definition : MutationDefinition < any , any , any , any >
328
+ endpointName : string
291
329
) : StartMutationActionCreator < any > {
292
330
return ( arg , { track = true , fixedCacheKey } = { } ) =>
293
331
( dispatch , getState ) => {
@@ -309,14 +347,28 @@ Features like automatic cache collection, automatic refetching etc. will not be
309
347
dispatch ( removeMutationResult ( { requestId, fixedCacheKey } ) )
310
348
}
311
349
312
- return Object . assign ( returnValuePromise , {
350
+ const ret = Object . assign ( returnValuePromise , {
313
351
arg : thunkResult . arg ,
314
352
requestId,
315
353
abort,
316
354
unwrap : thunkResult . unwrap ,
317
355
unsubscribe : reset ,
318
356
reset,
319
357
} )
358
+
359
+ runningMutations [ requestId ] = ret
360
+ ret . then ( ( ) => {
361
+ delete runningMutations [ requestId ]
362
+ } )
363
+ if ( fixedCacheKey ) {
364
+ runningMutations [ fixedCacheKey ] = ret
365
+ ret . then ( ( ) => {
366
+ if ( runningMutations [ fixedCacheKey ] === ret )
367
+ delete runningMutations [ fixedCacheKey ]
368
+ } )
369
+ }
370
+
371
+ return ret
320
372
}
321
373
}
322
374
}
0 commit comments