Initial Commit
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
# 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
|
||||
|
||||
- `connectClient` registers the client in the client map, presence tracker (when enabled), and bumps the OTel `presence_updates_total{kind: "join"}` counter.
|
||||
- `disconnectClient` is 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 the `presence:leave` side effects.
|
||||
- Returns `false` from `disconnectClient` when the client was never connected so the daemon's error-path handler is idempotent.
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```ts
|
||||
import { connectClient, disconnectClient } from "@suaveplan/websocket-gateway";
|
||||
|
||||
connectClient(deps, "alice");
|
||||
disconnectClient(deps, "alice", "normal");
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```ts
|
||||
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 with `lastHeartbeat = 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.
|
||||
Reference in New Issue
Block a user