vinext 0.0.49 → 0.0.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/build/client-build-config.js.map +1 -1
- package/dist/build/google-fonts/build-url.js.map +1 -1
- package/dist/build/google-fonts/fallback-metrics-data.js +14031 -0
- package/dist/build/google-fonts/fallback-metrics-data.js.map +1 -0
- package/dist/build/google-fonts/fallback-metrics.d.ts +13 -0
- package/dist/build/google-fonts/fallback-metrics.js +46 -0
- package/dist/build/google-fonts/fallback-metrics.js.map +1 -0
- package/dist/build/google-fonts/get-axes.js.map +1 -1
- package/dist/build/google-fonts/sort-variants.js.map +1 -1
- package/dist/build/google-fonts/validate.js.map +1 -1
- package/dist/build/layout-classification.js.map +1 -1
- package/dist/build/nitro-route-rules.js.map +1 -1
- package/dist/build/precompress.d.ts +13 -2
- package/dist/build/precompress.js +12 -3
- package/dist/build/precompress.js.map +1 -1
- package/dist/build/prerender.d.ts +17 -1
- package/dist/build/prerender.js +114 -23
- package/dist/build/prerender.js.map +1 -1
- package/dist/build/report.d.ts +5 -4
- package/dist/build/report.js +196 -348
- package/dist/build/report.js.map +1 -1
- package/dist/build/route-classification-injector.js.map +1 -1
- package/dist/build/route-classification-manifest.js.map +1 -1
- package/dist/build/run-prerender.js.map +1 -1
- package/dist/build/server-manifest.js.map +1 -1
- package/dist/build/ssr-manifest.js.map +1 -1
- package/dist/build/standalone.js.map +1 -1
- package/dist/build/static-export.js.map +1 -1
- package/dist/check.js +2 -1
- package/dist/check.js.map +1 -1
- package/dist/cli-args.js.map +1 -1
- package/dist/cli.js +68 -7
- package/dist/cli.js.map +1 -1
- package/dist/client/instrumentation-client-state.js.map +1 -1
- package/dist/client/validate-module-path.js.map +1 -1
- package/dist/client/vinext-next-data.d.ts +5 -1
- package/dist/client/window-next.d.ts +151 -0
- package/dist/client/window-next.js +48 -0
- package/dist/client/window-next.js.map +1 -0
- package/dist/cloudflare/kv-cache-handler.js.map +1 -1
- package/dist/cloudflare/tpr.js +2 -1
- package/dist/cloudflare/tpr.js.map +1 -1
- package/dist/config/config-matchers.d.ts +3 -1
- package/dist/config/config-matchers.js +5 -4
- package/dist/config/config-matchers.js.map +1 -1
- package/dist/config/dotenv.d.ts +11 -1
- package/dist/config/dotenv.js.map +1 -1
- package/dist/config/next-config.d.ts +93 -6
- package/dist/config/next-config.js +233 -6
- package/dist/config/next-config.js.map +1 -1
- package/dist/config/tsconfig-paths.d.ts +13 -0
- package/dist/config/tsconfig-paths.js +117 -0
- package/dist/config/tsconfig-paths.js.map +1 -0
- package/dist/deploy.js +16 -7
- package/dist/deploy.js.map +1 -1
- package/dist/entries/app-browser-entry.d.ts +3 -1
- package/dist/entries/app-browser-entry.js +36 -2
- package/dist/entries/app-browser-entry.js.map +1 -1
- package/dist/entries/app-rsc-entry.d.ts +19 -1
- package/dist/entries/app-rsc-entry.js +49 -12
- package/dist/entries/app-rsc-entry.js.map +1 -1
- package/dist/entries/app-rsc-manifest.d.ts +9 -0
- package/dist/entries/app-rsc-manifest.js +8 -1
- package/dist/entries/app-rsc-manifest.js.map +1 -1
- package/dist/entries/app-ssr-entry.js.map +1 -1
- package/dist/entries/pages-client-entry.js +3 -5
- package/dist/entries/pages-client-entry.js.map +1 -1
- package/dist/entries/pages-entry-helpers.js.map +1 -1
- package/dist/entries/pages-server-entry.js +34 -1
- package/dist/entries/pages-server-entry.js.map +1 -1
- package/dist/entries/runtime-entry-module.js.map +1 -1
- package/dist/index.js +204 -53
- package/dist/index.js.map +1 -1
- package/dist/init.js.map +1 -1
- package/dist/plugins/async-hooks-stub.js.map +1 -1
- package/dist/plugins/client-reference-dedup.d.ts +15 -2
- package/dist/plugins/client-reference-dedup.js +138 -16
- package/dist/plugins/client-reference-dedup.js.map +1 -1
- package/dist/plugins/fonts.d.ts +2 -2
- package/dist/plugins/fonts.js +15 -6
- package/dist/plugins/fonts.js.map +1 -1
- package/dist/plugins/instrumentation-client.js.map +1 -1
- package/dist/plugins/og-assets.js.map +1 -1
- package/dist/plugins/optimize-imports.js.map +1 -1
- package/dist/plugins/postcss.js.map +1 -1
- package/dist/plugins/rsc-client-reference-loaders.d.ts +7 -0
- package/dist/plugins/rsc-client-reference-loaders.js +48 -0
- package/dist/plugins/rsc-client-reference-loaders.js.map +1 -0
- package/dist/plugins/rsc-client-shim-excludes.js.map +1 -1
- package/dist/plugins/sass.d.ts +34 -0
- package/dist/plugins/sass.js +22 -0
- package/dist/plugins/sass.js.map +1 -0
- package/dist/plugins/server-externals-manifest.js.map +1 -1
- package/dist/plugins/strip-server-exports.js.map +1 -1
- package/dist/routing/app-route-graph.d.ts +78 -6
- package/dist/routing/app-route-graph.js +241 -25
- package/dist/routing/app-route-graph.js.map +1 -1
- package/dist/routing/app-router.js.map +1 -1
- package/dist/routing/file-matcher.js.map +1 -1
- package/dist/routing/pages-router.js.map +1 -1
- package/dist/routing/route-matching.js.map +1 -1
- package/dist/routing/route-pattern.d.ts +56 -1
- package/dist/routing/route-pattern.js +60 -1
- package/dist/routing/route-pattern.js.map +1 -1
- package/dist/routing/route-trie.js.map +1 -1
- package/dist/routing/route-validation.js.map +1 -1
- package/dist/routing/utils.js.map +1 -1
- package/dist/server/api-handler.js.map +1 -1
- package/dist/server/app-browser-action-result.d.ts +44 -0
- package/dist/server/app-browser-action-result.js +79 -0
- package/dist/server/app-browser-action-result.js.map +1 -0
- package/dist/server/app-browser-entry.js +330 -133
- package/dist/server/app-browser-entry.js.map +1 -1
- package/dist/server/app-browser-error.js.map +1 -1
- package/dist/server/app-browser-hydration.d.ts +31 -0
- package/dist/server/app-browser-hydration.js +30 -0
- package/dist/server/app-browser-hydration.js.map +1 -0
- package/dist/server/app-browser-navigation-controller.d.ts +20 -4
- package/dist/server/app-browser-navigation-controller.js +90 -23
- package/dist/server/app-browser-navigation-controller.js.map +1 -1
- package/dist/server/app-browser-popstate.d.ts +16 -0
- package/dist/server/app-browser-popstate.js +17 -0
- package/dist/server/app-browser-popstate.js.map +1 -0
- package/dist/server/app-browser-rsc-redirect.d.ts +28 -0
- package/dist/server/app-browser-rsc-redirect.js +37 -0
- package/dist/server/app-browser-rsc-redirect.js.map +1 -0
- package/dist/server/app-browser-state.d.ts +27 -23
- package/dist/server/app-browser-state.js +158 -54
- package/dist/server/app-browser-state.js.map +1 -1
- package/dist/server/app-browser-stream.d.ts +9 -4
- package/dist/server/app-browser-stream.js +29 -8
- package/dist/server/app-browser-stream.js.map +1 -1
- package/dist/server/app-browser-visible-commit.d.ts +11 -1
- package/dist/server/app-browser-visible-commit.js +69 -21
- package/dist/server/app-browser-visible-commit.js.map +1 -1
- package/dist/server/app-client-reference-preloader.js.map +1 -1
- package/dist/server/app-elements-wire.d.ts +43 -6
- package/dist/server/app-elements-wire.js +121 -5
- package/dist/server/app-elements-wire.js.map +1 -1
- package/dist/server/app-elements.d.ts +2 -2
- package/dist/server/app-elements.js +2 -2
- package/dist/server/app-elements.js.map +1 -1
- package/dist/server/app-fallback-renderer.d.ts +10 -1
- package/dist/server/app-fallback-renderer.js +37 -1
- package/dist/server/app-fallback-renderer.js.map +1 -1
- package/dist/server/app-history-state.d.ts +26 -0
- package/dist/server/app-history-state.js +53 -0
- package/dist/server/app-history-state.js.map +1 -0
- package/dist/server/app-hook-warning-suppression.js.map +1 -1
- package/dist/server/app-middleware.d.ts +1 -1
- package/dist/server/app-middleware.js +4 -9
- package/dist/server/app-middleware.js.map +1 -1
- package/dist/server/app-mounted-slots-header.js.map +1 -1
- package/dist/server/app-page-boundary-render.d.ts +11 -1
- package/dist/server/app-page-boundary-render.js +27 -19
- package/dist/server/app-page-boundary-render.js.map +1 -1
- package/dist/server/app-page-boundary.d.ts +1 -0
- package/dist/server/app-page-boundary.js +10 -7
- package/dist/server/app-page-boundary.js.map +1 -1
- package/dist/server/app-page-cache.d.ts +23 -3
- package/dist/server/app-page-cache.js +63 -27
- package/dist/server/app-page-cache.js.map +1 -1
- package/dist/server/app-page-dispatch.d.ts +11 -1
- package/dist/server/app-page-dispatch.js +85 -14
- package/dist/server/app-page-dispatch.js.map +1 -1
- package/dist/server/app-page-element-builder.d.ts +10 -1
- package/dist/server/app-page-element-builder.js +38 -6
- package/dist/server/app-page-element-builder.js.map +1 -1
- package/dist/server/app-page-execution.js +2 -3
- package/dist/server/app-page-execution.js.map +1 -1
- package/dist/server/app-page-head.d.ts +7 -0
- package/dist/server/app-page-head.js +6 -1
- package/dist/server/app-page-head.js.map +1 -1
- package/dist/server/app-page-method.js.map +1 -1
- package/dist/server/app-page-params.js.map +1 -1
- package/dist/server/app-page-probe.d.ts +23 -1
- package/dist/server/app-page-probe.js +29 -1
- package/dist/server/app-page-probe.js.map +1 -1
- package/dist/server/app-page-render-observation.d.ts +35 -0
- package/dist/server/app-page-render-observation.js +68 -0
- package/dist/server/app-page-render-observation.js.map +1 -0
- package/dist/server/app-page-render.d.ts +12 -2
- package/dist/server/app-page-render.js +90 -7
- package/dist/server/app-page-render.js.map +1 -1
- package/dist/server/app-page-request.d.ts +1 -0
- package/dist/server/app-page-request.js +2 -1
- package/dist/server/app-page-request.js.map +1 -1
- package/dist/server/app-page-response.d.ts +2 -0
- package/dist/server/app-page-response.js +18 -7
- package/dist/server/app-page-response.js.map +1 -1
- package/dist/server/app-page-route-wiring.d.ts +9 -3
- package/dist/server/app-page-route-wiring.js +91 -62
- package/dist/server/app-page-route-wiring.js.map +1 -1
- package/dist/server/app-page-segment-state.d.ts +10 -0
- package/dist/server/app-page-segment-state.js +87 -0
- package/dist/server/app-page-segment-state.js.map +1 -0
- package/dist/server/app-page-stream.d.ts +9 -2
- package/dist/server/app-page-stream.js +4 -1
- package/dist/server/app-page-stream.js.map +1 -1
- package/dist/server/app-post-middleware-context.js.map +1 -1
- package/dist/server/app-prerender-endpoints.js.map +1 -1
- package/dist/server/app-prerender-static-params.js.map +1 -1
- package/dist/server/app-render-dependency.js.map +1 -1
- package/dist/server/app-request-context.js.map +1 -1
- package/dist/server/app-route-handler-cache.js.map +1 -1
- package/dist/server/app-route-handler-dispatch.js +3 -1
- package/dist/server/app-route-handler-dispatch.js.map +1 -1
- package/dist/server/app-route-handler-execution.js.map +1 -1
- package/dist/server/app-route-handler-policy.js +1 -0
- package/dist/server/app-route-handler-policy.js.map +1 -1
- package/dist/server/app-route-handler-response.js +4 -3
- package/dist/server/app-route-handler-response.js.map +1 -1
- package/dist/server/app-route-handler-runtime.js.map +1 -1
- package/dist/server/app-router-entry.js +7 -15
- package/dist/server/app-router-entry.js.map +1 -1
- package/dist/server/app-rsc-cache-busting.d.ts +23 -2
- package/dist/server/app-rsc-cache-busting.js +75 -19
- package/dist/server/app-rsc-cache-busting.js.map +1 -1
- package/dist/server/app-rsc-embedded-chunks.d.ts +9 -0
- package/dist/server/app-rsc-embedded-chunks.js +34 -0
- package/dist/server/app-rsc-embedded-chunks.js.map +1 -0
- package/dist/server/app-rsc-error-handler.js.map +1 -1
- package/dist/server/app-rsc-errors.d.ts +4 -1
- package/dist/server/app-rsc-errors.js +1 -1
- package/dist/server/app-rsc-errors.js.map +1 -1
- package/dist/server/app-rsc-handler.d.ts +18 -1
- package/dist/server/app-rsc-handler.js +55 -16
- package/dist/server/app-rsc-handler.js.map +1 -1
- package/dist/server/app-rsc-render-mode.d.ts +11 -0
- package/dist/server/app-rsc-render-mode.js +21 -0
- package/dist/server/app-rsc-render-mode.js.map +1 -0
- package/dist/server/app-rsc-request-normalization.d.ts +4 -1
- package/dist/server/app-rsc-request-normalization.js +7 -2
- package/dist/server/app-rsc-request-normalization.js.map +1 -1
- package/dist/server/app-rsc-response-finalizer.d.ts +2 -1
- package/dist/server/app-rsc-response-finalizer.js +6 -1
- package/dist/server/app-rsc-response-finalizer.js.map +1 -1
- package/dist/server/app-rsc-route-matching.d.ts +23 -0
- package/dist/server/app-rsc-route-matching.js +45 -23
- package/dist/server/app-rsc-route-matching.js.map +1 -1
- package/dist/server/app-segment-config.js.map +1 -1
- package/dist/server/app-server-action-execution.d.ts +51 -5
- package/dist/server/app-server-action-execution.js +161 -51
- package/dist/server/app-server-action-execution.js.map +1 -1
- package/dist/server/app-ssr-entry.d.ts +7 -0
- package/dist/server/app-ssr-entry.js +44 -14
- package/dist/server/app-ssr-entry.js.map +1 -1
- package/dist/server/app-ssr-error-meta.d.ts +14 -0
- package/dist/server/app-ssr-error-meta.js +50 -0
- package/dist/server/app-ssr-error-meta.js.map +1 -0
- package/dist/server/app-ssr-stream.d.ts +1 -1
- package/dist/server/app-ssr-stream.js +9 -12
- package/dist/server/app-ssr-stream.js.map +1 -1
- package/dist/server/app-static-generation.js.map +1 -1
- package/dist/server/artifact-compatibility.d.ts +12 -2
- package/dist/server/artifact-compatibility.js +12 -8
- package/dist/server/artifact-compatibility.js.map +1 -1
- package/dist/server/cache-control.js +1 -0
- package/dist/server/cache-control.js.map +1 -1
- package/dist/server/cache-proof.d.ts +124 -5
- package/dist/server/cache-proof.js +416 -18
- package/dist/server/cache-proof.js.map +1 -1
- package/dist/server/csp.js.map +1 -1
- package/dist/server/dev-error-overlay-store.js.map +1 -1
- package/dist/server/dev-error-overlay.js +5 -0
- package/dist/server/dev-error-overlay.js.map +1 -1
- package/dist/server/dev-lockfile.d.ts +110 -0
- package/dist/server/dev-lockfile.js +180 -0
- package/dist/server/dev-lockfile.js.map +1 -0
- package/dist/server/dev-module-runner.js.map +1 -1
- package/dist/server/dev-origin-check.js.map +1 -1
- package/dist/server/dev-route-files.js.map +1 -1
- package/dist/server/dev-server.js +23 -10
- package/dist/server/dev-server.js.map +1 -1
- package/dist/server/file-based-metadata.d.ts +13 -0
- package/dist/server/file-based-metadata.js +49 -2
- package/dist/server/file-based-metadata.js.map +1 -1
- package/dist/server/headers.d.ts +81 -0
- package/dist/server/headers.js +104 -0
- package/dist/server/headers.js.map +1 -0
- package/dist/server/html.js +1 -1
- package/dist/server/html.js.map +1 -1
- package/dist/server/http-error-responses.d.ts +10 -0
- package/dist/server/http-error-responses.js +11 -1
- package/dist/server/http-error-responses.js.map +1 -1
- package/dist/server/image-optimization.d.ts +11 -1
- package/dist/server/image-optimization.js.map +1 -1
- package/dist/server/implicit-tags.js +2 -1
- package/dist/server/implicit-tags.js.map +1 -1
- package/dist/server/instrumentation-runtime.js.map +1 -1
- package/dist/server/instrumentation.js.map +1 -1
- package/dist/server/isr-cache.d.ts +12 -2
- package/dist/server/isr-cache.js +16 -5
- package/dist/server/isr-cache.js.map +1 -1
- package/dist/server/metadata-route-build-data.js.map +1 -1
- package/dist/server/metadata-route-response.js +22 -5
- package/dist/server/metadata-route-response.js.map +1 -1
- package/dist/server/metadata-routes.js +27 -8
- package/dist/server/metadata-routes.js.map +1 -1
- package/dist/server/middleware-matcher.js.map +1 -1
- package/dist/server/middleware-request-headers.d.ts +4 -1
- package/dist/server/middleware-request-headers.js +15 -8
- package/dist/server/middleware-request-headers.js.map +1 -1
- package/dist/server/middleware-response-headers.d.ts +2 -1
- package/dist/server/middleware-response-headers.js +1 -1
- package/dist/server/middleware-response-headers.js.map +1 -1
- package/dist/server/middleware-runtime.d.ts +1 -0
- package/dist/server/middleware-runtime.js +7 -3
- package/dist/server/middleware-runtime.js.map +1 -1
- package/dist/server/middleware.d.ts +12 -0
- package/dist/server/middleware.js +12 -0
- package/dist/server/middleware.js.map +1 -1
- package/dist/server/navigation-planner.d.ts +133 -0
- package/dist/server/navigation-planner.js +432 -0
- package/dist/server/navigation-planner.js.map +1 -0
- package/dist/server/navigation-trace.d.ts +19 -2
- package/dist/server/navigation-trace.js +20 -1
- package/dist/server/navigation-trace.js.map +1 -1
- package/dist/server/next-error-digest.d.ts +3 -2
- package/dist/server/next-error-digest.js +4 -2
- package/dist/server/next-error-digest.js.map +1 -1
- package/dist/server/normalize-path.d.ts +2 -1
- package/dist/server/normalize-path.js +4 -1
- package/dist/server/normalize-path.js.map +1 -1
- package/dist/server/pages-api-route.js +1 -0
- package/dist/server/pages-api-route.js.map +1 -1
- package/dist/server/pages-i18n.js.map +1 -1
- package/dist/server/pages-media-type.js.map +1 -1
- package/dist/server/pages-node-compat.js.map +1 -1
- package/dist/server/pages-page-data.d.ts +3 -2
- package/dist/server/pages-page-data.js +27 -5
- package/dist/server/pages-page-data.js.map +1 -1
- package/dist/server/pages-page-response.js +2 -1
- package/dist/server/pages-page-response.js.map +1 -1
- package/dist/server/prerender-work-unit-setup.js +1 -1
- package/dist/server/prerender-work-unit-setup.js.map +1 -1
- package/dist/server/prod-server.d.ts +28 -1
- package/dist/server/prod-server.js +97 -22
- package/dist/server/prod-server.js.map +1 -1
- package/dist/server/request-log.js.map +1 -1
- package/dist/server/request-pipeline.d.ts +1 -13
- package/dist/server/request-pipeline.js +3 -25
- package/dist/server/request-pipeline.js.map +1 -1
- package/dist/server/rsc-stream-hints.js.map +1 -1
- package/dist/server/seed-cache.js.map +1 -1
- package/dist/server/server-action-not-found.d.ts +16 -3
- package/dist/server/server-action-not-found.js +22 -4
- package/dist/server/server-action-not-found.js.map +1 -1
- package/dist/server/server-globals.d.ts +5 -0
- package/dist/server/server-globals.js +37 -0
- package/dist/server/server-globals.js.map +1 -0
- package/dist/server/socket-error-backstop.js.map +1 -1
- package/dist/server/static-file-cache.js +1 -1
- package/dist/server/static-file-cache.js.map +1 -1
- package/dist/server/worker-utils.d.ts +0 -7
- package/dist/server/worker-utils.js +3 -2
- package/dist/server/worker-utils.js.map +1 -1
- package/dist/shims/amp.js.map +1 -1
- package/dist/shims/app.d.ts +37 -4
- package/dist/shims/app.js +50 -1
- package/dist/shims/app.js.map +1 -0
- package/dist/shims/cache-for-request.js.map +1 -1
- package/dist/shims/cache-runtime.d.ts +19 -2
- package/dist/shims/cache-runtime.js +87 -19
- package/dist/shims/cache-runtime.js.map +1 -1
- package/dist/shims/cache.d.ts +20 -21
- package/dist/shims/cache.js +101 -15
- package/dist/shims/cache.js.map +1 -1
- package/dist/shims/client-hook-error.js.map +1 -1
- package/dist/shims/compat-router.js.map +1 -1
- package/dist/shims/config.js.map +1 -1
- package/dist/shims/constants.js.map +1 -1
- package/dist/shims/document.js.map +1 -1
- package/dist/shims/dynamic.d.ts +18 -10
- package/dist/shims/dynamic.js +107 -51
- package/dist/shims/dynamic.js.map +1 -1
- package/dist/shims/error-boundary.d.ts +35 -6
- package/dist/shims/error-boundary.js +116 -33
- package/dist/shims/error-boundary.js.map +1 -1
- package/dist/shims/error.d.ts +18 -1
- package/dist/shims/error.js +56 -1
- package/dist/shims/error.js.map +1 -1
- package/dist/shims/fetch-cache.d.ts +25 -1
- package/dist/shims/fetch-cache.js +159 -13
- package/dist/shims/fetch-cache.js.map +1 -1
- package/dist/shims/font-google-base.d.ts +22 -8
- package/dist/shims/font-google-base.js +41 -71
- package/dist/shims/font-google-base.js.map +1 -1
- package/dist/shims/font-local.d.ts +3 -20
- package/dist/shims/font-local.js +23 -75
- package/dist/shims/font-local.js.map +1 -1
- package/dist/shims/font-utils.d.ts +51 -0
- package/dist/shims/font-utils.js +97 -0
- package/dist/shims/font-utils.js.map +1 -0
- package/dist/shims/form.js +3 -1
- package/dist/shims/form.js.map +1 -1
- package/dist/shims/hash-scroll.d.ts +7 -0
- package/dist/shims/hash-scroll.js +30 -0
- package/dist/shims/hash-scroll.js.map +1 -0
- package/dist/shims/head-state.js.map +1 -1
- package/dist/shims/head.d.ts +3 -1
- package/dist/shims/head.js +28 -16
- package/dist/shims/head.js.map +1 -1
- package/dist/shims/headers.d.ts +11 -12
- package/dist/shims/headers.js +45 -8
- package/dist/shims/headers.js.map +1 -1
- package/dist/shims/i18n-context.js.map +1 -1
- package/dist/shims/i18n-state.js.map +1 -1
- package/dist/shims/image-config.d.ts +14 -1
- package/dist/shims/image-config.js +24 -1
- package/dist/shims/image-config.js.map +1 -1
- package/dist/shims/image.d.ts +1 -0
- package/dist/shims/image.js +159 -80
- package/dist/shims/image.js.map +1 -1
- package/dist/shims/internal/als-registry.js.map +1 -1
- package/dist/shims/internal/app-router-context.d.ts +7 -6
- package/dist/shims/internal/app-router-context.js +17 -6
- package/dist/shims/internal/app-router-context.js.map +1 -1
- package/dist/shims/internal/cookie-serialize.js.map +1 -1
- package/dist/shims/internal/make-hanging-promise.d.ts +1 -1
- package/dist/shims/internal/make-hanging-promise.js +1 -1
- package/dist/shims/internal/make-hanging-promise.js.map +1 -1
- package/dist/shims/internal/parse-cookie-header.js.map +1 -1
- package/dist/shims/internal/utils.js.map +1 -1
- package/dist/shims/internal/work-unit-async-storage.js +2 -2
- package/dist/shims/internal/work-unit-async-storage.js.map +1 -1
- package/dist/shims/layout-segment-context.js.map +1 -1
- package/dist/shims/legacy-image.js.map +1 -1
- package/dist/shims/link-prefetch.d.ts +42 -0
- package/dist/shims/link-prefetch.js +45 -0
- package/dist/shims/link-prefetch.js.map +1 -0
- package/dist/shims/link.d.ts +37 -4
- package/dist/shims/link.js +156 -46
- package/dist/shims/link.js.map +1 -1
- package/dist/shims/metadata.d.ts +16 -30
- package/dist/shims/metadata.js +87 -28
- package/dist/shims/metadata.js.map +1 -1
- package/dist/shims/navigation-state.js.map +1 -1
- package/dist/shims/navigation.d.ts +172 -10
- package/dist/shims/navigation.js +335 -70
- package/dist/shims/navigation.js.map +1 -1
- package/dist/shims/navigation.react-server.d.ts +3 -2
- package/dist/shims/navigation.react-server.js +5 -2
- package/dist/shims/navigation.react-server.js.map +1 -1
- package/dist/shims/offline.js.map +1 -1
- package/dist/shims/pages-router-runtime.d.ts +7 -0
- package/dist/shims/pages-router-runtime.js +16 -0
- package/dist/shims/pages-router-runtime.js.map +1 -0
- package/dist/shims/readonly-url-search-params.js.map +1 -1
- package/dist/shims/request-context.js.map +1 -1
- package/dist/shims/root-params.js.map +1 -1
- package/dist/shims/router-state.js.map +1 -1
- package/dist/shims/router.d.ts +69 -7
- package/dist/shims/router.js +232 -249
- package/dist/shims/router.js.map +1 -1
- package/dist/shims/script-nonce-context.js.map +1 -1
- package/dist/shims/script.js +110 -32
- package/dist/shims/script.js.map +1 -1
- package/dist/shims/server.js +12 -15
- package/dist/shims/server.js.map +1 -1
- package/dist/shims/slot.d.ts +7 -1
- package/dist/shims/slot.js +60 -7
- package/dist/shims/slot.js.map +1 -1
- package/dist/shims/thenable-params.js.map +1 -1
- package/dist/shims/unified-request-context.js +5 -0
- package/dist/shims/unified-request-context.js.map +1 -1
- package/dist/shims/unrecognized-action-error.d.ts +35 -0
- package/dist/shims/unrecognized-action-error.js +41 -0
- package/dist/shims/unrecognized-action-error.js.map +1 -0
- package/dist/shims/url-safety.js.map +1 -1
- package/dist/shims/url-utils.d.ts +22 -1
- package/dist/shims/url-utils.js +76 -3
- package/dist/shims/url-utils.js.map +1 -1
- package/dist/shims/use-merged-ref.js.map +1 -1
- package/dist/shims/web-vitals.d.ts +4 -21
- package/dist/shims/web-vitals.js +19 -6
- package/dist/shims/web-vitals.js.map +1 -1
- package/dist/utils/asset-prefix.d.ts +69 -0
- package/dist/utils/asset-prefix.js +91 -0
- package/dist/utils/asset-prefix.js.map +1 -0
- package/dist/utils/base-path.d.ts +7 -1
- package/dist/utils/base-path.js +10 -1
- package/dist/utils/base-path.js.map +1 -1
- package/dist/utils/cache-control-metadata.js.map +1 -1
- package/dist/utils/domain-locale.js.map +1 -1
- package/dist/utils/encode-cache-tag.d.ts +31 -0
- package/dist/utils/encode-cache-tag.js +38 -0
- package/dist/utils/encode-cache-tag.js.map +1 -0
- package/dist/utils/error-cause.js.map +1 -1
- package/dist/utils/hash.js.map +1 -1
- package/dist/utils/lazy-chunks.js.map +1 -1
- package/dist/utils/manifest-paths.js.map +1 -1
- package/dist/utils/mdx-scan.js.map +1 -1
- package/dist/utils/navigation-signal.d.ts +5 -0
- package/dist/utils/navigation-signal.js +14 -0
- package/dist/utils/navigation-signal.js.map +1 -0
- package/dist/utils/project.js.map +1 -1
- package/dist/utils/public-routes.js.map +1 -1
- package/dist/utils/query.js.map +1 -1
- package/dist/utils/safe-json-file.js.map +1 -1
- package/dist/utils/sorted-array.d.ts +9 -0
- package/dist/utils/sorted-array.js +22 -0
- package/dist/utils/sorted-array.js.map +1 -0
- package/dist/utils/text-stream.js.map +1 -1
- package/dist/utils/vinext-root.js.map +1 -1
- package/package.json +8 -6
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { NEXT_ROUTER_PREFETCH_HEADER, NEXT_ROUTER_SEGMENT_PREFETCH_HEADER, NEXT_ROUTER_STATE_TREE_HEADER, NEXT_URL_HEADER, VINEXT_INTERCEPTION_CONTEXT_HEADER, VINEXT_MOUNTED_SLOTS_HEADER, VINEXT_RSC_RENDER_MODE_HEADER } from "./headers.js";
|
|
1
2
|
import { fnv1a64 } from "../utils/hash.js";
|
|
3
|
+
import { parseAppRscRenderMode } from "./app-rsc-render-mode.js";
|
|
2
4
|
//#region src/server/app-rsc-cache-busting.ts
|
|
3
5
|
/**
|
|
4
6
|
* RSC cache-busting hashes cover the headers that make a `.rsc` payload vary.
|
|
@@ -7,23 +9,18 @@ import { fnv1a64 } from "../utils/hash.js";
|
|
|
7
9
|
* repeated canonicalization redirects.
|
|
8
10
|
*/
|
|
9
11
|
const VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM = "_rsc";
|
|
12
|
+
const VINEXT_RSC_COMPATIBILITY_ID_HEADER = "X-Vinext-RSC-Compatibility-Id";
|
|
10
13
|
const VINEXT_RSC_CONTENT_TYPE = "text/x-component";
|
|
11
|
-
const VINEXT_RSC_MOUNTED_SLOTS_HEADER = "X-Vinext-Mounted-Slots";
|
|
12
|
-
const VINEXT_RSC_HEADER = "RSC";
|
|
13
|
-
const VINEXT_RSC_INTERCEPTION_CONTEXT_HEADER = "X-Vinext-Interception-Context";
|
|
14
|
-
const NEXT_ROUTER_STATE_TREE_HEADER = "Next-Router-State-Tree";
|
|
15
|
-
const NEXT_ROUTER_PREFETCH_HEADER = "Next-Router-Prefetch";
|
|
16
|
-
const NEXT_ROUTER_SEGMENT_PREFETCH_HEADER = "Next-Router-Segment-Prefetch";
|
|
17
|
-
const NEXT_URL_HEADER = "Next-Url";
|
|
18
14
|
const VINEXT_RSC_VARY_HEADER = [
|
|
19
|
-
|
|
15
|
+
"RSC",
|
|
20
16
|
"Accept",
|
|
21
17
|
NEXT_ROUTER_STATE_TREE_HEADER,
|
|
22
18
|
NEXT_ROUTER_PREFETCH_HEADER,
|
|
23
19
|
NEXT_ROUTER_SEGMENT_PREFETCH_HEADER,
|
|
24
20
|
NEXT_URL_HEADER,
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
VINEXT_INTERCEPTION_CONTEXT_HEADER,
|
|
22
|
+
VINEXT_MOUNTED_SLOTS_HEADER,
|
|
23
|
+
VINEXT_RSC_RENDER_MODE_HEADER
|
|
27
24
|
].join(", ");
|
|
28
25
|
const CACHE_BUSTING_DIGEST_BYTES = 12;
|
|
29
26
|
const textEncoder = new TextEncoder();
|
|
@@ -35,14 +32,53 @@ function encodeBase64Url(bytes) {
|
|
|
35
32
|
function normalizeHeaderValue(value) {
|
|
36
33
|
return value ?? "0";
|
|
37
34
|
}
|
|
38
|
-
function
|
|
35
|
+
function normalizeCompatibilityId(value) {
|
|
36
|
+
return value && value.length > 0 ? value : null;
|
|
37
|
+
}
|
|
38
|
+
function getVinextRscCompatibilityId() {
|
|
39
|
+
return normalizeCompatibilityId(process.env.__VINEXT_RSC_COMPATIBILITY_ID);
|
|
40
|
+
}
|
|
41
|
+
function applyRscCompatibilityIdHeader(headers, compatibilityId = getVinextRscCompatibilityId()) {
|
|
42
|
+
const normalized = normalizeCompatibilityId(compatibilityId);
|
|
43
|
+
if (normalized) headers.set(VINEXT_RSC_COMPATIBILITY_ID_HEADER, normalized);
|
|
44
|
+
else headers.delete(VINEXT_RSC_COMPATIBILITY_ID_HEADER);
|
|
45
|
+
}
|
|
46
|
+
function isRscCompatibilityIdCompatible(responseCompatibilityId, clientCompatibilityId = getVinextRscCompatibilityId()) {
|
|
47
|
+
const normalizedResponseCompatibilityId = normalizeCompatibilityId(responseCompatibilityId);
|
|
48
|
+
const normalizedClientCompatibilityId = normalizeCompatibilityId(clientCompatibilityId);
|
|
49
|
+
return normalizedClientCompatibilityId === null || normalizedResponseCompatibilityId !== null && normalizedResponseCompatibilityId === normalizedClientCompatibilityId;
|
|
50
|
+
}
|
|
51
|
+
function resolveHardNavigationTargetFromRscResponse(responseUrl, currentHref, origin) {
|
|
52
|
+
if (!responseUrl) return currentHref;
|
|
53
|
+
const parsed = new URL(responseUrl, origin);
|
|
54
|
+
stripRscCacheBustingSearchParam(parsed);
|
|
55
|
+
const origUrl = new URL(currentHref, origin);
|
|
56
|
+
let pathname = stripRscSuffix(parsed.pathname);
|
|
57
|
+
if (origUrl.pathname.length > 1 && origUrl.pathname.endsWith("/") && !pathname.endsWith("/")) pathname += "/";
|
|
58
|
+
let hardNavigationTarget = pathname + parsed.search;
|
|
59
|
+
if (origUrl.hash) hardNavigationTarget += origUrl.hash;
|
|
60
|
+
return hardNavigationTarget;
|
|
61
|
+
}
|
|
62
|
+
function resolveRscCompatibilityNavigationDecision(options) {
|
|
63
|
+
if (isRscCompatibilityIdCompatible(options.responseCompatibilityId, options.clientCompatibilityId)) return { kind: "compatible" };
|
|
64
|
+
return {
|
|
65
|
+
hardNavigationTarget: resolveHardNavigationTargetFromRscResponse(options.responseUrl, options.currentHref, options.origin),
|
|
66
|
+
kind: "hard-navigate"
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function normalizeRenderModeHeaderValue(value) {
|
|
70
|
+
const renderMode = parseAppRscRenderMode(value);
|
|
71
|
+
return renderMode === "navigation" ? null : renderMode;
|
|
72
|
+
}
|
|
73
|
+
function createCacheBustingInput(headers, options = {}) {
|
|
39
74
|
const values = [
|
|
40
75
|
headers.get(NEXT_ROUTER_PREFETCH_HEADER),
|
|
41
76
|
headers.get(NEXT_ROUTER_SEGMENT_PREFETCH_HEADER),
|
|
42
77
|
headers.get(NEXT_ROUTER_STATE_TREE_HEADER),
|
|
43
78
|
headers.get(NEXT_URL_HEADER),
|
|
44
|
-
headers.get(
|
|
45
|
-
headers.get(
|
|
79
|
+
headers.get(VINEXT_INTERCEPTION_CONTEXT_HEADER),
|
|
80
|
+
headers.get(VINEXT_MOUNTED_SLOTS_HEADER),
|
|
81
|
+
...options.includeRenderModeHeader === false ? [] : [normalizeRenderModeHeaderValue(headers.get(VINEXT_RSC_RENDER_MODE_HEADER))]
|
|
46
82
|
];
|
|
47
83
|
if (values.every((value) => value === null)) return null;
|
|
48
84
|
return values.map(normalizeHeaderValue).join(",");
|
|
@@ -55,6 +91,15 @@ function computeLegacyRscCacheBustingSearchParam(headers) {
|
|
|
55
91
|
const input = createCacheBustingInput(headers);
|
|
56
92
|
return input === null ? "" : fnv1a64(input);
|
|
57
93
|
}
|
|
94
|
+
async function computePreviousRscCacheBustingSearchParam(headers) {
|
|
95
|
+
const input = createCacheBustingInput(headers, { includeRenderModeHeader: false });
|
|
96
|
+
if (input === null) return null;
|
|
97
|
+
return sha256CacheBustingHash(input);
|
|
98
|
+
}
|
|
99
|
+
function computePreviousLegacyRscCacheBustingSearchParam(headers) {
|
|
100
|
+
const input = createCacheBustingInput(headers, { includeRenderModeHeader: false });
|
|
101
|
+
return input === null ? null : fnv1a64(input);
|
|
102
|
+
}
|
|
58
103
|
function getSearchPairsWithoutRscCacheBusting(url) {
|
|
59
104
|
return (url.search.startsWith("?") ? url.search.slice(1) : url.search).split("&").filter((pair) => pair.length > 0 && !isRscCacheBustingSearchPair(pair));
|
|
60
105
|
}
|
|
@@ -91,10 +136,12 @@ function stripRscSuffix(pathname) {
|
|
|
91
136
|
function createRscRequestHeaders(options = {}) {
|
|
92
137
|
const headers = new Headers({
|
|
93
138
|
Accept: VINEXT_RSC_CONTENT_TYPE,
|
|
94
|
-
[
|
|
139
|
+
["RSC"]: "1"
|
|
95
140
|
});
|
|
96
|
-
if (options.interceptionContext !== void 0 && options.interceptionContext !== null) headers.set(
|
|
97
|
-
if (options.mountedSlotsHeader !== void 0 && options.mountedSlotsHeader !== null) headers.set(
|
|
141
|
+
if (options.interceptionContext !== void 0 && options.interceptionContext !== null) headers.set(VINEXT_INTERCEPTION_CONTEXT_HEADER, options.interceptionContext);
|
|
142
|
+
if (options.mountedSlotsHeader !== void 0 && options.mountedSlotsHeader !== null) headers.set(VINEXT_MOUNTED_SLOTS_HEADER, options.mountedSlotsHeader);
|
|
143
|
+
const renderMode = options.renderMode ?? "navigation";
|
|
144
|
+
if (renderMode !== "navigation") headers.set(VINEXT_RSC_RENDER_MODE_HEADER, renderMode);
|
|
98
145
|
return headers;
|
|
99
146
|
}
|
|
100
147
|
function toRscRequestPath(href) {
|
|
@@ -123,8 +170,17 @@ async function resolveInvalidRscCacheBustingRequest(options) {
|
|
|
123
170
|
const actualHash = url.searchParams.get(VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM);
|
|
124
171
|
const expectedHash = await computeRscCacheBustingSearchParam(options.request.headers);
|
|
125
172
|
if (actualHash === null && expectedHash === "") return null;
|
|
126
|
-
const
|
|
127
|
-
if (actualHash
|
|
173
|
+
const acceptedHashes = new Set([expectedHash]);
|
|
174
|
+
if (actualHash !== null && actualHash !== expectedHash) {
|
|
175
|
+
acceptedHashes.add(computeLegacyRscCacheBustingSearchParam(options.request.headers));
|
|
176
|
+
if (normalizeRenderModeHeaderValue(options.request.headers.get("X-Vinext-Rsc-Render-Mode")) === null) {
|
|
177
|
+
const previousHash = await computePreviousRscCacheBustingSearchParam(options.request.headers);
|
|
178
|
+
const previousLegacyHash = computePreviousLegacyRscCacheBustingSearchParam(options.request.headers);
|
|
179
|
+
if (previousHash !== null) acceptedHashes.add(previousHash);
|
|
180
|
+
if (previousLegacyHash !== null) acceptedHashes.add(previousLegacyHash);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
if (actualHash !== null && acceptedHashes.has(actualHash)) return null;
|
|
128
184
|
setRscCacheBustingSearchParam(url, expectedHash);
|
|
129
185
|
return new Response(null, {
|
|
130
186
|
status: 307,
|
|
@@ -132,6 +188,6 @@ async function resolveInvalidRscCacheBustingRequest(options) {
|
|
|
132
188
|
});
|
|
133
189
|
}
|
|
134
190
|
//#endregion
|
|
135
|
-
export { VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM, VINEXT_RSC_CONTENT_TYPE,
|
|
191
|
+
export { VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM, VINEXT_RSC_COMPATIBILITY_ID_HEADER, VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_RENDER_MODE_HEADER, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader, computeRscCacheBustingSearchParam, createRscRedirectLocation, createRscRequestHeaders, createRscRequestUrl, getVinextRscCompatibilityId, isRscCompatibilityIdCompatible, resolveHardNavigationTargetFromRscResponse, resolveInvalidRscCacheBustingRequest, resolveRscCompatibilityNavigationDecision, setRscCacheBustingSearchParam, stripRscCacheBustingSearchParam, stripRscSuffix };
|
|
136
192
|
|
|
137
193
|
//# sourceMappingURL=app-rsc-cache-busting.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-rsc-cache-busting.js","names":[],"sources":["../../src/server/app-rsc-cache-busting.ts"],"sourcesContent":["import { fnv1a64 } from \"../utils/hash.js\";\n\n/**\n * RSC cache-busting hashes cover the headers that make a `.rsc` payload vary.\n * Client-side variant headers must survive transit through CDNs and reverse\n * proxies; stripping them changes the server hash and turns stale URLs into\n * repeated canonicalization redirects.\n */\nexport const VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM = \"_rsc\";\nexport const VINEXT_RSC_CONTENT_TYPE = \"text/x-component\";\nexport const VINEXT_RSC_MOUNTED_SLOTS_HEADER = \"X-Vinext-Mounted-Slots\";\n\nconst VINEXT_RSC_HEADER = \"RSC\";\nconst VINEXT_RSC_INTERCEPTION_CONTEXT_HEADER = \"X-Vinext-Interception-Context\";\nconst NEXT_ROUTER_STATE_TREE_HEADER = \"Next-Router-State-Tree\";\nconst NEXT_ROUTER_PREFETCH_HEADER = \"Next-Router-Prefetch\";\nconst NEXT_ROUTER_SEGMENT_PREFETCH_HEADER = \"Next-Router-Segment-Prefetch\";\nconst NEXT_URL_HEADER = \"Next-Url\";\n\nexport const VINEXT_RSC_VARY_HEADER = [\n VINEXT_RSC_HEADER,\n \"Accept\",\n NEXT_ROUTER_STATE_TREE_HEADER,\n NEXT_ROUTER_PREFETCH_HEADER,\n NEXT_ROUTER_SEGMENT_PREFETCH_HEADER,\n NEXT_URL_HEADER,\n VINEXT_RSC_INTERCEPTION_CONTEXT_HEADER,\n VINEXT_RSC_MOUNTED_SLOTS_HEADER,\n].join(\", \");\n\nconst CACHE_BUSTING_DIGEST_BYTES = 12;\nconst textEncoder = new TextEncoder();\n\ntype CreateRscRequestHeadersOptions = {\n interceptionContext?: string | null;\n mountedSlotsHeader?: string | null;\n};\n\ntype ResolveInvalidRscCacheBustingRequestOptions = {\n isRscRequest: boolean;\n request: Request;\n};\n\nfunction encodeBase64Url(bytes: Uint8Array): string {\n let binary = \"\";\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n\n return btoa(binary).replaceAll(\"+\", \"-\").replaceAll(\"/\", \"_\").replace(/=+$/, \"\");\n}\n\nfunction normalizeHeaderValue(value: string | null): string {\n return value ?? \"0\";\n}\n\nfunction createCacheBustingInput(headers: Headers): string | null {\n // The order of these values determines the hash. Changing it is a breaking\n // cache-key change and requires accepting the previous hash during rollout.\n const values = [\n headers.get(NEXT_ROUTER_PREFETCH_HEADER),\n headers.get(NEXT_ROUTER_SEGMENT_PREFETCH_HEADER),\n headers.get(NEXT_ROUTER_STATE_TREE_HEADER),\n headers.get(NEXT_URL_HEADER),\n headers.get(VINEXT_RSC_INTERCEPTION_CONTEXT_HEADER),\n headers.get(VINEXT_RSC_MOUNTED_SLOTS_HEADER),\n ];\n\n if (values.every((value) => value === null)) {\n return null;\n }\n\n return values.map(normalizeHeaderValue).join(\",\");\n}\n\nasync function sha256CacheBustingHash(input: string): Promise<string> {\n const digest = await globalThis.crypto.subtle.digest(\"SHA-256\", textEncoder.encode(input));\n return encodeBase64Url(new Uint8Array(digest).subarray(0, CACHE_BUSTING_DIGEST_BYTES));\n}\n\nfunction computeLegacyRscCacheBustingSearchParam(headers: Headers): string {\n const input = createCacheBustingInput(headers);\n return input === null ? \"\" : fnv1a64(input);\n}\n\nfunction getSearchPairsWithoutRscCacheBusting(url: URL): string[] {\n const rawQuery = url.search.startsWith(\"?\") ? url.search.slice(1) : url.search;\n return rawQuery\n .split(\"&\")\n .filter((pair) => pair.length > 0 && !isRscCacheBustingSearchPair(pair));\n}\n\nfunction isRscCacheBustingSearchPair(pair: string): boolean {\n const separatorIndex = pair.indexOf(\"=\");\n const rawKey = separatorIndex === -1 ? pair : pair.slice(0, separatorIndex);\n\n try {\n return (\n decodeURIComponent(rawKey.replaceAll(\"+\", \" \")) === VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM\n );\n } catch {\n return rawKey === VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM;\n }\n}\n\nexport async function computeRscCacheBustingSearchParam(headers: Headers): Promise<string> {\n const input = createCacheBustingInput(headers);\n if (input === null) {\n return \"\";\n }\n\n return sha256CacheBustingHash(input);\n}\n\nexport function setRscCacheBustingSearchParam(url: URL, hash: string): void {\n const pairs = getSearchPairsWithoutRscCacheBusting(url);\n\n pairs.push(\n hash.length > 0\n ? `${VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM}=${hash}`\n : VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM,\n );\n url.search = `?${pairs.join(\"&\")}`;\n}\n\nexport function stripRscCacheBustingSearchParam(url: URL): void {\n const pairs = getSearchPairsWithoutRscCacheBusting(url);\n url.search = pairs.length > 0 ? `?${pairs.join(\"&\")}` : \"\";\n}\n\n/**\n * Remove a trailing `.rsc` suffix from a pathname. Returns the pathname\n * unchanged when the suffix is absent.\n */\nexport function stripRscSuffix(pathname: string): string {\n return pathname.endsWith(\".rsc\") ? pathname.slice(0, -4) : pathname;\n}\n\nexport function createRscRequestHeaders(options: CreateRscRequestHeadersOptions = {}): Headers {\n const headers = new Headers({\n Accept: VINEXT_RSC_CONTENT_TYPE,\n [VINEXT_RSC_HEADER]: \"1\",\n });\n\n if (options.interceptionContext !== undefined && options.interceptionContext !== null) {\n headers.set(VINEXT_RSC_INTERCEPTION_CONTEXT_HEADER, options.interceptionContext);\n }\n\n if (options.mountedSlotsHeader !== undefined && options.mountedSlotsHeader !== null) {\n headers.set(VINEXT_RSC_MOUNTED_SLOTS_HEADER, options.mountedSlotsHeader);\n }\n\n return headers;\n}\n\nfunction toRscRequestPath(href: string): string {\n const hashIndex = href.indexOf(\"#\");\n const beforeHash = hashIndex === -1 ? href : href.slice(0, hashIndex);\n const queryIndex = beforeHash.indexOf(\"?\");\n const pathname = queryIndex === -1 ? beforeHash : beforeHash.slice(0, queryIndex);\n const query = queryIndex === -1 ? \"\" : beforeHash.slice(queryIndex);\n const normalizedPath =\n pathname.length > 1 && pathname.endsWith(\"/\") ? pathname.slice(0, -1) : pathname;\n return `${normalizedPath}.rsc${query}`;\n}\n\nexport async function createRscRequestUrl(href: string, headers: Headers): Promise<string> {\n const url = new URL(toRscRequestPath(href), \"http://vinext.local\");\n const hash = await computeRscCacheBustingSearchParam(headers);\n setRscCacheBustingSearchParam(url, hash);\n return `${url.pathname}${url.search}`;\n}\n\nexport async function createRscRedirectLocation(\n location: string,\n request: Request,\n): Promise<string> {\n const requestUrl = new URL(request.url);\n const destinationUrl = new URL(location, requestUrl);\n\n if (destinationUrl.origin !== requestUrl.origin) {\n return destinationUrl.toString();\n }\n\n const rscPath = await createRscRequestUrl(\n `${destinationUrl.pathname}${destinationUrl.search}`,\n request.headers,\n );\n return `${destinationUrl.origin}${rscPath}`;\n}\n\nexport async function resolveInvalidRscCacheBustingRequest(\n options: ResolveInvalidRscCacheBustingRequestOptions,\n): Promise<Response | null> {\n if (\n !options.isRscRequest ||\n (options.request.method !== \"GET\" && options.request.method !== \"HEAD\")\n ) {\n return null;\n }\n\n const url = new URL(options.request.url);\n const actualHash = url.searchParams.get(VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM);\n const expectedHash = await computeRscCacheBustingSearchParam(options.request.headers);\n\n if (actualHash === null && expectedHash === \"\") {\n return null;\n }\n\n const legacyHash =\n actualHash !== null && actualHash !== expectedHash\n ? computeLegacyRscCacheBustingSearchParam(options.request.headers)\n : null;\n\n if (actualHash === expectedHash || (legacyHash !== null && actualHash === legacyHash)) {\n return null;\n }\n\n setRscCacheBustingSearchParam(url, expectedHash);\n return new Response(null, {\n status: 307,\n headers: {\n Location: `${url.pathname}${url.search}`,\n },\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"app-rsc-cache-busting.js","names":[],"sources":["../../src/server/app-rsc-cache-busting.ts"],"sourcesContent":["import { fnv1a64 } from \"../utils/hash.js\";\nimport {\n APP_RSC_RENDER_MODE_NAVIGATION,\n parseAppRscRenderMode,\n type AppRscRenderMode,\n} from \"./app-rsc-render-mode.js\";\nimport {\n NEXT_ROUTER_PREFETCH_HEADER,\n NEXT_ROUTER_SEGMENT_PREFETCH_HEADER,\n NEXT_ROUTER_STATE_TREE_HEADER,\n NEXT_URL_HEADER,\n RSC_HEADER,\n VINEXT_INTERCEPTION_CONTEXT_HEADER,\n VINEXT_MOUNTED_SLOTS_HEADER,\n VINEXT_RSC_RENDER_MODE_HEADER,\n} from \"./headers.js\";\n\n/**\n * RSC cache-busting hashes cover the headers that make a `.rsc` payload vary.\n * Client-side variant headers must survive transit through CDNs and reverse\n * proxies; stripping them changes the server hash and turns stale URLs into\n * repeated canonicalization redirects.\n */\nexport const VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM = \"_rsc\";\nexport const VINEXT_RSC_COMPATIBILITY_ID_HEADER = \"X-Vinext-RSC-Compatibility-Id\";\nexport const VINEXT_RSC_CONTENT_TYPE = \"text/x-component\";\n\n// Re-export so existing consumers that import from this module keep working.\nexport { VINEXT_RSC_RENDER_MODE_HEADER } from \"./headers.js\";\n\nexport const VINEXT_RSC_VARY_HEADER = [\n RSC_HEADER,\n \"Accept\",\n NEXT_ROUTER_STATE_TREE_HEADER,\n NEXT_ROUTER_PREFETCH_HEADER,\n NEXT_ROUTER_SEGMENT_PREFETCH_HEADER,\n NEXT_URL_HEADER,\n VINEXT_INTERCEPTION_CONTEXT_HEADER,\n VINEXT_MOUNTED_SLOTS_HEADER,\n VINEXT_RSC_RENDER_MODE_HEADER,\n].join(\", \");\n\nconst CACHE_BUSTING_DIGEST_BYTES = 12;\nconst textEncoder = new TextEncoder();\n\ntype CreateRscRequestHeadersOptions = {\n interceptionContext?: string | null;\n mountedSlotsHeader?: string | null;\n renderMode?: AppRscRenderMode;\n};\n\ntype ResolveInvalidRscCacheBustingRequestOptions = {\n isRscRequest: boolean;\n request: Request;\n};\n\nfunction encodeBase64Url(bytes: Uint8Array): string {\n let binary = \"\";\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n\n return btoa(binary).replaceAll(\"+\", \"-\").replaceAll(\"/\", \"_\").replace(/=+$/, \"\");\n}\n\nfunction normalizeHeaderValue(value: string | null): string {\n return value ?? \"0\";\n}\n\nfunction normalizeCompatibilityId(value: string | null | undefined): string | null {\n return value && value.length > 0 ? value : null;\n}\n\nexport function getVinextRscCompatibilityId(): string | null {\n return normalizeCompatibilityId(process.env.__VINEXT_RSC_COMPATIBILITY_ID);\n}\n\nexport function applyRscCompatibilityIdHeader(\n headers: Headers,\n compatibilityId: string | null | undefined = getVinextRscCompatibilityId(),\n): void {\n const normalized = normalizeCompatibilityId(compatibilityId);\n if (normalized) {\n headers.set(VINEXT_RSC_COMPATIBILITY_ID_HEADER, normalized);\n } else {\n headers.delete(VINEXT_RSC_COMPATIBILITY_ID_HEADER);\n }\n}\n\nexport function isRscCompatibilityIdCompatible(\n responseCompatibilityId: string | null | undefined,\n clientCompatibilityId: string | null | undefined = getVinextRscCompatibilityId(),\n): boolean {\n const normalizedResponseCompatibilityId = normalizeCompatibilityId(responseCompatibilityId);\n const normalizedClientCompatibilityId = normalizeCompatibilityId(clientCompatibilityId);\n return (\n normalizedClientCompatibilityId === null ||\n (normalizedResponseCompatibilityId !== null &&\n normalizedResponseCompatibilityId === normalizedClientCompatibilityId)\n );\n}\n\ntype RscCompatibilityNavigationDecision =\n | { kind: \"compatible\" }\n | { hardNavigationTarget: string; kind: \"hard-navigate\" };\n\nexport function resolveHardNavigationTargetFromRscResponse(\n responseUrl: string | null | undefined,\n currentHref: string,\n origin: string,\n): string {\n if (!responseUrl) {\n return currentHref;\n }\n\n const parsed = new URL(responseUrl, origin);\n stripRscCacheBustingSearchParam(parsed);\n const origUrl = new URL(currentHref, origin);\n let pathname = stripRscSuffix(parsed.pathname);\n if (origUrl.pathname.length > 1 && origUrl.pathname.endsWith(\"/\") && !pathname.endsWith(\"/\")) {\n pathname += \"/\";\n }\n\n let hardNavigationTarget = pathname + parsed.search;\n if (origUrl.hash) hardNavigationTarget += origUrl.hash;\n return hardNavigationTarget;\n}\n\nexport function resolveRscCompatibilityNavigationDecision(options: {\n clientCompatibilityId?: string | null;\n currentHref: string;\n origin: string;\n responseCompatibilityId: string | null | undefined;\n responseUrl?: string | null;\n}): RscCompatibilityNavigationDecision {\n if (\n isRscCompatibilityIdCompatible(options.responseCompatibilityId, options.clientCompatibilityId)\n ) {\n return { kind: \"compatible\" };\n }\n\n return {\n hardNavigationTarget: resolveHardNavigationTargetFromRscResponse(\n options.responseUrl,\n options.currentHref,\n options.origin,\n ),\n kind: \"hard-navigate\",\n };\n}\n\nfunction normalizeRenderModeHeaderValue(value: string | null): string | null {\n const renderMode = parseAppRscRenderMode(value);\n return renderMode === APP_RSC_RENDER_MODE_NAVIGATION ? null : renderMode;\n}\n\ntype CreateCacheBustingInputOptions = {\n includeRenderModeHeader?: boolean;\n};\n\nfunction createCacheBustingInput(\n headers: Headers,\n options: CreateCacheBustingInputOptions = {},\n): string | null {\n // The order of these values determines the hash. Changing it is a breaking\n // cache-key change and requires accepting the previous hash during rollout.\n const values = [\n headers.get(NEXT_ROUTER_PREFETCH_HEADER),\n headers.get(NEXT_ROUTER_SEGMENT_PREFETCH_HEADER),\n headers.get(NEXT_ROUTER_STATE_TREE_HEADER),\n headers.get(NEXT_URL_HEADER),\n headers.get(VINEXT_INTERCEPTION_CONTEXT_HEADER),\n headers.get(VINEXT_MOUNTED_SLOTS_HEADER),\n ...(options.includeRenderModeHeader === false\n ? []\n : [normalizeRenderModeHeaderValue(headers.get(VINEXT_RSC_RENDER_MODE_HEADER))]),\n ];\n\n if (values.every((value) => value === null)) {\n return null;\n }\n\n return values.map(normalizeHeaderValue).join(\",\");\n}\n\nasync function sha256CacheBustingHash(input: string): Promise<string> {\n const digest = await globalThis.crypto.subtle.digest(\"SHA-256\", textEncoder.encode(input));\n return encodeBase64Url(new Uint8Array(digest).subarray(0, CACHE_BUSTING_DIGEST_BYTES));\n}\n\nfunction computeLegacyRscCacheBustingSearchParam(headers: Headers): string {\n const input = createCacheBustingInput(headers);\n return input === null ? \"\" : fnv1a64(input);\n}\n\nasync function computePreviousRscCacheBustingSearchParam(headers: Headers): Promise<string | null> {\n const input = createCacheBustingInput(headers, { includeRenderModeHeader: false });\n if (input === null) {\n return null;\n }\n\n return sha256CacheBustingHash(input);\n}\n\nfunction computePreviousLegacyRscCacheBustingSearchParam(headers: Headers): string | null {\n const input = createCacheBustingInput(headers, { includeRenderModeHeader: false });\n return input === null ? null : fnv1a64(input);\n}\n\nfunction getSearchPairsWithoutRscCacheBusting(url: URL): string[] {\n const rawQuery = url.search.startsWith(\"?\") ? url.search.slice(1) : url.search;\n return rawQuery\n .split(\"&\")\n .filter((pair) => pair.length > 0 && !isRscCacheBustingSearchPair(pair));\n}\n\nfunction isRscCacheBustingSearchPair(pair: string): boolean {\n const separatorIndex = pair.indexOf(\"=\");\n const rawKey = separatorIndex === -1 ? pair : pair.slice(0, separatorIndex);\n\n try {\n return (\n decodeURIComponent(rawKey.replaceAll(\"+\", \" \")) === VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM\n );\n } catch {\n return rawKey === VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM;\n }\n}\n\nexport async function computeRscCacheBustingSearchParam(headers: Headers): Promise<string> {\n const input = createCacheBustingInput(headers);\n if (input === null) {\n return \"\";\n }\n\n return sha256CacheBustingHash(input);\n}\n\nexport function setRscCacheBustingSearchParam(url: URL, hash: string): void {\n const pairs = getSearchPairsWithoutRscCacheBusting(url);\n\n pairs.push(\n hash.length > 0\n ? `${VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM}=${hash}`\n : VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM,\n );\n url.search = `?${pairs.join(\"&\")}`;\n}\n\nexport function stripRscCacheBustingSearchParam(url: URL): void {\n const pairs = getSearchPairsWithoutRscCacheBusting(url);\n url.search = pairs.length > 0 ? `?${pairs.join(\"&\")}` : \"\";\n}\n\n/**\n * Remove a trailing `.rsc` suffix from a pathname. Returns the pathname\n * unchanged when the suffix is absent.\n */\nexport function stripRscSuffix(pathname: string): string {\n return pathname.endsWith(\".rsc\") ? pathname.slice(0, -4) : pathname;\n}\n\nexport function createRscRequestHeaders(options: CreateRscRequestHeadersOptions = {}): Headers {\n const headers = new Headers({\n Accept: VINEXT_RSC_CONTENT_TYPE,\n [RSC_HEADER]: \"1\",\n });\n\n if (options.interceptionContext !== undefined && options.interceptionContext !== null) {\n headers.set(VINEXT_INTERCEPTION_CONTEXT_HEADER, options.interceptionContext);\n }\n\n if (options.mountedSlotsHeader !== undefined && options.mountedSlotsHeader !== null) {\n headers.set(VINEXT_MOUNTED_SLOTS_HEADER, options.mountedSlotsHeader);\n }\n\n const renderMode = options.renderMode ?? APP_RSC_RENDER_MODE_NAVIGATION;\n if (renderMode !== APP_RSC_RENDER_MODE_NAVIGATION) {\n headers.set(VINEXT_RSC_RENDER_MODE_HEADER, renderMode);\n }\n\n return headers;\n}\n\nfunction toRscRequestPath(href: string): string {\n const hashIndex = href.indexOf(\"#\");\n const beforeHash = hashIndex === -1 ? href : href.slice(0, hashIndex);\n const queryIndex = beforeHash.indexOf(\"?\");\n const pathname = queryIndex === -1 ? beforeHash : beforeHash.slice(0, queryIndex);\n const query = queryIndex === -1 ? \"\" : beforeHash.slice(queryIndex);\n const normalizedPath =\n pathname.length > 1 && pathname.endsWith(\"/\") ? pathname.slice(0, -1) : pathname;\n return `${normalizedPath}.rsc${query}`;\n}\n\nexport async function createRscRequestUrl(href: string, headers: Headers): Promise<string> {\n const url = new URL(toRscRequestPath(href), \"http://vinext.local\");\n const hash = await computeRscCacheBustingSearchParam(headers);\n setRscCacheBustingSearchParam(url, hash);\n return `${url.pathname}${url.search}`;\n}\n\nexport async function createRscRedirectLocation(\n location: string,\n request: Request,\n): Promise<string> {\n const requestUrl = new URL(request.url);\n const destinationUrl = new URL(location, requestUrl);\n\n if (destinationUrl.origin !== requestUrl.origin) {\n return destinationUrl.toString();\n }\n\n const rscPath = await createRscRequestUrl(\n `${destinationUrl.pathname}${destinationUrl.search}`,\n request.headers,\n );\n return `${destinationUrl.origin}${rscPath}`;\n}\n\nexport async function resolveInvalidRscCacheBustingRequest(\n options: ResolveInvalidRscCacheBustingRequestOptions,\n): Promise<Response | null> {\n if (\n !options.isRscRequest ||\n (options.request.method !== \"GET\" && options.request.method !== \"HEAD\")\n ) {\n return null;\n }\n\n const url = new URL(options.request.url);\n const actualHash = url.searchParams.get(VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM);\n const expectedHash = await computeRscCacheBustingSearchParam(options.request.headers);\n\n if (actualHash === null && expectedHash === \"\") {\n return null;\n }\n\n const acceptedHashes = new Set<string>([expectedHash]);\n if (actualHash !== null && actualHash !== expectedHash) {\n acceptedHashes.add(computeLegacyRscCacheBustingSearchParam(options.request.headers));\n if (\n normalizeRenderModeHeaderValue(options.request.headers.get(VINEXT_RSC_RENDER_MODE_HEADER)) ===\n null\n ) {\n const previousHash = await computePreviousRscCacheBustingSearchParam(options.request.headers);\n const previousLegacyHash = computePreviousLegacyRscCacheBustingSearchParam(\n options.request.headers,\n );\n if (previousHash !== null) acceptedHashes.add(previousHash);\n if (previousLegacyHash !== null) acceptedHashes.add(previousLegacyHash);\n }\n }\n\n if (actualHash !== null && acceptedHashes.has(actualHash)) {\n return null;\n }\n\n setRscCacheBustingSearchParam(url, expectedHash);\n return new Response(null, {\n status: 307,\n headers: {\n Location: `${url.pathname}${url.search}`,\n },\n });\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
//#region src/server/app-rsc-embedded-chunks.d.ts
|
|
2
|
+
declare const RSC_EMBEDDED_BINARY_CHUNK = 3;
|
|
3
|
+
type RscEmbeddedChunk = string | [typeof RSC_EMBEDDED_BINARY_CHUNK, string];
|
|
4
|
+
declare function bytesToBase64(bytes: Uint8Array): string;
|
|
5
|
+
declare function decodeRscEmbeddedChunk(chunk: RscEmbeddedChunk): Uint8Array;
|
|
6
|
+
declare function concatUint8Arrays(chunks: readonly Uint8Array[]): Uint8Array<ArrayBuffer>;
|
|
7
|
+
//#endregion
|
|
8
|
+
export { RSC_EMBEDDED_BINARY_CHUNK, RscEmbeddedChunk, bytesToBase64, concatUint8Arrays, decodeRscEmbeddedChunk };
|
|
9
|
+
//# sourceMappingURL=app-rsc-embedded-chunks.d.ts.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//#region src/server/app-rsc-embedded-chunks.ts
|
|
2
|
+
const RSC_EMBEDDED_BINARY_CHUNK = 3;
|
|
3
|
+
const BASE64_CHUNK_SIZE = 32768;
|
|
4
|
+
const textEncoder = new TextEncoder();
|
|
5
|
+
function bytesToBase64(bytes) {
|
|
6
|
+
let binary = "";
|
|
7
|
+
for (let offset = 0; offset < bytes.byteLength; offset += BASE64_CHUNK_SIZE) binary += String.fromCharCode(...bytes.subarray(offset, offset + BASE64_CHUNK_SIZE));
|
|
8
|
+
return btoa(binary);
|
|
9
|
+
}
|
|
10
|
+
function base64ToBytes(base64) {
|
|
11
|
+
const binary = atob(base64);
|
|
12
|
+
const bytes = new Uint8Array(binary.length);
|
|
13
|
+
for (let index = 0; index < binary.length; index++) bytes[index] = binary.charCodeAt(index);
|
|
14
|
+
return bytes;
|
|
15
|
+
}
|
|
16
|
+
function decodeRscEmbeddedChunk(chunk) {
|
|
17
|
+
if (typeof chunk === "string") return textEncoder.encode(chunk);
|
|
18
|
+
return base64ToBytes(chunk[1]);
|
|
19
|
+
}
|
|
20
|
+
function concatUint8Arrays(chunks) {
|
|
21
|
+
let totalLength = 0;
|
|
22
|
+
for (const chunk of chunks) totalLength += chunk.byteLength;
|
|
23
|
+
const result = new Uint8Array(totalLength);
|
|
24
|
+
let offset = 0;
|
|
25
|
+
for (const chunk of chunks) {
|
|
26
|
+
result.set(chunk, offset);
|
|
27
|
+
offset += chunk.byteLength;
|
|
28
|
+
}
|
|
29
|
+
return result;
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
32
|
+
export { RSC_EMBEDDED_BINARY_CHUNK, bytesToBase64, concatUint8Arrays, decodeRscEmbeddedChunk };
|
|
33
|
+
|
|
34
|
+
//# sourceMappingURL=app-rsc-embedded-chunks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-rsc-embedded-chunks.js","names":[],"sources":["../../src/server/app-rsc-embedded-chunks.ts"],"sourcesContent":["export const RSC_EMBEDDED_BINARY_CHUNK = 3;\n\nexport type RscEmbeddedChunk = string | [typeof RSC_EMBEDDED_BINARY_CHUNK, string];\n\nconst BASE64_CHUNK_SIZE = 0x8000;\nconst textEncoder = new TextEncoder();\n\nexport function bytesToBase64(bytes: Uint8Array): string {\n let binary = \"\";\n for (let offset = 0; offset < bytes.byteLength; offset += BASE64_CHUNK_SIZE) {\n binary += String.fromCharCode(...bytes.subarray(offset, offset + BASE64_CHUNK_SIZE));\n }\n return btoa(binary);\n}\n\nfunction base64ToBytes(base64: string): Uint8Array {\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let index = 0; index < binary.length; index++) {\n bytes[index] = binary.charCodeAt(index);\n }\n return bytes;\n}\n\nexport function decodeRscEmbeddedChunk(chunk: RscEmbeddedChunk): Uint8Array {\n if (typeof chunk === \"string\") {\n return textEncoder.encode(chunk);\n }\n return base64ToBytes(chunk[1]);\n}\n\nexport function concatUint8Arrays(chunks: readonly Uint8Array[]): Uint8Array<ArrayBuffer> {\n let totalLength = 0;\n for (const chunk of chunks) {\n totalLength += chunk.byteLength;\n }\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of chunks) {\n result.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return result;\n}\n"],"mappings":";AAAA,MAAa,4BAA4B;AAIzC,MAAM,oBAAoB;AAC1B,MAAM,cAAc,IAAI,aAAa;AAErC,SAAgB,cAAc,OAA2B;CACvD,IAAI,SAAS;CACb,KAAK,IAAI,SAAS,GAAG,SAAS,MAAM,YAAY,UAAU,mBACxD,UAAU,OAAO,aAAa,GAAG,MAAM,SAAS,QAAQ,SAAS,kBAAkB,CAAC;CAEtF,OAAO,KAAK,OAAO;;AAGrB,SAAS,cAAc,QAA4B;CACjD,MAAM,SAAS,KAAK,OAAO;CAC3B,MAAM,QAAQ,IAAI,WAAW,OAAO,OAAO;CAC3C,KAAK,IAAI,QAAQ,GAAG,QAAQ,OAAO,QAAQ,SACzC,MAAM,SAAS,OAAO,WAAW,MAAM;CAEzC,OAAO;;AAGT,SAAgB,uBAAuB,OAAqC;CAC1E,IAAI,OAAO,UAAU,UACnB,OAAO,YAAY,OAAO,MAAM;CAElC,OAAO,cAAc,MAAM,GAAG;;AAGhC,SAAgB,kBAAkB,QAAwD;CACxF,IAAI,cAAc;CAClB,KAAK,MAAM,SAAS,QAClB,eAAe,MAAM;CAEvB,MAAM,SAAS,IAAI,WAAW,YAAY;CAC1C,IAAI,SAAS;CACb,KAAK,MAAM,SAAS,QAAQ;EAC1B,OAAO,IAAI,OAAO,OAAO;EACzB,UAAU,MAAM;;CAElB,OAAO"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-rsc-error-handler.js","names":[],"sources":["../../src/server/app-rsc-error-handler.ts"],"sourcesContent":["import { createRscOnErrorHandler } from \"./app-rsc-errors.js\";\n\ntype ReportRequestError = (\n error: Error,\n requestInfo: { path: string; method: string; headers: Record<string, string> },\n errorContext: { routerKind: \"App Router\"; routePath: string; routeType: \"render\" },\n) => void;\n\n/**\n * Build a per-request RSC error handler that extracts request metadata from\n * the incoming Web `Request`, wires it into a `createRscOnErrorHandler` call,\n * and binds the configured `reportRequestError` reporter.\n *\n * Pure factory: takes all deps explicitly — no closure over module-level state.\n */\nexport function createAppRscOnErrorHandler(\n reportRequestError: ReportRequestError,\n request: Request,\n pathname: string,\n routePath: string,\n): (error: unknown) => string | undefined {\n const requestHeaders: Record<string, string> = Object.fromEntries(request.headers.entries());\n const requestInfo = {\n path: pathname,\n method: request.method,\n headers: requestHeaders,\n };\n const errorContext = {\n routerKind: \"App Router\" as const,\n routePath: routePath || pathname,\n routeType: \"render\" as const,\n };\n return createRscOnErrorHandler({\n errorContext,\n reportRequestError,\n requestInfo,\n });\n}\n"],"mappings":";;;;;;;;;AAeA,SAAgB,2BACd,oBACA,SACA,UACA,WACwC;CACxC,MAAM,iBAAyC,OAAO,YAAY,QAAQ,QAAQ,SAAS,CAAC;CAC5F,MAAM,cAAc;EAClB,MAAM;EACN,QAAQ,QAAQ;EAChB,SAAS;EACV;
|
|
1
|
+
{"version":3,"file":"app-rsc-error-handler.js","names":[],"sources":["../../src/server/app-rsc-error-handler.ts"],"sourcesContent":["import { createRscOnErrorHandler } from \"./app-rsc-errors.js\";\n\ntype ReportRequestError = (\n error: Error,\n requestInfo: { path: string; method: string; headers: Record<string, string> },\n errorContext: { routerKind: \"App Router\"; routePath: string; routeType: \"render\" },\n) => void;\n\n/**\n * Build a per-request RSC error handler that extracts request metadata from\n * the incoming Web `Request`, wires it into a `createRscOnErrorHandler` call,\n * and binds the configured `reportRequestError` reporter.\n *\n * Pure factory: takes all deps explicitly — no closure over module-level state.\n */\nexport function createAppRscOnErrorHandler(\n reportRequestError: ReportRequestError,\n request: Request,\n pathname: string,\n routePath: string,\n): (error: unknown) => string | undefined {\n const requestHeaders: Record<string, string> = Object.fromEntries(request.headers.entries());\n const requestInfo = {\n path: pathname,\n method: request.method,\n headers: requestHeaders,\n };\n const errorContext = {\n routerKind: \"App Router\" as const,\n routePath: routePath || pathname,\n routeType: \"render\" as const,\n };\n return createRscOnErrorHandler({\n errorContext,\n reportRequestError,\n requestInfo,\n });\n}\n"],"mappings":";;;;;;;;;AAeA,SAAgB,2BACd,oBACA,SACA,UACA,WACwC;CACxC,MAAM,iBAAyC,OAAO,YAAY,QAAQ,QAAQ,SAAS,CAAC;CAC5F,MAAM,cAAc;EAClB,MAAM;EACN,QAAQ,QAAQ;EAChB,SAAS;EACV;CAMD,OAAO,wBAAwB;EAC7B,cAAA;GALA,YAAY;GACZ,WAAW,aAAa;GACxB,WAAW;GAGC;EACZ;EACA;EACD,CAAC"}
|
|
@@ -16,6 +16,9 @@ type CreateRscOnErrorHandlerOptions = {
|
|
|
16
16
|
reportRequestError: RscErrorReporter;
|
|
17
17
|
requestInfo: RscRequestInfo | null;
|
|
18
18
|
};
|
|
19
|
+
declare function hasDigest(error: unknown): error is {
|
|
20
|
+
digest: unknown;
|
|
21
|
+
};
|
|
19
22
|
/**
|
|
20
23
|
* djb2 hash matching Next.js's string-hash package for RSC error digests.
|
|
21
24
|
*/
|
|
@@ -23,5 +26,5 @@ declare function errorDigest(input: string): string;
|
|
|
23
26
|
declare function sanitizeErrorForClient(error: unknown, nodeEnv?: string | undefined): unknown;
|
|
24
27
|
declare function createRscOnErrorHandler(options: CreateRscOnErrorHandlerOptions): (error: unknown) => string | undefined;
|
|
25
28
|
//#endregion
|
|
26
|
-
export { createRscOnErrorHandler, errorDigest, sanitizeErrorForClient };
|
|
29
|
+
export { createRscOnErrorHandler, errorDigest, hasDigest, sanitizeErrorForClient };
|
|
27
30
|
//# sourceMappingURL=app-rsc-errors.d.ts.map
|
|
@@ -37,6 +37,6 @@ function createRscOnErrorHandler(options) {
|
|
|
37
37
|
};
|
|
38
38
|
}
|
|
39
39
|
//#endregion
|
|
40
|
-
export { createRscOnErrorHandler, errorDigest, sanitizeErrorForClient };
|
|
40
|
+
export { createRscOnErrorHandler, errorDigest, hasDigest, sanitizeErrorForClient };
|
|
41
41
|
|
|
42
42
|
//# sourceMappingURL=app-rsc-errors.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-rsc-errors.js","names":[],"sources":["../../src/server/app-rsc-errors.ts"],"sourcesContent":["import { resolveAppPageSpecialError } from \"./app-page-execution.js\";\n\ntype DigestError = Error & { digest?: string };\n\ntype RscRequestInfo = {\n path: string;\n method: string;\n headers: Record<string, string>;\n};\n\ntype RscErrorContext = {\n routerKind: \"App Router\";\n routePath: string;\n routeType: \"render\";\n};\n\ntype RscErrorReporter = (\n error: Error,\n requestInfo: RscRequestInfo,\n errorContext: RscErrorContext,\n) => void;\n\ntype CreateRscOnErrorHandlerOptions = {\n errorContext: RscErrorContext | null;\n nodeEnv?: string;\n reportRequestError: RscErrorReporter;\n requestInfo: RscRequestInfo | null;\n};\n\
|
|
1
|
+
{"version":3,"file":"app-rsc-errors.js","names":[],"sources":["../../src/server/app-rsc-errors.ts"],"sourcesContent":["import { resolveAppPageSpecialError } from \"./app-page-execution.js\";\n\ntype DigestError = Error & { digest?: string };\n\ntype RscRequestInfo = {\n path: string;\n method: string;\n headers: Record<string, string>;\n};\n\ntype RscErrorContext = {\n routerKind: \"App Router\";\n routePath: string;\n routeType: \"render\";\n};\n\ntype RscErrorReporter = (\n error: Error,\n requestInfo: RscRequestInfo,\n errorContext: RscErrorContext,\n) => void;\n\ntype CreateRscOnErrorHandlerOptions = {\n errorContext: RscErrorContext | null;\n nodeEnv?: string;\n reportRequestError: RscErrorReporter;\n requestInfo: RscRequestInfo | null;\n};\n\nexport function hasDigest(error: unknown): error is { digest: unknown } {\n return Boolean(error && typeof error === \"object\" && \"digest\" in error);\n}\n\nfunction getThrownValueMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction getThrownValueStack(error: unknown): string {\n return error instanceof Error ? error.stack || \"\" : \"\";\n}\n\n/**\n * djb2 hash matching Next.js's string-hash package for RSC error digests.\n */\nexport function errorDigest(input: string): string {\n let hash = 5381;\n for (let i = input.length - 1; i >= 0; i--) {\n hash = (hash * 33) ^ input.charCodeAt(i);\n }\n return (hash >>> 0).toString();\n}\n\nexport function sanitizeErrorForClient(error: unknown, nodeEnv = process.env.NODE_ENV): unknown {\n if (resolveAppPageSpecialError(error)) {\n return error;\n }\n\n if (nodeEnv !== \"production\") {\n return error;\n }\n\n const sanitized: DigestError = new Error(\n \"An error occurred in the Server Components render. \" +\n \"The specific message is omitted in production builds to avoid leaking sensitive details. \" +\n \"A digest property is included on this error instance which may provide additional details about the nature of the error.\",\n );\n sanitized.digest = errorDigest(getThrownValueMessage(error) + getThrownValueStack(error));\n return sanitized;\n}\n\nexport function createRscOnErrorHandler(\n options: CreateRscOnErrorHandlerOptions,\n): (error: unknown) => string | undefined {\n return (error) => {\n const nodeEnv = options.nodeEnv ?? process.env.NODE_ENV;\n\n if (hasDigest(error)) {\n return String(error.digest);\n }\n\n if (\n nodeEnv !== \"production\" &&\n error instanceof Error &&\n error.message.includes(\n \"Only plain objects, and a few built-ins, can be passed to Client Components\",\n )\n ) {\n console.error(\n \"[vinext] RSC serialization error: a non-plain object was passed from a Server Component to a Client Component.\\n\" +\n \"\\n\" +\n \"Common causes:\\n\" +\n \" * Passing a module namespace (import * as X) directly as a prop.\\n\" +\n \" Unlike Next.js (webpack), Vite produces real ESM module namespace objects\\n\" +\n \" which are not serializable. Fix: pass individual values instead,\\n\" +\n \" e.g. <Comp value={module.value} />\\n\" +\n \" * Passing a class instance (new Foo()) as a prop.\\n\" +\n \" Fix: convert to a plain object, e.g. { id: foo.id, name: foo.name }\\n\" +\n \" * Passing a Date, Map, or Set. Use .toISOString(), [...map.entries()], etc.\\n\" +\n \" * Passing Object.create(null). Use { ...obj } to restore a prototype.\\n\" +\n \"\\n\" +\n \"Original error:\",\n error.message,\n );\n return undefined;\n }\n\n if (options.requestInfo && options.errorContext && error) {\n options.reportRequestError(\n error instanceof Error ? error : new Error(getThrownValueMessage(error)),\n options.requestInfo,\n options.errorContext,\n );\n }\n\n if (nodeEnv === \"production\" && error) {\n return errorDigest(getThrownValueMessage(error) + getThrownValueStack(error));\n }\n\n return undefined;\n };\n}\n"],"mappings":";;AA6BA,SAAgB,UAAU,OAA8C;CACtE,OAAO,QAAQ,SAAS,OAAO,UAAU,YAAY,YAAY,MAAM;;AAGzE,SAAS,sBAAsB,OAAwB;CACrD,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;;AAG/D,SAAS,oBAAoB,OAAwB;CACnD,OAAO,iBAAiB,QAAQ,MAAM,SAAS,KAAK;;;;;AAMtD,SAAgB,YAAY,OAAuB;CACjD,IAAI,OAAO;CACX,KAAK,IAAI,IAAI,MAAM,SAAS,GAAG,KAAK,GAAG,KACrC,OAAQ,OAAO,KAAM,MAAM,WAAW,EAAE;CAE1C,QAAQ,SAAS,GAAG,UAAU;;AAGhC,SAAgB,uBAAuB,OAAgB,UAAU,QAAQ,IAAI,UAAmB;CAC9F,IAAI,2BAA2B,MAAM,EACnC,OAAO;CAGT,IAAI,YAAY,cACd,OAAO;CAGT,MAAM,4BAAyB,IAAI,MACjC,uQAGD;CACD,UAAU,SAAS,YAAY,sBAAsB,MAAM,GAAG,oBAAoB,MAAM,CAAC;CACzF,OAAO;;AAGT,SAAgB,wBACd,SACwC;CACxC,QAAQ,UAAU;EAChB,MAAM,UAAU,QAAQ,WAAW,QAAQ,IAAI;EAE/C,IAAI,UAAU,MAAM,EAClB,OAAO,OAAO,MAAM,OAAO;EAG7B,IACE,YAAY,gBACZ,iBAAiB,SACjB,MAAM,QAAQ,SACZ,8EACD,EACD;GACA,QAAQ,MACN,8qBAaA,MAAM,QACP;GACD;;EAGF,IAAI,QAAQ,eAAe,QAAQ,gBAAgB,OACjD,QAAQ,mBACN,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,sBAAsB,MAAM,CAAC,EACxE,QAAQ,aACR,QAAQ,aACT;EAGH,IAAI,YAAY,gBAAgB,OAC9B,OAAO,YAAY,sBAAsB,MAAM,GAAG,oBAAoB,MAAM,CAAC"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { NextHeader, NextI18nConfig, NextRedirect, NextRewrite } from "../config/next-config.js";
|
|
2
2
|
import { MiddlewareModule } from "./middleware-runtime.js";
|
|
3
3
|
import { AppMiddlewareContext } from "./app-middleware.js";
|
|
4
|
+
import { AppRscRenderMode } from "./app-rsc-render-mode.js";
|
|
4
5
|
import { handleAppPrerenderEndpoint } from "./app-prerender-endpoints.js";
|
|
5
6
|
import { handleMetadataRouteRequest } from "./metadata-route-response.js";
|
|
7
|
+
import { ReactFormState } from "react-dom/client";
|
|
6
8
|
|
|
7
9
|
//#region src/server/app-rsc-handler.d.ts
|
|
8
10
|
type AppPageParams = Record<string, string | string[]>;
|
|
@@ -12,6 +14,7 @@ type StaticParamsMap = Parameters<typeof handleAppPrerenderEndpoint>[1]["staticP
|
|
|
12
14
|
type RootParamNamesMap = Parameters<typeof handleAppPrerenderEndpoint>[1]["rootParamNamesByPattern"];
|
|
13
15
|
type AppRscMiddlewareContext = AppMiddlewareContext;
|
|
14
16
|
type AppRscHandlerRoute = {
|
|
17
|
+
isDynamic: boolean;
|
|
15
18
|
page?: unknown;
|
|
16
19
|
pattern: string;
|
|
17
20
|
rootParamNames?: readonly string[];
|
|
@@ -24,8 +27,12 @@ type AppRscRouteMatch<TRoute> = {
|
|
|
24
27
|
};
|
|
25
28
|
type DispatchMatchedPageOptions<TRoute> = {
|
|
26
29
|
cleanPathname: string;
|
|
30
|
+
formState: ReactFormState | null;
|
|
31
|
+
actionError?: unknown;
|
|
32
|
+
actionFailed?: boolean;
|
|
27
33
|
handlerStart: number;
|
|
28
34
|
interceptionContext: string | null;
|
|
35
|
+
isProgressiveActionRender: boolean;
|
|
29
36
|
isRscRequest: boolean;
|
|
30
37
|
middlewareContext: AppRscMiddlewareContext;
|
|
31
38
|
mountedSlotsHeader: string | null;
|
|
@@ -34,6 +41,7 @@ type DispatchMatchedPageOptions<TRoute> = {
|
|
|
34
41
|
route: TRoute;
|
|
35
42
|
scriptNonce?: string;
|
|
36
43
|
searchParams: URLSearchParams;
|
|
44
|
+
renderMode: AppRscRenderMode;
|
|
37
45
|
};
|
|
38
46
|
type DispatchMatchedRouteHandlerOptions<TRoute> = {
|
|
39
47
|
cleanPathname: string;
|
|
@@ -50,6 +58,15 @@ type HandleProgressiveActionRequestOptions = {
|
|
|
50
58
|
middlewareContext: AppRscMiddlewareContext;
|
|
51
59
|
request: Request;
|
|
52
60
|
};
|
|
61
|
+
type ProgressiveActionFormStateResult = {
|
|
62
|
+
formState: ReactFormState | null;
|
|
63
|
+
kind: "form-state";
|
|
64
|
+
} | {
|
|
65
|
+
actionError: unknown;
|
|
66
|
+
actionFailed: true;
|
|
67
|
+
formState: null;
|
|
68
|
+
kind: "form-state";
|
|
69
|
+
};
|
|
53
70
|
type HandleServerActionRequestOptions = {
|
|
54
71
|
actionId: string | null;
|
|
55
72
|
cleanPathname: string;
|
|
@@ -93,7 +110,7 @@ type CreateAppRscHandlerOptions<TRoute extends AppRscHandlerRoute> = {
|
|
|
93
110
|
dispatchMatchedPage: (options: DispatchMatchedPageOptions<TRoute>) => Promise<Response>;
|
|
94
111
|
dispatchMatchedRouteHandler: (options: DispatchMatchedRouteHandlerOptions<TRoute>) => Promise<Response>;
|
|
95
112
|
ensureInstrumentation?: () => Promise<void>;
|
|
96
|
-
handleProgressiveActionRequest: (options: HandleProgressiveActionRequestOptions) => Promise<Response | null>;
|
|
113
|
+
handleProgressiveActionRequest: (options: HandleProgressiveActionRequestOptions) => Promise<Response | ProgressiveActionFormStateResult | null>;
|
|
97
114
|
handleServerActionRequest: (options: HandleServerActionRequestOptions) => Promise<Response | null>;
|
|
98
115
|
i18nConfig: NextI18nConfig | null;
|
|
99
116
|
isMiddlewareProxy: boolean;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { createRequestContext, runWithRequestContext } from "../shims/unified-request-context.js";
|
|
2
2
|
import { hasBasePath } from "../utils/base-path.js";
|
|
3
3
|
import { getRequestExecutionContext } from "../shims/request-context.js";
|
|
4
|
+
import { VINEXT_MW_CTX_HEADER } from "./headers.js";
|
|
4
5
|
import { isExternalUrl, matchRedirect, matchRewrite, proxyExternalRequest, requestContextFromRequest, sanitizeDestination } from "../config/config-matchers.js";
|
|
5
6
|
import { notFoundResponse } from "./http-error-responses.js";
|
|
6
|
-
import { cloneRequestWithHeaders, filterInternalHeaders, normalizeTrailingSlash, resolvePublicFileRoute, validateImageUrl } from "./request-pipeline.js";
|
|
7
|
+
import { applyConfigHeadersToResponse, cloneRequestWithHeaders, filterInternalHeaders, normalizeTrailingSlash, resolvePublicFileRoute, validateImageUrl } from "./request-pipeline.js";
|
|
7
8
|
import { headersContextFromRequest } from "../shims/headers.js";
|
|
8
9
|
import { ensureFetchPatch, setCurrentFetchSoftTags } from "../shims/fetch-cache.js";
|
|
9
10
|
import { createRscRedirectLocation, resolveInvalidRscCacheBustingRequest, stripRscCacheBustingSearchParam, stripRscSuffix } from "./app-rsc-cache-busting.js";
|
|
@@ -42,6 +43,25 @@ async function applyRewrite(options, cleanPathname) {
|
|
|
42
43
|
}
|
|
43
44
|
return rewritten;
|
|
44
45
|
}
|
|
46
|
+
function applyConfigHeadersToMiddlewareRedirect(response, options) {
|
|
47
|
+
if (response.status < 300 || response.status >= 400) return response;
|
|
48
|
+
if (!options.configHeaders.length) return response;
|
|
49
|
+
const headers = new Headers();
|
|
50
|
+
applyConfigHeadersToResponse(headers, {
|
|
51
|
+
configHeaders: options.configHeaders,
|
|
52
|
+
pathname: options.pathname,
|
|
53
|
+
requestContext: options.requestContext
|
|
54
|
+
});
|
|
55
|
+
if (!headers.entries().next().done) {
|
|
56
|
+
mergeMiddlewareResponseHeaders(headers, response.headers);
|
|
57
|
+
return new Response(response.body, {
|
|
58
|
+
status: response.status,
|
|
59
|
+
statusText: response.statusText,
|
|
60
|
+
headers
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
return response;
|
|
64
|
+
}
|
|
45
65
|
async function handleAppRscRequest(options, request, preMiddlewareRequestContext) {
|
|
46
66
|
const handlerStart = process.env.NODE_ENV !== "production" ? performance.now() : 0;
|
|
47
67
|
if (process.env.NODE_ENV !== "production") {
|
|
@@ -50,7 +70,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
|
|
|
50
70
|
}
|
|
51
71
|
const normalized = normalizeRscRequest(request, options.basePath);
|
|
52
72
|
if (normalized instanceof Response) return normalized;
|
|
53
|
-
const { url, isRscRequest, interceptionContextHeader, mountedSlotsHeader } = normalized;
|
|
73
|
+
const { url, isRscRequest, interceptionContextHeader, mountedSlotsHeader, renderMode } = normalized;
|
|
54
74
|
let { pathname, cleanPathname } = normalized;
|
|
55
75
|
const prerenderEndpointResponse = await handleAppPrerenderEndpoint(request, {
|
|
56
76
|
isPrerenderEnabled() {
|
|
@@ -93,7 +113,11 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
|
|
|
93
113
|
module: options.middlewareModule,
|
|
94
114
|
request
|
|
95
115
|
});
|
|
96
|
-
if (middlewareResult.kind === "response") return middlewareResult.response
|
|
116
|
+
if (middlewareResult.kind === "response") return applyConfigHeadersToMiddlewareRedirect(middlewareResult.response, {
|
|
117
|
+
configHeaders: options.configHeaders,
|
|
118
|
+
pathname: cleanPathname,
|
|
119
|
+
requestContext: preMiddlewareRequestContext
|
|
120
|
+
});
|
|
97
121
|
cleanPathname = middlewareResult.cleanPathname;
|
|
98
122
|
if (middlewareResult.search !== null) url.search = middlewareResult.search;
|
|
99
123
|
}
|
|
@@ -137,14 +161,19 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
|
|
|
137
161
|
});
|
|
138
162
|
const actionId = request.headers.get("x-rsc-action") ?? request.headers.get("next-action");
|
|
139
163
|
const contentType = request.headers.get("content-type") || "";
|
|
140
|
-
const
|
|
164
|
+
const progressiveActionResult = await options.handleProgressiveActionRequest({
|
|
141
165
|
actionId,
|
|
142
166
|
cleanPathname,
|
|
143
167
|
contentType,
|
|
144
168
|
middlewareContext,
|
|
145
169
|
request
|
|
146
170
|
});
|
|
147
|
-
if (
|
|
171
|
+
if (progressiveActionResult instanceof Response) return progressiveActionResult;
|
|
172
|
+
const isProgressiveActionRender = progressiveActionResult?.kind === "form-state";
|
|
173
|
+
const formState = isProgressiveActionRender ? progressiveActionResult.formState : null;
|
|
174
|
+
const failedProgressiveActionResult = isProgressiveActionRender && "actionFailed" in progressiveActionResult ? progressiveActionResult : null;
|
|
175
|
+
const actionFailed = failedProgressiveActionResult !== null;
|
|
176
|
+
const actionError = failedProgressiveActionResult?.actionError;
|
|
148
177
|
const serverActionResponse = await options.handleServerActionRequest({
|
|
149
178
|
actionId,
|
|
150
179
|
cleanPathname,
|
|
@@ -157,15 +186,20 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
|
|
|
157
186
|
searchParams: url.searchParams
|
|
158
187
|
});
|
|
159
188
|
if (serverActionResponse) return serverActionResponse;
|
|
160
|
-
const afterFilesRewrite = await applyRewrite({
|
|
161
|
-
clearRequestContext: options.clearRequestContext,
|
|
162
|
-
request,
|
|
163
|
-
requestContext: postMiddlewareRequestContext,
|
|
164
|
-
rewrites: options.configRewrites.afterFiles
|
|
165
|
-
}, cleanPathname);
|
|
166
|
-
if (afterFilesRewrite instanceof Response) return afterFilesRewrite;
|
|
167
|
-
if (afterFilesRewrite) cleanPathname = afterFilesRewrite;
|
|
168
189
|
let match = options.matchRoute(cleanPathname);
|
|
190
|
+
if (!match || match.route.isDynamic) {
|
|
191
|
+
const afterFilesRewrite = await applyRewrite({
|
|
192
|
+
clearRequestContext: options.clearRequestContext,
|
|
193
|
+
request,
|
|
194
|
+
requestContext: postMiddlewareRequestContext,
|
|
195
|
+
rewrites: options.configRewrites.afterFiles
|
|
196
|
+
}, cleanPathname);
|
|
197
|
+
if (afterFilesRewrite instanceof Response) return afterFilesRewrite;
|
|
198
|
+
if (afterFilesRewrite) {
|
|
199
|
+
cleanPathname = afterFilesRewrite;
|
|
200
|
+
match = options.matchRoute(cleanPathname);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
169
203
|
if (!match) {
|
|
170
204
|
const fallbackRewrite = await applyRewrite({
|
|
171
205
|
clearRequestContext: options.clearRequestContext,
|
|
@@ -223,8 +257,12 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
|
|
|
223
257
|
}
|
|
224
258
|
return options.dispatchMatchedPage({
|
|
225
259
|
cleanPathname,
|
|
260
|
+
formState,
|
|
261
|
+
actionError,
|
|
262
|
+
actionFailed,
|
|
226
263
|
handlerStart,
|
|
227
264
|
interceptionContext: interceptionContextHeader,
|
|
265
|
+
isProgressiveActionRender,
|
|
228
266
|
isRscRequest,
|
|
229
267
|
middlewareContext,
|
|
230
268
|
mountedSlotsHeader,
|
|
@@ -232,15 +270,16 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
|
|
|
232
270
|
request,
|
|
233
271
|
route,
|
|
234
272
|
scriptNonce,
|
|
235
|
-
searchParams: url.searchParams
|
|
273
|
+
searchParams: url.searchParams,
|
|
274
|
+
renderMode
|
|
236
275
|
});
|
|
237
276
|
}
|
|
238
277
|
function createAppRscHandler(options) {
|
|
239
278
|
return async function appRscHandler(rawRequest, ctx) {
|
|
240
279
|
await options.ensureInstrumentation?.();
|
|
241
|
-
const mwCtx = rawRequest.headers.get(
|
|
280
|
+
const mwCtx = rawRequest.headers.get(VINEXT_MW_CTX_HEADER);
|
|
242
281
|
const filteredHeaders = filterInternalHeaders(rawRequest.headers);
|
|
243
|
-
if (mwCtx !== null) filteredHeaders.set(
|
|
282
|
+
if (mwCtx !== null) filteredHeaders.set(VINEXT_MW_CTX_HEADER, mwCtx);
|
|
244
283
|
const request = cloneRequestWithHeaders(rawRequest, filteredHeaders);
|
|
245
284
|
const executionContext = isExecutionContextLike(ctx) ? ctx : getRequestExecutionContext() ?? null;
|
|
246
285
|
return runWithRequestContext(createRequestContext({
|