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

Temporary, isolated CSS and compiled module for a runtime preview — a draft (Page/Layout/ErrorPage)
or a live original reached by its `preview_token` — keyed by that token in `AssetsState` (ETS),
NEVER the live site bundle or the live page module.

Compiled on demand (so a draft with brand-new Tailwind classes still styles correctly) via
`TailwindCompiler.compile_preview/4`, and **purged** when the draft is published or discarded.
Served at `/_preview/:resource/:token/css` (see `MishkaCmsWeb.DraftPreviewController`), and linked
by `MishkaCmsWeb.DraftPreviewLive`. JS is NOT compiled per-draft — the preview is a real LiveView
that loads the site's existing JS bundle, which already exports every active hook (a draft
template's `phx-hook` references `JsHook` rows in that bundle), so hooks run with no extra work.
The token records the site its assets belong to (`remember_site/2`) — the record's own, or for a
global record the host's its CSS was compiled against — so they are handed to whoever holds the
link, by that site's state (`site/1`), on an address `served_on?/2` allows.

A page or a layout is drawn by its compiled module (`ensure_module/2`), built by the compiler its
site uses, so its own helpers and the live components it nests render as on the published page.
The module is named after the token, so a draft never replaces the live one, and is compiled again
only when the record was saved since or is opened on another site. `purge/1` unloads it with the
CSS, and `MishkaCmsWeb.DraftPreviewLive` unloads it when the preview closes.

# `ensure_css`

Compile + store the draft's temp CSS under its token if missing, or if it was compiled against
another site. `asset_site` is an optional fallback site (the host the admin is viewing from) used
when the draft has no site of its own — a global layout draft — so its CSS compiles against a real
site's base. Returns `:ok` | `:error`.

# `ensure_module`

The module a Page, Layout or one of their drafts is previewed with, compiled if missing or older
than the record, against `asset_site`'s hooks. `{:ok, module}`, or `{:error, message}` when it
does not compile.

# `purge`

Delete the draft's temp CSS, its site and its compiled module (on publish / discard).

# `refresh_css`

Recompile + replace the draft's temp CSS (after an edit).

# `remember_site`

Records the site the preview's assets under the record's token belong to: the record's own, or for
a global record `asset_site`, the host's it is opened on.

# `served_on?`

```elixir
@spec served_on?(String.t() | nil, map() | nil) :: boolean()
```

Whether a preview of a record of `site_id` (`nil` for a global one) may be served on the address of
`current_site`, the site the request's host resolved to.

The master site's address serves every site's previews, and a site's own address serves its own.
A global record belongs to every site, so any site's address serves it. Another site's address,
or a request no site answers for, serves nothing: a preview of site A is never shown on site B.

    served_on?(site_a_id, %{id: site_a_id, master: false})  #=> true
    served_on?(site_a_id, %{id: master_id, master: true})   #=> true
    served_on?(site_a_id, %{id: site_b_id, master: false})  #=> false
    served_on?(nil, %{id: site_b_id, master: false})        #=> true

# `site`

The site the preview's assets under `token` belong to: `{:ok, site_id}`, `{:ok, nil}` for a global
record opened with no site, or `:error` when no preview has been opened under it.

# `unload_module`

Unloads the record's preview module. A process still drawing it keeps the old code, and the next
`ensure_module/2` compiles it again.

---

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