{"id":47712073,"url":"https://github.com/aim4code/nanoserviceflow-ui","last_synced_at":"2026-04-02T18:36:49.733Z","repository":{"id":347435296,"uuid":"1193540112","full_name":"aim4code/nanoserviceflow-ui","owner":"aim4code","description":"A reactive, event-driven UI framework for Unity built on NanoServiceFlow. It features hierarchy-based auto-routing, async UniTask transitions, and multi-canvas support. Achieve true separation of UI state, logic, and views with zero-friction workflows for designers.","archived":false,"fork":false,"pushed_at":"2026-03-27T22:14:49.000Z","size":21,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-28T04:57:23.470Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aim4code.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-27T10:35:22.000Z","updated_at":"2026-03-27T14:21:46.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/aim4code/nanoserviceflow-ui","commit_stats":null,"previous_names":["aim4code/nanoserviceflow-ui"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/aim4code/nanoserviceflow-ui","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aim4code%2Fnanoserviceflow-ui","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aim4code%2Fnanoserviceflow-ui/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aim4code%2Fnanoserviceflow-ui/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aim4code%2Fnanoserviceflow-ui/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aim4code","download_url":"https://codeload.github.com/aim4code/nanoserviceflow-ui/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aim4code%2Fnanoserviceflow-ui/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31313021,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-02T12:59:32.332Z","status":"ssl_error","status_checked_at":"2026-04-02T12:54:48.875Z","response_time":89,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":"2026-04-02T18:36:49.111Z","updated_at":"2026-04-02T18:36:49.719Z","avatar_url":"https://github.com/aim4code.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# NanoServiceFlow.UI\n\n[![CI](https://github.com/aim4code/nanoserviceflow-ui/actions/workflows/ci.yml/badge.svg)](https://github.com/aim4code/nanoserviceflow-ui/actions)\n[![openupm](https://img.shields.io/npm/v/com.aim4code.nanoserviceflow.ui?label=openupm\u0026registry_uri=https://package.openupm.com)](https://openupm.com/packages/com.aim4code.nanoserviceflow.ui/)\n[![](https://img.shields.io/badge/Unity-2022.3+-57b9d3.svg?style=flat\u0026logo=unity)](https://unity.com/)\n![last-commit](https://img.shields.io/github/last-commit/aim4code/nanoserviceflow)\n![open-issues](https://img.shields.io/github/issues/aim4code/nanoserviceflow)\n\n\u003e **A reactive, event-driven UI framework for Unity built on NanoServiceFlow. It features hierarchy-based auto-routing, async UniTask transitions, and multi-canvas support.**\n\nNanoServiceFlow.UI extends the core event-driven architecture to the presentation layer. It completely decouples your UI visuals (MonoBehaviours) from your UI logic (Services) and UI data (State), providing a blazing-fast, GC-friendly navigation system.\n\n\u003e [!NOTE]\n\u003e **A Note on Dependencies:** Unlike the core NanoServiceFlow package which is strictly zero-dependency, this UI framework relies on **[UniTask](https://github.com/Cysharp/UniTask)**. This is a deliberate choice to ensure high-performance, zero-allocation asynchronous visual transitions without relying on Unity's legacy Coroutines.\n\n## Key Features\n\n* **Hierarchy-Based Auto-Discovery:** Designers build UI naturally in the Unity Canvas. `UIPanel` components automatically look up their parent hierarchy to figure out which Canvas and Layer they belong to and register themselves with the global router.\n* **Keyed Multi-System Support:** Easily support additive scenes or multiple Canvases (e.g., `GlobalUI`, `GameHUD`, `WorldSpaceUI`) with isolated navigation stacks.\n* **Async/Await Workflow:** Fully integrated with `UniTask`. Safely await complex UI transitions (like screen fades) before proceeding with game logic. Input is safely guarded during animations.\n* **Designer-Friendly \u0026 Zero Magic Strings:** Designers never touch C# code. Routing configurations are managed in a centralized `UIRoutingDatabase` ScriptableObject. Components like `UIPanel` use custom Inspector Dropdowns to select `PanelId`, `Location`, and `RootKey`, completely eliminating typo-prone magic strings!\n\n## Installation\n\n### Option 1: Install via OpenUPM (Recommended)\n\nThe package is available on the [OpenUPM](https://openupm.com/) registry. The easiest way to install it is via the `openupm-cli`:\n\n```bash\nopenupm add com.aim4code.nanoserviceflow.ui\n```\n\nAlternatively, you can manually add the scoped registry to your `Packages/manifest.json`:\n\n```json\n\"scopedRegistries\": [\n  {\n    \"name\": \"package.openupm.com\",\n    \"url\": \"[https://package.openupm.com](https://package.openupm.com)\",\n    \"scopes\": [\n      \"com.aim4code\",\n      \"com.cysharp\"\n    ]\n  }\n],\n\"dependencies\": {\n  \"com.aim4code.nanoserviceflow.ui\": \"0.1.0\"\n}\n```\n\n### Option 2: Install via Git URL\n\nYou can also install the package directly from GitHub. Add the following dependency to your `Packages/manifest.json`:\n\n```json\n\"dependencies\": {\n  \"com.aim4code.nanoserviceflow\": \"[https://github.com/aim4code/nanoserviceflow.git#v0.2.1](https://github.com/aim4code/nanoserviceflow.git#v0.2.1)\",\n  \"com.aim4code.nanoserviceflow.ui\": \"[https://github.com/aim4code/nanoserviceflow-ui.git#v0.1.0](https://github.com/aim4code/nanoserviceflow-ui.git#v0.1.0)\",\n  \"com.cysharp.unitask\": \"[https://github.com/Cysharp/UniTask.git?path=src/UniTask/Assets/Plugins/UniTask](https://github.com/Cysharp/UniTask.git?path=src/UniTask/Assets/Plugins/UniTask)\"\n}\n```\n\n\u003e [!IMPORTANT]\n\u003e **Version Determinism:** Notice the `#v0.1.0` at the end of the URL. If you omit the version tag, Unity will resolve the dependency using the latest commit on the default branch at the time of checkout. As the branch updates, this can lead to team members having different versions of the package installed, breaking version determinism. Always lock your Git dependencies to a specific release tag.\n\n## Quick Start\n\n### 1. Define Pure Data (State) \u0026 Services\n\nCreate a concrete State for your specific UI Canvas, and a Provider to attach to the root GameObject.\n\n```csharp\nusing Aim4code.NanoServiceFlow;\nusing Aim4code.NanoServiceFlow.UI;\n\n// 1. The Data\npublic class MainUIState : UIRootState { }\n\n// 2. The Logic\npublic class MainUIService : UIServiceBase\u003cMainUIState\u003e \n{\n    public MainUIService(MainUIState state) : base(state, \"MainUI\") { }\n}\n\n// 3. The Unity Component (Attach to your Canvas)\npublic class MainUIProvider : UIRootProvider\n{\n    // Note: RootKey is configured via the Inspector Dropdown on the UIRootProvider component.\n    public override UIRootState GetState() =\u003e ServiceLocator.Get\u003cMainUIState\u003e();\n}\n```\n\n### 2. Setup the View (Unity Hierarchy)\n\nDesigners build out the canvas hierarchy in the Unity Editor using the provided base components. They select their routing keys from Dropdowns populated by your central `UIRoutingDatabase`. The framework discovers them automatically:\n\n* **Canvas** `[MainUIProvider: RootKey Dropdown=\"MainUI\"]`\n  * **MainStack GameObject** `[UILocationProvider: LocationName Dropdown=\"MainStack\"]`\n    * **MainMenu Panel** `[UIPanel: PanelId Dropdown=\"MainMenu\"]`\n    * **Settings Panel** `[UIPanel: PanelId Dropdown=\"SettingsMenu\"]`\n  * **Overlays GameObject** `[UILocationProvider: LocationName Dropdown=\"Overlays\"]`\n    * **Loading Screen** `[UIPanel: PanelId Dropdown=\"LoadingScreen\", RegisterWithRouter=false]`\n\n\u003e [!TIP]\n\u003e You can easily detach a `UIPanel` from the global router by unchecking the `RegisterWithRouter` toggle in the inspector. This is perfect for local reactive UI elements that only listen to state!\n\n### 3. Bootstrap the Architecture\n\nRegister everything centrally when your application boots.\n\n```csharp\nusing UnityEngine;\nusing Aim4code.NanoServiceFlow;\nusing Aim4code.NanoServiceFlow.UI;\n\npublic class AppBootstrapper : MonoBehaviour \n{\n    private void Awake() \n    {\n        // 1. Core routing\n        ServiceLocator.RegisterService\u003cUIRouterService\u003e();\n\n        // 2. Your specific UI\n        ServiceLocator.RegisterState(new MainUIState());\n        ServiceLocator.RegisterService\u003cMainUIService\u003e();\n\n        // 3. Start the Engine\n        ServiceLocator.InitializeAll();\n    }\n}\n```\n\n### 4. Dispatch Navigation Actions\n\nAny system, game flow, or UI button can now open a screen by dispatching a simple intent. The `UIRouterService` will automatically figure out which canvas and stack it belongs to.\n\n```csharp\nusing Aim4code.NanoServiceFlow;\nusing Aim4code.NanoServiceFlow.UI;\n\n// Push to a stack\nServiceLocator.Dispatch(new OpenScreenAction(\"SettingsMenu\"));\n\n// Toggle an independent overlay\nServiceLocator.Dispatch(new ToggleOverlayAction(\"MainUI\", \"LoadingScreen\", true));\n```\n\n## Architectural Philosophy\n\nNanoServiceFlow.UI diverges from traditional MVC models by embracing a **Unidirectional Data Flow**. Views (Panels) cannot mutate the state directly; they only observe the `ActivePanels` hashset. State mutations happen entirely via pure struct `Actions` intercepted by `[Reducer]` methods in the Service layer. The `UIRouterService` acts as a Mediator, translating generic screen requests into exact system coordinates, guaranteeing race-condition-free, highly predictable user interfaces.\n\n## License\n\nMIT License. See `LICENSE.md` for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faim4code%2Fnanoserviceflow-ui","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faim4code%2Fnanoserviceflow-ui","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faim4code%2Fnanoserviceflow-ui/lists"}