vinext 1.0.0 → 1.1.0

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 (263) hide show
  1. package/README.md +72 -1
  2. package/THIRD_PARTY_LICENSES.md +26 -0
  3. package/dist/build/app-page-static-eligibility.d.ts +15 -0
  4. package/dist/build/app-page-static-eligibility.js +82 -0
  5. package/dist/build/lifecycle.js +10 -10
  6. package/dist/build/pages-client-assets-module.js +6 -1
  7. package/dist/build/precompress.js +1 -1
  8. package/dist/build/prerender-paths.js +6 -85
  9. package/dist/build/prerender.d.ts +8 -1
  10. package/dist/build/prerender.js +167 -46
  11. package/dist/build/run-prerender.js +4 -3
  12. package/dist/build/server-entry.d.ts +2 -0
  13. package/dist/build/server-entry.js +7 -1
  14. package/dist/build/server-manifest.d.ts +7 -0
  15. package/dist/build/server-manifest.js +11 -1
  16. package/dist/cache/cache-adapters-virtual.d.ts +7 -1
  17. package/dist/cache/cache-adapters-virtual.js +3 -3
  18. package/dist/client/browser-globals.d.ts +4 -0
  19. package/dist/client/browser-globals.js +5 -0
  20. package/dist/client/navigation-runtime.d.ts +11 -1
  21. package/dist/client/navigation-runtime.js +3 -3
  22. package/dist/config/config-matchers.js +3 -1
  23. package/dist/config/dotenv.js +14 -3
  24. package/dist/config/next-config.d.ts +7 -0
  25. package/dist/config/next-config.js +18 -3
  26. package/dist/entries/app-rsc-entry.d.ts +2 -0
  27. package/dist/entries/app-rsc-entry.js +67 -45
  28. package/dist/index.d.ts +4 -1
  29. package/dist/index.js +200 -100
  30. package/dist/init-cloudflare.d.ts +1 -1
  31. package/dist/init-cloudflare.js +6 -6
  32. package/dist/init-platform.js +1 -1
  33. package/dist/init.js +4 -2
  34. package/dist/plugins/cache-flight-codec.d.ts +19 -0
  35. package/dist/plugins/cache-flight-codec.js +68 -0
  36. package/dist/plugins/commonjs-esm-facade.d.ts +35 -0
  37. package/dist/plugins/commonjs-esm-facade.js +80 -0
  38. package/dist/plugins/commonjs-syntax.d.ts +16 -0
  39. package/dist/plugins/commonjs-syntax.js +22 -0
  40. package/dist/plugins/fonts.d.ts +8 -11
  41. package/dist/plugins/fonts.js +71 -34
  42. package/dist/plugins/ignore-dynamic-requests.d.ts +11 -0
  43. package/dist/plugins/ignore-dynamic-requests.js +54 -3
  44. package/dist/plugins/import-meta-url.js +6 -6
  45. package/dist/plugins/og-asset-ownership.d.ts +2 -0
  46. package/dist/plugins/og-asset-ownership.js +24 -13
  47. package/dist/plugins/og-assets.d.ts +18 -0
  48. package/dist/plugins/og-assets.js +50 -8
  49. package/dist/plugins/og-harfbuzz.js +38 -27
  50. package/dist/plugins/optimize-imports.js +2 -1
  51. package/dist/plugins/require-context.d.ts +1 -0
  52. package/dist/plugins/require-context.js +28 -1
  53. package/dist/plugins/scan-build-css.d.ts +12 -0
  54. package/dist/plugins/scan-build-css.js +39 -0
  55. package/dist/plugins/strip-server-exports.d.ts +2 -0
  56. package/dist/plugins/strip-server-exports.js +3 -1
  57. package/dist/plugins/transform-result.d.ts +18 -0
  58. package/dist/plugins/transform-result.js +23 -2
  59. package/dist/plugins/typeof-window.d.ts +10 -0
  60. package/dist/plugins/typeof-window.js +33 -9
  61. package/dist/routing/app-route-graph.d.ts +0 -1
  62. package/dist/routing/app-route-graph.js +2 -4
  63. package/dist/routing/app-route-ids.d.ts +3 -0
  64. package/dist/routing/app-route-ids.js +6 -0
  65. package/dist/routing/file-matcher.d.ts +1 -0
  66. package/dist/routing/file-matcher.js +1 -1
  67. package/dist/server/api-handler.js +17 -7
  68. package/dist/server/app-bfcache-id.d.ts +1 -0
  69. package/dist/server/app-bfcache-id.js +7 -1
  70. package/dist/server/app-bfcache-identity.js +1 -2
  71. package/dist/server/app-browser-entry.js +15 -9
  72. package/dist/server/app-browser-history-controller.d.ts +2 -0
  73. package/dist/server/app-browser-history-controller.js +8 -0
  74. package/dist/server/app-browser-hydration.d.ts +1 -1
  75. package/dist/server/app-browser-hydration.js +2 -2
  76. package/dist/server/app-browser-interception-context.js +26 -2
  77. package/dist/server/app-browser-navigation-controller.d.ts +7 -1
  78. package/dist/server/app-browser-navigation-controller.js +94 -11
  79. package/dist/server/app-browser-state.js +1 -1
  80. package/dist/server/app-browser-stream.d.ts +1 -1
  81. package/dist/server/app-fallback-renderer.d.ts +2 -0
  82. package/dist/server/app-fallback-renderer.js +1 -0
  83. package/dist/server/app-history-state.d.ts +3 -1
  84. package/dist/server/app-history-state.js +9 -5
  85. package/dist/server/app-middleware.js +2 -1
  86. package/dist/server/app-optimistic-routing.js +1 -1
  87. package/dist/server/app-page-boundary-render.d.ts +5 -0
  88. package/dist/server/app-page-boundary-render.js +6 -4
  89. package/dist/server/app-page-cache-finalizer.d.ts +11 -0
  90. package/dist/server/app-page-cache-finalizer.js +41 -7
  91. package/dist/server/app-page-cache-render.d.ts +18 -0
  92. package/dist/server/app-page-cache-render.js +65 -44
  93. package/dist/server/app-page-cache.d.ts +5 -0
  94. package/dist/server/app-page-cache.js +27 -7
  95. package/dist/server/app-page-dispatch.d.ts +9 -1
  96. package/dist/server/app-page-dispatch.js +47 -30
  97. package/dist/server/app-page-element-builder.d.ts +7 -0
  98. package/dist/server/app-page-element-builder.js +27 -42
  99. package/dist/server/app-page-execution.d.ts +15 -12
  100. package/dist/server/app-page-execution.js +30 -40
  101. package/dist/server/app-page-head.d.ts +5 -0
  102. package/dist/server/app-page-head.js +9 -3
  103. package/dist/server/app-page-probe.d.ts +0 -109
  104. package/dist/server/app-page-probe.js +3 -136
  105. package/dist/server/app-page-render-identity.d.ts +0 -1
  106. package/dist/server/app-page-render-identity.js +1 -1
  107. package/dist/server/app-page-render-observation.js +2 -2
  108. package/dist/server/app-page-render.d.ts +13 -5
  109. package/dist/server/app-page-render.js +219 -118
  110. package/dist/server/app-page-request.d.ts +0 -1
  111. package/dist/server/app-page-request.js +1 -2
  112. package/dist/server/app-page-response.d.ts +4 -3
  113. package/dist/server/app-page-response.js +4 -3
  114. package/dist/server/app-page-route-wiring.d.ts +17 -5
  115. package/dist/server/app-page-route-wiring.js +55 -33
  116. package/dist/server/app-page-rsc-render-status.d.ts +48 -0
  117. package/dist/server/app-page-rsc-render-status.js +54 -0
  118. package/dist/server/app-page-search-params-observation.js +1 -1
  119. package/dist/server/app-page-stream.d.ts +15 -8
  120. package/dist/server/app-page-stream.js +7 -1
  121. package/dist/server/app-page-tracing.js +2 -1
  122. package/dist/server/app-pages-bridge.js +3 -2
  123. package/dist/server/app-render-abort-error.d.ts +3 -0
  124. package/dist/server/app-render-abort-error.js +8 -0
  125. package/dist/server/app-request-stage-dispatch.js +1 -1
  126. package/dist/server/app-request-stage-independent-entry.js +8 -11
  127. package/dist/server/app-response-header-provenance.d.ts +2 -0
  128. package/dist/server/app-response-header-provenance.js +10 -4
  129. package/dist/server/app-route-handler-cache.d.ts +2 -1
  130. package/dist/server/app-route-handler-cache.js +11 -7
  131. package/dist/server/app-route-handler-dispatch.js +11 -4
  132. package/dist/server/app-route-handler-execution.d.ts +9 -1
  133. package/dist/server/app-route-handler-execution.js +28 -13
  134. package/dist/server/app-route-handler-policy.js +2 -2
  135. package/dist/server/app-route-handler-response.d.ts +1 -1
  136. package/dist/server/app-route-handler-response.js +14 -5
  137. package/dist/server/app-router-entry.d.ts +2 -1
  138. package/dist/server/app-router-entry.js +8 -12
  139. package/dist/server/app-rsc-errors.d.ts +0 -1
  140. package/dist/server/app-rsc-errors.js +2 -6
  141. package/dist/server/app-rsc-handler.d.ts +5 -0
  142. package/dist/server/app-rsc-handler.js +229 -102
  143. package/dist/server/app-rsc-request-normalization.d.ts +4 -2
  144. package/dist/server/app-rsc-request-normalization.js +7 -4
  145. package/dist/server/app-rsc-response-finalizer.js +4 -1
  146. package/dist/server/app-rsc-response-stage.d.ts +1 -1
  147. package/dist/server/app-rsc-response-stage.js +6 -4
  148. package/dist/server/app-rsc-route-matching.d.ts +9 -1
  149. package/dist/server/app-rsc-route-matching.js +37 -20
  150. package/dist/server/app-server-action-execution.d.ts +2 -1
  151. package/dist/server/app-server-action-execution.js +1 -1
  152. package/dist/server/app-ssr-entry.d.ts +3 -2
  153. package/dist/server/app-ssr-entry.js +9 -7
  154. package/dist/server/app-ssr-search-params-gate.js +1 -1
  155. package/dist/server/app-ssr-stream.d.ts +6 -1
  156. package/dist/server/app-ssr-stream.js +35 -16
  157. package/dist/server/app-worker-stages.d.ts +2 -2
  158. package/dist/server/app-worker-stages.js +3 -3
  159. package/dist/server/cache-control.js +3 -11
  160. package/dist/server/cacheability-request.js +56 -52
  161. package/dist/server/config-headers.js +3 -1
  162. package/dist/server/dev-server.js +23 -5
  163. package/dist/server/headers.d.ts +16 -0
  164. package/dist/server/headers.js +19 -1
  165. package/dist/server/http-error-responses.js +1 -0
  166. package/dist/server/image-optimization.d.ts +16 -0
  167. package/dist/server/image-optimization.js +26 -6
  168. package/dist/server/isr-cache.d.ts +2 -0
  169. package/dist/server/isr-cache.js +8 -3
  170. package/dist/server/metadata-route-response.js +94 -37
  171. package/dist/server/middleware-matcher-pattern.js +8 -4
  172. package/dist/server/middleware-response-headers.js +2 -0
  173. package/dist/server/multi-stage.d.ts +8 -0
  174. package/dist/server/navigation-planner.js +1 -1
  175. package/dist/server/node-response-signal.d.ts +16 -0
  176. package/dist/server/node-response-signal.js +26 -0
  177. package/dist/server/open-redirect.d.ts +47 -0
  178. package/dist/server/open-redirect.js +74 -1
  179. package/dist/server/pages-api-route.js +8 -2
  180. package/dist/server/pages-asset-tags.d.ts +1 -0
  181. package/dist/server/pages-asset-tags.js +73 -22
  182. package/dist/server/pages-client-assets.d.ts +2 -0
  183. package/dist/server/pages-page-data.d.ts +6 -1
  184. package/dist/server/pages-page-data.js +71 -65
  185. package/dist/server/pages-page-handler.js +50 -15
  186. package/dist/server/pages-page-response.js +3 -1
  187. package/dist/server/pages-request-pipeline.d.ts +2 -1
  188. package/dist/server/pages-request-pipeline.js +20 -5
  189. package/dist/server/pages-request-stage-entry.js +14 -8
  190. package/dist/server/prerender-manifest.d.ts +6 -0
  191. package/dist/server/prerender-manifest.js +1 -1
  192. package/dist/server/prod-server.d.ts +8 -7
  193. package/dist/server/prod-server.js +152 -78
  194. package/dist/server/request-pipeline.d.ts +20 -8
  195. package/dist/server/request-pipeline.js +21 -7
  196. package/dist/server/response-compression.d.ts +43 -0
  197. package/dist/server/response-compression.js +111 -0
  198. package/dist/server/response-stage-cacheability.js +1 -1
  199. package/dist/server/seed-cache.js +10 -7
  200. package/dist/server/socket-error-backstop.d.ts +14 -0
  201. package/dist/server/socket-error-backstop.js +27 -4
  202. package/dist/server/worker-revalidation-context.d.ts +2 -1
  203. package/dist/server/worker-revalidation-context.js +1 -0
  204. package/dist/server/workers-tracing.d.ts +17 -0
  205. package/dist/server/workers-tracing.js +48 -8
  206. package/dist/shims/cache-adapter-instantiate.d.ts +50 -0
  207. package/dist/shims/cache-adapter-instantiate.js +118 -0
  208. package/dist/shims/cache-callable-runtime.d.ts +2 -40
  209. package/dist/shims/cache-callable-runtime.js +50 -168
  210. package/dist/shims/cache-flight-arguments.d.ts +22 -0
  211. package/dist/shims/cache-flight-arguments.js +56 -0
  212. package/dist/shims/cache-request-state.d.ts +18 -14
  213. package/dist/shims/cache-request-state.js +33 -21
  214. package/dist/shims/cache-runtime.d.ts +6 -19
  215. package/dist/shims/cache-runtime.js +168 -226
  216. package/dist/shims/cache.d.ts +3 -2
  217. package/dist/shims/cache.js +8 -5
  218. package/dist/shims/cacheability-classification.d.ts +8 -1
  219. package/dist/shims/cacheability-classification.js +2 -2
  220. package/dist/shims/cdn-cache.d.ts +10 -1
  221. package/dist/shims/cdn-cache.js +16 -9
  222. package/dist/shims/error-boundary-navigation.d.ts +7 -0
  223. package/dist/shims/error-boundary-navigation.js +19 -1
  224. package/dist/shims/error-boundary.d.ts +10 -10
  225. package/dist/shims/error-boundary.js +26 -7
  226. package/dist/shims/error.d.ts +4 -18
  227. package/dist/shims/error.js +17 -10
  228. package/dist/shims/error.react-server.d.ts +4 -6
  229. package/dist/shims/error.react-server.js +4 -1
  230. package/dist/shims/fetch-cache.d.ts +6 -0
  231. package/dist/shims/fetch-cache.js +23 -4
  232. package/dist/shims/form.js +1 -1
  233. package/dist/shims/headers.d.ts +19 -69
  234. package/dist/shims/headers.js +82 -183
  235. package/dist/shims/internal/app-page-props-cache-key.d.ts +5 -2
  236. package/dist/shims/internal/app-page-props-cache-key.js +24 -15
  237. package/dist/shims/internal/cache-context-accessor.d.ts +16 -0
  238. package/dist/shims/internal/cache-context-accessor.js +15 -0
  239. package/dist/shims/internal/headers-state.d.ts +73 -0
  240. package/dist/shims/internal/headers-state.js +157 -0
  241. package/dist/shims/metadata.js +3 -3
  242. package/dist/shims/navigation-errors.d.ts +6 -0
  243. package/dist/shims/navigation-errors.js +11 -1
  244. package/dist/shims/navigation.d.ts +7 -0
  245. package/dist/shims/navigation.js +16 -6
  246. package/dist/shims/request-context.d.ts +9 -0
  247. package/dist/shims/request-state-types.d.ts +2 -1
  248. package/dist/shims/root-params.js +1 -1
  249. package/dist/shims/server.js +52 -2
  250. package/dist/shims/thenable-params.d.ts +4 -0
  251. package/dist/shims/thenable-params.js +25 -3
  252. package/dist/shims/unified-request-context.d.ts +1 -1
  253. package/dist/shims/unified-request-context.js +1 -0
  254. package/dist/utils/encode-cache-tag.d.ts +1 -0
  255. package/dist/utils/encode-cache-tag.js +11 -1
  256. package/dist/utils/mdx-scan.d.ts +5 -0
  257. package/dist/utils/mdx-scan.js +8 -1
  258. package/dist/utils/regex-safety.d.ts +10 -0
  259. package/dist/utils/regex-safety.js +70 -18
  260. package/dist/utils/vite-cli-invocation.js +8 -1
  261. package/package.json +8 -4
  262. package/dist/server/metadata-route-cache-policy.d.ts +0 -5
  263. package/dist/server/metadata-route-cache-policy.js +0 -6
