//! The local-first core: an on-device SQLite store + Tauri commands implementing the //! frontend's repository seam, so the desktop app is fully usable with no server and //! no login. adapters/local.ts (M10.5) calls into `commands`. pub mod commands; pub mod derive; pub mod models; pub mod retention; pub mod schema; pub mod store; use std::path::Path; use std::sync::Mutex; use rusqlite::Connection; /// The shared database handle, held in Tauri's managed state. rusqlite connections /// aren't `Sync`, so a `Mutex` serializes access (fine — operations are quick and the /// UI is single-user). pub struct Db(pub Mutex); /// Open (creating if needed) the database at `path` and bring it to the latest schema. pub fn open(path: &Path) -> rusqlite::Result { let conn = Connection::open(path)?; schema::migrate(&conn)?; Ok(Db(Mutex::new(conn))) } /// A one-line count summary of the store, for the startup log. pub fn summary(db: &Db) -> String { let conn = match db.0.lock() { Ok(c) => c, Err(_) => return "counts unavailable (lock poisoned)".to_string(), }; let count = |sql: &str| { conn.query_row(sql, [], |r| r.get::<_, i64>(0)) .unwrap_or(-1) }; format!( "{} notes, {} labels", count("SELECT COUNT(*) FROM notes"), count("SELECT COUNT(*) FROM labels"), ) }