{"id":25014369,"url":"https://github.com/ryunen344/automuttonrecipe","last_synced_at":"2025-04-24T00:48:12.606Z","repository":{"id":274877444,"uuid":"918103212","full_name":"RyuNen344/AutoMuttonRecipe","owner":"RyuNen344","description":"AutoMuttonRecipe is a type-safe DSL and pure Kotlin Finite State Machine (FSM) implementation, inspired by Tinder/StateMachine.","archived":false,"fork":false,"pushed_at":"2025-04-18T04:21:05.000Z","size":291,"stargazers_count":8,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-04-18T17:20:10.376Z","etag":null,"topics":["kotlin","kotlin-multiplatform","statemachine"],"latest_commit_sha":null,"homepage":"https://ryunen344.github.io/AutoMuttonRecipe/","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RyuNen344.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","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":"2025-01-17T08:59:06.000Z","updated_at":"2025-04-18T04:20:49.000Z","dependencies_parsed_at":"2025-02-26T21:36:11.316Z","dependency_job_id":null,"html_url":"https://github.com/RyuNen344/AutoMuttonRecipe","commit_stats":null,"previous_names":["ryunen344/automuttonrecipe"],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RyuNen344%2FAutoMuttonRecipe","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RyuNen344%2FAutoMuttonRecipe/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RyuNen344%2FAutoMuttonRecipe/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RyuNen344%2FAutoMuttonRecipe/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RyuNen344","download_url":"https://codeload.github.com/RyuNen344/AutoMuttonRecipe/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250540955,"owners_count":21447426,"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":["kotlin","kotlin-multiplatform","statemachine"],"created_at":"2025-02-05T07:19:37.631Z","updated_at":"2025-04-24T00:48:12.595Z","avatar_url":"https://github.com/RyuNen344.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"AutoMuttonRecipe\n====\n\n**AutoMuttonRecipe** is a type-safe DSL and pure Kotlin Finite State Machine (FSM) implementation, inspired by [Tinder/StateMachine](https://github.com/Tinder/StateMachine).\n\n## Features\n### TypeSafe DSL\nAutoMuttonRecipe provides a type-safe DSL for defining state transitions and effects.\nIf you define an invalid state transition, the compiler will raise an error, ensuring robust state management.\n\n### Atomic State Transition\nAutoMuttonRecipe uses `kotlinx.coroutines.flow.StateFlow` to manage states, guaranteeing atomic state transitions.\nIf actions are dispatched in unexpected states, they will be ignored, preventing unintended behavior.\n\n### Lightweight and Supports Multiplatform\nAutoMuttonRecipe is a lightweight library designed for multiplatform projects.\n\n## Installation\n### Maven\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003eio.github.ryunen344.mutton\u003c/groupId\u003e\n  \u003cartifactId\u003eauto-mutton-recipe\u003c/artifactId\u003e\n  \u003cversion\u003e$version\u003c/version\u003e\n\u003c/dependency\u003e\n\u003cdependency\u003e\n  \u003cgroupId\u003eio.github.ryunen344.mutton\u003c/groupId\u003e\n  \u003cartifactId\u003eauto-mutton-recipe-compose\u003c/artifactId\u003e\n  \u003cversion\u003e$version\u003c/version\u003e\n\u003c/dependency\u003e\n\u003cdependency\u003e\n  \u003cgroupId\u003eio.github.ryunen344.mutton\u003c/groupId\u003e\n  \u003cartifactId\u003eauto-mutton-recipe-savedstate\u003c/artifactId\u003e\n  \u003cversion\u003e$version\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n### Gradle\n```gradle\nimplementation 'io.github.ryunen344.mutton:auto-mutton-recipe:$version'\nimplementation 'io.github.ryunen344.mutton:auto-mutton-recipe-compose:$version'\nimplementation 'io.github.ryunen344.mutton:auto-mutton-recipe-savedstate:$version'\n```\n\n## How to use\n### Step 1: Define Nodes\n```kotlin\nsealed class ExampleState : State() {\n    data object Idle : ExampleState()\n    data object Loading : ExampleState()\n    data class OK(val data: String) : ExampleState()\n    data class NG(val throwable: Throwable?) : ExampleState()\n}\n\nsealed class ExampleAction : Action() {\n    data object Load : ExampleAction()\n    data class Success(val data: String) : ExampleAction()\n    data class Failure(val throwable: Throwable?) : ExampleAction()\n    data object Reset : ExampleAction()\n}\n\nsealed class ExampleEffect : Effect() {\n    data object FetchRemoteData : ExampleEffect()\n}\n```\n\n### Step 2: Define Transitions with DSL\n```kotlin\nval exampleGraph = Graph\u003cExampleState, ExampleAction, ExampleEffect\u003e {\n    // when state is Idle\n    state\u003cExampleState.Idle\u003e {\n        // given action is Load\n        action\u003cExampleAction.Load\u003e { prev, action -\u003e\n            // then transition to Loading state and trigger FetchRemoteData effect\n            transition(ExampleState.Loading, ExampleEffect.FetchRemoteData)\n        }\n    }\n    state\u003cExampleState.Loading\u003e {\n        action\u003cExampleAction.Success\u003e { prev, action -\u003e\n            transition(ExampleState.OK(action.data))\n        }\n        action\u003cExampleAction.Failure\u003e { prev, action -\u003e\n            transition(ExampleState.NG(action.throwable))\n        }\n    }\n    state\u003cExampleState.NG\u003e {\n        action\u003cExampleAction.Reset\u003e { prev, action -\u003e\n            transition(ExampleState.Idle)\n        }\n    }\n}\n\nval exampleEffectHandle = EffectHandle\u003cExampleState, ExampleAction, ExampleEffect\u003e { effect, prev, next, dispatch -\u003e\n    when (effect) {\n        ExampleEffect.FetchRemoteData -\u003e {\n            runCatching {\n                // simulate fetching remote data\n            }.onSuccess {\n                dispatch(ExampleAction.Success(\"Remote data\"))\n            }.onFailure {\n                if (it !is CancellationException) {\n                    dispatch(ExampleAction.Failure(it))\n                } else {\n                    throw it\n                }\n            }\n        }\n    }\n}\n```\n\n### Step 3: Create StateMachine and Collect States\n```kotlin\nclass ExampleStateMachine(context: CoroutineContext) : StateMachine\u003cExampleState, ExampleAction, ExampleEffect\u003e(\n    initialState = ExampleState.Idle,\n    graph = exampleGraph,\n    effectHandle = exampleEffectHandle,\n    context = context,\n)\n\nfun main() {\n    val coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)\n    val stateMachine = ExampleStateMachine(coroutineScope.coroutineContext)\n\n    coroutineScope.launch {\n        stateMachine.state.collect {\n            // Handle state changes here\n        }\n    }\n\n    // Dispatch actions\n    stateMachine.dispatch(ExampleAction.Load)\n}\n```\n\n\u003e [!TIP]\n\u003e You can use `SavedStateMachine` with `auto-mutton-recipe-savedstate` module to save and restore the state machine's state.\n\n## License\n```text\nCopyright (C) 2025 RyuNen344\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fryunen344%2Fautomuttonrecipe","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fryunen344%2Fautomuttonrecipe","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fryunen344%2Fautomuttonrecipe/lists"}