Skip to main content

arora_websocket/
lib.rs

1//! The open local bridge for Arora: a WebSocket server that bridges the Arora
2//! API, implementing [`arora_bridge::Bridge`] (see [`bridge::WsBridge`]), with
3//! type-safe message definitions, a method registry, and a ready-to-use server.
4//!
5//! Messages speak the Arora data-layer vocabulary: the store is a shared,
6//! path-keyed blackboard, so clients **write** and **read** [`Value`]s at
7//! **keys** (hierarchical paths, e.g. `face/mouth`), list the available keys,
8//! and invoke registered RPC methods. The server binds the loopback interface
9//! by default: the link is unauthenticated and meant for editors and apps on
10//! trusted local links.
11//!
12//! # Features
13//!
14//! - **Message Types**: Type-safe [`Incoming`] and [`Outgoing`] message enums
15//! - **Registry**: Advertise keys and methods with [`Registry`]
16//! - **Server**: Full WebSocket server with [`AroraWSServer`]
17//! - **Bridge**: [`bridge::WsBridge`] drives the server as an Arora [`Bridge`](arora_bridge::Bridge)
18//!
19//! # Wire Format
20//!
21//! Messages are JSON-encoded with a `type` field discriminator:
22//!
23//! ```json
24//! // Client -> Server
25//! {"type": "write_values", "values": {"face/mouth": {"f64": 0.5}}}
26//! {"type": "read_values", "keys": ["face/mouth"]}
27//! {"type": "list_keys", "path": "face"}
28//! {"type": "list_methods"}
29//! {"type": "invoke", "method": "reset", "request_id": "req-1"}
30//!
31//! // Server -> Client
32//! {"type": "write_values_resp", "success": true}
33//! {"type": "read_values_resp", "values": {"face/mouth": {"f64": 0.5}}}
34//! {"type": "list_keys_resp", "keys": [...]}
35//! {"type": "list_methods_resp", "methods": [...]}
36//! {"type": "invoke_resp", "success": true, "request_id": "req-1"}
37//!
38//! // Server -> Client, unsolicited: the live state feed
39//! {"type": "values_changed", "values": {"face/mouth": {"f64": 0.5}}}
40//! ```
41//!
42//! # Server Example
43//!
44//! ```rust,no_run
45//! use arora_websocket::{AroraWSServer, ServerConfig, MethodInfo, InvokeResult};
46//! use tokio_util::sync::CancellationToken;
47//!
48//! #[tokio::main]
49//! async fn main() {
50//!     let server = AroraWSServer::with_port(9000);
51//!
52//!     // Register a method
53//!     server.registry().register_method_fn(
54//!         MethodInfo {
55//!             path: "reset".to_string(),
56//!             params: vec![],
57//!             return_type: None,
58//!             description: Some("Reset to defaults".to_string()),
59//!         },
60//!         |_args| InvokeResult::ok(),
61//!     ).await;
62//!
63//!     // Handle writes from clients
64//!     server.set_write_values_handler(|values| {
65//!         println!("Received {} writes", values.len());
66//!         Ok(())
67//!     }).await;
68//!
69//!     // Run the server
70//!     let cancel = CancellationToken::new();
71//!     server.run(cancel).await.unwrap();
72//! }
73//! ```
74
75/// The WS server as an Arora `Bridge`.
76pub mod bridge;
77pub mod handlers;
78mod key;
79mod messages;
80mod method;
81mod registry;
82mod server;
83
84pub use handlers::{
85    MethodHandler, OnClientConnectedHandler, ReadValuesHandler, WriteValuesHandler,
86    WriteValuesResult,
87};
88pub use key::KeyInfo;
89pub use messages::{Incoming, Outgoing};
90pub use method::{InvokeResult, MethodInfo, MethodParam};
91pub use registry::Registry;
92pub use server::{process_message, AroraWSServer, ServerConfig};
93pub use tokio_util::sync::CancellationToken;
94
95pub use arora_types::keyvalue::{KeyValue, KeyValueField};
96pub use arora_types::value::{Type, Value};