@bobfrankston/rmfmail 1.0.694 → 1.0.696

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 (42) hide show
  1. package/client/app.bundle.js +63 -64
  2. package/client/app.bundle.js.map +2 -2
  3. package/client/app.js +41 -36
  4. package/client/app.js.map +1 -1
  5. package/client/app.ts +39 -32
  6. package/client/components/folder-tree.js +36 -37
  7. package/client/components/folder-tree.js.map +1 -1
  8. package/client/components/folder-tree.ts +33 -33
  9. package/client/components/message-list.js +17 -7
  10. package/client/components/message-list.js.map +1 -1
  11. package/client/components/message-list.ts +14 -6
  12. package/client/index.html +14 -0
  13. package/package.json +1 -1
  14. package/packages/mailx-core/index.d.ts.map +1 -1
  15. package/packages/mailx-core/index.js +2 -3
  16. package/packages/mailx-core/index.js.map +1 -1
  17. package/packages/mailx-core/index.ts +2 -3
  18. package/packages/mailx-imap/index.d.ts.map +1 -1
  19. package/packages/mailx-imap/index.js +3 -5
  20. package/packages/mailx-imap/index.js.map +1 -1
  21. package/packages/mailx-imap/index.ts +3 -5
  22. package/packages/mailx-imap/package-lock.json +2 -2
  23. package/packages/mailx-imap/package.json +1 -1
  24. package/packages/mailx-service/index.d.ts.map +1 -1
  25. package/packages/mailx-service/index.js +2 -2
  26. package/packages/mailx-service/index.js.map +1 -1
  27. package/packages/mailx-service/index.ts +2 -3
  28. package/packages/mailx-service/local-store.js +2 -2
  29. package/packages/mailx-service/local-store.js.map +1 -1
  30. package/packages/mailx-service/local-store.ts +2 -2
  31. package/packages/mailx-store/index.d.ts +1 -0
  32. package/packages/mailx-store/index.d.ts.map +1 -1
  33. package/packages/mailx-store/index.js +1 -0
  34. package/packages/mailx-store/index.js.map +1 -1
  35. package/packages/mailx-store/index.ts +1 -0
  36. package/packages/mailx-store/package.json +3 -2
  37. package/packages/mailx-store/parse-serial.d.ts +33 -0
  38. package/packages/mailx-store/parse-serial.d.ts.map +1 -0
  39. package/packages/mailx-store/parse-serial.js +38 -0
  40. package/packages/mailx-store/parse-serial.js.map +1 -0
  41. package/packages/mailx-store/parse-serial.ts +40 -0
  42. /package/packages/mailx-imap/{node_modules.npmglobalize-stash-9032 → node_modules.npmglobalize-stash-34224}/.package-lock.json +0 -0
package/client/app.js CHANGED
@@ -1232,21 +1232,23 @@ async function deleteSelectedMessages() {
1232
1232
  if (statusSync?.textContent?.includes("undo"))
1233
1233
  statusSync.textContent = "";
1234
1234
  }, 30000);
1235
- try {
1236
- const byAccount = new Map();
1237
- for (const msg of snapshot) {
1238
- const uids = byAccount.get(msg.accountId) || [];
1239
- uids.push(msg.uid);
1240
- byAccount.set(msg.accountId, uids);
1241
- }
1242
- for (const [accountId, uids] of byAccount) {
1243
- await deleteMessages(accountId, uids);
1244
- }
1245
- }
1246
- catch (e) {
1247
- console.error(`Delete failed: ${e.message}`);
1248
- if (statusSync)
1249
- statusSync.textContent = `Delete failed: ${e?.message || e}`;
1235
+ // Fire-and-forget per local-first: optimistic remove above already
1236
+ // updated the UI; the daemon-side trash is sync DB + queued IMAP.
1237
+ // An IPC 120s timeout doesn't mean the trash failed — surfacing it
1238
+ // as a status-bar error would only mislead. Real errors are still
1239
+ // reported by next sync's diagnostics.
1240
+ const byAccount = new Map();
1241
+ for (const msg of snapshot) {
1242
+ const uids = byAccount.get(msg.accountId) || [];
1243
+ uids.push(msg.uid);
1244
+ byAccount.set(msg.accountId, uids);
1245
+ }
1246
+ for (const [accountId, uids] of byAccount) {
1247
+ deleteMessages(accountId, uids).catch((e) => {
1248
+ console.error(`Delete failed for ${accountId}: ${e?.message || e}`);
1249
+ if (statusSync)
1250
+ statusSync.textContent = `Delete sync issue (${accountId}): ${e?.message || e}`;
1251
+ });
1250
1252
  }
1251
1253
  }
