Skip to content

Commit

Permalink
Merge pull request #4393 from riqts/infQuery-API
Browse files Browse the repository at this point in the history
[API Concept] - Infinite Query API
  • Loading branch information
markerikson authored Nov 29, 2024
2 parents e848a55 + 4ee0f7f commit 1e5789f
Show file tree
Hide file tree
Showing 21 changed files with 2,566 additions and 108 deletions.
1 change: 1 addition & 0 deletions packages/toolkit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"@size-limit/webpack": "^11.0.1",
"@testing-library/dom": "^10.4.0",
"@testing-library/react": "^16.0.1",
"@testing-library/react-render-stream": "^1.0.3",
"@testing-library/user-event": "^14.5.2",
"@types/babel__core": "^7.20.5",
"@types/babel__helper-module-imports": "^7.18.3",
Expand Down
84 changes: 73 additions & 11 deletions packages/toolkit/src/query/core/apiState.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import type { SerializedError } from '@reduxjs/toolkit'
import type { BaseQueryError } from '../baseQueryTypes'
import type {
QueryDefinition,
MutationDefinition,
EndpointDefinitions,
BaseEndpointDefinition,
ResultTypeFrom,
EndpointDefinitions,
InfiniteQueryDefinition,
MutationDefinition,
PageParamFrom,
QueryArgFrom,
QueryDefinition,
ResultTypeFrom,
} from '../endpointDefinitions'
import type { Id, WithRequiredProp } from '../tsHelpers'

Expand All @@ -28,6 +30,35 @@ export type RefetchConfigOptions = {
refetchOnFocus: boolean
}

export type GetNextPageParamFunction<TPageParam, TQueryFnData> = (
lastPage: TQueryFnData,
allPages: Array<TQueryFnData>,
lastPageParam: TPageParam,
allPageParams: Array<TPageParam>,
) => TPageParam | undefined | null

export type GetPreviousPageParamFunction<TPageParam, TQueryFnData> = (
firstPage: TQueryFnData,
allPages: Array<TQueryFnData>,
firstPageParam: TPageParam,
allPageParams: Array<TPageParam>,
) => TPageParam | undefined | null

export type InfiniteQueryConfigOptions<TQueryFnData, TPageParam> = {
initialPageParam: TPageParam
/**
* This function can be set to automatically get the previous cursor for infinite queries.
* The result will also be used to determine the value of `hasPreviousPage`.
*/
getPreviousPageParam?: GetPreviousPageParamFunction<TPageParam, TQueryFnData>
getNextPageParam: GetNextPageParamFunction<TPageParam, TQueryFnData>
}

export interface InfiniteData<TData, TPageParam> {
pages: Array<TData>
pageParams: Array<TPageParam>
}

/**
* Strings describing the query state at any given time.
*/
Expand Down Expand Up @@ -133,7 +164,10 @@ export type MutationKeys<Definitions extends EndpointDefinitions> = {
: never
}[keyof Definitions]

type BaseQuerySubState<D extends BaseEndpointDefinition<any, any, any>> = {
type BaseQuerySubState<
D extends BaseEndpointDefinition<any, any, any>,
DataType = ResultTypeFrom<D>,
> = {
/**
* The argument originally passed into the hook or `initiate` action call
*/
Expand All @@ -145,7 +179,7 @@ type BaseQuerySubState<D extends BaseEndpointDefinition<any, any, any>> = {
/**
* The received data from the query
*/
data?: ResultTypeFrom<D>
data?: DataType
/**
* The received error if applicable
*/
Expand All @@ -166,21 +200,31 @@ type BaseQuerySubState<D extends BaseEndpointDefinition<any, any, any>> = {
* Time that the latest query was fulfilled
*/
fulfilledTimeStamp?: number
/**
* Infinite Query Specific substate properties
*/
hasNextPage?: boolean
hasPreviousPage?: boolean
direction?: 'forward' | 'backward'
param?: QueryArgFrom<D>
}

export type QuerySubState<D extends BaseEndpointDefinition<any, any, any>> = Id<
export type QuerySubState<
D extends BaseEndpointDefinition<any, any, any>,
DataType = ResultTypeFrom<D>,
> = Id<
| ({
status: QueryStatus.fulfilled
} & WithRequiredProp<
BaseQuerySubState<D>,
BaseQuerySubState<D, DataType>,
'data' | 'fulfilledTimeStamp'
> & { error: undefined })
| ({
status: QueryStatus.pending
} & BaseQuerySubState<D>)
} & BaseQuerySubState<D, DataType>)
| ({
status: QueryStatus.rejected
} & WithRequiredProp<BaseQuerySubState<D>, 'error'>)
} & WithRequiredProp<BaseQuerySubState<D, DataType>, 'error'>)
| {
status: QueryStatus.uninitialized
originalArgs?: undefined
Expand All @@ -193,6 +237,21 @@ export type QuerySubState<D extends BaseEndpointDefinition<any, any, any>> = Id<
}
>

export type InfiniteQuerySubState<
D extends BaseEndpointDefinition<any, any, any>,
> =
D extends InfiniteQueryDefinition<any, any, any, any, any>
? QuerySubState<D, InfiniteData<ResultTypeFrom<D>, PageParamFrom<D>>> & {
// TODO: These shouldn't be optional
hasNextPage?: boolean
hasPreviousPage?: boolean
isFetchingNextPage?: boolean
isFetchingPreviousPage?: boolean
param?: PageParamFrom<D>
direction?: 'forward' | 'backward'
}
: never

type BaseMutationSubState<D extends BaseEndpointDefinition<any, any, any>> = {
requestId: string
data?: ResultTypeFrom<D>
Expand Down Expand Up @@ -249,7 +308,10 @@ export type InvalidationState<TagTypes extends string> = {
}

export type QueryState<D extends EndpointDefinitions> = {
[queryCacheKey: string]: QuerySubState<D[string]> | undefined
[queryCacheKey: string]:
| QuerySubState<D[string]>
| InfiniteQuerySubState<D[string]>
| undefined
}

export type SubscriptionState = {
Expand Down
Loading

0 comments on commit 1e5789f

Please sign in to comment.