Skip to main content

rok_broadcasting/
lib.rs

1//! rok-broadcasting — Laravel Echo-compatible real-time channel broadcasting.
2//!
3//! Provides public, private, and presence channels backed by an in-process
4//! broadcast bus.  Pair with a WebSocket layer (e.g. `rok-websocket`) or a
5//! dedicated pusher-compatible server to deliver events to clients.
6//!
7//! # Quick start
8//!
9//! ```rust,ignore
10//! use rok_broadcasting::Broadcasting;
11//!
12//! // Public channel
13//! Broadcasting::channel("orders")
14//!     .to_user(user_id)
15//!     .emit("order.shipped", &payload)
16//!     .await?;
17//!
18//! // Private channel
19//! let ch = Broadcasting::private_channel("inbox.42");
20//! ch.emit("message.new", &msg).await?;
21//!
22//! // Presence channel
23//! let ch = Broadcasting::presence_channel("room.1");
24//! ch.join(user_id, &meta).await?;
25//! ch.emit("user.joined", &meta).await?;
26//! ```
27
28pub mod channel;
29pub mod driver;
30pub mod error;
31pub mod event;
32pub mod presence;
33
34pub use channel::{BroadcastChannel, ChannelKind};
35pub use driver::{BroadcastDriver, InMemoryDriver};
36pub use error::BroadcastError;
37pub use event::BroadcastEvent;
38pub use presence::PresenceChannel;
39
40use std::sync::{Arc, OnceLock};
41
42static DRIVER: OnceLock<Arc<dyn BroadcastDriver>> = OnceLock::new();
43
44/// Set the global broadcast driver.  Call once at startup before using [`Broadcasting`].
45pub fn set_driver<D: BroadcastDriver + 'static>(driver: D) {
46    let _ = DRIVER.set(Arc::new(driver));
47}
48
49fn driver() -> Arc<dyn BroadcastDriver> {
50    DRIVER
51        .get()
52        .cloned()
53        .unwrap_or_else(|| Arc::new(InMemoryDriver::new()))
54}
55
56// ── Broadcasting facade ───────────────────────────────────────────────────────
57
58/// Static facade — entry point for all broadcasting operations.
59pub struct Broadcasting;
60
61impl Broadcasting {
62    /// Open a public broadcast channel.
63    pub fn channel(name: impl Into<String>) -> BroadcastChannel {
64        BroadcastChannel::new(name.into(), ChannelKind::Public, driver())
65    }
66
67    /// Open a private channel (auth required on client side).
68    pub fn private_channel(name: impl Into<String>) -> BroadcastChannel {
69        BroadcastChannel::new(name.into(), ChannelKind::Private, driver())
70    }
71
72    /// Open a presence channel (tracks who is subscribed).
73    pub fn presence_channel(name: impl Into<String>) -> PresenceChannel {
74        PresenceChannel::new(name.into(), driver())
75    }
76}