/** * @deepseek-ai/dsh-host-webserver — Web route-registration plugin: a node:http * server plus the `httpServer` service (HTTP and upgrade route registries, * index transform taps, and the single fallback seat for everything no route * claims). Knows no harness concepts and serves no files; the composing * application's frontend plugin owns dist serving through the fallback hook. * Web shape only — Electron loads dist over file:// and carries fetch over an * IPC bridge. This package never prints: the URL line belongs to the shell. */ import type { IncomingMessage, ServerResponse } from 'node:http'; import type { Duplex } from 'node:stream'; import { Context, Service } from '@deepseek-ai/cordis'; import z from '@deepseek-ai/schemastery'; declare module '@deepseek-ai/cordis' { interface Context { httpServer: HttpServerService; } } /** Route match kind: 'exact' matches the pathname verbatim; 'prefix' p matches p and p/. */ export type WebRouteKind = 'exact' | 'prefix'; /** One named route registration. */ export interface WebRoute { kind: WebRouteKind; /** Absolute pathname, no trailing slash. */ path: string; /** Owns the full response lifecycle (may hold the response open, e.g. SSE). */ handler: (req: IncomingMessage, res: ServerResponse) => void | Promise; } /** One exact-path HTTP upgrade registration. */ export interface WebUpgradeRoute { /** Absolute pathname, no trailing slash. */ path: string; /** Owns protocol negotiation and the upgraded socket after dispatch. */ handler: (req: IncomingMessage, socket: Duplex, head: Buffer) => void | Promise; } /** Gateway config: the listen address. */ export interface Config { /** Listen host; the two supported values are loopback and all-interfaces. */ host: '127.0.0.1' | '0.0.0.0'; /** Listen port; zero requests an OS-assigned port. */ port: number; } /** * The browser HTTP carrier service. Activation listens immediately. Route * registration order does not affect requests because configured named routes * must be distinct, and the fallback handler answers anything not yet claimed * during startup with 404 until its owner registers. A listen failure rejects * initialization, and the boot process reports the failed fiber. */ export declare class HttpServerService extends Service { private config; static Config: z; private readonly exact; private readonly prefixes; private readonly upgrades; private readonly upgradedSockets; private readonly indexTaps; private fallback; private server; private listenedPort; constructor(ctx: Context, config: Config); /** The listening port (the OS-assigned value when config.port is 0). */ get port(): number; /** The configured bind host (the loopback or all-interfaces literal). */ get host(): Config['host']; /** * Register a named route. Duplicate (kind, path) throws — route patterns are * a composition-level contract, so a collision is a misconfiguration. * @param route - kind, path, and the owning handler. * @returns the disposer removing the route. */ register(route: WebRoute): () => void; /** * Register an exact-path HTTP upgrade route. Duplicate paths throw because * one socket can have only one protocol owner. * @param route - pathname and handler owning negotiation plus socket use. * @returns the disposer removing the route. */ registerUpgrade(route: WebUpgradeRoute): () => void; /** * Claim the fallback seat: the handler answering every request no named * route matches (the SPA dist server in the shipped Web composition). One * owner only — a second registration throws, because two fallbacks cannot * compose. * @param handler - owns the full response lifecycle of unmatched requests. * @returns the disposer releasing the seat. */ registerFallback(handler: WebRoute['handler']): () => void; /** * Register an index.html transform, applied by the fallback owner to every * index response ({@link applyIndexTaps}) in registration order. * @param transform - pure html-to-html function. * @returns the disposer removing the transform. */ tapIndex(transform: (html: string) => string): () => void; /** Listen; resolves once the socket is bound (rejection = FAILED fiber). */ [Service.init](): Promise; /** Longest-prefix-wins over the prefix table after an exact-table miss. */ private match; /** * Run an index.html body through the registered taps in registration order * — called by the fallback owner on every index response it renders. * @param html - the raw index.html body. * @returns the transformed body. */ applyIndexTaps(html: string): string; } export default HttpServerService; //# sourceMappingURL=index.d.ts.map