Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial implementation of per-segment prefetch request handling #71113

Merged
merged 4 commits into from
Oct 11, 2024

Conversation

acdlite
Copy link
Contributor

@acdlite acdlite commented Oct 10, 2024

Introduces a new type of request that will be used for prefetching individual segments. Requests are issued using the Next-Router-Segment-Prefetch header. It accepts a path to the segment that is being requested.

This feature part of PPR and will only be enabled when that flag is on.

Because these are prefetches, segment requests are always served from the cache. They must never reach the application layer or invoke a lambda. If a matching segment is not present in the cache, the server responds with a 404 and an empty body. Segments that are fully dynamic will also 404.

In this PR, I have not yet implemented the actual segment generation; I'm using placeholder data for now. The smoke test I added demonstrates that the placeholder data is correctly plumbed through the build, ISR, and server layers to respond to a basic request.

@ijjk
Copy link
Member

ijjk commented Oct 10, 2024

Tests Passed

@ijjk
Copy link
Member

ijjk commented Oct 10, 2024

Stats from current PR

Default Build (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary acdlite/next.js per-segment-prefetch-request-handling Change
buildDuration 19.9s 17s N/A
buildDurationCached 16.2s 14.3s N/A
nodeModulesSize 370 MB 370 MB ⚠️ +138 kB
nextStartRea..uration (ms) 449ms 449ms
Client Bundles (main, webpack)
vercel/next.js canary acdlite/next.js per-segment-prefetch-request-handling Change
1526.HASH.js gzip 170 B 169 B N/A
1698-HASH.js gzip 5.27 kB 5.27 kB N/A
3463-HASH.js gzip 43.4 kB 43.4 kB N/A
d1e65033-HASH.js gzip 52.8 kB 52.8 kB N/A
framework-HASH.js gzip 57.5 kB 57.5 kB N/A
main-app-HASH.js gzip 233 B 233 B
main-HASH.js gzip 32.8 kB 32.8 kB N/A
webpack-HASH.js gzip 1.71 kB 1.71 kB
Overall change 1.94 kB 1.94 kB
Legacy Client Bundles (polyfills)
vercel/next.js canary acdlite/next.js per-segment-prefetch-request-handling Change
polyfills-HASH.js gzip 39.4 kB 39.4 kB
Overall change 39.4 kB 39.4 kB
Client Pages
vercel/next.js canary acdlite/next.js per-segment-prefetch-request-handling Change
_app-HASH.js gzip 193 B 193 B
_error-HASH.js gzip 192 B 192 B
amp-HASH.js gzip 511 B 512 B N/A
css-HASH.js gzip 343 B 341 B N/A
dynamic-HASH.js gzip 1.84 kB 1.85 kB N/A
edge-ssr-HASH.js gzip 266 B 266 B
head-HASH.js gzip 364 B 363 B N/A
hooks-HASH.js gzip 392 B 389 B N/A
image-HASH.js gzip 4.41 kB 4.41 kB
index-HASH.js gzip 268 B 268 B
link-HASH.js gzip 2.78 kB 2.78 kB N/A
routerDirect..HASH.js gzip 329 B 328 B N/A
script-HASH.js gzip 396 B 396 B
withRouter-HASH.js gzip 325 B 324 B N/A
1afbb74e6ecf..834.css gzip 106 B 106 B
Overall change 5.83 kB 5.83 kB
Client Build Manifests
vercel/next.js canary acdlite/next.js per-segment-prefetch-request-handling Change
_buildManifest.js gzip 747 B 751 B N/A
Overall change 0 B 0 B
Rendered Page Sizes
vercel/next.js canary acdlite/next.js per-segment-prefetch-request-handling Change
index.html gzip 523 B 523 B
link.html gzip 539 B 538 B N/A
withRouter.html gzip 519 B 519 B
Overall change 1.04 kB 1.04 kB
Edge SSR bundle Size Overall increase ⚠️
vercel/next.js canary acdlite/next.js per-segment-prefetch-request-handling Change
edge-ssr.js gzip 129 kB 129 kB ⚠️ +121 B
page.js gzip 187 kB 187 kB ⚠️ +250 B
Overall change 316 kB 316 kB ⚠️ +371 B
Middleware size
vercel/next.js canary acdlite/next.js per-segment-prefetch-request-handling Change
middleware-b..fest.js gzip 669 B 667 B N/A
middleware-r..fest.js gzip 155 B 156 B N/A
middleware.js gzip 30.4 kB 30.4 kB N/A
edge-runtime..pack.js gzip 844 B 844 B
Overall change 844 B 844 B
Next Runtimes Overall increase ⚠️
vercel/next.js canary acdlite/next.js per-segment-prefetch-request-handling Change
973-experime...dev.js gzip 322 B 322 B
973.runtime.dev.js gzip 314 B 314 B
app-page-exp...dev.js gzip 310 kB 310 kB ⚠️ +104 B
app-page-exp..prod.js gzip 119 kB 119 kB N/A
app-page-tur..prod.js gzip 133 kB 133 kB N/A
app-page-tur..prod.js gzip 128 kB 128 kB N/A
app-page.run...dev.js gzip 301 kB 301 kB N/A
app-page.run..prod.js gzip 115 kB 115 kB N/A
app-route-ex...dev.js gzip 34.5 kB 34.5 kB N/A
app-route-ex..prod.js gzip 23.3 kB 23.3 kB N/A
app-route-tu..prod.js gzip 23.3 kB 23.3 kB N/A
app-route-tu..prod.js gzip 23.1 kB 23.2 kB N/A
app-route.ru...dev.js gzip 36.1 kB 36.1 kB N/A
app-route.ru..prod.js gzip 23.1 kB 23.1 kB N/A
pages-api-tu..prod.js gzip 9.61 kB 9.61 kB
pages-api.ru...dev.js gzip 11.4 kB 11.4 kB
pages-api.ru..prod.js gzip 9.61 kB 9.61 kB
pages-turbo...prod.js gzip 20.9 kB 20.9 kB
pages.runtim...dev.js gzip 26.5 kB 26.5 kB
pages.runtim..prod.js gzip 20.9 kB 20.9 kB
server.runti..prod.js gzip 59.4 kB 59.6 kB ⚠️ +240 B
Overall change 469 kB 469 kB ⚠️ +344 B
build cache Overall increase ⚠️
vercel/next.js canary acdlite/next.js per-segment-prefetch-request-handling Change
0.pack gzip 1.83 MB 1.84 MB ⚠️ +2.26 kB
index.pack gzip 142 kB 142 kB N/A
Overall change 1.83 MB 1.84 MB ⚠️ +2.26 kB
Diff details
Diff for page.js
@@ -15,7 +15,7 @@
       /***/
     },
 
-    /***/ 4767: /***/ (
+    /***/ 9759: /***/ (
       __unused_webpack_module,
       __webpack_exports__,
       __webpack_require__
@@ -30,7 +30,7 @@
         default: () => /* binding */ nHandler,
       });
 
-      // NAMESPACE OBJECT: ./node_modules/.pnpm/next@file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-2d16326d-20240930_re_aw34735d3a4s5ybwraoeym2z3m/node_modules/next/dist/build/webpack/loaders/next-app-loader/index.js?name=app%2Fapp-edge-ssr%2Fpage&page=%2Fapp-edge-ssr%2Fpage&pagePath=private-next-app-dir%2Fapp-edge-ssr%2Fpage.js&appDir=%2Ftmp%2Fnext-statsQ13pbp%2Fstats-app%2Fapp&appPaths=%2Fapp-edge-ssr%2Fpage&pageExtensions=tsx&pageExtensions=ts&pageExtensions=jsx&pageExtensions=js&basePath=&assetPrefix=&nextConfigOutput=&flyingShuttle=false&preferredRegion=&middlewareConfig=e30%3D!./app/app-edge-ssr/page.js?__next_edge_ssr_entry__
+      // NAMESPACE OBJECT: ./node_modules/.pnpm/next@file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-2d16326d-20240930_re_twsodcu6u2xc4vttzu7xhu5gra/node_modules/next/dist/build/webpack/loaders/next-app-loader/index.js?name=app%2Fapp-edge-ssr%2Fpage&page=%2Fapp-edge-ssr%2Fpage&pagePath=private-next-app-dir%2Fapp-edge-ssr%2Fpage.js&appDir=%2Ftmp%2Fnext-statsQ13pbp%2Fstats-app%2Fapp&appPaths=%2Fapp-edge-ssr%2Fpage&pageExtensions=tsx&pageExtensions=ts&pageExtensions=jsx&pageExtensions=js&basePath=&assetPrefix=&nextConfigOutput=&flyingShuttle=false&preferredRegion=&middlewareConfig=e30%3D!./app/app-edge-ssr/page.js?__next_edge_ssr_entry__
       var page_next_edge_ssr_entry_namespaceObject = {};
       __webpack_require__.r(page_next_edge_ssr_entry_namespaceObject);
       __webpack_require__.d(page_next_edge_ssr_entry_namespaceObject, {
@@ -80,35 +80,35 @@
         workUnitAsyncStorage: () => entry_base /* workUnitAsyncStorage */.Sz,
       });
 
