Server-Sent Events adapter for :rest mode real-time updates.
Turns a long-lived HTTP connection into an opt-in push channel:
server code broadcasts a JSON-Patch via Phoenix.PubSub, this
plug forwards each patch to subscribed browsers as an SSE
event: patch frame. The client-side subscribe() helper
parses the frame and hands the ops to the caller (typically
applyPatch($pageState.props, ops)).
Scope: SSE is one-way server → client. Pages that need
bidirectional real-time should use :live mode.
Publishing
CaravelaSvelte.SSE.publish("dashboard:user:42", [
["replace", "/counter", 7]
])The topic is an opaque string matched against subscriptions. Consumers should namespace it to avoid collisions with other apps sharing the PubSub.
Subscribing (route opt-in)
Wire up via CaravelaSvelte.Router:
caravela_rest "/dashboard", DashboardController, realtime: trueThis registers GET /dashboard/__events → this plug. The
client calls subscribe("dashboard:user:42", onPatch) which
opens an EventSource at that path, passing the topic as a
query-string parameter.
Options (plug init / route opts)
:pubsub— thePhoenix.PubSubmodule. Falls back toconfig :caravela_svelte, :pubsub, MyApp.PubSub.:heartbeat_ms— interval between keep-alive comments (default15_000). Proxies sometimes close idle connections silently; a comment every 15 s keeps the stream warm.:retry_ms— initialretry:hint sent once on connect. EventSource uses this when auto-reconnecting. Default3_000.:topic_prefix— required prefix for accepted topics. Defaults to""(any). Set this to avoid clients subscribing to topics the app did not intend to expose.
Heartbeat & reconnect
EventSource auto-reconnects. We send retry: <ms>\n\n once on
open; browsers honour it. Heartbeat comments flow every
:heartbeat_ms milliseconds; they carry no payload and exist
only to exercise the TCP path.
Termination
The plug exits when the client disconnects (the next chunk/2
returns {:error, :closed}). The process-dictionary has no
lingering PubSub subscription because the BEAM cleans up
automatically when the handler process exits.
Summary
Functions
Format a JSON-Patch ops list as an SSE frame. Pure — exported for tests.
Broadcast a JSON-Patch ops list on topic so subscribed SSE
clients receive it. Looks up the PubSub from app config when
not passed explicitly.
Functions
Format a JSON-Patch ops list as an SSE frame. Pure — exported for tests.
Broadcast a JSON-Patch ops list on topic so subscribed SSE
clients receive it. Looks up the PubSub from app config when
not passed explicitly.
ops is a list of compressed patch entries matching the
client-side applyPatch input shape — e.g.
[["replace", "/counter", 7]].