@bobfrankston/mailx 1.0.91 → 1.0.92

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/client/app.js CHANGED
@@ -781,10 +781,20 @@ optEditorTiptap?.addEventListener("change", () => {
781
781
  saveEditorSetting("tiptap");
782
782
  });
783
783
  const isApp = typeof mailxapi !== "undefined" && mailxapi?.isApp;
784
+ // Dismiss startup overlay immediately in browser/local mode — the UI components
785
+ // have their own loading states ("Loading accounts...", etc.). Only keep the
786
+ // overlay for native app mode where ensureServer needs to start the server.
787
+ if (!isApp) {
788
+ const overlay = document.getElementById("startup-overlay");
789
+ if (overlay) {
790
+ overlay.classList.add("hidden");
791
+ setTimeout(() => overlay.remove(), 400);
792
+ }
793
+ }
784
794
  async function checkServer() {
785
795
  const base = getServerUrl();
786
796
  try {
787
- const res = await fetch(`${base}/api/version`);
797
+ const res = await fetch(`${base}/api/version`, { signal: AbortSignal.timeout(5000) });
788
798
  const ct = res.headers.get("content-type") || "";
789
799
  if (ct.includes("text/html") || !res.ok)
790
800
  throw new Error("not JSON");
@@ -796,8 +806,10 @@ async function checkServer() {
796
806
  el.textContent = `mailx v${d.version}${storageLabel}${isApp ? "" : " · browser"}`;
797
807
  // Hide startup overlay on success
798
808
  const overlay = document.getElementById("startup-overlay");
799
- if (overlay)
800
- overlay.hidden = true;
809
+ if (overlay) {
810
+ overlay.classList.add("hidden");
811
+ setTimeout(() => overlay.remove(), 400);
812
+ }
801
813
  }
802
814
  catch {
803
815
  const startupStatus = document.getElementById("startup-status");
@@ -892,10 +904,23 @@ async function checkServer() {
892
904
  statusEl.textContent = `Error: ${e.message}`;
893
905
  }
894
906
  }
895
- else {
896
- // Browser mode — prompt for server URL
907
+ else if (getServerUrl()) {
908
+ // Remote server configured but unreachable — prompt to change URL
897
909
  promptForServer();
898
910
  }
911
+ else {
912
+ // Local server not responding — dismiss overlay, show UI with offline status
913
+ const overlay = document.getElementById("startup-overlay");
914
+ if (overlay) {
915
+ overlay.classList.add("hidden");
916
+ setTimeout(() => overlay.remove(), 400);
917
+ }
918
+ const statusSync = document.getElementById("status-sync");
919
+ if (statusSync) {
920
+ statusSync.textContent = "SERVER OFFLINE";
921
+ statusSync.style.color = "oklch(0.65 0.2 25)";
922
+ }
923
+ }
899
924
  }
900
925
  }
901
926
  function promptForServer() {
@@ -40,14 +40,21 @@ class HttpTransport {
40
40
  const base = serverUrl ? serverUrl : "";
41
41
  let res;
42
42
  try {
43
- res = await fetch(`${base}/api${path}`, {
43
+ // Default 10s timeout prevents hangs when server is zombie (accepts TCP, never responds)
44
+ const fetchOptions = {
44
45
  headers: { "Content-Type": "application/json" },
45
46
  ...options,
46
- });
47
+ };
48
+ if (!fetchOptions.signal) {
49
+ fetchOptions.signal = AbortSignal.timeout(10000);
50
+ }
51
+ res = await fetch(`${base}/api${path}`, fetchOptions);
47
52
  }
48
53
  catch (e) {
49
54
  if (e.name === "AbortError")
50
55
  throw e;
56
+ if (e.name === "TimeoutError")
57
+ throw new Error("Server not responding — request timed out");
51
58
  throw new Error("Server offline — check connection or run: mailx -server");
52
59
  }
53
60
  // Detect HTML error responses (server not reachable, returns error page)
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobfrankston/mailx-client",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "dependencies": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobfrankston/mailx",
3
- "version": "1.0.91",
3
+ "version": "1.0.92",
4
4
  "description": "Local-first email client with IMAP sync and standalone native app",
5
5
  "type": "module",
6
6
  "main": "bin/mailx.js",