index.js 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. var PassThrough = require('readable-stream').PassThrough
  2. var Readable = require('readable-stream').Readable
  3. var duplexer = require('duplexer2')
  4. module.exports = function () {
  5. var streams
  6. if(arguments.length == 1 && Array.isArray(arguments[0])) {
  7. streams = arguments[0]
  8. } else {
  9. streams = [].slice.call(arguments)
  10. }
  11. return combine(streams)
  12. }
  13. module.exports.obj = function () {
  14. var streams
  15. if(arguments.length == 1 && Array.isArray(arguments[0])) {
  16. streams = arguments[0]
  17. } else {
  18. streams = [].slice.call(arguments)
  19. }
  20. return combine(streams, { objectMode: true })
  21. }
  22. function combine (streams, opts) {
  23. for (var i = 0; i < streams.length; i++)
  24. streams[i] = wrap(streams[i], opts)
  25. if(streams.length == 0)
  26. return new PassThrough(opts)
  27. else if(streams.length == 1)
  28. return streams[0]
  29. var first = streams[0]
  30. , last = streams[streams.length - 1]
  31. , thepipe = duplexer(opts, first, last)
  32. //pipe all the streams together
  33. function recurse (streams) {
  34. if(streams.length < 2)
  35. return
  36. streams[0].pipe(streams[1])
  37. recurse(streams.slice(1))
  38. }
  39. recurse(streams)
  40. function onerror () {
  41. var args = [].slice.call(arguments)
  42. args.unshift('error')
  43. thepipe.emit.apply(thepipe, args)
  44. }
  45. //es.duplex already reemits the error from the first and last stream.
  46. //add a listener for the inner streams in the pipeline.
  47. for(var i = 1; i < streams.length - 1; i ++)
  48. streams[i].on('error', onerror)
  49. return thepipe
  50. }
  51. function wrap (tr, opts) {
  52. if (typeof tr.read === 'function') return tr
  53. return new Readable(opts).wrap(tr)
  54. }