vinext 1.1.0 → 1.2.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 (234) hide show
  1. package/README.md +21 -9
  2. package/dist/build/client-build-config.d.ts +10 -0
  3. package/dist/build/client-build-config.js +18 -2
  4. package/dist/build/pages-client-assets-module.d.ts +8 -0
  5. package/dist/build/pages-client-assets-module.js +21 -1
  6. package/dist/build/prerender-paths.js +5 -3
  7. package/dist/build/run-prerender.js +1 -1
  8. package/dist/build/ssr-manifest.d.ts +2 -0
  9. package/dist/build/ssr-manifest.js +6 -2
  10. package/dist/check.js +7 -6
  11. package/dist/cli.js +2 -1
  12. package/dist/client/client-redirect-matcher.d.ts +14 -0
  13. package/dist/client/client-redirect-matcher.js +37 -0
  14. package/dist/client/client-redirects.d.ts +27 -0
  15. package/dist/client/client-redirects.js +28 -0
  16. package/dist/client/client-rewrites.d.ts +2 -1
  17. package/dist/client/client-rewrites.js +1 -1
  18. package/dist/config/config-matchers.d.ts +26 -11
  19. package/dist/config/config-matchers.js +78 -81
  20. package/dist/config/destination-params.d.ts +47 -0
  21. package/dist/config/destination-params.js +116 -0
  22. package/dist/config/next-config.d.ts +7 -0
  23. package/dist/config/next-config.js +3 -0
  24. package/dist/entries/app-rsc-entry.d.ts +4 -0
  25. package/dist/entries/app-rsc-entry.js +20 -6
  26. package/dist/entries/pages-client-entry.js +3 -1
  27. package/dist/entries/pages-server-entry.js +13 -37
  28. package/dist/index.d.ts +3 -1
  29. package/dist/index.js +134 -43
  30. package/dist/init-cloudflare.d.ts +9 -0
  31. package/dist/init-cloudflare.js +107 -31
  32. package/dist/init-platform.d.ts +4 -0
  33. package/dist/init-platform.js +27 -2
  34. package/dist/init.d.ts +1 -0
  35. package/dist/init.js +67 -3
  36. package/dist/plugins/ast-scope.d.ts +7 -0
  37. package/dist/plugins/ast-scope.js +59 -3
  38. package/dist/plugins/cache-flight-codec.d.ts +1 -1
  39. package/dist/plugins/dynamic-preload-metadata.d.ts +1 -1
  40. package/dist/plugins/dynamic-preload-metadata.js +9 -8
  41. package/dist/plugins/ignore-dynamic-requests.d.ts +1 -1
  42. package/dist/plugins/ignore-dynamic-requests.js +3 -4
  43. package/dist/plugins/middleware-server-only.d.ts +5 -4
  44. package/dist/plugins/middleware-server-only.js +8 -5
  45. package/dist/plugins/pages-node-externals.js +1 -1
  46. package/dist/plugins/rsc-scan-glob-imports.d.ts +19 -0
  47. package/dist/plugins/rsc-scan-glob-imports.js +50 -0
  48. package/dist/plugins/strip-server-exports.js +262 -98
  49. package/dist/plugins/transform-result.d.ts +9 -5
  50. package/dist/plugins/transitive-externals.js +1 -1
  51. package/dist/plugins/typeof-window.d.ts +2 -2
  52. package/dist/plugins/use-cache-callable.js +8 -2
  53. package/dist/plugins/worker-server-only-imports.d.ts +20 -0
  54. package/dist/plugins/worker-server-only-imports.js +31 -0
  55. package/dist/plugins/worker-use-server.d.ts +25 -0
  56. package/dist/plugins/worker-use-server.js +129 -0
  57. package/dist/server/api-handler.d.ts +1 -0
  58. package/dist/server/api-handler.js +2 -1
  59. package/dist/server/app-browser-action-result.d.ts +1 -1
  60. package/dist/server/app-browser-action-result.js +9 -2
  61. package/dist/server/app-browser-navigation-controller.js +1 -1
  62. package/dist/server/app-browser-server-action-client.js +1 -1
  63. package/dist/server/app-middleware.d.ts +11 -0
  64. package/dist/server/app-middleware.js +17 -2
  65. package/dist/server/app-page-cache.d.ts +1 -1
  66. package/dist/server/app-page-cache.js +1 -1
  67. package/dist/server/app-page-dispatch.d.ts +3 -1
  68. package/dist/server/app-page-dispatch.js +4 -3
  69. package/dist/server/app-page-ppr-runtime.js +1 -1
  70. package/dist/server/app-page-render-observation.js +1 -1
  71. package/dist/server/app-page-request.js +53 -15
  72. package/dist/server/app-page-route-wiring.js +2 -2
  73. package/dist/server/app-pages-bridge.d.ts +1 -1
  74. package/dist/server/app-pages-bridge.js +2 -3
  75. package/dist/server/app-prerender-endpoints.js +9 -6
  76. package/dist/server/app-request-stage-dispatch.js +6 -2
  77. package/dist/server/app-request-stage-independent-entry.js +25 -5
  78. package/dist/server/app-response-stage-entry.js +10 -2
  79. package/dist/server/app-route-handler-cache.d.ts +1 -0
  80. package/dist/server/app-route-handler-cache.js +1 -0
  81. package/dist/server/app-route-handler-dispatch.d.ts +1 -0
  82. package/dist/server/app-route-handler-dispatch.js +5 -2
  83. package/dist/server/app-route-handler-execution.d.ts +1 -0
  84. package/dist/server/app-route-handler-execution.js +1 -0
  85. package/dist/server/app-route-handler-runtime.d.ts +4 -1
  86. package/dist/server/app-route-handler-runtime.js +45 -24
  87. package/dist/server/app-router-entry.js +24 -5
  88. package/dist/server/app-rsc-cache-busting.js +1 -1
  89. package/dist/server/app-rsc-errors.js +20 -16
  90. package/dist/server/app-rsc-handler.d.ts +7 -0
  91. package/dist/server/app-rsc-handler.js +85 -35
  92. package/dist/server/app-rsc-response-stage.js +4 -2
  93. package/dist/server/app-segment-config.d.ts +2 -1
  94. package/dist/server/app-server-action-execution.d.ts +2 -1
  95. package/dist/server/app-server-action-execution.js +61 -22
  96. package/dist/server/app-ssr-entry.js +2 -1
  97. package/dist/server/app-worker-stages.d.ts +5 -0
  98. package/dist/server/app-worker-stages.js +1 -1
  99. package/dist/server/cacheability-request.js +2 -2
  100. package/dist/server/client-build-files.d.ts +16 -0
  101. package/dist/server/client-build-files.js +36 -0
  102. package/dist/server/client-reuse-manifest.js +1 -1
  103. package/dist/server/dev-server.js +38 -27
  104. package/dist/server/dev-stack-sourcemap.js +18 -23
  105. package/dist/server/document-initial-head.d.ts +0 -11
  106. package/dist/server/document-initial-head.js +1 -1
  107. package/dist/server/forwarded-middleware-context.d.ts +5 -0
  108. package/dist/server/forwarded-middleware-context.js +22 -0
  109. package/dist/server/headers.d.ts +4 -1
  110. package/dist/server/headers.js +4 -1
  111. package/dist/server/http-conditional.d.ts +11 -0
  112. package/dist/server/http-conditional.js +10 -1
  113. package/dist/server/http-error-responses.d.ts +1 -1
  114. package/dist/server/image-optimization.d.ts +38 -0
  115. package/dist/server/image-optimization.js +93 -4
  116. package/dist/server/isr-cache.d.ts +10 -0
  117. package/dist/server/isr-cache.js +41 -6
  118. package/dist/server/metadata-route-response.js +9 -8
  119. package/dist/server/middleware-matcher.d.ts +2 -0
  120. package/dist/server/middleware-matcher.js +23 -2
  121. package/dist/server/middleware-runtime.d.ts +13 -0
  122. package/dist/server/middleware-runtime.js +33 -20
  123. package/dist/server/middleware.d.ts +1 -1
  124. package/dist/server/middleware.js +3 -1
  125. package/dist/server/multi-stage.d.ts +11 -0
  126. package/dist/server/normalize-path.d.ts +0 -13
  127. package/dist/server/normalize-path.js +1 -34
  128. package/dist/server/pages-api-route.d.ts +3 -2
  129. package/dist/server/pages-api-route.js +4 -3
  130. package/dist/server/pages-cache-tag.d.ts +12 -0
  131. package/dist/server/pages-cache-tag.js +19 -0
  132. package/dist/server/pages-client-assets.d.ts +2 -0
  133. package/dist/server/pages-data-route.d.ts +10 -0
  134. package/dist/server/pages-data-route.js +19 -2
  135. package/dist/server/pages-document-asset-props.d.ts +5 -1
  136. package/dist/server/pages-document-asset-props.js +13 -5
  137. package/dist/server/pages-document-splice.d.ts +19 -0
  138. package/dist/server/pages-document-splice.js +55 -0
  139. package/dist/server/pages-i18n.d.ts +12 -1
  140. package/dist/server/pages-i18n.js +18 -4
  141. package/dist/server/pages-node-compat.d.ts +16 -5
  142. package/dist/server/pages-node-compat.js +20 -12
  143. package/dist/server/pages-page-data.d.ts +32 -24
  144. package/dist/server/pages-page-data.js +50 -120
  145. package/dist/server/pages-page-handler.d.ts +0 -6
  146. package/dist/server/pages-page-handler.js +188 -126
  147. package/dist/server/pages-page-response.d.ts +12 -6
  148. package/dist/server/pages-page-response.js +41 -34
  149. package/dist/server/pages-request-pipeline.d.ts +10 -2
  150. package/dist/server/pages-request-pipeline.js +37 -18
  151. package/dist/server/pages-request-stage-entry.d.ts +6 -0
  152. package/dist/server/pages-request-stage-entry.js +71 -12
  153. package/dist/server/pages-response-stage-entry.js +4 -0
  154. package/dist/server/pages-revalidate.js +1 -1
  155. package/dist/server/pages-router-entry.js +4 -3
  156. package/dist/server/prerender-manifest.d.ts +3 -3
  157. package/dist/server/prerender-manifest.js +4 -3
  158. package/dist/server/prerender-work-unit-setup.js +4 -0
  159. package/dist/server/prod-server.d.ts +12 -0
  160. package/dist/server/prod-server.js +199 -69
  161. package/dist/server/proper-error.d.ts +4 -0
  162. package/dist/server/proper-error.js +31 -0
  163. package/dist/server/request-pipeline.d.ts +4 -1
  164. package/dist/server/request-pipeline.js +3 -2
  165. package/dist/server/revalidation-request.d.ts +1 -0
  166. package/dist/server/revalidation-request.js +1 -1
  167. package/dist/server/rsc-stream-hints.js +31 -2
  168. package/dist/server/seed-cache.d.ts +1 -0
  169. package/dist/server/seed-cache.js +5 -4
  170. package/dist/server/server-reference-loader.d.ts +4 -0
  171. package/dist/server/server-reference-loader.js +29 -0
  172. package/dist/server/socket-error-backstop.d.ts +9 -1
  173. package/dist/server/socket-error-backstop.js +46 -17
  174. package/dist/server/static-file-signal.d.ts +15 -4
  175. package/dist/server/static-file-signal.js +46 -12
  176. package/dist/server/worker-image-optimization.d.ts +34 -0
  177. package/dist/server/worker-image-optimization.js +86 -0
  178. package/dist/server/worker-stages.d.ts +1 -1
  179. package/dist/server/worker-stages.js +2 -2
  180. package/dist/server/worker-utils.d.ts +8 -3
  181. package/dist/server/worker-utils.js +12 -7
  182. package/dist/shims/app-router-scroll.js +4 -1
  183. package/dist/shims/app-router-tree-context.d.ts +5 -0
  184. package/dist/shims/app-router-tree-context.js +27 -0
  185. package/dist/shims/cache-callable-runtime.d.ts +4 -2
  186. package/dist/shims/cache-callable-runtime.js +21 -12
  187. package/dist/shims/cache-handler.js +1 -9
  188. package/dist/shims/cache-runtime.d.ts +6 -1
  189. package/dist/shims/cache-runtime.js +2 -1
  190. package/dist/shims/cache.d.ts +2 -2
  191. package/dist/shims/cache.js +40 -13
  192. package/dist/shims/cdn-cache.d.ts +8 -0
  193. package/dist/shims/cdn-cache.js +17 -1
  194. package/dist/shims/disable-smooth-scroll.d.ts +3 -0
  195. package/dist/shims/disable-smooth-scroll.js +36 -0
  196. package/dist/shims/document-placeholders.d.ts +19 -0
  197. package/dist/shims/document-placeholders.js +45 -0
  198. package/dist/shims/document.js +21 -5
  199. package/dist/shims/dynamic-preload-chunks.d.ts +1 -0
  200. package/dist/shims/dynamic-preload-chunks.js +13 -9
  201. package/dist/shims/dynamic.d.ts +1 -1
  202. package/dist/shims/dynamic.js +60 -8
  203. package/dist/shims/fetch-cache-state.d.ts +66 -0
  204. package/dist/shims/fetch-cache-state.js +92 -0
  205. package/dist/shims/fetch-cache.d.ts +3 -67
  206. package/dist/shims/fetch-cache.js +160 -125
  207. package/dist/shims/head.d.ts +10 -6
  208. package/dist/shims/head.js +15 -13
  209. package/dist/shims/image.js +2 -1
  210. package/dist/shims/internal/work-store-scope.d.ts +5 -0
  211. package/dist/shims/internal/work-store-scope.js +24 -0
  212. package/dist/shims/navigation.js +31 -5
  213. package/dist/shims/request-context.d.ts +2 -0
  214. package/dist/shims/request-state-types.d.ts +2 -1
  215. package/dist/shims/router.js +12 -20
  216. package/dist/shims/server.d.ts +16 -0
  217. package/dist/shims/server.js +24 -4
  218. package/dist/shims/unified-request-context.d.ts +1 -1
  219. package/dist/shims/url-utils.d.ts +2 -0
  220. package/dist/shims/url-utils.js +3 -1
  221. package/dist/utils/client-runtime-metadata.js +1 -1
  222. package/dist/utils/hash.d.ts +7 -0
  223. package/dist/utils/hash.js +11 -1
  224. package/dist/utils/package-name.d.ts +6 -0
  225. package/dist/utils/package-name.js +12 -1
  226. package/dist/utils/plugin-rsc-version.d.ts +4 -0
  227. package/dist/utils/plugin-rsc-version.js +15 -0
  228. package/dist/utils/prerender-output-paths.js +15 -4
  229. package/dist/utils/public-file-path.d.ts +10 -2
  230. package/dist/utils/public-file-path.js +13 -9
  231. package/dist/utils/public-routes.js +2 -2
  232. package/dist/utils/react-version.d.ts +3 -0
  233. package/dist/utils/react-version.js +1 -1
  234. package/package.json +7 -3
