@bobfrankston/rmfmail 1.1.4 → 1.1.6

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 (73) hide show
  1. package/bin/build-bundles.mjs +14 -4
  2. package/bin/mailx.js +8 -3
  3. package/bin/mailx.js.map +1 -1
  4. package/bin/mailx.ts +8 -3
  5. package/client/android-bootstrap.bundle.js +2151 -2
  6. package/client/android-bootstrap.bundle.js.map +4 -4
  7. package/client/app.bundle.js +40 -8
  8. package/client/app.bundle.js.map +2 -2
  9. package/client/app.js +15 -6
  10. package/client/app.js.map +1 -1
  11. package/client/app.ts +14 -6
  12. package/client/components/alarms.js +36 -10
  13. package/client/components/alarms.js.map +1 -1
  14. package/client/components/alarms.ts +32 -10
  15. package/client/components/message-list.js +30 -7
  16. package/client/components/message-list.js.map +1 -1
  17. package/client/components/message-list.ts +28 -6
  18. package/package.json +3 -3
  19. package/packages/mailx-api/index.d.ts +2 -2
  20. package/packages/mailx-api/index.d.ts.map +1 -1
  21. package/packages/mailx-api/index.js +2 -2
  22. package/packages/mailx-api/index.js.map +1 -1
  23. package/packages/mailx-api/index.ts +3 -3
  24. package/packages/mailx-core/index.d.ts.map +1 -1
  25. package/packages/mailx-core/index.js +3 -2
  26. package/packages/mailx-core/index.js.map +1 -1
  27. package/packages/mailx-core/index.ts +3 -2
  28. package/packages/mailx-imap/index.d.ts +13 -4
  29. package/packages/mailx-imap/index.d.ts.map +1 -1
  30. package/packages/mailx-imap/index.js +16 -8
  31. package/packages/mailx-imap/index.js.map +1 -1
  32. package/packages/mailx-imap/index.ts +15 -7
  33. package/packages/mailx-imap/package-lock.json +2 -2
  34. package/packages/mailx-imap/package.json +1 -1
  35. package/packages/mailx-server/index.d.ts.map +1 -1
  36. package/packages/mailx-server/index.js +4 -3
  37. package/packages/mailx-server/index.js.map +1 -1
  38. package/packages/mailx-server/index.ts +4 -3
  39. package/packages/mailx-service/db-worker.js +3 -4
  40. package/packages/mailx-service/db-worker.js.map +1 -1
  41. package/packages/mailx-service/db-worker.ts +5 -6
  42. package/packages/mailx-service/index.d.ts +20 -3
  43. package/packages/mailx-service/index.d.ts.map +1 -1
  44. package/packages/mailx-service/index.js +19 -17
  45. package/packages/mailx-service/index.js.map +1 -1
  46. package/packages/mailx-service/index.ts +18 -17
  47. package/packages/mailx-service/local-store.d.ts +7 -144
  48. package/packages/mailx-service/local-store.d.ts.map +1 -1
  49. package/packages/mailx-service/local-store.js +6 -511
  50. package/packages/mailx-service/local-store.js.map +1 -1
  51. package/packages/mailx-service/local-store.ts +7 -551
  52. package/packages/mailx-store/charset.d.ts +15 -0
  53. package/packages/mailx-store/charset.d.ts.map +1 -0
  54. package/packages/mailx-store/charset.js +61 -0
  55. package/packages/mailx-store/charset.js.map +1 -0
  56. package/packages/mailx-store/charset.ts +45 -0
  57. package/packages/mailx-store/index.d.ts +2 -0
  58. package/packages/mailx-store/index.d.ts.map +1 -1
  59. package/packages/mailx-store/index.js +2 -0
  60. package/packages/mailx-store/index.js.map +1 -1
  61. package/packages/mailx-store/index.ts +4 -0
  62. package/packages/mailx-store/package.json +1 -1
  63. package/packages/mailx-store/store.d.ts +169 -0
  64. package/packages/mailx-store/store.d.ts.map +1 -0
  65. package/packages/mailx-store/store.js +528 -0
  66. package/packages/mailx-store/store.js.map +1 -0
  67. package/packages/mailx-store/store.ts +567 -0
  68. package/client/lib/tinymce/themes/silver/index.js +0 -7
  69. package/client/lib/tinymce/themes/silver/theme.js +0 -34829
  70. package/client/lib/tinymce/themes/silver/theme.min.js +0 -1
  71. package/client/lib/tinymce/tinymce.js +0 -41682
  72. package/client/lib/tinymce/tinymce.min.js +0 -10
  73. /package/packages/mailx-imap/{node_modules.npmglobalize-stash-39436 → node_modules.npmglobalize-stash-41384}/.package-lock.json +0 -0
