import { serverLogger as log } from '$lib/server/logger'; import type { Workspace } from '$lib/types/workspace'; import { env } from '$env/dynamic/private'; import { Auth } from './auth'; import { Catalog } from './catalog'; import { Resources } from './resources'; import { WorkspaceManager } from './workspace'; class Server { // Guards against double-init in HMR / test environments. #initialized = false; #ws!: WorkspaceManager; #auth: Auth | undefined; #catalog!: Catalog; #resources!: Resources; async init(): Promise { if (this.#initialized) return; this.#initialized = true; log.info('Server initializing'); await Promise.all([this.#createWorkspaceManager(), this.#createAuth()]); const workspaces = this.#ws.list(); await Promise.all([this.#createCatalog(workspaces), this.#createResources(workspaces)]); log.info('Server ready'); } async shutdown(): Promise {} async #createWorkspaceManager(): Promise { const ws = new WorkspaceManager(); await ws.init(); this.#ws = ws; } async #createAuth(): Promise { if (!env.AUTH_JWT_SECRET || !env.AUTH_USERS_FILE) { log.info('Auth is disabled because AUTH_JWT_SECRET or AUTH_USERS_FILE is not set'); return; } const auth = new Auth({ jwtSecret: env.AUTH_JWT_SECRET, usersFile: env.AUTH_USERS_FILE, }); log.info(`Auth is enabled, users loaded from ${env.AUTH_USERS_FILE}`); await auth.init(); this.#auth = auth; } async #createCatalog(workspaces: Workspace[]): Promise { const catalog = new Catalog(workspaces); await catalog.init(); this.#catalog = catalog; } async #createResources(workspaces: Workspace[]): Promise { const resources = new Resources(workspaces); await resources.init(); this.#resources = resources; } get ws(): WorkspaceManager { return this.#ws; } get auth(): Auth | undefined { return this.#auth; } get catalog(): Catalog { return this.#catalog; } get resources(): Resources { return this.#resources; } } // Singleton shared across hooks and route handlers. const server = new Server(); export { Server, server };