f { model }
Accelerate development of compositional, safe and ergonomic applications
Functional, Algebraic and Reactive Domain Modeling
Kotlin / Multiplatform
Decide
A pure function that takes command and current state as parameters, and returns the flow of new events.
Evolve
A pure function that takes event and current state as parameters, and returns the new state of the system.
React
A pure function that takes event as parameter, and returns the flow of commands, deciding what to execute next.
EventSourced systems
Event-Sourced systems are storing the events in immutable storage by only appending.
StateStored systems
State-stored systems are traditional systems that are only storing the current state by overwriting the previous state in the storage.
typealias OrderDecider = Decider<OrderCommand?, Order?, OrderEvent?>
fun orderDecider() = OrderDecider(
    // Initial state/s of the Order
    initialState = null,
    // Decide new events/e based on the command/c and current state/s
    decide = { c, s ->
        when (c) {
            is CreateOrderCommand ->
                if (s == null) flowOf(OrderCreatedEvent(c.identifier, c.lineItems, c.restaurantIdentifier))
                else flowOf(OrderRejectedEvent(c.identifier, Reason("Order already exists")))
            is MarkOrderAsPreparedCommand ->
                if (s == null) flowOf(OrderNotPreparedEvent(c.identifier, Reason("Order does not exist")))
                else if (OrderStatus.CREATED != s.status) flowOf(OrderNotPreparedEvent(c.identifier, Reason("Order not in CREATED status")))
                else flowOf(OrderPreparedEvent(c.identifier))
            // Ignore the null command by emitting the empty flow of events
            null -> emptyFlow()
        }
    },
    // Evolve the new state/s based on the event/e and current state/s
    evolve = { s, e ->
        when (e) {
            is OrderCreatedEvent -> Order(e.identifier, e.restaurantId, e.status, e.lineItems)
            is OrderPreparedEvent -> s?.copy(status = e.status)
            is OrderRejectedEvent -> s?.copy(status = e.status)
            is OrderErrorEvent -> s
            // Ignore the null events, by not changing the state
            null -> s
        }
    }
)
// Check the demos for more examples:
// https://github.com/fraktalio/fmodel-spring-demo
// https://github.com/fraktalio/fmodel-ktor-demo