diff --git a/compose/build.gradle.kts b/compose/build.gradle.kts index e2bed1c3..3eeb88b8 100644 --- a/compose/build.gradle.kts +++ b/compose/build.gradle.kts @@ -28,7 +28,6 @@ kotlin { androidMain.dependencies { implementation(libs.compose.foundation) implementation(libs.compose.preview) - implementation(libs.compose.lifecycle.viewmodel) implementation(libs.compose.lifecycle.runtime) api(projects.android) } @@ -39,6 +38,7 @@ kotlin { } jvmMain.dependencies { implementation(compose.desktop.common) + implementation(libs.compose.lifecycle.runtime) } } } diff --git a/compose/src/androidMain/kotlin/pro/respawn/flowmvi/compose/android/AndroidInterop.kt b/compose/src/androidMain/kotlin/pro/respawn/flowmvi/compose/android/AndroidInterop.kt new file mode 100644 index 00000000..8a445a3a --- /dev/null +++ b/compose/src/androidMain/kotlin/pro/respawn/flowmvi/compose/android/AndroidInterop.kt @@ -0,0 +1,27 @@ +package pro.respawn.flowmvi.compose.android + +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.repeatOnLifecycle +import pro.respawn.flowmvi.compose.api.SubscriberLifecycleOwner +import pro.respawn.flowmvi.compose.api.SubscriptionMode + +public fun LifecycleOwner.asSubscriberOwner(): SubscriberLifecycleOwner = SubscriberLifecycleOwner { mode, block -> + repeatOnLifecycle(mode.asLifecycleState, block) +} + +public val SubscriptionMode.asLifecycleState: Lifecycle.State + get() = when (this) { + SubscriptionMode.Immediate -> Lifecycle.State.CREATED + SubscriptionMode.Started -> Lifecycle.State.STARTED + SubscriptionMode.Visible -> Lifecycle.State.RESUMED + } + +public val Lifecycle.State.asSubscriptionMode: SubscriptionMode + get() = when (this) { + Lifecycle.State.CREATED -> SubscriptionMode.Immediate + Lifecycle.State.STARTED -> SubscriptionMode.Started + Lifecycle.State.RESUMED -> SubscriptionMode.Visible + Lifecycle.State.DESTROYED, + Lifecycle.State.INITIALIZED -> error("Android lifecycle does not support $this as subscription mode") + } diff --git a/compose/src/androidMain/kotlin/pro/respawn/flowmvi/compose/dsl/LocalSubscriberLifecycle.android.kt b/compose/src/androidMain/kotlin/pro/respawn/flowmvi/compose/dsl/LocalSubscriberLifecycle.android.kt new file mode 100644 index 00000000..f71ca858 --- /dev/null +++ b/compose/src/androidMain/kotlin/pro/respawn/flowmvi/compose/dsl/LocalSubscriberLifecycle.android.kt @@ -0,0 +1,9 @@ +package pro.respawn.flowmvi.compose.dsl + +import androidx.compose.runtime.Composable +import androidx.compose.ui.platform.LocalLifecycleOwner +import pro.respawn.flowmvi.compose.android.asSubscriberOwner +import pro.respawn.flowmvi.compose.api.SubscriberLifecycleOwner + +internal actual val PlatformLifecycle: SubscriberLifecycleOwner? + @Composable get() = LocalLifecycleOwner.current.asSubscriberOwner() diff --git a/compose/src/androidMain/kotlin/pro/respawn/flowmvi/compose/dsl/SubscribeDsl.android.kt b/compose/src/androidMain/kotlin/pro/respawn/flowmvi/compose/dsl/SubscribeDsl.android.kt index 0c6e5f98..10f815d2 100644 --- a/compose/src/androidMain/kotlin/pro/respawn/flowmvi/compose/dsl/SubscribeDsl.android.kt +++ b/compose/src/androidMain/kotlin/pro/respawn/flowmvi/compose/dsl/SubscribeDsl.android.kt @@ -3,25 +3,19 @@ package pro.respawn.flowmvi.compose.dsl import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.State -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberUpdatedState import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.lifecycle.Lifecycle -import androidx.lifecycle.repeatOnLifecycle +import androidx.lifecycle.LifecycleOwner import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext import pro.respawn.flowmvi.android.subscribe -import pro.respawn.flowmvi.api.DelicateStoreApi import pro.respawn.flowmvi.api.FlowMVIDSL import pro.respawn.flowmvi.api.ImmutableStore import pro.respawn.flowmvi.api.MVIAction import pro.respawn.flowmvi.api.MVIIntent import pro.respawn.flowmvi.api.MVIState +import pro.respawn.flowmvi.compose.android.asSubscriberOwner +import pro.respawn.flowmvi.compose.android.asSubscriptionMode import pro.respawn.flowmvi.dsl.subscribe /** @@ -39,30 +33,14 @@ import pro.respawn.flowmvi.dsl.subscribe * @see ImmutableStore.subscribe * @see subscribe */ -@OptIn(DelicateStoreApi::class) @Suppress("NOTHING_TO_INLINE", "ComposableParametersOrdering") @Composable @FlowMVIDSL public inline fun ImmutableStore.subscribe( - lifecycleState: Lifecycle.State = Lifecycle.State.STARTED, + lifecycleState: Lifecycle.State, + lifecycleOwner: LifecycleOwner = LocalLifecycleOwner.current, noinline consume: suspend CoroutineScope.(action: A) -> Unit, -): State { - val owner = LocalLifecycleOwner.current - val state = remember(this) { mutableStateOf(state) } - val block by rememberUpdatedState(consume) - LaunchedEffect(this@subscribe, lifecycleState, owner) { - withContext(Dispatchers.Main.immediate) { - owner.repeatOnLifecycle(lifecycleState) { - subscribe( - store = this@subscribe, - consume = { block(it) }, - render = { state.value = it } - ).join() - } - } - } - return state -} +): State = subscribe(lifecycleState.asSubscriptionMode, lifecycleOwner.asSubscriberOwner(), consume) /** * A function to subscribe to the store that follows the system lifecycle. @@ -77,42 +55,10 @@ public inline fun ImmutableStore ImmutableStore.subscribe( - lifecycleState: Lifecycle.State = Lifecycle.State.STARTED, -): State { - val owner = LocalLifecycleOwner.current - val state = remember(this) { mutableStateOf(state) } - LaunchedEffect(this@subscribe, lifecycleState, owner) { - withContext(Dispatchers.Main.immediate) { - owner.repeatOnLifecycle(lifecycleState) { - subscribe( - store = this@subscribe, - render = { state.value = it } - ).join() - } - } - } - return state -} - -/** - * Alias for [pro.respawn.flowmvi.compose.dsl.subscribe] with [Lifecycle.State.STARTED]. - **/ -@FlowMVIDSL -@Composable -public actual inline fun ImmutableStore.subscribe(): State = - subscribe(Lifecycle.State.STARTED) - -/** - * Alias for [pro.respawn.flowmvi.compose.dsl.subscribe] with [Lifecycle.State.STARTED]. - **/ -@FlowMVIDSL -@Composable -@Suppress("NOTHING_TO_INLINE", "ComposableParametersOrdering") -public actual inline fun ImmutableStore.subscribe( - noinline consume: suspend CoroutineScope.(action: A) -> Unit -): State = subscribe(Lifecycle.State.STARTED, consume) + lifecycleState: Lifecycle.State, + lifecycleOwner: LifecycleOwner = LocalLifecycleOwner.current, +): State = subscribe(lifecycleState.asSubscriptionMode, lifecycleOwner.asSubscriberOwner()) diff --git a/compose/src/commonMain/kotlin/pro/respawn/flowmvi/compose/api/SubscriberLifecycleOwner.kt b/compose/src/commonMain/kotlin/pro/respawn/flowmvi/compose/api/SubscriberLifecycleOwner.kt new file mode 100644 index 00000000..7a432d0c --- /dev/null +++ b/compose/src/commonMain/kotlin/pro/respawn/flowmvi/compose/api/SubscriberLifecycleOwner.kt @@ -0,0 +1,8 @@ +package pro.respawn.flowmvi.compose.api + +import kotlinx.coroutines.CoroutineScope + +public fun interface SubscriberLifecycleOwner { + + public suspend fun repeatOnLifecycle(mode: SubscriptionMode, block: suspend CoroutineScope.() -> Unit) +} diff --git a/compose/src/commonMain/kotlin/pro/respawn/flowmvi/compose/api/SubscriptionMode.kt b/compose/src/commonMain/kotlin/pro/respawn/flowmvi/compose/api/SubscriptionMode.kt new file mode 100644 index 00000000..a3c30046 --- /dev/null +++ b/compose/src/commonMain/kotlin/pro/respawn/flowmvi/compose/api/SubscriptionMode.kt @@ -0,0 +1,7 @@ +package pro.respawn.flowmvi.compose.api + +public enum class SubscriptionMode { + Immediate, + Started, + Visible, +} diff --git a/compose/src/commonMain/kotlin/pro/respawn/flowmvi/compose/dsl/ImmediateLifecycleOwner.kt b/compose/src/commonMain/kotlin/pro/respawn/flowmvi/compose/dsl/ImmediateLifecycleOwner.kt new file mode 100644 index 00000000..fc138206 --- /dev/null +++ b/compose/src/commonMain/kotlin/pro/respawn/flowmvi/compose/dsl/ImmediateLifecycleOwner.kt @@ -0,0 +1,9 @@ +package pro.respawn.flowmvi.compose.dsl + +import kotlinx.coroutines.coroutineScope +import pro.respawn.flowmvi.compose.api.SubscriberLifecycleOwner + +@PublishedApi +internal val ImmediateLifecycleOwner: SubscriberLifecycleOwner = SubscriberLifecycleOwner { _, block -> + coroutineScope(block) +} diff --git a/compose/src/commonMain/kotlin/pro/respawn/flowmvi/compose/dsl/LocalSubscriberLifecycle.kt b/compose/src/commonMain/kotlin/pro/respawn/flowmvi/compose/dsl/LocalSubscriberLifecycle.kt new file mode 100644 index 00000000..d3d00693 --- /dev/null +++ b/compose/src/commonMain/kotlin/pro/respawn/flowmvi/compose/dsl/LocalSubscriberLifecycle.kt @@ -0,0 +1,17 @@ +package pro.respawn.flowmvi.compose.dsl + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.ProvidableCompositionLocal +import androidx.compose.runtime.staticCompositionLocalOf +import pro.respawn.flowmvi.compose.api.SubscriberLifecycleOwner + +public val LocalSubscriberLifecycle: ProvidableCompositionLocal = staticCompositionLocalOf { + null +} + +@PublishedApi +internal val CurrentLifecycle: SubscriberLifecycleOwner + @Composable get() = LocalSubscriberLifecycle.current ?: PlatformLifecycle ?: ImmediateLifecycleOwner + +@get:Composable +internal expect val PlatformLifecycle: SubscriberLifecycleOwner? diff --git a/compose/src/commonMain/kotlin/pro/respawn/flowmvi/compose/dsl/SubscribeDsl.kt b/compose/src/commonMain/kotlin/pro/respawn/flowmvi/compose/dsl/SubscribeDsl.kt index f51b14ee..5cc5e001 100644 --- a/compose/src/commonMain/kotlin/pro/respawn/flowmvi/compose/dsl/SubscribeDsl.kt +++ b/compose/src/commonMain/kotlin/pro/respawn/flowmvi/compose/dsl/SubscribeDsl.kt @@ -8,78 +8,62 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberUpdatedState import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext import pro.respawn.flowmvi.api.DelicateStoreApi import pro.respawn.flowmvi.api.FlowMVIDSL import pro.respawn.flowmvi.api.ImmutableStore import pro.respawn.flowmvi.api.MVIAction import pro.respawn.flowmvi.api.MVIIntent import pro.respawn.flowmvi.api.MVIState -import pro.respawn.flowmvi.api.Store +import pro.respawn.flowmvi.compose.api.SubscriberLifecycleOwner +import pro.respawn.flowmvi.compose.api.SubscriptionMode import pro.respawn.flowmvi.dsl.subscribe +import pro.respawn.flowmvi.util.immediateOrDefault -/** - * A function to subscribe to the store that follows the system lifecycle. - * - * * This function will assign the store a new subscriber when invoked, then populate the returned [State] with new states. - * * Provided [consume] parameter will be used to consume actions that come from the store. - * * Store's subscribers will **not** wait until the store is launched when they subscribe to the store. - * Such subscribers will not receive state updates or actions. Don't forget to launch the store. - * - * @param consume a lambda to consume actions with. - * @return the [State] that contains the [Store.state]. - * @see Store.subscribe - */ -@Composable -@FlowMVIDSL -public expect inline fun ImmutableStore.subscribe( - noinline consume: suspend CoroutineScope.(action: A) -> Unit, -): State - -/** - * A function to subscribe to the store that follows the system lifecycle. - * - * * This function will not collect [MVIAction]s. - * * This function will assign the store a new subscriber when invoked, then populate the returned [State] with new states. - * * Store's subscribers will **not** wait until the store is launched when they subscribe to the store. - * Such subscribers will not receive state updates or actions. Don't forget to launch the store. - * upon leaving that state, the function will unsubscribe. - * @return the [State] that contains the [Store.state]. - * @see Store.subscribe - */ -@Composable -@FlowMVIDSL -public expect inline fun ImmutableStore.subscribe(): State - -@PublishedApi @OptIn(DelicateStoreApi::class) +@Suppress("ComposableParametersOrdering") @Composable @FlowMVIDSL -internal inline fun ImmutableStore.subscribeDirect(): State { +public inline fun ImmutableStore.subscribe( + mode: SubscriptionMode = SubscriptionMode.Started, + owner: SubscriberLifecycleOwner = CurrentLifecycle, + noinline consume: suspend CoroutineScope.(action: A) -> Unit, +): State { val state = remember(this) { mutableStateOf(state) } - LaunchedEffect(this@subscribeDirect) { - subscribe( - store = this@subscribeDirect, - render = { state.value = it }, - ).join() + val block by rememberUpdatedState(consume) + LaunchedEffect(this@subscribe, mode, owner) { + withContext(Dispatchers.Main.immediateOrDefault) { + owner.repeatOnLifecycle(mode) { + subscribe( + store = this@subscribe, + consume = { block(it) }, + render = { state.value = it } + ).join() + } + } } return state } -@PublishedApi + @OptIn(DelicateStoreApi::class) @Composable @FlowMVIDSL -internal inline fun ImmutableStore.subscribeDirect( - noinline consume: suspend CoroutineScope.(action: A) -> Unit, +public inline fun ImmutableStore.subscribe( + mode: SubscriptionMode = SubscriptionMode.Visible, + owner: SubscriberLifecycleOwner = CurrentLifecycle, ): State { val state = remember(this) { mutableStateOf(state) } - val block by rememberUpdatedState(consume) - LaunchedEffect(this@subscribeDirect) { - subscribe( - store = this@subscribeDirect, - render = { state.value = it }, - consume = { block(it) } - ).join() + LaunchedEffect(this@subscribe, mode, owner) { + withContext(Dispatchers.Main.immediateOrDefault) { + owner.repeatOnLifecycle(mode) { + subscribe( + store = this@subscribe, + render = { state.value = it } + ).join() + } + } } return state } diff --git a/compose/src/jsMain/kotlin/pro/respawn/flowmvi/compose/dsl/LocalSubscriberLifecycle.js.kt b/compose/src/jsMain/kotlin/pro/respawn/flowmvi/compose/dsl/LocalSubscriberLifecycle.js.kt new file mode 100644 index 00000000..fd867f21 --- /dev/null +++ b/compose/src/jsMain/kotlin/pro/respawn/flowmvi/compose/dsl/LocalSubscriberLifecycle.js.kt @@ -0,0 +1,6 @@ +package pro.respawn.flowmvi.compose.dsl + +import androidx.compose.runtime.Composable +import pro.respawn.flowmvi.compose.api.SubscriberLifecycleOwner + +internal actual val PlatformLifecycle: SubscriberLifecycleOwner? @Composable get() = null diff --git a/compose/src/jsMain/kotlin/pro/respawn/flowmvi/compose/dsl/SubscribeDsl.js.kt b/compose/src/jsMain/kotlin/pro/respawn/flowmvi/compose/dsl/SubscribeDsl.js.kt deleted file mode 100644 index 4d9b66d1..00000000 --- a/compose/src/jsMain/kotlin/pro/respawn/flowmvi/compose/dsl/SubscribeDsl.js.kt +++ /dev/null @@ -1,46 +0,0 @@ -package pro.respawn.flowmvi.compose.dsl - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.State -import androidx.compose.runtime.getValue -import kotlinx.coroutines.CoroutineScope -import pro.respawn.flowmvi.api.FlowMVIDSL -import pro.respawn.flowmvi.api.ImmutableStore -import pro.respawn.flowmvi.api.MVIAction -import pro.respawn.flowmvi.api.MVIIntent -import pro.respawn.flowmvi.api.MVIState -import pro.respawn.flowmvi.dsl.subscribe - -/** - * A function to subscribe to the store that follows the system lifecycle. - * - * * This function will assign the store a new subscriber when invoked, then populate the returned [State] with new states. - * * Provided [consume] parameter will be used to consume actions that come from the store. - * * Store's subscribers will **not** wait until the store is launched when they subscribe to the store. - * Such subscribers will not receive state updates or actions. Don't forget to launch the store. - * - * @param consume a lambda to consume actions with. - * @return the [State] that contains the [ImmutableStore.state]. - * @see ImmutableStore.subscribe - */ -@FlowMVIDSL -@Composable -public actual inline fun ImmutableStore.subscribe( - noinline consume: suspend CoroutineScope.(action: A) -> Unit -): State = subscribeDirect(consume) - -/** - * A function to subscribe to the store that follows the system lifecycle. - * - * * This function will not collect [MVIAction]s. - * * This function will assign the store a new subscriber when invoked, then populate the returned [State] with new states. - * * Store's subscribers will **not** wait until the store is launched when they subscribe to the store. - * Such subscribers will not receive state updates or actions. Don't forget to launch the store. - * upon leaving that state, the function will unsubscribe. - * @return the [State] that contains the [ImmutableStore.state]. - * @see ImmutableStore.subscribe - */ -@FlowMVIDSL -@Composable -public actual inline fun ImmutableStore.subscribe(): State = - subscribeDirect() diff --git a/compose/src/jvmMain/kotlin/pro/respawn/flowmvi/compose/dsl/LocalSubscriberLifecycle.jvm.kt b/compose/src/jvmMain/kotlin/pro/respawn/flowmvi/compose/dsl/LocalSubscriberLifecycle.jvm.kt new file mode 100644 index 00000000..fd867f21 --- /dev/null +++ b/compose/src/jvmMain/kotlin/pro/respawn/flowmvi/compose/dsl/LocalSubscriberLifecycle.jvm.kt @@ -0,0 +1,6 @@ +package pro.respawn.flowmvi.compose.dsl + +import androidx.compose.runtime.Composable +import pro.respawn.flowmvi.compose.api.SubscriberLifecycleOwner + +internal actual val PlatformLifecycle: SubscriberLifecycleOwner? @Composable get() = null diff --git a/compose/src/jvmMain/kotlin/pro/respawn/flowmvi/compose/dsl/SubscribeDsl.jvm.kt b/compose/src/jvmMain/kotlin/pro/respawn/flowmvi/compose/dsl/SubscribeDsl.jvm.kt deleted file mode 100644 index 86ec3683..00000000 --- a/compose/src/jvmMain/kotlin/pro/respawn/flowmvi/compose/dsl/SubscribeDsl.jvm.kt +++ /dev/null @@ -1,44 +0,0 @@ -package pro.respawn.flowmvi.compose.dsl - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.State -import kotlinx.coroutines.CoroutineScope -import pro.respawn.flowmvi.api.FlowMVIDSL -import pro.respawn.flowmvi.api.ImmutableStore -import pro.respawn.flowmvi.api.MVIAction -import pro.respawn.flowmvi.api.MVIIntent -import pro.respawn.flowmvi.api.MVIState - -/** - * A function to subscribe to the store that follows the system lifecycle. - * - * * This function will assign the store a new subscriber when invoked, then populate the returned [State] with new states. - * * Provided [consume] parameter will be used to consume actions that come from the store. - * * Store's subscribers will **not** wait until the store is launched when they subscribe to the store. - * Such subscribers will not receive state updates or actions. Don't forget to launch the store. - * - * @param consume a lambda to consume actions with. - * @return the [State] that contains the [ImmutableStore.state]. - * @see ImmutableStore.subscribe - */ -@FlowMVIDSL -@Composable -public actual inline fun ImmutableStore.subscribe( - noinline consume: suspend CoroutineScope.(action: A) -> Unit -): State = subscribeDirect(consume) - -/** - * A function to subscribe to the store that follows the system lifecycle. - * - * * This function will not collect [MVIAction]s. - * * This function will assign the store a new subscriber when invoked, then populate the returned [State] with new states. - * * Store's subscribers will **not** wait until the store is launched when they subscribe to the store. - * Such subscribers will not receive state updates or actions. Don't forget to launch the store. - * upon leaving that state, the function will unsubscribe. - * @return the [State] that contains the [ImmutableStore.state]. - * @see ImmutableStore.subscribe - */ -@FlowMVIDSL -@Composable -public actual inline fun ImmutableStore.subscribe(): State = - subscribeDirect() diff --git a/compose/src/nativeMain/kotlin/pro/respawn/flowmvi/compose/dsl/LocalSubscriberLifecycle.native.kt b/compose/src/nativeMain/kotlin/pro/respawn/flowmvi/compose/dsl/LocalSubscriberLifecycle.native.kt new file mode 100644 index 00000000..fd867f21 --- /dev/null +++ b/compose/src/nativeMain/kotlin/pro/respawn/flowmvi/compose/dsl/LocalSubscriberLifecycle.native.kt @@ -0,0 +1,6 @@ +package pro.respawn.flowmvi.compose.dsl + +import androidx.compose.runtime.Composable +import pro.respawn.flowmvi.compose.api.SubscriberLifecycleOwner + +internal actual val PlatformLifecycle: SubscriberLifecycleOwner? @Composable get() = null diff --git a/compose/src/nativeMain/kotlin/pro/respawn/flowmvi/compose/dsl/SubscribeDsl.native.kt b/compose/src/nativeMain/kotlin/pro/respawn/flowmvi/compose/dsl/SubscribeDsl.native.kt deleted file mode 100644 index 4d9b66d1..00000000 --- a/compose/src/nativeMain/kotlin/pro/respawn/flowmvi/compose/dsl/SubscribeDsl.native.kt +++ /dev/null @@ -1,46 +0,0 @@ -package pro.respawn.flowmvi.compose.dsl - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.State -import androidx.compose.runtime.getValue -import kotlinx.coroutines.CoroutineScope -import pro.respawn.flowmvi.api.FlowMVIDSL -import pro.respawn.flowmvi.api.ImmutableStore -import pro.respawn.flowmvi.api.MVIAction -import pro.respawn.flowmvi.api.MVIIntent -import pro.respawn.flowmvi.api.MVIState -import pro.respawn.flowmvi.dsl.subscribe - -/** - * A function to subscribe to the store that follows the system lifecycle. - * - * * This function will assign the store a new subscriber when invoked, then populate the returned [State] with new states. - * * Provided [consume] parameter will be used to consume actions that come from the store. - * * Store's subscribers will **not** wait until the store is launched when they subscribe to the store. - * Such subscribers will not receive state updates or actions. Don't forget to launch the store. - * - * @param consume a lambda to consume actions with. - * @return the [State] that contains the [ImmutableStore.state]. - * @see ImmutableStore.subscribe - */ -@FlowMVIDSL -@Composable -public actual inline fun ImmutableStore.subscribe( - noinline consume: suspend CoroutineScope.(action: A) -> Unit -): State = subscribeDirect(consume) - -/** - * A function to subscribe to the store that follows the system lifecycle. - * - * * This function will not collect [MVIAction]s. - * * This function will assign the store a new subscriber when invoked, then populate the returned [State] with new states. - * * Store's subscribers will **not** wait until the store is launched when they subscribe to the store. - * Such subscribers will not receive state updates or actions. Don't forget to launch the store. - * upon leaving that state, the function will unsubscribe. - * @return the [State] that contains the [ImmutableStore.state]. - * @see ImmutableStore.subscribe - */ -@FlowMVIDSL -@Composable -public actual inline fun ImmutableStore.subscribe(): State = - subscribeDirect() diff --git a/compose/src/wasmJsMain/kotlin/pro/respawn/flowmvi/compose/dsl/LocalSubscriberLifecycle.wasmJs.kt b/compose/src/wasmJsMain/kotlin/pro/respawn/flowmvi/compose/dsl/LocalSubscriberLifecycle.wasmJs.kt new file mode 100644 index 00000000..fd867f21 --- /dev/null +++ b/compose/src/wasmJsMain/kotlin/pro/respawn/flowmvi/compose/dsl/LocalSubscriberLifecycle.wasmJs.kt @@ -0,0 +1,6 @@ +package pro.respawn.flowmvi.compose.dsl + +import androidx.compose.runtime.Composable +import pro.respawn.flowmvi.compose.api.SubscriberLifecycleOwner + +internal actual val PlatformLifecycle: SubscriberLifecycleOwner? @Composable get() = null diff --git a/compose/src/wasmJsMain/kotlin/pro/respawn/flowmvi/compose/dsl/SubscribeDsl.wasmJs.kt b/compose/src/wasmJsMain/kotlin/pro/respawn/flowmvi/compose/dsl/SubscribeDsl.wasmJs.kt deleted file mode 100644 index 4d9b66d1..00000000 --- a/compose/src/wasmJsMain/kotlin/pro/respawn/flowmvi/compose/dsl/SubscribeDsl.wasmJs.kt +++ /dev/null @@ -1,46 +0,0 @@ -package pro.respawn.flowmvi.compose.dsl - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.State -import androidx.compose.runtime.getValue -import kotlinx.coroutines.CoroutineScope -import pro.respawn.flowmvi.api.FlowMVIDSL -import pro.respawn.flowmvi.api.ImmutableStore -import pro.respawn.flowmvi.api.MVIAction -import pro.respawn.flowmvi.api.MVIIntent -import pro.respawn.flowmvi.api.MVIState -import pro.respawn.flowmvi.dsl.subscribe - -/** - * A function to subscribe to the store that follows the system lifecycle. - * - * * This function will assign the store a new subscriber when invoked, then populate the returned [State] with new states. - * * Provided [consume] parameter will be used to consume actions that come from the store. - * * Store's subscribers will **not** wait until the store is launched when they subscribe to the store. - * Such subscribers will not receive state updates or actions. Don't forget to launch the store. - * - * @param consume a lambda to consume actions with. - * @return the [State] that contains the [ImmutableStore.state]. - * @see ImmutableStore.subscribe - */ -@FlowMVIDSL -@Composable -public actual inline fun ImmutableStore.subscribe( - noinline consume: suspend CoroutineScope.(action: A) -> Unit -): State = subscribeDirect(consume) - -/** - * A function to subscribe to the store that follows the system lifecycle. - * - * * This function will not collect [MVIAction]s. - * * This function will assign the store a new subscriber when invoked, then populate the returned [State] with new states. - * * Store's subscribers will **not** wait until the store is launched when they subscribe to the store. - * Such subscribers will not receive state updates or actions. Don't forget to launch the store. - * upon leaving that state, the function will unsubscribe. - * @return the [State] that contains the [ImmutableStore.state]. - * @see ImmutableStore.subscribe - */ -@FlowMVIDSL -@Composable -public actual inline fun ImmutableStore.subscribe(): State = - subscribeDirect()