@vinext/cloudflare 1.0.0-beta.7 → 1.0.0-beta.8

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.
Files changed (52) hide show
  1. package/README.md +55 -22
  2. package/dist/cache/cdn-adapter-config.d.ts +16 -8
  3. package/dist/cache/cdn-adapter-config.js +57 -17
  4. package/dist/cache/cdn-adapter.d.ts +25 -24
  5. package/dist/cache/cdn-adapter.js +24 -20
  6. package/dist/cache/cdn-adapter.runtime.d.ts +9 -3
  7. package/dist/cache/cdn-adapter.runtime.js +63 -40
  8. package/dist/cache/cdn-adapter.worker.d.ts +30 -0
  9. package/dist/cache/cdn-adapter.worker.js +371 -0
  10. package/dist/cache/cdn-build-id.d.ts +4 -3
  11. package/dist/cache/cdn-build-id.js +5 -1
  12. package/dist/cache/kv-data-adapter.d.ts +21 -5
  13. package/dist/cache/kv-data-adapter.runtime.d.ts +38 -4
  14. package/dist/cache/kv-data-adapter.runtime.js +115 -41
  15. package/dist/cache/kv-key.d.ts +4 -5
  16. package/dist/cache/response-store-adapter.d.ts +37 -0
  17. package/dist/cache/response-store-adapter.js +39 -0
  18. package/dist/cache/response-store-adapter.self-contained.worker.d.ts +17 -0
  19. package/dist/cache/response-store-adapter.self-contained.worker.js +10 -0
  20. package/dist/cache/response-store-adapter.service-binding.worker.d.ts +15 -0
  21. package/dist/cache/response-store-adapter.service-binding.worker.js +9 -0
  22. package/dist/cache/response-store-adapter.worker.d.ts +14 -0
  23. package/dist/cache/response-store-adapter.worker.js +254 -0
  24. package/dist/cache/response-store-cdn.runtime.d.ts +5 -0
  25. package/dist/cache/response-store-cdn.runtime.js +41 -0
  26. package/dist/cache/response-store-data.runtime.d.ts +34 -0
  27. package/dist/cache/response-store-data.runtime.js +289 -0
  28. package/dist/cacheability-artifact.d.ts +2 -3
  29. package/dist/cacheability-artifact.js +27 -1
  30. package/dist/cacheability-manifest-limits.d.ts +3 -4
  31. package/dist/cacheability-manifest-limits.js +1 -1
  32. package/dist/cacheability-probe.d.ts +8 -9
  33. package/dist/cacheability-probe.js +255 -91
  34. package/dist/cdn-warm.d.ts +31 -25
  35. package/dist/cdn-warm.js +208 -50
  36. package/dist/deploy-config.d.ts +11 -12
  37. package/dist/deploy-config.js +8 -3
  38. package/dist/deploy-help.d.ts +3 -4
  39. package/dist/deploy.d.ts +23 -24
  40. package/dist/deploy.js +44 -11
  41. package/dist/images/images-optimizer.d.ts +3 -4
  42. package/dist/prerender-kv-populate.d.ts +3 -4
  43. package/dist/prerender-kv-populate.js +3 -2
  44. package/dist/tpr.d.ts +9 -10
  45. package/dist/tpr.js +1 -1
  46. package/dist/utils/cache-control-metadata.d.ts +3 -4
  47. package/dist/version-deploy.d.ts +17 -17
  48. package/dist/version-deploy.js +6 -3
  49. package/dist/worker-deployment-url.d.ts +3 -4
  50. package/dist/workers-dev-url.d.ts +2 -3
  51. package/dist/wrangler-version-metadata.d.ts +2 -3
  52. package/package.json +13 -7
@@ -1,7 +1,7 @@
1
- import { PrerenderRoutePattern } from "vinext/internal/build/prerender-paths";
1
+ import { PrerenderPathManifest, PrerenderRoutePattern } from "vinext/internal/build/prerender-paths";
2
2
  import { PrerenderManifest, PrerenderedPathSelectionOptions } from "vinext/internal/server/prerender-manifest";
3
3
  //#region src/cdn-warm.d.ts
