vinext 0.0.34 → 0.0.36

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 (48) hide show
  1. package/README.md +1 -0
  2. package/dist/build/prerender.d.ts +9 -4
  3. package/dist/build/prerender.js +27 -9
  4. package/dist/build/prerender.js.map +1 -1
  5. package/dist/build/run-prerender.js +4 -1
  6. package/dist/build/run-prerender.js.map +1 -1
  7. package/dist/config/config-matchers.js +1 -1
  8. package/dist/config/config-matchers.js.map +1 -1
  9. package/dist/config/next-config.d.ts +7 -1
  10. package/dist/config/next-config.js +39 -26
  11. package/dist/config/next-config.js.map +1 -1
  12. package/dist/entries/pages-server-entry.js +162 -354
  13. package/dist/entries/pages-server-entry.js.map +1 -1
  14. package/dist/index.d.ts +9 -1
  15. package/dist/index.js +40 -4
  16. package/dist/index.js.map +1 -1
  17. package/dist/plugins/optimize-imports.js +28 -2
  18. package/dist/plugins/optimize-imports.js.map +1 -1
  19. package/dist/server/app-browser-entry.js +2 -2
  20. package/dist/server/app-browser-entry.js.map +1 -1
  21. package/dist/server/app-page-render.js +6 -4
  22. package/dist/server/app-page-render.js.map +1 -1
  23. package/dist/server/app-page-response.js +1 -1
  24. package/dist/server/app-page-response.js.map +1 -1
  25. package/dist/server/app-page-stream.d.ts +9 -1
  26. package/dist/server/app-page-stream.js +37 -4
  27. package/dist/server/app-page-stream.js.map +1 -1
  28. package/dist/server/app-ssr-stream.js +5 -3
  29. package/dist/server/app-ssr-stream.js.map +1 -1
  30. package/dist/server/pages-page-data.d.ts +105 -0
  31. package/dist/server/pages-page-data.js +177 -0
  32. package/dist/server/pages-page-data.js.map +1 -0
  33. package/dist/server/pages-page-response.d.ts +55 -0
  34. package/dist/server/pages-page-response.js +140 -0
  35. package/dist/server/pages-page-response.js.map +1 -0
  36. package/dist/server/prod-server.js +3 -0
  37. package/dist/server/prod-server.js.map +1 -1
  38. package/dist/server/seed-cache.d.ts +44 -0
  39. package/dist/server/seed-cache.js +127 -0
  40. package/dist/server/seed-cache.js.map +1 -0
  41. package/dist/shims/image.js +4 -2
  42. package/dist/shims/image.js.map +1 -1
  43. package/dist/shims/navigation-state.js +5 -3
  44. package/dist/shims/navigation-state.js.map +1 -1
  45. package/dist/shims/navigation.d.ts +9 -7
  46. package/dist/shims/navigation.js +20 -5
  47. package/dist/shims/navigation.js.map +1 -1
  48. package/package.json +1 -1
@@ -18,6 +18,8 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
18
18
  const _requestContextShimPath = fileURLToPath(new URL("../shims/request-context.js", import.meta.url)).replace(/\\/g, "/");
19
19
  const _routeTriePath = fileURLToPath(new URL("../routing/route-trie.js", import.meta.url)).replace(/\\/g, "/");
20
20
  const _pagesI18nPath = fileURLToPath(new URL("../server/pages-i18n.js", import.meta.url)).replace(/\\/g, "/");
