{"id":19805990,"url":"https://github.com/cycloidio/state-updater-on-actions","last_synced_at":"2025-02-28T12:19:44.187Z","repository":{"id":57369949,"uuid":"129944507","full_name":"cycloidio/state-updater-on-actions","owner":"cycloidio","description":"Update a shared state by asynchronous actions when indicated","archived":false,"fork":false,"pushed_at":"2019-04-24T13:28:19.000Z","size":751,"stargazers_count":0,"open_issues_count":4,"forks_count":0,"subscribers_count":7,"default_branch":"master","last_synced_at":"2024-04-25T12:21:30.266Z","etag":null,"topics":["asynchronous","browser","js-library","nodejs"],"latest_commit_sha":null,"homepage":"https://cycloidio.github.io/state-updater-on-actions/docs/api/","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/cycloidio.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-04-17T17:57:21.000Z","updated_at":"2024-04-25T12:21:30.267Z","dependencies_parsed_at":"2022-09-09T16:40:15.873Z","dependency_job_id":null,"html_url":"https://github.com/cycloidio/state-updater-on-actions","commit_stats":null,"previous_names":["cycloidio/state-update-on-actions"],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cycloidio%2Fstate-updater-on-actions","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cycloidio%2Fstate-updater-on-actions/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cycloidio%2Fstate-updater-on-actions/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cycloidio%2Fstate-updater-on-actions/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cycloidio","download_url":"https://codeload.github.com/cycloidio/state-updater-on-actions/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241150243,"owners_count":19918334,"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":["asynchronous","browser","js-library","nodejs"],"created_at":"2024-11-12T09:06:06.498Z","updated_at":"2025-02-28T12:19:44.160Z","avatar_url":"https://github.com/cycloidio.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# State Updater on Actions\n\nSmall JS module for calling asynchronous actions which require an \"updated state\", in order to be executed.\n\n## Install\n\nYou can install it using _NPM_.\n\n```\nnpm install state-updater-on-actions\n```\n\nUse the `--save` or `--saveDev` parameters accordingly your needs.\n\n## How to use it\n\nYou can import the ES2016 version of this module or an ES5 one. The first one is informed in the _package.json_ file with the property _module_, the second one as _NPM_ has done since the early moments with the property _main_.\n\nIf your system supports ES2016 modules but it isn't automatically checking the _module_ property and you want to use the ES2016 version, then you can import directly the same script indicated by the _module_ property, present in the _pacakge.json_ file.\n\nUsing the ES2016 version is recommended when you are using this module on an application that you have a bundler which fully care of the ES2016 transformations, so the transformation of this one can be optimized together with the transformations that your own sources, avoiding to repeat general code that all the ES5 transpiled files require.\n\nOn the other hand, if you need the ES5 version, you can directly require the module, or even you need it so, you could require the script indicated in the _main_ property of the _pacakge.json_ file.\n\n## Rationale\n\nSmall JS module which allows to call asynchronous actions which are required to have an \"updated state\", which is shared by all them, and when the state isn't up to date, they get, some how, a result which notifies them to update the state previous to be executed again, in order to be executed.\n\nA clear example is a _HTTP API service_ which requires to send an updated authorization token for some of its endpoints, so the actions, which are requests to such endpoints, send the authorization token on each request and the server responds, some how (status HTTP code, specific header, etc), that the request cannot be fulfilled, when the token is outdated, until the token is up to date; the _API_ offers a specific endpoint which allow to renew/refresh the token, in order to update it.\n\nMeanwhile a _auto state_ functionality can be implemented inside of the business logic, this module abstract such part from it, making the logic of this functionality easy to be tested and not to have to repeated each time that's needed.\n\nThis module has an implementation which avoids multiple calls to the _state update action_ (henceforth _updater_) and/or actions, when more than one action has been called and notified with a _\"required updated state\"_, because, meanwhile the _updater_ is executing, the _actions_ are on hold and the ones which were run concurrently, previously any of them was notified with a _\"required updated state\"_, the _updater_ is only called once, and when it finishes successful, the actions are recalled, when they were called previous the notification, or called, when they were on hold. In case that the _updater_ finishes unsuccessful, all the actions calls return the result of the _updater_.\n\nIn the following image, you can see an UML state/activity diagram of the implemented logic by this module.\n\n![activity-state-diagram](docs/activity-state-diagram.png)\n\nBelow, the same diagram but for the _HTTP API service_ commented above.\n\n![activity-state-diagram-http-service](docs/activity-state-diagram-http-service.png)\n\n## API\n\nAs commented in the [rationale](#rationale), the _actions_ must be asynchronous; the _updater_, which itself an action too, must be asynchronous; hence, both, the _actions_ and the _updater_, must be asynchronous functions, in terms that they always return a _Promise_.\n\nOn the other hand, the _updater_ must be determined previously to be used, it's likely the most of the cases and we haven't thought in any use case which may need to change the _updater_ once an instance returned by one of the constructor functions of this module; however, it doesn't mean that there is one, so if you have one which require it, you may want to open an issue to expose it and we'll decide if we should create a new version of the module which allow to do so or not.\n\nThe public source code (i.e. the public API or exported functions, if you want to called it in such way) is documented using the [JSDoc syntax](http://usejsdoc.org), so you can see the [API documentation in the Github pages of this repository under the path _docs/api_](http://cycloidio.github.io/state-updater-on-actions/docs/api).\n\n### Notes about the implementation\n\nThe API of the module, may look a bit weird if you consider that it's a _javascript_ module and we could have done the same with only one function; however we believe, maybe influenced by other programming languages, __explicit is clear than implicit__, so the constructor and one of the methods exposed by the instances returned by the constructors, have a counterpart which do the same but allowing to pass a _context object_ (that's basically that the updater or action will be called with `bind` JS function, using such _context_).\n\nAnother thing to state is that _JS Classes_ haven't been used for the implementation, and you may think that we should/have/may use them, meanwhile that's totally right, we have our reasons for not using them, so we haven't used them because we don't know them, it's a mistake or another thing, it's our choice.\n\nWe have written this section with these 2 clarifications, to make you aware of them, and avoid that you be in a doubt of them and open an issue with the only purpose of changing so.\n\n## Development\n\nA conventional _NodeJS_ development, so you need _Node_ and _NPM_.\n\nAlthough _BabelJS_ is used, you'll see that in the _packgage.json_ file, it's indicated that _node_ should be greater or equal than `9.0.0`, that is because we developed with it and we haven't bother to test it in previous _Node_ versions, so we know that it work on this version and we can ensure that it will probably work in the following newer versions, but we don't know if it works on previous ones, although we think that in some previous ones should.\n\nThe _pacakge.json_ also contains the _scripts_ which are needed when developing this module, they are self explanatory and some of them must be used in a branch which is sent through a PR, as they are required to run without any error in order to be accept and merged. Because you should familiar with _NPM_, and they are pretty clear, we don't list them in this document, basically, go an check _package.json_ file _scripts_ property to find them out.\n\nCurrently, everything must be run manually, we have planned to add a [CI configuration at some point to run the _linter_ and _tests_ on new PRs](https://github.com/cycloidio/state-updater-on-actions/issues/3) and [run the _build_ and _NPM publish_ once a PR is merged into the _master branch_](https://github.com/cycloidio/state-updater-on-actions/issues/5) and [update the Github pages when the master branch gets updated](https://github.com/cycloidio/state-updater-on-actions/issues/6), but for now isn't done.\n\nThe module is developed with ES2016 version, all the source is _src_ including the _tests_, which are the files with the extension _*.spec.js_; however for not excluding possible consumers that requires to use an JS ES5 version, the sources are transpiled, with BabelJS, and made them available in the _dist_ directory; that's what the _NPM script build_ targets does.\n\n### Steps to do/check before merging a PR\n\nMeanwhile there is not automation for some tasks, the following steps must be done/checked before merging a PR to master and just after it is merged.\n\n1. Verify that the following _NPM scrips_ execute without any error: `lint` and `test`.\n2. Update the ES5 version of the module with the _NPM script_ `build`.\n3. Make sure that the _package-lock.json_.\n4. Regenerate the API docs if they have been updated and published them in the GH pages branch.\n5. Once is merged into _master_, bump the _package_ version and publish it in _NPM_.\n\n## License\n\nThe MIT License (MIT)\nCopyright (c) 2018 cycloid.io\nRead the LICENSE file for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcycloidio%2Fstate-updater-on-actions","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcycloidio%2Fstate-updater-on-actions","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcycloidio%2Fstate-updater-on-actions/lists"}