1252
1254
  async function undoDelete() {
@@ -1357,28 +1359,31 @@ async function spamSelectedMessages() {
1357
1359
  // sync is a background detail, the user's action should feel instant.
1358
1360
  const snapshot = [...selected];
1359
1361
  removeMessagesAndReconcile(selected);
1360
- try {
1361
- const byAccount = new Map();
1362
- for (const msg of snapshot) {
1363
- const uids = byAccount.get(msg.accountId) || [];
1364
- uids.push(msg.uid);
1365
- byAccount.set(msg.accountId, uids);
1366
- }
1367
- for (const [accountId, uids] of byAccount) {
1368
- const result = await markAsSpamMessages(accountId, uids);
1369
- console.log(`[spam] ${accountId}: moved ${result?.moved ?? uids.length} to folderId=${result?.targetFolderId}`);
1370
- }
1371
- if (statusSync)
1372
- statusSync.textContent = `Spam: ${snapshot.length} queued — pending server sync`;
1362
+ // Fire-and-forget per local-first: the optimistic remove above has
1363
+ // already updated the UI; the service-side move is sync DB + queued
1364
+ // IMAP. An IPC 120s timeout here doesn't mean the move failed — it
1365
+ // means the response is stuck behind a long-running prior op (e.g.
1366
+ // simpleParser blocking the event loop). The local commit and server
1367
+ // sync still happen. Surfacing it as a failure with an alert lies to
1368
+ // the user; the next folder reload reconciles either way.
1369
+ const byAccount = new Map();
1370
+ for (const msg of snapshot) {
1371
+ const uids = byAccount.get(msg.accountId) || [];
1372
+ uids.push(msg.uid);
1373
+ byAccount.set(msg.accountId, uids);
1373
1374
  }
1374
- catch (e) {
1375
- console.error(`[spam] failed:`, e);
1376
- if (statusSync)
1377
- statusSync.textContent = `Spam failed: ${e?.message || e}`;
1378
- alert(`Mark-as-spam failed: ${e?.message || e}\n\n${selected.length} message(s) stayed in the list; check Settings → account spam folder and accounts.jsonc.`);
1379
- // Best-effort restore: re-set the messages we optimistically removed.
1380
- // removeMessages has no inverse in message-state, so we'll rely on the
1381
- // next folder reload to repopulate. Surface the failure clearly.
1375
+ if (statusSync)
1376
+ statusSync.textContent = `Spam: ${snapshot.length} queued — pending server sync`;
1377
+ for (const [accountId, uids] of byAccount) {
1378
+ markAsSpamMessages(accountId, uids)
1379
+ .then(result => {
1380
+ console.log(`[spam] ${accountId}: moved ${result?.moved ?? uids.length} to folderId=${result?.targetFolderId}`);
1381
+ })
1382
+ .catch(e => {
1383
+ console.error(`[spam] ${accountId} failed:`, e);
1384
+ if (statusSync)
1385
+ statusSync.textContent = `Spam sync issue (${accountId}): ${e?.message || e}`;
1386
+ });
1382
1387
  }
1383
1388
  }
1384
1389
  document.getElementById("btn-spam")?.addEventListener("click", spamSelectedMessages);