I'm trying to understand how best to conditionally pipe a stream to a Transform
or similar without the use of a 3rd party lib.
Ideally I'd like to do something like this
const transformA, transformB = // my transforms
const booleanA, booleanB = // my various conditions
const stream = new Readable()
stream.push('...') // my content
return stream
.pipe(booleanA && transformA)
.pipe(booleanB && transformB)
I've attempted this using libs like detour-stream
, ternary-stream
and others but I've encountered various strange side effects where transforms are being invoked when they shouldn't, throwing errors etc, and its left me wondering about how people accomplish this type of thing without the added complexity of those libs.
In the interim I've solved this by just taking an imperative approach, reassigning the stream on each condition.
let stream = // get my stream
if (condition) stream = stream.pipe(someTransform)
if (otherCondition) stream = stream.pipe(otherTransform)
return stream
This is fine, but I'm still curious if the immutable and functional approach can be done
Thanks for looking & reading
Unfortunately, there's no built-in support for conditional pipes, an alternative to your approach without any third-party modules is using .pipeline
const stream = require('stream');
const pipeline = util.promisify(stream.pipeline);
const read = new stream.Readable()
const pipes = [
booleanA && transformA,
booleanB && transformB
].filter(Boolean); // remove empty pipes
await pipeline(
read,
...pipes
);
Since .pipeline
takes N transform streams, you can make use of spread operator from an already filtered array of pipes.
In case you want to return the last piped stream, you can drop the promisify version of pipeline
.
return pipeline(
read,
...pipes,
() => {}
)