@@ -62,11 +62,21 @@ export class ApkgZipWriter {
6262 // Ensure stream is a Node.js Readable, not Web API ReadableStream
6363 const readableStream = stream instanceof Readable ? stream : Readable . from ( stream ) ;
6464
65- // Handle stream errors
66- readableStream . once ( 'error' , reject ) ;
67-
68- // Wait for stream to end before resolving
69- readableStream . once ( 'end' , ( ) => resolve ( ) ) ;
65+ // Set up error handler
66+ readableStream . once ( 'error' , ( err ) => {
67+ reject ( err ) ;
68+ } ) ;
69+
70+ // Set up end handler - must be before append() call
71+ readableStream . once ( 'end' , ( ) => {
72+ resolve ( ) ;
73+ } ) ;
74+
75+ // Check if stream is already ended/destroyed
76+ if ( readableStream . readableEnded || readableStream . destroyed ) {
77+ resolve ( ) ;
78+ return ;
79+ }
7080
7181 // archiver handles the stream internally and will queue it
7282 this . archive . append ( readableStream , { name : index . toString ( ) } ) ;
@@ -104,12 +114,23 @@ export class ApkgZipWriter {
104114 if ( this . finalized ) throw new Error ( 'Archive already finalized' ) ;
105115
106116 this . finalized = true ;
107- await this . archive . finalize ( ) ;
108117
109- // Wait for output stream to finish
118+ // Wait for both archive finalization AND output stream to finish
110119 return new Promise ( ( resolve , reject ) => {
120+ // Set up output stream listeners first
111121 this . output . once ( 'finish' , resolve ) ;
112122 this . output . once ( 'error' , reject ) ;
123+
124+ // Set up archive listener for completion
125+ this . archive . once ( 'end' , ( ) => {
126+ // Archive has written everything to output stream
127+ // Output stream should emit 'finish' soon
128+ } ) ;
129+
130+ this . archive . once ( 'error' , reject ) ;
131+
132+ // Finalize the archive (this starts the finalization process)
133+ this . archive . finalize ( ) . catch ( reject ) ;
113134 } ) ;
114135 }
115136
0 commit comments