import { useCallback, useEffect, useMemo, useState } from "react"; import { createSilentCronXClient, type JobRecord, type QueueStats } from "silent-cronx"; export function useSilentCronXJob(baseUrl = "http://localhost:4517") { const client = useMemo(() => createSilentCronXClient({ baseUrl }), [baseUrl]); const [loading, setLoading] = useState(false); const [jobId, setJobId] = useState(null); const [job, setJob] = useState(null); const [error, setError] = useState(null); const triggerReport = useCallback( async (reportType: string) => { setLoading(true); setError(null); try { const response = await client.triggerJob("report", { payload: { reportType }, priority: 10, }); setJobId(response.jobId); return response; } catch (caught) { const message = caught instanceof Error ? caught.message : "SilentCronX request failed"; setError(message); throw caught; } finally { setLoading(false); } }, [client] ); useEffect(() => { if (!jobId) return; const timer = setInterval(() => { void client.getJob(jobId).then(setJob).catch((caught) => { setError(caught instanceof Error ? caught.message : "SilentCronX status failed"); }); }, 1000); return () => clearInterval(timer); }, [client, jobId]); return { loading, error, jobId, job, progress: job?.progress, triggerReport }; } export function useSilentCronXQueueStats(baseUrl = "http://localhost:4517") { const client = useMemo(() => createSilentCronXClient({ baseUrl }), [baseUrl]); const [stats, setStats] = useState([]); useEffect(() => { const load = () => void client.getQueueStats().then(setStats); load(); const timer = setInterval(load, 2000); return () => clearInterval(timer); }, [client]); return stats; }