Portable value codec for run state.
Values that cross a run boundary must survive serialization and restarts,
so they cannot contain PIDs, ports, references or functions. This module
validates that constraint, encodes values into JSON-safe tagged maps
(atoms, tuples, structs and non-string-keyed maps get a "$spectre" tag),
decodes them back, and derives deterministic identifiers from them.
Summary
Functions
Decodes a value produced by encode/1 back into its original shape.
Encodes a portable value into its JSON-safe representation.
Derives a stable identifier from value, or nil when it cannot.
Derives a stable identifier from value, keeping validation errors.
Preloads the modules referenced by an encoded value before decoding.
Builds a "prefix:hash" token from a deterministic digest of value.
Checks that value is portable run data.
Functions
Decodes a value produced by encode/1 back into its original shape.
Atoms and struct modules are resolved with String.to_existing_atom/1
only — unknown names return an error instead of creating atoms.
Encodes a portable value into its JSON-safe representation.
Primitives pass through unchanged; atoms, tuples, structs and maps with
non-string keys become tagged maps that decode/1 can reverse.
Derives a stable identifier from value, or nil when it cannot.
Non-empty strings are used as-is; any other portable value is hashed via
token/2. Non-portable values yield nil rather than an error.
Derives a stable identifier from value, keeping validation errors.
Unlike logical_id/2, a non-portable value returns the underlying
{:error, reason} so callers can surface it.
Preloads the modules referenced by an encoded value before decoding.
Struct tags require their module to exist and load; module-shaped atom tags
are loaded opportunistically so decode/1 can resolve them as existing
atoms.
Builds a "prefix:hash" token from a deterministic digest of value.
The same value always produces the same token, so tokens are safe to use as cross-restart identifiers.
Checks that value is portable run data.
Returns {:error, {:nonportable_run_value, path, kind}} when the value —
at any depth — contains a PID, port, reference, function or improper list.