🎭
Actomaton

Swift 5.5

🧑‍🎤
Actor +
🤖
Automaton =
🎭
Actomaton

Actomaton is Swift async/await & Actor-powered effectful state-management framework inspired by Elm and swift-composable-architecture.

This repository consists of 2 frameworks:

  1. Actomaton: Actor-based effect-handling state-machine at its core. Linux ready.
  2. ActomatonStore: SwiftUI & Combine support

These frameworks depend on swift-case-paths as Functional Prism library, which is a powerful tool to construct an App-level Mega-Reducer from each screen’s Reducers.

This framework is a successor of the following projects:

Demo App

1. Actomaton (Core)

Example 1-1. Simple Counter

<div class="highlight highlight-source-swift position-relative" data-snippet-clipboard-copy-content="enum State {
var count: Int = 0
}

enum Action {
case increment
case decrement
}

typealias Enviornment = Void

let reducer: Reducer
reducer = Reducer { action, state, environment in
switch action {
case .increment:
state.count += 1
return Effect.empty
case .decrement:
state.count -= 1
return Effect.empty
}
}

let actomaton = Actomaton(
state: State(),
reducer: reducer
)

@main
enum Main {
static func main() async {
assertEqual(await actomaton.state.count, 0)

await actomaton.send(.increment)
assertEqual(await actomaton.state.count, 1)

await actomaton.send(.increment)
assertEqual(await actomaton.state.count, 2)

await actomaton.send(.decrement)
assertEqual(await actomaton.state.count, 1)

await actomaton.send(.decrement)
assertEqual(await actomaton.state.count, 0)
}
}
“>

enum State {
    var count: Int = 0
}

enum Action {
    case increment
    case decrement
}

typealias Enviornment = Void

let reducer: Reducer<Action, State, Environment>
reducer = Reducer { action, state, environment in
    switch action {
    case .increment:
        state.count += 1
        return Effect.empty
    case .decrement:
        state.count -= 1
        return Effect.empty
    }
}

let actomaton = Actomaton<Action, State>(
    state: State(),
    reducer: reducer
)

@main
enum Main {
    static func main() async {
        assertEqual(await actomaton.state.count, 0)

        await actomaton.send(.increment)
        assertEqual(await actomaton.state.count, 1)

        await actomaton.send(.increment)
        assertEqual(await actomaton.state.count, 2)

        await actomaton.send(.decrement)
        assertEqual(await actomaton.state.count, 1)

        await actomaton.send(.decrement)
        assertEqual(await actomaton.state.count, 0)
    }
}