@@ -6,12 +6,16 @@ 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 { isDraftModeEnabled, markDynamicUsage, throwIfInsideCacheScope } from "./headers.js";
10
- import { _hasPendingRevalidatedTag, _registerCacheContextAccessor, _setRequestScopedCacheLife, cacheLifeProfiles } from "./cache-request-state.js";
11
- import { addCollectedRequestTags, getCurrentFetchSoftTags } from "./fetch-cache.js";
12
- import { makeThenableParams } from "./thenable-params.js";
13
- import { APP_PAGE_USE_CACHE_MARKER, hasUseCachePageMarker, isMarkedAppPagePropsObject, isUseCacheFunctionReference, markAppPagePropsForUseCache } from "./internal/app-page-props-cache-key.js";
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, runWithDetachedCacheObservations, shouldServeStaleUnstableCacheEntry } from "./cache-request-state.js";
13
+ import { addCollectedRequestTags, getCurrentFetchSoftTags, runWithDetachedFetchObservations } from "./fetch-cache.js";
14
+ import { hasUseCacheLayoutMarker, hasUseCachePageMarker, isUseCacheFunctionReference, withoutUseCacheSegmentMarker } from "./internal/app-page-props-cache-key.js";
15
+ import { getFallbackParamsSnapshot, makeThenableParams, restoreThenableParams } from "./thenable-params.js";
14
16
  import { getCurrentRootParams } from "./root-params.js";
