@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 +1 -1
- package/index.cjs.map +1 -1
- package/index.js +66 -55
- package/index.js.map +1 -1
- package/package.json +6 -6
- package/utils/streamed-file.d.ts +5 -1
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
|
|
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
|
|
64
|
+
async function ae(e, r) {
|
|
65
65
|
return new File([await c(r)], e);
|
|
66
66
|
}
|
|
67
|
-
function
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
183
|
-
function
|
|
193
|
+
const M = () => !0;
|
|
194
|
+
function v(e, r = M) {
|
|
184
195
|
return new ReadableStream({
|
|
185
196
|
async pull(n) {
|
|
186
|
-
const a = await
|
|
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
|
|
210
|
+
async function O(e) {
|
|
200
211
|
const t = new DataView((await c(e, 4)).buffer).getUint32(0, !0);
|
|
201
|
-
return t === h ? await
|
|
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
|
|
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 =
|
|
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 ===
|
|
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(
|
|
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 +
|
|
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
|
|
262
|
+
function C(e) {
|
|
252
263
|
return e[e.byteLength - 1] == 47;
|
|
253
264
|
}
|
|
254
|
-
async function
|
|
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
|
|
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
|
|
275
|
-
if (t <=
|
|
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
|
|
292
|
-
return
|
|
293
|
-
|
|
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
|
|
307
|
+
function Z(e) {
|
|
297
308
|
let r;
|
|
298
309
|
return new ReadableStream({
|
|
299
310
|
async start() {
|
|
300
|
-
r = await
|
|
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
|
|
315
|
-
const r =
|
|
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
|
|
361
|
+
function W() {
|
|
351
362
|
let e = 0, r = [];
|
|
352
363
|
return new TransformStream({
|
|
353
364
|
transform(t, n) {
|
|
354
|
-
t.firstByteAt > e +
|
|
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
|
|
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,
|
|
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
|
|
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
|
|
413
|
-
const t = await
|
|
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
|
|
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
|
|
435
|
-
return r === void 0 && (r = await
|
|
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
|
|
458
|
+
return q(e).pipeThrough(j());
|
|
448
459
|
}
|
|
449
|
-
function
|
|
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 ?
|
|
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 =
|
|
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:
|
|
502
|
+
diskNumber: 0,
|
|
492
503
|
internalAttributes: 0,
|
|
493
504
|
externalAttributes: 0
|
|
494
|
-
}, l =
|
|
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:
|
|
513
|
+
numberOfDisks: 0,
|
|
503
514
|
centralDirectoryOffset: n,
|
|
504
515
|
centralDirectorySize: a,
|
|
505
|
-
centralDirectoryStartDisk:
|
|
516
|
+
centralDirectoryStartDisk: 0,
|
|
506
517
|
numberCentralDirectoryRecordsOnThisDisk: e.size,
|
|
507
518
|
numberCentralDirectoryRecords: e.size,
|
|
508
519
|
comment: new Uint8Array(0)
|
|
509
|
-
}, s =
|
|
520
|
+
}, s = X(i);
|
|
510
521
|
t.enqueue(s), e.clear();
|
|
511
522
|
}
|
|
512
523
|
});
|
|
513
524
|
}
|
|
514
|
-
function
|
|
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
|
|
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
|
|
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
|
-
|
|
548
|
+
E as StreamedFile,
|
|
538
549
|
c as collectBytes,
|
|
539
|
-
|
|
550
|
+
ae as collectFile,
|
|
540
551
|
ie as decodeRemoteZip,
|
|
541
552
|
p as decodeZip,
|
|
542
553
|
se as encodeZip,
|
|
543
|
-
|
|
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":";;AAMO,SAASA,KAAoBC,GAAsB;AACzD,QAAMC,IAAS,IAAI;AAAA,IAClBD,EAAO,OAAO,CAACE,GAAKC,MAAUD,IAAMC,EAAM,QAAQ,CAAC;AAAA,EAAA;AAEpD,MAAIC,IAAS;AACb,aAAWD,KAASH;AACnB,IAAAC,EAAO,IAAIE,GAAOC,CAAM,GACxBA,KAAUD,EAAM;AAEjB,SAAOF;AACR;ACNO,SAASI,EAAYC,GAAqB;AAChD,MAAIA,MAAe,QAAW;AAC7B,QAAIC,IAAM,IAAI,WAAA;AACd,WAAO,IAAI,gBAAwC;AAAA,MAClD,UAAUC,GAAO;AAChB,QAAAD,IAAMR,EAAiBQ,GAAKC,CAAK;AAAA,MAClC;AAAA,MAEA,MAAMC,GAAY;AACjB,QAAAA,EAAW,QAAQF,CAAG;AAAA,MACvB;AAAA,IAAA,CACA;AAAA,EACF,OAAO;AACN,UAAMG,IAAS,IAAI,YAAYJ,KAAc,CAAC;AAC9C,QAAIF,IAAS;AACb,WAAO,IAAI,gBAAwC;AAAA,MAClD,UAAUI,GAAO;AAEhB,QADa,IAAI,WAAWE,CAAM,EAC7B,IAAIF,GAAOJ,CAAM,GACtBA,KAAUI,EAAM;AAAA,MACjB;AAAA,MAEA,MAAMC,GAAY;AACjB,QAAAA,EAAW,QAAQ,IAAI,WAAWC,CAAM,CAAC;AAAA,MAC1C;AAAA,IAAA,CACA;AAAA,EACF;AACD;AC9BO,SAASC,EAAWC,GAAoCC,GAAe;AAC7E,MAAIA,MAAU;AACb,WAAO,IAAI,eAAe;AAAA,MACzB,MAAMJ,GAAY;AACjB,QAAAA,EAAW,MAAA;AAAA,MACZ;AAAA,IAAA,CACA;AAEF,QAAMK,IAASF,EAAO,UAAU,EAAE,MAAM,QAAQ;AAChD,MAAIR,IAAS;AACb,SAAO,IAAI,eAAe;AAAA,IACzB,MAAM,KAAKK,GAAY;AACtB,YAAM,EAAE,OAAAM,GAAO,MAAAC,MAAS,MAAMF,EAAO;AAAA,QACpC,IAAI,WAAWD,IAAQT,CAAM;AAAA,MAAA;AAE9B,UAAIY,GAAM;AACT,QAAAF,EAAO,YAAA,GACPL,EAAW,MAAA;AACX;AAAA,MACD;AACA,MAAAL,KAAUW,EAAM,QAChBN,EAAW,QAAQM,CAAK,GAEpBX,KAAUS,MACbC,EAAO,YAAA,GACPL,EAAW,MAAA;AAAA,IAEb;AAAA,IACA,SAAS;AACR,MAAAK,EAAO,OAAA;AAAA,IACR;AAAA,EAAA,CACA;AACF;AC7BA,eAAsBG,EACrBL,GACAC,GACC;AACD,SAAIA,MAAU,WACbD,IAASD,EAAWC,GAAQC,CAAK,IAG3B,MAAMD,EACX,YAAYP,EAAYQ,CAAK,CAAC,EAC9B,YACA,KAAA,EACA,KAAK,CAAC,EAAE,OAAAE,EAAA,MAAYA,CAAM;AAC7B;ACdA,eAAsBG,GACrBC,GACAP,GACC;AAED,SAAO,IAAI,KAAK,CAAC,MAAMK,EAAaL,CAAM,CAAC,GAAGO,CAAQ;AACvD;ACPO,SAASC,EACfC,GAKC;AACD,MAAIA,aAA8B;AACjC,WAAOA;AAGR,MAAIC;AACJ,SAAI,OAAO,iBAAiBD,IAC3BC,IAAWD,EAAmB,OAAO,aAAa,EAAA,IACxC,OAAO,YAAYA,IAC7BC,IAAWD,EAAmB,OAAO,QAAQ,EAAA,IAE7CC,IAAWD,GAGL,IAAI,eAAkB;AAAA,IAC5B,MAAM,KAAKZ,GAAY;AACtB,YAAM,EAAE,MAAAO,GAAM,OAAAD,EAAA,IAAU,MAAMO,EAAS,KAAA;AACvC,UAAIN,GAAM;AACT,QAAAP,EAAW,MAAA;AACX;AAAA,MACD;AACA,MAAAA,EAAW,QAAQM,CAAK;AAAA,IACzB;AAAA,EAAA,CACA;AACF;AChCO,MAAMQ,WAAqB,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYtC,YACCC,GACAC,GACAC,GACC;AACD,UAAM,CAAA,GAAID,GAAM,EAAE,MAAMC,KAAA,gBAAAA,EAAS,MAAM,GACvC,KAAK,iBAAiBF,GACtB,KAAK,WAAWE,KAAA,gBAAAA,EAAS;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOS,QAAc;AACtB,UAAM,IAAI,MAAM,2CAA2C;AAAA,EAC5D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOS,SAAS;AACjB,WAAO,KAAK;AAAA,EACb;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAe,OAAO;AACrB,WAAO,IAAI,YAAA,EAAc,OAAO,MAAM,KAAK,aAAa;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAe,cAAc;AAC5B,WAAO,MAAMT,EAAa,KAAK,QAAQ;AAAA,EACxC;AACD;ACnDK,eAAe,UAAU,OAAO,aAAa,MAEjD,eAAe,UAAU,OAAO,aAAa,IAAI,mBAAmB;AACnE,QAAMH,IAAS,KAAK,UAAA;AACpB,MAAI;AACH,eAAa;AACZ,YAAM,EAAE,MAAAE,GAAM,OAAAD,EAAA,IAAU,MAAMD,EAAO,KAAA;AACrC,UAAIE;AACH;AAED,YAAMD;AAAA,IACP;AAAA,EACD,UAAA;AACC,IAAAD,EAAO,YAAA;AAAA,EACR;AACD,GAEA,eAAe,UAAU;AAExB,eAAe,UAAU,OAAO,aAAa;AC/BxC,MAAMa,IAAmB,IACnBC,IAAiB,UACjBC,IAA8B,UAC9BC,IAAkC,WAGlCC,IAAmB,GACnBC,IAAsB;ACD5B,SAASC,EAAgBC,GAAkC;AACjE,SAAO,IAAI,gBAAsB;AAAA,IAChC,UAAU1B,GAAOC,GAAY;AAC5B,MAAIyB,EAAU1B,CAAK,KAClBC,EAAW,QAAQD,CAAK;AAAA,IAE1B;AAAA,EAAA,CACA;AACF;ACRO,SAAS2B,EAAatB,GAAmB;AAC/C,MAAIuB,IAAc;AAClB,SAAO,IAAI,gBAAwC;AAAA,IAClD,MAAM,UAAU5B,GAAOC,GAAY;AAClC,MAAK2B,MACJA,IAAc,IACd3B,EAAW,QAAQI,CAAK,IAEzBJ,EAAW,QAAQD,CAAK;AAAA,IACzB;AAAA,EAAA,CACA;AACF;ACXO,SAAS6B,EAAYxB,GAAmB;AAC9C,SAAO,IAAI,gBAAwC;AAAA,IAClD,MAAM,UAAUL,GAAOC,GAAY;AAClC,MAAAA,EAAW,QAAQD,CAAK;AAAA,IACzB;AAAA,IACA,MAAM,MAAMC,GAAY;AACvB,MAAAA,EAAW,QAAQI,CAAK;AAAA,IACzB;AAAA,EAAA,CACA;AACF;ACkBO,SAASyB,EACf1B,GACAsB,GACC;AACD,SAAOK,EAAwB3B,GAAQsB,CAAS,EAAE;AAAA,IACjD,IAAI,gBAAiC;AAAA,MACpC,MAAM,UAAUM,GAAU/B,GAAY;AACrC,cAAMgC,IAAO,IAAI;AAAA,UAChB,CAACD,EAAS,KAAK;AAAA,UACf,IAAI,YAAA,EAAc,OAAOA,EAAS,IAAI;AAAA,UACtC;AAAA,YACC,MAAMA,EAAS,cAAc,cAAc;AAAA,UAAA;AAAA,QAC5C;AAED,QAAA/B,EAAW,QAAQgC,CAAI;AAAA,MACxB;AAAA,IAAA,CACA;AAAA,EAAA;AAEH;AAEA,MAAMC,IAAoB,MAAM;AASzB,SAASH,EACf3B,GACAsB,IAEeQ,GACd;AAYD,SAXsB,IAAI,eAAyB;AAAA,IAClD,MAAM,KAAKjC,GAAY;AACtB,YAAMkC,IAAQ,MAAMC,EAAahC,CAAM;AACvC,UAAI,CAAC+B,GAAO;AACX,QAAAlC,EAAW,MAAA;AACX;AAAA,MACD;AACA,MAAAA,EAAW,QAAQkC,CAAK;AAAA,IACzB;AAAA,EAAA,CACA,EAGC;AAAA,IACAV,EAAa,CAAC,EAAE,WAAAY,EAAA,MAAgBA,MAAcjB,CAAc;AAAA,EAAA,EAE5D;AAAA,IACAK,EAAaC,CAAgB;AAAA,EAAA;AAEhC;AAQA,eAAeU,EAAahC,GAAoC;AAE/D,QAAMiC,IADU,IAAI,UAAU,MAAM5B,EAAaL,GAAQ,CAAC,GAAI,MAAM,EAC1C,UAAU,GAAG,EAAI;AAC3C,SAAIiC,MAAcjB,IACV,MAAMkB,EAAclC,GAAQ,EAAI,IAC7BiC,MAAchB,IACjB,MAAMkB,EAA0BnC,GAAQ,EAAI,IACzCiC,MAAcf,IACjB,MAAMkB,EAA6BpC,GAAQ,EAAI,IAEhD;AACR;AA4BA,eAAsBkC,EACrBlC,GACAqC,IAAgB,IACY;AAC5B,MAAI,CAACA,KACY,IAAI,UAAU,MAAMhC,EAAaL,GAAQ,CAAC,GAAI,MAAM,EAC1C,UAAU,GAAG,EAAI,MACzBgB;AACjB,WAAO;AAGT,QAAMsB,IAAO,IAAI,UAAU,MAAMjC,EAAaL,GAAQ,EAAE,GAAI,MAAM,GAC5DuC,IAAaD,EAAK,UAAU,IAAI,EAAI,GACpCE,IAAcF,EAAK,UAAU,IAAI,EAAI,GACrCP,IAA4B;AAAA,IACjC,WAAWf;AAAA,IACX,SAASsB,EAAK,UAAU,GAAG,EAAI;AAAA,IAC/B,gBAAgBA,EAAK,UAAU,GAAG,EAAI;AAAA,IACtC,mBAAmBA,EAAK,UAAU,GAAG,EAAI;AAAA,IACzC,kBAAkBA,EAAK,UAAU,GAAG,EAAI;AAAA,IACxC,kBAAkBA,EAAK,UAAU,GAAG,EAAI;AAAA,IACxC,KAAKA,EAAK,UAAU,IAAI,EAAI;AAAA,IAC5B,gBAAgBA,EAAK,UAAU,IAAI,EAAI;AAAA,IACvC,kBAAkBA,EAAK,UAAU,IAAI,EAAI;AAAA,EAAA;AAG1C,EAAAP,EAAM,OAAU,MAAM1B,EAAaL,GAAQuC,CAAU,GACrDR,EAAM,cAAiBU,EAAcV,EAAM,IAAK,GAChDA,EAAM,QAAW,MAAM1B,EAAaL,GAAQwC,CAAW;AASvD,MAAIE,IAAa3C,EAAWC,GAAQ+B,EAAM,cAAkB;AAE5D,MAAIA,EAAM,sBAAyBX,GAAqB;AAuBvD,UAAMuB,IAAS,IAAI,WAAW,EAAE;AAChC,IAAAA,EAAO,IAAI,CAAC,IAAM,KAAM,CAAI,CAAC;AAE7B,UAAMC,IAAS,IAAI,WAAW,CAAC,GACzBC,IAAa,IAAI,SAASD,EAAO,MAAM;AAC7C,IAAAC,EAAW,UAAU,GAAGd,EAAM,KAAM,EAAI,GACxCc,EAAW,UAAU,GAAGd,EAAM,mBAAoB,KAAK,IAAI,EAAI,GAC/DW,IAAaA,EACX,YAAYnB,EAAaoB,CAAM,CAAC,EAChC,YAAYlB,EAAYmB,CAAM,CAAC,EAC/B,YAAY,IAAI,oBAAoB,MAAM,CAAC;AAAA,EAC9C;AACA,SAAAb,EAAM,QAAW,MAAMW,EACrB,YAAYjD,EAAYsC,EAAM,gBAAmB,CAAC,EAClD,UAAA,EACA,OACA,KAAK,CAAC,EAAE,OAAA5B,EAAA,MAAYA,CAAM,GACrB4B;AACR;AAmCA,eAAsBI,EACrBnC,GACAqC,IAAgB,IACwB;AACxC,MAAI,CAACA,KACY,IAAI,UAAU,MAAMhC,EAAaL,GAAQ,CAAC,GAAI,MAAM,EAC1C,UAAU,GAAG,EAAI,MACzBiB;AACjB,WAAO;AAGT,QAAMqB,IAAO,IAAI,UAAU,MAAMjC,EAAaL,GAAQ,EAAE,GAAI,MAAM,GAC5DuC,IAAaD,EAAK,UAAU,IAAI,EAAI,GACpCE,IAAcF,EAAK,UAAU,IAAI,EAAI,GACrCQ,IAAoBR,EAAK,UAAU,IAAI,EAAI,GAC3CS,IAAmD;AAAA,IACxD,WAAW9B;AAAA,IACX,gBAAgBqB,EAAK,UAAU,GAAG,EAAI;AAAA,IACtC,eAAeA,EAAK,UAAU,GAAG,EAAI;AAAA,IACrC,gBAAgBA,EAAK,UAAU,GAAG,EAAI;AAAA,IACtC,mBAAmBA,EAAK,UAAU,GAAG,EAAI;AAAA,IACzC,kBAAkBA,EAAK,UAAU,GAAG,EAAI;AAAA,IACxC,kBAAkBA,EAAK,UAAU,IAAI,EAAI;AAAA,IACzC,KAAKA,EAAK,UAAU,IAAI,EAAI;AAAA,IAC5B,gBAAgBA,EAAK,UAAU,IAAI,EAAI;AAAA,IACvC,kBAAkBA,EAAK,UAAU,IAAI,EAAI;AAAA,IACzC,YAAYA,EAAK,UAAU,IAAI,EAAI;AAAA,IACnC,oBAAoBA,EAAK,UAAU,IAAI,EAAI;AAAA,IAC3C,oBAAoBA,EAAK,UAAU,IAAI,EAAI;AAAA,IAC3C,aAAaA,EAAK,UAAU,IAAI,EAAI;AAAA,EAAA;AAErC,SAAAS,EAAiB,aAChBA,EAAiB,cACjBhC,IACAwB,IACAO,IACAN,IACAO,EAAiB,iBACjB,GAEDA,EAAiB,OAAU,MAAM1C,EAAaL,GAAQuC,CAAU,GAChEQ,EAAiB,cAAiBN,EAAcM,EAAiB,IAAK,GACtEA,EAAiB,QAAW,MAAM1C,EAAaL,GAAQwC,CAAW,GAClEO,EAAiB,cAAiB,MAAM1C;AAAA,IACvCL;AAAA,IACA8C;AAAA,EAAA,GAEMC;AACR;AAEA,SAASN,EAAcO,GAAkB;AACxC,SAAOA,EAAKA,EAAK,aAAa,CAAC,KAAK;AACrC;AAwBA,eAAeZ,EACdpC,GACAqC,IAAgB,IACf;AACD,MAAI,CAACA,KACY,IAAI,UAAU,MAAMhC,EAAaL,GAAQ,CAAC,GAAI,MAAM,EAC1C,UAAU,GAAG,EAAI,MACzBkB;AACjB,WAAO;AAGT,QAAMoB,IAAO,IAAI,UAAU,MAAMjC,EAAaL,GAAQ,EAAE,GAAI,MAAM,GAC5DiD,IAAoD;AAAA,IACzD,WAAW/B;AAAA,IACX,eAAeoB,EAAK,UAAU,GAAG,EAAI;AAAA,IACrC,2BAA2BA,EAAK,UAAU,GAAG,EAAI;AAAA,IACjD,yCAAyCA,EAAK,UAAU,GAAG,EAAI;AAAA,IAC/D,+BAA+BA,EAAK,UAAU,GAAG,EAAI;AAAA,IACrD,sBAAsBA,EAAK,UAAU,GAAG,EAAI;AAAA,IAC5C,wBAAwBA,EAAK,UAAU,IAAI,EAAI;AAAA,EAAA,GAE1CY,IAAgBZ,EAAK,UAAU,IAAI,EAAI;AAC7C,SAAAW,EAAe,UAAa,MAAM5C,EAAaL,GAAQkD,CAAa,GAC7DD;AACR;AC/UA,MAAME,IAAwC,MAAM,MAC9CC,IAAyC,KAAK,MAC9CC,IAAoC,OAAO,OAAO,GAClDC,IAAiB,IAAIC,EAAU,EAAE,aAAa,IAAI,GAElDzB,IAAoB,MAAM;AAahC,eAAsB0B,GACrBC,GACAnC,IAEeQ,GACd;AACD,MAAIR,MAAcQ,GAAmB;AAGpC,UAAM4B,IAAW,MAAM,MAAMD,CAAG;AAChC,WAAO/B,EAAUgC,EAAS,IAAK;AAAA,EAChC;AAEA,QAAMC,IAAgB,MAAMC,EAAmBH,CAAG;AAClD,MAAIE,KAAiBN,GAAmC;AAEvD,UAAMK,IAAW,MAAM,MAAMD,CAAG;AAChC,WAAO/B,EAAUgC,EAAS,IAAK;AAAA,EAChC;AAIA,QAAMA,IAAW,MAAM,MAAMD,GAAK;AAAA,IACjC,SAAS;AAAA;AAAA;AAAA;AAAA,MAIR,OAAO;AAAA,MACP,mBAAmB;AAAA,IAAA;AAAA,EACpB,CACA,GAKK,CAACI,GAAYC,CAAc,IAAIJ,EAAS,KAAM,IAAA,GAG9CK,IAAaF,EAAW,UAAA,GACxB,EAAE,OAAOG,EAAA,IAAc,MAAMD,EAAW,KAAA,GACxC,EAAE,MAAME,EAAA,IAAa,MAAMF,EAAW,KAAA;AAM5C,MALAA,EAAW,YAAA,GACXF,EAAW,OAAA,GAIP,GADoBG,KAAA,gBAAAA,EAAW,YAAW,KAAKC;AAIlD,WAAOvC,EAAUoC,CAAc;AAIhC,EAAAA,EAAe,OAAA;AACf,QAAMI,IAAS,MAAMC,EAAkBV,GAAKE,CAAa;AACzD,SAAOS,EAA8BF,CAAM,EACzC,YAAY7C,EAAaC,CAAS,CAAC,EACnC,YAAY+C,EAAA,CAAwB,EACpC;AAAA,IACAC,EAAwBJ,CAAM;AAAA,EAAA;AAEjC;AAQA,SAASE,EAA8BF,GAAqB;AAC3D,MAAIK;AAEJ,SAAO,IAAI,eAAsC;AAAA,IAChD,MAAM,QAAQ;AACb,MAAAA,IAAyB,MAAMC,EAA4BN,CAAM;AAAA,IAClE;AAAA,IACA,MAAM,KAAKrE,GAAY;AACtB,YAAMkC,IAAQ,MAAMI;AAAA,QACnBoC;AAAA,MAAA;AAED,UAAI,CAACxC,GAAO;AACX,QAAAlC,EAAW,MAAA;AACX;AAAA,MACD;AACA,MAAAA,EAAW,QAAQkC,CAAK;AAAA,IACzB;AAAA,EAAA,CACA;AACF;AAQA,eAAeyC,EAA4BN,GAAqB;AAC/D,QAAMO,IAAYtB;AAClB,MAAIJ,IAA+B,IAAI,WAAA,GAEnC2B,IAAaR,EAAO;AACxB,KAAG;AACF,IAAAQ,IAAa,KAAK,IAAI,GAAGA,IAAaD,CAAS;AAC/C,UAAME,IAAW,KAAK;AAAA,MACrBD,IAAaD,IAAY;AAAA,MACzBP,EAAO,SAAS;AAAA,IAAA,GAEXjE,IAAQ,MAAMI;AAAA,MACnB,MAAM6D,EAAO,YAAYQ,GAAYC,CAAQ;AAAA,IAAA;AAE9C,IAAA5B,IAAmB5D,EAAiBc,GAAQ8C,CAAgB;AAG5D,UAAM6B,IAAO,IAAI,SAAS3E,EAAO,MAAM;AACvC,aAAS4E,IAAID,EAAK,aAAa,GAAGC,KAAK,GAAGA,KAAK;AAC9C,UAAID,EAAK,UAAUC,GAAG,EAAI,MAAM3D;AAC/B;AAMD,YAAM4D,IAD2BD,IAAI,KACuB;AAC5D,UAAI9B,EAAiB,aAAa+B,IAA2B;AAC5D,cAAM,IAAI,MAAM,6BAA6B;AAI9C,YAAMC,IAAWH,EAAK,UAAUE,GAA0B,EAAI;AAC9D,UAAIC,IAAWL,GAAY;AAE1B,cAAMM,IAAe,MAAM3E;AAAA,UAC1B,MAAM6D,EAAO,YAAYa,GAAUL,IAAa,CAAC;AAAA,QAAA;AAElD,QAAA3B,IAAmB5D;AAAA,UAClB6F;AAAA,UACAjC;AAAA,QAAA;AAAA,MAEF,MAAA,CAAWgC,IAAWL,MAErB3B,IAAmBA,EAAiB;AAAA,QACnCgC,IAAWL;AAAA,MAAA;AAGb,aAAO,IAAI,KAAK,CAAC3B,CAAgB,CAAC,EAAE,OAAA;AAAA,IACrC;AAAA,EACD,SAAS2B,KAAc;AAEvB,QAAM,IAAI,MAAM,6BAA6B;AAC9C;AAQA,SAASL,IAAyB;AACjC,MAAIY,IAAiB,GACjBC,IAAwC,CAAA;AAC5C,SAAO,IAAI,gBAAgE;AAAA,IAC1E,UAAUtD,GAAU/B,GAAY;AAE/B,MACC+B,EAAS,cACTqD,IAAiB7B,MAEjBvD,EAAW,QAAQqF,CAAY,GAC/BA,IAAe,CAAA,IAEhBD,IAAiBrD,EAAS,YAC1BsD,EAAa,KAAKtD,CAAQ;AAAA,IAC3B;AAAA,IACA,MAAM/B,GAAY;AACjB,MAAAA,EAAW,QAAQqF,CAAY;AAAA,IAChC;AAAA,EAAA,CACA;AACF;AAQA,SAASZ,EACRJ,GAC2D;AAa3D,MAAIiB,IAAmB,IACnBC,IAAqB,GACrBC;AACJ,QAAMC,IAEF,CAAA,GAKEC,IAAW,IAAI,eAAwC;AAAA,IAC5D,MAAMC,GAAY3F,GAAY;AAC7B,MAAK2F,EAAW,WAGhB,EAAEJ,GAKFK,EAAkBvB,GAAQsB,CAAU,EAClC,KAAK,CAACE,MAAe;AACrB,QAAAJ,EAAY,KAAK,CAACE,GAAYE,CAAU,CAAC;AAAA,MAC1C,CAAC,EACA,MAAM,CAACC,MAAM;AACb,QAAA9F,EAAW,MAAM8F,CAAC;AAAA,MACnB,CAAC,EACA,QAAQ,MAAM;AACd,UAAEP;AAAA,MACH,CAAC;AAAA,IACH;AAAA,IACA,QAAQ;AACP,MAAAD,IAAmB,IACnBE,EAAmB,MAAA;AAAA,IACpB;AAAA,IACA,MAAM,QAAQ;AACb,MAAAF,IAAmB;AAAA,IACpB;AAAA,EAAA,CACA;AAuDD,SAAO;AAAA,IACN,UApDgB,IAAI,eAA0B;AAAA,MAC9C,MAAMtF,GAAY;AACjB,QAAAwF,IAAqBxF;AAAA,MACtB;AAAA,MACA,MAAM,KAAKA,GAAY;AACtB,mBAAa;AAKZ,cAHCsF,KACA,CAACG,EAAY,UACbF,MAAuB,GACA;AACvB,YAAAvF,EAAW,MAAA;AACX;AAAA,UACD;AAMA,cAD4B,CAACyF,EAAY,QAChB;AACxB,kBAAM,IAAI,QAAQ,CAACM,MAAY,WAAWA,GAAS,EAAE,CAAC;AACtD;AAAA,UACD;AAEA,gBAAM,CAACC,GAAgB7F,CAAM,IAAIsF,EAAY,CAAC,GACxCzD,IAAO,MAAMK,EAAclC,CAAM;AAIvC,cADwB,CAAC6B,GACJ;AACpB,YAAAyD,EAAY,MAAA;AACZ;AAAA,UACD;AAQA,cAH8BO,EAAe;AAAA,YAC5C,CAAC9D,MAAUA,EAAM,SAASF,EAAK;AAAA,UAAA,GAOhC;AAAA,YAAAhC,EAAW,QAAQgC,CAAI;AACvB;AAAA;AAAA,QACD;AAAA,MACD;AAAA,IAAA,CACA;AAAA,IAIA,UAAA0D;AAAA,EAAA;AAEF;AAQA,eAAeE,EACdvB,GACAsB,GACC;AACD,QAAMM,IAAU,MAAMxC,EAAe,QAAA;AACrC,MAAI;AACH,UAAMyC,IAAeP,EAAWA,EAAW,SAAS,CAAC;AAKrD,WAJkB,MAAMtB,EAAO;AAAA,MAC9BsB,EAAW,CAAC,EAAE;AAAA,MACdO,EAAa;AAAA,IAAA;AAAA,EAGf,UAAA;AACC,IAAAD,EAAA;AAAA,EACD;AACD;AAKA,eAAelC,EAAmBH,GAAa;AAC9C,SAAO,MAAM,MAAMA,GAAK,EAAE,QAAQ,OAAA,CAAQ,EACxC,KAAK,CAACC,MAAaA,EAAS,QAAQ,IAAI,gBAAgB,CAAC,EACzD,KAAK,CAACC,MAAkB;AACxB,QAAI,CAACA;AACJ,YAAM,IAAI,MAAM,kCAAkC;AAGnD,UAAMqC,IAAe,SAASrC,GAAe,EAAE;AAC/C,QAAI,MAAMqC,CAAY,KAAKA,IAAe;AACzC,YAAM,IAAI,MAAM,kCAAkC;AAEnD,WAAOA;AAAA,EACR,CAAC;AACH;AAoBA,eAAe7B,EACdV,GACAE,GACuB;AACvB,SAAIA,MAAkB,WACrBA,IAAgB,MAAMC,EAAmBH,CAAG,IAGtC;AAAA,IACN,QAAQE;AAAA,IACR,aAAa,OAAOsC,GAAcC,MACjC,MAAM,MAAMzC,GAAK;AAAA,MAChB,SAAS;AAAA;AAAA,QAER,OAAO,SAASwC,CAAI,IAAIC,IAAK,CAAC;AAAA,QAC9B,mBAAmB;AAAA,MAAA;AAAA,IACpB,CACA,EAAE,KAAK,CAACxC,MAAaA,EAAS,IAAK;AAAA,EAAA;AAEvC;ACpYO,SAASyC,GACfC,GAC6B;AAC7B,SAAO5F,EAAiB4F,CAAK,EAAE,YAAYC,GAAoB;AAChE;AAOA,SAASA,IAAqB;AAC7B,QAAMC,wBAAqD,IAAA;AAC3D,MAAIC,IAAe;AACnB,SAAO,IAAI,gBAAkC;AAAA,IAC5C,MAAM,UAAU1E,GAAMhC,GAAY;AACjC,YAAM2G,IAAa,IAAI,WAAW,MAAM3E,EAAK,aAAa;AAuB1D,UAAI4E,IAAc,MAAMpG;AAAA,QACvB,IAAI,KAAK,CAACmG,CAAU,CAAC,EACnB,OAAA,EACA,YAAY,IAAI,kBAAkB,MAAM,CAAC;AAAA,MAAA;AAG5C,YAAME,IAAU,IAAI,SAASD,EAAW,MAAM,EAAE;AAAA,QAC/CA,EAAW,aAAa;AAAA,QACxB;AAAA,MAAA;AAGD,MAAAA,IAAaA,EAAW,MAAM,IAAIA,EAAW,aAAa,CAAC;AAE3D,YAAME,IAAc,IAAI,YAAA,EAAc,OAAO9E,EAAK,IAAI,GAChD+E,IAA2B;AAAA,QAChC,WAAW5F;AAAA,QACX,SAAS;AAAA,QACT,gBAAgB;AAAA,QAChB,mBACCa,EAAK,SAAS,eAAe4E,EAAW,eAAe,IACpDtF,IACAC;AAAA,QACJ,kBAAkB;AAAA,QAClB,kBAAkB;AAAA,QAClB,KAAKsF;AAAA,QACL,gBAAgBD,EAAW;AAAA,QAC3B,kBAAkBD,EAAW;AAAA,QAC7B,MAAMG;AAAA,QACN,OAAO,IAAI,WAAW,CAAC;AAAA,MAAA;AAExB,MAAAL,EAAsB,IAAIC,GAAcK,CAAY;AAEpD,YAAMC,IAAcC,EAAsBF,CAAY;AACtD,MAAA/G,EAAW,QAAQgH,CAAW,GAC9BN,KAAgBM,EAAY,YAE5BhH,EAAW,QAAQ4G,CAAU,GAC7BF,KAAgBE,EAAW;AAAA,IAC5B;AAAA,IACA,MAAM5G,GAAY;AACjB,YAAMkH,IAAyBR;AAC/B,UAAIS,IAAuB;AAC3B,iBAAW;AAAA,QACVC;AAAA,QACAtE;AAAA,MAAA,KACI2D,EAAsB,WAAW;AACrC,cAAMY,IAAwD;AAAA,UAC7D,GAAGvE;AAAA,UACH,WAAW1B;AAAA,UACX,aAAa,IAAI,WAAW,CAAC;AAAA,UAC7B,YAAY;AAAA,UACZ,oBAAoB;AAAA,UACpB,oBAAoB;AAAA,QAErB,GACMkG,IAA6BC;AAAA,UAClCF;AAAA,UACAD;AAAA,QAAA;AAED,QAAApH,EAAW,QAAQsH,CAA0B,GAC7CH,KAAwBG,EAA2B;AAAA,MACpD;AACA,YAAME,IAAgD;AAAA,QACrD,WAAWnG;AAAA,QACX,eAAe;AAAA,QACf,wBAAA6F;AAAA,QACA,sBAAAC;AAAA,QACA,2BAA2B;AAAA,QAC3B,yCACCV,EAAsB;AAAA,QACvB,+BAA+BA,EAAsB;AAAA,QACrD,SAAS,IAAI,WAAW,CAAC;AAAA,MAAA,GAEpBgB,IACLC,EAA0BF,CAAmB;AAC9C,MAAAxH,EAAW,QAAQyH,CAAwB,GAC3ChB,EAAsB,MAAA;AAAA,IACvB;AAAA,EAAA,CACA;AACF;AAwBA,SAASQ,EAAsB/E,GAAmB;AACjD,QAAMjC,IAAS,IAAI;AAAA,IAClB,KAAKiC,EAAM,KAAK,aAAaA,EAAM,MAAM;AAAA,EAAA,GAEpC6C,IAAO,IAAI,SAAS9E,CAAM;AAChC,EAAA8E,EAAK,UAAU,GAAG7C,EAAM,WAAW,EAAI,GACvC6C,EAAK,UAAU,GAAG7C,EAAM,SAAS,EAAI,GACrC6C,EAAK,UAAU,GAAG7C,EAAM,gBAAgB,EAAI,GAC5C6C,EAAK,UAAU,GAAG7C,EAAM,mBAAmB,EAAI,GAC/C6C,EAAK,UAAU,IAAI7C,EAAM,kBAAkB,EAAI,GAC/C6C,EAAK,UAAU,IAAI7C,EAAM,kBAAkB,EAAI,GAC/C6C,EAAK,UAAU,IAAI7C,EAAM,KAAK,EAAI,GAClC6C,EAAK,UAAU,IAAI7C,EAAM,gBAAgB,EAAI,GAC7C6C,EAAK,UAAU,IAAI7C,EAAM,kBAAkB,EAAI,GAC/C6C,EAAK,UAAU,IAAI7C,EAAM,KAAK,YAAY,EAAI,GAC9C6C,EAAK,UAAU,IAAI7C,EAAM,MAAM,YAAY,EAAI;AAC/C,QAAMyF,IAAc,IAAI,WAAW1H,CAAM;AACzC,SAAA0H,EAAY,IAAIzF,EAAM,MAAM,EAAE,GAC9ByF,EAAY,IAAIzF,EAAM,OAAO,KAAKA,EAAM,KAAK,UAAU,GAChDyF;AACR;AA+BA,SAASJ,EACRrF,GACA0F,GACC;AACD,QAAM3H,IAAS,IAAI;AAAA,IAClB,KAAKiC,EAAM,KAAK,aAAaA,EAAM,MAAM;AAAA,EAAA,GAEpC6C,IAAO,IAAI,SAAS9E,CAAM;AAChC,EAAA8E,EAAK,UAAU,GAAG7C,EAAM,WAAW,EAAI,GACvC6C,EAAK,UAAU,GAAG7C,EAAM,gBAAgB,EAAI,GAC5C6C,EAAK,UAAU,GAAG7C,EAAM,eAAe,EAAI,GAC3C6C,EAAK,UAAU,GAAG7C,EAAM,gBAAgB,EAAI,GAC5C6C,EAAK,UAAU,IAAI7C,EAAM,mBAAmB,EAAI,GAChD6C,EAAK,UAAU,IAAI7C,EAAM,kBAAkB,EAAI,GAC/C6C,EAAK,UAAU,IAAI7C,EAAM,kBAAkB,EAAI,GAC/C6C,EAAK,UAAU,IAAI7C,EAAM,KAAK,EAAI,GAClC6C,EAAK,UAAU,IAAI7C,EAAM,gBAAgB,EAAI,GAC7C6C,EAAK,UAAU,IAAI7C,EAAM,kBAAkB,EAAI,GAC/C6C,EAAK,UAAU,IAAI7C,EAAM,KAAK,YAAY,EAAI,GAC9C6C,EAAK,UAAU,IAAI7C,EAAM,MAAM,YAAY,EAAI,GAC/C6C,EAAK,UAAU,IAAI7C,EAAM,YAAY,YAAY,EAAI,GACrD6C,EAAK,UAAU,IAAI7C,EAAM,YAAY,EAAI,GACzC6C,EAAK,UAAU,IAAI7C,EAAM,oBAAoB,EAAI,GACjD6C,EAAK,UAAU,IAAI7C,EAAM,oBAAoB,EAAI,GACjD6C,EAAK,UAAU,IAAI6C,GAAiB,EAAI;AACxC,QAAMD,IAAc,IAAI,WAAW1H,CAAM;AACzC,SAAA0H,EAAY,IAAIzF,EAAM,MAAM,EAAE,GAC9ByF,EAAY,IAAIzF,EAAM,OAAO,KAAKA,EAAM,KAAK,UAAU,GAChDyF;AACR;AAoBA,SAASD,EAA0BxF,GAAiC;AACnE,QAAMjC,IAAS,IAAI,YAAY,KAAKiC,EAAM,QAAQ,UAAU,GACtD6C,IAAO,IAAI,SAAS9E,CAAM;AAChC,EAAA8E,EAAK,UAAU,GAAG7C,EAAM,WAAW,EAAI,GACvC6C,EAAK,UAAU,GAAG7C,EAAM,eAAe,EAAI,GAC3C6C,EAAK,UAAU,GAAG7C,EAAM,2BAA2B,EAAI,GACvD6C,EAAK,UAAU,GAAG7C,EAAM,yCAAyC,EAAI,GACrE6C,EAAK,UAAU,IAAI7C,EAAM,+BAA+B,EAAI,GAC5D6C,EAAK,UAAU,IAAI7C,EAAM,sBAAsB,EAAI,GACnD6C,EAAK,UAAU,IAAI7C,EAAM,wBAAwB,EAAI,GACrD6C,EAAK,UAAU,IAAI7C,EAAM,QAAQ,YAAY,EAAI;AACjD,QAAMyF,IAAc,IAAI,WAAW1H,CAAM;AACzC,SAAA0H,EAAY,IAAIzF,EAAM,SAAS,EAAE,GAC1ByF;AACR;"}
|
|
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.
|
|
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": "
|
|
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.
|
|
40
|
-
"ws": "
|
|
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.
|
|
46
|
-
"@php-wasm/util": "3.0.
|
|
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"
|
package/utils/streamed-file.d.ts
CHANGED
|
@@ -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<
|
|
46
|
+
arrayBuffer(): Promise<ArrayBuffer>;
|
|
43
47
|
}
|