@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
package/reference/routing.md
CHANGED
|
@@ -1,167 +1,157 @@
|
|
|
1
1
|
# Routing
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Routes come from the file tree under `app/`. Directories make the URL path, and a `page` file inside one renders it as its default export.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
- `app/**/layout` exports metadata and can wrap descendant pages.
|
|
7
|
-
- `app/**/route` defines HTTP handlers.
|
|
8
|
-
- `proxy` or `middleware` runs before route matching.
|
|
9
|
-
- `app/**/loading` defines a Suspense fallback for the segment.
|
|
10
|
-
- `app/**/error` defines fallback UI for server render failures in the segment.
|
|
11
|
-
- `app/**/not-found` defines fallback UI.
|
|
5
|
+
## Path patterns
|
|
12
6
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
7
|
+
| Directory | Serves |
|
|
8
|
+
| -------------------------- | --------------------------------------- |
|
|
9
|
+
| `app/about/` | `/about` |
|
|
10
|
+
| `app/users/[id]/` | `/users/:id` |
|
|
11
|
+
| `app/docs/[...slug]/` | `/docs/*` |
|
|
12
|
+
| `app/docs/[[...slug]]/` | `/docs` and `/docs/*` |
|
|
13
|
+
| `app/(marketing)/pricing/` | `/pricing`, the group adds no segment |
|
|
14
|
+
| `app/dashboard/@team/` | a slot of `/dashboard`, no path segment |
|
|
16
15
|
|
|
17
|
-
##
|
|
16
|
+
## Convention files
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
18
|
+
| File | What it does |
|
|
19
|
+
| -------------- | --------------------------------------------------------- |
|
|
20
|
+
| `page` | Renders a UI route. |
|
|
21
|
+
| `layout` | Exports metadata and can wrap descendant pages. |
|
|
22
|
+
| `route` | Defines HTTP handlers. |
|
|
23
|
+
| `loading` | Suspense fallback for the segment. |
|
|
24
|
+
| `error` | Fallback UI when server rendering throws in the segment. |
|
|
25
|
+
| `not-found` | Fallback UI for `notFound()` and unmatched URLs. |
|
|
26
|
+
| `template` | Wraps children like a layout, but re-renders per request. |
|
|
27
|
+
| `default` | Fallback for a parallel slot with no page match. |
|
|
28
|
+
| `global-error` | Replaces the whole document for an uncaught root error. |
|
|
25
29
|
|
|
26
|
-
|
|
30
|
+
Convention files are matched across `.tsx`, `.ts`, `.jsx`, `.js`, and `.mjs`, with the TypeScript extensions tried first. Route handlers are the exception: they do not match `.jsx`. A proxy file lives at the project root rather than in a segment, and is covered under [Proxy](#proxy).
|
|
27
31
|
|
|
28
|
-
|
|
29
|
-
is stripped from the resulting path. See [Intercepting routes](#intercepting-routes).
|
|
32
|
+
Behavior worth knowing:
|
|
30
33
|
|
|
31
|
-
- `
|
|
32
|
-
- `
|
|
33
|
-
- `
|
|
34
|
-
- `
|
|
34
|
+
- `loading`: static builds wait for the final HTML, while dev and server responses can stream the fallback first.
|
|
35
|
+
- `error`: receives `error`, `reset`, and `unstable_retry`. Both callbacks refresh the current route in `compat.next` apps.
|
|
36
|
+
- `not-found`: `pnext build` also writes `404.html` when the app root has one.
|
|
37
|
+
- `global-error`: renders its own `<html>` and `<body>`, so pnext serves that markup instead of the normal document shell. A nearer error boundary wins, and a `"use client"` directive opts the file out.
|
|
38
|
+
- `template`: nesting order is layout, then template, then children. A segment with no layout still applies its template.
|
|
39
|
+
- `forbidden` and `unauthorized`: experimental `compat.next` boundaries that render 403 and 401 responses. Without compat, the thrown errors take the normal error path. The `forbidden()` and `unauthorized()` functions are core exports either way. See [Navigation](./navigation.md#auth-interrupts).
|
|
35
40
|
|
|
36
|
-
|
|
41
|
+
To leave a route, use `redirect()` or `notFound()`. See [Navigation](./navigation.md#redirects-and-not-found).
|
|
42
|
+
|
|
43
|
+
## Page props
|
|
37
44
|
|
|
38
45
|
Pages receive explicit props:
|
|
39
46
|
|
|
40
47
|
```ts
|
|
41
48
|
type PageProps<P = Record<string, string | string[]>> = {
|
|
42
|
-
params: Promise<P
|
|
43
|
-
searchParams: Promise<Record<string, string | string[] | undefined
|
|
44
|
-
request?: NextRequest
|
|
45
|
-
}
|
|
49
|
+
params: Promise<P>
|
|
50
|
+
searchParams: Promise<Record<string, string | string[] | undefined>>
|
|
51
|
+
request?: NextRequest
|
|
52
|
+
}
|
|
46
53
|
```
|
|
47
54
|
|
|
48
|
-
|
|
55
|
+
Read request data from the request prop. Typed per-route versions of these props are generated for you; see [Type Safety](./typegen.md).
|
|
49
56
|
|
|
50
|
-
## Route
|
|
57
|
+
## Route handlers
|
|
51
58
|
|
|
52
|
-
|
|
59
|
+
A `route` file exports one function per HTTP method. The request extends the standard `Request` with convenience access for cookies and `nextUrl`, and the context carries the route params.
|
|
53
60
|
|
|
54
61
|
```ts
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const { id } = await params
|
|
60
|
-
return Response.json({
|
|
61
|
-
id,
|
|
62
|
-
q: request.nextUrl.searchParams.get('q'),
|
|
63
|
-
});
|
|
62
|
+
export async function GET(
|
|
63
|
+
request: NextRequest,
|
|
64
|
+
{ params }: RouteContext,
|
|
65
|
+
) {
|
|
66
|
+
const { id } = await params
|
|
67
|
+
return Response.json({ id })
|
|
64
68
|
}
|
|
65
69
|
```
|
|
66
70
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
If `OPTIONS` is not exported, pnext returns an automatic `OPTIONS` response with an `Allow` header. Unsupported methods return `405 Method Not Allowed` with the same `Allow` header.
|
|
71
|
+
If a handler does not export `OPTIONS`, pnext answers with an automatic response carrying an `Allow` header. Unsupported methods get a 405 with that same header.
|
|
70
72
|
|
|
71
|
-
Static `GET`
|
|
73
|
+
Static `GET` handlers are written as files during the build. A dynamic handler can export `params()` to write selected param outputs at build time.
|
|
72
74
|
|
|
73
|
-
|
|
75
|
+
## Static and dynamic routes
|
|
74
76
|
|
|
75
|
-
|
|
77
|
+
pnext infers rendering from what a route uses:
|
|
76
78
|
|
|
77
|
-
|
|
79
|
+
- Static: no dynamic params and no request prop usage.
|
|
80
|
+
- Dynamic: request prop usage or dynamic route segments.
|
|
78
81
|
|
|
79
|
-
|
|
80
|
-
- `dynamic`: request prop usage or dynamic route segments.
|
|
82
|
+
Segment config overrides the inference. Hydration is inferred separately, from `"use client"`.
|
|
81
83
|
|
|
82
|
-
Route segment config
|
|
84
|
+
## Route segment config
|
|
83
85
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
Pages, layouts, and route handlers can export segment config. Values must be literals — they are read from the source, not evaluated.
|
|
86
|
+
Pages, layouts, and route handlers can export segment config. Values must be literals, because they are read from the source rather than evaluated.
|
|
87
87
|
|
|
88
88
|
```ts
|
|
89
|
-
export const dynamic = 'force-dynamic'
|
|
90
|
-
export const maxDuration = 60
|
|
89
|
+
export const dynamic = 'force-dynamic'
|
|
90
|
+
export const maxDuration = 60
|
|
91
91
|
```
|
|
92
92
|
|
|
93
|
-
|
|
93
|
+
- `dynamic`: `auto`, `force-dynamic`, `force-static`, or `error`.
|
|
94
|
+
- `revalidate`: a non-negative number, or `false`.
|
|
95
|
+
- `dynamicParams`: `false` restricts the route to its generated params.
|
|
96
|
+
- `runtime`: `edge` or `nodejs`.
|
|
97
|
+
- `maxDuration`: seconds, copied into the generated Vercel Node function metadata.
|
|
98
|
+
- `fetchCache`: `auto`, `default-cache`, `only-cache`, `force-cache`, `force-no-store`, `default-no-store`, or `only-no-store`.
|
|
99
|
+
- `prefetch`: `allow-runtime`, `partial`, or `unstable_eager`.
|
|
100
|
+
- `unstable_instant`: experimental, described below.
|
|
101
|
+
|
|
102
|
+
Config merges across the route's own file and its layout chain, leaf-first, so the nearest declaration wins. Two values behave differently: `force-dynamic` on any segment forces the whole route, and the lowest declared `revalidate` wins.
|
|
94
103
|
|
|
95
|
-
|
|
104
|
+
Setting `dynamicParams` to false applies to the dynamic segment declared by that file. When every dynamic segment has static params, requests must match a generated param tuple. Otherwise pnext drops the restriction and renders the route on demand. A page-level static params export makes this check apply to the complete param tuple.
|
|
96
105
|
|
|
97
|
-
|
|
106
|
+
`unstable_instant` is experimental. Set it to `true` or to an object of samples to opt in, and a leaf `false` overrides a layout opt-in. A full prefetch of such a route uses sampled request data and leaves `connection()`-gated content out of that prefetch render.
|
|
98
107
|
|
|
99
|
-
|
|
108
|
+
`experimental_ppr` is also experimental. For a request-using page without dynamic route segments, it records the page as a partial-prerendering candidate. See [Rendering](./rendering.md#experimental-partial-prerendering-and-cachecomponents).
|
|
100
109
|
|
|
101
|
-
`
|
|
110
|
+
`preferredRegion` is a `compat.next`-only export. It accepts a string or string array and is written to compat deployment metadata.
|
|
111
|
+
|
|
112
|
+
## Proxy
|
|
113
|
+
|
|
114
|
+
A `proxy` file at the project root runs before static files, pages, and route handlers.
|
|
102
115
|
|
|
103
116
|
```ts
|
|
104
|
-
import { NextResponse, type NextRequest } from '@wular/pnext/server'
|
|
117
|
+
import { NextResponse, type NextRequest } from '@wular/pnext/server'
|
|
105
118
|
|
|
106
|
-
export const config = {
|
|
107
|
-
matcher: ['/admin/:path*'],
|
|
108
|
-
};
|
|
119
|
+
export const config = { matcher: ['/admin/:path*'] }
|
|
109
120
|
|
|
110
121
|
export function proxy(request: NextRequest) {
|
|
111
122
|
if (!request.cookies.has('session')) {
|
|
112
|
-
return NextResponse.redirect(new URL('/login', request.url))
|
|
123
|
+
return NextResponse.redirect(new URL('/login', request.url))
|
|
113
124
|
}
|
|
114
|
-
return NextResponse.next()
|
|
125
|
+
return NextResponse.next()
|
|
115
126
|
}
|
|
116
127
|
```
|
|
117
128
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
- `NextResponse.next()` continues to the matched static file, page, or route handler.
|
|
121
|
-
- `NextResponse.redirect(url)` returns a redirect response.
|
|
122
|
-
- `NextResponse.rewrite(url)` serves another path without changing the browser URL.
|
|
123
|
-
- `new Response(...)` returns a custom response directly.
|
|
124
|
-
|
|
125
|
-
`config.matcher` takes a string, a string array, or objects with `source` plus `has`/`missing` conditions (`header`, `query`, `cookie`, `host`). Patterns support exact paths, `:param`, `:path*`, and regex. With no `matcher`, every request runs through the proxy.
|
|
129
|
+
Return one of:
|
|
126
130
|
|
|
127
|
-
`
|
|
131
|
+
- `NextResponse.next()` to continue to the matched static file, page, or route handler.
|
|
132
|
+
- `NextResponse.redirect(url)` for a redirect response.
|
|
133
|
+
- `NextResponse.rewrite(url)` to serve another path without changing the browser URL.
|
|
134
|
+
- `new Response(...)` for a custom response.
|
|
128
135
|
|
|
129
|
-
|
|
136
|
+
The matcher accepts a string, an array of strings, or objects with a source pattern plus `has` and `missing` conditions on header, query, cookie, and host. Patterns support exact paths, `:param`, `:path*`, and regex. Without a matcher, every request runs through the proxy.
|
|
130
137
|
|
|
131
|
-
`
|
|
138
|
+
A `middleware` file works the same way and is supported for compatibility. Use a proxy file for new code, and note that it wins if both exist.
|
|
132
139
|
|
|
133
|
-
|
|
134
|
-
Validate redirect targets that come from user input.
|
|
140
|
+
## Static params
|
|
135
141
|
|
|
136
|
-
`
|
|
142
|
+
Export `params()` from a dynamic route to choose which params `pnext build` writes as static HTML. See the typed example in [Type Safety](./typegen.md). Under `compat.next`, `generateStaticParams()` fills the same role when a module has no `params()` export.
|
|
137
143
|
|
|
138
|
-
|
|
144
|
+
## Parallel routes
|
|
139
145
|
|
|
140
|
-
`
|
|
146
|
+
A slot directory such as `@team` contributes no path segment. Its content is rendered and passed to the owning segment's layout as a prop named after the slot, alongside `children`. A slot uses its `page` when present, then its `default` fallback, and otherwise renders nothing. A slot's `loading` file wraps its content in a Suspense boundary.
|
|
141
147
|
|
|
142
|
-
|
|
148
|
+
## Intercepting routes
|
|
143
149
|
|
|
144
|
-
|
|
150
|
+
A marker prefixed to a segment intercepts a route from another level, and is stripped from the resulting path:
|
|
145
151
|
|
|
146
|
-
|
|
152
|
+
- `(.)segment` intercepts from the same level.
|
|
153
|
+
- `(..)segment` intercepts from one level up.
|
|
154
|
+
- `(..)(..)segment` intercepts from two levels up.
|
|
155
|
+
- `(...)segment` intercepts from the app root.
|
|
147
156
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
An interception marker (`(.)`, `(..)`, `(..)(..)`, `(...)`) makes the route respond to soft navigations toward the marked target from the intercepting level, usually rendered into a parallel `@slot`. Hard requests render the non-intercepted target. Intercepting routes are always dynamic and never take static params.
|
|
151
|
-
|
|
152
|
-
## Static Params
|
|
153
|
-
|
|
154
|
-
Use `params()` on a dynamic route to choose params that `pnext build` should write as static HTML.
|
|
155
|
-
Requests outside the returned list keep using dynamic rendering.
|
|
156
|
-
|
|
157
|
-
```tsx
|
|
158
|
-
import type { PageProps, StaticParams } from '#gen/app/users/[id]/page';
|
|
159
|
-
|
|
160
|
-
export function params(): StaticParams {
|
|
161
|
-
return [{ id: 'ada' }, { id: 'grace' }];
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
export default async function Page({ params }: PageProps) {
|
|
165
|
-
return <p>{(await params).id}</p>;
|
|
166
|
-
}
|
|
167
|
-
```
|
|
157
|
+
The intercepting route answers soft navigations toward the marked target, usually rendering into a parallel slot. A hard request renders the non-intercepted target instead. Intercepting routes are always dynamic and never take static params.
|
package/reference/typegen.md
CHANGED
|
@@ -1,57 +1,49 @@
|
|
|
1
1
|
# Type Safety
|
|
2
2
|
|
|
3
|
-
pnext generates
|
|
3
|
+
pnext generates types from the `app/` tree so route params, static params, route handler context, and links are all checked.
|
|
4
4
|
|
|
5
|
-
## Route
|
|
5
|
+
## Route types
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Each route imports the types generated for its own file path. pnext validates the exports against the route inferred from that path, so a wrong param name, a bad static param shape, or the wrong handler context fails TypeScript.
|
|
8
8
|
|
|
9
9
|
```tsx
|
|
10
10
|
// app/users/[id]/page.tsx
|
|
11
|
-
import type {
|
|
11
|
+
import type {
|
|
12
|
+
PageProps,
|
|
13
|
+
StaticParams,
|
|
14
|
+
} from '#gen/app/users/[id]/page'
|
|
12
15
|
|
|
13
16
|
export function params(): StaticParams {
|
|
14
|
-
return [{ id: 'ada' }]
|
|
17
|
+
return [{ id: 'ada' }]
|
|
15
18
|
}
|
|
16
19
|
|
|
17
20
|
export default async function Page({ params }: PageProps) {
|
|
18
|
-
return <p>{(await params).id}</p
|
|
21
|
+
return <p>{(await params).id}</p>
|
|
19
22
|
}
|
|
20
23
|
```
|
|
21
24
|
|
|
22
|
-
|
|
25
|
+
A route handler takes its generated context type as the second argument.
|
|
23
26
|
|
|
24
27
|
```ts
|
|
25
28
|
// app/users/[id]/route.ts
|
|
26
|
-
import type { RouteContext } from '#gen/app/users/[id]/route'
|
|
27
|
-
import type { NextRequest } from '@wular/pnext/server'
|
|
28
|
-
|
|
29
|
-
export async function GET(
|
|
30
|
-
|
|
29
|
+
import type { RouteContext } from '#gen/app/users/[id]/route'
|
|
30
|
+
import type { NextRequest } from '@wular/pnext/server'
|
|
31
|
+
|
|
32
|
+
export async function GET(
|
|
33
|
+
request: NextRequest,
|
|
34
|
+
{ params }: RouteContext,
|
|
35
|
+
) {
|
|
36
|
+
return Response.json({ id: (await params).id })
|
|
31
37
|
}
|
|
32
38
|
```
|
|
33
39
|
|
|
34
40
|
## Links
|
|
35
41
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
```tsx
|
|
39
|
-
import { Link } from '@wular/pnext/link';
|
|
40
|
-
|
|
41
|
-
export function Nav() {
|
|
42
|
-
return <Link href="/users/[id]" params={{ id: 'ada' }}>Ada</Link>;
|
|
43
|
-
}
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
Use a normal `<a>` for external URLs or intentionally untyped links.
|
|
47
|
-
|
|
48
|
-
## Generated Types
|
|
49
|
-
|
|
50
|
-
`pnext dev` and `pnext build` refresh generated types automatically. Use `pnext typegen` to refresh them manually.
|
|
42
|
+
`<Link>` and `href()` check their route template and params against the same generated types. See [Navigation](./navigation.md).
|
|
51
43
|
|
|
52
|
-
|
|
44
|
+
## Setup
|
|
53
45
|
|
|
54
|
-
|
|
46
|
+
Apps from `pnext create` are already set up. The package ships the `@wular/pnext/config/ts/react.json` preset, which the scaffold puts in `extends` alongside the alias for generated types:
|
|
55
47
|
|
|
56
48
|
```json
|
|
57
49
|
{
|
|
@@ -62,3 +54,9 @@ Use a TypeScript path alias for generated imports:
|
|
|
62
54
|
}
|
|
63
55
|
}
|
|
64
56
|
```
|
|
57
|
+
|
|
58
|
+
Include `.pnext/types/**/*.ts` in the app TypeScript project so the editor and `tsc` can see the generated files. `pnext migrate` repoints existing include paths there, but it does not add the alias.
|
|
59
|
+
|
|
60
|
+
## Regenerating
|
|
61
|
+
|
|
62
|
+
The dev server and the build refresh generated types on their own. Run `pnext typegen` to refresh them by hand. The files live in `.pnext/types` and should not be edited.
|
package/src/api/cache.ts
CHANGED
|
@@ -1,80 +1,79 @@
|
|
|
1
|
-
import { currentCacheScope, type CacheNode } from '../cache
|
|
1
|
+
import { currentCacheScope, type CacheNode } from '../request/cache'
|
|
2
2
|
|
|
3
3
|
export function cache<Args extends unknown[], Result>(
|
|
4
4
|
fn: (...args: Args) => Result,
|
|
5
5
|
): (...args: Args) => Result {
|
|
6
6
|
return (...args: Args) => {
|
|
7
|
-
const scope = currentCacheScope()
|
|
8
|
-
if (!scope) return fn(...args)
|
|
7
|
+
const scope = currentCacheScope()
|
|
8
|
+
if (!scope) return fn(...args)
|
|
9
9
|
|
|
10
|
-
let root = scope.functions.get(fn)
|
|
10
|
+
let root = scope.functions.get(fn)
|
|
11
11
|
if (!root) {
|
|
12
|
-
root = cacheNode()
|
|
13
|
-
scope.functions.set(fn, root)
|
|
12
|
+
root = cacheNode()
|
|
13
|
+
scope.functions.set(fn, root)
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
const node = cacheNodeForArgs(root, args)
|
|
17
|
-
const record = node.record
|
|
16
|
+
const node = cacheNodeForArgs(root, args)
|
|
17
|
+
const record = node.record
|
|
18
18
|
if (record) {
|
|
19
19
|
if (record.status === 'rejected') {
|
|
20
20
|
if (record.async) {
|
|
21
21
|
return Promise.resolve().then(() => {
|
|
22
|
-
throw record.error
|
|
23
|
-
}) as Result
|
|
22
|
+
throw record.error
|
|
23
|
+
}) as Result
|
|
24
24
|
}
|
|
25
|
-
throw record.error
|
|
25
|
+
throw record.error
|
|
26
26
|
}
|
|
27
|
-
if (record.status === 'resolved' && record.async)
|
|
28
|
-
|
|
27
|
+
if (record.status === 'resolved' && record.async)
|
|
28
|
+
return Promise.resolve(record.value) as Result
|
|
29
|
+
return record.value as Result
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
try {
|
|
32
|
-
const value = fn(...args)
|
|
33
|
+
const value = fn(...args)
|
|
33
34
|
if (isPromiseLike(value)) {
|
|
34
35
|
const promise = Promise.resolve(value).then(
|
|
35
36
|
result => {
|
|
36
|
-
node.record = { status: 'resolved', value: result, async: true }
|
|
37
|
-
return result
|
|
37
|
+
node.record = { status: 'resolved', value: result, async: true }
|
|
38
|
+
return result
|
|
38
39
|
},
|
|
39
40
|
error => {
|
|
40
|
-
node.record = { status: 'rejected', error, async: true }
|
|
41
|
-
throw error
|
|
41
|
+
node.record = { status: 'rejected', error, async: true }
|
|
42
|
+
throw error
|
|
42
43
|
},
|
|
43
|
-
)
|
|
44
|
-
node.record = { status: 'pending', value: promise }
|
|
45
|
-
return promise as Result
|
|
44
|
+
)
|
|
45
|
+
node.record = { status: 'pending', value: promise }
|
|
46
|
+
return promise as Result
|
|
46
47
|
}
|
|
47
48
|
|
|
48
|
-
node.record = { status: 'resolved', value, async: false }
|
|
49
|
-
return value
|
|
49
|
+
node.record = { status: 'resolved', value, async: false }
|
|
50
|
+
return value
|
|
50
51
|
} catch (error) {
|
|
51
|
-
node.record = { status: 'rejected', error, async: false }
|
|
52
|
-
throw error
|
|
52
|
+
node.record = { status: 'rejected', error, async: false }
|
|
53
|
+
throw error
|
|
53
54
|
}
|
|
54
|
-
}
|
|
55
|
+
}
|
|
55
56
|
}
|
|
56
57
|
|
|
57
58
|
function cacheNode(): CacheNode {
|
|
58
|
-
return { children: new Map() }
|
|
59
|
+
return { children: new Map() }
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
function cacheNodeForArgs(root: CacheNode, args: unknown[]) {
|
|
62
|
-
let node = root
|
|
63
|
+
let node = root
|
|
63
64
|
for (const arg of args) {
|
|
64
|
-
let child = node.children.get(arg)
|
|
65
|
+
let child = node.children.get(arg)
|
|
65
66
|
if (!child) {
|
|
66
|
-
child = cacheNode()
|
|
67
|
-
node.children.set(arg, child)
|
|
67
|
+
child = cacheNode()
|
|
68
|
+
node.children.set(arg, child)
|
|
68
69
|
}
|
|
69
|
-
node = child
|
|
70
|
+
node = child
|
|
70
71
|
}
|
|
71
|
-
return node
|
|
72
|
+
return node
|
|
72
73
|
}
|
|
73
74
|
|
|
74
75
|
function isPromiseLike(value: unknown): value is PromiseLike<unknown> {
|
|
75
76
|
return (
|
|
76
|
-
(typeof value === 'object' || typeof value === 'function') &&
|
|
77
|
-
|
|
78
|
-
'then' in value
|
|
79
|
-
);
|
|
77
|
+
(typeof value === 'object' || typeof value === 'function') && value !== null && 'then' in value
|
|
78
|
+
)
|
|
80
79
|
}
|
package/src/api/client-cache.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export function cache<Args extends unknown[], Result>(
|
|
2
2
|
fn: (...args: Args) => Result,
|
|
3
3
|
): (...args: Args) => Result {
|
|
4
|
-
return (...args: Args) => fn(...args)
|
|
4
|
+
return (...args: Args) => fn(...args)
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
export function cacheSignal() {
|
|
8
|
-
return null
|
|
8
|
+
return null
|
|
9
9
|
}
|