Files

87 lines
2.4 KiB
JavaScript

'use strict'
/**
* services/sse.js — Gerenciamento centralizado de Server-Sent Events
*
* sseClients: Map<accountId (string), { res, tenantId }>
*
* Funções exportadas:
* register(accountId, tenantId, res) — registra cliente
* unregister(accountId) — remove cliente
* sseSend(accountId, event, data) — envia para um cliente específico
* sseBroadcast(event, data) — envia para TODOS os clientes
* sseBroadcastTenant(tenantId, event, data, excludeAccountId?)
* — envia para todos do mesmo tenant
* isOnline(accountId) — verifica se cliente está conectado
* onlineIds(tenantId) — lista de accountIds online em um tenant
*/
const sseClients = new Map() // String(accountId) → { res, tenantId }
function register(accountId, tenantId, res) {
sseClients.set(String(accountId), { res, tenantId: String(tenantId) })
}
function unregister(accountId) {
sseClients.delete(String(accountId))
}
function sseSend(accountId, event, data) {
const client = sseClients.get(String(accountId))
if (!client) return false
try {
client.res.write(`event: ${event}\ndata: ${JSON.stringify(data)}\n\n`)
return true
} catch {
sseClients.delete(String(accountId))
return false
}
}
function sseBroadcast(event, data) {
const payload = `event: ${event}\ndata: ${JSON.stringify(data)}\n\n`
sseClients.forEach((client, id) => {
try { client.res.write(payload) } catch { sseClients.delete(id) }
})
}
function sseBroadcastTenant(tenantId, event, data, excludeAccountId = null) {
const payload = `event: ${event}\ndata: ${JSON.stringify(data)}\n\n`
const tid = String(tenantId)
const excl = excludeAccountId ? String(excludeAccountId) : null
sseClients.forEach((client, id) => {
if (client.tenantId === tid && id !== excl) {
try { client.res.write(payload) } catch { sseClients.delete(id) }
}
})
}
function isOnline(accountId) {
return sseClients.has(String(accountId))
}
function onlineIds(tenantId) {
const tid = String(tenantId)
const ids = []
sseClients.forEach((client, id) => {
if (client.tenantId === tid) ids.push(Number(id))
})
return ids
}
function connectedCount() {
return sseClients.size
}
module.exports = {
sseClients,
register,
unregister,
sseSend,
sseBroadcast,
sseBroadcastTenant,
isOnline,
onlineIds,
connectedCount,
}