@bobfrankston/rmfmail 1.0.697 → 1.0.699

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.
@@ -29,12 +29,53 @@
29
29
 
30
30
  import { simpleParser, type ParsedMail, type Source } from "mailparser";
31
31
 
32
- let _chain: Promise<unknown> = Promise.resolve();
32
+ /**
33
+ * Priority queue. A background pump runs the next pending parse; UI calls
34
+ * insert at the head of the line, sync calls go to the tail. Without this,
35
+ * a first-sync of 96 folders × thousands of messages each can queue
36
+ * thousands of `extractPreview` parses ahead of a single user click — the
37
+ * preview pane sits on "Loading body…" for minutes while the back-fill
38
+ * grinds through. Same parses, different order.
39
+ */
40
+ type Pending = {
41
+ source: Source;
42
+ resolve: (m: ParsedMail) => void;
43
+ reject: (e: unknown) => void;
44
+ };
45
+ const _head: Pending[] = []; // UI / foreground — drained first
46
+ const _tail: Pending[] = []; // sync / background
47
+ let _pumping = false;
48
+
49
+ async function pump(): Promise<void> {
50
+ if (_pumping) return;
51
+ _pumping = true;
52
+ try {
53
+ for (;;) {
54
+ const next = _head.shift() ?? _tail.shift();
55
+ if (!next) break;
56
+ try {
57
+ const parsed = await simpleParser(next.source);
58
+ next.resolve(parsed);
59
+ } catch (e) {
60
+ next.reject(e);
61
+ }
62
+ }
63
+ } finally {
64
+ _pumping = false;
65
+ }
66
+ }
33
67
 
34
- /** Serialized wrapper around `mailparser.simpleParser`. Drop-in replacement —
35
- * same signature, same return value. */
36
- export async function parseSerial(source: Source): Promise<ParsedMail> {
37
- const queued: Promise<ParsedMail> = _chain.then((): Promise<ParsedMail> => simpleParser(source));
38
- _chain = queued.catch((): undefined => undefined);
39
- return queued;
68
+ /** Serialized wrapper around `mailparser.simpleParser`. `priority` defaults
69
+ * to "foreground" only sync/background callers should pass "background"
70
+ * so user clicks aren't stuck behind a back-fill. */
71
+ export async function parseSerial(
72
+ source: Source,
73
+ priority: "foreground" | "background" = "foreground",
74
+ ): Promise<ParsedMail> {
75
+ return new Promise<ParsedMail>((resolve, reject) => {
76
+ const entry: Pending = { source, resolve, reject };
77
+ if (priority === "foreground") _head.push(entry);
78
+ else _tail.push(entry);
79
+ pump();
80
+ });
40
81
  }
@@ -1,116 +0,0 @@
1
- {
2
- "name": "@bobfrankston/mailx-imap",
3
- "version": "0.1.12",
4
- "lockfileVersion": 3,
5
- "requires": true,
6
- "packages": {
7
- "../../../../projects/oauth/oauthsupport": {
8
- "name": "@bobfrankston/oauthsupport",
9
- "version": "1.0.25",
10
- "license": "MIT",
11
- "devDependencies": {
12
- "@types/node": "^25.2.1"
13
- },
14
- "engines": {
15
- "node": ">=18.0.0"
16
- }
17
- },
18
- "../../../MailApps/iflow-direct": {
19
- "name": "@bobfrankston/iflow-direct",
20
- "version": "0.1.27",
21
- "license": "ISC",
22
- "dependencies": {
23
- "@bobfrankston/tcp-transport": "file:../tcp-transport"
24
- },
25
- "devDependencies": {
26
- "@types/node": "^25.6.0"
27
- }
28
- },
29
- "../../../MailApps/mailx-sync": {
30
- "name": "@bobfrankston/mailx-sync",
31
- "version": "0.1.10",
32
- "license": "ISC",
33
- "dependencies": {
34
- "@bobfrankston/iflow-direct": "file:../iflow-direct",
35
- "@bobfrankston/tcp-transport": "file:../tcp-transport"
36
- },
37
- "devDependencies": {
38
- "@types/node": "^25.6.0"
39
- }
40
- },
41
- "../../../MailApps/smtp-direct": {
42
- "name": "@bobfrankston/smtp-direct",
43
- "version": "0.1.5",
44
- "license": "ISC",
45
- "dependencies": {
46
- "@bobfrankston/tcp-transport": "file:../tcp-transport"
47
- },
48
- "devDependencies": {
49
- "@types/node": "^25.6.0"
50
- }
51
- },
52
- "../../../MailApps/tcp-transport": {
53
- "name": "@bobfrankston/tcp-transport",
54
- "version": "0.1.5",
55
- "license": "ISC",
56
- "devDependencies": {
57
- "@types/node": "^25.6.0"
58
- }
59
- },
60
- "../../app/packages/mailx-settings": {
61
- "name": "@bobfrankston/mailx-settings",
62
- "version": "0.1.6",
63
- "license": "ISC",
64
- "dependencies": {
65
- "@bobfrankston/mailx-types": "file:../mailx-types",
66
- "jsonc-parser": "^3.3.1"
67
- }
68
- },
69
- "../../app/packages/mailx-store": {
70
- "name": "@bobfrankston/mailx-store",
71
- "version": "0.1.5",
72
- "license": "ISC",
73
- "dependencies": {
74
- "@bobfrankston/mailx-settings": "file:../mailx-settings",
75
- "@bobfrankston/mailx-types": "file:../mailx-types"
76
- }
77
- },
78
- "../../app/packages/mailx-types": {
79
- "name": "@bobfrankston/mailx-types",
80
- "version": "0.1.5",
81
- "license": "ISC"
82
- },
83
- "node_modules/@bobfrankston/iflow-direct": {
84
- "resolved": "../../../MailApps/iflow-direct",
85
- "link": true
86
- },
87
- "node_modules/@bobfrankston/mailx-settings": {
88
- "resolved": "../../app/packages/mailx-settings",
89
- "link": true
90
- },
91
- "node_modules/@bobfrankston/mailx-store": {
92
- "resolved": "../../app/packages/mailx-store",
93
- "link": true
94
- },
95
- "node_modules/@bobfrankston/mailx-sync": {
96
- "resolved": "../../../MailApps/mailx-sync",
97
- "link": true
98
- },
99
- "node_modules/@bobfrankston/mailx-types": {
100
- "resolved": "../../app/packages/mailx-types",
101
- "link": true
102
- },
103
- "node_modules/@bobfrankston/oauthsupport": {
104
- "resolved": "../../../../projects/oauth/oauthsupport",
105
- "link": true
106
- },
107
- "node_modules/@bobfrankston/smtp-direct": {
108
- "resolved": "../../../MailApps/smtp-direct",
109
- "link": true
110
- },
111
- "node_modules/@bobfrankston/tcp-transport": {
112
- "resolved": "../../../MailApps/tcp-transport",
113
- "link": true
114
- }
115
- }
116
- }