@bobfrankston/mailx-types 0.1.73 → 0.1.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/index.d.ts +11 -4
- package/index.js +1 -0
- package/log-changes.d.ts +29 -0
- package/log-changes.js +42 -0
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export { CONTACT_RULES } from "./contact-rules.js";
|
|
7
7
|
export { assessMessageTrust, spamScoreOf } from "./trust.js";
|
|
8
|
+
export { logIfChanged, clearLogState } from "./log-changes.js";
|
|
8
9
|
export type { TrustFinding, TrustInput, SpamScore } from "./trust.js";
|
|
9
10
|
export type { MailxApi } from "./mailx-api.js";
|
|
10
11
|
export { addContactsDenylistEntry, addContactsPreferredEntry, type PreferredContactEntry, type CloudReadFn, type CloudWriteFn, } from "./contacts-config.js";
|
|
@@ -54,11 +55,17 @@ export interface AccountConfig {
|
|
|
54
55
|
signature?: string; /** Legacy: HTML signature appended to all outgoing messages (new + reply + forward). Plain text or HTML allowed. Superseded by `sig`. */
|
|
55
56
|
sig?: AccountSignature; /** Per-account signature object. Initially appended only to NEW messages; later options will cover replies/forwards. */
|
|
56
57
|
}
|
|
57
|
-
/** Signature configuration in accounts.jsonc.
|
|
58
|
-
*
|
|
58
|
+
/** Signature configuration in accounts.jsonc. May be set per-account or once
|
|
59
|
+
* at the top level of the file, where it applies to every account that has
|
|
60
|
+
* no `sig` of its own. Appended by compose to new mail, replies and
|
|
61
|
+
* forwards; drafts already carry it in the saved body.
|
|
62
|
+
*
|
|
63
|
+
* 2026-09-02 — Claude Code (Opus 5), at Bob's direction: `html` is honoured
|
|
64
|
+
* (client/compose/compose.ts), not "reserved for future use" as this comment
|
|
65
|
+
* previously claimed. */
|
|
59
66
|
export interface AccountSignature {
|
|
60
|
-
text: string; /** Plain
|
|
61
|
-
html?: boolean; /**
|
|
67
|
+
text: string; /** Signature body. Plain text unless `html` is set. Appended to NEW messages with the standard "-- " RFC 3676 separator. */
|
|
68
|
+
html?: boolean; /** When true, `text` is inserted as raw HTML — write your own `<br>` for line breaks. When false/absent, `text` is HTML-escaped and newlines become `<br>`. */
|
|
62
69
|
}
|
|
63
70
|
/** Standard IMAP special-use folder types */
|
|
64
71
|
export type SpecialUse = "inbox" | "sent" | "drafts" | "trash" | "junk" | "archive" | "all";
|
package/index.js
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
// junk-contact filtering on every platform.
|
|
9
9
|
export { CONTACT_RULES } from "./contact-rules.js";
|
|
10
10
|
export { assessMessageTrust, spamScoreOf } from "./trust.js";
|
|
11
|
+
export { logIfChanged, clearLogState } from "./log-changes.js";
|
|
11
12
|
// Shared contacts.jsonc mutations — one implementation for desktop + Android.
|
|
12
13
|
export { addContactsDenylistEntry, addContactsPreferredEntry, } from "./contacts-config.js";
|
|
13
14
|
// Group-name expansion for recipient fields. Lets users type a group name
|
package/log-changes.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Log a line only when it says something new.
|
|
3
|
+
*
|
|
4
|
+
* Sync walks ~90 folders every cycle, and a folder in a bad state produces the
|
|
5
|
+
* SAME line every time — "reconcile refused — would delete 250/250 (100%)"
|
|
6
|
+
* once per folder per cycle, forever. On Android each of those is an HTTP
|
|
7
|
+
* request to the log server, and in the file the real news is buried under
|
|
8
|
+
* hundreds of identical repeats (Bob 2026-08-29: "are we overlogging").
|
|
9
|
+
*
|
|
10
|
+
* Deleting the lines is the wrong fix — a refused reconcile is a genuine
|
|
11
|
+
* anomaly and the log is where it surfaces. What is worth reading is the
|
|
12
|
+
* CHANGE: the first time a folder enters that state, and every time the
|
|
13
|
+
* numbers move. So the same key + same text is dropped, a changed text is
|
|
14
|
+
* printed, and a state that persists is re-stated once an hour so a standing
|
|
15
|
+
* problem cannot become invisible.
|
|
16
|
+
*
|
|
17
|
+
* Keyed by caller-supplied string (account + folder + which check), because
|
|
18
|
+
* two folders in the same state are two facts, not one.
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* @param key identifies the thing being described — "acct/folder:reconcile"
|
|
22
|
+
* @param line the message; identical text for the same key is suppressed
|
|
23
|
+
* @param emit where to write (defaults to console.log; pass a logger in libraries)
|
|
24
|
+
* @returns whether the line was emitted, so callers can count what they skipped
|
|
25
|
+
*/
|
|
26
|
+
export declare function logIfChanged(key: string, line: string, emit?: (msg: string) => void): boolean;
|
|
27
|
+
/** Forget a key — call when the condition clears, so its return is news again. */
|
|
28
|
+
export declare function clearLogState(key: string): void;
|
|
29
|
+
//# sourceMappingURL=log-changes.d.ts.map
|
package/log-changes.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Log a line only when it says something new.
|
|
3
|
+
*
|
|
4
|
+
* Sync walks ~90 folders every cycle, and a folder in a bad state produces the
|
|
5
|
+
* SAME line every time — "reconcile refused — would delete 250/250 (100%)"
|
|
6
|
+
* once per folder per cycle, forever. On Android each of those is an HTTP
|
|
7
|
+
* request to the log server, and in the file the real news is buried under
|
|
8
|
+
* hundreds of identical repeats (Bob 2026-08-29: "are we overlogging").
|
|
9
|
+
*
|
|
10
|
+
* Deleting the lines is the wrong fix — a refused reconcile is a genuine
|
|
11
|
+
* anomaly and the log is where it surfaces. What is worth reading is the
|
|
12
|
+
* CHANGE: the first time a folder enters that state, and every time the
|
|
13
|
+
* numbers move. So the same key + same text is dropped, a changed text is
|
|
14
|
+
* printed, and a state that persists is re-stated once an hour so a standing
|
|
15
|
+
* problem cannot become invisible.
|
|
16
|
+
*
|
|
17
|
+
* Keyed by caller-supplied string (account + folder + which check), because
|
|
18
|
+
* two folders in the same state are two facts, not one.
|
|
19
|
+
*/
|
|
20
|
+
/** How long an unchanged line stays suppressed before being restated. */
|
|
21
|
+
const RESTATE_AFTER_MS = 60 * 60 * 1000;
|
|
22
|
+
const lastSeen = new Map();
|
|
23
|
+
/**
|
|
24
|
+
* @param key identifies the thing being described — "acct/folder:reconcile"
|
|
25
|
+
* @param line the message; identical text for the same key is suppressed
|
|
26
|
+
* @param emit where to write (defaults to console.log; pass a logger in libraries)
|
|
27
|
+
* @returns whether the line was emitted, so callers can count what they skipped
|
|
28
|
+
*/
|
|
29
|
+
export function logIfChanged(key, line, emit = console.log) {
|
|
30
|
+
const now = Date.now();
|
|
31
|
+
const prev = lastSeen.get(key);
|
|
32
|
+
if (prev && prev.line === line && now - prev.at < RESTATE_AFTER_MS)
|
|
33
|
+
return false;
|
|
34
|
+
lastSeen.set(key, { line, at: now });
|
|
35
|
+
emit(prev && prev.line === line ? `${line} (unchanged for an hour)` : line);
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
/** Forget a key — call when the condition clears, so its return is news again. */
|
|
39
|
+
export function clearLogState(key) {
|
|
40
|
+
lastSeen.delete(key);
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=log-changes.js.map
|