/** * 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