# parse-fallback-uri ## Purpose The `parse-fallback-uri` module owns the canonical grammar for the `fallback://` URI scheme. It parses input strings into ordered candidate URI lists, rejects malformed inputs with structured `FALLBACK_URI.*` errors, builds canonical URIs from candidate arrays, and exposes helpers to attach or strip the internal recursion-context query parameter used for cycle detection across resolver re-entries. ## Features - `parseFallbackUri(uri, maxCandidates?)` — split into candidates + canonical re-serialisation; throws `NO_CANDIDATES` / `INVALID_URI`. - `buildFallbackUri(uris, maxCandidates?)` — construct a canonical URI using stdlib `URLSearchParams`; rejects empty / oversized inputs. - `stripContext(uri)` / `withContextId(uri, id)` — manipulate the internal `__fbctx=` recursion-context marker. - Hard ceilings (`MAX_URI_LEN` 4096, `MAX_CANDIDATES_HARD` 64) enforced even when a more permissive policy value is supplied. ## Usage: Basic Example ```ts import { buildFallbackUri, parseFallbackUri, } from "@suaveplan/storage-uri-plugin-fallback/parse-uri"; const uri = buildFallbackUri([ "https://cdn.example.com/foo", "drive://primary/foo", ]); const { candidates } = parseFallbackUri(uri); console.log(candidates); ``` ## Usage: Advanced Example ```ts import { parseFallbackUri, withContextId, stripContext, } from "@suaveplan/storage-uri-plugin-fallback/parse-uri"; const decorated = withContextId(uri, "ctx-42"); const parsed = parseFallbackUri(decorated); if (parsed.contextId === "ctx-42") { const canonical = stripContext(decorated); console.log("recursion key:", canonical); } ``` ## API Reference - `parseFallbackUri(uri: string, maxCandidates?: number): ParsedFallbackUri` - `buildFallbackUri(uris: readonly string[], maxCandidates?: number): string` - `stripContext(uri: string): string` - `withContextId(uri: string, contextId: string): string` - `FB_CTX_PARAM` — `"__fbctx"` marker name. - `MAX_URI_LEN` — 4096. - `MAX_CANDIDATES_HARD` — 64. ## Implementation Notes Parsing is delegated entirely to the Web-standard `URL` and `URLSearchParams` constructors, eliminating every custom regex outside syntactic guards. Candidate ordering is preserved because `URLSearchParams.getAll` is ordered. Round-trip safety is verified by a fast-check property test in the sibling `.test.ts` file. The `__fbctx` parameter is stripped from the canonicalised visited-set key so nested re-entries cannot defeat cycle detection by carrying different context ids.