Comparing version 1.2.2 to 1.3.0
@@ -1,2 +0,4 @@ | ||
module.exports = Object.freeze({ | ||
// pull the version number that node is using | ||
const { ZLIB_VERNUM } = require('zlib').constants | ||
module.exports = Object.freeze(Object.assign(Object.create(null), { | ||
Z_NO_FLUSH: 0, | ||
@@ -26,3 +28,3 @@ Z_PARTIAL_FLUSH: 1, | ||
Z_DEFAULT_STRATEGY: 0, | ||
ZLIB_VERNUM: 4736, | ||
ZLIB_VERNUM, | ||
DEFLATE: 1, | ||
@@ -35,2 +37,4 @@ INFLATE: 2, | ||
UNZIP: 7, | ||
BROTLI_DECODE: 8, | ||
BROTLI_ENCODE: 9, | ||
Z_MIN_WINDOWBITS: 8, | ||
@@ -47,3 +51,65 @@ Z_MAX_WINDOWBITS: 15, | ||
Z_MAX_LEVEL: 9, | ||
Z_DEFAULT_LEVEL: -1 | ||
}) | ||
Z_DEFAULT_LEVEL: -1, | ||
BROTLI_OPERATION_PROCESS: 0, | ||
BROTLI_OPERATION_FLUSH: 1, | ||
BROTLI_OPERATION_FINISH: 2, | ||
BROTLI_OPERATION_EMIT_METADATA: 3, | ||
BROTLI_MODE_GENERIC: 0, | ||
BROTLI_MODE_TEXT: 1, | ||
BROTLI_MODE_FONT: 2, | ||
BROTLI_DEFAULT_MODE: 0, | ||
BROTLI_MIN_QUALITY: 0, | ||
BROTLI_MAX_QUALITY: 11, | ||
BROTLI_DEFAULT_QUALITY: 11, | ||
BROTLI_MIN_WINDOW_BITS: 10, | ||
BROTLI_MAX_WINDOW_BITS: 24, | ||
BROTLI_LARGE_MAX_WINDOW_BITS: 30, | ||
BROTLI_DEFAULT_WINDOW: 22, | ||
BROTLI_MIN_INPUT_BLOCK_BITS: 16, | ||
BROTLI_MAX_INPUT_BLOCK_BITS: 24, | ||
BROTLI_PARAM_MODE: 0, | ||
BROTLI_PARAM_QUALITY: 1, | ||
BROTLI_PARAM_LGWIN: 2, | ||
BROTLI_PARAM_LGBLOCK: 3, | ||
BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING: 4, | ||
BROTLI_PARAM_SIZE_HINT: 5, | ||
BROTLI_PARAM_LARGE_WINDOW: 6, | ||
BROTLI_PARAM_NPOSTFIX: 7, | ||
BROTLI_PARAM_NDIRECT: 8, | ||
MAX_VALID_BROTLI_PARAM: 8, | ||
BROTLI_DECODER_RESULT_ERROR: 0, | ||
BROTLI_DECODER_RESULT_SUCCESS: 1, | ||
BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT: 2, | ||
BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT: 3, | ||
BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION: 0, | ||
BROTLI_DECODER_PARAM_LARGE_WINDOW: 1, | ||
BROTLI_DECODER_NO_ERROR: 0, | ||
BROTLI_DECODER_SUCCESS: 1, | ||
BROTLI_DECODER_NEEDS_MORE_INPUT: 2, | ||
BROTLI_DECODER_NEEDS_MORE_OUTPUT: 3, | ||
BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_NIBBLE: -1, | ||
BROTLI_DECODER_ERROR_FORMAT_RESERVED: -2, | ||
BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_META_NIBBLE: -3, | ||
BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET: -4, | ||
BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME: -5, | ||
BROTLI_DECODER_ERROR_FORMAT_CL_SPACE: -6, | ||
BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE: -7, | ||
BROTLI_DECODER_ERROR_FORMAT_CONTEXT_MAP_REPEAT: -8, | ||
BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_1: -9, | ||
BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_2: -10, | ||
BROTLI_DECODER_ERROR_FORMAT_TRANSFORM: -11, | ||
BROTLI_DECODER_ERROR_FORMAT_DICTIONARY: -12, | ||
BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS: -13, | ||
BROTLI_DECODER_ERROR_FORMAT_PADDING_1: -14, | ||
BROTLI_DECODER_ERROR_FORMAT_PADDING_2: -15, | ||
BROTLI_DECODER_ERROR_FORMAT_DISTANCE: -16, | ||
BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET: -19, | ||
BROTLI_DECODER_ERROR_INVALID_ARGUMENTS: -20, | ||
BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES: -21, | ||
BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS: -22, | ||
BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MAP: -25, | ||
BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_1: -26, | ||
BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2: -27, | ||
BROTLI_DECODER_ERROR_ALLOC_BLOCK_TYPE_TREES: -30, | ||
BROTLI_DECODER_ERROR_UNREACHABLE: -31, | ||
})) |
275
index.js
@@ -8,48 +8,6 @@ 'use strict' | ||
const constants = exports.constants = require('./constants.js') | ||
const MiniPass = require('minipass') | ||
const Minipass = require('minipass') | ||
const OriginalBufferConcat = Buffer.concat | ||
class ZlibError extends Error { | ||
constructor (msg, errno) { | ||
super('zlib: ' + msg) | ||
this.errno = errno | ||
this.code = codes.get(errno) | ||
} | ||
get name () { | ||
return 'ZlibError' | ||
} | ||
} | ||
// translation table for return codes. | ||
const codes = new Map([ | ||
[constants.Z_OK, 'Z_OK'], | ||
[constants.Z_STREAM_END, 'Z_STREAM_END'], | ||
[constants.Z_NEED_DICT, 'Z_NEED_DICT'], | ||
[constants.Z_ERRNO, 'Z_ERRNO'], | ||
[constants.Z_STREAM_ERROR, 'Z_STREAM_ERROR'], | ||
[constants.Z_DATA_ERROR, 'Z_DATA_ERROR'], | ||
[constants.Z_MEM_ERROR, 'Z_MEM_ERROR'], | ||
[constants.Z_BUF_ERROR, 'Z_BUF_ERROR'], | ||
[constants.Z_VERSION_ERROR, 'Z_VERSION_ERROR'] | ||
]) | ||
const validFlushFlags = new Set([ | ||
constants.Z_NO_FLUSH, | ||
constants.Z_PARTIAL_FLUSH, | ||
constants.Z_SYNC_FLUSH, | ||
constants.Z_FULL_FLUSH, | ||
constants.Z_FINISH, | ||
constants.Z_BLOCK | ||
]) | ||
const strategies = new Set([ | ||
constants.Z_FILTERED, | ||
constants.Z_HUFFMAN_ONLY, | ||
constants.Z_RLE, | ||
constants.Z_FIXED, | ||
constants.Z_DEFAULT_STRATEGY | ||
]) | ||
// the Zlib class they all inherit from | ||
@@ -61,3 +19,4 @@ // This thing manages the queue of requests, and returns | ||
const _flushFlag = Symbol('flushFlag') | ||
const _finishFlush = Symbol('finishFlush') | ||
const _finishFlushFlag = Symbol('finishFlushFlag') | ||
const _fullFlushFlag = Symbol('fullFlushFlag') | ||
const _handle = Symbol('handle') | ||
@@ -69,55 +28,16 @@ const _onError = Symbol('onError') | ||
const _ended = Symbol('ended') | ||
const _defaultFullFlush = Symbol('_defaultFullFlush') | ||
class Zlib extends MiniPass { | ||
class ZlibBase extends Minipass { | ||
constructor (opts, mode) { | ||
if (!opts || typeof opts !== 'object') | ||
throw new TypeError('invalid options for ZlibBase constructor') | ||
super(opts) | ||
this[_ended] = false | ||
this[_opts] = opts = opts || {} | ||
if (opts.flush && !validFlushFlags.has(opts.flush)) { | ||
throw new TypeError('Invalid flush flag: ' + opts.flush) | ||
} | ||
if (opts.finishFlush && !validFlushFlags.has(opts.finishFlush)) { | ||
throw new TypeError('Invalid flush flag: ' + opts.finishFlush) | ||
} | ||
this[_opts] = opts | ||
this[_flushFlag] = opts.flush || constants.Z_NO_FLUSH | ||
this[_finishFlush] = typeof opts.finishFlush !== 'undefined' ? | ||
opts.finishFlush : constants.Z_FINISH | ||
if (opts.chunkSize) { | ||
if (opts.chunkSize < constants.Z_MIN_CHUNK) { | ||
throw new RangeError('Invalid chunk size: ' + opts.chunkSize) | ||
} | ||
} | ||
if (opts.windowBits) { | ||
if (opts.windowBits < constants.Z_MIN_WINDOWBITS || | ||
opts.windowBits > constants.Z_MAX_WINDOWBITS) { | ||
throw new RangeError('Invalid windowBits: ' + opts.windowBits) | ||
} | ||
} | ||
if (opts.level) { | ||
if (opts.level < constants.Z_MIN_LEVEL || | ||
opts.level > constants.Z_MAX_LEVEL) { | ||
throw new RangeError('Invalid compression level: ' + opts.level) | ||
} | ||
} | ||
if (opts.memLevel) { | ||
if (opts.memLevel < constants.Z_MIN_MEMLEVEL || | ||
opts.memLevel > constants.Z_MAX_MEMLEVEL) { | ||
throw new RangeError('Invalid memLevel: ' + opts.memLevel) | ||
} | ||
} | ||
if (opts.strategy && !(strategies.has(opts.strategy))) | ||
throw new TypeError('Invalid strategy: ' + opts.strategy) | ||
if (opts.dictionary) { | ||
if (!(opts.dictionary instanceof Buffer)) { | ||
throw new TypeError('Invalid dictionary: it should be a Buffer instance') | ||
} | ||
} | ||
this[_flushFlag] = opts.flush | ||
this[_finishFlushFlag] = opts.finishFlush | ||
// this will throw if any options are invalid for the class selected | ||
this[_handle] = new realZlib[mode](opts) | ||
@@ -130,21 +50,7 @@ | ||
this.close() | ||
const error = new ZlibError(err.message, err.errno) | ||
this.emit('error', error) | ||
this.emit('error', err) | ||
} | ||
this[_handle].on('error', this[_onError]) | ||
const level = typeof opts.level === 'number' ? opts.level | ||
: constants.Z_DEFAULT_COMPRESSION | ||
var strategy = typeof opts.strategy === 'number' ? opts.strategy | ||
: constants.Z_DEFAULT_STRATEGY | ||
// API changed in node v9 | ||
/* istanbul ignore next */ | ||
this[_level] = level | ||
this[_strategy] = strategy | ||
this.once('end', this.close) | ||
this[_handle].on('error', er => this[_onError](er)) | ||
this.once('end', () => this.close) | ||
} | ||
@@ -160,43 +66,2 @@ | ||
params (level, strategy) { | ||
if (this[_sawError]) | ||
return | ||
if (!this[_handle]) | ||
throw new Error('cannot switch params when binding is closed') | ||
// no way to test this without also not supporting params at all | ||
/* istanbul ignore if */ | ||
if (!this[_handle].params) | ||
throw new Error('not supported in this implementation') | ||
if (level < constants.Z_MIN_LEVEL || | ||
level > constants.Z_MAX_LEVEL) { | ||
throw new RangeError('Invalid compression level: ' + level) | ||
} | ||
if (!(strategies.has(strategy))) | ||
throw new TypeError('Invalid strategy: ' + strategy) | ||
if (this[_level] !== level || this[_strategy] !== strategy) { | ||
this.flush(constants.Z_SYNC_FLUSH) | ||
assert(this[_handle], 'zlib binding closed') | ||
// .params() calls .flush(), but the latter is always async in the | ||
// core zlib. We override .flush() temporarily to intercept that and | ||
// flush synchronously. | ||
const origFlush = this[_handle].flush | ||
this[_handle].flush = (flushFlag, cb) => { | ||
this[_handle].flush = origFlush | ||
this.flush(flushFlag) | ||
cb() | ||
} | ||
this[_handle].params(level, strategy) | ||
/* istanbul ignore else */ | ||
if (this[_handle]) { | ||
this[_level] = level | ||
this[_strategy] = strategy | ||
} | ||
} | ||
} | ||
reset () { | ||
@@ -209,13 +74,9 @@ if (!this[_sawError]) { | ||
flush (kind) { | ||
if (kind === undefined) | ||
kind = constants.Z_FULL_FLUSH | ||
flush (flushFlag) { | ||
if (this.ended) | ||
return | ||
const flushFlag = this[_flushFlag] | ||
this[_flushFlag] = kind | ||
this.write(Buffer.alloc(0)) | ||
this[_flushFlag] = flushFlag | ||
if (typeof flushFlag !== 'number') | ||
flushFlag = this[_fullFlushFlag] | ||
this.write(Object.assign(Buffer.alloc(0), { [_flushFlag]: flushFlag })) | ||
} | ||
@@ -226,3 +87,3 @@ | ||
this.write(chunk, encoding) | ||
this.flush(this[_finishFlush]) | ||
this.flush(this[_finishFlushFlag]) | ||
this[_ended] = true | ||
@@ -261,7 +122,13 @@ return super.end(null, null, cb) | ||
try { | ||
result = this[_handle]._processChunk(chunk, this[_flushFlag]) | ||
const flushFlag = typeof chunk[_flushFlag] === 'number' | ||
? chunk[_flushFlag] : this[_flushFlag] | ||
result = this[_handle]._processChunk(chunk, flushFlag) | ||
// if we don't throw, reset it back how it was | ||
Buffer.concat = OriginalBufferConcat | ||
} catch (err) { | ||
// or if we do, put Buffer.concat() back before we emit error | ||
// Error events call into user code, which may call Buffer.concat() | ||
Buffer.concat = OriginalBufferConcat | ||
this[_onError](err) | ||
} finally { | ||
Buffer.concat = OriginalBufferConcat | ||
if (this[_handle]) { | ||
@@ -300,2 +167,52 @@ // Core zlib resets `_handle` to null after attempting to close the | ||
class Zlib extends ZlibBase { | ||
constructor (opts, mode) { | ||
opts = opts || {} | ||
opts.flush = opts.flush || constants.Z_NO_FLUSH | ||
opts.finishFlush = opts.finishFlush || constants.Z_FINISH | ||
super(opts, mode) | ||
this[_fullFlushFlag] = constants.Z_FULL_FLUSH | ||
this[_level] = opts.level | ||
this[_strategy] = opts.strategy | ||
} | ||
params (level, strategy) { | ||
if (this[_sawError]) | ||
return | ||
if (!this[_handle]) | ||
throw new Error('cannot switch params when binding is closed') | ||
// no way to test this without also not supporting params at all | ||
/* istanbul ignore if */ | ||
if (!this[_handle].params) | ||
throw new Error('not supported in this implementation') | ||
if (this[_level] !== level || this[_strategy] !== strategy) { | ||
this.flush(constants.Z_SYNC_FLUSH) | ||
assert(this[_handle], 'zlib binding closed') | ||
// .params() calls .flush(), but the latter is always async in the | ||
// core zlib. We override .flush() temporarily to intercept that and | ||
// flush synchronously. | ||
const origFlush = this[_handle].flush | ||
this[_handle].flush = (flushFlag, cb) => { | ||
this.flush(flushFlag) | ||
cb() | ||
} | ||
try { | ||
this[_handle].params(level, strategy) | ||
} finally { | ||
this[_handle].flush = origFlush | ||
} | ||
/* istanbul ignore else */ | ||
if (this[_handle]) { | ||
this[_level] = level | ||
this[_strategy] = strategy | ||
} | ||
} | ||
} | ||
} | ||
// minimal 2-byte header | ||
@@ -347,2 +264,27 @@ class Deflate extends Zlib { | ||
class Brotli extends ZlibBase { | ||
constructor (opts, mode) { | ||
opts = opts || {} | ||
opts.flush = opts.flush || constants.BROTLI_OPERATION_PROCESS | ||
opts.finishFlush = opts.finishFlush || constants.BROTLI_OPERATION_FINISH | ||
super(opts, mode) | ||
this[_fullFlushFlag] = constants.BROTLI_OPERATION_FLUSH | ||
} | ||
} | ||
class BrotliCompress extends Brotli { | ||
constructor (opts) { | ||
super(opts, 'BrotliCompress') | ||
} | ||
} | ||
class BrotliDecompress extends Brotli { | ||
constructor (opts) { | ||
super(opts, 'BrotliDecompress') | ||
} | ||
} | ||
exports.Deflate = Deflate | ||
@@ -355,1 +297,12 @@ exports.Inflate = Inflate | ||
exports.Unzip = Unzip | ||
/* istanbul ignore else */ | ||
if (typeof realZlib.BrotliCompress === 'function') { | ||
exports.BrotliCompress = BrotliCompress | ||
exports.BrotliDecompress = BrotliDecompress | ||
} else { | ||
exports.BrotliCompress = exports.BrotliDecompress = class { | ||
constructor () { | ||
throw new Error('Brotli is not supported in this version of Node.js') | ||
} | ||
} | ||
} |
{ | ||
"name": "minizlib", | ||
"version": "1.2.2", | ||
"version": "1.3.0", | ||
"description": "A small fast zlib stream built on [minipass](http://npm.im/minipass) and Node.js's zlib binding.", | ||
"main": "index.js", | ||
"dependencies": { | ||
"minipass": "^2.2.1" | ||
"minipass": "^2.9.0" | ||
}, | ||
@@ -9,0 +9,0 @@ "scripts": { |
# minizlib | ||
A tiny fast zlib stream built on [minipass](http://npm.im/minipass) | ||
and Node.js's zlib binding. | ||
A fast zlib stream built on [minipass](http://npm.im/minipass) and | ||
Node.js's zlib binding. | ||
This module was created to serve the needs of | ||
[node-tar](http://npm.im/tar) v2. If your needs are different, then | ||
it may not be for you. | ||
[node-tar](http://npm.im/tar) and | ||
[minipass-fetch](http://npm.im/minipass-fetch). | ||
Brotli is supported in versions of node with a Brotli binding. | ||
## How does this differ from the streams in `require('zlib')`? | ||
@@ -14,8 +16,10 @@ | ||
buffer. If you want those, use the built-in `zlib` module. This is | ||
only streams. | ||
only streams. That being said, Minipass streams to make it fairly easy to | ||
use as one-liners: `new zlib.Deflate().end(data).read()` will return the | ||
deflate compressed result. | ||
This module compresses and decompresses the data as fast as you feed | ||
it in. It is synchronous, and runs on the main process thread. Zlib | ||
operations can be high CPU, but they're very fast, and doing it this | ||
way means much less bookkeeping and artificial deferral. | ||
and Brotli operations can be high CPU, but they're very fast, and doing it | ||
this way means much less bookkeeping and artificial deferral. | ||
@@ -26,21 +30,26 @@ Node's built in zlib streams are built on top of `stream.Transform`. | ||
This module _does_ support backpressure, and will buffer output chunks | ||
that are not consumed, but is less of a mediator between the input and | ||
output. There is no high or low watermarks, no state objects, and so | ||
artificial async deferrals. It will not protect you from Zalgo. | ||
See [Minipass](http://npm.im/minipass) for more on the differences between | ||
Node.js core streams and Minipass streams, and the convenience methods | ||
provided by that class. | ||
If you write, data will be emitted right away. If you write | ||
everything synchronously in one tick, and you are listening to the | ||
`data` event to consume it, then it'll all be emitted right away in | ||
that same tick. If you want data to be emitted in the next tick, then | ||
write it in the next tick. | ||
## Classes | ||
It is thus the responsibility of the reader and writer to manage their | ||
own consumption and process execution flow. | ||
- Deflate | ||
- Inflate | ||
- Gzip | ||
- Gunzip | ||
- DeflateRaw | ||
- InflateRaw | ||
- Unzip | ||
- BrotliCompress (Node v10 and higher) | ||
- BrotliDecompress (Node v10 and higher) | ||
The goal is to compress and decompress as fast as possible, even for | ||
files that are too large to store all in one buffer. | ||
## USAGE | ||
The API is very similar to the built-in zlib module. There are | ||
classes that you instantiate with `new` and they are streams that can | ||
be piped together. | ||
```js | ||
const zlib = require('minizlib') | ||
const input = sourceOfCompressedData() | ||
const decode = new zlib.BrotliDecompress() | ||
const output = whereToWriteTheDecodedData() | ||
input.pipe(decode).pipe(output) | ||
``` |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
15402
367
54
Updatedminipass@^2.9.0