vinext 0.1.8 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (285) hide show
  1. package/README.md +51 -30
  2. package/dist/build/css-url-assets.d.ts +3 -1
  3. package/dist/build/css-url-assets.js +18 -1
  4. package/dist/build/inject-pregenerated-paths.d.ts +7 -0
  5. package/dist/build/inject-pregenerated-paths.js +21 -0
  6. package/dist/build/layout-classification.js +1 -1
  7. package/dist/build/nitro-route-rules.js +1 -1
  8. package/dist/build/pages-client-assets-module.d.ts +11 -0
  9. package/dist/build/pages-client-assets-module.js +27 -0
  10. package/dist/build/prerender-server-entry.d.ts +1 -0
  11. package/dist/build/prerender-server-entry.js +49 -0
  12. package/dist/build/prerender-server-pool.d.ts +44 -0
  13. package/dist/build/prerender-server-pool.js +194 -0
  14. package/dist/build/prerender.d.ts +2 -1
  15. package/dist/build/prerender.js +98 -27
  16. package/dist/build/report.d.ts +13 -2
  17. package/dist/build/report.js +99 -2
  18. package/dist/build/run-prerender.d.ts +7 -0
  19. package/dist/build/run-prerender.js +12 -2
  20. package/dist/build/standalone.js +2 -0
  21. package/dist/cache/cache-adapters-virtual.js +3 -3
  22. package/dist/check.d.ts +4 -6
  23. package/dist/check.js +48 -11
  24. package/dist/cli-args.d.ts +1 -2
  25. package/dist/cli-args.js +1 -1
  26. package/dist/cli-dev-config.d.ts +12 -0
  27. package/dist/cli-dev-config.js +23 -0
  28. package/dist/cli.js +112 -96
  29. package/dist/{server → client}/dev-error-overlay-store.d.ts +1 -1
  30. package/dist/{server → client}/dev-error-overlay-store.js +1 -1
  31. package/dist/{server → client}/dev-error-overlay.d.ts +1 -1
  32. package/dist/{server → client}/dev-error-overlay.js +2 -2
  33. package/dist/client/navigation-runtime.d.ts +2 -0
  34. package/dist/client/navigation-runtime.js +3 -1
  35. package/dist/client/vinext-next-data.d.ts +4 -1
  36. package/dist/client/window-next.d.ts +2 -1
  37. package/dist/cloudflare/index.d.ts +2 -2
  38. package/dist/cloudflare/index.js +2 -2
  39. package/dist/config/config-matchers.js +45 -19
  40. package/dist/config/next-config.d.ts +41 -9
  41. package/dist/config/next-config.js +60 -3
  42. package/dist/config/prerender.d.ts +34 -0
  43. package/dist/config/prerender.js +55 -0
  44. package/dist/entries/app-browser-entry.js +5 -1
  45. package/dist/entries/app-rsc-entry.d.ts +5 -3
  46. package/dist/entries/app-rsc-entry.js +44 -10
  47. package/dist/entries/app-rsc-manifest.js +2 -0
  48. package/dist/entries/pages-client-entry.d.ts +3 -0
  49. package/dist/entries/pages-client-entry.js +28 -3
  50. package/dist/entries/pages-server-entry.js +23 -6
  51. package/dist/image/image-adapters-virtual.d.ts +59 -0
  52. package/dist/image/image-adapters-virtual.js +59 -0
  53. package/dist/index.d.ts +33 -0
  54. package/dist/index.js +482 -120
  55. package/dist/init-cloudflare.d.ts +43 -0
  56. package/dist/init-cloudflare.js +839 -0
  57. package/dist/init-platform.d.ts +40 -0
  58. package/dist/init-platform.js +195 -0
  59. package/dist/init.d.ts +16 -38
  60. package/dist/init.js +209 -99
  61. package/dist/node_modules/.pnpm/am-i-vibing@0.5.0/node_modules/am-i-vibing/dist/detector-1yx2Hoe0.js +294 -0
  62. package/dist/node_modules/.pnpm/process-ancestry@0.1.0/node_modules/process-ancestry/dist/index.js +94 -0
  63. package/dist/{cloudflare → packages/cloudflare}/src/cache/cdn-adapter.runtime.js +1 -1
  64. package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.d.ts +2 -2
  65. package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.js +9 -2
  66. package/dist/packages/cloudflare/src/deploy-config.js +150 -0
  67. package/dist/packages/cloudflare/src/deploy-help.js +55 -0
  68. package/dist/packages/cloudflare/src/deploy.js +272 -0
  69. package/dist/{cloudflare → packages/cloudflare/src}/tpr.d.ts +4 -41
  70. package/dist/{cloudflare → packages/cloudflare/src}/tpr.js +44 -20
  71. package/dist/plugins/ast-scope.d.ts +16 -0
  72. package/dist/plugins/ast-scope.js +62 -0
  73. package/dist/plugins/ast-utils.d.ts +27 -1
  74. package/dist/plugins/ast-utils.js +32 -1
  75. package/dist/plugins/css-module-imports.d.ts +14 -0
  76. package/dist/plugins/css-module-imports.js +59 -0
  77. package/dist/plugins/extensionless-dynamic-import.js +2 -2
  78. package/dist/plugins/fonts.js +1 -1
  79. package/dist/plugins/ignore-dynamic-requests.d.ts +11 -0
  80. package/dist/plugins/ignore-dynamic-requests.js +530 -0
  81. package/dist/plugins/og-assets.js +2 -1
  82. package/dist/plugins/optimize-imports.js +1 -1
  83. package/dist/plugins/rsc-reference-validation-normalizer.d.ts +12 -0
  84. package/dist/plugins/rsc-reference-validation-normalizer.js +48 -0
  85. package/dist/plugins/sass.d.ts +17 -1
  86. package/dist/plugins/sass.js +74 -1
  87. package/dist/plugins/styled-jsx.d.ts +16 -0
  88. package/dist/plugins/styled-jsx.js +149 -0
  89. package/dist/plugins/typeof-window.d.ts +1 -1
  90. package/dist/plugins/typeof-window.js +28 -56
  91. package/dist/routing/app-route-graph.d.ts +23 -2
  92. package/dist/routing/app-route-graph.js +138 -38
  93. package/dist/routing/file-matcher.d.ts +11 -1
  94. package/dist/routing/file-matcher.js +18 -3
  95. package/dist/routing/pages-router.js +2 -2
  96. package/dist/server/api-handler.js +9 -14
  97. package/dist/server/app-browser-action-result.d.ts +4 -1
  98. package/dist/server/app-browser-action-result.js +8 -1
  99. package/dist/server/app-browser-entry.js +198 -57
  100. package/dist/server/app-browser-interception-context.d.ts +1 -0
  101. package/dist/server/app-browser-interception-context.js +4 -2
  102. package/dist/server/app-browser-navigation-controller.d.ts +2 -0
  103. package/dist/server/app-browser-navigation-controller.js +60 -31
  104. package/dist/server/app-browser-server-action-client.d.ts +1 -1
  105. package/dist/server/app-browser-server-action-client.js +8 -7
  106. package/dist/server/app-browser-state.d.ts +12 -1
  107. package/dist/server/app-browser-state.js +25 -8
  108. package/dist/server/app-browser-visible-commit.d.ts +6 -1
  109. package/dist/server/app-browser-visible-commit.js +42 -24
  110. package/dist/server/app-elements-wire.d.ts +9 -2
  111. package/dist/server/app-elements-wire.js +8 -1
  112. package/dist/server/app-elements.d.ts +2 -2
  113. package/dist/server/app-elements.js +4 -3
  114. package/dist/server/app-fallback-renderer.d.ts +2 -1
  115. package/dist/server/app-fallback-renderer.js +10 -6
  116. package/dist/server/app-hydration-cache-publication.d.ts +11 -0
  117. package/dist/server/app-hydration-cache-publication.js +43 -0
  118. package/dist/server/app-middleware.d.ts +4 -3
  119. package/dist/server/app-middleware.js +8 -3
  120. package/dist/server/app-optimistic-routing.js +11 -4
  121. package/dist/server/app-page-boundary.js +2 -1
  122. package/dist/server/app-page-cache-finalizer.d.ts +1 -0
  123. package/dist/server/app-page-cache-finalizer.js +5 -4
  124. package/dist/server/app-page-cache-render.d.ts +1 -0
  125. package/dist/server/app-page-cache-render.js +8 -4
  126. package/dist/server/app-page-cache.d.ts +1 -0
  127. package/dist/server/app-page-cache.js +27 -7
  128. package/dist/server/app-page-dispatch.d.ts +1 -0
  129. package/dist/server/app-page-dispatch.js +26 -8
  130. package/dist/server/app-page-element-builder.d.ts +2 -1
  131. package/dist/server/app-page-element-builder.js +59 -4
  132. package/dist/server/app-page-execution.js +2 -1
  133. package/dist/server/app-page-probe.js +5 -0
  134. package/dist/server/app-page-render-identity.d.ts +2 -0
  135. package/dist/server/app-page-render-identity.js +3 -2
  136. package/dist/server/app-page-render.d.ts +2 -0
  137. package/dist/server/app-page-render.js +85 -16
  138. package/dist/server/app-page-request.d.ts +14 -0
  139. package/dist/server/app-page-request.js +69 -4
  140. package/dist/server/app-page-response.d.ts +7 -0
  141. package/dist/server/app-page-response.js +16 -4
  142. package/dist/server/app-page-route-wiring.d.ts +8 -1
  143. package/dist/server/app-page-route-wiring.js +32 -18
  144. package/dist/server/app-page-segment-state.d.ts +2 -1
  145. package/dist/server/app-page-segment-state.js +3 -1
  146. package/dist/server/app-page-stream.d.ts +7 -1
  147. package/dist/server/app-page-stream.js +3 -1
  148. package/dist/server/app-route-handler-execution.js +5 -1
  149. package/dist/server/app-route-handler-response.js +1 -0
  150. package/dist/server/app-route-handler-runtime.js +1 -1
  151. package/dist/server/app-route-tree-prefetch.d.ts +43 -0
  152. package/dist/server/app-route-tree-prefetch.js +187 -0
  153. package/dist/server/app-router-entry.js +9 -2
  154. package/dist/server/app-rsc-cache-busting.d.ts +2 -1
  155. package/dist/server/app-rsc-cache-busting.js +9 -4
  156. package/dist/server/app-rsc-handler.d.ts +7 -0
  157. package/dist/server/app-rsc-handler.js +148 -39
  158. package/dist/server/app-rsc-render-mode.d.ts +3 -2
  159. package/dist/server/app-rsc-render-mode.js +4 -1
  160. package/dist/server/app-rsc-request-normalization.d.ts +6 -6
  161. package/dist/server/app-rsc-request-normalization.js +10 -8
  162. package/dist/server/app-segment-config.d.ts +11 -0
  163. package/dist/server/app-segment-config.js +62 -6
  164. package/dist/server/app-server-action-execution.d.ts +1 -0
  165. package/dist/server/app-server-action-execution.js +61 -30
  166. package/dist/server/app-ssr-entry.d.ts +3 -0
  167. package/dist/server/app-ssr-entry.js +13 -5
  168. package/dist/server/app-ssr-stream.d.ts +7 -3
  169. package/dist/server/app-ssr-stream.js +10 -6
  170. package/dist/server/app-visited-response-cache.d.ts +6 -0
  171. package/dist/server/app-visited-response-cache.js +3 -1
  172. package/dist/server/cache-control.d.ts +3 -1
  173. package/dist/server/cache-control.js +13 -1
  174. package/dist/server/client-trace-metadata.js +26 -0
  175. package/dist/server/default-global-not-found-module.d.ts +14 -0
  176. package/dist/server/default-global-not-found-module.js +14 -0
  177. package/dist/server/dev-route-files.js +4 -0
  178. package/dist/server/dev-server.d.ts +11 -1
  179. package/dist/server/dev-server.js +94 -35
  180. package/dist/server/dev-stack-sourcemap.d.ts +1 -1
  181. package/dist/server/dev-stack-sourcemap.js +1 -1
  182. package/dist/server/fetch-handler.d.ts +2 -0
  183. package/dist/server/fetch-handler.js +18 -0
  184. package/dist/server/headers.d.ts +7 -15
  185. package/dist/server/headers.js +11 -18
  186. package/dist/server/image-optimization.d.ts +51 -1
  187. package/dist/server/image-optimization.js +52 -2
  188. package/dist/server/implicit-tags.js +1 -1
  189. package/dist/server/isr-cache.d.ts +3 -2
  190. package/dist/server/isr-cache.js +9 -5
  191. package/dist/server/metadata-routes.d.ts +3 -1
  192. package/dist/server/metadata-routes.js +12 -2
  193. package/dist/server/middleware-runtime.js +6 -1
  194. package/dist/server/navigation-planner.d.ts +1 -0
  195. package/dist/server/navigation-planner.js +14 -3
  196. package/dist/server/pages-api-route.js +2 -2
  197. package/dist/server/pages-asset-tags.d.ts +4 -6
  198. package/dist/server/pages-asset-tags.js +12 -12
  199. package/dist/server/pages-client-assets.d.ts +12 -0
  200. package/dist/server/pages-client-assets.js +10 -0
  201. package/dist/server/pages-data-route.d.ts +4 -2
  202. package/dist/server/pages-data-route.js +18 -4
  203. package/dist/server/pages-dev-module-url.d.ts +2 -1
  204. package/dist/server/pages-dev-module-url.js +6 -3
  205. package/dist/server/pages-node-compat.d.ts +19 -1
  206. package/dist/server/pages-node-compat.js +81 -4
  207. package/dist/server/pages-page-data.d.ts +33 -1
  208. package/dist/server/pages-page-data.js +62 -33
  209. package/dist/server/pages-page-handler.d.ts +2 -1
  210. package/dist/server/pages-page-handler.js +38 -19
  211. package/dist/server/pages-page-response.d.ts +8 -0
  212. package/dist/server/pages-page-response.js +7 -3
  213. package/dist/server/pages-request-pipeline.d.ts +9 -5
  214. package/dist/server/pages-request-pipeline.js +55 -7
  215. package/dist/server/pages-router-entry.d.ts +30 -0
  216. package/dist/server/pages-router-entry.js +108 -0
  217. package/dist/server/prerender-manifest.d.ts +3 -1
  218. package/dist/server/prerender-route-params.js +1 -1
  219. package/dist/server/prod-server.d.ts +5 -3
  220. package/dist/server/prod-server.js +68 -39
  221. package/dist/server/request-pipeline.js +2 -1
  222. package/dist/server/seed-cache.js +4 -4
  223. package/dist/shims/app-router-scroll-state.d.ts +1 -0
  224. package/dist/shims/app-router-scroll-state.js +1 -0
  225. package/dist/shims/app-router-scroll.js +2 -1
  226. package/dist/shims/cache-handler.js +8 -1
  227. package/dist/shims/cache.js +22 -15
  228. package/dist/shims/cdn-cache.js +1 -1
  229. package/dist/shims/dynamic-preload-chunks.js +2 -1
  230. package/dist/shims/fetch-cache.d.ts +3 -1
  231. package/dist/shims/fetch-cache.js +77 -52
  232. package/dist/shims/form.d.ts +4 -2
  233. package/dist/shims/form.js +37 -43
  234. package/dist/shims/headers.d.ts +7 -1
  235. package/dist/shims/headers.js +17 -3
  236. package/dist/shims/image.js +75 -14
  237. package/dist/shims/internal/app-prefetch-fetch-queue.d.ts +10 -0
  238. package/dist/shims/internal/app-prefetch-fetch-queue.js +61 -0
  239. package/dist/shims/internal/app-route-detection.d.ts +2 -17
  240. package/dist/shims/internal/app-route-detection.js +4 -17
  241. package/dist/shims/internal/hybrid-client-route-owner-direct.d.ts +23 -0
  242. package/dist/shims/internal/hybrid-client-route-owner-direct.js +51 -0
  243. package/dist/shims/internal/hybrid-client-route-owner.d.ts +3 -15
  244. package/dist/shims/internal/hybrid-client-route-owner.js +40 -58
  245. package/dist/shims/internal/pages-data-fetch-dedup.d.ts +10 -5
  246. package/dist/shims/internal/pages-data-fetch-dedup.js +84 -14
  247. package/dist/shims/internal/pages-data-target.d.ts +18 -12
  248. package/dist/shims/internal/pages-data-target.js +97 -13
  249. package/dist/shims/internal/pages-router-components.d.ts +7 -0
  250. package/dist/shims/internal/pages-router-components.js +13 -0
  251. package/dist/shims/layout-segment-context.d.ts +4 -1
  252. package/dist/shims/layout-segment-context.js +18 -4
  253. package/dist/shims/link.d.ts +1 -1
  254. package/dist/shims/link.js +224 -58
  255. package/dist/shims/navigation.d.ts +19 -3
  256. package/dist/shims/navigation.js +245 -47
  257. package/dist/shims/request-context.js +18 -0
  258. package/dist/shims/root-params.d.ts +15 -1
  259. package/dist/shims/root-params.js +21 -1
  260. package/dist/shims/router.d.ts +5 -7
  261. package/dist/shims/router.js +387 -102
  262. package/dist/shims/server.js +3 -2
  263. package/dist/shims/slot.js +3 -6
  264. package/dist/shims/unified-request-context.js +1 -0
  265. package/dist/typegen.js +1 -1
  266. package/dist/utils/client-runtime-metadata.d.ts +2 -18
  267. package/dist/utils/client-runtime-metadata.js +31 -22
  268. package/dist/utils/dev-stack-sourcemap-endpoint.d.ts +4 -0
  269. package/dist/{server → utils}/dev-stack-sourcemap-endpoint.js +1 -1
  270. package/dist/utils/domain-locale.d.ts +6 -3
  271. package/dist/{server → utils}/middleware-request-headers.d.ts +1 -1
  272. package/dist/{server → utils}/middleware-request-headers.js +3 -3
  273. package/dist/utils/project.d.ts +48 -2
  274. package/dist/utils/project.js +225 -4
  275. package/dist/utils/protocol-headers.d.ts +23 -0
  276. package/dist/utils/protocol-headers.js +23 -0
  277. package/dist/utils/react-version.d.ts +4 -0
  278. package/dist/utils/react-version.js +44 -0
  279. package/dist/utils/vite-version.d.ts +2 -0
  280. package/dist/utils/vite-version.js +11 -1
  281. package/package.json +47 -2
  282. package/dist/deploy.d.ts +0 -197
  283. package/dist/deploy.js +0 -1040
  284. package/dist/server/dev-stack-sourcemap-endpoint.d.ts +0 -4
  285. /package/dist/{cloudflare → packages/cloudflare}/src/utils/cache-control-metadata.js +0 -0
