Files
skills/docs/foundation/data/packer-browser/src/loader/loader.md
2026-05-29 08:20:56 +01:00

3.6 KiB

loader

(no submodules)

Purpose

loader.ts is the fetch → verify → unpack → Blob-URL pipeline for packed resources. It is the only place in the package that issues a network request, the only place that runs Unpacker.unpack, and the only place that allocates a Blob URL. Splitting it out from PackedResourceManager keeps every concern testable in isolation — fetch retry, signature failure, abort propagation, and OTel histogram emission can each be exercised without instantiating a cache.

Features

  • fetch routed through @suaveplan/retry's withRetry with a single-attempt default policy; callers opt in to retry by passing retryConfig.
  • AbortSignal honoured at every yield point — pre-fetch, post-fetch, post-buffer, post-verify, and pre-unpack.
  • Optional Ed25519 signature verification when verifyKey is supplied and the response carries an X-Archive-Signature header.
  • OTel emission: increments packed_resource_fetch_total on every attempt; records packed_resource_decode_ms on every successful pipeline run.
  • Typed error surface: every failure produces PackerBrowserError with a PACKER_BROWSER.* code and an i18n-resolved message.
  • Injectable fetch for tests — no vi.mock required.

Usage: Basic

import {
    createPackerBrowserObservability,
    PackedResourceLoader,
    resolveRuntime,
} from "@suaveplan/packer-browser";

const loader = new PackedResourceLoader({
    runtime: resolveRuntime(),
    observability: createPackerBrowserObservability(),
});

const { url, metadata } = await loader.load("/banner.packed");
img.src = url;

Usage: Advanced

import { createConstantBackoff } from "@suaveplan/retry";
import { PackedResourceLoader } from "@suaveplan/packer-browser";

const controller = new AbortController();
const loader = new PackedResourceLoader({
    runtime: resolveRuntime(),
    observability,
    fetch: async (url) => recordedFetch(url),
});

const out = await loader.load("/banner.packed", {
    verifyKey: trustAnchorPublicKey,
    signal: controller.signal,
    retryConfig: {
        maxAttempts: 3,
        delay: createConstantBackoff({ delay: 250 }),
    },
});

API Reference

  • new PackedResourceLoader(opts: PackedResourceLoaderOptions).
  • loader.load(url: string, opts?: PackedResourceLoadOptions): Promise<LoadedResource>.
    • Throws RESOURCE_NOT_FOUND for non-2xx.
    • Throws ARCHIVE_SIGNATURE_INVALID for a non-verifying signature when verifyKey is supplied.
    • Throws LOAD_FAILED when Unpacker.unpack rejects.
    • Throws ABORTED when the supplied signal fires.
  • PackedResourceLoadOptions:
    • verifyChecksum?: boolean — default false.
    • verifyKey?: Uint8Array — optional Ed25519 public key.
    • signal?: AbortSignal — checked at every yield.
    • retryConfig?: RetryConfig — default: single attempt.
    • messageResolver?: MessageResolver — overrides the constructor's resolver for this call.

Implementation Notes

Cluster A's loader treats every fetched payload as a raw PackedData whose metadata is reconstructed from the bytes; signature verification covers the archive transport layer, while integrity verification is delegated to the Unpacker and currently skipped (verifyIntegrity: false) because Cluster A archives do not carry the BLAKE3 integrity bundle. Cluster B introduces the formal manifest decoder and re-enables integrity. The X-Archive-Signature header contract is unchanged across clusters — switching to a separate signature manifest is a Cluster B concern only.