diff options
Diffstat (limited to 'src/daemon/protocol.ts')
| -rw-r--r-- | src/daemon/protocol.ts | 58 |
1 files changed, 2 insertions, 56 deletions
diff --git a/src/daemon/protocol.ts b/src/daemon/protocol.ts index 997a6c8..d3d8297 100644 --- a/src/daemon/protocol.ts +++ b/src/daemon/protocol.ts @@ -1,34 +1,17 @@ -/** - * Unix socket daemon protocol — wire message types, type guards, and constants. - * - * The daemon speaks JSON-line protocol over a Unix domain socket. - * One JSON object per newline. Four message types: request, response, event, control. - * - * References: - * - CDP message format: https://github.com/aslushnikov/getting-started-with-cdp#protocol-fundamentals - * - net.createServer IPC: https://nodejs.org/docs/latest-v22.x/api/net.html#serverlistenpath-backlog-callback - * - readline line-delimited: https://nodejs.org/docs/latest-v22.x/api/readline.html#event-line - */ import { isRecord } from "../util/guards"; -// ── Message types ────────────────────────────────────────────────────────────── -/** A CDP command sent from a pi client to the daemon. */ export type WireRequest = { readonly type: "request"; - /** Client-local CDP id. The daemon remaps this to a globally-unique id for Chrome. */ readonly id: number; readonly method: string; readonly params?: Record<string, unknown>; - /** Optional CDP session id. Omitted for browser-level commands. */ readonly sessionId?: string; }; -/** A CDP response (result or error) sent from the daemon back to the pi client. */ export type WireResponse = { readonly type: "response"; - /** Matches the id from the corresponding WireRequest. */ readonly id: number; readonly result?: unknown; readonly error?: { @@ -38,34 +21,23 @@ export type WireResponse = { }; }; -/** A CDP event forwarded from Chrome through the daemon to pi client(s). */ export type WireEvent = { readonly type: "event"; readonly method: string; readonly params?: Record<string, unknown>; - /** Session-scoped events carry this; browser-level events omit it. */ readonly sessionId?: string; }; -/** Daemon lifecycle control messages. Bidirectional. */ export type WireControl = { readonly type: "control"; readonly action: "register" | "registered" | "deregister" | "shutdown"; - /** pi client namespace (required for register/registered/deregister). */ readonly clientId?: string; - /** Human-readable reason for shutdown. */ readonly reason?: string; }; -/** All messages that may appear on the Unix socket. */ export type WireMessage = WireRequest | WireResponse | WireEvent | WireControl; -// ── Type guard ───────────────────────────────────────────────────────────────── -/** - * Validates that an unknown parsed-JSON value is a well-formed WireMessage. - * Does NOT validate the full CDP semantics — only structural shape. - */ export const isWireMessage = (v: unknown): v is WireMessage => { if (!isRecord(v)) return false; const t = v["type"]; @@ -113,12 +85,9 @@ export const isWireMessage = (v: unknown): v is WireMessage => { } }; -// ── Wire message constructors ────────────────────────────────────────────────── -/** Serialize a WireMessage to a JSON line (no trailing newline — caller adds \\n). */ export const serialize = (msg: WireMessage): string => JSON.stringify(msg); -/** Deserialize a single JSON-line string to a WireMessage. Returns null on parse failure. */ export const deserialize = (line: string): WireMessage | null => { let parsed: unknown; try { @@ -130,42 +99,19 @@ export const deserialize = (line: string): WireMessage | null => { return parsed; }; -// ── Constants ────────────────────────────────────────────────────────────────── -/** - * IPC endpoint for the daemon. - * - * On POSIX platforms this is a Unix domain socket path. On Windows, Node's IPC - * requires a named pipe of the form `\\.\pipe\<name>` — a Unix path like - * `/tmp/…` is not a valid `net` listen/connect target there and causes setup - * to fail. See https://nodejs.org/api/net.html#ipc-support. - */ +// Windows requires a named pipe (`\\.\pipe\<name>`); a Unix path is not a valid `net` listen/connect target there. export const DAEMON_SOCKET_PATH = process.platform === "win32" ? "\\\\.\\pipe\\pi-browser-daemon" : "/tmp/pi-browser-daemon.sock"; -/** - * How long the daemon stays alive with zero connected clients before exiting - * (milliseconds). After this period, the daemon cleans up and shuts down. - */ -export const DAEMON_IDLE_TIMEOUT_MS = 30 * 60 * 1000; // 30 minutes +export const DAEMON_IDLE_TIMEOUT_MS = 30 * 60 * 1000; -/** - * Hard cap on concurrent pi client connections. Extra connections are rejected - * immediately to prevent resource exhaustion. - */ export const DAEMON_MAX_CLIENTS = 16; -/** - * If true, the daemon unlinks (deletes) any stale socket file from a previous - * daemon crash before calling server.listen(). Without this, a crashed daemon - * leaves a socket inode that blocks the next listen() call with EADDRINUSE. - */ export const DAEMON_STALE_SOCKET_CLEANUP = true; -/** CDP WebSocket connection timeout (ms). */ export const CDP_CONNECT_TIMEOUT_MS = 10_000; -/** CDP command timeout when proxying through daemon (ms). */ export const CDP_COMMAND_TIMEOUT_MS = 10_000; |
