streaming zip archiver/extractor jsr.io/@mary/zip
typescript jsr
at trunk 1.4 kB view raw
1/** 2 * @module 3 * This module contains Node.js-specific functions 4 */ 5 6import type { FileHandle } from 'node:fs/promises'; 7 8import type { Reader } from './types.ts'; 9 10/** 11 * creates a reader from a Node.js' FileHandle 12 * @param handle the file handle to read from 13 * @returns a reader for the file 14 */ 15export const fromFileHandle = async (handle: FileHandle): Promise<Reader> => { 16 const totalLength = (await handle.stat()).size; 17 18 return { 19 length: totalLength, 20 // deno-lint-ignore require-await 21 async read(offset: number, length?: number): Promise<ReadableStream<Uint8Array<ArrayBuffer>>> { 22 let remaining = length !== undefined ? length : totalLength - offset; 23 24 return new ReadableStream<Uint8Array<ArrayBuffer>>({ 25 type: 'bytes', 26 async pull(controller) { 27 const size = Math.min(controller.desiredSize!, remaining); 28 29 const buffer = new Uint8Array(size); 30 const { bytesRead } = await handle.read(buffer, 0, size, offset); 31 32 if (bytesRead === 0) { 33 // end of file 34 controller.close(); 35 return; 36 } 37 38 if (bytesRead < size) { 39 // partial read, slice the buffer 40 controller.enqueue(buffer.subarray(0, bytesRead)); 41 } else { 42 controller.enqueue(buffer); 43 } 44 45 remaining -= bytesRead; 46 offset += bytesRead; 47 48 if (remaining <= 0) { 49 controller.close(); 50 return; 51 } 52 }, 53 }, { highWaterMark: 64 * 1024 }); 54 }, 55 }; 56};