use crate::prelude::*;
use crate::local_state::LocalState;
use crate::persist::global::{DatabaseService, WsbRepos};
#[derive(Clone)]
pub struct AppContext {
pub db: Arc<WsbRepos>,
pub db_service: Arc<DatabaseService>,
pub state: LocalState,
pub worktree_root: PathBuf,
pub repo_root: PathBuf,
}
impl AppContext {
pub fn bootstrap(repo_root: &Path) -> Result<Self> {
Self::bootstrap_in(repo_root, crate::store::open()?)
}
pub fn bootstrap_in(repo_root: &Path, service: Arc<DatabaseService>) -> Result<Self> {
let worktree_root = crate::roots::find_super_root(repo_root).unwrap_or_else(|| repo_root.to_path_buf());
let leftovers = crate::migrate::leftovers_in(&worktree_root)?;
if !leftovers.is_empty() {
anyhow::bail!(
"{} still holds an older wsb's layout:\n {}\nRun `wsb migrate` to bring it across",
worktree_root.display(),
leftovers.join("\n ")
);
}
let state = LocalState::of(&worktree_root)?;
Ok(Self {
db: Arc::new(WsbRepos::new(&service, state.key())),
db_service: service,
state,
worktree_root,
repo_root: repo_root.to_path_buf(),
})
}
}
#[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,
}