@bobfrankston/mailx-imap 0.1.115 → 0.1.116

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.
Files changed (2) hide show
  1. package/index.js +22 -1
  2. package/package.json +5 -5
package/index.js CHANGED
@@ -3979,7 +3979,28 @@ export class ImapManager extends EventEmitter {
3979
3979
  }
3980
3980
  }
3981
3981
  else if (batchSucceeded && !someReceived) {
3982
- console.error(` [prefetch] ${accountId}/${folder.path}: chunk ${chunkStart}-${chunkStart + chunk.length - 1} returned 0/${chunk.length} bodies — NOT pruning (set-diff reconcile owns deletion). UIDs: ${chunk.slice(0, 5).join(",")}${chunk.length > 5 ? "..." : ""}`);
3982
+ // Verify-then-classify (Q154): a 0-response chunk is
3983
+ // USUALLY a message server-side filtering moved out of
3984
+ // this folder between envelope arrival and body
3985
+ // prefetch (bobma: Sieve → _Spam within seconds) —
3986
+ // expected and self-healing via move-detect, not an
3987
+ // error. Ask the server which UIDs still exist:
3988
+ // absent → one info line (reconcile owns the rows);
3989
+ // still present → a REAL fetch failure, keep the ERROR.
3990
+ let stillPresent = null;
3991
+ try {
3992
+ await this.withConnection(accountId, async (vc) => {
3993
+ const serverUids = new Set(await vc.getUids(folder.path));
3994
+ stillPresent = chunk.filter((uid) => serverUids.has(uid));
3995
+ }, { lane: "prefetch", timeoutMs: 60_000 });
3996
+ }
3997
+ catch { /* verification unavailable — keep the ERROR below */ }
3998
+ if (stillPresent !== null && stillPresent.length === 0) {
3999
+ console.log(` [prefetch] ${accountId}/${folder.path}: ${chunk.length} UID(s) no longer in folder (moved/deleted server-side) — reconcile owns the rows. UIDs: ${chunk.slice(0, 5).join(",")}${chunk.length > 5 ? "..." : ""}`);
4000
+ }
4001
+ else {
4002
+ console.error(` [prefetch] ${accountId}/${folder.path}: chunk ${chunkStart}-${chunkStart + chunk.length - 1} returned 0/${chunk.length} bodies${stillPresent ? ` for UIDs STILL PRESENT on server — real fetch failure` : ""} — NOT pruning (set-diff reconcile owns deletion). UIDs: ${chunk.slice(0, 5).join(",")}${chunk.length > 5 ? "..." : ""}`);
4003
+ }
3983
4004
  for (const uid of chunk)
3984
4005
  this.markPrefetchEmpty(accountId, folderId, uid);
3985
4006
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobfrankston/mailx-imap",
3
- "version": "0.1.115",
3
+ "version": "0.1.116",
4
4
  "type": "module",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -9,8 +9,8 @@
9
9
  },
10
10
  "license": "ISC",
11
11
  "dependencies": {
12
- "@bobfrankston/mailx-types": "^0.1.23",
13
- "@bobfrankston/mailx-settings": "^0.1.34",
12
+ "@bobfrankston/mailx-types": "^0.1.24",
13
+ "@bobfrankston/mailx-settings": "^0.1.35",
14
14
  "@bobfrankston/mailx-store": "^0.1.58",
15
15
  "@bobfrankston/iflow-direct": "^0.1.56",
16
16
  "@bobfrankston/tcp-transport": "^0.1.8",
@@ -37,8 +37,8 @@
37
37
  },
38
38
  ".transformedSnapshot": {
39
39
  "dependencies": {
40
- "@bobfrankston/mailx-types": "^0.1.23",
41
- "@bobfrankston/mailx-settings": "^0.1.34",
40
+ "@bobfrankston/mailx-types": "^0.1.24",
41
+ "@bobfrankston/mailx-settings": "^0.1.35",
42
42
  "@bobfrankston/mailx-store": "^0.1.58",
43
43
  "@bobfrankston/iflow-direct": "^0.1.56",
44
44
  "@bobfrankston/tcp-transport": "^0.1.8",