/** * Server Registry - tracks dev servers registered with the gateway * * Identity model: * Project = directory path (persistent scope) * Server = projectId:type or projectId:key (stable, survives restarts) * Endpoint = port on a server (can have multiple per server) * Process = PID serving an endpoint (ephemeral, rotates transparently) * Browser = affiliated with a server, not an endpoint or process */ /** Stable project short ID: basename-hash4 (e.g. "nextjs-turbopack-a3f7") */ export declare function makeProjectId(directory: string): string; /** * Stable server identity: projectId:type (default) or projectId:key (user override). * This is the join key between browsers and servers — survives restarts. */ export declare function makeServerId(directory: string, type: string, key?: string): string; export interface Endpoint { port: number; pid: number; registeredAt: number; } export interface RegisteredServer { id: string; projectId: string; directory: string; type: 'vite' | 'nextjs' | 'storybook' | 'astro' | 'generic'; key?: string; name?: string; endpoints: Endpoint[]; logPaths: Record; logDir: string; } /** Create per-project log directory and return channel file paths */ export declare function initProjectLogDir(directory: string, channels?: string[]): { logDir: string; logPaths: Record; }; export type ServerEvent = 'register' | 'deregister'; export type ServerEventCallback = (event: ServerEvent, data: { serverId: string; server?: RegisteredServer; }) => void; export declare function onServerEvent(cb: ServerEventCallback): () => void; export declare class ServerRegistry { private servers; private projectIdIndex; private connectionOrder; /** * Register an endpoint on a server. Creates the server if it doesn't exist. * Same server + same port = update PID (restart on same port). * Same server + new port = add endpoint (additional instance). */ addEndpoint(serverId: string, serverInfo: Omit, endpoint: Endpoint): RegisteredServer; /** * Remove a specific endpoint from a server. * If the server has no more endpoints, the server entry stays (browsers still affiliated). */ removeEndpoint(serverId: string, port: number): void; /** Remove a server entirely (explicit unregister) */ remove(id: string): void; get(id: string): RegisteredServer | undefined; getByProjectId(projectId: string): RegisteredServer[]; getByDirectory(directory: string): RegisteredServer[]; getAll(): RegisteredServer[]; getByType(type: RegisteredServer['type']): RegisteredServer[]; /** Find a server that has an endpoint on this port */ getByPort(port: number): RegisteredServer | undefined; getLatest(): RegisteredServer | undefined; has(id: string): boolean; size(): number; /** List all registered project directories */ directories(): string[]; /** Check if any endpoint on any server has a live process */ hasLiveEndpoints(serverId: string): boolean; /** * Remove endpoints whose processes are no longer running. * Skips endpoints registered within the last 30s (grace period for process forks). * Server entries are never removed — only endpoints are cleaned up. */ cleanupDeadEndpoints(): string[]; } //# sourceMappingURL=registry.d.ts.map