vinext 1.3.1 → 1.4.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.
Files changed (271) hide show
  1. package/README.md +25 -22
  2. package/THIRD_PARTY_LICENSES.md +47 -0
  3. package/dist/_virtual/_rolldown/runtime.js +3 -2
  4. package/dist/build/prerender.js +4 -3
  5. package/dist/build/report.d.ts +0 -14
  6. package/dist/build/report.js +1 -51
  7. package/dist/check.js +4 -7
  8. package/dist/cli.js +3 -0
  9. package/dist/client/dev-error-overlay-store.d.ts +1 -0
  10. package/dist/client/dev-error-overlay.d.ts +2 -0
  11. package/dist/client/dev-error-overlay.js +20 -4
  12. package/dist/client/navigation-runtime.d.ts +13 -1
  13. package/dist/client/navigation-runtime.js +1 -1
  14. package/dist/config/config-matchers.js +2 -0
  15. package/dist/config/destination-params.d.ts +2 -1
  16. package/dist/config/destination-params.js +52 -2
  17. package/dist/config/next-config.d.ts +25 -0
  18. package/dist/config/next-config.js +82 -4
  19. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/dbcs-codec.js +327 -0
  20. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/dbcs-data.js +123 -0
  21. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/index.js +29 -0
  22. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/internal.js +134 -0
  23. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/sbcs-codec.js +50 -0
  24. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/sbcs-data-generated.js +455 -0
  25. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/sbcs-data.js +147 -0
  26. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/big5-added.json.js +169 -0
  27. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/cp936.json.js +2584 -0
  28. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/cp949.json.js +2220 -0
  29. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/cp950.json.js +227 -0
  30. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/eucjp.json.js +425 -0
  31. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/gb18030-ranges.json.js +427 -0
  32. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/gbk-added.json.js +229 -0
  33. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/shiftjis.json.js +292 -0
  34. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/utf16.js +106 -0
  35. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/utf7.js +182 -0
  36. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/lib/bom-handling.js +42 -0
  37. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/lib/extend-node.js +147 -0
  38. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/lib/index.js +94 -0
  39. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/lib/streams.js +95 -0
  40. package/dist/deps/.pnpm/safer-buffer@2.1.2/deps/safer-buffer/safer.js +45 -0
  41. package/dist/entries/app-rsc-entry.js +17 -49
  42. package/dist/entries/app-rsc-manifest.js +3 -4
  43. package/dist/entries/app-ssr-entry.js +1 -0
  44. package/dist/entries/pages-server-entry.js +36 -9
  45. package/dist/index.js +112 -90
  46. package/dist/init-cloudflare.d.ts +1 -3
  47. package/dist/init-cloudflare.js +10 -48
  48. package/dist/init-platform.d.ts +2 -0
  49. package/dist/init-platform.js +4 -0
  50. package/dist/plugins/extensionless-dynamic-import.js +6 -2
  51. package/dist/plugins/next-intl-catalog.d.ts +12 -0
  52. package/dist/plugins/next-intl-catalog.js +85 -0
  53. package/dist/plugins/pages-node-externals.d.ts +1 -0
  54. package/dist/plugins/pages-node-externals.js +1 -1
  55. package/dist/plugins/strip-server-exports.js +2 -1
  56. package/dist/plugins/use-cache-callable.d.ts +1 -1
  57. package/dist/plugins/use-cache-callable.js +136 -94
  58. package/dist/routing/app-route-graph.d.ts +6 -0
  59. package/dist/routing/app-route-graph.js +9 -1
  60. package/dist/server/api-handler.js +21 -5
  61. package/dist/server/app-bfcache-identity.js +1 -1
  62. package/dist/server/app-browser-entry.js +86 -66
  63. package/dist/server/app-browser-history-controller.d.ts +5 -4
  64. package/dist/server/app-browser-history-controller.js +93 -15
  65. package/dist/server/app-browser-navigation-controller.d.ts +2 -2
  66. package/dist/server/app-browser-navigation-controller.js +1 -2
  67. package/dist/server/app-browser-rsc-redirect.js +7 -7
  68. package/dist/server/app-browser-server-action-client.d.ts +2 -0
  69. package/dist/server/app-browser-server-action-client.js +5 -4
  70. package/dist/server/app-browser-state.d.ts +2 -4
  71. package/dist/server/app-browser-state.js +9 -4
  72. package/dist/server/app-browser-supplemental-refresh.js +16 -1
  73. package/dist/server/app-browser-visible-commit.d.ts +1 -1
  74. package/dist/server/app-browser-visible-commit.js +4 -14
  75. package/dist/server/app-elements-wire.d.ts +6 -38
  76. package/dist/server/app-elements-wire.js +4 -41
  77. package/dist/server/app-elements.d.ts +2 -2
  78. package/dist/server/app-elements.js +2 -2
  79. package/dist/server/app-history-state.d.ts +2 -2
  80. package/dist/server/app-history-state.js +5 -2
  81. package/dist/server/app-mounted-layouts.d.ts +21 -0
  82. package/dist/server/app-mounted-layouts.js +67 -0
  83. package/dist/server/app-optimistic-routing.d.ts +19 -1
  84. package/dist/server/app-optimistic-routing.js +43 -4
  85. package/dist/server/app-page-boundary-render.js +10 -14
  86. package/dist/server/app-page-boundary.js +2 -2
  87. package/dist/server/app-page-cache-finalizer.d.ts +12 -1
  88. package/dist/server/app-page-cache-finalizer.js +70 -29
  89. package/dist/server/app-page-cache.d.ts +13 -1
  90. package/dist/server/app-page-cache.js +31 -9
  91. package/dist/server/app-page-dispatch.d.ts +5 -11
  92. package/dist/server/app-page-dispatch.js +84 -155
  93. package/dist/server/app-page-element-builder.d.ts +2 -2
  94. package/dist/server/app-page-element-builder.js +13 -12
  95. package/dist/server/app-page-execution.d.ts +17 -52
  96. package/dist/server/app-page-execution.js +102 -95
  97. package/dist/server/app-page-head.d.ts +13 -0
  98. package/dist/server/app-page-head.js +44 -16
  99. package/dist/server/app-page-http-access-fallback-metadata.d.ts +1 -0
  100. package/dist/server/app-page-http-access-fallback-metadata.js +2 -2
  101. package/dist/server/app-page-layout-gate.d.ts +35 -0
  102. package/dist/server/app-page-layout-gate.js +50 -0
  103. package/dist/server/app-page-params.d.ts +0 -1
  104. package/dist/server/app-page-params.js +1 -14
  105. package/dist/server/app-page-probe.d.ts +3 -21
  106. package/dist/server/app-page-probe.js +4 -37
  107. package/dist/server/app-page-render.d.ts +2 -13
  108. package/dist/server/app-page-render.js +103 -234
  109. package/dist/server/app-page-request.d.ts +1 -3
  110. package/dist/server/app-page-request.js +1 -1
  111. package/dist/server/app-page-response.js +3 -3
  112. package/dist/server/app-page-route-wiring.d.ts +13 -6
  113. package/dist/server/app-page-route-wiring.js +86 -63
  114. package/dist/server/app-page-rsc-render-status.d.ts +27 -1
  115. package/dist/server/app-page-rsc-render-status.js +121 -13
  116. package/dist/server/app-page-stream.d.ts +12 -8
  117. package/dist/server/app-page-stream.js +4 -3
  118. package/dist/server/app-pages-bridge.d.ts +4 -0
  119. package/dist/server/app-pages-bridge.js +7 -3
  120. package/dist/server/app-render-dependency.d.ts +11 -4
  121. package/dist/server/app-render-dependency.js +86 -38
  122. package/dist/server/app-request-stage-dispatch.js +1 -1
  123. package/dist/server/app-request-stage-independent-entry.js +1 -1
  124. package/dist/server/app-route-handler-cache.js +2 -2
  125. package/dist/server/app-route-handler-dispatch.js +14 -9
  126. package/dist/server/app-route-handler-execution.js +11 -5
  127. package/dist/server/app-route-handler-policy.d.ts +1 -1
  128. package/dist/server/app-route-handler-policy.js +3 -3
  129. package/dist/server/app-route-handler-response.js +1 -1
  130. package/dist/server/app-route-handler-runtime.d.ts +1 -1
  131. package/dist/server/app-route-handler-runtime.js +28 -11
  132. package/dist/server/app-router-entry.js +1 -1
  133. package/dist/server/app-rsc-cache-busting.d.ts +12 -12
  134. package/dist/server/app-rsc-cache-busting.js +31 -72
  135. package/dist/server/app-rsc-error-handler.d.ts +2 -1
  136. package/dist/server/app-rsc-error-handler.js +10 -2
  137. package/dist/server/app-rsc-errors.d.ts +8 -0
  138. package/dist/server/app-rsc-errors.js +11 -1
  139. package/dist/server/app-rsc-handler.d.ts +5 -5
  140. package/dist/server/app-rsc-handler.js +80 -83
  141. package/dist/server/app-rsc-request-normalization.d.ts +10 -16
  142. package/dist/server/app-rsc-request-normalization.js +12 -18
  143. package/dist/server/app-rsc-response-finalizer.js +2 -2
  144. package/dist/server/app-rsc-response-stage.js +9 -15
  145. package/dist/server/app-server-action-execution.d.ts +3 -1
  146. package/dist/server/app-server-action-execution.js +15 -8
  147. package/dist/server/app-ssr-entry.d.ts +8 -0
  148. package/dist/server/app-ssr-entry.js +22 -16
  149. package/dist/server/app-ssr-stream.js +1 -1
  150. package/dist/server/app-visited-response-cache.d.ts +36 -1
  151. package/dist/server/app-visited-response-cache.js +46 -5
  152. package/dist/server/app-worker-stages.d.ts +37 -6
  153. package/dist/server/app-worker-stages.js +81 -9
  154. package/dist/server/artifact-compatibility.d.ts +0 -1
  155. package/dist/server/artifact-compatibility.js +1 -10
  156. package/dist/server/bfcache-identity.d.ts +7 -0
  157. package/dist/server/bfcache-identity.js +10 -1
  158. package/dist/server/cache-proof.d.ts +1 -115
  159. package/dist/server/cache-proof.js +1 -544
  160. package/dist/server/cacheability-manifest.js +1 -2
  161. package/dist/server/cacheability-request.js +13 -8
  162. package/dist/server/dev-origin-check.d.ts +2 -1
  163. package/dist/server/dev-origin-check.js +2 -1
  164. package/dist/server/dev-server.js +6 -4
  165. package/dist/server/headers.d.ts +6 -3
  166. package/dist/server/headers.js +9 -5
  167. package/dist/server/image-optimization.d.ts +5 -0
  168. package/dist/server/image-optimization.js +6 -1
  169. package/dist/server/isr-cache.d.ts +8 -2
  170. package/dist/server/isr-cache.js +30 -2
  171. package/dist/server/metadata-route-response.js +32 -15
  172. package/dist/server/middleware-matcher.js +19 -6
  173. package/dist/server/middleware-runtime.js +6 -2
  174. package/dist/server/multi-stage.d.ts +57 -12
  175. package/dist/server/multi-stage.js +13 -1
  176. package/dist/server/navigation-planner.js +1 -1
  177. package/dist/server/pages-api-route.js +28 -19
  178. package/dist/server/pages-media-type.d.ts +21 -1
  179. package/dist/server/pages-media-type.js +69 -5
  180. package/dist/server/pages-node-compat.d.ts +1 -1
  181. package/dist/server/pages-node-compat.js +54 -27
  182. package/dist/server/pages-page-data.js +2 -1
  183. package/dist/server/pages-page-handler.js +28 -26
  184. package/dist/server/pages-page-response.d.ts +9 -0
  185. package/dist/server/pages-page-response.js +18 -4
  186. package/dist/server/pages-request-pipeline.d.ts +8 -0
  187. package/dist/server/pages-request-pipeline.js +2 -2
  188. package/dist/server/pages-request-stage-entry.js +36 -14
  189. package/dist/server/pages-response-stage-entry.js +9 -3
  190. package/dist/server/pages-router-entry.js +3 -2
  191. package/dist/server/prod-server.d.ts +2 -2
  192. package/dist/server/prod-server.js +47 -9
  193. package/dist/server/request-error-log.d.ts +9 -0
  194. package/dist/server/request-error-log.js +13 -0
  195. package/dist/server/request-pipeline.d.ts +15 -4
  196. package/dist/server/request-pipeline.js +43 -15
  197. package/dist/server/rsc-completion-metadata.js +3 -0
  198. package/dist/server/shared-cache-identity.d.ts +23 -0
  199. package/dist/server/shared-cache-identity.js +36 -0
  200. package/dist/server/static-file-cache.d.ts +9 -0
  201. package/dist/server/static-file-cache.js +13 -2
  202. package/dist/server/worker-stages.d.ts +16 -3
  203. package/dist/server/worker-stages.js +23 -4
  204. package/dist/shims/cache-handler.js +2 -2
  205. package/dist/shims/cache-request-state.d.ts +23 -26
  206. package/dist/shims/cache-request-state.js +22 -57
  207. package/dist/shims/cache-runtime.d.ts +3 -1
  208. package/dist/shims/cache-runtime.js +94 -48
  209. package/dist/shims/cache.d.ts +16 -10
  210. package/dist/shims/cache.js +47 -36
  211. package/dist/shims/cacheability-classification.d.ts +2 -0
  212. package/dist/shims/cdn-cache.d.ts +22 -5
  213. package/dist/shims/client-hook-error.d.ts +2 -0
  214. package/dist/shims/client-hook-error.js +16 -1
  215. package/dist/shims/client-page-root.js +2 -2
  216. package/dist/shims/dynamic.js +9 -6
  217. package/dist/shims/error-boundary.js +2 -2
  218. package/dist/shims/fetch-cache-state.d.ts +5 -1
  219. package/dist/shims/fetch-cache-state.js +1 -3
  220. package/dist/shims/fetch-cache.d.ts +2 -1
  221. package/dist/shims/fetch-cache.js +39 -25
  222. package/dist/shims/form.js +2 -2
  223. package/dist/shims/headers.d.ts +10 -24
  224. package/dist/shims/headers.js +22 -70
  225. package/dist/shims/internal/cache-context-accessor.d.ts +1 -1
  226. package/dist/shims/internal/navigation-untracked.js +1 -1
  227. package/dist/shims/link.js +8 -11
  228. package/dist/shims/metadata.d.ts +23 -21
  229. package/dist/shims/metadata.js +62 -24
  230. package/dist/shims/navigation-server.js +1 -1
  231. package/dist/shims/navigation.d.ts +74 -7
  232. package/dist/shims/navigation.js +184 -31
  233. package/dist/shims/navigation.react-server.js +2 -2
  234. package/dist/shims/request-state-types.d.ts +3 -2
  235. package/dist/shims/slot.d.ts +16 -0
  236. package/dist/shims/slot.js +44 -9
  237. package/dist/shims/unified-request-context.d.ts +7 -1
  238. package/dist/shims/unified-request-context.js +3 -3
  239. package/dist/utils/cache-control-metadata.d.ts +5 -0
  240. package/dist/utils/cache-control-metadata.js +9 -1
  241. package/dist/utils/cache-life-profiles.d.ts +33 -0
  242. package/dist/utils/cache-life-profiles.js +111 -0
  243. package/dist/utils/middleware-request-headers.d.ts +14 -3
  244. package/dist/utils/middleware-request-headers.js +54 -7
  245. package/dist/utils/project.d.ts +2 -2
  246. package/dist/utils/project.js +3 -16
  247. package/dist/utils/regex.d.ts +5 -0
  248. package/dist/utils/regex.js +11 -1
  249. package/dist/utils/text-stream.d.ts +10 -5
  250. package/dist/utils/text-stream.js +6 -6
  251. package/package.json +2 -1
  252. package/dist/build/layout-classification-types.d.ts +0 -60
  253. package/dist/build/layout-classification-types.js +0 -1
  254. package/dist/build/layout-classification.d.ts +0 -62
  255. package/dist/build/layout-classification.js +0 -98
  256. package/dist/build/route-classification-injector.d.ts +0 -33
  257. package/dist/build/route-classification-injector.js +0 -59
  258. package/dist/build/route-classification-manifest.d.ts +0 -54
  259. package/dist/build/route-classification-manifest.js +0 -143
  260. package/dist/server/app-browser-client-reuse-manifest.d.ts +0 -11
  261. package/dist/server/app-browser-client-reuse-manifest.js +0 -101
  262. package/dist/server/app-layout-param-observation.d.ts +0 -42
  263. package/dist/server/app-layout-param-observation.js +0 -168
  264. package/dist/server/client-reuse-manifest.d.ts +0 -103
  265. package/dist/server/client-reuse-manifest.js +0 -209
  266. package/dist/server/skip-cache-proof.d.ts +0 -60
  267. package/dist/server/skip-cache-proof.js +0 -168
  268. package/dist/server/static-layout-client-reuse-proof.d.ts +0 -14
  269. package/dist/server/static-layout-client-reuse-proof.js +0 -33
  270. package/dist/utils/sorted-array.d.ts +0 -8
  271. package/dist/utils/sorted-array.js +0 -20
