export type RealtimeRefreshFilter = | { kind: "form"; formId?: string } | { kind: "uploads" } | { kind: "xp" } | { kind: "vc"; channelId?: string }; export type RealtimeRefreshHandlers = { onOpen: () => void; onForm: (event: { formId: string }) => void; onUpload: () => void; onXp: () => void; onVc: (event: { channelId: string }) => void; }; type StartRealtimeRefreshOptions = { filter: RealtimeRefreshFilter; debounceMs: number; refresh: () => void; subscribe: (handlers: RealtimeRefreshHandlers) => { clean: () => void }; }; export function startRealtimeRefresh({ filter, debounceMs, refresh, subscribe, }: StartRealtimeRefreshOptions) { let connectedOnce = false; let refreshTimer: ReturnType | undefined; const scheduleRefresh = () => { if (refreshTimer) clearTimeout(refreshTimer); refreshTimer = setTimeout(refresh, debounceMs); }; const subscription = subscribe({ onOpen() { if (connectedOnce) { scheduleRefresh(); } else { connectedOnce = true; } }, onForm(event) { if ( filter.kind === "form" && (!filter.formId || event.formId === filter.formId) ) { scheduleRefresh(); } }, onXp() { if (filter.kind === "xp") scheduleRefresh(); }, onUpload() { if (filter.kind === "uploads") scheduleRefresh(); }, onVc(event) { if ( filter.kind === "vc" && (!filter.channelId || event.channelId === filter.channelId) ) { scheduleRefresh(); } }, }); return () => { if (refreshTimer) clearTimeout(refreshTimer); subscription.clean(); }; }