import { type IncomingMessage, type Server, type ServerResponse } from "node:http"; import type { Socket } from "node:net"; import type { StaticMountInput } from "../frontend/StaticMountRegistry.js"; import { StaticMountRegistry } from "../frontend/StaticMountRegistry.js"; import type { EndpointResolver } from "./EndpointResolver.js"; import { ForgeEndpoints, type ForgeEndpointResult, type ServiceInstance } from "./ForgeEndpoints.js"; import { ForgeWebSocket, type WsOptions } from "./ForgeWebSocket.js"; import { IngressProtection } from "./Ingress.js"; import { Logger } from "./Logger.js"; import { isPrivateNetwork, isTrustedProxy } from "./network-utils.js"; import { PrometheusMetrics } from "./Prometheus.js"; import { RequestContext } from "./RequestContext.js"; import { Router } from "./Router.js"; import { StaticFileServer } from "./StaticFileServer.js"; import { WorkerChannelManager } from "./WorkerChannelManager.js"; import { type ServiceMode as ServiceModeValue, type ServiceType as ServiceTypeValue } from "./config-enums.js"; export { isPrivateNetwork, isTrustedProxy }; export declare const NOT_HANDLED: unique symbol; interface ForgeRequest extends IncomingMessage { body?: unknown; ctx?: RequestContext; auth?: Record | null; tenantId?: string | null; projectId?: string | null; userId?: string | null; correlationId?: string; params?: Record; query?: Record; } interface ForgeResponse extends ServerResponse { json?: (data: unknown, statusCode?: number) => void; status?: (code: number) => ForgeResponse; stream?: (statusCode?: number, headers?: Record) => ForgeResponse; _forgeTracked?: boolean; } interface IPCMessage { type: string; from?: string; payload?: unknown; requestId?: string; timestamp?: number; error?: string | null; [key: string]: unknown; } interface WsHandlerEntry { handler: WsHandler; options: WsOptions; } type WsHandler = (ws: ForgeWebSocket, req: ForgeRequest) => void; interface WsPluginHook { name: string; onWsUpgrade?: (payload: Record) => unknown | Promise; onWsConnect?: (payload: Record) => unknown | Promise; onWsMessage?: (payload: Record) => unknown | Promise; onWsClose?: (payload: Record) => unknown | Promise; [key: string]: unknown; } interface WsPluginResult { plugin: string; ok: boolean; result?: unknown; error?: Error; } interface IngressConfig { [key: string]: unknown; } interface ForgeContextOptions { serviceName: string; port: number; workerId: number; threadCount: number; mode: ServiceModeValue; serviceType?: ServiceTypeValue; sendIPC: (msg: Record) => void; localSend?: ((target: string, payload: unknown) => boolean) | null; localRequest?: ((target: string, payload: unknown) => Promise) | null; staticMounts?: StaticMountInput[]; ingress?: IngressConfig; forgeProxy?: string | null; } /** * ForgeContext * * Injected into every Service instance. Provides: * - HTTP router * - IPC messaging helpers (direct worker-to-worker when available) * - Metrics collection * - Structured logger * - Runtime metadata (service name, thread count, worker id, etc.) */ export declare class ForgeContext { serviceName: string; port: number; workerId: number; threadCount: number; mode: ServiceModeValue; serviceType: ServiceTypeValue; router: Router; logger: Logger; metrics: PrometheusMetrics; channels: WorkerChannelManager; ingress?: IngressProtection; _sendIPC: (msg: Record) => void; _localSend: ((target: string, payload: unknown) => boolean) | null; _localRequest: ((target: string, payload: unknown) => Promise) | null; _ingressConfig: IngressConfig; _ingressApplied: boolean; _forgeProxy: string | null; _serviceInstance: ServiceInstance | null; _servicePorts: Record; _endpointResolver: EndpointResolver | null; _staticMounts: StaticMountInput[]; _staticRegistry: StaticMountRegistry; _staticFileServer: StaticFileServer; _forgeEndpoints: ForgeEndpoints; _wsConnections: Set; _wsPerIpCounts: Map; _wsMaxPerIp: number; _wsPerIpCleanupTimer: ReturnType; _wsHandlers: Map; _wsPluginHooks: WsPluginHook[]; _server: Server | null; _needsHttpServer: boolean; _activeRequests: number; _messageHandlers: Map void>; _onMessage?: (from: string, payload: unknown) => void; _onRequest?: (from: string, payload: unknown) => unknown | Promise; _projectId?: string; _projectSchema?: string | null; _projectKeyPrefix?: string | null; _emitEvent?: (eventName: string, data: unknown) => void; constructor(options: ForgeContextOptions); setStaticMounts(mounts?: StaticMountInput[]): void; /** * Send a message to another service. * * Resolution order: * 1. Local dispatch (colocated service in same process) — zero overhead * 2. Direct UDS connection — bypasses supervisor * 3. Supervisor IPC fallback — only during startup */ send(target: string, payload: unknown): Promise; /** * Broadcast to all workers of a target service. * Note: channels.broadcast delivers to all workers including local via UDS. * We only use _localSend for colocated services that share this process * (no UDS needed), then broadcast to remote workers via channels. */ broadcast(target: string, payload: unknown): Promise; /** * Send a request to another service and await a response. * * If the target is colocated, this is a direct async function call * with zero serialization overhead. */ request(target: string, payload: unknown, timeoutMs?: number): Promise; /** * Start the HTTP server for this service. */ startServer(): Promise; /** * Route an incoming HTTP request. * Creates a RequestContext that flows through the entire call chain. */ _handleRequest(req: ForgeRequest, res: ForgeResponse, start: number): void; /** * Wire message/request handlers to both the direct channel manager * AND the supervisor fallback IPC path. */ _wireMessageHandlers(): void; /** * Handle an incoming IPC message from the supervisor. * This is the FALLBACK path — only used during startup before * direct MessagePorts are established, and for supervisor-level * commands (health checks, shutdown, etc.) */ _handleIPCMessage(msg: IPCMessage): void; _isMethodAllowed(method: string | undefined): boolean; _executeForgeEndpoint(res: ForgeResponse, rctx: RequestContext, handler: (...args: unknown[]) => unknown, method: string, { args, logPrefix }: { args: unknown[]; logPrefix: string; }): Promise; /** * Gracefully shut down. */ stop(): Promise; /** * Register a WebSocket handler for a path. * * ctx.ws('/ws', (socket, req) => { * socket.on('message', (data) => { * const msg = JSON.parse(data); * // req.ctx has the RequestContext with auth, correlationId * socket.send(JSON.stringify({ echo: msg })); * }); * }); */ ws(path: string, handlerOrOptions: WsHandler | WsOptions, maybeHandler?: WsHandler): void; /** * Write a short HTTP response over a raw upgrade socket and close it. */ _writeWsUpgradeError(socket: Socket, statusCode: number, reason: string, headers?: Record): void; /** * Run websocket plugin hooks for a lifecycle stage. */ _runWsPluginHooks(stage: "upgrade" | "connect" | "message" | "close", payload: Record): Promise; /** * Handle HTTP→WebSocket upgrade. * Implements RFC 6455 handshake without external dependencies. */ _handleWsUpgrade(req: ForgeRequest, socket: Socket, head: Buffer): Promise; _proxyWsUpgradeToDevServer(req: ForgeRequest, socket: Socket, head: Buffer, url: URL): Promise; /** * Register this service with ForgeProxy. * ForgeProxy then routes external traffic to us. */ _registerWithForgeProxy(): Promise; _getHost(): string; } export { ForgeWebSocket }; //# sourceMappingURL=ForgeContext.d.ts.map