veryfront 0.1.72 → 0.1.73

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.
Files changed (34) hide show
  1. package/esm/deno.js +1 -1
  2. package/esm/src/html/html-shell-generator.d.ts.map +1 -1
  3. package/esm/src/html/html-shell-generator.js +6 -0
  4. package/esm/src/rendering/orchestrator/pipeline.d.ts.map +1 -1
  5. package/esm/src/rendering/orchestrator/pipeline.js +116 -105
  6. package/esm/src/server/dev-server/error-overlay/error-formatter.d.ts +4 -0
  7. package/esm/src/server/dev-server/error-overlay/error-formatter.d.ts.map +1 -1
  8. package/esm/src/server/dev-server/error-overlay/error-formatter.js +15 -0
  9. package/esm/src/server/dev-server/error-overlay/html-template.d.ts +1 -1
  10. package/esm/src/server/dev-server/error-overlay/html-template.d.ts.map +1 -1
  11. package/esm/src/server/dev-server/error-overlay/html-template.js +131 -8
  12. package/esm/src/server/dev-server/error-overlay/index.d.ts +1 -1
  13. package/esm/src/server/dev-server/error-overlay/index.d.ts.map +1 -1
  14. package/esm/src/server/dev-server/error-overlay/index.js +1 -1
  15. package/esm/src/server/dev-server/error-overlay/overlay-renderer.d.ts +1 -1
  16. package/esm/src/server/dev-server/error-overlay/overlay-renderer.d.ts.map +1 -1
  17. package/esm/src/server/dev-server/error-overlay/overlay-renderer.js +2 -2
  18. package/esm/src/server/dev-server/request-handler.d.ts.map +1 -1
  19. package/esm/src/server/dev-server/request-handler.js +6 -2
  20. package/esm/src/server/services/rendering/ssr.service.d.ts.map +1 -1
  21. package/esm/src/server/services/rendering/ssr.service.js +9 -2
  22. package/esm/src/server/utils/error-html.d.ts.map +1 -1
  23. package/esm/src/server/utils/error-html.js +26 -6
  24. package/package.json +1 -1
  25. package/src/deno.js +1 -1
  26. package/src/src/html/html-shell-generator.ts +9 -0
  27. package/src/src/rendering/orchestrator/pipeline.ts +186 -172
  28. package/src/src/server/dev-server/error-overlay/error-formatter.ts +21 -0
  29. package/src/src/server/dev-server/error-overlay/html-template.ts +139 -8
  30. package/src/src/server/dev-server/error-overlay/index.ts +1 -0
  31. package/src/src/server/dev-server/error-overlay/overlay-renderer.ts +2 -1
  32. package/src/src/server/dev-server/request-handler.ts +6 -2
  33. package/src/src/server/services/rendering/ssr.service.ts +9 -2
  34. package/src/src/server/utils/error-html.ts +29 -6