-      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-2d16326d-20240930_re_aw34735d3a4s5ybwraoeym2z3m/node_modules/next/dist/esm/server/web/globals.js
-      var globals = __webpack_require__(786);
-      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-2d16326d-20240930_re_aw34735d3a4s5ybwraoeym2z3m/node_modules/next/dist/esm/server/web/adapter.js + 3 modules
-      var adapter = __webpack_require__(6671);
-      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-2d16326d-20240930_re_aw34735d3a4s5ybwraoeym2z3m/node_modules/next/dist/esm/build/webpack/loaders/next-edge-ssr-loader/render.js + 88 modules
-      var render = __webpack_require__(3276);
-      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-2d16326d-20240930_re_aw34735d3a4s5ybwraoeym2z3m/node_modules/next/dist/esm/server/lib/incremental-cache/index.js + 3 modules
-      var incremental_cache = __webpack_require__(3048);
-      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-2d16326d-20240930_re_aw34735d3a4s5ybwraoeym2z3m/node_modules/next/dist/esm/server/app-render/app-render.js + 61 modules
-      var app_render = __webpack_require__(8695);
-      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-2d16326d-20240930_re_aw34735d3a4s5ybwraoeym2z3m/node_modules/next/dist/esm/server/route-modules/app-page/module.compiled.js
-      var module_compiled = __webpack_require__(8320);
-      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-2d16326d-20240930_re_aw34735d3a4s5ybwraoeym2z3m/node_modules/next/dist/esm/server/route-kind.js
-      var route_kind = __webpack_require__(6965);
-      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-2d16326d-20240930_re_aw34735d3a4s5ybwraoeym2z3m/node_modules/next/dist/esm/client/components/error-boundary.js
-      var error_boundary = __webpack_require__(3226);
-      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-2d16326d-20240930_re_aw34735d3a4s5ybwraoeym2z3m/node_modules/next/dist/esm/server/app-render/entry-base.js + 29 modules
-      var entry_base = __webpack_require__(6950); // CONCATENATED MODULE: ./node_modules/.pnpm/next@file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-2d16326d-20240930_re_aw34735d3a4s5ybwraoeym2z3m/node_modules/next/dist/build/webpack/loaders/next-app-loader/index.js?name=app%2Fapp-edge-ssr%2Fpage&page=%2Fapp-edge-ssr%2Fpage&pagePath=private-next-app-dir%2Fapp-edge-ssr%2Fpage.js&appDir=%2Ftmp%2Fnext-statsQ13pbp%2Fstats-app%2Fapp&appPaths=%2Fapp-edge-ssr%2Fpage&pageExtensions=tsx&pageExtensions=ts&pageExtensions=jsx&pageExtensions=js&basePath=&assetPrefix=&nextConfigOutput=&flyingShuttle=false&preferredRegion=&middlewareConfig=e30%3D!./app/app-edge-ssr/page.js?__next_edge_ssr_entry__
+      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-2d16326d-20240930_re_twsodcu6u2xc4vttzu7xhu5gra/node_modules/next/dist/esm/server/web/globals.js
+      var globals = __webpack_require__(7371);
+      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-2d16326d-20240930_re_twsodcu6u2xc4vttzu7xhu5gra/node_modules/next/dist/esm/server/web/adapter.js + 3 modules
+      var adapter = __webpack_require__(4654);
+      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-2d16326d-20240930_re_twsodcu6u2xc4vttzu7xhu5gra/node_modules/next/dist/esm/build/webpack/loaders/next-edge-ssr-loader/render.js + 88 modules
+      var render = __webpack_require__(3880);
+      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-2d16326d-20240930_re_twsodcu6u2xc4vttzu7xhu5gra/node_modules/next/dist/esm/server/lib/incremental-cache/index.js + 3 modules
+      var incremental_cache = __webpack_require__(1622);
+      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-2d16326d-20240930_re_twsodcu6u2xc4vttzu7xhu5gra/node_modules/next/dist/esm/server/app-render/app-render.js + 61 modules
+      var app_render = __webpack_require__(4889);
+      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-2d16326d-20240930_re_twsodcu6u2xc4vttzu7xhu5gra/node_modules/next/dist/esm/server/route-modules/app-page/module.compiled.js
+      var module_compiled = __webpack_require__(4672);
+      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-2d16326d-20240930_re_twsodcu6u2xc4vttzu7xhu5gra/node_modules/next/dist/esm/server/route-kind.js
+      var route_kind = __webpack_require__(764);
+      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-2d16326d-20240930_re_twsodcu6u2xc4vttzu7xhu5gra/node_modules/next/dist/esm/client/components/error-boundary.js
+      var error_boundary = __webpack_require__(5978);
+      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-2d16326d-20240930_re_twsodcu6u2xc4vttzu7xhu5gra/node_modules/next/dist/esm/server/app-render/entry-base.js + 29 modules
+      var entry_base = __webpack_require__(1388); // CONCATENATED MODULE: ./node_modules/.pnpm/next@file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-2d16326d-20240930_re_twsodcu6u2xc4vttzu7xhu5gra/node_modules/next/dist/build/webpack/loaders/next-app-loader/index.js?name=app%2Fapp-edge-ssr%2Fpage&page=%2Fapp-edge-ssr%2Fpage&pagePath=private-next-app-dir%2Fapp-edge-ssr%2Fpage.js&appDir=%2Ftmp%2Fnext-statsQ13pbp%2Fstats-app%2Fapp&appPaths=%2Fapp-edge-ssr%2Fpage&pageExtensions=tsx&pageExtensions=ts&pageExtensions=jsx&pageExtensions=js&basePath=&assetPrefix=&nextConfigOutput=&flyingShuttle=false&preferredRegion=&middlewareConfig=e30%3D!./app/app-edge-ssr/page.js?__next_edge_ssr_entry__
       const module0 = () =>
         Promise.resolve(/* import() eager */).then(
-          __webpack_require__.bind(__webpack_require__, 4836)
+          __webpack_require__.bind(__webpack_require__, 6603)
         );
       const module1 = () =>
         Promise.resolve(/* import() eager */).then(
-          __webpack_require__.bind(__webpack_require__, 2881)
+          __webpack_require__.bind(__webpack_require__, 8334)
         );
       const page2 = () =>
         Promise.resolve(/* import() eager */).then(
-          __webpack_require__.bind(__webpack_require__, 2596)
+          __webpack_require__.bind(__webpack_require__, 6258)
         );
 
       // We inject the tree and pages here so that we can use them in the route
@@ -171,12 +171,12 @@
       });
 
       //# sourceMappingURL=app-page.js.map
