Skip to content

Architecture ​

PulseDesktop follows the MVI (Model-View-Intent) pattern. It adds three coordination primitives: Broadcast, Unicast, and View Refresh.

Data Flow ​

Broadcast Flow ​

When multiple ViewModels need to react to the same event, use PulseContainer.broadcast():

Unicast Flow ​

When a child ViewModel needs to notify its parent Container, use PulseViewModel.unicast():

View Refresh Flow ​

Container.refresh() forces the Compose view tree to reconstruct. ViewModel states are preserved; only the Composables are re-created:

Component Responsibilities ​

ComponentResponsibility
PulseStateImmutable snapshot of UI data
PulseActionUser intent — what the user wants to do
PulseEventOne-time side effect — navigation, dialog, snackbar
PulseBroadcastCross-ViewModel notification from Container
PulseUnicastChild-to-parent notification from ViewModel
PulseViewModelOwns state; handles actions and broadcasts; can emit unicasts
PulseContainerCoordinates ViewModels; enables broadcast, unicast handling, and refresh
PulseHostCompose wrapper that propagates container key
PulseContentCompose wrapper that observes a ViewModel

Lifecycle ​

TIP

onSetup() runs once, when PulseContent first observes the ViewModel. The ViewModel stays active for as long as its ViewModelStoreOwner lives. A composition restart never repeats setup. Neither does refresh().

Which owner that is decides the ViewModel's lifetime.

  • Created under the host owner, it stays alive for the whole screen
  • Created inside a Navigation 3 destination, it is scoped to that back stack entry: covered by another destination it is kept, and popping the route cancels it

The demo builds every destination the second way. See Navigation 3.

Released under the Apache 2.0 License.