import { encode, length } from "quicvarint"; //#region src/stream-decoder.d.ts /** Default maximum encoded non-content bytes accepted in one message. */ declare const DEFAULT_MAX_METADATA_SIZE: number; interface BHttpStreamDecoderOptions { /** * Maximum total encoded non-content bytes accepted in one message. * * This includes request control data, response status and informational * responses, header fields, trailers, and their length encodings. Content * and padding are excluded. * * @default 65536 */ readonly maxMetadataSize?: number; } /** * Events emitted by the streaming decoder. */ type BHttpEvent = BHttpRequestPreambleEvent | BHttpResponsePreambleEvent | BHttpInformationalEvent | BHttpContentEvent | BHttpTrailersEvent | BHttpEndEvent; interface BHttpRequestPreambleEvent { readonly type: "request-preamble"; readonly method: string; readonly scheme: string; readonly authority: string; readonly path: string; readonly headers: Headers; } interface BHttpResponsePreambleEvent { readonly type: "response-preamble"; readonly status: number; readonly headers: Headers; } interface BHttpInformationalEvent { readonly type: "informational"; readonly status: number; readonly headers: Headers; } interface BHttpContentEvent { readonly type: "content"; /** Content bytes. Events form a byte stream: one encoded content chunk may * surface as several events (bytes are emitted as they arrive rather than * buffered until the chunk completes), so chunk boundaries are not * preserved. May be a view into a buffer passed to push(); valid as long * as the caller does not mutate buffers it has pushed. */ readonly data: Uint8Array; } interface BHttpTrailersEvent { readonly type: "trailers"; readonly headers: Headers; } interface BHttpEndEvent { readonly type: "end"; } /** * Streaming BHTTP decoder. * * Usage: * ```ts * const decoder = new BHttpStreamDecoder(); * for (const chunk of incomingData) { * for (const event of decoder.push(chunk)) { * switch (event.type) { * case "request-preamble": // ... * case "content": // ... * } * } * } * for (const event of decoder.end()) { * // handle final events * } * ``` */ declare class BHttpStreamDecoder { private _buffer; private _offset; private _phase; private _isRequest; private _isKnownLength; private _method; private _scheme; private _authority; private _path; private _controlStep; private _status; private _informationalStatus; private _knownSectionLen; private _knownSectionEnd; private _knownSectionLenRead; private _contentRemaining; private _contentStarted; private _headers; private _pendingHeaderName; private readonly _maxMetadataSize; private _metadataBytes; constructor(options?: BHttpStreamDecoderOptions); private _chargeMetadata; private _shouldContinueProcessing; /** * Push bytes into the decoder and get parsed events. * * The decoder holds `data` by reference until it is consumed, and emitted * content events may be views into it — the caller must not mutate or reuse * a pushed buffer afterwards (copy first when filling a fixed read buffer, * e.g. with a BYOB reader). * * @param data - Incoming bytes * @returns Array of parsed events (may be empty if more data needed) */ push(data: Uint8Array): BHttpEvent[]; /** * Signal end of input and get any remaining events. * * @returns Final events * @throws InvalidMessageError if message is incomplete */ end(): BHttpEvent[]; private _discardPadding; /** * Process current phase, returning event if complete. * Returns undefined if more data needed, null if phase complete but no event. */ private _processPhase; private _vli; /** * Read the VLI at `_offset` without consuming it. `_vli.p` is left pointing * just past it, so a caller that keeps the value assigns `_offset = _vli.p`. * * Returns undefined when the buffer ends mid-VLI. A VLI above quicvarint's * MAX throws, since no amount of further data makes it valid. */ private _peekVli; private _processFraming; private _processRequestControl; private _processResponseStatus; private _processHeadersKnown; private _processHeadersIndeterminate; private _tryParseKnownLengthHeaders; private _tryParseIndeterminateLengthHeaders; private _emitPreambleEvent; private _processContentKnown; private _processContentIndeterminate; private _processTrailersKnown; private _processTrailersIndeterminate; /** * Try to decode a VLI-prefixed string. Returns undefined if not enough data. * Does NOT rollback offset on failure - caller must handle. */ private _tryDecodeVliString; } //#endregion //#region src/decoder.d.ts declare class BHttpDecoder { private _td; constructor(); decodeRequest(src: ArrayBuffer | Uint8Array): Request; decodeResponse(src: ArrayBuffer | Uint8Array): Response; /** Decode a BHTTP byte stream into a Request whose body remains streaming. */ decodeRequestStream(src: ReadableStream, options?: BHttpStreamDecoderOptions): Promise; /** Decode a BHTTP byte stream into a Response whose body remains streaming. */ decodeResponseStream(src: ReadableStream, options?: BHttpStreamDecoderOptions): Promise; private decodeKnownLengthRequest; private decodeIndeterminateLengthRequest; private decodeKnownLengthResponse; private decodeIndeterminateLengthResponse; private decodeRequestControlData; private decodeKnownLengthInformationalResponsesAndHeaders; private decodeIndeterminateLengthInformationalResponsesAndHeaders; private decodeKnownLengthInformationalResponse; private decodeIndeterminateLengthInformationalResponse; private decodeKnownLengthRequestHeaders; private decodeKnownLengthResponseHeaders; private decodeIndeterminateLengthRequestHeaders; private decodeIndeterminateLengthResponseHeaders; private decodeKnownLengthContent; private decodeIndeterminateLengthContent; private decodeKnownLengthTrailers; private decodeIndeterminateLengthTrailers; private isAtEnd; private checkPadding; private decodeVliAndValue; private decodeVli; } //#endregion //#region src/encoder.d.ts declare class BHttpEncoder { encodeRequest(src: Request, options?: BHttpEncoderOptions): Promise; encodeResponse(src: Response, options?: BHttpEncoderOptions): Promise; /** Encode a Request as an indeterminate-length, backpressure-aware BHTTP stream. */ encodeRequestStream(src: Request, options?: BHttpEncoderOptions): ReadableStream; /** Encode a Response as an indeterminate-length, backpressure-aware BHTTP stream. */ encodeResponseStream(src: Response, options?: BHttpEncoderOptions): ReadableStream; private encodeStream; private encodeKnownLengthRequest; private encodeKnownLengthResponse; private encodeVliAndValue; private encodeVli; } interface BHttpEncoderOptions { /** Maximum encoded bytes, including padding. */ readonly maxMessageSize?: number; /** Pad the complete message to a multiple of this many bytes. 0 disables padding. @default 0 */ readonly padding?: number; } //#endregion //#region src/errors.d.ts /** * The base error class of hpke-js. */ declare class BHttpError extends Error {} /** * Invalid message. */ declare class InvalidMessageError extends BHttpError {} /** Message metadata exceeds the decoder's configured resource limit. */ declare class MetadataLimitExceededError extends BHttpError {} /** Encoded message exceeds the encoder's configured size limit. */ declare class MessageLimitExceededError extends BHttpError {} /** * Not supported data. */ declare class NotSupportedError extends BHttpError {} //#endregion //#region src/stream-encoder.d.ts /** * Streaming BHTTP encoder for indeterminate-length messages. * * RFC 9292 Section 3.2: Indeterminate-Length Messages * - Framing indicator 2 = request, 3 = response * - Headers terminated by 0 (Name Length = 0) * - Content chunks: varint length + data, terminated by 0 * - Trailers terminated by 0 */ /** * Streaming encoder for BHTTP requests (indeterminate-length). * * Usage: * ```ts * const encoder = new BHttpRequestStreamEncoder(); * yield encoder.encodePreamble("POST", "https", "example.com", "/api", headers); * yield encoder.encodeContentChunk(chunk1); * yield encoder.encodeContentChunk(chunk2); * yield encoder.encodeEnd(); * ``` */ declare class BHttpRequestStreamEncoder { private _preambleEncoded; private _ended; /** * Encode request preamble: framing indicator + control data + headers. * * @param method - HTTP method (e.g., "GET", "POST") * @param scheme - URL scheme (e.g., "https") * @param authority - Host and optional port (e.g., "example.com:8080") * @param path - Request path with query (e.g., "/api?foo=bar") * @param headers - Request headers */ encodePreamble(method: string, scheme: string, authority: string, path: string, headers: Headers): Uint8Array; /** * Encode a content chunk as a single buffer (copies `data` once). * * Prefer {@link encodeContentChunkParts} when the destination accepts * multiple writes (e.g. a stream): it skips the copy. * * @param data - Chunk data (must be non-empty) */ encodeContentChunk(data: Uint8Array): Uint8Array; /** * Encode a content chunk as its wire parts, without copying the data: * the VLI length prefix and `data` itself, to be written in order. * * @param data - Chunk data (must be non-empty); returned as-is (aliased) */ encodeContentChunkParts(data: Uint8Array): [Uint8Array, Uint8Array]; /** * Encode end: content terminator + trailers. * * @param trailers - Optional trailing headers */ encodeEnd(trailers?: Headers): Uint8Array; } /** * Streaming encoder for BHTTP responses (indeterminate-length). * * Usage: * ```ts * const encoder = new BHttpResponseStreamEncoder(); * yield encoder.encodePreamble(200, headers); * yield encoder.encodeContentChunk(chunk1); * yield encoder.encodeEnd(); * ``` */ declare class BHttpResponseStreamEncoder { private _preambleEncoded; private _ended; /** * Encode response preamble: framing indicator + status + headers. * * @param status - HTTP status code (e.g., 200, 404) * @param headers - Response headers * @param informationalResponses - Optional 1xx informational responses */ encodePreamble(status: number, headers: Headers, informationalResponses?: Array<{ status: number; headers: Headers; }>): Uint8Array; /** * Encode a content chunk as a single buffer (copies `data` once). * * Prefer {@link encodeContentChunkParts} when the destination accepts * multiple writes (e.g. a stream): it skips the copy. * * @param data - Chunk data (must be non-empty) */ encodeContentChunk(data: Uint8Array): Uint8Array; /** * Encode a content chunk as its wire parts, without copying the data: * the VLI length prefix and `data` itself, to be written in order. * * @param data - Chunk data (must be non-empty); returned as-is (aliased) */ encodeContentChunkParts(data: Uint8Array): [Uint8Array, Uint8Array]; /** * Encode end: content terminator + trailers. * * @param trailers - Optional trailing headers */ encodeEnd(trailers?: Headers): Uint8Array; } //#endregion //#region src/vli.d.ts /** * Result of decoding a VLI. */ interface VliDecodeResult { /** The decoded value */ readonly value: number; /** Number of bytes consumed */ readonly bytesRead: number; } /** * Decode a VLI from buffer at offset. * * Returns undefined if not enough bytes are available (enables streaming). * * @throws if the encoded value exceeds {@link MAX}. */ declare function decodeVli(buf: Uint8Array, offset: number): VliDecodeResult | undefined; //#endregion export { type BHttpContentEvent, BHttpDecoder, BHttpEncoder, type BHttpEncoderOptions, type BHttpEndEvent, type BHttpEvent, type BHttpInformationalEvent, type BHttpRequestPreambleEvent, BHttpRequestStreamEncoder, type BHttpResponsePreambleEvent, BHttpResponseStreamEncoder, BHttpStreamDecoder, type BHttpStreamDecoderOptions, type BHttpTrailersEvent, DEFAULT_MAX_METADATA_SIZE, InvalidMessageError, MessageLimitExceededError, MetadataLimitExceededError, NotSupportedError, type VliDecodeResult, decodeVli, encode as encodeVli, length as vliEncodedLength }; //# sourceMappingURL=index.d.mts.map