MishkaCmsCore.Runtime.States.CardPreviewState (Mishka CMS Core v0.0.1)

Copy Markdown View Source

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.

Summary

Functions

Returns a specification to start this module under a supervisor.

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

Forget every preview, whatever site it belongs to.

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

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

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

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

drop(site_name)

@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()

@spec drop_all() :: :ok

Forget every preview, whatever site it belongs to.

get(template, site_name)

@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(template, site_name, result)

@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()

@spec size() :: non_neg_integer()

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