aboutsummaryrefslogtreecommitdiff
path: root/frontend/src/lib/realtime.ts
blob: fb9c75c6ee9a38b7a54d5ac46690f35fa8b89b95 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import type { Heartbeat } from '$lib/types';

type Listener = (hb: Heartbeat) => void;

const listeners = new Set<Listener>();
let es: EventSource | null = null;

function connect() {
	if (es) return;

	es = new EventSource('/api/stream');

	es.addEventListener('connected', () => {
		console.log('[sse] conectado');
	});

	es.addEventListener('heartbeat', (event: MessageEvent) => {
		try {
			const hb: Heartbeat = JSON.parse(event.data);
			listeners.forEach((fn) => fn(hb));
		} catch {
			// ignore parse errors
		}
	});

	es.onerror = () => {
		console.warn('[sse] erro — reconectando...');
	};
}

export function subscribeHeartbeats(fn: Listener) {
	listeners.add(fn);
	connect();

	return () => {
		listeners.delete(fn);
		if (listeners.size === 0 && es) {
			es.close();
			es = null;
		}
	};
}