import { useQuery, useQueryClient } from "@tanstack/react-query"; import { useEffect } from "react"; import { useHostRuntimeClient, useHostRuntimeIsConnected } from "@/runtime/host-runtime"; import { checkoutStatusQueryKey } from "@/git/query-keys"; import { applyCheckoutStatusUpdate, type CheckoutStatusClient, type CheckoutStatusPayload, peekOrFetchCheckoutStatus, } from "./checkout-status-cache"; export type { CheckoutStatusPayload } from "./checkout-status-cache"; export const CHECKOUT_STATUS_STALE_TIME = 15_000; interface UseCheckoutStatusQueryOptions { serverId: string; cwd: string; } function fetchCheckoutStatus( client: CheckoutStatusClient, cwd: string, ): Promise { return client.getCheckoutStatus(cwd); } export function useCheckoutStatusQuery({ serverId, cwd }: UseCheckoutStatusQueryOptions) { const queryClient = useQueryClient(); const client = useHostRuntimeClient(serverId); const isConnected = useHostRuntimeIsConnected(serverId); useEffect(() => { if (!client || !isConnected || !cwd) { return; } return client.on("checkout_status_update", (message) => { applyCheckoutStatusUpdate({ queryClient, serverId, cwd, message }); }); }, [client, isConnected, cwd, queryClient, serverId]); const query = useQuery({ queryKey: checkoutStatusQueryKey(serverId, cwd), queryFn: async () => { if (!client) { throw new Error("Daemon client not available"); } return await peekOrFetchCheckoutStatus({ queryClient, client, serverId, cwd }); }, enabled: !!client && isConnected && !!cwd, staleTime: Infinity, refetchOnMount: false, refetchOnReconnect: false, refetchOnWindowFocus: false, }); return { status: query.data ?? null, isLoading: query.isLoading, isFetching: query.isFetching, isError: query.isError, error: query.error, }; } /** * Subscribe to checkout status updates from the React Query cache without * initiating a fetch. Useful for list rows where a parent component prefetches * only the visible agents. */ export function useCheckoutStatusCacheOnly({ serverId, cwd }: UseCheckoutStatusQueryOptions) { const client = useHostRuntimeClient(serverId); return useQuery({ queryKey: checkoutStatusQueryKey(serverId, cwd), queryFn: async () => { if (!client) { throw new Error("Daemon client not available"); } return await fetchCheckoutStatus(client, cwd); }, enabled: false, staleTime: CHECKOUT_STATUS_STALE_TIME, }); }