first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,70 @@
# 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<T>(opts: SequentialWalkOptions, dispatch: Dispatch<T>): Promise<T>`
- `SequentialWalkOptions` — `{ uri, candidates, ctx, policy, events, signal }`.
- `Dispatch<T>` — `(candidateUri, signal) => Promise<T>`.
- `candidateScheme(uri)` — extracts the lowercased scheme.
- `decorateRecursive(candidate, ctx)` — appends `__fbctx=<ctx.id>` 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.