// WSTS codec — encoder/decoder for the WebSocket frames MWSE exchanges. // // Infrastructure for issue #42 (binary framing). The codec is pluggable: today // it speaks JSON text frames (mode=CODEC_JSON); the binary path (mode=CODEC_BINARY) // is stubbed and will be wired once the server side lands. // // Frame shapes (codec-agnostic, defined by WSTS protocol): // Inbound from server: [payload, signalName] — signal // [payload, id, 'E'|'C'] — reply // Outbound to server: [msg, 'R'] — fire-and-forget (WOM) // [msg, id, 'R'] — request (reply once) // [msg, id, 'S'] — stream (reply multiple) import { CODEC_JSON, CODEC_BINARY } from './version.js'; export class WSTSCodec { constructor() { this.mode = CODEC_JSON; } // encode turns a JS frame array into a wire value (string or ArrayBuffer). encode(frame) { if (this.mode === CODEC_JSON) { return JSON.stringify(frame); } if (this.mode === CODEC_BINARY) { return this._encodeBinary(frame); } throw new Error(`WSTSCodec: unknown mode ${this.mode}`); } // decode turns raw wire data into a JS frame array. decode(raw) { if (typeof raw === 'string') { return JSON.parse(raw); } if (raw instanceof ArrayBuffer) { if (this.mode === CODEC_BINARY) { return this._decodeBinary(raw); } throw new Error('WSTSCodec: received binary frame but codec is in JSON mode'); } throw new Error(`WSTSCodec: unexpected frame type ${typeof raw}`); } // negotiate picks the best codec from the server's offered list and activates it. // Returns true when a common codec was found. negotiate(serverCodecs) { // Prefer binary when both sides support it (future upgrade path). if (serverCodecs.includes(CODEC_BINARY)) { this.mode = CODEC_BINARY; return true; } if (serverCodecs.includes(CODEC_JSON)) { this.mode = CODEC_JSON; return true; } return false; } // ---- Binary codec (issue #42) ---------------------------------------- // Wire layout: 1-byte opcode | 4-byte uint32 big-endian payload length | payload bytes // Opcodes: 0x01 = signal, 0x02 = reply-end ('E'), 0x03 = reply-continue ('C'), // 0x04 = request ('R'), 0x05 = stream ('S'), 0x06 = wom ('R' no id) // Payload: MessagePack (or CBOR) encoded frame contents. // This is intentionally NOT implemented yet — throws so callers know when they // accidentally reach binary paths before #42 is merged. _encodeBinary(_frame) { throw new Error('WSTSCodec binary encoding not yet implemented (#42)'); } _decodeBinary(_buf) { throw new Error('WSTSCodec binary decoding not yet implemented (#42)'); } }