You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
87 lines
2.2 KiB
JavaScript
87 lines
2.2 KiB
JavaScript
var Stream = require('stream');
|
|
|
|
function createStreamAPI () {
|
|
var stream
|
|
, processEntry
|
|
, done
|
|
, handleError
|
|
, handleFatalError
|
|
, paused = true
|
|
, controlled = false
|
|
, buffer = []
|
|
, closed = false
|
|
;
|
|
|
|
stream = new Stream();
|
|
stream.writable = false;
|
|
stream.readable = true;
|
|
|
|
stream.pause = function () {
|
|
controlled = true;
|
|
paused = true;
|
|
};
|
|
|
|
stream.resume = function () {
|
|
controlled = true;
|
|
paused = false;
|
|
|
|
// emit all buffered entries, errors and ends
|
|
while (!paused && buffer.length) {
|
|
var msg = buffer.shift();
|
|
this.emit(msg.type, msg.data);
|
|
}
|
|
};
|
|
|
|
stream.destroy = function () {
|
|
closed = true;
|
|
stream.readable = false;
|
|
stream.emit('close');
|
|
};
|
|
|
|
// called for each entry
|
|
processEntry = function (entry) {
|
|
if (closed) return;
|
|
return paused ? buffer.push({ type: 'data', data: entry }) : stream.emit('data', entry);
|
|
};
|
|
|
|
// called with all found entries when directory walk finished
|
|
done = function (err, entries) {
|
|
if (closed) return;
|
|
|
|
// since we already emitted each entry and all non fatal errors
|
|
// all we need to do here is to signal that we are done
|
|
stream.emit('end');
|
|
};
|
|
|
|
handleError = function (err) {
|
|
if (closed) return;
|
|
return paused ? buffer.push({ type: 'warn', data: err }) : stream.emit('warn', err);
|
|
};
|
|
|
|
handleFatalError = function (err) {
|
|
if (closed) return;
|
|
return paused ? buffer.push({ type: 'error', data: err }) : stream.emit('error', err);
|
|
};
|
|
|
|
// Allow stream to be returned and handlers to be attached and/or stream to be piped before emitting messages
|
|
// Otherwise we may loose data/errors that are emitted immediately
|
|
process.nextTick(function () {
|
|
if (closed) return;
|
|
|
|
// In case was controlled (paused/resumed) manually, we don't interfer
|
|
// see https://github.com/thlorenz/readdirp/commit/ab7ff8561d73fca82c2ce7eb4ce9f7f5caf48b55#commitcomment-1964530
|
|
if (controlled) return;
|
|
stream.resume();
|
|
});
|
|
|
|
return {
|
|
stream : stream
|
|
, processEntry : processEntry
|
|
, done : done
|
|
, handleError : handleError
|
|
, handleFatalError : handleFatalError
|
|
};
|
|
}
|
|
|
|
module.exports = createStreamAPI;
|