diff --git a/lib/heroicons.ex b/lib/heroicons.ex index 2b632a5..0033d7b 100644 --- a/lib/heroicons.ex +++ b/lib/heroicons.ex @@ -18,12 +18,23 @@ defmodule Heroicons do """ # https://github.com/tailwindlabs/heroicons/releases + @latest_version "2.0.10" @tmp_dir_name "heroicons-elixir" - + use Application require Logger + @doc false + def start(_type, _args) do + children = [ + {Heroicons.IconCache, []} + ] + + opts = [strategy: :one_for_one, name: Heroicons.Supervisor] + Supervisor.start_link(children, opts) + end + @doc false # Latest known version at the time of publishing. def latest_version, do: @latest_version diff --git a/lib/heroicons/generator.ex b/lib/heroicons/generator.ex index bc559de..8b3fdf8 100644 --- a/lib/heroicons/generator.ex +++ b/lib/heroicons/generator.ex @@ -66,14 +66,13 @@ defmodule Heroicons.Generator do attrs = @assigns_to_attrs_mod.assigns_to_attributes(assigns) assigns = @assign_mod.assign(assigns, :attrs, attrs) - EEx.compile_string(" Heroicons.IconCache.icon_body(path), - engine: Phoenix.LiveView.HTMLEngine, - file: __ENV__.file, - line: __ENV__.line + 1, - module: __ENV__.module, - indentation: 0, - assigns: assigns - ) + {component, _binding} = + Code.eval_quoted( + Heroicons.IconCache.fetch_component(path), + assigns: assigns + ) + + component end @doc false @@ -93,7 +92,7 @@ defmodule Heroicons.Generator do " + component + + [] -> + GenServer.call(@name, {:cache_component, path}) + end + end + + def fetch_body(path) do + case :ets.lookup(@name, path) do + [{^path, body}] -> + body + + [] -> + GenServer.call(@name, {:cache_body, path}) + end + end + + def init(_) do + :ets.new(@name, [:set, :protected, :named_table]) + :ets.new(@name.Components, [:set, :protected, :named_table]) + + {:ok, []} + end + + def handle_call({:cache_body, path}, _ref, state) do + body = read_body(path) + + :ets.insert_new(@name, {path, body}) + + {:reply, body, state} + end + + def handle_call({:cache_component, path}, _ref, state) do + body = read_body(path) + + component = + EEx.compile_string(" body, + engine: Phoenix.LiveView.HTMLEngine, + file: __ENV__.file, + line: __ENV__.line + 1, + module: __ENV__.module, + indentation: 0 + ) + + :ets.insert_new(@name.Components, {path, component}) + + {:reply, component, state} + end + + defp read_body(path) do icon = File.read!(path) <<"> = icon diff --git a/mix.exs b/mix.exs index c0761d2..b9e14da 100644 --- a/mix.exs +++ b/mix.exs @@ -20,7 +20,8 @@ defmodule HeroiconsElixir.MixProject do # Run "mix help compile.app" to learn about applications. def application do [ - extra_applications: [:logger] + extra_applications: [:logger], + mod: {Heroicons, []} ] end