@bobfrankston/mailx-imap 0.1.72 → 0.1.74
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.d.ts +7 -0
- package/index.js +30 -5
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -398,6 +398,13 @@ export declare class ImapManager extends EventEmitter {
|
|
|
398
398
|
private prefetchFailures;
|
|
399
399
|
private markPrefetchEmpty;
|
|
400
400
|
private isPrefetchEmpty;
|
|
401
|
+
/** Clear a UID's prefetch-failure record after a successful fetch, so a
|
|
402
|
+
* message that healed (e.g. a transient iflow protocol desync that
|
|
403
|
+
* resolved on retry) doesn't carry a stale backoff count into the
|
|
404
|
+
* future. Without this, a once-failed-then-succeeded UID keeps its
|
|
405
|
+
* count and would back off longer than warranted if it ever re-enters
|
|
406
|
+
* the candidate set. */
|
|
407
|
+
private clearPrefetchEmpty;
|
|
401
408
|
/** Background body-cache backfill. Public so the Reconciler can schedule
|
|
402
409
|
* the periodic tick under its priority/back-pressure rules; existing
|
|
403
410
|
* in-method post-sync nudges (sync, fetchSince, fetchOne) call this
|
package/index.js
CHANGED
|
@@ -2467,14 +2467,29 @@ export class ImapManager extends EventEmitter {
|
|
|
2467
2467
|
// Quick STATUS check (above) and actions/outbox drain (above)
|
|
2468
2468
|
// stay here because they're tightly tied to IMAP connection state
|
|
2469
2469
|
// and the `syncing` flag.
|
|
2470
|
-
//
|
|
2471
|
-
//
|
|
2472
|
-
//
|
|
2473
|
-
//
|
|
2470
|
+
// LAZY FOLDER SYNC (Thunderbird model — Bob 2026-05-28). The full
|
|
2471
|
+
// sweep of ALL folders no longer runs on the tight `intervalMinutes`
|
|
2472
|
+
// (5 min) timer. On a mailbox with 79 folders + a 135k INBOX, that
|
|
2473
|
+
// sweep ran longer than 5 minutes (folders timing out at 360s) and
|
|
2474
|
+
// was therefore ALWAYS running, saturating the 4-permit connection
|
|
2475
|
+
// semaphore. That starved the three things that actually matter —
|
|
2476
|
+
// new INBOX mail (IDLE re-establish), body prefetch, and click-to-read
|
|
2477
|
+
// — producing the session's running complaints: "slow to get codes",
|
|
2478
|
+
// "lots not prefetched", "Loading… forever".
|
|
2479
|
+
//
|
|
2480
|
+
// New model:
|
|
2481
|
+
// - INBOX: IDLE push (instant) + the 5-min quick STATUS check above
|
|
2482
|
+
// (safety net). Unchanged — INBOX stays fresh.
|
|
2483
|
+
// - Every other folder: synced ON OPEN (the client fires syncFolder
|
|
2484
|
+
// when the user selects a folder) + a slow background sweep at
|
|
2485
|
+
// FULL_SWEEP_MIN so nothing goes stale indefinitely.
|
|
2486
|
+
// The slow sweep keeps connection headroom free for the hot paths.
|
|
2487
|
+
const FULL_SWEEP_MIN = 30;
|
|
2474
2488
|
const fullInterval = setInterval(() => {
|
|
2475
2489
|
this.runFullSync().catch(e => console.error(` [periodic] full sync error: ${e?.message || e}`));
|
|
2476
|
-
},
|
|
2490
|
+
}, FULL_SWEEP_MIN * 60000);
|
|
2477
2491
|
this.syncIntervals.set("all", fullInterval);
|
|
2492
|
+
console.log(` [periodic] full all-folders sweep every ${FULL_SWEEP_MIN}min (lazy model — folders also sync on open); INBOX stays live via IDLE + ${intervalMinutes}min quick check`);
|
|
2478
2493
|
}
|
|
2479
2494
|
/** One-shot full sync + IDLE restart. Public so callers (Reconciler,
|
|
2480
2495
|
* user-initiated "Sync now") can fire it on demand. The original body
|
|
@@ -2870,6 +2885,15 @@ export class ImapManager extends EventEmitter {
|
|
|
2870
2885
|
: 12 * 3600_000;
|
|
2871
2886
|
return Date.now() - f.lastTried < backoffMs;
|
|
2872
2887
|
}
|
|
2888
|
+
/** Clear a UID's prefetch-failure record after a successful fetch, so a
|
|
2889
|
+
* message that healed (e.g. a transient iflow protocol desync that
|
|
2890
|
+
* resolved on retry) doesn't carry a stale backoff count into the
|
|
2891
|
+
* future. Without this, a once-failed-then-succeeded UID keeps its
|
|
2892
|
+
* count and would back off longer than warranted if it ever re-enters
|
|
2893
|
+
* the candidate set. */
|
|
2894
|
+
clearPrefetchEmpty(accountId, folderId, uid) {
|
|
2895
|
+
this.prefetchFailures.delete(`${accountId}:${folderId}:${uid}`);
|
|
2896
|
+
}
|
|
2873
2897
|
/** Background body-cache backfill. Public so the Reconciler can schedule
|
|
2874
2898
|
* the periodic tick under its priority/back-pressure rules; existing
|
|
2875
2899
|
* in-method post-sync nudges (sync, fetchSince, fetchOne) call this
|
|
@@ -3095,6 +3119,7 @@ export class ImapManager extends EventEmitter {
|
|
|
3095
3119
|
const parsed = await extractPreview(source);
|
|
3096
3120
|
this.db.updateBodyMeta(accountId, uid, bodyPath, parsed.hasAttachments, parsed.preview);
|
|
3097
3121
|
this.emit("bodyCached", accountId, uid);
|
|
3122
|
+
this.clearPrefetchEmpty(accountId, folderId, uid); // healed — drop stale backoff
|
|
3098
3123
|
counters.totalFetched++;
|
|
3099
3124
|
madeProgress = true;
|
|
3100
3125
|
}
|