Canonical helpers for workflow-owned artifacts in the stepwise runtime.
Artifacts are durable, workflow-scoped data that should survive refreshes, retries, and external callbacks (e.g. email confirmation links).
Summary
Functions
Merges two artifact maps, with incoming entries overriding existing ones.
Normalizes an artifact map into canonical format.
Types
@type artifact_map() :: %{optional(String.t()) => artifact_entry()}
Functions
@spec merge(map() | nil, map() | nil) :: artifact_map()
Merges two artifact maps, with incoming entries overriding existing ones.
Both maps are normalized before merging. nil inputs are treated as empty maps.
Parameters
existing— the current artifact map (ornil)incoming— new artifacts to merge in (ornil)
Returns
- A merged and normalized
artifact_map().
Examples
Artifacts.merge(%{"a" => %{"data" => 1}}, %{"b" => %{"data" => 2}})
#=> %{"a" => %{...}, "b" => %{...}}
@spec normalize(map() | nil) :: artifact_map()
Normalizes an artifact map into canonical format.
Each artifact entry is coerced to include "kind", "version", "inserted_at",
and "data" keys with string keys throughout. Keys are stringified, and entries
without explicit metadata default to kind "opaque" and version 1.
Returns an empty map for nil or non-map inputs.
Parameters
artifacts— a map of artifact entries, ornil
Returns
- A normalized
artifact_map()with string keys and canonical entry structure.
Examples
Artifacts.normalize(%{report: %{kind: "pdf", data: "..."}})
#=> %{"report" => %{"kind" => "pdf", "version" => 1, "inserted_at" => "...", "data" => "..."}}
Artifacts.normalize(nil)
#=> %{}