@absolutejs/absolute 0.19.0-beta.1095 → 0.19.0-beta.1097

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.
@@ -1129,6 +1129,343 @@ var normalizeSlug = (str) => str.trim().replace(/\s+/g, "-").replace(/[^A-Za-z0-
1129
1129
  return normalizeSlug(str).split(/[-_]/).filter(Boolean).map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1).toLowerCase()).join("");
1130
1130
  };
1131
1131
 
1132
+ // src/utils/resolveConvention.ts
1133
+ import { basename } from "path";
1134
+ var CONVENTIONS_KEY = "__absoluteConventions", isConventionsMap = (value) => Boolean(value) && typeof value === "object", getMap = () => {
1135
+ const value = Reflect.get(globalThis, CONVENTIONS_KEY);
1136
+ if (isConventionsMap(value))
1137
+ return value;
1138
+ const empty = {};
1139
+ return empty;
1140
+ }, derivePageName = (pagePath) => {
1141
+ const base = basename(pagePath);
1142
+ const dotIndex = base.indexOf(".");
1143
+ const name = dotIndex > 0 ? base.slice(0, dotIndex) : base;
1144
+ return toPascal(name);
1145
+ }, normalizeConventionPageName = (name) => toPascal(name).replace(/\d+$/, ""), hasErrorConvention = (framework) => {
1146
+ const conventions = getMap()[framework];
1147
+ if (!conventions)
1148
+ return false;
1149
+ if (conventions.defaults?.error)
1150
+ return true;
1151
+ return Object.values(conventions.pages ?? {}).some((page) => Boolean(page.error));
1152
+ }, resolveErrorConventionPath = (framework, pageName) => {
1153
+ const conventions = getMap()[framework];
1154
+ if (!conventions)
1155
+ return;
1156
+ const exact = conventions.pages?.[pageName]?.error;
1157
+ if (exact)
1158
+ return exact;
1159
+ const normalizedPageName = normalizeConventionPageName(pageName);
1160
+ for (const [candidate, page] of Object.entries(conventions.pages ?? {})) {
1161
+ if (normalizeConventionPageName(candidate) === normalizedPageName) {
1162
+ return page.error ?? conventions.defaults?.error;
1163
+ }
1164
+ }
1165
+ return conventions.defaults?.error;
1166
+ }, resolveNotFoundConventionPath = (framework) => getMap()[framework]?.defaults?.notFound, setConventions = (map) => {
1167
+ Reflect.set(globalThis, CONVENTIONS_KEY, map);
1168
+ }, isDev = () => true, buildErrorProps = (error) => {
1169
+ if (error instanceof Error) {
1170
+ return {
1171
+ name: error.name,
1172
+ message: error.message,
1173
+ ...isDev() && error.stack ? { stack: error.stack } : {}
1174
+ };
1175
+ }
1176
+ return { message: String(error), name: "Error" };
1177
+ }, renderReactError = async (conventionPath, errorProps) => {
1178
+ const { createElement } = await import("react");
1179
+ const { renderToReadableStream } = await import("react-dom/server");
1180
+ const mod = await import(conventionPath);
1181
+ const ErrorComponent = mod.default;
1182
+ if (typeof ErrorComponent !== "function")
1183
+ return null;
1184
+ const element = createElement(ErrorComponent, errorProps);
1185
+ const stream = await renderToReadableStream(element);
1186
+ return new Response(stream, {
1187
+ headers: { "Content-Type": "text/html" },
1188
+ status: 500
1189
+ });
1190
+ }, renderSvelteError = async (conventionPath, errorProps) => {
1191
+ const { render } = await import("svelte/server");
1192
+ const mod = await import(conventionPath);
1193
+ const ErrorComponent = mod.default;
1194
+ if (!ErrorComponent)
1195
+ return null;
1196
+ const { head, body } = render(ErrorComponent, {
1197
+ props: errorProps
1198
+ });
1199
+ const html = `<!DOCTYPE html><html><head>${head}</head><body>${body}</body></html>`;
1200
+ return new Response(html, {
1201
+ headers: { "Content-Type": "text/html" },
1202
+ status: 500
1203
+ });
1204
+ }, unescapeVueStyles = (ssrBody) => {
1205
+ let styles = "";
1206
+ const body = ssrBody.replace(/<style>([\s\S]*?)<\/style>/g, (_, css) => {
1207
+ styles += `<style>${css.replace(/&quot;/g, '"').replace(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">")}</style>`;
1208
+ return "";
1209
+ });
1210
+ return { body, styles };
1211
+ }, renderVueError = async (conventionPath, errorProps) => {
1212
+ const { createSSRApp, h } = await import("vue");
1213
+ const { renderToString } = await import("vue/server-renderer");
1214
+ const mod = await import(conventionPath);
1215
+ const ErrorComponent = mod.default;
1216
+ if (!ErrorComponent)
1217
+ return null;
1218
+ const app = createSSRApp({
1219
+ render: () => h(ErrorComponent, errorProps)
1220
+ });
1221
+ const rawBody = await renderToString(app);
1222
+ const { styles, body } = unescapeVueStyles(rawBody);
1223
+ const html = `<!DOCTYPE html><html><head>${styles}</head><body><div id="root">${body}</div></body></html>`;
1224
+ return new Response(html, {
1225
+ headers: { "Content-Type": "text/html" },
1226
+ status: 500
1227
+ });
1228
+ }, renderAngularError = async (conventionPath, errorProps) => {
1229
+ const mod = await import(conventionPath);
1230
+ const renderFn = mod.default;
1231
+ if (typeof renderFn !== "function")
1232
+ return null;
1233
+ const html = renderFn(errorProps);
1234
+ return new Response(html, {
1235
+ headers: { "Content-Type": "text/html" },
1236
+ status: 500
1237
+ });
1238
+ }, escapeHtml = (value) => value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;"), replaceErrorTokens = (template, errorProps) => template.replace(/\{\{\s*name\s*\}\}/g, escapeHtml(errorProps.name)).replace(/\{\{\s*message\s*\}\}/g, escapeHtml(errorProps.message)).replace(/\{\{\s*stack\s*\}\}/g, errorProps.stack ? escapeHtml(errorProps.stack) : ""), renderHtmlError = async (conventionPath, errorProps) => {
1239
+ const template = await Bun.file(conventionPath).text();
1240
+ const html = replaceErrorTokens(template, errorProps);
1241
+ return new Response(html, {
1242
+ headers: { "Content-Type": "text/html" },
1243
+ status: 500
1244
+ });
1245
+ }, logConventionRenderError = (framework, label, renderError) => {
1246
+ const message = renderError instanceof Error ? renderError.message : "";
1247
+ if (message.includes("Cannot find module") || message.includes("Cannot find package") || message.includes("not found in module")) {
1248
+ console.error(`[SSR] Convention ${label} page for ${framework} failed: missing framework package. Ensure the ${framework} runtime is installed (e.g. bun add ${framework === "react" ? "react react-dom" : framework}).`);
1249
+ return;
1250
+ }
1251
+ console.error(`[SSR] Failed to render ${framework} convention ${label} page:`, renderError);
1252
+ }, renderEmberError = async () => null, renderEmberNotFound = async () => null, ERROR_RENDERERS, tryFrameworkErrorConvention = async (framework, pageName, errorProps, error) => {
1253
+ let conventionPath = resolveErrorConventionPath(framework, pageName);
1254
+ if (!conventionPath && error instanceof Error && error.stack) {
1255
+ for (const match of error.stack.matchAll(/^\s*at\s+([A-Za-z_$][\w$]*)/gm)) {
1256
+ const candidate = match[1];
1257
+ if (!candidate)
1258
+ continue;
1259
+ conventionPath = resolveErrorConventionPath(framework, candidate);
1260
+ if (conventionPath)
1261
+ break;
1262
+ }
1263
+ }
1264
+ if (!conventionPath)
1265
+ return null;
1266
+ const renderer = ERROR_RENDERERS[framework];
1267
+ if (!renderer)
1268
+ return null;
1269
+ try {
1270
+ return await renderer(conventionPath, errorProps);
1271
+ } catch (renderError) {
1272
+ logConventionRenderError(framework, "error", renderError);
1273
+ }
1274
+ return null;
1275
+ }, renderConventionError = async (framework, pageName, error) => {
1276
+ const errorProps = buildErrorProps(error);
1277
+ const frameworkResponse = await tryFrameworkErrorConvention(framework, pageName, errorProps, error);
1278
+ if (frameworkResponse)
1279
+ return frameworkResponse;
1280
+ if (framework !== "html") {
1281
+ const htmlResponse = await tryFrameworkErrorConvention("html", pageName, errorProps, error);
1282
+ if (htmlResponse)
1283
+ return htmlResponse;
1284
+ }
1285
+ return null;
1286
+ }, renderReactNotFound = async (conventionPath) => {
1287
+ const { createElement } = await import("react");
1288
+ const { renderToReadableStream } = await import("react-dom/server");
1289
+ const mod = await import(conventionPath);
1290
+ const NotFoundComponent = mod.default;
1291
+ if (typeof NotFoundComponent !== "function")
1292
+ return null;
1293
+ const element = createElement(NotFoundComponent);
1294
+ const stream = await renderToReadableStream(element);
1295
+ return new Response(stream, {
1296
+ headers: { "Content-Type": "text/html" },
1297
+ status: 404
1298
+ });
1299
+ }, renderSvelteNotFound = async (conventionPath) => {
1300
+ const { render } = await import("svelte/server");
1301
+ const mod = await import(conventionPath);
1302
+ const NotFoundComponent = mod.default;
1303
+ if (!NotFoundComponent)
1304
+ return null;
1305
+ const { head, body } = render(NotFoundComponent);
1306
+ const html = `<!DOCTYPE html><html><head>${head}</head><body>${body}</body></html>`;
1307
+ return new Response(html, {
1308
+ headers: { "Content-Type": "text/html" },
1309
+ status: 404
1310
+ });
1311
+ }, renderVueNotFound = async (conventionPath) => {
1312
+ const { createSSRApp, h } = await import("vue");
1313
+ const { renderToString } = await import("vue/server-renderer");
1314
+ const mod = await import(conventionPath);
1315
+ const NotFoundComponent = mod.default;
1316
+ if (!NotFoundComponent)
1317
+ return null;
1318
+ const app = createSSRApp({
1319
+ render: () => h(NotFoundComponent)
1320
+ });
1321
+ const rawBody = await renderToString(app);
1322
+ const { styles, body } = unescapeVueStyles(rawBody);
1323
+ const html = `<!DOCTYPE html><html><head>${styles}</head><body><div id="root">${body}</div></body></html>`;
1324
+ return new Response(html, {
1325
+ headers: { "Content-Type": "text/html" },
1326
+ status: 404
1327
+ });
1328
+ }, renderAngularNotFound = async (conventionPath) => {
1329
+ const mod = await import(conventionPath);
1330
+ const renderFn = mod.default;
1331
+ if (typeof renderFn !== "function")
1332
+ return null;
1333
+ const html = renderFn();
1334
+ return new Response(html, {
1335
+ headers: { "Content-Type": "text/html" },
1336
+ status: 404
1337
+ });
1338
+ }, renderHtmlNotFound = async (conventionPath) => {
1339
+ const html = await Bun.file(conventionPath).text();
1340
+ return new Response(html, {
1341
+ headers: { "Content-Type": "text/html" },
1342
+ status: 404
1343
+ });
1344
+ }, NOT_FOUND_RENDERERS, renderConventionNotFound = async (framework) => {
1345
+ const conventionPath = resolveNotFoundConventionPath(framework);
1346
+ if (!conventionPath)
1347
+ return null;
1348
+ const renderer = NOT_FOUND_RENDERERS[framework];
1349
+ if (!renderer)
1350
+ return null;
1351
+ try {
1352
+ return await renderer(conventionPath);
1353
+ } catch (renderError) {
1354
+ logConventionRenderError(framework, "not-found", renderError);
1355
+ }
1356
+ return null;
1357
+ }, NOT_FOUND_PRIORITY, renderFirstNotFound = async () => {
1358
+ const renderNext = async (frameworks) => {
1359
+ const [framework, ...remaining] = frameworks;
1360
+ if (!framework) {
1361
+ return null;
1362
+ }
1363
+ if (!getMap()[framework]?.defaults?.notFound) {
1364
+ return renderNext(remaining);
1365
+ }
1366
+ const response = await renderConventionNotFound(framework);
1367
+ if (response) {
1368
+ return response;
1369
+ }
1370
+ return renderNext(remaining);
1371
+ };
1372
+ return renderNext(NOT_FOUND_PRIORITY);
1373
+ };
1374
+ var init_resolveConvention = __esm(() => {
1375
+ ERROR_RENDERERS = {
1376
+ angular: renderAngularError,
1377
+ ember: renderEmberError,
1378
+ html: renderHtmlError,
1379
+ react: renderReactError,
1380
+ svelte: renderSvelteError,
1381
+ vue: renderVueError
1382
+ };
1383
+ NOT_FOUND_RENDERERS = {
1384
+ angular: renderAngularNotFound,
1385
+ ember: renderEmberNotFound,
1386
+ html: renderHtmlNotFound,
1387
+ react: renderReactNotFound,
1388
+ svelte: renderSvelteNotFound,
1389
+ vue: renderVueNotFound
1390
+ };
1391
+ NOT_FOUND_PRIORITY = [
1392
+ "react",
1393
+ "svelte",
1394
+ "vue",
1395
+ "angular",
1396
+ "html"
1397
+ ];
1398
+ });
1399
+
1400
+ // src/utils/spaRouteManifest.ts
1401
+ import { basename as basename2 } from "path";
1402
+ var SPA_ROUTES_KEY = "__absoluteSpaRoutes", setSpaRouteManifest = (hosts) => {
1403
+ Reflect.set(globalThis, SPA_ROUTES_KEY, hosts);
1404
+ }, getSpaRouteManifest = () => {
1405
+ const value = Reflect.get(globalThis, SPA_ROUTES_KEY);
1406
+ return Array.isArray(value) ? value : [];
1407
+ }, normalizePath = (path) => {
1408
+ const withLeadingSlash = path.startsWith("/") ? path : `/${path}`;
1409
+ const trimmed = withLeadingSlash.replace(/\/+$/, "");
1410
+ return trimmed || "/";
1411
+ }, fullRoutePath = (baseHref, routePath) => {
1412
+ const base = normalizePath(baseHref);
1413
+ const route = normalizePath(routePath);
1414
+ if (base !== "/" && (route === base || route.startsWith(`${base}/`))) {
1415
+ return route;
1416
+ }
1417
+ if (base === "/")
1418
+ return route;
1419
+ return normalizePath(`${base}/${route.replace(/^\/+/, "")}`);
1420
+ }, routePattern = (path) => {
1421
+ const segments = normalizePath(path).split("/").filter(Boolean);
1422
+ let expression = "^";
1423
+ for (const segment of segments) {
1424
+ if (segment === "*" || segment === "**") {
1425
+ expression += "(?:/.*)?";
1426
+ continue;
1427
+ }
1428
+ const parameter = /^:[A-Za-z_$][A-Za-z0-9_$]*(?:\((.*)\))?(\?)?$/.exec(segment);
1429
+ if (parameter) {
1430
+ const valuePattern = parameter[1] || "[^/]+";
1431
+ expression += parameter[2] ? `(?:/${valuePattern})?` : `/${valuePattern}`;
1432
+ continue;
1433
+ }
1434
+ expression += `/${segment.replace(/[.+?^${}()|[\]\\]/g, "\\$&")}`;
1435
+ }
1436
+ return new RegExp(`${expression || "^/"}/?$`);
1437
+ }, sourcePageName = (sourceFile) => basename2(sourceFile).replace(/\.[^.]+$/, "").toLowerCase(), isKnownSpaRoute = (framework, pageName, request) => {
1438
+ if (!request)
1439
+ return true;
1440
+ let pathname;
1441
+ try {
1442
+ pathname = normalizePath(new URL(request.url).pathname);
1443
+ } catch {
1444
+ return true;
1445
+ }
1446
+ const hosts = getSpaRouteManifest().filter((host) => {
1447
+ if (host.framework !== framework)
1448
+ return false;
1449
+ if (sourcePageName(host.sourceFile) !== pageName.toLowerCase())
1450
+ return false;
1451
+ const base = normalizePath(host.baseHref);
1452
+ return base === "/" || pathname === base || pathname.startsWith(`${base}/`);
1453
+ });
1454
+ if (hosts.length === 0)
1455
+ return true;
1456
+ return hosts.some((host) => host.routes.some((route) => routePattern(fullRoutePath(host.baseHref, route.path)).test(pathname)));
1457
+ }, renderSpaNotFound = async (framework, pageName, request) => {
1458
+ if (isKnownSpaRoute(framework, pageName, request))
1459
+ return null;
1460
+ return await renderFirstNotFound() ?? new Response("Not found", {
1461
+ headers: { "Content-Type": "text/plain" },
1462
+ status: 404
1463
+ });
1464
+ };
1465
+ var init_spaRouteManifest = __esm(() => {
1466
+ init_resolveConvention();
1467
+ });
1468
+
1132
1469
  // src/core/islandManifest.ts
