{"id":16823675,"url":"https://github.com/briancavalier/creed","last_synced_at":"2025-04-05T05:06:12.871Z","repository":{"id":58232100,"uuid":"39137690","full_name":"briancavalier/creed","owner":"briancavalier","description":"Sophisticated and functionally-minded async with advanced features: coroutines, promises, ES2015 iterables, fantasy-land","archived":false,"fork":false,"pushed_at":"2018-05-29T11:34:23.000Z","size":753,"stargazers_count":273,"open_issues_count":16,"forks_count":20,"subscribers_count":13,"default_branch":"master","last_synced_at":"2024-10-20T07:45:56.964Z","etag":null,"topics":["async","async-programming","asynchronous","coroutines","fantasy-land","promise"],"latest_commit_sha":null,"homepage":"https://briancavalier.github.io/creed","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/briancavalier.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":"2015-07-15T13:15:03.000Z","updated_at":"2023-12-05T18:57:29.000Z","dependencies_parsed_at":"2022-08-30T20:10:37.913Z","dependency_job_id":null,"html_url":"https://github.com/briancavalier/creed","commit_stats":null,"previous_names":[],"tags_count":29,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/briancavalier%2Fcreed","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/briancavalier%2Fcreed/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/briancavalier%2Fcreed/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/briancavalier%2Fcreed/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/briancavalier","download_url":"https://codeload.github.com/briancavalier/creed/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247289426,"owners_count":20914464,"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","async-programming","asynchronous","coroutines","fantasy-land","promise"],"created_at":"2024-10-13T11:08:48.805Z","updated_at":"2025-04-05T05:06:12.852Z","avatar_url":"https://github.com/briancavalier.png","language":"JavaScript","funding_links":[],"categories":["Libraries","Promises/A+ Implementations (ES6/ES2015 compatible)"],"sub_categories":["[Javascript](https://developer.mozilla.org/en-US/docs/Web/JavaScript)","Implementations with extras"],"readme":"# creed :: async\n\n[![Greenkeeper badge](https://badges.greenkeeper.io/briancavalier/creed.svg)](https://greenkeeper.io/)\n\n[![Join the chat at https://gitter.im/briancavalier/creed](https://badges.gitter.im/briancavalier/creed.svg)](https://gitter.im/briancavalier/creed?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n\nSophisticated and functionally-minded async with advanced features: coroutines, promises, ES2015 iterables, [fantasy-land](#fantasy-land).\n\nCreed simplifies async by letting you write coroutines using ES2015 generators and promises, and encourages functional programming via fantasy-land.  It also makes uncaught errors obvious by default, and supports other ES2015 features such as iterables.\n\nYou can also use [babel](https://babeljs.io) and the [babel-creed-async](https://github.com/briancavalier/babel-creed-async) plugin to write ES7 `async` functions backed by creed coroutines.\n\n\u003ca href=\"http://promises-aplus.github.com/promises-spec\"\u003e\u003cimg width=\"82\" height=\"82\" alt=\"Promises/A+\" src=\"http://promises-aplus.github.com/promises-spec/assets/logo-small.png\"\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/fantasyland/fantasy-land\"\u003e\u003cimg width=\"82\" height=\"82\" alt=\"Fantasy Land\" src=\"https://raw.github.com/puffnfresh/fantasy-land/master/logo.png\"\u003e\u003c/a\u003e\n[![Build Status](https://travis-ci.org/briancavalier/creed.svg?branch=master)](https://travis-ci.org/briancavalier/creed)\n[![Coverage Status](https://coveralls.io/repos/briancavalier/creed/badge.svg?branch=master\u0026service=github)](https://coveralls.io/github/briancavalier/creed?branch=master)\n\n## Example\n\nUsing creed coroutines, ES2015, and FP to solve the [async-problem](https://github.com/plaid/async-problem):\n\n```javascript\nimport { runNode, all, coroutine } from 'creed'\nimport { readFile } from 'fs'\nimport { join } from 'path'\n\n// joinPath :: String -\u003e String -\u003e String\nconst joinPath = init =\u003e tail =\u003e join(init, tail)\n\n// readFileP :: String -\u003e String -\u003e Promise Error Buffer\nconst readFileP = encoding =\u003e file =\u003e runNode(readFile, file, {encoding})\n\n// pipe :: (a -\u003e b) -\u003e (b -\u003e c) -\u003e (a -\u003e c)\nconst pipe = (f, g) =\u003e x =\u003e g(f(x))\n\n// concatFiles :: String -\u003e Promise Error String\nconst concatFiles = coroutine(function* (dir) {\n    const readUtf8P = pipe(joinPath(dir), readFileP('utf8'))\n\n    const index = yield readUtf8P('index.txt')\n    const results = yield all(index.match(/^.*(?=\\n)/gm).map(readUtf8P))\n    return results.join('')\n})\n\nconst main = process =\u003e concatFiles(process.argv[2])\n    .then(s =\u003e process.stdout.write(s))\n\nmain(process)\n```\n\n## Get it\n\n`npm install --save creed`\n\n`bower install --save creed`\n\nAs a module:\n\n```js\n// ES2015\nimport { resolve, reject, all, ... } from 'creed';\n\n// Node/CommonJS\nvar creed = require('creed')\n\n// AMD\ndefine(['creed'], function(creed) { ... })\n```\n\nAs `window.creed`:\n\n```html\n\u003c!-- Browser global: window.creed --\u003e\n\u003cscript src=\"creed/dist/creed.js\"\u003e\u003c/script\u003e\n```\n\n## Try it\n\nCreed will work anywhere ES5 works. Here's how to try it.\n\nCreed is REPL friendly, with instant and obvious feedback. [Try it out in JSBin](https://jsbin.com/muzoba/edit?js,console) or [using ES2015 with babel](https://jsbin.com/faxene/edit?js,console), or try it in Node \u003e= 6:\n\n```\nnpm install creed\nnode\n\u003e let { resolve, delay, all, race } = require('creed')\nundefined\n\u003e resolve('hello')\nPromise { fulfilled: hello }\n\u003e all([1, 2, 3].map(resolve))\nPromise { fulfilled: 1,2,3 }\n\u003e let p = delay(1000, 'done!'); p\nPromise { pending }\n\n... wait 1 second ...\n\n\u003e p\nPromise { fulfilled: done! }\n\u003e race([delay(100, 'no'), 'winner'])\nPromise { fulfilled: winner }\n```\n\n# Errors \u0026 debugging\n\nBy design, uncaught creed promise errors are fatal.  They will crash your program, forcing you to fix or [`.catch`](#catch--promise-e-a--e--bpromise-e-b--promise-e-b) them.  You can override this behavior by [registering your own error event listener](#debug-events).\n\nConsider this small program, which contains a `ReferenceError`.\n\n```js\nimport { all, runNode } from 'creed';\nimport { readFile } from 'fs';\n\nconst readFileP = file =\u003e runNode(readFile, file)\n\nconst readFilesP = files =\u003e all(files.map(readFileP))\n\nconst append = (head, tail) =\u003e head + fail; // Oops, typo will throw ReferenceError\n\n// Calling append() from nested promise causes\n// a ReferenceError, but it is not being caught\nreadFilesP(process.argv.slice(2))\n    .map(contents =\u003e contents.reduce(append, ''))\n    .then(s =\u003e console.log(s))\n```\n\nRunning this program (e.g. using `babel-node`) causes a fatal error, exiting the process with a stack trace:\n\n```\n\u003e babel-node experiments/errors.js file1 file2 ...\n/Users/brian/Projects/creed/dist/creed.js:672\n\t\tthrow value;\n\t\t^\n\nReferenceError: fail is not defined\n    at append (/Users/brian/Projects/creed/experiments/errors.js:8:39)\n    at Array.reduce (native)\n    at readFilesP.map.contents (/Users/brian/Projects/creed/experiments/errors.js:13:31)\n    at tryCall (/Users/brian/Projects/creed/dist/creed.js:344:12)\n    at Map.fulfilled (/Users/brian/Projects/creed/dist/creed.js:408:3)\n    at Fulfilled._runAction (/Users/brian/Projects/creed/dist/creed.js:945:10)\n    at Future.run (/Users/brian/Projects/creed/dist/creed.js:871:5)\n    at TaskQueue._drain (/Users/brian/Projects/creed/dist/creed.js:131:8)\n    at /Users/brian/Projects/creed/dist/creed.js:117:53\n    at _combinedTickCallback (internal/process/next_tick.js:67:7)\n```\n\n## Async traces\n\n**Experimental: V8 only**\n\nFatal stack traces are helpful, but sometimes they aren't enough.  Enable _async traces_ for stack traces for even more detail.\n\n**Note:** Enabling async traces is typically an application-level concern.  Libraries that use creed *should not* enable them in dist builds.\n\nRunning the example above with async traces enabled yields a more helpful trace. Notably:\n\n- asynchronous stack frames are shown: both the point at which map is called and the point in the mapping function (which is called asynchronous) are shown.\n- the Map operation is called out specifically\n- stack frames from within creed are omitted\n\n```\n\u003e CREED_DEBUG=1 babel-node experiments/errors.js file1 file2 ...\n/Users/brian/Projects/creed/dist/creed.js:672\n\t\tthrow value;\n\t\t^\n\nReferenceError: fail is not defined\n    at append (/Users/brian/Projects/creed/experiments/errors.js:8:39)\n    at Array.reduce (native)\n    at readFilesP.map.contents (/Users/brian/Projects/creed/experiments/errors.js:13:31)\n from Map:\n    at Object.\u003canonymous\u003e (/Users/brian/Projects/creed/experiments/errors.js:13:6)\n    at loader (/Users/brian/Projects/creed/node_modules/babel-register/lib/node.js:144:5)\n    at Object.require.extensions.(anonymous function) [as .js] (/Users/brian/Projects/creed/node_modules/babel-register/lib/node.js:154:7)\n```\n\n### Enabling async traces\n\nEnable async traces by:\n\n* `NODE_ENV=development` or `NODE_ENV=test` - async traces will be enabled automatically.\n* `CREED_DEBUG=1` (or any non-empty string) - enables async traces even if NODE_ENV=production or NODE_ENV not set.\n* [`enableAsyncTraces()`](#enableasynctraces----) - programatically enable async traces, e.g. for browsers, etc. where env vars aren't available.\n    * [`disableAsyncTraces()`](#disableasynctraces----) - programatically disable async traces.\n\n### Performance impact\n\nAsync traces typically have about a 3-4x impact on performance.\n\nThat may be just fine for some applications, while not for others.  Be sure to assess your application performance needs and budget before running with async traces enabled in production.\n\n## Debug events\n\nCreed supports global `window` events in browsers, and `process` events in Node, similar to Node's `'uncaughtException'` event. This allows applications to register a handler to receive events from all promise implementations that support these global events.\n\nErrors passed to unhandled rejection event handlers will have [async traces](#async-traces) if they are enabled.\n\nThe events are:\n\n* `'unhandledRejection'`: fired when an unhandled rejection is detected\n* `'rejectionHandled'`: fired when rejection previously reported via an '`unhandledRejection'` event becomes handled\n\n## Node global process events\n\nThe following example shows how to use global `process` events in Node.js to implement simple debug output.  The parameters passed to the `process` event handlers:\n\n* `reason` - the rejection reason, typically an `Error` instance.\n* `promise` - the promise that was rejected.  This can be used to correlate corresponding `unhandledRejection` and `rejectionHandled` events for the same promise.\n\n```js\nprocess.on('unhandledRejection', reportRejection)\nprocess.on('rejectionHandled', reportHandled)\n\nfunction reportRejection(error, promise) {\n\t// Implement whatever logic your application requires\n\t// Log or record error state, etc.\n}\n\nfunction reportHandled(promise) {\n\t// Implement whatever logic your application requires\n\t// Log that error has been handled, etc.\n}\n```\n\n## Browser window events\n\nThe following example shows how to use global `window` events in browsers to implement simple debug output.  The `event` object has the following extra properties:\n\n* `event.detail.reason` - the rejection reason (typically an `Error` instance)\n* `event.detail.promise` - the promise that was rejected.  This can be used to correlate corresponding `unhandledRejection` and `rejectionHandled` events for the same promise.\n\n```js\nwindow.addEventListener('unhandledRejection', event =\u003e {\n\t// Calling preventDefault() suppresses default rejection logging\n\t// in favor of your own.\n\tevent.preventDefault()\n\treportRejection(event.detail.reason, event.detail.promise)\n}, false)\n\nwindow.addEventListener('rejectionHandled', event =\u003e {\n\t// Calling preventDefault() suppresses default rejection logging\n\t// in favor of your own.\n\tevent.preventDefault()\n\treportHandled(event.detail.promise)\n}, false)\n\nfunction reportRejection(error, promise) {\n\t// Implement whatever logic your application requires\n\t// Log or record error state, etc.\n}\n\nfunction reportHandled(promise) {\n\t// Implement whatever logic your application requires\n\t// Log that error has been handled, etc.\n}\n```\n\n# API\n\n## Run async tasks\n\n### coroutine :: Generator a \u0026rarr; (...* \u0026rarr; Promise e a)\n\nCreate an async coroutine from a promise-yielding generator.\n\n```js\nimport { coroutine } from 'creed';\n\nfunction fetchTextFromUrl(url) {\n    // Fetch the text and return a promise for it\n    return promise;\n}\n\n// Make an async coroutine from a generator\nlet getUserProfile = coroutine(function* (userId) {\n    try {\n        let profileUrl = yield getUserProfileUrlFromDB(userId)\n        let text = yield fetchTextFromUrl(profileUrl)\n        return text;\n    } catch(e) {\n        return getDefaultText()\n    }\n})\n\n// Call it\ngetUserProfile(123)\n    .then(profile =\u003e console.log(profile))\n```\n\nNote: In current implementations of JavaScript, it's not possible to detect with reasonable certainty if the function passed to `coroutine` is a generator function or not.  Creed can't know until the function is executed, causing creed to throw an exception synchronously at run-time.\n\n### fromNode :: NodeApi e a \u0026rarr; (...* \u0026rarr; Promise e a)\ntype NodeApi e a = ...* \u0026rarr; Nodeback e a \u0026rarr; ()\u003cbr/\u003e\ntype Nodeback e a = e \u0026rarr; a \u0026rarr; ()\n\nTurn a Node API into a promise API\n\n```js\nimport { fromNode } from 'creed';\nimport { readFile } from 'fs';\n\n// Make a promised version of fs.readFile\nlet readFileP = fromNode(readFile)\n\nreadFileP('theFile.txt', 'utf8')\n    .then(contents =\u003e console.log(contents))\n```\n\n### runNode :: NodeApi e a \u0026rarr; ...* \u0026rarr; Promise e a\ntype NodeApi e a = ...* \u0026rarr; Nodeback e a \u0026rarr; ()\u003cbr/\u003e\ntype Nodeback e a = e \u0026rarr; a \u0026rarr; ()\n\nRun a Node API and return a promise for its result.\n\n```js\nimport { runNode } from 'creed';\nimport { readFile } from 'fs';\n\nrunNode(readFile, 'theFile.txt', 'utf8')\n    .then(contents =\u003e console.log(contents))\n```\n\n### runPromise :: Producer e a \u0026rarr; ...* \u0026rarr; Promise e a\ntype Producer e a = (...* \u0026rarr; Resolve e a \u0026rarr; Reject e \u0026rarr; ())\u003cbr/\u003e\ntype Resolve e a = a|Thenable e a \u0026rarr; ()\u003cbr/\u003e\ntype Reject e = e \u0026rarr; ()\n\nRun a function to produce a promised result.\n\n```js\nimport { runPromise } from 'creed';\n\n/* Run a function, threading in a url parameter */\nlet p = runPromise((url, resolve, reject) =\u003e {\n    var xhr = new XMLHttpRequest;\n    xhr.addEventListener(\"error\", reject)\n    xhr.addEventListener(\"load\", resolve)\n    xhr.open(\"GET\", url)\n    xhr.send(null)\n}, 'http://...') // inject url parameter\n\np.then(result =\u003e console.log(result))\n```\n\nParameter threading also makes it easy to create reusable tasks\nthat don't rely on closures and scope chain capturing.\n\n```js\nimport { runPromise } from 'creed';\n\nfunction xhrGet(url, resolve, reject) =\u003e {\n    var xhr = new XMLHttpRequest;\n    xhr.addEventListener(\"error\", reject)\n    xhr.addEventListener(\"load\", resolve)\n    xhr.open(\"GET\", url)\n    xhr.send(null)\n}\n\nrunPromise(xhrGet, 'http://...')\n    .then(result =\u003e console.log(result))\n```\n\n### merge :: (...* \u0026rarr; b) \u0026rarr; ...Promise e a \u0026rarr; Promise e b\n\nMerge promises by passing their fulfillment values to a merge\nfunction.  Returns a promise for the result of the merge function.\nEffectively liftN for promises.\n\n```js\nimport { merge, resolve } from 'creed';\n\nmerge((x, y) =\u003e x + y, resolve(123), resolve(1))\n    .then(z =\u003e console.log(z)) //=\u003e 124\n```\n\n## Make promises\n\n### future :: () \u0026rarr; { resolve: Resolve e a, promise: Promise e a }\ntype Resolve e a = a|Thenable e a \u0026rarr; ()\u003cbr/\u003e\n\nCreate a `{ resolve, promise }` pair, where `resolve` is a function that seals the fate of `promise`.\n\n```js\nimport { future, reject } from 'creed';\n\n// Fulfill\nlet { resolve, promise } = future()\nresolve(123)\npromise.then(x =\u003e console.log(x)) //=\u003e 123\n\n// Resolve to another promise\nlet anotherPromise = ...;\nlet { resolve, promise } = future()\nresolve(anotherPromise) //=\u003e make promise's fate the same as anotherPromise's\n\n// Reject\nlet { resolve, promise } = future()\nresolve(reject(new Error('oops')))\npromise.catch(e =\u003e console.log(e)) //=\u003e [Error: oops]\n```\n\n### resolve :: a|Thenable e a \u0026rarr; Promise e a\n\nCoerce a value or Thenable to a promise.\n\n```js\nimport { resolve } from 'creed';\n\nresolve(123)\n    .then(x =\u003e console.log(x)) //=\u003e 123\n\nresolve(resolve(123))\n    .then(x =\u003e console.log(x)) //=\u003e 123\n\nresolve(jQuery.get('http://...')) // coerce any thenable\n    .then(x =\u003e console.log(x)) //=\u003e 123\n```\n\n### fulfill :: a \u0026rarr; Promise e a\n\nLift a value into a promise.\n\n```js\nimport { fulfill, resolve } from 'creed';\n\nfulfill(123)\n    .then(x =\u003e console.log(x)) //=\u003e 123\n\n// Note the difference from resolve\nfulfill(fulfill(123))\n    .then(x =\u003e console.log(x)) //=\u003e '[object Promise { fulfilled: 123 }]'\n\nresolve(fulfill(123))\n    .then(x =\u003e console.log(x)) //=\u003e 123\n```\n\n### reject :: Error e =\u003e e \u0026rarr; Promise e a\n\nMake a rejected promise for an error.\n\n```js\nimport { reject } from 'creed';\n\nreject(new TypeError('oops!'))\n    .catch(e =\u003e console.log(e.message)) //=\u003e oops!\n```\n\n### never :: Promise e a\n\nMake a promise that remains pending forever.\n\n```js\nimport { never } from 'creed';\n\nnever()\n    .then(x =\u003e console.log(x)) // nothing logged, ever\n```\n\nNote: `never` consumes virtually no resources.  It does not hold references\nto any functions passed to `then`, `map`, `chain`, etc.\n\n## Transform promises\n\n### .then :: Promise e a \u0026rarr; (a \u0026rarr; b|Promise e b) \u0026rarr; Promise e b\n\n[Promises/A+ then](http://promisesaplus.com/).\nTransform a promise's value by applying a function to the\npromise's fulfillment value. Returns a new promise for the\ntransformed result.\n\n```js\nimport { resolve } from 'creed';\n\nresolve(1)\n    .then(x =\u003e x + 1) // return a transformed value\n    .then(y =\u003e console.log(y)) //=\u003e 2\n\nresolve(1)\n    .then(x =\u003e resolve(x + 1)) // return transformed promise\n    .then(y =\u003e console.log(y)) //=\u003e 2\n```\n\n### .catch :: Promise e a \u0026rarr; (e \u0026rarr; b|Promise e b) \u0026rarr; Promise e b\n\nCatch and handle a promise error.\n\n```js\nimport { reject, resolve } from 'creed';\n\nreject(new Error('oops!'))\n    .catch(e =\u003e 123) // recover by returning a new value\n    .then(x =\u003e console.log(x)) //=\u003e 123\n\nreject(new Error('oops!'))\n    .catch(e =\u003e resolve(123)) // recover by returning a promise\n    .then(x =\u003e console.log(x)) //=\u003e 123\n```\n\n### .finally :: Promise e a \u0026rarr; (() \u0026rarr; b|Promise e b) \u0026rarr; Promise e a\n\nPerform cleanup side effects regardless of a Promise's outcome.  If a finally handler:\n\n1. returns a non-promise, it is discarded\n2. returns a promise that fulfills, it's fulfillment value is discarded\n3. throws, the thrown error will take precedence\n4. returns a rejected promise, the rejection will take precedence\n\n```js\nimport { reject, resolve, delay } from 'creed'\n\nresolve(123)\n  .finally(() =\u003e resolve(456)) // do some cleanup\n  .then(x =\u003e console.log(x)) //=\u003e 123\n\nreject(new Error('oops!'))\n  .finally(() =\u003e resolve(456)) // do some cleanup\n  .catch(e =\u003e console.log(e.message)) //=\u003e oops!\n\nreject(new Error('oops!'))\n  .finally(() =\u003e delay(1000, 456)) // do some cleanup\n  .catch(e =\u003e console.log(e.message)) //=\u003e oops! after 1 second\n```\n\nAs mentioned above, errors from a finally handler take precedence:\n\n```js\n// Errors in finally handler take precedence\nreject(new Error('oops!'))\n  .finally(() =\u003e reject(new Error('finally error'))) // cleanup failed!\n  .catch(e =\u003e console.log(e.message)) //=\u003e finally error\n\nreject(new Error('oops!'))\n  .finally(() =\u003e {\n    throw new Error('finally error') // cleanup failed!\n  })\n  .catch(e =\u003e console.log(e.message)) //=\u003e finally error\n```\n\n### .map :: Promise e a \u0026rarr; (a \u0026rarr; b) \u0026rarr; Promise e b\n\nTransform a promise's value by applying a function.  The return\nvalue of the function will be used verbatim, even if it is a promise.\nReturns a new promise for the transformed value.\n\n```js\nimport { resolve } from 'creed';\n\nresolve(1)\n    .map(x =\u003e x + 1) // return a transformed value\n    .then(y =\u003e console.log(y)) //=\u003e 2\n```\n\n### .bimap :: Promise e a \u0026rarr; (e \u0026rarr; f) \u0026rarr; (a \u0026rarr; b) \u0026rarr; Promise f b\n\n[Fantasy-land Functor](https://github.com/fantasyland/fantasy-land#bifunctor).\nTransform a promise's error or value by applying functions to either.  The\nfirst function will be applied to the error of a rejected promise, and\nthe second function will be applied to the value of a fulfilled promise.\nLike `map`, the return value of the applied function will be used verbatim,\neven if it is a promise. Returns a new promise for the transformed value.\n\n```js\nimport { resolve, reject } from 'creed';\n\nresolve(1)\n    .bimap(e =\u003e new Error('not called'), x =\u003e x + 1) // transform value\n    .then(y =\u003e console.log(y)) //=\u003e 2\n\nreject(new Error('oops'))\n    .bimap(e =\u003e new Error(e.message + '!!!'), x =\u003e x + 1) // transform error\n    .catch(e =\u003e console.log(e)) //=\u003e Error: oops!!!\n```\n\n### .ap :: Promise e (a \u0026rarr; b) \u0026rarr; Promise e a \u0026rarr; Promise e b\n\nApply a promised function to a promised value.  Returns a new promise\nfor the result.\n\n```js\nimport { resolve } from 'creed';\n\nresolve(x =\u003e x + 1)\n    .ap(resolve(123))\n    .then(y =\u003e console.log(y)) //=\u003e 124\n\nresolve(x =\u003e y =\u003e x+y)\n    .ap(resolve(1))\n    .ap(resolve(123))\n    .then(y =\u003e console.log(y)) //=\u003e 124\n```\n\n### .chain :: Promise e a \u0026rarr; (a \u0026rarr; Promise e b) \u0026rarr; Promise e b\n\nSequence async actions.  When a promise fulfills, run another\nasync action and return a promise for its result.\n\n```js\nlet profileText = getUserProfileUrlFromDB(userId)\n    .chain(fetchTextFromUrl)\n\nprofileText.then(text =\u003e console.log(text)) //=\u003e \u003cuser profile text\u003e\n```\n\n### .or :: Promise e a \u0026rarr; Promise e a \u0026rarr; Promise e a\n### (deprecated) .concat :: Promise e a \u0026rarr; Promise e a \u0026rarr; Promise e a\n\n**Note:** The name `concat` is deprecated, use `or` instead.\n\nReturns a promise equivalent to the *earlier* of two promises. Preference is given to the callee promise in the case that both promises have already settled.\n\n```js\nimport { delay, fulfill } from 'creed';\n\ndelay(200, 'bar').or(delay(100, 'foo'))\n    .then(x =\u003e console.log(x)); //=\u003e 'foo'\n\nfulfill(123).or(fulfill(456))\n    .then(x =\u003e console.log(x)); //=\u003e 123\n```\n\n## Control time\n\n### delay :: Int \u0026rarr; a|Promise e a \u0026rarr; Promise e a\n\nCreate a delayed promise for a value, or further delay the fulfillment\nof an existing promise.  Delay only delays fulfillment: it has no\neffect on rejected promises.\n\n```js\nimport { delay, reject } from 'creed';\n\ndelay(5000, 'hi')\n    .then(x =\u003e console.log(x)) //=\u003e 'hi' after 5 seconds\n\ndelay(5000, delay(1000, 'hi'))\n    .then(x =\u003e console.log(x)) //=\u003e 'hi' after 6 seconds\n\ndelay(5000, reject(new Error('oops')))\n    .catch(e =\u003e console.log(e.message)) //=\u003e 'oops' immediately\n```\n\n### timeout :: Int \u0026rarr; Promise e a \u0026rarr; Promise e a\n\nCreate a promise that will reject after a specified time unless\nit settles earlier.\n\n```js\nimport { delay } from 'creed';\n\ntimeout(2000, delay(1000, 'hi'))\n    .then(x =\u003e console.log(x)) //=\u003e 'hi' after 1 second\n\ntimeout(1000, delay(2000, 'hi')) //=\u003e TimeoutError after 1 second\n```\n\n## Resolve Iterables\n\nCreed's iterable functions accept any ES2015 Iterable.  Most of\nthe examples in this section show Arrays, but Sets, generators,\netc. will work as well.\n\n### all :: Iterable (Promise e a) \u0026rarr; Promise e [a]\n\nAwait all promises from an Iterable.  Returns a promise that fulfills\nwith an array containing all input promise fulfillment values,\nor rejects if at least one input promise rejects.\n\n```js\nimport { all, resolve } from 'creed';\n\nall([resolve(123), resolve(456)])\n    .then(x =\u003e console.log(x)) //=\u003e [123, 456]\n\nlet promises = new Set()\npromises.add(resolve(123))\npromises.add(resolve(456))\n\nall(promises)\n    .then(x =\u003e console.log(x)) //=\u003e [123, 456]\n\nfunction *generator() {\n    yield resolve(123)\n    yield resolve(456)\n}\n\nall(generator())\n    .then(x =\u003e console.log(x)) //=\u003e [123, 456]\n```\n\n### race :: Iterable (Promise e a) \u0026rarr; Promise e a\n\nReturns a promise equivalent to the input promise that *settles* earliest.\n\nIf there are input promises that are already settled or settle\nsimultaneously, race prefers the one encountered first in the\niteration order.\n\nNote the differences from `any()`.\n\n**Note:** As per the ES6-spec, racing an empty iterable returns `never()`\n\n```js\nimport { race, resolve, reject, delay, isNever } from 'creed';\n\nrace([delay(100, 123), resolve(456)])\n    .then(x =\u003e console.log(x)) //=\u003e 456\n\nrace([resolve(123), reject(456)])\n    .then(x =\u003e console.log(x)) //=\u003e 123\n\nrace([delay(100, 123), reject(new Error('oops'))])\n    .catch(e =\u003e console.log(e)) //=\u003e [Error: oops]\n\nisNever(race([])) //=\u003e true\n```\n\n### any :: Iterable (Promise e a) \u0026rarr; Promise e a\n\nReturns a promise equivalent to the input promise that *fulfills*\nearliest.  If all input promises reject, the returned promise rejects.\n\nIf there are input promises that are already fulfilled or fulfill\nsimultaneously, any prefers the one encountered first in the\niteration order.\n\nNote the differences from `race()`.\n\n```js\nimport { any, resolve, reject, delay, isNever } from 'creed';\n\nany([delay(100, 123), resolve(456)])\n    .then(x =\u003e console.log(x)); //=\u003e 456\n\nany([resolve(123), reject(456)])\n    .then(x =\u003e console.log(x)) //=\u003e 123\n\nany([reject(456), resolve(123)])\n    .then(x =\u003e console.log(x)); //=\u003e 123\n\nany([delay(100, 123), reject(new Error('oops'))])\n    .catch(e =\u003e console.log(e)); //=\u003e 123\n\nany([reject(new Error('foo')), reject(new Error('bar'))])\n    .catch(e =\u003e console.log(e)) //=\u003e [RangeError: No fulfilled promises in input]\n\nany([])\n    .catch(e =\u003e console.log(e)) //=\u003e [RangeError: No fulfilled promises in input]\n```\n\n### settle :: Iterable (Promise e a) \u0026rarr; Promise e [Promise e a]\n\nReturns a promise that fulfills with an array of settled promises.\n\n```js\nimport { settle, resolve, reject, isFulfilled, getValue } from 'creed';\n\n// Find all the fulfilled promises in an iterable\nsettle([resolve(123), reject(new Error('oops')), resolve(456)])\n    .map(settled =\u003e settled.filter(isFulfilled).map(getValue))\n    .then(fulfilled =\u003e console.log(fulfilled)) //=\u003e [ 123, 456 ]\n```\n\n## Inspect\n\n### isFulfilled :: Promise e a \u0026rarr; boolean\n\nReturns true if the promise is fulfilled.\n\n```js\nimport { isFulfilled, resolve, reject, delay, never } from 'creed';\n\nisFulfilled(resolve(123))        //=\u003e true\nisFulfilled(reject(new Error())) //=\u003e false\nisFulfilled(delay(0, 123))       //=\u003e true\nisFulfilled(delay(1, 123))       //=\u003e false\nisFulfilled(never())             //=\u003e false\n```\n\n### isRejected :: Promise e a \u0026rarr; boolean\n\nReturns true if the promise is rejected.\n\n```js\nimport { isRejected, resolve, reject, delay, never } from 'creed';\n\nisRejected(resolve(123))        //=\u003e false\nisRejected(reject(new Error())) //=\u003e true\nisRejected(delay(0, 123))       //=\u003e false\nisRejected(delay(1, 123))       //=\u003e false\nisRejected(never())             //=\u003e false\n```\n\n### isSettled :: Promise e a \u0026rarr; boolean\n\nReturns true if the promise is either fulfilled or rejected.\n\n```js\nimport { isSettled, resolve, reject, delay, never } from 'creed';\n\nisSettled(resolve(123))        //=\u003e true\nisSettled(reject(new Error())) //=\u003e true\nisSettled(delay(0, 123))       //=\u003e true\nisSettled(delay(1, 123))       //=\u003e false\nisSettled(never())             //=\u003e false\n```\n\n### isPending :: Promise e a \u0026rarr; boolean\n\nReturns true if the promise is pending (not yet fulfilled or rejected).\n\n```js\nimport { isPending, resolve, reject, delay, never } from 'creed';\n\nisPending(resolve(123))        //=\u003e false\nisPending(reject(new Error())) //=\u003e false\nisPending(delay(0, 123))       //=\u003e false\nisPending(delay(1, 123))       //=\u003e true\nisPending(never())             //=\u003e true\n```\n\n### isNever :: Promise e a \u0026rarr; boolean\n\nReturns true if it is known that the promise will remain pending\nforever.  In practice, this means that the promise is one that was\nreturned by `never()` or a promise that has been resolved to such.\n\n```js\nimport { isNever, resolve, reject, delay, never, race } from 'creed';\n\nisNever(resolve(123))         //=\u003e false\nisNever(reject(new Error()))  //=\u003e false\nisNever(delay(0, 123))        //=\u003e false\nisNever(delay(1, 123))        //=\u003e false\nisNever(never())              //=\u003e true\nisNever(resolve(never()))     //=\u003e true\nisNever(delay(1000, never())) //=\u003e true\nisNever(race([]))             //=\u003e true\n```\n\n### getValue :: Promise e a \u0026rarr; a\n\nExtract the value of a *fulfilled* promise.  Throws if called on a\npending or rejected promise, so check first with `isFulfilled`.\n\n```js\nimport { getValue, resolve, reject, never } from 'creed';\n\ngetValue(resolve(123)) //=\u003e 123\ngetValue(reject())     //=\u003e throws TypeError\ngetValue(never())      //=\u003e throws TypeError\n```\n\n### getReason :: Promise e a \u0026rarr; e\n\nExtract the reason of a *rejected* promise.  Throws if called on a\npending or fulfilled promise, so check first with `isRejected`.\n\n```js\nimport { getReason, resolve, reject, never } from 'creed';\n\ngetReason(resolve(123))      //=\u003e throws TypeError\ngetReason(reject('because')) //=\u003e 'because'\ngetReason(never())           //=\u003e throws TypeError\n```\n\n## Debugging\n\n### enableAsyncTraces :: () \u0026rarr; ()\n\nEnable [async traces](#async-traces).  Can be called at any time, but will only trace promises created *after* it's called.  If called multiple times, *resets* the tracing state each time.\n\n### disableAsyncTraces :: () \u0026rarr; ()\n\nDisable [async traces](#async-traces).\n\n### isHandled :: Promise e a \u0026rarr; boolean\n\nReturns true if the promise is rejected and the rejection has been \"handled\", that is, [`.catch`](#catch--promise-e-a--e--bpromise-e-b--promise-e-b) has been called on the promise at least once with an argument that is a Function.\n\nNote that if `.catch` is called with zero arguments or with an argument that isn't a Function, it _does not_ affect the \"handled\" state of the promise.\n\n## Polyfill\n\n### shim :: () \u0026rarr; PromiseConstructor|undefined\n\nPolyfill the global `Promise` constructor with an ES6-compliant\ncreed `Promise`.  If there was a pre-existing global `Promise`,\nit is returned.\n\n```js\nimport { shim } from 'creed';\n\n// Install creed's ES2015-compliant Promise as global\nlet NativePromise = shim()\n\n// Create a creed promise\nPromise.resolve(123)\n```\n\n## Fantasy Land\n\nCreed implements Fantasy Land 2.1:\n\n* [Functor](https://github.com/fantasyland/fantasy-land#functor)\n* [Bifunctor](https://github.com/fantasyland/fantasy-land#bifunctor)\n* [Apply](https://github.com/fantasyland/fantasy-land#apply)\n* [Applicative](https://github.com/fantasyland/fantasy-land#applicative)\n* [Alt](https://github.com/fantasyland/fantasy-land#alt)\n* [Plus](https://github.com/fantasyland/fantasy-land#plus)\n* [Alternative](https://github.com/fantasyland/fantasy-land#alternative)\n* [Chain](https://github.com/fantasyland/fantasy-land#chain)\n* [Monad](https://github.com/fantasyland/fantasy-land#monad)\n* [Semigroup](https://github.com/fantasyland/fantasy-land#semigroup)\n* [Monoid](https://github.com/fantasyland/fantasy-land#monoid)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbriancavalier%2Fcreed","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbriancavalier%2Fcreed","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbriancavalier%2Fcreed/lists"}