@raini/pipes
@raini/pipes
is a set of composable blocks called Pipelines. Pipelines are lazy and do not get invoked until they are forked with process
method.
Pipelines are Monoids and can be concatenated with other Pipelines using p.concat
which allows joining separate sets 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
and P.empty
- 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 (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)