feat: complete Phase 2 transport layer — off-grid mode, transport icons, federation sync

- Add off-grid (mesh only) toggle to Mesh.vue with orange OFF-GRID banner
- Add per-peer transport indicator in Federation.vue (mesh/lan/tor icons)
- Add sync_with_peer_via_transport() for CBOR delta sync via transport router
- Fetch transport store on mount in both Mesh and Federation views

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-17 00:45:37 +00:00
parent 174dad9a66
commit f83e151f5a
3 changed files with 114 additions and 1 deletions

View File

@@ -428,6 +428,54 @@ pub async fn sync_with_peer(
Ok(state)
}
/// Sync with a peer using the transport router (Mesh > LAN > Tor).
/// Uses CBOR delta encoding for compact payloads over constrained links.
/// Falls back to `sync_with_peer()` if no transport router is available.
pub async fn sync_with_peer_via_transport(
data_dir: &Path,
peer: &FederatedNode,
local_did: &str,
previous_state: Option<&NodeStateSnapshot>,
router: &crate::transport::TransportRouter,
) -> Result<()> {
use crate::transport::{MessageType, TransportMessage};
use crate::transport::delta;
// Build the sync request payload — if we have a previous state from this peer,
// send a delta request (tells the peer we only need changes since timestamp).
let payload = if let Some(prev) = previous_state {
// Request delta since our last known state
let request = serde_json::json!({
"type": "state_sync_request",
"since": prev.timestamp,
});
delta::encode_cbor(&delta::StateDelta {
ts: prev.timestamp.clone(),
v: 1,
..Default::default()
})?
} else {
// First sync — request full state
let request = serde_json::json!({ "type": "state_sync_request" });
serde_json::to_vec(&request)?
};
let message = TransportMessage {
from_did: local_did.to_string(),
payload,
message_type: MessageType::StateSync,
};
let transport_used = router.send_to_peer(&peer.did, &message).await?;
tracing::info!(
peer = %peer.did,
transport = %transport_used,
"Federation sync sent via transport"
);
Ok(())
}
/// Build the local node's state snapshot for sharing with peers.
pub fn build_local_state(
apps: Vec<AppStatus>,