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,67 @@
# `range/range-stream-parse.ts`
## Purpose
Streams an HTTP response body line-by-line through a `TextDecoderStream`
and a newline framer, yielding `{ suffix, count }` records as soon as
each line crosses a complete byte boundary. The parser deliberately
never calls `Response.text()` and never collects the body into a single
string buffer, so even a 30 KiB `Add-Padding` response is processed in
bounded memory. Mid-flight `AbortSignal` is honoured between chunks.
## Features
- Async generator interface — drop in to `for await` loops.
- CRLF and LF newlines both work; trailing line without newline is
emitted; empty lines are skipped.
- Per-line validation delegated to `parseRangeLine` so strict-mode
rejection happens at first-fault.
- AbortSignal threading: pre-aborted and mid-flight aborts both throw
`HIBP.ABORTED` and the underlying reader is released in a `finally`
guard.
## Usage: Basic Example
```ts
import { streamParseRangeBody } from "@suaveplan/hibp";
for await (const line of streamParseRangeBody(response.body!, { strict: true })) {
if (line.suffix === expected) /* ... */;
}
```
## Usage: Advanced Example
```ts
import { streamParseRangeBody } from "@suaveplan/hibp";
const ac = new AbortController();
const iter = streamParseRangeBody(response.body!, {
strict: false,
signal: ac.signal,
});
setTimeout(() => ac.abort(), 100);
try {
for await (const _line of iter) { /* ... */ }
} catch (err) {
if ((err as { code?: string }).code === "HIBP.ABORTED") {
// user cancelled
}
}
```
## API Reference
- `streamParseRangeBody(body, { strict, signal? }): AsyncGenerator<RangeLine>`.
## Implementation Notes
The `TextDecoderStream` typings model the writable side as
`BufferSource`, which trips the structural `pipeThrough` constraint, so
the parser casts at the boundary. Calls to `Response.text()` are
forbidden by the spec — the test suite asserts zero invocations. The
generator's `finally` clause releases the underlying reader even when
the consumer breaks out early, preventing leaked readable streams when
a caller chooses to short-circuit on the first match.