@bobfrankston/mailx-sync 0.1.23 → 0.1.24

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/gmail.js +12 -1
  2. package/package.json +1 -1
  3. package/types.d.ts +8 -0
package/gmail.js CHANGED
@@ -322,7 +322,18 @@ export class GmailApiProvider {
322
322
  // is self-limiting. Otherwise cap at the recent 200.
323
323
  const cap = options.since ? 0 : 200;
324
324
  const ids = await this.listMessageIds(query, cap);
325
- return this.batchFetch(ids, options);
325
+ // Skip IDs already in the local store: the listing above is one cheap
326
+ // call, but fetching each message's metadata is a sequential per-ID GET
327
+ // (~200ms). Without this, a routine sync re-fetched all ~200 recent
328
+ // messages every time (~40s) just to discover nothing was new. With the
329
+ // caller's known-UID set, steady state fetches zero (Bob 2026-06-27).
330
+ const fresh = options.knownUids
331
+ ? ids.filter(id => !options.knownUids.has(idToUid(id)))
332
+ : ids;
333
+ if (options.knownUids) {
334
+ console.log(`[gmail] fetchSince ${folder}: ${ids.length} listed, ${ids.length - fresh.length} already stored, fetching ${fresh.length}`);
335
+ }
336
+ return this.batchFetch(fresh, options);
326
337
  }
327
338
  async fetchByDate(folder, since, before, options = {}, onChunk) {
328
339
  const afterDate = this.formatDate(since);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobfrankston/mailx-sync",
3
- "version": "0.1.23",
3
+ "version": "0.1.24",
4
4
  "description": "Platform-agnostic mail provider implementations + sync orchestration. Single source of truth for Gmail/IMAP/Outlook protocol code, consumed by both desktop (Node) and Android (WebView) — eliminates the parallel mailx-imap/mailx-store-web Gmail providers that drifted in practice.",
5
5
  "main": "index.js",
6
6
  "types": "index.ts",
package/types.d.ts CHANGED
@@ -47,6 +47,14 @@ export interface FetchOptions {
47
47
  * the default page-count cap doesn't silently truncate a large folder
48
48
  * to the last ~200 messages. */
49
49
  since?: Date;
50
+ /** UIDs already present in the local store for this folder. Providers whose
51
+ * incremental sync re-lists a fixed recent page (Gmail — IDs aren't
52
+ * monotonic, so it can't use a high-water mark) use this to SKIP fetching
53
+ * metadata for messages already stored: list IDs (one cheap call), drop the
54
+ * known ones, fetch only the genuinely-new. Steady state (nothing new) then
55
+ * costs one list call and zero per-message GETs instead of re-fetching 200
56
+ * one-by-one (~40s on mobile → near-instant) (Bob 2026-06-27). */
57
+ knownUids?: Set<number>;
50
58
  }
51
59
  /**
52
60
  * A mail provider that can list folders, fetch messages, and perform actions.