Comparing version 2.0.2 to 2.1.0
69
index.js
@@ -19,2 +19,3 @@ 'use strict' | ||
const BUFFERSHIFT = Symbol('bufferShift') | ||
const OBJECTMODE = Symbol('objectMode') | ||
@@ -27,3 +28,7 @@ class MiniPass extends EE { | ||
this.buffer = new Yallist() | ||
this[ENCODING] = options && options.encoding || null | ||
this[OBJECTMODE] = options && options.objectMode || false | ||
if (this[OBJECTMODE]) | ||
this[ENCODING] = null | ||
else | ||
this[ENCODING] = options && options.encoding || null | ||
if (this[ENCODING] === 'buffer') | ||
@@ -44,4 +49,15 @@ this[ENCODING] = null | ||
set encoding (enc) { | ||
if (enc !== this[ENCODING]) | ||
if (this[OBJECTMODE]) | ||
this.emit('error', new Error('cannot set encoding in objectMode')) | ||
if (this[ENCODING] && enc !== this[ENCODING] && | ||
(this[DECODER] && this[DECODER].lastNeed || this[BUFFERLENGTH])) | ||
this.emit('error', new Error('cannot change encoding')) | ||
if (this[ENCODING] !== enc) { | ||
this[DECODER] = enc ? new SD(enc) : null | ||
if (this.buffer.length) | ||
this.buffer = this.buffer.map(chunk => this[DECODER].write(chunk)) | ||
} | ||
this[ENCODING] = enc | ||
@@ -61,5 +77,16 @@ } | ||
if (typeof chunk === 'string') | ||
if (!encoding) | ||
encoding = 'utf8' | ||
// fast-path writing strings of same encoding to a stream with | ||
// an empty buffer, skipping the buffer/decoder dance | ||
if (typeof chunk === 'string' && !this[OBJECTMODE] && | ||
// unless it is a string already ready for us to use | ||
!(encoding === this[ENCODING] && !this[DECODER].lastNeed)) { | ||
chunk = new Buffer(chunk, encoding) | ||
} | ||
if (Buffer.isBuffer(chunk) && this[ENCODING]) | ||
chunk = this[DECODER].write(chunk) | ||
try { | ||
@@ -81,7 +108,16 @@ return this.flowing | ||
if (this.buffer.length > 1) | ||
this.buffer = new Yallist([ | ||
Buffer.concat(Array.from(this.buffer), this[BUFFERLENGTH]) | ||
]) | ||
if (this[OBJECTMODE]) | ||
n = null | ||
if (this.buffer.length > 1 && !this[OBJECTMODE]) { | ||
if (this.encoding) | ||
this.buffer = new Yallist([ | ||
Array.from(this.buffer).join('') | ||
]) | ||
else | ||
this.buffer = new Yallist([ | ||
Buffer.concat(Array.from(this.buffer), this[BUFFERLENGTH]) | ||
]) | ||
} | ||
return this[READ](n || null, this.buffer.head.value) | ||
@@ -103,4 +139,6 @@ } finally { | ||
this.emit('data', chunk) | ||
if (!this.buffer.length && !this[EOF]) | ||
this.emit('drain') | ||
return chunk | ||
@@ -149,3 +187,6 @@ } | ||
[BUFFERPUSH] (chunk) { | ||
this[BUFFERLENGTH] += chunk.length | ||
if (this[OBJECTMODE]) | ||
this[BUFFERLENGTH] += 1 | ||
else | ||
this[BUFFERLENGTH] += chunk.length | ||
return this.buffer.push(chunk) | ||
@@ -155,8 +196,11 @@ } | ||
[BUFFERSHIFT] () { | ||
if (this.buffer.length) | ||
this[BUFFERLENGTH] -= this.buffer.head.value.length | ||
if (this.buffer.length) { | ||
if (this[OBJECTMODE]) | ||
this[BUFFERLENGTH] -= 1 | ||
else | ||
this[BUFFERLENGTH] -= this.buffer.head.value.length | ||
} | ||
return this.buffer.shift() | ||
} | ||
[FLUSH] () { | ||
@@ -210,5 +254,2 @@ do {} while (this[FLUSHCHUNK](this[BUFFERSHIFT]())) | ||
if (ev === 'data') { | ||
if (this[DECODER]) | ||
data = this[DECODER].write(data) | ||
if (!data) | ||
@@ -215,0 +256,0 @@ return |
{ | ||
"name": "minipass", | ||
"version": "2.0.2", | ||
"version": "2.1.0", | ||
"description": "minimal implementation of a PassThrough stream", | ||
@@ -11,3 +11,4 @@ "main": "index.js", | ||
"end-of-stream": "^1.4.0", | ||
"tap": "10" | ||
"tap": "10", | ||
"through2": "^2.0.3" | ||
}, | ||
@@ -14,0 +15,0 @@ "scripts": { |
@@ -22,5 +22,8 @@ # minipass | ||
This is not a `through` or `through2` stream. It doesn't transform | ||
the data. It also assumes that the data will be Buffers or strings. | ||
It doesn't support object mode. | ||
the data, it just passes it right through. | ||
If you set `objectMode: true` in the options, then whatever is written | ||
will be emitted. Otherwise, it'll do a minimal amount of Buffer | ||
copying to ensure proper Streams semantics when `read(n)` is called. | ||
For an example of a stream that extends MiniPass to provide transform | ||
@@ -27,0 +30,0 @@ capabilities, check out [minizlib](http://npm.im/minizlib). |
@@ -107,13 +107,50 @@ const MiniPass = require('../') | ||
t.equal(mp.read(0), null) | ||
t.same(mp.read(4), new Buffer(butterfly)) | ||
t.same(mp.read(2), butterfly) | ||
}) | ||
t.test('read with no args', async t => { | ||
const butterfly = '🦋' | ||
const mp = new MiniPass({ encoding: 'utf8' }) | ||
mp.on('data', c => t.equal(c, butterfly)) | ||
mp.pause() | ||
mp.write(new Buffer(butterfly)) | ||
t.same(mp.read(), new Buffer(butterfly)) | ||
t.equal(mp.read(), null) | ||
t.test('buffer -> string', async t => { | ||
const butterfly = '🦋' | ||
const mp = new MiniPass({ encoding: 'utf8' }) | ||
mp.on('data', c => t.equal(c, butterfly)) | ||
mp.pause() | ||
const butterbuf = new Buffer(butterfly) | ||
mp.write(butterbuf.slice(0, 2)) | ||
mp.write(butterbuf.slice(2)) | ||
t.same(mp.read(), butterfly) | ||
t.equal(mp.read(), null) | ||
}) | ||
t.test('buffer -> buffer', async t => { | ||
const butterfly = new Buffer('🦋') | ||
const mp = new MiniPass() | ||
mp.on('data', c => t.same(c, butterfly)) | ||
mp.pause() | ||
mp.write(butterfly.slice(0, 2)) | ||
mp.write(butterfly.slice(2)) | ||
t.same(mp.read(), butterfly) | ||
t.equal(mp.read(), null) | ||
}) | ||
t.test('string -> buffer', async t => { | ||
const butterfly = '🦋' | ||
const butterbuf = new Buffer(butterfly) | ||
const mp = new MiniPass() | ||
mp.on('data', c => t.same(c, butterbuf)) | ||
mp.pause() | ||
mp.write(butterfly) | ||
t.same(mp.read(), butterbuf) | ||
t.equal(mp.read(), null) | ||
}) | ||
t.test('string -> string', async t => { | ||
const butterfly = '🦋' | ||
const mp = new MiniPass({ encoding: 'utf8' }) | ||
mp.on('data', c => t.equal(c, butterfly)) | ||
mp.pause() | ||
mp.write(butterfly[0]) | ||
mp.write(butterfly[1]) | ||
t.same(mp.read(), butterfly) | ||
t.equal(mp.read(), null) | ||
}) | ||
}) | ||
@@ -320,1 +357,74 @@ | ||
}) | ||
t.test('objectMode', t => { | ||
const mp = new MiniPass({ objectMode: true }) | ||
const a = { a: 1 } | ||
const b = { b: 1 } | ||
const out = [] | ||
mp.on('data', c => out.push(c)) | ||
mp.on('end', _ => { | ||
t.equal(out.length, 2) | ||
t.equal(out[0], a) | ||
t.equal(out[1], b) | ||
t.same(out, [ { a: 1 }, { b: 1 } ], 'objs not munged') | ||
t.end() | ||
}) | ||
t.ok(mp.write(a)) | ||
t.ok(mp.write(b)) | ||
mp.end() | ||
}) | ||
t.test('objectMode no encoding', t => { | ||
const mp = new MiniPass({ | ||
objectMode: true, | ||
encoding: 'utf8' | ||
}) | ||
t.equal(mp.encoding, null) | ||
const a = { a: 1 } | ||
const b = { b: 1 } | ||
const out = [] | ||
mp.on('data', c => out.push(c)) | ||
mp.on('end', _ => { | ||
t.equal(out.length, 2) | ||
t.equal(out[0], a) | ||
t.equal(out[1], b) | ||
t.same(out, [ { a: 1 }, { b: 1 } ], 'objs not munged') | ||
t.end() | ||
}) | ||
t.ok(mp.write(a)) | ||
t.ok(mp.write(b)) | ||
mp.end() | ||
}) | ||
t.test('objectMode read() and buffering', t => { | ||
const mp = new MiniPass({ objectMode: true }) | ||
const a = { a: 1 } | ||
const b = { b: 1 } | ||
t.notOk(mp.write(a)) | ||
t.notOk(mp.write(b)) | ||
t.equal(mp.read(2), a) | ||
t.equal(mp.read(), b) | ||
t.end() | ||
}) | ||
t.test('set encoding in object mode throws', async t => | ||
t.throws(_ => new MiniPass({ objectMode: true }).encoding = 'utf8', | ||
new Error('cannot set encoding in objectMode'))) | ||
t.test('set encoding again throws', async t => | ||
t.throws(_ => { | ||
const mp = new MiniPass({ encoding: 'hex' }) | ||
mp.write('ok') | ||
mp.encoding = 'utf8' | ||
}, new Error('cannot change encoding'))) | ||
t.test('set encoding with existing buffer', async t => { | ||
const mp = new MiniPass() | ||
const butterfly = '🦋' | ||
const butterbuf = new Buffer(butterfly) | ||
mp.write(butterbuf.slice(0, 1)) | ||
mp.write(butterbuf.slice(1, 2)) | ||
mp.setEncoding('utf8') | ||
mp.write(butterbuf.slice(2)) | ||
t.equal(mp.read(), butterfly) | ||
}) |
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
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances 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
85512
21
953
40
3
3
3