Vaizin Nikita
12/23/2023, 12:08 PMVaizin Nikita
12/23/2023, 12:12 PMFergus Hewson
09/14/2024, 3:21 AMCompileError: WebAssembly.instantiateStreaming(): Compiling function #67408:"pro.respawn.flowmvi.plugins.$onExceptionCOROUTI..." failed: struct.set[1] expected type (ref null 14487), found struct.get of type (ref null 846) @+10644021
Has anyone come across this? I have been using the FlowMVI as an example.Vaizin Nikita
09/22/2024, 12:54 PMFergus Hewson
09/29/2024, 12:43 AMFergus Hewson
11/05/2024, 10:43 PMVaizin Nikita
11/23/2024, 2:24 PMVaizin Nikita
11/23/2024, 2:34 PMVaizin Nikita
11/25/2024, 1:22 PMVaizin Nikita
11/28/2024, 2:54 PMdecorator { }
DSL and then install(decorator)
in the store. This enabled the creation of new built-in decorators (plugins) for retries, buffering, debouncing, and conflating intents.
🧨 API Changes
• Changed the installation order of “time travel” for plugin test DSL. This will break tests that relied on the old value in time travel—now it’s the new one. This was a mistake in the API design.
• Kotlin 2.1
• Changed store lifecycle behavior: now it doesn’t wait for the next lifecycle event to close but skips the operation instead. This was very inconvenient in beta02.
Debugger and Plugin Updates:
• Added live templates for the plugin:
• fmvic - a new container.
• fmvip - a new plugin.
• fmvilp - a new lazy plugin.
• fmvim - models (LCE states, intents, and actions).
I recommend using the plugin just because of this feature — it generates all (already minimal) boilerplate for creating new stores in seconds.
🚀 New Features
• Added a callback for undelivered intents/actions in the plugin DSL (#106).
• Added a shutdown context with some store API in the onStop callback.
• Optimized plugin chain execution by skipping empty callbacks.
• Implemented store decorators and corresponding DSLs.
• New decorators: TimeoutDecorator, ConflateDecorator, RetryDecorator, BatchIntents.
• Added logging of undelivered intents/actions in the loggingPlugin.
• Improved performance by reducing context switching in the store (#105).
Docs on the website are still in progress. I haven’t had time to write articles due to the volume of features, plus I need to use some of the new functionality for my work.
Currently working on a plugin for automatically collecting performance metrics for any store ⚡️ It should land in the fifth beta.Vaizin Nikita
12/22/2024, 11:33 PMVaizin Nikita
12/22/2024, 11:33 PMVaizin Nikita
12/31/2024, 11:01 AMMatteo Vettosi
01/08/2025, 10:46 PMgetViewModel(...)
in the composable version of storeViewModel
, but I couldn't figure out where that is coming from. I tried replacing it with koinViewModel
which has the same signature, but it's crashing saying
No definition found for type 'pro.respawn.flowmvi.android.StoreViewModel' and qualifier 'pro.respawn.flowmvi.api.Container'
Apologies if it ends up being a trivial question!Vaizin Nikita
01/09/2025, 3:12 PMimport org.koin.androidx.compose.koinViewModel
import org.koin.compose.currentKoinScope
import org.koin.core.module.Module
import org.koin.core.module.dsl.viewModel
import org.koin.core.parameter.ParametersDefinition
import org.koin.core.qualifier.qualifier
import org.koin.core.scope.Scope
import org.koin.viewmodel.defaultExtras
@FlowMVIDSL
inline fun <reified T : Container<*, *, *>> Module.storeViewModel() = viewModel(qualifier<T>()) { params ->
StoreViewModel(get<T> { params })
}
@FlowMVIDSL
@Composable
inline fun <reified T : Container<S, I, A>, S : MVIState, I : MVIIntent, A : MVIAction> storeViewModel(
key: String? = null,
scope: Scope = currentKoinScope(),
viewModelStoreOwner: ViewModelStoreOwner = checkNotNull(LocalViewModelStoreOwner.current),
extras: CreationExtras = defaultExtras(viewModelStoreOwner),
noinline params: ParametersDefinition? = null,
): Store<S, I, A> = koinViewModel<StoreViewModel<S, I, A>>(
qualifier = qualifier<T>(),
parameters = params,
key = key,
scope = scope,
viewModelStoreOwner = viewModelStoreOwner,
extras = extras
)
Matteo Vettosi
01/10/2025, 10:12 PMLaunchedEffect(Unit) { intent(LoadItem(itemId) }
?
I saw some people normally place that parameter in the viewmodel constructor and pass it to koin during injection, but I don't particularly like the method and it doesn't seem possible when view models are built on the fly from the Container type anyway.Benny Sway
04/01/2025, 7:36 PMVaizin Nikita
04/02/2025, 2:38 PMBenny Sway
05/01/2025, 1:49 PMVaizin Nikita
05/24/2025, 7:15 AM3.2.0-alpha03
. https://github.com/respawn-app/FlowMVI/releases/tag/3.2.0-alpha03
The main focus of this update is on store composition. To help with that, there are two new plugins: childStorePlugin
and storeDelegatePlugin
. These let you build store hierarchies and achieve a cleaner separation of concerns. For instance, you can now extract logic for specific features or even UI components into child stores, instead of bloating a single main store. To show how it works, there's an example in the sample app for progressive content loading that’s just 7 lines of code. Details and guides are in the docs. https://opensource.respawn.pro/FlowMVI/plugins/delegates
I’ve also seriously reworked the whileSubscribed
plugin. It's now based on the new SubscriptionAware
interface, which allows the store to get direct information about its subscribers. In practice, this solves the issue of unnecessary restarts during configuration changes on Android – there's now a small, configurable delay before the store stops.
I wrote a ton of tests for this, but I'm still a bit anxious about the new whileSubscribed
implementation. Please let me know if you run into any issues.
The new default 1-second delay shouldn't be a major problem when updating, but who knows who might have depended on the old plugin's behavior.Vaizin Nikita
05/24/2025, 7:16 AM