@raini/pipes
@raini/pipes
is a set of monoids called Pipelines. Pipelines are lazy and do not get invoked until they are forked with process
method.
A Pipeline is a Monoid and can be concatenated with other Pipelines with concat
which allows joining separate pieces of composed functions.
Features
- Composition of functions via
pipe
- Helper pipe methods, e.g.
pipeTap
or extendPipe
- Implements Semigroup (holds associativity) with
p.concat
- Implements Monoid (holds right identity and left identity) with
P.concat
- PromisePipeline allows abstracting from using Promises in composed functions -
promisePipeline.process
returns the only Promise to work with - Can be used both in Node and in browsers (JS transpiled to ES5)
Installation
npm i -S @raini/pipes
Usage
PromisePipeline
import { PromisePipeline } from "@raini/pipes";
import * as rl from "readline";
const addSpaceIfMissing = (q: string): string => (q.endsWith(" ") ? q : q.concat(" "));
const toObject = (q: string) => ({ q });
const createReadLine = () => ({ rl: rl.createInterface(process.stdin, process.stdout) });
const askQuestionAsync = ({ rl, q }) => new Promise((res) => rl.question(q, (a: string) => res(a)));
const applyGreenColor = (x: string) => `\x1b[32m${x}\x1b[0m`;
const log = console.log;
const exit = () => process.exit(0);
PromisePipeline.of(addSpaceIfMissing)
.pipe(toObject)
.pipeExtend(createReadLine)
.pipe(askQuestionAsync)
.pipe(applyGreenColor)
.pipeTap(log)
.process(() => "What is the answer to life, the universe and everything?")
.then(exit);
SyncPipeline
import { SyncPipeline } from "@raini/pipes";
const isOdd = (num: number) => num % 2 == 0;
const negate = <T>(f: (x: T) => any) => (x: T) => !f(x);
const filterOutOddNumbers = (nums: number[]) => nums.filter(negate(isOdd));
const multiplyBy2 = (num: number) => num * 2;
const multiplyItemsBy2 = (nums: number[]) => nums.map(multiplyBy2);
const log = console.log;
const result = SyncPipeline.of(filterOutOddNumbers)
.pipeTap(log)
.pipe(multiplyItemsBy2)
.process(() => [1, 2, 3, 4, 5]);
log(result);
const result2 = SyncPipeline.of(filterOutOddNumbers)
.pipeTap(log)
.pipeExtend(multiplyItemsBy2)
.process(() => [1, 2, 3, 4, 5]);
log(result2);