@bobfrankston/rmfmail 1.2.77 → 1.2.78
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.
- package/client/android-bootstrap.bundle.js +43 -28
- package/client/android-bootstrap.bundle.js.map +2 -2
- package/package.json +3 -3
- package/packages/mailx-store-web/android-bootstrap.d.ts.map +1 -1
- package/packages/mailx-store-web/android-bootstrap.js +50 -39
- package/packages/mailx-store-web/android-bootstrap.js.map +1 -1
- package/packages/mailx-store-web/android-bootstrap.ts +52 -37
- package/packages/mailx-store-web/package.json +1 -1
|
@@ -9796,6 +9796,11 @@ var AndroidSyncManager = class {
|
|
|
9796
9796
|
// advanced to fetching new mail, so the list stayed stale despite "Synced"
|
|
9797
9797
|
// (Bob 2026-06-27). Coalesce concurrent calls to one in-flight run.
|
|
9798
9798
|
syncAllInflight = null;
|
|
9799
|
+
// Separate guard for the Phase-2/3 background pass (other folders + body
|
|
9800
|
+
// prefetch). It runs DETACHED from the inbox guard so a long folder sweep
|
|
9801
|
+
// can't make the 60s poll skip the inbox refresh (new mail must keep
|
|
9802
|
+
// flowing). One background pass at a time — overlapping triggers no-op.
|
|
9803
|
+
bgSyncInflight = null;
|
|
9799
9804
|
on(_event, _handler) {
|
|
9800
9805
|
}
|
|
9801
9806
|
emit(event, ...args) {
|
|
@@ -9850,41 +9855,53 @@ var AndroidSyncManager = class {
|
|
|
9850
9855
|
}
|
|
9851
9856
|
async syncAll() {
|
|
9852
9857
|
if (this.syncAllInflight) {
|
|
9853
|
-
console.log("[sync]
|
|
9858
|
+
console.log("[sync] inbox sync already in flight \u2014 coalescing this trigger");
|
|
9854
9859
|
return this.syncAllInflight;
|
|
9855
9860
|
}
|
|
9856
9861
|
const t0 = Date.now();
|
|
9857
|
-
console.log("[sync] syncAll START");
|
|
9858
|
-
this.syncAllInflight = this.
|
|
9859
|
-
console.error(`[sync]
|
|
9862
|
+
console.log("[sync] syncAll START (inbox phase)");
|
|
9863
|
+
this.syncAllInflight = this._syncInboxes().catch((e) => {
|
|
9864
|
+
console.error(`[sync] inbox sync error: ${e?.message || e}`);
|
|
9860
9865
|
}).finally(() => {
|
|
9861
|
-
console.log(`[sync]
|
|
9866
|
+
console.log(`[sync] inbox phase DONE in ${Date.now() - t0}ms`);
|
|
9862
9867
|
this.syncAllInflight = null;
|
|
9863
9868
|
});
|
|
9869
|
+
this._kickBackgroundSync();
|
|
9864
9870
|
return this.syncAllInflight;
|
|
9865
9871
|
}
|
|
9866
|
-
|
|
9867
|
-
|
|
9868
|
-
|
|
9869
|
-
|
|
9870
|
-
|
|
9871
|
-
|
|
9872
|
-
|
|
9873
|
-
|
|
9874
|
-
|
|
9875
|
-
|
|
9876
|
-
|
|
9877
|
-
|
|
9878
|
-
|
|
9879
|
-
|
|
9880
|
-
}
|
|
9881
|
-
|
|
9882
|
-
|
|
9883
|
-
|
|
9884
|
-
|
|
9885
|
-
|
|
9872
|
+
/** Phase 1: sync every account's INBOX IN PARALLEL so a slow account (e.g.
|
|
9873
|
+
* Gmail's metadata fetch, or an auth-failing IMAP account) can't delay new
|
|
9874
|
+
* mail for the others. Each account is time-boxed; network fetches overlap
|
|
9875
|
+
* even though JS is single-threaded (the awaits yield). */
|
|
9876
|
+
async _syncInboxes() {
|
|
9877
|
+
const accounts = this.db.getAccounts().filter((a) => this.providers.has(a.id));
|
|
9878
|
+
vlog(`syncInboxes: ${accounts.length} accounts: ${accounts.map((a) => a.id).join(",")}`);
|
|
9879
|
+
await Promise.all(accounts.map(
|
|
9880
|
+
(account) => withTimeout(`${account.id} inbox`, 6e4, async () => {
|
|
9881
|
+
const folders = await this.syncFolders(account.id);
|
|
9882
|
+
const inbox = folders.find((f) => f.specialUse === "inbox");
|
|
9883
|
+
if (inbox) {
|
|
9884
|
+
console.log(`[sync] ${account.id}: fetching INBOX (folderId=${inbox.id})`);
|
|
9885
|
+
await this.syncFolder(account.id, inbox.id);
|
|
9886
|
+
console.log(`[sync] ${account.id}: INBOX fetch done`);
|
|
9887
|
+
emitEvent({ type: "syncComplete", accountId: account.id });
|
|
9888
|
+
}
|
|
9889
|
+
}).catch((e) => console.error(`[sync] ${account.id} inbox: ${e?.message || e}`))
|
|
9890
|
+
));
|
|
9891
|
+
}
|
|
9892
|
+
/** Phase 2 + 3: remaining folders, then body prefetch. Runs in the
|
|
9893
|
+
* background under its own single-flight guard. */
|
|
9894
|
+
_kickBackgroundSync() {
|
|
9895
|
+
if (this.bgSyncInflight) return;
|
|
9896
|
+
const t0 = Date.now();
|
|
9897
|
+
this.bgSyncInflight = this._syncRemainingAndPrefetch().catch((e) => console.error(`[sync] background sweep error: ${e?.message || e}`)).finally(() => {
|
|
9898
|
+
console.log(`[sync] background sweep DONE in ${Date.now() - t0}ms`);
|
|
9899
|
+
this.bgSyncInflight = null;
|
|
9900
|
+
});
|
|
9901
|
+
}
|
|
9902
|
+
async _syncRemainingAndPrefetch() {
|
|
9903
|
+
const accounts = this.db.getAccounts().filter((a) => this.providers.has(a.id));
|
|
9886
9904
|
for (const account of accounts) {
|
|
9887
|
-
if (!this.providers.has(account.id)) continue;
|
|
9888
9905
|
try {
|
|
9889
9906
|
const folders = this.db.getFolders(account.id);
|
|
9890
9907
|
const remaining = folders.filter((f) => f.specialUse !== "inbox");
|
|
@@ -9899,12 +9916,10 @@ var AndroidSyncManager = class {
|
|
|
9899
9916
|
emitEvent({ type: "syncComplete", accountId: account.id });
|
|
9900
9917
|
} catch (e) {
|
|
9901
9918
|
console.error(`[sync] ${account.id}: ${e.message}`);
|
|
9902
|
-
vlog(`syncAll: ${account.id} ERROR: ${e.message}`);
|
|
9903
9919
|
emitEvent({ type: "syncError", accountId: account.id, error: e.message });
|
|
9904
9920
|
}
|
|
9905
9921
|
}
|
|
9906
9922
|
for (const account of accounts) {
|
|
9907
|
-
if (!this.providers.has(account.id)) continue;
|
|
9908
9923
|
this.prefetchBodies(account.id).catch((e) => console.error(`[prefetch] ${account.id}: ${e.message}`));
|
|
9909
9924
|
}
|
|
9910
9925
|
}
|