# load ## Purpose Loads server-signed manifests from the two supported sources: a sentinel chunk inside the file's own chunk space (`manifestSource: "manifest-as-chunk"`) and a separate manifest server keyed by file id (`manifestSource: "server-only"`). Every code path runs the same `parseAndVerifyManifest` so signature verification can never be skipped. ## Features - `loadManifestAsChunk(fileId, getChunk, serverPubKey)` — reads chunkId `-1` from the chunk source. - `loadManifestFromServer(fileId, url, fetchFn, serverPubKey)` — issues a `fetch(url + "/manifest/")` GET; injectable `fetchFn` for testing. - `parseAndVerifyManifest(raw, serverPubKey)` — JSON-decodes (with `base64:` Uint8Array unwrapping), validates against `ManifestSchema`, and runs Ed25519 verification with the canonical encoder. - `MANIFEST_NOT_FOUND` and `MANIFEST_INVALID` are the only errors that can come out of this module — every internal failure is mapped onto one of those two codes. ## Usage: Basic Example ```ts import { loadManifestAsChunk } from "@suaveplan/drive-plugin-chunks"; const manifest = await loadManifestAsChunk( fileId, (id, idx) => chunks.getChunk(id, idx), serverPubKey ); ``` ## Usage: Advanced Example ```ts import { loadManifestFromServer, parseAndVerifyManifest, } from "@suaveplan/drive-plugin-chunks"; const manifest = await loadManifestFromServer( fileId, "https://manifests.example.com", fetch, serverPubKey ); // Verifying a manifest received over a side-channel const verified = parseAndVerifyManifest(receivedBytes, serverPubKey); ``` ## API Reference - `loadManifestAsChunk(fileId, getChunk, serverPubKey): Promise`. - `loadManifestFromServer(fileId, url, fetchFn, serverPubKey): Promise`. - `parseAndVerifyManifest(raw: Uint8Array, serverPubKey: Uint8Array): Manifest`. - All three throw `ChunksError(CHUNKS.MANIFEST_NOT_FOUND)` (missing input) or `ChunksError(CHUNKS.MANIFEST_INVALID)` (schema or signature failure). ## Implementation Notes `parseAndVerifyManifest` first tries to parse as UTF-8 JSON because manifests are persisted as JSON inside `plugin.ingest`; the catch falls back to treating the raw bytes as the parsed value, which lets future binary manifest formats slot in without changing the call site. Signature verification rebuilds `withoutSig` with a 64-byte zero placeholder and asks the canonical encoder to lay out the bytes; this matches the layout used at sign time so the verification is over identical bytes.