@bobfrankston/rmfmail 1.2.171 → 1.2.173
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/TODO.md +1 -0
- package/client/android-bootstrap.bundle.js +27 -1
- package/client/android-bootstrap.bundle.js.map +2 -2
- package/client/app.bundle.js +58 -0
- package/client/app.bundle.js.map +3 -3
- package/client/components/message-viewer.js +60 -0
- package/client/components/message-viewer.js.map +1 -1
- package/client/components/message-viewer.ts +60 -0
- package/client/compose/compose.bundle.js +7 -0
- package/client/compose/compose.bundle.js.map +2 -2
- package/client/lib/api-client.js +9 -0
- package/client/lib/api-client.js.map +1 -1
- package/client/lib/api-client.ts +9 -0
- package/client/lib/mailxapi.js +6 -0
- package/package.json +5 -5
- package/packages/mailx-imap/index.d.ts.map +1 -1
- package/packages/mailx-imap/index.js +22 -0
- package/packages/mailx-imap/index.js.map +1 -1
- package/packages/mailx-imap/index.ts +22 -0
- package/packages/mailx-imap/package-lock.json +2 -2
- package/packages/mailx-imap/package.json +1 -1
- package/packages/mailx-service/index.d.ts +23 -0
- package/packages/mailx-service/index.d.ts.map +1 -1
- package/packages/mailx-service/index.js +206 -0
- package/packages/mailx-service/index.js.map +1 -1
- package/packages/mailx-service/index.ts +198 -0
- package/packages/mailx-service/jsonrpc.js +2 -0
- package/packages/mailx-service/jsonrpc.js.map +1 -1
- package/packages/mailx-service/jsonrpc.ts +2 -0
- package/packages/mailx-service/package.json +1 -1
- package/packages/mailx-settings/index.d.ts.map +1 -1
- package/packages/mailx-settings/index.js +35 -1
- package/packages/mailx-settings/index.js.map +1 -1
- package/packages/mailx-settings/index.ts +32 -1
- package/packages/mailx-settings/package.json +1 -1
- package/packages/mailx-store/db.d.ts +3 -0
- package/packages/mailx-store/db.d.ts.map +1 -1
- package/packages/mailx-store/db.js +5 -0
- package/packages/mailx-store/db.js.map +1 -1
- package/packages/mailx-store/db.ts +8 -0
- package/packages/mailx-store/package.json +1 -1
- package/packages/mailx-store-web/package.json +1 -1
- package/packages/mailx-store-web/web-settings.d.ts.map +1 -1
- package/packages/mailx-store-web/web-settings.js +31 -0
- package/packages/mailx-store-web/web-settings.js.map +1 -1
- package/packages/mailx-store-web/web-settings.ts +31 -0
- package/packages/mailx-types/mailx-api.d.ts +8 -0
- package/packages/mailx-types/mailx-api.d.ts.map +1 -1
- package/packages/mailx-types/mailx-api.ts +4 -0
- package/packages/mailx-types/package.json +1 -1
- /package/packages/mailx-imap/{node_modules.npmglobalize-stash-3252 → node_modules.npmglobalize-stash-7284}/.package-lock.json +0 -0
package/TODO.md
CHANGED
|
@@ -22,6 +22,7 @@ These items don't need user input — source-only changes, compile-verified befo
|
|
|
22
22
|
| **8** | **C157 — Android fresh install: paint folder list before message sync** [S/M] | S/M | First sync ran minutes with an empty tree. Prioritize per-account folder-LIST fetch + paint ahead of message sync so the skeleton appears in seconds; message counts stream in behind. |
|
|
23
23
|
| **10** | **C159 — Harper local grammar check** [M] | M | **Desktop SHIPPED v1.2.168** (2026-07-22): daemon-side Harper engine + `grammarLint` IPC, generic squiggle overlay + suggestion popup across ALL THREE editors, Settings toggle default ON, quoted chains + spelling lints skipped. **Remaining: Android** (host LocalLinter in android-bootstrap, harper.js dist in APK assets like sql.js, ~+18 MB) + per-rule config + userdict merge. Details: `docs/harper-integration.md`. |
|
|
24
24
|
| **9** | **C158 — Android double-init after fold-triggered reload** [M] | M | 2026-07-22 13:07:49 logit trail: ONE page reload after unfolding produced TWO module loads, duplicate "bridge installed", duplicate GDrive lookups, and THREE "Starting OAuth flow" launches. Activity did NOT recreate (ConfigChanges already declared; no OnCreate in trail) — find what reloads the WebView on fold and make android-bootstrap init idempotent (single-flight guard on the module-level init, dedupe OAuth intent launches). |
|
|
25
|
+
| **11** | **C160 — Attachment delete: Gmail + Android halves** [M] | M | Desktop IMAP shipped v1.2.173 (right-click chip → Delete one/all: verified local strip + append-confirm-then-delete server replace, .pre-strip.bak backup, UID rebind). Remaining: Gmail REST path (messages.insert + trash of original — changes message id, provider_id rebind) and Android (bridge method + web-service strip using its own parser). Strip helper lives in mailx-service (enumerateMimeLeafParts) — move to mailx-types when Android needs it. |
|
|
25
26
|
| **5** | **C124 — mailto handler on macOS** (Linux ✅ 2026-07-08 v1.2.115) | S | Linux half shipped: `--register-mailto` on linux writes `~/.local/share/applications/rmfmail.desktop` (`MimeType=x-scheme-handler/mailto;`, quoted node+mailx.js Exec, bare `%u`), runs `xdg-mime default` + `update-desktop-database`; `--unregister-mailto` removes it. **Remaining: macOS** — real `.app` bundle (LaunchServices won't register a bare script) with `Info.plist` `CFBundleURLTypes` declaring `mailto` + a tiny launcher binary; `LSSetDefaultHandlerForURLScheme` programmatically sets the default. Rust `rmfmailto-src/` crate already portable — drop the Win32 imports and `cargo build --target x86_64-apple-darwin` produces the macOS launcher. Needs a Mac to build/verify. |
|
|
26
27
|
| ~~7~~ | ~~**C154 — Audit Android bridge vs MailxApi contract**~~ — **DONE** (2026-07-08, v1.2.115). Bridge now has a generic contract-backstop: every service method not explicitly adapted gets a positional pass-through, so a missing method can never again fail as `parent bridge has no method "X"`. Wire-shape mismatches adapted explicitly (`readJsoncFile`/`writeJsoncFile`/`formatJsonc`/`readConfigHelp` → `{content}`/`{ok}`, `drainStoreSync`/`syncFolderNow` → `{ok}`). Contract gained the missing entries (`getMessageSource`, `copyMessages`, `syncFolderNow`, `cancelServerSearch`, `getReminderSound`, `getCalendars`, optional `popoutWindow`) with web-service stubs per the policy (reads → graceful default, writes/OS → notImpl). Bonus fixes: bridge `getMessages` was dropping sort/sortDir/search and `searchMessages` was dropping scope/accountId/folderId — Android sort toggles and scoped search silently didn't work. | S | |
|
|
27
28
|
~~done — C120 read transport diagnostics~~ shipped v1.0.583 (per-folder timeout error now includes `[conn#X r=YB w=ZB writes=N sinceLastRead=Tms]` snapshot for the doomed socket).
|
|
@@ -2631,6 +2631,15 @@ async function idbDelete(key) {
|
|
|
2631
2631
|
tx.onerror = () => reject(tx.error);
|
|
2632
2632
|
});
|
|
2633
2633
|
}
|
|
2634
|
+
async function idbListKeys(prefix) {
|
|
2635
|
+
const db2 = await openSettingsDb();
|
|
2636
|
+
return new Promise((resolve, reject) => {
|
|
2637
|
+
const tx = db2.transaction(STORE_NAME2, "readonly");
|
|
2638
|
+
const req = tx.objectStore(STORE_NAME2).getAllKeys(IDBKeyRange.bound(prefix, prefix + "\uFFFF"));
|
|
2639
|
+
req.onsuccess = () => resolve(req.result.map(String));
|
|
2640
|
+
req.onerror = () => reject(req.error);
|
|
2641
|
+
});
|
|
2642
|
+
}
|
|
2634
2643
|
function setGDriveTokenProvider(provider) {
|
|
2635
2644
|
tokenProvider = provider;
|
|
2636
2645
|
}
|
|
@@ -2830,6 +2839,20 @@ function parseJsonc(text) {
|
|
|
2830
2839
|
stripped = stripped.replace(/,(\s*[}\]])/g, "$1");
|
|
2831
2840
|
return JSON.parse(stripped);
|
|
2832
2841
|
}
|
|
2842
|
+
async function stashPrevIdb(filename, aboutToBecome) {
|
|
2843
|
+
try {
|
|
2844
|
+
const old = await idbRead(filename);
|
|
2845
|
+
if (!old || old === aboutToBecome)
|
|
2846
|
+
return;
|
|
2847
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
2848
|
+
await idbWrite(`prev:${filename}:${stamp}`, old);
|
|
2849
|
+
const keys = await idbListKeys(`prev:${filename}:`);
|
|
2850
|
+
for (const k of keys.sort().slice(0, Math.max(0, keys.length - PREV_KEEP))) {
|
|
2851
|
+
await idbDelete(k);
|
|
2852
|
+
}
|
|
2853
|
+
} catch {
|
|
2854
|
+
}
|
|
2855
|
+
}
|
|
2833
2856
|
function refreshSharedFile(filename, cached) {
|
|
2834
2857
|
const now = Date.now();
|
|
2835
2858
|
if (now - (__lastSharedRefresh.get(filename) || 0) < SHARED_REFRESH_MS)
|
|
@@ -2922,6 +2945,7 @@ async function loadPreferences() {
|
|
|
2922
2945
|
}
|
|
2923
2946
|
async function savePreferences(prefs) {
|
|
2924
2947
|
const content = JSON.stringify(prefs, null, 2);
|
|
2948
|
+
await stashPrevIdb("preferences.jsonc", content);
|
|
2925
2949
|
await idbWrite("preferences.jsonc", content);
|
|
2926
2950
|
await gDriveWrite("preferences.jsonc", content);
|
|
2927
2951
|
}
|
|
@@ -2986,6 +3010,7 @@ async function updateAllowlist(mutate) {
|
|
|
2986
3010
|
}
|
|
2987
3011
|
async function saveAllowlist(list) {
|
|
2988
3012
|
const content = JSON.stringify(list, null, 2);
|
|
3013
|
+
await stashPrevIdb("allowlist.jsonc", content);
|
|
2989
3014
|
await idbWrite("allowlist.jsonc", content);
|
|
2990
3015
|
try {
|
|
2991
3016
|
const cloudRaw = await gDriveRead("allowlist.jsonc");
|
|
@@ -3068,7 +3093,7 @@ async function loadDeviceState() {
|
|
|
3068
3093
|
}
|
|
3069
3094
|
return {};
|
|
3070
3095
|
}
|
|
3071
|
-
var IDB_NAME2, IDB_VERSION, STORE_NAME2, gDriveFolderId, gDriveFolderName, gDriveFolderPath, gDriveFolderOwner, tokenProvider, PROVIDERS, DEFAULT_PREFERENCES, DEFAULT_ALLOWLIST, SHARED_REFRESH_MS, __lastSharedRefresh, ALLOWLIST_KEYS, DEVICE_ID_KEY;
|
|
3096
|
+
var IDB_NAME2, IDB_VERSION, STORE_NAME2, gDriveFolderId, gDriveFolderName, gDriveFolderPath, gDriveFolderOwner, tokenProvider, PROVIDERS, DEFAULT_PREFERENCES, DEFAULT_ALLOWLIST, PREV_KEEP, SHARED_REFRESH_MS, __lastSharedRefresh, ALLOWLIST_KEYS, DEVICE_ID_KEY;
|
|
3072
3097
|
var init_web_settings = __esm({
|
|
3073
3098
|
"packages/mailx-store-web/web-settings.js"() {
|
|
3074
3099
|
"use strict";
|
|
@@ -3143,6 +3168,7 @@ var init_web_settings = __esm({
|
|
|
3143
3168
|
flaggedSenders: [],
|
|
3144
3169
|
flaggedDomains: []
|
|
3145
3170
|
};
|
|
3171
|
+
PREV_KEEP = 5;
|
|
3146
3172
|
SHARED_REFRESH_MS = 5 * 6e4;
|
|
3147
3173
|
__lastSharedRefresh = /* @__PURE__ */ new Map();
|
|
3148
3174
|
ALLOWLIST_KEYS = ["senders", "domains", "recipients", "flaggedSenders", "flaggedDomains"];
|