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}
42
43impl Namespace {
44    /// Convert from raw u8 (for storage layer deserialization).
45    pub fn from_u8(v: u8) -> Option<Self> {
46        match v {
47            0 => Some(Self::Meta),
48            1 => Some(Self::Vector),
49            2 => Some(Self::Graph),
50            3 => Some(Self::Crdt),
51            4 => Some(Self::LoroState),
52            5 => Some(Self::Spatial),
53            6 => Some(Self::Strict),
54            7 => Some(Self::Columnar),
55            _ => None,
56        }
57    }
58}
59
60#[cfg(test)]
61mod tests {
62    use super::*;
63
64    #[test]
65    fn namespace_roundtrip() {
66        for v in 0u8..=7 {
67            let ns = Namespace::from_u8(v).unwrap();
68            assert_eq!(ns as u8, v);
69        }
70        assert!(Namespace::from_u8(8).is_none());
71    }
72}