@bobfrankston/mailx-imap 0.1.113 → 0.1.115

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 (3) hide show
  1. package/index.d.ts +4 -1
  2. package/index.js +60 -6
  3. package/package.json +9 -9
package/index.d.ts CHANGED
@@ -701,7 +701,10 @@ export declare class ImapManager extends EventEmitter {
701
701
  * contacts added or removed in this run. */
702
702
  syncGoogleContacts(accountId: string): Promise<number>;
703
703
  private syncGoogleContactsImpl;
704
- /** Sync contacts for all OAuth accounts */
704
+ /** Sync contacts for all GOOGLE OAuth accounts. The People API only
705
+ * accepts Google tokens — feeding it an Outlook/AOL OAuth token just
706
+ * logged `API error for outlook: 401` on every periodic tick. Outlook
707
+ * contacts belong to the Graph provider (blocked on Azure app reg). */
705
708
  syncAllContacts(): Promise<void>;
706
709
  /** Shut down all watchers and timers */
707
710
  shutdown(): Promise<void>;
package/index.js CHANGED
@@ -906,7 +906,54 @@ export class ImapManager extends EventEmitter {
906
906
  // to re-enable for a debugging session. Default is quiet.
907
907
  const imapTrace = process.env.RMFMAIL_IMAP_TRACE === "1";
908
908
  const cfgWithVerbose = (imapTrace && (purpose === "ops" || purpose === "fast")) ? { ...config, verbose: true } : config;
909
- client = new CompatImapClient(cfgWithVerbose, this.transportFactory);
909
+ // C121: connect-phase progress. Wrap the injected transport so the
910
+ // socket phase (DNS+TCP+TLS inside transport.connect) is visibly
911
+ // distinct from the IMAP handshake (greeting + LOGIN, which run
912
+ // inside client.connect after the socket is up). The client shows
913
+ // "Connecting to <host> (<phase>, N.Ns)" from these events, so
914
+ // "DNS/TCP/TLS hung" vs "greeting missing" vs "LOGIN slow" are
915
+ // distinguishable at a glance instead of one opaque long wait.
916
+ let connT0 = Date.now();
917
+ const phaseT = {};
918
+ const emitPhase = (phase, detail) => {
919
+ phaseT[phase] = Date.now();
920
+ this.emit("connectProgress", accountId, {
921
+ host, purpose, phase, detail,
922
+ elapsedMs: Date.now() - connT0,
923
+ });
924
+ };
925
+ const phaseTimings = () => Object.entries(phaseT).map(([p, t]) => `${p}@${t - connT0}ms`).join(" ");
926
+ const wrappedFactory = () => {
927
+ const t = this.transportFactory();
928
+ const origTransportConnect = t.connect.bind(t);
929
+ t.connect = async (h, p, tls, sni) => {
930
+ emitPhase("socket");
931
+ await origTransportConnect(h, p, tls, sni);
932
+ emitPhase("handshake");
933
+ };
934
+ return t;
935
+ };
936
+ client = new CompatImapClient(cfgWithVerbose, wrappedFactory);
937
+ const origClientConnect = client.connect?.bind(client);
938
+ if (origClientConnect) {
939
+ client.connect = async (...a) => {
940
+ // Clock starts when the connect actually begins — clients
941
+ // are constructed eagerly but connect lazily on first use.
942
+ connT0 = Date.now();
943
+ try {
944
+ const r = await origClientConnect(...a);
945
+ emitPhase("done");
946
+ const total = Date.now() - connT0;
947
+ if (total > 3000)
948
+ console.log(` [conn-slow] ${accountId} (${purpose}): connect took ${total}ms — ${phaseTimings()}`);
949
+ return r;
950
+ }
951
+ catch (e) {
952
+ emitPhase("failed", e?.message || String(e));
953
+ throw e;
954
+ }
955
+ };
956
+ }
910
957
  }
911
958
  catch (e) {
912
959
  releaseHostSlot();
@@ -2172,7 +2219,7 @@ export class ImapManager extends EventEmitter {
2172
2219
  for (const uid of toDelete) {
2173
2220
  this.scheduleDeferredReconcileDelete(accountId, folderId, uid, folder.path);
2174
2221
  }
2175
- console.log(` [reconcile-defer] ${accountId}/${folder.path}: scheduled ${toDelete.length} deletes (60s grace for move-detect)`);
2222
+ console.log(` [reconcile-defer] ${accountId}/${folder.path}: scheduled ${toDelete.length} deletes (${ImapManager.RECONCILE_DELETE_GRACE_MS / 60_000}min grace for move-detect)`);
2176
2223
  }
2177
2224
  }
2178
2225
  catch (e) {
@@ -5996,13 +6043,20 @@ export class ImapManager extends EventEmitter {
5996
6043
  }
5997
6044
  return changed;
5998
6045
  }
5999
- /** Sync contacts for all OAuth accounts */
6046
+ /** Sync contacts for all GOOGLE OAuth accounts. The People API only
6047
+ * accepts Google tokens — feeding it an Outlook/AOL OAuth token just
6048
+ * logged `API error for outlook: 401` on every periodic tick. Outlook
6049
+ * contacts belong to the Graph provider (blocked on Azure app reg). */
6000
6050
  async syncAllContacts() {
6001
6051
  const settings = loadSettings();
6002
6052
  for (const account of settings.accounts) {
6003
- if (account.imap.auth === "oauth2" && (account.enabled || account.syncContacts)) {
6004
- await this.syncGoogleContacts(account.id);
6005
- }
6053
+ if (account.imap.auth !== "oauth2")
6054
+ continue;
6055
+ if (!(account.enabled || account.syncContacts))
6056
+ continue;
6057
+ if (!this.isGmailAccount(account.id))
6058
+ continue;
6059
+ await this.syncGoogleContacts(account.id);
6006
6060
  }
6007
6061
  }
6008
6062
  /** Shut down all watchers and timers */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobfrankston/mailx-imap",
3
- "version": "0.1.113",
3
+ "version": "0.1.115",
4
4
  "type": "module",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -9,14 +9,14 @@
9
9
  },
