@semiont/frontend 0.3.3 → 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 +8 -8
- 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 +8 -8
- package/standalone/apps/frontend/.next/server/chunks/2617.js +43 -7
- package/standalone/apps/frontend/.next/server/chunks/3144.js +1 -1
- 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-ac307b22cd0a4080.js → common-42653c14d34c8864.js} +7 -7
- 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/framework-86c2a58f458066a5.js +0 -1
- package/standalone/apps/frontend/.next/static/chunks/vendors-c7197feb11002a6e.js +0 -10
- package/standalone/apps/frontend/.next/static/xSLAuzRvOCf1TdGHvLFQ0/_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/{xSLAuzRvOCf1TdGHvLFQ0 → I_XveRdyStDMqYJPcAAy5}/_ssgManifest.js +0 -0
package/standalone/node_modules/next/dist/client/components/router-reducer/ppr-navigations.js
CHANGED
|
@@ -32,59 +32,56 @@ _export(exports, {
|
|
|
32
32
|
return startPPRNavigation;
|
|
33
33
|
}
|
|
34
34
|
});
|
|
35
|
+
const _approutertypes = require("../../../shared/lib/app-router-types");
|
|
35
36
|
const _segment = require("../../../shared/lib/segment");
|
|
36
37
|
const _matchsegments = require("../match-segments");
|
|
37
38
|
const _createhreffromurl = require("./create-href-from-url");
|
|
38
|
-
const _createroutercachekey = require("./create-router-cache-key");
|
|
39
39
|
const _fetchserverresponse = require("./fetch-server-response");
|
|
40
40
|
const _useactionqueue = require("../use-action-queue");
|
|
41
41
|
const _routerreducertypes = require("./router-reducer-types");
|
|
42
42
|
const _isnavigatingtonewrootlayout = require("./is-navigating-to-new-root-layout");
|
|
43
|
-
const
|
|
43
|
+
const _committedstate = require("./reducers/committed-state");
|
|
44
44
|
const _navigation = require("../segment-cache/navigation");
|
|
45
|
+
const _cache = require("../segment-cache/cache");
|
|
46
|
+
const _types = require("../segment-cache/types");
|
|
47
|
+
const _optimisticroutes = require("../segment-cache/optimistic-routes");
|
|
48
|
+
const _constants = require("../../../lib/constants");
|
|
49
|
+
const _varypath = require("../segment-cache/vary-path");
|
|
50
|
+
const _bfcache = require("../segment-cache/bfcache");
|
|
45
51
|
var FreshnessPolicy = /*#__PURE__*/ function(FreshnessPolicy) {
|
|
46
52
|
FreshnessPolicy[FreshnessPolicy["Default"] = 0] = "Default";
|
|
47
53
|
FreshnessPolicy[FreshnessPolicy["Hydration"] = 1] = "Hydration";
|
|
48
54
|
FreshnessPolicy[FreshnessPolicy["HistoryTraversal"] = 2] = "HistoryTraversal";
|
|
49
55
|
FreshnessPolicy[FreshnessPolicy["RefreshAll"] = 3] = "RefreshAll";
|
|
50
56
|
FreshnessPolicy[FreshnessPolicy["HMRRefresh"] = 4] = "HMRRefresh";
|
|
57
|
+
FreshnessPolicy[FreshnessPolicy["Gesture"] = 5] = "Gesture";
|
|
51
58
|
return FreshnessPolicy;
|
|
52
59
|
}({});
|
|
53
60
|
const noop = ()=>{};
|
|
54
|
-
function createInitialCacheNodeForHydration(navigatedAt, initialTree, seedData, seedHead) {
|
|
61
|
+
function createInitialCacheNodeForHydration(navigatedAt, initialTree, seedData, seedHead, seedDynamicStaleAt) {
|
|
55
62
|
// Create the initial cache node tree, using the data embedded into the
|
|
56
63
|
// HTML document.
|
|
57
64
|
const accumulation = {
|
|
58
|
-
|
|
59
|
-
|
|
65
|
+
separateRefreshUrls: null,
|
|
66
|
+
scrollRef: null
|
|
60
67
|
};
|
|
61
|
-
const task = createCacheNodeOnNavigation(navigatedAt, initialTree,
|
|
62
|
-
|
|
63
|
-
// server. We assume the initial hydration payload is sufficient to render
|
|
64
|
-
// the page.
|
|
65
|
-
//
|
|
66
|
-
// The completeness of the initial data is an important property that we rely
|
|
67
|
-
// on as a last-ditch mechanism for recovering the app; we must always be able
|
|
68
|
-
// to reload a fresh HTML document to get to a consistent state.
|
|
69
|
-
//
|
|
70
|
-
// In the future, there may be cases where the server intentionally sends
|
|
71
|
-
// partial data and expects the client to fill in the rest, in which case this
|
|
72
|
-
// logic may change. (There already is a similar case where the server sends
|
|
73
|
-
// _no_ hydration data in the HTML document at all, and the client fetches it
|
|
74
|
-
// separately, but that's different because we still end up hydrating with a
|
|
75
|
-
// complete tree.)
|
|
76
|
-
return task.node;
|
|
68
|
+
const task = createCacheNodeOnNavigation(navigatedAt, initialTree, null, 1, seedData, seedHead, seedDynamicStaleAt, false, accumulation);
|
|
69
|
+
return task;
|
|
77
70
|
}
|
|
78
|
-
function startPPRNavigation(navigatedAt, oldUrl, oldCacheNode, oldRouterState,
|
|
71
|
+
function startPPRNavigation(navigatedAt, oldUrl, oldRenderedSearch, oldCacheNode, oldRouterState, newRouteTree, newMetadataVaryPath, freshness, seedData, seedHead, seedDynamicStaleAt, isSamePageNavigation, accumulation) {
|
|
79
72
|
const didFindRootLayout = false;
|
|
80
73
|
const parentNeedsDynamicRequest = false;
|
|
81
|
-
const
|
|
82
|
-
|
|
74
|
+
const parentRefreshState = null;
|
|
75
|
+
const oldRootRefreshState = {
|
|
76
|
+
canonicalUrl: (0, _createhreffromurl.createHrefFromUrl)(oldUrl),
|
|
77
|
+
renderedSearch: oldRenderedSearch
|
|
78
|
+
};
|
|
79
|
+
return updateCacheNodeOnNavigation(navigatedAt, oldUrl, oldCacheNode !== null ? oldCacheNode : undefined, oldRouterState, newRouteTree, newMetadataVaryPath, freshness, didFindRootLayout, seedData, seedHead, seedDynamicStaleAt, isSamePageNavigation, parentNeedsDynamicRequest, oldRootRefreshState, parentRefreshState, accumulation);
|
|
83
80
|
}
|
|
84
|
-
function updateCacheNodeOnNavigation(navigatedAt, oldUrl, oldCacheNode, oldRouterState,
|
|
81
|
+
function updateCacheNodeOnNavigation(navigatedAt, oldUrl, oldCacheNode, oldRouterState, newRouteTree, newMetadataVaryPath, freshness, didFindRootLayout, seedData, seedHead, seedDynamicStaleAt, isSamePageNavigation, parentNeedsDynamicRequest, oldRootRefreshState, parentRefreshState, accumulation) {
|
|
85
82
|
// Check if this segment matches the one in the previous route.
|
|
86
83
|
const oldSegment = oldRouterState[0];
|
|
87
|
-
const newSegment =
|
|
84
|
+
const newSegment = createSegmentFromRouteTree(newRouteTree);
|
|
88
85
|
if (!(0, _matchsegments.matchSegment)(newSegment, oldSegment)) {
|
|
89
86
|
// This segment does not match the previous route. We're now entering the
|
|
90
87
|
// new part of the target route. Switch to the "create" path.
|
|
@@ -109,7 +106,7 @@ function updateCacheNodeOnNavigation(navigatedAt, oldUrl, oldCacheNode, oldRoute
|
|
|
109
106
|
// already discover a root layout in the part of the tree that is
|
|
110
107
|
// unchanged. We also only need to compare the subtree that is not
|
|
111
108
|
// shared. In the common case, this branch is skipped completely.
|
|
112
|
-
!didFindRootLayout && (0, _isnavigatingtonewrootlayout.isNavigatingToNewRootLayout)(oldRouterState,
|
|
109
|
+
!didFindRootLayout && (0, _isnavigatingtonewrootlayout.isNavigatingToNewRootLayout)(oldRouterState, newRouteTree) || // The global Not Found route (app/global-not-found.tsx) is a special
|
|
113
110
|
// case, because it acts like a root layout, but in the router tree, it
|
|
114
111
|
// is rendered in the same position as app/layout.tsx.
|
|
115
112
|
//
|
|
@@ -122,71 +119,37 @@ function updateCacheNodeOnNavigation(navigatedAt, oldUrl, oldCacheNode, oldRoute
|
|
|
122
119
|
newSegment === _segment.NOT_FOUND_SEGMENT_KEY) {
|
|
123
120
|
return null;
|
|
124
121
|
}
|
|
125
|
-
|
|
126
|
-
// The root should never mismatch. If it does, it suggests an internal
|
|
127
|
-
// Next.js error, or a malformed server response. Trigger a full-
|
|
128
|
-
// page navigation.
|
|
129
|
-
return null;
|
|
130
|
-
}
|
|
131
|
-
return createCacheNodeOnNavigation(navigatedAt, newRouterState, oldCacheNode, freshness, seedData, seedHead, prefetchData, prefetchHead, isPrefetchHeadPartial, parentSegmentPath, parentParallelRouteKey, parentNeedsDynamicRequest, accumulation);
|
|
122
|
+
return createCacheNodeOnNavigation(navigatedAt, newRouteTree, newMetadataVaryPath, freshness, seedData, seedHead, seedDynamicStaleAt, parentNeedsDynamicRequest, accumulation);
|
|
132
123
|
}
|
|
133
|
-
|
|
134
|
-
// segments to scroll to after a navigation. But we should just mark this
|
|
135
|
-
// information on the CacheNode directly. It used to be necessary to do this
|
|
136
|
-
// separately because CacheNodes were created lazily during render, not when
|
|
137
|
-
// rather than when creating the route tree.
|
|
138
|
-
const segmentPath = parentParallelRouteKey !== null && parentSegmentPath !== null ? parentSegmentPath.concat([
|
|
139
|
-
parentParallelRouteKey,
|
|
140
|
-
newSegment
|
|
141
|
-
]) : [];
|
|
142
|
-
const newRouterStateChildren = newRouterState[1];
|
|
124
|
+
const newSlots = newRouteTree.slots;
|
|
143
125
|
const oldRouterStateChildren = oldRouterState[1];
|
|
144
126
|
const seedDataChildren = seedData !== null ? seedData[1] : null;
|
|
145
|
-
const prefetchDataChildren = prefetchData !== null ? prefetchData[1] : null;
|
|
146
127
|
// We're currently traversing the part of the tree that was also part of
|
|
147
128
|
// the previous route. If we discover a root layout, then we don't need to
|
|
148
129
|
// trigger an MPA navigation.
|
|
149
|
-
const
|
|
150
|
-
const childDidFindRootLayout = didFindRootLayout || isRootLayout;
|
|
151
|
-
const oldParallelRoutes = oldCacheNode !== undefined ? oldCacheNode.parallelRoutes : undefined;
|
|
152
|
-
// Clone the current set of segment children, even if they aren't active in
|
|
153
|
-
// the new tree.
|
|
154
|
-
// TODO: We currently retain all the inactive segments indefinitely, until
|
|
155
|
-
// there's an explicit refresh, or a parent layout is lazily refreshed. We
|
|
156
|
-
// rely on this for popstate navigations, which update the Router State Tree
|
|
157
|
-
// but do not eagerly perform a data fetch, because they expect the segment
|
|
158
|
-
// data to already be in the Cache Node tree. For highly static sites that
|
|
159
|
-
// are mostly read-only, this may happen only rarely, causing memory to
|
|
160
|
-
// leak. We should figure out a better model for the lifetime of inactive
|
|
161
|
-
// segments, so we can maintain instant back/forward navigations without
|
|
162
|
-
// leaking memory indefinitely.
|
|
163
|
-
let shouldDropSiblingCaches = false;
|
|
130
|
+
const childDidFindRootLayout = didFindRootLayout || (newRouteTree.prefetchHints & _approutertypes.PrefetchHint.IsRootLayout) !== 0;
|
|
164
131
|
let shouldRefreshDynamicData = false;
|
|
165
132
|
switch(freshness){
|
|
166
133
|
case 0:
|
|
167
134
|
case 2:
|
|
168
135
|
case 1:
|
|
169
|
-
|
|
170
|
-
// a refresh.
|
|
171
|
-
shouldDropSiblingCaches = false;
|
|
136
|
+
case 5:
|
|
172
137
|
shouldRefreshDynamicData = false;
|
|
173
138
|
break;
|
|
174
139
|
case 3:
|
|
175
140
|
case 4:
|
|
176
|
-
shouldDropSiblingCaches = true;
|
|
177
141
|
shouldRefreshDynamicData = true;
|
|
178
142
|
break;
|
|
179
143
|
default:
|
|
180
144
|
freshness;
|
|
181
145
|
break;
|
|
182
146
|
}
|
|
183
|
-
const newParallelRoutes = new Map(shouldDropSiblingCaches ? undefined : oldParallelRoutes);
|
|
184
147
|
// TODO: We're not consistent about how we do this check. Some places
|
|
185
148
|
// check if the segment starts with PAGE_SEGMENT_KEY, but most seem to
|
|
186
149
|
// check if there any any children, which is why I'm doing it here. We
|
|
187
150
|
// should probably encode an empty children set as `null` though. Either
|
|
188
151
|
// way, we should update all the checks to be consistent.
|
|
189
|
-
const isLeafSegment =
|
|
152
|
+
const isLeafSegment = newSlots === null;
|
|
190
153
|
// Get the data for this segment. Since it was part of the previous route,
|
|
191
154
|
// usually we just clone the data from the old CacheNode. However, during a
|
|
192
155
|
// refresh or a revalidation, there won't be any existing CacheNode. So we
|
|
@@ -197,46 +160,37 @@ function updateCacheNodeOnNavigation(navigatedAt, oldUrl, oldCacheNode, oldRoute
|
|
|
197
160
|
!(isLeafSegment && isSamePageNavigation)) {
|
|
198
161
|
// Reuse the existing CacheNode
|
|
199
162
|
const dropPrefetchRsc = false;
|
|
200
|
-
newCacheNode =
|
|
163
|
+
newCacheNode = reuseSharedCacheNode(dropPrefetchRsc, oldCacheNode);
|
|
201
164
|
needsDynamicRequest = false;
|
|
202
|
-
} else if (seedData !== null && seedData[0] !== null) {
|
|
203
|
-
// If this navigation was the result of an action, then check if the
|
|
204
|
-
// server sent back data in the action response. We should favor using
|
|
205
|
-
// that, rather than performing a separate request. This is both better
|
|
206
|
-
// for performance and it's more likely to be consistent with any
|
|
207
|
-
// writes that were just performed by the action, compared to a
|
|
208
|
-
// separate request.
|
|
209
|
-
const seedRsc = seedData[0];
|
|
210
|
-
const seedLoading = seedData[2];
|
|
211
|
-
const isSeedRscPartial = false;
|
|
212
|
-
const isSeedHeadPartial = seedHead === null;
|
|
213
|
-
newCacheNode = readCacheNodeFromSeedData(seedRsc, seedLoading, isSeedRscPartial, seedHead, isSeedHeadPartial, isLeafSegment, newParallelRoutes, navigatedAt);
|
|
214
|
-
needsDynamicRequest = isLeafSegment && isSeedHeadPartial;
|
|
215
|
-
} else if (prefetchData !== null) {
|
|
216
|
-
// Consult the prefetch cache.
|
|
217
|
-
const prefetchRsc = prefetchData[0];
|
|
218
|
-
const prefetchLoading = prefetchData[2];
|
|
219
|
-
const isPrefetchRSCPartial = prefetchData[3];
|
|
220
|
-
newCacheNode = readCacheNodeFromSeedData(prefetchRsc, prefetchLoading, isPrefetchRSCPartial, prefetchHead, isPrefetchHeadPartial, isLeafSegment, newParallelRoutes, navigatedAt);
|
|
221
|
-
needsDynamicRequest = isPrefetchRSCPartial || isLeafSegment && isPrefetchHeadPartial;
|
|
222
165
|
} else {
|
|
223
|
-
//
|
|
224
|
-
|
|
225
|
-
|
|
166
|
+
// If this is part of a refresh, ignore the existing CacheNode and create a
|
|
167
|
+
// new one.
|
|
168
|
+
const seedRsc = seedData !== null ? seedData[0] : null;
|
|
169
|
+
const result = createCacheNodeForSegment(navigatedAt, newRouteTree, seedRsc, newMetadataVaryPath, seedHead, freshness, seedDynamicStaleAt);
|
|
170
|
+
newCacheNode = result.cacheNode;
|
|
171
|
+
needsDynamicRequest = result.needsDynamicRequest;
|
|
172
|
+
// Carry forward the old node's scrollRef. This preserves scroll
|
|
173
|
+
// intent when a prior navigation's cache node is replaced by a
|
|
174
|
+
// refresh before the scroll handler has had a chance to fire —
|
|
175
|
+
// e.g. when router.push() and router.refresh() are called in the
|
|
176
|
+
// same startTransition batch.
|
|
177
|
+
if (oldCacheNode !== undefined) {
|
|
178
|
+
newCacheNode.scrollRef = oldCacheNode.scrollRef;
|
|
179
|
+
}
|
|
226
180
|
}
|
|
227
181
|
// During a refresh navigation, there's a special case that happens when
|
|
228
182
|
// entering a "default" slot. The default slot may not be part of the
|
|
229
183
|
// current route; it may have been reused from an older route. If so,
|
|
230
184
|
// we need to fetch its data from the old route's URL rather than current
|
|
231
185
|
// route's URL. Keep track of this as we traverse the tree.
|
|
232
|
-
const
|
|
233
|
-
const
|
|
234
|
-
|
|
186
|
+
const maybeRefreshState = newRouteTree.refreshState;
|
|
187
|
+
const refreshState = maybeRefreshState !== undefined && maybeRefreshState !== null ? // refresh URL as we continue traversing the tree.
|
|
188
|
+
maybeRefreshState : parentRefreshState;
|
|
235
189
|
// If this segment itself needs to fetch new data from the server, then by
|
|
236
190
|
// definition it is being refreshed. Track its refresh URL so we know which
|
|
237
191
|
// URL to request the data from.
|
|
238
|
-
if (needsDynamicRequest &&
|
|
239
|
-
accumulateRefreshUrl(accumulation,
|
|
192
|
+
if (needsDynamicRequest && refreshState !== null) {
|
|
193
|
+
accumulateRefreshUrl(accumulation, refreshState);
|
|
240
194
|
}
|
|
241
195
|
// As we diff the trees, we may sometimes modify (copy-on-write, not mutate)
|
|
242
196
|
// the Route Tree that was returned by the server — for example, in the case
|
|
@@ -263,260 +217,207 @@ function updateCacheNodeOnNavigation(navigatedAt, oldUrl, oldCacheNode, oldRoute
|
|
|
263
217
|
// include paths that are dynamic. Instead of reusing the
|
|
264
218
|
// FlightRouterState type.
|
|
265
219
|
let dynamicRequestTreeChildren = {};
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
const
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
//
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
const taskChildRoute = taskChild.route;
|
|
321
|
-
patchedRouterStateChildren[parallelRouteKey] = taskChildRoute;
|
|
322
|
-
const dynamicRequestTreeChild = taskChild.dynamicRequestTree;
|
|
323
|
-
if (dynamicRequestTreeChild !== null) {
|
|
324
|
-
// Something in the child tree is dynamic.
|
|
325
|
-
childNeedsDynamicRequest = true;
|
|
326
|
-
dynamicRequestTreeChildren[parallelRouteKey] = dynamicRequestTreeChild;
|
|
327
|
-
} else {
|
|
328
|
-
dynamicRequestTreeChildren[parallelRouteKey] = taskChildRoute;
|
|
220
|
+
let newCacheNodeSlots = null;
|
|
221
|
+
if (newSlots !== null) {
|
|
222
|
+
const oldCacheNodeSlots = oldCacheNode !== undefined ? oldCacheNode.slots : null;
|
|
223
|
+
newCacheNode.slots = newCacheNodeSlots = {};
|
|
224
|
+
taskChildren = new Map();
|
|
225
|
+
for(let parallelRouteKey in newSlots){
|
|
226
|
+
let newRouteTreeChild = newSlots[parallelRouteKey];
|
|
227
|
+
const oldRouterStateChild = oldRouterStateChildren[parallelRouteKey];
|
|
228
|
+
if (oldRouterStateChild === undefined) {
|
|
229
|
+
// This should never happen, but if it does, it suggests a malformed
|
|
230
|
+
// server response. Trigger a full-page navigation.
|
|
231
|
+
return null;
|
|
232
|
+
}
|
|
233
|
+
let seedDataChild = seedDataChildren !== null ? seedDataChildren[parallelRouteKey] : null;
|
|
234
|
+
const oldSegmentChild = oldRouterStateChild[0];
|
|
235
|
+
let newSegmentChild = createSegmentFromRouteTree(newRouteTreeChild);
|
|
236
|
+
let seedHeadChild = seedHead;
|
|
237
|
+
if (// Skip this branch during a history traversal. We restore the tree that
|
|
238
|
+
// was stashed in the history entry as-is.
|
|
239
|
+
freshness !== 2 && newSegmentChild === _segment.DEFAULT_SEGMENT_KEY && oldSegmentChild !== _segment.DEFAULT_SEGMENT_KEY) {
|
|
240
|
+
// This is a "default" segment. These are never sent by the server during
|
|
241
|
+
// a soft navigation; instead, the client reuses whatever segment was
|
|
242
|
+
// already active in that slot on the previous route.
|
|
243
|
+
newRouteTreeChild = reuseActiveSegmentInDefaultSlot(newRouteTree, parallelRouteKey, oldRootRefreshState, oldRouterStateChild);
|
|
244
|
+
newSegmentChild = createSegmentFromRouteTree(newRouteTreeChild);
|
|
245
|
+
// Since we're switching to a different route tree, these are no
|
|
246
|
+
// longer valid, because they correspond to the outer tree.
|
|
247
|
+
seedDataChild = null;
|
|
248
|
+
seedHeadChild = null;
|
|
249
|
+
}
|
|
250
|
+
const oldCacheNodeChild = oldCacheNodeSlots !== null ? oldCacheNodeSlots[parallelRouteKey] : undefined;
|
|
251
|
+
const taskChild = updateCacheNodeOnNavigation(navigatedAt, oldUrl, oldCacheNodeChild, oldRouterStateChild, newRouteTreeChild, newMetadataVaryPath, freshness, childDidFindRootLayout, seedDataChild ?? null, seedHeadChild, seedDynamicStaleAt, isSamePageNavigation, parentNeedsDynamicRequest || needsDynamicRequest, oldRootRefreshState, refreshState, accumulation);
|
|
252
|
+
if (taskChild === null) {
|
|
253
|
+
// One of the child tasks discovered a change to the root layout.
|
|
254
|
+
// Immediately unwind from this recursive traversal. This will trigger a
|
|
255
|
+
// full-page navigation.
|
|
256
|
+
return null;
|
|
257
|
+
}
|
|
258
|
+
// Recursively propagate up the child tasks.
|
|
259
|
+
taskChildren.set(parallelRouteKey, taskChild);
|
|
260
|
+
newCacheNodeSlots[parallelRouteKey] = taskChild.node;
|
|
261
|
+
// The child tree's route state may be different from the prefetched
|
|
262
|
+
// route sent by the server. We need to clone it as we traverse back up
|
|
263
|
+
// the tree.
|
|
264
|
+
const taskChildRoute = taskChild.route;
|
|
265
|
+
patchedRouterStateChildren[parallelRouteKey] = taskChildRoute;
|
|
266
|
+
const dynamicRequestTreeChild = taskChild.dynamicRequestTree;
|
|
267
|
+
if (dynamicRequestTreeChild !== null) {
|
|
268
|
+
// Something in the child tree is dynamic.
|
|
269
|
+
childNeedsDynamicRequest = true;
|
|
270
|
+
dynamicRequestTreeChildren[parallelRouteKey] = dynamicRequestTreeChild;
|
|
271
|
+
} else {
|
|
272
|
+
dynamicRequestTreeChildren[parallelRouteKey] = taskChildRoute;
|
|
273
|
+
}
|
|
329
274
|
}
|
|
330
275
|
}
|
|
276
|
+
const newFlightRouterState = [
|
|
277
|
+
createSegmentFromRouteTree(newRouteTree),
|
|
278
|
+
patchedRouterStateChildren,
|
|
279
|
+
refreshState !== null ? [
|
|
280
|
+
refreshState.canonicalUrl,
|
|
281
|
+
refreshState.renderedSearch
|
|
282
|
+
] : null,
|
|
283
|
+
null,
|
|
284
|
+
newRouteTree.prefetchHints
|
|
285
|
+
];
|
|
331
286
|
return {
|
|
332
287
|
status: needsDynamicRequest ? 0 : 1,
|
|
333
|
-
route:
|
|
288
|
+
route: newFlightRouterState,
|
|
334
289
|
node: newCacheNode,
|
|
335
|
-
dynamicRequestTree: createDynamicRequestTree(
|
|
336
|
-
|
|
290
|
+
dynamicRequestTree: createDynamicRequestTree(newFlightRouterState, dynamicRequestTreeChildren, needsDynamicRequest, childNeedsDynamicRequest, parentNeedsDynamicRequest),
|
|
291
|
+
refreshState,
|
|
337
292
|
children: taskChildren
|
|
338
293
|
};
|
|
339
294
|
}
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
const seedDataChildren = seedData !== null ? seedData[1] : null;
|
|
358
|
-
const oldParallelRoutes = oldCacheNode !== undefined ? oldCacheNode.parallelRoutes : undefined;
|
|
359
|
-
let shouldDropSiblingCaches = false;
|
|
360
|
-
let shouldRefreshDynamicData = false;
|
|
361
|
-
let dropPrefetchRsc = false;
|
|
295
|
+
/**
|
|
296
|
+
* Assigns a ScrollRef to a new leaf CacheNode so the scroll handler
|
|
297
|
+
* knows to scroll to it after navigation. All leaves in the same
|
|
298
|
+
* navigation share the same ScrollRef — the first segment to scroll
|
|
299
|
+
* consumes it, preventing others from also scrolling.
|
|
300
|
+
*
|
|
301
|
+
* This is only called inside `createCacheNodeOnNavigation`, which only
|
|
302
|
+
* runs when segments diverge from the previous route. So for a refresh
|
|
303
|
+
* where the route structure stays the same, segments match, the update
|
|
304
|
+
* path is taken, and this function is never called — no scroll ref is
|
|
305
|
+
* assigned. A scroll ref is only assigned when the route actually
|
|
306
|
+
* changed (e.g. a redirect, or a dynamic condition on the server that
|
|
307
|
+
* produces a different route).
|
|
308
|
+
*
|
|
309
|
+
* Skipped during hydration (initial render should not scroll) and
|
|
310
|
+
* history traversal (scroll restoration is handled separately).
|
|
311
|
+
*/ function accumulateScrollRef(freshness, cacheNode, accumulation) {
|
|
362
312
|
switch(freshness){
|
|
363
313
|
case 0:
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
shouldRefreshDynamicData = oldCacheNode === undefined || navigatedAt - oldCacheNode.navigatedAt >= _navigatereducer.DYNAMIC_STALETIME_MS;
|
|
374
|
-
dropPrefetchRsc = false;
|
|
314
|
+
case 5:
|
|
315
|
+
case 3:
|
|
316
|
+
case 4:
|
|
317
|
+
if (accumulation.scrollRef === null) {
|
|
318
|
+
accumulation.scrollRef = {
|
|
319
|
+
current: true
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
cacheNode.scrollRef = accumulation.scrollRef;
|
|
375
323
|
break;
|
|
376
324
|
case 1:
|
|
377
|
-
// During hydration, we assume the data sent by the server is both
|
|
378
|
-
// consistent and complete.
|
|
379
|
-
shouldRefreshDynamicData = false;
|
|
380
|
-
shouldDropSiblingCaches = false;
|
|
381
|
-
dropPrefetchRsc = false;
|
|
382
325
|
break;
|
|
383
326
|
case 2:
|
|
384
|
-
// During back/forward navigations, we reuse the dynamic data regardless
|
|
385
|
-
// of how stale it may be.
|
|
386
|
-
shouldRefreshDynamicData = false;
|
|
387
|
-
shouldRefreshDynamicData = false;
|
|
388
|
-
// Only show prefetched data if the dynamic data is still pending. This
|
|
389
|
-
// avoids a flash back to the prefetch state in a case where it's highly
|
|
390
|
-
// likely to have already streamed in.
|
|
391
|
-
//
|
|
392
|
-
// Tehnically, what we're actually checking is whether the dynamic network
|
|
393
|
-
// response was received. But since it's a streaming response, this does
|
|
394
|
-
// not mean that all the dynamic data has fully streamed in. It just means
|
|
395
|
-
// that _some_ of the dynamic data was received. But as a heuristic, we
|
|
396
|
-
// assume that the rest dynamic data will stream in quickly, so it's still
|
|
397
|
-
// better to skip the prefetch state.
|
|
398
|
-
if (oldCacheNode !== undefined) {
|
|
399
|
-
const oldRsc = oldCacheNode.rsc;
|
|
400
|
-
const oldRscDidResolve = !isDeferredRsc(oldRsc) || oldRsc.status !== 'pending';
|
|
401
|
-
dropPrefetchRsc = oldRscDidResolve;
|
|
402
|
-
} else {
|
|
403
|
-
dropPrefetchRsc = false;
|
|
404
|
-
}
|
|
405
|
-
break;
|
|
406
|
-
case 3:
|
|
407
|
-
case 4:
|
|
408
|
-
// Drop all dynamic data.
|
|
409
|
-
shouldRefreshDynamicData = true;
|
|
410
|
-
shouldDropSiblingCaches = true;
|
|
411
|
-
dropPrefetchRsc = false;
|
|
412
327
|
break;
|
|
413
328
|
default:
|
|
414
329
|
freshness;
|
|
415
330
|
break;
|
|
416
331
|
}
|
|
417
|
-
|
|
418
|
-
|
|
332
|
+
}
|
|
333
|
+
function createCacheNodeOnNavigation(navigatedAt, newRouteTree, newMetadataVaryPath, freshness, seedData, seedHead, seedDynamicStaleAt, parentNeedsDynamicRequest, accumulation) {
|
|
334
|
+
// Same traversal as updateCacheNodeNavigation, but simpler. We switch to this
|
|
335
|
+
// path once we reach the part of the tree that was not in the previous route.
|
|
336
|
+
// We don't need to diff against the old tree, we just need to create a new
|
|
337
|
+
// one. We also don't need to worry about any refresh-related logic.
|
|
338
|
+
//
|
|
339
|
+
// For the most part, this is a subset of updateCacheNodeOnNavigation, so any
|
|
340
|
+
// change that happens in this function likely needs to be applied to that
|
|
341
|
+
// one, too. However there are some places where the behavior intentionally
|
|
342
|
+
// diverges, which is why we keep them separate.
|
|
343
|
+
const newSegment = createSegmentFromRouteTree(newRouteTree);
|
|
344
|
+
const newSlots = newRouteTree.slots;
|
|
345
|
+
const seedDataChildren = seedData !== null ? seedData[1] : null;
|
|
346
|
+
const seedRsc = seedData !== null ? seedData[0] : null;
|
|
347
|
+
const result = createCacheNodeForSegment(navigatedAt, newRouteTree, seedRsc, newMetadataVaryPath, seedHead, freshness, seedDynamicStaleAt);
|
|
348
|
+
const newCacheNode = result.cacheNode;
|
|
349
|
+
const needsDynamicRequest = result.needsDynamicRequest;
|
|
350
|
+
const isLeafSegment = newSlots === null;
|
|
419
351
|
if (isLeafSegment) {
|
|
420
|
-
|
|
421
|
-
// a result array. This is used by the LayoutRouter to scroll to ensure that
|
|
422
|
-
// new pages are visible after a navigation.
|
|
423
|
-
//
|
|
424
|
-
// This only happens for new pages, not for refreshed pages.
|
|
425
|
-
//
|
|
426
|
-
// TODO: We should use a string to represent the segment path instead of
|
|
427
|
-
// an array. We already use a string representation for the path when
|
|
428
|
-
// accessing the Segment Cache, so we can use the same one.
|
|
429
|
-
if (accumulation.scrollableSegments === null) {
|
|
430
|
-
accumulation.scrollableSegments = [];
|
|
431
|
-
}
|
|
432
|
-
accumulation.scrollableSegments.push(segmentPath);
|
|
433
|
-
}
|
|
434
|
-
let newCacheNode;
|
|
435
|
-
let needsDynamicRequest;
|
|
436
|
-
if (!shouldRefreshDynamicData && oldCacheNode !== undefined) {
|
|
437
|
-
// Reuse the existing CacheNode
|
|
438
|
-
newCacheNode = reuseDynamicCacheNode(dropPrefetchRsc, oldCacheNode, newParallelRoutes);
|
|
439
|
-
needsDynamicRequest = false;
|
|
440
|
-
} else if (seedData !== null && seedData[0] !== null) {
|
|
441
|
-
// If this navigation was the result of an action, then check if the
|
|
442
|
-
// server sent back data in the action response. We should favor using
|
|
443
|
-
// that, rather than performing a separate request. This is both better
|
|
444
|
-
// for performance and it's more likely to be consistent with any
|
|
445
|
-
// writes that were just performed by the action, compared to a
|
|
446
|
-
// separate request.
|
|
447
|
-
const seedRsc = seedData[0];
|
|
448
|
-
const seedLoading = seedData[2];
|
|
449
|
-
const isSeedRscPartial = false;
|
|
450
|
-
const isSeedHeadPartial = seedHead === null && freshness !== 1;
|
|
451
|
-
newCacheNode = readCacheNodeFromSeedData(seedRsc, seedLoading, isSeedRscPartial, seedHead, isSeedHeadPartial, isLeafSegment, newParallelRoutes, navigatedAt);
|
|
452
|
-
needsDynamicRequest = isLeafSegment && isSeedHeadPartial;
|
|
453
|
-
} else if (freshness === 1 && isLeafSegment && seedHead !== null) {
|
|
454
|
-
// This is another weird case related to "not found" pages and hydration.
|
|
455
|
-
// There will be a head sent by the server, but no page seed data.
|
|
456
|
-
// TODO: We really should get rid of all these "not found" specific quirks
|
|
457
|
-
// and make sure the tree is always consistent.
|
|
458
|
-
const seedRsc = null;
|
|
459
|
-
const seedLoading = null;
|
|
460
|
-
const isSeedRscPartial = false;
|
|
461
|
-
const isSeedHeadPartial = false;
|
|
462
|
-
newCacheNode = readCacheNodeFromSeedData(seedRsc, seedLoading, isSeedRscPartial, seedHead, isSeedHeadPartial, isLeafSegment, newParallelRoutes, navigatedAt);
|
|
463
|
-
needsDynamicRequest = false;
|
|
464
|
-
} else if (freshness !== 1 && prefetchData !== null) {
|
|
465
|
-
// Consult the prefetch cache.
|
|
466
|
-
const prefetchRsc = prefetchData[0];
|
|
467
|
-
const prefetchLoading = prefetchData[2];
|
|
468
|
-
const isPrefetchRSCPartial = prefetchData[3];
|
|
469
|
-
newCacheNode = readCacheNodeFromSeedData(prefetchRsc, prefetchLoading, isPrefetchRSCPartial, prefetchHead, isPrefetchHeadPartial, isLeafSegment, newParallelRoutes, navigatedAt);
|
|
470
|
-
needsDynamicRequest = isPrefetchRSCPartial || isLeafSegment && isPrefetchHeadPartial;
|
|
471
|
-
} else {
|
|
472
|
-
// Spawn a request to fetch new data from the server.
|
|
473
|
-
newCacheNode = spawnNewCacheNode(newParallelRoutes, isLeafSegment, navigatedAt, freshness);
|
|
474
|
-
needsDynamicRequest = true;
|
|
352
|
+
accumulateScrollRef(freshness, newCacheNode, accumulation);
|
|
475
353
|
}
|
|
476
354
|
let patchedRouterStateChildren = {};
|
|
477
355
|
let taskChildren = null;
|
|
478
356
|
let childNeedsDynamicRequest = false;
|
|
479
357
|
let dynamicRequestTreeChildren = {};
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
const taskChildRoute = taskChild.route;
|
|
500
|
-
patchedRouterStateChildren[parallelRouteKey] = taskChildRoute;
|
|
501
|
-
const dynamicRequestTreeChild = taskChild.dynamicRequestTree;
|
|
502
|
-
if (dynamicRequestTreeChild !== null) {
|
|
503
|
-
childNeedsDynamicRequest = true;
|
|
504
|
-
dynamicRequestTreeChildren[parallelRouteKey] = dynamicRequestTreeChild;
|
|
505
|
-
} else {
|
|
506
|
-
dynamicRequestTreeChildren[parallelRouteKey] = taskChildRoute;
|
|
358
|
+
let newCacheNodeSlots = null;
|
|
359
|
+
if (newSlots !== null) {
|
|
360
|
+
newCacheNode.slots = newCacheNodeSlots = {};
|
|
361
|
+
taskChildren = new Map();
|
|
362
|
+
for(let parallelRouteKey in newSlots){
|
|
363
|
+
const newRouteTreeChild = newSlots[parallelRouteKey];
|
|
364
|
+
const seedDataChild = seedDataChildren !== null ? seedDataChildren[parallelRouteKey] : null;
|
|
365
|
+
const taskChild = createCacheNodeOnNavigation(navigatedAt, newRouteTreeChild, newMetadataVaryPath, freshness, seedDataChild ?? null, seedHead, seedDynamicStaleAt, parentNeedsDynamicRequest || needsDynamicRequest, accumulation);
|
|
366
|
+
taskChildren.set(parallelRouteKey, taskChild);
|
|
367
|
+
newCacheNodeSlots[parallelRouteKey] = taskChild.node;
|
|
368
|
+
const taskChildRoute = taskChild.route;
|
|
369
|
+
patchedRouterStateChildren[parallelRouteKey] = taskChildRoute;
|
|
370
|
+
const dynamicRequestTreeChild = taskChild.dynamicRequestTree;
|
|
371
|
+
if (dynamicRequestTreeChild !== null) {
|
|
372
|
+
childNeedsDynamicRequest = true;
|
|
373
|
+
dynamicRequestTreeChildren[parallelRouteKey] = dynamicRequestTreeChild;
|
|
374
|
+
} else {
|
|
375
|
+
dynamicRequestTreeChildren[parallelRouteKey] = taskChildRoute;
|
|
376
|
+
}
|
|
507
377
|
}
|
|
508
378
|
}
|
|
379
|
+
const newFlightRouterState = [
|
|
380
|
+
newSegment,
|
|
381
|
+
patchedRouterStateChildren,
|
|
382
|
+
null,
|
|
383
|
+
null,
|
|
384
|
+
newRouteTree.prefetchHints
|
|
385
|
+
];
|
|
509
386
|
return {
|
|
510
387
|
status: needsDynamicRequest ? 0 : 1,
|
|
511
|
-
route:
|
|
388
|
+
route: newFlightRouterState,
|
|
512
389
|
node: newCacheNode,
|
|
513
|
-
dynamicRequestTree: createDynamicRequestTree(
|
|
390
|
+
dynamicRequestTree: createDynamicRequestTree(newFlightRouterState, dynamicRequestTreeChildren, needsDynamicRequest, childNeedsDynamicRequest, parentNeedsDynamicRequest),
|
|
514
391
|
// This route is not part of the current tree, so there's no reason to
|
|
515
392
|
// track the refresh URL.
|
|
516
|
-
|
|
393
|
+
refreshState: null,
|
|
517
394
|
children: taskChildren
|
|
518
395
|
};
|
|
519
396
|
}
|
|
397
|
+
function createSegmentFromRouteTree(newRouteTree) {
|
|
398
|
+
if (newRouteTree.isPage) {
|
|
399
|
+
// In a dynamic server response, the server embeds the search params into
|
|
400
|
+
// the segment key, but in a static one it's omitted. The client handles
|
|
401
|
+
// this inconsistency by adding the search params back right at the end.
|
|
402
|
+
//
|
|
403
|
+
// TODO: The only thing this is used for is to create a cache key for
|
|
404
|
+
// ChildSegmentMap. But we already track the `renderedSearch` everywhere as
|
|
405
|
+
// part of the varyPath. The plan is get rid of ChildSegmentMap and
|
|
406
|
+
// store the page data in a CacheMap using the varyPath, like we do
|
|
407
|
+
// for prefetches. Then we can remove it from the segment key.
|
|
408
|
+
//
|
|
409
|
+
// As an incremental step, we can grab the search params from the varyPath.
|
|
410
|
+
const renderedSearch = (0, _varypath.getRenderedSearchFromVaryPath)(newRouteTree.varyPath);
|
|
411
|
+
if (renderedSearch === null) {
|
|
412
|
+
return _segment.PAGE_SEGMENT_KEY;
|
|
413
|
+
}
|
|
414
|
+
// This is based on equivalent logic in addSearchParamsIfPageSegment, used
|
|
415
|
+
// on the server.
|
|
416
|
+
const stringifiedQuery = JSON.stringify(Object.fromEntries(new URLSearchParams(renderedSearch)));
|
|
417
|
+
return stringifiedQuery !== '{}' ? _segment.PAGE_SEGMENT_KEY + '?' + stringifiedQuery : _segment.PAGE_SEGMENT_KEY;
|
|
418
|
+
}
|
|
419
|
+
return newRouteTree.segment;
|
|
420
|
+
}
|
|
520
421
|
function patchRouterStateWithNewChildren(baseRouterState, newChildren) {
|
|
521
422
|
const clone = [
|
|
522
423
|
baseRouterState[0],
|
|
@@ -559,7 +460,7 @@ function createDynamicRequestTree(newRouterState, dynamicRequestTreeChildren, ne
|
|
|
559
460
|
}
|
|
560
461
|
return dynamicRequestTree;
|
|
561
462
|
}
|
|
562
|
-
function accumulateRefreshUrl(accumulation,
|
|
463
|
+
function accumulateRefreshUrl(accumulation, refreshState) {
|
|
563
464
|
// This is a refresh navigation, and we're inside a "default" slot that's
|
|
564
465
|
// not part of the current route; it was reused from an older route. In
|
|
565
466
|
// order to get fresh data for this reused route, we need to issue a
|
|
@@ -570,6 +471,7 @@ function accumulateRefreshUrl(accumulation, refreshUrl) {
|
|
|
570
471
|
// we don't do it immediately here is so we can deduplicate multiple
|
|
571
472
|
// instances of the same URL into a single request. See
|
|
572
473
|
// listenForDynamicRequest for more details.
|
|
474
|
+
const refreshUrl = refreshState.canonicalUrl;
|
|
573
475
|
const separateRefreshUrls = accumulation.separateRefreshUrls;
|
|
574
476
|
if (separateRefreshUrls === null) {
|
|
575
477
|
accumulation.separateRefreshUrls = new Set([
|
|
@@ -579,123 +481,347 @@ function accumulateRefreshUrl(accumulation, refreshUrl) {
|
|
|
579
481
|
separateRefreshUrls.add(refreshUrl);
|
|
580
482
|
}
|
|
581
483
|
}
|
|
582
|
-
function reuseActiveSegmentInDefaultSlot(
|
|
484
|
+
function reuseActiveSegmentInDefaultSlot(parentRouteTree, parallelRouteKey, oldRootRefreshState, oldRouterState) {
|
|
583
485
|
// This is a "default" segment. These are never sent by the server during a
|
|
584
486
|
// soft navigation; instead, the client reuses whatever segment was already
|
|
585
487
|
// active in that slot on the previous route. This means if we later need to
|
|
586
488
|
// refresh the segment, it will have to be refetched from the previous route's
|
|
587
489
|
// URL. We store it in the Flight Router State.
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
let reusedRouterState;
|
|
593
|
-
const oldRefreshMarker = oldRouterState[3];
|
|
594
|
-
if (oldRefreshMarker === 'refresh') {
|
|
490
|
+
let reusedUrl;
|
|
491
|
+
let reusedRenderedSearch;
|
|
492
|
+
const oldRefreshState = oldRouterState[2];
|
|
493
|
+
if (oldRefreshState !== undefined && oldRefreshState !== null) {
|
|
595
494
|
// This segment was already reused from an even older route. Keep its
|
|
596
|
-
// existing URL and refresh
|
|
597
|
-
|
|
495
|
+
// existing URL and refresh state.
|
|
496
|
+
reusedUrl = oldRefreshState[0];
|
|
497
|
+
reusedRenderedSearch = oldRefreshState[1];
|
|
598
498
|
} else {
|
|
599
|
-
//
|
|
600
|
-
//
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
499
|
+
// Since this route didn't already have a refresh state, it must have been
|
|
500
|
+
// reachable from the root of the old route. So we use the refresh state
|
|
501
|
+
// that represents the old route.
|
|
502
|
+
reusedUrl = oldRootRefreshState.canonicalUrl;
|
|
503
|
+
reusedRenderedSearch = oldRootRefreshState.renderedSearch;
|
|
604
504
|
}
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
function reuseDynamicCacheNode(dropPrefetchRsc, existingCacheNode, parallelRoutes) {
|
|
608
|
-
// Clone an existing CacheNode's data, with (possibly) new children.
|
|
609
|
-
const cacheNode = {
|
|
610
|
-
rsc: existingCacheNode.rsc,
|
|
611
|
-
prefetchRsc: dropPrefetchRsc ? null : existingCacheNode.prefetchRsc,
|
|
612
|
-
head: existingCacheNode.head,
|
|
613
|
-
prefetchHead: dropPrefetchRsc ? null : existingCacheNode.prefetchHead,
|
|
614
|
-
loading: existingCacheNode.loading,
|
|
615
|
-
parallelRoutes,
|
|
616
|
-
// Don't update the navigatedAt timestamp, since we're reusing
|
|
617
|
-
// existing data.
|
|
618
|
-
navigatedAt: existingCacheNode.navigatedAt
|
|
505
|
+
const acc = {
|
|
506
|
+
metadataVaryPath: null
|
|
619
507
|
};
|
|
620
|
-
|
|
508
|
+
const reusedRouteTree = (0, _cache.convertReusedFlightRouterStateToRouteTree)(parentRouteTree, parallelRouteKey, oldRouterState, reusedRenderedSearch, acc);
|
|
509
|
+
reusedRouteTree.refreshState = {
|
|
510
|
+
canonicalUrl: reusedUrl,
|
|
511
|
+
renderedSearch: reusedRenderedSearch
|
|
512
|
+
};
|
|
513
|
+
return reusedRouteTree;
|
|
621
514
|
}
|
|
622
|
-
function
|
|
623
|
-
//
|
|
624
|
-
//
|
|
625
|
-
//
|
|
626
|
-
|
|
515
|
+
function reuseSharedCacheNode(dropPrefetchRsc, existingCacheNode) {
|
|
516
|
+
// Clone the CacheNode that was already present in the previous tree.
|
|
517
|
+
// Carry forward the scrollRef so scroll intent from a prior navigation
|
|
518
|
+
// survives tree rebuilds (e.g. push + refresh in the same batch).
|
|
519
|
+
return createCacheNode(existingCacheNode.rsc, dropPrefetchRsc ? null : existingCacheNode.prefetchRsc, existingCacheNode.head, dropPrefetchRsc ? null : existingCacheNode.prefetchHead, existingCacheNode.scrollRef);
|
|
520
|
+
}
|
|
521
|
+
function createCacheNodeForSegment(now, tree, seedRsc, metadataVaryPath, seedHead, freshness, dynamicStaleAt) {
|
|
522
|
+
// Construct a new CacheNode using data from the BFCache, the client's
|
|
523
|
+
// Segment Cache, or seeded from a server response.
|
|
524
|
+
//
|
|
525
|
+
// If there's a cache miss, or if we only have a partial hit, we'll render
|
|
526
|
+
// the partial state immediately, and spawn a request to the server to fill
|
|
527
|
+
// in the missing data.
|
|
528
|
+
//
|
|
529
|
+
// If the segment is fully cached on the client already, we can omit this
|
|
530
|
+
// segment from the server request.
|
|
531
|
+
//
|
|
532
|
+
// If we already have a dynamic data response associated with this navigation,
|
|
533
|
+
// as in the case of a Server Action-initiated redirect or refresh, we may
|
|
534
|
+
// also be able to use that data without spawning a new request. (This is
|
|
535
|
+
// referred to as the "seed" data.)
|
|
536
|
+
const isPage = tree.isPage;
|
|
537
|
+
// During certain kinds of navigations, we may be able to render from
|
|
538
|
+
// the BFCache.
|
|
539
|
+
switch(freshness){
|
|
540
|
+
case 0:
|
|
541
|
+
{
|
|
542
|
+
// Check BFCache during regular navigations. The entry's staleAt
|
|
543
|
+
// determines whether it's still fresh. This is used when
|
|
544
|
+
// staleTimes.dynamic is configured globally or when a page exports
|
|
545
|
+
// unstable_dynamicStaleTime for per-page control.
|
|
546
|
+
const bfcacheEntry = (0, _bfcache.readFromBFCacheDuringRegularNavigation)(now, tree.varyPath);
|
|
547
|
+
if (bfcacheEntry !== null) {
|
|
548
|
+
return {
|
|
549
|
+
cacheNode: createCacheNode(bfcacheEntry.rsc, bfcacheEntry.prefetchRsc, bfcacheEntry.head, bfcacheEntry.prefetchHead),
|
|
550
|
+
needsDynamicRequest: false
|
|
551
|
+
};
|
|
552
|
+
}
|
|
553
|
+
break;
|
|
554
|
+
}
|
|
555
|
+
case 1:
|
|
556
|
+
{
|
|
557
|
+
// This is not related to the BFCache but it is a special case.
|
|
558
|
+
//
|
|
559
|
+
// We should never spawn network requests during hydration. We must treat
|
|
560
|
+
// the initial payload as authoritative, because the initial page load is
|
|
561
|
+
// used as a last-ditch mechanism for recovering the app.
|
|
562
|
+
//
|
|
563
|
+
// This is also an important safety check because if this leaks into the
|
|
564
|
+
// server rendering path (which theoretically it never should because the
|
|
565
|
+
// server payload should be consistent), the server would hang because these
|
|
566
|
+
// promises would never resolve.
|
|
567
|
+
//
|
|
568
|
+
// TODO: There is an existing case where the global "not found" boundary
|
|
569
|
+
// triggers this path. But it does render correctly despite that. That's an
|
|
570
|
+
// unusual render path so it's not surprising, but we should look into
|
|
571
|
+
// modeling it in a more consistent way. See also the /_notFound special
|
|
572
|
+
// case in updateCacheNodeOnNavigation.
|
|
573
|
+
const rsc = seedRsc;
|
|
574
|
+
const prefetchRsc = null;
|
|
575
|
+
const head = isPage ? seedHead : null;
|
|
576
|
+
const prefetchHead = null;
|
|
577
|
+
(0, _bfcache.writeToBFCache)(now, tree.varyPath, rsc, prefetchRsc, head, prefetchHead, dynamicStaleAt);
|
|
578
|
+
if (isPage && metadataVaryPath !== null) {
|
|
579
|
+
(0, _bfcache.writeHeadToBFCache)(now, metadataVaryPath, head, prefetchHead, dynamicStaleAt);
|
|
580
|
+
}
|
|
581
|
+
return {
|
|
582
|
+
cacheNode: createCacheNode(rsc, prefetchRsc, head, prefetchHead),
|
|
583
|
+
needsDynamicRequest: false
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
case 2:
|
|
587
|
+
const bfcacheEntry = (0, _bfcache.readFromBFCache)(tree.varyPath);
|
|
588
|
+
if (bfcacheEntry !== null) {
|
|
589
|
+
// Only show prefetched data if the dynamic data is still pending. This
|
|
590
|
+
// avoids a flash back to the prefetch state in a case where it's highly
|
|
591
|
+
// likely to have already streamed in.
|
|
592
|
+
//
|
|
593
|
+
// Tehnically, what we're actually checking is whether the dynamic
|
|
594
|
+
// network response was received. But since it's a streaming response,
|
|
595
|
+
// this does not mean that all the dynamic data has fully streamed in.
|
|
596
|
+
// It just means that _some_ of the dynamic data was received. But as a
|
|
597
|
+
// heuristic, we assume that the rest dynamic data will stream in
|
|
598
|
+
// quickly, so it's still better to skip the prefetch state.
|
|
599
|
+
const oldRsc = bfcacheEntry.rsc;
|
|
600
|
+
const oldRscDidResolve = !isDeferredRsc(oldRsc) || oldRsc.status !== 'pending';
|
|
601
|
+
const dropPrefetchRsc = oldRscDidResolve;
|
|
602
|
+
return {
|
|
603
|
+
cacheNode: createCacheNode(bfcacheEntry.rsc, dropPrefetchRsc ? null : bfcacheEntry.prefetchRsc, bfcacheEntry.head, dropPrefetchRsc ? null : bfcacheEntry.prefetchHead),
|
|
604
|
+
needsDynamicRequest: false
|
|
605
|
+
};
|
|
606
|
+
}
|
|
607
|
+
break;
|
|
608
|
+
case 3:
|
|
609
|
+
case 4:
|
|
610
|
+
case 5:
|
|
611
|
+
break;
|
|
612
|
+
default:
|
|
613
|
+
freshness;
|
|
614
|
+
break;
|
|
615
|
+
}
|
|
616
|
+
let cachedRsc = null;
|
|
617
|
+
let isCachedRscPartial = true;
|
|
618
|
+
const segmentEntry = (0, _cache.readSegmentCacheEntry)(now, tree.varyPath);
|
|
619
|
+
if (segmentEntry !== null) {
|
|
620
|
+
switch(segmentEntry.status){
|
|
621
|
+
case _cache.EntryStatus.Fulfilled:
|
|
622
|
+
{
|
|
623
|
+
// Happy path: a cache hit
|
|
624
|
+
cachedRsc = segmentEntry.rsc;
|
|
625
|
+
isCachedRscPartial = segmentEntry.isPartial;
|
|
626
|
+
break;
|
|
627
|
+
}
|
|
628
|
+
case _cache.EntryStatus.Pending:
|
|
629
|
+
{
|
|
630
|
+
// We haven't received data for this segment yet, but there's already
|
|
631
|
+
// an in-progress request. Since it's extremely likely to arrive
|
|
632
|
+
// before the dynamic data response, we might as well use it.
|
|
633
|
+
const promiseForFulfilledEntry = (0, _cache.waitForSegmentCacheEntry)(segmentEntry);
|
|
634
|
+
cachedRsc = promiseForFulfilledEntry.then((entry)=>entry !== null ? entry.rsc : null);
|
|
635
|
+
// Because the request is still pending, we typically don't know yet
|
|
636
|
+
// whether the response will be partial. We shouldn't skip this segment
|
|
637
|
+
// during the dynamic navigation request. Otherwise, we might need to
|
|
638
|
+
// do yet another request to fill in the remaining data, creating
|
|
639
|
+
// a waterfall.
|
|
640
|
+
//
|
|
641
|
+
// The one exception is if this segment is being fetched with via
|
|
642
|
+
// prefetch={true} (i.e. the "force stale" or "full" strategy). If so,
|
|
643
|
+
// we can assume the response will be full. This field is set to `false`
|
|
644
|
+
// for such segments.
|
|
645
|
+
isCachedRscPartial = segmentEntry.isPartial;
|
|
646
|
+
break;
|
|
647
|
+
}
|
|
648
|
+
case _cache.EntryStatus.Empty:
|
|
649
|
+
case _cache.EntryStatus.Rejected:
|
|
650
|
+
{
|
|
651
|
+
break;
|
|
652
|
+
}
|
|
653
|
+
default:
|
|
654
|
+
{
|
|
655
|
+
segmentEntry;
|
|
656
|
+
break;
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
// Now combine the cached data with the seed data to determine what we can
|
|
661
|
+
// render immediately, versus what needs to stream in later.
|
|
662
|
+
// A partial state to show immediately while we wait for the final data to
|
|
663
|
+
// arrive. If `rsc` is already a complete value (not partial), or if we
|
|
664
|
+
// don't have any useful partial state, this will be `null`.
|
|
627
665
|
let prefetchRsc;
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
666
|
+
// The final, resolved segment data. If the data is missing, this will be a
|
|
667
|
+
// promise that resolves to the eventual data. A resolved value of `null`
|
|
668
|
+
// means the data failed to load; the LayoutRouter will suspend indefinitely
|
|
669
|
+
// until the router updates again (refer to finishNavigationTask).
|
|
670
|
+
let rsc;
|
|
671
|
+
let doesSegmentNeedDynamicRequest;
|
|
672
|
+
if (seedRsc !== null) {
|
|
673
|
+
// We already have a dynamic server response for this segment.
|
|
674
|
+
if (isCachedRscPartial) {
|
|
675
|
+
// The seed data may still be streaming in, so it's worth showing the
|
|
676
|
+
// partial cached state in the meantime.
|
|
677
|
+
prefetchRsc = cachedRsc;
|
|
678
|
+
rsc = seedRsc;
|
|
679
|
+
} else {
|
|
680
|
+
// We already have a completely cached segment. Ignore the seed data,
|
|
681
|
+
// which may still be streaming in. This shouldn't happen in the normal
|
|
682
|
+
// case because the client will inform the server which segments are
|
|
683
|
+
// already fully cached, and the server will skip rendering them.
|
|
684
|
+
prefetchRsc = null;
|
|
685
|
+
rsc = cachedRsc;
|
|
686
|
+
}
|
|
687
|
+
doesSegmentNeedDynamicRequest = false;
|
|
633
688
|
} else {
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
689
|
+
if (isCachedRscPartial) {
|
|
690
|
+
// The cached data contains dynamic holes, or it's missing entirely. We'll
|
|
691
|
+
// show the partial state immediately (if available), and stream in the
|
|
692
|
+
// final data.
|
|
693
|
+
//
|
|
694
|
+
// Create a pending promise that we can later write to when the
|
|
695
|
+
// data arrives from the server.
|
|
696
|
+
prefetchRsc = cachedRsc;
|
|
697
|
+
rsc = createDeferredRsc();
|
|
698
|
+
} else {
|
|
699
|
+
// The data is fully cached.
|
|
700
|
+
prefetchRsc = null;
|
|
701
|
+
rsc = cachedRsc;
|
|
702
|
+
}
|
|
703
|
+
doesSegmentNeedDynamicRequest = isCachedRscPartial;
|
|
637
704
|
}
|
|
638
|
-
// If this is a page segment,
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
705
|
+
// If this is a page segment, we need to do the same for the head. This
|
|
706
|
+
// follows analogous logic to the segment data above.
|
|
707
|
+
// TODO: We don't need to store the head on the page segment's CacheNode; we
|
|
708
|
+
// can lift it to the main state object. Then we can also delete
|
|
709
|
+
// findHeadCache.
|
|
710
|
+
let prefetchHead = null;
|
|
711
|
+
let head = null;
|
|
712
|
+
let doesHeadNeedDynamicRequest = isPage;
|
|
713
|
+
if (isPage) {
|
|
714
|
+
let cachedHead = null;
|
|
715
|
+
let isCachedHeadPartial = true;
|
|
716
|
+
if (metadataVaryPath !== null) {
|
|
717
|
+
const metadataEntry = (0, _cache.readSegmentCacheEntry)(now, metadataVaryPath);
|
|
718
|
+
if (metadataEntry !== null) {
|
|
719
|
+
switch(metadataEntry.status){
|
|
720
|
+
case _cache.EntryStatus.Fulfilled:
|
|
721
|
+
{
|
|
722
|
+
cachedHead = metadataEntry.rsc;
|
|
723
|
+
isCachedHeadPartial = metadataEntry.isPartial;
|
|
724
|
+
break;
|
|
725
|
+
}
|
|
726
|
+
case _cache.EntryStatus.Pending:
|
|
727
|
+
{
|
|
728
|
+
cachedHead = (0, _cache.waitForSegmentCacheEntry)(metadataEntry).then((entry)=>entry !== null ? entry.rsc : null);
|
|
729
|
+
isCachedHeadPartial = metadataEntry.isPartial;
|
|
730
|
+
break;
|
|
731
|
+
}
|
|
732
|
+
case _cache.EntryStatus.Empty:
|
|
733
|
+
case _cache.EntryStatus.Rejected:
|
|
734
|
+
{
|
|
735
|
+
break;
|
|
736
|
+
}
|
|
737
|
+
default:
|
|
738
|
+
{
|
|
739
|
+
metadataEntry;
|
|
740
|
+
break;
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
if (process.env.__NEXT_OPTIMISTIC_ROUTING && isCachedHeadPartial) {
|
|
746
|
+
// TODO: When optimistic routing is enabled, don't block on waiting for
|
|
747
|
+
// the viewport to resolve. This is a temporary workaround until Vary
|
|
748
|
+
// Params are tracked when rendering the metadata. We'll fix it before
|
|
749
|
+
// this feature is stable. However, it's not a critical issue because 1)
|
|
750
|
+
// it will stream in eventually anyway 2) metadata is wrapped in an
|
|
751
|
+
// internal Suspense boundary, so is always non-blocking; this only
|
|
752
|
+
// affects the viewport node, which is meant to blocking, however... 3)
|
|
753
|
+
// before Segment Cache landed this wasn't always the case, anyway, so
|
|
754
|
+
// it's unlikely that many people are relying on this behavior. Still,
|
|
755
|
+
// will be fixed before stable. It's the very next step in the sequence of
|
|
756
|
+
// work on this project.
|
|
757
|
+
//
|
|
758
|
+
// This line of code works because the App Router treats `null` as
|
|
759
|
+
// "no renderable head available", rather than an empty head. React treats
|
|
760
|
+
// an empty string as empty.
|
|
761
|
+
cachedHead = '';
|
|
762
|
+
}
|
|
763
|
+
if (seedHead !== null) {
|
|
764
|
+
if (isCachedHeadPartial) {
|
|
765
|
+
prefetchHead = cachedHead;
|
|
766
|
+
head = seedHead;
|
|
767
|
+
} else {
|
|
768
|
+
prefetchHead = null;
|
|
769
|
+
head = cachedHead;
|
|
770
|
+
}
|
|
771
|
+
doesHeadNeedDynamicRequest = false;
|
|
645
772
|
} else {
|
|
646
|
-
|
|
647
|
-
|
|
773
|
+
if (isCachedHeadPartial) {
|
|
774
|
+
prefetchHead = cachedHead;
|
|
775
|
+
head = createDeferredRsc();
|
|
776
|
+
} else {
|
|
777
|
+
prefetchHead = null;
|
|
778
|
+
head = cachedHead;
|
|
779
|
+
}
|
|
780
|
+
doesHeadNeedDynamicRequest = isCachedHeadPartial;
|
|
648
781
|
}
|
|
649
|
-
} else {
|
|
650
|
-
prefetchHead = null;
|
|
651
|
-
head = null;
|
|
652
782
|
}
|
|
653
|
-
|
|
783
|
+
// Now that we're creating a new segment, write its data to the BFCache. A
|
|
784
|
+
// subsequent back/forward navigation will reuse this same data, until or
|
|
785
|
+
// unless it's cleared by a refresh/revalidation.
|
|
786
|
+
//
|
|
787
|
+
// Skip BFCache writes for optimistic navigations since they are transient
|
|
788
|
+
// and will be replaced by the canonical navigation.
|
|
789
|
+
if (freshness !== 5) {
|
|
790
|
+
(0, _bfcache.writeToBFCache)(now, tree.varyPath, rsc, prefetchRsc, head, prefetchHead, dynamicStaleAt);
|
|
791
|
+
if (isPage && metadataVaryPath !== null) {
|
|
792
|
+
(0, _bfcache.writeHeadToBFCache)(now, metadataVaryPath, head, prefetchHead, dynamicStaleAt);
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
return {
|
|
796
|
+
cacheNode: createCacheNode(rsc, prefetchRsc, head, prefetchHead),
|
|
797
|
+
// TODO: We should store this field on the CacheNode itself. I think we can
|
|
798
|
+
// probably unify NavigationTask, CacheNode, and DeferredRsc into a
|
|
799
|
+
// single type. Or at least CacheNode and DeferredRsc.
|
|
800
|
+
needsDynamicRequest: doesSegmentNeedDynamicRequest || doesHeadNeedDynamicRequest
|
|
801
|
+
};
|
|
802
|
+
}
|
|
803
|
+
function createCacheNode(rsc, prefetchRsc, head, prefetchHead, scrollRef = null) {
|
|
804
|
+
return {
|
|
654
805
|
rsc,
|
|
655
806
|
prefetchRsc,
|
|
656
807
|
head,
|
|
657
808
|
prefetchHead,
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
// this, like we do for the segment data and head.
|
|
661
|
-
loading: seedLoading,
|
|
662
|
-
parallelRoutes,
|
|
663
|
-
navigatedAt
|
|
809
|
+
slots: null,
|
|
810
|
+
scrollRef
|
|
664
811
|
};
|
|
665
|
-
return cacheNode;
|
|
666
|
-
}
|
|
667
|
-
function spawnNewCacheNode(parallelRoutes, isLeafSegment, navigatedAt, freshness) {
|
|
668
|
-
// We should never spawn network requests during hydration. We must treat the
|
|
669
|
-
// initial payload as authoritative, because the initial page load is used
|
|
670
|
-
// as a last-ditch mechanism for recovering the app.
|
|
671
|
-
//
|
|
672
|
-
// This is also an important safety check because if this leaks into the
|
|
673
|
-
// server rendering path (which theoretically it never should because
|
|
674
|
-
// the server payload should be consistent), the server would hang because
|
|
675
|
-
// these promises would never resolve.
|
|
676
|
-
//
|
|
677
|
-
// TODO: There is an existing case where the global "not found" boundary
|
|
678
|
-
// triggers this path. But it does render correctly despite that. That's an
|
|
679
|
-
// unusual render path so it's not surprising, but we should look into
|
|
680
|
-
// modeling it in a more consistent way. See also the /_notFound special
|
|
681
|
-
// case in updateCacheNodeOnNavigation.
|
|
682
|
-
const isHydration = freshness === 1;
|
|
683
|
-
const cacheNode = {
|
|
684
|
-
rsc: !isHydration ? createDeferredRsc() : null,
|
|
685
|
-
prefetchRsc: null,
|
|
686
|
-
head: !isHydration && isLeafSegment ? createDeferredRsc() : null,
|
|
687
|
-
prefetchHead: null,
|
|
688
|
-
loading: !isHydration ? createDeferredRsc() : null,
|
|
689
|
-
parallelRoutes,
|
|
690
|
-
navigatedAt
|
|
691
|
-
};
|
|
692
|
-
return cacheNode;
|
|
693
812
|
}
|
|
694
813
|
// Represents whether the previuos navigation resulted in a route tree mismatch.
|
|
695
814
|
// A mismatch results in a refresh of the page. If there are two successive
|
|
696
815
|
// mismatches, we will fall back to an MPA navigation, to prevent a retry loop.
|
|
697
816
|
let previousNavigationDidMismatch = false;
|
|
698
|
-
function spawnDynamicRequests(task, primaryUrl, nextUrl, freshnessPolicy, accumulation
|
|
817
|
+
function spawnDynamicRequests(task, primaryUrl, nextUrl, freshnessPolicy, accumulation, // The route cache entry used for this navigation, if it came from route
|
|
818
|
+
// prediction. Passed through so it can be marked as having a dynamic rewrite
|
|
819
|
+
// if the server returns a different pathname than expected (indicating
|
|
820
|
+
// dynamic rewrite behavior that varies by param value).
|
|
821
|
+
routeCacheEntry, // The original navigation's push/replace intent. Threaded through to the
|
|
822
|
+
// server-patch retry logic so it can inherit the intent if the original
|
|
823
|
+
// transition hasn't committed yet.
|
|
824
|
+
navigateType) {
|
|
699
825
|
const dynamicRequestTree = task.dynamicRequestTree;
|
|
700
826
|
if (dynamicRequestTree === null) {
|
|
701
827
|
// This navigation was fully cached. There are no dynamic requests to spawn.
|
|
@@ -711,7 +837,7 @@ function spawnDynamicRequests(task, primaryUrl, nextUrl, freshnessPolicy, accumu
|
|
|
711
837
|
// block the navigation, and collect the promises. The next function,
|
|
712
838
|
// `finishNavigationTask`, can await the promises in any order without
|
|
713
839
|
// accidentally introducing a network waterfall.
|
|
714
|
-
const primaryRequestPromise = fetchMissingDynamicData(task, dynamicRequestTree, primaryUrl, nextUrl, freshnessPolicy);
|
|
840
|
+
const primaryRequestPromise = fetchMissingDynamicData(task, dynamicRequestTree, primaryUrl, nextUrl, freshnessPolicy, routeCacheEntry);
|
|
715
841
|
const separateRefreshUrls = accumulation.separateRefreshUrls;
|
|
716
842
|
let refreshRequestPromises = null;
|
|
717
843
|
if (separateRefreshUrls !== null) {
|
|
@@ -746,18 +872,18 @@ function spawnDynamicRequests(task, primaryUrl, nextUrl, freshnessPolicy, accumu
|
|
|
746
872
|
// start tracking this alongside the refresh URL. In the meantime,
|
|
747
873
|
// if a refresh fails due to a mismatch, it will trigger a
|
|
748
874
|
// hard refresh.
|
|
749
|
-
nextUrl, freshnessPolicy));
|
|
875
|
+
nextUrl, freshnessPolicy, routeCacheEntry));
|
|
750
876
|
}
|
|
751
877
|
}
|
|
752
878
|
}
|
|
753
879
|
// Further async operations are moved into this separate function to
|
|
754
880
|
// discourage sequential network requests.
|
|
755
|
-
const voidPromise = finishNavigationTask(task, nextUrl, primaryRequestPromise, refreshRequestPromises);
|
|
881
|
+
const voidPromise = finishNavigationTask(task, nextUrl, primaryRequestPromise, refreshRequestPromises, routeCacheEntry, navigateType);
|
|
756
882
|
// `finishNavigationTask` is responsible for error handling, so we can attach
|
|
757
883
|
// noop callbacks to this promise.
|
|
758
884
|
voidPromise.then(noop, noop);
|
|
759
885
|
}
|
|
760
|
-
async function finishNavigationTask(task, nextUrl, primaryRequestPromise, refreshRequestPromises) {
|
|
886
|
+
async function finishNavigationTask(task, nextUrl, primaryRequestPromise, refreshRequestPromises, routeCacheEntry, navigateType) {
|
|
761
887
|
// Wait for all the requests to finish, or for the first one to fail.
|
|
762
888
|
let exitStatus = await waitForRequestsToFinish(primaryRequestPromise, refreshRequestPromises);
|
|
763
889
|
// Once the all the requests have finished, check the tree for any remaining
|
|
@@ -784,7 +910,7 @@ async function finishNavigationTask(task, nextUrl, primaryRequestPromise, refres
|
|
|
784
910
|
// happen in a row, fall back to a hard retry.
|
|
785
911
|
const isHardRetry = false;
|
|
786
912
|
const primaryRequestResult = await primaryRequestPromise;
|
|
787
|
-
dispatchRetryDueToTreeMismatch(isHardRetry, primaryRequestResult.url, nextUrl, primaryRequestResult.seed, task.route);
|
|
913
|
+
dispatchRetryDueToTreeMismatch(isHardRetry, primaryRequestResult.url, nextUrl, primaryRequestResult.seed, task.route, routeCacheEntry, navigateType);
|
|
788
914
|
return;
|
|
789
915
|
}
|
|
790
916
|
case 2:
|
|
@@ -799,7 +925,7 @@ async function finishNavigationTask(task, nextUrl, primaryRequestPromise, refres
|
|
|
799
925
|
// doesn't exist yet.
|
|
800
926
|
const isHardRetry = true;
|
|
801
927
|
const primaryRequestResult = await primaryRequestPromise;
|
|
802
|
-
dispatchRetryDueToTreeMismatch(isHardRetry, primaryRequestResult.url, nextUrl, primaryRequestResult.seed, task.route);
|
|
928
|
+
dispatchRetryDueToTreeMismatch(isHardRetry, primaryRequestResult.url, nextUrl, primaryRequestResult.seed, task.route, routeCacheEntry, navigateType);
|
|
803
929
|
return;
|
|
804
930
|
}
|
|
805
931
|
default:
|
|
@@ -848,22 +974,63 @@ function waitForRequestsToFinish(primaryRequestPromise, refreshRequestPromises)
|
|
|
848
974
|
}
|
|
849
975
|
});
|
|
850
976
|
}
|
|
851
|
-
function dispatchRetryDueToTreeMismatch(isHardRetry, retryUrl, retryNextUrl, seed, baseTree
|
|
977
|
+
function dispatchRetryDueToTreeMismatch(isHardRetry, retryUrl, retryNextUrl, seed, baseTree, // The route cache entry used for this navigation, if it came from route
|
|
978
|
+
// prediction. If the navigation results in a mismatch, we mark it as having
|
|
979
|
+
// a dynamic rewrite so future predictions bail out.
|
|
980
|
+
routeCacheEntry, // The original navigation's push/replace intent.
|
|
981
|
+
originalNavigateType) {
|
|
982
|
+
// If the navigation used a route prediction, mark it as having a dynamic
|
|
983
|
+
// rewrite since it resulted in a mismatch.
|
|
984
|
+
if (routeCacheEntry !== null) {
|
|
985
|
+
(0, _cache.markRouteEntryAsDynamicRewrite)(routeCacheEntry);
|
|
986
|
+
} else if (seed !== null) {
|
|
987
|
+
// Even without a direct reference to the route cache entry, we can still
|
|
988
|
+
// mark the route as having a dynamic rewrite by traversing the known route
|
|
989
|
+
// tree. This handles cases where the navigation didn't originate from a
|
|
990
|
+
// route prediction, but still needs to mark the pattern.
|
|
991
|
+
const metadataVaryPath = seed.metadataVaryPath;
|
|
992
|
+
if (metadataVaryPath !== null) {
|
|
993
|
+
const now = Date.now();
|
|
994
|
+
(0, _optimisticroutes.discoverKnownRoute)(now, retryUrl.pathname, retryNextUrl, null, seed.routeTree, metadataVaryPath, false, (0, _createhreffromurl.createHrefFromUrl)(retryUrl), false, true // hasDynamicRewrite
|
|
995
|
+
);
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
// Invalidate all route cache entries. Other entries may have been derived
|
|
999
|
+
// from the template before we knew it had a dynamic rewrite. This also
|
|
1000
|
+
// triggers re-prefetching of visible links.
|
|
1001
|
+
(0, _cache.invalidateRouteCacheEntries)(retryNextUrl, baseTree);
|
|
852
1002
|
// If this is the second time in a row that a navigation resulted in a
|
|
853
1003
|
// mismatch, fall back to a hard (MPA) refresh.
|
|
854
1004
|
isHardRetry = isHardRetry || previousNavigationDidMismatch;
|
|
855
1005
|
previousNavigationDidMismatch = true;
|
|
1006
|
+
// If the original navigation hasn't committed to the browser history yet
|
|
1007
|
+
// (the transition suspended before React committed), inherit its push/replace
|
|
1008
|
+
// intent. Otherwise, the pushState already ran, so use 'replace' to avoid
|
|
1009
|
+
// creating a duplicate history entry.
|
|
1010
|
+
//
|
|
1011
|
+
// This works because React entangles the retry's state update with the
|
|
1012
|
+
// original pending transition — they commit together as a single batch,
|
|
1013
|
+
// so the navigate type from the retry is what HistoryUpdater ultimately sees.
|
|
1014
|
+
//
|
|
1015
|
+
// TODO: Ideally this check would happen right before we schedule the React
|
|
1016
|
+
// update (i.e., closer to where the action is dispatched into the queue),
|
|
1017
|
+
// not here where the action is constructed. But the current action queue
|
|
1018
|
+
// doesn't provide a natural place for that. Revisit when we refactor the
|
|
1019
|
+
// action queue into a more reactive navigation model.
|
|
1020
|
+
const lastCommitted = (0, _committedstate.getLastCommittedTree)();
|
|
1021
|
+
const retryNavigateType = lastCommitted !== null && baseTree !== lastCommitted ? originalNavigateType : 'replace';
|
|
856
1022
|
const retryAction = {
|
|
857
1023
|
type: _routerreducertypes.ACTION_SERVER_PATCH,
|
|
858
1024
|
previousTree: baseTree,
|
|
859
1025
|
url: retryUrl,
|
|
860
1026
|
nextUrl: retryNextUrl,
|
|
861
1027
|
seed,
|
|
862
|
-
mpa: isHardRetry
|
|
1028
|
+
mpa: isHardRetry,
|
|
1029
|
+
navigateType: retryNavigateType
|
|
863
1030
|
};
|
|
864
1031
|
(0, _useactionqueue.dispatchAppRouterAction)(retryAction);
|
|
865
1032
|
}
|
|
866
|
-
async function fetchMissingDynamicData(task, dynamicRequestTree, url, nextUrl, freshnessPolicy) {
|
|
1033
|
+
async function fetchMissingDynamicData(task, dynamicRequestTree, url, nextUrl, freshnessPolicy, routeCacheEntry) {
|
|
867
1034
|
try {
|
|
868
1035
|
const result = await (0, _fetchserverresponse.fetchServerResponse)(url, {
|
|
869
1036
|
flightRouterState: dynamicRequestTree,
|
|
@@ -881,8 +1048,38 @@ async function fetchMissingDynamicData(task, dynamicRequestTree, url, nextUrl, f
|
|
|
881
1048
|
seed: null
|
|
882
1049
|
};
|
|
883
1050
|
}
|
|
884
|
-
const
|
|
885
|
-
const
|
|
1051
|
+
const now = Date.now();
|
|
1052
|
+
const seed = (0, _navigation.convertServerPatchToFullTree)(now, task.route, result.flightData, result.renderedSearch, result.dynamicStaleTime);
|
|
1053
|
+
// If the navigation lock is active, wait for it to be released before
|
|
1054
|
+
// writing the dynamic data. This allows tests to assert on the prefetched
|
|
1055
|
+
// UI state.
|
|
1056
|
+
if (process.env.__NEXT_EXPOSE_TESTING_API) {
|
|
1057
|
+
await waitForNavigationLock();
|
|
1058
|
+
}
|
|
1059
|
+
if (routeCacheEntry !== null && result.staticStageData !== null) {
|
|
1060
|
+
const { response: staticStageResponse, isResponsePartial } = result.staticStageData;
|
|
1061
|
+
(0, _cache.getStaleAt)(now, staticStageResponse.s).then((staleAt)=>{
|
|
1062
|
+
const buildId = result.responseHeaders.get(_constants.NEXT_NAV_DEPLOYMENT_ID_HEADER) ?? staticStageResponse.b;
|
|
1063
|
+
(0, _cache.writeStaticStageResponseIntoCache)(now, staticStageResponse.f, buildId, staticStageResponse.h, staleAt, dynamicRequestTree, result.renderedSearch, isResponsePartial);
|
|
1064
|
+
}).catch(()=>{
|
|
1065
|
+
// The static stage processing failed. Not fatal — the navigation
|
|
1066
|
+
// completed normally, we just won't write into the cache.
|
|
1067
|
+
});
|
|
1068
|
+
}
|
|
1069
|
+
if (routeCacheEntry !== null && result.runtimePrefetchStream !== null) {
|
|
1070
|
+
(0, _cache.processRuntimePrefetchStream)(now, result.runtimePrefetchStream, dynamicRequestTree, result.renderedSearch).then((processed)=>{
|
|
1071
|
+
if (processed !== null) {
|
|
1072
|
+
(0, _cache.writeDynamicRenderResponseIntoCache)(now, _types.FetchStrategy.PPRRuntime, processed.flightDatas, processed.buildId, processed.isResponsePartial, processed.headVaryParams, processed.staleAt, processed.navigationSeed, null);
|
|
1073
|
+
}
|
|
1074
|
+
}).catch(()=>{
|
|
1075
|
+
// The runtime prefetch cache write failed. Not fatal — the
|
|
1076
|
+
// navigation completed normally, we just won't cache runtime data.
|
|
1077
|
+
});
|
|
1078
|
+
}
|
|
1079
|
+
// result.dynamicStaleTime is in seconds (from the server's `d` field).
|
|
1080
|
+
// Convert to an absolute timestamp using the centralized helper.
|
|
1081
|
+
const dynamicStaleAt = (0, _bfcache.computeDynamicStaleAt)(now, result.dynamicStaleTime);
|
|
1082
|
+
const didReceiveUnknownParallelRoute = writeDynamicDataIntoNavigationTask(task, seed.routeTree, seed.data, seed.head, dynamicStaleAt, result.debugInfo);
|
|
886
1083
|
return {
|
|
887
1084
|
exitStatus: didReceiveUnknownParallelRoute ? 1 : 0,
|
|
888
1085
|
url: new URL(result.canonicalUrl, location.origin),
|
|
@@ -899,47 +1096,61 @@ async function fetchMissingDynamicData(task, dynamicRequestTree, url, nextUrl, f
|
|
|
899
1096
|
};
|
|
900
1097
|
}
|
|
901
1098
|
}
|
|
902
|
-
function writeDynamicDataIntoNavigationTask(task,
|
|
1099
|
+
function writeDynamicDataIntoNavigationTask(task, serverRouteTree, dynamicData, dynamicHead, dynamicStaleAt, debugInfo) {
|
|
903
1100
|
if (task.status === 0 && dynamicData !== null) {
|
|
904
1101
|
task.status = 1;
|
|
905
1102
|
finishPendingCacheNode(task.node, dynamicData, dynamicHead, debugInfo);
|
|
1103
|
+
// Update the BFCache entry's staleAt for this segment with the value
|
|
1104
|
+
// from the dynamic response. This applies the per-page
|
|
1105
|
+
// unstable_dynamicStaleTime if set, or the default DYNAMIC_STALETIME_MS.
|
|
1106
|
+
// We only update segments that received dynamic data — static segments
|
|
1107
|
+
// are unaffected.
|
|
1108
|
+
(0, _bfcache.updateBFCacheEntryStaleAt)(serverRouteTree.varyPath, dynamicStaleAt);
|
|
906
1109
|
}
|
|
907
1110
|
const taskChildren = task.children;
|
|
908
|
-
const serverChildren =
|
|
1111
|
+
const serverChildren = serverRouteTree.slots;
|
|
909
1112
|
const dynamicDataChildren = dynamicData !== null ? dynamicData[1] : null;
|
|
910
1113
|
// Detect whether the server sends a parallel route slot that the client
|
|
911
1114
|
// doesn't know about.
|
|
912
1115
|
let didReceiveUnknownParallelRoute = false;
|
|
913
1116
|
if (taskChildren !== null) {
|
|
914
|
-
|
|
915
|
-
const
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
1117
|
+
if (serverChildren !== null) {
|
|
1118
|
+
for(const parallelRouteKey in serverChildren){
|
|
1119
|
+
const serverRouteTreeChild = serverChildren[parallelRouteKey];
|
|
1120
|
+
const dynamicDataChild = dynamicDataChildren !== null ? dynamicDataChildren[parallelRouteKey] : null;
|
|
1121
|
+
const taskChild = taskChildren.get(parallelRouteKey);
|
|
1122
|
+
if (taskChild === undefined) {
|
|
1123
|
+
// The server sent a child segment that the client doesn't know about.
|
|
1124
|
+
//
|
|
1125
|
+
// When we receive an unknown parallel route, we must consider it a
|
|
1126
|
+
// mismatch. This is unlike the case where the segment itself
|
|
1127
|
+
// mismatches, because multiple routes can be active simultaneously.
|
|
1128
|
+
// But a given layout should never have a mismatching set of
|
|
1129
|
+
// child slots.
|
|
1130
|
+
//
|
|
1131
|
+
// Theoretically, this should only happen in development during an HMR
|
|
1132
|
+
// refresh, because the set of parallel routes for a layout does not
|
|
1133
|
+
// change over the lifetime of a build/deployment. In production, we
|
|
1134
|
+
// should have already mismatched on either the build id or the segment
|
|
1135
|
+
// path. But as an extra precaution, we validate in prod, too.
|
|
1136
|
+
didReceiveUnknownParallelRoute = true;
|
|
1137
|
+
} else {
|
|
1138
|
+
const taskSegment = taskChild.route[0];
|
|
1139
|
+
const serverSegment = createSegmentFromRouteTree(serverRouteTreeChild);
|
|
1140
|
+
if ((0, _matchsegments.matchSegment)(serverSegment, taskSegment) && dynamicDataChild !== null && dynamicDataChild !== undefined) {
|
|
1141
|
+
// Found a match for this task. Keep traversing down the task tree.
|
|
1142
|
+
const childDidReceiveUnknownParallelRoute = writeDynamicDataIntoNavigationTask(taskChild, serverRouteTreeChild, dynamicDataChild, dynamicHead, dynamicStaleAt, debugInfo);
|
|
1143
|
+
if (childDidReceiveUnknownParallelRoute) {
|
|
1144
|
+
didReceiveUnknownParallelRoute = true;
|
|
1145
|
+
}
|
|
940
1146
|
}
|
|
941
1147
|
}
|
|
942
1148
|
}
|
|
1149
|
+
} else {
|
|
1150
|
+
if (serverChildren !== null) {
|
|
1151
|
+
// The server sent a child segment that the client doesn't know about.
|
|
1152
|
+
didReceiveUnknownParallelRoute = true;
|
|
1153
|
+
}
|
|
943
1154
|
}
|
|
944
1155
|
}
|
|
945
1156
|
return didReceiveUnknownParallelRoute;
|
|
@@ -978,13 +1189,6 @@ function finishPendingCacheNode(cacheNode, dynamicData, dynamicHead, debugInfo)
|
|
|
978
1189
|
// This is not a deferred RSC promise, nor is it empty, so it must have
|
|
979
1190
|
// been populated by a different navigation. We must not overwrite it.
|
|
980
1191
|
}
|
|
981
|
-
// If we navigated without a prefetch, then `loading` will be a deferred promise too.
|
|
982
|
-
// Fulfill it using the dynamic response so that we can display the loading boundary.
|
|
983
|
-
const loading = cacheNode.loading;
|
|
984
|
-
if (isDeferredRsc(loading)) {
|
|
985
|
-
const dynamicLoading = dynamicData[2];
|
|
986
|
-
loading.resolve(dynamicLoading, debugInfo);
|
|
987
|
-
}
|
|
988
1192
|
// Check if this is a leaf segment. If so, it will have a `head` property with
|
|
989
1193
|
// a pending promise that needs to be resolved with the dynamic head from
|
|
990
1194
|
// the server.
|
|
@@ -1011,7 +1215,7 @@ function abortRemainingPendingTasks(task, error, debugInfo) {
|
|
|
1011
1215
|
//
|
|
1012
1216
|
// When this happens, we treat this the same as a refresh(). The entire
|
|
1013
1217
|
// tree will be re-rendered from the root.
|
|
1014
|
-
if (task.
|
|
1218
|
+
if (task.refreshState === null) {
|
|
1015
1219
|
// Trigger a "soft" refresh. Essentially the same as calling `refresh()`
|
|
1016
1220
|
// in a Server Action.
|
|
1017
1221
|
exitStatus = 1;
|
|
@@ -1053,10 +1257,6 @@ function abortPendingCacheNode(cacheNode, error, debugInfo) {
|
|
|
1053
1257
|
rsc.reject(error, debugInfo);
|
|
1054
1258
|
}
|
|
1055
1259
|
}
|
|
1056
|
-
const loading = cacheNode.loading;
|
|
1057
|
-
if (isDeferredRsc(loading)) {
|
|
1058
|
-
loading.resolve(null, debugInfo);
|
|
1059
|
-
}
|
|
1060
1260
|
// Check if this is a leaf segment. If so, it will have a `head` property with
|
|
1061
1261
|
// a pending promise that needs to be resolved. If an error was provided, we
|
|
1062
1262
|
// will not resolve it with an error, since this is rendered at the root of
|
|
@@ -1119,6 +1319,18 @@ function createDeferredRsc() {
|
|
|
1119
1319
|
pendingRsc._debugInfo = debugInfo;
|
|
1120
1320
|
return pendingRsc;
|
|
1121
1321
|
}
|
|
1322
|
+
/**
|
|
1323
|
+
* Helper for the Instant Navigation Testing API. Waits for the navigation lock
|
|
1324
|
+
* to be released before returning. The network request has already completed by
|
|
1325
|
+
* the time this is called, so this only delays writing the dynamic data.
|
|
1326
|
+
*
|
|
1327
|
+
* Not exposed in production builds by default.
|
|
1328
|
+
*/ async function waitForNavigationLock() {
|
|
1329
|
+
if (process.env.__NEXT_EXPOSE_TESTING_API) {
|
|
1330
|
+
const { waitForNavigationLockIfActive } = require('../segment-cache/navigation-testing-lock');
|
|
1331
|
+
await waitForNavigationLockIfActive();
|
|
1332
|
+
}
|
|
1333
|
+
}
|
|
1122
1334
|
|
|
1123
1335
|
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
|
|
1124
1336
|
Object.defineProperty(exports.default, '__esModule', { value: true });
|