
Serialises each upstream value of generic type t to JSON and fans it out over the channels in transports: a WebSocket broadcast on port 8999, an SSE stream on the same path, and/or an HTTP POST to url, each channel independent.
Live browser dashboard. Derive an event record per call and broadcast it to every connected WebSocket / SSE subscriber for a frontend to render.
Webhook fan-out with parsing. Pull a structured request, normalise it, and POST each resulting record to a remote ingest endpoint.
transports must be websocket, sse, or http; any other value aborts startup, and so does an empty list.url is empty silently skips the POST per message; WebSocket and SSE delivery continue unaffected.async_http_delivery holds, with exponential backoff from initial_retry_delay_ms to max_retry_delay_ms, retried up to max_retries times; once pending requests exceed queue_capacity the oldest queued request is dropped, unless wait_when_full holds the incoming message instead (the wait holds the tick, so it backs pressure up the graph; a replay recording turns it on). Turning it off runs the attempts on the tick, so the destination paces the graph.max_in_flight POSTs are sent at once, so a destination answering in 60 ms takes about 16 messages a second at one and eight times that at eight. At one under wait_when_full they arrive in order (without it a failed one is retried behind those queued after it); above one they arrive in the order their requests finish and a failed one is retried while later ones go out, which a replay recording accepts once every message carries `pts_ns`, and raises it to eight. Under wait_when_full the requests in flight count against queue_capacity.sse_replay_events holds it.sse_replay_events above zero numbers every SSE event and holds that many of the most recent ones, so a subscriber that reconnects reporting Last-Event-ID is given what it missed; sse_retry_hint_ms above zero tells a subscriber how long to wait before reconnecting, and a non-empty allow_origin is what a page on another origin needs to read either stream.url is bound, so a graph nobody is reading does not pay for the serialisation. With sse_replay_events above zero every message is serialised anyway, because what is produced while nobody is connected is what a reconnecting subscriber is given.metadata_keys. They travel only on the POST to url, as one JSON object in the metadata_json_header header (a replay recording sets that header to `X-Replay-Frame-Meta` and reads it, where `pts_ns` places the message on the replay's timeline); the body and both streams carry the message alone.sse_event_name is emitted as the SSE event line, so EventSource clients must use addEventListener rather than onmessage.url and sse_event_name are hot-swappable at runtime; every other key is captured once at startup.url is retried on any response other than 2xx, 4xx included, and on a transport error or a timeout. Once max_retries retries have failed the message is logged with its last failure, the curl error or the HTTP status, and its attempt count, and dropped, so a destination that keeps refusing a message never receives it. Messages still queued when the worker stops are logged and dropped.max_retry_delay_ms is below initial_retry_delay_ms; password is sent only with a non-empty username. The types hold timeout_seconds at one second or more, both retry delays at one hour or less, and websocket_max_frame_bytes and sse_retry_hint_ms within 32 bits.live-test prerelease