pax_global_header00006660000000000000000000000064130157425120014512gustar00rootroot0000000000000052 comment=1b33da64b219dcc8bf33645953c32a6fd9e3b36d merge-stream-1.0.1/000077500000000000000000000000001301574251200141015ustar00rootroot00000000000000merge-stream-1.0.1/.gitattributes000066400000000000000000000000141301574251200167670ustar00rootroot00000000000000* text=auto merge-stream-1.0.1/.gitignore000066400000000000000000000000261301574251200160670ustar00rootroot00000000000000coverage node_modules merge-stream-1.0.1/.jshintrc000066400000000000000000000002631301574251200157270ustar00rootroot00000000000000{ "globalstrict": true, "node": true, "proto": true, "quotmark": "single", "strict": true, "trailing": true, "unused": true, "latedef": "nofunc", "asi": true } merge-stream-1.0.1/.travis.yml000066400000000000000000000001461301574251200162130ustar00rootroot00000000000000sudo: false branches: except: /^v\d/ language: node_js node_js: - node - '6' - '4' - '0.10' merge-stream-1.0.1/LICENSE000066400000000000000000000021371301574251200151110ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) Stephen Sugden (stephensugden.com) 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. merge-stream-1.0.1/README.md000066400000000000000000000023231301574251200153600ustar00rootroot00000000000000# merge-stream Merge (interleave) a bunch of streams. [![build status](https://secure.travis-ci.org/grncdr/merge-stream.svg?branch=master)](http://travis-ci.org/grncdr/merge-stream) ## Synopsis ```javascript var stream1 = new Stream(); var stream2 = new Stream(); var merged = mergeStream(stream1, stream2); var stream3 = new Stream(); merged.add(stream3); merged.isEmpty(); //=> false ``` ## Description This is adapted from [event-stream](https://github.com/dominictarr/event-stream) separated into a new module, using Streams3. ## API ### `mergeStream` Type: `function` Merges an arbitrary number of streams. Returns a merged stream. #### `merged.add` A method to dynamically add more sources to the stream. The argument supplied to `add` can be either a source or an array of sources. #### `merged.isEmpty` A method that tells you if the merged stream is empty. When a stream is "empty" (aka. no sources were added), it could not be returned to a gulp task. So, we could do something like this: ```js stream = require('merge-stream')(); // Something like a loop to add some streams to the merge stream // stream.add(streamA); // stream.add(streamB); return stream.isEmpty() ? null : stream; ``` ## License MIT merge-stream-1.0.1/index.js000066400000000000000000000016031301574251200155460ustar00rootroot00000000000000'use strict'; var PassThrough = require('readable-stream/passthrough') module.exports = function (/*streams...*/) { var sources = [] var output = new PassThrough({objectMode: true}) output.setMaxListeners(0) output.add = add output.isEmpty = isEmpty output.on('unpipe', remove) Array.prototype.slice.call(arguments).forEach(add) return output function add (source) { if (Array.isArray(source)) { source.forEach(add) return this } sources.push(source); source.once('end', remove.bind(null, source)) source.once('error', output.emit.bind(output, 'error')) source.pipe(output, {end: false}) return this } function isEmpty () { return sources.length == 0; } function remove (source) { sources = sources.filter(function (it) { return it !== source }) if (!sources.length && output.readable) { output.end() } } } merge-stream-1.0.1/package.json000066400000000000000000000010141301574251200163630ustar00rootroot00000000000000{ "name": "merge-stream", "version": "1.0.1", "description": "Create a stream that emits events from multiple other streams", "files": [ "index.js" ], "scripts": { "test": "istanbul cover test.js && istanbul check-cover --statements 100 --branches 100" }, "repository": "grncdr/merge-stream", "author": "Stephen Sugden ", "license": "MIT", "dependencies": { "readable-stream": "^2.0.1" }, "devDependencies": { "from2": "^2.0.3", "istanbul": "^0.3.2" } } merge-stream-1.0.1/test.js000066400000000000000000000046051301574251200154230ustar00rootroot00000000000000'use strict'; var assert = require('assert') var from = require('from2') var merge = require('./') function test (name, fn, c) { var combined = c || merge(); var to = after(1000, process.emit.bind(process), 'error', new Error('Timed out: ' + name)) combined.on('end', function () { clearTimeout(to) }); fn(combined); } test('smoke', function (combined) { function addSource (i) { if (i === 38) return; combined.add(range(i)) after(6, addSource, i + 1) } var total = 0 combined.on('data', function (i) { total += i }) combined.on('end', function () { assert.equal(666, total) }) addSource(-36) }) test('pause/resume', function (combined) { combined.add(range(100)) combined.add(range(-100)) var counter = 0; combined.on('data', function () { counter++ }) after(20, function () { combined.pause() assert(counter < 200) var pauseCount = counter; after(50, function () { assert.equal(pauseCount, counter); combined.resume(); }); }); combined.on('end', function () { assert.equal(counter, 200) }) }) test('array', function (combined) { var counter = 0; combined.on('data', function () { counter++ }) combined.on('end', function () { assert.equal(counter, 200) }) }, merge([ range(100), range(-100) ])) test('isEmpty', function (combined) { assert(combined.isEmpty()); combined.on('data', function (n) { assert.equal(0, n) }); combined.add(range(1)); assert(!combined.isEmpty()); }) test('propagates errors', function (combined) { var ERROR_MESSAGE = 'TEST: INTERNAL STREAM ERROR'; var streamToError = range(100); var streamJustFine = range(-100); var errorCounter = 0; combined.add(streamToError); combined.add(streamJustFine); combined.on('error', function(err) { assert.equal(err.message, ERROR_MESSAGE); errorCounter++; }) after(50, function () { assert.equal(errorCounter, 0); streamToError.emit('error', new Error(ERROR_MESSAGE)); after(1, function () { assert.equal(errorCounter, 1); // End the stream manually to end the test combined.emit('end'); }); }); }) function range (n) { var k = n > 0 ? -1 : 1 return from.obj(function (_, next) { setTimeout(function () { next(null, n === 0 ? null : n += k) }, Math.round(6 + Math.round(Math.random() * 6))); }) } function after (ms, fn, a, b, c) { return setTimeout(fn, ms, a, b, c) }