Files
skills/docs/security-stack/security/hibp/src/range/range-stream-parse.md
2026-05-29 08:20:56 +01:00

2.1 KiB

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

import { streamParseRangeBody } from "@suaveplan/hibp";

for await (const line of streamParseRangeBody(response.body!, { strict: true })) {
    if (line.suffix === expected) /* ... */;
}

Usage: Advanced Example

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.