10
10
  "license": "ISC",
11
11
  "dependencies": {
12
- "@bobfrankston/mailx-types": "^0.1.22",
13
- "@bobfrankston/mailx-settings": "^0.1.33",
12
+ "@bobfrankston/mailx-types": "^0.1.23",
13
+ "@bobfrankston/mailx-settings": "^0.1.34",
14
14
  "@bobfrankston/mailx-store": "^0.1.58",
15
15
  "@bobfrankston/iflow-direct": "^0.1.56",
16
- "@bobfrankston/tcp-transport": "^0.1.7",
16
+ "@bobfrankston/tcp-transport": "^0.1.8",
17
17
  "@bobfrankston/smtp-direct": "^0.1.9",
18
18
  "@bobfrankston/mailx-sync": "^0.1.27",
19
- "@bobfrankston/oauthsupport": "^1.0.33"
19
+ "@bobfrankston/oauthsupport": "^1.0.34"
20
20
  },
21
21
  "repository": {
22
22
  "type": "git",
@@ -37,14 +37,14 @@
37
37
  },
38
38
  ".transformedSnapshot": {
39
39
  "dependencies": {
40
- "@bobfrankston/mailx-types": "^0.1.22",
41
- "@bobfrankston/mailx-settings": "^0.1.33",
40
+ "@bobfrankston/mailx-types": "^0.1.23",
41
+ "@bobfrankston/mailx-settings": "^0.1.34",
42
42
  "@bobfrankston/mailx-store": "^0.1.58",
43
43
  "@bobfrankston/iflow-direct": "^0.1.56",
44
- "@bobfrankston/tcp-transport": "^0.1.7",
44
+ "@bobfrankston/tcp-transport": "^0.1.8",
45
45
  "@bobfrankston/smtp-direct": "^0.1.9",
46
46
  "@bobfrankston/mailx-sync": "^0.1.27",
47
- "@bobfrankston/oauthsupport": "^1.0.33"
47
+ "@bobfrankston/oauthsupport": "^1.0.34"
48
48
  }
49
49
  }
50
50
  }