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,84 @@
# depth-context
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
The `depth-context` module tracks the recursion state threaded through
nested `fallback://` dispatches: the per-call depth counter, the visited
set used for cycle detection, and the process-wide context registry that
lets recursive resolver re-entries rehydrate their parent context purely
from the URI string (via the `__fbctx` marker). It is the cornerstone of
the package's two recursion safeguards.
## Features
- `DepthContext` value carrying `id`, `depth`, `maxDepth`, `visited`.
- `enterDepth` / `leaveDepth` lifecycle with depth-cap enforcement.
- `hasVisited` canonicalises URIs via `stripContext` so context-id
variations of the same `fallback://` URI deduplicate correctly.
- Process-wide registry (`registerContext`, `lookupContext`,
`unregisterContext`) keyed by `ctx.id` so child dispatches survive a
full resolver round trip.
## Usage: Basic Example
```ts
import {
createDepthContext,
enterDepth,
leaveDepth,
} from "@suaveplan/storage-uri-plugin-fallback/recursion";
const ctx = createDepthContext(4);
enterDepth(ctx, "fallback://?u=mem%3A%2F%2Fa");
try {
// walk candidates
} finally {
leaveDepth(ctx);
}
```
## Usage: Advanced Example
```ts
import {
createDepthContext,
lookupContext,
registerContext,
unregisterContext,
} from "@suaveplan/storage-uri-plugin-fallback/recursion";
const ctx = createDepthContext(6);
registerContext(ctx);
try {
// Pass ctx.id via the URI's __fbctx parameter so recursive resolver
// dispatches re-enter the same context state.
await dispatchWithContextId(uri, ctx.id);
} finally {
unregisterContext(ctx);
}
console.log(lookupContext(ctx.id)); // undefined post-cleanup
```
## API Reference
- `createDepthContext(maxDepth: number): DepthContext`
- `enterDepth(ctx, uri)` — throws `MAX_DEPTH_EXCEEDED` past cap.
- `leaveDepth(ctx)` — decrements; safe to over-call.
- `hasVisited(ctx, uri): boolean`
- `registerContext(ctx)` / `unregisterContext(ctx)` / `lookupContext(id)`.
## Implementation Notes
Depth contexts are mutable inside one walk and never shared across
unrelated calls — the registry is keyed by an opaque id so concurrent
walks remain isolated. The visited set retains entries across
`leaveDepth` because cycle detection cares about whether a URI has been
seen anywhere in the call chain, not just whether it is currently on the
stack.
This module is part of the universal fallback URI plugin family. It coordinates with the recursion, walk, ops, observability, and classification modules through small, narrowly-typed value contracts. The implementation deliberately keeps surface area small so each piece can be substituted or instrumented independently without touching consumers. Refer to the package README for the end-to-end picture and to the spec delta for the requirement matrix this module helps satisfy.