hole
Version:
Async friendly, stream-based task consuming utility in Node.js
135 lines (134 loc) • 4.38 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const pump_1 = __importDefault(require("pump"));
const stream_array_1 = __importDefault(require("stream-array"));
const is_stream_1 = __importDefault(require("is-stream"));
const stream_1 = require("stream");
const lazy_promise_1 = __importDefault(require("lazy-promise"));
const transform_1 = require("./transform");
function fromStream(readable) {
return new Hole(readable);
}
exports.fromStream = fromStream;
function fromArray(array) {
return fromStream(stream_array_1.default(array));
}
exports.fromArray = fromArray;
function hole(obj) {
return fromArray([obj]);
}
exports.default = hole;
class Hole extends lazy_promise_1.default {
constructor(readable) {
super(start);
this.readable = readable;
this.procInfoArray = [];
}
pipe(p, opts) {
const options = typeof opts === 'number' ? { maxParallel: opts } : opts || {};
this.procInfoArray = [...this.procInfoArray, [p, options]];
return this;
}
split() {
const p = new stream_1.Transform({
objectMode: true,
transform: function (chunks, enc, callback) {
if (!Array.isArray(chunks)) {
throw new Error('.split() must receive an array from a previous function.');
}
push.call(this, callback, chunks, 0);
function push(callback, chunks, curr) {
if (chunks[curr] === undefined) {
callback();
return;
}
// @ts-ignore
const bufferAvailable = this.push(chunks[curr]);
if (bufferAvailable) {
// @ts-ignore
push.call(this, callback, chunks, curr + 1);
return;
}
// Avoid synchronous pushing over capacity of readable buffer
setImmediate(() => {
// @ts-ignore
push.call(this, callback, chunks, curr + 1);
});
}
},
});
this.procInfoArray = [...this.procInfoArray, [p, {}]];
return this;
}
concat(size) {
let buffered = [];
const p = new stream_1.Transform({
transform(chunk, enc, callback) {
buffered = [...buffered, chunk];
if (buffered.length >= size) {
this.push(buffered);
buffered = [];
}
callback();
},
flush(callback) {
if (buffered.length > 0) {
this.push(buffered);
}
callback();
},
objectMode: true,
});
this.procInfoArray = [...this.procInfoArray, [p, {}]];
return this;
}
collect() {
// noinspection JSMismatchedCollectionQueryUpdate
const results = [];
return this.pipe((data) => {
results.push(data);
}).then(() => results);
}
collectSet() {
const results = new Set();
return this.pipe((data) => {
results.add(data);
}).then(() => results);
}
}
exports.Hole = Hole;
function start(resolve, reject) {
// @ts-ignore
if (this.procInfoArray.length <= 0) {
throw new Error('Hole requires at least one ".pipe(fn)" call.');
}
// @ts-ignore
const transforms = this.procInfoArray.map(toStream);
const voidWriter = new stream_1.Writable({
objectMode: true,
write(data, enc, callback) {
callback();
},
});
// @ts-ignore
const streams = [this.readable, ...transforms, voidWriter];
pump_1.default.apply(null, [
...streams,
(error) => {
if (error) {
reject(error);
}
else {
resolve();
}
},
]);
function toStream([fn, opts]) {
if (is_stream_1.default(fn))
return fn;
return new transform_1.HoleTransform(fn, opts);
}
}