The content-addressed blob storage seam.
On-disk transports (OCI layouts, the registry server, the static tree) all read and write
blobs by digest; Store is the single interface they go through, so storage backends are
interchangeable. Blobs are immutable and addressed by their Stevedore.Digest — there is no
rename or mutate, only put/get/delete/exists.
The config term threaded through every callback is the backend's own handle (a root path,
an agent pid, …); each implementation defines its shape.
Implementations: Stevedore.Store.Local (filesystem) and Stevedore.Store.Memory (in-process,
for tests).
Summary
Callbacks
Deletes the blob for digest. Deleting an absent blob is :ok (idempotent).
Whether a blob exists for digest.
Fetches the blob for digest.
Lists the digests currently held.
Returns a filesystem path to the blob for zero-copy serving (send_file), or :unsupported
for backends without a stable on-disk path.
Stores data under digest. Implementations must verify the bytes match the digest.
Types
@type config() :: term()
Backend-specific handle (e.g. {root: path} for Local, a pid for Memory).
Callbacks
@callback delete(config(), Stevedore.Digest.t()) :: :ok | {:error, term()}
Deletes the blob for digest. Deleting an absent blob is :ok (idempotent).
@callback exists?(config(), Stevedore.Digest.t()) :: boolean()
Whether a blob exists for digest.
@callback get(config(), Stevedore.Digest.t()) :: {:ok, binary()} | {:error, :not_found}
Fetches the blob for digest.
@callback list(config(), opts :: keyword()) :: {:ok, [Stevedore.Digest.t()]}
Lists the digests currently held.
@callback local_path(config(), Stevedore.Digest.t()) :: {:ok, Path.t()} | :unsupported
Returns a filesystem path to the blob for zero-copy serving (send_file), or :unsupported
for backends without a stable on-disk path.
@callback put(config(), Stevedore.Digest.t(), iodata()) :: :ok | {:error, term()}
Stores data under digest. Implementations must verify the bytes match the digest.