Skip to main content

nodedb_types/
namespace.rs

1//! Storage namespace identifiers for the blob KV store.
2//!
3//! Both SQLite (native) and OPFS (WASM) backends use the same namespace
4//! scheme to partition data by engine.
5
6use serde::{Deserialize, Serialize};
7
8/// Storage namespace. Each engine writes to its own namespace in the
9/// blob KV store, preventing key collisions.
10#[derive(
11    Debug,
12    Clone,
13    Copy,
14    PartialEq,
15    Eq,
16    Hash,
17    Serialize,
18    Deserialize,
19    rkyv::Archive,
20    rkyv::Serialize,
21    rkyv::Deserialize,
22)]
23#[repr(u8)]
24pub enum Namespace {
25    /// Database metadata: schema version, config, Shape subscriptions.
26    Meta = 0,
27    /// Vector engine: HNSW graph layers, vector data.
28    Vector = 1,
29    /// Graph engine: CSR arrays, node/label interning tables.
30    Graph = 2,
31    /// CRDT deltas: unsent mutations awaiting sync.
32    Crdt = 3,
33    /// Loro state snapshots: compacted CRDT state for fast cold-start.
34    LoroState = 4,
35    /// Spatial engine: R-tree checkpoints, geohash indexes.
36    Spatial = 5,
37    /// Strict document engine: Binary Tuple rows keyed by PK.
38    Strict = 6,
39    /// Columnar engine: compressed segments, delete bitmaps, segment metadata.
40    Columnar = 7,
41    /// KV engine: direct key-value storage (bypasses Loro CRDT).
42    /// Used when sync is disabled or for the local-only KV fast path.
43    Kv = 8,
44}
45
46impl Namespace {
47    /// Convert from raw u8 (for storage layer deserialization).
48    pub fn from_u8(v: u8) -> Option<Self> {
49        match v {
50            0 => Some(Self::Meta),
51            1 => Some(Self::Vector),
52            2 => Some(Self::Graph),
53            3 => Some(Self::Crdt),
54            4 => Some(Self::LoroState),
55            5 => Some(Self::Spatial),
56            6 => Some(Self::Strict),
57            7 => Some(Self::Columnar),
58            8 => Some(Self::Kv),
59            _ => None,
60        }
61    }
62}
63
64#[cfg(test)]
65mod tests {
66    use super::*;
67
68    #[test]
69    fn namespace_roundtrip() {
70        for v in 0u8..=8 {
71            let ns = Namespace::from_u8(v).unwrap();
72            assert_eq!(ns as u8, v);
73        }
74        assert!(Namespace::from_u8(9).is_none());
75    }
76}