{"id":13415187,"url":"https://github.com/sartaj/pipe-me","last_synced_at":"2025-04-22T12:35:36.812Z","repository":{"id":57324749,"uuid":"120734556","full_name":"sartaj/pipe-me","owner":"sartaj","description":"👜Pipeable programming for humans.","archived":false,"fork":false,"pushed_at":"2022-12-06T21:53:58.000Z","size":2538,"stargazers_count":98,"open_issues_count":1,"forks_count":2,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-10-14T15:09:40.654Z","etag":null,"topics":["callbag","functional-programming","iterables","pipeline-operator","reactive-programming"],"latest_commit_sha":null,"homepage":"http://sartaj.me/pipe-me","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sartaj.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-02-08T08:42:44.000Z","updated_at":"2023-12-06T21:28:07.000Z","dependencies_parsed_at":"2023-01-24T11:31:02.436Z","dependency_job_id":null,"html_url":"https://github.com/sartaj/pipe-me","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sartaj%2Fpipe-me","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sartaj%2Fpipe-me/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sartaj%2Fpipe-me/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sartaj%2Fpipe-me/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sartaj","download_url":"https://codeload.github.com/sartaj/pipe-me/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223897024,"owners_count":17221475,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["callbag","functional-programming","iterables","pipeline-operator","reactive-programming"],"created_at":"2024-07-30T21:00:44.766Z","updated_at":"2024-11-10T00:04:21.308Z","avatar_url":"https://github.com/sartaj.png","language":"JavaScript","funding_links":[],"categories":["Table Contents"],"sub_categories":["Misc"],"readme":"_\"Check this library! Convert anything to callbags, then use pipeline operator (ES proposal), and experience an entirely new flavor of JS\" - [André Staltz](https://twitter.com/andrestaltz/status/962301798244548609)_\n\n# pipe-me\n\n[![npm](https://img.shields.io/npm/v/pipe-me.svg)](https://npmjs.org/pipe-me)\n[![Build Status](https://travis-ci.org/sartaj/pipe-me.svg?branch=master)](https://travis-ci.org/sartaj/pipe-me)\n[![GitHub issues](https://img.shields.io/github/issues/sartaj/pipe-me.svg)](https://github.com/sartaj/pipe-me/issues)\n[![codecov](https://codecov.io/gh/sartaj/pipe-me/branch/master/graph/badge.svg)](https://codecov.io/gh/sartaj/pipe-me)\n[![Dependencies](https://img.shields.io/david/sartaj/pipe-me.svg)](https://david-dm.org/sartaj/pipe-me)\n[![Known Vulnerabilities](https://snyk.io/test/github/sartaj/pipe-me/badge.svg)](https://snyk.io/test/github/sartaj/pipe-me)\n\n`pipe-me` is a clean \u0026 functional way to describe interactions in JavaScript.\n\n```javascript\nimport { fromEvent, filter, map, merge, sideEffect } from 'pipe-me'\n\nimport { getRandomFruit, getCurrentDateTime } from './utils'\nimport { renderDOM } from './dom'\n\nconst buttonClicked = fromEvent(document, 'click')\n  |\u003e filter(event =\u003e event.target.tagName === 'BUTTON')\n  |\u003e map(() =\u003e ({ date: getCurrentDateTime(), fruit: getRandomFruit() }))\n\nbuttonClicked\n  |\u003e sideEffect(renderDOM)\n\nbuttonClicked\n  |\u003e sideEffect(state =\u003e console.log(state))\n```\n\n[See Live Demo](http://sartaj.me/pipe-me/examples/convert-fruit/)\n\n## Features\n\n* **UNIX(ish) FTW**: Describe your entire app as functions over time with streams and pipes.\n* **More Design Pattern than Framework** — Under the hood, `pipe-me` merely uses the [pipeline operator](https://github.com/tc39/proposal-pipeline-operator) and [callbags](https://github.com/callbag/callbag). To move off of `pipe-me`, or to extend it, you can use anything in the [callbag universe](https://github.com/callbag/callbag/wiki).\n* **Simplified Language Design**: This is designed to be a starter kit for callbags, with a focus on naming functions in a way that tries to keep analogies and concepts unified and designed for modeling complex interactions in apps.\n* **Elm in JS**: By mixing with [flow](https://flow.org/) for type annotations, JavaScript is given all the major syntax features [elm](https://elm-lang.org), allowing you to create beautiful streams of functions based on beautiful data structures.\n* **Streams For Interactive Apps**: All of `pipe-me` creators [multicast](https://blog.angularindepth.com/rxjs-understanding-the-publish-and-share-operators-16ea2f446635), aka [share](https://github.com/staltz/callbag-share), by default. This works well for modeling [dataflow](https://staltz.com/why-we-need-callbags.html#interoperability) between interactions.\n* **Graphical Code Annotations**: Graphic code annotations make understanding different functions a lot easier.  \u003cbr\u003e \u003cimg src=\"http://sartaj.me/pipe-me/assets/readme/flatten.gif\" /\u003e \u003cbr\u003e \u003cimg src=\"http://sartaj.me/pipe-me/assets/readme/concat.png\" /\u003e\n\n### Callbag Features\n\nBy using [callbags](https://github.com/callbag/callbag) under the hood, we get all the benefits of callbags.\n\n* **Support Reactive \u0026 Interactive Programming:** Callbags as a spec supports promises/async, iterators/generators, events, \u0026 observables to provide a hybrid of reactive and interactive programming.\n* **Chain Everything**: Working just like Rx.js, `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.\n* **Fast:** Approximately [as fast as](https://github.com/staltz/callbag-basics/tree/master/perf) xstream and RxJS.\n* **Modular**: Everything is a utility function based on the callbag spec, so no core library is needed.\n\n## Installation\n\n### Try Out\n\nClone 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.\n\n### Install\n\n#### Yarn/npm\n\n```bash\nyarn add pipe-me\n```\n\n```bash\nnpm install pipe-me --save\n```\n\n#### Babel\n\nTo use the [pipeline operator](https://github.com/tc39/proposal-pipeline-operator), you'll need to add the [pipeline-operator plugin](https://github.com/babel/babel/tree/master/packages/babel-plugin-proposal-pipeline-operator) to your babel config. We would also recommend installing [babel-flow](http://flow.org) for clean data structures.\n\n##### Fresh Install\n\nFor setting up from scratch, the following should be adequate.\n\n```json\nyarn add @babel/cli @babel/preset-env @babel/preset-plugin-proposal-pipeline babel-preset-flow  --dev\n```\n\n```json\n{\n    \"presets\": [\"@babel/preset-env\", \"flow\"],\n    \"plugins\": [\"@babel/plugin-proposal-pipeline-operator\"]\n}\n```\n\n###### CLI\n\n```bash\nyarn run babel src/ -- -d lib/\n```\n\n## Main Concepts\n\nIf 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.\n\n* **Create**: Create callbags from a number of sources, including Promises, Generators, etc.\n* **Side Effects**: Only way to have data affect external world, including UI. Only two methods are `sideEffect`, and `log`.\n* **Transforms**: Change the content of your data.\n* **Filters**: Filter out data based on different criteria. Includes different timer operators, like time based ones like `throttle`.\n* **Combiners**: Combine 2 or more callbags into with different techniques.\n\n## Language Design\n\n`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](https://github.com/callbags/callbags) and [UNIX-like Principles](http://www.faqs.org/docs/artu/ch01s06.html) for professional app development.\n\n### Current Problem\n\nThe world of Observables, FRP, and related systems have a huge learning curve for many beginner coders.\n\nPart of this may be due to the size of operations and complex amount of analogies used within the world.\n\n* Water utilities (streams, pipes, backpressure, pool, sources, sinks)\n* Radio systems (subscribe, publish, observable, signals)\n* Grammar (subject, predicate)\n* Paper (foldp, fold)\n* Sensory (observable, observe)\n* Computer hardware related (drivers, ports)\n* Math + Lambda Calculus (map, flatten)\n* And sheer mind games (wtf is a flatmap)\n\n### `pipe-me` API Goals\n\n* Simple language for basic English speakers and bare bones computer science / js knowledge, focusing on stream and first class event variables.\n* Commit to internally consistent analogy.\n* Maximize pipe syntax to mimic UNIX pipes.\n* Allow for gradual learning of inner workings of callbag spec.\n\n### Is This Standard JavaScript?\n\nWhile `pipe-me` makes opinions on naming conventions of operators, under the hood is just a mash of two proposal specs, the [pipeline operator](https://github.com/tc39/proposal-pipeline-operator), and [callbags](https://github.com/callbag/callbag). \n\nIn terms of the the [pipeline operator](https://github.com/tc39/proposal-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](https://github.com/tc39/proposal-pipeline-operator/issues), 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.\n\nIn terms of the actual operators themselves, the far majority of the magic here is possible because of André Staltz's brilliant [callbag](https://github.com/callbag/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.\n\nThis actually means you can use this library with any other callbag library to unleash this awesome writing style in JS.\n\n### Inspirations\n\n* rxjs\n* cycle.js\n* kefir.js\n* xstream\n* elm\n* cycle-react\n* react.js\n\n## [API Docs](http://sartaj.me/pipe-me)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsartaj%2Fpipe-me","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsartaj%2Fpipe-me","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsartaj%2Fpipe-me/lists"}