Skip to main content

clasp_federation/
config.rs

1//! Federation configuration types
2
3use serde::{Deserialize, Serialize};
4use std::time::Duration;
5
6/// Federation operating mode
7#[derive(Debug, Clone, Default, Serialize, Deserialize)]
8pub enum FederationMode {
9    /// Hub mode: accepts leaf connections, central point of star
10    #[default]
11    Hub,
12    /// Leaf mode: connects to a single hub router
13    Leaf {
14        /// Hub endpoint URL (e.g., "wss://hub.example.com:7330")
15        hub_endpoint: String,
16    },
17    /// Mesh mode: connects to multiple peer routers
18    Mesh {
19        /// Peer endpoint URLs
20        peers: Vec<String>,
21    },
22}
23
24/// Configuration for a federation link
25#[derive(Debug, Clone)]
26pub struct FederationConfig {
27    /// Operating mode
28    pub mode: FederationMode,
29    /// Router identity name (used in origin field for loop prevention)
30    pub router_id: String,
31    /// Namespace patterns this router owns (e.g., "/site-a/**")
32    pub owned_namespaces: Vec<String>,
33    /// Token for authenticating to peers (if required)
34    pub auth_token: Option<String>,
35    /// Reconnect on disconnect
36    pub auto_reconnect: bool,
37    /// Reconnect delay
38    pub reconnect_delay: Duration,
39    /// Maximum reconnect attempts (0 = unlimited)
40    pub max_reconnect_attempts: u32,
41    /// How often to exchange revision vectors for sync verification
42    pub sync_interval: Duration,
43    /// Client name to advertise in HELLO
44    pub client_name: String,
45    /// Features to advertise in HELLO
46    pub features: Vec<String>,
47}
48
49impl Default for FederationConfig {
50    fn default() -> Self {
51        Self {
52            mode: FederationMode::Hub,
53            router_id: uuid::Uuid::new_v4().to_string(),
54            owned_namespaces: vec!["/**".to_string()],
55            auth_token: None,
56            auto_reconnect: true,
57            reconnect_delay: Duration::from_secs(5),
58            max_reconnect_attempts: 0,
59            sync_interval: Duration::from_secs(30),
60            client_name: "clasp-federation".to_string(),
61            features: vec![
62                "param".to_string(),
63                "event".to_string(),
64                "stream".to_string(),
65                "federation".to_string(),
66            ],
67        }
68    }
69}
70
71/// Information about a connected peer router
72#[derive(Debug, Clone)]
73pub struct PeerInfo {
74    /// Peer's router ID
75    pub router_id: String,
76    /// Peer's session ID on the local router (if the peer is a virtual session)
77    pub session_id: Option<String>,
78    /// Namespace patterns the peer owns
79    pub namespaces: Vec<String>,
80    /// Endpoint URL (for reconnection)
81    pub endpoint: Option<String>,
82    /// Whether we initiated the connection (outbound) or they connected to us (inbound)
83    pub outbound: bool,
84    /// Connection state
85    pub state: PeerState,
86}
87
88/// Peer connection state
89#[derive(Debug, Clone, Copy, PartialEq, Eq)]
90pub enum PeerState {
91    /// Connecting to peer
92    Connecting,
93    /// Connected, performing handshake
94    Handshaking,
95    /// Performing initial state sync
96    Syncing,
97    /// Fully operational
98    Active,
99    /// Disconnected, will reconnect
100    Disconnected,
101    /// Permanently failed
102    Failed,
103}