101arrowz 1 year ago
parent
commit
e81b3e573a

+ 7 - 9
README.md

@@ -58,17 +58,15 @@ You should use either UNPKG or jsDelivr (i.e. only one of the following)
 
 Note that tree shaking is completely unsupported from the CDN. If you want
 a small build without build tools, please ask me and I will make one manually
-with only the features you need. This build is about 27kB, or 9kB gzipped.
-
-You may also want to specify the version, e.g. with [email protected]
+with only the features you need. This build is about 31kB, or 11.5kB gzipped.
 -->
-<script src="https://unpkg.com/fflate"></script>
-<script src="https://cdn.jsdelivr.net/npm/fflate/umd/index.js"></script>
+<script src="https://unpkg.com/[email protected]"></script>
+<script src="https://cdn.jsdelivr.net/npm/fflate@0.8.0/umd/index.js"></script>
 <!-- Now, the global variable fflate contains the library -->
 
 <!-- If you're going buildless but want ESM, import from Skypack -->
 <script type="module">
-  import * as fflate from 'https://cdn.skypack.dev/fflate?min';
+  import * as fflate from 'https://cdn.skypack.dev/fflate@0.8.0?min';
 </script>
 ```
 
@@ -77,8 +75,8 @@ If you are using Deno:
 // Don't use the ?dts Skypack flag; it isn't necessary for Deno support
 // The @deno-types comment adds TypeScript typings
 
-// @deno-types="https://cdn.skypack.dev/fflate/lib/index.d.ts"
-import * as fflate from 'https://cdn.skypack.dev/fflate?min';
+// @deno-types="https://cdn.skypack.dev/fflate@0.8.0/lib/index.d.ts"
+import * as fflate from 'https://cdn.skypack.dev/fflate@0.8.0?min';
 ```
 
 
