export type RealtimeRefreshFilter = | { kind: "form"; formId?: string } | { kind: "uploads" } | { kind: "profile" } | { kind: "xp" } | { kind: "vc"; channelId?: string }; export type RealtimeRefreshEvent = | { kind: "open" } | { kind: "form"; formId: string } | { kind: "upload" } | { kind: "xp" } | { kind: "vc"; channelId: string }; export type RealtimeRefreshSubscription = { clean: () => void }; export function matchesRealtimeRefresh( filter: RealtimeRefreshFilter, event: Exclude, ) { if (filter.kind === "form") { return event.kind === "form" && (!filter.formId || event.formId === filter.formId); } if (filter.kind === "uploads") return event.kind === "upload"; if (filter.kind === "xp") return event.kind === "xp"; if (filter.kind === "profile") return event.kind === "xp" || event.kind === "vc"; return event.kind === "vc" && (!filter.channelId || event.channelId === filter.channelId); } export function startRealtimeRefresh({ filter, debounceMs, refresh, subscribe, }: { filter: RealtimeRefreshFilter; debounceMs: number; refresh: () => void; subscribe: (emit: (event: RealtimeRefreshEvent) => void) => RealtimeRefreshSubscription; }) { let connectedOnce = false; let refreshTimer: ReturnType | undefined; const scheduleRefresh = () => { if (refreshTimer) clearTimeout(refreshTimer); refreshTimer = setTimeout(refresh, debounceMs); }; const subscription = subscribe((event) => { if (event.kind === "open") { if (connectedOnce) scheduleRefresh(); connectedOnce = true; return; } if (matchesRealtimeRefresh(filter, event)) scheduleRefresh(); }); return () => { if (refreshTimer) clearTimeout(refreshTimer); subscription.clean(); }; }