@@ -1,4 +1,5 @@
1
- import "../../utils/deployment-id.js";
1
+ import "../../utils/protocol-headers.js";
2
+ import { getDeploymentId } from "../../utils/deployment-id.js";
2
3
  //#region src/shims/internal/pages-data-fetch-dedup.ts
3
4
  /**
4
5
  * In-flight request dedup for the Pages Router `/_next/data/<id>/<page>.json`
@@ -25,16 +26,87 @@ import "../../utils/deployment-id.js";
25
26
  * directly by anyone, which keeps subsequent clones legal even after one
26
27
  * caller has consumed its copy.
27
28
  *
28
- * - Each caller owns one waiter. Cancelling a waiter leaves the shared request
29
- * alive while another waiter remains; cancelling the final waiter aborts the
30
- * underlying fetch and evicts the entry immediately so a replacement caller
31
- * can retry without joining a doomed request.
29
+ * - Each caller owns one waiter. Cancelling a waiter rejects only that caller;
30
+ * the shared request continues and self-evicts when it settles. This mirrors
31
+ * Next.js: a superseded data request may still reach the server, but its
32
+ * result is ignored by the cancelled navigation.
32
33
  *
33
34
  * - The map is module-scoped (one per realm). The Pages Router runs in the
34
35
  * browser only, so a single `Map` is sufficient.
35
36
  */
