# `ZenWebsocket.RecorderServer`
[🔗](https://github.com/ZenHive/zen_websocket/blob/v0.4.2/lib/zen_websocket/recorder_server.ex#L1)

Async GenServer for recording WebSocket sessions to JSONL files.

Provides non-blocking recording with buffered I/O to minimize performance
impact on the WebSocket client. Records are batched and flushed periodically
or when the buffer reaches a threshold.

## Usage

This module is typically used internally by `ZenWebsocket.Client` when the
`record_to` config option is set. You can also use it directly:

    {:ok, recorder} = RecorderServer.start_link("/tmp/session.jsonl")
    RecorderServer.record(recorder, :out, {:text, "hello"})
    RecorderServer.record(recorder, :in, {:text, "world"})
    RecorderServer.flush(recorder)
    stats = RecorderServer.stats(recorder)
    RecorderServer.stop(recorder)

## API Functions
| Function | Arity | Description | Param Kinds |
| --- | --- | --- | --- |
| `stats` | 1 | Return recording statistics. | `server: value` |
| `stop` | 1 | Stop the recorder, flush remaining buffer, and close the file. | `server: value` |
| `flush` | 1 | Force an immediate flush of the buffer to disk. | `server: value` |
| `record` | 3 | Record a WebSocket frame asynchronously. | `server: value`, `direction: value`, `frame: value` |
| `start_link` | 1 | Start a recorder server writing to a JSONL file. | `path: value` |

# `stats`

```elixir
@type stats() :: %{entries: non_neg_integer(), bytes: non_neg_integer()}
```

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `flush`

```elixir
@spec flush(pid()) :: :ok
```

Forces an immediate flush of the buffer to disk.

This is a synchronous operation that blocks until all buffered
records have been written.

# `record`

```elixir
@spec record(pid(), ZenWebsocket.Recorder.direction(), ZenWebsocket.Recorder.frame()) ::
  :ok
```

Records a WebSocket frame asynchronously.

This is a non-blocking operation - it sends a message to the GenServer
and returns immediately. The frame will be buffered and written to disk
during the next flush.

## Parameters

- `server` - The RecorderServer pid
- `direction` - `:in` for received frames, `:out` for sent frames
- `frame` - The WebSocket frame `{:text, data}`, `{:binary, data}`, or `{:close, code, reason}`

# `start_link`

```elixir
@spec start_link(String.t()) :: {:ok, pid()} | {:error, term()}
```

Starts a RecorderServer linked to the current process.

Opens the file at `path` for writing. Returns `{:error, reason}` if
the file cannot be opened.

# `stats`

```elixir
@spec stats(pid()) :: stats()
```

Returns recording statistics.

## Returns

A map with:
- `:entries` - Total number of entries recorded
- `:bytes` - Total bytes written to disk

# `stop`

```elixir
@spec stop(pid()) :: :ok
```

Stops the recorder, flushing any remaining buffer and closing the file.

---

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