import { useEffect, useRef } from 'react'; import { useForge } from '../context/ForgeContext'; const FORGE_POLL_MS = 1000; /** Poll GET /api/v1/builder/progress/{token} while a forge is running. */ export function useForgeProgressPoll( active: boolean, cancelTokenRef: React.RefObject, ) { const { startForge, endForge, setStage } = useForge(); const timerRef = useRef | null>(null); useEffect(() => { if (!active) { endForge(); if (timerRef.current) clearTimeout(timerRef.current); return; } startForge(); const token = cancelTokenRef.current; if (!token) return; let alive = true; const poll = async () => { if (!alive) return; try { const { authHeaders } = await import('../api/auth'); const res = await fetch(`/api/v1/builder/progress/${encodeURIComponent(token)}`, { headers: authHeaders(), }); if (res.ok) { const data: { stage?: string; pct?: number } = await res.json(); const pct = typeof data.pct === 'number' ? data.pct : 0; if (alive && (data.stage || pct > 0)) { setStage(data.stage || 'Forging...', pct); } } } catch { // network hiccup — keep polling } if (alive) { timerRef.current = setTimeout(poll, FORGE_POLL_MS); } }; poll(); return () => { alive = false; if (timerRef.current) clearTimeout(timerRef.current); }; // eslint-disable-next-line react-hooks/exhaustive-deps }, [active]); }