1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
//! AP2.1-8 realtime surface — first-class WebSocket + SSE in the facade
//! (PROGRAM.md §AP2.1-8, ADR-0006 §36).
//!
//! Typed wrappers over `axum::extract::ws` and `axum::response::sse` that
//! add the realtime safety core without a proprietary realtime protocol
//! and without a second application model. Raw `axum::extract::ws` /
//! `axum::response::sse` remain first-class escape hatches (AGENTS.md
//! §16); every entry point the wrappers use is a public, documented seam.
//!
//! # What this module owns
//!
//! * [`channel`] — a typed in-process broadcast channel (bounded buffer,
//! typed lag/closed/full errors, live-subscriber tracking). The fan-out
//! core shared by WS and SSE.
//! * [`origin`] — a server-side origin policy for upgrade requests (the
//! safe default rejects all; the application lists its origins).
//! * [`registry`] — a live-connection registry for drain, app-owned (not a
//! process-global singleton; AGENTS.md §20).
//! * [`shutdown`] — the shared drain signal the WS/SSE endpoints and the
//! registry use to coordinate graceful shutdown.
//! * [`websocket`] — a typed WebSocket wrapper: explicit authorization
//! (channel names never implicitly authorize), origin policy,
//! connection limits, frame/message size limits, bounded-buffer
//! backpressure, heartbeat, graceful shutdown, tracing spans, typed
//! protocol errors. Raw `axum::extract::ws` preserved.
//! * [`sse`] — a typed SSE event-stream wrapper: backpressure, graceful
//! shutdown, tracing, typed outcomes. Raw `axum::response::sse`
//! preserved.
//! * [`error`] — typed realtime errors; no raw `String`, no
//! attacker-controlled bytes in `Display`.
//!
//! # What this module does not own
//!
//! No distributed pub/sub platform (Redis/Valkey `PUBLISH`, NATS) — the
//! server owns an explicit in-process broadcast per channel; distributed
//! fanout is deferred (PROGRAM.md §AP2.1-8: "start concrete, traits only at
//! natural seams"). No proprietary realtime protocol, no `X-Arcature-*`
//! headers, no page protocol (AGENTS.md §15). The server does not own
//! client reconnect; the contract is documented per endpoint. No UAG-
//! generated frontend helpers this wave (deferred until the master
//! coordinates the `arcature-build` codegen).
//!
//! # Ownership
//!
//! A [`channel::Broadcast`], a [`registry::Registry`], and a
//! [`shutdown::ShutdownConfig`] are built once and stored in `AppState`
//! (or resolved via a typed service). The realtime module keeps no hidden
//! global channel or connection registry — every value is app-owned and
//! request-explicit (AGENTS.md §20). The shutdown seam is self-contained:
//! the application flips `ShutdownConfig` to draining and calls
//! `Registry::drain`; it does not edit `application::shutdown` this wave.
//!
//! # Security note — attacker-facing
//!
//! Realtime endpoints are attacker-facing (PROGRAM.md §AP2.1-8 / AGENTS.md
//! §11). The wrappers enforce: origin policy (server-verified same-origin
//! default), explicit per-connection authorization (channel names never
//! implicitly authorize), connection limits (no unbounded connections),
//! frame/message size limits (no unbounded frames), bounded-buffer
//! backpressure (no unbounded per-client queueing), malformed-message
//! rejection (typed close, no panic), cleanup on disconnect (guard drop
//! decrements live counts, no orphaned tasks), and graceful drain. No
//! payload bytes appear in tracing spans (observe spec §53/§59).
// Minimal public re-exports (the crate root re-exports the primary surface
// behind the `realtime` feature; submodule paths remain the canonical
// location). Re-exporting here keeps the module self-contained for
// qualified use (`arcature::realtime::Broadcast`).
pub use ;
pub use drain;
pub use ;
pub use ;
pub use ;
pub use ShutdownConfig;
pub use ;
pub use ;