1import { RegistryContext } from "@effect/atom-react";
2import {
3 executeAtomQuery,
4 type AtomQueryOptions,
5 type AtomCommandResult,
6} from "@t3tools/client-runtime/state/runtime";
7import { AsyncResult, type Atom } from "effect/reactivity";
8import { useCallback, useContext } from "react";
9
10export function useAtomQueryRunner<T, A, E>(
11 family: (target: T) => Atom.Atom<AsyncResult.AsyncResult<A, E>>,
12 options?: string | AtomQueryOptions,
13): (target: T) => Promise<AtomCommandResult<A, E>> {
14 const registry = useContext(RegistryContext);
15 const explicitLabel = typeof options === "string" ? options : options?.label;
16 const reportFailure = typeof options === "string" ? true : (options?.reportFailure ?? true);
17 const reportDefect = typeof options === "string" ? true : (options?.reportDefect ?? true);
18 const refresh = typeof options === "string" ? false : (options?.refresh ?? false);
19
20 return useCallback(
21 (target: T) => {
22 const atom = family(target);
23 return executeAtomQuery(registry, atom, {
24 label: explicitLabel ?? atom.label?.[0] ?? "atom query",
25 reportFailure,
26 reportDefect,
27 refresh,
28 });
29 },
30 [explicitLabel, family, registry, refresh, reportDefect, reportFailure],
31 );
32}