Getting Started
This guide will get you running with a Meteor installation in one minute!
Setup
Add the dependency below into your module's build.gradle.kts
file:
// It includes viewmodel, stateflow and core components.
implementation("io.github.behzodhalil:meteor-core:<latest-version>")
// If only need common use case
implementation("io.github.behzodhalil:meteor-usecase:<latest-version>")
// For testing
implementation("io.github.behzodhalil:meteor-test:<latest-version>")
Define the contract
data class CountState(
val count: Int = 0
)
sealed interface CountWish {
object Increase : CountWish
object Decrease : CountWish
object Reset : CountWish
object ZeroValue : CountWish
}
sealed interface CountEffect {
data class Failure(val message: String) : CountEffect
}
State
represents the current state of your application. Effects are a way to handle side effects in Meteor. Side effects can include operations such as making network requests, updating a database, displaying UI messages, or triggering external actions. A "wish" in Meteor represents an action or an intention to change the state of the application.
Create the ViewModel
Define a ViewModel class, such as MainViewModel
, that extends CommonViewModel
with the appropriate state, wish, and effect types:
class MainViewModel : CommonViewModel<CountState, CountWish, CountEffect>() {
// ....
}
Inside your ViewModel, override the store property by creating a Meteor
store using the createMeteor
function and providing the necessary configurations:
override val store: Store<CountState, CountWish, CountEffect> = createMeteor(
configs = MeteorConfigs.build {
initialState = CountState.Empty
storeName = "MainViewModel"
reducer = CountReducer
middleware = CountMiddleware
}
)
Define properties for effect and state in your ViewModel, which will expose the effect and state as CommonFlow
and CommonStateFlow
, respectively:
val effect: NonNullCommonFlow<CountEffect> = store.effect.asCommonFlow()
val state: NonNullCommonStateFlow<CountState> = store.state.asCommonStateFlow()
Define Reducer and Middleware
Create an object / class , such as CountReducer
, that implements the Reducer
interface with the appropriate state, wish, and effect types:
object CountReducer : Reducer<CountState, CountWish, CountEffect> {
override fun reduce(state: CountState, wish: CountWish): Change<CountState, CountEffect> {
return when (wish) {
CountWish.Decrease -> {
expect { state.copy(count = state.count - 1) }
}
CountWish.Increase -> {
expect { state.copy(count = state.count + 1) }
}
CountWish.Reset -> {
expect { state.copy(count = 0) }
}
CountWish.ZeroValue -> {
effect {
CountEffect.Failure("The value is zero")
}
}
}
}
}
Start using Meteor in your application
viewModel.state.onEach { state ->
// Handle the state
}.launchIn(lifecycleScope)
viewModel.effect.onEach { effect ->
// Handle the effect, such as displaying a toast message or triggering an action
}.launchIn(lifecycleScope)