@php-wasm/stream-compression 3.0.21 → 3.0.30

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 CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require("@php-wasm/node-polyfills");const F=require("@php-wasm/util");function U(...e){const r=new Uint8Array(e.reduce((n,a)=>n+a.length,0));let t=0;for(const n of e)r.set(n,t),t+=n.length;return r}function S(e){if(e===void 0){let r=new Uint8Array;return new TransformStream({transform(t){r=U(r,t)},flush(t){t.enqueue(r)}})}else{const r=new ArrayBuffer(e||0);let t=0;return new TransformStream({transform(n){new Uint8Array(r).set(n,t),t+=n.byteLength},flush(n){n.enqueue(new Uint8Array(r))}})}}function A(e,r){if(r===0)return new ReadableStream({start(a){a.close()}});const t=e.getReader({mode:"byob"});let n=0;return new ReadableStream({async pull(a){const{value:i,done:s}=await t.read(new Uint8Array(r-n));if(s){t.releaseLock(),a.close();return}n+=i.length,a.enqueue(i),n>=r&&(t.releaseLock(),a.close())},cancel(){t.cancel()}})}async function c(e,r){return r!==void 0&&(e=A(e,r)),await e.pipeThrough(S(r)).getReader().read().then(({value:t})=>t)}async function _(e,r){return new File([await c(r)],e)}function E(e){if(e instanceof ReadableStream)return e;let r;return Symbol.asyncIterator in e?r=e[Symbol.asyncIterator]():Symbol.iterator in e?r=e[Symbol.iterator]():r=e,new ReadableStream({async pull(t){const{done:n,value:a}=await r.next();if(n){t.close();return}t.enqueue(a)}})}class q extends File{constructor(r,t,n){super([],t,{type:n==null?void 0:n.type}),this.readableStream=r,this.filesize=n==null?void 0:n.filesize}slice(){throw new Error("slice() is not possible on a StreamedFile")}stream(){return this.readableStream}async text(){return new TextDecoder().decode(await this.arrayBuffer())}async arrayBuffer(){return await c(this.stream())}}ReadableStream.prototype[Symbol.asyncIterator]||(ReadableStream.prototype[Symbol.asyncIterator]=async function*(){const e=this.getReader();try{for(;;){const{done:r,value:t}=await e.read();if(r)return;yield t}}finally{e.releaseLock()}},ReadableStream.prototype.iterate=ReadableStream.prototype[Symbol.asyncIterator]);const N=32,h=67324752,y=33639248,g=101010256,M=0,T=8;function b(e){return new TransformStream({transform(r,t){e(r)&&t.enqueue(r)}})}function k(e){let r=!1;return new TransformStream({async transform(t,n){r||(r=!0,n.enqueue(e)),n.enqueue(t)}})}function x(e){return new TransformStream({async transform(r,t){t.enqueue(r)},async flush(r){r.enqueue(e)}})}function w(e,r){return O(e,r).pipeThrough(new TransformStream({async transform(t,n){const a=new File([t.bytes],new TextDecoder().decode(t.path),{type:t.isDirectory?"directory":void 0});n.enqueue(a)}}))}const v=()=>!0;function O(e,r=v){return new ReadableStream({async pull(n){const a=await P(e);if(!a){n.close();return}n.enqueue(a)}}).pipeThrough(b(({signature:n})=>n===h)).pipeThrough(b(r))}async function P(e){const t=new DataView((await c(e,4)).buffer).getUint32(0,!0);return t===h?await L(e,!0):t===y?await R(e,!0):t===g?await I(e,!0):null}async function L(e,r=!1){if(!r&&new DataView((await c(e,4)).buffer).getUint32(0,!0)!==h)return null;const t=new DataView((await c(e,26)).buffer),n=t.getUint16(22,!0),a=t.getUint16(24,!0),i={signature:h,version:t.getUint32(0,!0),generalPurpose:t.getUint16(2,!0),compressionMethod:t.getUint16(4,!0),lastModifiedTime:t.getUint16(6,!0),lastModifiedDate:t.getUint16(8,!0),crc:t.getUint32(10,!0),compressedSize:t.getUint32(14,!0),uncompressedSize:t.getUint32(18,!0)};i.path=await c(e,n),i.isDirectory=C(i.path),i.extra=await c(e,a);let s=A(e,i.compressedSize);if(i.compressionMethod===T){const o=new Uint8Array(10);o.set([31,139,8]);const f=new Uint8Array(8),u=new DataView(f.buffer);u.setUint32(0,i.crc,!0),u.setUint32(4,i.uncompressedSize%2**32,!0),s=s.pipeThrough(k(o)).pipeThrough(x(f)).pipeThrough(new DecompressionStream("gzip"))}return i.bytes=await s.pipeThrough(S(i.uncompressedSize)).getReader().read().then(({value:o})=>o),i}async function R(e,r=!1){if(!r&&new DataView((await c(e,4)).buffer).getUint32(0,!0)!==y)return null;const t=new DataView((await c(e,42)).buffer),n=t.getUint16(24,!0),a=t.getUint16(26,!0),i=t.getUint16(28,!0),s={signature:y,versionCreated:t.getUint16(0,!0),versionNeeded:t.getUint16(2,!0),generalPurpose:t.getUint16(4,!0),compressionMethod:t.getUint16(6,!0),lastModifiedTime:t.getUint16(8,!0),lastModifiedDate:t.getUint16(10,!0),crc:t.getUint32(12,!0),compressedSize:t.getUint32(16,!0),uncompressedSize:t.getUint32(20,!0),diskNumber:t.getUint16(30,!0),internalAttributes:t.getUint16(32,!0),externalAttributes:t.getUint32(34,!0),firstByteAt:t.getUint32(38,!0)};return s.lastByteAt=s.firstByteAt+N+n+i+a+s.compressedSize-1,s.path=await c(e,n),s.isDirectory=C(s.path),s.extra=await c(e,a),s.fileComment=await c(e,i),s}function C(e){return e[e.byteLength-1]==47}async function I(e,r=!1){if(!r&&new DataView((await c(e,4)).buffer).getUint32(0,!0)!==g)return null;const t=new DataView((await c(e,18)).buffer),n={signature:g,numberOfDisks:t.getUint16(0,!0),centralDirectoryStartDisk:t.getUint16(2,!0),numberCentralDirectoryRecordsOnThisDisk:t.getUint16(4,!0),numberCentralDirectoryRecords:t.getUint16(6,!0),centralDirectorySize:t.getUint32(8,!0),centralDirectoryOffset:t.getUint32(12,!0)},a=t.getUint16(16,!0);return n.comment=await c(e,a),n}const z=110*1024,V=10*1024,H=1024*1024*1,Z=new F.Semaphore({concurrency:10}),D=()=>!0;async function G(e,r=D){if(r===D){const d=await fetch(e);return w(d.body)}const t=await B(e);if(t<=H){const d=await fetch(e);return w(d.body)}const n=await fetch(e,{headers:{Range:"bytes=0-0","Accept-Encoding":"none"}}),[a,i]=n.body.tee(),s=a.getReader(),{value:o}=await s.read(),{done:f}=await s.read();if(s.releaseLock(),a.cancel(),!((o==null?void 0:o.length)===1&&f))return w(i);i.cancel();const l=await J(e,t);return W(l).pipeThrough(b(r)).pipeThrough($()).pipeThrough(j(l))}function W(e){let r;return new ReadableStream({async start(){r=await Y(e)},async pull(t){const n=await R(r);if(!n){t.close();return}t.enqueue(n)}})}async function Y(e){const r=z;let t=new Uint8Array,n=e.length;do{n=Math.max(0,n-r);const a=Math.min(n+r-1,e.length-1),i=await c(await e.streamBytes(n,a));t=U(i,t);const s=new DataView(i.buffer);for(let o=s.byteLength-4;o>=0;o--){if(s.getUint32(o,!0)!==g)continue;const u=o+12+4;if(t.byteLength<u+4)throw new Error("Central directory not found");const l=s.getUint32(u,!0);if(l<n){const d=await c(await e.streamBytes(l,n-1));t=U(d,t)}else l>n&&(t=t.slice(l-n));return new Blob([t]).stream()}}while(n>=0);throw new Error("Central directory not found")}function $(){let e=0,r=[];return new TransformStream({transform(t,n){t.firstByteAt>e+V&&(n.enqueue(r),r=[]),e=t.lastByteAt,r.push(t)},flush(t){t.enqueue(r)}})}function j(e){let r=!1,t=0,n;const a=[],i=new WritableStream({write(o,f){o.length&&(++t,K(e,o).then(u=>{a.push([o,u])}).catch(u=>{f.error(u)}).finally(()=>{--t}))},abort(){r=!0,n.close()},async close(){r=!0}});return{readable:new ReadableStream({start(o){n=o},async pull(o){for(;;){if(r&&!a.length&&t===0){o.close();return}if(!a.length){await new Promise(p=>setTimeout(p,50));continue}const[l,d]=a[0],m=await L(d);if(!m){a.shift();continue}if(l.find(p=>p.path===m.path)){o.enqueue(m);break}}}}),writable:i}}async function K(e,r){const t=await Z.acquire();try{const n=r[r.length-1];return await e.streamBytes(r[0].firstByteAt,n.lastByteAt)}finally{t()}}async function B(e){return await fetch(e,{method:"HEAD"}).then(r=>r.headers.get("Content-Length")).then(r=>{if(!r)throw new Error("Content-Length header is missing");const t=parseInt(r,10);if(isNaN(t)||t<0)throw new Error("Content-Length header is invalid");return t})}async function J(e,r){return r===void 0&&(r=await B(e)),{length:r,streamBytes:async(t,n)=>await fetch(e,{headers:{Range:`bytes=${t}-${n-1}`,"Accept-Encoding":"none"}}).then(a=>a.body)}}function Q(e){return E(e).pipeThrough(X())}function X(){const e=new Map;let r=0;return new TransformStream({async transform(t,n){const a=new Uint8Array(await t.arrayBuffer());let i=await c(new Blob([a]).stream().pipeThrough(new CompressionStream("gzip")));const s=new DataView(i.buffer).getUint32(i.byteLength-8,!0);i=i.slice(10,i.byteLength-8);const o=new TextEncoder().encode(t.name),f={signature:h,version:2,generalPurpose:0,compressionMethod:t.type==="directory"||i.byteLength===0?M:T,lastModifiedTime:0,lastModifiedDate:0,crc:s,compressedSize:i.byteLength,uncompressedSize:a.byteLength,path:o,extra:new Uint8Array(0)};e.set(r,f);const u=ee(f);n.enqueue(u),r+=u.byteLength,n.enqueue(i),r+=i.byteLength},flush(t){const n=r;let a=0;for(const[o,f]of e.entries()){const u={...f,signature:y,fileComment:new Uint8Array(0),diskNumber:1,internalAttributes:0,externalAttributes:0},l=te(u,o);t.enqueue(l),a+=l.byteLength}const i={signature:g,numberOfDisks:1,centralDirectoryOffset:n,centralDirectorySize:a,centralDirectoryStartDisk:1,numberCentralDirectoryRecordsOnThisDisk:e.size,numberCentralDirectoryRecords:e.size,comment:new Uint8Array(0)},s=ne(i);t.enqueue(s),e.clear()}})}function ee(e){const r=new ArrayBuffer(30+e.path.byteLength+e.extra.byteLength),t=new DataView(r);t.setUint32(0,e.signature,!0),t.setUint16(4,e.version,!0),t.setUint16(6,e.generalPurpose,!0),t.setUint16(8,e.compressionMethod,!0),t.setUint16(10,e.lastModifiedDate,!0),t.setUint16(12,e.lastModifiedTime,!0),t.setUint32(14,e.crc,!0),t.setUint32(18,e.compressedSize,!0),t.setUint32(22,e.uncompressedSize,!0),t.setUint16(26,e.path.byteLength,!0),t.setUint16(28,e.extra.byteLength,!0);const n=new Uint8Array(r);return n.set(e.path,30),n.set(e.extra,30+e.path.byteLength),n}function te(e,r){const t=new ArrayBuffer(46+e.path.byteLength+e.extra.byteLength),n=new DataView(t);n.setUint32(0,e.signature,!0),n.setUint16(4,e.versionCreated,!0),n.setUint16(6,e.versionNeeded,!0),n.setUint16(8,e.generalPurpose,!0),n.setUint16(10,e.compressionMethod,!0),n.setUint16(12,e.lastModifiedDate,!0),n.setUint16(14,e.lastModifiedTime,!0),n.setUint32(16,e.crc,!0),n.setUint32(20,e.compressedSize,!0),n.setUint32(24,e.uncompressedSize,!0),n.setUint16(28,e.path.byteLength,!0),n.setUint16(30,e.extra.byteLength,!0),n.setUint16(32,e.fileComment.byteLength,!0),n.setUint16(34,e.diskNumber,!0),n.setUint16(36,e.internalAttributes,!0),n.setUint32(38,e.externalAttributes,!0),n.setUint32(42,r,!0);const a=new Uint8Array(t);return a.set(e.path,46),a.set(e.extra,46+e.path.byteLength),a}function ne(e){const r=new ArrayBuffer(22+e.comment.byteLength),t=new DataView(r);t.setUint32(0,e.signature,!0),t.setUint16(4,e.numberOfDisks,!0),t.setUint16(6,e.centralDirectoryStartDisk,!0),t.setUint16(8,e.numberCentralDirectoryRecordsOnThisDisk,!0),t.setUint16(10,e.numberCentralDirectoryRecords,!0),t.setUint32(12,e.centralDirectorySize,!0),t.setUint32(16,e.centralDirectoryOffset,!0),t.setUint16(20,e.comment.byteLength,!0);const n=new Uint8Array(r);return n.set(e.comment,22),n}exports.StreamedFile=q;exports.collectBytes=c;exports.collectFile=_;exports.decodeRemoteZip=G;exports.decodeZip=w;exports.encodeZip=Q;exports.iteratorToStream=E;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require("@php-wasm/node-polyfills");const F=require("@php-wasm/util");function U(...e){const r=new Uint8Array(e.reduce((n,a)=>n+a.length,0));let t=0;for(const n of e)r.set(n,t),t+=n.length;return r}function A(e){if(e===void 0){let r=new Uint8Array;return new TransformStream({transform(t){r=U(r,t)},flush(t){t.enqueue(r)}})}else{const r=new ArrayBuffer(e||0);let t=0;return new TransformStream({transform(n){new Uint8Array(r).set(n,t),t+=n.byteLength},flush(n){n.enqueue(new Uint8Array(r))}})}}function E(e,r){if(r===0)return new ReadableStream({start(a){a.close()}});const t=e.getReader({mode:"byob"});let n=0;return new ReadableStream({async pull(a){const{value:i,done:s}=await t.read(new Uint8Array(r-n));if(s){t.releaseLock(),a.close();return}n+=i.length,a.enqueue(i),n>=r&&(t.releaseLock(),a.close())},cancel(){t.cancel()}})}async function c(e,r){return r!==void 0&&(e=E(e,r)),await e.pipeThrough(A(r)).getReader().read().then(({value:t})=>t)}async function _(e,r){return new File([await c(r)],e)}function T(e){if(e instanceof ReadableStream)return e;let r;return Symbol.asyncIterator in e?r=e[Symbol.asyncIterator]():Symbol.iterator in e?r=e[Symbol.iterator]():r=e,new ReadableStream({async pull(t){const{done:n,value:a}=await r.next();if(n){t.close();return}t.enqueue(a)}})}class D extends File{static fromArrayBuffer(r,t,n){return new D(new ReadableStream({start(a){a.enqueue(new Uint8Array(r)),a.close()}}),t,n)}constructor(r,t,n){super([],t,{type:n==null?void 0:n.type}),this.readableStream=r,this.filesize=n==null?void 0:n.filesize}slice(){throw new Error("slice() is not possible on a StreamedFile")}stream(){return this.readableStream}async text(){return new TextDecoder().decode(await this.arrayBuffer())}async arrayBuffer(){return await c(this.stream())}}ReadableStream.prototype[Symbol.asyncIterator]||(ReadableStream.prototype[Symbol.asyncIterator]=async function*(){const e=this.getReader();try{for(;;){const{done:r,value:t}=await e.read();if(r)return;yield t}}finally{e.releaseLock()}},ReadableStream.prototype.iterate=ReadableStream.prototype[Symbol.asyncIterator]);const N=32,h=67324752,y=33639248,g=101010256,M=0,R=8;function b(e){return new TransformStream({transform(r,t){e(r)&&t.enqueue(r)}})}function k(e){let r=!1;return new TransformStream({async transform(t,n){r||(r=!0,n.enqueue(e)),n.enqueue(t)}})}function x(e){return new TransformStream({async transform(r,t){t.enqueue(r)},async flush(r){r.enqueue(e)}})}function w(e,r){return O(e,r).pipeThrough(new TransformStream({async transform(t,n){const a=new File([t.bytes],new TextDecoder().decode(t.path),{type:t.isDirectory?"directory":void 0});n.enqueue(a)}}))}const v=()=>!0;function O(e,r=v){return new ReadableStream({async pull(n){const a=await P(e);if(!a){n.close();return}n.enqueue(a)}}).pipeThrough(b(({signature:n})=>n===h)).pipeThrough(b(r))}async function P(e){const t=new DataView((await c(e,4)).buffer).getUint32(0,!0);return t===h?await L(e,!0):t===y?await C(e,!0):t===g?await I(e,!0):null}async function L(e,r=!1){if(!r&&new DataView((await c(e,4)).buffer).getUint32(0,!0)!==h)return null;const t=new DataView((await c(e,26)).buffer),n=t.getUint16(22,!0),a=t.getUint16(24,!0),i={signature:h,version:t.getUint32(0,!0),generalPurpose:t.getUint16(2,!0),compressionMethod:t.getUint16(4,!0),lastModifiedTime:t.getUint16(6,!0),lastModifiedDate:t.getUint16(8,!0),crc:t.getUint32(10,!0),compressedSize:t.getUint32(14,!0),uncompressedSize:t.getUint32(18,!0)};i.path=await c(e,n),i.isDirectory=B(i.path),i.extra=await c(e,a);let s=E(e,i.compressedSize);if(i.compressionMethod===R){const o=new Uint8Array(10);o.set([31,139,8]);const f=new Uint8Array(8),u=new DataView(f.buffer);u.setUint32(0,i.crc,!0),u.setUint32(4,i.uncompressedSize%2**32,!0),s=s.pipeThrough(k(o)).pipeThrough(x(f)).pipeThrough(new DecompressionStream("gzip"))}return i.bytes=await s.pipeThrough(A(i.uncompressedSize)).getReader().read().then(({value:o})=>o),i}async function C(e,r=!1){if(!r&&new DataView((await c(e,4)).buffer).getUint32(0,!0)!==y)return null;const t=new DataView((await c(e,42)).buffer),n=t.getUint16(24,!0),a=t.getUint16(26,!0),i=t.getUint16(28,!0),s={signature:y,versionCreated:t.getUint16(0,!0),versionNeeded:t.getUint16(2,!0),generalPurpose:t.getUint16(4,!0),compressionMethod:t.getUint16(6,!0),lastModifiedTime:t.getUint16(8,!0),lastModifiedDate:t.getUint16(10,!0),crc:t.getUint32(12,!0),compressedSize:t.getUint32(16,!0),uncompressedSize:t.getUint32(20,!0),diskNumber:t.getUint16(30,!0),internalAttributes:t.getUint16(32,!0),externalAttributes:t.getUint32(34,!0),firstByteAt:t.getUint32(38,!0)};return s.lastByteAt=s.firstByteAt+N+n+i+a+s.compressedSize-1,s.path=await c(e,n),s.isDirectory=B(s.path),s.extra=await c(e,a),s.fileComment=await c(e,i),s}function B(e){return e[e.byteLength-1]==47}async function I(e,r=!1){if(!r&&new DataView((await c(e,4)).buffer).getUint32(0,!0)!==g)return null;const t=new DataView((await c(e,18)).buffer),n={signature:g,numberOfDisks:t.getUint16(0,!0),centralDirectoryStartDisk:t.getUint16(2,!0),numberCentralDirectoryRecordsOnThisDisk:t.getUint16(4,!0),numberCentralDirectoryRecords:t.getUint16(6,!0),centralDirectorySize:t.getUint32(8,!0),centralDirectoryOffset:t.getUint32(12,!0)},a=t.getUint16(16,!0);return n.comment=await c(e,a),n}const z=110*1024,V=10*1024,H=1024*1024*1,Z=new F.Semaphore({concurrency:10}),S=()=>!0;async function G(e,r=S){if(r===S){const d=await fetch(e);return w(d.body)}const t=await q(e);if(t<=H){const d=await fetch(e);return w(d.body)}const n=await fetch(e,{headers:{Range:"bytes=0-0","Accept-Encoding":"none"}}),[a,i]=n.body.tee(),s=a.getReader(),{value:o}=await s.read(),{done:f}=await s.read();if(s.releaseLock(),a.cancel(),!((o==null?void 0:o.length)===1&&f))return w(i);i.cancel();const l=await J(e,t);return W(l).pipeThrough(b(r)).pipeThrough($()).pipeThrough(j(l))}function W(e){let r;return new ReadableStream({async start(){r=await Y(e)},async pull(t){const n=await C(r);if(!n){t.close();return}t.enqueue(n)}})}async function Y(e){const r=z;let t=new Uint8Array,n=e.length;do{n=Math.max(0,n-r);const a=Math.min(n+r-1,e.length-1),i=await c(await e.streamBytes(n,a));t=U(i,t);const s=new DataView(i.buffer);for(let o=s.byteLength-4;o>=0;o--){if(s.getUint32(o,!0)!==g)continue;const u=o+12+4;if(t.byteLength<u+4)throw new Error("Central directory not found");const l=s.getUint32(u,!0);if(l<n){const d=await c(await e.streamBytes(l,n-1));t=U(d,t)}else l>n&&(t=t.slice(l-n));return new Blob([t]).stream()}}while(n>=0);throw new Error("Central directory not found")}function $(){let e=0,r=[];return new TransformStream({transform(t,n){t.firstByteAt>e+V&&(n.enqueue(r),r=[]),e=t.lastByteAt,r.push(t)},flush(t){t.enqueue(r)}})}function j(e){let r=!1,t=0,n;const a=[],i=new WritableStream({write(o,f){o.length&&(++t,K(e,o).then(u=>{a.push([o,u])}).catch(u=>{f.error(u)}).finally(()=>{--t}))},abort(){r=!0,n.close()},async close(){r=!0}});return{readable:new ReadableStream({start(o){n=o},async pull(o){for(;;){if(r&&!a.length&&t===0){o.close();return}if(!a.length){await new Promise(p=>setTimeout(p,50));continue}const[l,d]=a[0],m=await L(d);if(!m){a.shift();continue}if(l.find(p=>p.path===m.path)){o.enqueue(m);break}}}}),writable:i}}async function K(e,r){const t=await Z.acquire();try{const n=r[r.length-1];return await e.streamBytes(r[0].firstByteAt,n.lastByteAt)}finally{t()}}async function q(e){return await fetch(e,{method:"HEAD"}).then(r=>r.headers.get("Content-Length")).then(r=>{if(!r)throw new Error("Content-Length header is missing");const t=parseInt(r,10);if(isNaN(t)||t<0)throw new Error("Content-Length header is invalid");return t})}async function J(e,r){return r===void 0&&(r=await q(e)),{length:r,streamBytes:async(t,n)=>await fetch(e,{headers:{Range:`bytes=${t}-${n-1}`,"Accept-Encoding":"none"}}).then(a=>a.body)}}function Q(e){return T(e).pipeThrough(X())}function X(){const e=new Map;let r=0;return new TransformStream({async transform(t,n){const a=new Uint8Array(await t.arrayBuffer());let i=await c(new Blob([a]).stream().pipeThrough(new CompressionStream("gzip")));const s=new DataView(i.buffer).getUint32(i.byteLength-8,!0);i=i.slice(10,i.byteLength-8);const o=new TextEncoder().encode(t.name),f={signature:h,version:2,generalPurpose:0,compressionMethod:t.type==="directory"||i.byteLength===0?M:R,lastModifiedTime:0,lastModifiedDate:0,crc:s,compressedSize:i.byteLength,uncompressedSize:a.byteLength,path:o,extra:new Uint8Array(0)};e.set(r,f);const u=ee(f);n.enqueue(u),r+=u.byteLength,n.enqueue(i),r+=i.byteLength},flush(t){const n=r;let a=0;for(const[o,f]of e.entries()){const u={...f,signature:y,fileComment:new Uint8Array(0),diskNumber:0,internalAttributes:0,externalAttributes:0},l=te(u,o);t.enqueue(l),a+=l.byteLength}const i={signature:g,numberOfDisks:0,centralDirectoryOffset:n,centralDirectorySize:a,centralDirectoryStartDisk:0,numberCentralDirectoryRecordsOnThisDisk:e.size,numberCentralDirectoryRecords:e.size,comment:new Uint8Array(0)},s=ne(i);t.enqueue(s),e.clear()}})}function ee(e){const r=new ArrayBuffer(30+e.path.byteLength+e.extra.byteLength),t=new DataView(r);t.setUint32(0,e.signature,!0),t.setUint16(4,e.version,!0),t.setUint16(6,e.generalPurpose,!0),t.setUint16(8,e.compressionMethod,!0),t.setUint16(10,e.lastModifiedDate,!0),t.setUint16(12,e.lastModifiedTime,!0),t.setUint32(14,e.crc,!0),t.setUint32(18,e.compressedSize,!0),t.setUint32(22,e.uncompressedSize,!0),t.setUint16(26,e.path.byteLength,!0),t.setUint16(28,e.extra.byteLength,!0);const n=new Uint8Array(r);return n.set(e.path,30),n.set(e.extra,30+e.path.byteLength),n}function te(e,r){const t=new ArrayBuffer(46+e.path.byteLength+e.extra.byteLength),n=new DataView(t);n.setUint32(0,e.signature,!0),n.setUint16(4,e.versionCreated,!0),n.setUint16(6,e.versionNeeded,!0),n.setUint16(8,e.generalPurpose,!0),n.setUint16(10,e.compressionMethod,!0),n.setUint16(12,e.lastModifiedDate,!0),n.setUint16(14,e.lastModifiedTime,!0),n.setUint32(16,e.crc,!0),n.setUint32(20,e.compressedSize,!0),n.setUint32(24,e.uncompressedSize,!0),n.setUint16(28,e.path.byteLength,!0),n.setUint16(30,e.extra.byteLength,!0),n.setUint16(32,e.fileComment.byteLength,!0),n.setUint16(34,e.diskNumber,!0),n.setUint16(36,e.internalAttributes,!0),n.setUint32(38,e.externalAttributes,!0),n.setUint32(42,r,!0);const a=new Uint8Array(t);return a.set(e.path,46),a.set(e.extra,46+e.path.byteLength),a}function ne(e){const r=new ArrayBuffer(22+e.comment.byteLength),t=new DataView(r);t.setUint32(0,e.signature,!0),t.setUint16(4,e.numberOfDisks,!0),t.setUint16(6,e.centralDirectoryStartDisk,!0),t.setUint16(8,e.numberCentralDirectoryRecordsOnThisDisk,!0),t.setUint16(10,e.numberCentralDirectoryRecords,!0),t.setUint32(12,e.centralDirectorySize,!0),t.setUint32(16,e.centralDirectoryOffset,!0),t.setUint16(20,e.comment.byteLength,!0);const n=new Uint8Array(r);return n.set(e.comment,22),n}exports.StreamedFile=D;exports.collectBytes=c;exports.collectFile=_;exports.decodeRemoteZip=G;exports.decodeZip=w;exports.encodeZip=Q;exports.iteratorToStream=T;
2
2
  //# sourceMappingURL=index.cjs.map
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\tstatic fromArrayBuffer(\n\t\tarrayBuffer: Uint8Array,\n\t\tname: string,\n\t\toptions?: { type?: string; filesize?: number }\n\t): StreamedFile {\n\t\treturn new StreamedFile(\n\t\t\tnew ReadableStream({\n\t\t\t\tstart(controller) {\n\t\t\t\t\tcontroller.enqueue(new Uint8Array(arrayBuffer));\n\t\t\t\t\tcontroller.close();\n\t\t\t\t},\n\t\t\t}),\n\t\t\tname,\n\t\t\toptions\n\t\t);\n\t}\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())) as unknown as ArrayBuffer;\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: 0,\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: 0,\n\t\t\t\tcentralDirectoryOffset,\n\t\t\t\tcentralDirectorySize,\n\t\t\t\tcentralDirectoryStartDisk: 0,\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","arrayBuffer","name","options","readableStream","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 CHANGED
@@ -1,5 +1,5 @@
1
1
  import "@php-wasm/node-polyfills";
