import { useMemo } from "react"
import {
QueryKey,
useSuspenseQuery,
QueryObserverOptions,
UseSuspenseQueryResult,
QueryFunction,
} from "@tanstack/react-query"
import {
FunctionName,
Reactor,
TransformKey,
ReactorArgs,
ReactorReturnOk,
ReactorReturnErr,
} from "@ic-reactor/core"
import { CallConfig } from "@icp-sdk/core/agent"
export interface UseActorSuspenseQueryParameters<
A,
M extends FunctionName,
T extends TransformKey = "candid",
TSelected = ReactorReturnOk,
> extends Omit<
QueryObserverOptions<
ReactorReturnOk,
ReactorReturnErr,
TSelected,
ReactorReturnOk,
QueryKey
>,
"queryKey" | "queryFn"
> {
reactor: Reactor
functionName: M
args?: ReactorArgs
callConfig?: CallConfig
queryKey?: QueryKey
}
export type UseActorSuspenseQueryConfig<
A,
M extends FunctionName,
T extends TransformKey = "candid",
TSelected = ReactorReturnOk,
> = Omit, "reactor">
export type UseActorSuspenseQueryResult<
A,
M extends FunctionName,
T extends TransformKey = "candid",
TSelected = ReactorReturnOk,
> = UseSuspenseQueryResult>
/**
* Hook for executing suspense-enabled query calls on a canister.
*
* @example
* const { data } = useActorSuspenseQuery({
* reactor,
* functionName: "getUser",
* args: ["user-123"],
* })
*
* // With select transformation
* const { data } = useActorSuspenseQuery({
* reactor,
* functionName: "getUser",
* args: ["user-123"],
* select: (user) => user.name,
* })
*/
export const useActorSuspenseQuery = <
A,
M extends FunctionName,
T extends TransformKey = "candid",
TSelected = ReactorReturnOk,
>({
reactor,
functionName,
args,
callConfig,
queryKey: defaultQueryKey,
...options
}: UseActorSuspenseQueryParameters<
A,
M,
T,
TSelected
>): UseActorSuspenseQueryResult => {
// Memoize query options to prevent unnecessary re-computations
const { queryKey, queryFn } = useMemo(
() =>
reactor.getQueryOptions({
callConfig,
functionName,
args,
queryKey: defaultQueryKey,
}),
[reactor, callConfig, functionName, args, defaultQueryKey]
)
return useSuspenseQuery(
{
// Suspense queries don't support skipToken, so cast the queryFn
queryFn: queryFn as QueryFunction, QueryKey>,
...options,
queryKey,
},
reactor.queryClient
)
}