# walk/sequential ## Purpose The `walk/sequential` module implements the default ordered fall-through walk strategy. It iterates the candidate list in declaration order, dispatches each candidate via a caller-supplied dispatcher, and returns the first successful result. Transient failures fall through to the next candidate; semantic failures surface immediately; aborts cut the walk per policy. On exhaustion it throws `ALL_CANDIDATES_FAILED` with every per-leg error preserved, or `CIRCULAR_REFERENCE` when every candidate cycles back to an already-visited URI. ## Features - Ordered fall-through with `EventBusLike` `attempt-failed` / `attempt-succeeded` emissions per candidate. - Cycle skipping via `hasVisited` + `cycle-detected` event emission. - Per-candidate OTel counter increments (`fallback_total`). - Foreign throwable wrapping into structured `FallbackUriError`. - `decorateRecursive` injects the recursion-context id into nested `fallback://` candidates so re-entries see the parent context. ## Usage: Basic Example ```ts import { walkSequential } from "@suaveplan/storage-uri-plugin-fallback/walk"; const value = await walkSequential( { uri, candidates, ctx, policy, events, signal, }, async (candidate, s) => resolver.read(candidate, s), ); ``` ## Usage: Advanced Example ```ts import { candidateScheme, decorateRecursive, walkSequential, } from "@suaveplan/storage-uri-plugin-fallback/walk"; const decorated = candidates.map((c) => decorateRecursive(c, ctx)); console.log(candidateScheme(decorated[0])); ``` ## API Reference - `walkSequential(opts: SequentialWalkOptions, dispatch: Dispatch): Promise` - `SequentialWalkOptions` — `{ uri, candidates, ctx, policy, events, signal }`. - `Dispatch` — `(candidateUri, signal) => Promise`. - `candidateScheme(uri)` — extracts the lowercased scheme. - `decorateRecursive(candidate, ctx)` — appends `__fbctx=` to `fallback://` candidates. ## Implementation Notes The walk respects `policy.stopOnAbort`: when `true` (default), an aborted caller signal is checked before each candidate and throws `FALLBACK_URI.ABORTED` immediately. The recorded counter outcome for cycle-skipped candidates is `"semantic"` to align with the classifier's treatment of cycle detection as a non-transient surface.