- Add an sseEnabled option to useTasks and skip SSE subscription setup when disabled - Compute taskSseEnabled in App based on board/list views and pass it through to useTasks - Migrate useRemoteNodeEvents from raw EventSource management to shared subscribeSse bus usage - Update App, useTasks, and useRemoteNodeEvents tests to cover SSE gating and bus-based event wiring
65 lines
1.8 KiB
TypeScript
65 lines
1.8 KiB
TypeScript
/**
|
|
* useRemoteNodeEvents hook - subscribes to SSE events from a remote node via the proxy.
|
|
*/
|
|
|
|
import { useEffect, useState } from "react";
|
|
import { subscribeSse } from "../sse-bus";
|
|
|
|
export interface RemoteNodeEvent {
|
|
type: string;
|
|
data: unknown;
|
|
}
|
|
|
|
export interface UseRemoteNodeEventsResult {
|
|
/** Whether the SSE connection is currently active */
|
|
isConnected: boolean;
|
|
/** The last received event, or null if no events received */
|
|
lastEvent: RemoteNodeEvent | null;
|
|
}
|
|
|
|
/**
|
|
* Hook for subscribing to SSE events from a remote node via the proxy.
|
|
* Uses the shared SSE bus for connection multiplexing, heartbeat, and reconnection.
|
|
*/
|
|
export function useRemoteNodeEvents(nodeId: string | null): UseRemoteNodeEventsResult {
|
|
const [isConnected, setIsConnected] = useState(false);
|
|
const [lastEvent, setLastEvent] = useState<RemoteNodeEvent | null>(null);
|
|
|
|
useEffect(() => {
|
|
if (!nodeId) {
|
|
setIsConnected(false);
|
|
setLastEvent(null);
|
|
return;
|
|
}
|
|
|
|
const url = `/api/proxy/${encodeURIComponent(nodeId)}/events`;
|
|
|
|
return subscribeSse(url, {
|
|
events: {
|
|
"task:created": (e: MessageEvent) => {
|
|
setLastEvent({ type: "task:created", data: e.data });
|
|
},
|
|
"task:moved": (e: MessageEvent) => {
|
|
setLastEvent({ type: "task:moved", data: e.data });
|
|
},
|
|
"task:updated": (e: MessageEvent) => {
|
|
setLastEvent({ type: "task:updated", data: e.data });
|
|
},
|
|
"task:deleted": (e: MessageEvent) => {
|
|
setLastEvent({ type: "task:deleted", data: e.data });
|
|
},
|
|
"task:merged": (e: MessageEvent) => {
|
|
setLastEvent({ type: "task:merged", data: e.data });
|
|
},
|
|
},
|
|
onOpen: () => setIsConnected(true),
|
|
onError: () => setIsConnected(false),
|
|
});
|
|
}, [nodeId]);
|
|
|
|
return {
|
|
isConnected,
|
|
lastEvent,
|
|
};
|
|
}
|