@bobfrankston/mailx-imap 0.1.90 → 0.1.92
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/index.js +34 -8
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -636,14 +636,16 @@ export class ImapManager extends EventEmitter {
|
|
|
636
636
|
const releaseHostSlot = skipSemaphore ? (() => { }) : await this.acquireHostSlot(host);
|
|
637
637
|
let client;
|
|
638
638
|
try {
|
|
639
|
-
// Verbose IMAP wire trace
|
|
640
|
-
//
|
|
641
|
-
//
|
|
642
|
-
//
|
|
643
|
-
//
|
|
644
|
-
//
|
|
645
|
-
//
|
|
646
|
-
|
|
639
|
+
// Verbose IMAP wire trace — diagnostic for silently-hanging
|
|
640
|
+
// commands. It was left permanently ON for the ops/fast lanes, but
|
|
641
|
+
// that logs every literal chunk (8000+ lines during a body-fetch
|
|
642
|
+
// burst), and on Windows the daemon's console.log writes to the log
|
|
643
|
+
// file SYNCHRONOUSLY — so the trace itself blocked the main event
|
|
644
|
+
// loop during sync, starving the IPC reply relay and producing the
|
|
645
|
+
// 78s read stalls (Bob 2026-06-13). Now opt-in: set RMFMAIL_IMAP_TRACE=1
|
|
646
|
+
// to re-enable for a debugging session. Default is quiet.
|
|
647
|
+
const imapTrace = process.env.RMFMAIL_IMAP_TRACE === "1";
|
|
648
|
+
const cfgWithVerbose = (imapTrace && (purpose === "ops" || purpose === "fast")) ? { ...config, verbose: true } : config;
|
|
647
649
|
client = new CompatImapClient(cfgWithVerbose, this.transportFactory);
|
|
648
650
|
}
|
|
649
651
|
catch (e) {
|
|
@@ -3590,6 +3592,30 @@ export class ImapManager extends EventEmitter {
|
|
|
3590
3592
|
}
|
|
3591
3593
|
break;
|
|
3592
3594
|
}
|
|
3595
|
+
case "copy": {
|
|
3596
|
+
const target = folders.find(f => f.id === action.targetFolderId);
|
|
3597
|
+
if (!target) {
|
|
3598
|
+
console.error(` [sync] Copy target folder ${action.targetFolderId} missing — dropping action UID ${action.uid}`);
|
|
3599
|
+
throw new Error(`copy target folder ${action.targetFolderId} not found`);
|
|
3600
|
+
}
|
|
3601
|
+
// Copy = fetch the raw message and APPEND it to the
|
|
3602
|
+
// target; it stays in the source folder too. The
|
|
3603
|
+
// compat client has no native IMAP COPY, but
|
|
3604
|
+
// fetch+append is equivalent and reuses existing
|
|
3605
|
+
// primitives. The new copy is pulled into the local
|
|
3606
|
+
// store by a target-folder sync below.
|
|
3607
|
+
const msg = await client.fetchMessageByUid(folder.path, action.uid, { source: true });
|
|
3608
|
+
if (!msg || !msg.source) {
|
|
3609
|
+
console.log(` [sync] Copy UID ${action.uid} in ${folder.path}: message gone (attempt ${action.attempts + 1}); dropping action`);
|
|
3610
|
+
break;
|
|
3611
|
+
}
|
|
3612
|
+
const copyFlags = (msg.flags || []).filter((f) => f !== "\\Recent");
|
|
3613
|
+
await client.appendMessage(target.path, msg.source, copyFlags);
|
|
3614
|
+
console.log(` [sync] Copied UID ${action.uid}: ${folder.path} → ${target.path}`);
|
|
3615
|
+
// Import the new copy so it appears in the target folder.
|
|
3616
|
+
this.syncFolder(accountId, target.id).catch(() => { });
|
|
3617
|
+
break;
|
|
3618
|
+
}
|
|
3593
3619
|
}
|
|
3594
3620
|
// Success: the local action reached the server. Lift the
|
|
3595
3621
|
// in-flight delete/move suppression so the destination
|