@bobfrankston/rmfmail 1.0.665 → 1.0.666
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 +8 -5
- package/bin/build-bundles.mjs +96 -0
- package/client/app.bundle.js +8942 -0
- package/client/app.bundle.js.map +7 -0
- package/client/app.js +69 -2
- package/client/app.js.map +1 -1
- package/client/app.ts +69 -2
- package/client/compose/compose.bundle.js +2872 -0
- package/client/compose/compose.bundle.js.map +7 -0
- package/client/compose/compose.html +5 -1
- package/client/index.html +53 -3
- package/package.json +3 -2
package/client/index.html
CHANGED
|
@@ -648,9 +648,16 @@
|
|
|
648
648
|
} else {
|
|
649
649
|
window.__btick && window.__btick("desktop bootstrap (mailxapi pre-injected)");
|
|
650
650
|
}
|
|
651
|
-
window.__btick && window.__btick("app.js import begin");
|
|
652
|
-
|
|
653
|
-
|
|
651
|
+
window.__btick && window.__btick("app.bundle.js import begin");
|
|
652
|
+
// app.bundle.js collapses the client's ~17-file import graph
|
|
653
|
+
// into one fetch — msger's custom protocol pays a multi-second
|
|
654
|
+
// IPC roundtrip per request, so the cascade was the dominant
|
|
655
|
+
// cold-start cost (~43 s on 2026-05-11 measurements). The
|
|
656
|
+
// bundle is regenerated by `npm run build` via
|
|
657
|
+
// bin/build-bundles.mjs; dynamic `await import()` of optional
|
|
658
|
+
// adapters (rmf-tiny, android-bootstrap) stays external.
|
|
659
|
+
await import("./app.bundle.js");
|
|
660
|
+
window.__btick && window.__btick("app.bundle.js loaded");
|
|
654
661
|
} catch (e) {
|
|
655
662
|
const msg = "BOOTSTRAP FAILED: " + (e.message || e) + "\n" + (e.stack || "");
|
|
656
663
|
const el = document.getElementById("startup-status");
|
|
@@ -885,5 +892,48 @@
|
|
|
885
892
|
<div id="startup-status">Starting…</div>
|
|
886
893
|
</div>
|
|
887
894
|
</div>
|
|
895
|
+
|
|
896
|
+
<!-- Boot-snapshot hydration. The bundled app saves the rendered folder
|
|
897
|
+
tree, message list, and viewer state into localStorage on a 30 s
|
|
898
|
+
tick and on beforeunload. This inline script (synchronous, runs at
|
|
899
|
+
body-end before any module imports) restores those DOM regions
|
|
900
|
+
instantly so the user sees their inbox / preview right away while
|
|
901
|
+
the bundle is still being fetched + parsed. The live render later
|
|
902
|
+
overwrites in place — no flicker because the snapshot DOM matches
|
|
903
|
+
the post-bundle structure.
|
|
904
|
+
|
|
905
|
+
Best-effort: missing snapshot, parse failure, stale data ≥ 7 days,
|
|
906
|
+
or any DOM mutation error → quietly skip and show the regular
|
|
907
|
+
"Starting…" overlay. -->
|
|
908
|
+
<script>
|
|
909
|
+
(function hydrateFromBootSnapshot() {
|
|
910
|
+
try {
|
|
911
|
+
var raw = localStorage.getItem("mailx-boot-snapshot");
|
|
912
|
+
if (!raw) return;
|
|
913
|
+
var snap = JSON.parse(raw);
|
|
914
|
+
if (!snap || !snap.savedAt) return;
|
|
915
|
+
var ageMs = Date.now() - snap.savedAt;
|
|
916
|
+
if (ageMs < 0 || ageMs > 7 * 24 * 60 * 60 * 1000) return;
|
|
917
|
+
var hydrated = false;
|
|
918
|
+
var setIfHas = function (id, html) {
|
|
919
|
+
if (!html) return;
|
|
920
|
+
var el = document.getElementById(id);
|
|
921
|
+
if (el) { el.innerHTML = html; hydrated = true; }
|
|
922
|
+
};
|
|
923
|
+
setIfHas("folder-tree", snap.folderTree);
|
|
924
|
+
setIfHas("ml-body", snap.messageList);
|
|
925
|
+
setIfHas("ml-folder-title", snap.folderTitle);
|
|
926
|
+
if (hydrated) {
|
|
927
|
+
// Drop the spinner overlay — we have content. The
|
|
928
|
+
// bundle's first render will overwrite this DOM in
|
|
929
|
+
// place (typically a flicker-free no-op since the
|
|
930
|
+
// snapshot was captured from the same render path).
|
|
931
|
+
var overlay = document.getElementById("startup-overlay");
|
|
932
|
+
if (overlay) overlay.style.display = "none";
|
|
933
|
+
window.__btick && window.__btick("boot-snapshot hydrated (age " + Math.round(ageMs / 1000) + "s)");
|
|
934
|
+
}
|
|
935
|
+
} catch (e) { /* hydration is best-effort */ }
|
|
936
|
+
})();
|
|
937
|
+
</script>
|
|
888
938
|
</body>
|
|
889
939
|
</html>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bobfrankston/rmfmail",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.666",
|
|
4
4
|
"description": "Local-first email client with IMAP sync and standalone native app",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "bin/mailx.js",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"client"
|
|
24
24
|
],
|
|
25
25
|
"scripts": {
|
|
26
|
-
"build": "npm run build --workspaces --if-present && tsc -p bin && node bin/build-icon-ico.js && node bin/build-rmfmailto-exe.js && node bin/build-rmf-tiny.js && node bin/build-tinymce.js",
|
|
26
|
+
"build": "npm run build --workspaces --if-present && tsc -p bin && node bin/build-icon-ico.js && node bin/build-rmfmailto-exe.js && node bin/build-rmf-tiny.js && node bin/build-tinymce.js && node bin/build-bundles.mjs",
|
|
27
27
|
"watch": "tsc -w",
|
|
28
28
|
"start": "node --watch packages/mailx-server/index.js",
|
|
29
29
|
"start:prod": "node packages/mailx-server/index.js",
|
|
@@ -61,6 +61,7 @@
|
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
63
|
"@types/mailparser": "^3.4.6",
|
|
64
|
+
"esbuild": "^0.28.0",
|
|
64
65
|
"jsdom": "^29.1.1"
|
|
65
66
|
},
|
|
66
67
|
"keywords": [
|