use crate::axon::AxonEvent; use tokio::sync::broadcast; /// SSE channel — broadcasts AxonEvents to all connected SSE clients. #[derive(Clone)] pub struct SseChannel { sender: broadcast::Sender, } impl SseChannel { pub fn new(capacity: usize) -> Self { let (sender, _) = broadcast::channel(capacity); Self { sender } } /// Send an event to all subscribers. pub fn send(&self, event: &AxonEvent) -> Result<(), String> { let json = serde_json::to_string(event).map_err(|e| e.to_string())?; // Ignore errors when no receivers are connected let _ = self.sender.send(json); Ok(()) } /// Subscribe to the SSE channel. pub fn subscribe(&self) -> broadcast::Receiver { self.sender.subscribe() } } #[cfg(test)] mod tests { use super::*; #[tokio::test] async fn sse_channel_broadcast() { let ch = SseChannel::new(16); let mut rx = ch.subscribe(); let event = AxonEvent::new("test", serde_json::json!({ "msg": "hello" })); ch.send(&event).unwrap(); let received = rx.recv().await.unwrap(); let parsed: serde_json::Value = serde_json::from_str(&received).unwrap(); assert_eq!(parsed["event_type"], "test"); assert_eq!(parsed["payload"]["msg"], "hello"); } }