17
+ import { flightArgumentsKey, restoreFlightReply, snapshotFlightReply } from "./cache-flight-arguments.js";
18
+ import { cache } from "react";
15
19
  //#region src/shims/cache-runtime.ts
16
20
  /**
17
21
  * "use cache" runtime
@@ -34,14 +38,17 @@ import { getCurrentRootParams } from "./root-params.js";
34
38
  * and all RSC-serializable types — unlike JSON.stringify which silently
35
39
  * drops $$typeof Symbols and function values.
36
40
  *
37
- * When RSC APIs are unavailable (e.g. in unit tests), falls back to
38
- * JSON.stringify/parse with the same stableStringify cache key generation.
39
- *
40
41
  * Cache variants:
41
42
  * - "use cache" — shared cache (default profile)
42
43
  * - "use cache: remote" — shared cache (explicit)
43
44
  * - "use cache: private" — per-request cache (not shared across requests)
44
45
  */
46
+ const replayableFunctions = /* @__PURE__ */ new WeakMap();
47
+ function replayCachedFunction(fn, args) {
48
+ const replay = replayableFunctions.get(fn);
49
+ if (!replay || args.version !== 1) throw new Error("Invalid cache function arguments");
50
+ return replay(args);
51
+ }
45
52
  /** Threshold below which expire is considered "dynamic" (5 minutes in seconds). */
46
53
  const DYNAMIC_EXPIRE = 300;
47
54
  /**
@@ -122,16 +129,9 @@ function buildUseCacheKey(id, keySeed, argsKey) {
122
129
  const scopedId = keySeed ? `build:${encodeURIComponent(keySeed)}:${id}` : id;
123
130
  return argsKey === void 0 ? `use-cache:${scopedId}` : `use-cache:${scopedId}:${argsKey}`;
124
131
  }
125
- const NOT_LOADED = Symbol("not-loaded");
126
- let _rscModule = NOT_LOADED;
127
- async function getRscModule() {
128
- if (_rscModule !== NOT_LOADED) return _rscModule;
129
- try {
130
- _rscModule = await import("@vitejs/plugin-rsc/react/rsc");
131
- } catch {
132
- _rscModule = null;
133
- }
134
- return _rscModule;
132
+ let _rscModule;
133
+ function getRscModule() {
134
+ return _rscModule ??= import("@vitejs/plugin-rsc/react/rsc");
135
135
  }
136
136
  /** Collect a ReadableStream<Uint8Array> into a single Uint8Array. */
137
137
  async function collectStream(stream) {
@@ -169,55 +169,22 @@ function uint8ToStream(bytes) {
169
169
  } });
170
170
  }
