@absolutejs/absolute 0.19.0-beta.766 → 0.19.0-beta.768

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);
@@ -882,7 +887,13 @@ __export(exports_compile, {
882
887
  compile: () => compile
883
888
  });
884
889
  var {env: env3 } = globalThis.Bun;
885
- 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";
886
897
  import { basename as basename2, join as join6, relative, resolve as resolve8 } from "path";
887
898
  var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[cli]\x1B[0m ${color}${message}\x1B[0m`, compileBanner = (version2) => {
888
899
  const resolvedVersion = version2 || "unknown";
@@ -960,22 +971,39 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
960
971
  if (relativePath.includes("/server/"))
961
972
  return false;
962
973
  return true;
963
- }, generateEntrypoint = (distDir, serverEntry, prerenderMap, version2) => {
974
+ }, generateEntrypoint = (distDir, serverEntry, prerenderMap, version2, buildConfig) => {
964
975
  const allFiles = collectFiles2(distDir);
965
976
  const serverBundleName = `${basename2(serverEntry).replace(/\.[^.]+$/, "")}.js`;
966
- const skip = new Set([
977
+ const embeddedSkip = new Set([serverBundleName, "_compile_entrypoint.ts"]);
978
+ const assetSkip = new Set([
967
979
  serverBundleName,
968
980
  "manifest.json",
969
981
  "_compile_entrypoint.ts"
970
982
  ]);
971
- const clientFiles = allFiles.filter((file) => shouldEmbedCompiledAsset(relative(distDir, file), skip));
983
+ const embeddedFiles = allFiles.filter((file) => {
984
+ const rel = relative(distDir, file);
985
+ if (embeddedSkip.has(rel))
986
+ return false;
987
+ return true;
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,10 +1219,103 @@ 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
- }, stubPlugin, FRAMEWORK_EXTERNALS, compile = async (serverEntry, outdir, outfile, configPath2) => {
1225
+ }, createStubPlugin = (options = {}) => ({
1226
+ name: "stub-framework-sources",
1227
+ setup(bld) {
1228
+ const escapeRegex = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1229
+ const runtimeStubs = new Map;
1230
+ if (options.stubReact) {
1231
+ runtimeStubs.set("react", "export const createElement = () => null; export default { createElement };");
1232
+ runtimeStubs.set("react-dom/server", 'const unavailable = async () => { throw new Error("React runtime is unavailable in this compiled app."); }; export const renderToReadableStream = unavailable; export const renderToString = unavailable; export const renderToStaticMarkup = unavailable;');
1233
+ runtimeStubs.set("react-dom", "export const createPortal = () => null; export default { createPortal };");
1234
+ runtimeStubs.set("react/jsx-runtime", 'export const jsx = () => null; export const jsxs = () => null; export const Fragment = Symbol.for("react.fragment");');
1235
+ runtimeStubs.set("react/jsx-dev-runtime", 'export const jsxDEV = () => null; export const Fragment = Symbol.for("react.fragment");');
1236
+ }
1237
+ if (options.stubSvelte) {
1238
+ runtimeStubs.set("svelte/server", 'const unavailable = () => { throw new Error("Svelte runtime is unavailable in this compiled app."); }; export const render = unavailable;');
1239
+ runtimeStubs.set("svelte", "export default {};");
1240
+ }
1241
+ runtimeStubs.set("svelte/compiler", 'const unavailable = () => { throw new Error("Svelte source compiler is unavailable in compiled production runtime. Use built manifest page paths."); }; export const compile = unavailable; export const compileModule = unavailable; export const preprocess = unavailable;');
1242
+ if (options.stubVue) {
1243
+ runtimeStubs.set("vue", 'const unavailable = () => { throw new Error("Vue runtime is unavailable in this compiled app."); }; export const createSSRApp = unavailable; export const h = unavailable; export default {};');
1244
+ runtimeStubs.set("vue/server-renderer", 'const unavailable = async () => { throw new Error("Vue runtime is unavailable in this compiled app."); }; export const renderToString = unavailable;');
1245
+ }
1246
+ runtimeStubs.set("@vue/compiler-sfc", '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;');
1247
+ const runtimeStubFilter = new RegExp(`^(${Array.from(runtimeStubs.keys()).map(escapeRegex).join("|")})$`);
1248
+ bld.onResolve({ filter: runtimeStubFilter }, (args) => ({
1249
+ namespace: "absolute-compile-stub",
1250
+ path: args.path
1251
+ }));
1252
+ bld.onLoad({ filter: runtimeStubFilter, namespace: "absolute-compile-stub" }, (args) => ({
1253
+ contents: runtimeStubs.get(args.path) ?? "export {};",
1254
+ loader: "js"
1255
+ }));
1256
+ bld.onLoad({ filter: /\.(svelte|vue)$/ }, () => ({
1257
+ contents: "export default {}",
1258
+ loader: "js"
1259
+ }));
1260
+ bld.onLoad({ filter: /devBuild\.(ts|js)$/ }, () => ({
1261
+ contents: "export const devBuild = () => {}",
1262
+ loader: "js"
1263
+ }));
1264
+ bld.onLoad({ filter: /core\/build\.(ts|js)$/ }, () => ({
1265
+ contents: "export const build = () => ({})",
1266
+ loader: "js"
1267
+ }));
1268
+ bld.onLoad({ filter: /src\/build\.(ts|js)$/ }, () => ({
1269
+ contents: "export const build = () => ({}); export const devBuild = () => {};",
1270
+ loader: "js"
1271
+ }));
1272
+ bld.onLoad({ filter: /plugins\/hmr\.(ts|js)$/ }, () => ({
1273
+ contents: "export const hmr = () => (app) => app;",
1274
+ loader: "js"
1275
+ }));
1276
+ bld.onLoad({
1277
+ filter: /dev\/(assetStore|clientManager|webSocket|moduleVersionTracker|buildHMRClient)\.ts$/
1278
+ }, () => ({ contents: "export {};", loader: "js" }));
1279
+ bld.onLoad({ filter: /dev\/moduleServer\.(ts|js)$/ }, () => ({
1280
+ contents: "export {};",
1281
+ loader: "js"
1282
+ }));
1283
+ bld.onLoad({ filter: /build\/compile(Svelte|Vue|Angular)\.(ts|js)$/ }, () => ({
1284
+ 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;',
1285
+ loader: "js"
1286
+ }));
1287
+ bld.onLoad({ filter: /cli\/(telemetryEvent|scripts\/telemetry)\.ts$/ }, () => ({
1288
+ contents: "export const sendTelemetryEvent = () => {}; export const getTelemetryConfig = () => null; export const telemetry = () => {};",
1289
+ loader: "js"
1290
+ }));
1291
+ bld.onLoad({
1292
+ filter: /react-dom-server-legacy\.browser\.(production|development)\.js$/
1293
+ }, () => ({
1294
+ contents: "exports.renderToString = undefined; exports.renderToStaticMarkup = undefined;",
1295
+ loader: "js"
1296
+ }));
1297
+ bld.onResolve({ filter: /^react\/jsx-dev-runtime$/ }, () => ({
1298
+ path: jsxDevRuntimeCompatPath2
1299
+ }));
1300
+ bld.onLoad({ filter: /node_modules\/debug/ }, () => ({
1301
+ contents: "module.exports = () => { const noop = () => {}; noop.enabled = false; return noop; }; module.exports.enable = () => {}; module.exports.disable = () => {}; module.exports.enabled = () => false;",
1302
+ loader: "js"
1303
+ }));
1304
+ bld.onLoad({ filter: /\.ts$/ }, async (args) => {
1305
+ if (args.path.includes("node_modules"))
1306
+ return;
1307
+ const normalizedPath = args.path.replace(/\\/g, "/");
1308
+ if (normalizedPath.includes("/src/angular/"))
1309
+ return;
1310
+ const text = await Bun.file(args.path).text();
1311
+ const stripped = text.replace(/`(?:[^`\\]|\\.)*`/gs, "").replace(/'(?:[^'\\]|\\.)*'/g, "").replace(/"(?:[^"\\]|\\.)*"/g, "");
1312
+ if (stripped.includes("@Component")) {
1313
+ return { contents: "export default {}", loader: "js" };
1314
+ }
1315
+ return;
1316
+ });
1317
+ }
1318
+ }), FRAMEWORK_EXTERNALS, compile = async (serverEntry, outdir, outfile, configPath2) => {
1074
1319
  const prerenderPort = Number(env3.COMPILE_PORT) || Number(env3.PORT) || DEFAULT_PORT + 1;
1075
1320
  killStaleProcesses(prerenderPort);
1076
1321
  const entryName = basename2(serverEntry).replace(/\.[^.]+$/, "");
@@ -1108,7 +1353,7 @@ console.log(\`
1108
1353
  entrypoints: [resolve8(serverEntry)],
1109
1354
  external: FRAMEWORK_EXTERNALS,
1110
1355
  outdir: resolvedOutdir,
1111
- plugins: [stubPlugin],
1356
+ plugins: [createStubPlugin()],
1112
1357
  target: "bun"
1113
1358
  });
1114
1359
  if (!serverBundle.success) {
@@ -1124,6 +1369,10 @@ console.log(\`
1124
1369
  console.log(` \x1B[2m(${getDurationString(performance.now() - bundleStart)})\x1B[0m`);
1125
1370
  const prerenderStart = performance.now();
1126
1371
  process.stdout.write(cliTag4("\x1B[36m", "Pre-rendering pages"));
1372
+ rmSync2(join6(resolvedOutdir, "_prerendered"), {
1373
+ force: true,
1374
+ recursive: true
1375
+ });
1127
1376
  const staticConfig = buildConfig.static ?? { routes: "all" };
1128
1377
  const prerenderResult = await prerenderWithServer(outputPath, prerenderPort, resolvedOutdir, staticConfig, {
1129
1378
  ABSOLUTE_BUILD_DIR: resolvedOutdir,
@@ -1136,13 +1385,20 @@ console.log(\`
1136
1385
  console.log(` \x1B[2m(${prerenderMap.size} pages, ${getDurationString(performance.now() - prerenderStart)})\x1B[0m`);
1137
1386
  const compileStart = performance.now();
1138
1387
  process.stdout.write(cliTag4("\x1B[36m", "Compiling standalone executable"));
1139
- const entrypointCode = generateEntrypoint(resolvedOutdir, serverEntry, prerenderMap, absoluteVersion);
1388
+ const entrypointCode = generateEntrypoint(resolvedOutdir, serverEntry, prerenderMap, absoluteVersion, buildConfig);
1140
1389
  const entrypointPath = join6(resolvedOutdir, "_compile_entrypoint.ts");
1141
1390
  await Bun.write(entrypointPath, entrypointCode);
1142
1391
  const result = await Bun.build({
1143
1392
  compile: { outfile: resolvedOutfile },
1144
1393
  define: { "process.env.NODE_ENV": '"production"' },
1145
1394
  entrypoints: [entrypointPath],
1395
+ plugins: [
1396
+ createStubPlugin({
1397
+ stubReact: !buildConfig.reactDirectory,
1398
+ stubSvelte: !buildConfig.svelteDirectory,
1399
+ stubVue: !buildConfig.vueDirectory
1400
+ })
1401
+ ],
1146
1402
  target: "bun"
1147
1403
  });
1148
1404
  if (!result.success) {
@@ -1174,64 +1430,6 @@ var init_compile = __esm(() => {
1174
1430
  init_telemetryEvent();
1175
1431
  init_utils();
1176
1432
  jsxDevRuntimeCompatPath2 = resolveJsxDevRuntimeCompatPath2();
1177
- stubPlugin = {
1178
- name: "stub-framework-sources",
1179
- setup(bld) {
1180
- bld.onLoad({ filter: /\.(svelte|vue)$/ }, () => ({
1181
- contents: "export default {}",
1182
- loader: "js"
1183
- }));
1184
- bld.onLoad({ filter: /devBuild\.ts$/ }, () => ({
1185
- contents: "export const devBuild = () => {}",
1186
- loader: "js"
1187
- }));
1188
- bld.onLoad({ filter: /core\/build\.ts$/ }, () => ({
1189
- contents: "export const build = () => ({})",
1190
- loader: "js"
1191
- }));
1192
- bld.onLoad({ filter: /src\/build\.ts$/ }, () => ({
1193
- contents: "export const build = () => ({}); export const devBuild = () => {};",
1194
- loader: "js"
1195
- }));
1196
- bld.onLoad({ filter: /plugins\/hmr\.ts$/ }, () => ({
1197
- contents: "export const hmr = () => (app) => app;",
1198
- loader: "js"
1199
- }));
1200
- bld.onLoad({
1201
- filter: /dev\/(assetStore|clientManager|webSocket|moduleVersionTracker|buildHMRClient)\.ts$/
1202
- }, () => ({ contents: "export {};", loader: "js" }));
1203
- bld.onLoad({ filter: /cli\/(telemetryEvent|scripts\/telemetry)\.ts$/ }, () => ({
1204
- contents: "export const sendTelemetryEvent = () => {}; export const getTelemetryConfig = () => null; export const telemetry = () => {};",
1205
- loader: "js"
1206
- }));
1207
- bld.onLoad({
1208
- filter: /react-dom-server-legacy\.browser\.(production|development)\.js$/
1209
- }, () => ({
1210
- contents: "exports.renderToString = undefined; exports.renderToStaticMarkup = undefined;",
1211
- loader: "js"
1212
- }));
1213
- bld.onResolve({ filter: /^react\/jsx-dev-runtime$/ }, () => ({
1214
- path: jsxDevRuntimeCompatPath2
1215
- }));
1216
- bld.onLoad({ filter: /node_modules\/debug/ }, () => ({
1217
- contents: "module.exports = () => { const noop = () => {}; noop.enabled = false; return noop; }; module.exports.enable = () => {}; module.exports.disable = () => {}; module.exports.enabled = () => false;",
1218
- loader: "js"
1219
- }));
1220
- bld.onLoad({ filter: /\.ts$/ }, async (args) => {
1221
- if (args.path.includes("node_modules"))
1222
- return;
1223
- const normalizedPath = args.path.replace(/\\/g, "/");
1224
- if (normalizedPath.includes("/src/angular/"))
1225
- return;
1226
- const text = await Bun.file(args.path).text();
1227
- const stripped = text.replace(/`(?:[^`\\]|\\.)*`/gs, "").replace(/'(?:[^'\\]|\\.)*'/g, "").replace(/"(?:[^"\\]|\\.)*"/g, "");
1228
- if (stripped.includes("@Component")) {
1229
- return { contents: "export default {}", loader: "js" };
1230
- }
1231
- return;
1232
- });
1233
- }
1234
- };
1235
1433
  FRAMEWORK_EXTERNALS = [
1236
1434
  "react",
1237
1435
  "react/jsx-runtime",
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