defmodule Vize do @moduledoc """ Elixir bindings for the [Vize](https://vizejs.dev) Vue.js toolchain. Compile, lint, and analyze Vue Single File Components at native speed via Rust NIFs. Includes Vapor mode IR for BEAM-native SSR. iex> {:ok, result} = Vize.compile_sfc(\""" ...> ...> ...> \""") iex> result.code =~ "msg" true ## Vapor IR The `vapor_ir/1` function exposes Vue's Vapor mode intermediate representation as Elixir maps — enabling BEAM-native SSR without executing JavaScript: iex> {:ok, ir} = Vize.vapor_ir("
{{ msg }}
") iex> [template] = ir.templates iex> template =~ "
" true """ @type macro_artifact :: %{ required(:kind) => String.t(), required(:name) => String.t(), required(:source) => String.t(), required(:content) => String.t(), required(:start) => non_neg_integer(), required(:end) => non_neg_integer(), optional(:code) => String.t() } @type sfc_result :: %{ code: String.t(), css: String.t() | nil, errors: [map()], warnings: [map()], template_hash: String.t() | nil, style_hash: String.t() | nil, script_hash: String.t() | nil, macro_artifacts: [macro_artifact()] } @type template_result :: %{ code: String.t(), preamble: String.t(), helpers: [String.t()] } @type vapor_result :: Vize.Vapor.Result.t() @type ssr_result :: %{ code: String.t(), preamble: String.t() } @type ir_result :: %{ templates: [String.t()], components: [String.t()], directives: [String.t()], block: map(), element_template_map: [{non_neg_integer(), non_neg_integer()}] } @type diagnostic :: %{message: String.t(), name: String.t() | nil} # ── SFC Parsing ── @doc """ Parse a Vue Single File Component into its constituent blocks. Returns the SFC descriptor with template, script, script_setup, styles, and custom_blocks — without compiling. ## Examples iex> {:ok, descriptor} = Vize.parse_sfc(\""" ...> ...> ...> ...> \""") iex> descriptor.template.content =~ "hello" true iex> descriptor.script_setup.setup true iex> hd(descriptor.styles).scoped true """ @spec parse_sfc(String.t()) :: {:ok, map()} | {:error, String.t()} def parse_sfc(source) do Vize.Native.parse_sfc_nif(source) end @doc """ Like `parse_sfc/1` but raises on errors. """ @spec parse_sfc!(String.t()) :: map() def parse_sfc!(source) do case parse_sfc(source) do {:ok, descriptor} -> descriptor {:error, reason} -> raise "Vize parse error: #{reason}" end end # ── SFC Analysis ── @doc """ Analyze a Vue Single File Component into a semantic Croquis summary. ## Options * `:mode` — analysis mode: `:full`, `:lint`, `:compile`, or `:declaration` """ @spec analyze_sfc(String.t(), keyword()) :: {:ok, Vize.Croquis.t()} | {:error, Vize.Error.t()} def analyze_sfc(source, opts \\ []) do mode = opts |> Keyword.get(:mode, :full) |> to_string() case Vize.Native.analyze_sfc_nif(source, mode) do {:ok, result} -> {:ok, Vize.Croquis.new(result)} {:error, reason} -> {:error, error("Vize SFC analysis error", [reason])} end end @doc "Like `analyze_sfc/2` but raises `Vize.Error` on errors." @spec analyze_sfc!(String.t(), keyword()) :: Vize.Croquis.t() def analyze_sfc!(source, opts \\ []) do case analyze_sfc(source, opts) do {:ok, croquis} -> croquis {:error, error} -> raise error end end # ── SFC Compilation ── @doc """ Compile a Vue Single File Component to JavaScript + CSS. Handles `