import { InfiniteQueryPageParamsOptions, hasNextPage, hasPreviousPage, } from './infiniteQueryBehavior' import { ObservableQuery, ObservableQueryBaseResult, ObservableQueryOptions, createObservableQuery, } from './observableQuery' import { QueryClient, ResultOptions } from './queryClient' import { QueryInfo } from './queryInfo' import { InfiniteQuery } from './queryWithInfinite' import { Override } from './typeUtils' import { InfiniteData } from './types' export interface FetchNextPageOptions extends ResultOptions { cancelRefetch?: boolean } export interface FetchPreviousPageOptions extends ResultOptions { cancelRefetch?: boolean } export interface ObservableInfiniteQueryOptions< TFetcherData = unknown, TVars = unknown, TError = Error, TData = InfiniteData > extends ObservableQueryOptions< TFetcherData, TVars, TError, InfiniteData, TData > { query: InfiniteQuery } export interface ObservableInfiniteQueryBaseResult< TData = unknown, TError = Error > extends ObservableQueryBaseResult { fetchNextPage: ( options?: FetchNextPageOptions ) => Promise> fetchPreviousPage: ( options?: FetchPreviousPageOptions ) => Promise> hasNextPage: boolean hasPreviousPage: boolean isFetchingNextPage: boolean isFetchingPreviousPage: boolean } export interface ObservableInfiniteQueryLoadingResult< TData = unknown, TError = Error > extends ObservableInfiniteQueryBaseResult { data: undefined error: null } export interface ObservableInfiniteQueryLoadingErrorResult< TData = unknown, TError = Error > extends ObservableInfiniteQueryBaseResult { data: undefined error: TError } export interface ObservableInfiniteQuerySuccessResult< TData = unknown, TError = Error > extends ObservableInfiniteQueryBaseResult { data: TData error: null } export type ObservableInfiniteQueryResult = | ObservableInfiniteQueryLoadingResult | ObservableInfiniteQueryLoadingErrorResult | ObservableInfiniteQuerySuccessResult type ObservableInfiniteQueryListener = ( result: ObservableInfiniteQueryResult ) => void export interface ObservableInfiniteQuery< TFetcherData = unknown, TVars = unknown, TError = Error, TData = InfiniteData > extends Override< ObservableQuery< TFetcherData, TVars, TError, InfiniteData, TData >, { subscribe: ( listener?: ObservableInfiniteQueryListener ) => () => void createResult: ( queryInfo: QueryInfo< TFetcherData, TVars, TError, InfiniteData >, options: ObservableInfiniteQueryOptions< TFetcherData, TVars, TError, TData > ) => ObservableInfiniteQueryResult getCurrentResult: () => ObservableInfiniteQueryResult getOptimisticResult: ( options: ObservableInfiniteQueryOptions< TFetcherData, TVars, TError, TData > ) => ObservableInfiniteQueryResult } > { fetchNextPage: ( options?: FetchNextPageOptions ) => Promise> fetchPreviousPage: ( options?: FetchPreviousPageOptions ) => Promise> } export const createObservableInfiniteQuery = < TFetcherData = unknown, TVars = unknown, TError = Error, TData = InfiniteData >( client: QueryClient, initialOptions: ObservableInfiniteQueryOptions< TFetcherData, TVars, TError, TData > ): ObservableInfiniteQuery => { initialOptions.behavior = ( obsQuery: ObservableInfiniteQuery ) => { const { fetch, createResult } = obsQuery const fetchNextPage = (options?: FetchNextPageOptions) => fetch({ ...options, meta: { fetchMore: { direction: 'forward' }, }, }) as Promise> const fetchPreviousPage = (options?: FetchPreviousPageOptions) => fetch({ ...options, meta: { fetchMore: { direction: 'backward' }, }, }) as Promise> Object.assign(obsQuery, { fetchNextPage, fetchPreviousPage, createResult: ( queryInfo: QueryInfo< TFetcherData, TVars, TError, InfiniteData >, options: ObservableInfiniteQueryOptions< TFetcherData, TVars, TError, TData > ): ObservableInfiniteQueryResult => { const { state } = queryInfo const result = createResult(queryInfo, options) const { isFetching } = result const isFetchingNextPage = isFetching && state.fetchMeta?.fetchMore?.direction === 'forward' const isFetchingPreviousPage = isFetching && state.fetchMeta?.fetchMore?.direction === 'backward' return { ...result, fetchNextPage, fetchPreviousPage, hasNextPage: hasNextPage( options as unknown as InfiniteQueryPageParamsOptions, state.data ), hasPreviousPage: hasPreviousPage( options as unknown as InfiniteQueryPageParamsOptions, state.data ), isFetchingNextPage, isFetchingPreviousPage, } }, }) } return createObservableQuery( client, initialOptions ) as ObservableInfiniteQuery }