@absolutejs/absolute 0.20.0-beta.127 → 0.20.0-beta.128

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.
@@ -29,6 +29,8 @@ export type DevPageWarmer = {
29
29
  warm: (key: string) => Promise<DevPageWarmStatus>;
30
30
  /** Current manifest value for a key, after a warm. */
31
31
  lookup: (key: string) => string | undefined;
32
+ /** The error the last failed page build reported, if any. */
33
+ lastError?: () => string | undefined;
32
34
  };
33
35
  export type DeferredPageAssets = {
34
36
  /** PascalCase page name the missing keys resolved to. */
@@ -37,6 +39,8 @@ export type DeferredPageAssets = {
37
39
  * then yields `''` for every key, so the handler falls through to its
38
40
  * manifest error — now with the real page name in it. */
39
41
  failed: boolean;
42
+ /** What the failed build reported (`undefined` when it built). */
43
+ error: string | undefined;
40
44
  /** Manifest value for a key after the build (`''` when still absent). */
41
45
  lookup: (key: string) => string;
42
46
  /** Stylesheet hrefs for the CSS keys that went missing during this
@@ -45,19 +49,10 @@ export type DeferredPageAssets = {
45
49
  * response; every later request resolves them through `asset()`. */
46
50
  cssHrefs: () => string[];
47
51
  };
52
+ export declare const devBuildErrorResponse: (framework: string, assets: DeferredPageAssets | null) => Response | null;
48
53
  export declare const getDevPageWarmer: () => DevPageWarmer | undefined;
49
54
  export declare const getMissingAssets: () => string[];
50
- /** Called by `asset()` when a key is missing in dev. */
51
55
  export declare const recordMissingAsset: (name: string) => void;
52
- /** Handler miss path. When a page asset came back `''` from `asset()`,
53
- * build the page those keys belong to and return accessors for the
54
- * fresh manifest values. Returns `null` when the keys are not a deferred
55
- * page's (production, `--eager`, no recorded misses, unknown key) and a
56
- * `failed` result when the build did not produce the page; either way
57
- * the caller falls through to its existing "not found in manifest"
58
- * error. */
59
56
  export declare const resolveDeferredPageAssets: () => Promise<DeferredPageAssets | null>;
60
57
  export declare const setDevPageWarmer: (warmer: DevPageWarmer | undefined) => void;
61
- /** Append `<link rel="stylesheet">` tags for the deferred page's CSS to a
62
- * `<head>…</head>` string (or head fragment). No-op without hrefs. */
63
58
  export declare const withDeferredStylesheets: (head: string, assets: DeferredPageAssets | null) => string;
@@ -0,0 +1 @@
1
+ export declare const changeNeedsRestart: (path: string, isLoaded?: (path: string) => boolean) => boolean;
@@ -1 +1,4 @@
1
+ /** Dev only: the page a request gets when its page failed to build, with
2
+ * the build's own error and a page that reloads itself once fixed. */
3
+ export declare const buildErrorPage: (framework: string, pageName: string, error: string | undefined) => string;
1
4
  export declare const ssrErrorPage: (framework: string, error: unknown) => string;
@@ -1359,7 +1359,96 @@ var init_devRouteRegistrationCallsite = __esm(() => {
1359
1359
  pageHandlerWrappers = new WeakMap;
1360
1360
  });
1361
1361
 
1362
+ // src/utils/ssrErrorPage.ts
1363
+ var exports_ssrErrorPage = {};
1364
+ __export(exports_ssrErrorPage, {
1365
+ buildErrorPage: () => buildErrorPage,
1366
+ ssrErrorPage: () => ssrErrorPage
1367
+ });
1368
+ var errorPageHtml = ({
1369
+ framework,
1370
+ hint,
1371
+ kind,
1372
+ message,
1373
+ script = ""
1374
+ }) => {
1375
+ const frameworkColors = {
1376
+ angular: "#dd0031",
1377
+ html: "#e34c26",
1378
+ htmx: "#1a365d",
1379
+ react: "#61dafb",
1380
+ svelte: "#ff3e00",
1381
+ vue: "#42b883"
1382
+ };
1383
+ const accent = frameworkColors[framework] ?? "#94a3b8";
1384
+ const label = framework.charAt(0).toUpperCase() + framework.slice(1);
1385
+ return `<!DOCTYPE html>
1386
+ <html>
1387
+ <head>
1388
+ <meta charset="utf-8">
1389
+ <meta name="viewport" content="width=device-width, initial-scale=1">
1390
+ <title>SSR Error - AbsoluteJS</title>
1391
+ <style>
1392
+ *{margin:0;padding:0;box-sizing:border-box}
1393
+ body{min-height:100vh;background:linear-gradient(135deg,rgba(15,23,42,0.98) 0%,rgba(30,41,59,0.98) 100%);color:#e2e8f0;font-family:"JetBrains Mono","Fira Code",ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:14px;line-height:1.6;display:flex;align-items:flex-start;justify-content:center;padding:32px}
1394
+ .card{max-width:720px;width:100%;background:rgba(30,41,59,0.6);border:1px solid rgba(71,85,105,0.5);border-radius:16px;box-shadow:0 25px 50px -12px rgba(0,0,0,0.5),0 0 0 1px rgba(255,255,255,0.05);overflow:hidden}
1395
+ .header{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:20px 24px;background:rgba(15,23,42,0.5);border-bottom:1px solid rgba(71,85,105,0.4)}
1396
+ .brand{font-weight:700;font-size:20px;color:#fff;letter-spacing:-0.02em}
1397
+ .badge{padding:5px 10px;border-radius:8px;font-size:12px;font-weight:600;background:${accent};color:#fff;opacity:0.95;box-shadow:0 2px 4px rgba(0,0,0,0.2)}
1398
+ .kind{color:#94a3b8;font-size:13px;font-weight:500}
1399
+ .content{padding:24px}
1400
+ .label{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:0.08em;color:#94a3b8;margin-bottom:8px}
1401
+ .message{margin:0;padding:16px 20px;background:rgba(239,68,68,0.12);border:1px solid rgba(239,68,68,0.25);border-radius:10px;overflow-x:auto;white-space:pre-wrap;word-break:break-word;color:#fca5a5;font-size:13px;line-height:1.5}
1402
+ .hint{margin-top:20px;padding:12px 20px;background:rgba(71,85,105,0.3);border-radius:10px;border:1px solid rgba(71,85,105,0.4);color:#cbd5e1;font-size:13px}
1403
+ </style>
1404
+ </head>
1405
+ <body>
1406
+ <div class="card">
1407
+ <div class="header">
1408
+ <div style="display:flex;align-items:center;gap:12px">
1409
+ <span class="brand">AbsoluteJS</span>
1410
+ <span class="badge">${label}</span>
1411
+ </div>
1412
+ <span class="kind">${kind}</span>
1413
+ </div>
1414
+ <div class="content">
1415
+ <div class="label">What went wrong</div>
1416
+ <pre class="message">${message.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")}</pre>
1417
+ <div class="hint">${hint}</div>
1418
+ </div>
1419
+ </div>
1420
+ ${script}
1421
+ </body>
1422
+ </html>`;
1423
+ }, RELOAD_ON_REBUILD = `<script>(()=>{const url=(location.protocol==='https:'?'wss://':'ws://')+location.host+'/hmr';let seen=false;const connect=()=>{const socket=new WebSocket(url);socket.onopen=()=>{if(seen)location.reload();seen=true;};socket.onmessage=(event)=>{try{const message=JSON.parse(event.data);const type=message&&typeof message.type==='string'?message.type:'';if(type==='rebuild-complete'||type==='server-entry-reloaded'||type.endsWith('-update'))location.reload();}catch{}};socket.onclose=()=>setTimeout(connect,500);};connect();})();</script>`, buildErrorPage = (framework, pageName, error) => errorPageHtml({
1424
+ framework,
1425
+ hint: "Fix the file and save. This page reloads by itself when the build succeeds.",
1426
+ kind: "Build Error",
1427
+ message: `${pageName || "This page"} could not be built.
1428
+
1429
+ ${error ?? "The dev-server terminal has the build output."}`,
1430
+ script: RELOAD_ON_REBUILD
1431
+ }), ssrErrorPage = (framework, error) => errorPageHtml({
1432
+ framework,
1433
+ hint: "A component threw during server-side rendering. Check the terminal for the full stack trace.",
1434
+ kind: "Server Render Error",
1435
+ message: error instanceof Error ? error.message : String(error)
1436
+ });
1437
+
1362
1438
  // src/core/requestContext.ts
1439
+ var exports_requestContext = {};
1440
+ __export(exports_requestContext, {
1441
+ absoluteRequestContext: () => absoluteRequestContext,
1442
+ devBuildErrorResponse: () => devBuildErrorResponse,
1443
+ getCurrentAbsoluteRequest: () => getCurrentAbsoluteRequest,
1444
+ getDevPageWarmer: () => getDevPageWarmer,
1445
+ getMissingAssets: () => getMissingAssets,
1446
+ recordMissingAsset: () => recordMissingAsset,
1447
+ resolveDeferredPageAssets: () => resolveDeferredPageAssets,
1448
+ runWithAbsoluteRequest: () => runWithAbsoluteRequest,
1449
+ setDevPageWarmer: () => setDevPageWarmer,
1450
+ withDeferredStylesheets: () => withDeferredStylesheets
1451
+ });
1363
1452
  import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
1364
1453
  import { Elysia as Elysia2 } from "elysia";
1365
1454
  var REQUEST_STORAGE_KEY, PAGE_WARMER_KEY, isAbsoluteRequestStorage = (value) => typeof value === "object" && value !== null && ("getStore" in value) && typeof value.getStore === "function" && ("run" in value) && typeof value.run === "function", getRequestStorage = () => {
@@ -1372,7 +1461,17 @@ var REQUEST_STORAGE_KEY, PAGE_WARMER_KEY, isAbsoluteRequestStorage = (value) =>
1372
1461
  const storage = new AsyncLocalStorage2;
1373
1462
  Reflect.set(globalThis, REQUEST_STORAGE_KEY, storage);
1374
1463
  return storage;
1375
- }, absoluteRequestContext, getCurrentAbsoluteRequest = () => getRequestStorage()?.getStore()?.request, runWithAbsoluteRequest = (request, callback) => ensureRequestStorage().run({ request }, callback), CSS_KEY_RE, isDevPageWarmer = (value) => typeof value === "object" && value !== null && ("describe" in value) && typeof value.describe === "function" && ("warm" in value) && typeof value.warm === "function" && ("lookup" in value) && typeof value.lookup === "function", getDevPageWarmer = () => {
1464
+ }, absoluteRequestContext, getCurrentAbsoluteRequest = () => getRequestStorage()?.getStore()?.request, runWithAbsoluteRequest = (request, callback) => ensureRequestStorage().run({ request }, callback), CSS_KEY_RE, isDevPageWarmer = (value) => typeof value === "object" && value !== null && ("describe" in value) && typeof value.describe === "function" && ("warm" in value) && typeof value.warm === "function" && ("lookup" in value) && typeof value.lookup === "function", devBuildErrorResponse = (framework, assets) => {
1465
+ if (!assets?.failed)
1466
+ return null;
1467
+ return new Response(buildErrorPage(framework, assets.name, assets.error), {
1468
+ headers: {
1469
+ "cache-control": "no-store",
1470
+ "content-type": "text/html; charset=utf-8"
1471
+ },
1472
+ status: 500
1473
+ });
1474
+ }, getDevPageWarmer = () => {
1376
1475
  const value = Reflect.get(globalThis, PAGE_WARMER_KEY);
1377
1476
  return isDevPageWarmer(value) ? value : undefined;
1378
1477
  }, getMissingAssets = () => {
@@ -1402,6 +1501,7 @@ var REQUEST_STORAGE_KEY, PAGE_WARMER_KEY, isAbsoluteRequestStorage = (value) =>
1402
1501
  const cssHrefs = () => cssKeys.map(lookup).filter((href) => href.length > 0 && href.startsWith("/"));
1403
1502
  const assets = {
1404
1503
  cssHrefs,
1504
+ error: failed ? warmer.lastError?.() : undefined,
1405
1505
  failed,
1406
1506
  lookup,
1407
1507
  name: described.name
@@ -2727,62 +2827,6 @@ var init_inlinePageCss = __esm(() => {
2727
2827
  siblingCssCache = new Map;
2728
2828
  });
2729
2829
 
2730
- // src/utils/ssrErrorPage.ts
2731
- var exports_ssrErrorPage = {};
2732
- __export(exports_ssrErrorPage, {
2733
- ssrErrorPage: () => ssrErrorPage
2734
- });
2735
- var ssrErrorPage = (framework, error) => {
2736
- const frameworkColors2 = {
2737
- angular: "#dd0031",
2738
- html: "#e34c26",
2739
- htmx: "#1a365d",
2740
- react: "#61dafb",
2741
- svelte: "#ff3e00",
2742
- vue: "#42b883"
2743
- };
2744
- const accent = frameworkColors2[framework] ?? "#94a3b8";
2745
- const label = framework.charAt(0).toUpperCase() + framework.slice(1);
2746
- const message = error instanceof Error ? error.message : String(error);
2747
- return `<!DOCTYPE html>
2748
- <html>
2749
- <head>
2750
- <meta charset="utf-8">
2751
- <meta name="viewport" content="width=device-width, initial-scale=1">
2752
- <title>SSR Error - AbsoluteJS</title>
2753
- <style>
2754
- *{margin:0;padding:0;box-sizing:border-box}
2755
- body{min-height:100vh;background:linear-gradient(135deg,rgba(15,23,42,0.98) 0%,rgba(30,41,59,0.98) 100%);color:#e2e8f0;font-family:"JetBrains Mono","Fira Code",ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:14px;line-height:1.6;display:flex;align-items:flex-start;justify-content:center;padding:32px}
2756
- .card{max-width:720px;width:100%;background:rgba(30,41,59,0.6);border:1px solid rgba(71,85,105,0.5);border-radius:16px;box-shadow:0 25px 50px -12px rgba(0,0,0,0.5),0 0 0 1px rgba(255,255,255,0.05);overflow:hidden}
2757
- .header{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:20px 24px;background:rgba(15,23,42,0.5);border-bottom:1px solid rgba(71,85,105,0.4)}
2758
- .brand{font-weight:700;font-size:20px;color:#fff;letter-spacing:-0.02em}
2759
- .badge{padding:5px 10px;border-radius:8px;font-size:12px;font-weight:600;background:${accent};color:#fff;opacity:0.95;box-shadow:0 2px 4px rgba(0,0,0,0.2)}
2760
- .kind{color:#94a3b8;font-size:13px;font-weight:500}
2761
- .content{padding:24px}
2762
- .label{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:0.08em;color:#94a3b8;margin-bottom:8px}
2763
- .message{margin:0;padding:16px 20px;background:rgba(239,68,68,0.12);border:1px solid rgba(239,68,68,0.25);border-radius:10px;overflow-x:auto;white-space:pre-wrap;word-break:break-word;color:#fca5a5;font-size:13px;line-height:1.5}
2764
- .hint{margin-top:20px;padding:12px 20px;background:rgba(71,85,105,0.3);border-radius:10px;border:1px solid rgba(71,85,105,0.4);color:#cbd5e1;font-size:13px}
2765
- </style>
2766
- </head>
2767
- <body>
2768
- <div class="card">
2769
- <div class="header">
2770
- <div style="display:flex;align-items:center;gap:12px">
2771
- <span class="brand">AbsoluteJS</span>
2772
- <span class="badge">${label}</span>
2773
- </div>
2774
- <span class="kind">Server Render Error</span>
2775
- </div>
2776
- <div class="content">
2777
- <div class="label">What went wrong</div>
2778
- <pre class="message">${message.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")}</pre>
2779
- <div class="hint">A component threw during server-side rendering. Check the terminal for the full stack trace.</div>
2780
- </div>
2781
- </div>
2782
- </body>
2783
- </html>`;
2784
- };
2785
-
2786
2830
  // src/utils/stringModifiers.ts
2787
2831
  var normalizeSlug = (str) => str.trim().replace(/\s+/g, "-").replace(/[^A-Za-z0-9\-_]+/g, "").replace(/[-_]{2,}/g, "-"), toKebab = (str) => normalizeSlug(str).replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(), toPascal = (str) => {
2788
2832
  if (!str.includes("-") && !str.includes("_")) {
@@ -4953,6 +4997,9 @@ var resolveRequestPathname = (request) => {
4953
4997
  };
4954
4998
  var handleSveltePageRequest = async (input) => {
4955
4999
  const deferredAssets = input.pagePath === "" || input.indexPath === "" ? await resolveDeferredPageAssets() : null;
5000
+ const buildFailure = devBuildErrorResponse("svelte", deferredAssets);
5001
+ if (buildFailure)
5002
+ return buildFailure;
4956
5003
  const resolvedIndexPath = deferredAssets && input.indexPath === "" ? deferredAssets.lookup(`${deferredAssets.name}Index`) : input.indexPath;
4957
5004
  const resolvedOptions = input;
4958
5005
  const resolvedPagePath = deferredAssets && input.pagePath === "" ? deferredAssets.lookup(deferredAssets.name) : input.pagePath;
@@ -5190,5 +5237,5 @@ export {
5190
5237
  useIslandStore
5191
5238
  };
5192
5239
 
5193
- //# debugId=4751F1FBF20B796164756E2164756E21
5240
+ //# debugId=2EDE00DA0C38CFA264756E2164756E21
5194
5241
  //# sourceMappingURL=index.js.map