@@ -0,0 +1,5 @@
1
+ import React from "react";
2
+ //#region src/shims/app-router-tree-context.d.ts
3
+ export declare const AppRouterTreeContext: React.Context<boolean> | null;
4
+ export declare function withAppRouterTree(children: React.ReactElement): React.ReactElement;
5
+ //#endregion
@@ -0,0 +1,27 @@
1
+ import React from "react";
2
+ //#region src/shims/app-router-tree-context.ts
3
+ /**
4
+ * Marks an App Router server render tree. The App Router SSR entry provides
5
+ * `true` at its root; every other server tree (Pages Router pages,
6
+ * `pages/_document`, ad-hoc react-dom/server renders) reads the `false`
7
+ * default. Lets shared shims such as next/dynamic apply App Router semantics
8
+ * only where Next.js does. In the browser, `window.next.appDir` (installed
9
+ * when the App Router browser entry loads) identifies App Router documents.
10
+ *
11
+ * Stored on a global symbol so duplicate module instances share one context,
12
+ * and null in react-server, which has no createContext (RSC is App Router
13
+ * only).
14
+ */
15
+ const APP_ROUTER_TREE_CONTEXT_KEY = Symbol.for("vinext.appRouterTreeContext");
16
+ function getAppRouterTreeContext() {
17
+ if (typeof React.createContext !== "function") return null;
18
+ const globalState = globalThis;
19
+ globalState[APP_ROUTER_TREE_CONTEXT_KEY] ??= React.createContext(false);
20
+ return globalState[APP_ROUTER_TREE_CONTEXT_KEY];
21
+ }
22
+ const AppRouterTreeContext = getAppRouterTreeContext();
23
+ function withAppRouterTree(children) {
24
+ return AppRouterTreeContext ? React.createElement(AppRouterTreeContext.Provider, { value: true }, children) : children;
25
+ }
26
+ //#endregion
27
+ export { AppRouterTreeContext, withAppRouterTree };
@@ -6,8 +6,10 @@ type CacheCaptureEnvelope = {
6
6
  type: typeof CACHE_CAPTURE_TYPE;
7
7
  encrypted: Promise<string>;
8
8
  };
