Cache icon bodies and components
This commit is contained in:
@ -18,12 +18,23 @@ defmodule Heroicons do
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# https://github.com/tailwindlabs/heroicons/releases
|
# https://github.com/tailwindlabs/heroicons/releases
|
||||||
|
|
||||||
@latest_version "2.0.10"
|
@latest_version "2.0.10"
|
||||||
|
|
||||||
@tmp_dir_name "heroicons-elixir"
|
@tmp_dir_name "heroicons-elixir"
|
||||||
|
use Application
|
||||||
require Logger
|
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
|
@doc false
|
||||||
# Latest known version at the time of publishing.
|
# Latest known version at the time of publishing.
|
||||||
def latest_version, do: @latest_version
|
def latest_version, do: @latest_version
|
||||||
|
@ -66,14 +66,13 @@ defmodule Heroicons.Generator do
|
|||||||
attrs = @assigns_to_attrs_mod.assigns_to_attributes(assigns)
|
attrs = @assigns_to_attrs_mod.assigns_to_attributes(assigns)
|
||||||
assigns = @assign_mod.assign(assigns, :attrs, attrs)
|
assigns = @assign_mod.assign(assigns, :attrs, attrs)
|
||||||
|
|
||||||
EEx.compile_string("<svg {@attrs}" <> Heroicons.IconCache.icon_body(path),
|
{component, _binding} =
|
||||||
engine: Phoenix.LiveView.HTMLEngine,
|
Code.eval_quoted(
|
||||||
file: __ENV__.file,
|
Heroicons.IconCache.fetch_component(path),
|
||||||
line: __ENV__.line + 1,
|
assigns: assigns
|
||||||
module: __ENV__.module,
|
)
|
||||||
indentation: 0,
|
|
||||||
assigns: assigns
|
component
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc false
|
@doc false
|
||||||
@ -93,7 +92,7 @@ defmodule Heroicons.Generator do
|
|||||||
"<svg",
|
"<svg",
|
||||||
Phoenix.HTML.Safe.to_iodata(attrs),
|
Phoenix.HTML.Safe.to_iodata(attrs),
|
||||||
" ",
|
" ",
|
||||||
Heroicons.IconCache.icon_body(path)
|
Heroicons.IconCache.fetch_body(path)
|
||||||
]}
|
]}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,8 +1,64 @@
|
|||||||
defmodule Heroicons.IconCache do
|
defmodule Heroicons.IconCache do
|
||||||
|
|
||||||
@doc "Get's an icon's body from the filesystem"
|
@doc "Get's an icon's body from the filesystem"
|
||||||
# TODO implement ETS-based caching & benchmark
|
use GenServer
|
||||||
def icon_body(path) do
|
|
||||||
|
@name __MODULE__
|
||||||
|
|
||||||
|
def start_link(_), do: GenServer.start_link(__MODULE__, [], name: @name)
|
||||||
|
|
||||||
|
def fetch_component(path) do
|
||||||
|
case :ets.lookup(@name.Components, path) do
|
||||||
|
[{^path, component}] ->
|
||||||
|
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("<svg {@attrs}" <> 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 = File.read!(path)
|
||||||
|
|
||||||
<<"<svg ", body::binary>> = icon
|
<<"<svg ", body::binary>> = icon
|
||||||
|
3
mix.exs
3
mix.exs
@ -20,7 +20,8 @@ defmodule HeroiconsElixir.MixProject do
|
|||||||
# Run "mix help compile.app" to learn about applications.
|
# Run "mix help compile.app" to learn about applications.
|
||||||
def application do
|
def application do
|
||||||
[
|
[
|
||||||
extra_applications: [:logger]
|
extra_applications: [:logger],
|
||||||
|
mod: {Heroicons, []}
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user