@bobfrankston/rmfmail 1.1.250 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/android-bootstrap.bundle.js +12 -3
- package/client/android-bootstrap.bundle.js.map +1 -1
- package/client/app.bundle.js +12 -11
- package/client/app.bundle.js.map +2 -2
- package/client/app.js +11 -13
- package/client/app.js.map +1 -1
- package/client/app.ts +10 -12
- package/client/compose/compose.bundle.js +12 -3
- package/client/compose/compose.bundle.js.map +1 -1
- package/docs/architecture-review.md +182 -0
- package/docs/clean-architecture.md +161 -0
- package/package.json +1 -1
- package/packages/mailx-api/index.d.ts.map +1 -1
- package/packages/mailx-api/index.js +8 -5
- package/packages/mailx-api/index.js.map +1 -1
- package/packages/mailx-api/index.ts +8 -5
- package/packages/mailx-service/db-worker.js +5 -1
- package/packages/mailx-service/db-worker.js.map +1 -1
- package/packages/mailx-service/db-worker.ts +5 -1
- package/packages/mailx-service/index.d.ts +18 -1
- package/packages/mailx-service/index.d.ts.map +1 -1
- package/packages/mailx-service/index.js +67 -7
- package/packages/mailx-service/index.js.map +1 -1
- package/packages/mailx-service/index.ts +76 -7
- package/packages/mailx-store/db.d.ts +7 -1
- package/packages/mailx-store/db.d.ts.map +1 -1
- package/packages/mailx-store/db.js +26 -1
- package/packages/mailx-store/db.js.map +1 -1
- package/packages/mailx-store/db.ts +27 -1
- package/test/phase0-readworker.mjs +185 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# rmfmail / mailx — Architecture Review
|
|
2
|
+
|
|
3
|
+
**Date:** 2026-06-12
|
|
4
|
+
**Author:** Claude (Opus 4.8), at Bob's request, after a day where each fix surfaced the next failure.
|
|
5
|
+
**Status:** Diagnosis for independent audit. No code changed by this document.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 0. How to use this document (instructions to the reviewing model)
|
|
10
|
+
|
|
11
|
+
You are being handed this to **audit, not echo**. For each numbered finding below:
|
|
12
|
+
|
|
13
|
+
1. Open the cited file(s) and **verify the claim against the actual code**. Line numbers are as of 2026-06-12 and may have drifted — confirm by content, not line number.
|
|
14
|
+
2. Mark each finding **CONFIRMED / PARTIALLY-CONFIRMED / WRONG**, and say *why* with your own file:line evidence.
|
|
15
|
+
3. Call out anything this review **overstates, misattributes, or misses**. The author was firefighting all day and may have pattern-matched. Be adversarial.
|
|
16
|
+
4. The repo root is `Y:/dev/email/mailx/app/` (note: code lives under `app/`; the top-level dir is not the git repo). Desktop packages are under `app/packages/`; the browser/Android variant is `app/packages/mailx-store-web`; the UI is `app/client/`.
|
|
17
|
+
|
|
18
|
+
The goal is a **correct** assessment of whether these are architectural faults or incidental bugs, and whether the proposed refactor sequence (§6) is right.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 1. Executive summary
|
|
23
|
+
|
|
24
|
+
The recurring failures (messages reappearing/not disappearing after delete, ghost copies, stars on the wrong message, a 70k-row wipe on 2026-05-27, the list "summary" timing out while the preview works, folder-create silently failing, "AggregateError", search returning nothing or everything) are **not independent bugs**. They are symptoms of a small number of structural decisions:
|
|
25
|
+
|
|
26
|
+
- **No isolation between local reads and network I/O** — a remote stall blocks local-only operations (the list times out).
|
|
27
|
+
- **A claimed-but-unfinished local-first model** — `CLAUDE.md` itself flags the reconciliation refactor as Priority 0 / incomplete.
|
|
28
|
+
- **Message identity is overloaded** — per-folder IMAP UID is used as identity in many places, despite a stable `uuid` column existing.
|
|
29
|
+
- **No single mutation funnel** — the same logical operation (delete/move/trash) is implemented ~21 times across 6 packages, including a dead duplicate and divergent desktop/Android copies.
|
|
30
|
+
- **Search is three different query languages behind one box.**
|
|
31
|
+
|
|
32
|
+
Comparison point: Thunderbird/Outlook don't exhibit these because they (a) keep the UI/read path strictly off the network thread and (b) have one canonical store + one message-identity. rmfmail's debt is in exactly those two places.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 2. The triggering symptom (verify first — it's the clearest signal)
|
|
37
|
+
|
|
38
|
+
**Observed:** the message list shows `Error: mailxapi timeout: getUnifiedInbox` while the preview pane successfully renders a message.
|
|
39
|
+
|
|
40
|
+
**Why this is diagnostic:** `getUnifiedInbox` is a **local SQLite read** (`packages/mailx-store/db.ts`, `getUnifiedInbox(...)`, and `packages/mailx-service` → `store.getUnifiedInbox`). It should never touch the network and should be sub-millisecond. For it to **time out** with an IPC-level `mailxapi timeout`, a pure-local read must be **queued behind a slow/hung network operation**. That is only possible if reads and network writes share one serialized pipe (see Finding #1).
|
|
41
|
+
|
|
42
|
+
**Verify:** trace `getUnifiedInbox` from the client (`client/lib/api-client.ts`) through the IPC pump (`bin/mailx.ts`) to `MailxService` and `MailxDB`. Confirm there is no network call on that path, and confirm the IPC pump serializes it behind other handlers.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## 3. Finding 1 — Single serialized IPC pump; no read/network isolation (root cause of the timeouts)
|
|
47
|
+
|
|
48
|
+
**Claim:** All IPC requests (interactive reads, deletes, sync, prefetch) are dispatched through one serialized `await dispatch(...)`. One slow handler blocks every subsequent call, including local-only reads.
|
|
49
|
+
|
|
50
|
+
**Evidence:**
|
|
51
|
+
- `bin/mailx.ts` (~lines 2049–2140): a single `handle.onRequest()` callback does `await dispatch(svc, req)` per request, serially. No concurrency, no per-action timeout, no priority lane at this layer.
|
|
52
|
+
- `packages/mailx-service/jsonrpc.ts:34–42`: `dispatch()` has **no timeout wrapper** and awaits the service method directly.
|
|
53
|
+
- `packages/mailx-imap/index.ts`: there IS a dual-lane connection model (`opsClients`/`fastClients`, `opsQueues` fast/slow, a per-host semaphore `HOST_PERMITS = 4`, ~lines 484–662) and per-op timeouts (`withTimeout`, fast 90s / slow 300s). **But** that isolation is *below* the IPC pump — it does not prevent a slow service method from holding the single dispatch await.
|
|
54
|
+
- Documented in code: `packages/mailx-imap/index.ts` ~2873 — "one un-fetchable message … each attempt hanging ~90s and tying up the ops queue, so user actions (delete, open) were delayed."
|
|
55
|
+
|
|
56
|
+
**Impact:** A single hung IMAP operation (today: UID 4966060 body fetch) cascades into delete timeouts, folder-create failures, `AggregateError` on new connections (host-permit exhaustion), and the `getUnifiedInbox` list timeout. These were *one* congestion event, not many bugs.
|
|
57
|
+
|
|
58
|
+
**How to verify:** Confirm `bin/mailx.ts` awaits dispatch serially. Confirm no read-only fast path that bypasses IMAP-touching handlers. Confirm whether any RPC method that should be local-only (`getMessages`, `getUnifiedInbox`, search-from-cache) can transitively `await` an IMAP call.
|
|
59
|
+
|
|
60
|
+
**This is the highest-leverage fix (see §6.1).**
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## 4. Finding 2 — Local-first is half-wired
|
|
65
|
+
|
|
66
|
+
**Claim:** The design states "local store is source of truth; server is async-reconciled mirror," but several reads/writes still block on the daemon/IMAP, and the reconciliation refactor is explicitly unfinished.
|
|
67
|
+
|
|
68
|
+
**Evidence:**
|
|
69
|
+
- `CLAUDE.md` (project root) — "CRITICAL: Local-first" section and the note that the **Priority 0 "Local-first reconciliation refactor"** is the load-bearing unfinished work; several user-visible bugs are called out as symptoms of the violation.
|
|
70
|
+
- `docs/local-first-plan.md` — the plan; check how much is implemented vs aspirational.
|
|
71
|
+
- Truly local-first today (commit local + queue): `packages/mailx-service/index.ts` `deleteMessages` (~2219), `moveMessages` (~2277), `copyMessages` (~2262, new), `saveDraft` via `sync-queue.ts` `enqueueDraftPush` (~110).
|
|
72
|
+
- Still synchronous / blocking: cross-account `moveMessage` (~2242) explicitly calls `imapManager.moveMessageCrossAccount(...)` synchronously and is labeled a "local-first violation"; outbox send remains a dir-based queue outside the reconciler.
|
|
73
|
+
- Reads are NOT guaranteed local: see Finding 1 — `getUnifiedInbox`/`getMessages` can time out, which a true local-first read path cannot.
|
|
74
|
+
|
|
75
|
+
**Impact:** The app *advertises* instant local behavior but degrades to "frozen UI" under a slow server — the exact failure `CLAUDE.md` says must not happen.
|
|
76
|
+
|
|
77
|
+
**How to verify:** Enumerate every read RPC and confirm whether it can block on IMAP. Confirm which writes return after a local commit vs after a server round-trip.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## 5. Finding 3 — Message identity is overloaded; UID used as identity
|
|
82
|
+
|
|
83
|
+
**Claim:** Messages are keyed by per-folder IMAP UID (often without `folder_id`) in many places, despite UID not being a stable identity and despite a `uuid` column existing.
|
|
84
|
+
|
|
85
|
+
**Evidence (each is a distinct call site to verify):**
|
|
86
|
+
- Stable identity exists but is under-used: `messages.uuid` + `idx_messages_uuid` (`packages/mailx-store/db.ts` ~472). Most lookups still go by `(account, uid)` or `(account, folder, uid)`.
|
|
87
|
+
- `packages/mailx-store/db.ts` `getMessageBodyPath(...)` (~2129–2138): when `folderId` is omitted, `WHERE account_id=? AND uid=?` — **cross-folder collision** (can return the wrong folder's body).
|
|
88
|
+
- `db.ts` `updateMessageFolder(...)` (~2167+): `UPDATE messages SET folder_id=? WHERE account_id=? AND uid=?` — updates **every** folder's row with that UID.
|
|
89
|
+
- `db.ts` `deleteMessage(...)` (~2512): the comment documents the **70k-row wipe on 2026-05-27** — a QRESYNC `VANISHED` for one folder's UID deleted the same numeric UID in every other folder. Fix added `folder_id` but still allows `folderId === null` ("delete in every folder") which is a footgun.
|
|
90
|
+
- `db.ts` `updateMessageFlags(...)` (~2148): comment documents the "stars on un-starred messages" bug (same numeric UID across folders); the null branch is still loose.
|
|
91
|
+
- Client: `client/components/message-list.ts` `rowKey(accountId, uid)` (~307) omits folder → `rowByKey` collides across folders; `focusByIdentity` can land on the wrong row. (Today's "Trash rows didn't disappear" was the same class in `removeMessages` / the DOM-removal key — partially fixed 2026-06-12 by adding folder to the key.)
|
|
92
|
+
- Service/IMAP callers that read without folder context: `packages/mailx-service/index.ts` `moveMessages` loop uses `getMessageByUid(accountId, uid)` (no folder, ~2280 area); `packages/mailx-imap/index.ts` `processSyncActions` uses `getMessageByUid(accountId, action.uid)` without folder (~3452/3472 area).
|
|
93
|
+
- Re-binding after a server move depends on **Message-ID** (`db.ts` upsert ~1710–1757). Messages with empty Message-ID (malformed, partial fetch, some Gmail-API rows) never re-bind → ghosting.
|
|
94
|
+
|
|
95
|
+
**Impact:** This identity model is the common root of: messages reappearing, not disappearing, ghost copies, wrong message in viewer on auto-advance, stars on wrong rows, and the catastrophic 70k-row wipe.
|
|
96
|
+
|
|
97
|
+
**How to verify:** grep `db.ts` for `WHERE account_id = ? AND uid = ?` (no `folder_id`) and judge each. grep the client for `${accountId}:${uid}` keys. Check whether any single identity abstraction exists or it's ad-hoc per call site.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## 6. Finding 4 — No single mutation funnel (~21 implementations)
|
|
102
|
+
|
|
103
|
+
**Claim:** Delete/trash/move is implemented in ~21 loosely-coupled places; a fix in one rarely reaches the others. This is the mechanical reason "every fix generates more problems."
|
|
104
|
+
|
|
105
|
+
**Evidence (entry points → service → store → db, plus duplicates):**
|
|
106
|
+
- Client triggers (`client/app.ts`): `deleteSelectedMessages` (~1459), `spamSelectedMessages` (~1824), pop-out delete listener (~5169), right-drag move (~1710), undo handler (~1550). Each does its own optimistic `removeMessagesAndReconcile` + its own IPC.
|
|
107
|
+
- Service (`packages/mailx-service/index.ts`): `deleteMessage` (~2199), `deleteMessages` (~2219), `markAsSpamMessages` (~2290, delegates to `moveMessages`), `moveMessage` (~2242), `moveMessages` (~2277), `undeleteMessage` (~2358), `emptyFolder` (~2581, its own IMAP delete loop — bypasses trash).
|
|
108
|
+
- Store (`packages/mailx-store/store.ts`): `trashMessage` (~581, smart move-or-expunge), `undeleteMessage` (~618).
|
|
109
|
+
- DB (`packages/mailx-store/db.ts`): `deleteMessage` (~2512), `deleteAllMessages` (~1400).
|
|
110
|
+
- **DEAD duplicate:** `packages/mailx-core/index.ts` `deleteMessage` (~297) reimplements trash but **skips** `addTombstone`, `recalcFolderCounts`, the pending-delete flag, and the store bus event. It is unreachable today but is a trap (a memory note: "fixes kept landing in the dead mailx-core dup").
|
|
111
|
+
- **Divergent Android copies:** `packages/mailx-store-web/sync-manager.ts` `trashMessage` (~354) and `android-bootstrap.ts` `trashMessage` (~502) both **hard-delete** (no smart trash, no tombstone, no pending flag) — different side-effects from desktop.
|
|
112
|
+
|
|
113
|
+
**Impact:** When you fix one delete path (e.g., add `folderId` disambiguation, add a confirmation, fix optimistic removal), the sibling paths (`emptyFolder`'s inline loop, Android's stub, the dead core) stay broken or diverge. That is the literal mechanism behind "I fix one thing and another breaks."
|
|
114
|
+
|
|
115
|
+
**How to verify:** Confirm there is no single function all mutations funnel through. Confirm `emptyFolder` and the Android stubs do not call `LocalStore.trashMessage`. Confirm `mailx-core` is unreferenced (grep imports of `@bobfrankston/mailx-core`).
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## 7. Finding 5 — Search is three languages behind one box
|
|
120
|
+
|
|
121
|
+
**Claim:** The one search box maps to three different executors with different semantics.
|
|
122
|
+
|
|
123
|
+
**Evidence:**
|
|
124
|
+
- Client-side substring filter: `client/components/message-list.ts` `setLiveFilter` (~40) — `.textContent` substring; no qualifier parsing. (This is what made `from:amazon` return nothing and `Hoddie` return everything; routed "This folder" through it until the 2026-06-12 fix.)
|
|
125
|
+
- DB FTS5: `packages/mailx-store/db.ts` `searchMessages` (~3176) — `MATCH` + `from:/to:/subject:/date:/is:/has:/folder:` qualifiers, wildcard, trash exclusion gated on `folderId`.
|
|
126
|
+
- Server IMAP sweep: `packages/mailx-service/index.ts` `search(scope="server")` (~1128) — per-folder IMAP `SEARCH`, different syntax, minutes-slow.
|
|
127
|
+
|
|
128
|
+
**Impact:** The same query string means different things by scope; qualifiers work in one path and not another. Inconsistent and surprising.
|
|
129
|
+
|
|
130
|
+
**How to verify:** Confirm the three executors and that there is no shared query parser/normalizer feeding them.
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## 8. Cross-cutting root cause
|
|
135
|
+
|
|
136
|
+
Two decisions explain most of it:
|
|
137
|
+
|
|
138
|
+
1. **The UI/read path is not isolated from network I/O** (Findings 1–2). Fix this and the timeouts/"frozen summary"/cascade class disappears.
|
|
139
|
+
2. **There is no canonical identity and no canonical mutation path** (Findings 3–4). Fix this and the reappear/ghost/wrong-row/wipe class disappears.
|
|
140
|
+
|
|
141
|
+
Search (Finding 5) and Android divergence are smaller, independent cleanups.
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## 9. Recommended refactor sequence (audit this ordering too)
|
|
146
|
+
|
|
147
|
+
**9.1 — Isolate reads from the network (highest leverage; ends the timeouts).**
|
|
148
|
+
- Every read RPC (`getMessages`, `getUnifiedInbox`, cached `getMessage`, FTS search) served **straight from SQLite** on a path that never `await`s IMAP and cannot be blocked by a network handler.
|
|
149
|
+
- Put IMAP/network work on its own queue/worker so a hung fetch can't occupy the dispatch pump. At minimum: don't serialize reads behind writes in `bin/mailx.ts`; add a hard timeout + cancellation on network-touching handlers; never let a read transitively call `withConnection`.
|
|
150
|
+
|
|
151
|
+
**9.2 — Finish local-first.** Every user action commits to SQLite and returns; the reconciler is the *only* code that touches the server. Move cross-account move and outbox under it.
|
|
152
|
+
|
|
153
|
+
**9.3 — One identity + one mutation funnel.** Use `uuid` as the in-memory and cross-folder identity; treat `(folder, uid)` as transient server metadata only. Route **all** deletes/moves/trash through a single function (validate → local commit → enqueue → undo). Delete `mailx-core`. Unify the Android `trashMessage` with the desktop store path (the `mailx-imap-core` over `Transport`/`Storage` interfaces noted as TODO C125).
|
|
154
|
+
|
|
155
|
+
**9.4 — One search parser, three executors behind it.**
|
|
156
|
+
|
|
157
|
+
Do 9.1 and 9.2 first — they're what's burning the user right now.
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## 10. What is NOT the architecture (be honest)
|
|
162
|
+
|
|
163
|
+
Not everything today was structural. Some was incidental and some was self-inflicted:
|
|
164
|
+
- **No bulk-delete confirmation** (the 114-message accident) was a missing UX guard, not deep architecture. Fixed 2026-06-12.
|
|
165
|
+
- **Repeatedly hot-patching the running daemon** during diagnosis caused stale-version confusion and extra churn — process, not architecture.
|
|
166
|
+
- The **immediate trigger** (UID 4966060 stalling on the server's `BODY[]`) was external. The *architecture* is at fault only for letting that one stall cascade (Finding 1).
|
|
167
|
+
|
|
168
|
+
A fair audit should separate "architecture guarantees recurring failures" (Findings 1–4: yes) from "incidental bug or operator error" (the above).
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## 11. Open questions for the reviewer
|
|
173
|
+
|
|
174
|
+
1. Is the IPC pump truly the bottleneck, or is there a read fast-path I missed in `bin/mailx.ts` / `api-client.ts`?
|
|
175
|
+
2. Is `getUnifiedInbox` actually network-free, or does it transitively trigger a fetch/reconcile?
|
|
176
|
+
3. How much of `docs/local-first-plan.md` is implemented vs aspirational?
|
|
177
|
+
4. Is `uuid` populated reliably on every row (IMAP + Gmail-API + APPEND paths), or are there rows with null `uuid` that would break a UUID-keyed identity?
|
|
178
|
+
5. Is the ordering in §9 right, or should identity (9.3) precede read-isolation (9.1)?
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
*End of review. Verify everything; trust nothing here on faith.*
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# rmfmail / mailx — Target Architecture & Migration Plan
|
|
2
|
+
|
|
3
|
+
**Date:** 2026-06-12
|
|
4
|
+
**Goal:** Thunderbird/Outlook-grade reliability without a green-field rewrite. Re-architect the **core data + sync layer**; keep the existing UI and feature surface and migrate it onto the new core in shippable, reversible phases.
|
|
5
|
+
**Companion:** `architecture-review.md` (the diagnosis this design answers).
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. The two principles that make mail clients reliable
|
|
10
|
+
|
|
11
|
+
Every reliable mail client (Thunderbird's global DB / "Panorama", Outlook's OST, Apple Mail's Envelope Index) obeys these:
|
|
12
|
+
|
|
13
|
+
1. **The display layer never blocks on the network.** A local store (a database) is the single source of truth for *everything the user sees and does*. Opening a folder, reading a message, searching, deleting — all are local operations that complete instantly. The network is a **separate, fully asynchronous background engine** that reconciles the store with the server. A dead/slow server makes mail *stale*, never makes the UI *freeze*.
|
|
14
|
+
|
|
15
|
+
2. **One canonical store, one stable identity, one path per operation.** A message has one durable local identity that survives folder moves and server UID renumbering. Each operation (delete, move, flag) has exactly one implementation that mutates the store and queues a server action. There are no parallel code paths to drift.
|
|
16
|
+
|
|
17
|
+
rmfmail violates both today (see review §3, §6). This design restores both.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 2. Three layers, strictly separated
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
25
|
+
│ UI (client/) │
|
|
26
|
+
│ • reads: pure store queries (instant, never await network) │
|
|
27
|
+
│ • writes: call Store mutation → optimistic local change │
|
|
28
|
+
│ + enqueue server action; return immediately │
|
|
29
|
+
│ • re-renders from Store change events │
|
|
30
|
+
└───────────────▲───────────────────────────┬─────────────────┘
|
|
31
|
+
│ store events │ read / mutate (local only)
|
|
32
|
+
┌───────────────┴───────────────────────────▼─────────────────┐
|
|
33
|
+
│ STORE (the source of truth for display) │
|
|
34
|
+
│ • SQLite. Stable message identity = local UUID. │
|
|
35
|
+
│ • Pure, synchronous, network-free read API. │
|
|
36
|
+
│ • Mutation funnel: trash/move/flag/copy/deletePermanent — │
|
|
37
|
+
│ one function each, keyed by UUID. Each = local change + │
|
|
38
|
+
│ durable queued action + change event. │
|
|
39
|
+
│ • Durable action queue (idempotent, UUID-keyed). │
|
|
40
|
+
└───────────────▲───────────────────────────┬─────────────────┘
|
|
41
|
+
│ "here is new/changed data" │ "drain these actions"
|
|
42
|
+
┌───────────────┴───────────────────────────▼─────────────────┐
|
|
43
|
+
│ SYNC ENGINE (the ONLY thing that touches the network) │
|
|
44
|
+
│ • Owns all IMAP/Gmail connections, fully isolated. │
|
|
45
|
+
│ • PULL: incremental fetch (QRESYNC/CONDSTORE → set-diff). │
|
|
46
|
+
│ • PUSH: drain the action queue to the server, idempotently. │
|
|
47
|
+
│ • RECONCILE: re-bind identity across UID changes by │
|
|
48
|
+
│ Message-ID / UUID. Maintain (folder,uid,uidvalidity) map. │
|
|
49
|
+
│ • Bounded connections, per-op timeout + cancellation, │
|
|
50
|
+
│ backoff, poison-action cap. A hung op affects ONLY here. │
|
|
51
|
+
└──────────────────────────────────────────────────────────────┘
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
The hard rule: **an arrow never points "up-and-blocking."** The UI calls into the Store and returns; it never awaits the Sync Engine. The Sync Engine pushes results down into the Store and the Store emits events up to the UI. There is no path where a network stall can sit inside a UI read.
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## 3. Identity (fixes review §5 — the reappear/ghost/wipe class)
|
|
59
|
+
|
|
60
|
+
- Every message gets a **stable local `id` (UUID)** at first sight.
|
|
61
|
+
- The identity key is **Message-ID** when present; otherwise a synthesized stable hash of `(account, internaldate, from, subject, size)`. This guarantees an identity even for malformed / Message-ID-less mail (the gap that breaks re-binding today).
|
|
62
|
+
- `(folder, server_uid, uidvalidity)` is **transient routing metadata**, owned and maintained only by the Sync Engine, in a `message_locations` table. **Nothing in the UI or Store mutations is ever keyed on a bare `uid`.**
|
|
63
|
+
- Multi-folder membership (Gmail labels, or a message genuinely in two folders) is N rows in `message_locations` pointing at one message UUID.
|
|
64
|
+
- Server-side UID renumber (move, UIDVALIDITY bump) re-binds the location row to the same UUID by Message-ID match — never creates a new identity, never orphans the body.
|
|
65
|
+
|
|
66
|
+
**Consequence:** the 70k-row wipe (a `WHERE uid=?` that hit every folder) becomes structurally impossible — there is no UID-only delete. Cross-folder collisions, stars-on-wrong-rows, ghosts, wrong-row-on-auto-advance all dissolve because UID is no longer identity.
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## 4. Mutation funnel (fixes review §6 — "every fix breaks another path")
|
|
71
|
+
|
|
72
|
+
The Store exposes exactly these mutators, each taking message UUIDs:
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
store.trash(uuids) // move to Trash, or permanent-expunge if already in Trash
|
|
76
|
+
store.move(uuids, toFolder)
|
|
77
|
+
store.copy(uuids, toFolder)
|
|
78
|
+
store.flag(uuids, flag, on)
|
|
79
|
+
store.deletePermanent(uuids)
|
|
80
|
+
store.markRead(uuids, on)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Each does, atomically: **(1)** update local rows + folder counts, **(2)** record an undo entry, **(3)** enqueue a durable, idempotent server action keyed by UUID, **(4)** emit a change event.
|
|
84
|
+
|
|
85
|
+
- **Every** UI trigger (Delete key, toolbar, drag, right-drag menu, context menu, pop-out, undo) calls these and nothing else. No optimistic-removal logic scattered in the UI; the UI just re-renders from the change event.
|
|
86
|
+
- `emptyFolder` becomes `store.deletePermanent(all-uuids-in-folder)` — same funnel, not a separate IMAP loop.
|
|
87
|
+
- **Delete `packages/mailx-core`** (dead duplicate).
|
|
88
|
+
- **Android shares this exact Store + queue.** The only platform difference is the `Transport` the Sync Engine injects (Node TCP vs bridge). No second `trashMessage`.
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## 5. Read path & dispatch isolation (fixes review §1/§2 — the timeouts you're hitting now)
|
|
93
|
+
|
|
94
|
+
- All reads — `listFolder`, `unifiedInbox`, `getMessage`, `search` — are **pure synchronous SQLite** behind a single read facade. They **cannot** call the network. `getMessage` returns the cached body if present, else `{cached:false}` and the UI shows a placeholder while the Sync Engine fetches and emits `bodyReady`. A read **can never time out.**
|
|
95
|
+
- The IPC dispatch (`bin/mailx.ts`) must not serialize a read behind a network write. Two concrete options (pick after measuring):
|
|
96
|
+
- **(A)** Run the Sync Engine's network work off the dispatch thread (worker), so `dispatch()` only ever does fast local work.
|
|
97
|
+
- **(B)** Split dispatch into a read lane (own SQLite read handle, always-fast) and a write/command lane; reads are answered immediately regardless of what the write lane is doing.
|
|
98
|
+
- Network handlers get a hard wall-clock timeout + cancellation; a hung op is abandoned and its connection discarded, never occupying a shared slot. (The `withTimeout`/dual-lane machinery already exists in `mailx-imap` — it just needs to be *above* nothing that a read depends on.)
|
|
99
|
+
|
|
100
|
+
**Consequence:** `getUnifiedInbox` (and every list/read) returns instantly even while the server is hung. The "nothing in the summary" / `mailxapi timeout` failure class is gone by construction.
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## 6. Sync Engine robustness (the part that earns "Thunderbird-grade")
|
|
105
|
+
|
|
106
|
+
- **Connection discipline:** per-account budget with a **dedicated interactive connection** that background sync/prefetch can never starve. Per-host semaphore stays as the server-cap guard.
|
|
107
|
+
- **Every op:** wall-clock timeout + cancellation; on timeout, discard the connection and back off. A single un-fetchable message (today's 4966060) is recorded with backoff and never re-attempted in a tight loop.
|
|
108
|
+
- **Push queue:** durable, idempotent, UUID-keyed actions; retry with backoff; a **poison cap** (give up after N, surface to the UI) so one bad action can't loop forever.
|
|
109
|
+
- **Pull:** capability-gated incremental sync — QRESYNC/CONDSTORE when the server advertises them, UID set-diff fallback otherwise; persist per-folder `UIDVALIDITY` + `HIGHESTMODSEQ`. (Memory note: capability-gate, don't hostname-branch.)
|
|
110
|
+
- **Reconcile:** the only place that re-binds UID↔UUID; tombstones with retained UUID suppress re-fetch of locally-deleted mail; UIDVALIDITY bump triggers a clean re-map, not a wipe.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## 7. Migration plan — phased, shippable, reversible (NOT big-bang)
|
|
115
|
+
|
|
116
|
+
Each phase ships on its own, is independently verifiable, and can be reverted. We do **not** rewrite the UI or the features.
|
|
117
|
+
|
|
118
|
+
**Phase 0 — Read isolation (do first; ends the timeouts).**
|
|
119
|
+
- Guarantee every read RPC is network-free and cannot be head-of-line-blocked. Implement §5 option A or B in `bin/mailx.ts` + the service read methods. Add hard timeouts/cancellation to network handlers.
|
|
120
|
+
- *Exit test:* with the IMAP server artificially hung, the list, folder switch, search, and cached-message open all still respond instantly. No `mailxapi timeout` on any read.
|
|
121
|
+
|
|
122
|
+
**Phase 1 — Identity + mutation funnel.**
|
|
123
|
+
- Introduce/standardize the UUID identity and `message_locations`; backfill UUIDs (rebuild-from-server is acceptable per the "no migrations, redownload" rule).
|
|
124
|
+
- Route all deletes/moves/flags through the §4 funnel; delete `mailx-core`; converge `emptyFolder`.
|
|
125
|
+
- *Exit test:* a scripted scenario with the same numeric UID in INBOX + Trash + Sent — delete/flag/move one and confirm the others are untouched. No ghost rows after a move+delete cycle.
|
|
126
|
+
|
|
127
|
+
**Phase 2 — Sync Engine extraction.**
|
|
128
|
+
- Make the Sync Engine the sole network owner with §6 discipline; move cross-account move and outbox under it. Dedicated interactive lane.
|
|
129
|
+
- *Exit test:* hung-folder fault injection — background sync stalls, interactive open/delete stay responsive; poison action gives up instead of looping.
|
|
130
|
+
|
|
131
|
+
**Phase 3 — Search unification + Android convergence.**
|
|
132
|
+
- One query parser feeding the (local-FTS / server-IMAP) executors. Android uses the shared Store + queue + a `Transport`.
|
|
133
|
+
- *Exit test:* identical query semantics across scopes; Android delete sets the same pending/tombstone state as desktop.
|
|
134
|
+
|
|
135
|
+
Order rationale: Phase 0 stops the bleeding you're seeing *right now*; Phase 1 removes the data-integrity class (the scary one — the wipe); Phases 2–3 are robustness + cleanup.
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## 8. What we explicitly do NOT do
|
|
140
|
+
|
|
141
|
+
- No green-field rewrite. The UI, compose/editor, providers, OAuth, calendar/tasks, Android shell, and the feature set stay.
|
|
142
|
+
- No big-bang cutover. Each phase coexists with the rest.
|
|
143
|
+
- No hot-patching the live daemon during this work — changes land, get built, and are verified deliberately (the firefighting pattern is over).
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## 9. How we'll verify reliability (the Thunderbird bar)
|
|
148
|
+
|
|
149
|
+
A short fault-injection harness, run after each phase:
|
|
150
|
+
1. **Server hung** (stall `BODY[]` / SELECT): UI reads stay instant; no timeouts.
|
|
151
|
+
2. **Server slow** (5s/op): actions queue and drain; UI never blocks.
|
|
152
|
+
3. **Offline → online:** queued actions drain in order, idempotently; no dupes, no loss.
|
|
153
|
+
4. **UID collision** across folders: per-message ops never hit the wrong message.
|
|
154
|
+
5. **UIDVALIDITY bump:** re-map, no wipe.
|
|
155
|
+
6. **Crash mid-action:** durable queue resumes; nothing lost, nothing double-applied.
|
|
156
|
+
|
|
157
|
+
When all six pass under injection, we're at the reliability bar you're asking for.
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
*This is the target. Phase 0 is the next concrete step and is self-contained.*
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAIvD,wBAAgB,eAAe,CAAC,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,WAAW,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAIvD,wBAAgB,eAAe,CAAC,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,WAAW,GAAG,MAAM,CA+Q9E;AAGD,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC"}
|
|
@@ -11,13 +11,16 @@ export function createApiRouter(store, imapManager) {
|
|
|
11
11
|
// ── Accounts ──
|
|
12
12
|
router.get("/accounts", (req, res) => { res.json(svc.getAccounts()); });
|
|
13
13
|
// ── Folders ──
|
|
14
|
-
|
|
14
|
+
// NB: getFolders/getUnifiedInbox/getMessages now return Promises (Phase 0
|
|
15
|
+
// read-worker routes them off the main thread). Await before res.json or
|
|
16
|
+
// the client gets a serialized empty Promise.
|
|
17
|
+
router.get("/folders/:accountId", async (req, res) => { res.json(await svc.getFolders(req.params.accountId)); });
|
|
15
18
|
// ── Messages ──
|
|
16
|
-
router.get("/messages/unified/inbox", (req, res) => {
|
|
17
|
-
res.json(svc.getUnifiedInbox(Number(req.query.page) || 1, Number(req.query.pageSize) || 50));
|
|
19
|
+
router.get("/messages/unified/inbox", async (req, res) => {
|
|
20
|
+
res.json(await svc.getUnifiedInbox(Number(req.query.page) || 1, Number(req.query.pageSize) || 50));
|
|
18
21
|
});
|
|
19
|
-
router.get("/messages/:accountId/:folderId", (req, res) => {
|
|
20
|
-
res.json(svc.getMessages(req.params.accountId, Number(req.params.folderId), Number(req.query.page) || 1, Number(req.query.pageSize) || 50, req.query.sort || "date", req.query.sortDir || "desc", req.query.search));
|
|
22
|
+
router.get("/messages/:accountId/:folderId", async (req, res) => {
|
|
23
|
+
res.json(await svc.getMessages(req.params.accountId, Number(req.params.folderId), Number(req.query.page) || 1, Number(req.query.pageSize) || 50, req.query.sort || "date", req.query.sortDir || "desc", req.query.search));
|
|
21
24
|
});
|
|
22
25
|
router.get("/message/:accountId/:uid", async (req, res) => {
|
|
23
26
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,15 +18,18 @@ export function createApiRouter(store: Store, imapManager: ImapManager): Router
|
|
|
18
18
|
router.get("/accounts", (req, res) => { res.json(svc.getAccounts()); });
|
|
19
19
|
|
|
20
20
|
// ── Folders ──
|
|
21
|
-
|
|
21
|
+
// NB: getFolders/getUnifiedInbox/getMessages now return Promises (Phase 0
|
|
22
|
+
// read-worker routes them off the main thread). Await before res.json or
|
|
23
|
+
// the client gets a serialized empty Promise.
|
|
24
|
+
router.get("/folders/:accountId", async (req, res) => { res.json(await svc.getFolders(req.params.accountId)); });
|
|
22
25
|
|
|
23
26
|
// ── Messages ──
|
|
24
|
-
router.get("/messages/unified/inbox", (req, res) => {
|
|
25
|
-
res.json(svc.getUnifiedInbox(Number(req.query.page) || 1, Number(req.query.pageSize) || 50));
|
|
27
|
+
router.get("/messages/unified/inbox", async (req, res) => {
|
|
28
|
+
res.json(await svc.getUnifiedInbox(Number(req.query.page) || 1, Number(req.query.pageSize) || 50));
|
|
26
29
|
});
|
|
27
30
|
|
|
28
|
-
router.get("/messages/:accountId/:folderId", (req, res) => {
|
|
29
|
-
res.json(svc.getMessages(
|
|
31
|
+
router.get("/messages/:accountId/:folderId", async (req, res) => {
|
|
32
|
+
res.json(await svc.getMessages(
|
|
30
33
|
req.params.accountId, Number(req.params.folderId),
|
|
31
34
|
Number(req.query.page) || 1, Number(req.query.pageSize) || 50,
|
|
32
35
|
(req.query.sort as string) || "date", (req.query.sortDir as string) || "desc",
|
|
@@ -51,7 +51,11 @@ parentPort.once("message", async (msg) => {
|
|
|
51
51
|
return;
|
|
52
52
|
}
|
|
53
53
|
try {
|
|
54
|
-
|
|
54
|
+
// Read-only handle: the main thread owns all writes/migrations and has
|
|
55
|
+
// already run them before spawning us. query_only forbids any write
|
|
56
|
+
// here, and WAL lets us read committed rows the instant the writer
|
|
57
|
+
// commits. See MailxDB readOnly branch.
|
|
58
|
+
const db = new MailxDB(msg.dbPath, { readOnly: true });
|
|
55
59
|
const bodyStore = new FileMessageStore(msg.storePath);
|
|
56
60
|
store = new Store(db, bodyStore);
|
|
57
61
|
initialized = true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db-worker.js","sourceRoot":"","sources":["db-worker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAwB,MAAM,yBAAyB,CAAC;AAC1E,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAG7E,IAAI,CAAC,UAAU,EAAE,CAAC;IACd,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;AAClF,CAAC;AAQD,yEAAyE;AACzE,8CAA8C;AAC9C,IAAI,KAAK,GAAiB,IAAI,CAAC;AAC/B,IAAI,WAAW,GAAG,KAAK,CAAC;AAExB,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,GAAgB,EAAE,EAAE;IAClD,IAAI,GAAG,EAAE,IAAI,KAAK,MAAM,EAAE,CAAC;QACvB,UAAW,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,gCAAgC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QAC9G,OAAO;IACX,CAAC;IACD,IAAI,CAAC;QACD,MAAM,EAAE,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"db-worker.js","sourceRoot":"","sources":["db-worker.ts"],"names":[],"mappings":"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"}
|
|
@@ -62,7 +62,11 @@ parentPort.once("message", async (msg: InitMessage) => {
|
|
|
62
62
|
return;
|
|
63
63
|
}
|
|
64
64
|
try {
|
|
65
|
-
|
|
65
|
+
// Read-only handle: the main thread owns all writes/migrations and has
|
|
66
|
+
// already run them before spawning us. query_only forbids any write
|
|
67
|
+
// here, and WAL lets us read committed rows the instant the writer
|
|
68
|
+
// commits. See MailxDB readOnly branch.
|
|
69
|
+
const db = new MailxDB(msg.dbPath, { readOnly: true });
|
|
66
70
|
const bodyStore = new FileMessageStore(msg.storePath);
|
|
67
71
|
store = new Store(db, bodyStore);
|
|
68
72
|
initialized = true;
|
|
@@ -51,6 +51,16 @@ export declare class MailxService implements MailxApi {
|
|
|
51
51
|
* local DB or body store goes through this — no awaiting IMAP, no
|
|
52
52
|
* awaiting Gmail API, no awaiting SMTP. See docs/local-first-plan.md. */
|
|
53
53
|
private localStore;
|
|
54
|
+
/** Phase 0 read isolation (docs/clean-architecture.md §5). The DB read
|
|
55
|
+
* surface runs on its OWN thread with its own read-only SQLite handle, so
|
|
56
|
+
* UI list/search/open reads can NEVER be head-of-line-blocked behind a
|
|
57
|
+
* synchronous sync write or a hung IMAP op on the main event loop. Null
|
|
58
|
+
* until the worker has finished its init handshake (a few ms at startup)
|
|
59
|
+
* and null forever if spawning failed — in both cases reads fall back to
|
|
60
|
+
* the in-process `localStore`, same code, same answers. `readReady`
|
|
61
|
+
* resolves once the spawn attempt settles (either outcome). */
|
|
62
|
+
private dbWorker;
|
|
63
|
+
private readReady;
|
|
54
64
|
/** Persistent (and in-memory body-fetch) queue. UI handlers commit
|
|
55
65
|
* locally, then enqueue a server-mirror task here. */
|
|
56
66
|
private syncQueue;
|
|
@@ -65,6 +75,13 @@ export declare class MailxService implements MailxApi {
|
|
|
65
75
|
* the ~50 `this.db.X(...)` callsites in this file don't all need
|
|
66
76
|
* touching at once; all writes should migrate to `this.localStore.X(...)`. */
|
|
67
77
|
store: Store, imapManager: ImapManager);
|
|
78
|
+
/** Bring up the read-worker. Resolves whether it succeeded or not — on
|
|
79
|
+
* failure `dbWorker` stays null and every read uses `localStore`. */
|
|
80
|
+
private spawnReadWorker;
|
|
81
|
+
/** Route a read through the worker bus if it's up, else run it in-process.
|
|
82
|
+
* A worker-side error (or a dead worker) transparently falls back so a
|
|
83
|
+
* read never fails just because the isolation layer hiccuped. */
|
|
84
|
+
private read;
|
|
68
85
|
/** Transitional getter — direct DB access from MailxService for the
|
|
69
86
|
* ~50 callsites that haven't yet migrated to Store methods. Future:
|
|
70
87
|
* every mutation routes through `this.localStore.X(...)`. */
|
|
@@ -127,7 +144,7 @@ export declare class MailxService implements MailxApi {
|
|
|
127
144
|
* comment for the wedge-28-seconds story. */
|
|
128
145
|
private getCachedSettings;
|
|
129
146
|
getAccounts(): any[];
|
|
130
|
-
getFolders(accountId: string): Folder[]
|
|
147
|
+
getFolders(accountId: string): Folder[] | Promise<Folder[]>;
|
|
131
148
|
getUnifiedInbox(page?: number, pageSize?: number, flaggedOnly?: boolean): any;
|
|
132
149
|
getMessages(accountId: string, folderId: number, page?: number, pageSize?: number, sort?: string, sortDir?: string, search?: string, flaggedOnly?: boolean): any;
|
|
133
150
|
/** UI body read — local-first. Returns immediately from the local cache:
|