@wular/pnext 0.0.4 → 0.0.7
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 +22 -16
- package/bin/pnext +6 -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 +87 -22
- package/reference/config.md +40 -93
- package/reference/css.md +42 -33
- package/reference/dev.md +26 -33
- package/reference/env.md +18 -20
- package/reference/getting-started.md +132 -0
- package/reference/metadata.md +31 -46
- package/reference/navigation.md +65 -105
- package/reference/performance.md +21 -142
- package/reference/rendering.md +78 -75
- package/reference/routing.md +97 -107
- package/reference/typegen.md +27 -29
- package/src/api/cache.ts +36 -37
- package/src/api/client-cache.ts +2 -2
- package/src/api/client-navigation.ts +121 -114
- package/src/api/dynamic.tsx +58 -55
- package/src/api/link.tsx +52 -53
- 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 +72 -64
- package/src/cli/dev.ts +116 -116
- package/src/cli/index.ts +94 -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 +802 -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 +32 -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 +2022 -1995
- package/src/{api → client}/router/types.ts +98 -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 +86 -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 +2087 -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 +87 -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 +954 -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 +428 -406
- package/src/styles.d.ts +9 -0
- package/src/types.ts +324 -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/reference/overview.md +0 -35
- 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
|
@@ -11,19 +11,19 @@
|
|
|
11
11
|
// node. The bit-flags and inlining are deliberately omitted; the tree carries just enough for the client
|
|
12
12
|
// LRU and staleTime keying.
|
|
13
13
|
|
|
14
|
-
import { RSC_CONTENT_TYPE_HEADER } from '../next/dist/client/components/app-router-headers'
|
|
15
|
-
import { varyNamesFor, type ResponseVaryParams, type SegmentVaryPayload } from './vary-params'
|
|
14
|
+
import { RSC_CONTENT_TYPE_HEADER } from '../next/dist/client/components/app-router-headers'
|
|
15
|
+
import { varyNamesFor, type ResponseVaryParams, type SegmentVaryPayload } from './vary-params'
|
|
16
16
|
|
|
17
17
|
/** The segment-prefetch request sentinel the client sends for the whole tree. */
|
|
18
|
-
export const TREE_SEGMENT_PATH = '/_tree' as const
|
|
18
|
+
export const TREE_SEGMENT_PATH = '/_tree' as const
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* Default dynamic staleTime (seconds) - mirrors Next's staleTimes.dynamic, which has defaulted to 0 since
|
|
22
22
|
* Next 15: dynamic data is never reused unless `experimental.staleTimes.dynamic` opts in.
|
|
23
23
|
*/
|
|
24
|
-
export const DEFAULT_DYNAMIC_STALE_TIME_SECONDS = 0
|
|
24
|
+
export const DEFAULT_DYNAMIC_STALE_TIME_SECONDS = 0
|
|
25
25
|
/** Default static staleTime (seconds) — mirrors Next's staleTimes.static. */
|
|
26
|
-
export const DEFAULT_STATIC_STALE_TIME_SECONDS = 300
|
|
26
|
+
export const DEFAULT_STATIC_STALE_TIME_SECONDS = 300
|
|
27
27
|
|
|
28
28
|
export const enum PrefetchHint {
|
|
29
29
|
HasRuntimePrefetch = 0b00001,
|
|
@@ -42,86 +42,86 @@ export const enum PrefetchHint {
|
|
|
42
42
|
*/
|
|
43
43
|
export interface SegmentTreeNode {
|
|
44
44
|
/** Route segment name (the whole pathname for the single-node milestone). */
|
|
45
|
-
name: string
|
|
45
|
+
name: string
|
|
46
46
|
/** Dynamic param name captured at this segment, when any. */
|
|
47
|
-
param: null | { type: 'd' | 'c' | 'oc'; key: string | null; siblings: string[] | null }
|
|
47
|
+
param: null | { type: 'd' | 'c' | 'oc'; key: string | null; siblings: string[] | null }
|
|
48
48
|
/** Child slots keyed by slot name (empty for the whole-route node). */
|
|
49
|
-
slots: Record<string, SegmentTreeNode> | null
|
|
49
|
+
slots: Record<string, SegmentTreeNode> | null
|
|
50
50
|
/** Next-compatible prefetch hint bitmask. */
|
|
51
|
-
prefetchHints: number
|
|
51
|
+
prefetchHints: number
|
|
52
52
|
/** Byte size of this segment payload when it is available at build time. */
|
|
53
|
-
sizeBytes?: number
|
|
53
|
+
sizeBytes?: number
|
|
54
54
|
/** Body segment path in the per-route segment store, when outlined. */
|
|
55
|
-
segmentPath?: string
|
|
55
|
+
segmentPath?: string
|
|
56
56
|
/**
|
|
57
57
|
* Segment-M2: the param names this segment's render actually read (`'?'` for
|
|
58
58
|
* any searchParams access). An EMPTY array means "shareable across every param
|
|
59
59
|
* value"; an ABSENT field means the server did not track vary params and the
|
|
60
60
|
* client must key on the exact URL.
|
|
61
61
|
*/
|
|
62
|
-
varyParams?: string[]
|
|
62
|
+
varyParams?: string[]
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
/** The `/_tree` response payload (Next `RootTreePrefetch` analogue). */
|
|
66
66
|
export interface RootTreePrefetch {
|
|
67
67
|
/** Build id when known (start reads it from the manifest; optional). */
|
|
68
|
-
buildId?: string
|
|
68
|
+
buildId?: string
|
|
69
69
|
/** The route prefetch tree (single whole-route node in milestone 1). */
|
|
70
|
-
tree: SegmentTreeNode
|
|
70
|
+
tree: SegmentTreeNode
|
|
71
71
|
/** Per-tree staleTime in seconds the client keys its LRU window on. */
|
|
72
|
-
staleTime: number
|
|
72
|
+
staleTime: number
|
|
73
73
|
/** True when the whole route is statically prerenderable (static window). */
|
|
74
|
-
isStatic: boolean
|
|
74
|
+
isStatic: boolean
|
|
75
75
|
/**
|
|
76
76
|
* Segment-M2 vary sets for this route (body / head / root). Absent when the
|
|
77
77
|
* response was produced without render-time tracking.
|
|
78
78
|
*/
|
|
79
|
-
vary?: SegmentVaryPayload
|
|
79
|
+
vary?: SegmentVaryPayload
|
|
80
80
|
/** The matched route pattern the client keys shared segment entries on. */
|
|
81
|
-
route?: string
|
|
81
|
+
route?: string
|
|
82
82
|
/** Concrete params of the requested URL, so the client can build vary keys. */
|
|
83
|
-
params?: Record<string, string | string[]
|
|
83
|
+
params?: Record<string, string | string[]>
|
|
84
84
|
/**
|
|
85
85
|
* The route's <title> is DYNAMIC and rides in its own `/_head` response. The client learns it here -
|
|
86
86
|
* before the body request - so the head is fetched FIRST, the order Next's segment prefetch produces,
|
|
87
87
|
* since the head segment sits above the page in the route tree.
|
|
88
88
|
*/
|
|
89
|
-
headOutlined?: boolean
|
|
89
|
+
headOutlined?: boolean
|
|
90
90
|
/**
|
|
91
91
|
* The outlined head is fetched BEFORE the body: this route has dynamic
|
|
92
92
|
* params, so its (param-shared) body and its per-URL head are separate
|
|
93
93
|
* segments and the head leads.
|
|
94
94
|
*/
|
|
95
|
-
headFirst?: boolean
|
|
95
|
+
headFirst?: boolean
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
interface BuildTreeOptions {
|
|
99
|
-
pathname: string
|
|
100
|
-
isStatic: boolean
|
|
101
|
-
staleTimeSeconds?: number
|
|
102
|
-
buildId?: string
|
|
103
|
-
routeId?: string
|
|
104
|
-
bodySizeBytes?: number
|
|
105
|
-
inlineBudgetBytes?: number
|
|
106
|
-
runtimePrefetch?: boolean
|
|
107
|
-
postponed?: boolean
|
|
99
|
+
pathname: string
|
|
100
|
+
isStatic: boolean
|
|
101
|
+
staleTimeSeconds?: number
|
|
102
|
+
buildId?: string
|
|
103
|
+
routeId?: string
|
|
104
|
+
bodySizeBytes?: number
|
|
105
|
+
inlineBudgetBytes?: number
|
|
106
|
+
runtimePrefetch?: boolean
|
|
107
|
+
postponed?: boolean
|
|
108
108
|
/** Segment-M2 vary sets collected while rendering this route, when tracked. */
|
|
109
|
-
vary?: SegmentVaryPayload
|
|
109
|
+
vary?: SegmentVaryPayload
|
|
110
110
|
/** The matched route pattern (client vary-key identity). */
|
|
111
|
-
routePattern?: string
|
|
111
|
+
routePattern?: string
|
|
112
112
|
/** Concrete params of the requested URL. */
|
|
113
|
-
params?: Record<string, string | string[]
|
|
113
|
+
params?: Record<string, string | string[]>
|
|
114
114
|
/** The route's head is outlined into a separate `/_head` response. */
|
|
115
|
-
headOutlined?: boolean
|
|
115
|
+
headOutlined?: boolean
|
|
116
116
|
/** That head is fetched before the body (param-varying head). */
|
|
117
|
-
headFirst?: boolean
|
|
117
|
+
headFirst?: boolean
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
/** Build the whole-route `/_tree` payload for `pathname` (milestone 1). */
|
|
121
121
|
export function buildRootTreePrefetch(options: BuildTreeOptions): RootTreePrefetch {
|
|
122
122
|
const staleTime =
|
|
123
123
|
options.staleTimeSeconds ??
|
|
124
|
-
(options.isStatic ? DEFAULT_STATIC_STALE_TIME_SECONDS : DEFAULT_DYNAMIC_STALE_TIME_SECONDS)
|
|
124
|
+
(options.isStatic ? DEFAULT_STATIC_STALE_TIME_SECONDS : DEFAULT_DYNAMIC_STALE_TIME_SECONDS)
|
|
125
125
|
return {
|
|
126
126
|
...(options.buildId ? { buildId: options.buildId } : {}),
|
|
127
127
|
tree: buildTree(options),
|
|
@@ -132,45 +132,44 @@ export function buildRootTreePrefetch(options: BuildTreeOptions): RootTreePrefet
|
|
|
132
132
|
...(options.params ? { params: options.params } : {}),
|
|
133
133
|
...(options.headOutlined ? { headOutlined: true } : {}),
|
|
134
134
|
...(options.headFirst ? { headFirst: true } : {}),
|
|
135
|
-
}
|
|
135
|
+
}
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
function buildTree(options: BuildTreeOptions): SegmentTreeNode {
|
|
139
|
-
const parts = routeParts(options)
|
|
140
|
-
const bodySize = options.bodySizeBytes ?? 0
|
|
141
|
-
const budget = options.inlineBudgetBytes ?? 32 * 1024
|
|
142
|
-
const canInlineBody = options.isStatic && !options.postponed && bodySize <= budget
|
|
139
|
+
const parts = routeParts(options)
|
|
140
|
+
const bodySize = options.bodySizeBytes ?? 0
|
|
141
|
+
const budget = options.inlineBudgetBytes ?? 32 * 1024
|
|
142
|
+
const canInlineBody = options.isStatic && !options.postponed && bodySize <= budget
|
|
143
143
|
let child = pageNode(parts.length === 0, {
|
|
144
144
|
isStatic: options.isStatic,
|
|
145
145
|
canInlineBody,
|
|
146
146
|
bodySizeBytes: options.bodySizeBytes,
|
|
147
147
|
...(options.vary ? { varyParams: options.vary.params } : {}),
|
|
148
|
-
})
|
|
148
|
+
})
|
|
149
149
|
for (let index = parts.length - 1; index >= 0; index--) {
|
|
150
150
|
child = routeNode(parts[index]!, child, index === 0, {
|
|
151
151
|
isStatic: options.isStatic,
|
|
152
152
|
canInlineBody,
|
|
153
153
|
runtimePrefetch: options.runtimePrefetch,
|
|
154
|
-
})
|
|
154
|
+
})
|
|
155
155
|
}
|
|
156
156
|
return {
|
|
157
157
|
name: '',
|
|
158
158
|
param: null,
|
|
159
159
|
slots: { children: child },
|
|
160
|
-
prefetchHints:
|
|
161
|
-
|
|
162
|
-
};
|
|
160
|
+
prefetchHints: PrefetchHint.IsRootLayout | (canInlineBody ? PrefetchHint.InlinedIntoChild : 0),
|
|
161
|
+
}
|
|
163
162
|
}
|
|
164
163
|
|
|
165
164
|
function routeParts(options: BuildTreeOptions): string[] {
|
|
166
|
-
const source = options.routeId ?? options.pathname
|
|
167
|
-
if (source === 'index' || source === '/') return []
|
|
165
|
+
const source = options.routeId ?? options.pathname
|
|
166
|
+
if (source === 'index' || source === '/') return []
|
|
168
167
|
return source
|
|
169
168
|
.split('/')
|
|
170
169
|
.map(part => part.trim())
|
|
171
170
|
.filter(Boolean)
|
|
172
171
|
.filter(part => !part.startsWith('(') && !part.startsWith('@'))
|
|
173
|
-
.map(part => (part === 'index' ? '__PAGE__' : part))
|
|
172
|
+
.map(part => (part === 'index' ? '__PAGE__' : part))
|
|
174
173
|
}
|
|
175
174
|
|
|
176
175
|
function routeNode(
|
|
@@ -179,28 +178,30 @@ function routeNode(
|
|
|
179
178
|
parentInlined: boolean,
|
|
180
179
|
options: { isStatic: boolean; canInlineBody: boolean; runtimePrefetch?: boolean },
|
|
181
180
|
): SegmentTreeNode {
|
|
182
|
-
const dynamic = !options.isStatic || name.includes('instant-false')
|
|
183
|
-
const runtime = Boolean(options.runtimePrefetch) || name.includes('runtime')
|
|
184
|
-
const inlinesIntoChild = options.canInlineBody && !dynamic && !runtime
|
|
181
|
+
const dynamic = !options.isStatic || name.includes('instant-false')
|
|
182
|
+
const runtime = Boolean(options.runtimePrefetch) || name.includes('runtime')
|
|
183
|
+
const inlinesIntoChild = options.canInlineBody && !dynamic && !runtime
|
|
185
184
|
return {
|
|
186
185
|
name,
|
|
187
186
|
param: name.startsWith('[') ? { type: 'd', key: null, siblings: null } : null,
|
|
188
|
-
slots: {
|
|
187
|
+
slots: {
|
|
188
|
+
children: { ...child, prefetchHints: child.prefetchHints | parentHint(inlinesIntoChild) },
|
|
189
|
+
},
|
|
189
190
|
prefetchHints:
|
|
190
191
|
(parentInlined ? PrefetchHint.ParentInlinedIntoSelf : 0) |
|
|
191
192
|
(runtime ? PrefetchHint.HasRuntimePrefetch : 0) |
|
|
192
193
|
(dynamic ? PrefetchHint.PrefetchDisabled : 0) |
|
|
193
194
|
(inlinesIntoChild ? PrefetchHint.InlinedIntoChild : 0),
|
|
194
|
-
}
|
|
195
|
+
}
|
|
195
196
|
}
|
|
196
197
|
|
|
197
198
|
function pageNode(
|
|
198
199
|
parentInlined: boolean,
|
|
199
200
|
options: {
|
|
200
|
-
isStatic: boolean
|
|
201
|
-
canInlineBody: boolean
|
|
202
|
-
bodySizeBytes?: number
|
|
203
|
-
varyParams?: string[]
|
|
201
|
+
isStatic: boolean
|
|
202
|
+
canInlineBody: boolean
|
|
203
|
+
bodySizeBytes?: number
|
|
204
|
+
varyParams?: string[]
|
|
204
205
|
},
|
|
205
206
|
): SegmentTreeNode {
|
|
206
207
|
return {
|
|
@@ -213,19 +214,19 @@ function pageNode(
|
|
|
213
214
|
...(options.bodySizeBytes !== undefined ? { sizeBytes: options.bodySizeBytes } : {}),
|
|
214
215
|
...(options.canInlineBody ? {} : { segmentPath: ROUTE_SEGMENT_PATH }),
|
|
215
216
|
...(options.varyParams ? { varyParams: options.varyParams } : {}),
|
|
216
|
-
}
|
|
217
|
+
}
|
|
217
218
|
}
|
|
218
219
|
|
|
219
220
|
function parentHint(enabled: boolean): number {
|
|
220
|
-
return enabled ? PrefetchHint.ParentInlinedIntoSelf : 0
|
|
221
|
+
return enabled ? PrefetchHint.ParentInlinedIntoSelf : 0
|
|
221
222
|
}
|
|
222
223
|
|
|
223
224
|
export function rootTreePrefetchText(
|
|
224
225
|
payload: RootTreePrefetch,
|
|
225
226
|
format: 'json' | 'flight' = 'json',
|
|
226
227
|
): string {
|
|
227
|
-
const json = JSON.stringify(payload)
|
|
228
|
-
return format === 'flight' ? `0:${json}` : json
|
|
228
|
+
const json = JSON.stringify(payload)
|
|
229
|
+
return format === 'flight' ? `0:${json}` : json
|
|
229
230
|
}
|
|
230
231
|
|
|
231
232
|
/**
|
|
@@ -252,7 +253,7 @@ export function treePrefetchResponse(
|
|
|
252
253
|
? 's-maxage=31536000, stale-while-revalidate'
|
|
253
254
|
: 'private, no-store',
|
|
254
255
|
},
|
|
255
|
-
})
|
|
256
|
+
})
|
|
256
257
|
}
|
|
257
258
|
|
|
258
259
|
// Per-segment payload emission and serving (COMPAT).
|
|
@@ -270,28 +271,28 @@ export function treePrefetchResponse(
|
|
|
270
271
|
// mirroring Next's `.segments/` layout.
|
|
271
272
|
|
|
272
273
|
/** The whole-route segment path sentinel (the route body as one segment). */
|
|
273
|
-
export const ROUTE_SEGMENT_PATH = '/' as const
|
|
274
|
+
export const ROUTE_SEGMENT_PATH = '/' as const
|
|
274
275
|
|
|
275
276
|
export interface SegmentBodyPayload {
|
|
276
|
-
segment: string
|
|
277
|
-
html: string
|
|
277
|
+
segment: string
|
|
278
|
+
html: string
|
|
278
279
|
/**
|
|
279
280
|
* Segment-M2: this segment's vary set (param names, `'?'` for searchParams).
|
|
280
281
|
* Absent when the render was not tracked; the client then keys on the URL.
|
|
281
282
|
*/
|
|
282
|
-
vary?: string[]
|
|
283
|
+
vary?: string[]
|
|
283
284
|
/**
|
|
284
285
|
* w9-segment-split: the LAYOUT frame's own vary set. An `/_index` response
|
|
285
286
|
* carries layout AND page markup, so `vary` above (their union) keys the
|
|
286
287
|
* whole document; these two key the split frames the client composes from.
|
|
287
288
|
*/
|
|
288
|
-
layoutVary?: string[]
|
|
289
|
+
layoutVary?: string[]
|
|
289
290
|
/** w9-segment-split: the PAGE frame's own vary set. */
|
|
290
|
-
pageVary?: string[]
|
|
291
|
+
pageVary?: string[]
|
|
291
292
|
/** The matched route pattern the client keys shared entries on. */
|
|
292
|
-
route?: string
|
|
293
|
+
route?: string
|
|
293
294
|
/** Concrete params of the requested URL. */
|
|
294
|
-
params?: Record<string, string | string[]
|
|
295
|
+
params?: Record<string, string | string[]>
|
|
295
296
|
/**
|
|
296
297
|
* The route's shared APP SHELL (rendered with the params hanging), carried
|
|
297
298
|
* alongside a fully-static per-URL prerender. Next's Flight prerender embeds
|
|
@@ -300,25 +301,25 @@ export interface SegmentBodyPayload {
|
|
|
300
301
|
* payload has no fallback left once the boundary resolved, so the shell rides
|
|
301
302
|
* as its own field instead.
|
|
302
303
|
*/
|
|
303
|
-
shell?: SegmentAppShell
|
|
304
|
+
shell?: SegmentAppShell
|
|
304
305
|
}
|
|
305
306
|
|
|
306
307
|
/** A route's shared app shell, carried alongside a per-URL prerender. */
|
|
307
308
|
export interface SegmentAppShell {
|
|
308
|
-
html: string
|
|
309
|
+
html: string
|
|
309
310
|
/** The route pattern (colon form) the shell is shared across. */
|
|
310
|
-
route: string
|
|
311
|
+
route: string
|
|
311
312
|
}
|
|
312
313
|
|
|
313
314
|
/** Segment-M2 vary metadata a producer attaches to a segment body response. */
|
|
314
315
|
export interface SegmentVaryInfo {
|
|
315
|
-
vary: string[]
|
|
316
|
+
vary: string[]
|
|
316
317
|
/** w9-segment-split: the layout frame's vary set, when the render tracked one. */
|
|
317
|
-
layoutVary?: string[]
|
|
318
|
+
layoutVary?: string[]
|
|
318
319
|
/** w9-segment-split: the page frame's vary set, when the render tracked one. */
|
|
319
|
-
pageVary?: string[]
|
|
320
|
-
route?: string
|
|
321
|
-
params?: Record<string, string | string[]
|
|
320
|
+
pageVary?: string[]
|
|
321
|
+
route?: string
|
|
322
|
+
params?: Record<string, string | string[]>
|
|
322
323
|
}
|
|
323
324
|
|
|
324
325
|
export function segmentBodyText(
|
|
@@ -337,66 +338,66 @@ export function segmentBodyText(
|
|
|
337
338
|
...(vary?.route ? { route: vary.route } : {}),
|
|
338
339
|
...(vary?.params ? { params: vary.params } : {}),
|
|
339
340
|
...(shell ? { shell } : {}),
|
|
340
|
-
}
|
|
341
|
-
const json = JSON.stringify(payload)
|
|
342
|
-
return format === 'flight' ? `0:${json}` : json
|
|
341
|
+
}
|
|
342
|
+
const json = JSON.stringify(payload)
|
|
343
|
+
return format === 'flight' ? `0:${json}` : json
|
|
343
344
|
}
|
|
344
345
|
|
|
345
346
|
/** The response header carrying a segment's vary set (comma-separated names). */
|
|
346
|
-
export const SEGMENT_VARY_HEADER = 'x-pnext-segment-vary'
|
|
347
|
+
export const SEGMENT_VARY_HEADER = 'x-pnext-segment-vary'
|
|
347
348
|
/** The response header carrying the matched route pattern. */
|
|
348
|
-
export const SEGMENT_ROUTE_HEADER = 'x-pnext-segment-route'
|
|
349
|
+
export const SEGMENT_ROUTE_HEADER = 'x-pnext-segment-route'
|
|
349
350
|
/** w9-segment-split: the LAYOUT frame's vary set (comma-separated names). */
|
|
350
|
-
export const SEGMENT_LAYOUT_VARY_HEADER = 'x-pnext-segment-layout-vary'
|
|
351
|
+
export const SEGMENT_LAYOUT_VARY_HEADER = 'x-pnext-segment-layout-vary'
|
|
351
352
|
/** w9-segment-split: the PAGE frame's vary set (comma-separated names). */
|
|
352
|
-
export const SEGMENT_PAGE_VARY_HEADER = 'x-pnext-segment-page-vary'
|
|
353
|
+
export const SEGMENT_PAGE_VARY_HEADER = 'x-pnext-segment-page-vary'
|
|
353
354
|
|
|
354
355
|
/** Per-route segment `.meta` sidecar (contract: status/postponed/segmentPaths). */
|
|
355
356
|
export interface SegmentMeta {
|
|
356
|
-
status: number
|
|
357
|
+
status: number
|
|
357
358
|
/** Effective client-cache staleTime for this route, in seconds. */
|
|
358
|
-
staleTime: number
|
|
359
|
+
staleTime: number
|
|
359
360
|
/** True when the route was postponed (a PPR shell with holes). */
|
|
360
|
-
postponed: boolean
|
|
361
|
+
postponed: boolean
|
|
361
362
|
/** Segment request keys this route can serve (always includes `/_tree`). */
|
|
362
|
-
segmentPaths: string[]
|
|
363
|
+
segmentPaths: string[]
|
|
363
364
|
/** Actual emitted segment byte sizes keyed by segment request path. */
|
|
364
|
-
segmentSizes?: Record<string, number
|
|
365
|
+
segmentSizes?: Record<string, number>
|
|
365
366
|
/** Segment request keys whose payload was inlined into the route tree. */
|
|
366
|
-
inlinedSegmentPaths?: string[]
|
|
367
|
+
inlinedSegmentPaths?: string[]
|
|
367
368
|
/** Route-level prefetch hints, mirrored into Next-shaped metadata. */
|
|
368
|
-
prefetchHints?: Record<string, number
|
|
369
|
+
prefetchHints?: Record<string, number>
|
|
369
370
|
/**
|
|
370
371
|
* The vary set the BUILD render tracked for this baked body, in the same wire encoding a live response
|
|
371
372
|
* publishes. ABSENT means "unknown" - the client then keys the entry on its exact URL.
|
|
372
373
|
*/
|
|
373
|
-
vary?: string[]
|
|
374
|
+
vary?: string[]
|
|
374
375
|
/** w9-segment-split: the baked LAYOUT frame's vary names. */
|
|
375
|
-
layoutVary?: string[]
|
|
376
|
+
layoutVary?: string[]
|
|
376
377
|
/** w9-segment-split: the baked PAGE frame's vary names. */
|
|
377
|
-
pageVary?: string[]
|
|
378
|
+
pageVary?: string[]
|
|
378
379
|
}
|
|
379
380
|
|
|
380
381
|
/** The segment-request key the client sends for the whole-route body segment. */
|
|
381
382
|
export function segmentBodyPath(): string {
|
|
382
|
-
return ROUTE_SEGMENT_PATH
|
|
383
|
+
return ROUTE_SEGMENT_PATH
|
|
383
384
|
}
|
|
384
385
|
|
|
385
386
|
/** Build the `.meta` sidecar for a route (whole-route single-segment milestone). */
|
|
386
387
|
export function buildSegmentMeta(options: {
|
|
387
|
-
status: number
|
|
388
|
-
staleTime: number
|
|
389
|
-
postponed: boolean
|
|
390
|
-
bodySizeBytes?: number
|
|
391
|
-
inlineBudgetBytes?: number
|
|
392
|
-
prefetchHints?: Record<string, number
|
|
388
|
+
status: number
|
|
389
|
+
staleTime: number
|
|
390
|
+
postponed: boolean
|
|
391
|
+
bodySizeBytes?: number
|
|
392
|
+
inlineBudgetBytes?: number
|
|
393
|
+
prefetchHints?: Record<string, number>
|
|
393
394
|
/** The build render's tracked vary set — omitted when it is not trustworthy. */
|
|
394
|
-
vary?: ResponseVaryParams
|
|
395
|
+
vary?: ResponseVaryParams
|
|
395
396
|
}): SegmentMeta {
|
|
396
397
|
const inlined =
|
|
397
398
|
!options.postponed &&
|
|
398
399
|
options.bodySizeBytes !== undefined &&
|
|
399
|
-
options.bodySizeBytes <= (options.inlineBudgetBytes ?? 32 * 1024)
|
|
400
|
+
options.bodySizeBytes <= (options.inlineBudgetBytes ?? 32 * 1024)
|
|
400
401
|
return {
|
|
401
402
|
status: options.status,
|
|
402
403
|
staleTime: options.staleTime,
|
|
@@ -422,7 +423,7 @@ export function buildSegmentMeta(options: {
|
|
|
422
423
|
: {}),
|
|
423
424
|
}
|
|
424
425
|
: {}),
|
|
425
|
-
}
|
|
426
|
+
}
|
|
426
427
|
}
|
|
427
428
|
|
|
428
429
|
/**
|
|
@@ -443,7 +444,7 @@ export function segmentBodyResponse(
|
|
|
443
444
|
// A COMPLETE prerendered segment is static content: CDN-cacheable, exactly like Next serves prerendered
|
|
444
445
|
// payloads. Correctness against a Vary-ignoring CDN comes from the per-variant `_rsc` cache-buster and
|
|
445
446
|
// the revalidation-versioned redirects, NOT from no-store. Anything dynamic or truncated stays private.
|
|
446
|
-
const cacheable = prerendered && !postponed
|
|
447
|
+
const cacheable = prerendered && !postponed
|
|
447
448
|
return new Response(segmentBodyText(segment, body, 'flight', vary, shell), {
|
|
448
449
|
status: 200,
|
|
449
450
|
headers: {
|
|
@@ -463,19 +464,19 @@ export function segmentBodyResponse(
|
|
|
463
464
|
? 's-maxage=31536000, stale-while-revalidate'
|
|
464
465
|
: 'private, no-store',
|
|
465
466
|
},
|
|
466
|
-
})
|
|
467
|
+
})
|
|
467
468
|
}
|
|
468
469
|
|
|
469
470
|
/** On-disk names for a route's segment artifacts under `<route>.segments/`. */
|
|
470
471
|
export function segmentDir(outPath: string, routeId: string): string {
|
|
471
|
-
return `${outPath}/segments/${routeId}
|
|
472
|
+
return `${outPath}/segments/${routeId}`
|
|
472
473
|
}
|
|
473
474
|
export function treeSegmentFile(outPath: string, routeId: string): string {
|
|
474
|
-
return `${segmentDir(outPath, routeId)}/_tree.segment.rsc
|
|
475
|
+
return `${segmentDir(outPath, routeId)}/_tree.segment.rsc`
|
|
475
476
|
}
|
|
476
477
|
export function bodySegmentFile(outPath: string, routeId: string): string {
|
|
477
|
-
return `${segmentDir(outPath, routeId)}/index.segment.rsc
|
|
478
|
+
return `${segmentDir(outPath, routeId)}/index.segment.rsc`
|
|
478
479
|
}
|
|
479
480
|
export function segmentMetaFile(outPath: string, routeId: string): string {
|
|
480
|
-
return `${segmentDir(outPath, routeId)}/route.segment.meta
|
|
481
|
+
return `${segmentDir(outPath, routeId)}/route.segment.meta`
|
|
481
482
|
}
|
|
@@ -3,18 +3,18 @@
|
|
|
3
3
|
// machinery lives in vary-params.ts, which re-exports these for server callers.
|
|
4
4
|
|
|
5
5
|
/** The searchParams sentinel: any query access varies the whole query string. */
|
|
6
|
-
export const SEARCH_PARAMS_SENTINEL = '?'
|
|
6
|
+
export const SEARCH_PARAMS_SENTINEL = '?'
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Field separator inside a segment cache key. A NUL can never appear in a
|
|
10
10
|
* pathname, a route pattern, or a param value, so no field boundary is ambiguous
|
|
11
11
|
* (the same convention router.ts uses for its own composite cache keys).
|
|
12
12
|
*/
|
|
13
|
-
export const VARY_KEY_SEPARATOR = '\u0000'
|
|
13
|
+
export const VARY_KEY_SEPARATOR = '\u0000'
|
|
14
14
|
|
|
15
15
|
/** Next's floor on a prefetch reuse window, and its default when unreported. */
|
|
16
|
-
const MIN_PREFETCH_STALE_TIME_SECONDS = 30
|
|
17
|
-
const DEFAULT_PREFETCH_STALE_TIME_SECONDS = 300
|
|
16
|
+
const MIN_PREFETCH_STALE_TIME_SECONDS = 30
|
|
17
|
+
const DEFAULT_PREFETCH_STALE_TIME_SECONDS = 300
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* The reuse window (ms) for a prefetch response reporting `seconds` of staleness. Next clamps every
|
|
@@ -23,19 +23,19 @@ const DEFAULT_PREFETCH_STALE_TIME_SECONDS = 300;
|
|
|
23
23
|
* reveal refetches it - a prefetch loop, never a cache hit.
|
|
24
24
|
*/
|
|
25
25
|
export function getStaleTimeMs(seconds: number): number {
|
|
26
|
-
const reported = Number.isFinite(seconds) ? seconds : DEFAULT_PREFETCH_STALE_TIME_SECONDS
|
|
27
|
-
return Math.max(reported, MIN_PREFETCH_STALE_TIME_SECONDS) * 1000
|
|
26
|
+
const reported = Number.isFinite(seconds) ? seconds : DEFAULT_PREFETCH_STALE_TIME_SECONDS
|
|
27
|
+
return Math.max(reported, MIN_PREFETCH_STALE_TIME_SECONDS) * 1000
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
export function encodeVarySet(names: readonly string[], search = false): string {
|
|
31
|
-
const parts = search ? [...names, SEARCH_PARAMS_SENTINEL] : [...names]
|
|
32
|
-
return parts.join(',')
|
|
31
|
+
const parts = search ? [...names, SEARCH_PARAMS_SENTINEL] : [...names]
|
|
32
|
+
return parts.join(',')
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
export function decodeVarySet(text: string | null | undefined): string[] | null {
|
|
36
|
-
if (text === null || text === undefined) return null
|
|
37
|
-
if (text === '') return []
|
|
38
|
-
return text.split(',').filter(Boolean)
|
|
36
|
+
if (text === null || text === undefined) return null
|
|
37
|
+
if (text === '') return []
|
|
38
|
+
return text.split(',').filter(Boolean)
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
/**
|
|
@@ -48,29 +48,29 @@ export function decodeVarySet(text: string | null | undefined): string[] | null
|
|
|
48
48
|
*/
|
|
49
49
|
export function segmentVaryCacheKey(options: {
|
|
50
50
|
/** Route identity (the matched route pattern or id). */
|
|
51
|
-
route: string
|
|
51
|
+
route: string
|
|
52
52
|
/** Segment request path (`/_index`, `/_head`, `/_tree`, …). */
|
|
53
|
-
segmentPath: string
|
|
53
|
+
segmentPath: string
|
|
54
54
|
/** Concrete params of the URL being keyed. */
|
|
55
|
-
params: Readonly<Record<string, string | string[] | undefined
|
|
55
|
+
params: Readonly<Record<string, string | string[] | undefined>>
|
|
56
56
|
/** The URL's query string (with or without a leading `?`). */
|
|
57
|
-
search?: string
|
|
57
|
+
search?: string
|
|
58
58
|
/** The segment's vary set, or null when the server reported none. */
|
|
59
|
-
vary: readonly string[] | null
|
|
59
|
+
vary: readonly string[] | null
|
|
60
60
|
/** Full URL path, used verbatim when `vary` is null (unknown). */
|
|
61
|
-
pathname: string
|
|
61
|
+
pathname: string
|
|
62
62
|
}): string {
|
|
63
|
-
const { route, segmentPath, params, vary, pathname } = options
|
|
64
|
-
const search = normalizeSearch(options.search)
|
|
65
|
-
if (vary === null) return `${segmentPath}${VARY_KEY_SEPARATOR}!${pathname}${search}
|
|
66
|
-
const varied = [...vary].sort()
|
|
67
|
-
const parts: string[] = []
|
|
63
|
+
const { route, segmentPath, params, vary, pathname } = options
|
|
64
|
+
const search = normalizeSearch(options.search)
|
|
65
|
+
if (vary === null) return `${segmentPath}${VARY_KEY_SEPARATOR}!${pathname}${search}`
|
|
66
|
+
const varied = [...vary].sort()
|
|
67
|
+
const parts: string[] = []
|
|
68
68
|
for (const name of varied) {
|
|
69
|
-
if (name === SEARCH_PARAMS_SENTINEL) continue
|
|
70
|
-
parts.push(`${name}=${encodeParamValue(params[name])}`)
|
|
69
|
+
if (name === SEARCH_PARAMS_SENTINEL) continue
|
|
70
|
+
parts.push(`${name}=${encodeParamValue(params[name])}`)
|
|
71
71
|
}
|
|
72
|
-
const query = varied.includes(SEARCH_PARAMS_SENTINEL) ? search : ''
|
|
73
|
-
return `${segmentPath}${VARY_KEY_SEPARATOR}${route}${VARY_KEY_SEPARATOR}${parts.join('&')}${query}
|
|
72
|
+
const query = varied.includes(SEARCH_PARAMS_SENTINEL) ? search : ''
|
|
73
|
+
return `${segmentPath}${VARY_KEY_SEPARATOR}${route}${VARY_KEY_SEPARATOR}${parts.join('&')}${query}`
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
/**
|
|
@@ -80,23 +80,23 @@ export function segmentVaryCacheKey(options: {
|
|
|
80
80
|
* exactly the way the key does.
|
|
81
81
|
*/
|
|
82
82
|
export function normalizeSegmentSearch(search: string | undefined): string {
|
|
83
|
-
return normalizeSearch(search)
|
|
83
|
+
return normalizeSearch(search)
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
function normalizeSearch(search: string | undefined): string {
|
|
87
|
-
if (!search) return ''
|
|
88
|
-
const text = search.startsWith('?') ? search.slice(1) : search
|
|
89
|
-
if (!text) return ''
|
|
87
|
+
if (!search) return ''
|
|
88
|
+
const text = search.startsWith('?') ? search.slice(1) : search
|
|
89
|
+
if (!text) return ''
|
|
90
90
|
// `_rsc` is a CDN cache-buster, never an app param: it must not key entries.
|
|
91
|
-
const query = new URLSearchParams(text)
|
|
92
|
-
query.delete('_rsc')
|
|
93
|
-
const pairs = [...query.entries()].sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))
|
|
94
|
-
if (pairs.length === 0) return ''
|
|
95
|
-
return `?${pairs.map(([key, value]) => `${key}=${value}`).join('&')}
|
|
91
|
+
const query = new URLSearchParams(text)
|
|
92
|
+
query.delete('_rsc')
|
|
93
|
+
const pairs = [...query.entries()].sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))
|
|
94
|
+
if (pairs.length === 0) return ''
|
|
95
|
+
return `?${pairs.map(([key, value]) => `${key}=${value}`).join('&')}`
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
function encodeParamValue(value: string | string[] | undefined): string {
|
|
99
|
-
if (value === undefined) return 'absent'
|
|
100
|
-
if (Array.isArray(value)) return value.map(part => encodeURIComponent(part)).join('/')
|
|
101
|
-
return encodeURIComponent(value)
|
|
99
|
+
if (value === undefined) return 'absent'
|
|
100
|
+
if (Array.isArray(value)) return value.map(part => encodeURIComponent(part)).join('/')
|
|
101
|
+
return encodeURIComponent(value)
|
|
102
102
|
}
|