1111import { UnarchiveAppendEvent , UnarchiveErrorEvent , UnarchiveEvent , UnarchiveEventType ,
1212 UnarchiveExtractEvent , UnarchiveFinishEvent , UnarchiveInfoEvent ,
1313 UnarchiveProgressEvent , UnarchiveStartEvent } from './events.js' ;
14+ import { getConnectedPort } from './common.js' ;
1415import { findMimeType } from '../file/sniffer.js' ;
1516
1617// Exported as a convenience (and also because this module used to contain these).
@@ -43,29 +44,6 @@ export {
4344 * @property {boolean= } debug Set to true for verbose unarchiver logging.
4445 */
4546
46- /**
47- * Connects the MessagePort to the unarchiver implementation (e.g. unzip.js). If Workers exist
48- * (e.g. web browsers or deno), imports the implementation inside a Web Worker. Otherwise, it
49- * dynamically imports the implementation inside the current JS context.
50- * The MessagePort is used for communication between host and implementation.
51- * @param {string } implFilename The decompressor implementation filename relative to this path
52- * (e.g. './unzip.js').
53- * @param {MessagePort } implPort The MessagePort to connect to the decompressor implementation.
54- * @returns {Promise<void> } The Promise resolves once the ports are connected.
55- */
56- const connectPortFn = async ( implFilename , implPort ) => {
57- if ( typeof Worker === 'undefined' ) {
58- return import ( `${ implFilename } ` ) . then ( implModule => implModule . connect ( implPort ) ) ;
59- }
60-
61- return new Promise ( ( resolve , reject ) => {
62- const workerScriptPath = new URL ( `./webworker-wrapper.js` , import . meta. url ) . href ;
63- const worker = new Worker ( workerScriptPath , { type : 'module' } ) ;
64- worker . postMessage ( { implSrc : implFilename } , [ implPort ] ) ;
65- resolve ( ) ;
66- } ) ;
67- } ;
68-
6947/**
7048 * Base class for all Unarchivers.
7149 */
@@ -82,13 +60,11 @@ export class Unarchiver extends EventTarget {
8260 * @param {ArrayBuffer } arrayBuffer The Array Buffer. Note that this ArrayBuffer must not be
8361 * referenced once it is sent to the Unarchiver, since it is marked as Transferable and sent
8462 * to the decompress implementation.
85- * @param {Function(string, MessagePort):Promise<*> } connectPortFn A function that takes a path
86- * to a JS decompression implementation (unzip.js) and connects it to a MessagePort.
8763 * @param {UnarchiverOptions|string } options An optional object of options, or a string
8864 * representing where the BitJS files are located. The string version of this argument is
8965 * deprecated.
9066 */
91- constructor ( arrayBuffer , connectPortFn , options = { } ) {
67+ constructor ( arrayBuffer , options = { } ) {
9268 super ( ) ;
9369
9470 if ( typeof options === 'string' ) {
@@ -104,13 +80,6 @@ export class Unarchiver extends EventTarget {
10480 */
10581 this . ab = arrayBuffer ;
10682
107- /**
108- * A factory method that connects a port to the decompress implementation.
109- * @type {Function(MessagePort): Promise<*> }
110- * @private
111- */
112- this . connectPortFn_ = connectPortFn ;
113-
11483 /**
11584 * @orivate
11685 * @type {boolean }
@@ -170,6 +139,7 @@ export class Unarchiver extends EventTarget {
170139 * Receive an event and pass it to the listener functions.
171140 *
172141 * @param {Object } obj
142+ * @returns {boolean } Returns true if the decompression is finished.
173143 * @private
174144 */
175145 handlePortEvent_ ( obj ) {
@@ -179,31 +149,36 @@ export class Unarchiver extends EventTarget {
179149 this . dispatchEvent ( evt ) ;
180150 if ( evt . type == UnarchiveEventType . FINISH ) {
181151 this . stop ( ) ;
152+ return true ;
182153 }
183154 } else {
184155 console . log ( `Unknown object received from port: ${ obj } ` ) ;
185156 }
157+ return false ;
186158 }
187159
188160 /**
189161 * Starts the unarchive by connecting the ports and sending the first ArrayBuffer.
162+ * @returns {Promise<void> } A Promise that resolves when the decompression is complete. While the
163+ * decompression is proceeding, you can send more bytes of the archive to the decompressor
164+ * using the update() method.
190165 */
191- start ( ) {
192- const me = this ;
193- const messageChannel = new MessageChannel ( ) ;
194- this . port_ = messageChannel . port1 ;
195- this . connectPortFn_ ( this . getScriptFileName ( ) , messageChannel . port2 ) . then ( ( ) => {
196- this . port_ . onerror = function ( e ) {
197- console . log ( 'Impl error: message = ' + e . message ) ;
198- throw e ;
166+ async start ( ) {
167+ this . port_ = await getConnectedPort ( this . getScriptFileName ( ) ) ;
168+ return new Promise ( ( resolve , reject ) => {
169+ this . port_ . onerror = ( evt ) => {
170+ console . log ( 'Impl error: message = ' + evt . message ) ;
171+ reject ( evt ) ;
199172 } ;
200173
201- this . port_ . onmessage = function ( e ) {
202- if ( typeof e . data == 'string' ) {
203- // Just log any strings the port pumps our way.
204- console . log ( e . data ) ;
174+ this . port_ . onmessage = ( evt ) => {
175+ if ( typeof evt . data == 'string' ) {
176+ // Just log any strings the implementation pumps our way.
177+ console . log ( evt . data ) ;
205178 } else {
206- me . handlePortEvent_ ( e . data ) ;
179+ if ( this . handlePortEvent_ ( evt . data ) ) {
180+ resolve ( ) ;
181+ }
207182 }
208183 } ;
209184
@@ -212,10 +187,11 @@ export class Unarchiver extends EventTarget {
212187 file : ab ,
213188 logToConsole : this . debugMode_ ,
214189 } , [ ab ] ) ;
215- this . ab = null ;
190+ this . ab = null ;
216191 } ) ;
217192 }
218193
194+ // TODO(bitjs): Test whether ArrayBuffers must be transferred...
219195 /**
220196 * Adds more bytes to the unarchiver.
221197 * @param {ArrayBuffer } ab The ArrayBuffer with more bytes in it. If opt_transferable is
@@ -258,7 +234,7 @@ export class Unzipper extends Unarchiver {
258234 * @param {UnarchiverOptions } options
259235 */
260236 constructor ( ab , options = { } ) {
261- super ( ab , connectPortFn , options ) ;
237+ super ( ab , options ) ;
262238 }
263239
264240 getMIMEType ( ) { return 'application/zip' ; }
@@ -271,7 +247,7 @@ export class Unrarrer extends Unarchiver {
271247 * @param {UnarchiverOptions } options
272248 */
273249 constructor ( ab , options = { } ) {
274- super ( ab , connectPortFn , options ) ;
250+ super ( ab , options ) ;
275251 }
276252
277253 getMIMEType ( ) { return 'application/x-rar-compressed' ; }
@@ -284,7 +260,7 @@ export class Untarrer extends Unarchiver {
284260 * @param {UnarchiverOptions } options
285261 */
286262 constructor ( ab , options = { } ) {
287- super ( ab , connectPortFn , options ) ;
263+ super ( ab , options ) ;
288264 }
289265
290266 getMIMEType ( ) { return 'application/x-tar' ; }
@@ -311,11 +287,11 @@ export function getUnarchiver(ab, options = {}) {
311287 const mimeType = findMimeType ( ab ) ;
312288
313289 if ( mimeType === 'application/x-rar-compressed' ) { // Rar!
314- unarchiver = new Unrarrer ( ab , connectPortFn , options ) ;
290+ unarchiver = new Unrarrer ( ab , options ) ;
315291 } else if ( mimeType === 'application/zip' ) { // PK (Zip)
316- unarchiver = new Unzipper ( ab , connectPortFn , options ) ;
292+ unarchiver = new Unzipper ( ab , options ) ;
317293 } else { // Try with tar
318- unarchiver = new Untarrer ( ab , connectPortFn , options ) ;
294+ unarchiver = new Untarrer ( ab , options ) ;
319295 }
320296 return unarchiver ;
321297}
0 commit comments