Skip to content

Instantly share code, notes, and snippets.

@cowboy
Last active October 27, 2022 09:39
Show Gist options
  • Save cowboy/6342610 to your computer and use it in GitHub Desktop.
Save cowboy/6342610 to your computer and use it in GitHub Desktop.
Node.js Transform stream piping, order, asynchronous, wtf
var stream = require('readable-stream');
var Transform = stream.Transform;
var util = require('util');
var _ = require('lodash');
var $ = require('chalk')
// Just serialize a object stream into lines of JSON
function Serializer() {
Transform.call(this, {objectMode: true});
}
Serializer.prototype = Object.create(Transform.prototype, {constructor: {value: Serializer}});
Serializer.prototype._transform = function(chunk, encoding, done) {
done(null, $.green(JSON.stringify(chunk)) + '\n');
};
// For each "log" method call, output an object. Allow indentation to be
// increased and decreased. For any logger piped into this logger, increment
// indentation cumulatively.
var counter = 0;
function Log(name, options) {
Transform.call(this, {objectMode: true});
this.name = name;
this.indent = 0;
}
Log.prototype = Object.create(Transform.prototype, {constructor: {value: Log}});
Log.prototype._transform = function(chunk, encoding, done) {
console.log('[%s] %s', this.name, '_transform');
var obj = _.extend({}, chunk);
obj.indent += this.indent;
done(null, obj);
};
Log.prototype.group = function() {
console.log('[%s] %s', this.name, 'group');
this.indent++;
};
Log.prototype.groupEnd = function() {
console.log('[%s] %s', this.name, 'groupEnd');
this.indent--;
};
Log.prototype.log = function(message) {
console.log('[%s] %s "%s"', this.name, 'log', message);
this.push({
counter: ++counter,
logger: this.name,
message: message,
indent: this.indent,
});
};
// Create parent logger that will be serialized and output to stdout.
var parent = new Log('parent');
parent.pipe(new Serializer).pipe(process.stdout);
// Create child logger that will be passed through the parent logger,
// so that indentation can (theoretically) be accumulated, then serialized
// and output to stdout.
var child = new Log('child');
child.pipe(parent);
parent.log('indent should be 0');
child.log('indent should stay at 0');
parent.group();
parent.log('indent should be 1');
child.log('indent should go from 0→1');
child.group();
parent.log('indent should be 1');
child.log('indent should go from 1→2');
child.groupEnd();
parent.log('indent should be 1');
child.log('indent should go from 0→1');
parent.groupEnd();
child.group();
parent.log('indent should be 0');
child.log('indent should stay at 1');
child.groupEnd();
[parent] log "indent should be 0"
[child] log "indent should stay at 0"
[parent] group
[parent] log "indent should be 1"
[child] log "indent should go from 0→1"
[child] group
[parent] log "indent should be 1"
[child] log "indent should go from 1→2"
[child] groupEnd
[parent] log "indent should be 1"
[child] log "indent should go from 0→1"
[parent] groupEnd
[child] group
[parent] log "indent should be 0"
[child] log "indent should stay at 1"
[child] groupEnd
{"counter":1,"logger":"parent","message":"indent should be 0","indent":0}
{"counter":3,"logger":"parent","message":"indent should be 1","indent":1}
{"counter":5,"logger":"parent","message":"indent should be 1","indent":1}
{"counter":7,"logger":"parent","message":"indent should be 1","indent":1}
{"counter":9,"logger":"parent","message":"indent should be 0","indent":0}
[parent] _transform
{"counter":2,"logger":"child","message":"indent should stay at 0","indent":0}
[parent] _transform
{"counter":4,"logger":"child","message":"indent should go from 0→1","indent":0}
[parent] _transform
{"counter":6,"logger":"child","message":"indent should go from 1→2","indent":1}
[parent] _transform
{"counter":8,"logger":"child","message":"indent should go from 0→1","indent":0}
[parent] _transform
{"counter":10,"logger":"child","message":"indent should stay at 1","indent":1}
{
"name": "dunno",
"version": "0.0.0",
"dependencies": {
"lodash": "~1.3.1",
"chalk": "~0.2.0",
"readable-stream": "~1.0.15"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment