import { ReadableStreamBYOBReadResult , ReadableStreamBYOBReader , TransformStream , } from "stream/web" ; import { bufferSourceToArray , buildNotBufferSourceError , isBufferSource , } from "./helpers" ; export type ArrayBufferViewConstructor = typeof Int8Array | typeof Uint8Array | typeof Uint8ClampedArray | typeof Int16Array | typeof Uint16Array | typeof Int32Array | typeof Uint32Array | typeof Float32Array | typeof Float64Array | typeof DataView ; ReadableStreamBYOBReader . prototype . readAtLeast = async function < T extends ArrayBufferView > ( bytes , view ) : Promise < ReadableStreamBYOBReadResult < T > > { const { byteOffset , byteLength } = view ; if ( isNaN ( bytes ) || bytes <= 0 ) { throw new TypeError ( `Requested invalid minimum number of bytes to read (${ bytes }).` ) ; } if ( byteLength <= 0 ) { throw new TypeError ( 'You must call read() on a "byob" reader with a positive-sized TypedArray object.' ) ; } if ( bytes > byteLength ) { throw new TypeError ( `Minimum bytes to read (${ bytes }) exceeds size of buffer (${ byteLength }).` ) ; } const proto = Object . getPrototypeOf ( view ) ; const bytesPerElement = proto . BYTES_PER_ELEMENT ?? 1 ; const ctor = proto . constructor ; let buffer = view . buffer ; let read = 0 ; let done = false ; while ( read < byteLength && read < bytes ) { const result = await this . read ( new ctor ( buffer , byteOffset + read , ( byteLength - read ) / bytesPerElement ) ) ; if ( result . value ) { buffer = result . value . buffer ; read += result . value . byteLength ; } if ( result . done ) { done = read === 0 ; break ; } } const value = new ctor ( buffer , byteOffset , read / bytesPerElement ) ; return { value : value as any , done } ; } ; export const kContentLength = Symbol ( "kContentLength" ) ; export class FixedLengthStream extends TransformStream < Uint8Array , Uint8Array > { constructor ( expectedLength ) { if ( typeof expectedLength !== "number" || expectedLength < 0 ) { throw new TypeError ( "FixedLengthStream requires a non-negative integer expected length." ) ; } let written = 0 ; super ( { transform ( chunk , controller ) { if ( isBufferSource ( chunk ) ) { const array = bufferSourceToArray ( chunk ) ; written += array . byteLength ; if ( written > expectedLength ) { return controller . error ( new TypeError ( "Attempt to write too many bytes through a FixedLengthStream." ) ) ; } controller . enqueue ( array ) ; } else { controller . error ( new TypeError ( buildNotBufferSourceError ( chunk ) ) ) ; } } , flush ( controller ) { if ( written < expectedLength ) { controller . error ( new TypeError ( "FixedLengthStream did not see all expected bytes before close()." ) ) ; } } , } ) ; ( this . readable as any ) [ kContentLength ] = expectedLength ; } }