@wirecat/cli-core 0.490.0 → 0.491.0
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/CHANGELOG.md +8 -1
- package/dist/mail/sync.js +14 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,7 +5,14 @@ Notable changes to `@wirecat/cli-core` (`@wirecat/cli-messaging` up to 0.261.0,
|
|
|
5
5
|
minor version may break callers, and says how under "Changed — may break callers". `pnpm docs:check` checks the
|
|
6
6
|
shape of this file.
|
|
7
7
|
|
|
8
|
-
##
|
|
8
|
+
## 0.491.0 — 31.10.2026
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- **A budgeted mail sync now finishes locating a large folder stored before email locations existed.** It listed
|
|
13
|
+
the same newest messages every run, so a 16,100-message INBOX never got every UID stored and never switched to
|
|
14
|
+
the quick UID listing. Each budgeted run now leaves out the mail already done and located and lists the next
|
|
15
|
+
part; once the rest is listed whole, the folder is located. Such a run checks no deletions.
|
|
9
16
|
|
|
10
17
|
## 0.490.0 — 31.10.2026
|
|
11
18
|
|
package/dist/mail/sync.js
CHANGED
|
@@ -147,6 +147,8 @@ const syncRound = async (source, store, { account, since, max = 200, maxBodyChar
|
|
|
147
147
|
/** Every folder's stored point, valid or not: the widest window outlives what invalidates the rest. */
|
|
148
148
|
const storedPoints = new Map();
|
|
149
149
|
const resumed = new Set();
|
|
150
|
+
/** Backfilling folders listed without the mail already done and located: their listing proves no deletion. */
|
|
151
|
+
const narrowed = new Set();
|
|
150
152
|
let mboxPoint;
|
|
151
153
|
let mboxStamp;
|
|
152
154
|
// A rerun lists only what the last left; --rescan, a rule change or a new UIDVALIDITY lists everything again.
|
|
@@ -254,6 +256,15 @@ const syncRound = async (source, store, { account, since, max = 200, maxBodyChar
|
|
|
254
256
|
resumed.add(folder);
|
|
255
257
|
wanted = { ...searched, uids: searched.uids.filter((uid) => !within(point.done, Number(uid))) };
|
|
256
258
|
}
|
|
259
|
+
else if (backfill && plan !== undefined) {
|
|
260
|
+
// A budgeted run lists newest first, so a backfill that starts over every run never reaches the oldest mail.
|
|
261
|
+
const placed = new Set((await store.mail.folderEmails(accountId, folder, searched.validity)).map(({ uid }) => uid));
|
|
262
|
+
const left = searched.uids.filter((uid) => !(placed.has(Number(uid)) && within(point.done, Number(uid))));
|
|
263
|
+
if (left.length < searched.uids.length) {
|
|
264
|
+
narrowed.add(folder);
|
|
265
|
+
wanted = { ...searched, uids: left };
|
|
266
|
+
}
|
|
267
|
+
}
|
|
257
268
|
}
|
|
258
269
|
if (plan !== undefined) {
|
|
259
270
|
plan.modes.set(folder, resumed.has(folder) ? "resumed" : "full");
|
|
@@ -364,6 +375,8 @@ const syncRound = async (source, store, { account, since, max = 200, maxBodyChar
|
|
|
364
375
|
? "folders this run did not list by UID are not checked for deletions; --rescan lists every message and checks them"
|
|
365
376
|
: undefined);
|
|
366
377
|
}
|
|
378
|
+
else if (narrowed.size > 0)
|
|
379
|
+
skipped = "this run listed only mail whose place is not stored yet; once every place is, deletions are checked";
|
|
367
380
|
else if (resumed.size > 0)
|
|
368
381
|
skipped =
|
|
369
382
|
"this run listed only mail not read before; a full listing, at least daily or with --rescan, checks deletions";
|
|
@@ -487,6 +500,7 @@ const syncRound = async (source, store, { account, since, max = 200, maxBodyChar
|
|
|
487
500
|
// A narrower whole listing, like the timer's 30 days, does not replace a wider one that is still fresh.
|
|
488
501
|
const keepFull = before !== undefined &&
|
|
489
502
|
(resumed.has(folder) ||
|
|
503
|
+
narrowed.has(folder) ||
|
|
490
504
|
(Date.parse(before.full.since) < since.getTime() && startedAt - Date.parse(before.full.at) < FULL_PASS_MS));
|
|
491
505
|
const merged = mergeRanges(before?.done ?? [], rangesOf(done));
|
|
492
506
|
const widest = before === undefined || since.getTime() <= Date.parse(before.window.since);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wirecat/cli-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.491.0",
|
|
4
4
|
"description": "The messenger-neutral half of a messaging CLI: domain model, message locators, rendering, name resolution, the SQLite seam, the command skeleton and shared read commands, the send guard, run records and the message store",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Viacheslav Ptsarev",
|