diff options
Diffstat (limited to 'node_modules/multistream')
-rw-r--r-- | node_modules/multistream/LICENSE | 20 | ||||
-rw-r--r-- | node_modules/multistream/README.md | 86 | ||||
-rw-r--r-- | node_modules/multistream/index.js | 166 | ||||
-rw-r--r-- | node_modules/multistream/package.json | 68 |
4 files changed, 340 insertions, 0 deletions
diff --git a/node_modules/multistream/LICENSE b/node_modules/multistream/LICENSE new file mode 100644 index 0000000..c7e6852 --- /dev/null +++ b/node_modules/multistream/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) Feross Aboukhadijeh + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/multistream/README.md b/node_modules/multistream/README.md new file mode 100644 index 0000000..508034e --- /dev/null +++ b/node_modules/multistream/README.md @@ -0,0 +1,86 @@ +# multistream [![travis][travis-image]][travis-url] [![npm][npm-image]][npm-url] [![downloads][downloads-image]][downloads-url] [![javascript style guide][standard-image]][standard-url] + +[travis-image]: https://img.shields.io/travis/feross/multistream/master.svg +[travis-url]: https://travis-ci.org/feross/multistream +[npm-image]: https://img.shields.io/npm/v/multistream.svg +[npm-url]: https://npmjs.org/package/multistream +[downloads-image]: https://img.shields.io/npm/dm/multistream.svg +[downloads-url]: https://npmjs.org/package/multistream +[standard-image]: https://img.shields.io/badge/code_style-standard-brightgreen.svg +[standard-url]: https://standardjs.com + +#### A stream that emits multiple other streams one after another (streams3) + +[![Sauce Test Status](https://saucelabs.com/browser-matrix/multistream.svg)](https://saucelabs.com/u/multistream) + +![cat](https://raw.githubusercontent.com/feross/multistream/master/img.jpg) + +Simple, robust streams3 version of [combined-stream](https://www.npmjs.org/package/combined-stream). Allows you to combine multiple streams into a single stream. When the first stream ends, the next one starts, and so on, until all streams are consumed. + +This module is used by [WebTorrent](http://webtorrent.io), specifically [create-torrent](https://github.com/feross/create-torrent). + +### install + +``` +npm install multistream +``` + +### usage + +Use `multistream` like this: + +```js +var MultiStream = require('multistream') +var fs = require('fs') + +var streams = [ + fs.createReadStream(__dirname + '/numbers/1.txt'), + fs.createReadStream(__dirname + '/numbers/2.txt'), + fs.createReadStream(__dirname + '/numbers/3.txt') +] + +new MultiStream(streams).pipe(process.stdout) // => 123 +``` + +You can also create an object-mode stream with `MultiStream.obj(streams)`. + +To lazily create the streams, wrap them in a function: + +```js +var streams = [ + fs.createReadStream(__dirname + '/numbers/1.txt'), + function () { // will be executed when the stream is active + return fs.createReadStream(__dirname + '/numbers/2.txt') + }, + function () { // same + return fs.createReadStream(__dirname + '/numbers/3.txt') + } +] + +new MultiStream(streams).pipe(process.stdout) // => 123 +``` + +Alternatively, streams may be created by an asynchronous "factory" function: + +```js +var count = 0 +function factory (cb) { + if (count > 3) return cb(null, null) + count++ + setTimeout(function () { + cb(null, fs.createReadStream(__dirname + '/numbers/' + count + '.txt')) + }, 100) +} + +new MultiStream(factory).pipe(process.stdout) // => 123 +``` + +### contributors + +- [Feross Aboukhadijeh](http://feross.org) +- [Mathias Buus](https://github.com/mafintosh/) +- [Yuri Astrakhan](https://github.com/nyurik/) + +### license + +MIT. Copyright (c) [Feross Aboukhadijeh](http://feross.org). diff --git a/node_modules/multistream/index.js b/node_modules/multistream/index.js new file mode 100644 index 0000000..13f03f1 --- /dev/null +++ b/node_modules/multistream/index.js @@ -0,0 +1,166 @@ +/*! multistream. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */ +const stream = require('readable-stream') +const once = require('once') + +function toStreams2Obj (s) { + return toStreams2(s, { objectMode: true, highWaterMark: 16 }) +} + +function toStreams2Buf (s) { + return toStreams2(s) +} + +function toStreams2 (s, opts) { + if (!s || typeof s === 'function' || s._readableState) return s + + const wrap = new stream.Readable(opts).wrap(s) + if (s.destroy) { + wrap.destroy = s.destroy.bind(s) + } + return wrap +} + +class MultiStream extends stream.Readable { + constructor (streams, opts) { + super({ ...opts, autoDestroy: true }) + + this._drained = false + this._forwarding = false + this._current = null + this._toStreams2 = (opts && opts.objectMode) ? toStreams2Obj : toStreams2Buf + + if (typeof streams === 'function') { + this._queue = streams + } else { + this._queue = streams.map(this._toStreams2) + this._queue.forEach(stream => { + if (typeof stream !== 'function') this._attachErrorListener(stream) + }) + } + + this._next() + } + + _read () { + this._drained = true + this._forward() + } + + _forward () { + if (this._forwarding || !this._drained || !this._current) return + this._forwarding = true + + let chunk + while (this._drained && (chunk = this._current.read()) !== null) { + this._drained = this.push(chunk) + } + + this._forwarding = false + } + + _destroy (err, cb) { + let streams = [] + if (this._current) streams.push(this._current) + if (typeof this._queue !== 'function') streams = streams.concat(this._queue) + + if (streams.length === 0) { + cb(err) + } else { + let counter = streams.length + let er = err + streams.forEach(stream => { + destroy(stream, err, err => { + er = er || err + if (--counter === 0) { + cb(er) + } + }) + }) + } + } + + _next () { + this._current = null + + if (typeof this._queue === 'function') { + this._queue((err, stream) => { + if (err) return this.destroy(err) + stream = this._toStreams2(stream) + this._attachErrorListener(stream) + this._gotNextStream(stream) + }) + } else { + let stream = this._queue.shift() + if (typeof stream === 'function') { + stream = this._toStreams2(stream()) + this._attachErrorListener(stream) + } + this._gotNextStream(stream) + } + } + + _gotNextStream (stream) { + if (!stream) { + this.push(null) + return + } + + this._current = stream + this._forward() + + const onReadable = () => { + this._forward() + } + + const onClose = () => { + if (!stream._readableState.ended && !stream.destroyed) { + const err = new Error('ERR_STREAM_PREMATURE_CLOSE') + err.code = 'ERR_STREAM_PREMATURE_CLOSE' + this.destroy(err) + } + } + + const onEnd = () => { + this._current = null + stream.removeListener('readable', onReadable) + stream.removeListener('end', onEnd) + stream.removeListener('close', onClose) + stream.destroy() + this._next() + } + + stream.on('readable', onReadable) + stream.once('end', onEnd) + stream.once('close', onClose) + } + + _attachErrorListener (stream) { + if (!stream) return + + const onError = (err) => { + stream.removeListener('error', onError) + this.destroy(err) + } + + stream.once('error', onError) + } +} + +MultiStream.obj = streams => ( + new MultiStream(streams, { objectMode: true, highWaterMark: 16 }) +) + +module.exports = MultiStream + +// Normalize stream destroy w/ callback. +function destroy (stream, err, cb) { + if (!stream.destroy || stream.destroyed) { + cb(err) + } else { + const callback = once(er => cb(er || err)) + stream + .on('error', callback) + .on('close', () => callback()) + .destroy(err, callback) + } +} diff --git a/node_modules/multistream/package.json b/node_modules/multistream/package.json new file mode 100644 index 0000000..edb6da9 --- /dev/null +++ b/node_modules/multistream/package.json @@ -0,0 +1,68 @@ +{ + "name": "multistream", + "description": "A stream that emits multiple other streams one after another (streams3)", + "version": "4.1.0", + "author": { + "name": "Feross Aboukhadijeh", + "email": "feross@feross.org", + "url": "https://feross.org" + }, + "bugs": { + "url": "https://github.com/feross/multistream/issues" + }, + "dependencies": { + "once": "^1.4.0", + "readable-stream": "^3.6.0" + }, + "devDependencies": { + "airtap": "^3.0.0", + "array-to-stream": "^1.0.2", + "simple-concat": "^1.0.1", + "standard": "*", + "string-to-stream": "^3.0.1", + "tape": "^5.0.1", + "through": "^2.3.8" + }, + "homepage": "https://github.com/feross/multistream", + "keywords": [ + "combine streams", + "join streams", + "concat streams", + "multiple streams", + "combine", + "join", + "concat", + "multiple", + "file stream", + "append", + "append streams", + "combiner", + "joiner" + ], + "license": "MIT", + "main": "index.js", + "repository": { + "type": "git", + "url": "git://github.com/feross/multistream.git" + }, + "scripts": { + "test": "standard && npm run test-node && npm run test-browser", + "test-browser": "airtap -- test/*.js", + "test-browser-local": "airtap --local -- test/*.js", + "test-node": "tape test/*.js" + }, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] +} |