@push.rocks/smartarchive 5.1.0 β†’ 5.2.1

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.
Files changed (45) hide show
  1. package/dist_ts/00_commitinfo_data.js +1 -1
  2. package/dist_ts/classes.smartarchive.d.ts +4 -4
  3. package/dist_ts/classes.smartarchive.js +29 -24
  4. package/dist_ts/classes.tartools.d.ts +81 -6
  5. package/dist_ts/classes.tartools.js +202 -16
  6. package/dist_ts/index.d.ts +2 -2
  7. package/dist_ts/index.js +3 -3
  8. package/dist_ts/plugins.d.ts +3 -1
  9. package/dist_ts/plugins.js +5 -2
  10. package/dist_ts_shared/bzip2/bititerator.d.ts +6 -0
  11. package/dist_ts_shared/bzip2/bititerator.js +50 -0
  12. package/dist_ts_shared/bzip2/bzip2.d.ts +29 -0
  13. package/dist_ts_shared/bzip2/bzip2.js +398 -0
  14. package/dist_ts_shared/bzip2/index.d.ts +5 -0
  15. package/dist_ts_shared/bzip2/index.js +92 -0
  16. package/dist_ts_shared/classes.bzip2tools.d.ts +10 -0
  17. package/dist_ts_shared/classes.bzip2tools.js +14 -0
  18. package/dist_ts_shared/classes.gziptools.d.ts +26 -0
  19. package/dist_ts_shared/classes.gziptools.js +38 -0
  20. package/dist_ts_shared/classes.tartools.d.ts +30 -0
  21. package/dist_ts_shared/classes.tartools.js +78 -0
  22. package/dist_ts_shared/classes.ziptools.d.ts +31 -0
  23. package/dist_ts_shared/classes.ziptools.js +103 -0
  24. package/dist_ts_shared/errors.d.ts +44 -0
  25. package/dist_ts_shared/errors.js +62 -0
  26. package/dist_ts_shared/index.d.ts +8 -0
  27. package/dist_ts_shared/index.js +14 -0
  28. package/dist_ts_shared/interfaces.d.ts +129 -0
  29. package/dist_ts_shared/interfaces.js +2 -0
  30. package/dist_ts_shared/plugins.d.ts +9 -0
  31. package/dist_ts_shared/plugins.js +14 -0
  32. package/dist_ts_web/00_commitinfo_data.d.ts +8 -0
  33. package/dist_ts_web/00_commitinfo_data.js +9 -0
  34. package/dist_ts_web/index.d.ts +1 -0
  35. package/dist_ts_web/index.js +4 -0
  36. package/dist_ts_web/plugins.d.ts +1 -0
  37. package/dist_ts_web/plugins.js +4 -0
  38. package/package.json +7 -5
  39. package/readme.md +154 -46
  40. package/ts/00_commitinfo_data.ts +1 -1
  41. package/ts/classes.smartarchive.ts +28 -23
  42. package/ts/classes.tartools.ts +235 -14
  43. package/ts/index.ts +2 -2
  44. package/ts/plugins.ts +4 -0
  45. package/ts_web/00_commitinfo_data.ts +1 -1
@@ -0,0 +1 @@
1
+ export * from '../ts_shared/index.js';
@@ -0,0 +1,4 @@
1
+ // ts_web - Browser-compatible entry point
2
+ // Re-exports everything from ts_shared
3
+ export * from '../ts_shared/index.js';
4
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90c193ZWIvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsMENBQTBDO0FBQzFDLHVDQUF1QztBQUV2QyxjQUFjLHVCQUF1QixDQUFDIn0=
@@ -0,0 +1 @@
1
+ export * from '../ts_shared/plugins.js';
@@ -0,0 +1,4 @@
1
+ // Browser-compatible plugins for ts_web
2
+ // Re-export from ts_shared
3
+ export * from '../ts_shared/plugins.js';
4
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzX3dlYi9wbHVnaW5zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHdDQUF3QztBQUN4QywyQkFBMkI7QUFDM0IsY0FBYyx5QkFBeUIsQ0FBQyJ9
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@push.rocks/smartarchive",
3
- "version": "5.1.0",
3
+ "version": "5.2.1",
4
4
  "description": "A library for working with archive files, providing utilities for compressing and decompressing data.",
