first commit
This commit is contained in:
@@ -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.
|
||||
Reference in New Issue
Block a user