use crate::state::{AppState, StudioEvent};
use axum::{
extract::State,
response::sse::{Event, KeepAlive, Sse},
routing::get,
};
use std::convert::Infallible;
use tokio_stream::wrappers::BroadcastStream;
use tokio_stream::StreamExt as _;
pub fn routes() -> axum::Router<AppState> {
axum::Router::new().route("/api/events", get(sse_handler))
}
async fn sse_handler(
State(state): State<AppState>,
) -> Sse<impl tokio_stream::Stream<Item = Result<Event, Infallible>>> {
let rx = state.event_tx.subscribe();
let broadcast = BroadcastStream::new(rx);
let stream = broadcast.filter_map(|res| {
match res {
Ok(event) => {
let data = serde_json::to_string(&event).unwrap_or_default();
Some(Ok(Event::default().data(data)))
}
Err(_) => None, }
});
Sse::new(stream).keep_alive(KeepAlive::default())
}
pub fn emit_queued(state: &AppState, id: u64, query: &str, app_id: &str) {
let _ = state.event_tx.send(StudioEvent::ItemQueued {
id,
query: query.to_string(),
app_id: app_id.to_string(),
});
state.worker_notify.notify_one();
}