import { useQuery, useQueryClient } from "@tanstack/react-query"; import { useEffect, useRef } from "react"; import { getPullMergeFix } from "~/fns/mergefix"; import type { QueryClient } from "@tanstack/react-query"; export type MergeFix = Awaited>; export type PullParams = { owner: string; repo: string; number: number }; const POLL_MS = 4000; export const MERGE_FIX_ACTIVE = new Set(["queued", "running", "applying"]); export const mergeFixQueryKey = ({ owner, repo, number }: PullParams) => ["merge-fix", owner, repo, number] as const; export async function refreshMergeFix(queryClient: QueryClient, params: PullParams): Promise { await queryClient.invalidateQueries({ queryKey: mergeFixQueryKey(params) }); } /** Seeds from the route loader, polls while a run is active and reports once it settles. */ export function useMergeFix(params: PullParams, initial: MergeFix, onSettled: (fix: MergeFix) => void) { const queryClient = useQueryClient(); const query = useQuery({ queryKey: mergeFixQueryKey(params), queryFn: () => getPullMergeFix({ data: params }), initialData: initial, refetchInterval: (state) => { const fix = state.state.data; return fix && MERGE_FIX_ACTIVE.has(fix.status) ? POLL_MS : false; }, }); const fix = query.data; const active = fix !== null && MERGE_FIX_ACTIVE.has(fix.status); const wasActive = useRef(active); const latestOnSettled = useRef(onSettled); latestOnSettled.current = onSettled; useEffect(() => { if (wasActive.current && !active) latestOnSettled.current(fix); wasActive.current = active; }, [active, fix]); return { fix, refresh: () => refreshMergeFix(queryClient, params) }; }