Snapshot of the in-memory state (also reflects the on-disk file at construction time). Returns a copy so callers can't mutate internal state by accident.
Push the room to the front of recentRooms (deduped by uri),
stamp lastJoinedAt to now, and persist. If the room is already
present, its existing displayName is preserved unless the new
call provides one.
Remove a room from
recentRooms(e.g. so the user can prune a stale entry). No-op if the URI isn't present.