@reckona/mreact-router 0.0.188 → 0.0.190

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 (69) hide show
  1. package/README.md +16 -3
  2. package/bin/mreact-router.js +23 -0
  3. package/dist/adapters/aws-lambda.d.ts +33 -13
  4. package/dist/adapters/aws-lambda.d.ts.map +1 -1
  5. package/dist/adapters/aws-lambda.js +128 -20
  6. package/dist/adapters/aws-lambda.js.map +1 -1
  7. package/dist/adapters/cloudflare.d.ts +18 -0
  8. package/dist/adapters/cloudflare.d.ts.map +1 -1
  9. package/dist/adapters/cloudflare.js.map +1 -1
  10. package/dist/adapters/edge.d.ts +2 -0
  11. package/dist/adapters/edge.d.ts.map +1 -1
  12. package/dist/adapters/edge.js.map +1 -1
  13. package/dist/adapters/node.d.ts +16 -2
  14. package/dist/adapters/node.d.ts.map +1 -1
  15. package/dist/adapters/node.js.map +1 -1
  16. package/dist/cache.d.ts +8 -0
  17. package/dist/cache.d.ts.map +1 -1
  18. package/dist/cache.js +34 -13
  19. package/dist/cache.js.map +1 -1
  20. package/dist/cli-options.d.ts +1 -1
  21. package/dist/cli-options.d.ts.map +1 -1
  22. package/dist/cli-options.js +21 -3
  23. package/dist/cli-options.js.map +1 -1
  24. package/dist/cli.js +0 -0
  25. package/dist/client.d.ts +1 -1
  26. package/dist/client.d.ts.map +1 -1
  27. package/dist/client.js +1 -0
  28. package/dist/client.js.map +1 -1
  29. package/dist/config.d.ts +4 -0
  30. package/dist/config.d.ts.map +1 -1
  31. package/dist/config.js +6 -2
  32. package/dist/config.js.map +1 -1
  33. package/dist/index.d.ts +19 -16
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +15 -5
  36. package/dist/index.js.map +1 -1
  37. package/dist/link.d.ts +22 -1
  38. package/dist/link.d.ts.map +1 -1
  39. package/dist/link.js +130 -5
  40. package/dist/link.js.map +1 -1
  41. package/dist/render.d.ts.map +1 -1
  42. package/dist/render.js +514 -517
  43. package/dist/render.js.map +1 -1
  44. package/dist/request.d.ts +10 -0
  45. package/dist/request.d.ts.map +1 -0
  46. package/dist/request.js +6 -0
  47. package/dist/request.js.map +1 -0
  48. package/dist/typed-routes.d.ts +4 -5
  49. package/dist/typed-routes.d.ts.map +1 -1
  50. package/dist/typed-routes.js.map +1 -1
  51. package/dist/vite.d.ts +6 -0
  52. package/dist/vite.d.ts.map +1 -1
  53. package/dist/vite.js +4 -1
  54. package/dist/vite.js.map +1 -1
  55. package/package.json +19 -13
  56. package/src/adapters/aws-lambda.ts +227 -56
  57. package/src/adapters/cloudflare.ts +59 -0
  58. package/src/adapters/edge.ts +14 -0
  59. package/src/adapters/node.ts +44 -2
  60. package/src/cache.ts +39 -17
  61. package/src/cli-options.ts +28 -6
  62. package/src/client.ts +2 -1
  63. package/src/config.ts +10 -2
  64. package/src/index.ts +56 -10
  65. package/src/link.ts +205 -10
  66. package/src/render.ts +5 -7
  67. package/src/request.ts +35 -0
  68. package/src/typed-routes.ts +4 -4
  69. package/src/vite.ts +30 -1
package/dist/render.js CHANGED
@@ -13,7 +13,7 @@ import { matchRoute, scanAppRoutes } from "./routes.js";
13
13
  import { appFileConventionContentType } from "./file-conventions.js";
14
14
  import { dispatchServerActionRequest, prepareRouteServerActionPlaceholders, prepareRouteServerActions, } from "./actions.js";
15
15
  import { serverActionCookie } from "./csrf.js";
16
- import { beginRouteCacheContext, cachedRouteResponse, cacheRouteResponse, routeCacheKey, routeCachePolicyFromSource, } from "./cache.js";
16
+ import { activeRouteCacheContext, withRouteCacheContext, cachedRouteResponse, cacheRouteResponse, routeCacheKey, routeCachePolicyFromSource, } from "./cache.js";
17
17
  import { resolveRouterCacheLimit } from "./cache-config.js";
18
18
  import { importAppRouterBuiltFileModule, importAppRouterFileModule, importAppRouterSourceModule, fileImportMetaUrlPlugin, rewriteCompatVendorPlaceholderImportsForRunner, } from "./module-runner.js";
19
19
  import { bytesResponse, htmlResponse } from "./http.js";
@@ -489,335 +489,430 @@ async function renderAppRequestInternal(options) {
489
489
  }
490
490
  const queryClient = options.queryClient ?? createQueryClient();
491
491
  let recoveryRoute;
