/** * Protocol-conformant stub SSR worker — speaks the EXACT same newline-delimited * JSON-RPC the real `workers/mizan-ssr/src/worker.tsx` speaks, but with no React * dependency. It lets `tests/ssr.test.ts` exercise the full SSRBridge subprocess * machinery (ready handshake, id correlation, render reply, ping, error frame) * under plain Node, independent of the real worker's install state. * * `render` echoes the props into a deterministic HTML string so the bridge's * request/response correlation is observable; a file named "*boom*" yields an * error frame to prove the failure path. */ function respond(msg) { process.stdout.write(JSON.stringify(msg) + '\n') } function handle(msg) { if (msg.method === 'ping') { respond({ id: msg.id, pong: true }) return } if (msg.method === 'render') { const { file, props } = msg.params ?? {} if (typeof file === 'string' && file.includes('boom')) { respond({ id: msg.id, error: `cannot render ${file}` }) return } respond({ id: msg.id, html: `
${JSON.stringify(props ?? {})}
` }) return } respond({ id: msg.id, error: `Unknown method: ${msg.method}` }) } let buffer = '' process.stdin.setEncoding('utf-8') process.stdin.on('data', (chunk) => { buffer += chunk let nl while ((nl = buffer.indexOf('\n')) !== -1) { const line = buffer.slice(0, nl).trim() buffer = buffer.slice(nl + 1) if (line) { try { handle(JSON.parse(line)) } catch (e) { respond({ id: -1, error: e.message }) } } } }) // Ready handshake — identical to the real worker. respond({ id: 0, ready: true })