1 | /**
|
2 | * Note: this file should import all other files for type discovery and declaration merging
|
3 | */
|
4 | import type {
|
5 | PatchQueryDataThunk,
|
6 | UpdateQueryDataThunk,
|
7 | UpsertQueryDataThunk,
|
8 | } from './buildThunks'
|
9 | import { buildThunks } from './buildThunks'
|
10 | import type {
|
11 | ActionCreatorWithPayload,
|
12 | Middleware,
|
13 | Reducer,
|
14 | ThunkAction,
|
15 | ThunkDispatch,
|
16 | UnknownAction,
|
17 | } from '@reduxjs/toolkit'
|
18 | import type {
|
19 | EndpointDefinitions,
|
20 | QueryArgFrom,
|
21 | QueryDefinition,
|
22 | MutationDefinition,
|
23 | AssertTagTypes,
|
24 | TagDescription,
|
25 | } from '../endpointDefinitions'
|
26 | import { isQueryDefinition, isMutationDefinition } from '../endpointDefinitions'
|
27 | import type {
|
28 | CombinedState,
|
29 | QueryKeys,
|
30 | MutationKeys,
|
31 | RootState,
|
32 | } from './apiState'
|
33 | import type { Api, Module } from '../apiTypes'
|
34 | import { onFocus, onFocusLost, onOnline, onOffline } from './setupListeners'
|
35 | import { buildSlice } from './buildSlice'
|
36 | import { buildMiddleware } from './buildMiddleware'
|
37 | import { buildSelectors } from './buildSelectors'
|
38 | import type {
|
39 | MutationActionCreatorResult,
|
40 | QueryActionCreatorResult,
|
41 | } from './buildInitiate'
|
42 | import { buildInitiate } from './buildInitiate'
|
43 | import { assertCast, safeAssign } from '../tsHelpers'
|
44 | import type { InternalSerializeQueryArgs } from '../defaultSerializeQueryArgs'
|
45 | import type { SliceActions } from './buildSlice'
|
46 | import type { BaseQueryFn } from '../baseQueryTypes'
|
47 |
|
48 | import type { ReferenceCacheLifecycle } from './buildMiddleware/cacheLifecycle'
|
49 | import type { ReferenceQueryLifecycle } from './buildMiddleware/queryLifecycle'
|
50 | import type { ReferenceCacheCollection } from './buildMiddleware/cacheCollection'
|
51 | import { enablePatches } from 'immer'
|
52 | import { createSelector as _createSelector } from './rtkImports'
|
53 |
|
54 | /**
|
55 | * `ifOlderThan` - (default: `false` | `number`) - _number is value in seconds_
|
56 | * - If specified, it will only run the query if the difference between `new Date()` and the last `fulfilledTimeStamp` is greater than the given value
|
57 | *
|
58 | * @overloadSummary
|
59 | * `force`
|
60 | * - If `force: true`, it will ignore the `ifOlderThan` value if it is set and the query will be run even if it exists in the cache.
|
61 | */
|
62 | export type PrefetchOptions =
|
63 | | {
|
64 | ifOlderThan?: false | number
|
65 | }
|
66 | | { force?: boolean }
|
67 |
|
68 | export const coreModuleName = /* @__PURE__ */ Symbol()
|
69 | export type CoreModule =
|
70 | | typeof coreModuleName
|
71 | | ReferenceCacheLifecycle
|
72 | | ReferenceQueryLifecycle
|
73 | | ReferenceCacheCollection
|
74 |
|
75 | export interface ThunkWithReturnValue<T>
|
76 | extends ThunkAction<T, any, any, UnknownAction> {}
|
77 |
|
78 | declare module '../apiTypes' {
|
79 | export interface ApiModules<
|
80 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
|
81 | BaseQuery extends BaseQueryFn,
|
82 | Definitions extends EndpointDefinitions,
|
83 | ReducerPath extends string,
|
84 | TagTypes extends string,
|
85 | > {
|
86 | [coreModuleName]: {
|
87 | /**
|
88 | * This api's reducer should be mounted at `store[api.reducerPath]`.
|
89 | *
|
90 | * @example
|
91 | * ```ts
|
92 | * configureStore({
|
93 | * reducer: {
|
94 | * [api.reducerPath]: api.reducer,
|
95 | * },
|
96 | * middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(api.middleware),
|
97 | * })
|
98 | * ```
|
99 | */
|
100 | reducerPath: ReducerPath
|
101 | /**
|
102 | * Internal actions not part of the public API. Note: These are subject to change at any given time.
|
103 | */
|
104 | internalActions: InternalActions
|
105 | /**
|
106 | * A standard redux reducer that enables core functionality. Make sure it's included in your store.
|
107 | *
|
108 | * @example
|
109 | * ```ts
|
110 | * configureStore({
|
111 | * reducer: {
|
112 | * [api.reducerPath]: api.reducer,
|
113 | * },
|
114 | * middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(api.middleware),
|
115 | * })
|
116 | * ```
|
117 | */
|
118 | reducer: Reducer<
|
119 | CombinedState<Definitions, TagTypes, ReducerPath>,
|
120 | UnknownAction
|
121 | >
|
122 | /**
|
123 | * This is a standard redux middleware and is responsible for things like polling, garbage collection and a handful of other things. Make sure it's included in your store.
|
124 | *
|
125 | * @example
|
126 | * ```ts
|
127 | * configureStore({
|
128 | * reducer: {
|
129 | * [api.reducerPath]: api.reducer,
|
130 | * },
|
131 | * middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(api.middleware),
|
132 | * })
|
133 | * ```
|
134 | */
|
135 | middleware: Middleware<
|
136 | {},
|
137 | RootState<Definitions, string, ReducerPath>,
|
138 | ThunkDispatch<any, any, UnknownAction>
|
139 | >
|
140 | /**
|
141 | * A collection of utility thunks for various situations.
|
142 | */
|
143 | util: {
|
144 | /**
|
145 | * A thunk that (if dispatched) will return a specific running query, identified
|
146 | * by `endpointName` and `args`.
|
147 | * If that query is not running, dispatching the thunk will result in `undefined`.
|
148 | *
|
149 | * Can be used to await a specific query triggered in any way,
|
150 | * including via hook calls or manually dispatching `initiate` actions.
|
151 | *
|
152 | * See https://redux-toolkit.js.org/rtk-query/usage/server-side-rendering for details.
|
153 | */
|
154 | getRunningQueryThunk<EndpointName extends QueryKeys<Definitions>>(
|
155 | endpointName: EndpointName,
|
156 | args: QueryArgFrom<Definitions[EndpointName]>,
|
157 | ): ThunkWithReturnValue<
|
158 | | QueryActionCreatorResult<
|
159 | Definitions[EndpointName] & { type: 'query' }
|
160 | >
|
161 | | undefined
|
162 | >
|
163 |
|
164 | /**
|
165 | * A thunk that (if dispatched) will return a specific running mutation, identified
|
166 | * by `endpointName` and `fixedCacheKey` or `requestId`.
|
167 | * If that mutation is not running, dispatching the thunk will result in `undefined`.
|
168 | *
|
169 | * Can be used to await a specific mutation triggered in any way,
|
170 | * including via hook trigger functions or manually dispatching `initiate` actions.
|
171 | *
|
172 | * See https://redux-toolkit.js.org/rtk-query/usage/server-side-rendering for details.
|
173 | */
|
174 | getRunningMutationThunk<EndpointName extends MutationKeys<Definitions>>(
|
175 | endpointName: EndpointName,
|
176 | fixedCacheKeyOrRequestId: string,
|
177 | ): ThunkWithReturnValue<
|
178 | | MutationActionCreatorResult<
|
179 | Definitions[EndpointName] & { type: 'mutation' }
|
180 | >
|
181 | | undefined
|
182 | >
|
183 |
|
184 | /**
|
185 | * A thunk that (if dispatched) will return all running queries.
|
186 | *
|
187 | * Useful for SSR scenarios to await all running queries triggered in any way,
|
188 | * including via hook calls or manually dispatching `initiate` actions.
|
189 | *
|
190 | * See https://redux-toolkit.js.org/rtk-query/usage/server-side-rendering for details.
|
191 | */
|
192 | getRunningQueriesThunk(): ThunkWithReturnValue<
|
193 | Array<QueryActionCreatorResult<any>>
|
194 | >
|
195 |
|
196 | /**
|
197 | * A thunk that (if dispatched) will return all running mutations.
|
198 | *
|
199 | * Useful for SSR scenarios to await all running mutations triggered in any way,
|
200 | * including via hook calls or manually dispatching `initiate` actions.
|
201 | *
|
202 | * See https://redux-toolkit.js.org/rtk-query/usage/server-side-rendering for details.
|
203 | */
|
204 | getRunningMutationsThunk(): ThunkWithReturnValue<
|
205 | Array<MutationActionCreatorResult<any>>
|
206 | >
|
207 |
|
208 | /**
|
209 | * A Redux thunk that can be used to manually trigger pre-fetching of data.
|
210 | *
|
211 | * The thunk accepts three arguments: the name of the endpoint we are updating (such as `'getPost'`), the appropriate query arg values to construct the desired cache key, and a set of options used to determine if the data actually should be re-fetched based on cache staleness.
|
212 | *
|
213 | * React Hooks users will most likely never need to use this directly, as the `usePrefetch` hook will dispatch this thunk internally as needed when you call the prefetching function supplied by the hook.
|
214 | *
|
215 | * @example
|
216 | *
|
217 | * ```ts no-transpile
|
218 | * dispatch(api.util.prefetch('getPosts', undefined, { force: true }))
|
219 | * ```
|
220 | */
|
221 | prefetch<EndpointName extends QueryKeys<Definitions>>(
|
222 | endpointName: EndpointName,
|
223 | arg: QueryArgFrom<Definitions[EndpointName]>,
|
224 | options: PrefetchOptions,
|
225 | ): ThunkAction<void, any, any, UnknownAction>
|
226 | /**
|
227 | * A Redux thunk action creator that, when dispatched, creates and applies a set of JSON diff/patch objects to the current state. This immediately updates the Redux state with those changes.
|
228 | *
|
229 | * The thunk action creator accepts three arguments: the name of the endpoint we are updating (such as `'getPost'`), the appropriate query arg values to construct the desired cache key, and an `updateRecipe` callback function. The callback receives an Immer-wrapped `draft` of the current state, and may modify the draft to match the expected results after the mutation completes successfully.
|
230 | *
|
231 | * The thunk executes _synchronously_, and returns an object containing `{patches: Patch[], inversePatches: Patch[], undo: () => void}`. The `patches` and `inversePatches` are generated using Immer's [`produceWithPatches` method](https://immerjs.github.io/immer/patches).
|
232 | *
|
233 | * This is typically used as the first step in implementing optimistic updates. The generated `inversePatches` can be used to revert the updates by calling `dispatch(patchQueryData(endpointName, args, inversePatches))`. Alternatively, the `undo` method can be called directly to achieve the same effect.
|
234 | *
|
235 | * Note that the first two arguments (`endpointName` and `args`) are used to determine which existing cache entry to update. If no existing cache entry is found, the `updateRecipe` callback will not run.
|
236 | *
|
237 | * @example
|
238 | *
|
239 | * ```ts
|
240 | * const patchCollection = dispatch(
|
241 | * api.util.updateQueryData('getPosts', undefined, (draftPosts) => {
|
242 | * draftPosts.push({ id: 1, name: 'Teddy' })
|
243 | * })
|
244 | * )
|
245 | * ```
|
246 | */
|
247 | updateQueryData: UpdateQueryDataThunk<
|
248 | Definitions,
|
249 | RootState<Definitions, string, ReducerPath>
|
250 | >
|
251 |
|
252 | /**
|
253 | * A Redux thunk action creator that, when dispatched, acts as an artificial API request to upsert a value into the cache.
|
254 | *
|
255 | * The thunk action creator accepts three arguments: the name of the endpoint we are updating (such as `'getPost'`), the appropriate query arg values to construct the desired cache key, and the data to upsert.
|
256 | *
|
257 | * If no cache entry for that cache key exists, a cache entry will be created and the data added. If a cache entry already exists, this will _overwrite_ the existing cache entry data.
|
258 | *
|
259 | * The thunk executes _asynchronously_, and returns a promise that resolves when the store has been updated.
|
260 | *
|
261 | * If dispatched while an actual request is in progress, both the upsert and request will be handled as soon as they resolve, resulting in a "last result wins" update behavior.
|
262 | *
|
263 | * @example
|
264 | *
|
265 | * ```ts
|
266 | * await dispatch(
|
267 | * api.util.upsertQueryData('getPost', {id: 1}, {id: 1, text: "Hello!"})
|
268 | * )
|
269 | * ```
|
270 | */
|
271 | upsertQueryData: UpsertQueryDataThunk<
|
272 | Definitions,
|
273 | RootState<Definitions, string, ReducerPath>
|
274 | >
|
275 | /**
|
276 | * A Redux thunk that applies a JSON diff/patch array to the cached data for a given query result. This immediately updates the Redux state with those changes.
|
277 | *
|
278 | * The thunk accepts three arguments: the name of the endpoint we are updating (such as `'getPost'`), the appropriate query arg values to construct the desired cache key, and a JSON diff/patch array as produced by Immer's `produceWithPatches`.
|
279 | *
|
280 | * This is typically used as the second step in implementing optimistic updates. If a request fails, the optimistically-applied changes can be reverted by dispatching `patchQueryData` with the `inversePatches` that were generated by `updateQueryData` earlier.
|
281 | *
|
282 | * In cases where it is desired to simply revert the previous changes, it may be preferable to call the `undo` method returned from dispatching `updateQueryData` instead.
|
283 | *
|
284 | * @example
|
285 | * ```ts
|
286 | * const patchCollection = dispatch(
|
287 | * api.util.updateQueryData('getPosts', undefined, (draftPosts) => {
|
288 | * draftPosts.push({ id: 1, name: 'Teddy' })
|
289 | * })
|
290 | * )
|
291 | *
|
292 | * // later
|
293 | * dispatch(
|
294 | * api.util.patchQueryData('getPosts', undefined, patchCollection.inversePatches)
|
295 | * )
|
296 | *
|
297 | * // or
|
298 | * patchCollection.undo()
|
299 | * ```
|
300 | */
|
301 | patchQueryData: PatchQueryDataThunk<
|
302 | Definitions,
|
303 | RootState<Definitions, string, ReducerPath>
|
304 | >
|
305 |
|
306 | /**
|
307 | * A Redux action creator that can be dispatched to manually reset the api state completely. This will immediately remove all existing cache entries, and all queries will be considered 'uninitialized'.
|
308 | *
|
309 | * @example
|
310 | *
|
311 | * ```ts
|
312 | * dispatch(api.util.resetApiState())
|
313 | * ```
|
314 | */
|
315 | resetApiState: SliceActions['resetApiState']
|
316 | /**
|
317 | * A Redux action creator that can be used to manually invalidate cache tags for [automated re-fetching](../../usage/automated-refetching.mdx).
|
318 | *
|
319 | * The action creator accepts one argument: the cache tags to be invalidated. It returns an action with those tags as a payload, and the corresponding `invalidateTags` action type for the api.
|
320 | *
|
321 | * Dispatching the result of this action creator will [invalidate](../../usage/automated-refetching.mdx#invalidating-cache-data) the given tags, causing queries to automatically re-fetch if they are subscribed to cache data that [provides](../../usage/automated-refetching.mdx#providing-cache-data) the corresponding tags.
|
322 | *
|
323 | * The array of tags provided to the action creator should be in one of the following formats, where `TagType` is equal to a string provided to the [`tagTypes`](../createApi.mdx#tagtypes) property of the api:
|
324 | *
|
325 | * - `[TagType]`
|
326 | * - `[{ type: TagType }]`
|
327 | * - `[{ type: TagType, id: number | string }]`
|
328 | *
|
329 | * @example
|
330 | *
|
331 | * ```ts
|
332 | * dispatch(api.util.invalidateTags(['Post']))
|
333 | * dispatch(api.util.invalidateTags([{ type: 'Post', id: 1 }]))
|
334 | * dispatch(
|
335 | * api.util.invalidateTags([
|
336 | * { type: 'Post', id: 1 },
|
337 | * { type: 'Post', id: 'LIST' },
|
338 | * ])
|
339 | * )
|
340 | * ```
|
341 | */
|
342 | invalidateTags: ActionCreatorWithPayload<
|
343 | Array<TagDescription<TagTypes>>,
|
344 | string
|
345 | >
|
346 |
|
347 | /**
|
348 | * A function to select all `{ endpointName, originalArgs, queryCacheKey }` combinations that would be invalidated by a specific set of tags.
|
349 | *
|
350 | * Can be used for mutations that want to do optimistic updates instead of invalidating a set of tags, but don't know exactly what they need to update.
|
351 | */
|
352 | selectInvalidatedBy: (
|
353 | state: RootState<Definitions, string, ReducerPath>,
|
354 | tags: ReadonlyArray<TagDescription<TagTypes>>,
|
355 | ) => Array<{
|
356 | endpointName: string
|
357 | originalArgs: any
|
358 | queryCacheKey: string
|
359 | }>
|
360 |
|
361 | /**
|
362 | * A function to select all arguments currently cached for a given endpoint.
|
363 | *
|
364 | * Can be used for mutations that want to do optimistic updates instead of invalidating a set of tags, but don't know exactly what they need to update.
|
365 | */
|
366 | selectCachedArgsForQuery: <QueryName extends QueryKeys<Definitions>>(
|
367 | state: RootState<Definitions, string, ReducerPath>,
|
368 | queryName: QueryName,
|
369 | ) => Array<QueryArgFrom<Definitions[QueryName]>>
|
370 | }
|
371 | /**
|
372 | * Endpoints based on the input endpoints provided to `createApi`, containing `select` and `action matchers`.
|
373 | */
|
374 | endpoints: {
|
375 | [K in keyof Definitions]: Definitions[K] extends QueryDefinition<
|
376 | any,
|
377 | any,
|
378 | any,
|
379 | any,
|
380 | any
|
381 | >
|
382 | ? ApiEndpointQuery<Definitions[K], Definitions>
|
383 | : Definitions[K] extends MutationDefinition<any, any, any, any, any>
|
384 | ? ApiEndpointMutation<Definitions[K], Definitions>
|
385 | : never
|
386 | }
|
387 | }
|
388 | }
|
389 | }
|
390 |
|
391 | export interface ApiEndpointQuery<
|
392 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
|
393 | Definition extends QueryDefinition<any, any, any, any, any>,
|
394 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
|
395 | Definitions extends EndpointDefinitions,
|
396 | > {
|
397 | name: string
|
398 | /**
|
399 | * All of these are `undefined` at runtime, purely to be used in TypeScript declarations!
|
400 | */
|
401 | Types: NonNullable<Definition['Types']>
|
402 | }
|
403 |
|
404 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
|
405 | export interface ApiEndpointMutation<
|
406 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
|
407 | Definition extends MutationDefinition<any, any, any, any, any>,
|
408 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
|
409 | Definitions extends EndpointDefinitions,
|
410 | > {
|
411 | name: string
|
412 | /**
|
413 | * All of these are `undefined` at runtime, purely to be used in TypeScript declarations!
|
414 | */
|
415 | Types: NonNullable<Definition['Types']>
|
416 | }
|
417 |
|
418 | export type ListenerActions = {
|
419 | /**
|
420 | * Will cause the RTK Query middleware to trigger any refetchOnReconnect-related behavior
|
421 | * @link https://rtk-query-docs.netlify.app/api/setupListeners
|
422 | */
|
423 | onOnline: typeof onOnline
|
424 | onOffline: typeof onOffline
|
425 | /**
|
426 | * Will cause the RTK Query middleware to trigger any refetchOnFocus-related behavior
|
427 | * @link https://rtk-query-docs.netlify.app/api/setupListeners
|
428 | */
|
429 | onFocus: typeof onFocus
|
430 | onFocusLost: typeof onFocusLost
|
431 | }
|
432 |
|
433 | export type InternalActions = SliceActions & ListenerActions
|
434 |
|
435 | export interface CoreModuleOptions {
|
436 | /**
|
437 | * A selector creator (usually from `reselect`, or matching the same signature)
|
438 | */
|
439 | createSelector?: typeof _createSelector
|
440 | }
|
441 |
|
442 | /**
|
443 | * Creates a module containing the basic redux logic for use with `buildCreateApi`.
|
444 | *
|
445 | * @example
|
446 | * ```ts
|
447 | * const createBaseApi = buildCreateApi(coreModule());
|
448 | * ```
|
449 | */
|
450 | export const coreModule = ({
|
451 | createSelector = _createSelector,
|
452 | }: CoreModuleOptions = {}): Module<CoreModule> => ({
|
453 | name: coreModuleName,
|
454 | init(
|
455 | api,
|
456 | {
|
457 | baseQuery,
|
458 | tagTypes,
|
459 | reducerPath,
|
460 | serializeQueryArgs,
|
461 | keepUnusedDataFor,
|
462 | refetchOnMountOrArgChange,
|
463 | refetchOnFocus,
|
464 | refetchOnReconnect,
|
465 | invalidationBehavior,
|
466 | },
|
467 | context,
|
468 | ) {
|
469 | enablePatches()
|
470 |
|
471 | assertCast<InternalSerializeQueryArgs>(serializeQueryArgs)
|
472 |
|
473 | const assertTagType: AssertTagTypes = (tag) => {
|
474 | if (
|
475 | typeof process !== 'undefined' &&
|
476 | process.env.NODE_ENV === 'development'
|
477 | ) {
|
478 | if (!tagTypes.includes(tag.type as any)) {
|
479 | console.error(
|
480 | `Tag type '${tag.type}' was used, but not specified in \`tagTypes\`!`,
|
481 | )
|
482 | }
|
483 | }
|
484 | return tag
|
485 | }
|
486 |
|
487 | Object.assign(api, {
|
488 | reducerPath,
|
489 | endpoints: {},
|
490 | internalActions: {
|
491 | onOnline,
|
492 | onOffline,
|
493 | onFocus,
|
494 | onFocusLost,
|
495 | },
|
496 | util: {},
|
497 | })
|
498 |
|
499 | const {
|
500 | queryThunk,
|
501 | mutationThunk,
|
502 | patchQueryData,
|
503 | updateQueryData,
|
504 | upsertQueryData,
|
505 | prefetch,
|
506 | buildMatchThunkActions,
|
507 | } = buildThunks({
|
508 | baseQuery,
|
509 | reducerPath,
|
510 | context,
|
511 | api,
|
512 | serializeQueryArgs,
|
513 | assertTagType,
|
514 | })
|
515 |
|
516 | const { reducer, actions: sliceActions } = buildSlice({
|
517 | context,
|
518 | queryThunk,
|
519 | mutationThunk,
|
520 | reducerPath,
|
521 | assertTagType,
|
522 | config: {
|
523 | refetchOnFocus,
|
524 | refetchOnReconnect,
|
525 | refetchOnMountOrArgChange,
|
526 | keepUnusedDataFor,
|
527 | reducerPath,
|
528 | invalidationBehavior,
|
529 | },
|
530 | })
|
531 |
|
532 | safeAssign(api.util, {
|
533 | patchQueryData,
|
534 | updateQueryData,
|
535 | upsertQueryData,
|
536 | prefetch,
|
537 | resetApiState: sliceActions.resetApiState,
|
538 | })
|
539 | safeAssign(api.internalActions, sliceActions)
|
540 |
|
541 | const { middleware, actions: middlewareActions } = buildMiddleware({
|
542 | reducerPath,
|
543 | context,
|
544 | queryThunk,
|
545 | mutationThunk,
|
546 | api,
|
547 | assertTagType,
|
548 | })
|
549 | safeAssign(api.util, middlewareActions)
|
550 |
|
551 | safeAssign(api, { reducer: reducer as any, middleware })
|
552 |
|
553 | const {
|
554 | buildQuerySelector,
|
555 | buildMutationSelector,
|
556 | selectInvalidatedBy,
|
557 | selectCachedArgsForQuery,
|
558 | } = buildSelectors({
|
559 | serializeQueryArgs: serializeQueryArgs as any,
|
560 | reducerPath,
|
561 | createSelector,
|
562 | })
|
563 |
|
564 | safeAssign(api.util, { selectInvalidatedBy, selectCachedArgsForQuery })
|
565 |
|
566 | const {
|
567 | buildInitiateQuery,
|
568 | buildInitiateMutation,
|
569 | getRunningMutationThunk,
|
570 | getRunningMutationsThunk,
|
571 | getRunningQueriesThunk,
|
572 | getRunningQueryThunk,
|
573 | } = buildInitiate({
|
574 | queryThunk,
|
575 | mutationThunk,
|
576 | api,
|
577 | serializeQueryArgs: serializeQueryArgs as any,
|
578 | context,
|
579 | })
|
580 |
|
581 | safeAssign(api.util, {
|
582 | getRunningMutationThunk,
|
583 | getRunningMutationsThunk,
|
584 | getRunningQueryThunk,
|
585 | getRunningQueriesThunk,
|
586 | })
|
587 |
|
588 | return {
|
589 | name: coreModuleName,
|
590 | injectEndpoint(endpointName, definition) {
|
591 | const anyApi = api as any as Api<
|
592 | any,
|
593 | Record<string, any>,
|
594 | string,
|
595 | string,
|
596 | CoreModule
|
597 | >
|
598 | anyApi.endpoints[endpointName] ??= {} as any
|
599 | if (isQueryDefinition(definition)) {
|
600 | safeAssign(
|
601 | anyApi.endpoints[endpointName],
|
602 | {
|
603 | name: endpointName,
|
604 | select: buildQuerySelector(endpointName, definition),
|
605 | initiate: buildInitiateQuery(endpointName, definition),
|
606 | },
|
607 | buildMatchThunkActions(queryThunk, endpointName),
|
608 | )
|
609 | } else if (isMutationDefinition(definition)) {
|
610 | safeAssign(
|
611 | anyApi.endpoints[endpointName],
|
612 | {
|
613 | name: endpointName,
|
614 | select: buildMutationSelector(),
|
615 | initiate: buildInitiateMutation(endpointName),
|
616 | },
|
617 | buildMatchThunkActions(mutationThunk, endpointName),
|
618 | )
|
619 | }
|
620 | },
|
621 | }
|
622 | },
|
623 | })
|