{"id":19602658,"url":"https://github.com/qiwi/inside-out-promise","last_synced_at":"2026-05-13T18:39:18.370Z","repository":{"id":35102524,"uuid":"206583348","full_name":"qiwi/inside-out-promise","owner":"qiwi","description":"Inside out Promise factory","archived":false,"fork":false,"pushed_at":"2023-10-03T08:33:32.000Z","size":2965,"stargazers_count":1,"open_issues_count":9,"forks_count":0,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-02-18T02:39:00.868Z","etag":null,"topics":["js-platform","promise","utils"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/qiwi.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-09-05T14:25:48.000Z","updated_at":"2022-04-11T15:06:28.000Z","dependencies_parsed_at":"2024-10-23T07:18:03.062Z","dependency_job_id":"c5c43809-c07c-4872-a5ee-b1f6098e1b40","html_url":"https://github.com/qiwi/inside-out-promise","commit_stats":{"total_commits":95,"total_committers":6,"mean_commits":"15.833333333333334","dds":0.4526315789473684,"last_synced_commit":"6bf4797669596c820dc65121ed4708b8341c2523"},"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qiwi%2Finside-out-promise","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qiwi%2Finside-out-promise/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qiwi%2Finside-out-promise/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qiwi%2Finside-out-promise/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/qiwi","download_url":"https://codeload.github.com/qiwi/inside-out-promise/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240885484,"owners_count":19873525,"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":["js-platform","promise","utils"],"created_at":"2024-11-11T09:25:20.953Z","updated_at":"2026-05-13T18:39:13.345Z","avatar_url":"https://github.com/qiwi.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# inside-out-promise\nProduces promises with chainable resolvers and observable state.\n\n[![Build Status](https://travis-ci.com/qiwi/inside-out-promise.svg?branch=master)](https://travis-ci.com/qiwi/inside-out-promise)\n[![David](https://img.shields.io/david/qiwi/inside-out-promise?label=deps)](https://david-dm.org/qiwi/inside-out-promise)\n[![Maintainability](https://api.codeclimate.com/v1/badges/45b3792789211c6c8f09/maintainability)](https://codeclimate.com/github/qiwi/inside-out-promise/maintainability)\n[![Test Coverage](https://api.codeclimate.com/v1/badges/45b3792789211c6c8f09/test_coverage)](https://codeclimate.com/github/qiwi/inside-out-promise/test_coverage)\n[![npm](https://img.shields.io/npm/v/inside-out-promise)](https://www.npmjs.com/package/inside-out-promise)\n\n## Install\n```bash\nnpm add inside-out-promise\nyarn add inside-out-promise\n```\n\n## Key features\n* Chainable `resolve` and `reject` methods\n* Exposed promise `state` and `result` fields\n* Configurable `Promise` implementation\n* **TS** and **Flow** typings out of box\n\n## Usage\n```javascript\nimport {factory} from 'inside-out-promise'\n\nconst promise = factory() // produces a promise\npromise.then((data) =\u003e {  // standard `thenable` iface\n  doSomething(data)\n})\n\nconst data = await fetch({...})\npromise.resolve(data)     // internal resolver is exposed as public promise field\npromise.result            // data ref\npromise.value             // same data ref, result alias\npromise.state             // 'Fulfilled'\npromise.status            // status alias: 'Fulfilled'\npromise.isPending()       // false\npromise.isFulfilled()     // true\npromise.isResolved()      // true\n\n// Or the same in OOP style\nimport {InsideOutPromise} from 'inside-out-promise'\nconst p = new InsideOutPromise()\n```\n## API\n#### Resolvers\nBoth `executor` args — `resolve` and `reject` — are available as chainable public methods:\n```javascript\nconst promise = factory()\n\npromise.resolve('foo')            // This's a promise\npromise.reject(new Error('bar'))  // and this is too\n```\n\n#### Chains\n```javascript\nfactory().resolve('value').then(data =\u003e {\n  // here's the value: data === 'value'\n})\n\nfactory().catch(error =\u003e {\n  // the error goes here\n}).reject(new Error())\n```\n\nYou're able to combine steps in Java-like style: first build the \"[CompletableFuture](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html)\" chain and `resolve` it after\n```javascript\nconst p = new InsideOutPromise()\n  .then(data =\u003e data.repeat(2))\n    .then(data =\u003e data.toUpperCase())\n      .then(data =\u003e data + 'bar')\n        .resolve('foo')\n\nconst res = await p // 'FOOFOObar'\n```\n\nEach step return `InsideOutPromise` instance inherited from `Promise`, `Bluebird` (see [Configuration](#Configuration) for details), etc, so the `intanceof` check still works.\n```javascript\nconst p1 = new InsideOutPromise()\nconst p2 = p1.then(data =\u003e data)\n\nconst v1 = await(p1)\nconst v2 = await(p2)\n\nexpect(p1).toBeInstanceOf(Promise)\nexpect(p2).toBeInstanceOf(Promise)\nexpect(p1).toBeInstanceOf(InsideOutPromise)\nexpect(p2).toBeInstanceOf(InsideOutPromise)\n```\n\n#### State\nPromise [state](https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/Promise.jsm/Promise) field may take values: `Pending`, `Fulfilled` and `Rejected` \n```javascript\nconst promise = factory()\npromise.state // 'Pending'\n\npromise.resolve()\npromise.state // 'Fulfilled'\n```\n\nThere're also 3 helper methods:\n* `isPending()`\n* `isRejected()`\n* `isFulfilled()`\n\n#### InsideOutPromise\n```javascript\nimport InsideOutPromise from 'inside-out-promise'\n\nconst promise = new InsideOutPromise((resolve, reject) =\u003e {\n  // Legacy executor flow is still supported\n  // ...\n})\n\npromise.resolve('foo')\npromise.then(data =\u003e console.log(data)) // It's `foo`\n```\n\n## \u003ca name=\"Configuration\"\u003e\u003c/a\u003eConfiguration\n```javascript\nimport factory from 'inside-out-promise'\nimport * as Bluebird from 'bluebird'\n\nfactory.Promise = Bluebird // Native `Promise` by default\n```\n\n## Refs\n* [Fulfill vs resolve](https://stackoverflow.com/questions/35398365/js-promises-fulfill-vs-resolve)\n* [States and fates](https://github.com/domenic/promises-unwrapping/blob/master/docs/states-and-fates.md)\n* [esimorp](https://github.com/WebReflection/esimorp)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqiwi%2Finside-out-promise","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fqiwi%2Finside-out-promise","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqiwi%2Finside-out-promise/lists"}