@bobfrankston/mailx-imap 0.1.36 → 0.1.37

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 +31 -6
  2. package/package.json +5 -5
package/index.js CHANGED
@@ -3152,6 +3152,34 @@ export class ImapManager extends EventEmitter {
3152
3152
  return;
3153
3153
  if (!draftUid && !draftId)
3154
3154
  return;
3155
+ // Local-first: drop the draft from the local DB FIRST so the user's
3156
+ // Drafts view reflects the Send click instantly. The IMAP delete is
3157
+ // queued for the background reconciler. Without this, the draft
3158
+ // stayed visible in Drafts until the IMAP round-trip completed (or
3159
+ // forever if it failed) — Bob 2026-05-12: "when I send a letter you
3160
+ // seem to still leave it in draft so I don't know if it has been
3161
+ // sent or not. Once you hand it off it must leave draft."
3162
+ let localDeletedUid = 0;
3163
+ if (draftUid) {
3164
+ const existing = this.db.getMessageByUid(accountId, draftUid, drafts.id);
3165
+ if (existing) {
3166
+ this.unlinkBodyFile(accountId, draftUid, drafts.id).catch(() => { });
3167
+ this.db.deleteMessage(accountId, draftUid, "user sent the message (draft cleanup)", "mailx-imap deleteDraft (local)");
3168
+ localDeletedUid = draftUid;
3169
+ }
3170
+ }
3171
+ if (draftId && !localDeletedUid) {
3172
+ // Look up any local draft rows by X-Mailx-Draft-ID. The DB
3173
+ // doesn't index that header directly, but locally-saved drafts
3174
+ // share a stable header set; rely on the UID path 99% of the
3175
+ // time. This branch covers the "draft was saved on another
3176
+ // device, came in via sync, no UID known yet" edge case — for
3177
+ // now the IMAP path below handles it.
3178
+ }
3179
+ if (localDeletedUid > 0) {
3180
+ this.db.recalcFolderCounts(drafts.id);
3181
+ this.emit("folderCountsChanged", accountId, {});
3182
+ }
3155
3183
  let succeeded = false;
3156
3184
  try {
3157
3185
  await this.withConnection(accountId, async (client) => {
@@ -3190,12 +3218,9 @@ export class ImapManager extends EventEmitter {
3190
3218
  console.error(` [drafts] withConnection failed for ${accountId}: ${e?.message || e}`);
3191
3219
  }
3192
3220
  // Reliable cleanup: if the inline attempt didn't actually delete the
3193
- // draft, queue a sync_action so the regular processSyncActions loop
3194
- // retries it later. Without this, transient IMAP failures left stale
3195
- // drafts in the folder ("draft droppings" that pile up after sends).
3196
- // Only the UID path can be queued — searchByHeader retries on every
3197
- // future call anyway, and queuing a header-lookup isn't a real
3198
- // sync_action shape.
3221
+ // draft on the server, queue a sync_action so the regular
3222
+ // processSyncActions loop retries it later. The local row is already
3223
+ // gone (above), so the user doesn't see stale UI either way.
3199
3224
  if (!succeeded && draftUid) {
3200
3225
  console.log(` [drafts] Queueing sync_action for retry: delete UID ${draftUid} in ${drafts.path}`);
3201
3226
  this.db.queueSyncAction(accountId, "delete", draftUid, drafts.id);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobfrankston/mailx-imap",
3
- "version": "0.1.36",
3
+ "version": "0.1.37",
4
4
  "type": "module",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -9,10 +9,10 @@
9
9
  },
10
10
  "license": "ISC",
11
11
  "dependencies": {
12
- "@bobfrankston/mailx-types": "^0.1.10",
12
+ "@bobfrankston/mailx-types": "^0.1.11",
13
13
  "@bobfrankston/mailx-settings": "^0.1.14",
14
14
  "@bobfrankston/mailx-store": "^0.1.18",
15
- "@bobfrankston/iflow-direct": "^0.1.40",
15
+ "@bobfrankston/iflow-direct": "^0.1.41",
16
16
  "@bobfrankston/tcp-transport": "^0.1.6",
17
17
  "@bobfrankston/smtp-direct": "^0.1.8",
18
18
  "@bobfrankston/mailx-sync": "^0.1.16",
@@ -37,10 +37,10 @@
37
37
  },
38
38
  ".transformedSnapshot": {
39
39
  "dependencies": {
40
- "@bobfrankston/mailx-types": "^0.1.10",
40
+ "@bobfrankston/mailx-types": "^0.1.11",
41
41
  "@bobfrankston/mailx-settings": "^0.1.14",
42
42
  "@bobfrankston/mailx-store": "^0.1.18",
43
- "@bobfrankston/iflow-direct": "^0.1.40",
43
+ "@bobfrankston/iflow-direct": "^0.1.41",
44
44
  "@bobfrankston/tcp-transport": "^0.1.6",
45
45
  "@bobfrankston/smtp-direct": "^0.1.8",
46
46
  "@bobfrankston/mailx-sync": "^0.1.16",