vinext 0.0.50 → 0.0.52
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/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/precompress.d.ts +13 -2
- package/dist/build/precompress.js +23 -13
- package/dist/build/precompress.js.map +1 -1
- package/dist/build/prerender.d.ts +4 -15
- package/dist/build/prerender.js +83 -53
- 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/check.js +5 -0
- package/dist/check.js.map +1 -1
- package/dist/cli-args.d.ts +1 -0
- package/dist/cli-args.js +5 -0
- package/dist/cli-args.js.map +1 -1
- package/dist/cli.js +99 -3
- package/dist/cli.js.map +1 -1
- package/dist/client/navigation-runtime.d.ts +47 -0
- package/dist/client/navigation-runtime.js +156 -0
- package/dist/client/navigation-runtime.js.map +1 -0
- package/dist/client/pages-router-link-navigation.d.ts +26 -0
- package/dist/client/pages-router-link-navigation.js +14 -0
- package/dist/client/pages-router-link-navigation.js.map +1 -0
- package/dist/client/vinext-next-data.d.ts +12 -2
- package/dist/client/vinext-next-data.js +50 -1
- package/dist/client/vinext-next-data.js.map +1 -0
- package/dist/client/window-next.d.ts +3 -1
- package/dist/client/window-next.js.map +1 -1
- package/dist/cloudflare/kv-cache-handler.js +2 -1
- package/dist/cloudflare/kv-cache-handler.js.map +1 -1
- package/dist/config/config-matchers.d.ts +63 -16
- package/dist/config/config-matchers.js +143 -8
- 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 +107 -5
- package/dist/config/next-config.js +233 -7
- 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 +104 -41
- package/dist/deploy.js.map +1 -1
- package/dist/entries/app-browser-entry.d.ts +2 -2
- package/dist/entries/app-browser-entry.js +34 -3
- 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 +89 -23
- package/dist/entries/app-rsc-entry.js.map +1 -1
- package/dist/entries/app-rsc-manifest.d.ts +10 -0
- package/dist/entries/app-rsc-manifest.js +57 -7
- package/dist/entries/app-rsc-manifest.js.map +1 -1
- package/dist/entries/app-ssr-entry.d.ts +3 -3
- package/dist/entries/app-ssr-entry.js +4 -4
- package/dist/entries/app-ssr-entry.js.map +1 -1
- package/dist/entries/pages-client-entry.js +21 -7
- package/dist/entries/pages-client-entry.js.map +1 -1
- package/dist/entries/pages-server-entry.js +77 -9
- package/dist/entries/pages-server-entry.js.map +1 -1
- package/dist/entries/runtime-entry-module.d.ts +2 -1
- package/dist/entries/runtime-entry-module.js +9 -3
- package/dist/entries/runtime-entry-module.js.map +1 -1
- package/dist/index.js +260 -75
- package/dist/index.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/css-data-url.d.ts +7 -0
- package/dist/plugins/css-data-url.js +81 -0
- package/dist/plugins/css-data-url.js.map +1 -0
- package/dist/plugins/fonts.d.ts +2 -2
- package/dist/plugins/fonts.js +20 -9
- package/dist/plugins/fonts.js.map +1 -1
- package/dist/plugins/middleware-server-only.d.ts +54 -0
- package/dist/plugins/middleware-server-only.js +91 -0
- package/dist/plugins/middleware-server-only.js.map +1 -0
- package/dist/plugins/optimize-imports.js +4 -4
- package/dist/plugins/optimize-imports.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/strip-server-exports.js +5 -8
- package/dist/plugins/strip-server-exports.js.map +1 -1
- package/dist/routing/app-route-graph.d.ts +50 -2
- package/dist/routing/app-route-graph.js +140 -16
- package/dist/routing/app-route-graph.js.map +1 -1
- package/dist/routing/app-router.d.ts +2 -2
- package/dist/routing/app-router.js +2 -2
- package/dist/routing/app-router.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/utils.d.ts +2 -1
- package/dist/routing/utils.js +4 -1
- package/dist/routing/utils.js.map +1 -1
- package/dist/server/api-handler.js +139 -37
- package/dist/server/api-handler.js.map +1 -1
- package/dist/server/app-browser-action-result.d.ts +27 -2
- package/dist/server/app-browser-action-result.js +63 -2
- package/dist/server/app-browser-action-result.js.map +1 -1
- package/dist/server/app-browser-entry.js +493 -195
- package/dist/server/app-browser-entry.js.map +1 -1
- package/dist/server/app-browser-hydration.d.ts +13 -1
- package/dist/server/app-browser-hydration.js +9 -1
- package/dist/server/app-browser-hydration.js.map +1 -1
- package/dist/server/app-browser-interception-context.d.ts +24 -0
- package/dist/server/app-browser-interception-context.js +32 -0
- package/dist/server/app-browser-interception-context.js.map +1 -0
- package/dist/server/app-browser-navigation-controller.d.ts +17 -2
- package/dist/server/app-browser-navigation-controller.js +33 -10
- 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 +29 -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 +28 -7
- package/dist/server/app-browser-state.js +63 -27
- package/dist/server/app-browser-state.js.map +1 -1
- package/dist/server/app-browser-stream.d.ts +9 -17
- package/dist/server/app-browser-stream.js +18 -13
- package/dist/server/app-browser-stream.js.map +1 -1
- package/dist/server/app-browser-visible-commit.d.ts +7 -1
- package/dist/server/app-browser-visible-commit.js +39 -5
- package/dist/server/app-browser-visible-commit.js.map +1 -1
- package/dist/server/app-elements-wire.d.ts +43 -6
- package/dist/server/app-elements-wire.js +189 -7
- package/dist/server/app-elements-wire.js.map +1 -1
- package/dist/server/app-elements.d.ts +3 -2
- package/dist/server/app-elements.js +3 -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 +41 -3
- 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-middleware.d.ts +13 -0
- package/dist/server/app-middleware.js +3 -1
- package/dist/server/app-middleware.js.map +1 -1
- package/dist/server/app-optimistic-routing.d.ts +54 -0
- package/dist/server/app-optimistic-routing.js +200 -0
- package/dist/server/app-optimistic-routing.js.map +1 -0
- package/dist/server/app-page-boundary-render.d.ts +10 -1
- package/dist/server/app-page-boundary-render.js +13 -6
- package/dist/server/app-page-boundary-render.js.map +1 -1
- package/dist/server/app-page-boundary.js +3 -2
- package/dist/server/app-page-boundary.js.map +1 -1
- package/dist/server/app-page-cache.d.ts +26 -1
- package/dist/server/app-page-cache.js +86 -14
- package/dist/server/app-page-cache.js.map +1 -1
- package/dist/server/app-page-dispatch.d.ts +7 -0
- package/dist/server/app-page-dispatch.js +96 -12
- package/dist/server/app-page-dispatch.js.map +1 -1
- package/dist/server/app-page-element-builder.d.ts +7 -0
- package/dist/server/app-page-element-builder.js +34 -5
- package/dist/server/app-page-element-builder.js.map +1 -1
- package/dist/server/app-page-execution.d.ts +28 -1
- package/dist/server/app-page-execution.js +91 -7
- 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 +23 -3
- package/dist/server/app-page-head.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 +7 -1
- package/dist/server/app-page-render.js +81 -4
- 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.map +1 -1
- package/dist/server/app-page-response.js +7 -5
- package/dist/server/app-page-response.js.map +1 -1
- package/dist/server/app-page-route-wiring.d.ts +3 -1
- package/dist/server/app-page-route-wiring.js +59 -24
- package/dist/server/app-page-route-wiring.js.map +1 -1
- package/dist/server/app-page-stream.d.ts +5 -0
- package/dist/server/app-page-stream.js +2 -0
- package/dist/server/app-page-stream.js.map +1 -1
- package/dist/server/app-prerender-static-params.d.ts +2 -1
- package/dist/server/app-prerender-static-params.js +44 -8
- package/dist/server/app-prerender-static-params.js.map +1 -1
- package/dist/server/app-route-handler-cache.d.ts +2 -2
- package/dist/server/app-route-handler-cache.js +3 -2
- package/dist/server/app-route-handler-cache.js.map +1 -1
- package/dist/server/app-route-handler-dispatch.d.ts +6 -1
- package/dist/server/app-route-handler-dispatch.js +1 -1
- package/dist/server/app-route-handler-dispatch.js.map +1 -1
- package/dist/server/app-route-handler-execution.d.ts +17 -2
- package/dist/server/app-route-handler-execution.js.map +1 -1
- package/dist/server/app-route-handler-response.js +5 -4
- package/dist/server/app-route-handler-response.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 +19 -1
- package/dist/server/app-rsc-cache-busting.js +36 -1
- 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-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 +21 -5
- package/dist/server/app-rsc-handler.js +38 -15
- package/dist/server/app-rsc-handler.js.map +1 -1
- package/dist/server/app-rsc-render-mode.d.ts +4 -3
- package/dist/server/app-rsc-render-mode.js +7 -1
- package/dist/server/app-rsc-render-mode.js.map +1 -1
- package/dist/server/app-rsc-request-normalization.d.ts +4 -1
- package/dist/server/app-rsc-request-normalization.js +4 -1
- package/dist/server/app-rsc-request-normalization.js.map +1 -1
- package/dist/server/app-rsc-response-finalizer.d.ts +8 -1
- package/dist/server/app-rsc-response-finalizer.js +10 -3
- 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 +47 -25
- package/dist/server/app-rsc-route-matching.js.map +1 -1
- package/dist/server/app-server-action-execution.d.ts +35 -3
- package/dist/server/app-server-action-execution.js +87 -33
- package/dist/server/app-server-action-execution.js.map +1 -1
- package/dist/server/app-ssr-entry.d.ts +3 -0
- package/dist/server/app-ssr-entry.js +83 -58
- 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 +7 -2
- package/dist/server/app-ssr-stream.js +26 -15
- package/dist/server/app-ssr-stream.js.map +1 -1
- package/dist/server/artifact-compatibility.d.ts +13 -3
- package/dist/server/artifact-compatibility.js +12 -8
- package/dist/server/artifact-compatibility.js.map +1 -1
- package/dist/server/cache-headers.d.ts +7 -0
- package/dist/server/cache-headers.js +19 -0
- package/dist/server/cache-headers.js.map +1 -0
- package/dist/server/cache-proof.d.ts +170 -5
- package/dist/server/cache-proof.js +472 -18
- package/dist/server/cache-proof.js.map +1 -1
- package/dist/server/client-reuse-manifest.d.ts +99 -0
- package/dist/server/client-reuse-manifest.js +212 -0
- package/dist/server/client-reuse-manifest.js.map +1 -0
- package/dist/server/default-global-error-module.d.ts +20 -0
- package/dist/server/default-global-error-module.js +20 -0
- package/dist/server/default-global-error-module.js.map +1 -0
- 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-server.d.ts +9 -1
- package/dist/server/dev-server.js +76 -19
- package/dist/server/dev-server.js.map +1 -1
- package/dist/server/edge-api-runtime.d.ts +5 -0
- package/dist/server/edge-api-runtime.js +8 -0
- package/dist/server/edge-api-runtime.js.map +1 -0
- 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 +20 -1
- package/dist/server/headers.js +22 -2
- package/dist/server/headers.js.map +1 -1
- package/dist/server/html.js +1 -1
- package/dist/server/html.js.map +1 -1
- package/dist/server/http-error-responses.d.ts +26 -1
- package/dist/server/http-error-responses.js +32 -2
- package/dist/server/http-error-responses.js.map +1 -1
- package/dist/server/isr-cache.d.ts +8 -3
- package/dist/server/isr-cache.js +24 -6
- package/dist/server/isr-cache.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-runtime.d.ts +15 -0
- package/dist/server/middleware-runtime.js +60 -7
- package/dist/server/middleware-runtime.js.map +1 -1
- package/dist/server/middleware.d.ts +13 -1
- package/dist/server/middleware.js +16 -2
- package/dist/server/middleware.js.map +1 -1
- package/dist/server/navigation-planner.d.ts +26 -6
- package/dist/server/navigation-planner.js +358 -24
- package/dist/server/navigation-planner.js.map +1 -1
- package/dist/server/navigation-trace.d.ts +9 -1
- package/dist/server/navigation-trace.js +8 -0
- package/dist/server/navigation-trace.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.d.ts +27 -1
- package/dist/server/pages-api-route.js +25 -3
- package/dist/server/pages-api-route.js.map +1 -1
- package/dist/server/pages-data-route.d.ts +77 -0
- package/dist/server/pages-data-route.js +97 -0
- package/dist/server/pages-data-route.js.map +1 -0
- package/dist/server/pages-i18n.d.ts +51 -1
- package/dist/server/pages-i18n.js +61 -1
- package/dist/server/pages-i18n.js.map +1 -1
- package/dist/server/pages-page-data.d.ts +32 -4
- package/dist/server/pages-page-data.js +52 -19
- package/dist/server/pages-page-data.js.map +1 -1
- package/dist/server/pages-page-response.d.ts +11 -1
- package/dist/server/pages-page-response.js +6 -4
- package/dist/server/pages-page-response.js.map +1 -1
- package/dist/server/prod-server.d.ts +26 -1
- package/dist/server/prod-server.js +150 -44
- package/dist/server/prod-server.js.map +1 -1
- package/dist/server/request-pipeline.d.ts +11 -2
- package/dist/server/request-pipeline.js +28 -11
- package/dist/server/request-pipeline.js.map +1 -1
- package/dist/server/seed-cache.d.ts +12 -31
- package/dist/server/seed-cache.js +22 -35
- 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 +27 -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/skip-cache-proof.d.ts +41 -0
- package/dist/server/skip-cache-proof.js +101 -0
- package/dist/server/skip-cache-proof.js.map +1 -0
- package/dist/server/static-file-cache.d.ts +1 -1
- package/dist/server/static-file-cache.js +7 -6
- package/dist/server/static-file-cache.js.map +1 -1
- package/dist/shims/cache-runtime.d.ts +19 -2
- package/dist/shims/cache-runtime.js +67 -11
- package/dist/shims/cache-runtime.js.map +1 -1
- package/dist/shims/cache.d.ts +5 -18
- package/dist/shims/cache.js +2 -0
- package/dist/shims/cache.js.map +1 -1
- package/dist/shims/client-locale.d.ts +15 -0
- package/dist/shims/client-locale.js +13 -0
- package/dist/shims/client-locale.js.map +1 -0
- package/dist/shims/default-global-error.d.ts +32 -0
- package/dist/shims/default-global-error.js +181 -0
- package/dist/shims/default-global-error.js.map +1 -0
- package/dist/shims/document.d.ts +59 -3
- package/dist/shims/document.js +36 -5
- package/dist/shims/document.js.map +1 -1
- package/dist/shims/error-boundary.d.ts +2 -2
- package/dist/shims/error-boundary.js +6 -8
- 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 +4 -1
- package/dist/shims/fetch-cache.js +40 -5
- 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 +13 -6
- 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/headers.d.ts +8 -11
- package/dist/shims/headers.js +22 -2
- package/dist/shims/headers.js.map +1 -1
- package/dist/shims/image.d.ts +1 -0
- package/dist/shims/image.js +144 -78
- package/dist/shims/image.js.map +1 -1
- package/dist/shims/internal/app-router-context.d.ts +6 -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/link-prefetch.d.ts +9 -1
- package/dist/shims/link-prefetch.js +11 -6
- package/dist/shims/link-prefetch.js.map +1 -1
- package/dist/shims/link.d.ts +33 -5
- package/dist/shims/link.js +205 -50
- package/dist/shims/link.js.map +1 -1
- package/dist/shims/metadata.d.ts +16 -30
- package/dist/shims/metadata.js +91 -32
- package/dist/shims/metadata.js.map +1 -1
- package/dist/shims/navigation.d.ts +164 -17
- package/dist/shims/navigation.js +355 -84
- 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/og.d.ts +18 -2
- package/dist/shims/og.js +49 -1
- package/dist/shims/og.js.map +1 -0
- 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/request-state-types.d.ts +1 -1
- package/dist/shims/root-params.d.ts +3 -1
- package/dist/shims/root-params.js +11 -3
- package/dist/shims/root-params.js.map +1 -1
- package/dist/shims/router-state.d.ts +1 -0
- package/dist/shims/router-state.js.map +1 -1
- package/dist/shims/router.d.ts +40 -7
- package/dist/shims/router.js +355 -250
- package/dist/shims/router.js.map +1 -1
- package/dist/shims/script.js +110 -32
- package/dist/shims/script.js.map +1 -1
- package/dist/shims/server.d.ts +21 -4
- package/dist/shims/server.js +31 -10
- package/dist/shims/server.js.map +1 -1
- package/dist/shims/slot.d.ts +1 -0
- package/dist/shims/slot.js +45 -1
- package/dist/shims/slot.js.map +1 -1
- package/dist/shims/unified-request-context.d.ts +1 -1
- package/dist/shims/unified-request-context.js +2 -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.d.ts +23 -1
- package/dist/shims/url-safety.js +29 -2
- package/dist/shims/url-safety.js.map +1 -1
- package/dist/shims/url-utils.d.ts +21 -1
- package/dist/shims/url-utils.js +67 -3
- package/dist/shims/url-utils.js.map +1 -1
- package/dist/typegen.d.ts +10 -0
- package/dist/typegen.js +242 -0
- package/dist/typegen.js.map +1 -0
- package/dist/utils/asset-prefix.d.ts +97 -0
- package/dist/utils/asset-prefix.js +124 -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.d.ts +2 -1
- package/dist/utils/cache-control-metadata.js +1 -3
- package/dist/utils/cache-control-metadata.js.map +1 -1
- package/dist/utils/domain-locale.d.ts +2 -1
- package/dist/utils/domain-locale.js +9 -1
- package/dist/utils/domain-locale.js.map +1 -1
- package/dist/utils/lazy-chunks.d.ts +1 -1
- package/dist/utils/lazy-chunks.js +1 -1
- package/dist/utils/lazy-chunks.js.map +1 -1
- package/dist/utils/navigation-signal.d.ts +1 -2
- package/dist/utils/navigation-signal.js +1 -1
- package/dist/utils/navigation-signal.js.map +1 -1
- package/dist/utils/prerender-output-paths.d.ts +15 -0
- package/dist/utils/prerender-output-paths.js +24 -0
- package/dist/utils/prerender-output-paths.js.map +1 -0
- package/dist/utils/query.d.ts +17 -1
- package/dist/utils/query.js +36 -1
- package/dist/utils/query.js.map +1 -1
- package/dist/utils/record.d.ts +5 -0
- package/dist/utils/record.js +8 -0
- package/dist/utils/record.js.map +1 -0
- 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/package.json +13 -5
|
@@ -1,28 +1,17 @@
|
|
|
1
|
+
import { normalizePathnameForRouteMatch } from "../routing/utils.js";
|
|
1
2
|
import { stripBasePath } from "../utils/base-path.js";
|
|
2
3
|
import { RSC_ACTION_HEADER, VINEXT_INTERCEPTION_CONTEXT_HEADER, VINEXT_MOUNTED_SLOTS_HEADER } from "./headers.js";
|
|
4
|
+
import { normalizePath } from "./normalize-path.js";
|
|
3
5
|
import { AppElementsWire } from "./app-elements-wire.js";
|
|
4
6
|
import { getMountedSlotIds, getMountedSlotIdsHeader } from "./app-elements.js";
|
|
7
|
+
import { createHistoryStateWithNavigationMetadata, createHistoryStateWithPreviousNextUrl, readHistoryStatePreviousNextUrl, readHistoryStateTraversalIndex, resolveHistoryTraversalIntent } from "./app-history-state.js";
|
|
5
8
|
import { createRscRequestHeaders } from "./app-rsc-cache-busting.js";
|
|
6
9
|
import { NavigationTraceReasonCodes, createNavigationLifecycleTraceFields, createNavigationTrace } from "./navigation-trace.js";
|
|
10
|
+
import { createCacheEntryReuseProof } from "./cache-proof.js";
|
|
7
11
|
import { navigationPlanner } from "./navigation-planner.js";
|
|
8
12
|
//#region src/server/app-browser-state.ts
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
if (!state || typeof state !== "object") return {};
|
|
12
|
-
const nextState = {};
|
|
13
|
-
for (const [key, value] of Object.entries(state)) nextState[key] = value;
|
|
14
|
-
return nextState;
|
|
15
|
-
}
|
|
16
|
-
function createHistoryStateWithPreviousNextUrl(state, previousNextUrl) {
|
|
17
|
-
const nextState = cloneHistoryState(state);
|
|
18
|
-
if (previousNextUrl === null) delete nextState[VINEXT_PREVIOUS_NEXT_URL_HISTORY_STATE_KEY];
|
|
19
|
-
else nextState[VINEXT_PREVIOUS_NEXT_URL_HISTORY_STATE_KEY] = previousNextUrl;
|
|
20
|
-
return Object.keys(nextState).length > 0 ? nextState : null;
|
|
21
|
-
}
|
|
22
|
-
function readHistoryStatePreviousNextUrl(state) {
|
|
23
|
-
const value = cloneHistoryState(state)[VINEXT_PREVIOUS_NEXT_URL_HISTORY_STATE_KEY];
|
|
24
|
-
return typeof value === "string" ? value : null;
|
|
25
|
-
}
|
|
13
|
+
const FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN = { origin: "fresh" };
|
|
14
|
+
const VISITED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN = { origin: "visited-cache" };
|
|
26
15
|
function createOperationRecord(options) {
|
|
27
16
|
return {
|
|
28
17
|
id: options.id,
|
|
@@ -31,6 +20,25 @@ function createOperationRecord(options) {
|
|
|
31
20
|
state: "pending"
|
|
32
21
|
};
|
|
33
22
|
}
|
|
23
|
+
function isCacheRestorableAppPayloadMetadata(metadata) {
|
|
24
|
+
return metadata.cacheEntryReuseProof !== void 0;
|
|
25
|
+
}
|
|
26
|
+
function requiresCacheEntryReuseProof(origin) {
|
|
27
|
+
switch (origin.origin) {
|
|
28
|
+
case "fresh": return false;
|
|
29
|
+
case "visited-cache": return true;
|
|
30
|
+
default: throw new Error("[vinext] Unknown App Router payload origin: " + String(origin));
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function normalizeNavigationSnapshotMatchedUrl(pathname) {
|
|
34
|
+
return normalizePath(normalizePathnameForRouteMatch(pathname));
|
|
35
|
+
}
|
|
36
|
+
function createRouteSnapshotRouteId(options) {
|
|
37
|
+
if (options.interception !== null) return options.routeId;
|
|
38
|
+
const parsed = AppElementsWire.parseElementKey(options.routeId);
|
|
39
|
+
if (parsed?.kind !== "route" || parsed.interceptionContext === null) return options.routeId;
|
|
40
|
+
return AppElementsWire.encodeRouteId(parsed.path, null);
|
|
41
|
+
}
|
|
34
42
|
function resolveInterceptionContextFromPreviousNextUrl(previousNextUrl, basePath = "") {
|
|
35
43
|
if (previousNextUrl === null) return null;
|
|
36
44
|
return stripBasePath(new URL(previousNextUrl, "http://localhost").pathname, basePath);
|
|
@@ -65,6 +73,7 @@ function resolvePendingNavigationCommitDispositionDecision(options) {
|
|
|
65
73
|
return mapNavigationDecisionToPendingDisposition(planPendingRootBoundaryFlightResponse({
|
|
66
74
|
currentState: options.currentState,
|
|
67
75
|
pending: options.pending,
|
|
76
|
+
routeManifest: options.routeManifest ?? null,
|
|
68
77
|
targetHref: options.targetHref,
|
|
69
78
|
traceFields
|
|
70
79
|
}));
|
|
@@ -99,30 +108,46 @@ function createMountedParallelSlotSnapshots(elements) {
|
|
|
99
108
|
return snapshots;
|
|
100
109
|
}
|
|
101
110
|
function createVisibleRouteSnapshot(state) {
|
|
111
|
+
const displayUrl = createNavigationSnapshotUrl(state.navigationSnapshot);
|
|
112
|
+
const matchedUrl = normalizeNavigationSnapshotMatchedUrl(state.navigationSnapshot.pathname);
|
|
102
113
|
return {
|
|
103
|
-
displayUrl
|
|
114
|
+
displayUrl,
|
|
115
|
+
interception: state.interception,
|
|
116
|
+
interceptionContext: state.interceptionContext,
|
|
104
117
|
layoutIds: state.layoutIds,
|
|
105
|
-
matchedUrl
|
|
118
|
+
matchedUrl,
|
|
106
119
|
mountedParallelSlots: createMountedParallelSlotSnapshots(state.elements),
|
|
107
120
|
rootBoundaryId: state.rootLayoutTreePath,
|
|
108
|
-
routeId:
|
|
121
|
+
routeId: createRouteSnapshotRouteId({
|
|
122
|
+
interception: state.interception,
|
|
123
|
+
routeId: state.routeId
|
|
124
|
+
}),
|
|
125
|
+
slotBindings: state.slotBindings
|
|
109
126
|
};
|
|
110
127
|
}
|
|
111
128
|
function createPendingRouteSnapshot(pending) {
|
|
129
|
+
const displayUrl = createNavigationSnapshotUrl(pending.action.navigationSnapshot);
|
|
130
|
+
const matchedUrl = normalizeNavigationSnapshotMatchedUrl(pending.action.navigationSnapshot.pathname);
|
|
112
131
|
return {
|
|
113
|
-
displayUrl
|
|
132
|
+
displayUrl,
|
|
133
|
+
interception: pending.action.interception,
|
|
134
|
+
interceptionContext: pending.action.interceptionContext,
|
|
114
135
|
layoutIds: pending.action.layoutIds,
|
|
115
|
-
matchedUrl
|
|
136
|
+
matchedUrl,
|
|
116
137
|
mountedParallelSlots: createMountedParallelSlotSnapshots(pending.action.elements),
|
|
117
138
|
rootBoundaryId: pending.rootLayoutTreePath,
|
|
118
|
-
routeId:
|
|
139
|
+
routeId: createRouteSnapshotRouteId({
|
|
140
|
+
interception: pending.action.interception,
|
|
141
|
+
routeId: pending.routeId
|
|
142
|
+
}),
|
|
143
|
+
slotBindings: pending.action.slotBindings
|
|
119
144
|
};
|
|
120
145
|
}
|
|
121
146
|
function createPendingNavigationOperationToken(options) {
|
|
122
147
|
return {
|
|
123
148
|
baseVisibleCommitVersion: options.pending.action.operation.startedVisibleCommitVersion,
|
|
124
149
|
deploymentVersion: null,
|
|
125
|
-
graphVersion: null,
|
|
150
|
+
graphVersion: options.routeManifest?.graphVersion ?? null,
|
|
126
151
|
lane: options.pending.action.operation.lane,
|
|
127
152
|
operationId: options.pending.action.operation.id,
|
|
128
153
|
targetSnapshotFingerprint: createRootBoundarySnapshotFingerprint(options.targetSnapshot)
|
|
@@ -135,10 +160,12 @@ function planPendingRootBoundaryFlightResponse(options) {
|
|
|
135
160
|
const targetSnapshot = createPendingRouteSnapshot(options.pending);
|
|
136
161
|
const token = createPendingNavigationOperationToken({
|
|
137
162
|
pending: options.pending,
|
|
163
|
+
routeManifest: options.routeManifest,
|
|
138
164
|
targetSnapshot
|
|
139
165
|
});
|
|
166
|
+
const cacheEntryReuseProof = options.pending.cacheEntryReuseProof;
|
|
140
167
|
return navigationPlanner.plan({
|
|
141
|
-
routeManifest:
|
|
168
|
+
routeManifest: options.routeManifest,
|
|
142
169
|
state: {
|
|
143
170
|
nextOperationToken: token,
|
|
144
171
|
traceFields: options.traceFields,
|
|
@@ -148,6 +175,7 @@ function planPendingRootBoundaryFlightResponse(options) {
|
|
|
148
175
|
event: {
|
|
149
176
|
kind: "flightResponseArrived",
|
|
150
177
|
result: {
|
|
178
|
+
...cacheEntryReuseProof ? { cacheEntryReuseProof } : {},
|
|
151
179
|
href: options.targetHref ?? targetSnapshot.displayUrl,
|
|
152
180
|
targetSnapshot
|
|
153
181
|
},
|
|
@@ -161,6 +189,7 @@ function mapNavigationDecisionToPendingDisposition(decision) {
|
|
|
161
189
|
disposition: "dispatch",
|
|
162
190
|
preserveAbsentSlots: decision.proposal.preserveAbsentSlots,
|
|
163
191
|
preserveElementIds: decision.proposal.preserveElementIds,
|
|
192
|
+
preservePreviousSlotIds: decision.proposal.preservePreviousSlotIds,
|
|
164
193
|
trace: decision.trace
|
|
165
194
|
};
|
|
166
195
|
case "hardNavigate": return {
|
|
@@ -180,13 +209,18 @@ function mapNavigationDecisionToPendingDisposition(decision) {
|
|
|
180
209
|
async function createPendingNavigationCommit(options) {
|
|
181
210
|
const elements = await options.nextElements;
|
|
182
211
|
const metadata = AppElementsWire.readMetadata(elements);
|
|
183
|
-
const
|
|
212
|
+
const cacheEntryReuseProof = metadata.cacheEntryReuseProof ?? (requiresCacheEntryReuseProof(options.payloadOrigin) ? createCacheEntryReuseProof(null) : void 0);
|
|
213
|
+
const requestedPreviousNextUrl = options.previousNextUrl !== void 0 ? options.previousNextUrl : options.currentState.previousNextUrl;
|
|
214
|
+
const previousNextUrl = metadata.interception === null ? null : requestedPreviousNextUrl;
|
|
184
215
|
return {
|
|
185
216
|
action: {
|
|
217
|
+
...cacheEntryReuseProof ? { cacheEntryReuseProof } : {},
|
|
186
218
|
elements,
|
|
219
|
+
interception: metadata.interception,
|
|
187
220
|
interceptionContext: metadata.interceptionContext,
|
|
188
221
|
layoutIds: metadata.layoutIds,
|
|
189
222
|
layoutFlags: metadata.layoutFlags,
|
|
223
|
+
slotBindings: metadata.slotBindings,
|
|
190
224
|
navigationSnapshot: options.navigationSnapshot,
|
|
191
225
|
operation: createOperationRecord({
|
|
192
226
|
id: options.renderId,
|
|
@@ -199,6 +233,8 @@ async function createPendingNavigationCommit(options) {
|
|
|
199
233
|
routeId: metadata.routeId,
|
|
200
234
|
type: options.type
|
|
201
235
|
},
|
|
236
|
+
...cacheEntryReuseProof ? { cacheEntryReuseProof } : {},
|
|
237
|
+
interception: metadata.interception,
|
|
202
238
|
interceptionContext: metadata.interceptionContext,
|
|
203
239
|
previousNextUrl,
|
|
204
240
|
rootLayoutTreePath: metadata.rootLayoutTreePath,
|
|
@@ -206,6 +242,6 @@ async function createPendingNavigationCommit(options) {
|
|
|
206
242
|
};
|
|
207
243
|
}
|
|
208
244
|
//#endregion
|
|
209
|
-
export { createHistoryStateWithPreviousNextUrl, createPendingNavigationCommit, readHistoryStatePreviousNextUrl, resolveInterceptionContextFromPreviousNextUrl, resolvePendingNavigationCommitDispositionDecision, resolveServerActionRequestState };
|
|
245
|
+
export { FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN, VISITED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN, createHistoryStateWithNavigationMetadata, createHistoryStateWithPreviousNextUrl, createPendingNavigationCommit, isCacheRestorableAppPayloadMetadata, readHistoryStatePreviousNextUrl, readHistoryStateTraversalIndex, resolveHistoryTraversalIntent, resolveInterceptionContextFromPreviousNextUrl, resolvePendingNavigationCommitDispositionDecision, resolveServerActionRequestState };
|
|
210
246
|
|
|
211
247
|
//# sourceMappingURL=app-browser-state.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-browser-state.js","names":["_exhaustive"],"sources":["../../src/server/app-browser-state.ts"],"sourcesContent":["import { stripBasePath } from \"../utils/base-path.js\";\nimport {\n AppElementsWire,\n getMountedSlotIds,\n getMountedSlotIdsHeader,\n type AppElements,\n type LayoutFlags,\n} from \"./app-elements.js\";\nimport { createRscRequestHeaders } from \"./app-rsc-cache-busting.js\";\nimport {\n RSC_ACTION_HEADER,\n VINEXT_INTERCEPTION_CONTEXT_HEADER,\n VINEXT_MOUNTED_SLOTS_HEADER,\n} from \"./headers.js\";\nimport {\n NavigationTraceReasonCodes,\n createNavigationLifecycleTraceFields,\n createNavigationTrace,\n type NavigationTrace,\n type NavigationTraceFields,\n} from \"./navigation-trace.js\";\nimport {\n navigationPlanner,\n type MountedParallelSlotSnapshotV0,\n type NavigationDecisionV0,\n type OperationLane,\n type OperationToken,\n type RouteSnapshotV0,\n} from \"./navigation-planner.js\";\nimport type { ClientNavigationRenderSnapshot } from \"vinext/shims/navigation\";\n\nconst VINEXT_PREVIOUS_NEXT_URL_HISTORY_STATE_KEY = \"__vinext_previousNextUrl\";\n\ntype HistoryStateRecord = {\n [key: string]: unknown;\n};\n\nexport type { OperationLane } from \"./navigation-planner.js\";\n\ntype OperationRecordBase = {\n id: number;\n lane: OperationLane;\n startedVisibleCommitVersion: number;\n};\n\nexport type PendingOperationRecord = OperationRecordBase & {\n state: \"pending\";\n};\n\nexport type CommittedOperationRecord = OperationRecordBase & {\n state: \"committed\";\n visibleCommitVersion: number;\n};\n\nexport type OperationRecord = PendingOperationRecord | CommittedOperationRecord;\n\nexport type AppRouterState = {\n activeOperation: OperationRecord | null;\n elements: AppElements;\n interceptionContext: string | null;\n layoutFlags: LayoutFlags;\n layoutIds: readonly string[];\n previousNextUrl: string | null;\n renderId: number;\n navigationSnapshot: ClientNavigationRenderSnapshot;\n rootLayoutTreePath: string | null;\n routeId: string;\n visibleCommitVersion: number;\n};\n\nexport type AppRouterAction = {\n elements: AppElements;\n interceptionContext: string | null;\n layoutFlags: LayoutFlags;\n layoutIds: readonly string[];\n navigationSnapshot: ClientNavigationRenderSnapshot;\n operation: PendingOperationRecord;\n previousNextUrl: string | null;\n renderId: number;\n rootLayoutTreePath: string | null;\n routeId: string;\n type: \"navigate\" | \"replace\" | \"traverse\";\n};\n\nexport type PendingNavigationCommit = {\n action: AppRouterAction;\n interceptionContext: string | null;\n previousNextUrl: string | null;\n rootLayoutTreePath: string | null;\n routeId: string;\n};\n\ntype PendingNavigationCommitDisposition = \"dispatch\" | \"hard-navigate\" | \"skip\";\ntype DispatchPendingNavigationCommitDispositionDecision = {\n disposition: \"dispatch\";\n preserveAbsentSlots: boolean;\n preserveElementIds: readonly string[];\n trace: NavigationTrace;\n};\ntype NonDispatchPendingNavigationCommitDispositionDecision = {\n disposition: Exclude<PendingNavigationCommitDisposition, \"dispatch\">;\n preserveElementIds: readonly [];\n trace: NavigationTrace;\n};\ntype PendingNavigationCommitDispositionDecision =\n | DispatchPendingNavigationCommitDispositionDecision\n | NonDispatchPendingNavigationCommitDispositionDecision;\n\nfunction cloneHistoryState(state: unknown): HistoryStateRecord {\n if (!state || typeof state !== \"object\") {\n return {};\n }\n\n const nextState: HistoryStateRecord = {};\n for (const [key, value] of Object.entries(state)) {\n nextState[key] = value;\n }\n return nextState;\n}\n\nexport function createHistoryStateWithPreviousNextUrl(\n state: unknown,\n previousNextUrl: string | null,\n): HistoryStateRecord | null {\n const nextState = cloneHistoryState(state);\n\n if (previousNextUrl === null) {\n delete nextState[VINEXT_PREVIOUS_NEXT_URL_HISTORY_STATE_KEY];\n } else {\n nextState[VINEXT_PREVIOUS_NEXT_URL_HISTORY_STATE_KEY] = previousNextUrl;\n }\n\n return Object.keys(nextState).length > 0 ? nextState : null;\n}\n\nexport function readHistoryStatePreviousNextUrl(state: unknown): string | null {\n const value = cloneHistoryState(state)[VINEXT_PREVIOUS_NEXT_URL_HISTORY_STATE_KEY];\n return typeof value === \"string\" ? value : null;\n}\n\nfunction createOperationRecord(options: {\n id: number;\n lane: OperationLane;\n startedVisibleCommitVersion: number;\n}): PendingOperationRecord {\n return {\n id: options.id,\n lane: options.lane,\n startedVisibleCommitVersion: options.startedVisibleCommitVersion,\n state: \"pending\",\n };\n}\n\nexport function resolveInterceptionContextFromPreviousNextUrl(\n previousNextUrl: string | null,\n basePath: string = \"\",\n): string | null {\n if (previousNextUrl === null) {\n return null;\n }\n\n const parsedUrl = new URL(previousNextUrl, \"http://localhost\");\n return stripBasePath(parsedUrl.pathname, basePath);\n}\n\ntype ResolveServerActionRequestStateOptions = {\n actionId: string;\n basePath: string;\n elements: AppElements;\n previousNextUrl: string | null;\n};\n\ntype ResolveServerActionRequestStateResult = {\n headers: Headers;\n};\n\n/**\n * Pure: builds the fetch Headers for a server-action POST. Carries the same\n * interception-context and mounted-slots headers the refresh path already\n * sends, so the server-action re-render can rebuild the intercepted tree\n * instead of replacing it with the direct route.\n *\n * Next.js sends `Next-URL: state.previousNextUrl || state.nextUrl` on action\n * POSTs when `hasInterceptionRouteInCurrentTree(state.tree)`. Vinext's\n * X-Vinext-Interception-Context is the equivalent signal for the server-side\n * `findIntercept` lookup.\n */\nexport function resolveServerActionRequestState(\n options: ResolveServerActionRequestStateOptions,\n): ResolveServerActionRequestStateResult {\n const headers = createRscRequestHeaders();\n headers.set(RSC_ACTION_HEADER, options.actionId);\n\n const interceptionContext = resolveInterceptionContextFromPreviousNextUrl(\n options.previousNextUrl,\n options.basePath,\n );\n if (interceptionContext !== null) {\n headers.set(VINEXT_INTERCEPTION_CONTEXT_HEADER, interceptionContext);\n }\n\n const mountedSlotsHeader = getMountedSlotIdsHeader(options.elements);\n if (mountedSlotsHeader !== null) {\n headers.set(VINEXT_MOUNTED_SLOTS_HEADER, mountedSlotsHeader);\n }\n\n return { headers };\n}\n\nexport function resolvePendingNavigationCommitDispositionDecision(options: {\n activeNavigationId: number;\n currentState: AppRouterState;\n pending: PendingNavigationCommit;\n startedNavigationId: number;\n targetHref?: string;\n}): PendingNavigationCommitDispositionDecision {\n const traceFields = createPendingNavigationTraceFields(options);\n\n if (\n options.startedNavigationId !== options.activeNavigationId ||\n options.pending.action.operation.startedVisibleCommitVersion !==\n options.currentState.visibleCommitVersion\n ) {\n return {\n disposition: \"skip\",\n preserveElementIds: [],\n trace: createNavigationTrace(NavigationTraceReasonCodes.staleOperation, traceFields),\n };\n }\n\n return mapNavigationDecisionToPendingDisposition(\n planPendingRootBoundaryFlightResponse({\n currentState: options.currentState,\n pending: options.pending,\n targetHref: options.targetHref,\n traceFields,\n }),\n );\n}\n\nfunction createPendingNavigationTraceFields(options: {\n activeNavigationId: number;\n currentState: AppRouterState;\n pending: PendingNavigationCommit;\n startedNavigationId: number;\n targetHref?: string;\n}): NavigationTraceFields {\n return {\n ...createNavigationLifecycleTraceFields({\n activeNavigationId: options.activeNavigationId,\n currentRootLayoutTreePath: options.currentState.rootLayoutTreePath,\n currentVisibleCommitVersion: options.currentState.visibleCommitVersion,\n nextRootLayoutTreePath: options.pending.rootLayoutTreePath,\n startedNavigationId: options.startedNavigationId,\n startedVisibleCommitVersion: options.pending.action.operation.startedVisibleCommitVersion,\n }),\n ...(options.targetHref !== undefined ? { targetHref: options.targetHref } : {}),\n };\n}\n\nfunction createNavigationSnapshotUrl(snapshot: ClientNavigationRenderSnapshot): string {\n const query = snapshot.searchParams.toString();\n return query === \"\" ? snapshot.pathname : `${snapshot.pathname}?${query}`;\n}\n\nfunction createMountedParallelSlotSnapshots(\n elements: AppElements,\n): readonly MountedParallelSlotSnapshotV0[] {\n const snapshots: MountedParallelSlotSnapshotV0[] = [];\n for (const slotId of getMountedSlotIds(elements)) {\n const parsed = AppElementsWire.parseElementKey(slotId);\n if (parsed?.kind !== \"slot\") continue;\n snapshots.push({\n ownerLayoutId: AppElementsWire.encodeLayoutId(parsed.treePath),\n slotId,\n });\n }\n return snapshots;\n}\n\nfunction createVisibleRouteSnapshot(state: AppRouterState): RouteSnapshotV0 {\n const displayUrl = createNavigationSnapshotUrl(state.navigationSnapshot);\n return {\n displayUrl,\n layoutIds: state.layoutIds,\n // `displayUrl` preserves the browser-visible query string for decisions and\n // traces. `matchedUrl` stays path-only because route matching has already\n // consumed query params before AppElements metadata reaches this boundary.\n matchedUrl: state.navigationSnapshot.pathname,\n mountedParallelSlots: createMountedParallelSlotSnapshots(state.elements),\n rootBoundaryId: state.rootLayoutTreePath,\n routeId: state.routeId,\n };\n}\n\nfunction createPendingRouteSnapshot(pending: PendingNavigationCommit): RouteSnapshotV0 {\n const displayUrl = createNavigationSnapshotUrl(pending.action.navigationSnapshot);\n return {\n displayUrl,\n layoutIds: pending.action.layoutIds,\n // See createVisibleRouteSnapshot: matchedUrl intentionally models the route\n // identity, not the address bar URL.\n matchedUrl: pending.action.navigationSnapshot.pathname,\n mountedParallelSlots: createMountedParallelSlotSnapshots(pending.action.elements),\n rootBoundaryId: pending.rootLayoutTreePath,\n routeId: pending.routeId,\n };\n}\n\nfunction createPendingNavigationOperationToken(options: {\n pending: PendingNavigationCommit;\n targetSnapshot: RouteSnapshotV0;\n}): OperationToken {\n return {\n baseVisibleCommitVersion: options.pending.action.operation.startedVisibleCommitVersion,\n deploymentVersion: null,\n graphVersion: null,\n lane: options.pending.action.operation.lane,\n operationId: options.pending.action.operation.id,\n targetSnapshotFingerprint: createRootBoundarySnapshotFingerprint(options.targetSnapshot),\n };\n}\n\nfunction createRootBoundarySnapshotFingerprint(snapshot: RouteSnapshotV0): string {\n return `${snapshot.routeId}|root:${snapshot.rootBoundaryId ?? \"unknown\"}`;\n}\n\nfunction planPendingRootBoundaryFlightResponse(options: {\n currentState: AppRouterState;\n pending: PendingNavigationCommit;\n targetHref?: string;\n traceFields: NavigationTraceFields;\n}): NavigationDecisionV0 {\n const targetSnapshot = createPendingRouteSnapshot(options.pending);\n const token = createPendingNavigationOperationToken({\n pending: options.pending,\n targetSnapshot,\n });\n\n // #726-CORE-07/08 keeps the browser state layer as the lifecycle gate and\n // only translates committed AppElements metadata into planner snapshots.\n // The planner owns the root-boundary decision; later #726 route-graph work\n // should replace these client-visible snapshots with the read model called\n // out in routing/app-router.ts instead of adding more local topology checks.\n return navigationPlanner.plan({\n routeManifest: null,\n state: {\n nextOperationToken: token,\n traceFields: options.traceFields,\n visibleCommitVersion: options.currentState.visibleCommitVersion,\n visibleSnapshot: createVisibleRouteSnapshot(options.currentState),\n },\n event: {\n kind: \"flightResponseArrived\",\n result: {\n // Approval call sites must pass the executor's targetHref so the\n // planner trace and future hard-nav executor agree with the browser\n // URL. The fallback remains for lower-level tests and direct disposition\n // callers that exercise only snapshot-derived planner semantics.\n href: options.targetHref ?? targetSnapshot.displayUrl,\n targetSnapshot,\n },\n token,\n },\n });\n}\n\nfunction mapNavigationDecisionToPendingDisposition(\n decision: NavigationDecisionV0,\n): PendingNavigationCommitDispositionDecision {\n switch (decision.kind) {\n case \"proposeCommit\":\n return {\n disposition: \"dispatch\",\n preserveAbsentSlots: decision.proposal.preserveAbsentSlots,\n preserveElementIds: decision.proposal.preserveElementIds,\n trace: decision.trace,\n };\n case \"hardNavigate\":\n return { disposition: \"hard-navigate\", preserveElementIds: [], trace: decision.trace };\n case \"noCommit\":\n return { disposition: \"skip\", preserveElementIds: [], trace: decision.trace };\n case \"requestWork\":\n throw new Error(\n `[vinext] Root-boundary commit planning returned requestWork (${decision.work.kind}); flightResponseArrived should never request work`,\n );\n default: {\n const _exhaustive: never = decision;\n throw new Error(\"[vinext] Unknown navigation decision: \" + String(_exhaustive));\n }\n }\n}\n\nexport async function createPendingNavigationCommit(options: {\n currentState: AppRouterState;\n nextElements: Promise<AppElements>;\n navigationSnapshot: ClientNavigationRenderSnapshot;\n operationLane: OperationLane;\n previousNextUrl?: string | null;\n renderId: number;\n type: \"navigate\" | \"replace\" | \"traverse\";\n}): Promise<PendingNavigationCommit> {\n const elements = await options.nextElements;\n const metadata = AppElementsWire.readMetadata(elements);\n const previousNextUrl =\n options.previousNextUrl !== undefined\n ? options.previousNextUrl\n : options.currentState.previousNextUrl;\n\n return {\n action: {\n elements,\n interceptionContext: metadata.interceptionContext,\n layoutIds: metadata.layoutIds,\n layoutFlags: metadata.layoutFlags,\n navigationSnapshot: options.navigationSnapshot,\n operation: createOperationRecord({\n id: options.renderId,\n lane: options.operationLane,\n startedVisibleCommitVersion: options.currentState.visibleCommitVersion,\n }),\n previousNextUrl,\n renderId: options.renderId,\n rootLayoutTreePath: metadata.rootLayoutTreePath,\n routeId: metadata.routeId,\n type: options.type,\n },\n // Convenience aliases — always equal action.interceptionContext / action.rootLayoutTreePath / action.routeId.\n interceptionContext: metadata.interceptionContext,\n previousNextUrl,\n rootLayoutTreePath: metadata.rootLayoutTreePath,\n routeId: metadata.routeId,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"app-browser-state.js","names":["_exhaustive"],"sources":["../../src/server/app-browser-state.ts"],"sourcesContent":["import { stripBasePath } from \"../utils/base-path.js\";\nimport type { RouteManifest } from \"../routing/app-route-graph.js\";\nimport {\n AppElementsWire,\n getMountedSlotIds,\n getMountedSlotIdsHeader,\n type AppElements,\n type AppElementsInterception,\n type AppElementsSlotBinding,\n type LayoutFlags,\n} from \"./app-elements.js\";\nimport { createRscRequestHeaders } from \"./app-rsc-cache-busting.js\";\nimport {\n RSC_ACTION_HEADER,\n VINEXT_INTERCEPTION_CONTEXT_HEADER,\n VINEXT_MOUNTED_SLOTS_HEADER,\n} from \"./headers.js\";\nimport {\n NavigationTraceReasonCodes,\n createNavigationLifecycleTraceFields,\n createNavigationTrace,\n type NavigationTrace,\n type NavigationTraceFields,\n} from \"./navigation-trace.js\";\nimport { createCacheEntryReuseProof, type CacheEntryReuseProof } from \"./cache-proof.js\";\nimport {\n navigationPlanner,\n type MountedParallelSlotSnapshotV0,\n type NavigationDecisionV0,\n type OperationLane,\n type OperationToken,\n type RouteSnapshotV0,\n} from \"./navigation-planner.js\";\nimport type { ClientNavigationRenderSnapshot } from \"vinext/shims/navigation\";\nimport { normalizePathnameForRouteMatch } from \"../routing/utils.js\";\nimport { normalizePath } from \"./normalize-path.js\";\nexport {\n createHistoryStateWithNavigationMetadata,\n createHistoryStateWithPreviousNextUrl,\n readHistoryStatePreviousNextUrl,\n readHistoryStateTraversalIndex,\n resolveHistoryTraversalIntent,\n type HistoryTraversalIntent,\n} from \"./app-history-state.js\";\n\nexport type { OperationLane } from \"./navigation-planner.js\";\n\ntype OperationRecordBase = {\n id: number;\n lane: OperationLane;\n startedVisibleCommitVersion: number;\n};\n\nexport type PendingOperationRecord = OperationRecordBase & {\n state: \"pending\";\n};\n\nexport type CommittedOperationRecord = OperationRecordBase & {\n state: \"committed\";\n visibleCommitVersion: number;\n};\n\nexport type OperationRecord = PendingOperationRecord | CommittedOperationRecord;\n\nexport type AppRouterState = {\n activeOperation: OperationRecord | null;\n elements: AppElements;\n interception: AppElementsInterception | null;\n interceptionContext: string | null;\n layoutFlags: LayoutFlags;\n layoutIds: readonly string[];\n previousNextUrl: string | null;\n renderId: number;\n navigationSnapshot: ClientNavigationRenderSnapshot;\n rootLayoutTreePath: string | null;\n routeId: string;\n slotBindings: readonly AppElementsSlotBinding[];\n visibleCommitVersion: number;\n};\n\nexport type AppRouterAction = {\n cacheEntryReuseProof?: CacheEntryReuseProof;\n elements: AppElements;\n interception: AppElementsInterception | null;\n interceptionContext: string | null;\n layoutFlags: LayoutFlags;\n layoutIds: readonly string[];\n navigationSnapshot: ClientNavigationRenderSnapshot;\n operation: PendingOperationRecord;\n previousNextUrl: string | null;\n renderId: number;\n rootLayoutTreePath: string | null;\n routeId: string;\n slotBindings: readonly AppElementsSlotBinding[];\n type: \"navigate\" | \"replace\" | \"traverse\";\n};\n\nexport type PendingNavigationCommit = {\n action: AppRouterAction;\n cacheEntryReuseProof?: CacheEntryReuseProof;\n interception: AppElementsInterception | null;\n interceptionContext: string | null;\n previousNextUrl: string | null;\n rootLayoutTreePath: string | null;\n routeId: string;\n};\n\nexport type AppNavigationPayloadOrigin = Readonly<\n { origin: \"fresh\" } | { origin: \"visited-cache\" }\n>;\n\nexport const FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN: AppNavigationPayloadOrigin = {\n origin: \"fresh\",\n};\nexport const VISITED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN: AppNavigationPayloadOrigin = {\n origin: \"visited-cache\",\n};\n\ntype PendingNavigationCommitDisposition = \"dispatch\" | \"hard-navigate\" | \"skip\";\ntype CacheRestorableAppPayloadMetadata = Readonly<{\n cacheEntryReuseProof?: CacheEntryReuseProof;\n}>;\ntype DispatchPendingNavigationCommitDispositionDecision = {\n disposition: \"dispatch\";\n preserveAbsentSlots: boolean;\n preserveElementIds: readonly string[];\n preservePreviousSlotIds: readonly string[];\n trace: NavigationTrace;\n};\ntype NonDispatchPendingNavigationCommitDispositionDecision = {\n disposition: Exclude<PendingNavigationCommitDisposition, \"dispatch\">;\n preserveElementIds: readonly [];\n trace: NavigationTrace;\n};\ntype PendingNavigationCommitDispositionDecision =\n | DispatchPendingNavigationCommitDispositionDecision\n | NonDispatchPendingNavigationCommitDispositionDecision;\nfunction createOperationRecord(options: {\n id: number;\n lane: OperationLane;\n startedVisibleCommitVersion: number;\n}): PendingOperationRecord {\n return {\n id: options.id,\n lane: options.lane,\n startedVisibleCommitVersion: options.startedVisibleCommitVersion,\n state: \"pending\",\n };\n}\n\nexport function isCacheRestorableAppPayloadMetadata(\n metadata: CacheRestorableAppPayloadMetadata,\n): metadata is CacheRestorableAppPayloadMetadata & { cacheEntryReuseProof: CacheEntryReuseProof } {\n return metadata.cacheEntryReuseProof !== undefined;\n}\n\nfunction requiresCacheEntryReuseProof(origin: AppNavigationPayloadOrigin): boolean {\n switch (origin.origin) {\n case \"fresh\":\n return false;\n case \"visited-cache\":\n return true;\n default: {\n const _exhaustive: never = origin;\n throw new Error(\"[vinext] Unknown App Router payload origin: \" + String(_exhaustive));\n }\n }\n}\n\nfunction normalizeNavigationSnapshotMatchedUrl(pathname: string): string {\n return normalizePath(normalizePathnameForRouteMatch(pathname));\n}\n\nfunction createRouteSnapshotRouteId(options: {\n interception: AppElementsInterception | null;\n routeId: string;\n}): string {\n if (options.interception !== null) return options.routeId;\n\n const parsed = AppElementsWire.parseElementKey(options.routeId);\n if (parsed?.kind !== \"route\" || parsed.interceptionContext === null) {\n return options.routeId;\n }\n\n // A context suffix keeps AppElements render keys partitioned, but without\n // explicit interception proof it is not semantic route authority.\n return AppElementsWire.encodeRouteId(parsed.path, null);\n}\n\nexport function resolveInterceptionContextFromPreviousNextUrl(\n previousNextUrl: string | null,\n basePath: string = \"\",\n): string | null {\n if (previousNextUrl === null) {\n return null;\n }\n\n const parsedUrl = new URL(previousNextUrl, \"http://localhost\");\n return stripBasePath(parsedUrl.pathname, basePath);\n}\n\ntype ResolveServerActionRequestStateOptions = {\n actionId: string;\n basePath: string;\n elements: AppElements;\n previousNextUrl: string | null;\n};\n\ntype ResolveServerActionRequestStateResult = {\n headers: Headers;\n};\n\n/**\n * Pure: builds the fetch Headers for a server-action POST. Carries the same\n * interception-context and mounted-slots headers the refresh path already\n * sends, so the server-action re-render can rebuild the intercepted tree\n * instead of replacing it with the direct route.\n *\n * Next.js sends `Next-URL: state.previousNextUrl || state.nextUrl` on action\n * POSTs when `hasInterceptionRouteInCurrentTree(state.tree)`. Vinext's\n * X-Vinext-Interception-Context is the equivalent signal for the server-side\n * `findIntercept` lookup.\n */\nexport function resolveServerActionRequestState(\n options: ResolveServerActionRequestStateOptions,\n): ResolveServerActionRequestStateResult {\n const headers = createRscRequestHeaders();\n headers.set(RSC_ACTION_HEADER, options.actionId);\n\n const interceptionContext = resolveInterceptionContextFromPreviousNextUrl(\n options.previousNextUrl,\n options.basePath,\n );\n if (interceptionContext !== null) {\n headers.set(VINEXT_INTERCEPTION_CONTEXT_HEADER, interceptionContext);\n }\n\n const mountedSlotsHeader = getMountedSlotIdsHeader(options.elements);\n if (mountedSlotsHeader !== null) {\n headers.set(VINEXT_MOUNTED_SLOTS_HEADER, mountedSlotsHeader);\n }\n\n return { headers };\n}\n\nexport function resolvePendingNavigationCommitDispositionDecision(options: {\n activeNavigationId: number;\n currentState: AppRouterState;\n pending: PendingNavigationCommit;\n routeManifest?: RouteManifest | null;\n startedNavigationId: number;\n targetHref?: string;\n}): PendingNavigationCommitDispositionDecision {\n const traceFields = createPendingNavigationTraceFields(options);\n\n if (\n options.startedNavigationId !== options.activeNavigationId ||\n options.pending.action.operation.startedVisibleCommitVersion !==\n options.currentState.visibleCommitVersion\n ) {\n return {\n disposition: \"skip\",\n preserveElementIds: [],\n trace: createNavigationTrace(NavigationTraceReasonCodes.staleOperation, traceFields),\n };\n }\n\n return mapNavigationDecisionToPendingDisposition(\n planPendingRootBoundaryFlightResponse({\n currentState: options.currentState,\n pending: options.pending,\n routeManifest: options.routeManifest ?? null,\n targetHref: options.targetHref,\n traceFields,\n }),\n );\n}\n\nfunction createPendingNavigationTraceFields(options: {\n activeNavigationId: number;\n currentState: AppRouterState;\n pending: PendingNavigationCommit;\n startedNavigationId: number;\n targetHref?: string;\n}): NavigationTraceFields {\n return {\n ...createNavigationLifecycleTraceFields({\n activeNavigationId: options.activeNavigationId,\n currentRootLayoutTreePath: options.currentState.rootLayoutTreePath,\n currentVisibleCommitVersion: options.currentState.visibleCommitVersion,\n nextRootLayoutTreePath: options.pending.rootLayoutTreePath,\n startedNavigationId: options.startedNavigationId,\n startedVisibleCommitVersion: options.pending.action.operation.startedVisibleCommitVersion,\n }),\n ...(options.targetHref !== undefined ? { targetHref: options.targetHref } : {}),\n };\n}\n\nfunction createNavigationSnapshotUrl(snapshot: ClientNavigationRenderSnapshot): string {\n const query = snapshot.searchParams.toString();\n return query === \"\" ? snapshot.pathname : `${snapshot.pathname}?${query}`;\n}\n\nfunction createMountedParallelSlotSnapshots(\n elements: AppElements,\n): readonly MountedParallelSlotSnapshotV0[] {\n const snapshots: MountedParallelSlotSnapshotV0[] = [];\n for (const slotId of getMountedSlotIds(elements)) {\n const parsed = AppElementsWire.parseElementKey(slotId);\n if (parsed?.kind !== \"slot\") continue;\n snapshots.push({\n ownerLayoutId: AppElementsWire.encodeLayoutId(parsed.treePath),\n slotId,\n });\n }\n return snapshots;\n}\n\nfunction createVisibleRouteSnapshot(state: AppRouterState): RouteSnapshotV0 {\n const displayUrl = createNavigationSnapshotUrl(state.navigationSnapshot);\n const matchedUrl = normalizeNavigationSnapshotMatchedUrl(state.navigationSnapshot.pathname);\n return {\n displayUrl,\n interception: state.interception,\n interceptionContext: state.interceptionContext,\n layoutIds: state.layoutIds,\n // `displayUrl` preserves the browser-visible URL for decisions and traces.\n // `matchedUrl` uses the route-state canonical pathname, matching the\n // server's segment-decoded representation without changing user-facing\n // navigation state such as usePathname().\n matchedUrl,\n mountedParallelSlots: createMountedParallelSlotSnapshots(state.elements),\n rootBoundaryId: state.rootLayoutTreePath,\n routeId: createRouteSnapshotRouteId({\n interception: state.interception,\n routeId: state.routeId,\n }),\n slotBindings: state.slotBindings,\n };\n}\n\nfunction createPendingRouteSnapshot(pending: PendingNavigationCommit): RouteSnapshotV0 {\n const displayUrl = createNavigationSnapshotUrl(pending.action.navigationSnapshot);\n const matchedUrl = normalizeNavigationSnapshotMatchedUrl(\n pending.action.navigationSnapshot.pathname,\n );\n return {\n displayUrl,\n interception: pending.action.interception,\n interceptionContext: pending.action.interceptionContext,\n layoutIds: pending.action.layoutIds,\n // See createVisibleRouteSnapshot: matchedUrl intentionally models the route\n // identity, not the address bar URL.\n matchedUrl,\n mountedParallelSlots: createMountedParallelSlotSnapshots(pending.action.elements),\n rootBoundaryId: pending.rootLayoutTreePath,\n routeId: createRouteSnapshotRouteId({\n interception: pending.action.interception,\n routeId: pending.routeId,\n }),\n slotBindings: pending.action.slotBindings,\n };\n}\n\nfunction createPendingNavigationOperationToken(options: {\n pending: PendingNavigationCommit;\n routeManifest: RouteManifest | null;\n targetSnapshot: RouteSnapshotV0;\n}): OperationToken {\n return {\n baseVisibleCommitVersion: options.pending.action.operation.startedVisibleCommitVersion,\n deploymentVersion: null,\n graphVersion: options.routeManifest?.graphVersion ?? null,\n lane: options.pending.action.operation.lane,\n operationId: options.pending.action.operation.id,\n targetSnapshotFingerprint: createRootBoundarySnapshotFingerprint(options.targetSnapshot),\n };\n}\n\nfunction createRootBoundarySnapshotFingerprint(snapshot: RouteSnapshotV0): string {\n return `${snapshot.routeId}|root:${snapshot.rootBoundaryId ?? \"unknown\"}`;\n}\n\nfunction planPendingRootBoundaryFlightResponse(options: {\n currentState: AppRouterState;\n pending: PendingNavigationCommit;\n routeManifest: RouteManifest | null;\n targetHref?: string;\n traceFields: NavigationTraceFields;\n}): NavigationDecisionV0 {\n const targetSnapshot = createPendingRouteSnapshot(options.pending);\n const token = createPendingNavigationOperationToken({\n pending: options.pending,\n routeManifest: options.routeManifest,\n targetSnapshot,\n });\n const cacheEntryReuseProof = options.pending.cacheEntryReuseProof;\n\n // #726-CORE-07/08 keeps the browser state layer as the lifecycle gate and\n // only translates committed AppElements metadata into planner snapshots.\n // RouteManifest now supplies graph-owned route topology while snapshots\n // continue to carry runtime state such as visible slot content.\n return navigationPlanner.plan({\n routeManifest: options.routeManifest,\n state: {\n nextOperationToken: token,\n traceFields: options.traceFields,\n visibleCommitVersion: options.currentState.visibleCommitVersion,\n visibleSnapshot: createVisibleRouteSnapshot(options.currentState),\n },\n event: {\n kind: \"flightResponseArrived\",\n result: {\n ...(cacheEntryReuseProof ? { cacheEntryReuseProof } : {}),\n // Approval call sites must pass the executor's targetHref so the\n // planner trace and future hard-nav executor agree with the browser\n // URL. The fallback remains for lower-level tests and direct disposition\n // callers that exercise only snapshot-derived planner semantics.\n href: options.targetHref ?? targetSnapshot.displayUrl,\n targetSnapshot,\n },\n token,\n },\n });\n}\n\nfunction mapNavigationDecisionToPendingDisposition(\n decision: NavigationDecisionV0,\n): PendingNavigationCommitDispositionDecision {\n switch (decision.kind) {\n case \"proposeCommit\":\n return {\n disposition: \"dispatch\",\n preserveAbsentSlots: decision.proposal.preserveAbsentSlots,\n preserveElementIds: decision.proposal.preserveElementIds,\n preservePreviousSlotIds: decision.proposal.preservePreviousSlotIds,\n trace: decision.trace,\n };\n case \"hardNavigate\":\n return { disposition: \"hard-navigate\", preserveElementIds: [], trace: decision.trace };\n case \"noCommit\":\n return { disposition: \"skip\", preserveElementIds: [], trace: decision.trace };\n case \"requestWork\":\n throw new Error(\n `[vinext] Root-boundary commit planning returned requestWork (${decision.work.kind}); flightResponseArrived should never request work`,\n );\n default: {\n const _exhaustive: never = decision;\n throw new Error(\"[vinext] Unknown navigation decision: \" + String(_exhaustive));\n }\n }\n}\n\nexport async function createPendingNavigationCommit(options: {\n currentState: AppRouterState;\n nextElements: Promise<AppElements>;\n navigationSnapshot: ClientNavigationRenderSnapshot;\n operationLane: OperationLane;\n payloadOrigin: AppNavigationPayloadOrigin;\n // Advisory: non-intercepted responses clear this even when callers pass the\n // current visible previousNextUrl.\n previousNextUrl?: string | null;\n renderId: number;\n type: \"navigate\" | \"replace\" | \"traverse\";\n}): Promise<PendingNavigationCommit> {\n const elements = await options.nextElements;\n const metadata = AppElementsWire.readMetadata(elements);\n const cacheEntryReuseProof =\n metadata.cacheEntryReuseProof ??\n (requiresCacheEntryReuseProof(options.payloadOrigin)\n ? createCacheEntryReuseProof(null)\n : undefined);\n const requestedPreviousNextUrl =\n options.previousNextUrl !== undefined\n ? options.previousNextUrl\n : options.currentState.previousNextUrl;\n const previousNextUrl = metadata.interception === null ? null : requestedPreviousNextUrl;\n\n return {\n action: {\n ...(cacheEntryReuseProof ? { cacheEntryReuseProof } : {}),\n elements,\n interception: metadata.interception,\n interceptionContext: metadata.interceptionContext,\n layoutIds: metadata.layoutIds,\n layoutFlags: metadata.layoutFlags,\n slotBindings: metadata.slotBindings,\n navigationSnapshot: options.navigationSnapshot,\n operation: createOperationRecord({\n id: options.renderId,\n lane: options.operationLane,\n startedVisibleCommitVersion: options.currentState.visibleCommitVersion,\n }),\n previousNextUrl,\n renderId: options.renderId,\n rootLayoutTreePath: metadata.rootLayoutTreePath,\n routeId: metadata.routeId,\n type: options.type,\n },\n // Convenience aliases — always equal their action.* counterparts.\n ...(cacheEntryReuseProof ? { cacheEntryReuseProof } : {}),\n interception: metadata.interception,\n interceptionContext: metadata.interceptionContext,\n previousNextUrl,\n rootLayoutTreePath: metadata.rootLayoutTreePath,\n routeId: metadata.routeId,\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,35 +1,27 @@
|
|
|
1
|
+
import { NavigationRuntimeSnapshot } from "../client/navigation-runtime.js";
|
|
1
2
|
import { RSC_FORM_STATE_GLOBAL } from "./app-browser-hydration.js";
|
|
3
|
+
import { RscEmbeddedChunk } from "./app-rsc-embedded-chunks.js";
|
|
2
4
|
import { ReactFormState } from "react-dom/client";
|
|
3
5
|
|
|
4
6
|
//#region src/server/app-browser-stream.d.ts
|
|
5
|
-
type NavigationSnapshot = {
|
|
6
|
-
pathname: string;
|
|
7
|
-
searchParams: [string, string][];
|
|
8
|
-
};
|
|
9
|
-
type LegacyRscEmbedData = {
|
|
10
|
-
rsc: string[];
|
|
11
|
-
params?: Record<string, string | string[]>;
|
|
12
|
-
nav?: NavigationSnapshot;
|
|
13
|
-
};
|
|
14
7
|
type VinextBrowserGlobals = {
|
|
15
|
-
|
|
16
|
-
__VINEXT_RSC_CHUNKS__?: string[];
|
|
8
|
+
__VINEXT_RSC_CHUNKS__?: RscEmbeddedChunk[];
|
|
17
9
|
__VINEXT_RSC_DONE__?: boolean;
|
|
18
10
|
[RSC_FORM_STATE_GLOBAL]?: ReactFormState;
|
|
19
11
|
__VINEXT_RSC_PARAMS__?: Record<string, string | string[]>;
|
|
20
|
-
__VINEXT_RSC_NAV__?:
|
|
12
|
+
__VINEXT_RSC_NAV__?: NavigationRuntimeSnapshot;
|
|
21
13
|
};
|
|
22
14
|
declare function getVinextBrowserGlobal(): typeof globalThis & VinextBrowserGlobals;
|
|
23
15
|
/**
|
|
24
|
-
* Convert embedded
|
|
16
|
+
* Convert embedded chunks back to a ReadableStream of Uint8Array chunks.
|
|
25
17
|
*/
|
|
26
|
-
declare function chunksToReadableStream(chunks: readonly
|
|
18
|
+
declare function chunksToReadableStream(chunks: readonly RscEmbeddedChunk[]): ReadableStream<Uint8Array>;
|
|
27
19
|
/**
|
|
28
20
|
* Create a ReadableStream from progressively-embedded RSC chunks.
|
|
29
21
|
*
|
|
30
|
-
* The server pushes chunks into
|
|
31
|
-
* tags. We monkey-patch `push()` so new chunks stream to React
|
|
32
|
-
* instead of polling with setTimeout.
|
|
22
|
+
* The server pushes chunks into the typed navigation runtime via inline
|
|
23
|
+
* <script> tags. We monkey-patch `push()` so new chunks stream to React
|
|
24
|
+
* immediately instead of polling with setTimeout.
|
|
33
25
|
*/
|
|
34
26
|
declare function createProgressiveRscStream(): ReadableStream<Uint8Array>;
|
|
35
27
|
//#endregion
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { ensureNavigationRuntimeRscBootstrap, getNavigationRuntime } from "../client/navigation-runtime.js";
|
|
2
|
+
import { decodeRscEmbeddedChunk } from "./app-rsc-embedded-chunks.js";
|
|
1
3
|
//#region src/server/app-browser-stream.ts
|
|
2
4
|
function getVinextBrowserGlobal() {
|
|
3
5
|
return globalThis;
|
|
@@ -6,29 +8,31 @@ function createUnexpectedRscStreamCloseError() {
|
|
|
6
8
|
return /* @__PURE__ */ new Error("The connection to the page was unexpectedly closed, possibly due to the stop button being clicked, loss of Wi-Fi, or an unstable internet connection.");
|
|
7
9
|
}
|
|
8
10
|
/**
|
|
9
|
-
* Convert embedded
|
|
11
|
+
* Convert embedded chunks back to a ReadableStream of Uint8Array chunks.
|
|
10
12
|
*/
|
|
11
13
|
function chunksToReadableStream(chunks) {
|
|
12
|
-
const encoder = new TextEncoder();
|
|
13
14
|
return new ReadableStream({ start(controller) {
|
|
14
|
-
for (const chunk of chunks) controller.enqueue(
|
|
15
|
+
for (const chunk of chunks) controller.enqueue(decodeRscEmbeddedChunk(chunk));
|
|
15
16
|
controller.close();
|
|
16
17
|
} });
|
|
17
18
|
}
|
|
19
|
+
function getNavigationRuntimeRscBootstrap() {
|
|
20
|
+
return getNavigationRuntime()?.bootstrap.rsc ?? null;
|
|
21
|
+
}
|
|
18
22
|
/**
|
|
19
23
|
* Create a ReadableStream from progressively-embedded RSC chunks.
|
|
20
24
|
*
|
|
21
|
-
* The server pushes chunks into
|
|
22
|
-
* tags. We monkey-patch `push()` so new chunks stream to React
|
|
23
|
-
* instead of polling with setTimeout.
|
|
25
|
+
* The server pushes chunks into the typed navigation runtime via inline
|
|
26
|
+
* <script> tags. We monkey-patch `push()` so new chunks stream to React
|
|
27
|
+
* immediately instead of polling with setTimeout.
|
|
24
28
|
*/
|
|
25
29
|
function createProgressiveRscStream() {
|
|
26
|
-
const encoder = new TextEncoder();
|
|
27
30
|
return new ReadableStream({ start(controller) {
|
|
28
31
|
const vinext = getVinextBrowserGlobal();
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
const runtimeRsc = getNavigationRuntimeRscBootstrap();
|
|
33
|
+
const initialChunks = runtimeRsc?.rsc ?? vinext.__VINEXT_RSC_CHUNKS__ ?? [];
|
|
34
|
+
for (const chunk of initialChunks) controller.enqueue(decodeRscEmbeddedChunk(chunk));
|
|
35
|
+
if (runtimeRsc?.done || vinext.__VINEXT_RSC_DONE__) {
|
|
32
36
|
controller.close();
|
|
33
37
|
return;
|
|
34
38
|
}
|
|
@@ -53,12 +57,13 @@ function createProgressiveRscStream() {
|
|
|
53
57
|
controller.error(createUnexpectedRscStreamCloseError());
|
|
54
58
|
}
|
|
55
59
|
};
|
|
56
|
-
const
|
|
60
|
+
const liveRuntimeRsc = getNavigationRuntime() === null ? null : ensureNavigationRuntimeRscBootstrap();
|
|
61
|
+
const arr = liveRuntimeRsc?.rsc ?? (vinext.__VINEXT_RSC_CHUNKS__ ??= []);
|
|
57
62
|
arr.push = function(...chunks) {
|
|
58
63
|
const length = Array.prototype.push.apply(this, chunks);
|
|
59
64
|
if (closed) return length;
|
|
60
|
-
for (const chunk of chunks) controller.enqueue(
|
|
61
|
-
if (vinext.__VINEXT_RSC_DONE__) closeOnce();
|
|
65
|
+
for (const chunk of chunks) controller.enqueue(decodeRscEmbeddedChunk(chunk));
|
|
66
|
+
if (liveRuntimeRsc?.done || vinext.__VINEXT_RSC_DONE__) closeOnce();
|
|
62
67
|
return length;
|
|
63
68
|
};
|
|
64
69
|
if (typeof document !== "undefined") if (document.readyState === "loading") {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-browser-stream.js","names":[],"sources":["../../src/server/app-browser-stream.ts"],"sourcesContent":["import type { ReactFormState } from \"react-dom/client\";\nimport { RSC_FORM_STATE_GLOBAL } from \"./app-browser-hydration.js\";\
|
|
1
|
+
{"version":3,"file":"app-browser-stream.js","names":[],"sources":["../../src/server/app-browser-stream.ts"],"sourcesContent":["import type { ReactFormState } from \"react-dom/client\";\nimport {\n ensureNavigationRuntimeRscBootstrap,\n getNavigationRuntime,\n type NavigationRuntimeRscBootstrap,\n type NavigationRuntimeSnapshot,\n} from \"../client/navigation-runtime.js\";\nimport { RSC_FORM_STATE_GLOBAL } from \"./app-browser-hydration.js\";\nimport { decodeRscEmbeddedChunk, type RscEmbeddedChunk } from \"./app-rsc-embedded-chunks.js\";\n\ntype VinextBrowserGlobals = {\n __VINEXT_RSC_CHUNKS__?: RscEmbeddedChunk[];\n __VINEXT_RSC_DONE__?: boolean;\n [RSC_FORM_STATE_GLOBAL]?: ReactFormState;\n __VINEXT_RSC_PARAMS__?: Record<string, string | string[]>;\n __VINEXT_RSC_NAV__?: NavigationRuntimeSnapshot;\n};\n\nexport function getVinextBrowserGlobal(): typeof globalThis & VinextBrowserGlobals {\n return globalThis as typeof globalThis & VinextBrowserGlobals;\n}\n\nfunction createUnexpectedRscStreamCloseError(): Error {\n return new Error(\n \"The connection to the page was unexpectedly closed, possibly due to the stop button being clicked, loss of Wi-Fi, or an unstable internet connection.\",\n );\n}\n\n/**\n * Convert embedded chunks back to a ReadableStream of Uint8Array chunks.\n */\nexport function chunksToReadableStream(\n chunks: readonly RscEmbeddedChunk[],\n): ReadableStream<Uint8Array> {\n return new ReadableStream<Uint8Array>({\n start(controller) {\n for (const chunk of chunks) {\n controller.enqueue(decodeRscEmbeddedChunk(chunk));\n }\n controller.close();\n },\n });\n}\n\nfunction getNavigationRuntimeRscBootstrap(): NavigationRuntimeRscBootstrap | null {\n return getNavigationRuntime()?.bootstrap.rsc ?? null;\n}\n\n/**\n * Create a ReadableStream from progressively-embedded RSC chunks.\n *\n * The server pushes chunks into the typed navigation runtime via inline\n * <script> tags. We monkey-patch `push()` so new chunks stream to React\n * immediately instead of polling with setTimeout.\n */\nexport function createProgressiveRscStream(): ReadableStream<Uint8Array> {\n return new ReadableStream<Uint8Array>({\n start(controller) {\n const vinext = getVinextBrowserGlobal();\n const runtimeRsc = getNavigationRuntimeRscBootstrap();\n const initialChunks = runtimeRsc?.rsc ?? vinext.__VINEXT_RSC_CHUNKS__ ?? [];\n\n for (const chunk of initialChunks) {\n controller.enqueue(decodeRscEmbeddedChunk(chunk));\n }\n\n if (runtimeRsc?.done || vinext.__VINEXT_RSC_DONE__) {\n controller.close();\n return;\n }\n\n let closed = false;\n let cancelDocumentCompletionCheck: (() => void) | undefined;\n const cancelPendingDocumentCompletionCheck = () => {\n const cancel = cancelDocumentCompletionCheck;\n cancelDocumentCompletionCheck = undefined;\n cancel?.();\n };\n const closeOnce = () => {\n if (!closed) {\n closed = true;\n cancelPendingDocumentCompletionCheck();\n controller.close();\n }\n };\n const errorOnce = () => {\n if (!closed) {\n closed = true;\n cancelPendingDocumentCompletionCheck();\n controller.error(createUnexpectedRscStreamCloseError());\n }\n };\n\n const liveRuntimeRsc =\n getNavigationRuntime() === null ? null : ensureNavigationRuntimeRscBootstrap();\n const arr = liveRuntimeRsc?.rsc ?? (vinext.__VINEXT_RSC_CHUNKS__ ??= []);\n // Capture the bootstrap object before it can be cleared. Inline done\n // scripts mutate this same object, and clearing happens only after the\n // stream has already been consumed or closed.\n arr.push = function (...chunks: RscEmbeddedChunk[]): number {\n const length = Array.prototype.push.apply(this, chunks);\n\n if (closed) return length;\n\n for (const chunk of chunks) {\n controller.enqueue(decodeRscEmbeddedChunk(chunk));\n }\n\n if (liveRuntimeRsc?.done || vinext.__VINEXT_RSC_DONE__) {\n closeOnce();\n }\n\n return length;\n };\n\n if (typeof document !== \"undefined\") {\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", errorOnce);\n cancelDocumentCompletionCheck = () =>\n document.removeEventListener(\"DOMContentLoaded\", errorOnce);\n } else {\n const timeoutId = setTimeout(errorOnce);\n cancelDocumentCompletionCheck = () => clearTimeout(timeoutId);\n }\n }\n },\n });\n}\n"],"mappings":";;;AAkBA,SAAgB,yBAAmE;CACjF,OAAO;;AAGT,SAAS,sCAA6C;CACpD,uBAAO,IAAI,MACT,wJACD;;;;;AAMH,SAAgB,uBACd,QAC4B;CAC5B,OAAO,IAAI,eAA2B,EACpC,MAAM,YAAY;EAChB,KAAK,MAAM,SAAS,QAClB,WAAW,QAAQ,uBAAuB,MAAM,CAAC;EAEnD,WAAW,OAAO;IAErB,CAAC;;AAGJ,SAAS,mCAAyE;CAChF,OAAO,sBAAsB,EAAE,UAAU,OAAO;;;;;;;;;AAUlD,SAAgB,6BAAyD;CACvE,OAAO,IAAI,eAA2B,EACpC,MAAM,YAAY;EAChB,MAAM,SAAS,wBAAwB;EACvC,MAAM,aAAa,kCAAkC;EACrD,MAAM,gBAAgB,YAAY,OAAO,OAAO,yBAAyB,EAAE;EAE3E,KAAK,MAAM,SAAS,eAClB,WAAW,QAAQ,uBAAuB,MAAM,CAAC;EAGnD,IAAI,YAAY,QAAQ,OAAO,qBAAqB;GAClD,WAAW,OAAO;GAClB;;EAGF,IAAI,SAAS;EACb,IAAI;EACJ,MAAM,6CAA6C;GACjD,MAAM,SAAS;GACf,gCAAgC,KAAA;GAChC,UAAU;;EAEZ,MAAM,kBAAkB;GACtB,IAAI,CAAC,QAAQ;IACX,SAAS;IACT,sCAAsC;IACtC,WAAW,OAAO;;;EAGtB,MAAM,kBAAkB;GACtB,IAAI,CAAC,QAAQ;IACX,SAAS;IACT,sCAAsC;IACtC,WAAW,MAAM,qCAAqC,CAAC;;;EAI3D,MAAM,iBACJ,sBAAsB,KAAK,OAAO,OAAO,qCAAqC;EAChF,MAAM,MAAM,gBAAgB,QAAQ,OAAO,0BAA0B,EAAE;EAIvE,IAAI,OAAO,SAAU,GAAG,QAAoC;GAC1D,MAAM,SAAS,MAAM,UAAU,KAAK,MAAM,MAAM,OAAO;GAEvD,IAAI,QAAQ,OAAO;GAEnB,KAAK,MAAM,SAAS,QAClB,WAAW,QAAQ,uBAAuB,MAAM,CAAC;GAGnD,IAAI,gBAAgB,QAAQ,OAAO,qBACjC,WAAW;GAGb,OAAO;;EAGT,IAAI,OAAO,aAAa,aACtB,IAAI,SAAS,eAAe,WAAW;GACrC,SAAS,iBAAiB,oBAAoB,UAAU;GACxD,sCACE,SAAS,oBAAoB,oBAAoB,UAAU;SACxD;GACL,MAAM,YAAY,WAAW,UAAU;GACvC,sCAAsC,aAAa,UAAU;;IAIpE,CAAC"}
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
+
import { RouteManifest } from "../routing/app-route-graph.js";
|
|
1
2
|
import { ClientNavigationRenderSnapshot } from "../shims/navigation.js";
|
|
2
3
|
import { AppElements } from "./app-elements-wire.js";
|
|
3
4
|
import { NavigationTrace } from "./navigation-trace.js";
|
|
4
5
|
import { OperationLane } from "./navigation-planner.js";
|
|
5
|
-
import { AppRouterAction, AppRouterState, PendingNavigationCommit } from "./app-browser-state.js";
|
|
6
|
+
import { AppNavigationPayloadOrigin, AppRouterAction, AppRouterState, PendingNavigationCommit } from "./app-browser-state.js";
|
|
6
7
|
|
|
7
8
|
//#region src/server/app-browser-visible-commit.d.ts
|
|
8
9
|
type VisibleCommitDecision = {
|
|
9
10
|
disposition: "commit";
|
|
10
11
|
preserveAbsentSlots: boolean;
|
|
11
12
|
preserveElementIds: readonly string[];
|
|
13
|
+
preservePreviousSlotIds: readonly string[];
|
|
12
14
|
trace: NavigationTrace;
|
|
13
15
|
};
|
|
14
16
|
type HardNavigateCommitDecision = {
|
|
@@ -25,6 +27,7 @@ type ApprovedVisibleCommit = {
|
|
|
25
27
|
readonly [approvedVisibleCommitBrand]: true;
|
|
26
28
|
readonly action: AppRouterAction;
|
|
27
29
|
readonly decision: VisibleCommitDecision;
|
|
30
|
+
readonly interception: AppRouterAction["interception"];
|
|
28
31
|
readonly interceptionContext: string | null;
|
|
29
32
|
readonly previousNextUrl: string | null;
|
|
30
33
|
readonly rootLayoutTreePath: string | null;
|
|
@@ -51,6 +54,7 @@ declare function approvePendingNavigationCommit(options: {
|
|
|
51
54
|
activeNavigationId: number;
|
|
52
55
|
currentState: AppRouterState;
|
|
53
56
|
pending: PendingNavigationCommit;
|
|
57
|
+
routeManifest?: RouteManifest | null;
|
|
54
58
|
startedNavigationId: number;
|
|
55
59
|
targetHref: string;
|
|
56
60
|
}): CommitApproval;
|
|
@@ -62,8 +66,10 @@ declare function resolveAndClassifyNavigationCommit(options: {
|
|
|
62
66
|
navigationSnapshot: ClientNavigationRenderSnapshot;
|
|
63
67
|
nextElements: Promise<AppElements>;
|
|
64
68
|
operationLane: OperationLane;
|
|
69
|
+
payloadOrigin: AppNavigationPayloadOrigin;
|
|
65
70
|
previousNextUrl?: string | null;
|
|
66
71
|
renderId: number;
|
|
72
|
+
routeManifest?: RouteManifest | null;
|
|
67
73
|
startedNavigationId: number;
|
|
68
74
|
targetHref: string;
|
|
69
75
|
type: "navigate" | "replace" | "traverse";
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { normalizeAppElementsSlotBindings } from "./app-elements-wire.js";
|
|
2
|
+
import "./app-elements.js";
|
|
1
3
|
import { mergeElements } from "../shims/slot.js";
|
|
2
4
|
import { NavigationTraceReasonCodes, NavigationTraceTransactionCodes, createNavigationTrace, prependNavigationTraceEntry } from "./navigation-trace.js";
|
|
3
5
|
import { createPendingNavigationCommit, resolvePendingNavigationCommitDispositionDecision } from "./app-browser-state.js";
|
|
@@ -27,6 +29,28 @@ function commitVisibleRouterState(state, nextState, operation) {
|
|
|
27
29
|
visibleCommitVersion
|
|
28
30
|
};
|
|
29
31
|
}
|
|
32
|
+
function mergeSlotBindings(previousBindings, nextBindings, layoutIds, preservePreviousSlotIds) {
|
|
33
|
+
if (preservePreviousSlotIds.length === 0) return nextBindings;
|
|
34
|
+
const preservedSlotIds = new Set(preservePreviousSlotIds);
|
|
35
|
+
const previousBindingsBySlotId = /* @__PURE__ */ new Map();
|
|
36
|
+
for (const binding of previousBindings) {
|
|
37
|
+
if (!preservedSlotIds.has(binding.slotId)) continue;
|
|
38
|
+
previousBindingsBySlotId.set(binding.slotId, binding);
|
|
39
|
+
}
|
|
40
|
+
const mergedBindings = [];
|
|
41
|
+
const seenSlotIds = /* @__PURE__ */ new Set();
|
|
42
|
+
for (const binding of nextBindings) {
|
|
43
|
+
const previousBinding = previousBindingsBySlotId.get(binding.slotId);
|
|
44
|
+
mergedBindings.push(previousBinding ?? binding);
|
|
45
|
+
seenSlotIds.add(binding.slotId);
|
|
46
|
+
}
|
|
47
|
+
for (const slotId of preservePreviousSlotIds) {
|
|
48
|
+
if (seenSlotIds.has(slotId)) continue;
|
|
49
|
+
const previousBinding = previousBindingsBySlotId.get(slotId);
|
|
50
|
+
if (previousBinding) mergedBindings.push(previousBinding);
|
|
51
|
+
}
|
|
52
|
+
return normalizeAppElementsSlotBindings(mergedBindings, { layoutIds });
|
|
53
|
+
}
|
|
30
54
|
function reduceApprovedVisibleCommitState(state, commit) {
|
|
31
55
|
const { action } = commit;
|
|
32
56
|
switch (action.type) {
|
|
@@ -35,8 +59,10 @@ function reduceApprovedVisibleCommitState(state, commit) {
|
|
|
35
59
|
elements: mergeElements(state.elements, action.elements, {
|
|
36
60
|
clearAbsentSlots: action.type === "traverse",
|
|
37
61
|
preserveAbsentSlots: commit.decision.preserveAbsentSlots,
|
|
38
|
-
preserveElementIds: commit.decision.preserveElementIds
|
|
62
|
+
preserveElementIds: commit.decision.preserveElementIds,
|
|
63
|
+
preservePreviousSlotIds: commit.decision.preservePreviousSlotIds
|
|
39
64
|
}),
|
|
65
|
+
interception: action.interception,
|
|
40
66
|
interceptionContext: action.interceptionContext,
|
|
41
67
|
layoutFlags: mergeLayoutFlags(state.layoutFlags, action.layoutFlags, commit.decision.preserveElementIds),
|
|
42
68
|
layoutIds: action.layoutIds,
|
|
@@ -44,10 +70,12 @@ function reduceApprovedVisibleCommitState(state, commit) {
|
|
|
44
70
|
previousNextUrl: action.previousNextUrl,
|
|
45
71
|
renderId: action.renderId,
|
|
46
72
|
rootLayoutTreePath: action.rootLayoutTreePath,
|
|
47
|
-
routeId: action.routeId
|
|
73
|
+
routeId: action.routeId,
|
|
74
|
+
slotBindings: mergeSlotBindings(state.slotBindings, action.slotBindings, action.layoutIds, commit.decision.preservePreviousSlotIds)
|
|
48
75
|
}, action.operation);
|
|
49
76
|
case "replace": return commitVisibleRouterState(state, {
|
|
50
77
|
elements: action.elements,
|
|
78
|
+
interception: action.interception,
|
|
51
79
|
interceptionContext: action.interceptionContext,
|
|
52
80
|
layoutFlags: action.layoutFlags,
|
|
53
81
|
layoutIds: action.layoutIds,
|
|
@@ -55,7 +83,8 @@ function reduceApprovedVisibleCommitState(state, commit) {
|
|
|
55
83
|
previousNextUrl: action.previousNextUrl,
|
|
56
84
|
renderId: action.renderId,
|
|
57
85
|
rootLayoutTreePath: action.rootLayoutTreePath,
|
|
58
|
-
routeId: action.routeId
|
|
86
|
+
routeId: action.routeId,
|
|
87
|
+
slotBindings: action.slotBindings
|
|
59
88
|
}, action.operation);
|
|
60
89
|
default: {
|
|
61
90
|
const _exhaustive = action.type;
|
|
@@ -74,15 +103,16 @@ function resolvePendingNavigationCommitDecision(options) {
|
|
|
74
103
|
disposition: "hard-navigate",
|
|
75
104
|
trace: decision.trace
|
|
76
105
|
};
|
|
77
|
-
case "dispatch": return createVisibleCommitDecision(decision.trace, decision.preserveElementIds, decision.preserveAbsentSlots);
|
|
106
|
+
case "dispatch": return createVisibleCommitDecision(decision.trace, decision.preserveElementIds, decision.preserveAbsentSlots, decision.preservePreviousSlotIds);
|
|
78
107
|
default: throw new Error("[vinext] Unknown navigation commit disposition: " + String(decision));
|
|
79
108
|
}
|
|
80
109
|
}
|
|
81
|
-
function createVisibleCommitDecision(trace = createNavigationTrace(NavigationTraceReasonCodes.commitCurrent), preserveElementIds = [], preserveAbsentSlots = false) {
|
|
110
|
+
function createVisibleCommitDecision(trace = createNavigationTrace(NavigationTraceReasonCodes.commitCurrent), preserveElementIds = [], preserveAbsentSlots = false, preservePreviousSlotIds = []) {
|
|
82
111
|
return {
|
|
83
112
|
disposition: "commit",
|
|
84
113
|
preserveAbsentSlots,
|
|
85
114
|
preserveElementIds: [...preserveElementIds],
|
|
115
|
+
preservePreviousSlotIds: [...preservePreviousSlotIds],
|
|
86
116
|
trace
|
|
87
117
|
};
|
|
88
118
|
}
|
|
@@ -100,6 +130,7 @@ function createApprovedVisibleCommit(options) {
|
|
|
100
130
|
[approvedVisibleCommitBrand]: true,
|
|
101
131
|
action: options.pending.action,
|
|
102
132
|
decision: options.decision,
|
|
133
|
+
interception: options.pending.interception,
|
|
103
134
|
interceptionContext: options.pending.interceptionContext,
|
|
104
135
|
previousNextUrl: options.pending.previousNextUrl,
|
|
105
136
|
rootLayoutTreePath: options.pending.rootLayoutTreePath,
|
|
@@ -147,6 +178,7 @@ function approvePendingNavigationCommit(options) {
|
|
|
147
178
|
activeNavigationId: options.activeNavigationId,
|
|
148
179
|
currentState: options.currentState,
|
|
149
180
|
pending: options.pending,
|
|
181
|
+
routeManifest: options.routeManifest ?? null,
|
|
150
182
|
startedNavigationId: options.startedNavigationId,
|
|
151
183
|
targetHref: options.targetHref
|
|
152
184
|
}), options.pending);
|
|
@@ -172,6 +204,7 @@ async function resolveAndClassifyNavigationCommit(options) {
|
|
|
172
204
|
nextElements: options.nextElements,
|
|
173
205
|
navigationSnapshot: options.navigationSnapshot,
|
|
174
206
|
operationLane: options.operationLane,
|
|
207
|
+
payloadOrigin: options.payloadOrigin,
|
|
175
208
|
previousNextUrl: options.previousNextUrl,
|
|
176
209
|
renderId: options.renderId,
|
|
177
210
|
type: options.type
|
|
@@ -181,6 +214,7 @@ async function resolveAndClassifyNavigationCommit(options) {
|
|
|
181
214
|
activeNavigationId: options.getActiveNavigationId?.() ?? options.activeNavigationId,
|
|
182
215
|
currentState: approvalState,
|
|
183
216
|
pending,
|
|
217
|
+
routeManifest: options.routeManifest ?? null,
|
|
184
218
|
startedNavigationId: options.startedNavigationId,
|
|
185
219
|
targetHref: options.targetHref
|
|
186
220
|
});
|