# `ReqServerSentEvents`
[🔗](https://github.com/sgerrand/ex_req_server_sent_events/blob/v0.1.0/lib/req_server_sent_events.ex#L1)

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{}, ...]

# `attach`

```elixir
@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`

```elixir
@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}`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
