use crate::config::Config; use crate::domain::{AppId, Target}; use crate::events::EventTx; use crate::ota::OtaRegistry; use crate::topology::Topology; use metrics_exporter_prometheus::PrometheusHandle; use sqlx::SqlitePool; use std::collections::HashMap; use std::sync::Arc; use tokio::sync::Mutex; use tokio::task::AbortHandle; #[derive(Clone)] pub struct AppState { pub pool: SqlitePool, pub topo: Arc, pub cfg: Arc, pub prom: PrometheusHandle, pub events: EventTx, pub ota: Arc, /// Single-slot guard per `(app, target)`: a newer build for the same /// target aborts the in-flight one (latest request wins), mirroring /// Sando's `active_build`. Other targets keep running — that's the fan-out. pub active: Arc>>, }