-      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-2d16326d-20240930_re_aw34735d3a4s5ybwraoeym2z3m/node_modules/next/dist/esm/lib/page-types.js
-      var page_types = __webpack_require__(9641);
-      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-2d16326d-20240930_re_aw34735d3a4s5ybwraoeym2z3m/node_modules/next/dist/esm/server/app-render/encryption-utils.js
-      var encryption_utils = __webpack_require__(2663);
-      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-2d16326d-20240930_re_aw34735d3a4s5ybwraoeym2z3m/node_modules/next/dist/esm/server/app-render/action-utils.js
-      var action_utils = __webpack_require__(497); // CONCATENATED MODULE: ./node_modules/.pnpm/next@file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-2d16326d-20240930_re_aw34735d3a4s5ybwraoeym2z3m/node_modules/next/dist/build/webpack/loaders/next-edge-ssr-loader/index.js?{"absolute500Path":"","absoluteAppPath":"next/dist/pages/_app","absoluteDocumentPath":"next/dist/pages/_document","absoluteErrorPath":"next/dist/pages/_error","absolutePagePath":"private-next-app-dir/app-edge-ssr/page.js","dev":false,"isServerComponent":true,"page":"/app-edge-ssr/page","stringifiedConfig":"eyJlbnYiOnt9LCJlc2xpbnQiOnsiaWdub3JlRHVyaW5nQnVpbGRzIjpmYWxzZX0sInR5cGVzY3JpcHQiOnsiaWdub3JlQnVpbGRFcnJvcnMiOmZhbHNlLCJ0c2NvbmZpZ1BhdGgiOiJ0c2NvbmZpZy5qc29uIn0sImRpc3REaXIiOiIubmV4dCIsImNsZWFuRGlzdERpciI6dHJ1ZSwiYXNzZXRQcmVmaXgiOiIiLCJjYWNoZU1heE1lbW9yeVNpemUiOjUyNDI4ODAwLCJjb25maWdPcmlnaW4iOiJuZXh0LmNvbmZpZy5qcyIsInVzZUZpbGVTeXN0ZW1QdWJsaWNSb3V0ZXMiOnRydWUsImdlbmVyYXRlRXRhZ3MiOnRydWUsInBhZ2VFeHRlbnNpb25zIjpbInRzeCIsInRzIiwianN4IiwianMiXSwicG93ZXJlZEJ5SGVhZGVyIjp0cnVlLCJjb21wcmVzcyI6dHJ1ZSwiaW1hZ2VzIjp7ImRldmljZVNpemVzIjpbNjQwLDc1MCw4MjgsMTA4MCwxMjAwLDE5MjAsMjA0OCwzODQwXSwiaW1hZ2VTaXplcyI6WzE2LDMyLDQ4LDY0LDk2LDEyOCwyNTYsMzg0XSwicGF0aCI6Ii9fbmV4dC9pbWFnZSIsImxvYWRlciI6ImRlZmF1bHQiLCJsb2FkZXJGaWxlIjoiIiwiZG9tYWlucyI6W10sImRpc2FibGVTdGF0aWNJbWFnZXMiOmZhbHNlLCJtaW5pbXVtQ2FjaGVUVEwiOjYwLCJmb3JtYXRzIjpbImltYWdlL3dlYnAiXSwiZGFuZ2Vyb3VzbHlBbGxvd1NWRyI6ZmFsc2UsImNvbnRlbnRTZWN1cml0eVBvbGljeSI6InNjcmlwdC1zcmMgJ25vbmUnOyBmcmFtZS1zcmMgJ25vbmUnOyBzYW5kYm94OyIsImNvbnRlbnREaXNwb3NpdGlvblR5cGUiOiJhdHRhY2htZW50IiwicmVtb3RlUGF0dGVybnMiOltdLCJ1bm9wdGltaXplZCI6ZmFsc2V9LCJkZXZJbmRpY2F0b3JzIjp7ImFwcElzclN0YXR1cyI6dHJ1ZSwiYnVpbGRBY3Rpdml0eSI6dHJ1ZSwiYnVpbGRBY3Rpdml0eVBvc2l0aW9uIjoiYm90dG9tLXJpZ2h0In0sIm9uRGVtYW5kRW50cmllcyI6eyJtYXhJbmFjdGl2ZUFnZSI6NjAwMDAsInBhZ2VzQnVmZmVyTGVuZ3RoIjo1fSwiYW1wIjp7ImNhbm9uaWNhbEJhc2UiOiIifSwiYmFzZVBhdGgiOiIiLCJzYXNzT3B0aW9ucyI6e30sInRyYWlsaW5nU2xhc2giOmZhbHNlLCJpMThuIjpudWxsLCJwcm9kdWN0aW9uQnJvd3NlclNvdXJjZU1hcHMiOmZhbHNlLCJleGNsdWRlRGVmYXVsdE1vbWVudExvY2FsZXMiOnRydWUsInNlcnZlclJ1bnRpbWVDb25maWciOnt9LCJwdWJsaWNSdW50aW1lQ29uZmlnIjp7fSwicmVhY3RQcm9kdWN0aW9uUHJvZmlsaW5nIjpmYWxzZSwicmVhY3RTdHJpY3RNb2RlIjpudWxsLCJyZWFjdE1heEhlYWRlcnNMZW5ndGgiOjYwMDAsImh0dHBBZ2VudE9wdGlvbnMiOnsia2VlcEFsaXZlIjp0cnVlfSwibG9nZ2luZyI6e30sInN3ckRlbHRhIjozMTUzNjAwMCwic3RhdGljUGFnZUdlbmVyYXRpb25UaW1lb3V0Ijo2MCwibW9kdWxhcml6ZUltcG9ydHMiOnsiQG11aS9pY29ucy1tYXRlcmlhbCI6eyJ0cmFuc2Zvcm0iOiJAbXVpL2ljb25zLW1hdGVyaWFsL3t7bWVtYmVyfX0ifSwibG9kYXNoIjp7InRyYW5zZm9ybSI6ImxvZGFzaC97e21lbWJlcn19In19LCJvdXRwdXRGaWxlVHJhY2luZ1Jvb3QiOiIvdG1wL25leHQtc3RhdHNRMTNwYnAvc3RhdHMtYXBwIiwiZXhwZXJpbWVudGFsIjp7Im11bHRpWm9uZURyYWZ0TW9kZSI6ZmFsc2UsImFwcE5hdkZhaWxIYW5kbGluZyI6ZmFsc2UsInByZXJlbmRlckVhcmx5RXhpdCI6dHJ1ZSwic2VydmVyTWluaWZpY2F0aW9uIjp0cnVlLCJzZXJ2ZXJTb3VyY2VNYXBzIjpmYWxzZSwibGlua05vVG91Y2hTdGFydCI6ZmFsc2UsImNhc2VTZW5zaXRpdmVSb3V0ZXMiOmZhbHNlLCJwcmVsb2FkRW50cmllc09uU3RhcnQiOnRydWUsImNsaWVudFJvdXRlckZpbHRlciI6dHJ1ZSwiY2xpZW50Um91dGVyRmlsdGVyUmVkaXJlY3RzIjpmYWxzZSwiZmV0Y2hDYWNoZUtleVByZWZpeCI6IiIsIm1pZGRsZXdhcmVQcmVmZXRjaCI6ImZsZXhpYmxlIiwib3B0aW1pc3RpY0NsaWVudENhY2hlIjp0cnVlLCJtYW51YWxDbGllbnRCYXNlUGF0aCI6ZmFsc2UsImNwdXMiOjE5LCJtZW1vcnlCYXNlZFdvcmtlcnNDb3VudCI6ZmFsc2UsImlzckZsdXNoVG9EaXNrIjp0cnVlLCJ3b3JrZXJUaHJlYWRzIjpmYWxzZSwib3B0aW1pemVDc3MiOmZhbHNlLCJuZXh0U2NyaXB0V29ya2VycyI6ZmFsc2UsInNjcm9sbFJlc3RvcmF0aW9uIjpmYWxzZSwiZXh0ZXJuYWxEaXIiOmZhbHNlLCJkaXNhYmxlT3B0aW1pemVkTG9hZGluZyI6ZmFsc2UsImd6aXBTaXplIjp0cnVlLCJjcmFDb21wYXQiOmZhbHNlLCJlc21FeHRlcm5hbHMiOnRydWUsImZ1bGx5U3BlY2lmaWVkIjpmYWxzZSwic3djVHJhY2VQcm9maWxpbmciOmZhbHNlLCJmb3JjZVN3Y1RyYW5zZm9ybXMiOmZhbHNlLCJsYXJnZVBhZ2VEYXRhQnl0ZXMiOjEyODAwMCwidHVyYm8iOnsicm9vdCI6Ii90bXAvbmV4dC1zdGF0c1ExM3BicC9zdGF0cy1hcHAifSwidHlwZWRSb3V0ZXMiOmZhbHNlLCJ0eXBlZEVudiI6ZmFsc2UsInBhcmFsbGVsU2VydmVyQ29tcGlsZXMiOmZhbHNlLCJwYXJhbGxlbFNlcnZlckJ1aWxkVHJhY2VzIjpmYWxzZSwicHByIjpmYWxzZSwicHByRmFsbGJhY2tzIjpmYWxzZSwid2VicGFja01lbW9yeU9wdGltaXphdGlvbnMiOmZhbHNlLCJvcHRpbWl6ZVNlcnZlclJlYWN0Ijp0cnVlLCJ1c2VFYXJseUltcG9ydCI6ZmFsc2UsInN0YWxlVGltZXMiOnsiZHluYW1pYyI6MCwic3RhdGljIjozMDB9LCJhZnRlciI6ZmFsc2UsInNlcnZlckNvbXBvbmVudHNIbXJDYWNoZSI6dHJ1ZSwic3RhdGljR2VuZXJhdGlvbk1heENvbmN1cnJlbmN5Ijo4LCJzdGF0aWNHZW5lcmF0aW9uTWluUGFnZXNQZXJXb3JrZXIiOjI1LCJkeW5hbWljSU8iOmZhbHNlLCJvcHRpbWl6ZVBhY2thZ2VJbXBvcnRzIjpbImx1Y2lkZS1yZWFjdCIsImRhdGUtZm5zIiwibG9kYXNoLWVzIiwicmFtZGEiLCJhbnRkIiwicmVhY3QtYm9vdHN0cmFwIiwiYWhvb2tzIiwiQGFudC1kZXNpZ24vaWNvbnMiLCJAaGVhZGxlc3N1aS9yZWFjdCIsIkBoZWFkbGVzc3VpLWZsb2F0L3JlYWN0IiwiQGhlcm9pY29ucy9yZWFjdC8yMC9zb2xpZCIsIkBoZXJvaWNvbnMvcmVhY3QvMjQvc29saWQiLCJAaGVyb2ljb25zL3JlYWN0LzI0L291dGxpbmUiLCJAdmlzeC92aXN4IiwiQHRyZW1vci9yZWFjdCIsInJ4anMiLCJAbXVpL21hdGVyaWFsIiwiQG11aS9pY29ucy1tYXRlcmlhbCIsInJlY2hhcnRzIiwicmVhY3QtdXNlIiwiZWZmZWN0IiwiQGVmZmVjdC9zY2hlbWEiLCJAZWZmZWN0L3BsYXRmb3JtIiwiQGVmZmVjdC9wbGF0Zm9ybS1ub2RlIiwiQGVmZmVjdC9wbGF0Zm9ybS1icm93c2VyIiwiQGVmZmVjdC9wbGF0Zm9ybS1idW4iLCJAZWZmZWN0L3NxbCIsIkBlZmZlY3Qvc3FsLW1zc3FsIiwiQGVmZmVjdC9zcWwtbXlzcWwyIiwiQGVmZmVjdC9zcWwtcGciLCJAZWZmZWN0L3NxbC1zcXVsaXRlLW5vZGUiLCJAZWZmZWN0L3NxbC1zcXVsaXRlLWJ1biIsIkBlZmZlY3Qvc3FsLXNxdWxpdGUtd2FzbSIsIkBlZmZlY3Qvc3FsLXNxdWxpdGUtcmVhY3QtbmF0aXZlIiwiQGVmZmVjdC9ycGMiLCJAZWZmZWN0L3JwYy1odHRwIiwiQGVmZmVjdC90eXBlY2xhc3MiLCJAZWZmZWN0L2V4cGVyaW1lbnRhbCIsIkBlZmZlY3Qvb3BlbnRlbGVtZXRyeSIsIkBtYXRlcmlhbC11aS9jb3JlIiwiQG1hdGVyaWFsLXVpL2ljb25zIiwiQHRhYmxlci9pY29ucy1yZWFjdCIsIm11aS1jb3JlIiwicmVhY3QtaWNvbnMvYWkiLCJyZWFjdC1pY29ucy9iaSIsInJlYWN0LWljb25zL2JzIiwicmVhY3QtaWNvbnMvY2ciLCJyZWFjdC1pY29ucy9jaSIsInJlYWN0LWljb25zL2RpIiwicmVhY3QtaWNvbnMvZmEiLCJyZWFjdC1pY29ucy9mYTYiLCJyZWFjdC1pY29ucy9mYyIsInJlYWN0LWljb25zL2ZpIiwicmVhY3QtaWNvbnMvZ2kiLCJyZWFjdC1pY29ucy9nbyIsInJlYWN0LWljb25zL2dyIiwicmVhY3QtaWNvbnMvaGkiLCJyZWFjdC1pY29ucy9oaTIiLCJyZWFjdC1pY29ucy9pbSIsInJlYWN0LWljb25zL2lvIiwicmVhY3QtaWNvbnMvaW81IiwicmVhY3QtaWNvbnMvbGlhIiwicmVhY3QtaWNvbnMvbGliIiwicmVhY3QtaWNvbnMvbHUiLCJyZWFjdC1pY29ucy9tZCIsInJlYWN0LWljb25zL3BpIiwicmVhY3QtaWNvbnMvcmkiLCJyZWFjdC1pY29ucy9yeCIsInJlYWN0LWljb25zL3NpIiwicmVhY3QtaWNvbnMvc2wiLCJyZWFjdC1pY29ucy90YiIsInJlYWN0LWljb25zL3RmaSIsInJlYWN0LWljb25zL3RpIiwicmVhY3QtaWNvbnMvdnNjIiwicmVhY3QtaWNvbnMvd2kiXX0sImJ1bmRsZVBhZ2VzUm91dGVyRGVwZW5kZW5jaWVzIjpmYWxzZSwiY29uZmlnRmlsZSI6Ii90bXAvbmV4dC1zdGF0c1ExM3BicC9zdGF0cy1hcHAvbmV4dC5jb25maWcuanMiLCJjb25maWdGaWxlTmFtZSI6Im5leHQuY29uZmlnLmpzIn0=","pagesType":"app","appDirLoader":"bmV4dC1hcHAtbG9hZGVyP25hbWU9YXBwJTJGYXBwLWVkZ2Utc3NyJTJGcGFnZSZwYWdlPSUyRmFwcC1lZGdlLXNzciUyRnBhZ2UmcGFnZVBhdGg9cHJpdmF0ZS1uZXh0LWFwcC1kaXIlMkZhcHAtZWRnZS1zc3IlMkZwYWdlLmpzJmFwcERpcj0lMkZ0bXAlMkZuZXh0LXN0YXRzUTEzcGJwJTJGc3RhdHMtYXBwJTJGYXBwJmFwcFBhdGhzPSUyRmFwcC1lZGdlLXNzciUyRnBhZ2UmcGFnZUV4dGVuc2lvbnM9dHN4JnBhZ2VFeHRlbnNpb25zPXRzJnBhZ2VFeHRlbnNpb25zPWpzeCZwYWdlRXh0ZW5zaW9ucz1qcyZiYXNlUGF0aD0mYXNzZXRQcmVmaXg9Jm5leHRDb25maWdPdXRwdXQ9JmZseWluZ1NodXR0bGU9ZmFsc2UmcHJlZmVycmVkUmVnaW9uPSZtaWRkbGV3YXJlQ29uZmlnPWUzMCUzRCE=","sriEnabled":false,"middlewareConfig":"e30="}!
+      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-2d16326d-20240930_re_twsodcu6u2xc4vttzu7xhu5gra/node_modules/next/dist/esm/lib/page-types.js
+      var page_types = __webpack_require__(9544);
+      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-2d16326d-20240930_re_twsodcu6u2xc4vttzu7xhu5gra/node_modules/next/dist/esm/server/app-render/encryption-utils.js
+      var encryption_utils = __webpack_require__(1028);
+      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-2d16326d-20240930_re_twsodcu6u2xc4vttzu7xhu5gra/node_modules/next/dist/esm/server/app-render/action-utils.js
+      var action_utils = __webpack_require__(6273); // CONCATENATED MODULE: ./node_modules/.pnpm/next@file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-2d16326d-20240930_re_twsodcu6u2xc4vttzu7xhu5gra/node_modules/next/dist/build/webpack/loaders/next-edge-ssr-loader/index.js?{"absolute500Path":"","absoluteAppPath":"next/dist/pages/_app","absoluteDocumentPath":"next/dist/pages/_document","absoluteErrorPath":"next/dist/pages/_error","absolutePagePath":"private-next-app-dir/app-edge-ssr/page.js","dev":false,"isServerComponent":true,"page":"/app-edge-ssr/page","stringifiedConfig":"eyJlbnYiOnt9LCJlc2xpbnQiOnsiaWdub3JlRHVyaW5nQnVpbGRzIjpmYWxzZX0sInR5cGVzY3JpcHQiOnsiaWdub3JlQnVpbGRFcnJvcnMiOmZhbHNlLCJ0c2NvbmZpZ1BhdGgiOiJ0c2NvbmZpZy5qc29uIn0sImRpc3REaXIiOiIubmV4dCIsImNsZWFuRGlzdERpciI6dHJ1ZSwiYXNzZXRQcmVmaXgiOiIiLCJjYWNoZU1heE1lbW9yeVNpemUiOjUyNDI4ODAwLCJjb25maWdPcmlnaW4iOiJuZXh0LmNvbmZpZy5qcyIsInVzZUZpbGVTeXN0ZW1QdWJsaWNSb3V0ZXMiOnRydWUsImdlbmVyYXRlRXRhZ3MiOnRydWUsInBhZ2VFeHRlbnNpb25zIjpbInRzeCIsInRzIiwianN4IiwianMiXSwicG93ZXJlZEJ5SGVhZGVyIjp0cnVlLCJjb21wcmVzcyI6dHJ1ZSwiaW1hZ2VzIjp7ImRldmljZVNpemVzIjpbNjQwLDc1MCw4MjgsMTA4MCwxMjAwLDE5MjAsMjA0OCwzODQwXSwiaW1hZ2VTaXplcyI6WzE2LDMyLDQ4LDY0LDk2LDEyOCwyNTYsMzg0XSwicGF0aCI6Ii9fbmV4dC9pbWFnZSIsImxvYWRlciI6ImRlZmF1bHQiLCJsb2FkZXJGaWxlIjoiIiwiZG9tYWlucyI6W10sImRpc2FibGVTdGF0aWNJbWFnZXMiOmZhbHNlLCJtaW5pbXVtQ2FjaGVUVEwiOjYwLCJmb3JtYXRzIjpbImltYWdlL3dlYnAiXSwiZGFuZ2Vyb3VzbHlBbGxvd1NWRyI6ZmFsc2UsImNvbnRlbnRTZWN1cml0eVBvbGljeSI6InNjcmlwdC1zcmMgJ25vbmUnOyBmcmFtZS1zcmMgJ25vbmUnOyBzYW5kYm94OyIsImNvbnRlbnREaXNwb3NpdGlvblR5cGUiOiJhdHRhY2htZW50IiwicmVtb3RlUGF0dGVybnMiOltdLCJ1bm9wdGltaXplZCI6ZmFsc2V9LCJkZXZJbmRpY2F0b3JzIjp7ImFwcElzclN0YXR1cyI6dHJ1ZSwiYnVpbGRBY3Rpdml0eSI6dHJ1ZSwiYnVpbGRBY3Rpdml0eVBvc2l0aW9uIjoiYm90dG9tLXJpZ2h0In0sIm9uRGVtYW5kRW50cmllcyI6eyJtYXhJbmFjdGl2ZUFnZSI6NjAwMDAsInBhZ2VzQnVmZmVyTGVuZ3RoIjo1fSwiYW1wIjp7ImNhbm9uaWNhbEJhc2UiOiIifSwiYmFzZVBhdGgiOiIiLCJzYXNzT3B0aW9ucyI6e30sInRyYWlsaW5nU2xhc2giOmZhbHNlLCJpMThuIjpudWxsLCJwcm9kdWN0aW9uQnJvd3NlclNvdXJjZU1hcHMiOmZhbHNlLCJleGNsdWRlRGVmYXVsdE1vbWVudExvY2FsZXMiOnRydWUsInNlcnZlclJ1bnRpbWVDb25maWciOnt9LCJwdWJsaWNSdW50aW1lQ29uZmlnIjp7fSwicmVhY3RQcm9kdWN0aW9uUHJvZmlsaW5nIjpmYWxzZSwicmVhY3RTdHJpY3RNb2RlIjpudWxsLCJyZWFjdE1heEhlYWRlcnNMZW5ndGgiOjYwMDAsImh0dHBBZ2VudE9wdGlvbnMiOnsia2VlcEFsaXZlIjp0cnVlfSwibG9nZ2luZyI6e30sInN3ckRlbHRhIjozMTUzNjAwMCwic3RhdGljUGFnZUdlbmVyYXRpb25UaW1lb3V0Ijo2MCwibW9kdWxhcml6ZUltcG9ydHMiOnsiQG11aS9pY29ucy1tYXRlcmlhbCI6eyJ0cmFuc2Zvcm0iOiJAbXVpL2ljb25zLW1hdGVyaWFsL3t7bWVtYmVyfX0ifSwibG9kYXNoIjp7InRyYW5zZm9ybSI6ImxvZGFzaC97e21lbWJlcn19In19LCJvdXRwdXRGaWxlVHJhY2luZ1Jvb3QiOiIvdG1wL25leHQtc3RhdHNRMTNwYnAvc3RhdHMtYXBwIiwiZXhwZXJpbWVudGFsIjp7Im11bHRpWm9uZURyYWZ0TW9kZSI6ZmFsc2UsImFwcE5hdkZhaWxIYW5kbGluZyI6ZmFsc2UsInByZXJlbmRlckVhcmx5RXhpdCI6dHJ1ZSwic2VydmVyTWluaWZpY2F0aW9uIjp0cnVlLCJzZXJ2ZXJTb3VyY2VNYXBzIjpmYWxzZSwibGlua05vVG91Y2hTdGFydCI6ZmFsc2UsImNhc2VTZW5zaXRpdmVSb3V0ZXMiOmZhbHNlLCJwcmVsb2FkRW50cmllc09uU3RhcnQiOnRydWUsImNsaWVudFJvdXRlckZpbHRlciI6dHJ1ZSwiY2xpZW50Um91dGVyRmlsdGVyUmVkaXJlY3RzIjpmYWxzZSwiZmV0Y2hDYWNoZUtleVByZWZpeCI6IiIsIm1pZGRsZXdhcmVQcmVmZXRjaCI6ImZsZXhpYmxlIiwib3B0aW1pc3RpY0NsaWVudENhY2hlIjp0cnVlLCJtYW51YWxDbGllbnRCYXNlUGF0aCI6ZmFsc2UsImNwdXMiOjE5LCJtZW1vcnlCYXNlZFdvcmtlcnNDb3VudCI6ZmFsc2UsImlzckZsdXNoVG9EaXNrIjp0cnVlLCJ3b3JrZXJUaHJlYWRzIjpmYWxzZSwib3B0aW1pemVDc3MiOmZhbHNlLCJuZXh0U2NyaXB0V29ya2VycyI6ZmFsc2UsInNjcm9sbFJlc3RvcmF0aW9uIjpmYWxzZSwiZXh0ZXJuYWxEaXIiOmZhbHNlLCJkaXNhYmxlT3B0aW1pemVkTG9hZGluZyI6ZmFsc2UsImd6aXBTaXplIjp0cnVlLCJjcmFDb21wYXQiOmZhbHNlLCJlc21FeHRlcm5hbHMiOnRydWUsImZ1bGx5U3BlY2lmaWVkIjpmYWxzZSwic3djVHJhY2VQcm9maWxpbmciOmZhbHNlLCJmb3JjZVN3Y1RyYW5zZm9ybXMiOmZhbHNlLCJsYXJnZVBhZ2VEYXRhQnl0ZXMiOjEyODAwMCwidHVyYm8iOnsicm9vdCI6Ii90bXAvbmV4dC1zdGF0c1ExM3BicC9zdGF0cy1hcHAifSwidHlwZWRSb3V0ZXMiOmZhbHNlLCJ0eXBlZEVudiI6ZmFsc2UsInBhcmFsbGVsU2VydmVyQ29tcGlsZXMiOmZhbHNlLCJwYXJhbGxlbFNlcnZlckJ1aWxkVHJhY2VzIjpmYWxzZSwicHByIjpmYWxzZSwicHByRmFsbGJhY2tzIjpmYWxzZSwid2VicGFja01lbW9yeU9wdGltaXphdGlvbnMiOmZhbHNlLCJvcHRpbWl6ZVNlcnZlclJlYWN0Ijp0cnVlLCJ1c2VFYXJseUltcG9ydCI6ZmFsc2UsInN0YWxlVGltZXMiOnsiZHluYW1pYyI6MCwic3RhdGljIjozMDB9LCJhZnRlciI6ZmFsc2UsInNlcnZlckNvbXBvbmVudHNIbXJDYWNoZSI6dHJ1ZSwic3RhdGljR2VuZXJhdGlvbk1heENvbmN1cnJlbmN5Ijo4LCJzdGF0aWNHZW5lcmF0aW9uTWluUGFnZXNQZXJXb3JrZXIiOjI1LCJkeW5hbWljSU8iOmZhbHNlLCJvcHRpbWl6ZVBhY2thZ2VJbXBvcnRzIjpbImx1Y2lkZS1yZWFjdCIsImRhdGUtZm5zIiwibG9kYXNoLWVzIiwicmFtZGEiLCJhbnRkIiwicmVhY3QtYm9vdHN0cmFwIiwiYWhvb2tzIiwiQGFudC1kZXNpZ24vaWNvbnMiLCJAaGVhZGxlc3N1aS9yZWFjdCIsIkBoZWFkbGVzc3VpLWZsb2F0L3JlYWN0IiwiQGhlcm9pY29ucy9yZWFjdC8yMC9zb2xpZCIsIkBoZXJvaWNvbnMvcmVhY3QvMjQvc29saWQiLCJAaGVyb2ljb25zL3JlYWN0LzI0L291dGxpbmUiLCJAdmlzeC92aXN4IiwiQHRyZW1vci9yZWFjdCIsInJ4anMiLCJAbXVpL21hdGVyaWFsIiwiQG11aS9pY29ucy1tYXRlcmlhbCIsInJlY2hhcnRzIiwicmVhY3QtdXNlIiwiZWZmZWN0IiwiQGVmZmVjdC9zY2hlbWEiLCJAZWZmZWN0L3BsYXRmb3JtIiwiQGVmZmVjdC9wbGF0Zm9ybS1ub2RlIiwiQGVmZmVjdC9wbGF0Zm9ybS1icm93c2VyIiwiQGVmZmVjdC9wbGF0Zm9ybS1idW4iLCJAZWZmZWN0L3NxbCIsIkBlZmZlY3Qvc3FsLW1zc3FsIiwiQGVmZmVjdC9zcWwtbXlzcWwyIiwiQGVmZmVjdC9zcWwtcGciLCJAZWZmZWN0L3NxbC1zcXVsaXRlLW5vZGUiLCJAZWZmZWN0L3NxbC1zcXVsaXRlLWJ1biIsIkBlZmZlY3Qvc3FsLXNxdWxpdGUtd2FzbSIsIkBlZmZlY3Qvc3FsLXNxdWxpdGUtcmVhY3QtbmF0aXZlIiwiQGVmZmVjdC9ycGMiLCJAZWZmZWN0L3JwYy1odHRwIiwiQGVmZmVjdC90eXBlY2xhc3MiLCJAZWZmZWN0L2V4cGVyaW1lbnRhbCIsIkBlZmZlY3Qvb3BlbnRlbGVtZXRyeSIsIkBtYXRlcmlhbC11aS9jb3JlIiwiQG1hdGVyaWFsLXVpL2ljb25zIiwiQHRhYmxlci9pY29ucy1yZWFjdCIsIm11aS1jb3JlIiwicmVhY3QtaWNvbnMvYWkiLCJyZWFjdC1pY29ucy9iaSIsInJlYWN0LWljb25zL2JzIiwicmVhY3QtaWNvbnMvY2ciLCJyZWFjdC1pY29ucy9jaSIsInJlYWN0LWljb25zL2RpIiwicmVhY3QtaWNvbnMvZmEiLCJyZWFjdC1pY29ucy9mYTYiLCJyZWFjdC1pY29ucy9mYyIsInJlYWN0LWljb25zL2ZpIiwicmVhY3QtaWNvbnMvZ2kiLCJyZWFjdC1pY29ucy9nbyIsInJlYWN0LWljb25zL2dyIiwicmVhY3QtaWNvbnMvaGkiLCJyZWFjdC1pY29ucy9oaTIiLCJyZWFjdC1pY29ucy9pbSIsInJlYWN0LWljb25zL2lvIiwicmVhY3QtaWNvbnMvaW81IiwicmVhY3QtaWNvbnMvbGlhIiwicmVhY3QtaWNvbnMvbGliIiwicmVhY3QtaWNvbnMvbHUiLCJyZWFjdC1pY29ucy9tZCIsInJlYWN0LWljb25zL3BpIiwicmVhY3QtaWNvbnMvcmkiLCJyZWFjdC1pY29ucy9yeCIsInJlYWN0LWljb25zL3NpIiwicmVhY3QtaWNvbnMvc2wiLCJyZWFjdC1pY29ucy90YiIsInJlYWN0LWljb25zL3RmaSIsInJlYWN0LWljb25zL3RpIiwicmVhY3QtaWNvbnMvdnNjIiwicmVhY3QtaWNvbnMvd2kiXX0sImJ1bmRsZVBhZ2VzUm91dGVyRGVwZW5kZW5jaWVzIjpmYWxzZSwiY29uZmlnRmlsZSI6Ii90bXAvbmV4dC1zdGF0c1ExM3BicC9zdGF0cy1hcHAvbmV4dC5jb25maWcuanMiLCJjb25maWdGaWxlTmFtZSI6Im5leHQuY29uZmlnLmpzIn0=","pagesType":"app","appDirLoader":"bmV4dC1hcHAtbG9hZGVyP25hbWU9YXBwJTJGYXBwLWVkZ2Utc3NyJTJGcGFnZSZwYWdlPSUyRmFwcC1lZGdlLXNzciUyRnBhZ2UmcGFnZVBhdGg9cHJpdmF0ZS1uZXh0LWFwcC1kaXIlMkZhcHAtZWRnZS1zc3IlMkZwYWdlLmpzJmFwcERpcj0lMkZ0bXAlMkZuZXh0LXN0YXRzUTEzcGJwJTJGc3RhdHMtYXBwJTJGYXBwJmFwcFBhdGhzPSUyRmFwcC1lZGdlLXNzciUyRnBhZ2UmcGFnZUV4dGVuc2lvbnM9dHN4JnBhZ2VFeHRlbnNpb25zPXRzJnBhZ2VFeHRlbnNpb25zPWpzeCZwYWdlRXh0ZW5zaW9ucz1qcyZiYXNlUGF0aD0mYXNzZXRQcmVmaXg9Jm5leHRDb25maWdPdXRwdXQ9JmZseWluZ1NodXR0bGU9ZmFsc2UmcHJlZmVycmVkUmVnaW9uPSZtaWRkbGV3YXJlQ29uZmlnPWUzMCUzRCE=","sriEnabled":false,"middlewareConfig":"e30="}!
       var _self___RSC_MANIFEST;
 
       const incrementalCacheHandler = null;
