# `Skullet.Memory`
[🔗](https://github.com/gilbertwong96/skullet/blob/main/lib/skullet/memory.ex#L1)

Remembers the data a skeleton last showed, so its next skeleton is drawn from that
instead of from a hand-written sample.

The upstream JavaScript library remembers *shapes* in `localStorage`; a Phoenix app can
do better and remember the *data*, then render it: the skeleton is measured from the
real component and is exact at any viewport size, on any device.

Opt in per skeleton:

    <Skullet.skeleton :let={user} id="profile" async={@user} remember={@current_user.id}>
      …
    </Skullet.skeleton>

`remember` is a scope — usually the user's id — and the skeleton's `id` completes the
key. While loading, a remembered value is used as the sample; once loaded, the real
value replaces it.

The store is this node's memory only: it is not shared between nodes, it expires after
`config :skullet, :memory_ttl_ms` (30 minutes by default), and it must be cleared when
somebody signs out — `forget/1` with their scope, from wherever that happens.

# `key`

```elixir
@type key() :: String.t()
```

The skeleton's `id` attribute, which completes the key with the scope.

# `option`

```elixir
@type option() :: {:ttl_ms, integer()}
```

How far back `get/3` looks; `:ttl_ms` may be negative, which expires everything.

# `scope`

```elixir
@type scope() :: term()
```

The scope a skeleton remembers under: usually the current user's id, but any term works
— a tenant, an account, `:global`.

# `value`

```elixir
@type value() :: term()
```

The data the skeleton last showed: whatever your component was passed.

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `clear`

```elixir
@spec clear() :: :ok
```

Forgets everything, for every scope.

# `forget`

```elixir
@spec forget(scope()) :: :ok
```

Forgets everything remembered under `scope`, as on sign-out.

# `get`

```elixir
@spec get(scope(), key(), [option()]) :: value() | nil
```

The value remembered for `scope` and `id`, or `nil`.

## Options

  * `:ttl_ms` — how old a value may be; defaults to `config :skullet, :memory_ttl_ms`

# `put`

```elixir
@spec put(scope(), key(), value()) :: :ok
```

Remembers `value` for `scope` and `id`.

# `start_link`

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

---

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