36 lines
1.1 KiB
TypeScript
36 lines
1.1 KiB
TypeScript
"use client";
|
|
|
|
import { useRouter } from "next/navigation";
|
|
import { useEffect } from "react";
|
|
|
|
import { parseInvalidationEvent } from "@/lib/events/invalidation";
|
|
import { createRefreshScheduler } from "@/lib/events/refresh";
|
|
import { withBasePath } from "@/lib/base-path";
|
|
|
|
export function LiveRefresh({ endpoint }: { endpoint: string }) {
|
|
const router = useRouter();
|
|
|
|
useEffect(() => {
|
|
const scheduler = createRefreshScheduler(() => router.refresh());
|
|
const source = new EventSource(withBasePath(endpoint));
|
|
const connected = () => scheduler.connected();
|
|
const notified = (message: Event) => {
|
|
if (!(message instanceof MessageEvent) || typeof message.data !== "string") {
|
|
return;
|
|
}
|
|
const event = parseInvalidationEvent(message.data);
|
|
if (event) scheduler.notified(event);
|
|
};
|
|
source.addEventListener("open", connected);
|
|
source.addEventListener("invalidation", notified);
|
|
return () => {
|
|
source.removeEventListener("open", connected);
|
|
source.removeEventListener("invalidation", notified);
|
|
source.close();
|
|
scheduler.dispose();
|
|
};
|
|
}, [endpoint, router]);
|
|
|
|
return null;
|
|
}
|