@@ -441,56 +441,56 @@
       /***/
     },
 
-    /***/ 1847: /***/ (
+    /***/ 8136: /***/ (
       __unused_webpack_module,
       __unused_webpack_exports,
       __webpack_require__
     ) => {
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.bind(__webpack_require__, 7478)
+        __webpack_require__.bind(__webpack_require__, 203)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.bind(__webpack_require__, 3102)
+        __webpack_require__.bind(__webpack_require__, 2954)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.bind(__webpack_require__, 3908)
+        __webpack_require__.bind(__webpack_require__, 9995)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.bind(__webpack_require__, 2131)
+        __webpack_require__.bind(__webpack_require__, 865)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.bind(__webpack_require__, 8591)
+        __webpack_require__.bind(__webpack_require__, 1014)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.bind(__webpack_require__, 7981)
+        __webpack_require__.bind(__webpack_require__, 1059)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.bind(__webpack_require__, 6570)
+        __webpack_require__.bind(__webpack_require__, 6265)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.bind(__webpack_require__, 5074)
+        __webpack_require__.bind(__webpack_require__, 9348)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.bind(__webpack_require__, 1952)
+        __webpack_require__.bind(__webpack_require__, 4152)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.bind(__webpack_require__, 7139)
+        __webpack_require__.bind(__webpack_require__, 2571)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.bind(__webpack_require__, 1548)
+        __webpack_require__.bind(__webpack_require__, 4480)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.bind(__webpack_require__, 5936)
+        __webpack_require__.bind(__webpack_require__, 187)
       );
 
       /***/
     },
 
