# `Decibel.ReplayWindow`
[🔗](https://github.com/ausimian/decibel/blob/1.2.1/lib/decibel/replay_window.ex#L1)

An immutable replay window for connectionless transports.

Applications own this value and store it alongside their session. Check an
incoming nonce before authentication with `check/2`, then replace the stored
window with the result of `commit/2` only after `Decibel.decrypt/3` succeeds.
The module holds no process, ETS, or hidden session state.

A window of size `size` retains exactly `size` nonce positions. After the
first commit, those positions run from `highest` down to
`highest - size + 1`; `highest - size` is the first stale value. Internally,
bit `i` in the bitmap records nonce `highest - i`.

Applications must serialize session operations with updates to their replay
window. Sharing an old value between concurrent operations can allow both to
pass `check/2` before either commits.

# `t`

```elixir
@opaque t()
```

# `check`

```elixir
@spec check(t(), Decibel.usable_nonce()) :: :ok | {:error, :duplicate | :stale}
```

Checks whether `nonce` is eligible for authentication.

Returns `:ok` for a new nonce, `{:error, :duplicate}` for an already
committed nonce still inside the window, or `{:error, :stale}` for a nonce
below the window. The window is not changed.

A value outside `t:Decibel.usable_nonce/0` raises `ArgumentError`.

# `commit`

```elixir
@spec commit(t(), Decibel.usable_nonce()) :: t()
```

Commits a nonce after successful authentication.

Returns a new window. A nonce that `check/2` classifies as duplicate or stale
raises `ArgumentError`, because committing it indicates a caller error. A
value outside `t:Decibel.usable_nonce/0` also raises `ArgumentError`.

# `new`

```elixir
@spec new(pos_integer()) :: t()
```

Creates an empty replay window.

The default window size is 64. An explicit size must be a positive integer;
invalid sizes raise `ArgumentError`.

---

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