You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
'use strict' /* * merge2 * https://github.com/teambition/merge2
* * Copyright (c) 2014-2020 Teambition * Licensed under the MIT license. */ const Stream = require('stream') const PassThrough = Stream.PassThrough const slice = Array.prototype.slice
module.exports = merge2
function merge2 () { const streamsQueue = [] const args = slice.call(arguments) let merging = false let options = args[args.length - 1]
if (options && !Array.isArray(options) && options.pipe == null) { args.pop() } else { options = {} }
const doEnd = options.end !== false const doPipeError = options.pipeError === true if (options.objectMode == null) { options.objectMode = true } if (options.highWaterMark == null) { options.highWaterMark = 64 * 1024 } const mergedStream = PassThrough(options)
function addStream () { for (let i = 0, len = arguments.length; i < len; i++) { streamsQueue.push(pauseStreams(arguments[i], options)) } mergeStream() return this }
function mergeStream () { if (merging) { return } merging = true
let streams = streamsQueue.shift() if (!streams) { process.nextTick(endStream) return } if (!Array.isArray(streams)) { streams = [streams] }
let pipesCount = streams.length + 1
function next () { if (--pipesCount > 0) { return } merging = false mergeStream() }
function pipe (stream) { function onend () { stream.removeListener('merge2UnpipeEnd', onend) stream.removeListener('end', onend) if (doPipeError) { stream.removeListener('error', onerror) } next() } function onerror (err) { mergedStream.emit('error', err) } // skip ended stream
if (stream._readableState.endEmitted) { return next() }
stream.on('merge2UnpipeEnd', onend) stream.on('end', onend)
if (doPipeError) { stream.on('error', onerror) }
stream.pipe(mergedStream, { end: false }) // compatible for old stream
stream.resume() }
for (let i = 0; i < streams.length; i++) { pipe(streams[i]) }
next() }
function endStream () { merging = false // emit 'queueDrain' when all streams merged.
mergedStream.emit('queueDrain') if (doEnd) { mergedStream.end() } }
mergedStream.setMaxListeners(0) mergedStream.add = addStream mergedStream.on('unpipe', function (stream) { stream.emit('merge2UnpipeEnd') })
if (args.length) { addStream.apply(null, args) } return mergedStream }
// check and pause streams for pipe.
function pauseStreams (streams, options) { if (!Array.isArray(streams)) { // Backwards-compat with old-style streams
if (!streams._readableState && streams.pipe) { streams = streams.pipe(PassThrough(options)) } if (!streams._readableState || !streams.pause || !streams.pipe) { throw new Error('Only readable stream can be merged.') } streams.pause() } else { for (let i = 0, len = streams.length; i < len; i++) { streams[i] = pauseStreams(streams[i], options) } } return streams }
|