{"id":13431317,"url":"https://github.com/functional-promises/functional-promises","last_synced_at":"2025-03-16T11:31:36.023Z","repository":{"id":46688889,"uuid":"112386498","full_name":"functional-promises/functional-promises","owner":"functional-promises","description":"Write code like a story w/ a powerful Fluent (function chaining) API","archived":false,"fork":false,"pushed_at":"2021-09-29T21:43:50.000Z","size":12005,"stargazers_count":155,"open_issues_count":10,"forks_count":14,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-03-07T17:18:46.552Z","etag":null,"topics":["async","composition","event-handlers","function-chain","functional-promises","hacktoberfest","monad","promise","promises"],"latest_commit_sha":null,"homepage":"https://www.fpromises.io/","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/functional-promises.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-11-28T20:37:59.000Z","updated_at":"2024-09-06T20:54:18.000Z","dependencies_parsed_at":"2022-09-26T20:30:39.581Z","dependency_job_id":null,"html_url":"https://github.com/functional-promises/functional-promises","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/functional-promises%2Ffunctional-promises","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/functional-promises%2Ffunctional-promises/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/functional-promises%2Ffunctional-promises/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/functional-promises%2Ffunctional-promises/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/functional-promises","download_url":"https://codeload.github.com/functional-promises/functional-promises/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243862937,"owners_count":20360238,"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":["async","composition","event-handlers","function-chain","functional-promises","hacktoberfest","monad","promise","promises"],"created_at":"2024-07-31T02:01:02.193Z","updated_at":"2025-03-16T11:31:31.005Z","avatar_url":"https://github.com/functional-promises.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# Functional Promises\n\n[![Build Status](https://travis-ci.org/functional-promises/functional-promises.svg?branch=master)](https://travis-ci.org/functional-promises/functional-promises)\n[![GitHub package version](https://img.shields.io/github/package-json/v/functional-promises/functional-promises.svg?style=flat)](https://github.com/functional-promises/functional-promises)\n[![GitHub stars](https://img.shields.io/github/stars/functional-promises/functional-promises.svg?label=Stars\u0026style=flat)](https://github.com/functional-promises/functional-promises)\n\n# [Updated Documentation: fpromises.io](https://www.fpromises.io/)\n\n[![New Docs](docs-source/source/images/FunctionalPromises-Docs-Upgraded-960w.gif?raw=true)](http://www.fpromises.io/)\n\n## Summary\n\nThe Functional Promises library is a [Fluent API](https://en.wikipedia.org/wiki/Fluent_interface#JavaScript) supporting a specific **Function Chaining technique** (using composition).\n\n\u003e Note: `FP` **doesn't replace or extend** Promises. It uses them.\n\nThere are many names for this general pattern. Including [Collection Pipeline](https://martinfowler.com/articles/collection-pipeline/) and Promise Chain.\nThe emphasis here is a seamless async/sync Developer Experience.\n\nI call this pattern a `Functional River` - your `data` is the _water_, and your `functions` describe its _path_ or riverbed.\n\n### Advantages\n\n* Only 400 Lines of Source \u0026 3Kb compressed\n* Easily handle Sync, Async, Events, Promises, and Callbacks.\n* Familiar methods, including `Array.prototype.map`, `[].filter()`, `[].find()`, `[].some()`, etc.\n* Create Monads in JavaScript (so far as they contain side-effects to a sequence of instructions).\n* Point-free code is easily achieved (no temp variables).\n* Higher code test coverage w/ less repetitive code in tests.\n* Use the best features from multiple programming styles: a little imperative, plenty functional, a pinch of OOP, yet still resembling declarative methods!!!\n\n#### Library Comparison\n\nTotal Lines of Code (LoC) calculated using `cloc` CLI utility.\n\nLoC #'s included because a smaller surface === fewer places bugs can hide.\n\n\n| Library                                                       | Main deal                  | Files     | Lines of Code  | .min.js kB\n|------------------------------                                 |-----------                 |---------: |--------------: |-------------------:\n| **Functional Promise v1.8.1**                                | Sync \u0026 Async Chains        |         8 |           375  | 12 Kb (3Kb compressed)\n| [Bluebird](https://github.com/petkaantonov/bluebird) v3.5.1   | Promises Replacement       |        38 |         5,188  | 80 Kb\n| [RxJS](https://github.com/ReactiveX/RxJS) v5.5.6              | Observables Chaining       |       458 |        12,266  | 150 Kb\n| [IxJS](https://github.com/ReactiveX/IxJS) v2.3.4              | \\[Async\\]Iterable Chaining |       521 |        12,366  | 145 Kb\n\nAdmittedly `IxJS`/`RxJS` have a far larger API than `FP` also some behavior in `RxJS`/`IxJS` may never be added.\nCurrently however there is a lot of overlap with `FP` (plus more planned).\n\nThe table above show `FP` is roughly **1/30th** the LOC (lines of code) in `R/IxJs`.\n`FP`'s bundle size is about **10%** the size of either `RxJS`/`IxJS`.\n\n`BluebirdJS` and `FP` have roughly the same number of API methods, yet `Bluebird` has a **fair bit more code**.\n\n\u003e **To be clear: Bluebird and RxJS/IxJS are amazing.** Their interface/designs has been very influential on `FP`.\n\u003e\n\u003e Note: [R/IxJS](https://github.com/ReactiveX/IxJS)'s hyper-modular design also allows for bundles to be lots smaller (though using quite different syntax, either `.pipe(...)` or `ix/iterable`/`ix/add/...`).\n\n## Installation\n\n```sh\nnpm install functional-promises\n```\n\n## Getting Started\n\nUse one of the following:\n\n```js\nconst FP = require('functional-promises')\n// or:\nimport FP from 'functional-promises'\n```\n\n### Quick Examples\n\n**Using `.map()`**\n\n```js\nFP.resolve([1, 2, 3, 4, 5])\n  .map(x =\u003e x * 2)\n  .map(x =\u003e x * 2)\n  .then(results =\u003e {\n    // results === [4, 8, 12, 16, 20]\n  })\n```\n\n**Handling Events**\n\nCreate function chains to handle the case where promises don't fit very naturally.\n\nFor example streams \u0026 event handlers must (usually) support multiple calls over time.\n\nHere's how `FP.chain()` and `FP.chainEnd()`/`FP.listen(obj, event)` help you handle this like a pro:\n\n```js\nconst button = document.getElementById('submitBtn')\nFP.chain() // start a chain\n  .then(({target}) =\u003e { // destructure 'target' from the `event`\n    target.textContent = 'Clicked!'\n  })\n  .listen(button, 'click') // end the repeatable chain, started at `.chain()`\n```\n\n# [API Outline](http://fpromises.io/)\n\n* [Thenable Methods](http://www.fpromises.io/#thenable-methods)\n    * [Arrays](http://www.fpromises.io/#array-methods)\n        * [`.map(fn)`](http://www.fpromises.io/#fp-map)\n        * [`.filter(fn)`](http://www.fpromises.io/#fp-filter)\n        * [`.find(fn)`](http://www.fpromises.io/#fp-find)\n        * [`.findIndex(fn)`](http://www.fpromises.io/#fp-findIndex)\n        * [`.some(fn)`](http://www.fpromises.io/#fp-some)\n        * [`.none(fn)`](http://www.fpromises.io/#fp-none)\n        * [`.series(fn)`](http://www.fpromises.io/#fp-series)\n    * [Errors](http://www.fpromises.io/#errors)\n        * [`.catch(fn)`](http://www.fpromises.io/#fp-catch)\n        * [`.catch(filter, fn)`](http://www.fpromises.io/#fp-catch)\n    * [Conditional](http://www.fpromises.io/#conditional)\n        * [`.thenIf(fn, ifTrue, ifFalse)`](http://www.fpromises.io/#fp-thenIf)\n    * [Utilities](http://www.fpromises.io/#utilities)\n        * [`.tap(fn)`](http://www.fpromises.io/#fp-tap)\n        * [`.delay(msec)`](http://www.fpromises.io/#fp-delay)\n    * [Properties](http://www.fpromises.io/#properties)\n        * [`.get(keyName)`](http://www.fpromises.io/#fp-get)\n        * [`.set(keyName, value)`](http://www.fpromises.io/#fp-set)\n* [Specialty Methods](http://www.fpromises.io/#specialty-methods)\n    * [Helpers](http://www.fpromises.io/#helpers)\n        * [`FP.resolve()`](http://www.fpromises.io/#fp-resolve)\n        * [`FP.all(Object/Array)`](http://www.fpromises.io/#fp-all)\n        * [`FP.unpack()`](http://www.fpromises.io/#fp-unpack)\n    * [Events](http://www.fpromises.io/#events)\n        * [`.listen(obj, ...eventNames)`](http://www.fpromises.io/#fp-listen)\n    * [Composition Pipelines](http://www.fpromises.io/#composition-pipelines)\n        * [`FP.chain(options)`](http://www.fpromises.io/#fp-chain)\n        * [`.chainEnd()`](http://www.fpromises.io/#fp-chainend)\n    * [Modifiers](http://www.fpromises.io/#modifiers)\n        * [`.quiet()` - prevents errors from stopping array methods mid-loop](http://www.fpromises.io/#fp-quiet)\n        * [`.concurrency(threadLimit)` - limits parallel workers for array methods](http://www.fpromises.io/#fp-concurrency)\n\n\n\n## Development\n\n```sh\ngit clone git@github.com:functional-promises/functional-promises.git\ncd functional-promises\nnpm install\nnpm test\n```\n\n\n\u003e Thanks to several influencial projects: [RxJS](https://github.com/ReactiveX/RxJS), [IxJS](https://github.com/ReactiveX/IxJS), [Bluebird](https://github.com/petkaantonov/bluebird), [asynquence](https://github.com/getify/asynquence), [FantasyLand](https://github.com/fantasyland/fantasy-land), [Gulp](https://github.com/gulpjs/gulp), [HighlandJS](https://github.com/caolan/highland), et al.\n\u003e\n\u003e Special thanks to [Kyle Simpson](https://github.com/getify), [Eric Elliot](https://medium.com/@_ericelliott), and [Sarah Drasner](https://sarahdrasnerdesign.com/) for their work for the OSS community, as well as their advice \u0026 encouragement.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffunctional-promises%2Ffunctional-promises","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffunctional-promises%2Ffunctional-promises","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffunctional-promises%2Ffunctional-promises/lists"}