Iconvex.RuntimeAsset (iconvex v0.1.1)

Copy Markdown View Source

Safely loads and caches versioned ETF runtime assets.

Every asset supplies an explicit configuration:

  • :owner_app — the OTP application that owns the asset;
  • :cache_namespace, :cache_schema, and :cache_version — caller-owned cache identity and invalidation terms;
  • :allowed_atoms — the finite atom vocabulary permitted in the decoded schema;
  • :asset_sha256 and :asset_version — the pinned content identity.

Cache keys include the namespace, owner application, and owner module. Cache records include the schema plus an effective version derived from the caller's cache version, the owning application version, the asset digest/version, and the allowed atom vocabulary. This prevents collisions between independently shipped packages and makes stale application, asset, or schema-policy data reload automatically.

fetch/3 verifies SHA-256 before decoding with :erlang.binary_to_term/2 in safe mode, then rejects every atom outside the caller's schema vocabulary and every non-data term. Concurrent cold or stale loads publish exactly one value.

Summary

Types

Explicit ownership, cache, schema, and content identity for one asset.

Functions

Returns the isolated persistent-term key for owner and config.

Returns the effective cache version for config.

Loads path safely on a cold or stale cache and returns the cached value.

Caches the result of loader using the same explicit identity as fetch/3.

Types

config()

@type config() :: %{
  owner_app: atom(),
  cache_namespace: term(),
  cache_schema: term(),
  cache_version: term(),
  allowed_atoms: [atom()],
  asset_sha256: binary(),
  asset_version: term()
}

Explicit ownership, cache, schema, and content identity for one asset.

Functions

cache_key(owner, config)

@spec cache_key(module(), config()) :: tuple()

Returns the isolated persistent-term key for owner and config.

cache_version(config)

@spec cache_version(config()) :: tuple()

Returns the effective cache version for config.

The owning application's loaded version is included automatically; unloaded applications use the stable ~c"unloaded" marker.

fetch(owner, path, config)

@spec fetch(module(), Path.t(), config()) :: term()

Loads path safely on a cold or stale cache and returns the cached value.

Raises File.Error for file-system failures and ArgumentError for an invalid configuration, digest mismatch, malformed ETF, unsafe term, or atom outside :allowed_atoms.

fetch_with(owner, config, loader)

@spec fetch_with(module(), config(), (-> term())) :: term()

Caches the result of loader using the same explicit identity as fetch/3.

This lower-level form is useful when validation happens in a package-specific loader. The caller remains responsible for ensuring that loader verifies the asset described by :asset_sha256 and :asset_version.