package/esm/deno.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export default {
2
2
  "name": "veryfront",
3
- "version": "0.1.72",
3
+ "version": "0.1.73",
4
4
  "license": "Apache-2.0",
5
5
  "nodeModulesDir": "auto",
6
6
  "exclude": [
@@ -1 +1 @@
1
- {"version":3,"file":"html-shell-generator.d.ts","sourceRoot":"","sources":["../../../src/src/html/html-shell-generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAmBxE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AA+ExD,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,qBAAqB,EAC9B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,EAC1C,KAAK,CAAC,EAAE,cAAc,EACtB,kBAAkB,CAAC,EAAE,MAAM,GAC1B,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAWzC;AAsPD,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,qBAAqB,EAC9B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,EAC1C,KAAK,CAAC,EAAE,cAAc,GACrB,OAAO,CAAC,MAAM,CAAC,CAmBjB"}
1
+ {"version":3,"file":"html-shell-generator.d.ts","sourceRoot":"","sources":["../../../src/src/html/html-shell-generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAmBxE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AA+ExD,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,qBAAqB,EAC9B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,EAC1C,KAAK,CAAC,EAAE,cAAc,EACtB,kBAAkB,CAAC,EAAE,MAAM,GAC1B,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAWzC;AA+PD,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,qBAAqB,EAC9B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,EAC1C,KAAK,CAAC,EAAE,cAAc,GACrB,OAAO,CAAC,MAAM,CAAC,CAmBjB"}
@@ -134,6 +134,11 @@ async function generateHTMLShellPartsImpl(meta, options, params, props, contentF
134
134
  ? `<link rel="modulepreload" href="${jsxRuntimeUrl}">`
135
135
  : "";
136
136
  const nonceAttr = nonce ? ` nonce="${nonce}"` : "";
137
+ // Expose project slug for runtime error overlay "Fix in Veryfront" button
138
+ const overlaySlug = options.projectId || meta.slug;
139
+ const slugForOverlay = useDevScripts && overlaySlug
140
+ ? `<script${nonceAttr}>window.__VF_PROJECT_SLUG__=${JSON.stringify(overlaySlug).replace(/</g, "\\u003c")};</script>`
141
+ : "";
137
142
  const hydrationErrorSuppression = useDevScripts ? "" : `<script${nonceAttr}>
138
143
  (function(){
139
144
  var origError = console.error;
@@ -222,6 +227,7 @@ async function generateHTMLShellPartsImpl(meta, options, params, props, contentF
222
227
  ${linkTags}
223
228
  ${styleTags}
224
229
  ${modeStyles}
230
+ ${slugForOverlay}
225
231
  </head>
226
232
  <body${bodyClass ? ` class="${bodyClass}"` : ""} suppressHydrationWarning>
227
233
  <div ${rootAttributes}>`;
@@ -1 +1 @@
1
- {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../../../src/src/rendering/orchestrator/pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAgBH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAEtE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AA6ChF,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAE1D;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACxE,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrF;AAED,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,YAAY,CAAC;IAC3B,gBAAgB,EAAE,wBAAwB,CAAC;IAC3C,YAAY,EAAE,YAAY,CAAC;IAC3B,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,eAAe,EAAE,eAAe,CAAC;IACjC,OAAO,EAAE,cAAc,CAAC;IACxB,IAAI,EAAE,aAAa,GAAG,YAAY,CAAC;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,iBAAiB,CAAC,EAAE,OAAO,qBAAqB,EAAE,sBAAsB,CAAC;CAC1E;AAQD,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,kBAAkB,CAAqB;gBAEnC,MAAM,EAAE,oBAAoB;IAaxC;;;OAGG;IACH,gBAAgB,IAAI,IAAI;IAKxB,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,sBAAsB;YAIhB,0BAA0B;IAaxC;;;;;;;;;OASG;YACW,qBAAqB;IAyDnC;;;OAGG;YACW,mBAAmB;IAqH3B,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IAgP9E,+EAA+E;IACzE,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA6LvF;;;;;;OAMG;IACH,OAAO,CAAC,aAAa;CAetB"}
1
+ {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../../../src/src/rendering/orchestrator/pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAgBH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAEtE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AA6ChF,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAE1D;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACxE,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrF;AAED,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,YAAY,CAAC;IAC3B,gBAAgB,EAAE,wBAAwB,CAAC;IAC3C,YAAY,EAAE,YAAY,CAAC;IAC3B,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,eAAe,EAAE,eAAe,CAAC;IACjC,OAAO,EAAE,cAAc,CAAC;IACxB,IAAI,EAAE,aAAa,GAAG,YAAY,CAAC;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,iBAAiB,CAAC,EAAE,OAAO,qBAAqB,EAAE,sBAAsB,CAAC;CAC1E;AAQD,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,kBAAkB,CAAqB;gBAEnC,MAAM,EAAE,oBAAoB;IAaxC;;;OAGG;IACH,gBAAgB,IAAI,IAAI;IAKxB,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,sBAAsB;YAIhB,0BAA0B;IAaxC;;;;;;;;;OASG;YACW,qBAAqB;IAyDnC;;;OAGG;YACW,mBAAmB;IAqH3B,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IA8P9E,+EAA+E;IACzE,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA6LvF;;;;;;OAMG;IACH,OAAO,CAAC,aAAa;CAetB"}
@@ -247,119 +247,130 @@ export class RenderPipeline {
247
247
  const pageResolveStart = performance.now();
248
248
  const pageInfo = await withSpan("render.resolve_page", () => this.config.pageResolver.resolvePage(slug), { "render.slug": slug });
249
249
  timing.pageResolve = Math.round(performance.now() - pageResolveStart);
250
- const skipLayouts = isDotPath(slug, pageInfo.entity.path);
251
- const layoutCollectStart = performance.now();
252
- const layoutResult = skipLayouts ? EMPTY_LAYOUT_RESULT : await withSpan("render.collect_layouts", () => this.config.layoutOrchestrator.collectLayouts(pageInfo), { "render.slug": slug });
253
- timing.layoutCollect = Math.round(performance.now() - layoutCollectStart);
254
- const layoutPreloadPromise = !skipLayouts && layoutResult.nestedLayouts.length > 0
255
- ? this.config.layoutOrchestrator.preloadLayoutModules(layoutResult.nestedLayouts)
256
- : Promise.resolve();
257
- let dataFetchingProps;
258
- let resolvedParams = options?.params
259
- ? { ...options.params }
260
- : {};
261
- let layoutDataMap = new Map();
262
- const dataFetchStart = performance.now();
263
- if (options?.request && options?.url) {
264
- await withSpan("render.data_fetching", async () => {
265
- try {
266
- const dataResolution = await this.resolveDataFetching(slug, pageInfo.entity.path, layoutResult.nestedLayouts, options);
267
- resolvedParams = dataResolution.params;
268
- dataFetchingProps = Object.keys(dataResolution.pageProps).length > 0
269
- ? dataResolution.pageProps
270
- : undefined;
271
- layoutDataMap = dataResolution.layoutProps;
272
- }
273
- catch (error) {
274
- if (error instanceof VeryfrontError)
250
+ const sourceFile = extractRelativePathShared(pageInfo.entity.path, this.config.projectDir);
251
+ try {
252
+ const skipLayouts = isDotPath(slug, pageInfo.entity.path);
253
+ const layoutCollectStart = performance.now();
254
+ const layoutResult = skipLayouts ? EMPTY_LAYOUT_RESULT : await withSpan("render.collect_layouts", () => this.config.layoutOrchestrator.collectLayouts(pageInfo), { "render.slug": slug });
255
+ timing.layoutCollect = Math.round(performance.now() - layoutCollectStart);
256
+ const layoutPreloadPromise = !skipLayouts && layoutResult.nestedLayouts.length > 0
257
+ ? this.config.layoutOrchestrator.preloadLayoutModules(layoutResult.nestedLayouts)
258
+ : Promise.resolve();
259
+ let dataFetchingProps;
260
+ let resolvedParams = options?.params
261
+ ? { ...options.params }
262
+ : {};
263
+ let layoutDataMap = new Map();
264
+ const dataFetchStart = performance.now();
265
+ if (options?.request && options?.url) {
266
+ await withSpan("render.data_fetching", async () => {
267
+ try {
268
+ const dataResolution = await this.resolveDataFetching(slug, pageInfo.entity.path, layoutResult.nestedLayouts, options);
269
+ resolvedParams = dataResolution.params;
270
+ dataFetchingProps = Object.keys(dataResolution.pageProps).length > 0
271
+ ? dataResolution.pageProps
272
+ : undefined;
273
+ layoutDataMap = dataResolution.layoutProps;
274
+ }
275
+ catch (error) {
276
+ if (error instanceof VeryfrontError)
277
+ throw error;
278
+ renderPageLog.error("Data fetching error", {
279
+ slug,
280
+ error: error instanceof Error ? error.message : String(error),
281
+ });
275
282
  throw error;
276
- renderPageLog.error("Data fetching error", {
277
- slug,
278
- error: error instanceof Error ? error.message : String(error),
279
- });
280
- throw error;
283
+ }
284
+ }, { "render.slug": slug });
285
+ }
286
+ timing.dataFetch = Math.round(performance.now() - dataFetchStart);
287
+ const hasResolvedParams = Object.keys(resolvedParams).length > 0;
288
+ const mergedOptions = (dataFetchingProps || hasResolvedParams)
289
+ ? {
290
+ ...options,
291
+ ...(hasResolvedParams ? { params: resolvedParams } : {}),
292
+ ...(dataFetchingProps
293
+ ? { props: { ...options?.props, ...dataFetchingProps } }
294
+ : {}),
281
295
  }
282
- }, { "render.slug": slug });
283
- }
284
- timing.dataFetch = Math.round(performance.now() - dataFetchStart);
285
- const hasResolvedParams = Object.keys(resolvedParams).length > 0;
286
- const mergedOptions = (dataFetchingProps || hasResolvedParams)
287
- ? {
288
- ...options,
289
- ...(hasResolvedParams ? { params: resolvedParams } : {}),
290
- ...(dataFetchingProps ? { props: { ...options?.props, ...dataFetchingProps } } : {}),
296
+ : options;
297
+ const bundlePrepStart = performance.now();
298
+ const pageBundleResult = await withSpan("render.prepare_bundles", () => this.config.pageRenderer.preparePageBundles(pageInfo, slug, cacheResult?.cachedModule, mergedOptions), { "render.slug": slug });
299
+ timing.bundlePrep = Math.round(performance.now() - bundlePrepStart);
300
+ if (pageBundleResult.scriptResult)
301
+ return pageBundleResult.scriptResult;
302
+ if (!pageBundleResult.pageElement || !pageBundleResult.pageBundle) {
303
+ throw RENDER_ERROR.create({
304
+ detail: "Failed to prepare page bundle",
305
+ context: { slug },
306
+ });
291
307
  }
292
- : options;
293
- const bundlePrepStart = performance.now();
294
- const pageBundleResult = await withSpan("render.prepare_bundles", () => this.config.pageRenderer.preparePageBundles(pageInfo, slug, cacheResult?.cachedModule, mergedOptions), { "render.slug": slug });
295
- timing.bundlePrep = Math.round(performance.now() - bundlePrepStart);
296
- if (pageBundleResult.scriptResult)
297
- return pageBundleResult.scriptResult;
298
- if (!pageBundleResult.pageElement || !pageBundleResult.pageBundle) {
299
- throw RENDER_ERROR.create({
300
- detail: "Failed to prepare page bundle",
301
- context: { slug },
302
- });
303
- }
304
- const { pageElement, pageBundle } = pageBundleResult;
305
- const mergedFrontmatter = {
306
- ...pageInfo.entity.frontmatter,
307
- ...pageBundle.frontmatter,
308
- };
309
- const headings = pageBundle.headings || [];
310
- await layoutPreloadPromise;
311
- const layoutApplyStart = performance.now();
312
- const wrappedElement = await withSpan("render.apply_layouts", () => this.config.layoutOrchestrator.applyLayoutsAndWrappers(pageElement, pageInfo, layoutResult.layoutBundle, layoutResult.nestedLayouts, layoutDataMap, options?.url, mergedFrontmatter, headings, options?.projectSlug), { "render.slug": slug, "render.layout_count": layoutResult.nestedLayouts.length });
313
- timing.layoutApply = Math.round(performance.now() - layoutApplyStart);
314
- // Snapshot CSS imports collected during module loading (before SSR rendering).
315
- // These are passed to the HTML generator to be included in the output.
316
- const collectedCSSImports = getCSSImports();
317
- const ssrStart = performance.now();
318
- const ssrResult = await withSpan("render.ssr", () => withTimeoutThrow(this.config.ssrOrchestrator.performSSRRendering(wrappedElement, {
319
- pageInfo,
320
- pageBundle,
321
- layoutBundle: layoutResult.layoutBundle,
322
- nestedLayouts: layoutResult.nestedLayouts,
323
- collectedMetadata: pageBundleResult.collectedMetadata,
324
- slug,
325
- cssImports: collectedCSSImports,
326
- }, mergedOptions), SSR_RENDER_TIMEOUT_MS, `SSR rendering for ${slug}`), { "render.slug": slug, "render.delivery": mergedOptions?.delivery || "full" });
327
- timing.ssr = Math.round(performance.now() - ssrStart);
328
- if (collectedCSSImports.length > 0) {
329
- renderPipelineLog.debug("CSS imports collected for HTML generation", {
330
- slug,
331
- count: collectedCSSImports.length,
332
- paths: collectedCSSImports.map((p) => p.split("/").pop()),
333
- });
334
- }
335
- const pageModule = pageBundleResult.clientModuleCode && pageBundleResult.pageModuleType
336
- ? {
308
+ const { pageElement, pageBundle } = pageBundleResult;
309
+ const mergedFrontmatter = {
310
+ ...pageInfo.entity.frontmatter,
311
+ ...pageBundle.frontmatter,
312
+ };
313
+ const headings = pageBundle.headings || [];
314
+ await layoutPreloadPromise;
315
+ const layoutApplyStart = performance.now();
316
+ const wrappedElement = await withSpan("render.apply_layouts", () => this.config.layoutOrchestrator.applyLayoutsAndWrappers(pageElement, pageInfo, layoutResult.layoutBundle, layoutResult.nestedLayouts, layoutDataMap, options?.url, mergedFrontmatter, headings, options?.projectSlug), { "render.slug": slug, "render.layout_count": layoutResult.nestedLayouts.length });
317
+ timing.layoutApply = Math.round(performance.now() - layoutApplyStart);
318
+ // Snapshot CSS imports collected during module loading (before SSR rendering).
319
+ // These are passed to the HTML generator to be included in the output.
320
+ const collectedCSSImports = getCSSImports();
321
+ const ssrStart = performance.now();
322
+ const ssrResult = await withSpan("render.ssr", () => withTimeoutThrow(this.config.ssrOrchestrator.performSSRRendering(wrappedElement, {
323
+ pageInfo,
324
+ pageBundle,
325
+ layoutBundle: layoutResult.layoutBundle,
326
+ nestedLayouts: layoutResult.nestedLayouts,
327
+ collectedMetadata: pageBundleResult.collectedMetadata,
337
328
  slug,
338
- code: pageBundleResult.clientModuleCode,
339
- type: pageBundleResult.pageModuleType,
329
+ cssImports: collectedCSSImports,
330
+ }, mergedOptions), SSR_RENDER_TIMEOUT_MS, `SSR rendering for ${slug}`), { "render.slug": slug, "render.delivery": mergedOptions?.delivery || "full" });
331
+ timing.ssr = Math.round(performance.now() - ssrStart);
332
+ if (collectedCSSImports.length > 0) {
333
+ renderPipelineLog.debug("CSS imports collected for HTML generation", {
334
+ slug,
335
+ count: collectedCSSImports.length,
336
+ paths: collectedCSSImports.map((p) => p.split("/").pop()),
337
+ });
340
338
  }
341
- : undefined;
342
- const result = {
343
- html: ssrResult.fullHtml,
344
- frontmatter: pageBundleResult.pageBundle.frontmatter || {},
345
- headings: pageBundleResult.pageBundle.headings || [],
346
- nodeMap: pageBundleResult.pageBundle.nodeMap,
347
- stream: ssrResult.finalStream,
348
- ssrHash: ssrResult.ssrHash,
349
- ...(pageModule ? { pageModule } : {}),
350
- };
351
- if (shouldCache && !options?.skipCachePersist) {
352
- void this.config.cacheCoordinator.persistResult(result, slug, cacheKey).catch((error) => {
353
- renderPipelineLog.error("Cache persist failed", {
339
+ const pageModule = pageBundleResult.clientModuleCode && pageBundleResult.pageModuleType
340
+ ? {
354
341
  slug,
355
- error: error instanceof Error ? error.message : String(error),
356
- stack: error instanceof Error ? error.stack : undefined,
342
+ code: pageBundleResult.clientModuleCode,
343
+ type: pageBundleResult.pageModuleType,
344
+ }
345
+ : undefined;
346
+ const result = {
347
+ html: ssrResult.fullHtml,
348
+ frontmatter: pageBundleResult.pageBundle.frontmatter || {},
349
+ headings: pageBundleResult.pageBundle.headings || [],
350
+ nodeMap: pageBundleResult.pageBundle.nodeMap,
351
+ stream: ssrResult.finalStream,
352
+ ssrHash: ssrResult.ssrHash,
353
+ ...(pageModule ? { pageModule } : {}),
354
+ };
355
+ if (shouldCache && !options?.skipCachePersist) {
356
+ void this.config.cacheCoordinator.persistResult(result, slug, cacheKey).catch((error) => {
357
+ renderPipelineLog.error("Cache persist failed", {
358
+ slug,
359
+ error: error instanceof Error ? error.message : String(error),
360
+ stack: error instanceof Error ? error.stack : undefined,
361
+ });
357
362
  });
358
- });
363
+ }
364
+ timing.total = Math.round(performance.now() - pipelineStartTime);
365
+ renderPipelineLog.debug("Complete", { slug, timing });
366
+ return result;
367
+ }
368
+ catch (error) {
369
+ if (error instanceof Error) {
370
+ error.sourceFile = sourceFile;
371
+ }
372
+ throw error;
359
373
  }
360
- timing.total = Math.round(performance.now() - pipelineStartTime);
361
- renderPipelineLog.debug("Complete", { slug, timing });
362
- return result;
363
374
  });
364
375
  return result;
365
376
  }, {
@@ -8,5 +8,9 @@ export interface ErrorInfo {
8
8
  suggestion?: string;
9
9
  }
10
10
  export declare function getSuggestion(error: Error): string | undefined;
11
+ export declare function parseErrorLocation(error: Error, file: string): {
12
+ line?: number;
13
+ column?: number;
14
+ };
11
15
  export declare function formatErrorType(type: ErrorType): string;
12
16
  //# sourceMappingURL=error-formatter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"error-formatter.d.ts","sourceRoot":"","sources":["../../../../../src/src/server/dev-server/error-overlay/error-formatter.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,WAAW,CAAC;AAE1D,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,KAAK,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAkCD,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,GAAG,SAAS,CAU9D;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAKvD"}
1
+ {"version":3,"file":"error-formatter.d.ts","sourceRoot":"","sources":["../../../../../src/src/server/dev-server/error-overlay/error-formatter.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,WAAW,CAAC;AAE1D,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,KAAK,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAkCD,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,GAAG,SAAS,CAU9D;AAED,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,MAAM,GACX;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAgBpC;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAKvD"}
@@ -33,6 +33,21 @@ export function getSuggestion(error) {
33
33
  }
34
34
  return undefined;
35
35
  }
36
+ export function parseErrorLocation(error, file) {
37
+ if (!error.stack || !file)
38
+ return {};
39
+ const lines = error.stack.split("\n");
40
+ // First try to match the known source file
41
+ for (const stackLine of lines) {
42
+ if (!stackLine.includes(file))
43
+ continue;
44
+ const match = stackLine.match(/:(\d+):(\d+)\)?$/);
45
+ if (match) {
46
+ return { line: Number(match[1]), column: Number(match[2]) };
47
+ }
48
+ }
49
+ return {};
50
+ }
36
51
  export function formatErrorType(type) {
37
52
  const firstChar = type[0];
38
53
  if (!firstChar)
@@ -1,4 +1,4 @@
1
1
  import { type ErrorInfo } from "./error-formatter.js";
2
2
  export declare function generateRuntimeScript(): string;
3
- export declare function generateErrorHTML(errorInfo: ErrorInfo, suggestion?: string): string;
3
+ export declare function generateErrorHTML(errorInfo: ErrorInfo, suggestion?: string, projectSlug?: string): string;
4
4
  //# sourceMappingURL=html-template.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"html-template.d.ts","sourceRoot":"","sources":["../../../../../src/src/server/dev-server/error-overlay/html-template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAmB,MAAM,sBAAsB,CAAC;AAYvE,wBAAgB,qBAAqB,IAAI,MAAM,CAsI9C;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,SAAS,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAsKnF"}
1
+ {"version":3,"file":"html-template.d.ts","sourceRoot":"","sources":["../../../../../src/src/server/dev-server/error-overlay/html-template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAmB,MAAM,sBAAsB,CAAC;AAmBvE,wBAAgB,qBAAqB,IAAI,MAAM,CA6L9C;AAED,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,SAAS,EACpB,UAAU,CAAC,EAAE,MAAM,EACnB,WAAW,CAAC,EAAE,MAAM,GACnB,MAAM,CAuOR"}
@@ -6,6 +6,12 @@ const WS_RECONNECT_BASE_DELAY_MS = 1_000;
6
6
  const WS_RECONNECT_MAX_DELAY_MS = 5_000;
7
7
  /** Maximum number of WebSocket reconnection attempts before giving up */
8
8
  const WS_MAX_RECONNECT_ATTEMPTS = 10;
9
+ /** JSON.stringify that escapes `<` to prevent `</script>` breaking inline scripts */
10
+ function jsonForScript(value) {
11
+ const json = JSON.stringify(value);
12
+ // JSON.stringify(undefined) returns undefined (not a string)
13
+ return json === undefined ? "undefined" : json.replace(/</g, "\\u003c");
14
+ }
9
15
  export function generateRuntimeScript() {
10
16
  return `
11
17
  // Veryfront Error Overlay Runtime
@@ -106,21 +112,76 @@ export function generateRuntimeScript() {
106
112
  </div>
107
113
 
108
114
  <button type="button" onclick="document.getElementById('veryfront-error-overlay').remove()" style="
109
- background: #333;
110
- border: 1px solid #555;
111
- color: #ccc;
112
- padding: 8px 16px;
113
- border-radius: 4px;
115
+ background: #fff;
116
+ border: none;
117
+ color: #000;
118
+ padding: 10px 20px;
119
+ border-radius: 9999px;
114
120
  cursor: pointer;
115
121
  font-family: inherit;
116
122
  ">
117
123
  Dismiss
118
124
  </button>
125
+ \${window.__VF_PROJECT_SLUG__ ? \`
126
+ <button type="button" id="vf-fix-btn-runtime" style="
127
+ background: transparent;
128
+ border: 1px solid rgba(255, 255, 255, 0.2);
129
+ color: rgba(255, 255, 255, 0.7);
130
+ padding: 10px 20px;
131
+ border-radius: 9999px;
132
+ cursor: pointer;
133
+ font-family: inherit;
134
+ margin-left: 8px;
135
+ ">
136
+ Fix in Veryfront
137
+ </button>
138
+ \` : ''}
119
139
  </div>
120
140
  </div>
121
141
  \`;
122
142
 
123
143
  document.body.appendChild(overlay);
144
+
145
+ // Notify Studio of runtime error
146
+ if (window.parent !== window) {
147
+ try {
148
+ window.parent.postMessage({
149
+ action: 'runtimeError',
150
+ url: window.location.href,
151
+ hasError: true,
152
+ errors: [{
153
+ type: 'error',
154
+ message: (errorInfo.error && errorInfo.error.message) || 'Unknown error',
155
+ file: errorInfo.file ? String(errorInfo.file) : undefined,
156
+ line: errorInfo.line ? Number(errorInfo.line) : undefined,
157
+ column: errorInfo.column ? Number(errorInfo.column) : undefined
158
+ }]
159
+ }, '*');
160
+ } catch (e) { /* postMessage may fail */ }
161
+ }
162
+
163
+ if (window.__VF_PROJECT_SLUG__) {
164
+ var fixBtn = document.getElementById('vf-fix-btn-runtime');
165
+ if (fixBtn) {
166
+ fixBtn.addEventListener('click', function() {
167
+ var rawName = (errorInfo.error && errorInfo.error.name) || 'Error';
168
+ var rawMessage = (errorInfo.error && errorInfo.error.message) || 'Unknown error';
169
+ var rawFile = errorInfo.file ? String(errorInfo.file) : null;
170
+ var rawLine = errorInfo.line ? String(errorInfo.line) : null;
171
+ var rawColumn = errorInfo.column ? String(errorInfo.column) : null;
172
+ var loc = rawFile ? rawFile + (rawLine ? ':' + rawLine : '') + (rawColumn ? ':' + rawColumn : '') : null;
173
+ var bt = String.fromCharCode(96);
174
+ var prompt = 'Find and fix the following error' +
175
+ (loc ? ' in ' + bt + loc + bt : '') +
176
+ '\\n\\n' + bt + rawMessage + bt;
177
+ if (window.parent !== window) {
178
+ window.parent.postMessage({ action: 'chatMessage', prompt: prompt }, '*');
179
+ } else {
180
+ window.open('https://veryfront.com/projects/' + window.__VF_PROJECT_SLUG__ + '?prompt=' + encodeURIComponent(prompt));
181
+ }
182
+ });
183
+ }
184
+ }
124
185
  };
125
186
 
126
187
  window.addEventListener('error', (event) => {
@@ -141,7 +202,7 @@ export function generateRuntimeScript() {
141
202
  });
142
203
  `;
143
204
  }
144
- export function generateErrorHTML(errorInfo, suggestion) {
205
+ export function generateErrorHTML(errorInfo, suggestion, projectSlug) {
145
206
  const errorType = escapeHtml(formatErrorType(errorInfo.type));
146
207
  const errorName = escapeHtml(errorInfo.error.name);
147
208
  const errorMessage = escapeHtml(errorInfo.error.message);
@@ -173,6 +234,9 @@ export function generateErrorHTML(errorInfo, suggestion) {
173
234
  </details>
174
235
  `
175
236
  : "";
237
+ const fixButtonHtml = projectSlug
238
+ ? `<button type="button" id="vf-fix-btn" class="btn btn-fix">Fix in Veryfront</button>`
239
+ : "";
176
240
  return `
177
241
  <!DOCTYPE html>
178
242
  <html>
@@ -244,6 +308,32 @@ export function generateErrorHTML(errorInfo, suggestion) {
244
308
  overflow-x: auto;
245
309
  font-size: 12px;
246
310
  }
311
+ .btn {
312
+ padding: 10px 20px;
313
+ border-radius: 9999px;
314
+ cursor: pointer;
315
+ font-family: inherit;
316
+ font-size: 14px;
317
+ border: none;
318
+ }
319
+ .btn-dismiss {
320
+ background: #fff;
321
+ color: #000;
322
+ }
323
+ .btn-dismiss:hover {
324
+ background: #e5e5e5;
325
+ }
326
+ .btn-fix {
327
+ background: transparent;
328
+ color: rgba(255, 255, 255, 0.7);
329
+ border: 1px solid rgba(255, 255, 255, 0.2);
330
+ margin-left: 8px;
331
+ }
332
+ .btn-fix:hover {
333
+ background: rgba(255, 255, 255, 0.1);
334
+ color: #fff;
335
+ border-color: rgba(255, 255, 255, 0.4);
336
+ }
247
337
  </style>
248
338
  </head>
249
339
  <body>
@@ -258,8 +348,34 @@ export function generateErrorHTML(errorInfo, suggestion) {
258
348
  ${suggestionSection}
259
349
  ${stackSection}
260
350
  </div>
351
+ ${fixButtonHtml}
261
352
  </div>
262
- <script>
353
+ <script>${projectSlug
354
+ ? `
355
+ (function() {
356
+ var slug = ${jsonForScript(projectSlug)};
357
+ var errorName = ${jsonForScript(errorInfo.error.name)};
358
+ var errorMessage = ${jsonForScript(errorInfo.error.message)};
359
+ var errorFile = ${jsonForScript(errorInfo.file ?? null)};
360
+ var errorLine = ${jsonForScript(errorInfo.line ?? null)};
361
+ var errorColumn = ${jsonForScript(errorInfo.column ?? null)};
362
+ var btn = document.getElementById('vf-fix-btn');
363
+ if (btn) {
364
+ btn.addEventListener('click', function() {
365
+ var loc = errorFile ? errorFile + (errorLine ? ':' + errorLine : '') + (errorColumn ? ':' + errorColumn : '') : null;
366
+ var bt = String.fromCharCode(96);
367
+ var prompt = 'Find and fix the following error' +
368
+ (loc ? ' in ' + bt + loc + bt : '') +
369
+ '\\n\\n' + bt + errorMessage + bt;
370
+ if (window.parent !== window) {
371
+ window.parent.postMessage({ action: 'chatMessage', prompt: prompt }, '*');
372
+ } else {
373
+ window.open('https://veryfront.com/projects/' + slug + '?prompt=' + encodeURIComponent(prompt));
374
+ }
375
+ });
376
+ }
377
+ })();`
378
+ : ""}
263
379
  // Notify Studio (parent) that page has loaded with an error
264
380
  // This hides the loading spinner in Studio's preview iframe
265
381
  if (window.parent !== window) {
@@ -268,7 +384,14 @@ export function generateErrorHTML(errorInfo, suggestion) {
268
384
  action: 'appUpdated',
269
385
  isInitialLoad: true,
270
386
  hasError: true,
271
- url: window.location.href
387
+ url: window.location.href,
388
+ errors: [{
389
+ type: 'error',
390
+ message: ${jsonForScript(errorInfo.error.message)},
391
+ file: ${jsonForScript(errorInfo.file || undefined)},
392
+ line: ${errorInfo.line ? String(errorInfo.line) : "undefined"},
393
+ column: ${errorInfo.column ? String(errorInfo.column) : "undefined"}
394
+ }]
272
395
  }, '*');
273
396
  } catch (e) { /* postMessage may fail in cross-origin iframes */ }
274
397
  }
@@ -4,7 +4,7 @@
4
4
  * @module server/dev-server/error-overlay
5
5
  */
6
6
  export { ErrorOverlay } from "./overlay-renderer.js";
7
- export { type ErrorInfo, type ErrorType, formatErrorType, getSuggestion, } from "./error-formatter.js";
7
+ export { type ErrorInfo, type ErrorType, formatErrorType, getSuggestion, parseErrorLocation, } from "./error-formatter.js";
8
8
  export { generateErrorHTML, generateRuntimeScript } from "./html-template.js";
9
9
  export { formatStackTrace, hasStackTrace, type ParsedStackFrame, parseStackTrace, } from "./stack-parser.js";
10
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/src/server/dev-server/error-overlay/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EACL,KAAK,SAAS,EACd,KAAK,SAAS,EACd,eAAe,EACf,aAAa,GACd,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,KAAK,gBAAgB,EACrB,eAAe,GAChB,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/src/server/dev-server/error-overlay/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EACL,KAAK,SAAS,EACd,KAAK,SAAS,EACd,eAAe,EACf,aAAa,EACb,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,KAAK,gBAAgB,EACrB,eAAe,GAChB,MAAM,mBAAmB,CAAC"}
@@ -4,6 +4,6 @@
4
4
  * @module server/dev-server/error-overlay
5
5
  */
6
6
  export { ErrorOverlay } from "./overlay-renderer.js";
7
- export { formatErrorType, getSuggestion, } from "./error-formatter.js";
7
+ export { formatErrorType, getSuggestion, parseErrorLocation, } from "./error-formatter.js";
8
8
  export { generateErrorHTML, generateRuntimeScript } from "./html-template.js";
9
9
  export { formatStackTrace, hasStackTrace, parseStackTrace, } from "./stack-parser.js";
@@ -3,6 +3,6 @@ import { generateRuntimeScript } from "./html-template.js";
3
3
  export declare const ErrorOverlay: {
4
4
  getRuntime: typeof generateRuntimeScript;
5
5
  getSuggestion: typeof getSuggestion;
6
- createHTML(errorInfo: ErrorInfo): string;
6
+ createHTML(errorInfo: ErrorInfo, projectSlug?: string): string;
7
7
  };
8
8
  //# sourceMappingURL=overlay-renderer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"overlay-renderer.d.ts","sourceRoot":"","sources":["../../../../../src/src/server/dev-server/error-overlay/overlay-renderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAqB,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAE9E,eAAO,MAAM,YAAY;;;0BAGD,SAAS,GAAG,MAAM;CAMzC,CAAC"}
1
+ {"version":3,"file":"overlay-renderer.d.ts","sourceRoot":"","sources":["../../../../../src/src/server/dev-server/error-overlay/overlay-renderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAqB,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAE9E,eAAO,MAAM,YAAY;;;0BAGD,SAAS,gBAAgB,MAAM,GAAG,MAAM;CAO/D,CAAC"}
@@ -3,7 +3,7 @@ import { generateErrorHTML, generateRuntimeScript } from "./html-template.js";
3
3
  export const ErrorOverlay = {
4
4
  getRuntime: generateRuntimeScript,
5
5
  getSuggestion,
6
- createHTML(errorInfo) {
7
- return generateErrorHTML(errorInfo, errorInfo.suggestion ?? getSuggestion(errorInfo.error));
6
+ createHTML(errorInfo, projectSlug) {
7
+ return generateErrorHTML(errorInfo, errorInfo.suggestion ?? getSuggestion(errorInfo.error), projectSlug);
8
8
  },
9
9
  };
@@ -1 +1 @@
1
- {"version":3,"file":"request-handler.d.ts","sourceRoot":"","sources":["../../../../src/src/server/dev-server/request-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,wBAAwB,CAAC;AASlD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAY7D,qBAAa,cAAc;IAIvB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,MAAM,CAAC;IACf,OAAO,CAAC,kBAAkB,CAAC;IAC3B,OAAO,CAAC,gBAAgB,CAAC;IACzB,OAAO,CAAC,aAAa,CAAC;IAVxB,OAAO,CAAC,cAAc,CAAC,CAAsD;gBAGnE,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,MAAM,OAAO,EACtB,OAAO,EAAE,MAAM,OAAO,EACtB,MAAM,CAAC,EAAE,eAAe,YAAA,EACxB,kBAAkB,CAAC,EAAE,MAAM,YAAA,EAC3B,gBAAgB,CAAC,EAAE,MAAM,YAAA,EACzB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,YAAA;IAG1C,aAAa,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC;IA0BpE,OAAO,CAAC,UAAU;IAYlB,OAAO,CAAC,iBAAiB;YAiBX,uBAAuB;IASrC,OAAO,CAAC,iBAAiB;IAqBzB,OAAO,CAAC,oBAAoB;YAYd,wBAAwB;IAiBtC,wBAAwB,IAAI,IAAI;IAehC,OAAO,CAAC,iBAAiB;CAiB1B"}
1
+ {"version":3,"file":"request-handler.d.ts","sourceRoot":"","sources":["../../../../src/src/server/dev-server/request-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,wBAAwB,CAAC;AASlD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAY7D,qBAAa,cAAc;IAIvB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,MAAM,CAAC;IACf,OAAO,CAAC,kBAAkB,CAAC;IAC3B,OAAO,CAAC,gBAAgB,CAAC;IACzB,OAAO,CAAC,aAAa,CAAC;IAVxB,OAAO,CAAC,cAAc,CAAC,CAAsD;gBAGnE,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,MAAM,OAAO,EACtB,OAAO,EAAE,MAAM,OAAO,EACtB,MAAM,CAAC,EAAE,eAAe,YAAA,EACxB,kBAAkB,CAAC,EAAE,MAAM,YAAA,EAC3B,gBAAgB,CAAC,EAAE,MAAM,YAAA,EACzB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,YAAA;IAG1C,aAAa,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC;IA0BpE,OAAO,CAAC,UAAU;IAYlB,OAAO,CAAC,iBAAiB;YAiBX,uBAAuB;IASrC,OAAO,CAAC,iBAAiB;IAqBzB,OAAO,CAAC,oBAAoB;YAYd,wBAAwB;IAiBtC,wBAAwB,IAAI,IAAI;IAehC,OAAO,CAAC,iBAAiB;CAqB1B"}
@@ -1,7 +1,7 @@
1
1
  import * as dntShim from "../../../_dnt.shims.js";
2
2
  import { DEV_SERVER_ENDPOINTS, HTTP_CONTENT_TYPES, HTTP_OK, HTTP_SERVER_ERROR, HTTP_UNAVAILABLE, serverLogger, } from "../../utils/index.js";
3
3
  import { clearConfigCache } from "../../config/index.js";
4
- import { ErrorOverlay } from "./error-overlay/index.js";
4
+ import { ErrorOverlay, parseErrorLocation } from "./error-overlay/index.js";
5
5
  import { createResponseBuilder } from "../../security/index.js";
6
6
  import { resetApiHandler } from "../handlers/request/api/pages-api-handler.js";
7
7
  import { clearLayoutDiscoveryCache } from "../../rendering/layouts/index.js";
@@ -147,10 +147,14 @@ export class RequestHandler {
147
147
  logger.error("Server error:", error);
148
148
  const err = error;
149
149
  getErrorCollector().addRuntimeError(err.message, err.stack, { source: "request-handler" });
150
+ const sourceFile = err.sourceFile;
151
+ const location = sourceFile ? parseErrorLocation(err, sourceFile) : {};
150
152
  return new dntShim.Response(ErrorOverlay.createHTML({
151
153
  type: "runtime",
152
154
  error: err,
153
- }), {
155
+ ...(sourceFile ? { file: sourceFile } : {}),
156
+ ...location,
157
+ }, this.defaultProjectSlug), {
154
158
  status: HTTP_SERVER_ERROR,
155
159
  headers: { "content-type": "text/html; charset=utf-8" },
156
160
  });