171
171
  async function serializeCacheResult(result, rsc) {
172
- if (rsc) {
173
- let serializationError;
174
- const [returnStream, savedStream] = rsc.renderToReadableStream(result, { onError(error) {
175
- serializationError ??= { value: error };
176
- } }).tee();
177
- try {
178
- const [deserializedResult, bytes] = await Promise.all([rsc.createFromReadableStream(returnStream, {}, { preserveServerReferences: true }), collectStream(savedStream)]);
179
- return {
180
- result: deserializedResult,
181
- cacheEntry: serializationError ? null : {
182
- body: uint8ToBase64(bytes),
183
- headers: { [VINEXT_RSC_MARKER_HEADER]: "1" }
184
- }
185
- };
186
- } catch (error) {
187
- throw serializationError?.value ?? error;
188
- }
189
- }
190
- const body = JSON.stringify(result);
191
- return body === void 0 ? null : {
192
- result,
193
- cacheEntry: {
194
- body,
195
- headers: {}
196
- }
197
- };
198
- }
199
- /**
200
- * Convert an encodeReply result (string | FormData) to a cache key string.
201
- * For FormData (binary args), produces a deterministic SHA-256 hash over
202
- * the sorted entries. We can't hash `new Response(formData).arrayBuffer()`
203
- * because multipart boundaries are non-deterministic across serializations.
204
- *
205
- * Exported for testing.
206
- */
207
- async function replyToCacheKey(reply) {
208
- if (typeof reply === "string") return reply;
209
- const entries = [...reply.entries()];
210
- const valStr = (v) => typeof v === "string" ? v : v.name;
211
- entries.sort((a, b) => a[0].localeCompare(b[0]) || valStr(a[1]).localeCompare(valStr(b[1])));
212
- const parts = [];
213
- for (const [name, value] of entries) if (typeof value === "string") parts.push(`${name}=s:${value}`);
214
- else {
215
- const bytes = new Uint8Array(await value.arrayBuffer());
216
- parts.push(`${name}=b:${value.type}:${value.size}:${Buffer.from(bytes).toString("base64")}`);
172
+ let serializationError;
173
+ const [returnStream, savedStream] = rsc.renderToReadableStream(result, { onError(error) {
174
+ serializationError ??= { value: error };
175
+ } }).tee();
176
+ try {
177
+ const [deserializedResult, bytes] = await Promise.all([rsc.createFromReadableStream(returnStream, {}, { preserveServerReferences: true }), collectStream(savedStream)]);
178
+ return {
179
+ result: deserializedResult,
180
+ cacheEntry: serializationError ? null : {
181
+ body: uint8ToBase64(bytes),
182
+ headers: { [VINEXT_RSC_MARKER_HEADER]: "1" }
183
+ }
184
+ };
185
+ } catch (error) {
186
+ throw serializationError?.value ?? error;
217
187
  }
218
- const payload = new TextEncoder().encode(parts.join("\0"));
219
- const hashBuffer = await crypto.subtle.digest("SHA-256", payload);
220
- return Buffer.from(new Uint8Array(hashBuffer)).toString("base64url");
221
188
  }
222
189
  /**
223
190
  * Resolve collected cacheLife configs into a single effective config.
@@ -299,6 +266,17 @@ function propagateRootParamNamesToParent(names) {
299
266
  if (!parent || parent.variant === "private") return;
300
267
  for (const name of names) parent.readRootParamNames?.add(name);
301
268
  }
269
+ function isServableCacheState(cacheState) {
270
+ if (cacheState === "expired") return false;
271
+ if (cacheState !== "stale") return true;
272
+ return shouldServeStaleUnstableCacheEntry() && process.env.VINEXT_PRERENDER !== "1" && !isRouteCacheabilityProbe();
273
+ }
274
+ function regenerateInBackground(id, regenerate) {
275
+ const regeneration = runWithDetachedCacheObservations(() => runWithDetachedFetchObservations(() => cacheContextStorage.exit(regenerate))).then(() => void 0, (error) => {
276
+ console.error(`[vinext] use cache: background regeneration failed for ${id}:`, error);
277
+ });
278
+ if (isInsideUnifiedScope()) getRequestContext().executionContext?.waitUntil(regeneration);
279
+ }
302
280
  /**
303
281
  * Register a function as a cached function. This is called by the Vite
304
282
  * transform for each "use cache" function.
@@ -313,7 +291,7 @@ function registerCachedFunction(fn, id, variant, options = {}) {
313
291
  const omitAppPageSearchParams = cacheVariant !== "private";
314
292
  const cacheFunctionId = options.serverReferenceId ? JSON.stringify([id, options.serverReferenceId]) : id;
315
293
  const isDev = typeof process !== "undefined" && process.env.NODE_ENV === "development";
316
- const cachedFn = (...args) => {
294
+ const invoke = (args, replay) => {
317
295
  if (cacheVariant === "private") {
318
296
  const parentCtx = cacheContextStorage.getStore();
319
297
  if (parentCtx && parentCtx.variant !== "private") throwPrivateUseCacheInsidePublicUseCacheError();
@@ -344,40 +322,60 @@ function registerCachedFunction(fn, id, variant, options = {}) {
344
322
  }
345
323
  }
346
324
  return trackPprFallbackShellCacheTask(async () => {
347
- const rsc = await getRscModule();
325
+ const codec = await getRscModule();
326
+ const clientReferences = codec.createClientTemporaryReferenceSet();
327
+ const serverReferences = codec.createTemporaryReferenceSet();
328
+ const rsc = {
329
+ ...codec,
330
+ renderToReadableStream: (value, options) => codec.renderToReadableStream(value, {
331
+ ...options,
332
+ temporaryReferences: serverReferences
333
+ }),
334
+ createFromReadableStream: (stream, options, context) => codec.createFromReadableStream(stream, {
335
+ ...options,
336
+ temporaryReferences: clientReferences
337
+ }, context)
338
+ };
348
339
  const keySeed = getUseCacheKeySeed();
349
- const captures = options.decryptCaptures ? await options.decryptCaptures(args[0]) : void 0;
340
+ const captures = !replay && options.decryptCaptures ? await options.decryptCaptures(args[0]) : void 0;
350
341
  const hasCaptureEnvelope = captures !== void 0;
351
- const pagePropsArgIndex = args.findIndex(hasUseCachePageMarker);
342
+ const limitedArgs = options.argumentCount === void 0 ? args : hasCaptureEnvelope ? [args[0], ...args.slice(1, 1 + options.argumentCount)] : args.slice(0, options.argumentCount);
343
+ const pagePropsArgIndex = replay?.pagePropsIndex ?? limitedArgs.findIndex(hasUseCachePageMarker);
344
+ const layoutPropsArgIndex = replay?.layoutPropsIndex ?? limitedArgs.findIndex(hasUseCacheLayoutMarker);
352
345
  const isPageInvocation = pagePropsArgIndex !== -1;
353
- const invocationArgs = isPageInvocation ? replaceArgument(args, pagePropsArgIndex, withoutUseCachePageMarker(args[pagePropsArgIndex])) : args;
354
- const admittedArgs = options.argumentCount === void 0 ? invocationArgs : hasCaptureEnvelope ? [invocationArgs[0], ...invocationArgs.slice(1, 1 + options.argumentCount)] : invocationArgs.slice(0, options.argumentCount);
346
+ const segmentPropsIndex = isPageInvocation ? pagePropsArgIndex : layoutPropsArgIndex;
347
+ const admittedArgs = segmentPropsIndex !== -1 && !replay ? replaceArgument(limitedArgs, segmentPropsIndex, withoutUseCacheSegmentMarker(limitedArgs[segmentPropsIndex], isPageInvocation)) : limitedArgs;
355
348
  const executionArgs = hasCaptureEnvelope ? [captures, ...admittedArgs.slice(1)] : admittedArgs;
349
+ const outerParams = !replay && segmentPropsIndex !== -1 ? executionArgs[segmentPropsIndex].params : void 0;
350
+ const fallbackParams = getFallbackParamsSnapshot(outerParams);
351
+ const serializationArgs = fallbackParams ? replaceArgument(executionArgs, segmentPropsIndex, {
352
+ ...executionArgs[segmentPropsIndex],
353
+ params: fallbackParams
354
+ }) : executionArgs;
356
355
  const pagePropsIndex = omitAppPageSearchParams && isPageInvocation ? pagePropsArgIndex : void 0;
357
- const callArgs = pagePropsIndex === void 0 ? executionArgs : withErroringPageSearchParams(executionArgs, pagePropsIndex);
358
- let cacheKey;
359
- try {
360
- const processedArgs = executionArgs.length > 0 ? unwrapThenableObjectArray(executionArgs, {
361
- pagePropsIndex,
362
- omitMarkedAppPageSearchParams: omitAppPageSearchParams
363
- }) : [];
364
- if (rsc && executionArgs.length > 0) {
365
- const tempRefs = rsc.createClientTemporaryReferenceSet();
366
- const encoded = await rsc.encodeReply(processedArgs, { temporaryReferences: tempRefs });
367
- cacheKey = buildUseCacheKey(cacheFunctionId, keySeed, await replyToCacheKey(encoded));
368
- } else {
369
- const argsKey = processedArgs.length > 0 ? stableStringify(processedArgs) : void 0;
370
- cacheKey = buildUseCacheKey(cacheFunctionId, keySeed, argsKey);
371
- }
372
- } catch {
373
- return (await executeWithContext(fn, callArgs, cacheVariant)).result;
356
+ const keyArgs = pagePropsIndex === void 0 ? serializationArgs : toReplayablePageArgs(serializationArgs, pagePropsIndex);
357
+ const flightArguments = replay ?? await snapshotFlightReply(await rsc.encodeReply(keyArgs, { temporaryReferences: clientReferences }), isPageInvocation ? pagePropsArgIndex : void 0);
358
+ if (!replay && layoutPropsArgIndex !== -1) flightArguments.layoutPropsIndex = layoutPropsArgIndex;
359
+ let cacheKey = buildUseCacheKey(cacheFunctionId, keySeed, flightArgumentsKey(flightArguments));
360
+ let callArgs = await rsc.decodeReply(restoreFlightReply(flightArguments), { temporaryReferences: serverReferences });
361
+ if (segmentPropsIndex !== -1) {
362
+ const props = callArgs[segmentPropsIndex];
363
+ callArgs = replaceArgument(callArgs, segmentPropsIndex, {
364
+ ...props,
365
+ params: restoreThenableParams(await props.params, outerParams)
366
+ });
367
+ if (pagePropsIndex !== void 0) callArgs = withErroringPageSearchParams(callArgs, pagePropsIndex);
374
368
  }
369
+ if (fallbackParams) return (await executeWithContext(fn, callArgs, cacheVariant, rsc)).result;
375
370
  if (cacheVariant === "private") {
376
371
  const privateCache = _getPrivateState()._privateCache;
377
372
  const privateHit = privateCache.get(cacheKey);
378
- if (privateHit !== void 0) return privateHit;
373
+ if (privateHit !== void 0) {
374
+ if (privateHit.serialized) return rsc.createFromReadableStream(uint8ToStream(base64ToUint8(privateHit.serialized.body)), {}, { preserveServerReferences: true });
375
+ return privateHit.result;
376
+ }
379
377
  const execution = await executeWithContext(fn, callArgs, cacheVariant, rsc);
380
- if (execution.cacheable) privateCache.set(cacheKey, execution.result);
378
+ if (execution.cacheable) privateCache.set(cacheKey, execution);
381
379
  return execution.result;
382
380
  }
383
381
  if (isDev || isDraftModeEnabled()) return (await executeWithContext(fn, callArgs, cacheVariant, rsc)).result;
@@ -397,7 +395,7 @@ function registerCachedFunction(fn, id, variant, options = {}) {
397
395
  console.error("[vinext] use cache: handler.get failed; treating as a cache miss:", error);
398
396
  }
399
397
  const redirectValue = existing?.value;
400
- if (isRootParamRedirect(existing) && existing?.cacheState !== "stale" && rootParams && redirectValue?.kind === "FETCH" && !_hasPendingRevalidatedTag([...redirectValue.tags ?? [], ...softTags])) {
398
+ if (isRootParamRedirect(existing) && isServableCacheState(existing?.cacheState) && rootParams && redirectValue?.kind === "FETCH" && !_hasPendingRevalidatedTag([...redirectValue.tags ?? [], ...softTags])) {
401
399
  cacheKey = coarseCacheKey + computeRootParamsCacheKeySuffix(rootParams, addKnownRootParamNames(id, rootParamNamesFromTags(redirectValue.tags)));
402
400
  try {
403
401
  existing = await handler.get(cacheKey, {
@@ -409,78 +407,80 @@ function registerCachedFunction(fn, id, variant, options = {}) {
409
407
  existing = null;
410
408
  }
411
409
  }
412
- if (existing?.value && existing.value.kind === "FETCH" && existing.cacheState !== "stale" && !_hasPendingRevalidatedTag([...existing.value.tags ?? [], ...softTags])) try {
413
- propagateRootParamNamesToParent(knownRootParamsByFunctionId.get(id));
414
- propagateCacheTagsToRequest(existing.value.tags);
415
- if (rsc && existing.value.data.headers["x-vinext-rsc"] === "1") {
416
- const stream = uint8ToStream(base64ToUint8(existing.value.data.body));
417
- const result = await rsc.createFromReadableStream(stream, {}, { preserveServerReferences: true });
418
- recordRequestScopedCacheControl(existing.cacheControl);
419
- return result;
410
+ const generate = async (propagate) => {
411
+ const { result, ctx, effectiveLife, collectedResult } = await runCachedFunctionWithContext(fn, callArgs, cacheVariant, (value) => serializeCacheResult(value, rsc));
412
+ const rootParamNames = ctx.readRootParamNames && ctx.readRootParamNames.size > 0 ? addKnownRootParamNames(id, ctx.readRootParamNames) : knownRootParamsByFunctionId.get(id);
413
+ if (propagate) {
414
+ recordRequestScopedCacheLife(effectiveLife);
415
+ propagateCacheTagsToRequest(ctx.tags);
420
416
  }
421
- const result = JSON.parse(existing.value.data.body);
422
- recordRequestScopedCacheControl(existing.cacheControl);
423
- return result;
424
- } catch {}
425
- const { result, ctx, effectiveLife, collectedResult } = await runCachedFunctionWithContext(fn, callArgs, cacheVariant, (value) => serializeCacheResult(value, rsc));
426
- const rootParamNames = ctx.readRootParamNames && ctx.readRootParamNames.size > 0 ? addKnownRootParamNames(id, ctx.readRootParamNames) : knownRootParamsByFunctionId.get(id);
427
- recordRequestScopedCacheLife(effectiveLife);
428
- propagateCacheTagsToRequest(ctx.tags);
429
- const revalidateSeconds = effectiveLife.revalidate ?? cacheLifeProfiles.default.revalidate ?? 900;
430
- if (collectedResult?.cacheEntry) try {
431
- let cacheFunctionInvocation;
432
- if (options.serverReferenceId && options.encodeInvocationArgs) try {
433
- cacheFunctionInvocation = {
434
- encryptedArgs: await options.encodeInvocationArgs(pagePropsIndex === void 0 ? admittedArgs : toReplayablePageArgs(admittedArgs, pagePropsIndex)),
435
- referenceId: options.serverReferenceId,
436
- rootParams: Object.fromEntries(Object.entries(rootParams ?? {}).filter((entry) => entry[1] !== void 0)),
437
- softTags
438
- };
439
- } catch {}
440
- const serialized = collectedResult.cacheEntry;
441
- const cacheValue = {
442
- kind: "FETCH",
443
- data: {
444
- headers: serialized.headers,
445
- body: serialized.body,
446
- url: cacheKey
447
- },
448
- tags: ctx.tags,
449
- revalidate: revalidateSeconds
450
- };
451
- const cacheContext = {
452
- fetchCache: true,
453
- tags: ctx.tags,
454
- ...cacheFunctionInvocation ? { cacheFunctionInvocation } : {},
455
- cacheControl: {
456
- revalidate: revalidateSeconds,
457
- expire: effectiveLife.expire,
458
- stale: effectiveLife.stale
459
- }
460
- };
461
- if (rootParamNames && rootParamNames.size > 0 && rootParams) {
462
- const specificCacheKey = coarseCacheKey + computeRootParamsCacheKeySuffix(rootParams, rootParamNames);
463
- const redirectTags = [...ctx.tags, ...[...rootParamNames].map((name) => ROOT_PARAM_TAG_PREFIX + name)];
464
- await handler.set(coarseCacheKey, {
417
+ const revalidateSeconds = effectiveLife.revalidate ?? cacheLifeProfiles.default.revalidate ?? 900;
418
+ if (collectedResult?.cacheEntry) try {
419
+ let cacheFunctionInvocation;
420
+ if (options.serverReferenceId && options.encodeInvocation) try {
421
+ cacheFunctionInvocation = {
422
+ encryptedArgs: await options.encodeInvocation(flightArguments),
423
+ referenceId: options.serverReferenceId,
424
+ rootParams: Object.fromEntries(Object.entries(rootParams ?? {}).filter((entry) => entry[1] !== void 0)),
425
+ softTags
426
+ };
427
+ } catch {}
428
+ const serialized = collectedResult.cacheEntry;
429
+ const cacheValue = {
465
430
  kind: "FETCH",
466
431
  data: {
467
- headers: { [ROOT_PARAM_REDIRECT_HEADER]: "1" },
468
- body: "",
469
- url: coarseCacheKey
432
+ headers: serialized.headers,
433
+ body: serialized.body,
434
+ url: cacheKey
470
435
  },
471
- tags: redirectTags,
436
+ tags: ctx.tags,
472
437
  revalidate: revalidateSeconds
473
- }, {
474
- ...cacheContext,
475
- tags: redirectTags
476
- });
477
- cacheValue.data.url = specificCacheKey;
478
- await handler.set(specificCacheKey, cacheValue, cacheContext);
479
- } else await handler.set(cacheKey, cacheValue, cacheContext);
438
+ };
439
+ const cacheContext = {
440
+ fetchCache: true,
441
+ tags: ctx.tags,
442
+ ...cacheFunctionInvocation ? { cacheFunctionInvocation } : {},
443
+ cacheControl: {
444
+ revalidate: revalidateSeconds,
445
+ expire: effectiveLife.expire,
446
+ stale: effectiveLife.stale
447
+ }
448
+ };
449
+ if (rootParamNames && rootParamNames.size > 0 && rootParams) {
450
+ const specificCacheKey = coarseCacheKey + computeRootParamsCacheKeySuffix(rootParams, rootParamNames);
451
+ const redirectTags = [...ctx.tags, ...[...rootParamNames].map((name) => ROOT_PARAM_TAG_PREFIX + name)];
452
+ await handler.set(coarseCacheKey, {
453
+ kind: "FETCH",
454
+ data: {
455
+ headers: { [ROOT_PARAM_REDIRECT_HEADER]: "1" },
456
+ body: "",
457
+ url: coarseCacheKey
458
+ },
459
+ tags: redirectTags,
460
+ revalidate: revalidateSeconds
461
+ }, {
462
+ ...cacheContext,
463
+ tags: redirectTags
464
+ });
465
+ cacheValue.data.url = specificCacheKey;
466
+ await handler.set(specificCacheKey, cacheValue, cacheContext);
467
+ } else await handler.set(cacheKey, cacheValue, cacheContext);
468
+ } catch {}
469
+ return collectedResult ? collectedResult.result : result;
470
+ };
471
+ if (existing?.value && existing.value.kind === "FETCH" && existing.value.data.headers["x-vinext-rsc"] === "1" && isServableCacheState(existing.cacheState) && !_hasPendingRevalidatedTag([...existing.value.tags ?? [], ...softTags])) try {
472
+ propagateRootParamNamesToParent(knownRootParamsByFunctionId.get(id));
473
+ propagateCacheTagsToRequest(existing.value.tags);
474
+ const result = await rsc.createFromReadableStream(uint8ToStream(base64ToUint8(existing.value.data.body)), {}, { preserveServerReferences: true });
475
+ recordRequestScopedCacheControl(existing.cacheControl);
476
+ if (existing.cacheState === "stale") regenerateInBackground(id, () => generate(false));
477
+ return result;
480
478
  } catch {}
481
- return collectedResult ? collectedResult.result : result;
479
+ return generate(true);
482
480
  }, cacheVariant);
483
481
  };
482
+ const cachedFn = memoizeInCacheScope((...args) => invoke(args));
483
+ replayableFunctions.set(cachedFn, (data) => invoke([], data));
484
484
  Object.defineProperty(cachedFn, "length", {
485
485
  value: fn.length,
486
486
  configurable: true
@@ -489,6 +489,11 @@ function registerCachedFunction(fn, id, variant, options = {}) {
489
489
  if (options.acceptsSecondArgument !== void 0) Reflect.set(cachedFn, USE_CACHE_ACCEPTS_SECOND_ARGUMENT_SYMBOL, options.acceptsSecondArgument);
490
490
  return cachedFn;
491
491
  }
492
+ /** Memoize in one React render without skipping cache guards or scoped serialization. */
493
+ function memoizeInCacheScope(fn) {
494
+ const memoized = cache((_parent, _workUnit, _unstable, ...args) => fn(...args));
495
+ return (...args) => memoized(cacheContextStorage.getStore(), workUnitAsyncStorage.getStore(), unstableCacheContextStorage.getStore() === true, ...args);
496
+ }
492
497
  /** @internal Symbol used to identify "use cache" wrapper functions. */
493
498
  const USE_CACHE_FUNCTION_SYMBOL = Symbol.for("vinext.useCacheFunction");
494
499
  /** @internal Symbol carrying transform-derived cached function argument metadata. */
@@ -553,11 +558,12 @@ function propagateCacheTagsToRequest(tags) {
553
558
  addCollectedRequestTags(tags);
554
559
  }
555
560
  async function executeWithContext(fn, args, variant, rsc) {
556
- const { result, ctx: _ctx, effectiveLife, collectedResult } = await runCachedFunctionWithContext(fn, args, variant, rsc ? (value) => serializeCacheResult(value, rsc) : void 0);
561
+ const { result, ctx: _ctx, effectiveLife, collectedResult } = await runCachedFunctionWithContext(fn, args, variant, (value) => serializeCacheResult(value, rsc));
557
562
  recordRequestScopedCacheLife(effectiveLife);
558
563
  return {
559
564
  result: collectedResult ? collectedResult.result : result,
560
- cacheable: collectedResult?.cacheEntry !== null
565
+ cacheable: collectedResult?.cacheEntry !== null,
566
+ serialized: collectedResult?.cacheEntry
561
567
  };
562
568
  }
563
569
  async function runCachedFunctionWithContext(fn, args, variant, collectResult) {
@@ -603,31 +609,6 @@ async function runCachedFunctionWithContext(fn, args, variant, collectResult) {
603
609
  collectedResult
604
610
  };
605
611
  }
606
- function unwrapThenableObjects(value, options) {
607
- if (value === null || value === void 0 || typeof value !== "object") return value;
608
- const childOptions = { omitMarkedAppPageSearchParams: options.omitMarkedAppPageSearchParams };
609
- if (Array.isArray(value)) return value.map((item) => unwrapThenableObjects(item, childOptions));
610
- if (isThenableObject(value)) {
611
- const plain = {};
612
- for (const key of Object.keys(value)) plain[key] = unwrapThenableObjects(value[key], childOptions);
613
- return plain;
614
- }
615
- if (typeof value.then === "function") return value;
616
- const result = {};
617
- for (const key of Object.keys(value)) {
618
- if (key === "searchParams" && (options.omitAppPageSearchParamsAtRoot || options.omitMarkedAppPageSearchParams && isMarkedAppPagePropsObject(value))) continue;
619
- result[key] = unwrapThenableObjects(value[key], childOptions);
620
- }
621
- return result;
622
- }
623
- /**
624
- * A thenable (not an array) with own enumerable properties — the
625
- * `Object.assign(Promise.resolve(obj), obj)` pattern Next.js params use. The
626
- * cache key is built from its fields instead of the promise.
627
- */
628
- function isThenableObject(value) {
629
- return !Array.isArray(value) && "then" in value && typeof value.then === "function" && Object.keys(value).length > 0;
630
- }
631
612
  function isPagePropsObject(value) {
632
613
  return value !== null && typeof value === "object" && !Array.isArray(value);
633
614
  }
@@ -636,26 +617,17 @@ function replaceArgument(args, index, value) {
636
617
  result[index] = value;
637
618
  return result;
638
619
  }
639
- /** Remove the `$$isPage` invocation marker before props reach the key or user code. */
640
- function withoutUseCachePageMarker(props) {
641
- const { [APP_PAGE_USE_CACHE_MARKER]: _marker, ...pageProps } = props;
642
- return isMarkedAppPagePropsObject(props) ? markAppPagePropsForUseCache(pageProps) : pageProps;
643
- }
644
620
  /**
645
621
  * Response Store replay args for a public page cache: drop `searchParams` from
646
622
  * the page props at `index` (after a capture envelope, if any), as Next.js does
647
- * for the serialized arguments (use-cache-wrapper.ts, `isPageSegmentFunction`),
648
- * and keep the `$$isPage` marker so a replay regains page semantics, including
649
- * the erroring searchParams fallback.
623
+ * for the serialized arguments (use-cache-wrapper.ts, `isPageSegmentFunction`).
624
+ * The replay regains page semantics from `CacheFlightArguments.pagePropsIndex`.
650
625
  */
651
626
  function toReplayablePageArgs(args, index) {
652
627
  const props = args[index];
653
628
  if (!isPagePropsObject(props)) return [...args];
654
629
  const { searchParams: _searchParams, ...pageProps } = props;
655
- return replaceArgument(args, index, {
656
- ...pageProps,
657
- [APP_PAGE_USE_CACHE_MARKER]: true
658
- });
630
+ return replaceArgument(args, index, pageProps);
659
631
  }
660
632
  /**
661
633
  * Give page props at `index` without `searchParams` (a Response Store replay of
@@ -671,35 +643,5 @@ function withErroringPageSearchParams(args, index) {
671
643
  searchParams: makeThenableParams({}, { observeParamAccess: () => throwIfInsideCacheScope("searchParams") })
672
644
  });
673
645
  }
674
- function unwrapThenableObjectArray(values, options) {
675
- return values.map((value, index) => unwrapThenableObjects(value, {
676
- omitAppPageSearchParamsAtRoot: index === options.pagePropsIndex,
677
- omitMarkedAppPageSearchParams: options.omitMarkedAppPageSearchParams
678
- }));
679
- }
680
- function stableStringify(value, seen) {
681
- if (value === void 0) return "undefined";
682
- if (value === null) return "null";
683
- if (typeof value === "function") throw new Error("Cannot serialize function");
684
- if (typeof value === "symbol") throw new Error("Cannot serialize symbol");
685
- if (Array.isArray(value)) {
686
- if (!seen) seen = /* @__PURE__ */ new Set();
687
- if (seen.has(value)) throw new Error("Circular reference");
688
- seen.add(value);
689
- const result = "[" + value.map((v) => stableStringify(v, seen)).join(",") + "]";
690
- seen.delete(value);
691
- return result;
692
- }
693
- if (typeof value === "object" && value !== null) {
694
- if (value instanceof Date) return `Date(${value.getTime()})`;
695
- if (!seen) seen = /* @__PURE__ */ new Set();
696
- if (seen.has(value)) throw new Error("Circular reference");
697
- seen.add(value);
698
- const result = "{" + Object.keys(value).sort().map((k) => `${JSON.stringify(k)}:${stableStringify(value[k], seen)}`).join(",") + "}";
699
- seen.delete(value);
700
- return result;
701
- }
702
- return JSON.stringify(value);
703
- }
704
646
  //#endregion
