import { EventSourcePolyfill } from "event-source-polyfill"; class SseSource { private readonly accessId: number private readonly url: URL private eventSource: EventSource | null = null constructor(mercureBaseUrl: string, accessId: number) { this.accessId = accessId this.url = new URL(mercureBaseUrl) this.url.searchParams.append('topic', "access/" + this.accessId) } getUrl () { return this.url } isOpen () { return this.eventSource !== null && this.eventSource.readyState === EventSource.OPEN } public subscribe () { if (this.isOpen()) { throw new Error('SSE - Already subscribed to this event source') } if (process.server) { throw new Error('SSE - Cannot subscribe on server side') } this.eventSource = new EventSourcePolyfill( this.url.toString(), { withCredentials: true } ); this.eventSource.onerror = (event) => { console.error('SSE - An error happened : ' + JSON.stringify(event)) this.eventSource?.close() } this.eventSource.onopen = () => { console.log('SSE - Listening for events...') } this.eventSource.onmessage = event => { const data = JSON.parse(event.data) console.log(data) } } public unsubscribe () { if (this.eventSource === null || this.eventSource.readyState === EventSource.CLOSED) { return } this.eventSource.close() console.log('SSE - Subscription closed') } } export default SseSource