Skip to main content

f { model }

Accelerate development of compositional, safe and ergonomic applications

Functional, Algebraic and Reactive Domain Modeling

Kotlin / Multiplatform

StateStored systems

State-stored systems are traditional systems that are only storing the current state by overwriting the previous state in the storage.

EventSourced + StateStored

Both types of systems can be designed by using only these three functions (decide, evolve, react) and three generic parameters (command, event, state).


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