agent-ecosystem/src/main/http/events.ts
iliya 032d9b478b feat: enhance team member validation and improve logging
- Added validation to prevent the use of reserved names ("user" and "team-lead") for team members, ensuring clearer error messages during member addition.
- Updated IPC handlers to improve logging functionality, enhancing observability of team-related actions.
- Implemented normalization of file paths across various services to ensure consistent handling on different platforms.
- Enhanced UI components to provide better feedback on team member statuses and actions.

Made-with: Cursor
2026-03-03 23:58:19 +02:00

65 lines
1.6 KiB
TypeScript

/**
* SSE (Server-Sent Events) route for real-time event streaming.
*
* Routes:
* - GET /api/events: SSE stream with keep-alive pings
*/
import { createLogger } from '@shared/utils/logger';
import type { FastifyInstance, FastifyReply } from 'fastify';
const logger = createLogger('HTTP:events');
const KEEPALIVE_INTERVAL_MS = 30_000;
/** All connected SSE clients */
const clients = new Set<FastifyReply>();
/**
* Registers the SSE events endpoint.
*/
export function registerEventRoutes(app: FastifyInstance): void {
app.get('/api/events', async (request, reply) => {
reply.raw.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
Connection: 'keep-alive',
});
clients.add(reply);
logger.info(`SSE client connected (total: ${clients.size})`);
// Keep-alive ping
const timer = setInterval(() => {
reply.raw.write(':ping\n\n');
}, KEEPALIVE_INTERVAL_MS);
// Keepalive should not prevent shutdown (socket already keeps connection alive).
timer.unref();
// Cleanup on disconnect
request.raw.on('close', () => {
clearInterval(timer);
clients.delete(reply);
logger.info(`SSE client disconnected (total: ${clients.size})`);
});
// Prevent Fastify from ending the response
await reply;
});
}
/**
* Broadcasts an event to all connected SSE clients.
*/
export function broadcastEvent(channel: string, data: unknown): void {
const payload = `event: ${channel}\ndata: ${JSON.stringify(data)}\n\n`;
for (const client of clients) {
try {
client.raw.write(payload);
} catch {
clients.delete(client);
}
}
}