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