{"id":15541916,"url":"https://github.com/snewcomer/ember-stateful-promise","last_synced_at":"2025-04-23T17:10:08.197Z","repository":{"id":43663342,"uuid":"421652568","full_name":"snewcomer/ember-stateful-promise","owner":"snewcomer","description":"Stateful wrapper for native Promises","archived":false,"fork":false,"pushed_at":"2022-02-25T03:11:55.000Z","size":5100,"stargazers_count":11,"open_issues_count":1,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-23T17:10:00.892Z","etag":null,"topics":["ember-addon","emberjs","promises"],"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/snewcomer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-10-27T02:36:19.000Z","updated_at":"2022-12-02T14:42:29.000Z","dependencies_parsed_at":"2022-08-22T16:11:03.936Z","dependency_job_id":null,"html_url":"https://github.com/snewcomer/ember-stateful-promise","commit_stats":null,"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snewcomer%2Fember-stateful-promise","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snewcomer%2Fember-stateful-promise/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snewcomer%2Fember-stateful-promise/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snewcomer%2Fember-stateful-promise/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/snewcomer","download_url":"https://codeload.github.com/snewcomer/ember-stateful-promise/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250477812,"owners_count":21437049,"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":["ember-addon","emberjs","promises"],"created_at":"2024-10-02T12:20:02.164Z","updated_at":"2025-04-23T17:10:08.159Z","avatar_url":"https://github.com/snewcomer.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"ember-stateful-promise\n==============================================================================\n\n[![Download count all time](https://img.shields.io/npm/dt/ember-stateful-promise.svg)](https://badge.fury.io/js/ember-stateful-promise)\n[![GitHub Actions Build Status](https://img.shields.io/github/workflow/status/snewcomer/ember-stateful-promise/CI/main)](https://github.com/snewcomer/ember-stateful-promise/actions/workflows/ci.yml?query=branch%3Amain)\n[![npm version](https://badge.fury.io/js/ember-stateful-promise.svg)](https://badge.fury.io/js/ember-stateful-promise)\n[![Ember Observer Score](https://emberobserver.com/badges/ember-stateful-promise.svg)](https://emberobserver.com/addons/ember-stateful-promise)\n\n[ember-concurrency](http://ember-concurrency.com/docs/introduction/) is the go to solution in the Ember community for tracking async action state and many other tasks around async behaviour.  \n\n`ember-stateful-promise` seeks to *simplify* with native `async/await` instead of generators and expose a few flags on a promise object for you to use.  Moreover, they are tracked! This library can be used if you simply need derived state your async functions and/or need a lightweight version of ember-concurrency.\n\nAlso [ember-promise-helpers](https://github.com/fivetanley/ember-promise-helpers) is another great library if you want to calculate state from your promises.  `ember-stateful-promise` is different in that is seeks to provide derived state.\n\nLastly, if you already use ember-concurrency but rather author with `async/await`, [ember-concurrency-async](https://github.com/chancancode/ember-concurrency-async) is available as a babel build time plugin.  Again, you just need to weigh the tradeoffs (size, complexity) for your project.\n\n## API\n\nSupports\n\n1. Derived state\n2. Debouncing async functions\n3. Cleanup of async functions wired up with `@ember/destroyable`\n\n- `isRunning`\n- `isResolved`\n- `isError`\n- `isCanceled`\n- `performCount`\n- `cancel()` // this.clickMe.cancel()\n\n## Usage\n\nThere are a few ways to use this addon.  Likely, you only need the `stateful-function` decorator.  However, if you need the lower level util, we make that available as `StatefulPromise` as well.\n\n\n### Decorator\n\n```js\nimport Component from '@glimmer/component';\nimport { action } from '@ember/object';\nimport { statefulFunction } from 'ember-stateful-promise/decorators/stateful-function';\n\nclass MyComponent extends Component {\n    @statefulFunction\n    async clickMe() {\n        await fetch(url);\n    }\n}\n```\n\n```hbs\n\u003cbutton\n  disabled={{if this.clickMe.isRunning \"true\"}}\n  {{on \"click\" this.clickMe}}\u003e\n    Click \n\u003c/button\u003e\n\u003cp\u003e(Clicked this many times - {{this.clickMe.performCount}})\u003c/p\u003e\n```\n\nNote - the default behaviour out of the box is to `debounce` the action.  When clicked while a promise is outstanding, the first promise will be rejected and a new promise will be created.\n\nTo throttle the function, pass `{ throttle: true }` to the decorator arguments.\n\n```js\nimport Component from '@glimmer/component';\nimport { action } from '@ember/object';\nimport { statefulFunction } from 'ember-stateful-promise/decorators/stateful-function';\n\nclass MyComponent extends Component {\n    @statefulFunction({ throttle: true })\n    async clickMe() {\n        await fetch(url);\n    }\n}\n```\n\n`@statefulFunction` replaces `@action` while giving you all the features of this addon!\n\n\n### Stateful Promise\n\n- Promise `interface`\n```js\nimport { StatefulPromise } from 'ember-stateful-promise/utils/stateful-promise';\n\nconst promise = fetch(url);\nlet result = new StatefulPromise((resolveFn, rejectFn) =\u003e {\n    promise.then((data) =\u003e resolveFn(data)).catch((e) =\u003e rejectFn(e));\n});\n\nresult.isRunning; // true\nresult.isResolved; // false\nresult.isError; // false\n\nawait result;\n\nresult.isRunning; // false\nresult.isResolved; // true\nresult.isError; // false\n```\n\n- `create` method with destroyable\n\n```js\nimport { StatefulPromise } from 'ember-stateful-promise/utils/stateful-promise';\n\nconst promise = fetch(url);\nlet result = new StatefulPromise().create(this, promise);\n\nresult.isRunning; // true\nresult.isResolved; // false\nresult.isError; // false\n\nawait result;\n\nresult.isRunning; // false\nresult.isResolved; // true\nresult.isError; // false\n```\n\n```js\nimport { StatefulPromise } from 'ember-stateful-promise/utils/stateful-promise';\nimport { action } from '@ember/object';\n\nclass MyComponent extends Component {\n    @action\n    clickMe() {\n        const promise = fetch(url);\n        // Destroyable registered\n        let result = new StatefulPromise().create(this, (resolveFn, rejectFn) =\u003e {\n            promise.then((data) =\u003e resolveFn(data)).catch((e) =\u003e rejectFn(e));\n        });\n\n        // Component destroyed\n        // and then\n        try {\n            await result;\n        } catch (e) {\n            // WILL ERROR here!\n        }\n\n    }\n}\n```\n\nCompatibility\n------------------------------------------------------------------------------\n\n* Ember.js v3.20 or above\n* Ember CLI v3.20 or above\n* Node.js v12 or above\n\n\nInstallation\n------------------------------------------------------------------------------\n\n```\nember install ember-stateful-promise\n```\n\n\nContributing\n------------------------------------------------------------------------------\n\nSee the [Contributing](CONTRIBUTING.md) guide for details.\n\n\nLicense\n------------------------------------------------------------------------------\n\nThis project is licensed under the [MIT License](LICENSE.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsnewcomer%2Fember-stateful-promise","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsnewcomer%2Fember-stateful-promise","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsnewcomer%2Fember-stateful-promise/lists"}