{"id":22595150,"url":"https://github.com/constantiner/fun-ctional","last_synced_at":"2025-04-11T00:20:56.785Z","repository":{"id":44173437,"uuid":"135169055","full_name":"Constantiner/fun-ctional","owner":"Constantiner","description":"The library brings most of the familiar functional techniques (like functional composition) to asynchronous world with shining Promises","archived":false,"fork":false,"pushed_at":"2023-01-04T21:36:42.000Z","size":877,"stargazers_count":3,"open_issues_count":21,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-17T21:44:16.744Z","etag":null,"topics":["async","asynchronous","asynchronous-functions","asynchronous-programming","client-side","functional","functional-composition","functional-programming","javascript","javascript-library","library","mapreduce","nodejs","promise","promise-handling","promises","server-side"],"latest_commit_sha":null,"homepage":"","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/Constantiner.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-05-28T14:06:04.000Z","updated_at":"2021-08-30T13:17:35.000Z","dependencies_parsed_at":"2023-02-02T20:46:09.641Z","dependency_job_id":null,"html_url":"https://github.com/Constantiner/fun-ctional","commit_stats":null,"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Constantiner%2Ffun-ctional","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Constantiner%2Ffun-ctional/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Constantiner%2Ffun-ctional/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Constantiner%2Ffun-ctional/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Constantiner","download_url":"https://codeload.github.com/Constantiner/fun-ctional/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248318858,"owners_count":21083738,"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","asynchronous","asynchronous-functions","asynchronous-programming","client-side","functional","functional-composition","functional-programming","javascript","javascript-library","library","mapreduce","nodejs","promise","promise-handling","promises","server-side"],"created_at":"2024-12-08T10:09:10.027Z","updated_at":"2025-04-11T00:20:56.764Z","avatar_url":"https://github.com/Constantiner.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# fun-ctional\u003c!-- omit in toc --\u003e\n\n[![Build Status](https://travis-ci.org/Constantiner/fun-ctional.svg?branch=master)](https://travis-ci.org/Constantiner/fun-ctional) [![codecov](https://codecov.io/gh/Constantiner/fun-ctional/branch/master/graph/badge.svg)](https://codecov.io/gh/Constantiner/fun-ctional)\n\nWith `fun-ctional` library it is possible to use most of the familiar functional techniques (like functional composition) in asynchronous world with shining Promises.\n\nIt allows to mix synchronous and asynchronous functions to produce reusable composable functions which compatible with all good old utilities from functional libraries like [Lodash](https://lodash.com/) in terms of ability to use any synchronous functions. The only difference is that functions from `fun-ctional` library always return promises.\n\n- [Changelog](#changelog)\n- [Installation](#installation)\n- [Documentation](#documentation)\n\t- [acompose](#acompose)\n\t- [apipe](#apipe)\n\t- [amap](#amap)\n\t- [amapSeq](#amapseq)\n\t- [areduce](#areduce)\n\t- [areduceRight](#areduceright)\n\t- [afilter](#afilter)\n\t- [afilterSeq](#afilterseq)\n\t- [applyFns](#applyfns)\n\t- [acatch](#acatch)\n\t- [applySafe](#applysafe)\n\n## Changelog\n\nVersions [changelog](docs/CHANGELOG.md).\n\n## Installation\n\nInstall it with NPM:\n\n`npm install @constantiner/fun-ctional`\n\n**Note**. The UMD version of package is ES5 compatible but you may need to use [`@babel/polyfill`](https://babeljs.io/docs/en/babel-polyfill/) (for `Symbol` support) or even [`@babel/runtime`](https://babeljs.io/docs/en/babel-runtime) (`async`/`await` support) with it.\n\n**Note**. Build includes sourcemaps and minified versions of UMD files as well. You can find them in your `node_modules/@constantiner/fun-ctional/browser` folder.\n\n## Documentation\n\nAt this moment the following utilities are available:\n\n### acompose\n\nAsynchronous compose function (`acompose` stays for async-compose).\n\nThe main purpose is to replace a Promise handling code like this:\n\n```JavaScript\nsomePromise.then(normalize).then(upperCase).then(insertGreetings);\n```\n\nwith point-free style of functional compose syntax like the following:\n\n```JavaScript\nacompose(insertGreetings, upperCase, normalize)(somePromise);\n```\n\nIt is lazy and allows of reusing of promise handling chains.\n\nFirst you need to import it:\n\n```JavaScript\nimport { acompose } from \"@constantiner/fun-ctional\";\n```\n\nOr:\n\n```JavaScript\nconst { acompose } = require(\"@constantiner/fun-ctional\");\n```\n\nOr you can import it separately without the whole bundle:\n\n```JavaScript\nimport acompose from \"@constantiner/fun-ctional/acompose\";\n```\n\nOr:\n\n```JavaScript\nconst acompose = require(\"@constantiner/fun-ctional/acompose\");\n```\n\n\n\nYou can run `acompose` with Promise instance (for true asynchronous execution) or with any other object to use as usual functional composition. It produces a Promise and can be used in async/await context:\n\n```JavaScript\nconst message = await acompose(insertGreetings, upperCase, normalize)(somePromise);\n```\n\nIt also allows to handle errors like for traditional Promise but only in the tail position of the chain:\n\n```JavaScript\nacompose(insertGreetings, upperCase, normalize)(somePromise).catch(e =\u003e console.error(e));\n```\n\n### apipe\n\nAsynchronous pipe function (`apipe` stays for async-pipe).\n\nThe main purpose is to replace a Promise handling code like this:\n\n```JavaScript\nsomePromise.then(normalize).then(upperCase).then(insertGreetings);\n```\n\nwith point-free style of functional pipe syntax like the following:\n\n```JavaScript\napipe(normalize, upperCase, insertGreetings)(somePromise);\n```\n\nIt is lazy and allows of reusing of promise handling chains.\n\nFirst you need to import it:\n\n```JavaScript\nimport { apipe } from \"@constantiner/fun-ctional\";\n```\n\nOr:\n\n```JavaScript\nconst { apipe } = require(\"@constantiner/fun-ctional\");\n```\n\nOr you can import it separately without the whole bundle:\n\n```JavaScript\nimport apipe from \"@constantiner/fun-ctional/apipe\";\n```\n\nOr:\n\n```JavaScript\nconst apipe = require(\"@constantiner/fun-ctional/apipe\");\n```\n\n\nYou can run `apipe` with Promise instance (for true asynchronous execution) or with any other object to use as in usual functional composition. It produces a Promise and can be used in async/await context:\n\n```JavaScript\nconst message = await apipe(normalize, upperCase, insertGreetings)(somePromise);\n```\n\nIt also allows to handle errors like for traditional Promise but only in the tail position of the chain:\n\n```JavaScript\napipe(normalize, upperCase, insertGreetings)(somePromise).catch(e =\u003e console.error(e));\n```\n\n### amap\n\nAn asynchronous version of map over an iterable (amap stays for async-map).\n\nIt gets an iterable of values (or promises) as input (or a promise to resolve to iterable), resolves them, maps over map function and returns a promise which resolves to an array of values.\n\nIt allows asynchronous mapping point-free way and can be used with asynchronous compose functions.\n\nIt uses `Promise.all()` under the hood. So if mapping function is asynchronous (returns a promise) all promises are being generated at once and then resolved with `Promise.all()`. So if any of promises will produce error (promise rejection) all the other promises will be invoked. The advantage of this method of invoking promises it will finish earlier than sequential map (because of `Promise.all()`) but it may perform some fetches or even state modifications even in case of fail on some previous mapping steps.\n\nSee [`amapSeq`](#amapseq) for sequential implementation.\n\n```JavaScript\nconst [ first, second, third ] = await amap(getDataFromServer)([somePromise1, someValue2, somePromise3]);\n```\n\nOr even more traditional way:\n\n```JavaScript\namap(getDataFromServer)([somePromise1, someValue2, somePromise3])\n\t.then(values =\u003e console.log(values));\n```\n\nIt first resolves a promises passed and then pass resolutions value to the mapping function.\n\nMapping function is called with three parameters: `currentValue`, `currentIndex`, `array` which are plain resolved values (not promises).\n\nInput iterable's values are not restricted to promises but can be any value to pass as input to functions.\n\nIt also allows to handle errors like for traditional Promise:\n\n```JavaScript\namap(getDataFromServer)([somePromise1, someValue2, somePromise3]).catch(e =\u003e console.error(e));\n```\n\nOr you can use `try/catch` in `async/await` constructions.\n\nНou can use it with [`acompose`](#acompose) or [`apipe`](#apipe):\n\n```JavaScript\nconst usersHtml = await acompose(getHtmlRepresentation, getUserNames, amap(getUser), getUserIds)(somePromise);\n```\n\nYou can import it the following way:\n\n```JavaScript\nimport { amap } from \"@constantiner/fun-ctional\";\n```\n\nOr:\n\n```JavaScript\nconst { amap } = require(\"@constantiner/fun-ctional\");\n```\n\nOr you can import it separately without the whole bundle:\n\n```JavaScript\nimport amap from \"@constantiner/fun-ctional/amap\";\n```\n\nOr:\n\n```JavaScript\nconst amap = require(\"@constantiner/fun-ctional/amap\");\n```\n\n### amapSeq\n\nAn asynchronous version of map over an iterable (amapSeq stays for async-map).\n\nIt gets an iterable of values (or promises) as input (or a promise to resolve to iterable), resolves them, maps over map function and returns a promise which resolves to an array of values.\n\nIt allows asynchronous mapping point-free way and can be used with asynchronous compose functions.\n\nThe difference from regular [`amap`](#amap) is if map function is asynchronous (returns a promise) every new invocation of map function performs sequentially after resolving previous promise. So if any of promises produces error (promise rejection) `amapSeq` will not produce new promises and they won't be invoked.\n\nSee [`amap`](#amap) for parallel implementation.\n\n```JavaScript\nconst [ first, second, third ] = await amapSeq(getDataFromServer)([somePromise1, someValue2, somePromise3]);\n```\n\nOr even more traditional way:\n\n```JavaScript\namapSeq(getDataFromServer)([somePromise1, someValue2, somePromise3])\n\t.then(values =\u003e console.log(values));\n```\n\nIt first resolves a promises passed and then pass resolutions value to the mapping function.\n\nMapping function is called with three parameters: `currentValue`, `currentIndex`, `array` which are plain resolved values (not promises).\n\nInput iterable's values are not restricted to promises but can be any value to pass as input to functions.\n\nIt also allows to handle errors like for traditional Promise:\n\n```JavaScript\namapSeq(getDataFromServer)([somePromise1, someValue2, somePromise3]).catch(e =\u003e console.error(e));\n```\n\nOr you can use `try/catch` in `async/await` constructions.\n\nНou can use it with [`acompose`](#acompose) or [`apipe`](#apipe):\n\n```JavaScript\nconst usersHtml = await acompose(getHtmlRepresentation, getUserNames, amapSeq(getUser), getUserIds)(somePromise);\n```\n\nYou can import it the following way:\n\n```JavaScript\nimport { amapSeq } from \"@constantiner/fun-ctional\";\n```\n\nOr:\n\n```JavaScript\nconst { amapSeq } = require(\"@constantiner/fun-ctional\");\n```\n\nOr you can import it separately without the whole bundle:\n\n```JavaScript\nimport amapSeq from \"@constantiner/fun-ctional/amapSeq\";\n```\n\nOr:\n\n```JavaScript\nconst amapSeq = require(\"@constantiner/fun-ctional/amapSeq\");\n```\n\n### areduce\n\nAsynchronous composable version of `reduce` method for iterables (\"a\" stays for \"asynchronous\").\n\nIt gets a list of values (or list of promises, or promise to resolve to list) and performs standard `reduce` on them.\n\nReduce function may be asynchronous to return a promise (to fetch some data etc). Initial value of reducer also could be a promise.\n\nA sample usage is:\n\n```JavaScript\nconst sum = async (currentSum, invoiceId) =\u003e {\n\tconst { total:invoiceTotal } = await fetchInvoiceById(invoiceId);\n\treturn currentSum + invoiceTotal;\n};\n\nconst paymentTotal = await areduce(sum, 0)(fetchInvoiceIds(userId));\n```\n\nOr the same with [`acompose`](#acompose):\n\n```JavaScript\nconst paymentTotal = await acompose(areduce(sum, 0), fetchInvoiceIds)(userId);\n```\n\nIt takes a standard callback Function to execute on each element in the array, taking four standard arguments (`accumulator`, `currentValue`, `currentIndex`, `array`) and returns a function to accept input value (so it is composable).\n\nYou can import it the following way:\n\n```JavaScript\nimport { areduce } from \"@constantiner/fun-ctional\";\n```\n\nOr:\n\n```JavaScript\nconst { areduce } = require(\"@constantiner/fun-ctional\");\n```\n\nOr you can import it separately without the whole bundle:\n\n```JavaScript\nimport areduce from \"@constantiner/fun-ctional/areduce\";\n```\n\nOr:\n\n```JavaScript\nconst areduce = require(\"@constantiner/fun-ctional/areduce\");\n```\n\n### areduceRight\n\nAsynchronous composable version of `reduce` method for iterables (\"a\" stays for \"asynchronous\").\n\nIt gets a list of values (or list of promises, or promise to resolve to list) and performs standard `reduce` on them.\n\nReduce function may be asynchronous to return a promise (to fetch some data etc). Initial value of reducer also could be a promise.\n\nA sample usage is:\n\n```JavaScript\nconst sum = async (currentSum, invoiceId) =\u003e {\n\tconst { total:invoiceTotal } = await fetchInvoiceById(invoiceId);\n\treturn currentSum + invoiceTotal;\n};\n\nconst paymentTotal = await areduceRight(sum, 0)(fetchInvoiceIds(userId));\n```\n\nOr the same with [`acompose`](#acompose):\n\n```JavaScript\nconst paymentTotal = await acompose(areduceRight(sum, 0), fetchInvoiceIds)(userId);\n```\n\nIt takes a standard callback Function to execute on each element in the array, taking four standard arguments (`accumulator`, `currentValue`, `currentIndex`, `array`) and returns a function to accept input value (so it is composable).\n\nYou can import it the following way:\n\n```JavaScript\nimport { areduceRight } from \"@constantiner/fun-ctional\";\n```\n\nOr:\n\n```JavaScript\nconst { areduceRight } = require(\"@constantiner/fun-ctional\");\n```\n\nOr you can import it separately without the whole bundle:\n\n```JavaScript\nimport areduceRight from \"@constantiner/fun-ctional/areduceRight\";\n```\n\nOr:\n\n```JavaScript\nconst areduceRight = require(\"@constantiner/fun-ctional/areduceRight\");\n```\n\n### afilter\n\nAn asynchronous version of filter over an iterable (afilter stays for async-filter).\n\nIt gets an iterable of values (or promises) as input (or a promise to resolve to iterable), resolves them, filters over filter function (which returns boolean where true means current value will be included in resulting array) and returns a promise which resolves to an array of values (filtered input iterable).\n\nIt allows asynchronous filtering point-free way and can be used with asynchronous compose functions.\n\nIt uses `Promise.all()` under the hood. So if filtering function is asynchronous (returns a promise) all promises are being generated at once and then resolved with `Promise.all()`. So if any of promises will produce error (promise rejection) all the other promises will be invoked anyway. The advantage of this method of invoking promises it will finish earlier than sequential filter (because of `Promise.all()`) but it may perform some fetches or even state modifications even in case of fail on some previous filtering steps.\n\nSee [`afilterSeq`](#afilterseq) for sequential implementation.\n\n```JavaScript\nconst [ first, third ] = await afilter(fetchPermissions)([somePromise1, someValue2, somePromise3]);\n```\n\nOr even more traditional way:\n\n```JavaScript\nafilter(fetchPermissions)([somePromise1, someValue2, somePromise3])\n\t.then(values =\u003e console.log(values));\n```\n\nIt first resolves a promises passed and then pass resolutions value to the filtering function.\n\nFiltering function is called with three parameters: `currentValue`, `currentIndex`, `array` which are plain resolved values (not promises) and expects `Boolean` as return value (or a promise resolved to `Boolean`).\n\nInput iterable's values are not restricted to promises but can be any value to pass as input to functions.\n\nIt also allows to handle errors like for traditional Promise:\n\n```JavaScript\nafilter(fetchPermissions)([somePromise1, someValue2, somePromise3]).catch(e =\u003e console.error(e));\n```\n\nOr you can use `try/catch` in `async/await` constructions.\n\nНou can use it with [`acompose`](#acompose) or [`apipe`](#apipe):\n\n```JavaScript\nconst usersHtml = await acompose(getHtmlRepresentation, getUserNames, afilter(fetchPermissions), getUserIds)(somePromise);\n```\n\nYou can import it the following way:\n\n```JavaScript\nimport { afilter } from \"@constantiner/fun-ctional\";\n```\n\nOr:\n\n```JavaScript\nconst { afilter } = require(\"@constantiner/fun-ctional\");\n```\n\nOr you can import it separately without the whole bundle:\n\n```JavaScript\nimport afilter from \"@constantiner/fun-ctional/afilter\";\n```\n\nOr:\n\n```JavaScript\nconst afilter = require(\"@constantiner/fun-ctional/afilter\");\n```\n\n### afilterSeq\n\nAn asynchronous version of filter over an iterable (afilterSeq stays for async-filter).\n\nIt gets an iterable of values (or promises) as input (or a promise to resolve to iterable), resolves them, filters over filter function (which returns boolean where true means current value will be included in resulting array) and returns a promise which resolves to an array of values (filtered input iterable).\n\nIt allows asynchronous filtering point-free way and can be used with asynchronous compose functions.\n\nThe difference from regular [`afilter`](#afilter) is if filter function is asynchronous (returns a promise) every new invocation of filter function performs sequentially after resolving previous promise. So if any of promises produces error (promise rejection) `afilterSeq` will not produce new promises and they won't be invoked.\n\nSee [`afilter`](#afilter) for parallel implementation.\n\n```JavaScript\nconst [ first, third ] = await afilterSeq(fetchPermissions)([somePromise1, someValue2, somePromise3]);\n```\n\nOr even more traditional way:\n\n```JavaScript\nafilterSeq(fetchPermissions)([somePromise1, someValue2, somePromise3])\n\t.then(values =\u003e console.log(values));\n```\n\nIt first resolves a promises passed and then pass resolutions value to the filtering function.\n\nFiltering function is called with three parameters: `currentValue`, `currentIndex`, `array` which are plain resolved values (not promises) and expects `Boolean` as return value (or a promise resolved to `Boolean`).\n\nInput iterable's values are not restricted to promises but can be any value to pass as input to functions.\n\nIt also allows to handle errors like for traditional Promise:\n\n```JavaScript\nafilterSeq(fetchPermissions)([somePromise1, someValue2, somePromise3]).catch(e =\u003e console.error(e));\n```\n\nOr you can use `try/catch` in `async/await` constructions.\n\nНou can use it with [`acompose`](#acompose) or [`apipe`](#apipe):\n\n```JavaScript\nconst usersHtml = await acompose(getHtmlRepresentation, getUserNames, afilterSeq(fetchPermissions), getUserIds)(somePromise);\n```\n\nYou can import it the following way:\n\n```JavaScript\nimport { afilterSeq } from \"@constantiner/fun-ctional\";\n```\n\nOr:\n\n```JavaScript\nconst { afilterSeq } = require(\"@constantiner/fun-ctional\");\n```\n\nOr you can import it separately without the whole bundle:\n\n```JavaScript\nimport afilterSeq from \"@constantiner/fun-ctional/afilterSeq\";\n```\n\nOr:\n\n```JavaScript\nconst afilterSeq = require(\"@constantiner/fun-ctional/afilterSeq\");\n```\n\n### applyFns\n\nA kind of composable version of Promise.all().\n\nIt gets some value or promise as input, pass it to the functions list and produces the array of results after resolving all the functions which can return promises as well.\n\nIt allows to use Promise.all() point-free way:\n\n```JavaScript\nconst [ first, second ] = await applyFns(squareRoot, getDataFromServer)(somePromise);\n```\n\nOr:\n\n```JavaScript\nconst [ first, second ] = await applyFns(squareRoot, getDataFromServer)(25);\n```\n\nOr some more traditional way:\n\n```JavaScript\napplyFns(squareRoot, getDataFromServer)(somePromise)\n\t.then(([ first, second ]) =\u003e [ second, first ]);\n```\n\nIt first resolves a promise passed and then pass resolution value to all the functions.\n\nInput value is not restricted to promise but can be any value to pass as input to functions.\n\nIt also allows to handle errors like for traditional Promise:\n\n```JavaScript\napplyFns(squareRoot, getDataFromServer)(somePromise).catch(e =\u003e console.error(e));\n```\n\nor the same with async/await.\n\nYou can use it with [`acompose`](#acompose) or [`apipe`](#apipe):\n\n```JavaScript\nconst userHtml = await acompose(getHtmlRepresentation, getFullName, applyFns(getFirstNameById, getLastNameById), getUserId)(somePromise);\n```\n\nYou can import it the following way:\n\n```JavaScript\nimport { applyFns } from \"@constantiner/fun-ctional\";\n```\n\nOr:\n\n```JavaScript\nconst { applyFns } = require(\"@constantiner/fun-ctional\");\n```\n\nOr you can import it separately without the whole bundle:\n\n```JavaScript\nimport applyFns from \"@constantiner/fun-ctional/applyFns\";\n```\n\nOr:\n\n```JavaScript\nconst applyFns = require(\"@constantiner/fun-ctional/applyFns\");\n```\n\n### acatch\n\nComposable version of `catch` method for promises.\n\nIt gets a value (a promise or not), resolves it and if resulting promise was rejected, calls catch function passed.\n\nIt allows to handle errors within [`acompose`](#acompose) or [`apipe`](#apipe) asynchronous composition chains to restore broken state etc.\n\nSee [`applySafe`](#applysafe) for an option to invoke catch handler along with some mapping function.\n\nA sample with [`acompose`](#acompose):\n\n```JavaScript\nconst resultOrFallback = await acompose(acatch(handleAndRecoverFn), canFailFn)(someInput);\n```\n\nStandalone usage:\n\n```JavaScript\nconst resultOrFallback = await acatch(handleAndRecoverFn)(requestDataAndReturnPromise());\n```\n\nIt is the same as the following:\n\n```JavaScript\nrequestDataAndReturnPromise().catch(handleAndRecoverFn).then(resultOrFallback =\u003e console.log(resultOrFallback));\n```\n\nYou can import it the following way:\n\n```JavaScript\nimport { acatch } from \"@constantiner/fun-ctional\";\n```\n\nOr:\n\n```JavaScript\nconst { acatch } = require(\"@constantiner/fun-ctional\");\n```\n\nOr you can import it separately without the whole bundle:\n\n```JavaScript\nimport acatch from \"@constantiner/fun-ctional/acatch\";\n```\n\nOr:\n\n```JavaScript\nconst acatch = require(\"@constantiner/fun-ctional/acatch\");\n```\n\n### applySafe\n\nComposable version of `promise.then(mapFn).catch(catchFn)`.\n\nIt gets a value (a promise or not), resolves it and handles as `promise.then(mapFn).catch(catchFn)` returning resulting promise.\n\nIt allows to handle errors within [`acompose`](#acompose) or [`apipe`](#apipe) asynchronous composition chains to restore broken state etc.\n\nSee [`acatch`](#acatch) for composable invocation of catch handler separately.\n\nA sample with [`acompose`](#acompose):\n\n```JavaScript\nconst resultOrFallback = await acompose(applySafe(canFailFn, handleAndRecoverFn), canFailTooFn)(someInput);\n```\n\nStandalone usage:\n\n```JavaScript\nconst resultOrFallback = await applySafe(canFailFn, handleAndRecoverFn)(requestDataAndReturnPromise());\n```\n\nHere `canFailFn` is replacement for standard Promise's `then` method (which can reject) and `handleAndRecoverFn` for Promise's `catch`.\n\nIt is the same as the following:\n\n```JavaScript\nrequestDataAndReturnPromise().then(canFailFn).catch(handleAndRecoverFn).then(resultOrFallback =\u003e console.log(resultOrFallback));\n```\n\nOr even more complex example:\n\n```JavaScript\nconst resultOrFallback = await applySafe(acompose(handlerFn2, handlerFn1), handleAndRecoverFn)(requestDataAndReturnPromise());\n```\n\nYou can import it the following way:\n\n```JavaScript\nimport { applySafe } from \"@constantiner/fun-ctional\";\n```\n\nOr:\n\n```JavaScript\nconst { applySafe } = require(\"@constantiner/fun-ctional\");\n```\n\nOr you can import it separately without the whole bundle:\n\n```JavaScript\nimport applySafe from \"@constantiner/fun-ctional/applySafe\";\n```\n\nOr:\n\n```JavaScript\nconst applySafe = require(\"@constantiner/fun-ctional/applySafe\");\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fconstantiner%2Ffun-ctional","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fconstantiner%2Ffun-ctional","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fconstantiner%2Ffun-ctional/lists"}