Repository Public
1/**2 * Registry of every open browser WebSocket (events), keyed by the auth3 * session that opened it, so that revoking a session closes its sockets immediately (4401).4 */5import type WebSocket from 'ws';6import { WS_CLOSE } from './dto-auth.js';78export type LiveKind = 'events';9interface Entry {10 socket: WebSocket;11 authSessionId: string;12 kind: LiveKind;13 beforeClose?: () => void;14}1516export class LiveRegistry {17 private readonly entries = new Set<Entry>();1819 add(socket: WebSocket, authSessionId: string, kind: LiveKind, beforeClose?: () => void): () => void {20 const e: Entry = { socket, authSessionId, kind, beforeClose };21 this.entries.add(e);22 return () => this.entries.delete(e);23 }24 count(kind?: LiveKind): number {25 if (!kind) return this.entries.size;26 let n = 0;27 for (const e of this.entries) if (e.kind === kind) n++;28 return n;29 }30 kickAuthSessions(ids: readonly string[]): void {31 for (const e of [...this.entries]) {32 if (!ids.includes(e.authSessionId)) continue;33 e.beforeClose?.();34 e.socket.close(WS_CLOSE.UNAUTHORIZED, 'session ended');35 this.entries.delete(e);36 }37 }38 closeAll(code: number, reason: string): void {39 for (const e of this.entries) e.socket.close(code, reason);40 this.entries.clear();41 }42}43