use crate::prelude::*;
use tokio::sync::broadcast;
use crate::logging::{LogLine, LogRingBuffer};
use crate::persist::global::{DatabaseConfig, DatabaseService, WsbRepos};
#[derive(Clone)]
pub struct AppContext {
pub db: Arc<WsbRepos>,
pub db_service: Arc<DatabaseService>,
pub workspace_root: PathBuf,
}
impl AppContext {
pub fn bootstrap(workspace_root: &Path) -> Result<Self> {
let db_path = workspace_root.join(".wsb").join("wsb.db");
let config = DatabaseConfig::new(&db_path);
let service = DatabaseService::new(&config)?;
let service = Arc::new(service);
let repos = Arc::new(WsbRepos::new(&service));
Ok(Self {
db: repos,
db_service: service,
workspace_root: workspace_root.to_path_buf(),
})
}
}
#[derive(Clone)]
pub struct AppState {
pub ctx: AppContext,
pub debug: bool,
pub port: u16,
pub log_tx: broadcast::Sender<LogLine>,
pub log_ring: LogRingBuffer,
}
impl AppState {
pub fn new(
ctx: AppContext,
debug: bool,
port: u16,
log_tx: broadcast::Sender<LogLine>,
log_ring: LogRingBuffer,
) -> Self {
Self {
ctx,
debug,
port,
log_tx,
log_ring,
}
}
}
#[derive(Clone, Debug, serde::Serialize)]
pub struct SyncProgress {
pub phase: SyncPhase,
#[serde(skip_serializing_if = "Option::is_none")]
pub current_project: Option<String>,
pub sessions_total: usize,
pub sessions_done: usize,
pub messages_indexed: usize,
}
#[derive(Clone, Debug, serde::Serialize)]
#[serde(rename_all = "snake_case")]
pub enum SyncPhase {
Idle,
Discovering,
Syncing,
Done,
}