@@ -13,7 +13,7 @@ const __dirname = import.meta.dirname;
13
13
  import { ImapManager } from "@bobfrankston/mailx-imap";
14
14
  import * as gsync from "./google-sync.js";
15
15
  import { sniffAndFixCharset } from "./charset.js";
16
- import { LocalStore } from "./local-store.js";
16
+ import { Store } from "@bobfrankston/mailx-store";
17
17
  import { SyncQueue } from "./sync-queue.js";
18
18
  import { Reconciler } from "./reconciler.js";
19
19
  import { loadSettings, saveSettings, loadAccounts, loadAccountsAsync, saveAccounts, initCloudConfig, loadAllowlist, saveAllowlist, loadAutocomplete, saveAutocomplete, loadKeys, saveKeys, ensureKeysSectionExists, getStorePath, getStorageInfo, getConfigDir, loadUserDict, saveUserDict } from "@bobfrankston/mailx-settings";
@@ -135,7 +135,7 @@ export class MailxService implements MailxApi {
135
135
  /** Local-first read/write facade. Every UI IPC handler that touches the
136
136
  * local DB or body store goes through this — no awaiting IMAP, no
137
137
  * awaiting Gmail API, no awaiting SMTP. See docs/local-first-plan.md. */
138
- private localStore: LocalStore;
138
+ private localStore: Store;
139
139
 
140
140
  /** Persistent (and in-memory body-fetch) queue. UI handlers commit
141
141
  * locally, then enqueue a server-mirror task here. */
@@ -146,20 +146,21 @@ export class MailxService implements MailxApi {
146
146
  private reconciler: Reconciler;
147
147
 
148
148
  constructor(
149
- private db: MailxDB,
149
+ /** The Store is the nexus — owns DB + .eml files + bus + operations.
150
+ * MailxService is the IPC adapter on top: it routes UI requests to
151
+ * Store reads/writes and to the SyncQueue/Reconciler for server-
152
+ * mirror work. The raw `db` getter below is a transitional shim so
153
+ * the ~50 `this.db.X(...)` callsites in this file don't all need
154
+ * touching at once; all writes should migrate to `this.localStore.X(...)`. */
155
+ private store: Store,
150
156
  private imapManager: ImapManager,
151
157
  ) {
152
- this.localStore = new LocalStore(db, imapManager.getBodyStore());
153
- this.syncQueue = new SyncQueue(db, imapManager);
154
- this.reconciler = new Reconciler(db, imapManager, this.syncQueue);
158
+ this.localStore = store;
159
+ this.syncQueue = new SyncQueue(store.db, imapManager);
160
+ this.reconciler = new Reconciler(store.db, imapManager, this.syncQueue);
155
161
  this.reconciler.start();
156
162
 
157
163
  // Invalidate caches when their source files change on disk / GDrive.
158
- // configChanged fires for any *.jsonc the watcher tracks (accounts,
159
- // preferences, allowlist, etc.); broadly invalidate settings too so
160
- // a preferences edit takes effect on the next getMessage / refresh.
161
- // LocalStore also caches allowlist + settings to keep .eml display
162
- // off the GDrive hot path; nudge it on the same event.
163
164
  this.imapManager.on?.("configChanged", (filename: string) => {
164
165
  if (filename === "accounts.jsonc") this._accountsCache = null;
165
166
  this._settingsCache = null;
@@ -169,15 +170,15 @@ export class MailxService implements MailxApi {
169
170
  console.error(` [contacts] reload failed: ${e?.message || e}`));
170
171
  }
171
172
  });
172
- // Wire DB → cloud flush. Debounced to absorb bursts (a sync run can
173
- // call recordSentAddress hundreds of times). 30s flush window is
174
- // long enough that the steady state is one cloud write per sync,
175
- // short enough that quitting after a single send still flushes.
176
- this.db.setOnContactsChanged(() => this.markContactsDirty());
177
-
173
+ // Wire DB → cloud flush. Debounced to absorb bursts.
174
+ this.store.db.setOnContactsChanged(() => this.markContactsDirty());
178
175
  // Initial load of contacts.jsonc — fire-and-forget; missing file is fine.
179
176
  this.loadContactsConfig().catch(() => { /* file may not exist yet */ });
180
177
  }
178
+ /** Transitional getter — direct DB access from MailxService for the
179
+ * ~50 callsites that haven't yet migrated to Store methods. Future:
180
+ * every mutation routes through `this.localStore.X(...)`. */
181
+ private get db(): MailxDB { return this.store.db; }
181
182
 
182
183
  private _contactsFlushTimer: ReturnType<typeof setTimeout> | null = null;
183
184
  private _contactsFlushInFlight = false;
@@ -1,147 +1,10 @@
1
1
  /**
2
- * LocalStore — the formal API surface for UI-bound reads and writes.
3
- *
4
- * Contract: every method here is local-only. No IMAP, no Gmail API, no
5
- * SMTP, no DNS, no Drive API. Methods complete in microseconds (DB reads)
6
- * or whatever a single local file IO takes (body reads). They never await
7
- * network calls.
8
- *
9
- * UI-side IPC dispatch lands here. The reconciler / sync queue is a
10
- * separate concern — it owns network IO and signals completed work via
11
- * events that the UI listens for. The two never call each other directly.
12
- *
13
- * This file is part of the local-first refactor (docs/local-first-plan.md).
14
- * Step 1 of that plan: introduce the facade, prove it compiles, route
15
- * one IPC method through it as proof-of-pattern. Subsequent steps migrate
16
- * remaining call sites and remove the server-fetch path from the UI.
2
+ * LocalStore — DEPRECATED. The Store moved to `@bobfrankston/mailx-store`
3
+ * (it's now the architectural nexus and lives in the package that owns
4
+ * the underlying DB + .eml file backend). Re-exported here only so any
5
+ * stale `./local-store.js` imports keep resolving while in-tree callers
6
+ * migrate to `import { Store } from "@bobfrankston/mailx-store"`.
17
7
  */
18
- import type { MailxDB, FileMessageStore, StoreBus } from "@bobfrankston/mailx-store";
19
- import type { MessageEnvelope, MessageQuery, PagedResult } from "@bobfrankston/mailx-types";
20
- /** What the UI gets back from a body read. Mirrors the historical
21
- * `getMessage` shape so call-site migration is mechanical. `cached: false`
22
- * means the body isn't on disk yet — the UI shows a "downloading…"
23
- * placeholder and listens for `bodyAvailable` to re-render. The reconciler
24
- * is responsible for actually fetching and emitting the event. */
25
- export interface LocalMessage extends MessageEnvelope {
26
- bodyHtml: string;
27
- bodyText: string;
28
- hasRemoteContent: boolean;
29
- remoteAllowed: boolean;
30
- attachments: Array<{
31
- id: number;
32
- filename: string;
33
- mimeType: string;
34
- size: number;
35
- contentId: string;
36
- }>;
37
- cached: boolean;
38
- deliveredTo: string;
39
- returnPath: string;
40
- listUnsubscribe: string;
41
- listUnsubscribeMail: string;
42
- listUnsubscribeHttp: string;
43
- listUnsubscribeOneClick: boolean;
44
- emlPath: string;
45
- isFlagged: boolean;
46
- }
47
- export declare class LocalStore {
48
- private db;
49
- private bodyStore;
50
- /** Event bus for Store mutations. Defaults to the process-singleton
51
- * so cross-package subscribers (bin/mailx.ts forwarder → WebView,
52
- * in-process reconciler triggers) see all writes without explicit
53
- * wiring. Tests can pass a fresh StoreBus for isolation. */
54
- readonly bus: StoreBus;
55
- private static readonly PARSED_LRU_CAPACITY;
56
- private parsedLru;
57
- private parsedLruGet;
58
- private parsedLruPut;
59
- private _allowlistCache;
60
- private _settingsCache;
61
- private getCachedAllowlist;
62
- private getCachedSettings;
63
- invalidateConfigCaches(): void;
64
- constructor(db: MailxDB, bodyStore: FileMessageStore,
65
- /** Event bus for Store mutations. Defaults to the process-singleton
66
- * so cross-package subscribers (bin/mailx.ts forwarder → WebView,
67
- * in-process reconciler triggers) see all writes without explicit
68
- * wiring. Tests can pass a fresh StoreBus for isolation. */
69
- bus?: StoreBus);
70
- /** DB-shape account list (id/name/email/lastSync). The richer
71
- * AccountConfig (with imap/smtp/etc.) lives in accounts.jsonc and is
72
- * loaded by mailx-settings, not the DB — that path stays in
73
- * MailxService until step 3 of the local-first plan. */
74
- getAccounts(): {
75
- id: string;
76
- name: string;
77
- email: string;
78
- lastSync: number;
79
- }[];
80
- getFolders(accountId: string): any[];
81
- /** Look up a folder by RFC 6154 specialUse tag (`trash`, `drafts`, `sent`,
82
- * `junk`, etc.) for the given account. Falls back to a case-insensitive
83
- * path match for legacy rows where specialUse never got tagged.
84
- * Returns null when the account has no such folder configured. */
85
- findSpecialFolder(accountId: string, specialUse: string): {
86
- id: number;
87
- path: string;
88
- } | null;
89
- /** Single envelope by (account, uid, folder). Null when the row isn't
90
- * in the DB — caller decides whether to show "deleted" or queue a
91
- * server lookup via the reconciler. */
92
- getMessageEnvelope(accountId: string, uid: number, folderId?: number): MessageEnvelope | null;
93
- /** Paginated message list for a (account, folder, ...) query. */
94
- getMessages(query: MessageQuery): PagedResult<MessageEnvelope>;
95
- /** All-Inboxes view: union of every account's INBOX, paginated. */
96
- getUnifiedInbox(page?: number, pageSize?: number): PagedResult<MessageEnvelope>;
97
- /** Local FTS5 search. Server-scope search is the reconciler's job. */
98
- searchMessages(query: string, page?: number, pageSize?: number, accountId?: string, folderId?: number, includeTrashSpam?: boolean): PagedResult<MessageEnvelope>;
99
- /** Read a fully-parsed message (envelope + body + attachments) entirely
100
- * from local state. Returns null when the envelope isn't known.
101
- * Returns `{ ...envelope, cached: false }` when the envelope is known
102
- * but the body file isn't on disk — UI shows a placeholder and the
103
- * reconciler queues the fetch.
104
- *
105
- * `allowRemote=true` skips HTML sanitization. Used when the user has
106
- * explicitly allowed remote content for this sender / domain. */
107
- getMessage(accountId: string, uid: number, allowRemote: boolean, folderId?: number): Promise<LocalMessage | null>;
108
- getCalendarEvents(accountId: string, fromMs: number, toMs: number): any[];
109
- getTasks(accountId: string, includeCompleted?: boolean): any[];
110
- searchContacts(query: string, limit?: number): any[];
111
- listContacts(query: string, page?: number, pageSize?: number): any;
112
- /** Update a message's flag set. Local DB write completes synchronously;
113
- * the server-mirror enqueue is the caller's responsibility (typically
114
- * via SyncQueue.enqueueFlag) so callers that don't want a server push
115
- * — pure-local UI state like "pin in pane" — can skip it.
116
- *
117
- * Publishes:
118
- * `message:<uuid>` { kind: "flagsChanged" }
119
- * `folder:<id>` (auto fan-out)
120
- */
121
- updateFlags(accountId: string, uid: number, folderId: number, flags: string[]): void;
122
- /** Move a message between folders in the same account. Adds a tombstone
123
- * on the Message-ID so the next sync doesn't re-import the pre-move row
124
- * in the source folder before the server-side MOVE completes; tombstone
125
- * is cleared on terminal IMAP failure (see processSyncActions).
126
- *
127
- * Returns true if a local row existed and was moved, false otherwise.
128
- *
129
- * Publishes:
130
- * `message:<uuid>` { kind: "messageMoved", folderId: source, targetFolderId }
131
- * `folder:<source>` and `folder:<target>` (auto fan-out + explicit count)
132
- */
133
- moveMessage(accountId: string, uid: number, fromFolderId: number, targetFolderId: number): boolean;
134
- /** Trash a message. If a trash folder is configured and the message is
135
- * not already in it, this is a move-to-trash. If the message is already
136
- * in trash (or no trash exists), it's a hard delete + body unlink.
137
- *
138
- * Returns "moved-to-trash" or "expunged" so the caller knows whether
139
- * to enqueue an IMAP MOVE or a DELETE+EXPUNGE on the queue.
140
- */
141
- trashMessage(accountId: string, uid: number, folderId: number, trashFolderId: number | null): "moved-to-trash" | "expunged";
142
- /** Restore a message from trash back to its original folder. Local-only;
143
- * caller handles the queue (cancel-pending-MOVE vs queue-counter-MOVE).
144
- * Returns true if a local row was moved. */
145
- undeleteMessage(accountId: string, uid: number, trashFolderId: number, originalFolderId: number): boolean;
146
- }
8
+ export { Store as LocalStore } from "@bobfrankston/mailx-store";
9
+ export type { StoreMessage as LocalMessage } from "@bobfrankston/mailx-store";
147
10
  //# sourceMappingURL=local-store.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"local-store.d.ts","sourceRoot":"","sources":["local-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"local-store.d.ts","sourceRoot":"","sources":["local-store.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,KAAK,IAAI,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAChE,YAAY,EAAE,YAAY,IAAI,YAAY,EAAE,MAAM,2BAA2B,CAAC"}