11import { Entry as ZipEntry , open , Options as ZipOptions , ZipFile } from "yauzl" ;
2- import { Readable } from "stream" ;
2+ import { Readable , Transform } from "stream" ;
33import { dirname , join } from "path" ;
44import { WriteStream } from "fs" ;
55import { createWriteStream , ensureDir } from "fs-extra" ;
@@ -84,6 +84,7 @@ export async function openZipBuffer(
8484async function copyStream (
8585 readable : Readable ,
8686 writeStream : WriteStream ,
87+ bytesExtractedCallback ?: ( bytesExtracted : number ) => void ,
8788) : Promise < void > {
8889 return new Promise ( ( resolve , reject ) => {
8990 readable . on ( "error" , ( err ) => {
@@ -93,7 +94,17 @@ async function copyStream(
9394 resolve ( ) ;
9495 } ) ;
9596
96- readable . pipe ( writeStream ) ;
97+ readable
98+ . pipe (
99+ new Transform ( {
100+ transform ( chunk , _encoding , callback ) {
101+ bytesExtractedCallback ?.( chunk . length ) ;
102+ this . push ( chunk ) ;
103+ callback ( ) ;
104+ } ,
105+ } ) ,
106+ )
107+ . pipe ( writeStream ) ;
97108 } ) ;
98109}
99110
@@ -113,12 +124,14 @@ export type UnzipProgressCallback = (progress: UnzipProgress) => void;
113124 * @param zipFile
114125 * @param entry
115126 * @param rootDestinationPath
127+ * @param bytesExtractedCallback Called when bytes are extracted.
116128 * @return The number of bytes extracted.
117129 */
118130async function unzipFile (
119131 zipFile : ZipFile ,
120132 entry : ZipEntry ,
121133 rootDestinationPath : string ,
134+ bytesExtractedCallback ?: ( bytesExtracted : number ) => void ,
122135) : Promise < number > {
123136 const path = join ( rootDestinationPath , entry . fileName ) ;
124137
@@ -144,7 +157,7 @@ async function unzipFile(
144157 mode,
145158 } ) ;
146159
147- await copyStream ( readable , writeStream ) ;
160+ await copyStream ( readable , writeStream , bytesExtractedCallback ) ;
148161
149162 return entry . uncompressedSize ;
150163 }
@@ -194,13 +207,21 @@ export async function unzipToDirectory(
194207
195208 await taskRunner (
196209 entries . map ( ( entry ) => async ( ) => {
210+ let entryBytesExtracted = 0 ;
211+
197212 const totalEntryBytesExtracted = await unzipFile (
198213 zipFile ,
199214 entry ,
200215 destinationPath ,
216+ ( thisBytesExtracted ) => {
217+ entryBytesExtracted += thisBytesExtracted ;
218+ bytesExtracted += thisBytesExtracted ;
219+ reportProgress ( ) ;
220+ } ,
201221 ) ;
202222
203- bytesExtracted += totalEntryBytesExtracted ;
223+ // Should be 0, but just in case.
224+ bytesExtracted += - entryBytesExtracted + totalEntryBytesExtracted ;
204225
205226 filesExtracted ++ ;
206227 reportProgress ( ) ;
0 commit comments