import type { AxiosRequestConfig } from "axios"; import { ErrorEvent, EventSource } from 'eventsource' type Unarray = T extends Array ? U : T; export interface EventSourceListener { handle: (callback: (data: T) => void) => EventSourceListener; close: () => void; onError: (callback: (error: ErrorEvent) => void) => EventSourceListener; onOpen: (callback: (event: Event) => void) => EventSourceListener; } const eventSource = ( config: AxiosRequestConfig, options?: AxiosRequestConfig, ): Promise>> => { return new Promise((resolve, reject) => { try { const baseURL = useRuntimeConfig().public.apiBaseUrl; const endpoint = config.url; const eventSource = new EventSource(baseURL + endpoint, { fetch: (input, init) => fetch(input, { ...init, headers: { ...init.headers, Authorization: 'Basic ' + btoa('user1' + ":" + 'password'), }, }) }) let messageCallback: ((data: Unarray) => void) | null = null; let errorCallback: ((error: ErrorEvent) => void) | null = null; let openCallback: ((event: Event) => void) | null = null; eventSource.addEventListener("message", (event: MessageEvent) => { if (messageCallback) { try { let data = JSON.parse(event.data) as Unarray; messageCallback(data); } catch (error) { console.error('Error parsing EventSource data:', error); } } }); eventSource.addEventListener('error', (event) => { if (errorCallback) { errorCallback(event); } }); eventSource.addEventListener('open', (event) => { if (openCallback) { openCallback(event); } }); const listener: EventSourceListener> = { handle: (callback: (data: Unarray) => void) => { messageCallback = callback; return listener; }, onError: (callback: (error: ErrorEvent) => void) => { errorCallback = callback; return listener; }, onOpen: (callback: (event: Event) => void) => { openCallback = callback; return listener; }, close: () => { eventSource.close(); messageCallback = null; errorCallback = null; openCallback = null; } }; resolve(listener); setTimeout(() => { if (eventSource.readyState === EventSource.CLOSED && !errorCallback) { reject(new Error('EventSource connection failed')); } }, 5000); } catch (error) { reject(error); } }); } export default eventSource;