Transforming streams

On occasion, stream data needs to be processed, often in cases where one is writing some sort of binary protocol or other on the fly data transformation. A Transform stream is designed for this purpose, functioning as a Duplex stream that sits between a Readable stream and a Writable stream.

A Transform stream is initialized using the same options used to initialize a typical Duplex stream, where Transform differs from a normal Duplex stream is in its requirement that the custom implementation merely provides a _transform method, excluding the _write and _read method requirement.

The _transform method will receive three arguments, first the sent buffer, an optional encoding argument, and finally a callback which _transform is expected to call when the transformation is complete:

_transform = function(buffer, encoding, cb) {
let transformation = "...";
this.push(transformation);
cb();
};

Let's imagine a program that helps to convert ASCII (American Standard Code for Information Interchange) codes into ASCII characters, receiving input from stdin. You type in an ASCII code, and the program responds with the alphanumeric character corresponding to that code. Here we can simply pipe our input to a Transform stream, then pipe its output back to stdout:

const stream = require('stream');
let converter = new stream.Transform();

converter._transform = function(num, encoding, cb) {
this.push(String.fromCharCode(new Number(num)) + "\n");
cb();
};

process.stdin.pipe(converter).pipe(process.stdout);

Interacting with this program might produce an output resembling the following:

65 A
66 B
256 Ā
257 ā

A more involved example of a transform stream will be demonstrated in the example that ends this chapter.