{"id":24989296,"url":"https://github.com/githubnext/tiny-svelte-fsm","last_synced_at":"2025-04-19T18:39:17.198Z","repository":{"id":245931945,"uuid":"819568872","full_name":"githubnext/tiny-svelte-fsm","owner":"githubnext","description":"A minimalistic finite state machine library for Svelte 5","archived":false,"fork":false,"pushed_at":"2024-11-25T16:05:44.000Z","size":157,"stargazers_count":8,"open_issues_count":5,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-29T11:44:05.024Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/githubnext.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":"2024-06-24T19:14:46.000Z","updated_at":"2025-03-18T21:49:03.000Z","dependencies_parsed_at":"2024-06-24T22:37:25.594Z","dependency_job_id":null,"html_url":"https://github.com/githubnext/tiny-svelte-fsm","commit_stats":null,"previous_names":["githubnext/tiny-svelte-fsm"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/githubnext%2Ftiny-svelte-fsm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/githubnext%2Ftiny-svelte-fsm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/githubnext%2Ftiny-svelte-fsm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/githubnext%2Ftiny-svelte-fsm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/githubnext","download_url":"https://codeload.github.com/githubnext/tiny-svelte-fsm/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249766531,"owners_count":21322614,"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":[],"created_at":"2025-02-04T12:56:57.401Z","updated_at":"2025-04-19T18:39:17.176Z","avatar_url":"https://github.com/githubnext.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# tiny-svelte-fsm\n\nA minimalistic finite state machine library for Svelte 5, heavily inspired by [kenkunz/svelte-fsm](https://github.com/kenkunz/svelte-fsm) — but strongly-typed, and powered by Svelte 5 runes.\n\nFSMs are ideal for representing many different kinds of systems and interaction patterns. Stately's [xstate](https://github.com/statelyai/xstate) is an incredibly powerful library with more functionality. This is a much smaller and simpler library, and hopefully it's easy to understand.\n\n\n## Usage\n\n### Installation\n\n`pnpm i @githubnext/tiny-svelte-fsm`\n\n### Introduction\n\nEvery state machine is defined as a collection of _states_ and _events_. To define a state machine, create a list of the valid states and events:\n\n```ts\ntype myStates = 'on' | 'off';\ntype myEvents = 'toggle';\n```\n\nNext, create the actual state machine:\n\n```ts\nconst f = fsm\u003cmyStates, myEvents\u003e('off', {\n\toff: {\n\t\ttoggle: 'on'\n\t},\n\ton: {\n\t\ttoggle: 'off'\n\t}\n});\n```\n\nThe first argument is the initial state. The second argument is an object with one key for each state. Each state then describes which events are valid for that state, and which state that event should lead to.\n\nIn the above example of a simple switch, there are two states (`on` and `off`). The `toggle` event in either state leads to the other state.\n\nYou send events to the fsm using `f.send`. To send the `toggle` event, invoke `f.send('toggle')`.\n\n### Actions\n\nMaybe you want fancier logic for an event handler, or you want to conditionally transition into another state:\n\n```ts\ntype myStates = 'on' | 'off' | 'cooldown';\n\nconst f = fsm\u003cmyStates, myEvents\u003e('off', {\n\toff: {\n\t\ttoggle: () =\u003e {\n\t\t\t// You can prevent state transitions from happening by returning nothing.\n\t\t\tif (isTuesday) {\n\t\t\t\t// switch can only turn on during Tuesdays\n\t\t\t\treturn 'on'\n\t\t\t}\n\t\t}\n\t},\n\ton: {\n\t\ttoggle: (heldMillis: number) =\u003e {\n\t\t\t// You can also dynamically return the next state\n\t\t\t// only turn off if switch is depressed for 3 seconds\n\t\t\t// otherwise enter the `cooldown` state\n\t\t\treturn heldMillis \u003e 3000 ? 'off' : 'cooldown'\n\t\t}\n\t}\n});\n```\n\n### Lifecycle methods\n\nYou can define special handlers that are invoked whenever a state is entered or exited:\n\n```ts\nconst f = fsm\u003cmyStates, myEvents\u003e('off', {\n\toff: {\n\t\ttoggle: 'on'\n\t\t_enter: () =\u003e { console.log('switch is off')}\n\t\t_exit: () =\u003e { console.log('switch is no longer off')}\n\t},\n\ton: {\n\t\ttoggle: 'off'\n\t\t_enter: () =\u003e { console.log('switch is on')}\n\t\t_exit: () =\u003e { console.log('switch is no longer on')}\n\t}\n});\n```\n\nThe lifecycle methods are invoked with an argument containing useful metadata:\n\n- `from`: the name of the event that is being exited\n- `to`: the name of the event that is being entered\n- `event`: the name of the event which has triggered the transition\n- `args`: (optional) you may pass additional metadata when invoking an action with `f.send('theAction', additional, params, as, args)`\n\nThe `_enter` handler for the initial state is called upon creation of the FSM. It is invoked with both the `from` and `event` fields set to `null`.\n\n### Wildcard handlers\n\nThere is one special state used as a fallback: `*`. If you attempt to `send()` an event that is not handled by the current state, it will try to find a handler for that event on the `*` state:\n\n```ts\nconst f = fsm\u003cmyStates, myEvents\u003e('off', {\n\toff: {\n\t\ttoggle: 'on'\n\t},\n\ton: {\n\t\ttoggle: 'off'\n\t}\n\t'*': {\n\t\temergency: 'off'\n\t}\n});\n\n// will always result in the switch turning off.\nf.send('emergency');\n```\n\n### Debouncing\n\nFrequently, you want to transition to another state after some time has elapsed. To do this, use the `debounce` method:\n\n```ts\nf.send('toggle'); // turn on immediately\nf.debounce(5000, 'toggle'); // turn off in 5000 milliseconds\n```\n\nIf you re-invoke debounce with the same event, it will cancel the existing timer and start the countdown over:\n\n```ts\n// schedule a toggle in five seconds\nf.debounce(5000, 'toggle');\n\n// Cancels the original timer, and starts a fresh one:\nf.debounce(5000, 'toggle'); \n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgithubnext%2Ftiny-svelte-fsm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgithubnext%2Ftiny-svelte-fsm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgithubnext%2Ftiny-svelte-fsm/lists"}