Room lifecycle state machine
Room lifecycle state machine
stateDiagram-v2
[*] --> Inactive
Inactive --> Active : shell activates (user navigates to room)
Active --> Inactive : shell deactivates (user navigates away)
Transitions
| From | To | Trigger | Notes |
|---|---|---|---|
| Inactive | Active | Shell activates | onActivate(ctx) called. Room receives RoomContext. |
| Active | Inactive | Shell deactivates | onDeactivate() called. Component stays mounted (hidden via CSS). |
Why only Inactive ↔ Active
Rooms are experience spaces, not browser tabs. A browser tab is a document that can be frozen, serialized, and restored at any time. A room is an interaction model — it has ephemeral state (scroll position, sub-view stack, search results, draft form input) that would need to be serialized and restored for suspend/resume to work correctly.
Suspend/resume exists for memory-constrained environments (mobile browsers, Electron apps with hundreds of tabs). Rymflux v1 is a desktop app with a small fixed number of rooms. There is no memory pressure that justifies serializing and restoring room state.
If keeping deactivated rooms fully mounted ever becomes a problem, the fix is lazy mounting (don’t mount until first activation), not suspend/resume — because a room’s state is its in-memory component tree, and serializing that tree is more complex than keeping it alive.
No Suspended state in v1. Deactivated rooms remain fully mounted in the DOM — Svelte components are hidden, not destroyed. This makes reactivation instant and avoids state serialization. Suspended would require memory pressure signals (which vary per OS and aren’t exposed cleanly by Tauri in v1) and a defined serialization contract for room state — that’s a v2 problem.
References
- ADR-009 (Room API TypeScript interface)
- FR-ROOM-1 (room registration and lifecycle)