feat: add Redis-backed SSE updates
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useRef } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { sse, type SseTopic } from "@/lib/sse";
|
||||
|
||||
type RealtimeRefreshProps = {
|
||||
topic: SseTopic;
|
||||
formId?: string;
|
||||
debounceMs?: number;
|
||||
};
|
||||
|
||||
export function RealtimeRefresh({
|
||||
topic,
|
||||
formId,
|
||||
debounceMs = 150,
|
||||
}: RealtimeRefreshProps) {
|
||||
const router = useRouter();
|
||||
const connectedOnce = useRef(false);
|
||||
|
||||
useEffect(() => {
|
||||
connectedOnce.current = false;
|
||||
let refreshTimer: ReturnType<typeof setTimeout> | undefined;
|
||||
|
||||
const refresh = () => {
|
||||
if (refreshTimer) clearTimeout(refreshTimer);
|
||||
refreshTimer = setTimeout(() => router.refresh(), debounceMs);
|
||||
};
|
||||
|
||||
const onopen = () => {
|
||||
if (connectedOnce.current) {
|
||||
refresh();
|
||||
} else {
|
||||
connectedOnce.current = true;
|
||||
}
|
||||
};
|
||||
|
||||
const handleUpdate = (event: { formId: string }) => {
|
||||
if (!formId || event.formId === formId) {
|
||||
refresh();
|
||||
}
|
||||
};
|
||||
|
||||
const subscription = topic === "forms"
|
||||
? sse.forms.sub("update", handleUpdate, { onopen })
|
||||
: sse.submissions.sub("update", handleUpdate, { onopen });
|
||||
|
||||
return () => {
|
||||
if (refreshTimer) clearTimeout(refreshTimer);
|
||||
subscription.clean();
|
||||
};
|
||||
}, [debounceMs, formId, router, topic]);
|
||||
|
||||
return null;
|
||||
}
|
||||
Reference in New Issue
Block a user