const through = require('through2'); const {Writable} = require('stream'); const {StringDecoder} = require('string_decoder'); const Vinyl = require('vinyl'); const {Tail} = require('tail'); const {Transform} = require('stream'); class TailVinyl extends Vinyl { constructor(params) { params.contents = new Transform(); super(params); this.tail = new Tail(params.path); this.tail.on('line', data => this.contents.write(data + '\n')); this.tail.on('error', error => this.contents.write('error: ' + error)); } dispose() { this.tail.unwatch(); } } class StringWritable extends Writable { constructor(handler, options) { super(options); this.handler = handler; const state = this._writableState; this._decoder = new StringDecoder(state.defaultEncoding); this.data = ''; } _write(chunk, encoding, callback) { if (encoding === 'buffer') { chunk = this._decoder.write(chunk); for (const line of chunk.split('\n')) if (line.length) { this.handler(line); } } this.data += chunk; callback(); } _final(callback) { this.data += this._decoder.end(); callback(); } } module.exports = (handler) => { return through.obj(function (file, enc, callback) { if (file.contents && file.contents.pipe) { file.contents.pipe(new StringWritable(handler)); } this.push(file); callback(); }); }; module.exports.TailVinyl = TailVinyl;