705
- export { NestedDynamicUseCacheError, buildUseCacheKey, cacheContextStorage, clearPrivateCache, getCacheContext, isThenableObject, isUseCacheFunction, markAppPagePropsForUseCache, registerCachedFunction, replyToCacheKey, runWithPrivateCache };
647
+ export { NestedDynamicUseCacheError, buildUseCacheKey, cacheContextStorage, clearPrivateCache, getCacheContext, isUseCacheFunction, memoizeInCacheScope, registerCachedFunction, replayCachedFunction, runWithPrivateCache };
@@ -1,5 +1,6 @@
1
1
  import { ExecutionContextLike, getRequestExecutionContext, runWithExecutionContext } from "./request-context.js";
2
- 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, _recordUseCacheRootParamRead, _registerCacheContextAccessor, _runWithCacheState, _setRequestScopedCacheLife, cacheLifeProfiles, getAndClearActionRevalidationKind, getRegisteredCacheContext, markActionRevalidation, recordUnstableCacheObservation, shouldServeStaleUnstableCacheEntry } from "./cache-request-state.js";
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, CacheLifeSink, CacheState, UnstableCacheObservation, UnstableCacheRevalidationMode, _captureRequestScopedCacheLifeAccessors, _consumeRequestScopedCacheLife, _drainPendingRevalidations, _hasPendingRevalidatedTag, _initRequestScopedCacheState, _markPendingRevalidatedTag, _peekRequestScopedCacheLife, _peekUnstableCacheObservations, _queuePendingRevalidation, _runWithCacheState, _setRequestScopedCacheLife, cacheLifeProfiles, getAndClearActionRevalidationKind, markActionRevalidation, recordUnstableCacheObservation, runWithDetachedCacheObservations, 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
  /**
@@ -141,4 +142,4 @@ type UnstableCacheOptions = {
141
142
  */
