UNPKG

s-pipe

Version:

Functional streams, with a lisp-inspired chaining syntax

73 lines (54 loc) 1.82 kB
var classic = require('classic'); var is = require('istype'); var PullStream = require('./pull'); var slice = Array.prototype.slice; var Pipeline = PullStream.extend({ constructor: function Pipeline(start, end) { PullStream.call(this, end); this._start = start; }, _process: function(chunk) { this.push(chunk); }, _write: function(chunk, encoding, callback) { return this._start._write(chunk, encoding, callback); } }); module.exports = function spipe(stream) { var start = stream; // The 'pipeline' function returns itself until called with no // arguments or a false value. return function pipeline(fn) { if (arguments.length && typeof fn === 'function') { var args = slice.call(arguments, 1); stream = fn.apply(stream, args); return pipeline; } var eagerEvaluation = fn; // If 'eagerEvaluation' is true(default), we will try to eagerly evaluate // the entire stream by hooking into its 'data' event and buffering // the results into an array. if (is.nil(eagerEvaluation)) eagerEvaluation = true; if (eagerEvaluation) { var buffer, tmpHandler, ended = false; stream.on('data', function(data) { buffer = buffer || []; buffer.push(data); }); // If the stream is done emitting data, return the buffer if (stream._done && stream._done()) return buffer || []; // Remove all listeners stream.removeAllListeners('data'); // If we consumed anything synchronously but the stream didnt complete, // send it back so the caller can consume it if (buffer) { while (buffer.length) stream.unshift(buffer.shift()); } stream._readableState.flowing = false; } return new Pipeline(start, stream); }; };