-    /***/ 6913: /***/ () => {
+    /***/ 232: /***/ () => {
       /***/
     },
 
-    /***/ 2596: /***/ (
+    /***/ 6258: /***/ (
       __unused_webpack_module,
       __webpack_exports__,
       __webpack_require__
@@ -510,7 +510,7 @@
       /***/
     },
 
-    /***/ 4836: /***/ (
+    /***/ 6603: /***/ (
       __unused_webpack_module,
       __webpack_exports__,
       __webpack_require__
@@ -522,7 +522,7 @@
         /* harmony export */
       });
       /* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ =
-        __webpack_require__(547);
+        __webpack_require__(648);
 
       function RootLayout({ children }) {
         return /*#__PURE__*/ (0,
@@ -541,7 +541,7 @@
     // webpackRuntimeModules
     /******/ var __webpack_exec__ = (moduleId) =>
       __webpack_require__((__webpack_require__.s = moduleId));
-    /******/ __webpack_require__.O(0, [129, 707], () => __webpack_exec__(4767));
+    /******/ __webpack_require__.O(0, [523, 582], () => __webpack_exec__(9759));
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ (_ENTRIES = typeof _ENTRIES === "undefined" ? {} : _ENTRIES)[
       "middleware_app/app-edge-ssr/page"
Diff for middleware.js

Diff too large to display

Diff for edge-ssr.js

Diff too large to display

Diff for image-HASH.js
@@ -1,7 +1,7 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [8358],
   {
-    /***/ 4519: /***/ (
+    /***/ 766: /***/ (
       __unused_webpack_module,
       __unused_webpack_exports,
       __webpack_require__
@@ -9,7 +9,7 @@
       (window.__NEXT_P = window.__NEXT_P || []).push([
         "/image",
         function () {
-          return __webpack_require__(6366);
+          return __webpack_require__(8898);
         },
       ]);
       if (false) {
@@ -18,7 +18,7 @@
       /***/
     },
 
-    /***/ 7847: /***/ (module, exports, __webpack_require__) => {
+    /***/ 8501: /***/ (module, exports, __webpack_require__) => {
       "use strict";
       /* __next_internal_client_entry_do_not_use__  cjs */
       Object.defineProperty(exports, "__esModule", {
@@ -40,17 +40,17 @@
         __webpack_require__(133)
       );
       const _head = /*#__PURE__*/ _interop_require_default._(
-        __webpack_require__(6142)
+        __webpack_require__(294)
       );
-      const _getimgprops = __webpack_require__(2989);
-      const _imageconfig = __webpack_require__(2948);
-      const _imageconfigcontextsharedruntime = __webpack_require__(3394);
-      const _warnonce = __webpack_require__(6308);
-      const _routercontextsharedruntime = __webpack_require__(932);
+      const _getimgprops = __webpack_require__(2367);
+      const _imageconfig = __webpack_require__(9037);
+      const _imageconfigcontextsharedruntime = __webpack_require__(6876);
+      const _warnonce = __webpack_require__(5603);
+      const _routercontextsharedruntime = __webpack_require__(6967);
       const _imageloader = /*#__PURE__*/ _interop_require_default._(
-        __webpack_require__(4394)
+        __webpack_require__(9275)
       );
-      const _usemergedref = __webpack_require__(9673);
+      const _usemergedref = __webpack_require__(9386);
       // This is replaced by webpack define plugin
       const configEnv = {
         deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
@@ -371,7 +371,7 @@
       /***/
     },
 
-    /***/ 9673: /***/ (module, exports, __webpack_require__) => {
+    /***/ 9386: /***/ (module, exports, __webpack_require__) => {
       "use strict";
 
       Object.defineProperty(exports, "__esModule", {
@@ -432,7 +432,7 @@
       /***/
     },
 
-    /***/ 2989: /***/ (
+    /***/ 2367: /***/ (
       __unused_webpack_module,
       exports,
       __webpack_require__
@@ -448,9 +448,9 @@
           return getImgProps;
         },
       });
-      const _warnonce = __webpack_require__(6308);
-      const _imageblursvg = __webpack_require__(9492);
-      const _imageconfig = __webpack_require__(2948);
+      const _warnonce = __webpack_require__(5603);
+      const _imageblursvg = __webpack_require__(2052);
+      const _imageconfig = __webpack_require__(9037);
       const VALID_LOADING_VALUES =
         /* unused pure expression or super */ null && [
           "lazy",
@@ -823,7 +823,7 @@
       /***/
     },
 
-    /***/ 9492: /***/ (__unused_webpack_module, exports) => {
+    /***/ 2052: /***/ (__unused_webpack_module, exports) => {
       "use strict";
       /**
        * A shared function, used on both client and server, to generate a SVG blur placeholder.
@@ -878,7 +878,7 @@
       /***/
     },
 
-    /***/ 9256: /***/ (
+    /***/ 3038: /***/ (
       __unused_webpack_module,
       exports,
       __webpack_require__
@@ -905,10 +905,10 @@
         },
       });
       const _interop_require_default = __webpack_require__(9608);
-      const _getimgprops = __webpack_require__(2989);
-      const _imagecomponent = __webpack_require__(7847);
+      const _getimgprops = __webpack_require__(2367);
+      const _imagecomponent = __webpack_require__(8501);
       const _imageloader = /*#__PURE__*/ _interop_require_default._(
-        __webpack_require__(4394)
+        __webpack_require__(9275)
       );
       function getImageProps(imgProps) {
         const { props } = (0, _getimgprops.getImgProps)(imgProps, {
@@ -940,7 +940,7 @@
       /***/
     },
 
-    /***/ 4394: /***/ (__unused_webpack_module, exports) => {
+    /***/ 9275: /***/ (__unused_webpack_module, exports) => {
       "use strict";
 
       Object.defineProperty(exports, "__esModule", {
@@ -975,7 +975,7 @@
       /***/
     },
 
-    /***/ 6366: /***/ (
+    /***/ 8898: /***/ (
       __unused_webpack_module,
       __webpack_exports__,
       __webpack_require__
@@ -992,8 +992,8 @@
 
       // EXTERNAL MODULE: ./node_modules/.pnpm/react@19.0.0-rc-2d16326d-20240930/node_modules/react/jsx-runtime.js
       var jsx_runtime = __webpack_require__(9837);
-      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-2d16326d-20240930_re_aw34735d3a4s5ybwraoeym2z3m/node_modules/next/image.js
-      var next_image = __webpack_require__(6020);
+      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-2d16326d-20240930_re_twsodcu6u2xc4vttzu7xhu5gra/node_modules/next/image.js
+      var next_image = __webpack_require__(3843);
       var image_default = /*#__PURE__*/ __webpack_require__.n(next_image); // CONCATENATED MODULE: ./pages/nextjs.png
       /* harmony default export */ const nextjs = {
         src: "/_next/static/media/nextjs.cae0b805.png",
@@ -1023,12 +1023,12 @@
       /***/
     },
 
-    /***/ 6020: /***/ (
+    /***/ 3843: /***/ (
       module,
       __unused_webpack_exports,
       __webpack_require__
     ) => {
-      module.exports = __webpack_require__(9256);
+      module.exports = __webpack_require__(3038);
 
       /***/
     },
@@ -1038,7 +1038,7 @@
     /******/ var __webpack_exec__ = (moduleId) =>
       __webpack_require__((__webpack_require__.s = moduleId));
     /******/ __webpack_require__.O(0, [2888, 9774, 179], () =>
-      __webpack_exec__(4519)
+      __webpack_exec__(766)
     );
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
Diff for 1698-HASH.js
@@ -1,8 +1,8 @@
 "use strict";
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
-  [1698],
+  [2859],
   {
-    /***/ 1698: /***/ (module, exports, __webpack_require__) => {
+    /***/ 2859: /***/ (module, exports, __webpack_require__) => {
       /* __next_internal_client_entry_do_not_use__  cjs */
       Object.defineProperty(exports, "__esModule", {
         value: true,
@@ -13,27 +13,27 @@
           return Image;
         },
       });
-      const _interop_require_default = __webpack_require__(3280);
-      const _interop_require_wildcard = __webpack_require__(8464);
-      const _jsxruntime = __webpack_require__(673);
+      const _interop_require_default = __webpack_require__(9218);
+      const _interop_require_wildcard = __webpack_require__(8553);
+      const _jsxruntime = __webpack_require__(9348);
       const _react = /*#__PURE__*/ _interop_require_wildcard._(
-        __webpack_require__(254)
+        __webpack_require__(8196)
       );
       const _reactdom = /*#__PURE__*/ _interop_require_default._(
-        __webpack_require__(177)
+        __webpack_require__(8174)
       );
       const _head = /*#__PURE__*/ _interop_require_default._(
-        __webpack_require__(4591)
+        __webpack_require__(3039)
       );
-      const _getimgprops = __webpack_require__(6509);
-      const _imageconfig = __webpack_require__(1545);
-      const _imageconfigcontextsharedruntime = __webpack_require__(9041);
-      const _warnonce = __webpack_require__(7147);
-      const _routercontextsharedruntime = __webpack_require__(7112);
+      const _getimgprops = __webpack_require__(4645);
+      const _imageconfig = __webpack_require__(8661);
+      const _imageconfigcontextsharedruntime = __webpack_require__(5611);
+      const _warnonce = __webpack_require__(3975);
+      const _routercontextsharedruntime = __webpack_require__(4332);
       const _imageloader = /*#__PURE__*/ _interop_require_default._(
-        __webpack_require__(4980)
+        __webpack_require__(9206)
       );
-      const _usemergedref = __webpack_require__(3096);
+      const _usemergedref = __webpack_require__(900);
       // This is replaced by webpack define plugin
       const configEnv = {
         deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
@@ -355,7 +355,7 @@
       /***/
     },
 
-    /***/ 3096: /***/ (module, exports, __webpack_require__) => {
+    /***/ 900: /***/ (module, exports, __webpack_require__) => {
       Object.defineProperty(exports, "__esModule", {
         value: true,
       });
@@ -365,7 +365,7 @@
           return useMergedRef;
         },
       });
-      const _react = __webpack_require__(254);
+      const _react = __webpack_require__(8196);
       function useMergedRef(refA, refB) {
         const cleanupA = (0, _react.useRef)(() => {});
         const cleanupB = (0, _react.useRef)(() => {});
@@ -414,7 +414,7 @@
       /***/
     },
 
-    /***/ 5225: /***/ (
+    /***/ 4551: /***/ (
       __unused_webpack_module,
       exports,
       __webpack_require__
@@ -428,9 +428,9 @@
           return AmpStateContext;
         },
       });
-      const _interop_require_default = __webpack_require__(3280);
+      const _interop_require_default = __webpack_require__(9218);
       const _react = /*#__PURE__*/ _interop_require_default._(
-        __webpack_require__(254)
+        __webpack_require__(8196)
       );
       const AmpStateContext = _react.default.createContext({});
       if (false) {
@@ -439,7 +439,7 @@
       /***/
     },
 
-    /***/ 4457: /***/ (__unused_webpack_module, exports) => {
+    /***/ 7094: /***/ (__unused_webpack_module, exports) => {
       Object.defineProperty(exports, "__esModule", {
         value: true,
       });
@@ -461,7 +461,7 @@
       /***/
     },
 
-    /***/ 6509: /***/ (
+    /***/ 4645: /***/ (
       __unused_webpack_module,
       exports,
       __webpack_require__
@@ -475,9 +475,9 @@
           return getImgProps;
         },
       });
-      const _warnonce = __webpack_require__(7147);
-      const _imageblursvg = __webpack_require__(5901);
-      const _imageconfig = __webpack_require__(1545);
+      const _warnonce = __webpack_require__(3975);
+      const _imageblursvg = __webpack_require__(3749);
+      const _imageconfig = __webpack_require__(8661);
       const VALID_LOADING_VALUES =
         /* unused pure expression or super */ null && [
           "lazy",
@@ -850,8 +850,8 @@
       /***/
     },
 
-    /***/ 4591: /***/ (module, exports, __webpack_require__) => {
-      /* provided dependency */ var process = __webpack_require__(4784);
+    /***/ 3039: /***/ (module, exports, __webpack_require__) => {
+      /* provided dependency */ var process = __webpack_require__(1482);
       /* __next_internal_client_entry_do_not_use__  cjs */
       Object.defineProperty(exports, "__esModule", {
         value: true,
@@ -872,19 +872,19 @@
           return defaultHead;
         },
       });
-      const _interop_require_default = __webpack_require__(3280);
-      const _interop_require_wildcard = __webpack_require__(8464);
-      const _jsxruntime = __webpack_require__(673);
+      const _interop_require_default = __webpack_require__(9218);
+      const _interop_require_wildcard = __webpack_require__(8553);
+      const _jsxruntime = __webpack_require__(9348);
       const _react = /*#__PURE__*/ _interop_require_wildcard._(
-        __webpack_require__(254)
+        __webpack_require__(8196)
       );
       const _sideeffect = /*#__PURE__*/ _interop_require_default._(
-        __webpack_require__(31)
+        __webpack_require__(2968)
       );
-      const _ampcontextsharedruntime = __webpack_require__(5225);
-      const _headmanagercontextsharedruntime = __webpack_require__(3382);
-      const _ampmode = __webpack_require__(4457);
-      const _warnonce = __webpack_require__(7147);
+      const _ampcontextsharedruntime = __webpack_require__(4551);
+      const _headmanagercontextsharedruntime = __webpack_require__(452);
+      const _ampmode = __webpack_require__(7094);
+      const _warnonce = __webpack_require__(3975);
       function defaultHead(inAmpMode) {
         if (inAmpMode === void 0) inAmpMode = false;
         const head = [
@@ -1068,7 +1068,7 @@
       /***/
     },
 
-    /***/ 5901: /***/ (__unused_webpack_module, exports) => {
+    /***/ 3749: /***/ (__unused_webpack_module, exports) => {
       /**
        * A shared function, used on both client and server, to generate a SVG blur placeholder.
        */
@@ -1122,7 +1122,7 @@
       /***/
     },
 
-    /***/ 9041: /***/ (
+    /***/ 5611: /***/ (
       __unused_webpack_module,
       exports,
       __webpack_require__
@@ -1136,11 +1136,11 @@
           return ImageConfigContext;
         },
       });
-      const _interop_require_default = __webpack_require__(3280);
+      const _interop_require_default = __webpack_require__(9218);
       const _react = /*#__PURE__*/ _interop_require_default._(
-        __webpack_require__(254)
+        __webpack_require__(8196)
       );
-      const _imageconfig = __webpack_require__(1545);
+      const _imageconfig = __webpack_require__(8661);
       const ImageConfigContext = _react.default.createContext(
         _imageconfig.imageConfigDefault
       );
@@ -1150,7 +1150,7 @@
       /***/
     },
 
-    /***/ 1545: /***/ (__unused_webpack_module, exports) => {
+    /***/ 8661: /***/ (__unused_webpack_module, exports) => {
       Object.defineProperty(exports, "__esModule", {
         value: true,
       });
@@ -1198,7 +1198,7 @@
       /***/
     },
 
-    /***/ 4980: /***/ (__unused_webpack_module, exports) => {
+    /***/ 9206: /***/ (__unused_webpack_module, exports) => {
       Object.defineProperty(exports, "__esModule", {
         value: true,
       });
@@ -1231,7 +1231,7 @@
       /***/
     },
 
-    /***/ 7112: /***/ (
+    /***/ 4332: /***/ (
       __unused_webpack_module,
       exports,
       __webpack_require__
@@ -1245,9 +1245,9 @@
           return RouterContext;
         },
       });
-      const _interop_require_default = __webpack_require__(3280);
+      const _interop_require_default = __webpack_require__(9218);
       const _react = /*#__PURE__*/ _interop_require_default._(
-        __webpack_require__(254)
+        __webpack_require__(8196)
       );
       const RouterContext = _react.default.createContext(null);
       if (false) {
@@ -1256,7 +1256,11 @@
       /***/
     },
 
-    /***/ 31: /***/ (__unused_webpack_module, exports, __webpack_require__) => {
+    /***/ 2968: /***/ (
+      __unused_webpack_module,
+      exports,
+      __webpack_require__
+    ) => {
       Object.defineProperty(exports, "__esModule", {
         value: true,
       });
@@ -1266,7 +1270,7 @@
           return SideEffect;
         },
       });
-      const _react = __webpack_require__(254);
+      const _react = __webpack_require__(8196);
       const isServer = typeof window === "undefined";
       const useClientOnlyLayoutEffect = isServer
         ? () => {}
Diff for 3463-HASH.js

Diff too large to display

Diff for main-HASH.js

Diff too large to display

Diff for app-page-exp..ntime.dev.js

Diff too large to display

Diff for app-page-exp..time.prod.js

Diff too large to display

Diff for app-page-tur..time.prod.js

Diff too large to display

Diff for app-page-tur..time.prod.js

Diff too large to display

Diff for app-page.runtime.dev.js

Diff too large to display

Diff for app-page.runtime.prod.js

Diff too large to display

Diff for app-route-ex..ntime.dev.js

Diff too large to display

Diff for app-route-ex..time.prod.js

Diff too large to display

Diff for app-route-tu..time.prod.js

Diff too large to display

Diff for app-route-tu..time.prod.js

Diff too large to display

Diff for app-route.runtime.dev.js

Diff too large to display

Diff for app-route.ru..time.prod.js

Diff too large to display

Diff for server.runtime.prod.js

Diff too large to display

Commit: f32883c

@acdlite acdlite force-pushed the per-segment-prefetch-request-handling branch from d39c29b to 997235d Compare October 10, 2024 18:21
@@ -1910,7 +1911,7 @@ export default abstract class Server<
isAppPath: boolean,
resolvedPathname: string
): void {
const baseVaryHeader = `${RSC_HEADER}, ${NEXT_ROUTER_STATE_TREE_HEADER}, ${NEXT_ROUTER_PREFETCH_HEADER}`
const baseVaryHeader = `${RSC_HEADER}, ${NEXT_ROUTER_STATE_TREE_HEADER}, ${NEXT_ROUTER_PREFETCH_HEADER}, ${NEXT_ROUTER_SEGMENT_PREFETCH_HEADER}`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also need to update the vary header here I think:

varyHeader: `${RSC_HEADER}, ${NEXT_ROUTER_STATE_TREE_HEADER}, ${NEXT_ROUTER_PREFETCH_HEADER}`,

return
}

const { next } = nextTestSetup({
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const { next } = nextTestSetup({
const { next, isNextDev, isNextDeploy } = nextTestSetup({

Can grab these from here instead of global now

import { nextTestSetup } from 'e2e-utils'

describe('per segment prefetching', () => {
if ((global as any).isNextDev) {
Copy link
Member

@ijjk ijjk Oct 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can move this below nextTestSetup and use the fields from that, I think we also want to skip deploy for now until that's updated

@acdlite acdlite force-pushed the per-segment-prefetch-request-handling branch from 997235d to f940874 Compare October 10, 2024 18:43
segmentPath === '/'
? segmentsDir + '/_index' + RSC_SEGMENT_SUFFIX
: segmentsDir + segmentPath + RSC_SEGMENT_SUFFIX
tasks.push(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these awaited somewhere to avoid dangling promise?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh good catch, meant to do Promise.all on the line below

@acdlite acdlite force-pushed the per-segment-prefetch-request-handling branch 3 times, most recently from dddc132 to 16552df Compare October 10, 2024 19:25
Comment on lines 1148 to 1149
['/', placeholder],
['/blog', placeholder],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't tell from the diff but is this flagged?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The whole feature is flagged by PPR but generating these output files isn't. So in the meantime it does generate extra stuff. I'll add the flag here, too.

@@ -1258,7 +1259,7 @@ export default async function build(
header: RSC_HEADER,
// This vary header is used as a default. It is technically re-assigned in `base-server`,
// and may include an additional Vary option for `Next-URL`.
varyHeader: `${RSC_HEADER}, ${NEXT_ROUTER_STATE_TREE_HEADER}, ${NEXT_ROUTER_PREFETCH_HEADER}`,
varyHeader: `${RSC_HEADER}, ${NEXT_ROUTER_STATE_TREE_HEADER}, ${NEXT_ROUTER_PREFETCH_HEADER}, ${NEXT_ROUTER_SEGMENT_PREFETCH_HEADER}`,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we'll need to duplicate this in fetchServerResponse to mirror the workaround we have for CDNs that don't respect Vary (the computed ?_rsc param)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah right, forgot about that one, will do

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I remember now: I left that alone for now since the client doesn't actually issue any of these requests yet. So it doesn't matter. Will update once I update the client.

Introduces a new App Router header that will be used for prefetching
individual segments. It will accept a path to the segment that is
being requested.

The header is treated similarly to the other known headers: it is
stripped by `stripFlightHeaders` before the application handles the
request, and it's part of the Vary header so clients cache
it correctly.

This does not yet implement any of the actual response handling.
Implements exporting segment prefetch data during build.

Although the goal is to support individual segments being requested by
the client, all of the segments for a page are generated simultaneously,
including during revalidations. This is to ensure consistency, because
it's possible for a mismatch between a layout and page segment can
cause the client to error during rendering. We want to preserve the
ability of the client to recover from such a mismatch by re-requesting
all the segments to get a consistent view of the page.

The segments data is generated during the same phase that we currently
generate prefetch data for the entire page.

In this commit, I have not yet implemented the actual segment
generation; I'm using placeholder data for now. I've only implemented
the plumbing of the data through the build process. I will implement
the segment generation in a separate PR.
This updates the server and incremental cache to handle segment
prefetch requests.

Segment requests must always be served from the cache. They must never
reach the application layer or invoke a lambda. If a matching segment
is not present in the cache, it's a 404.
We can't test per-segment fetching end-to-end yet because the client
behavior hasn't been implemented. These are basic smoke tests to
demonstrate that the server correctly responds to a request. We will
replace them with proper e2e tests once more of the feature has
been implemented.
@acdlite acdlite force-pushed the per-segment-prefetch-request-handling branch from 16552df to f32883c Compare October 11, 2024 14:57
@acdlite acdlite requested review from ztanner and ijjk October 11, 2024 14:58
// TODO: Update the client to use the same encoding for segment paths that
// we use here, so we don't have to convert between them. Needs to be
// filesystem safe.
['/blog/[post]-1-d', placeholder],
Copy link
Member

@ztanner ztanner Oct 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

non-blocking nit: since people (including front) are using PPR actively it might be confusing to see these generated placeholders for pages that don't exist in their build output, but since it's still experimental I don't think it's necessarily a blocker.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If anyone complains I can change it to something more obscure like /a/b or whatever

@acdlite acdlite merged commit a108bbb into vercel:canary Oct 11, 2024
85 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants