@@ -89,6 +89,9 @@ export class PenumbraZipWriter extends EventTarget {
89
89
/** Current zip archive size */
90
90
private bytesWritten = 0 ;
91
91
92
+ /** Promise representing completion of the zip stream piping to the file sink */
93
+ private pipePromise ?: Promise < void > ;
94
+
92
95
/**
93
96
* Penumbra zip writer constructor
94
97
* @param options - ZipOptions
@@ -150,13 +153,10 @@ export class PenumbraZipWriter extends EventTarget {
150
153
ReadableStream | null ,
151
154
] = saveBuffer ? readable . tee ( ) : [ readable , null ] ;
152
155
153
- /**
154
- * This is intentionally not awaited because it does not complete until the entire stream has finished.
155
- * We want the main caller to be able to error-handle the function for any errors during stream setup.
156
- *
157
- * The consumer can handle the event via the streams interface.
158
- */
159
- zipStream . pipeTo ( saveStream , { signal } ) . catch ( ( error : unknown ) => {
156
+ this . pipePromise = zipStream . pipeTo ( saveStream , { signal } ) ;
157
+ // Attach a rejection handler for logging to avoid unhandledrejection, but
158
+ // keep the original promise's rejection for callers that await done().
159
+ this . pipePromise . catch ( ( error : unknown ) => {
160
160
const finalError =
161
161
error instanceof Error
162
162
? error
@@ -371,6 +371,16 @@ export class PenumbraZipWriter extends EventTarget {
371
371
return size ;
372
372
}
373
373
374
+ /**
375
+ * Await completion of the underlying zip stream being written to the sink
376
+ * @returns Promise that resolves when the sink write completes
377
+ */
378
+ async done ( ) : Promise < void > {
379
+ if ( this . pipePromise ) {
380
+ await this . pipePromise ;
381
+ }
382
+ }
383
+
374
384
/** Cancel Penumbra zip writer */
375
385
abort ( ) : void {
376
386
if ( ! this . controller . signal . aborted ) {
0 commit comments