Files
Neon-Desk/hooks/use-task-poller.ts

60 lines
1.2 KiB
TypeScript

'use client';
import { useEffect, useState } from 'react';
import { getTask } from '@/lib/api';
import type { Task } from '@/lib/types';
type UseTaskPollerInput = {
taskId: string | null;
intervalMs?: number;
onTerminalState?: (task: Task) => void;
};
export function useTaskPoller({ taskId, intervalMs = 2200, onTerminalState }: UseTaskPollerInput) {
const [task, setTask] = useState<Task | null>(null);
useEffect(() => {
if (!taskId) {
setTask(null);
return;
}
let stopped = false;
let timer: ReturnType<typeof setTimeout> | null = null;
const poll = async () => {
try {
const { task: latest } = await getTask(taskId);
if (stopped) {
return;
}
setTask(latest);
if (latest.status === 'completed' || latest.status === 'failed') {
onTerminalState?.(latest);
return;
}
} catch {
if (stopped) {
return;
}
}
timer = setTimeout(poll, intervalMs);
};
void poll();
return () => {
stopped = true;
if (timer) {
clearTimeout(timer);
}
};
}, [taskId, intervalMs, onTerminalState]);
return task;
}