# `Slap.Yjs.Presence`
[🔗](https://github.com/mjrusso/slap/blob/slap_yjs-v0.4.0/slap_yjs/lib/slap/yjs/presence.ex#L1)

Publishes an awareness state for a server-side participant, such as an
agent or tool. The process subscribes to a document and keeps one client id
for its lifetime.

Awareness is Yjs's term for ephemeral participant state. To inspect and
authorize client awareness messages, use the `Slap.Yjs.Awareness` codec.
The process claims its id before publishing. Local client claims cannot
take it over; remote awareness conflicts remain possible.

    {:ok, presence} =
      Slap.Yjs.Presence.start_link(
        module: MyApp.DocServer,
        doc_id: {"my-service", "doc-1"},
        state: %{"user" => %{"name" => "Assistant"}}
      )

    :ok =
      Slap.Yjs.Presence.update(presence, %{
        "user" => %{"name" => "Assistant"},
        "busy" => true
      })

The process republishes its state every `:renew_every` milliseconds
(15,000 by default). y-protocols clients remove a state if its clock does
not advance for 30 seconds. If the document server stops, the process
rejoins and republishes. Transient rejoin failures are retried after 1 s,
backing off to at most 30 s. Updates received while disconnected are
published on rejoin. Stopping the presence process removes its state.
Deleting the document stops the process without a supervisor restart.

Options:

  * `:module` (required) - the document server module, as for
    `Slap.Yjs.Docs.join/3`.
  * `:doc_id` (required) - the document.
  * `:state` (required) - a JSON map with string keys, or `fn client_id -> map end`.
    The function runs in the presence process once during startup; rejoining
    preserves the id and latest state. Nested maps require string keys;
    strings must be valid UTF-8, and integers must fit in signed 64 bits.
    Invalid maps raise `ArgumentError` in the caller. Invalid function results
    fail startup.
  * `:owner` - a pid to monitor. Its exit stops the presence without a
    supervisor restart, including while retrying a join. The owner is
    independent of the process that starts or supervises the presence.
  * `:renew_every` - milliseconds between renewals (default 15,000).
  * `:docs`, `:timeout` - as for `Slap.Yjs.Docs.join/3`.
  * `:name` - the process name.

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `start_link`

```elixir
@spec start_link(keyword()) :: GenServer.on_start()
```

Starts a linked presence process and publishes its initial state.

# `update`

```elixir
@spec update(GenServer.server(), map(), timeout()) :: :ok | {:error, term()}
```

Sets `state`, publishing it now if connected, or on rejoin.

---

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