Skip to main content

nodedb_types/sync/wire/
session.rs

1//! Session lifecycle messages: handshake, token refresh, keepalive.
2
3use std::collections::HashMap;
4
5use serde::{Deserialize, Serialize};
6
7/// Handshake message (client → server, 0x01).
8#[derive(
9    Debug, Clone, Serialize, Deserialize, zerompk::ToMessagePack, zerompk::FromMessagePack,
10)]
11pub struct HandshakeMsg {
12    /// JWT bearer token for authentication.
13    pub jwt_token: String,
14    /// Client's vector clock: `{ collection: { doc_id: lamport_ts } }`.
15    pub vector_clock: HashMap<String, HashMap<String, u64>>,
16    /// Shape IDs the client is subscribed to.
17    pub subscribed_shapes: Vec<String>,
18    /// Client version string.
19    pub client_version: String,
20    /// Lite instance identity (UUID v7). Empty for legacy clients.
21    #[serde(default)]
22    pub lite_id: String,
23    /// Monotonic epoch counter (incremented on every open). 0 for legacy clients.
24    #[serde(default)]
25    pub epoch: u64,
26    /// Wire format version. Server rejects connections with incompatible versions.
27    /// 0 = legacy client (pre-wire-version; treated as version 1).
28    #[serde(default)]
29    pub wire_version: u16,
30}
31
32/// Handshake acknowledgment (server → client, 0x02).
33#[derive(
34    Debug, Clone, Serialize, Deserialize, zerompk::ToMessagePack, zerompk::FromMessagePack,
35)]
36pub struct HandshakeAckMsg {
37    /// Whether the handshake succeeded.
38    pub success: bool,
39    /// Session ID assigned by the server.
40    pub session_id: String,
41    /// Server's vector clock (for initial sync).
42    pub server_clock: HashMap<String, u64>,
43    /// Error message (if !success).
44    pub error: Option<String>,
45    /// Fork detection: if true, client must regenerate LiteId and reconnect.
46    #[serde(default)]
47    pub fork_detected: bool,
48    /// Server's wire format version (for client-side compatibility check).
49    #[serde(default)]
50    pub server_wire_version: u16,
51}
52
53/// Token refresh request (client → server, 0x60).
54///
55/// Sent by Lite before the current JWT expires. The client provides
56/// a fresh token obtained from the application's auth layer.
57/// Origin validates the new token and either upgrades the session
58/// or disconnects if the token is invalid.
59#[derive(
60    Debug, Clone, Serialize, Deserialize, zerompk::ToMessagePack, zerompk::FromMessagePack,
61)]
62pub struct TokenRefreshMsg {
63    /// New JWT bearer token.
64    pub new_token: String,
65}
66
67/// Token refresh acknowledgment (server → client, 0x61).
68#[derive(
69    Debug, Clone, Serialize, Deserialize, zerompk::ToMessagePack, zerompk::FromMessagePack,
70)]
71pub struct TokenRefreshAckMsg {
72    /// Whether the token refresh succeeded.
73    pub success: bool,
74    /// Error message (if !success).
75    pub error: Option<String>,
76    /// Seconds until this new token expires (so Lite can schedule next refresh).
77    #[serde(default)]
78    pub expires_in_secs: u64,
79}
80
81/// Ping/Pong keepalive (0xFF).
82#[derive(
83    Debug, Clone, Serialize, Deserialize, zerompk::ToMessagePack, zerompk::FromMessagePack,
84)]
85pub struct PingPongMsg {
86    /// Timestamp (epoch milliseconds) for RTT measurement.
87    pub timestamp_ms: u64,
88    /// Whether this is a pong (response to ping).
89    pub is_pong: bool,
90}