Files
homelab-optimized/dashboard/ui/lib/use-sse.ts
Gitea Mirror Bot 85f77995ec
Some checks failed
Documentation / Deploy to GitHub Pages (push) Has been cancelled
Documentation / Build Docusaurus (push) Has been cancelled
Sanitized mirror from private repository - 2026-04-05 11:04:10 UTC
2026-04-05 11:04:10 +00:00

53 lines
1.4 KiB
TypeScript

"use client";
import { useState, useEffect, useRef } from "react";
import type { ActivityEvent } from "./types";
// Use same origin — Next.js rewrites /api/* to backend
export function useSSE(path: string, maxEvents: number = 30) {
const [events, setEvents] = useState<ActivityEvent[]>([]);
const retryTimeout = useRef<ReturnType<typeof setTimeout> | null>(null);
useEffect(() => {
let es: EventSource | null = null;
function connect() {
es = new EventSource(path);
// Backend sends "init" with the full batch and "update" with new events
es.addEventListener("init", (e: MessageEvent) => {
try {
const batch: ActivityEvent[] = JSON.parse(e.data);
setEvents(batch.slice(0, maxEvents));
} catch {
// ignore malformed events
}
});
es.addEventListener("update", (e: MessageEvent) => {
try {
const batch: ActivityEvent[] = JSON.parse(e.data);
setEvents((prev) => [...batch, ...prev].slice(0, maxEvents));
} catch {
// ignore malformed events
}
});
es.onerror = () => {
es?.close();
retryTimeout.current = setTimeout(connect, 5000);
};
}
connect();
return () => {
es?.close();
if (retryTimeout.current) clearTimeout(retryTimeout.current);
};
}, [path, maxEvents]);
return events;
}