492
- let routeCacheContext;
493
- try {
494
- if (matched.route.kind === "asset") {
495
- return await dispatchConventionAssetRoute({
496
- file: matched.route.file,
497
- request: options.request,
498
- });
499
- }
500
- if (matched.route.kind === "metadata") {
501
- return await dispatchMetadataRoute({
502
- appDir: options.appDir,
503
- file: matched.route.file,
504
- importPolicy: options.importPolicy,
505
- params: matched.params,
506
- request: options.request,
507
- route: matched.route,
508
- serverModules: options.serverModules,
509
- serverModuleCacheVersion: options.serverModuleCacheVersion,
510
- serverSourceFiles: options.serverSourceFiles,
511
- vitePlugins: options.vitePlugins,
512
- });
513
- }
514
- if (matched.route.kind === "server") {
515
- return await dispatchServerRoute({
516
- appDir: options.appDir,
517
- env: options.env,
518
- file: matched.route.file,
519
- importPolicy: options.importPolicy,
520
- params: matched.params,
521
- request: options.request,
522
- route: matched.route,
523
- serverModules: options.serverModules,
524
- serverModuleCacheVersion: options.serverModuleCacheVersion,
525
- serverSourceFiles: options.serverSourceFiles,
526
- vitePlugins: options.vitePlugins,
527
- });
528
- }
529
- // Issue 080: page routes render HTML for GET / HEAD only. Other
530
- // methods (PUT, PATCH, DELETE, PROPFIND, ...) get 405 with an
531
- // Allow header so the response shape complies with RFC 9110 §9
532
- // and so caching intermediaries do not cross-cache method results.
533
- const methodResponse = pageRouteMethodResponse(options.request.method);
534
- if (methodResponse !== undefined) {
535
- return methodResponse;
536
- }
537
- routeCacheContext = beginRouteCacheContext(options.routeCache);
538
- const clientScript = options.clientScripts?.get(matched.route.path);
539
- const clientStyleSheets = options.clientStyles?.get(matched.route.path);
540
- phaseStartedAt = renderTimingPhaseStartedAt(timing);
541
- const originalCode = await readServerSourceFile(matched.route.file, options.serverModuleCacheVersion, options.serverSourceFiles);
542
- finishRenderTimingPhase(timing, phaseStartedAt, "readSourceMs");
543
- phaseStartedAt = renderTimingPhaseStartedAt(timing);
544
- const originalAnalysis = await analyzeRouteSource({
545
- appDir: options.appDir,
546
- artifact: options.serverModules?.get(matched.route.file)?.analysis,
547
- code: originalCode,
548
- filename: matched.route.file,
549
- routePath: matched.route.path,
550
- clientRouteInferenceCache,
551
- serverModuleCacheVersion: options.serverModuleCacheVersion,
552
- serverSourceFiles: options.serverSourceFiles,
553
- define: options.define,
554
- timing,
555
- vitePlugins: options.vitePlugins,
556
- });
557
- finishRenderTimingPhase(timing, phaseStartedAt, "sourceAnalysisMs");
558
- const cachePolicy = originalAnalysis.cachePolicy;
559
- const navigationScript = options.navigationScripts?.get(matched.route.path);
560
- const cacheKey = routeCacheKey(options.appDir, matched.route.path, url);
561
- const mayUseRouteCache = cachePolicy === undefined
562
- ? originalAnalysis.usesRuntimeCacheControl
563
- : cachePolicy.revalidateSeconds !== 0;
564
- const reloadRouteCache = isNavigationRouteCacheReloadRequest(options.request);
565
- phaseStartedAt = renderTimingPhaseStartedAt(timing);
566
- const cachedResponse = !mayUseRouteCache || reloadRouteCache
567
- ? undefined
568
- : await cachedRouteResponse({
569
- cache: options.routeCache,
570
- key: cacheKey,
571
- request: options.request,
572
- });
573
- finishRenderTimingPhase(timing, phaseStartedAt, "routeCacheMs");
574
- if (cachedResponse !== undefined) {
575
- return cachedResponse;
576
- }
577
- phaseStartedAt = renderTimingPhaseStartedAt(timing);
578
- const preparedActions = await prepareRouteServerActions({
579
- appDir: options.appDir,
580
- code: originalCode,
581
- formActionReferences: options.serverActionReferencesByFile?.get(matched.route.file),
582
- placeholders: true,
583
- pageFile: matched.route.file,
584
- request: options.request,
585
- });
586
- for (const diagnostic of preparedActions.diagnostics ?? []) {
587
- console.warn(`${diagnostic.code}: ${diagnostic.message}`);
588
- }
589
- finishRenderTimingPhase(timing, phaseStartedAt, "serverActionsMs");
590
- const code = preparedActions.code;
591
- phaseStartedAt = renderTimingPhaseStartedAt(timing);
592
- const routeAnalysis = code === originalCode
593
- ? originalAnalysis
594
- : await analyzeRouteSource({
492
+ return (await withRouteCacheContext(options.routeCache, async () => {
493
+ try {
494
+ if (matched.route.kind === "asset") {
495
+ return await dispatchConventionAssetRoute({
496
+ file: matched.route.file,
497
+ request: options.request,
498
+ });
499
+ }
500
+ if (matched.route.kind === "metadata") {
501
+ return await dispatchMetadataRoute({
502
+ appDir: options.appDir,
503
+ file: matched.route.file,
504
+ importPolicy: options.importPolicy,
505
+ params: matched.params,
506
+ request: options.request,
507
+ route: matched.route,
508
+ serverModules: options.serverModules,
509
+ serverModuleCacheVersion: options.serverModuleCacheVersion,
510
+ serverSourceFiles: options.serverSourceFiles,
511
+ vitePlugins: options.vitePlugins,
512
+ });
513
+ }
514
+ if (matched.route.kind === "server") {
515
+ return await dispatchServerRoute({
516
+ appDir: options.appDir,
517
+ env: options.env,
518
+ file: matched.route.file,
519
+ importPolicy: options.importPolicy,
520
+ params: matched.params,
521
+ request: options.request,
522
+ route: matched.route,
523
+ serverModules: options.serverModules,
524
+ serverModuleCacheVersion: options.serverModuleCacheVersion,
525
+ serverSourceFiles: options.serverSourceFiles,
526
+ vitePlugins: options.vitePlugins,
527
+ });
528
+ }
529
+ // Issue 080: page routes render HTML for GET / HEAD only. Other
530
+ // methods (PUT, PATCH, DELETE, PROPFIND, ...) get 405 with an
531
+ // Allow header so the response shape complies with RFC 9110 §9
532
+ // and so caching intermediaries do not cross-cache method results.
533
+ const methodResponse = pageRouteMethodResponse(options.request.method);
534
+ if (methodResponse !== undefined) {
535
+ return methodResponse;
536
+ }
537
+ const clientScript = options.clientScripts?.get(matched.route.path);
538
+ const clientStyleSheets = options.clientStyles?.get(matched.route.path);
539
+ phaseStartedAt = renderTimingPhaseStartedAt(timing);
540
+ const originalCode = await readServerSourceFile(matched.route.file, options.serverModuleCacheVersion, options.serverSourceFiles);
541
+ finishRenderTimingPhase(timing, phaseStartedAt, "readSourceMs");
542
+ phaseStartedAt = renderTimingPhaseStartedAt(timing);
543
+ const originalAnalysis = await analyzeRouteSource({
595
544
  appDir: options.appDir,
596
- buildRenderCode: preparedActions.htmlReplacements !== undefined,
597
- code,
545
+ artifact: options.serverModules?.get(matched.route.file)?.analysis,
546
+ code: originalCode,
598
547
  filename: matched.route.file,
599
548
  routePath: matched.route.path,
600
549
  clientRouteInferenceCache,
601
- serverModuleCacheVersion: undefined,
550
+ serverModuleCacheVersion: options.serverModuleCacheVersion,
602
551
  serverSourceFiles: options.serverSourceFiles,
603
552
  define: options.define,
553
+ timing,
604
554
  vitePlugins: options.vitePlugins,
605
555
  });
606
- finishRenderTimingPhase(timing, phaseStartedAt, "routeCodeAnalysisMs");
607
- const routeCode = routeAnalysis.routeCode;
608
- const streamRoute = routeAnalysis.streamRoute;
609
- const clientInference = routeAnalysis.clientInference;
610
- const clientRoute = clientInference.client;
611
- phaseStartedAt = renderTimingPhaseStartedAt(timing);
612
- const loaderReady = routeAnalysis.hasLoader ? createDeferredSignal() : undefined;
613
- const dataPromise = routeAnalysis.hasLoader
614
- ? loadRouteDataWithInstrumentation({
615
- appDir: options.appDir,
616
- code: originalCode,
617
- context: {
618
- env: options.env,
619
- params: matched.params,
620
- queryClient,
556
+ finishRenderTimingPhase(timing, phaseStartedAt, "sourceAnalysisMs");
557
+ const cachePolicy = originalAnalysis.cachePolicy;
558
+ const navigationScript = options.navigationScripts?.get(matched.route.path);
559
+ const cacheKey = routeCacheKey(options.appDir, matched.route.path, url);
560
+ const mayUseRouteCache = cachePolicy === undefined
561
+ ? originalAnalysis.usesRuntimeCacheControl
562
+ : cachePolicy.revalidateSeconds !== 0;
563
+ const reloadRouteCache = isNavigationRouteCacheReloadRequest(options.request);
564
+ phaseStartedAt = renderTimingPhaseStartedAt(timing);
565
+ const cachedResponse = !mayUseRouteCache || reloadRouteCache
566
+ ? undefined
567
+ : await cachedRouteResponse({
568
+ cache: options.routeCache,
569
+ key: cacheKey,
621
570
  request: options.request,
622
- },
623
- filename: matched.route.file,
624
- importPolicy: options.importPolicy,
625
- instrumentation: options.instrumentation,
626
- devServerModuleCacheVersion: options.devServerModuleCacheVersion,
627
- request: options.request,
628
- routeId: routeIdForPath(matched.route.path),
629
- routePath: matched.route.path,
630
- serverModules: options.serverModules,
631
- serverModuleCacheVersion: options.serverModuleCacheVersion,
632
- define: options.define,
633
- vitePlugins: options.vitePlugins,
634
- timing,
635
- onLoaderReady: loaderReady?.resolve,
636
- })
637
- : undefined;
638
- finishRenderTimingPhase(timing, phaseStartedAt, "loaderStartMs");
639
- recoveryRoute = {
640
- clientRoute,
641
- props: {
642
- params: matched.params,
643
- request: { url: options.request.url },
644
- },
645
- routePath: matched.route.path,
646
- script: clientScript,
647
- };
648
- if (streamRoute) {
571
+ });
572
+ finishRenderTimingPhase(timing, phaseStartedAt, "routeCacheMs");
573
+ if (cachedResponse !== undefined) {
574
+ return cachedResponse;
575
+ }
649
576
  phaseStartedAt = renderTimingPhaseStartedAt(timing);
650
- const loadingFile = await nearestExistingBoundaryFileForPage({
577
+ const preparedActions = await prepareRouteServerActions({
651
578
  appDir: options.appDir,
652
- filename: "loading.mreact.tsx",
579
+ code: originalCode,
580
+ formActionReferences: options.serverActionReferencesByFile?.get(matched.route.file),
581
+ placeholders: true,
653
582
  pageFile: matched.route.file,
654
- serverSourceFiles: options.serverSourceFiles,
583
+ request: options.request,
655
584
  });
656
- finishRenderTimingPhase(timing, phaseStartedAt, "loadingBoundaryLookupMs");
657
- const streamShellResponseHeaders = {
658
- "content-type": "text/html; charset=utf-8",
659
- "x-mreact-stream": "1",
660
- };
585
+ for (const diagnostic of preparedActions.diagnostics ?? []) {
586
+ console.warn(`${diagnostic.code}: ${diagnostic.message}`);
587
+ }
588
+ finishRenderTimingPhase(timing, phaseStartedAt, "serverActionsMs");
589
+ const code = preparedActions.code;
661
590
  phaseStartedAt = renderTimingPhaseStartedAt(timing);
662
- const mayRenderOutOfOrder = await mayRenderOutOfOrderBoundaryDeep({
663
- code: routeCode,
664
- filename: matched.route.file,
665
- serverModuleCacheVersion: options.serverModuleCacheVersion,
666
- serverSourceFiles: options.serverSourceFiles,
667
- });
668
- finishRenderTimingPhase(timing, phaseStartedAt, "outOfOrderAnalysisMs");
669
- if (loadingFile === undefined && !mayRenderOutOfOrder) {
591
+ const routeAnalysis = code === originalCode
592
+ ? originalAnalysis
593
+ : await analyzeRouteSource({
594
+ appDir: options.appDir,
595
+ buildRenderCode: preparedActions.htmlReplacements !== undefined,
596
+ code,
597
+ filename: matched.route.file,
598
+ routePath: matched.route.path,
599
+ clientRouteInferenceCache,
600
+ serverModuleCacheVersion: undefined,
601
+ serverSourceFiles: options.serverSourceFiles,
602
+ define: options.define,
603
+ vitePlugins: options.vitePlugins,
604
+ });
605
+ finishRenderTimingPhase(timing, phaseStartedAt, "routeCodeAnalysisMs");
606
+ const routeCode = routeAnalysis.routeCode;
607
+ const streamRoute = routeAnalysis.streamRoute;
608
+ const clientInference = routeAnalysis.clientInference;
609
+ const clientRoute = clientInference.client;
610
+ phaseStartedAt = renderTimingPhaseStartedAt(timing);
611
+ const loaderReady = routeAnalysis.hasLoader ? createDeferredSignal() : undefined;
612
+ const dataPromise = routeAnalysis.hasLoader
613
+ ? loadRouteDataWithInstrumentation({
614
+ appDir: options.appDir,
615
+ code: originalCode,
616
+ context: {
617
+ env: options.env,
618
+ params: matched.params,
619
+ queryClient,
620
+ request: options.request,
621
+ },
622
+ filename: matched.route.file,
623
+ importPolicy: options.importPolicy,
624
+ instrumentation: options.instrumentation,
625
+ devServerModuleCacheVersion: options.devServerModuleCacheVersion,
626
+ request: options.request,
627
+ routeId: routeIdForPath(matched.route.path),
628
+ routePath: matched.route.path,
629
+ serverModules: options.serverModules,
630
+ serverModuleCacheVersion: options.serverModuleCacheVersion,
631
+ define: options.define,
632
+ vitePlugins: options.vitePlugins,
633
+ timing,
634
+ onLoaderReady: loaderReady?.resolve,
635
+ })
636
+ : undefined;
637
+ finishRenderTimingPhase(timing, phaseStartedAt, "loaderStartMs");
638
+ recoveryRoute = {
639
+ clientRoute,
640
+ props: {
641
+ params: matched.params,
642
+ request: { url: options.request.url },
643
+ },
644
+ routePath: matched.route.path,
645
+ script: clientScript,
646
+ };
647
+ if (streamRoute) {
648
+ phaseStartedAt = renderTimingPhaseStartedAt(timing);
649
+ const loadingFile = await nearestExistingBoundaryFileForPage({
650
+ appDir: options.appDir,
651
+ filename: "loading.mreact.tsx",
652
+ pageFile: matched.route.file,
653
+ serverSourceFiles: options.serverSourceFiles,
654
+ });
655
+ finishRenderTimingPhase(timing, phaseStartedAt, "loadingBoundaryLookupMs");
656
+ const streamShellResponseHeaders = {
657
+ "content-type": "text/html; charset=utf-8",
658
+ "x-mreact-stream": "1",
659
+ };
670
660
  phaseStartedAt = renderTimingPhaseStartedAt(timing);
671
- let data;
672
- try {
673
- data = dataPromise === undefined ? undefined : await dataPromise;
661
+ const mayRenderOutOfOrder = await mayRenderOutOfOrderBoundaryDeep({
662
+ code: routeCode,
663
+ filename: matched.route.file,
664
+ serverModuleCacheVersion: options.serverModuleCacheVersion,
665
+ serverSourceFiles: options.serverSourceFiles,
666
+ });
667
+ finishRenderTimingPhase(timing, phaseStartedAt, "outOfOrderAnalysisMs");
668
+ if (loadingFile === undefined && !mayRenderOutOfOrder) {
669
+ phaseStartedAt = renderTimingPhaseStartedAt(timing);
670
+ let data;
671
+ try {
672
+ data = dataPromise === undefined ? undefined : await dataPromise;
673
+ }
674
+ finally {
675
+ finishRenderTimingPhase(timing, phaseStartedAt, "loaderWaitMs");
676
+ }
677
+ if (data instanceof Response) {
678
+ emitRenderTiming(options, timing, data.status);
679
+ return data;
680
+ }
681
+ await waitForRenderPreload(options, timing);
682
+ await loadServerRenderArtifacts(options, matched.route.file, timing);
683
+ phaseStartedAt = renderTimingPhaseStartedAt(timing);
684
+ const stringOutput = transformServerModule({
685
+ code: routeCode,
686
+ clientBoundaryImports: clientInference.clientBoundaryImports,
687
+ clientBoundaryFallbackImports: clientInference.clientBoundaryFallbackImports,
688
+ filename: matched.route.file,
689
+ serverModules: options.serverModules,
690
+ serverOutput: "string",
691
+ });
692
+ finishRenderTimingPhase(timing, phaseStartedAt, "stringTransformMs");
693
+ const stringFatalDiagnostics = fatalServerDiagnostics(stringOutput.diagnostics);
694
+ if (stringFatalDiagnostics.length > 0) {
695
+ return new Response(formatServerDiagnostics(matched.route.file, stringFatalDiagnostics), {
696
+ status: 500,
697
+ headers: { "content-type": "text/plain; charset=utf-8" },
698
+ });
699
+ }
700
+ const renderedPage = await runWithQueryClient(queryClient, () => runServerModuleWithSlots(stringOutput.code, {
701
+ data,
702
+ params: matched.params,
703
+ queryClient,
704
+ request: options.request,
705
+ }, matched.route.file, options.serverModules, options.serverModuleCacheVersion, options.define, options.vitePlugins, undefined, options.importPolicy, options.devServerModuleCacheVersion));
706
+ const pageHtml = renderedPage.html;
707
+ const pageHtmlForLayout = clientRoute
708
+ ? withHydrationMarkers({
709
+ assetBaseUrl: options.assetBaseUrl,
710
+ clientReferenceManifest: stringOutput.metadata.clientReferenceManifest,
711
+ html: pageHtml,
712
+ routePath: matched.route.path,
713
+ script: clientScript,
714
+ props: {
715
+ params: matched.params,
716
+ request: { url: options.request.url },
717
+ data,
718
+ },
719
+ })
720
+ : isNavigationRequest(options.request)
721
+ ? withRouteMarkers({
722
+ html: pageHtml,
723
+ routePath: matched.route.path,
724
+ })
725
+ : pageHtml;
726
+ let html = await runWithQueryClient(queryClient, () => applyLayouts({
727
+ appDir: options.appDir,
728
+ pageFile: matched.route.file,
729
+ html: pageHtmlForLayout,
730
+ props: {
731
+ data,
732
+ params: matched.params,
733
+ queryClient,
734
+ request: options.request,
735
+ },
736
+ slots: renderedPage.slots,
737
+ serverModules: options.serverModules,
738
+ serverModuleCacheVersion: options.serverModuleCacheVersion,
739
+ serverSourceFiles: options.serverSourceFiles,
740
+ clientRouteInferenceCache,
741
+ timing,
742
+ vitePlugins: options.vitePlugins,
743
+ importPolicy: options.importPolicy,
744
+ }));
745
+ const metadata = await loadComposedRouteMetadata({
746
+ appDir: options.appDir,
747
+ code: originalCode,
748
+ context: {
749
+ data,
750
+ params: matched.params,
751
+ request: options.request,
752
+ },
753
+ filename: matched.route.file,
754
+ importPolicy: options.importPolicy,
755
+ routes,
756
+ serverModules: options.serverModules,
757
+ serverModuleCacheVersion: options.serverModuleCacheVersion,
758
+ devServerModuleCacheVersion: options.devServerModuleCacheVersion,
759
+ serverSourceFiles: options.serverSourceFiles,
760
+ define: options.define,
761
+ vitePlugins: options.vitePlugins,
762
+ });
763
+ html = injectHeadMetadata(html, metadata);
764
+ warnIfCspNonceWouldBlockInlineTags({
765
+ html,
766
+ logger: options.logger,
767
+ metadata,
768
+ request: options.request,
769
+ serverModuleCacheVersion: options.serverModuleCacheVersion,
770
+ });
771
+ html = injectAuthSessionClaims(html, originalAnalysis.authIncludesClaims ? currentAuthClaims() : undefined);
772
+ html = injectQueryState(html, dehydrate(queryClient));
773
+ const response = withOptionalActionCookie(htmlResponse(applyActionHtmlReplacements(`<!DOCTYPE html>${clientNavigationHeadTags({
774
+ assetBaseUrl: options.assetBaseUrl,
775
+ currentStyleSheets: clientStyleSheets,
776
+ currentScript: clientRoute ? clientScript : undefined,
777
+ currentNavigationScript: navigationScript,
778
+ routeScripts: options.clientScripts,
779
+ })}${html}`, preparedActions.htmlReplacements), {
780
+ headers: responseHeadersForMetadata(metadata, options.request, {
781
+ "x-mreact-stream": "1",
782
+ }),
783
+ }), preparedActions.csrfToken, preparedActions.csrfTokenIsNew === true);
784
+ emitRenderTiming(options, timing, response.status);
785
+ return response;
674
786
  }
675
- finally {
676
- finishRenderTimingPhase(timing, phaseStartedAt, "loaderWaitMs");
787
+ let streamData;
788
+ let streamDataPromise = dataPromise ?? Promise.resolve(undefined);
789
+ phaseStartedAt = renderTimingPhaseStartedAt(timing);
790
+ if (loadingFile === undefined || routeLoaderMayReturnControlResponse(originalCode)) {
791
+ try {
792
+ streamData = dataPromise === undefined ? undefined : await dataPromise;
793
+ }
794
+ finally {
795
+ finishRenderTimingPhase(timing, phaseStartedAt, "loaderWaitMs");
796
+ }
797
+ if (streamData instanceof Response) {
798
+ emitRenderTiming(options, timing, streamData.status);
799
+ return streamData;
800
+ }
801
+ streamDataPromise = Promise.resolve(streamData);
677
802
  }
678
- if (data instanceof Response) {
679
- emitRenderTiming(options, timing, data.status);
680
- return data;
803
+ else {
804
+ try {
805
+ const settledData = await readSettledPromiseAtNextTask(streamDataPromise);
806
+ if (settledData.settled) {
807
+ if (settledData.value instanceof Response) {
808
+ emitRenderTiming(options, timing, settledData.value.status);
809
+ return settledData.value;
810
+ }
811
+ streamDataPromise = Promise.resolve(settledData.value);
812
+ }
813
+ else {
814
+ await waitForLoaderReadyOrSettled(streamDataPromise, loaderReady?.promise);
815
+ }
816
+ }
817
+ finally {
818
+ finishRenderTimingPhase(timing, phaseStartedAt, "loaderWaitMs");
819
+ }
681
820
  }
682
821
  await waitForRenderPreload(options, timing);
683
822
  await loadServerRenderArtifacts(options, matched.route.file, timing);
684
823
  phaseStartedAt = renderTimingPhaseStartedAt(timing);
685
- const stringOutput = transformServerModule({
824
+ const output = transformServerModule({
686
825
  code: routeCode,
687
826
  clientBoundaryImports: clientInference.clientBoundaryImports,
688
827
  clientBoundaryFallbackImports: clientInference.clientBoundaryFallbackImports,
689
828
  filename: matched.route.file,
690
829
  serverModules: options.serverModules,
691
- serverOutput: "string",
830
+ serverOutput: "stream",
831
+ serverAwaitHydration: clientRoute,
692
832
  });
693
- finishRenderTimingPhase(timing, phaseStartedAt, "stringTransformMs");
694
- const stringFatalDiagnostics = fatalServerDiagnostics(stringOutput.diagnostics);
695
- if (stringFatalDiagnostics.length > 0) {
696
- return new Response(formatServerDiagnostics(matched.route.file, stringFatalDiagnostics), {
833
+ finishRenderTimingPhase(timing, phaseStartedAt, "streamTransformMs");
834
+ const fatalDiagnostics = fatalServerDiagnostics(output.diagnostics);
835
+ if (fatalDiagnostics.length > 0) {
836
+ return new Response(formatServerDiagnostics(matched.route.file, fatalDiagnostics), {
697
837
  status: 500,
698
838
  headers: { "content-type": "text/plain; charset=utf-8" },
699
839
  });
700
840
  }
701
- const renderedPage = await runWithQueryClient(queryClient, () => runServerModuleWithSlots(stringOutput.code, {
841
+ if (loadingFile !== undefined) {
842
+ phaseStartedAt = renderTimingPhaseStartedAt(timing);
843
+ const stream = await runServerStreamModuleWithLoading(output.code, {
844
+ appDir: options.appDir,
845
+ assetBaseUrl: options.assetBaseUrl,
846
+ clientRoute,
847
+ data: streamDataPromise,
848
+ define: options.define,
849
+ loadingFile,
850
+ pageFile: matched.route.file,
851
+ params: matched.params,
852
+ queryClient,
853
+ request: options.request,
854
+ routePath: matched.route.path,
855
+ routeScripts: options.clientScripts,
856
+ serverModules: options.serverModules,
857
+ serverModuleCacheVersion: options.serverModuleCacheVersion,
858
+ serverSourceFiles: options.serverSourceFiles,
859
+ vitePlugins: options.vitePlugins,
860
+ clientRouteInferenceCache,
861
+ importPolicy: options.importPolicy,
862
+ script: clientScript,
863
+ clientReferenceManifest: output.metadata.clientReferenceManifest,
864
+ });
865
+ finishRenderTimingPhase(timing, phaseStartedAt, "streamConstructionMs");
866
+ const response = withOptionalActionCookie(new Response(stream, {
867
+ headers: streamShellResponseHeaders,
868
+ }), preparedActions.csrfToken, preparedActions.csrfTokenIsNew === true);
869
+ emitRenderTiming(options, timing, response.status);
870
+ return response;
871
+ }
872
+ const data = streamData;
873
+ const props = {
702
874
  data,
703
875
  params: matched.params,
704
876
  queryClient,
705
877
  request: options.request,
706
- }, matched.route.file, options.serverModules, options.serverModuleCacheVersion, options.define, options.vitePlugins, undefined, options.importPolicy, options.devServerModuleCacheVersion));
707
- const pageHtml = renderedPage.html;
708
- const pageHtmlForLayout = clientRoute
709
- ? withHydrationMarkers({
710
- assetBaseUrl: options.assetBaseUrl,
711
- clientReferenceManifest: stringOutput.metadata.clientReferenceManifest,
712
- html: pageHtml,
713
- routePath: matched.route.path,
714
- script: clientScript,
715
- props: {
716
- params: matched.params,
717
- request: { url: options.request.url },
718
- data,
719
- },
720
- })
721
- : isNavigationRequest(options.request)
722
- ? withRouteMarkers({
723
- html: pageHtml,
724
- routePath: matched.route.path,
725
- })
726
- : pageHtml;
727
- let html = await runWithQueryClient(queryClient, () => applyLayouts({
878
+ };
879
+ phaseStartedAt = renderTimingPhaseStartedAt(timing);
880
+ const stream = runServerStreamModule(output.code, {
728
881
  appDir: options.appDir,
882
+ assetBaseUrl: options.assetBaseUrl,
729
883
  pageFile: matched.route.file,
730
- html: pageHtmlForLayout,
731
- props: {
732
- data,
733
- params: matched.params,
734
- queryClient,
735
- request: options.request,
736
- },
737
- slots: renderedPage.slots,
738
- serverModules: options.serverModules,
739
- serverModuleCacheVersion: options.serverModuleCacheVersion,
740
- serverSourceFiles: options.serverSourceFiles,
741
- clientRouteInferenceCache,
742
- timing,
743
- vitePlugins: options.vitePlugins,
744
- importPolicy: options.importPolicy,
745
- }));
746
- const metadata = await loadComposedRouteMetadata({
747
- appDir: options.appDir,
748
- code: originalCode,
749
- context: {
750
- data,
751
- params: matched.params,
752
- request: options.request,
753
- },
754
- filename: matched.route.file,
755
- importPolicy: options.importPolicy,
756
- routes,
884
+ props,
885
+ routePath: matched.route.path,
886
+ routeScripts: options.clientScripts,
757
887
  serverModules: options.serverModules,
758
888
  serverModuleCacheVersion: options.serverModuleCacheVersion,
759
- devServerModuleCacheVersion: options.devServerModuleCacheVersion,
760
889
  serverSourceFiles: options.serverSourceFiles,
761
890
  define: options.define,
762
891
  vitePlugins: options.vitePlugins,
892
+ clientRouteInferenceCache,
893
+ importPolicy: options.importPolicy,
894
+ clientRoute,
895
+ script: clientScript,
896
+ clientReferenceManifest: output.metadata.clientReferenceManifest,
763
897
  });
764
- html = injectHeadMetadata(html, metadata);
765
- warnIfCspNonceWouldBlockInlineTags({
766
- html,
767
- logger: options.logger,
768
- metadata,
769
- request: options.request,
770
- serverModuleCacheVersion: options.serverModuleCacheVersion,
771
- });
772
- html = injectAuthSessionClaims(html, originalAnalysis.authIncludesClaims ? currentAuthClaims() : undefined);
773
- html = injectQueryState(html, dehydrate(queryClient));
774
- const response = withOptionalActionCookie(htmlResponse(applyActionHtmlReplacements(`<!DOCTYPE html>${clientNavigationHeadTags({
775
- assetBaseUrl: options.assetBaseUrl,
776
- currentStyleSheets: clientStyleSheets,
777
- currentScript: clientRoute ? clientScript : undefined,
778
- currentNavigationScript: navigationScript,
779
- routeScripts: options.clientScripts,
780
- })}${html}`, preparedActions.htmlReplacements), {
781
- headers: responseHeadersForMetadata(metadata, options.request, {
782
- "x-mreact-stream": "1",
783
- }),
898
+ finishRenderTimingPhase(timing, phaseStartedAt, "streamConstructionMs");
899
+ const response = withOptionalActionCookie(new Response(stream, {
900
+ headers: streamShellResponseHeaders,
784
901
  }), preparedActions.csrfToken, preparedActions.csrfTokenIsNew === true);
785
902
  emitRenderTiming(options, timing, response.status);
786
903
  return response;
787
904
  }
788
- let streamData;
789
- let streamDataPromise = dataPromise ?? Promise.resolve(undefined);
790
905
  phaseStartedAt = renderTimingPhaseStartedAt(timing);
791
- if (loadingFile === undefined || routeLoaderMayReturnControlResponse(originalCode)) {
792
- try {
793
- streamData = dataPromise === undefined ? undefined : await dataPromise;
794
- }
795
- finally {
796
- finishRenderTimingPhase(timing, phaseStartedAt, "loaderWaitMs");
797
- }
798
- if (streamData instanceof Response) {
799
- emitRenderTiming(options, timing, streamData.status);
800
- return streamData;
801
- }
802
- streamDataPromise = Promise.resolve(streamData);
906
+ let data;
907
+ try {
908
+ data = dataPromise === undefined ? undefined : await dataPromise;
803
909
  }
804
- else {
805
- try {
806
- const settledData = await readSettledPromiseAtNextTask(streamDataPromise);
807
- if (settledData.settled) {
808
- if (settledData.value instanceof Response) {
809
- emitRenderTiming(options, timing, settledData.value.status);
810
- return settledData.value;
811
- }
812
- streamDataPromise = Promise.resolve(settledData.value);
813
- }
814
- else {
815
- await waitForLoaderReadyOrSettled(streamDataPromise, loaderReady?.promise);
816
- }
817
- }
818
- finally {
819
- finishRenderTimingPhase(timing, phaseStartedAt, "loaderWaitMs");
820
- }
910
+ finally {
911
+ finishRenderTimingPhase(timing, phaseStartedAt, "loaderWaitMs");
912
+ }
913
+ if (data instanceof Response) {
914
+ emitRenderTiming(options, timing, data.status);
915
+ return data;
821
916
  }
822
917
  await waitForRenderPreload(options, timing);
823
918
  await loadServerRenderArtifacts(options, matched.route.file, timing);
@@ -828,10 +923,9 @@ async function renderAppRequestInternal(options) {
828
923
  clientBoundaryFallbackImports: clientInference.clientBoundaryFallbackImports,
829
924
  filename: matched.route.file,
830
925
  serverModules: options.serverModules,
831
- serverOutput: "stream",
832
- serverAwaitHydration: clientRoute,
926
+ serverOutput: "string",
833
927
  });
834
- finishRenderTimingPhase(timing, phaseStartedAt, "streamTransformMs");
928
+ finishRenderTimingPhase(timing, phaseStartedAt, "stringTransformMs");
835
929
  const fatalDiagnostics = fatalServerDiagnostics(output.diagnostics);
836
930
  if (fatalDiagnostics.length > 0) {
837
931
  return new Response(formatServerDiagnostics(matched.route.file, fatalDiagnostics), {
@@ -839,273 +933,176 @@ async function renderAppRequestInternal(options) {
839
933
  headers: { "content-type": "text/plain; charset=utf-8" },
840
934
  });
841
935
  }
842
- if (loadingFile !== undefined) {
843
- phaseStartedAt = renderTimingPhaseStartedAt(timing);
844
- const stream = await runServerStreamModuleWithLoading(output.code, {
845
- appDir: options.appDir,
846
- assetBaseUrl: options.assetBaseUrl,
847
- clientRoute,
848
- data: streamDataPromise,
849
- define: options.define,
850
- loadingFile,
851
- pageFile: matched.route.file,
852
- params: matched.params,
853
- queryClient,
854
- request: options.request,
855
- routePath: matched.route.path,
856
- routeScripts: options.clientScripts,
857
- serverModules: options.serverModules,
858
- serverModuleCacheVersion: options.serverModuleCacheVersion,
859
- serverSourceFiles: options.serverSourceFiles,
860
- vitePlugins: options.vitePlugins,
861
- clientRouteInferenceCache,
862
- importPolicy: options.importPolicy,
863
- script: clientScript,
864
- clientReferenceManifest: output.metadata.clientReferenceManifest,
865
- });
866
- finishRenderTimingPhase(timing, phaseStartedAt, "streamConstructionMs");
867
- const response = withOptionalActionCookie(new Response(stream, {
868
- headers: streamShellResponseHeaders,
869
- }), preparedActions.csrfToken, preparedActions.csrfTokenIsNew === true);
870
- emitRenderTiming(options, timing, response.status);
871
- return response;
872
- }
873
- const data = streamData;
874
- const props = {
936
+ phaseStartedAt = renderTimingPhaseStartedAt(timing);
937
+ const renderedPage = await runWithQueryClient(queryClient, () => runServerModuleWithSlots(output.code, {
875
938
  data,
876
939
  params: matched.params,
877
940
  queryClient,
878
941
  request: options.request,
879
- };
942
+ }, matched.route.file, options.serverModules, options.serverModuleCacheVersion, options.define, options.vitePlugins, timing, options.importPolicy, options.devServerModuleCacheVersion));
943
+ finishRenderTimingPhase(timing, phaseStartedAt, "pageRenderMs");
944
+ const pageHtml = renderedPage.html;
945
+ // Wrap the page (not the full document) with the hydration marker so
946
+ // the marker sits inside <body>, not around <html>. Wrapping <html>
947
+ // forces the browser HTML parser to strip the wrappers and promote
948
+ // <head> / <body> children up to the marker, which flattens the
949
+ // layout into the marker and breaks the hydration target lookup.
950
+ const pageHtmlForLayout = clientRoute
951
+ ? withHydrationMarkers({
952
+ assetBaseUrl: options.assetBaseUrl,
953
+ clientReferenceManifest: output.metadata.clientReferenceManifest,
954
+ html: pageHtml,
955
+ routePath: matched.route.path,
956
+ script: clientScript,
957
+ props: {
958
+ params: matched.params,
959
+ request: { url: options.request.url },
960
+ data,
961
+ },
962
+ })
963
+ : isNavigationRequest(options.request)
964
+ ? withRouteMarkers({
965
+ html: pageHtml,
966
+ routePath: matched.route.path,
967
+ })
968
+ : pageHtml;
880
969
  phaseStartedAt = renderTimingPhaseStartedAt(timing);
881
- const stream = runServerStreamModule(output.code, {
970
+ let html = await runWithQueryClient(queryClient, () => applyLayouts({
882
971
  appDir: options.appDir,
883
- assetBaseUrl: options.assetBaseUrl,
884
972
  pageFile: matched.route.file,
885
- props,
886
- routePath: matched.route.path,
887
- routeScripts: options.clientScripts,
973
+ html: pageHtmlForLayout,
974
+ props: {
975
+ data,
976
+ params: matched.params,
977
+ queryClient,
978
+ request: options.request,
979
+ },
980
+ slots: renderedPage.slots,
888
981
  serverModules: options.serverModules,
889
982
  serverModuleCacheVersion: options.serverModuleCacheVersion,
890
983
  serverSourceFiles: options.serverSourceFiles,
891
- define: options.define,
892
- vitePlugins: options.vitePlugins,
893
984
  clientRouteInferenceCache,
894
- importPolicy: options.importPolicy,
895
- clientRoute,
896
- script: clientScript,
897
- clientReferenceManifest: output.metadata.clientReferenceManifest,
898
- });
899
- finishRenderTimingPhase(timing, phaseStartedAt, "streamConstructionMs");
900
- const response = withOptionalActionCookie(new Response(stream, {
901
- headers: streamShellResponseHeaders,
902
- }), preparedActions.csrfToken, preparedActions.csrfTokenIsNew === true);
903
- emitRenderTiming(options, timing, response.status);
904
- return response;
905
- }
906
- phaseStartedAt = renderTimingPhaseStartedAt(timing);
907
- let data;
908
- try {
909
- data = dataPromise === undefined ? undefined : await dataPromise;
910
- }
911
- finally {
912
- finishRenderTimingPhase(timing, phaseStartedAt, "loaderWaitMs");
913
- }
914
- if (data instanceof Response) {
915
- emitRenderTiming(options, timing, data.status);
916
- return data;
917
- }
918
- await waitForRenderPreload(options, timing);
919
- await loadServerRenderArtifacts(options, matched.route.file, timing);
920
- phaseStartedAt = renderTimingPhaseStartedAt(timing);
921
- const output = transformServerModule({
922
- code: routeCode,
923
- clientBoundaryImports: clientInference.clientBoundaryImports,
924
- clientBoundaryFallbackImports: clientInference.clientBoundaryFallbackImports,
925
- filename: matched.route.file,
926
- serverModules: options.serverModules,
927
- serverOutput: "string",
928
- });
929
- finishRenderTimingPhase(timing, phaseStartedAt, "stringTransformMs");
930
- const fatalDiagnostics = fatalServerDiagnostics(output.diagnostics);
931
- if (fatalDiagnostics.length > 0) {
932
- return new Response(formatServerDiagnostics(matched.route.file, fatalDiagnostics), {
933
- status: 500,
934
- headers: { "content-type": "text/plain; charset=utf-8" },
935
- });
936
- }
937
- phaseStartedAt = renderTimingPhaseStartedAt(timing);
938
- const renderedPage = await runWithQueryClient(queryClient, () => runServerModuleWithSlots(output.code, {
939
- data,
940
- params: matched.params,
941
- queryClient,
942
- request: options.request,
943
- }, matched.route.file, options.serverModules, options.serverModuleCacheVersion, options.define, options.vitePlugins, timing, options.importPolicy, options.devServerModuleCacheVersion));
944
- finishRenderTimingPhase(timing, phaseStartedAt, "pageRenderMs");
945
- const pageHtml = renderedPage.html;
946
- // Wrap the page (not the full document) with the hydration marker so
947
- // the marker sits inside <body>, not around <html>. Wrapping <html>
948
- // forces the browser HTML parser to strip the wrappers and promote
949
- // <head> / <body> children up to the marker, which flattens the
950
- // layout into the marker and breaks the hydration target lookup.
951
- const pageHtmlForLayout = clientRoute
952
- ? withHydrationMarkers({
953
- assetBaseUrl: options.assetBaseUrl,
954
- clientReferenceManifest: output.metadata.clientReferenceManifest,
955
- html: pageHtml,
956
- routePath: matched.route.path,
957
- script: clientScript,
958
- props: {
959
- params: matched.params,
960
- request: { url: options.request.url },
985
+ timing,
986
+ vitePlugins: options.vitePlugins,
987
+ }));
988
+ finishRenderTimingPhase(timing, phaseStartedAt, "layoutRenderMs");
989
+ phaseStartedAt = renderTimingPhaseStartedAt(timing);
990
+ const metadata = await loadComposedRouteMetadata({
991
+ appDir: options.appDir,
992
+ code: originalCode,
993
+ context: {
961
994
  data,
995
+ params: matched.params,
996
+ request: options.request,
962
997
  },
963
- })
964
- : isNavigationRequest(options.request)
965
- ? withRouteMarkers({
966
- html: pageHtml,
967
- routePath: matched.route.path,
968
- })
969
- : pageHtml;
970
- phaseStartedAt = renderTimingPhaseStartedAt(timing);
971
- let html = await runWithQueryClient(queryClient, () => applyLayouts({
972
- appDir: options.appDir,
973
- pageFile: matched.route.file,
974
- html: pageHtmlForLayout,
975
- props: {
976
- data,
977
- params: matched.params,
978
- queryClient,
979
- request: options.request,
980
- },
981
- slots: renderedPage.slots,
982
- serverModules: options.serverModules,
983
- serverModuleCacheVersion: options.serverModuleCacheVersion,
984
- serverSourceFiles: options.serverSourceFiles,
985
- clientRouteInferenceCache,
986
- timing,
987
- vitePlugins: options.vitePlugins,
988
- }));
989
- finishRenderTimingPhase(timing, phaseStartedAt, "layoutRenderMs");
990
- phaseStartedAt = renderTimingPhaseStartedAt(timing);
991
- const metadata = await loadComposedRouteMetadata({
992
- appDir: options.appDir,
993
- code: originalCode,
994
- context: {
995
- data,
996
- params: matched.params,
997
- request: options.request,
998
- },
999
- filename: matched.route.file,
1000
- importPolicy: options.importPolicy,
1001
- routes,
1002
- serverModules: options.serverModules,
1003
- serverModuleCacheVersion: options.serverModuleCacheVersion,
1004
- devServerModuleCacheVersion: options.devServerModuleCacheVersion,
1005
- serverSourceFiles: options.serverSourceFiles,
1006
- define: options.define,
1007
- vitePlugins: options.vitePlugins,
1008
- });
1009
- finishRenderTimingPhase(timing, phaseStartedAt, "metadataMs");
1010
- phaseStartedAt = renderTimingPhaseStartedAt(timing);
1011
- html = injectHeadMetadata(html, metadata);
1012
- warnIfCspNonceWouldBlockInlineTags({
1013
- html,
1014
- logger: options.logger,
1015
- metadata,
1016
- request: options.request,
1017
- serverModuleCacheVersion: options.serverModuleCacheVersion,
1018
- });
1019
- html = injectAuthSessionClaims(html, originalAnalysis.authIncludesClaims ? currentAuthClaims() : undefined);
1020
- html = injectQueryState(html, dehydrate(queryClient));
1021
- const response = withOptionalActionCookie(htmlResponse(applyActionHtmlReplacements(`<!DOCTYPE html>${clientNavigationHeadTags({
1022
- assetBaseUrl: options.assetBaseUrl,
1023
- currentStyleSheets: clientStyleSheets,
1024
- currentScript: clientRoute ? clientScript : undefined,
1025
- currentNavigationScript: navigationScript,
1026
- routeScripts: options.clientScripts,
1027
- })}${html}`, preparedActions.htmlReplacements), {
1028
- headers: responseHeadersForMetadata(metadata, options.request),
1029
- }), preparedActions.csrfToken, preparedActions.csrfTokenIsNew === true);
1030
- const effectiveCachePolicy = cachePolicy ?? routeCacheContext.cachePolicy;
1031
- const finalResponse = preparedActions.hasFormActions
1032
- ? withRouteCacheHeader(response, effectiveCachePolicy)
1033
- : await cacheRouteResponse({
1034
- key: cacheKey,
1035
- cache: options.routeCache,
1036
- path: matched.route.path,
1037
- policy: effectiveCachePolicy,
1038
- request: options.request,
1039
- response,
998
+ filename: matched.route.file,
999
+ importPolicy: options.importPolicy,
1000
+ routes,
1001
+ serverModules: options.serverModules,
1002
+ serverModuleCacheVersion: options.serverModuleCacheVersion,
1003
+ devServerModuleCacheVersion: options.devServerModuleCacheVersion,
1004
+ serverSourceFiles: options.serverSourceFiles,
1005
+ define: options.define,
1006
+ vitePlugins: options.vitePlugins,
1040
1007
  });
1041
- finishRenderTimingPhase(timing, phaseStartedAt, "responseBuildMs");
1042
- emitRenderTiming(options, timing, finalResponse.status);
1043
- return finalResponse;
1044
- }
1045
- catch (error) {
1046
- if (isRedirectError(error)) {
1047
- const response = new Response(null, {
1048
- headers: { location: error.location },
1049
- status: error.status,
1008
+ finishRenderTimingPhase(timing, phaseStartedAt, "metadataMs");
1009
+ phaseStartedAt = renderTimingPhaseStartedAt(timing);
1010
+ html = injectHeadMetadata(html, metadata);
1011
+ warnIfCspNonceWouldBlockInlineTags({
1012
+ html,
1013
+ logger: options.logger,
1014
+ metadata,
1015
+ request: options.request,
1016
+ serverModuleCacheVersion: options.serverModuleCacheVersion,
1050
1017
  });
1051
- emitRenderTiming(options, timing, response.status);
1052
- return response;
1018
+ html = injectAuthSessionClaims(html, originalAnalysis.authIncludesClaims ? currentAuthClaims() : undefined);
1019
+ html = injectQueryState(html, dehydrate(queryClient));
1020
+ const response = withOptionalActionCookie(htmlResponse(applyActionHtmlReplacements(`<!DOCTYPE html>${clientNavigationHeadTags({
1021
+ assetBaseUrl: options.assetBaseUrl,
1022
+ currentStyleSheets: clientStyleSheets,
1023
+ currentScript: clientRoute ? clientScript : undefined,
1024
+ currentNavigationScript: navigationScript,
1025
+ routeScripts: options.clientScripts,
1026
+ })}${html}`, preparedActions.htmlReplacements), {
1027
+ headers: responseHeadersForMetadata(metadata, options.request),
1028
+ }), preparedActions.csrfToken, preparedActions.csrfTokenIsNew === true);
1029
+ const effectiveCachePolicy = cachePolicy ?? activeRouteCacheContext()?.cachePolicy;
1030
+ const finalResponse = preparedActions.hasFormActions
1031
+ ? withRouteCacheHeader(response, effectiveCachePolicy)
1032
+ : await cacheRouteResponse({
1033
+ key: cacheKey,
1034
+ cache: options.routeCache,
1035
+ path: matched.route.path,
1036
+ policy: effectiveCachePolicy,
1037
+ request: options.request,
1038
+ response,
1039
+ });
1040
+ finishRenderTimingPhase(timing, phaseStartedAt, "responseBuildMs");
1041
+ emitRenderTiming(options, timing, finalResponse.status);
1042
+ return finalResponse;
1053
1043
  }
1054
- if (isNotFoundError(error)) {
1055
- const notFoundFile = await nearestBoundaryFileForPage({
1044
+ catch (error) {
1045
+ if (isRedirectError(error)) {
1046
+ const response = new Response(null, {
1047
+ headers: { location: error.location },
1048
+ status: error.status,
1049
+ });
1050
+ emitRenderTiming(options, timing, response.status);
1051
+ return response;
1052
+ }
1053
+ if (isNotFoundError(error)) {
1054
+ const notFoundFile = await nearestBoundaryFileForPage({
1055
+ appDir: options.appDir,
1056
+ filename: "not-found.mreact.tsx",
1057
+ pageFile: matched.route.file,
1058
+ });
1059
+ const response = await renderSpecialRoute({
1060
+ appDir: options.appDir,
1061
+ assetBaseUrl: options.assetBaseUrl,
1062
+ currentStyleSheets: options.clientStylesByFile?.get(notFoundFile),
1063
+ error: undefined,
1064
+ request: options.request,
1065
+ routePath: matched.route.path,
1066
+ routeFile: notFoundFile,
1067
+ routeScripts: options.clientScripts,
1068
+ serverModules: options.serverModules,
1069
+ serverModuleCacheVersion: options.serverModuleCacheVersion,
1070
+ serverSourceFiles: options.serverSourceFiles,
1071
+ vitePlugins: options.vitePlugins,
1072
+ navigation: recoveryRoute,
1073
+ status: 404,
1074
+ textFallback: "Not Found",
1075
+ });
1076
+ emitRenderTiming(options, timing, response.status);
1077
+ return response;
1078
+ }
1079
+ const errorFile = await nearestBoundaryFileForPage({
1056
1080
  appDir: options.appDir,
1057
- filename: "not-found.mreact.tsx",
1081
+ filename: "error.mreact.tsx",
1058
1082
  pageFile: matched.route.file,
1059
1083
  });
1084
+ options.onRenderError?.(error);
1060
1085
  const response = await renderSpecialRoute({
1061
1086
  appDir: options.appDir,
1062
1087
  assetBaseUrl: options.assetBaseUrl,
1063
- currentStyleSheets: options.clientStylesByFile?.get(notFoundFile),
1064
- error: undefined,
1088
+ currentStyleSheets: options.clientStylesByFile?.get(errorFile),
1089
+ error,
1065
1090
  request: options.request,
1066
1091
  routePath: matched.route.path,
1067
- routeFile: notFoundFile,
1092
+ routeFile: errorFile,
1068
1093
  routeScripts: options.clientScripts,
1069
1094
  serverModules: options.serverModules,
1070
1095
  serverModuleCacheVersion: options.serverModuleCacheVersion,
1071
1096
  serverSourceFiles: options.serverSourceFiles,
1072
1097
  vitePlugins: options.vitePlugins,
1073
1098
  navigation: recoveryRoute,
1074
- status: 404,
1075
- textFallback: "Not Found",
1099
+ status: 500,
1100
+ textFallback: "Internal Server Error",
1076
1101
  });
1077
1102
  emitRenderTiming(options, timing, response.status);
1078
1103
  return response;
1079
1104
  }
1080
- const errorFile = await nearestBoundaryFileForPage({
1081
- appDir: options.appDir,
1082
- filename: "error.mreact.tsx",
1083
- pageFile: matched.route.file,
1084
- });
1085
- options.onRenderError?.(error);
1086
- const response = await renderSpecialRoute({
1087
- appDir: options.appDir,
1088
- assetBaseUrl: options.assetBaseUrl,
1089
- currentStyleSheets: options.clientStylesByFile?.get(errorFile),
1090
- error,
1091
- request: options.request,
1092
- routePath: matched.route.path,
1093
- routeFile: errorFile,
1094
- routeScripts: options.clientScripts,
1095
- serverModules: options.serverModules,
1096
- serverModuleCacheVersion: options.serverModuleCacheVersion,
1097
- serverSourceFiles: options.serverSourceFiles,
1098
- vitePlugins: options.vitePlugins,
1099
- navigation: recoveryRoute,
1100
- status: 500,
1101
- textFallback: "Internal Server Error",
1102
- });
1103
- emitRenderTiming(options, timing, response.status);
1104
- return response;
1105
- }
1106
- finally {
1107
- await routeCacheContext?.dispose();
1108
- }
1105
+ })).value;
1109
1106
  }
1110
1107
  async function applyAppRouterResponseHook(response, options) {
1111
1108
  const hooked = await options.onResponse?.(response, {