Files

58 lines
1.6 KiB
TypeScript

import type { Socket } from "net";
/**
* Write a length-prefixed message to a socket.
* Format: 4-byte big-endian length + JSON payload
*/
export function writeMessage(socket: Socket, msg: unknown): void {
const json = JSON.stringify(msg);
const payload = Buffer.from(json, "utf-8");
const header = Buffer.alloc(4);
header.writeUInt32BE(payload.length, 0);
socket.write(Buffer.concat([header, payload]));
}
/**
* Create a message reader that handles partial reads.
* Calls onMessage for each complete message received.
* Protocol or handler errors are reported to onError so the caller can close the socket.
*/
export function createMessageReader(
onMessage: (msg: unknown) => void,
onError: (error: Error) => void,
) {
let buffer = Buffer.alloc(0);
return (data: Buffer) => {
buffer = Buffer.concat([buffer, data]);
while (buffer.length >= 4) {
const length = buffer.readUInt32BE(0);
if (buffer.length < 4 + length) {
break;
}
const payload = buffer.subarray(4, 4 + length);
buffer = buffer.subarray(4 + length);
let msg: unknown;
try {
msg = JSON.parse(payload.toString("utf-8"));
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
onError(new Error(`Failed to parse intercom message: ${message}`, { cause: error }));
return;
}
try {
onMessage(msg);
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
onError(new Error(`Failed to handle intercom message: ${message}`, { cause: error }));
return;
}
}
};
}