aboutsummaryrefslogtreecommitdiff
path: root/src/daemon/server.ts
diff options
context:
space:
mode:
authoramankumarsingh77 <amankumarsingh7702@gmail.com>2026-07-28 22:08:16 +0530
committerAman Kumar <145339995+amankumarsingh77@users.noreply.github.com>2026-08-02 19:12:46 +0530
commitb913f2d4af218ae61de7073778feb56da89a15de (patch)
treed1c0f6796b3756563284c8edfd8be46a54e4f221 /src/daemon/server.ts
parentc88082515dcd9c0df1328b85420e97d7286ad428 (diff)
refactor: daemon internals, and fix a leak the merge exposed
IdMultiplexer and EventRouter were the only classes in src/; they are now createIdMultiplexer/createEventRouter closures like every other factory here. The multiplexer kept {clientId, localId} per daemon id while the bridge kept {send, clientId, localId, timer, isAttach} under the same key — two maps of overlapping data, and mux.resolve()'s return value was discarded at three of four call sites. One map now holds the union. That merge fixes a real leak: removeClient cleared the multiplexer but never the callbacks map, so a disconnected client's timers stayed armed and later fired a response at a socket that was gone. clearClient now cancels them, and a test pins it. handleRequest polled every 250ms for up to 15s per request when Chrome was down; N queued requests now await one connect signal. server.ts uses its own protocol's serialize/deserialize instead of hand-rolled JSON, and broadcast no longer routes through `this` — the only `this` in the codebase, and the one thing that breaks when the server object is destructured. cdp/event-queue.ts held two unrelated concerns; the request/timeout half moves to cdp/pending-requests.ts. cdp/daemon-transport.ts is the client half of the daemon protocol, so it moves to daemon/transport.ts. test/daemon/ needs adding to the test glob to run at all — there was no daemon test directory before because none of this was reachable without live Chrome. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'src/daemon/server.ts')
-rw-r--r--src/daemon/server.ts37
1 files changed, 16 insertions, 21 deletions
diff --git a/src/daemon/server.ts b/src/daemon/server.ts
index 142bddb..b98f37e 100644
--- a/src/daemon/server.ts
+++ b/src/daemon/server.ts
@@ -4,7 +4,8 @@ import { unlinkSync } from "node:fs";
import {
type WireMessage,
type WireControl,
- isWireMessage,
+ deserialize,
+ serialize,
DAEMON_SOCKET_PATH,
DAEMON_MAX_CLIENTS,
} from "./protocol";
@@ -59,14 +60,8 @@ export const createIpcServer = (): IpcServer => {
sockets.set(tempId, currentClient);
rl.on("line", (line: string) => {
- let msg: WireMessage | null;
- try {
- const parsed: unknown = JSON.parse(line);
- if (!isWireMessage(parsed)) return;
- msg = parsed;
- } catch {
- return;
- }
+ const msg = deserialize(line);
+ if (!msg) return;
if (msg.type === "control" && msg.action === "register" && !currentClient.registered) {
const clientId = msg.clientId;
@@ -78,7 +73,7 @@ export const createIpcServer = (): IpcServer => {
action: "shutdown",
reason: `clientId ${clientId} is already connected`,
};
- socket.write(JSON.stringify(reply) + "\n");
+ socket.write(serialize(reply) + "\n");
socket.destroy();
return;
}
@@ -90,7 +85,7 @@ export const createIpcServer = (): IpcServer => {
clients.set(clientId, currentClient);
const ack: WireControl = { type: "control", action: "registered", clientId };
- socket.write(JSON.stringify(ack) + "\n");
+ socket.write(serialize(ack) + "\n");
connectHandler?.(currentClient);
return;
@@ -146,6 +141,14 @@ export const createIpcServer = (): IpcServer => {
}
});
+ const send = (clientId: string, msg: WireMessage): void => {
+ const client = clients.get(clientId);
+ if (!client) return;
+ try {
+ client.socket.write(serialize(msg) + "\n");
+ } catch {}
+ };
+
return {
start,
stop,
@@ -158,17 +161,9 @@ export const createIpcServer = (): IpcServer => {
onDisconnect(handler) {
disconnectHandler = handler;
},
- send(clientId, msg) {
- const client = clients.get(clientId);
- if (!client) return;
- try {
- client.socket.write(JSON.stringify(msg) + "\n");
- } catch {}
- },
+ send,
broadcast(msg) {
- for (const [clientId] of clients) {
- this.send(clientId, msg);
- }
+ for (const [clientId] of clients) send(clientId, msg);
},
clientCount: (): number => clients.size,
};