Spaces:
Paused
Paused
Download apps/web/src/lib/hooks/useJobPolling.ts from nathycodes/presentercoach: direct link, hf CLI and curl.
- Browser
- Download file 1.99 kB
-
https://huggingface.co/spaces/nathycodes/presentercoach/resolve/main/apps/web/src/lib/hooks/useJobPolling.ts
- Command line
-
hf download hf://spaces/nathycodes/presentercoach/apps/web/src/lib/hooks/useJobPolling.ts
-
curl -L -o useJobPolling.ts https://huggingface.co/spaces/nathycodes/presentercoach/resolve/main/apps/web/src/lib/hooks/useJobPolling.ts
1.99 kB
| import { useEffect, useRef, useState } from "react"; | |
| import { apiFetch } from "@/lib/api"; | |
| export type JobStatus = "pending" | "queued" | "in_progress" | "complete" | "failed" | "not_found" | "unknown"; | |
| type JobState = { | |
| status: JobStatus; | |
| result: Record<string, unknown> | null; | |
| error: string | null; | |
| }; | |
| type UseJobPollingOptions = { | |
| jobId: string | null; | |
| intervalMs?: number; | |
| onComplete?: (result: Record<string, unknown>) => void; | |
| onError?: (error: string) => void; | |
| }; | |
| export function useJobPolling({ | |
| jobId, | |
| intervalMs = 2000, | |
| onComplete, | |
| onError, | |
| }: UseJobPollingOptions): JobState { | |
| const [state, setState] = useState<JobState>({ status: "pending", result: null, error: null }); | |
| const onCompleteRef = useRef(onComplete); | |
| const onErrorRef = useRef(onError); | |
| useEffect(() => { | |
| onCompleteRef.current = onComplete; | |
| onErrorRef.current = onError; | |
| }, [onComplete, onError]); | |
| useEffect(() => { | |
| if (!jobId) return; | |
| let active = true; | |
| let interval: number | null = null; | |
| const poll = async () => { | |
| try { | |
| const data = await apiFetch<JobState>(`/jobs/${jobId}`); | |
| if (!active) return; | |
| setState(data); | |
| if (data.status === "complete") { | |
| if (interval) window.clearInterval(interval); | |
| onCompleteRef.current?.(data.result || {}); | |
| } | |
| if (data.status === "failed") { | |
| if (interval) window.clearInterval(interval); | |
| onErrorRef.current?.(data.error || "Job failed."); | |
| } | |
| } catch (error) { | |
| if (!active) return; | |
| const message = error instanceof Error ? error.message : "Job polling failed."; | |
| setState({ status: "failed", result: null, error: message }); | |
| onErrorRef.current?.(message); | |
| } | |
| }; | |
| poll(); | |
| interval = window.setInterval(poll, intervalMs); | |
| return () => { | |
| active = false; | |
| if (interval) window.clearInterval(interval); | |
| }; | |
| }, [intervalMs, jobId]); | |
| return state; | |
| } | |