Server-Sent Event (SSE) connection helpers.
Sets up a Plug conn for chunked SSE streaming and provides functions to send events over it.
Example
conn
|> Dstar.SSE.start()
|> Dstar.SSE.send_event!("my-event", ["data line 1", "data line 2"])
Summary
Functions
Checks if an SSE connection is still open by sending a comment line.
Formats a single SSE event as a string (no connection needed).
Sends an SSE event to the client.
Sends an SSE event, raising on error. Returns the updated conn.
Starts an SSE connection from a Plug conn.
Functions
@spec check_connection(Plug.Conn.t()) :: {:ok, Plug.Conn.t()} | {:error, Plug.Conn.t()}
Checks if an SSE connection is still open by sending a comment line.
SSE comments (lines starting with :) are ignored by clients but
will fail if the connection has been closed. Useful for detecting
disconnections in streaming loops.
Returns {:ok, conn} if the connection is open, {:error, conn} if closed
or not yet started.
Example
case Dstar.SSE.check_connection(conn) do
{:ok, conn} ->
# Continue streaming
stream_loop(conn)
{:error, _conn} ->
# Connection closed, clean up
:ok
end
Formats a single SSE event as a string (no connection needed).
Useful for building SSE response bodies without chunked streaming.
Example
Dstar.SSE.format_event("datastar-patch-signals", ["signals {\"count\":42}"])
# => "event: datastar-patch-signals\ndata: signals {\"count\":42}\n\n"
@spec send_event(Plug.Conn.t(), String.t(), [String.t()] | String.t(), keyword()) :: {:ok, Plug.Conn.t()} | {:error, term()}
Sends an SSE event to the client.
Returns {:ok, conn} on success, {:error, reason} on failure.
Options
:event_id— Event ID for client tracking:retry— Retry duration in milliseconds
Example
{:ok, conn} = Dstar.SSE.send_event(conn, "my-event", ["line1", "line2"])
@spec send_event!(Plug.Conn.t(), String.t(), [String.t()] | String.t(), keyword()) :: Plug.Conn.t()
Sends an SSE event, raising on error. Returns the updated conn.
Useful for pipelines:
conn
|> send_event!("event-a", "data a")
|> send_event!("event-b", "data b")
@spec start(Plug.Conn.t()) :: Plug.Conn.t()
Starts an SSE connection from a Plug conn.
Sets the required SSE response headers (Content-Type: text/event-stream,
Cache-Control: no-cache) and sends a chunked 200 response.
The Connection header is intentionally NOT set — it is forbidden in
HTTP/2 (RFC 9113 §8.2.2) and browsers/curl reject the entire response
body when they see it. Connection: keep-alive is an HTTP/1.1-only
header and is already the default there.
Example
conn = Dstar.SSE.start(conn)