@bobfrankston/mailx-store 0.1.57 → 0.1.58
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/db.d.ts +7 -0
- package/db.js +13 -1
- package/package.json +1 -1
package/db.d.ts
CHANGED
|
@@ -301,6 +301,13 @@ export declare class MailxDB {
|
|
|
301
301
|
* message_folders. Omitted/false for Gmail (label = folder, many per
|
|
302
302
|
* message). Set true by the IMAP storeMessages path. */
|
|
303
303
|
exclusive?: boolean;
|
|
304
|
+
/** UIDs the server currently lists for THIS folder, when the caller
|
|
305
|
+
* just enumerated them (the set-diff backfill path). Lets move-detect
|
|
306
|
+
* distinguish a real move (old uid gone) from a DUPLICATE DELIVERY
|
|
307
|
+
* (same Message-ID at two live uids in one folder — e.g. a message
|
|
308
|
+
* addressed to two aliases of the same mailbox). Without this the
|
|
309
|
+
* single row ping-pongs between the two uids every sync cycle. */
|
|
310
|
+
liveServerUids?: Set<number>;
|
|
304
311
|
}): number;
|
|
305
312
|
/** Backfill the FTS5 `body_text` column for a message after its body
|
|
306
313
|
* has been parsed. Capped at ~64 KB of text per row — FTS5 stores the
|
package/db.js
CHANGED
|
@@ -1828,7 +1828,19 @@ export class MailxDB {
|
|
|
1828
1828
|
// surface transient move-dups. Keeping the collapse for now.
|
|
1829
1829
|
if (msg.messageId) {
|
|
1830
1830
|
const moved = this.db.prepare("SELECT id, folder_id, uid FROM messages WHERE account_id = ? AND message_id = ? LIMIT 1").get(msg.accountId, msg.messageId);
|
|
1831
|
-
|
|
1831
|
+
// Duplicate delivery, NOT a move: same folder, different uid, and
|
|
1832
|
+
// the caller's server UID list confirms the OLD uid is still in the
|
|
1833
|
+
// mailbox. Rebinding here would ping-pong the row between the two
|
|
1834
|
+
// uids on every sync (each cycle sees the unbound uid as
|
|
1835
|
+
// "server-only", refetches it, and rebinds). Fall through to a
|
|
1836
|
+
// fresh insert instead — both copies get their own row, matching
|
|
1837
|
+
// what the server (and every other client) actually shows, and the
|
|
1838
|
+
// set-diff converges.
|
|
1839
|
+
if (moved && moved.folder_id === msg.folderId && moved.uid !== msg.uid
|
|
1840
|
+
&& msg.liveServerUids?.has(moved.uid)) {
|
|
1841
|
+
console.log(` [move-detect] ${msg.accountId} ${msg.messageId}: uid ${moved.uid} still on server — duplicate copy at uid ${msg.uid}, inserting second row`);
|
|
1842
|
+
}
|
|
1843
|
+
else if (moved) {
|
|
1832
1844
|
console.log(` [move-detect] ${msg.accountId} ${msg.messageId}: rebinding row ${moved.id} (folder ${moved.folder_id}/uid ${moved.uid} → folder ${msg.folderId}/uid ${msg.uid})`);
|
|
1833
1845
|
this.db.prepare("UPDATE messages SET folder_id = ?, uid = ?, cached_at = ? WHERE id = ?").run(msg.folderId, msg.uid, Date.now(), moved.id);
|
|
1834
1846
|
this.upsertMessageFolder(moved.id, msg.folderId, msg.uid, msg.exclusive);
|