# `Snodo.Client.Transport`
[🔗](https://github.com/joshrotenberg/snodo/blob/v0.3.1/lib/snodo/client/transport.ex#L1)

Behaviour for the connection underneath `Snodo.Client`.

A transport moves one complete JSON-RPC request to a server and returns the
complete JSON-RPC response. `Snodo.Client` builds the request and decodes the
response, so a transport never interprets `result` or `error`.

`request/3` receives these options:

  * `:timeout` - milliseconds to wait for the response.
  * `:dialect` - the protocol dialect module that built the request. HTTP
    uses its `transport_policy/1` to derive headers.
  * `:on_progress` - present when the caller asked for progress. A function
    of one argument to call, in the process that called `request/3`, with
    the `params` of each `notifications/progress` whose `progressToken` is
    the request's `params["_meta"]["progressToken"]`, before returning the
    response.
  * `:reset_timeout_on_progress` - when `true`, each delivered progress
    notification restarts `:timeout`, up to `:max_total_timeout`
    milliseconds after the request started. Past that the request fails
    with `max_total_timeout_error/1`.

A transport that ignores the progress options delivers no progress and keeps
a fixed timeout.

Failures of the connection itself are `%Snodo.Error{kind: :transport}`. Use
`connection_error/2` (-32000) and `timeout_error/1` (-32001), the codes the
official TypeScript SDK uses for the same client-side conditions.

# `state`

```elixir
@type state() :: term()
```

# `close`

```elixir
@callback close(state()) :: :ok
```

# `connect`

```elixir
@callback connect(init_arg :: term(), opts :: keyword()) ::
  {:ok, state()} | {:error, Snodo.Error.t()}
```

# `request`

```elixir
@callback request(state(), message :: map(), opts :: keyword()) ::
  {:ok, map()} | {:error, Snodo.Error.t()}
```

# `connection_error`

```elixir
@spec connection_error(String.t(), term()) :: Snodo.Error.t()
```

The connection is closed, unreachable, or produced an unusable response.

# `max_total_timeout_error`

```elixir
@spec max_total_timeout_error(pos_integer()) :: Snodo.Error.t()
```

Progress kept moving the deadline of a request, and the response had not
arrived `max_total_timeout` milliseconds after the request started.

# `timeout_error`

```elixir
@spec timeout_error(timeout()) :: Snodo.Error.t()
```

No response arrived within `timeout` milliseconds.

---

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