5
5
  "main": "dist_ts/index.js",
6
6
  "typings": "dist_ts/index.d.ts",
@@ -35,13 +35,15 @@
35
35
  "@push.rocks/smartunique": "^3.0.9",
36
36
  "@push.rocks/smarturl": "^3.1.0",
37
37
  "fflate": "^0.8.2",
38
- "file-type": "^21.2.0",
39
- "modern-tar": "^0.7.3"
38
+ "file-type": "^21.3.0",
39
+ "modern-tar": "^0.7.3",
40
+ "tar-stream": "^3.1.7"
40
41
  },
41
42
  "devDependencies": {
42
- "@git.zone/tsbuild": "^4.0.2",
43
+ "@git.zone/tsbuild": "^4.1.2",
43
44
  "@git.zone/tsrun": "^2.0.1",
44
- "@git.zone/tstest": "^3.1.4"
45
+ "@git.zone/tstest": "^3.1.4",
46
+ "@types/tar-stream": "^3.1.3"
45
47
  },
46
48
  "private": false,
47
49
  "files": [
package/readme.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @push.rocks/smartarchive πŸ“¦
2
2
 
3
- A powerful, streaming-first archive manipulation library with a fluent builder API. Works seamlessly in Node.js and Deno.
3
+ A powerful, streaming-first archive manipulation library with a fluent builder API. Works seamlessly in **Node.js**, **Deno**, and **browsers**.
4
4
 
5
5
  ## Issue Reporting and Security
6
6
 
@@ -12,11 +12,12 @@ For reporting bugs, issues, or security vulnerabilities, please visit [community
12
12
  - 🌊 **Streaming-first architecture** – Process large archives without memory constraints
13
13
  - ✨ **Fluent builder API** – Chain methods for readable, expressive code
14
14
  - 🎯 **Smart detection** – Automatically identifies archive types via magic bytes
15
- - ⚑ **High performance** – Built on `tar-stream` and `fflate` for speed
15
+ - ⚑ **High performance** – Built on `modern-tar` and `fflate` for speed
16
16
  - πŸ”§ **Flexible I/O** – Work with files, URLs, streams, and buffers seamlessly
17
17
  - πŸ› οΈ **Modern TypeScript** – Full type safety and excellent IDE support
18
18
  - πŸ”„ **Dual-mode operation** – Extract existing archives OR create new ones
19
- - πŸ¦• **Cross-runtime** – Works in both Node.js and Deno environments
19
+ - πŸ¦• **Cross-runtime** – Works in Node.js, Deno, and browsers
20
+ - 🌐 **Browser-ready** – Dedicated browser bundle with zero Node.js dependencies
20
21
 
21
22
  ## Installation πŸ“₯
22
23
 
@@ -71,6 +72,59 @@ await SmartArchive.create()
71
72
  .extract('./node_modules/lodash');
72
73
  ```
73
74
 
75
+ ## Browser Usage 🌐
76
+
77
+ smartarchive provides a dedicated browser-compatible bundle with no Node.js dependencies:
78
+
79
+ ```typescript
80
+ // Import from the /web subpath for browser environments
81
+ import { TarTools, ZipTools, GzipTools, Bzip2Tools } from '@push.rocks/smartarchive/web';
82
+
83
+ // Create a TAR archive in the browser
84
+ const tarTools = new TarTools();
85
+ const tarBuffer = await tarTools.packFiles([
86
+ { archivePath: 'hello.txt', content: 'Hello from the browser!' },
87
+ { archivePath: 'data.json', content: JSON.stringify({ browser: true }) }
88
+ ]);
89
+
90
+ // Create a TAR.GZ archive
91
+ const tgzBuffer = await tarTools.packFilesToTarGz([
92
+ { archivePath: 'file.txt', content: 'Compressed!' }
93
+ ], 6);
94
+
95
+ // Extract a TAR archive
96
+ const entries = await tarTools.extractTar(tarBuffer);
97
+ for (const entry of entries) {
98
+ console.log(`${entry.path}: ${entry.content.length} bytes`);
99
+ }
100
+
101
+ // Work with ZIP files
102
+ const zipTools = new ZipTools();
103
+ const zipBuffer = await zipTools.createZip([
104
+ { archivePath: 'doc.txt', content: 'Document content' }
105
+ ], 6);
106
+
107
+ const zipEntries = await zipTools.extractZip(zipBuffer);
108
+
109
+ // GZIP compression
110
+ const gzipTools = new GzipTools();
111
+ const compressed = gzipTools.compressSync(new TextEncoder().encode('Hello World'), 6);
112
+ const decompressed = gzipTools.decompressSync(compressed);
113
+ ```
114
+
115
+ ### Browser Bundle Exports
116
+
117
+ The `/web` subpath exports these browser-compatible tools:
118
+
119
+ | Export | Description |
120
+ |--------|-------------|
121
+ | `TarTools` | Create and extract TAR and TAR.GZ archives |
122
+ | `ZipTools` | Create and extract ZIP archives |
123
+ | `GzipTools` | GZIP compression and decompression |
124
+ | `Bzip2Tools` | BZIP2 decompression (extraction only) |
125
+
126
+ > πŸ’‘ **Note:** The browser bundle does **not** include `SmartArchive` (which requires filesystem access). Use the individual tool classes for browser applications.
127
+
74
128
  ## Core Concepts πŸ’‘
75
129
 
76
130
  ### Fluent Builder Pattern
@@ -294,51 +348,107 @@ await SmartArchive.create()
294
348
  // Use GzipTools directly for compression/decompression
295
349
  const gzipTools = new GzipTools();
296
350
 
297
- // Compress a buffer
298
- const compressed = await gzipTools.compress(Buffer.from('Hello World'), 9);
299
- const decompressed = await gzipTools.decompress(compressed);
351
+ // Compress a buffer (sync and async available)
352
+ const input = new TextEncoder().encode('Hello World');
353
+ const compressed = gzipTools.compressSync(input, 9);
354
+ const decompressed = gzipTools.decompressSync(compressed);
300
355
 
301
- // Synchronous operations
302
- const compressedSync = gzipTools.compressSync(inputBuffer, 6);
303
- const decompressedSync = gzipTools.decompressSync(compressedSync);
356
+ // Async versions (internally use sync for cross-runtime compatibility)
357
+ const compressedAsync = await gzipTools.compress(input, 6);
358
+ const decompressedAsync = await gzipTools.decompress(compressedAsync);
359
+ ```
304
360
 
305
- // Streaming
306
- const compressStream = gzipTools.getCompressionStream(6);
307
- const decompressStream = gzipTools.getDecompressionStream();
361
+ ### Working with TAR archives directly
362
+
363
+ ```typescript
364
+ import { TarTools } from '@push.rocks/smartarchive';
365
+
366
+ const tarTools = new TarTools();
367
+
368
+ // Create a TAR archive from entries (buffer-based, good for small files)
369
+ const tarBuffer = await tarTools.packFiles([
370
+ { archivePath: 'hello.txt', content: 'Hello, World!' },
371
+ { archivePath: 'data.json', content: JSON.stringify({ foo: 'bar' }) }
372
+ ]);
373
+
374
+ // Create a TAR.GZ archive
375
+ const tgzBuffer = await tarTools.packFilesToTarGz([
376
+ { archivePath: 'file.txt', content: 'Compressed content' }
377
+ ], 6);
378
+
379
+ // Extract a TAR archive
380
+ const entries = await tarTools.extractTar(tarBuffer);
381
+ for (const entry of entries) {
382
+ console.log(`${entry.path}: ${entry.isDirectory ? 'dir' : 'file'}`);
383
+ }
308
384
 
309
- createReadStream('./input.txt')
310
- .pipe(compressStream)
311
- .pipe(createWriteStream('./output.gz'));
385
+ // Extract a TAR.GZ archive
386
+ const tgzEntries = await tarTools.extractTarGz(tgzBuffer);
387
+
388
+ // Node.js only: Pack a directory (buffer-based)
389
+ const dirBuffer = await tarTools.packDirectory('./src');
390
+ const dirTgzBuffer = await tarTools.packDirectoryToTarGz('./src', 9);
312
391
  ```
313
392
 
314
- ### Working with TAR archives directly
393
+ ### Streaming TAR for Large Files (Node.js only) πŸš€
394
+
395
+ For large files that don't fit in memory, use the streaming APIs:
315
396
 
316
397
  ```typescript
317
398
  import { TarTools } from '@push.rocks/smartarchive';
399
+ import * as fs from 'fs';
318
400
 
319
401
  const tarTools = new TarTools();
320
402
 
321
- // Create a TAR archive manually
322
- const pack = await tarTools.getPackStream();
403
+ // ===== STREAMING PACK =====
404
+ // Create a TAR pack stream - files are processed one at a time
405
+ const pack = tarTools.getPackStream();
323
406
 
407
+ // Add files with streaming content (requires size for streams)
324
408
  await tarTools.addFileToPack(pack, {
325
- fileName: 'hello.txt',
326
- content: 'Hello, World!'
409
+ fileName: 'small.txt',
410
+ content: 'Hello World' // Strings and buffers auto-detect size
327
411
  });
328
412
 
329
413
  await tarTools.addFileToPack(pack, {
330
- fileName: 'data.json',
331
- content: Buffer.from(JSON.stringify({ foo: 'bar' }))
414
+ fileName: 'large-video.mp4',
415
+ content: fs.createReadStream('./video.mp4'),
416
+ size: fs.statSync('./video.mp4').size // Size required for streams
332
417
  });
333
418
 
334
419
  pack.finalize();
335
- pack.pipe(createWriteStream('./output.tar'));
420
+ pack.pipe(fs.createWriteStream('output.tar'));
421
+
422
+ // ===== STREAMING DIRECTORY PACK =====
423
+ // Pack entire directory with true streaming (no buffering)
424
+ const tarStream = await tarTools.getDirectoryPackStream('./large-folder');
425
+ tarStream.pipe(fs.createWriteStream('backup.tar'));
426
+
427
+ // With GZIP compression
428
+ const tgzStream = await tarTools.getDirectoryPackStreamGz('./large-folder', 6);
429
+ tgzStream.pipe(fs.createWriteStream('backup.tar.gz'));
430
+
431
+ // ===== STREAMING EXTRACT =====
432
+ // Extract large archives without loading into memory
433
+ const extract = tarTools.getExtractStream();
336
434
 
337
- // Pack a directory to TAR.GZ buffer
338
- const tgzBuffer = await tarTools.packDirectoryToTarGz('./src', 6);
435
+ extract.on('entry', (header, stream, next) => {
436
+ console.log(`Extracting: ${header.name} (${header.size} bytes)`);
339
437
 
340
- // Pack a directory to TAR.GZ stream
341
- const tgzStream = await tarTools.packDirectoryToTarGzStream('./src');
438
+ const writeStream = fs.createWriteStream(`./out/${header.name}`);
439
+ stream.pipe(writeStream);
440
+ writeStream.on('finish', next);
441
+ });
442
+
443
+ extract.on('finish', () => console.log('Extraction complete'));
444
+
445
+ fs.createReadStream('large-archive.tar').pipe(extract);
446
+
447
+ // Or use the convenient directory extraction
448
+ await tarTools.extractToDirectory(
449
+ fs.createReadStream('archive.tar'),
450
+ './output-folder'
451
+ );
342
452
  ```
343
453
 
344
454
  ### Working with ZIP archives directly
@@ -351,7 +461,7 @@ const zipTools = new ZipTools();
351
461
  // Create a ZIP archive from entries
352
462
  const zipBuffer = await zipTools.createZip([
353
463
  { archivePath: 'readme.txt', content: 'Hello!' },
354
- { archivePath: 'data.bin', content: Buffer.from([0x00, 0x01, 0x02]) }
464
+ { archivePath: 'data.bin', content: new Uint8Array([0x00, 0x01, 0x02]) }
355
465
  ], 6);
356
466
 
357
467
  // Extract a ZIP buffer
@@ -448,13 +558,13 @@ fileStream.on('data', async (file) => {
448
558
 
449
559
  ## Supported Formats πŸ“‹
450
560
 
451
- | Format | Extension(s) | Extract | Create |
452
- |--------|--------------|---------|--------|
453
- | TAR | `.tar` | βœ… | βœ… |
454
- | TAR.GZ / TGZ | `.tar.gz`, `.tgz` | βœ… | βœ… |
455
- | ZIP | `.zip` | βœ… | βœ… |
456
- | GZIP | `.gz` | βœ… | βœ… |
457
- | BZIP2 | `.bz2` | βœ… | ❌ |
561
+ | Format | Extension(s) | Extract | Create | Browser |
562
+ |--------|--------------|---------|--------|---------|
563
+ | TAR | `.tar` | βœ… | βœ… | βœ… |
564
+ | TAR.GZ / TGZ | `.tar.gz`, `.tgz` | βœ… | βœ… | βœ… |
565
+ | ZIP | `.zip` | βœ… | βœ… | βœ… |
566
+ | GZIP | `.gz` | βœ… | βœ… | βœ… |
567
+ | BZIP2 | `.bz2` | βœ… | ❌ | βœ… |
458
568
 
459
569
  ## Type Definitions
460
570
 
@@ -468,7 +578,7 @@ type TCompressionLevel = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
468
578
  // Entry for creating archives
469
579
  interface IArchiveEntry {
470
580
  archivePath: string;
471
- content: string | Buffer | Readable | SmartFile | StreamFile;
581
+ content: string | Buffer | Uint8Array | SmartFile | StreamFile;
472
582
  size?: number;
473
583
  mode?: number;
474
584
  mtime?: Date;
@@ -496,9 +606,9 @@ interface IArchiveInfo {
496
606
  ## Performance Tips 🏎️
497
607
 
498
608
  1. **Use streaming for large files** – `.toStreamFiles()` processes entries one at a time without loading the entire archive
499
- 2. **Provide byte lengths when known** – When using TarTools directly, provide `byteLength` for better performance
500
- 3. **Choose appropriate compression** – Use 1-3 for speed, 6 (default) for balance, 9 for maximum compression
501
- 4. **Filter early** – Use `.include()`/`.exclude()` to skip unwanted entries before processing
609
+ 2. **Choose appropriate compression** – Use 1-3 for speed, 6 (default) for balance, 9 for maximum compression
610
+ 3. **Filter early** – Use `.include()`/`.exclude()` to skip unwanted entries before processing
611
+ 4. **Use Uint8Array in browsers** – The browser bundle works with `Uint8Array` for optimal performance
502
612
 
503
613
  ## Error Handling πŸ›‘οΈ
504
614
 
@@ -524,23 +634,21 @@ try {
524
634
 
525
635
  ## License and Legal Information
526
636
 
527
- This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository.
637
+ This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [LICENSE](./LICENSE) file.
528
638
 
529
639
  **Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
530
640
 
531
641
  ### Trademarks
532
642
 
533
- This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.
534
-
535
- ### Issue Reporting and Security
643
+ This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH or third parties, and are not included within the scope of the MIT license granted herein.
536
644
 
537
- For reporting bugs, issues, or security vulnerabilities, please visit [community.foss.global/](https://community.foss.global/). This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a [code.foss.global/](https://code.foss.global/) account to submit Pull Requests directly.
645
+ Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines or the guidelines of the respective third-party owners, and any usage must be approved in writing. Third-party trademarks used herein are the property of their respective owners and used only in a descriptive manner, e.g. for an implementation of an API or similar.
538
646
 
539
647
  ### Company Information
540
648
 
541
649
  Task Venture Capital GmbH
542
- Registered at District court Bremen HRB 35230 HB, Germany
650
+ Registered at District Court Bremen HRB 35230 HB, Germany
543
651
 
544
- For any legal inquiries or if you require further information, please contact us via email at hello@task.vc.
652
+ For any legal inquiries or further information, please contact us via email at hello@task.vc.
545
653
 
546
654
  By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@push.rocks/smartarchive',
6
- version: '5.1.0',
6
+ version: '5.2.0',
7
7
  description: 'A library for working with archive files, providing utilities for compressing and decompressing data.'
8
8
  }
@@ -380,36 +380,41 @@ export class SmartArchive {
380
380
  plugins.smartstream.createTransformFunction<IAnalyzedResult, void>(
381
381
  async (analyzedResultChunk) => {
382
382
  if (analyzedResultChunk.fileType?.mime === 'application/x-tar') {
383
- // Use modern-tar for TAR extraction
384
- const chunks: Buffer[] = [];
383
+ // Use tar-stream for streaming TAR extraction
384
+ // Buffer each entry to ensure tar-stream can proceed to next entry
385
+ const extract = this.tarTools.getExtractStream();
386
+
387
+ extract.on('entry', (header, stream, next) => {
388
+ if (header.type === 'directory') {
389
+ stream.resume(); // Drain the stream
390
+ next();
391
+ return;
392
+ }
385
393
 
386
- analyzedResultChunk.resultStream.on('data', (chunk: Buffer) => {
387
- chunks.push(chunk);
394
+ // Buffer the entry content to avoid blocking tar-stream
395
+ const chunks: Buffer[] = [];
396
+ stream.on('data', (chunk: Buffer) => chunks.push(chunk));
397
+ stream.on('end', () => {
398
+ const content = Buffer.concat(chunks);
399
+ const streamFile = plugins.smartfile.StreamFile.fromBuffer(content);
400
+ streamFile.relativeFilePath = header.name;
401
+ streamFileIntake.push(streamFile);
402
+ next();
403
+ });
404
+ stream.on('error', (err: Error) => {
405
+ streamFileIntake.emit('error', err);
406
+ });
388
407
  });
389
408
 
390
- analyzedResultChunk.resultStream.on('end', async () => {
391
- try {
392
- const tarBuffer = Buffer.concat(chunks);
393
- const entries = await this.tarTools.extractTar(new Uint8Array(tarBuffer));
394
-
395
- for (const entry of entries) {
396
- if (entry.isDirectory) continue;
397
-
398
- const streamFile = plugins.smartfile.StreamFile.fromBuffer(
399
- Buffer.from(entry.content)
400
- );
401
- streamFile.relativeFilePath = entry.path;
402
- streamFileIntake.push(streamFile);
403
- }
404
- safeSignalEnd();
405
- } catch (err) {
406
- streamFileIntake.emit('error', err);
407
- }
409
+ extract.on('finish', () => {
410
+ safeSignalEnd();
408
411
  });
409
412
 
410
- analyzedResultChunk.resultStream.on('error', (err: Error) => {
413
+ extract.on('error', (err: Error) => {
411
414
  streamFileIntake.emit('error', err);
412
415
  });
416
+
417
+ analyzedResultChunk.resultStream.pipe(extract);
413
418
  } else if (analyzedResultChunk.fileType?.mime === 'application/zip') {
414
419
  analyzedResultChunk.resultStream
415
420
  .pipe(analyzedResultChunk.decompressionStream)