/** * Suspense Infinite Query Factory - Generic wrapper for React Query suspense-based paginated canister data * * Creates unified fetch/hook/invalidate functions for any paginated canister method. * Works with any Reactor instance. * * Uses `useSuspenseInfiniteQuery` which: * - Requires wrapping in boundary * - Data is always defined (no undefined checks) * - Does NOT support `enabled` or `placeholderData` options * * @example * const postsQuery = createSuspenseInfiniteQuery(reactor, { * functionName: "get_posts", * initialPageParam: 0, * getArgs: (cursor) => [{ cursor, limit: 10 }], * getNextPageParam: (lastPage) => lastPage.nextCursor, * }) * * // In component (wrap in Suspense) * const { data, fetchNextPage, hasNextPage } = postsQuery.useSuspenseInfiniteQuery() * * // Flatten all pages * const allPosts = data.pages.flatMap(page => page.posts) */ import type { Reactor, FunctionName, ReactorArgs, BaseActor, TransformKey, ReactorReturnOk, ReactorReturnErr } from "@ic-reactor/core"; import { QueryKey, InfiniteData, UseSuspenseInfiniteQueryResult, UseSuspenseInfiniteQueryOptions, InfiniteQueryObserverOptions } from "@tanstack/react-query"; import { CallConfig } from "@icp-sdk/core/agent"; import { NoInfer } from "./types"; type SuspenseInfiniteFactoryCallOptions = { queryKey?: QueryKey; }; type SuspenseInfiniteQueryFactoryFn, T extends TransformKey, TPageParam, TSelected> = { (getArgs: (pageParam: TPageParam) => ReactorArgs): SuspenseInfiniteQueryResult, TPageParam, TSelected, SuspenseInfiniteQueryError>; (getArgs: (pageParam: TPageParam) => ReactorArgs, options?: SuspenseInfiniteFactoryCallOptions): SuspenseInfiniteQueryResult, TPageParam, TSelected, SuspenseInfiniteQueryError>; }; /** The raw page data type returned by the query function */ export type SuspenseInfiniteQueryPageData = FunctionName, T extends TransformKey = "candid"> = ReactorReturnOk; /** The error type for infinite queries */ export type SuspenseInfiniteQueryError = FunctionName, T extends TransformKey = "candid"> = ReactorReturnErr; /** * Configuration for createActorSuspenseInfiniteQuery. * Extends InfiniteQueryObserverOptions to accept all React Query options at the create level. * * @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 SuspenseInfiniteQueryConfig = FunctionName, T extends TransformKey = "candid", TPageParam = unknown, TSelected = InfiniteData, TPageParam>> extends Omit, SuspenseInfiniteQueryError, 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; /** Function to get args from page parameter */ getArgs: (pageParam: TPageParam) => ReactorArgs; } /** * Configuration for createActorSuspenseInfiniteQueryFactory (without getArgs; provided at call time). */ export type SuspenseInfiniteQueryFactoryConfig = 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; }; /** * useSuspenseInfiniteQuery hook with chained select support. */ export interface UseSuspenseInfiniteQueryWithSelect, TError = Error> { (options?: Omit, "select" | "queryKey" | "queryFn" | "initialPageParam" | "getNextPageParam" | "getPreviousPageParam">): UseSuspenseInfiniteQueryResult; (options: Omit, "queryKey" | "queryFn" | "select" | "initialPageParam" | "getNextPageParam" | "getPreviousPageParam"> & { select: (data: TSelected) => TFinal; }): UseSuspenseInfiniteQueryResult; } /** * Result from createActorSuspenseInfiniteQuery * * @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 SuspenseInfiniteQueryResult, TError = Error> { /** Fetch first page in loader (uses ensureInfiniteQueryData for cache-first) */ fetch: () => Promise; /** React hook for components - supports pagination */ useSuspenseInfiniteQuery: UseSuspenseInfiniteQueryWithSelect; /** 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 createSuspenseInfiniteQuery = FunctionName, TPageParam = unknown, TSelected = InfiniteData, TPageParam>>(reactor: Reactor, config: SuspenseInfiniteQueryConfig, M, T, TPageParam, TSelected>): SuspenseInfiniteQueryResult, TPageParam, TSelected, SuspenseInfiniteQueryError>; /** * Create a suspense 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 - Suspense infinite query configuration (without getArgs) * @returns A function that accepts getArgs and returns an SuspenseActorInfiniteQueryResult * * @example * const getPostsQuery = createActorSuspenseInfiniteQueryFactory(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.useSuspenseInfiniteQuery() * * // Optional: append a manual query-key suffix in addition to auto key args * const scopedPostsQuery = getPostsQuery( * (cursor) => [{ userId, cursor, limit: 10 }], * { queryKey: ["v2"] } * ) */ export declare function createSuspenseInfiniteQueryFactory = FunctionName, TPageParam = unknown, TSelected = InfiniteData, TPageParam>>(reactor: Reactor, config: SuspenseInfiniteQueryFactoryConfig, M, T, TPageParam, TSelected>): SuspenseInfiniteQueryFactoryFn; export {}; //# sourceMappingURL=createSuspenseInfiniteQuery.d.ts.map