@bobfrankston/rmfmail 1.2.1 → 1.2.3
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/package.json +1 -1
- package/packages/mailx-imap/index.d.ts.map +1 -1
- package/packages/mailx-imap/index.js +10 -8
- package/packages/mailx-imap/index.js.map +1 -1
- package/packages/mailx-imap/index.ts +10 -8
- package/packages/mailx-imap/package-lock.json +2 -2
- package/packages/mailx-imap/package.json +1 -1
- package/packages/mailx-service/index.d.ts +11 -1
- package/packages/mailx-service/index.d.ts.map +1 -1
- package/packages/mailx-service/index.js +41 -7
- package/packages/mailx-service/index.js.map +1 -1
- package/packages/mailx-service/index.ts +35 -9
- package/packages/mailx-store/db.d.ts.map +1 -1
- package/packages/mailx-store/db.js +9 -0
- package/packages/mailx-store/db.js.map +1 -1
- package/packages/mailx-store/db.ts +9 -0
- package/packages/mailx-store/package.json +1 -1
- package/test/phase0-deepcompare.mjs +51 -0
|
@@ -1232,6 +1232,7 @@ export class MailxDB {
|
|
|
1232
1232
|
accountId: r.account_id,
|
|
1233
1233
|
folderId: r.folder_id,
|
|
1234
1234
|
uid: r.uid,
|
|
1235
|
+
uuid: r.uuid || "", // stable identity for row data-uuid / selection restore
|
|
1235
1236
|
messageId: r.message_id || "",
|
|
1236
1237
|
inReplyTo: r.in_reply_to || "",
|
|
1237
1238
|
references: JSON.parse(r.refs || "[]"),
|
|
@@ -2082,6 +2083,13 @@ export class MailxDB {
|
|
|
2082
2083
|
// Bcc). The unified-inbox UI shows a small ⇆ badge on these
|
|
2083
2084
|
// rows so the user knows "this is a copy of the same message".
|
|
2084
2085
|
dupeCount: (r.dupeCount as number) | 0,
|
|
2086
|
+
// uuid is the stable local identity each message-list row carries as
|
|
2087
|
+
// data-uuid. Without it, restoreSelection() / rememberPosition() /
|
|
2088
|
+
// the set-diff scroll anchor all match on empty string and fail, so
|
|
2089
|
+
// the selected-row highlight vanishes on every reload (Bob
|
|
2090
|
+
// 2026-06-13: "no highlighting in the summary"). getMessages already
|
|
2091
|
+
// maps uuid; this unified-inbox map dropped it. SELECT m.* exposes it.
|
|
2092
|
+
uuid: r.uuid || "",
|
|
2085
2093
|
} as any));
|
|
2086
2094
|
|
|
2087
2095
|
return { items, total, page, pageSize };
|
|
@@ -3403,6 +3411,7 @@ export class MailxDB {
|
|
|
3403
3411
|
folderId: r.folder_id,
|
|
3404
3412
|
folderName: r.folder_name || "",
|
|
3405
3413
|
uid: r.uid,
|
|
3414
|
+
uuid: r.uuid || "", // stable identity for row data-uuid / selection restore
|
|
3406
3415
|
messageId: r.message_id || "",
|
|
3407
3416
|
inReplyTo: r.in_reply_to || "",
|
|
3408
3417
|
references: JSON.parse(r.refs || "[]"),
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/** Deep-compare worker vs in-process envelopes to catch any field the
|
|
2
|
+
* structured-clone boundary drops/alters (suspected highlight regression). */
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import os from "node:os";
|
|
6
|
+
import { MailxDB, Store, FileMessageStore } from "../packages/mailx-store/index.js";
|
|
7
|
+
import { spawnDbWorker } from "../packages/mailx-service/db-worker-client.js";
|
|
8
|
+
|
|
9
|
+
const liveDir = process.env.RMFMAIL_DIR || path.join(os.homedir(), ".rmfmail");
|
|
10
|
+
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "rmf-deep-"));
|
|
11
|
+
for (const s of ["", "-wal", "-shm"]) {
|
|
12
|
+
const src = path.join(liveDir, "mailx.db" + s);
|
|
13
|
+
if (fs.existsSync(src)) try { fs.copyFileSync(src, path.join(tmp, "mailx.db" + s)); } catch {}
|
|
14
|
+
}
|
|
15
|
+
const db = new MailxDB(tmp);
|
|
16
|
+
const store = new Store(db, new FileMessageStore(path.join(tmp, "store")));
|
|
17
|
+
const worker = await spawnDbWorker({ dbPath: tmp, storePath: path.join(tmp, "store") });
|
|
18
|
+
|
|
19
|
+
const ip = store.getUnifiedInbox(1, 10, false);
|
|
20
|
+
const wk = await worker.bus.request("db:getUnifiedInbox", { page: 1, pageSize: 10, flaggedOnly: false });
|
|
21
|
+
|
|
22
|
+
function describe(v) {
|
|
23
|
+
if (v === null) return "null";
|
|
24
|
+
if (v instanceof Date) return `Date(${v.getTime()})`;
|
|
25
|
+
if (Array.isArray(v)) return `Array[${v.length}]`;
|
|
26
|
+
return typeof v;
|
|
27
|
+
}
|
|
28
|
+
let mismatches = 0;
|
|
29
|
+
for (let i = 0; i < Math.min(ip.items.length, wk.items.length); i++) {
|
|
30
|
+
const a = ip.items[i], b = wk.items[i];
|
|
31
|
+
const keys = new Set([...Object.keys(a), ...Object.keys(b)]);
|
|
32
|
+
for (const k of keys) {
|
|
33
|
+
const sa = JSON.stringify(a[k]), sb = JSON.stringify(b[k]);
|
|
34
|
+
if (sa !== sb) {
|
|
35
|
+
mismatches++;
|
|
36
|
+
console.log(` item[${i}].${k}: in-proc=${describe(a[k])} ${sa} || worker=${describe(b[k])} ${sb}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
console.log(mismatches === 0
|
|
41
|
+
? `\n✓ ALL fields identical across ${ip.items.length} envelopes — highlighting is NOT a worker data issue`
|
|
42
|
+
: `\n✗ ${mismatches} field mismatch(es) — likely the highlight cause`);
|
|
43
|
+
|
|
44
|
+
// Show which fields exist + the flags shape (unread highlight driver).
|
|
45
|
+
console.log("\nfields on envelope[0]:", Object.keys(ip.items[0] || {}).join(", "));
|
|
46
|
+
console.log("flags[0]:", JSON.stringify(ip.items[0]?.flags), "| unread driver candidates:",
|
|
47
|
+
["unread", "seen", "isRead", "flags"].filter(k => k in (ip.items[0] || {})).join(", "));
|
|
48
|
+
|
|
49
|
+
await worker.close();
|
|
50
|
+
try { fs.rmSync(tmp, { recursive: true, force: true }); } catch {}
|
|
51
|
+
process.exit(0);
|