Anthony 1b9a517b43 Realtime sync via the SDK event bus, drop the periodic poll
The 60s list-sync loop is replaced by the WebSocket event bus from the
SDK (sdk-event-bus). On startup the syncer still does Phase 0 (load the
local store into memory), then a one-shot bootstrap sync only if no
event-bus catch-up state is cached. From there on:

- `EventBusClient` runs in its own task, streams `EventBusMessage`s into
  an mpsc channel and reconnects with backoff.
- `event_handler` consumes the channel: MailSetEntry CREATE/DELETE
  triggers a targeted `sync_folder` for the affected folder; Mail UPDATE
  refreshes metadata in place; Mail DELETE drops the cache + .eml.
- After each batch the `(group_id, batch_id)` is persisted in the new
  `event_bus_state` SQLite table (schema bumped to v4) and mirrored in
  the bus's in-memory map, so the next reconnect resumes catch-up via
  `groupsToLastEventBatchIds`.

`stop()` aborts and awaits the new bus + handler tasks alongside the
existing syncer/IMAP/SMTP teardown, so ports release before the next
start rebinds them.

138/138 bridge unit tests pass (incl. 2 new ones for the event-bus state
table). End-to-end behaviour to be verified against the live server.
2026-05-28 12:02:18 +02:00
Languages
Rust 89.5%
TypeScript 5.9%
CSS 2.5%
Python 1.2%
Shell 0.7%
Other 0.1%