Files
erika/lib/realtime-refresh.ts
T

68 lines
1.5 KiB
TypeScript

export type RealtimeRefreshFilter =
| { kind: "form"; formId?: string }
| { kind: "xp" }
| { kind: "vc"; channelId?: string };
export type RealtimeRefreshHandlers = {
onOpen: () => void;
onForm: (event: { formId: string }) => 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<typeof setTimeout> | 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();
},
onVc(event) {
if (
filter.kind === "vc"
&& (!filter.channelId || event.channelId === filter.channelId)
) {
scheduleRefresh();
}
},
});
return () => {
if (refreshTimer) clearTimeout(refreshTimer);
subscription.clean();
};
}