@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
|
@@ -1,55 +1,55 @@
|
|
|
1
|
-
// Persisted route-bundle names - the restart half of
|
|
1
|
+
// Persisted route-bundle names - the restart half of runtime/modules.ts' devRouteBundlePath. A route's
|
|
2
2
|
// bundle already lives at a content-addressed path, so a restart never has to rebuild it; deriving
|
|
3
3
|
// that path did, by walking the whole source graph of the route and its layouts breadth-first, with
|
|
4
4
|
// a stat round trip per level, on the first page of every restart. The sources cannot have moved
|
|
5
5
|
// while nothing was watching them *unless* the file did, so this persists the walk's answer and
|
|
6
6
|
// re-validates it with one flat stat per source.
|
|
7
7
|
//
|
|
8
|
-
// The same three-step ladder dev/client-key
|
|
8
|
+
// The same three-step ladder dev/restart/client-key.ts and dev/restart/route-facts.ts use:
|
|
9
9
|
// stat matches -> reuse (the common case, and the only O(1) one)
|
|
10
10
|
// stat moved -> read + hash; equal content still reuses the path
|
|
11
11
|
// content differs -> discard, walk again, record the new answer
|
|
12
12
|
// A missing source is a miss too, which is what keeps a deleted file from naming an artifact whose
|
|
13
13
|
// edges are gone.
|
|
14
14
|
//
|
|
15
|
-
// One file PER ROUTE, not one index, for the reason route-facts
|
|
15
|
+
// One file PER ROUTE, not one index, for the reason restart/route-facts.ts records: the source lists are
|
|
16
16
|
// large across the whole table and the first page only ever asks about the route it is serving.
|
|
17
|
-
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs'
|
|
18
|
-
import { readFile, stat } from 'node:fs/promises'
|
|
19
|
-
import path from 'node:path'
|
|
20
|
-
import type { ResolvedConfig } from '
|
|
17
|
+
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs'
|
|
18
|
+
import { readFile, stat } from 'node:fs/promises'
|
|
19
|
+
import path from 'node:path'
|
|
20
|
+
import type { ResolvedConfig } from '../../config'
|
|
21
21
|
import {
|
|
22
22
|
DEV_SOURCE_MISSING,
|
|
23
23
|
devTextSourceHash,
|
|
24
24
|
isBinaryDevSource,
|
|
25
25
|
type DevGraphSource,
|
|
26
|
-
} from '
|
|
27
|
-
import { restartCacheEnabled } from './
|
|
26
|
+
} from '../../runtime/module-cache'
|
|
27
|
+
import { restartCacheEnabled } from './enabled'
|
|
28
28
|
|
|
29
29
|
interface RecordFile {
|
|
30
|
-
version: number
|
|
30
|
+
version: number
|
|
31
31
|
/** Hash of everything in the name that is not a walked source (see recordKey). */
|
|
32
|
-
key: string
|
|
32
|
+
key: string
|
|
33
33
|
/** The named bundle path itself — the whole point of the record. */
|
|
34
|
-
bundle: string
|
|
35
|
-
files: DevGraphSource[]
|
|
34
|
+
bundle: string
|
|
35
|
+
files: DevGraphSource[]
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
/** Bumped whenever a record's shape changes; an older record is simply ignored. */
|
|
39
|
-
const RECORD_VERSION = 1
|
|
39
|
+
const RECORD_VERSION = 1
|
|
40
40
|
|
|
41
|
-
const hash = (value: string) => Bun.hash(value).toString(36)
|
|
41
|
+
const hash = (value: string) => Bun.hash(value).toString(36)
|
|
42
42
|
|
|
43
43
|
/** Records written this process (by record file), so a repeat naming does not re-serialize. */
|
|
44
|
-
const written = new Map<string, string>()
|
|
44
|
+
const written = new Map<string, string>()
|
|
45
45
|
|
|
46
46
|
function enabled() {
|
|
47
47
|
// eslint-disable-next-line turbo/no-undeclared-env-vars
|
|
48
|
-
return restartCacheEnabled() && process.env.PNEXT_DEV_BUNDLE_KEY_CACHE !== '0'
|
|
48
|
+
return restartCacheEnabled() && process.env.PNEXT_DEV_BUNDLE_KEY_CACHE !== '0'
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
function recordFile(config: ResolvedConfig, routeId: string) {
|
|
52
|
-
return path.join(config.outPath, 'cache', 'route-bundles', `${hash(routeId)}.json`)
|
|
52
|
+
return path.join(config.outPath, 'cache', 'route-bundles', `${hash(routeId)}.json`)
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
/**
|
|
@@ -58,7 +58,7 @@ function recordFile(config: ResolvedConfig, routeId: string) {
|
|
|
58
58
|
* the record read as a miss instead of half-validating it.
|
|
59
59
|
*/
|
|
60
60
|
function recordKey(graphKey: string, files: string[]) {
|
|
61
|
-
return hash(`${RECORD_VERSION}\n${graphKey}\n${files.join('\0')}`)
|
|
61
|
+
return hash(`${RECORD_VERSION}\n${graphKey}\n${files.join('\0')}`)
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
/** The persisted bundle path when every source it was named for is unchanged. */
|
|
@@ -68,25 +68,25 @@ export async function cachedRouteBundlePath(
|
|
|
68
68
|
graphKey: string,
|
|
69
69
|
files: string[],
|
|
70
70
|
): Promise<string | undefined> {
|
|
71
|
-
if (!enabled()) return undefined
|
|
72
|
-
const key = recordKey(graphKey, files)
|
|
73
|
-
let record: RecordFile | undefined
|
|
71
|
+
if (!enabled()) return undefined
|
|
72
|
+
const key = recordKey(graphKey, files)
|
|
73
|
+
let record: RecordFile | undefined
|
|
74
74
|
try {
|
|
75
|
-
record = JSON.parse(readFileSync(recordFile(config, routeId), 'utf8')) as RecordFile
|
|
75
|
+
record = JSON.parse(readFileSync(recordFile(config, routeId), 'utf8')) as RecordFile
|
|
76
76
|
} catch {
|
|
77
|
-
return undefined
|
|
77
|
+
return undefined
|
|
78
78
|
}
|
|
79
|
-
if (record?.version !== RECORD_VERSION || record.key !== key) return undefined
|
|
80
|
-
if (typeof record.bundle !== 'string' || !Array.isArray(record.files)) return undefined
|
|
81
|
-
const revalidated = await revalidate(record.files)
|
|
82
|
-
if (!revalidated) return undefined
|
|
79
|
+
if (record?.version !== RECORD_VERSION || record.key !== key) return undefined
|
|
80
|
+
if (typeof record.bundle !== 'string' || !Array.isArray(record.files)) return undefined
|
|
81
|
+
const revalidated = await revalidate(record.files)
|
|
82
|
+
if (!revalidated) return undefined
|
|
83
83
|
// Only the stats moved (a touch, a checkout): keep the name, record the new
|
|
84
84
|
// stats so the next boot takes the O(1) path again.
|
|
85
85
|
if (revalidated !== record.files) {
|
|
86
|
-
written.delete(recordFile(config, routeId))
|
|
87
|
-
write(config, routeId, key, record.bundle, revalidated)
|
|
86
|
+
written.delete(recordFile(config, routeId))
|
|
87
|
+
write(config, routeId, key, record.bundle, revalidated)
|
|
88
88
|
}
|
|
89
|
-
return record.bundle
|
|
89
|
+
return record.bundle
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
export function saveRouteBundlePath(
|
|
@@ -97,11 +97,11 @@ export function saveRouteBundlePath(
|
|
|
97
97
|
bundle: string,
|
|
98
98
|
sources: DevGraphSource[],
|
|
99
99
|
): void {
|
|
100
|
-
if (!enabled()) return
|
|
100
|
+
if (!enabled()) return
|
|
101
101
|
// A source the walk could not read describes a tree that no longer exists;
|
|
102
102
|
// the next boot walking again is the safe answer.
|
|
103
|
-
if (sources.some(([, , , srcHash]) => srcHash === DEV_SOURCE_MISSING)) return
|
|
104
|
-
write(config, routeId, recordKey(graphKey, files), bundle, sources)
|
|
103
|
+
if (sources.some(([, , , srcHash]) => srcHash === DEV_SOURCE_MISSING)) return
|
|
104
|
+
write(config, routeId, recordKey(graphKey, files), bundle, sources)
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
function write(
|
|
@@ -111,18 +111,18 @@ function write(
|
|
|
111
111
|
bundle: string,
|
|
112
112
|
files: DevGraphSource[],
|
|
113
113
|
) {
|
|
114
|
-
const file = recordFile(config, routeId)
|
|
115
|
-
if (written.get(file) === bundle) return
|
|
116
|
-
written.set(file, bundle)
|
|
114
|
+
const file = recordFile(config, routeId)
|
|
115
|
+
if (written.get(file) === bundle) return
|
|
116
|
+
written.set(file, bundle)
|
|
117
117
|
const contents = JSON.stringify({
|
|
118
118
|
version: RECORD_VERSION,
|
|
119
119
|
key,
|
|
120
120
|
bundle,
|
|
121
121
|
files,
|
|
122
|
-
} satisfies RecordFile)
|
|
122
|
+
} satisfies RecordFile)
|
|
123
123
|
try {
|
|
124
|
-
mkdirSync(path.dirname(file), { recursive: true })
|
|
125
|
-
writeFileSync(file, contents)
|
|
124
|
+
mkdirSync(path.dirname(file), { recursive: true })
|
|
125
|
+
writeFileSync(file, contents)
|
|
126
126
|
} catch {
|
|
127
127
|
// Best effort: a missing record only costs the next boot a walk.
|
|
128
128
|
}
|
|
@@ -134,21 +134,21 @@ function write(
|
|
|
134
134
|
* walk has to run again.
|
|
135
135
|
*/
|
|
136
136
|
async function revalidate(files: DevGraphSource[]): Promise<DevGraphSource[] | undefined> {
|
|
137
|
-
let moved = false
|
|
137
|
+
let moved = false
|
|
138
138
|
const checked = await Promise.all(
|
|
139
139
|
files.map(async (entry): Promise<DevGraphSource | undefined> => {
|
|
140
|
-
const [file, mtimeMs, size, srcHash] = entry
|
|
141
|
-
const stats = await stat(file).catch(() => undefined)
|
|
142
|
-
if (!stats) return undefined
|
|
143
|
-
if (stats.mtimeMs === mtimeMs && stats.size === size) return entry
|
|
140
|
+
const [file, mtimeMs, size, srcHash] = entry
|
|
141
|
+
const stats = await stat(file).catch(() => undefined)
|
|
142
|
+
if (!stats) return undefined
|
|
143
|
+
if (stats.mtimeMs === mtimeMs && stats.size === size) return entry
|
|
144
144
|
// A binary source is hashed from its stat, so a moved stat IS a new hash.
|
|
145
|
-
if (isBinaryDevSource(file)) return undefined
|
|
146
|
-
const source = await readFile(file, 'utf8').catch(() => undefined)
|
|
147
|
-
if (source === undefined || devTextSourceHash(source) !== srcHash) return undefined
|
|
148
|
-
moved = true
|
|
149
|
-
return [file, stats.mtimeMs, stats.size, srcHash]
|
|
145
|
+
if (isBinaryDevSource(file)) return undefined
|
|
146
|
+
const source = await readFile(file, 'utf8').catch(() => undefined)
|
|
147
|
+
if (source === undefined || devTextSourceHash(source) !== srcHash) return undefined
|
|
148
|
+
moved = true
|
|
149
|
+
return [file, stats.mtimeMs, stats.size, srcHash]
|
|
150
150
|
}),
|
|
151
|
-
)
|
|
152
|
-
if (checked.some(entry => entry === undefined)) return undefined
|
|
153
|
-
return moved ? (checked as DevGraphSource[]) : files
|
|
151
|
+
)
|
|
152
|
+
if (checked.some(entry => entry === undefined)) return undefined
|
|
153
|
+
return moved ? (checked as DevGraphSource[]) : files
|
|
154
154
|
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// cannot have moved while nothing was watching them *unless* the file did, so this persists the
|
|
6
6
|
// walk's result next to the compiled cache and re-validates it with one stat per source.
|
|
7
7
|
//
|
|
8
|
-
// The same three-step ladder dev/client-key
|
|
8
|
+
// The same three-step ladder dev/restart/client-key.ts uses:
|
|
9
9
|
// stat matches -> reuse (the common case, and the only O(1) one)
|
|
10
10
|
// stat moved -> read + hash; equal content still reuses the facts
|
|
11
11
|
// content differs -> discard, walk again, record the new facts
|
|
@@ -13,27 +13,27 @@
|
|
|
13
13
|
// One file PER ROUTE, not one index: the whole table is large and the first page only ever asks
|
|
14
14
|
// about the route it is serving, so as a single index its JSON.parse landed, in full, on that
|
|
15
15
|
// request and gave most of the walk back.
|
|
16
|
-
import { mkdirSync, readFileSync, statSync, writeFileSync } from 'node:fs'
|
|
17
|
-
import path from 'node:path'
|
|
18
|
-
import type { ResolvedConfig } from '
|
|
19
|
-
import { setRouteFactsStore, type RouteFacts, type RouteFactsStore } from '
|
|
20
|
-
import { restartCacheEnabled } from './
|
|
16
|
+
import { mkdirSync, readFileSync, statSync, writeFileSync } from 'node:fs'
|
|
17
|
+
import path from 'node:path'
|
|
18
|
+
import type { ResolvedConfig } from '../../config'
|
|
19
|
+
import { setRouteFactsStore, type RouteFacts, type RouteFactsStore } from '../../routing/routes'
|
|
20
|
+
import { restartCacheEnabled } from './enabled'
|
|
21
21
|
|
|
22
22
|
/** `[file, mtimeMs, size, contentHash]` — the same record shape the key cache uses. */
|
|
23
|
-
type SourceEntry = [string, number, number, string]
|
|
23
|
+
type SourceEntry = [string, number, number, string]
|
|
24
24
|
|
|
25
25
|
interface RecordFile {
|
|
26
|
-
version: number
|
|
26
|
+
version: number
|
|
27
27
|
/** Everything the facts depend on that is not a walked source (see cacheKey). */
|
|
28
|
-
key: string
|
|
29
|
-
files: SourceEntry[]
|
|
30
|
-
facts: RouteFacts
|
|
28
|
+
key: string
|
|
29
|
+
files: SourceEntry[]
|
|
30
|
+
facts: RouteFacts
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
/** Bumped whenever a record's shape changes; an older record is simply ignored. */
|
|
34
|
-
const RECORD_VERSION = 1
|
|
34
|
+
const RECORD_VERSION = 1
|
|
35
35
|
|
|
36
|
-
const hash = (value: string) => Bun.hash(value).toString(36)
|
|
36
|
+
const hash = (value: string) => Bun.hash(value).toString(36)
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
39
|
* The facts of a route whose own sources did not move can still change when the
|
|
@@ -45,11 +45,11 @@ function cacheKey(config: ResolvedConfig): string | undefined {
|
|
|
45
45
|
try {
|
|
46
46
|
const shape = JSON.stringify(config, (_key, value: unknown) =>
|
|
47
47
|
typeof value === 'function' ? '[fn]' : value,
|
|
48
|
-
)
|
|
49
|
-
return hash(`${RECORD_VERSION}\n${pnextBuildStamp()}\n${shape}`)
|
|
48
|
+
)
|
|
49
|
+
return hash(`${RECORD_VERSION}\n${pnextBuildStamp()}\n${shape}`)
|
|
50
50
|
} catch {
|
|
51
51
|
// A config that will not serialize (cycles, exotic values) simply opts out.
|
|
52
|
-
return undefined
|
|
52
|
+
return undefined
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
|
|
@@ -60,80 +60,80 @@ function cacheKey(config: ResolvedConfig): string | undefined {
|
|
|
60
60
|
*/
|
|
61
61
|
function pnextBuildStamp() {
|
|
62
62
|
try {
|
|
63
|
-
const self = Bun.fileURLToPath(import.meta.url)
|
|
64
|
-
const scanner = path.join(path.dirname(path.dirname(self)), 'routing', 'routes.ts')
|
|
65
|
-
const info = statSync(scanner, { throwIfNoEntry: false })
|
|
66
|
-
return info ? `${info.mtimeMs}:${info.size}` : self
|
|
63
|
+
const self = Bun.fileURLToPath(import.meta.url)
|
|
64
|
+
const scanner = path.join(path.dirname(path.dirname(self)), 'routing', 'routes.ts')
|
|
65
|
+
const info = statSync(scanner, { throwIfNoEntry: false })
|
|
66
|
+
return info ? `${info.mtimeMs}:${info.size}` : self
|
|
67
67
|
} catch {
|
|
68
|
-
return 'unknown'
|
|
68
|
+
return 'unknown'
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
interface FactsCache {
|
|
73
|
-
dir: string
|
|
74
|
-
key: string
|
|
73
|
+
dir: string
|
|
74
|
+
key: string
|
|
75
75
|
/** Records written this process, so a repeat save does not re-serialize. */
|
|
76
|
-
written: Set<string
|
|
76
|
+
written: Set<string>
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
export function installRouteFactsCache(config: ResolvedConfig) {
|
|
80
|
-
if (!restartCacheEnabled()) return
|
|
80
|
+
if (!restartCacheEnabled()) return
|
|
81
81
|
// eslint-disable-next-line turbo/no-undeclared-env-vars
|
|
82
|
-
if (process.env.PNEXT_DEV_FACTS_CACHE === '0') return
|
|
83
|
-
const key = cacheKey(config)
|
|
84
|
-
if (!key) return
|
|
82
|
+
if (process.env.PNEXT_DEV_FACTS_CACHE === '0') return
|
|
83
|
+
const key = cacheKey(config)
|
|
84
|
+
if (!key) return
|
|
85
85
|
const cache: FactsCache = {
|
|
86
86
|
dir: path.join(config.outPath, 'cache', 'route-facts'),
|
|
87
87
|
key,
|
|
88
88
|
written: new Set(),
|
|
89
|
-
}
|
|
90
|
-
setRouteFactsStore(createStore(cache))
|
|
89
|
+
}
|
|
90
|
+
setRouteFactsStore(createStore(cache))
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
function recordFile(cache: FactsCache, routeId: string) {
|
|
94
|
-
return path.join(cache.dir, `${hash(routeId)}.json`)
|
|
94
|
+
return path.join(cache.dir, `${hash(routeId)}.json`)
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
function createStore(cache: FactsCache): RouteFactsStore {
|
|
98
98
|
return {
|
|
99
99
|
load(routeId) {
|
|
100
|
-
const record = readRecord(cache, routeId)
|
|
100
|
+
const record = readRecord(cache, routeId)
|
|
101
101
|
if (!record) {
|
|
102
|
-
stats.misses += 1
|
|
103
|
-
return undefined
|
|
102
|
+
stats.misses += 1
|
|
103
|
+
return undefined
|
|
104
104
|
}
|
|
105
|
-
const revalidated = revalidate(record.files)
|
|
105
|
+
const revalidated = revalidate(record.files)
|
|
106
106
|
if (!revalidated) {
|
|
107
|
-
stats.misses += 1
|
|
108
|
-
return undefined
|
|
107
|
+
stats.misses += 1
|
|
108
|
+
return undefined
|
|
109
109
|
}
|
|
110
|
-
stats.hits += 1
|
|
110
|
+
stats.hits += 1
|
|
111
111
|
// Only the stats moved (a touch, a checkout): keep the facts, record the
|
|
112
112
|
// new stats so the next boot takes the O(1) path again.
|
|
113
113
|
if (revalidated !== record.files) {
|
|
114
|
-
cache.written.delete(routeId)
|
|
115
|
-
write(cache, routeId, revalidated, record.facts)
|
|
114
|
+
cache.written.delete(routeId)
|
|
115
|
+
write(cache, routeId, revalidated, record.facts)
|
|
116
116
|
}
|
|
117
|
-
return record.facts
|
|
117
|
+
return record.facts
|
|
118
118
|
},
|
|
119
119
|
save(routeId, facts) {
|
|
120
|
-
const files = factsSources(facts)
|
|
121
|
-
if (!files) return
|
|
122
|
-
write(cache, routeId, files, facts)
|
|
120
|
+
const files = factsSources(facts)
|
|
121
|
+
if (!files) return
|
|
122
|
+
write(cache, routeId, files, facts)
|
|
123
123
|
},
|
|
124
|
-
}
|
|
124
|
+
}
|
|
125
125
|
}
|
|
126
126
|
|
|
127
127
|
function readRecord(cache: FactsCache, routeId: string): RecordFile | undefined {
|
|
128
|
-
let parsed: RecordFile | undefined
|
|
128
|
+
let parsed: RecordFile | undefined
|
|
129
129
|
try {
|
|
130
|
-
parsed = JSON.parse(readFileSync(recordFile(cache, routeId), 'utf8')) as RecordFile
|
|
130
|
+
parsed = JSON.parse(readFileSync(recordFile(cache, routeId), 'utf8')) as RecordFile
|
|
131
131
|
} catch {
|
|
132
|
-
return undefined
|
|
132
|
+
return undefined
|
|
133
133
|
}
|
|
134
|
-
if (parsed?.version !== RECORD_VERSION || parsed.key !== cache.key) return undefined
|
|
135
|
-
if (!parsed.facts || !Array.isArray(parsed.files)) return undefined
|
|
136
|
-
return parsed
|
|
134
|
+
if (parsed?.version !== RECORD_VERSION || parsed.key !== cache.key) return undefined
|
|
135
|
+
if (!parsed.facts || !Array.isArray(parsed.files)) return undefined
|
|
136
|
+
return parsed
|
|
137
137
|
}
|
|
138
138
|
|
|
139
139
|
/**
|
|
@@ -142,17 +142,17 @@ function readRecord(cache: FactsCache, routeId: string): RecordFile | undefined
|
|
|
142
142
|
* once per process per route.
|
|
143
143
|
*/
|
|
144
144
|
function write(cache: FactsCache, routeId: string, files: SourceEntry[], facts: RouteFacts) {
|
|
145
|
-
if (cache.written.has(routeId)) return
|
|
146
|
-
cache.written.add(routeId)
|
|
145
|
+
if (cache.written.has(routeId)) return
|
|
146
|
+
cache.written.add(routeId)
|
|
147
147
|
const contents = JSON.stringify({
|
|
148
148
|
version: RECORD_VERSION,
|
|
149
149
|
key: cache.key,
|
|
150
150
|
files,
|
|
151
151
|
facts,
|
|
152
|
-
} satisfies RecordFile)
|
|
152
|
+
} satisfies RecordFile)
|
|
153
153
|
try {
|
|
154
|
-
mkdirSync(cache.dir, { recursive: true })
|
|
155
|
-
writeFileSync(recordFile(cache, routeId), contents)
|
|
154
|
+
mkdirSync(cache.dir, { recursive: true })
|
|
155
|
+
writeFileSync(recordFile(cache, routeId), contents)
|
|
156
156
|
} catch {
|
|
157
157
|
// Best effort: a missing record only costs the next boot a walk.
|
|
158
158
|
}
|
|
@@ -164,25 +164,25 @@ function write(cache: FactsCache, routeId: string, files: SourceEntry[], facts:
|
|
|
164
164
|
* answer.
|
|
165
165
|
*/
|
|
166
166
|
function factsSources(facts: RouteFacts): SourceEntry[] | undefined {
|
|
167
|
-
const entries: SourceEntry[] = []
|
|
167
|
+
const entries: SourceEntry[] = []
|
|
168
168
|
for (const file of facts.sourceFiles) {
|
|
169
|
-
const entry = sourceEntry(file)
|
|
170
|
-
if (!entry) return undefined
|
|
171
|
-
entries.push(entry)
|
|
169
|
+
const entry = sourceEntry(file)
|
|
170
|
+
if (!entry) return undefined
|
|
171
|
+
entries.push(entry)
|
|
172
172
|
}
|
|
173
|
-
return entries
|
|
173
|
+
return entries
|
|
174
174
|
}
|
|
175
175
|
|
|
176
176
|
function sourceEntry(file: string): SourceEntry | undefined {
|
|
177
177
|
try {
|
|
178
|
-
const source = readFileSync(file, 'utf8')
|
|
178
|
+
const source = readFileSync(file, 'utf8')
|
|
179
179
|
// Stat AFTER the read: a file that changes between the two records the
|
|
180
180
|
// older stat, so the next boot re-hashes rather than trusting a stale one.
|
|
181
|
-
const info = statSync(file, { throwIfNoEntry: false })
|
|
182
|
-
if (!info) return undefined
|
|
183
|
-
return [file, info.mtimeMs, info.size, hash(source)]
|
|
181
|
+
const info = statSync(file, { throwIfNoEntry: false })
|
|
182
|
+
if (!info) return undefined
|
|
183
|
+
return [file, info.mtimeMs, info.size, hash(source)]
|
|
184
184
|
} catch {
|
|
185
|
-
return undefined
|
|
185
|
+
return undefined
|
|
186
186
|
}
|
|
187
187
|
}
|
|
188
188
|
|
|
@@ -192,32 +192,32 @@ function sourceEntry(file: string): SourceEntry | undefined {
|
|
|
192
192
|
* walk has to run again.
|
|
193
193
|
*/
|
|
194
194
|
function revalidate(files: SourceEntry[]): SourceEntry[] | undefined {
|
|
195
|
-
let moved = false
|
|
196
|
-
const checked: SourceEntry[] = []
|
|
195
|
+
let moved = false
|
|
196
|
+
const checked: SourceEntry[] = []
|
|
197
197
|
for (const entry of files) {
|
|
198
|
-
const [file, mtimeMs, size, contentHash] = entry
|
|
199
|
-
const info = statSync(file, { throwIfNoEntry: false })
|
|
200
|
-
if (!info) return undefined
|
|
198
|
+
const [file, mtimeMs, size, contentHash] = entry
|
|
199
|
+
const info = statSync(file, { throwIfNoEntry: false })
|
|
200
|
+
if (!info) return undefined
|
|
201
201
|
if (info.mtimeMs === mtimeMs && info.size === size) {
|
|
202
|
-
checked.push(entry)
|
|
203
|
-
continue
|
|
202
|
+
checked.push(entry)
|
|
203
|
+
continue
|
|
204
204
|
}
|
|
205
|
-
let source: string
|
|
205
|
+
let source: string
|
|
206
206
|
try {
|
|
207
|
-
source = readFileSync(file, 'utf8')
|
|
207
|
+
source = readFileSync(file, 'utf8')
|
|
208
208
|
} catch {
|
|
209
|
-
return undefined
|
|
209
|
+
return undefined
|
|
210
210
|
}
|
|
211
|
-
if (hash(source) !== contentHash) return undefined
|
|
212
|
-
moved = true
|
|
213
|
-
checked.push([file, info.mtimeMs, info.size, contentHash])
|
|
211
|
+
if (hash(source) !== contentHash) return undefined
|
|
212
|
+
moved = true
|
|
213
|
+
checked.push([file, info.mtimeMs, info.size, contentHash])
|
|
214
214
|
}
|
|
215
|
-
return moved ? checked : files
|
|
215
|
+
return moved ? checked : files
|
|
216
216
|
}
|
|
217
217
|
|
|
218
218
|
/** Bisect seam: `PNEXT_DEV_FACTS_STATS=1` prints the hit/miss split at exit. */
|
|
219
|
-
const stats = { hits: 0, misses: 0 }
|
|
219
|
+
const stats = { hits: 0, misses: 0 }
|
|
220
220
|
// eslint-disable-next-line turbo/no-undeclared-env-vars
|
|
221
221
|
if (process.env.PNEXT_DEV_FACTS_STATS === '1') {
|
|
222
|
-
process.on('exit', () => console.log(`route-facts hits=${stats.hits} misses=${stats.misses}`))
|
|
222
|
+
process.on('exit', () => console.log(`route-facts hits=${stats.hits} misses=${stats.misses}`))
|
|
223
223
|
}
|