Merge branch 'fix/progress-panel-sse-listeners' into dev
This commit is contained in:
@@ -14,10 +14,13 @@ const mockedCreateEventSource = vi.mocked(createEventSource);
|
|||||||
const mockedProbeEventStreamStatus = vi.mocked(probeEventStreamStatus);
|
const mockedProbeEventStreamStatus = vi.mocked(probeEventStreamStatus);
|
||||||
|
|
||||||
describe("useEvents", () => {
|
describe("useEvents", () => {
|
||||||
let mockEs: EventSource;
|
let mockEs: EventSource & {
|
||||||
|
emit: (type: string, data: string) => void;
|
||||||
|
};
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.useFakeTimers({ shouldAdvanceTime: true });
|
vi.useFakeTimers({ shouldAdvanceTime: true });
|
||||||
|
const listeners = new Map<string, Set<(e: MessageEvent) => void>>();
|
||||||
mockEs = {
|
mockEs = {
|
||||||
close: vi.fn(),
|
close: vi.fn(),
|
||||||
onopen: null,
|
onopen: null,
|
||||||
@@ -27,7 +30,17 @@ describe("useEvents", () => {
|
|||||||
return EventSource.OPEN;
|
return EventSource.OPEN;
|
||||||
},
|
},
|
||||||
url: "http://localhost:8000/events/stream",
|
url: "http://localhost:8000/events/stream",
|
||||||
} as unknown as EventSource;
|
addEventListener: vi.fn((type: string, handler: (e: MessageEvent) => void) => {
|
||||||
|
if (!listeners.has(type)) listeners.set(type, new Set());
|
||||||
|
listeners.get(type)!.add(handler);
|
||||||
|
}),
|
||||||
|
removeEventListener: vi.fn((type: string, handler: (e: MessageEvent) => void) => {
|
||||||
|
listeners.get(type)?.delete(handler);
|
||||||
|
}),
|
||||||
|
emit: (type: string, data: string) => {
|
||||||
|
listeners.get(type)?.forEach((handler) => handler({ data } as MessageEvent));
|
||||||
|
},
|
||||||
|
} as unknown as EventSource & { emit: (type: string, data: string) => void };
|
||||||
mockedCreateEventSource.mockReturnValue(mockEs);
|
mockedCreateEventSource.mockReturnValue(mockEs);
|
||||||
mockedProbeEventStreamStatus.mockResolvedValue(null);
|
mockedProbeEventStreamStatus.mockResolvedValue(null);
|
||||||
});
|
});
|
||||||
@@ -56,9 +69,7 @@ describe("useEvents", () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
act(() => {
|
act(() => {
|
||||||
mockEs.onmessage?.({
|
mockEs.emit("instance.started", JSON.stringify(payload));
|
||||||
data: JSON.stringify(payload),
|
|
||||||
} as MessageEvent);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
|
|||||||
@@ -12,6 +12,16 @@ export interface UseEventsReturn {
|
|||||||
const MAX_DELAY = 30000;
|
const MAX_DELAY = 30000;
|
||||||
const BASE_DELAY = 1000;
|
const BASE_DELAY = 1000;
|
||||||
|
|
||||||
|
const LIFECYCLE_EVENT_TYPES = [
|
||||||
|
"instance.created",
|
||||||
|
"instance.started",
|
||||||
|
"instance.stopped",
|
||||||
|
"instance.restarted",
|
||||||
|
"instance.deleted",
|
||||||
|
"instance.error",
|
||||||
|
"instance.health_changed",
|
||||||
|
] as const;
|
||||||
|
|
||||||
export function useEvents(): UseEventsReturn {
|
export function useEvents(): UseEventsReturn {
|
||||||
const [events, setEvents] = useState<InstanceEventPayload[]>([]);
|
const [events, setEvents] = useState<InstanceEventPayload[]>([]);
|
||||||
const [connected, setConnected] = useState(false);
|
const [connected, setConnected] = useState(false);
|
||||||
@@ -39,7 +49,7 @@ export function useEvents(): UseEventsReturn {
|
|||||||
setReconnectCount(0);
|
setReconnectCount(0);
|
||||||
};
|
};
|
||||||
|
|
||||||
es.onmessage = (e) => {
|
const handleEventMessage = (e: MessageEvent) => {
|
||||||
if (!isMountedRef.current) return;
|
if (!isMountedRef.current) return;
|
||||||
try {
|
try {
|
||||||
const payload: InstanceEventPayload = JSON.parse(e.data);
|
const payload: InstanceEventPayload = JSON.parse(e.data);
|
||||||
@@ -49,6 +59,11 @@ export function useEvents(): UseEventsReturn {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
es.addEventListener("message", handleEventMessage);
|
||||||
|
for (const eventType of LIFECYCLE_EVENT_TYPES) {
|
||||||
|
es.addEventListener(eventType, handleEventMessage);
|
||||||
|
}
|
||||||
|
|
||||||
es.onerror = () => {
|
es.onerror = () => {
|
||||||
if (!isMountedRef.current) return;
|
if (!isMountedRef.current) return;
|
||||||
setConnected(false);
|
setConnected(false);
|
||||||
|
|||||||
Reference in New Issue
Block a user