@bobfrankston/rmfmail 1.2.335 → 1.2.337

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.
@@ -2405,10 +2405,17 @@ export class MailxService implements MailxApi {
2405
2405
  const SERVER_SEARCH_BATCH = 8;
2406
2406
 
2407
2407
  let aborted = false;
2408
+ // 2026-09-16 — Claude Code (Fable 5.1), at Bob's direction ("make
2409
+ // server search honor the folder dropdown"). A folderId means the
2410
+ // scope dropdown says "This folder": sweep only that folder on that
2411
+ // account. folderId 0 / absent = every selectable folder everywhere.
2412
+ const scopedAccounts = folderId && accountId ? dbAccounts.filter((a: any) => a.id === accountId) : dbAccounts;
2413
+ if (folderId) console.log(` [server-search] q="${q}" scoped to ${accountId}/folder ${folderId}`);
2408
2414
  outer:
2409
- for (const acct of dbAccounts) {
2415
+ for (const acct of scopedAccounts) {
2410
2416
  const folders = this.db.getFolders(acct.id)
2411
2417
  .filter((f: any) => !(f.flags || []).some((x: string) => /noselect/i.test(x)))
2418
+ .filter((f: any) => !folderId || f.id === folderId)
2412
2419
  .filter((f: any) => folderTerms.length === 0 || folderTerms.some(t =>
2413
2420
  (f.name || "").toLowerCase().includes(t) || (f.path || "").toLowerCase().includes(t)));
2414
2421
  for (let i = 0; i < folders.length; i += SERVER_SEARCH_BATCH) {
@@ -3728,7 +3735,21 @@ export class MailxService implements MailxApi {
3728
3735
  try {
3729
3736
  (this.imapManager as any).emit?.("folderCountsChanged", accountId, {});
3730
3737
  } catch { /* non-fatal */ }
3731
- await this.imapManager.emptyFolderViaServer(accountId, folder.path);
3738
+ // 2026-09-16 — Claude Code (Fable 5.1), at Bob's direction. Local-first:
3739
+ // the local commit above IS the user's result; the server purge is a
3740
+ // background mirror. This used to be awaited, so the WebView's IPC call
3741
+ // sat on a per-message IMAP delete loop and expired ("Failed: mailxapi
3742
+ // timeout: emptyFolder") while the server kept deleting. Failures now
3743
+ // surface through the syncError banner instead of a dead IPC promise.
3744
+ const started = Date.now();
3745
+ console.log(` [folder] ${accountId}: emptying "${folder.path}" on the server (background)`);
3746
+ void this.imapManager.emptyFolderViaServer(accountId, folder.path)
3747
+ .then((n: number) => console.log(` [folder] ${accountId}: emptied "${folder.path}" on the server — ${n} message(s) in ${Date.now() - started} ms`))
3748
+ .catch((e: any) => {
3749
+ console.error(` [folder] ${accountId}: empty "${folder.path}" on the server FAILED: ${e?.message || e}`);
3750
+ try { (this.imapManager as any).emit?.("syncError", accountId, `Emptying "${folder.name}" on the server failed: ${e?.message || e}. The local copy is cleared; the next sync will show what remains.`); }
3751
+ catch { /* the banner is best-effort; the console line above is the record */ }
3752
+ });
3732
3753
  }
3733
3754
 
3734
3755
  // ── Attachments ──
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobfrankston/mailx-service",
3
- "version": "0.1.42",
3
+ "version": "0.1.43",
4
4
  "type": "module",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobfrankston/mailx-store-web",
3
- "version": "0.1.120",
3
+ "version": "0.1.121",
4
4
  "type": "module",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",