StatefulWorkflow

A composable, stateful object that can handle events, delegate to children, subscribe to arbitrary asynchronous events from the outside world, and be saved to a serialized form to be restored later.

The basic purpose of a Workflow is to take some props and return a rendering that serves as a public representation of its current state, and which can be used to update that state. A rendering typically serves as a view model, though this is not assumed, and is not the only use case.

To that end, a workflow may keep track of internal state, recursively ask other workflows to render themselves, subscribe to data streams from the outside world, and handle events both from its renderings and from workflows it's delegated to (its "children"). A Workflow may also emit output events up to its parent Workflow.

Workflows form a tree, where each workflow can have zero or more child workflows. Child workflows are started as necessary whenever another workflow asks for them, and are cleaned up automatically when they're no longer needed. Props propagate down the tree, outputs and renderings propagate up the tree.

Avoid capturing stale state

Workflows may not perform side effects in their render methods, but may perform side effects by running Workers and getting events from RenderingTs via WorkflowActions. A WorkflowAction defines how to update the StateT and what OutputTs to emit. Actions get access to the current workflow's state, and they must use that view of the state. If an action is defined inline, it is incorrect to capture, or close over, the StateT passed to render in the action. Workflows are executed synchronously, but external events may not be, so captured state may be stale when the action is invoked.

Parameters

PropsT

Typically a data class that is used to pass configuration information or bits of state that the workflow can always get from its parent and needn't duplicate in its own state. May be Unit if the workflow does not need any props data.

StateT

Typically a data class that contains all of the internal state for this workflow. The state is seeded via props in initialState. It can be serialized and later used to restore the workflow. Implementations of the Workflow interface should not generally contain their own state directly. They may inject objects like instances of their child workflows, or network clients, but should not contain directly mutable state. This is the only type parameter that a parent workflow needn't care about for its children, and may just use star (*) instead of specifying it. May be Unit if the workflow does not have any internal state (see StatelessWorkflow).

OutputT

Typically a sealed class that represents "events" that this workflow can send to its parent. May be Nothing if the workflow doesn't need to emit anything.

RenderingT

The value returned to this workflow's parent during composition. Typically represents a "view" of this workflow's props, current state, and children's renderings. A workflow that represents a UI component may use a view model as its rendering type.

See also

Inheritors

Constructors

Link copied to clipboard
constructor()

Types

Link copied to clipboard

Properties

Link copied to clipboard

Use a lazy delegate so that any ImpostorWorkflow.realIdentifier will have been computed before this is initialized and cached.

Link copied to clipboard

The computed WorkflowIdentifier for this Workflow. Any IdCacheable Workflow should call this and then store the value in the cachedIdentifier property so as to prevent the extra work needed to create the WorkflowIdentifier and look up the class name each time.

Link copied to clipboard

The WorkflowIdentifier that identifies this Workflow.

Functions

Link copied to clipboard

Convenience to create a WorkflowAction with parameter types matching those of the receiving StatefulWorkflow. The action will invoke the given lambda when it is applied.

Link copied to clipboard

Satisfies the Workflow interface by returning this.

Link copied to clipboard
abstract fun initialState(props: PropsT, snapshot: Snapshot?): StateT

Called from RenderContext.renderChild when the state machine is first started, to get the initial state.

open fun initialState(props: PropsT, snapshot: Snapshot?, workflowScope: CoroutineScope): StateT
Link copied to clipboard
Link copied to clipboard
open fun onPropsChanged(old: PropsT, new: PropsT, state: StateT): StateT

Called from RenderContext.renderChild instead of initialState when the workflow is already running. This allows the workflow to detect changes in props, and possibly change its state in response. This method is called only if the new props value is not == with the old.

Link copied to clipboard
abstract fun render(renderProps: PropsT, renderState: StateT, context: StatefulWorkflow.RenderContext<PropsT, StateT, OutputT, RenderingT>): RenderingT

Called at least once† any time one of the following things happens:

Link copied to clipboard
abstract fun snapshotState(state: StateT): Snapshot?

Called whenever the state changes to generate a new Snapshot of the state.