9
- export declare function encryptCacheCaptures(captures: unknown[]): CacheCaptureEnvelope;
10
- export declare function registerCachedFunction<TArgs extends unknown[], TResult>(fn: (...args: TArgs) => Promise<TResult>, id: string, variant: string, options: RegisterCachedFunctionOptions): (...args: TArgs) => Promise<TResult>;
9
+ export declare function encryptCacheCaptures(referenceId: string, captures: unknown[]): CacheCaptureEnvelope;
10
+ export declare function registerCachedFunction<TArgs extends unknown[], TResult>(fn: (...args: TArgs) => Promise<TResult>, id: string, variant: string, { captureCount, ...options }: RegisterCachedFunctionOptions & {
11
+ captureCount?: number;
12
+ }): (...args: TArgs) => Promise<TResult>;
11
13
  /** Replay the persisted payload without re-reading or re-encoding caller objects. */
12
14
  export declare function invokeCacheFunction(invocation: VinextCacheFunctionInvocation, loadServerAction: (id: string) => Promise<unknown>): Promise<void>;
13
15
  //#endregion
@@ -14,14 +14,14 @@ async function decryptArguments(encrypted) {
14
14
  if (value?.version !== 1) throw new Error("Invalid cache function arguments");
15
15
  return value;
16
16
  }
