# `MishkaCmsCore.Runtime.States.CardPreviewState`
[🔗](https://github.com/mishka-group/mishka_cms_core/blob/v0.0.1/lib/mishka_cms_core/runtime/states/card_preview_state.ex#L5)

O(1) ETS cache of rendered palette-card previews, keyed by the template a card would drop.

## Why a cache at all

The first render of a component costs 0.5–1.4 seconds — that is its module being compiled — and
every later one costs about 2 ms. Without this, moving back along a row of cards would pay the
first price again each time the pointer returned, because nothing else remembers the answer.

Keyed on the TEMPLATE rather than the component name, because two cards for the same component
with different presets are two different previews, and the template is the thing that actually
differs. The site rides in the key too: the same component draws differently under two sites'
stylesheets.

## Why it is a plain table and not a GenServer

The reads are the hot path and there is nothing to serialise: a preview is a pure function of its
key, so two processes racing to compute the same one write identical bytes. `CompileFailureState`
is the precedent.

## What bounds it

A single install ships on the order of a hundred components, each a few kilobytes rendered, so a
full cache is measured in hundreds of kilobytes — small enough to keep for the life of the node.
It is dropped wholesale when a site recompiles, because that is when a preview can become a lie.

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `drop`

```elixir
@spec drop(String.t() | nil) :: :ok
```

Forget everything a site's stylesheet or components could have changed.

Called when a site recompiles: a preview drawn against the old bundle is not wrong in a way anyone
can see, which is exactly why it has to go.

# `drop_all`

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

Forget every preview, whatever site it belongs to.

# `get`

```elixir
@spec get(String.t(), String.t() | nil) ::
  {:ok, String.t()} | {:error, String.t()} | nil
```

The cached preview for a template under a site, or `nil`.

# `put`

```elixir
@spec put(String.t(), String.t() | nil, {:ok, String.t()} | {:error, String.t()}) ::
  :ok
```

Remember a rendered preview — or a refusal, which is just as expensive to work out twice.

# `size`

```elixir
@spec size() :: non_neg_integer()
```

How many previews are held, for tests and for anyone measuring.

---

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