/** * ServerConfig - Runtime configuration services. * * Defines process-level server configuration and networking helpers used by * startup and runtime layers. * * @module ServerConfig */ import { Effect, FileSystem, Layer, Path, ServiceMap } from "effect"; export const DEFAULT_PORT = 3773; export type RuntimeMode = "web" | "desktop"; /** * ServerConfigShape - Process/runtime configuration required by the server. */ export interface ServerConfigShape { readonly mode: RuntimeMode; readonly port: number; readonly host: string | undefined; readonly cwd: string; readonly keybindingsConfigPath: string; readonly stateDir: string; readonly staticDir: string | undefined; readonly devUrl: URL | undefined; readonly noBrowser: boolean; readonly authToken: string | undefined; readonly allowedHosts: readonly string[]; readonly autoBootstrapProjectFromCwd: boolean; readonly logWebSocketEvents: boolean; } /** * ServerConfig - Service tag for server runtime configuration. */ export class ServerConfig extends ServiceMap.Service()( "t3/config/ServerConfig", ) { static readonly layerTest = (cwd: string, statedir: string) => Layer.effect( ServerConfig, Effect.gen(function* () { const path = yield* Path.Path; return { cwd, stateDir: statedir, mode: "web", autoBootstrapProjectFromCwd: false, logWebSocketEvents: false, port: 0, host: undefined, authToken: undefined, allowedHosts: [], keybindingsConfigPath: path.join(statedir, "keybindings.json"), staticDir: undefined, devUrl: undefined, noBrowser: false, }; }), ); } export const resolveStaticDir = Effect.fn(function* () { const { join, resolve } = yield* Path.Path; const { exists } = yield* FileSystem.FileSystem; const bundledClient = resolve(join(import.meta.dirname, "client")); const bundledStat = yield* exists(join(bundledClient, "index.html")).pipe( Effect.orElseSucceed(() => false), ); if (bundledStat) { return bundledClient; } const monorepoClient = resolve(join(import.meta.dirname, "../../web/dist")); const monorepoStat = yield* exists(join(monorepoClient, "index.html")).pipe( Effect.orElseSucceed(() => false), ); if (monorepoStat) { return monorepoClient; } return undefined; });