import net from 'node:net'; import fs from 'node:fs'; import path from 'node:path'; import { mkdir, rm } from 'node:fs/promises'; const MAX_LINE = 64 * 1024; export async function createEventSocket({ socketPath, onMessage }) { await mkdir(path.dirname(socketPath), { recursive: true }); try { await rm(socketPath, { force: true }); } catch {} const server = net.createServer((socket) => { let buffer = ''; socket.setEncoding('utf8'); socket.on('data', (chunk) => { buffer += chunk; if (buffer.length > MAX_LINE * 2) { socket.destroy(new Error('IPC buffer too large')); return; } let index; while ((index = buffer.indexOf('\n')) >= 0) { const line = buffer.slice(0, index); buffer = buffer.slice(index + 1); if (line.length > MAX_LINE) { socket.destroy(new Error('IPC message too large')); return; } try { onMessage?.(JSON.parse(line), socket); } catch { socket.write(JSON.stringify({ error: 'invalid IPC message' }) + '\n'); } } }); }); await new Promise((resolve, reject) => { server.once('error', reject); server.listen(socketPath, resolve); }); return { server, socketPath, close: () => new Promise((resolve) => server.close(() => fs.unlink(socketPath, () => resolve()))) }; } export function sendEvent(socket, event, payload = {}) { const message = JSON.stringify({ event, ...payload }); if (Buffer.byteLength(message) > MAX_LINE) throw new Error('IPC event too large; use a file path for bulk data'); socket.write(`${message}\n`); } export { MAX_LINE };