ReqServerSentEvents (ReqServerSentEvents v0.1.0)

Copy Markdown View Source

Req plugin for Server-Sent Events (SSE).

Attach to any %Req.Request{} via attach/2. The plugin intercepts Req's three streaming hooks and transparently decodes raw SSE byte chunks into %ReqServerSentEvents.Frame{} structs.

Usage

# into: fun — frames delivered as {:sse_event, %Frame{}} arguments
Req.get!(url, into: fn {:sse_event, frame}, {req, resp} ->
  IO.inspect(frame)
  {:cont, {req, resp}}
end)
|> ReqServerSentEvents.attach()

# into: :self — frames sent as messages to the calling process
task = Task.async(fn -> Req.get!(url, into: :self) |> ReqServerSentEvents.attach() end)
resp = Task.await(task)
sse_ref = ReqServerSentEvents.ref(resp)
receive do
  {^sse_ref, {:sse_event, frame}} -> IO.inspect(frame)
  {^sse_ref, :sse_done}           -> :done
end

# into: collectable — frames collected into any Collectable
{:ok, resp} = Req.get(url, into: []) |> ReqServerSentEvents.attach()
frames = resp.body  # [%ReqServerSentEvents.Frame{}, ...]

Summary

Functions

Attach the SSE decoder to a %Req.Request{}.

Return the SSE ref for a into: :self request.

Functions

attach(req, opts \\ [])

@spec attach(
  Req.Request.t(),
  keyword()
) :: Req.Request.t()

Attach the SSE decoder to a %Req.Request{}.

Registers two Req steps:

  • A request step (sse_rewrite) that rewrites the into: field to decode SSE frames before delivering them to the user's handler.
  • A response step (sse_done) that sends a {ref, :sse_done} sentinel when into: :self is used (the into: fun callback has no :done signal).

ref(req)

@spec ref(Req.Request.t() | Req.Response.t()) :: reference() | nil

Return the SSE ref for a into: :self request.

Accepts either the final %Req.Request{} or %Req.Response{} — Req's high-level functions (Req.get!/2 etc.) return only the response, while Req.request/2 returns {request, response}.