@php-wasm/stream-compression 3.0.15 → 3.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.cjs.map +1 -1
- package/index.js.map +1 -1
- package/package.json +4 -4
package/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../../../packages/php-wasm/stream-compression/src/utils/concat-uint8-array.ts","../../../../packages/php-wasm/stream-compression/src/utils/concat-bytes.ts","../../../../packages/php-wasm/stream-compression/src/utils/limit-bytes.ts","../../../../packages/php-wasm/stream-compression/src/utils/collect-bytes.ts","../../../../packages/php-wasm/stream-compression/src/utils/collect-file.ts","../../../../packages/php-wasm/stream-compression/src/utils/iterator-to-stream.ts","../../../../packages/php-wasm/stream-compression/src/utils/streamed-file.ts","../../../../packages/php-wasm/stream-compression/src/utils/iterable-stream-polyfill.ts","../../../../packages/php-wasm/stream-compression/src/zip/types.ts","../../../../packages/php-wasm/stream-compression/src/utils/filter-stream.ts","../../../../packages/php-wasm/stream-compression/src/utils/prepend-bytes.ts","../../../../packages/php-wasm/stream-compression/src/utils/append-bytes.ts","../../../../packages/php-wasm/stream-compression/src/zip/decode-zip.ts","../../../../packages/php-wasm/stream-compression/src/zip/decode-remote-zip.ts","../../../../packages/php-wasm/stream-compression/src/zip/encode-zip.ts"],"sourcesContent":["/**\n * Concatenates multiple Uint8Arrays into a single Uint8Array.\n *\n * @param arrays The arrays to concatenate.\n * @returns A new Uint8Array containing the contents of all the arrays.\n */\nexport function concatUint8Array(...arrays: Uint8Array[]) {\n\tconst result = new Uint8Array(\n\t\tarrays.reduce((sum, array) => sum + array.length, 0)\n\t);\n\tlet offset = 0;\n\tfor (const array of arrays) {\n\t\tresult.set(array, offset);\n\t\toffset += array.length;\n\t}\n\treturn result;\n}\n","import { concatUint8Array } from './concat-uint8-array';\n\n/**\n * Concatenates the contents of the stream into a single Uint8Array.\n *\n * @param totalBytes Optional. The number of bytes to concatenate. Used to\n * \t\t\t\t pre-allocate the buffer. If not provided, the buffer will\n * \t\t\t\t be dynamically resized as needed.\n * @returns A stream that will emit a single UInt8Array entry before closing.\n */\nexport function concatBytes(totalBytes?: number) {\n\tif (totalBytes === undefined) {\n\t\tlet acc = new Uint8Array();\n\t\treturn new TransformStream<Uint8Array, Uint8Array>({\n\t\t\ttransform(chunk) {\n\t\t\t\tacc = concatUint8Array(acc, chunk);\n\t\t\t},\n\n\t\t\tflush(controller) {\n\t\t\t\tcontroller.enqueue(acc);\n\t\t\t},\n\t\t});\n\t} else {\n\t\tconst buffer = new ArrayBuffer(totalBytes || 0);\n\t\tlet offset = 0;\n\t\treturn new TransformStream<Uint8Array, Uint8Array>({\n\t\t\ttransform(chunk) {\n\t\t\t\tconst view = new Uint8Array(buffer);\n\t\t\t\tview.set(chunk, offset);\n\t\t\t\toffset += chunk.byteLength;\n\t\t\t},\n\n\t\t\tflush(controller) {\n\t\t\t\tcontroller.enqueue(new Uint8Array(buffer));\n\t\t\t},\n\t\t});\n\t}\n}\n","/**\n * Limit the number of bytes read from a stream.\n *\n * @param stream The stream to limit.\n * @param bytes The number of bytes to read from the stream.\n * @returns A new stream that will read at most `bytes` bytes from `stream`.\n */\nexport function limitBytes(stream: ReadableStream<Uint8Array>, bytes: number) {\n\tif (bytes === 0) {\n\t\treturn new ReadableStream({\n\t\t\tstart(controller) {\n\t\t\t\tcontroller.close();\n\t\t\t},\n\t\t});\n\t}\n\tconst reader = stream.getReader({ mode: 'byob' });\n\tlet offset = 0;\n\treturn new ReadableStream({\n\t\tasync pull(controller) {\n\t\t\tconst { value, done } = await reader.read(\n\t\t\t\tnew Uint8Array(bytes - offset)\n\t\t\t);\n\t\t\tif (done) {\n\t\t\t\treader.releaseLock();\n\t\t\t\tcontroller.close();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\toffset += value.length;\n\t\t\tcontroller.enqueue(value);\n\n\t\t\tif (offset >= bytes) {\n\t\t\t\treader.releaseLock();\n\t\t\t\tcontroller.close();\n\t\t\t}\n\t\t},\n\t\tcancel() {\n\t\t\treader.cancel();\n\t\t},\n\t});\n}\n","import { concatBytes } from './concat-bytes';\nimport { limitBytes } from './limit-bytes';\n\n/**\n * Collects the contents of the entire stream into a single Uint8Array.\n *\n * @param stream The stream to collect.\n * @param bytes Optional. The number of bytes to read from the stream.\n * @returns The string contents of the stream.\n */\nexport async function collectBytes(\n\tstream: ReadableStream<Uint8Array>,\n\tbytes?: number\n) {\n\tif (bytes !== undefined) {\n\t\tstream = limitBytes(stream, bytes);\n\t}\n\n\treturn await stream\n\t\t.pipeThrough(concatBytes(bytes))\n\t\t.getReader()\n\t\t.read()\n\t\t.then(({ value }) => value!);\n}\n","import { collectBytes } from './collect-bytes';\n\n/**\n * Collects the contents of the entire stream into a single File object.\n *\n * @param stream The stream to collect.\n * @param fileName The name of the file\n * @returns The string contents of the stream.\n */\nexport async function collectFile(\n\tfileName: string,\n\tstream: ReadableStream<Uint8Array>\n) {\n\t// @TODO: use StreamingFile\n\treturn new File([await collectBytes(stream)], fileName);\n}\n","import type { IterableReadableStream } from './iterable-stream-polyfill';\n\n/**\n * Converts an iterator or iterable to a stream.\n *\n * @param iteratorOrIterable The iterator or iterable to convert.\n * @returns A stream that will yield the values from the iterator or iterable.\n */\nexport function iteratorToStream<T>(\n\titeratorOrIterable:\n\t\t| AsyncIterator<T>\n\t\t| Iterator<T>\n\t\t| AsyncIterable<T>\n\t\t| Iterable<T>\n) {\n\tif (iteratorOrIterable instanceof ReadableStream) {\n\t\treturn iteratorOrIterable as IterableReadableStream<T>;\n\t}\n\n\tlet iterator: AsyncIterator<T> | Iterator<T>;\n\tif (Symbol.asyncIterator in iteratorOrIterable) {\n\t\titerator = iteratorOrIterable[Symbol.asyncIterator]();\n\t} else if (Symbol.iterator in iteratorOrIterable) {\n\t\titerator = iteratorOrIterable[Symbol.iterator]();\n\t} else {\n\t\titerator = iteratorOrIterable;\n\t}\n\n\treturn new ReadableStream<T>({\n\t\tasync pull(controller) {\n\t\t\tconst { done, value } = await iterator.next();\n\t\t\tif (done) {\n\t\t\t\tcontroller.close();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcontroller.enqueue(value);\n\t\t},\n\t}) as IterableReadableStream<T>;\n}\n","import { collectBytes } from './collect-bytes';\n\n/**\n * Represents a file that is streamed and not fully\n * loaded into memory.\n */\nexport class StreamedFile extends File {\n\treadonly filesize: number | undefined;\n\n\tprivate readableStream: ReadableStream<Uint8Array>;\n\n\t/**\n\t * Creates a new StreamedFile instance.\n\t *\n\t * @param readableStream The readable stream containing the file data.\n\t * @param name The name of the file.\n\t * @param options An object containing options such as the MIME type and file size.\n\t */\n\tconstructor(\n\t\treadableStream: ReadableStream<Uint8Array>,\n\t\tname: string,\n\t\toptions?: { type?: string; filesize?: number }\n\t) {\n\t\tsuper([], name, { type: options?.type });\n\t\tthis.readableStream = readableStream;\n\t\tthis.filesize = options?.filesize;\n\t}\n\n\t/**\n\t * Overrides the slice() method of the File class.\n\t *\n\t * @returns A Blob representing a portion of the file.\n\t */\n\toverride slice(): Blob {\n\t\tthrow new Error('slice() is not possible on a StreamedFile');\n\t}\n\n\t/**\n\t * Returns the readable stream associated with the file.\n\t *\n\t * @returns The readable stream.\n\t */\n\toverride stream() {\n\t\treturn this.readableStream;\n\t}\n\n\t/**\n\t * Loads the file data into memory and then returns it as a string.\n\t *\n\t * @returns File data as text.\n\t */\n\toverride async text() {\n\t\treturn new TextDecoder().decode(await this.arrayBuffer());\n\t}\n\n\t/**\n\t * Loads the file data into memory and then returns it as an ArrayBuffer.\n\t *\n\t * @returns File data as an ArrayBuffer.\n\t */\n\toverride async arrayBuffer() {\n\t\treturn await collectBytes(this.stream());\n\t}\n}\n","/**\n * Polyfill for ReadableStream[Symbol.asyncIterator]\n * This enables the use of for-await-of loops with ReadableStreams\n *\n * @example\n * ```ts\n * for await (const entry of stream) {\n * \t // ...\n * }\n * ```\n */\n// @ts-ignore\nif (!ReadableStream.prototype[Symbol.asyncIterator]) {\n\t// @ts-ignore\n\tReadableStream.prototype[Symbol.asyncIterator] = async function* () {\n\t\tconst reader = this.getReader();\n\t\ttry {\n\t\t\twhile (true) {\n\t\t\t\tconst { done, value } = await reader.read();\n\t\t\t\tif (done) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tyield value;\n\t\t\t}\n\t\t} finally {\n\t\t\treader.releaseLock();\n\t\t}\n\t};\n\t// @ts-ignore\n\tReadableStream.prototype.iterate =\n\t\t// @ts-ignore\n\t\tReadableStream.prototype[Symbol.asyncIterator];\n}\n\nexport type IterableReadableStream<R> = ReadableStream<R> & AsyncIterable<R>;\n","export const FILE_HEADER_SIZE = 32;\nexport const SIGNATURE_FILE = 67324752 as const;\nexport const SIGNATURE_CENTRAL_DIRECTORY = 33639248 as const;\nexport const SIGNATURE_CENTRAL_DIRECTORY_END = 101010256 as const;\nexport const SIGNATURE_DATA_DESCRIPTOR = 134695760 as const;\n\nexport const COMPRESSION_NONE = 0 as const;\nexport const COMPRESSION_DEFLATE = 8 as const;\nexport type CompressionMethod =\n\t| typeof COMPRESSION_NONE\n\t| typeof COMPRESSION_DEFLATE;\n\nexport type ZipEntry =\n\t| FileEntry\n\t| CentralDirectoryEntry\n\t| CentralDirectoryEndEntry;\n\n/**\n * Data of the file entry header encoded in a \".zip\" file.\n */\nexport interface FileHeader {\n\tsignature: typeof SIGNATURE_FILE;\n\tversion: number;\n\tgeneralPurpose: number;\n\tcompressionMethod: CompressionMethod;\n\tlastModifiedTime: number;\n\tlastModifiedDate: number;\n\tcrc: number;\n\tcompressedSize: number;\n\tuncompressedSize: number;\n\tpath: Uint8Array;\n\textra: Uint8Array;\n}\nexport interface FileEntry extends FileHeader {\n\tisDirectory: boolean;\n\tbytes: Uint8Array;\n}\n\n/**\n * Data of the central directory entry encoded in a \".zip\" file.\n */\nexport interface CentralDirectoryEntry {\n\tsignature: typeof SIGNATURE_CENTRAL_DIRECTORY;\n\tversionCreated: number;\n\tversionNeeded: number;\n\tgeneralPurpose: number;\n\tcompressionMethod: CompressionMethod;\n\tlastModifiedTime: number;\n\tlastModifiedDate: number;\n\tcrc: number;\n\tcompressedSize: number;\n\tuncompressedSize: number;\n\tdiskNumber: number;\n\tinternalAttributes: number;\n\texternalAttributes: number;\n\tfirstByteAt: number;\n\tlastByteAt: number;\n\tpath: Uint8Array;\n\textra: Uint8Array;\n\tfileComment: Uint8Array;\n\tisDirectory: boolean;\n}\n\n/**\n * Data of the central directory end entry encoded in a \".zip\" file.\n */\nexport interface CentralDirectoryEndEntry {\n\tsignature: typeof SIGNATURE_CENTRAL_DIRECTORY_END;\n\tnumberOfDisks: number;\n\tcentralDirectoryStartDisk: number;\n\tnumberCentralDirectoryRecordsOnThisDisk: number;\n\tnumberCentralDirectoryRecords: number;\n\tcentralDirectorySize: number;\n\tcentralDirectoryOffset: number;\n\tcomment: Uint8Array;\n}\n","/**\n * Filter the stream based on a predicate.\n *\n * @param predicate The predicate to filter the stream with.\n * @returns A new stream that will only contain chunks that pass the predicate.\n */\nexport function filterStream<T>(predicate: (chunk: T) => boolean) {\n\treturn new TransformStream<T, T>({\n\t\ttransform(chunk, controller) {\n\t\t\tif (predicate(chunk)) {\n\t\t\t\tcontroller.enqueue(chunk);\n\t\t\t}\n\t\t},\n\t});\n}\n","/**\n * Prepend bytes to a stream.\n *\n * @param bytes The bytes to prepend.\n * @returns A transform stream that will prepend the specified bytes.\n */\nexport function prependBytes(bytes: Uint8Array) {\n\tlet isPrepended = false;\n\treturn new TransformStream<Uint8Array, Uint8Array>({\n\t\tasync transform(chunk, controller) {\n\t\t\tif (!isPrepended) {\n\t\t\t\tisPrepended = true;\n\t\t\t\tcontroller.enqueue(bytes);\n\t\t\t}\n\t\t\tcontroller.enqueue(chunk);\n\t\t},\n\t});\n}\n","/**\n * Appends bytes to a stream.\n *\n * @param bytes The bytes to append.\n * @returns A transform stream that will append the specified bytes.\n */\nexport function appendBytes(bytes: Uint8Array) {\n\treturn new TransformStream<Uint8Array, Uint8Array>({\n\t\tasync transform(chunk, controller) {\n\t\t\tcontroller.enqueue(chunk);\n\t\t},\n\t\tasync flush(controller) {\n\t\t\tcontroller.enqueue(bytes);\n\t\t},\n\t});\n}\n","/**\n * Reads files from a stream of zip file bytes.\n */\nimport type { IterableReadableStream } from '../utils/iterable-stream-polyfill';\n\nimport type { CompressionMethod } from './types';\nimport {\n\tSIGNATURE_FILE,\n\tSIGNATURE_CENTRAL_DIRECTORY,\n\tSIGNATURE_CENTRAL_DIRECTORY_END,\n\tFILE_HEADER_SIZE,\n\tCOMPRESSION_DEFLATE,\n} from './types';\nimport type {\n\tCentralDirectoryEntry,\n\tFileEntry,\n\tZipEntry,\n\tCentralDirectoryEndEntry,\n} from './types';\nimport { filterStream } from '../utils/filter-stream';\nimport { collectBytes } from '../utils/collect-bytes';\nimport { limitBytes } from '../utils/limit-bytes';\nimport { concatBytes } from '../utils/concat-bytes';\nimport { prependBytes } from '../utils/prepend-bytes';\nimport { appendBytes } from '../utils/append-bytes';\n\n/**\n * Unzips a stream of zip file bytes.\n *\n * @param stream A stream of zip file bytes.\n * @param predicate Optional. A function that returns true if the file should be downloaded.\n * @returns An iterable stream of File objects.\n */\nexport function decodeZip(\n\tstream: ReadableStream<Uint8Array>,\n\tpredicate?: () => boolean\n) {\n\treturn streamZippedFileEntries(stream, predicate).pipeThrough(\n\t\tnew TransformStream<FileEntry, File>({\n\t\t\tasync transform(zipEntry, controller) {\n\t\t\t\tconst file = new File(\n\t\t\t\t\t[zipEntry.bytes],\n\t\t\t\t\tnew TextDecoder().decode(zipEntry.path),\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: zipEntry.isDirectory ? 'directory' : undefined,\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t\tcontroller.enqueue(file);\n\t\t\t},\n\t\t})\n\t) as IterableReadableStream<File>;\n}\n\nconst DEFAULT_PREDICATE = () => true;\n\n/**\n * Parses a stream of zipped bytes into FileEntry informations.\n *\n * @param stream A stream of zip file bytes.\n * @param predicate Optional. A function that returns true if the file should be downloaded.\n * @returns An iterable stream of FileEntry objects.\n */\nexport function streamZippedFileEntries(\n\tstream: ReadableStream<Uint8Array>,\n\tpredicate: (\n\t\tdirEntry: CentralDirectoryEntry | FileEntry\n\t) => boolean = DEFAULT_PREDICATE\n) {\n\tconst entriesStream = new ReadableStream<ZipEntry>({\n\t\tasync pull(controller) {\n\t\t\tconst entry = await nextZipEntry(stream);\n\t\t\tif (!entry) {\n\t\t\t\tcontroller.close();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcontroller.enqueue(entry);\n\t\t},\n\t}) as IterableReadableStream<ZipEntry>;\n\n\treturn entriesStream\n\t\t.pipeThrough(\n\t\t\tfilterStream(({ signature }) => signature === SIGNATURE_FILE)\n\t\t)\n\t\t.pipeThrough(\n\t\t\tfilterStream(predicate as any)\n\t\t) as IterableReadableStream<FileEntry>;\n}\n\n/**\n * Reads the next zip entry from a stream of zip file bytes.\n *\n * @param stream A stream of zip file bytes.\n * @returns A FileEntry object.\n */\nasync function nextZipEntry(stream: ReadableStream<Uint8Array>) {\n\tconst sigData = new DataView((await collectBytes(stream, 4))!.buffer);\n\tconst signature = sigData.getUint32(0, true);\n\tif (signature === SIGNATURE_FILE) {\n\t\treturn await readFileEntry(stream, true);\n\t} else if (signature === SIGNATURE_CENTRAL_DIRECTORY) {\n\t\treturn await readCentralDirectoryEntry(stream, true);\n\t} else if (signature === SIGNATURE_CENTRAL_DIRECTORY_END) {\n\t\treturn await readEndCentralDirectoryEntry(stream, true);\n\t}\n\treturn null;\n}\n\n/**\n * Reads a file entry from a zip file.\n *\n * The file entry is structured as follows:\n *\n * ```\n * Offset\tBytes\tDescription\n * 0\t\t4\tLocal file header signature = 0x04034b50 (PK♥♦ or \"PK\\3\\4\")\n * 4\t\t2\tVersion needed to extract (minimum)\n * 6\t\t2\tGeneral purpose bit flag\n * 8\t\t2\tCompression method; e.g. none = 0, DEFLATE = 8 (or \"\\0x08\\0x00\")\n * 10\t\t2\tFile last modification time\n * 12\t\t2\tFile last modification date\n * 14\t\t4\tCRC-32 of uncompressed data\n * 18\t\t4\tCompressed size (or 0xffffffff for ZIP64)\n * 22\t\t4\tUncompressed size (or 0xffffffff for ZIP64)\n * 26\t\t2\tFile name length (n)\n * 28\t\t2\tExtra field length (m)\n * 30\t\tn\tFile name\n * 30+n\tm\tExtra field\n * ```\n *\n * @param stream\n * @param skipSignature Do not consume the signature from the stream.\n * @returns\n */\nexport async function readFileEntry(\n\tstream: ReadableStream<Uint8Array>,\n\tskipSignature = false\n): Promise<FileEntry | null> {\n\tif (!skipSignature) {\n\t\tconst sigData = new DataView((await collectBytes(stream, 4))!.buffer);\n\t\tconst signature = sigData.getUint32(0, true);\n\t\tif (signature !== SIGNATURE_FILE) {\n\t\t\treturn null;\n\t\t}\n\t}\n\tconst data = new DataView((await collectBytes(stream, 26))!.buffer);\n\tconst pathLength = data.getUint16(22, true);\n\tconst extraLength = data.getUint16(24, true);\n\tconst entry: Partial<FileEntry> = {\n\t\tsignature: SIGNATURE_FILE,\n\t\tversion: data.getUint32(0, true),\n\t\tgeneralPurpose: data.getUint16(2, true),\n\t\tcompressionMethod: data.getUint16(4, true) as CompressionMethod,\n\t\tlastModifiedTime: data.getUint16(6, true),\n\t\tlastModifiedDate: data.getUint16(8, true),\n\t\tcrc: data.getUint32(10, true),\n\t\tcompressedSize: data.getUint32(14, true),\n\t\tuncompressedSize: data.getUint32(18, true),\n\t};\n\n\tentry['path'] = await collectBytes(stream, pathLength);\n\tentry['isDirectory'] = endsWithSlash(entry.path!);\n\tentry['extra'] = await collectBytes(stream, extraLength);\n\n\t// Make sure we consume the body stream or else\n\t// we'll start reading the next file at the wrong\n\t// offset.\n\t// @TODO: Expose the body stream instead of reading it all\n\t// eagerly. Ensure the next iteration exhausts\n\t// the last body stream before moving on.\n\n\tlet bodyStream = limitBytes(stream, entry['compressedSize']!);\n\n\tif (entry['compressionMethod'] === COMPRESSION_DEFLATE) {\n\t\t/**\n\t\t * We want to write raw deflate-compressed bytes into our\n\t\t * final ZIP file. CompressionStream supports \"deflate-raw\"\n\t\t * compression, but not on Node.js v20, it's available since v21.2.0.\n\t\t *\n\t\t * As a workaround, we use the \"gzip\" compression and add\n\t\t * the header and footer bytes. It works, because \"gzip\"\n\t\t * compression is the same as \"deflate\" compression plus\n\t\t * the header and the footer.\n\t\t *\n\t\t * The header is 10 bytes long:\n\t\t * - 2 magic bytes: 0x1f, 0x8b\n\t\t * - 1 compression method: 0x08 (deflate)\n\t\t * - 1 header flags\n\t\t * - 4 mtime: 0x00000000 (no timestamp)\n\t\t * - 1 compression flags\n\t\t * - 1 OS: 0x03 (Unix)\n\t\t *\n\t\t * The footer is 8 bytes long:\n\t\t * - 4 bytes for CRC32 of the uncompressed data\n\t\t * - 4 bytes for ISIZE (uncompressed size modulo 2^32)\n\t\t */\n\t\tconst header = new Uint8Array(10);\n\t\theader.set([0x1f, 0x8b, 0x08]);\n\n\t\tconst footer = new Uint8Array(8);\n\t\tconst footerView = new DataView(footer.buffer);\n\t\tfooterView.setUint32(0, entry.crc!, true);\n\t\tfooterView.setUint32(4, entry.uncompressedSize! % 2 ** 32, true);\n\t\tbodyStream = bodyStream\n\t\t\t.pipeThrough(prependBytes(header))\n\t\t\t.pipeThrough(appendBytes(footer))\n\t\t\t.pipeThrough(new DecompressionStream('gzip'));\n\t}\n\tentry['bytes'] = await bodyStream\n\t\t.pipeThrough(concatBytes(entry['uncompressedSize']))\n\t\t.getReader()\n\t\t.read()\n\t\t.then(({ value }) => value!);\n\treturn entry as FileEntry;\n}\n\n/**\n * Reads a central directory entry from a zip file.\n *\n * The central directory entry is structured as follows:\n *\n * ```\n * Offset Bytes Description\n * 0\t\t4\tCentral directory file header signature = 0x02014b50\n * 4\t\t2\tVersion made by\n * 6\t\t2\tVersion needed to extract (minimum)\n * 8\t\t2\tGeneral purpose bit flag\n * 10\t\t2\tCompression method\n * 12\t\t2\tFile last modification time\n * 14\t\t2\tFile last modification date\n * 16\t\t4\tCRC-32 of uncompressed data\n * 20\t\t4\tCompressed size (or 0xffffffff for ZIP64)\n * 24\t\t4\tUncompressed size (or 0xffffffff for ZIP64)\n * 28\t\t2\tFile name length (n)\n * 30\t\t2\tExtra field length (m)\n * 32\t\t2\tFile comment length (k)\n * 34\t\t2\tDisk number where file starts (or 0xffff for ZIP64)\n * 36\t\t2\tInternal file attributes\n * 38\t\t4\tExternal file attributes\n * 42\t\t4\tRelative offset of local file header (or 0xffffffff for ZIP64). This is the number of bytes between the start of the first disk on which the file occurs, and the start of the local file header. This allows software reading the central directory to locate the position of the file inside the ZIP file.\n * 46\t\tn\tFile name\n * 46+n\tm\tExtra field\n * 46+n+m\tk\tFile comment\n * ```\n *\n * @param stream\n * @param skipSignature\n * @returns\n */\nexport async function readCentralDirectoryEntry(\n\tstream: ReadableStream<Uint8Array>,\n\tskipSignature = false\n): Promise<CentralDirectoryEntry | null> {\n\tif (!skipSignature) {\n\t\tconst sigData = new DataView((await collectBytes(stream, 4))!.buffer);\n\t\tconst signature = sigData.getUint32(0, true);\n\t\tif (signature !== SIGNATURE_CENTRAL_DIRECTORY) {\n\t\t\treturn null;\n\t\t}\n\t}\n\tconst data = new DataView((await collectBytes(stream, 42))!.buffer);\n\tconst pathLength = data.getUint16(24, true);\n\tconst extraLength = data.getUint16(26, true);\n\tconst fileCommentLength = data.getUint16(28, true);\n\tconst centralDirectory: Partial<CentralDirectoryEntry> = {\n\t\tsignature: SIGNATURE_CENTRAL_DIRECTORY,\n\t\tversionCreated: data.getUint16(0, true),\n\t\tversionNeeded: data.getUint16(2, true),\n\t\tgeneralPurpose: data.getUint16(4, true),\n\t\tcompressionMethod: data.getUint16(6, true) as CompressionMethod,\n\t\tlastModifiedTime: data.getUint16(8, true),\n\t\tlastModifiedDate: data.getUint16(10, true),\n\t\tcrc: data.getUint32(12, true),\n\t\tcompressedSize: data.getUint32(16, true),\n\t\tuncompressedSize: data.getUint32(20, true),\n\t\tdiskNumber: data.getUint16(30, true),\n\t\tinternalAttributes: data.getUint16(32, true),\n\t\texternalAttributes: data.getUint32(34, true),\n\t\tfirstByteAt: data.getUint32(38, true),\n\t};\n\tcentralDirectory['lastByteAt'] =\n\t\tcentralDirectory.firstByteAt! +\n\t\tFILE_HEADER_SIZE +\n\t\tpathLength +\n\t\tfileCommentLength +\n\t\textraLength! +\n\t\tcentralDirectory.compressedSize! -\n\t\t1;\n\n\tcentralDirectory['path'] = await collectBytes(stream, pathLength);\n\tcentralDirectory['isDirectory'] = endsWithSlash(centralDirectory.path!);\n\tcentralDirectory['extra'] = await collectBytes(stream, extraLength);\n\tcentralDirectory['fileComment'] = await collectBytes(\n\t\tstream,\n\t\tfileCommentLength\n\t);\n\treturn centralDirectory as CentralDirectoryEntry;\n}\n\nfunction endsWithSlash(path: Uint8Array) {\n\treturn path[path.byteLength - 1] == '/'.charCodeAt(0);\n}\n\n/**\n * Reads the end of central directory entry from a zip file.\n *\n * The end of central directory entry is structured as follows:\n *\n * ```\n * Offset\tBytes\tDescription[33]\n * 0\t\t 4\t\tEnd of central directory signature = 0x06054b50\n * 4\t\t 2\t\tNumber of this disk (or 0xffff for ZIP64)\n * 6\t\t 2\t\tDisk where central directory starts (or 0xffff for ZIP64)\n * 8\t\t 2\t\tNumber of central directory records on this disk (or 0xffff for ZIP64)\n * 10\t\t 2\t\tTotal number of central directory records (or 0xffff for ZIP64)\n * 12\t\t 4\t\tSize of central directory (bytes) (or 0xffffffff for ZIP64)\n * 16\t\t 4\t\tOffset of start of central directory, relative to start of archive (or 0xffffffff for ZIP64)\n * 20\t\t 2\t\tComment length (n)\n * 22\t\t n\t\tComment\n * ```\n *\n * @param stream\n * @param skipSignature\n * @returns\n */\nasync function readEndCentralDirectoryEntry(\n\tstream: ReadableStream<Uint8Array>,\n\tskipSignature = false\n) {\n\tif (!skipSignature) {\n\t\tconst sigData = new DataView((await collectBytes(stream, 4))!.buffer);\n\t\tconst signature = sigData.getUint32(0, true);\n\t\tif (signature !== SIGNATURE_CENTRAL_DIRECTORY_END) {\n\t\t\treturn null;\n\t\t}\n\t}\n\tconst data = new DataView((await collectBytes(stream, 18))!.buffer);\n\tconst endOfDirectory: Partial<CentralDirectoryEndEntry> = {\n\t\tsignature: SIGNATURE_CENTRAL_DIRECTORY_END,\n\t\tnumberOfDisks: data.getUint16(0, true),\n\t\tcentralDirectoryStartDisk: data.getUint16(2, true),\n\t\tnumberCentralDirectoryRecordsOnThisDisk: data.getUint16(4, true),\n\t\tnumberCentralDirectoryRecords: data.getUint16(6, true),\n\t\tcentralDirectorySize: data.getUint32(8, true),\n\t\tcentralDirectoryOffset: data.getUint32(12, true),\n\t};\n\tconst commentLength = data.getUint16(16, true);\n\tendOfDirectory['comment'] = await collectBytes(stream, commentLength);\n\treturn endOfDirectory as CentralDirectoryEndEntry;\n}\n","import { Semaphore } from '@php-wasm/util';\nimport { filterStream } from '../utils/filter-stream';\nimport { concatUint8Array } from '../utils/concat-uint8-array';\nimport { collectBytes } from '../utils/collect-bytes';\nimport {\n\treadCentralDirectoryEntry,\n\treadFileEntry,\n\tdecodeZip,\n} from './decode-zip';\nimport type { CentralDirectoryEntry, FileEntry } from './types';\nimport { SIGNATURE_CENTRAL_DIRECTORY_END } from './types';\nimport type { IterableReadableStream } from '../utils/iterable-stream-polyfill';\n\nconst CENTRAL_DIRECTORY_END_SCAN_CHUNK_SIZE = 110 * 1024;\nconst BATCH_DOWNLOAD_OF_FILES_IF_CLOSER_THAN = 10 * 1024;\nconst PREFER_RANGES_IF_FILE_LARGER_THAN = 1024 * 1024 * 1;\nconst fetchSemaphore = new Semaphore({ concurrency: 10 });\n\nconst DEFAULT_PREDICATE = () => true;\n\n/**\n * Streams the contents of a remote zip file.\n *\n * If the zip is large and the predicate is filtering the zip contents,\n * only the matching files will be downloaded using the Range header\n * (if supported by the server).\n *\n * @param url The URL of the zip file.\n * @param predicate Optional. A function that returns true if the file should be downloaded.\n * @returns A stream of zip entries.\n */\nexport async function decodeRemoteZip(\n\turl: string,\n\tpredicate: (\n\t\tdirEntry: CentralDirectoryEntry | FileEntry\n\t) => boolean = DEFAULT_PREDICATE\n) {\n\tif (predicate === DEFAULT_PREDICATE) {\n\t\t// If we're not filtering the zip contents, let's just\n\t\t// grab the entire zip.\n\t\tconst response = await fetch(url);\n\t\treturn decodeZip(response.body!);\n\t}\n\n\tconst contentLength = await fetchContentLength(url);\n\tif (contentLength <= PREFER_RANGES_IF_FILE_LARGER_THAN) {\n\t\t// If the zip is small enough, let's just grab it.\n\t\tconst response = await fetch(url);\n\t\treturn decodeZip(response.body!);\n\t}\n\n\t// Ensure ranges query support:\n\t// Fetch one byte\n\tconst response = await fetch(url, {\n\t\theaders: {\n\t\t\t// 0-0 looks weird, doesn't it?\n\t\t\t// The Range header is inclusive so it's actually\n\t\t\t// a valid header asking for the first byte.\n\t\t\tRange: 'bytes=0-0',\n\t\t\t'Accept-Encoding': 'none',\n\t\t},\n\t});\n\n\t// Fork the stream so that we can reuse it in case\n\t// the Range header is unsupported and we're now streaming\n\t// the entire file\n\tconst [peekStream, responseStream] = response.body!.tee();\n\n\t// Read from the forked stream and close it.\n\tconst peekReader = peekStream.getReader();\n\tconst { value: peekBytes } = await peekReader.read();\n\tconst { done: peekDone } = await peekReader.read();\n\tpeekReader.releaseLock();\n\tpeekStream.cancel();\n\n\t// Confirm our Range query worked as intended:\n\tconst rangesSupported = peekBytes?.length === 1 && peekDone;\n\tif (!rangesSupported) {\n\t\t// Uh-oh, we're actually streaming the entire file.\n\t\t// Let's reuse the forked stream as our response stream.\n\t\treturn decodeZip(responseStream);\n\t}\n\n\t// We're good, let's clean up the other branch of the response stream.\n\tresponseStream.cancel();\n\tconst source = await createFetchSource(url, contentLength);\n\treturn streamCentralDirectoryEntries(source)\n\t\t.pipeThrough(filterStream(predicate))\n\t\t.pipeThrough(partitionNearbyEntries())\n\t\t.pipeThrough(\n\t\t\tfetchPartitionedEntries(source)\n\t\t) as IterableReadableStream<FileEntry>;\n}\n\n/**\n * Streams the central directory entries of a zip file.\n *\n * @param source\n * @returns\n */\nfunction streamCentralDirectoryEntries(source: BytesSource) {\n\tlet centralDirectoryStream: ReadableStream<Uint8Array>;\n\n\treturn new ReadableStream<CentralDirectoryEntry>({\n\t\tasync start() {\n\t\t\tcentralDirectoryStream = await streamCentralDirectoryBytes(source);\n\t\t},\n\t\tasync pull(controller) {\n\t\t\tconst entry = await readCentralDirectoryEntry(\n\t\t\t\tcentralDirectoryStream\n\t\t\t);\n\t\t\tif (!entry) {\n\t\t\t\tcontroller.close();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcontroller.enqueue(entry);\n\t\t},\n\t});\n}\n\n/**\n * Streams the central directory bytes of a zip file.\n *\n * @param source\n * @returns\n */\nasync function streamCentralDirectoryBytes(source: BytesSource) {\n\tconst chunkSize = CENTRAL_DIRECTORY_END_SCAN_CHUNK_SIZE;\n\tlet centralDirectory: Uint8Array = new Uint8Array();\n\n\tlet chunkStart = source.length;\n\tdo {\n\t\tchunkStart = Math.max(0, chunkStart - chunkSize);\n\t\tconst chunkEnd = Math.min(\n\t\t\tchunkStart + chunkSize - 1,\n\t\t\tsource.length - 1\n\t\t);\n\t\tconst bytes = await collectBytes(\n\t\t\tawait source.streamBytes(chunkStart, chunkEnd)\n\t\t);\n\t\tcentralDirectory = concatUint8Array(bytes!, centralDirectory);\n\n\t\t// Scan the buffer for the signature\n\t\tconst view = new DataView(bytes!.buffer);\n\t\tfor (let i = view.byteLength - 4; i >= 0; i--) {\n\t\t\tif (view.getUint32(i, true) !== SIGNATURE_CENTRAL_DIRECTORY_END) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Confirm we have enough data to read the offset and the\n\t\t\t// length of the central directory.\n\t\t\tconst centralDirectoryLengthAt = i + 12;\n\t\t\tconst centralDirectoryOffsetAt = centralDirectoryLengthAt + 4;\n\t\t\tif (centralDirectory.byteLength < centralDirectoryOffsetAt + 4) {\n\t\t\t\tthrow new Error('Central directory not found');\n\t\t\t}\n\n\t\t\t// Read where the central directory starts\n\t\t\tconst dirStart = view.getUint32(centralDirectoryOffsetAt, true);\n\t\t\tif (dirStart < chunkStart) {\n\t\t\t\t// We're missing some bytes, let's grab them\n\t\t\t\tconst missingBytes = await collectBytes(\n\t\t\t\t\tawait source.streamBytes(dirStart, chunkStart - 1)\n\t\t\t\t);\n\t\t\t\tcentralDirectory = concatUint8Array(\n\t\t\t\t\tmissingBytes!,\n\t\t\t\t\tcentralDirectory\n\t\t\t\t);\n\t\t\t} else if (dirStart > chunkStart) {\n\t\t\t\t// We've read too many bytes, let's trim them\n\t\t\t\tcentralDirectory = centralDirectory.slice(\n\t\t\t\t\tdirStart - chunkStart\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn new Blob([centralDirectory]).stream();\n\t\t}\n\t} while (chunkStart >= 0);\n\n\tthrow new Error('Central directory not found');\n}\n\n/**\n * Partitions files that are no further apart in the zip\n * archive than BATCH_DOWNLOAD_OF_FILES_IF_CLOSER_THAN.\n * It may download some extra files living within the gaps\n * between the partitions.\n */\nfunction partitionNearbyEntries() {\n\tlet lastFileEndsAt = 0;\n\tlet currentChunk: CentralDirectoryEntry[] = [];\n\treturn new TransformStream<CentralDirectoryEntry, CentralDirectoryEntry[]>({\n\t\ttransform(zipEntry, controller) {\n\t\t\t// Byte distance too large, flush and start a new chunk\n\t\t\tif (\n\t\t\t\tzipEntry.firstByteAt >\n\t\t\t\tlastFileEndsAt + BATCH_DOWNLOAD_OF_FILES_IF_CLOSER_THAN\n\t\t\t) {\n\t\t\t\tcontroller.enqueue(currentChunk);\n\t\t\t\tcurrentChunk = [];\n\t\t\t}\n\t\t\tlastFileEndsAt = zipEntry.lastByteAt;\n\t\t\tcurrentChunk.push(zipEntry);\n\t\t},\n\t\tflush(controller) {\n\t\t\tcontroller.enqueue(currentChunk);\n\t\t},\n\t});\n}\n\n/**\n * Fetches a chunk of files from the zip archive.\n *\n * If any extra files are present in the received\n * bytes stream, they are filtered out.\n */\nfunction fetchPartitionedEntries(\n\tsource: BytesSource\n): ReadableWritablePair<FileEntry, CentralDirectoryEntry[]> {\n\t/**\n\t * This function implements a ReadableStream and a WritableStream\n\t * instead of a TransformStream. This is intentional.\n\t *\n\t * In TransformStream, the `transform` function may return a\n\t * promise. The next call to `transform` will be delayed until\n\t * the promise resolves. This is a problem for us because we\n\t * want to issue many fetch() requests in parallel.\n\t *\n\t * The only way to do that seems to be creating separate ReadableStream\n\t * and WritableStream implementations.\n\t */\n\tlet isWritableClosed = false;\n\tlet requestsInProgress = 0;\n\tlet readableController: ReadableStreamDefaultController<FileEntry>;\n\tconst byteStreams: Array<\n\t\t[CentralDirectoryEntry[], ReadableStream<Uint8Array>]\n\t> = [];\n\t/**\n\t * Receives chunks of CentralDirectoryEntries, and fetches\n\t * the corresponding byte ranges from the remote zip file.\n\t */\n\tconst writable = new WritableStream<CentralDirectoryEntry[]>({\n\t\twrite(zipEntries, controller) {\n\t\t\tif (!zipEntries.length) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t++requestsInProgress;\n\t\t\t// If the write() method returns a promise, the next\n\t\t\t// call will be delayed until the promise resolves.\n\t\t\t// Let's not return the promise, then.\n\t\t\t// This will effectively issue many requests in parallel.\n\t\t\trequestChunkRange(source, zipEntries)\n\t\t\t\t.then((byteStream) => {\n\t\t\t\t\tbyteStreams.push([zipEntries, byteStream]);\n\t\t\t\t})\n\t\t\t\t.catch((e) => {\n\t\t\t\t\tcontroller.error(e);\n\t\t\t\t})\n\t\t\t\t.finally(() => {\n\t\t\t\t\t--requestsInProgress;\n\t\t\t\t});\n\t\t},\n\t\tabort() {\n\t\t\tisWritableClosed = true;\n\t\t\treadableController.close();\n\t\t},\n\t\tasync close() {\n\t\t\tisWritableClosed = true;\n\t\t},\n\t});\n\t/**\n\t * Decodes zipped bytes into FileEntry objects.\n\t */\n\tconst readable = new ReadableStream<FileEntry>({\n\t\tstart(controller) {\n\t\t\treadableController = controller;\n\t\t},\n\t\tasync pull(controller) {\n\t\t\twhile (true) {\n\t\t\t\tconst allChunksProcessed =\n\t\t\t\t\tisWritableClosed &&\n\t\t\t\t\t!byteStreams.length &&\n\t\t\t\t\trequestsInProgress === 0;\n\t\t\t\tif (allChunksProcessed) {\n\t\t\t\t\tcontroller.close();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// There's no bytes available, but the writable\n\t\t\t\t// stream is still open or there are still requests\n\t\t\t\t// in progress. Let's wait for more bytes.\n\t\t\t\tconst waitingForMoreBytes = !byteStreams.length;\n\t\t\t\tif (waitingForMoreBytes) {\n\t\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, 50));\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst [requestedPaths, stream] = byteStreams[0];\n\t\t\t\tconst file = await readFileEntry(stream);\n\t\t\t\t// The stream is exhausted, let's remove it from the queue\n\t\t\t\t// and try the next one.\n\t\t\t\tconst streamExhausted = !file;\n\t\t\t\tif (streamExhausted) {\n\t\t\t\t\tbyteStreams.shift();\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// There may be some extra files between the ones we're\n\t\t\t\t// interested in. Let's filter out any files that got\n\t\t\t\t// intertwined in the byte stream.\n\t\t\t\tconst isOneOfRequestedPaths = requestedPaths.find(\n\t\t\t\t\t(entry) => entry.path === file.path\n\t\t\t\t);\n\t\t\t\tif (!isOneOfRequestedPaths) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Finally! We've got a file we're interested in.\n\t\t\t\tcontroller.enqueue(file);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t},\n\t});\n\n\treturn {\n\t\treadable,\n\t\twritable,\n\t};\n}\n\n/**\n * Requests a chunk of bytes from the bytes source.\n *\n * @param source\n * @param zipEntries\n */\nasync function requestChunkRange(\n\tsource: BytesSource,\n\tzipEntries: CentralDirectoryEntry[]\n) {\n\tconst release = await fetchSemaphore.acquire();\n\ttry {\n\t\tconst lastZipEntry = zipEntries[zipEntries.length - 1];\n\t\tconst substream = await source.streamBytes(\n\t\t\tzipEntries[0].firstByteAt,\n\t\t\tlastZipEntry.lastByteAt\n\t\t);\n\t\treturn substream;\n\t} finally {\n\t\trelease();\n\t}\n}\n\n/**\n * Fetches the Content-Length header from a remote URL.\n */\nasync function fetchContentLength(url: string) {\n\treturn await fetch(url, { method: 'HEAD' })\n\t\t.then((response) => response.headers.get('Content-Length'))\n\t\t.then((contentLength) => {\n\t\t\tif (!contentLength) {\n\t\t\t\tthrow new Error('Content-Length header is missing');\n\t\t\t}\n\n\t\t\tconst parsedLength = parseInt(contentLength, 10);\n\t\t\tif (isNaN(parsedLength) || parsedLength < 0) {\n\t\t\t\tthrow new Error('Content-Length header is invalid');\n\t\t\t}\n\t\t\treturn parsedLength;\n\t\t});\n}\n\n/**\n * Private and experimental API: Range-based data sources.\n *\n * The idea is that if we can read arbitrary byte ranges from\n * a file, we can retrieve a specific subset of a zip file.\n */\ntype BytesSource = {\n\tlength: number;\n\tstreamBytes: (\n\t\tstart: number,\n\t\tend: number\n\t) => Promise<ReadableStream<Uint8Array>>;\n};\n\n/**\n * Creates a BytesSource enabling fetching ranges of bytes\n * from a remote URL.\n */\nasync function createFetchSource(\n\turl: string,\n\tcontentLength?: number\n): Promise<BytesSource> {\n\tif (contentLength === undefined) {\n\t\tcontentLength = await fetchContentLength(url);\n\t}\n\n\treturn {\n\t\tlength: contentLength,\n\t\tstreamBytes: async (from: number, to: number) =>\n\t\t\tawait fetch(url, {\n\t\t\t\theaders: {\n\t\t\t\t\t// The Range header is inclusive, so we need to subtract 1\n\t\t\t\t\tRange: `bytes=${from}-${to - 1}`,\n\t\t\t\t\t'Accept-Encoding': 'none',\n\t\t\t\t},\n\t\t\t}).then((response) => response.body!),\n\t};\n}\n","import type {\n\tCentralDirectoryEndEntry,\n\tCentralDirectoryEntry,\n\tFileHeader,\n} from './types';\nimport { COMPRESSION_DEFLATE, COMPRESSION_NONE } from './types';\nimport {\n\tSIGNATURE_CENTRAL_DIRECTORY_END,\n\tSIGNATURE_CENTRAL_DIRECTORY,\n\tSIGNATURE_FILE,\n} from './types';\nimport { iteratorToStream } from '../utils/iterator-to-stream';\nimport { collectBytes } from '../utils/collect-bytes';\n\n/**\n * Compresses the given files into a ZIP archive.\n *\n * @param files - An async or sync iterable of files to be compressed.\n * @returns A readable stream of the compressed ZIP archive as Uint8Array chunks.\n */\nexport function encodeZip(\n\tfiles: AsyncIterable<File> | Iterable<File>\n): ReadableStream<Uint8Array> {\n\treturn iteratorToStream(files).pipeThrough(encodeZipTransform());\n}\n\n/**\n * Encodes the files into a ZIP format.\n *\n * @returns A stream transforming File objects into zipped bytes.\n */\nfunction encodeZipTransform() {\n\tconst offsetToFileHeaderMap: Map<number, FileHeader> = new Map();\n\tlet writtenBytes = 0;\n\treturn new TransformStream<File, Uint8Array>({\n\t\tasync transform(file, controller) {\n\t\t\tconst entryBytes = new Uint8Array(await file.arrayBuffer());\n\t\t\t/**\n\t\t\t * We want to write raw deflate-compressed bytes into our\n\t\t\t * final ZIP file. CompressionStream supports \"deflate-raw\"\n\t\t\t * compression, but not on Node.js v20, it's available since v21.2.0.\n\t\t\t *\n\t\t\t * As a workaround, we use the \"gzip\" compression and add\n\t\t\t * the header and footer bytes. It works, because \"gzip\"\n\t\t\t * compression is the same as \"deflate\" compression plus\n\t\t\t * the header and the footer.\n\t\t\t *\n\t\t\t * The header is 10 bytes long:\n\t\t\t * - 2 magic bytes: 0x1f, 0x8b\n\t\t\t * - 1 compression method: 0x08 (deflate)\n\t\t\t * - 1 header flags\n\t\t\t * - 4 mtime: 0x00000000 (no timestamp)\n\t\t\t * - 1 compression flags\n\t\t\t * - 1 OS: 0x03 (Unix)\n\t\t\t *\n\t\t\t * The footer is 8 bytes long:\n\t\t\t * - 4 bytes for CRC32 of the uncompressed data\n\t\t\t * - 4 bytes for ISIZE (uncompressed size modulo 2^32)\n\t\t\t */\n\t\t\tlet compressed = (await collectBytes(\n\t\t\t\tnew Blob([entryBytes])\n\t\t\t\t\t.stream()\n\t\t\t\t\t.pipeThrough(new CompressionStream('gzip'))\n\t\t\t))!;\n\t\t\t// Grab the CRC32 hash from the footer.\n\t\t\tconst crcHash = new DataView(compressed.buffer).getUint32(\n\t\t\t\tcompressed.byteLength - 8,\n\t\t\t\ttrue\n\t\t\t);\n\t\t\t// Strip the header and the footer.\n\t\t\tcompressed = compressed.slice(10, compressed.byteLength - 8);\n\n\t\t\tconst encodedPath = new TextEncoder().encode(file.name);\n\t\t\tconst zipFileEntry: FileHeader = {\n\t\t\t\tsignature: SIGNATURE_FILE,\n\t\t\t\tversion: 2,\n\t\t\t\tgeneralPurpose: 0,\n\t\t\t\tcompressionMethod:\n\t\t\t\t\tfile.type === 'directory' || compressed.byteLength === 0\n\t\t\t\t\t\t? COMPRESSION_NONE\n\t\t\t\t\t\t: COMPRESSION_DEFLATE,\n\t\t\t\tlastModifiedTime: 0,\n\t\t\t\tlastModifiedDate: 0,\n\t\t\t\tcrc: crcHash,\n\t\t\t\tcompressedSize: compressed.byteLength,\n\t\t\t\tuncompressedSize: entryBytes.byteLength,\n\t\t\t\tpath: encodedPath,\n\t\t\t\textra: new Uint8Array(0),\n\t\t\t};\n\t\t\toffsetToFileHeaderMap.set(writtenBytes, zipFileEntry);\n\n\t\t\tconst headerBytes = encodeFileEntryHeader(zipFileEntry);\n\t\t\tcontroller.enqueue(headerBytes);\n\t\t\twrittenBytes += headerBytes.byteLength;\n\n\t\t\tcontroller.enqueue(compressed);\n\t\t\twrittenBytes += compressed.byteLength;\n\t\t},\n\t\tflush(controller) {\n\t\t\tconst centralDirectoryOffset = writtenBytes;\n\t\t\tlet centralDirectorySize = 0;\n\t\t\tfor (const [\n\t\t\t\tfileOffset,\n\t\t\t\theader,\n\t\t\t] of offsetToFileHeaderMap.entries()) {\n\t\t\t\tconst centralDirectoryEntry: Partial<CentralDirectoryEntry> = {\n\t\t\t\t\t...header,\n\t\t\t\t\tsignature: SIGNATURE_CENTRAL_DIRECTORY,\n\t\t\t\t\tfileComment: new Uint8Array(0),\n\t\t\t\t\tdiskNumber: 1,\n\t\t\t\t\tinternalAttributes: 0,\n\t\t\t\t\texternalAttributes: 0,\n\t\t\t\t\tfirstByteAt: fileOffset,\n\t\t\t\t};\n\t\t\t\tconst centralDirectoryEntryBytes = encodeCentralDirectoryEntry(\n\t\t\t\t\tcentralDirectoryEntry as CentralDirectoryEntry,\n\t\t\t\t\tfileOffset\n\t\t\t\t);\n\t\t\t\tcontroller.enqueue(centralDirectoryEntryBytes);\n\t\t\t\tcentralDirectorySize += centralDirectoryEntryBytes.byteLength;\n\t\t\t}\n\t\t\tconst centralDirectoryEnd: CentralDirectoryEndEntry = {\n\t\t\t\tsignature: SIGNATURE_CENTRAL_DIRECTORY_END,\n\t\t\t\tnumberOfDisks: 1,\n\t\t\t\tcentralDirectoryOffset,\n\t\t\t\tcentralDirectorySize,\n\t\t\t\tcentralDirectoryStartDisk: 1,\n\t\t\t\tnumberCentralDirectoryRecordsOnThisDisk:\n\t\t\t\t\toffsetToFileHeaderMap.size,\n\t\t\t\tnumberCentralDirectoryRecords: offsetToFileHeaderMap.size,\n\t\t\t\tcomment: new Uint8Array(0),\n\t\t\t};\n\t\t\tconst centralDirectoryEndBytes =\n\t\t\t\tencodeCentralDirectoryEnd(centralDirectoryEnd);\n\t\t\tcontroller.enqueue(centralDirectoryEndBytes);\n\t\t\toffsetToFileHeaderMap.clear();\n\t\t},\n\t});\n}\n\n/**\n * Encodes a file entry header as a Uint8Array.\n *\n * The array is structured as follows:\n *\n * ```\n * Offset\tBytes\tDescription\n * 0\t\t4\tLocal file header signature = 0x04034b50 (PK♥♦ or \"PK\\3\\4\")\n * 4\t\t2\tVersion needed to extract (minimum)\n * 6\t\t2\tGeneral purpose bit flag\n * 8\t\t2\tCompression method; e.g. none = 0, DEFLATE = 8 (or \"\\0x08\\0x00\")\n * 10\t\t2\tFile last modification time\n * 12\t\t2\tFile last modification date\n * 14\t\t4\tCRC-32 of uncompressed data\n * 18\t\t4\tCompressed size (or 0xffffffff for ZIP64)\n * 22\t\t4\tUncompressed size (or 0xffffffff for ZIP64)\n * 26\t\t2\tFile name length (n)\n * 28\t\t2\tExtra field length (m)\n * 30\t\tn\tFile name\n * 30+n\tm\tExtra field\n * ```\n */\nfunction encodeFileEntryHeader(entry: FileHeader) {\n\tconst buffer = new ArrayBuffer(\n\t\t30 + entry.path.byteLength + entry.extra.byteLength\n\t);\n\tconst view = new DataView(buffer);\n\tview.setUint32(0, entry.signature, true);\n\tview.setUint16(4, entry.version, true);\n\tview.setUint16(6, entry.generalPurpose, true);\n\tview.setUint16(8, entry.compressionMethod, true);\n\tview.setUint16(10, entry.lastModifiedDate, true);\n\tview.setUint16(12, entry.lastModifiedTime, true);\n\tview.setUint32(14, entry.crc, true);\n\tview.setUint32(18, entry.compressedSize, true);\n\tview.setUint32(22, entry.uncompressedSize, true);\n\tview.setUint16(26, entry.path.byteLength, true);\n\tview.setUint16(28, entry.extra.byteLength, true);\n\tconst uint8Header = new Uint8Array(buffer);\n\tuint8Header.set(entry.path, 30);\n\tuint8Header.set(entry.extra, 30 + entry.path.byteLength);\n\treturn uint8Header;\n}\n\n/**\n * Encodes a central directory entry as a Uint8Array.\n *\n * The central directory entry is structured as follows:\n *\n * ```\n * Offset Bytes Description\n * 0\t\t4\tCentral directory file header signature = 0x02014b50\n * 4\t\t2\tVersion made by\n * 6\t\t2\tVersion needed to extract (minimum)\n * 8\t\t2\tGeneral purpose bit flag\n * 10\t\t2\tCompression method\n * 12\t\t2\tFile last modification time\n * 14\t\t2\tFile last modification date\n * 16\t\t4\tCRC-32 of uncompressed data\n * 20\t\t4\tCompressed size (or 0xffffffff for ZIP64)\n * 24\t\t4\tUncompressed size (or 0xffffffff for ZIP64)\n * 28\t\t2\tFile name length (n)\n * 30\t\t2\tExtra field length (m)\n * 32\t\t2\tFile comment length (k)\n * 34\t\t2\tDisk number where file starts (or 0xffff for ZIP64)\n * 36\t\t2\tInternal file attributes\n * 38\t\t4\tExternal file attributes\n * 42\t\t4\tRelative offset of local file header (or 0xffffffff for ZIP64). This is the number of bytes between the start of the first disk on which the file occurs, and the start of the local file header. This allows software reading the central directory to locate the position of the file inside the ZIP file.\n * 46\t\tn\tFile name\n * 46+n\tm\tExtra field\n * 46+n+m\tk\tFile comment\n * ```\n */\nfunction encodeCentralDirectoryEntry(\n\tentry: CentralDirectoryEntry,\n\tfileEntryOffset: number\n) {\n\tconst buffer = new ArrayBuffer(\n\t\t46 + entry.path.byteLength + entry.extra.byteLength\n\t);\n\tconst view = new DataView(buffer);\n\tview.setUint32(0, entry.signature, true);\n\tview.setUint16(4, entry.versionCreated, true);\n\tview.setUint16(6, entry.versionNeeded, true);\n\tview.setUint16(8, entry.generalPurpose, true);\n\tview.setUint16(10, entry.compressionMethod, true);\n\tview.setUint16(12, entry.lastModifiedDate, true);\n\tview.setUint16(14, entry.lastModifiedTime, true);\n\tview.setUint32(16, entry.crc, true);\n\tview.setUint32(20, entry.compressedSize, true);\n\tview.setUint32(24, entry.uncompressedSize, true);\n\tview.setUint16(28, entry.path.byteLength, true);\n\tview.setUint16(30, entry.extra.byteLength, true);\n\tview.setUint16(32, entry.fileComment.byteLength, true);\n\tview.setUint16(34, entry.diskNumber, true);\n\tview.setUint16(36, entry.internalAttributes, true);\n\tview.setUint32(38, entry.externalAttributes, true);\n\tview.setUint32(42, fileEntryOffset, true);\n\tconst uint8Header = new Uint8Array(buffer);\n\tuint8Header.set(entry.path, 46);\n\tuint8Header.set(entry.extra, 46 + entry.path.byteLength);\n\treturn uint8Header;\n}\n\n/**\n * Encodes the end of central directory entry as a Uint8Array.\n *\n * The end of central directory entry is structured as follows:\n *\n * ```\n * Offset\tBytes\tDescription[33]\n * 0\t\t 4\t\tEnd of central directory signature = 0x06054b50\n * 4\t\t 2\t\tNumber of this disk (or 0xffff for ZIP64)\n * 6\t\t 2\t\tDisk where central directory starts (or 0xffff for ZIP64)\n * 8\t\t 2\t\tNumber of central directory records on this disk (or 0xffff for ZIP64)\n * 10\t\t 2\t\tTotal number of central directory records (or 0xffff for ZIP64)\n * 12\t\t 4\t\tSize of central directory (bytes) (or 0xffffffff for ZIP64)\n * 16\t\t 4\t\tOffset of start of central directory, relative to start of archive (or 0xffffffff for ZIP64)\n * 20\t\t 2\t\tComment length (n)\n * 22\t\t n\t\tComment\n * ```\n */\nfunction encodeCentralDirectoryEnd(entry: CentralDirectoryEndEntry) {\n\tconst buffer = new ArrayBuffer(22 + entry.comment.byteLength);\n\tconst view = new DataView(buffer);\n\tview.setUint32(0, entry.signature, true);\n\tview.setUint16(4, entry.numberOfDisks, true);\n\tview.setUint16(6, entry.centralDirectoryStartDisk, true);\n\tview.setUint16(8, entry.numberCentralDirectoryRecordsOnThisDisk, true);\n\tview.setUint16(10, entry.numberCentralDirectoryRecords, true);\n\tview.setUint32(12, entry.centralDirectorySize, true);\n\tview.setUint32(16, entry.centralDirectoryOffset, true);\n\tview.setUint16(20, entry.comment.byteLength, true);\n\tconst uint8Header = new Uint8Array(buffer);\n\tuint8Header.set(entry.comment, 22);\n\treturn uint8Header;\n}\n"],"names":["concatUint8Array","arrays","result","sum","array","offset","concatBytes","totalBytes","acc","chunk","controller","buffer","limitBytes","stream","bytes","reader","value","done","collectBytes","collectFile","fileName","iteratorToStream","iteratorOrIterable","iterator","StreamedFile","readableStream","name","options","FILE_HEADER_SIZE","SIGNATURE_FILE","SIGNATURE_CENTRAL_DIRECTORY","SIGNATURE_CENTRAL_DIRECTORY_END","COMPRESSION_NONE","COMPRESSION_DEFLATE","filterStream","predicate","prependBytes","isPrepended","appendBytes","decodeZip","streamZippedFileEntries","zipEntry","file","DEFAULT_PREDICATE","entry","nextZipEntry","signature","readFileEntry","readCentralDirectoryEntry","readEndCentralDirectoryEntry","skipSignature","data","pathLength","extraLength","endsWithSlash","bodyStream","header","footer","footerView","fileCommentLength","centralDirectory","path","endOfDirectory","commentLength","CENTRAL_DIRECTORY_END_SCAN_CHUNK_SIZE","BATCH_DOWNLOAD_OF_FILES_IF_CLOSER_THAN","PREFER_RANGES_IF_FILE_LARGER_THAN","fetchSemaphore","Semaphore","decodeRemoteZip","url","response","contentLength","fetchContentLength","peekStream","responseStream","peekReader","peekBytes","peekDone","source","createFetchSource","streamCentralDirectoryEntries","partitionNearbyEntries","fetchPartitionedEntries","centralDirectoryStream","streamCentralDirectoryBytes","chunkSize","chunkStart","chunkEnd","view","i","centralDirectoryOffsetAt","dirStart","missingBytes","lastFileEndsAt","currentChunk","isWritableClosed","requestsInProgress","readableController","byteStreams","writable","zipEntries","requestChunkRange","byteStream","e","resolve","requestedPaths","release","lastZipEntry","parsedLength","from","to","encodeZip","files","encodeZipTransform","offsetToFileHeaderMap","writtenBytes","entryBytes","compressed","crcHash","encodedPath","zipFileEntry","headerBytes","encodeFileEntryHeader","centralDirectoryOffset","centralDirectorySize","fileOffset","centralDirectoryEntry","centralDirectoryEntryBytes","encodeCentralDirectoryEntry","centralDirectoryEnd","centralDirectoryEndBytes","encodeCentralDirectoryEnd","uint8Header","fileEntryOffset"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../../../packages/php-wasm/stream-compression/src/utils/concat-uint8-array.ts","../../../../packages/php-wasm/stream-compression/src/utils/concat-bytes.ts","../../../../packages/php-wasm/stream-compression/src/utils/limit-bytes.ts","../../../../packages/php-wasm/stream-compression/src/utils/collect-bytes.ts","../../../../packages/php-wasm/stream-compression/src/utils/collect-file.ts","../../../../packages/php-wasm/stream-compression/src/utils/iterator-to-stream.ts","../../../../packages/php-wasm/stream-compression/src/utils/streamed-file.ts","../../../../packages/php-wasm/stream-compression/src/utils/iterable-stream-polyfill.ts","../../../../packages/php-wasm/stream-compression/src/zip/types.ts","../../../../packages/php-wasm/stream-compression/src/utils/filter-stream.ts","../../../../packages/php-wasm/stream-compression/src/utils/prepend-bytes.ts","../../../../packages/php-wasm/stream-compression/src/utils/append-bytes.ts","../../../../packages/php-wasm/stream-compression/src/zip/decode-zip.ts","../../../../packages/php-wasm/stream-compression/src/zip/decode-remote-zip.ts","../../../../packages/php-wasm/stream-compression/src/zip/encode-zip.ts"],"sourcesContent":["/**\n * Concatenates multiple Uint8Arrays into a single Uint8Array.\n *\n * @param arrays The arrays to concatenate.\n * @returns A new Uint8Array containing the contents of all the arrays.\n */\nexport function concatUint8Array(...arrays: Uint8Array[]) {\n\tconst result = new Uint8Array(\n\t\tarrays.reduce((sum, array) => sum + array.length, 0)\n\t);\n\tlet offset = 0;\n\tfor (const array of arrays) {\n\t\tresult.set(array, offset);\n\t\toffset += array.length;\n\t}\n\treturn result;\n}\n","import { concatUint8Array } from './concat-uint8-array';\n\n/**\n * Concatenates the contents of the stream into a single Uint8Array.\n *\n * @param totalBytes Optional. The number of bytes to concatenate. Used to\n * \t\t\t\t pre-allocate the buffer. If not provided, the buffer will\n * \t\t\t\t be dynamically resized as needed.\n * @returns A stream that will emit a single UInt8Array entry before closing.\n */\nexport function concatBytes(totalBytes?: number) {\n\tif (totalBytes === undefined) {\n\t\tlet acc = new Uint8Array();\n\t\treturn new TransformStream<Uint8Array, Uint8Array>({\n\t\t\ttransform(chunk) {\n\t\t\t\tacc = concatUint8Array(acc, chunk);\n\t\t\t},\n\n\t\t\tflush(controller) {\n\t\t\t\tcontroller.enqueue(acc);\n\t\t\t},\n\t\t});\n\t} else {\n\t\tconst buffer = new ArrayBuffer(totalBytes || 0);\n\t\tlet offset = 0;\n\t\treturn new TransformStream<Uint8Array, Uint8Array>({\n\t\t\ttransform(chunk) {\n\t\t\t\tconst view = new Uint8Array(buffer);\n\t\t\t\tview.set(chunk, offset);\n\t\t\t\toffset += chunk.byteLength;\n\t\t\t},\n\n\t\t\tflush(controller) {\n\t\t\t\tcontroller.enqueue(new Uint8Array(buffer));\n\t\t\t},\n\t\t});\n\t}\n}\n","/**\n * Limit the number of bytes read from a stream.\n *\n * @param stream The stream to limit.\n * @param bytes The number of bytes to read from the stream.\n * @returns A new stream that will read at most `bytes` bytes from `stream`.\n */\nexport function limitBytes(stream: ReadableStream<Uint8Array>, bytes: number) {\n\tif (bytes === 0) {\n\t\treturn new ReadableStream({\n\t\t\tstart(controller) {\n\t\t\t\tcontroller.close();\n\t\t\t},\n\t\t});\n\t}\n\tconst reader = stream.getReader({ mode: 'byob' });\n\tlet offset = 0;\n\treturn new ReadableStream({\n\t\tasync pull(controller) {\n\t\t\tconst { value, done } = await reader.read(\n\t\t\t\tnew Uint8Array(bytes - offset)\n\t\t\t);\n\t\t\tif (done) {\n\t\t\t\treader.releaseLock();\n\t\t\t\tcontroller.close();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\toffset += value.length;\n\t\t\tcontroller.enqueue(value);\n\n\t\t\tif (offset >= bytes) {\n\t\t\t\treader.releaseLock();\n\t\t\t\tcontroller.close();\n\t\t\t}\n\t\t},\n\t\tcancel() {\n\t\t\treader.cancel();\n\t\t},\n\t});\n}\n","import { concatBytes } from './concat-bytes';\nimport { limitBytes } from './limit-bytes';\n\n/**\n * Collects the contents of the entire stream into a single Uint8Array.\n *\n * @param stream The stream to collect.\n * @param bytes Optional. The number of bytes to read from the stream.\n * @returns The string contents of the stream.\n */\nexport async function collectBytes(\n\tstream: ReadableStream<Uint8Array>,\n\tbytes?: number\n) {\n\tif (bytes !== undefined) {\n\t\tstream = limitBytes(stream, bytes);\n\t}\n\n\treturn await stream\n\t\t.pipeThrough(concatBytes(bytes))\n\t\t.getReader()\n\t\t.read()\n\t\t.then(({ value }) => value!);\n}\n","import { collectBytes } from './collect-bytes';\n\n/**\n * Collects the contents of the entire stream into a single File object.\n *\n * @param stream The stream to collect.\n * @param fileName The name of the file\n * @returns The string contents of the stream.\n */\nexport async function collectFile(\n\tfileName: string,\n\tstream: ReadableStream<Uint8Array>\n) {\n\t// @TODO: use StreamingFile\n\treturn new File([await collectBytes(stream)], fileName);\n}\n","import type { IterableReadableStream } from './iterable-stream-polyfill';\n\n/**\n * Converts an iterator or iterable to a stream.\n *\n * @param iteratorOrIterable The iterator or iterable to convert.\n * @returns A stream that will yield the values from the iterator or iterable.\n */\nexport function iteratorToStream<T>(\n\titeratorOrIterable:\n\t\t| AsyncIterator<T>\n\t\t| Iterator<T>\n\t\t| AsyncIterable<T>\n\t\t| Iterable<T>\n) {\n\tif (iteratorOrIterable instanceof ReadableStream) {\n\t\treturn iteratorOrIterable as IterableReadableStream<T>;\n\t}\n\n\tlet iterator: AsyncIterator<T> | Iterator<T>;\n\tif (Symbol.asyncIterator in iteratorOrIterable) {\n\t\titerator = iteratorOrIterable[Symbol.asyncIterator]();\n\t} else if (Symbol.iterator in iteratorOrIterable) {\n\t\titerator = iteratorOrIterable[Symbol.iterator]();\n\t} else {\n\t\titerator = iteratorOrIterable;\n\t}\n\n\treturn new ReadableStream<T>({\n\t\tasync pull(controller) {\n\t\t\tconst { done, value } = await iterator.next();\n\t\t\tif (done) {\n\t\t\t\tcontroller.close();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcontroller.enqueue(value);\n\t\t},\n\t}) as IterableReadableStream<T>;\n}\n","import { collectBytes } from './collect-bytes';\n\n/**\n * Represents a file that is streamed and not fully\n * loaded into memory.\n */\nexport class StreamedFile extends File {\n\treadonly filesize: number | undefined;\n\n\tprivate readableStream: ReadableStream<Uint8Array>;\n\n\t/**\n\t * Creates a new StreamedFile instance.\n\t *\n\t * @param readableStream The readable stream containing the file data.\n\t * @param name The name of the file.\n\t * @param options An object containing options such as the MIME type and file size.\n\t */\n\tconstructor(\n\t\treadableStream: ReadableStream<Uint8Array>,\n\t\tname: string,\n\t\toptions?: { type?: string; filesize?: number }\n\t) {\n\t\tsuper([], name, { type: options?.type });\n\t\tthis.readableStream = readableStream;\n\t\tthis.filesize = options?.filesize;\n\t}\n\n\t/**\n\t * Overrides the slice() method of the File class.\n\t *\n\t * @returns A Blob representing a portion of the file.\n\t */\n\toverride slice(): Blob {\n\t\tthrow new Error('slice() is not possible on a StreamedFile');\n\t}\n\n\t/**\n\t * Returns the readable stream associated with the file.\n\t *\n\t * @returns The readable stream.\n\t */\n\toverride stream() {\n\t\treturn this.readableStream;\n\t}\n\n\t/**\n\t * Loads the file data into memory and then returns it as a string.\n\t *\n\t * @returns File data as text.\n\t */\n\toverride async text() {\n\t\treturn new TextDecoder().decode(await this.arrayBuffer());\n\t}\n\n\t/**\n\t * Loads the file data into memory and then returns it as an ArrayBuffer.\n\t *\n\t * @returns File data as an ArrayBuffer.\n\t */\n\toverride async arrayBuffer() {\n\t\treturn await collectBytes(this.stream());\n\t}\n}\n","/**\n * Polyfill for ReadableStream[Symbol.asyncIterator]\n * This enables the use of for-await-of loops with ReadableStreams\n *\n * @example\n * ```ts\n * for await (const entry of stream) {\n * \t // ...\n * }\n * ```\n */\n// @ts-ignore\nif (!ReadableStream.prototype[Symbol.asyncIterator]) {\n\t// @ts-ignore\n\tReadableStream.prototype[Symbol.asyncIterator] = async function* () {\n\t\tconst reader = this.getReader();\n\t\ttry {\n\t\t\twhile (true) {\n\t\t\t\tconst { done, value } = await reader.read();\n\t\t\t\tif (done) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tyield value;\n\t\t\t}\n\t\t} finally {\n\t\t\treader.releaseLock();\n\t\t}\n\t};\n\t// @ts-ignore\n\tReadableStream.prototype.iterate =\n\t\t// @ts-ignore\n\t\tReadableStream.prototype[Symbol.asyncIterator];\n}\n\nexport type IterableReadableStream<R> = ReadableStream<R> & AsyncIterable<R>;\n","export const FILE_HEADER_SIZE = 32;\nexport const SIGNATURE_FILE = 67324752 as const;\nexport const SIGNATURE_CENTRAL_DIRECTORY = 33639248 as const;\nexport const SIGNATURE_CENTRAL_DIRECTORY_END = 101010256 as const;\nexport const SIGNATURE_DATA_DESCRIPTOR = 134695760 as const;\n\nexport const COMPRESSION_NONE = 0 as const;\nexport const COMPRESSION_DEFLATE = 8 as const;\nexport type CompressionMethod =\n\t| typeof COMPRESSION_NONE\n\t| typeof COMPRESSION_DEFLATE;\n\nexport type ZipEntry =\n\t| FileEntry\n\t| CentralDirectoryEntry\n\t| CentralDirectoryEndEntry;\n\n/**\n * Data of the file entry header encoded in a \".zip\" file.\n */\nexport interface FileHeader {\n\tsignature: typeof SIGNATURE_FILE;\n\tversion: number;\n\tgeneralPurpose: number;\n\tcompressionMethod: CompressionMethod;\n\tlastModifiedTime: number;\n\tlastModifiedDate: number;\n\tcrc: number;\n\tcompressedSize: number;\n\tuncompressedSize: number;\n\tpath: Uint8Array;\n\textra: Uint8Array;\n}\nexport interface FileEntry extends FileHeader {\n\tisDirectory: boolean;\n\tbytes: Uint8Array;\n}\n\n/**\n * Data of the central directory entry encoded in a \".zip\" file.\n */\nexport interface CentralDirectoryEntry {\n\tsignature: typeof SIGNATURE_CENTRAL_DIRECTORY;\n\tversionCreated: number;\n\tversionNeeded: number;\n\tgeneralPurpose: number;\n\tcompressionMethod: CompressionMethod;\n\tlastModifiedTime: number;\n\tlastModifiedDate: number;\n\tcrc: number;\n\tcompressedSize: number;\n\tuncompressedSize: number;\n\tdiskNumber: number;\n\tinternalAttributes: number;\n\texternalAttributes: number;\n\tfirstByteAt: number;\n\tlastByteAt: number;\n\tpath: Uint8Array;\n\textra: Uint8Array;\n\tfileComment: Uint8Array;\n\tisDirectory: boolean;\n}\n\n/**\n * Data of the central directory end entry encoded in a \".zip\" file.\n */\nexport interface CentralDirectoryEndEntry {\n\tsignature: typeof SIGNATURE_CENTRAL_DIRECTORY_END;\n\tnumberOfDisks: number;\n\tcentralDirectoryStartDisk: number;\n\tnumberCentralDirectoryRecordsOnThisDisk: number;\n\tnumberCentralDirectoryRecords: number;\n\tcentralDirectorySize: number;\n\tcentralDirectoryOffset: number;\n\tcomment: Uint8Array;\n}\n","/**\n * Filter the stream based on a predicate.\n *\n * @param predicate The predicate to filter the stream with.\n * @returns A new stream that will only contain chunks that pass the predicate.\n */\nexport function filterStream<T>(predicate: (chunk: T) => boolean) {\n\treturn new TransformStream<T, T>({\n\t\ttransform(chunk, controller) {\n\t\t\tif (predicate(chunk)) {\n\t\t\t\tcontroller.enqueue(chunk);\n\t\t\t}\n\t\t},\n\t});\n}\n","/**\n * Prepend bytes to a stream.\n *\n * @param bytes The bytes to prepend.\n * @returns A transform stream that will prepend the specified bytes.\n */\nexport function prependBytes(bytes: Uint8Array) {\n\tlet isPrepended = false;\n\treturn new TransformStream<Uint8Array, Uint8Array>({\n\t\tasync transform(chunk, controller) {\n\t\t\tif (!isPrepended) {\n\t\t\t\tisPrepended = true;\n\t\t\t\tcontroller.enqueue(bytes);\n\t\t\t}\n\t\t\tcontroller.enqueue(chunk);\n\t\t},\n\t});\n}\n","/**\n * Appends bytes to a stream.\n *\n * @param bytes The bytes to append.\n * @returns A transform stream that will append the specified bytes.\n */\nexport function appendBytes(bytes: Uint8Array) {\n\treturn new TransformStream<Uint8Array, Uint8Array>({\n\t\tasync transform(chunk, controller) {\n\t\t\tcontroller.enqueue(chunk);\n\t\t},\n\t\tasync flush(controller) {\n\t\t\tcontroller.enqueue(bytes);\n\t\t},\n\t});\n}\n","/**\n * Reads files from a stream of zip file bytes.\n */\nimport type { IterableReadableStream } from '../utils/iterable-stream-polyfill';\n\nimport type { CompressionMethod } from './types';\nimport {\n\tSIGNATURE_FILE,\n\tSIGNATURE_CENTRAL_DIRECTORY,\n\tSIGNATURE_CENTRAL_DIRECTORY_END,\n\tFILE_HEADER_SIZE,\n\tCOMPRESSION_DEFLATE,\n} from './types';\nimport type {\n\tCentralDirectoryEntry,\n\tFileEntry,\n\tZipEntry,\n\tCentralDirectoryEndEntry,\n} from './types';\nimport { filterStream } from '../utils/filter-stream';\nimport { collectBytes } from '../utils/collect-bytes';\nimport { limitBytes } from '../utils/limit-bytes';\nimport { concatBytes } from '../utils/concat-bytes';\nimport { prependBytes } from '../utils/prepend-bytes';\nimport { appendBytes } from '../utils/append-bytes';\n\n/**\n * Unzips a stream of zip file bytes.\n *\n * @param stream A stream of zip file bytes.\n * @param predicate Optional. A function that returns true if the file should be downloaded.\n * @returns An iterable stream of File objects.\n */\nexport function decodeZip(\n\tstream: ReadableStream<Uint8Array>,\n\tpredicate?: () => boolean\n) {\n\treturn streamZippedFileEntries(stream, predicate).pipeThrough(\n\t\tnew TransformStream<FileEntry, File>({\n\t\t\tasync transform(zipEntry, controller) {\n\t\t\t\tconst file = new File(\n\t\t\t\t\t[zipEntry.bytes],\n\t\t\t\t\tnew TextDecoder().decode(zipEntry.path),\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: zipEntry.isDirectory ? 'directory' : undefined,\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t\tcontroller.enqueue(file);\n\t\t\t},\n\t\t})\n\t) as IterableReadableStream<File>;\n}\n\nconst DEFAULT_PREDICATE = () => true;\n\n/**\n * Parses a stream of zipped bytes into FileEntry informations.\n *\n * @param stream A stream of zip file bytes.\n * @param predicate Optional. A function that returns true if the file should be downloaded.\n * @returns An iterable stream of FileEntry objects.\n */\nexport function streamZippedFileEntries(\n\tstream: ReadableStream<Uint8Array>,\n\tpredicate: (\n\t\tdirEntry: CentralDirectoryEntry | FileEntry\n\t) => boolean = DEFAULT_PREDICATE\n) {\n\tconst entriesStream = new ReadableStream<ZipEntry>({\n\t\tasync pull(controller) {\n\t\t\tconst entry = await nextZipEntry(stream);\n\t\t\tif (!entry) {\n\t\t\t\tcontroller.close();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcontroller.enqueue(entry);\n\t\t},\n\t}) as IterableReadableStream<ZipEntry>;\n\n\treturn entriesStream\n\t\t.pipeThrough(\n\t\t\tfilterStream(({ signature }) => signature === SIGNATURE_FILE)\n\t\t)\n\t\t.pipeThrough(\n\t\t\tfilterStream(predicate as any)\n\t\t) as IterableReadableStream<FileEntry>;\n}\n\n/**\n * Reads the next zip entry from a stream of zip file bytes.\n *\n * @param stream A stream of zip file bytes.\n * @returns A FileEntry object.\n */\nasync function nextZipEntry(stream: ReadableStream<Uint8Array>) {\n\tconst sigData = new DataView((await collectBytes(stream, 4))!.buffer);\n\tconst signature = sigData.getUint32(0, true);\n\tif (signature === SIGNATURE_FILE) {\n\t\treturn await readFileEntry(stream, true);\n\t} else if (signature === SIGNATURE_CENTRAL_DIRECTORY) {\n\t\treturn await readCentralDirectoryEntry(stream, true);\n\t} else if (signature === SIGNATURE_CENTRAL_DIRECTORY_END) {\n\t\treturn await readEndCentralDirectoryEntry(stream, true);\n\t}\n\treturn null;\n}\n\n/**\n * Reads a file entry from a zip file.\n *\n * The file entry is structured as follows:\n *\n * ```\n * Offset\tBytes\tDescription\n * 0\t\t4\tLocal file header signature = 0x04034b50 (PK♥♦ or \"PK\\3\\4\")\n * 4\t\t2\tVersion needed to extract (minimum)\n * 6\t\t2\tGeneral purpose bit flag\n * 8\t\t2\tCompression method; e.g. none = 0, DEFLATE = 8 (or \"\\0x08\\0x00\")\n * 10\t\t2\tFile last modification time\n * 12\t\t2\tFile last modification date\n * 14\t\t4\tCRC-32 of uncompressed data\n * 18\t\t4\tCompressed size (or 0xffffffff for ZIP64)\n * 22\t\t4\tUncompressed size (or 0xffffffff for ZIP64)\n * 26\t\t2\tFile name length (n)\n * 28\t\t2\tExtra field length (m)\n * 30\t\tn\tFile name\n * 30+n\tm\tExtra field\n * ```\n *\n * @param stream\n * @param skipSignature Do not consume the signature from the stream.\n * @returns\n */\nexport async function readFileEntry(\n\tstream: ReadableStream<Uint8Array>,\n\tskipSignature = false\n): Promise<FileEntry | null> {\n\tif (!skipSignature) {\n\t\tconst sigData = new DataView((await collectBytes(stream, 4))!.buffer);\n\t\tconst signature = sigData.getUint32(0, true);\n\t\tif (signature !== SIGNATURE_FILE) {\n\t\t\treturn null;\n\t\t}\n\t}\n\tconst data = new DataView((await collectBytes(stream, 26))!.buffer);\n\tconst pathLength = data.getUint16(22, true);\n\tconst extraLength = data.getUint16(24, true);\n\tconst entry: Partial<FileEntry> = {\n\t\tsignature: SIGNATURE_FILE,\n\t\tversion: data.getUint32(0, true),\n\t\tgeneralPurpose: data.getUint16(2, true),\n\t\tcompressionMethod: data.getUint16(4, true) as CompressionMethod,\n\t\tlastModifiedTime: data.getUint16(6, true),\n\t\tlastModifiedDate: data.getUint16(8, true),\n\t\tcrc: data.getUint32(10, true),\n\t\tcompressedSize: data.getUint32(14, true),\n\t\tuncompressedSize: data.getUint32(18, true),\n\t};\n\n\tentry['path'] = await collectBytes(stream, pathLength);\n\tentry['isDirectory'] = endsWithSlash(entry.path!);\n\tentry['extra'] = await collectBytes(stream, extraLength);\n\n\t// Make sure we consume the body stream or else\n\t// we'll start reading the next file at the wrong\n\t// offset.\n\t// @TODO: Expose the body stream instead of reading it all\n\t// eagerly. Ensure the next iteration exhausts\n\t// the last body stream before moving on.\n\n\tlet bodyStream = limitBytes(stream, entry['compressedSize']!);\n\n\tif (entry['compressionMethod'] === COMPRESSION_DEFLATE) {\n\t\t/**\n\t\t * We want to write raw deflate-compressed bytes into our\n\t\t * final ZIP file. CompressionStream supports \"deflate-raw\"\n\t\t * compression, but not on Node.js v20, it's available since v21.2.0.\n\t\t *\n\t\t * As a workaround, we use the \"gzip\" compression and add\n\t\t * the header and footer bytes. It works, because \"gzip\"\n\t\t * compression is the same as \"deflate\" compression plus\n\t\t * the header and the footer.\n\t\t *\n\t\t * The header is 10 bytes long:\n\t\t * - 2 magic bytes: 0x1f, 0x8b\n\t\t * - 1 compression method: 0x08 (deflate)\n\t\t * - 1 header flags\n\t\t * - 4 mtime: 0x00000000 (no timestamp)\n\t\t * - 1 compression flags\n\t\t * - 1 OS: 0x03 (Unix)\n\t\t *\n\t\t * The footer is 8 bytes long:\n\t\t * - 4 bytes for CRC32 of the uncompressed data\n\t\t * - 4 bytes for ISIZE (uncompressed size modulo 2^32)\n\t\t */\n\t\tconst header = new Uint8Array(10);\n\t\theader.set([0x1f, 0x8b, 0x08]);\n\n\t\tconst footer = new Uint8Array(8);\n\t\tconst footerView = new DataView(footer.buffer);\n\t\tfooterView.setUint32(0, entry.crc!, true);\n\t\tfooterView.setUint32(4, entry.uncompressedSize! % 2 ** 32, true);\n\t\tbodyStream = bodyStream\n\t\t\t.pipeThrough(prependBytes(header))\n\t\t\t.pipeThrough(appendBytes(footer))\n\t\t\t.pipeThrough(new DecompressionStream('gzip'));\n\t}\n\tentry['bytes'] = await bodyStream\n\t\t.pipeThrough(concatBytes(entry['uncompressedSize']))\n\t\t.getReader()\n\t\t.read()\n\t\t.then(({ value }) => value!);\n\treturn entry as FileEntry;\n}\n\n/**\n * Reads a central directory entry from a zip file.\n *\n * The central directory entry is structured as follows:\n *\n * ```\n * Offset Bytes Description\n * 0\t\t4\tCentral directory file header signature = 0x02014b50\n * 4\t\t2\tVersion made by\n * 6\t\t2\tVersion needed to extract (minimum)\n * 8\t\t2\tGeneral purpose bit flag\n * 10\t\t2\tCompression method\n * 12\t\t2\tFile last modification time\n * 14\t\t2\tFile last modification date\n * 16\t\t4\tCRC-32 of uncompressed data\n * 20\t\t4\tCompressed size (or 0xffffffff for ZIP64)\n * 24\t\t4\tUncompressed size (or 0xffffffff for ZIP64)\n * 28\t\t2\tFile name length (n)\n * 30\t\t2\tExtra field length (m)\n * 32\t\t2\tFile comment length (k)\n * 34\t\t2\tDisk number where file starts (or 0xffff for ZIP64)\n * 36\t\t2\tInternal file attributes\n * 38\t\t4\tExternal file attributes\n * 42\t\t4\tRelative offset of local file header (or 0xffffffff for ZIP64). This is the number of bytes between the start of the first disk on which the file occurs, and the start of the local file header. This allows software reading the central directory to locate the position of the file inside the ZIP file.\n * 46\t\tn\tFile name\n * 46+n\tm\tExtra field\n * 46+n+m\tk\tFile comment\n * ```\n *\n * @param stream\n * @param skipSignature\n * @returns\n */\nexport async function readCentralDirectoryEntry(\n\tstream: ReadableStream<Uint8Array>,\n\tskipSignature = false\n): Promise<CentralDirectoryEntry | null> {\n\tif (!skipSignature) {\n\t\tconst sigData = new DataView((await collectBytes(stream, 4))!.buffer);\n\t\tconst signature = sigData.getUint32(0, true);\n\t\tif (signature !== SIGNATURE_CENTRAL_DIRECTORY) {\n\t\t\treturn null;\n\t\t}\n\t}\n\tconst data = new DataView((await collectBytes(stream, 42))!.buffer);\n\tconst pathLength = data.getUint16(24, true);\n\tconst extraLength = data.getUint16(26, true);\n\tconst fileCommentLength = data.getUint16(28, true);\n\tconst centralDirectory: Partial<CentralDirectoryEntry> = {\n\t\tsignature: SIGNATURE_CENTRAL_DIRECTORY,\n\t\tversionCreated: data.getUint16(0, true),\n\t\tversionNeeded: data.getUint16(2, true),\n\t\tgeneralPurpose: data.getUint16(4, true),\n\t\tcompressionMethod: data.getUint16(6, true) as CompressionMethod,\n\t\tlastModifiedTime: data.getUint16(8, true),\n\t\tlastModifiedDate: data.getUint16(10, true),\n\t\tcrc: data.getUint32(12, true),\n\t\tcompressedSize: data.getUint32(16, true),\n\t\tuncompressedSize: data.getUint32(20, true),\n\t\tdiskNumber: data.getUint16(30, true),\n\t\tinternalAttributes: data.getUint16(32, true),\n\t\texternalAttributes: data.getUint32(34, true),\n\t\tfirstByteAt: data.getUint32(38, true),\n\t};\n\tcentralDirectory['lastByteAt'] =\n\t\tcentralDirectory.firstByteAt! +\n\t\tFILE_HEADER_SIZE +\n\t\tpathLength +\n\t\tfileCommentLength +\n\t\textraLength! +\n\t\tcentralDirectory.compressedSize! -\n\t\t1;\n\n\tcentralDirectory['path'] = await collectBytes(stream, pathLength);\n\tcentralDirectory['isDirectory'] = endsWithSlash(centralDirectory.path!);\n\tcentralDirectory['extra'] = await collectBytes(stream, extraLength);\n\tcentralDirectory['fileComment'] = await collectBytes(\n\t\tstream,\n\t\tfileCommentLength\n\t);\n\treturn centralDirectory as CentralDirectoryEntry;\n}\n\nfunction endsWithSlash(path: Uint8Array) {\n\treturn path[path.byteLength - 1] == '/'.charCodeAt(0);\n}\n\n/**\n * Reads the end of central directory entry from a zip file.\n *\n * The end of central directory entry is structured as follows:\n *\n * ```\n * Offset\tBytes\tDescription[33]\n * 0\t\t 4\t\tEnd of central directory signature = 0x06054b50\n * 4\t\t 2\t\tNumber of this disk (or 0xffff for ZIP64)\n * 6\t\t 2\t\tDisk where central directory starts (or 0xffff for ZIP64)\n * 8\t\t 2\t\tNumber of central directory records on this disk (or 0xffff for ZIP64)\n * 10\t\t 2\t\tTotal number of central directory records (or 0xffff for ZIP64)\n * 12\t\t 4\t\tSize of central directory (bytes) (or 0xffffffff for ZIP64)\n * 16\t\t 4\t\tOffset of start of central directory, relative to start of archive (or 0xffffffff for ZIP64)\n * 20\t\t 2\t\tComment length (n)\n * 22\t\t n\t\tComment\n * ```\n *\n * @param stream\n * @param skipSignature\n * @returns\n */\nasync function readEndCentralDirectoryEntry(\n\tstream: ReadableStream<Uint8Array>,\n\tskipSignature = false\n) {\n\tif (!skipSignature) {\n\t\tconst sigData = new DataView((await collectBytes(stream, 4))!.buffer);\n\t\tconst signature = sigData.getUint32(0, true);\n\t\tif (signature !== SIGNATURE_CENTRAL_DIRECTORY_END) {\n\t\t\treturn null;\n\t\t}\n\t}\n\tconst data = new DataView((await collectBytes(stream, 18))!.buffer);\n\tconst endOfDirectory: Partial<CentralDirectoryEndEntry> = {\n\t\tsignature: SIGNATURE_CENTRAL_DIRECTORY_END,\n\t\tnumberOfDisks: data.getUint16(0, true),\n\t\tcentralDirectoryStartDisk: data.getUint16(2, true),\n\t\tnumberCentralDirectoryRecordsOnThisDisk: data.getUint16(4, true),\n\t\tnumberCentralDirectoryRecords: data.getUint16(6, true),\n\t\tcentralDirectorySize: data.getUint32(8, true),\n\t\tcentralDirectoryOffset: data.getUint32(12, true),\n\t};\n\tconst commentLength = data.getUint16(16, true);\n\tendOfDirectory['comment'] = await collectBytes(stream, commentLength);\n\treturn endOfDirectory as CentralDirectoryEndEntry;\n}\n","import { Semaphore } from '@php-wasm/util';\nimport { filterStream } from '../utils/filter-stream';\nimport { concatUint8Array } from '../utils/concat-uint8-array';\nimport { collectBytes } from '../utils/collect-bytes';\nimport {\n\treadCentralDirectoryEntry,\n\treadFileEntry,\n\tdecodeZip,\n} from './decode-zip';\nimport type { CentralDirectoryEntry, FileEntry } from './types';\nimport { SIGNATURE_CENTRAL_DIRECTORY_END } from './types';\nimport type { IterableReadableStream } from '../utils/iterable-stream-polyfill';\n\nconst CENTRAL_DIRECTORY_END_SCAN_CHUNK_SIZE = 110 * 1024;\nconst BATCH_DOWNLOAD_OF_FILES_IF_CLOSER_THAN = 10 * 1024;\nconst PREFER_RANGES_IF_FILE_LARGER_THAN = 1024 * 1024 * 1;\nconst fetchSemaphore = new Semaphore({ concurrency: 10 });\n\nconst DEFAULT_PREDICATE = () => true;\n\n/**\n * Streams the contents of a remote zip file.\n *\n * If the zip is large and the predicate is filtering the zip contents,\n * only the matching files will be downloaded using the Range header\n * (if supported by the server).\n *\n * @param url The URL of the zip file.\n * @param predicate Optional. A function that returns true if the file should be downloaded.\n * @returns A stream of zip entries.\n */\nexport async function decodeRemoteZip(\n\turl: string,\n\tpredicate: (\n\t\tdirEntry: CentralDirectoryEntry | FileEntry\n\t) => boolean = DEFAULT_PREDICATE\n) {\n\tif (predicate === DEFAULT_PREDICATE) {\n\t\t// If we're not filtering the zip contents, let's just\n\t\t// grab the entire zip.\n\t\tconst response = await fetch(url);\n\t\treturn decodeZip(response.body!);\n\t}\n\n\tconst contentLength = await fetchContentLength(url);\n\tif (contentLength <= PREFER_RANGES_IF_FILE_LARGER_THAN) {\n\t\t// If the zip is small enough, let's just grab it.\n\t\tconst response = await fetch(url);\n\t\treturn decodeZip(response.body!);\n\t}\n\n\t// Ensure ranges query support:\n\t// Fetch one byte\n\tconst response = await fetch(url, {\n\t\theaders: {\n\t\t\t// 0-0 looks weird, doesn't it?\n\t\t\t// The Range header is inclusive so it's actually\n\t\t\t// a valid header asking for the first byte.\n\t\t\tRange: 'bytes=0-0',\n\t\t\t'Accept-Encoding': 'none',\n\t\t},\n\t});\n\n\t// Fork the stream so that we can reuse it in case\n\t// the Range header is unsupported and we're now streaming\n\t// the entire file\n\tconst [peekStream, responseStream] = response.body!.tee();\n\n\t// Read from the forked stream and close it.\n\tconst peekReader = peekStream.getReader();\n\tconst { value: peekBytes } = await peekReader.read();\n\tconst { done: peekDone } = await peekReader.read();\n\tpeekReader.releaseLock();\n\tpeekStream.cancel();\n\n\t// Confirm our Range query worked as intended:\n\tconst rangesSupported = peekBytes?.length === 1 && peekDone;\n\tif (!rangesSupported) {\n\t\t// Uh-oh, we're actually streaming the entire file.\n\t\t// Let's reuse the forked stream as our response stream.\n\t\treturn decodeZip(responseStream);\n\t}\n\n\t// We're good, let's clean up the other branch of the response stream.\n\tresponseStream.cancel();\n\tconst source = await createFetchSource(url, contentLength);\n\treturn streamCentralDirectoryEntries(source)\n\t\t.pipeThrough(filterStream(predicate))\n\t\t.pipeThrough(partitionNearbyEntries())\n\t\t.pipeThrough(\n\t\t\tfetchPartitionedEntries(source)\n\t\t) as IterableReadableStream<FileEntry>;\n}\n\n/**\n * Streams the central directory entries of a zip file.\n *\n * @param source\n * @returns\n */\nfunction streamCentralDirectoryEntries(source: BytesSource) {\n\tlet centralDirectoryStream: ReadableStream<Uint8Array>;\n\n\treturn new ReadableStream<CentralDirectoryEntry>({\n\t\tasync start() {\n\t\t\tcentralDirectoryStream = await streamCentralDirectoryBytes(source);\n\t\t},\n\t\tasync pull(controller) {\n\t\t\tconst entry = await readCentralDirectoryEntry(\n\t\t\t\tcentralDirectoryStream\n\t\t\t);\n\t\t\tif (!entry) {\n\t\t\t\tcontroller.close();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcontroller.enqueue(entry);\n\t\t},\n\t});\n}\n\n/**\n * Streams the central directory bytes of a zip file.\n *\n * @param source\n * @returns\n */\nasync function streamCentralDirectoryBytes(source: BytesSource) {\n\tconst chunkSize = CENTRAL_DIRECTORY_END_SCAN_CHUNK_SIZE;\n\tlet centralDirectory: Uint8Array = new Uint8Array();\n\n\tlet chunkStart = source.length;\n\tdo {\n\t\tchunkStart = Math.max(0, chunkStart - chunkSize);\n\t\tconst chunkEnd = Math.min(\n\t\t\tchunkStart + chunkSize - 1,\n\t\t\tsource.length - 1\n\t\t);\n\t\tconst bytes = await collectBytes(\n\t\t\tawait source.streamBytes(chunkStart, chunkEnd)\n\t\t);\n\t\tcentralDirectory = concatUint8Array(bytes!, centralDirectory);\n\n\t\t// Scan the buffer for the signature\n\t\tconst view = new DataView(bytes!.buffer);\n\t\tfor (let i = view.byteLength - 4; i >= 0; i--) {\n\t\t\tif (view.getUint32(i, true) !== SIGNATURE_CENTRAL_DIRECTORY_END) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Confirm we have enough data to read the offset and the\n\t\t\t// length of the central directory.\n\t\t\tconst centralDirectoryLengthAt = i + 12;\n\t\t\tconst centralDirectoryOffsetAt = centralDirectoryLengthAt + 4;\n\t\t\tif (centralDirectory.byteLength < centralDirectoryOffsetAt + 4) {\n\t\t\t\tthrow new Error('Central directory not found');\n\t\t\t}\n\n\t\t\t// Read where the central directory starts\n\t\t\tconst dirStart = view.getUint32(centralDirectoryOffsetAt, true);\n\t\t\tif (dirStart < chunkStart) {\n\t\t\t\t// We're missing some bytes, let's grab them\n\t\t\t\tconst missingBytes = await collectBytes(\n\t\t\t\t\tawait source.streamBytes(dirStart, chunkStart - 1)\n\t\t\t\t);\n\t\t\t\tcentralDirectory = concatUint8Array(\n\t\t\t\t\tmissingBytes!,\n\t\t\t\t\tcentralDirectory\n\t\t\t\t);\n\t\t\t} else if (dirStart > chunkStart) {\n\t\t\t\t// We've read too many bytes, let's trim them\n\t\t\t\tcentralDirectory = centralDirectory.slice(\n\t\t\t\t\tdirStart - chunkStart\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn new Blob([centralDirectory]).stream();\n\t\t}\n\t} while (chunkStart >= 0);\n\n\tthrow new Error('Central directory not found');\n}\n\n/**\n * Partitions files that are no further apart in the zip\n * archive than BATCH_DOWNLOAD_OF_FILES_IF_CLOSER_THAN.\n * It may download some extra files living within the gaps\n * between the partitions.\n */\nfunction partitionNearbyEntries() {\n\tlet lastFileEndsAt = 0;\n\tlet currentChunk: CentralDirectoryEntry[] = [];\n\treturn new TransformStream<CentralDirectoryEntry, CentralDirectoryEntry[]>({\n\t\ttransform(zipEntry, controller) {\n\t\t\t// Byte distance too large, flush and start a new chunk\n\t\t\tif (\n\t\t\t\tzipEntry.firstByteAt >\n\t\t\t\tlastFileEndsAt + BATCH_DOWNLOAD_OF_FILES_IF_CLOSER_THAN\n\t\t\t) {\n\t\t\t\tcontroller.enqueue(currentChunk);\n\t\t\t\tcurrentChunk = [];\n\t\t\t}\n\t\t\tlastFileEndsAt = zipEntry.lastByteAt;\n\t\t\tcurrentChunk.push(zipEntry);\n\t\t},\n\t\tflush(controller) {\n\t\t\tcontroller.enqueue(currentChunk);\n\t\t},\n\t});\n}\n\n/**\n * Fetches a chunk of files from the zip archive.\n *\n * If any extra files are present in the received\n * bytes stream, they are filtered out.\n */\nfunction fetchPartitionedEntries(\n\tsource: BytesSource\n): ReadableWritablePair<FileEntry, CentralDirectoryEntry[]> {\n\t/**\n\t * This function implements a ReadableStream and a WritableStream\n\t * instead of a TransformStream. This is intentional.\n\t *\n\t * In TransformStream, the `transform` function may return a\n\t * promise. The next call to `transform` will be delayed until\n\t * the promise resolves. This is a problem for us because we\n\t * want to issue many fetch() requests in parallel.\n\t *\n\t * The only way to do that seems to be creating separate ReadableStream\n\t * and WritableStream implementations.\n\t */\n\tlet isWritableClosed = false;\n\tlet requestsInProgress = 0;\n\tlet readableController: ReadableStreamDefaultController<FileEntry>;\n\tconst byteStreams: Array<\n\t\t[CentralDirectoryEntry[], ReadableStream<Uint8Array>]\n\t> = [];\n\t/**\n\t * Receives chunks of CentralDirectoryEntries, and fetches\n\t * the corresponding byte ranges from the remote zip file.\n\t */\n\tconst writable = new WritableStream<CentralDirectoryEntry[]>({\n\t\twrite(zipEntries, controller) {\n\t\t\tif (!zipEntries.length) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t++requestsInProgress;\n\t\t\t// If the write() method returns a promise, the next\n\t\t\t// call will be delayed until the promise resolves.\n\t\t\t// Let's not return the promise, then.\n\t\t\t// This will effectively issue many requests in parallel.\n\t\t\trequestChunkRange(source, zipEntries)\n\t\t\t\t.then((byteStream) => {\n\t\t\t\t\tbyteStreams.push([zipEntries, byteStream]);\n\t\t\t\t})\n\t\t\t\t.catch((e) => {\n\t\t\t\t\tcontroller.error(e);\n\t\t\t\t})\n\t\t\t\t.finally(() => {\n\t\t\t\t\t--requestsInProgress;\n\t\t\t\t});\n\t\t},\n\t\tabort() {\n\t\t\tisWritableClosed = true;\n\t\t\treadableController.close();\n\t\t},\n\t\tasync close() {\n\t\t\tisWritableClosed = true;\n\t\t},\n\t});\n\t/**\n\t * Decodes zipped bytes into FileEntry objects.\n\t */\n\tconst readable = new ReadableStream<FileEntry>({\n\t\tstart(controller) {\n\t\t\treadableController = controller;\n\t\t},\n\t\tasync pull(controller) {\n\t\t\twhile (true) {\n\t\t\t\tconst allChunksProcessed =\n\t\t\t\t\tisWritableClosed &&\n\t\t\t\t\t!byteStreams.length &&\n\t\t\t\t\trequestsInProgress === 0;\n\t\t\t\tif (allChunksProcessed) {\n\t\t\t\t\tcontroller.close();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// There's no bytes available, but the writable\n\t\t\t\t// stream is still open or there are still requests\n\t\t\t\t// in progress. Let's wait for more bytes.\n\t\t\t\tconst waitingForMoreBytes = !byteStreams.length;\n\t\t\t\tif (waitingForMoreBytes) {\n\t\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, 50));\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst [requestedPaths, stream] = byteStreams[0];\n\t\t\t\tconst file = await readFileEntry(stream);\n\t\t\t\t// The stream is exhausted, let's remove it from the queue\n\t\t\t\t// and try the next one.\n\t\t\t\tconst streamExhausted = !file;\n\t\t\t\tif (streamExhausted) {\n\t\t\t\t\tbyteStreams.shift();\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// There may be some extra files between the ones we're\n\t\t\t\t// interested in. Let's filter out any files that got\n\t\t\t\t// intertwined in the byte stream.\n\t\t\t\tconst isOneOfRequestedPaths = requestedPaths.find(\n\t\t\t\t\t(entry) => entry.path === file.path\n\t\t\t\t);\n\t\t\t\tif (!isOneOfRequestedPaths) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Finally! We've got a file we're interested in.\n\t\t\t\tcontroller.enqueue(file);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t},\n\t});\n\n\treturn {\n\t\treadable,\n\t\twritable,\n\t};\n}\n\n/**\n * Requests a chunk of bytes from the bytes source.\n *\n * @param source\n * @param zipEntries\n */\nasync function requestChunkRange(\n\tsource: BytesSource,\n\tzipEntries: CentralDirectoryEntry[]\n) {\n\tconst release = await fetchSemaphore.acquire();\n\ttry {\n\t\tconst lastZipEntry = zipEntries[zipEntries.length - 1];\n\t\tconst substream = await source.streamBytes(\n\t\t\tzipEntries[0].firstByteAt,\n\t\t\tlastZipEntry.lastByteAt\n\t\t);\n\t\treturn substream;\n\t} finally {\n\t\trelease();\n\t}\n}\n\n/**\n * Fetches the Content-Length header from a remote URL.\n */\nasync function fetchContentLength(url: string) {\n\treturn await fetch(url, { method: 'HEAD' })\n\t\t.then((response) => response.headers.get('Content-Length'))\n\t\t.then((contentLength) => {\n\t\t\tif (!contentLength) {\n\t\t\t\tthrow new Error('Content-Length header is missing');\n\t\t\t}\n\n\t\t\tconst parsedLength = parseInt(contentLength, 10);\n\t\t\tif (isNaN(parsedLength) || parsedLength < 0) {\n\t\t\t\tthrow new Error('Content-Length header is invalid');\n\t\t\t}\n\t\t\treturn parsedLength;\n\t\t});\n}\n\n/**\n * Private and experimental API: Range-based data sources.\n *\n * The idea is that if we can read arbitrary byte ranges from\n * a file, we can retrieve a specific subset of a zip file.\n */\ntype BytesSource = {\n\tlength: number;\n\tstreamBytes: (\n\t\tstart: number,\n\t\tend: number\n\t) => Promise<ReadableStream<Uint8Array>>;\n};\n\n/**\n * Creates a BytesSource enabling fetching ranges of bytes\n * from a remote URL.\n */\nasync function createFetchSource(\n\turl: string,\n\tcontentLength?: number\n): Promise<BytesSource> {\n\tif (contentLength === undefined) {\n\t\tcontentLength = await fetchContentLength(url);\n\t}\n\n\treturn {\n\t\tlength: contentLength,\n\t\tstreamBytes: async (from: number, to: number) =>\n\t\t\tawait fetch(url, {\n\t\t\t\theaders: {\n\t\t\t\t\t// The Range header is inclusive, so we need to subtract 1\n\t\t\t\t\tRange: `bytes=${from}-${to - 1}`,\n\t\t\t\t\t'Accept-Encoding': 'none',\n\t\t\t\t},\n\t\t\t}).then((response) => response.body!),\n\t};\n}\n","import type {\n\tCentralDirectoryEndEntry,\n\tCentralDirectoryEntry,\n\tFileHeader,\n} from './types';\nimport { COMPRESSION_DEFLATE, COMPRESSION_NONE } from './types';\nimport {\n\tSIGNATURE_CENTRAL_DIRECTORY_END,\n\tSIGNATURE_CENTRAL_DIRECTORY,\n\tSIGNATURE_FILE,\n} from './types';\nimport { iteratorToStream } from '../utils/iterator-to-stream';\nimport { collectBytes } from '../utils/collect-bytes';\n\n/**\n * Compresses the given files into a ZIP archive.\n *\n * @param files - An async or sync iterable of files to be compressed.\n * @returns A readable stream of the compressed ZIP archive as Uint8Array chunks.\n */\nexport function encodeZip(\n\tfiles: AsyncIterable<File> | Iterable<File>\n): ReadableStream<Uint8Array> {\n\treturn iteratorToStream(files).pipeThrough(encodeZipTransform());\n}\n\n/**\n * Encodes the files into a ZIP format.\n *\n * @returns A stream transforming File objects into zipped bytes.\n */\nfunction encodeZipTransform() {\n\tconst offsetToFileHeaderMap: Map<number, FileHeader> = new Map();\n\tlet writtenBytes = 0;\n\treturn new TransformStream<File, Uint8Array>({\n\t\tasync transform(file, controller) {\n\t\t\tconst entryBytes = new Uint8Array(await file.arrayBuffer());\n\t\t\t/**\n\t\t\t * We want to write raw deflate-compressed bytes into our\n\t\t\t * final ZIP file. CompressionStream supports \"deflate-raw\"\n\t\t\t * compression, but not on Node.js v20, it's available since v21.2.0.\n\t\t\t *\n\t\t\t * As a workaround, we use the \"gzip\" compression and add\n\t\t\t * the header and footer bytes. It works, because \"gzip\"\n\t\t\t * compression is the same as \"deflate\" compression plus\n\t\t\t * the header and the footer.\n\t\t\t *\n\t\t\t * The header is 10 bytes long:\n\t\t\t * - 2 magic bytes: 0x1f, 0x8b\n\t\t\t * - 1 compression method: 0x08 (deflate)\n\t\t\t * - 1 header flags\n\t\t\t * - 4 mtime: 0x00000000 (no timestamp)\n\t\t\t * - 1 compression flags\n\t\t\t * - 1 OS: 0x03 (Unix)\n\t\t\t *\n\t\t\t * The footer is 8 bytes long:\n\t\t\t * - 4 bytes for CRC32 of the uncompressed data\n\t\t\t * - 4 bytes for ISIZE (uncompressed size modulo 2^32)\n\t\t\t */\n\t\t\tlet compressed = (await collectBytes(\n\t\t\t\tnew Blob([entryBytes])\n\t\t\t\t\t.stream()\n\t\t\t\t\t.pipeThrough(new CompressionStream('gzip'))\n\t\t\t))!;\n\t\t\t// Grab the CRC32 hash from the footer.\n\t\t\tconst crcHash = new DataView(compressed.buffer).getUint32(\n\t\t\t\tcompressed.byteLength - 8,\n\t\t\t\ttrue\n\t\t\t);\n\t\t\t// Strip the header and the footer.\n\t\t\tcompressed = compressed.slice(10, compressed.byteLength - 8);\n\n\t\t\tconst encodedPath = new TextEncoder().encode(file.name);\n\t\t\tconst zipFileEntry: FileHeader = {\n\t\t\t\tsignature: SIGNATURE_FILE,\n\t\t\t\tversion: 2,\n\t\t\t\tgeneralPurpose: 0,\n\t\t\t\tcompressionMethod:\n\t\t\t\t\tfile.type === 'directory' || compressed.byteLength === 0\n\t\t\t\t\t\t? COMPRESSION_NONE\n\t\t\t\t\t\t: COMPRESSION_DEFLATE,\n\t\t\t\tlastModifiedTime: 0,\n\t\t\t\tlastModifiedDate: 0,\n\t\t\t\tcrc: crcHash,\n\t\t\t\tcompressedSize: compressed.byteLength,\n\t\t\t\tuncompressedSize: entryBytes.byteLength,\n\t\t\t\tpath: encodedPath,\n\t\t\t\textra: new Uint8Array(0),\n\t\t\t};\n\t\t\toffsetToFileHeaderMap.set(writtenBytes, zipFileEntry);\n\n\t\t\tconst headerBytes = encodeFileEntryHeader(zipFileEntry);\n\t\t\tcontroller.enqueue(headerBytes);\n\t\t\twrittenBytes += headerBytes.byteLength;\n\n\t\t\tcontroller.enqueue(compressed);\n\t\t\twrittenBytes += compressed.byteLength;\n\t\t},\n\t\tflush(controller) {\n\t\t\tconst centralDirectoryOffset = writtenBytes;\n\t\t\tlet centralDirectorySize = 0;\n\t\t\tfor (const [\n\t\t\t\tfileOffset,\n\t\t\t\theader,\n\t\t\t] of offsetToFileHeaderMap.entries()) {\n\t\t\t\tconst centralDirectoryEntry: Partial<CentralDirectoryEntry> = {\n\t\t\t\t\t...header,\n\t\t\t\t\tsignature: SIGNATURE_CENTRAL_DIRECTORY,\n\t\t\t\t\tfileComment: new Uint8Array(0),\n\t\t\t\t\tdiskNumber: 1,\n\t\t\t\t\tinternalAttributes: 0,\n\t\t\t\t\texternalAttributes: 0,\n\t\t\t\t\tfirstByteAt: fileOffset,\n\t\t\t\t};\n\t\t\t\tconst centralDirectoryEntryBytes = encodeCentralDirectoryEntry(\n\t\t\t\t\tcentralDirectoryEntry as CentralDirectoryEntry,\n\t\t\t\t\tfileOffset\n\t\t\t\t);\n\t\t\t\tcontroller.enqueue(centralDirectoryEntryBytes);\n\t\t\t\tcentralDirectorySize += centralDirectoryEntryBytes.byteLength;\n\t\t\t}\n\t\t\tconst centralDirectoryEnd: CentralDirectoryEndEntry = {\n\t\t\t\tsignature: SIGNATURE_CENTRAL_DIRECTORY_END,\n\t\t\t\tnumberOfDisks: 1,\n\t\t\t\tcentralDirectoryOffset,\n\t\t\t\tcentralDirectorySize,\n\t\t\t\tcentralDirectoryStartDisk: 1,\n\t\t\t\tnumberCentralDirectoryRecordsOnThisDisk:\n\t\t\t\t\toffsetToFileHeaderMap.size,\n\t\t\t\tnumberCentralDirectoryRecords: offsetToFileHeaderMap.size,\n\t\t\t\tcomment: new Uint8Array(0),\n\t\t\t};\n\t\t\tconst centralDirectoryEndBytes =\n\t\t\t\tencodeCentralDirectoryEnd(centralDirectoryEnd);\n\t\t\tcontroller.enqueue(centralDirectoryEndBytes);\n\t\t\toffsetToFileHeaderMap.clear();\n\t\t},\n\t});\n}\n\n/**\n * Encodes a file entry header as a Uint8Array.\n *\n * The array is structured as follows:\n *\n * ```\n * Offset\tBytes\tDescription\n * 0\t\t4\tLocal file header signature = 0x04034b50 (PK♥♦ or \"PK\\3\\4\")\n * 4\t\t2\tVersion needed to extract (minimum)\n * 6\t\t2\tGeneral purpose bit flag\n * 8\t\t2\tCompression method; e.g. none = 0, DEFLATE = 8 (or \"\\0x08\\0x00\")\n * 10\t\t2\tFile last modification time\n * 12\t\t2\tFile last modification date\n * 14\t\t4\tCRC-32 of uncompressed data\n * 18\t\t4\tCompressed size (or 0xffffffff for ZIP64)\n * 22\t\t4\tUncompressed size (or 0xffffffff for ZIP64)\n * 26\t\t2\tFile name length (n)\n * 28\t\t2\tExtra field length (m)\n * 30\t\tn\tFile name\n * 30+n\tm\tExtra field\n * ```\n */\nfunction encodeFileEntryHeader(entry: FileHeader) {\n\tconst buffer = new ArrayBuffer(\n\t\t30 + entry.path.byteLength + entry.extra.byteLength\n\t);\n\tconst view = new DataView(buffer);\n\tview.setUint32(0, entry.signature, true);\n\tview.setUint16(4, entry.version, true);\n\tview.setUint16(6, entry.generalPurpose, true);\n\tview.setUint16(8, entry.compressionMethod, true);\n\tview.setUint16(10, entry.lastModifiedDate, true);\n\tview.setUint16(12, entry.lastModifiedTime, true);\n\tview.setUint32(14, entry.crc, true);\n\tview.setUint32(18, entry.compressedSize, true);\n\tview.setUint32(22, entry.uncompressedSize, true);\n\tview.setUint16(26, entry.path.byteLength, true);\n\tview.setUint16(28, entry.extra.byteLength, true);\n\tconst uint8Header = new Uint8Array(buffer);\n\tuint8Header.set(entry.path, 30);\n\tuint8Header.set(entry.extra, 30 + entry.path.byteLength);\n\treturn uint8Header;\n}\n\n/**\n * Encodes a central directory entry as a Uint8Array.\n *\n * The central directory entry is structured as follows:\n *\n * ```\n * Offset Bytes Description\n * 0\t\t4\tCentral directory file header signature = 0x02014b50\n * 4\t\t2\tVersion made by\n * 6\t\t2\tVersion needed to extract (minimum)\n * 8\t\t2\tGeneral purpose bit flag\n * 10\t\t2\tCompression method\n * 12\t\t2\tFile last modification time\n * 14\t\t2\tFile last modification date\n * 16\t\t4\tCRC-32 of uncompressed data\n * 20\t\t4\tCompressed size (or 0xffffffff for ZIP64)\n * 24\t\t4\tUncompressed size (or 0xffffffff for ZIP64)\n * 28\t\t2\tFile name length (n)\n * 30\t\t2\tExtra field length (m)\n * 32\t\t2\tFile comment length (k)\n * 34\t\t2\tDisk number where file starts (or 0xffff for ZIP64)\n * 36\t\t2\tInternal file attributes\n * 38\t\t4\tExternal file attributes\n * 42\t\t4\tRelative offset of local file header (or 0xffffffff for ZIP64). This is the number of bytes between the start of the first disk on which the file occurs, and the start of the local file header. This allows software reading the central directory to locate the position of the file inside the ZIP file.\n * 46\t\tn\tFile name\n * 46+n\tm\tExtra field\n * 46+n+m\tk\tFile comment\n * ```\n */\nfunction encodeCentralDirectoryEntry(\n\tentry: CentralDirectoryEntry,\n\tfileEntryOffset: number\n) {\n\tconst buffer = new ArrayBuffer(\n\t\t46 + entry.path.byteLength + entry.extra.byteLength\n\t);\n\tconst view = new DataView(buffer);\n\tview.setUint32(0, entry.signature, true);\n\tview.setUint16(4, entry.versionCreated, true);\n\tview.setUint16(6, entry.versionNeeded, true);\n\tview.setUint16(8, entry.generalPurpose, true);\n\tview.setUint16(10, entry.compressionMethod, true);\n\tview.setUint16(12, entry.lastModifiedDate, true);\n\tview.setUint16(14, entry.lastModifiedTime, true);\n\tview.setUint32(16, entry.crc, true);\n\tview.setUint32(20, entry.compressedSize, true);\n\tview.setUint32(24, entry.uncompressedSize, true);\n\tview.setUint16(28, entry.path.byteLength, true);\n\tview.setUint16(30, entry.extra.byteLength, true);\n\tview.setUint16(32, entry.fileComment.byteLength, true);\n\tview.setUint16(34, entry.diskNumber, true);\n\tview.setUint16(36, entry.internalAttributes, true);\n\tview.setUint32(38, entry.externalAttributes, true);\n\tview.setUint32(42, fileEntryOffset, true);\n\tconst uint8Header = new Uint8Array(buffer);\n\tuint8Header.set(entry.path, 46);\n\tuint8Header.set(entry.extra, 46 + entry.path.byteLength);\n\treturn uint8Header;\n}\n\n/**\n * Encodes the end of central directory entry as a Uint8Array.\n *\n * The end of central directory entry is structured as follows:\n *\n * ```\n * Offset\tBytes\tDescription[33]\n * 0\t\t 4\t\tEnd of central directory signature = 0x06054b50\n * 4\t\t 2\t\tNumber of this disk (or 0xffff for ZIP64)\n * 6\t\t 2\t\tDisk where central directory starts (or 0xffff for ZIP64)\n * 8\t\t 2\t\tNumber of central directory records on this disk (or 0xffff for ZIP64)\n * 10\t\t 2\t\tTotal number of central directory records (or 0xffff for ZIP64)\n * 12\t\t 4\t\tSize of central directory (bytes) (or 0xffffffff for ZIP64)\n * 16\t\t 4\t\tOffset of start of central directory, relative to start of archive (or 0xffffffff for ZIP64)\n * 20\t\t 2\t\tComment length (n)\n * 22\t\t n\t\tComment\n * ```\n */\nfunction encodeCentralDirectoryEnd(entry: CentralDirectoryEndEntry) {\n\tconst buffer = new ArrayBuffer(22 + entry.comment.byteLength);\n\tconst view = new DataView(buffer);\n\tview.setUint32(0, entry.signature, true);\n\tview.setUint16(4, entry.numberOfDisks, true);\n\tview.setUint16(6, entry.centralDirectoryStartDisk, true);\n\tview.setUint16(8, entry.numberCentralDirectoryRecordsOnThisDisk, true);\n\tview.setUint16(10, entry.numberCentralDirectoryRecords, true);\n\tview.setUint32(12, entry.centralDirectorySize, true);\n\tview.setUint32(16, entry.centralDirectoryOffset, true);\n\tview.setUint16(20, entry.comment.byteLength, true);\n\tconst uint8Header = new Uint8Array(buffer);\n\tuint8Header.set(entry.comment, 22);\n\treturn uint8Header;\n}\n"],"names":["concatUint8Array","arrays","result","sum","array","offset","concatBytes","totalBytes","acc","chunk","controller","buffer","limitBytes","stream","bytes","reader","value","done","collectBytes","collectFile","fileName","iteratorToStream","iteratorOrIterable","iterator","StreamedFile","readableStream","name","options","FILE_HEADER_SIZE","SIGNATURE_FILE","SIGNATURE_CENTRAL_DIRECTORY","SIGNATURE_CENTRAL_DIRECTORY_END","COMPRESSION_NONE","COMPRESSION_DEFLATE","filterStream","predicate","prependBytes","isPrepended","appendBytes","decodeZip","streamZippedFileEntries","zipEntry","file","DEFAULT_PREDICATE","entry","nextZipEntry","signature","readFileEntry","readCentralDirectoryEntry","readEndCentralDirectoryEntry","skipSignature","data","pathLength","extraLength","endsWithSlash","bodyStream","header","footer","footerView","fileCommentLength","centralDirectory","path","endOfDirectory","commentLength","CENTRAL_DIRECTORY_END_SCAN_CHUNK_SIZE","BATCH_DOWNLOAD_OF_FILES_IF_CLOSER_THAN","PREFER_RANGES_IF_FILE_LARGER_THAN","fetchSemaphore","Semaphore","decodeRemoteZip","url","response","contentLength","fetchContentLength","peekStream","responseStream","peekReader","peekBytes","peekDone","source","createFetchSource","streamCentralDirectoryEntries","partitionNearbyEntries","fetchPartitionedEntries","centralDirectoryStream","streamCentralDirectoryBytes","chunkSize","chunkStart","chunkEnd","view","i","centralDirectoryOffsetAt","dirStart","missingBytes","lastFileEndsAt","currentChunk","isWritableClosed","requestsInProgress","readableController","byteStreams","writable","zipEntries","requestChunkRange","byteStream","e","resolve","requestedPaths","release","lastZipEntry","parsedLength","from","to","encodeZip","files","encodeZipTransform","offsetToFileHeaderMap","writtenBytes","entryBytes","compressed","crcHash","encodedPath","zipFileEntry","headerBytes","encodeFileEntryHeader","centralDirectoryOffset","centralDirectorySize","fileOffset","centralDirectoryEntry","centralDirectoryEntryBytes","encodeCentralDirectoryEntry","centralDirectoryEnd","centralDirectoryEndBytes","encodeCentralDirectoryEnd","uint8Header","fileEntryOffset"],"mappings":"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"}
|
package/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../packages/php-wasm/stream-compression/src/utils/concat-uint8-array.ts","../../../../packages/php-wasm/stream-compression/src/utils/concat-bytes.ts","../../../../packages/php-wasm/stream-compression/src/utils/limit-bytes.ts","../../../../packages/php-wasm/stream-compression/src/utils/collect-bytes.ts","../../../../packages/php-wasm/stream-compression/src/utils/collect-file.ts","../../../../packages/php-wasm/stream-compression/src/utils/iterator-to-stream.ts","../../../../packages/php-wasm/stream-compression/src/utils/streamed-file.ts","../../../../packages/php-wasm/stream-compression/src/utils/iterable-stream-polyfill.ts","../../../../packages/php-wasm/stream-compression/src/zip/types.ts","../../../../packages/php-wasm/stream-compression/src/utils/filter-stream.ts","../../../../packages/php-wasm/stream-compression/src/utils/prepend-bytes.ts","../../../../packages/php-wasm/stream-compression/src/utils/append-bytes.ts","../../../../packages/php-wasm/stream-compression/src/zip/decode-zip.ts","../../../../packages/php-wasm/stream-compression/src/zip/decode-remote-zip.ts","../../../../packages/php-wasm/stream-compression/src/zip/encode-zip.ts"],"sourcesContent":["/**\n * Concatenates multiple Uint8Arrays into a single Uint8Array.\n *\n * @param arrays The arrays to concatenate.\n * @returns A new Uint8Array containing the contents of all the arrays.\n */\nexport function concatUint8Array(...arrays: Uint8Array[]) {\n\tconst result = new Uint8Array(\n\t\tarrays.reduce((sum, array) => sum + array.length, 0)\n\t);\n\tlet offset = 0;\n\tfor (const array of arrays) {\n\t\tresult.set(array, offset);\n\t\toffset += array.length;\n\t}\n\treturn result;\n}\n","import { concatUint8Array } from './concat-uint8-array';\n\n/**\n * Concatenates the contents of the stream into a single Uint8Array.\n *\n * @param totalBytes Optional. The number of bytes to concatenate. Used to\n * \t\t\t\t pre-allocate the buffer. If not provided, the buffer will\n * \t\t\t\t be dynamically resized as needed.\n * @returns A stream that will emit a single UInt8Array entry before closing.\n */\nexport function concatBytes(totalBytes?: number) {\n\tif (totalBytes === undefined) {\n\t\tlet acc = new Uint8Array();\n\t\treturn new TransformStream<Uint8Array, Uint8Array>({\n\t\t\ttransform(chunk) {\n\t\t\t\tacc = concatUint8Array(acc, chunk);\n\t\t\t},\n\n\t\t\tflush(controller) {\n\t\t\t\tcontroller.enqueue(acc);\n\t\t\t},\n\t\t});\n\t} else {\n\t\tconst buffer = new ArrayBuffer(totalBytes || 0);\n\t\tlet offset = 0;\n\t\treturn new TransformStream<Uint8Array, Uint8Array>({\n\t\t\ttransform(chunk) {\n\t\t\t\tconst view = new Uint8Array(buffer);\n\t\t\t\tview.set(chunk, offset);\n\t\t\t\toffset += chunk.byteLength;\n\t\t\t},\n\n\t\t\tflush(controller) {\n\t\t\t\tcontroller.enqueue(new Uint8Array(buffer));\n\t\t\t},\n\t\t});\n\t}\n}\n","/**\n * Limit the number of bytes read from a stream.\n *\n * @param stream The stream to limit.\n * @param bytes The number of bytes to read from the stream.\n * @returns A new stream that will read at most `bytes` bytes from `stream`.\n */\nexport function limitBytes(stream: ReadableStream<Uint8Array>, bytes: number) {\n\tif (bytes === 0) {\n\t\treturn new ReadableStream({\n\t\t\tstart(controller) {\n\t\t\t\tcontroller.close();\n\t\t\t},\n\t\t});\n\t}\n\tconst reader = stream.getReader({ mode: 'byob' });\n\tlet offset = 0;\n\treturn new ReadableStream({\n\t\tasync pull(controller) {\n\t\t\tconst { value, done } = await reader.read(\n\t\t\t\tnew Uint8Array(bytes - offset)\n\t\t\t);\n\t\t\tif (done) {\n\t\t\t\treader.releaseLock();\n\t\t\t\tcontroller.close();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\toffset += value.length;\n\t\t\tcontroller.enqueue(value);\n\n\t\t\tif (offset >= bytes) {\n\t\t\t\treader.releaseLock();\n\t\t\t\tcontroller.close();\n\t\t\t}\n\t\t},\n\t\tcancel() {\n\t\t\treader.cancel();\n\t\t},\n\t});\n}\n","import { concatBytes } from './concat-bytes';\nimport { limitBytes } from './limit-bytes';\n\n/**\n * Collects the contents of the entire stream into a single Uint8Array.\n *\n * @param stream The stream to collect.\n * @param bytes Optional. The number of bytes to read from the stream.\n * @returns The string contents of the stream.\n */\nexport async function collectBytes(\n\tstream: ReadableStream<Uint8Array>,\n\tbytes?: number\n) {\n\tif (bytes !== undefined) {\n\t\tstream = limitBytes(stream, bytes);\n\t}\n\n\treturn await stream\n\t\t.pipeThrough(concatBytes(bytes))\n\t\t.getReader()\n\t\t.read()\n\t\t.then(({ value }) => value!);\n}\n","import { collectBytes } from './collect-bytes';\n\n/**\n * Collects the contents of the entire stream into a single File object.\n *\n * @param stream The stream to collect.\n * @param fileName The name of the file\n * @returns The string contents of the stream.\n */\nexport async function collectFile(\n\tfileName: string,\n\tstream: ReadableStream<Uint8Array>\n) {\n\t// @TODO: use StreamingFile\n\treturn new File([await collectBytes(stream)], fileName);\n}\n","import type { IterableReadableStream } from './iterable-stream-polyfill';\n\n/**\n * Converts an iterator or iterable to a stream.\n *\n * @param iteratorOrIterable The iterator or iterable to convert.\n * @returns A stream that will yield the values from the iterator or iterable.\n */\nexport function iteratorToStream<T>(\n\titeratorOrIterable:\n\t\t| AsyncIterator<T>\n\t\t| Iterator<T>\n\t\t| AsyncIterable<T>\n\t\t| Iterable<T>\n) {\n\tif (iteratorOrIterable instanceof ReadableStream) {\n\t\treturn iteratorOrIterable as IterableReadableStream<T>;\n\t}\n\n\tlet iterator: AsyncIterator<T> | Iterator<T>;\n\tif (Symbol.asyncIterator in iteratorOrIterable) {\n\t\titerator = iteratorOrIterable[Symbol.asyncIterator]();\n\t} else if (Symbol.iterator in iteratorOrIterable) {\n\t\titerator = iteratorOrIterable[Symbol.iterator]();\n\t} else {\n\t\titerator = iteratorOrIterable;\n\t}\n\n\treturn new ReadableStream<T>({\n\t\tasync pull(controller) {\n\t\t\tconst { done, value } = await iterator.next();\n\t\t\tif (done) {\n\t\t\t\tcontroller.close();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcontroller.enqueue(value);\n\t\t},\n\t}) as IterableReadableStream<T>;\n}\n","import { collectBytes } from './collect-bytes';\n\n/**\n * Represents a file that is streamed and not fully\n * loaded into memory.\n */\nexport class StreamedFile extends File {\n\treadonly filesize: number | undefined;\n\n\tprivate readableStream: ReadableStream<Uint8Array>;\n\n\t/**\n\t * Creates a new StreamedFile instance.\n\t *\n\t * @param readableStream The readable stream containing the file data.\n\t * @param name The name of the file.\n\t * @param options An object containing options such as the MIME type and file size.\n\t */\n\tconstructor(\n\t\treadableStream: ReadableStream<Uint8Array>,\n\t\tname: string,\n\t\toptions?: { type?: string; filesize?: number }\n\t) {\n\t\tsuper([], name, { type: options?.type });\n\t\tthis.readableStream = readableStream;\n\t\tthis.filesize = options?.filesize;\n\t}\n\n\t/**\n\t * Overrides the slice() method of the File class.\n\t *\n\t * @returns A Blob representing a portion of the file.\n\t */\n\toverride slice(): Blob {\n\t\tthrow new Error('slice() is not possible on a StreamedFile');\n\t}\n\n\t/**\n\t * Returns the readable stream associated with the file.\n\t *\n\t * @returns The readable stream.\n\t */\n\toverride stream() {\n\t\treturn this.readableStream;\n\t}\n\n\t/**\n\t * Loads the file data into memory and then returns it as a string.\n\t *\n\t * @returns File data as text.\n\t */\n\toverride async text() {\n\t\treturn new TextDecoder().decode(await this.arrayBuffer());\n\t}\n\n\t/**\n\t * Loads the file data into memory and then returns it as an ArrayBuffer.\n\t *\n\t * @returns File data as an ArrayBuffer.\n\t */\n\toverride async arrayBuffer() {\n\t\treturn await collectBytes(this.stream());\n\t}\n}\n","/**\n * Polyfill for ReadableStream[Symbol.asyncIterator]\n * This enables the use of for-await-of loops with ReadableStreams\n *\n * @example\n * ```ts\n * for await (const entry of stream) {\n * \t // ...\n * }\n * ```\n */\n// @ts-ignore\nif (!ReadableStream.prototype[Symbol.asyncIterator]) {\n\t// @ts-ignore\n\tReadableStream.prototype[Symbol.asyncIterator] = async function* () {\n\t\tconst reader = this.getReader();\n\t\ttry {\n\t\t\twhile (true) {\n\t\t\t\tconst { done, value } = await reader.read();\n\t\t\t\tif (done) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tyield value;\n\t\t\t}\n\t\t} finally {\n\t\t\treader.releaseLock();\n\t\t}\n\t};\n\t// @ts-ignore\n\tReadableStream.prototype.iterate =\n\t\t// @ts-ignore\n\t\tReadableStream.prototype[Symbol.asyncIterator];\n}\n\nexport type IterableReadableStream<R> = ReadableStream<R> & AsyncIterable<R>;\n","export const FILE_HEADER_SIZE = 32;\nexport const SIGNATURE_FILE = 67324752 as const;\nexport const SIGNATURE_CENTRAL_DIRECTORY = 33639248 as const;\nexport const SIGNATURE_CENTRAL_DIRECTORY_END = 101010256 as const;\nexport const SIGNATURE_DATA_DESCRIPTOR = 134695760 as const;\n\nexport const COMPRESSION_NONE = 0 as const;\nexport const COMPRESSION_DEFLATE = 8 as const;\nexport type CompressionMethod =\n\t| typeof COMPRESSION_NONE\n\t| typeof COMPRESSION_DEFLATE;\n\nexport type ZipEntry =\n\t| FileEntry\n\t| CentralDirectoryEntry\n\t| CentralDirectoryEndEntry;\n\n/**\n * Data of the file entry header encoded in a \".zip\" file.\n */\nexport interface FileHeader {\n\tsignature: typeof SIGNATURE_FILE;\n\tversion: number;\n\tgeneralPurpose: number;\n\tcompressionMethod: CompressionMethod;\n\tlastModifiedTime: number;\n\tlastModifiedDate: number;\n\tcrc: number;\n\tcompressedSize: number;\n\tuncompressedSize: number;\n\tpath: Uint8Array;\n\textra: Uint8Array;\n}\nexport interface FileEntry extends FileHeader {\n\tisDirectory: boolean;\n\tbytes: Uint8Array;\n}\n\n/**\n * Data of the central directory entry encoded in a \".zip\" file.\n */\nexport interface CentralDirectoryEntry {\n\tsignature: typeof SIGNATURE_CENTRAL_DIRECTORY;\n\tversionCreated: number;\n\tversionNeeded: number;\n\tgeneralPurpose: number;\n\tcompressionMethod: CompressionMethod;\n\tlastModifiedTime: number;\n\tlastModifiedDate: number;\n\tcrc: number;\n\tcompressedSize: number;\n\tuncompressedSize: number;\n\tdiskNumber: number;\n\tinternalAttributes: number;\n\texternalAttributes: number;\n\tfirstByteAt: number;\n\tlastByteAt: number;\n\tpath: Uint8Array;\n\textra: Uint8Array;\n\tfileComment: Uint8Array;\n\tisDirectory: boolean;\n}\n\n/**\n * Data of the central directory end entry encoded in a \".zip\" file.\n */\nexport interface CentralDirectoryEndEntry {\n\tsignature: typeof SIGNATURE_CENTRAL_DIRECTORY_END;\n\tnumberOfDisks: number;\n\tcentralDirectoryStartDisk: number;\n\tnumberCentralDirectoryRecordsOnThisDisk: number;\n\tnumberCentralDirectoryRecords: number;\n\tcentralDirectorySize: number;\n\tcentralDirectoryOffset: number;\n\tcomment: Uint8Array;\n}\n","/**\n * Filter the stream based on a predicate.\n *\n * @param predicate The predicate to filter the stream with.\n * @returns A new stream that will only contain chunks that pass the predicate.\n */\nexport function filterStream<T>(predicate: (chunk: T) => boolean) {\n\treturn new TransformStream<T, T>({\n\t\ttransform(chunk, controller) {\n\t\t\tif (predicate(chunk)) {\n\t\t\t\tcontroller.enqueue(chunk);\n\t\t\t}\n\t\t},\n\t});\n}\n","/**\n * Prepend bytes to a stream.\n *\n * @param bytes The bytes to prepend.\n * @returns A transform stream that will prepend the specified bytes.\n */\nexport function prependBytes(bytes: Uint8Array) {\n\tlet isPrepended = false;\n\treturn new TransformStream<Uint8Array, Uint8Array>({\n\t\tasync transform(chunk, controller) {\n\t\t\tif (!isPrepended) {\n\t\t\t\tisPrepended = true;\n\t\t\t\tcontroller.enqueue(bytes);\n\t\t\t}\n\t\t\tcontroller.enqueue(chunk);\n\t\t},\n\t});\n}\n","/**\n * Appends bytes to a stream.\n *\n * @param bytes The bytes to append.\n * @returns A transform stream that will append the specified bytes.\n */\nexport function appendBytes(bytes: Uint8Array) {\n\treturn new TransformStream<Uint8Array, Uint8Array>({\n\t\tasync transform(chunk, controller) {\n\t\t\tcontroller.enqueue(chunk);\n\t\t},\n\t\tasync flush(controller) {\n\t\t\tcontroller.enqueue(bytes);\n\t\t},\n\t});\n}\n","/**\n * Reads files from a stream of zip file bytes.\n */\nimport type { IterableReadableStream } from '../utils/iterable-stream-polyfill';\n\nimport type { CompressionMethod } from './types';\nimport {\n\tSIGNATURE_FILE,\n\tSIGNATURE_CENTRAL_DIRECTORY,\n\tSIGNATURE_CENTRAL_DIRECTORY_END,\n\tFILE_HEADER_SIZE,\n\tCOMPRESSION_DEFLATE,\n} from './types';\nimport type {\n\tCentralDirectoryEntry,\n\tFileEntry,\n\tZipEntry,\n\tCentralDirectoryEndEntry,\n} from './types';\nimport { filterStream } from '../utils/filter-stream';\nimport { collectBytes } from '../utils/collect-bytes';\nimport { limitBytes } from '../utils/limit-bytes';\nimport { concatBytes } from '../utils/concat-bytes';\nimport { prependBytes } from '../utils/prepend-bytes';\nimport { appendBytes } from '../utils/append-bytes';\n\n/**\n * Unzips a stream of zip file bytes.\n *\n * @param stream A stream of zip file bytes.\n * @param predicate Optional. A function that returns true if the file should be downloaded.\n * @returns An iterable stream of File objects.\n */\nexport function decodeZip(\n\tstream: ReadableStream<Uint8Array>,\n\tpredicate?: () => boolean\n) {\n\treturn streamZippedFileEntries(stream, predicate).pipeThrough(\n\t\tnew TransformStream<FileEntry, File>({\n\t\t\tasync transform(zipEntry, controller) {\n\t\t\t\tconst file = new File(\n\t\t\t\t\t[zipEntry.bytes],\n\t\t\t\t\tnew TextDecoder().decode(zipEntry.path),\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: zipEntry.isDirectory ? 'directory' : undefined,\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t\tcontroller.enqueue(file);\n\t\t\t},\n\t\t})\n\t) as IterableReadableStream<File>;\n}\n\nconst DEFAULT_PREDICATE = () => true;\n\n/**\n * Parses a stream of zipped bytes into FileEntry informations.\n *\n * @param stream A stream of zip file bytes.\n * @param predicate Optional. A function that returns true if the file should be downloaded.\n * @returns An iterable stream of FileEntry objects.\n */\nexport function streamZippedFileEntries(\n\tstream: ReadableStream<Uint8Array>,\n\tpredicate: (\n\t\tdirEntry: CentralDirectoryEntry | FileEntry\n\t) => boolean = DEFAULT_PREDICATE\n) {\n\tconst entriesStream = new ReadableStream<ZipEntry>({\n\t\tasync pull(controller) {\n\t\t\tconst entry = await nextZipEntry(stream);\n\t\t\tif (!entry) {\n\t\t\t\tcontroller.close();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcontroller.enqueue(entry);\n\t\t},\n\t}) as IterableReadableStream<ZipEntry>;\n\n\treturn entriesStream\n\t\t.pipeThrough(\n\t\t\tfilterStream(({ signature }) => signature === SIGNATURE_FILE)\n\t\t)\n\t\t.pipeThrough(\n\t\t\tfilterStream(predicate as any)\n\t\t) as IterableReadableStream<FileEntry>;\n}\n\n/**\n * Reads the next zip entry from a stream of zip file bytes.\n *\n * @param stream A stream of zip file bytes.\n * @returns A FileEntry object.\n */\nasync function nextZipEntry(stream: ReadableStream<Uint8Array>) {\n\tconst sigData = new DataView((await collectBytes(stream, 4))!.buffer);\n\tconst signature = sigData.getUint32(0, true);\n\tif (signature === SIGNATURE_FILE) {\n\t\treturn await readFileEntry(stream, true);\n\t} else if (signature === SIGNATURE_CENTRAL_DIRECTORY) {\n\t\treturn await readCentralDirectoryEntry(stream, true);\n\t} else if (signature === SIGNATURE_CENTRAL_DIRECTORY_END) {\n\t\treturn await readEndCentralDirectoryEntry(stream, true);\n\t}\n\treturn null;\n}\n\n/**\n * Reads a file entry from a zip file.\n *\n * The file entry is structured as follows:\n *\n * ```\n * Offset\tBytes\tDescription\n * 0\t\t4\tLocal file header signature = 0x04034b50 (PK♥♦ or \"PK\\3\\4\")\n * 4\t\t2\tVersion needed to extract (minimum)\n * 6\t\t2\tGeneral purpose bit flag\n * 8\t\t2\tCompression method; e.g. none = 0, DEFLATE = 8 (or \"\\0x08\\0x00\")\n * 10\t\t2\tFile last modification time\n * 12\t\t2\tFile last modification date\n * 14\t\t4\tCRC-32 of uncompressed data\n * 18\t\t4\tCompressed size (or 0xffffffff for ZIP64)\n * 22\t\t4\tUncompressed size (or 0xffffffff for ZIP64)\n * 26\t\t2\tFile name length (n)\n * 28\t\t2\tExtra field length (m)\n * 30\t\tn\tFile name\n * 30+n\tm\tExtra field\n * ```\n *\n * @param stream\n * @param skipSignature Do not consume the signature from the stream.\n * @returns\n */\nexport async function readFileEntry(\n\tstream: ReadableStream<Uint8Array>,\n\tskipSignature = false\n): Promise<FileEntry | null> {\n\tif (!skipSignature) {\n\t\tconst sigData = new DataView((await collectBytes(stream, 4))!.buffer);\n\t\tconst signature = sigData.getUint32(0, true);\n\t\tif (signature !== SIGNATURE_FILE) {\n\t\t\treturn null;\n\t\t}\n\t}\n\tconst data = new DataView((await collectBytes(stream, 26))!.buffer);\n\tconst pathLength = data.getUint16(22, true);\n\tconst extraLength = data.getUint16(24, true);\n\tconst entry: Partial<FileEntry> = {\n\t\tsignature: SIGNATURE_FILE,\n\t\tversion: data.getUint32(0, true),\n\t\tgeneralPurpose: data.getUint16(2, true),\n\t\tcompressionMethod: data.getUint16(4, true) as CompressionMethod,\n\t\tlastModifiedTime: data.getUint16(6, true),\n\t\tlastModifiedDate: data.getUint16(8, true),\n\t\tcrc: data.getUint32(10, true),\n\t\tcompressedSize: data.getUint32(14, true),\n\t\tuncompressedSize: data.getUint32(18, true),\n\t};\n\n\tentry['path'] = await collectBytes(stream, pathLength);\n\tentry['isDirectory'] = endsWithSlash(entry.path!);\n\tentry['extra'] = await collectBytes(stream, extraLength);\n\n\t// Make sure we consume the body stream or else\n\t// we'll start reading the next file at the wrong\n\t// offset.\n\t// @TODO: Expose the body stream instead of reading it all\n\t// eagerly. Ensure the next iteration exhausts\n\t// the last body stream before moving on.\n\n\tlet bodyStream = limitBytes(stream, entry['compressedSize']!);\n\n\tif (entry['compressionMethod'] === COMPRESSION_DEFLATE) {\n\t\t/**\n\t\t * We want to write raw deflate-compressed bytes into our\n\t\t * final ZIP file. CompressionStream supports \"deflate-raw\"\n\t\t * compression, but not on Node.js v20, it's available since v21.2.0.\n\t\t *\n\t\t * As a workaround, we use the \"gzip\" compression and add\n\t\t * the header and footer bytes. It works, because \"gzip\"\n\t\t * compression is the same as \"deflate\" compression plus\n\t\t * the header and the footer.\n\t\t *\n\t\t * The header is 10 bytes long:\n\t\t * - 2 magic bytes: 0x1f, 0x8b\n\t\t * - 1 compression method: 0x08 (deflate)\n\t\t * - 1 header flags\n\t\t * - 4 mtime: 0x00000000 (no timestamp)\n\t\t * - 1 compression flags\n\t\t * - 1 OS: 0x03 (Unix)\n\t\t *\n\t\t * The footer is 8 bytes long:\n\t\t * - 4 bytes for CRC32 of the uncompressed data\n\t\t * - 4 bytes for ISIZE (uncompressed size modulo 2^32)\n\t\t */\n\t\tconst header = new Uint8Array(10);\n\t\theader.set([0x1f, 0x8b, 0x08]);\n\n\t\tconst footer = new Uint8Array(8);\n\t\tconst footerView = new DataView(footer.buffer);\n\t\tfooterView.setUint32(0, entry.crc!, true);\n\t\tfooterView.setUint32(4, entry.uncompressedSize! % 2 ** 32, true);\n\t\tbodyStream = bodyStream\n\t\t\t.pipeThrough(prependBytes(header))\n\t\t\t.pipeThrough(appendBytes(footer))\n\t\t\t.pipeThrough(new DecompressionStream('gzip'));\n\t}\n\tentry['bytes'] = await bodyStream\n\t\t.pipeThrough(concatBytes(entry['uncompressedSize']))\n\t\t.getReader()\n\t\t.read()\n\t\t.then(({ value }) => value!);\n\treturn entry as FileEntry;\n}\n\n/**\n * Reads a central directory entry from a zip file.\n *\n * The central directory entry is structured as follows:\n *\n * ```\n * Offset Bytes Description\n * 0\t\t4\tCentral directory file header signature = 0x02014b50\n * 4\t\t2\tVersion made by\n * 6\t\t2\tVersion needed to extract (minimum)\n * 8\t\t2\tGeneral purpose bit flag\n * 10\t\t2\tCompression method\n * 12\t\t2\tFile last modification time\n * 14\t\t2\tFile last modification date\n * 16\t\t4\tCRC-32 of uncompressed data\n * 20\t\t4\tCompressed size (or 0xffffffff for ZIP64)\n * 24\t\t4\tUncompressed size (or 0xffffffff for ZIP64)\n * 28\t\t2\tFile name length (n)\n * 30\t\t2\tExtra field length (m)\n * 32\t\t2\tFile comment length (k)\n * 34\t\t2\tDisk number where file starts (or 0xffff for ZIP64)\n * 36\t\t2\tInternal file attributes\n * 38\t\t4\tExternal file attributes\n * 42\t\t4\tRelative offset of local file header (or 0xffffffff for ZIP64). This is the number of bytes between the start of the first disk on which the file occurs, and the start of the local file header. This allows software reading the central directory to locate the position of the file inside the ZIP file.\n * 46\t\tn\tFile name\n * 46+n\tm\tExtra field\n * 46+n+m\tk\tFile comment\n * ```\n *\n * @param stream\n * @param skipSignature\n * @returns\n */\nexport async function readCentralDirectoryEntry(\n\tstream: ReadableStream<Uint8Array>,\n\tskipSignature = false\n): Promise<CentralDirectoryEntry | null> {\n\tif (!skipSignature) {\n\t\tconst sigData = new DataView((await collectBytes(stream, 4))!.buffer);\n\t\tconst signature = sigData.getUint32(0, true);\n\t\tif (signature !== SIGNATURE_CENTRAL_DIRECTORY) {\n\t\t\treturn null;\n\t\t}\n\t}\n\tconst data = new DataView((await collectBytes(stream, 42))!.buffer);\n\tconst pathLength = data.getUint16(24, true);\n\tconst extraLength = data.getUint16(26, true);\n\tconst fileCommentLength = data.getUint16(28, true);\n\tconst centralDirectory: Partial<CentralDirectoryEntry> = {\n\t\tsignature: SIGNATURE_CENTRAL_DIRECTORY,\n\t\tversionCreated: data.getUint16(0, true),\n\t\tversionNeeded: data.getUint16(2, true),\n\t\tgeneralPurpose: data.getUint16(4, true),\n\t\tcompressionMethod: data.getUint16(6, true) as CompressionMethod,\n\t\tlastModifiedTime: data.getUint16(8, true),\n\t\tlastModifiedDate: data.getUint16(10, true),\n\t\tcrc: data.getUint32(12, true),\n\t\tcompressedSize: data.getUint32(16, true),\n\t\tuncompressedSize: data.getUint32(20, true),\n\t\tdiskNumber: data.getUint16(30, true),\n\t\tinternalAttributes: data.getUint16(32, true),\n\t\texternalAttributes: data.getUint32(34, true),\n\t\tfirstByteAt: data.getUint32(38, true),\n\t};\n\tcentralDirectory['lastByteAt'] =\n\t\tcentralDirectory.firstByteAt! +\n\t\tFILE_HEADER_SIZE +\n\t\tpathLength +\n\t\tfileCommentLength +\n\t\textraLength! +\n\t\tcentralDirectory.compressedSize! -\n\t\t1;\n\n\tcentralDirectory['path'] = await collectBytes(stream, pathLength);\n\tcentralDirectory['isDirectory'] = endsWithSlash(centralDirectory.path!);\n\tcentralDirectory['extra'] = await collectBytes(stream, extraLength);\n\tcentralDirectory['fileComment'] = await collectBytes(\n\t\tstream,\n\t\tfileCommentLength\n\t);\n\treturn centralDirectory as CentralDirectoryEntry;\n}\n\nfunction endsWithSlash(path: Uint8Array) {\n\treturn path[path.byteLength - 1] == '/'.charCodeAt(0);\n}\n\n/**\n * Reads the end of central directory entry from a zip file.\n *\n * The end of central directory entry is structured as follows:\n *\n * ```\n * Offset\tBytes\tDescription[33]\n * 0\t\t 4\t\tEnd of central directory signature = 0x06054b50\n * 4\t\t 2\t\tNumber of this disk (or 0xffff for ZIP64)\n * 6\t\t 2\t\tDisk where central directory starts (or 0xffff for ZIP64)\n * 8\t\t 2\t\tNumber of central directory records on this disk (or 0xffff for ZIP64)\n * 10\t\t 2\t\tTotal number of central directory records (or 0xffff for ZIP64)\n * 12\t\t 4\t\tSize of central directory (bytes) (or 0xffffffff for ZIP64)\n * 16\t\t 4\t\tOffset of start of central directory, relative to start of archive (or 0xffffffff for ZIP64)\n * 20\t\t 2\t\tComment length (n)\n * 22\t\t n\t\tComment\n * ```\n *\n * @param stream\n * @param skipSignature\n * @returns\n */\nasync function readEndCentralDirectoryEntry(\n\tstream: ReadableStream<Uint8Array>,\n\tskipSignature = false\n) {\n\tif (!skipSignature) {\n\t\tconst sigData = new DataView((await collectBytes(stream, 4))!.buffer);\n\t\tconst signature = sigData.getUint32(0, true);\n\t\tif (signature !== SIGNATURE_CENTRAL_DIRECTORY_END) {\n\t\t\treturn null;\n\t\t}\n\t}\n\tconst data = new DataView((await collectBytes(stream, 18))!.buffer);\n\tconst endOfDirectory: Partial<CentralDirectoryEndEntry> = {\n\t\tsignature: SIGNATURE_CENTRAL_DIRECTORY_END,\n\t\tnumberOfDisks: data.getUint16(0, true),\n\t\tcentralDirectoryStartDisk: data.getUint16(2, true),\n\t\tnumberCentralDirectoryRecordsOnThisDisk: data.getUint16(4, true),\n\t\tnumberCentralDirectoryRecords: data.getUint16(6, true),\n\t\tcentralDirectorySize: data.getUint32(8, true),\n\t\tcentralDirectoryOffset: data.getUint32(12, true),\n\t};\n\tconst commentLength = data.getUint16(16, true);\n\tendOfDirectory['comment'] = await collectBytes(stream, commentLength);\n\treturn endOfDirectory as CentralDirectoryEndEntry;\n}\n","import { Semaphore } from '@php-wasm/util';\nimport { filterStream } from '../utils/filter-stream';\nimport { concatUint8Array } from '../utils/concat-uint8-array';\nimport { collectBytes } from '../utils/collect-bytes';\nimport {\n\treadCentralDirectoryEntry,\n\treadFileEntry,\n\tdecodeZip,\n} from './decode-zip';\nimport type { CentralDirectoryEntry, FileEntry } from './types';\nimport { SIGNATURE_CENTRAL_DIRECTORY_END } from './types';\nimport type { IterableReadableStream } from '../utils/iterable-stream-polyfill';\n\nconst CENTRAL_DIRECTORY_END_SCAN_CHUNK_SIZE = 110 * 1024;\nconst BATCH_DOWNLOAD_OF_FILES_IF_CLOSER_THAN = 10 * 1024;\nconst PREFER_RANGES_IF_FILE_LARGER_THAN = 1024 * 1024 * 1;\nconst fetchSemaphore = new Semaphore({ concurrency: 10 });\n\nconst DEFAULT_PREDICATE = () => true;\n\n/**\n * Streams the contents of a remote zip file.\n *\n * If the zip is large and the predicate is filtering the zip contents,\n * only the matching files will be downloaded using the Range header\n * (if supported by the server).\n *\n * @param url The URL of the zip file.\n * @param predicate Optional. A function that returns true if the file should be downloaded.\n * @returns A stream of zip entries.\n */\nexport async function decodeRemoteZip(\n\turl: string,\n\tpredicate: (\n\t\tdirEntry: CentralDirectoryEntry | FileEntry\n\t) => boolean = DEFAULT_PREDICATE\n) {\n\tif (predicate === DEFAULT_PREDICATE) {\n\t\t// If we're not filtering the zip contents, let's just\n\t\t// grab the entire zip.\n\t\tconst response = await fetch(url);\n\t\treturn decodeZip(response.body!);\n\t}\n\n\tconst contentLength = await fetchContentLength(url);\n\tif (contentLength <= PREFER_RANGES_IF_FILE_LARGER_THAN) {\n\t\t// If the zip is small enough, let's just grab it.\n\t\tconst response = await fetch(url);\n\t\treturn decodeZip(response.body!);\n\t}\n\n\t// Ensure ranges query support:\n\t// Fetch one byte\n\tconst response = await fetch(url, {\n\t\theaders: {\n\t\t\t// 0-0 looks weird, doesn't it?\n\t\t\t// The Range header is inclusive so it's actually\n\t\t\t// a valid header asking for the first byte.\n\t\t\tRange: 'bytes=0-0',\n\t\t\t'Accept-Encoding': 'none',\n\t\t},\n\t});\n\n\t// Fork the stream so that we can reuse it in case\n\t// the Range header is unsupported and we're now streaming\n\t// the entire file\n\tconst [peekStream, responseStream] = response.body!.tee();\n\n\t// Read from the forked stream and close it.\n\tconst peekReader = peekStream.getReader();\n\tconst { value: peekBytes } = await peekReader.read();\n\tconst { done: peekDone } = await peekReader.read();\n\tpeekReader.releaseLock();\n\tpeekStream.cancel();\n\n\t// Confirm our Range query worked as intended:\n\tconst rangesSupported = peekBytes?.length === 1 && peekDone;\n\tif (!rangesSupported) {\n\t\t// Uh-oh, we're actually streaming the entire file.\n\t\t// Let's reuse the forked stream as our response stream.\n\t\treturn decodeZip(responseStream);\n\t}\n\n\t// We're good, let's clean up the other branch of the response stream.\n\tresponseStream.cancel();\n\tconst source = await createFetchSource(url, contentLength);\n\treturn streamCentralDirectoryEntries(source)\n\t\t.pipeThrough(filterStream(predicate))\n\t\t.pipeThrough(partitionNearbyEntries())\n\t\t.pipeThrough(\n\t\t\tfetchPartitionedEntries(source)\n\t\t) as IterableReadableStream<FileEntry>;\n}\n\n/**\n * Streams the central directory entries of a zip file.\n *\n * @param source\n * @returns\n */\nfunction streamCentralDirectoryEntries(source: BytesSource) {\n\tlet centralDirectoryStream: ReadableStream<Uint8Array>;\n\n\treturn new ReadableStream<CentralDirectoryEntry>({\n\t\tasync start() {\n\t\t\tcentralDirectoryStream = await streamCentralDirectoryBytes(source);\n\t\t},\n\t\tasync pull(controller) {\n\t\t\tconst entry = await readCentralDirectoryEntry(\n\t\t\t\tcentralDirectoryStream\n\t\t\t);\n\t\t\tif (!entry) {\n\t\t\t\tcontroller.close();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcontroller.enqueue(entry);\n\t\t},\n\t});\n}\n\n/**\n * Streams the central directory bytes of a zip file.\n *\n * @param source\n * @returns\n */\nasync function streamCentralDirectoryBytes(source: BytesSource) {\n\tconst chunkSize = CENTRAL_DIRECTORY_END_SCAN_CHUNK_SIZE;\n\tlet centralDirectory: Uint8Array = new Uint8Array();\n\n\tlet chunkStart = source.length;\n\tdo {\n\t\tchunkStart = Math.max(0, chunkStart - chunkSize);\n\t\tconst chunkEnd = Math.min(\n\t\t\tchunkStart + chunkSize - 1,\n\t\t\tsource.length - 1\n\t\t);\n\t\tconst bytes = await collectBytes(\n\t\t\tawait source.streamBytes(chunkStart, chunkEnd)\n\t\t);\n\t\tcentralDirectory = concatUint8Array(bytes!, centralDirectory);\n\n\t\t// Scan the buffer for the signature\n\t\tconst view = new DataView(bytes!.buffer);\n\t\tfor (let i = view.byteLength - 4; i >= 0; i--) {\n\t\t\tif (view.getUint32(i, true) !== SIGNATURE_CENTRAL_DIRECTORY_END) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Confirm we have enough data to read the offset and the\n\t\t\t// length of the central directory.\n\t\t\tconst centralDirectoryLengthAt = i + 12;\n\t\t\tconst centralDirectoryOffsetAt = centralDirectoryLengthAt + 4;\n\t\t\tif (centralDirectory.byteLength < centralDirectoryOffsetAt + 4) {\n\t\t\t\tthrow new Error('Central directory not found');\n\t\t\t}\n\n\t\t\t// Read where the central directory starts\n\t\t\tconst dirStart = view.getUint32(centralDirectoryOffsetAt, true);\n\t\t\tif (dirStart < chunkStart) {\n\t\t\t\t// We're missing some bytes, let's grab them\n\t\t\t\tconst missingBytes = await collectBytes(\n\t\t\t\t\tawait source.streamBytes(dirStart, chunkStart - 1)\n\t\t\t\t);\n\t\t\t\tcentralDirectory = concatUint8Array(\n\t\t\t\t\tmissingBytes!,\n\t\t\t\t\tcentralDirectory\n\t\t\t\t);\n\t\t\t} else if (dirStart > chunkStart) {\n\t\t\t\t// We've read too many bytes, let's trim them\n\t\t\t\tcentralDirectory = centralDirectory.slice(\n\t\t\t\t\tdirStart - chunkStart\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn new Blob([centralDirectory]).stream();\n\t\t}\n\t} while (chunkStart >= 0);\n\n\tthrow new Error('Central directory not found');\n}\n\n/**\n * Partitions files that are no further apart in the zip\n * archive than BATCH_DOWNLOAD_OF_FILES_IF_CLOSER_THAN.\n * It may download some extra files living within the gaps\n * between the partitions.\n */\nfunction partitionNearbyEntries() {\n\tlet lastFileEndsAt = 0;\n\tlet currentChunk: CentralDirectoryEntry[] = [];\n\treturn new TransformStream<CentralDirectoryEntry, CentralDirectoryEntry[]>({\n\t\ttransform(zipEntry, controller) {\n\t\t\t// Byte distance too large, flush and start a new chunk\n\t\t\tif (\n\t\t\t\tzipEntry.firstByteAt >\n\t\t\t\tlastFileEndsAt + BATCH_DOWNLOAD_OF_FILES_IF_CLOSER_THAN\n\t\t\t) {\n\t\t\t\tcontroller.enqueue(currentChunk);\n\t\t\t\tcurrentChunk = [];\n\t\t\t}\n\t\t\tlastFileEndsAt = zipEntry.lastByteAt;\n\t\t\tcurrentChunk.push(zipEntry);\n\t\t},\n\t\tflush(controller) {\n\t\t\tcontroller.enqueue(currentChunk);\n\t\t},\n\t});\n}\n\n/**\n * Fetches a chunk of files from the zip archive.\n *\n * If any extra files are present in the received\n * bytes stream, they are filtered out.\n */\nfunction fetchPartitionedEntries(\n\tsource: BytesSource\n): ReadableWritablePair<FileEntry, CentralDirectoryEntry[]> {\n\t/**\n\t * This function implements a ReadableStream and a WritableStream\n\t * instead of a TransformStream. This is intentional.\n\t *\n\t * In TransformStream, the `transform` function may return a\n\t * promise. The next call to `transform` will be delayed until\n\t * the promise resolves. This is a problem for us because we\n\t * want to issue many fetch() requests in parallel.\n\t *\n\t * The only way to do that seems to be creating separate ReadableStream\n\t * and WritableStream implementations.\n\t */\n\tlet isWritableClosed = false;\n\tlet requestsInProgress = 0;\n\tlet readableController: ReadableStreamDefaultController<FileEntry>;\n\tconst byteStreams: Array<\n\t\t[CentralDirectoryEntry[], ReadableStream<Uint8Array>]\n\t> = [];\n\t/**\n\t * Receives chunks of CentralDirectoryEntries, and fetches\n\t * the corresponding byte ranges from the remote zip file.\n\t */\n\tconst writable = new WritableStream<CentralDirectoryEntry[]>({\n\t\twrite(zipEntries, controller) {\n\t\t\tif (!zipEntries.length) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t++requestsInProgress;\n\t\t\t// If the write() method returns a promise, the next\n\t\t\t// call will be delayed until the promise resolves.\n\t\t\t// Let's not return the promise, then.\n\t\t\t// This will effectively issue many requests in parallel.\n\t\t\trequestChunkRange(source, zipEntries)\n\t\t\t\t.then((byteStream) => {\n\t\t\t\t\tbyteStreams.push([zipEntries, byteStream]);\n\t\t\t\t})\n\t\t\t\t.catch((e) => {\n\t\t\t\t\tcontroller.error(e);\n\t\t\t\t})\n\t\t\t\t.finally(() => {\n\t\t\t\t\t--requestsInProgress;\n\t\t\t\t});\n\t\t},\n\t\tabort() {\n\t\t\tisWritableClosed = true;\n\t\t\treadableController.close();\n\t\t},\n\t\tasync close() {\n\t\t\tisWritableClosed = true;\n\t\t},\n\t});\n\t/**\n\t * Decodes zipped bytes into FileEntry objects.\n\t */\n\tconst readable = new ReadableStream<FileEntry>({\n\t\tstart(controller) {\n\t\t\treadableController = controller;\n\t\t},\n\t\tasync pull(controller) {\n\t\t\twhile (true) {\n\t\t\t\tconst allChunksProcessed =\n\t\t\t\t\tisWritableClosed &&\n\t\t\t\t\t!byteStreams.length &&\n\t\t\t\t\trequestsInProgress === 0;\n\t\t\t\tif (allChunksProcessed) {\n\t\t\t\t\tcontroller.close();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// There's no bytes available, but the writable\n\t\t\t\t// stream is still open or there are still requests\n\t\t\t\t// in progress. Let's wait for more bytes.\n\t\t\t\tconst waitingForMoreBytes = !byteStreams.length;\n\t\t\t\tif (waitingForMoreBytes) {\n\t\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, 50));\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst [requestedPaths, stream] = byteStreams[0];\n\t\t\t\tconst file = await readFileEntry(stream);\n\t\t\t\t// The stream is exhausted, let's remove it from the queue\n\t\t\t\t// and try the next one.\n\t\t\t\tconst streamExhausted = !file;\n\t\t\t\tif (streamExhausted) {\n\t\t\t\t\tbyteStreams.shift();\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// There may be some extra files between the ones we're\n\t\t\t\t// interested in. Let's filter out any files that got\n\t\t\t\t// intertwined in the byte stream.\n\t\t\t\tconst isOneOfRequestedPaths = requestedPaths.find(\n\t\t\t\t\t(entry) => entry.path === file.path\n\t\t\t\t);\n\t\t\t\tif (!isOneOfRequestedPaths) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Finally! We've got a file we're interested in.\n\t\t\t\tcontroller.enqueue(file);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t},\n\t});\n\n\treturn {\n\t\treadable,\n\t\twritable,\n\t};\n}\n\n/**\n * Requests a chunk of bytes from the bytes source.\n *\n * @param source\n * @param zipEntries\n */\nasync function requestChunkRange(\n\tsource: BytesSource,\n\tzipEntries: CentralDirectoryEntry[]\n) {\n\tconst release = await fetchSemaphore.acquire();\n\ttry {\n\t\tconst lastZipEntry = zipEntries[zipEntries.length - 1];\n\t\tconst substream = await source.streamBytes(\n\t\t\tzipEntries[0].firstByteAt,\n\t\t\tlastZipEntry.lastByteAt\n\t\t);\n\t\treturn substream;\n\t} finally {\n\t\trelease();\n\t}\n}\n\n/**\n * Fetches the Content-Length header from a remote URL.\n */\nasync function fetchContentLength(url: string) {\n\treturn await fetch(url, { method: 'HEAD' })\n\t\t.then((response) => response.headers.get('Content-Length'))\n\t\t.then((contentLength) => {\n\t\t\tif (!contentLength) {\n\t\t\t\tthrow new Error('Content-Length header is missing');\n\t\t\t}\n\n\t\t\tconst parsedLength = parseInt(contentLength, 10);\n\t\t\tif (isNaN(parsedLength) || parsedLength < 0) {\n\t\t\t\tthrow new Error('Content-Length header is invalid');\n\t\t\t}\n\t\t\treturn parsedLength;\n\t\t});\n}\n\n/**\n * Private and experimental API: Range-based data sources.\n *\n * The idea is that if we can read arbitrary byte ranges from\n * a file, we can retrieve a specific subset of a zip file.\n */\ntype BytesSource = {\n\tlength: number;\n\tstreamBytes: (\n\t\tstart: number,\n\t\tend: number\n\t) => Promise<ReadableStream<Uint8Array>>;\n};\n\n/**\n * Creates a BytesSource enabling fetching ranges of bytes\n * from a remote URL.\n */\nasync function createFetchSource(\n\turl: string,\n\tcontentLength?: number\n): Promise<BytesSource> {\n\tif (contentLength === undefined) {\n\t\tcontentLength = await fetchContentLength(url);\n\t}\n\n\treturn {\n\t\tlength: contentLength,\n\t\tstreamBytes: async (from: number, to: number) =>\n\t\t\tawait fetch(url, {\n\t\t\t\theaders: {\n\t\t\t\t\t// The Range header is inclusive, so we need to subtract 1\n\t\t\t\t\tRange: `bytes=${from}-${to - 1}`,\n\t\t\t\t\t'Accept-Encoding': 'none',\n\t\t\t\t},\n\t\t\t}).then((response) => response.body!),\n\t};\n}\n","import type {\n\tCentralDirectoryEndEntry,\n\tCentralDirectoryEntry,\n\tFileHeader,\n} from './types';\nimport { COMPRESSION_DEFLATE, COMPRESSION_NONE } from './types';\nimport {\n\tSIGNATURE_CENTRAL_DIRECTORY_END,\n\tSIGNATURE_CENTRAL_DIRECTORY,\n\tSIGNATURE_FILE,\n} from './types';\nimport { iteratorToStream } from '../utils/iterator-to-stream';\nimport { collectBytes } from '../utils/collect-bytes';\n\n/**\n * Compresses the given files into a ZIP archive.\n *\n * @param files - An async or sync iterable of files to be compressed.\n * @returns A readable stream of the compressed ZIP archive as Uint8Array chunks.\n */\nexport function encodeZip(\n\tfiles: AsyncIterable<File> | Iterable<File>\n): ReadableStream<Uint8Array> {\n\treturn iteratorToStream(files).pipeThrough(encodeZipTransform());\n}\n\n/**\n * Encodes the files into a ZIP format.\n *\n * @returns A stream transforming File objects into zipped bytes.\n */\nfunction encodeZipTransform() {\n\tconst offsetToFileHeaderMap: Map<number, FileHeader> = new Map();\n\tlet writtenBytes = 0;\n\treturn new TransformStream<File, Uint8Array>({\n\t\tasync transform(file, controller) {\n\t\t\tconst entryBytes = new Uint8Array(await file.arrayBuffer());\n\t\t\t/**\n\t\t\t * We want to write raw deflate-compressed bytes into our\n\t\t\t * final ZIP file. CompressionStream supports \"deflate-raw\"\n\t\t\t * compression, but not on Node.js v20, it's available since v21.2.0.\n\t\t\t *\n\t\t\t * As a workaround, we use the \"gzip\" compression and add\n\t\t\t * the header and footer bytes. It works, because \"gzip\"\n\t\t\t * compression is the same as \"deflate\" compression plus\n\t\t\t * the header and the footer.\n\t\t\t *\n\t\t\t * The header is 10 bytes long:\n\t\t\t * - 2 magic bytes: 0x1f, 0x8b\n\t\t\t * - 1 compression method: 0x08 (deflate)\n\t\t\t * - 1 header flags\n\t\t\t * - 4 mtime: 0x00000000 (no timestamp)\n\t\t\t * - 1 compression flags\n\t\t\t * - 1 OS: 0x03 (Unix)\n\t\t\t *\n\t\t\t * The footer is 8 bytes long:\n\t\t\t * - 4 bytes for CRC32 of the uncompressed data\n\t\t\t * - 4 bytes for ISIZE (uncompressed size modulo 2^32)\n\t\t\t */\n\t\t\tlet compressed = (await collectBytes(\n\t\t\t\tnew Blob([entryBytes])\n\t\t\t\t\t.stream()\n\t\t\t\t\t.pipeThrough(new CompressionStream('gzip'))\n\t\t\t))!;\n\t\t\t// Grab the CRC32 hash from the footer.\n\t\t\tconst crcHash = new DataView(compressed.buffer).getUint32(\n\t\t\t\tcompressed.byteLength - 8,\n\t\t\t\ttrue\n\t\t\t);\n\t\t\t// Strip the header and the footer.\n\t\t\tcompressed = compressed.slice(10, compressed.byteLength - 8);\n\n\t\t\tconst encodedPath = new TextEncoder().encode(file.name);\n\t\t\tconst zipFileEntry: FileHeader = {\n\t\t\t\tsignature: SIGNATURE_FILE,\n\t\t\t\tversion: 2,\n\t\t\t\tgeneralPurpose: 0,\n\t\t\t\tcompressionMethod:\n\t\t\t\t\tfile.type === 'directory' || compressed.byteLength === 0\n\t\t\t\t\t\t? COMPRESSION_NONE\n\t\t\t\t\t\t: COMPRESSION_DEFLATE,\n\t\t\t\tlastModifiedTime: 0,\n\t\t\t\tlastModifiedDate: 0,\n\t\t\t\tcrc: crcHash,\n\t\t\t\tcompressedSize: compressed.byteLength,\n\t\t\t\tuncompressedSize: entryBytes.byteLength,\n\t\t\t\tpath: encodedPath,\n\t\t\t\textra: new Uint8Array(0),\n\t\t\t};\n\t\t\toffsetToFileHeaderMap.set(writtenBytes, zipFileEntry);\n\n\t\t\tconst headerBytes = encodeFileEntryHeader(zipFileEntry);\n\t\t\tcontroller.enqueue(headerBytes);\n\t\t\twrittenBytes += headerBytes.byteLength;\n\n\t\t\tcontroller.enqueue(compressed);\n\t\t\twrittenBytes += compressed.byteLength;\n\t\t},\n\t\tflush(controller) {\n\t\t\tconst centralDirectoryOffset = writtenBytes;\n\t\t\tlet centralDirectorySize = 0;\n\t\t\tfor (const [\n\t\t\t\tfileOffset,\n\t\t\t\theader,\n\t\t\t] of offsetToFileHeaderMap.entries()) {\n\t\t\t\tconst centralDirectoryEntry: Partial<CentralDirectoryEntry> = {\n\t\t\t\t\t...header,\n\t\t\t\t\tsignature: SIGNATURE_CENTRAL_DIRECTORY,\n\t\t\t\t\tfileComment: new Uint8Array(0),\n\t\t\t\t\tdiskNumber: 1,\n\t\t\t\t\tinternalAttributes: 0,\n\t\t\t\t\texternalAttributes: 0,\n\t\t\t\t\tfirstByteAt: fileOffset,\n\t\t\t\t};\n\t\t\t\tconst centralDirectoryEntryBytes = encodeCentralDirectoryEntry(\n\t\t\t\t\tcentralDirectoryEntry as CentralDirectoryEntry,\n\t\t\t\t\tfileOffset\n\t\t\t\t);\n\t\t\t\tcontroller.enqueue(centralDirectoryEntryBytes);\n\t\t\t\tcentralDirectorySize += centralDirectoryEntryBytes.byteLength;\n\t\t\t}\n\t\t\tconst centralDirectoryEnd: CentralDirectoryEndEntry = {\n\t\t\t\tsignature: SIGNATURE_CENTRAL_DIRECTORY_END,\n\t\t\t\tnumberOfDisks: 1,\n\t\t\t\tcentralDirectoryOffset,\n\t\t\t\tcentralDirectorySize,\n\t\t\t\tcentralDirectoryStartDisk: 1,\n\t\t\t\tnumberCentralDirectoryRecordsOnThisDisk:\n\t\t\t\t\toffsetToFileHeaderMap.size,\n\t\t\t\tnumberCentralDirectoryRecords: offsetToFileHeaderMap.size,\n\t\t\t\tcomment: new Uint8Array(0),\n\t\t\t};\n\t\t\tconst centralDirectoryEndBytes =\n\t\t\t\tencodeCentralDirectoryEnd(centralDirectoryEnd);\n\t\t\tcontroller.enqueue(centralDirectoryEndBytes);\n\t\t\toffsetToFileHeaderMap.clear();\n\t\t},\n\t});\n}\n\n/**\n * Encodes a file entry header as a Uint8Array.\n *\n * The array is structured as follows:\n *\n * ```\n * Offset\tBytes\tDescription\n * 0\t\t4\tLocal file header signature = 0x04034b50 (PK♥♦ or \"PK\\3\\4\")\n * 4\t\t2\tVersion needed to extract (minimum)\n * 6\t\t2\tGeneral purpose bit flag\n * 8\t\t2\tCompression method; e.g. none = 0, DEFLATE = 8 (or \"\\0x08\\0x00\")\n * 10\t\t2\tFile last modification time\n * 12\t\t2\tFile last modification date\n * 14\t\t4\tCRC-32 of uncompressed data\n * 18\t\t4\tCompressed size (or 0xffffffff for ZIP64)\n * 22\t\t4\tUncompressed size (or 0xffffffff for ZIP64)\n * 26\t\t2\tFile name length (n)\n * 28\t\t2\tExtra field length (m)\n * 30\t\tn\tFile name\n * 30+n\tm\tExtra field\n * ```\n */\nfunction encodeFileEntryHeader(entry: FileHeader) {\n\tconst buffer = new ArrayBuffer(\n\t\t30 + entry.path.byteLength + entry.extra.byteLength\n\t);\n\tconst view = new DataView(buffer);\n\tview.setUint32(0, entry.signature, true);\n\tview.setUint16(4, entry.version, true);\n\tview.setUint16(6, entry.generalPurpose, true);\n\tview.setUint16(8, entry.compressionMethod, true);\n\tview.setUint16(10, entry.lastModifiedDate, true);\n\tview.setUint16(12, entry.lastModifiedTime, true);\n\tview.setUint32(14, entry.crc, true);\n\tview.setUint32(18, entry.compressedSize, true);\n\tview.setUint32(22, entry.uncompressedSize, true);\n\tview.setUint16(26, entry.path.byteLength, true);\n\tview.setUint16(28, entry.extra.byteLength, true);\n\tconst uint8Header = new Uint8Array(buffer);\n\tuint8Header.set(entry.path, 30);\n\tuint8Header.set(entry.extra, 30 + entry.path.byteLength);\n\treturn uint8Header;\n}\n\n/**\n * Encodes a central directory entry as a Uint8Array.\n *\n * The central directory entry is structured as follows:\n *\n * ```\n * Offset Bytes Description\n * 0\t\t4\tCentral directory file header signature = 0x02014b50\n * 4\t\t2\tVersion made by\n * 6\t\t2\tVersion needed to extract (minimum)\n * 8\t\t2\tGeneral purpose bit flag\n * 10\t\t2\tCompression method\n * 12\t\t2\tFile last modification time\n * 14\t\t2\tFile last modification date\n * 16\t\t4\tCRC-32 of uncompressed data\n * 20\t\t4\tCompressed size (or 0xffffffff for ZIP64)\n * 24\t\t4\tUncompressed size (or 0xffffffff for ZIP64)\n * 28\t\t2\tFile name length (n)\n * 30\t\t2\tExtra field length (m)\n * 32\t\t2\tFile comment length (k)\n * 34\t\t2\tDisk number where file starts (or 0xffff for ZIP64)\n * 36\t\t2\tInternal file attributes\n * 38\t\t4\tExternal file attributes\n * 42\t\t4\tRelative offset of local file header (or 0xffffffff for ZIP64). This is the number of bytes between the start of the first disk on which the file occurs, and the start of the local file header. This allows software reading the central directory to locate the position of the file inside the ZIP file.\n * 46\t\tn\tFile name\n * 46+n\tm\tExtra field\n * 46+n+m\tk\tFile comment\n * ```\n */\nfunction encodeCentralDirectoryEntry(\n\tentry: CentralDirectoryEntry,\n\tfileEntryOffset: number\n) {\n\tconst buffer = new ArrayBuffer(\n\t\t46 + entry.path.byteLength + entry.extra.byteLength\n\t);\n\tconst view = new DataView(buffer);\n\tview.setUint32(0, entry.signature, true);\n\tview.setUint16(4, entry.versionCreated, true);\n\tview.setUint16(6, entry.versionNeeded, true);\n\tview.setUint16(8, entry.generalPurpose, true);\n\tview.setUint16(10, entry.compressionMethod, true);\n\tview.setUint16(12, entry.lastModifiedDate, true);\n\tview.setUint16(14, entry.lastModifiedTime, true);\n\tview.setUint32(16, entry.crc, true);\n\tview.setUint32(20, entry.compressedSize, true);\n\tview.setUint32(24, entry.uncompressedSize, true);\n\tview.setUint16(28, entry.path.byteLength, true);\n\tview.setUint16(30, entry.extra.byteLength, true);\n\tview.setUint16(32, entry.fileComment.byteLength, true);\n\tview.setUint16(34, entry.diskNumber, true);\n\tview.setUint16(36, entry.internalAttributes, true);\n\tview.setUint32(38, entry.externalAttributes, true);\n\tview.setUint32(42, fileEntryOffset, true);\n\tconst uint8Header = new Uint8Array(buffer);\n\tuint8Header.set(entry.path, 46);\n\tuint8Header.set(entry.extra, 46 + entry.path.byteLength);\n\treturn uint8Header;\n}\n\n/**\n * Encodes the end of central directory entry as a Uint8Array.\n *\n * The end of central directory entry is structured as follows:\n *\n * ```\n * Offset\tBytes\tDescription[33]\n * 0\t\t 4\t\tEnd of central directory signature = 0x06054b50\n * 4\t\t 2\t\tNumber of this disk (or 0xffff for ZIP64)\n * 6\t\t 2\t\tDisk where central directory starts (or 0xffff for ZIP64)\n * 8\t\t 2\t\tNumber of central directory records on this disk (or 0xffff for ZIP64)\n * 10\t\t 2\t\tTotal number of central directory records (or 0xffff for ZIP64)\n * 12\t\t 4\t\tSize of central directory (bytes) (or 0xffffffff for ZIP64)\n * 16\t\t 4\t\tOffset of start of central directory, relative to start of archive (or 0xffffffff for ZIP64)\n * 20\t\t 2\t\tComment length (n)\n * 22\t\t n\t\tComment\n * ```\n */\nfunction encodeCentralDirectoryEnd(entry: CentralDirectoryEndEntry) {\n\tconst buffer = new ArrayBuffer(22 + entry.comment.byteLength);\n\tconst view = new DataView(buffer);\n\tview.setUint32(0, entry.signature, true);\n\tview.setUint16(4, entry.numberOfDisks, true);\n\tview.setUint16(6, entry.centralDirectoryStartDisk, true);\n\tview.setUint16(8, entry.numberCentralDirectoryRecordsOnThisDisk, true);\n\tview.setUint16(10, entry.numberCentralDirectoryRecords, true);\n\tview.setUint32(12, entry.centralDirectorySize, true);\n\tview.setUint32(16, entry.centralDirectoryOffset, true);\n\tview.setUint16(20, entry.comment.byteLength, true);\n\tconst uint8Header = new Uint8Array(buffer);\n\tuint8Header.set(entry.comment, 22);\n\treturn uint8Header;\n}\n"],"names":["concatUint8Array","arrays","result","sum","array","offset","concatBytes","totalBytes","acc","chunk","controller","buffer","limitBytes","stream","bytes","reader","value","done","collectBytes","collectFile","fileName","iteratorToStream","iteratorOrIterable","iterator","StreamedFile","readableStream","name","options","FILE_HEADER_SIZE","SIGNATURE_FILE","SIGNATURE_CENTRAL_DIRECTORY","SIGNATURE_CENTRAL_DIRECTORY_END","COMPRESSION_NONE","COMPRESSION_DEFLATE","filterStream","predicate","prependBytes","isPrepended","appendBytes","decodeZip","streamZippedFileEntries","zipEntry","file","DEFAULT_PREDICATE","entry","nextZipEntry","signature","readFileEntry","readCentralDirectoryEntry","readEndCentralDirectoryEntry","skipSignature","data","pathLength","extraLength","endsWithSlash","bodyStream","header","footer","footerView","fileCommentLength","centralDirectory","path","endOfDirectory","commentLength","CENTRAL_DIRECTORY_END_SCAN_CHUNK_SIZE","BATCH_DOWNLOAD_OF_FILES_IF_CLOSER_THAN","PREFER_RANGES_IF_FILE_LARGER_THAN","fetchSemaphore","Semaphore","decodeRemoteZip","url","response","contentLength","fetchContentLength","peekStream","responseStream","peekReader","peekBytes","peekDone","source","createFetchSource","streamCentralDirectoryEntries","partitionNearbyEntries","fetchPartitionedEntries","centralDirectoryStream","streamCentralDirectoryBytes","chunkSize","chunkStart","chunkEnd","view","i","centralDirectoryOffsetAt","dirStart","missingBytes","lastFileEndsAt","currentChunk","isWritableClosed","requestsInProgress","readableController","byteStreams","writable","zipEntries","requestChunkRange","byteStream","e","resolve","requestedPaths","release","lastZipEntry","parsedLength","from","to","encodeZip","files","encodeZipTransform","offsetToFileHeaderMap","writtenBytes","entryBytes","compressed","crcHash","encodedPath","zipFileEntry","headerBytes","encodeFileEntryHeader","centralDirectoryOffset","centralDirectorySize","fileOffset","centralDirectoryEntry","centralDirectoryEntryBytes","encodeCentralDirectoryEntry","centralDirectoryEnd","centralDirectoryEndBytes","encodeCentralDirectoryEnd","uint8Header","fileEntryOffset"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../packages/php-wasm/stream-compression/src/utils/concat-uint8-array.ts","../../../../packages/php-wasm/stream-compression/src/utils/concat-bytes.ts","../../../../packages/php-wasm/stream-compression/src/utils/limit-bytes.ts","../../../../packages/php-wasm/stream-compression/src/utils/collect-bytes.ts","../../../../packages/php-wasm/stream-compression/src/utils/collect-file.ts","../../../../packages/php-wasm/stream-compression/src/utils/iterator-to-stream.ts","../../../../packages/php-wasm/stream-compression/src/utils/streamed-file.ts","../../../../packages/php-wasm/stream-compression/src/utils/iterable-stream-polyfill.ts","../../../../packages/php-wasm/stream-compression/src/zip/types.ts","../../../../packages/php-wasm/stream-compression/src/utils/filter-stream.ts","../../../../packages/php-wasm/stream-compression/src/utils/prepend-bytes.ts","../../../../packages/php-wasm/stream-compression/src/utils/append-bytes.ts","../../../../packages/php-wasm/stream-compression/src/zip/decode-zip.ts","../../../../packages/php-wasm/stream-compression/src/zip/decode-remote-zip.ts","../../../../packages/php-wasm/stream-compression/src/zip/encode-zip.ts"],"sourcesContent":["/**\n * Concatenates multiple Uint8Arrays into a single Uint8Array.\n *\n * @param arrays The arrays to concatenate.\n * @returns A new Uint8Array containing the contents of all the arrays.\n */\nexport function concatUint8Array(...arrays: Uint8Array[]) {\n\tconst result = new Uint8Array(\n\t\tarrays.reduce((sum, array) => sum + array.length, 0)\n\t);\n\tlet offset = 0;\n\tfor (const array of arrays) {\n\t\tresult.set(array, offset);\n\t\toffset += array.length;\n\t}\n\treturn result;\n}\n","import { concatUint8Array } from './concat-uint8-array';\n\n/**\n * Concatenates the contents of the stream into a single Uint8Array.\n *\n * @param totalBytes Optional. The number of bytes to concatenate. Used to\n * \t\t\t\t pre-allocate the buffer. If not provided, the buffer will\n * \t\t\t\t be dynamically resized as needed.\n * @returns A stream that will emit a single UInt8Array entry before closing.\n */\nexport function concatBytes(totalBytes?: number) {\n\tif (totalBytes === undefined) {\n\t\tlet acc = new Uint8Array();\n\t\treturn new TransformStream<Uint8Array, Uint8Array>({\n\t\t\ttransform(chunk) {\n\t\t\t\tacc = concatUint8Array(acc, chunk);\n\t\t\t},\n\n\t\t\tflush(controller) {\n\t\t\t\tcontroller.enqueue(acc);\n\t\t\t},\n\t\t});\n\t} else {\n\t\tconst buffer = new ArrayBuffer(totalBytes || 0);\n\t\tlet offset = 0;\n\t\treturn new TransformStream<Uint8Array, Uint8Array>({\n\t\t\ttransform(chunk) {\n\t\t\t\tconst view = new Uint8Array(buffer);\n\t\t\t\tview.set(chunk, offset);\n\t\t\t\toffset += chunk.byteLength;\n\t\t\t},\n\n\t\t\tflush(controller) {\n\t\t\t\tcontroller.enqueue(new Uint8Array(buffer));\n\t\t\t},\n\t\t});\n\t}\n}\n","/**\n * Limit the number of bytes read from a stream.\n *\n * @param stream The stream to limit.\n * @param bytes The number of bytes to read from the stream.\n * @returns A new stream that will read at most `bytes` bytes from `stream`.\n */\nexport function limitBytes(stream: ReadableStream<Uint8Array>, bytes: number) {\n\tif (bytes === 0) {\n\t\treturn new ReadableStream({\n\t\t\tstart(controller) {\n\t\t\t\tcontroller.close();\n\t\t\t},\n\t\t});\n\t}\n\tconst reader = stream.getReader({ mode: 'byob' });\n\tlet offset = 0;\n\treturn new ReadableStream({\n\t\tasync pull(controller) {\n\t\t\tconst { value, done } = await reader.read(\n\t\t\t\tnew Uint8Array(bytes - offset)\n\t\t\t);\n\t\t\tif (done) {\n\t\t\t\treader.releaseLock();\n\t\t\t\tcontroller.close();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\toffset += value.length;\n\t\t\tcontroller.enqueue(value);\n\n\t\t\tif (offset >= bytes) {\n\t\t\t\treader.releaseLock();\n\t\t\t\tcontroller.close();\n\t\t\t}\n\t\t},\n\t\tcancel() {\n\t\t\treader.cancel();\n\t\t},\n\t});\n}\n","import { concatBytes } from './concat-bytes';\nimport { limitBytes } from './limit-bytes';\n\n/**\n * Collects the contents of the entire stream into a single Uint8Array.\n *\n * @param stream The stream to collect.\n * @param bytes Optional. The number of bytes to read from the stream.\n * @returns The string contents of the stream.\n */\nexport async function collectBytes(\n\tstream: ReadableStream<Uint8Array>,\n\tbytes?: number\n) {\n\tif (bytes !== undefined) {\n\t\tstream = limitBytes(stream, bytes);\n\t}\n\n\treturn await stream\n\t\t.pipeThrough(concatBytes(bytes))\n\t\t.getReader()\n\t\t.read()\n\t\t.then(({ value }) => value!);\n}\n","import { collectBytes } from './collect-bytes';\n\n/**\n * Collects the contents of the entire stream into a single File object.\n *\n * @param stream The stream to collect.\n * @param fileName The name of the file\n * @returns The string contents of the stream.\n */\nexport async function collectFile(\n\tfileName: string,\n\tstream: ReadableStream<Uint8Array>\n) {\n\t// @TODO: use StreamingFile\n\treturn new File([await collectBytes(stream)], fileName);\n}\n","import type { IterableReadableStream } from './iterable-stream-polyfill';\n\n/**\n * Converts an iterator or iterable to a stream.\n *\n * @param iteratorOrIterable The iterator or iterable to convert.\n * @returns A stream that will yield the values from the iterator or iterable.\n */\nexport function iteratorToStream<T>(\n\titeratorOrIterable:\n\t\t| AsyncIterator<T>\n\t\t| Iterator<T>\n\t\t| AsyncIterable<T>\n\t\t| Iterable<T>\n) {\n\tif (iteratorOrIterable instanceof ReadableStream) {\n\t\treturn iteratorOrIterable as IterableReadableStream<T>;\n\t}\n\n\tlet iterator: AsyncIterator<T> | Iterator<T>;\n\tif (Symbol.asyncIterator in iteratorOrIterable) {\n\t\titerator = iteratorOrIterable[Symbol.asyncIterator]();\n\t} else if (Symbol.iterator in iteratorOrIterable) {\n\t\titerator = iteratorOrIterable[Symbol.iterator]();\n\t} else {\n\t\titerator = iteratorOrIterable;\n\t}\n\n\treturn new ReadableStream<T>({\n\t\tasync pull(controller) {\n\t\t\tconst { done, value } = await iterator.next();\n\t\t\tif (done) {\n\t\t\t\tcontroller.close();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcontroller.enqueue(value);\n\t\t},\n\t}) as IterableReadableStream<T>;\n}\n","import { collectBytes } from './collect-bytes';\n\n/**\n * Represents a file that is streamed and not fully\n * loaded into memory.\n */\nexport class StreamedFile extends File {\n\treadonly filesize: number | undefined;\n\n\tprivate readableStream: ReadableStream<Uint8Array>;\n\n\t/**\n\t * Creates a new StreamedFile instance.\n\t *\n\t * @param readableStream The readable stream containing the file data.\n\t * @param name The name of the file.\n\t * @param options An object containing options such as the MIME type and file size.\n\t */\n\tconstructor(\n\t\treadableStream: ReadableStream<Uint8Array>,\n\t\tname: string,\n\t\toptions?: { type?: string; filesize?: number }\n\t) {\n\t\tsuper([], name, { type: options?.type });\n\t\tthis.readableStream = readableStream;\n\t\tthis.filesize = options?.filesize;\n\t}\n\n\t/**\n\t * Overrides the slice() method of the File class.\n\t *\n\t * @returns A Blob representing a portion of the file.\n\t */\n\toverride slice(): Blob {\n\t\tthrow new Error('slice() is not possible on a StreamedFile');\n\t}\n\n\t/**\n\t * Returns the readable stream associated with the file.\n\t *\n\t * @returns The readable stream.\n\t */\n\toverride stream() {\n\t\treturn this.readableStream;\n\t}\n\n\t/**\n\t * Loads the file data into memory and then returns it as a string.\n\t *\n\t * @returns File data as text.\n\t */\n\toverride async text() {\n\t\treturn new TextDecoder().decode(await this.arrayBuffer());\n\t}\n\n\t/**\n\t * Loads the file data into memory and then returns it as an ArrayBuffer.\n\t *\n\t * @returns File data as an ArrayBuffer.\n\t */\n\toverride async arrayBuffer() {\n\t\treturn await collectBytes(this.stream());\n\t}\n}\n","/**\n * Polyfill for ReadableStream[Symbol.asyncIterator]\n * This enables the use of for-await-of loops with ReadableStreams\n *\n * @example\n * ```ts\n * for await (const entry of stream) {\n * \t // ...\n * }\n * ```\n */\n// @ts-ignore\nif (!ReadableStream.prototype[Symbol.asyncIterator]) {\n\t// @ts-ignore\n\tReadableStream.prototype[Symbol.asyncIterator] = async function* () {\n\t\tconst reader = this.getReader();\n\t\ttry {\n\t\t\twhile (true) {\n\t\t\t\tconst { done, value } = await reader.read();\n\t\t\t\tif (done) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tyield value;\n\t\t\t}\n\t\t} finally {\n\t\t\treader.releaseLock();\n\t\t}\n\t};\n\t// @ts-ignore\n\tReadableStream.prototype.iterate =\n\t\t// @ts-ignore\n\t\tReadableStream.prototype[Symbol.asyncIterator];\n}\n\nexport type IterableReadableStream<R> = ReadableStream<R> & AsyncIterable<R>;\n","export const FILE_HEADER_SIZE = 32;\nexport const SIGNATURE_FILE = 67324752 as const;\nexport const SIGNATURE_CENTRAL_DIRECTORY = 33639248 as const;\nexport const SIGNATURE_CENTRAL_DIRECTORY_END = 101010256 as const;\nexport const SIGNATURE_DATA_DESCRIPTOR = 134695760 as const;\n\nexport const COMPRESSION_NONE = 0 as const;\nexport const COMPRESSION_DEFLATE = 8 as const;\nexport type CompressionMethod =\n\t| typeof COMPRESSION_NONE\n\t| typeof COMPRESSION_DEFLATE;\n\nexport type ZipEntry =\n\t| FileEntry\n\t| CentralDirectoryEntry\n\t| CentralDirectoryEndEntry;\n\n/**\n * Data of the file entry header encoded in a \".zip\" file.\n */\nexport interface FileHeader {\n\tsignature: typeof SIGNATURE_FILE;\n\tversion: number;\n\tgeneralPurpose: number;\n\tcompressionMethod: CompressionMethod;\n\tlastModifiedTime: number;\n\tlastModifiedDate: number;\n\tcrc: number;\n\tcompressedSize: number;\n\tuncompressedSize: number;\n\tpath: Uint8Array;\n\textra: Uint8Array;\n}\nexport interface FileEntry extends FileHeader {\n\tisDirectory: boolean;\n\tbytes: Uint8Array;\n}\n\n/**\n * Data of the central directory entry encoded in a \".zip\" file.\n */\nexport interface CentralDirectoryEntry {\n\tsignature: typeof SIGNATURE_CENTRAL_DIRECTORY;\n\tversionCreated: number;\n\tversionNeeded: number;\n\tgeneralPurpose: number;\n\tcompressionMethod: CompressionMethod;\n\tlastModifiedTime: number;\n\tlastModifiedDate: number;\n\tcrc: number;\n\tcompressedSize: number;\n\tuncompressedSize: number;\n\tdiskNumber: number;\n\tinternalAttributes: number;\n\texternalAttributes: number;\n\tfirstByteAt: number;\n\tlastByteAt: number;\n\tpath: Uint8Array;\n\textra: Uint8Array;\n\tfileComment: Uint8Array;\n\tisDirectory: boolean;\n}\n\n/**\n * Data of the central directory end entry encoded in a \".zip\" file.\n */\nexport interface CentralDirectoryEndEntry {\n\tsignature: typeof SIGNATURE_CENTRAL_DIRECTORY_END;\n\tnumberOfDisks: number;\n\tcentralDirectoryStartDisk: number;\n\tnumberCentralDirectoryRecordsOnThisDisk: number;\n\tnumberCentralDirectoryRecords: number;\n\tcentralDirectorySize: number;\n\tcentralDirectoryOffset: number;\n\tcomment: Uint8Array;\n}\n","/**\n * Filter the stream based on a predicate.\n *\n * @param predicate The predicate to filter the stream with.\n * @returns A new stream that will only contain chunks that pass the predicate.\n */\nexport function filterStream<T>(predicate: (chunk: T) => boolean) {\n\treturn new TransformStream<T, T>({\n\t\ttransform(chunk, controller) {\n\t\t\tif (predicate(chunk)) {\n\t\t\t\tcontroller.enqueue(chunk);\n\t\t\t}\n\t\t},\n\t});\n}\n","/**\n * Prepend bytes to a stream.\n *\n * @param bytes The bytes to prepend.\n * @returns A transform stream that will prepend the specified bytes.\n */\nexport function prependBytes(bytes: Uint8Array) {\n\tlet isPrepended = false;\n\treturn new TransformStream<Uint8Array, Uint8Array>({\n\t\tasync transform(chunk, controller) {\n\t\t\tif (!isPrepended) {\n\t\t\t\tisPrepended = true;\n\t\t\t\tcontroller.enqueue(bytes);\n\t\t\t}\n\t\t\tcontroller.enqueue(chunk);\n\t\t},\n\t});\n}\n","/**\n * Appends bytes to a stream.\n *\n * @param bytes The bytes to append.\n * @returns A transform stream that will append the specified bytes.\n */\nexport function appendBytes(bytes: Uint8Array) {\n\treturn new TransformStream<Uint8Array, Uint8Array>({\n\t\tasync transform(chunk, controller) {\n\t\t\tcontroller.enqueue(chunk);\n\t\t},\n\t\tasync flush(controller) {\n\t\t\tcontroller.enqueue(bytes);\n\t\t},\n\t});\n}\n","/**\n * Reads files from a stream of zip file bytes.\n */\nimport type { IterableReadableStream } from '../utils/iterable-stream-polyfill';\n\nimport type { CompressionMethod } from './types';\nimport {\n\tSIGNATURE_FILE,\n\tSIGNATURE_CENTRAL_DIRECTORY,\n\tSIGNATURE_CENTRAL_DIRECTORY_END,\n\tFILE_HEADER_SIZE,\n\tCOMPRESSION_DEFLATE,\n} from './types';\nimport type {\n\tCentralDirectoryEntry,\n\tFileEntry,\n\tZipEntry,\n\tCentralDirectoryEndEntry,\n} from './types';\nimport { filterStream } from '../utils/filter-stream';\nimport { collectBytes } from '../utils/collect-bytes';\nimport { limitBytes } from '../utils/limit-bytes';\nimport { concatBytes } from '../utils/concat-bytes';\nimport { prependBytes } from '../utils/prepend-bytes';\nimport { appendBytes } from '../utils/append-bytes';\n\n/**\n * Unzips a stream of zip file bytes.\n *\n * @param stream A stream of zip file bytes.\n * @param predicate Optional. A function that returns true if the file should be downloaded.\n * @returns An iterable stream of File objects.\n */\nexport function decodeZip(\n\tstream: ReadableStream<Uint8Array>,\n\tpredicate?: () => boolean\n) {\n\treturn streamZippedFileEntries(stream, predicate).pipeThrough(\n\t\tnew TransformStream<FileEntry, File>({\n\t\t\tasync transform(zipEntry, controller) {\n\t\t\t\tconst file = new File(\n\t\t\t\t\t[zipEntry.bytes],\n\t\t\t\t\tnew TextDecoder().decode(zipEntry.path),\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: zipEntry.isDirectory ? 'directory' : undefined,\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t\tcontroller.enqueue(file);\n\t\t\t},\n\t\t})\n\t) as IterableReadableStream<File>;\n}\n\nconst DEFAULT_PREDICATE = () => true;\n\n/**\n * Parses a stream of zipped bytes into FileEntry informations.\n *\n * @param stream A stream of zip file bytes.\n * @param predicate Optional. A function that returns true if the file should be downloaded.\n * @returns An iterable stream of FileEntry objects.\n */\nexport function streamZippedFileEntries(\n\tstream: ReadableStream<Uint8Array>,\n\tpredicate: (\n\t\tdirEntry: CentralDirectoryEntry | FileEntry\n\t) => boolean = DEFAULT_PREDICATE\n) {\n\tconst entriesStream = new ReadableStream<ZipEntry>({\n\t\tasync pull(controller) {\n\t\t\tconst entry = await nextZipEntry(stream);\n\t\t\tif (!entry) {\n\t\t\t\tcontroller.close();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcontroller.enqueue(entry);\n\t\t},\n\t}) as IterableReadableStream<ZipEntry>;\n\n\treturn entriesStream\n\t\t.pipeThrough(\n\t\t\tfilterStream(({ signature }) => signature === SIGNATURE_FILE)\n\t\t)\n\t\t.pipeThrough(\n\t\t\tfilterStream(predicate as any)\n\t\t) as IterableReadableStream<FileEntry>;\n}\n\n/**\n * Reads the next zip entry from a stream of zip file bytes.\n *\n * @param stream A stream of zip file bytes.\n * @returns A FileEntry object.\n */\nasync function nextZipEntry(stream: ReadableStream<Uint8Array>) {\n\tconst sigData = new DataView((await collectBytes(stream, 4))!.buffer);\n\tconst signature = sigData.getUint32(0, true);\n\tif (signature === SIGNATURE_FILE) {\n\t\treturn await readFileEntry(stream, true);\n\t} else if (signature === SIGNATURE_CENTRAL_DIRECTORY) {\n\t\treturn await readCentralDirectoryEntry(stream, true);\n\t} else if (signature === SIGNATURE_CENTRAL_DIRECTORY_END) {\n\t\treturn await readEndCentralDirectoryEntry(stream, true);\n\t}\n\treturn null;\n}\n\n/**\n * Reads a file entry from a zip file.\n *\n * The file entry is structured as follows:\n *\n * ```\n * Offset\tBytes\tDescription\n * 0\t\t4\tLocal file header signature = 0x04034b50 (PK♥♦ or \"PK\\3\\4\")\n * 4\t\t2\tVersion needed to extract (minimum)\n * 6\t\t2\tGeneral purpose bit flag\n * 8\t\t2\tCompression method; e.g. none = 0, DEFLATE = 8 (or \"\\0x08\\0x00\")\n * 10\t\t2\tFile last modification time\n * 12\t\t2\tFile last modification date\n * 14\t\t4\tCRC-32 of uncompressed data\n * 18\t\t4\tCompressed size (or 0xffffffff for ZIP64)\n * 22\t\t4\tUncompressed size (or 0xffffffff for ZIP64)\n * 26\t\t2\tFile name length (n)\n * 28\t\t2\tExtra field length (m)\n * 30\t\tn\tFile name\n * 30+n\tm\tExtra field\n * ```\n *\n * @param stream\n * @param skipSignature Do not consume the signature from the stream.\n * @returns\n */\nexport async function readFileEntry(\n\tstream: ReadableStream<Uint8Array>,\n\tskipSignature = false\n): Promise<FileEntry | null> {\n\tif (!skipSignature) {\n\t\tconst sigData = new DataView((await collectBytes(stream, 4))!.buffer);\n\t\tconst signature = sigData.getUint32(0, true);\n\t\tif (signature !== SIGNATURE_FILE) {\n\t\t\treturn null;\n\t\t}\n\t}\n\tconst data = new DataView((await collectBytes(stream, 26))!.buffer);\n\tconst pathLength = data.getUint16(22, true);\n\tconst extraLength = data.getUint16(24, true);\n\tconst entry: Partial<FileEntry> = {\n\t\tsignature: SIGNATURE_FILE,\n\t\tversion: data.getUint32(0, true),\n\t\tgeneralPurpose: data.getUint16(2, true),\n\t\tcompressionMethod: data.getUint16(4, true) as CompressionMethod,\n\t\tlastModifiedTime: data.getUint16(6, true),\n\t\tlastModifiedDate: data.getUint16(8, true),\n\t\tcrc: data.getUint32(10, true),\n\t\tcompressedSize: data.getUint32(14, true),\n\t\tuncompressedSize: data.getUint32(18, true),\n\t};\n\n\tentry['path'] = await collectBytes(stream, pathLength);\n\tentry['isDirectory'] = endsWithSlash(entry.path!);\n\tentry['extra'] = await collectBytes(stream, extraLength);\n\n\t// Make sure we consume the body stream or else\n\t// we'll start reading the next file at the wrong\n\t// offset.\n\t// @TODO: Expose the body stream instead of reading it all\n\t// eagerly. Ensure the next iteration exhausts\n\t// the last body stream before moving on.\n\n\tlet bodyStream = limitBytes(stream, entry['compressedSize']!);\n\n\tif (entry['compressionMethod'] === COMPRESSION_DEFLATE) {\n\t\t/**\n\t\t * We want to write raw deflate-compressed bytes into our\n\t\t * final ZIP file. CompressionStream supports \"deflate-raw\"\n\t\t * compression, but not on Node.js v20, it's available since v21.2.0.\n\t\t *\n\t\t * As a workaround, we use the \"gzip\" compression and add\n\t\t * the header and footer bytes. It works, because \"gzip\"\n\t\t * compression is the same as \"deflate\" compression plus\n\t\t * the header and the footer.\n\t\t *\n\t\t * The header is 10 bytes long:\n\t\t * - 2 magic bytes: 0x1f, 0x8b\n\t\t * - 1 compression method: 0x08 (deflate)\n\t\t * - 1 header flags\n\t\t * - 4 mtime: 0x00000000 (no timestamp)\n\t\t * - 1 compression flags\n\t\t * - 1 OS: 0x03 (Unix)\n\t\t *\n\t\t * The footer is 8 bytes long:\n\t\t * - 4 bytes for CRC32 of the uncompressed data\n\t\t * - 4 bytes for ISIZE (uncompressed size modulo 2^32)\n\t\t */\n\t\tconst header = new Uint8Array(10);\n\t\theader.set([0x1f, 0x8b, 0x08]);\n\n\t\tconst footer = new Uint8Array(8);\n\t\tconst footerView = new DataView(footer.buffer);\n\t\tfooterView.setUint32(0, entry.crc!, true);\n\t\tfooterView.setUint32(4, entry.uncompressedSize! % 2 ** 32, true);\n\t\tbodyStream = bodyStream\n\t\t\t.pipeThrough(prependBytes(header))\n\t\t\t.pipeThrough(appendBytes(footer))\n\t\t\t.pipeThrough(new DecompressionStream('gzip'));\n\t}\n\tentry['bytes'] = await bodyStream\n\t\t.pipeThrough(concatBytes(entry['uncompressedSize']))\n\t\t.getReader()\n\t\t.read()\n\t\t.then(({ value }) => value!);\n\treturn entry as FileEntry;\n}\n\n/**\n * Reads a central directory entry from a zip file.\n *\n * The central directory entry is structured as follows:\n *\n * ```\n * Offset Bytes Description\n * 0\t\t4\tCentral directory file header signature = 0x02014b50\n * 4\t\t2\tVersion made by\n * 6\t\t2\tVersion needed to extract (minimum)\n * 8\t\t2\tGeneral purpose bit flag\n * 10\t\t2\tCompression method\n * 12\t\t2\tFile last modification time\n * 14\t\t2\tFile last modification date\n * 16\t\t4\tCRC-32 of uncompressed data\n * 20\t\t4\tCompressed size (or 0xffffffff for ZIP64)\n * 24\t\t4\tUncompressed size (or 0xffffffff for ZIP64)\n * 28\t\t2\tFile name length (n)\n * 30\t\t2\tExtra field length (m)\n * 32\t\t2\tFile comment length (k)\n * 34\t\t2\tDisk number where file starts (or 0xffff for ZIP64)\n * 36\t\t2\tInternal file attributes\n * 38\t\t4\tExternal file attributes\n * 42\t\t4\tRelative offset of local file header (or 0xffffffff for ZIP64). This is the number of bytes between the start of the first disk on which the file occurs, and the start of the local file header. This allows software reading the central directory to locate the position of the file inside the ZIP file.\n * 46\t\tn\tFile name\n * 46+n\tm\tExtra field\n * 46+n+m\tk\tFile comment\n * ```\n *\n * @param stream\n * @param skipSignature\n * @returns\n */\nexport async function readCentralDirectoryEntry(\n\tstream: ReadableStream<Uint8Array>,\n\tskipSignature = false\n): Promise<CentralDirectoryEntry | null> {\n\tif (!skipSignature) {\n\t\tconst sigData = new DataView((await collectBytes(stream, 4))!.buffer);\n\t\tconst signature = sigData.getUint32(0, true);\n\t\tif (signature !== SIGNATURE_CENTRAL_DIRECTORY) {\n\t\t\treturn null;\n\t\t}\n\t}\n\tconst data = new DataView((await collectBytes(stream, 42))!.buffer);\n\tconst pathLength = data.getUint16(24, true);\n\tconst extraLength = data.getUint16(26, true);\n\tconst fileCommentLength = data.getUint16(28, true);\n\tconst centralDirectory: Partial<CentralDirectoryEntry> = {\n\t\tsignature: SIGNATURE_CENTRAL_DIRECTORY,\n\t\tversionCreated: data.getUint16(0, true),\n\t\tversionNeeded: data.getUint16(2, true),\n\t\tgeneralPurpose: data.getUint16(4, true),\n\t\tcompressionMethod: data.getUint16(6, true) as CompressionMethod,\n\t\tlastModifiedTime: data.getUint16(8, true),\n\t\tlastModifiedDate: data.getUint16(10, true),\n\t\tcrc: data.getUint32(12, true),\n\t\tcompressedSize: data.getUint32(16, true),\n\t\tuncompressedSize: data.getUint32(20, true),\n\t\tdiskNumber: data.getUint16(30, true),\n\t\tinternalAttributes: data.getUint16(32, true),\n\t\texternalAttributes: data.getUint32(34, true),\n\t\tfirstByteAt: data.getUint32(38, true),\n\t};\n\tcentralDirectory['lastByteAt'] =\n\t\tcentralDirectory.firstByteAt! +\n\t\tFILE_HEADER_SIZE +\n\t\tpathLength +\n\t\tfileCommentLength +\n\t\textraLength! +\n\t\tcentralDirectory.compressedSize! -\n\t\t1;\n\n\tcentralDirectory['path'] = await collectBytes(stream, pathLength);\n\tcentralDirectory['isDirectory'] = endsWithSlash(centralDirectory.path!);\n\tcentralDirectory['extra'] = await collectBytes(stream, extraLength);\n\tcentralDirectory['fileComment'] = await collectBytes(\n\t\tstream,\n\t\tfileCommentLength\n\t);\n\treturn centralDirectory as CentralDirectoryEntry;\n}\n\nfunction endsWithSlash(path: Uint8Array) {\n\treturn path[path.byteLength - 1] == '/'.charCodeAt(0);\n}\n\n/**\n * Reads the end of central directory entry from a zip file.\n *\n * The end of central directory entry is structured as follows:\n *\n * ```\n * Offset\tBytes\tDescription[33]\n * 0\t\t 4\t\tEnd of central directory signature = 0x06054b50\n * 4\t\t 2\t\tNumber of this disk (or 0xffff for ZIP64)\n * 6\t\t 2\t\tDisk where central directory starts (or 0xffff for ZIP64)\n * 8\t\t 2\t\tNumber of central directory records on this disk (or 0xffff for ZIP64)\n * 10\t\t 2\t\tTotal number of central directory records (or 0xffff for ZIP64)\n * 12\t\t 4\t\tSize of central directory (bytes) (or 0xffffffff for ZIP64)\n * 16\t\t 4\t\tOffset of start of central directory, relative to start of archive (or 0xffffffff for ZIP64)\n * 20\t\t 2\t\tComment length (n)\n * 22\t\t n\t\tComment\n * ```\n *\n * @param stream\n * @param skipSignature\n * @returns\n */\nasync function readEndCentralDirectoryEntry(\n\tstream: ReadableStream<Uint8Array>,\n\tskipSignature = false\n) {\n\tif (!skipSignature) {\n\t\tconst sigData = new DataView((await collectBytes(stream, 4))!.buffer);\n\t\tconst signature = sigData.getUint32(0, true);\n\t\tif (signature !== SIGNATURE_CENTRAL_DIRECTORY_END) {\n\t\t\treturn null;\n\t\t}\n\t}\n\tconst data = new DataView((await collectBytes(stream, 18))!.buffer);\n\tconst endOfDirectory: Partial<CentralDirectoryEndEntry> = {\n\t\tsignature: SIGNATURE_CENTRAL_DIRECTORY_END,\n\t\tnumberOfDisks: data.getUint16(0, true),\n\t\tcentralDirectoryStartDisk: data.getUint16(2, true),\n\t\tnumberCentralDirectoryRecordsOnThisDisk: data.getUint16(4, true),\n\t\tnumberCentralDirectoryRecords: data.getUint16(6, true),\n\t\tcentralDirectorySize: data.getUint32(8, true),\n\t\tcentralDirectoryOffset: data.getUint32(12, true),\n\t};\n\tconst commentLength = data.getUint16(16, true);\n\tendOfDirectory['comment'] = await collectBytes(stream, commentLength);\n\treturn endOfDirectory as CentralDirectoryEndEntry;\n}\n","import { Semaphore } from '@php-wasm/util';\nimport { filterStream } from '../utils/filter-stream';\nimport { concatUint8Array } from '../utils/concat-uint8-array';\nimport { collectBytes } from '../utils/collect-bytes';\nimport {\n\treadCentralDirectoryEntry,\n\treadFileEntry,\n\tdecodeZip,\n} from './decode-zip';\nimport type { CentralDirectoryEntry, FileEntry } from './types';\nimport { SIGNATURE_CENTRAL_DIRECTORY_END } from './types';\nimport type { IterableReadableStream } from '../utils/iterable-stream-polyfill';\n\nconst CENTRAL_DIRECTORY_END_SCAN_CHUNK_SIZE = 110 * 1024;\nconst BATCH_DOWNLOAD_OF_FILES_IF_CLOSER_THAN = 10 * 1024;\nconst PREFER_RANGES_IF_FILE_LARGER_THAN = 1024 * 1024 * 1;\nconst fetchSemaphore = new Semaphore({ concurrency: 10 });\n\nconst DEFAULT_PREDICATE = () => true;\n\n/**\n * Streams the contents of a remote zip file.\n *\n * If the zip is large and the predicate is filtering the zip contents,\n * only the matching files will be downloaded using the Range header\n * (if supported by the server).\n *\n * @param url The URL of the zip file.\n * @param predicate Optional. A function that returns true if the file should be downloaded.\n * @returns A stream of zip entries.\n */\nexport async function decodeRemoteZip(\n\turl: string,\n\tpredicate: (\n\t\tdirEntry: CentralDirectoryEntry | FileEntry\n\t) => boolean = DEFAULT_PREDICATE\n) {\n\tif (predicate === DEFAULT_PREDICATE) {\n\t\t// If we're not filtering the zip contents, let's just\n\t\t// grab the entire zip.\n\t\tconst response = await fetch(url);\n\t\treturn decodeZip(response.body!);\n\t}\n\n\tconst contentLength = await fetchContentLength(url);\n\tif (contentLength <= PREFER_RANGES_IF_FILE_LARGER_THAN) {\n\t\t// If the zip is small enough, let's just grab it.\n\t\tconst response = await fetch(url);\n\t\treturn decodeZip(response.body!);\n\t}\n\n\t// Ensure ranges query support:\n\t// Fetch one byte\n\tconst response = await fetch(url, {\n\t\theaders: {\n\t\t\t// 0-0 looks weird, doesn't it?\n\t\t\t// The Range header is inclusive so it's actually\n\t\t\t// a valid header asking for the first byte.\n\t\t\tRange: 'bytes=0-0',\n\t\t\t'Accept-Encoding': 'none',\n\t\t},\n\t});\n\n\t// Fork the stream so that we can reuse it in case\n\t// the Range header is unsupported and we're now streaming\n\t// the entire file\n\tconst [peekStream, responseStream] = response.body!.tee();\n\n\t// Read from the forked stream and close it.\n\tconst peekReader = peekStream.getReader();\n\tconst { value: peekBytes } = await peekReader.read();\n\tconst { done: peekDone } = await peekReader.read();\n\tpeekReader.releaseLock();\n\tpeekStream.cancel();\n\n\t// Confirm our Range query worked as intended:\n\tconst rangesSupported = peekBytes?.length === 1 && peekDone;\n\tif (!rangesSupported) {\n\t\t// Uh-oh, we're actually streaming the entire file.\n\t\t// Let's reuse the forked stream as our response stream.\n\t\treturn decodeZip(responseStream);\n\t}\n\n\t// We're good, let's clean up the other branch of the response stream.\n\tresponseStream.cancel();\n\tconst source = await createFetchSource(url, contentLength);\n\treturn streamCentralDirectoryEntries(source)\n\t\t.pipeThrough(filterStream(predicate))\n\t\t.pipeThrough(partitionNearbyEntries())\n\t\t.pipeThrough(\n\t\t\tfetchPartitionedEntries(source)\n\t\t) as IterableReadableStream<FileEntry>;\n}\n\n/**\n * Streams the central directory entries of a zip file.\n *\n * @param source\n * @returns\n */\nfunction streamCentralDirectoryEntries(source: BytesSource) {\n\tlet centralDirectoryStream: ReadableStream<Uint8Array>;\n\n\treturn new ReadableStream<CentralDirectoryEntry>({\n\t\tasync start() {\n\t\t\tcentralDirectoryStream = await streamCentralDirectoryBytes(source);\n\t\t},\n\t\tasync pull(controller) {\n\t\t\tconst entry = await readCentralDirectoryEntry(\n\t\t\t\tcentralDirectoryStream\n\t\t\t);\n\t\t\tif (!entry) {\n\t\t\t\tcontroller.close();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcontroller.enqueue(entry);\n\t\t},\n\t});\n}\n\n/**\n * Streams the central directory bytes of a zip file.\n *\n * @param source\n * @returns\n */\nasync function streamCentralDirectoryBytes(source: BytesSource) {\n\tconst chunkSize = CENTRAL_DIRECTORY_END_SCAN_CHUNK_SIZE;\n\tlet centralDirectory: Uint8Array = new Uint8Array();\n\n\tlet chunkStart = source.length;\n\tdo {\n\t\tchunkStart = Math.max(0, chunkStart - chunkSize);\n\t\tconst chunkEnd = Math.min(\n\t\t\tchunkStart + chunkSize - 1,\n\t\t\tsource.length - 1\n\t\t);\n\t\tconst bytes = await collectBytes(\n\t\t\tawait source.streamBytes(chunkStart, chunkEnd)\n\t\t);\n\t\tcentralDirectory = concatUint8Array(bytes!, centralDirectory);\n\n\t\t// Scan the buffer for the signature\n\t\tconst view = new DataView(bytes!.buffer);\n\t\tfor (let i = view.byteLength - 4; i >= 0; i--) {\n\t\t\tif (view.getUint32(i, true) !== SIGNATURE_CENTRAL_DIRECTORY_END) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Confirm we have enough data to read the offset and the\n\t\t\t// length of the central directory.\n\t\t\tconst centralDirectoryLengthAt = i + 12;\n\t\t\tconst centralDirectoryOffsetAt = centralDirectoryLengthAt + 4;\n\t\t\tif (centralDirectory.byteLength < centralDirectoryOffsetAt + 4) {\n\t\t\t\tthrow new Error('Central directory not found');\n\t\t\t}\n\n\t\t\t// Read where the central directory starts\n\t\t\tconst dirStart = view.getUint32(centralDirectoryOffsetAt, true);\n\t\t\tif (dirStart < chunkStart) {\n\t\t\t\t// We're missing some bytes, let's grab them\n\t\t\t\tconst missingBytes = await collectBytes(\n\t\t\t\t\tawait source.streamBytes(dirStart, chunkStart - 1)\n\t\t\t\t);\n\t\t\t\tcentralDirectory = concatUint8Array(\n\t\t\t\t\tmissingBytes!,\n\t\t\t\t\tcentralDirectory\n\t\t\t\t);\n\t\t\t} else if (dirStart > chunkStart) {\n\t\t\t\t// We've read too many bytes, let's trim them\n\t\t\t\tcentralDirectory = centralDirectory.slice(\n\t\t\t\t\tdirStart - chunkStart\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn new Blob([centralDirectory]).stream();\n\t\t}\n\t} while (chunkStart >= 0);\n\n\tthrow new Error('Central directory not found');\n}\n\n/**\n * Partitions files that are no further apart in the zip\n * archive than BATCH_DOWNLOAD_OF_FILES_IF_CLOSER_THAN.\n * It may download some extra files living within the gaps\n * between the partitions.\n */\nfunction partitionNearbyEntries() {\n\tlet lastFileEndsAt = 0;\n\tlet currentChunk: CentralDirectoryEntry[] = [];\n\treturn new TransformStream<CentralDirectoryEntry, CentralDirectoryEntry[]>({\n\t\ttransform(zipEntry, controller) {\n\t\t\t// Byte distance too large, flush and start a new chunk\n\t\t\tif (\n\t\t\t\tzipEntry.firstByteAt >\n\t\t\t\tlastFileEndsAt + BATCH_DOWNLOAD_OF_FILES_IF_CLOSER_THAN\n\t\t\t) {\n\t\t\t\tcontroller.enqueue(currentChunk);\n\t\t\t\tcurrentChunk = [];\n\t\t\t}\n\t\t\tlastFileEndsAt = zipEntry.lastByteAt;\n\t\t\tcurrentChunk.push(zipEntry);\n\t\t},\n\t\tflush(controller) {\n\t\t\tcontroller.enqueue(currentChunk);\n\t\t},\n\t});\n}\n\n/**\n * Fetches a chunk of files from the zip archive.\n *\n * If any extra files are present in the received\n * bytes stream, they are filtered out.\n */\nfunction fetchPartitionedEntries(\n\tsource: BytesSource\n): ReadableWritablePair<FileEntry, CentralDirectoryEntry[]> {\n\t/**\n\t * This function implements a ReadableStream and a WritableStream\n\t * instead of a TransformStream. This is intentional.\n\t *\n\t * In TransformStream, the `transform` function may return a\n\t * promise. The next call to `transform` will be delayed until\n\t * the promise resolves. This is a problem for us because we\n\t * want to issue many fetch() requests in parallel.\n\t *\n\t * The only way to do that seems to be creating separate ReadableStream\n\t * and WritableStream implementations.\n\t */\n\tlet isWritableClosed = false;\n\tlet requestsInProgress = 0;\n\tlet readableController: ReadableStreamDefaultController<FileEntry>;\n\tconst byteStreams: Array<\n\t\t[CentralDirectoryEntry[], ReadableStream<Uint8Array>]\n\t> = [];\n\t/**\n\t * Receives chunks of CentralDirectoryEntries, and fetches\n\t * the corresponding byte ranges from the remote zip file.\n\t */\n\tconst writable = new WritableStream<CentralDirectoryEntry[]>({\n\t\twrite(zipEntries, controller) {\n\t\t\tif (!zipEntries.length) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t++requestsInProgress;\n\t\t\t// If the write() method returns a promise, the next\n\t\t\t// call will be delayed until the promise resolves.\n\t\t\t// Let's not return the promise, then.\n\t\t\t// This will effectively issue many requests in parallel.\n\t\t\trequestChunkRange(source, zipEntries)\n\t\t\t\t.then((byteStream) => {\n\t\t\t\t\tbyteStreams.push([zipEntries, byteStream]);\n\t\t\t\t})\n\t\t\t\t.catch((e) => {\n\t\t\t\t\tcontroller.error(e);\n\t\t\t\t})\n\t\t\t\t.finally(() => {\n\t\t\t\t\t--requestsInProgress;\n\t\t\t\t});\n\t\t},\n\t\tabort() {\n\t\t\tisWritableClosed = true;\n\t\t\treadableController.close();\n\t\t},\n\t\tasync close() {\n\t\t\tisWritableClosed = true;\n\t\t},\n\t});\n\t/**\n\t * Decodes zipped bytes into FileEntry objects.\n\t */\n\tconst readable = new ReadableStream<FileEntry>({\n\t\tstart(controller) {\n\t\t\treadableController = controller;\n\t\t},\n\t\tasync pull(controller) {\n\t\t\twhile (true) {\n\t\t\t\tconst allChunksProcessed =\n\t\t\t\t\tisWritableClosed &&\n\t\t\t\t\t!byteStreams.length &&\n\t\t\t\t\trequestsInProgress === 0;\n\t\t\t\tif (allChunksProcessed) {\n\t\t\t\t\tcontroller.close();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// There's no bytes available, but the writable\n\t\t\t\t// stream is still open or there are still requests\n\t\t\t\t// in progress. Let's wait for more bytes.\n\t\t\t\tconst waitingForMoreBytes = !byteStreams.length;\n\t\t\t\tif (waitingForMoreBytes) {\n\t\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, 50));\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst [requestedPaths, stream] = byteStreams[0];\n\t\t\t\tconst file = await readFileEntry(stream);\n\t\t\t\t// The stream is exhausted, let's remove it from the queue\n\t\t\t\t// and try the next one.\n\t\t\t\tconst streamExhausted = !file;\n\t\t\t\tif (streamExhausted) {\n\t\t\t\t\tbyteStreams.shift();\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// There may be some extra files between the ones we're\n\t\t\t\t// interested in. Let's filter out any files that got\n\t\t\t\t// intertwined in the byte stream.\n\t\t\t\tconst isOneOfRequestedPaths = requestedPaths.find(\n\t\t\t\t\t(entry) => entry.path === file.path\n\t\t\t\t);\n\t\t\t\tif (!isOneOfRequestedPaths) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Finally! We've got a file we're interested in.\n\t\t\t\tcontroller.enqueue(file);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t},\n\t});\n\n\treturn {\n\t\treadable,\n\t\twritable,\n\t};\n}\n\n/**\n * Requests a chunk of bytes from the bytes source.\n *\n * @param source\n * @param zipEntries\n */\nasync function requestChunkRange(\n\tsource: BytesSource,\n\tzipEntries: CentralDirectoryEntry[]\n) {\n\tconst release = await fetchSemaphore.acquire();\n\ttry {\n\t\tconst lastZipEntry = zipEntries[zipEntries.length - 1];\n\t\tconst substream = await source.streamBytes(\n\t\t\tzipEntries[0].firstByteAt,\n\t\t\tlastZipEntry.lastByteAt\n\t\t);\n\t\treturn substream;\n\t} finally {\n\t\trelease();\n\t}\n}\n\n/**\n * Fetches the Content-Length header from a remote URL.\n */\nasync function fetchContentLength(url: string) {\n\treturn await fetch(url, { method: 'HEAD' })\n\t\t.then((response) => response.headers.get('Content-Length'))\n\t\t.then((contentLength) => {\n\t\t\tif (!contentLength) {\n\t\t\t\tthrow new Error('Content-Length header is missing');\n\t\t\t}\n\n\t\t\tconst parsedLength = parseInt(contentLength, 10);\n\t\t\tif (isNaN(parsedLength) || parsedLength < 0) {\n\t\t\t\tthrow new Error('Content-Length header is invalid');\n\t\t\t}\n\t\t\treturn parsedLength;\n\t\t});\n}\n\n/**\n * Private and experimental API: Range-based data sources.\n *\n * The idea is that if we can read arbitrary byte ranges from\n * a file, we can retrieve a specific subset of a zip file.\n */\ntype BytesSource = {\n\tlength: number;\n\tstreamBytes: (\n\t\tstart: number,\n\t\tend: number\n\t) => Promise<ReadableStream<Uint8Array>>;\n};\n\n/**\n * Creates a BytesSource enabling fetching ranges of bytes\n * from a remote URL.\n */\nasync function createFetchSource(\n\turl: string,\n\tcontentLength?: number\n): Promise<BytesSource> {\n\tif (contentLength === undefined) {\n\t\tcontentLength = await fetchContentLength(url);\n\t}\n\n\treturn {\n\t\tlength: contentLength,\n\t\tstreamBytes: async (from: number, to: number) =>\n\t\t\tawait fetch(url, {\n\t\t\t\theaders: {\n\t\t\t\t\t// The Range header is inclusive, so we need to subtract 1\n\t\t\t\t\tRange: `bytes=${from}-${to - 1}`,\n\t\t\t\t\t'Accept-Encoding': 'none',\n\t\t\t\t},\n\t\t\t}).then((response) => response.body!),\n\t};\n}\n","import type {\n\tCentralDirectoryEndEntry,\n\tCentralDirectoryEntry,\n\tFileHeader,\n} from './types';\nimport { COMPRESSION_DEFLATE, COMPRESSION_NONE } from './types';\nimport {\n\tSIGNATURE_CENTRAL_DIRECTORY_END,\n\tSIGNATURE_CENTRAL_DIRECTORY,\n\tSIGNATURE_FILE,\n} from './types';\nimport { iteratorToStream } from '../utils/iterator-to-stream';\nimport { collectBytes } from '../utils/collect-bytes';\n\n/**\n * Compresses the given files into a ZIP archive.\n *\n * @param files - An async or sync iterable of files to be compressed.\n * @returns A readable stream of the compressed ZIP archive as Uint8Array chunks.\n */\nexport function encodeZip(\n\tfiles: AsyncIterable<File> | Iterable<File>\n): ReadableStream<Uint8Array> {\n\treturn iteratorToStream(files).pipeThrough(encodeZipTransform());\n}\n\n/**\n * Encodes the files into a ZIP format.\n *\n * @returns A stream transforming File objects into zipped bytes.\n */\nfunction encodeZipTransform() {\n\tconst offsetToFileHeaderMap: Map<number, FileHeader> = new Map();\n\tlet writtenBytes = 0;\n\treturn new TransformStream<File, Uint8Array>({\n\t\tasync transform(file, controller) {\n\t\t\tconst entryBytes = new Uint8Array(await file.arrayBuffer());\n\t\t\t/**\n\t\t\t * We want to write raw deflate-compressed bytes into our\n\t\t\t * final ZIP file. CompressionStream supports \"deflate-raw\"\n\t\t\t * compression, but not on Node.js v20, it's available since v21.2.0.\n\t\t\t *\n\t\t\t * As a workaround, we use the \"gzip\" compression and add\n\t\t\t * the header and footer bytes. It works, because \"gzip\"\n\t\t\t * compression is the same as \"deflate\" compression plus\n\t\t\t * the header and the footer.\n\t\t\t *\n\t\t\t * The header is 10 bytes long:\n\t\t\t * - 2 magic bytes: 0x1f, 0x8b\n\t\t\t * - 1 compression method: 0x08 (deflate)\n\t\t\t * - 1 header flags\n\t\t\t * - 4 mtime: 0x00000000 (no timestamp)\n\t\t\t * - 1 compression flags\n\t\t\t * - 1 OS: 0x03 (Unix)\n\t\t\t *\n\t\t\t * The footer is 8 bytes long:\n\t\t\t * - 4 bytes for CRC32 of the uncompressed data\n\t\t\t * - 4 bytes for ISIZE (uncompressed size modulo 2^32)\n\t\t\t */\n\t\t\tlet compressed = (await collectBytes(\n\t\t\t\tnew Blob([entryBytes])\n\t\t\t\t\t.stream()\n\t\t\t\t\t.pipeThrough(new CompressionStream('gzip'))\n\t\t\t))!;\n\t\t\t// Grab the CRC32 hash from the footer.\n\t\t\tconst crcHash = new DataView(compressed.buffer).getUint32(\n\t\t\t\tcompressed.byteLength - 8,\n\t\t\t\ttrue\n\t\t\t);\n\t\t\t// Strip the header and the footer.\n\t\t\tcompressed = compressed.slice(10, compressed.byteLength - 8);\n\n\t\t\tconst encodedPath = new TextEncoder().encode(file.name);\n\t\t\tconst zipFileEntry: FileHeader = {\n\t\t\t\tsignature: SIGNATURE_FILE,\n\t\t\t\tversion: 2,\n\t\t\t\tgeneralPurpose: 0,\n\t\t\t\tcompressionMethod:\n\t\t\t\t\tfile.type === 'directory' || compressed.byteLength === 0\n\t\t\t\t\t\t? COMPRESSION_NONE\n\t\t\t\t\t\t: COMPRESSION_DEFLATE,\n\t\t\t\tlastModifiedTime: 0,\n\t\t\t\tlastModifiedDate: 0,\n\t\t\t\tcrc: crcHash,\n\t\t\t\tcompressedSize: compressed.byteLength,\n\t\t\t\tuncompressedSize: entryBytes.byteLength,\n\t\t\t\tpath: encodedPath,\n\t\t\t\textra: new Uint8Array(0),\n\t\t\t};\n\t\t\toffsetToFileHeaderMap.set(writtenBytes, zipFileEntry);\n\n\t\t\tconst headerBytes = encodeFileEntryHeader(zipFileEntry);\n\t\t\tcontroller.enqueue(headerBytes);\n\t\t\twrittenBytes += headerBytes.byteLength;\n\n\t\t\tcontroller.enqueue(compressed);\n\t\t\twrittenBytes += compressed.byteLength;\n\t\t},\n\t\tflush(controller) {\n\t\t\tconst centralDirectoryOffset = writtenBytes;\n\t\t\tlet centralDirectorySize = 0;\n\t\t\tfor (const [\n\t\t\t\tfileOffset,\n\t\t\t\theader,\n\t\t\t] of offsetToFileHeaderMap.entries()) {\n\t\t\t\tconst centralDirectoryEntry: Partial<CentralDirectoryEntry> = {\n\t\t\t\t\t...header,\n\t\t\t\t\tsignature: SIGNATURE_CENTRAL_DIRECTORY,\n\t\t\t\t\tfileComment: new Uint8Array(0),\n\t\t\t\t\tdiskNumber: 1,\n\t\t\t\t\tinternalAttributes: 0,\n\t\t\t\t\texternalAttributes: 0,\n\t\t\t\t\tfirstByteAt: fileOffset,\n\t\t\t\t};\n\t\t\t\tconst centralDirectoryEntryBytes = encodeCentralDirectoryEntry(\n\t\t\t\t\tcentralDirectoryEntry as CentralDirectoryEntry,\n\t\t\t\t\tfileOffset\n\t\t\t\t);\n\t\t\t\tcontroller.enqueue(centralDirectoryEntryBytes);\n\t\t\t\tcentralDirectorySize += centralDirectoryEntryBytes.byteLength;\n\t\t\t}\n\t\t\tconst centralDirectoryEnd: CentralDirectoryEndEntry = {\n\t\t\t\tsignature: SIGNATURE_CENTRAL_DIRECTORY_END,\n\t\t\t\tnumberOfDisks: 1,\n\t\t\t\tcentralDirectoryOffset,\n\t\t\t\tcentralDirectorySize,\n\t\t\t\tcentralDirectoryStartDisk: 1,\n\t\t\t\tnumberCentralDirectoryRecordsOnThisDisk:\n\t\t\t\t\toffsetToFileHeaderMap.size,\n\t\t\t\tnumberCentralDirectoryRecords: offsetToFileHeaderMap.size,\n\t\t\t\tcomment: new Uint8Array(0),\n\t\t\t};\n\t\t\tconst centralDirectoryEndBytes =\n\t\t\t\tencodeCentralDirectoryEnd(centralDirectoryEnd);\n\t\t\tcontroller.enqueue(centralDirectoryEndBytes);\n\t\t\toffsetToFileHeaderMap.clear();\n\t\t},\n\t});\n}\n\n/**\n * Encodes a file entry header as a Uint8Array.\n *\n * The array is structured as follows:\n *\n * ```\n * Offset\tBytes\tDescription\n * 0\t\t4\tLocal file header signature = 0x04034b50 (PK♥♦ or \"PK\\3\\4\")\n * 4\t\t2\tVersion needed to extract (minimum)\n * 6\t\t2\tGeneral purpose bit flag\n * 8\t\t2\tCompression method; e.g. none = 0, DEFLATE = 8 (or \"\\0x08\\0x00\")\n * 10\t\t2\tFile last modification time\n * 12\t\t2\tFile last modification date\n * 14\t\t4\tCRC-32 of uncompressed data\n * 18\t\t4\tCompressed size (or 0xffffffff for ZIP64)\n * 22\t\t4\tUncompressed size (or 0xffffffff for ZIP64)\n * 26\t\t2\tFile name length (n)\n * 28\t\t2\tExtra field length (m)\n * 30\t\tn\tFile name\n * 30+n\tm\tExtra field\n * ```\n */\nfunction encodeFileEntryHeader(entry: FileHeader) {\n\tconst buffer = new ArrayBuffer(\n\t\t30 + entry.path.byteLength + entry.extra.byteLength\n\t);\n\tconst view = new DataView(buffer);\n\tview.setUint32(0, entry.signature, true);\n\tview.setUint16(4, entry.version, true);\n\tview.setUint16(6, entry.generalPurpose, true);\n\tview.setUint16(8, entry.compressionMethod, true);\n\tview.setUint16(10, entry.lastModifiedDate, true);\n\tview.setUint16(12, entry.lastModifiedTime, true);\n\tview.setUint32(14, entry.crc, true);\n\tview.setUint32(18, entry.compressedSize, true);\n\tview.setUint32(22, entry.uncompressedSize, true);\n\tview.setUint16(26, entry.path.byteLength, true);\n\tview.setUint16(28, entry.extra.byteLength, true);\n\tconst uint8Header = new Uint8Array(buffer);\n\tuint8Header.set(entry.path, 30);\n\tuint8Header.set(entry.extra, 30 + entry.path.byteLength);\n\treturn uint8Header;\n}\n\n/**\n * Encodes a central directory entry as a Uint8Array.\n *\n * The central directory entry is structured as follows:\n *\n * ```\n * Offset Bytes Description\n * 0\t\t4\tCentral directory file header signature = 0x02014b50\n * 4\t\t2\tVersion made by\n * 6\t\t2\tVersion needed to extract (minimum)\n * 8\t\t2\tGeneral purpose bit flag\n * 10\t\t2\tCompression method\n * 12\t\t2\tFile last modification time\n * 14\t\t2\tFile last modification date\n * 16\t\t4\tCRC-32 of uncompressed data\n * 20\t\t4\tCompressed size (or 0xffffffff for ZIP64)\n * 24\t\t4\tUncompressed size (or 0xffffffff for ZIP64)\n * 28\t\t2\tFile name length (n)\n * 30\t\t2\tExtra field length (m)\n * 32\t\t2\tFile comment length (k)\n * 34\t\t2\tDisk number where file starts (or 0xffff for ZIP64)\n * 36\t\t2\tInternal file attributes\n * 38\t\t4\tExternal file attributes\n * 42\t\t4\tRelative offset of local file header (or 0xffffffff for ZIP64). This is the number of bytes between the start of the first disk on which the file occurs, and the start of the local file header. This allows software reading the central directory to locate the position of the file inside the ZIP file.\n * 46\t\tn\tFile name\n * 46+n\tm\tExtra field\n * 46+n+m\tk\tFile comment\n * ```\n */\nfunction encodeCentralDirectoryEntry(\n\tentry: CentralDirectoryEntry,\n\tfileEntryOffset: number\n) {\n\tconst buffer = new ArrayBuffer(\n\t\t46 + entry.path.byteLength + entry.extra.byteLength\n\t);\n\tconst view = new DataView(buffer);\n\tview.setUint32(0, entry.signature, true);\n\tview.setUint16(4, entry.versionCreated, true);\n\tview.setUint16(6, entry.versionNeeded, true);\n\tview.setUint16(8, entry.generalPurpose, true);\n\tview.setUint16(10, entry.compressionMethod, true);\n\tview.setUint16(12, entry.lastModifiedDate, true);\n\tview.setUint16(14, entry.lastModifiedTime, true);\n\tview.setUint32(16, entry.crc, true);\n\tview.setUint32(20, entry.compressedSize, true);\n\tview.setUint32(24, entry.uncompressedSize, true);\n\tview.setUint16(28, entry.path.byteLength, true);\n\tview.setUint16(30, entry.extra.byteLength, true);\n\tview.setUint16(32, entry.fileComment.byteLength, true);\n\tview.setUint16(34, entry.diskNumber, true);\n\tview.setUint16(36, entry.internalAttributes, true);\n\tview.setUint32(38, entry.externalAttributes, true);\n\tview.setUint32(42, fileEntryOffset, true);\n\tconst uint8Header = new Uint8Array(buffer);\n\tuint8Header.set(entry.path, 46);\n\tuint8Header.set(entry.extra, 46 + entry.path.byteLength);\n\treturn uint8Header;\n}\n\n/**\n * Encodes the end of central directory entry as a Uint8Array.\n *\n * The end of central directory entry is structured as follows:\n *\n * ```\n * Offset\tBytes\tDescription[33]\n * 0\t\t 4\t\tEnd of central directory signature = 0x06054b50\n * 4\t\t 2\t\tNumber of this disk (or 0xffff for ZIP64)\n * 6\t\t 2\t\tDisk where central directory starts (or 0xffff for ZIP64)\n * 8\t\t 2\t\tNumber of central directory records on this disk (or 0xffff for ZIP64)\n * 10\t\t 2\t\tTotal number of central directory records (or 0xffff for ZIP64)\n * 12\t\t 4\t\tSize of central directory (bytes) (or 0xffffffff for ZIP64)\n * 16\t\t 4\t\tOffset of start of central directory, relative to start of archive (or 0xffffffff for ZIP64)\n * 20\t\t 2\t\tComment length (n)\n * 22\t\t n\t\tComment\n * ```\n */\nfunction encodeCentralDirectoryEnd(entry: CentralDirectoryEndEntry) {\n\tconst buffer = new ArrayBuffer(22 + entry.comment.byteLength);\n\tconst view = new DataView(buffer);\n\tview.setUint32(0, entry.signature, true);\n\tview.setUint16(4, entry.numberOfDisks, true);\n\tview.setUint16(6, entry.centralDirectoryStartDisk, true);\n\tview.setUint16(8, entry.numberCentralDirectoryRecordsOnThisDisk, true);\n\tview.setUint16(10, entry.numberCentralDirectoryRecords, true);\n\tview.setUint32(12, entry.centralDirectorySize, true);\n\tview.setUint32(16, entry.centralDirectoryOffset, true);\n\tview.setUint16(20, entry.comment.byteLength, true);\n\tconst uint8Header = new Uint8Array(buffer);\n\tuint8Header.set(entry.comment, 22);\n\treturn uint8Header;\n}\n"],"names":["concatUint8Array","arrays","result","sum","array","offset","concatBytes","totalBytes","acc","chunk","controller","buffer","limitBytes","stream","bytes","reader","value","done","collectBytes","collectFile","fileName","iteratorToStream","iteratorOrIterable","iterator","StreamedFile","readableStream","name","options","FILE_HEADER_SIZE","SIGNATURE_FILE","SIGNATURE_CENTRAL_DIRECTORY","SIGNATURE_CENTRAL_DIRECTORY_END","COMPRESSION_NONE","COMPRESSION_DEFLATE","filterStream","predicate","prependBytes","isPrepended","appendBytes","decodeZip","streamZippedFileEntries","zipEntry","file","DEFAULT_PREDICATE","entry","nextZipEntry","signature","readFileEntry","readCentralDirectoryEntry","readEndCentralDirectoryEntry","skipSignature","data","pathLength","extraLength","endsWithSlash","bodyStream","header","footer","footerView","fileCommentLength","centralDirectory","path","endOfDirectory","commentLength","CENTRAL_DIRECTORY_END_SCAN_CHUNK_SIZE","BATCH_DOWNLOAD_OF_FILES_IF_CLOSER_THAN","PREFER_RANGES_IF_FILE_LARGER_THAN","fetchSemaphore","Semaphore","decodeRemoteZip","url","response","contentLength","fetchContentLength","peekStream","responseStream","peekReader","peekBytes","peekDone","source","createFetchSource","streamCentralDirectoryEntries","partitionNearbyEntries","fetchPartitionedEntries","centralDirectoryStream","streamCentralDirectoryBytes","chunkSize","chunkStart","chunkEnd","view","i","centralDirectoryOffsetAt","dirStart","missingBytes","lastFileEndsAt","currentChunk","isWritableClosed","requestsInProgress","readableController","byteStreams","writable","zipEntries","requestChunkRange","byteStream","e","resolve","requestedPaths","release","lastZipEntry","parsedLength","from","to","encodeZip","files","encodeZipTransform","offsetToFileHeaderMap","writtenBytes","entryBytes","compressed","crcHash","encodedPath","zipFileEntry","headerBytes","encodeFileEntryHeader","centralDirectoryOffset","centralDirectorySize","fileOffset","centralDirectoryEntry","centralDirectoryEntryBytes","encodeCentralDirectoryEntry","centralDirectoryEnd","centralDirectoryEndBytes","encodeCentralDirectoryEnd","uint8Header","fileEntryOffset"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@php-wasm/stream-compression",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.16",
|
|
4
4
|
"description": "Stream-based compression bindings.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
},
|
|
30
30
|
"license": "GPL-2.0-or-later",
|
|
31
31
|
"type": "module",
|
|
32
|
-
"gitHead": "
|
|
32
|
+
"gitHead": "1f96a559fda4946f36f8543a2715cee411a5c8f2",
|
|
33
33
|
"packageManager": "npm@10.9.2",
|
|
34
34
|
"overrides": {
|
|
35
35
|
"rollup": "^4.34.6",
|
|
@@ -42,8 +42,8 @@
|
|
|
42
42
|
"form-data": "^4.0.4"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@php-wasm/node-polyfills": "3.0.
|
|
46
|
-
"@php-wasm/util": "3.0.
|
|
45
|
+
"@php-wasm/node-polyfills": "3.0.16",
|
|
46
|
+
"@php-wasm/util": "3.0.16"
|
|
47
47
|
},
|
|
48
48
|
"optionalDependencies": {
|
|
49
49
|
"fs-ext": "2.1.1"
|