utp_service/frontend/src/hooks/useDashboardMonitorSSE.ts
2026-05-05 11:32:25 +03:00

45 lines
1.3 KiB
TypeScript

import { fetchEventSource } from '@microsoft/fetch-event-source'
import { useEffect, useRef } from 'react'
import { useAuthStore } from '../store/auth'
interface DashboardMonitorHandlers {
onUpdate?: (eventType: string, data: Record<string, unknown>) => void
}
const DASHBOARD_MONITOR_CHANNEL = '__dashboard_monitor__'
export function useDashboardMonitorSSE(handlers: DashboardMonitorHandlers) {
const accessToken = useAuthStore((s) => s.accessToken)
const handlersRef = useRef(handlers)
handlersRef.current = handlers
useEffect(() => {
if (!accessToken) return
const ctrl = new AbortController()
fetchEventSource(`/api/v1/events?task_id=${DASHBOARD_MONITOR_CHANNEL}`, {
headers: { Authorization: `Bearer ${accessToken}` },
signal: ctrl.signal,
onmessage(ev) {
try {
const data = JSON.parse(ev.data)
if (
ev.event === 'dashboard_monitor_update' ||
ev.event === 'dashboard_monitor_cycle_done' ||
ev.event === 'dashboard_monitor_cycle_failed'
) {
handlersRef.current.onUpdate?.(ev.event, data)
}
} catch {
// ignore parse errors
}
},
onerror(err) {
ctrl.abort()
throw err
},
})
return () => ctrl.abort()
}, [accessToken])
}