17
- function encryptCacheCaptures(captures) {
18
- return memoizedCaptureEnvelope(...captures);
17
+ function encryptCacheCaptures(referenceId, captures) {
18
+ return memoizedCaptureEnvelope(referenceId, ...captures);
19
19
  }
20
- const memoizedCaptureEnvelope = memoizeInCacheScope((...captures) => ({
20
+ const memoizedCaptureEnvelope = memoizeInCacheScope((referenceId, ...captures) => ({
21
21
  type: CACHE_CAPTURE_TYPE,
22
- encrypted: encryptCaptures(captures)
22
+ encrypted: encryptCaptures(referenceId, captures)
23
23
  }));
24
- async function encryptCaptures(captures) {
24
+ async function encryptCaptures(referenceId, captures) {
25
25
  const files = new FormData();
26
26
  let nextFileId = 0;
27
27
  const temporaryReferences = new class extends WeakMap {
@@ -39,26 +39,35 @@ async function encryptCaptures(captures) {
39
39
  const bytes = await new Response(stream).arrayBuffer();
40
40
  return encryptActionBoundArgs(JSON.stringify({
41
41
  version: 1,
42
+ referenceId,
42
43
  result: Buffer.from(bytes).toString("base64"),
43
44
  files: await snapshotFlightReply(files)
44
45
  }));
45
46
  }
46
- async function decryptCacheCaptures(value) {
47
- if (typeof value !== "object" || value === null || !("type" in value) || value.type !== CACHE_CAPTURE_TYPE || !("encrypted" in value)) return;
47
+ async function decryptCacheCaptures(value, referenceId, captureCount) {
48
+ if (typeof value !== "object" || value === null || !("type" in value) || value.type !== CACHE_CAPTURE_TYPE || !("encrypted" in value)) throw new Error("Invalid cache capture arguments");
48
49
  const encrypted = value.encrypted;
49
- if (typeof encrypted !== "string" && !(typeof encrypted === "object" && encrypted !== null && "then" in encrypted && typeof encrypted.then === "function")) return;
50
+ if (typeof encrypted !== "string" && !(typeof encrypted === "object" && encrypted !== null && "then" in encrypted && typeof encrypted.then === "function")) throw new Error("Invalid cache capture arguments");
50
51
  const serialized = await decryptActionBoundArgs(Promise.resolve(encrypted));
51
52
  if (typeof serialized !== "string") throw new Error("Invalid cache capture arguments");
52
53
  const payload = JSON.parse(serialized);
53
- if (payload.version !== 1) throw new Error("Invalid cache capture arguments");
54
+ if (payload.version !== 1 || payload.referenceId !== referenceId) throw new Error("Invalid cache capture arguments");
54
55
  const files = restoreFlightReply(payload.files);
55
56
  if (typeof files === "string") throw new Error("Invalid cache capture files");
56
- return await createFromReadableStream(new Response(Buffer.from(payload.result, "base64")).body, { temporaryReferences: new Map([...files].map(([id, file]) => [`$${id}`, file])) }, { preserveServerReferences: true });
57
+ const captures = await createFromReadableStream(new Response(Buffer.from(payload.result, "base64")).body, { temporaryReferences: new Map([...files].map(([id, file]) => [`$${id}`, file])) }, { preserveServerReferences: true });
58
+ if (!Array.isArray(captures) || captures.length !== captureCount) throw new Error("Invalid cache capture arguments");
59
+ return captures;
57
60
  }
58
- function registerCachedFunction(fn, id, variant, options) {
61
+ function registerCachedFunction(fn, id, variant, { captureCount, ...options }) {
62
+ let decryptCaptures;
63
+ if (captureCount !== void 0) {
64
+ const referenceId = options.serverReferenceId;
65
+ if (referenceId === void 0) throw new Error(`Cache function ${id} has captures but no server reference`);
66
+ decryptCaptures = (value) => decryptCacheCaptures(value, referenceId, captureCount);
67
+ }
59
68
  return registerCachedFunction$1(fn, id, variant, {
60
69
  ...options,
61
- decryptCaptures: decryptCacheCaptures,
70
+ ...decryptCaptures ? { decryptCaptures } : {},
62
71
  encodeInvocation: encryptArguments
63
72
  });
64
73
  }
@@ -8,7 +8,6 @@ var NoOpCacheHandler = class {
8
8
  async revalidateTag(_tags, _durations) {}
9
9
  };
10
10
  const DEFAULT_MEMORY_CACHE_MAX_SIZE = 52428800;
11
- const MAX_REVALIDATED_TAG_ENTRIES = 1e4;
12
11
  function estimateStringMapSize(map) {
13
12
  if (!map) return 0;
14
13
  let size = 0;
@@ -151,14 +150,7 @@ var MemoryCacheHandler = class {
151
150
  async revalidateTag(tags) {
152
151
  const tagList = Array.isArray(tags) ? tags : [tags];
153
152
  const now = Date.now();
154
- for (const tag of tagList) {
155
- this.tagRevalidatedAt.set(tag, now);
156
- while (this.tagRevalidatedAt.size > MAX_REVALIDATED_TAG_ENTRIES) {
157
- const oldest = this.tagRevalidatedAt.keys().next().value;
158
- if (oldest === void 0) break;
159
- this.tagRevalidatedAt.delete(oldest);
160
- }
161
- }
153
+ for (const tag of tagList) this.tagRevalidatedAt.set(tag, now);
162
154
  }
163
155
  resetRequestCache() {}
164
156
  };
@@ -77,7 +77,12 @@ export type RegisterCachedFunctionOptions = {
77
77
  acceptsSecondArgument?: boolean;
78
78
  /** Number of declared arguments supplied by the directive transform. */
79
79
  argumentCount?: number;
80
- decryptCaptures?: (value: unknown) => Promise<unknown[] | undefined>;
80
+ /**
81
+ * Set only for an inline function that closes over values. It decrypts the
82
+ * capture envelope bound ahead of the call arguments and must reject any
83
+ * other first argument.
84
+ */
85
+ decryptCaptures?: (value: unknown) => Promise<unknown[]>;
81
86
  encodeInvocation?: (args: CacheFlightArguments) => Promise<string>;
82
87
  serverReferenceId?: string;
83
88
  };
@@ -4,13 +4,14 @@ import { VINEXT_RSC_MARKER_HEADER } from "../server/headers.js";
4
4
  import { workUnitAsyncStorage } from "./internal/work-unit-async-storage.js";
5
5
  import { isRouteCacheabilityProbe, recordRouteCacheabilityProbeBailout } from "./cacheability-classification.js";
6
6
  import { getDataCacheHandler } from "./cache-handler.js";
7
+ import { addCollectedRequestTags, getCurrentFetchSoftTags, runWithDetachedFetchObservations } from "./fetch-cache-state.js";
7
8
  import { suppressHangingPromiseAbortRejections } from "./internal/make-hanging-promise.js";
8
9
  import { createPprFallbackShellSuspensePromise, trackPprFallbackShellCacheTask } from "./ppr-fallback-shell.js";
9
10
  import { markDynamicUsage, throwIfInsideCacheScope } from "./internal/headers-state.js";
10
11
  import { isDraftModeEnabled } from "./headers.js";
11
12
  import { _registerCacheContextAccessor } from "./internal/cache-context-accessor.js";
12
13
  import { _hasPendingRevalidatedTag, _setRequestScopedCacheLife, cacheLifeProfiles, runWithDetachedCacheObservations, shouldServeStaleUnstableCacheEntry } from "./cache-request-state.js";
13
- import { addCollectedRequestTags, getCurrentFetchSoftTags, runWithDetachedFetchObservations } from "./fetch-cache.js";
14
+ import "./fetch-cache.js";
14
15
  import { hasUseCacheLayoutMarker, hasUseCachePageMarker, isUseCacheFunctionReference, withoutUseCacheSegmentMarker } from "./internal/app-page-props-cache-key.js";
15
16
  import { getFallbackParamsSnapshot, makeThenableParams, restoreThenableParams } from "./thenable-params.js";
16
17
  import { getCurrentRootParams } from "./root-params.js";
@@ -137,8 +137,8 @@ type UnstableCacheOptions = {
137
137
  /**
138
138
  * Wrap an async function with caching.
139
139
  *
140
- * Returns a new function that caches results. The cache key is derived
141
- * from keyParts + serialized arguments.
140
+ * Returns a new function that caches results. The cache key is a SHA-256
141
+ * digest of the callback source, keyParts and serialized arguments.
142
142
  */
143
143
  export declare function unstable_cache<T extends (...args: any[]) => Promise<any>>(fn: T, keyParts?: string[], options?: UnstableCacheOptions): T;
144
144
  //#endregion
@@ -1,18 +1,19 @@
1
1
  import { getOrCreateAls } from "./internal/als-registry.js";
2
2
  import { getRequestContext, isInsideUnifiedScope } from "./unified-request-context.js";
3
3
  import { getRequestExecutionContext, runWithExecutionContext } from "./request-context.js";
4
+ import { isInsideWorkStoreScope } from "./internal/work-store-scope.js";
4
5
  import { workUnitAsyncStorage } from "./internal/work-unit-async-storage.js";
5
6
  import { getCdnCacheAdapter } from "./cdn-cache.js";
6
7
  import { isStagedCacheabilityProbeActive } from "./cacheability-classification.js";
7
- 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
+ import { fnv1a64, sha256Hex } from "../utils/hash.js";
11
+ import { addCollectedRequestTags, getCurrentFetchSoftTags, runWithDetachedFetchObservations } from "./fetch-cache-state.js";
10
12
  import { makeHangingPromise } from "./internal/make-hanging-promise.js";
11
13
  import { getHeadersAccessPhase, markDynamicUsage } from "./internal/headers-state.js";
12
14
  import { isDraftModeEnabled } from "./headers.js";
13
15
  import { _recordUseCacheRootParamRead, _registerCacheContextAccessor, getRegisteredCacheContext } from "./internal/cache-context-accessor.js";
14
16
  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";
16
17
  //#region src/shims/cache.ts
17
18
  /**
18
19
  * next/cache shim
@@ -323,6 +324,7 @@ const UNSTABLE_CACHE_KEY_PREFIX = "unstable_cache:v2";
323
324
  */
324
325
  const _unstableCacheAls = getOrCreateAls("vinext.unstableCache.als");
325
326
  const _useCacheContextAls = getOrCreateAls("vinext.cacheRuntime.contextAls");
327
+ const _unstableCacheCallbackAls = getOrCreateAls("vinext.unstableCache.callbackAls");
326
328
  function serializeUnstableCacheResult(value) {
327
329
  return JSON.stringify(value === void 0 ? { undef: true } : { v: value });
328
330
  }
@@ -348,6 +350,18 @@ function tryDeserializeUnstableCacheResult(body) {
348
350
  function isInsideUnstableCacheScope() {
349
351
  return _unstableCacheAls.getStore() === true;
350
352
  }
353
+ /**
354
+ * Whether an unstable_cache call is nested in another one's callback, as
355
+ * Next.js's `isNestedUnstableCache` decides: only where Next.js has a work
356
+ * store (not in Pages Router or outside a render), and only when the
357
+ * innermost cache scope is that callback rather than a "use cache" function
358
+ * it called.
359
+ * Source: https://github.com/vercel/next.js/blob/canary/packages/next/src/server/web/spec-extension/unstable-cache.ts
360
+ */
361
+ function isNestedUnstableCacheCall() {
362
+ const callback = _unstableCacheCallbackAls.getStore();
363
+ return callback !== void 0 && callback.useCacheContext === _useCacheContextAls.getStore() && isInsideWorkStoreScope();
364
+ }
351
365
  const _UNSTABLE_CACHE_PENDING_REVALIDATIONS_KEY = Symbol.for("vinext.unstableCache.pendingRevalidations");
352
366
  function getPendingUnstableCacheRevalidations() {
353
367
  const existing = _g[_UNSTABLE_CACHE_PENDING_REVALIDATIONS_KEY];
@@ -371,8 +385,10 @@ function scheduleUnstableCacheBackgroundRevalidation(cacheKey, refresh) {
371
385
  pending.set(cacheKey, trackedRevalidation);
372
386
  waitUntilUnstableCacheRevalidation(trackedRevalidation);
373
387
  }
374
- async function refreshUnstableCacheResult(fn, args, cacheKey, tags, revalidateSeconds) {
375
- const result = await _unstableCacheAls.run(true, () => fn(...args));
388
+ async function refreshUnstableCacheResult(fn, args, keyedArgs, cacheKey, tags, revalidateSeconds) {
389
+ const argsUnchanged = serializeArgsOrNull(args) === keyedArgs;
390
+ const result = await _unstableCacheAls.run(true, () => _unstableCacheCallbackAls.run({ useCacheContext: _useCacheContextAls.getStore() }, () => fn(...args)));
391
+ if (!argsUnchanged) return result;
376
392
  const cacheValue = {
377
393
  kind: "FETCH",
378
394
  data: {
@@ -390,29 +406,40 @@ async function refreshUnstableCacheResult(fn, args, cacheKey, tags, revalidateSe
390
406
  });
391
407
  return result;
392
408
  }
409
+ function serializeArgsOrNull(args) {
410
+ try {
411
+ return JSON.stringify(args);
412
+ } catch {
413
+ return null;
414
+ }
415
+ }
393
416
  /**
394
417
  * Wrap an async function with caching.
395
418
  *
396
- * Returns a new function that caches results. The cache key is derived
397
- * from keyParts + serialized arguments.
419
+ * Returns a new function that caches results. The cache key is a SHA-256
420
+ * digest of the callback source, keyParts and serialized arguments.
398
421
  */
399
422
  function unstable_cache(fn, keyParts, options) {
400
- const baseKey = keyParts ? keyParts.join(":") : fnv1a64(fn.toString());
423
+ if (typeof window !== "undefined") return function cached(...args) {
424
+ return fn.apply(this, args);
425
+ };
426
+ const fixedKey = JSON.stringify([fn.toString(), keyParts ?? null]);
401
427
  const tags = encodeCacheTags(options?.tags ?? []);
402
428
  const revalidateSeconds = options?.revalidate;
403
429
  const cachedFn = async (...args) => {
404
- const argsKey = JSON.stringify(args);
405
- const cacheKey = `${UNSTABLE_CACHE_KEY_PREFIX}:${baseKey}:${argsKey}`;
430
+ const keyedArgs = JSON.stringify(args);
431
+ const invocationKey = `${fixedKey}${keyedArgs}`;
406
432
  addCollectedRequestTags(tags);
407
433
  recordUnstableCacheObservation({
408
434
  kind: "unstable_cache",
409
- keyHash: fnv1a64(cacheKey),
435
+ keyHash: fnv1a64(invocationKey),
410
436
  revalidate: typeof revalidateSeconds === "number" ? revalidateSeconds : revalidateSeconds === false ? false : null,
411
437
  tagCount: tags.length,
412
438
  tagHash: tags.length > 0 ? fnv1a64(JSON.stringify(tags)) : null
413
439
  });
440
+ const cacheKey = `${UNSTABLE_CACHE_KEY_PREFIX}:${await sha256Hex(invocationKey)}`;
414
441
  const isDraftMode = isDraftModeEnabled();
415
- if (!isDraftMode) {
442
+ if (!isDraftMode && !isNestedUnstableCacheCall()) {
416
443
  const softTags = getCurrentFetchSoftTags();
417
444
  const existing = _hasPendingRevalidatedTag([...tags, ...softTags]) ? null : await getDataCacheHandler().get(cacheKey, {
418
445
  kind: "FETCH",
@@ -424,7 +451,7 @@ function unstable_cache(fn, keyParts, options) {
424
451
  if (cached.ok) {
425
452
  if (existing.cacheState === "stale") {
426
453
  if (shouldServeStaleUnstableCacheEntry()) {
427
- scheduleUnstableCacheBackgroundRevalidation(cacheKey, () => refreshUnstableCacheResult(fn, args, cacheKey, tags, revalidateSeconds));
454
+ scheduleUnstableCacheBackgroundRevalidation(cacheKey, () => refreshUnstableCacheResult(fn, args, keyedArgs, cacheKey, tags, revalidateSeconds));
428
455
  return cached.value;
429
456
  }
430
457
  } else return cached.value;
@@ -432,7 +459,7 @@ function unstable_cache(fn, keyParts, options) {
432
459
  }
433
460
  }
434
461
  if (isDraftMode) return await _unstableCacheAls.run(true, () => fn(...args));
435
- return await refreshUnstableCacheResult(fn, args, cacheKey, tags, revalidateSeconds);
462
+ return await refreshUnstableCacheResult(fn, args, keyedArgs, cacheKey, tags, revalidateSeconds);
436
463
  };
437
464
  return cachedFn;
438
465
  }
@@ -54,6 +54,8 @@ export type CdnResponsePolicy = {
54
54
  export declare function splitCacheControlDirectives(cacheControl: string): string[];
55
55
  /** Whether a Cache-Control value contains an exact non-cacheable directive. */
56
56
  export declare function isNonCacheableCacheControl(cacheControl: string, scope?: "shared" | "browser"): boolean;
57
+ /** Whether a request carries credentials a shared response cache must not capture. */
58
+ export declare function hasSharedCacheCredentials(headers: Headers): boolean;
57
59
  /**
58
60
  * The serving strategy for page-level ISR. Implement this to delegate
59
61
  * page/route/image caching to a CDN edge instead of the origin store.
@@ -88,6 +90,12 @@ export type CdnCacheAdapter = {
88
90
  deferCompletedPageResponseAdmission?(response: Response, complete: (response: Response) => Promise<Response>): Response | null;
89
91
  /** Capture the full-route RSC side stream while admitting a completed HTML response. */
90
92
  captureAppPageRscData?(rscData: Promise<ArrayBuffer>): void;
93
+ /**
94
+ * Whether this adapter sends the 304 for a Pages render whose If-None-Match
95
+ * matches. When it does, the render returns the page, so an adapter that
96
+ * stores completed responses stores the page rather than the 304.
97
+ */
98
+ deferNotModifiedResponse?(): boolean;
91
99
  /**
92
100
  * Validate provider-specific request routing before the application handles
93
101
  * the request. Returning a response short-circuits the request pipeline;
@@ -31,6 +31,22 @@ function isNonCacheableCacheControl(cacheControl, scope = "shared") {
31
31
  return name === "no-store" || equals === -1 && (name === "no-cache" || scope === "shared" && name === "private");
32
32
  });
33
33
  }
34
+ /**
35
+ * Request headers that identify the caller. A shared response cache never
36
+ * admits a Route Handler or API response's own policy for a request carrying
37
+ * them, and never replays such a render to refill its data entries.
38
+ * `x-api-key` matches the fetch cache's credential headers.
39
+ */
40
+ const SHARED_CACHE_CREDENTIAL_HEADERS = [
41
+ "authorization",
42
+ "cookie",
43
+ "proxy-authorization",
44
+ "x-api-key"
45
+ ];
46
+ /** Whether a request carries credentials a shared response cache must not capture. */
47
+ function hasSharedCacheCredentials(headers) {
48
+ return SHARED_CACHE_CREDENTIAL_HEADERS.some((name) => headers.has(name));
49
+ }
34
50
  const PENDING_DYNAMIC_CACHE_CONTROL = "no-store, must-revalidate";
35
51
  /**
36
52
  * Default origin-managed ISR strategy: store page artifacts in the data cache,
@@ -95,4 +111,4 @@ function getCdnCacheAdapter() {
95
111
  return _defaultAdapter ??= new DefaultCdnCacheAdapter();
96
112
  }
97
113
  //#endregion
98
- export { DefaultCdnCacheAdapter, getCdnCacheAdapter, isNonCacheableCacheControl, setCdnCacheAdapter, splitCacheControlDirectives };
114
+ export { DefaultCdnCacheAdapter, getCdnCacheAdapter, hasSharedCacheCredentials, isNonCacheableCacheControl, setCdnCacheAdapter, splitCacheControlDirectives };
@@ -0,0 +1,3 @@
1
+ //#region src/shims/disable-smooth-scroll.d.ts
2
+ export declare function disableSmoothScrollDuringRouteTransition(fn: () => void): void;
3
+ //#endregion
@@ -0,0 +1,36 @@
1
+ //#region src/shims/disable-smooth-scroll.ts
2
+ /**
3
+ * Run a route-transition scroll with `scroll-behavior: auto` on `<html>`.
4
+ *
5
+ * Ported from Next.js:
6
+ * packages/next/src/shared/lib/router/utils/disable-smooth-scroll.ts
7
+ *
8
+ * Since Next.js 16 (vercel/next.js#84102) the override is opt-in: it only
9
+ * applies when the root element carries `data-scroll-behavior="smooth"`.
10
+ * Without the attribute, a page-level `scroll-behavior: smooth` is respected
11
+ * and route-change scrolls animate (development warns once about the missing
12
+ * opt-in). Hash-only navigations never use this helper, so in-page anchor
13
+ * jumps keep the smooth behavior.
14
+ */
15
+ let warnedMissingDataScrollBehavior = false;
16
+ function disableSmoothScrollDuringRouteTransition(fn) {
17
+ const htmlElement = document.documentElement;
18
+ if (htmlElement.dataset.scrollBehavior !== "smooth") {
19
+ if (process.env.NODE_ENV === "development" && !warnedMissingDataScrollBehavior && getComputedStyle(htmlElement).scrollBehavior === "smooth") {
20
+ warnedMissingDataScrollBehavior = true;
21
+ console.warn("Detected `scroll-behavior: smooth` on the `<html>` element. To disable smooth scrolling during route transitions, add `data-scroll-behavior=\"smooth\"` to your <html> element. Learn more: https://nextjs.org/docs/messages/missing-data-scroll-behavior");
22
+ }
23
+ fn();
24
+ return;
25
+ }
26
+ const previousScrollBehavior = htmlElement.style.scrollBehavior;
27
+ htmlElement.style.scrollBehavior = "auto";
28
+ htmlElement.getClientRects();
29
+ try {
30
+ fn();
31
+ } finally {
32
+ htmlElement.style.scrollBehavior = previousScrollBehavior;
33
+ }
34
+ }
35
+ //#endregion
36
+ export { disableSmoothScrollDuringRouteTransition };
@@ -0,0 +1,19 @@
1
+ import React from "react";
2
+ //#region src/shims/document-placeholders.d.ts
3
+ /** Attribute `<Head>` adds last on its opening tag. */
4
+ export declare const DOCUMENT_HEAD_OPEN_ATTRIBUTE = "data-vinext-head-open";
5
+ /** Attribute of the `<template>` `<Head>` renders as its last child. */
6
+ export declare const DOCUMENT_HEAD_CLOSE_ATTRIBUTE = "data-vinext-head-close";
7
+ export declare function createDocumentPlaceholderToken(): string;
8
+ export declare function withDocumentPlaceholders(element: React.ReactElement, token: string): React.ReactElement;
9
+ export declare function useDocumentPlaceholderToken(): string | null;
10
+ /**
11
+ * `<Main />`'s placeholder. Without a renderer-provided token (a Document
12
+ * rendered on its own, e.g. in tests) it falls back to a static comment.
13
+ */
14
+ export declare function getDocumentMainPlaceholder(token: string | null): string;
15
+ export declare function getDocumentScriptsPlaceholder(token: string | null): string;
16
+ /** The marker attribute on `<Head>`'s opening tag. */
17
+ export declare function getDocumentHeadOpenMarker(token: string): string;
18
+ export declare function getDocumentHeadCloseMarker(token: string): string;
19
+ //#endregion
@@ -0,0 +1,45 @@
1
+ import React from "react";
2
+ //#region src/shims/document-placeholders.ts
3
+ /**
4
+ * Per-render placeholders for the Pages Router `next/document` shims.
5
+ *
6
+ * The renderers splice the page body, `next/head` output, asset tags and
7
+ * hydration scripts into the serialized custom Document. Each render provides
8
+ * a fresh random token, and `<Head>`, `<Main />` and `<NextScript />` mark
9
+ * their splice points with it. Nothing the Document renders, request data in
10
+ * raw `<script>` text included, can know the token, so nothing can be mistaken
11
+ * for a splice point.
12
+ */
13
+ const DocumentPlaceholderContext = React.createContext(null);
14
+ /** Attribute `<Head>` adds last on its opening tag. */
15
+ const DOCUMENT_HEAD_OPEN_ATTRIBUTE = "data-vinext-head-open";
16
+ /** Attribute of the `<template>` `<Head>` renders as its last child. */
17
+ const DOCUMENT_HEAD_CLOSE_ATTRIBUTE = "data-vinext-head-close";
18
+ function createDocumentPlaceholderToken() {
19
+ return crypto.randomUUID();
20
+ }
21
+ function withDocumentPlaceholders(element, token) {
22
+ return React.createElement(DocumentPlaceholderContext.Provider, { value: token }, element);
23
+ }
24
+ function useDocumentPlaceholderToken() {
25
+ return React.useContext(DocumentPlaceholderContext);
26
+ }
27
+ /**
28
+ * `<Main />`'s placeholder. Without a renderer-provided token (a Document
29
+ * rendered on its own, e.g. in tests) it falls back to a static comment.
30
+ */
31
+ function getDocumentMainPlaceholder(token) {
32
+ return token ? `<!--__NEXT_MAIN__:${token}-->` : "<!-- __NEXT_MAIN__ -->";
33
+ }
34
+ function getDocumentScriptsPlaceholder(token) {
35
+ return token ? `<!--__NEXT_SCRIPTS__:${token}-->` : "<!-- __NEXT_SCRIPTS__ -->";
36
+ }
37
+ /** The marker attribute on `<Head>`'s opening tag. */
38
+ function getDocumentHeadOpenMarker(token) {
39
+ return ` ${DOCUMENT_HEAD_OPEN_ATTRIBUTE}="${token}"`;
40
+ }
41
+ function getDocumentHeadCloseMarker(token) {
42
+ return `<template ${DOCUMENT_HEAD_CLOSE_ATTRIBUTE}="${token}"></template>`;
43
+ }
44
+ //#endregion
45
+ export { DOCUMENT_HEAD_CLOSE_ATTRIBUTE, DOCUMENT_HEAD_OPEN_ATTRIBUTE, createDocumentPlaceholderToken, getDocumentHeadCloseMarker, getDocumentHeadOpenMarker, getDocumentMainPlaceholder, getDocumentScriptsPlaceholder, useDocumentPlaceholderToken, withDocumentPlaceholders };
@@ -1,4 +1,5 @@
1
1
  import { safeJsonStringify } from "../server/html.js";
2
+ import { DOCUMENT_HEAD_CLOSE_ATTRIBUTE, DOCUMENT_HEAD_OPEN_ATTRIBUTE, getDocumentMainPlaceholder, getDocumentScriptsPlaceholder, useDocumentPlaceholderToken } from "./document-placeholders.js";
2
3
  import React from "react";
3
4
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
4
5
  //#region src/shims/document.tsx
@@ -47,7 +48,7 @@ var Head = class extends React.Component {
47
48
  }
48
49
  render() {
49
50
  const { children, nonce, crossOrigin, ...props } = this.props;
50
- return /* @__PURE__ */ jsx("head", {
51
+ return /* @__PURE__ */ jsx(DocumentHeadElement, {
51
52
  ...props,
52
53
  ...nonce ? { [documentAssetMarkerAttributes.headNonce]: nonce } : {},
53
54
  ...crossOrigin ? { [documentAssetMarkerAttributes.headCrossOrigin]: crossOrigin } : {},
@@ -55,10 +56,19 @@ var Head = class extends React.Component {
55
56
  });
56
57
  }
57
58
  };
59
+ function DocumentHeadElement({ children, ...props }) {
60
+ const token = useDocumentPlaceholderToken();
61
+ return /* @__PURE__ */ jsxs("head", {
62
+ ...props,
63
+ ...token ? { [DOCUMENT_HEAD_OPEN_ATTRIBUTE]: token } : {},
64
+ children: [children, token ? /* @__PURE__ */ jsx("template", { [DOCUMENT_HEAD_CLOSE_ATTRIBUTE]: token }) : null]
65
+ });
66
+ }
58
67
  function Main() {
68
+ const token = useDocumentPlaceholderToken();
59
69
  return /* @__PURE__ */ jsx("div", {
60
70
  id: "__next",
61
- dangerouslySetInnerHTML: { __html: "__NEXT_MAIN__" }
71
+ dangerouslySetInnerHTML: { __html: getDocumentMainPlaceholder(token) }
62
72
  });
63
73
  }
64
74
  var NextScript = class extends React.Component {
@@ -80,13 +90,19 @@ var NextScript = class extends React.Component {
80
90
  }
81
91
  render() {
82
92
  const { nonce, crossOrigin } = this.props;
83
- return /* @__PURE__ */ jsx("span", {
93
+ return /* @__PURE__ */ jsx(NextScriptPlaceholder, {
84
94
  ...nonce ? { [documentAssetMarkerAttributes.scriptNonce]: nonce } : {},
85
- ...crossOrigin ? { [documentAssetMarkerAttributes.scriptCrossOrigin]: crossOrigin } : {},
86
- dangerouslySetInnerHTML: { __html: "<!-- __NEXT_SCRIPTS__ -->" }
95
+ ...crossOrigin ? { [documentAssetMarkerAttributes.scriptCrossOrigin]: crossOrigin } : {}
87
96
  });
88
97
  }
89
98
  };
99
+ function NextScriptPlaceholder(props) {
100
+ const token = useDocumentPlaceholderToken();
101
+ return /* @__PURE__ */ jsx("span", {
102
+ ...props,
103
+ dangerouslySetInnerHTML: { __html: getDocumentScriptsPlaceholder(token) }
104
+ });
105
+ }
90
106
  var Document = class extends React.Component {
91
107
  static getInitialProps(ctx) {
92
108
  return ctx.defaultGetInitialProps(ctx);
@@ -2,5 +2,6 @@ import React from "react";
2
2
  //#region src/shims/dynamic-preload-chunks.d.ts
3
3
  export declare function DynamicPreloadChunks(props: {
4
4
  moduleIds?: readonly string[];
5
+ assets: "styles" | "scripts";
5
6
  }): React.FunctionComponentElement<React.FragmentProps> | null;
6
7
  //#endregion
@@ -56,6 +56,7 @@ function DynamicPreloadChunks(props) {
56
56
  for (const file of files) {
57
57
  const assetHref = dynamicPreloadHref(file);
58
58
  if (assetHref.endsWith(".css")) {
59
+ if (props.assets !== "styles") continue;
59
60
  const href = appendAssetDeploymentIdQuery(assetHref);
60
61
  if (initialStylesheetHrefs?.has(href)) continue;
61
62
  preloadLinks.push(React.createElement("link", {
@@ -68,15 +69,18 @@ function DynamicPreloadChunks(props) {
68
69
  }));
69
70
  continue;
70
71
  }
71
- if (assetHref.endsWith(".js")) preloadLinks.push(React.createElement("link", {
72
- key: assetHref,
73
- rel: "modulepreload",
74
- href: assetHref,
75
- as: "script",
76
- crossOrigin,
77
- fetchPriority: "low",
78
- nonce
79
- }));
72
+ if (assetHref.endsWith(".js")) {
73
+ if (props.assets !== "scripts") continue;
74
+ preloadLinks.push(React.createElement("link", {
75
+ key: assetHref,
76
+ rel: "modulepreload",
77
+ href: assetHref,
78
+ as: "script",
79
+ crossOrigin,
80
+ fetchPriority: "low",
81
+ nonce
82
+ }));
83
+ }
80
84
  }
81
85
  return preloadLinks.length > 0 ? React.createElement(React.Fragment, null, ...preloadLinks) : null;
82
86
  }
@@ -4,7 +4,7 @@ import { DynamicOptions, DynamicOptionsLoadingProps, LoadableComponent, Loadable
4
4
  type DynamicInput<P> = DynamicOptions<P> | Loader<P>;
5
5
  /**
6
6
  * Retained for the Pages Router render pipeline, which calls this before
7
- * rendering. Dynamic imports now use React.lazy + Suspense, so there is no
7
+ * rendering. Dynamic imports now use React.lazy, so there is no
8
8
  * separate preload work to await.
9
9
  */
10
10
  export declare function flushPreloads(): Promise<void[]>;