You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Keep an account's inbox live-updating only while it has a tab open — not for every authenticated account in the background
Background
Today, each tab opens one EventSource to /api/v1/events while isAuthenticated && inboxName is true. The backend (realtime.Hub, server/internal/realtime/hub.go) keeps one ref-counted IMAP IDLE connection per watched mailbox per session, torn down when the last subscriber disconnects — no backend changes are needed, this is entirely a frontend subscription-lifecycle change.
Scope (revised — significantly smaller than originally spec'd, and now effectively closed)
Because #23's window.open named-target change means each account maps to exactly one tab for its entire life (no in-place switching between already-linked accounts anymore), ref-counting and cross-tab liveness tracking are no longer required for correctness: a tab's own mount/unmount already is that account's "opened"/"closed" signal, and DataContext's existing per-tab EventSource effect (opens while isAuthenticated && inboxName, closes on unmount) already satisfies "only accounts with a tab open stay live" as-is, with no changes needed.
The one remaining in-place transition (#29 — addAccount reassigning an already-active tab from one account to another) also turned out not to need any new hook API: #29's fix resets inboxName back to "" the instant the active account changes, which already forces the existing realtime effect to close the old account's EventSource and reopen a fresh one (reading the new session's token) once the new account's inbox name resolves. So there is no onAccountOpened/onAccountClosed callback to wire into — the mechanism is automatic.
Handle connection lifecycle: reconnect on drop, teardown on logout/session removal (coordinate with Account Lifecycle Management: remove account, sign out everywhere, and session expiry/re-auth #25 — when 5.1 removes an account or 5.2 invalidates its session, this issue's subscription for that account must also close). This piece is still open — confirm today's EventSource/isAuthenticated wiring already covers it, or file the small remaining piece separately.
Scoped to each account's default/inbox mailbox only, matching what a single-account tab watches today — already true today, no change needed.
Cut from scope: the cross-tab liveness heartbeat (localStorage/BroadcastChannel, crash/force-quit detection) originally planned here. It solved "does this account have a tab open somewhere" for ref-counting a shared subscription — a problem that no longer exists once an account maps to at most one tab. If a future need arises for showing a "currently open elsewhere" indicator in the switcher UI, that's a cosmetic addition, not a functional dependency, and can be scoped separately then.
Acceptance criteria
Opening account A's tab starts a live subscription for A; accounts with no open tab receive no updates until opened (already true today via DataContext's existing per-tab effect).
Closing an account's only tab tears down its subscription (already true today via unmount cleanup).
No backend changes required — confirmed existing Hub ref-counting behavior is sufficient as-is.
Files likely touched
None expected beyond what #29 already covers — revisit only if #25's removal/invalidation flow surfaces a gap.
Dependencies
Depends on #22 (switch-flow hook points — resolved without new API, see #29) and #23 (tab-open/close is driven by the switcher's window.open behavior).
Goal
Keep an account's inbox live-updating only while it has a tab open — not for every authenticated account in the background
Background
Today, each tab opens one
EventSourceto/api/v1/eventswhileisAuthenticated && inboxNameis true. The backend (realtime.Hub,server/internal/realtime/hub.go) keeps one ref-counted IMAP IDLE connection per watched mailbox per session, torn down when the last subscriber disconnects — no backend changes are needed, this is entirely a frontend subscription-lifecycle change.Scope (revised — significantly smaller than originally spec'd, and now effectively closed)
Because #23's
window.opennamed-target change means each account maps to exactly one tab for its entire life (no in-place switching between already-linked accounts anymore), ref-counting and cross-tab liveness tracking are no longer required for correctness: a tab's own mount/unmount already is that account's "opened"/"closed" signal, andDataContext's existing per-tabEventSourceeffect (opens whileisAuthenticated && inboxName, closes on unmount) already satisfies "only accounts with a tab open stay live" as-is, with no changes needed.The one remaining in-place transition (#29 —
addAccountreassigning an already-active tab from one account to another) also turned out not to need any new hook API: #29's fix resetsinboxNameback to""the instant the active account changes, which already forces the existing realtime effect to close the old account'sEventSourceand reopen a fresh one (reading the new session's token) once the new account's inbox name resolves. So there is noonAccountOpened/onAccountClosedcallback to wire into — the mechanism is automatic.Wire into Implement— not needed, see above. ImplementswitchAccount(): state reset, cache hydration, and background sync for the addAccount in-place switch #29'sonAccountOpened/onAccountClosedhook pointsswitchAccount(): state reset, cache hydration, and background sync for the addAccount in-place switch #29 already lands this issue's entire functional requirement as a side effect of its own fix.EventSource/isAuthenticatedwiring already covers it, or file the small remaining piece separately.localStorage/BroadcastChannel, crash/force-quit detection) originally planned here. It solved "does this account have a tab open somewhere" for ref-counting a shared subscription — a problem that no longer exists once an account maps to at most one tab. If a future need arises for showing a "currently open elsewhere" indicator in the switcher UI, that's a cosmetic addition, not a functional dependency, and can be scoped separately then.Acceptance criteria
DataContext's existing per-tab effect).addAccount-driven in-place transition (ImplementswitchAccount(): state reset, cache hydration, and background sync for the addAccount in-place switch #29) correctly closes the old account's subscription and opens the new one's without a page reload (confirmed as an automatic side effect of ImplementswitchAccount(): state reset, cache hydration, and background sync for the addAccount in-place switch #29'sinboxNamereset).Hubref-counting behavior is sufficient as-is.Files likely touched
None expected beyond what #29 already covers — revisit only if #25's removal/invalidation flow surfaces a gap.
Dependencies
Depends on #22 (switch-flow hook points — resolved without new API, see #29) and #23 (tab-open/close is driven by the switcher's
window.openbehavior).Sub-issues
switchAccount(): state reset, cache hydration, and background sync for the addAccount in-place switch #29, no separate implementation needed.