2
- import { Semaphore as B } from "@php-wasm/util";
2
+ import { Semaphore as _ } from "@php-wasm/util";
3
3
  function U(...e) {
4
4
  const r = new Uint8Array(
5
5
  e.reduce((n, a) => n + a.length, 0)
@@ -61,10 +61,10 @@ function A(e, r) {
61
61
  async function c(e, r) {
62
62
  return r !== void 0 && (e = A(e, r)), await e.pipeThrough(S(r)).getReader().read().then(({ value: t }) => t);
63
63
  }
64
- async function re(e, r) {
64
+ async function ae(e, r) {
65
65
  return new File([await c(r)], e);
66
66
  }
67
- function _(e) {
67
+ function q(e) {
68
68
  if (e instanceof ReadableStream)
69
69
  return e;
70
70
  let r;
@@ -79,7 +79,18 @@ function _(e) {
79
79
  }
80
80
  });
81
81
  }
82
- class ae extends File {
82
+ class E extends File {
83
+ static fromArrayBuffer(r, t, n) {
84
+ return new E(
85
+ new ReadableStream({
86
+ start(a) {
87
+ a.enqueue(new Uint8Array(r)), a.close();
88
+ }
89
+ }),
90
+ t,
91
+ n
92
+ );
93
+ }
83
94
  /**
84
95
  * Creates a new StreamedFile instance.
85
96
  *
@@ -137,7 +148,7 @@ ReadableStream.prototype[Symbol.asyncIterator] || (ReadableStream.prototype[Symb
137
148
  }
138
149
  }, ReadableStream.prototype.iterate = // @ts-ignore
139
150
  ReadableStream.prototype[Symbol.asyncIterator]);
140
- const F = 32, h = 67324752, w = 33639248, g = 101010256, N = 0, E = 8;
151
+ const N = 32, h = 67324752, w = 33639248, g = 101010256, x = 0, L = 8;
141
152
  function b(e) {
142
153
  return new TransformStream({
143
154
  transform(r, t) {
@@ -145,7 +156,7 @@ function b(e) {
145
156
  }
146
157
  });
147
158
  }
148
- function q(e) {
159
+ function F(e) {
149
160
  let r = !1;
150
161
  return new TransformStream({
151
162
  async transform(t, n) {
@@ -153,7 +164,7 @@ function q(e) {
153
164
  }
154
165
  });
155
166
  }
156
- function x(e) {
167
+ function k(e) {
157
168
  return new TransformStream({
158
169
  async transform(r, t) {
159
170
  t.enqueue(r);
@@ -164,7 +175,7 @@ function x(e) {
164
175
  });
165
176
  }
166
177
  function p(e, r) {
167
- return M(e, r).pipeThrough(
178
+ return v(e, r).pipeThrough(
168
179
  new TransformStream({
169
180
  async transform(t, n) {
170
181
  const a = new File(
@@ -179,11 +190,11 @@ function p(e, r) {
179
190
  })
180
191
  );
181
192
  }
182
- const k = () => !0;
183
- function M(e, r = k) {
193
+ const M = () => !0;
194
+ function v(e, r = M) {
184
195
  return new ReadableStream({
185
196
  async pull(n) {
186
- const a = await v(e);
197
+ const a = await O(e);
187
198
  if (!a) {
188
199
  n.close();
189
200
  return;
@@ -196,11 +207,11 @@ function M(e, r = k) {
196
207
  b(r)
197
208
  );
198
209
  }
199
- async function v(e) {
210
+ async function O(e) {
200
211
  const t = new DataView((await c(e, 4)).buffer).getUint32(0, !0);
201
- return t === h ? await L(e, !0) : t === w ? await T(e, !0) : t === g ? await O(e, !0) : null;
212
+ return t === h ? await R(e, !0) : t === w ? await T(e, !0) : t === g ? await P(e, !0) : null;
202
213
  }
203
- async function L(e, r = !1) {
214
+ async function R(e, r = !1) {
204
215
  if (!r && new DataView((await c(e, 4)).buffer).getUint32(0, !0) !== h)
205
216
  return null;
206
217
  const t = new DataView((await c(e, 26)).buffer), n = t.getUint16(22, !0), a = t.getUint16(24, !0), i = {
@@ -214,13 +225,13 @@ async function L(e, r = !1) {
214
225
  compressedSize: t.getUint32(14, !0),
215
226
  uncompressedSize: t.getUint32(18, !0)
216
227
  };
217
- i.path = await c(e, n), i.isDirectory = R(i.path), i.extra = await c(e, a);
228
+ i.path = await c(e, n), i.isDirectory = C(i.path), i.extra = await c(e, a);
218
229
  let s = A(e, i.compressedSize);
219
- if (i.compressionMethod === E) {
230
+ if (i.compressionMethod === L) {
220
231
  const o = new Uint8Array(10);
221
232
  o.set([31, 139, 8]);
222
233
  const f = new Uint8Array(8), u = new DataView(f.buffer);
223
- u.setUint32(0, i.crc, !0), u.setUint32(4, i.uncompressedSize % 2 ** 32, !0), s = s.pipeThrough(q(o)).pipeThrough(x(f)).pipeThrough(new DecompressionStream("gzip"));
234
+ u.setUint32(0, i.crc, !0), u.setUint32(4, i.uncompressedSize % 2 ** 32, !0), s = s.pipeThrough(F(o)).pipeThrough(k(f)).pipeThrough(new DecompressionStream("gzip"));
224
235
  }
225
236
  return i.bytes = await s.pipeThrough(S(i.uncompressedSize)).getReader().read().then(({ value: o }) => o), i;
226
237
  }
@@ -243,15 +254,15 @@ async function T(e, r = !1) {
243
254
  externalAttributes: t.getUint32(34, !0),
244
255
  firstByteAt: t.getUint32(38, !0)
245
256
  };
246
- return s.lastByteAt = s.firstByteAt + F + n + i + a + s.compressedSize - 1, s.path = await c(e, n), s.isDirectory = R(s.path), s.extra = await c(e, a), s.fileComment = await c(
257
+ return s.lastByteAt = s.firstByteAt + N + n + i + a + s.compressedSize - 1, s.path = await c(e, n), s.isDirectory = C(s.path), s.extra = await c(e, a), s.fileComment = await c(
247
258
  e,
248
259
  i
249
260
  ), s;
250
261
  }
251
- function R(e) {
262
+ function C(e) {
252
263
  return e[e.byteLength - 1] == 47;
253
264
  }
254
- async function O(e, r = !1) {
265
+ async function P(e, r = !1) {
255
266
  if (!r && new DataView((await c(e, 4)).buffer).getUint32(0, !0) !== g)
256
267
  return null;
257
268
  const t = new DataView((await c(e, 18)).buffer), n = {
@@ -265,14 +276,14 @@ async function O(e, r = !1) {
265
276
  }, a = t.getUint16(16, !0);
266
277
  return n.comment = await c(e, a), n;
267
278
  }
268
- const P = 110 * 1024, I = 10 * 1024, z = 1024 * 1024 * 1, V = new B({ concurrency: 10 }), D = () => !0;
279
+ const I = 110 * 1024, z = 10 * 1024, V = 1024 * 1024 * 1, H = new _({ concurrency: 10 }), D = () => !0;
269
280
  async function ie(e, r = D) {
270
281
  if (r === D) {
271
282
  const d = await fetch(e);
272
283
  return p(d.body);
273
284
  }
274
- const t = await C(e);
275
- if (t <= z) {
285
+ const t = await B(e);
286
+ if (t <= V) {
276
287
  const d = await fetch(e);
277
288
  return p(d.body);
278
289
  }
@@ -288,16 +299,16 @@ async function ie(e, r = D) {
288
299
  if (s.releaseLock(), a.cancel(), !((o == null ? void 0 : o.length) === 1 && f))
289
300
  return p(i);
290
301
  i.cancel();
291
- const l = await $(e, t);
292
- return H(l).pipeThrough(b(r)).pipeThrough(G()).pipeThrough(
293
- W(l)
302
+ const l = await K(e, t);
303
+ return Z(l).pipeThrough(b(r)).pipeThrough(W()).pipeThrough(
304
+ Y(l)
294
305
  );
295
306
  }
296
- function H(e) {
307
+ function Z(e) {
297
308
  let r;
298
309
  return new ReadableStream({
299
310
  async start() {
300
- r = await Z(e);
311
+ r = await G(e);
301
312
  },
302
313
  async pull(t) {
303
314
  const n = await T(
@@ -311,8 +322,8 @@ function H(e) {
311
322
  }
312
323
  });
313
324
  }
314
- async function Z(e) {
315
- const r = P;
325
+ async function G(e) {
326
+ const r = I;
316
327
  let t = new Uint8Array(), n = e.length;
317
328
  do {
318
329
  n = Math.max(0, n - r);
@@ -347,22 +358,22 @@ async function Z(e) {
347
358
  } while (n >= 0);
348
359
  throw new Error("Central directory not found");
349
360
  }
350
- function G() {
361
+ function W() {
351
362
  let e = 0, r = [];
352
363
  return new TransformStream({
353
364
  transform(t, n) {
354
- t.firstByteAt > e + I && (n.enqueue(r), r = []), e = t.lastByteAt, r.push(t);
365
+ t.firstByteAt > e + z && (n.enqueue(r), r = []), e = t.lastByteAt, r.push(t);
355
366
  },
356
367
  flush(t) {
357
368
  t.enqueue(r);
358
369
  }
359
370
  });
360
371
  }
361
- function W(e) {
372
+ function Y(e) {
362
373
  let r = !1, t = 0, n;
363
374
  const a = [], i = new WritableStream({
364
375
  write(o, f) {
365
- o.length && (++t, Y(e, o).then((u) => {
376
+ o.length && (++t, $(e, o).then((u) => {
366
377
  a.push([o, u]);
367
378
  }).catch((u) => {
368
379
  f.error(u);
@@ -392,7 +403,7 @@ function W(e) {
392
403
  await new Promise((m) => setTimeout(m, 50));
393
404
  continue;
394
405
  }
395
- const [l, d] = a[0], y = await L(d);
406
+ const [l, d] = a[0], y = await R(d);
396
407
  if (!y) {
397
408
  a.shift();
398
409
  continue;
@@ -409,8 +420,8 @@ function W(e) {
409
420
  writable: i
410
421
  };
411
422
  }
412
- async function Y(e, r) {
413
- const t = await V.acquire();
423
+ async function $(e, r) {
424
+ const t = await H.acquire();
414
425
  try {
415
426
  const n = r[r.length - 1];
416
427
  return await e.streamBytes(
@@ -421,7 +432,7 @@ async function Y(e, r) {
421
432
  t();
422
433
  }
423
434
  }
424
- async function C(e) {
435
+ async function B(e) {
425
436
  return await fetch(e, { method: "HEAD" }).then((r) => r.headers.get("Content-Length")).then((r) => {
426
437
  if (!r)
427
438
  throw new Error("Content-Length header is missing");
@@ -431,8 +442,8 @@ async function C(e) {
431
442
  return t;
432
443
  });
433
444
  }
434
- async function $(e, r) {
435
- return r === void 0 && (r = await C(e)), {
445
+ async function K(e, r) {
446
+ return r === void 0 && (r = await B(e)), {
436
447
  length: r,
437
448
  streamBytes: async (t, n) => await fetch(e, {
438
449
  headers: {
@@ -444,9 +455,9 @@ async function $(e, r) {
444
455
  };
445
456
  }
446
457
  function se(e) {
447
- return _(e).pipeThrough(K());
458
+ return q(e).pipeThrough(j());
448
459
  }
449
- function K() {
460
+ function j() {
450
461
  const e = /* @__PURE__ */ new Map();
451
462
  let r = 0;
452
463
  return new TransformStream({
@@ -464,7 +475,7 @@ function K() {
464
475
  signature: h,
465
476
  version: 2,
466
477
  generalPurpose: 0,
467
- compressionMethod: t.type === "directory" || i.byteLength === 0 ? N : E,
478
+ compressionMethod: t.type === "directory" || i.byteLength === 0 ? x : L,
468
479
  lastModifiedTime: 0,
469
480
  lastModifiedDate: 0,
470
481
  crc: s,
@@ -474,7 +485,7 @@ function K() {
474
485
  extra: new Uint8Array(0)
475
486
  };
476
487
  e.set(r, f);
477
- const u = j(f);
488
+ const u = J(f);
478
489
  n.enqueue(u), r += u.byteLength, n.enqueue(i), r += i.byteLength;
479
490
  },
480
491
  flush(t) {
@@ -488,10 +499,10 @@ function K() {
488
499
  ...f,
489
500
  signature: w,
490
501
  fileComment: new Uint8Array(0),
491
- diskNumber: 1,
502
+ diskNumber: 0,
492
503
  internalAttributes: 0,
493
504
  externalAttributes: 0
494
- }, l = J(
505
+ }, l = Q(
495
506
  u,
496
507
  o
497
508
  );
@@ -499,19 +510,19 @@ function K() {
499
510
  }
500
511
  const i = {
501
512
  signature: g,
502
- numberOfDisks: 1,
513
+ numberOfDisks: 0,
503
514
  centralDirectoryOffset: n,
504
515
  centralDirectorySize: a,
505
- centralDirectoryStartDisk: 1,
516
+ centralDirectoryStartDisk: 0,
506
517
  numberCentralDirectoryRecordsOnThisDisk: e.size,
507
518
  numberCentralDirectoryRecords: e.size,
508
519
  comment: new Uint8Array(0)
509
- }, s = Q(i);
520
+ }, s = X(i);
510
521
  t.enqueue(s), e.clear();
511
522
  }
512
523
  });
513
524
  }
514
- function j(e) {
525
+ function J(e) {
515
526
  const r = new ArrayBuffer(
516
527
  30 + e.path.byteLength + e.extra.byteLength
517
528
  ), t = new DataView(r);
@@ -519,7 +530,7 @@ function j(e) {
519
530
  const n = new Uint8Array(r);
520
531
  return n.set(e.path, 30), n.set(e.extra, 30 + e.path.byteLength), n;
521
532
  }
522
- function J(e, r) {
533
+ function Q(e, r) {
523
534
  const t = new ArrayBuffer(
524
535
  46 + e.path.byteLength + e.extra.byteLength
525
536
  ), n = new DataView(t);
@@ -527,19 +538,19 @@ function J(e, r) {
527
538
  const a = new Uint8Array(t);
528
539
  return a.set(e.path, 46), a.set(e.extra, 46 + e.path.byteLength), a;
529
540
  }
530
- function Q(e) {
541
+ function X(e) {
531
542
  const r = new ArrayBuffer(22 + e.comment.byteLength), t = new DataView(r);
532
543
  t.setUint32(0, e.signature, !0), t.setUint16(4, e.numberOfDisks, !0), t.setUint16(6, e.centralDirectoryStartDisk, !0), t.setUint16(8, e.numberCentralDirectoryRecordsOnThisDisk, !0), t.setUint16(10, e.numberCentralDirectoryRecords, !0), t.setUint32(12, e.centralDirectorySize, !0), t.setUint32(16, e.centralDirectoryOffset, !0), t.setUint16(20, e.comment.byteLength, !0);
533
544
  const n = new Uint8Array(r);
534
545
  return n.set(e.comment, 22), n;
535
546
  }
536
547
  export {
537
- ae as StreamedFile,
548
+ E as StreamedFile,
538
549
  c as collectBytes,
539
- re as collectFile,
550
+ ae as collectFile,
540
551
  ie as decodeRemoteZip,
541
552
  p as decodeZip,
542
553
  se as encodeZip,
543
- _ as iteratorToStream
554
+ q as iteratorToStream
544
555
  };
545
556
  //# sourceMappingURL=index.js.map
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\tstatic fromArrayBuffer(\n\t\tarrayBuffer: Uint8Array,\n\t\tname: string,\n\t\toptions?: { type?: string; filesize?: number }\n\t): StreamedFile {\n\t\treturn new StreamedFile(\n\t\t\tnew ReadableStream({\n\t\t\t\tstart(controller) {\n\t\t\t\t\tcontroller.enqueue(new Uint8Array(arrayBuffer));\n\t\t\t\t\tcontroller.close();\n\t\t\t\t},\n\t\t\t}),\n\t\t\tname,\n\t\t\toptions\n\t\t);\n\t}\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())) as unknown as ArrayBuffer;\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: 0,\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: 0,\n\t\t\t\tcentralDirectoryOffset,\n\t\t\t\tcentralDirectorySize,\n\t\t\t\tcentralDirectoryStartDisk: 0,\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","arrayBuffer","name","options","readableStream","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.21",
3
+ "version": "3.0.30",
4
4
  "description": "Stream-based compression bindings.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -29,21 +29,21 @@
29
29
  },
30
30
  "license": "GPL-2.0-or-later",
31
31
  "type": "module",
32
- "gitHead": "8d3a2da8f91ca792ba8f6fe7e92fdb658f4075ee",
32
+ "gitHead": "13a2c22a01669fcfecf6e72a7d131282cec9b251",
33
33
  "packageManager": "npm@10.9.2",
34
34
  "overrides": {
35
35
  "rollup": "^4.34.6",
36
36
  "react": "18.3.1",
37
37
  "react-dom": "18.3.1",
38
38
  "typescript": "5.4.5",
39
- "@playwright/test": "1.47.1",
40
- "ws": "^8.18.0",
39
+ "@playwright/test": "1.55.1",
40
+ "ws": "8.18.3",
41
41
  "tmp": "0.2.5",
42
42
  "form-data": "^4.0.4"
43
43
  },
44
44
  "dependencies": {
45
- "@php-wasm/node-polyfills": "3.0.21",
46
- "@php-wasm/util": "3.0.21"
45
+ "@php-wasm/node-polyfills": "3.0.30",
46
+ "@php-wasm/util": "3.0.30"
47
47
  },
48
48
  "optionalDependencies": {
49
49
  "fs-ext": "2.1.1"
@@ -5,6 +5,10 @@
5
5
  export declare class StreamedFile extends File {
6
6
  readonly filesize: number | undefined;
7
7
  private readableStream;
8
+ static fromArrayBuffer(arrayBuffer: Uint8Array, name: string, options?: {
9
+ type?: string;
10
+ filesize?: number;
11
+ }): StreamedFile;
8
12
  /**
9
13
  * Creates a new StreamedFile instance.
10
14
  *
@@ -39,5 +43,5 @@ export declare class StreamedFile extends File {
39
43
  *
40
44
  * @returns File data as an ArrayBuffer.
41
45
  */
42
- arrayBuffer(): Promise<Uint8Array>;
46
+ arrayBuffer(): Promise<ArrayBuffer>;
43
47
  }