@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
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
// Process-wide state (the ALS) is anchored on globalThis: a pnext module can be loaded twice (built copy
|
|
18
18
|
// vs original) and a split ALS would silently drop every access recorded by the other copy.
|
|
19
19
|
|
|
20
|
-
import { AsyncLocalStorage } from 'node:async_hooks'
|
|
21
|
-
import { SEARCH_PARAMS_SENTINEL } from './vary-key'
|
|
20
|
+
import { AsyncLocalStorage } from 'node:async_hooks'
|
|
21
|
+
import { SEARCH_PARAMS_SENTINEL } from './vary-key'
|
|
22
22
|
|
|
23
23
|
// Pure keying/encoding helpers live in ./vary-key (browser-safe — the client
|
|
24
24
|
// segment cache imports them); re-exported here for server callers.
|
|
@@ -28,10 +28,10 @@ export {
|
|
|
28
28
|
encodeVarySet,
|
|
29
29
|
decodeVarySet,
|
|
30
30
|
segmentVaryCacheKey,
|
|
31
|
-
} from './vary-key'
|
|
31
|
+
} from './vary-key'
|
|
32
32
|
|
|
33
33
|
/** The set of param names a segment read. `'?'` means "any searchParams access". */
|
|
34
|
-
export type VaryParams = Set<string
|
|
34
|
+
export type VaryParams = Set<string>
|
|
35
35
|
|
|
36
36
|
/**
|
|
37
37
|
* Which segment of the route an accumulator belongs to.
|
|
@@ -42,7 +42,7 @@ export type VaryParams = Set<string>;
|
|
|
42
42
|
* now carry their segment kind so the response can publish the layout and page sets side by side and the
|
|
43
43
|
* client can re-fetch one frame while reusing the other.
|
|
44
44
|
*/
|
|
45
|
-
export type VarySegmentKind = 'page' | 'layout' | 'head' | 'root'
|
|
45
|
+
export type VarySegmentKind = 'page' | 'layout' | 'head' | 'root'
|
|
46
46
|
|
|
47
47
|
/**
|
|
48
48
|
* Accumulates vary params for a single segment (or for metadata/rootParams). Mirrors Next's
|
|
@@ -52,15 +52,15 @@ export type VarySegmentKind = 'page' | 'layout' | 'head' | 'root';
|
|
|
52
52
|
*/
|
|
53
53
|
export interface VaryParamsAccumulator {
|
|
54
54
|
/** Which route segment this accumulator tracks (page / layout / head / root). */
|
|
55
|
-
kind: VarySegmentKind
|
|
55
|
+
kind: VarySegmentKind
|
|
56
56
|
/** Mutable during render — accumulates param access. */
|
|
57
|
-
varyParams: VaryParams
|
|
57
|
+
varyParams: VaryParams
|
|
58
58
|
/** React thenable protocol: 'pending' until finishAccumulatingVaryParams. */
|
|
59
|
-
status: 'pending' | 'fulfilled'
|
|
60
|
-
value: VaryParams
|
|
61
|
-
then(onfulfilled?: ((value: VaryParams) => unknown) | null): void
|
|
59
|
+
status: 'pending' | 'fulfilled'
|
|
60
|
+
value: VaryParams
|
|
61
|
+
then(onfulfilled?: ((value: VaryParams) => unknown) | null): void
|
|
62
62
|
/** Callbacks waiting for resolution. */
|
|
63
|
-
resolvers: ((value: VaryParams) => unknown)[]
|
|
63
|
+
resolvers: ((value: VaryParams) => unknown)[]
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
/**
|
|
@@ -69,11 +69,11 @@ export interface VaryParamsAccumulator {
|
|
|
69
69
|
*/
|
|
70
70
|
export interface ResponseVaryParamsAccumulator {
|
|
71
71
|
/** metadata/viewport (the "head" segment). */
|
|
72
|
-
head: VaryParamsAccumulator
|
|
72
|
+
head: VaryParamsAccumulator
|
|
73
73
|
/** `next/root-params` accesses; merged into every other segment's set. */
|
|
74
|
-
rootParams: VaryParamsAccumulator
|
|
74
|
+
rootParams: VaryParamsAccumulator
|
|
75
75
|
/** One accumulator per rendered body segment (page + layouts). */
|
|
76
|
-
segments: Set<VaryParamsAccumulator
|
|
76
|
+
segments: Set<VaryParamsAccumulator>
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
export function createSegmentVaryParamsAccumulator(
|
|
@@ -85,16 +85,16 @@ export function createSegmentVaryParamsAccumulator(
|
|
|
85
85
|
status: 'pending',
|
|
86
86
|
value: new Set<string>(),
|
|
87
87
|
then(onfulfilled) {
|
|
88
|
-
if (!onfulfilled) return
|
|
89
|
-
if (accumulator.status === 'pending') accumulator.resolvers.push(onfulfilled)
|
|
90
|
-
else onfulfilled(accumulator.value)
|
|
88
|
+
if (!onfulfilled) return
|
|
89
|
+
if (accumulator.status === 'pending') accumulator.resolvers.push(onfulfilled)
|
|
90
|
+
else onfulfilled(accumulator.value)
|
|
91
91
|
},
|
|
92
92
|
resolvers: [],
|
|
93
|
-
}
|
|
94
|
-
return accumulator
|
|
93
|
+
}
|
|
94
|
+
return accumulator
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
const emptySet: VaryParams = new Set<string>()
|
|
97
|
+
const emptySet: VaryParams = new Set<string>()
|
|
98
98
|
|
|
99
99
|
/**
|
|
100
100
|
* A singleton accumulator already resolved to an empty set, for segments known
|
|
@@ -106,40 +106,40 @@ export const emptyVaryParamsAccumulator: VaryParamsAccumulator = {
|
|
|
106
106
|
status: 'fulfilled',
|
|
107
107
|
value: emptySet,
|
|
108
108
|
then(onfulfilled) {
|
|
109
|
-
if (onfulfilled) onfulfilled(emptySet)
|
|
109
|
+
if (onfulfilled) onfulfilled(emptySet)
|
|
110
110
|
},
|
|
111
111
|
resolvers: [],
|
|
112
|
-
}
|
|
112
|
+
}
|
|
113
113
|
|
|
114
114
|
export function createResponseVaryParamsAccumulator(): ResponseVaryParamsAccumulator {
|
|
115
115
|
return {
|
|
116
116
|
head: createSegmentVaryParamsAccumulator('head'),
|
|
117
117
|
rootParams: createSegmentVaryParamsAccumulator('root'),
|
|
118
118
|
segments: new Set<VaryParamsAccumulator>(),
|
|
119
|
-
}
|
|
119
|
+
}
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
// ---------------------------------------------------------------------------
|
|
123
123
|
// Response scope (ALS).
|
|
124
124
|
// ---------------------------------------------------------------------------
|
|
125
125
|
|
|
126
|
-
const VARY_PARAMS_GLOBALS = Symbol.for('pnext.compat.varyParamsGlobals')
|
|
126
|
+
const VARY_PARAMS_GLOBALS = Symbol.for('pnext.compat.varyParamsGlobals')
|
|
127
127
|
|
|
128
128
|
function varyGlobal<T>(name: string, create: () => T): T {
|
|
129
|
-
const root = globalThis as Record<PropertyKey, unknown
|
|
130
|
-
const container = (root[VARY_PARAMS_GLOBALS] ??= {}) as Record<string, unknown
|
|
131
|
-
if (!(name in container)) container[name] = create()
|
|
132
|
-
return container[name] as T
|
|
129
|
+
const root = globalThis as Record<PropertyKey, unknown>
|
|
130
|
+
const container = (root[VARY_PARAMS_GLOBALS] ??= {}) as Record<string, unknown>
|
|
131
|
+
if (!(name in container)) container[name] = create()
|
|
132
|
+
return container[name] as T
|
|
133
133
|
}
|
|
134
134
|
|
|
135
135
|
const varyStorage = varyGlobal(
|
|
136
136
|
'storage',
|
|
137
137
|
() => new AsyncLocalStorage<ResponseVaryParamsAccumulator>(),
|
|
138
|
-
)
|
|
138
|
+
)
|
|
139
139
|
|
|
140
140
|
/** The response accumulator of the render in progress, or null outside one. */
|
|
141
141
|
export function currentResponseVaryParams(): ResponseVaryParamsAccumulator | null {
|
|
142
|
-
return varyStorage.getStore() ?? null
|
|
142
|
+
return varyStorage.getStore() ?? null
|
|
143
143
|
}
|
|
144
144
|
|
|
145
145
|
/**
|
|
@@ -150,40 +150,37 @@ export function currentResponseVaryParams(): ResponseVaryParamsAccumulator | nul
|
|
|
150
150
|
export function createVaryParamsAccumulator(
|
|
151
151
|
kind: 'page' | 'layout' = 'page',
|
|
152
152
|
): VaryParamsAccumulator | null {
|
|
153
|
-
const response = varyStorage.getStore()
|
|
154
|
-
if (!response) return null
|
|
155
|
-
const accumulator = createSegmentVaryParamsAccumulator(kind)
|
|
156
|
-
response.segments.add(accumulator)
|
|
157
|
-
return accumulator
|
|
153
|
+
const response = varyStorage.getStore()
|
|
154
|
+
if (!response) return null
|
|
155
|
+
const accumulator = createSegmentVaryParamsAccumulator(kind)
|
|
156
|
+
response.segments.add(accumulator)
|
|
157
|
+
return accumulator
|
|
158
158
|
}
|
|
159
159
|
|
|
160
160
|
/** The HEAD (metadata/viewport) accumulator of the current response, or null. */
|
|
161
161
|
export function getMetadataVaryParamsAccumulator(): VaryParamsAccumulator | null {
|
|
162
|
-
return varyStorage.getStore()?.head ?? null
|
|
162
|
+
return varyStorage.getStore()?.head ?? null
|
|
163
163
|
}
|
|
164
164
|
|
|
165
165
|
// metadata and viewport ship in one payload, so they share one accumulator.
|
|
166
|
-
export const getViewportVaryParamsAccumulator = getMetadataVaryParamsAccumulator
|
|
166
|
+
export const getViewportVaryParamsAccumulator = getMetadataVaryParamsAccumulator
|
|
167
167
|
|
|
168
168
|
/** The rootParams accumulator of the current response, or null. */
|
|
169
169
|
export function getRootParamsVaryParamsAccumulator(): VaryParamsAccumulator | null {
|
|
170
|
-
return varyStorage.getStore()?.rootParams ?? null
|
|
170
|
+
return varyStorage.getStore()?.rootParams ?? null
|
|
171
171
|
}
|
|
172
172
|
|
|
173
173
|
/** Record that `paramName` was read by the segment owning `accumulator`. */
|
|
174
|
-
export function accumulateVaryParam(
|
|
175
|
-
accumulator: VaryParamsAccumulator,
|
|
176
|
-
paramName: string,
|
|
177
|
-
): void {
|
|
174
|
+
export function accumulateVaryParam(accumulator: VaryParamsAccumulator, paramName: string): void {
|
|
178
175
|
// The shared empty accumulator is immutable — never widen it.
|
|
179
|
-
if (accumulator === emptyVaryParamsAccumulator) return
|
|
180
|
-
accumulator.varyParams.add(paramName)
|
|
176
|
+
if (accumulator === emptyVaryParamsAccumulator) return
|
|
177
|
+
accumulator.varyParams.add(paramName)
|
|
181
178
|
}
|
|
182
179
|
|
|
183
180
|
/** Record a `next/root-params` access (varies every segment of the response). */
|
|
184
181
|
export function accumulateRootVaryParam(paramName: string): void {
|
|
185
|
-
const accumulator = getRootParamsVaryParamsAccumulator()
|
|
186
|
-
if (accumulator !== null) accumulateVaryParam(accumulator, paramName)
|
|
182
|
+
const accumulator = getRootParamsVaryParamsAccumulator()
|
|
183
|
+
if (accumulator !== null) accumulateVaryParam(accumulator, paramName)
|
|
187
184
|
}
|
|
188
185
|
|
|
189
186
|
// ---------------------------------------------------------------------------
|
|
@@ -198,12 +195,12 @@ export function accumulateRootVaryParam(paramName: string): void {
|
|
|
198
195
|
* A symbol key: it never enumerates, never serializes, and never collides with a param literally named
|
|
199
196
|
* `then`/`value`/`status`.
|
|
200
197
|
*/
|
|
201
|
-
const VARY_TRACKING = Symbol.for('pnext.compat.varyTracking')
|
|
198
|
+
const VARY_TRACKING = Symbol.for('pnext.compat.varyTracking')
|
|
202
199
|
|
|
203
200
|
export interface VaryTrackingInfo {
|
|
204
|
-
raw: Record<string, unknown
|
|
205
|
-
kind: 'params' | 'searchParams'
|
|
206
|
-
optionalCatchAllParam: string | null
|
|
201
|
+
raw: Record<string, unknown>
|
|
202
|
+
kind: 'params' | 'searchParams'
|
|
203
|
+
optionalCatchAllParam: string | null
|
|
207
204
|
}
|
|
208
205
|
|
|
209
206
|
function markVaryTracking(target: object, info: VaryTrackingInfo): void {
|
|
@@ -211,14 +208,14 @@ function markVaryTracking(target: object, info: VaryTrackingInfo): void {
|
|
|
211
208
|
value: info,
|
|
212
209
|
enumerable: false,
|
|
213
210
|
configurable: true,
|
|
214
|
-
})
|
|
211
|
+
})
|
|
215
212
|
}
|
|
216
213
|
|
|
217
214
|
/** The tracking info behind a params/searchParams view, or null when untracked. */
|
|
218
215
|
export function varyTrackingInfo(value: unknown): VaryTrackingInfo | null {
|
|
219
|
-
if (typeof value !== 'object' || value === null) return null
|
|
220
|
-
const info = (value as Record<PropertyKey, unknown>)[VARY_TRACKING]
|
|
221
|
-
return (info as VaryTrackingInfo | undefined) ?? null
|
|
216
|
+
if (typeof value !== 'object' || value === null) return null
|
|
217
|
+
const info = (value as Record<PropertyKey, unknown>)[VARY_TRACKING]
|
|
218
|
+
return (info as VaryTrackingInfo | undefined) ?? null
|
|
222
219
|
}
|
|
223
220
|
|
|
224
221
|
/**
|
|
@@ -241,53 +238,52 @@ export function createVaryingParams<T extends Record<string, unknown>>(
|
|
|
241
238
|
params: T,
|
|
242
239
|
optionalCatchAllParamName: string | null = null,
|
|
243
240
|
): T {
|
|
244
|
-
const originalParams = normalizeOptionalCatchAllParams(params, optionalCatchAllParamName)
|
|
241
|
+
const originalParams = normalizeOptionalCatchAllParams(params, optionalCatchAllParamName)
|
|
245
242
|
const info: VaryTrackingInfo = {
|
|
246
243
|
raw: originalParams,
|
|
247
244
|
kind: 'params',
|
|
248
245
|
optionalCatchAllParam: optionalCatchAllParamName,
|
|
249
|
-
}
|
|
246
|
+
}
|
|
250
247
|
if (optionalCatchAllParamName !== null) {
|
|
251
248
|
return new Proxy(originalParams, {
|
|
252
249
|
get(target, prop, receiver) {
|
|
253
|
-
if (prop === VARY_TRACKING) return info
|
|
250
|
+
if (prop === VARY_TRACKING) return info
|
|
254
251
|
if (
|
|
255
252
|
typeof prop === 'string' &&
|
|
256
|
-
(prop === optionalCatchAllParamName ||
|
|
257
|
-
Object.prototype.hasOwnProperty.call(target, prop))
|
|
253
|
+
(prop === optionalCatchAllParamName || Object.prototype.hasOwnProperty.call(target, prop))
|
|
258
254
|
) {
|
|
259
|
-
accumulateVaryParam(accumulator, prop)
|
|
255
|
+
accumulateVaryParam(accumulator, prop)
|
|
260
256
|
}
|
|
261
|
-
return Reflect.get(target, prop, receiver)
|
|
257
|
+
return Reflect.get(target, prop, receiver)
|
|
262
258
|
},
|
|
263
259
|
has(target, prop) {
|
|
264
260
|
if (prop === optionalCatchAllParamName) {
|
|
265
|
-
accumulateVaryParam(accumulator, optionalCatchAllParamName)
|
|
261
|
+
accumulateVaryParam(accumulator, optionalCatchAllParamName)
|
|
266
262
|
}
|
|
267
|
-
return Reflect.has(target, prop)
|
|
263
|
+
return Reflect.has(target, prop)
|
|
268
264
|
},
|
|
269
265
|
ownKeys(target) {
|
|
270
266
|
// Enumeration means user code may branch on which params exist, so the
|
|
271
267
|
// (possibly absent) optional param counts as read.
|
|
272
|
-
accumulateVaryParam(accumulator, optionalCatchAllParamName)
|
|
273
|
-
return Reflect.ownKeys(target)
|
|
268
|
+
accumulateVaryParam(accumulator, optionalCatchAllParamName)
|
|
269
|
+
return Reflect.ownKeys(target)
|
|
274
270
|
},
|
|
275
|
-
})
|
|
271
|
+
})
|
|
276
272
|
}
|
|
277
273
|
|
|
278
|
-
const tracked = {} as Record<string, unknown
|
|
274
|
+
const tracked = {} as Record<string, unknown>
|
|
279
275
|
for (const paramName in originalParams) {
|
|
280
276
|
Object.defineProperty(tracked, paramName, {
|
|
281
277
|
get() {
|
|
282
|
-
accumulateVaryParam(accumulator, paramName)
|
|
283
|
-
return originalParams[paramName]
|
|
278
|
+
accumulateVaryParam(accumulator, paramName)
|
|
279
|
+
return originalParams[paramName]
|
|
284
280
|
},
|
|
285
281
|
enumerable: true,
|
|
286
282
|
configurable: true,
|
|
287
|
-
})
|
|
283
|
+
})
|
|
288
284
|
}
|
|
289
|
-
markVaryTracking(tracked, info)
|
|
290
|
-
return tracked as T
|
|
285
|
+
markVaryTracking(tracked, info)
|
|
286
|
+
return tracked as T
|
|
291
287
|
}
|
|
292
288
|
|
|
293
289
|
/**
|
|
@@ -304,11 +300,11 @@ export function normalizeOptionalCatchAllParams<T extends Record<string, unknown
|
|
|
304
300
|
params: T,
|
|
305
301
|
optionalCatchAllParamName: string | null,
|
|
306
302
|
): T {
|
|
307
|
-
if (optionalCatchAllParamName === null) return params
|
|
308
|
-
const value = params[optionalCatchAllParamName]
|
|
309
|
-
if (!Array.isArray(value) || value.length > 0) return params
|
|
310
|
-
const { [optionalCatchAllParamName]: _empty, ...rest } = params
|
|
311
|
-
return rest as unknown as T
|
|
303
|
+
if (optionalCatchAllParamName === null) return params
|
|
304
|
+
const value = params[optionalCatchAllParamName]
|
|
305
|
+
if (!Array.isArray(value) || value.length > 0) return params
|
|
306
|
+
const { [optionalCatchAllParamName]: _empty, ...rest } = params
|
|
307
|
+
return rest as unknown as T
|
|
312
308
|
}
|
|
313
309
|
|
|
314
310
|
/**
|
|
@@ -324,33 +320,33 @@ export function createVaryingSearchParams<T extends Record<string, unknown>>(
|
|
|
324
320
|
raw: originalSearchParams,
|
|
325
321
|
kind: 'searchParams',
|
|
326
322
|
optionalCatchAllParam: null,
|
|
327
|
-
}
|
|
323
|
+
}
|
|
328
324
|
return new Proxy(originalSearchParams, {
|
|
329
325
|
get(target, prop, receiver) {
|
|
330
|
-
if (prop === VARY_TRACKING) return info
|
|
326
|
+
if (prop === VARY_TRACKING) return info
|
|
331
327
|
// `then` is probed by `await`/`Promise.resolve` on the wrapping promise;
|
|
332
328
|
// searchParams never legitimately carries it as a protocol member, but a
|
|
333
329
|
// real `?then=` query value must still read through as data. Only skip
|
|
334
330
|
// the sentinel when the key is absent (the probe case).
|
|
335
331
|
if (typeof prop === 'string' && !isPromiseProbe(target, prop)) {
|
|
336
|
-
accumulateVaryParam(accumulator, SEARCH_PARAMS_SENTINEL)
|
|
332
|
+
accumulateVaryParam(accumulator, SEARCH_PARAMS_SENTINEL)
|
|
337
333
|
}
|
|
338
|
-
return Reflect.get(target, prop, receiver)
|
|
334
|
+
return Reflect.get(target, prop, receiver)
|
|
339
335
|
},
|
|
340
336
|
has(target, prop) {
|
|
341
|
-
if (typeof prop === 'string') accumulateVaryParam(accumulator, SEARCH_PARAMS_SENTINEL)
|
|
342
|
-
return Reflect.has(target, prop)
|
|
337
|
+
if (typeof prop === 'string') accumulateVaryParam(accumulator, SEARCH_PARAMS_SENTINEL)
|
|
338
|
+
return Reflect.has(target, prop)
|
|
343
339
|
},
|
|
344
340
|
ownKeys(target) {
|
|
345
|
-
accumulateVaryParam(accumulator, SEARCH_PARAMS_SENTINEL)
|
|
346
|
-
return Reflect.ownKeys(target)
|
|
341
|
+
accumulateVaryParam(accumulator, SEARCH_PARAMS_SENTINEL)
|
|
342
|
+
return Reflect.ownKeys(target)
|
|
347
343
|
},
|
|
348
|
-
})
|
|
344
|
+
})
|
|
349
345
|
}
|
|
350
346
|
|
|
351
347
|
/** True for a `then` read on an object that has no such key (promise probing). */
|
|
352
348
|
function isPromiseProbe(target: object, prop: string): boolean {
|
|
353
|
-
return prop === 'then' && !Object.prototype.hasOwnProperty.call(target, prop)
|
|
349
|
+
return prop === 'then' && !Object.prototype.hasOwnProperty.call(target, prop)
|
|
354
350
|
}
|
|
355
351
|
|
|
356
352
|
// ---------------------------------------------------------------------------
|
|
@@ -363,24 +359,24 @@ function isPromiseProbe(target: object, prop: string): boolean {
|
|
|
363
359
|
* "unknown vary params" by the client (it then keys on the exact URL).
|
|
364
360
|
*/
|
|
365
361
|
export function finishAccumulatingVaryParams(response: ResponseVaryParamsAccumulator): void {
|
|
366
|
-
const rootVaryParams = response.rootParams.varyParams
|
|
367
|
-
finishSegmentAccumulator(response.head, rootVaryParams)
|
|
368
|
-
for (const segment of response.segments) finishSegmentAccumulator(segment, rootVaryParams)
|
|
369
|
-
finishSegmentAccumulator(response.rootParams, emptySet)
|
|
362
|
+
const rootVaryParams = response.rootParams.varyParams
|
|
363
|
+
finishSegmentAccumulator(response.head, rootVaryParams)
|
|
364
|
+
for (const segment of response.segments) finishSegmentAccumulator(segment, rootVaryParams)
|
|
365
|
+
finishSegmentAccumulator(response.rootParams, emptySet)
|
|
370
366
|
}
|
|
371
367
|
|
|
372
368
|
function finishSegmentAccumulator(
|
|
373
369
|
accumulator: VaryParamsAccumulator,
|
|
374
370
|
rootVaryParams: VaryParams,
|
|
375
371
|
): void {
|
|
376
|
-
if (accumulator.status !== 'pending') return
|
|
377
|
-
const merged = new Set<string>(accumulator.varyParams)
|
|
378
|
-
for (const param of rootVaryParams) merged.add(param)
|
|
379
|
-
accumulator.value = merged
|
|
380
|
-
accumulator.status = 'fulfilled'
|
|
381
|
-
const resolvers = accumulator.resolvers
|
|
382
|
-
accumulator.resolvers = []
|
|
383
|
-
for (const resolve of resolvers) resolve(merged)
|
|
372
|
+
if (accumulator.status !== 'pending') return
|
|
373
|
+
const merged = new Set<string>(accumulator.varyParams)
|
|
374
|
+
for (const param of rootVaryParams) merged.add(param)
|
|
375
|
+
accumulator.value = merged
|
|
376
|
+
accumulator.status = 'fulfilled'
|
|
377
|
+
const resolvers = accumulator.resolvers
|
|
378
|
+
accumulator.resolvers = []
|
|
379
|
+
for (const resolve of resolvers) resolve(merged)
|
|
384
380
|
}
|
|
385
381
|
|
|
386
382
|
/**
|
|
@@ -394,44 +390,44 @@ export interface ResponseVaryParams {
|
|
|
394
390
|
* `/_index` response carries layout AND page markup, so it is only byte-correct for a URL that matches
|
|
395
391
|
* both sets. The split frames below are what let the client reuse one half of it.
|
|
396
392
|
*/
|
|
397
|
-
params: string[]
|
|
393
|
+
params: string[]
|
|
398
394
|
/** Params the PAGE (leaf) segment read, sorted. */
|
|
399
|
-
page: string[]
|
|
395
|
+
page: string[]
|
|
400
396
|
/** Params the LAYOUT segments read, sorted (union across the layout chain). */
|
|
401
|
-
layout: string[]
|
|
397
|
+
layout: string[]
|
|
402
398
|
/** Params `generateMetadata`/`generateViewport` read, sorted. */
|
|
403
|
-
head: string[]
|
|
399
|
+
head: string[]
|
|
404
400
|
/** Params read through `next/root-params`, sorted. */
|
|
405
|
-
root: string[]
|
|
401
|
+
root: string[]
|
|
406
402
|
/** True when the body read searchParams in any way. */
|
|
407
|
-
search: boolean
|
|
403
|
+
search: boolean
|
|
408
404
|
/** True when the PAGE segment read searchParams. */
|
|
409
|
-
pageSearch: boolean
|
|
405
|
+
pageSearch: boolean
|
|
410
406
|
/** True when a LAYOUT segment read searchParams. */
|
|
411
|
-
layoutSearch: boolean
|
|
407
|
+
layoutSearch: boolean
|
|
412
408
|
/** True when the head read searchParams in any way. */
|
|
413
|
-
headSearch: boolean
|
|
409
|
+
headSearch: boolean
|
|
414
410
|
}
|
|
415
411
|
|
|
416
412
|
export function collectResponseVaryParams(
|
|
417
413
|
response: ResponseVaryParamsAccumulator,
|
|
418
414
|
): ResponseVaryParams {
|
|
419
|
-
finishAccumulatingVaryParams(response)
|
|
415
|
+
finishAccumulatingVaryParams(response)
|
|
420
416
|
// w9-segment-split: the per-kind sets are collected SEPARATELY (no union at
|
|
421
417
|
// the accumulator level). `params` is still published as their union, but
|
|
422
418
|
// only as the whole-`/_index`-document key — the layout/page sets are the
|
|
423
419
|
// ones the split frames key on.
|
|
424
|
-
const body = new Set<string>()
|
|
425
|
-
const page = new Set<string>()
|
|
426
|
-
const layout = new Set<string>()
|
|
420
|
+
const body = new Set<string>()
|
|
421
|
+
const page = new Set<string>()
|
|
422
|
+
const layout = new Set<string>()
|
|
427
423
|
for (const segment of response.segments) {
|
|
428
|
-
const target = segment.kind === 'layout' ? layout : page
|
|
424
|
+
const target = segment.kind === 'layout' ? layout : page
|
|
429
425
|
for (const name of segment.value) {
|
|
430
|
-
body.add(name)
|
|
431
|
-
target.add(name)
|
|
426
|
+
body.add(name)
|
|
427
|
+
target.add(name)
|
|
432
428
|
}
|
|
433
429
|
}
|
|
434
|
-
const head = new Set<string>(response.head.value)
|
|
430
|
+
const head = new Set<string>(response.head.value)
|
|
435
431
|
return {
|
|
436
432
|
params: sortedParamNames(body),
|
|
437
433
|
page: sortedParamNames(page),
|
|
@@ -442,11 +438,11 @@ export function collectResponseVaryParams(
|
|
|
442
438
|
pageSearch: page.has(SEARCH_PARAMS_SENTINEL),
|
|
443
439
|
layoutSearch: layout.has(SEARCH_PARAMS_SENTINEL),
|
|
444
440
|
headSearch: head.has(SEARCH_PARAMS_SENTINEL),
|
|
445
|
-
}
|
|
441
|
+
}
|
|
446
442
|
}
|
|
447
443
|
|
|
448
444
|
function sortedParamNames(set: VaryParams): string[] {
|
|
449
|
-
return [...set].filter(name => name !== SEARCH_PARAMS_SENTINEL).sort()
|
|
445
|
+
return [...set].filter(name => name !== SEARCH_PARAMS_SENTINEL).sort()
|
|
450
446
|
}
|
|
451
447
|
|
|
452
448
|
/**
|
|
@@ -458,11 +454,11 @@ function sortedParamNames(set: VaryParams): string[] {
|
|
|
458
454
|
export async function withVaryParamsTracking<T>(
|
|
459
455
|
produce: () => Promise<T>,
|
|
460
456
|
): Promise<{ value: T; vary: ResponseVaryParams }> {
|
|
461
|
-
const outer = varyStorage.getStore()
|
|
462
|
-
if (outer) return { value: await produce(), vary: collectResponseVaryParams(outer) }
|
|
463
|
-
const response = createResponseVaryParamsAccumulator()
|
|
464
|
-
const value = await varyStorage.run(response, produce)
|
|
465
|
-
return { value, vary: collectResponseVaryParams(response) }
|
|
457
|
+
const outer = varyStorage.getStore()
|
|
458
|
+
if (outer) return { value: await produce(), vary: collectResponseVaryParams(outer) }
|
|
459
|
+
const response = createResponseVaryParamsAccumulator()
|
|
460
|
+
const value = await varyStorage.run(response, produce)
|
|
461
|
+
return { value, vary: collectResponseVaryParams(response) }
|
|
466
462
|
}
|
|
467
463
|
|
|
468
464
|
// ---------------------------------------------------------------------------
|
|
@@ -477,15 +473,15 @@ export async function withVaryParamsTracking<T>(
|
|
|
477
473
|
/** The wire payload emitted alongside a segment/tree response. */
|
|
478
474
|
export interface SegmentVaryPayload {
|
|
479
475
|
/** Body-segment vary names (may include the `?` sentinel). */
|
|
480
|
-
params: string[]
|
|
476
|
+
params: string[]
|
|
481
477
|
/** Head-segment vary names (may include the `?` sentinel). */
|
|
482
|
-
head: string[]
|
|
478
|
+
head: string[]
|
|
483
479
|
/** Root-param vary names. */
|
|
484
|
-
root?: string[]
|
|
480
|
+
root?: string[]
|
|
485
481
|
/** w9-segment-split: the PAGE frame's own vary names. */
|
|
486
|
-
page?: string[]
|
|
482
|
+
page?: string[]
|
|
487
483
|
/** w9-segment-split: the LAYOUT frame's own vary names. */
|
|
488
|
-
layout?: string[]
|
|
484
|
+
layout?: string[]
|
|
489
485
|
}
|
|
490
486
|
|
|
491
487
|
export function toSegmentVaryPayload(vary: ResponseVaryParams): SegmentVaryPayload {
|
|
@@ -495,11 +491,11 @@ export function toSegmentVaryPayload(vary: ResponseVaryParams): SegmentVaryPaylo
|
|
|
495
491
|
page: encodeVaryNames(vary.page, vary.pageSearch),
|
|
496
492
|
layout: encodeVaryNames(vary.layout, vary.layoutSearch),
|
|
497
493
|
...(vary.root.length > 0 ? { root: vary.root } : {}),
|
|
498
|
-
}
|
|
494
|
+
}
|
|
499
495
|
}
|
|
500
496
|
|
|
501
497
|
function encodeVaryNames(names: readonly string[], search: boolean): string[] {
|
|
502
|
-
return search ? [...names, SEARCH_PARAMS_SENTINEL] : [...names]
|
|
498
|
+
return search ? [...names, SEARCH_PARAMS_SENTINEL] : [...names]
|
|
503
499
|
}
|
|
504
500
|
|
|
505
501
|
/**
|
|
@@ -509,17 +505,17 @@ function encodeVaryNames(names: readonly string[], search: boolean): string[] {
|
|
|
509
505
|
* segment publishes its own), so they come back empty.
|
|
510
506
|
*/
|
|
511
507
|
export function responseVaryParamsFromWire(wire: {
|
|
512
|
-
vary?: string[]
|
|
513
|
-
layoutVary?: string[]
|
|
514
|
-
pageVary?: string[]
|
|
508
|
+
vary?: string[]
|
|
509
|
+
layoutVary?: string[]
|
|
510
|
+
pageVary?: string[]
|
|
515
511
|
}): ResponseVaryParams {
|
|
516
512
|
const split = (names: readonly string[] | undefined): { names: string[]; search: boolean } => ({
|
|
517
513
|
names: (names ?? []).filter(name => name !== SEARCH_PARAMS_SENTINEL),
|
|
518
514
|
search: (names ?? []).includes(SEARCH_PARAMS_SENTINEL),
|
|
519
|
-
})
|
|
520
|
-
const body = split(wire.vary)
|
|
521
|
-
const layout = split(wire.layoutVary)
|
|
522
|
-
const page = split(wire.pageVary)
|
|
515
|
+
})
|
|
516
|
+
const body = split(wire.vary)
|
|
517
|
+
const layout = split(wire.layoutVary)
|
|
518
|
+
const page = split(wire.pageVary)
|
|
523
519
|
return {
|
|
524
520
|
params: body.names,
|
|
525
521
|
page: page.names,
|
|
@@ -530,7 +526,7 @@ export function responseVaryParamsFromWire(wire: {
|
|
|
530
526
|
pageSearch: page.search,
|
|
531
527
|
layoutSearch: layout.search,
|
|
532
528
|
headSearch: false,
|
|
533
|
-
}
|
|
529
|
+
}
|
|
534
530
|
}
|
|
535
531
|
|
|
536
532
|
/** The wire vary names for one segment kind of a finished response. */
|
|
@@ -540,12 +536,12 @@ export function varyNamesFor(
|
|
|
540
536
|
): string[] {
|
|
541
537
|
switch (kind) {
|
|
542
538
|
case 'head':
|
|
543
|
-
return encodeVaryNames(vary.head, vary.headSearch)
|
|
539
|
+
return encodeVaryNames(vary.head, vary.headSearch)
|
|
544
540
|
case 'page':
|
|
545
|
-
return encodeVaryNames(vary.page, vary.pageSearch)
|
|
541
|
+
return encodeVaryNames(vary.page, vary.pageSearch)
|
|
546
542
|
case 'layout':
|
|
547
|
-
return encodeVaryNames(vary.layout, vary.layoutSearch)
|
|
543
|
+
return encodeVaryNames(vary.layout, vary.layoutSearch)
|
|
548
544
|
default:
|
|
549
|
-
return encodeVaryNames(vary.params, vary.search)
|
|
545
|
+
return encodeVaryNames(vary.params, vary.search)
|
|
550
546
|
}
|
|
551
547
|
}
|
|
@@ -1,33 +1,35 @@
|
|
|
1
|
-
import { AsyncLocalStorage } from 'node:async_hooks'
|
|
1
|
+
import { AsyncLocalStorage } from 'node:async_hooks'
|
|
2
2
|
|
|
3
3
|
// globalThis-anchored (this module can be loaded twice — original + built copy
|
|
4
4
|
// — and both must observe the same scope; see the use-cache module-duplication
|
|
5
5
|
// incident).
|
|
6
|
-
const GSP_SCOPE = Symbol.for('pnext.generateStaticParamsScope')
|
|
6
|
+
const GSP_SCOPE = Symbol.for('pnext.generateStaticParamsScope')
|
|
7
7
|
interface GspScope {
|
|
8
8
|
/** Params provided by parent generateStaticParams calls. */
|
|
9
|
-
provided: Record<string, unknown
|
|
9
|
+
provided: Record<string, unknown>
|
|
10
10
|
}
|
|
11
|
-
const globals = globalThis as { [GSP_SCOPE]?: AsyncLocalStorage<GspScope> }
|
|
12
|
-
const gspScope = (globals[GSP_SCOPE] ??= new AsyncLocalStorage<GspScope>())
|
|
11
|
+
const globals = globalThis as { [GSP_SCOPE]?: AsyncLocalStorage<GspScope> }
|
|
12
|
+
const gspScope = (globals[GSP_SCOPE] ??= new AsyncLocalStorage<GspScope>())
|
|
13
13
|
|
|
14
14
|
/** The active generateStaticParams scope, or undefined outside one. */
|
|
15
15
|
export function generateStaticParamsScope(): GspScope | undefined {
|
|
16
|
-
return gspScope.getStore()
|
|
16
|
+
return gspScope.getStore()
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
export function aliasGenerateStaticParams(
|
|
19
|
+
export function aliasGenerateStaticParams(
|
|
20
|
+
module: Record<string, unknown>,
|
|
21
|
+
): Record<string, unknown> {
|
|
20
22
|
if (typeof module.params === 'function' || typeof module.generateStaticParams !== 'function') {
|
|
21
|
-
return module
|
|
23
|
+
return module
|
|
22
24
|
}
|
|
23
25
|
const generate = module.generateStaticParams as (args?: {
|
|
24
|
-
params?: Record<string, unknown
|
|
25
|
-
}) => unknown
|
|
26
|
+
params?: Record<string, unknown>
|
|
27
|
+
}) => unknown
|
|
26
28
|
// Wrap so root-params getters can tell they are running inside a
|
|
27
29
|
// generateStaticParams call (and which parent params are available) —
|
|
28
30
|
// reading a root param inside the generateStaticParams that defines it is a
|
|
29
31
|
// build error (app-root-params-getters/generate-static-params-error).
|
|
30
32
|
const params = (args?: { params?: Record<string, unknown> }) =>
|
|
31
|
-
gspScope.run({ provided: args?.params ?? {} }, () => generate(args))
|
|
32
|
-
return { ...module, params }
|
|
33
|
+
gspScope.run({ provided: args?.params ?? {} }, () => generate(args))
|
|
34
|
+
return { ...module, params }
|
|
33
35
|
}
|