Contents

sobabear/coreengine

Core is a framework for making more reactive applications inspired by [ReactorKit](https://github.com/ReactorKit/ReactorKit), [Redux](http://redux.js.org/docs/basics/index.html).

Installation

CoreEngine is available through CocoaPods. To install it, simply add the following line to your Podfile:

CocoaPods

pod 'CoreEngine'

Swift Package Manager

Swift Package Manager is a tool for managing the distribution of Swift code. It's integrated with the Swift build system to automate the process of downloading, compiling, and linking dependencies.

To integrate CoreEngine into your Xcode project using Swift Package Manager, add it to the dependencies value of your Package.swift:

dependencies: [
    .package(url: "https://github.com/sobabear/CoreEngine.git", .upToNextMajor(from: "2.0.0"))
]

Performance

<img width="914" alt="Screenshot 2023-04-28 at 1 39 26 PM" src="https://user-images.githubusercontent.com/47838132/235057288-8f17a13d-2ed8-475e-9607-442151ecbff6.png">

Core Engine is insanely fast and light-weight compared to similar frameworks you can check details here CoreEngineBenchMark

Side Effect & Error Handling

Not just simple core, but complex core is also supported. For example, Side Effect and Error handling. When it comes to those, you use AsyncCore or PublisherCore.

func dispatch(effect: any Publisher) & func handleError(error: Error)

This method is defined in PublisherCore and when you deal with side-effect generated publisher send into the function. Also you can handle every errors on the handleError(error: Error) function.

```swift class MainCore: PublisherCore { var subscription: Set<AnyCancellable> = .init()

enum Action { case increase case decrease case setNumber(Int) }

struct State: Equatable, Sendable { var count = 0 }

@Published var state: State = .init()

private let sessionService = SessionService()

init() { dispatch(effect: sessionService.randomUInt$().map(Action.setNumber)) }

func reduce(state: State, action: Action) -> State { var newState = state switch action { case .increase: newState.count += 1 case .decrease: newState.count -= 1 case let .setNumber(value): newState.count = value } return newState }

func handleError(error: Error) { // handle } } ```


Migration Guide (v1 → v2)

| Breaking change | Migration | |---|---| | State must conform to Equatable & Sendable | Add conformances to all State structs | | AsyncCore removes currentState, states, continuation protocol requirements | Replace 3 properties + async init with let store: AsyncCoreStore<State> + sync init | | AsyncCore.init is no longer async | Remove await from init call sites | | Core.action is a method, not a closure property | core.action(.x) unchanged; let fn = core.action no longer compiles | | iOS 13/14/15 no longer supported | Update deployment targets to iOS 16+ |

Before (v1)

actor MyCore: AsyncCore {
    nonisolated(unsafe) var currentState: State
    var states: AsyncCoreSequence<State>
    var continuation: AsyncStream<State>.Continuation

    init(initialState: State) async {
        self.currentState = initialState
        let (stream, continuation) = AsyncStream<State>.makeStream()
        self.states = await .init(stream)
        self.continuation = continuation
    }
}

// Call site
let core = await MyCore(initialState: .init())

After (v2)

actor MyCore: AsyncCore {
    let store: AsyncCoreStore<State>

    init(initialState: State) {
        self.store = .init(initialState: initialState)
    }
}

// Call site — no await
let core = MyCore(initialState: .init())

Examples + RxSwift

import Foundation
import CoreEngine
import RxSwift

protocol RxCore: Core {
    var disposeBag: DisposeBag { get set }
    
    func mutate(effect: Observable<Action>)
    func handleError(error: Error)
}

extension RxCore {
    public func mutate(effect: Observable<Action>) {
        effect
            .subscribe(onNext: { [weak self] in
                self?.action($0)
            }, onError: { [weak self] in
                self?.handleError(error: $0)
            })
            .disposed(by: disposeBag)
    }
    
    public func handleError(error: Error) { }
}

Author

stareta1202, stareta1202@gmail.com

License

CoreEngine is available under the MIT license. See the LICENSE file for more info.

Package Metadata

Repository: sobabear/coreengine

Default branch: main

README: README.md