nodedb_types/sync/wire/presence.rs
1//! Presence / awareness messages.
2
3use serde::{Deserialize, Serialize};
4
5/// Presence update message (client → server, 0x80).
6///
7/// Sends ephemeral user state to a channel. The server broadcasts the state
8/// to all other subscribers of the same channel. Presence is NOT persisted,
9/// NOT CRDT-merged — it is fire-and-forget with latest-state-wins semantics.
10///
11/// Sending a `PresenceUpdate` implicitly subscribes the sender to the channel
12/// (if not already subscribed).
13#[derive(
14 Debug, Clone, Serialize, Deserialize, zerompk::ToMessagePack, zerompk::FromMessagePack,
15)]
16pub struct PresenceUpdateMsg {
17 /// Channel scoping key (e.g., `"doc:doc-123"`, `"workspace:ws-acme"`).
18 pub channel: String,
19 /// Opaque user state (MessagePack-encoded application-defined payload).
20 /// Common fields: user_id, user_name, cursor_position, selection_range,
21 /// active_document_id, color, avatar_url.
22 pub state: Vec<u8>,
23}
24
25/// A single peer's presence state within a channel.
26#[derive(
27 Debug, Clone, Serialize, Deserialize, zerompk::ToMessagePack, zerompk::FromMessagePack,
28)]
29pub struct PeerPresence {
30 /// User identifier.
31 pub user_id: String,
32 /// Opaque user state (same format as `PresenceUpdateMsg::state`).
33 pub state: Vec<u8>,
34 /// Milliseconds since this peer's last update.
35 pub last_seen_ms: u64,
36}
37
38/// Presence broadcast message (server → all subscribers except sender, 0x81).
39///
40/// Contains the full set of currently-present peers in the channel.
41/// Sent whenever any peer updates their state or leaves.
42#[derive(
43 Debug, Clone, Serialize, Deserialize, zerompk::ToMessagePack, zerompk::FromMessagePack,
44)]
45pub struct PresenceBroadcastMsg {
46 /// Channel this broadcast belongs to.
47 pub channel: String,
48 /// All currently-present peers and their latest state.
49 pub peers: Vec<PeerPresence>,
50}
51
52/// Presence leave message (server → all subscribers, 0x82).
53///
54/// Emitted when a peer disconnects (WebSocket close) or when their
55/// presence TTL expires (no heartbeat within `presence_ttl_ms`).
56#[derive(
57 Debug, Clone, Serialize, Deserialize, zerompk::ToMessagePack, zerompk::FromMessagePack,
58)]
59pub struct PresenceLeaveMsg {
60 /// Channel the user left.
61 pub channel: String,
62 /// User who left.
63 pub user_id: String,
64}