142
143
  export declare function unstable_cache<T extends (...args: any[]) => Promise<any>>(fn: T, keyParts?: string[], options?: UnstableCacheOptions): T;
143
144
  //#endregion
144
- export { ACTION_DID_REVALIDATE_DYNAMIC_ONLY, ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC, ActionRevalidationKind, CacheControlMetadata, CacheHandler, CacheHandlerContext, CacheHandlerValue, CacheLifeConfig, CacheState, CachedAppPageValue, CachedFetchValue, CachedImageValue, CachedPagesValue, CachedRedirectValue, CachedRouteValue, type ExecutionContextLike, IncrementalCacheValue, MemoryCacheHandler, NoOpCacheHandler, UnstableCacheObservation, UnstableCacheRevalidationMode, _captureRequestScopedCacheLifeAccessors, _consumeRequestScopedCacheLife, _drainPendingRevalidations, _hasPendingRevalidatedTag, _initRequestScopedCacheState, _markPendingRevalidatedTag, _peekRequestScopedCacheLife, _peekUnstableCacheObservations, _queuePendingRevalidation, _recordUseCacheRootParamRead, _registerCacheContextAccessor, _runWithCacheState, _setRequestScopedCacheLife, cacheLifeProfiles, configureMemoryCacheHandler, getAndClearActionRevalidationKind, getCacheHandler, getDataCacheHandler, getRegisteredCacheContext, getRequestExecutionContext, markActionRevalidation, unstable_noStore as noStore, recordUnstableCacheObservation, registerDataCacheHandler, registerLazyDataCacheHandler, runWithExecutionContext, setCacheHandler, setDataCacheHandler, shouldServeStaleUnstableCacheEntry };
145
+ export { ACTION_DID_REVALIDATE_DYNAMIC_ONLY, ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC, ActionRevalidationKind, CacheControlMetadata, CacheHandler, CacheHandlerContext, CacheHandlerValue, CacheLifeConfig, CacheLifeSink, CacheState, CachedAppPageValue, CachedFetchValue, CachedImageValue, CachedPagesValue, CachedRedirectValue, CachedRouteValue, type ExecutionContextLike, IncrementalCacheValue, MemoryCacheHandler, NoOpCacheHandler, UnstableCacheObservation, UnstableCacheRevalidationMode, _captureRequestScopedCacheLifeAccessors, _consumeRequestScopedCacheLife, _drainPendingRevalidations, _hasPendingRevalidatedTag, _initRequestScopedCacheState, _markPendingRevalidatedTag, _peekRequestScopedCacheLife, _peekUnstableCacheObservations, _queuePendingRevalidation, _recordUseCacheRootParamRead, _registerCacheContextAccessor, _runWithCacheState, _setRequestScopedCacheLife, cacheLifeProfiles, configureMemoryCacheHandler, getAndClearActionRevalidationKind, getCacheHandler, getDataCacheHandler, getRegisteredCacheContext, getRequestExecutionContext, markActionRevalidation, unstable_noStore as noStore, recordUnstableCacheObservation, registerDataCacheHandler, registerLazyDataCacheHandler, runWithDetachedCacheObservations, runWithExecutionContext, setCacheHandler, setDataCacheHandler, shouldServeStaleUnstableCacheEntry };
@@ -8,9 +8,11 @@ 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, isDraftModeEnabled, markDynamicUsage } from "./headers.js";
12
- import { ACTION_DID_REVALIDATE_DYNAMIC_ONLY, ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC, _captureRequestScopedCacheLifeAccessors, _consumeRequestScopedCacheLife, _drainPendingRevalidations, _hasPendingRevalidatedTag, _initRequestScopedCacheState, _markPendingRevalidatedTag, _peekRequestScopedCacheLife, _peekUnstableCacheObservations, _queuePendingRevalidation, _recordUseCacheRootParamRead, _registerCacheContextAccessor, _runWithCacheState, _setRequestScopedCacheLife, cacheLifeProfiles, getAndClearActionRevalidationKind, getRegisteredCacheContext, markActionRevalidation, recordUnstableCacheObservation, shouldServeStaleUnstableCacheEntry } from "./cache-request-state.js";
13
- import { addCollectedRequestTags, getCurrentFetchSoftTags } from "./fetch-cache.js";
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, runWithDetachedCacheObservations, shouldServeStaleUnstableCacheEntry } from "./cache-request-state.js";
15
+ import { addCollectedRequestTags, getCurrentFetchSoftTags, runWithDetachedFetchObservations } from "./fetch-cache.js";
14
16
  //#region src/shims/cache.ts
