export interface HealthChecks { pocketbase: "ok" | "down"; supertokens: "ok" | "down"; } export interface HealthSnapshot { status: "ok" | "degraded"; checks: HealthChecks; checkedAt: string; } const CHECK_TTL_MS = 10_000; const CHECK_TIMEOUT_MS = 2_000; let cached: HealthSnapshot | null = null; let refreshing: Promise | null = null; const ping = async (url: string): Promise => { try { const response = await fetch(url, { signal: AbortSignal.timeout(CHECK_TIMEOUT_MS) }); return response.ok; } catch { return false; } }; const runChecks = async (): Promise => { const [pocketbase, supertokens] = await Promise.all([ ping(`${process.env.POCKETBASE_URL}/api/health`), ping(`${process.env.SUPERTOKENS_URI}/hello`), ]); cached = { status: pocketbase && supertokens ? "ok" : "degraded", checks: { pocketbase: pocketbase ? "ok" : "down", supertokens: supertokens ? "ok" : "down", }, checkedAt: new Date().toISOString(), }; return cached; }; // Stale-while-revalidate: k8s probes get the cached snapshot instantly while a // refresh runs in the background; only the very first request awaits a check. export const getHealthSnapshot = async (): Promise => { if (cached && Date.now() - Date.parse(cached.checkedAt) < CHECK_TTL_MS) { return cached; } if (!refreshing) { refreshing = runChecks().finally(() => { refreshing = null; }); } return cached ?? refreshing; };