Download src/utils/protocol.ts from Collabos/chatapi: direct link, hf CLI and curl.
- Browser
- Download file 2.53 kB
-
https://huggingface.co/spaces/Collabos/chatapi/resolve/main/src/utils/protocol.ts
- Command line
-
hf download hf://spaces/Collabos/chatapi/src/utils/protocol.ts
-
curl -L -o protocol.ts https://huggingface.co/spaces/Collabos/chatapi/resolve/main/src/utils/protocol.ts
2.53 kB
| import WebSocket from 'ws'; | |
| // ββ Inbound message types (client β server) ββββββββββββββββββββββββββββββββββ | |
| export type ClientMessageType = | |
| | 'heartbeat' | |
| | 'offer' | |
| | 'answer' | |
| | 'ice-candidate' | |
| | 'message' | |
| | 'get-upload-url' | |
| | 'relay' | |
| | 'friend'; | |
| // ββ Outbound message types (server β client) ββββββββββββββββββββββββββββββββββ | |
| export type ServerMessageType = | |
| | 'connected' | |
| | 'ice-servers' | |
| | 'offer' | |
| | 'answer' | |
| | 'ice-candidate' | |
| | 'message' | |
| | 'upload-url' | |
| | 'relay' | |
| | 'peer-online' | |
| | 'peer-offline' | |
| | 'offline-flush' | |
| | 'error'; | |
| export interface ClientMessage { | |
| type: ClientMessageType; | |
| payload: Record<string, unknown>; | |
| // requestId allows client to correlate responses | |
| requestId?: string; | |
| } | |
| export interface ServerMessage { | |
| type: ServerMessageType; | |
| payload: Record<string, unknown>; | |
| requestId?: string; | |
| ts: number; // epoch ms | |
| } | |
| /** | |
| * Parse and validate an incoming raw WS message. | |
| * Returns null if the data is malformed β caller should silently drop. | |
| */ | |
| export function parseClientMessage(raw: WebSocket.RawData): ClientMessage | null { | |
| try { | |
| const str = raw.toString('utf8'); | |
| if (str.length > 65536) return null; // 64 KB hard cap β protects against flood | |
| const obj = JSON.parse(str) as unknown; | |
| if ( | |
| typeof obj !== 'object' || | |
| obj === null || | |
| typeof (obj as Record<string, unknown>).type !== 'string' | |
| ) { | |
| return null; | |
| } | |
| return obj as ClientMessage; | |
| } catch { | |
| return null; | |
| } | |
| } | |
| /** | |
| * Serialize a server message. | |
| * Using a single Buffer allocation avoids repeated JSON.stringify on hot paths. | |
| */ | |
| export function buildServerMessage( | |
| type: ServerMessageType, | |
| payload: Record<string, unknown>, | |
| requestId?: string | |
| ): Buffer { | |
| const msg: ServerMessage = { type, payload, requestId, ts: Date.now() }; | |
| return Buffer.from(JSON.stringify(msg), 'utf8'); | |
| } | |
| /** | |
| * Send a message to a WebSocket, catching send errors silently. | |
| * Avoids crashing the process when a socket closes mid-send. | |
| */ | |
| export function safeSend( | |
| ws: WebSocket, | |
| type: ServerMessageType, | |
| payload: Record<string, unknown>, | |
| requestId?: string | |
| ): void { | |
| if (ws.readyState !== WebSocket.OPEN) return; | |
| try { | |
| ws.send(buildServerMessage(type, payload, requestId)); | |
| } catch { | |
| // Socket probably closed between the readyState check and send β ignore | |
| } | |
| } | |