21
+ const _pagesPageResponsePath = fileURLToPath(new URL("../server/pages-page-response.js", import.meta.url)).replace(/\\/g, "/");
22
+ const _pagesPageDataPath = fileURLToPath(new URL("../server/pages-page-data.js", import.meta.url)).replace(/\\/g, "/");
21
23
  /**
22
24
  * Generate the virtual SSR server entry module.
23
25
  * This is the entry point for `vite build --ssr`.
@@ -210,6 +212,8 @@ import { runWithExecutionContext as _runWithExecutionContext, getRequestExecutio
210
212
  import { buildRouteTrie as _buildRouteTrie, trieMatch as _trieMatch } from ${JSON.stringify(_routeTriePath)};
211
213
  import { reportRequestError as _reportRequestError } from "vinext/instrumentation";
212
214
  import { resolvePagesI18nRequest } from ${JSON.stringify(_pagesI18nPath)};
215
+ import { resolvePagesPageData as __resolvePagesPageData } from ${JSON.stringify(_pagesPageDataPath)};
216
+ import { renderPagesPageResponse as __renderPagesPageResponse } from ${JSON.stringify(_pagesPageResponsePath)};
213
217
  ${instrumentationImportCode}
214
218
  ${middlewareImportCode}
215
219
 
@@ -666,19 +670,20 @@ async function _renderPage(request, url, manifest) {
666
670
  { status: 404, headers: { "Content-Type": "text/html" } });
667
671
  }
668
672
 
669
- const { route, params } = match;
670
- const __uCtx = _createUnifiedCtx({
671
- executionContext: _getRequestExecutionContext(),
672
- });
673
- return _runWithUnifiedCtx(__uCtx, async () => {
674
- ensureFetchPatch();
675
- try {
676
- if (typeof setSSRContext === "function") {
677
- setSSRContext({
678
- pathname: patternToNextFormat(route.pattern),
679
- query: { ...params, ...parseQuery(routeUrl) },
680
- asPath: routeUrl,
681
- locale: locale,
673
+ const { route, params } = match;
674
+ const __uCtx = _createUnifiedCtx({
675
+ executionContext: _getRequestExecutionContext(),
676
+ });
677
+ return _runWithUnifiedCtx(__uCtx, async () => {
678
+ ensureFetchPatch();
679
+ try {
680
+ const routePattern = patternToNextFormat(route.pattern);
681
+ if (typeof setSSRContext === "function") {
682
+ setSSRContext({
683
+ pathname: routePattern,
684
+ query: { ...params, ...parseQuery(routeUrl) },
685
+ asPath: routeUrl,
686
+ locale: locale,
682
687
  locales: i18nConfig ? i18nConfig.locales : undefined,
683
688
  defaultLocale: currentDefaultLocale,
684
689
  domainLocales: domainLocales,
@@ -697,355 +702,158 @@ async function _renderPage(request, url, manifest) {
697
702
 
698
703
  const pageModule = route.module;
699
704
  const PageComponent = pageModule.default;
700
- if (!PageComponent) {
701
- return new Response("Page has no default export", { status: 500 });
702
- }
703
-
704
- // Handle getStaticPaths for dynamic routes
705
- if (typeof pageModule.getStaticPaths === "function" && route.isDynamic) {
706
- const pathsResult = await pageModule.getStaticPaths({
707
- locales: i18nConfig ? i18nConfig.locales : [],
708
- defaultLocale: currentDefaultLocale || "",
709
- });
710
- const fallback = pathsResult && pathsResult.fallback !== undefined ? pathsResult.fallback : false;
711
-
712
- if (fallback === false) {
713
- const paths = pathsResult && pathsResult.paths ? pathsResult.paths : [];
714
- const isValidPath = paths.some(function(p) {
715
- return Object.entries(p.params).every(function(entry) {
716
- var key = entry[0], val = entry[1];
717
- var actual = params[key];
718
- if (Array.isArray(val)) {
719
- return Array.isArray(actual) && val.join("/") === actual.join("/");
720
- }
721
- return String(val) === String(actual);
722
- });
723
- });
724
- if (!isValidPath) {
725
- return new Response("<!DOCTYPE html><html><body><h1>404 - Page not found</h1></body></html>",
726
- { status: 404, headers: { "Content-Type": "text/html" } });
727
- }
728
- }
729
- }
730
-
731
- let pageProps = {};
732
- var gsspRes = null;
733
- if (typeof pageModule.getServerSideProps === "function") {
734
- const { req, res, responsePromise } = createReqRes(request, routeUrl, parseQuery(routeUrl), undefined);
735
- const ctx = {
736
- params, req, res,
737
- query: parseQuery(routeUrl),
738
- resolvedUrl: routeUrl,
739
- locale: locale,
740
- locales: i18nConfig ? i18nConfig.locales : undefined,
741
- defaultLocale: currentDefaultLocale,
742
- };
743
- const result = await pageModule.getServerSideProps(ctx);
744
- // If gSSP called res.end() directly (short-circuit), return that response.
745
- if (res.headersSent) {
746
- return await responsePromise;
747
- }
748
- if (result && result.props) pageProps = result.props;
749
- if (result && result.redirect) {
750
- var gsspStatus = result.redirect.statusCode != null ? result.redirect.statusCode : (result.redirect.permanent ? 308 : 307);
751
- return new Response(null, { status: gsspStatus, headers: { Location: sanitizeDestinationLocal(result.redirect.destination) } });
752
- }
753
- if (result && result.notFound) {
754
- return new Response("404", { status: 404 });
755
- }
756
- // Preserve the res object so headers/status/cookies set by gSSP
757
- // can be merged into the final HTML response.
758
- gsspRes = res;
759
- }
760
- // Build font Link header early so it's available for ISR cached responses too.
761
- // Font preloads are module-level state populated at import time and persist across requests.
762
- var _fontLinkHeader = "";
763
- var _allFp = [];
705
+ if (!PageComponent) {
706
+ return new Response("Page has no default export", { status: 500 });
707
+ }
708
+ // Build font Link header early so it's available for ISR cached responses too.
709
+ // Font preloads are module-level state populated at import time and persist across requests.
710
+ var _fontLinkHeader = "";
711
+ var _allFp = [];
764
712
  try {
765
713
  var _fpGoogle = typeof _getSSRFontPreloadsGoogle === "function" ? _getSSRFontPreloadsGoogle() : [];
766
714
  var _fpLocal = typeof _getSSRFontPreloadsLocal === "function" ? _getSSRFontPreloadsLocal() : [];
767
715
  _allFp = _fpGoogle.concat(_fpLocal);
768
- if (_allFp.length > 0) {
769
- _fontLinkHeader = _allFp.map(function(p) { return "<" + p.href + ">; rel=preload; as=font; type=" + p.type + "; crossorigin"; }).join(", ");
770
- }
771
- } catch (e) { /* font preloads not available */ }
772
-
773
- let isrRevalidateSeconds = null;
774
- if (typeof pageModule.getStaticProps === "function") {
775
- const pathname = routeUrl.split("?")[0];
776
- const cacheKey = isrCacheKey("pages", pathname);
777
- const cached = await isrGet(cacheKey);
778
-
779
- if (cached && !cached.isStale && cached.value.value && cached.value.value.kind === "PAGES") {
780
- var _hitHeaders = {
781
- "Content-Type": "text/html", "X-Vinext-Cache": "HIT",
782
- "Cache-Control": "s-maxage=" + (cached.value.value.revalidate || 60) + ", stale-while-revalidate",
783
- };
784
- if (_fontLinkHeader) _hitHeaders["Link"] = _fontLinkHeader;
785
- return new Response(cached.value.value.html, { status: 200, headers: _hitHeaders });
786
- }
787
-
788
- if (cached && cached.isStale && cached.value.value && cached.value.value.kind === "PAGES") {
789
- triggerBackgroundRegeneration(cacheKey, async function() {
790
- var revalCtx = _createUnifiedCtx({
791
- executionContext: _getRequestExecutionContext(),
792
- });
793
- return _runWithUnifiedCtx(revalCtx, async () => {
794
- ensureFetchPatch();
795
- var freshResult = await pageModule.getStaticProps({
796
- params: params,
797
- locale: locale,
798
- locales: i18nConfig ? i18nConfig.locales : undefined,
799
- defaultLocale: currentDefaultLocale,
800
- });
801
- if (freshResult && freshResult.props && typeof freshResult.revalidate === "number" && freshResult.revalidate > 0) {
802
- var _fp = freshResult.props;
803
- if (typeof setSSRContext === "function") {
804
- setSSRContext({
805
- pathname: patternToNextFormat(route.pattern),
806
- query: { ...params, ...parseQuery(routeUrl) },
807
- asPath: routeUrl,
808
- locale: locale,
809
- locales: i18nConfig ? i18nConfig.locales : undefined,
810
- defaultLocale: currentDefaultLocale,
811
- domainLocales: domainLocales,
812
- });
813
- }
814
- if (i18nConfig) {
815
- setI18nContext({
816
- locale: locale,
817
- locales: i18nConfig.locales,
818
- defaultLocale: currentDefaultLocale,
819
- domainLocales: domainLocales,
820
- hostname: new URL(request.url).hostname,
821
- });
822
- }
823
- // Re-render the page with fresh props inside fresh render sub-scopes
824
- // so head/cache state cannot leak across passes.
825
- var _el = AppComponent
826
- ? React.createElement(AppComponent, { Component: PageComponent, pageProps: _fp })
827
- : React.createElement(PageComponent, _fp);
828
- _el = wrapWithRouterContext(_el);
829
- var _freshBody = await renderIsrPassToStringAsync(_el);
830
- // Rebuild __NEXT_DATA__ with fresh props
831
- var _regenPayload = {
832
- props: { pageProps: _fp }, page: patternToNextFormat(route.pattern),
833
- query: params, buildId: buildId, isFallback: false,
834
- };
835
- if (i18nConfig) {
836
- _regenPayload.locale = locale;
837
- _regenPayload.locales = i18nConfig.locales;
838
- _regenPayload.defaultLocale = currentDefaultLocale;
839
- _regenPayload.domainLocales = domainLocales;
840
- }
841
- var _lGlobals = i18nConfig
842
- ? ";window.__VINEXT_LOCALE__=" + safeJsonStringify(locale) +
843
- ";window.__VINEXT_LOCALES__=" + safeJsonStringify(i18nConfig.locales) +
844
- ";window.__VINEXT_DEFAULT_LOCALE__=" + safeJsonStringify(currentDefaultLocale)
845
- : "";
846
- var _freshNDS = "<script>window.__NEXT_DATA__ = " + safeJsonStringify(_regenPayload) + _lGlobals + "<\/script>";
847
- // Reconstruct ISR HTML preserving the document shell from the
848
- // cached entry (head, fonts, assets, custom _document markup).
849
- var _cachedStr = cached.value.value.html;
850
- var _btag = '<div id="__next">';
851
- var _bstart = _cachedStr.indexOf(_btag);
852
- var _bodyStart = _bstart >= 0 ? _bstart + _btag.length : -1;
853
- // Locate __NEXT_DATA__ script to split body from suffix
854
- var _ndMarker = '<script>window.__NEXT_DATA__';
855
- var _ndStart = _cachedStr.indexOf(_ndMarker);
856
- var _freshHtml;
857
- if (_bodyStart >= 0 && _ndStart >= 0) {
858
- // Region between body start and __NEXT_DATA__ contains:
859
- // BODY_HTML + </div> + optional gap (custom _document content)
860
- var _region = _cachedStr.slice(_bodyStart, _ndStart);
861
- var _lastClose = _region.lastIndexOf('</div>');
862
- var _gap = _lastClose >= 0 ? _region.slice(_lastClose + 6) : '';
863
- // Tail: everything after the old __NEXT_DATA__ <\/script>
864
- var _ndEnd = _cachedStr.indexOf('<\/script>', _ndStart) + 9;
865
- var _tail = _cachedStr.slice(_ndEnd);
866
- _freshHtml = _cachedStr.slice(0, _bodyStart) + _freshBody + '</div>' + _gap + _freshNDS + _tail;
867
- } else {
868
- _freshHtml = '<!DOCTYPE html>\\n<html>\\n<head>\\n</head>\\n<body>\\n <div id="__next">' + _freshBody + '</div>\\n ' + _freshNDS + '\\n</body>\\n</html>';
869
- }
870
- await isrSet(cacheKey, { kind: "PAGES", html: _freshHtml, pageData: _fp, headers: undefined, status: undefined }, freshResult.revalidate);
871
- }
872
- });
873
- });
874
- var _staleHeaders = {
875
- "Content-Type": "text/html", "X-Vinext-Cache": "STALE",
876
- "Cache-Control": "s-maxage=0, stale-while-revalidate",
877
- };
878
- if (_fontLinkHeader) _staleHeaders["Link"] = _fontLinkHeader;
879
- return new Response(cached.value.value.html, { status: 200, headers: _staleHeaders });
880
- }
881
-
882
- const ctx = {
883
- params,
884
- locale: locale,
885
- locales: i18nConfig ? i18nConfig.locales : undefined,
886
- defaultLocale: currentDefaultLocale,
887
- };
888
- const result = await pageModule.getStaticProps(ctx);
889
- if (result && result.props) pageProps = result.props;
890
- if (result && result.redirect) {
891
- var gspStatus = result.redirect.statusCode != null ? result.redirect.statusCode : (result.redirect.permanent ? 308 : 307);
892
- return new Response(null, { status: gspStatus, headers: { Location: sanitizeDestinationLocal(result.redirect.destination) } });
893
- }
894
- if (result && result.notFound) {
895
- return new Response("404", { status: 404 });
896
- }
897
- if (typeof result.revalidate === "number" && result.revalidate > 0) {
898
- isrRevalidateSeconds = result.revalidate;
899
- }
900
- }
901
-
902
- let element;
903
- if (AppComponent) {
904
- element = React.createElement(AppComponent, { Component: PageComponent, pageProps });
905
- } else {
906
- element = React.createElement(PageComponent, pageProps);
907
- }
908
- element = wrapWithRouterContext(element);
909
-
910
- if (typeof resetSSRHead === "function") resetSSRHead();
911
- if (typeof flushPreloads === "function") await flushPreloads();
912
-
913
- const ssrHeadHTML = typeof getSSRHeadHTML === "function" ? getSSRHeadHTML() : "";
914
-
915
- // Collect SSR font data (Google Font links, font preloads, font-face styles)
916
- var fontHeadHTML = "";
917
- function _escAttr(s) { return s.replace(/&/g, "&amp;").replace(/"/g, "&quot;"); }
918
- try {
919
- var fontLinks = typeof _getSSRFontLinks === "function" ? _getSSRFontLinks() : [];
920
- for (var fl of fontLinks) { fontHeadHTML += '<link rel="stylesheet" href="' + _escAttr(fl) + '" />\\n '; }
921
- } catch (e) { /* next/font/google not used */ }
922
- // Emit <link rel="preload"> for all font files (reuse _allFp collected earlier for Link header)
923
- for (var fp of _allFp) { fontHeadHTML += '<link rel="preload" href="' + _escAttr(fp.href) + '" as="font" type="' + _escAttr(fp.type) + '" crossorigin />\\n '; }
924
- try {
925
- var allFontStyles = [];
926
- if (typeof _getSSRFontStylesGoogle === "function") allFontStyles.push(..._getSSRFontStylesGoogle());
927
- if (typeof _getSSRFontStylesLocal === "function") allFontStyles.push(..._getSSRFontStylesLocal());
928
- if (allFontStyles.length > 0) { fontHeadHTML += '<style data-vinext-fonts>' + allFontStyles.join("\\n") + '</style>\\n '; }
929
- } catch (e) { /* font styles not available */ }
930
-
931
- const pageModuleIds = route.filePath ? [route.filePath] : [];
932
- const assetTags = collectAssetTags(manifest, pageModuleIds);
933
- const nextDataPayload = {
934
- props: { pageProps }, page: patternToNextFormat(route.pattern), query: params, buildId, isFallback: false,
935
- };
936
- if (i18nConfig) {
937
- nextDataPayload.locale = locale;
938
- nextDataPayload.locales = i18nConfig.locales;
939
- nextDataPayload.defaultLocale = currentDefaultLocale;
940
- nextDataPayload.domainLocales = domainLocales;
941
- }
942
- const localeGlobals = i18nConfig
943
- ? ";window.__VINEXT_LOCALE__=" + safeJsonStringify(locale) +
944
- ";window.__VINEXT_LOCALES__=" + safeJsonStringify(i18nConfig.locales) +
945
- ";window.__VINEXT_DEFAULT_LOCALE__=" + safeJsonStringify(currentDefaultLocale)
946
- : "";
947
- const nextDataScript = "<script>window.__NEXT_DATA__ = " + safeJsonStringify(nextDataPayload) + localeGlobals + "<\/script>";
948
-
949
- // Build the document shell with a placeholder for the streamed body
950
- var BODY_MARKER = "<!--VINEXT_STREAM_BODY-->";
951
- var shellHtml;
952
- if (DocumentComponent) {
953
- const docElement = React.createElement(DocumentComponent);
954
- shellHtml = await renderToStringAsync(docElement);
955
- shellHtml = shellHtml.replace("__NEXT_MAIN__", BODY_MARKER);
956
- if (ssrHeadHTML || assetTags || fontHeadHTML) {
957
- shellHtml = shellHtml.replace("</head>", " " + fontHeadHTML + ssrHeadHTML + "\\n " + assetTags + "\\n</head>");
958
- }
959
- shellHtml = shellHtml.replace("<!-- __NEXT_SCRIPTS__ -->", nextDataScript);
960
- if (!shellHtml.includes("__NEXT_DATA__")) {
961
- shellHtml = shellHtml.replace("</body>", " " + nextDataScript + "\\n</body>");
962
- }
963
- } else {
964
- shellHtml = "<!DOCTYPE html>\\n<html>\\n<head>\\n <meta charset=\\"utf-8\\" />\\n <meta name=\\"viewport\\" content=\\"width=device-width, initial-scale=1\\" />\\n " + fontHeadHTML + ssrHeadHTML + "\\n " + assetTags + "\\n</head>\\n<body>\\n <div id=\\"__next\\">" + BODY_MARKER + "</div>\\n " + nextDataScript + "\\n</body>\\n</html>";
965
- }
966
-
967
- if (typeof setSSRContext === "function") setSSRContext(null);
968
-
969
- // Split the shell at the body marker
970
- var markerIdx = shellHtml.indexOf(BODY_MARKER);
971
- var shellPrefix = shellHtml.slice(0, markerIdx);
972
- var shellSuffix = shellHtml.slice(markerIdx + BODY_MARKER.length);
973
-
974
- // Start the React body stream — progressive SSR (no allReady wait)
975
- var bodyStream = await renderToReadableStream(element);
976
- var encoder = new TextEncoder();
977
-
978
- // Create a composite stream: prefix + body + suffix
979
- var compositeStream = new ReadableStream({
980
- async start(controller) {
981
- controller.enqueue(encoder.encode(shellPrefix));
982
- var reader = bodyStream.getReader();
716
+ if (_allFp.length > 0) {
717
+ _fontLinkHeader = _allFp.map(function(p) { return "<" + p.href + ">; rel=preload; as=font; type=" + p.type + "; crossorigin"; }).join(", ");
718
+ }
719
+ } catch (e) { /* font preloads not available */ }
720
+ const query = parseQuery(routeUrl);
721
+ const pageDataResult = await __resolvePagesPageData({
722
+ applyRequestContexts() {
723
+ if (typeof setSSRContext === "function") {
724
+ setSSRContext({
725
+ pathname: routePattern,
726
+ query: { ...params, ...query },
727
+ asPath: routeUrl,
728
+ locale: locale,
729
+ locales: i18nConfig ? i18nConfig.locales : undefined,
730
+ defaultLocale: currentDefaultLocale,
731
+ domainLocales: domainLocales,
732
+ });
733
+ }
734
+ if (i18nConfig) {
735
+ setI18nContext({
736
+ locale: locale,
737
+ locales: i18nConfig.locales,
738
+ defaultLocale: currentDefaultLocale,
739
+ domainLocales: domainLocales,
740
+ hostname: new URL(request.url).hostname,
741
+ });
742
+ }
743
+ },
744
+ buildId,
745
+ createGsspReqRes() {
746
+ return createReqRes(request, routeUrl, query, undefined);
747
+ },
748
+ createPageElement(currentPageProps) {
749
+ var currentElement = AppComponent
750
+ ? React.createElement(AppComponent, { Component: PageComponent, pageProps: currentPageProps })
751
+ : React.createElement(PageComponent, currentPageProps);
752
+ return wrapWithRouterContext(currentElement);
753
+ },
754
+ fontLinkHeader: _fontLinkHeader,
755
+ i18n: {
756
+ locale: locale,
757
+ locales: i18nConfig ? i18nConfig.locales : undefined,
758
+ defaultLocale: currentDefaultLocale,
759
+ domainLocales: domainLocales,
760
+ },
761
+ isrCacheKey,
762
+ isrGet,
763
+ isrSet,
764
+ pageModule,
765
+ params,
766
+ query,
767
+ renderIsrPassToStringAsync,
768
+ route: {
769
+ isDynamic: route.isDynamic,
770
+ },
771
+ routePattern,
772
+ routeUrl,
773
+ runInFreshUnifiedContext(callback) {
774
+ var revalCtx = _createUnifiedCtx({
775
+ executionContext: _getRequestExecutionContext(),
776
+ });
777
+ return _runWithUnifiedCtx(revalCtx, async () => {
778
+ ensureFetchPatch();
779
+ return callback();
780
+ });
781
+ },
782
+ safeJsonStringify,
783
+ sanitizeDestination: sanitizeDestinationLocal,
784
+ triggerBackgroundRegeneration,
785
+ });
786
+ if (pageDataResult.kind === "response") {
787
+ return pageDataResult.response;
788
+ }
789
+ let pageProps = pageDataResult.pageProps;
790
+ var gsspRes = pageDataResult.gsspRes;
791
+ let isrRevalidateSeconds = pageDataResult.isrRevalidateSeconds;
792
+
793
+ const pageModuleIds = route.filePath ? [route.filePath] : [];
794
+ const assetTags = collectAssetTags(manifest, pageModuleIds);
795
+
796
+ return __renderPagesPageResponse({
797
+ assetTags,
798
+ buildId,
799
+ clearSsrContext() {
800
+ if (typeof setSSRContext === "function") setSSRContext(null);
801
+ },
802
+ createPageElement(currentPageProps) {
803
+ var currentElement;
804
+ if (AppComponent) {
805
+ currentElement = React.createElement(AppComponent, { Component: PageComponent, pageProps: currentPageProps });
806
+ } else {
807
+ currentElement = React.createElement(PageComponent, currentPageProps);
808
+ }
809
+ return wrapWithRouterContext(currentElement);
810
+ },
811
+ DocumentComponent,
812
+ flushPreloads: typeof flushPreloads === "function" ? flushPreloads : undefined,
813
+ fontLinkHeader: _fontLinkHeader,
814
+ fontPreloads: _allFp,
815
+ getFontLinks() {
983
816
  try {
984
- for (;;) {
985
- var chunk = await reader.read();
986
- if (chunk.done) break;
987
- controller.enqueue(chunk.value);
988
- }
989
- } finally {
990
- reader.releaseLock();
817
+ return typeof _getSSRFontLinks === "function" ? _getSSRFontLinks() : [];
818
+ } catch (e) {
819
+ return [];
991
820
  }
992
- controller.enqueue(encoder.encode(shellSuffix));
993
- controller.close();
994
- }
995
- });
996
-
997
- // Cache the rendered HTML for ISR (needs the full string — re-render synchronously)
998
- if (isrRevalidateSeconds !== null && isrRevalidateSeconds > 0) {
999
- // Tee the stream so we can cache and respond simultaneously would be ideal,
1000
- // but ISR responses are rare on first hit. Re-render to get complete HTML for cache.
1001
- var isrElement;
1002
- if (AppComponent) {
1003
- isrElement = React.createElement(AppComponent, { Component: PageComponent, pageProps });
1004
- } else {
1005
- isrElement = React.createElement(PageComponent, pageProps);
1006
- }
1007
- isrElement = wrapWithRouterContext(isrElement);
1008
- var isrHtml = await renderIsrPassToStringAsync(isrElement);
1009
- var fullHtml = shellPrefix + isrHtml + shellSuffix;
1010
- var isrPathname = url.split("?")[0];
1011
- var _cacheKey = isrCacheKey("pages", isrPathname);
1012
- await isrSet(_cacheKey, { kind: "PAGES", html: fullHtml, pageData: pageProps, headers: undefined, status: undefined }, isrRevalidateSeconds);
1013
- }
1014
-
1015
- // Merge headers/status/cookies set by getServerSideProps on the res object.
1016
- // gSSP commonly uses res.setHeader("Set-Cookie", ...) or res.status(304).
1017
- var finalStatus = 200;
1018
- const responseHeaders = new Headers({ "Content-Type": "text/html" });
1019
- if (gsspRes) {
1020
- finalStatus = gsspRes.statusCode;
1021
- var gsspHeaders = gsspRes.getHeaders();
1022
- for (var hk of Object.keys(gsspHeaders)) {
1023
- var hv = gsspHeaders[hk];
1024
- if (hk === "set-cookie" && Array.isArray(hv)) {
1025
- for (var sc of hv) responseHeaders.append("set-cookie", sc);
1026
- } else if (hv != null) {
1027
- responseHeaders.set(hk, String(hv));
821
+ },
822
+ getFontStyles() {
823
+ try {
824
+ var allFontStyles = [];
825
+ if (typeof _getSSRFontStylesGoogle === "function") allFontStyles.push(..._getSSRFontStylesGoogle());
826
+ if (typeof _getSSRFontStylesLocal === "function") allFontStyles.push(..._getSSRFontStylesLocal());
827
+ return allFontStyles;
828
+ } catch (e) {
829
+ return [];
1028
830
  }
1029
- }
1030
- // Ensure Content-Type stays text/html (gSSP shouldn't override it for page renders)
1031
- responseHeaders.set("Content-Type", "text/html");
1032
- }
1033
- if (isrRevalidateSeconds) {
1034
- responseHeaders.set("Cache-Control", "s-maxage=" + isrRevalidateSeconds + ", stale-while-revalidate");
1035
- responseHeaders.set("X-Vinext-Cache", "MISS");
1036
- }
1037
- // Set HTTP Link header for font preloading
1038
- if (_fontLinkHeader) {
1039
- responseHeaders.set("Link", _fontLinkHeader);
1040
- }
1041
- const streamedPageResponse = new Response(compositeStream, {
1042
- status: finalStatus,
1043
- headers: responseHeaders,
831
+ },
832
+ getSSRHeadHTML: typeof getSSRHeadHTML === "function" ? getSSRHeadHTML : undefined,
833
+ gsspRes,
834
+ isrCacheKey,
835
+ isrRevalidateSeconds,
836
+ isrSet,
837
+ i18n: {
838
+ locale: locale,
839
+ locales: i18nConfig ? i18nConfig.locales : undefined,
840
+ defaultLocale: currentDefaultLocale,
841
+ domainLocales: domainLocales,
842
+ },
843
+ pageProps,
844
+ params,
845
+ renderDocumentToString(element) {
846
+ return renderToStringAsync(element);
847
+ },
848
+ renderIsrPassToStringAsync,
849
+ renderToReadableStream(element) {
850
+ return renderToReadableStream(element);
851
+ },
852
+ resetSSRHead: typeof resetSSRHead === "function" ? resetSSRHead : undefined,
853
+ routePattern,
854
+ routeUrl,
855
+ safeJsonStringify,
1044
856
  });
1045
- // Mark the normal streamed HTML render so the Node prod server can strip
1046
- // stale Content-Length only for this path, not for custom gSSP responses.
1047
- streamedPageResponse.__vinextStreamedHtmlResponse = true;
1048
- return streamedPageResponse;
1049
857
  } catch (e) {
1050
858
  console.error("[vinext] SSR error:", e);
1051
859
  _reportRequestError(