2.1 KiB
2.1 KiB
Gateway client-lifecycle helpers
Purpose
Free-function module containing connectClient and disconnectClient — every state mutation that happens when a client attaches or detaches from the daemon. Extracted from gateway.ts so the daemon file stays under the 300-line cap.
Features
connectClientregisters the client in the client map, presence tracker (when enabled), and bumps the OTelpresence_updates_total{kind: "join"}counter.disconnectClientis the cleanup orchestrator: leaves every room, removes the client from every channel, untracks presence (with counter bump), drops the auth context, emits the typed bus event, and fires thepresence:leaveside effects.- Returns
falsefromdisconnectClientwhen the client was never connected so the daemon's error-path handler is idempotent.
Usage: Basic Example
import { connectClient, disconnectClient } from "@suaveplan/websocket-gateway";
connectClient(deps, "alice");
disconnectClient(deps, "alice", "normal");
Usage: Advanced Example
import { connectClient } from "@suaveplan/websocket-gateway";
const client = connectClient(deps, "alice", {
userAgent: "Chrome/123",
region: "us-east-1",
});
// client.metadata is a defensive copy of the input
API Reference
connectClient(deps, id, metadata?): ClientInfo— registers a client withlastHeartbeat = clock().disconnectClient(deps, clientId, reason = "normal"): boolean— full cleanup; idempotent.ClientLifecycleDeps— structurally-typed dependency bundle.
Implementation Notes
connectClient clones metadata so the daemon cannot leak mutations back to the caller. disconnectClient calls room.leave on every registered room rather than maintaining a per-client room index because the room set is bounded by maxRooms and the linear sweep keeps disconnect O(rooms) without paying the index-maintenance cost on every join/leave. The OTel counter increments fire next to the actual map mutations so the counter reflects true client lifecycle, not best-effort presence webhook fan-out.