vinext 0.1.1 → 0.1.3
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 +2 -5
- package/dist/build/client-build-config.d.ts +7 -1
- package/dist/build/client-build-config.js +9 -1
- package/dist/build/prerender.d.ts +9 -1
- package/dist/build/prerender.js +41 -12
- package/dist/build/run-prerender.d.ts +10 -2
- package/dist/build/run-prerender.js +15 -1
- package/dist/check.js +4 -3
- package/dist/client/app-nav-failure-handler.d.ts +8 -0
- package/dist/client/app-nav-failure-handler.js +44 -0
- package/dist/client/navigation-runtime.d.ts +3 -2
- package/dist/client/vinext-next-data.d.ts +18 -1
- package/dist/client/window-next.d.ts +8 -5
- package/dist/client/window-next.js +12 -1
- package/dist/cloudflare/src/cache/cdn-adapter.runtime.js +6 -1
- package/dist/config/config-matchers.d.ts +11 -4
- package/dist/config/config-matchers.js +88 -16
- package/dist/config/next-config.d.ts +59 -4
- package/dist/config/next-config.js +149 -48
- package/dist/deploy.d.ts +30 -11
- package/dist/deploy.js +189 -101
- package/dist/entries/app-browser-entry.d.ts +9 -3
- package/dist/entries/app-browser-entry.js +21 -3
- package/dist/entries/app-rsc-entry.d.ts +2 -0
- package/dist/entries/app-rsc-entry.js +71 -6
- package/dist/entries/app-rsc-manifest.js +2 -0
- package/dist/entries/app-ssr-entry.js +1 -1
- package/dist/entries/pages-client-entry.js +54 -9
- package/dist/entries/pages-server-entry.js +48 -11
- package/dist/index.d.ts +0 -2
- package/dist/index.js +285 -139
- package/dist/plugins/dynamic-preload-metadata.d.ts +13 -0
- package/dist/plugins/dynamic-preload-metadata.js +415 -0
- package/dist/plugins/extensionless-dynamic-import.d.ts +6 -0
- package/dist/plugins/extensionless-dynamic-import.js +152 -0
- package/dist/plugins/og-assets.js +2 -2
- package/dist/plugins/optimize-imports.d.ts +10 -5
- package/dist/plugins/optimize-imports.js +27 -21
- package/dist/plugins/postcss.js +7 -7
- package/dist/plugins/sass.d.ts +53 -24
- package/dist/plugins/sass.js +249 -1
- package/dist/plugins/typeof-window.d.ts +14 -0
- package/dist/plugins/typeof-window.js +150 -0
- package/dist/plugins/wasm-module-import.d.ts +15 -0
- package/dist/plugins/wasm-module-import.js +50 -0
- package/dist/routing/app-route-graph.d.ts +25 -2
- package/dist/routing/app-route-graph.js +91 -22
- package/dist/routing/file-matcher.d.ts +10 -1
- package/dist/routing/file-matcher.js +23 -2
- package/dist/routing/pages-router.js +3 -3
- package/dist/routing/utils.d.ts +35 -6
- package/dist/routing/utils.js +59 -7
- package/dist/server/api-handler.d.ts +6 -1
- package/dist/server/api-handler.js +21 -15
- package/dist/server/app-browser-action-result.d.ts +19 -6
- package/dist/server/app-browser-action-result.js +19 -10
- package/dist/server/app-browser-entry.js +269 -297
- package/dist/server/app-browser-error.d.ts +10 -3
- package/dist/server/app-browser-error.js +47 -6
- package/dist/server/app-browser-history-controller.d.ts +104 -0
- package/dist/server/app-browser-history-controller.js +210 -0
- package/dist/server/app-browser-hydration.d.ts +2 -0
- package/dist/server/app-browser-hydration.js +1 -0
- package/dist/server/app-browser-navigation-controller.d.ts +7 -4
- package/dist/server/app-browser-navigation-controller.js +33 -9
- package/dist/server/app-browser-rsc-redirect.d.ts +11 -2
- package/dist/server/app-browser-rsc-redirect.js +30 -8
- package/dist/server/app-browser-server-action-navigation.d.ts +6 -0
- package/dist/server/app-browser-server-action-navigation.js +9 -0
- package/dist/server/app-browser-state.js +4 -7
- package/dist/server/app-browser-stream.js +86 -43
- package/dist/server/app-browser-visible-commit.js +1 -1
- package/dist/server/app-elements-wire.d.ts +6 -1
- package/dist/server/app-elements-wire.js +14 -4
- package/dist/server/app-elements.d.ts +2 -2
- package/dist/server/app-elements.js +2 -2
- package/dist/server/app-fallback-renderer.d.ts +3 -1
- package/dist/server/app-fallback-renderer.js +6 -2
- package/dist/server/app-middleware.js +1 -0
- package/dist/server/app-optimistic-routing.js +24 -3
- package/dist/server/app-page-boundary-render.d.ts +3 -1
- package/dist/server/app-page-boundary-render.js +31 -16
- package/dist/server/app-page-cache-render.d.ts +53 -0
- package/dist/server/app-page-cache-render.js +91 -0
- package/dist/server/app-page-cache.d.ts +16 -2
- package/dist/server/app-page-cache.js +71 -8
- package/dist/server/app-page-dispatch.d.ts +34 -0
- package/dist/server/app-page-dispatch.js +167 -97
- package/dist/server/app-page-element-builder.d.ts +23 -2
- package/dist/server/app-page-element-builder.js +42 -10
- package/dist/server/app-page-execution.d.ts +7 -2
- package/dist/server/app-page-execution.js +53 -18
- package/dist/server/app-page-probe.d.ts +1 -0
- package/dist/server/app-page-probe.js +4 -0
- package/dist/server/app-page-render-observation.d.ts +3 -1
- package/dist/server/app-page-render-observation.js +17 -1
- package/dist/server/app-page-render.d.ts +13 -2
- package/dist/server/app-page-render.js +48 -17
- package/dist/server/app-page-request.d.ts +3 -0
- package/dist/server/app-page-request.js +5 -3
- package/dist/server/app-page-response.js +1 -1
- package/dist/server/app-page-route-wiring.d.ts +5 -1
- package/dist/server/app-page-route-wiring.js +21 -11
- package/dist/server/app-page-stream.d.ts +16 -9
- package/dist/server/app-page-stream.js +12 -9
- package/dist/server/app-pages-bridge.d.ts +18 -0
- package/dist/server/app-pages-bridge.js +22 -5
- package/dist/server/app-ppr-fallback-shell-render.d.ts +17 -0
- package/dist/server/app-ppr-fallback-shell-render.js +26 -0
- package/dist/server/app-ppr-fallback-shell.d.ts +13 -1
- package/dist/server/app-ppr-fallback-shell.js +8 -1
- package/dist/server/app-route-handler-dispatch.js +9 -2
- package/dist/server/app-route-handler-policy.d.ts +1 -0
- package/dist/server/app-route-handler-response.js +11 -10
- package/dist/server/app-route-handler-runtime.js +12 -1
- package/dist/server/app-router-entry.js +5 -0
- package/dist/server/app-rsc-cache-busting.js +2 -0
- package/dist/server/app-rsc-handler.d.ts +25 -0
- package/dist/server/app-rsc-handler.js +153 -53
- package/dist/server/app-rsc-response-finalizer.js +1 -1
- package/dist/server/app-rsc-route-matching.d.ts +3 -0
- package/dist/server/app-rsc-route-matching.js +2 -0
- package/dist/server/app-segment-config.d.ts +9 -1
- package/dist/server/app-segment-config.js +12 -3
- package/dist/server/app-server-action-execution.d.ts +12 -0
- package/dist/server/app-server-action-execution.js +47 -15
- package/dist/server/app-ssr-entry.d.ts +2 -0
- package/dist/server/app-ssr-entry.js +81 -8
- package/dist/server/app-ssr-stream.js +9 -1
- package/dist/server/cache-control.js +4 -0
- package/dist/server/dev-lockfile.js +2 -1
- package/dist/server/dev-server.d.ts +2 -2
- package/dist/server/dev-server.js +287 -63
- package/dist/server/headers.d.ts +8 -1
- package/dist/server/headers.js +8 -1
- package/dist/server/hybrid-route-priority.d.ts +22 -0
- package/dist/server/hybrid-route-priority.js +33 -0
- package/dist/server/image-optimization.d.ts +18 -9
- package/dist/server/image-optimization.js +37 -23
- package/dist/server/implicit-tags.d.ts +2 -1
- package/dist/server/implicit-tags.js +4 -1
- package/dist/server/instrumentation-runtime.d.ts +6 -0
- package/dist/server/instrumentation-runtime.js +8 -0
- package/dist/server/isr-decision.d.ts +79 -0
- package/dist/server/isr-decision.js +70 -0
- package/dist/server/metadata-route-response.js +5 -3
- package/dist/server/middleware-runtime.d.ts +13 -0
- package/dist/server/middleware-runtime.js +11 -7
- package/dist/server/middleware.js +1 -0
- package/dist/server/navigation-planner.d.ts +186 -22
- package/dist/server/navigation-planner.js +302 -0
- package/dist/server/navigation-trace.d.ts +18 -1
- package/dist/server/navigation-trace.js +18 -1
- package/dist/server/normalize-path.d.ts +0 -8
- package/dist/server/normalize-path.js +3 -1
- package/dist/server/otel-tracer-extension.d.ts +45 -0
- package/dist/server/otel-tracer-extension.js +89 -0
- package/dist/server/pages-api-route.d.ts +20 -3
- package/dist/server/pages-api-route.js +19 -3
- package/dist/server/pages-asset-tags.d.ts +16 -4
- package/dist/server/pages-asset-tags.js +22 -12
- package/dist/server/pages-data-route.d.ts +8 -1
- package/dist/server/pages-data-route.js +16 -3
- package/dist/server/pages-get-initial-props.d.ts +54 -4
- package/dist/server/pages-get-initial-props.js +43 -1
- package/dist/server/pages-node-compat.d.ts +3 -11
- package/dist/server/pages-node-compat.js +175 -122
- package/dist/server/pages-page-data.d.ts +39 -2
- package/dist/server/pages-page-data.js +261 -46
- package/dist/server/pages-page-handler.d.ts +5 -2
- package/dist/server/pages-page-handler.js +78 -25
- package/dist/server/pages-page-response.d.ts +47 -2
- package/dist/server/pages-page-response.js +73 -9
- package/dist/server/pages-readiness.d.ts +1 -1
- package/dist/server/pages-request-pipeline.d.ts +16 -1
- package/dist/server/pages-request-pipeline.js +96 -38
- package/dist/server/pregenerated-concrete-paths.d.ts +1 -17
- package/dist/server/pregenerated-concrete-paths.js +2 -19
- package/dist/server/prerender-manifest.d.ts +33 -0
- package/dist/server/prerender-manifest.js +54 -0
- package/dist/server/prerender-route-params.d.ts +1 -2
- package/dist/server/prod-server.d.ts +39 -1
- package/dist/server/prod-server.js +107 -37
- package/dist/server/request-pipeline.d.ts +3 -15
- package/dist/server/request-pipeline.js +58 -47
- package/dist/server/rsc-stream-hints.d.ts +5 -1
- package/dist/server/rsc-stream-hints.js +6 -1
- package/dist/server/seed-cache.js +10 -18
- package/dist/shims/app-router-scroll-state.d.ts +3 -1
- package/dist/shims/app-router-scroll-state.js +14 -2
- package/dist/shims/app-router-scroll.d.ts +3 -0
- package/dist/shims/app-router-scroll.js +28 -18
- package/dist/shims/cache-runtime.js +12 -4
- package/dist/shims/cache.d.ts +1 -0
- package/dist/shims/cache.js +1 -1
- package/dist/shims/cdn-cache.d.ts +5 -5
- package/dist/shims/dynamic-preload-chunks.d.ts +8 -0
- package/dist/shims/dynamic-preload-chunks.js +79 -0
- package/dist/shims/dynamic.d.ts +4 -0
- package/dist/shims/dynamic.js +4 -2
- package/dist/shims/error-boundary.d.ts +6 -4
- package/dist/shims/error-boundary.js +7 -0
- package/dist/shims/error.js +38 -11
- package/dist/shims/error.react-server.d.ts +9 -0
- package/dist/shims/error.react-server.js +6 -0
- package/dist/shims/fetch-cache.d.ts +11 -1
- package/dist/shims/fetch-cache.js +55 -20
- package/dist/shims/hash-scroll.js +6 -1
- package/dist/shims/head.js +6 -1
- package/dist/shims/headers.d.ts +16 -2
- package/dist/shims/headers.js +66 -5
- package/dist/shims/image-config.js +7 -1
- package/dist/shims/internal/als-registry.js +28 -1
- package/dist/shims/internal/app-route-detection.d.ts +6 -3
- package/dist/shims/internal/app-route-detection.js +18 -23
- package/dist/shims/internal/app-router-context.d.ts +5 -0
- package/dist/shims/internal/hybrid-client-route-owner.d.ts +31 -0
- package/dist/shims/internal/hybrid-client-route-owner.js +143 -0
- package/dist/shims/internal/navigation-untracked.d.ts +35 -0
- package/dist/shims/internal/navigation-untracked.js +55 -0
- package/dist/shims/internal/pages-data-target.d.ts +7 -2
- package/dist/shims/internal/pages-data-target.js +17 -8
- package/dist/shims/internal/pages-router-accessor.d.ts +19 -0
- package/dist/shims/internal/pages-router-accessor.js +13 -0
- package/dist/shims/internal/router-context.d.ts +2 -1
- package/dist/shims/internal/router-context.js +3 -1
- package/dist/shims/link.js +12 -5
- package/dist/shims/metadata.d.ts +6 -2
- package/dist/shims/metadata.js +32 -14
- package/dist/shims/navigation.d.ts +14 -17
- package/dist/shims/navigation.js +93 -46
- package/dist/shims/ppr-fallback-shell.d.ts +5 -1
- package/dist/shims/ppr-fallback-shell.js +28 -7
- package/dist/shims/router.d.ts +13 -2
- package/dist/shims/router.js +434 -116
- package/dist/shims/script-nonce-context.d.ts +1 -1
- package/dist/shims/script-nonce-context.js +11 -3
- package/dist/shims/server.d.ts +33 -2
- package/dist/shims/server.js +75 -18
- package/dist/shims/slot.js +1 -1
- package/dist/shims/unified-request-context.js +2 -0
- package/dist/typegen.js +1 -0
- package/dist/utils/built-asset-url.d.ts +4 -0
- package/dist/utils/built-asset-url.js +11 -0
- package/dist/utils/client-build-manifest.js +15 -5
- package/dist/utils/client-runtime-metadata.d.ts +45 -0
- package/dist/utils/client-runtime-metadata.js +63 -0
- package/dist/utils/commonjs-loader.d.ts +16 -0
- package/dist/utils/commonjs-loader.js +100 -0
- package/dist/utils/deployment-id.d.ts +8 -0
- package/dist/utils/deployment-id.js +22 -0
- package/dist/utils/hash.d.ts +17 -1
- package/dist/utils/hash.js +36 -1
- package/dist/utils/html-limited-bots.d.ts +18 -1
- package/dist/utils/html-limited-bots.js +23 -1
- package/dist/utils/lazy-chunks.d.ts +27 -1
- package/dist/utils/lazy-chunks.js +65 -1
- package/dist/utils/manifest-paths.d.ts +20 -2
- package/dist/utils/manifest-paths.js +38 -3
- package/dist/utils/parse-cookie.d.ts +13 -0
- package/dist/utils/parse-cookie.js +52 -0
- package/dist/utils/path.d.ts +8 -1
- package/dist/utils/path.js +13 -1
- package/package.json +2 -2
- package/dist/shims/internal/parse-cookie-header.d.ts +0 -14
- package/dist/shims/internal/parse-cookie-header.js +0 -30
package/README.md
CHANGED
|
@@ -528,22 +528,19 @@ The cache is pluggable. The default `MemoryCacheHandler` works out of the box. S
|
|
|
528
528
|
|
|
529
529
|
#### Configuring cache adapters from `vite.config`
|
|
530
530
|
|
|
531
|
-
Instead of wiring up cache handlers imperatively from a worker entry, you can declare them in the `vinext()` plugin config. The `@vinext/cloudflare` package ships
|
|
531
|
+
Instead of wiring up cache handlers imperatively from a worker entry, you can declare them in the `vinext()` plugin config. The `@vinext/cloudflare` package ships Cloudflare adapters for this:
|
|
532
532
|
|
|
533
533
|
- **`kvDataAdapter()`** (`@vinext/cloudflare/cache/kv-data-adapter`) — backs the `"use cache"` data cache with a Workers KV namespace.
|
|
534
|
-
- **`cdnAdapter()`** (`@vinext/cloudflare/cache/cdn-adapter`) — backs full-route CDN caching with the Workers Cache API.
|
|
535
534
|
|
|
536
535
|
```ts
|
|
537
536
|
import { defineConfig } from "vite";
|
|
538
537
|
import vinext from "vinext";
|
|
539
|
-
import { cdnAdapter } from "@vinext/cloudflare/cache/cdn-adapter";
|
|
540
538
|
import { kvDataAdapter } from "@vinext/cloudflare/cache/kv-data-adapter";
|
|
541
539
|
|
|
542
540
|
export default defineConfig({
|
|
543
541
|
plugins: [
|
|
544
542
|
vinext({
|
|
545
543
|
cache: {
|
|
546
|
-
cdn: cdnAdapter(),
|
|
547
544
|
data: kvDataAdapter(),
|
|
548
545
|
},
|
|
549
546
|
}),
|
|
@@ -559,7 +556,7 @@ The KV data adapter reads `env[binding]` at runtime, so add the matching KV name
|
|
|
559
556
|
}
|
|
560
557
|
```
|
|
561
558
|
|
|
562
|
-
`binding` defaults to `VINEXT_KV_CACHE`, so `kvDataAdapter()` with no options works as long as that's your binding name. Other options: `appPrefix` (namespace cache keys to isolate multiple apps in one KV namespace), `ttlSeconds` (default KV `expirationTtl`, default 30 days), and `tagCacheTtlMs` (in-memory tag-invalidation cache TTL, default 5s).
|
|
559
|
+
`binding` defaults to `VINEXT_KV_CACHE`, so `kvDataAdapter()` with no options works as long as that's your binding name. Other options: `appPrefix` (namespace cache keys to isolate multiple apps in one KV namespace), `ttlSeconds` (default KV `expirationTtl`, default 30 days), and `tagCacheTtlMs` (in-memory tag-invalidation cache TTL, default 5s).
|
|
563
560
|
|
|
564
561
|
Each builder returns a plain, serializable `{ adapter, options }` descriptor — **it never touches the Workers runtime**, so nothing throws at build or dev time when bindings aren't available. The actual adapter (and its `env` binding lookup) is instantiated lazily on the first request.
|
|
565
562
|
|
|
@@ -51,10 +51,16 @@ declare function createClientManualChunks(shimsDir: string): (id: string) => str
|
|
|
51
51
|
* compression efficiency — small files restart the compression dictionary,
|
|
52
52
|
* adding ~5-15% wire overhead vs fewer larger chunks.
|
|
53
53
|
*/
|
|
54
|
+
declare function createClientFileNameConfig(assetsDir: string): {
|
|
55
|
+
entryFileNames: string;
|
|
56
|
+
chunkFileNames: string;
|
|
57
|
+
};
|
|
54
58
|
declare function createClientOutputConfig(clientManualChunks: (id: string) => string | undefined, assetsDir: string): {
|
|
55
59
|
assetFileNames: (assetInfo: ClientAssetFileNameInfo) => string;
|
|
56
60
|
manualChunks: (id: string) => string | undefined;
|
|
57
61
|
experimentalMinChunkSize: number;
|
|
62
|
+
entryFileNames: string;
|
|
63
|
+
chunkFileNames: string;
|
|
58
64
|
};
|
|
59
65
|
declare function createClientCodeSplittingConfig(clientManualChunks: (id: string) => string | undefined): {
|
|
60
66
|
minSize: number;
|
|
@@ -155,4 +161,4 @@ type VinextBuildConfigWithLegacy = VinextBuildConfig & {
|
|
|
155
161
|
declare function getBuildBundlerOptions(build: UserConfig["build"] | undefined): VinextBuildBundlerOptions | undefined;
|
|
156
162
|
declare function withBuildBundlerOptions(viteMajorVersion: number, bundlerOptions: VinextBuildBundlerOptions): Partial<VinextBuildConfigWithLegacy>;
|
|
157
163
|
//#endregion
|
|
158
|
-
export { RSC_FRAMEWORK_CHUNK_TEST, clientTreeshakeConfig, createClientAssetFileNames, createClientCodeSplittingConfig, createClientManualChunks, createClientOutputConfig, createRscFrameworkChunkOutputConfig, getBuildBundlerOptions, getClientTreeshakeConfigForVite, isRscFrameworkModule, withBuildBundlerOptions };
|
|
164
|
+
export { RSC_FRAMEWORK_CHUNK_TEST, clientTreeshakeConfig, createClientAssetFileNames, createClientCodeSplittingConfig, createClientFileNameConfig, createClientManualChunks, createClientOutputConfig, createRscFrameworkChunkOutputConfig, getBuildBundlerOptions, getClientTreeshakeConfigForVite, isRscFrameworkModule, withBuildBundlerOptions };
|
|
@@ -89,8 +89,16 @@ function createClientManualChunks(shimsDir) {
|
|
|
89
89
|
* compression efficiency — small files restart the compression dictionary,
|
|
90
90
|
* adding ~5-15% wire overhead vs fewer larger chunks.
|
|
91
91
|
*/
|
|
92
|
+
function createClientFileNameConfig(assetsDir) {
|
|
93
|
+
const chunksDir = `${assetsDir}/chunks`;
|
|
94
|
+
return {
|
|
95
|
+
entryFileNames: `${chunksDir}/[name]-[hash].js`,
|
|
96
|
+
chunkFileNames: `${chunksDir}/[name]-[hash].js`
|
|
97
|
+
};
|
|
98
|
+
}
|
|
92
99
|
function createClientOutputConfig(clientManualChunks, assetsDir) {
|
|
93
100
|
return {
|
|
101
|
+
...createClientFileNameConfig(assetsDir),
|
|
94
102
|
assetFileNames: createClientAssetFileNames(assetsDir),
|
|
95
103
|
manualChunks: clientManualChunks,
|
|
96
104
|
experimentalMinChunkSize: 1e4
|
|
@@ -228,4 +236,4 @@ function withBuildBundlerOptions(viteMajorVersion, bundlerOptions) {
|
|
|
228
236
|
return viteMajorVersion >= 8 ? { rolldownOptions: bundlerOptions } : { rollupOptions: bundlerOptions };
|
|
229
237
|
}
|
|
230
238
|
//#endregion
|
|
231
|
-
export { RSC_FRAMEWORK_CHUNK_TEST, clientTreeshakeConfig, createClientAssetFileNames, createClientCodeSplittingConfig, createClientManualChunks, createClientOutputConfig, createRscFrameworkChunkOutputConfig, getBuildBundlerOptions, getClientTreeshakeConfigForVite, isRscFrameworkModule, withBuildBundlerOptions };
|
|
239
|
+
export { RSC_FRAMEWORK_CHUNK_TEST, clientTreeshakeConfig, createClientAssetFileNames, createClientCodeSplittingConfig, createClientFileNameConfig, createClientManualChunks, createClientOutputConfig, createRscFrameworkChunkOutputConfig, getBuildBundlerOptions, getClientTreeshakeConfigForVite, isRscFrameworkModule, withBuildBundlerOptions };
|
|
@@ -22,7 +22,8 @@ type PrerenderRouteResult = {
|
|
|
22
22
|
* Omitted for non-dynamic routes where pattern === path.
|
|
23
23
|
*/
|
|
24
24
|
path?: string; /** Which router produced this route. Used by cache seeding. */
|
|
25
|
-
router: "app" | "pages";
|
|
25
|
+
router: "app" | "pages"; /** Set to true when this is a PPR fallback shell. */
|
|
26
|
+
fallback?: boolean;
|
|
26
27
|
} | {
|
|
27
28
|
route: string;
|
|
28
29
|
status: "skipped";
|
|
@@ -31,6 +32,13 @@ type PrerenderRouteResult = {
|
|
|
31
32
|
route: string;
|
|
32
33
|
status: "error";
|
|
33
34
|
error: string;
|
|
35
|
+
/**
|
|
36
|
+
* Set when the error must fail the build in ALL modes (default included),
|
|
37
|
+
* not just `output: 'export'`. Used for a thrown generateStaticParams /
|
|
38
|
+
* getStaticPaths, which Next.js treats as a fatal build error rather than a
|
|
39
|
+
* silently-skipped route. Refs cloudflare/vinext#1982
|
|
40
|
+
*/
|
|
41
|
+
fatal?: true;
|
|
34
42
|
};
|
|
35
43
|
/** Called after each route is resolved (rendered, skipped, or error). */
|
|
36
44
|
type PrerenderProgressCallback = (update: {
|
package/dist/build/prerender.js
CHANGED
|
@@ -7,11 +7,11 @@ import { classifyAppRoute, classifyPagesRoute, getAppRouteRenderEntryPath } from
|
|
|
7
7
|
import { BLOCKED_PAGES } from "../shims/constants.js";
|
|
8
8
|
import { concatUint8Arrays, decodeRscEmbeddedChunk } from "../server/app-rsc-embedded-chunks.js";
|
|
9
9
|
import { navigationRuntimeRscBootstrapExpression } from "../server/app-ssr-stream.js";
|
|
10
|
+
import { createAppPprFallbackShells, markAppPprDynamicFallbackShellHtml } from "../server/app-ppr-fallback-shell.js";
|
|
10
11
|
import { encodePrerenderRouteParams, serializePrerenderRouteParamsHeader } from "../server/prerender-route-params.js";
|
|
11
12
|
import { readPrerenderSecret } from "./server-manifest.js";
|
|
12
13
|
import { getOutputPath, getRscOutputPath } from "../utils/prerender-output-paths.js";
|
|
13
14
|
import { startProdServer } from "../server/prod-server.js";
|
|
14
|
-
import { createAppPprFallbackShells } from "../server/app-ppr-fallback-shell.js";
|
|
15
15
|
import fs from "node:fs";
|
|
16
16
|
import path from "node:path";
|
|
17
17
|
import os from "node:os";
|
|
@@ -33,9 +33,21 @@ import os from "node:os";
|
|
|
33
33
|
* 'default' — skips SSR routes (served at request time); ISR routes rendered
|
|
34
34
|
* 'export' — SSR routes are build errors; ISR treated as static (no revalidate)
|
|
35
35
|
*/
|
|
36
|
+
const EXPERIMENTAL_PPR_FALLBACK_SHELLS_ENV = "__VINEXT_EXPERIMENTAL_PPR_FALLBACK_SHELLS";
|
|
37
|
+
function isExperimentalPprFallbackShellGenerationEnabled(env = process.env) {
|
|
38
|
+
return env[EXPERIMENTAL_PPR_FALLBACK_SHELLS_ENV] === "1";
|
|
39
|
+
}
|
|
36
40
|
function getErrorMessageWithStack(err) {
|
|
37
41
|
return err.stack || err.message;
|
|
38
42
|
}
|
|
43
|
+
var PrerenderUserFunctionError = class extends Error {};
|
|
44
|
+
function parsePrerenderEndpointError(text) {
|
|
45
|
+
try {
|
|
46
|
+
const parsed = JSON.parse(text);
|
|
47
|
+
if (parsed && typeof parsed === "object" && "error" in parsed) return typeof parsed.error === "string" && parsed.error.length > 0 ? parsed.error : "Unknown prerender endpoint error";
|
|
48
|
+
} catch {}
|
|
49
|
+
return text || "Unknown prerender endpoint error";
|
|
50
|
+
}
|
|
39
51
|
/** Sentinel path used to trigger 404 rendering without a real route match. */
|
|
40
52
|
const NOT_FOUND_SENTINEL_PATH = "/__vinext_nonexistent_for_404__";
|
|
41
53
|
const DEFAULT_CONCURRENCY = Math.min(os.availableParallelism(), 8);
|
|
@@ -275,6 +287,7 @@ async function prerenderPages({ routes, apiRoutes, pagesDir, outDir, config, mod
|
|
|
275
287
|
const res = await fetch(`${baseUrl}/__vinext/prerender/pages-static-paths?${search}`, { headers: secretHeaders });
|
|
276
288
|
const text = await res.text();
|
|
277
289
|
if (!res.ok) {
|
|
290
|
+
if (res.status === 500) throw new PrerenderUserFunctionError(parsePrerenderEndpointError(text));
|
|
278
291
|
console.warn(`[vinext] Warning: /__vinext/prerender/pages-static-paths returned ${res.status} for ${r.pattern}. Dynamic paths will be skipped. This may indicate a stale or missing prerender secret.`);
|
|
279
292
|
return {
|
|
280
293
|
paths: [],
|
|
@@ -322,10 +335,21 @@ async function prerenderPages({ routes, apiRoutes, pagesDir, outDir, config, mod
|
|
|
322
335
|
});
|
|
323
336
|
continue;
|
|
324
337
|
}
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
338
|
+
let pathsResult;
|
|
339
|
+
try {
|
|
340
|
+
pathsResult = await route.module.getStaticPaths({
|
|
341
|
+
locales: [],
|
|
342
|
+
defaultLocale: ""
|
|
343
|
+
});
|
|
344
|
+
} catch (e) {
|
|
345
|
+
results.push({
|
|
346
|
+
route: route.pattern,
|
|
347
|
+
status: "error",
|
|
348
|
+
error: `Failed to call getStaticPaths(): ${e.message}`,
|
|
349
|
+
...e instanceof PrerenderUserFunctionError ? { fatal: true } : {}
|
|
350
|
+
});
|
|
351
|
+
continue;
|
|
352
|
+
}
|
|
329
353
|
const fallback = pathsResult?.fallback ?? false;
|
|
330
354
|
if (mode === "export" && fallback !== false) {
|
|
331
355
|
results.push({
|
|
@@ -521,6 +545,7 @@ async function prerenderApp({ routes, metadataRoutes = [], outDir, config, mode,
|
|
|
521
545
|
const res = await fetch(`${baseUrl}/__vinext/prerender/static-params?${search}`, { headers: secretHeaders });
|
|
522
546
|
const text = await res.text();
|
|
523
547
|
if (!res.ok) {
|
|
548
|
+
if (res.status === 500) throw new PrerenderUserFunctionError(parsePrerenderEndpointError(text));
|
|
524
549
|
console.warn(`[vinext] Warning: /__vinext/prerender/static-params returned ${res.status} for ${pattern}. Static params will be skipped. This may indicate a stale or missing prerender secret.`);
|
|
525
550
|
return null;
|
|
526
551
|
}
|
|
@@ -642,7 +667,7 @@ async function prerenderApp({ routes, metadataRoutes = [], outDir, config, mode,
|
|
|
642
667
|
revalidate,
|
|
643
668
|
isSpeculative: false
|
|
644
669
|
});
|
|
645
|
-
if (config.cacheComponents === true) for (const fallbackShell of createAppPprFallbackShells(route, params)) {
|
|
670
|
+
if (config.cacheComponents === true && isExperimentalPprFallbackShellGenerationEnabled()) for (const fallbackShell of createAppPprFallbackShells(route, params)) {
|
|
646
671
|
if (queuedRouteUrls.has(fallbackShell.pathname)) continue;
|
|
647
672
|
queuedRouteUrls.add(fallbackShell.pathname);
|
|
648
673
|
urlsToRender.push({
|
|
@@ -650,7 +675,8 @@ async function prerenderApp({ routes, metadataRoutes = [], outDir, config, mode,
|
|
|
650
675
|
routePattern: route.pattern,
|
|
651
676
|
prerenderRouteParams: encodePrerenderRouteParams(route.pattern, fallbackShell.params, fallbackShell.fallbackParamNames),
|
|
652
677
|
revalidate,
|
|
653
|
-
isSpeculative: false
|
|
678
|
+
isSpeculative: false,
|
|
679
|
+
isFallback: true
|
|
654
680
|
});
|
|
655
681
|
}
|
|
656
682
|
}
|
|
@@ -660,7 +686,8 @@ async function prerenderApp({ routes, metadataRoutes = [], outDir, config, mode,
|
|
|
660
686
|
results.push({
|
|
661
687
|
route: route.pattern,
|
|
662
688
|
status: "error",
|
|
663
|
-
error: `Failed to call generateStaticParams(): ${detail}
|
|
689
|
+
error: `Failed to call generateStaticParams(): ${detail}`,
|
|
690
|
+
...e instanceof PrerenderUserFunctionError ? { fatal: true } : {}
|
|
664
691
|
});
|
|
665
692
|
}
|
|
666
693
|
else if (type === "unknown") urlsToRender.push({
|
|
@@ -684,7 +711,7 @@ async function prerenderApp({ routes, metadataRoutes = [], outDir, config, mode,
|
|
|
684
711
|
* exactly once per URL after this function returns, keeping the callback
|
|
685
712
|
* at a single, predictable call site.
|
|
686
713
|
*/
|
|
687
|
-
async function renderUrl({ urlPath, routePattern, prerenderRouteParams, revalidate, isSpeculative }) {
|
|
714
|
+
async function renderUrl({ urlPath, routePattern, prerenderRouteParams, revalidate, isSpeculative, isFallback }) {
|
|
688
715
|
try {
|
|
689
716
|
const prerenderRouteParamsHeader = serializePrerenderRouteParamsHeader(prerenderRouteParams);
|
|
690
717
|
const htmlHeaders = new Headers();
|
|
@@ -736,7 +763,7 @@ async function prerenderApp({ routes, metadataRoutes = [], outDir, config, mode,
|
|
|
736
763
|
status: "error",
|
|
737
764
|
error: "RSC handler returned no prerender HTML"
|
|
738
765
|
};
|
|
739
|
-
const html = htmlRender.html;
|
|
766
|
+
const html = isFallback ? markAppPprDynamicFallbackShellHtml(htmlRender.html) : htmlRender.html;
|
|
740
767
|
let rscData = extractRscPayloadFromPrerenderedHtml(html);
|
|
741
768
|
if (rscData === null) {
|
|
742
769
|
const rscHeaders = new Headers({
|
|
@@ -772,7 +799,8 @@ async function prerenderApp({ routes, metadataRoutes = [], outDir, config, mode,
|
|
|
772
799
|
revalidate: renderedRevalidate,
|
|
773
800
|
...typeof renderedRevalidate === "number" ? { expire: renderedCacheControl.expire } : {},
|
|
774
801
|
router: "app",
|
|
775
|
-
...urlPath !== routePattern ? { path: urlPath } : {}
|
|
802
|
+
...urlPath !== routePattern ? { path: urlPath } : {},
|
|
803
|
+
...isFallback ? { fallback: true } : {}
|
|
776
804
|
};
|
|
777
805
|
} catch (e) {
|
|
778
806
|
if (isSpeculative) return {
|
|
@@ -878,7 +906,8 @@ function writePrerenderIndex(routes, outDir, options) {
|
|
|
878
906
|
revalidate: r.revalidate,
|
|
879
907
|
...typeof r.revalidate === "number" ? { expire: r.expire } : {},
|
|
880
908
|
router: r.router,
|
|
881
|
-
...r.path ? { path: r.path } : {}
|
|
909
|
+
...r.path ? { path: r.path } : {},
|
|
910
|
+
...r.fallback ? { fallback: true } : {}
|
|
882
911
|
};
|
|
883
912
|
if (r.status === "skipped") return {
|
|
884
913
|
route: r.route,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ResolvedNextConfig } from "../config/next-config.js";
|
|
2
|
-
import { PrerenderResult } from "./prerender.js";
|
|
2
|
+
import { PrerenderResult, PrerenderRouteResult } from "./prerender.js";
|
|
3
3
|
|
|
4
4
|
//#region src/build/run-prerender.d.ts
|
|
5
5
|
type RunPrerenderOptions = {
|
|
@@ -48,6 +48,14 @@ type RunPrerenderOptions = {
|
|
|
48
48
|
* If a required production bundle does not exist, an error is thrown directing
|
|
49
49
|
* the user to run `vinext build` first.
|
|
50
50
|
*/
|
|
51
|
+
/**
|
|
52
|
+
* Throw if any route is a `fatal` error (a thrown generateStaticParams /
|
|
53
|
+
* getStaticPaths). These fail the build in ALL modes — default included —
|
|
54
|
+
* matching `next build`, unlike intentionally-skipped dynamic/SSR routes and
|
|
55
|
+
* non-fatal errors (e.g. transport failures), which only fail under
|
|
56
|
+
* `output: 'export'`. Exported for direct unit testing. Refs cloudflare/vinext#1982
|
|
57
|
+
*/
|
|
58
|
+
declare function assertNoFatalPrerenderRoutes(routes: readonly PrerenderRouteResult[]): void;
|
|
51
59
|
declare function runPrerender(options: RunPrerenderOptions): Promise<PrerenderResult | null>;
|
|
52
60
|
//#endregion
|
|
53
|
-
export { runPrerender };
|
|
61
|
+
export { assertNoFatalPrerenderRoutes, runPrerender };
|
|
@@ -82,6 +82,19 @@ function readBuiltBuildId(serverDir) {
|
|
|
82
82
|
* If a required production bundle does not exist, an error is thrown directing
|
|
83
83
|
* the user to run `vinext build` first.
|
|
84
84
|
*/
|
|
85
|
+
/**
|
|
86
|
+
* Throw if any route is a `fatal` error (a thrown generateStaticParams /
|
|
87
|
+
* getStaticPaths). These fail the build in ALL modes — default included —
|
|
88
|
+
* matching `next build`, unlike intentionally-skipped dynamic/SSR routes and
|
|
89
|
+
* non-fatal errors (e.g. transport failures), which only fail under
|
|
90
|
+
* `output: 'export'`. Exported for direct unit testing. Refs cloudflare/vinext#1982
|
|
91
|
+
*/
|
|
92
|
+
function assertNoFatalPrerenderRoutes(routes) {
|
|
93
|
+
const fatalRoutes = routes.filter((r) => r.status === "error" && r.fatal === true);
|
|
94
|
+
if (fatalRoutes.length === 0) return;
|
|
95
|
+
const fatalList = fatalRoutes.map((r) => ` ${r.route}: ${r.error}`).join("\n");
|
|
96
|
+
throw new Error(`Prerender failed: ${fatalRoutes.length} route${fatalRoutes.length !== 1 ? "s" : ""} errored during static generation.\n${fatalList}`);
|
|
97
|
+
}
|
|
85
98
|
async function runPrerender(options) {
|
|
86
99
|
const { root } = options;
|
|
87
100
|
const appDir = findDir(root, "app", "src/app");
|
|
@@ -197,6 +210,7 @@ async function runPrerender(options) {
|
|
|
197
210
|
} finally {
|
|
198
211
|
progress.finish(rendered, skipped, errors);
|
|
199
212
|
}
|
|
213
|
+
assertNoFatalPrerenderRoutes(allRoutes);
|
|
200
214
|
if (mode === "export" && errors > 0) {
|
|
201
215
|
const errorRoutes = allRoutes.filter((r) => r.status === "error").map((r) => ` ${r.route}: ${r.error}`).join("\n");
|
|
202
216
|
throw new Error(`Static export failed: ${errors} route${errors !== 1 ? "s" : ""} cannot be statically exported.\n${errorRoutes}\n\nRemove server-side data fetching (getServerSideProps, force-dynamic, revalidate) from these routes, or remove \`output: "export"\` from next.config.js.`);
|
|
@@ -207,4 +221,4 @@ async function runPrerender(options) {
|
|
|
207
221
|
};
|
|
208
222
|
}
|
|
209
223
|
//#endregion
|
|
210
|
-
export { runPrerender };
|
|
224
|
+
export { assertNoFatalPrerenderRoutes, runPrerender };
|
package/dist/check.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { detectPackageManager } from "./utils/project.js";
|
|
2
|
+
import { normalizePathSeparators } from "./utils/path.js";
|
|
2
3
|
import fs from "node:fs";
|
|
3
4
|
import path from "node:path";
|
|
4
5
|
import { parseAst } from "vite";
|
|
@@ -342,7 +343,7 @@ function findSourceFiles(dir, extensions = [
|
|
|
342
343
|
if (!fs.existsSync(dir)) return results;
|
|
343
344
|
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
344
345
|
for (const entry of entries) {
|
|
345
|
-
const fullPath = path.join(dir, entry.name);
|
|
346
|
+
const fullPath = normalizePathSeparators(path.join(dir, entry.name));
|
|
346
347
|
if (entry.isDirectory()) {
|
|
347
348
|
if (entry.name === "node_modules" || entry.name === ".next" || entry.name === "dist" || entry.name === ".git") continue;
|
|
348
349
|
results.push(...findSourceFiles(fullPath, extensions));
|
|
@@ -563,7 +564,7 @@ function scanImports(root) {
|
|
|
563
564
|
if (mod.startsWith("next/") || mod === "next" || mod === "server-only" || mod === "client-only") {
|
|
564
565
|
const normalized = mod === "next" ? "next" : mod;
|
|
565
566
|
if (!importUsage.has(normalized)) importUsage.set(normalized, []);
|
|
566
|
-
const relFile = path.relative(root, file);
|
|
567
|
+
const relFile = normalizePathSeparators(path.relative(root, file));
|
|
567
568
|
const usedInFiles = importUsage.get(normalized) ?? [];
|
|
568
569
|
if (!usedInFiles.includes(relFile)) usedInFiles.push(relFile);
|
|
569
570
|
}
|
|
@@ -876,7 +877,7 @@ function checkConventions(root) {
|
|
|
876
877
|
const cjsGlobalFiles = [];
|
|
877
878
|
for (const file of allSourceFiles) {
|
|
878
879
|
const content = fs.readFileSync(file, "utf-8");
|
|
879
|
-
const rel = path.relative(root, file);
|
|
880
|
+
const rel = normalizePathSeparators(path.relative(root, file));
|
|
880
881
|
if (viewTransitionRegex.test(content)) viewTransitionFiles.push(rel);
|
|
881
882
|
if (hasFreeCjsGlobal(content)) cjsGlobalFiles.push(rel);
|
|
882
883
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
//#region src/client/app-nav-failure-handler.d.ts
|
|
2
|
+
declare function stageAppNavigationFailureTarget(href: string): void;
|
|
3
|
+
declare function getAppNavigationFailureTarget(href: string): URL | null;
|
|
4
|
+
declare function clearAppNavigationFailureTarget(target?: string | URL): void;
|
|
5
|
+
declare function handleAppNavigationFailure(error: unknown): boolean;
|
|
6
|
+
declare function installAppNavigationFailureListeners(): () => void;
|
|
7
|
+
//#endregion
|
|
8
|
+
export { clearAppNavigationFailureTarget, getAppNavigationFailureTarget, handleAppNavigationFailure, installAppNavigationFailureListeners, stageAppNavigationFailureTarget };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { installWindowNext } from "./window-next.js";
|
|
2
|
+
//#region src/client/app-nav-failure-handler.ts
|
|
3
|
+
function getPendingUrl() {
|
|
4
|
+
if (typeof window === "undefined") return null;
|
|
5
|
+
return window.next?.__pendingUrl ?? null;
|
|
6
|
+
}
|
|
7
|
+
function stageAppNavigationFailureTarget(href) {
|
|
8
|
+
if (!process.env.__NEXT_APP_NAV_FAIL_HANDLING || typeof window === "undefined") return;
|
|
9
|
+
installWindowNext({ __pendingUrl: new URL(href, window.location.href) });
|
|
10
|
+
}
|
|
11
|
+
function getAppNavigationFailureTarget(href) {
|
|
12
|
+
const pendingUrl = getPendingUrl();
|
|
13
|
+
if (pendingUrl === null || typeof window === "undefined") return null;
|
|
14
|
+
return pendingUrl.href === new URL(href, window.location.href).href ? pendingUrl : null;
|
|
15
|
+
}
|
|
16
|
+
function clearAppNavigationFailureTarget(target) {
|
|
17
|
+
if (typeof window === "undefined" || window.next?.__pendingUrl === void 0) return;
|
|
18
|
+
if (target instanceof URL) {
|
|
19
|
+
if (window.next.__pendingUrl !== target) return;
|
|
20
|
+
} else if (target !== void 0 && window.next.__pendingUrl.href !== new URL(target, window.location.href).href) return;
|
|
21
|
+
delete window.next.__pendingUrl;
|
|
22
|
+
}
|
|
23
|
+
function handleAppNavigationFailure(error) {
|
|
24
|
+
if (!process.env.__NEXT_APP_NAV_FAIL_HANDLING || typeof window === "undefined") return false;
|
|
25
|
+
const pendingUrl = getPendingUrl();
|
|
26
|
+
if (pendingUrl === null || pendingUrl.href === window.location.href) return false;
|
|
27
|
+
console.error("Error occurred during navigation, falling back to hard navigation", error);
|
|
28
|
+
window.location.assign(pendingUrl.href);
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
function installAppNavigationFailureListeners() {
|
|
32
|
+
if (!process.env.__NEXT_APP_NAV_FAIL_HANDLING || typeof window === "undefined") return () => {};
|
|
33
|
+
const listener = (event) => {
|
|
34
|
+
handleAppNavigationFailure("reason" in event ? event.reason : event.error);
|
|
35
|
+
};
|
|
36
|
+
window.addEventListener("error", listener);
|
|
37
|
+
window.addEventListener("unhandledrejection", listener);
|
|
38
|
+
return () => {
|
|
39
|
+
window.removeEventListener("error", listener);
|
|
40
|
+
window.removeEventListener("unhandledrejection", listener);
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
//#endregion
|
|
44
|
+
export { clearAppNavigationFailureTarget, getAppNavigationFailureTarget, handleAppNavigationFailure, installAppNavigationFailureListeners, stageAppNavigationFailureTarget };
|
|
@@ -15,12 +15,13 @@ type NavigationRuntimeRscBootstrap = {
|
|
|
15
15
|
};
|
|
16
16
|
type NavigationRuntimeKind = "navigate" | "traverse" | "refresh";
|
|
17
17
|
type NavigationRuntimeHistoryUpdateMode = "push" | "replace";
|
|
18
|
+
type NavigationRuntimeVisibleCommitMode = "transition" | "synchronous";
|
|
18
19
|
type NavigationRuntimeTraversalIntent = {
|
|
19
20
|
direction: "back" | "forward" | "unknown";
|
|
20
21
|
historyState: unknown;
|
|
21
22
|
targetHistoryIndex: number | null;
|
|
22
23
|
};
|
|
23
|
-
type NavigationRuntimeNavigate = (href: string, redirectDepth?: number, navigationKind?: NavigationRuntimeKind, historyUpdateMode?: NavigationRuntimeHistoryUpdateMode, previousNextUrlOverride?: string | null, programmaticTransition?: boolean, traversalIntent?: NavigationRuntimeTraversalIntent, scrollIntent?: AppRouterScrollIntent | null) => Promise<void>;
|
|
24
|
+
type NavigationRuntimeNavigate = (href: string, redirectDepth?: number, navigationKind?: NavigationRuntimeKind, historyUpdateMode?: NavigationRuntimeHistoryUpdateMode, previousNextUrlOverride?: string | null, programmaticTransition?: boolean, traversalIntent?: NavigationRuntimeTraversalIntent, scrollIntent?: AppRouterScrollIntent | null, visibleCommitMode?: NavigationRuntimeVisibleCommitMode) => Promise<void>;
|
|
24
25
|
type NavigationRuntimeFunctions = {
|
|
25
26
|
clearNavigationCaches?: () => void;
|
|
26
27
|
commitHashNavigation?: (href: string, historyUpdateMode: NavigationRuntimeHistoryUpdateMode, scroll: boolean) => void;
|
|
@@ -66,4 +67,4 @@ declare function hasAppNavigationRuntime(): boolean;
|
|
|
66
67
|
*/
|
|
67
68
|
declare function hasAppNavigationRuntimeBootstrap(): boolean;
|
|
68
69
|
//#endregion
|
|
69
|
-
export { NAVIGATION_RUNTIME_KEY, NAVIGATION_RUNTIME_SYMBOL_DESCRIPTION, NavigationRuntime, NavigationRuntimeBootstrap, NavigationRuntimeFunctions, NavigationRuntimeNavigate, NavigationRuntimeRscBootstrap, NavigationRuntimeRscChunk, NavigationRuntimeSnapshot, ensureNavigationRuntimeRscBootstrap, getNavigationRuntime, hasAppNavigationRuntime, hasAppNavigationRuntimeBootstrap, registerNavigationRuntimeBootstrap, registerNavigationRuntimeFunctions, subscribeNavigationRuntimeRscChunk };
|
|
70
|
+
export { NAVIGATION_RUNTIME_KEY, NAVIGATION_RUNTIME_SYMBOL_DESCRIPTION, NavigationRuntime, NavigationRuntimeBootstrap, NavigationRuntimeFunctions, NavigationRuntimeNavigate, NavigationRuntimeRscBootstrap, NavigationRuntimeRscChunk, NavigationRuntimeSnapshot, NavigationRuntimeVisibleCommitMode, ensureNavigationRuntimeRscBootstrap, getNavigationRuntime, hasAppNavigationRuntime, hasAppNavigationRuntimeBootstrap, registerNavigationRuntimeBootstrap, registerNavigationRuntimeFunctions, subscribeNavigationRuntimeRscChunk };
|
|
@@ -3,6 +3,23 @@ import { NEXT_DATA } from "../shims/internal/utils.js";
|
|
|
3
3
|
//#region src/client/vinext-next-data.d.ts
|
|
4
4
|
type VinextLinkPrefetchRoute = {
|
|
5
5
|
canPrefetchLoadingShell: boolean;
|
|
6
|
+
documentOnly?: boolean;
|
|
7
|
+
isDynamic: boolean;
|
|
8
|
+
patternParts: string[];
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Pages Router route pattern exposed to the client so the App Router's
|
|
12
|
+
* navigation runtime can decide whether a soft-navigated URL should be
|
|
13
|
+
* handled by Pages (hard nav) or App (RSC). Mirrors the public shape of
|
|
14
|
+
* `VinextLinkPrefetchRoute` so a single trie matcher handles both.
|
|
15
|
+
*
|
|
16
|
+
* `canPrefetchLoadingShell` is always `false` for Pages routes — Pages
|
|
17
|
+
* does not have a separate loading boundary and its prefetch surface is
|
|
18
|
+
* `_next/data/<buildId>/<page>.json`.
|
|
19
|
+
*/
|
|
20
|
+
type VinextPagesLinkPrefetchRoute = {
|
|
21
|
+
canPrefetchLoadingShell: false;
|
|
22
|
+
documentOnly?: boolean;
|
|
6
23
|
isDynamic: boolean;
|
|
7
24
|
patternParts: string[];
|
|
8
25
|
};
|
|
@@ -24,4 +41,4 @@ declare function extractVinextNextDataJson(html: string): string | null;
|
|
|
24
41
|
declare function parseVinextNextDataJson(json: string): BrowserVinextNextData;
|
|
25
42
|
declare function applyVinextLocaleGlobals(target: VinextLocaleGlobalTarget, nextData: VinextNextData): void;
|
|
26
43
|
//#endregion
|
|
27
|
-
export { VinextLinkPrefetchRoute, VinextNextData, applyVinextLocaleGlobals, extractVinextNextDataJson, parseVinextNextDataJson };
|
|
44
|
+
export { VinextLinkPrefetchRoute, VinextNextData, VinextPagesLinkPrefetchRoute, applyVinextLocaleGlobals, extractVinextNextDataJson, parseVinextNextDataJson };
|
|
@@ -40,10 +40,9 @@
|
|
|
40
40
|
* `window.next.router`. Mirrors the `publicAppRouterInstance` shape from
|
|
41
41
|
* `packages/next/src/client/components/app-router-instance.ts`.
|
|
42
42
|
*
|
|
43
|
-
* `hmrRefresh`
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
* branch, matching what they would do on a production Next.js build.
|
|
43
|
+
* `hmrRefresh` is intentionally omitted — vinext does not implement it.
|
|
44
|
+
* `experimental_gesturePush` is attached only when
|
|
45
|
+
* `experimental.gestureTransition` is enabled, matching Next.js.
|
|
47
46
|
*/
|
|
48
47
|
type AppRouterPublicInstance = {
|
|
49
48
|
push: (href: string, options?: {
|
|
@@ -57,6 +56,9 @@ type AppRouterPublicInstance = {
|
|
|
57
56
|
refresh: () => void;
|
|
58
57
|
prefetch: (href: string, options?: {
|
|
59
58
|
onInvalidate?: () => void;
|
|
59
|
+
}) => void;
|
|
60
|
+
experimental_gesturePush?: (href: string, options?: {
|
|
61
|
+
scroll?: boolean;
|
|
60
62
|
}) => void; /** Default placeholder, matches Next.js. */
|
|
61
63
|
bfcacheId?: string;
|
|
62
64
|
};
|
|
@@ -161,5 +163,6 @@ type WindowNext = {
|
|
|
161
163
|
* resets state.
|
|
162
164
|
*/
|
|
163
165
|
declare function installWindowNext(fields: Partial<WindowNext>): void;
|
|
166
|
+
declare function setWindowNextInternalSourcePage(sourcePage: string | null): void;
|
|
164
167
|
//#endregion
|
|
165
|
-
export { PagesRouterPublicInstance, installWindowNext };
|
|
168
|
+
export { PagesRouterPublicInstance, installWindowNext, setWindowNextInternalSourcePage };
|
|
@@ -42,5 +42,16 @@ function installWindowNext(fields) {
|
|
|
42
42
|
...fields
|
|
43
43
|
};
|
|
44
44
|
}
|
|
45
|
+
function setWindowNextInternalSourcePage(sourcePage) {
|
|
46
|
+
if (typeof window === "undefined") return;
|
|
47
|
+
installWindowNext({});
|
|
48
|
+
if (sourcePage === null) {
|
|
49
|
+
delete window.next?.__internal_src_page;
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const next = window.next;
|
|
53
|
+
if (!next) return;
|
|
54
|
+
next.__internal_src_page = sourcePage;
|
|
55
|
+
}
|
|
45
56
|
//#endregion
|
|
46
|
-
export { installWindowNext };
|
|
57
|
+
export { installWindowNext, setWindowNextInternalSourcePage };
|
|
@@ -73,7 +73,12 @@ var CloudflareCdnCacheAdapter = class {
|
|
|
73
73
|
async set(_key, _data, _ctx) {}
|
|
74
74
|
buildResponseHeaders(input) {
|
|
75
75
|
if (!input.cacheControl) return { "Cache-Control": NO_STORE };
|
|
76
|
-
if (/\b(?:no-store|no-cache|private)\b/.test(input.cacheControl)) return {
|
|
76
|
+
if (/\b(?:no-store|no-cache|private)\b/.test(input.cacheControl)) return {
|
|
77
|
+
"Cache-Control": input.cacheControl,
|
|
78
|
+
"CDN-Cache-Control": null,
|
|
79
|
+
"Cloudflare-CDN-Cache-Control": null,
|
|
80
|
+
"Cache-Tag": null
|
|
81
|
+
};
|
|
77
82
|
const headers = {
|
|
78
83
|
"Cache-Control": BROWSER_REVALIDATE,
|
|
79
84
|
"CDN-Cache-Control": toEdgeCacheControl(input.cacheControl)
|
|
@@ -32,10 +32,10 @@ declare function escapeHeaderSource(source: string): string;
|
|
|
32
32
|
* Callers extract the relevant parts from the incoming Request.
|
|
33
33
|
*/
|
|
34
34
|
type RequestContext = {
|
|
35
|
-
headers: Headers;
|
|
36
|
-
cookies: Record<string, string>;
|
|
37
|
-
query: URLSearchParams;
|
|
38
|
-
host: string;
|
|
35
|
+
readonly headers: Headers;
|
|
36
|
+
readonly cookies: Record<string, string>;
|
|
37
|
+
readonly query: URLSearchParams;
|
|
38
|
+
readonly host: string;
|
|
39
39
|
};
|
|
40
40
|
/**
|
|
41
41
|
* basePath gating state passed alongside the pathname to every matcher.
|
|
@@ -65,6 +65,13 @@ type BasePathMatchState = {
|
|
|
65
65
|
declare function parseCookies(cookieHeader: string | null): Record<string, string>;
|
|
66
66
|
/**
|
|
67
67
|
* Build a RequestContext from a Web Request object.
|
|
68
|
+
*
|
|
69
|
+
* `cookies` and `query` are lazy memoized getters: they are consumed only by
|
|
70
|
+
* `has`/`missing` condition evaluation (`checkHasConditions` /
|
|
71
|
+
* `matchesRuleConditions`), and most apps configure no such conditions. The
|
|
72
|
+
* cookie split and `searchParams` access are therefore deferred until first
|
|
73
|
+
* read and computed at most once. Mirrors `headersContextFromRequest` in
|
|
74
|
+
* `shims/headers.ts`.
|
|
68
75
|
*/
|
|
69
76
|
declare function requestContextFromRequest(request: Request): RequestContext;
|
|
70
77
|
declare function normalizeHost(hostHeader: string | null, fallbackHostname: string): string;
|