Architecture
PulseMVI follows the MVI (Model-View-Intent) pattern and adds two Desktop-specific primitives: Broadcast and View Refresh.
Data Flow
┌─────────────────────────────────────────────────────┐
│ Compose UI │
│ │
│ User Interaction │
│ │ │
│ ▼ │
│ onAction(action) ──────────▶ PulseStore │
│ │ │
│ onAction() │
│ │ │
│ update { } │
│ │ │
│ StateFlow<State> │
│ │ │
│ ◀──────────────────────────── │ │
│ PulseContent re-renders │ │
│ │ │
│ event(effect) │
│ │ │
│ ◀──────────── onEvent ──────── │ │
│ Handle side effect │
└─────────────────────────────────────────────────────┘Broadcast Flow
When multiple Stores need to react to the same event, use PulseContainer.broadcast():
Container.broadcast(MyBroadcast.Sync)
│
├──▶ StoreA.onReceive(Sync) ──▶ update { } ──▶ UI re-renders
│
└──▶ StoreB.onReceive(Sync) ──▶ update { } ──▶ UI re-rendersView Refresh Flow
Container.refresh() forces the Compose view tree to reconstruct. Store states are preserved — only the Composables are re-created:
Container.refresh()
│
└──▶ PulseApp detects new key
│
└──▶ PulseContent re-created (via `key()`)
│
└──▶ Store.cancel() then Store re-subscribes
│
└──▶ onSetup() called againComponent Responsibilities
| Component | Responsibility |
|---|---|
PulseState | Immutable snapshot of UI data |
PulseAction | User intent — what the user wants to do |
PulseEvent | One-time side effect — navigation, dialog, snackbar |
PulseBroadcast | Cross-Store notification from Container |
PulseStore | Owns state; handles actions and broadcasts |
PulseContainer | Coordinates Stores; enables broadcast and refresh |
PulseApp | Compose wrapper that propagates container key |
PulseContent | Compose wrapper that observes a Store |
Lifecycle
PulseContent appears
│
└──▶ Store.state subscribed ──▶ onSetup() called
│
coroutineScope active
PulseContent disappears
│
└──▶ Store.cancel() called
│
└──▶ coroutineScope cancelled + recreated
(Store is ready to be reused)TIP
onSetup() is called every time the Store is first subscribed to — including after a refresh(). Use it to start your data-collection coroutines.