Browse Source

Add ZIP support
Fixes #1

Arjun Barrett 4 năm trước cách đây
mục cha
commit
26ba67f5f3

+ 80 - 17
README.md

@@ -4,15 +4,18 @@ High performance (de)compression in an 8kB package
 ## Why fflate?
 `fflate` (short for fast flate) is the **fastest, smallest, and most versatile** pure JavaScript compression and decompression library in existence, handily beating [`pako`](https://npmjs.com/package/pako), [`tiny-inflate`](https://npmjs.com/package/tiny-inflate), and [`UZIP.js`](https://github.com/photopea/UZIP.js) in performance benchmarks while being multiple times more lightweight. Its compression ratios are often better than even the original Zlib C library. It includes support for DEFLATE, GZIP, and Zlib data. Data compressed by `fflate` can be decompressed by other tools, and vice versa.
 
-|                            | `pako` | `tiny-inflate`       | `UZIP.js`             | `fflate`                       |
-|----------------------------|--------|----------------------|-----------------------|--------------------------------|
-| Decompression performance  | 1x     | Up to 40% slower     | **Up to 40% faster**  | **Up to 40% faster**           |
-| Compression performance    | 1x     | N/A                  | Up to 5% faster       | **Up to 50% faster**           |
-| Bundle size (minzipped)    | 45.6kB | **3kB**              | 14.2kB                | 8kB **(3kB for only inflate)** |
-| Compression support        | ✅     | ❌                    | ✅                    | ✅                             |
-| Thread/Worker safe         | ✅     | ✅                    | ❌                    | ✅                             |
-| GZIP/Zlib support          | ✅     | ❌                    | ❌                    | ✅                             |
-| Uses ES Modules            | ❌     | ❌                    | ❌                    | ✅                             |
+In addition to the base decompression and compression APIs, `fflate` supports high-speed ZIP compression and decompression for an extra 3 kB. In fact, the compressor, in synchronous mode, compresses both more quickly and with a higher compression ratio than most compression software (even Info-ZIP, a C program), and in asynchronous mode it can utilize multiple cores to achieve over 3x the performance of any other utility.
+
+|                           | `pako` | `tiny-inflate`       | `UZIP.js`             | `fflate`                       |
+|---------------------------|--------|----------------------|-----------------------|--------------------------------|
+| Decompression performance | 1x     | Up to 40% slower     | **Up to 40% faster**  | **Up to 40% faster**           |
+| Compression performance   | 1x     | N/A                  | Up to 5% faster       | **Up to 50% faster**           |
+| Bundle size (minified)    | 45.6kB | **3kB**              | 14.2kB                | 8kB **(3kB for only inflate)** |
+| Compression support       | ✅     | ❌                    | ✅                    | ✅                             |
+| ZIP support               | ❌     | ❌                    | ✅                    | ✅                             |
+| Thread/Worker safe        | ✅     | ✅                    | ❌                    | ✅                             |
+| GZIP/Zlib support         | ✅     | ❌                    | ❌                    | ✅                             |
+| Uses ES Modules           | ❌     | ❌                    | ❌                    | ✅                             |
 
 ## Usage
 
@@ -76,7 +79,7 @@ const decompressed = fflate.decompressSync(compressed);
 const origText = dec.decode(decompressed);
 console.log(origText); // Hello world!
 ```
-Note that encoding the compressed data as a string, like in `pako`, is not nearly as efficient as binary for data transfer. However, you can do it:
+If you're using an older browser, only want ASCII, or need to encode the compressed data itself as a string, you can use the following methods:
 ```js
 // data to string
 const dts = data => {
@@ -92,23 +95,67 @@ const std = str => {
     result[i] = str.charCodeAt(i);
   return result;
 }
+const buf = std('Hello world!');
+// Note that compressed data strings are much less efficient than raw binary
 const compressedString = dts(fflate.compressSync(buf));
 const decompressed = fflate.decompressSync(std(compressedString));
+const origText = dts(decompressed);
+console.log(origText); // Hello world!
+```
+You can create multi-file ZIP archives easily as well:
+```js
+// Note that the asynchronous version (see below) runs in parallel and
+// is *much* (up to 3x) faster for larger archives.
+const zipped = fflate.zipSync({
+  // Directories can be nested structures, as in an actual filesystem
+  'dir1': {
+    'nested': {
+      // You can use Unicode in filenames
+      '你好.txt': std('Hey there!')
+    },
+    // You can also manually write out a directory path
+    'other/tmp.txt': new Uint8Array([97, 98, 99, 100])
+  },
+  // You can also provide compression options
+  'myImageData.bmp': [aMassiveFile, { level: 9, mem: 12 }],
+  'superTinyFile.bin': [new Uint8Array([0]), { level: 0 }]
+}, {
+  // These options are the defaults for all files, but file-specific
+  // options take precedence.
+  level: 1
+});
+
+// If you write the zipped data to myzip.zip and unzip, the folder
+// structure will be outputted as:
+
+// myzip.zip (original file)
+// dir1
+// |-> nested
+// |   |-> 你好.txt
+// |-> other
+// |   |-> tmp.txt
+// myImageData.bmp
+// superTinyFile.bin
+
+// When decompressing, folders are not nested; all filepaths are fully
+// written out in the keys. For example, the return value may be:
+// { 'nested/directory/a2.txt': Uint8Array(2) [97, 97] })
+const decompressed = fflate.unzipSync(zipped);
 ```
 As you may have guessed, there is an asynchronous version of every method as well. Unlike most libraries, this will cause the compression or decompression run in a separate thread entirely and automatically by using Web (or Node) Workers. This means that the processing will not block the main thread at all.
 
-Note that there is a significant initial overhead to using workers for both performance (about 70ms) and bundle size (about 5kB), so it's best to avoid the asynchronous API unless necessary.
+Note that there is a significant initial overhead to using workers of about 70ms, so it's best to avoid the asynchronous API unless necessary.
 
 For data under about 2MB, the main thread is blocked for so short a time (under 100ms) during both compression and decompression that most users cannot notice it anyway, so using the synchronous API is better. However, if you're compressing multiple files at once, or are compressing large amounts of data, the callback APIs are an order of magnitude better.
 ```js
-import { gzip, zlib } from 'fflate';
+import { gzip, zlib, zip } from 'fflate';
 
 // Workers will work in almost any browser (even IE10!)
-// However, they fail on Node below v12 without the --experimental-worker
+// However, they fail below Node v12 without the --experimental-worker
 // CLI flag, and will fail entirely on Node below v10.
 
 // All of the async APIs use a node-style callback as so:
-gzip(aMassiveFile, (err, data) => {
+const terminate = gzip(aMassiveFile, (err, data) => {
   if (err) {
     // Note that for now, this rarely, if ever, happens. This will only
     // occur upon an exception in the worker (which is typically a bug).
@@ -118,11 +165,25 @@ gzip(aMassiveFile, (err, data) => {
   console.log(data.length);
 });
 
-// This will render the data inside aMassiveFile unusable, but can
-// dramatically improve performance and reduce memory usage.
-zlib(aMassiveFile, { consume: true }, (err, data) => {
+if (needToCancel) {
+  // The return value of any of the asynchronous APIs is a function that,
+  // when called, will immediately cancel the operation. The callback
+  // will not be called.
+  terminate();
+}
+
+// The consume option will render the data inside aMassiveFile unusable,
+// but can dramatically improve performance and reduce memory usage.
+zlib(aMassiveFile, { consume: true, level: 9 }, (err, data) => {
   // Use the data
 });
+
+// This is way faster than zipSync because the compression of multiple
+// files runs in parallel. In fact, the fact that it's parallelized
+// makes it faster than most standalone ZIP CLIs.
+zip({ f1: aMassiveFile, 'f2.txt': anotherMassiveFile }, (err, data) => {
+  // Save the ZIP file
+})
 ```
 
 Try not to use *both* the asynchronous and synchronous APIs. They are about 9kB and 8kB individually, but using them both leads to a 16kB bundle (as you can see from [Bundlephobia](https://bundlephobia.com/result?p=fflate)).
@@ -143,6 +204,8 @@ Before you decide that `fflate` is the end-all compression library, you should n
 ## Browser support
 `fflate` makes heavy use of typed arrays (`Uint8Array`, `Uint16Array`, etc.). Typed arrays can be polyfilled at the cost of performance, but the most recent browser that doesn't support them [is from 2011](https://caniuse.com/typedarrays), so I wouldn't bother.
 
+The asynchronous APIs also use `Worker`, which is not supported in a few browsers (however, the vast majority of browsers that support typed arrays support `Worker`).
+
 Other than that, `fflate` is completely ES3, meaning you probably won't even need a bundler to use it.
 
 ## Testing

+ 170 - 47
docs/README.md

@@ -8,15 +8,24 @@
 * [AsyncGunzipOptions](interfaces/asyncgunzipoptions.md)
 * [AsyncGzipOptions](interfaces/asyncgzipoptions.md)
 * [AsyncInflateOptions](interfaces/asyncinflateoptions.md)
+* [AsyncTerminable](interfaces/asyncterminable.md)
 * [AsyncUnzlibOptions](interfaces/asyncunzliboptions.md)
+* [AsyncZipOptions](interfaces/asynczipoptions.md)
+* [AsyncZippable](interfaces/asynczippable.md)
 * [AsyncZlibOptions](interfaces/asynczliboptions.md)
 * [DeflateOptions](interfaces/deflateoptions.md)
 * [GzipOptions](interfaces/gzipoptions.md)
+* [Unzipped](interfaces/unzipped.md)
+* [ZipOptions](interfaces/zipoptions.md)
+* [Zippable](interfaces/zippable.md)
 * [ZlibOptions](interfaces/zliboptions.md)
 
 ### Type aliases
 
+* [AsyncZippableFile](README.md#asynczippablefile)
 * [FlateCallback](README.md#flatecallback)
+* [UnzipCallback](README.md#unzipcallback)
+* [ZippableFile](README.md#zippablefile)
 
 ### Functions
 
@@ -30,28 +39,60 @@
 * [gzipSync](README.md#gzipsync)
 * [inflate](README.md#inflate)
 * [inflateSync](README.md#inflatesync)
+* [unzip](README.md#unzip)
+* [unzipSync](README.md#unzipsync)
 * [unzlib](README.md#unzlib)
 * [unzlibSync](README.md#unzlibsync)
+* [zip](README.md#zip)
+* [zipSync](README.md#zipsync)
 * [zlib](README.md#zlib)
 * [zlibSync](README.md#zlibsync)
 
 ## Type aliases
 
+### AsyncZippableFile
+
+Ƭ  **AsyncZippableFile**: Uint8Array \| []
+
+A file that can be used to asynchronously createa a ZIP archive
+
+___
+
 ### FlateCallback
 
 Ƭ  **FlateCallback**: (err: Error,data: Uint8Array) => unknown
 
-Callback for asynchronous comrpession methods
+Callback for asynchronous (de)compression methods
 
 **`param`** Any error that occurred
 
 **`param`** The resulting data. Only present if `err` is null
 
+___
+
+### UnzipCallback
+
+Ƭ  **UnzipCallback**: (err: Error,data: [Unzipped](interfaces/unzipped.md)) => unknown
+
+Callback for asynchronous ZIP decompression
+
+**`param`** Any error that occurred
+
+**`param`** The decompressed ZIP archive
+
+___
+
+### ZippableFile
+
+Ƭ  **ZippableFile**: Uint8Array \| []
+
+A file that can be used to create a ZIP archive
+
 ## Functions
 
 ### decompress
 
-▸ **decompress**(`data`: Uint8Array, `opts`: [AsyncInflateOptions](interfaces/asyncinflateoptions.md), `cb`: [FlateCallback](README.md#flatecallback)): void
+▸ **decompress**(`data`: Uint8Array, `opts`: [AsyncInflateOptions](interfaces/asyncinflateoptions.md), `cb`: [FlateCallback](README.md#flatecallback)): [AsyncTerminable](interfaces/asyncterminable.md)
 
 Asynchrononously expands compressed GZIP, Zlib, or raw DEFLATE data, automatically detecting the format
 
@@ -61,11 +102,11 @@ Name | Type | Description |
 ------ | ------ | ------ |
 `data` | Uint8Array | The data to decompress |
 `opts` | [AsyncInflateOptions](interfaces/asyncinflateoptions.md) | The decompression options |
-`cb` | [FlateCallback](README.md#flatecallback) | The function to be called upon decompression completion  |
+`cb` | [FlateCallback](README.md#flatecallback) | The function to be called upon decompression completion |
 
-**Returns:** void
+**Returns:** [AsyncTerminable](interfaces/asyncterminable.md)
 
-▸ **decompress**(`data`: Uint8Array, `cb`: [FlateCallback](README.md#flatecallback)): void
+▸ **decompress**(`data`: Uint8Array, `cb`: [FlateCallback](README.md#flatecallback)): [AsyncTerminable](interfaces/asyncterminable.md)
 
 Asynchrononously expands compressed GZIP, Zlib, or raw DEFLATE data, automatically detecting the format
 
@@ -74,9 +115,9 @@ Asynchrononously expands compressed GZIP, Zlib, or raw DEFLATE data, automatical
 Name | Type | Description |
 ------ | ------ | ------ |
 `data` | Uint8Array | The data to decompress |
-`cb` | [FlateCallback](README.md#flatecallback) | The function to be called upon decompression completion  |
+`cb` | [FlateCallback](README.md#flatecallback) | The function to be called upon decompression completion |
 
-**Returns:** void
+**Returns:** [AsyncTerminable](interfaces/asyncterminable.md)
 
 ___
 
@@ -99,7 +140,7 @@ ___
 
 ### deflate
 
-▸ **deflate**(`data`: Uint8Array, `opts`: [AsyncDeflateOptions](interfaces/asyncdeflateoptions.md), `cb`: [FlateCallback](README.md#flatecallback)): void
+▸ **deflate**(`data`: Uint8Array, `opts`: [AsyncDeflateOptions](interfaces/asyncdeflateoptions.md), `cb`: [FlateCallback](README.md#flatecallback)): [AsyncTerminable](interfaces/asyncterminable.md)
 
 Asynchronously compresses data with DEFLATE without any wrapper
 
@@ -109,11 +150,11 @@ Name | Type | Description |
 ------ | ------ | ------ |
 `data` | Uint8Array | The data to compress |
 `opts` | [AsyncDeflateOptions](interfaces/asyncdeflateoptions.md) | The compression options |
-`cb` | [FlateCallback](README.md#flatecallback) | The function to be called upon compression completion  |
+`cb` | [FlateCallback](README.md#flatecallback) | The function to be called upon compression completion |
 
-**Returns:** void
+**Returns:** [AsyncTerminable](interfaces/asyncterminable.md)
 
-▸ **deflate**(`data`: Uint8Array, `cb`: [FlateCallback](README.md#flatecallback)): void
+▸ **deflate**(`data`: Uint8Array, `cb`: [FlateCallback](README.md#flatecallback)): [AsyncTerminable](interfaces/asyncterminable.md)
 
 Asynchronously compresses data with DEFLATE without any wrapper
 
@@ -124,7 +165,7 @@ Name | Type | Description |
 `data` | Uint8Array | The data to compress |
 `cb` | [FlateCallback](README.md#flatecallback) | The function to be called upon compression completion  |
 
-**Returns:** void
+**Returns:** [AsyncTerminable](interfaces/asyncterminable.md)
 
 ___
 
@@ -147,7 +188,7 @@ ___
 
 ### gunzip
 
-▸ **gunzip**(`data`: Uint8Array, `opts`: [AsyncGunzipOptions](interfaces/asyncgunzipoptions.md), `cb`: [FlateCallback](README.md#flatecallback)): void
+▸ **gunzip**(`data`: Uint8Array, `opts`: [AsyncGunzipOptions](interfaces/asyncgunzipoptions.md), `cb`: [FlateCallback](README.md#flatecallback)): [AsyncTerminable](interfaces/asyncterminable.md)
 
 Asynchronously expands GZIP data
 
@@ -157,11 +198,11 @@ Name | Type | Description |
 ------ | ------ | ------ |
 `data` | Uint8Array | The data to decompress |
 `opts` | [AsyncGunzipOptions](interfaces/asyncgunzipoptions.md) | The decompression options |
-`cb` | [FlateCallback](README.md#flatecallback) | The function to be called upon decompression completion  |
+`cb` | [FlateCallback](README.md#flatecallback) | The function to be called upon decompression completion |
 
-**Returns:** void
+**Returns:** [AsyncTerminable](interfaces/asyncterminable.md)
 
-▸ **gunzip**(`data`: Uint8Array, `cb`: [FlateCallback](README.md#flatecallback)): void
+▸ **gunzip**(`data`: Uint8Array, `cb`: [FlateCallback](README.md#flatecallback)): [AsyncTerminable](interfaces/asyncterminable.md)
 
 Asynchronously expands GZIP data
 
@@ -170,9 +211,9 @@ Asynchronously expands GZIP data
 Name | Type | Description |
 ------ | ------ | ------ |
 `data` | Uint8Array | The data to decompress |
-`cb` | [FlateCallback](README.md#flatecallback) | The function to be called upon decompression completion  |
+`cb` | [FlateCallback](README.md#flatecallback) | The function to be called upon decompression completion |
 
-**Returns:** void
+**Returns:** [AsyncTerminable](interfaces/asyncterminable.md)
 
 ___
 
@@ -195,7 +236,7 @@ ___
 
 ### gzip
 
-▸ **gzip**(`data`: Uint8Array, `opts`: [AsyncGzipOptions](interfaces/asyncgzipoptions.md), `cb`: [FlateCallback](README.md#flatecallback)): void
+▸ **gzip**(`data`: Uint8Array, `opts`: [AsyncGzipOptions](interfaces/asyncgzipoptions.md), `cb`: [FlateCallback](README.md#flatecallback)): [AsyncTerminable](interfaces/asyncterminable.md)
 
 Asynchronously compresses data with GZIP
 
@@ -205,11 +246,11 @@ Name | Type | Description |
 ------ | ------ | ------ |
 `data` | Uint8Array | The data to compress |
 `opts` | [AsyncGzipOptions](interfaces/asyncgzipoptions.md) | The compression options |
-`cb` | [FlateCallback](README.md#flatecallback) | The function to be called upon compression completion  |
+`cb` | [FlateCallback](README.md#flatecallback) | The function to be called upon compression completion |
 
-**Returns:** void
+**Returns:** [AsyncTerminable](interfaces/asyncterminable.md)
 
-▸ **gzip**(`data`: Uint8Array, `cb`: [FlateCallback](README.md#flatecallback)): void
+▸ **gzip**(`data`: Uint8Array, `cb`: [FlateCallback](README.md#flatecallback)): [AsyncTerminable](interfaces/asyncterminable.md)
 
 Asynchronously compresses data with GZIP
 
@@ -218,11 +259,11 @@ Asynchronously compresses data with GZIP
 Name | Type | Description |
 ------ | ------ | ------ |
 `data` | Uint8Array | The data to compress |
-`cb` | [FlateCallback](README.md#flatecallback) | The function to be called upon compression completion  |
+`cb` | [FlateCallback](README.md#flatecallback) | The function to be called upon compression completion |
 
-**Returns:** void
+**Returns:** [AsyncTerminable](interfaces/asyncterminable.md)
 
-▸ **gzip**(`data`: Uint8Array, `opts`: [AsyncGzipOptions](interfaces/asyncgzipoptions.md), `cb`: [FlateCallback](README.md#flatecallback)): void
+▸ **gzip**(`data`: Uint8Array, `opts`: [AsyncGzipOptions](interfaces/asyncgzipoptions.md), `cb`: [FlateCallback](README.md#flatecallback)): [AsyncTerminable](interfaces/asyncterminable.md)
 
 Asynchronously compresses data with GZIP
 
@@ -232,11 +273,11 @@ Name | Type | Description |
 ------ | ------ | ------ |
 `data` | Uint8Array | The data to compress |
 `opts` | [AsyncGzipOptions](interfaces/asyncgzipoptions.md) | The compression options |
-`cb` | [FlateCallback](README.md#flatecallback) | The function to be called upon compression completion  |
+`cb` | [FlateCallback](README.md#flatecallback) | The function to be called upon compression completion |
 
-**Returns:** void
+**Returns:** [AsyncTerminable](interfaces/asyncterminable.md)
 
-▸ **gzip**(`data`: Uint8Array, `cb`: [FlateCallback](README.md#flatecallback)): void
+▸ **gzip**(`data`: Uint8Array, `cb`: [FlateCallback](README.md#flatecallback)): [AsyncTerminable](interfaces/asyncterminable.md)
 
 Asynchronously compresses data with GZIP
 
@@ -245,9 +286,9 @@ Asynchronously compresses data with GZIP
 Name | Type | Description |
 ------ | ------ | ------ |
 `data` | Uint8Array | The data to compress |
-`cb` | [FlateCallback](README.md#flatecallback) | The function to be called upon compression completion  |
+`cb` | [FlateCallback](README.md#flatecallback) | The function to be called upon compression completion |
 
-**Returns:** void
+**Returns:** [AsyncTerminable](interfaces/asyncterminable.md)
 
 ___
 
@@ -270,7 +311,7 @@ ___
 
 ### inflate
 
-▸ **inflate**(`data`: Uint8Array, `opts`: [AsyncInflateOptions](interfaces/asyncinflateoptions.md), `cb`: [FlateCallback](README.md#flatecallback)): void
+▸ **inflate**(`data`: Uint8Array, `opts`: [AsyncInflateOptions](interfaces/asyncinflateoptions.md), `cb`: [FlateCallback](README.md#flatecallback)): [AsyncTerminable](interfaces/asyncterminable.md)
 
 Asynchronously expands DEFLATE data with no wrapper
 
@@ -280,11 +321,11 @@ Name | Type | Description |
 ------ | ------ | ------ |
 `data` | Uint8Array | The data to decompress |
 `opts` | [AsyncInflateOptions](interfaces/asyncinflateoptions.md) | The decompression options |
-`cb` | [FlateCallback](README.md#flatecallback) | The function to be called upon decompression completion  |
+`cb` | [FlateCallback](README.md#flatecallback) | The function to be called upon decompression completion |
 
-**Returns:** void
+**Returns:** [AsyncTerminable](interfaces/asyncterminable.md)
 
-▸ **inflate**(`data`: Uint8Array, `cb`: [FlateCallback](README.md#flatecallback)): void
+▸ **inflate**(`data`: Uint8Array, `cb`: [FlateCallback](README.md#flatecallback)): [AsyncTerminable](interfaces/asyncterminable.md)
 
 Asynchronously expands DEFLATE data with no wrapper
 
@@ -293,9 +334,9 @@ Asynchronously expands DEFLATE data with no wrapper
 Name | Type | Description |
 ------ | ------ | ------ |
 `data` | Uint8Array | The data to decompress |
-`cb` | [FlateCallback](README.md#flatecallback) | The function to be called upon decompression completion  |
+`cb` | [FlateCallback](README.md#flatecallback) | The function to be called upon decompression completion |
 
-**Returns:** void
+**Returns:** [AsyncTerminable](interfaces/asyncterminable.md)
 
 ___
 
@@ -316,9 +357,42 @@ Name | Type | Description |
 
 ___
 
+### unzip
+
+▸ **unzip**(`data`: Uint8Array, `cb`: [UnzipCallback](README.md#unzipcallback)): [AsyncTerminable](interfaces/asyncterminable.md)
+
+Asynchronously decompresses a ZIP archive
+
+#### Parameters:
+
+Name | Type | Description |
+------ | ------ | ------ |
+`data` | Uint8Array | The raw compressed ZIP file |
+`cb` | [UnzipCallback](README.md#unzipcallback) | The callback to call with the decompressed files |
+
+**Returns:** [AsyncTerminable](interfaces/asyncterminable.md)
+
+___
+
+### unzipSync
+
+▸ **unzipSync**(`data`: Uint8Array): [Unzipped](interfaces/unzipped.md)
+
+Synchronously decompresses a ZIP archive
+
+#### Parameters:
+
+Name | Type | Description |
+------ | ------ | ------ |
+`data` | Uint8Array | The raw compressed ZIP file |
+
+**Returns:** [Unzipped](interfaces/unzipped.md)
+
+___
+
 ### unzlib
 
-▸ **unzlib**(`data`: Uint8Array, `opts`: [AsyncGunzipOptions](interfaces/asyncgunzipoptions.md), `cb`: [FlateCallback](README.md#flatecallback)): void
+▸ **unzlib**(`data`: Uint8Array, `opts`: [AsyncGunzipOptions](interfaces/asyncgunzipoptions.md), `cb`: [FlateCallback](README.md#flatecallback)): [AsyncTerminable](interfaces/asyncterminable.md)
 
 Asynchronously expands Zlib data
 
@@ -328,11 +402,11 @@ Name | Type | Description |
 ------ | ------ | ------ |
 `data` | Uint8Array | The data to decompress |
 `opts` | [AsyncGunzipOptions](interfaces/asyncgunzipoptions.md) | The decompression options |
-`cb` | [FlateCallback](README.md#flatecallback) | The function to be called upon decompression completion  |
+`cb` | [FlateCallback](README.md#flatecallback) | The function to be called upon decompression completion |
 
-**Returns:** void
+**Returns:** [AsyncTerminable](interfaces/asyncterminable.md)
 
-▸ **unzlib**(`data`: Uint8Array, `cb`: [FlateCallback](README.md#flatecallback)): void
+▸ **unzlib**(`data`: Uint8Array, `cb`: [FlateCallback](README.md#flatecallback)): [AsyncTerminable](interfaces/asyncterminable.md)
 
 Asynchronously expands Zlib data
 
@@ -341,9 +415,9 @@ Asynchronously expands Zlib data
 Name | Type | Description |
 ------ | ------ | ------ |
 `data` | Uint8Array | The data to decompress |
-`cb` | [FlateCallback](README.md#flatecallback) | The function to be called upon decompression completion  |
+`cb` | [FlateCallback](README.md#flatecallback) | The function to be called upon decompression completion |
 
-**Returns:** void
+**Returns:** [AsyncTerminable](interfaces/asyncterminable.md)
 
 ___
 
@@ -364,9 +438,58 @@ Name | Type | Description |
 
 ___
 
+### zip
+
+▸ **zip**(`data`: [AsyncZippable](interfaces/asynczippable.md), `opts`: [AsyncZipOptions](interfaces/asynczipoptions.md), `cb`: [FlateCallback](README.md#flatecallback)): [AsyncTerminable](interfaces/asyncterminable.md)
+
+Asynchronously creates a ZIP file
+
+#### Parameters:
+
+Name | Type | Description |
+------ | ------ | ------ |
+`data` | [AsyncZippable](interfaces/asynczippable.md) | The directory structure for the ZIP archive |
+`opts` | [AsyncZipOptions](interfaces/asynczipoptions.md) | The main options, merged with per-file options |
+`cb` | [FlateCallback](README.md#flatecallback) | The callback to call with the generated ZIP archive |
+
+**Returns:** [AsyncTerminable](interfaces/asyncterminable.md)
+
+▸ **zip**(`data`: [AsyncZippable](interfaces/asynczippable.md), `cb`: [FlateCallback](README.md#flatecallback)): [AsyncTerminable](interfaces/asyncterminable.md)
+
+Asynchronously creates a ZIP file
+
+#### Parameters:
+
+Name | Type | Description |
+------ | ------ | ------ |
+`data` | [AsyncZippable](interfaces/asynczippable.md) | The directory structure for the ZIP archive |
+`cb` | [FlateCallback](README.md#flatecallback) | The callback to call with the generated ZIP archive |
+
+**Returns:** [AsyncTerminable](interfaces/asyncterminable.md)
+
+___
+
+### zipSync
+
+▸ **zipSync**(`data`: [Zippable](interfaces/zippable.md), `opts`: [ZipOptions](interfaces/zipoptions.md)): Uint8Array
+
+Synchronously creates a ZIP file. Prefer using `zip` for better performance
+with more than one file.
+
+#### Parameters:
+
+Name | Type | Default value | Description |
+------ | ------ | ------ | ------ |
+`data` | [Zippable](interfaces/zippable.md) | - | The directory structure for the ZIP archive |
+`opts` | [ZipOptions](interfaces/zipoptions.md) | {} | The main options, merged with per-file options |
+
+**Returns:** Uint8Array
+
+___
+
 ### zlib
 
-▸ **zlib**(`data`: Uint8Array, `opts`: [AsyncZlibOptions](interfaces/asynczliboptions.md), `cb`: [FlateCallback](README.md#flatecallback)): void
+▸ **zlib**(`data`: Uint8Array, `opts`: [AsyncZlibOptions](interfaces/asynczliboptions.md), `cb`: [FlateCallback](README.md#flatecallback)): [AsyncTerminable](interfaces/asyncterminable.md)
 
 Asynchronously compresses data with Zlib
 
@@ -378,9 +501,9 @@ Name | Type | Description |
 `opts` | [AsyncZlibOptions](interfaces/asynczliboptions.md) | The compression options |
 `cb` | [FlateCallback](README.md#flatecallback) | The function to be called upon compression completion  |
 
-**Returns:** void
+**Returns:** [AsyncTerminable](interfaces/asyncterminable.md)
 
-▸ **zlib**(`data`: Uint8Array, `cb`: [FlateCallback](README.md#flatecallback)): void
+▸ **zlib**(`data`: Uint8Array, `cb`: [FlateCallback](README.md#flatecallback)): [AsyncTerminable](interfaces/asyncterminable.md)
 
 Asynchronously compresses data with Zlib
 
@@ -389,9 +512,9 @@ Asynchronously compresses data with Zlib
 Name | Type | Description |
 ------ | ------ | ------ |
 `data` | Uint8Array | The data to compress |
-`cb` | [FlateCallback](README.md#flatecallback) | The function to be called upon compression completion  |
+`cb` | [FlateCallback](README.md#flatecallback) | The function to be called upon compression completion |
 
-**Returns:** void
+**Returns:** [AsyncTerminable](interfaces/asyncterminable.md)
 
 ___
 

+ 2 - 0
docs/interfaces/asyncdeflateoptions.md

@@ -10,6 +10,8 @@ Options for compressing data asynchronously into a DEFLATE format
 
   ↳ **AsyncDeflateOptions**
 
+  ↳↳ [AsyncZipOptions](asynczipoptions.md)
+
 ## Index
 
 ### Properties

+ 15 - 0
docs/interfaces/asyncterminable.md

@@ -0,0 +1,15 @@
+# Interface: AsyncTerminable
+
+A terminable compression/decompression process
+
+## Hierarchy
+
+* **AsyncTerminable**
+
+## Callable
+
+▸ (): void
+
+Terminates the worker thread immediately. The callback will not be called.
+
+**Returns:** void

+ 68 - 0
docs/interfaces/asynczipoptions.md

@@ -0,0 +1,68 @@
+# Interface: AsyncZipOptions
+
+Options for asynchronously creating a ZIP archive
+
+## Hierarchy
+
+* [AsyncDeflateOptions](asyncdeflateoptions.md)
+
+* {}
+
+  ↳ **AsyncZipOptions**
+
+## Index
+
+### Properties
+
+* [consume](asynczipoptions.md#consume)
+* [level](asynczipoptions.md#level)
+* [mem](asynczipoptions.md#mem)
+
+## Properties
+
+### consume
+
+• `Optional` **consume**: boolean
+
+*Inherited from [AsyncDeflateOptions](asyncdeflateoptions.md).[consume](asyncdeflateoptions.md#consume)*
+
+Whether or not to "consume" the source data. This will make the typed array/buffer you pass in
+unusable but will increase performance and reduce memory usage.
+
+___
+
+### level
+
+• `Optional` **level**: 0 \| 1 \| 2 \| 3 \| 4 \| 5 \| 6 \| 7 \| 8 \| 9
+
+*Inherited from [DeflateOptions](deflateoptions.md).[level](deflateoptions.md#level)*
+
+The level of compression to use, ranging from 0-9.
+
+0 will store the data without compression.
+1 is fastest but compresses the worst, 9 is slowest but compresses the best.
+The default level is 6.
+
+Typically, binary data benefits much more from higher values than text data.
+In both cases, higher values usually take disproportionately longer than the reduction in final size that results.
+
+For example, a 1 MB text file could:
+- become 1.01 MB with level 0 in 1ms
+- become 400 kB with level 1 in 10ms
+- become 320 kB with level 9 in 100ms
+
+___
+
+### mem
+
+• `Optional` **mem**: 0 \| 1 \| 2 \| 3 \| 4 \| 5 \| 6 \| 7 \| 8 \| 9 \| 10 \| 11 \| 12
+
+*Inherited from [DeflateOptions](deflateoptions.md).[mem](deflateoptions.md#mem)*
+
+The memory level to use, ranging from 0-12. Increasing this increases speed and compression ratio at the cost of memory.
+
+Note that this is exponential: while level 0 uses 4 kB, level 4 uses 64 kB, level 8 uses 1 MB, and level 12 uses 16 MB.
+It is recommended not to lower the value below 4, since that tends to hurt performance.
+In addition, values above 8 tend to help very little on most data and can even hurt performance.
+
+The default value is automatically determined based on the size of the input data.

+ 9 - 0
docs/interfaces/asynczippable.md

@@ -0,0 +1,9 @@
+# Interface: AsyncZippable
+
+The complete directory structure of an asynchronously ZIPpable archive
+
+## Hierarchy
+
+* {}
+
+  ↳ **AsyncZippable**

+ 2 - 0
docs/interfaces/deflateoptions.md

@@ -12,6 +12,8 @@ Options for compressing data into a DEFLATE format
 
   ↳ [AsyncDeflateOptions](asyncdeflateoptions.md)
 
+  ↳ [ZipOptions](zipoptions.md)
+
 ## Index
 
 ### Properties

+ 10 - 0
docs/interfaces/unzipped.md

@@ -0,0 +1,10 @@
+# Interface: Unzipped
+
+An unzipped archive. The full path of each file is used as the key,
+and the file is the value
+
+## Hierarchy
+
+* {}
+
+  ↳ **Unzipped**

+ 56 - 0
docs/interfaces/zipoptions.md

@@ -0,0 +1,56 @@
+# Interface: ZipOptions
+
+Options for creating a ZIP archive
+
+## Hierarchy
+
+* [DeflateOptions](deflateoptions.md)
+
+* {}
+
+  ↳ **ZipOptions**
+
+## Index
+
+### Properties
+
+* [level](zipoptions.md#level)
+* [mem](zipoptions.md#mem)
+
+## Properties
+
+### level
+
+• `Optional` **level**: 0 \| 1 \| 2 \| 3 \| 4 \| 5 \| 6 \| 7 \| 8 \| 9
+
+*Inherited from [DeflateOptions](deflateoptions.md).[level](deflateoptions.md#level)*
+
+The level of compression to use, ranging from 0-9.
+
+0 will store the data without compression.
+1 is fastest but compresses the worst, 9 is slowest but compresses the best.
+The default level is 6.
+
+Typically, binary data benefits much more from higher values than text data.
+In both cases, higher values usually take disproportionately longer than the reduction in final size that results.
+
+For example, a 1 MB text file could:
+- become 1.01 MB with level 0 in 1ms
+- become 400 kB with level 1 in 10ms
+- become 320 kB with level 9 in 100ms
+
+___
+
+### mem
+
+• `Optional` **mem**: 0 \| 1 \| 2 \| 3 \| 4 \| 5 \| 6 \| 7 \| 8 \| 9 \| 10 \| 11 \| 12
+
+*Inherited from [DeflateOptions](deflateoptions.md).[mem](deflateoptions.md#mem)*
+
+The memory level to use, ranging from 0-12. Increasing this increases speed and compression ratio at the cost of memory.
+
+Note that this is exponential: while level 0 uses 4 kB, level 4 uses 64 kB, level 8 uses 1 MB, and level 12 uses 16 MB.
+It is recommended not to lower the value below 4, since that tends to hurt performance.
+In addition, values above 8 tend to help very little on most data and can even hurt performance.
+
+The default value is automatically determined based on the size of the input data.

+ 9 - 0
docs/interfaces/zippable.md

@@ -0,0 +1,9 @@
+# Interface: Zippable
+
+The complete directory structure of a ZIPpable archive
+
+## Hierarchy
+
+* {}
+
+  ↳ **Zippable**

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 25 - 9
src/index.ts


+ 4 - 3
src/node-worker.ts

@@ -8,11 +8,12 @@ export default (c: string, msg: unknown, transfer: ArrayBuffer[], cb: FlateCallb
     done = true;
     cb(e, d);
   }
-  new Worker(c + workerAdd, { eval: true })
+  const wk = new Worker(c + workerAdd, { eval: true })
     .on('error', e => cb2(e, null))
     .on('message', m => cb2(null, m))
     .on('exit', c => {
       if (!done) cb2(new Error('Exited with code ' + c), null);
-    })
-    .postMessage(msg, transfer);
+    });
+  wk.postMessage(msg, transfer);
+  return () => { done = true; wk.terminate(); }
 }

+ 1 - 0
src/worker.ts

@@ -11,4 +11,5 @@ export default (c: string, msg: unknown, transfer: ArrayBuffer[], cb: FlateCallb
   w.onerror = e => cb2(e.error, null);
   w.onmessage = e => cb2(null, e.data);
   w.postMessage(msg, transfer);
+  return () => w.terminate();
 }

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác