'use strict' const { log } = require('./helpers') const subscribers = new Map() let clientIdSeq = 0 function addClient (topics, res, email) { const id = ++clientIdSeq const client = { id, res, email, topics } for (const t of topics) { if (!subscribers.has(t)) subscribers.set(t, new Set()) subscribers.get(t).add(client) } res.on('close', () => { for (const t of topics) { const set = subscribers.get(t) if (set) { set.delete(client); if (!set.size) subscribers.delete(t) } } log(`SSE client #${id} disconnected (${email})`) }) log(`SSE client #${id} connected (${email}) topics=[${topics.join(',')}]`) return id } function broadcast (topic, event, data) { const set = subscribers.get(topic) if (!set?.size) return 0 const payload = `event: ${event}\ndata: ${JSON.stringify(data)}\n\n` let count = 0 for (const c of set) { try { c.res.write(payload); count++ } catch {} } return count } function broadcastAll (event, data) { const sent = new Set() let count = 0 for (const [, set] of subscribers) { for (const c of set) { if (!sent.has(c.id)) { sent.add(c.id) try { c.res.write(`event: ${event}\ndata: ${JSON.stringify(data)}\n\n`); count++ } catch {} } } } return count } function clientCount () { const ids = new Set() for (const [, set] of subscribers) for (const c of set) ids.add(c.id) return ids.size } function topicCount () { return subscribers.size } module.exports = { addClient, broadcast, broadcastAll, clientCount, topicCount }