// Anonymous-relevant auth policy (currently just whether self- // registration is enabled). Loaded once per browser session on root- // layout mount, then read reactively from `authConfig.self_register_enabled`. // // Defaults to `self_register_enabled = true` while loading so the // register link doesn't flash off-and-on for the default-open case. // If the fetch fails (network blip, backend restart), the stale value // is kept — there's no per-request retry. A new tab will retry on its // own mount. // // Same browser-only contract as `session.svelte.ts` — see that file's // SSR comment. import { browser } from '$app/environment'; import { getAuthConfig } from './api/auth'; class AuthConfigStore { self_register_enabled = $state(true); private_mode = $state(false); loaded = $state(false); private loading = false; async load(): Promise { if (this.loaded || this.loading || !browser) return; this.loading = true; try { const cfg = await getAuthConfig(); this.self_register_enabled = cfg.self_register_enabled; this.private_mode = cfg.private_mode; this.loaded = true; } catch { // Keep optimistic default; next page mount will retry. } finally { this.loading = false; } } /** Seed from server-rendered layout data so the very first paint * doesn't flash the loading state. Used by `+layout.ts` / * `+layout.svelte` on the universal-load path. Safe to call from * SSR (no `browser` guard) since it touches only reactive state. */ seed(cfg: { self_register_enabled: boolean; private_mode: boolean }): void { this.self_register_enabled = cfg.self_register_enabled; this.private_mode = cfg.private_mode; this.loaded = true; } } export const authConfig = new AuthConfigStore();