aboutsummaryrefslogtreecommitdiff
path: root/node_modules/readdirp/stream-api.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/readdirp/stream-api.js')
-rw-r--r--node_modules/readdirp/stream-api.js98
1 files changed, 98 insertions, 0 deletions
diff --git a/node_modules/readdirp/stream-api.js b/node_modules/readdirp/stream-api.js
new file mode 100644
index 0000000..bffd1a9
--- /dev/null
+++ b/node_modules/readdirp/stream-api.js
@@ -0,0 +1,98 @@
+'use strict';
+
+var stream = require('readable-stream');
+var util = require('util');
+
+var Readable = stream.Readable;
+
+module.exports = ReaddirpReadable;
+
+util.inherits(ReaddirpReadable, Readable);
+
+function ReaddirpReadable (opts) {
+ if (!(this instanceof ReaddirpReadable)) return new ReaddirpReadable(opts);
+
+ opts = opts || {};
+
+ opts.objectMode = true;
+ Readable.call(this, opts);
+
+ // backpressure not implemented at this point
+ this.highWaterMark = Infinity;
+
+ this._destroyed = false;
+ this._paused = false;
+ this._warnings = [];
+ this._errors = [];
+
+ this._pauseResumeErrors();
+}
+
+var proto = ReaddirpReadable.prototype;
+
+proto._pauseResumeErrors = function () {
+ var self = this;
+ self.on('pause', function () { self._paused = true });
+ self.on('resume', function () {
+ if (self._destroyed) return;
+ self._paused = false;
+
+ self._warnings.forEach(function (err) { self.emit('warn', err) });
+ self._warnings.length = 0;
+
+ self._errors.forEach(function (err) { self.emit('error', err) });
+ self._errors.length = 0;
+ })
+}
+
+// called for each entry
+proto._processEntry = function (entry) {
+ if (this._destroyed) return;
+ this.push(entry);
+}
+
+proto._read = function () { }
+
+proto.destroy = function () {
+ // when stream is destroyed it will emit nothing further, not even errors or warnings
+ this.push(null);
+ this.readable = false;
+ this._destroyed = true;
+ this.emit('close');
+}
+
+proto._done = function () {
+ this.push(null);
+}
+
+// we emit errors and warnings async since we may handle errors like invalid args
+// within the initial event loop before any event listeners subscribed
+proto._handleError = function (err) {
+ var self = this;
+ setImmediate(function () {
+ if (self._paused) return self._warnings.push(err);
+ if (!self._destroyed) self.emit('warn', err);
+ });
+}
+
+proto._handleFatalError = function (err) {
+ var self = this;
+ setImmediate(function () {
+ if (self._paused) return self._errors.push(err);
+ if (!self._destroyed) self.emit('error', err);
+ });
+}
+
+function createStreamAPI () {
+ var stream = new ReaddirpReadable();
+
+ return {
+ stream : stream
+ , processEntry : stream._processEntry.bind(stream)
+ , done : stream._done.bind(stream)
+ , handleError : stream._handleError.bind(stream)
+ , handleFatalError : stream._handleFatalError.bind(stream)
+ };
+}
+
+module.exports = createStreamAPI;