import http from 'http'; import { nanoid } from 'nanoid'; import { Pull, Push } from 'zeromq'; const host = 'localhost'; const port = 3000; const sender = new Push(); await sender.bind(`tcp://127.0.0.1:5557`); const receiver = new Pull(); await receiver.bind(`tcp://127.0.0.1:5558`); const generateId = () => nanoid(32); const clients: Record = {}; const server = http.createServer((req, res) => { switch (req.url) { case '/run': const jobId = generateId(); const code = 'echo a'; const image = 'ghcr.io/moshell-lang/moshell:master'; const buffer = Buffer.allocUnsafe(jobId.length + image.length + code.length + 8); buffer.write(jobId, 0); buffer.writeUInt32BE(image.length, jobId.length); buffer.writeUInt32BE(code.length, jobId.length + 4); buffer.write(image, jobId.length + 8); buffer.write(code, jobId.length + 8 + image.length); res.writeHead(200, { 'Content-Type': 'text/event-stream', Connection: 'keep-alive', 'Cache-Control': 'no-cache', 'Access-Control-Allow-Origin': process.env.ALLOW_ORIGIN || '*', }); sender.send(buffer).then(() => { res.write('event: connected\n'); res.write(`data: ${jobId}\n`); res.write('id: 0\n\n'); }); req.on('close', () => { res.end('OK'); delete clients[jobId]; }); clients[jobId] = res; break; default: res.writeHead(404); res.end('404!'); } }); server.listen(port, () => { console.log(`Server is running on http://${host}:${port}`); }); for await (const [buff] of receiver) { const jobId = buff.subarray(0, 32).toString(); console.log(`Received ${jobId}`); const res = clients[jobId]; if (!res) { continue; } res.write('event: message\n'); res.write(`data: ${encodeURIComponent(buff.subarray(32).toString())}\n`); res.write('id: 1\n\n'); }