Kaskade
State Container for Kotlin and Android.
The name comes from cascade, a waterfall, which reflects the objective of the library to make flows easier with unidirectional data flow.
Inspired by MVI or Model View Intent.
Why Kaskade?
- Lightweight - enforces unidirectional data flow without the use of external dependencies.
- Modular - can be easily substituted to different implementation with or without the use of another library.
- Extendable - in relation to modular and lightweight, it's important to extend the API and create user defined implementation to fit specific requirements.
- Unidirectional - data flows in one direction.
- Predictable - control on
state
changes andaction
triggers. - DSL - able to hide complexity in a fluent way.
- Multiplatform - built for JVM, iOS, and Javascript.
Installation
- Add to
settings.gradle
enableFeaturePreview('GRADLE_METADATA')
- Add the dependency
dependencies {
// core module
implementation 'dev.gumil.kaskade:core:0.x.y'
// coroutines module
implementation 'dev.gumil.kaskade:coroutines:0.x.y'
// rx module
implementation 'dev.gumil.kaskade:rx:0.x.y'
// livedata module
implementation 'dev.gumil.kaskade:livedata:0.x.y'
}
(Please replace x and y with the latest version numbers: )
Usage
Create the Action
and State
objects.
Note: objects are only used here for simplicity in real projects data classes are more appropriate
internal sealed class TestState : State {
object State1 : TestState()
object State2 : TestState()
object State3 : TestState()
}
internal sealed class TestAction : Action {
object Action1 : TestAction()
object Action2 : TestAction()
object Action3 : TestAction()
}
Create Kaskade
with TestState.State1
as initial state
val kaskade = Kaskade.create<TestAction, TestState>(TestState.State1) {
on<TestAction.Action1> {
TestState.State1
}
on<TestAction.Action2> {
TestState.State2
}
on<TestAction.Action3> {
TestState.State3
}
}
Adding actions to Action
with parameter ActionState
on<TestAction.Action1> { actionState ->
// do any side effects when returning a new state
TestState.State1
}
Observing states
kaskade.onStateChanged = {
// Do something with new state
render(it)
}
Observing states with Emitter
kaskade.stateEmitter().subscribe {
// Do something with new state
render(it)
}
Executing actions
kaskade.dispatch(TestAction.Action1)
Documentation
Check out the wiki for documentation.
Some of the topics covered are:
Sample projects
-
Android App - Android use cases
-
Kotlin Console - Kotlin only project
-
- Android master-detail
- Reactive FlowBinding and StateFlow use case