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

4.0 KiB

content-address

(no submodules)

Purpose

Content-addressed URL builder and cache-invalidation helpers for packed archives. Each archive's canonical URL is derived from a BLAKE3 Merkle root over its entries plus the format-version byte, so any payload or wire-format change produces a different URL and the Service Worker can cleanly invalidate the prior version on next install. This module is the foundation for the /packed/<hash>.bundle.asset URL form and the SW activate-time cache pruning.

Features

  • computeArchiveContentHash(entries, formatVersion) — deterministic 32-byte BLAKE3 root that mixes the format-version byte into the leaf set so a wire-format bump is reflected in the URL.
  • contentHashHex(hash) — lowercase-hex serialiser used by URL builders and cache-key emitters.
  • buildContentAddressedUrl(prefix, hash, ext?) — emits the canonical <prefix>/<hash>.<ext> URL (default ext bundle.asset matches the Cluster A SW pattern).
  • cleanupOutdatedCaches(caches, prefix, keep) — Service Worker helper that deletes every cache name with a given prefix not in keep.
  • PACKER_BROWSER_FLAGS.URL_CONTENT_ADDRESSED — stable feature-flag string registered against the manager's FlagProvider.

Usage: Basic Example

import {
    buildContentAddressedUrl,
    computeArchiveContentHash,
    contentHashHex,
} from "@suaveplan/packer-browser";

const entries = [new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6])];
const hash = computeArchiveContentHash(entries, /* formatVersion */ 1);
const url = buildContentAddressedUrl("/packed", contentHashHex(hash));
// → "/packed/<64-hex>.bundle.asset"

Usage: Advanced Example

import {
    cleanupOutdatedCaches,
    runPackedResourceServiceWorker,
} from "@suaveplan/packer-browser";

// Inside the Service Worker bootstrap:
runPackedResourceServiceWorker(self as unknown as ServiceWorkerGlobalScope, {
    cacheName: `packed-resources-${currentHash}`,
    contentAddressed: true,
});

// `cleanupOutdatedCaches` is invoked by the SW's activate handler
// automatically when `contentAddressed` is on. You can also call it
// from a maintenance message handler:
self.addEventListener("message", async (ev) => {
    if ((ev as MessageEvent).data?.type === "GC") {
        const deleted = await cleanupOutdatedCaches(
            self.caches,
            "packed-resources-",
            [`packed-resources-${currentHash}`]
        );
        console.info("Pruned", deleted);
    }
});

API Reference

  • computeArchiveContentHash(entries: ReadonlyArray<Uint8Array>, formatVersion: number): Uint8Array Throws RangeError if formatVersion is not an integer in [0, 255].
  • contentHashHex(hash: Uint8Array): string Throws RangeError on non-32-byte input.
  • buildContentAddressedUrl(prefix: string, hash: string, ext?: string): string
  • cleanupOutdatedCaches(caches: CacheStorageLike, prefix: string, keep: ReadonlyArray<string>): Promise<string[]> Returns the list of cache names that were deleted.
  • PACKER_BROWSER_FLAGS.URL_CONTENT_ADDRESSED: string — "packer-browser.url.content-addressed".

Implementation Notes

  • The format-version byte is appended as a synthetic trailing entry rather than mixed via HKDF so the implementation stays simple and every transformation is auditable via the existing entryDigestBlake3 + merkleRootBlake3 primitives.
  • cleanupOutdatedCaches accepts any object with keys() and delete() methods; both the production globalThis.caches and the in-memory ShimCacheStorage satisfy the contract, which keeps the SW unit tests honest.
  • buildContentAddressedUrl trims a trailing slash from the prefix so callers can pass /packed or /packed/ interchangeably.
  • The Cluster A SW pattern /\.packed$/ continues to match the canonical content-addressed form; the Cluster B RunServiceWorkerOptions.legacyUrlPattern slot accepts any other RegExp callers need for backwards compatibility (e.g. legacy named-archive URLs).