source: node_modules/@reduxjs/toolkit/src/query/core/apiState.ts

Last change on this file was a762898, checked in by istevanoska <ilinastevanoska@…>, 5 months ago

Added visualizations

  • Property mode set to 100644
File size: 10.8 KB
Line 
1import type { SerializedError } from '@reduxjs/toolkit'
2import type { BaseQueryError } from '../baseQueryTypes'
3import type {
4 BaseEndpointDefinition,
5 EndpointDefinitions,
6 FullTagDescription,
7 InfiniteQueryDefinition,
8 MutationDefinition,
9 PageParamFrom,
10 QueryArgFromAnyQuery,
11 QueryDefinition,
12 ResultTypeFrom,
13} from '../endpointDefinitions'
14import type { Id, WithRequiredProp } from '../tsHelpers'
15
16export type QueryCacheKey = string & { _type: 'queryCacheKey' }
17export type QuerySubstateIdentifier = { queryCacheKey: QueryCacheKey }
18export type MutationSubstateIdentifier =
19 | { requestId: string; fixedCacheKey?: string }
20 | { requestId?: string; fixedCacheKey: string }
21
22export type RefetchConfigOptions = {
23 refetchOnMountOrArgChange: boolean | number
24 refetchOnReconnect: boolean
25 refetchOnFocus: boolean
26}
27
28export type InfiniteQueryConfigOptions<DataType, PageParam, QueryArg> = {
29 /**
30 * The initial page parameter to use for the first page fetch.
31 */
32 initialPageParam: PageParam
33 /**
34 * This function is required to automatically get the next cursor for infinite queries.
35 * The result will also be used to determine the value of `hasNextPage`.
36 */
37 getNextPageParam: (
38 lastPage: DataType,
39 allPages: Array<DataType>,
40 lastPageParam: PageParam,
41 allPageParams: Array<PageParam>,
42 queryArg: QueryArg,
43 ) => PageParam | undefined | null
44 /**
45 * This function can be set to automatically get the previous cursor for infinite queries.
46 * The result will also be used to determine the value of `hasPreviousPage`.
47 */
48 getPreviousPageParam?: (
49 firstPage: DataType,
50 allPages: Array<DataType>,
51 firstPageParam: PageParam,
52 allPageParams: Array<PageParam>,
53 queryArg: QueryArg,
54 ) => PageParam | undefined | null
55 /**
56 * If specified, only keep this many pages in cache at once.
57 * If additional pages are fetched, older pages in the other
58 * direction will be dropped from the cache.
59 */
60 maxPages?: number
61 /**
62 * Defaults to `true`. When this is `true` and an infinite query endpoint is refetched
63 * (due to tag invalidation, polling, arg change configuration, or manual refetching),
64 * RTK Query will try to sequentially refetch all pages currently in the cache.
65 * When `false` only the first page will be refetched.
66 */
67 refetchCachedPages?: boolean
68}
69
70export type InfiniteData<DataType, PageParam> = {
71 pages: Array<DataType>
72 pageParams: Array<PageParam>
73}
74
75// NOTE: DO NOT import and use this for runtime comparisons internally,
76// except in the RTKQ React package. Use the string versions just below this.
77// ESBuild auto-inlines TS enums, which bloats our bundle with many repeated
78// constants like "initialized":
79// https://github.com/evanw/esbuild/releases/tag/v0.14.7
80// We still have to use this in the React package since we don't publicly export
81// the string constants below.
82/**
83 * Strings describing the query state at any given time.
84 */
85export enum QueryStatus {
86 uninitialized = 'uninitialized',
87 pending = 'pending',
88 fulfilled = 'fulfilled',
89 rejected = 'rejected',
90}
91
92// Use these string constants for runtime comparisons internally
93export const STATUS_UNINITIALIZED = QueryStatus.uninitialized
94export const STATUS_PENDING = QueryStatus.pending
95export const STATUS_FULFILLED = QueryStatus.fulfilled
96export const STATUS_REJECTED = QueryStatus.rejected
97
98export type RequestStatusFlags =
99 | {
100 status: QueryStatus.uninitialized
101 isUninitialized: true
102 isLoading: false
103 isSuccess: false
104 isError: false
105 }
106 | {
107 status: QueryStatus.pending
108 isUninitialized: false
109 isLoading: true
110 isSuccess: false
111 isError: false
112 }
113 | {
114 status: QueryStatus.fulfilled
115 isUninitialized: false
116 isLoading: false
117 isSuccess: true
118 isError: false
119 }
120 | {
121 status: QueryStatus.rejected
122 isUninitialized: false
123 isLoading: false
124 isSuccess: false
125 isError: true
126 }
127
128export function getRequestStatusFlags(status: QueryStatus): RequestStatusFlags {
129 return {
130 status,
131 isUninitialized: status === STATUS_UNINITIALIZED,
132 isLoading: status === STATUS_PENDING,
133 isSuccess: status === STATUS_FULFILLED,
134 isError: status === STATUS_REJECTED,
135 } as any
136}
137
138/**
139 * @public
140 */
141export type SubscriptionOptions = {
142 /**
143 * How frequently to automatically re-fetch data (in milliseconds). Defaults to `0` (off).
144 */
145 pollingInterval?: number
146 /**
147 * Defaults to 'false'. This setting allows you to control whether RTK Query will continue polling if the window is not focused.
148 *
149 * If pollingInterval is not set or set to 0, this **will not be evaluated** until pollingInterval is greater than 0.
150 *
151 * Note: requires [`setupListeners`](./setupListeners) to have been called.
152 */
153 skipPollingIfUnfocused?: boolean
154 /**
155 * Defaults to `false`. This setting allows you to control whether RTK Query will try to refetch all subscribed queries after regaining a network connection.
156 *
157 * If you specify this option alongside `skip: true`, this **will not be evaluated** until `skip` is false.
158 *
159 * Note: requires [`setupListeners`](./setupListeners) to have been called.
160 */
161 refetchOnReconnect?: boolean
162 /**
163 * Defaults to `false`. This setting allows you to control whether RTK Query will try to refetch all subscribed queries after the application window regains focus.
164 *
165 * If you specify this option alongside `skip: true`, this **will not be evaluated** until `skip` is false.
166 *
167 * Note: requires [`setupListeners`](./setupListeners) to have been called.
168 */
169 refetchOnFocus?: boolean
170}
171export type SubscribersInternal = Map<string, SubscriptionOptions>
172export type Subscribers = { [requestId: string]: SubscriptionOptions }
173export type QueryKeys<Definitions extends EndpointDefinitions> = {
174 [K in keyof Definitions]: Definitions[K] extends QueryDefinition<
175 any,
176 any,
177 any,
178 any
179 >
180 ? K
181 : never
182}[keyof Definitions]
183
184export type InfiniteQueryKeys<Definitions extends EndpointDefinitions> = {
185 [K in keyof Definitions]: Definitions[K] extends InfiniteQueryDefinition<
186 any,
187 any,
188 any,
189 any,
190 any
191 >
192 ? K
193 : never
194}[keyof Definitions]
195
196export type MutationKeys<Definitions extends EndpointDefinitions> = {
197 [K in keyof Definitions]: Definitions[K] extends MutationDefinition<
198 any,
199 any,
200 any,
201 any
202 >
203 ? K
204 : never
205}[keyof Definitions]
206
207type BaseQuerySubState<
208 D extends BaseEndpointDefinition<any, any, any, any>,
209 DataType = ResultTypeFrom<D>,
210> = {
211 /**
212 * The argument originally passed into the hook or `initiate` action call
213 */
214 originalArgs: QueryArgFromAnyQuery<D>
215 /**
216 * A unique ID associated with the request
217 */
218 requestId: string
219 /**
220 * The received data from the query
221 */
222 data?: DataType
223 /**
224 * The received error if applicable
225 */
226 error?:
227 | SerializedError
228 | (D extends QueryDefinition<any, infer BaseQuery, any, any>
229 ? BaseQueryError<BaseQuery>
230 : never)
231 /**
232 * The name of the endpoint associated with the query
233 */
234 endpointName: string
235 /**
236 * Time that the latest query started
237 */
238 startedTimeStamp: number
239 /**
240 * Time that the latest query was fulfilled
241 */
242 fulfilledTimeStamp?: number
243}
244
245export type QuerySubState<
246 D extends BaseEndpointDefinition<any, any, any, any>,
247 DataType = ResultTypeFrom<D>,
248> = Id<
249 | ({ status: QueryStatus.fulfilled } & WithRequiredProp<
250 BaseQuerySubState<D, DataType>,
251 'data' | 'fulfilledTimeStamp'
252 > & { error: undefined })
253 | ({ status: QueryStatus.pending } & BaseQuerySubState<D, DataType>)
254 | ({ status: QueryStatus.rejected } & WithRequiredProp<
255 BaseQuerySubState<D, DataType>,
256 'error'
257 >)
258 | {
259 status: QueryStatus.uninitialized
260 originalArgs?: undefined
261 data?: undefined
262 error?: undefined
263 requestId?: undefined
264 endpointName?: string
265 startedTimeStamp?: undefined
266 fulfilledTimeStamp?: undefined
267 }
268>
269
270export type InfiniteQueryDirection = 'forward' | 'backward'
271
272export type InfiniteQuerySubState<
273 D extends BaseEndpointDefinition<any, any, any, any>,
274> =
275 D extends InfiniteQueryDefinition<any, any, any, any, any>
276 ? QuerySubState<D, InfiniteData<ResultTypeFrom<D>, PageParamFrom<D>>> & {
277 direction?: InfiniteQueryDirection
278 }
279 : never
280
281type BaseMutationSubState<
282 D extends BaseEndpointDefinition<any, any, any, any>,
283> = {
284 requestId: string
285 data?: ResultTypeFrom<D>
286 error?:
287 | SerializedError
288 | (D extends MutationDefinition<any, infer BaseQuery, any, any>
289 ? BaseQueryError<BaseQuery>
290 : never)
291 endpointName: string
292 startedTimeStamp: number
293 fulfilledTimeStamp?: number
294}
295
296export type MutationSubState<
297 D extends BaseEndpointDefinition<any, any, any, any>,
298> =
299 | (({
300 status: QueryStatus.fulfilled
301 } & WithRequiredProp<
302 BaseMutationSubState<D>,
303 'data' | 'fulfilledTimeStamp'
304 >) & { error: undefined })
305 | (({ status: QueryStatus.pending } & BaseMutationSubState<D>) & {
306 data?: undefined
307 })
308 | ({ status: QueryStatus.rejected } & WithRequiredProp<
309 BaseMutationSubState<D>,
310 'error'
311 >)
312 | {
313 requestId?: undefined
314 status: QueryStatus.uninitialized
315 data?: undefined
316 error?: undefined
317 endpointName?: string
318 startedTimeStamp?: undefined
319 fulfilledTimeStamp?: undefined
320 }
321
322export type CombinedState<
323 D extends EndpointDefinitions,
324 E extends string,
325 ReducerPath extends string,
326> = {
327 queries: QueryState<D>
328 mutations: MutationState<D>
329 provided: InvalidationState<E>
330 subscriptions: SubscriptionState
331 config: ConfigState<ReducerPath>
332}
333
334export type InvalidationState<TagTypes extends string> = {
335 tags: {
336 [_ in TagTypes]: {
337 [id: string]: Array<QueryCacheKey>
338 [id: number]: Array<QueryCacheKey>
339 }
340 }
341 keys: Record<QueryCacheKey, Array<FullTagDescription<any>>>
342}
343
344export type QueryState<D extends EndpointDefinitions> = {
345 [queryCacheKey: string]:
346 | QuerySubState<D[string]>
347 | InfiniteQuerySubState<D[string]>
348 | undefined
349}
350
351export type SubscriptionInternalState = Map<string, SubscribersInternal>
352
353export type SubscriptionState = {
354 [queryCacheKey: string]: Subscribers | undefined
355}
356
357export type ConfigState<ReducerPath> = RefetchConfigOptions & {
358 reducerPath: ReducerPath
359 online: boolean
360 focused: boolean
361 middlewareRegistered: boolean | 'conflict'
362} & ModifiableConfigState
363
364export type ModifiableConfigState = {
365 keepUnusedDataFor: number
366 invalidationBehavior: 'delayed' | 'immediately'
367} & RefetchConfigOptions
368
369export type MutationState<D extends EndpointDefinitions> = {
370 [requestId: string]: MutationSubState<D[string]> | undefined
371}
372
373export type RootState<
374 Definitions extends EndpointDefinitions,
375 TagTypes extends string,
376 ReducerPath extends string,
377> = { [P in ReducerPath]: CombinedState<Definitions, TagTypes, P> }
Note: See TracBrowser for help on using the repository browser.