UNPKG

stream-flow-control

Version:
114 lines (99 loc) 3.37 kB
const {Readable} = require('stream'); const {Manager} = require('../manager/manager.js'); const uuid = require('uuid'); const {DataWrapper} = require('../wrapper/data_wrapper.js') /** * Join messages from multiple sources into a single messages. If no method is overwitten, then releases a message when there is exactly one message from each source. * * @extends Readable */ class FlowJoin extends Readable { /** * Create a FlowJoin stream * @param {object} options Global options. * @param {string} [options.name] Name for this stream. * @param {Process} [options.join] How messages are joined. */ constructor(options) { options = {...options, objectMode: true}; super(options); this.options = options; this._sources = {}; this._payloads = []; this._readableState.sync = false; this.type = 'FlowJoin'; if(this.options.name) Manager.set(this.type, this); if(this.options.join && typeof this.options.join == 'function') this._join = this.options.join; this.on('pipe', (src)=>{ const id = this.goal || (src.options && src.options.name)?src.options.name:uuid.v4(); if(src.options && src.options.port) { id += '/'+src.options.port; } this._sources[id] = src; src.on('data', (data)=>{ //console.log('hay data'); this._join({ id, data }); }); //src.on('end', () => this.end(src)); this.on('pause', ()=>{ src.pause(); }); this.on('resume', ()=>{ src.resume(); }); }); } // none(dst) { // if(!this._none_reader) { // this._none_reader = new Readable({ // objectMode: true, // read() {} // }); // this._none_reader._readableState.sync = false; // } // const pipes = Array.isArray(dst)?dst:[dst]; // pipes.forEach(dst=>this._none_reader.pipe(dst)); // return Array.isArray(dst)?this:dst; // } _join(data) { var found = false; var doSend = false; for(let i = 0; i < this._payloads.length; i++) { let payload = this._payloads[i]; if(payload.hasOwnProperty(data.id)) continue; found=true; payload[data.id] = data.data; doSend = Object.keys(payload).length == Object.keys(this._sources).length; break; } if(doSend) { let payload = this._payloads.shift(); if(this.goal) { // Is goal player payload = new DataWrapper(null, this).setParents(payload); } if(!this.push(payload)) this.pause(); return; } if(!found) { let payload = {}; payload[data.id] = data.data; this._payloads.push(payload); } } _read() { this.resume(); } write(payload) { } end(src) { for(let i in this._sources) { if(!this._sources[i]._readableState.ended) return; } this.push(null); } } module.exports.FlowJoin = FlowJoin;