vinext 1.0.0 → 1.0.1
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/THIRD_PARTY_LICENSES.md +26 -0
- package/dist/build/lifecycle.js +10 -10
- package/dist/build/pages-client-assets-module.js +6 -1
- package/dist/build/precompress.js +1 -1
- package/dist/build/prerender-paths.js +3 -7
- package/dist/build/prerender.d.ts +8 -1
- package/dist/build/prerender.js +134 -38
- package/dist/build/run-prerender.js +4 -3
- package/dist/build/server-entry.d.ts +2 -0
- package/dist/build/server-entry.js +7 -1
- package/dist/client/browser-globals.d.ts +4 -0
- package/dist/client/browser-globals.js +5 -0
- package/dist/client/navigation-runtime.d.ts +0 -1
- package/dist/client/navigation-runtime.js +2 -2
- package/dist/config/dotenv.js +14 -3
- package/dist/entries/app-rsc-entry.js +3 -2
- package/dist/index.js +142 -71
- package/dist/init-cloudflare.d.ts +1 -1
- package/dist/init-cloudflare.js +6 -6
- package/dist/init-platform.js +1 -1
- package/dist/init.js +4 -2
- package/dist/plugins/commonjs-syntax.d.ts +16 -0
- package/dist/plugins/commonjs-syntax.js +22 -0
- package/dist/plugins/ignore-dynamic-requests.d.ts +11 -0
- package/dist/plugins/ignore-dynamic-requests.js +54 -3
- package/dist/plugins/import-meta-url.js +6 -6
- package/dist/plugins/og-asset-ownership.d.ts +2 -0
- package/dist/plugins/og-asset-ownership.js +24 -13
- package/dist/plugins/og-assets.d.ts +18 -0
- package/dist/plugins/og-assets.js +50 -8
- package/dist/plugins/og-harfbuzz.js +38 -27
- package/dist/plugins/optimize-imports.js +2 -1
- package/dist/plugins/require-context.d.ts +1 -0
- package/dist/plugins/require-context.js +28 -1
- package/dist/plugins/scan-build-css.d.ts +12 -0
- package/dist/plugins/scan-build-css.js +39 -0
- package/dist/plugins/strip-server-exports.d.ts +2 -0
- package/dist/plugins/strip-server-exports.js +3 -1
- package/dist/plugins/transform-result.d.ts +18 -0
- package/dist/plugins/transform-result.js +23 -2
- package/dist/plugins/typeof-window.d.ts +10 -0
- package/dist/plugins/typeof-window.js +33 -9
- package/dist/routing/app-route-graph.d.ts +0 -1
- package/dist/routing/app-route-graph.js +2 -4
- package/dist/routing/app-route-ids.d.ts +3 -0
- package/dist/routing/app-route-ids.js +6 -0
- package/dist/server/app-bfcache-id.d.ts +1 -0
- package/dist/server/app-bfcache-id.js +7 -1
- package/dist/server/app-bfcache-identity.js +1 -2
- package/dist/server/app-browser-entry.js +4 -2
- package/dist/server/app-browser-hydration.d.ts +1 -1
- package/dist/server/app-browser-hydration.js +2 -2
- package/dist/server/app-browser-navigation-controller.js +1 -1
- package/dist/server/app-browser-state.js +1 -1
- package/dist/server/app-browser-stream.d.ts +1 -1
- package/dist/server/app-history-state.d.ts +0 -1
- package/dist/server/app-history-state.js +2 -5
- package/dist/server/app-page-cache-render.js +2 -1
- package/dist/server/app-page-render.js +2 -1
- package/dist/server/app-page-search-params-observation.js +1 -1
- package/dist/server/app-page-stream.js +1 -1
- package/dist/server/app-page-tracing.js +2 -1
- package/dist/server/app-pages-bridge.js +3 -2
- package/dist/server/app-render-abort-error.d.ts +3 -0
- package/dist/server/app-render-abort-error.js +8 -0
- package/dist/server/app-request-stage-independent-entry.js +4 -7
- package/dist/server/app-route-handler-cache.d.ts +2 -1
- package/dist/server/app-route-handler-cache.js +11 -7
- package/dist/server/app-route-handler-dispatch.js +10 -3
- package/dist/server/app-route-handler-execution.d.ts +9 -1
- package/dist/server/app-route-handler-execution.js +28 -13
- package/dist/server/app-route-handler-policy.js +2 -2
- package/dist/server/app-route-handler-response.d.ts +1 -1
- package/dist/server/app-route-handler-response.js +14 -5
- package/dist/server/app-router-entry.d.ts +2 -1
- package/dist/server/app-router-entry.js +5 -9
- package/dist/server/app-rsc-errors.d.ts +0 -1
- package/dist/server/app-rsc-errors.js +2 -6
- package/dist/server/app-rsc-handler.d.ts +1 -0
- package/dist/server/app-rsc-handler.js +18 -7
- package/dist/server/app-rsc-request-normalization.d.ts +1 -1
- package/dist/server/app-rsc-request-normalization.js +3 -2
- package/dist/server/app-rsc-response-finalizer.js +4 -1
- package/dist/server/app-rsc-route-matching.js +1 -1
- package/dist/server/app-server-action-execution.d.ts +2 -1
- package/dist/server/app-ssr-entry.js +3 -3
- package/dist/server/app-ssr-search-params-gate.js +1 -1
- package/dist/server/app-ssr-stream.js +1 -1
- package/dist/server/cache-control.js +3 -11
- package/dist/server/cacheability-request.js +49 -49
- package/dist/server/config-headers.js +1 -1
- package/dist/server/dev-server.js +11 -3
- package/dist/server/headers.d.ts +2 -0
- package/dist/server/headers.js +5 -1
- package/dist/server/http-error-responses.js +1 -0
- package/dist/server/isr-cache.d.ts +2 -0
- package/dist/server/isr-cache.js +6 -1
- package/dist/server/metadata-route-response.js +94 -37
- package/dist/server/pages-api-route.js +8 -2
- package/dist/server/pages-asset-tags.d.ts +1 -0
- package/dist/server/pages-asset-tags.js +73 -22
- package/dist/server/pages-client-assets.d.ts +2 -0
- package/dist/server/pages-page-data.d.ts +6 -1
- package/dist/server/pages-page-data.js +71 -65
- package/dist/server/pages-page-handler.js +29 -11
- package/dist/server/pages-page-response.js +3 -1
- package/dist/server/pages-request-pipeline.d.ts +2 -1
- package/dist/server/pages-request-pipeline.js +20 -5
- package/dist/server/pages-request-stage-entry.js +6 -4
- package/dist/server/prerender-manifest.d.ts +6 -0
- package/dist/server/prerender-manifest.js +1 -1
- package/dist/server/prod-server.js +3 -13
- package/dist/server/response-stage-cacheability.js +1 -1
- package/dist/server/worker-revalidation-context.d.ts +2 -1
- package/dist/server/worker-revalidation-context.js +1 -0
- package/dist/server/workers-tracing.d.ts +17 -0
- package/dist/server/workers-tracing.js +48 -8
- package/dist/shims/cache-request-state.d.ts +3 -14
- package/dist/shims/cache-request-state.js +2 -13
- package/dist/shims/cache-runtime.js +4 -2
- package/dist/shims/cache.d.ts +2 -1
- package/dist/shims/cache.js +4 -2
- package/dist/shims/cacheability-classification.d.ts +1 -1
- package/dist/shims/cacheability-classification.js +2 -2
- package/dist/shims/cdn-cache.d.ts +10 -1
- package/dist/shims/cdn-cache.js +16 -9
- package/dist/shims/error.d.ts +4 -18
- package/dist/shims/error.js +17 -10
- package/dist/shims/error.react-server.d.ts +4 -6
- package/dist/shims/error.react-server.js +4 -1
- package/dist/shims/fetch-cache.js +4 -3
- package/dist/shims/headers.d.ts +6 -69
- package/dist/shims/headers.js +37 -181
- package/dist/shims/internal/cache-context-accessor.d.ts +16 -0
- package/dist/shims/internal/cache-context-accessor.js +15 -0
- package/dist/shims/internal/headers-state.d.ts +74 -0
- package/dist/shims/internal/headers-state.js +157 -0
- package/dist/shims/navigation.js +2 -2
- package/dist/shims/request-state-types.d.ts +2 -1
- package/dist/shims/root-params.js +1 -1
- package/dist/shims/server.js +52 -2
- package/dist/shims/unified-request-context.d.ts +1 -1
- package/dist/utils/encode-cache-tag.d.ts +1 -0
- package/dist/utils/encode-cache-tag.js +11 -1
- package/dist/utils/vite-cli-invocation.js +8 -1
- package/package.json +6 -2
- package/dist/server/metadata-route-cache-policy.d.ts +0 -5
- package/dist/server/metadata-route-cache-policy.js +0 -6
|
@@ -2,9 +2,11 @@ import { PRERENDER_REVALIDATE_HEADER } from "../utils/protocol-headers.js";
|
|
|
2
2
|
import { requestContextFromRequest } from "../config/request-context.js";
|
|
3
3
|
import { isExternalUrl } from "../utils/external-url.js";
|
|
4
4
|
import { applyMiddlewareRequestHeaders, matchRedirect, matchRewrite, preserveRedirectDestinationQuery, proxyExternalRequest, sanitizeDestination } from "../config/config-matchers.js";
|
|
5
|
+
import { assetPrefixPathname, isNextStaticPath } from "../utils/asset-prefix.js";
|
|
5
6
|
import { addBasePathToPathname, hasBasePath } from "../utils/base-path.js";
|
|
6
7
|
import { patternToNextFormat } from "../routing/route-validation.js";
|
|
7
|
-
import {
|
|
8
|
+
import { VINEXT_PRERENDER_REWRITTEN_HEADER } from "./headers.js";
|
|
9
|
+
import { methodNotAllowedResponse, notFoundStaticAssetResponse, sanitizeMethodNotAllowedHeaders } from "./http-error-responses.js";
|
|
8
10
|
import { cloneRequestWithUrl, normalizeTrailingSlash } from "./request-pipeline.js";
|
|
9
11
|
import { normalizeDefaultLocalePathname, stripI18nLocaleForApiRoute } from "./pages-i18n.js";
|
|
10
12
|
import { markRouteCacheabilityDynamic } from "../shims/cacheability-classification.js";
|
|
@@ -13,7 +15,7 @@ import { mergeRewriteQuery } from "../utils/query.js";
|
|
|
13
15
|
import { buildMiddlewarePrefetchSkipResponse } from "./pages-data-route.js";
|
|
14
16
|
import { setFrameworkRequestRoute } from "./request-tracing.js";
|
|
15
17
|
import { applyConfigHeadersToHeaderRecord } from "./config-headers.js";
|
|
16
|
-
import { mergeHeaders } from "./worker-utils.js";
|
|
18
|
+
import { finalizeMissingStaticAssetResponse, mergeHeaders } from "./worker-utils.js";
|
|
17
19
|
//#region src/server/pages-request-pipeline.ts
|
|
18
20
|
function ruleUsesUnkeyedRequestCondition(rule) {
|
|
19
21
|
return [...rule.has ?? [], ...rule.missing ?? []].some((condition) => condition.type === "header" || condition.type === "cookie" || condition.type === "host");
|
|
@@ -30,12 +32,19 @@ function headersFromRecord(record) {
|
|
|
30
32
|
else headers.set(name, value);
|
|
31
33
|
return headers;
|
|
32
34
|
}
|
|
33
|
-
async function fetchWorkerFilesystemRoute(request, requestPathname, phase, fetchAsset, publicFiles,
|
|
35
|
+
async function fetchWorkerFilesystemRoute(request, requestPathname, phase, fetchAsset, publicFiles, basePath = "", assetPathPrefix = "") {
|
|
34
36
|
const isRetrievalMethod = request.method === "GET" || request.method === "HEAD";
|
|
35
|
-
if (phase === "direct" && isRetrievalMethod ||
|
|
37
|
+
if (phase === "direct" && isRetrievalMethod || requestPathname === "/api" || requestPathname.startsWith("/api/")) return false;
|
|
36
38
|
const assetUrl = new URL(request.url);
|
|
37
39
|
assetUrl.pathname = requestPathname;
|
|
38
40
|
assetUrl.search = "";
|
|
41
|
+
const decodedAssetUrl = new URL(assetUrl);
|
|
42
|
+
try {
|
|
43
|
+
decodedAssetUrl.pathname = decodeURIComponent(assetUrl.pathname);
|
|
44
|
+
} catch {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
if (!publicFiles.has(assetUrl.pathname) && !publicFiles.has(decodedAssetUrl.pathname) && !isNextStaticPath(decodedAssetUrl.pathname, basePath, assetPathPrefix)) return false;
|
|
39
48
|
const response = await fetchAsset(isRetrievalMethod ? new Request(assetUrl, request) : new Request(assetUrl, {
|
|
40
49
|
method: "HEAD",
|
|
41
50
|
headers: request.headers
|
|
@@ -254,10 +263,11 @@ async function runPagesRequest(request, deps) {
|
|
|
254
263
|
}
|
|
255
264
|
const initialFilesystemResult = await serveFilesystemRoute(resolvedPathname, resolvedPathnameIsRequestPathname ? "direct" : "beforeFiles");
|
|
256
265
|
if (initialFilesystemResult) return initialFilesystemResult;
|
|
266
|
+
const isMissingBuildAsset = () => isNextStaticPath(resolvedPathname, "", assetPrefixPathname(deps.assetPrefix ?? ""));
|
|
257
267
|
const isOutsideBasePathUnclaimed = () => basePath && !hadBasePath && !configRewriteFired;
|
|
258
268
|
const outOfBasePathNotFound = () => ({
|
|
259
269
|
type: "response",
|
|
260
|
-
response: new Response("This page could not be found", {
|
|
270
|
+
response: isMissingBuildAsset() ? notFoundStaticAssetResponse(headersFromRecord(middlewareHeaders)) : new Response("This page could not be found", {
|
|
261
271
|
status: 404,
|
|
262
272
|
headers: { "Content-Type": "text/html; charset=utf-8" }
|
|
263
273
|
})
|
|
@@ -375,6 +385,10 @@ async function runPagesRequest(request, deps) {
|
|
|
375
385
|
matchedFallbackRewrite = true;
|
|
376
386
|
if (response.status !== 404) break;
|
|
377
387
|
}
|
|
388
|
+
if (!renderPageMatch && response.status === 404 && isMissingBuildAsset()) return {
|
|
389
|
+
type: "response",
|
|
390
|
+
response: finalizeMissingStaticAssetResponse(mergeHeaders(response, middlewareHeaders, middlewareStatus), true)
|
|
391
|
+
};
|
|
378
392
|
if (response.status === 404 && shouldDeferErrorPageOnMiss && !matchedFallbackRewrite) response = await deps.renderPage(request, resolvedUrl, void 0, stagedHeaders);
|
|
379
393
|
const matchedPathHeaders = { ...middlewareHeaders };
|
|
380
394
|
if ((isDataReq || isDataRequest) && deps.hasMiddleware && !renderPageMatch && response.status === 404 && (middlewareStatus === void 0 || middlewareStatus === 200 || middlewareStatus === 404)) {
|
|
@@ -392,6 +406,7 @@ async function runPagesRequest(request, deps) {
|
|
|
392
406
|
};
|
|
393
407
|
}
|
|
394
408
|
if ((isDataReq || isDataRequest) && renderPageMatch && (middlewareStatus ?? response.status) === 200) matchedPathHeaders["x-nextjs-matched-path"] = matchedPathnameForRoute(renderPageMatch?.route.pattern);
|
|
409
|
+
if (typeof process !== "undefined" && process.env?.VINEXT_PRERENDER === "1") matchedPathHeaders[VINEXT_PRERENDER_REWRITTEN_HEADER] = resolvedUrl === originalResolvedUrl ? "0" : "1";
|
|
395
410
|
const merged = mergeHeaders(response, matchedPathHeaders, middlewareStatus);
|
|
396
411
|
if (merged !== response) merged.__vinextStreamedHtmlResponse = response.__vinextStreamedHtmlResponse;
|
|
397
412
|
return {
|
|
@@ -9,13 +9,13 @@ import { notFoundStaticAssetResponse } from "./http-error-responses.js";
|
|
|
9
9
|
import { isOpenRedirectShaped } from "./open-redirect.js";
|
|
10
10
|
import { attachRequestCfMetadata, cloneRequestWithHeaders, cloneRequestWithUrl, filterInternalHeaders } from "./request-pipeline.js";
|
|
11
11
|
import { normalizeDefaultLocalePathname } from "./pages-i18n.js";
|
|
12
|
+
import { getExplicitCdnCacheAdapter } from "../shims/cdn-cache-state.js";
|
|
12
13
|
import { CACHEABILITY_REQUEST_STATE } from "../shims/cacheability-classification.js";
|
|
13
14
|
import { applyCdnResponseIdentityHeaders, captureCdnResponsePolicyOverrides, reconcileCdnResponseHeadersAfterOuterPolicy, validateCdnRequest } from "./cache-control.js";
|
|
14
15
|
import { registerLazyDataCacheHandler } from "../shims/cache-handler.js";
|
|
15
16
|
import { DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES, handleConfiguredImageOptimization, isImageOptimizationPath } from "./image-optimization.js";
|
|
16
17
|
import { traceFrameworkRequest } from "./request-tracing.js";
|
|
17
18
|
import { resolveResponseStageCachePolicy } from "./config-headers.js";
|
|
18
|
-
import { finalizeMissingStaticAssetResponse } from "./worker-utils.js";
|
|
19
19
|
import { fetchWorkerFilesystemRoute, runPagesRequest, wrapMiddlewareWithBasePath } from "./pages-request-pipeline.js";
|
|
20
20
|
import { createWorkerRevalidationContext } from "./worker-revalidation-context.js";
|
|
21
21
|
import { createWorkerPrerenderDiscoveryContext, createWorkerPrerenderReadinessResponse, isWorkerPrerenderDiscoveryPath } from "./worker-prerender-discovery.js";
|
|
@@ -69,7 +69,7 @@ function handleRequestStage(request, env, ctx, dispatchResponseStage) {
|
|
|
69
69
|
/** Preserve the direct single-entry Worker path without retaining it in request-only builds. */
|
|
70
70
|
function handleRequestStageLocally(request, env, ctx, dispatchResponseStage) {
|
|
71
71
|
const originalRequest = request;
|
|
72
|
-
return handleRequest(request, env, ctx, (stageRequest, props, _options, stageEnv, stageCtx) => dispatchResponseStage(stageRequest, stageEnv, stageCtx, props), true, "worker",
|
|
72
|
+
return handleRequest(request, env, ctx, (stageRequest, props, _options, stageEnv, stageCtx) => dispatchResponseStage(stageRequest, stageEnv, stageCtx, props), true, "worker", ctx?.assets).then((response) => applyCdnResponseIdentityHeaders(response, originalRequest));
|
|
73
73
|
}
|
|
74
74
|
function handleRequest(request, env, platformCtx, dispatchResponseStage, forceCacheBypass, defaultHostRuntime, assets) {
|
|
75
75
|
const url = new URL(request.url);
|
|
@@ -90,6 +90,7 @@ async function handleRequestImpl(request, env, platformCtx, dispatchResponseStag
|
|
|
90
90
|
let sharedOuterPolicyHeaders = null;
|
|
91
91
|
let ctx = createWorkerRevalidationContext(platformCtx, (internalRequest, internalCtx) => handleRequest(internalRequest, env, internalCtx, dispatchResponseStage, forceCacheBypass, defaultHostRuntime, assets), defaultHostRuntime);
|
|
92
92
|
configuredCdnCacheAdapters.registerConfiguredCacheAdapters(env);
|
|
93
|
+
assets ??= getExplicitCdnCacheAdapter()?.assets ?? (defaultHostRuntime === "worker" ? env?.ASSETS : void 0);
|
|
93
94
|
if (configuredCdnCacheAdapters.hasConfiguredDataCache) registerLazyDataCacheHandler(async () => {
|
|
94
95
|
(await import("virtual:vinext-cache-adapters")).registerConfiguredCacheAdapters(env);
|
|
95
96
|
});
|
|
@@ -184,6 +185,7 @@ async function handleRequestImpl(request, env, platformCtx, dispatchResponseStag
|
|
|
184
185
|
});
|
|
185
186
|
let speculativeRenderRequest = null;
|
|
186
187
|
const deps = {
|
|
188
|
+
assetPrefix: vinextConfig?.assetPrefix,
|
|
187
189
|
basePath,
|
|
188
190
|
trailingSlash,
|
|
189
191
|
i18nConfig,
|
|
@@ -287,12 +289,12 @@ async function handleRequestImpl(request, env, platformCtx, dispatchResponseStag
|
|
|
287
289
|
const allowedWidths = [...vinextConfig?.images?.deviceSizes ?? DEFAULT_DEVICE_SIZES, ...vinextConfig?.images?.imageSizes ?? DEFAULT_IMAGE_SIZES];
|
|
288
290
|
return handleConfiguredImageOptimization(imageRequest, (assetPath) => Promise.resolve(assets.fetch(new Request(new URL(assetPath, request.url)))), allowedWidths, imageConfig);
|
|
289
291
|
}
|
|
290
|
-
return fetchWorkerFilesystemRoute(request, requestPathname, phase, (assetRequest) => Promise.resolve(assets.fetch(assetRequest)), publicFiles,
|
|
292
|
+
return fetchWorkerFilesystemRoute(request, requestPathname, phase, (assetRequest) => Promise.resolve(assets.fetch(assetRequest)), publicFiles, basePath, assetPathPrefix);
|
|
291
293
|
}
|
|
292
294
|
};
|
|
293
295
|
const result = await runPagesRequest(request, deps);
|
|
294
296
|
if (result.type === "response") {
|
|
295
|
-
let response =
|
|
297
|
+
let response = result.response;
|
|
296
298
|
if (sharedResponseHeaders && sharedOuterPolicyHeaders) reconcileCdnResponseHeadersAfterOuterPolicy(response.headers, sharedOuterPolicyHeaders);
|
|
297
299
|
if (probeMode && probeRoute && !responseStageDispatched) {
|
|
298
300
|
const { finalizeRequestStageCacheabilityProbe } = await import("./cacheability-request.js");
|
|
@@ -16,6 +16,12 @@ export type PrerenderManifestRoute = {
|
|
|
16
16
|
fallback?: boolean;
|
|
17
17
|
headers?: Record<string, string | string[]>;
|
|
18
18
|
responseStatus?: number;
|
|
19
|
+
/** Pages source returned notFound, rather than rendering a custom 404 document. */
|
|
20
|
+
notFound?: true;
|
|
21
|
+
/** Original Pages redirect props, including client navigation semantics. */
|
|
22
|
+
redirectProps?: object;
|
|
23
|
+
/** Pages locale rendered for this public pathname. */
|
|
24
|
+
locale?: string;
|
|
19
25
|
routeSegments?: string[];
|
|
20
26
|
tags?: string[];
|
|
21
27
|
};
|
|
@@ -74,7 +74,7 @@ function getPrerenderedConcretePaths(manifest, options) {
|
|
|
74
74
|
const paths = [];
|
|
75
75
|
const seen = /* @__PURE__ */ new Set();
|
|
76
76
|
for (const route of routes) {
|
|
77
|
-
if (route.status !== "rendered") continue;
|
|
77
|
+
if (route.status !== "rendered" || route.notFound) continue;
|
|
78
78
|
const pathname = route.path ?? route.route;
|
|
79
79
|
if (!options?.includeFallbackShells && isFallbackShellArtifactPath(pathname, route)) continue;
|
|
80
80
|
if (!options?.includeErrorDocuments && isErrorDocumentRoute(pathname, route)) continue;
|
|
@@ -21,7 +21,7 @@ import { installSocketErrorBackstop } from "./socket-error-backstop.js";
|
|
|
21
21
|
import { collectInlineCssManifest } from "../build/inline-css.js";
|
|
22
22
|
import { readTrustedRevalidationHostname } from "./revalidation-host.js";
|
|
23
23
|
import { traceFrameworkRequest } from "./request-tracing.js";
|
|
24
|
-
import {
|
|
24
|
+
import { mergeHeaders } from "./worker-utils.js";
|
|
25
25
|
import { runPagesRequest, wrapMiddlewareWithBasePath } from "./pages-request-pipeline.js";
|
|
26
26
|
import { computeClientRuntimeMetadata } from "../utils/client-runtime-metadata.js";
|
|
27
27
|
import { readPrerenderSecret } from "../build/server-manifest.js";
|
|
@@ -1070,12 +1070,10 @@ async function startAppRouterServer(options) {
|
|
|
1070
1070
|
return;
|
|
1071
1071
|
}
|
|
1072
1072
|
}
|
|
1073
|
-
let missingBuildAsset = false;
|
|
1074
1073
|
{
|
|
1075
1074
|
const assetLookupPath = resolveAppRouterAssetPath(pathname, appAssetPathPrefix, appRouterAssetPrefix);
|
|
1076
1075
|
if (assetLookupPath) {
|
|
1077
1076
|
if (await tryServeStatic(req, res, clientDir, assetLookupPath, compress, staticCache)) return;
|
|
1078
|
-
missingBuildAsset = true;
|
|
1079
1077
|
}
|
|
1080
1078
|
}
|
|
1081
1079
|
if (isImageOptimizationPath(pathname)) {
|
|
@@ -1105,10 +1103,6 @@ async function startAppRouterServer(options) {
|
|
|
1105
1103
|
try {
|
|
1106
1104
|
const request = nodeToWebRequest(req, rawUrl, prerenderSecret, appRouterI18nConfig, appRouterAuthorizeOnDemandRevalidate);
|
|
1107
1105
|
const response = await rscHandler(request, createNodeExecutionContext(resolveTrustedNodeRevalidateOrigin(req, host, port)));
|
|
1108
|
-
if (missingBuildAsset && response.status === 404) {
|
|
1109
|
-
await sendWebResponse(finalizeMissingStaticAssetResponse(response, true), req, res, compress);
|
|
1110
|
-
return;
|
|
1111
|
-
}
|
|
1112
1106
|
const staticFileSignal = readStaticFileSignal(response);
|
|
1113
1107
|
if (staticFileSignal) {
|
|
1114
1108
|
let staticFilePath = "/";
|
|
@@ -1316,7 +1310,6 @@ async function startPagesRouterServer(options) {
|
|
|
1316
1310
|
return;
|
|
1317
1311
|
}
|
|
1318
1312
|
const pagesAssetLookup = resolveAppRouterAssetPath(pathname, pagesAssetPathPrefix, assetPrefix);
|
|
1319
|
-
const missingBuildAsset = pagesAssetLookup !== null;
|
|
1320
1313
|
if (pagesAssetLookup) {
|
|
1321
1314
|
if (await tryServeStatic(req, res, clientDir, pagesAssetLookup, compress, staticCache)) return;
|
|
1322
1315
|
}
|
|
@@ -1382,6 +1375,7 @@ async function startPagesRouterServer(options) {
|
|
|
1382
1375
|
});
|
|
1383
1376
|
const middlewareRequest = isDataReq && skipProxyUrlNormalize ? new Request(new URL(originalRenderUrl, webRequest.url), webRequest) : void 0;
|
|
1384
1377
|
const deps = {
|
|
1378
|
+
assetPrefix,
|
|
1385
1379
|
basePath,
|
|
1386
1380
|
trailingSlash,
|
|
1387
1381
|
i18nConfig,
|
|
@@ -1404,7 +1398,7 @@ async function startPagesRouterServer(options) {
|
|
|
1404
1398
|
renderPage: typeof renderPage === "function" ? (request, resolvedUrl, options, stagedHeaders) => renderPage(request, resolvedUrl, ssrManifest, void 0, stagedHeaders, {
|
|
1405
1399
|
...options,
|
|
1406
1400
|
originalUrl: originalRenderUrl
|
|
1407
|
-
}) : null,
|
|
1401
|
+
}, stagedHeaders?.has("Cache-Control") ? new Headers({ "Cache-Control": stagedHeaders.get("Cache-Control") }) : void 0) : null,
|
|
1408
1402
|
handleApi: typeof handleApi === "function" ? (request, apiUrl) => handleApi(request, apiUrl, createNodeExecutionContext(), resolveTrustedNodeRevalidateOrigin(req, host, port), "node") : null,
|
|
1409
1403
|
serveFilesystemRoute: async (requestPathname, stagedHeaders, phase, resolvedUrl) => {
|
|
1410
1404
|
if (isImageOptimizationPath(requestPathname)) {
|
|
@@ -1440,10 +1434,6 @@ async function startPagesRouterServer(options) {
|
|
|
1440
1434
|
if (result.type === "handled") return;
|
|
1441
1435
|
if (result.type === "response") {
|
|
1442
1436
|
const { response } = result;
|
|
1443
|
-
if (missingBuildAsset && response.status === 404) {
|
|
1444
|
-
await sendWebResponse(finalizeMissingStaticAssetResponse(response, true), req, res, compress);
|
|
1445
|
-
return;
|
|
1446
|
-
}
|
|
1447
1437
|
const streamedApi = isVinextStreamedApiResponse(response);
|
|
1448
1438
|
if (isVinextStreamedHtmlResponse(response) || streamedApi || !response.body || result.defaultContentType === void 0) {
|
|
1449
1439
|
if (streamedApi && result.defaultContentType !== void 0 && !response.headers.has("content-type")) response.headers.set("content-type", result.defaultContentType);
|
|
@@ -34,7 +34,7 @@ async function withResponseStageCacheability(options, render) {
|
|
|
34
34
|
const response = options.policyHeadersAppliedBeforeRender ? rendered : cacheability.applyResponseStageCachePolicy(rendered, context, options.policyHeaders);
|
|
35
35
|
const complete = (candidate) => cacheability.finalizeWorkerCacheabilityResponse(candidate, context);
|
|
36
36
|
const route = state?.route;
|
|
37
|
-
if (!options.probeMode && state?.admission?.policy !== "manifest" && (route?.kind === "app-page" || route?.kind === "pages-page")) {
|
|
37
|
+
if (!options.probeMode && state?.admission?.policy !== "manifest" && (route?.kind === "app-page" || route?.kind === "pages-page") && !(route.kind === "pages-page" && state?.outcome?.cacheable === false)) {
|
|
38
38
|
const deferred = adapter.deferCompletedPageResponseAdmission?.(response, complete);
|
|
39
39
|
if (deferred) return deferred;
|
|
40
40
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { VinextRequestStageContext } from "./multi-stage.js";
|
|
1
2
|
import { ExecutionContextLike } from "../shims/request-context.js";
|
|
2
3
|
//#region src/server/worker-revalidation-context.d.ts
|
|
3
|
-
type PlatformExecutionContext = Partial<ExecutionContextLike
|
|
4
|
+
type PlatformExecutionContext = Partial<ExecutionContextLike> & VinextRequestStageContext;
|
|
4
5
|
/**
|
|
5
6
|
* Add a request-local, in-process Pages revalidation dispatcher to a Worker
|
|
6
7
|
* execution context. Re-entering with the derived internal context preserves
|
|
@@ -10,6 +10,7 @@ function deriveExecutionContext(base, dispatchPagesRevalidate, isInternalPagesRe
|
|
|
10
10
|
} } : {},
|
|
11
11
|
hostRuntime: base?.hostRuntime ?? defaultHostRuntime,
|
|
12
12
|
...base?.cache === void 0 ? {} : { cache: base.cache },
|
|
13
|
+
...base?.assets === void 0 ? {} : { assets: base.assets },
|
|
13
14
|
...base?.trustedRevalidateOrigin === void 0 ? {} : { trustedRevalidateOrigin: base.trustedRevalidateOrigin },
|
|
14
15
|
dispatchPagesRevalidate,
|
|
15
16
|
isInternalPagesRevalidation
|
|
@@ -1,7 +1,18 @@
|
|
|
1
1
|
import { FrameworkTracingIntegration } from "./framework-tracer.js";
|
|
2
2
|
//#region src/server/workers-tracing.d.ts
|
|
3
3
|
export type WorkersTracingException = string | {
|
|
4
|
+
code: string | number;
|
|
5
|
+
name?: string;
|
|
6
|
+
message?: string;
|
|
7
|
+
stack?: string;
|
|
8
|
+
} | {
|
|
9
|
+
code?: string | number;
|
|
4
10
|
name: string;
|
|
11
|
+
message?: string;
|
|
12
|
+
stack?: string;
|
|
13
|
+
} | {
|
|
14
|
+
code?: string | number;
|
|
15
|
+
name?: string;
|
|
5
16
|
message: string;
|
|
6
17
|
stack?: string;
|
|
7
18
|
};
|
|
@@ -9,9 +20,15 @@ export type WorkersTracingSpan = {
|
|
|
9
20
|
readonly isTraced: boolean;
|
|
10
21
|
recordException?(exception: WorkersTracingException): void;
|
|
11
22
|
setAttribute(key: string, value: boolean | number | string): void;
|
|
23
|
+
setStatus?(status: {
|
|
24
|
+
code: "error";
|
|
25
|
+
message?: string;
|
|
26
|
+
}): void;
|
|
27
|
+
updateName?(name: string): void;
|
|
12
28
|
};
|
|
13
29
|
export type WorkersTracing = {
|
|
14
30
|
enterSpan<T>(name: string, callback: (span: WorkersTracingSpan) => T): T;
|
|
31
|
+
getActiveSpan?(): WorkersTracingSpan | undefined;
|
|
15
32
|
};
|
|
16
33
|
export declare function createWorkersTracingIntegration(tracing: WorkersTracing): FrameworkTracingIntegration;
|
|
17
34
|
//#endregion
|
|
@@ -1,20 +1,60 @@
|
|
|
1
1
|
//#region src/server/workers-tracing.ts
|
|
2
|
+
function readExceptionField(error, key) {
|
|
3
|
+
try {
|
|
4
|
+
return Reflect.get(error, key);
|
|
5
|
+
} catch {
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
2
9
|
function normalizeException(error) {
|
|
3
10
|
if (typeof error === "string") return error;
|
|
4
|
-
if (error
|
|
5
|
-
|
|
6
|
-
name
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
11
|
+
if (error && typeof error === "object") {
|
|
12
|
+
const code = readExceptionField(error, "code");
|
|
13
|
+
const name = readExceptionField(error, "name");
|
|
14
|
+
const message = readExceptionField(error, "message");
|
|
15
|
+
const stack = readExceptionField(error, "stack");
|
|
16
|
+
const details = {
|
|
17
|
+
...typeof name === "string" ? { name } : {},
|
|
18
|
+
...typeof message === "string" ? { message } : {},
|
|
19
|
+
...typeof stack === "string" ? { stack } : {}
|
|
20
|
+
};
|
|
21
|
+
if (typeof code === "string" || typeof code === "number") return {
|
|
22
|
+
...details,
|
|
23
|
+
code
|
|
24
|
+
};
|
|
25
|
+
if (typeof name === "string") return {
|
|
26
|
+
...details,
|
|
27
|
+
name
|
|
28
|
+
};
|
|
29
|
+
if (typeof message === "string") return {
|
|
30
|
+
...details,
|
|
31
|
+
message
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
return String(error);
|
|
36
|
+
} catch {
|
|
37
|
+
return "Unknown exception";
|
|
38
|
+
}
|
|
10
39
|
}
|
|
11
40
|
function createWorkersTracingIntegration(tracing) {
|
|
12
41
|
const backendSpan = (span) => ({
|
|
13
|
-
recordException: (error) =>
|
|
14
|
-
|
|
42
|
+
recordException: (error) => {
|
|
43
|
+
if (span.isTraced) span.recordException?.(normalizeException(error));
|
|
44
|
+
},
|
|
45
|
+
setAttribute: (key, value) => span.setAttribute(key, value),
|
|
46
|
+
setErrorStatus: (message) => span.setStatus?.({
|
|
47
|
+
code: "error",
|
|
48
|
+
message
|
|
49
|
+
}),
|
|
50
|
+
updateName: (name) => span.updateName?.(name)
|
|
15
51
|
});
|
|
16
52
|
return {
|
|
17
53
|
id: "cloudflare-workers",
|
|
54
|
+
getActiveSpan() {
|
|
55
|
+
const span = tracing.getActiveSpan?.();
|
|
56
|
+
return span ? backendSpan(span) : void 0;
|
|
57
|
+
},
|
|
18
58
|
enterSpan(descriptor, callback) {
|
|
19
59
|
return tracing.enterSpan(descriptor.name, (span) => {
|
|
20
60
|
for (const [key, value] of Object.entries(descriptor.attributes)) span.setAttribute(key, value);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { _recordUseCacheRootParamRead, _registerCacheContextAccessor, getRegisteredCacheContext } from "./internal/cache-context-accessor.js";
|
|
1
2
|
//#region src/shims/cache-request-state.d.ts
|
|
2
3
|
export type CacheLifeConfig = {
|
|
3
4
|
stale?: number;
|
|
@@ -5,19 +6,6 @@ export type CacheLifeConfig = {
|
|
|
5
6
|
expire?: number;
|
|
6
7
|
};
|
|
7
8
|
export declare const cacheLifeProfiles: Record<string, CacheLifeConfig>;
|
|
8
|
-
type CacheContextLike = {
|
|
9
|
-
tags: string[];
|
|
10
|
-
lifeConfigs: CacheLifeConfig[];
|
|
11
|
-
variant: string;
|
|
12
|
-
readRootParamNames?: Set<string>;
|
|
13
|
-
hasExplicitRevalidate: boolean;
|
|
14
|
-
hasExplicitExpire: boolean;
|
|
15
|
-
dynamicNestedCacheError: Error | undefined;
|
|
16
|
-
};
|
|
17
|
-
export declare function _registerCacheContextAccessor(fn: () => CacheContextLike | null): void;
|
|
18
|
-
export declare function getRegisteredCacheContext(): CacheContextLike | null;
|
|
19
|
-
/** Record a root-param dependency on the active public `"use cache"` scope. */
|
|
20
|
-
export declare function _recordUseCacheRootParamRead(name: string): void;
|
|
21
9
|
export type UnstableCacheRevalidationMode = "foreground" | "background";
|
|
22
10
|
export type ActionRevalidationKind = 0 | 1 | 2;
|
|
23
11
|
export type UnstableCacheObservation = Readonly<{
|
|
@@ -83,4 +71,5 @@ export declare function _captureRequestScopedCacheLifeAccessors(): {
|
|
|
83
71
|
export declare function recordUnstableCacheObservation(observation: UnstableCacheObservation): void;
|
|
84
72
|
export declare function _peekUnstableCacheObservations(): UnstableCacheObservation[];
|
|
85
73
|
export declare function shouldServeStaleUnstableCacheEntry(): boolean;
|
|
86
|
-
//#endregion
|
|
74
|
+
//#endregion
|
|
75
|
+
export { _recordUseCacheRootParamRead, _registerCacheContextAccessor, getRegisteredCacheContext };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { getOrCreateAls } from "./internal/als-registry.js";
|
|
2
2
|
import { getRequestContext, isInsideUnifiedScope, runWithUnifiedStateMutation } from "./unified-request-context.js";
|
|
3
|
-
import { getHeadersAccessPhase } from "./headers.js";
|
|
3
|
+
import { getHeadersAccessPhase } from "./internal/headers-state.js";
|
|
4
|
+
import { _recordUseCacheRootParamRead, _registerCacheContextAccessor, getRegisteredCacheContext } from "./internal/cache-context-accessor.js";
|
|
4
5
|
//#region src/shims/cache-request-state.ts
|
|
5
6
|
const cacheLifeProfiles = {
|
|
6
7
|
default: {
|
|
@@ -38,18 +39,6 @@ const cacheLifeProfiles = {
|
|
|
38
39
|
expire: 31536e3
|
|
39
40
|
}
|
|
40
41
|
};
|
|
41
|
-
let getCacheContext = null;
|
|
42
|
-
function _registerCacheContextAccessor(fn) {
|
|
43
|
-
getCacheContext = fn;
|
|
44
|
-
}
|
|
45
|
-
function getRegisteredCacheContext() {
|
|
46
|
-
return getCacheContext?.() ?? null;
|
|
47
|
-
}
|
|
48
|
-
/** Record a root-param dependency on the active public `"use cache"` scope. */
|
|
49
|
-
function _recordUseCacheRootParamRead(name) {
|
|
50
|
-
const context = getRegisteredCacheContext();
|
|
51
|
-
if (context && context.variant !== "private") context.readRootParamNames?.add(name);
|
|
52
|
-
}
|
|
53
42
|
const FALLBACK_KEY = Symbol.for("vinext.cache.fallback");
|
|
54
43
|
const globalState = globalThis;
|
|
55
44
|
const cacheAls = getOrCreateAls("vinext.cache.als");
|
|
@@ -6,8 +6,10 @@ import { isRouteCacheabilityProbe, recordRouteCacheabilityProbeBailout } from ".
|
|
|
6
6
|
import { getDataCacheHandler } from "./cache-handler.js";
|
|
7
7
|
import { suppressHangingPromiseAbortRejections } from "./internal/make-hanging-promise.js";
|
|
8
8
|
import { createPprFallbackShellSuspensePromise, trackPprFallbackShellCacheTask } from "./ppr-fallback-shell.js";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
9
|
+
import { markDynamicUsage, throwIfInsideCacheScope } from "./internal/headers-state.js";
|
|
10
|
+
import { isDraftModeEnabled } from "./headers.js";
|
|
11
|
+
import { _registerCacheContextAccessor } from "./internal/cache-context-accessor.js";
|
|
12
|
+
import { _hasPendingRevalidatedTag, _setRequestScopedCacheLife, cacheLifeProfiles } from "./cache-request-state.js";
|
|
11
13
|
import { addCollectedRequestTags, getCurrentFetchSoftTags } from "./fetch-cache.js";
|
|
12
14
|
import { makeThenableParams } from "./thenable-params.js";
|
|
13
15
|
import { APP_PAGE_USE_CACHE_MARKER, hasUseCachePageMarker, isMarkedAppPagePropsObject, isUseCacheFunctionReference, markAppPagePropsForUseCache } from "./internal/app-page-props-cache-key.js";
|
package/dist/shims/cache.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ExecutionContextLike, getRequestExecutionContext, runWithExecutionContext } from "./request-context.js";
|
|
2
|
-
import {
|
|
2
|
+
import { _recordUseCacheRootParamRead, _registerCacheContextAccessor, getRegisteredCacheContext } from "./internal/cache-context-accessor.js";
|
|
3
|
+
import { ACTION_DID_REVALIDATE_DYNAMIC_ONLY, ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC, ActionRevalidationKind, CacheLifeConfig, CacheState, UnstableCacheObservation, UnstableCacheRevalidationMode, _captureRequestScopedCacheLifeAccessors, _consumeRequestScopedCacheLife, _drainPendingRevalidations, _hasPendingRevalidatedTag, _initRequestScopedCacheState, _markPendingRevalidatedTag, _peekRequestScopedCacheLife, _peekUnstableCacheObservations, _queuePendingRevalidation, _runWithCacheState, _setRequestScopedCacheLife, cacheLifeProfiles, getAndClearActionRevalidationKind, markActionRevalidation, recordUnstableCacheObservation, shouldServeStaleUnstableCacheEntry } from "./cache-request-state.js";
|
|
3
4
|
import { CacheControlMetadata, CacheHandler, CacheHandlerContext, CacheHandlerValue, CachedAppPageValue, CachedFetchValue, CachedImageValue, CachedPagesValue, CachedRedirectValue, CachedRouteValue, IncrementalCacheValue, MemoryCacheHandler, NoOpCacheHandler, configureMemoryCacheHandler, getCacheHandler, getDataCacheHandler, registerDataCacheHandler, registerLazyDataCacheHandler, setCacheHandler, setDataCacheHandler } from "./cache-handler.js";
|
|
4
5
|
//#region src/shims/cache.d.ts
|
|
5
6
|
/**
|
package/dist/shims/cache.js
CHANGED
|
@@ -8,8 +8,10 @@ import { fnv1a64 } from "../utils/hash.js";
|
|
|
8
8
|
import { MemoryCacheHandler, NoOpCacheHandler, configureMemoryCacheHandler, getCacheHandler, getDataCacheHandler, registerDataCacheHandler, registerLazyDataCacheHandler, setCacheHandler, setDataCacheHandler } from "./cache-handler.js";
|
|
9
9
|
import { encodeCacheTag, encodeCacheTags } from "../utils/encode-cache-tag.js";
|
|
10
10
|
import { makeHangingPromise } from "./internal/make-hanging-promise.js";
|
|
11
|
-
import { getHeadersAccessPhase,
|
|
12
|
-
import {
|
|
11
|
+
import { getHeadersAccessPhase, markDynamicUsage } from "./internal/headers-state.js";
|
|
12
|
+
import { isDraftModeEnabled } from "./headers.js";
|
|
13
|
+
import { _recordUseCacheRootParamRead, _registerCacheContextAccessor, getRegisteredCacheContext } from "./internal/cache-context-accessor.js";
|
|
14
|
+
import { ACTION_DID_REVALIDATE_DYNAMIC_ONLY, ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC, _captureRequestScopedCacheLifeAccessors, _consumeRequestScopedCacheLife, _drainPendingRevalidations, _hasPendingRevalidatedTag, _initRequestScopedCacheState, _markPendingRevalidatedTag, _peekRequestScopedCacheLife, _peekUnstableCacheObservations, _queuePendingRevalidation, _runWithCacheState, _setRequestScopedCacheLife, cacheLifeProfiles, getAndClearActionRevalidationKind, markActionRevalidation, recordUnstableCacheObservation, shouldServeStaleUnstableCacheEntry } from "./cache-request-state.js";
|
|
13
15
|
import { addCollectedRequestTags, getCurrentFetchSoftTags } from "./fetch-cache.js";
|
|
14
16
|
//#region src/shims/cache.ts
|
|
15
17
|
/**
|
|
@@ -86,7 +86,7 @@ export declare function markRouteCacheabilityExplicitConfigPolicy(): void;
|
|
|
86
86
|
export declare function markRouteCacheabilityConfigCdnCachePolicy(name: string, value: string): void;
|
|
87
87
|
/** Record a next.config cache policy header with the value a response carries. */
|
|
88
88
|
export declare function recordConfigCdnCachePolicyHeader(state: RouteCacheabilityState, name: string, value: string): void;
|
|
89
|
-
/** Record
|
|
89
|
+
/** Record an explicit cache policy supplied by the Route Handler itself. */
|
|
90
90
|
export declare function markRouteCacheabilityExplicitResponsePolicy(): void;
|
|
91
91
|
/** Record that the response body reached clean EOF and is now a replay stream. */
|
|
92
92
|
export declare function markRouteCacheabilityResponseBodyComplete(): void;
|
|
@@ -84,10 +84,10 @@ function recordConfigCdnCachePolicyHeader(state, name, value) {
|
|
|
84
84
|
const applied = new Headers([[name, value]]).get(name) ?? value;
|
|
85
85
|
(state.configCdnCachePolicy ??= /* @__PURE__ */ new Map()).set(name.toLowerCase(), applied);
|
|
86
86
|
}
|
|
87
|
-
/** Record
|
|
87
|
+
/** Record an explicit cache policy supplied by the Route Handler itself. */
|
|
88
88
|
function markRouteCacheabilityExplicitResponsePolicy() {
|
|
89
89
|
const state = readRouteCacheabilityState();
|
|
90
|
-
if (!state
|
|
90
|
+
if (!state) return;
|
|
91
91
|
state.explicitResponseCachePolicy = true;
|
|
92
92
|
}
|
|
93
93
|
/** Record that the response body reached clean EOF and is now a replay stream. */
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { VinextAssetFetcher } from "../server/multi-stage.js";
|
|
1
2
|
import { CacheHandlerValue, IncrementalCacheValue } from "./cache-handler.js";
|
|
2
3
|
import { setCdnCacheAdapter } from "./cdn-cache-state.js";
|
|
3
4
|
//#region src/shims/cdn-cache.d.ts
|
|
@@ -10,6 +11,8 @@ export type CdnCacheableHeaderInput = {
|
|
|
10
11
|
* when no cacheable policy applies.
|
|
11
12
|
*/
|
|
12
13
|
cacheControl: string;
|
|
14
|
+
/** Explicit endpoint policy returned to clients, independent of shared admission. */
|
|
15
|
+
browserCacheControl?: string;
|
|
13
16
|
/**
|
|
14
17
|
* True when this is a freshly-rendered **streaming** response whose
|
|
15
18
|
* dynamic-ness is not yet proven (late Server Component request-API usage can
|
|
@@ -47,8 +50,10 @@ export type CdnResponsePolicy = {
|
|
|
47
50
|
/** Whether provider policy explicitly opts out of storage. */
|
|
48
51
|
hasExplicitNonCacheablePolicy(headers: Headers, baseline?: Headers): boolean;
|
|
49
52
|
};
|
|
53
|
+
/** Split Cache-Control directives without treating quoted commas as separators. */
|
|
54
|
+
export declare function splitCacheControlDirectives(cacheControl: string): string[];
|
|
50
55
|
/** Whether a Cache-Control value contains an exact non-cacheable directive. */
|
|
51
|
-
export declare function isNonCacheableCacheControl(cacheControl: string): boolean;
|
|
56
|
+
export declare function isNonCacheableCacheControl(cacheControl: string, scope?: "shared" | "browser"): boolean;
|
|
52
57
|
/**
|
|
53
58
|
* The serving strategy for page-level ISR. Implement this to delegate
|
|
54
59
|
* page/route/image caching to a CDN edge instead of the origin store.
|
|
@@ -100,6 +105,10 @@ export type CdnCacheAdapter = {
|
|
|
100
105
|
* edge owns serving.
|
|
101
106
|
*/
|
|
102
107
|
get(key: string, ctx?: Record<string, unknown>): Promise<CacheHandlerValue | null>;
|
|
108
|
+
/** Also supplies build-time PAGES entries for pages without getStaticProps. */
|
|
109
|
+
readonly hasPrerenderedPages?: boolean;
|
|
110
|
+
/** Optional host asset fetcher resolved by the adapter's platform bindings. */
|
|
111
|
+
readonly assets?: VinextAssetFetcher;
|
|
103
112
|
/**
|
|
104
113
|
* Persist a freshly-rendered page-level artifact.
|
|
105
114
|
*
|
package/dist/shims/cdn-cache.js
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import { getExplicitCdnCacheAdapter, setCdnCacheAdapter } from "./cdn-cache-state.js";
|
|
2
2
|
//#region src/shims/cdn-cache.ts
|
|
3
|
-
/**
|
|
4
|
-
function
|
|
3
|
+
/** Split Cache-Control directives without treating quoted commas as separators. */
|
|
4
|
+
function splitCacheControlDirectives(cacheControl) {
|
|
5
|
+
const directives = [];
|
|
5
6
|
let start = 0;
|
|
6
7
|
let quoted = false;
|
|
7
8
|
let escaped = false;
|
|
8
9
|
for (let index = 0; index <= cacheControl.length; index++) {
|
|
9
10
|
const char = cacheControl[index];
|
|
10
11
|
if (index === cacheControl.length || char === "," && !quoted) {
|
|
11
|
-
const directive = cacheControl.slice(start, index);
|
|
12
|
-
|
|
13
|
-
const name = (equals === -1 ? directive : directive.slice(0, equals)).trim().toLowerCase();
|
|
14
|
-
if (name === "no-store" || equals === -1 && (name === "private" || name === "no-cache")) return true;
|
|
12
|
+
const directive = cacheControl.slice(start, index).trim();
|
|
13
|
+
if (directive) directives.push(directive);
|
|
15
14
|
start = index + 1;
|
|
16
15
|
continue;
|
|
17
16
|
}
|
|
@@ -22,7 +21,15 @@ function isNonCacheableCacheControl(cacheControl) {
|
|
|
22
21
|
if (char === "\"" && !escaped) quoted = !quoted;
|
|
23
22
|
escaped = false;
|
|
24
23
|
}
|
|
25
|
-
return
|
|
24
|
+
return directives;
|
|
25
|
+
}
|
|
26
|
+
/** Whether a Cache-Control value contains an exact non-cacheable directive. */
|
|
27
|
+
function isNonCacheableCacheControl(cacheControl, scope = "shared") {
|
|
28
|
+
return splitCacheControlDirectives(cacheControl).some((directive) => {
|
|
29
|
+
const equals = directive.indexOf("=");
|
|
30
|
+
const name = (equals === -1 ? directive : directive.slice(0, equals)).trim().toLowerCase();
|
|
31
|
+
return name === "no-store" || equals === -1 && (name === "no-cache" || scope === "shared" && name === "private");
|
|
32
|
+
});
|
|
26
33
|
}
|
|
27
34
|
const PENDING_DYNAMIC_CACHE_CONTROL = "no-store, must-revalidate";
|
|
28
35
|
/**
|
|
@@ -48,7 +55,7 @@ var DefaultCdnCacheAdapter = class {
|
|
|
48
55
|
}
|
|
49
56
|
buildResponseHeaders(input) {
|
|
50
57
|
if (input.pendingDynamicCheck) return { "Cache-Control": PENDING_DYNAMIC_CACHE_CONTROL };
|
|
51
|
-
return { "Cache-Control": input.cacheControl };
|
|
58
|
+
return { "Cache-Control": input.browserCacheControl ?? input.cacheControl };
|
|
52
59
|
}
|
|
53
60
|
buildResponseIdentityHeaders() {
|
|
54
61
|
return this.buildIdentity ? { "X-Vinext-Build-Id": this.buildIdentity } : {};
|
|
@@ -88,4 +95,4 @@ function getCdnCacheAdapter() {
|
|
|
88
95
|
return _defaultAdapter ??= new DefaultCdnCacheAdapter();
|
|
89
96
|
}
|
|
90
97
|
//#endregion
|
|
91
|
-
export { DefaultCdnCacheAdapter, getCdnCacheAdapter, isNonCacheableCacheControl, setCdnCacheAdapter };
|
|
98
|
+
export { DefaultCdnCacheAdapter, getCdnCacheAdapter, isNonCacheableCacheControl, setCdnCacheAdapter, splitCacheControlDirectives };
|
package/dist/shims/error.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { IncomingMessage, ServerResponse } from "node:http";
|
|
3
|
+
import { ErrorInfo, catchError as catchError$1, unstable_catchError as unstable_catchError$1 } from "@vinext/types/next/vinext/error";
|
|
3
4
|
//#region src/shims/error.d.ts
|
|
4
5
|
export type ErrorProps = {
|
|
5
6
|
statusCode: number;
|
|
@@ -21,22 +22,7 @@ declare class ErrorComponent<P = {}> extends React.Component<P & ErrorProps> {
|
|
|
21
22
|
static origGetInitialProps: typeof getErrorInitialProps;
|
|
22
23
|
render(): React.ReactElement;
|
|
23
24
|
}
|
|
24
|
-
export
|
|
25
|
-
|
|
26
|
-
reset: () => void;
|
|
27
|
-
unstable_retry: () => void;
|
|
28
|
-
};
|
|
29
|
-
type _UserProps = Record<string, unknown>;
|
|
30
|
-
/**
|
|
31
|
-
* Wrap a fallback render function in a Component-level error boundary.
|
|
32
|
-
* Returns a Component that renders `children` and, on error, renders the
|
|
33
|
-
* supplied fallback with an `ErrorInfo` value.
|
|
34
|
-
*
|
|
35
|
-
* Ported from Next.js:
|
|
36
|
-
* https://github.com/vercel/next.js/blob/canary/packages/next/src/client/components/catch-error.tsx
|
|
37
|
-
*/
|
|
38
|
-
export declare function unstable_catchError<P extends _UserProps>(fallback: (props: P, errorInfo: ErrorInfo) => React.ReactNode): React.ComponentType<P & {
|
|
39
|
-
children?: React.ReactNode;
|
|
40
|
-
}>;
|
|
25
|
+
export declare const catchError: typeof catchError$1;
|
|
26
|
+
export declare const unstable_catchError: typeof unstable_catchError$1;
|
|
41
27
|
//#endregion
|
|
42
|
-
export { ErrorComponent as default };
|
|
28
|
+
export { type ErrorInfo, ErrorComponent as default };
|