Skip to main content

lib/scoria_web/assets.ex

defmodule ScoriaWeb.Assets do
  @moduledoc """
  Compile-time-embedded, self-contained dashboard assets.

  The compiled CSS/JS bundles (built by `mix scoria.assets.build` into
  `priv/static/scoria/`) are read at COMPILE TIME and baked into this module. The Scoria
  root layout inlines them into a `<style>` / `<script>` tag, so the dashboard is fully
  styled and interactive under any mount path with no dependency on the host's asset
  pipeline (the Phoenix LiveDashboard / Oban Web self-contained model).

  Inlining (vs hashed asset routes) keeps the library independent of the host's mount path
  and `Plug.Static` configuration. For a LiveView dashboard full page loads are rare
  (navigation is via live patches), so the one-time inline cost is acceptable.
  """

  css_path =
    [__DIR__, "..", "..", "priv", "static", "scoria", "app.css"] |> Path.join() |> Path.expand()

  js_path =
    [__DIR__, "..", "..", "priv", "static", "scoria", "app.js"] |> Path.join() |> Path.expand()

  favicon_path =
    [__DIR__, "..", "..", "priv", "static", "favicon.svg"] |> Path.join() |> Path.expand()

  @external_resource css_path
  @external_resource js_path
  @external_resource favicon_path

  @css (if File.exists?(css_path), do: File.read!(css_path), else: "")
  @js (if File.exists?(js_path), do: File.read!(js_path), else: "")
  @favicon (if File.exists?(favicon_path), do: File.read!(favicon_path), else: "")
  @css_hash Base.encode16(:crypto.hash(:md5, @css), case: :lower)
  @js_hash Base.encode16(:crypto.hash(:md5, @js), case: :lower)

  @doc "Compiled dashboard stylesheet (inlined into the root layout)."
  def css, do: @css

  @doc "Compiled dashboard client bundle (inlined into the root layout)."
  def js, do: @js

  @doc "Content hash of the compiled CSS (for cache keys / smoke checks)."
  def css_hash, do: @css_hash

  @doc "Content hash of the compiled JS (for cache keys / smoke checks)."
  def js_hash, do: @js_hash

  @doc "True when the compiled bundle is present (i.e. `mix scoria.assets.build` has run)."
  def built?, do: @css != "" and @js != ""

  @doc "Compile-time base64 data-URI for the Scoria favicon SVG (inlined into the dashboard <head>)."
  def favicon_data_uri, do: "data:image/svg+xml;base64," <> Base.encode64(@favicon)
end