11import { useEffect } from 'react'
22import { createLogger } from '@sim/logger'
3+ import type { QueryClient } from '@tanstack/react-query'
34import { useQueryClient } from '@tanstack/react-query'
45import { taskKeys } from '@/hooks/queries/tasks'
56
67const logger = createLogger ( 'TaskEvents' )
78
9+ interface TaskStatusEventPayload {
10+ chatId ?: string
11+ type ?: 'started' | 'completed' | 'created' | 'deleted' | 'renamed'
12+ }
13+
14+ function parseTaskStatusEventPayload ( data : unknown ) : TaskStatusEventPayload | null {
15+ let parsed = data
16+
17+ if ( typeof parsed === 'string' ) {
18+ try {
19+ parsed = JSON . parse ( parsed )
20+ } catch {
21+ return null
22+ }
23+ }
24+
25+ if ( ! parsed || typeof parsed !== 'object' || Array . isArray ( parsed ) ) {
26+ return null
27+ }
28+
29+ const record = parsed as Record < string , unknown >
30+
31+ return {
32+ ...( typeof record . chatId === 'string' ? { chatId : record . chatId } : { } ) ,
33+ ...( typeof record . type === 'string'
34+ ? { type : record . type as TaskStatusEventPayload [ 'type' ] }
35+ : { } ) ,
36+ }
37+ }
38+
39+ export function handleTaskStatusEvent (
40+ queryClient : Pick < QueryClient , 'invalidateQueries' > ,
41+ data : unknown
42+ ) : void {
43+ queryClient . invalidateQueries ( { queryKey : taskKeys . lists ( ) } )
44+
45+ const payload = parseTaskStatusEventPayload ( data )
46+ if ( ! payload ) {
47+ logger . warn ( 'Received invalid task_status payload' )
48+ return
49+ }
50+
51+ if ( payload . type === 'completed' && payload . chatId ) {
52+ queryClient . invalidateQueries ( { queryKey : taskKeys . detail ( payload . chatId ) } )
53+ }
54+ }
55+
856/**
9- * Subscribes to task status SSE events and invalidates the task list on changes.
57+ * Subscribes to task status SSE events and invalidates task caches on changes.
1058 */
1159export function useTaskEvents ( workspaceId : string | undefined ) {
1260 const queryClient = useQueryClient ( )
@@ -18,8 +66,8 @@ export function useTaskEvents(workspaceId: string | undefined) {
1866 `/api/mothership/events?workspaceId=${ encodeURIComponent ( workspaceId ) } `
1967 )
2068
21- eventSource . addEventListener ( 'task_status' , ( ) => {
22- queryClient . invalidateQueries ( { queryKey : taskKeys . lists ( ) } )
69+ eventSource . addEventListener ( 'task_status' , ( event ) => {
70+ handleTaskStatusEvent ( queryClient , event instanceof MessageEvent ? event . data : undefined )
2371 } )
2472
2573 eventSource . onerror = ( ) => {
0 commit comments