15
17
  /**
16
18
  * next/cache shim
@@ -320,6 +322,7 @@ const UNSTABLE_CACHE_KEY_PREFIX = "unstable_cache:v2";
320
322
  * a direct import (avoiding circular dependencies).
321
323
  */
322
324
  const _unstableCacheAls = getOrCreateAls("vinext.unstableCache.als");
325
+ const _useCacheContextAls = getOrCreateAls("vinext.cacheRuntime.contextAls");
323
326
  function serializeUnstableCacheResult(value) {
324
327
  return JSON.stringify(value === void 0 ? { undef: true } : { v: value });
325
328
  }
@@ -360,7 +363,7 @@ function waitUntilUnstableCacheRevalidation(promise) {
360
363
  function scheduleUnstableCacheBackgroundRevalidation(cacheKey, refresh) {
361
364
  const pending = getPendingUnstableCacheRevalidations();
362
365
  if (pending.has(cacheKey)) return;
363
- const trackedRevalidation = refresh().then(() => void 0).catch((err) => {
366
+ const trackedRevalidation = runWithDetachedCacheObservations(() => runWithDetachedFetchObservations(() => _useCacheContextAls.exit(refresh))).then(() => void 0).catch((err) => {
364
367
  console.error(`[vinext] unstable_cache background revalidation failed for ${cacheKey}:`, err);
365
368
  }).finally(() => {
366
369
  if (pending.get(cacheKey) === trackedRevalidation) pending.delete(cacheKey);
@@ -434,4 +437,4 @@ function unstable_cache(fn, keyParts, options) {
434
437
  return cachedFn;
435
438
  }
436
439
  //#endregion
437
- export { ACTION_DID_REVALIDATE_DYNAMIC_ONLY, ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC, MemoryCacheHandler, NoOpCacheHandler, _captureRequestScopedCacheLifeAccessors, _consumeRequestScopedCacheLife, _drainPendingRevalidations, _hasPendingRevalidatedTag, _initRequestScopedCacheState, _markPendingRevalidatedTag, _peekRequestScopedCacheLife, _peekUnstableCacheObservations, _queuePendingRevalidation, _recordUseCacheRootParamRead, _registerCacheContextAccessor, _runWithCacheState, _setRequestScopedCacheLife, cacheLife, cacheLifeProfiles, cacheTag, configureMemoryCacheHandler, getAndClearActionRevalidationKind, getCacheHandler, getDataCacheHandler, getRegisteredCacheContext, getRequestExecutionContext, io, isInsideUnstableCacheScope, markActionRevalidation, unstable_noStore as noStore, unstable_noStore, recordUnstableCacheObservation, refresh, registerDataCacheHandler, registerLazyDataCacheHandler, revalidatePath, revalidateTag, runWithExecutionContext, setCacheHandler, setDataCacheHandler, shouldServeStaleUnstableCacheEntry, unstable_cache, unstable_cacheLife, unstable_cacheTag, unstable_io, updateTag };
440
+ export { ACTION_DID_REVALIDATE_DYNAMIC_ONLY, ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC, MemoryCacheHandler, NoOpCacheHandler, _captureRequestScopedCacheLifeAccessors, _consumeRequestScopedCacheLife, _drainPendingRevalidations, _hasPendingRevalidatedTag, _initRequestScopedCacheState, _markPendingRevalidatedTag, _peekRequestScopedCacheLife, _peekUnstableCacheObservations, _queuePendingRevalidation, _recordUseCacheRootParamRead, _registerCacheContextAccessor, _runWithCacheState, _setRequestScopedCacheLife, cacheLife, cacheLifeProfiles, cacheTag, configureMemoryCacheHandler, getAndClearActionRevalidationKind, getCacheHandler, getDataCacheHandler, getRegisteredCacheContext, getRequestExecutionContext, io, isInsideUnstableCacheScope, markActionRevalidation, unstable_noStore as noStore, unstable_noStore, recordUnstableCacheObservation, refresh, registerDataCacheHandler, registerLazyDataCacheHandler, revalidatePath, revalidateTag, runWithDetachedCacheObservations, runWithExecutionContext, setCacheHandler, setDataCacheHandler, shouldServeStaleUnstableCacheEntry, unstable_cache, unstable_cacheLife, unstable_cacheTag, unstable_io, updateTag };
@@ -10,6 +10,13 @@ export type RouteCacheabilityOutcome = {
10
10
  searchParamsUnread?: true;
11
11
  /** A transient classification failure that may succeed on another bounded attempt. */
12
12
  retryable?: true;
13
+ /**
14
+ * App page RSC: the status and headers that replace the streamed 200 of a
15
+ * render whose special error rejected its document's shell, once the
16
+ * response is complete.
17
+ */
18
+ status?: number;
19
+ headers?: Readonly<Record<string, string>>;
13
20
  tags?: readonly string[];
14
21
  };
15
22
  export type RouteCacheabilityState = {
@@ -86,7 +93,7 @@ export declare function markRouteCacheabilityExplicitConfigPolicy(): void;
86
93
  export declare function markRouteCacheabilityConfigCdnCachePolicy(name: string, value: string): void;
87
94
  /** Record a next.config cache policy header with the value a response carries. */
88
95
  export declare function recordConfigCdnCachePolicyHeader(state: RouteCacheabilityState, name: string, value: string): void;
89
- /** Record a public cache policy supplied by the Route Handler itself. */
96
+ /** Record an explicit cache policy supplied by the Route Handler itself. */
90
97
  export declare function markRouteCacheabilityExplicitResponsePolicy(): void;
91
98
  /** Record that the response body reached clean EOF and is now a replay stream. */
92
99
  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 a public cache policy supplied by the Route Handler itself. */
87
+ /** Record an explicit cache policy supplied by the Route Handler itself. */
88
88
  function markRouteCacheabilityExplicitResponsePolicy() {
89
89
  const state = readRouteCacheabilityState();
90
- if (!state || state.mode !== "admit") return;
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. */