@vercel/next 4.0.11 → 4.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +280 -68
- package/dist/server-launcher.js +8 -5
- package/package.json +2 -2
package/dist/index.js
CHANGED
@@ -9677,7 +9677,7 @@ async function getRoutesManifest(entryPath, outputDirectory, nextVersion) {
|
|
9677
9677
|
}
|
9678
9678
|
return routesManifest;
|
9679
9679
|
}
|
9680
|
-
async function getDynamicRoutes(entryPath, entryDirectory, dynamicPages, isDev, routesManifest, omittedRoutes, canUsePreviewMode, bypassToken, isServerMode, dynamicMiddlewareRouteMap) {
|
9680
|
+
async function getDynamicRoutes(entryPath, entryDirectory, dynamicPages, isDev, routesManifest, omittedRoutes, canUsePreviewMode, bypassToken, isServerMode, dynamicMiddlewareRouteMap, experimentalPPR) {
|
9681
9681
|
if (routesManifest) {
|
9682
9682
|
switch (routesManifest.version) {
|
9683
9683
|
case 1:
|
@@ -9730,6 +9730,20 @@ async function getDynamicRoutes(entryPath, entryDirectory, dynamicPages, isDev,
|
|
9730
9730
|
}
|
9731
9731
|
];
|
9732
9732
|
}
|
9733
|
+
if (experimentalPPR) {
|
9734
|
+
let dest = route.dest?.replace(/($|\?)/, ".prefetch.rsc$1");
|
9735
|
+
if (page === "/" || page === "/index") {
|
9736
|
+
dest = dest?.replace(/([^/]+\.prefetch\.rsc(\?.*|$))/, "__$1");
|
9737
|
+
}
|
9738
|
+
routes2.push({
|
9739
|
+
...route,
|
9740
|
+
src: route.src.replace(
|
9741
|
+
new RegExp((0, import_escape_string_regexp.default)("(?:/)?$")),
|
9742
|
+
"(?:\\.prefetch\\.rsc)(?:/)?$"
|
9743
|
+
),
|
9744
|
+
dest
|
9745
|
+
});
|
9746
|
+
}
|
9733
9747
|
routes2.push({
|
9734
9748
|
...route,
|
9735
9749
|
src: route.src.replace(
|
@@ -9739,7 +9753,6 @@ async function getDynamicRoutes(entryPath, entryDirectory, dynamicPages, isDev,
|
|
9739
9753
|
dest: route.dest?.replace(/($|\?)/, ".rsc$1")
|
9740
9754
|
});
|
9741
9755
|
routes2.push(route);
|
9742
|
-
continue;
|
9743
9756
|
}
|
9744
9757
|
return routes2;
|
9745
9758
|
}
|
@@ -10152,47 +10165,68 @@ async function getPrerenderManifest(entryPath, outputDirectory) {
|
|
10152
10165
|
let initialStatus;
|
10153
10166
|
let initialHeaders;
|
10154
10167
|
let experimentalBypassFor;
|
10168
|
+
let experimentalPPR;
|
10169
|
+
let prefetchDataRoute;
|
10155
10170
|
if (manifest.version === 4) {
|
10156
10171
|
initialStatus = manifest.routes[route].initialStatus;
|
10157
10172
|
initialHeaders = manifest.routes[route].initialHeaders;
|
10158
10173
|
experimentalBypassFor = manifest.routes[route].experimentalBypassFor;
|
10174
|
+
experimentalPPR = manifest.routes[route].experimentalPPR;
|
10175
|
+
prefetchDataRoute = manifest.routes[route].prefetchDataRoute;
|
10159
10176
|
}
|
10160
10177
|
ret.staticRoutes[route] = {
|
10161
10178
|
initialRevalidate: initialRevalidateSeconds === false ? false : Math.max(1, initialRevalidateSeconds),
|
10162
10179
|
dataRoute,
|
10180
|
+
prefetchDataRoute,
|
10163
10181
|
srcRoute,
|
10164
10182
|
initialStatus,
|
10165
10183
|
initialHeaders,
|
10166
|
-
experimentalBypassFor
|
10184
|
+
experimentalBypassFor,
|
10185
|
+
experimentalPPR
|
10167
10186
|
};
|
10168
10187
|
});
|
10169
10188
|
lazyRoutes.forEach((lazyRoute) => {
|
10170
10189
|
const { routeRegex, fallback, dataRoute, dataRouteRegex } = manifest.dynamicRoutes[lazyRoute];
|
10171
10190
|
let experimentalBypassFor;
|
10191
|
+
let experimentalPPR;
|
10192
|
+
let prefetchDataRoute;
|
10193
|
+
let prefetchDataRouteRegex;
|
10172
10194
|
if (manifest.version === 4) {
|
10173
10195
|
experimentalBypassFor = manifest.dynamicRoutes[lazyRoute].experimentalBypassFor;
|
10196
|
+
experimentalPPR = manifest.dynamicRoutes[lazyRoute].experimentalPPR;
|
10197
|
+
prefetchDataRoute = manifest.dynamicRoutes[lazyRoute].prefetchDataRoute;
|
10198
|
+
prefetchDataRouteRegex = manifest.dynamicRoutes[lazyRoute].prefetchDataRouteRegex;
|
10174
10199
|
}
|
10175
10200
|
if (typeof fallback === "string") {
|
10176
10201
|
ret.fallbackRoutes[lazyRoute] = {
|
10177
10202
|
experimentalBypassFor,
|
10203
|
+
experimentalPPR,
|
10178
10204
|
routeRegex,
|
10179
10205
|
fallback,
|
10180
10206
|
dataRoute,
|
10181
|
-
dataRouteRegex
|
10207
|
+
dataRouteRegex,
|
10208
|
+
prefetchDataRoute,
|
10209
|
+
prefetchDataRouteRegex
|
10182
10210
|
};
|
10183
10211
|
} else if (fallback === null) {
|
10184
10212
|
ret.blockingFallbackRoutes[lazyRoute] = {
|
10185
10213
|
experimentalBypassFor,
|
10214
|
+
experimentalPPR,
|
10186
10215
|
routeRegex,
|
10187
10216
|
dataRoute,
|
10188
|
-
dataRouteRegex
|
10217
|
+
dataRouteRegex,
|
10218
|
+
prefetchDataRoute,
|
10219
|
+
prefetchDataRouteRegex
|
10189
10220
|
};
|
10190
10221
|
} else {
|
10191
10222
|
ret.omittedRoutes[lazyRoute] = {
|
10192
10223
|
experimentalBypassFor,
|
10224
|
+
experimentalPPR,
|
10193
10225
|
routeRegex,
|
10194
10226
|
dataRoute,
|
10195
|
-
dataRouteRegex
|
10227
|
+
dataRouteRegex,
|
10228
|
+
prefetchDataRoute,
|
10229
|
+
prefetchDataRouteRegex
|
10196
10230
|
};
|
10197
10231
|
}
|
10198
10232
|
});
|
@@ -10322,6 +10356,7 @@ async function getPageLambdaGroups({
|
|
10322
10356
|
functionsConfigManifest,
|
10323
10357
|
pages,
|
10324
10358
|
prerenderRoutes,
|
10359
|
+
experimentalPPRRoutes,
|
10325
10360
|
pageTraces,
|
10326
10361
|
compressedPages,
|
10327
10362
|
tracedPseudoLayer,
|
@@ -10336,6 +10371,7 @@ async function getPageLambdaGroups({
|
|
10336
10371
|
const newPages = [...internalPages, page];
|
10337
10372
|
const routeName = normalizePage(page.replace(/\.js$/, ""));
|
10338
10373
|
const isPrerenderRoute = prerenderRoutes.has(routeName);
|
10374
|
+
const isExperimentalPPR = experimentalPPRRoutes?.has(routeName) ?? false;
|
10339
10375
|
let opts = {};
|
10340
10376
|
if (functionsConfigManifest && functionsConfigManifest.functions[routeName]) {
|
10341
10377
|
opts = functionsConfigManifest.functions[routeName];
|
@@ -10353,7 +10389,7 @@ async function getPageLambdaGroups({
|
|
10353
10389
|
opts = { ...vercelConfigOpts, ...opts };
|
10354
10390
|
}
|
10355
10391
|
let matchingGroup = groups.find((group) => {
|
10356
|
-
const matches = group.maxDuration === opts.maxDuration && group.memory === opts.memory && group.isPrerenders === isPrerenderRoute;
|
10392
|
+
const matches = group.maxDuration === opts.maxDuration && group.memory === opts.memory && group.isPrerenders === isPrerenderRoute && group.isExperimentalPPR === isExperimentalPPR;
|
10357
10393
|
if (matches) {
|
10358
10394
|
let newTracedFilesSize = group.pseudoLayerBytes;
|
10359
10395
|
let newTracedFilesUncompressedSize = group.pseudoLayerUncompressedBytes;
|
@@ -10381,6 +10417,7 @@ async function getPageLambdaGroups({
|
|
10381
10417
|
pages: [page],
|
10382
10418
|
...opts,
|
10383
10419
|
isPrerenders: isPrerenderRoute,
|
10420
|
+
isExperimentalPPR,
|
10384
10421
|
isApiLambda: !!isApiPage(page),
|
10385
10422
|
pseudoLayerBytes: initialPseudoLayer.pseudoLayerBytes,
|
10386
10423
|
pseudoLayerUncompressedBytes: initialPseudoLayerUncompressed,
|
@@ -10562,7 +10599,7 @@ var onPrerenderRouteInitial = (prerenderManifest, canUsePreviewMode, entryDirect
|
|
10562
10599
|
};
|
10563
10600
|
};
|
10564
10601
|
var prerenderGroup = 1;
|
10565
|
-
var onPrerenderRoute = (prerenderRouteArgs) => (routeKey, {
|
10602
|
+
var onPrerenderRoute = (prerenderRouteArgs) => async (routeKey, {
|
10566
10603
|
isBlocking,
|
10567
10604
|
isFallback,
|
10568
10605
|
isOmitted,
|
@@ -10579,6 +10616,7 @@ var onPrerenderRoute = (prerenderRouteArgs) => (routeKey, {
|
|
10579
10616
|
isServerMode,
|
10580
10617
|
canUsePreviewMode,
|
10581
10618
|
lambdas,
|
10619
|
+
experimentalStreamingLambdaPaths,
|
10582
10620
|
prerenders,
|
10583
10621
|
pageLambdaMap,
|
10584
10622
|
routesManifest,
|
@@ -10621,9 +10659,11 @@ var onPrerenderRoute = (prerenderRouteArgs) => (routeKey, {
|
|
10621
10659
|
let initialRevalidate;
|
10622
10660
|
let srcRoute;
|
10623
10661
|
let dataRoute;
|
10662
|
+
let prefetchDataRoute;
|
10624
10663
|
let initialStatus;
|
10625
10664
|
let initialHeaders;
|
10626
10665
|
let experimentalBypassFor;
|
10666
|
+
let experimentalPPR;
|
10627
10667
|
if (isFallback || isBlocking) {
|
10628
10668
|
const pr = isFallback ? prerenderManifest.fallbackRoutes[routeKey] : prerenderManifest.blockingFallbackRoutes[routeKey];
|
10629
10669
|
initialRevalidate = 1;
|
@@ -10636,11 +10676,15 @@ var onPrerenderRoute = (prerenderRouteArgs) => (routeKey, {
|
|
10636
10676
|
srcRoute = null;
|
10637
10677
|
dataRoute = pr.dataRoute;
|
10638
10678
|
experimentalBypassFor = pr.experimentalBypassFor;
|
10679
|
+
experimentalPPR = pr.experimentalPPR;
|
10680
|
+
prefetchDataRoute = pr.prefetchDataRoute;
|
10639
10681
|
} else if (isOmitted) {
|
10640
10682
|
initialRevalidate = false;
|
10641
10683
|
srcRoute = routeKey;
|
10642
10684
|
dataRoute = prerenderManifest.omittedRoutes[routeKey].dataRoute;
|
10643
10685
|
experimentalBypassFor = prerenderManifest.omittedRoutes[routeKey].experimentalBypassFor;
|
10686
|
+
experimentalPPR = prerenderManifest.omittedRoutes[routeKey].experimentalPPR;
|
10687
|
+
prefetchDataRoute = prerenderManifest.omittedRoutes[routeKey].prefetchDataRoute;
|
10644
10688
|
} else {
|
10645
10689
|
const pr = prerenderManifest.staticRoutes[routeKey];
|
10646
10690
|
({
|
@@ -10649,7 +10693,9 @@ var onPrerenderRoute = (prerenderRouteArgs) => (routeKey, {
|
|
10649
10693
|
dataRoute,
|
10650
10694
|
initialHeaders,
|
10651
10695
|
initialStatus,
|
10652
|
-
experimentalBypassFor
|
10696
|
+
experimentalBypassFor,
|
10697
|
+
experimentalPPR,
|
10698
|
+
prefetchDataRoute
|
10653
10699
|
} = pr);
|
10654
10700
|
}
|
10655
10701
|
let isAppPathRoute = false;
|
@@ -10658,7 +10704,38 @@ var onPrerenderRoute = (prerenderRouteArgs) => (routeKey, {
|
|
10658
10704
|
}
|
10659
10705
|
const isOmittedOrNotFound = isOmitted || isNotFound;
|
10660
10706
|
let htmlFsRef;
|
10661
|
-
|
10707
|
+
let prerender;
|
10708
|
+
if (experimentalPPR && appDir) {
|
10709
|
+
const htmlPath = import_path2.default.join(appDir, `${routeFileNoExt}.html`);
|
10710
|
+
const metaPath = import_path2.default.join(appDir, `${routeFileNoExt}.meta`);
|
10711
|
+
if (import_fs_extra3.default.existsSync(htmlPath) && import_fs_extra3.default.existsSync(metaPath)) {
|
10712
|
+
const meta = JSON.parse(await import_fs_extra3.default.readFile(metaPath, "utf8"));
|
10713
|
+
if ("postponed" in meta && typeof meta.postponed === "string") {
|
10714
|
+
prerender = meta.postponed;
|
10715
|
+
initialHeaders ??= {};
|
10716
|
+
initialHeaders["content-type"] = `application/x-nextjs-pre-render; state-length=${meta.postponed.length}`;
|
10717
|
+
const html = await import_fs_extra3.default.readFileSync(htmlPath, "utf8");
|
10718
|
+
prerender += html;
|
10719
|
+
}
|
10720
|
+
}
|
10721
|
+
if (!dataRoute?.endsWith(".rsc")) {
|
10722
|
+
throw new Error(
|
10723
|
+
`Invariant: unexpected output path for ${dataRoute} and PPR`
|
10724
|
+
);
|
10725
|
+
}
|
10726
|
+
if (!prefetchDataRoute?.endsWith(".prefetch.rsc")) {
|
10727
|
+
throw new Error(
|
10728
|
+
`Invariant: unexpected output path for ${prefetchDataRoute} and PPR`
|
10729
|
+
);
|
10730
|
+
}
|
10731
|
+
}
|
10732
|
+
if (prerender) {
|
10733
|
+
const contentType = initialHeaders?.["content-type"];
|
10734
|
+
if (!contentType) {
|
10735
|
+
throw new Error("Invariant: contentType can't be undefined");
|
10736
|
+
}
|
10737
|
+
htmlFsRef = new import_build_utils.FileBlob({ contentType, data: prerender });
|
10738
|
+
} else if (appDir && !dataRoute && isAppPathRoute && !(isBlocking || isFallback)) {
|
10662
10739
|
const contentType = initialHeaders?.["content-type"];
|
10663
10740
|
htmlFsRef = new import_build_utils.FileFsRef({
|
10664
10741
|
fsPath: import_path2.default.join(appDir, `${routeFileNoExt}.body`),
|
@@ -10691,7 +10768,7 @@ var onPrerenderRoute = (prerenderRouteArgs) => (routeKey, {
|
|
10691
10768
|
isFallback || isBlocking || isNotFound && !static404Page || !dataRoute ? null : new import_build_utils.FileFsRef({
|
10692
10769
|
fsPath: import_path2.default.join(
|
10693
10770
|
isAppPathRoute && !isOmittedOrNotFound && appDir ? appDir : pagesDir,
|
10694
|
-
`${isOmittedOrNotFound ? localePrefixed404 ? addLocaleOrDefault("/404.html", routesManifest, locale) : "/404.html" : isAppPathRoute ? dataRoute : routeFileNoExt + ".json"}`
|
10771
|
+
`${isOmittedOrNotFound ? localePrefixed404 ? addLocaleOrDefault("/404.html", routesManifest, locale) : "/404.html" : isAppPathRoute ? prefetchDataRoute || dataRoute : routeFileNoExt + ".json"}`
|
10695
10772
|
)
|
10696
10773
|
})
|
10697
10774
|
);
|
@@ -10714,11 +10791,10 @@ var onPrerenderRoute = (prerenderRouteArgs) => (routeKey, {
|
|
10714
10791
|
origRouteFileNoExt
|
10715
10792
|
);
|
10716
10793
|
let lambda;
|
10717
|
-
|
10718
|
-
|
10719
|
-
outputPathData = import_path2.default.posix.join(entryDirectory, dataRoute);
|
10794
|
+
function normalizeDataRoute(route) {
|
10795
|
+
let normalized = import_path2.default.posix.join(entryDirectory, route);
|
10720
10796
|
if (nonDynamicSsg || isFallback || isOmitted) {
|
10721
|
-
|
10797
|
+
normalized = normalized.replace(
|
10722
10798
|
new RegExp(`${(0, import_escape_string_regexp.default)(origRouteFileNoExt)}.json$`),
|
10723
10799
|
// ensure we escape "$" correctly while replacing as "$" is a special
|
10724
10800
|
// character, we need to do double escaping as first is for the initial
|
@@ -10726,7 +10802,24 @@ var onPrerenderRoute = (prerenderRouteArgs) => (routeKey, {
|
|
10726
10802
|
`${routeFileNoExt.replace(/\$/g, "$$$$")}.json`
|
10727
10803
|
);
|
10728
10804
|
}
|
10805
|
+
return normalized;
|
10806
|
+
}
|
10807
|
+
let outputPathData = null;
|
10808
|
+
if (dataRoute) {
|
10809
|
+
outputPathData = normalizeDataRoute(dataRoute);
|
10810
|
+
}
|
10811
|
+
let outputPathPrefetchData = null;
|
10812
|
+
if (prefetchDataRoute) {
|
10813
|
+
if (!experimentalPPR) {
|
10814
|
+
throw new Error(
|
10815
|
+
"Invariant: prefetchDataRoute can't be set without PPR"
|
10816
|
+
);
|
10817
|
+
}
|
10818
|
+
outputPathPrefetchData = normalizeDataRoute(prefetchDataRoute);
|
10819
|
+
} else if (experimentalPPR) {
|
10820
|
+
throw new Error("Invariant: expected to find prefetch data route PPR");
|
10729
10821
|
}
|
10822
|
+
const outputPrerenderPathData = outputPathPrefetchData || outputPathData;
|
10730
10823
|
if (isSharedLambdas) {
|
10731
10824
|
const outputSrcPathPage = normalizeIndexOutput(
|
10732
10825
|
import_path2.default.join(
|
@@ -10760,8 +10853,8 @@ var onPrerenderRoute = (prerenderRouteArgs) => (routeKey, {
|
|
10760
10853
|
if (!canUsePreviewMode || routeKey === "/404" && !lambdas[outputPathPage]) {
|
10761
10854
|
htmlFsRef.contentType = htmlContentType;
|
10762
10855
|
prerenders[outputPathPage] = htmlFsRef;
|
10763
|
-
if (
|
10764
|
-
prerenders[
|
10856
|
+
if (outputPrerenderPathData) {
|
10857
|
+
prerenders[outputPrerenderPathData] = jsonFsRef;
|
10765
10858
|
}
|
10766
10859
|
}
|
10767
10860
|
}
|
@@ -10797,10 +10890,22 @@ var onPrerenderRoute = (prerenderRouteArgs) => (routeKey, {
|
|
10797
10890
|
const rscEnabled = !!routesManifest?.rsc;
|
10798
10891
|
const rscVaryHeader = routesManifest?.rsc?.varyHeader || "RSC, Next-Router-State-Tree, Next-Router-Prefetch";
|
10799
10892
|
const rscContentTypeHeader = routesManifest?.rsc?.contentTypeHeader || RSC_CONTENT_TYPE;
|
10893
|
+
const rscDidPostponeHeader = routesManifest?.rsc?.didPostponeHeader;
|
10800
10894
|
let sourcePath;
|
10801
10895
|
if (`/${outputPathPage}` !== srcRoute && srcRoute) {
|
10802
10896
|
sourcePath = srcRoute;
|
10803
10897
|
}
|
10898
|
+
let key = srcRoute || routeKey;
|
10899
|
+
if (key === "/") {
|
10900
|
+
key = "index";
|
10901
|
+
} else {
|
10902
|
+
if (!key.startsWith("/")) {
|
10903
|
+
throw new Error("Invariant: key doesn't start with /");
|
10904
|
+
}
|
10905
|
+
key = key.substring(1);
|
10906
|
+
}
|
10907
|
+
key = import_path2.default.posix.join(entryDirectory, key);
|
10908
|
+
const experimentalStreamingLambdaPath = experimentalStreamingLambdaPaths?.get(key);
|
10804
10909
|
prerenders[outputPathPage] = new import_build_utils.Prerender({
|
10805
10910
|
expiration: initialRevalidate,
|
10806
10911
|
lambda,
|
@@ -10812,6 +10917,7 @@ var onPrerenderRoute = (prerenderRouteArgs) => (routeKey, {
|
|
10812
10917
|
initialStatus,
|
10813
10918
|
initialHeaders,
|
10814
10919
|
sourcePath,
|
10920
|
+
experimentalStreamingLambdaPath,
|
10815
10921
|
...isNotFound ? {
|
10816
10922
|
initialStatus: 404
|
10817
10923
|
} : {},
|
@@ -10822,8 +10928,16 @@ var onPrerenderRoute = (prerenderRouteArgs) => (routeKey, {
|
|
10822
10928
|
}
|
10823
10929
|
} : {}
|
10824
10930
|
});
|
10825
|
-
if (
|
10826
|
-
|
10931
|
+
if (outputPrerenderPathData) {
|
10932
|
+
let normalizedPathData = outputPrerenderPathData;
|
10933
|
+
if ((srcRoute === "/" || srcRoute == "/index") && outputPrerenderPathData.endsWith(RSC_PREFETCH_SUFFIX)) {
|
10934
|
+
delete lambdas[normalizedPathData];
|
10935
|
+
normalizedPathData = normalizedPathData.replace(
|
10936
|
+
/([^/]+\.prefetch\.rsc)$/,
|
10937
|
+
"__$1"
|
10938
|
+
);
|
10939
|
+
}
|
10940
|
+
prerenders[normalizedPathData] = new import_build_utils.Prerender({
|
10827
10941
|
expiration: initialRevalidate,
|
10828
10942
|
lambda,
|
10829
10943
|
allowQuery,
|
@@ -10837,7 +10951,8 @@ var onPrerenderRoute = (prerenderRouteArgs) => (routeKey, {
|
|
10837
10951
|
...rscEnabled ? {
|
10838
10952
|
initialHeaders: {
|
10839
10953
|
"content-type": rscContentTypeHeader,
|
10840
|
-
vary: rscVaryHeader
|
10954
|
+
vary: rscVaryHeader,
|
10955
|
+
...experimentalPPR && rscDidPostponeHeader ? { [rscDidPostponeHeader]: "1" } : {}
|
10841
10956
|
}
|
10842
10957
|
} : {}
|
10843
10958
|
});
|
@@ -11375,6 +11490,18 @@ async function getServerlessPages(params) {
|
|
11375
11490
|
}
|
11376
11491
|
return { pages, appPaths: normalizedAppPaths };
|
11377
11492
|
}
|
11493
|
+
function normalizePrefetches(prefetches) {
|
11494
|
+
const updatedPrefetches = {};
|
11495
|
+
for (const key in prefetches) {
|
11496
|
+
if (key === "index.prefetch.rsc") {
|
11497
|
+
const newKey = key.replace(/([^/]+\.prefetch\.rsc)$/, "__$1");
|
11498
|
+
updatedPrefetches[newKey] = prefetches[key];
|
11499
|
+
} else {
|
11500
|
+
updatedPrefetches[key] = prefetches[key];
|
11501
|
+
}
|
11502
|
+
}
|
11503
|
+
return updatedPrefetches;
|
11504
|
+
}
|
11378
11505
|
|
11379
11506
|
// src/create-serverless-config.ts
|
11380
11507
|
function getCustomData(importName, target) {
|
@@ -11865,18 +11992,18 @@ async function serverBuild({
|
|
11865
11992
|
inversedAppPathManifest[appPathRoutesManifest[ogRoute]] = ogRoute;
|
11866
11993
|
}
|
11867
11994
|
}
|
11995
|
+
const experimental = {
|
11996
|
+
ppr: requiredServerFilesManifest.config.experimental?.ppr === true
|
11997
|
+
};
|
11868
11998
|
let appRscPrefetches = {};
|
11869
11999
|
let appBuildTraces = {};
|
11870
12000
|
let appDir = null;
|
11871
12001
|
if (appPathRoutesManifest) {
|
11872
12002
|
appDir = import_path4.default.join(pagesDir, "../app");
|
11873
12003
|
appBuildTraces = await (0, import_build_utils2.glob)("**/*.js.nft.json", appDir);
|
11874
|
-
appRscPrefetches = await (0, import_build_utils2.glob)(`**/*${RSC_PREFETCH_SUFFIX}`, appDir);
|
12004
|
+
appRscPrefetches = experimental.ppr ? {} : await (0, import_build_utils2.glob)(`**/*${RSC_PREFETCH_SUFFIX}`, appDir);
|
11875
12005
|
const rscContentTypeHeader = routesManifest?.rsc?.contentTypeHeader || RSC_CONTENT_TYPE;
|
11876
|
-
|
11877
|
-
appRscPrefetches["__index.prefetch.rsc"] = appRscPrefetches["index.prefetch.rsc"];
|
11878
|
-
delete appRscPrefetches["index.prefetch.rsc"];
|
11879
|
-
}
|
12006
|
+
appRscPrefetches = normalizePrefetches(appRscPrefetches);
|
11880
12007
|
for (const value of Object.values(appRscPrefetches)) {
|
11881
12008
|
if (!value.contentType) {
|
11882
12009
|
value.contentType = rscContentTypeHeader;
|
@@ -11943,6 +12070,16 @@ async function serverBuild({
|
|
11943
12070
|
if (lambdaPages["404.js"]) {
|
11944
12071
|
internalPages.push("404.js");
|
11945
12072
|
}
|
12073
|
+
const experimentalPPRRoutes = /* @__PURE__ */ new Set();
|
12074
|
+
for (const [route, { experimentalPPR }] of [
|
12075
|
+
...Object.entries(prerenderManifest.staticRoutes),
|
12076
|
+
...Object.entries(prerenderManifest.blockingFallbackRoutes),
|
12077
|
+
...Object.entries(prerenderManifest.fallbackRoutes)
|
12078
|
+
]) {
|
12079
|
+
if (!experimentalPPR)
|
12080
|
+
continue;
|
12081
|
+
experimentalPPRRoutes.add(route);
|
12082
|
+
}
|
11946
12083
|
const prerenderRoutes = /* @__PURE__ */ new Set([
|
11947
12084
|
...canUsePreviewMode ? omittedPrerenderRoutes : [],
|
11948
12085
|
...Object.keys(prerenderManifest.blockingFallbackRoutes),
|
@@ -11952,6 +12089,7 @@ async function serverBuild({
|
|
11952
12089
|
return staticRoute.srcRoute || route;
|
11953
12090
|
})
|
11954
12091
|
]);
|
12092
|
+
const experimentalStreamingLambdaPaths = /* @__PURE__ */ new Map();
|
11955
12093
|
if (hasLambdas) {
|
11956
12094
|
const initialTracingLabel = "Traced Next.js server files in";
|
11957
12095
|
console.time(initialTracingLabel);
|
@@ -12197,8 +12335,8 @@ async function serverBuild({
|
|
12197
12335
|
"utf8"
|
12198
12336
|
);
|
12199
12337
|
let launcher = launcherData.replace(
|
12200
|
-
"conf
|
12201
|
-
`conf
|
12338
|
+
"const conf = __NEXT_CONFIG__",
|
12339
|
+
`const conf = ${JSON.stringify({
|
12202
12340
|
...requiredServerFilesManifest.config,
|
12203
12341
|
distDir: import_path4.default.relative(
|
12204
12342
|
projectDir,
|
@@ -12345,6 +12483,7 @@ async function serverBuild({
|
|
12345
12483
|
prerenderRoutes,
|
12346
12484
|
pageTraces,
|
12347
12485
|
compressedPages,
|
12486
|
+
experimentalPPRRoutes: void 0,
|
12348
12487
|
tracedPseudoLayer: tracedPseudoLayer.pseudoLayer,
|
12349
12488
|
initialPseudoLayer,
|
12350
12489
|
lambdaCompressedByteLimit,
|
@@ -12363,6 +12502,7 @@ async function serverBuild({
|
|
12363
12502
|
prerenderRoutes,
|
12364
12503
|
pageTraces,
|
12365
12504
|
compressedPages,
|
12505
|
+
experimentalPPRRoutes,
|
12366
12506
|
tracedPseudoLayer: tracedPseudoLayer.pseudoLayer,
|
12367
12507
|
initialPseudoLayer,
|
12368
12508
|
lambdaCompressedByteLimit,
|
@@ -12378,6 +12518,7 @@ async function serverBuild({
|
|
12378
12518
|
prerenderRoutes,
|
12379
12519
|
pageTraces,
|
12380
12520
|
compressedPages,
|
12521
|
+
experimentalPPRRoutes: void 0,
|
12381
12522
|
tracedPseudoLayer: tracedPseudoLayer.pseudoLayer,
|
12382
12523
|
initialPseudoLayer,
|
12383
12524
|
lambdaCompressedByteLimit,
|
@@ -12386,7 +12527,7 @@ async function serverBuild({
|
|
12386
12527
|
pageExtensions
|
12387
12528
|
});
|
12388
12529
|
for (const group of appRouterLambdaGroups) {
|
12389
|
-
if (!group.isPrerenders) {
|
12530
|
+
if (!group.isPrerenders || group.isExperimentalPPR) {
|
12390
12531
|
group.isStreaming = true;
|
12391
12532
|
}
|
12392
12533
|
group.isAppRouter = true;
|
@@ -12406,6 +12547,7 @@ async function serverBuild({
|
|
12406
12547
|
prerenderRoutes,
|
12407
12548
|
pageTraces,
|
12408
12549
|
compressedPages,
|
12550
|
+
experimentalPPRRoutes: void 0,
|
12409
12551
|
tracedPseudoLayer: tracedPseudoLayer.pseudoLayer,
|
12410
12552
|
initialPseudoLayer,
|
12411
12553
|
initialPseudoLayerUncompressed: uncompressedInitialSize,
|
@@ -12520,7 +12662,7 @@ async function serverBuild({
|
|
12520
12662
|
[import_path4.default.join(import_path4.default.relative(baseDir, projectDir), "___next_launcher.cjs")]: new import_build_utils2.FileBlob({ data: group.isAppRouter ? appLauncher : launcher })
|
12521
12663
|
};
|
12522
12664
|
const operationType = getOperationType({ group, prerenderManifest });
|
12523
|
-
const
|
12665
|
+
const options = {
|
12524
12666
|
files: {
|
12525
12667
|
...launcherFiles,
|
12526
12668
|
...updatedManifestFiles
|
@@ -12536,7 +12678,19 @@ async function serverBuild({
|
|
12536
12678
|
maxDuration: group.maxDuration,
|
12537
12679
|
isStreaming: group.isStreaming,
|
12538
12680
|
nextVersion
|
12539
|
-
}
|
12681
|
+
};
|
12682
|
+
const lambda = await createLambdaFromPseudoLayers(options);
|
12683
|
+
const isPPR = experimental.ppr && group.isAppRouter && !group.isAppRouteHandler;
|
12684
|
+
let revalidate;
|
12685
|
+
if (isPPR) {
|
12686
|
+
if (isPPR && !options.isStreaming) {
|
12687
|
+
throw new Error("Invariant: PPR lambda isn't streaming");
|
12688
|
+
}
|
12689
|
+
revalidate = await createLambdaFromPseudoLayers({
|
12690
|
+
...options,
|
12691
|
+
isStreaming: false
|
12692
|
+
});
|
12693
|
+
}
|
12540
12694
|
for (const page of group.pages) {
|
12541
12695
|
const pageNoExt = page.replace(/\.js$/, "");
|
12542
12696
|
let isPrerender = prerenderRoutes.has(
|
@@ -12549,10 +12703,25 @@ async function serverBuild({
|
|
12549
12703
|
);
|
12550
12704
|
});
|
12551
12705
|
}
|
12552
|
-
|
12706
|
+
let outputName = normalizeIndexOutput(
|
12553
12707
|
import_path4.default.posix.join(entryDirectory, pageNoExt),
|
12554
12708
|
true
|
12555
12709
|
);
|
12710
|
+
if (isPPR) {
|
12711
|
+
if (!revalidate) {
|
12712
|
+
throw new Error("Invariant: PPR lambda isn't set");
|
12713
|
+
}
|
12714
|
+
outputName = import_path4.default.posix.join(entryDirectory, pageNoExt);
|
12715
|
+
lambdas[outputName] = revalidate;
|
12716
|
+
const pprOutputName = import_path4.default.posix.join(
|
12717
|
+
entryDirectory,
|
12718
|
+
"/_next/postponed/resume",
|
12719
|
+
pageNoExt
|
12720
|
+
);
|
12721
|
+
lambdas[pprOutputName] = lambda;
|
12722
|
+
experimentalStreamingLambdaPaths.set(outputName, pprOutputName);
|
12723
|
+
continue;
|
12724
|
+
}
|
12556
12725
|
if (i18n && !isPrerender && !group.isAppRouter && (!isCorrectLocaleAPIRoutes || !(pageNoExt === "api" || pageNoExt.startsWith("api/")))) {
|
12557
12726
|
for (const locale of i18n.locales) {
|
12558
12727
|
lambdas[normalizeIndexOutput(
|
@@ -12576,6 +12745,7 @@ async function serverBuild({
|
|
12576
12745
|
pagesDir,
|
12577
12746
|
pageLambdaMap: {},
|
12578
12747
|
lambdas,
|
12748
|
+
experimentalStreamingLambdaPaths,
|
12579
12749
|
prerenders,
|
12580
12750
|
entryDirectory,
|
12581
12751
|
routesManifest,
|
@@ -12590,25 +12760,38 @@ async function serverBuild({
|
|
12590
12760
|
isCorrectNotFoundRoutes,
|
12591
12761
|
isEmptyAllowQueryForPrendered
|
12592
12762
|
});
|
12593
|
-
|
12594
|
-
(
|
12763
|
+
await Promise.all(
|
12764
|
+
Object.keys(prerenderManifest.staticRoutes).map(
|
12765
|
+
(route) => prerenderRoute(route, {})
|
12766
|
+
)
|
12595
12767
|
);
|
12596
|
-
|
12597
|
-
(
|
12768
|
+
await Promise.all(
|
12769
|
+
Object.keys(prerenderManifest.fallbackRoutes).map(
|
12770
|
+
(route) => prerenderRoute(route, { isFallback: true })
|
12771
|
+
)
|
12598
12772
|
);
|
12599
|
-
|
12600
|
-
(
|
12773
|
+
await Promise.all(
|
12774
|
+
Object.keys(prerenderManifest.blockingFallbackRoutes).map(
|
12775
|
+
(route) => prerenderRoute(route, { isBlocking: true })
|
12776
|
+
)
|
12601
12777
|
);
|
12602
12778
|
if (static404Page && canUsePreviewMode) {
|
12603
|
-
|
12604
|
-
|
12605
|
-
|
12779
|
+
await Promise.all(
|
12780
|
+
[...omittedPrerenderRoutes].map((route) => {
|
12781
|
+
return prerenderRoute(route, { isOmitted: true });
|
12782
|
+
})
|
12783
|
+
);
|
12606
12784
|
}
|
12607
12785
|
prerenderRoutes.forEach((route) => {
|
12786
|
+
if (experimentalPPRRoutes.has(route))
|
12787
|
+
return;
|
12608
12788
|
if (routesManifest?.i18n) {
|
12609
12789
|
route = normalizeLocalePath(route, routesManifest.i18n.locales).pathname;
|
12610
12790
|
}
|
12611
|
-
delete lambdas[
|
12791
|
+
delete lambdas[normalizeIndexOutput(
|
12792
|
+
import_path4.default.posix.join("./", entryDirectory, route === "/" ? "/index" : route),
|
12793
|
+
true
|
12794
|
+
)];
|
12612
12795
|
});
|
12613
12796
|
const middleware = await getMiddlewareBundle({
|
12614
12797
|
config,
|
@@ -12631,7 +12814,8 @@ async function serverBuild({
|
|
12631
12814
|
canUsePreviewMode,
|
12632
12815
|
prerenderManifest.bypassToken || "",
|
12633
12816
|
true,
|
12634
|
-
middleware.dynamicRouteMap
|
12817
|
+
middleware.dynamicRouteMap,
|
12818
|
+
experimental.ppr
|
12635
12819
|
).then(
|
12636
12820
|
(arr) => localizeDynamicRoutes(
|
12637
12821
|
arr,
|
@@ -12771,20 +12955,20 @@ async function serverBuild({
|
|
12771
12955
|
}
|
12772
12956
|
if (appPathRoutesManifest) {
|
12773
12957
|
const edgeFunctions = middleware.edgeFunctions;
|
12774
|
-
for (
|
12958
|
+
for (const route of Object.values(appPathRoutesManifest)) {
|
12775
12959
|
const ogRoute = inversedAppPathManifest[route];
|
12776
12960
|
if (ogRoute.endsWith("/route")) {
|
12777
12961
|
continue;
|
12778
12962
|
}
|
12779
|
-
|
12963
|
+
const pathname = normalizeIndexOutput(
|
12780
12964
|
import_path4.default.posix.join("./", entryDirectory, route === "/" ? "/index" : route),
|
12781
12965
|
true
|
12782
12966
|
);
|
12783
|
-
if (lambdas[
|
12784
|
-
lambdas[`${
|
12967
|
+
if (lambdas[pathname]) {
|
12968
|
+
lambdas[`${pathname}.rsc`] = lambdas[pathname];
|
12785
12969
|
}
|
12786
|
-
if (edgeFunctions[
|
12787
|
-
edgeFunctions[`${
|
12970
|
+
if (edgeFunctions[pathname]) {
|
12971
|
+
edgeFunctions[`${pathname}.rsc`] = edgeFunctions[pathname];
|
12788
12972
|
}
|
12789
12973
|
}
|
12790
12974
|
}
|
@@ -12797,6 +12981,9 @@ async function serverBuild({
|
|
12797
12981
|
...value,
|
12798
12982
|
metadata: value.metadata ?? {}
|
12799
12983
|
})) : [];
|
12984
|
+
if (experimental.ppr && !rscPrefetchHeader) {
|
12985
|
+
throw new Error("Invariant: cannot use PPR without 'rsc.prefetchHeader'");
|
12986
|
+
}
|
12800
12987
|
return {
|
12801
12988
|
wildcard: wildcardConfig,
|
12802
12989
|
images: getImagesConfig(imagesManifest),
|
@@ -13079,7 +13266,7 @@ async function serverBuild({
|
|
13079
13266
|
check: true
|
13080
13267
|
}
|
13081
13268
|
] : [],
|
13082
|
-
...rscPrefetchHeader ? [
|
13269
|
+
...rscPrefetchHeader && !experimental.ppr ? [
|
13083
13270
|
{
|
13084
13271
|
src: import_path4.default.posix.join(
|
13085
13272
|
"/",
|
@@ -13102,7 +13289,11 @@ async function serverBuild({
|
|
13102
13289
|
entryDirectory,
|
13103
13290
|
`/(.+?)${RSC_PREFETCH_SUFFIX}(?:/)?$`
|
13104
13291
|
)}`,
|
13105
|
-
dest: import_path4.default.posix.join(
|
13292
|
+
dest: import_path4.default.posix.join(
|
13293
|
+
"/",
|
13294
|
+
entryDirectory,
|
13295
|
+
`/$1${experimental.ppr ? RSC_PREFETCH_SUFFIX : ".rsc"}`
|
13296
|
+
),
|
13106
13297
|
has: [
|
13107
13298
|
{
|
13108
13299
|
type: "header",
|
@@ -13273,8 +13464,6 @@ async function serverBuild({
|
|
13273
13464
|
continue: true,
|
13274
13465
|
important: true
|
13275
13466
|
},
|
13276
|
-
// TODO: remove below workaround when `/` is allowed to be output
|
13277
|
-
// different than `/index`
|
13278
13467
|
{
|
13279
13468
|
src: import_path4.default.posix.join("/", entryDirectory, "/index"),
|
13280
13469
|
headers: {
|
@@ -14460,7 +14649,8 @@ More info: http://err.sh/vercel/vercel/next-functions-config-optimized-lambdas`
|
|
14460
14649
|
lambdaCompressedByteLimit,
|
14461
14650
|
// internal pages are already referenced in traces for serverless
|
14462
14651
|
// like builds
|
14463
|
-
internalPages: []
|
14652
|
+
internalPages: [],
|
14653
|
+
experimentalPPRRoutes: void 0
|
14464
14654
|
});
|
14465
14655
|
const initialApiLambdaGroups = await getPageLambdaGroups({
|
14466
14656
|
entryPath,
|
@@ -14474,7 +14664,8 @@ More info: http://err.sh/vercel/vercel/next-functions-config-optimized-lambdas`
|
|
14474
14664
|
initialPseudoLayer: { pseudoLayer: {}, pseudoLayerBytes: 0 },
|
14475
14665
|
initialPseudoLayerUncompressed: 0,
|
14476
14666
|
lambdaCompressedByteLimit,
|
14477
|
-
internalPages: []
|
14667
|
+
internalPages: [],
|
14668
|
+
experimentalPPRRoutes: void 0
|
14478
14669
|
});
|
14479
14670
|
for (const group of initialApiLambdaGroups) {
|
14480
14671
|
group.isApiLambda = true;
|
@@ -14882,6 +15073,7 @@ More info: http://err.sh/vercel/vercel/next-functions-config-optimized-lambdas`
|
|
14882
15073
|
static404Page,
|
14883
15074
|
pageLambdaMap,
|
14884
15075
|
lambdas,
|
15076
|
+
experimentalStreamingLambdaPaths: void 0,
|
14885
15077
|
isServerMode,
|
14886
15078
|
prerenders,
|
14887
15079
|
entryDirectory,
|
@@ -14909,20 +15101,40 @@ More info: http://err.sh/vercel/vercel/next-functions-config-optimized-lambdas`
|
|
14909
15101
|
[
|
14910
15102
|
...Object.entries(prerenderManifest.fallbackRoutes),
|
14911
15103
|
...Object.entries(prerenderManifest.blockingFallbackRoutes)
|
14912
|
-
].forEach(
|
14913
|
-
|
14914
|
-
|
14915
|
-
|
14916
|
-
|
14917
|
-
|
14918
|
-
|
14919
|
-
|
14920
|
-
|
14921
|
-
|
14922
|
-
|
14923
|
-
|
14924
|
-
|
14925
|
-
|
15104
|
+
].forEach(
|
15105
|
+
([
|
15106
|
+
,
|
15107
|
+
{
|
15108
|
+
dataRouteRegex,
|
15109
|
+
dataRoute,
|
15110
|
+
prefetchDataRouteRegex,
|
15111
|
+
prefetchDataRoute
|
15112
|
+
}
|
15113
|
+
]) => {
|
15114
|
+
if (!dataRoute || !dataRouteRegex)
|
15115
|
+
return;
|
15116
|
+
dataRoutes.push({
|
15117
|
+
// Next.js provided data route regex
|
15118
|
+
src: dataRouteRegex.replace(
|
15119
|
+
/^\^/,
|
15120
|
+
`^${appMountPrefixNoTrailingSlash}`
|
15121
|
+
),
|
15122
|
+
// Location of lambda in builder output
|
15123
|
+
dest: import_path5.default.posix.join(entryDirectory, dataRoute),
|
15124
|
+
check: true
|
15125
|
+
});
|
15126
|
+
if (!prefetchDataRoute || !prefetchDataRouteRegex)
|
15127
|
+
return;
|
15128
|
+
dataRoutes.push({
|
15129
|
+
src: prefetchDataRouteRegex.replace(
|
15130
|
+
/^\^/,
|
15131
|
+
`^${appMountPrefixNoTrailingSlash}`
|
15132
|
+
),
|
15133
|
+
dest: import_path5.default.posix.join(entryDirectory, prefetchDataRoute),
|
15134
|
+
check: true
|
15135
|
+
});
|
15136
|
+
}
|
15137
|
+
);
|
14926
15138
|
}
|
14927
15139
|
}
|
14928
15140
|
if (!isSharedLambdas) {
|
package/dist/server-launcher.js
CHANGED
@@ -12,20 +12,23 @@ if (process.env.NODE_ENV !== "production" && region !== "dev1") {
|
|
12
12
|
}
|
13
13
|
// @preserve pre-next-server-target
|
14
14
|
const NextServer = require("__NEXT_SERVER_PATH__").default;
|
15
|
+
const conf = __NEXT_CONFIG__;
|
15
16
|
const nextServer = new NextServer({
|
16
|
-
|
17
|
-
conf: __NEXT_CONFIG__,
|
17
|
+
conf,
|
18
18
|
dir: ".",
|
19
19
|
minimalMode: true,
|
20
20
|
customServer: false
|
21
21
|
});
|
22
|
-
const
|
23
|
-
module.exports = async (req, res) => {
|
22
|
+
const serve = (handler) => async (req, res) => {
|
24
23
|
try {
|
25
24
|
// @preserve entryDirectory handler
|
26
|
-
await
|
25
|
+
await handler(req, res);
|
27
26
|
} catch (err) {
|
28
27
|
console.error(err);
|
29
28
|
process.exit(1);
|
30
29
|
}
|
31
30
|
};
|
31
|
+
module.exports = serve(nextServer.getRequestHandler());
|
32
|
+
if (conf.experimental?.ppr && "getRequestHandlerWithMetadata" in nextServer && typeof nextServer.getRequestHandlerWithMetadata === "function") {
|
33
|
+
module.exports.getRequestHandlerWithMetadata = (metadata) => serve(nextServer.getRequestHandlerWithMetadata(metadata));
|
34
|
+
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@vercel/next",
|
3
|
-
"version": "4.0.
|
3
|
+
"version": "4.0.13",
|
4
4
|
"license": "Apache-2.0",
|
5
5
|
"main": "./dist/index",
|
6
6
|
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/next-js",
|
@@ -30,7 +30,7 @@
|
|
30
30
|
"@types/semver": "6.0.0",
|
31
31
|
"@types/text-table": "0.2.1",
|
32
32
|
"@types/webpack-sources": "3.2.0",
|
33
|
-
"@vercel/build-utils": "7.2.
|
33
|
+
"@vercel/build-utils": "7.2.3",
|
34
34
|
"@vercel/routing-utils": "3.1.0",
|
35
35
|
"async-sema": "3.0.1",
|
36
36
|
"buffer-crc32": "0.2.13",
|