4
- type CdnWarmOptions = {
4
+ export type CdnWarmOptions = {
5
5
  targetUrl: string;
6
6
  paths: readonly string[];
7
7
  /** Pages Router JSON data identities used by client navigation. */
@@ -27,23 +27,27 @@ type CdnWarmOptions = {
27
27
  phaseTimeoutMs?: number;
28
28
  /** Retry a newly staged version or preview alias until its routing has propagated. */
29
29
  propagatingTarget?: boolean;
30
+ /** @internal Matching skipped targets that may be transient while a staged version propagates. */
31
+ retrySkippedTargetKeys?: ReadonlySet<string>;
30
32
  /** Require the response to come from a reusable cache entry, not merely an eligible MISS. */
31
33
  requireCacheHit?: boolean;
32
34
  strict?: boolean;
35
+ /** Cache-admission signal exposed by the deployed adapter. */
36
+ statusSource?: "cloudflare" | "vinext";
33
37
  fetchImpl?: typeof fetch;
34
38
  };
35
- declare const DEFAULT_CDN_WARM_CONCURRENCY = 25;
36
- declare const DEFAULT_CDN_WARM_TIMEOUT_MS = 10000;
37
- declare const DEFAULT_STAGED_READINESS_RETRIES = 60;
38
- declare const DEFAULT_STAGED_READINESS_INTERVAL_MS = 1000;
39
- declare const DEFAULT_STAGED_READINESS_PHASE_TIMEOUT_MS = 120000;
40
- type PrerenderCdnWarmOptions = Omit<CdnWarmOptions, "paths"> & {
39
+ export declare const DEFAULT_CDN_WARM_CONCURRENCY = 25;
40
+ export declare const DEFAULT_CDN_WARM_TIMEOUT_MS = 10000;
41
+ export declare const DEFAULT_STAGED_READINESS_RETRIES = 60;
42
+ export declare const DEFAULT_STAGED_READINESS_INTERVAL_MS = 1000;
43
+ export declare const DEFAULT_STAGED_READINESS_PHASE_TIMEOUT_MS = 120000;
44
+ export type PrerenderCdnWarmOptions = Omit<CdnWarmOptions, "paths"> & {
41
45
  root: string;
42
46
  includeFallbackShells?: boolean;
43
47
  /** Use the manifest build identity unless the configured adapter cannot expose it. */
44
48
  validateBuildIdentity?: boolean;
45
49
  };
46
- type CdnWarmResult = {
50
+ export type CdnWarmResult = {
47
51
  total: number;
48
52
  warmed: number;
49
53
  skipped: number;
@@ -56,7 +60,7 @@ type CdnWarmResult = {
56
60
  warmedPlan: CdnWarmRequestPlan;
57
61
  retryPlan: CdnWarmRequestPlan;
58
62
  };
59
- type CdnWarmRequestPlan = {
63
+ export type CdnWarmRequestPlan = {
60
64
  loadingShellPaths: string[];
61
65
  pagesDataPaths: string[];
62
66
  paths: string[];
@@ -64,13 +68,13 @@ type CdnWarmRequestPlan = {
64
68
  routeHandlerPaths?: string[];
65
69
  routePatterns?: Record<string, PrerenderRoutePattern>;
66
70
  };
67
- type CdnWarmReadinessResult = {
71
+ export type CdnWarmReadinessResult = {
68
72
  ready: true;
69
73
  } | {
70
74
  error: string;
71
75
  ready: false;
72
76
  };
73
- type PrerenderWarmPlan = {
77
+ export type PrerenderWarmPlan = {
74
78
  appPaths?: string[];
75
79
  buildId?: string;
76
80
  buildIdentity?: string;
@@ -85,17 +89,20 @@ type PrerenderWarmPlan = {
85
89
  rscBuildId?: string;
86
90
  rscPaths: string[];
87
91
  };
88
- declare function readPrerenderWarmPlan(root: string, options?: {
92
+ type PrerenderWarmPlanOptions = {
93
+ includeCanonicalRsc?: boolean;
89
94
  includeFallbackShells?: boolean;
90
95
  strict?: boolean;
91
- }): PrerenderWarmPlan;
92
- declare function readPrerenderWarmPaths(root: string, options?: {
96
+ };
97
+ export declare function createPrerenderWarmPlan(root: string, manifest: PrerenderPathManifest, options?: PrerenderWarmPlanOptions): PrerenderWarmPlan;
98
+ export declare function readPrerenderWarmPlan(root: string, options?: PrerenderWarmPlanOptions): PrerenderWarmPlan;
99
+ export declare function readPrerenderWarmPaths(root: string, options?: {
93
100
  includeFallbackShells?: boolean;
94
101
  strict?: boolean;
95
102
  }): string[];
96
- declare function getWarmPathsFromPrerenderManifest(manifest: PrerenderManifest, options?: PrerenderedPathSelectionOptions): string[];
97
- declare function buildWarmupUrl(targetUrl: string, pathname: string): URL;
98
- type CdnWarmTarget = {
103
+ export declare function getWarmPathsFromPrerenderManifest(manifest: PrerenderManifest, options?: PrerenderedPathSelectionOptions): string[];
104
+ export declare function buildWarmupUrl(targetUrl: string, pathname: string): URL;
105
+ export type CdnWarmTarget = {
99
106
  headers?: HeadersInit;
100
107
  kind: "app-route" | "html" | "pages-data" | "rsc-full" | "rsc-loading-shell";
101
108
  label: string;
@@ -103,8 +110,8 @@ type CdnWarmTarget = {
103
110
  sourcePathname: string;
104
111
  route?: PrerenderRoutePattern;
105
112
  };
106
- declare function createCdnWarmTargets(options: Pick<CdnWarmOptions, "deploymentId" | "headers" | "loadingShellPaths" | "pagesDataPaths" | "paths" | "routeHandlerPaths" | "routePatterns" | "rscPaths">): Promise<CdnWarmTarget[]>;
107
- declare class CdnOperationProgress {
113
+ export declare function createCdnWarmTargets(options: Pick<CdnWarmOptions, "deploymentId" | "headers" | "loadingShellPaths" | "pagesDataPaths" | "paths" | "routeHandlerPaths" | "routePatterns" | "rscPaths">): Promise<CdnWarmTarget[]>;
114
+ export declare class CdnOperationProgress {
108
115
  private readonly isTTY;
109
116
  private lastLineLength;
110
117
  update(completed: number, total: number, label: string, phase?: string): void;
@@ -115,7 +122,7 @@ declare class CdnOperationProgress {
115
122
  * before any real cache key is filled. Every probe has a unique query key, so
116
123
  * an early response cannot make a later readiness attempt pass from cache.
117
124
  */
118
- declare function waitForCdnWarmTargetReadiness(options: Pick<CdnWarmOptions, "deploymentId" | "expectedBuildId" | "expectedRscBuildId" | "fetchImpl" | "headers" | "retries" | "targetUrl" | "timeoutMs"> & {
125
+ export declare function waitForCdnWarmTargetReadiness(options: Pick<CdnWarmOptions, "deploymentId" | "expectedBuildId" | "expectedRscBuildId" | "fetchImpl" | "headers" | "retries" | "targetUrl" | "timeoutMs"> & {
119
126
  plan: CdnWarmRequestPlan;
120
127
  maxAttempts?: number;
121
128
  phaseTimeoutMs?: number;
@@ -123,7 +130,6 @@ declare function waitForCdnWarmTargetReadiness(options: Pick<CdnWarmOptions, "de
123
130
  probeIntervalMs?: number;
124
131
  requiredConsecutiveSuccesses?: number;
125
132
  }): Promise<CdnWarmReadinessResult>;
126
- declare function warmCdnCache(options: CdnWarmOptions): Promise<CdnWarmResult>;
127
- declare function warmCdnCacheFromPrerender(options: PrerenderCdnWarmOptions): Promise<CdnWarmResult>;
128
- //#endregion
129
- export { CdnOperationProgress, CdnWarmOptions, CdnWarmReadinessResult, CdnWarmRequestPlan, CdnWarmResult, CdnWarmTarget, DEFAULT_CDN_WARM_CONCURRENCY, DEFAULT_CDN_WARM_TIMEOUT_MS, DEFAULT_STAGED_READINESS_INTERVAL_MS, DEFAULT_STAGED_READINESS_PHASE_TIMEOUT_MS, DEFAULT_STAGED_READINESS_RETRIES, PrerenderCdnWarmOptions, PrerenderWarmPlan, buildWarmupUrl, createCdnWarmTargets, getWarmPathsFromPrerenderManifest, readPrerenderWarmPaths, readPrerenderWarmPlan, waitForCdnWarmTargetReadiness, warmCdnCache, warmCdnCacheFromPrerender };
133
+ export declare function warmCdnCache(options: CdnWarmOptions): Promise<CdnWarmResult>;
134
+ export declare function warmCdnCacheFromPrerender(options: PrerenderCdnWarmOptions): Promise<CdnWarmResult>;
135
+ //#endregion
package/dist/cdn-warm.js CHANGED
@@ -1,12 +1,13 @@
1
1
  import { VINEXT_CDN_BUILD_ID_HEADER } from "./cache/cdn-build-id.js";
2
2
  import fs from "node:fs";
3
3
  import path from "node:path";
4
+ import { cacheabilityRoutePathname } from "vinext/internal/server/cacheability-manifest";
4
5
  import { randomUUID } from "node:crypto";
5
6
  import { setTimeout as setTimeout$1 } from "node:timers/promises";
6
- import { VINEXT_PRERENDER_READINESS_HEADER, VINEXT_PRERENDER_READINESS_PATH, VINEXT_PRERENDER_SECRET_HEADER } from "vinext/internal/server/headers";
7
+ import { VINEXT_CACHE_HEADER, VINEXT_PRERENDER_READINESS_HEADER, VINEXT_PRERENDER_READINESS_PATH, VINEXT_PRERENDER_SECRET_HEADER } from "vinext/internal/server/headers";
7
8
  import { PRERENDER_PATHS_MANIFEST } from "vinext/internal/build/prerender-paths";
8
9
  import { getPrerenderedConcretePaths, readPrerenderManifest } from "vinext/internal/server/prerender-manifest";
9
- import { VINEXT_RSC_BUILD_ID_HEADER, VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_VARY_HEADER, createCanonicalLoadingShellRscRequestHeaders, createCanonicalRscRequestHeaders, createCanonicalRscRequestUrl, createRscRequestUrl } from "vinext/internal/server/app-rsc-cache-busting";
10
+ import { VINEXT_RSC_BUILD_ID_HEADER, VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_VARY_HEADER as VINEXT_RSC_VARY_HEADER$1, createCanonicalLoadingShellRscRequestHeaders, createCanonicalRscRequestHeaders, createCanonicalRscRequestUrl, createRscRequestUrl } from "vinext/internal/server/app-rsc-cache-busting";
10
11
  import { isNonCacheableCacheControl } from "vinext/shims/cdn-cache";
11
12
  import { normalizePathTrailingSlash } from "vinext/shims/url-utils";
12
13
  //#region src/cdn-warm.ts
@@ -18,7 +19,8 @@ const DEFAULT_STAGED_READINESS_PHASE_TIMEOUT_MS = 12e4;
18
19
  const DEFAULT_STAGED_READINESS_SUCCESSES = 6;
19
20
  const STAGED_READINESS_QUERY_PARAM = "__vinext_cdn_warm_readiness";
20
21
  function applyWarmPathConfig(pathname, config) {
21
- const normalized = normalizePathTrailingSlash(config.basePath ? pathname === "/" ? config.basePath : `${config.basePath}${pathname}` : pathname, config.trailingSlash === true);
22
+ const withBasePath = config.basePath ? pathname === "/" ? config.basePath : `${config.basePath}${pathname}` : pathname;
23
+ const normalized = normalizePathTrailingSlash(withBasePath, config.trailingSlash === true);
22
24
  return new URL(normalized, "http://vinext.local").pathname;
23
25
  }
24
26
  function readBuiltBuildId(root) {
@@ -36,16 +38,14 @@ function readPrerenderPathManifest(manifestPath) {
36
38
  const parsed = JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
37
39
  if (!parsed || typeof parsed !== "object") return null;
38
40
  const manifest = parsed;
39
- if (!Array.isArray(manifest.paths) || !manifest.paths.every((pathname) => typeof pathname === "string") || manifest.appPaths !== void 0 && (!Array.isArray(manifest.appPaths) || !manifest.appPaths.every((pathname) => typeof pathname === "string")) || manifest.pagesPaths !== void 0 && (!Array.isArray(manifest.pagesPaths) || !manifest.pagesPaths.every((pathname) => typeof pathname === "string")) || manifest.pagesDataPaths !== void 0 && (!Array.isArray(manifest.pagesDataPaths) || !manifest.pagesDataPaths.every((pathname) => typeof pathname === "string")) || manifest.excludedWarmPaths !== void 0 && (!Array.isArray(manifest.excludedWarmPaths) || !manifest.excludedWarmPaths.every((pathname) => typeof pathname === "string")) || manifest.fallbackRoutePatterns !== void 0 && (!Array.isArray(manifest.fallbackRoutePatterns) || !manifest.fallbackRoutePatterns.every((route) => route !== null && typeof route === "object" && !Array.isArray(route) && (route.kind === "app-page" || route.kind === "app-route" || route.kind === "pages-page") && typeof route.pattern === "string" && route.pattern.startsWith("/"))) || manifest.rscPaths !== void 0 && (!Array.isArray(manifest.rscPaths) || !manifest.rscPaths.every((pathname) => typeof pathname === "string")) || manifest.routeHandlerPaths !== void 0 && (!Array.isArray(manifest.routeHandlerPaths) || !manifest.routeHandlerPaths.every((pathname) => typeof pathname === "string")) || manifest.routePatterns !== void 0 && (!manifest.routePatterns || typeof manifest.routePatterns !== "object" || Array.isArray(manifest.routePatterns) || !Object.entries(manifest.routePatterns).every(([pathname, route]) => pathname.startsWith("/") && route !== null && typeof route === "object" && !Array.isArray(route) && (route.kind === "app-page" || route.kind === "app-route" || route.kind === "pages-page") && typeof route.pattern === "string" && route.pattern.startsWith("/") && (route.cacheabilityProbe === void 0 || route.cacheabilityProbe !== null && typeof route.cacheabilityProbe === "object" && !Array.isArray(route.cacheabilityProbe) && typeof route.cacheabilityProbe.canPrunePattern === "boolean" && (route.cacheabilityProbe.concretePathname === void 0 || typeof route.cacheabilityProbe.concretePathname === "string" && route.cacheabilityProbe.concretePathname.startsWith("/"))))) || manifest.loadingShellPaths !== void 0 && (!Array.isArray(manifest.loadingShellPaths) || !manifest.loadingShellPaths.every((pathname) => typeof pathname === "string")) || manifest.basePath !== void 0 && typeof manifest.basePath !== "string" || manifest.buildIdentity !== void 0 && typeof manifest.buildIdentity !== "string" || manifest.deploymentId !== void 0 && typeof manifest.deploymentId !== "string" || manifest.rscBuildId !== void 0 && typeof manifest.rscBuildId !== "string" || manifest.trailingSlash !== void 0 && typeof manifest.trailingSlash !== "boolean" || manifest.responseVary !== void 0 && manifest.responseVary !== "verbatim") return null;
41
+ if (!Array.isArray(manifest.paths) || !manifest.paths.every((pathname) => typeof pathname === "string") || manifest.appPaths !== void 0 && (!Array.isArray(manifest.appPaths) || !manifest.appPaths.every((pathname) => typeof pathname === "string")) || manifest.pagesPaths !== void 0 && (!Array.isArray(manifest.pagesPaths) || !manifest.pagesPaths.every((pathname) => typeof pathname === "string")) || manifest.pagesDataPaths !== void 0 && (!Array.isArray(manifest.pagesDataPaths) || !manifest.pagesDataPaths.every((pathname) => typeof pathname === "string")) || manifest.excludedWarmPaths !== void 0 && (!Array.isArray(manifest.excludedWarmPaths) || !manifest.excludedWarmPaths.every((pathname) => typeof pathname === "string")) || manifest.fallbackRoutePatterns !== void 0 && (!Array.isArray(manifest.fallbackRoutePatterns) || !manifest.fallbackRoutePatterns.every((route) => route !== null && typeof route === "object" && !Array.isArray(route) && (route.kind === "app-page" || route.kind === "app-route" || route.kind === "pages-page") && typeof route.pattern === "string" && route.pattern.startsWith("/"))) || manifest.rscPaths !== void 0 && (!Array.isArray(manifest.rscPaths) || !manifest.rscPaths.every((pathname) => typeof pathname === "string")) || manifest.routeHandlerPaths !== void 0 && (!Array.isArray(manifest.routeHandlerPaths) || !manifest.routeHandlerPaths.every((pathname) => typeof pathname === "string")) || manifest.routePatterns !== void 0 && (!manifest.routePatterns || typeof manifest.routePatterns !== "object" || Array.isArray(manifest.routePatterns) || !Object.entries(manifest.routePatterns).every(([pathname, route]) => pathname.startsWith("/") && route !== null && typeof route === "object" && !Array.isArray(route) && (route.kind === "app-page" || route.kind === "app-route" || route.kind === "pages-page") && typeof route.pattern === "string" && route.pattern.startsWith("/") && (route.cacheabilityProbe === void 0 || route.cacheabilityProbe !== null && typeof route.cacheabilityProbe === "object" && !Array.isArray(route.cacheabilityProbe) && typeof route.cacheabilityProbe.canPrunePattern === "boolean" && (route.cacheabilityProbe.concretePathname === void 0 || typeof route.cacheabilityProbe.concretePathname === "string" && route.cacheabilityProbe.concretePathname.startsWith("/")) && (route.cacheabilityProbe.routeMayResolve === void 0 || typeof route.cacheabilityProbe.routeMayResolve === "boolean") && (route.cacheabilityProbe.requestStageMayTerminate === void 0 || typeof route.cacheabilityProbe.requestStageMayTerminate === "boolean")))) || manifest.loadingShellPaths !== void 0 && (!Array.isArray(manifest.loadingShellPaths) || !manifest.loadingShellPaths.every((pathname) => typeof pathname === "string")) || manifest.basePath !== void 0 && typeof manifest.basePath !== "string" || manifest.buildIdentity !== void 0 && typeof manifest.buildIdentity !== "string" || manifest.deploymentId !== void 0 && typeof manifest.deploymentId !== "string" || manifest.rscBuildId !== void 0 && typeof manifest.rscBuildId !== "string" || manifest.trailingSlash !== void 0 && typeof manifest.trailingSlash !== "boolean" || manifest.responseVary !== void 0 && manifest.responseVary !== "verbatim") return null;
40
42
  return manifest;
41
43
  } catch (error) {
42
44
  console.warn(`[vinext] Failed to read prerender path manifest at ${manifestPath}:`, error);
43
45
  return null;
44
46
  }
45
47
  }
46
- function readPrerenderPathWarmPaths(root, options) {
47
- const manifest = readPrerenderPathManifest(path.join(root, "dist", "server", PRERENDER_PATHS_MANIFEST));
48
- if (!manifest) return null;
48
+ function createPrerenderPathWarmPaths(root, manifest, options) {
49
49
  const builtBuildId = readBuiltBuildId(root);
50
50
  if (!manifest.buildId || !builtBuildId || manifest.buildId !== builtBuildId) {
51
51
  const message = "[vinext] CDN warmup skipped: prerender path manifest buildId does not match dist/server/BUILD_ID.";
@@ -59,10 +59,10 @@ function readPrerenderPathWarmPaths(root, options) {
59
59
  paths: manifest.paths.filter((pathname) => pathname.startsWith("/")).filter((pathname) => !manifest.excludedWarmPaths?.includes(pathname)).map((pathname) => applyWarmPathConfig(pathname, manifest))
60
60
  };
61
61
  }
62
- function readPrerenderWarmPlan(root, options) {
63
- const pathPlan = readPrerenderPathWarmPaths(root, options);
62
+ function createPrerenderWarmPlan(root, manifest, options) {
63
+ const pathPlan = createPrerenderPathWarmPaths(root, manifest, options);
64
64
  if (!pathPlan) {
65
- const message = "[vinext] CDN warmup skipped: prerender path manifest not found.";
65
+ const message = "[vinext] CDN warmup skipped: prerender path discovery is invalid.";
66
66
  if (options?.strict) throw new Error(message);
67
67
  return {
68
68
  loadingShellPaths: [],
@@ -70,8 +70,7 @@ function readPrerenderWarmPlan(root, options) {
70
70
  rscPaths: []
71
71
  };
72
72
  }
73
- const { manifest } = pathPlan;
74
- const supportsCanonicalRsc = manifest.responseVary === "verbatim" && manifest.rscPaths !== void 0 && manifest.rscBuildId !== void 0;
73
+ const supportsCanonicalRsc = (manifest.responseVary === "verbatim" || options?.includeCanonicalRsc === true) && manifest.rscPaths !== void 0 && manifest.rscBuildId !== void 0;
75
74
  const applyConfig = (pathname) => applyWarmPathConfig(pathname, manifest);
76
75
  const routePatterns = manifest.routePatterns ? Object.fromEntries(Object.entries(manifest.routePatterns).map(([pathname, route]) => [pathname.includes("/_next/data/") ? pathname : applyConfig(pathname), route])) : void 0;
77
76
  let htmlPaths = pathPlan.paths;
@@ -101,6 +100,19 @@ function readPrerenderWarmPlan(root, options) {
101
100
  ...routePatterns ? { routePatterns } : {}
102
101
  };
103
102
  }
103
+ function readPrerenderWarmPlan(root, options) {
104
+ const manifest = readPrerenderPathManifest(path.join(root, "dist", "server", PRERENDER_PATHS_MANIFEST));
105
+ if (!manifest) {
106
+ const message = "[vinext] CDN warmup skipped: prerender path manifest not found.";
107
+ if (options?.strict) throw new Error(message);
108
+ return {
109
+ loadingShellPaths: [],
110
+ paths: [],
111
+ rscPaths: []
112
+ };
113
+ }
114
+ return createPrerenderWarmPlan(root, manifest, options);
115
+ }
104
116
  function readPrerenderWarmPaths(root, options) {
105
117
  return readPrerenderWarmPlan(root, options).paths;
106
118
  }
@@ -169,6 +181,89 @@ async function fetchHeadersWithTimeout(fetchImpl, url, timeoutMs, headers, metho
169
181
  if (timer !== void 0) clearTimeout(timer);
170
182
  }
171
183
  }
184
+ const MAX_CDN_WARM_REPORT_ROUTES = 10;
185
+ const MAX_CDN_WARM_REPORT_PATTERN_WIDTH = 48;
186
+ const CDN_WARM_ROUTE_KIND_LABELS = {
187
+ "app-page": "App page",
188
+ "app-route": "Route Handler",
189
+ "pages-page": "Pages page"
190
+ };
191
+ function formatCount(count, singular, plural = `${singular}s`) {
192
+ return `${count.toLocaleString("en-US")} ${count === 1 ? singular : plural}`;
193
+ }
194
+ function formatNumber(count) {
195
+ return count.toLocaleString("en-US");
196
+ }
197
+ function truncateMiddle(value, maxLength) {
198
+ if (value.length <= maxLength) return value;
199
+ const remaining = maxLength - 1;
200
+ const startLength = Math.ceil(remaining / 2);
201
+ return `${value.slice(0, startLength)}…${value.slice(-(remaining - startLength))}`;
202
+ }
203
+ function printCdnWarmTable(headings, rows, rightAlignedFrom) {
204
+ const widths = headings.map((heading, index) => Math.max(heading.length, ...rows.map((row) => row[index]?.length ?? 0)));
205
+ for (const row of [headings, ...rows]) console.log(` ${row.map((value, index) => index >= rightAlignedFrom ? value.padStart(widths[index]) : value.padEnd(widths[index])).join(" ")}`);
206
+ }
207
+ function createCdnWarmRouteReport(targets, outcomes) {
208
+ const routes = /* @__PURE__ */ new Map();
209
+ for (const [index, target] of targets.entries()) {
210
+ const key = target.route ? `${target.route.kind}\0${target.route.pattern}` : "unmatched";
211
+ const route = routes.get(key) ?? {
212
+ failed: 0,
213
+ kind: target.route ? CDN_WARM_ROUTE_KIND_LABELS[target.route.kind] : "Other",
214
+ key,
215
+ pattern: target.route?.pattern ?? "Other discovered requests",
216
+ paths: /* @__PURE__ */ new Set(),
217
+ skipped: 0,
218
+ total: 0,
219
+ warmed: 0
220
+ };
221
+ route.paths.add(target.route?.cacheabilityProbe?.concretePathname ?? cacheabilityRoutePathname(target.pathname, target.kind));
222
+ route.total++;
223
+ const outcome = outcomes?.[index];
224
+ if (outcome) route[outcome]++;
225
+ routes.set(key, route);
226
+ }
227
+ return [...routes.values()].sort((left, right) => right.total - left.total || left.key.localeCompare(right.key));
228
+ }
229
+ function printCdnWarmRouteReport(targets, outcomes) {
230
+ if (!targets.some((target) => target.route)) return;
231
+ const routes = createCdnWarmRouteReport(targets, outcomes);
232
+ if (routes.length === 0) return;
233
+ console.log(` CDN warmup ${outcomes ? "result" : "plan"} by route:`);
234
+ const visible = routes.slice(0, MAX_CDN_WARM_REPORT_ROUTES);
235
+ const routeColumns = (route) => [truncateMiddle(route.pattern, MAX_CDN_WARM_REPORT_PATTERN_WIDTH), route.kind];
236
+ if (outcomes) printCdnWarmTable([
237
+ "Route pattern",
238
+ "Kind",
239
+ "Warmed",
240
+ "Skipped",
241
+ "Failed"
242
+ ], visible.map((route) => [
243
+ ...routeColumns(route),
244
+ `${formatNumber(route.warmed)}/${formatNumber(route.total)}`,
245
+ formatNumber(route.skipped),
246
+ formatNumber(route.failed)
247
+ ]), 2);
248
+ else printCdnWarmTable([
249
+ "Route pattern",
250
+ "Kind",
251
+ "Paths",
252
+ "Entries"
253
+ ], visible.map((route) => [
254
+ ...routeColumns(route),
255
+ formatNumber(route.paths.size),
256
+ formatNumber(route.total)
257
+ ]), 2);
258
+ const omitted = routes.slice(MAX_CDN_WARM_REPORT_ROUTES);
259
+ if (omitted.length > 0) {
260
+ const omittedEntries = omitted.reduce((total, route) => total + route.total, 0);
261
+ console.log(` ... ${formatCount(omitted.length, "additional route pattern")} omitted (${formatCount(omittedEntries, "cache entry", "cache entries")})`);
262
+ }
263
+ }
264
+ function cdnWarmTargetKey(target) {
265
+ return `${target.kind}\0${target.sourcePathname}`;
266
+ }
172
267
  async function createCdnWarmTargets(options) {
173
268
  const requests = [];
174
269
  const fullRscPaths = new Set(options.rscPaths ?? []);
@@ -257,7 +352,7 @@ var CdnOperationProgress = class {
257
352
  this.lastLineLength = 0;
258
353
  }
259
354
  };
260
- const REQUIRED_RSC_VARY_HEADERS = VINEXT_RSC_VARY_HEADER.split(",").map((name) => name.trim().toLowerCase());
355
+ const REQUIRED_RSC_VARY_HEADERS = VINEXT_RSC_VARY_HEADER$1.split(",").map((name) => name.trim().toLowerCase());
261
356
  const ADMITTED_CF_CACHE_STATUSES = /* @__PURE__ */ new Set([
262
357
  "HIT",
263
358
  "MISS",
@@ -350,17 +445,35 @@ function validateCachePolicy(response, requireCacheStatus, requireCacheHit = fal
350
445
  error: `CF-Cache-Status is ${cacheStatus}`
351
446
  };
352
447
  }
353
- function validateBuildIdentity(response, expectedBuildId) {
354
- if (expectedBuildId !== void 0 && response.headers.get("X-Vinext-Build-Id") !== expectedBuildId) return {
448
+ function validateVinextCacheStatus(response) {
449
+ const status = response.headers.get(VINEXT_CACHE_HEADER)?.trim().toUpperCase();
450
+ if (status === "MISS" || status === "HIT" || status === "UPDATING") return { outcome: "warmed" };
451
+ if (status === "BYPASS" || status === "DYNAMIC") return {
452
+ outcome: "skipped",
453
+ reason: `${VINEXT_CACHE_HEADER} is ${status}`
454
+ };
455
+ return {
355
456
  outcome: "failed",
356
- error: `response ${VINEXT_CDN_BUILD_ID_HEADER} does not match build ${expectedBuildId} (received ${response.headers.get("X-Vinext-Build-Id") ?? "missing"})`
457
+ error: `response is missing ${VINEXT_CACHE_HEADER}`
357
458
  };
459
+ }
460
+ function validateWarmAdmission(response, statusSource, requireCacheHit) {
461
+ return statusSource === "vinext" ? validateVinextCacheStatus(response) : validateCachePolicy(response, true, requireCacheHit);
462
+ }
463
+ function validateBuildIdentity(response, expectedBuildId) {
464
+ if (expectedBuildId !== void 0 && response.headers.get("X-Vinext-Build-Id") !== expectedBuildId) {
465
+ const actualBuildId = response.headers.get("X-Vinext-Build-Id") ?? "missing";
466
+ return {
467
+ outcome: "failed",
468
+ error: `response ${VINEXT_CDN_BUILD_ID_HEADER} does not match build ${expectedBuildId} (received ${actualBuildId})`
469
+ };
470
+ }
358
471
  return null;
359
472
  }
360
473
  function isExpectedTerminalStatus(status) {
361
474
  return status >= 300 && status < 400 || status === 404;
362
475
  }
363
- function validateRscWarmResponse(response, expectedBuildId, expectedRscBuildId, requireCacheHit = false) {
476
+ function validateRscWarmResponse(response, expectedBuildId, expectedRscBuildId, requireCacheHit = false, statusSource = "cloudflare") {
364
477
  const buildIdentityValidation = validateBuildIdentity(response, expectedBuildId);
365
478
  if (buildIdentityValidation) return buildIdentityValidation;
366
479
  if (expectedRscBuildId !== void 0 && response.headers.get(VINEXT_RSC_BUILD_ID_HEADER) !== expectedRscBuildId) return {
@@ -381,7 +494,7 @@ function validateRscWarmResponse(response, expectedBuildId, expectedRscBuildId,
381
494
  outcome: "failed",
382
495
  error: `expected ${VINEXT_RSC_CONTENT_TYPE} response`
383
496
  };
384
- const cachePolicyValidation = validateCachePolicy(response, true, requireCacheHit);
497
+ const cachePolicyValidation = validateWarmAdmission(response, statusSource, requireCacheHit);
385
498
  if (cachePolicyValidation.outcome !== "warmed") return cachePolicyValidation;
386
499
  if (terminalResponse && !response.headers.get("Content-Type")?.toLowerCase().startsWith(VINEXT_RSC_CONTENT_TYPE)) return {
387
500
  outcome: "failed",
@@ -395,7 +508,7 @@ function validateRscWarmResponse(response, expectedBuildId, expectedRscBuildId,
395
508
  };
396
509
  return { outcome: "warmed" };
397
510
  }
398
- function validateHtmlWarmResponse(response, expectedBuildId, requireCacheHit = false) {
511
+ function validateHtmlWarmResponse(response, expectedBuildId, requireCacheHit = false, statusSource = "cloudflare") {
399
512
  const buildIdentityValidation = validateBuildIdentity(response, expectedBuildId);
400
513
  if (buildIdentityValidation) return buildIdentityValidation;
401
514
  if (response.redirected) return {
@@ -408,12 +521,12 @@ function validateHtmlWarmResponse(response, expectedBuildId, requireCacheHit = f
408
521
  error: `HTTP ${response.status}`
409
522
  };
410
523
  }
411
- const cachePolicyValidation = validateCachePolicy(response, true, requireCacheHit);
524
+ const cachePolicyValidation = validateWarmAdmission(response, statusSource, requireCacheHit);
412
525
  if (cachePolicyValidation.outcome !== "warmed") return cachePolicyValidation;
413
526
  return { outcome: "warmed" };
414
527
  }
415
- function validatePagesDataWarmResponse(response, expectedBuildId, requireCacheHit = false) {
416
- const validation = validateHtmlWarmResponse(response, expectedBuildId, requireCacheHit);
528
+ function validatePagesDataWarmResponse(response, expectedBuildId, requireCacheHit = false, statusSource = "cloudflare") {
529
+ const validation = validateHtmlWarmResponse(response, expectedBuildId, requireCacheHit, statusSource);
417
530
  if (validation.outcome !== "warmed") return validation;
418
531
  if (!response.headers.get("Content-Type")?.toLowerCase().startsWith("application/json")) return {
419
532
  outcome: "failed",
@@ -536,6 +649,7 @@ async function warmOnePath(target, options) {
536
649
  const url = buildWarmupUrl(options.targetUrl, target.pathname);
537
650
  let lastError = "request failed before the first attempt";
538
651
  let lastRetryable = true;
652
+ let lastSkippedReason = null;
539
653
  const phaseDeadlineError = () => `CDN warmup exceeded its ${options.phaseTimeoutMs}ms phase deadline`;
540
654
  const remainingPhaseMs = () => options.deadlineAt === void 0 ? options.timeoutMs : options.deadlineAt - Date.now();
541
655
  const canRetry = (attempt) => attempt < options.retries;
@@ -555,6 +669,7 @@ async function warmOnePath(target, options) {
555
669
  retryable: false
556
670
  };
557
671
  const attemptTimeoutMs = Math.min(options.timeoutMs, remainingMs);
672
+ const phaseLimitedAttempt = options.deadlineAt !== void 0 && remainingMs <= options.timeoutMs;
558
673
  try {
559
674
  const response = options.requireCacheHit ? await fetchHeadersWithTimeout(options.fetchImpl, url, attemptTimeoutMs, target.headers ?? options.headers) : (await fetchWithTimeout(options.fetchImpl, url, attemptTimeoutMs, target.headers ?? options.headers, "manual")).response;
560
675
  if (options.deadlineAt !== void 0 && Date.now() >= options.deadlineAt) return {
@@ -566,18 +681,31 @@ async function warmOnePath(target, options) {
566
681
  if (options.requireCacheHit) response.body?.cancel().catch(() => {});
567
682
  if (process.env.VINEXT_CDN_WARM_DEBUG === "1") console.log(` CDN warm debug ${target.label} attempt ${attempt + 1}: ${url.pathname}${url.search} HTTP ${response.status} cache=${response.headers.get("CF-Cache-Status") ?? "missing"} ray=${response.headers.get("CF-Ray") ?? "missing"} encoding=${response.headers.get("Content-Encoding") ?? "identity"} rscBuild=${response.headers.get(VINEXT_RSC_BUILD_ID_HEADER) ?? "missing"}`);
568
683
  if (target.kind.startsWith("rsc-")) {
569
- const validation = validateRscWarmResponse(response, options.expectedBuildId, options.expectedRscBuildId, options.requireCacheHit);
684
+ const validation = validateRscWarmResponse(response, options.expectedBuildId, options.expectedRscBuildId, options.requireCacheHit, options.statusSource);
570
685
  if (validation.outcome === "warmed") return {
571
686
  path: target.label,
572
687
  ok: true,
573
688
  skipped: false
574
689
  };
575
- if (validation.outcome === "skipped") return {
576
- path: target.label,
577
- ok: true,
578
- skipped: true,
579
- reason: validation.reason
580
- };
690
+ if (validation.outcome === "skipped") {
691
+ if (!options.retrySkipped) return {
692
+ path: target.label,
693
+ ok: true,
694
+ skipped: true,
695
+ reason: validation.reason
696
+ };
697
+ lastSkippedReason = validation.reason;
698
+ lastRetryable = true;
699
+ if (!canRetry(attempt)) break;
700
+ if (!await waitBeforeRetry()) return {
701
+ path: target.label,
702
+ ok: false,
703
+ error: phaseDeadlineError(),
704
+ retryable: false
705
+ };
706
+ continue;
707
+ }
708
+ lastSkippedReason = null;
581
709
  lastError = validation.error;
582
710
  const cacheStatus = response.headers.get("CF-Cache-Status")?.trim().toUpperCase();
583
711
  lastRetryable = options.requireCacheHit && ADMITTED_CF_CACHE_STATUSES.has(cacheStatus ?? "") && !REUSABLE_CF_CACHE_STATUSES.has(cacheStatus ?? "") || shouldRetryValidationFailure(response, target, options);
@@ -591,26 +719,47 @@ async function warmOnePath(target, options) {
591
719
  };
592
720
  continue;
593
721
  }
594
- const validation = target.kind === "pages-data" ? validatePagesDataWarmResponse(response, options.expectedBuildId, options.requireCacheHit) : validateHtmlWarmResponse(response, options.expectedBuildId, options.requireCacheHit);
722
+ const validation = target.kind === "pages-data" ? validatePagesDataWarmResponse(response, options.expectedBuildId, options.requireCacheHit, options.statusSource) : validateHtmlWarmResponse(response, options.expectedBuildId, options.requireCacheHit, options.statusSource);
595
723
  if (validation.outcome === "warmed") return {
596
724
  path: target.label,
597
725
  ok: true,
598
726
  skipped: false
599
727
  };
600
- if (validation.outcome === "skipped") return {
601
- path: target.label,
602
- ok: true,
603
- skipped: true,
604
- reason: validation.reason
605
- };
728
+ if (validation.outcome === "skipped") {
729
+ if (!options.retrySkipped) return {
730
+ path: target.label,
731
+ ok: true,
732
+ skipped: true,
733
+ reason: validation.reason
734
+ };
735
+ lastSkippedReason = validation.reason;
736
+ lastRetryable = true;
737
+ if (!canRetry(attempt)) break;
738
+ if (!await waitBeforeRetry()) return {
739
+ path: target.label,
740
+ ok: false,
741
+ error: phaseDeadlineError(),
742
+ retryable: false
743
+ };
744
+ continue;
745
+ }
746
+ lastSkippedReason = null;
606
747
  lastError = validation.error;
607
748
  const cacheStatus = response.headers.get("CF-Cache-Status")?.trim().toUpperCase();
608
749
  lastRetryable = options.requireCacheHit && ADMITTED_CF_CACHE_STATUSES.has(cacheStatus ?? "") && !REUSABLE_CF_CACHE_STATUSES.has(cacheStatus ?? "") || shouldRetryValidationFailure(response, target, options);
609
750
  if (!lastRetryable) break;
610
751
  } catch (error) {
752
+ lastSkippedReason = null;
611
753
  lastRetryable = true;
612
- if (error instanceof DOMException && error.name === "AbortError") lastError = options.deadlineAt !== void 0 && Date.now() >= options.deadlineAt ? phaseDeadlineError() : `timed out after ${attemptTimeoutMs}ms`;
613
- else lastError = error instanceof Error ? error.message : String(error);
754
+ if (error instanceof DOMException && error.name === "AbortError") {
755
+ if (phaseLimitedAttempt) return {
756
+ path: target.label,
757
+ ok: false,
758
+ error: phaseDeadlineError(),
759
+ retryable: false
760
+ };
761
+ lastError = `timed out after ${attemptTimeoutMs}ms`;
762
+ } else lastError = error instanceof Error ? error.message : String(error);
614
763
  }
615
764
  if (!canRetry(attempt)) break;
616
765
  if (!await waitBeforeRetry()) return {
@@ -620,11 +769,16 @@ async function warmOnePath(target, options) {
620
769
  retryable: false
621
770
  };
622
771
  }
623
- return {
772
+ return lastSkippedReason === null ? {
624
773
  path: target.label,
625
774
  ok: false,
626
775
  error: lastError,
627
776
  retryable: lastRetryable
777
+ } : {
778
+ path: target.label,
779
+ ok: true,
780
+ skipped: true,
781
+ reason: lastSkippedReason
628
782
  };
629
783
  }
630
784
  async function runWithConcurrency(items, concurrency, fn) {
@@ -677,7 +831,8 @@ async function warmCdnCache(options) {
677
831
  rscPaths: []
678
832
  }
679
833
  };
680
- console.log(`\n Warming CDN cache with ${requests.length} discovered request(s)...`);
834
+ console.log(`\n Warming ${formatCount(requests.length, "CDN cache entry", "CDN cache entries")}...`);
835
+ printCdnWarmRouteReport(requests);
681
836
  const progress = new CdnOperationProgress();
682
837
  let completedRequests = 0;
683
838
  progress.update(0, requests.length, "starting warmup");
@@ -697,7 +852,9 @@ async function warmCdnCache(options) {
697
852
  retryDelayMs: isPropagationRequest ? propagationRetryDelayMs : normalRetryDelayMs,
698
853
  retryNotFound: isPropagationRequest,
699
854
  phaseTimeoutMs,
700
- requireCacheHit: options.requireCacheHit === true
855
+ requireCacheHit: options.requireCacheHit === true,
856
+ statusSource: options.statusSource ?? "cloudflare",
857
+ retrySkipped: isPropagationRequest && options.retrySkippedTargetKeys?.has(cdnWarmTargetKey(target)) === true
701
858
  });
702
859
  };
703
860
  const warmRequest = async (target, retryMode = "normal") => {
@@ -708,24 +865,24 @@ async function warmCdnCache(options) {
708
865
  };
709
866
  const warmPropagatingPass = async (targets) => {
710
867
  const results = await runWithConcurrency(targets, concurrency, (target) => warmRequest(target, "propagation-pass"));
711
- const retryableFailed = targets.map((target, index) => ({
868
+ const retryable = targets.map((target, index) => ({
712
869
  index,
713
870
  result: results[index],
714
871
  target
715
- })).filter((entry) => !entry.result.ok).filter(({ result }) => result.retryable);
716
- if (retryableFailed.length === 0 || propagationRetries === 0) return results;
872
+ })).filter(({ result, target }) => result.ok ? result.skipped && options.retrySkippedTargetKeys?.has(cdnWarmTargetKey(target)) === true : result.retryable);
873
+ if (retryable.length === 0 || propagationRetries === 0) return results;
717
874
  progress.finish();
718
- console.log(` CDN warmup: retrying ${retryableFailed.length} failed request(s) after completing the initial pass...`);
875
+ console.log(` CDN warmup: retrying ${retryable.length} unresolved request(s) after completing the initial pass...`);
719
876
  let completedRetries = 0;
720
- progress.update(0, retryableFailed.length, "starting retry pass", "Retrying CDN cache");
721
- const retried = await runWithConcurrency(retryableFailed.map(({ target }) => target), concurrency, async (target) => {
877
+ progress.update(0, retryable.length, "starting retry pass", "Retrying CDN cache");
878
+ const retried = await runWithConcurrency(retryable.map(({ target }) => target), concurrency, async (target) => {
722
879
  const result = await warmTarget(target, "propagation-retry");
723
880
  completedRetries++;
724
- progress.update(completedRetries, retryableFailed.length, target.label, "Retrying CDN cache");
881
+ progress.update(completedRetries, retryable.length, target.label, "Retrying CDN cache");
725
882
  return result;
726
883
  });
727
884
  progress.finish();
728
- for (const [retryIndex, { index }] of retryableFailed.entries()) results[index] = retried[retryIndex];
885
+ for (const [retryIndex, { index }] of retryable.entries()) results[index] = retried[retryIndex];
729
886
  return results;
730
887
  };
731
888
  let results;
@@ -752,6 +909,7 @@ async function warmCdnCache(options) {
752
909
  const warmed = results.length - failures.length - skippedResults.length;
753
910
  const warmedRouteHandlerPaths = warmedRequests.filter((target) => target.kind === "app-route").map((target) => target.sourcePathname);
754
911
  const failedRouteHandlerPaths = failedRequests.filter(({ target }) => target.kind === "app-route").map(({ target }) => target.sourcePathname);
912
+ printCdnWarmRouteReport(requests, results.map((result) => !result.ok ? "failed" : result.skipped ? "skipped" : "warmed"));
755
913
  console.log(` CDN warmup: ${warmed} warmed, ${skippedResults.length} skipped, ${failures.length} failed.`);
756
914
  for (const skipped of skippedResults.slice(0, 5)) console.log(` CDN warmup skipped ${skipped.path}: ${skipped.reason}`);
757
915
  if (failures.length > 0) {
@@ -804,4 +962,4 @@ async function warmCdnCacheFromPrerender(options) {
804
962
  });
805
963
  }
806
964
  //#endregion
807
- export { CdnOperationProgress, DEFAULT_CDN_WARM_CONCURRENCY, DEFAULT_CDN_WARM_TIMEOUT_MS, DEFAULT_STAGED_READINESS_INTERVAL_MS, DEFAULT_STAGED_READINESS_PHASE_TIMEOUT_MS, DEFAULT_STAGED_READINESS_RETRIES, buildWarmupUrl, createCdnWarmTargets, getWarmPathsFromPrerenderManifest, readPrerenderWarmPaths, readPrerenderWarmPlan, waitForCdnWarmTargetReadiness, warmCdnCache, warmCdnCacheFromPrerender };
965
+ export { CdnOperationProgress, DEFAULT_CDN_WARM_CONCURRENCY, DEFAULT_CDN_WARM_TIMEOUT_MS, DEFAULT_STAGED_READINESS_INTERVAL_MS, DEFAULT_STAGED_READINESS_PHASE_TIMEOUT_MS, DEFAULT_STAGED_READINESS_RETRIES, buildWarmupUrl, createCdnWarmTargets, createPrerenderWarmPlan, getWarmPathsFromPrerenderManifest, readPrerenderWarmPaths, readPrerenderWarmPlan, waitForCdnWarmTargetReadiness, warmCdnCache, warmCdnCacheFromPrerender };
@@ -8,7 +8,7 @@ import { VinextCacheConfig } from "vinext/internal/cache-adapters";
8
8
  * Returns true when the config both imports the package and invokes
9
9
  * `cloudflare(...)` in the plugin list.
10
10
  */
11
- declare function viteConfigHasCloudflarePlugin(root: string): boolean;
11
+ export declare function viteConfigHasCloudflarePlugin(root: string): boolean;
12
12
  /**
13
13
  * Detect whether the Vite config assigns a CDN or data cache adapter — i.e. the
14
14
  * `cdn` or `data` field of the `vinext({ cache })` option is given a value.
@@ -17,18 +17,18 @@ declare function viteConfigHasCloudflarePlugin(root: string): boolean;
17
17
  * an unreadable or absent config is treated as configured so a deploy is never
18
18
  * blocked on a false negative.
19
19
  */
20
- declare function viteConfigHasCacheAdapter(root: string): boolean;
21
- type ResolvedKvDataAdapterConfig = {
20
+ export declare function viteConfigHasCacheAdapter(root: string): boolean;
21
+ export type ResolvedKvDataAdapterConfig = {
22
22
  binding: string;
23
23
  appPrefix?: string;
24
24
  ttlSeconds?: number;
25
25
  };
26
- type ResolvedCdnAdapterConfig = {
26
+ export type ResolvedCdnAdapterConfig = {
27
27
  versionMetadataBinding: string;
28
28
  };
29
- declare function resolveCdnAdapterConfig(cache: VinextCacheConfig | null | undefined): ResolvedCdnAdapterConfig | null;
30
- declare function resolveKvDataAdapterConfig(cache: VinextCacheConfig | null | undefined): ResolvedKvDataAdapterConfig | null;
31
- declare function viteConfigHasImageAdapter(root: string): boolean;
29
+ export declare function resolveCdnAdapterConfig(cache: VinextCacheConfig | null | undefined): ResolvedCdnAdapterConfig | null;
30
+ export declare function resolveKvDataAdapterConfig(cache: VinextCacheConfig | null | undefined): ResolvedKvDataAdapterConfig | null;
31
+ export declare function viteConfigHasImageAdapter(root: string): boolean;
32
32
  /**
33
33
  * Detect whether an existing user-authored Worker entry wires up a cache
34
34
  * backend imperatively via one of the `setCacheHandler` / `setDataCacheHandler`
@@ -43,16 +43,15 @@ declare function viteConfigHasImageAdapter(root: string): boolean;
43
43
  * missing Worker entry returns false (nothing to inspect — defer to other
44
44
  * checks).
45
45
  */
46
- declare function workerEntryHasCacheHandler(root: string): boolean;
46
+ export declare function workerEntryHasCacheHandler(root: string): boolean;
47
47
  /**
48
48
  * Build the error thrown when an ISR/cached app is deployed without a cache
49
49
  * adapter configured in the Vite config. Production deployments need a
50
50
  * persistent cache backend; vinext no longer scaffolds one into the Worker
51
51
  * entry, so it must be declared via `vinext({ cache })`.
52
52
  */
53
- declare function formatMissingCacheAdapterError(options: {
53
+ export declare function formatMissingCacheAdapterError(options: {
54
54
  configFile?: string;
55
55
  }): string;
56
- declare function formatImageOptimizationHint(): string;
57
- //#endregion
58
- export { ResolvedCdnAdapterConfig, ResolvedKvDataAdapterConfig, formatImageOptimizationHint, formatMissingCacheAdapterError, resolveCdnAdapterConfig, resolveKvDataAdapterConfig, viteConfigHasCacheAdapter, viteConfigHasCloudflarePlugin, viteConfigHasImageAdapter, workerEntryHasCacheHandler };
56
+ export declare function formatImageOptimizationHint(): string;
57
+ //#endregion