···11//! Wire protocol for collaborative editing messages.
2233+use jacquard::smol_str::SmolStr;
34use serde::{Deserialize, Serialize};
4556/// Messages exchanged between collaborators over gossip.
···2627 /// Collaborator joined the session
2728 Join {
2829 /// DID of the joining user
2929- did: String,
3030+ did: SmolStr,
3031 /// Display name for presence UI
3131- display_name: String,
3232+ display_name: SmolStr,
3233 },
33343435 /// Collaborator left the session
3536 Leave {
3637 /// DID of the leaving user
3737- did: String,
3838+ did: SmolStr,
3839 },
39404041 /// Request sync from peers (late joiner)
···183184 #[test]
184185 fn test_roundtrip_join() {
185186 let msg = CollabMessage::Join {
186186- did: "did:plc:abc123".to_string(),
187187- display_name: "Alice".to_string(),
187187+ did: "did:plc:abc123".into(),
188188+ display_name: "Alice".into(),
188189 };
189190 let bytes = msg.to_bytes().unwrap();
190191 let decoded = CollabMessage::from_bytes(&bytes).unwrap();
+6-5
crates/weaver-common/src/transport/node.rs
···66use iroh::EndpointId;
77use iroh::SecretKey;
88use iroh_gossip::net::{GOSSIP_ALPN, Gossip};
99+use jacquard::smol_str::{SmolStr, ToSmolStr};
910use miette::Diagnostic;
1011use std::sync::Arc;
1112···8081 }
81828283 /// Get the node ID as a z-base32 string for storage in AT Protocol records.
8383- pub fn node_id_string(&self) -> String {
8484- self.endpoint.id().to_string()
8484+ pub fn node_id_string(&self) -> SmolStr {
8585+ self.endpoint.id().to_smolstr()
8586 }
86878788 /// Get a reference to the gossip handler for joining topics.
···103104 ///
104105 /// This should be published in session records so other peers can connect
105106 /// via relay (essential for browser-to-browser connections).
106106- pub fn relay_url(&self) -> Option<String> {
107107+ pub fn relay_url(&self) -> Option<SmolStr> {
107108 self.endpoint
108109 .addr()
109110 .relay_urls()
110111 .next()
111111- .map(|url| url.to_string())
112112+ .map(|url| url.to_smolstr())
112113 }
113114114115 /// Get the full node address including relay info.
···131132 ///
132133 /// Waits indefinitely for relay - browser clients require relay URLs
133134 /// for peer discovery. Returns the relay URL once connected.
134134- pub async fn wait_for_relay(&self) -> String {
135135+ pub async fn wait_for_relay(&self) -> SmolStr {
135136 self.endpoint.online().await;
136137 // After online(), relay_url should always be Some for browser clients
137138 self.relay_url()
···11//! Presence types for main thread rendering.
22//!
33-//! These types use String node IDs instead of EndpointId,
33+//! These types use SmolStr node IDs instead of EndpointId,
44//! allowing them to be used without the iroh feature.
5566+use jacquard::smol_str::SmolStr;
67use serde::{Deserialize, Serialize};
7889/// A remote collaborator's cursor for rendering.
910#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1011pub struct RemoteCursorInfo {
1112 /// Node ID as string (z-base32 encoded)
1212- pub node_id: String,
1313+ pub node_id: SmolStr,
1314 /// Character offset in the document
1415 pub position: usize,
1516 /// Selection range (anchor, head) if any
···2223#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2324pub struct CollaboratorInfo {
2425 /// Node ID as string
2525- pub node_id: String,
2626+ pub node_id: SmolStr,
2627 /// The collaborator's DID
2727- pub did: String,
2828+ pub did: SmolStr,
2829 /// Display name for UI
2929- pub display_name: String,
3030+ pub display_name: SmolStr,
3031 /// Assigned colour (RGBA)
3132 pub color: u32,
3233 /// Current cursor position (if known)