Files
Control-Center/frontend/src/hooks/useRealtimeSync.ts

53 lines
1.6 KiB
TypeScript
Raw Normal View History

/**
* useRealtimeSync mounts the SSE connection once at the app level and
* wires incoming events to React Query cache invalidation.
*
* Event query key mapping:
* agent.status ['agents']
* agent.task ['tasks'], ['agents']
* agent.progress ['tasks'], ['agents']
* fleet.update ['agents'], ['sessions'], ['tasks']
*/
import { useQueryClient } from '@tanstack/react-query'
import { useCallback } from 'react'
import { useSSE, type SSEMessage, type SSEStatus } from './useSSE'
export function useRealtimeSync(): { sseStatus: SSEStatus } {
const queryClient = useQueryClient()
const handleMessage = useCallback(
(msg: SSEMessage) => {
switch (msg.type) {
case 'agent.status':
queryClient.invalidateQueries({ queryKey: ['agents'] })
break
case 'agent.task':
queryClient.invalidateQueries({ queryKey: ['tasks'] })
queryClient.invalidateQueries({ queryKey: ['agents'] })
break
case 'agent.progress':
queryClient.invalidateQueries({ queryKey: ['tasks'] })
queryClient.invalidateQueries({ queryKey: ['agents'] })
break
case 'fleet.update':
queryClient.invalidateQueries({ queryKey: ['agents'] })
queryClient.invalidateQueries({ queryKey: ['sessions'] })
queryClient.invalidateQueries({ queryKey: ['tasks'] })
break
default:
// 'connected' and unknown events — no action needed
break
}
},
[queryClient],
)
const { status: sseStatus } = useSSE({ onMessage: handleMessage })
return { sseStatus }
}