36
37
  /** Inflight fetch entries keyed by the resolved data request identity. */
37
38
  const inflight = /* @__PURE__ */ new Map();
39
+ const staticDataCache = Object.create(null);
40
+ const staticDataSources = /* @__PURE__ */ new Map();
41
+ function getStaticDataKey(dataHref) {
42
+ if (typeof window === "undefined") return dataHref;
43
+ try {
44
+ return new URL(dataHref, window.location.href).href;
45
+ } catch {
46
+ return dataHref;
47
+ }
48
+ }
49
+ function cloneStaticResponse(cached, signal) {
50
+ if (signal?.aborted) return Promise.reject(new DOMException("Aborted", "AbortError"));
51
+ if (!signal) return cached.then((response) => response.clone());
52
+ return new Promise((resolve, reject) => {
53
+ const abort = () => reject(new DOMException("Aborted", "AbortError"));
54
+ signal.addEventListener("abort", abort, { once: true });
55
+ cached.then((response) => {
56
+ signal.removeEventListener("abort", abort);
57
+ resolve(response.clone());
58
+ }, (error) => {
59
+ signal.removeEventListener("abort", abort);
60
+ reject(error);
61
+ });
62
+ });
63
+ }
64
+ function getPagesStaticDataCache() {
65
+ return staticDataCache;
66
+ }
67
+ function fetchCachedPagesData(dataHref, init) {
68
+ const key = getStaticDataKey(dataHref);
69
+ let cached = staticDataSources.get(key);
70
+ if (cached === void 0) {
71
+ const { signal: _signal, ...sharedInit } = init ?? {};
72
+ cached = dedupedPagesDataFetch(dataHref, sharedInit).then((response) => {
73
+ const expectedDeploymentId = getDeploymentId() ?? null;
74
+ const responseDeploymentId = response.headers.get("x-nextjs-deployment-id");
75
+ if (!response.ok || response.headers.get("x-middleware-cache") === "no-cache" || response.headers.get("x-middleware-skip") !== null || responseDeploymentId !== null && responseDeploymentId !== expectedDeploymentId) {
76
+ delete staticDataCache[key];
77
+ staticDataSources.delete(key);
78
+ }
79
+ return response;
80
+ }).catch((error) => {
81
+ delete staticDataCache[key];
82
+ staticDataSources.delete(key);
83
+ throw error;
84
+ });
85
+ staticDataSources.set(key, cached);
86
+ const publicCached = cached.then((response) => response.clone());
87
+ publicCached.catch(() => {});
88
+ staticDataCache[key] = publicCached;
89
+ }
90
+ return cloneStaticResponse(cached, init?.signal ?? void 0);
91
+ }
92
+ function fetchStaticPagesData(dataHref, init) {
93
+ return fetchCachedPagesData(dataHref, init);
94
+ }
95
+ function fetchUncachedPagesData(dataHref, init) {
96
+ return fetch(dataHref, init).then(async (response) => {
97
+ const body = await response.arrayBuffer();
98
+ return new Response(body, {
99
+ headers: response.headers,
100
+ status: response.status,
101
+ statusText: response.statusText
102
+ });
103
+ });
104
+ }
105
+ function evictPagesDataCache(dataHref) {
106
+ const key = getStaticDataKey(dataHref);
107
+ delete staticDataCache[key];
108
+ staticDataSources.delete(key);
109
+ }
38
110
  function getInflightKey(dataHref, init) {
39
111
  let resolvedHref = dataHref;
40
112
  if (typeof window !== "undefined") try {
@@ -47,27 +119,23 @@ function cloneSharedResponse(key, entry, signal) {
47
119
  entry.waiters += 1;
48
120
  return new Promise((resolve, reject) => {
49
121
  let released = false;
50
- const release = (cancelled) => {
122
+ const release = () => {
51
123
  if (released) return;
52
124
  released = true;
53
125
  entry.waiters -= 1;
54
- if (cancelled && entry.waiters === 0 && !entry.settled) {
55
- if (inflight.get(key) === entry) inflight.delete(key);
56
- entry.controller.abort();
57
- }
58
126
  };
59
127
  const abort = () => {
60
- release(true);
128
+ release();
61
129
  reject(new DOMException("Aborted", "AbortError"));
62
130
  };
63
131
  signal?.addEventListener("abort", abort, { once: true });
64
132
  entry.promise.then((response) => {
65
133
  signal?.removeEventListener("abort", abort);
66
- release(false);
134
+ release();
67
135
  resolve(response.clone());
68
136
  }, (error) => {
69
137
  signal?.removeEventListener("abort", abort);
70
- release(false);
138
+ release();
71
139
  reject(error);
72
140
  });
73
141
  });
@@ -116,6 +184,8 @@ function dedupedPagesDataFetch(dataHref, init) {
116
184
  function clearPagesDataInflight() {
117
185
  for (const entry of inflight.values()) entry.controller.abort();
118
186
  inflight.clear();
187
+ staticDataSources.clear();
188
+ for (const key of Object.keys(staticDataCache)) delete staticDataCache[key];
119
189
  }
120
190
  //#endregion
121
- export { clearPagesDataInflight, dedupedPagesDataFetch };
191
+ export { clearPagesDataInflight, dedupedPagesDataFetch, evictPagesDataCache, fetchCachedPagesData, fetchStaticPagesData, fetchUncachedPagesData, getPagesStaticDataCache };
@@ -1,15 +1,19 @@
1
1
  //#region src/shims/internal/pages-data-target.d.ts
2
2
  type PagesDataTarget = {
3
- /** Final fetch URL for the data endpoint, including basePath and search. */dataHref: string; /** Matched route pattern (e.g. `/blog/[slug]`). */
3
+ /** Final fetch URL for the data endpoint, including basePath and search. */dataHref: string; /** Locale-qualified data endpoint used by Pages Router prefetch. */
4
+ prefetchDataHref?: string; /** Matched route pattern (e.g. `/blog/[slug]`). */
4
5
  pattern: string; /** Dynamic params extracted from the URL by the pattern matcher. */
5
6
  params: Record<string, string | string[]>; /** Code-split loader thunk for the matched route's page module. */
6
7
  loader: () => Promise<{
7
8
  default?: unknown;
8
9
  [key: string]: unknown;
9
- }>; /** Current buildId snapshot, used by the data URL and consistency checks. */
10
+ }>; /** Next.js data-fetch mode for this route. Plain pages are component-only. */
11
+ dataKind: "none" | "server" | "static"; /** Middleware-effect data URL to prefetch when the static matcher includes this route. */
12
+ middlewareDataHref?: string; /** Current buildId snapshot, used by the data URL and consistency checks. */
10
13
  buildId: string; /** Locale-prefixed (server-routable) page path. */
11
14
  pagePath: string; /** URL search string including the leading `?`. */
12
- search: string;
15
+ search: string; /** Locale selected for middleware-prefetch data URLs when the visible URL is unprefixed. */
16
+ prefetchLocale?: string;
13
17
  /**
14
18
  * Locale prefix detected on the URL, or `undefined` when the URL is
15
19
  * unprefixed (default locale, or no i18n configured). Lets the caller refresh
@@ -18,6 +22,10 @@ type PagesDataTarget = {
18
22
  */
19
23
  locale: string | undefined;
20
24
  };
25
+ type PagesDataNavigationTargetOptions = {
26
+ locale?: string | false;
27
+ };
28
+ declare function getPagesMiddlewareDataHref(browserUrl: string, basePath: string): string | null;
21
29
  /**
22
30
  * Decide whether the JSON data-endpoint navigation path is usable for this
23
31
  * browser URL. We require:
@@ -41,16 +49,14 @@ type PagesDataTarget = {
41
49
  * (`getDataHref`). vinext's equivalent uses an in-memory loader map instead
42
50
  * of Next.js' `_buildManifest.js`.
43
51
  */
44
- declare function resolvePagesDataNavigationTarget(browserUrl: string, basePath: string): PagesDataTarget | null;
52
+ declare function resolvePagesDataNavigationTarget(browserUrl: string, basePath: string, options?: PagesDataNavigationTargetOptions): PagesDataTarget | null;
45
53
  /**
46
- * Prefetch the data JSON and kick off the code-split loader so the chunk is
47
- * warm by the time the user clicks.
54
+ * Kick off the code-split loader and, for SSG pages, prefetch the data JSON so
55
+ * the chunk and payload are warm by the time the user clicks.
48
56
  *
49
- * Used by both `Router.prefetch()` and `<Link>` hover/viewport prefetch. The
50
- * JSON request uses `fetch()` rather than `<link rel="prefetch">` so it can
51
- * carry Next.js's `x-deployment-id` skew-protection header. The in-flight
52
- * request is shared with a racing navigation; after it settles, the browser's
53
- * normal HTTP cache remains responsible for reuse.
57
+ * Used by both `Router.prefetch()` and `<Link>` hover/viewport prefetch.
58
+ * Matches Next.js Pages Router prefetch: non-SSG routes only warm the page
59
+ * chunk, while `getStaticProps` routes also fetch `/_next/data`.
54
60
  *
55
61
  * loader's returned Promise is intentionally discarded — `import()` caches the
56
62
  * result, so a subsequent navigation re-invocation hits the cache without
@@ -59,4 +65,4 @@ declare function resolvePagesDataNavigationTarget(browserUrl: string, basePath:
59
65
  */
60
66
  declare function prefetchPagesData(target: PagesDataTarget): void;
61
67
  //#endregion
62
- export { PagesDataTarget, prefetchPagesData, resolvePagesDataNavigationTarget };
68
+ export { PagesDataTarget, getPagesMiddlewareDataHref, prefetchPagesData, resolvePagesDataNavigationTarget };
@@ -1,8 +1,9 @@
1
- import { stripBasePath } from "../../utils/base-path.js";
1
+ import { removeTrailingSlash, stripBasePath } from "../../utils/base-path.js";
2
+ import { isUnknownRecord } from "../../utils/record.js";
2
3
  import { getLocalePathPrefix } from "../../utils/domain-locale.js";
3
4
  import { buildPagesDataHref, matchPagesPattern } from "./pages-data-url.js";
4
5
  import { NEXT_DEPLOYMENT_ID_HEADER, getDeploymentId } from "../../utils/deployment-id.js";
5
- import { dedupedPagesDataFetch } from "./pages-data-fetch-dedup.js";
6
+ import { fetchStaticPagesData, fetchUncachedPagesData } from "./pages-data-fetch-dedup.js";
6
7
  //#region src/shims/internal/pages-data-target.ts
7
8
  /**
8
9
  * Shared decision helper for the Pages Router `/_next/data/<id>/<page>.json`
@@ -13,6 +14,75 @@ import { dedupedPagesDataFetch } from "./pages-data-fetch-dedup.js";
13
14
  * module init time — link.tsx and router.ts must remain free of circular
14
15
  * imports and SSR-side router-init side effects.
15
16
  */
17
+ function hasVinextMiddleware(nextData) {
18
+ if (!isUnknownRecord(nextData)) return false;
19
+ const vinext = nextData.__vinext;
20
+ return isUnknownRecord(vinext) && vinext.hasMiddleware === true;
21
+ }
22
+ function isClientMiddlewareMatcherObject(value) {
23
+ if (!isUnknownRecord(value)) return false;
24
+ if (typeof value.source !== "string") return false;
25
+ if (value.locale !== void 0 && value.locale !== false) return false;
26
+ if (value.has !== void 0 && !Array.isArray(value.has)) return false;
27
+ if (value.missing !== void 0 && !Array.isArray(value.missing)) return false;
28
+ return true;
29
+ }
30
+ function stripLocaleForMiddlewareMatcher(pathname) {
31
+ const locales = window.__VINEXT_LOCALES__;
32
+ if (!locales || locales.length === 0 || pathname === "/") return pathname;
33
+ const firstSegment = pathname.split("/")[1];
34
+ if (!firstSegment || !locales.includes(firstSegment)) return pathname;
35
+ return "/" + pathname.split("/").slice(2).join("/");
36
+ }
37
+ function clientMiddlewareSourceMatches(pathname, source) {
38
+ if (!/[\\():*+?]/.test(source)) return removeTrailingSlash(pathname) === removeTrailingSlash(source);
39
+ if (source.includes("(") || source.includes("\\")) return true;
40
+ const sourceParts = source.split("/").filter(Boolean);
41
+ const pathParts = pathname.split("/").filter(Boolean);
42
+ let pathIndex = 0;
43
+ for (const sourcePart of sourceParts) {
44
+ if (sourcePart.startsWith(":")) {
45
+ if (sourcePart.endsWith("*")) return true;
46
+ if (sourcePart.endsWith("+")) return pathIndex < pathParts.length;
47
+ if (pathIndex >= pathParts.length) return false;
48
+ pathIndex++;
49
+ continue;
50
+ }
51
+ if (pathParts[pathIndex] !== sourcePart) return false;
52
+ pathIndex++;
53
+ }
54
+ return pathIndex === pathParts.length;
55
+ }
56
+ function clientMiddlewareMatcherMatches(pathname, matcher) {
57
+ if (matcher === void 0) return true;
58
+ if (typeof matcher === "string") return clientMiddlewareSourceMatches(stripLocaleForMiddlewareMatcher(pathname), matcher);
59
+ if (!Array.isArray(matcher)) return true;
60
+ for (const item of matcher) {
61
+ if (typeof item === "string") {
62
+ if (clientMiddlewareSourceMatches(stripLocaleForMiddlewareMatcher(pathname), item)) return true;
63
+ continue;
64
+ }
65
+ if (!isClientMiddlewareMatcherObject(item)) return true;
66
+ if (clientMiddlewareSourceMatches(item.locale === false ? pathname : stripLocaleForMiddlewareMatcher(pathname), item.source)) return true;
67
+ }
68
+ return false;
69
+ }
70
+ function getPagesMiddlewareDataHref(browserUrl, basePath) {
71
+ const nextData = window.__NEXT_DATA__;
72
+ if (!nextData || !hasVinextMiddleware(nextData)) return null;
73
+ const buildId = nextData.buildId;
74
+ if (typeof buildId !== "string" || buildId.length === 0) return null;
75
+ let parsed;
76
+ try {
77
+ parsed = new URL(browserUrl, window.location.href);
78
+ } catch {
79
+ return null;
80
+ }
81
+ if (parsed.origin !== window.location.origin) return null;
82
+ const pathname = stripBasePath(parsed.pathname, basePath);
83
+ if (!clientMiddlewareMatcherMatches(pathname, window.__VINEXT_MIDDLEWARE_MATCHER__)) return null;
84
+ return buildPagesDataHref(basePath, buildId, pathname, parsed.search);
85
+ }
16
86
  /**
17
87
  * Decide whether the JSON data-endpoint navigation path is usable for this
18
88
  * browser URL. We require:
@@ -36,7 +106,7 @@ import { dedupedPagesDataFetch } from "./pages-data-fetch-dedup.js";
36
106
  * (`getDataHref`). vinext's equivalent uses an in-memory loader map instead
37
107
  * of Next.js' `_buildManifest.js`.
38
108
  */
39
- function resolvePagesDataNavigationTarget(browserUrl, basePath) {
109
+ function resolvePagesDataNavigationTarget(browserUrl, basePath, options = {}) {
40
110
  if (typeof window === "undefined") return null;
41
111
  const loaders = window.__VINEXT_PAGE_LOADERS__;
42
112
  const patterns = window.__VINEXT_PAGE_PATTERNS__;
@@ -56,26 +126,34 @@ function resolvePagesDataNavigationTarget(browserUrl, basePath) {
56
126
  if (!match) return null;
57
127
  const loader = loaders[match.pattern];
58
128
  if (!loader) return null;
129
+ const ssgPatterns = window.__VINEXT_PAGES_SSG_PATTERNS__;
130
+ const sspPatterns = window.__VINEXT_PAGES_SSP_PATTERNS__;
131
+ const dataKind = ssgPatterns?.includes(match.pattern) ? "static" : sspPatterns?.includes(match.pattern) ? "server" : ssgPatterns === void 0 || sspPatterns === void 0 ? "server" : "none";
132
+ const explicitLocale = options.locale === false ? window.__VINEXT_DEFAULT_LOCALE__ : options.locale;
133
+ const currentLocale = locale ?? explicitLocale ?? window.__VINEXT_LOCALE__;
134
+ const prefetchPagePath = locale || !currentLocale || !window.__VINEXT_LOCALES__?.includes(currentLocale) ? pagePath : `/${currentLocale}${pagePath === "/" ? "" : pagePath}`;
59
135
  return {
60
136
  dataHref: buildPagesDataHref(basePath, buildId, pagePath, parsed.search),
137
+ prefetchDataHref: buildPagesDataHref(basePath, buildId, prefetchPagePath, parsed.search),
61
138
  pattern: match.pattern,
62
139
  params: match.params,
63
140
  loader,
141
+ dataKind,
142
+ middlewareDataHref: getPagesMiddlewareDataHref(browserUrl, basePath) ?? void 0,
64
143
  buildId,
65
144
  pagePath,
66
145
  search: parsed.search,
146
+ prefetchLocale: currentLocale,
67
147
  locale
68
148
  };
69
149
  }
70
150
  /**
71
- * Prefetch the data JSON and kick off the code-split loader so the chunk is
72
- * warm by the time the user clicks.
151
+ * Kick off the code-split loader and, for SSG pages, prefetch the data JSON so
152
+ * the chunk and payload are warm by the time the user clicks.
73
153
  *
74
- * Used by both `Router.prefetch()` and `<Link>` hover/viewport prefetch. The
75
- * JSON request uses `fetch()` rather than `<link rel="prefetch">` so it can
76
- * carry Next.js's `x-deployment-id` skew-protection header. The in-flight
77
- * request is shared with a racing navigation; after it settles, the browser's
78
- * normal HTTP cache remains responsible for reuse.
154
+ * Used by both `Router.prefetch()` and `<Link>` hover/viewport prefetch.
155
+ * Matches Next.js Pages Router prefetch: non-SSG routes only warm the page
156
+ * chunk, while `getStaticProps` routes also fetch `/_next/data`.
79
157
  *
80
158
  * loader's returned Promise is intentionally discarded — `import()` caches the
81
159
  * result, so a subsequent navigation re-invocation hits the cache without
@@ -84,15 +162,21 @@ function resolvePagesDataNavigationTarget(browserUrl, basePath) {
84
162
  */
85
163
  function prefetchPagesData(target) {
86
164
  if (typeof document === "undefined") return;
165
+ target.loader().catch(() => {});
166
+ if (target.dataKind !== "static" && !target.middlewareDataHref) return;
87
167
  const headers = {
88
168
  Accept: "application/json",
89
169
  purpose: "prefetch",
90
170
  "x-nextjs-data": "1"
91
171
  };
172
+ if (target.middlewareDataHref) headers["x-middleware-prefetch"] = "1";
92
173
  const deploymentId = getDeploymentId();
93
174
  if (deploymentId) headers[NEXT_DEPLOYMENT_ID_HEADER] = deploymentId;
94
- dedupedPagesDataFetch(target.dataHref, { headers }).catch(() => {});
95
- target.loader().catch(() => {});
175
+ if (target.dataKind === "static") {
176
+ fetchStaticPagesData(target.middlewareDataHref && target.middlewareDataHref !== target.dataHref ? target.middlewareDataHref : target.prefetchDataHref ?? target.middlewareDataHref ?? target.dataHref, { headers }).then((response) => response.arrayBuffer()).catch(() => {});
177
+ return;
178
+ }
179
+ if (target.middlewareDataHref) fetchUncachedPagesData(target.middlewareDataHref, { headers }).catch(() => {});
96
180
  }
97
181
  //#endregion
98
- export { prefetchPagesData, resolvePagesDataNavigationTarget };
182
+ export { getPagesMiddlewareDataHref, prefetchPagesData, resolvePagesDataNavigationTarget };
@@ -0,0 +1,7 @@
1
+ //#region src/shims/internal/pages-router-components.d.ts
2
+ type PagesRouterComponentsMap = Record<string, {
3
+ __appRouter: true;
4
+ } | Record<string, unknown>>;
5
+ declare function getPagesRouterComponentsMap(): PagesRouterComponentsMap;
6
+ //#endregion
7
+ export { PagesRouterComponentsMap, getPagesRouterComponentsMap };
@@ -0,0 +1,13 @@
1
+ //#region src/shims/internal/pages-router-components.ts
2
+ const COMPONENTS_KEY = Symbol.for("vinext.pagesRouter.components");
3
+ function getPagesRouterComponentsMap() {
4
+ const globalState = globalThis;
5
+ let components = globalState[COMPONENTS_KEY];
6
+ if (!components) {
7
+ components = {};
8
+ globalState[COMPONENTS_KEY] = components;
9
+ }
10
+ return components;
11
+ }
12
+ //#endregion
13
+ export { getPagesRouterComponentsMap };
@@ -2,6 +2,7 @@ import { SegmentMap } from "./navigation-context-state.js";
2
2
  import { ReactNode } from "react";
3
3
 
4
4
  //#region src/shims/layout-segment-context.d.ts
5
+ declare function mergeLayoutSegmentMap(previous: SegmentMap | null, next: SegmentMap): SegmentMap;
5
6
  /**
6
7
  * Wraps children with the layout segment context.
7
8
  *
@@ -14,11 +15,13 @@ import { ReactNode } from "react";
14
15
  * to read the segments for a specific parallel route.
15
16
  */
16
17
  declare function LayoutSegmentProvider({
18
+ providerId,
17
19
  segmentMap,
18
20
  children
19
21
  }: {
22
+ providerId?: string;
20
23
  segmentMap: SegmentMap;
21
24
  children: ReactNode;
22
25
  }): string | number | bigint | boolean | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | import("react").FunctionComponentElement<import("react").ProviderProps<SegmentMap>> | null | undefined;
23
26
  //#endregion
24
- export { LayoutSegmentProvider };
27
+ export { LayoutSegmentProvider, mergeLayoutSegmentMap };
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { getLayoutSegmentContext } from "./navigation-context-state.js";
3
3
  import "./navigation-server.js";
4
- import { createElement } from "react";
4
+ import { createElement, useEffect, useRef } from "react";
5
5
  //#region src/shims/layout-segment-context.tsx
6
6
  /**
7
7
  * Layout segment context provider.
@@ -19,6 +19,14 @@ import { createElement } from "react";
19
19
  * The context is shared with navigation.ts via getLayoutSegmentContext()
20
20
  * to avoid creating separate contexts in different modules.
21
21
  */
22
+ const committedSegmentMapsByProviderId = /* @__PURE__ */ new Map();
23
+ function mergeLayoutSegmentMap(previous, next) {
24
+ if (!previous) return next;
25
+ return {
26
+ ...previous,
27
+ ...next
28
+ };
29
+ }
22
30
  /**
23
31
  * Wraps children with the layout segment context.
24
32
  *
@@ -30,10 +38,16 @@ import { createElement } from "react";
30
38
  * Components inside the provider call useSelectedLayoutSegments(parallelRoutesKey)
31
39
  * to read the segments for a specific parallel route.
32
40
  */
33
- function LayoutSegmentProvider({ segmentMap, children }) {
41
+ function LayoutSegmentProvider({ providerId, segmentMap, children }) {
42
+ const previousSegmentMap = useRef(null);
34
43
  const ctx = getLayoutSegmentContext();
44
+ const mergedSegmentMap = mergeLayoutSegmentMap(previousSegmentMap.current ?? (providerId ? committedSegmentMapsByProviderId.get(providerId) ?? null : null), segmentMap);
45
+ useEffect(() => {
46
+ previousSegmentMap.current = mergedSegmentMap;
47
+ if (providerId) committedSegmentMapsByProviderId.set(providerId, mergedSegmentMap);
48
+ }, [mergedSegmentMap, providerId]);
35
49
  if (!ctx) return children;
36
- return createElement(ctx.Provider, { value: segmentMap }, children);
50
+ return createElement(ctx.Provider, { value: mergedSegmentMap }, children);
37
51
  }
38
52
  //#endregion
39
- export { LayoutSegmentProvider };
53
+ export { LayoutSegmentProvider, mergeLayoutSegmentMap };
@@ -42,7 +42,7 @@ type LinkProps = {
42
42
  onNavigate?: (event: NavigateEvent) => void;
43
43
  children?: React.ReactNode;
44
44
  } & Omit<AnchorHTMLAttributes<HTMLAnchorElement>, "href">;
45
- type LinkPrefetchMode = "disabled" | "auto" | "full";
45
+ type LinkPrefetchMode = "disabled" | "auto" | "full" | "full-after-shell";
46
46
  declare global {
47
47
  interface Window {
48
48
  __VINEXT_LINK_PREFETCH_ROUTES__?: VinextLinkPrefetchRoute[];