{"id":14156627,"url":"https://github.com/eram/typescript-fsm","last_synced_at":"2025-05-15T14:04:08.243Z","repository":{"id":21363603,"uuid":"92419711","full_name":"eram/typescript-fsm","owner":"eram","description":"TS-FSM is a strongly typed finite state machine for TypeScript that is using async operations. Library uses generics to take the user states and events. Zero dependencies!","archived":false,"fork":false,"pushed_at":"2025-04-10T11:21:58.000Z","size":282,"stargazers_count":202,"open_issues_count":1,"forks_count":21,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-15T03:49:11.272Z","etag":null,"topics":["fsm","generics","no-dependencies","promise","state-machine","typescript"],"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/eram.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-05-25T15:54:04.000Z","updated_at":"2025-04-10T11:21:58.000Z","dependencies_parsed_at":"2023-10-24T16:41:15.439Z","dependency_job_id":"d4a98894-4eea-4e62-b0da-9850d67211e0","html_url":"https://github.com/eram/typescript-fsm","commit_stats":null,"previous_names":["eram/typescript-fsm"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eram%2Ftypescript-fsm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eram%2Ftypescript-fsm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eram%2Ftypescript-fsm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eram%2Ftypescript-fsm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eram","download_url":"https://codeload.github.com/eram/typescript-fsm/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249003941,"owners_count":21196794,"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":["fsm","generics","no-dependencies","promise","state-machine","typescript"],"created_at":"2024-08-17T08:07:25.479Z","updated_at":"2025-04-15T03:49:16.857Z","avatar_url":"https://github.com/eram.png","language":"TypeScript","funding_links":[],"categories":["typescript"],"sub_categories":[],"readme":"# TypeScript State Machine (typescript-fsm)\n\n[![Build Status](https://app.travis-ci.com/eram/typescript-fsm.svg?branch=master)](https://app.travis-ci.com/github/eram/typescript-fsm)\n[![npm package](https://img.shields.io/npm/v/typescript-fsm.svg?logo=nodedotjs\u0026color=00a400)](https://www.npmjs.com/package/typescript-fsm)\n\u003cimg src=\"https://img.shields.io/badge/winter-is%20coming-5593c8\" alt=\"It's already here!\" height=\"20\"/\u003e\n\nFinite state machines are useful for modeling complicated flows and keeping track of state. TS-FSM is a strongly typed finite state machine for TypeScript that is using promises for async operations.\nI'm using this state-machine as a simple replacement for Redux in some ReactJs based apps. Example [here](https://github.com/eram/tensorflow-stack-ts/blob/master/client/src/components/server-status-card/StatusCardModel.ts)\n\n## Features\n\n- TypeScript native (compiles to ES6)\n- Only 1 KB (minified) and zero dependencies!!!\n- Hooks after state change - - async or sync callbacks\n- Promises are used for async transition completion\n- Generics for states and events types\n- Simple tabular state machine definition\n- Use with NodeJS or JS client\n\n## Get it\n\n  ```script\n  git clone https://github.com/eram/typescript-fsm.git\n  cd typescript-fsm\n  npm install\n  npm test\n  ```\n\n## Use it\n\n  ```script\n  npm install typescript-fsm\n ```\n\n## Basic Example\n\nI'm modeling a \"door\" here. One can open the door, close it or break it. Each action is done async: when you open it goes into opening state and then resolved to opened state etc. Once broken, it reaches a final state.\n\n\u003cimg src=\"https://mermaid.ink/svg/c3RhdGVEaWFncmFtLXYyCiAgICBbKl0gLS0+IENsb3NlZAogICAgQ2xvc2VkIC0tPiBPcGVuaW5nIDogT3BlbgogICAgT3BlbmluZyAtLT4gT3BlbmVkIDogb3BlbkNvbXBsZXRlCiAgICBPcGVuZWQgLS0+IENsb3NpbmcgOiBDbG9zZQogICAgQ2xvc2luZyAtLT4gQ2xvc2VkIDogY2xvc2VDb21wbGV0ZQogICAgQ2xvc2VkIC0tPiBCcm9rZW4gOiBCcmVhawogICAgT3BlbmluZyAtLT4gQnJva2VuIDogQnJlYWsKICAgIE9wZW5lZCAtLT4gQnJva2VuIDogQnJlYWsKICAgIENsb3NpbmcgLS0+IEJyb2tlbiA6IEJyZWFrCiAgICBCcm9rZW4gLS0+IFsqXQo=?bgColor=!white\" alt=\"Door state machine\" height=\"500\" /\u003e\n\nLet's code it in Typescript! Note that the same code can be run in Javascript, just remove the generics.\n\n```typescript\nimport { t, StateMachine } from \"typescript-fsm\";\n\n// these are the states and events for the door\nenum States { closing = 0, closed, opening, opened, broken };\nenum Events { open = 100, openComplete, close, closeComplete, break };\n\n// lets define the transitions that will govern the state-machine\nconst transitions = [\n  /* fromState        event                 toState         callback */\n  t(States.closed,    Events.open,        States.opening, onOpen),\n  t(States.opening,   Events.openComplete,  States.opened,  justLog),\n  t(States.opened,    Events.close,         States.closing, onClose),\n  t(States.closing,   Events.closeComplete, States.closed,  justLog),\n  t(States.closed,    Events.break,         States.broken,  justLog),\n  t(States.opened,    Events.break,         States.broken,  justLog),\n  t(States.opening,   Events.break,         States.broken,  justLog),\n  t(States.closing,   Events.break,         States.broken,  justLog),\n];\n\n// initialize the state machine\nconst door = new StateMachine\u003cStates, Events\u003e(\n   States.closed,   // initial state\n   transitions,     // array of transitions \n);\n\n// transition callbacks - async functions\nasync function onOpen() {\n    console.log(\"onOpen...\");\n    return door.dispatch(Events.openComplete);\n}\n\nasync function onClose() {\n    console.log(\"onClose...\");\n    return door.dispatch(Events.closeComplete);\n}\n\n// synchronous callbacks are also ok\nfunction justLog() { \n    console.log(`${States[door.getState()]}`);\n}\n\n// we are ready for action - run a few state-machine steps...\nnew Promise(async (resolve) =\u003e {\n\n    // open the door and wait for it to be opened\n    await door.dispatch(Events.open);\n    door.getState(); // =\u003e States.opened\n\n    // check if the door can be closed\n    door.can(Events.close); // =\u003e true\n\n    // break the door async\n    door.dispatch(Events.break).then(() =\u003e {\n        // did we get to a finite state?\n        door.isFinal(); // =\u003e true \n    });\n\n    // door is now broken. It cannot be closed...\n    try {\n        await door.dispatch(Events.close);\n        assert(\"should not get here!\");\n    } catch (e) {\n        // we're good\n    }\n\n    // let the async complete\n    setTimeout(resolve, 10);\n});\n\n```\n\n## Another example\n\nCheck out [the test code](https://github.com/eram/typescript-fsm/blob/master/src/__test__/stateMachine.test.ts) - a class that implements a state machine with method binding, method params and more transitions. 100% coverage here!\n\n## Beautiful :-)\n\nComments and suggestions are [welcome](https://github.com/eram/typescript-fsm/issues/new).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feram%2Ftypescript-fsm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feram%2Ftypescript-fsm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feram%2Ftypescript-fsm/lists"}