UNPKG

better-auth

Version:

The most comprehensive authentication framework for TypeScript.

127 lines (125 loc) 3.98 kB
import { getGlobalBroadcastChannel } from "./broadcast-channel.mjs"; import { getGlobalFocusManager } from "./focus-manager.mjs"; import { getGlobalOnlineManager } from "./online-manager.mjs"; //#region src/client/session-refresh.ts const now = () => Math.floor(Date.now() / 1e3); /** * Rate limit: don't refetch on focus if a session request was made within this many seconds */ const FOCUS_REFETCH_RATE_LIMIT_SECONDS = 5; function createSessionRefreshManager(opts) { const { sessionAtom, sessionSignal, $fetch, options = {} } = opts; const refetchInterval = options.sessionOptions?.refetchInterval ?? 0; const refetchOnWindowFocus = options.sessionOptions?.refetchOnWindowFocus ?? true; const refetchWhenOffline = options.sessionOptions?.refetchWhenOffline ?? false; const state = { lastSync: 0, lastSessionRequest: 0, cachedSession: void 0 }; const shouldRefetch = () => { return refetchWhenOffline || getGlobalOnlineManager().isOnline; }; const triggerRefetch = (event) => { if (!shouldRefetch()) return; if (event?.event === "storage") { state.lastSync = now(); sessionSignal.set(!sessionSignal.get()); return; } const currentSession = sessionAtom.get(); if (event?.event === "poll") { state.lastSessionRequest = now(); $fetch("/get-session").then((res) => { if (res.error) sessionAtom.set({ ...currentSession, data: null, error: res.error }); else sessionAtom.set({ ...currentSession, data: res.data, error: null }); state.lastSync = now(); sessionSignal.set(!sessionSignal.get()); }).catch(() => {}); return; } if (event?.event === "visibilitychange") { if (now() - state.lastSessionRequest < FOCUS_REFETCH_RATE_LIMIT_SECONDS && currentSession?.data !== null && currentSession?.data !== void 0) return; } if (currentSession?.data === null || currentSession?.data === void 0 || event?.event === "visibilitychange") { if (event?.event === "visibilitychange") state.lastSessionRequest = now(); state.lastSync = now(); sessionSignal.set(!sessionSignal.get()); } }; const broadcastSessionUpdate = (trigger) => { getGlobalBroadcastChannel().post({ event: "session", data: { trigger }, clientId: Math.random().toString(36).substring(7) }); }; const setupPolling = () => { if (refetchInterval && refetchInterval > 0) state.pollInterval = setInterval(() => { if (sessionAtom.get()?.data) triggerRefetch({ event: "poll" }); }, refetchInterval * 1e3); }; const setupBroadcast = () => { state.unsubscribeBroadcast = getGlobalBroadcastChannel().subscribe(() => { triggerRefetch({ event: "storage" }); }); }; const setupFocusRefetch = () => { if (!refetchOnWindowFocus) return; state.unsubscribeFocus = getGlobalFocusManager().subscribe(() => { triggerRefetch({ event: "visibilitychange" }); }); }; const setupOnlineRefetch = () => { state.unsubscribeOnline = getGlobalOnlineManager().subscribe((online) => { if (online) triggerRefetch({ event: "visibilitychange" }); }); }; const init = () => { setupPolling(); setupBroadcast(); setupFocusRefetch(); setupOnlineRefetch(); getGlobalBroadcastChannel().setup(); getGlobalFocusManager().setup(); getGlobalOnlineManager().setup(); }; const cleanup = () => { if (state.pollInterval) { clearInterval(state.pollInterval); state.pollInterval = void 0; } if (state.unsubscribeBroadcast) { state.unsubscribeBroadcast(); state.unsubscribeBroadcast = void 0; } if (state.unsubscribeFocus) { state.unsubscribeFocus(); state.unsubscribeFocus = void 0; } if (state.unsubscribeOnline) { state.unsubscribeOnline(); state.unsubscribeOnline = void 0; } state.lastSync = 0; state.lastSessionRequest = 0; state.cachedSession = void 0; }; return { init, cleanup, triggerRefetch, broadcastSessionUpdate }; } //#endregion export { createSessionRefreshManager }; //# sourceMappingURL=session-refresh.mjs.map