const { canReceiveEvent, toClientEvent } = require("../services/events"); const HEARTBEAT_INTERVAL_MS = 25_000; function writeSseEvent(raw, event) { const clientEvent = toClientEvent(event); if (!clientEvent) { return; } raw.write(`id: ${clientEvent.id}\n`); raw.write(`event: ${clientEvent.type}\n`); raw.write(`data: ${JSON.stringify(clientEvent)}\n\n`); } async function eventsRoutes(fastify) { fastify.get( "/events", { preHandler: fastify.authenticate, }, async (request, reply) => { const canManageInvoice = fastify.hasPermission(request.employee, "invoice.manage"); reply.hijack(); reply.raw.writeHead(200, { "content-type": "text/event-stream; charset=utf-8", "cache-control": "no-cache, no-transform", "connection": "keep-alive", "x-accel-buffering": "no", }); reply.raw.write(": connected\n\n"); const unsubscribe = fastify.appEvents.subscribe((event) => { if (!canReceiveEvent(request.employee, event, { canManageInvoice })) { return; } writeSseEvent(reply.raw, event); }); const heartbeat = setInterval(() => { reply.raw.write(": heartbeat\n\n"); }, HEARTBEAT_INTERVAL_MS); request.raw.on("close", () => { clearInterval(heartbeat); unsubscribe(); }); }, ); } module.exports = eventsRoutes;