//! Tauri event relay. //! //! The stable serialisable event DTOs live in `backend::events`. This module //! owns only the Tauri-specific relay: subscribing to the domain event bus and //! emitting named Tauri events. pub use backend::events::{ AgentLaunchFailedDto, DomainEventDto, ModelServerStatusChangedDto, OrchestrationSourceDto, AGENT_LAUNCH_FAILED, DOMAIN_EVENT, MODEL_SERVER_STATUS_CHANGED, }; use domain::events::DomainEvent; use infrastructure::TokioBroadcastEventBus; use tauri::{AppHandle, Emitter}; /// Subscribes the relay to the bus and spawns a background task that forwards /// every non-PTY [`DomainEvent`] to the frontend as Tauri events. /// /// High-frequency `PtyOutput` is intentionally not relayed through this global /// event; it goes through per-session PTY channels instead. pub fn spawn_relay(app: AppHandle, bus: &TokioBroadcastEventBus) { use tokio::sync::broadcast::error::RecvError; let mut rx = bus.raw_receiver(); tauri::async_runtime::spawn(async move { loop { match rx.recv().await { Ok(event) => { if matches!(event, DomainEvent::PtyOutput { .. }) { continue; } let dto = DomainEventDto::from(&event); let _ = app.emit(DOMAIN_EVENT, dto); match &event { DomainEvent::ModelServerStatusChanged { server_id, status } => { let _ = app.emit( MODEL_SERVER_STATUS_CHANGED, ModelServerStatusChangedDto { server_id: server_id.to_string(), status: status.into(), }, ); } DomainEvent::AgentLaunchFailed { agent_id, cause, code, message, } => { let _ = app.emit( AGENT_LAUNCH_FAILED, AgentLaunchFailedDto { agent_id: agent_id.to_string(), cause: cause.clone(), code: code.clone(), message: message.clone(), }, ); } _ => {} } } Err(RecvError::Lagged(_)) => continue, Err(RecvError::Closed) => break, } } }); }