👜Pipeable programming for humans.
"Check this library! Convert anything to callbags, then use pipeline operator (ES proposal), and experience an entirely new flavor of JS" - André Staltz
pipe-me
is a clean & functional way to describe interactions in JavaScript.
import { fromEvent, filter, map, merge, sideEffect } from 'pipe-me'
import { getRandomFruit, getCurrentDateTime } from './utils'
import { renderDOM } from './dom'
const buttonClicked = fromEvent(document, 'click')
|> filter(event => event.target.tagName === 'BUTTON')
|> map(() => ({ date: getCurrentDateTime(), fruit: getRandomFruit() }))
buttonClicked
|> sideEffect(renderDOM)
buttonClicked
|> sideEffect(state => console.log(state))
pipe-me
merely uses the pipeline operator and callbags. To move off of pipe-me
, or to extend it, you can use anything in the callbag universe.pipe-me
creators multicast, aka share, by default. This works well for modeling dataflow between interactions.By using callbags under the hood, we get all the benefits of callbags.
var
/let
/const
can be used to create chains of callbags that describe your app clearly. If you are new to JavaScript, this library may sound complicated, but bear with it. Do you know how to use spreadsheets? Well then, you already understand the basics concepts behind this library.Clone this repo. Run yarn
or npm install
. Then yarn example
. Then click the button in the example and watch the DOM and console both print at the same time with such little effort.
yarn add pipe-me
npm install pipe-me --save
To use the pipeline operator, you'll need to add the pipeline-operator plugin to your babel config. We would also recommend installing babel-flow for clean data structures.
For setting up from scratch, the following should be adequate.
yarn add @babel/cli @babel/preset-env @babel/preset-plugin-proposal-pipeline babel-preset-flow --dev
{
"presets": ["@babel/preset-env", "flow"],
"plugins": ["@babel/plugin-proposal-pipeline-operator"]
}
yarn run babel src/ -- -d lib/
If you are new to paradigms like this (found in systems like RxJS and IxJS), sometimes it can be hard to remember the purpose of different operators. To simplify this, you can import from 5 different categories.
sideEffect
, and log
.throttle
.pipe-me
is designed with the hope of having a gradual learning curve for beginner js developers with little background in computer science or functional programming, while maximizing use of proper callbags and UNIX-like Principles for professional app development.
The world of Observables, FRP, and related systems have a huge learning curve for many beginner coders.
Part of this may be due to the size of operations and complex amount of analogies used within the world.
pipe-me
API GoalsWhile pipe-me
makes opinions on naming conventions of operators, under the hood is just a mash of two proposal specs, the pipeline operator, and callbags.
In terms of the the pipeline operator, it is currently a TC39 proposal, similar to object spread. So technically it is subject to change. However, based on the issues in the proposal, most concerns are around how to handle the await
syntax and multiple parameters. These issues are a mute point in pipe-me
, because by using the callbag
spec, all of our non combining operators are single parameter, and async/await
is handled by the fromIterable
and fromAsync
operator.
In terms of the actual operators themselves, the far majority of the magic here is possible because of André Staltz's brilliant callbag spec. Because callbags are functional compositions, and because pipeline operators are just function compositions under the hood, any callbag can be used with pipeline operators.
This actually means you can use this library with any other callbag library to unleash this awesome writing style in JS.