# `Raxol.AgentClientProtocol.Schema.MaybeUndefined`
[🔗](https://github.com/DROOdotFOO/raxol-agent/blob/raxol_agent_client_protocol-v0.1.0/packages/raxol_agent_client_protocol/lib/raxol/agent_client_protocol/schema/maybe_undefined.ex#L1)

A three-state value type: `:undefined`, `nil` (null), or `{:value, term}`.

Distinguishes a missing field (undefined) from an explicitly null field.
This is load-bearing for partial-update semantics where omitting a field
means "don't change" and setting it to null means "clear".

`Raxol.AgentClientProtocol.Schema.Unstable.SessionInfoUpdate` uses this
type: its decoder maps an absent key to `:undefined` and passes a present
value through `from_json/1` (`null` -> `nil`, anything else ->
`{:value, v}`); its encoder omits `:undefined` fields via the `{:skip}`
sentinel returned by `to_json/1`.

## JSON serialization

- `:undefined` -> field is omitted from JSON output
- `nil` -> `null`
- `{:value, x}` -> the JSON encoding of `x`

Ported from the MIT `f1729/agent_client_protocol` (c) 2025 f1729; see NOTICE.md.

# `t`

```elixir
@type t(value) :: :undefined | nil | {:value, value}
```

# `from_json`

```elixir
@spec from_json(:missing | term()) :: t(term())
```

Decodes from JSON deserialization. Call with `:missing` if the key was not
present, or with the raw value if it was.

# `map_value`

```elixir
@spec map_value(t(value), (value -&gt; mapped)) :: t(mapped)
when value: term(), mapped: term()
```

Maps a function over the value, preserving undefined/null.

# `null?`

```elixir
@spec null?(t(term())) :: boolean()
```

Returns true if the value is null.

# `to_json`

```elixir
@spec to_json(t(term())) :: {:skip} | nil | term()
```

Encodes for JSON serialization. Returns `{:skip}` for undefined (the caller
omits the field), `nil` for null, or the value itself.

# `undefined?`

```elixir
@spec undefined?(t(term())) :: boolean()
```

Returns true if the value is undefined.

# `update_to`

```elixir
@spec update_to(t(value), value | nil) :: value | nil when value: term()
```

Applies partial-update semantics against a current value.

- `:undefined` -> returns the current value unchanged (don't change)
- `nil` -> returns nil (clear)
- `{:value, v}` -> returns v (set)

# `value`

```elixir
@spec value(t(value)) :: value | nil when value: term()
```

Returns the inner value, or nil if undefined or null.

# `value?`

```elixir
@spec value?(t(term())) :: boolean()
```

Returns true if the value carries a value.

---

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