@absolutejs/absolute 0.19.0-beta.765 → 0.19.0-beta.767

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/dist/cli/index.js CHANGED
@@ -714,6 +714,11 @@ var SERVER_OUTPUT_LIMIT = 4000, STARTUP_POLL_INTERVAL_MS = 100, DEFAULT_STARTUP_
714
714
  log?.(` Skipped ${route} (HTTP ${res.status})`);
715
715
  return;
716
716
  }
717
+ const contentType = res.headers.get("content-type") ?? "";
718
+ if (!contentType.includes("text/html")) {
719
+ log?.(` Skipped ${route} (non-HTML response)`);
720
+ return;
721
+ }
717
722
  const html = await res.text();
718
723
  const fileName = routeToFilename(route);
719
724
  const filePath = join5(prerenderDir, fileName);
@@ -878,10 +883,17 @@ var init_build = __esm(() => {
878
883
  // src/cli/scripts/compile.ts
879
884
  var exports_compile = {};
880
885
  __export(exports_compile, {
886
+ shouldEmbedCompiledAsset: () => shouldEmbedCompiledAsset,
881
887
  compile: () => compile
882
888
  });
883
889
  var {env: env3 } = globalThis.Bun;
884
- import { existsSync as existsSync9, readdirSync as readdirSync2, readFileSync as readFileSync9, unlinkSync as unlinkSync2 } from "fs";
890
+ import {
891
+ existsSync as existsSync9,
892
+ readdirSync as readdirSync2,
893
+ readFileSync as readFileSync9,
894
+ rmSync as rmSync2,
895
+ unlinkSync as unlinkSync2
896
+ } from "fs";
885
897
  import { basename as basename2, join as join6, relative, resolve as resolve8 } from "path";
886
898
  var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[cli]\x1B[0m ${color}${message}\x1B[0m`, compileBanner = (version2) => {
887
899
  const resolvedVersion = version2 || "unknown";
@@ -951,31 +963,47 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
951
963
  return candidate;
952
964
  }
953
965
  return resolve8(import.meta.dir, "..", "..", "react", "jsxDevRuntimeCompat.js");
954
- }, jsxDevRuntimeCompatPath2, generateEntrypoint = (distDir, serverEntry, prerenderMap, version2) => {
966
+ }, jsxDevRuntimeCompatPath2, shouldEmbedCompiledAsset = (relativePath, skip = new Set) => {
967
+ if (skip.has(relativePath))
968
+ return false;
969
+ if (relativePath.split(/[\\/]/).includes(".generated"))
970
+ return false;
971
+ if (relativePath.includes("/server/"))
972
+ return false;
973
+ return true;
974
+ }, generateEntrypoint = (distDir, serverEntry, prerenderMap, version2, buildConfig) => {
955
975
  const allFiles = collectFiles2(distDir);
956
976
  const serverBundleName = `${basename2(serverEntry).replace(/\.[^.]+$/, "")}.js`;
957
- const skip = new Set([
977
+ const embeddedSkip = new Set([serverBundleName, "_compile_entrypoint.ts"]);
978
+ const assetSkip = new Set([
958
979
  serverBundleName,
959
980
  "manifest.json",
960
981
  "_compile_entrypoint.ts"
961
982
  ]);
962
- const clientFiles = allFiles.filter((file) => {
983
+ const embeddedFiles = allFiles.filter((file) => {
963
984
  const rel = relative(distDir, file);
964
- if (skip.has(rel))
965
- return false;
966
- if (rel.includes(".generated"))
967
- return false;
968
- if (rel.includes("/server/"))
985
+ if (embeddedSkip.has(rel))
969
986
  return false;
970
987
  return true;
971
988
  });
989
+ const clientFiles = embeddedFiles.filter((file) => shouldEmbedCompiledAsset(relative(distDir, file), assetSkip));
972
990
  const imports = [];
991
+ const embeddedMappings = [];
973
992
  const mappings = [];
974
- clientFiles.forEach((filePath, idx) => {
993
+ const embeddedVarMap = new Map;
994
+ embeddedFiles.forEach((filePath, idx) => {
975
995
  const rel = relative(distDir, filePath).replace(/\\/g, "/");
976
996
  const varName = `__a${idx}`;
977
- const urlPath = `/${rel}`;
997
+ embeddedVarMap.set(rel, varName);
978
998
  imports.push(`import ${varName} from "./${rel}" with { type: "file" };`);
999
+ embeddedMappings.push(` ["${rel}", ${varName}],`);
1000
+ });
1001
+ clientFiles.forEach((filePath) => {
1002
+ const rel = relative(distDir, filePath).replace(/\\/g, "/");
1003
+ const varName = embeddedVarMap.get(rel);
1004
+ if (!varName)
1005
+ return;
1006
+ const urlPath = `/${rel}`;
979
1007
  mappings.push(` "${urlPath}": ${varName},`);
980
1008
  const workerParts = rel.startsWith("workers/") && rel.endsWith(".js") ? rel.match(/^(workers\/[^.]+\.worker)\.[a-z0-9]+\.js$/) : null;
981
1009
  if (workerParts) {
@@ -986,23 +1014,44 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
986
1014
  const prerenderEntries = Array.from(prerenderMap.entries());
987
1015
  prerenderEntries.forEach(([route, filePath]) => {
988
1016
  const rel = relative(distDir, filePath).replace(/\\/g, "/");
989
- const idx = clientFiles.findIndex((file) => relative(distDir, file).replace(/\\/g, "/") === rel);
990
- if (idx >= 0)
991
- pageVarMap.set(route, `__a${idx}`);
1017
+ const varName = embeddedVarMap.get(rel);
1018
+ if (varName)
1019
+ pageVarMap.set(route, varName);
992
1020
  });
993
1021
  const routeEntries = Array.from(pageVarMap.entries()).map(([route, varName]) => ` "${route}": ${varName},`).join(`
994
1022
  `);
1023
+ const runtimeBuildId = `${version2}-${Date.now().toString(36)}`;
1024
+ const runtimeConfigSource = JSON.stringify(buildConfig, (_key, value) => typeof value === "function" || typeof value === "symbol" ? undefined : value, 2);
995
1025
  return `// Auto-generated compile entrypoint
996
1026
  // \u2500\u2500 Embedded asset imports \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
997
1027
  ${imports.join(`
998
1028
  `)}
999
1029
 
1030
+ import { existsSync } from "node:fs";
1031
+ import { mkdir } from "node:fs/promises";
1032
+ import { dirname, join } from "node:path";
1033
+ import { tmpdir } from "node:os";
1034
+ import { createHash } from "node:crypto";
1035
+ import { readFileSync, writeFileSync } from "node:fs";
1036
+
1037
+ const SERVER_MODULE = () => import("./${serverBundleName}");
1038
+ const RUNTIME_BUILD_ID = ${JSON.stringify(runtimeBuildId)};
1039
+ const RUNTIME_CONFIG_SOURCE = ${JSON.stringify(runtimeConfigSource)};
1040
+ const ORIGINAL_BUILD_DIR = ${JSON.stringify(resolve8(distDir))};
1041
+ const ORIGINAL_BUILD_DIR_NORMALIZED = ORIGINAL_BUILD_DIR.replace(/\\\\/g, "/");
1042
+
1000
1043
  // \u2500\u2500 Asset URL \u2192 embedded path map \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
1001
1044
  const ASSETS: Record<string, string> = {
1002
1045
  ${mappings.join(`
1003
1046
  `)}
1004
1047
  };
1005
1048
 
1049
+ // \u2500\u2500 Embedded build files \u2192 source paths \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
1050
+ const EMBEDDED_FILES: Array<[string, string]> = [
1051
+ ${embeddedMappings.join(`
1052
+ `)}
1053
+ ];
1054
+
1006
1055
  // \u2500\u2500 Pre-rendered page routes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
1007
1056
  const PAGES: Record<string, string> = {
1008
1057
  ${routeEntries}
@@ -1036,13 +1085,113 @@ const servePage = (path: string) =>
1036
1085
  headers: { "content-type": "text/html; charset=utf-8" },
1037
1086
  });
1038
1087
 
1088
+ const resolvePage = (url: URL) => PAGES[url.pathname + url.search] ?? PAGES[url.pathname];
1089
+
1090
+ let runtimeFetchPromise: Promise<((request: Request) => Response | Promise<Response>) | null> | undefined;
1091
+
1092
+ const getRuntimeDir = () => {
1093
+ const hash = createHash("sha1")
1094
+ .update(import.meta.path)
1095
+ .update(RUNTIME_BUILD_ID)
1096
+ .digest("hex")
1097
+ .slice(0, 12);
1098
+
1099
+ return join(tmpdir(), "absolutejs-compiled-runtime-" + hash);
1100
+ };
1101
+
1102
+ const materializeRuntimeFiles = async () => {
1103
+ const runtimeDir = getRuntimeDir();
1104
+ const marker = join(runtimeDir, ".ready");
1105
+ const configPath = join(runtimeDir, "absolute.config.mjs");
1106
+
1107
+ if (existsSync(marker) && existsSync(configPath)) {
1108
+ return { configPath, runtimeDir };
1109
+ }
1110
+
1111
+ await mkdir(runtimeDir, { recursive: true });
1112
+ await Promise.all(
1113
+ EMBEDDED_FILES.map(async ([rel, source]) => {
1114
+ const target = join(runtimeDir, rel);
1115
+ await mkdir(dirname(target), { recursive: true });
1116
+ await Bun.write(target, Bun.file(source));
1117
+ })
1118
+ );
1119
+ writeFileSync(
1120
+ configPath,
1121
+ "export default " + RUNTIME_CONFIG_SOURCE + ";\\n"
1122
+ );
1123
+ rewriteRuntimeJsonPaths(runtimeDir, "manifest.json");
1124
+ rewriteRuntimeJsonPaths(runtimeDir, "conventions.json");
1125
+ writeFileSync(marker, String(Date.now()));
1126
+
1127
+ return { configPath, runtimeDir };
1128
+ };
1129
+
1130
+ const rewriteRuntimePath = (value: string, runtimeDir: string) => {
1131
+ const normalized = value.replace(/\\\\/g, "/");
1132
+ if (normalized === ORIGINAL_BUILD_DIR_NORMALIZED) return runtimeDir;
1133
+ if (!normalized.startsWith(ORIGINAL_BUILD_DIR_NORMALIZED + "/")) return value;
1134
+
1135
+ const rel = normalized.slice(ORIGINAL_BUILD_DIR_NORMALIZED.length + 1);
1136
+ return join(runtimeDir, ...rel.split("/"));
1137
+ };
1138
+
1139
+ const rewriteRuntimeJsonValue = (value: unknown, runtimeDir: string): unknown => {
1140
+ if (typeof value === "string") return rewriteRuntimePath(value, runtimeDir);
1141
+ if (Array.isArray(value))
1142
+ return value.map((item) => rewriteRuntimeJsonValue(item, runtimeDir));
1143
+ if (!value || typeof value !== "object") return value;
1144
+
1145
+ const next: Record<string, unknown> = {};
1146
+ for (const [key, child] of Object.entries(value)) {
1147
+ next[key] = rewriteRuntimeJsonValue(child, runtimeDir);
1148
+ }
1149
+
1150
+ return next;
1151
+ };
1152
+
1153
+ const rewriteRuntimeJsonPaths = (runtimeDir: string, fileName: string) => {
1154
+ const filePath = join(runtimeDir, fileName);
1155
+ if (!existsSync(filePath)) return;
1156
+
1157
+ const original = JSON.parse(readFileSync(filePath, "utf-8"));
1158
+ const rewritten = rewriteRuntimeJsonValue(original, runtimeDir);
1159
+ writeFileSync(filePath, JSON.stringify(rewritten, null, "\\t"));
1160
+ };
1161
+
1162
+ const resolveRuntimeFetch = async () => {
1163
+ const { configPath, runtimeDir } = await materializeRuntimeFiles();
1164
+ process.env.ABSOLUTE_BUILD_DIR = runtimeDir;
1165
+ process.env.ABSOLUTE_CONFIG = configPath;
1166
+ process.env.ABSOLUTE_COMPILED_RUNTIME = "1";
1167
+ process.env.ABSOLUTE_VERSION = process.env.ABSOLUTE_VERSION || "${version2}";
1168
+ process.env.NODE_ENV = "production";
1169
+
1170
+ const mod = await SERVER_MODULE();
1171
+ const runtimeServer = mod.server ?? mod.default ?? mod.app;
1172
+ const fetchHandler = runtimeServer?.fetch;
1173
+ if (typeof fetchHandler !== "function") return null;
1174
+
1175
+ return fetchHandler.bind(runtimeServer);
1176
+ };
1177
+
1178
+ const getRuntimeFetch = () => {
1179
+ runtimeFetchPromise ??= resolveRuntimeFetch().catch((error) => {
1180
+ console.error("[compile] Failed to load embedded runtime:", error);
1181
+
1182
+ return null;
1183
+ });
1184
+
1185
+ return runtimeFetchPromise;
1186
+ };
1187
+
1039
1188
  const server = Bun.serve({
1040
1189
  port,
1041
- fetch(request) {
1190
+ async fetch(request) {
1042
1191
  const url = new URL(request.url);
1043
1192
 
1044
1193
  // Check for pre-rendered page
1045
- const page = PAGES[url.pathname];
1194
+ const page = resolvePage(url);
1046
1195
  if (page) return servePage(page);
1047
1196
 
1048
1197
  // Check for embedded asset
@@ -1056,6 +1205,9 @@ const server = Bun.serve({
1056
1205
  });
1057
1206
  }
1058
1207
 
1208
+ const runtimeFetch = await getRuntimeFetch();
1209
+ if (runtimeFetch) return runtimeFetch(request);
1210
+
1059
1211
  return new Response("Not found", { status: 404 });
1060
1212
  },
1061
1213
  });
@@ -1067,7 +1219,7 @@ console.log(\`
1067
1219
 
1068
1220
  \\x1b[32m\u279C\\x1b[0m \\x1b[1mLocal:\\x1b[0m http://localhost:\${server.port}/
1069
1221
 
1070
- \\x1b[2m\${pageCount} pre-rendered pages, \${assetCount} embedded assets\\x1b[0m
1222
+ \\x1b[2m\${pageCount} pre-rendered pages, \${assetCount} embedded assets, runtime fallback\\x1b[0m
1071
1223
  \`);
1072
1224
  `;
1073
1225
  }, stubPlugin, FRAMEWORK_EXTERNALS, compile = async (serverEntry, outdir, outfile, configPath2) => {
@@ -1124,6 +1276,10 @@ console.log(\`
1124
1276
  console.log(` \x1B[2m(${getDurationString(performance.now() - bundleStart)})\x1B[0m`);
1125
1277
  const prerenderStart = performance.now();
1126
1278
  process.stdout.write(cliTag4("\x1B[36m", "Pre-rendering pages"));
1279
+ rmSync2(join6(resolvedOutdir, "_prerendered"), {
1280
+ force: true,
1281
+ recursive: true
1282
+ });
1127
1283
  const staticConfig = buildConfig.static ?? { routes: "all" };
1128
1284
  const prerenderResult = await prerenderWithServer(outputPath, prerenderPort, resolvedOutdir, staticConfig, {
1129
1285
  ABSOLUTE_BUILD_DIR: resolvedOutdir,
@@ -1136,13 +1292,14 @@ console.log(\`
1136
1292
  console.log(` \x1B[2m(${prerenderMap.size} pages, ${getDurationString(performance.now() - prerenderStart)})\x1B[0m`);
1137
1293
  const compileStart = performance.now();
1138
1294
  process.stdout.write(cliTag4("\x1B[36m", "Compiling standalone executable"));
1139
- const entrypointCode = generateEntrypoint(resolvedOutdir, serverEntry, prerenderMap, absoluteVersion);
1295
+ const entrypointCode = generateEntrypoint(resolvedOutdir, serverEntry, prerenderMap, absoluteVersion, buildConfig);
1140
1296
  const entrypointPath = join6(resolvedOutdir, "_compile_entrypoint.ts");
1141
1297
  await Bun.write(entrypointPath, entrypointCode);
1142
1298
  const result = await Bun.build({
1143
1299
  compile: { outfile: resolvedOutfile },
1144
1300
  define: { "process.env.NODE_ENV": '"production"' },
1145
1301
  entrypoints: [entrypointPath],
1302
+ plugins: [stubPlugin],
1146
1303
  target: "bun"
1147
1304
  });
1148
1305
  if (!result.success) {
@@ -1177,29 +1334,48 @@ var init_compile = __esm(() => {
1177
1334
  stubPlugin = {
1178
1335
  name: "stub-framework-sources",
1179
1336
  setup(bld) {
1337
+ bld.onResolve({ filter: /^@vue\/compiler-sfc$/ }, () => ({
1338
+ namespace: "absolute-compile-stub",
1339
+ path: "@vue/compiler-sfc"
1340
+ }));
1341
+ bld.onLoad({
1342
+ filter: /^@vue\/compiler-sfc$/,
1343
+ namespace: "absolute-compile-stub"
1344
+ }, () => ({
1345
+ contents: 'const unavailable = () => { throw new Error("Vue source compiler is unavailable in compiled production runtime. Use built manifest page paths."); }; export const compileScript = unavailable; export const compileStyle = unavailable; export const compileTemplate = unavailable; export const parse = unavailable;',
1346
+ loader: "js"
1347
+ }));
1180
1348
  bld.onLoad({ filter: /\.(svelte|vue)$/ }, () => ({
1181
1349
  contents: "export default {}",
1182
1350
  loader: "js"
1183
1351
  }));
1184
- bld.onLoad({ filter: /devBuild\.ts$/ }, () => ({
1352
+ bld.onLoad({ filter: /devBuild\.(ts|js)$/ }, () => ({
1185
1353
  contents: "export const devBuild = () => {}",
1186
1354
  loader: "js"
1187
1355
  }));
1188
- bld.onLoad({ filter: /core\/build\.ts$/ }, () => ({
1356
+ bld.onLoad({ filter: /core\/build\.(ts|js)$/ }, () => ({
1189
1357
  contents: "export const build = () => ({})",
1190
1358
  loader: "js"
1191
1359
  }));
1192
- bld.onLoad({ filter: /src\/build\.ts$/ }, () => ({
1360
+ bld.onLoad({ filter: /src\/build\.(ts|js)$/ }, () => ({
1193
1361
  contents: "export const build = () => ({}); export const devBuild = () => {};",
1194
1362
  loader: "js"
1195
1363
  }));
1196
- bld.onLoad({ filter: /plugins\/hmr\.ts$/ }, () => ({
1364
+ bld.onLoad({ filter: /plugins\/hmr\.(ts|js)$/ }, () => ({
1197
1365
  contents: "export const hmr = () => (app) => app;",
1198
1366
  loader: "js"
1199
1367
  }));
1200
1368
  bld.onLoad({
1201
1369
  filter: /dev\/(assetStore|clientManager|webSocket|moduleVersionTracker|buildHMRClient)\.ts$/
1202
1370
  }, () => ({ contents: "export {};", loader: "js" }));
1371
+ bld.onLoad({ filter: /dev\/moduleServer\.(ts|js)$/ }, () => ({
1372
+ contents: "export {};",
1373
+ loader: "js"
1374
+ }));
1375
+ bld.onLoad({ filter: /build\/compile(Svelte|Vue|Angular)\.(ts|js)$/ }, () => ({
1376
+ contents: 'const unavailable = async () => { throw new Error("Framework source compiler fallback is unavailable in compiled production runtime. Use built manifest page paths."); }; export const compileSvelte = unavailable; export const compileVue = unavailable; export const compileAngularFileJIT = unavailable; export const compileAngularFile = unavailable; export const compileAngularFiles = unavailable; export const compileAngular = unavailable;',
1377
+ loader: "js"
1378
+ }));
1203
1379
  bld.onLoad({ filter: /cli\/(telemetryEvent|scripts\/telemetry)\.ts$/ }, () => ({
1204
1380
  contents: "export const sendTelemetryEvent = () => {}; export const getTelemetryConfig = () => null; export const telemetry = () => {};",
1205
1381
  loader: "js"
package/dist/index.js CHANGED
@@ -46081,12 +46081,57 @@ ${content.slice(firstUseIdx)}`;
46081
46081
  continue;
46082
46082
  islandAngularClientPathMap.set(resolve21(sourcePath), clientPath);
46083
46083
  }
46084
+ const reactConventionSources = collectConventionSourceFiles(conventionsMap.react);
46084
46085
  const svelteConventionSources = collectConventionSourceFiles(conventionsMap.svelte);
46085
46086
  const vueConventionSources = collectConventionSourceFiles(conventionsMap.vue);
46086
- if (svelteConventionSources.length > 0 || vueConventionSources.length > 0) {
46087
- const [svelteConvResult, vueConvResult] = await Promise.all([
46087
+ const angularConventionSources = collectConventionSourceFiles(conventionsMap.angular);
46088
+ let conventionOutputPaths = [];
46089
+ if (reactConventionSources.length > 0 || svelteConventionSources.length > 0 || vueConventionSources.length > 0 || angularConventionSources.length > 0) {
46090
+ const compileReactConventions = async () => {
46091
+ if (reactConventionSources.length === 0)
46092
+ return emptyStringArray;
46093
+ const destDir = join20(buildPath, "conventions", "react");
46094
+ rmSync2(destDir, { force: true, recursive: true });
46095
+ mkdirSync10(destDir, { recursive: true });
46096
+ const destPaths = [];
46097
+ for (let idx = 0;idx < reactConventionSources.length; idx++) {
46098
+ const source = reactConventionSources[idx];
46099
+ if (!source)
46100
+ continue;
46101
+ const result = await bunBuild7({
46102
+ entrypoints: [source],
46103
+ format: "esm",
46104
+ jsx: { development: false },
46105
+ minify: !isDev2,
46106
+ naming: `${idx}-[name].[ext]`,
46107
+ outdir: destDir,
46108
+ plugins: [stylePreprocessorPlugin2],
46109
+ root: dirname12(source),
46110
+ target: "bun",
46111
+ throw: false,
46112
+ tsconfig: "./tsconfig.json"
46113
+ });
46114
+ if (!result.success) {
46115
+ outputLogs(result.logs);
46116
+ throw new Error(`Failed to compile React convention: ${source}`);
46117
+ }
46118
+ const output = result.outputs.find((artifact) => artifact.path.endsWith(".js"));
46119
+ if (!output)
46120
+ throw new Error(`React convention did not emit JavaScript: ${source}`);
46121
+ destPaths.push(output.path);
46122
+ }
46123
+ return destPaths;
46124
+ };
46125
+ const [
46126
+ reactConvPaths,
46127
+ svelteConvResult,
46128
+ vueConvResult,
46129
+ angularConvResult
46130
+ ] = await Promise.all([
46131
+ tracePhase("compile/convention-react", compileReactConventions),
46088
46132
  svelteConventionSources.length > 0 && svelteDir ? tracePhase("compile/convention-svelte", () => Promise.resolve().then(() => (init_compileSvelte(), exports_compileSvelte)).then((mod) => mod.compileSvelte(svelteConventionSources, svelteDir, new Map, false, styleTransformConfig))) : { svelteServerPaths: emptyStringArray },
46089
- vueConventionSources.length > 0 && vueDir ? tracePhase("compile/convention-vue", () => Promise.resolve().then(() => (init_compileVue(), exports_compileVue)).then((mod) => mod.compileVue(vueConventionSources, vueDir, false, styleTransformConfig))) : { vueServerPaths: emptyStringArray }
46133
+ vueConventionSources.length > 0 && vueDir ? tracePhase("compile/convention-vue", () => Promise.resolve().then(() => (init_compileVue(), exports_compileVue)).then((mod) => mod.compileVue(vueConventionSources, vueDir, false, styleTransformConfig))) : { vueServerPaths: emptyStringArray },
46134
+ angularConventionSources.length > 0 && angularDir ? tracePhase("compile/convention-angular", () => Promise.resolve().then(() => (init_compileAngular(), exports_compileAngular)).then((mod) => mod.compileAngular(angularConventionSources, angularDir, hmr, styleTransformConfig))) : { serverPaths: emptyStringArray }
46090
46135
  ]);
46091
46136
  const copyConventionFiles = (framework, sources, compiledPaths) => {
46092
46137
  const destDir = join20(buildPath, "conventions", framework);
@@ -46101,8 +46146,17 @@ ${content.slice(firstUseIdx)}`;
46101
46146
  };
46102
46147
  const svelteDests = copyConventionFiles("svelte", svelteConventionSources, svelteConvResult.svelteServerPaths);
46103
46148
  const vueDests = copyConventionFiles("vue", vueConventionSources, vueConvResult.vueServerPaths);
46149
+ const angularDests = copyConventionFiles("angular", angularConventionSources, angularConvResult.serverPaths);
46150
+ conventionOutputPaths = [
46151
+ ...reactConvPaths,
46152
+ ...svelteDests,
46153
+ ...vueDests,
46154
+ ...angularDests
46155
+ ];
46156
+ updateConventionCompiledPaths(conventionsMap.react, reactConventionSources, reactConvPaths);
46104
46157
  updateConventionCompiledPaths(conventionsMap.svelte, svelteConventionSources, svelteDests);
46105
46158
  updateConventionCompiledPaths(conventionsMap.vue, vueConventionSources, vueDests);
46159
+ updateConventionCompiledPaths(conventionsMap.angular, angularConventionSources, angularDests);
46106
46160
  }
46107
46161
  const serverEntryPoints = [
46108
46162
  ...svelteServerPaths,
@@ -46511,7 +46565,8 @@ ${content.slice(firstUseIdx)}`;
46511
46565
  ...reactClientOutputs.map((a) => a.path),
46512
46566
  ...nonReactClientOutputs.map((a) => a.path),
46513
46567
  ...islandClientOutputs.map((a) => a.path),
46514
- ...cssOutputs.map((a) => a.path)
46568
+ ...cssOutputs.map((a) => a.path),
46569
+ ...conventionOutputPaths
46515
46570
  ]));
46516
46571
  }
46517
46572
  if (hmr) {
@@ -51011,6 +51066,11 @@ var SERVER_OUTPUT_LIMIT = 4000, STARTUP_POLL_INTERVAL_MS = 100, DEFAULT_STARTUP_
51011
51066
  log2?.(` Skipped ${route} (HTTP ${res.status})`);
51012
51067
  return;
51013
51068
  }
51069
+ const contentType = res.headers.get("content-type") ?? "";
51070
+ if (!contentType.includes("text/html")) {
51071
+ log2?.(` Skipped ${route} (non-HTML response)`);
51072
+ return;
51073
+ }
51014
51074
  const html = await res.text();
51015
51075
  const fileName = routeToFilename(route);
51016
51076
  const filePath = join24(prerenderDir, fileName);
@@ -51704,13 +51764,31 @@ var derivePageName = (pagePath) => {
51704
51764
  const name = dotIndex > 0 ? base.slice(0, dotIndex) : base;
51705
51765
  return toPascal(name);
51706
51766
  };
51767
+ var normalizeConventionPageName = (name) => toPascal(name).replace(/\d+$/, "");
51707
51768
  var resolveErrorConventionPath = (framework, pageName) => {
51708
51769
  const conventions2 = getMap()[framework];
51709
51770
  if (!conventions2)
51710
51771
  return;
51711
- return conventions2.pages?.[pageName]?.error ?? conventions2.defaults?.error;
51772
+ const exact = conventions2.pages?.[pageName]?.error;
51773
+ if (exact)
51774
+ return exact;
51775
+ const normalizedPageName = normalizeConventionPageName(pageName);
51776
+ for (const [candidate, page] of Object.entries(conventions2.pages ?? {})) {
51777
+ if (normalizeConventionPageName(candidate) === normalizedPageName) {
51778
+ return page.error ?? conventions2.defaults?.error;
51779
+ }
51780
+ }
51781
+ return conventions2.defaults?.error;
51712
51782
  };
51713
51783
  var resolveNotFoundConventionPath = (framework) => getMap()[framework]?.defaults?.notFound;
51784
+ var hasErrorConvention = (framework) => {
51785
+ const conventions2 = getMap()[framework];
51786
+ if (!conventions2)
51787
+ return false;
51788
+ if (conventions2.defaults?.error)
51789
+ return true;
51790
+ return Object.values(conventions2.pages ?? {}).some((page) => Boolean(page.error));
51791
+ };
51714
51792
  var setConventions = (map) => {
51715
51793
  Reflect.set(globalThis, CONVENTIONS_KEY, map);
51716
51794
  };
@@ -51796,7 +51874,17 @@ var ERROR_RENDERERS = {
51796
51874
  vue: renderVueError
51797
51875
  };
51798
51876
  var renderConventionError = async (framework, pageName, error) => {
51799
- const conventionPath = resolveErrorConventionPath(framework, pageName);
51877
+ let conventionPath = resolveErrorConventionPath(framework, pageName);
51878
+ if (!conventionPath && error instanceof Error && error.stack) {
51879
+ for (const match of error.stack.matchAll(/^\s*at\s+([A-Za-z_$][\w$]*)/gm)) {
51880
+ const candidate = match[1];
51881
+ if (!candidate)
51882
+ continue;
51883
+ conventionPath = resolveErrorConventionPath(framework, candidate);
51884
+ if (conventionPath)
51885
+ break;
51886
+ }
51887
+ }
51800
51888
  if (!conventionPath)
51801
51889
  return null;
51802
51890
  const errorProps = buildErrorProps(error);
@@ -52375,7 +52463,7 @@ var loadTls = () => {
52375
52463
  };
52376
52464
  var tls = loadTls();
52377
52465
  var protocol = tls ? "https" : "http";
52378
- var networking = (app) => app.listen({
52466
+ var networking = (app) => env4.ABSOLUTE_COMPILED_RUNTIME === "1" ? app : app.listen({
52379
52467
  hostname: host,
52380
52468
  port,
52381
52469
  ...tls ? {
@@ -58832,5 +58920,5 @@ export {
58832
58920
  ANGULAR_INIT_TIMEOUT_MS
58833
58921
  };
58834
58922
 
58835
- //# debugId=5BEDAE621CA2EF3664756E2164756E21
58923
+ //# debugId=14CA0A980231DD4B64756E2164756E21
58836
58924
  //# sourceMappingURL=index.js.map