@@ -509,7 +507,7 @@ See the [documentation](https://github.com/101arrowz/fflate/blob/master/docs/REA
 
 The bundle size measurements for `fflate` on sites like Bundlephobia include every feature of the library and should be seen as an upper bound. As long as you are using tree shaking or dead code elimination, this table should give you a general idea of `fflate`'s bundle size for the features you need.
 
-The maximum bundle size that is possible with `fflate` is about 31kB if you use every single feature, but feature parity with `pako` is only around 10kB (as opposed to 45kB from `pako`). If your bundle size increases dramatically after adding `fflate`, please [create an issue](https://github.com/101arrowz/fflate/issues/new).
+The maximum bundle size that is possible with `fflate` is about 31kB (11.5kB gzipped) if you use every single feature, but feature parity with `pako` is only around 10kB (as opposed to 45kB from `pako`). If your bundle size increases dramatically after adding `fflate`, please [create an issue](https://github.com/101arrowz/fflate/issues/new).
 
 | Feature                 | Bundle size (minified)         | Nearest competitor      |
 |-------------------------|--------------------------------|-------------------------|

+ 13 - 2
docs/README.md

@@ -68,6 +68,7 @@
 * [AsyncZippableFile](README.md#asynczippablefile)
 * [FlateCallback](README.md#flatecallback)
 * [FlateStreamHandler](README.md#flatestreamhandler)
+* [GunzipMemberHandler](README.md#gunzipmemberhandler)
 * [StringStreamHandler](README.md#stringstreamhandler)
 * [UnzipCallback](README.md#unzipcallback)
 * [UnzipFileFilter](README.md#unzipfilefilter)
@@ -149,6 +150,16 @@ Handler for data (de)compression streams
 
 ___
 
+### GunzipMemberHandler
+
+Ƭ  **GunzipMemberHandler**: (offset: number) => void
+
+Handler for new GZIP members in concatenated GZIP streams. Useful for building indices used to perform random-access reads on compressed files.
+
+**`param`** The offset of the new member relative to the start of the stream
+
+___
+
 ### StringStreamHandler
 
 Ƭ  **StringStreamHandler**: (data: string,final: boolean) => void
@@ -264,7 +275,7 @@ ___
 
 ### decompressSync
 
-▸ **decompressSync**(`data`: Uint8Array, `opts?`: [AsyncInflateOptions](interfaces/asyncinflateoptions.md)): Uint8Array
+▸ **decompressSync**(`data`: Uint8Array, `opts?`: [InflateOptions](interfaces/inflateoptions.md)): Uint8Array
 
 Expands compressed GZIP, Zlib, or raw DEFLATE data, automatically detecting the format
 
@@ -273,7 +284,7 @@ Expands compressed GZIP, Zlib, or raw DEFLATE data, automatically detecting the
 Name | Type | Description |
 ------ | ------ | ------ |
 `data` | Uint8Array | The data to decompress |
-`opts?` | [AsyncInflateOptions](interfaces/asyncinflateoptions.md) | The decompression options |
+`opts?` | [InflateOptions](interfaces/inflateoptions.md) | The decompression options |
 
 **Returns:** Uint8Array
 

+ 13 - 0
docs/classes/asyncdecompress.md

@@ -24,6 +24,19 @@ Asynchronous streaming GZIP, Zlib, or raw DEFLATE decompression
 
 ### constructor
 
+\+ **new AsyncDecompress**(`opts`: [InflateStreamOptions](../interfaces/inflatestreamoptions.md), `cb?`: [AsyncFlateStreamHandler](../README.md#asyncflatestreamhandler)): [AsyncDecompress](asyncdecompress.md)
+
+Creates an asynchronous decompression stream
+
+#### Parameters:
+
+Name | Type | Description |
+------ | ------ | ------ |
+`opts` | [InflateStreamOptions](../interfaces/inflatestreamoptions.md) | The decompression options |
+`cb?` | [AsyncFlateStreamHandler](../README.md#asyncflatestreamhandler) | The callback to call whenever data is decompressed  |
+
+**Returns:** [AsyncDecompress](asyncdecompress.md)
+
 \+ **new AsyncDecompress**(`cb?`: [AsyncFlateStreamHandler](../README.md#asyncflatestreamhandler)): [AsyncDecompress](asyncdecompress.md)
 
 Creates an asynchronous decompression stream

+ 23 - 1
docs/classes/asyncgunzip.md

@@ -15,6 +15,7 @@ Asynchronous streaming single or multi-member GZIP decompression
 ### Properties
 
 * [ondata](asyncgunzip.md#ondata)
+* [onmember](asyncgunzip.md#onmember)
 * [terminate](asyncgunzip.md#terminate)
 
 ### Methods
@@ -25,6 +26,19 @@ Asynchronous streaming single or multi-member GZIP decompression
 
 ### constructor
 
+\+ **new AsyncGunzip**(`opts`: [GunzipStreamOptions](../interfaces/gunzipstreamoptions.md), `cb?`: [AsyncFlateStreamHandler](../README.md#asyncflatestreamhandler)): [AsyncGunzip](asyncgunzip.md)
+
+Creates an asynchronous GUNZIP stream
+
+#### Parameters:
+
+Name | Type | Description |
+------ | ------ | ------ |
+`opts` | [GunzipStreamOptions](../interfaces/gunzipstreamoptions.md) | The decompression options |
+`cb?` | [AsyncFlateStreamHandler](../README.md#asyncflatestreamhandler) | The callback to call whenever data is inflated  |
+
+**Returns:** [AsyncGunzip](asyncgunzip.md)
+
 \+ **new AsyncGunzip**(`cb?`: [AsyncFlateStreamHandler](../README.md#asyncflatestreamhandler)): [AsyncGunzip](asyncgunzip.md)
 
 Creates an asynchronous GUNZIP stream
@@ -33,7 +47,7 @@ Creates an asynchronous GUNZIP stream
 
 Name | Type | Description |
 ------ | ------ | ------ |
-`cb?` | [AsyncFlateStreamHandler](../README.md#asyncflatestreamhandler) | The callback to call whenever data is deflated  |
+`cb?` | [AsyncFlateStreamHandler](../README.md#asyncflatestreamhandler) | The callback to call whenever data is inflated  |
 
 **Returns:** [AsyncGunzip](asyncgunzip.md)
 
@@ -47,6 +61,14 @@ The handler to call whenever data is available
 
 ___
 
+### onmember
+
+• `Optional` **onmember**: [GunzipMemberHandler](../README.md#gunzipmemberhandler)
+
+The handler to call whenever a new GZIP member is found
+
+___
+
 ### terminate
 
 •  **terminate**: [AsyncTerminable](../interfaces/asyncterminable.md)

+ 15 - 2
docs/classes/asyncinflate.md

@@ -25,15 +25,28 @@ Asynchronous streaming DEFLATE decompression
 
 ### constructor
 
+\+ **new AsyncInflate**(`opts`: [InflateStreamOptions](../interfaces/inflatestreamoptions.md), `cb?`: [AsyncFlateStreamHandler](../README.md#asyncflatestreamhandler)): [AsyncInflate](asyncinflate.md)
+
+Creates an asynchronous DEFLATE decompression stream
+
+#### Parameters:
+
+Name | Type | Description |
+------ | ------ | ------ |
+`opts` | [InflateStreamOptions](../interfaces/inflatestreamoptions.md) | The decompression options |
+`cb?` | [AsyncFlateStreamHandler](../README.md#asyncflatestreamhandler) | The callback to call whenever data is inflated  |
+
+**Returns:** [AsyncInflate](asyncinflate.md)
+
 \+ **new AsyncInflate**(`cb?`: [AsyncFlateStreamHandler](../README.md#asyncflatestreamhandler)): [AsyncInflate](asyncinflate.md)
 
-Creates an asynchronous inflation stream
+Creates an asynchronous DEFLATE decompression stream
 
 #### Parameters:
 
 Name | Type | Description |
 ------ | ------ | ------ |
-`cb?` | [AsyncFlateStreamHandler](../README.md#asyncflatestreamhandler) | The callback to call whenever data is deflated  |
+`cb?` | [AsyncFlateStreamHandler](../README.md#asyncflatestreamhandler) | The callback to call whenever data is inflated  |
 
 **Returns:** [AsyncInflate](asyncinflate.md)
 

+ 14 - 1
docs/classes/asyncunzlib.md

@@ -25,6 +25,19 @@ Asynchronous streaming Zlib decompression
 
 ### constructor
 
+\+ **new AsyncUnzlib**(`opts`: [UnzlibStreamOptions](../interfaces/unzlibstreamoptions.md), `cb?`: [AsyncFlateStreamHandler](../README.md#asyncflatestreamhandler)): [AsyncUnzlib](asyncunzlib.md)
+
+Creates an asynchronous Zlib decompression stream
+
+#### Parameters:
+
+Name | Type | Description |
+------ | ------ | ------ |
+`opts` | [UnzlibStreamOptions](../interfaces/unzlibstreamoptions.md) | The decompression options |
+`cb?` | [AsyncFlateStreamHandler](../README.md#asyncflatestreamhandler) | The callback to call whenever data is inflated  |
+
+**Returns:** [AsyncUnzlib](asyncunzlib.md)
+
 \+ **new AsyncUnzlib**(`cb?`: [AsyncFlateStreamHandler](../README.md#asyncflatestreamhandler)): [AsyncUnzlib](asyncunzlib.md)
 
 Creates an asynchronous Zlib decompression stream
@@ -33,7 +46,7 @@ Creates an asynchronous Zlib decompression stream
 
 Name | Type | Description |
 ------ | ------ | ------ |
-`cb?` | [AsyncFlateStreamHandler](../README.md#asyncflatestreamhandler) | The callback to call whenever data is deflated  |
+`cb?` | [AsyncFlateStreamHandler](../README.md#asyncflatestreamhandler) | The callback to call whenever data is inflated  |
 
 **Returns:** [AsyncUnzlib](asyncunzlib.md)
 

+ 1 - 1
docs/classes/asynczipdeflate.md

@@ -42,7 +42,7 @@ Asynchronous streaming DEFLATE compression for ZIP archives
 
 \+ **new AsyncZipDeflate**(`filename`: string, `opts?`: [DeflateOptions](../interfaces/deflateoptions.md)): [AsyncZipDeflate](asynczipdeflate.md)
 
-Creates a DEFLATE stream that can be added to ZIP archives
+Creates an asynchronous DEFLATE stream that can be added to ZIP archives
 
 #### Parameters:
 

+ 2 - 2
docs/classes/asynczlib.md

@@ -27,7 +27,7 @@ Asynchronous streaming Zlib compression
 
 \+ **new AsyncZlib**(`opts`: [ZlibOptions](../interfaces/zliboptions.md), `cb?`: [AsyncFlateStreamHandler](../README.md#asyncflatestreamhandler)): [AsyncZlib](asynczlib.md)
 
-Creates an asynchronous DEFLATE stream
+Creates an asynchronous Zlib stream
 
 #### Parameters:
 
@@ -40,7 +40,7 @@ Name | Type | Description |
 
 \+ **new AsyncZlib**(`cb?`: [AsyncFlateStreamHandler](../README.md#asyncflatestreamhandler)): [AsyncZlib](asynczlib.md)
 
-Creates an asynchronous DEFLATE stream
+Creates an asynchronous Zlib stream
 
 #### Parameters:
 

+ 15 - 2
docs/classes/decompress.md

@@ -24,7 +24,7 @@ Streaming GZIP, Zlib, or raw DEFLATE decompression
 
 ### constructor
 
-\+ **new Decompress**(`cb?`: [FlateStreamHandler](../README.md#flatestreamhandler)): [Decompress](decompress.md)
+\+ **new Decompress**(`opts`: [InflateStreamOptions](../interfaces/inflatestreamoptions.md), `cb?`: [AsyncFlateStreamHandler](../README.md#asyncflatestreamhandler)): [Decompress](decompress.md)
 
 Creates a decompression stream
 
@@ -32,7 +32,20 @@ Creates a decompression stream
 
 Name | Type | Description |
 ------ | ------ | ------ |
-`cb?` | [FlateStreamHandler](../README.md#flatestreamhandler) | The callback to call whenever data is decompressed  |
+`opts` | [InflateStreamOptions](../interfaces/inflatestreamoptions.md) | The decompression options |
+`cb?` | [AsyncFlateStreamHandler](../README.md#asyncflatestreamhandler) | The callback to call whenever data is decompressed  |
+
+**Returns:** [Decompress](decompress.md)
+
+\+ **new Decompress**(`cb?`: [AsyncFlateStreamHandler](../README.md#asyncflatestreamhandler)): [Decompress](decompress.md)
+
+Creates a decompression stream
+
+#### Parameters:
+
+Name | Type | Description |
+------ | ------ | ------ |
+`cb?` | [AsyncFlateStreamHandler](../README.md#asyncflatestreamhandler) | The callback to call whenever data is decompressed  |
 
 **Returns:** [Decompress](decompress.md)
 

+ 9 - 0
docs/classes/gunzip.md

@@ -15,6 +15,7 @@ Streaming single or multi-member GZIP decompression
 ### Properties
 
 * [ondata](gunzip.md#ondata)
+* [onmember](gunzip.md#onmember)
 
 ### Methods
 
@@ -57,6 +58,14 @@ Name | Type | Description |
 
 The handler to call whenever data is available
 
+___
+
+### onmember
+
+• `Optional` **onmember**: [GunzipMemberHandler](../README.md#gunzipmemberhandler)
+
+The handler to call whenever a new GZIP member is found
+
 ## Methods
 
 ### push

+ 119 - 65
src/index.ts

@@ -739,15 +739,17 @@ const dflt = (dat: Uint8Array, lvl: number, plvl: number, pre: number, post: num
       st.h = head, st.p = prev, st.i = i, st.w = wi;
     }
   } else {
-    for (let i = 0; i <= s; i += 65535) {
+    for (let i = st.w || 0; i < s + lst; i += 65535) {
       // end
-      const e = i + 65535;
+      let e = i + 65535;
       if (e >= s) {
         // write final block
         w[(pos / 8) | 0] = lst;
+        e = s;
       }
       pos = wfblk(w, pos + 1, dat.subarray(i, e));
     }
+    st.i = s;
   }
   return slc(o, 0, pre + shft(pos) + post);
 }
@@ -1131,7 +1133,7 @@ const astrm = (strm: CmpDecmpStrm) => {
 type Astrm = { ondata: AsyncFlateStreamHandler; push: (d: Uint8Array, f?: boolean) => void; terminate: AsyncTerminable; };
 
 // async stream attach
-const astrmify = <T>(fns: (() => unknown[])[], strm: Astrm, opts: T | 0, init: (ev: MessageEvent<T>) => void, id: number) => {
+const astrmify = <T>(fns: (() => unknown[])[], strm: Astrm, opts: T | 0, init: (ev: MessageEvent<T>) => void, id: number, ext?: (msg: unknown) => unknown) => {
   let t: boolean;
   const w = wrkr<T, [Uint8Array, boolean]>(
     fns,
@@ -1139,6 +1141,7 @@ const astrmify = <T>(fns: (() => unknown[])[], strm: Astrm, opts: T | 0, init: (
     id,
     (err, dat) => {
       if (err) w.terminate(), strm.ondata.call(strm, err);
+      else if (!Array.isArray(dat)) ext(dat);
       else {
         if (dat[1]) w.terminate();
         strm.ondata.call(strm, err, dat[0], dat[1]);
@@ -1218,20 +1221,12 @@ const zls = (d: Uint8Array, dict?: unknown) => {
   return (d[1] >> 3 & 4) + 2;
 }
 
-/**
- * Creates an asynchronous compression stream
- * @param opts The compression options
- * @param cb The callback to call whenever data is deflated
- */
-function AsyncCmpStrm<T>(opts: T, cb?: AsyncFlateStreamHandler): T;
-/**
- * Creates an asynchronous compression stream
- * @param cb The callback to call whenever data is deflated
- */
-function AsyncCmpStrm<T>(cb?: AsyncFlateStreamHandler): T;
-function AsyncCmpStrm<T>(opts?: T | AsyncFlateStreamHandler, cb?: AsyncFlateStreamHandler): T {
-  if (!cb && typeof opts == 'function') cb = opts as AsyncFlateStreamHandler, opts = {} as T;
-  this.ondata = cb as AsyncFlateStreamHandler;
+// stream options and callback
+function StrmOpt<T, H>(opts: T, cb?: H): T;
+function StrmOpt<T, H>(cb?: H): T;
+function StrmOpt<T, H>(opts?: T | H, cb?: H): T {
+  if (typeof opts == 'function') cb = opts as H, opts = {} as T;
+  this.ondata = cb as H;
   return opts as T;
 }
 
@@ -1251,7 +1246,7 @@ export class Deflate {
    */
   constructor(cb?: FlateStreamHandler);
   constructor(opts?: DeflateOptions | FlateStreamHandler, cb?: FlateStreamHandler) {
-    if (!cb && typeof opts == 'function') cb = opts as FlateStreamHandler, opts = {};
+    if (typeof opts == 'function') cb = opts as FlateStreamHandler, opts = {};
     this.ondata = cb;
     this.o = (opts as DeflateOptions) || {};
     this.s = { l: 0, i: 32768, w: 32768, z: 32768 };
@@ -1307,9 +1302,9 @@ export class Deflate {
     }
     this.s.l = (final as unknown as number) & 1;
     if (this.s.z > this.s.w + 8191 || final) {
-        this.p(this.b, final || false);
-        this.s.w = this.s.i, this.s.i -= 2;
-      }
+      this.p(this.b, final || false);
+      this.s.w = this.s.i, this.s.i -= 2;
+    }
   }
 }
 
@@ -1337,7 +1332,7 @@ export class AsyncDeflate {
     astrmify([
       bDflt,
       () => [astrm, Deflate]
-    ], this as unknown as Astrm, AsyncCmpStrm.call(this, opts, cb), ev => {
+    ], this as unknown as Astrm, StrmOpt.call(this, opts, cb), ev => {
       const strm = new Deflate(ev.data);
       onmessage = astrm(strm);
     }, 6);
@@ -1415,7 +1410,8 @@ export class Inflate {
    */
   constructor(cb?: FlateStreamHandler);
   constructor(opts?: InflateStreamOptions | FlateStreamHandler, cb?: FlateStreamHandler) {
-    if (!cb && typeof opts == 'function') cb = opts as FlateStreamHandler, opts = {};
+    // no StrmOpt here to avoid adding to workerizer
+    if (typeof opts == 'function') cb = opts as FlateStreamHandler, opts = {};
     this.ondata = cb;
     const dict = opts && (opts as InflateStreamOptions).dictionary && (opts as InflateStreamOptions).dictionary.subarray(-32768);
     this.s = { i: 0, b: dict ? dict.length : 0 };
@@ -1463,16 +1459,22 @@ export class AsyncInflate {
   ondata: AsyncFlateStreamHandler;
 
   /**
-   * Creates an asynchronous inflation stream
-   * @param cb The callback to call whenever data is deflated
+   * Creates an asynchronous DEFLATE decompression stream
+   * @param opts The decompression options
+   * @param cb The callback to call whenever data is inflated
    */
-  constructor(cb?: AsyncFlateStreamHandler) {
-    this.ondata = cb;
+  constructor(opts: InflateStreamOptions, cb?: AsyncFlateStreamHandler);
+  /**
+   * Creates an asynchronous DEFLATE decompression stream
+   * @param cb The callback to call whenever data is inflated
+   */
+  constructor(cb?: AsyncFlateStreamHandler);
+  constructor(opts?: InflateStreamOptions | AsyncFlateStreamHandler, cb?: AsyncFlateStreamHandler) {
     astrmify([
       bInflt,
       () => [astrm, Inflate]
-    ], this as unknown as Astrm, 0, () => {
-      const strm = new Inflate();
+    ], this as unknown as Astrm, StrmOpt.call(this, opts, cb), ev => {
+      const strm = new Inflate(ev.data);
       onmessage = astrm(strm);
     }, 7);
   }
@@ -1600,7 +1602,7 @@ export class AsyncGzip {
       bDflt,
       gze,
       () => [astrm, Deflate, Gzip]
-    ], this as unknown as Astrm, AsyncCmpStrm.call(this, opts, cb), ev => {
+    ], this as unknown as Astrm, StrmOpt.call(this, opts, cb), ev => {
       const strm = new Gzip(ev.data);
       onmessage = astrm(strm);
     }, 8);
@@ -1660,11 +1662,18 @@ export function gzipSync(data: Uint8Array, opts?: GzipOptions) {
   return gzh(d, opts), wbytes(d, s - 8, c.d()), wbytes(d, s - 4, l), d;
 }
 
+/**
+ * Handler for new GZIP members in concatenated GZIP streams. Useful for building indices used to perform random-access reads on compressed files.
+ * @param offset The offset of the new member relative to the start of the stream
+ */
+export type GunzipMemberHandler = (offset: number) => void;
+
 /**
  * Streaming single or multi-member GZIP decompression
  */
 export class Gunzip {
   private v = 1;
+  private r = 0;
   private o: Uint8Array;
   private p: Uint8Array;
   private s: InflateState;
@@ -1672,6 +1681,10 @@ export class Gunzip {
    * The handler to call whenever data is available
    */
   ondata: FlateStreamHandler;
+  /**
+   * The handler to call whenever a new GZIP member is found
+   */
+  onmember?: GunzipMemberHandler;
 
   /**
    * Creates a GUNZIP stream
@@ -1695,10 +1708,15 @@ export class Gunzip {
    */
   push(chunk: Uint8Array, final?: boolean) {
     (Inflate.prototype as unknown as { e: typeof Inflate.prototype['e'] }).e.call(this, chunk);
+    this.r += chunk.length;
     if (this.v) {
       const p = this.p.subarray(this.v - 1);
       const s = p.length > 3 ? gzs(p) : 4;
-      if (s >= p.length && !final) return;
+      if (s > p.length) {
+        if (!final) return;
+      } else if (this.v > 1 && this.onmember) {
+        this.onmember(this.r - p.length);
+      }
       this.p = p.subarray(s), this.v = 0;
     }
     // necessary to prevent TS from using the closure value
@@ -1706,10 +1724,8 @@ export class Gunzip {
     (Inflate.prototype as unknown as { c: typeof Inflate.prototype['c'] }).c.call(this, final);
     // process concatenated GZIP
     if (this.s.f && !this.s.l) {
-      const need = shft(this.s.p) + 8;
+      this.v = shft(this.s.p) + 9;
       this.s = { i: 0 };
-      this.v = Math.max(need - this.p.length, 0) + 1;
-      this.p = this.p.subarray(need);
       this.o = new u8(0);
       if (this.p.length) this.push(new u8(0), final);
     }
@@ -1724,21 +1740,32 @@ export class AsyncGunzip {
    * The handler to call whenever data is available
    */
   ondata: AsyncFlateStreamHandler;
+  /**
+   * The handler to call whenever a new GZIP member is found
+   */
+  onmember?: GunzipMemberHandler;
 
   /**
    * Creates an asynchronous GUNZIP stream
-   * @param cb The callback to call whenever data is deflated
+   * @param opts The decompression options
+   * @param cb The callback to call whenever data is inflated
    */
-  constructor(cb?: AsyncFlateStreamHandler) {
-    this.ondata = cb;
+  constructor(opts: GunzipStreamOptions, cb?: AsyncFlateStreamHandler);
+  /**
+   * Creates an asynchronous GUNZIP stream
+   * @param cb The callback to call whenever data is inflated
+   */
+  constructor(cb?: AsyncFlateStreamHandler);
+  constructor(opts?: GunzipStreamOptions | AsyncFlateStreamHandler, cb?: AsyncFlateStreamHandler) {
     astrmify([
       bInflt,
       guze,
       () => [astrm, Inflate, Gunzip]
-    ], this as unknown as Astrm, 0, () => {
-      const strm = new Gunzip();
+    ], this as unknown as Astrm, StrmOpt.call(this, opts, cb), ev => {
+      const strm = new Gunzip(ev.data);
+      strm.onmember = (offset) => (postMessage as Worker['postMessage'])(offset);
       onmessage = astrm(strm);
-    }, 9);
+    }, 9, offset => this.onmember && this.onmember(offset as number));
   }
 
   /**
@@ -1778,7 +1805,7 @@ export function gunzip(data: Uint8Array, opts: AsyncGunzipOptions | FlateCallbac
     bInflt,
     guze,
     () => [gunzipSync]
-  ], ev => pbf(gunzipSync(ev.data[0])), 3, cb);
+  ], ev => pbf(gunzipSync(ev.data[0], ev.data[1])), 3, cb);
 }
 
 /**
@@ -1849,13 +1876,13 @@ export class AsyncZlib {
   ondata: AsyncFlateStreamHandler;
 
   /**
-   * Creates an asynchronous DEFLATE stream
+   * Creates an asynchronous Zlib stream
    * @param opts The compression options
    * @param cb The callback to call whenever data is deflated
    */
   constructor(opts: ZlibOptions, cb?: AsyncFlateStreamHandler);
   /**
-   * Creates an asynchronous DEFLATE stream
+   * Creates an asynchronous Zlib stream
    * @param cb The callback to call whenever data is deflated
    */
   constructor(cb?: AsyncFlateStreamHandler);
@@ -1864,7 +1891,7 @@ export class AsyncZlib {
       bDflt,
       zle,
       () => [astrm, Deflate, Zlib]
-    ], this as unknown as Astrm, AsyncCmpStrm.call(this, opts, cb), ev => {
+    ], this as unknown as Astrm, StrmOpt.call(this, opts, cb), ev => {
       const strm = new Zlib(ev.data);
       onmessage = astrm(strm);
     }, 10);
@@ -1947,7 +1974,7 @@ export class Unzlib {
   constructor(cb?: FlateStreamHandler);
   constructor(opts?: UnzlibStreamOptions | FlateStreamHandler, cb?: FlateStreamHandler) {
     Inflate.call(this, opts, cb);
-    this.v = cb && opts && (opts as UnzlibStreamOptions).dictionary ? 2 : 1;
+    this.v = opts && (opts as UnzlibStreamOptions).dictionary ? 2 : 1;
   }
 
   /**
@@ -1982,16 +2009,22 @@ export class AsyncUnzlib {
 
   /**
    * Creates an asynchronous Zlib decompression stream
-   * @param cb The callback to call whenever data is deflated
+   * @param opts The decompression options
+   * @param cb The callback to call whenever data is inflated
    */
-  constructor(cb?: AsyncFlateStreamHandler) {
-    this.ondata = cb;
+  constructor(opts: UnzlibStreamOptions, cb?: AsyncFlateStreamHandler);
+  /**
+   * Creates an asynchronous Zlib decompression stream
+   * @param cb The callback to call whenever data is inflated
+   */
+  constructor(cb?: AsyncFlateStreamHandler);
+  constructor(opts?: UnzlibStreamOptions | AsyncFlateStreamHandler, cb?: AsyncFlateStreamHandler) {
     astrmify([
       bInflt,
       zule,
       () => [astrm, Inflate, Unzlib]
-    ], this as unknown as Astrm, 0, () => {
-      const strm = new Unzlib();
+    ], this as unknown as Astrm, StrmOpt.call(this, opts, cb), ev => {
+      const strm = new Unzlib(ev.data);
       onmessage = astrm(strm);
     }, 11);
   }
@@ -2057,17 +2090,28 @@ export class Decompress {
   private G = Gunzip;
   private I = Inflate;
   private Z = Unzlib;
+  private o: InflateOptions;
+  private s: Inflate | Gunzip | Unzlib;
+  private p: Uint8Array;
+  /**
+   * The handler to call whenever data is available
+   */
+  ondata: FlateStreamHandler;
+
   /**
    * Creates a decompression stream
+   * @param opts The decompression options
    * @param cb The callback to call whenever data is decompressed
    */
-  constructor(cb?: FlateStreamHandler) { this.ondata = cb; }
-  private s: Inflate | Gunzip | Unzlib;
+  constructor(opts: InflateStreamOptions, cb?: AsyncFlateStreamHandler);
   /**
-   * The handler to call whenever data is available
+   * Creates a decompression stream
+   * @param cb The callback to call whenever data is decompressed
    */
-  ondata: FlateStreamHandler;
-  private p: Uint8Array;
+  constructor(cb?: AsyncFlateStreamHandler);
+  constructor(opts?: InflateStreamOptions | AsyncFlateStreamHandler, cb?: AsyncFlateStreamHandler) {
+    this.o = StrmOpt.call(this, opts, cb) || {};
+  }
 
   /**
    * Pushes a chunk to be decompressed
@@ -2083,12 +2127,13 @@ export class Decompress {
       } else this.p = chunk;
       if (this.p.length > 2) {
         const _this = this;
+        // enables reuse of this method by AsyncDecompress
         const cb: FlateStreamHandler = function() { _this.ondata.apply(_this, arguments); }
         this.s = (this.p[0] == 31 && this.p[1] == 139 && this.p[2] == 8)
-          ? new this.G(cb)
+          ? new this.G(this.o, cb)
           : ((this.p[0] & 15) != 8 || (this.p[0] >> 4) > 7 || ((this.p[0] << 8 | this.p[1]) % 31))
-            ? new this.I(cb)
-            : new this.Z(cb);
+            ? new this.I(this.o, cb)
+            : new this.Z(this.o, cb);
         this.s.push(this.p, final);
         this.p = null;
       }
@@ -2103,16 +2148,25 @@ export class AsyncDecompress {
   private G = AsyncGunzip;
   private I = AsyncInflate;
   private Z = AsyncUnzlib;
-    /**
+  /**
+   * The handler to call whenever data is available
+   */
+  ondata: AsyncFlateStreamHandler;
+
+  /**
    * Creates an asynchronous decompression stream
+   * @param opts The decompression options
    * @param cb The callback to call whenever data is decompressed
    */
-  constructor(cb?: AsyncFlateStreamHandler) { this.ondata = cb; }
-  
+  constructor(opts: InflateStreamOptions, cb?: AsyncFlateStreamHandler);
   /**
-   * The handler to call whenever data is available
+   * Creates an asynchronous decompression stream
+   * @param cb The callback to call whenever data is decompressed
    */
-  ondata: AsyncFlateStreamHandler;
+  constructor(cb?: AsyncFlateStreamHandler);
+  constructor(opts?: InflateStreamOptions | AsyncFlateStreamHandler, cb?: AsyncFlateStreamHandler) {
+    Decompress.call(this, opts, cb);
+  }
 
   /**
    * Pushes a chunk to be decompressed
@@ -2155,7 +2209,7 @@ export function decompress(data: Uint8Array, opts: AsyncInflateOptions | FlateCa
  * @param opts The decompression options
  * @returns The decompressed version of the data
  */
-export function decompressSync(data: Uint8Array, opts?: AsyncInflateOptions) {
+export function decompressSync(data: Uint8Array, opts?: InflateOptions) {
   return (data[0] == 31 && data[1] == 139 && data[2] == 8)
     ? gunzipSync(data, opts)
     : ((data[0] & 15) != 8 || (data[0] >> 4) > 7 || ((data[0] << 8 | data[1]) % 31))
@@ -2772,7 +2826,7 @@ export class AsyncZipDeflate implements ZipInputFile {
   terminate: AsyncTerminable;
 
   /**
-   * Creates a DEFLATE stream that can be added to ZIP archives
+   * Creates an asynchronous DEFLATE stream that can be added to ZIP archives
    * @param filename The filename to associate with this data stream
    * @param opts The compression options
    */