@bobfrankston/rmfmail 1.2.68 → 1.2.70
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/bin/build-bundles.mjs +42 -0
- package/client/app.bundle.js +9 -3
- package/client/app.bundle.js.map +2 -2
- package/client/app.js +7 -2
- package/client/app.js.map +1 -1
- package/client/app.ts +7 -2
- package/client/components/tabs.js +12 -1
- package/client/components/tabs.js.map +1 -1
- package/client/components/tabs.ts +11 -1
- package/client/compose/compose.html +1 -1
- package/client/index.html +2 -2
- package/package.json +1 -1
package/bin/build-bundles.mjs
CHANGED
|
@@ -18,11 +18,52 @@
|
|
|
18
18
|
*/
|
|
19
19
|
import * as esbuild from "esbuild";
|
|
20
20
|
import path from "node:path";
|
|
21
|
+
import fs from "node:fs";
|
|
22
|
+
import crypto from "node:crypto";
|
|
21
23
|
import { fileURLToPath } from "node:url";
|
|
22
24
|
|
|
23
25
|
const root = path.resolve(fileURLToPath(import.meta.url), "..", "..");
|
|
24
26
|
const watch = process.argv.includes("--watch");
|
|
25
27
|
|
|
28
|
+
/** Cache-bust the bundle references in the HTML entry points with a content
|
|
29
|
+
* hash. The msger custom protocol serves bundles with no cache headers, so
|
|
30
|
+
* WebView2 caches `app.bundle.js` and keeps serving the OLD bundle across
|
|
31
|
+
* daemon relaunches — every client-side fix silently failed to reach the user
|
|
32
|
+
* until the cache happened to evict (Bob 2026-06-26: flag/Ctrl+A fixes "still
|
|
33
|
+
* happening" while the daemon was already on the new version). Stamping a
|
|
34
|
+
* per-build `?v=<hash>` makes the URL change whenever the bundle changes, so
|
|
35
|
+
* the WebView is forced to fetch the new one. */
|
|
36
|
+
function shortHash(file) {
|
|
37
|
+
try { return crypto.createHash("sha1").update(fs.readFileSync(file)).digest("hex").slice(0, 10); }
|
|
38
|
+
catch { return String(Date.now()); }
|
|
39
|
+
}
|
|
40
|
+
function stampHtml(htmlFile, refs) {
|
|
41
|
+
let html;
|
|
42
|
+
try { html = fs.readFileSync(htmlFile, "utf8"); } catch { return; }
|
|
43
|
+
let changed = false;
|
|
44
|
+
for (const { name, file } of refs) {
|
|
45
|
+
const v = shortHash(file);
|
|
46
|
+
// Match the bundle name + optional existing ?v=… up to the closing
|
|
47
|
+
// quote, so re-runs replace the prior hash instead of stacking.
|
|
48
|
+
const re = new RegExp(`(${name.replace(/[.\\/]/g, m => "\\" + m)})(\\?v=[a-z0-9]+)?(")`, "g");
|
|
49
|
+
const next = html.replace(re, `$1?v=${v}$3`);
|
|
50
|
+
if (next !== html) { html = next; changed = true; }
|
|
51
|
+
}
|
|
52
|
+
if (changed) {
|
|
53
|
+
fs.writeFileSync(htmlFile, html);
|
|
54
|
+
console.log(` stamped ${path.relative(root, htmlFile)}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function stampAll() {
|
|
58
|
+
stampHtml(path.join(root, "client", "index.html"), [
|
|
59
|
+
{ name: "./app.bundle.js", file: path.join(root, "client", "app.bundle.js") },
|
|
60
|
+
{ name: "./android-bootstrap.bundle.js", file: path.join(root, "client", "android-bootstrap.bundle.js") },
|
|
61
|
+
]);
|
|
62
|
+
stampHtml(path.join(root, "client", "compose", "compose.html"), [
|
|
63
|
+
{ name: "compose.bundle.js", file: path.join(root, "client", "compose", "compose.bundle.js") },
|
|
64
|
+
]);
|
|
65
|
+
}
|
|
66
|
+
|
|
26
67
|
// Each entry has its own external list because the Android bootstrap bundle
|
|
27
68
|
// needs to INCLUDE @bobfrankston/mailx-store-web (entire purpose of the
|
|
28
69
|
// bundle), while app.bundle.js externalizes it so the desktop build doesn't
|
|
@@ -132,6 +173,7 @@ async function buildAll() {
|
|
|
132
173
|
}
|
|
133
174
|
const failed = results.filter(r => !r.ok).length;
|
|
134
175
|
if (failed) process.exit(1);
|
|
176
|
+
stampAll();
|
|
135
177
|
console.log(`build-bundles: done in ${Date.now() - t0} ms`);
|
|
136
178
|
}
|
|
137
179
|
|
package/client/app.bundle.js
CHANGED
|
@@ -6240,7 +6240,12 @@ function initTabs(strip, apply) {
|
|
|
6240
6240
|
if (raw) {
|
|
6241
6241
|
const parsed = JSON.parse(raw);
|
|
6242
6242
|
if (Array.isArray(parsed?.tabs) && parsed.tabs.length) {
|
|
6243
|
-
tabs = parsed.tabs
|
|
6243
|
+
tabs = parsed.tabs.map((t) => {
|
|
6244
|
+
if (t.view?.kind !== "search")
|
|
6245
|
+
return t;
|
|
6246
|
+
const v = t.view;
|
|
6247
|
+
return v.folderId ? { id: t.id, title: "Mail", view: { kind: "folder", accountId: v.accountId, folderId: v.folderId, specialUse: "" } } : { id: t.id, title: "All Inboxes", view: { kind: "unified" } };
|
|
6248
|
+
});
|
|
6244
6249
|
activeId = parsed.activeId || tabs[0].id;
|
|
6245
6250
|
for (const t of tabs) {
|
|
6246
6251
|
const n = Number(String(t.id).replace(/^t/, ""));
|
|
@@ -11694,12 +11699,13 @@ function saveBootSnapshot() {
|
|
|
11694
11699
|
const messageList2 = document.getElementById("ml-body");
|
|
11695
11700
|
const folderTitle = document.getElementById("ml-folder-title");
|
|
11696
11701
|
const ftHtml = folderTree2?.innerHTML?.trim() || "";
|
|
11697
|
-
const
|
|
11702
|
+
const searching = (searchInput?.value.trim() || "") !== "";
|
|
11703
|
+
const mlHtml = searching ? "" : messageList2?.innerHTML?.trim() || "";
|
|
11698
11704
|
if (!ftHtml && !mlHtml) return;
|
|
11699
11705
|
const snap = {
|
|
11700
11706
|
folderTree: ftHtml,
|
|
11701
11707
|
messageList: mlHtml,
|
|
11702
|
-
folderTitle: folderTitle?.innerHTML?.trim() || "",
|
|
11708
|
+
folderTitle: searching ? "" : folderTitle?.innerHTML?.trim() || "",
|
|
11703
11709
|
savedAt: Date.now()
|
|
11704
11710
|
};
|
|
11705
11711
|
localStorage.setItem("mailx-boot-snapshot", JSON.stringify(snap));
|