@semiont/frontend 0.3.2 → 0.3.4
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/package.json +1 -1
- package/standalone/apps/frontend/.next/BUILD_ID +1 -1
- package/standalone/apps/frontend/.next/app-path-routes-manifest.json +5 -5
- package/standalone/apps/frontend/.next/build-manifest.json +6 -6
- package/standalone/apps/frontend/.next/prerender-manifest.json +3 -3
- package/standalone/apps/frontend/.next/react-loadable-manifest.json +2 -2
- package/standalone/apps/frontend/.next/required-server-files.json +18 -6
- package/standalone/apps/frontend/.next/routes-manifest.json +1 -0
- package/standalone/apps/frontend/.next/server/app/[locale]/about/page.js +776 -516
- package/standalone/apps/frontend/.next/server/app/[locale]/about/page.js.nft.json +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/about/page_client-reference-manifest.js +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/admin/devops/page.js +1718 -1455
- package/standalone/apps/frontend/.next/server/app/[locale]/admin/devops/page.js.nft.json +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/admin/devops/page_client-reference-manifest.js +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/admin/exchange/page.js +724 -461
- package/standalone/apps/frontend/.next/server/app/[locale]/admin/exchange/page.js.nft.json +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/admin/exchange/page_client-reference-manifest.js +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/admin/page.js +370 -109
- package/standalone/apps/frontend/.next/server/app/[locale]/admin/page.js.nft.json +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/admin/page_client-reference-manifest.js +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/admin/security/page.js +581 -318
- package/standalone/apps/frontend/.next/server/app/[locale]/admin/security/page.js.nft.json +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/admin/security/page_client-reference-manifest.js +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/admin/users/page.js +449 -186
- package/standalone/apps/frontend/.next/server/app/[locale]/admin/users/page.js.nft.json +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/admin/users/page_client-reference-manifest.js +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/auth/error/page.js +430 -168
- package/standalone/apps/frontend/.next/server/app/[locale]/auth/error/page.js.nft.json +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/auth/error/page_client-reference-manifest.js +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/auth/mcp-setup/route.js +31 -16
- package/standalone/apps/frontend/.next/server/app/[locale]/auth/mcp-setup/route.js.nft.json +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/auth/mcp-setup/route_client-reference-manifest.js +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/auth/signin/page.js +388 -126
- package/standalone/apps/frontend/.next/server/app/[locale]/auth/signin/page.js.nft.json +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/auth/signin/page_client-reference-manifest.js +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/auth/signup/page.js +537 -275
- package/standalone/apps/frontend/.next/server/app/[locale]/auth/signup/page.js.nft.json +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/auth/signup/page_client-reference-manifest.js +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/auth/welcome/page.js +388 -126
- package/standalone/apps/frontend/.next/server/app/[locale]/auth/welcome/page.js.nft.json +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/auth/welcome/page_client-reference-manifest.js +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/know/compose/page.js +745 -482
- package/standalone/apps/frontend/.next/server/app/[locale]/know/compose/page.js.nft.json +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/know/compose/page_client-reference-manifest.js +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/know/discover/page.js +366 -103
- package/standalone/apps/frontend/.next/server/app/[locale]/know/discover/page.js.nft.json +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/know/discover/page_client-reference-manifest.js +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/know/page.js +600 -339
- package/standalone/apps/frontend/.next/server/app/[locale]/know/page.js.nft.json +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/know/page_client-reference-manifest.js +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/know/resource/[id]/page.js +956 -691
- package/standalone/apps/frontend/.next/server/app/[locale]/know/resource/[id]/page.js.nft.json +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/know/resource/[id]/page_client-reference-manifest.js +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/moderate/entity-tags/page.js +1699 -1436
- package/standalone/apps/frontend/.next/server/app/[locale]/moderate/entity-tags/page.js.nft.json +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/moderate/entity-tags/page_client-reference-manifest.js +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/moderate/linked-data/page.js +390 -127
- package/standalone/apps/frontend/.next/server/app/[locale]/moderate/linked-data/page.js.nft.json +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/moderate/linked-data/page_client-reference-manifest.js +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/moderate/page.js +1779 -1518
- package/standalone/apps/frontend/.next/server/app/[locale]/moderate/page.js.nft.json +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/moderate/page_client-reference-manifest.js +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/moderate/recent/page.js +1601 -1338
- package/standalone/apps/frontend/.next/server/app/[locale]/moderate/recent/page.js.nft.json +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/moderate/recent/page_client-reference-manifest.js +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/moderate/tag-schemas/page.js +2048 -1785
- package/standalone/apps/frontend/.next/server/app/[locale]/moderate/tag-schemas/page.js.nft.json +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/moderate/tag-schemas/page_client-reference-manifest.js +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/page.js +462 -204
- package/standalone/apps/frontend/.next/server/app/[locale]/page.js.nft.json +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/page_client-reference-manifest.js +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/privacy/page.js +476 -216
- package/standalone/apps/frontend/.next/server/app/[locale]/privacy/page.js.nft.json +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/privacy/page_client-reference-manifest.js +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/terms/page.js +489 -229
- package/standalone/apps/frontend/.next/server/app/[locale]/terms/page.js.nft.json +1 -1
- package/standalone/apps/frontend/.next/server/app/[locale]/terms/page_client-reference-manifest.js +1 -1
- package/standalone/apps/frontend/.next/server/app/_global-error/page.js +627 -240
- package/standalone/apps/frontend/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/standalone/apps/frontend/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/standalone/apps/frontend/.next/server/app/_global-error.html +1 -2
- package/standalone/apps/frontend/.next/server/app/_global-error.rsc +13 -9
- package/standalone/apps/frontend/.next/server/app/_global-error.segments/_full.segment.rsc +13 -9
- package/standalone/apps/frontend/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/standalone/apps/frontend/.next/server/app/_global-error.segments/_global-error.segment.rsc +2 -1
- package/standalone/apps/frontend/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/standalone/apps/frontend/.next/server/app/_global-error.segments/_index.segment.rsc +2 -1
- package/standalone/apps/frontend/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/standalone/apps/frontend/.next/server/app/_not-found/page.js +814 -559
- package/standalone/apps/frontend/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/standalone/apps/frontend/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/standalone/apps/frontend/.next/server/app/_not-found.html +1 -1
- package/standalone/apps/frontend/.next/server/app/_not-found.rsc +8 -6
- package/standalone/apps/frontend/.next/server/app/_not-found.segments/_full.segment.rsc +8 -6
- package/standalone/apps/frontend/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/standalone/apps/frontend/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/standalone/apps/frontend/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/standalone/apps/frontend/.next/server/app/_not-found.segments/_not-found.segment.rsc +2 -1
- package/standalone/apps/frontend/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/standalone/apps/frontend/.next/server/app/api/auth/[...nextauth]/route.js +54 -39
- package/standalone/apps/frontend/.next/server/app/api/auth/[...nextauth]/route.js.nft.json +1 -1
- package/standalone/apps/frontend/.next/server/app/api/auth/[...nextauth]/route_client-reference-manifest.js +1 -1
- package/standalone/apps/frontend/.next/server/app/api/cookies/consent/route.js +49 -34
- package/standalone/apps/frontend/.next/server/app/api/cookies/consent/route.js.nft.json +1 -1
- package/standalone/apps/frontend/.next/server/app/api/cookies/consent/route_client-reference-manifest.js +1 -1
- package/standalone/apps/frontend/.next/server/app/api/cookies/export/route.js +24 -9
- package/standalone/apps/frontend/.next/server/app/api/cookies/export/route.js.nft.json +1 -1
- package/standalone/apps/frontend/.next/server/app/api/cookies/export/route_client-reference-manifest.js +1 -1
- package/standalone/apps/frontend/.next/server/app/api/resources/[id]/route.js +24 -9
- package/standalone/apps/frontend/.next/server/app/api/resources/[id]/route.js.nft.json +1 -1
- package/standalone/apps/frontend/.next/server/app/api/resources/[id]/route_client-reference-manifest.js +1 -1
- package/standalone/apps/frontend/.next/server/app-paths-manifest.json +5 -5
- package/standalone/apps/frontend/.next/server/chunks/2617.js +43 -7
- package/standalone/apps/frontend/.next/server/chunks/3144.js +7 -3
- package/standalone/apps/frontend/.next/server/chunks/4741.js +60 -252
- package/standalone/apps/frontend/.next/server/chunks/730.js +1 -1
- package/standalone/apps/frontend/.next/server/chunks/7420.js +21 -288
- package/standalone/apps/frontend/.next/server/chunks/7873.js +24 -2
- package/standalone/apps/frontend/.next/server/chunks/{7246.js → 8569.js} +1169 -282
- package/standalone/apps/frontend/.next/server/chunks/{2628.js → 9927.js} +11422 -4290
- package/standalone/apps/frontend/.next/server/middleware-build-manifest.js +1 -1
- package/standalone/apps/frontend/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/standalone/apps/frontend/.next/server/middleware.js +17991 -10692
- package/standalone/apps/frontend/.next/server/pages/404.html +1 -1
- package/standalone/apps/frontend/.next/server/pages/500.html +1 -2
- package/standalone/apps/frontend/.next/server/prefetch-hints.json +1 -0
- package/standalone/apps/frontend/.next/server/server-reference-manifest.json +1 -1
- package/standalone/apps/frontend/.next/static/I_XveRdyStDMqYJPcAAy5/_buildManifest.js +1 -0
- package/standalone/apps/frontend/.next/static/chunks/1315.3f76aa23520d903e.js +1 -0
- package/standalone/apps/frontend/.next/static/chunks/{432.4c1d971431c60454.js → 432.8cb455bfe72957a9.js} +1 -1
- package/standalone/apps/frontend/.next/static/chunks/87c73c54-e11922cda838f8cc.js +1 -0
- package/standalone/apps/frontend/.next/static/chunks/{891cff7f-c20ce667b1225aa7.js → 891cff7f-d7677a8f46c597cc.js} +1 -1
- package/standalone/apps/frontend/.next/static/chunks/app/[locale]/admin/{layout-4b67f7b5d5ba4728.js → layout-956ba0ffa1199bff.js} +1 -1
- package/standalone/apps/frontend/.next/static/chunks/app/[locale]/know/{layout-f76e1916749e66f6.js → layout-262d8dd6c6e33738.js} +1 -1
- package/standalone/apps/frontend/.next/static/chunks/app/[locale]/{layout-a403fd7a4877cc04.js → layout-c072ce8c7aeaa92e.js} +1 -1
- package/standalone/apps/frontend/.next/static/chunks/app/[locale]/moderate/{layout-2d4e9c2be4b4a4c7.js → layout-b60605082e447f42.js} +1 -1
- package/standalone/apps/frontend/.next/static/chunks/common-42653c14d34c8864.js +69 -0
- package/standalone/apps/frontend/.next/static/chunks/framework-b879567b90d34fb5.js +1 -0
- package/standalone/apps/frontend/.next/static/chunks/vendors-63213253c18580f4.js +40 -0
- package/standalone/apps/frontend/.next/static/chunks/{webpack-abf2ad17f175f867.js → webpack-a0284d55d288650f.js} +1 -1
- package/standalone/apps/frontend/package.json +5 -5
- package/standalone/apps/frontend/server.js +1 -1
- package/standalone/node_modules/@next/env/package.json +1 -1
- package/standalone/node_modules/next/dist/build/adapter/setup-node-env.external.js +15 -0
- package/standalone/node_modules/next/dist/build/analysis/extract-const-value.js +78 -63
- package/standalone/node_modules/next/dist/build/analysis/get-page-static-info.js +64 -40
- package/standalone/node_modules/next/dist/build/create-compiler-aliases.js +2 -0
- package/standalone/node_modules/next/dist/build/define-env.js +29 -11
- package/standalone/node_modules/next/dist/build/duration-to-string.js +1 -1
- package/standalone/node_modules/next/dist/build/entries.js +55 -295
- package/standalone/node_modules/next/dist/build/file-classifier.js +76 -0
- package/standalone/node_modules/next/dist/build/get-supported-browsers.js +38 -0
- package/standalone/node_modules/next/dist/build/load-jsconfig.js +7 -7
- package/standalone/node_modules/next/dist/build/lockfile.js +90 -9
- package/standalone/node_modules/next/dist/build/next-config-ts/transpile-config.js +128 -49
- package/standalone/node_modules/next/dist/build/print-build-errors.js +72 -0
- package/standalone/node_modules/next/dist/build/route-discovery.js +353 -0
- package/standalone/node_modules/next/dist/build/segment-config/app/app-segment-config.js +34 -17
- package/standalone/node_modules/next/dist/build/static-paths/app.js +68 -15
- package/standalone/node_modules/next/dist/build/static-paths/pages.js +3 -3
- package/standalone/node_modules/next/dist/build/swc/index.js +125 -48
- package/standalone/node_modules/next/dist/build/swc/loaderWorkerPool.js +40 -0
- package/standalone/node_modules/next/dist/build/swc/options.js +23 -6
- package/standalone/node_modules/next/dist/build/utils.js +48 -94
- package/standalone/node_modules/next/dist/build/webpack/config/blocks/css/index.js +14 -3
- package/standalone/node_modules/next/dist/build/webpack/config/blocks/css/loaders/global.js +4 -2
- package/standalone/node_modules/next/dist/build/webpack/config/blocks/css/loaders/modules.js +4 -2
- package/standalone/node_modules/next/dist/build/webpack/config/blocks/css/loaders/next-font.js +1 -0
- package/standalone/node_modules/next/dist/build/webpack/config/blocks/css/plugins.js +5 -5
- package/standalone/node_modules/next/dist/build/webpack/config/index.js +3 -2
- package/standalone/node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js +2 -1
- package/standalone/node_modules/next/dist/build/webpack/loaders/css-loader/src/plugins/postcss-url-parser.js +8 -1
- package/standalone/node_modules/next/dist/build/webpack/loaders/lightningcss-loader/src/loader.js +13 -4
- package/standalone/node_modules/next/dist/build/webpack/loaders/next-middleware-loader.js +3 -1
- package/standalone/node_modules/next/dist/build/webpack/plugins/build-manifest-plugin-utils.js +2 -16
- package/standalone/node_modules/next/dist/build/webpack/plugins/build-manifest-plugin.js +2 -2
- package/standalone/node_modules/next/dist/build/webpack/plugins/deferred-entries-plugin.js +106 -0
- package/standalone/node_modules/next/dist/build/webpack/plugins/flight-client-entry-plugin.js +16 -8
- package/standalone/node_modules/next/dist/build/webpack/plugins/flight-manifest-plugin.js +24 -11
- package/standalone/node_modules/next/dist/build/webpack/plugins/middleware-plugin.js +21 -2
- package/standalone/node_modules/next/dist/build/webpack/plugins/next-types-plugin/index.js +6 -5
- package/standalone/node_modules/next/dist/build/webpack/plugins/nextjs-require-cache-hot-reloader.js +10 -14
- package/standalone/node_modules/next/dist/build/webpack/plugins/wellknown-errors-plugin/parseNotFoundError.js +18 -4
- package/standalone/node_modules/next/dist/build/webpack/plugins/wellknown-errors-plugin/parseScss.js +5 -4
- package/standalone/node_modules/next/dist/build/webpack-config.js +18 -8
- package/standalone/node_modules/next/dist/cli/next-test.js +4 -3
- package/standalone/node_modules/next/dist/client/app-find-source-map-url.js +2 -1
- package/standalone/node_modules/next/dist/client/components/app-router-headers.js +10 -0
- package/standalone/node_modules/next/dist/client/components/app-router-instance.js +82 -4
- package/standalone/node_modules/next/dist/client/components/app-router.js +39 -20
- package/standalone/node_modules/next/dist/client/components/builtin/app-error.js +29 -65
- package/standalone/node_modules/next/dist/client/components/builtin/error-styles.js +165 -0
- package/standalone/node_modules/next/dist/client/components/builtin/global-error.js +56 -38
- package/standalone/node_modules/next/dist/client/components/error-boundary.js +16 -6
- package/standalone/node_modules/next/dist/client/components/forbidden.js +1 -1
- package/standalone/node_modules/next/dist/client/components/handle-isr-error.js +3 -4
- package/standalone/node_modules/next/dist/client/components/links.js +7 -0
- package/standalone/node_modules/next/dist/client/components/navigation-untracked.js +2 -0
- package/standalone/node_modules/next/dist/client/components/navigation.js +27 -0
- package/standalone/node_modules/next/dist/client/components/navigation.react-server.js +5 -2
- package/standalone/node_modules/next/dist/client/components/not-found.js +1 -1
- package/standalone/node_modules/next/dist/client/components/redirect-boundary.js +1 -1
- package/standalone/node_modules/next/dist/client/components/redirect-error.js +0 -9
- package/standalone/node_modules/next/dist/client/components/redirect.js +2 -2
- package/standalone/node_modules/next/dist/client/components/router-reducer/compute-changed-path.js +73 -0
- package/standalone/node_modules/next/dist/client/components/router-reducer/create-initial-router-state.js +102 -8
- package/standalone/node_modules/next/dist/client/components/router-reducer/fetch-server-response.js +165 -48
- package/standalone/node_modules/next/dist/client/components/router-reducer/is-navigating-to-new-root-layout.js +19 -11
- package/standalone/node_modules/next/dist/client/components/router-reducer/ppr-navigations.js +669 -457
- package/standalone/node_modules/next/dist/client/components/router-reducer/reducers/committed-state.js +49 -0
- package/standalone/node_modules/next/dist/client/components/router-reducer/reducers/find-head-in-cache.js +19 -20
- package/standalone/node_modules/next/dist/client/components/router-reducer/reducers/navigate-reducer.js +5 -117
- package/standalone/node_modules/next/dist/client/components/router-reducer/reducers/refresh-reducer.js +34 -19
- package/standalone/node_modules/next/dist/client/components/router-reducer/reducers/restore-reducer.js +16 -32
- package/standalone/node_modules/next/dist/client/components/router-reducer/reducers/server-action-reducer.js +85 -57
- package/standalone/node_modules/next/dist/client/components/router-reducer/reducers/server-patch-reducer.js +12 -10
- package/standalone/node_modules/next/dist/client/components/router-reducer/router-reducer-types.js +10 -1
- package/standalone/node_modules/next/dist/client/components/router-reducer/router-reducer.js +1 -1
- package/standalone/node_modules/next/dist/client/components/segment-cache/bfcache.js +128 -0
- package/standalone/node_modules/next/dist/client/components/segment-cache/cache.js +732 -231
- package/standalone/node_modules/next/dist/client/components/segment-cache/lru.js +13 -6
- package/standalone/node_modules/next/dist/client/components/segment-cache/navigation-testing-lock.js +194 -0
- package/standalone/node_modules/next/dist/client/components/segment-cache/navigation.js +388 -250
- package/standalone/node_modules/next/dist/client/components/segment-cache/optimistic-routes.js +543 -0
- package/standalone/node_modules/next/dist/client/components/segment-cache/scheduler.js +154 -55
- package/standalone/node_modules/next/dist/client/components/segment-cache/vary-path.js +63 -1
- package/standalone/node_modules/next/dist/client/components/unauthorized.js +1 -1
- package/standalone/node_modules/next/dist/client/components/use-action-queue.js +49 -3
- package/standalone/node_modules/next/dist/client/dev/hot-reloader/app/hot-reloader-app.js +9 -1
- package/standalone/node_modules/next/dist/client/flight-data-helpers.js +42 -29
- package/standalone/node_modules/next/dist/client/lib/javascript-url.js +32 -0
- package/standalone/node_modules/next/dist/client/lib/promise.js +53 -0
- package/standalone/node_modules/next/dist/client/{app-build-id.js → navigation-build-id.js} +17 -13
- package/standalone/node_modules/next/dist/client/react-client-callbacks/on-recoverable-error.js +14 -0
- package/standalone/node_modules/next/dist/client/route-loader.js +9 -46
- package/standalone/node_modules/next/dist/client/router.js +1 -1
- package/standalone/node_modules/next/dist/compiled/@next/font/dist/google/font-data.json +74 -3
- package/standalone/node_modules/next/dist/compiled/babel/bundle.js +1 -1
- package/standalone/node_modules/next/dist/compiled/babel-packages/packages-bundle.js +4 -4
- package/standalone/node_modules/next/dist/compiled/browserslist/index.js +1 -1
- package/standalone/node_modules/next/dist/compiled/http-proxy/index.js +5 -5
- package/standalone/node_modules/next/dist/compiled/next-devtools/index.js +2209 -23
- package/standalone/node_modules/next/dist/compiled/next-server/app-page-experimental.runtime.prod.js +42 -12
- package/standalone/node_modules/next/dist/compiled/next-server/app-page-turbo-experimental.runtime.prod.js +42 -12
- package/standalone/node_modules/next/dist/compiled/next-server/app-page-turbo.runtime.prod.js +42 -12
- package/standalone/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js +42 -12
- package/standalone/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js +2 -2
- package/standalone/node_modules/next/dist/compiled/next-server/pages-turbo.runtime.prod.js +10 -10
- package/standalone/node_modules/next/dist/compiled/next-server/pages.runtime.prod.js +10 -10
- package/standalone/node_modules/next/dist/compiled/react-is/package.json +1 -1
- package/standalone/node_modules/next/dist/compiled/tar/index.min.js +1 -0
- package/standalone/node_modules/next/dist/compiled/tar/package.json +1 -1
- package/standalone/node_modules/next/dist/compiled/unistore/unistore.js +1 -1
- package/standalone/node_modules/next/dist/lib/bundler.js +97 -0
- package/standalone/node_modules/next/dist/lib/constants.js +19 -4
- package/standalone/node_modules/next/dist/lib/download-swc.js +2 -2
- package/standalone/node_modules/next/dist/lib/find-root.js +11 -7
- package/standalone/node_modules/next/dist/lib/format-server-error.js +1 -0
- package/standalone/node_modules/next/dist/lib/generate-interception-routes-rewrites.js +3 -20
- package/standalone/node_modules/next/dist/lib/interop-default.js +1 -0
- package/standalone/node_modules/next/dist/lib/is-interception-route-rewrite.js +18 -0
- package/standalone/node_modules/next/dist/lib/load-custom-routes.js +49 -5
- package/standalone/node_modules/next/dist/lib/memory/trace.js +109 -0
- package/standalone/node_modules/next/dist/lib/metadata/get-metadata-route.js +11 -2
- package/standalone/node_modules/next/dist/lib/needs-experimental-react.js +2 -2
- package/standalone/node_modules/next/dist/lib/patch-incorrect-lockfile.js +5 -5
- package/standalone/node_modules/next/dist/lib/try-to-parse-path.js +1 -2
- package/standalone/node_modules/next/dist/lib/turbopack-warning.js +0 -1
- package/standalone/node_modules/next/dist/lib/typescript/diagnosticFormatter.js +6 -3
- package/standalone/node_modules/next/dist/lib/typescript/getTypeScriptConfiguration.js +1 -1
- package/standalone/node_modules/next/dist/lib/typescript/missingDependencyError.js +1 -1
- package/standalone/node_modules/next/dist/lib/typescript/runTypeCheck.js +6 -8
- package/standalone/node_modules/next/dist/lib/typescript/type-paths.js +7 -12
- package/standalone/node_modules/next/dist/lib/typescript/writeAppTypeDeclarations.js +17 -7
- package/standalone/node_modules/next/dist/lib/typescript/writeConfigurationDefaults.js +9 -12
- package/standalone/node_modules/next/dist/lib/verify-typescript-setup.js +66 -16
- package/standalone/node_modules/next/dist/next-devtools/server/shared.js +6 -10
- package/standalone/node_modules/next/dist/next-devtools/shared/webpack-module-path.js +4 -4
- package/standalone/node_modules/next/dist/next-devtools/userspace/app/app-dev-overlay-error-boundary.js +22 -4
- package/standalone/node_modules/next/dist/next-devtools/userspace/app/errors/stitched-error.js +7 -1
- package/standalone/node_modules/next/dist/next-devtools/userspace/app/forward-logs.js +18 -13
- package/standalone/node_modules/next/dist/next-devtools/userspace/app/segment-explorer-node.js +7 -4
- package/standalone/node_modules/next/dist/server/app-render/action-handler.js +83 -15
- package/standalone/node_modules/next/dist/server/app-render/app-render-prerender-utils.js +0 -82
- package/standalone/node_modules/next/dist/server/app-render/app-render-render-utils.js +45 -81
- package/standalone/node_modules/next/dist/server/app-render/app-render.js +1746 -803
- package/standalone/node_modules/next/dist/server/app-render/create-component-tree.js +136 -50
- package/standalone/node_modules/next/dist/server/app-render/create-error-handler.js +6 -4
- package/standalone/node_modules/next/dist/server/app-render/create-flight-router-state-from-loader-tree.js +52 -26
- package/standalone/node_modules/next/dist/server/app-render/csrf-protection.js +14 -3
- package/standalone/node_modules/next/dist/server/app-render/debug-channel-server.js +30 -0
- package/standalone/node_modules/next/dist/server/app-render/debug-channel-server.web.js +71 -0
- package/standalone/node_modules/next/dist/server/app-render/dynamic-rendering.js +353 -37
- package/standalone/node_modules/next/dist/server/app-render/get-asset-query-string.js +2 -2
- package/standalone/node_modules/next/dist/server/app-render/get-layer-assets.js +1 -1
- package/standalone/node_modules/next/dist/server/app-render/instant-validation/boundary-constants.js +13 -0
- package/standalone/node_modules/next/dist/server/app-render/instant-validation/boundary-tracking.js +18 -0
- package/standalone/node_modules/next/dist/server/app-render/instant-validation/instant-config.js +181 -0
- package/standalone/node_modules/next/dist/server/app-render/instant-validation/instant-samples-client.js +128 -0
- package/standalone/node_modules/next/dist/server/app-render/instant-validation/instant-samples.js +432 -0
- package/standalone/node_modules/next/dist/server/app-render/instant-validation/instant-validation-error.js +33 -0
- package/standalone/node_modules/next/dist/server/app-render/instant-validation/stream-utils.js +96 -0
- package/standalone/node_modules/next/dist/server/app-render/manifests-singleton.js +8 -1
- package/standalone/node_modules/next/dist/server/app-render/postponed-state.js +2 -1
- package/standalone/node_modules/next/dist/server/app-render/prospective-render-utils.js +1 -0
- package/standalone/node_modules/next/dist/server/app-render/segment-explorer-path.js +35 -10
- package/standalone/node_modules/next/dist/server/app-render/staged-rendering.js +142 -72
- package/standalone/node_modules/next/dist/server/app-render/stale-time.js +111 -0
- package/standalone/node_modules/next/dist/server/app-render/stream-ops.js +106 -0
- package/standalone/node_modules/next/dist/server/app-render/stream-ops.web.js +163 -0
- package/standalone/node_modules/next/dist/server/app-render/types.js +10 -4
- package/standalone/node_modules/next/dist/server/app-render/use-flight-response.js +3 -1
- package/standalone/node_modules/next/dist/server/app-render/vary-params.js +336 -0
- package/standalone/node_modules/next/dist/server/app-render/walk-tree-with-flight-router-state.js +59 -12
- package/standalone/node_modules/next/dist/server/app-render/work-unit-async-storage.external.js +54 -26
- package/standalone/node_modules/next/dist/server/async-storage/request-store.js +4 -4
- package/standalone/node_modules/next/dist/server/async-storage/work-store.js +2 -5
- package/standalone/node_modules/next/dist/server/base-server.js +65 -53
- package/standalone/node_modules/next/dist/server/config-schema.js +93 -8
- package/standalone/node_modules/next/dist/server/config-shared.js +57 -7
- package/standalone/node_modules/next/dist/server/config.js +96 -25
- package/standalone/node_modules/next/dist/server/dev/browser-logs/file-logger.js +9 -6
- package/standalone/node_modules/next/dist/server/dev/browser-logs/receive-logs.js +46 -0
- package/standalone/node_modules/next/dist/server/dev/browser-logs/source-map.js +1 -4
- package/standalone/node_modules/next/dist/server/dev/hot-reloader-turbopack.js +264 -33
- package/standalone/node_modules/next/dist/server/dev/hot-reloader-webpack.js +8 -4
- package/standalone/node_modules/next/dist/server/dev/log-requests.js +10 -2
- package/standalone/node_modules/next/dist/server/dev/middleware-turbopack.js +20 -10
- package/standalone/node_modules/next/dist/server/dev/middleware-webpack.js +13 -3
- package/standalone/node_modules/next/dist/server/dev/next-dev-server.js +19 -6
- package/standalone/node_modules/next/dist/server/dev/on-demand-entry-handler.js +69 -0
- package/standalone/node_modules/next/dist/server/dev/require-cache.js +51 -21
- package/standalone/node_modules/next/dist/server/dev/server-action-logger.js +37 -0
- package/standalone/node_modules/next/dist/server/dev/static-paths-worker.js +1 -0
- package/standalone/node_modules/next/dist/server/dev/turbopack-utils.js +6 -15
- package/standalone/node_modules/next/dist/server/dynamic-rendering-utils.js +22 -0
- package/standalone/node_modules/next/dist/server/image-optimizer.js +157 -27
- package/standalone/node_modules/next/dist/server/lib/app-info-log.js +16 -38
- package/standalone/node_modules/next/dist/server/lib/cache-control.js +1 -1
- package/standalone/node_modules/next/dist/server/lib/clone-response.js +16 -16
- package/standalone/node_modules/next/dist/server/lib/cpu-profile.js +47 -16
- package/standalone/node_modules/next/dist/server/lib/dev-bundler-service.js +2 -2
- package/standalone/node_modules/next/dist/server/lib/disk-lru-cache.external.js +57 -0
- package/standalone/node_modules/next/dist/server/lib/find-page-file.js +27 -7
- package/standalone/node_modules/next/dist/server/lib/implicit-tags.js +3 -3
- package/standalone/node_modules/next/dist/server/lib/incremental-cache/file-system-cache.js +5 -3
- package/standalone/node_modules/next/dist/server/lib/incremental-cache/index.js +32 -10
- package/standalone/node_modules/next/dist/server/lib/incremental-cache/memory-cache.external.js +18 -1
- package/standalone/node_modules/next/dist/server/lib/install-code-frame.js +22 -0
- package/standalone/node_modules/next/dist/server/lib/lru-cache.js +9 -1
- package/standalone/node_modules/next/dist/server/lib/patch-fetch.js +40 -7
- package/standalone/node_modules/next/dist/server/lib/postponed-request-body.js +64 -0
- package/standalone/node_modules/next/dist/server/lib/render-server.js +4 -1
- package/standalone/node_modules/next/dist/server/lib/router-server.js +24 -13
- package/standalone/node_modules/next/dist/server/lib/router-utils/block-cross-site-dev.js +110 -0
- package/standalone/node_modules/next/dist/server/lib/router-utils/filesystem.js +16 -15
- package/standalone/node_modules/next/dist/server/lib/router-utils/resolve-routes.js +32 -11
- package/standalone/node_modules/next/dist/server/lib/router-utils/route-types-utils.js +3 -3
- package/standalone/node_modules/next/dist/server/lib/router-utils/setup-dev-bundler.js +71 -71
- package/standalone/node_modules/next/dist/server/lib/router-utils/typegen.js +247 -2
- package/standalone/node_modules/next/dist/server/lib/server-ipc/utils.js +2 -1
- package/standalone/node_modules/next/dist/server/lib/start-server.js +73 -39
- package/standalone/node_modules/next/dist/server/lib/trace/tracer.js +11 -1
- package/standalone/node_modules/next/dist/server/lib/utils.js +40 -11
- package/standalone/node_modules/next/dist/server/load-components.js +2 -0
- package/standalone/node_modules/next/dist/server/load-manifest.external.js +37 -17
- package/standalone/node_modules/next/dist/server/mcp/tools/get-errors.js +11 -4
- package/standalone/node_modules/next/dist/server/mcp/tools/get-logs.js +9 -3
- package/standalone/node_modules/next/dist/server/mcp/tools/get-page-metadata.js +52 -44
- package/standalone/node_modules/next/dist/server/mcp/tools/get-project-metadata.js +6 -2
- package/standalone/node_modules/next/dist/server/mcp/tools/get-routes.js +44 -79
- package/standalone/node_modules/next/dist/server/mcp/tools/get-server-action-by-id.js +12 -4
- package/standalone/node_modules/next/dist/server/mcp/tools/utils/format-errors.js +62 -72
- package/standalone/node_modules/next/dist/server/next-server.js +69 -99
- package/standalone/node_modules/next/dist/server/next.js +3 -0
- package/standalone/node_modules/next/dist/server/node-environment-extensions/console-dim.external.js +61 -6
- package/standalone/node_modules/next/dist/server/node-environment-extensions/date.js +4 -4
- package/standalone/node_modules/next/dist/server/node-environment-extensions/fast-set-immediate.external.js +13 -6
- package/standalone/node_modules/next/dist/server/node-environment-extensions/{utils.js → io-utils.js} +14 -5
- package/standalone/node_modules/next/dist/server/node-environment-extensions/node-crypto.js +8 -8
- package/standalone/node_modules/next/dist/server/node-environment-extensions/process-error-handlers.js +91 -0
- package/standalone/node_modules/next/dist/server/node-environment-extensions/random.js +2 -2
- package/standalone/node_modules/next/dist/server/node-environment-extensions/{unhandled-rejection.js → unhandled-rejection.external.js} +23 -4
- package/standalone/node_modules/next/dist/server/node-environment-extensions/web-crypto.js +3 -3
- package/standalone/node_modules/next/dist/server/node-environment.js +1 -1
- package/standalone/node_modules/next/dist/server/normalizers/request/segment-prefix-rsc.js +2 -1
- package/standalone/node_modules/next/dist/server/patch-error-inspect.js +37 -20
- package/standalone/node_modules/next/dist/server/render-result.js +9 -0
- package/standalone/node_modules/next/dist/server/render.js +27 -25
- package/standalone/node_modules/next/dist/server/require-hook.js +19 -8
- package/standalone/node_modules/next/dist/server/response-cache/utils.js +1 -0
- package/standalone/node_modules/next/dist/server/resume-data-cache/cache-store.js +35 -23
- package/standalone/node_modules/next/dist/server/resume-data-cache/resume-data-cache.js +16 -7
- package/standalone/node_modules/next/dist/server/revalidation-utils.js +12 -7
- package/standalone/node_modules/next/dist/server/route-matcher-providers/dev/dev-app-page-route-matcher-provider.js +2 -1
- package/standalone/node_modules/next/dist/server/route-modules/app-page/helpers/prerender-manifest-matcher.js +4 -1
- package/standalone/node_modules/next/dist/server/route-modules/app-page/module.js +31 -1
- package/standalone/node_modules/next/dist/server/route-modules/app-page/normalize-request-url.js +25 -0
- package/standalone/node_modules/next/dist/server/route-modules/pages/pages-handler.js +31 -8
- package/standalone/node_modules/next/dist/server/route-modules/route-module.js +71 -18
- package/standalone/node_modules/next/dist/server/stream-utils/encoded-tags.js +8 -0
- package/standalone/node_modules/next/dist/server/stream-utils/node-web-streams-helper.js +239 -58
- package/standalone/node_modules/next/dist/server/stream-utils/uint8array-helpers.js +7 -2
- package/standalone/node_modules/next/dist/server/typescript/constant.js +1 -0
- package/standalone/node_modules/next/dist/server/typescript/rules/config.js +14 -3
- package/standalone/node_modules/next/dist/server/web/adapter.js +7 -3
- package/standalone/node_modules/next/dist/server/web/next-url.js +6 -2
- package/standalone/node_modules/next/dist/server/web/sandbox/sandbox.js +3 -0
- package/standalone/node_modules/next/dist/shared/lib/app-router-types.js +30 -11
- package/standalone/node_modules/next/dist/shared/lib/constants.js +7 -7
- package/standalone/node_modules/next/dist/shared/lib/deployment-id.js +37 -10
- package/standalone/node_modules/next/dist/shared/lib/errors/canary-only-config-error.js +1 -1
- package/standalone/node_modules/next/dist/shared/lib/errors/code-frame.js +20 -0
- package/standalone/node_modules/next/dist/shared/lib/format-webpack-messages.js +22 -2
- package/standalone/node_modules/next/dist/shared/lib/image-config.js +3 -1
- package/standalone/node_modules/next/dist/shared/lib/is-internal.js +2 -0
- package/standalone/node_modules/next/dist/shared/lib/magic-identifier.js +6 -6
- package/standalone/node_modules/next/dist/shared/lib/router/router.js +32 -0
- package/standalone/node_modules/next/dist/shared/lib/router/utils/app-paths.js +11 -0
- package/standalone/node_modules/next/dist/shared/lib/router/utils/get-dynamic-param.js +11 -4
- package/standalone/node_modules/next/dist/shared/lib/router/utils/parse-loader-tree.js +3 -2
- package/standalone/node_modules/next/dist/shared/lib/router/utils/parse-relative-url.js +9 -2
- package/standalone/node_modules/next/dist/shared/lib/router/utils/parse-url.js +8 -2
- package/standalone/node_modules/next/dist/shared/lib/segment-cache/vary-params-decoding.js +32 -0
- package/standalone/node_modules/next/dist/shared/lib/server-reference-info.js +4 -0
- package/standalone/node_modules/next/dist/shared/lib/size-limit.js +6 -1
- package/standalone/node_modules/next/dist/shared/lib/turbopack/compilation-events.js +47 -10
- package/standalone/node_modules/next/dist/shared/lib/turbopack/manifest-loader.js +90 -116
- package/standalone/node_modules/next/dist/shared/lib/turbopack/utils.js +14 -26
- package/standalone/node_modules/next/dist/shared/lib/utils/reflect-utils.js +69 -0
- package/standalone/node_modules/next/dist/shared/lib/utils.js +2 -2
- package/standalone/node_modules/next/dist/telemetry/anonymous-meta.js +1 -1
- package/standalone/node_modules/next/dist/telemetry/events/swc-load-failure.js +1 -1
- package/standalone/node_modules/next/dist/telemetry/events/version.js +2 -2
- package/standalone/node_modules/next/dist/trace/index.js +4 -0
- package/standalone/node_modules/next/dist/trace/report/to-json-build.js +11 -108
- package/standalone/node_modules/next/dist/trace/report/to-json.js +52 -38
- package/standalone/node_modules/next/dist/trace/trace.js +15 -1
- package/standalone/node_modules/next/package.json +21 -23
- package/standalone/node_modules/react/cjs/react.development.js +1284 -0
- package/standalone/package.json +3 -3
- package/standalone/packages/core/package.json +1 -1
- package/standalone/apps/frontend/.next/static/chunks/1315.18c68981a2eab4fe.js +0 -1
- package/standalone/apps/frontend/.next/static/chunks/87c73c54-c5fda2db2a4bd732.js +0 -1
- package/standalone/apps/frontend/.next/static/chunks/common-d9b436492e46bb05.js +0 -69
- package/standalone/apps/frontend/.next/static/chunks/framework-86c2a58f458066a5.js +0 -1
- package/standalone/apps/frontend/.next/static/chunks/vendors-c7197feb11002a6e.js +0 -10
- package/standalone/apps/frontend/.next/static/kMwuefB4Z1_6Xta5NPqs1/_buildManifest.js +0 -1
- package/standalone/node_modules/next/dist/client/components/router-reducer/handle-mutable.js +0 -66
- package/standalone/node_modules/next/dist/compiled/babel/code-frame.js +0 -1
- package/standalone/node_modules/next/dist/compiled/babel-code-frame/index.js +0 -1
- package/standalone/node_modules/next/dist/compiled/babel-code-frame/package.json +0 -1
- package/standalone/node_modules/next/dist/compiled/tar/index.js +0 -1
- package/standalone/node_modules/next/dist/server/app-render/staged-validation.js +0 -32
- package/standalone/node_modules/next/dist/server/lib/router-utils/block-cross-site.js +0 -76
- package/standalone/node_modules/next/dist/shared/lib/segment-cache/output-export-prefetch-encoding.js +0 -52
- package/standalone/node_modules/typescript/lib/typescript.js +0 -200276
- package/standalone/node_modules/typescript/package.json +0 -120
- /package/standalone/apps/frontend/.next/static/{kMwuefB4Z1_6Xta5NPqs1 → I_XveRdyStDMqYJPcAAy5}/_ssgManifest.js +0 -0
|
@@ -12,7 +12,7 @@ const _jsxruntime = require("react/jsx-runtime");
|
|
|
12
12
|
const _workasyncstorageexternal = require("../app-render/work-async-storage.external");
|
|
13
13
|
const _react = /*#__PURE__*/ _interop_require_wildcard(require("react"));
|
|
14
14
|
const _renderresult = /*#__PURE__*/ _interop_require_default(require("../render-result"));
|
|
15
|
-
const
|
|
15
|
+
const _streamops = require("./stream-ops");
|
|
16
16
|
const _internalutils = require("../internal-utils");
|
|
17
17
|
const _approuterheaders = require("../../client/components/app-router-headers");
|
|
18
18
|
const _metadatacontext = require("../../lib/metadata/metadata-context");
|
|
@@ -48,6 +48,7 @@ const _hooksservercontext = require("../../client/components/hooks-server-contex
|
|
|
48
48
|
const _useflightresponse = require("./use-flight-response");
|
|
49
49
|
const _staticgenerationbailout = require("../../client/components/static-generation-bailout");
|
|
50
50
|
const _formatservererror = require("../../lib/format-server-error");
|
|
51
|
+
const _errortelemetryutils = require("../../lib/error-telemetry-utils");
|
|
51
52
|
const _dynamicrendering = require("./dynamic-rendering");
|
|
52
53
|
const _clientcomponentrendererlogger = require("../client-component-renderer-logger");
|
|
53
54
|
const _helpers = require("../base-http/helpers");
|
|
@@ -58,6 +59,7 @@ const _createinitialrouterstate = require("../../client/components/router-reduce
|
|
|
58
59
|
const _approuterinstance = require("../../client/components/app-router-instance");
|
|
59
60
|
const _utils = require("../instrumentation/utils");
|
|
60
61
|
const _segment = require("../../shared/lib/segment");
|
|
62
|
+
const _fallbackparams = require("../request/fallback-params");
|
|
61
63
|
const _apprenderprerenderutils = require("./app-render-prerender-utils");
|
|
62
64
|
const _prospectiverenderutils = require("./prospective-render-utils");
|
|
63
65
|
const _apprenderrenderutils = require("./app-render-render-utils");
|
|
@@ -65,8 +67,10 @@ const _scheduler = require("../../lib/scheduler");
|
|
|
65
67
|
const _workunitasyncstorageexternal = require("./work-unit-async-storage.external");
|
|
66
68
|
const _consoleasyncstorageexternal = require("./console-async-storage.external");
|
|
67
69
|
const _cachesignal = require("./cache-signal");
|
|
70
|
+
const _varyparams = require("./vary-params");
|
|
68
71
|
const _utils1 = require("../lib/trace/utils");
|
|
69
72
|
const _invarianterror = require("../../shared/lib/invariant-error");
|
|
73
|
+
const _staletime = require("./stale-time");
|
|
70
74
|
const _constants1 = require("../../lib/constants");
|
|
71
75
|
const _createcomponentstylesandscripts = require("./create-component-styles-and-scripts");
|
|
72
76
|
const _parseloadertree = require("../../shared/lib/router/utils/parse-loader-tree");
|
|
@@ -80,12 +84,16 @@ const _reactlargeshellerror = require("./react-large-shell-error");
|
|
|
80
84
|
const _segmentexplorerpath = require("./segment-explorer-path");
|
|
81
85
|
const _requestmeta = require("../request-meta");
|
|
82
86
|
const _getdynamicparam = require("../../shared/lib/router/utils/get-dynamic-param");
|
|
83
|
-
const _promisewithresolvers = require("../../shared/lib/promise-with-resolvers");
|
|
84
87
|
const _imageconfigcontextsharedruntime = require("../../shared/lib/image-config-context.shared-runtime");
|
|
85
88
|
const _imageconfig = require("../../shared/lib/image-config");
|
|
86
89
|
const _stagedrendering = require("./staged-rendering");
|
|
87
|
-
const
|
|
90
|
+
const _instantconfig = require("./instant-validation/instant-config");
|
|
88
91
|
const _warnonce = require("../../shared/lib/utils/warn-once");
|
|
92
|
+
const _debugchannelserver = require("./debug-channel-server");
|
|
93
|
+
const _streamutils = require("./instant-validation/stream-utils");
|
|
94
|
+
const _boundarytracking = require("./instant-validation/boundary-tracking");
|
|
95
|
+
const _cookies = require("../web/spec-extension/cookies");
|
|
96
|
+
const _instantvalidationerror = require("./instant-validation/instant-validation-error");
|
|
89
97
|
function _interop_require_default(obj) {
|
|
90
98
|
return obj && obj.__esModule ? obj : {
|
|
91
99
|
default: obj
|
|
@@ -132,6 +140,14 @@ function _interop_require_wildcard(obj, nodeInterop) {
|
|
|
132
140
|
}
|
|
133
141
|
return newObj;
|
|
134
142
|
}
|
|
143
|
+
function maybeAppendBuildIdToRSCPayload(ctx, payload) {
|
|
144
|
+
if (!ctx.sharedContext.deploymentId) {
|
|
145
|
+
// When using the build id, we need to initialize the id on initial page load, so a build id
|
|
146
|
+
// header wouldn't be enough.
|
|
147
|
+
payload.b = ctx.sharedContext.buildId;
|
|
148
|
+
}
|
|
149
|
+
return payload;
|
|
150
|
+
}
|
|
135
151
|
const flightDataPathHeadKey = 'h';
|
|
136
152
|
const getFlightViewportKey = (requestId)=>requestId + 'v';
|
|
137
153
|
const getFlightMetadataKey = (requestId)=>requestId + 'm';
|
|
@@ -152,8 +168,8 @@ function parseRequestHeaders(headers, options) {
|
|
|
152
168
|
const previouslyRevalidatedTags = (0, _serverutils.getPreviouslyRevalidatedTags)(headers, options.previewModeId);
|
|
153
169
|
let requestId;
|
|
154
170
|
let htmlRequestId;
|
|
155
|
-
if (process.env.
|
|
156
|
-
// The request IDs are only used
|
|
171
|
+
if (process.env.__NEXT_DEV_SERVER) {
|
|
172
|
+
// The request IDs are only used for the dev server to send debug
|
|
157
173
|
// information to the matching client (identified by the HTML request ID
|
|
158
174
|
// that was sent to the client with the HTML document) for the current
|
|
159
175
|
// request (identified by the request ID, as defined by the client).
|
|
@@ -173,6 +189,38 @@ function parseRequestHeaders(headers, options) {
|
|
|
173
189
|
htmlRequestId
|
|
174
190
|
};
|
|
175
191
|
}
|
|
192
|
+
/**
|
|
193
|
+
* Walks the loader tree to find the minimum `unstable_dynamicStaleTime` exported by
|
|
194
|
+
* any page module. Returns null if no page exports the config.
|
|
195
|
+
*
|
|
196
|
+
* This only reads static exports from page modules — it does not render any
|
|
197
|
+
* server components, so it's cheap to call.
|
|
198
|
+
*
|
|
199
|
+
* TODO: Move this to the prefetch hints file so we don't have to walk the
|
|
200
|
+
* tree on every render.
|
|
201
|
+
*/ async function getDynamicStaleTime(tree) {
|
|
202
|
+
const { page, parallelRoutes } = (0, _parseloadertree.parseLoaderTree)(tree);
|
|
203
|
+
let result = null;
|
|
204
|
+
// Only pages (not layouts) can export unstable_dynamicStaleTime.
|
|
205
|
+
if (typeof page !== 'undefined') {
|
|
206
|
+
const pageMod = await page[0]();
|
|
207
|
+
if (pageMod && typeof pageMod.unstable_dynamicStaleTime === 'number') {
|
|
208
|
+
const value = pageMod.unstable_dynamicStaleTime;
|
|
209
|
+
result = result !== null ? Math.min(result, value) : value;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
const childPromises = [];
|
|
213
|
+
for(const parallelRouteKey in parallelRoutes){
|
|
214
|
+
childPromises.push(getDynamicStaleTime(parallelRoutes[parallelRouteKey]));
|
|
215
|
+
}
|
|
216
|
+
const childResults = await Promise.all(childPromises);
|
|
217
|
+
for (const childResult of childResults){
|
|
218
|
+
if (childResult !== null) {
|
|
219
|
+
result = result !== null ? Math.min(result, childResult) : childResult;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
return result;
|
|
223
|
+
}
|
|
176
224
|
function createNotFoundLoaderTree(loaderTree) {
|
|
177
225
|
const components = loaderTree[2];
|
|
178
226
|
const hasGlobalNotFound = !!components['global-not-found'];
|
|
@@ -191,25 +239,33 @@ function createNotFoundLoaderTree(loaderTree) {
|
|
|
191
239
|
children: [
|
|
192
240
|
_segment.PAGE_SEGMENT_KEY,
|
|
193
241
|
{},
|
|
194
|
-
notFoundTreeComponents
|
|
242
|
+
notFoundTreeComponents,
|
|
243
|
+
null
|
|
195
244
|
]
|
|
196
245
|
},
|
|
197
|
-
//
|
|
198
|
-
|
|
246
|
+
// Always include global-error so that getGlobalErrorStyles can access it.
|
|
247
|
+
// When global-not-found is present, use full components.
|
|
248
|
+
// Otherwise, only include global-error module.
|
|
249
|
+
hasGlobalNotFound ? components : {
|
|
250
|
+
'global-error': components['global-error']
|
|
251
|
+
},
|
|
252
|
+
null
|
|
199
253
|
];
|
|
200
254
|
}
|
|
201
255
|
/**
|
|
202
256
|
* Returns a function that parses the dynamic segment and return the associated value.
|
|
203
|
-
*/ function makeGetDynamicParamFromSegment(interpolatedParams, fallbackRouteParams) {
|
|
204
|
-
return function getDynamicParamFromSegment(
|
|
205
|
-
|
|
257
|
+
*/ function makeGetDynamicParamFromSegment(interpolatedParams, fallbackRouteParams, optimisticRouting) {
|
|
258
|
+
return function getDynamicParamFromSegment(loaderTree) {
|
|
259
|
+
const [segment, , , staticSiblings] = loaderTree;
|
|
206
260
|
const segmentParam = (0, _getsegmentparam.getSegmentParam)(segment);
|
|
207
261
|
if (!segmentParam) {
|
|
208
262
|
return null;
|
|
209
263
|
}
|
|
210
264
|
const segmentKey = segmentParam.paramName;
|
|
211
265
|
const dynamicParamType = _getshortdynamicparamtype.dynamicParamTypes[segmentParam.paramType];
|
|
212
|
-
|
|
266
|
+
// Static siblings are only included when optimistic routing is enabled
|
|
267
|
+
const siblings = optimisticRouting ? staticSiblings : null;
|
|
268
|
+
return (0, _getdynamicparam.getDynamicParam)(interpolatedParams, segmentKey, dynamicParamType, fallbackRouteParams, siblings);
|
|
213
269
|
};
|
|
214
270
|
}
|
|
215
271
|
function NonIndex({ createElement, pagePath, statusCode, isPossibleServerAction }) {
|
|
@@ -237,78 +293,105 @@ function NonIndex({ createElement, pagePath, statusCode, isPossibleServerAction
|
|
|
237
293
|
// is for server actions, if the server action handler instructs this function to skip it. When the server
|
|
238
294
|
// action reducer sees a falsy value, it'll simply resolve the action with no data.
|
|
239
295
|
let flightData = '';
|
|
240
|
-
const { componentMod: { routeModule: { userland: { loaderTree } }, createElement, createMetadataComponents, Fragment },
|
|
296
|
+
const { componentMod: { routeModule: { userland: { loaderTree } }, createElement, createMetadataComponents, Fragment }, query, requestId, flightRouterState, workStore, url } = ctx;
|
|
241
297
|
const serveStreamingMetadata = !!ctx.renderOpts.serveStreamingMetadata;
|
|
242
298
|
if (!(options == null ? void 0 : options.skipPageRendering)) {
|
|
299
|
+
var _ctx_renderOpts_prefetchHints;
|
|
243
300
|
const preloadCallbacks = [];
|
|
301
|
+
// If we're performing instant validation, we need to render the whole tree,
|
|
302
|
+
// without skipping shared layouts.
|
|
303
|
+
const needsFullTree = process.env.__NEXT_DEV_SERVER && ctx.renderOpts.cacheComponents && !(options == null ? void 0 : options.actionResult) && // Only for navigations
|
|
304
|
+
await (0, _instantconfig.anySegmentNeedsInstantValidationInDev)(loaderTree);
|
|
305
|
+
const metadataIsRuntimePrefetchable = await (0, _instantconfig.anySegmentHasRuntimePrefetchEnabled)(loaderTree);
|
|
244
306
|
const { Viewport, Metadata, MetadataOutlet } = createMetadataComponents({
|
|
245
307
|
tree: loaderTree,
|
|
246
308
|
parsedQuery: query,
|
|
247
309
|
pathname: url.pathname,
|
|
248
310
|
metadataContext: (0, _metadatacontext.createMetadataContext)(ctx.renderOpts),
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
311
|
+
interpolatedParams: ctx.interpolatedParams,
|
|
312
|
+
serveStreamingMetadata,
|
|
313
|
+
isRuntimePrefetchable: metadataIsRuntimePrefetchable
|
|
252
314
|
});
|
|
253
|
-
|
|
315
|
+
const rscHead = createElement(Fragment, {
|
|
316
|
+
key: flightDataPathHeadKey
|
|
317
|
+
}, createElement(NonIndex, {
|
|
318
|
+
createElement,
|
|
319
|
+
pagePath: ctx.pagePath,
|
|
320
|
+
statusCode: ctx.res.statusCode,
|
|
321
|
+
isPossibleServerAction: ctx.isPossibleServerAction
|
|
322
|
+
}), createElement(Viewport, {
|
|
323
|
+
key: getFlightViewportKey(requestId)
|
|
324
|
+
}), createElement(Metadata, {
|
|
325
|
+
key: getFlightMetadataKey(requestId)
|
|
326
|
+
}));
|
|
327
|
+
flightData = (needsFullTree ? await (0, _walktreewithflightrouterstate.createFullTreeFlightDataForNavigation)({
|
|
328
|
+
ctx,
|
|
329
|
+
loaderTree,
|
|
330
|
+
rscHead,
|
|
331
|
+
injectedCSS: new Set(),
|
|
332
|
+
injectedJS: new Set(),
|
|
333
|
+
injectedFontPreloadTags: new Set(),
|
|
334
|
+
preloadCallbacks,
|
|
335
|
+
MetadataOutlet
|
|
336
|
+
}) : await (0, _walktreewithflightrouterstate.walkTreeWithFlightRouterState)({
|
|
254
337
|
ctx,
|
|
255
338
|
loaderTreeToFilter: loaderTree,
|
|
256
339
|
parentParams: {},
|
|
257
340
|
flightRouterState,
|
|
258
|
-
|
|
259
|
-
rscHead: createElement(Fragment, {
|
|
260
|
-
key: flightDataPathHeadKey
|
|
261
|
-
}, createElement(NonIndex, {
|
|
262
|
-
createElement,
|
|
263
|
-
pagePath: ctx.pagePath,
|
|
264
|
-
statusCode: ctx.res.statusCode,
|
|
265
|
-
isPossibleServerAction: ctx.isPossibleServerAction
|
|
266
|
-
}), createElement(Viewport, {
|
|
267
|
-
key: getFlightViewportKey(requestId)
|
|
268
|
-
}), createElement(Metadata, {
|
|
269
|
-
key: getFlightMetadataKey(requestId)
|
|
270
|
-
})),
|
|
341
|
+
rscHead,
|
|
271
342
|
injectedCSS: new Set(),
|
|
272
343
|
injectedJS: new Set(),
|
|
273
344
|
injectedFontPreloadTags: new Set(),
|
|
274
345
|
rootLayoutIncluded: false,
|
|
275
346
|
preloadCallbacks,
|
|
276
|
-
MetadataOutlet
|
|
347
|
+
MetadataOutlet,
|
|
348
|
+
hintTree: ((_ctx_renderOpts_prefetchHints = ctx.renderOpts.prefetchHints) == null ? void 0 : _ctx_renderOpts_prefetchHints[ctx.pagePath]) ?? null
|
|
277
349
|
})).map((path)=>path.slice(1)) // remove the '' (root) segment
|
|
278
350
|
;
|
|
279
351
|
}
|
|
352
|
+
// In dev, the Vary header may not reliably reflect whether a route can
|
|
353
|
+
// be intercepted, because interception routes are compiled on demand.
|
|
354
|
+
// Default to true so the client doesn't cache a stale Fallback entry.
|
|
280
355
|
const varyHeader = ctx.res.getHeader('vary');
|
|
281
|
-
const couldBeIntercepted = typeof varyHeader === 'string' && varyHeader.includes(_approuterheaders.NEXT_URL);
|
|
356
|
+
const couldBeIntercepted = !!process.env.__NEXT_DEV_SERVER || typeof varyHeader === 'string' && varyHeader.includes(_approuterheaders.NEXT_URL);
|
|
282
357
|
// If we have an action result, then this is a server action response.
|
|
283
358
|
// We can rely on this because `ActionResult` will always be a promise, even if
|
|
284
359
|
// the result is falsey.
|
|
285
360
|
if (options == null ? void 0 : options.actionResult) {
|
|
286
|
-
return {
|
|
361
|
+
return maybeAppendBuildIdToRSCPayload(ctx, {
|
|
287
362
|
a: options.actionResult,
|
|
288
363
|
f: flightData,
|
|
289
|
-
b: ctx.sharedContext.buildId,
|
|
290
364
|
q: getRenderedSearch(query),
|
|
291
365
|
i: !!couldBeIntercepted
|
|
292
|
-
};
|
|
366
|
+
});
|
|
293
367
|
}
|
|
294
368
|
// Otherwise, it's a regular RSC response.
|
|
295
|
-
const baseResponse = {
|
|
296
|
-
b: ctx.sharedContext.buildId,
|
|
369
|
+
const baseResponse = maybeAppendBuildIdToRSCPayload(ctx, {
|
|
297
370
|
f: flightData,
|
|
298
371
|
q: getRenderedSearch(query),
|
|
299
372
|
i: !!couldBeIntercepted,
|
|
300
|
-
S: workStore.isStaticGeneration
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
373
|
+
S: workStore.isStaticGeneration,
|
|
374
|
+
h: (0, _varyparams.getMetadataVaryParamsThenable)()
|
|
375
|
+
});
|
|
376
|
+
if ((options == null ? void 0 : options.staleTimeIterable) !== undefined) {
|
|
377
|
+
baseResponse.s = options.staleTimeIterable;
|
|
378
|
+
}
|
|
379
|
+
if ((options == null ? void 0 : options.staticStageByteLengthPromise) !== undefined) {
|
|
380
|
+
baseResponse.l = options.staticStageByteLengthPromise;
|
|
381
|
+
}
|
|
382
|
+
if ((options == null ? void 0 : options.runtimePrefetchStream) !== undefined) {
|
|
383
|
+
baseResponse.p = options.runtimePrefetchStream;
|
|
384
|
+
}
|
|
385
|
+
// Include the per-page dynamic stale time from unstable_dynamicStaleTime, but only
|
|
386
|
+
// for dynamic renders (not prerenders/static generation). The client treats
|
|
387
|
+
// its presence as authoritative.
|
|
388
|
+
// TODO: Move this to the prefetch hints file so we don't have to walk the
|
|
389
|
+
// tree on every render.
|
|
390
|
+
if (!workStore.isStaticGeneration) {
|
|
391
|
+
const dynamicStaleTime = await getDynamicStaleTime(ctx.componentMod.routeModule.userland.loaderTree);
|
|
392
|
+
if (dynamicStaleTime !== null) {
|
|
393
|
+
baseResponse.d = dynamicStaleTime;
|
|
394
|
+
}
|
|
312
395
|
}
|
|
313
396
|
return baseResponse;
|
|
314
397
|
}
|
|
@@ -326,13 +409,13 @@ function createErrorContext(ctx, renderSource) {
|
|
|
326
409
|
* Produces a RenderResult containing the Flight data for the given request. See
|
|
327
410
|
* `generateDynamicRSCPayload` for information on the contents of the render result.
|
|
328
411
|
*/ async function generateDynamicFlightRenderResult(req, ctx, requestStore, options) {
|
|
329
|
-
const {
|
|
330
|
-
const {
|
|
412
|
+
const { htmlRequestId, renderOpts, requestId, workStore } = ctx;
|
|
413
|
+
const { onInstrumentationRequestError, setReactDebugChannel, isBuildTimePrerendering = false } = renderOpts;
|
|
331
414
|
function onFlightDataRenderError(err, silenceLog) {
|
|
332
415
|
return onInstrumentationRequestError == null ? void 0 : onInstrumentationRequestError(err, req, createErrorContext(ctx, 'react-server-components-payload'), silenceLog);
|
|
333
416
|
}
|
|
334
|
-
const onError = (0, _createerrorhandler.createReactServerErrorHandler)(
|
|
335
|
-
const debugChannel = setReactDebugChannel && createDebugChannel();
|
|
417
|
+
const onError = (0, _createerrorhandler.createReactServerErrorHandler)(process.env.NODE_ENV === 'development', isBuildTimePrerendering, workStore.reactServerErrorsByDigest, onFlightDataRenderError);
|
|
418
|
+
const debugChannel = setReactDebugChannel && (0, _debugchannelserver.createDebugChannel)();
|
|
336
419
|
if (debugChannel) {
|
|
337
420
|
setReactDebugChannel(debugChannel.clientSide, htmlRequestId, requestId);
|
|
338
421
|
}
|
|
@@ -340,36 +423,142 @@ function createErrorContext(ctx, renderSource) {
|
|
|
340
423
|
// For app dir, use the bundled version of Flight server renderer (renderToReadableStream)
|
|
341
424
|
// which contains the subset React.
|
|
342
425
|
const rscPayload = await _workunitasyncstorageexternal.workUnitAsyncStorage.run(requestStore, generateDynamicRSCPayload, ctx, options);
|
|
343
|
-
const
|
|
426
|
+
const flightStream = _workunitasyncstorageexternal.workUnitAsyncStorage.run(requestStore, _streamops.renderToFlightStream, ctx.componentMod, rscPayload, clientModules, {
|
|
344
427
|
onError,
|
|
345
428
|
temporaryReferences: options == null ? void 0 : options.temporaryReferences,
|
|
346
429
|
filterStackFrame,
|
|
347
430
|
debugChannel: debugChannel == null ? void 0 : debugChannel.serverSide
|
|
348
431
|
});
|
|
349
|
-
return new _flightrenderresult.FlightRenderResult(
|
|
432
|
+
return new _flightrenderresult.FlightRenderResult(flightStream, {
|
|
350
433
|
fetchMetrics: workStore.fetchMetrics
|
|
351
434
|
}, options == null ? void 0 : options.waitUntil);
|
|
352
435
|
}
|
|
436
|
+
/**
|
|
437
|
+
* Production-only staged dynamic flight render for cache components. Uses
|
|
438
|
+
* staged rendering to separate static (RDC-backed) from runtime/dynamic
|
|
439
|
+
* content.
|
|
440
|
+
*/ async function generateStagedDynamicFlightRenderResult(req, ctx, requestStore) {
|
|
441
|
+
const { componentMod, workStore, renderOpts } = ctx;
|
|
442
|
+
const { renderToReadableStream, routeModule } = componentMod;
|
|
443
|
+
const { loaderTree } = routeModule.userland;
|
|
444
|
+
const { onInstrumentationRequestError, experimental } = renderOpts;
|
|
445
|
+
function onFlightDataRenderError(err, silenceLog) {
|
|
446
|
+
return onInstrumentationRequestError == null ? void 0 : onInstrumentationRequestError(err, req, createErrorContext(ctx, 'react-server-components-payload'), silenceLog);
|
|
447
|
+
}
|
|
448
|
+
const onError = (0, _createerrorhandler.createReactServerErrorHandler)(false, false, workStore.reactServerErrorsByDigest, onFlightDataRenderError);
|
|
449
|
+
const selectStaleTime = (0, _staletime.createSelectStaleTime)(experimental);
|
|
450
|
+
const staleTimeIterable = new _staletime.StaleTimeIterable();
|
|
451
|
+
// TODO(cached-navs): this assumes that we checked during build that there's no sync IO.
|
|
452
|
+
// but it can happen e.g. after a revalidation or conditionally for a param that wasn't prerendered.
|
|
453
|
+
// we should change this to track sync IO, log an error and advance to dynamic.
|
|
454
|
+
const shouldTrackSyncIO = false;
|
|
455
|
+
const stageController = new _stagedrendering.StagedRenderingController(null, null, shouldTrackSyncIO);
|
|
456
|
+
// Initialize stale time tracking on the request store.
|
|
457
|
+
requestStore.stale = _constants1.INFINITE_CACHE;
|
|
458
|
+
requestStore.stagedRendering = stageController;
|
|
459
|
+
requestStore.asyncApiPromises = createAsyncApiPromises(stageController, requestStore.cookies, requestStore.mutableCookies, requestStore.headers);
|
|
460
|
+
(0, _staletime.trackStaleTime)(requestStore, staleTimeIterable, selectStaleTime);
|
|
461
|
+
// Deferred promise for the static stage byte length. Flight serializes the
|
|
462
|
+
// resolved value into the stream so the client knows where the static
|
|
463
|
+
// prefix ends.
|
|
464
|
+
let resolveStaticStageByteLength;
|
|
465
|
+
const staticStageByteLengthPromise = new Promise((resolve)=>{
|
|
466
|
+
resolveStaticStageByteLength = resolve;
|
|
467
|
+
});
|
|
468
|
+
// Check if this route has opted into runtime prefetching via
|
|
469
|
+
// unstable_instant. If so, we piggyback on the dynamic render to fill caches
|
|
470
|
+
// and then spawn a final runtime prerender whose result stream is embedded in
|
|
471
|
+
// the RSC payload. This is gated on the explicit opt-in because it adds extra
|
|
472
|
+
// server processing, increases the response payload size, and the runtime
|
|
473
|
+
// prefetch output should have been validated first.
|
|
474
|
+
const hasRuntimePrefetch = await (0, _instantconfig.anySegmentHasRuntimePrefetchEnabled)(loaderTree);
|
|
475
|
+
let runtimePrefetchStream;
|
|
476
|
+
if (hasRuntimePrefetch) {
|
|
477
|
+
// Create a mutable cache that gets filled during the dynamic render.
|
|
478
|
+
const prerenderResumeDataCache = (0, _resumedatacache.createPrerenderResumeDataCache)();
|
|
479
|
+
requestStore.prerenderResumeDataCache = prerenderResumeDataCache;
|
|
480
|
+
const cacheSignal = new _cachesignal.CacheSignal();
|
|
481
|
+
(0, _trackmoduleloadingexternal.trackPendingModules)(cacheSignal);
|
|
482
|
+
requestStore.cacheSignal = cacheSignal;
|
|
483
|
+
// Create a deferred stream for the runtime prefetch result. Its readable
|
|
484
|
+
// side goes into the RSC payload (Flight serializes it lazily). The
|
|
485
|
+
// writable side receives the runtime prerender result once the dynamic
|
|
486
|
+
// render has filled all caches.
|
|
487
|
+
const runtimePrefetchTransform = new TransformStream();
|
|
488
|
+
runtimePrefetchStream = runtimePrefetchTransform.readable;
|
|
489
|
+
// Wait for the dynamic render to fill caches, then run the final runtime
|
|
490
|
+
// prerender (fire-and-forget — does not block the response).
|
|
491
|
+
void cacheSignal.cacheReady().then(()=>spawnRuntimePrefetchWithFilledCaches(runtimePrefetchTransform.writable, ctx, prerenderResumeDataCache, requestStore, onError));
|
|
492
|
+
}
|
|
493
|
+
const rscPayload = await _workunitasyncstorageexternal.workUnitAsyncStorage.run(requestStore, generateDynamicRSCPayload, ctx, {
|
|
494
|
+
staleTimeIterable,
|
|
495
|
+
staticStageByteLengthPromise,
|
|
496
|
+
runtimePrefetchStream
|
|
497
|
+
});
|
|
498
|
+
const { clientModules } = (0, _manifestssingleton.getClientReferenceManifest)();
|
|
499
|
+
const flightReadableStream = await (0, _apprenderrenderutils.runInSequentialTasks)(()=>{
|
|
500
|
+
stageController.advanceStage(_stagedrendering.RenderStage.Static);
|
|
501
|
+
const stream = _workunitasyncstorageexternal.workUnitAsyncStorage.run(requestStore, renderToReadableStream, rscPayload, clientModules, {
|
|
502
|
+
onError,
|
|
503
|
+
filterStackFrame
|
|
504
|
+
});
|
|
505
|
+
const [dynamicStream, staticStream] = stream.tee();
|
|
506
|
+
countStaticStageBytes(staticStream, stageController).then(resolveStaticStageByteLength);
|
|
507
|
+
return dynamicStream;
|
|
508
|
+
}, ()=>{
|
|
509
|
+
// This is a separate task that doesn't advance a stage. It forces
|
|
510
|
+
// draining the microtask queue so that the stale time iterable is closed
|
|
511
|
+
// before we advance to the dynamic stage.
|
|
512
|
+
void (0, _staletime.finishStaleTimeTracking)(staleTimeIterable);
|
|
513
|
+
}, ()=>{
|
|
514
|
+
stageController.advanceStage(_stagedrendering.RenderStage.Dynamic);
|
|
515
|
+
});
|
|
516
|
+
return new _flightrenderresult.FlightRenderResult(flightReadableStream, {
|
|
517
|
+
fetchMetrics: workStore.fetchMetrics
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
/**
|
|
521
|
+
* Runs a final runtime prerender using the provided (already filled) cache and
|
|
522
|
+
* pipes its output into the provided writable stream. The caller is responsible
|
|
523
|
+
* for waiting until caches are warm before calling this function.
|
|
524
|
+
*/ async function spawnRuntimePrefetchWithFilledCaches(writable, ctx, prerenderResumeDataCache, requestStore, onError) {
|
|
525
|
+
try {
|
|
526
|
+
const { componentMod, getDynamicParamFromSegment } = ctx;
|
|
527
|
+
const { loaderTree } = componentMod.routeModule.userland;
|
|
528
|
+
const rootParams = (0, _createcomponenttree.getRootParams)(loaderTree, getDynamicParamFromSegment);
|
|
529
|
+
const staleTimeIterable = new _staletime.StaleTimeIterable();
|
|
530
|
+
const { result } = await finalRuntimeServerPrerender(ctx, generateDynamicRSCPayload.bind(null, ctx, {
|
|
531
|
+
staleTimeIterable
|
|
532
|
+
}), prerenderResumeDataCache, null, rootParams, requestStore.headers, requestStore.cookies, requestStore.draftMode, onError, staleTimeIterable);
|
|
533
|
+
await result.prelude.pipeTo(writable);
|
|
534
|
+
} catch {
|
|
535
|
+
// Runtime prerender failed. Close the stream gracefully — the navigation
|
|
536
|
+
// still works, we just won't get cached runtime data.
|
|
537
|
+
try {
|
|
538
|
+
await writable.close();
|
|
539
|
+
} catch {
|
|
540
|
+
// Writable may already be closed/errored.
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
}
|
|
353
544
|
async function stagedRenderToReadableStreamWithoutCachesInDev(ctx, requestStore, getPayload, options) {
|
|
354
|
-
const { componentMod: { renderToReadableStream } } = ctx;
|
|
355
545
|
// We're rendering while bypassing caches,
|
|
356
546
|
// so we have no hope of showing a useful runtime stage.
|
|
357
547
|
// But we still want things like `params` to show up in devtools correctly,
|
|
358
548
|
// which relies on mechanisms we've set up for staged rendering,
|
|
359
549
|
// so we do a 2-task version (Static -> Dynamic) instead.
|
|
360
|
-
// We aren't doing any validation in this kind of render so we say there
|
|
361
|
-
// is not runtime prefetch regardless of whether there is or not
|
|
362
|
-
const hasRuntimePrefetch = false;
|
|
363
550
|
// We aren't filling caches so we don't need to abort this render, it'll
|
|
364
551
|
// stream in a single pass
|
|
365
|
-
const
|
|
366
|
-
|
|
552
|
+
const stageController = new _stagedrendering.StagedRenderingController(null, null, false // do not track sync IO (we don't have reliable stages)
|
|
553
|
+
);
|
|
367
554
|
const environmentName = ()=>{
|
|
368
555
|
const currentStage = stageController.currentStage;
|
|
369
556
|
switch(currentStage){
|
|
370
557
|
case _stagedrendering.RenderStage.Before:
|
|
558
|
+
case _stagedrendering.RenderStage.EarlyStatic:
|
|
371
559
|
case _stagedrendering.RenderStage.Static:
|
|
372
560
|
return 'Prerender';
|
|
561
|
+
case _stagedrendering.RenderStage.EarlyRuntime:
|
|
373
562
|
case _stagedrendering.RenderStage.Runtime:
|
|
374
563
|
case _stagedrendering.RenderStage.Dynamic:
|
|
375
564
|
case _stagedrendering.RenderStage.Abandoned:
|
|
@@ -384,12 +573,12 @@ async function stagedRenderToReadableStreamWithoutCachesInDev(ctx, requestStore,
|
|
|
384
573
|
}
|
|
385
574
|
};
|
|
386
575
|
requestStore.stagedRendering = stageController;
|
|
387
|
-
requestStore.asyncApiPromises =
|
|
576
|
+
requestStore.asyncApiPromises = createAsyncApiPromises(stageController, requestStore.cookies, requestStore.mutableCookies, requestStore.headers);
|
|
388
577
|
const { clientModules } = (0, _manifestssingleton.getClientReferenceManifest)();
|
|
389
578
|
const rscPayload = await getPayload(requestStore);
|
|
390
|
-
return await
|
|
579
|
+
return await (0, _apprenderrenderutils.runInSequentialTasks)(()=>{
|
|
391
580
|
stageController.advanceStage(_stagedrendering.RenderStage.Static);
|
|
392
|
-
return
|
|
581
|
+
return _workunitasyncstorageexternal.workUnitAsyncStorage.run(requestStore, _streamops.renderToFlightStream, ctx.componentMod, rscPayload, clientModules, {
|
|
393
582
|
...options,
|
|
394
583
|
environmentName
|
|
395
584
|
});
|
|
@@ -400,19 +589,20 @@ async function stagedRenderToReadableStreamWithoutCachesInDev(ctx, requestStore,
|
|
|
400
589
|
/**
|
|
401
590
|
* Fork of `generateDynamicFlightRenderResult` that renders using `renderWithRestartOnCacheMissInDev`
|
|
402
591
|
* to ensure correct separation of environments Prerender/Server (for use in Cache Components)
|
|
403
|
-
*/ async function generateDynamicFlightRenderResultWithStagesInDev(req, ctx, initialRequestStore, createRequestStore,
|
|
404
|
-
const { htmlRequestId, renderOpts, requestId, workStore, componentMod: { createElement }, url } = ctx;
|
|
405
|
-
const {
|
|
592
|
+
*/ async function generateDynamicFlightRenderResultWithStagesInDev(req, ctx, initialRequestStore, createRequestStore, fallbackParams) {
|
|
593
|
+
const { htmlRequestId, renderOpts, requestId, workStore, componentMod: { createElement, routeModule: { userland: { loaderTree } } }, url } = ctx;
|
|
594
|
+
const { onInstrumentationRequestError, setReactDebugChannel, setCacheStatus, isBuildTimePrerendering = false } = renderOpts;
|
|
406
595
|
function onFlightDataRenderError(err, silenceLog) {
|
|
407
596
|
return onInstrumentationRequestError == null ? void 0 : onInstrumentationRequestError(err, req, createErrorContext(ctx, 'react-server-components-payload'), silenceLog);
|
|
408
597
|
}
|
|
409
|
-
const onError = (0, _createerrorhandler.createReactServerErrorHandler)(
|
|
410
|
-
// We
|
|
411
|
-
//
|
|
412
|
-
|
|
598
|
+
const onError = (0, _createerrorhandler.createReactServerErrorHandler)(process.env.NODE_ENV === 'development', isBuildTimePrerendering, workStore.reactServerErrorsByDigest, onFlightDataRenderError);
|
|
599
|
+
// We validate RSC requests for HMR refreshes and client navigations when
|
|
600
|
+
// instant configs exist, since we render all the layouts necessary to perform
|
|
601
|
+
// the validation in those cases.
|
|
602
|
+
const shouldValidate = !isBypassingCachesInDev(initialRequestStore) && (initialRequestStore.isHmrRefresh === true || await (0, _instantconfig.anySegmentNeedsInstantValidationInDev)(loaderTree));
|
|
413
603
|
const getPayload = async (requestStore)=>{
|
|
414
604
|
const payload = await _workunitasyncstorageexternal.workUnitAsyncStorage.run(requestStore, generateDynamicRSCPayload, ctx, undefined);
|
|
415
|
-
if (isBypassingCachesInDev(
|
|
605
|
+
if (isBypassingCachesInDev(requestStore)) {
|
|
416
606
|
// Mark the RSC payload to indicate that caches were bypassed in dev.
|
|
417
607
|
// This lets the client know not to cache anything based on this render.
|
|
418
608
|
payload._bypassCachesInDev = createElement(WarnForBypassCachesInDev, {
|
|
@@ -431,13 +621,13 @@ async function stagedRenderToReadableStreamWithoutCachesInDev(ctx, requestStore,
|
|
|
431
621
|
// (which is not the case for renders after an action)
|
|
432
622
|
createRequestStore && // We only do this flow if we're not bypassing caches in dev using
|
|
433
623
|
// "disable cache" in devtools or a hard refresh (cache-control: "no-store")
|
|
434
|
-
!isBypassingCachesInDev(
|
|
624
|
+
!isBypassingCachesInDev(initialRequestStore)) {
|
|
435
625
|
// Before we kick off the render, we set the cache status back to it's initial state
|
|
436
626
|
// in case a previous render bypassed the cache.
|
|
437
627
|
if (setCacheStatus) {
|
|
438
628
|
setCacheStatus('ready', htmlRequestId);
|
|
439
629
|
}
|
|
440
|
-
const { stream: serverStream, accumulatedChunksPromise,
|
|
630
|
+
const { stream: serverStream, accumulatedChunksPromise, syncInterruptReason, startTime, staticStageEndTime, runtimeStageEndTime, debugChannel: returnedDebugChannel, requestStore: finalRequestStore } = await renderWithRestartOnCacheMissInDev(ctx, initialRequestStore, createRequestStore, getPayload, onError);
|
|
441
631
|
if (shouldValidate) {
|
|
442
632
|
let validationDebugChannelClient = undefined;
|
|
443
633
|
if (returnedDebugChannel) {
|
|
@@ -447,7 +637,9 @@ async function stagedRenderToReadableStreamWithoutCachesInDev(ctx, requestStore,
|
|
|
447
637
|
}
|
|
448
638
|
_consoleasyncstorageexternal.consoleAsyncStorage.run({
|
|
449
639
|
dim: true
|
|
450
|
-
}, spawnStaticShellValidationInDev, accumulatedChunksPromise,
|
|
640
|
+
}, spawnStaticShellValidationInDev, accumulatedChunksPromise, syncInterruptReason, startTime, staticStageEndTime, runtimeStageEndTime, ctx, finalRequestStore, fallbackParams, validationDebugChannelClient);
|
|
641
|
+
} else {
|
|
642
|
+
logValidationSkipped(ctx);
|
|
451
643
|
}
|
|
452
644
|
debugChannel = returnedDebugChannel;
|
|
453
645
|
stream = serverStream;
|
|
@@ -458,7 +650,7 @@ async function stagedRenderToReadableStreamWithoutCachesInDev(ctx, requestStore,
|
|
|
458
650
|
if (setCacheStatus) {
|
|
459
651
|
setCacheStatus('bypass', htmlRequestId);
|
|
460
652
|
}
|
|
461
|
-
debugChannel = setReactDebugChannel && createDebugChannel();
|
|
653
|
+
debugChannel = setReactDebugChannel && (0, _debugchannelserver.createDebugChannel)();
|
|
462
654
|
stream = await stagedRenderToReadableStreamWithoutCachesInDev(ctx, initialRequestStore, getPayload, {
|
|
463
655
|
onError: onError,
|
|
464
656
|
filterStackFrame,
|
|
@@ -474,19 +666,14 @@ async function stagedRenderToReadableStreamWithoutCachesInDev(ctx, requestStore,
|
|
|
474
666
|
}
|
|
475
667
|
async function generateRuntimePrefetchResult(req, ctx, requestStore) {
|
|
476
668
|
const { workStore, renderOpts } = ctx;
|
|
477
|
-
const {
|
|
669
|
+
const { isBuildTimePrerendering = false, onInstrumentationRequestError } = renderOpts;
|
|
478
670
|
function onFlightDataRenderError(err, silenceLog) {
|
|
479
671
|
return onInstrumentationRequestError == null ? void 0 : onInstrumentationRequestError(err, req, // TODO(runtime-ppr): should we use a different value?
|
|
480
672
|
createErrorContext(ctx, 'react-server-components-payload'), silenceLog);
|
|
481
673
|
}
|
|
482
|
-
const onError = (0, _createerrorhandler.createReactServerErrorHandler)(false,
|
|
674
|
+
const onError = (0, _createerrorhandler.createReactServerErrorHandler)(false, isBuildTimePrerendering, workStore.reactServerErrorsByDigest, onFlightDataRenderError);
|
|
483
675
|
const metadata = {};
|
|
484
|
-
|
|
485
|
-
// and later replaced by the transform stream
|
|
486
|
-
const runtimePrefetchSentinel = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
|
|
487
|
-
const generatePayload = ()=>generateDynamicRSCPayload(ctx, {
|
|
488
|
-
runtimePrefetchSentinel
|
|
489
|
-
});
|
|
676
|
+
const staleTimeIterable = new _staletime.StaleTimeIterable();
|
|
490
677
|
const { componentMod: { routeModule: { userland: { loaderTree } } }, getDynamicParamFromSegment } = ctx;
|
|
491
678
|
const rootParams = (0, _createcomponenttree.getRootParams)(loaderTree, getDynamicParamFromSegment);
|
|
492
679
|
// We need to share caches between the prospective prerender and the final prerender,
|
|
@@ -494,8 +681,10 @@ async function generateRuntimePrefetchResult(req, ctx, requestStore) {
|
|
|
494
681
|
const prerenderResumeDataCache = (0, _resumedatacache.createPrerenderResumeDataCache)();
|
|
495
682
|
// We're not resuming an existing render.
|
|
496
683
|
const renderResumeDataCache = null;
|
|
497
|
-
await prospectiveRuntimeServerPrerender(ctx,
|
|
498
|
-
const response = await finalRuntimeServerPrerender(ctx,
|
|
684
|
+
await prospectiveRuntimeServerPrerender(ctx, generateDynamicRSCPayload.bind(null, ctx), prerenderResumeDataCache, renderResumeDataCache, rootParams, requestStore.headers, requestStore.cookies, requestStore.draftMode);
|
|
685
|
+
const response = await finalRuntimeServerPrerender(ctx, generateDynamicRSCPayload.bind(null, ctx, {
|
|
686
|
+
staleTimeIterable
|
|
687
|
+
}), prerenderResumeDataCache, renderResumeDataCache, rootParams, requestStore.headers, requestStore.cookies, requestStore.draftMode, onError, staleTimeIterable);
|
|
499
688
|
applyMetadataFromPrerenderResult(response, metadata, workStore);
|
|
500
689
|
metadata.fetchMetrics = ctx.workStore.fetchMetrics;
|
|
501
690
|
return new _flightrenderresult.FlightRenderResult(response.result.prelude, metadata);
|
|
@@ -539,8 +728,10 @@ async function prospectiveRuntimeServerPrerender(ctx, getPayload, prerenderResum
|
|
|
539
728
|
renderResumeDataCache,
|
|
540
729
|
prerenderResumeDataCache,
|
|
541
730
|
hmrRefreshHash: undefined,
|
|
542
|
-
// We
|
|
543
|
-
|
|
731
|
+
// We don't track vary params during initial prerender, only the final one
|
|
732
|
+
varyParamsAccumulator: null,
|
|
733
|
+
// No stage sequencing needed for prospective renders.
|
|
734
|
+
stagedRendering: null,
|
|
544
735
|
// These are not present in regular prerenders, but allowed in a runtime prerender.
|
|
545
736
|
headers,
|
|
546
737
|
cookies,
|
|
@@ -550,7 +741,7 @@ async function prospectiveRuntimeServerPrerender(ctx, getPayload, prerenderResum
|
|
|
550
741
|
// We're not going to use the result of this render because the only time it could be used
|
|
551
742
|
// is if it completes in a microtask and that's likely very rare for any non-trivial app
|
|
552
743
|
const initialServerPayload = await _workunitasyncstorageexternal.workUnitAsyncStorage.run(initialServerPrerenderStore, getPayload);
|
|
553
|
-
const
|
|
744
|
+
const prerenderOptions = {
|
|
554
745
|
filterStackFrame,
|
|
555
746
|
onError: (err)=>{
|
|
556
747
|
const digest = (0, _createerrorhandler.getDigestForWellKnownError)(err);
|
|
@@ -569,7 +760,8 @@ async function prospectiveRuntimeServerPrerender(ctx, getPayload, prerenderResum
|
|
|
569
760
|
// a different signal to this render call than is used by dynamic APIs to signify
|
|
570
761
|
// transitioning out of the prerender environment
|
|
571
762
|
signal: initialServerRenderController.signal
|
|
572
|
-
}
|
|
763
|
+
};
|
|
764
|
+
const pendingInitialServerResult = _workunitasyncstorageexternal.workUnitAsyncStorage.run(initialServerPrerenderStore, (0, _streamops.getServerPrerender)(ComponentMod), initialServerPayload, clientModules, prerenderOptions);
|
|
573
765
|
// Wait for all caches to be finished filling and for async imports to resolve
|
|
574
766
|
(0, _trackmoduleloadingexternal.trackPendingModules)(cacheSignal);
|
|
575
767
|
await cacheSignal.cacheReady();
|
|
@@ -594,101 +786,29 @@ async function prospectiveRuntimeServerPrerender(ctx, getPayload, prerenderResum
|
|
|
594
786
|
}
|
|
595
787
|
}
|
|
596
788
|
/**
|
|
597
|
-
*
|
|
598
|
-
*
|
|
599
|
-
*
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
const first = search[0];
|
|
608
|
-
const replace = encoder.encode(`[${isPartial},${staleTime}]`);
|
|
609
|
-
const searchLen = search.length;
|
|
610
|
-
let currentChunk = null;
|
|
611
|
-
let found = false;
|
|
612
|
-
function processChunk(controller, nextChunk) {
|
|
613
|
-
if (found) {
|
|
614
|
-
if (nextChunk) {
|
|
615
|
-
controller.enqueue(nextChunk);
|
|
616
|
-
}
|
|
617
|
-
return;
|
|
618
|
-
}
|
|
619
|
-
if (currentChunk) {
|
|
620
|
-
// We can't search past the index that can contain a full match
|
|
621
|
-
let exclusiveUpperBound = currentChunk.length - (searchLen - 1);
|
|
622
|
-
if (nextChunk) {
|
|
623
|
-
// If we have any overflow bytes we can search up to the chunk's final byte
|
|
624
|
-
exclusiveUpperBound += Math.min(nextChunk.length, searchLen - 1);
|
|
625
|
-
}
|
|
626
|
-
if (exclusiveUpperBound < 1) {
|
|
627
|
-
// we can't match the current chunk.
|
|
628
|
-
controller.enqueue(currentChunk);
|
|
629
|
-
currentChunk = nextChunk // advance so we don't process this chunk again
|
|
630
|
-
;
|
|
631
|
-
return;
|
|
632
|
-
}
|
|
633
|
-
let currentIndex = currentChunk.indexOf(first);
|
|
634
|
-
// check the current candidate match if it is within the bounds of our search space for the currentChunk
|
|
635
|
-
candidateLoop: while(-1 < currentIndex && currentIndex < exclusiveUpperBound){
|
|
636
|
-
// We already know index 0 matches because we used indexOf to find the candidateIndex so we start at index 1
|
|
637
|
-
let matchIndex = 1;
|
|
638
|
-
while(matchIndex < searchLen){
|
|
639
|
-
const candidateIndex = currentIndex + matchIndex;
|
|
640
|
-
const candidateValue = candidateIndex < currentChunk.length ? currentChunk[candidateIndex] : nextChunk[candidateIndex - currentChunk.length];
|
|
641
|
-
if (candidateValue !== search[matchIndex]) {
|
|
642
|
-
// No match, reset and continue the search from the next position
|
|
643
|
-
currentIndex = currentChunk.indexOf(first, currentIndex + 1);
|
|
644
|
-
continue candidateLoop;
|
|
645
|
-
}
|
|
646
|
-
matchIndex++;
|
|
647
|
-
}
|
|
648
|
-
// We found a complete match. currentIndex is our starting point to replace the value.
|
|
649
|
-
found = true;
|
|
650
|
-
// enqueue everything up to the match
|
|
651
|
-
controller.enqueue(currentChunk.subarray(0, currentIndex));
|
|
652
|
-
// enqueue the replacement value
|
|
653
|
-
controller.enqueue(replace);
|
|
654
|
-
// If there are bytes in the currentChunk after the match enqueue them
|
|
655
|
-
if (currentIndex + searchLen < currentChunk.length) {
|
|
656
|
-
controller.enqueue(currentChunk.slice(currentIndex + searchLen));
|
|
657
|
-
}
|
|
658
|
-
// If we have a next chunk we enqueue it now
|
|
659
|
-
if (nextChunk) {
|
|
660
|
-
// if replacement spills over to the next chunk we first exclude the replaced bytes
|
|
661
|
-
const overflowBytes = currentIndex + searchLen - currentChunk.length;
|
|
662
|
-
const truncatedChunk = overflowBytes > 0 ? nextChunk.subarray(overflowBytes) : nextChunk;
|
|
663
|
-
controller.enqueue(truncatedChunk);
|
|
664
|
-
}
|
|
665
|
-
// We are now in found mode and don't need to track currentChunk anymore
|
|
666
|
-
currentChunk = null;
|
|
667
|
-
return;
|
|
668
|
-
}
|
|
669
|
-
// No match found in this chunk, emit it and wait for the next one
|
|
670
|
-
controller.enqueue(currentChunk);
|
|
671
|
-
}
|
|
672
|
-
// Advance to the next chunk
|
|
673
|
-
currentChunk = nextChunk;
|
|
674
|
-
}
|
|
675
|
-
return new TransformStream({
|
|
676
|
-
transform (chunk, controller) {
|
|
677
|
-
processChunk(controller, chunk);
|
|
678
|
-
},
|
|
679
|
-
flush (controller) {
|
|
680
|
-
processChunk(controller, null);
|
|
789
|
+
* Prepends a single ASCII byte to the stream indicating whether the response
|
|
790
|
+
* is partial (contains dynamic holes): '~' (0x7e) for partial, '#' (0x23)
|
|
791
|
+
* for complete.
|
|
792
|
+
*/ function prependIsPartialByte(stream, isPartial) {
|
|
793
|
+
const byte = new Uint8Array([
|
|
794
|
+
isPartial ? 0x7e : 0x23
|
|
795
|
+
]);
|
|
796
|
+
return stream.pipeThrough(new TransformStream({
|
|
797
|
+
start (controller) {
|
|
798
|
+
controller.enqueue(byte);
|
|
681
799
|
}
|
|
682
|
-
});
|
|
800
|
+
}));
|
|
683
801
|
}
|
|
684
|
-
async function finalRuntimeServerPrerender(ctx, getPayload, prerenderResumeDataCache, renderResumeDataCache, rootParams, headers, cookies, draftMode, onError,
|
|
802
|
+
async function finalRuntimeServerPrerender(ctx, getPayload, prerenderResumeDataCache, renderResumeDataCache, rootParams, headers, cookies, draftMode, onError, staleTimeIterable) {
|
|
685
803
|
const { implicitTags, renderOpts } = ctx;
|
|
686
804
|
const { ComponentMod, experimental, isDebugDynamicAccesses } = renderOpts;
|
|
687
|
-
const selectStaleTime = createSelectStaleTime(experimental);
|
|
805
|
+
const selectStaleTime = (0, _staletime.createSelectStaleTime)(experimental);
|
|
688
806
|
let serverIsDynamic = false;
|
|
689
807
|
const finalServerController = new AbortController();
|
|
690
808
|
const serverDynamicTracking = (0, _dynamicrendering.createDynamicTrackingState)(isDebugDynamicAccesses);
|
|
691
|
-
const
|
|
809
|
+
const finalStageController = new _stagedrendering.StagedRenderingController(finalServerController.signal, null, true // track sync IO
|
|
810
|
+
);
|
|
811
|
+
const varyParamsAccumulator = (0, _varyparams.createResponseVaryParamsAccumulator)();
|
|
692
812
|
const finalServerPrerenderStore = {
|
|
693
813
|
type: 'prerender-runtime',
|
|
694
814
|
phase: 'render',
|
|
@@ -710,19 +830,24 @@ async function finalRuntimeServerPrerender(ctx, getPayload, prerenderResumeDataC
|
|
|
710
830
|
prerenderResumeDataCache,
|
|
711
831
|
renderResumeDataCache,
|
|
712
832
|
hmrRefreshHash: undefined,
|
|
713
|
-
|
|
714
|
-
|
|
833
|
+
varyParamsAccumulator,
|
|
834
|
+
// Used to separate the stages in the 5-task pipeline.
|
|
835
|
+
stagedRendering: finalStageController,
|
|
715
836
|
// These are not present in regular prerenders, but allowed in a runtime prerender.
|
|
716
837
|
headers,
|
|
717
838
|
cookies,
|
|
718
839
|
draftMode
|
|
719
840
|
};
|
|
841
|
+
(0, _staletime.trackStaleTime)(finalServerPrerenderStore, staleTimeIterable, selectStaleTime);
|
|
720
842
|
const { clientModules } = (0, _manifestssingleton.getClientReferenceManifest)();
|
|
721
843
|
const finalRSCPayload = await _workunitasyncstorageexternal.workUnitAsyncStorage.run(finalServerPrerenderStore, getPayload);
|
|
722
844
|
let prerenderIsPending = true;
|
|
723
|
-
const result = await (0,
|
|
724
|
-
//
|
|
725
|
-
|
|
845
|
+
const result = await (0, _apprenderrenderutils.runInSequentialTasks)(async ()=>{
|
|
846
|
+
// EarlyStatic stage: render begins.
|
|
847
|
+
// Runtime-prefetchable segments render immediately.
|
|
848
|
+
// Non-prefetchable segments are gated until the Static stage.
|
|
849
|
+
finalStageController.advanceStage(_stagedrendering.RenderStage.EarlyStatic);
|
|
850
|
+
const prerenderResult = await _workunitasyncstorageexternal.workUnitAsyncStorage.run(finalServerPrerenderStore, (0, _streamops.getServerPrerender)(ComponentMod), finalRSCPayload, clientModules, {
|
|
726
851
|
filterStackFrame,
|
|
727
852
|
onError,
|
|
728
853
|
signal: finalServerController.signal
|
|
@@ -730,33 +855,41 @@ async function finalRuntimeServerPrerender(ctx, getPayload, prerenderResumeDataC
|
|
|
730
855
|
prerenderIsPending = false;
|
|
731
856
|
return prerenderResult;
|
|
732
857
|
}, ()=>{
|
|
733
|
-
// Advance to
|
|
734
|
-
//
|
|
735
|
-
|
|
736
|
-
// This makes sure that, at this point, we'll have finished all the static parts (what we'd prerender statically).
|
|
737
|
-
// We know that they don't contain any incorrect sync IO, because that'd have caused a build error.
|
|
738
|
-
// After we unblock Runtime APIs, if we encounter sync IO (e.g. `await cookies(); Date.now()`),
|
|
739
|
-
// we'll abort, but we'll produce at least as much output as a static prerender would.
|
|
740
|
-
resolveBlockedRuntimeAPIs();
|
|
858
|
+
// Advance to Static stage: resolve promise holding back
|
|
859
|
+
// non-prefetchable segments so they can begin rendering.
|
|
860
|
+
finalStageController.advanceStage(_stagedrendering.RenderStage.Static);
|
|
741
861
|
}, ()=>{
|
|
742
|
-
//
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
862
|
+
// Advance to EarlyRuntime stage: resolve cookies/headers for
|
|
863
|
+
// runtime-prefetchable segments. Sync IO is checked here.
|
|
864
|
+
finalStageController.advanceStage(_stagedrendering.RenderStage.EarlyRuntime);
|
|
865
|
+
}, ()=>{
|
|
866
|
+
// Advance to Runtime stage: resolve cookies/headers for
|
|
867
|
+
// non-prefetchable segments. Sync IO is allowed here.
|
|
868
|
+
finalStageController.advanceStage(_stagedrendering.RenderStage.Runtime);
|
|
869
|
+
}, ()=>{
|
|
870
|
+
Promise.all([
|
|
871
|
+
(0, _staletime.finishStaleTimeTracking)(staleTimeIterable),
|
|
872
|
+
(0, _varyparams.finishAccumulatingVaryParams)(varyParamsAccumulator)
|
|
873
|
+
]).then(()=>{
|
|
874
|
+
// Abort. This runs as a microtask after Flight has flushed the
|
|
875
|
+
// staleTime and varyParams closing chunks, but before the next
|
|
876
|
+
// macrotask resolves the overall result.
|
|
877
|
+
if (finalServerController.signal.aborted) {
|
|
878
|
+
// If the server controller is already aborted we must have called
|
|
879
|
+
// something that required aborting the prerender synchronously such
|
|
880
|
+
// as with new Date()
|
|
881
|
+
serverIsDynamic = true;
|
|
882
|
+
return;
|
|
883
|
+
}
|
|
884
|
+
if (prerenderIsPending) {
|
|
885
|
+
// If prerenderIsPending then we have blocked for longer than a Task
|
|
886
|
+
// and we assume there is something unfinished.
|
|
887
|
+
serverIsDynamic = true;
|
|
888
|
+
}
|
|
889
|
+
finalServerController.abort();
|
|
890
|
+
});
|
|
755
891
|
});
|
|
756
|
-
|
|
757
|
-
// React has already serialized the payload with the sentinel, so we need to transform the stream.
|
|
758
|
-
const collectedStale = selectStaleTime(finalServerPrerenderStore.stale);
|
|
759
|
-
result.prelude = result.prelude.pipeThrough(createRuntimePrefetchTransformStream(runtimePrefetchSentinel, serverIsDynamic, collectedStale));
|
|
892
|
+
result.prelude = prependIsPartialByte(result.prelude, serverIsDynamic);
|
|
760
893
|
return {
|
|
761
894
|
result,
|
|
762
895
|
// TODO(runtime-ppr): do we need to produce a digest map here?
|
|
@@ -765,7 +898,7 @@ async function finalRuntimeServerPrerender(ctx, getPayload, prerenderResumeDataC
|
|
|
765
898
|
isPartial: serverIsDynamic,
|
|
766
899
|
collectedRevalidate: finalServerPrerenderStore.revalidate,
|
|
767
900
|
collectedExpire: finalServerPrerenderStore.expire,
|
|
768
|
-
collectedStale,
|
|
901
|
+
collectedStale: staleTimeIterable.currentValue,
|
|
769
902
|
collectedTags: finalServerPrerenderStore.tags
|
|
770
903
|
};
|
|
771
904
|
}
|
|
@@ -805,19 +938,23 @@ function getRenderedSearch(query) {
|
|
|
805
938
|
return '?' + pairs.join('&');
|
|
806
939
|
}
|
|
807
940
|
// This is the data necessary to render <AppRouter /> when no SSR errors are encountered
|
|
808
|
-
async function getRSCPayload(tree, ctx,
|
|
941
|
+
async function getRSCPayload(tree, ctx, options) {
|
|
942
|
+
var _ctx_renderOpts_prefetchHints;
|
|
943
|
+
const { is404, staleTimeIterable, staticStageByteLengthPromise, runtimePrefetchStream } = options;
|
|
809
944
|
const injectedCSS = new Set();
|
|
810
945
|
const injectedJS = new Set();
|
|
811
946
|
const injectedFontPreloadTags = new Set();
|
|
812
947
|
let missingSlots;
|
|
813
948
|
// We only track missing parallel slots in development
|
|
814
|
-
if (process.env.
|
|
949
|
+
if (process.env.__NEXT_DEV_SERVER) {
|
|
815
950
|
missingSlots = new Set();
|
|
816
951
|
}
|
|
817
952
|
const { getDynamicParamFromSegment, query, appUsingSizeAdjustment, componentMod: { createMetadataComponents, createElement, Fragment }, url, workStore } = ctx;
|
|
818
|
-
const
|
|
953
|
+
const hints = ((_ctx_renderOpts_prefetchHints = ctx.renderOpts.prefetchHints) == null ? void 0 : _ctx_renderOpts_prefetchHints[ctx.pagePath]) ?? null;
|
|
954
|
+
const initialTree = await (0, _createflightrouterstatefromloadertree.createFlightRouterStateFromLoaderTree)(tree, hints, getDynamicParamFromSegment, query);
|
|
819
955
|
const serveStreamingMetadata = !!ctx.renderOpts.serveStreamingMetadata;
|
|
820
956
|
const hasGlobalNotFound = !!tree[2]['global-not-found'];
|
|
957
|
+
const metadataIsRuntimePrefetchable = await (0, _instantconfig.anySegmentHasRuntimePrefetchEnabled)(tree);
|
|
821
958
|
const { Viewport, Metadata, MetadataOutlet } = createMetadataComponents({
|
|
822
959
|
tree,
|
|
823
960
|
// When it's using global-not-found, metadata errorType is undefined, which will retrieve the
|
|
@@ -829,15 +966,17 @@ async function getRSCPayload(tree, ctx, is404) {
|
|
|
829
966
|
parsedQuery: query,
|
|
830
967
|
pathname: url.pathname,
|
|
831
968
|
metadataContext: (0, _metadatacontext.createMetadataContext)(ctx.renderOpts),
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
969
|
+
interpolatedParams: ctx.interpolatedParams,
|
|
970
|
+
serveStreamingMetadata,
|
|
971
|
+
isRuntimePrefetchable: metadataIsRuntimePrefetchable
|
|
835
972
|
});
|
|
836
973
|
const preloadCallbacks = [];
|
|
837
974
|
const seedData = await (0, _createcomponenttree.createComponentTree)({
|
|
838
975
|
ctx,
|
|
839
976
|
loaderTree: tree,
|
|
840
977
|
parentParams: {},
|
|
978
|
+
parentOptionalCatchAllParamName: null,
|
|
979
|
+
parentRuntimePrefetchable: false,
|
|
841
980
|
injectedCSS,
|
|
842
981
|
injectedJS,
|
|
843
982
|
injectedFontPreloadTags,
|
|
@@ -850,8 +989,11 @@ async function getRSCPayload(tree, ctx, is404) {
|
|
|
850
989
|
// When the `vary` response header is present with `Next-URL`, that means there's a chance
|
|
851
990
|
// it could respond differently if there's an interception route. We provide this information
|
|
852
991
|
// to `AppRouter` so that it can properly seed the prefetch cache with a prefix, if needed.
|
|
992
|
+
// In dev, the Vary header may not reliably reflect whether a route can
|
|
993
|
+
// be intercepted, because interception routes are compiled on demand.
|
|
994
|
+
// Default to true so the client doesn't cache a stale Fallback entry.
|
|
853
995
|
const varyHeader = ctx.res.getHeader('vary');
|
|
854
|
-
const couldBeIntercepted = typeof varyHeader === 'string' && varyHeader.includes(_approuterheaders.NEXT_URL);
|
|
996
|
+
const couldBeIntercepted = !!process.env.__NEXT_DEV_SERVER || typeof varyHeader === 'string' && varyHeader.includes(_approuterheaders.NEXT_URL);
|
|
855
997
|
const initialHead = createElement(Fragment, {
|
|
856
998
|
key: flightDataPathHeadKey
|
|
857
999
|
}, createElement(NonIndex, {
|
|
@@ -871,12 +1013,11 @@ async function getRSCPayload(tree, ctx, is404) {
|
|
|
871
1013
|
//
|
|
872
1014
|
// See similar comment in create-component-tree.tsx for more context.
|
|
873
1015
|
const isPossiblyPartialHead = workStore.isStaticGeneration && ctx.renderOpts.experimental.isRoutePPREnabled === true;
|
|
874
|
-
return {
|
|
1016
|
+
return maybeAppendBuildIdToRSCPayload(ctx, {
|
|
875
1017
|
// See the comment above the `Preloads` component (below) for why this is part of the payload
|
|
876
1018
|
P: createElement(Preloads, {
|
|
877
1019
|
preloadCallbacks: preloadCallbacks
|
|
878
1020
|
}),
|
|
879
|
-
b: ctx.sharedContext.buildId,
|
|
880
1021
|
c: prepareInitialCanonicalUrl(url),
|
|
881
1022
|
q: getRenderedSearch(query),
|
|
882
1023
|
i: !!couldBeIntercepted,
|
|
@@ -893,8 +1034,22 @@ async function getRSCPayload(tree, ctx, is404) {
|
|
|
893
1034
|
GlobalError,
|
|
894
1035
|
globalErrorStyles
|
|
895
1036
|
],
|
|
896
|
-
|
|
897
|
-
|
|
1037
|
+
// Tells the client whether this route supports per-segment prefetching.
|
|
1038
|
+
// With Cache Components, all routes support it. Without it, only fully
|
|
1039
|
+
// static pages do, because their per-segment prefetch responses are
|
|
1040
|
+
// generated during static generation (build or ISR).
|
|
1041
|
+
S: workStore.isStaticGeneration || ctx.renderOpts.cacheComponents,
|
|
1042
|
+
h: (0, _varyparams.getMetadataVaryParamsThenable)(),
|
|
1043
|
+
s: staleTimeIterable,
|
|
1044
|
+
l: staticStageByteLengthPromise,
|
|
1045
|
+
p: runtimePrefetchStream,
|
|
1046
|
+
// Include the per-page dynamic stale time from unstable_dynamicStaleTime, but
|
|
1047
|
+
// only for dynamic renders. The client treats its presence as
|
|
1048
|
+
// authoritative.
|
|
1049
|
+
// TODO: Move this to the prefetch hints file so we don't have to walk
|
|
1050
|
+
// the tree on every render.
|
|
1051
|
+
d: !workStore.isStaticGeneration ? await getDynamicStaleTime(tree) ?? undefined : undefined
|
|
1052
|
+
});
|
|
898
1053
|
}
|
|
899
1054
|
/**
|
|
900
1055
|
* Preload calls (such as `ReactDOM.preloadStyle` and `ReactDOM.preloadFont`) need to be called during rendering
|
|
@@ -907,17 +1062,19 @@ async function getRSCPayload(tree, ctx, is404) {
|
|
|
907
1062
|
}
|
|
908
1063
|
// This is the data necessary to render <AppRouter /> when an error state is triggered
|
|
909
1064
|
async function getErrorRSCPayload(tree, ctx, ssrError, errorType) {
|
|
1065
|
+
var _ctx_renderOpts_prefetchHints;
|
|
910
1066
|
const { getDynamicParamFromSegment, query, componentMod: { createMetadataComponents, createElement, Fragment }, url, workStore } = ctx;
|
|
911
1067
|
const serveStreamingMetadata = !!ctx.renderOpts.serveStreamingMetadata;
|
|
1068
|
+
const metadataIsRuntimePrefetchable = await (0, _instantconfig.anySegmentHasRuntimePrefetchEnabled)(tree);
|
|
912
1069
|
const { Viewport, Metadata } = createMetadataComponents({
|
|
913
1070
|
tree,
|
|
914
1071
|
parsedQuery: query,
|
|
915
1072
|
pathname: url.pathname,
|
|
916
1073
|
metadataContext: (0, _metadatacontext.createMetadataContext)(ctx.renderOpts),
|
|
917
1074
|
errorType,
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
1075
|
+
interpolatedParams: ctx.interpolatedParams,
|
|
1076
|
+
serveStreamingMetadata: serveStreamingMetadata,
|
|
1077
|
+
isRuntimePrefetchable: metadataIsRuntimePrefetchable
|
|
921
1078
|
});
|
|
922
1079
|
const initialHead = createElement(Fragment, {
|
|
923
1080
|
key: flightDataPathHeadKey
|
|
@@ -926,11 +1083,12 @@ async function getErrorRSCPayload(tree, ctx, ssrError, errorType) {
|
|
|
926
1083
|
pagePath: ctx.pagePath,
|
|
927
1084
|
statusCode: ctx.res.statusCode,
|
|
928
1085
|
isPossibleServerAction: ctx.isPossibleServerAction
|
|
929
|
-
}), createElement(Viewport, null), process.env.
|
|
1086
|
+
}), createElement(Viewport, null), process.env.__NEXT_DEV_SERVER && createElement('meta', {
|
|
930
1087
|
name: 'next-error',
|
|
931
1088
|
content: 'not-found'
|
|
932
1089
|
}), createElement(Metadata, null));
|
|
933
|
-
const
|
|
1090
|
+
const errorHints = ((_ctx_renderOpts_prefetchHints = ctx.renderOpts.prefetchHints) == null ? void 0 : _ctx_renderOpts_prefetchHints[ctx.pagePath]) ?? null;
|
|
1091
|
+
const initialTree = await (0, _createflightrouterstatefromloadertree.createFlightRouterStateFromLoaderTree)(tree, errorHints, getDynamicParamFromSegment, query);
|
|
934
1092
|
let err = undefined;
|
|
935
1093
|
if (ssrError) {
|
|
936
1094
|
err = (0, _iserror.default)(ssrError) ? ssrError : Object.defineProperty(new Error(ssrError + ''), "__NEXT_ERROR_CODE", {
|
|
@@ -944,7 +1102,7 @@ async function getErrorRSCPayload(tree, ctx, ssrError, errorType) {
|
|
|
944
1102
|
const seedData = [
|
|
945
1103
|
createElement('html', {
|
|
946
1104
|
id: '__next_error__'
|
|
947
|
-
}, createElement('head', null), createElement('body', null, process.env.
|
|
1105
|
+
}, createElement('head', null), createElement('body', null, process.env.__NEXT_DEV_SERVER && err ? createElement('template', {
|
|
948
1106
|
'data-next-error-message': err.message,
|
|
949
1107
|
'data-next-error-digest': 'digest' in err ? err.digest : '',
|
|
950
1108
|
'data-next-error-stack': err.stack
|
|
@@ -952,12 +1110,11 @@ async function getErrorRSCPayload(tree, ctx, ssrError, errorType) {
|
|
|
952
1110
|
{},
|
|
953
1111
|
null,
|
|
954
1112
|
false,
|
|
955
|
-
|
|
1113
|
+
null
|
|
956
1114
|
];
|
|
957
1115
|
const { GlobalError, styles: globalErrorStyles } = await getGlobalErrorStyles(tree, ctx);
|
|
958
1116
|
const isPossiblyPartialHead = workStore.isStaticGeneration && ctx.renderOpts.experimental.isRoutePPREnabled === true;
|
|
959
|
-
return {
|
|
960
|
-
b: ctx.sharedContext.buildId,
|
|
1117
|
+
return maybeAppendBuildIdToRSCPayload(ctx, {
|
|
961
1118
|
c: prepareInitialCanonicalUrl(url),
|
|
962
1119
|
q: getRenderedSearch(query),
|
|
963
1120
|
m: undefined,
|
|
@@ -974,8 +1131,13 @@ async function getErrorRSCPayload(tree, ctx, ssrError, errorType) {
|
|
|
974
1131
|
GlobalError,
|
|
975
1132
|
globalErrorStyles
|
|
976
1133
|
],
|
|
977
|
-
|
|
978
|
-
|
|
1134
|
+
// Tells the client whether this route supports per-segment prefetching.
|
|
1135
|
+
// With Cache Components, all routes support it. Without it, only fully
|
|
1136
|
+
// static pages do, because their per-segment prefetch responses are
|
|
1137
|
+
// generated during static generation (build or ISR).
|
|
1138
|
+
S: workStore.isStaticGeneration || ctx.renderOpts.cacheComponents,
|
|
1139
|
+
h: (0, _varyparams.getMetadataVaryParamsThenable)()
|
|
1140
|
+
});
|
|
979
1141
|
}
|
|
980
1142
|
// This component must run in an SSR context. It will render the RSC root component
|
|
981
1143
|
function App({ reactServerStream, reactDebugStream, debugEndTime, preinitScripts, ServerInsertedHTMLProvider, nonce, images }) {
|
|
@@ -985,9 +1147,7 @@ function App({ reactServerStream, reactDebugStream, debugEndTime, preinitScripts
|
|
|
985
1147
|
// This is not used during hydration, so we don't have to pass a
|
|
986
1148
|
// real timestamp.
|
|
987
1149
|
navigatedAt: -1,
|
|
988
|
-
|
|
989
|
-
initialCanonicalUrlParts: response.c,
|
|
990
|
-
initialRenderedSearch: response.q,
|
|
1150
|
+
initialRSCPayload: response,
|
|
991
1151
|
// location is not initialized in the SSR render
|
|
992
1152
|
// it's set to window.location during hydration
|
|
993
1153
|
location: null
|
|
@@ -1020,9 +1180,7 @@ function ErrorApp({ reactServerStream, preinitScripts, ServerInsertedHTMLProvide
|
|
|
1020
1180
|
// This is not used during hydration, so we don't have to pass a
|
|
1021
1181
|
// real timestamp.
|
|
1022
1182
|
navigatedAt: -1,
|
|
1023
|
-
|
|
1024
|
-
initialCanonicalUrlParts: response.c,
|
|
1025
|
-
initialRenderedSearch: response.q,
|
|
1183
|
+
initialRSCPayload: response,
|
|
1026
1184
|
// location is not initialized in the SSR render
|
|
1027
1185
|
// it's set to window.location during hydration
|
|
1028
1186
|
location: null
|
|
@@ -1048,7 +1206,8 @@ async function renderToHTMLOrFlightImpl(req, res, url, pagePath, query, renderOp
|
|
|
1048
1206
|
// avoid that resources can be deduped by React Float if the same resource is
|
|
1049
1207
|
// rendered or preloaded multiple times: `<link href="a.css?v={Date.now()}"/>`.
|
|
1050
1208
|
const requestTimestamp = Date.now();
|
|
1051
|
-
const { ComponentMod, nextFontManifest, serverActions, assetPrefix = '', enableTainting, cacheComponents } = renderOpts;
|
|
1209
|
+
const { ComponentMod, nextFontManifest, serverActions, assetPrefix = '', enableTainting, cacheComponents, setIsrStatus } = renderOpts;
|
|
1210
|
+
const { cachedNavigations } = renderOpts.experimental;
|
|
1052
1211
|
// We need to expose the bundled `require` API globally for
|
|
1053
1212
|
// react-server-dom-webpack. This is a hack until we find a better way.
|
|
1054
1213
|
if (ComponentMod.__next_app__) {
|
|
@@ -1061,7 +1220,7 @@ async function renderToHTMLOrFlightImpl(req, res, url, pagePath, query, renderOp
|
|
|
1061
1220
|
if (!cacheComponents) {
|
|
1062
1221
|
return false;
|
|
1063
1222
|
}
|
|
1064
|
-
if (
|
|
1223
|
+
if (process.env.__NEXT_DEV_SERVER) {
|
|
1065
1224
|
return true;
|
|
1066
1225
|
}
|
|
1067
1226
|
const workUnitStore = _workunitasyncstorageexternal.workUnitAsyncStorage.getStore();
|
|
@@ -1071,6 +1230,7 @@ async function renderToHTMLOrFlightImpl(req, res, url, pagePath, query, renderOp
|
|
|
1071
1230
|
switch(workUnitStore.type){
|
|
1072
1231
|
case 'prerender':
|
|
1073
1232
|
case 'prerender-client':
|
|
1233
|
+
case 'validation-client':
|
|
1074
1234
|
case 'prerender-runtime':
|
|
1075
1235
|
case 'cache':
|
|
1076
1236
|
case 'private-cache':
|
|
@@ -1079,6 +1239,7 @@ async function renderToHTMLOrFlightImpl(req, res, url, pagePath, query, renderOp
|
|
|
1079
1239
|
case 'prerender-legacy':
|
|
1080
1240
|
case 'request':
|
|
1081
1241
|
case 'unstable-cache':
|
|
1242
|
+
case 'generate-static-params':
|
|
1082
1243
|
return false;
|
|
1083
1244
|
default:
|
|
1084
1245
|
workUnitStore;
|
|
@@ -1104,10 +1265,10 @@ async function renderToHTMLOrFlightImpl(req, res, url, pagePath, query, renderOp
|
|
|
1104
1265
|
// @ts-expect-error
|
|
1105
1266
|
globalThis.__next_chunk_load__ = __next_chunk_load__;
|
|
1106
1267
|
}
|
|
1107
|
-
if (process.env.
|
|
1268
|
+
if (process.env.__NEXT_DEV_SERVER && setIsrStatus && !cacheComponents) {
|
|
1108
1269
|
// Reset the ISR status at start of request.
|
|
1109
1270
|
const { pathname } = new URL(req.url || '/', 'http://n');
|
|
1110
|
-
|
|
1271
|
+
setIsrStatus(pathname, // Only pages using the Node runtime can use ISR, Edge is always dynamic.
|
|
1111
1272
|
process.env.NEXT_RUNTIME === 'edge' ? false : undefined);
|
|
1112
1273
|
}
|
|
1113
1274
|
if (// The type check here ensures that `req` is correctly typed, and the
|
|
@@ -1175,9 +1336,19 @@ async function renderToHTMLOrFlightImpl(req, res, url, pagePath, query, renderOp
|
|
|
1175
1336
|
// is the request for the HTML document, so we use the request ID also as the
|
|
1176
1337
|
// HTML request ID.
|
|
1177
1338
|
htmlRequestId = parsedRequestHeaders.htmlRequestId || requestId;
|
|
1178
|
-
const getDynamicParamFromSegment = makeGetDynamicParamFromSegment(interpolatedParams, fallbackRouteParams);
|
|
1339
|
+
const getDynamicParamFromSegment = makeGetDynamicParamFromSegment(interpolatedParams, fallbackRouteParams, renderOpts.experimental.optimisticRouting);
|
|
1179
1340
|
const isPossibleActionRequest = (0, _serveractionrequestmeta.getIsPossibleServerAction)(req);
|
|
1180
|
-
|
|
1341
|
+
// For implicit tags, we use the resolved pathname which has dynamic params
|
|
1342
|
+
// interpolated, is decoded, and has trailing slash removed.
|
|
1343
|
+
const resolvedPathname = (0, _requestmeta.getRequestMeta)(req, 'resolvedPathname');
|
|
1344
|
+
if (!resolvedPathname) {
|
|
1345
|
+
throw Object.defineProperty(new _invarianterror.InvariantError('resolvedPathname must be set in request metadata'), "__NEXT_ERROR_CODE", {
|
|
1346
|
+
value: "E981",
|
|
1347
|
+
enumerable: false,
|
|
1348
|
+
configurable: true
|
|
1349
|
+
});
|
|
1350
|
+
}
|
|
1351
|
+
const implicitTags = await (0, _implicittags.getImplicitTags)(workStore.page, resolvedPathname, fallbackRouteParams);
|
|
1181
1352
|
const ctx = {
|
|
1182
1353
|
componentMod: ComponentMod,
|
|
1183
1354
|
url,
|
|
@@ -1185,6 +1356,7 @@ async function renderToHTMLOrFlightImpl(req, res, url, pagePath, query, renderOp
|
|
|
1185
1356
|
workStore,
|
|
1186
1357
|
parsedRequestHeaders,
|
|
1187
1358
|
getDynamicParamFromSegment,
|
|
1359
|
+
interpolatedParams,
|
|
1188
1360
|
query,
|
|
1189
1361
|
isPrefetch: isPrefetchRequest,
|
|
1190
1362
|
isPossibleServerAction: isPossibleActionRequest,
|
|
@@ -1241,36 +1413,44 @@ async function renderToHTMLOrFlightImpl(req, res, url, pagePath, query, renderOp
|
|
|
1241
1413
|
contentType: _constants1.HTML_CONTENT_TYPE_HEADER
|
|
1242
1414
|
};
|
|
1243
1415
|
// If we have pending revalidates, wait until they are all resolved.
|
|
1244
|
-
|
|
1245
|
-
|
|
1416
|
+
const maybeRevalidatesPromise = (0, _revalidationutils.executeRevalidates)(workStore);
|
|
1417
|
+
if (maybeRevalidatesPromise !== false) {
|
|
1418
|
+
const revalidatesPromise = maybeRevalidatesPromise.finally(()=>{
|
|
1246
1419
|
if (process.env.NEXT_PRIVATE_DEBUG_CACHE) {
|
|
1247
|
-
console.log('pending revalidates promise finished for:', url);
|
|
1420
|
+
console.log('pending revalidates promise finished for:', url.href);
|
|
1248
1421
|
}
|
|
1249
1422
|
});
|
|
1250
1423
|
if (renderOpts.waitUntil) {
|
|
1251
|
-
renderOpts.waitUntil(
|
|
1424
|
+
renderOpts.waitUntil(revalidatesPromise);
|
|
1252
1425
|
} else {
|
|
1253
|
-
options.waitUntil =
|
|
1426
|
+
options.waitUntil = revalidatesPromise;
|
|
1254
1427
|
}
|
|
1255
1428
|
}
|
|
1256
1429
|
applyMetadataFromPrerenderResult(response, metadata, workStore);
|
|
1257
1430
|
if (response.renderResumeDataCache) {
|
|
1258
1431
|
metadata.renderResumeDataCache = response.renderResumeDataCache;
|
|
1259
1432
|
}
|
|
1260
|
-
|
|
1433
|
+
const streamString = await (0, _streamops.streamToString)(response.stream);
|
|
1434
|
+
const result = new _renderresult.default(streamString, options);
|
|
1435
|
+
// Run build-time instant validation if the page has instant configs
|
|
1436
|
+
// TODO(instant-validation-build): This is not a great place to wire this in.
|
|
1437
|
+
if (workStore.cacheComponentsEnabled && workStore.isBuildTimePrerendering && renderOpts.runInstantValidation && await (0, _instantconfig.anySegmentNeedsInstantValidationInBuild)(loaderTree)) {
|
|
1438
|
+
// Throws StaticGenBailoutError if validation failed.
|
|
1439
|
+
await validateInstantConfigsInBuild(ctx, response.renderResumeDataCache ?? null);
|
|
1440
|
+
}
|
|
1441
|
+
return result;
|
|
1261
1442
|
} else {
|
|
1262
1443
|
// We're rendering dynamically
|
|
1263
1444
|
const renderResumeDataCache = renderOpts.renderResumeDataCache ?? (postponedState == null ? void 0 : postponedState.renderResumeDataCache) ?? null;
|
|
1264
1445
|
const rootParams = (0, _createcomponenttree.getRootParams)(loaderTree, ctx.getDynamicParamFromSegment);
|
|
1265
|
-
const
|
|
1266
|
-
const createRequestStore = _requeststore.createRequestStoreForRender.bind(null, req, res, url, rootParams, implicitTags, renderOpts.onUpdateCookies, renderOpts.previewProps, isHmrRefresh, serverComponentsHmrCache, renderResumeDataCache,
|
|
1446
|
+
const fallbackParams = (0, _requestmeta.getRequestMeta)(req, 'fallbackParams') || null;
|
|
1447
|
+
const createRequestStore = _requeststore.createRequestStoreForRender.bind(null, req, res, url, rootParams, implicitTags, renderOpts.onUpdateCookies, renderOpts.previewProps, isHmrRefresh, serverComponentsHmrCache, renderResumeDataCache, fallbackParams);
|
|
1267
1448
|
const requestStore = createRequestStore();
|
|
1268
|
-
if (process.env.
|
|
1449
|
+
if (process.env.__NEXT_DEV_SERVER && setIsrStatus && !cacheComponents && // Only pages using the Node runtime can use ISR, so we only need to
|
|
1269
1450
|
// update the status for those.
|
|
1270
1451
|
// The type check here ensures that `req` is correctly typed, and the
|
|
1271
1452
|
// environment variable check provides dead code elimination.
|
|
1272
1453
|
process.env.NEXT_RUNTIME !== 'edge' && (0, _helpers.isNodeNextRequest)(req)) {
|
|
1273
|
-
const setIsrStatus = renderOpts.setIsrStatus;
|
|
1274
1454
|
req.originalRequest.on('end', ()=>{
|
|
1275
1455
|
const { pathname } = new URL(req.url || '/', 'http://n');
|
|
1276
1456
|
const isStatic = !requestStore.usedDynamic && !workStore.forceDynamic;
|
|
@@ -1281,8 +1461,10 @@ async function renderToHTMLOrFlightImpl(req, res, url, pagePath, query, renderOp
|
|
|
1281
1461
|
if (isRuntimePrefetchRequest) {
|
|
1282
1462
|
return generateRuntimePrefetchResult(req, ctx, requestStore);
|
|
1283
1463
|
} else {
|
|
1284
|
-
if (process.env.
|
|
1285
|
-
return generateDynamicFlightRenderResultWithStagesInDev(req, ctx, requestStore, createRequestStore,
|
|
1464
|
+
if (process.env.__NEXT_DEV_SERVER && process.env.NEXT_RUNTIME !== 'edge' && cacheComponents) {
|
|
1465
|
+
return generateDynamicFlightRenderResultWithStagesInDev(req, ctx, requestStore, createRequestStore, fallbackParams);
|
|
1466
|
+
} else if (cacheComponents && cachedNavigations) {
|
|
1467
|
+
return generateStagedDynamicFlightRenderResult(req, ctx, requestStore);
|
|
1286
1468
|
} else {
|
|
1287
1469
|
return generateDynamicFlightRenderResult(req, ctx, requestStore);
|
|
1288
1470
|
}
|
|
@@ -1291,8 +1473,6 @@ async function renderToHTMLOrFlightImpl(req, res, url, pagePath, query, renderOp
|
|
|
1291
1473
|
let didExecuteServerAction = false;
|
|
1292
1474
|
let formState = null;
|
|
1293
1475
|
if (isPossibleActionRequest) {
|
|
1294
|
-
// For action requests, we don't want to use the resume data cache.
|
|
1295
|
-
requestStore.renderResumeDataCache = null;
|
|
1296
1476
|
// For action requests, we handle them differently with a special render result.
|
|
1297
1477
|
const actionRequestResult = await (0, _actionhandler.handleAction)({
|
|
1298
1478
|
req,
|
|
@@ -1310,7 +1490,7 @@ async function renderToHTMLOrFlightImpl(req, res, url, pagePath, query, renderOp
|
|
|
1310
1490
|
const notFoundLoaderTree = createNotFoundLoaderTree(loaderTree);
|
|
1311
1491
|
res.statusCode = 404;
|
|
1312
1492
|
metadata.statusCode = 404;
|
|
1313
|
-
const stream = await renderToStream(requestStore, req, res, ctx, notFoundLoaderTree, formState, postponedState, metadata, undefined,
|
|
1493
|
+
const stream = await renderToStream(requestStore, req, res, ctx, notFoundLoaderTree, formState, postponedState, metadata, undefined, fallbackParams);
|
|
1314
1494
|
return new _renderresult.default(stream, {
|
|
1315
1495
|
metadata,
|
|
1316
1496
|
contentType: _constants1.HTML_CONTENT_TYPE_HEADER
|
|
@@ -1325,8 +1505,6 @@ async function renderToHTMLOrFlightImpl(req, res, url, pagePath, query, renderOp
|
|
|
1325
1505
|
}
|
|
1326
1506
|
}
|
|
1327
1507
|
didExecuteServerAction = true;
|
|
1328
|
-
// Restore the resume data cache
|
|
1329
|
-
requestStore.renderResumeDataCache = renderResumeDataCache;
|
|
1330
1508
|
}
|
|
1331
1509
|
const options = {
|
|
1332
1510
|
metadata,
|
|
@@ -1339,24 +1517,25 @@ async function renderToHTMLOrFlightImpl(req, res, url, pagePath, query, renderOp
|
|
|
1339
1517
|
// Also, the request store might have been mutated by the action (e.g. enabling draftMode)
|
|
1340
1518
|
// and we currently we don't copy changes over when creating a new store,
|
|
1341
1519
|
// so the restarted render wouldn't be correct.
|
|
1342
|
-
didExecuteServerAction ? undefined : createRequestStore,
|
|
1520
|
+
didExecuteServerAction ? undefined : createRequestStore, fallbackParams);
|
|
1343
1521
|
// Invalid dynamic usages should only error the request in development.
|
|
1344
1522
|
// In production, it's better to produce a result.
|
|
1345
1523
|
// (the dynamic error will still be thrown inside the component tree, but it's catchable by error boundaries)
|
|
1346
|
-
if (workStore.invalidDynamicUsageError &&
|
|
1524
|
+
if (workStore.invalidDynamicUsageError && process.env.__NEXT_DEV_SERVER) {
|
|
1347
1525
|
throw workStore.invalidDynamicUsageError;
|
|
1348
1526
|
}
|
|
1349
1527
|
// If we have pending revalidates, wait until they are all resolved.
|
|
1350
|
-
|
|
1351
|
-
|
|
1528
|
+
const maybeRevalidatesPromise = (0, _revalidationutils.executeRevalidates)(workStore);
|
|
1529
|
+
if (maybeRevalidatesPromise !== false) {
|
|
1530
|
+
const revalidatesPromise = maybeRevalidatesPromise.finally(()=>{
|
|
1352
1531
|
if (process.env.NEXT_PRIVATE_DEBUG_CACHE) {
|
|
1353
|
-
console.log('pending revalidates promise finished for:', url);
|
|
1532
|
+
console.log('pending revalidates promise finished for:', url.href);
|
|
1354
1533
|
}
|
|
1355
1534
|
});
|
|
1356
1535
|
if (renderOpts.waitUntil) {
|
|
1357
|
-
renderOpts.waitUntil(
|
|
1536
|
+
renderOpts.waitUntil(revalidatesPromise);
|
|
1358
1537
|
} else {
|
|
1359
|
-
options.waitUntil =
|
|
1538
|
+
options.waitUntil = revalidatesPromise;
|
|
1360
1539
|
}
|
|
1361
1540
|
}
|
|
1362
1541
|
// Create the new render result for the response.
|
|
@@ -1447,9 +1626,10 @@ function applyMetadataFromPrerenderResult(response, metadata, workStore) {
|
|
|
1447
1626
|
};
|
|
1448
1627
|
}
|
|
1449
1628
|
}
|
|
1450
|
-
async function renderToStream(requestStore, req, res, ctx, tree, formState, postponedState, metadata, createRequestStore,
|
|
1629
|
+
async function renderToStream(requestStore, req, res, ctx, tree, formState, postponedState, metadata, createRequestStore, fallbackParams) {
|
|
1451
1630
|
/* eslint-disable @next/internal/no-ambiguous-jsx -- React Client */ const { assetPrefix, htmlRequestId, nonce, pagePath, renderOpts, requestId, workStore } = ctx;
|
|
1452
|
-
const { basePath, buildManifest, ComponentMod: { createElement
|
|
1631
|
+
const { basePath, buildManifest, ComponentMod: { createElement }, crossOrigin, experimental, isBuildTimePrerendering = false, onInstrumentationRequestError, page, reactMaxHeadersLength, setReactDebugChannel, shouldWaitOnAllReady, subresourceIntegrityManifest, supportsDynamicResponse, cacheComponents } = renderOpts;
|
|
1632
|
+
const { cachedNavigations } = renderOpts.experimental;
|
|
1453
1633
|
const { ServerInsertedHTMLProvider, renderServerInsertedHTML } = (0, _serverinsertedhtml.createServerInsertedHTML)();
|
|
1454
1634
|
const getServerInsertedMetadata = (0, _createserverinsertedmetadata.createServerInsertedMetadata)(nonce);
|
|
1455
1635
|
const tracingMetadata = (0, _utils1.getTracedMetadata)((0, _tracer.getTracer)().getTracePropagationData(), experimental.clientTraceMetadata);
|
|
@@ -1465,7 +1645,9 @@ async function renderToStream(requestStore, req, res, ctx, tree, formState, post
|
|
|
1465
1645
|
assetPrefix, crossOrigin, subresourceIntegrityManifest, (0, _getassetquerystring.getAssetQueryString)(ctx, true), nonce, page);
|
|
1466
1646
|
// In development mode, set the request ID as a global variable, before the
|
|
1467
1647
|
// bootstrap script is executed, which depends on it during hydration.
|
|
1468
|
-
|
|
1648
|
+
// For MPA navigations (page reload, direct URL entry), the request ID
|
|
1649
|
+
// header is not present, so we generate a random one.
|
|
1650
|
+
const bootstrapScriptContent = process.env.__NEXT_DEV_SERVER ? `self.__next_r=${JSON.stringify(requestId ?? crypto.randomUUID())}` : undefined;
|
|
1469
1651
|
// Create the "render route (app)" span manually so we can keep it open during streaming.
|
|
1470
1652
|
// This is necessary because errors inside Suspense boundaries are reported asynchronously
|
|
1471
1653
|
// during stream consumption, after a typical wrapped function would have ended the span.
|
|
@@ -1497,7 +1679,7 @@ async function renderToStream(requestStore, req, res, ctx, tree, formState, post
|
|
|
1497
1679
|
function onHTMLRenderRSCError(err, silenceLog) {
|
|
1498
1680
|
return onInstrumentationRequestError == null ? void 0 : onInstrumentationRequestError(err, req, createErrorContext(ctx, 'react-server-components'), silenceLog);
|
|
1499
1681
|
}
|
|
1500
|
-
const serverComponentsErrorHandler = (0, _createerrorhandler.createReactServerErrorHandler)(
|
|
1682
|
+
const serverComponentsErrorHandler = (0, _createerrorhandler.createReactServerErrorHandler)(process.env.NODE_ENV === 'development', isBuildTimePrerendering, reactServerErrorsByDigest, onHTMLRenderRSCError, renderSpan);
|
|
1501
1683
|
function onHTMLRenderSSRError(err) {
|
|
1502
1684
|
// We don't need to silence logs here. onHTMLRenderSSRError won't be called
|
|
1503
1685
|
// at all if the error was logged before in the RSC error handler.
|
|
@@ -1505,23 +1687,23 @@ async function renderToStream(requestStore, req, res, ctx, tree, formState, post
|
|
|
1505
1687
|
return onInstrumentationRequestError == null ? void 0 : onInstrumentationRequestError(err, req, createErrorContext(ctx, 'server-rendering'), silenceLog);
|
|
1506
1688
|
}
|
|
1507
1689
|
const allCapturedErrors = [];
|
|
1508
|
-
const htmlRendererErrorHandler = (0, _createerrorhandler.createHTMLErrorHandler)(
|
|
1690
|
+
const htmlRendererErrorHandler = (0, _createerrorhandler.createHTMLErrorHandler)(process.env.NODE_ENV === 'development', isBuildTimePrerendering, reactServerErrorsByDigest, allCapturedErrors, onHTMLRenderSSRError, renderSpan);
|
|
1509
1691
|
let reactServerResult = null;
|
|
1510
1692
|
let reactDebugStream;
|
|
1511
1693
|
const setHeader = res.setHeader.bind(res);
|
|
1512
1694
|
const appendHeader = res.appendHeader.bind(res);
|
|
1513
1695
|
const { clientModules } = (0, _manifestssingleton.getClientReferenceManifest)();
|
|
1514
1696
|
try {
|
|
1515
|
-
if (//
|
|
1516
|
-
process.env.NODE_ENV === 'development' && // We only want this behavior when running `next dev`
|
|
1517
|
-
dev && // Edge routes never prerender so we don't have a Prerender environment for anything in edge runtime
|
|
1697
|
+
if (process.env.__NEXT_DEV_SERVER && // Edge routes never prerender so we don't have a Prerender environment for anything in edge runtime
|
|
1518
1698
|
process.env.NEXT_RUNTIME !== 'edge' && // We only have a Prerender environment for projects opted into cacheComponents
|
|
1519
1699
|
cacheComponents) {
|
|
1520
1700
|
let debugChannel;
|
|
1521
|
-
|
|
1522
|
-
requestStore)=>{
|
|
1523
|
-
const payload = await _workunitasyncstorageexternal.workUnitAsyncStorage.run(requestStore, getRSCPayload, tree, ctx,
|
|
1524
|
-
|
|
1701
|
+
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
1702
|
+
const getPayload = async (requestStore)=>{
|
|
1703
|
+
const payload = await _workunitasyncstorageexternal.workUnitAsyncStorage.run(requestStore, getRSCPayload, tree, ctx, {
|
|
1704
|
+
is404: res.statusCode === 404
|
|
1705
|
+
});
|
|
1706
|
+
if (isBypassingCachesInDev(requestStore)) {
|
|
1525
1707
|
// Mark the RSC payload to indicate that caches were bypassed in dev.
|
|
1526
1708
|
// This lets the client know not to cache anything based on this render.
|
|
1527
1709
|
if (renderOpts.setCacheStatus) {
|
|
@@ -1538,8 +1720,8 @@ async function renderToStream(requestStore, req, res, ctx, tree, formState, post
|
|
|
1538
1720
|
// (which is not the case for renders after an action)
|
|
1539
1721
|
createRequestStore && // We only do this flow if we're not bypassing caches in dev using
|
|
1540
1722
|
// "disable cache" in devtools or a hard refresh (cache-control: "no-store")
|
|
1541
|
-
!isBypassingCachesInDev(
|
|
1542
|
-
const { stream: serverStream, accumulatedChunksPromise,
|
|
1723
|
+
!isBypassingCachesInDev(requestStore)) {
|
|
1724
|
+
const { stream: serverStream, accumulatedChunksPromise, syncInterruptReason, startTime, staticStageEndTime, runtimeStageEndTime, debugChannel: returnedDebugChannel, requestStore: finalRequestStore } = await renderWithRestartOnCacheMissInDev(ctx, requestStore, createRequestStore, getPayload, serverComponentsErrorHandler);
|
|
1543
1725
|
let validationDebugChannelClient = undefined;
|
|
1544
1726
|
if (returnedDebugChannel) {
|
|
1545
1727
|
const [t1, t2] = returnedDebugChannel.clientSide.readable.tee();
|
|
@@ -1548,14 +1730,15 @@ async function renderToStream(requestStore, req, res, ctx, tree, formState, post
|
|
|
1548
1730
|
}
|
|
1549
1731
|
_consoleasyncstorageexternal.consoleAsyncStorage.run({
|
|
1550
1732
|
dim: true
|
|
1551
|
-
}, spawnStaticShellValidationInDev, accumulatedChunksPromise,
|
|
1733
|
+
}, spawnStaticShellValidationInDev, accumulatedChunksPromise, syncInterruptReason, startTime, staticStageEndTime, runtimeStageEndTime, ctx, finalRequestStore, fallbackParams, validationDebugChannelClient);
|
|
1552
1734
|
reactServerResult = new _apprenderprerenderutils.ReactServerResult(serverStream);
|
|
1553
1735
|
requestStore = finalRequestStore;
|
|
1554
1736
|
debugChannel = returnedDebugChannel;
|
|
1555
1737
|
} else {
|
|
1738
|
+
logValidationSkipped(ctx);
|
|
1556
1739
|
// We're either bypassing caches or we can't restart the render.
|
|
1557
1740
|
// Do a dynamic render, but with (basic) environment labels.
|
|
1558
|
-
debugChannel = setReactDebugChannel && createDebugChannel();
|
|
1741
|
+
debugChannel = setReactDebugChannel && (0, _debugchannelserver.createDebugChannel)();
|
|
1559
1742
|
const serverStream = await stagedRenderToReadableStreamWithoutCachesInDev(ctx, requestStore, getPayload, {
|
|
1560
1743
|
onError: serverComponentsErrorHandler,
|
|
1561
1744
|
filterStackFrame,
|
|
@@ -1570,10 +1753,72 @@ async function renderToStream(requestStore, req, res, ctx, tree, formState, post
|
|
|
1570
1753
|
readable: readableBrowser
|
|
1571
1754
|
}, htmlRequestId, requestId);
|
|
1572
1755
|
}
|
|
1756
|
+
} else if (cacheComponents && cachedNavigations) {
|
|
1757
|
+
// Production Cache Components + Cached Navigations: use staged
|
|
1758
|
+
// rendering so the RSC payload includes the static stage byte length
|
|
1759
|
+
// (`l` field), enabling the client to cache the static subset during
|
|
1760
|
+
// hydration.
|
|
1761
|
+
const { renderToReadableStream } = ctx.componentMod;
|
|
1762
|
+
const selectStaleTime = (0, _staletime.createSelectStaleTime)(experimental);
|
|
1763
|
+
const staleTimeIterable = new _staletime.StaleTimeIterable();
|
|
1764
|
+
// TODO(cached-navs): this assumes that we checked during build that there's no sync IO.
|
|
1765
|
+
// but it can happen e.g. after a revalidation or conditionally for a param that wasn't prerendered.
|
|
1766
|
+
// we should change this to track sync IO, log an error and advance to dynamic.
|
|
1767
|
+
const shouldTrackSyncIO = false;
|
|
1768
|
+
const stageController = new _stagedrendering.StagedRenderingController(null, null, shouldTrackSyncIO);
|
|
1769
|
+
requestStore.stale = _constants1.INFINITE_CACHE;
|
|
1770
|
+
requestStore.stagedRendering = stageController;
|
|
1771
|
+
(0, _staletime.trackStaleTime)(requestStore, staleTimeIterable, selectStaleTime);
|
|
1772
|
+
let resolveStaticStageByteLength;
|
|
1773
|
+
const staticStageByteLengthPromise = new Promise((resolve)=>{
|
|
1774
|
+
resolveStaticStageByteLength = resolve;
|
|
1775
|
+
});
|
|
1776
|
+
// If the route has runtime prefetching enabled, spawn a runtime
|
|
1777
|
+
// prerender after the resume render fills caches. The result is
|
|
1778
|
+
// embedded in the initial RSC payload so the client can cache
|
|
1779
|
+
// runtime-prefetchable content during hydration.
|
|
1780
|
+
const hasRuntimePrefetch = await (0, _instantconfig.anySegmentHasRuntimePrefetchEnabled)(tree);
|
|
1781
|
+
let runtimePrefetchStream;
|
|
1782
|
+
if (hasRuntimePrefetch) {
|
|
1783
|
+
const prerenderResumeDataCache = (0, _resumedatacache.createPrerenderResumeDataCache)();
|
|
1784
|
+
requestStore.prerenderResumeDataCache = prerenderResumeDataCache;
|
|
1785
|
+
const cacheSignal = new _cachesignal.CacheSignal();
|
|
1786
|
+
(0, _trackmoduleloadingexternal.trackPendingModules)(cacheSignal);
|
|
1787
|
+
requestStore.cacheSignal = cacheSignal;
|
|
1788
|
+
const runtimePrefetchTransform = new TransformStream();
|
|
1789
|
+
runtimePrefetchStream = runtimePrefetchTransform.readable;
|
|
1790
|
+
void cacheSignal.cacheReady().then(()=>spawnRuntimePrefetchWithFilledCaches(runtimePrefetchTransform.writable, ctx, prerenderResumeDataCache, requestStore, serverComponentsErrorHandler));
|
|
1791
|
+
}
|
|
1792
|
+
const RSCPayload = await _workunitasyncstorageexternal.workUnitAsyncStorage.run(requestStore, getRSCPayload, tree, ctx, {
|
|
1793
|
+
is404: res.statusCode === 404,
|
|
1794
|
+
staleTimeIterable,
|
|
1795
|
+
staticStageByteLengthPromise,
|
|
1796
|
+
runtimePrefetchStream
|
|
1797
|
+
});
|
|
1798
|
+
const flightStream = await (0, _apprenderrenderutils.runInSequentialTasks)(()=>{
|
|
1799
|
+
stageController.advanceStage(_stagedrendering.RenderStage.Static);
|
|
1800
|
+
const stream = _workunitasyncstorageexternal.workUnitAsyncStorage.run(requestStore, renderToReadableStream, RSCPayload, clientModules, {
|
|
1801
|
+
onError: serverComponentsErrorHandler,
|
|
1802
|
+
filterStackFrame
|
|
1803
|
+
});
|
|
1804
|
+
const [dynamicStream, staticStream] = stream.tee();
|
|
1805
|
+
countStaticStageBytes(staticStream, stageController).then(resolveStaticStageByteLength);
|
|
1806
|
+
return dynamicStream;
|
|
1807
|
+
}, ()=>{
|
|
1808
|
+
// This is a separate task that doesn't advance a stage. It forces
|
|
1809
|
+
// draining the microtask queue so that the stale time iterable is
|
|
1810
|
+
// closed before we advance to the dynamic stage.
|
|
1811
|
+
void (0, _staletime.finishStaleTimeTracking)(staleTimeIterable);
|
|
1812
|
+
}, ()=>{
|
|
1813
|
+
stageController.advanceStage(_stagedrendering.RenderStage.Dynamic);
|
|
1814
|
+
});
|
|
1815
|
+
reactServerResult = new _apprenderprerenderutils.ReactServerResult(flightStream);
|
|
1573
1816
|
} else {
|
|
1574
1817
|
// This is a dynamic render. We don't do dynamic tracking because we're not prerendering
|
|
1575
|
-
const RSCPayload = await _workunitasyncstorageexternal.workUnitAsyncStorage.run(requestStore, getRSCPayload, tree, ctx,
|
|
1576
|
-
|
|
1818
|
+
const RSCPayload = await _workunitasyncstorageexternal.workUnitAsyncStorage.run(requestStore, getRSCPayload, tree, ctx, {
|
|
1819
|
+
is404: res.statusCode === 404
|
|
1820
|
+
});
|
|
1821
|
+
const debugChannel = setReactDebugChannel && (0, _debugchannelserver.createDebugChannel)();
|
|
1577
1822
|
if (debugChannel) {
|
|
1578
1823
|
const [readableSsr, readableBrowser] = debugChannel.clientSide.readable.tee();
|
|
1579
1824
|
reactDebugStream = readableSsr;
|
|
@@ -1581,7 +1826,7 @@ async function renderToStream(requestStore, req, res, ctx, tree, formState, post
|
|
|
1581
1826
|
readable: readableBrowser
|
|
1582
1827
|
}, htmlRequestId, requestId);
|
|
1583
1828
|
}
|
|
1584
|
-
reactServerResult = new _apprenderprerenderutils.ReactServerResult(_workunitasyncstorageexternal.workUnitAsyncStorage.run(requestStore,
|
|
1829
|
+
reactServerResult = new _apprenderprerenderutils.ReactServerResult(_workunitasyncstorageexternal.workUnitAsyncStorage.run(requestStore, _streamops.renderToFlightStream, ctx.componentMod, RSCPayload, clientModules, {
|
|
1585
1830
|
filterStackFrame,
|
|
1586
1831
|
onError: serverComponentsErrorHandler,
|
|
1587
1832
|
debugChannel: debugChannel == null ? void 0 : debugChannel.serverSide
|
|
@@ -1598,15 +1843,14 @@ async function renderToStream(requestStore, req, res, ctx, tree, formState, post
|
|
|
1598
1843
|
// We have a complete HTML Document in the prerender but we need to
|
|
1599
1844
|
// still include the new server component render because it was not included
|
|
1600
1845
|
// in the static prelude.
|
|
1601
|
-
const
|
|
1846
|
+
const inlinedDataStream = (0, _streamops.createInlinedDataStream)(reactServerResult.tee(), nonce, formState);
|
|
1602
1847
|
// End the span since there's no async rendering in this path
|
|
1603
1848
|
if (renderSpan.isRecording()) renderSpan.end();
|
|
1604
|
-
return (0,
|
|
1849
|
+
return (0, _streamops.chainStreams)(inlinedDataStream, (0, _streamops.createDocumentClosingStream)());
|
|
1605
1850
|
} else if (postponedState) {
|
|
1606
1851
|
// We assume we have dynamic HTML requiring a resume render to complete
|
|
1607
1852
|
const { postponed, preludeState } = (0, _postponedstate.getPostponedFromState)(postponedState);
|
|
1608
|
-
const
|
|
1609
|
-
const htmlStream = await _workunitasyncstorageexternal.workUnitAsyncStorage.run(requestStore, resume, /*#__PURE__*/ (0, _jsxruntime.jsx)(App, {
|
|
1853
|
+
const resumeAppElement = /*#__PURE__*/ (0, _jsxruntime.jsx)(App, {
|
|
1610
1854
|
reactServerStream: reactServerResult.tee(),
|
|
1611
1855
|
reactDebugStream: reactDebugStream,
|
|
1612
1856
|
debugEndTime: undefined,
|
|
@@ -1614,13 +1858,6 @@ async function renderToStream(requestStore, req, res, ctx, tree, formState, post
|
|
|
1614
1858
|
ServerInsertedHTMLProvider: ServerInsertedHTMLProvider,
|
|
1615
1859
|
nonce: nonce,
|
|
1616
1860
|
images: ctx.renderOpts.images
|
|
1617
|
-
}), postponed, {
|
|
1618
|
-
onError: htmlRendererErrorHandler,
|
|
1619
|
-
nonce
|
|
1620
|
-
});
|
|
1621
|
-
// End the render span only after React completed rendering (including anything inside Suspense boundaries)
|
|
1622
|
-
htmlStream.allReady.finally(()=>{
|
|
1623
|
-
if (renderSpan.isRecording()) renderSpan.end();
|
|
1624
1861
|
});
|
|
1625
1862
|
const getServerInsertedHTML = (0, _makegetserverinsertedhtml.makeGetServerInsertedHTML)({
|
|
1626
1863
|
polyfills,
|
|
@@ -1629,21 +1866,33 @@ async function renderToStream(requestStore, req, res, ctx, tree, formState, post
|
|
|
1629
1866
|
basePath,
|
|
1630
1867
|
tracingMetadata: tracingMetadata
|
|
1631
1868
|
});
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1869
|
+
const { stream: htmlStream, allReady } = await _workunitasyncstorageexternal.workUnitAsyncStorage.run(requestStore, _streamops.resumeToFizzStream, resumeAppElement, postponed, {
|
|
1870
|
+
onError: htmlRendererErrorHandler,
|
|
1871
|
+
nonce
|
|
1872
|
+
});
|
|
1873
|
+
// End the render span only after React completed rendering (including anything inside Suspense boundaries)
|
|
1874
|
+
allReady.finally(()=>{
|
|
1875
|
+
if (renderSpan.isRecording()) renderSpan.end();
|
|
1876
|
+
});
|
|
1877
|
+
return await (0, _streamops.continueDynamicHTMLResume)(htmlStream, {
|
|
1637
1878
|
delayDataUntilFirstHtmlChunk: preludeState === _postponedstate.DynamicHTMLPreludeState.Empty,
|
|
1638
|
-
inlinedDataStream: (0,
|
|
1879
|
+
inlinedDataStream: (0, _streamops.createInlinedDataStream)(reactServerResult.consume(), nonce, formState),
|
|
1639
1880
|
getServerInsertedHTML,
|
|
1640
|
-
getServerInsertedMetadata
|
|
1881
|
+
getServerInsertedMetadata,
|
|
1882
|
+
deploymentId: ctx.sharedContext.deploymentId
|
|
1641
1883
|
});
|
|
1642
1884
|
}
|
|
1643
1885
|
}
|
|
1644
1886
|
// This is a regular dynamic render
|
|
1645
|
-
const
|
|
1646
|
-
|
|
1887
|
+
const getServerInsertedHTML = (0, _makegetserverinsertedhtml.makeGetServerInsertedHTML)({
|
|
1888
|
+
polyfills,
|
|
1889
|
+
renderServerInsertedHTML,
|
|
1890
|
+
serverCapturedErrors: allCapturedErrors,
|
|
1891
|
+
basePath,
|
|
1892
|
+
tracingMetadata: tracingMetadata
|
|
1893
|
+
});
|
|
1894
|
+
const generateStaticHTML = supportsDynamicResponse !== true || !!shouldWaitOnAllReady;
|
|
1895
|
+
const appElement = /*#__PURE__*/ (0, _jsxruntime.jsx)(App, {
|
|
1647
1896
|
reactServerStream: reactServerResult.tee(),
|
|
1648
1897
|
reactDebugStream: reactDebugStream,
|
|
1649
1898
|
debugEndTime: undefined,
|
|
@@ -1651,7 +1900,8 @@ async function renderToStream(requestStore, req, res, ctx, tree, formState, post
|
|
|
1651
1900
|
ServerInsertedHTMLProvider: ServerInsertedHTMLProvider,
|
|
1652
1901
|
nonce: nonce,
|
|
1653
1902
|
images: ctx.renderOpts.images
|
|
1654
|
-
})
|
|
1903
|
+
});
|
|
1904
|
+
const fizzOptions = {
|
|
1655
1905
|
onError: htmlRendererErrorHandler,
|
|
1656
1906
|
nonce,
|
|
1657
1907
|
onHeaders: (headers)=>{
|
|
@@ -1665,43 +1915,20 @@ async function renderToStream(requestStore, req, res, ctx, tree, formState, post
|
|
|
1665
1915
|
bootstrapScript
|
|
1666
1916
|
],
|
|
1667
1917
|
formState
|
|
1668
|
-
}
|
|
1918
|
+
};
|
|
1919
|
+
const { stream: htmlStream, allReady } = await _workunitasyncstorageexternal.workUnitAsyncStorage.run(requestStore, _streamops.renderToFizzStream, appElement, fizzOptions);
|
|
1669
1920
|
// End the render span only after React completed rendering (including anything inside Suspense boundaries)
|
|
1670
|
-
|
|
1921
|
+
allReady.finally(()=>{
|
|
1671
1922
|
if (renderSpan.isRecording()) renderSpan.end();
|
|
1672
1923
|
});
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
renderServerInsertedHTML,
|
|
1676
|
-
serverCapturedErrors: allCapturedErrors,
|
|
1677
|
-
basePath,
|
|
1678
|
-
tracingMetadata: tracingMetadata
|
|
1679
|
-
});
|
|
1680
|
-
/**
|
|
1681
|
-
* Rules of Static & Dynamic HTML:
|
|
1682
|
-
*
|
|
1683
|
-
* 1.) We must generate static HTML unless the caller explicitly opts
|
|
1684
|
-
* in to dynamic HTML support.
|
|
1685
|
-
*
|
|
1686
|
-
* 2.) If dynamic HTML support is requested, we must honor that request
|
|
1687
|
-
* or throw an error. It is the sole responsibility of the caller to
|
|
1688
|
-
* ensure they aren't e.g. requesting dynamic HTML for a static page.
|
|
1689
|
-
*
|
|
1690
|
-
* 3.) If `shouldWaitOnAllReady` is true, which indicates we need to
|
|
1691
|
-
* resolve all suspenses and generate a full HTML. e.g. when it's a
|
|
1692
|
-
* html limited bot requests, we produce the full HTML content.
|
|
1693
|
-
*
|
|
1694
|
-
* These rules help ensure that other existing features like request caching,
|
|
1695
|
-
* coalescing, and ISR continue working as intended.
|
|
1696
|
-
*/ const generateStaticHTML = supportsDynamicResponse !== true || !!shouldWaitOnAllReady;
|
|
1697
|
-
return await (0, _nodewebstreamshelper.continueFizzStream)(htmlStream, {
|
|
1698
|
-
inlinedDataStream: (0, _useflightresponse.createInlinedDataReadableStream)(reactServerResult.consume(), nonce, formState),
|
|
1924
|
+
return await (0, _streamops.continueFizzStream)(htmlStream, {
|
|
1925
|
+
inlinedDataStream: (0, _streamops.createInlinedDataStream)(reactServerResult.consume(), nonce, formState),
|
|
1699
1926
|
isStaticGeneration: generateStaticHTML,
|
|
1700
|
-
|
|
1701
|
-
|
|
1927
|
+
allReady,
|
|
1928
|
+
deploymentId: ctx.sharedContext.deploymentId,
|
|
1702
1929
|
getServerInsertedHTML,
|
|
1703
1930
|
getServerInsertedMetadata,
|
|
1704
|
-
validateRootLayout:
|
|
1931
|
+
validateRootLayout: !!process.env.__NEXT_DEV_SERVER
|
|
1705
1932
|
});
|
|
1706
1933
|
} catch (err) {
|
|
1707
1934
|
if ((0, _staticgenerationbailout.isStaticGenBailoutError)(err) || typeof err === 'object' && err !== null && 'message' in err && typeof err.message === 'string' && err.message.includes('https://nextjs.org/docs/advanced-features/static-html-export')) {
|
|
@@ -1744,7 +1971,7 @@ async function renderToStream(requestStore, req, res, ctx, tree, formState, post
|
|
|
1744
1971
|
let errorServerStream;
|
|
1745
1972
|
try {
|
|
1746
1973
|
errorRSCPayload = await _workunitasyncstorageexternal.workUnitAsyncStorage.run(requestStore, getErrorRSCPayload, tree, ctx, reactServerErrorsByDigest.has(err.digest) ? null : err, errorType);
|
|
1747
|
-
errorServerStream = _workunitasyncstorageexternal.workUnitAsyncStorage.run(requestStore,
|
|
1974
|
+
errorServerStream = _workunitasyncstorageexternal.workUnitAsyncStorage.run(requestStore, _streamops.renderToFlightStream, ctx.componentMod, errorRSCPayload, clientModules, {
|
|
1748
1975
|
filterStackFrame,
|
|
1749
1976
|
onError: serverComponentsErrorHandler
|
|
1750
1977
|
});
|
|
@@ -1759,53 +1986,32 @@ async function renderToStream(requestStore, req, res, ctx, tree, formState, post
|
|
|
1759
1986
|
throw setupErr;
|
|
1760
1987
|
}
|
|
1761
1988
|
try {
|
|
1762
|
-
const
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
errorBootstrapScript
|
|
1777
|
-
],
|
|
1778
|
-
formState
|
|
1779
|
-
}
|
|
1989
|
+
const generateStaticHTML = supportsDynamicResponse !== true || !!shouldWaitOnAllReady;
|
|
1990
|
+
const { stream: errorHtmlStream, allReady: errorAllReady } = await _workunitasyncstorageexternal.workUnitAsyncStorage.run(requestStore, _streamops.renderToFizzStream, /*#__PURE__*/ (0, _jsxruntime.jsx)(ErrorApp, {
|
|
1991
|
+
reactServerStream: errorServerStream,
|
|
1992
|
+
ServerInsertedHTMLProvider: ServerInsertedHTMLProvider,
|
|
1993
|
+
preinitScripts: errorPreinitScripts,
|
|
1994
|
+
nonce: nonce,
|
|
1995
|
+
images: ctx.renderOpts.images
|
|
1996
|
+
}), {
|
|
1997
|
+
nonce,
|
|
1998
|
+
bootstrapScriptContent,
|
|
1999
|
+
bootstrapScripts: [
|
|
2000
|
+
errorBootstrapScript
|
|
2001
|
+
],
|
|
2002
|
+
formState
|
|
1780
2003
|
});
|
|
1781
2004
|
// End the render span only after React completed rendering (including anything inside Suspense boundaries)
|
|
1782
|
-
|
|
2005
|
+
errorAllReady.finally(()=>{
|
|
1783
2006
|
if (renderSpan.isRecording()) renderSpan.end();
|
|
1784
2007
|
});
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
*
|
|
1788
|
-
* 1.) We must generate static HTML unless the caller explicitly opts
|
|
1789
|
-
* in to dynamic HTML support.
|
|
1790
|
-
*
|
|
1791
|
-
* 2.) If dynamic HTML support is requested, we must honor that request
|
|
1792
|
-
* or throw an error. It is the sole responsibility of the caller to
|
|
1793
|
-
* ensure they aren't e.g. requesting dynamic HTML for a static page.
|
|
1794
|
-
* 3.) If `shouldWaitOnAllReady` is true, which indicates we need to
|
|
1795
|
-
* resolve all suspenses and generate a full HTML. e.g. when it's a
|
|
1796
|
-
* html limited bot requests, we produce the full HTML content.
|
|
1797
|
-
*
|
|
1798
|
-
* These rules help ensure that other existing features like request caching,
|
|
1799
|
-
* coalescing, and ISR continue working as intended.
|
|
1800
|
-
*/ const generateStaticHTML = supportsDynamicResponse !== true || !!shouldWaitOnAllReady;
|
|
1801
|
-
return await (0, _nodewebstreamshelper.continueFizzStream)(fizzStream, {
|
|
1802
|
-
inlinedDataStream: (0, _useflightresponse.createInlinedDataReadableStream)(// This is intentionally using the readable datastream from the
|
|
2008
|
+
return await (0, _streamops.continueFizzStream)(errorHtmlStream, {
|
|
2009
|
+
inlinedDataStream: (0, _streamops.createInlinedDataStream)(// This is intentionally using the readable datastream from the
|
|
1803
2010
|
// main render rather than the flight data from the error page
|
|
1804
2011
|
// render
|
|
1805
2012
|
reactServerResult.consume(), nonce, formState),
|
|
1806
2013
|
isStaticGeneration: generateStaticHTML,
|
|
1807
|
-
|
|
1808
|
-
buildId: ctx.workStore.buildId,
|
|
2014
|
+
deploymentId: ctx.sharedContext.deploymentId,
|
|
1809
2015
|
getServerInsertedHTML: (0, _makegetserverinsertedhtml.makeGetServerInsertedHTML)({
|
|
1810
2016
|
polyfills,
|
|
1811
2017
|
renderServerInsertedHTML,
|
|
@@ -1814,10 +2020,10 @@ async function renderToStream(requestStore, req, res, ctx, tree, formState, post
|
|
|
1814
2020
|
tracingMetadata: tracingMetadata
|
|
1815
2021
|
}),
|
|
1816
2022
|
getServerInsertedMetadata,
|
|
1817
|
-
validateRootLayout:
|
|
2023
|
+
validateRootLayout: !!process.env.__NEXT_DEV_SERVER
|
|
1818
2024
|
});
|
|
1819
2025
|
} catch (finalErr) {
|
|
1820
|
-
if (process.env.
|
|
2026
|
+
if (process.env.__NEXT_DEV_SERVER && (0, _httpaccessfallback.isHTTPAccessFallbackError)(finalErr)) {
|
|
1821
2027
|
const { bailOnRootNotFound } = require('../../client/components/dev-root-http-access-fallback-boundary');
|
|
1822
2028
|
bailOnRootNotFound();
|
|
1823
2029
|
}
|
|
@@ -1828,19 +2034,22 @@ async function renderToStream(requestStore, req, res, ctx, tree, formState, post
|
|
|
1828
2034
|
});
|
|
1829
2035
|
/* eslint-enable @next/internal/no-ambiguous-jsx */ }
|
|
1830
2036
|
async function renderWithRestartOnCacheMissInDev(ctx, initialRequestStore, createRequestStore, getPayload, onError) {
|
|
1831
|
-
const { htmlRequestId, renderOpts
|
|
2037
|
+
const { htmlRequestId, renderOpts } = ctx;
|
|
1832
2038
|
const { ComponentMod, setCacheStatus, setReactDebugChannel } = renderOpts;
|
|
1833
|
-
|
|
2039
|
+
let startTime = -Infinity;
|
|
1834
2040
|
// If the render is restarted, we'll recreate a fresh request store
|
|
1835
2041
|
let requestStore = initialRequestStore;
|
|
1836
2042
|
const environmentName = ()=>{
|
|
1837
2043
|
const currentStage = requestStore.stagedRendering.currentStage;
|
|
1838
2044
|
switch(currentStage){
|
|
1839
2045
|
case _stagedrendering.RenderStage.Before:
|
|
2046
|
+
case _stagedrendering.RenderStage.EarlyStatic:
|
|
1840
2047
|
case _stagedrendering.RenderStage.Static:
|
|
1841
2048
|
return 'Prerender';
|
|
2049
|
+
case _stagedrendering.RenderStage.EarlyRuntime:
|
|
2050
|
+
return 'Prefetch';
|
|
1842
2051
|
case _stagedrendering.RenderStage.Runtime:
|
|
1843
|
-
return
|
|
2052
|
+
return 'Prefetchable';
|
|
1844
2053
|
case _stagedrendering.RenderStage.Dynamic:
|
|
1845
2054
|
case _stagedrendering.RenderStage.Abandoned:
|
|
1846
2055
|
return 'Server';
|
|
@@ -1869,97 +2078,101 @@ async function renderWithRestartOnCacheMissInDev(ctx, initialRequestStore, creat
|
|
|
1869
2078
|
const initialReactController = new AbortController();
|
|
1870
2079
|
const initialDataController = new AbortController() // Controls hanging promises we create
|
|
1871
2080
|
;
|
|
1872
|
-
const
|
|
2081
|
+
const initialAbandonController = new AbortController() // Controls whether this render is abandoned
|
|
2082
|
+
;
|
|
2083
|
+
const initialStageController = new _stagedrendering.StagedRenderingController(initialDataController.signal, initialAbandonController, true // track sync IO
|
|
2084
|
+
);
|
|
1873
2085
|
requestStore.prerenderResumeDataCache = prerenderResumeDataCache;
|
|
1874
2086
|
// `getRenderResumeDataCache` will fall back to using `prerenderResumeDataCache` as `renderResumeDataCache`,
|
|
1875
2087
|
// so not having a resume data cache won't break any expectations in case we don't need to restart.
|
|
1876
2088
|
requestStore.renderResumeDataCache = null;
|
|
1877
2089
|
requestStore.stagedRendering = initialStageController;
|
|
1878
|
-
requestStore.asyncApiPromises =
|
|
2090
|
+
requestStore.asyncApiPromises = createAsyncApiPromises(initialStageController, requestStore.cookies, requestStore.mutableCookies, requestStore.headers);
|
|
1879
2091
|
requestStore.cacheSignal = cacheSignal;
|
|
1880
|
-
let debugChannel = setReactDebugChannel && createDebugChannel();
|
|
2092
|
+
let debugChannel = setReactDebugChannel && (0, _debugchannelserver.createDebugChannel)();
|
|
1881
2093
|
const { clientModules } = (0, _manifestssingleton.getClientReferenceManifest)();
|
|
1882
2094
|
// Note: The stage controller starts out in the `Before` stage,
|
|
1883
2095
|
// where sync IO does not cause aborts, so it's okay if it happens before render.
|
|
1884
2096
|
const initialRscPayload = await getPayload(requestStore);
|
|
1885
|
-
const
|
|
1886
|
-
|
|
2097
|
+
const initialStreamResult = await (0, _apprenderrenderutils.runInSequentialTasks)(()=>{
|
|
2098
|
+
initialStageController.advanceStage(_stagedrendering.RenderStage.EarlyStatic);
|
|
2099
|
+
startTime = performance.now() + performance.timeOrigin;
|
|
2100
|
+
const streamPair = _workunitasyncstorageexternal.workUnitAsyncStorage.run(requestStore, _streamops.renderToFlightStream, ComponentMod, initialRscPayload, clientModules, {
|
|
2101
|
+
onError,
|
|
2102
|
+
environmentName,
|
|
2103
|
+
startTime,
|
|
2104
|
+
filterStackFrame,
|
|
2105
|
+
debugChannel: debugChannel == null ? void 0 : debugChannel.serverSide,
|
|
2106
|
+
signal: initialReactController.signal
|
|
2107
|
+
}).tee();
|
|
2108
|
+
// If we abort the render, we want to reject the stage-dependent promises as well.
|
|
2109
|
+
// Note that we want to install this listener after the render is started
|
|
2110
|
+
// so that it runs after react is finished running its abort code.
|
|
2111
|
+
initialReactController.signal.addEventListener('abort', ()=>{
|
|
2112
|
+
const { reason } = initialReactController.signal;
|
|
2113
|
+
initialDataController.abort(reason);
|
|
2114
|
+
}, {
|
|
2115
|
+
once: true
|
|
2116
|
+
});
|
|
2117
|
+
const stream = streamPair[0];
|
|
2118
|
+
const accumulatedChunksPromise = accumulateStreamChunks(streamPair[1], initialStageController, initialDataController.signal);
|
|
2119
|
+
initialDataController.signal.addEventListener('abort', ()=>{
|
|
2120
|
+
accumulatedChunksPromise.catch(()=>{});
|
|
2121
|
+
stream.cancel();
|
|
2122
|
+
}, {
|
|
2123
|
+
once: true
|
|
2124
|
+
});
|
|
2125
|
+
return {
|
|
2126
|
+
stream,
|
|
2127
|
+
accumulatedChunksPromise
|
|
2128
|
+
};
|
|
2129
|
+
}, ()=>{
|
|
2130
|
+
if (initialAbandonController.signal.aborted === true) {
|
|
2131
|
+
return;
|
|
2132
|
+
} else if (cacheSignal.hasPendingReads()) {
|
|
2133
|
+
initialAbandonController.abort();
|
|
2134
|
+
} else {
|
|
1887
2135
|
initialStageController.advanceStage(_stagedrendering.RenderStage.Static);
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
return {
|
|
1904
|
-
stream: continuationStream,
|
|
1905
|
-
accumulatedChunksPromise
|
|
1906
|
-
};
|
|
1907
|
-
}, ({ stream, accumulatedChunksPromise })=>{
|
|
1908
|
-
// Runtime stage
|
|
1909
|
-
if (initialStageController.currentStage === _stagedrendering.RenderStage.Abandoned) {
|
|
1910
|
-
// If we abandoned the render in the static stage, we won't proceed further.
|
|
1911
|
-
return null;
|
|
1912
|
-
}
|
|
1913
|
-
// If we had a cache miss in the static stage, we'll have to discard this stream
|
|
1914
|
-
// and render again once the caches are warm.
|
|
1915
|
-
// If we already advanced stages we similarly had sync IO that might be from module loading
|
|
1916
|
-
// and need to render again once the caches are warm.
|
|
1917
|
-
if (cacheSignal.hasPendingReads()) {
|
|
1918
|
-
// Regardless of whether we are going to abandon this
|
|
1919
|
-
// render we need the unblock runtime b/c it's essential
|
|
1920
|
-
// filling caches.
|
|
1921
|
-
initialStageController.abandonRender();
|
|
1922
|
-
return null;
|
|
1923
|
-
}
|
|
2136
|
+
}
|
|
2137
|
+
}, ()=>{
|
|
2138
|
+
if (initialAbandonController.signal.aborted === true) {
|
|
2139
|
+
return;
|
|
2140
|
+
} else if (cacheSignal.hasPendingReads()) {
|
|
2141
|
+
initialAbandonController.abort();
|
|
2142
|
+
} else {
|
|
2143
|
+
initialStageController.advanceStage(_stagedrendering.RenderStage.EarlyRuntime);
|
|
2144
|
+
}
|
|
2145
|
+
}, ()=>{
|
|
2146
|
+
if (initialAbandonController.signal.aborted === true) {
|
|
2147
|
+
return;
|
|
2148
|
+
} else if (cacheSignal.hasPendingReads()) {
|
|
2149
|
+
initialAbandonController.abort();
|
|
2150
|
+
} else {
|
|
1924
2151
|
initialStageController.advanceStage(_stagedrendering.RenderStage.Runtime);
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
}
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
// If we abandoned the render in the static or runtime stage, we won't proceed further.
|
|
1933
|
-
return null;
|
|
1934
|
-
}
|
|
1935
|
-
// If we had cache misses in either of the previous stages,
|
|
1936
|
-
// then we'll only use this render for filling caches.
|
|
1937
|
-
// We won't advance the stage, and thus leave dynamic APIs hanging,
|
|
1938
|
-
// because they won't be cached anyway, so it'd be wasted work.
|
|
1939
|
-
if (cacheSignal.hasPendingReads()) {
|
|
1940
|
-
initialStageController.abandonRender();
|
|
1941
|
-
return null;
|
|
1942
|
-
}
|
|
1943
|
-
// Regardless of whether we are going to abandon this
|
|
1944
|
-
// render we need the unblock runtime b/c it's essential
|
|
1945
|
-
// filling caches.
|
|
2152
|
+
}
|
|
2153
|
+
}, ()=>{
|
|
2154
|
+
if (initialAbandonController.signal.aborted === true) {
|
|
2155
|
+
return;
|
|
2156
|
+
} else if (cacheSignal.hasPendingReads()) {
|
|
2157
|
+
initialAbandonController.abort();
|
|
2158
|
+
} else {
|
|
1946
2159
|
initialStageController.advanceStage(_stagedrendering.RenderStage.Dynamic);
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
if (
|
|
2160
|
+
}
|
|
2161
|
+
});
|
|
2162
|
+
if (initialStageController.currentStage !== _stagedrendering.RenderStage.Abandoned) {
|
|
1950
2163
|
// No cache misses. We can use the result as-is.
|
|
1951
2164
|
return {
|
|
1952
|
-
stream:
|
|
1953
|
-
accumulatedChunksPromise:
|
|
1954
|
-
|
|
1955
|
-
|
|
2165
|
+
stream: initialStreamResult.stream,
|
|
2166
|
+
accumulatedChunksPromise: initialStreamResult.accumulatedChunksPromise,
|
|
2167
|
+
syncInterruptReason: initialStageController.getSyncInterruptReason(),
|
|
2168
|
+
startTime,
|
|
1956
2169
|
staticStageEndTime: initialStageController.getStaticStageEndTime(),
|
|
1957
2170
|
runtimeStageEndTime: initialStageController.getRuntimeStageEndTime(),
|
|
1958
2171
|
debugChannel,
|
|
1959
2172
|
requestStore
|
|
1960
2173
|
};
|
|
1961
2174
|
}
|
|
1962
|
-
if (process.env.
|
|
2175
|
+
if (process.env.__NEXT_DEV_SERVER && setCacheStatus) {
|
|
1963
2176
|
setCacheStatus('filling', htmlRequestId);
|
|
1964
2177
|
}
|
|
1965
2178
|
// Cache miss. We will use the initial render to fill caches, and discard its result.
|
|
@@ -1979,52 +2192,56 @@ async function renderWithRestartOnCacheMissInDev(ctx, initialRequestStore, creat
|
|
|
1979
2192
|
// We are going to render this pass all the way through because we've already
|
|
1980
2193
|
// filled any caches so we won't be aborting this time.
|
|
1981
2194
|
const abortSignal = null;
|
|
1982
|
-
const finalStageController = new _stagedrendering.StagedRenderingController(abortSignal,
|
|
2195
|
+
const finalStageController = new _stagedrendering.StagedRenderingController(abortSignal, null, true // track sync IO
|
|
2196
|
+
);
|
|
1983
2197
|
// We've filled the caches, so now we can render as usual,
|
|
1984
2198
|
// without any cache-filling mechanics.
|
|
1985
2199
|
requestStore.prerenderResumeDataCache = null;
|
|
1986
2200
|
requestStore.renderResumeDataCache = (0, _resumedatacache.createRenderResumeDataCache)(prerenderResumeDataCache);
|
|
1987
2201
|
requestStore.stagedRendering = finalStageController;
|
|
1988
2202
|
requestStore.cacheSignal = null;
|
|
1989
|
-
requestStore.asyncApiPromises =
|
|
2203
|
+
requestStore.asyncApiPromises = createAsyncApiPromises(finalStageController, requestStore.cookies, requestStore.mutableCookies, requestStore.headers);
|
|
1990
2204
|
// The initial render already wrote to its debug channel.
|
|
1991
2205
|
// We're not using it, so we need to create a new one.
|
|
1992
|
-
debugChannel = setReactDebugChannel && createDebugChannel();
|
|
2206
|
+
debugChannel = setReactDebugChannel && (0, _debugchannelserver.createDebugChannel)();
|
|
1993
2207
|
// Note: The stage controller starts out in the `Before` stage,
|
|
1994
2208
|
// where sync IO does not cause aborts, so it's okay if it happens before render.
|
|
1995
2209
|
const finalRscPayload = await getPayload(requestStore);
|
|
1996
|
-
const finalStreamResult = await
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2210
|
+
const finalStreamResult = await (0, _apprenderrenderutils.runInSequentialTasks)(()=>{
|
|
2211
|
+
finalStageController.advanceStage(_stagedrendering.RenderStage.EarlyStatic);
|
|
2212
|
+
startTime = performance.now() + performance.timeOrigin;
|
|
2213
|
+
const streamPair = _workunitasyncstorageexternal.workUnitAsyncStorage.run(requestStore, _streamops.renderToFlightStream, ComponentMod, finalRscPayload, clientModules, {
|
|
2214
|
+
onError,
|
|
2215
|
+
environmentName,
|
|
2216
|
+
startTime,
|
|
2217
|
+
filterStackFrame,
|
|
2218
|
+
debugChannel: debugChannel == null ? void 0 : debugChannel.serverSide
|
|
2219
|
+
}).tee();
|
|
2220
|
+
return {
|
|
2221
|
+
stream: streamPair[0],
|
|
2222
|
+
accumulatedChunksPromise: accumulateStreamChunks(streamPair[1], finalStageController, null)
|
|
2223
|
+
};
|
|
2224
|
+
}, ()=>{
|
|
2225
|
+
// Static stage
|
|
2226
|
+
finalStageController.advanceStage(_stagedrendering.RenderStage.Static);
|
|
2227
|
+
}, ()=>{
|
|
2228
|
+
// EarlyRuntime stage
|
|
2229
|
+
finalStageController.advanceStage(_stagedrendering.RenderStage.EarlyRuntime);
|
|
2230
|
+
}, ()=>{
|
|
2231
|
+
// Runtime stage
|
|
2232
|
+
finalStageController.advanceStage(_stagedrendering.RenderStage.Runtime);
|
|
2233
|
+
}, ()=>{
|
|
2234
|
+
// Dynamic stage
|
|
2235
|
+
finalStageController.advanceStage(_stagedrendering.RenderStage.Dynamic);
|
|
2236
|
+
});
|
|
2237
|
+
if (process.env.__NEXT_DEV_SERVER && setCacheStatus) {
|
|
2021
2238
|
setCacheStatus('filled', htmlRequestId);
|
|
2022
2239
|
}
|
|
2023
2240
|
return {
|
|
2024
2241
|
stream: finalStreamResult.stream,
|
|
2025
2242
|
accumulatedChunksPromise: finalStreamResult.accumulatedChunksPromise,
|
|
2026
|
-
|
|
2027
|
-
|
|
2243
|
+
syncInterruptReason: finalStageController.getSyncInterruptReason(),
|
|
2244
|
+
startTime,
|
|
2028
2245
|
staticStageEndTime: finalStageController.getStaticStageEndTime(),
|
|
2029
2246
|
runtimeStageEndTime: finalStageController.getRuntimeStageEndTime(),
|
|
2030
2247
|
debugChannel,
|
|
@@ -2062,9 +2279,11 @@ async function accumulateStreamChunks(stream, stageController, signal) {
|
|
|
2062
2279
|
enumerable: false,
|
|
2063
2280
|
configurable: true
|
|
2064
2281
|
});
|
|
2282
|
+
case _stagedrendering.RenderStage.EarlyStatic:
|
|
2065
2283
|
case _stagedrendering.RenderStage.Static:
|
|
2066
2284
|
staticChunks.push(value);
|
|
2067
2285
|
// fall through
|
|
2286
|
+
case _stagedrendering.RenderStage.EarlyRuntime:
|
|
2068
2287
|
case _stagedrendering.RenderStage.Runtime:
|
|
2069
2288
|
runtimeChunks.push(value);
|
|
2070
2289
|
// fall through
|
|
@@ -2078,8 +2297,13 @@ async function accumulateStreamChunks(stream, stageController, signal) {
|
|
|
2078
2297
|
break;
|
|
2079
2298
|
}
|
|
2080
2299
|
}
|
|
2081
|
-
} catch
|
|
2082
|
-
|
|
2300
|
+
} catch (err) {
|
|
2301
|
+
// When we cancel the reader we may reject the read.
|
|
2302
|
+
// Only swallow errors caused by our intentional cancel();
|
|
2303
|
+
// re-throw unexpected errors to avoid silently returning partial data.
|
|
2304
|
+
if (!cancelled) {
|
|
2305
|
+
throw err;
|
|
2306
|
+
}
|
|
2083
2307
|
}
|
|
2084
2308
|
return {
|
|
2085
2309
|
staticChunks,
|
|
@@ -2087,47 +2311,43 @@ async function accumulateStreamChunks(stream, stageController, signal) {
|
|
|
2087
2311
|
dynamicChunks
|
|
2088
2312
|
};
|
|
2089
2313
|
}
|
|
2090
|
-
function
|
|
2314
|
+
async function countStaticStageBytes(stream, stageController) {
|
|
2315
|
+
let byteLength = 0;
|
|
2316
|
+
const reader = stream.getReader();
|
|
2317
|
+
stageController.onStage(_stagedrendering.RenderStage.EarlyRuntime, ()=>{
|
|
2318
|
+
reader.cancel();
|
|
2319
|
+
});
|
|
2320
|
+
while(true){
|
|
2321
|
+
const { done, value } = await reader.read();
|
|
2322
|
+
if (done) {
|
|
2323
|
+
break;
|
|
2324
|
+
}
|
|
2325
|
+
if (stageController.currentStage <= _stagedrendering.RenderStage.Static) {
|
|
2326
|
+
byteLength += value.byteLength;
|
|
2327
|
+
} else {
|
|
2328
|
+
reader.cancel();
|
|
2329
|
+
break;
|
|
2330
|
+
}
|
|
2331
|
+
}
|
|
2332
|
+
return byteLength;
|
|
2333
|
+
}
|
|
2334
|
+
function createAsyncApiPromises(stagedRendering, cookies, mutableCookies, headers) {
|
|
2091
2335
|
return {
|
|
2092
|
-
// Runtime APIs
|
|
2336
|
+
// Runtime APIs (for prefetch segments)
|
|
2093
2337
|
cookies: stagedRendering.delayUntilStage(_stagedrendering.RenderStage.Runtime, 'cookies', cookies),
|
|
2338
|
+
earlyCookies: stagedRendering.delayUntilStage(_stagedrendering.RenderStage.EarlyRuntime, 'cookies', cookies),
|
|
2094
2339
|
mutableCookies: stagedRendering.delayUntilStage(_stagedrendering.RenderStage.Runtime, 'cookies', mutableCookies),
|
|
2340
|
+
earlyMutableCookies: stagedRendering.delayUntilStage(_stagedrendering.RenderStage.EarlyRuntime, 'cookies', mutableCookies),
|
|
2095
2341
|
headers: stagedRendering.delayUntilStage(_stagedrendering.RenderStage.Runtime, 'headers', headers),
|
|
2342
|
+
earlyHeaders: stagedRendering.delayUntilStage(_stagedrendering.RenderStage.EarlyRuntime, 'headers', headers),
|
|
2096
2343
|
// These are not used directly, but we chain other `params`/`searchParams` promises off of them.
|
|
2097
2344
|
sharedParamsParent: stagedRendering.delayUntilStage(_stagedrendering.RenderStage.Runtime, undefined, '<internal params>'),
|
|
2345
|
+
earlySharedParamsParent: stagedRendering.delayUntilStage(_stagedrendering.RenderStage.EarlyRuntime, undefined, '<internal params>'),
|
|
2098
2346
|
sharedSearchParamsParent: stagedRendering.delayUntilStage(_stagedrendering.RenderStage.Runtime, undefined, '<internal searchParams>'),
|
|
2347
|
+
earlySharedSearchParamsParent: stagedRendering.delayUntilStage(_stagedrendering.RenderStage.EarlyRuntime, undefined, '<internal searchParams>'),
|
|
2099
2348
|
connection: stagedRendering.delayUntilStage(_stagedrendering.RenderStage.Dynamic, 'connection', undefined)
|
|
2100
2349
|
};
|
|
2101
2350
|
}
|
|
2102
|
-
function createDebugChannel() {
|
|
2103
|
-
if (process.env.NODE_ENV === 'production') {
|
|
2104
|
-
return undefined;
|
|
2105
|
-
}
|
|
2106
|
-
let readableController;
|
|
2107
|
-
let clientSideReadable = new ReadableStream({
|
|
2108
|
-
start (controller) {
|
|
2109
|
-
readableController = controller;
|
|
2110
|
-
}
|
|
2111
|
-
});
|
|
2112
|
-
return {
|
|
2113
|
-
serverSide: {
|
|
2114
|
-
writable: new WritableStream({
|
|
2115
|
-
write (chunk) {
|
|
2116
|
-
readableController == null ? void 0 : readableController.enqueue(chunk);
|
|
2117
|
-
},
|
|
2118
|
-
close () {
|
|
2119
|
-
readableController == null ? void 0 : readableController.close();
|
|
2120
|
-
},
|
|
2121
|
-
abort (err) {
|
|
2122
|
-
readableController == null ? void 0 : readableController.error(err);
|
|
2123
|
-
}
|
|
2124
|
-
})
|
|
2125
|
-
},
|
|
2126
|
-
clientSide: {
|
|
2127
|
-
readable: clientSideReadable
|
|
2128
|
-
}
|
|
2129
|
-
};
|
|
2130
|
-
}
|
|
2131
2351
|
/**
|
|
2132
2352
|
* Logs the given messages, and sends the error instances to the browser as an
|
|
2133
2353
|
* RSC stream, where they can be deserialized and logged (or otherwise presented
|
|
@@ -2136,7 +2356,7 @@ function createDebugChannel() {
|
|
|
2136
2356
|
* server modules that allow users to inspect the server source code in the
|
|
2137
2357
|
* browser.
|
|
2138
2358
|
*/ async function logMessagesAndSendErrorsToBrowser(messages, ctx) {
|
|
2139
|
-
const {
|
|
2359
|
+
const { htmlRequestId, renderOpts } = ctx;
|
|
2140
2360
|
const { sendErrorsToBrowser } = renderOpts;
|
|
2141
2361
|
const errors = [];
|
|
2142
2362
|
for (const message of messages){
|
|
@@ -2163,11 +2383,64 @@ function createDebugChannel() {
|
|
|
2163
2383
|
configurable: true
|
|
2164
2384
|
});
|
|
2165
2385
|
}
|
|
2386
|
+
// Build a Map of error → error code for errors that have one.
|
|
2387
|
+
// React doesn't revive __NEXT_ERROR_CODE during RSC deserialization, so we
|
|
2388
|
+
// send it as a side-channel Map. RSC preserves object identity, so the
|
|
2389
|
+
// deserialized Map keys will reference the same Error objects.
|
|
2390
|
+
const errorCodes = new Map();
|
|
2391
|
+
for (const err of errors){
|
|
2392
|
+
const code = (0, _errortelemetryutils.extractNextErrorCode)(err);
|
|
2393
|
+
if (code !== undefined) {
|
|
2394
|
+
errorCodes.set(err, code);
|
|
2395
|
+
}
|
|
2396
|
+
}
|
|
2166
2397
|
const { clientModules } = (0, _manifestssingleton.getClientReferenceManifest)();
|
|
2167
|
-
const
|
|
2398
|
+
const errorsFlightStream = (0, _streamops.renderToFlightStream)(ctx.componentMod, {
|
|
2399
|
+
errors,
|
|
2400
|
+
errorCodes
|
|
2401
|
+
}, clientModules, {
|
|
2168
2402
|
filterStackFrame
|
|
2169
2403
|
});
|
|
2170
|
-
sendErrorsToBrowser(
|
|
2404
|
+
sendErrorsToBrowser(errorsFlightStream, htmlRequestId);
|
|
2405
|
+
}
|
|
2406
|
+
}
|
|
2407
|
+
function logValidationSkipped(ctx) {
|
|
2408
|
+
if (process.env.__NEXT_TEST_MODE && process.env.NEXT_TEST_LOG_VALIDATION) {
|
|
2409
|
+
const requestId = ctx.requestId;
|
|
2410
|
+
const url = ctx.url.href;
|
|
2411
|
+
console.log('<VALIDATION_MESSAGE>' + JSON.stringify({
|
|
2412
|
+
type: 'validation_start',
|
|
2413
|
+
requestId,
|
|
2414
|
+
url
|
|
2415
|
+
}) + '</VALIDATION_MESSAGE>');
|
|
2416
|
+
console.log('<VALIDATION_MESSAGE>' + JSON.stringify({
|
|
2417
|
+
type: 'validation_end',
|
|
2418
|
+
requestId,
|
|
2419
|
+
url
|
|
2420
|
+
}) + '</VALIDATION_MESSAGE>');
|
|
2421
|
+
}
|
|
2422
|
+
}
|
|
2423
|
+
async function spawnStaticShellValidationInDev(...args) {
|
|
2424
|
+
if (process.env.__NEXT_TEST_MODE && process.env.NEXT_TEST_LOG_VALIDATION) {
|
|
2425
|
+
const ctx = args[5];
|
|
2426
|
+
const requestId = ctx.requestId;
|
|
2427
|
+
const url = ctx.url.href;
|
|
2428
|
+
console.log('<VALIDATION_MESSAGE>' + JSON.stringify({
|
|
2429
|
+
type: 'validation_start',
|
|
2430
|
+
requestId,
|
|
2431
|
+
url
|
|
2432
|
+
}) + '</VALIDATION_MESSAGE>');
|
|
2433
|
+
try {
|
|
2434
|
+
return await spawnStaticShellValidationInDevImpl(...args);
|
|
2435
|
+
} finally{
|
|
2436
|
+
console.log('<VALIDATION_MESSAGE>' + JSON.stringify({
|
|
2437
|
+
type: 'validation_end',
|
|
2438
|
+
requestId,
|
|
2439
|
+
url
|
|
2440
|
+
}) + '</VALIDATION_MESSAGE>');
|
|
2441
|
+
}
|
|
2442
|
+
} else {
|
|
2443
|
+
return await spawnStaticShellValidationInDevImpl(...args);
|
|
2171
2444
|
}
|
|
2172
2445
|
}
|
|
2173
2446
|
/**
|
|
@@ -2175,11 +2448,13 @@ function createDebugChannel() {
|
|
|
2175
2448
|
* While it doesn't return a stream we want it to have identical
|
|
2176
2449
|
* prerender semantics to prerenderToStream and should update it
|
|
2177
2450
|
* in conjunction with any changes to that function.
|
|
2178
|
-
*/ async function
|
|
2451
|
+
*/ async function spawnStaticShellValidationInDevImpl(accumulatedChunksPromise, syncInterruptReason, startTime, staticStageEndTime, runtimeStageEndTime, ctx, requestStore, fallbackRouteParams, debugChannelClient) {
|
|
2452
|
+
const debug = process.env.NEXT_PRIVATE_DEBUG_VALIDATION === '1' ? console.log : undefined;
|
|
2179
2453
|
const { componentMod: ComponentMod, getDynamicParamFromSegment, renderOpts, workStore } = ctx;
|
|
2180
|
-
const
|
|
2181
|
-
const
|
|
2182
|
-
const
|
|
2454
|
+
const loaderTree = ComponentMod.routeModule.userland.loaderTree;
|
|
2455
|
+
const allowEmptyStaticShell = (renderOpts.allowEmptyStaticShell ?? false) || await (0, _instantconfig.isPageAllowedToBlock)(loaderTree);
|
|
2456
|
+
const rootParams = (0, _createcomponenttree.getRootParams)(loaderTree, getDynamicParamFromSegment);
|
|
2457
|
+
const hmrRefreshHash = (0, _workunitasyncstorageexternal.getHmrRefreshHash)(requestStore);
|
|
2183
2458
|
// We don't need to continue the prerender process if we already
|
|
2184
2459
|
// detected invalid dynamic usage in the initial prerender phase.
|
|
2185
2460
|
const { invalidDynamicUsageError } = workStore;
|
|
@@ -2188,36 +2463,55 @@ function createDebugChannel() {
|
|
|
2188
2463
|
invalidDynamicUsageError
|
|
2189
2464
|
], ctx);
|
|
2190
2465
|
}
|
|
2191
|
-
if (
|
|
2192
|
-
return logMessagesAndSendErrorsToBrowser([
|
|
2193
|
-
staticInterruptReason
|
|
2194
|
-
], ctx);
|
|
2195
|
-
}
|
|
2196
|
-
if (runtimeInterruptReason) {
|
|
2466
|
+
if (syncInterruptReason) {
|
|
2197
2467
|
return logMessagesAndSendErrorsToBrowser([
|
|
2198
|
-
|
|
2468
|
+
syncInterruptReason
|
|
2199
2469
|
], ctx);
|
|
2200
2470
|
}
|
|
2201
|
-
const { staticChunks, runtimeChunks, dynamicChunks } = await accumulatedChunksPromise;
|
|
2202
|
-
// First we warmup SSR with the runtime chunks. This ensures that when we do
|
|
2203
|
-
// the full prerender pass with dynamic tracking module loading won't
|
|
2204
|
-
// interrupt the prerender and can properly observe the entire content
|
|
2205
|
-
await warmupModuleCacheForRuntimeValidationInDev(runtimeChunks, dynamicChunks, rootParams, fallbackRouteParams, allowEmptyStaticShell, ctx);
|
|
2206
2471
|
let debugChunks = null;
|
|
2207
2472
|
if (debugChannelClient) {
|
|
2208
2473
|
debugChunks = [];
|
|
2209
|
-
debugChannelClient.on('data', (c)=>
|
|
2474
|
+
debugChannelClient.on('data', (c)=>{
|
|
2475
|
+
debugChunks.push(c);
|
|
2476
|
+
});
|
|
2210
2477
|
}
|
|
2478
|
+
const accumulatedChunks = await accumulatedChunksPromise;
|
|
2479
|
+
const { staticChunks, runtimeChunks, dynamicChunks } = accumulatedChunks;
|
|
2480
|
+
const needsInstantValidation = await (0, _instantconfig.anySegmentNeedsInstantValidationInDev)(loaderTree);
|
|
2481
|
+
// `samples` from instant config are only used during build
|
|
2482
|
+
const validationSamples = null;
|
|
2483
|
+
const validationSampleTracking = null;
|
|
2484
|
+
// First we warmup SSR with the runtime chunks. This ensures that when we do
|
|
2485
|
+
// the full prerender pass with dynamic tracking module loading won't
|
|
2486
|
+
// interrupt the prerender and can properly observe the entire content
|
|
2487
|
+
await warmupClientModulesForStagedValidation(// if we're going to be validating prefetches, we'll be rendering some segments in the dynamic stage.
|
|
2488
|
+
// otherwise, for static shell validation, we only need to warm up to the runtime stage.
|
|
2489
|
+
// we also need to use a different store type, because instant validation allows more APIs to resolve.
|
|
2490
|
+
needsInstantValidation ? 'validation-client' : 'prerender-client', needsInstantValidation ? dynamicChunks : runtimeChunks, dynamicChunks, rootParams, fallbackRouteParams, allowEmptyStaticShell, ctx, validationSamples, validationSampleTracking);
|
|
2491
|
+
debug == null ? void 0 : debug(`Starting static shell validation...`);
|
|
2211
2492
|
const runtimeResult = await validateStagedShell(runtimeChunks, dynamicChunks, debugChunks, runtimeStageEndTime, rootParams, fallbackRouteParams, allowEmptyStaticShell, ctx, hmrRefreshHash, _dynamicrendering.trackDynamicHoleInRuntimeShell);
|
|
2212
2493
|
if (runtimeResult.length > 0) {
|
|
2494
|
+
debug == null ? void 0 : debug(`❌ Failed - ${runtimeResult.length} errors from runtime stage`);
|
|
2213
2495
|
// We have something to report from the runtime validation
|
|
2214
|
-
// We can skip the
|
|
2496
|
+
// We can skip the rest
|
|
2215
2497
|
return logMessagesAndSendErrorsToBrowser(runtimeResult, ctx);
|
|
2216
2498
|
}
|
|
2217
2499
|
const staticResult = await validateStagedShell(staticChunks, dynamicChunks, debugChunks, staticStageEndTime, rootParams, fallbackRouteParams, allowEmptyStaticShell, ctx, hmrRefreshHash, _dynamicrendering.trackDynamicHoleInStaticShell);
|
|
2218
|
-
|
|
2500
|
+
if (staticResult.length > 0) {
|
|
2501
|
+
debug == null ? void 0 : debug(`❌ Failed - ${staticResult.length} errors from static stage`);
|
|
2502
|
+
// We have something to report from the static validation
|
|
2503
|
+
// We can skip the rest
|
|
2504
|
+
return logMessagesAndSendErrorsToBrowser(staticResult, ctx);
|
|
2505
|
+
}
|
|
2506
|
+
debug == null ? void 0 : debug(`✅ Passed`);
|
|
2507
|
+
if (needsInstantValidation) {
|
|
2508
|
+
const instantConfigsResult = await validateInstantConfigs(accumulatedChunks, debugChunks, startTime, rootParams, fallbackRouteParams, ctx, hmrRefreshHash, validationSamples);
|
|
2509
|
+
if (instantConfigsResult.length > 0) {
|
|
2510
|
+
return logMessagesAndSendErrorsToBrowser(instantConfigsResult, ctx);
|
|
2511
|
+
}
|
|
2512
|
+
}
|
|
2219
2513
|
}
|
|
2220
|
-
async function
|
|
2514
|
+
async function warmupClientModulesForStagedValidation(storeType, partialServerChunks, allServerChunks, rootParams, fallbackRouteParams, allowEmptyStaticShell, ctx, validationSamples, validationSampleTracking) {
|
|
2221
2515
|
const { implicitTags, nonce, workStore } = ctx;
|
|
2222
2516
|
// Warmup SSR
|
|
2223
2517
|
const initialClientPrerenderController = new AbortController();
|
|
@@ -2225,35 +2519,73 @@ async function warmupModuleCacheForRuntimeValidationInDev(runtimeServerChunks, a
|
|
|
2225
2519
|
const initialClientRenderController = new AbortController();
|
|
2226
2520
|
const preinitScripts = ()=>{};
|
|
2227
2521
|
const { ServerInsertedHTMLProvider } = (0, _serverinsertedhtml.createServerInsertedHTML)();
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2522
|
+
let initialClientPrerenderStore;
|
|
2523
|
+
if (storeType === 'prerender-client') {
|
|
2524
|
+
const store = {
|
|
2525
|
+
type: 'prerender-client',
|
|
2526
|
+
phase: 'render',
|
|
2527
|
+
rootParams,
|
|
2528
|
+
fallbackRouteParams,
|
|
2529
|
+
implicitTags,
|
|
2530
|
+
renderSignal: initialClientRenderController.signal,
|
|
2531
|
+
controller: initialClientPrerenderController,
|
|
2532
|
+
// For HTML Generation the only cache tracked activity
|
|
2533
|
+
// is module loading, which has it's own cache signal
|
|
2534
|
+
cacheSignal: null,
|
|
2535
|
+
dynamicTracking: null,
|
|
2536
|
+
allowEmptyStaticShell,
|
|
2537
|
+
revalidate: _constants1.INFINITE_CACHE,
|
|
2538
|
+
expire: _constants1.INFINITE_CACHE,
|
|
2539
|
+
stale: _constants1.INFINITE_CACHE,
|
|
2540
|
+
tags: [
|
|
2541
|
+
...implicitTags.tags
|
|
2542
|
+
],
|
|
2543
|
+
// TODO should this be removed from client stores?
|
|
2544
|
+
prerenderResumeDataCache: null,
|
|
2545
|
+
renderResumeDataCache: null,
|
|
2546
|
+
hmrRefreshHash: undefined,
|
|
2547
|
+
// Client prerenders don't track server param access
|
|
2548
|
+
varyParamsAccumulator: null
|
|
2549
|
+
};
|
|
2550
|
+
initialClientPrerenderStore = store;
|
|
2551
|
+
} else {
|
|
2552
|
+
const store = {
|
|
2553
|
+
type: 'validation-client',
|
|
2554
|
+
phase: 'render',
|
|
2555
|
+
rootParams,
|
|
2556
|
+
implicitTags,
|
|
2557
|
+
renderSignal: initialClientRenderController.signal,
|
|
2558
|
+
controller: initialClientPrerenderController,
|
|
2559
|
+
// For HTML Generation the only cache tracked activity
|
|
2560
|
+
// is module loading, which has it's own cache signal
|
|
2561
|
+
cacheSignal: null,
|
|
2562
|
+
dynamicTracking: null,
|
|
2563
|
+
revalidate: _constants1.INFINITE_CACHE,
|
|
2564
|
+
expire: _constants1.INFINITE_CACHE,
|
|
2565
|
+
stale: _constants1.INFINITE_CACHE,
|
|
2566
|
+
tags: [
|
|
2567
|
+
...implicitTags.tags
|
|
2568
|
+
],
|
|
2569
|
+
// TODO should this be removed from client stores?
|
|
2570
|
+
prerenderResumeDataCache: null,
|
|
2571
|
+
renderResumeDataCache: null,
|
|
2572
|
+
hmrRefreshHash: undefined,
|
|
2573
|
+
// Client prerenders don't track server param access
|
|
2574
|
+
varyParamsAccumulator: null,
|
|
2575
|
+
// We're not rendering any validation boundaries yet.
|
|
2576
|
+
boundaryState: null,
|
|
2577
|
+
validationSamples,
|
|
2578
|
+
validationSampleTracking,
|
|
2579
|
+
fallbackRouteParams
|
|
2580
|
+
};
|
|
2581
|
+
initialClientPrerenderStore = store;
|
|
2582
|
+
}
|
|
2583
|
+
// TODO: maybe conditionally switch between runtime chunks and all chunks?
|
|
2584
|
+
// but warming too much should always be fine, just not always necessary
|
|
2585
|
+
const serverStream = (0, _streamutils.createNodeStreamWithLateRelease)(partialServerChunks, allServerChunks, initialClientReactController.signal);
|
|
2586
|
+
const pendingInitialClientResult = _workunitasyncstorageexternal.workUnitAsyncStorage.run(initialClientPrerenderStore, _streamops.getClientPrerender, // eslint-disable-next-line @next/internal/no-ambiguous-jsx -- React Client
|
|
2255
2587
|
/*#__PURE__*/ (0, _jsxruntime.jsx)(App, {
|
|
2256
|
-
reactServerStream:
|
|
2588
|
+
reactServerStream: serverStream,
|
|
2257
2589
|
reactDebugStream: undefined,
|
|
2258
2590
|
debugEndTime: undefined,
|
|
2259
2591
|
preinitScripts: preinitScripts,
|
|
@@ -2334,15 +2666,16 @@ async function validateStagedShell(stageChunks, allServerChunks, debugChunks, de
|
|
|
2334
2666
|
// TODO should this be removed from client stores?
|
|
2335
2667
|
prerenderResumeDataCache: null,
|
|
2336
2668
|
renderResumeDataCache: null,
|
|
2337
|
-
hmrRefreshHash
|
|
2669
|
+
hmrRefreshHash,
|
|
2670
|
+
// Client prerenders don't track server param access
|
|
2671
|
+
varyParamsAccumulator: null
|
|
2338
2672
|
};
|
|
2339
|
-
|
|
2340
|
-
const serverStream =
|
|
2341
|
-
const debugChannelClient = debugChunks ?
|
|
2342
|
-
const prerender = require('react-dom/static').prerender;
|
|
2673
|
+
const dynamicValidation = (0, _dynamicrendering.createDynamicValidationState)();
|
|
2674
|
+
const serverStream = (0, _streamutils.createNodeStreamWithLateRelease)(stageChunks, allServerChunks, clientReactController.signal);
|
|
2675
|
+
const debugChannelClient = debugChunks ? (0, _streamutils.createNodeStreamWithLateRelease)(debugChunks, debugChunks, clientReactController.signal) : undefined;
|
|
2343
2676
|
try {
|
|
2344
|
-
let { prelude: unprocessedPrelude } = await (0,
|
|
2345
|
-
const pendingFinalClientResult = _workunitasyncstorageexternal.workUnitAsyncStorage.run(finalClientPrerenderStore,
|
|
2677
|
+
let { prelude: unprocessedPrelude } = await (0, _apprenderrenderutils.runInSequentialTasks)(()=>{
|
|
2678
|
+
const pendingFinalClientResult = _workunitasyncstorageexternal.workUnitAsyncStorage.run(finalClientPrerenderStore, _streamops.getClientPrerender, // eslint-disable-next-line @next/internal/no-ambiguous-jsx -- React Client
|
|
2346
2679
|
/*#__PURE__*/ (0, _jsxruntime.jsx)(App, {
|
|
2347
2680
|
reactServerStream: serverStream,
|
|
2348
2681
|
reactDebugStream: debugChannelClient,
|
|
@@ -2357,7 +2690,7 @@ async function validateStagedShell(stageChunks, allServerChunks, debugChunks, de
|
|
|
2357
2690
|
if ((0, _dynamicrendering.isPrerenderInterruptedError)(err) || clientReactController.signal.aborted) {
|
|
2358
2691
|
const componentStack = errorInfo.componentStack;
|
|
2359
2692
|
if (typeof componentStack === 'string') {
|
|
2360
|
-
trackDynamicHole(workStore, componentStack,
|
|
2693
|
+
trackDynamicHole(workStore, componentStack, dynamicValidation, clientDynamicTracking);
|
|
2361
2694
|
}
|
|
2362
2695
|
return;
|
|
2363
2696
|
}
|
|
@@ -2381,18 +2714,624 @@ async function validateStagedShell(stageChunks, allServerChunks, debugChunks, de
|
|
|
2381
2714
|
}, ()=>{
|
|
2382
2715
|
clientReactController.abort();
|
|
2383
2716
|
});
|
|
2384
|
-
const { preludeIsEmpty } = await (0,
|
|
2385
|
-
return (0, _dynamicrendering.getStaticShellDisallowedDynamicReasons)(workStore, preludeIsEmpty ? _dynamicrendering.PreludeState.Empty : _dynamicrendering.PreludeState.Full,
|
|
2717
|
+
const { preludeIsEmpty } = await (0, _streamops.processPrelude)(unprocessedPrelude);
|
|
2718
|
+
return (0, _dynamicrendering.getStaticShellDisallowedDynamicReasons)(workStore, preludeIsEmpty ? _dynamicrendering.PreludeState.Empty : _dynamicrendering.PreludeState.Full, dynamicValidation, // TODO(instant-validation): if allowEmptyStaticShell is true (likely due to blocking configs),
|
|
2719
|
+
// we should probably just skip this altogether
|
|
2720
|
+
allowEmptyStaticShell);
|
|
2386
2721
|
} catch (thrownValue) {
|
|
2387
2722
|
// Even if the root errors we still want to report any cache components errors
|
|
2388
2723
|
// that were discovered before the root errored.
|
|
2389
|
-
let errors = (0, _dynamicrendering.getStaticShellDisallowedDynamicReasons)(workStore, _dynamicrendering.PreludeState.Errored,
|
|
2724
|
+
let errors = (0, _dynamicrendering.getStaticShellDisallowedDynamicReasons)(workStore, _dynamicrendering.PreludeState.Errored, dynamicValidation, // TODO(instant-validation): if allowEmptyStaticShell is true (likely due to blocking configs),
|
|
2725
|
+
// we should probably just skip this altogether
|
|
2726
|
+
allowEmptyStaticShell);
|
|
2390
2727
|
if (process.env.NEXT_DEBUG_BUILD || process.env.__NEXT_VERBOSE_LOGGING) {
|
|
2391
2728
|
errors.unshift('During dynamic validation the root of the page errored. The next logged error is the thrown value. It may be a duplicate of errors reported during the normal development mode render.', thrownValue);
|
|
2392
2729
|
}
|
|
2393
2730
|
return errors;
|
|
2394
2731
|
}
|
|
2395
2732
|
}
|
|
2733
|
+
/**
|
|
2734
|
+
* Validates instant configs by iterating URL depths from deepest to
|
|
2735
|
+
* shallowest. At each depth, builds a combined payload where segments
|
|
2736
|
+
* above the boundary use Dynamic stage (already mounted) and segments
|
|
2737
|
+
* below use Static/Runtime stage (being prefetched). If the new subtree
|
|
2738
|
+
* contains any `unstable_instant` configs, the payload is rendered to
|
|
2739
|
+
* detect dynamic holes without Suspense.
|
|
2740
|
+
*/ async function validateInstantConfigs(accumulatedChunks, debugChunks, startTime, rootParams, fallbackRouteParams, ctx, hmrRefreshHash, validationSamples) {
|
|
2741
|
+
const debug = process.env.NEXT_PRIVATE_DEBUG_VALIDATION === '1' ? console.log : undefined;
|
|
2742
|
+
const { createCombinedPayloadAtDepth, createCombinedPayloadStream, collectStagedSegmentData, discoverValidationDepths } = ctx.componentMod.InstantValidation();
|
|
2743
|
+
const { createValidationSampleTracking } = require('./instant-validation/instant-samples');
|
|
2744
|
+
debug == null ? void 0 : debug('\nStarting depth-based instant validation...');
|
|
2745
|
+
const loaderTree = ctx.componentMod.routeModule.userland.loaderTree;
|
|
2746
|
+
// Only affects a debug environment name label, not functional behavior.
|
|
2747
|
+
const hasRuntimePrefetch = true;
|
|
2748
|
+
const clientReferenceManifest = (0, _manifestssingleton.getClientReferenceManifest)();
|
|
2749
|
+
const { cache, payload: initialRscPayload, stageEndTimes } = await collectStagedSegmentData({
|
|
2750
|
+
[_stagedrendering.RenderStage.Static]: accumulatedChunks.staticChunks,
|
|
2751
|
+
[_stagedrendering.RenderStage.Runtime]: accumulatedChunks.runtimeChunks,
|
|
2752
|
+
[_stagedrendering.RenderStage.Dynamic]: accumulatedChunks.dynamicChunks
|
|
2753
|
+
}, debugChunks, startTime, hasRuntimePrefetch, clientReferenceManifest);
|
|
2754
|
+
const { implicitTags, nonce, workStore } = ctx;
|
|
2755
|
+
const isDebugChannelEnabled = !!ctx.renderOpts.setReactDebugChannel;
|
|
2756
|
+
/**
|
|
2757
|
+
* Build and validate a combined payload at the given URL depth.
|
|
2758
|
+
*
|
|
2759
|
+
* Returns null if no instant config exists at this depth.
|
|
2760
|
+
* Returns an empty array if validation passed.
|
|
2761
|
+
* Returns a non-empty array of errors if validation failed.
|
|
2762
|
+
*
|
|
2763
|
+
* When the initial validation uses static segments and finds errors,
|
|
2764
|
+
* automatically retries with runtime stages to discriminate between
|
|
2765
|
+
* runtime and dynamic errors, returning the more specific result.
|
|
2766
|
+
*/ async function validateAtDepth(depth, groupDepthForValidation) {
|
|
2767
|
+
return validateAtDepthImpl(depth, groupDepthForValidation, null);
|
|
2768
|
+
}
|
|
2769
|
+
async function validateAtDepthImpl(depth, groupDepthForValidation, previousBoundaryState) {
|
|
2770
|
+
const extraChunksController = new AbortController();
|
|
2771
|
+
const boundaryState = (0, _boundarytracking.createValidationBoundaryTracking)();
|
|
2772
|
+
let useRuntimeStageForPartialSegments = false;
|
|
2773
|
+
if (previousBoundaryState) {
|
|
2774
|
+
// We're doing a followup render to better discriminate error types
|
|
2775
|
+
useRuntimeStageForPartialSegments = true;
|
|
2776
|
+
for (const id of previousBoundaryState.expectedIds){
|
|
2777
|
+
boundaryState.expectedIds.add(id);
|
|
2778
|
+
}
|
|
2779
|
+
}
|
|
2780
|
+
const payloadResult = await createCombinedPayloadAtDepth(initialRscPayload, cache, loaderTree, ctx.getDynamicParamFromSegment, ctx.query, depth, groupDepthForValidation, extraChunksController.signal, boundaryState, clientReferenceManifest, stageEndTimes, useRuntimeStageForPartialSegments);
|
|
2781
|
+
if (payloadResult === null) {
|
|
2782
|
+
return null;
|
|
2783
|
+
}
|
|
2784
|
+
const reactController = new AbortController();
|
|
2785
|
+
const renderController = new AbortController();
|
|
2786
|
+
const preinitScripts = ()=>{};
|
|
2787
|
+
const { ServerInsertedHTMLProvider } = (0, _serverinsertedhtml.createServerInsertedHTML)();
|
|
2788
|
+
const { stream: serverStream, debugStream } = await createCombinedPayloadStream(payloadResult.payload, extraChunksController, reactController.signal, clientReferenceManifest, startTime, isDebugChannelEnabled);
|
|
2789
|
+
const instantValidationState = (0, _dynamicrendering.createInstantValidationState)(payloadResult.createInstantStack);
|
|
2790
|
+
const validationSampleTracking = validationSamples !== null ? createValidationSampleTracking() : null;
|
|
2791
|
+
const clientDynamicTracking = (0, _dynamicrendering.createDynamicTrackingState)(false);
|
|
2792
|
+
const prerenderStore = {
|
|
2793
|
+
type: 'validation-client',
|
|
2794
|
+
phase: 'render',
|
|
2795
|
+
rootParams,
|
|
2796
|
+
implicitTags,
|
|
2797
|
+
renderSignal: renderController.signal,
|
|
2798
|
+
controller: reactController,
|
|
2799
|
+
cacheSignal: null,
|
|
2800
|
+
dynamicTracking: clientDynamicTracking,
|
|
2801
|
+
revalidate: _constants1.INFINITE_CACHE,
|
|
2802
|
+
expire: _constants1.INFINITE_CACHE,
|
|
2803
|
+
stale: _constants1.INFINITE_CACHE,
|
|
2804
|
+
tags: [
|
|
2805
|
+
...implicitTags.tags
|
|
2806
|
+
],
|
|
2807
|
+
prerenderResumeDataCache: null,
|
|
2808
|
+
renderResumeDataCache: null,
|
|
2809
|
+
hmrRefreshHash,
|
|
2810
|
+
varyParamsAccumulator: null,
|
|
2811
|
+
boundaryState,
|
|
2812
|
+
fallbackRouteParams,
|
|
2813
|
+
validationSamples,
|
|
2814
|
+
validationSampleTracking
|
|
2815
|
+
};
|
|
2816
|
+
let errors;
|
|
2817
|
+
try {
|
|
2818
|
+
const { prelude: unprocessedPrelude } = await (0, _apprenderrenderutils.runInSequentialTasks)(()=>{
|
|
2819
|
+
const pendingResult = _workunitasyncstorageexternal.workUnitAsyncStorage.run(prerenderStore, _streamops.getClientPrerender, // eslint-disable-next-line @next/internal/no-ambiguous-jsx -- React Client
|
|
2820
|
+
/*#__PURE__*/ (0, _jsxruntime.jsx)(App, {
|
|
2821
|
+
reactServerStream: serverStream,
|
|
2822
|
+
reactDebugStream: debugStream ?? undefined,
|
|
2823
|
+
debugEndTime: undefined,
|
|
2824
|
+
preinitScripts: preinitScripts,
|
|
2825
|
+
ServerInsertedHTMLProvider: ServerInsertedHTMLProvider,
|
|
2826
|
+
nonce: nonce,
|
|
2827
|
+
images: ctx.renderOpts.images
|
|
2828
|
+
}), {
|
|
2829
|
+
signal: reactController.signal,
|
|
2830
|
+
onError: (err, errorInfo)=>{
|
|
2831
|
+
if ((0, _dynamicrendering.isPrerenderInterruptedError)(err) || reactController.signal.aborted) {
|
|
2832
|
+
const componentStack = errorInfo.componentStack;
|
|
2833
|
+
if (typeof componentStack === 'string') {
|
|
2834
|
+
(0, _dynamicrendering.trackDynamicHoleInNavigation)(workStore, componentStack, instantValidationState, clientDynamicTracking, payloadResult.hasAmbiguousErrors ? _dynamicrendering.DynamicHoleKind.Runtime : _dynamicrendering.DynamicHoleKind.Dynamic, boundaryState);
|
|
2835
|
+
}
|
|
2836
|
+
return;
|
|
2837
|
+
} else if (!reactController.signal.aborted) {
|
|
2838
|
+
const componentStack = errorInfo.componentStack;
|
|
2839
|
+
if (typeof componentStack === 'string') {
|
|
2840
|
+
let errorForDisplay = err;
|
|
2841
|
+
if (process.env.NODE_ENV === 'production') {
|
|
2842
|
+
// In production (i.e. build validation), Flight omits everything except the digest
|
|
2843
|
+
// when serializing errors, which makes them very unfriendly for debugging.
|
|
2844
|
+
// Map the deserialized errors back to their original error object to make it more useful.
|
|
2845
|
+
if (err && typeof err === 'object' && 'digest' in err && typeof err.digest === 'string') {
|
|
2846
|
+
const serverError = workStore.reactServerErrorsByDigest.get(err.digest);
|
|
2847
|
+
if (serverError !== undefined) {
|
|
2848
|
+
errorForDisplay = serverError;
|
|
2849
|
+
}
|
|
2850
|
+
}
|
|
2851
|
+
}
|
|
2852
|
+
(0, _dynamicrendering.trackThrownErrorInNavigation)(workStore, instantValidationState, errorForDisplay, componentStack);
|
|
2853
|
+
}
|
|
2854
|
+
}
|
|
2855
|
+
if ((0, _reactlargeshellerror.isReactLargeShellError)(err)) {
|
|
2856
|
+
console.error(err);
|
|
2857
|
+
return undefined;
|
|
2858
|
+
}
|
|
2859
|
+
return (0, _createerrorhandler.getDigestForWellKnownError)(err);
|
|
2860
|
+
}
|
|
2861
|
+
});
|
|
2862
|
+
reactController.signal.addEventListener('abort', ()=>{
|
|
2863
|
+
renderController.abort();
|
|
2864
|
+
}, {
|
|
2865
|
+
once: true
|
|
2866
|
+
});
|
|
2867
|
+
return pendingResult;
|
|
2868
|
+
}, ()=>{
|
|
2869
|
+
reactController.abort();
|
|
2870
|
+
});
|
|
2871
|
+
const { preludeIsEmpty } = await (0, _streamops.processPrelude)(unprocessedPrelude);
|
|
2872
|
+
errors = (0, _dynamicrendering.getNavigationDisallowedDynamicReasons)(workStore, preludeIsEmpty ? _dynamicrendering.PreludeState.Empty : _dynamicrendering.PreludeState.Full, instantValidationState, validationSampleTracking, boundaryState);
|
|
2873
|
+
} catch (thrownValue) {
|
|
2874
|
+
errors = (0, _dynamicrendering.getNavigationDisallowedDynamicReasons)(workStore, _dynamicrendering.PreludeState.Errored, instantValidationState, validationSampleTracking, boundaryState);
|
|
2875
|
+
}
|
|
2876
|
+
// This prerender did not produce any errors
|
|
2877
|
+
if (errors.length === 0) {
|
|
2878
|
+
return [];
|
|
2879
|
+
}
|
|
2880
|
+
if (previousBoundaryState === null && payloadResult.hasAmbiguousErrors) {
|
|
2881
|
+
// This is the first validation attempt. we prepared a payload where dynamic holes might be runtime data dependencies
|
|
2882
|
+
// or dynamic data dependencies. We do a followup validation using a payload with only Runtime segments to discriminate
|
|
2883
|
+
const dynamicOnlyErrors = await validateAtDepthImpl(depth, groupDepthForValidation, boundaryState);
|
|
2884
|
+
if (dynamicOnlyErrors !== null && dynamicOnlyErrors.length > 0) {
|
|
2885
|
+
// The dynamic errors only validation found errors to report so we favor those
|
|
2886
|
+
return dynamicOnlyErrors;
|
|
2887
|
+
}
|
|
2888
|
+
}
|
|
2889
|
+
// If we didn't return some other errors at this point the only thing to return is this validation's errors
|
|
2890
|
+
return errors;
|
|
2891
|
+
}
|
|
2892
|
+
// Discover validation depth bounds from the LoaderTree. The array
|
|
2893
|
+
// length is the max URL depth; each entry is the max group depth
|
|
2894
|
+
// (route group segments) between that URL depth and the next.
|
|
2895
|
+
const groupDepthsByUrlDepth = discoverValidationDepths(loaderTree);
|
|
2896
|
+
const maxDepth = groupDepthsByUrlDepth.length;
|
|
2897
|
+
for(let depth = maxDepth - 1; depth >= 0; depth--){
|
|
2898
|
+
const maxGroupDepth = groupDepthsByUrlDepth[depth];
|
|
2899
|
+
for(let currentGroupDepth = maxGroupDepth; currentGroupDepth >= 0; currentGroupDepth--){
|
|
2900
|
+
debug == null ? void 0 : debug(`Trying depth ${depth}` + (currentGroupDepth > 0 ? ` + groupDepth ${currentGroupDepth}...` : '...'));
|
|
2901
|
+
const errors = await validateAtDepth(depth, currentGroupDepth);
|
|
2902
|
+
if (errors === null) {
|
|
2903
|
+
debug == null ? void 0 : debug(` No config at depth ${depth}+${currentGroupDepth}, skipping.`);
|
|
2904
|
+
continue;
|
|
2905
|
+
}
|
|
2906
|
+
if (errors.length > 0) {
|
|
2907
|
+
debug == null ? void 0 : debug(` Depth ${depth}+${currentGroupDepth}: ❌ Failed (${errors.length} errors)`);
|
|
2908
|
+
return errors;
|
|
2909
|
+
}
|
|
2910
|
+
debug == null ? void 0 : debug(` Depth ${depth}+${currentGroupDepth}: ✅ Passed`);
|
|
2911
|
+
}
|
|
2912
|
+
}
|
|
2913
|
+
debug == null ? void 0 : debug(`✅ All depths passed`);
|
|
2914
|
+
return [];
|
|
2915
|
+
}
|
|
2916
|
+
/**
|
|
2917
|
+
* Two-pass render for build-time instant validation.
|
|
2918
|
+
* The flow is similar to `renderWithRestartOnCacheMissInDev`: pass 1 warms caches,
|
|
2919
|
+
* pass 2 renders with warm caches. If pass 1 has no cache misses,
|
|
2920
|
+
* its result is returned directly.
|
|
2921
|
+
*
|
|
2922
|
+
* Differences from `renderWithRestartOnCacheMissInDev`:
|
|
2923
|
+
* - both renders are abortable: if we know that we can't use a stream, we can just
|
|
2924
|
+
* throw it away, we don't have to render a complete result.
|
|
2925
|
+
* - We don't need to tee the stream, we only care about accumulating chunks.
|
|
2926
|
+
*/ async function renderWithRestartOnCacheMissInValidation(ctx, initialRequestStore, createRequestStore, getPayload, createOnError, prefilledDataCache) {
|
|
2927
|
+
const { componentMod: ComponentMod } = ctx;
|
|
2928
|
+
const { clientModules } = (0, _manifestssingleton.getClientReferenceManifest)();
|
|
2929
|
+
let startTime = -Infinity;
|
|
2930
|
+
let requestStore = initialRequestStore;
|
|
2931
|
+
//===============================================
|
|
2932
|
+
// Initial render (prospective — may warm caches)
|
|
2933
|
+
//===============================================
|
|
2934
|
+
const cacheSignal = new _cachesignal.CacheSignal();
|
|
2935
|
+
(0, _trackmoduleloadingexternal.trackPendingModules)(cacheSignal);
|
|
2936
|
+
// The prerender we rean before the validation probably already filled some caches,
|
|
2937
|
+
// so we want to save work and re-use them.
|
|
2938
|
+
const prerenderResumeDataCache = prefilledDataCache ? (0, _resumedatacache.createPrerenderResumeDataCache)(prefilledDataCache) : (0, _resumedatacache.createPrerenderResumeDataCache)();
|
|
2939
|
+
const initialReactController = new AbortController();
|
|
2940
|
+
const initialDataController = new AbortController();
|
|
2941
|
+
const initialAbandonController = new AbortController();
|
|
2942
|
+
const initialStageController = new _stagedrendering.StagedRenderingController(initialDataController.signal, initialAbandonController, true // track sync IO
|
|
2943
|
+
);
|
|
2944
|
+
requestStore.prerenderResumeDataCache = prerenderResumeDataCache;
|
|
2945
|
+
requestStore.renderResumeDataCache = null;
|
|
2946
|
+
requestStore.stagedRendering = initialStageController;
|
|
2947
|
+
requestStore.cacheSignal = cacheSignal;
|
|
2948
|
+
requestStore.asyncApiPromises = createAsyncApiPromises(initialStageController, requestStore.cookies, requestStore.mutableCookies, requestStore.headers);
|
|
2949
|
+
// We don't set `requestStore.controller and requestStore.renderSignal here.
|
|
2950
|
+
// Right now, we only abort for sync IO, and in the first render, that's just a restart
|
|
2951
|
+
// (after waiting for caches)
|
|
2952
|
+
requestStore.controller = undefined;
|
|
2953
|
+
requestStore.renderSignal = undefined;
|
|
2954
|
+
const initialRscPayload = await getPayload(requestStore);
|
|
2955
|
+
const advanceStageIfNoCacheMiss = (stage)=>{
|
|
2956
|
+
if (initialAbandonController.signal.aborted === true) {
|
|
2957
|
+
return;
|
|
2958
|
+
} else if (cacheSignal.hasPendingReads()) {
|
|
2959
|
+
initialAbandonController.abort();
|
|
2960
|
+
} else {
|
|
2961
|
+
initialStageController.advanceStage(stage);
|
|
2962
|
+
}
|
|
2963
|
+
};
|
|
2964
|
+
const initialResult = await (0, _apprenderrenderutils.runInSequentialTasks)(()=>{
|
|
2965
|
+
initialStageController.advanceStage(_stagedrendering.RenderStage.EarlyStatic);
|
|
2966
|
+
startTime = performance.now() + performance.timeOrigin;
|
|
2967
|
+
const stream = _workunitasyncstorageexternal.workUnitAsyncStorage.run(requestStore, _streamops.renderToFlightStream, ComponentMod, initialRscPayload, clientModules, {
|
|
2968
|
+
onError: createOnError(initialReactController.signal, false),
|
|
2969
|
+
startTime,
|
|
2970
|
+
filterStackFrame,
|
|
2971
|
+
signal: initialReactController.signal
|
|
2972
|
+
});
|
|
2973
|
+
initialReactController.signal.addEventListener('abort', ()=>{
|
|
2974
|
+
const { reason } = initialReactController.signal;
|
|
2975
|
+
initialDataController.abort(reason);
|
|
2976
|
+
}, {
|
|
2977
|
+
once: true
|
|
2978
|
+
});
|
|
2979
|
+
const accumulatedChunksPromise = accumulateStreamChunks(stream, initialStageController, initialDataController.signal);
|
|
2980
|
+
accumulatedChunksPromise.catch(()=>{});
|
|
2981
|
+
return {
|
|
2982
|
+
accumulatedChunksPromise
|
|
2983
|
+
};
|
|
2984
|
+
}, ()=>{
|
|
2985
|
+
advanceStageIfNoCacheMiss(_stagedrendering.RenderStage.Static);
|
|
2986
|
+
}, ()=>{
|
|
2987
|
+
advanceStageIfNoCacheMiss(_stagedrendering.RenderStage.EarlyRuntime);
|
|
2988
|
+
}, ()=>{
|
|
2989
|
+
advanceStageIfNoCacheMiss(_stagedrendering.RenderStage.Runtime);
|
|
2990
|
+
}, ()=>{
|
|
2991
|
+
advanceStageIfNoCacheMiss(_stagedrendering.RenderStage.Dynamic);
|
|
2992
|
+
});
|
|
2993
|
+
if (initialStageController.currentStage !== _stagedrendering.RenderStage.Abandoned) {
|
|
2994
|
+
// No cache misses. Use the result as-is.
|
|
2995
|
+
return {
|
|
2996
|
+
accumulatedChunksPromise: initialResult.accumulatedChunksPromise,
|
|
2997
|
+
startTime,
|
|
2998
|
+
stageController: initialStageController,
|
|
2999
|
+
requestStore
|
|
3000
|
+
};
|
|
3001
|
+
}
|
|
3002
|
+
// Cache miss. Wait for caches to fill, then re-render with warm caches.
|
|
3003
|
+
await cacheSignal.cacheReady();
|
|
3004
|
+
initialReactController.abort();
|
|
3005
|
+
//===============================================
|
|
3006
|
+
// Final render (restarted, with warm caches)
|
|
3007
|
+
//===============================================
|
|
3008
|
+
requestStore = createRequestStore();
|
|
3009
|
+
// Unlike dev, where we're re-using the render that'll be visible in the browser,
|
|
3010
|
+
// we *can* abort the validation render.
|
|
3011
|
+
const finalReactController = new AbortController();
|
|
3012
|
+
const finalDataController = new AbortController();
|
|
3013
|
+
const finalStageController = new _stagedrendering.StagedRenderingController(finalDataController.signal, null, true // track sync IO
|
|
3014
|
+
);
|
|
3015
|
+
requestStore.prerenderResumeDataCache = null;
|
|
3016
|
+
requestStore.renderResumeDataCache = (0, _resumedatacache.createRenderResumeDataCache)(prerenderResumeDataCache);
|
|
3017
|
+
requestStore.stagedRendering = finalStageController;
|
|
3018
|
+
requestStore.cacheSignal = null;
|
|
3019
|
+
requestStore.asyncApiPromises = createAsyncApiPromises(finalStageController, requestStore.cookies, requestStore.mutableCookies, requestStore.headers);
|
|
3020
|
+
// Right now, we only abort for sync IO.
|
|
3021
|
+
// If sync IO occurs in a place where it's not allowed, then we have to fail validation,
|
|
3022
|
+
// and we can abort the render immediately, without waiting for anything else..
|
|
3023
|
+
requestStore.controller = finalReactController;
|
|
3024
|
+
requestStore.renderSignal = finalDataController.signal;
|
|
3025
|
+
const finalRscPayload = await getPayload(requestStore);
|
|
3026
|
+
const finalResult = await (0, _apprenderrenderutils.runInSequentialTasks)(()=>{
|
|
3027
|
+
finalStageController.advanceStage(_stagedrendering.RenderStage.EarlyStatic);
|
|
3028
|
+
startTime = performance.now() + performance.timeOrigin;
|
|
3029
|
+
const stream = _workunitasyncstorageexternal.workUnitAsyncStorage.run(requestStore, _streamops.renderToFlightStream, ComponentMod, finalRscPayload, clientModules, {
|
|
3030
|
+
onError: createOnError(finalReactController.signal, true),
|
|
3031
|
+
startTime,
|
|
3032
|
+
filterStackFrame,
|
|
3033
|
+
signal: finalReactController.signal
|
|
3034
|
+
});
|
|
3035
|
+
finalReactController.signal.addEventListener('abort', ()=>{
|
|
3036
|
+
finalDataController.abort(finalReactController.signal.reason);
|
|
3037
|
+
}, {
|
|
3038
|
+
once: true
|
|
3039
|
+
});
|
|
3040
|
+
const accumulatedChunksPromise = accumulateStreamChunks(stream, finalStageController, null);
|
|
3041
|
+
accumulatedChunksPromise.catch(()=>{});
|
|
3042
|
+
return {
|
|
3043
|
+
accumulatedChunksPromise
|
|
3044
|
+
};
|
|
3045
|
+
}, ()=>{
|
|
3046
|
+
finalStageController.advanceStage(_stagedrendering.RenderStage.Static);
|
|
3047
|
+
}, ()=>{
|
|
3048
|
+
finalStageController.advanceStage(_stagedrendering.RenderStage.EarlyRuntime);
|
|
3049
|
+
}, ()=>{
|
|
3050
|
+
finalStageController.advanceStage(_stagedrendering.RenderStage.Runtime);
|
|
3051
|
+
}, ()=>{
|
|
3052
|
+
finalStageController.advanceStage(_stagedrendering.RenderStage.Dynamic);
|
|
3053
|
+
});
|
|
3054
|
+
return {
|
|
3055
|
+
accumulatedChunksPromise: finalResult.accumulatedChunksPromise,
|
|
3056
|
+
startTime,
|
|
3057
|
+
stageController: finalStageController,
|
|
3058
|
+
requestStore
|
|
3059
|
+
};
|
|
3060
|
+
}
|
|
3061
|
+
async function validateInstantConfigsInBuild(ctx, prefilledDataCache) {
|
|
3062
|
+
const run = async ()=>{
|
|
3063
|
+
let success;
|
|
3064
|
+
try {
|
|
3065
|
+
// The validation renders are separate renders, and use a separate WorkStore.
|
|
3066
|
+
// However, we defensively exit the existing workStore to avoid relying on something from there
|
|
3067
|
+
// before we shadow it.
|
|
3068
|
+
success = await _workasyncstorageexternal.workAsyncStorage.exit(async ()=>validateInstantConfigsInBuildImpl(ctx, prefilledDataCache));
|
|
3069
|
+
} catch (err) {
|
|
3070
|
+
console.error(Object.defineProperty(new _invarianterror.InvariantError('An unexpected error occcured during instant validation', {
|
|
3071
|
+
cause: err
|
|
3072
|
+
}), "__NEXT_ERROR_CODE", {
|
|
3073
|
+
value: "E1097",
|
|
3074
|
+
enumerable: false,
|
|
3075
|
+
configurable: true
|
|
3076
|
+
}));
|
|
3077
|
+
success = false;
|
|
3078
|
+
}
|
|
3079
|
+
if (!success) {
|
|
3080
|
+
console.error('Stopping prerender due to instant validation errors.');
|
|
3081
|
+
throw new _staticgenerationbailout.StaticGenBailoutError();
|
|
3082
|
+
}
|
|
3083
|
+
};
|
|
3084
|
+
if (process.env.__NEXT_TEST_MODE && process.env.NEXT_TEST_LOG_VALIDATION) {
|
|
3085
|
+
// In tests, we use these markers to extract the relevant portion of the CLI logs.
|
|
3086
|
+
// We want consistent ordering of these messages and other console.error calls,
|
|
3087
|
+
// so we use console.error here as well. Using console.log leads to non-deterministic
|
|
3088
|
+
// log order, likely stdout/stderr can interleave in non-deterministic ways.
|
|
3089
|
+
const requestId = Date.now();
|
|
3090
|
+
const route = ctx.workStore.route;
|
|
3091
|
+
console.error('<VALIDATION_MESSAGE>' + JSON.stringify({
|
|
3092
|
+
type: 'validation_start',
|
|
3093
|
+
requestId,
|
|
3094
|
+
url: route
|
|
3095
|
+
}) + '</VALIDATION_MESSAGE>');
|
|
3096
|
+
try {
|
|
3097
|
+
return await run();
|
|
3098
|
+
} finally{
|
|
3099
|
+
console.error('<VALIDATION_MESSAGE>' + JSON.stringify({
|
|
3100
|
+
type: 'validation_end',
|
|
3101
|
+
requestId,
|
|
3102
|
+
url: route
|
|
3103
|
+
}) + '</VALIDATION_MESSAGE>');
|
|
3104
|
+
}
|
|
3105
|
+
} else {
|
|
3106
|
+
return await run();
|
|
3107
|
+
}
|
|
3108
|
+
}
|
|
3109
|
+
/**
|
|
3110
|
+
* Runs instant validation at build time using the `samples` from `unstable_instant`.
|
|
3111
|
+
*
|
|
3112
|
+
* For each sample, this creates a staged RSC render with a synthetic `RequestStore`
|
|
3113
|
+
* populated from sample data, then feeds the accumulated chunks to
|
|
3114
|
+
* `validateInstantConfigs` which handles the actual validation.
|
|
3115
|
+
*/ async function validateInstantConfigsInBuildImpl(ctx, prefilledDataCache) {
|
|
3116
|
+
const debug = process.env.NEXT_PRIVATE_DEBUG_VALIDATION === '1' ? console.log : undefined;
|
|
3117
|
+
const { workStore: outerWorkStore } = ctx;
|
|
3118
|
+
const route = outerWorkStore.route;
|
|
3119
|
+
const loaderTree = ctx.componentMod.routeModule.userland.loaderTree;
|
|
3120
|
+
let samples = await (0, _instantconfig.resolveInstantConfigSamplesForPage)(loaderTree);
|
|
3121
|
+
if (!samples || samples.length === 0) {
|
|
3122
|
+
// No samples defined; use a single empty sample to still run validation
|
|
3123
|
+
samples = [
|
|
3124
|
+
{}
|
|
3125
|
+
];
|
|
3126
|
+
}
|
|
3127
|
+
debug == null ? void 0 : debug('Resolved samples:', samples);
|
|
3128
|
+
const allPossibleFallbackRouteParams = (0, _fallbackparams.getFallbackRouteParams)(route, ctx.componentMod.routeModule);
|
|
3129
|
+
for(let sampleIndex = 0; sampleIndex < samples.length; sampleIndex++){
|
|
3130
|
+
const sample = samples[sampleIndex];
|
|
3131
|
+
debug == null ? void 0 : debug(`Validating sample (${sampleIndex + 1}/${samples.length}):`, sample);
|
|
3132
|
+
let errors;
|
|
3133
|
+
try {
|
|
3134
|
+
errors = await _consoleasyncstorageexternal.consoleAsyncStorage.run({
|
|
3135
|
+
dim: true
|
|
3136
|
+
}, ()=>validateInstantConfigInBuildWithSample(ctx, sample, allPossibleFallbackRouteParams, prefilledDataCache));
|
|
3137
|
+
} catch (err) {
|
|
3138
|
+
if ((0, _instantvalidationerror.isInstantValidationError)(err)) {
|
|
3139
|
+
errors = [
|
|
3140
|
+
err
|
|
3141
|
+
];
|
|
3142
|
+
} else {
|
|
3143
|
+
throw err;
|
|
3144
|
+
}
|
|
3145
|
+
}
|
|
3146
|
+
if (errors.length > 0) {
|
|
3147
|
+
debug == null ? void 0 : debug(`❌ Sample failed validation (${errors.length} errors)`);
|
|
3148
|
+
const sampleDesc = samples.length > 1 ? ` (sample ${sampleIndex + 1} of ${samples.length})` : '';
|
|
3149
|
+
for (const err of errors){
|
|
3150
|
+
console.error(err);
|
|
3151
|
+
}
|
|
3152
|
+
console.error(`Build-time instant validation failed for route "${route}"${sampleDesc}.`);
|
|
3153
|
+
return false;
|
|
3154
|
+
} else {
|
|
3155
|
+
debug == null ? void 0 : debug('✅ Sample validated successfully');
|
|
3156
|
+
}
|
|
3157
|
+
}
|
|
3158
|
+
return true;
|
|
3159
|
+
}
|
|
3160
|
+
async function validateInstantConfigInBuildWithSample(outerCtx, sample, allPossibleFallbackRouteParams, prefilledDataCache) {
|
|
3161
|
+
// The flow for build mirrors what we do when validating in dev.
|
|
3162
|
+
// We have to perform a full dynamic render to get the RSC chunks for each stage.
|
|
3163
|
+
// In order to do that, we have to set up a mock AppRenderContext, workStore, and requestStore
|
|
3164
|
+
// based on the `sample` we're using.
|
|
3165
|
+
const { workStore: outerWorkStore } = outerCtx;
|
|
3166
|
+
const loaderTree = outerCtx.componentMod.routeModule.userland.loaderTree;
|
|
3167
|
+
const route = outerWorkStore.route;
|
|
3168
|
+
const { createCookiesFromSample, createHeadersFromSample, createDraftModeForValidation, createRelativeURLFromSamples, createValidationSampleTracking } = require('./instant-validation/instant-samples');
|
|
3169
|
+
// TODO(instant-validation-build): it feels like this should happen higher up
|
|
3170
|
+
// and go through existing URL parsing/generation logic?
|
|
3171
|
+
const sampleUrl = createRelativeURLFromSamples(route, sample.params, sample.searchParams);
|
|
3172
|
+
const sampleParams = sample.params ?? {};
|
|
3173
|
+
let fallbackRouteParams = null;
|
|
3174
|
+
if (allPossibleFallbackRouteParams) {
|
|
3175
|
+
const fallbackRouteParamsMut = new Map();
|
|
3176
|
+
for (const [paramKey, value] of allPossibleFallbackRouteParams){
|
|
3177
|
+
if (!(paramKey in sampleParams)) {
|
|
3178
|
+
fallbackRouteParamsMut.set(paramKey, value);
|
|
3179
|
+
}
|
|
3180
|
+
}
|
|
3181
|
+
fallbackRouteParams = fallbackRouteParamsMut;
|
|
3182
|
+
}
|
|
3183
|
+
const getDynamicParamFromSegment = makeGetDynamicParamFromSegment(sampleParams, fallbackRouteParams, false);
|
|
3184
|
+
const sampleRootParams = (0, _createcomponenttree.getRootParams)(loaderTree, getDynamicParamFromSegment);
|
|
3185
|
+
let sampleUrlWithoutQuery;
|
|
3186
|
+
let sampleQuery;
|
|
3187
|
+
({ query: sampleQuery, ...sampleUrlWithoutQuery } = sampleUrl);
|
|
3188
|
+
const { AfterContext } = require('../after/after-context');
|
|
3189
|
+
// NOTE: Matching the field order in `createWorkStore` to avoid deopting.
|
|
3190
|
+
const workStore = {
|
|
3191
|
+
isStaticGeneration: false,
|
|
3192
|
+
page: outerWorkStore.page,
|
|
3193
|
+
route: outerWorkStore.route,
|
|
3194
|
+
incrementalCache: outerWorkStore.incrementalCache,
|
|
3195
|
+
cacheLifeProfiles: outerWorkStore.cacheLifeProfiles,
|
|
3196
|
+
isBuildTimePrerendering: false,
|
|
3197
|
+
fetchCache: outerWorkStore.fetchCache,
|
|
3198
|
+
isOnDemandRevalidate: false,
|
|
3199
|
+
isDraftMode: false,
|
|
3200
|
+
isPrefetchRequest: false,
|
|
3201
|
+
buildId: outerWorkStore.buildId,
|
|
3202
|
+
reactLoadableManifest: outerWorkStore.reactLoadableManifest,
|
|
3203
|
+
assetPrefix: outerWorkStore.assetPrefix,
|
|
3204
|
+
nonce: outerWorkStore.nonce,
|
|
3205
|
+
// Never run `after()` for this validation render. by definition, `after` can't affect the rendered output.
|
|
3206
|
+
afterContext: new AfterContext({
|
|
3207
|
+
waitUntil (promise) {
|
|
3208
|
+
promise.catch(()=>{});
|
|
3209
|
+
},
|
|
3210
|
+
onClose () {},
|
|
3211
|
+
onTaskError () {}
|
|
3212
|
+
}),
|
|
3213
|
+
cacheComponentsEnabled: outerWorkStore.cacheComponentsEnabled,
|
|
3214
|
+
previouslyRevalidatedTags: [],
|
|
3215
|
+
refreshTagsByCacheKind: new Map(),
|
|
3216
|
+
runInCleanSnapshot: outerWorkStore.runInCleanSnapshot,
|
|
3217
|
+
shouldTrackFetchMetrics: false,
|
|
3218
|
+
reactServerErrorsByDigest: new Map()
|
|
3219
|
+
};
|
|
3220
|
+
return _workasyncstorageexternal.workAsyncStorage.run(workStore, async ()=>{
|
|
3221
|
+
// NOTE: match field order in renderToHTMLOrFlightImpl to avoid deopts
|
|
3222
|
+
const validationCtx = {
|
|
3223
|
+
componentMod: outerCtx.componentMod,
|
|
3224
|
+
url: sampleUrlWithoutQuery,
|
|
3225
|
+
renderOpts: outerCtx.renderOpts,
|
|
3226
|
+
workStore,
|
|
3227
|
+
parsedRequestHeaders: outerCtx.parsedRequestHeaders,
|
|
3228
|
+
getDynamicParamFromSegment,
|
|
3229
|
+
interpolatedParams: sampleParams,
|
|
3230
|
+
query: sampleQuery,
|
|
3231
|
+
isPrefetch: false,
|
|
3232
|
+
isPossibleServerAction: false,
|
|
3233
|
+
requestTimestamp: outerCtx.requestTimestamp,
|
|
3234
|
+
appUsingSizeAdjustment: outerCtx.appUsingSizeAdjustment,
|
|
3235
|
+
flightRouterState: undefined,
|
|
3236
|
+
requestId: outerCtx.requestId,
|
|
3237
|
+
htmlRequestId: outerCtx.htmlRequestId,
|
|
3238
|
+
pagePath: outerCtx.pagePath,
|
|
3239
|
+
assetPrefix: outerCtx.assetPrefix,
|
|
3240
|
+
isNotFoundPath: outerCtx.isNotFoundPath,
|
|
3241
|
+
nonce: outerCtx.nonce,
|
|
3242
|
+
res: outerCtx.res,
|
|
3243
|
+
sharedContext: outerCtx.sharedContext,
|
|
3244
|
+
implicitTags: outerCtx.implicitTags
|
|
3245
|
+
};
|
|
3246
|
+
const validationSamples = {
|
|
3247
|
+
params: sample.params,
|
|
3248
|
+
searchParams: sample.searchParams
|
|
3249
|
+
};
|
|
3250
|
+
const createRequestStore = ()=>{
|
|
3251
|
+
// Create exhaustive request data from sample
|
|
3252
|
+
const sampleCookies = createCookiesFromSample(sample.cookies, route);
|
|
3253
|
+
// We don't have to bother initializing these, pages can't access them anyway,
|
|
3254
|
+
// we just need them because RequestStore requires them.
|
|
3255
|
+
const unusedMutableCookies = new _cookies.ResponseCookies(new Headers());
|
|
3256
|
+
// Create headers.
|
|
3257
|
+
const sampleHeaders = createHeadersFromSample(sample.headers, sample.cookies, route);
|
|
3258
|
+
const draftMode = createDraftModeForValidation();
|
|
3259
|
+
return {
|
|
3260
|
+
type: 'request',
|
|
3261
|
+
phase: 'render',
|
|
3262
|
+
implicitTags: outerCtx.implicitTags,
|
|
3263
|
+
url: {
|
|
3264
|
+
pathname: sampleUrl.pathname,
|
|
3265
|
+
search: sampleUrl.search
|
|
3266
|
+
},
|
|
3267
|
+
headers: sampleHeaders,
|
|
3268
|
+
cookies: sampleCookies,
|
|
3269
|
+
mutableCookies: unusedMutableCookies,
|
|
3270
|
+
userspaceMutableCookies: unusedMutableCookies,
|
|
3271
|
+
draftMode,
|
|
3272
|
+
rootParams: sampleRootParams,
|
|
3273
|
+
validationSamples,
|
|
3274
|
+
validationSampleTracking: createValidationSampleTracking(),
|
|
3275
|
+
// These will be set when rendering
|
|
3276
|
+
renderResumeDataCache: null,
|
|
3277
|
+
prerenderResumeDataCache: null,
|
|
3278
|
+
stagedRendering: null,
|
|
3279
|
+
asyncApiPromises: undefined
|
|
3280
|
+
};
|
|
3281
|
+
};
|
|
3282
|
+
// Track server errors. If one of them surfaces during the client render
|
|
3283
|
+
// in the deserialized form (with no message/stack) we'll use this to map it
|
|
3284
|
+
// back to the original.
|
|
3285
|
+
const onServerError = (0, _createerrorhandler.createReactServerErrorHandler)(true, true, workStore.reactServerErrorsByDigest, ()=>{} // Don't report anything here. If needed, it will be reported in the client render.
|
|
3286
|
+
);
|
|
3287
|
+
const { accumulatedChunksPromise, startTime, stageController, requestStore: finalServerStore } = await renderWithRestartOnCacheMissInValidation(validationCtx, createRequestStore(), createRequestStore, (requestStore)=>_workunitasyncstorageexternal.workUnitAsyncStorage.run(requestStore, getRSCPayload, loaderTree, validationCtx, {
|
|
3288
|
+
is404: false
|
|
3289
|
+
}), (signal)=>function onError(err) {
|
|
3290
|
+
const digest = (0, _createerrorhandler.getDigestForWellKnownError)(err);
|
|
3291
|
+
if (digest) {
|
|
3292
|
+
return digest;
|
|
3293
|
+
}
|
|
3294
|
+
if (signal.aborted) {
|
|
3295
|
+
return;
|
|
3296
|
+
}
|
|
3297
|
+
return onServerError(err);
|
|
3298
|
+
}, prefilledDataCache);
|
|
3299
|
+
const accumulatedChunks = await accumulatedChunksPromise;
|
|
3300
|
+
const debugChunks = null // TODO(instant-validation-build): support debugChannel
|
|
3301
|
+
;
|
|
3302
|
+
// Missing sample errors take priority over everything else,
|
|
3303
|
+
// because they prevent us from rendering everything we need to validate.
|
|
3304
|
+
const serverValidationSampleTracking = finalServerStore.validationSampleTracking;
|
|
3305
|
+
if (serverValidationSampleTracking.missingSampleErrors.length > 0) {
|
|
3306
|
+
return serverValidationSampleTracking.missingSampleErrors;
|
|
3307
|
+
}
|
|
3308
|
+
// We also error for sync IO. This runs after the prerender,
|
|
3309
|
+
// so if we get sync IO errors here, they're likely from the runtime stage --
|
|
3310
|
+
// the prerender probably discovered sync IO in the static stage
|
|
3311
|
+
if (stageController.currentStage === _stagedrendering.RenderStage.Abandoned && stageController.syncInterruptReason) {
|
|
3312
|
+
return [
|
|
3313
|
+
stageController.syncInterruptReason
|
|
3314
|
+
];
|
|
3315
|
+
}
|
|
3316
|
+
const allowEmptyStaticShell = (validationCtx.renderOpts.allowEmptyStaticShell ?? false) || await (0, _instantconfig.isPageAllowedToBlock)(loaderTree);
|
|
3317
|
+
// Now we the chunks of a fully rendered page, just like in dev.
|
|
3318
|
+
// We can use them to validate all the navigations required by `instant` configs.
|
|
3319
|
+
// Note that we're not performing static shell validation here -- that happens
|
|
3320
|
+
// implicitly as part of the static prerender.
|
|
3321
|
+
// The static prerender has warmed some client modules already,
|
|
3322
|
+
// but we'll be reaching Runtime/Dynamic stages and thus rendering more content,
|
|
3323
|
+
// so we need to warm again.
|
|
3324
|
+
// TODO(instant-validation-build): This might warm too much, possibly hitting errors on code that didn't expect
|
|
3325
|
+
// to run at build time. For example, we generally don't need to render leaf segments (e.g. __PAGE__) in
|
|
3326
|
+
// the Dynamic stage, they're Runtime at best.
|
|
3327
|
+
const warmupValidationSamplesTracking = createValidationSampleTracking();
|
|
3328
|
+
await warmupClientModulesForStagedValidation('validation-client', accumulatedChunks.dynamicChunks, accumulatedChunks.dynamicChunks, sampleRootParams, fallbackRouteParams, allowEmptyStaticShell, validationCtx, validationSamples, warmupValidationSamplesTracking);
|
|
3329
|
+
if (warmupValidationSamplesTracking.missingSampleErrors.length > 0) {
|
|
3330
|
+
return warmupValidationSamplesTracking.missingSampleErrors;
|
|
3331
|
+
}
|
|
3332
|
+
return await validateInstantConfigs(accumulatedChunks, debugChunks, startTime, sampleRootParams, fallbackRouteParams, validationCtx, undefined, validationSamples);
|
|
3333
|
+
});
|
|
3334
|
+
}
|
|
2396
3335
|
/**
|
|
2397
3336
|
* Determines whether we should generate static flight data.
|
|
2398
3337
|
*/ function shouldGenerateStaticFlightData(workStore) {
|
|
@@ -2406,7 +3345,9 @@ async function prerenderToStream(req, res, ctx, metadata, tree, fallbackRoutePar
|
|
|
2406
3345
|
// more explicit than making it an optional function argument
|
|
2407
3346
|
const formState = null;
|
|
2408
3347
|
const { assetPrefix, getDynamicParamFromSegment, implicitTags, nonce, pagePath, renderOpts, workStore } = ctx;
|
|
2409
|
-
const {
|
|
3348
|
+
const { basePath, buildManifest, ComponentMod, crossOrigin, experimental, isDebugDynamicAccesses, isBuildTimePrerendering = false, onInstrumentationRequestError, page, reactMaxHeadersLength, subresourceIntegrityManifest, cacheComponents } = renderOpts;
|
|
3349
|
+
const { cachedNavigations } = renderOpts.experimental;
|
|
3350
|
+
const allowEmptyStaticShell = (renderOpts.allowEmptyStaticShell ?? false) || await (0, _instantconfig.isPageAllowedToBlock)(tree);
|
|
2410
3351
|
const rootParams = (0, _createcomponenttree.getRootParams)(tree, getDynamicParamFromSegment);
|
|
2411
3352
|
const { ServerInsertedHTMLProvider, renderServerInsertedHTML } = (0, _serverinsertedhtml.createServerInsertedHTML)();
|
|
2412
3353
|
const getServerInsertedMetadata = (0, _createserverinsertedmetadata.createServerInsertedMetadata)(nonce);
|
|
@@ -2429,7 +3370,7 @@ async function prerenderToStream(req, res, ctx, metadata, tree, fallbackRoutePar
|
|
|
2429
3370
|
return onInstrumentationRequestError == null ? void 0 : onInstrumentationRequestError(err, req, createErrorContext(ctx, 'react-server-components'), silenceLog);
|
|
2430
3371
|
}
|
|
2431
3372
|
}
|
|
2432
|
-
const serverComponentsErrorHandler = (0, _createerrorhandler.createReactServerErrorHandler)(
|
|
3373
|
+
const serverComponentsErrorHandler = (0, _createerrorhandler.createReactServerErrorHandler)(process.env.NODE_ENV === 'development', isBuildTimePrerendering, reactServerErrorsByDigest, onHTMLRenderRSCError);
|
|
2433
3374
|
function onHTMLRenderSSRError(err) {
|
|
2434
3375
|
if (reportErrors) {
|
|
2435
3376
|
// We don't need to silence logs here. onHTMLRenderSSRError won't be
|
|
@@ -2439,7 +3380,7 @@ async function prerenderToStream(req, res, ctx, metadata, tree, fallbackRoutePar
|
|
|
2439
3380
|
}
|
|
2440
3381
|
}
|
|
2441
3382
|
const allCapturedErrors = [];
|
|
2442
|
-
const htmlRendererErrorHandler = (0, _createerrorhandler.createHTMLErrorHandler)(
|
|
3383
|
+
const htmlRendererErrorHandler = (0, _createerrorhandler.createHTMLErrorHandler)(process.env.NODE_ENV === 'development', isBuildTimePrerendering, reactServerErrorsByDigest, allCapturedErrors, onHTMLRenderSSRError);
|
|
2443
3384
|
let reactServerPrerenderResult = null;
|
|
2444
3385
|
const setMetadataHeader = (name)=>{
|
|
2445
3386
|
metadata.headers ??= {};
|
|
@@ -2460,7 +3401,7 @@ async function prerenderToStream(req, res, ctx, metadata, tree, fallbackRoutePar
|
|
|
2460
3401
|
}
|
|
2461
3402
|
setMetadataHeader(name);
|
|
2462
3403
|
};
|
|
2463
|
-
const selectStaleTime = createSelectStaleTime(experimental);
|
|
3404
|
+
const selectStaleTime = (0, _staletime.createSelectStaleTime)(experimental);
|
|
2464
3405
|
const { clientModules } = (0, _manifestssingleton.getClientReferenceManifest)();
|
|
2465
3406
|
let prerenderStore = null;
|
|
2466
3407
|
try {
|
|
@@ -2500,19 +3441,10 @@ async function prerenderToStream(req, res, ctx, metadata, tree, fallbackRoutePar
|
|
|
2500
3441
|
// The cacheSignal helps us track whether caches are still filling or we are ready
|
|
2501
3442
|
// to cut the render off.
|
|
2502
3443
|
const cacheSignal = new _cachesignal.CacheSignal();
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
// If a prefilled immutable render resume data cache is provided, e.g.
|
|
2508
|
-
// when prerendering an optional fallback shell after having prerendered
|
|
2509
|
-
// pages with defined params, we use this instead of a prerender resume
|
|
2510
|
-
// data cache.
|
|
2511
|
-
resumeDataCache = renderResumeDataCache = renderOpts.renderResumeDataCache;
|
|
2512
|
-
} else {
|
|
2513
|
-
// Otherwise we create a new mutable prerender resume data cache.
|
|
2514
|
-
resumeDataCache = prerenderResumeDataCache = (0, _resumedatacache.createPrerenderResumeDataCache)();
|
|
2515
|
-
}
|
|
3444
|
+
// Always start with a fresh prerender RDC so warmup can fill misses,
|
|
3445
|
+
// even when we have a prefilled render RDC to seed from.
|
|
3446
|
+
const prerenderResumeDataCache = (0, _resumedatacache.createPrerenderResumeDataCache)();
|
|
3447
|
+
let renderResumeDataCache = renderOpts.renderResumeDataCache ?? null;
|
|
2516
3448
|
const initialServerPayloadPrerenderStore = {
|
|
2517
3449
|
type: 'prerender',
|
|
2518
3450
|
phase: 'render',
|
|
@@ -2540,11 +3472,15 @@ async function prerenderToStream(req, res, ctx, metadata, tree, fallbackRoutePar
|
|
|
2540
3472
|
],
|
|
2541
3473
|
prerenderResumeDataCache,
|
|
2542
3474
|
renderResumeDataCache,
|
|
2543
|
-
hmrRefreshHash: undefined
|
|
3475
|
+
hmrRefreshHash: undefined,
|
|
3476
|
+
// We don't track vary params during initial prerender, only the final one
|
|
3477
|
+
varyParamsAccumulator: null
|
|
2544
3478
|
};
|
|
2545
3479
|
// We're not going to use the result of this render because the only time it could be used
|
|
2546
3480
|
// is if it completes in a microtask and that's likely very rare for any non-trivial app
|
|
2547
|
-
const initialServerPayload = await _workunitasyncstorageexternal.workUnitAsyncStorage.run(initialServerPayloadPrerenderStore, getRSCPayload, tree, ctx,
|
|
3481
|
+
const initialServerPayload = await _workunitasyncstorageexternal.workUnitAsyncStorage.run(initialServerPayloadPrerenderStore, getRSCPayload, tree, ctx, {
|
|
3482
|
+
is404: res.statusCode === 404
|
|
3483
|
+
});
|
|
2548
3484
|
const initialServerPrerenderStore = prerenderStore = {
|
|
2549
3485
|
type: 'prerender',
|
|
2550
3486
|
phase: 'render',
|
|
@@ -2567,9 +3503,11 @@ async function prerenderToStream(req, res, ctx, metadata, tree, fallbackRoutePar
|
|
|
2567
3503
|
],
|
|
2568
3504
|
prerenderResumeDataCache,
|
|
2569
3505
|
renderResumeDataCache,
|
|
2570
|
-
hmrRefreshHash: undefined
|
|
3506
|
+
hmrRefreshHash: undefined,
|
|
3507
|
+
// We don't track vary params during initial prerender, only the final one
|
|
3508
|
+
varyParamsAccumulator: null
|
|
2571
3509
|
};
|
|
2572
|
-
const
|
|
3510
|
+
const initialPrerenderOptions = {
|
|
2573
3511
|
filterStackFrame,
|
|
2574
3512
|
onError: (err)=>{
|
|
2575
3513
|
const digest = (0, _createerrorhandler.getDigestForWellKnownError)(err);
|
|
@@ -2593,7 +3531,8 @@ async function prerenderToStream(req, res, ctx, metadata, tree, fallbackRoutePar
|
|
|
2593
3531
|
// a different signal to this render call than is used by dynamic APIs to signify
|
|
2594
3532
|
// transitioning out of the prerender environment
|
|
2595
3533
|
signal: initialServerReactController.signal
|
|
2596
|
-
}
|
|
3534
|
+
};
|
|
3535
|
+
const pendingInitialServerResult = _workunitasyncstorageexternal.workUnitAsyncStorage.run(initialServerPrerenderStore, (0, _streamops.getServerPrerender)(ComponentMod), initialServerPayload, clientModules, initialPrerenderOptions);
|
|
2597
3536
|
// The listener to abort our own render controller must be added after
|
|
2598
3537
|
// React has added its listener, to ensure that pending I/O is not
|
|
2599
3538
|
// aborted/rejected too early.
|
|
@@ -2650,10 +3589,11 @@ async function prerenderToStream(req, res, ctx, metadata, tree, fallbackRoutePar
|
|
|
2650
3589
|
],
|
|
2651
3590
|
prerenderResumeDataCache,
|
|
2652
3591
|
renderResumeDataCache,
|
|
2653
|
-
hmrRefreshHash: undefined
|
|
3592
|
+
hmrRefreshHash: undefined,
|
|
3593
|
+
// Client prerenders don't track server param access
|
|
3594
|
+
varyParamsAccumulator: null
|
|
2654
3595
|
};
|
|
2655
|
-
const
|
|
2656
|
-
const pendingInitialClientResult = _workunitasyncstorageexternal.workUnitAsyncStorage.run(initialClientPrerenderStore, prerender, // eslint-disable-next-line @next/internal/no-ambiguous-jsx
|
|
3596
|
+
const pendingInitialClientResult = _workunitasyncstorageexternal.workUnitAsyncStorage.run(initialClientPrerenderStore, _streamops.getClientPrerender, // eslint-disable-next-line @next/internal/no-ambiguous-jsx
|
|
2657
3597
|
/*#__PURE__*/ (0, _jsxruntime.jsx)(App, {
|
|
2658
3598
|
reactServerStream: initialServerResult.asUnclosingStream(),
|
|
2659
3599
|
reactDebugStream: undefined,
|
|
@@ -2709,8 +3649,13 @@ async function prerenderToStream(req, res, ctx, metadata, tree, fallbackRoutePar
|
|
|
2709
3649
|
await cacheSignal.cacheReady();
|
|
2710
3650
|
initialClientReactController.abort();
|
|
2711
3651
|
}
|
|
3652
|
+
if (renderOpts.renderResumeDataCache) {
|
|
3653
|
+
// Swap to the warmed cache so the final render uses entries produced during warmup.
|
|
3654
|
+
renderResumeDataCache = (0, _resumedatacache.createRenderResumeDataCache)(prerenderResumeDataCache);
|
|
3655
|
+
}
|
|
2712
3656
|
const finalServerReactController = new AbortController();
|
|
2713
3657
|
const finalServerRenderController = new AbortController();
|
|
3658
|
+
const varyParamsAccumulator = (0, _varyparams.createResponseVaryParamsAccumulator)();
|
|
2714
3659
|
const finalServerPayloadPrerenderStore = {
|
|
2715
3660
|
type: 'prerender',
|
|
2716
3661
|
phase: 'render',
|
|
@@ -2736,9 +3681,17 @@ async function prerenderToStream(req, res, ctx, metadata, tree, fallbackRoutePar
|
|
|
2736
3681
|
],
|
|
2737
3682
|
prerenderResumeDataCache,
|
|
2738
3683
|
renderResumeDataCache,
|
|
2739
|
-
hmrRefreshHash: undefined
|
|
3684
|
+
hmrRefreshHash: undefined,
|
|
3685
|
+
varyParamsAccumulator
|
|
2740
3686
|
};
|
|
2741
|
-
const finalAttemptRSCPayload = await _workunitasyncstorageexternal.workUnitAsyncStorage.run(finalServerPayloadPrerenderStore, getRSCPayload, tree, ctx,
|
|
3687
|
+
const finalAttemptRSCPayload = await _workunitasyncstorageexternal.workUnitAsyncStorage.run(finalServerPayloadPrerenderStore, getRSCPayload, tree, ctx, {
|
|
3688
|
+
is404: res.statusCode === 404
|
|
3689
|
+
});
|
|
3690
|
+
let staleTimeIterable;
|
|
3691
|
+
if (cachedNavigations) {
|
|
3692
|
+
staleTimeIterable = new _staletime.StaleTimeIterable();
|
|
3693
|
+
finalAttemptRSCPayload.s = staleTimeIterable;
|
|
3694
|
+
}
|
|
2742
3695
|
const serverDynamicTracking = (0, _dynamicrendering.createDynamicTrackingState)(isDebugDynamicAccesses);
|
|
2743
3696
|
let serverIsDynamic = false;
|
|
2744
3697
|
const finalServerPrerenderStore = prerenderStore = {
|
|
@@ -2761,20 +3714,56 @@ async function prerenderToStream(req, res, ctx, metadata, tree, fallbackRoutePar
|
|
|
2761
3714
|
],
|
|
2762
3715
|
prerenderResumeDataCache,
|
|
2763
3716
|
renderResumeDataCache,
|
|
2764
|
-
hmrRefreshHash: undefined
|
|
3717
|
+
hmrRefreshHash: undefined,
|
|
3718
|
+
varyParamsAccumulator
|
|
2765
3719
|
};
|
|
3720
|
+
if (staleTimeIterable !== undefined) {
|
|
3721
|
+
(0, _staletime.trackStaleTime)(finalServerPrerenderStore, staleTimeIterable, selectStaleTime);
|
|
3722
|
+
}
|
|
2766
3723
|
let prerenderIsPending = true;
|
|
2767
|
-
const
|
|
3724
|
+
const finalRSCPrerenderOptions = {
|
|
3725
|
+
filterStackFrame,
|
|
3726
|
+
onError: (err)=>{
|
|
3727
|
+
return serverComponentsErrorHandler(err);
|
|
3728
|
+
},
|
|
3729
|
+
signal: finalServerReactController.signal
|
|
3730
|
+
};
|
|
3731
|
+
const finalRSCAbortCallback = async ()=>{
|
|
3732
|
+
// Now that the prerendering is complete, we know the final stale
|
|
3733
|
+
// time and vary params. Close the stale time iterable and resolve
|
|
3734
|
+
// the vary params thenable so Flight can serialize their values
|
|
3735
|
+
// into the stream. The timing here is important: both were
|
|
3736
|
+
// included in the Flight payload, but they can only be serialized
|
|
3737
|
+
// at the very end, after all the components have finished.
|
|
3738
|
+
//
|
|
3739
|
+
// We resolve these directly here instead of reading from the work
|
|
3740
|
+
// unit store because this callback runs in a separate task (via
|
|
3741
|
+
// setTimeout) and may not have access to the async storage context.
|
|
3742
|
+
const pendingFinishes = [
|
|
3743
|
+
(0, _varyparams.finishAccumulatingVaryParams)(varyParamsAccumulator)
|
|
3744
|
+
];
|
|
3745
|
+
if (staleTimeIterable !== undefined) {
|
|
3746
|
+
pendingFinishes.push((0, _staletime.finishStaleTimeTracking)(staleTimeIterable));
|
|
3747
|
+
}
|
|
3748
|
+
await Promise.all(pendingFinishes);
|
|
3749
|
+
if (finalServerReactController.signal.aborted) {
|
|
3750
|
+
// If the server controller is already aborted we must have called something
|
|
3751
|
+
// that required aborting the prerender synchronously such as with new Date()
|
|
3752
|
+
serverIsDynamic = true;
|
|
3753
|
+
return;
|
|
3754
|
+
}
|
|
3755
|
+
if (prerenderIsPending) {
|
|
3756
|
+
// If prerenderIsPending then we have blocked for longer than a Task and we assume
|
|
3757
|
+
// there is something unfinished.
|
|
3758
|
+
serverIsDynamic = true;
|
|
3759
|
+
}
|
|
3760
|
+
finalServerReactController.abort();
|
|
3761
|
+
};
|
|
3762
|
+
const finalRSCPrerenderFn = async ()=>{
|
|
2768
3763
|
const pendingPrerenderResult = _workunitasyncstorageexternal.workUnitAsyncStorage.run(// The store to scope
|
|
2769
3764
|
finalServerPrerenderStore, // The function to run
|
|
2770
|
-
ComponentMod
|
|
2771
|
-
finalAttemptRSCPayload, clientModules,
|
|
2772
|
-
filterStackFrame,
|
|
2773
|
-
onError: (err)=>{
|
|
2774
|
-
return serverComponentsErrorHandler(err);
|
|
2775
|
-
},
|
|
2776
|
-
signal: finalServerReactController.signal
|
|
2777
|
-
});
|
|
3765
|
+
(0, _streamops.getServerPrerender)(ComponentMod), // ... the arguments for the function to run
|
|
3766
|
+
finalAttemptRSCPayload, clientModules, finalRSCPrerenderOptions);
|
|
2778
3767
|
// The listener to abort our own render controller must be added
|
|
2779
3768
|
// after React has added its listener, to ensure that pending I/O
|
|
2780
3769
|
// is not aborted/rejected too early.
|
|
@@ -2786,20 +3775,8 @@ async function prerenderToStream(req, res, ctx, metadata, tree, fallbackRoutePar
|
|
|
2786
3775
|
const prerenderResult = await pendingPrerenderResult;
|
|
2787
3776
|
prerenderIsPending = false;
|
|
2788
3777
|
return prerenderResult;
|
|
2789
|
-
}
|
|
2790
|
-
|
|
2791
|
-
// If the server controller is already aborted we must have called something
|
|
2792
|
-
// that required aborting the prerender synchronously such as with new Date()
|
|
2793
|
-
serverIsDynamic = true;
|
|
2794
|
-
return;
|
|
2795
|
-
}
|
|
2796
|
-
if (prerenderIsPending) {
|
|
2797
|
-
// If prerenderIsPending then we have blocked for longer than a Task and we assume
|
|
2798
|
-
// there is something unfinished.
|
|
2799
|
-
serverIsDynamic = true;
|
|
2800
|
-
}
|
|
2801
|
-
finalServerReactController.abort();
|
|
2802
|
-
}));
|
|
3778
|
+
};
|
|
3779
|
+
const reactServerResult = reactServerPrerenderResult = await (0, _apprenderprerenderutils.createReactServerPrerenderResult)((0, _apprenderrenderutils.runInSequentialTasks)(finalRSCPrerenderFn, finalRSCAbortCallback));
|
|
2803
3780
|
const clientDynamicTracking = (0, _dynamicrendering.createDynamicTrackingState)(isDebugDynamicAccesses);
|
|
2804
3781
|
const finalClientReactController = new AbortController();
|
|
2805
3782
|
const finalClientRenderController = new AbortController();
|
|
@@ -2823,12 +3800,14 @@ async function prerenderToStream(req, res, ctx, metadata, tree, fallbackRoutePar
|
|
|
2823
3800
|
],
|
|
2824
3801
|
prerenderResumeDataCache,
|
|
2825
3802
|
renderResumeDataCache,
|
|
2826
|
-
hmrRefreshHash: undefined
|
|
3803
|
+
hmrRefreshHash: undefined,
|
|
3804
|
+
// Client prerenders don't track server param access
|
|
3805
|
+
varyParamsAccumulator: null
|
|
2827
3806
|
};
|
|
2828
3807
|
let dynamicValidation = (0, _dynamicrendering.createDynamicValidationState)();
|
|
2829
|
-
const
|
|
2830
|
-
let { prelude: unprocessedPrelude, postponed } = await (0,
|
|
2831
|
-
const pendingFinalClientResult = _workunitasyncstorageexternal.workUnitAsyncStorage.run(finalClientPrerenderStore,
|
|
3808
|
+
const finalClientOnHeaders = (0, _streamops.createOnHeadersCallback)(appendHeader);
|
|
3809
|
+
let { prelude: unprocessedPrelude, postponed } = await (0, _apprenderrenderutils.runInSequentialTasks)(()=>{
|
|
3810
|
+
const pendingFinalClientResult = _workunitasyncstorageexternal.workUnitAsyncStorage.run(finalClientPrerenderStore, _streamops.getClientPrerender, // eslint-disable-next-line @next/internal/no-ambiguous-jsx
|
|
2832
3811
|
/*#__PURE__*/ (0, _jsxruntime.jsx)(App, {
|
|
2833
3812
|
reactServerStream: reactServerResult.asUnclosingStream(),
|
|
2834
3813
|
reactDebugStream: undefined,
|
|
@@ -2849,11 +3828,7 @@ async function prerenderToStream(req, res, ctx, metadata, tree, fallbackRoutePar
|
|
|
2849
3828
|
}
|
|
2850
3829
|
return htmlRendererErrorHandler(err, errorInfo);
|
|
2851
3830
|
},
|
|
2852
|
-
onHeaders:
|
|
2853
|
-
headers.forEach((value, key)=>{
|
|
2854
|
-
appendHeader(key, value);
|
|
2855
|
-
});
|
|
2856
|
-
},
|
|
3831
|
+
onHeaders: finalClientOnHeaders,
|
|
2857
3832
|
maxHeadersLength: reactMaxHeadersLength,
|
|
2858
3833
|
bootstrapScripts: [
|
|
2859
3834
|
bootstrapScript
|
|
@@ -2871,7 +3846,7 @@ async function prerenderToStream(req, res, ctx, metadata, tree, fallbackRoutePar
|
|
|
2871
3846
|
}, ()=>{
|
|
2872
3847
|
finalClientReactController.abort();
|
|
2873
3848
|
});
|
|
2874
|
-
const { prelude, preludeIsEmpty } = await (0,
|
|
3849
|
+
const { prelude, preludeIsEmpty } = await (0, _streamops.processPrelude)(unprocessedPrelude);
|
|
2875
3850
|
// If we've disabled throwing on empty static shell, then we don't need to
|
|
2876
3851
|
// track any dynamic access that occurs above the suspense boundary because
|
|
2877
3852
|
// we'll do so in the route shell.
|
|
@@ -2885,9 +3860,10 @@ async function prerenderToStream(req, res, ctx, metadata, tree, fallbackRoutePar
|
|
|
2885
3860
|
basePath,
|
|
2886
3861
|
tracingMetadata: tracingMetadata
|
|
2887
3862
|
});
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
3863
|
+
metadata.flightData = await (0, _streamops.streamToBuffer)(cachedNavigations ? prependIsPartialByte(reactServerResult.asStream(), serverIsDynamic) : reactServerResult.asStream());
|
|
3864
|
+
// collectSegmentData needs the raw flight data without the marker byte.
|
|
3865
|
+
const flightData = cachedNavigations ? metadata.flightData.subarray(1) : metadata.flightData;
|
|
3866
|
+
await collectSegmentData(flightData, finalServerPrerenderStore, ComponentMod, renderOpts, ctx.pagePath, metadata);
|
|
2891
3867
|
if (serverIsDynamic) {
|
|
2892
3868
|
// Dynamic case
|
|
2893
3869
|
// We will always need to perform a "resume" render of some kind when this route is accessed
|
|
@@ -2896,26 +3872,28 @@ async function prerenderToStream(req, res, ctx, metadata, tree, fallbackRoutePar
|
|
|
2896
3872
|
// concatenated to the static shell.
|
|
2897
3873
|
if (postponed != null) {
|
|
2898
3874
|
// Dynamic HTML case
|
|
2899
|
-
metadata.postponed = await (0, _postponedstate.getDynamicHTMLPostponedState)(postponed, preludeIsEmpty ? _postponedstate.DynamicHTMLPreludeState.Empty : _postponedstate.DynamicHTMLPreludeState.Full, fallbackRouteParams,
|
|
3875
|
+
metadata.postponed = await (0, _postponedstate.getDynamicHTMLPostponedState)(postponed, preludeIsEmpty ? _postponedstate.DynamicHTMLPreludeState.Empty : _postponedstate.DynamicHTMLPreludeState.Full, fallbackRouteParams, prerenderResumeDataCache, cacheComponents);
|
|
2900
3876
|
} else {
|
|
2901
3877
|
// Dynamic Data case
|
|
2902
|
-
metadata.postponed = await (0, _postponedstate.getDynamicDataPostponedState)(
|
|
3878
|
+
metadata.postponed = await (0, _postponedstate.getDynamicDataPostponedState)(prerenderResumeDataCache, cacheComponents);
|
|
2903
3879
|
}
|
|
2904
3880
|
reactServerResult.consume();
|
|
3881
|
+
const continueDynamicPrerenderOpts = {
|
|
3882
|
+
getServerInsertedHTML,
|
|
3883
|
+
getServerInsertedMetadata,
|
|
3884
|
+
deploymentId: ctx.sharedContext.deploymentId
|
|
3885
|
+
};
|
|
2905
3886
|
return {
|
|
2906
3887
|
digestErrorsMap: reactServerErrorsByDigest,
|
|
2907
3888
|
ssrErrors: allCapturedErrors,
|
|
2908
|
-
stream: await (0,
|
|
2909
|
-
getServerInsertedHTML,
|
|
2910
|
-
getServerInsertedMetadata
|
|
2911
|
-
}),
|
|
3889
|
+
stream: await (0, _streamops.continueDynamicPrerender)(prelude, continueDynamicPrerenderOpts),
|
|
2912
3890
|
dynamicAccess: (0, _dynamicrendering.consumeDynamicAccess)(serverDynamicTracking, clientDynamicTracking),
|
|
2913
3891
|
// TODO: Should this include the SSR pass?
|
|
2914
3892
|
collectedRevalidate: finalServerPrerenderStore.revalidate,
|
|
2915
3893
|
collectedExpire: finalServerPrerenderStore.expire,
|
|
2916
3894
|
collectedStale: selectStaleTime(finalServerPrerenderStore.stale),
|
|
2917
3895
|
collectedTags: finalServerPrerenderStore.tags,
|
|
2918
|
-
renderResumeDataCache: (0, _resumedatacache.createRenderResumeDataCache)(
|
|
3896
|
+
renderResumeDataCache: (0, _resumedatacache.createRenderResumeDataCache)(prerenderResumeDataCache)
|
|
2919
3897
|
};
|
|
2920
3898
|
} else {
|
|
2921
3899
|
// Static case
|
|
@@ -2932,11 +3910,8 @@ async function prerenderToStream(req, res, ctx, metadata, tree, fallbackRoutePar
|
|
|
2932
3910
|
if (postponed != null) {
|
|
2933
3911
|
// We postponed but nothing dynamic was used. We resume the render now and immediately abort it
|
|
2934
3912
|
// so we can set all the postponed boundaries to client render mode before we store the HTML response
|
|
2935
|
-
const
|
|
2936
|
-
|
|
2937
|
-
// that never resolves. The resume call is going to abort immediately anyway
|
|
2938
|
-
const foreverStream = new ReadableStream();
|
|
2939
|
-
const resumeStream = await resume(// eslint-disable-next-line @next/internal/no-ambiguous-jsx
|
|
3913
|
+
const foreverStream = (0, _streamops.createPendingStream)();
|
|
3914
|
+
const resumePrelude = await (0, _streamops.resumeAndAbort)(// eslint-disable-next-line @next/internal/no-ambiguous-jsx
|
|
2940
3915
|
/*#__PURE__*/ (0, _jsxruntime.jsx)(App, {
|
|
2941
3916
|
reactServerStream: foreverStream,
|
|
2942
3917
|
reactDebugStream: undefined,
|
|
@@ -2951,7 +3926,7 @@ async function prerenderToStream(req, res, ctx, metadata, tree, fallbackRoutePar
|
|
|
2951
3926
|
nonce
|
|
2952
3927
|
});
|
|
2953
3928
|
// First we write everything from the prerender, then we write everything from the aborted resume render
|
|
2954
|
-
htmlStream = (0,
|
|
3929
|
+
htmlStream = (0, _streamops.chainStreams)(prelude, resumePrelude);
|
|
2955
3930
|
}
|
|
2956
3931
|
let finalStream;
|
|
2957
3932
|
const hasFallbackRouteParams = fallbackRouteParams && fallbackRouteParams.size > 0;
|
|
@@ -2972,25 +3947,23 @@ async function prerenderToStream(req, res, ctx, metadata, tree, fallbackRoutePar
|
|
|
2972
3947
|
// TODO: In the future, rather than defer the entire hydration payload
|
|
2973
3948
|
// to be fetched by the client, we should only defer the client
|
|
2974
3949
|
// segments, since those are the only ones whose data is not complete.
|
|
2975
|
-
const emptyReactServerResult = await (0, _apprenderprerenderutils.createReactServerPrerenderResultFromRender)(
|
|
3950
|
+
const emptyReactServerResult = await (0, _apprenderprerenderutils.createReactServerPrerenderResultFromRender)((0, _streamops.renderToFlightStream)(ComponentMod, [], clientModules, {
|
|
2976
3951
|
filterStackFrame,
|
|
2977
3952
|
onError: serverComponentsErrorHandler
|
|
2978
3953
|
}));
|
|
2979
|
-
finalStream = await (0,
|
|
2980
|
-
inlinedDataStream: (0,
|
|
3954
|
+
finalStream = await (0, _streamops.continueStaticFallbackPrerender)(htmlStream, {
|
|
3955
|
+
inlinedDataStream: (0, _streamops.createInlinedDataStream)(emptyReactServerResult.consumeAsStream(), nonce, formState),
|
|
2981
3956
|
getServerInsertedHTML,
|
|
2982
3957
|
getServerInsertedMetadata,
|
|
2983
|
-
|
|
2984
|
-
buildId: ctx.workStore.buildId
|
|
3958
|
+
deploymentId: ctx.sharedContext.deploymentId
|
|
2985
3959
|
});
|
|
2986
3960
|
} else {
|
|
2987
3961
|
// Normal static prerender case, no fallback param handling needed
|
|
2988
|
-
finalStream = await (0,
|
|
2989
|
-
inlinedDataStream: (0,
|
|
3962
|
+
finalStream = await (0, _streamops.continueStaticPrerender)(htmlStream, {
|
|
3963
|
+
inlinedDataStream: (0, _streamops.createInlinedDataStream)(reactServerResult.consumeAsStream(), nonce, formState),
|
|
2990
3964
|
getServerInsertedHTML,
|
|
2991
3965
|
getServerInsertedMetadata,
|
|
2992
|
-
|
|
2993
|
-
buildId: ctx.workStore.buildId
|
|
3966
|
+
deploymentId: ctx.sharedContext.deploymentId
|
|
2994
3967
|
});
|
|
2995
3968
|
}
|
|
2996
3969
|
return {
|
|
@@ -3003,7 +3976,7 @@ async function prerenderToStream(req, res, ctx, metadata, tree, fallbackRoutePar
|
|
|
3003
3976
|
collectedExpire: finalServerPrerenderStore.expire,
|
|
3004
3977
|
collectedStale: selectStaleTime(finalServerPrerenderStore.stale),
|
|
3005
3978
|
collectedTags: finalServerPrerenderStore.tags,
|
|
3006
|
-
renderResumeDataCache: (0, _resumedatacache.createRenderResumeDataCache)(
|
|
3979
|
+
renderResumeDataCache: (0, _resumedatacache.createRenderResumeDataCache)(prerenderResumeDataCache)
|
|
3007
3980
|
};
|
|
3008
3981
|
}
|
|
3009
3982
|
} else if (experimental.isRoutePPREnabled) {
|
|
@@ -3025,9 +3998,11 @@ async function prerenderToStream(req, res, ctx, metadata, tree, fallbackRoutePar
|
|
|
3025
3998
|
],
|
|
3026
3999
|
prerenderResumeDataCache
|
|
3027
4000
|
};
|
|
3028
|
-
const RSCPayload = await _workunitasyncstorageexternal.workUnitAsyncStorage.run(reactServerPrerenderStore, getRSCPayload, tree, ctx,
|
|
3029
|
-
|
|
3030
|
-
|
|
4001
|
+
const RSCPayload = await _workunitasyncstorageexternal.workUnitAsyncStorage.run(reactServerPrerenderStore, getRSCPayload, tree, ctx, {
|
|
4002
|
+
is404: res.statusCode === 404
|
|
4003
|
+
});
|
|
4004
|
+
let reactServerResult;
|
|
4005
|
+
reactServerResult = reactServerPrerenderResult = await (0, _apprenderprerenderutils.createReactServerPrerenderResultFromRender)(_workunitasyncstorageexternal.workUnitAsyncStorage.run(reactServerPrerenderStore, _streamops.renderToFlightStream, ComponentMod, RSCPayload, clientModules, {
|
|
3031
4006
|
filterStackFrame,
|
|
3032
4007
|
onError: serverComponentsErrorHandler
|
|
3033
4008
|
}));
|
|
@@ -3046,8 +4021,8 @@ async function prerenderToStream(req, res, ctx, metadata, tree, fallbackRoutePar
|
|
|
3046
4021
|
],
|
|
3047
4022
|
prerenderResumeDataCache
|
|
3048
4023
|
};
|
|
3049
|
-
const
|
|
3050
|
-
const { prelude: unprocessedPrelude, postponed } = await _workunitasyncstorageexternal.workUnitAsyncStorage.run(ssrPrerenderStore,
|
|
4024
|
+
const pprOnHeaders = (0, _streamops.createOnHeadersCallback)(appendHeader);
|
|
4025
|
+
const { prelude: unprocessedPrelude, postponed } = await _workunitasyncstorageexternal.workUnitAsyncStorage.run(ssrPrerenderStore, _streamops.getClientPrerender, // eslint-disable-next-line @next/internal/no-ambiguous-jsx
|
|
3051
4026
|
/*#__PURE__*/ (0, _jsxruntime.jsx)(App, {
|
|
3052
4027
|
reactServerStream: reactServerResult.asUnclosingStream(),
|
|
3053
4028
|
reactDebugStream: undefined,
|
|
@@ -3058,11 +4033,7 @@ async function prerenderToStream(req, res, ctx, metadata, tree, fallbackRoutePar
|
|
|
3058
4033
|
images: ctx.renderOpts.images
|
|
3059
4034
|
}), {
|
|
3060
4035
|
onError: htmlRendererErrorHandler,
|
|
3061
|
-
onHeaders:
|
|
3062
|
-
headers.forEach((value, key)=>{
|
|
3063
|
-
appendHeader(key, value);
|
|
3064
|
-
});
|
|
3065
|
-
},
|
|
4036
|
+
onHeaders: pprOnHeaders,
|
|
3066
4037
|
maxHeadersLength: reactMaxHeadersLength,
|
|
3067
4038
|
bootstrapScripts: [
|
|
3068
4039
|
bootstrapScript
|
|
@@ -3078,12 +4049,12 @@ async function prerenderToStream(req, res, ctx, metadata, tree, fallbackRoutePar
|
|
|
3078
4049
|
// After awaiting here we've waited for the entire RSC render to complete. Crucially this means
|
|
3079
4050
|
// that when we detect whether we've used dynamic APIs below we know we'll have picked up even
|
|
3080
4051
|
// parts of the React Server render that might not be used in the SSR render.
|
|
3081
|
-
const flightData = await (0,
|
|
4052
|
+
const flightData = await (0, _streamops.streamToBuffer)(reactServerResult.asStream());
|
|
3082
4053
|
if (shouldGenerateStaticFlightData(workStore)) {
|
|
3083
4054
|
metadata.flightData = flightData;
|
|
3084
|
-
|
|
4055
|
+
await collectSegmentData(flightData, ssrPrerenderStore, ComponentMod, renderOpts, ctx.pagePath, metadata);
|
|
3085
4056
|
}
|
|
3086
|
-
const { prelude, preludeIsEmpty } = await (0,
|
|
4057
|
+
const { prelude, preludeIsEmpty } = await (0, _streamops.processPrelude)(unprocessedPrelude);
|
|
3087
4058
|
/**
|
|
3088
4059
|
* When prerendering there are three outcomes to consider
|
|
3089
4060
|
*
|
|
@@ -3111,13 +4082,15 @@ async function prerenderToStream(req, res, ctx, metadata, tree, fallbackRoutePar
|
|
|
3111
4082
|
// It is possible in the set of stream transforms for Dynamic HTML vs Dynamic Data may differ but currently both states
|
|
3112
4083
|
// require the same set so we unify the code path here
|
|
3113
4084
|
reactServerResult.consume();
|
|
4085
|
+
const pprDynamicOpts = {
|
|
4086
|
+
getServerInsertedHTML,
|
|
4087
|
+
getServerInsertedMetadata,
|
|
4088
|
+
deploymentId: ctx.sharedContext.deploymentId
|
|
4089
|
+
};
|
|
3114
4090
|
return {
|
|
3115
4091
|
digestErrorsMap: reactServerErrorsByDigest,
|
|
3116
4092
|
ssrErrors: allCapturedErrors,
|
|
3117
|
-
stream: await (0,
|
|
3118
|
-
getServerInsertedHTML,
|
|
3119
|
-
getServerInsertedMetadata
|
|
3120
|
-
}),
|
|
4093
|
+
stream: await (0, _streamops.continueDynamicPrerender)(prelude, pprDynamicOpts),
|
|
3121
4094
|
dynamicAccess: dynamicTracking.dynamicAccesses,
|
|
3122
4095
|
// TODO: Should this include the SSR pass?
|
|
3123
4096
|
collectedRevalidate: reactServerPrerenderStore.revalidate,
|
|
@@ -3128,13 +4101,15 @@ async function prerenderToStream(req, res, ctx, metadata, tree, fallbackRoutePar
|
|
|
3128
4101
|
} else if (fallbackRouteParams && fallbackRouteParams.size > 0) {
|
|
3129
4102
|
// Rendering the fallback case.
|
|
3130
4103
|
metadata.postponed = await (0, _postponedstate.getDynamicDataPostponedState)(prerenderResumeDataCache, cacheComponents);
|
|
4104
|
+
const pprFallbackDynamicOpts = {
|
|
4105
|
+
getServerInsertedHTML,
|
|
4106
|
+
getServerInsertedMetadata,
|
|
4107
|
+
deploymentId: ctx.sharedContext.deploymentId
|
|
4108
|
+
};
|
|
3131
4109
|
return {
|
|
3132
4110
|
digestErrorsMap: reactServerErrorsByDigest,
|
|
3133
4111
|
ssrErrors: allCapturedErrors,
|
|
3134
|
-
stream: await (0,
|
|
3135
|
-
getServerInsertedHTML,
|
|
3136
|
-
getServerInsertedMetadata
|
|
3137
|
-
}),
|
|
4112
|
+
stream: await (0, _streamops.continueDynamicPrerender)(prelude, pprFallbackDynamicOpts),
|
|
3138
4113
|
dynamicAccess: dynamicTracking.dynamicAccesses,
|
|
3139
4114
|
// TODO: Should this include the SSR pass?
|
|
3140
4115
|
collectedRevalidate: reactServerPrerenderStore.revalidate,
|
|
@@ -3156,11 +4131,8 @@ async function prerenderToStream(req, res, ctx, metadata, tree, fallbackRoutePar
|
|
|
3156
4131
|
if (postponed != null) {
|
|
3157
4132
|
// We postponed but nothing dynamic was used. We resume the render now and immediately abort it
|
|
3158
4133
|
// so we can set all the postponed boundaries to client render mode before we store the HTML response
|
|
3159
|
-
const
|
|
3160
|
-
|
|
3161
|
-
// that never resolves. The resume call is going to abort immediately anyway
|
|
3162
|
-
const foreverStream = new ReadableStream();
|
|
3163
|
-
const resumeStream = await resume(// eslint-disable-next-line @next/internal/no-ambiguous-jsx
|
|
4134
|
+
const foreverStream = (0, _streamops.createPendingStream)();
|
|
4135
|
+
const resumePrelude = await (0, _streamops.resumeAndAbort)(// eslint-disable-next-line @next/internal/no-ambiguous-jsx
|
|
3164
4136
|
/*#__PURE__*/ (0, _jsxruntime.jsx)(App, {
|
|
3165
4137
|
reactServerStream: foreverStream,
|
|
3166
4138
|
reactDebugStream: undefined,
|
|
@@ -3175,17 +4147,16 @@ async function prerenderToStream(req, res, ctx, metadata, tree, fallbackRoutePar
|
|
|
3175
4147
|
nonce
|
|
3176
4148
|
});
|
|
3177
4149
|
// First we write everything from the prerender, then we write everything from the aborted resume render
|
|
3178
|
-
htmlStream = (0,
|
|
4150
|
+
htmlStream = (0, _streamops.chainStreams)(prelude, resumePrelude);
|
|
3179
4151
|
}
|
|
3180
4152
|
return {
|
|
3181
4153
|
digestErrorsMap: reactServerErrorsByDigest,
|
|
3182
4154
|
ssrErrors: allCapturedErrors,
|
|
3183
|
-
stream: await (0,
|
|
3184
|
-
inlinedDataStream: (0,
|
|
4155
|
+
stream: await (0, _streamops.continueStaticPrerender)(htmlStream, {
|
|
4156
|
+
inlinedDataStream: (0, _streamops.createInlinedDataStream)(reactServerResult.consumeAsStream(), nonce, formState),
|
|
3185
4157
|
getServerInsertedHTML,
|
|
3186
4158
|
getServerInsertedMetadata,
|
|
3187
|
-
|
|
3188
|
-
buildId: ctx.workStore.buildId
|
|
4159
|
+
deploymentId: ctx.sharedContext.deploymentId
|
|
3189
4160
|
}),
|
|
3190
4161
|
dynamicAccess: dynamicTracking.dynamicAccesses,
|
|
3191
4162
|
// TODO: Should this include the SSR pass?
|
|
@@ -3210,13 +4181,15 @@ async function prerenderToStream(req, res, ctx, metadata, tree, fallbackRoutePar
|
|
|
3210
4181
|
};
|
|
3211
4182
|
// This is a regular static generation. We don't do dynamic tracking because we rely on
|
|
3212
4183
|
// the old-school dynamic error handling to bail out of static generation
|
|
3213
|
-
const RSCPayload = await _workunitasyncstorageexternal.workUnitAsyncStorage.run(prerenderLegacyStore, getRSCPayload, tree, ctx,
|
|
3214
|
-
|
|
4184
|
+
const RSCPayload = await _workunitasyncstorageexternal.workUnitAsyncStorage.run(prerenderLegacyStore, getRSCPayload, tree, ctx, {
|
|
4185
|
+
is404: res.statusCode === 404
|
|
4186
|
+
});
|
|
4187
|
+
let reactServerResult;
|
|
4188
|
+
reactServerResult = reactServerPrerenderResult = await (0, _apprenderprerenderutils.createReactServerPrerenderResultFromRender)(_workunitasyncstorageexternal.workUnitAsyncStorage.run(prerenderLegacyStore, _streamops.renderToFlightStream, ComponentMod, RSCPayload, clientModules, {
|
|
3215
4189
|
filterStackFrame,
|
|
3216
4190
|
onError: serverComponentsErrorHandler
|
|
3217
4191
|
}));
|
|
3218
|
-
const
|
|
3219
|
-
const htmlStream = await _workunitasyncstorageexternal.workUnitAsyncStorage.run(prerenderLegacyStore, renderToReadableStream, // eslint-disable-next-line @next/internal/no-ambiguous-jsx
|
|
4192
|
+
const { stream: htmlStream } = await _workunitasyncstorageexternal.workUnitAsyncStorage.run(prerenderLegacyStore, _streamops.renderToFizzStream, // eslint-disable-next-line @next/internal/no-ambiguous-jsx
|
|
3220
4193
|
/*#__PURE__*/ (0, _jsxruntime.jsx)(App, {
|
|
3221
4194
|
reactServerStream: reactServerResult.asUnclosingStream(),
|
|
3222
4195
|
reactDebugStream: undefined,
|
|
@@ -3233,9 +4206,9 @@ async function prerenderToStream(req, res, ctx, metadata, tree, fallbackRoutePar
|
|
|
3233
4206
|
]
|
|
3234
4207
|
});
|
|
3235
4208
|
if (shouldGenerateStaticFlightData(workStore)) {
|
|
3236
|
-
const flightData = await (0,
|
|
4209
|
+
const flightData = await (0, _streamops.streamToBuffer)(reactServerResult.asStream());
|
|
3237
4210
|
metadata.flightData = flightData;
|
|
3238
|
-
|
|
4211
|
+
await collectSegmentData(flightData, prerenderLegacyStore, ComponentMod, renderOpts, ctx.pagePath, metadata);
|
|
3239
4212
|
}
|
|
3240
4213
|
const getServerInsertedHTML = (0, _makegetserverinsertedhtml.makeGetServerInsertedHTML)({
|
|
3241
4214
|
polyfills,
|
|
@@ -3247,13 +4220,12 @@ async function prerenderToStream(req, res, ctx, metadata, tree, fallbackRoutePar
|
|
|
3247
4220
|
return {
|
|
3248
4221
|
digestErrorsMap: reactServerErrorsByDigest,
|
|
3249
4222
|
ssrErrors: allCapturedErrors,
|
|
3250
|
-
stream: await (0,
|
|
3251
|
-
inlinedDataStream: (0,
|
|
4223
|
+
stream: await (0, _streamops.continueFizzStream)(htmlStream, {
|
|
4224
|
+
inlinedDataStream: (0, _streamops.createInlinedDataStream)(reactServerResult.consumeAsStream(), nonce, formState),
|
|
3252
4225
|
isStaticGeneration: true,
|
|
3253
|
-
isBuildTimePrerendering: ctx.workStore.isBuildTimePrerendering === true,
|
|
3254
|
-
buildId: ctx.workStore.buildId,
|
|
3255
4226
|
getServerInsertedHTML,
|
|
3256
|
-
getServerInsertedMetadata
|
|
4227
|
+
getServerInsertedMetadata,
|
|
4228
|
+
deploymentId: ctx.sharedContext.deploymentId
|
|
3257
4229
|
}),
|
|
3258
4230
|
// TODO: Should this include the SSR pass?
|
|
3259
4231
|
collectedRevalidate: prerenderLegacyStore.revalidate,
|
|
@@ -3314,51 +4286,39 @@ async function prerenderToStream(req, res, ctx, metadata, tree, fallbackRoutePar
|
|
|
3314
4286
|
]
|
|
3315
4287
|
};
|
|
3316
4288
|
const errorRSCPayload = await _workunitasyncstorageexternal.workUnitAsyncStorage.run(prerenderLegacyStore, getErrorRSCPayload, tree, ctx, reactServerErrorsByDigest.has(err.digest) ? undefined : err, errorType);
|
|
3317
|
-
const errorServerStream = _workunitasyncstorageexternal.workUnitAsyncStorage.run(prerenderLegacyStore,
|
|
4289
|
+
const errorServerStream = _workunitasyncstorageexternal.workUnitAsyncStorage.run(prerenderLegacyStore, _streamops.renderToFlightStream, ComponentMod, errorRSCPayload, clientModules, {
|
|
3318
4290
|
filterStackFrame,
|
|
3319
4291
|
onError: serverComponentsErrorHandler
|
|
3320
4292
|
});
|
|
3321
4293
|
try {
|
|
3322
|
-
|
|
3323
|
-
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3334
|
-
|
|
3335
|
-
streamOptions: {
|
|
3336
|
-
nonce,
|
|
3337
|
-
// Include hydration scripts in the HTML
|
|
3338
|
-
bootstrapScripts: [
|
|
3339
|
-
errorBootstrapScript
|
|
3340
|
-
],
|
|
3341
|
-
formState
|
|
3342
|
-
}
|
|
4294
|
+
const { stream: errorHtmlStream } = await _workunitasyncstorageexternal.workUnitAsyncStorage.run(prerenderLegacyStore, _streamops.renderToFizzStream, // eslint-disable-next-line @next/internal/no-ambiguous-jsx
|
|
4295
|
+
/*#__PURE__*/ (0, _jsxruntime.jsx)(ErrorApp, {
|
|
4296
|
+
reactServerStream: errorServerStream,
|
|
4297
|
+
ServerInsertedHTMLProvider: ServerInsertedHTMLProvider,
|
|
4298
|
+
preinitScripts: errorPreinitScripts,
|
|
4299
|
+
nonce: nonce,
|
|
4300
|
+
images: ctx.renderOpts.images
|
|
4301
|
+
}), {
|
|
4302
|
+
nonce,
|
|
4303
|
+
bootstrapScripts: [
|
|
4304
|
+
errorBootstrapScript
|
|
4305
|
+
],
|
|
4306
|
+
formState
|
|
3343
4307
|
});
|
|
3344
4308
|
if (shouldGenerateStaticFlightData(workStore)) {
|
|
3345
|
-
const flightData = await (0,
|
|
4309
|
+
const flightData = await (0, _streamops.streamToBuffer)(reactServerPrerenderResult.asStream());
|
|
3346
4310
|
metadata.flightData = flightData;
|
|
3347
|
-
|
|
4311
|
+
await collectSegmentData(flightData, prerenderLegacyStore, ComponentMod, renderOpts, ctx.pagePath, metadata);
|
|
3348
4312
|
}
|
|
3349
4313
|
// This is intentionally using the readable datastream from the main
|
|
3350
4314
|
// render rather than the flight data from the error page render
|
|
3351
4315
|
const flightStream = reactServerPrerenderResult.consumeAsStream();
|
|
3352
4316
|
return {
|
|
3353
|
-
// Returning the error that was thrown so it can be used to handle
|
|
3354
|
-
// the response in the caller.
|
|
3355
4317
|
digestErrorsMap: reactServerErrorsByDigest,
|
|
3356
4318
|
ssrErrors: allCapturedErrors,
|
|
3357
|
-
stream: await (0,
|
|
3358
|
-
inlinedDataStream: (0,
|
|
4319
|
+
stream: await (0, _streamops.continueFizzStream)(errorHtmlStream, {
|
|
4320
|
+
inlinedDataStream: (0, _streamops.createInlinedDataStream)(flightStream, nonce, formState),
|
|
3359
4321
|
isStaticGeneration: true,
|
|
3360
|
-
isBuildTimePrerendering: ctx.workStore.isBuildTimePrerendering === true,
|
|
3361
|
-
buildId: ctx.workStore.buildId,
|
|
3362
4322
|
getServerInsertedHTML: (0, _makegetserverinsertedhtml.makeGetServerInsertedHTML)({
|
|
3363
4323
|
polyfills,
|
|
3364
4324
|
renderServerInsertedHTML,
|
|
@@ -3367,7 +4327,8 @@ async function prerenderToStream(req, res, ctx, metadata, tree, fallbackRoutePar
|
|
|
3367
4327
|
tracingMetadata: tracingMetadata
|
|
3368
4328
|
}),
|
|
3369
4329
|
getServerInsertedMetadata,
|
|
3370
|
-
validateRootLayout:
|
|
4330
|
+
validateRootLayout: !!process.env.__NEXT_DEV_SERVER,
|
|
4331
|
+
deploymentId: ctx.sharedContext.deploymentId
|
|
3371
4332
|
}),
|
|
3372
4333
|
dynamicAccess: null,
|
|
3373
4334
|
collectedRevalidate: prerenderStore !== null ? prerenderStore.revalidate : _constants1.INFINITE_CACHE,
|
|
@@ -3376,7 +4337,7 @@ async function prerenderToStream(req, res, ctx, metadata, tree, fallbackRoutePar
|
|
|
3376
4337
|
collectedTags: prerenderStore !== null ? prerenderStore.tags : null
|
|
3377
4338
|
};
|
|
3378
4339
|
} catch (finalErr) {
|
|
3379
|
-
if (process.env.
|
|
4340
|
+
if (process.env.__NEXT_DEV_SERVER && (0, _httpaccessfallback.isHTTPAccessFallbackError)(finalErr)) {
|
|
3380
4341
|
const { bailOnRootNotFound } = require('../../client/components/dev-root-http-access-fallback-boundary');
|
|
3381
4342
|
bailOnRootNotFound();
|
|
3382
4343
|
}
|
|
@@ -3385,23 +4346,27 @@ async function prerenderToStream(req, res, ctx, metadata, tree, fallbackRoutePar
|
|
|
3385
4346
|
}
|
|
3386
4347
|
}
|
|
3387
4348
|
const getGlobalErrorStyles = async (tree, ctx)=>{
|
|
3388
|
-
const
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
ctx,
|
|
3395
|
-
filePath: globalErrorModule[1],
|
|
3396
|
-
getComponent: globalErrorModule[0],
|
|
3397
|
-
injectedCSS: new Set(),
|
|
3398
|
-
injectedJS: new Set()
|
|
4349
|
+
const globalErrorModule = (0, _parseloadertree.parseLoaderTree)(tree).modules['global-error'];
|
|
4350
|
+
if (!globalErrorModule) {
|
|
4351
|
+
throw Object.defineProperty(new Error('Invariant: global-error module is required but not found in loader tree'), "__NEXT_ERROR_CODE", {
|
|
4352
|
+
value: "E983",
|
|
4353
|
+
enumerable: false,
|
|
4354
|
+
configurable: true
|
|
3399
4355
|
});
|
|
3400
|
-
globalErrorStyles = styles;
|
|
3401
4356
|
}
|
|
3402
|
-
|
|
4357
|
+
const { componentMod: { createElement } } = ctx;
|
|
4358
|
+
// Get the GlobalError component and styles from the loader tree
|
|
4359
|
+
const [GlobalErrorComponent, styles] = await (0, _createcomponentstylesandscripts.createComponentStylesAndScripts)({
|
|
4360
|
+
ctx,
|
|
4361
|
+
filePath: globalErrorModule[1],
|
|
4362
|
+
getComponent: globalErrorModule[0],
|
|
4363
|
+
injectedCSS: new Set(),
|
|
4364
|
+
injectedJS: new Set()
|
|
4365
|
+
});
|
|
4366
|
+
let globalErrorStyles = styles;
|
|
4367
|
+
if (process.env.__NEXT_DEV_SERVER) {
|
|
3403
4368
|
const dir = (process.env.NEXT_RUNTIME === 'edge' ? process.env.__NEXT_EDGE_PROJECT_DIR : ctx.renderOpts.dir) || '';
|
|
3404
|
-
const globalErrorModulePath = (0, _segmentexplorerpath.normalizeConventionFilePath)(dir, globalErrorModule
|
|
4369
|
+
const globalErrorModulePath = (0, _segmentexplorerpath.normalizeConventionFilePath)(dir, globalErrorModule[1]);
|
|
3405
4370
|
if (globalErrorModulePath) {
|
|
3406
4371
|
const SegmentViewNode = ctx.componentMod.SegmentViewNode;
|
|
3407
4372
|
globalErrorStyles = // This will be rendered next to GlobalError component under ErrorBoundary,
|
|
@@ -3418,13 +4383,7 @@ const getGlobalErrorStyles = async (tree, ctx)=>{
|
|
|
3418
4383
|
styles: globalErrorStyles
|
|
3419
4384
|
};
|
|
3420
4385
|
};
|
|
3421
|
-
function
|
|
3422
|
-
return (stale)=>{
|
|
3423
|
-
var _experimental_staleTimes;
|
|
3424
|
-
return stale === _constants1.INFINITE_CACHE && typeof ((_experimental_staleTimes = experimental.staleTimes) == null ? void 0 : _experimental_staleTimes.static) === 'number' ? experimental.staleTimes.static : stale;
|
|
3425
|
-
};
|
|
3426
|
-
}
|
|
3427
|
-
async function collectSegmentData(fullPageDataBuffer, prerenderStore, ComponentMod, renderOpts) {
|
|
4386
|
+
async function collectSegmentData(fullPageDataBuffer, prerenderStore, ComponentMod, renderOpts, pagePath, metadata) {
|
|
3428
4387
|
// Per-segment prefetch data
|
|
3429
4388
|
//
|
|
3430
4389
|
// All of the segments for a page are generated simultaneously, including
|
|
@@ -3449,12 +4408,35 @@ async function collectSegmentData(fullPageDataBuffer, prerenderStore, ComponentM
|
|
|
3449
4408
|
moduleMap: isEdgeRuntime ? edgeRscModuleMapping : rscModuleMapping,
|
|
3450
4409
|
serverModuleMap: (0, _manifestssingleton.getServerModuleMap)()
|
|
3451
4410
|
};
|
|
3452
|
-
const selectStaleTime = createSelectStaleTime(renderOpts.experimental);
|
|
4411
|
+
const selectStaleTime = (0, _staletime.createSelectStaleTime)(renderOpts.experimental);
|
|
3453
4412
|
const staleTime = selectStaleTime(prerenderStore.stale);
|
|
3454
|
-
|
|
4413
|
+
// Resolve prefetch hints. At runtime (next start / ISR), the precomputed
|
|
4414
|
+
// hints are already loaded from the prefetch-hints.json manifest. During
|
|
4415
|
+
// build, compute them by measuring segment gzip sizes and write them to
|
|
4416
|
+
// metadata so the build pipeline can persist them to the manifest.
|
|
4417
|
+
let hints;
|
|
4418
|
+
const prefetchInlining = renderOpts.experimental.prefetchInlining;
|
|
4419
|
+
if (!prefetchInlining) {
|
|
4420
|
+
hints = null;
|
|
4421
|
+
} else if (renderOpts.isBuildTimePrerendering) {
|
|
4422
|
+
// Build time: compute fresh hints and store in metadata for the manifest.
|
|
4423
|
+
hints = await ComponentMod.collectPrefetchHints(fullPageDataBuffer, staleTime, clientModules, serverConsumerManifest, prefetchInlining.maxSize, prefetchInlining.maxBundleSize);
|
|
4424
|
+
metadata.prefetchHints = hints;
|
|
4425
|
+
} else {
|
|
4426
|
+
var _renderOpts_prefetchHints;
|
|
4427
|
+
// Runtime: use hints from the manifest. Never compute fresh hints
|
|
4428
|
+
// during ISR/revalidation.
|
|
4429
|
+
hints = ((_renderOpts_prefetchHints = renderOpts.prefetchHints) == null ? void 0 : _renderOpts_prefetchHints[pagePath]) ?? null;
|
|
4430
|
+
}
|
|
4431
|
+
// Pass the resolved hints so collectSegmentData can union them into
|
|
4432
|
+
// the TreePrefetch. During the initial build the FlightRouterState in
|
|
4433
|
+
// the buffer doesn't have inlining hints yet (they were just computed
|
|
4434
|
+
// above), so we need to merge them in here. At runtime/ISR the hints
|
|
4435
|
+
// are already embedded in the FlightRouterState, so this is null.
|
|
4436
|
+
metadata.segmentData = await ComponentMod.collectSegmentData(renderOpts.cacheComponents, fullPageDataBuffer, staleTime, clientModules, serverConsumerManifest, Boolean(renderOpts.experimental.prefetchInlining), hints);
|
|
3455
4437
|
}
|
|
3456
|
-
function isBypassingCachesInDev(
|
|
3457
|
-
return process.env.
|
|
4438
|
+
function isBypassingCachesInDev(requestStore) {
|
|
4439
|
+
return !!process.env.__NEXT_DEV_SERVER && requestStore.headers.get('cache-control') === 'no-cache';
|
|
3458
4440
|
}
|
|
3459
4441
|
function WarnForBypassCachesInDev({ route }) {
|
|
3460
4442
|
(0, _warnonce.warnOnce)(`Route ${route} is rendering with server caches disabled. For this navigation, Component Metadata in React DevTools will not accurately reflect what is statically prerenderable and runtime prefetchable. See more info here: https://nextjs.org/docs/messages/cache-bypass-in-dev`);
|
|
@@ -3483,44 +4465,5 @@ function nodeStreamFromReadableStream(stream) {
|
|
|
3483
4465
|
});
|
|
3484
4466
|
}
|
|
3485
4467
|
}
|
|
3486
|
-
function createNodeStreamFromChunks(partialChunks, allChunks, signal) {
|
|
3487
|
-
if (process.env.NEXT_RUNTIME === 'edge') {
|
|
3488
|
-
throw Object.defineProperty(new _invarianterror.InvariantError('createNodeStreamFromChunks cannot be used in the edge runtime'), "__NEXT_ERROR_CODE", {
|
|
3489
|
-
value: "E945",
|
|
3490
|
-
enumerable: false,
|
|
3491
|
-
configurable: true
|
|
3492
|
-
});
|
|
3493
|
-
} else {
|
|
3494
|
-
const { Readable } = require('node:stream');
|
|
3495
|
-
let nextIndex = 0;
|
|
3496
|
-
const readable = new Readable({
|
|
3497
|
-
read () {
|
|
3498
|
-
while(nextIndex < partialChunks.length){
|
|
3499
|
-
this.push(partialChunks[nextIndex]);
|
|
3500
|
-
nextIndex++;
|
|
3501
|
-
}
|
|
3502
|
-
}
|
|
3503
|
-
});
|
|
3504
|
-
signal.addEventListener('abort', ()=>{
|
|
3505
|
-
// Flush any remaining chunks from the original set
|
|
3506
|
-
while(nextIndex < partialChunks.length){
|
|
3507
|
-
readable.push(partialChunks[nextIndex]);
|
|
3508
|
-
nextIndex++;
|
|
3509
|
-
}
|
|
3510
|
-
// Flush all chunks since we're now aborted and can't schedule
|
|
3511
|
-
// any new work but these chunks might unblock debugInfo
|
|
3512
|
-
while(nextIndex < allChunks.length){
|
|
3513
|
-
readable.push(allChunks[nextIndex]);
|
|
3514
|
-
nextIndex++;
|
|
3515
|
-
}
|
|
3516
|
-
setImmediate(()=>{
|
|
3517
|
-
readable.push(null);
|
|
3518
|
-
});
|
|
3519
|
-
}, {
|
|
3520
|
-
once: true
|
|
3521
|
-
});
|
|
3522
|
-
return readable;
|
|
3523
|
-
}
|
|
3524
|
-
}
|
|
3525
4468
|
|
|
3526
4469
|
//# sourceMappingURL=app-render.js.map
|