Skip to content

WIP Support rememberSaveable #1274

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 3 commits into
base: zachklipp/render-composable
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ package com.squareup.sample.compose.nestedrenderings
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import com.squareup.sample.compose.databinding.LegacyViewBinding
import com.squareup.sample.compose.nestedrenderings.RecursiveWorkflow.LegacyRendering
import com.squareup.sample.compose.nestedrenderings.RecursiveWorkflow.Rendering
import com.squareup.workflow1.StatelessWorkflow
import com.squareup.workflow1.WorkflowExperimentalApi
import com.squareup.workflow1.renderComposable
import com.squareup.workflow1.ui.AndroidScreen
import com.squareup.workflow1.ui.Screen
import com.squareup.workflow1.ui.ScreenViewFactory
Expand Down Expand Up @@ -63,7 +64,7 @@ object RecursiveWorkflow : StatelessWorkflow<Unit, Nothing, Screen>() {
@OptIn(WorkflowUiExperimentalApi::class)
@Composable
private fun produceRendering(): Rendering {
var children by remember { mutableIntStateOf(0) }
var children by rememberSaveable { mutableIntStateOf(0) }

return Rendering(
children = List(children) { i ->
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
androidx.annotation:annotation-experimental:1.4.1
androidx.annotation:annotation-jvm:1.8.1
androidx.annotation:annotation:1.8.1
androidx.collection:collection-jvm:1.4.4
androidx.collection:collection:1.4.4
androidx.compose.runtime:runtime-android:1.7.6
androidx.compose.runtime:runtime-saveable-android:1.7.6
androidx.compose.runtime:runtime-saveable:1.7.6
androidx.compose.runtime:runtime:1.7.6
com.squareup.okio:okio-jvm:3.3.0
com.squareup.okio:okio:3.3.0
org.jetbrains.compose.annotation-internal:annotation:1.7.3
org.jetbrains.compose.collection-internal:collection:1.7.3
org.jetbrains.compose.runtime:runtime-saveable:1.7.3
org.jetbrains.compose.runtime:runtime:1.7.3
org.jetbrains.kotlin:kotlin-bom:1.9.24
org.jetbrains.kotlin:kotlin-stdlib-common:1.9.24
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.24
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.24
org.jetbrains.kotlin:kotlin-stdlib:1.9.24
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.7.3
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.7.3
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3
org.jetbrains.kotlinx:atomicfu-jvm:0.23.2
org.jetbrains.kotlinx:atomicfu:0.23.2
org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.8.1
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.1
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1
org.jetbrains:annotations:23.0.0
18 changes: 15 additions & 3 deletions workflow-config/config-jvm/dependencies/runtimeClasspath.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
androidx.annotation:annotation-jvm:1.8.0
androidx.annotation:annotation:1.8.0
androidx.collection:collection-jvm:1.4.0
androidx.collection:collection:1.4.0
com.squareup.okio:okio-jvm:3.3.0
com.squareup.okio:okio:3.3.0
org.jetbrains.compose.annotation-internal:annotation:1.7.3
org.jetbrains.compose.collection-internal:collection:1.7.3
org.jetbrains.compose.runtime:runtime-desktop:1.7.3
org.jetbrains.compose.runtime:runtime-saveable-desktop:1.7.3
org.jetbrains.compose.runtime:runtime-saveable:1.7.3
org.jetbrains.compose.runtime:runtime:1.7.3
org.jetbrains.kotlin:kotlin-bom:1.9.24
org.jetbrains.kotlin:kotlin-stdlib-common:1.9.24
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.24
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.24
org.jetbrains.kotlin:kotlin-stdlib:1.9.24
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.7.3
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.7.3
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3
org.jetbrains.kotlinx:atomicfu-jvm:0.23.2
org.jetbrains.kotlinx:atomicfu:0.23.2
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.8.1
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.1
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1
org.jetbrains:annotations:23.0.0
17 changes: 13 additions & 4 deletions workflow-core/dependencies/jsRuntimeClasspath.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
com.squareup.okio:okio-js:3.3.0
com.squareup.okio:okio:3.3.0
org.jetbrains.compose.annotation-internal:annotation-js:1.7.3
org.jetbrains.compose.annotation-internal:annotation:1.7.3
org.jetbrains.compose.collection-internal:collection-js:1.7.3
org.jetbrains.compose.collection-internal:collection:1.7.3
org.jetbrains.compose.runtime:runtime-js:1.7.3
org.jetbrains.compose.runtime:runtime-saveable-js:1.7.3
org.jetbrains.compose.runtime:runtime-saveable:1.7.3
org.jetbrains.compose.runtime:runtime:1.7.3
org.jetbrains.kotlin:kotlin-bom:1.9.24
org.jetbrains.kotlin:kotlin-dom-api-compat:1.9.24
org.jetbrains.kotlin:kotlin-stdlib-js:1.9.24
org.jetbrains.kotlin:kotlin-stdlib:1.9.24
org.jetbrains.kotlin:kotlinx-atomicfu-runtime:1.8.20
org.jetbrains.kotlinx:atomicfu-js:0.21.0
org.jetbrains.kotlinx:kotlinx-coroutines-core-js:1.7.3
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3
org.jetbrains.kotlin:kotlinx-atomicfu-runtime:1.9.24
org.jetbrains.kotlinx:atomicfu-js:0.23.2
org.jetbrains.kotlinx:atomicfu:0.23.2
org.jetbrains.kotlinx:kotlinx-coroutines-core-js:1.8.0
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0
18 changes: 15 additions & 3 deletions workflow-core/dependencies/jvmRuntimeClasspath.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
androidx.annotation:annotation-jvm:1.8.0
androidx.annotation:annotation:1.8.0
androidx.collection:collection-jvm:1.4.0
androidx.collection:collection:1.4.0
com.squareup.okio:okio-jvm:3.3.0
com.squareup.okio:okio:3.3.0
org.jetbrains.compose.annotation-internal:annotation:1.7.3
org.jetbrains.compose.collection-internal:collection:1.7.3
org.jetbrains.compose.runtime:runtime-desktop:1.7.3
org.jetbrains.compose.runtime:runtime-saveable-desktop:1.7.3
org.jetbrains.compose.runtime:runtime-saveable:1.7.3
org.jetbrains.compose.runtime:runtime:1.7.3
org.jetbrains.kotlin:kotlin-bom:1.9.24
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.24
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.24
org.jetbrains.kotlin:kotlin-stdlib:1.9.24
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.7.3
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.7.3
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3
org.jetbrains.kotlinx:atomicfu-jvm:0.23.2
org.jetbrains.kotlinx:atomicfu:0.23.2
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.8.0
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.0
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0
org.jetbrains:annotations:23.0.0
18 changes: 15 additions & 3 deletions workflow-core/dependencies/runtimeClasspath.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
androidx.annotation:annotation-jvm:1.8.0
androidx.annotation:annotation:1.8.0
androidx.collection:collection-jvm:1.4.0
androidx.collection:collection:1.4.0
com.squareup.okio:okio-jvm:3.3.0
com.squareup.okio:okio:3.3.0
org.jetbrains.compose.annotation-internal:annotation:1.7.3
org.jetbrains.compose.collection-internal:collection:1.7.3
org.jetbrains.compose.runtime:runtime-desktop:1.7.3
org.jetbrains.compose.runtime:runtime-saveable-desktop:1.7.3
org.jetbrains.compose.runtime:runtime-saveable:1.7.3
org.jetbrains.compose.runtime:runtime:1.7.3
org.jetbrains.kotlin:kotlin-bom:1.9.24
org.jetbrains.kotlin:kotlin-stdlib-common:1.9.24
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.24
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.24
org.jetbrains.kotlin:kotlin-stdlib:1.9.24
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.7.3
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.7.3
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3
org.jetbrains.kotlinx:atomicfu-jvm:0.23.2
org.jetbrains.kotlinx:atomicfu:0.23.2
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.8.0
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.0
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0
org.jetbrains:annotations:23.0.0
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,17 @@ public interface BaseRenderContext<out PropsT, StateT, in OutputT> {
* being sent to this context's [actionSink]. However, it's important for the composable never to
* send to [actionSink] directly because we need to ensure that any state writes the composable
* does invalidate their composables before sending into the [actionSink].
*
* Any state saved using Compose's state restoration mechanism (e.g. [rememberSaveable]) will be
* saved and restored using the workflow snapshot mechanism.
*/
@WorkflowExperimentalApi
public fun <ChildOutputT, ChildRenderingT> renderComposable(
key: String = "",
handler: (ChildOutputT) -> WorkflowAction<PropsT, StateT, OutputT>,
content: @WorkflowComposable @Composable (
content:
@WorkflowComposable @Composable
(
emitOutput: (ChildOutputT) -> Unit
) -> ChildRenderingT
): ChildRenderingT
Expand Down Expand Up @@ -404,9 +409,11 @@ public fun <PropsT, StateT, OutputT, ChildRenderingT>
@WorkflowExperimentalApi
public fun <PropsT, StateT, OutputT, ChildRenderingT>
BaseRenderContext<PropsT, StateT, OutputT>.renderComposable(
key: String = "",
content: @WorkflowComposable @Composable () -> ChildRenderingT
): ChildRenderingT = renderComposable<Nothing, ChildRenderingT>(
key: String = "",
content:
@WorkflowComposable @Composable
() -> ChildRenderingT
): ChildRenderingT = renderComposable<Nothing, ChildRenderingT>(
key = key,
handler = { noAction() },
content = { content() }
Expand Down
5 changes: 5 additions & 0 deletions workflow-runtime/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import com.squareup.workflow1.buildsrc.iosWithSimulatorArm64
plugins {
id("kotlin-multiplatform")
id("published")
// TODO add android target so we can auto-save Parcelables from SaveableStateRegistry.
// id("com.android.library")
id("org.jetbrains.compose") version "1.6.11"
}

Expand All @@ -17,6 +19,9 @@ kotlin {
if (targets == "kmp" || targets == "js") {
js(IR) { browser() }
}
// if (targets == "kmp" || targets == "android") {
// androidTarget()
// }
sourceSets {
getByName("commonMain") {
dependencies {
Expand Down
17 changes: 13 additions & 4 deletions workflow-runtime/dependencies/jsRuntimeClasspath.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
com.squareup.okio:okio-js:3.3.0
com.squareup.okio:okio:3.3.0
org.jetbrains.compose.annotation-internal:annotation-js:1.7.3
org.jetbrains.compose.annotation-internal:annotation:1.7.3
org.jetbrains.compose.collection-internal:collection-js:1.7.3
org.jetbrains.compose.collection-internal:collection:1.7.3
org.jetbrains.compose.runtime:runtime-js:1.7.3
org.jetbrains.compose.runtime:runtime-saveable-js:1.7.3
org.jetbrains.compose.runtime:runtime-saveable:1.7.3
org.jetbrains.compose.runtime:runtime:1.7.3
org.jetbrains.kotlin:kotlin-bom:1.9.24
org.jetbrains.kotlin:kotlin-dom-api-compat:1.9.24
org.jetbrains.kotlin:kotlin-stdlib-js:1.9.24
org.jetbrains.kotlin:kotlin-stdlib:1.9.24
org.jetbrains.kotlin:kotlinx-atomicfu-runtime:1.8.20
org.jetbrains.kotlinx:atomicfu-js:0.21.0
org.jetbrains.kotlinx:kotlinx-coroutines-core-js:1.7.3
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3
org.jetbrains.kotlin:kotlinx-atomicfu-runtime:1.9.24
org.jetbrains.kotlinx:atomicfu-js:0.23.2
org.jetbrains.kotlinx:atomicfu:0.23.2
org.jetbrains.kotlinx:kotlinx-coroutines-core-js:1.8.1
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1
18 changes: 15 additions & 3 deletions workflow-runtime/dependencies/jvmRuntimeClasspath.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
androidx.annotation:annotation-jvm:1.8.0
androidx.annotation:annotation:1.8.0
androidx.collection:collection-jvm:1.4.0
androidx.collection:collection:1.4.0
com.squareup.okio:okio-jvm:3.3.0
com.squareup.okio:okio:3.3.0
org.jetbrains.compose.annotation-internal:annotation:1.7.3
org.jetbrains.compose.collection-internal:collection:1.7.3
org.jetbrains.compose.runtime:runtime-desktop:1.7.3
org.jetbrains.compose.runtime:runtime-saveable-desktop:1.7.3
org.jetbrains.compose.runtime:runtime-saveable:1.7.3
org.jetbrains.compose.runtime:runtime:1.7.3
org.jetbrains.kotlin:kotlin-bom:1.9.24
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.24
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.24
org.jetbrains.kotlin:kotlin-stdlib:1.9.24
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.7.3
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.7.3
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3
org.jetbrains.kotlinx:atomicfu-jvm:0.23.2
org.jetbrains.kotlinx:atomicfu:0.23.2
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.8.1
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.1
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1
org.jetbrains:annotations:23.0.0
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import kotlin.LazyThreadSafetyMode.NONE
*/
public class TreeSnapshot internal constructor(
workflowSnapshot: Snapshot?,
childTreeSnapshots: () -> Map<WorkflowNodeId, TreeSnapshot>
childTreeSnapshots: () -> Map<ByteString, TreeSnapshot>
) {
/**
* The [Snapshot] for the root workflow, or null if that snapshot was empty or unspecified.
Expand All @@ -35,7 +35,7 @@ public class TreeSnapshot internal constructor(
* The map of child snapshots by child [WorkflowNodeId]. Computed lazily so the entire snapshot
* tree isn't parsed upfront.
*/
internal val childTreeSnapshots: Map<WorkflowNodeId, TreeSnapshot>
internal val childTreeSnapshots: Map<ByteString, TreeSnapshot>
by lazy(NONE, childTreeSnapshots)

/**
Expand All @@ -49,11 +49,10 @@ public class TreeSnapshot internal constructor(
sink.writeByteStringWithLength(workflowSnapshot?.bytes ?: ByteString.EMPTY)
val childBytes: List<Pair<ByteString, ByteString>> =
childTreeSnapshots.mapNotNull { (childId, childSnapshot) ->
val childIdBytes = childId.toByteStringOrNull() ?: return@mapNotNull null
val childSnapshotBytes = childSnapshot.toByteString()
.takeUnless { it.size == 0 }
?: return@mapNotNull null
return@mapNotNull Pair(childIdBytes, childSnapshotBytes)
return@mapNotNull Pair(childId, childSnapshotBytes)
}
sink.writeInt(childBytes.size)
childBytes.forEach { (childIdBytes, childSnapshotBytes) ->
Expand Down Expand Up @@ -104,9 +103,8 @@ public class TreeSnapshot internal constructor(
buildMap(childSnapshotCount) {
for (i in 0 until childSnapshotCount) {
val idBytes = source.readByteStringWithLength()
val id = WorkflowNodeId.parse(idBytes)
val childSnapshot = source.readByteStringWithLength()
this[id] = parse(childSnapshot)
this[idBytes] = parse(childSnapshot)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,9 @@ private class InterceptedRenderContext<P, S, O>(
override fun <ChildOutputT, ChildRenderingT> renderComposable(
key: String,
handler: (ChildOutputT) -> WorkflowAction<P, S, O>,
content: @WorkflowComposable @Composable (emitOutput: (ChildOutputT) -> Unit) -> ChildRenderingT
content:
@WorkflowComposable @Composable
(emitOutput: (ChildOutputT) -> Unit) -> ChildRenderingT
): ChildRenderingT = interceptor.onRenderComposable(
key = key,
content = content,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ internal class RealRenderContext<out PropsT, StateT, OutputT>(
override fun <ChildOutputT, ChildRenderingT> renderComposable(
key: String,
handler: (ChildOutputT) -> WorkflowAction<PropsT, StateT, OutputT>,
content: @WorkflowComposable @Composable (emitOutput: (ChildOutputT) -> Unit) -> ChildRenderingT
content:
@WorkflowComposable @Composable
(emitOutput: (ChildOutputT) -> Unit) -> ChildRenderingT
): ChildRenderingT {
checkNotFrozen()
return renderer.renderComposable(key, handler, content)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import com.squareup.workflow1.WorkflowTracer
import com.squareup.workflow1.identifier
import com.squareup.workflow1.trace
import kotlinx.coroutines.selects.SelectBuilder
import okio.ByteString
import kotlin.coroutines.CoroutineContext

/**
Expand Down Expand Up @@ -87,7 +88,7 @@ import kotlin.coroutines.CoroutineContext
* first time, they are also restored from their snapshots.
*/
internal class SubtreeManager<PropsT, StateT, OutputT>(
private var snapshotCache: Map<WorkflowNodeId, TreeSnapshot>?,
private var snapshotCache: Map<ByteString, TreeSnapshot>?,
private val contextForChildren: CoroutineContext,
private val emitActionToParent: (
action: WorkflowAction<PropsT, StateT, OutputT>,
Expand All @@ -99,7 +100,7 @@ internal class SubtreeManager<PropsT, StateT, OutputT>(
private val interceptor: WorkflowInterceptor = NoopWorkflowInterceptor,
private val idCounter: IdCounter? = null,
private val requestRerender: () -> Unit = {},
private val sendActionFromComposable: (WorkflowAction<PropsT,StateT,OutputT>) -> Unit
private val sendActionFromComposable: (WorkflowAction<PropsT, StateT, OutputT>) -> Unit
) : RealRenderContext.Renderer<PropsT, StateT, OutputT> {
private var children = ActiveStagingList<WorkflowChildNode<*, *, *, *, *>>()
private var composables = ActiveStagingList<WorkflowComposableNode<*, *, *, *, *>>()
Expand Down Expand Up @@ -189,12 +190,18 @@ internal class SubtreeManager<PropsT, StateT, OutputT>(
return empty
}

fun createChildSnapshots(): Map<WorkflowNodeId, TreeSnapshot> {
val snapshots = mutableMapOf<WorkflowNodeId, TreeSnapshot>()
fun createChildSnapshots(): Map<ByteString, TreeSnapshot> {
val snapshots = mutableMapOf<ByteString, TreeSnapshot>()
children.forEachActive { child ->
val childWorkflow = child.workflow.asStatefulWorkflow()
// Skip children who aren't snapshottable.
snapshots[child.id] = child.workflowNode.snapshot(childWorkflow)
val childIdBytes = child.id.toByteStringOrNull() ?: return@forEachActive
snapshots[childIdBytes] = child.workflowNode.snapshot(childWorkflow)
}
composables.forEachActive { composable ->
val childIdBytes = composable.getIdBytes()
val childSnapshot = composable.snapshot()
snapshots[childIdBytes] = TreeSnapshot(childSnapshot, childTreeSnapshots = ::emptyMap)
}
return snapshots
}
Expand All @@ -217,7 +224,7 @@ internal class SubtreeManager<PropsT, StateT, OutputT>(
return emitActionToParent(action, actionResult)
}

val childTreeSnapshots = snapshotCache?.get(id)
val childTreeSnapshots = snapshotCache?.get(id.toByteStringOrNull())

val workflowNode = WorkflowNode(
id = id,
Expand All @@ -240,9 +247,13 @@ internal class SubtreeManager<PropsT, StateT, OutputT>(
key: String,
handler: (ChildOutputT) -> WorkflowAction<PropsT, StateT, OutputT>,
): WorkflowComposableNode<ChildOutputT, ChildRenderingT, PropsT, StateT, OutputT> {
val composableId = WorkflowComposableNode.idFromKey(key)
val composableTreeSnapshot: TreeSnapshot? = snapshotCache?.get(composableId)

return WorkflowComposableNode<ChildOutputT, ChildRenderingT, PropsT, StateT, OutputT>(
workflowKey = key,
handler = handler,
snapshot = composableTreeSnapshot?.workflowSnapshot,
coroutineContext = contextForChildren,
requestRerender = requestRerender,
sendAction = sendActionFromComposable,
Expand Down
Loading
Loading