{"id":15066905,"url":"https://github.com/pfriedrix/FlowKit","last_synced_at":"2025-11-01T09:30:27.176Z","repository":{"id":255373946,"uuid":"849407033","full_name":"pfriedrix/FlowKit","owner":"pfriedrix","description":"A lightweight Swift framework implementing the Redux pattern for iOS, providing centralized state management, reducers, effects, and seamless SwiftUI integration.","archived":false,"fork":false,"pushed_at":"2024-11-14T20:31:04.000Z","size":57,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-20T06:14:06.753Z","etag":null,"topics":["architecture","lightweight","reducer","redux-persist","swift","swiftui","tca"],"latest_commit_sha":null,"homepage":"","language":"Swift","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/pfriedrix.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-08-29T14:39:10.000Z","updated_at":"2024-11-14T20:34:06.000Z","dependencies_parsed_at":"2024-08-29T16:24:15.827Z","dependency_job_id":"591f1ee8-7cb3-456f-ac35-02976736ae77","html_url":"https://github.com/pfriedrix/FlowKit","commit_stats":null,"previous_names":["pfriedrix/redux","pfriedrix/flowkit"],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pfriedrix%2FFlowKit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pfriedrix%2FFlowKit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pfriedrix%2FFlowKit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pfriedrix%2FFlowKit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pfriedrix","download_url":"https://codeload.github.com/pfriedrix/FlowKit/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239275540,"owners_count":19611938,"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":["architecture","lightweight","reducer","redux-persist","swift","swiftui","tca"],"created_at":"2024-09-25T01:13:47.195Z","updated_at":"2025-11-01T09:30:27.118Z","avatar_url":"https://github.com/pfriedrix.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"---\n\n# FlowKit\n\nFlowKit is a Swift-based library that implements a Unidirectional Data Flow (UDF) architecture, designed to simplify state management within applications. It centralizes application state and logic, making your app's behavior more predictable, testable, and maintainable.\n\n## Table of Contents\n\n1. [Introduction](#introduction)\n2. [Installation](#installation)\n3. [Architecture Overview](#architecture-overview)\n4. [Usage](#usage)\n   - [Store](#store)\n   - [Reducer](#reducer)\n   - [Effect](#effect)\n   - [Storage](#storage)\n   - [Persistable](#persistable)\n5. [License](#license)\n\n## Introduction\n\nInspired by the UDF architecture pattern, FlowKit provides a structured approach to managing state in Swift applications. With FlowKit, developers can centralize state in a single `Store`, apply updates through `Reducers`, and handle asynchronous tasks with `Effects`. This architecture provides a straightforward flow that scales easily and aids in debugging by making application state predictable and consistent.\n\n## Installation\n\nTo install FlowKit via Swift Package Manager (SPM):\n\n1. Open your Xcode project.\n2. Go to `File` \u003e `Add Packages...`.\n3. Enter the following URL in the search bar:\n   ```\n   https://github.com/pfriedrix/FlowKit\n   ```\n4. Select the FlowKit package and choose the desired version.\n5. Click `Add Package`.\n\nThis will add FlowKit to your project, enabling state management using UDF principles in Swift.\n\n## Architecture Overview\n\nFlowKit follows a unidirectional data flow to make state changes predictable and easy to trace. The main components are:\n\n- **Store**: Holds the application’s state and allows updates via dispatched actions.\n- **Action**: Describes events that occur, like user interactions or external data updates.\n- **Reducer**: Pure functions that specify how the state transitions in response to actions.\n- **Effect**: Manages side effects, such as network requests and asynchronous operations.\n- **Persistable**: Extends `Storable` by automatically handling state persistence and restoration.\n\n## Usage\n\n### Store\n\nThe `Store` is the central component that maintains the application’s state. It initializes with an initial state and a reducer that specifies how actions change the state.\n\n```swift\nlet store = Store(initialState: AppReducer.State(), reducer: AppReducer())\n```\n\n### Reducer\n\nA `Reducer` defines how state changes in response to actions. It takes the current state and an action, applies the necessary changes, and returns any `Effects` for asynchronous tasks.\n\nExample:\n\n```swift\nfunc appReducer(state: inout State, action: Action) -\u003e Effect\u003cAction\u003e {\n    switch action {\n    case .increment:\n        state.count += 1  \n        return .none\n    }\n}\n```\n\n### Effect\n\n`Effect` is used to handle side effects, such as network requests and other asynchronous operations. Effects can send actions or run async tasks that dispatch actions upon completion.\n\nExample of using an effect to handle async tasks:\n\n```swift\nfunc reduce(into state: inout State, action: Action) -\u003e Effect\u003cAction\u003e {\n    switch action {\n    case .fetchData:\n        return .run { send in\n            let data = await fetchData()\n            await send(.updateData(data))\n        }\n    case .updateData(let newData):\n        state.data = newData\n        return .none\n    }\n}\n```\n\n`Effect` can also send direct actions without async tasks:\n\n```swift\nfunc reduce(into state: inout State, action: Action) -\u003e Effect\u003cAction\u003e {\n    switch action {\n    case .fetchData:\n        return .send(.updateData(\"Update Data\"))\n    case .updateData(let newData):\n        state.data = newData\n        return .none\n    }\n}\n```\n\n### Storage\n\nFlowKit provides the `Storable` protocol for persisting state between app sessions. Conforming to `Storable` allows state to be saved and loaded automatically. Any state conforming to `Storable` can be saved to and restored from persistent storage, such as `UserDefaults`.\n\nTo conform to `Storable`, implement these two methods:\n\n- `save()`: Saves the current state.\n- `load()`: Restores the saved state.\n\nExample:\n\n```swift\nstruct State: Storable {\n    var count: Int\n\n    func save() {\n        // Save the state\n    }\n\n    static func load() -\u003e State? {\n        // Load and return the saved state\n    }\n}\n```\n\n### Persistable\n\n`Persistable` builds on `Storable` to streamline automatic state persistence in `UserDefaults`. By conforming to `Persistable`, state types are automatically assigned a unique key based on their type name, and gain default implementations for saving and loading to `UserDefaults`. This removes the need to manually implement `save()` and `load()`.\n\nTo use `Persistable`, simply conform your state to `Persistable` and call the provided `save()` and `load()` methods.\n\nExample:\n\n```swift\nstruct AppState: Persistable, Equatable {\n    var count: Int\n    var isLoggedIn: Bool\n}\n\n// Saving state\nlet state = AppState(count: 5, isLoggedIn: true)\nstate.save()\n\n// Loading state\nif let restoredState = AppState.load() {\n    print(\"Restored state: \\(restoredState)\")\n}\n```\n\nUsing `Persistable` provides a convenient way to persist state with minimal setup, as it requires only `Codable` conformance for encoding and decoding.\n\n## License\n\nThis project is licensed under the MIT License. For details, see the [LICENSE](https://github.com/pfriedrix/FlowKit/blob/main/LICENSE) file.\n\n--- \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpfriedrix%2FFlowKit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpfriedrix%2FFlowKit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpfriedrix%2FFlowKit/lists"}