Renders verified artifacts in bounded, isolated BEAM processes.
Rendering is atomic across channels: a caller receives every configured subject, HTML, and text value or an error with no partial output. Values are normalized as JSON, checked against the artifact's typed schema, and escaped according to contexts proven during compilation.
Each render runs in a monitored process with a deadline, maximum heap, input budgets, loop budget, and per-channel output limit. The MJML compiler and Node are never used in this path.
Example
iex> schema = %{
...> "version" => 1,
...> "variables" => %{
...> "name" => %{"type" => "string", "context" => "text"}
...> }
...> }
iex> {:ok, artifact, []} =
...> Letterpress.compile("text/liquid@1", "Hello {{ name }}", schema)
iex> Letterpress.Renderer.render(artifact, %{"name" => "Grace"})
{:ok, %{text: "Hello Grace"}}
Summary
Functions
Renders a decoded artifact with typed values and runtime budgets.
Functions
@spec render(Letterpress.Artifact.t() | map(), map(), keyword()) :: {:ok, %{optional(atom()) => String.t()}} | {:error, [Letterpress.Diagnostic.t()]}
Renders a decoded artifact with typed values and runtime budgets.
artifact may be a verified Letterpress.Artifact or its string-keyed map
projection. values must be a JSON object whose delivery-phase values match
the embedded schema.
Options
:strict_values- reject undeclared root keys; defaults totrue:timeout- whole-render deadline in milliseconds; defaults to5_000:max_heap_words- isolated process heap limit; defaults to2_000_000:max_output_bytes- limit for each rendered channel; defaults to1_000_000:subject_max_bytes- subject byte limit; defaults to998:allowed_url_schemes- narrows the contract's absolute URL schemes for this call; defaults tohttp,https,mailto,tel, andcid
Relative paths and fragment URLs remain valid regardless of the absolute scheme list. Invalid options and expected render failures return diagnostics.