@wular/pnext 0.0.4 → 0.0.6
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/README.md +11 -11
- package/bin/pnext +1 -1
- package/config/lint/base.js +7 -7
- package/config/ts/base.json +2 -4
- package/config/ts/react.json +2 -6
- package/package.json +23 -2
- package/reference/compat.md +1 -1
- package/reference/config.md +2 -2
- package/reference/css.md +13 -9
- package/reference/dev.md +1 -1
- package/reference/metadata.md +7 -7
- package/reference/navigation.md +35 -28
- package/reference/performance.md +70 -70
- package/reference/rendering.md +17 -17
- package/reference/routing.md +17 -17
- package/reference/typegen.md +12 -8
- package/src/api/cache.ts +36 -37
- package/src/api/client-cache.ts +2 -2
- package/src/api/client-navigation.ts +113 -109
- package/src/api/dynamic.tsx +58 -55
- package/src/api/link.tsx +49 -52
- package/src/api/navigation.ts +59 -58
- package/src/api/server.ts +152 -144
- package/src/api/suspense.ts +4 -4
- package/src/cli/adapters/vercel-warm.ts +126 -121
- package/src/cli/adapters/vercel.ts +437 -443
- package/src/cli/analyze.ts +333 -144
- package/src/cli/{named-bin.ts → boot/named-bin.ts} +37 -37
- package/src/cli/{boot-trace.ts → boot/trace.ts} +10 -10
- package/src/cli/build.ts +976 -978
- package/src/cli/create.ts +71 -63
- package/src/cli/dev.ts +116 -116
- package/src/cli/index.ts +88 -85
- package/src/cli/migrate/package-json.ts +73 -71
- package/src/cli/migrate/report.ts +32 -33
- package/src/cli/migrate/{index.ts → run.ts} +48 -49
- package/src/cli/migrate/scan.ts +46 -46
- package/src/cli/migrate/spinner.ts +9 -9
- package/src/cli/migrate/tsconfig.ts +35 -35
- package/src/cli/{server-entry.ts → serve/entry.ts} +57 -57
- package/src/cli/{request-pipeline.ts → serve/pipeline.ts} +386 -394
- package/src/cli/{serve-ui.ts → serve/ui.ts} +47 -47
- package/src/cli/start.ts +65 -66
- package/src/{typegen.ts → cli/typegen.ts} +59 -59
- package/src/client/build.ts +794 -768
- package/src/client/chunk-fold.ts +245 -240
- package/src/client/{paths.ts → chunk-name.ts} +6 -6
- package/src/client/entry.ts +162 -147
- package/src/client/prebuilt.ts +231 -223
- package/src/client/profile.ts +29 -29
- package/src/client/react-compiler.ts +20 -15
- package/src/client/{compat-surface.ts → react-tier.ts} +64 -64
- package/src/client/reference-stub.ts +51 -51
- package/src/client/reference.ts +19 -19
- package/src/{api → client}/router/events.ts +17 -17
- package/src/{api → client}/router/history.ts +16 -16
- package/src/{api → client}/router/hub.ts +52 -53
- package/src/{api/router.ts → client/router/index.ts} +61 -60
- package/src/{api → client}/router/policies.ts +24 -24
- package/src/{api → client}/router/runtime.ts +1988 -1992
- package/src/{api → client}/router/types.ts +93 -98
- package/src/compat/actions/client-plugin.ts +42 -43
- package/src/compat/actions/client-stub.ts +14 -14
- package/src/compat/actions/{action-client.ts → client.ts} +194 -193
- package/src/compat/actions/config.ts +63 -64
- package/src/compat/actions/detect.ts +68 -68
- package/src/compat/actions/discovery.ts +105 -105
- package/src/compat/actions/{action-dispatch.ts → dispatch.ts} +277 -274
- package/src/compat/actions/early-submit.ts +1 -1
- package/src/compat/actions/endpoint.ts +198 -198
- package/src/compat/actions/extensions.ts +811 -0
- package/src/compat/actions/flight.ts +23 -23
- package/src/compat/actions/form-state.ts +34 -34
- package/src/compat/actions/hoist.ts +382 -236
- package/src/compat/actions/ids.ts +7 -12
- package/src/compat/actions/index.ts +8 -8
- package/src/compat/actions/instances.ts +46 -46
- package/src/compat/actions/origin.ts +47 -48
- package/src/compat/actions/protocol.ts +22 -22
- package/src/compat/actions/registry.ts +19 -19
- package/src/compat/{misc/action-return.ts → actions/return.ts} +60 -57
- package/src/compat/actions/rewrite.ts +125 -125
- package/src/compat/actions/{action-router.ts → router.ts} +10 -10
- package/src/compat/actions/serve.ts +132 -136
- package/src/compat/actions/server-tag.ts +4 -4
- package/src/compat/actions/{action-shared.ts → shared.ts} +34 -34
- package/src/compat/actions/unrecognized-error.ts +4 -4
- package/src/compat/{index.ts → aliases.ts} +112 -109
- package/src/compat/bundler/bun-externals.ts +18 -18
- package/src/compat/bundler/cjs-exports.ts +271 -223
- package/src/compat/bundler/config.ts +116 -111
- package/src/compat/bundler/externals.ts +12 -12
- package/src/compat/bundler/import-meta-url.ts +19 -19
- package/src/compat/bundler/modularize-imports.ts +36 -33
- package/src/compat/bundler/new-url-asset.ts +22 -24
- package/src/compat/bundler/optimize-package-imports.ts +111 -107
- package/src/compat/bundler/polyfill.ts +28 -28
- package/src/compat/bundler/react-compiler.ts +35 -29
- package/src/compat/bundler/react-profiler.tsx +11 -11
- package/src/compat/bundler/relay-transform.ts +48 -47
- package/src/compat/bundler/require-context.ts +119 -113
- package/src/compat/bundler/resolve-extensions.ts +19 -19
- package/src/compat/bundler/source-cache.ts +25 -25
- package/src/compat/bundler/static-imports.ts +7 -7
- package/src/compat/bundler/symlink-imports.ts +46 -46
- package/src/compat/bundler/tsconfig-paths.ts +13 -15
- package/src/compat/bundler/wasm.ts +58 -60
- package/src/compat/bundler/webpack-loaders.ts +254 -241
- package/src/compat/bundler/worker.ts +101 -104
- package/src/compat/cache/build-flags.ts +29 -29
- package/src/compat/cache/build-prerender-errors.ts +40 -44
- package/src/compat/cache/custom-handler.ts +60 -53
- package/src/compat/cache/fetch-patch.ts +240 -240
- package/src/compat/cache/handler.ts +27 -31
- package/src/compat/cache/modern-handler.ts +148 -126
- package/src/compat/cache/resume-data-cache.ts +47 -45
- package/src/compat/cache/revalidate.ts +233 -232
- package/src/compat/cache/runtime-error.ts +35 -35
- package/src/compat/cache/use-cache-transform.ts +442 -417
- package/src/compat/cache/use-cache.ts +650 -614
- package/src/compat/cache-control.ts +140 -142
- package/src/compat/client/base-path.ts +21 -20
- package/src/compat/client/css-order.ts +18 -18
- package/src/compat/client/errors/bare-boundary.ts +11 -11
- package/src/compat/client/errors/control-flow.ts +23 -23
- package/src/compat/client/errors/error-boundary.ts +61 -61
- package/src/compat/client/errors/global-error.ts +101 -91
- package/src/compat/client/errors/install.ts +71 -72
- package/src/compat/client/errors/lazy.ts +23 -23
- package/src/compat/client/errors/primitive-throw.ts +47 -45
- package/src/compat/client/errors/soft-refresh.ts +4 -4
- package/src/compat/client/link-status.ts +33 -33
- package/src/compat/client/{nav-compat-runtime.ts → nav-runtime.ts} +20 -20
- package/src/compat/client/{nav-compat.ts → nav.ts} +12 -13
- package/src/compat/client/navigation-scroll.ts +63 -63
- package/src/compat/client/optimistic-routing.ts +93 -88
- package/src/compat/client/prefetch-cache.ts +23 -24
- package/src/compat/client/route-announcer.ts +35 -35
- package/src/compat/client/segment-cache-policy.ts +20 -20
- package/src/compat/client/segment-cache.ts +309 -315
- package/src/compat/client/segment-prefetch.ts +127 -132
- package/src/compat/client/trailing-slash.ts +5 -4
- package/src/compat/css/chunking.ts +113 -116
- package/src/compat/css/inline-css.ts +21 -21
- package/src/compat/css/lightningcss.ts +37 -38
- package/src/compat/css/modules.ts +161 -175
- package/src/compat/css/nonce.ts +7 -7
- package/src/compat/css/sass-plugin.ts +18 -21
- package/src/compat/css/sass.ts +150 -152
- package/src/compat/css/styled-jsx-runtime.ts +27 -27
- package/src/compat/css/styled-jsx.ts +21 -21
- package/src/compat/edge-runtime.ts +27 -27
- package/src/compat/{adapter → export}/build-complete.ts +72 -75
- package/src/compat/export/client.ts +29 -31
- package/src/compat/export/{index.ts → emit.ts} +111 -110
- package/src/compat/export/standalone.ts +62 -54
- package/src/compat/image-optimizer/cache.ts +51 -49
- package/src/compat/image-optimizer/detect.ts +52 -52
- package/src/compat/image-optimizer/{index.ts → optimize.ts} +189 -194
- package/src/compat/image-optimizer/source.ts +77 -80
- package/src/compat/lifecycle/after-scope.ts +26 -26
- package/src/compat/lifecycle/after.ts +48 -45
- package/src/compat/lifecycle/error-funnel.ts +98 -102
- package/src/compat/lifecycle/error-serialize.ts +30 -26
- package/src/compat/lifecycle/error-ui.ts +67 -32
- package/src/compat/lifecycle/instrumentation-client.ts +36 -38
- package/src/compat/lifecycle/instrumentation.ts +85 -85
- package/src/compat/lifecycle/node-console.ts +11 -11
- package/src/compat/lifecycle/testmode.ts +160 -132
- package/src/compat/mdx/compile.ts +60 -57
- package/src/compat/mdx/plugin.ts +11 -11
- package/src/compat/mdx/{next-mdx-stub.ts → stub.ts} +5 -5
- package/src/compat/{metadata-route-artifacts.ts → metadata-artifacts.ts} +195 -191
- package/src/compat/metadata.ts +75 -81
- package/src/compat/next/cache.ts +68 -69
- package/src/compat/next/canonical-url.ts +9 -9
- package/src/compat/next/client-cache.ts +19 -19
- package/src/compat/next/client-navigation.ts +112 -116
- package/src/compat/next/client-only.ts +1 -1
- package/src/compat/next/client-script.tsx +99 -93
- package/src/compat/next/client-server.ts +10 -10
- package/src/compat/next/config-loader.ts +176 -173
- package/src/compat/next/config.ts +7 -7
- package/src/compat/next/constants.cjs +6 -6
- package/src/compat/next/constants.ts +6 -6
- package/src/compat/next/custom-server.ts +26 -24
- package/src/compat/next/dist/client/components/app-router-headers.ts +21 -21
- package/src/compat/next/dist/server/app-render/work-unit-async-storage.external.cjs +3 -4
- package/src/compat/next/dist/server/web/spec-extension/revalidate.ts +1 -1
- package/src/compat/next/dist/server/web/spec-extension/unstable-cache.ts +1 -1
- package/src/compat/next/dist/server/web/spec-extension/unstable-no-store.ts +1 -1
- package/src/compat/next/dynamic.tsx +21 -18
- package/src/compat/next/error.tsx +52 -52
- package/src/compat/next/font/cache.ts +74 -74
- package/src/compat/next/font/google.ts +2 -2
- package/src/compat/next/font/index.ts +1 -1
- package/src/compat/next/font/local.ts +3 -3
- package/src/compat/next/font/runtime-client.ts +17 -15
- package/src/compat/next/font/runtime.ts +443 -408
- package/src/compat/next/font/shared.ts +120 -108
- package/src/compat/next/form.tsx +63 -63
- package/src/compat/next/head.tsx +2 -2
- package/src/compat/next/headers.ts +103 -95
- package/src/compat/next/image/client.tsx +220 -0
- package/src/compat/next/image/config.ts +56 -58
- package/src/compat/next/image/optimizer.ts +40 -36
- package/src/compat/next/image/patterns.ts +37 -40
- package/src/compat/next/{image-props.ts → image/props.ts} +208 -202
- package/src/compat/next/image/shared.ts +65 -57
- package/src/compat/next/image/static-metadata.ts +98 -107
- package/src/compat/next/image/validate.ts +79 -88
- package/src/compat/next/image.tsx +19 -23
- package/src/compat/next/index.ts +1 -1
- package/src/compat/next/legacy-image.tsx +59 -60
- package/src/compat/next/{link-validation-transform.ts → link-transform.ts} +95 -96
- package/src/compat/next/link.tsx +158 -158
- package/src/compat/next/navigation.cjs +12 -3
- package/src/compat/next/navigation.ts +48 -50
- package/src/compat/next/offline.ts +27 -27
- package/src/compat/next/og.ts +121 -124
- package/src/compat/next/preferred-region.ts +13 -14
- package/src/compat/next/redirects.ts +58 -56
- package/src/compat/next/resource-hints.ts +73 -76
- package/src/compat/next/rewrites.ts +130 -133
- package/src/compat/next/root-params.ts +45 -45
- package/src/compat/next/{optimistic-route-state.ts → route-state.ts} +52 -52
- package/src/compat/next/router.cjs +4 -2
- package/src/compat/next/router.ts +58 -61
- package/src/compat/next/script.tsx +108 -108
- package/src/compat/next/server-only.ts +1 -1
- package/src/compat/next/server.ts +19 -19
- package/src/compat/next/svgr.ts +18 -17
- package/src/compat/next/telemetry.ts +24 -24
- package/src/compat/next/{image-usage.ts → usage.ts} +70 -39
- package/src/compat/next/user-agent.ts +53 -49
- package/src/compat/next/web-vitals.ts +22 -24
- package/src/compat/otel/api.ts +41 -41
- package/src/compat/otel/client-trace-metadata.ts +25 -27
- package/src/compat/otel/fetch-span.ts +29 -29
- package/src/compat/otel/tracer.ts +331 -331
- package/src/compat/pages/api.ts +456 -0
- package/src/compat/pages/client-plugin.ts +36 -36
- package/src/compat/pages/router-state.ts +34 -34
- package/src/compat/pages/{index.ts → router.ts} +130 -135
- package/src/compat/ppr/io.ts +12 -12
- package/src/compat/ppr/missing-root-params.ts +34 -38
- package/src/compat/ppr/root-params-scan.ts +66 -66
- package/src/compat/ppr/root-params-transform.ts +24 -26
- package/src/compat/ppr/root-params.ts +30 -30
- package/src/compat/ppr/segment-config-incompat.ts +6 -7
- package/src/compat/protocol.ts +71 -70
- package/src/compat/react/action-state.ts +47 -48
- package/src/compat/react/client-lite.ts +15 -15
- package/src/compat/react/client.ts +4 -4
- package/src/compat/react/compiler-runtime.ts +11 -11
- package/src/compat/react/dom-client.ts +44 -44
- package/src/compat/react/dom-react-server.ts +10 -16
- package/src/compat/react/dom-server.ts +10 -10
- package/src/compat/react/dom.ts +52 -52
- package/src/compat/react/hooks-extra.ts +34 -35
- package/src/compat/react/parity.ts +64 -61
- package/src/compat/react/preact.ts +81 -82
- package/src/compat/react/react-server.ts +28 -28
- package/src/compat/react/router-shim.ts +1 -1
- package/src/compat/react/server-component-use.ts +8 -8
- package/src/compat/react/server-inserted-html.ts +30 -31
- package/src/compat/react/server.ts +53 -55
- package/src/compat/react/use.ts +32 -32
- package/src/compat/react/view-transition.ts +20 -20
- package/src/compat/register/actions.ts +35 -824
- package/src/compat/register/boot.ts +41 -41
- package/src/compat/register/build-tier.ts +5 -5
- package/src/compat/register/build.ts +74 -70
- package/src/compat/register/bundler.ts +161 -156
- package/src/compat/register/cache.ts +20 -20
- package/src/compat/register/client-errors.ts +3 -3
- package/src/compat/register/config.ts +6 -6
- package/src/compat/register/css-extras.ts +30 -34
- package/src/compat/register/edge-runtime.ts +3 -3
- package/src/compat/register/errors.ts +10 -12
- package/src/compat/register/export.ts +16 -16
- package/src/compat/register/font.ts +11 -11
- package/src/compat/register/hooks.ts +2 -2
- package/src/compat/register/image.ts +40 -40
- package/src/compat/register/index.ts +59 -62
- package/src/compat/register/instrumentation-client.ts +10 -10
- package/src/compat/register/lifecycle.ts +25 -28
- package/src/compat/register/mdx.ts +10 -10
- package/src/compat/register/middleware.ts +226 -16
- package/src/compat/register/otel.ts +80 -88
- package/src/compat/register/pages-api.ts +10 -463
- package/src/compat/register/ppr.ts +16 -16
- package/src/compat/register/protocol.ts +17 -18
- package/src/compat/register/proxy.ts +49 -51
- package/src/compat/register/render.ts +79 -76
- package/src/compat/register/routing.ts +162 -159
- package/src/compat/register/segment.ts +24 -1897
- package/src/compat/register/static-image.ts +3 -3
- package/src/compat/register/{misc.ts → taint.ts} +9 -9
- package/src/compat/register/typed-routes.ts +14 -14
- package/src/compat/register/{usecache.ts → use-cache.ts} +39 -39
- package/src/compat/register/validation.ts +18 -18
- package/src/compat/segment/loading-boundary.ts +43 -45
- package/src/compat/segment/page-slot.ts +69 -69
- package/src/compat/segment/serve.ts +1884 -0
- package/src/compat/segment/tree.ts +113 -112
- package/src/compat/segment/vary-key.ts +38 -38
- package/src/compat/segment/vary-params.ts +138 -142
- package/src/compat/static-params.ts +14 -12
- package/src/compat/tsconfig-defaults.ts +87 -91
- package/src/compat/typecheck/{index.ts → check.ts} +234 -212
- package/src/compat/typecheck/worker.ts +15 -12
- package/src/compat/typed-routes/{index.ts → generate.ts} +36 -36
- package/src/compat/typed-routes/manifest.ts +174 -170
- package/src/compat/typed-routes/typegen.ts +127 -110
- package/src/compat/validation/errors.ts +16 -19
- package/src/compat/validation/prerender-diagnostics.ts +521 -504
- package/src/compat/validation/{index.ts → validate.ts} +647 -648
- package/src/compat-bootstrap.ts +16 -16
- package/src/config.ts +69 -69
- package/src/css/build.ts +230 -227
- package/src/css/postcss.ts +79 -80
- package/src/css/worker.ts +14 -15
- package/src/dev/client-actions.ts +10 -10
- package/src/dev/client-chunk-store.ts +27 -27
- package/src/dev/{client-key-cache.ts → restart/client-key.ts} +76 -76
- package/src/dev/{restart-cache.ts → restart/enabled.ts} +1 -1
- package/src/dev/{global-css-cache.ts → restart/global-css.ts} +91 -83
- package/src/dev/{node-module-bundle-cache.ts → restart/node-modules.ts} +24 -24
- package/src/dev/{route-bundle-key-cache.ts → restart/route-bundle-key.ts} +53 -53
- package/src/dev/{route-facts-cache.ts → restart/route-facts.ts} +82 -82
- package/src/dev/server.ts +804 -820
- package/src/env.ts +46 -43
- package/src/extensions.ts +491 -478
- package/src/index.ts +8 -8
- package/src/internal.ts +20 -23
- package/src/{islands → render}/boundary-error.ts +3 -3
- package/src/render/hooks.ts +71 -71
- package/src/render/island-context.ts +14 -14
- package/src/render/metadata.ts +310 -310
- package/src/{ppr-postpone.ts → render/postpone.ts} +5 -5
- package/src/{ppr.ts → render/ppr.ts} +244 -245
- package/src/render/renderer.ts +2076 -2082
- package/src/render/resource-hints.ts +16 -17
- package/src/render/slots.tsx +224 -235
- package/src/{islands → render}/static-children.ts +9 -12
- package/src/{islands → render}/static-slots.ts +37 -37
- package/src/{cache/context.ts → request/cache.ts} +20 -20
- package/src/request/context.ts +107 -107
- package/src/{dynamic/source.ts → resolve/dynamic.ts} +139 -139
- package/src/resolve/engine.ts +90 -77
- package/src/resolve/imports.ts +475 -463
- package/src/resolve/scan-facts.ts +318 -296
- package/src/resolve/source-text.ts +37 -37
- package/src/{dynamic → resolve}/tree-shake.ts +132 -128
- package/src/routing/forwarded.ts +19 -19
- package/src/routing/handler.ts +84 -91
- package/src/routing/href.ts +69 -70
- package/src/routing/{metadata.ts → metadata-files.ts} +403 -401
- package/src/{proxy.ts → routing/proxy.ts} +306 -312
- package/src/routing/{request-runtime.ts → request-environment.ts} +10 -10
- package/src/routing/routes.ts +827 -815
- package/src/routing/slots.ts +164 -160
- package/src/runtime/loader.ts +952 -0
- package/src/{dev → runtime}/module-cache.ts +309 -287
- package/src/{dev → runtime}/module-generations.ts +9 -9
- package/src/{dev → runtime}/module-transform.ts +81 -72
- package/src/{dev/imports.ts → runtime/modules.ts} +934 -847
- package/src/runtime/{server.ts → vendor-build.ts} +848 -1696
- package/src/runtime/vendor.ts +425 -404
- package/src/styles.d.ts +9 -0
- package/src/types.ts +320 -335
- package/src/utils/ansi.ts +5 -5
- package/src/utils/{source.ts → code.ts} +15 -12
- package/src/utils/content-type.ts +3 -3
- package/src/utils/decode.ts +2 -2
- package/src/utils/dev-profile.ts +13 -13
- package/src/utils/error-log.ts +6 -6
- package/src/utils/esbuild.ts +18 -18
- package/src/utils/fs-cache.ts +13 -13
- package/src/utils/fs.ts +57 -49
- package/src/utils/html.ts +20 -24
- package/src/utils/native-require.ts +8 -8
- package/src/utils/serialize.ts +139 -146
- package/src/utils/verbose.ts +18 -18
- package/src/cli/analyze-print.ts +0 -181
- package/src/compat/middleware/manifest.ts +0 -210
- package/src/compat/next/image-client.tsx +0 -215
- package/src/compat/next/link-usage.ts +0 -29
- package/src/css/index.ts +0 -2
- package/src/render/index.ts +0 -1
- package/src/style-modules.d.ts +0 -9
|
@@ -3,118 +3,118 @@ import {
|
|
|
3
3
|
recordSegment,
|
|
4
4
|
segmentPrefetchCovered,
|
|
5
5
|
takeSegment,
|
|
6
|
-
} from './segment-cache'
|
|
7
|
-
import { getStaleTimeMs } from '../segment/vary-key'
|
|
6
|
+
} from './segment-cache'
|
|
7
|
+
import { getStaleTimeMs } from '../segment/vary-key'
|
|
8
8
|
|
|
9
|
-
const SEGMENT_PREFETCH_HEADER = 'next-router-segment-prefetch'
|
|
10
|
-
const APP_SHELL_PREFETCH_HEADER = 'x-pnext-app-shell'
|
|
11
|
-
const INDEX_SEGMENT_PATH = '/_index'
|
|
12
|
-
const TREE_SEGMENT_PATH = '/_tree'
|
|
13
|
-
const RSC_QUERY = '_rsc'
|
|
14
|
-
const SEGMENT_CACHE_LIMIT = 64
|
|
9
|
+
const SEGMENT_PREFETCH_HEADER = 'next-router-segment-prefetch'
|
|
10
|
+
const APP_SHELL_PREFETCH_HEADER = 'x-pnext-app-shell'
|
|
11
|
+
const INDEX_SEGMENT_PATH = '/_index'
|
|
12
|
+
const TREE_SEGMENT_PATH = '/_tree'
|
|
13
|
+
const RSC_QUERY = '_rsc'
|
|
14
|
+
const SEGMENT_CACHE_LIMIT = 64
|
|
15
15
|
|
|
16
|
-
type Priority = 'low' | 'high'
|
|
16
|
+
type Priority = 'low' | 'high'
|
|
17
17
|
|
|
18
18
|
interface SegmentEntry {
|
|
19
|
-
time: number
|
|
20
|
-
staleTimeMs: number
|
|
19
|
+
time: number
|
|
20
|
+
staleTimeMs: number
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
interface ScheduledPrefetch {
|
|
24
|
-
controller: AbortController
|
|
25
|
-
priority: Priority
|
|
24
|
+
controller: AbortController
|
|
25
|
+
priority: Priority
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
const treeCache = new Map<string, SegmentEntry>()
|
|
29
|
-
const scheduled = new WeakMap<Element, ScheduledPrefetch>()
|
|
30
|
-
const watched = new WeakSet<Element>()
|
|
31
|
-
let observer: IntersectionObserver | undefined
|
|
32
|
-
let installed = false
|
|
28
|
+
const treeCache = new Map<string, SegmentEntry>()
|
|
29
|
+
const scheduled = new WeakMap<Element, ScheduledPrefetch>()
|
|
30
|
+
const watched = new WeakSet<Element>()
|
|
31
|
+
let observer: IntersectionObserver | undefined
|
|
32
|
+
let installed = false
|
|
33
33
|
|
|
34
34
|
export function installSegmentPrefetchRuntime(): void {
|
|
35
|
-
if ((!process.browser && typeof window === 'undefined') || installed) return
|
|
36
|
-
installed = true
|
|
37
|
-
document.addEventListener('pointerover', onIntent, true)
|
|
38
|
-
document.addEventListener('touchstart', onIntent, { capture: true, passive: true })
|
|
39
|
-
document.addEventListener('focusin', onIntent, true)
|
|
40
|
-
watchLinks()
|
|
35
|
+
if ((!process.browser && typeof window === 'undefined') || installed) return
|
|
36
|
+
installed = true
|
|
37
|
+
document.addEventListener('pointerover', onIntent, true)
|
|
38
|
+
document.addEventListener('touchstart', onIntent, { capture: true, passive: true })
|
|
39
|
+
document.addEventListener('focusin', onIntent, true)
|
|
40
|
+
watchLinks()
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
function watchLinks(): void {
|
|
44
|
-
scanLinks(document.documentElement)
|
|
44
|
+
scanLinks(document.documentElement)
|
|
45
45
|
const mutations = new MutationObserver(records => {
|
|
46
46
|
for (const record of records) {
|
|
47
47
|
for (const node of record.addedNodes) {
|
|
48
|
-
if (node instanceof Element) scanLinks(node)
|
|
48
|
+
if (node instanceof Element) scanLinks(node)
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
|
-
})
|
|
52
|
-
mutations.observe(document.documentElement, { childList: true, subtree: true })
|
|
51
|
+
})
|
|
52
|
+
mutations.observe(document.documentElement, { childList: true, subtree: true })
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
function scanLinks(root: Element): void {
|
|
56
|
-
const links = [...root.querySelectorAll<HTMLAnchorElement>('a[data-pnext-link]')]
|
|
57
|
-
if (root.matches('a[data-pnext-link]')) links.push(root as HTMLAnchorElement)
|
|
56
|
+
const links = [...root.querySelectorAll<HTMLAnchorElement>('a[data-pnext-link]')]
|
|
57
|
+
if (root.matches('a[data-pnext-link]')) links.push(root as HTMLAnchorElement)
|
|
58
58
|
for (const link of links) {
|
|
59
|
-
if (watched.has(link)) continue
|
|
60
|
-
if (link.getAttribute('data-prefetch') === 'false') continue
|
|
61
|
-
watched.add(link)
|
|
62
|
-
observer ??= new IntersectionObserver(onVisibility)
|
|
63
|
-
observer.observe(link)
|
|
59
|
+
if (watched.has(link)) continue
|
|
60
|
+
if (link.getAttribute('data-prefetch') === 'false') continue
|
|
61
|
+
watched.add(link)
|
|
62
|
+
observer ??= new IntersectionObserver(onVisibility)
|
|
63
|
+
observer.observe(link)
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
function onVisibility(entries: IntersectionObserverEntry[]): void {
|
|
68
68
|
for (const entry of entries) {
|
|
69
|
-
const link = entry.target
|
|
69
|
+
const link = entry.target
|
|
70
70
|
if (entry.isIntersecting) {
|
|
71
71
|
// Revealing a link prefetches the BODY segment too, not just the route
|
|
72
72
|
// tree: Next's default prefetch fetches the route's static data, and the
|
|
73
73
|
// shared segment cache is fed from that body response (see
|
|
74
74
|
// `prefetchSegment`). A tree-only reveal left the cache empty, so the
|
|
75
75
|
// navigation that follows had nothing cached to paint.
|
|
76
|
-
schedule(link, 'low')
|
|
76
|
+
schedule(link, 'low')
|
|
77
77
|
} else {
|
|
78
|
-
scheduled.get(link)?.controller.abort()
|
|
79
|
-
scheduled.delete(link)
|
|
78
|
+
scheduled.get(link)?.controller.abort()
|
|
79
|
+
scheduled.delete(link)
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
function onIntent(event: Event): void {
|
|
85
|
-
const link = linkFromEvent(event)
|
|
86
|
-
if (!link || link.getAttribute('data-prefetch') === 'false') return
|
|
87
|
-
scheduled.get(link)?.controller.abort()
|
|
88
|
-
scheduled.delete(link)
|
|
89
|
-
schedule(link, 'high')
|
|
85
|
+
const link = linkFromEvent(event)
|
|
86
|
+
if (!link || link.getAttribute('data-prefetch') === 'false') return
|
|
87
|
+
scheduled.get(link)?.controller.abort()
|
|
88
|
+
scheduled.delete(link)
|
|
89
|
+
schedule(link, 'high')
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
function schedule(link: Element, priority: Priority): void {
|
|
93
|
-
const href = link.getAttribute('href')
|
|
94
|
-
if (!href || isBotUserAgent()) return
|
|
95
|
-
const url = softUrl(href)
|
|
96
|
-
if (!url) return
|
|
97
|
-
const current = scheduled.get(link)
|
|
98
|
-
if (current?.priority === 'high') return
|
|
99
|
-
const controller = new AbortController()
|
|
100
|
-
scheduled.set(link, { controller, priority })
|
|
93
|
+
const href = link.getAttribute('href')
|
|
94
|
+
if (!href || isBotUserAgent()) return
|
|
95
|
+
const url = softUrl(href)
|
|
96
|
+
if (!url) return
|
|
97
|
+
const current = scheduled.get(link)
|
|
98
|
+
if (current?.priority === 'high') return
|
|
99
|
+
const controller = new AbortController()
|
|
100
|
+
scheduled.set(link, { controller, priority })
|
|
101
101
|
void prefetchSegments(url, { priority, signal: controller.signal })
|
|
102
102
|
// Best-effort: an aborted (link left viewport / superseded) or failed
|
|
103
103
|
// segment prefetch must never surface as an unhandled rejection — the
|
|
104
104
|
// client error runtime would swap the live page for the global error.
|
|
105
105
|
.catch(() => undefined)
|
|
106
106
|
.finally(() => {
|
|
107
|
-
if (scheduled.get(link)?.controller === controller) scheduled.delete(link)
|
|
108
|
-
})
|
|
107
|
+
if (scheduled.get(link)?.controller === controller) scheduled.delete(link)
|
|
108
|
+
})
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
async function prefetchSegments(
|
|
112
112
|
url: URL,
|
|
113
113
|
options: { priority: Priority; signal: AbortSignal },
|
|
114
114
|
): Promise<void> {
|
|
115
|
-
const staleTimeMs = await prefetchSegment(url, TREE_SEGMENT_PATH, options)
|
|
116
|
-
if (options.signal.aborted) return
|
|
117
|
-
await prefetchSegment(url, INDEX_SEGMENT_PATH, options, staleTimeMs)
|
|
115
|
+
const staleTimeMs = await prefetchSegment(url, TREE_SEGMENT_PATH, options)
|
|
116
|
+
if (options.signal.aborted) return
|
|
117
|
+
await prefetchSegment(url, INDEX_SEGMENT_PATH, options, staleTimeMs)
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
async function prefetchSegment(
|
|
@@ -129,13 +129,13 @@ async function prefetchSegment(
|
|
|
129
129
|
// and re-fetching it is the network request the suites assert never happens.
|
|
130
130
|
// The tree response carries no vary metadata, so it keeps its own pathname map.
|
|
131
131
|
if (segment === TREE_SEGMENT_PATH) {
|
|
132
|
-
const cached = treeCache.get(url.pathname)
|
|
133
|
-
if (cached && Date.now() - cached.time < cached.staleTimeMs) return cached.staleTimeMs
|
|
132
|
+
const cached = treeCache.get(url.pathname)
|
|
133
|
+
if (cached && Date.now() - cached.time < cached.staleTimeMs) return cached.staleTimeMs
|
|
134
134
|
} else {
|
|
135
135
|
// A hit alone is not a dedupe: `takeSegment` also returns PAINT-only
|
|
136
136
|
// entries (a postponed body, a shared shell, another URL's runtime
|
|
137
137
|
// sample), and those still have real content to fetch. Only a
|
|
138
|
-
// network-free hit dedupes here. (
|
|
138
|
+
// network-free hit dedupes here. (client/router/index.ts's
|
|
139
139
|
// `segmentVaryPrefetchSatisfied` uses the weaker `prefetchSatisfied`; this
|
|
140
140
|
// is the App-Shell scheduler, whose shells are shared by construction, so
|
|
141
141
|
// the weaker rule would dedupe away the shell fetch that primes them.)
|
|
@@ -143,8 +143,8 @@ async function prefetchSegment(
|
|
|
143
143
|
pathname: url.pathname,
|
|
144
144
|
search: url.search,
|
|
145
145
|
segmentPath: INDEX_SEGMENT_PATH,
|
|
146
|
-
})
|
|
147
|
-
if (hit?.networkFree === true) return fallbackStaleTimeMs
|
|
146
|
+
})
|
|
147
|
+
if (hit?.networkFree === true) return fallbackStaleTimeMs
|
|
148
148
|
// …plus the one case `takeSegment` deliberately refuses to share: a PPR
|
|
149
149
|
// SHELL (postponed, so neither complete nor `x-nextjs-prerender`) whose
|
|
150
150
|
// published vary set already covers this URL. Nothing about it would differ
|
|
@@ -153,8 +153,8 @@ async function prefetchSegment(
|
|
|
153
153
|
pathname: url.pathname,
|
|
154
154
|
search: url.search,
|
|
155
155
|
segmentPath: INDEX_SEGMENT_PATH,
|
|
156
|
-
})
|
|
157
|
-
if (covered) return fallbackStaleTimeMs
|
|
156
|
+
})
|
|
157
|
+
if (covered) return fallbackStaleTimeMs
|
|
158
158
|
}
|
|
159
159
|
const response = await fetch(withRscQuery(url.href), {
|
|
160
160
|
headers: {
|
|
@@ -165,45 +165,40 @@ async function prefetchSegment(
|
|
|
165
165
|
credentials: 'same-origin',
|
|
166
166
|
priority: options.priority,
|
|
167
167
|
signal: options.signal,
|
|
168
|
-
})
|
|
169
|
-
if (!response.ok) return fallbackStaleTimeMs
|
|
170
|
-
const body = await response.text()
|
|
171
|
-
const staleTimeMs = getStaleTimeMs(headerStaleTimeSeconds(response))
|
|
168
|
+
})
|
|
169
|
+
if (!response.ok) return fallbackStaleTimeMs
|
|
170
|
+
const body = await response.text()
|
|
171
|
+
const staleTimeMs = getStaleTimeMs(headerStaleTimeSeconds(response))
|
|
172
172
|
// The RECORDED entry keeps the response's own window: a `stale: 0` /
|
|
173
173
|
// expireNow payload is born stale by contract, and clamping it would let a
|
|
174
174
|
// revalidated route serve pre-revalidation bytes for 30s. The floor exists
|
|
175
175
|
// to stop a prefetch LOOP, so it applies to the dedupe window only.
|
|
176
|
-
const rawSeconds = headerStaleTimeSeconds(response)
|
|
177
|
-
const recordStaleTimeMs = (Number.isFinite(rawSeconds) ? rawSeconds : 300) * 1000
|
|
176
|
+
const rawSeconds = headerStaleTimeSeconds(response)
|
|
177
|
+
const recordStaleTimeMs = (Number.isFinite(rawSeconds) ? rawSeconds : 300) * 1000
|
|
178
178
|
if (segment === TREE_SEGMENT_PATH) {
|
|
179
|
-
treeCache.set(url.pathname, { time: Date.now(), staleTimeMs })
|
|
180
|
-
trim(treeCache)
|
|
179
|
+
treeCache.set(url.pathname, { time: Date.now(), staleTimeMs })
|
|
180
|
+
trim(treeCache)
|
|
181
181
|
}
|
|
182
182
|
// The BODY response is the route's static stage. Recording it into the shared
|
|
183
183
|
// segment cache is the whole point of the prefetch: without it the payload was
|
|
184
184
|
// fetched, timed and thrown away, and the navigation that followed a reveal
|
|
185
185
|
// had nothing to paint (Segment-M2 fix-forward 3). The tree response carries no
|
|
186
186
|
// markup, so only the body segment is recorded.
|
|
187
|
-
if (segment === INDEX_SEGMENT_PATH) recordBodySegment(url, response, body, recordStaleTimeMs)
|
|
188
|
-
return staleTimeMs
|
|
187
|
+
if (segment === INDEX_SEGMENT_PATH) recordBodySegment(url, response, body, recordStaleTimeMs)
|
|
188
|
+
return staleTimeMs
|
|
189
189
|
}
|
|
190
190
|
|
|
191
191
|
/** File one `/_index` body-prefetch response into the shared segment cache. */
|
|
192
|
-
function recordBodySegment(
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
staleTimeMs: number,
|
|
197
|
-
): void {
|
|
198
|
-
const decoded = decodeSegmentPayload(body, INDEX_SEGMENT_PATH);
|
|
199
|
-
if (!decoded) return;
|
|
200
|
-
// Mirrors the router's own segment-prefetch bookkeeping (api/router.ts
|
|
192
|
+
function recordBodySegment(url: URL, response: Response, body: string, staleTimeMs: number): void {
|
|
193
|
+
const decoded = decodeSegmentPayload(body, INDEX_SEGMENT_PATH)
|
|
194
|
+
if (!decoded) return
|
|
195
|
+
// Mirrors the router's own segment-prefetch bookkeeping (client/router/index.ts
|
|
201
196
|
// recordSegmentEntry): a runtime (request-sampled) shell reports its own
|
|
202
197
|
// completeness, everything else is complete unless the render postponed.
|
|
203
|
-
const runtime = response.headers.get('x-pnext-runtime-prefetch') === '1'
|
|
198
|
+
const runtime = response.headers.get('x-pnext-runtime-prefetch') === '1'
|
|
204
199
|
const complete = runtime
|
|
205
200
|
? response.headers.get('x-pnext-runtime-complete') === '1'
|
|
206
|
-
: response.headers.get('x-pnext-segment-postponed') !== '1'
|
|
201
|
+
: response.headers.get('x-pnext-segment-postponed') !== '1'
|
|
207
202
|
recordSegment({
|
|
208
203
|
segmentPath: INDEX_SEGMENT_PATH,
|
|
209
204
|
pathname: url.pathname,
|
|
@@ -216,7 +211,7 @@ function recordBodySegment(
|
|
|
216
211
|
vary: decoded.vary,
|
|
217
212
|
route: decoded.route,
|
|
218
213
|
params: decoded.params,
|
|
219
|
-
})
|
|
214
|
+
})
|
|
220
215
|
// A per-URL static prerender of a params-reading route also primes the route's
|
|
221
216
|
// shared App Shell (no-op unless experimental.appShells is on).
|
|
222
217
|
scheduleAppShellPrefetch({
|
|
@@ -226,56 +221,56 @@ function recordBodySegment(
|
|
|
226
221
|
static: response.headers.get('x-nextjs-prerender') === '1',
|
|
227
222
|
complete,
|
|
228
223
|
runtime,
|
|
229
|
-
})
|
|
224
|
+
})
|
|
230
225
|
}
|
|
231
226
|
|
|
232
227
|
/** The response's reported staleness in seconds, NaN when it reported none. */
|
|
233
228
|
function headerStaleTimeSeconds(response: Response): number {
|
|
234
|
-
const header = response.headers.get('x-nextjs-stale-time')
|
|
235
|
-
return header === null ? Number.NaN : Number(header)
|
|
229
|
+
const header = response.headers.get('x-nextjs-stale-time')
|
|
230
|
+
return header === null ? Number.NaN : Number(header)
|
|
236
231
|
}
|
|
237
232
|
|
|
238
233
|
function withRscQuery(href: string, variant = ''): string {
|
|
239
|
-
const url = new URL(href, location.href)
|
|
240
|
-
if (url.searchParams.has(RSC_QUERY)) return url.href
|
|
241
|
-
const hash = rscHash(url.pathname + url.search + (variant ? `#${variant}` : ''))
|
|
242
|
-
const separator = url.search ? '&' : '?'
|
|
243
|
-
return `${url.origin}${url.pathname}${url.search}${separator}${RSC_QUERY}=${hash}${url.hash}
|
|
234
|
+
const url = new URL(href, location.href)
|
|
235
|
+
if (url.searchParams.has(RSC_QUERY)) return url.href
|
|
236
|
+
const hash = rscHash(url.pathname + url.search + (variant ? `#${variant}` : ''))
|
|
237
|
+
const separator = url.search ? '&' : '?'
|
|
238
|
+
return `${url.origin}${url.pathname}${url.search}${separator}${RSC_QUERY}=${hash}${url.hash}`
|
|
244
239
|
}
|
|
245
240
|
|
|
246
241
|
function rscHash(input: string): string {
|
|
247
|
-
let hash = 0
|
|
242
|
+
let hash = 0
|
|
248
243
|
for (let index = 0; index < input.length; index++) {
|
|
249
|
-
hash = (Math.imul(31, hash) + input.charCodeAt(index)) | 0
|
|
244
|
+
hash = (Math.imul(31, hash) + input.charCodeAt(index)) | 0
|
|
250
245
|
}
|
|
251
|
-
return (hash >>> 0).toString(36)
|
|
246
|
+
return (hash >>> 0).toString(36)
|
|
252
247
|
}
|
|
253
248
|
|
|
254
249
|
function linkFromEvent(event: Event): Element | null {
|
|
255
|
-
const target = event.target
|
|
256
|
-
return target instanceof Element ? target.closest('a[data-pnext-link]') : null
|
|
250
|
+
const target = event.target
|
|
251
|
+
return target instanceof Element ? target.closest('a[data-pnext-link]') : null
|
|
257
252
|
}
|
|
258
253
|
|
|
259
254
|
function softUrl(href: string): URL | null {
|
|
260
255
|
try {
|
|
261
|
-
const url = new URL(href, location.href)
|
|
262
|
-
return url.origin === location.origin ? url : null
|
|
256
|
+
const url = new URL(href, location.href)
|
|
257
|
+
return url.origin === location.origin ? url : null
|
|
263
258
|
} catch {
|
|
264
|
-
return null
|
|
259
|
+
return null
|
|
265
260
|
}
|
|
266
261
|
}
|
|
267
262
|
|
|
268
263
|
function isBotUserAgent(): boolean {
|
|
269
264
|
return /Googlebot(?!-)|Googlebot$|bingbot|Slurp|DuckDuckBot|Baiduspider|YandexBot/i.test(
|
|
270
265
|
navigator.userAgent,
|
|
271
|
-
)
|
|
266
|
+
)
|
|
272
267
|
}
|
|
273
268
|
|
|
274
269
|
function trim(cache: Map<string, SegmentEntry>): void {
|
|
275
270
|
while (cache.size > SEGMENT_CACHE_LIMIT) {
|
|
276
|
-
const oldest = cache.keys().next().value
|
|
277
|
-
if (oldest === undefined) return
|
|
278
|
-
cache.delete(oldest)
|
|
271
|
+
const oldest = cache.keys().next().value
|
|
272
|
+
if (oldest === undefined) return
|
|
273
|
+
cache.delete(oldest)
|
|
279
274
|
}
|
|
280
275
|
}
|
|
281
276
|
|
|
@@ -292,35 +287,35 @@ function trim(cache: Map<string, SegmentEntry>): void {
|
|
|
292
287
|
// response (empty vary set) already serves every URL.
|
|
293
288
|
|
|
294
289
|
/** Routes whose shared shell has been requested; one request per route, ever. */
|
|
295
|
-
const appShellRequested = new Set<string>()
|
|
290
|
+
const appShellRequested = new Set<string>()
|
|
296
291
|
|
|
297
292
|
export interface AppShellPrefetchInput {
|
|
298
293
|
/** The URL whose per-segment prefetch just landed. */
|
|
299
|
-
pathname: string
|
|
294
|
+
pathname: string
|
|
300
295
|
/** Route pattern the response reported (colon form), or null. */
|
|
301
|
-
route: string | null
|
|
296
|
+
route: string | null
|
|
302
297
|
/** The response's vary set, or null when it published none. */
|
|
303
|
-
vary: readonly string[] | null
|
|
304
|
-
static: boolean
|
|
305
|
-
complete: boolean
|
|
306
|
-
runtime: boolean
|
|
298
|
+
vary: readonly string[] | null
|
|
299
|
+
static: boolean
|
|
300
|
+
complete: boolean
|
|
301
|
+
runtime: boolean
|
|
307
302
|
}
|
|
308
303
|
|
|
309
304
|
export function scheduleAppShellPrefetch(input: AppShellPrefetchInput): void {
|
|
310
|
-
if (!appShellsEnabled()) return
|
|
311
|
-
if (input.runtime || !input.static || !input.complete) return
|
|
312
|
-
const route = input.route
|
|
305
|
+
if (!appShellsEnabled()) return
|
|
306
|
+
if (input.runtime || !input.static || !input.complete) return
|
|
307
|
+
const route = input.route
|
|
313
308
|
// A route with no dynamic segment has nothing to share across params, and a
|
|
314
309
|
// response that read no params is already the shared entry.
|
|
315
|
-
if (!route?.includes(':')) return
|
|
316
|
-
if (!input.vary || input.vary.length === 0) return
|
|
317
|
-
if (appShellRequested.has(route)) return
|
|
318
|
-
appShellRequested.add(route)
|
|
310
|
+
if (!route?.includes(':')) return
|
|
311
|
+
if (!input.vary || input.vary.length === 0) return
|
|
312
|
+
if (appShellRequested.has(route)) return
|
|
313
|
+
appShellRequested.add(route)
|
|
319
314
|
void fetchAppShell(input.pathname).catch(() => {
|
|
320
315
|
// Best-effort: a failed shell prefetch just means the next navigation to an
|
|
321
316
|
// unprefetched param of this route waits for its own response.
|
|
322
|
-
appShellRequested.delete(route)
|
|
323
|
-
})
|
|
317
|
+
appShellRequested.delete(route)
|
|
318
|
+
})
|
|
324
319
|
}
|
|
325
320
|
|
|
326
321
|
async function fetchAppShell(pathname: string): Promise<void> {
|
|
@@ -333,10 +328,10 @@ async function fetchAppShell(pathname: string): Promise<void> {
|
|
|
333
328
|
},
|
|
334
329
|
credentials: 'same-origin',
|
|
335
330
|
priority: 'low',
|
|
336
|
-
})
|
|
337
|
-
if (!response.ok) return
|
|
338
|
-
const decoded = decodeSegmentPayload(await response.text(), INDEX_SEGMENT_PATH)
|
|
339
|
-
if (!decoded) return
|
|
331
|
+
})
|
|
332
|
+
if (!response.ok) return
|
|
333
|
+
const decoded = decodeSegmentPayload(await response.text(), INDEX_SEGMENT_PATH)
|
|
334
|
+
if (!decoded) return
|
|
340
335
|
recordSegment({
|
|
341
336
|
segmentPath: INDEX_SEGMENT_PATH,
|
|
342
337
|
pathname,
|
|
@@ -355,21 +350,21 @@ async function fetchAppShell(pathname: string): Promise<void> {
|
|
|
355
350
|
vary: decoded.vary,
|
|
356
351
|
route: decoded.route,
|
|
357
352
|
params: decoded.params,
|
|
358
|
-
})
|
|
353
|
+
})
|
|
359
354
|
}
|
|
360
355
|
|
|
361
356
|
function appShellsEnabled(): boolean {
|
|
362
|
-
if (!process.browser && typeof window === 'undefined') return false
|
|
363
|
-
return (window as { __PNEXT_APP_SHELLS__?: boolean }).__PNEXT_APP_SHELLS__ === true
|
|
357
|
+
if (!process.browser && typeof window === 'undefined') return false
|
|
358
|
+
return (window as { __PNEXT_APP_SHELLS__?: boolean }).__PNEXT_APP_SHELLS__ === true
|
|
364
359
|
}
|
|
365
360
|
|
|
366
361
|
/** Test seam: forget which routes have already primed their shared shell. */
|
|
367
362
|
export function resetAppShellPrefetches(): void {
|
|
368
|
-
appShellRequested.clear()
|
|
363
|
+
appShellRequested.clear()
|
|
369
364
|
}
|
|
370
365
|
|
|
371
366
|
/** Drop all prefetch dedupe state — a revalidation invalidated every window. */
|
|
372
367
|
export function resetSegmentPrefetchDedupe(): void {
|
|
373
|
-
treeCache.clear()
|
|
374
|
-
appShellRequested.clear()
|
|
368
|
+
treeCache.clear()
|
|
369
|
+
appShellRequested.clear()
|
|
375
370
|
}
|
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
|
|
8
8
|
declare global {
|
|
9
9
|
interface Window {
|
|
10
|
-
__PNEXT_SKIP_TRAILING_SLASH__?: boolean
|
|
10
|
+
__PNEXT_SKIP_TRAILING_SLASH__?: boolean
|
|
11
11
|
}
|
|
12
|
-
var __PNEXT_SKIP_TRAILING_SLASH__: boolean | undefined
|
|
12
|
+
var __PNEXT_SKIP_TRAILING_SLASH__: boolean | undefined
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
/**
|
|
@@ -19,6 +19,7 @@ declare global {
|
|
|
19
19
|
* esbuild-backed config loader, so this stays safe to ship to the browser.
|
|
20
20
|
*/
|
|
21
21
|
export function skipTrailingSlashRedirect(): boolean {
|
|
22
|
-
if (process.browser || typeof window !== 'undefined')
|
|
23
|
-
|
|
22
|
+
if (process.browser || typeof window !== 'undefined')
|
|
23
|
+
return window.__PNEXT_SKIP_TRAILING_SLASH__ === true
|
|
24
|
+
return globalThis.__PNEXT_SKIP_TRAILING_SLASH__ === true
|
|
24
25
|
}
|