1133
1470
  var toIslandFrameworkSegment = (framework) => framework[0]?.toUpperCase() + framework.slice(1), collectFrameworkIslands = (manifest, prefix) => {
1134
1471
  const entries = {};
@@ -3137,7 +3474,7 @@ var init_stylePreprocessor = __esm(() => {
3137
3474
 
3138
3475
  // src/core/svelteServerModule.ts
3139
3476
  import { mkdir as mkdir2, readdir as readdir2 } from "fs/promises";
3140
- import { basename as basename2, dirname as dirname3, extname as extname2, join as join6, relative as relative3, resolve as resolve5 } from "path";
3477
+ import { basename as basename3, dirname as dirname3, extname as extname2, join as join6, relative as relative3, resolve as resolve5 } from "path";
3141
3478
  var serverCacheRoot2, compiledModuleCache2, originalSourcePathCache, transpiler, ensureRelativeImportPath = (from, target) => {
3142
3479
  const importPath = relative3(dirname3(from), target).replace(/\\/g, "/");
3143
3480
  return importPath.startsWith(".") ? importPath : `./${importPath}`;
@@ -3168,7 +3505,7 @@ var serverCacheRoot2, compiledModuleCache2, originalSourcePathCache, transpiler,
3168
3505
  return found;
3169
3506
  }
3170
3507
  return searchDirectoryLevel(nextStack, targetFileName);
3171
- }, findSourceFileByBasename = async (searchRoot, targetFileName) => searchDirectoryLevel([searchRoot], targetFileName), normalizeBuiltSvelteFileName = (sourcePath) => basename2(sourcePath).replace(/-[a-z0-9]{6,}(?=\.svelte$)/i, ""), resolveOriginalSourcePath = async (sourcePath) => {
3508
+ }, findSourceFileByBasename = async (searchRoot, targetFileName) => searchDirectoryLevel([searchRoot], targetFileName), normalizeBuiltSvelteFileName = (sourcePath) => basename3(sourcePath).replace(/-[a-z0-9]{6,}(?=\.svelte$)/i, ""), resolveOriginalSourcePath = async (sourcePath) => {
3172
3509
  const cachedPath = originalSourcePathCache.get(sourcePath);
3173
3510
  if (cachedPath !== undefined) {
3174
3511
  return cachedPath;
@@ -4008,303 +4345,10 @@ var captureStreamingSlotWarningCallsite = () => {
4008
4345
  return extractCallsiteFromStack(stack);
4009
4346
  };
4010
4347
  var runWithStreamingSlotWarningScope = (task, metadata) => ensureWarningStorage().run({ handlerCallsite: metadata?.handlerCallsite, hasWarned: false }, task);
4011
- // src/utils/resolveConvention.ts
4012
- import { basename } from "path";
4013
- var CONVENTIONS_KEY = "__absoluteConventions";
4014
- var isConventionsMap = (value) => Boolean(value) && typeof value === "object";
4015
- var getMap = () => {
4016
- const value = Reflect.get(globalThis, CONVENTIONS_KEY);
4017
- if (isConventionsMap(value))
4018
- return value;
4019
- const empty = {};
4020
- return empty;
4021
- };
4022
- var derivePageName = (pagePath) => {
4023
- const base = basename(pagePath);
4024
- const dotIndex = base.indexOf(".");
4025
- const name = dotIndex > 0 ? base.slice(0, dotIndex) : base;
4026
- return toPascal(name);
4027
- };
4028
- var normalizeConventionPageName = (name) => toPascal(name).replace(/\d+$/, "");
4029
- var hasErrorConvention = (framework) => {
4030
- const conventions = getMap()[framework];
4031
- if (!conventions)
4032
- return false;
4033
- if (conventions.defaults?.error)
4034
- return true;
4035
- return Object.values(conventions.pages ?? {}).some((page) => Boolean(page.error));
4036
- };
4037
- var resolveErrorConventionPath = (framework, pageName) => {
4038
- const conventions = getMap()[framework];
4039
- if (!conventions)
4040
- return;
4041
- const exact = conventions.pages?.[pageName]?.error;
4042
- if (exact)
4043
- return exact;
4044
- const normalizedPageName = normalizeConventionPageName(pageName);
4045
- for (const [candidate, page] of Object.entries(conventions.pages ?? {})) {
4046
- if (normalizeConventionPageName(candidate) === normalizedPageName) {
4047
- return page.error ?? conventions.defaults?.error;
4048
- }
4049
- }
4050
- return conventions.defaults?.error;
4051
- };
4052
- var resolveNotFoundConventionPath = (framework) => getMap()[framework]?.defaults?.notFound;
4053
- var setConventions = (map) => {
4054
- Reflect.set(globalThis, CONVENTIONS_KEY, map);
4055
- };
4056
- var isDev = () => true;
4057
- var buildErrorProps = (error) => {
4058
- if (error instanceof Error) {
4059
- return {
4060
- name: error.name,
4061
- message: error.message,
4062
- ...isDev() && error.stack ? { stack: error.stack } : {}
4063
- };
4064
- }
4065
- return { message: String(error), name: "Error" };
4066
- };
4067
- var renderReactError = async (conventionPath, errorProps) => {
4068
- const { createElement } = await import("react");
4069
- const { renderToReadableStream } = await import("react-dom/server");
4070
- const mod = await import(conventionPath);
4071
- const ErrorComponent = mod.default;
4072
- if (typeof ErrorComponent !== "function")
4073
- return null;
4074
- const element = createElement(ErrorComponent, errorProps);
4075
- const stream = await renderToReadableStream(element);
4076
- return new Response(stream, {
4077
- headers: { "Content-Type": "text/html" },
4078
- status: 500
4079
- });
4080
- };
4081
- var renderSvelteError = async (conventionPath, errorProps) => {
4082
- const { render } = await import("svelte/server");
4083
- const mod = await import(conventionPath);
4084
- const ErrorComponent = mod.default;
4085
- if (!ErrorComponent)
4086
- return null;
4087
- const { head, body } = render(ErrorComponent, {
4088
- props: errorProps
4089
- });
4090
- const html = `<!DOCTYPE html><html><head>${head}</head><body>${body}</body></html>`;
4091
- return new Response(html, {
4092
- headers: { "Content-Type": "text/html" },
4093
- status: 500
4094
- });
4095
- };
4096
- var unescapeVueStyles = (ssrBody) => {
4097
- let styles = "";
4098
- const body = ssrBody.replace(/<style>([\s\S]*?)<\/style>/g, (_, css) => {
4099
- styles += `<style>${css.replace(/&quot;/g, '"').replace(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">")}</style>`;
4100
- return "";
4101
- });
4102
- return { body, styles };
4103
- };
4104
- var renderVueError = async (conventionPath, errorProps) => {
4105
- const { createSSRApp, h } = await import("vue");
4106
- const { renderToString } = await import("vue/server-renderer");
4107
- const mod = await import(conventionPath);
4108
- const ErrorComponent = mod.default;
4109
- if (!ErrorComponent)
4110
- return null;
4111
- const app = createSSRApp({
4112
- render: () => h(ErrorComponent, errorProps)
4113
- });
4114
- const rawBody = await renderToString(app);
4115
- const { styles, body } = unescapeVueStyles(rawBody);
4116
- const html = `<!DOCTYPE html><html><head>${styles}</head><body><div id="root">${body}</div></body></html>`;
4117
- return new Response(html, {
4118
- headers: { "Content-Type": "text/html" },
4119
- status: 500
4120
- });
4121
- };
4122
- var renderAngularError = async (conventionPath, errorProps) => {
4123
- const mod = await import(conventionPath);
4124
- const renderFn = mod.default;
4125
- if (typeof renderFn !== "function")
4126
- return null;
4127
- const html = renderFn(errorProps);
4128
- return new Response(html, {
4129
- headers: { "Content-Type": "text/html" },
4130
- status: 500
4131
- });
4132
- };
4133
- var escapeHtml = (value) => value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
4134
- var replaceErrorTokens = (template, errorProps) => template.replace(/\{\{\s*name\s*\}\}/g, escapeHtml(errorProps.name)).replace(/\{\{\s*message\s*\}\}/g, escapeHtml(errorProps.message)).replace(/\{\{\s*stack\s*\}\}/g, errorProps.stack ? escapeHtml(errorProps.stack) : "");
4135
- var renderHtmlError = async (conventionPath, errorProps) => {
4136
- const template = await Bun.file(conventionPath).text();
4137
- const html = replaceErrorTokens(template, errorProps);
4138
- return new Response(html, {
4139
- headers: { "Content-Type": "text/html" },
4140
- status: 500
4141
- });
4142
- };
4143
- var logConventionRenderError = (framework, label, renderError) => {
4144
- const message = renderError instanceof Error ? renderError.message : "";
4145
- if (message.includes("Cannot find module") || message.includes("Cannot find package") || message.includes("not found in module")) {
4146
- console.error(`[SSR] Convention ${label} page for ${framework} failed: missing framework package. Ensure the ${framework} runtime is installed (e.g. bun add ${framework === "react" ? "react react-dom" : framework}).`);
4147
- return;
4148
- }
4149
- console.error(`[SSR] Failed to render ${framework} convention ${label} page:`, renderError);
4150
- };
4151
- var renderEmberError = async () => null;
4152
- var renderEmberNotFound = async () => null;
4153
- var ERROR_RENDERERS = {
4154
- angular: renderAngularError,
4155
- ember: renderEmberError,
4156
- html: renderHtmlError,
4157
- react: renderReactError,
4158
- svelte: renderSvelteError,
4159
- vue: renderVueError
4160
- };
4161
- var tryFrameworkErrorConvention = async (framework, pageName, errorProps, error) => {
4162
- let conventionPath = resolveErrorConventionPath(framework, pageName);
4163
- if (!conventionPath && error instanceof Error && error.stack) {
4164
- for (const match of error.stack.matchAll(/^\s*at\s+([A-Za-z_$][\w$]*)/gm)) {
4165
- const candidate = match[1];
4166
- if (!candidate)
4167
- continue;
4168
- conventionPath = resolveErrorConventionPath(framework, candidate);
4169
- if (conventionPath)
4170
- break;
4171
- }
4172
- }
4173
- if (!conventionPath)
4174
- return null;
4175
- const renderer = ERROR_RENDERERS[framework];
4176
- if (!renderer)
4177
- return null;
4178
- try {
4179
- return await renderer(conventionPath, errorProps);
4180
- } catch (renderError) {
4181
- logConventionRenderError(framework, "error", renderError);
4182
- }
4183
- return null;
4184
- };
4185
- var renderConventionError = async (framework, pageName, error) => {
4186
- const errorProps = buildErrorProps(error);
4187
- const frameworkResponse = await tryFrameworkErrorConvention(framework, pageName, errorProps, error);
4188
- if (frameworkResponse)
4189
- return frameworkResponse;
4190
- if (framework !== "html") {
4191
- const htmlResponse = await tryFrameworkErrorConvention("html", pageName, errorProps, error);
4192
- if (htmlResponse)
4193
- return htmlResponse;
4194
- }
4195
- return null;
4196
- };
4197
- var renderReactNotFound = async (conventionPath) => {
4198
- const { createElement } = await import("react");
4199
- const { renderToReadableStream } = await import("react-dom/server");
4200
- const mod = await import(conventionPath);
4201
- const NotFoundComponent = mod.default;
4202
- if (typeof NotFoundComponent !== "function")
4203
- return null;
4204
- const element = createElement(NotFoundComponent);
4205
- const stream = await renderToReadableStream(element);
4206
- return new Response(stream, {
4207
- headers: { "Content-Type": "text/html" },
4208
- status: 404
4209
- });
4210
- };
4211
- var renderSvelteNotFound = async (conventionPath) => {
4212
- const { render } = await import("svelte/server");
4213
- const mod = await import(conventionPath);
4214
- const NotFoundComponent = mod.default;
4215
- if (!NotFoundComponent)
4216
- return null;
4217
- const { head, body } = render(NotFoundComponent);
4218
- const html = `<!DOCTYPE html><html><head>${head}</head><body>${body}</body></html>`;
4219
- return new Response(html, {
4220
- headers: { "Content-Type": "text/html" },
4221
- status: 404
4222
- });
4223
- };
4224
- var renderVueNotFound = async (conventionPath) => {
4225
- const { createSSRApp, h } = await import("vue");
4226
- const { renderToString } = await import("vue/server-renderer");
4227
- const mod = await import(conventionPath);
4228
- const NotFoundComponent = mod.default;
4229
- if (!NotFoundComponent)
4230
- return null;
4231
- const app = createSSRApp({
4232
- render: () => h(NotFoundComponent)
4233
- });
4234
- const rawBody = await renderToString(app);
4235
- const { styles, body } = unescapeVueStyles(rawBody);
4236
- const html = `<!DOCTYPE html><html><head>${styles}</head><body><div id="root">${body}</div></body></html>`;
4237
- return new Response(html, {
4238
- headers: { "Content-Type": "text/html" },
4239
- status: 404
4240
- });
4241
- };
4242
- var renderAngularNotFound = async (conventionPath) => {
4243
- const mod = await import(conventionPath);
4244
- const renderFn = mod.default;
4245
- if (typeof renderFn !== "function")
4246
- return null;
4247
- const html = renderFn();
4248
- return new Response(html, {
4249
- headers: { "Content-Type": "text/html" },
4250
- status: 404
4251
- });
4252
- };
4253
- var renderHtmlNotFound = async (conventionPath) => {
4254
- const html = await Bun.file(conventionPath).text();
4255
- return new Response(html, {
4256
- headers: { "Content-Type": "text/html" },
4257
- status: 404
4258
- });
4259
- };
4260
- var NOT_FOUND_RENDERERS = {
4261
- angular: renderAngularNotFound,
4262
- ember: renderEmberNotFound,
4263
- html: renderHtmlNotFound,
4264
- react: renderReactNotFound,
4265
- svelte: renderSvelteNotFound,
4266
- vue: renderVueNotFound
4267
- };
4268
- var renderConventionNotFound = async (framework) => {
4269
- const conventionPath = resolveNotFoundConventionPath(framework);
4270
- if (!conventionPath)
4271
- return null;
4272
- const renderer = NOT_FOUND_RENDERERS[framework];
4273
- if (!renderer)
4274
- return null;
4275
- try {
4276
- return await renderer(conventionPath);
4277
- } catch (renderError) {
4278
- logConventionRenderError(framework, "not-found", renderError);
4279
- }
4280
- return null;
4281
- };
4282
- var NOT_FOUND_PRIORITY = [
4283
- "react",
4284
- "svelte",
4285
- "vue",
4286
- "angular",
4287
- "html"
4288
- ];
4289
- var renderFirstNotFound = async () => {
4290
- const renderNext = async (frameworks) => {
4291
- const [framework, ...remaining] = frameworks;
4292
- if (!framework) {
4293
- return null;
4294
- }
4295
- if (!getMap()[framework]?.defaults?.notFound) {
4296
- return renderNext(remaining);
4297
- }
4298
- const response = await renderConventionNotFound(framework);
4299
- if (response) {
4300
- return response;
4301
- }
4302
- return renderNext(remaining);
4303
- };
4304
- return renderNext(NOT_FOUND_PRIORITY);
4305
- };
4306
4348
 
4307
4349
  // src/react/pageHandler.ts
4350
+ init_spaRouteManifest();
4351
+ init_resolveConvention();
4308
4352
  var resolveRequestPathname = (request) => {
4309
4353
  if (!request)
4310
4354
  return;
@@ -4331,6 +4375,9 @@ var handleReactPageRequest = async (input) => {
4331
4375
  } : userProps;
4332
4376
  const pageName = Page.name || Page.displayName || "";
4333
4377
  try {
4378
+ const spaNotFound = await renderSpaNotFound("react", pageName, input.request);
4379
+ if (spaNotFound)
4380
+ return withPageCacheHeaders(spaNotFound, input.request);
4334
4381
  const handlerCallsite = options?.collectStreamingSlots === true ? undefined : getCurrentRouteRegistrationCallsite() ?? captureStreamingSlotWarningCallsite();
4335
4382
  const renderPageResponse = async () => {
4336
4383
  const { createElement } = await import("react");
@@ -4536,5 +4583,5 @@ export {
4536
4583
  Island
4537
4584
  };
4538
4585
 
4539
- //# debugId=5D057DA7E1D729CF64756E2164756E21
4586
+ //# debugId=9C4F3F4F46157D7C64756E2164756E21
4540
4587
  //# sourceMappingURL=index.js.map