fix(outbox): two tabs no longer overwrite each other's queue (#268) #430

Merged
jared merged 1 commits from fix/outbox-multi-tab into lotus 2026-10-19 15:31:01 -04:00
Owner

Fixes #268.

OutboxFeature loaded lotus_outbox_v1 once at mount, then saved its own in-memory list over the whole key on every change. A second tab's save therefore dropped the first tab's unsent messages, which never came back if the first tab closed or crashed.

Fix: persist() takes an update function. It re-reads the stored list, applies the change (add or remove by txnId), and writes the result. Since entries are only ever added or removed by txnId, that merges the tabs' changes correctly.

Verified (Playwright: two tabs in one profile, browser offline, each sends a message):

stored outbox after tab 1 sends A after tab 2 sends B
before [A] [B]: A lost
after [A] [A, B]

🤖 Generated with Claude Code

https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5

Fixes #268. `OutboxFeature` loaded `lotus_outbox_v1` once at mount, then saved **its own in-memory list** over the whole key on every change. A second tab's save therefore dropped the first tab's unsent messages, which never came back if the first tab closed or crashed. **Fix:** `persist()` takes an update function. It re-reads the stored list, applies the change (add or remove by txnId), and writes the result. Since entries are only ever added or removed by txnId, that merges the tabs' changes correctly. **Verified** (Playwright: two tabs in one profile, browser offline, each sends a message): | | stored outbox after tab 1 sends A | after tab 2 sends B | |---|---|---| | before | `[A]` | **`[B]`**: A lost | | after | `[A]` | **`[A, B]`** | 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
jared added 1 commit 2026-10-19 14:49:44 -04:00
fix(outbox): two tabs no longer overwrite each other's queue (#268)
CI / Build & Quality Checks (pull_request) Successful in 1m40s
CI / Trigger Desktop Build (pull_request) Skipped
CI / Docker image build & smoke test (pull_request) Skipped
CI / Secret scan (gitleaks) (pull_request) Successful in 6s
CI / Playwright smoke (e2e) (pull_request) Successful in 12m4s
97d2d195c3
OutboxFeature loaded lotus_outbox_v1 once and then saved its own
in-memory list over the key on every change, so a second tab's save
dropped the first tab's unsent messages. persist() now re-reads the
stored list and applies the change (add/remove by txnId) to it.

Fixes #268

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
jared merged commit 997df415dd into lotus 2026-10-19 15:31:01 -04:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: LotusGuild/cinny#430