@wular/pnext 0.0.3 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -11
- package/bin/pnext +1 -1
- package/config/lint/base.js +7 -7
- package/config/ts/base.json +2 -4
- package/config/ts/react.json +2 -6
- package/package.json +23 -2
- package/reference/compat.md +1 -1
- package/reference/config.md +2 -2
- package/reference/css.md +13 -9
- package/reference/dev.md +1 -1
- package/reference/metadata.md +7 -7
- package/reference/navigation.md +35 -28
- package/reference/performance.md +70 -70
- package/reference/rendering.md +17 -17
- package/reference/routing.md +17 -17
- package/reference/typegen.md +12 -8
- package/src/api/cache.ts +36 -37
- package/src/api/client-cache.ts +2 -2
- package/src/api/client-navigation.ts +113 -109
- package/src/api/dynamic.tsx +58 -55
- package/src/api/link.tsx +49 -52
- package/src/api/navigation.ts +59 -58
- package/src/api/server.ts +152 -144
- package/src/api/suspense.ts +4 -4
- package/src/cli/adapters/vercel-warm.ts +126 -121
- package/src/cli/adapters/vercel.ts +437 -443
- package/src/cli/analyze.ts +333 -144
- package/src/cli/{named-bin.ts → boot/named-bin.ts} +37 -37
- package/src/cli/{boot-trace.ts → boot/trace.ts} +10 -10
- package/src/cli/build.ts +976 -978
- package/src/cli/create.ts +71 -63
- package/src/cli/dev.ts +116 -116
- package/src/cli/index.ts +88 -85
- package/src/cli/migrate/package-json.ts +73 -71
- package/src/cli/migrate/report.ts +32 -33
- package/src/cli/migrate/{index.ts → run.ts} +48 -49
- package/src/cli/migrate/scan.ts +46 -46
- package/src/cli/migrate/spinner.ts +9 -9
- package/src/cli/migrate/tsconfig.ts +35 -35
- package/src/cli/{server-entry.ts → serve/entry.ts} +57 -57
- package/src/cli/{request-pipeline.ts → serve/pipeline.ts} +386 -394
- package/src/cli/{serve-ui.ts → serve/ui.ts} +47 -47
- package/src/cli/start.ts +65 -66
- package/src/{typegen.ts → cli/typegen.ts} +59 -59
- package/src/client/build.ts +794 -768
- package/src/client/chunk-fold.ts +245 -240
- package/src/client/{paths.ts → chunk-name.ts} +6 -6
- package/src/client/entry.ts +162 -147
- package/src/client/prebuilt.ts +231 -223
- package/src/client/profile.ts +29 -29
- package/src/client/react-compiler.ts +20 -15
- package/src/client/{compat-surface.ts → react-tier.ts} +64 -64
- package/src/client/reference-stub.ts +51 -51
- package/src/client/reference.ts +19 -19
- package/src/{api → client}/router/events.ts +17 -17
- package/src/{api → client}/router/history.ts +16 -16
- package/src/{api → client}/router/hub.ts +52 -53
- package/src/{api/router.ts → client/router/index.ts} +61 -60
- package/src/{api → client}/router/policies.ts +24 -24
- package/src/{api → client}/router/runtime.ts +1988 -1961
- package/src/{api → client}/router/types.ts +93 -98
- package/src/compat/actions/client-plugin.ts +42 -43
- package/src/compat/actions/client-stub.ts +14 -14
- package/src/compat/actions/{action-client.ts → client.ts} +194 -193
- package/src/compat/actions/config.ts +63 -64
- package/src/compat/actions/detect.ts +68 -68
- package/src/compat/actions/discovery.ts +105 -105
- package/src/compat/actions/{action-dispatch.ts → dispatch.ts} +277 -274
- package/src/compat/actions/early-submit.ts +1 -1
- package/src/compat/actions/endpoint.ts +198 -198
- package/src/compat/actions/extensions.ts +811 -0
- package/src/compat/actions/flight.ts +23 -23
- package/src/compat/actions/form-state.ts +34 -34
- package/src/compat/actions/hoist.ts +382 -236
- package/src/compat/actions/ids.ts +7 -12
- package/src/compat/actions/index.ts +8 -8
- package/src/compat/actions/instances.ts +46 -46
- package/src/compat/actions/origin.ts +47 -48
- package/src/compat/actions/protocol.ts +22 -22
- package/src/compat/actions/registry.ts +19 -19
- package/src/compat/{misc/action-return.ts → actions/return.ts} +60 -57
- package/src/compat/actions/rewrite.ts +125 -125
- package/src/compat/actions/{action-router.ts → router.ts} +10 -10
- package/src/compat/actions/serve.ts +132 -136
- package/src/compat/actions/server-tag.ts +4 -4
- package/src/compat/actions/{action-shared.ts → shared.ts} +34 -34
- package/src/compat/actions/unrecognized-error.ts +4 -4
- package/src/compat/{index.ts → aliases.ts} +112 -109
- package/src/compat/bundler/bun-externals.ts +18 -18
- package/src/compat/bundler/cjs-exports.ts +271 -223
- package/src/compat/bundler/config.ts +116 -111
- package/src/compat/bundler/externals.ts +12 -12
- package/src/compat/bundler/import-meta-url.ts +19 -19
- package/src/compat/bundler/modularize-imports.ts +36 -33
- package/src/compat/bundler/new-url-asset.ts +22 -24
- package/src/compat/bundler/optimize-package-imports.ts +111 -107
- package/src/compat/bundler/polyfill.ts +28 -28
- package/src/compat/bundler/react-compiler.ts +35 -29
- package/src/compat/bundler/react-profiler.tsx +11 -11
- package/src/compat/bundler/relay-transform.ts +48 -47
- package/src/compat/bundler/require-context.ts +119 -113
- package/src/compat/bundler/resolve-extensions.ts +19 -19
- package/src/compat/bundler/source-cache.ts +25 -25
- package/src/compat/bundler/static-imports.ts +7 -7
- package/src/compat/bundler/symlink-imports.ts +46 -46
- package/src/compat/bundler/tsconfig-paths.ts +13 -15
- package/src/compat/bundler/wasm.ts +58 -60
- package/src/compat/bundler/webpack-loaders.ts +254 -241
- package/src/compat/bundler/worker.ts +101 -104
- package/src/compat/cache/build-flags.ts +29 -29
- package/src/compat/cache/build-prerender-errors.ts +40 -44
- package/src/compat/cache/custom-handler.ts +60 -53
- package/src/compat/cache/fetch-patch.ts +240 -240
- package/src/compat/cache/handler.ts +27 -31
- package/src/compat/cache/modern-handler.ts +148 -126
- package/src/compat/cache/resume-data-cache.ts +47 -45
- package/src/compat/cache/revalidate.ts +233 -232
- package/src/compat/cache/runtime-error.ts +35 -35
- package/src/compat/cache/use-cache-transform.ts +442 -417
- package/src/compat/cache/use-cache.ts +650 -614
- package/src/compat/cache-control.ts +140 -142
- package/src/compat/client/base-path.ts +21 -20
- package/src/compat/client/css-order.ts +18 -18
- package/src/compat/client/errors/bare-boundary.ts +11 -11
- package/src/compat/client/errors/control-flow.ts +23 -23
- package/src/compat/client/errors/error-boundary.ts +61 -61
- package/src/compat/client/errors/global-error.ts +101 -91
- package/src/compat/client/errors/install.ts +71 -72
- package/src/compat/client/errors/lazy.ts +23 -23
- package/src/compat/client/errors/primitive-throw.ts +47 -45
- package/src/compat/client/errors/soft-refresh.ts +4 -4
- package/src/compat/client/link-status.ts +33 -33
- package/src/compat/client/{nav-compat-runtime.ts → nav-runtime.ts} +20 -20
- package/src/compat/client/{nav-compat.ts → nav.ts} +12 -13
- package/src/compat/client/navigation-scroll.ts +63 -63
- package/src/compat/client/optimistic-routing.ts +93 -88
- package/src/compat/client/prefetch-cache.ts +23 -24
- package/src/compat/client/route-announcer.ts +35 -35
- package/src/compat/client/segment-cache-policy.ts +20 -20
- package/src/compat/client/segment-cache.ts +309 -315
- package/src/compat/client/segment-prefetch.ts +127 -132
- package/src/compat/client/trailing-slash.ts +5 -4
- package/src/compat/css/chunking.ts +113 -116
- package/src/compat/css/inline-css.ts +21 -21
- package/src/compat/css/lightningcss.ts +37 -38
- package/src/compat/css/modules.ts +161 -175
- package/src/compat/css/nonce.ts +7 -7
- package/src/compat/css/sass-plugin.ts +18 -21
- package/src/compat/css/sass.ts +150 -152
- package/src/compat/css/styled-jsx-runtime.ts +27 -27
- package/src/compat/css/styled-jsx.ts +21 -21
- package/src/compat/edge-runtime.ts +27 -27
- package/src/compat/{adapter → export}/build-complete.ts +72 -75
- package/src/compat/export/client.ts +29 -31
- package/src/compat/export/{index.ts → emit.ts} +111 -110
- package/src/compat/export/standalone.ts +62 -54
- package/src/compat/image-optimizer/cache.ts +51 -49
- package/src/compat/image-optimizer/detect.ts +52 -52
- package/src/compat/image-optimizer/{index.ts → optimize.ts} +189 -194
- package/src/compat/image-optimizer/source.ts +77 -80
- package/src/compat/lifecycle/after-scope.ts +26 -26
- package/src/compat/lifecycle/after.ts +48 -45
- package/src/compat/lifecycle/error-funnel.ts +98 -102
- package/src/compat/lifecycle/error-serialize.ts +30 -26
- package/src/compat/lifecycle/error-ui.ts +67 -32
- package/src/compat/lifecycle/instrumentation-client.ts +36 -38
- package/src/compat/lifecycle/instrumentation.ts +85 -85
- package/src/compat/lifecycle/node-console.ts +11 -11
- package/src/compat/lifecycle/testmode.ts +160 -132
- package/src/compat/mdx/compile.ts +60 -57
- package/src/compat/mdx/plugin.ts +11 -11
- package/src/compat/mdx/{next-mdx-stub.ts → stub.ts} +5 -5
- package/src/compat/{metadata-route-artifacts.ts → metadata-artifacts.ts} +195 -191
- package/src/compat/metadata.ts +75 -81
- package/src/compat/next/cache.ts +68 -69
- package/src/compat/next/canonical-url.ts +9 -9
- package/src/compat/next/client-cache.ts +19 -19
- package/src/compat/next/client-navigation.ts +112 -116
- package/src/compat/next/client-only.ts +1 -1
- package/src/compat/next/client-script.tsx +99 -93
- package/src/compat/next/client-server.ts +10 -10
- package/src/compat/next/config-loader.ts +176 -173
- package/src/compat/next/config.ts +7 -7
- package/src/compat/next/constants.cjs +6 -6
- package/src/compat/next/constants.ts +6 -6
- package/src/compat/next/custom-server.ts +26 -24
- package/src/compat/next/dist/client/components/app-router-headers.ts +21 -21
- package/src/compat/next/dist/server/app-render/work-unit-async-storage.external.cjs +3 -4
- package/src/compat/next/dist/server/web/spec-extension/revalidate.ts +1 -1
- package/src/compat/next/dist/server/web/spec-extension/unstable-cache.ts +1 -1
- package/src/compat/next/dist/server/web/spec-extension/unstable-no-store.ts +1 -1
- package/src/compat/next/dynamic.tsx +21 -18
- package/src/compat/next/error.tsx +52 -52
- package/src/compat/next/font/cache.ts +74 -74
- package/src/compat/next/font/google.ts +2 -2
- package/src/compat/next/font/index.ts +1 -1
- package/src/compat/next/font/local.ts +3 -3
- package/src/compat/next/font/runtime-client.ts +17 -15
- package/src/compat/next/font/runtime.ts +443 -408
- package/src/compat/next/font/shared.ts +120 -108
- package/src/compat/next/form.tsx +63 -63
- package/src/compat/next/head.tsx +2 -2
- package/src/compat/next/headers.ts +103 -95
- package/src/compat/next/image/client.tsx +220 -0
- package/src/compat/next/image/config.ts +56 -58
- package/src/compat/next/image/optimizer.ts +40 -36
- package/src/compat/next/image/patterns.ts +37 -40
- package/src/compat/next/{image-props.ts → image/props.ts} +208 -202
- package/src/compat/next/image/shared.ts +65 -57
- package/src/compat/next/image/static-metadata.ts +98 -107
- package/src/compat/next/image/validate.ts +79 -88
- package/src/compat/next/image.tsx +19 -23
- package/src/compat/next/index.ts +1 -1
- package/src/compat/next/legacy-image.tsx +59 -60
- package/src/compat/next/{link-validation-transform.ts → link-transform.ts} +95 -96
- package/src/compat/next/link.tsx +158 -158
- package/src/compat/next/navigation.cjs +12 -3
- package/src/compat/next/navigation.ts +48 -50
- package/src/compat/next/offline.ts +27 -27
- package/src/compat/next/og.ts +121 -124
- package/src/compat/next/preferred-region.ts +13 -14
- package/src/compat/next/redirects.ts +58 -56
- package/src/compat/next/resource-hints.ts +73 -76
- package/src/compat/next/rewrites.ts +130 -133
- package/src/compat/next/root-params.ts +45 -45
- package/src/compat/next/{optimistic-route-state.ts → route-state.ts} +52 -52
- package/src/compat/next/router.cjs +4 -2
- package/src/compat/next/router.ts +58 -61
- package/src/compat/next/script.tsx +108 -108
- package/src/compat/next/server-only.ts +1 -1
- package/src/compat/next/server.ts +19 -19
- package/src/compat/next/svgr.ts +18 -17
- package/src/compat/next/telemetry.ts +24 -24
- package/src/compat/next/{image-usage.ts → usage.ts} +70 -39
- package/src/compat/next/user-agent.ts +53 -49
- package/src/compat/next/web-vitals.ts +22 -24
- package/src/compat/otel/api.ts +41 -41
- package/src/compat/otel/client-trace-metadata.ts +25 -27
- package/src/compat/otel/fetch-span.ts +29 -29
- package/src/compat/otel/tracer.ts +331 -331
- package/src/compat/pages/api.ts +456 -0
- package/src/compat/pages/client-plugin.ts +36 -36
- package/src/compat/pages/router-state.ts +34 -34
- package/src/compat/pages/{index.ts → router.ts} +130 -135
- package/src/compat/ppr/io.ts +12 -12
- package/src/compat/ppr/missing-root-params.ts +34 -38
- package/src/compat/ppr/root-params-scan.ts +66 -66
- package/src/compat/ppr/root-params-transform.ts +24 -26
- package/src/compat/ppr/root-params.ts +30 -30
- package/src/compat/ppr/segment-config-incompat.ts +6 -7
- package/src/compat/protocol.ts +71 -70
- package/src/compat/react/action-state.ts +47 -48
- package/src/compat/react/client-lite.ts +15 -15
- package/src/compat/react/client.ts +4 -4
- package/src/compat/react/compiler-runtime.ts +11 -11
- package/src/compat/react/dom-client.ts +44 -44
- package/src/compat/react/dom-react-server.ts +10 -16
- package/src/compat/react/dom-server.ts +10 -10
- package/src/compat/react/dom.ts +52 -52
- package/src/compat/react/hooks-extra.ts +34 -35
- package/src/compat/react/parity.ts +64 -61
- package/src/compat/react/preact.ts +81 -82
- package/src/compat/react/react-server.ts +28 -28
- package/src/compat/react/router-shim.ts +1 -1
- package/src/compat/react/server-component-use.ts +8 -8
- package/src/compat/react/server-inserted-html.ts +30 -31
- package/src/compat/react/server.ts +53 -55
- package/src/compat/react/use.ts +32 -32
- package/src/compat/react/view-transition.ts +20 -20
- package/src/compat/register/actions.ts +35 -824
- package/src/compat/register/boot.ts +41 -41
- package/src/compat/register/build-tier.ts +5 -5
- package/src/compat/register/build.ts +74 -70
- package/src/compat/register/bundler.ts +161 -156
- package/src/compat/register/cache.ts +20 -20
- package/src/compat/register/client-errors.ts +3 -3
- package/src/compat/register/config.ts +6 -6
- package/src/compat/register/css-extras.ts +30 -34
- package/src/compat/register/edge-runtime.ts +3 -3
- package/src/compat/register/errors.ts +10 -12
- package/src/compat/register/export.ts +16 -16
- package/src/compat/register/font.ts +11 -11
- package/src/compat/register/hooks.ts +2 -2
- package/src/compat/register/image.ts +40 -40
- package/src/compat/register/index.ts +59 -62
- package/src/compat/register/instrumentation-client.ts +10 -10
- package/src/compat/register/lifecycle.ts +25 -28
- package/src/compat/register/mdx.ts +10 -10
- package/src/compat/register/middleware.ts +226 -16
- package/src/compat/register/otel.ts +80 -88
- package/src/compat/register/pages-api.ts +10 -463
- package/src/compat/register/ppr.ts +16 -16
- package/src/compat/register/protocol.ts +17 -18
- package/src/compat/register/proxy.ts +49 -51
- package/src/compat/register/render.ts +79 -76
- package/src/compat/register/routing.ts +162 -159
- package/src/compat/register/segment.ts +24 -1887
- package/src/compat/register/static-image.ts +3 -3
- package/src/compat/register/{misc.ts → taint.ts} +9 -9
- package/src/compat/register/typed-routes.ts +14 -14
- package/src/compat/register/{usecache.ts → use-cache.ts} +39 -39
- package/src/compat/register/validation.ts +18 -18
- package/src/compat/segment/loading-boundary.ts +43 -45
- package/src/compat/segment/page-slot.ts +69 -69
- package/src/compat/segment/serve.ts +1884 -0
- package/src/compat/segment/tree.ts +113 -112
- package/src/compat/segment/vary-key.ts +38 -38
- package/src/compat/segment/vary-params.ts +138 -142
- package/src/compat/static-params.ts +14 -12
- package/src/compat/tsconfig-defaults.ts +87 -91
- package/src/compat/typecheck/{index.ts → check.ts} +234 -212
- package/src/compat/typecheck/worker.ts +15 -12
- package/src/compat/typed-routes/{index.ts → generate.ts} +36 -36
- package/src/compat/typed-routes/manifest.ts +174 -170
- package/src/compat/typed-routes/typegen.ts +127 -110
- package/src/compat/validation/errors.ts +16 -19
- package/src/compat/validation/prerender-diagnostics.ts +521 -504
- package/src/compat/validation/{index.ts → validate.ts} +647 -648
- package/src/compat-bootstrap.ts +16 -16
- package/src/config.ts +69 -69
- package/src/css/build.ts +230 -227
- package/src/css/postcss.ts +79 -80
- package/src/css/worker.ts +14 -15
- package/src/dev/client-actions.ts +10 -10
- package/src/dev/client-chunk-store.ts +27 -27
- package/src/dev/{client-key-cache.ts → restart/client-key.ts} +76 -76
- package/src/dev/{restart-cache.ts → restart/enabled.ts} +1 -1
- package/src/dev/{global-css-cache.ts → restart/global-css.ts} +91 -83
- package/src/dev/{node-module-bundle-cache.ts → restart/node-modules.ts} +24 -24
- package/src/dev/{route-bundle-key-cache.ts → restart/route-bundle-key.ts} +53 -53
- package/src/dev/{route-facts-cache.ts → restart/route-facts.ts} +82 -82
- package/src/dev/server.ts +804 -820
- package/src/env.ts +46 -43
- package/src/extensions.ts +491 -478
- package/src/index.ts +8 -8
- package/src/internal.ts +20 -23
- package/src/{islands → render}/boundary-error.ts +3 -3
- package/src/render/hooks.ts +71 -71
- package/src/render/island-context.ts +14 -14
- package/src/render/metadata.ts +310 -310
- package/src/{ppr-postpone.ts → render/postpone.ts} +5 -5
- package/src/{ppr.ts → render/ppr.ts} +244 -245
- package/src/render/renderer.ts +2076 -2082
- package/src/render/resource-hints.ts +16 -17
- package/src/render/slots.tsx +224 -235
- package/src/{islands → render}/static-children.ts +9 -12
- package/src/{islands → render}/static-slots.ts +37 -37
- package/src/{cache/context.ts → request/cache.ts} +20 -20
- package/src/request/context.ts +107 -107
- package/src/{dynamic/source.ts → resolve/dynamic.ts} +152 -143
- package/src/resolve/engine.ts +90 -77
- package/src/resolve/imports.ts +475 -463
- package/src/resolve/scan-facts.ts +442 -186
- package/src/resolve/source-text.ts +37 -37
- package/src/{dynamic → resolve}/tree-shake.ts +132 -128
- package/src/routing/forwarded.ts +19 -19
- package/src/routing/handler.ts +84 -91
- package/src/routing/href.ts +69 -70
- package/src/routing/{metadata.ts → metadata-files.ts} +403 -401
- package/src/{proxy.ts → routing/proxy.ts} +306 -312
- package/src/routing/{request-runtime.ts → request-environment.ts} +10 -10
- package/src/routing/routes.ts +833 -848
- package/src/routing/slots.ts +164 -160
- package/src/runtime/loader.ts +952 -0
- package/src/{dev → runtime}/module-cache.ts +309 -287
- package/src/{dev → runtime}/module-generations.ts +9 -9
- package/src/{dev → runtime}/module-transform.ts +81 -72
- package/src/{dev/imports.ts → runtime/modules.ts} +934 -847
- package/src/runtime/{server.ts → vendor-build.ts} +848 -1696
- package/src/runtime/vendor.ts +425 -404
- package/src/styles.d.ts +9 -0
- package/src/types.ts +320 -335
- package/src/utils/ansi.ts +5 -5
- package/src/utils/{source.ts → code.ts} +15 -12
- package/src/utils/content-type.ts +3 -3
- package/src/utils/decode.ts +2 -2
- package/src/utils/dev-profile.ts +13 -13
- package/src/utils/error-log.ts +6 -6
- package/src/utils/esbuild.ts +18 -18
- package/src/utils/fs-cache.ts +13 -13
- package/src/utils/fs.ts +57 -49
- package/src/utils/html.ts +20 -24
- package/src/utils/native-require.ts +8 -8
- package/src/utils/serialize.ts +139 -146
- package/src/utils/verbose.ts +18 -18
- package/src/cli/analyze-print.ts +0 -181
- package/src/compat/middleware/manifest.ts +0 -210
- package/src/compat/next/image-client.tsx +0 -215
- package/src/compat/next/link-usage.ts +0 -29
- package/src/css/index.ts +0 -2
- package/src/render/index.ts +0 -1
- package/src/style-modules.d.ts +0 -9
|
@@ -13,35 +13,35 @@
|
|
|
13
13
|
// Worker graphs get their own static-asset handling, reusing the compat staticAssetModule extension for
|
|
14
14
|
// images and a generic `{ src }` module for other assets.
|
|
15
15
|
|
|
16
|
-
import { createHash } from 'node:crypto'
|
|
17
|
-
import { existsSync, statSync } from 'node:fs'
|
|
18
|
-
import { copyFile, mkdir, readFile, writeFile } from 'node:fs/promises'
|
|
19
|
-
import path from 'node:path'
|
|
20
|
-
import type { Plugin } from 'esbuild'
|
|
21
|
-
import { build } from '../../utils/esbuild'
|
|
22
|
-
import { publicEnvDefines, type ResolvedConfig } from '../../config'
|
|
23
|
-
import { getAssetExtensions } from '../../extensions'
|
|
16
|
+
import { createHash } from 'node:crypto'
|
|
17
|
+
import { existsSync, statSync } from 'node:fs'
|
|
18
|
+
import { copyFile, mkdir, readFile, writeFile } from 'node:fs/promises'
|
|
19
|
+
import path from 'node:path'
|
|
20
|
+
import type { Plugin } from 'esbuild'
|
|
21
|
+
import { build } from '../../utils/esbuild'
|
|
22
|
+
import { publicEnvDefines, type ResolvedConfig } from '../../config'
|
|
23
|
+
import { getAssetExtensions } from '../../extensions'
|
|
24
24
|
|
|
25
25
|
// `new Worker(new URL('<spec>', import.meta.url)` / SharedWorker — the URL
|
|
26
26
|
// argument must be a string literal and the base exactly `import.meta.url`.
|
|
27
27
|
const workerPattern = () =>
|
|
28
|
-
/\bnew\s+(Worker|SharedWorker)\(\s*new\s+URL\(\s*(['"])([^'"]+)\2\s*,\s*import\.meta\.url\s*\)/g
|
|
28
|
+
/\bnew\s+(Worker|SharedWorker)\(\s*new\s+URL\(\s*(['"])([^'"]+)\2\s*,\s*import\.meta\.url\s*\)/g
|
|
29
29
|
|
|
30
30
|
/** Cheap gate: does this source construct a Worker from a `new URL(...)`? */
|
|
31
31
|
export function sourceHasWorkerNewUrl(source: string): boolean {
|
|
32
32
|
return (
|
|
33
33
|
(source.includes('new Worker(') || source.includes('new SharedWorker(')) &&
|
|
34
34
|
workerPattern().test(source)
|
|
35
|
-
)
|
|
35
|
+
)
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
const workerSpecifierExtensions = ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.mts']
|
|
38
|
+
const workerSpecifierExtensions = ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.mts']
|
|
39
39
|
|
|
40
40
|
function isFile(file: string): boolean {
|
|
41
41
|
try {
|
|
42
|
-
return statSync(file).isFile()
|
|
42
|
+
return statSync(file).isFile()
|
|
43
43
|
} catch {
|
|
44
|
-
return false
|
|
44
|
+
return false
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
|
|
@@ -50,89 +50,89 @@ function resolveWorkerEntry(
|
|
|
50
50
|
specifier: string,
|
|
51
51
|
configuredExtensions: readonly string[] | undefined,
|
|
52
52
|
): string | undefined {
|
|
53
|
-
if (!specifier.startsWith('.')) return undefined
|
|
54
|
-
const base = path.resolve(importerDir, specifier)
|
|
55
|
-
if (path.extname(base) && isFile(base)) return base
|
|
53
|
+
if (!specifier.startsWith('.')) return undefined
|
|
54
|
+
const base = path.resolve(importerDir, specifier)
|
|
55
|
+
if (path.extname(base) && isFile(base)) return base
|
|
56
56
|
for (const extension of configuredExtensions ?? workerSpecifierExtensions) {
|
|
57
57
|
if (extension === '') {
|
|
58
|
-
if (isFile(base)) return base
|
|
59
|
-
continue
|
|
58
|
+
if (isFile(base)) return base
|
|
59
|
+
continue
|
|
60
60
|
}
|
|
61
|
-
const candidate = `${base}${extension}
|
|
62
|
-
if (isFile(candidate)) return candidate
|
|
61
|
+
const candidate = `${base}${extension}`
|
|
62
|
+
if (isFile(candidate)) return candidate
|
|
63
63
|
}
|
|
64
64
|
// A configured extension list that misses the worker's real extension must
|
|
65
65
|
// not break the build — fall back to the built-in source order.
|
|
66
66
|
if (configuredExtensions) {
|
|
67
67
|
for (const extension of workerSpecifierExtensions) {
|
|
68
|
-
const candidate = `${base}${extension}
|
|
69
|
-
if (isFile(candidate)) return candidate
|
|
68
|
+
const candidate = `${base}${extension}`
|
|
69
|
+
if (isFile(candidate)) return candidate
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
|
-
return isFile(base) ? base : undefined
|
|
72
|
+
return isFile(base) ? base : undefined
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
// Any importable asset a worker may reference: static images (compat descriptor
|
|
76
76
|
// module) plus generic binary assets (.wasm) exposed as `{ src }`.
|
|
77
|
-
const workerAssetFilter = /\.(?:png|jpe?g|gif|webp|avif|svg|ico|bmp|wasm)(?:$|[?#])
|
|
77
|
+
const workerAssetFilter = /\.(?:png|jpe?g|gif|webp|avif|svg|ico|bmp|wasm)(?:$|[?#])/
|
|
78
78
|
|
|
79
79
|
// Workers fetch `.wasm` via `new URL('./x.wasm', import.meta.url)`; rewrite it
|
|
80
80
|
// (and image URLs) onto the asset import pipeline exactly like the main-graph
|
|
81
81
|
// new-url-asset transform, but with `.wasm` included.
|
|
82
82
|
const workerNewUrlAssetPattern = () =>
|
|
83
|
-
/new\s+URL\(\s*(['"])([^'"]+?\.(?:png|jpe?g|gif|webp|avif|svg|ico|bmp|wasm)(?:[?#][^'"]*)?)\1\s*,\s*import\.meta\.url\s*\)/g
|
|
83
|
+
/new\s+URL\(\s*(['"])([^'"]+?\.(?:png|jpe?g|gif|webp|avif|svg|ico|bmp|wasm)(?:[?#][^'"]*)?)\1\s*,\s*import\.meta\.url\s*\)/g
|
|
84
84
|
|
|
85
85
|
function rewriteWorkerNewUrlAssets(source: string): string {
|
|
86
|
-
if (!source.includes('import.meta.url')) return source
|
|
87
|
-
const bindings = new Map<string, string>()
|
|
86
|
+
if (!source.includes('import.meta.url')) return source
|
|
87
|
+
const bindings = new Map<string, string>()
|
|
88
88
|
const replaced = source.replace(workerNewUrlAssetPattern(), (_match, _quote, spec: string) => {
|
|
89
|
-
let binding = bindings.get(spec)
|
|
89
|
+
let binding = bindings.get(spec)
|
|
90
90
|
if (!binding) {
|
|
91
|
-
binding = `__pnext_worker_url_${bindings.size}
|
|
92
|
-
bindings.set(spec, binding)
|
|
91
|
+
binding = `__pnext_worker_url_${bindings.size}`
|
|
92
|
+
bindings.set(spec, binding)
|
|
93
93
|
}
|
|
94
|
-
return `(${binding}.src)
|
|
95
|
-
})
|
|
96
|
-
if (bindings.size === 0) return source
|
|
94
|
+
return `(${binding}.src)`
|
|
95
|
+
})
|
|
96
|
+
if (bindings.size === 0) return source
|
|
97
97
|
const imports = [...bindings]
|
|
98
98
|
.map(([spec, binding]) => `import ${binding} from ${JSON.stringify(spec)};`)
|
|
99
|
-
.join('\n')
|
|
100
|
-
return `${imports}\n${replaced}
|
|
99
|
+
.join('\n')
|
|
100
|
+
return `${imports}\n${replaced}`
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
function splitAssetHash(specifier: string) {
|
|
104
|
-
const index = specifier.search(/[?#]/)
|
|
104
|
+
const index = specifier.search(/[?#]/)
|
|
105
105
|
return index === -1
|
|
106
106
|
? { sourcePath: specifier, hash: '' }
|
|
107
|
-
: { sourcePath: specifier.slice(0, index), hash: specifier.slice(index) }
|
|
107
|
+
: { sourcePath: specifier.slice(0, index), hash: specifier.slice(index) }
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
async function workerAssetModuleSource(config: ResolvedConfig, file: string): Promise<string> {
|
|
111
|
-
const { sourcePath } = splitAssetHash(file)
|
|
112
|
-
const bytes = new Uint8Array(await readFile(sourcePath))
|
|
113
|
-
const emitted: string[] = []
|
|
111
|
+
const { sourcePath } = splitAssetHash(file)
|
|
112
|
+
const bytes = new Uint8Array(await readFile(sourcePath))
|
|
113
|
+
const emitted: string[] = []
|
|
114
114
|
const emit = (relative: string) => {
|
|
115
|
-
emitted.push(relative)
|
|
116
|
-
return `/${relative}
|
|
117
|
-
}
|
|
118
|
-
let source = await getAssetExtensions().staticAssetModule({ sourcePath, bytes, emit })
|
|
115
|
+
emitted.push(relative)
|
|
116
|
+
return `/${relative}`
|
|
117
|
+
}
|
|
118
|
+
let source = await getAssetExtensions().staticAssetModule({ sourcePath, bytes, emit })
|
|
119
119
|
if (!source) {
|
|
120
|
-
const ext = path.extname(sourcePath).toLowerCase() || '.bin'
|
|
121
|
-
const hash = createHash('sha256').update(bytes).digest('hex').slice(0, 8)
|
|
120
|
+
const ext = path.extname(sourcePath).toLowerCase() || '.bin'
|
|
121
|
+
const hash = createHash('sha256').update(bytes).digest('hex').slice(0, 8)
|
|
122
122
|
const base = path
|
|
123
123
|
.basename(sourcePath, path.extname(sourcePath))
|
|
124
|
-
.replace(/[^A-Za-z0-9_-]+/g, '-')
|
|
125
|
-
const relative = getAssetExtensions().staticAssetRelativePath({ sourcePath, base, hash, ext })
|
|
126
|
-
const src = emit(relative)
|
|
124
|
+
.replace(/[^A-Za-z0-9_-]+/g, '-')
|
|
125
|
+
const relative = getAssetExtensions().staticAssetRelativePath({ sourcePath, base, hash, ext })
|
|
126
|
+
const src = emit(relative)
|
|
127
127
|
// `.src` (worker new-URL rewrite) and default-as-string both observable.
|
|
128
|
-
source = `const src = ${JSON.stringify(src)};\nexport default { src };\nexport { src };\n
|
|
128
|
+
source = `const src = ${JSON.stringify(src)};\nexport default { src };\nexport { src };\n`
|
|
129
129
|
}
|
|
130
130
|
for (const relative of emitted) {
|
|
131
|
-
const target = path.join(config.outPath, 'public', ...relative.split('/'))
|
|
132
|
-
await mkdir(path.dirname(target), { recursive: true })
|
|
133
|
-
if (!existsSync(target)) await copyFile(sourcePath, target)
|
|
131
|
+
const target = path.join(config.outPath, 'public', ...relative.split('/'))
|
|
132
|
+
await mkdir(path.dirname(target), { recursive: true })
|
|
133
|
+
if (!existsSync(target)) await copyFile(sourcePath, target)
|
|
134
134
|
}
|
|
135
|
-
return source
|
|
135
|
+
return source
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
function workerAssetPlugin(config: ResolvedConfig): Plugin {
|
|
@@ -143,44 +143,44 @@ function workerAssetPlugin(config: ResolvedConfig): Plugin {
|
|
|
143
143
|
// (esbuild would otherwise mangle `import.meta.url` in the iife output) are
|
|
144
144
|
// rewritten onto the asset import pipeline below.
|
|
145
145
|
build.onLoad({ filter: /\.(?:js|mjs|jsx|ts|tsx|mts)$/, namespace: 'file' }, async args => {
|
|
146
|
-
const source = await readFile(args.path, 'utf8')
|
|
147
|
-
if (!workerNewUrlAssetPattern().test(source)) return undefined
|
|
146
|
+
const source = await readFile(args.path, 'utf8')
|
|
147
|
+
if (!workerNewUrlAssetPattern().test(source)) return undefined
|
|
148
148
|
const loader = args.path.endsWith('.ts')
|
|
149
149
|
? ('ts' as const)
|
|
150
150
|
: args.path.endsWith('.mts')
|
|
151
151
|
? ('ts' as const)
|
|
152
152
|
: args.path.endsWith('.tsx')
|
|
153
153
|
? ('tsx' as const)
|
|
154
|
-
: ('jsx' as const)
|
|
155
|
-
return { contents: rewriteWorkerNewUrlAssets(source), loader }
|
|
156
|
-
})
|
|
154
|
+
: ('jsx' as const)
|
|
155
|
+
return { contents: rewriteWorkerNewUrlAssets(source), loader }
|
|
156
|
+
})
|
|
157
157
|
build.onResolve({ filter: workerAssetFilter }, args => {
|
|
158
|
-
const { sourcePath, hash } = splitAssetHash(args.path)
|
|
158
|
+
const { sourcePath, hash } = splitAssetHash(args.path)
|
|
159
159
|
const resolved = path.isAbsolute(sourcePath)
|
|
160
160
|
? sourcePath
|
|
161
|
-
: path.resolve(args.resolveDir, sourcePath)
|
|
162
|
-
return { path: `${resolved}${hash}`, namespace: 'pnext-worker-asset' }
|
|
163
|
-
})
|
|
161
|
+
: path.resolve(args.resolveDir, sourcePath)
|
|
162
|
+
return { path: `${resolved}${hash}`, namespace: 'pnext-worker-asset' }
|
|
163
|
+
})
|
|
164
164
|
build.onLoad({ filter: /.*/, namespace: 'pnext-worker-asset' }, async args => ({
|
|
165
165
|
contents: await workerAssetModuleSource(config, args.path),
|
|
166
166
|
loader: 'js',
|
|
167
|
-
}))
|
|
167
|
+
}))
|
|
168
168
|
},
|
|
169
|
-
}
|
|
169
|
+
}
|
|
170
170
|
}
|
|
171
171
|
|
|
172
172
|
function workerDefines(): Record<string, string> {
|
|
173
173
|
const defines: Record<string, string> = {
|
|
174
174
|
...publicEnvDefines(),
|
|
175
175
|
'process.browser': 'true',
|
|
176
|
-
}
|
|
176
|
+
}
|
|
177
177
|
// Next inlines the deployment id into every graph, workers included.
|
|
178
178
|
// eslint-disable-next-line turbo/no-undeclared-env-vars
|
|
179
|
-
const deploymentId = process.env.NEXT_DEPLOYMENT_ID
|
|
179
|
+
const deploymentId = process.env.NEXT_DEPLOYMENT_ID
|
|
180
180
|
if (deploymentId !== undefined) {
|
|
181
|
-
defines['process.env.NEXT_DEPLOYMENT_ID'] = JSON.stringify(deploymentId)
|
|
181
|
+
defines['process.env.NEXT_DEPLOYMENT_ID'] = JSON.stringify(deploymentId)
|
|
182
182
|
}
|
|
183
|
-
return defines
|
|
183
|
+
return defines
|
|
184
184
|
}
|
|
185
185
|
|
|
186
186
|
/**
|
|
@@ -202,16 +202,16 @@ async function bundleWorkerEntry(config: ResolvedConfig, entry: string): Promise
|
|
|
202
202
|
define: workerDefines(),
|
|
203
203
|
plugins: [workerAssetPlugin(config)],
|
|
204
204
|
logLevel: 'silent',
|
|
205
|
-
})
|
|
206
|
-
const output = result.outputFiles[0]
|
|
207
|
-
if (!output) throw new Error(`pnext: worker bundle produced no output for ${entry}`)
|
|
208
|
-
const hash = createHash('sha256').update(output.contents).digest('hex').slice(0, 8)
|
|
209
|
-
const base = path.basename(entry, path.extname(entry)).replace(/[^A-Za-z0-9_-]+/g, '-')
|
|
210
|
-
const relative = path.posix.join('assets', 'workers', `${base}.${hash}.js`)
|
|
211
|
-
const target = path.join(config.outPath, 'public', ...relative.split('/'))
|
|
212
|
-
await mkdir(path.dirname(target), { recursive: true })
|
|
213
|
-
await writeFile(target, output.contents)
|
|
214
|
-
return `/${relative}
|
|
205
|
+
})
|
|
206
|
+
const output = result.outputFiles[0]
|
|
207
|
+
if (!output) throw new Error(`pnext: worker bundle produced no output for ${entry}`)
|
|
208
|
+
const hash = createHash('sha256').update(output.contents).digest('hex').slice(0, 8)
|
|
209
|
+
const base = path.basename(entry, path.extname(entry)).replace(/[^A-Za-z0-9_-]+/g, '-')
|
|
210
|
+
const relative = path.posix.join('assets', 'workers', `${base}.${hash}.js`)
|
|
211
|
+
const target = path.join(config.outPath, 'public', ...relative.split('/'))
|
|
212
|
+
await mkdir(path.dirname(target), { recursive: true })
|
|
213
|
+
await writeFile(target, output.contents)
|
|
214
|
+
return `/${relative}`
|
|
215
215
|
}
|
|
216
216
|
|
|
217
217
|
/**
|
|
@@ -224,18 +224,18 @@ export function createClientWorkerTransform(
|
|
|
224
224
|
config: ResolvedConfig,
|
|
225
225
|
configuredExtensions: readonly string[] | undefined,
|
|
226
226
|
): (source: string, file: string) => Promise<string> {
|
|
227
|
-
const bundleCache = new Map<string, Promise<string>>()
|
|
227
|
+
const bundleCache = new Map<string, Promise<string>>()
|
|
228
228
|
return async (source, file) => {
|
|
229
|
-
if (!sourceHasWorkerNewUrl(source)) return source
|
|
229
|
+
if (!sourceHasWorkerNewUrl(source)) return source
|
|
230
230
|
const rewritten = await rewriteWorkerSource(
|
|
231
231
|
config,
|
|
232
232
|
source,
|
|
233
233
|
file,
|
|
234
234
|
bundleCache,
|
|
235
235
|
configuredExtensions,
|
|
236
|
-
)
|
|
237
|
-
return rewritten ?? source
|
|
238
|
-
}
|
|
236
|
+
)
|
|
237
|
+
return rewritten ?? source
|
|
238
|
+
}
|
|
239
239
|
}
|
|
240
240
|
|
|
241
241
|
/**
|
|
@@ -250,30 +250,27 @@ export async function rewriteWorkerSource(
|
|
|
250
250
|
bundleCache: Map<string, Promise<string>>,
|
|
251
251
|
configuredExtensions: readonly string[] | undefined,
|
|
252
252
|
): Promise<string | undefined> {
|
|
253
|
-
const importerDir = path.dirname(file)
|
|
254
|
-
const matches = [...source.matchAll(workerPattern())]
|
|
255
|
-
if (matches.length === 0) return undefined
|
|
253
|
+
const importerDir = path.dirname(file)
|
|
254
|
+
const matches = [...source.matchAll(workerPattern())]
|
|
255
|
+
if (matches.length === 0) return undefined
|
|
256
256
|
|
|
257
|
-
const urls = new Map<string, string>()
|
|
257
|
+
const urls = new Map<string, string>()
|
|
258
258
|
for (const match of matches) {
|
|
259
|
-
const spec = match[3]
|
|
260
|
-
if (urls.has(spec)) continue
|
|
261
|
-
const entry = resolveWorkerEntry(importerDir, spec, configuredExtensions)
|
|
262
|
-
if (!entry) continue
|
|
263
|
-
let pending = bundleCache.get(entry)
|
|
259
|
+
const spec = match[3]!
|
|
260
|
+
if (urls.has(spec)) continue
|
|
261
|
+
const entry = resolveWorkerEntry(importerDir, spec, configuredExtensions)
|
|
262
|
+
if (!entry) continue // unresolvable: leave the construction untouched
|
|
263
|
+
let pending = bundleCache.get(entry)
|
|
264
264
|
if (!pending) {
|
|
265
|
-
pending = bundleWorkerEntry(config, entry)
|
|
266
|
-
bundleCache.set(entry, pending)
|
|
265
|
+
pending = bundleWorkerEntry(config, entry)
|
|
266
|
+
bundleCache.set(entry, pending)
|
|
267
267
|
}
|
|
268
|
-
urls.set(spec, await pending)
|
|
268
|
+
urls.set(spec, await pending)
|
|
269
269
|
}
|
|
270
|
-
if (urls.size === 0) return undefined
|
|
270
|
+
if (urls.size === 0) return undefined
|
|
271
271
|
|
|
272
|
-
return source.replace(
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
return url ? `new ${ctor}(${JSON.stringify(url)}` : match;
|
|
277
|
-
},
|
|
278
|
-
);
|
|
272
|
+
return source.replace(workerPattern(), (match, ctor: string, _quote: string, spec: string) => {
|
|
273
|
+
const url = urls.get(spec)
|
|
274
|
+
return url ? `new ${ctor}(${JSON.stringify(url)}` : match
|
|
275
|
+
})
|
|
279
276
|
}
|
|
@@ -8,52 +8,52 @@
|
|
|
8
8
|
// State is anchored on globalThis: the built compat-server bundle and the original module can both be
|
|
9
9
|
// loaded in one process, and a module-local cache would then be filled in one copy and empty in the other.
|
|
10
10
|
|
|
11
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'
|
|
12
|
-
import path from 'node:path'
|
|
11
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'
|
|
12
|
+
import path from 'node:path'
|
|
13
13
|
|
|
14
|
-
const BUILD_FLAG_GLOBALS = Symbol.for('pnext.compat.buildFlags')
|
|
14
|
+
const BUILD_FLAG_GLOBALS = Symbol.for('pnext.compat.buildFlags')
|
|
15
15
|
|
|
16
16
|
export interface BuildFlags {
|
|
17
|
-
debugPrerender: boolean
|
|
17
|
+
debugPrerender: boolean
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
interface BuildFlagState {
|
|
21
21
|
/** The serving root's output dir, recorded by the init hook. */
|
|
22
|
-
outPath?: string
|
|
22
|
+
outPath?: string
|
|
23
23
|
/** Lazily read flags: `null` once a read found no build to serve. */
|
|
24
|
-
flags?: BuildFlags | null
|
|
24
|
+
flags?: BuildFlags | null
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
function state(): BuildFlagState {
|
|
28
|
-
const root = globalThis as unknown as Record<PropertyKey, BuildFlagState | undefined
|
|
29
|
-
return (root[BUILD_FLAG_GLOBALS] ??= {})
|
|
28
|
+
const root = globalThis as unknown as Record<PropertyKey, BuildFlagState | undefined>
|
|
29
|
+
return (root[BUILD_FLAG_GLOBALS] ??= {})
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
function flagsFile(outPath: string): string {
|
|
33
|
-
return path.join(outPath, 'server', 'pnext-build-flags.json')
|
|
33
|
+
return path.join(outPath, 'server', 'pnext-build-flags.json')
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
/** Record the output dir at build/start init so the runtime can find the file. */
|
|
37
37
|
export function setBuildFlagsOutPath(outPath: string): void {
|
|
38
|
-
const current = state()
|
|
38
|
+
const current = state()
|
|
39
39
|
if (current.outPath !== outPath) {
|
|
40
|
-
current.outPath = outPath
|
|
41
|
-
current.flags = undefined
|
|
40
|
+
current.outPath = outPath
|
|
41
|
+
current.flags = undefined
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
/** Persist the build's `--debug-prerender` flag for the serving runtime. */
|
|
46
46
|
export function writeBuildFlags(outPath: string, debugPrerender: boolean): void {
|
|
47
|
-
const file = flagsFile(outPath)
|
|
47
|
+
const file = flagsFile(outPath)
|
|
48
48
|
try {
|
|
49
|
-
mkdirSync(path.dirname(file), { recursive: true })
|
|
50
|
-
writeFileSync(file, `${JSON.stringify({ debugPrerender })}\n`)
|
|
49
|
+
mkdirSync(path.dirname(file), { recursive: true })
|
|
50
|
+
writeFileSync(file, `${JSON.stringify({ debugPrerender })}\n`)
|
|
51
51
|
} catch {
|
|
52
52
|
// A read-only/absent output dir only costs the runtime this hint.
|
|
53
53
|
}
|
|
54
|
-
const current = state()
|
|
55
|
-
current.outPath = outPath
|
|
56
|
-
current.flags = { debugPrerender }
|
|
54
|
+
const current = state()
|
|
55
|
+
current.outPath = outPath
|
|
56
|
+
current.flags = { debugPrerender }
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
/**
|
|
@@ -62,20 +62,20 @@ export function writeBuildFlags(outPath: string, debugPrerender: boolean): void
|
|
|
62
62
|
* Callers use the absence to stay out of production-only behavior.
|
|
63
63
|
*/
|
|
64
64
|
export function servedBuildFlags(): BuildFlags | undefined {
|
|
65
|
-
const current = state()
|
|
66
|
-
if (current.flags !== undefined) return current.flags ?? undefined
|
|
67
|
-
const outPath = current.outPath
|
|
68
|
-
if (outPath === undefined) return undefined
|
|
69
|
-
let flags: BuildFlags | null = null
|
|
65
|
+
const current = state()
|
|
66
|
+
if (current.flags !== undefined) return current.flags ?? undefined
|
|
67
|
+
const outPath = current.outPath
|
|
68
|
+
if (outPath === undefined) return undefined
|
|
69
|
+
let flags: BuildFlags | null = null
|
|
70
70
|
try {
|
|
71
|
-
const file = flagsFile(outPath)
|
|
71
|
+
const file = flagsFile(outPath)
|
|
72
72
|
if (existsSync(file)) {
|
|
73
|
-
const parsed = JSON.parse(readFileSync(file, 'utf8')) as { debugPrerender?: unknown }
|
|
74
|
-
flags = { debugPrerender: parsed.debugPrerender === true }
|
|
73
|
+
const parsed = JSON.parse(readFileSync(file, 'utf8')) as { debugPrerender?: unknown }
|
|
74
|
+
flags = { debugPrerender: parsed.debugPrerender === true }
|
|
75
75
|
}
|
|
76
76
|
} catch {
|
|
77
|
-
flags = null
|
|
77
|
+
flags = null
|
|
78
78
|
}
|
|
79
|
-
current.flags = flags
|
|
80
|
-
return flags ?? undefined
|
|
79
|
+
current.flags = flags
|
|
80
|
+
return flags ?? undefined
|
|
81
81
|
}
|
|
@@ -13,49 +13,45 @@
|
|
|
13
13
|
// the serving runtime and pure-core builds are unaffected.
|
|
14
14
|
|
|
15
15
|
export type PrerenderErrorKind =
|
|
16
|
-
| '
|
|
17
|
-
| 'close-over'
|
|
18
|
-
| 'search-params'
|
|
19
|
-
| 'use-cache-dynamic'
|
|
20
|
-
| 'unstable-cache-dynamic';
|
|
16
|
+
'hanging' | 'close-over' | 'search-params' | 'use-cache-dynamic' | 'unstable-cache-dynamic'
|
|
21
17
|
|
|
22
18
|
export interface PrerenderError {
|
|
23
|
-
kind: PrerenderErrorKind
|
|
24
|
-
route: string
|
|
19
|
+
kind: PrerenderErrorKind
|
|
20
|
+
route: string
|
|
25
21
|
/** The error detail printed to stderr (Next's `Error: …` block). */
|
|
26
|
-
consoleBlock: string
|
|
22
|
+
consoleBlock: string
|
|
27
23
|
}
|
|
28
24
|
|
|
29
25
|
// The build process (which calls begin/end) and the built compat-server bundle (which runs the
|
|
30
26
|
// prerender and records violations) each load their OWN copy of this module, so a module-local
|
|
31
27
|
// armed/collected set by one copy is invisible to the other and detection would silently never fire.
|
|
32
28
|
// Anchor the state on globalThis so every copy shares one collection window.
|
|
33
|
-
const PRERENDER_ERROR_GLOBALS = Symbol.for('pnext.compat.prerenderErrorGlobals')
|
|
29
|
+
const PRERENDER_ERROR_GLOBALS = Symbol.for('pnext.compat.prerenderErrorGlobals')
|
|
34
30
|
|
|
35
31
|
interface PrerenderErrorState {
|
|
36
|
-
collected: PrerenderError[]
|
|
37
|
-
armed: boolean
|
|
32
|
+
collected: PrerenderError[]
|
|
33
|
+
armed: boolean
|
|
38
34
|
}
|
|
39
35
|
|
|
40
36
|
function state(): PrerenderErrorState {
|
|
41
|
-
const root = globalThis as Record<PropertyKey, unknown
|
|
42
|
-
return (root[PRERENDER_ERROR_GLOBALS] ??= { collected: [], armed: false }) as PrerenderErrorState
|
|
37
|
+
const root = globalThis as Record<PropertyKey, unknown>
|
|
38
|
+
return (root[PRERENDER_ERROR_GLOBALS] ??= { collected: [], armed: false }) as PrerenderErrorState
|
|
43
39
|
}
|
|
44
40
|
|
|
45
41
|
/** Arm collection at the start of a compat build's prerender pass. */
|
|
46
42
|
export function beginPrerenderErrorCollection(): void {
|
|
47
|
-
const s = state()
|
|
48
|
-
s.collected.length = 0
|
|
49
|
-
s.armed = true
|
|
43
|
+
const s = state()
|
|
44
|
+
s.collected.length = 0
|
|
45
|
+
s.armed = true
|
|
50
46
|
}
|
|
51
47
|
|
|
52
48
|
/** Disarm collection and drain the recorded violations (build-complete hook). */
|
|
53
49
|
export function endPrerenderErrorCollection(): PrerenderError[] {
|
|
54
|
-
const s = state()
|
|
55
|
-
s.armed = false
|
|
56
|
-
const out = s.collected.slice()
|
|
57
|
-
s.collected.length = 0
|
|
58
|
-
return out
|
|
50
|
+
const s = state()
|
|
51
|
+
s.armed = false
|
|
52
|
+
const out = s.collected.slice()
|
|
53
|
+
s.collected.length = 0
|
|
54
|
+
return out
|
|
59
55
|
}
|
|
60
56
|
|
|
61
57
|
/**
|
|
@@ -64,24 +60,24 @@ export function endPrerenderErrorCollection(): PrerenderError[] {
|
|
|
64
60
|
* `pnext build` and never affects `pnext start`/dev or pure-core builds.
|
|
65
61
|
*/
|
|
66
62
|
export function prerenderErrorCollectionActive(): boolean {
|
|
67
|
-
return state().armed
|
|
63
|
+
return state().armed
|
|
68
64
|
}
|
|
69
65
|
|
|
70
66
|
export function recordPrerenderError(error: PrerenderError): void {
|
|
71
|
-
const s = state()
|
|
72
|
-
if (!s.armed) return
|
|
73
|
-
const collected = s.collected
|
|
74
|
-
if (collected.some(e => e.kind === error.kind && e.route === error.route)) return
|
|
75
|
-
collected.push(error)
|
|
67
|
+
const s = state()
|
|
68
|
+
if (!s.armed) return
|
|
69
|
+
const collected = s.collected
|
|
70
|
+
if (collected.some(e => e.kind === error.kind && e.route === error.route)) return
|
|
71
|
+
collected.push(error)
|
|
76
72
|
// Print at detection time (not only from the build-complete hook): a
|
|
77
73
|
// close-over violation rethrows out of the cache-components shell render and
|
|
78
74
|
// aborts the build BEFORE the complete hook runs, so the hook would never get
|
|
79
75
|
// to print it. Printing here guarantees the message reaches the build output
|
|
80
76
|
// (stderr) in every abort path; the hook only needs to force the non-zero
|
|
81
77
|
// exit for the swallowed cases (hanging / caught search-params).
|
|
82
|
-
console.error(error.consoleBlock)
|
|
78
|
+
console.error(error.consoleBlock)
|
|
83
79
|
if (error.route) {
|
|
84
|
-
console.error(`Error occurred prerendering page "${error.route}".`)
|
|
80
|
+
console.error(`Error occurred prerendering page "${error.route}".`)
|
|
85
81
|
}
|
|
86
82
|
}
|
|
87
83
|
|
|
@@ -91,15 +87,15 @@ export function recordPrerenderError(error: PrerenderError): void {
|
|
|
91
87
|
* recognizable app-router file.
|
|
92
88
|
*/
|
|
93
89
|
export function routeFromCacheId(id: string): string {
|
|
94
|
-
const file = id.split('#', 1)[0] ?? ''
|
|
95
|
-
const withoutExt = file.replace(/\.[jt]sx?$/, '')
|
|
96
|
-
const segments = withoutExt.split('/')
|
|
97
|
-
if (segments[0] === 'app' || segments[0] === 'src') segments.shift()
|
|
98
|
-
if (segments[0] === 'app') segments.shift()
|
|
99
|
-
const last = segments[segments.length - 1]
|
|
100
|
-
if (last === 'page' || last === 'route' || last === 'default') segments.pop()
|
|
101
|
-
const routeSegments = segments.filter(seg => !/^\(.*\)$/.test(seg))
|
|
102
|
-
return `/${routeSegments.join('/')}`.replace(/\/+$/, '') || '/'
|
|
90
|
+
const file = id.split('#', 1)[0] ?? ''
|
|
91
|
+
const withoutExt = file.replace(/\.[jt]sx?$/, '')
|
|
92
|
+
const segments = withoutExt.split('/')
|
|
93
|
+
if (segments[0] === 'app' || segments[0] === 'src') segments.shift()
|
|
94
|
+
if (segments[0] === 'app') segments.shift()
|
|
95
|
+
const last = segments[segments.length - 1]
|
|
96
|
+
if (last === 'page' || last === 'route' || last === 'default') segments.pop()
|
|
97
|
+
const routeSegments = segments.filter(seg => !/^\(.*\)$/.test(seg))
|
|
98
|
+
return `/${routeSegments.join('/')}`.replace(/\/+$/, '') || '/'
|
|
103
99
|
}
|
|
104
100
|
|
|
105
101
|
// --- Next's exact error strings -------------------------------------------
|
|
@@ -107,16 +103,16 @@ export function routeFromCacheId(id: string): string {
|
|
|
107
103
|
export const USE_CACHE_HANGING_MESSAGE =
|
|
108
104
|
'Filling a cache during prerender timed out, likely because request-specific ' +
|
|
109
105
|
'arguments such as params, searchParams, cookies() or dynamic data were used ' +
|
|
110
|
-
'inside "use cache".'
|
|
106
|
+
'inside "use cache".'
|
|
111
107
|
|
|
112
108
|
export const USE_CACHE_CLOSE_OVER_FUNCTION_MESSAGE =
|
|
113
109
|
'Functions cannot be passed directly to Client Components unless you ' +
|
|
114
110
|
'explicitly expose it by marking it with "use server". Or maybe you meant to ' +
|
|
115
|
-
'call this function rather than return it.'
|
|
111
|
+
'call this function rather than return it.'
|
|
116
112
|
|
|
117
113
|
/** The `[function]` / caret block Next prints under the close-over error. */
|
|
118
114
|
export const USE_CACHE_CLOSE_OVER_FUNCTION_BLOCK =
|
|
119
|
-
`\nError: ${USE_CACHE_CLOSE_OVER_FUNCTION_MESSAGE}` + '\n [function]' + '\n ^^^^^^^^'
|
|
115
|
+
`\nError: ${USE_CACHE_CLOSE_OVER_FUNCTION_MESSAGE}` + '\n [function]' + '\n ^^^^^^^^'
|
|
120
116
|
|
|
121
117
|
/**
|
|
122
118
|
* Next's E838 message: a dynamic request API (`cookies()`/`headers()`/
|
|
@@ -136,7 +132,7 @@ export function unstableCacheDynamicApiMessage(
|
|
|
136
132
|
'outside of the cached function and pass the required dynamic data in as an ' +
|
|
137
133
|
'argument. See more info here: ' +
|
|
138
134
|
'https://nextjs.org/docs/app/api-reference/functions/unstable_cache'
|
|
139
|
-
)
|
|
135
|
+
)
|
|
140
136
|
}
|
|
141
137
|
|
|
142
138
|
export function useCacheDynamicApiMessage(
|
|
@@ -149,7 +145,7 @@ export function useCacheDynamicApiMessage(
|
|
|
149
145
|
`a cached function use \`${api}\` outside of the cached function and pass the ` +
|
|
150
146
|
'required dynamic data in as an argument. See more info here: ' +
|
|
151
147
|
'https://nextjs.org/docs/messages/next-request-in-use-cache'
|
|
152
|
-
)
|
|
148
|
+
)
|
|
153
149
|
}
|
|
154
150
|
|
|
155
151
|
export function useCacheSearchParamsMessage(route: string): string {
|
|
@@ -159,5 +155,5 @@ export function useCacheSearchParamsMessage(route: string): string {
|
|
|
159
155
|
'params inside a cached function await `searchParams` outside of the cached ' +
|
|
160
156
|
'function and pass only the required search params as arguments to the cached ' +
|
|
161
157
|
'function. See more info here: https://nextjs.org/docs/messages/next-request-in-use-cache'
|
|
162
|
-
)
|
|
158
|
+
)
|
|
163
159
|
}
|