bra0-kg 0.2.2

bra0 Knowledge Graph core — RDF transformations (sophia) + KgStore trait (NextGraph-First)
Documentation
//! KgStore trait — persistence abstraction for dual-mode parity
//!
//! Implementations:
//! - NextGraph: primary (CRDT P2P, browser). Implemented in TypeScript via wasm-bindgen bridge.
//! - Oxigraph: standalone fallback (native or WASM). Feature-gated behind "standalone".
//!
//! Design: application code depends on KgStore, never on a specific backend.
//! This is Nael's Principle 5 (dual-mode parity): every pattern must work in both modes.

/// Result type for KgStore operations.
pub type StoreResult<T> = Result<T, StoreError>;

/// Errors from KgStore operations.
#[derive(Debug)]
pub enum StoreError {
    /// SPARQL query or update failed
    QueryError(String),
    /// Graph loading failed
    LoadError(String),
    /// Serialization/export failed
    ExportError(String),
}

impl std::fmt::Display for StoreError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            StoreError::QueryError(msg) => write!(f, "query error: {}", msg),
            StoreError::LoadError(msg) => write!(f, "load error: {}", msg),
            StoreError::ExportError(msg) => write!(f, "export error: {}", msg),
        }
    }
}

impl std::error::Error for StoreError {}

/// Abstraction over the bra0 persistence layer.
///
/// Two implementations exist:
/// - **NextGraph** (primary): CRDT-based, P2P sync, E2E encrypted.
///   Implemented on the TypeScript side — calls come through wasm-bindgen.
/// - **Oxigraph** (standalone): local quadstore, SPARQL 1.1 full.
///   Feature-gated behind `standalone`. Used for Tauri and topo CLI.
pub trait KgStore {
    /// Load RDF triples (Turtle string) into the store.
    /// Returns the number of triples loaded.
    fn load_turtle(&mut self, turtle: &str, graph_name: Option<&str>) -> StoreResult<usize>;

    /// Execute a SPARQL SELECT/ASK query. Returns results as a JSON string.
    fn sparql_query(&self, sparql: &str) -> StoreResult<String>;

    /// Execute a SPARQL UPDATE (INSERT/DELETE).
    fn sparql_update(&mut self, sparql: &str) -> StoreResult<()>;

    /// Export a named graph (or default graph) as Turtle.
    fn export_turtle(&self, graph_name: Option<&str>) -> StoreResult<String>;
}