{"id":26711654,"url":"https://github.com/rfieve/finite-state-machine","last_synced_at":"2025-03-27T10:30:02.576Z","repository":{"id":196327650,"uuid":"695272710","full_name":"rfieve/finite-state-machine","owner":"rfieve","description":"A TypeScript library to work with finite state machines.","archived":false,"fork":false,"pushed_at":"2024-07-30T13:33:44.000Z","size":411,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-11T05:17:16.847Z","etag":null,"topics":["finite-state-machine","typescript","utility-library"],"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/rfieve.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-09-22T18:31:27.000Z","updated_at":"2024-07-30T13:33:47.000Z","dependencies_parsed_at":null,"dependency_job_id":"55bc138f-1fb8-4add-92fa-a4701f31e944","html_url":"https://github.com/rfieve/finite-state-machine","commit_stats":null,"previous_names":["rfieve/finite-state-machine"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rfieve%2Ffinite-state-machine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rfieve%2Ffinite-state-machine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rfieve%2Ffinite-state-machine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rfieve%2Ffinite-state-machine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rfieve","download_url":"https://codeload.github.com/rfieve/finite-state-machine/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245826554,"owners_count":20678812,"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":["finite-state-machine","typescript","utility-library"],"created_at":"2025-03-27T10:30:02.055Z","updated_at":"2025-03-27T10:30:02.560Z","avatar_url":"https://github.com/rfieve.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# finite-state-machine\n\nA TypeScript library to work with finite-state machines.\n\n## Table of Content\n\n-   [finite-state-machine](#finite-state-machine)\n    -   [Table of Content](#table-of-content)\n    -   [Installation](#installation)\n    -   [Options](#options)\n    -   [Usage](#usage)\n\n## Installation\n\n```sh\nyarn add @romainfieve/finite-state-machine\n```\n\nor\n\n```sh\nnpm install @romainfieve/finite-state-machine\n```\n\n## Options\n\n```typescript\n/**\n * @param {MachineDefinition\u003cStates, Data, Context\u003e} machineDefinition - The definition of the state machine.\n * @param {States} machineDefinition.initialState - The initial state of the state machine.\n * @param {Partial\u003cData\u003e} [machineDefinition.initialData={}] - The initial machine data.\n * @param {Context} [machineDefinition.context={}] - The machine context.\n * @param {Transitions\u003cStates, Data, Context\u003e} machineDefinition.transitions - The transition functions between states.\n * @param {Setters\u003cStates, Data, Context\u003e} machineDefinition.setters - The conversion functions for input data at each state.\n * @param {Runners\u003cStates, Data, Context\u003e} machineDefinition.runners - The runners for each state.\n * @param {Effects\u003cStates, Data, Context\u003e} machineDefinition.effects - The side effects to trigger at each state.\n * @param onEnd - The side effect to trigger when the machine reaches the end.\n * @param isImmutable - Should the machine return a new instance at every state change.\n */\n```\n\n## Usage\n\n```typescript\nconst isAdult = (age?: number, legalAge = 18) =\u003e !!age \u0026\u0026 age \u003e= legalAge\n\nenum States {\n    Age = 'age',\n    FirstName = 'firstName',\n    IsAllowed = 'isAllowed',\n    LastName = 'lastName',\n}\n\ntype Data = {\n    age?: number\n    firstName?: string\n    isAllowed?: boolean\n    lastName?: string\n}\n\ntype Context = {\n    legalAge: number\n}\n\ntype Machine = FiniteStateMachine\u003cStates, Data, Context\u003e\n\nconst context = { legalAge: 18 }\nconst onEnd = ({ data, context }: Machine) =\u003e console.log(data, context)\nconst immutable = true\n\nconst transitions: Transitions\u003cStates, Data, Context\u003e = {\n    age: ({ data: { age }, constext: { legalAge } }) =\u003e\n        isAdult(age, legalAge) ? States.FirstName : States.IsAllowed,\n    isAllowed: ({ data: { isAllowed } }) =\u003e (isAllowed ? States.FirstName : undefined),\n    firstName: (_machine) =\u003e States.LastName,\n    lastName: () =\u003e undefined,\n}\n\nconst effects: Effects\u003cStates, Data, Context\u003e = {\n    age: ({ data: { age }, constext: { legalAge } }) =\u003e console.log(age, legalAge),\n    firstName: ({ firstName }, _context) =\u003e console.log(firstName),\n    lastName: (data, context) =\u003e console.log(data, context),\n}\n\nconst baseMachineDef = { context, initialState: States.Age, initialData: {}, transitions, effects }\n\n// With setters\nconst setters: Setters\u003cStates, Data, Context\u003e = {\n    age: (age: number, _data, { legalAge }) =\u003e ({ isAllowed: isAdult(age, legalAge), age }),\n    isAllowed: (isAllowed: boolean, _data, _context) =\u003e ({ isAllowed }),\n    firstName: (firstName: string, _data, _context) =\u003e ({ firstName }),\n    lastName: (lastName: string, _data, _context) =\u003e ({ lastName }),\n}\nconst fsm = new FiniteStateMachine({ ...baseMachineDef, setters }, onEnd, immutable)\n    .set(18) // provide the value directly\n    .set((_machine) =\u003e 'John') // or, set receives the machine as first arg when providing a function\n    .set('Doe')\n//\n\n// With runners\nconst runners: Runners\u003cStates, Data, Context\u003e = {\n    age: (_data, _context) =\u003e ({ isAllowed: isAdult(18), age: 18 }),\n    isAllowed: (_data, _context) =\u003e new Promise((resolve) =\u003e resolve({ isAllowed: true })),\n    firstName: (_data, _context) =\u003e new Promise((resolve) =\u003e resolve({ firstName: 'John' })),\n    lastName: (_data, _context) =\u003e new Promise((resolve) =\u003e resolve({ lastName: 'Doe' })),\n}\nconst fsm = await new FiniteStateMachine({ ...baseMachineDef, runners }, onEnd, immutable).run()\n//\n// 18, true (age effect)\n// 'John' (firstName effect)\n// {...data}, {...context} (lastName effect)\n// {...data}, {...context} (onEnd)\nconsole.log(fsm.state) // 'lastName'\nconsole.log(fsm.data) // { lastName: 'Doe', firstName: 'John', age: 18, isAllowed: true }\n```\n\n---\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frfieve%2Ffinite-state-machine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frfieve%2Ffinite-state-machine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frfieve%2Ffinite-state-machine/lists"}