@@ -3,6 +3,15 @@
3
3
  export declare const CONTENT_TYPES: Record<string, string>;
4
4
  /** Resolve a path's MIME type with case-insensitive extension matching. */
5
5
  export declare function contentTypeForPath(filePath: string): string;
6
+ /**
7
+ * Default `Cache-Control` for a file in the client build directory. Hashed
8
+ * build assets never change at their URL. Every other file (`public/`) must be
9
+ * revalidated on each reuse, as Next.js's `send` serves it with `max-age=0`:
10
+ * middleware may admit it per request, so a shared cache must not reuse it
11
+ * without asking the origin. A `Cache-Control` set by middleware or config
12
+ * headers replaces this default.
13
+ */
14
+ export declare function staticFileCacheControl(isHashed: boolean): string;
6
15
  /** A servable file variant with pre-computed response headers. */
7
16
  type FileVariant = {
8
17
  /** Absolute file path (used for streaming large files). */
@@ -57,6 +57,17 @@ function contentTypeForPath(filePath) {
57
57
  return CONTENT_TYPES[path.extname(filePath).toLowerCase()] ?? "application/octet-stream";
58
58
  }
59
59
  /**
60
+ * Default `Cache-Control` for a file in the client build directory. Hashed
61
+ * build assets never change at their URL. Every other file (`public/`) must be
62
+ * revalidated on each reuse, as Next.js's `send` serves it with `max-age=0`:
63
+ * middleware may admit it per request, so a shared cache must not reuse it
64
+ * without asking the origin. A `Cache-Control` set by middleware or config
65
+ * headers replaces this default.
66
+ */
67
+ function staticFileCacheControl(isHashed) {
68
+ return isHashed ? "public, max-age=31536000, immutable" : "public, max-age=0";
69
+ }
70
+ /**
60
71
  * Files below this size are buffered in memory at startup for zero-syscall
61
72
  * serving via res.end(buffer). Above this, files stream via createReadStream.
62
73
  * 64KB covers virtually all precompressed assets (a 200KB JS bundle compresses
@@ -98,7 +109,7 @@ var StaticFileCache = class StaticFileCache {
98
109
  if (isHashed && PRECOMPRESSION_TEMP_FILE_RE.test(relativePath)) continue;
99
110
  const ext = path.extname(relativePath);
100
111
  const contentType = contentTypeForPath(relativePath);
101
- const cacheControl = isHashed ? "public, max-age=31536000, immutable" : "public, max-age=3600";
112
+ const cacheControl = staticFileCacheControl(isHashed);
102
113
  const etag = isHashed && etagFromFilenameHash(relativePath, ext) || `W/"${fileInfo.size}-${Math.floor(fileInfo.mtimeMs / 1e3)}"`;
103
114
  const lastModified = new Date(fileInfo.mtimeMs).toUTCString();
104
115
  const baseHeaders = {
@@ -266,4 +277,4 @@ async function* walkFilesWithStats(dir, base = dir) {
266
277
  }
267
278
  }
268
279
  //#endregion
269
- export { CONTENT_TYPES, StaticFileCache, contentTypeForPath, etagFromFilenameHash };
280
+ export { CONTENT_TYPES, StaticFileCache, contentTypeForPath, etagFromFilenameHash, staticFileCacheControl };
@@ -1,7 +1,7 @@
1
- import { VinextResponseStageCacheability, VinextResponseStageTransport } from "./multi-stage.js";
1
+ import { VinextResponseStageCacheability, VinextResponseStageDispatchOptions, VinextResponseStageTransport } from "./multi-stage.js";
2
2
  import { PagesRenderOptions } from "./pages-request-pipeline.js";
3
3
  //#region src/server/worker-stages.d.ts
4
- export declare const PAGES_RESPONSE_STAGE_PROTOCOL_VERSION = 5;
4
+ export declare const PAGES_RESPONSE_STAGE_PROTOCOL_VERSION = 6;
5
5
  export declare const PAGES_RESPONSE_STAGE_POLICY_OWNER_HEADER = "x-vinext-pages-response-stage-policy-owner";
6
6
  export type PagesResponseStagePolicyOwner = "request-time" | "static";
7
7
  type PagesResponseStageEnvelope = {
@@ -14,10 +14,16 @@ type PagesResponseStageEnvelope = {
14
14
  stagedHeaders: Array<[string, string]> | null;
15
15
  };
16
16
  /** Serializable Pages page render delegated to a cacheable Worker stage. */
17
- type PagesPageResponseStageProps = PagesResponseStageEnvelope & {
17
+ export type PagesPageResponseStageProps = PagesResponseStageEnvelope & {
18
18
  kind: "pages-page";
19
19
  renderOptions: PagesRenderOptions | null;
20
20
  resolvedUrl: string;
21
+ /**
22
+ * The shared cache entry answers every host, as Next.js keys a static page
23
+ * by its path, so a getInitialProps render of a page without
24
+ * getStaticProps, which reads the request, is not stored.
25
+ */
26
+ sharedAcrossHosts: boolean;
21
27
  };
22
28
  /** Serializable Pages API dispatch delegated to a cacheable Worker stage. */
23
29
  type PagesApiResponseStageProps = PagesResponseStageEnvelope & {
@@ -39,6 +45,13 @@ export type WorkerResponseStageProps = PagesApiResponseStageProps | PagesPageRes
39
45
  * response as Next.js.
40
46
  */
41
47
  export type DispatchWorkerResponseStage = VinextResponseStageTransport<WorkerResponseStageProps>;
48
+ type PagesPageResponseStageCacheIdentity = NonNullable<VinextResponseStageDispatchOptions["cacheIdentity"]>;
49
+ /**
50
+ * Build the cache identity of a shared Pages page dispatch: the dispatched
51
+ * request and props under `origin`, so every host that names it shares one
52
+ * entry.
53
+ */
54
+ export declare function createSharedPagesPageCacheIdentity(request: Request, props: PagesPageResponseStageProps, origin: string): PagesPageResponseStageCacheIdentity;
42
55
  export declare function isPagesResponseStageProps(value: unknown): value is WorkerResponseStageProps;
43
56
  //#endregion
44
57
  export {};
@@ -1,6 +1,25 @@
1
+ import { withCacheIdentityOrigin } from "./multi-stage.js";
1
2
  //#region src/server/worker-stages.ts
2
- const PAGES_RESPONSE_STAGE_PROTOCOL_VERSION = 5;
3
+ const PAGES_RESPONSE_STAGE_PROTOCOL_VERSION = 6;
3
4
  const PAGES_RESPONSE_STAGE_POLICY_OWNER_HEADER = "x-vinext-pages-response-stage-policy-owner";
5
+ /**
6
+ * Build the cache identity of a shared Pages page dispatch: the dispatched
7
+ * request and props under `origin`, so every host that names it shares one
8
+ * entry.
9
+ */
10
+ function createSharedPagesPageCacheIdentity(request, props, origin) {
11
+ return {
12
+ props: {
13
+ ...props,
14
+ requestHost: new URL(origin).host
15
+ },
16
+ regenerateFromDispatch: true,
17
+ request: new Request(withCacheIdentityOrigin(request.url, origin), {
18
+ headers: new Headers(request.headers),
19
+ method: request.method
20
+ })
21
+ };
22
+ }
4
23
  function isSerializedHeaders(value) {
5
24
  return Array.isArray(value) && value.every((entry) => Array.isArray(entry) && entry.length === 2 && typeof entry[0] === "string" && typeof entry[1] === "string");
6
25
  }
@@ -12,14 +31,14 @@ function isResponseStageCacheability(value) {
12
31
  function isPagesResponseStageProps(value) {
13
32
  if (!value || typeof value !== "object") return false;
14
33
  const props = value;
15
- if (props.protocolVersion !== 5 || props.buildId !== null && typeof props.buildId !== "string" || !isResponseStageCacheability(props.cacheability) || typeof props.requestHost !== "string" || props.requestHost.length === 0 || props.stagedHeaders !== null && !isSerializedHeaders(props.stagedHeaders)) return false;
34
+ if (props.protocolVersion !== 6 || props.buildId !== null && typeof props.buildId !== "string" || !isResponseStageCacheability(props.cacheability) || typeof props.requestHost !== "string" || props.requestHost.length === 0 || props.stagedHeaders !== null && !isSerializedHeaders(props.stagedHeaders)) return false;
16
35
  if (props.kind === "pages-api") return typeof props.apiUrl === "string";
17
36
  if (props.kind === "pages-prerender-discovery") return true;
18
- if (props.kind !== "pages-page" || typeof props.resolvedUrl !== "string") return false;
37
+ if (props.kind !== "pages-page" || typeof props.resolvedUrl !== "string" || typeof props.sharedAcrossHosts !== "boolean") return false;
19
38
  if (props.renderOptions === null) return true;
20
39
  if (!props.renderOptions || typeof props.renderOptions !== "object") return false;
21
40
  const options = props.renderOptions;
22
41
  return (options.isDataReq === void 0 || typeof options.isDataReq === "boolean") && (options.renderErrorPageOnMiss === void 0 || typeof options.renderErrorPageOnMiss === "boolean") && (options.originalUrl === void 0 || typeof options.originalUrl === "string");
23
42
  }
24
43
  //#endregion
25
- export { PAGES_RESPONSE_STAGE_POLICY_OWNER_HEADER, PAGES_RESPONSE_STAGE_PROTOCOL_VERSION, isPagesResponseStageProps };
44
+ export { PAGES_RESPONSE_STAGE_POLICY_OWNER_HEADER, PAGES_RESPONSE_STAGE_PROTOCOL_VERSION, createSharedPagesPageCacheIdentity, isPagesResponseStageProps };
@@ -1,5 +1,5 @@
1
1
  import { shareIsolatePromise } from "../server/isolate-shared-promise.js";
2
- import { readCacheControlNumberField, readCacheControlRevalidateField } from "../utils/cache-control-metadata.js";
2
+ import { readCacheControlNumberField, readCacheControlRevalidateField, readCacheTimestamp } from "../utils/cache-control-metadata.js";
3
3
  //#region src/shims/cache-handler.ts
4
4
  var NoOpCacheHandler = class {
5
5
  async get(_key, _ctx) {
@@ -122,7 +122,7 @@ var MemoryCacheHandler = class {
122
122
  if (data && "revalidate" in data && typeof data.revalidate === "number") effectiveRevalidate = data.revalidate;
123
123
  else if (data && "revalidate" in data && data.revalidate === false) effectiveRevalidate ??= false;
124
124
  if (effectiveRevalidate === 0) return;
125
- const now = Date.now();
125
+ const now = readCacheTimestamp(ctx, Date.now());
126
126
  const revalidateAt = typeof effectiveRevalidate === "number" && effectiveRevalidate > 0 ? now + effectiveRevalidate * 1e3 : null;
127
127
  const expireAt = typeof effectiveExpire === "number" && effectiveExpire > 0 ? now + effectiveExpire * 1e3 : null;
128
128
  const cacheControl = typeof effectiveRevalidate === "number" || effectiveRevalidate === false ? {
@@ -1,28 +1,13 @@
1
+ import { CacheLifeConfig } from "../utils/cache-life-profiles.js";
1
2
  import { _recordUseCacheRootParamRead, _registerCacheContextAccessor, getRegisteredCacheContext } from "./internal/cache-context-accessor.js";
2
3
  //#region src/shims/cache-request-state.d.ts
3
- export type CacheLifeConfig = {
4
- stale?: number;
5
- revalidate?: number;
6
- expire?: number;
7
- };
4
+ /**
5
+ * The built-in profiles merged with next.config `cacheLife`, baked in at
6
+ * build time like Next.js's `process.env.__NEXT_CACHE_LIFE` define.
7
+ */
8
8
  export declare const cacheLifeProfiles: Record<string, CacheLifeConfig>;
9
9
  export type UnstableCacheRevalidationMode = "foreground" | "background";
10
10
  export type ActionRevalidationKind = 0 | 1 | 2;
11
- export type UnstableCacheObservation = Readonly<{
12
- kind: "unstable_cache";
13
- keyHash: string;
14
- revalidate: number | false | null;
15
- tagCount: number;
16
- tagHash: string | null;
17
- }>;
18
- /**
19
- * Collects the cacheLife claims made anywhere below the scope that installed
20
- * it, including nested scopes that reset `requestScopedCacheLife`. Shallow
21
- * scope clones share it by reference.
22
- */
23
- export type CacheLifeSink = {
24
- cacheLife: CacheLifeConfig | null;
25
- };
26
11
  type TagInvalidationDurations = {
27
12
  expire?: number;
28
13
  } | undefined;
@@ -34,12 +19,17 @@ export type PendingCdnTagInvalidation = Readonly<{
34
19
  }>;
35
20
  export type CacheState = {
36
21
  actionRevalidationKind: ActionRevalidationKind;
37
- cacheLifeSink: CacheLifeSink | null;
22
+ /**
23
+ * The request is an authorized on-demand revalidation (`res.revalidate()`).
24
+ * Like Next.js's `workStore.isOnDemandRevalidate`, the data caches then skip
25
+ * their reads but still execute and store fresh results. Set once when the
26
+ * request context is created; nested scopes inherit it.
27
+ */
28
+ isOnDemandRevalidate: boolean;
38
29
  pendingCdnTagInvalidations: PendingCdnTagInvalidation[];
39
30
  pendingRevalidatedTags: Set<string>;
40
31
  pendingRevalidations: Set<Promise<void>>;
41
32
  requestScopedCacheLife: CacheLifeConfig | null;
42
- unstableCacheObservations: Map<string, UnstableCacheObservation>;
43
33
  unstableCacheRevalidation: UnstableCacheRevalidationMode;
44
34
  };
45
35
  export declare const ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC = 1;
@@ -47,6 +37,15 @@ export declare const ACTION_DID_REVALIDATE_DYNAMIC_ONLY = 2;
47
37
  export declare function _runWithCacheState<T>(fn: () => Promise<T>): Promise<T>;
48
38
  export declare function _runWithCacheState<T>(fn: () => T | Promise<T>): T | Promise<T>;
49
39
  export declare function _initRequestScopedCacheState(): void;
40
+ /**
41
+ * Whether the current request is an authorized on-demand revalidation, so the
42
+ * data caches must skip their reads (not their writes). Mirrors Next.js's
43
+ * `workStore.isOnDemandRevalidate` checks in use-cache-wrapper, patch-fetch
44
+ * and unstable-cache.
45
+ *
46
+ * @internal
47
+ */
48
+ export declare function _isOnDemandRevalidate(): boolean;
50
49
  export declare function markActionRevalidation(kind: ActionRevalidationKind): void;
51
50
  export declare function getAndClearActionRevalidationKind(): ActionRevalidationKind;
52
51
  /** @internal */
@@ -114,14 +113,12 @@ export declare function _captureRequestScopedCacheLifeAccessors(): {
114
113
  consume: () => CacheLifeConfig | null;
115
114
  peek: () => CacheLifeConfig | null;
116
115
  };
117
- export declare function recordUnstableCacheObservation(observation: UnstableCacheObservation): void;
118
- export declare function _peekUnstableCacheObservations(): UnstableCacheObservation[];
119
116
  /**
120
117
  * Run `fn` with the request's cache settings, including its revalidation mode,
121
- * but its own record of cache lives and unstable_cache observations, so work
118
+ * but its own record of cache lives, so work
122
119
  * done on the request's behalf after the fact leaves the request untouched.
123
120
  */
124
121
  export declare function runWithDetachedCacheObservations<T>(fn: () => Promise<T>): Promise<T>;
125
122
  export declare function shouldServeStaleUnstableCacheEntry(): boolean;
126
123
  //#endregion
127
- export { _recordUseCacheRootParamRead, _registerCacheContextAccessor, getRegisteredCacheContext };
124
+ export { type CacheLifeConfig, _recordUseCacheRootParamRead, _registerCacheContextAccessor, getRegisteredCacheContext };
@@ -1,45 +1,15 @@
1
1
  import { getOrCreateAls } from "./internal/als-registry.js";
2
2
  import { getRequestContext, isInsideUnifiedScope, runWithUnifiedStateMutation } from "./unified-request-context.js";
3
+ import { parseCacheLifeProfiles } from "../utils/cache-life-profiles.js";
3
4
  import { getCdnCacheAdapter } from "./cdn-cache.js";
4
5
  import { getHeadersAccessPhase } from "./internal/headers-state.js";
5
6
  import { _recordUseCacheRootParamRead, _registerCacheContextAccessor, getRegisteredCacheContext } from "./internal/cache-context-accessor.js";
6
7
  //#region src/shims/cache-request-state.ts
7
- const cacheLifeProfiles = {
8
- default: {
9
- revalidate: 900,
10
- expire: 4294967294
11
- },
12
- seconds: {
13
- stale: 30,
14
- revalidate: 1,
15
- expire: 60
16
- },
17
- minutes: {
18
- stale: 300,
19
- revalidate: 60,
20
- expire: 3600
21
- },
22
- hours: {
23
- stale: 300,
24
- revalidate: 3600,
25
- expire: 86400
26
- },
27
- days: {
28
- stale: 300,
29
- revalidate: 86400,
30
- expire: 604800
31
- },
32
- weeks: {
33
- stale: 300,
34
- revalidate: 604800,
35
- expire: 2592e3
36
- },
37
- max: {
38
- stale: 300,
39
- revalidate: 2592e3,
40
- expire: 31536e3
41
- }
42
- };
8
+ /**
9
+ * The built-in profiles merged with next.config `cacheLife`, baked in at
10
+ * build time like Next.js's `process.env.__NEXT_CACHE_LIFE` define.
11
+ */
12
+ const cacheLifeProfiles = parseCacheLifeProfiles(process.env.__VINEXT_CACHE_LIFE_PROFILES);
43
13
  const FALLBACK_KEY = Symbol.for("vinext.cache.fallback");
44
14
  const globalState = globalThis;
45
15
  const cacheAls = getOrCreateAls("vinext.cache.als");
@@ -48,12 +18,11 @@ const ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC = 1;
48
18
  const ACTION_DID_REVALIDATE_DYNAMIC_ONLY = 2;
49
19
  const fallbackState = globalState[FALLBACK_KEY] ??= {
50
20
  actionRevalidationKind: ACTION_DID_NOT_REVALIDATE,
51
- cacheLifeSink: null,
21
+ isOnDemandRevalidate: false,
52
22
  pendingCdnTagInvalidations: [],
53
23
  pendingRevalidatedTags: /* @__PURE__ */ new Set(),
54
24
  pendingRevalidations: /* @__PURE__ */ new Set(),
55
25
  requestScopedCacheLife: null,
56
- unstableCacheObservations: /* @__PURE__ */ new Map(),
57
26
  unstableCacheRevalidation: "foreground"
58
27
  };
59
28
  function getCacheState() {
@@ -63,19 +32,16 @@ function getCacheState() {
63
32
  function _runWithCacheState(fn) {
64
33
  if (isInsideUnifiedScope()) return runWithUnifiedStateMutation((context) => {
65
34
  context.actionRevalidationKind = ACTION_DID_NOT_REVALIDATE;
66
- context.cacheLifeSink = null;
67
35
  context.requestScopedCacheLife = null;
68
- context.unstableCacheObservations = /* @__PURE__ */ new Map();
69
36
  context.unstableCacheRevalidation = "foreground";
70
37
  }, fn);
71
38
  const state = {
72
39
  actionRevalidationKind: ACTION_DID_NOT_REVALIDATE,
73
- cacheLifeSink: null,
40
+ isOnDemandRevalidate: false,
74
41
  pendingCdnTagInvalidations: [],
75
42
  pendingRevalidatedTags: /* @__PURE__ */ new Set(),
76
43
  pendingRevalidations: /* @__PURE__ */ new Set(),
77
44
  requestScopedCacheLife: null,
78
- unstableCacheObservations: /* @__PURE__ */ new Map(),
79
45
  unstableCacheRevalidation: "foreground"
80
46
  };
81
47
  return cacheAls.run(state, fn);
@@ -84,7 +50,17 @@ function _initRequestScopedCacheState() {
84
50
  const state = getCacheState();
85
51
  state.actionRevalidationKind = ACTION_DID_NOT_REVALIDATE;
86
52
  state.requestScopedCacheLife = null;
87
- state.unstableCacheObservations = /* @__PURE__ */ new Map();
53
+ }
54
+ /**
55
+ * Whether the current request is an authorized on-demand revalidation, so the
56
+ * data caches must skip their reads (not their writes). Mirrors Next.js's
57
+ * `workStore.isOnDemandRevalidate` checks in use-cache-wrapper, patch-fetch
58
+ * and unstable-cache.
59
+ *
60
+ * @internal
61
+ */
62
+ function _isOnDemandRevalidate() {
63
+ return getCacheState().isOnDemandRevalidate === true;
88
64
  }
89
65
  function markActionRevalidation(kind) {
90
66
  if (getHeadersAccessPhase() !== "action") return;
@@ -224,7 +200,6 @@ function mergeCacheLife(current, config) {
224
200
  function _setRequestScopedCacheLife(config) {
225
201
  const state = getCacheState();
226
202
  state.requestScopedCacheLife = mergeCacheLife(state.requestScopedCacheLife, config);
227
- if (state.cacheLifeSink) state.cacheLifeSink.cacheLife = mergeCacheLife(state.cacheLifeSink.cacheLife, config);
228
203
  }
229
204
  function _peekRequestScopedCacheLife() {
230
205
  const config = getCacheState().requestScopedCacheLife;
@@ -257,32 +232,22 @@ function _captureRequestScopedCacheLifeAccessors() {
257
232
  }
258
233
  };
259
234
  }
260
- function recordUnstableCacheObservation(observation) {
261
- getCacheState().unstableCacheObservations.set(observation.keyHash, observation);
262
- }
263
- function _peekUnstableCacheObservations() {
264
- return [...getCacheState().unstableCacheObservations.values()].sort((a, b) => a.keyHash.localeCompare(b.keyHash));
265
- }
266
235
  /**
267
236
  * Run `fn` with the request's cache settings, including its revalidation mode,
268
- * but its own record of cache lives and unstable_cache observations, so work
237
+ * but its own record of cache lives, so work
269
238
  * done on the request's behalf after the fact leaves the request untouched.
270
239
  */
271
240
  function runWithDetachedCacheObservations(fn) {
272
241
  if (isInsideUnifiedScope()) return runWithUnifiedStateMutation((context) => {
273
- context.cacheLifeSink = null;
274
242
  context.requestScopedCacheLife = null;
275
- context.unstableCacheObservations = /* @__PURE__ */ new Map();
276
243
  }, fn);
277
244
  return cacheAls.run({
278
245
  ...getCacheState(),
279
- cacheLifeSink: null,
280
- requestScopedCacheLife: null,
281
- unstableCacheObservations: /* @__PURE__ */ new Map()
246
+ requestScopedCacheLife: null
282
247
  }, fn);
283
248
  }
284
249
  function shouldServeStaleUnstableCacheEntry() {
285
250
  return getCacheState().unstableCacheRevalidation === "background";
286
251
  }
287
252
  //#endregion
288
- export { ACTION_DID_REVALIDATE_DYNAMIC_ONLY, ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC, _captureRequestScopedCacheLifeAccessors, _consumeRequestScopedCacheLife, _drainPendingRevalidations, _hasPendingRevalidatedTag, _initRequestScopedCacheState, _markPendingRevalidatedTag, _peekRequestScopedCacheLife, _peekUnstableCacheObservations, _queuePendingCdnTagInvalidation, _queuePendingRevalidation, _recordUseCacheRootParamRead, _registerCacheContextAccessor, _revalidateCdnTags, _runWithCacheState, _setRequestScopedCacheLife, cacheLifeProfiles, getAndClearActionRevalidationKind, getRegisteredCacheContext, markActionRevalidation, recordUnstableCacheObservation, runWithDetachedCacheObservations, shouldServeStaleUnstableCacheEntry };
253
+ export { ACTION_DID_REVALIDATE_DYNAMIC_ONLY, ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC, _captureRequestScopedCacheLifeAccessors, _consumeRequestScopedCacheLife, _drainPendingRevalidations, _hasPendingRevalidatedTag, _initRequestScopedCacheState, _isOnDemandRevalidate, _markPendingRevalidatedTag, _peekRequestScopedCacheLife, _queuePendingCdnTagInvalidation, _queuePendingRevalidation, _recordUseCacheRootParamRead, _registerCacheContextAccessor, _revalidateCdnTags, _runWithCacheState, _setRequestScopedCacheLife, cacheLifeProfiles, getAndClearActionRevalidationKind, getRegisteredCacheContext, markActionRevalidation, runWithDetachedCacheObservations, shouldServeStaleUnstableCacheEntry };
@@ -1,4 +1,4 @@
1
- import { CacheLifeConfig } from "./cache-request-state.js";
1
+ import { CacheLifeConfig } from "../utils/cache-life-profiles.js";
2
2
  import { CacheFlightArguments } from "./cache-flight-arguments.js";
3
3
  //#region src/shims/cache-runtime.d.ts
4
4
  export declare function replayCachedFunction(fn: object, args: CacheFlightArguments): Promise<unknown>;
@@ -16,6 +16,8 @@ export type CacheContext = {
16
16
  tags: string[];
17
17
  /** Cache life configs collected via cacheLife() — minimum-wins rule applies */
18
18
  lifeConfigs: CacheLifeConfig[];
19
+ /** Resolved lives of nested caches; they only constrain fields cacheLife() left unset */
20
+ nestedLifeConfigs: CacheLifeConfig[];
19
21
  /** Cache variant: "default" | "remote" | "private" */
20
22
  variant: string;
21
23
  /** Root params observed while producing this public cache entry. */