# `MishkaCmsCore.Runtime.PageBuilder.Icons.Bundled`
[🔗](https://github.com/mishka-group/mishka_cms_core/blob/v0.0.1/lib/mishka_cms_core/runtime/page_builder/icons/bundled.ex#L5)

Icon sets that arrived INSIDE an installed kit, needing no code and no configuration.

## Why this exists

`MishkaCmsCore.Runtime.PageBuilder.Icons.Heroicons` reads `deps/heroicons` at compile time, which
means a second icon set needed a second module and a line of config. That is the wrong shape for a
CMS: installing a kit should be enough. Nobody adding Lucide to their site should have to write an
Elixir module to see its glyphs in the picker.

A kit that ships its glyphs in its bundle needs neither. `mix mishka.ui.export` writes them under a
top-level `icons` key, `MishkaCmsCore.Runtime.Handlers.UiKitHandler` leaves that file in
`priv/cms_ui_kits/`, and this module reads it.

## Why reading a file at runtime is safe here, and was not for heroicons

The constraint that forced heroicons to compile-time is that `deps/` is a BUILD artefact — it does
not exist in a release. `priv/` does: it is shipped, it is exactly where the installed bundles
already live, and the CMS reads them at runtime anyway. So the same instinct that was right for
`deps/` is unnecessary here.

## Caching

The glyphs are ~0.7 MB per set and the picker asks on every keystroke, so the parse happens once
into `:persistent_term`. That is the right store rather than ETS: written once at first read,
read from every process with no copy, and the cost of a write — a global GC — is paid one time.
`refresh/0` clears it, which is what an install calls after replacing a bundle.

# `available?`

```elixir
@spec available?() :: boolean()
```

Whether any installed kit shipped an icon set at all.

False on a stock install, which is why the facade must not offer this library then — an empty set
in the picker's library row is a button that finds nothing.

# `refresh`

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

Drops the cache, so the next read sees a bundle that has just been installed or replaced.

---

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