# `Mob.ScreenState`
[🔗](https://github.com/genericjam/mob/blob/master/lib/mob/screen_state.ex#L1)

Persistent store for screen assigns.

Backed by the app's configured Ecto Repo (via `config :mob, :repo, MyApp.Repo`).
All functions are no-ops when no Repo is configured, so screens compiled with
`vsn:` enabled don't crash in environments without a database.

## Setup

Generated projects include the required table migration and config automatically.
For existing projects, add to `config/config.exs`:

    config :mob, :repo, MyApp.Repo

And run the migration (see `priv/repo/migrations/*_create_mob_screen_states.exs`
generated by `mix mob.new`).

## Storage

State is keyed by screen module name by default. Screens with per-user or
parameterised state should implement `screen_key/1`:

    def screen_key(assigns), do: "#{__MODULE__}:#{assigns.user_id}"

## Serialisation

Values are encoded with `:erlang.term_to_binary/1` after stripping
non-serialisable terms (PIDs, references, ports, functions). The `:safe`
flag is used on decode to prevent atom-table pollution from untrusted data.

# `delete`

```elixir
@spec delete(module(), Mob.Socket.t()) :: :ok
```

Delete the persisted state for `module`. Used when resetting or logging out.

# `dump`

```elixir
@spec dump(module(), Mob.Socket.t()) :: :ok
```

Persist the current assigns of `socket` for `module`.

Calls `module.dump_state/1`, strips non-serialisable values, and writes to
the configured Repo. Returns `:ok` regardless — persistence failures are
silent so a missing or misconfigured Repo never crashes a screen.

# `load`

```elixir
@spec load(module(), Mob.Socket.t()) :: {:ok, non_neg_integer(), map()} | :not_found
```

Load previously persisted assigns for `module`.

Returns `{:ok, stored_vsn, raw_map}` when a record exists, `:not_found`
otherwise (including when no Repo is configured or the data cannot be decoded).

---

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