bosia 0.5.10 → 0.5.11

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bosia",
3
- "version": "0.5.10",
3
+ "version": "0.5.11",
4
4
  "type": "module",
5
5
  "description": "A fast, batteries-included fullstack framework — SSR · Svelte 5 Runes · Bun · ElysiaJS. File-based routing inspired by SvelteKit. No Node.js, no Vite, no adapters.",
6
6
  "keywords": [
@@ -0,0 +1,78 @@
1
+ import { safeJsonForScript } from "./html.ts";
2
+ import { getOverlayScript } from "./plugins/inspector/overlay.ts";
3
+
4
+ export interface DevServerError {
5
+ id: string;
6
+ ts: number;
7
+ source: string;
8
+ message: string;
9
+ stack?: string;
10
+ file?: string;
11
+ line?: number;
12
+ col?: number;
13
+ }
14
+
15
+ /**
16
+ * Minimal HTML shown when the dev proxy can't reach the app server (initial
17
+ * build failure, crash loop, port conflict). Mounts the same inspector overlay
18
+ * so the red error badge appears identical to the in-app experience, pre-seeds
19
+ * the buffered errors that fired before the page loaded, and subscribes to the
20
+ * dev SSE channel so it auto-reloads when the next build succeeds.
21
+ */
22
+ export function renderDevErrorPage(buffered: DevServerError[]): string {
23
+ const overlay = getOverlayScript({ endpoint: "/__bosia/locate", errorsEnabled: true });
24
+ const seed = safeJsonForScript(buffered);
25
+
26
+ return `<!DOCTYPE html>
27
+ <html lang="en">
28
+ <head>
29
+ <meta charset="UTF-8">
30
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
31
+ <title>Dev server error — Bosia</title>
32
+ <style>
33
+ html,body{margin:0;padding:0;height:100%;background:#0a0a0a;color:#e5e5e5;font:14px/1.5 ui-sans-serif,system-ui,-apple-system,sans-serif}
34
+ .wrap{min-height:100%;display:flex;align-items:center;justify-content:center;padding:24px;box-sizing:border-box}
35
+ .card{max-width:540px;text-align:center}
36
+ .dot{display:inline-block;width:10px;height:10px;background:#dc2626;border-radius:50%;margin-right:8px;vertical-align:middle;animation:p 1.4s ease-in-out infinite}
37
+ @keyframes p{0%,100%{opacity:1}50%{opacity:.3}}
38
+ h1{font-size:18px;font-weight:600;margin:0 0 8px}
39
+ p{margin:0;color:#a3a3a3;font-size:13px}
40
+ code{font-family:ui-monospace,monospace;color:#fafafa;background:#1f1f1f;padding:1px 6px;border-radius:3px}
41
+ </style>
42
+ </head>
43
+ <body>
44
+ <div class="wrap">
45
+ <div class="card">
46
+ <h1><span class="dot"></span>Dev server error</h1>
47
+ <p>See the red badge in the bottom-right for details. This page will reload automatically when the next build succeeds.</p>
48
+ </div>
49
+ </div>
50
+ <script type="application/json" id="__bosia-dev-errors__">${seed}</script>
51
+ ${overlay}
52
+ <script>
53
+ (function(){
54
+ function seed(){
55
+ var node=document.getElementById("__bosia-dev-errors__");
56
+ if(!node||!window.__BOSIA_PUSH_ERROR__)return false;
57
+ try{
58
+ var list=JSON.parse(node.textContent||"[]");
59
+ for(var i=0;i<list.length;i++)window.__BOSIA_PUSH_ERROR__(list[i]);
60
+ }catch(_){}
61
+ return true;
62
+ }
63
+ if(!seed()){
64
+ var tries=0;
65
+ var iv=setInterval(function(){tries++;if(seed()||tries>20)clearInterval(iv)},50);
66
+ }
67
+ !function r(){
68
+ try{
69
+ var e=new EventSource("/__bosia/sse");
70
+ e.addEventListener("reload",function(){location.reload()});
71
+ e.onerror=function(){e.close();setTimeout(r,2000)};
72
+ }catch(_){setTimeout(r,2000)}
73
+ }();
74
+ })();
75
+ </script>
76
+ </body>
77
+ </html>`;
78
+ }
@@ -6,7 +6,7 @@
6
6
  // is a safe no-op otherwise.
7
7
 
8
8
  interface DevReportInput {
9
- source?: "elysia" | "uncaught" | "rejection";
9
+ source?: "server" | "uncaught" | "rejection";
10
10
  message: string;
11
11
  stack?: string;
12
12
  }
@@ -22,7 +22,7 @@ export function reportDevErrorFromCatch(err: unknown): void {
22
22
  const e = err as Error | undefined;
23
23
  try {
24
24
  fn({
25
- source: "elysia",
25
+ source: "server",
26
26
  message: e?.message ?? String(err),
27
27
  stack: e?.stack,
28
28
  });
package/src/core/html.ts CHANGED
@@ -160,7 +160,7 @@ export function buildHtml(
160
160
  ` <script${n}>try{var t=localStorage.getItem('theme');if(t==='dark'||(!t&&window.matchMedia('(prefers-color-scheme: dark)').matches))document.documentElement.classList.add('dark');else document.documentElement.classList.remove('dark')}catch(_){}</script>\n` +
161
161
  ` ${fallbackTitle}${head}` +
162
162
  headCloseInterpolated +
163
- `\n${SPINNER}` +
163
+ (body ? "" : `\n${SPINNER}`) +
164
164
  `\n <div id="app">${body}</div>${scripts}${bodyEnd}` +
165
165
  tailInterpolated
166
166
  );
@@ -42,6 +42,7 @@ async function pluginRenderFragments(
42
42
  } catch (err) {
43
43
  if (isDev) console.error(`Plugin "${p.name}" render.${hook} failed:`, err);
44
44
  else console.error(`Plugin "${p.name}" render.${hook} failed:`, (err as Error).message);
45
+ if (isDev) reportDevErrorFromCatch(err);
45
46
  }
46
47
  }
47
48
  return out;
@@ -481,6 +482,7 @@ export async function loadMetadata(
481
482
  } catch (err) {
482
483
  if (isDev) console.error("Metadata load error:", err);
483
484
  else console.error("Metadata load error:", (err as Error).message ?? err);
485
+ if (isDev) reportDevErrorFromCatch(err);
484
486
  }
485
487
  return null;
486
488
  }
@@ -524,6 +526,7 @@ export async function renderSSRStream(
524
526
  }
525
527
  if (isDev) console.error("Metadata load error:", err);
526
528
  else console.error("Metadata load error:", (err as Error).message ?? err);
529
+ if (isDev) reportDevErrorFromCatch(err);
527
530
  // Continue with null metadata — don't break the page for a metadata failure
528
531
  }
529
532
 
@@ -651,6 +654,7 @@ export async function renderSSRStream(
651
654
  } catch (err) {
652
655
  if (isDev) console.error("SSR render error:", err);
653
656
  else console.error("SSR render error:", (err as Error).message ?? err);
657
+ if (isDev) reportDevErrorFromCatch(err);
654
658
  // Render-phase errors fall through to deepest boundary like a page error.
655
659
  return renderErrorPage(
656
660
  500,
@@ -910,6 +914,7 @@ export async function renderErrorPage(
910
914
  "Nested error page render failed:",
911
915
  (err as Error).message ?? err,
912
916
  );
917
+ if (isDev) reportDevErrorFromCatch(err);
913
918
  // fall through to global / text fallback
914
919
  }
915
920
  }
@@ -944,6 +949,7 @@ export async function renderErrorPage(
944
949
  } catch (err) {
945
950
  if (isDev) console.error("Error page render failed:", err);
946
951
  else console.error("Error page render failed:", (err as Error).message ?? err);
952
+ if (isDev) reportDevErrorFromCatch(err);
947
953
  }
948
954
  }
949
955
  return new Response(message, {