//! IPC protocol — command dispatch and event emission. //! //! All communication with the TypeScript control plane goes through //! JSON-line messages on stdin/stdout (smartrust protocol). use serde::Deserialize; use tokio::sync::mpsc; /// Sender for serialized stdout output. pub type OutTx = mpsc::UnboundedSender; /// A command received from the TypeScript control plane. #[derive(Deserialize)] pub struct Command { pub id: String, pub method: String, #[serde(default)] pub params: serde_json::Value, } /// Send a response to a command. pub fn respond(tx: &OutTx, id: &str, success: bool, result: Option, error: Option<&str>) { let mut resp = serde_json::json!({ "id": id, "success": success }); if let Some(r) = result { resp["result"] = r; } if let Some(e) = error { resp["error"] = serde_json::Value::String(e.to_string()); } let _ = tx.send(resp.to_string()); } /// Send a success response. pub fn respond_ok(tx: &OutTx, id: &str, result: serde_json::Value) { respond(tx, id, true, Some(result), None); } /// Send an error response. pub fn respond_err(tx: &OutTx, id: &str, error: &str) { respond(tx, id, false, None, Some(error)); } /// Emit an event to the TypeScript control plane. pub fn emit_event(tx: &OutTx, event: &str, data: serde_json::Value) { let msg = serde_json::json!({ "event": event, "data": data }); let _ = tx.send(msg.to_string()); }