/**
* Infinite Query Factory - Generic wrapper for React Query paginated canister data
*
* Creates unified fetch/hook/invalidate functions for any paginated canister method.
* Works with any Reactor instance.
*
* @example
* const postsQuery = createInfiniteQuery(reactor, {
* functionName: "get_posts",
* initialPageParam: 0,
* getArgs: (cursor) => [{ cursor, limit: 10 }],
* getNextPageParam: (lastPage) => lastPage.nextCursor,
* })
*
* // In component
* const { data, fetchNextPage, hasNextPage } = postsQuery.useInfiniteQuery()
*
* // Flatten all pages
* const allPosts = data?.pages.flatMap(page => page.posts)
*
* // Invalidate cache
* postsQuery.invalidate()
*/
import type { Reactor, FunctionName, ReactorArgs, BaseActor, TransformKey, ReactorReturnOk, ReactorReturnErr } from "@ic-reactor/core";
import { QueryKey, InfiniteData, UseInfiniteQueryResult, UseInfiniteQueryOptions, InfiniteQueryObserverOptions } from "@tanstack/react-query";
import { CallConfig } from "@icp-sdk/core/agent";
import { NoInfer } from "./types";
type InfiniteQueryFactoryFn, T extends TransformKey, TPageParam, TSelected> = {
(getArgs: (pageParam: TPageParam) => ReactorArgs): InfiniteQueryResult, TPageParam, TSelected, InfiniteQueryError>;
};
/** The raw page data type returned by the query function */
export type InfiniteQueryPageData = FunctionName, T extends TransformKey = "candid"> = ReactorReturnOk;
/** The error type for infinite queries */
export type InfiniteQueryError = FunctionName, T extends TransformKey = "candid"> = ReactorReturnErr;
/**
* Configuration for createActorInfiniteQuery.
* Extends InfiniteQueryObserverOptions to accept standard TanStack Query
* infinite-query options at the create level (e.g. refetchInterval,
* refetchOnMount, refetchOnWindowFocus, retry, gcTime, networkMode).
*
* @template A - The actor interface type
* @template M - The method name on the actor
* @template T - The transformation key (identity, display, etc.)
* @template TPageParam - The type of the page parameter
* @template TSelected - The type returned after select transformation
*/
export interface InfiniteQueryConfig = FunctionName, T extends TransformKey = "candid", TPageParam = unknown, TSelected = InfiniteData, TPageParam>> extends Omit, InfiniteQueryError, TSelected, QueryKey, TPageParam>, "queryKey" | "queryFn"> {
/** The method to call on the canister */
functionName: M;
/** Call configuration for the actor method */
callConfig?: CallConfig;
/** Custom query key (optional, auto-generated if not provided) */
queryKey?: QueryKey;
/** Initial page parameter */
initialPageParam: TPageParam;
/** Function to get args from page parameter */
getArgs: (pageParam: TPageParam) => ReactorArgs;
/** Function to determine next page parameter */
getNextPageParam: (lastPage: InfiniteQueryPageData, allPages: InfiniteQueryPageData[], lastPageParam: TPageParam, allPageParams: TPageParam[]) => TPageParam | undefined | null;
/** Function to determine previous page parameter (for bi-directional) */
getPreviousPageParam?: (firstPage: InfiniteQueryPageData, allPages: InfiniteQueryPageData[], firstPageParam: TPageParam, allPageParams: TPageParam[]) => TPageParam | undefined | null;
}
/**
* Configuration for createActorInfiniteQueryFactory (without initialPageParam, getArgs determined at call time).
*/
export type InfiniteQueryFactoryConfig = FunctionName, T extends TransformKey = "candid", TPageParam = unknown, TSelected = InfiniteData, TPageParam>> = Omit, "getArgs"> & {
/**
* Optional key-args derivation for factory calls.
* Receives the resolved args from `getArgs(initialPageParam)` and should return
* a stable serializable representation of the logical query identity
* (typically excluding pagination/cursor fields).
*/
getKeyArgs?: (args: ReactorArgs) => unknown;
};
/**
* useInfiniteQuery hook with chained select support.
*/
export interface UseInfiniteQueryWithSelect, TError = Error> {
(options?: Omit, "select" | "queryKey" | "queryFn" | "initialPageParam" | "getNextPageParam" | "getPreviousPageParam">): UseInfiniteQueryResult;
(options: Omit, "queryKey" | "queryFn" | "select" | "initialPageParam" | "getNextPageParam" | "getPreviousPageParam"> & {
select: (data: TSelected) => TFinal;
}): UseInfiniteQueryResult;
}
/**
* Result from createActorInfiniteQuery
*
* @template TPageData - The raw page data type
* @template TPageParam - The page parameter type
* @template TSelected - The type after select transformation
* @template TError - The error type
*/
export interface InfiniteQueryResult, TError = Error> {
/** Fetch first page in loader (uses ensureQueryData for cache-first) */
fetch: () => Promise;
/** React hook for components - supports pagination */
useInfiniteQuery: UseInfiniteQueryWithSelect;
/** Invalidate the cache (refetches if query is active) */
invalidate: () => Promise;
/** Get query key (for advanced React Query usage) */
getQueryKey: () => QueryKey;
/**
* Read data directly from cache without fetching.
* Returns undefined if data is not in cache.
*/
getCacheData: {
(): TSelected | undefined;
(select: (data: TSelected) => TFinal): TFinal | undefined;
};
}
export declare function createInfiniteQuery = FunctionName, TPageParam = unknown, TSelected = InfiniteData, TPageParam>>(reactor: Reactor, config: InfiniteQueryConfig, M, T, TPageParam, TSelected>): InfiniteQueryResult, TPageParam, TSelected, InfiniteQueryError>;
/**
* Create an infinite query factory that accepts getArgs at call time.
* Useful when pagination logic varies by context.
*
* @template A - The actor interface type
* @template M - The method name on the actor
* @template T - The transformation key (identity, display, etc.)
* @template TPageParam - The page parameter type
* @template TSelected - The type returned after select transformation
*
* @param reactor - The Reactor instance
* @param config - Infinite query configuration (without getArgs)
* @returns A function that accepts getArgs and returns an ActorInfiniteQueryResult
*
* @example
* const getPostsQuery = createActorInfiniteQueryFactory(reactor, {
* functionName: "get_posts",
* initialPageParam: 0,
* getKeyArgs: (args) => {
* const [{ userId }] = args
* return [{ userId }]
* },
* getNextPageParam: (lastPage) => lastPage.nextCursor,
* })
*
* // Create query with specific args builder
* const userPostsQuery = getPostsQuery((cursor) => [{ userId, cursor, limit: 10 }])
* const { data, fetchNextPage } = userPostsQuery.useInfiniteQuery()
*/
export declare function createInfiniteQueryFactory = FunctionName, TPageParam = unknown, TSelected = InfiniteData, TPageParam>>(reactor: Reactor, config: InfiniteQueryFactoryConfig, M, T, TPageParam, TSelected>): InfiniteQueryFactoryFn;
export {};
//# sourceMappingURL=createInfiniteQuery.d.ts.map