95 lines
3.2 KiB
TypeScript
95 lines
3.2 KiB
TypeScript
import type { AxiosRequestConfig } from "axios";
|
|
import { ErrorEvent, EventSource } from 'eventsource'
|
|
|
|
type Unarray<T> = T extends Array<infer U> ? U : T;
|
|
|
|
export interface EventSourceListener<T> {
|
|
handle: (callback: (data: T) => void) => EventSourceListener<T>;
|
|
close: () => void;
|
|
onError: (callback: (error: ErrorEvent) => void) => EventSourceListener<T>;
|
|
onOpen: (callback: (event: Event) => void) => EventSourceListener<T>;
|
|
}
|
|
|
|
const eventSource = <T>(
|
|
config: AxiosRequestConfig,
|
|
options?: AxiosRequestConfig,
|
|
): Promise<EventSourceListener<Unarray<T>>> => {
|
|
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<T>) => void) | null = null;
|
|
let errorCallback: ((error: ErrorEvent) => void) | null = null;
|
|
let openCallback: ((event: Event) => void) | null = null;
|
|
|
|
eventSource.addEventListener("message", (event: MessageEvent<any>) => {
|
|
if (messageCallback) {
|
|
try {
|
|
let data = JSON.parse(event.data) as Unarray<T>;
|
|
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<Unarray<T>> = {
|
|
handle: (callback: (data: Unarray<T>) => 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;
|