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
|
@@ -1,28 +1,93 @@
|
|
|
1
|
+
import { NEXTJS_DEPLOYMENT_ID_HEADER } from "./headers.js";
|
|
1
2
|
import { normalizeStaticPathname } from "../routing/route-pattern.js";
|
|
2
3
|
import { buildCacheStateHeaders } from "./cache-headers.js";
|
|
4
|
+
import { isUnknownRecord } from "../utils/record.js";
|
|
5
|
+
import { applyCdnResponseHeaders } from "./cache-control.js";
|
|
6
|
+
import { decideIsr } from "./isr-decision.js";
|
|
3
7
|
import { buildPagesCacheValue } from "./isr-cache.js";
|
|
4
8
|
import { isSerializableProps } from "./pages-serializable-props.js";
|
|
5
9
|
import { hasPagesGetInitialProps, isResponseSent, loadPagesGetInitialProps } from "./pages-get-initial-props.js";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { buildPagesNextDataScript } from "./pages-page-response.js";
|
|
10
|
+
import { isBotUserAgent } from "../utils/html-limited-bots.js";
|
|
11
|
+
import { buildNextDataPropsJsonResponse } from "./pages-data-route.js";
|
|
12
|
+
import { buildPagesNextDataScript, etagMatches, generatePagesETag, isPagesStreamingBot, requestsNoCache } from "./pages-page-response.js";
|
|
9
13
|
//#region src/server/pages-page-data.ts
|
|
10
|
-
function buildPagesDataNotFoundResponse() {
|
|
14
|
+
function buildPagesDataNotFoundResponse(deploymentId) {
|
|
15
|
+
const headers = { "Content-Type": "application/json" };
|
|
16
|
+
if (deploymentId) headers[NEXTJS_DEPLOYMENT_ID_HEADER] = deploymentId;
|
|
11
17
|
return new Response("{}", {
|
|
12
18
|
status: 404,
|
|
13
|
-
headers
|
|
19
|
+
headers
|
|
14
20
|
});
|
|
15
21
|
}
|
|
16
22
|
function buildPagesNotFoundResult(options) {
|
|
17
23
|
if (options.isDataReq) return {
|
|
18
24
|
kind: "response",
|
|
19
|
-
response: buildPagesDataNotFoundResponse()
|
|
25
|
+
response: buildPagesDataNotFoundResponse(options.deploymentId)
|
|
20
26
|
};
|
|
21
27
|
return { kind: "notFound" };
|
|
22
28
|
}
|
|
23
29
|
function resolvePagesRedirectStatus(redirect) {
|
|
24
30
|
return redirect.statusCode != null ? redirect.statusCode : redirect.permanent ? 308 : 307;
|
|
25
31
|
}
|
|
32
|
+
function normalizePagesRenderProps(props) {
|
|
33
|
+
return {
|
|
34
|
+
...props,
|
|
35
|
+
pageProps: props.pageProps
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Load `_app.getInitialProps` and return the normalized render props and the
|
|
40
|
+
* extracted `pageProps`. This is shared between the foreground render path and
|
|
41
|
+
* the stale-while-revalidate background regeneration path so both produce the
|
|
42
|
+
* same full props envelope (app-level props plus the page's `pageProps`).
|
|
43
|
+
*
|
|
44
|
+
* `getSharedReqRes` lets callers share the same mock req/res with other
|
|
45
|
+
* data-fetching steps (e.g. `getServerSideProps`) when they run in the same
|
|
46
|
+
* request context.
|
|
47
|
+
*/
|
|
48
|
+
async function loadPagesAppInitialRenderProps(options, getSharedReqRes) {
|
|
49
|
+
let pageProps = {};
|
|
50
|
+
let renderProps = { pageProps };
|
|
51
|
+
if (!hasPagesGetInitialProps(options.AppComponent)) return {
|
|
52
|
+
kind: "props",
|
|
53
|
+
pageProps,
|
|
54
|
+
renderProps
|
|
55
|
+
};
|
|
56
|
+
const { req, res, responsePromise } = getSharedReqRes();
|
|
57
|
+
const initialProps = await loadPagesGetInitialProps(options.AppComponent, {
|
|
58
|
+
AppTree: options.createAppTree ?? options.createPageElement,
|
|
59
|
+
Component: options.pageModule.default,
|
|
60
|
+
router: {
|
|
61
|
+
pathname: options.routePattern,
|
|
62
|
+
query: options.query,
|
|
63
|
+
asPath: options.asPath ?? options.routeUrl
|
|
64
|
+
},
|
|
65
|
+
ctx: {
|
|
66
|
+
req,
|
|
67
|
+
res,
|
|
68
|
+
err: options.err,
|
|
69
|
+
pathname: options.routePattern,
|
|
70
|
+
query: options.query,
|
|
71
|
+
asPath: options.asPath ?? options.routeUrl,
|
|
72
|
+
locale: options.i18n.locale,
|
|
73
|
+
locales: options.i18n.locales,
|
|
74
|
+
defaultLocale: options.i18n.defaultLocale
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
if (isResponseSent(res)) return {
|
|
78
|
+
kind: "response",
|
|
79
|
+
response: responsePromise
|
|
80
|
+
};
|
|
81
|
+
if (initialProps) {
|
|
82
|
+
renderProps = normalizePagesRenderProps(initialProps);
|
|
83
|
+
pageProps = isUnknownRecord(renderProps.pageProps) ? renderProps.pageProps : {};
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
kind: "props",
|
|
87
|
+
pageProps,
|
|
88
|
+
renderProps
|
|
89
|
+
};
|
|
90
|
+
}
|
|
26
91
|
/**
|
|
27
92
|
* Build the response for a `getServerSideProps` / `getStaticProps`
|
|
28
93
|
* `{ redirect }` result.
|
|
@@ -44,12 +109,20 @@ function resolvePagesRedirectStatus(redirect) {
|
|
|
44
109
|
* redirects (search `__N_REDIRECT`), consumed in
|
|
45
110
|
* `packages/next/src/shared/lib/router/router.ts` (`pageProps.__N_REDIRECT`).
|
|
46
111
|
*/
|
|
47
|
-
function buildPagesRedirectResponse(redirect, options) {
|
|
112
|
+
function buildPagesRedirectResponse(redirect, options, props = { pageProps: {} }) {
|
|
48
113
|
const destination = options.sanitizeDestination(redirect.destination);
|
|
49
|
-
if (options.isDataReq)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
114
|
+
if (options.isDataReq) {
|
|
115
|
+
const init = { headers: {} };
|
|
116
|
+
if (options.deploymentId) init.headers[NEXTJS_DEPLOYMENT_ID_HEADER] = options.deploymentId;
|
|
117
|
+
return buildNextDataPropsJsonResponse({
|
|
118
|
+
...props,
|
|
119
|
+
pageProps: {
|
|
120
|
+
...isUnknownRecord(props.pageProps) ? props.pageProps : {},
|
|
121
|
+
__N_REDIRECT: destination,
|
|
122
|
+
__N_REDIRECT_STATUS: resolvePagesRedirectStatus(redirect)
|
|
123
|
+
}
|
|
124
|
+
}, options.safeJsonStringify, init);
|
|
125
|
+
}
|
|
53
126
|
return new Response(null, {
|
|
54
127
|
status: resolvePagesRedirectStatus(redirect),
|
|
55
128
|
headers: { Location: destination }
|
|
@@ -81,19 +154,47 @@ function matchesPagesStaticPath(pathEntry, params, routeUrl) {
|
|
|
81
154
|
});
|
|
82
155
|
}
|
|
83
156
|
function buildPagesCacheResponse(html, cacheState, fontLinkHeader, revalidateSeconds, expireSeconds, cacheControl, status) {
|
|
84
|
-
const
|
|
85
|
-
|
|
157
|
+
const { cacheControl: cacheControlHeader } = decideIsr({
|
|
158
|
+
cacheState,
|
|
159
|
+
kind: "pages",
|
|
160
|
+
revalidateSeconds: revalidateSeconds ?? 60,
|
|
161
|
+
expireSeconds,
|
|
162
|
+
cacheControlMeta: cacheControl
|
|
163
|
+
});
|
|
86
164
|
const headers = new Headers({
|
|
87
165
|
"Content-Type": "text/html",
|
|
88
166
|
...buildCacheStateHeaders(cacheState)
|
|
89
167
|
});
|
|
90
|
-
applyCdnResponseHeaders(headers, { cacheControl:
|
|
168
|
+
applyCdnResponseHeaders(headers, { cacheControl: cacheControlHeader });
|
|
91
169
|
if (fontLinkHeader) headers.set("Link", fontLinkHeader);
|
|
92
170
|
return new Response(html, {
|
|
93
171
|
status: status ?? 200,
|
|
94
172
|
headers
|
|
95
173
|
});
|
|
96
174
|
}
|
|
175
|
+
/**
|
|
176
|
+
* For bot / crawler UAs, attach an ETag to a cached ISR response (HIT or
|
|
177
|
+
* STALE) so it is consistent with the fresh-MISS path, then check for a
|
|
178
|
+
* matching `If-None-Match`. When the check passes — and the request did NOT
|
|
179
|
+
* carry `Cache-Control: no-cache` — returns a 304 response; otherwise returns
|
|
180
|
+
* `null` so the caller can return the full response.
|
|
181
|
+
*
|
|
182
|
+
* Extracted to avoid duplicating the same three-line block across the HIT and
|
|
183
|
+
* STALE branches.
|
|
184
|
+
*/
|
|
185
|
+
function applyBotETagAndCheck(cachedResponse, html, options) {
|
|
186
|
+
if (!options.userAgent || !isPagesStreamingBot(options.userAgent)) return null;
|
|
187
|
+
const etag = generatePagesETag(html);
|
|
188
|
+
cachedResponse.headers.set("ETag", etag);
|
|
189
|
+
if (!requestsNoCache(options.requestCacheControl) && options.ifNoneMatch && etagMatches(etag, options.ifNoneMatch)) return {
|
|
190
|
+
kind: "response",
|
|
191
|
+
response: new Response(null, {
|
|
192
|
+
status: 304,
|
|
193
|
+
headers: cachedResponse.headers
|
|
194
|
+
})
|
|
195
|
+
};
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
97
198
|
function rewritePagesCachedHtml(cachedHtml, freshBody, nextDataScript) {
|
|
98
199
|
const bodyStart = cachedHtml.indexOf("<div id=\"__next\">");
|
|
99
200
|
const contentStart = bodyStart >= 0 ? bodyStart + 17 : -1;
|
|
@@ -109,11 +210,13 @@ function rewritePagesCachedHtml(cachedHtml, freshBody, nextDataScript) {
|
|
|
109
210
|
return "<!DOCTYPE html>\n<html>\n<head>\n</head>\n<body>\n <div id=\"__next\">" + freshBody + "</div>\n " + nextDataScript + "\n</body>\n</html>";
|
|
110
211
|
}
|
|
111
212
|
async function renderPagesIsrHtml(options) {
|
|
112
|
-
const
|
|
213
|
+
const renderProps = options.props ?? { pageProps: options.pageProps };
|
|
214
|
+
const freshBody = await options.renderIsrPassToStringAsync(options.createPageElement(renderProps));
|
|
113
215
|
const nextDataScript = buildPagesNextDataScript({
|
|
114
216
|
buildId: options.buildId,
|
|
115
217
|
i18n: options.i18n,
|
|
116
218
|
pageProps: options.pageProps,
|
|
219
|
+
props: renderProps,
|
|
117
220
|
params: options.params,
|
|
118
221
|
routePattern: options.routePattern,
|
|
119
222
|
safeJsonStringify: options.safeJsonStringify,
|
|
@@ -125,6 +228,7 @@ async function renderPagesIsrHtml(options) {
|
|
|
125
228
|
async function resolvePagesPageData(options) {
|
|
126
229
|
const userFacingParams = options.route.isDynamic ? options.params : null;
|
|
127
230
|
let isFallback = false;
|
|
231
|
+
let shouldPersistFallbackData = false;
|
|
128
232
|
if (typeof options.pageModule.getStaticPaths === "function" && options.route.isDynamic) {
|
|
129
233
|
const pathsResult = await options.pageModule.getStaticPaths({
|
|
130
234
|
locales: options.i18n.locales ?? [],
|
|
@@ -133,25 +237,62 @@ async function resolvePagesPageData(options) {
|
|
|
133
237
|
const fallback = pathsResult?.fallback ?? false;
|
|
134
238
|
const isValidPath = (pathsResult?.paths ?? []).some((pathEntry) => matchesPagesStaticPath(pathEntry, options.params, options.routeUrl));
|
|
135
239
|
if (fallback === false && !isValidPath) return buildPagesNotFoundResult(options);
|
|
136
|
-
|
|
240
|
+
const isBotRequest = !!options.userAgent && isBotUserAgent(options.userAgent, options.htmlLimitedBots);
|
|
241
|
+
if (fallback === true && !isValidPath && !options.isDataReq && !isBotRequest) isFallback = true;
|
|
242
|
+
shouldPersistFallbackData = fallback === true && !isValidPath && options.isDataReq === true;
|
|
137
243
|
}
|
|
138
244
|
let pageProps = {};
|
|
139
245
|
let gsspRes = null;
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
246
|
+
let sharedReqRes = null;
|
|
247
|
+
function getSharedReqRes() {
|
|
248
|
+
sharedReqRes ??= options.createGsspReqRes();
|
|
249
|
+
return sharedReqRes;
|
|
250
|
+
}
|
|
251
|
+
let renderProps = { pageProps };
|
|
252
|
+
async function loadForegroundAppInitialRenderProps() {
|
|
253
|
+
const result = await loadPagesAppInitialRenderProps(options, getSharedReqRes);
|
|
254
|
+
if (result.kind === "response") return {
|
|
255
|
+
kind: "response",
|
|
256
|
+
response: await result.response
|
|
257
|
+
};
|
|
258
|
+
renderProps = result.renderProps;
|
|
259
|
+
pageProps = result.pageProps;
|
|
260
|
+
return null;
|
|
261
|
+
}
|
|
262
|
+
if (isFallback) {
|
|
263
|
+
const pathname = options.routeUrl.split("?")[0];
|
|
264
|
+
if ((await options.isrGet(options.isrCacheKey("pages", pathname)))?.value.value?.kind !== "PAGES") {
|
|
265
|
+
const appShortCircuit = await loadForegroundAppInitialRenderProps();
|
|
266
|
+
if (appShortCircuit) return appShortCircuit;
|
|
267
|
+
pageProps = {};
|
|
268
|
+
renderProps = {
|
|
269
|
+
...renderProps,
|
|
270
|
+
pageProps
|
|
271
|
+
};
|
|
272
|
+
return {
|
|
273
|
+
kind: "render",
|
|
274
|
+
gsspRes: null,
|
|
275
|
+
isrRevalidateSeconds: null,
|
|
276
|
+
pageProps,
|
|
277
|
+
props: renderProps,
|
|
278
|
+
isFallback: true
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
}
|
|
147
282
|
if (typeof options.pageModule.getServerSideProps === "function") {
|
|
148
|
-
const
|
|
283
|
+
const shortCircuit = await loadForegroundAppInitialRenderProps();
|
|
284
|
+
if (shortCircuit) return shortCircuit;
|
|
285
|
+
renderProps = {
|
|
286
|
+
...renderProps,
|
|
287
|
+
__N_SSP: true
|
|
288
|
+
};
|
|
289
|
+
const { req, res, responsePromise } = getSharedReqRes();
|
|
149
290
|
const result = await options.pageModule.getServerSideProps({
|
|
150
291
|
params: userFacingParams,
|
|
151
292
|
req,
|
|
152
293
|
res,
|
|
153
294
|
query: options.query,
|
|
154
|
-
resolvedUrl: options.routeUrl,
|
|
295
|
+
resolvedUrl: options.resolvedUrl ?? options.routeUrl,
|
|
155
296
|
locale: options.i18n.locale,
|
|
156
297
|
locales: options.i18n.locales,
|
|
157
298
|
defaultLocale: options.i18n.defaultLocale
|
|
@@ -160,10 +301,19 @@ async function resolvePagesPageData(options) {
|
|
|
160
301
|
kind: "response",
|
|
161
302
|
response: await responsePromise
|
|
162
303
|
};
|
|
163
|
-
if (result?.props)
|
|
304
|
+
if (result?.props) {
|
|
305
|
+
pageProps = {
|
|
306
|
+
...pageProps,
|
|
307
|
+
...await Promise.resolve(result.props)
|
|
308
|
+
};
|
|
309
|
+
renderProps = {
|
|
310
|
+
...renderProps,
|
|
311
|
+
pageProps
|
|
312
|
+
};
|
|
313
|
+
}
|
|
164
314
|
if (result?.redirect) return {
|
|
165
315
|
kind: "response",
|
|
166
|
-
response: buildPagesRedirectResponse(result.redirect, options)
|
|
316
|
+
response: buildPagesRedirectResponse(result.redirect, options, renderProps)
|
|
167
317
|
};
|
|
168
318
|
if (result?.notFound) return buildPagesNotFoundResult(options);
|
|
169
319
|
if (result?.props !== void 0) isSerializableProps(options.routePattern, "getServerSideProps", pageProps);
|
|
@@ -175,13 +325,23 @@ async function resolvePagesPageData(options) {
|
|
|
175
325
|
const cacheKey = options.isrCacheKey("pages", pathname);
|
|
176
326
|
const cached = await options.isrGet(cacheKey);
|
|
177
327
|
const cachedValue = cached?.value.value;
|
|
178
|
-
if (!options.isOnDemandRevalidate && cachedValue?.kind === "PAGES" && cached && !cached.isStale && !options.scriptNonce && !options.isDataReq)
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
328
|
+
if (!options.isOnDemandRevalidate && cached?.isStale === false && cachedValue?.kind === "PAGES" && !cachedValue.generatedFromDataRequest && cached && !cached.isStale && !options.scriptNonce && !options.isDataReq) {
|
|
329
|
+
const hitResponse = buildPagesCacheResponse(cachedValue.html, "HIT", options.fontLinkHeader, void 0, options.expireSeconds, cached.value.cacheControl, cachedValue.status);
|
|
330
|
+
const hitBotResult = applyBotETagAndCheck(hitResponse, cachedValue.html, options);
|
|
331
|
+
if (hitBotResult) return hitBotResult;
|
|
332
|
+
return {
|
|
333
|
+
kind: "response",
|
|
334
|
+
response: hitResponse
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
if (!options.isOnDemandRevalidate && cachedValue?.kind === "PAGES" && !cachedValue.generatedFromDataRequest && cached && cached.isStale && !options.scriptNonce && !options.isDataReq) {
|
|
183
338
|
options.triggerBackgroundRegeneration(cacheKey, async function() {
|
|
184
339
|
return options.runInFreshUnifiedContext(async () => {
|
|
340
|
+
options.applyRequestContexts();
|
|
341
|
+
const freshAppResult = await loadPagesAppInitialRenderProps(options, () => options.createGsspReqRes());
|
|
342
|
+
if (freshAppResult.kind === "response") return;
|
|
343
|
+
let freshPageProps = freshAppResult.pageProps;
|
|
344
|
+
let freshRenderProps = freshAppResult.renderProps;
|
|
185
345
|
const freshResult = await options.pageModule.getStaticProps?.({
|
|
186
346
|
params: userFacingParams,
|
|
187
347
|
locale: options.i18n.locale,
|
|
@@ -189,14 +349,25 @@ async function resolvePagesPageData(options) {
|
|
|
189
349
|
defaultLocale: options.i18n.defaultLocale,
|
|
190
350
|
revalidateReason: "stale"
|
|
191
351
|
});
|
|
192
|
-
if (freshResult?.props
|
|
193
|
-
|
|
352
|
+
if (freshResult?.props) {
|
|
353
|
+
freshPageProps = {
|
|
354
|
+
...freshPageProps,
|
|
355
|
+
...freshResult.props
|
|
356
|
+
};
|
|
357
|
+
freshRenderProps = {
|
|
358
|
+
...freshRenderProps,
|
|
359
|
+
pageProps: freshPageProps
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
const freshRevalidateSeconds = typeof freshResult?.revalidate === "number" && freshResult.revalidate > 0 ? freshResult.revalidate : cached.value.cacheControl?.revalidate;
|
|
363
|
+
if (freshResult?.props && freshRevalidateSeconds && freshRevalidateSeconds > 0) {
|
|
194
364
|
const freshHtml = await renderPagesIsrHtml({
|
|
195
365
|
buildId: options.buildId,
|
|
196
366
|
cachedHtml: cachedValue.html,
|
|
197
367
|
createPageElement: options.createPageElement,
|
|
198
368
|
i18n: options.i18n,
|
|
199
|
-
pageProps:
|
|
369
|
+
pageProps: freshPageProps,
|
|
370
|
+
props: freshRenderProps,
|
|
200
371
|
params: options.params,
|
|
201
372
|
renderIsrPassToStringAsync: options.renderIsrPassToStringAsync,
|
|
202
373
|
routePattern: options.routePattern,
|
|
@@ -204,7 +375,7 @@ async function resolvePagesPageData(options) {
|
|
|
204
375
|
nextData: options.nextData,
|
|
205
376
|
vinext: options.vinext
|
|
206
377
|
});
|
|
207
|
-
await options.isrSet(cacheKey, buildPagesCacheValue(freshHtml,
|
|
378
|
+
await options.isrSet(cacheKey, buildPagesCacheValue(freshHtml, freshRenderProps, options.statusCode), freshRevalidateSeconds, void 0, options.expireSeconds);
|
|
208
379
|
}
|
|
209
380
|
});
|
|
210
381
|
}, {
|
|
@@ -212,29 +383,66 @@ async function resolvePagesPageData(options) {
|
|
|
212
383
|
routePath: options.routePattern,
|
|
213
384
|
routeType: "render"
|
|
214
385
|
});
|
|
386
|
+
const staleResponse = buildPagesCacheResponse(cachedValue.html, "STALE", options.fontLinkHeader, void 0, options.expireSeconds, cached.value.cacheControl, cachedValue.status);
|
|
387
|
+
const staleBotResult = applyBotETagAndCheck(staleResponse, cachedValue.html, options);
|
|
388
|
+
if (staleBotResult) return staleBotResult;
|
|
215
389
|
return {
|
|
216
390
|
kind: "response",
|
|
217
|
-
response:
|
|
391
|
+
response: staleResponse
|
|
218
392
|
};
|
|
219
393
|
}
|
|
220
|
-
const
|
|
394
|
+
const generatedPageData = !options.isOnDemandRevalidate && cached?.isStale === false && cachedValue?.kind === "PAGES" && cachedValue.generatedFromDataRequest && isUnknownRecord(cachedValue.pageData) ? cachedValue.pageData : null;
|
|
395
|
+
if (!generatedPageData) {
|
|
396
|
+
const shortCircuit = await loadForegroundAppInitialRenderProps();
|
|
397
|
+
if (shortCircuit) return shortCircuit;
|
|
398
|
+
}
|
|
399
|
+
const result = generatedPageData ? null : await options.pageModule.getStaticProps({
|
|
221
400
|
params: userFacingParams,
|
|
222
401
|
locale: options.i18n.locale,
|
|
223
402
|
locales: options.i18n.locales,
|
|
224
403
|
defaultLocale: options.i18n.defaultLocale,
|
|
225
404
|
revalidateReason: options.isOnDemandRevalidate ? "on-demand" : options.isBuildTimePrerendering ? "build" : "stale"
|
|
226
405
|
});
|
|
227
|
-
if (
|
|
406
|
+
if (generatedPageData) {
|
|
407
|
+
renderProps = generatedPageData;
|
|
408
|
+
pageProps = isUnknownRecord(renderProps.pageProps) ? renderProps.pageProps : {};
|
|
409
|
+
}
|
|
410
|
+
if (result?.props) {
|
|
411
|
+
pageProps = {
|
|
412
|
+
...pageProps,
|
|
413
|
+
...result.props
|
|
414
|
+
};
|
|
415
|
+
renderProps = {
|
|
416
|
+
...renderProps,
|
|
417
|
+
pageProps
|
|
418
|
+
};
|
|
419
|
+
}
|
|
228
420
|
if (result?.redirect) return {
|
|
229
421
|
kind: "response",
|
|
230
|
-
response: buildPagesRedirectResponse(result.redirect, options)
|
|
422
|
+
response: buildPagesRedirectResponse(result.redirect, options, renderProps)
|
|
231
423
|
};
|
|
232
424
|
if (result?.notFound) return buildPagesNotFoundResult(options);
|
|
233
425
|
if (result?.props !== void 0) isSerializableProps(options.routePattern, "getStaticProps", pageProps);
|
|
234
426
|
if (typeof result?.revalidate === "number" && result.revalidate > 0) isrRevalidateSeconds = result.revalidate;
|
|
427
|
+
else if (cachedValue?.kind === "PAGES" && cachedValue.generatedFromDataRequest) isrRevalidateSeconds = cached?.value.cacheControl?.revalidate ?? 31536e3;
|
|
428
|
+
if (shouldPersistFallbackData) {
|
|
429
|
+
const revalidateSeconds = isrRevalidateSeconds ?? 31536e3;
|
|
430
|
+
await options.isrSet(cacheKey, {
|
|
431
|
+
kind: "PAGES",
|
|
432
|
+
html: "",
|
|
433
|
+
pageData: renderProps,
|
|
434
|
+
generatedFromDataRequest: true,
|
|
435
|
+
headers: void 0,
|
|
436
|
+
status: void 0
|
|
437
|
+
}, revalidateSeconds, void 0, options.expireSeconds);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
if (typeof options.pageModule.getServerSideProps !== "function" && typeof options.pageModule.getStaticProps !== "function" && hasPagesGetInitialProps(options.AppComponent)) {
|
|
441
|
+
const shortCircuit = await loadForegroundAppInitialRenderProps();
|
|
442
|
+
if (shortCircuit) return shortCircuit;
|
|
235
443
|
}
|
|
236
|
-
if (typeof options.pageModule.getServerSideProps !== "function" && typeof options.pageModule.getStaticProps !== "function" && hasPagesGetInitialProps(options.pageModule.default)) {
|
|
237
|
-
const { req, res, responsePromise } =
|
|
444
|
+
if (typeof options.pageModule.getServerSideProps !== "function" && typeof options.pageModule.getStaticProps !== "function" && !hasPagesGetInitialProps(options.AppComponent) && hasPagesGetInitialProps(options.pageModule.default)) {
|
|
445
|
+
const { req, res, responsePromise } = getSharedReqRes();
|
|
238
446
|
const initialProps = await loadPagesGetInitialProps(options.pageModule.default, {
|
|
239
447
|
req,
|
|
240
448
|
res,
|
|
@@ -250,16 +458,23 @@ async function resolvePagesPageData(options) {
|
|
|
250
458
|
kind: "response",
|
|
251
459
|
response: await responsePromise
|
|
252
460
|
};
|
|
253
|
-
if (initialProps)
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
461
|
+
if (initialProps) {
|
|
462
|
+
pageProps = {
|
|
463
|
+
...pageProps,
|
|
464
|
+
...initialProps
|
|
465
|
+
};
|
|
466
|
+
renderProps = {
|
|
467
|
+
...renderProps,
|
|
468
|
+
pageProps
|
|
469
|
+
};
|
|
470
|
+
}
|
|
257
471
|
}
|
|
258
472
|
return {
|
|
259
473
|
kind: "render",
|
|
260
474
|
gsspRes,
|
|
261
475
|
isrRevalidateSeconds,
|
|
262
476
|
pageProps,
|
|
477
|
+
props: renderProps,
|
|
263
478
|
isFallback: false
|
|
264
479
|
};
|
|
265
480
|
}
|
|
@@ -28,8 +28,10 @@ type I18nConfig = {
|
|
|
28
28
|
} | null;
|
|
29
29
|
type VinextConfigSubset = {
|
|
30
30
|
basePath: string;
|
|
31
|
+
assetPrefix: string;
|
|
31
32
|
trailingSlash: boolean;
|
|
32
33
|
expireTime?: number;
|
|
34
|
+
htmlLimitedBots?: string;
|
|
33
35
|
clientTraceMetadata?: readonly string[];
|
|
34
36
|
disableOptimizedLoading: boolean;
|
|
35
37
|
};
|
|
@@ -72,8 +74,8 @@ type CreatePagesPageHandlerOptions = {
|
|
|
72
74
|
renderIsrPassToStringAsync: (element: ReactNode) => Promise<string>; /** `safeJsonStringify` from `vinext/html`. */
|
|
73
75
|
safeJsonStringify: (value: unknown) => string; /** `sanitizeDestination` from the config-matchers module. */
|
|
74
76
|
sanitizeDestination: (dest: string) => string; /** Build the React page element for a given set of page props. */
|
|
75
|
-
createPageElement: (PageComponent: ComponentType, AppComponent: ComponentType | null,
|
|
76
|
-
enhancePageElement: (PageComponent: ComponentType, AppComponent: ComponentType | null,
|
|
77
|
+
createPageElement: (PageComponent: ComponentType, AppComponent: ComponentType | null, props: Record<string, unknown>) => ReactNode; /** Build the element with optional App/Component enhancers (for _document). */
|
|
78
|
+
enhancePageElement: (PageComponent: ComponentType, AppComponent: ComponentType | null, props: Record<string, unknown>, opts: RenderPageEnhancers) => ReactNode; /** The `_app` page component (or null). */
|
|
77
79
|
AppComponent: ComponentType | null; /** The `_document` page component (or null). */
|
|
78
80
|
DocumentComponent: ComponentType | null;
|
|
79
81
|
};
|
|
@@ -81,6 +83,7 @@ type RenderPageOptions = {
|
|
|
81
83
|
isDataReq?: boolean;
|
|
82
84
|
statusCode?: number;
|
|
83
85
|
asPath?: string;
|
|
86
|
+
originalUrl?: string;
|
|
84
87
|
renderErrorPageOnMiss?: boolean;
|
|
85
88
|
__isInternalErrorRender?: boolean;
|
|
86
89
|
__forcedRoute?: PageRoute;
|