vinext 0.0.29 → 0.0.31

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 (428) hide show
  1. package/README.md +12 -6
  2. package/dist/build/prerender.d.ts +188 -0
  3. package/dist/build/prerender.js +675 -0
  4. package/dist/build/prerender.js.map +1 -0
  5. package/dist/build/report.d.ts +45 -46
  6. package/dist/build/report.js +247 -276
  7. package/dist/build/report.js.map +1 -1
  8. package/dist/build/run-prerender.d.ts +62 -0
  9. package/dist/build/run-prerender.js +183 -0
  10. package/dist/build/run-prerender.js.map +1 -0
  11. package/dist/build/server-manifest.d.ts +19 -0
  12. package/dist/build/server-manifest.js +29 -0
  13. package/dist/build/server-manifest.js.map +1 -0
  14. package/dist/build/static-export.d.ts +51 -66
  15. package/dist/build/static-export.js +51 -545
  16. package/dist/build/static-export.js.map +1 -1
  17. package/dist/check.d.ts +26 -24
  18. package/dist/check.js +591 -567
  19. package/dist/check.js.map +1 -1
  20. package/dist/cli.d.ts +1 -15
  21. package/dist/cli.js +430 -491
  22. package/dist/cli.js.map +1 -1
  23. package/dist/client/entry.d.ts +1 -2
  24. package/dist/client/entry.js +49 -62
  25. package/dist/client/entry.js.map +1 -1
  26. package/dist/client/validate-module-path.d.ts +4 -1
  27. package/dist/client/validate-module-path.js +23 -28
  28. package/dist/client/validate-module-path.js.map +1 -1
  29. package/dist/client/vinext-next-data.d.ts +15 -20
  30. package/dist/client/vinext-next-data.js +0 -1
  31. package/dist/cloudflare/index.d.ts +3 -8
  32. package/dist/cloudflare/index.js +3 -8
  33. package/dist/cloudflare/kv-cache-handler.d.ts +95 -105
  34. package/dist/cloudflare/kv-cache-handler.js +354 -366
  35. package/dist/cloudflare/kv-cache-handler.js.map +1 -1
  36. package/dist/cloudflare/tpr.d.ts +36 -34
  37. package/dist/cloudflare/tpr.js +460 -603
  38. package/dist/cloudflare/tpr.js.map +1 -1
  39. package/dist/config/config-matchers.d.ts +31 -40
  40. package/dist/config/config-matchers.js +727 -936
  41. package/dist/config/config-matchers.js.map +1 -1
  42. package/dist/config/dotenv.d.ts +18 -11
  43. package/dist/config/dotenv.js +79 -84
  44. package/dist/config/dotenv.js.map +1 -1
  45. package/dist/config/next-config.d.ts +156 -146
  46. package/dist/config/next-config.js +374 -464
  47. package/dist/config/next-config.js.map +1 -1
  48. package/dist/deploy.d.ts +87 -96
  49. package/dist/deploy.js +490 -628
  50. package/dist/deploy.js.map +1 -1
  51. package/dist/entries/app-browser-entry.d.ts +4 -1
  52. package/dist/entries/app-browser-entry.js +12 -8
  53. package/dist/entries/app-browser-entry.js.map +1 -1
  54. package/dist/entries/app-rsc-entry.d.ts +33 -20
  55. package/dist/entries/app-rsc-entry.js +618 -343
  56. package/dist/entries/app-rsc-entry.js.map +1 -1
  57. package/dist/entries/app-ssr-entry.d.ts +9 -1
  58. package/dist/entries/app-ssr-entry.js +61 -28
  59. package/dist/entries/app-ssr-entry.js.map +1 -1
  60. package/dist/entries/pages-client-entry.d.ts +6 -2
  61. package/dist/entries/pages-client-entry.js +30 -33
  62. package/dist/entries/pages-client-entry.js.map +1 -1
  63. package/dist/entries/pages-entry-helpers.d.ts +5 -1
  64. package/dist/entries/pages-entry-helpers.js +17 -14
  65. package/dist/entries/pages-entry-helpers.js.map +1 -1
  66. package/dist/entries/pages-server-entry.d.ts +6 -2
  67. package/dist/entries/pages-server-entry.js +229 -207
  68. package/dist/entries/pages-server-entry.js.map +1 -1
  69. package/dist/index.d.ts +82 -62
  70. package/dist/index.js +2172 -3125
  71. package/dist/index.js.map +1 -1
  72. package/dist/init.d.ts +40 -37
  73. package/dist/init.js +201 -258
  74. package/dist/init.js.map +1 -1
  75. package/dist/plugins/async-hooks-stub.d.ts +7 -3
  76. package/dist/plugins/async-hooks-stub.js +39 -42
  77. package/dist/plugins/async-hooks-stub.js.map +1 -1
  78. package/dist/plugins/client-reference-dedup.d.ts +7 -3
  79. package/dist/plugins/client-reference-dedup.js +63 -88
  80. package/dist/plugins/client-reference-dedup.js.map +1 -1
  81. package/dist/routing/app-router.d.ts +100 -96
  82. package/dist/routing/app-router.js +563 -659
  83. package/dist/routing/app-router.js.map +1 -1
  84. package/dist/routing/file-matcher.d.ts +18 -15
  85. package/dist/routing/file-matcher.js +65 -65
  86. package/dist/routing/file-matcher.js.map +1 -1
  87. package/dist/routing/pages-router.d.ts +23 -24
  88. package/dist/routing/pages-router.js +147 -172
  89. package/dist/routing/pages-router.js.map +1 -1
  90. package/dist/routing/route-trie.d.ts +23 -20
  91. package/dist/routing/route-trie.js +131 -151
  92. package/dist/routing/route-trie.js.map +1 -1
  93. package/dist/routing/route-validation.d.ts +5 -2
  94. package/dist/routing/route-validation.js +98 -130
  95. package/dist/routing/route-validation.js.map +1 -1
  96. package/dist/routing/utils.d.ts +10 -7
  97. package/dist/routing/utils.js +75 -111
  98. package/dist/routing/utils.js.map +1 -1
  99. package/dist/server/api-handler.d.ts +8 -13
  100. package/dist/server/api-handler.js +161 -193
  101. package/dist/server/api-handler.js.map +1 -1
  102. package/dist/server/app-router-entry.d.ts +6 -16
  103. package/dist/server/app-router-entry.js +26 -54
  104. package/dist/server/app-router-entry.js.map +1 -1
  105. package/dist/server/dev-module-runner.d.ts +11 -64
  106. package/dist/server/dev-module-runner.js +89 -101
  107. package/dist/server/dev-module-runner.js.map +1 -1
  108. package/dist/server/dev-origin-check.d.ts +12 -10
  109. package/dist/server/dev-origin-check.js +98 -108
  110. package/dist/server/dev-origin-check.js.map +1 -1
  111. package/dist/server/dev-server.d.ts +17 -13
  112. package/dist/server/dev-server.js +547 -874
  113. package/dist/server/dev-server.js.map +1 -1
  114. package/dist/server/html.d.ts +4 -1
  115. package/dist/server/html.js +25 -26
  116. package/dist/server/html.js.map +1 -1
  117. package/dist/server/image-optimization.d.ts +31 -28
  118. package/dist/server/image-optimization.js +183 -200
  119. package/dist/server/image-optimization.js.map +1 -1
  120. package/dist/server/instrumentation.d.ts +25 -22
  121. package/dist/server/instrumentation.js +110 -122
  122. package/dist/server/instrumentation.js.map +1 -1
  123. package/dist/server/isr-cache.d.ts +16 -26
  124. package/dist/server/isr-cache.js +109 -126
  125. package/dist/server/isr-cache.js.map +1 -1
  126. package/dist/server/metadata-routes.d.ts +85 -88
  127. package/dist/server/metadata-routes.js +277 -286
  128. package/dist/server/metadata-routes.js.map +1 -1
  129. package/dist/server/middleware-codegen.d.ts +7 -4
  130. package/dist/server/middleware-codegen.js +98 -65
  131. package/dist/server/middleware-codegen.js.map +1 -1
  132. package/dist/server/middleware-request-headers.d.ts +8 -6
  133. package/dist/server/middleware-request-headers.js +47 -65
  134. package/dist/server/middleware-request-headers.js.map +1 -1
  135. package/dist/server/middleware.d.ts +31 -47
  136. package/dist/server/middleware.js +276 -363
  137. package/dist/server/middleware.js.map +1 -1
  138. package/dist/server/normalize-path.d.ts +4 -1
  139. package/dist/server/normalize-path.js +33 -47
  140. package/dist/server/normalize-path.js.map +1 -1
  141. package/dist/server/pages-i18n.d.ts +58 -0
  142. package/dist/server/pages-i18n.js +125 -0
  143. package/dist/server/pages-i18n.js.map +1 -0
  144. package/dist/server/prod-server.d.ts +19 -31
  145. package/dist/server/prod-server.js +714 -945
  146. package/dist/server/prod-server.js.map +1 -1
  147. package/dist/server/request-log.d.ts +18 -12
  148. package/dist/server/request-log.js +45 -52
  149. package/dist/server/request-log.js.map +1 -1
  150. package/dist/server/request-pipeline.d.ts +9 -17
  151. package/dist/server/request-pipeline.js +133 -184
  152. package/dist/server/request-pipeline.js.map +1 -1
  153. package/dist/server/worker-utils.d.ts +4 -1
  154. package/dist/server/worker-utils.js +31 -37
  155. package/dist/server/worker-utils.js.map +1 -1
  156. package/dist/shims/amp.d.ts +5 -2
  157. package/dist/shims/amp.js +19 -15
  158. package/dist/shims/amp.js.map +1 -1
  159. package/dist/shims/app.d.ts +8 -10
  160. package/dist/shims/app.js +0 -1
  161. package/dist/shims/cache-runtime.d.ts +21 -43
  162. package/dist/shims/cache-runtime.js +271 -405
  163. package/dist/shims/cache-runtime.js.map +1 -1
  164. package/dist/shims/cache.d.ts +131 -119
  165. package/dist/shims/cache.js +339 -418
  166. package/dist/shims/cache.js.map +1 -1
  167. package/dist/shims/client-only.d.ts +1 -18
  168. package/dist/shims/client-only.js +0 -17
  169. package/dist/shims/compat-router.d.ts +4 -1
  170. package/dist/shims/compat-router.js +23 -19
  171. package/dist/shims/compat-router.js.map +1 -1
  172. package/dist/shims/config.d.ts +7 -5
  173. package/dist/shims/config.js +16 -23
  174. package/dist/shims/config.js.map +1 -1
  175. package/dist/shims/constants.d.ts +119 -118
  176. package/dist/shims/constants.js +159 -165
  177. package/dist/shims/constants.js.map +1 -1
  178. package/dist/shims/document.d.ts +20 -16
  179. package/dist/shims/document.js +41 -22
  180. package/dist/shims/document.js.map +1 -1
  181. package/dist/shims/dynamic.d.ts +13 -22
  182. package/dist/shims/dynamic.js +122 -136
  183. package/dist/shims/dynamic.js.map +1 -1
  184. package/dist/shims/error-boundary.d.ts +22 -15
  185. package/dist/shims/error-boundary.js +81 -79
  186. package/dist/shims/error-boundary.js.map +1 -1
  187. package/dist/shims/error.d.ts +11 -12
  188. package/dist/shims/error.js +35 -39
  189. package/dist/shims/error.js.map +1 -1
  190. package/dist/shims/fetch-cache.d.ts +26 -10
  191. package/dist/shims/fetch-cache.js +443 -586
  192. package/dist/shims/fetch-cache.js.map +1 -1
  193. package/dist/shims/font-google-base.d.ts +28 -26
  194. package/dist/shims/font-google-base.js +238 -325
  195. package/dist/shims/font-google-base.js.map +1 -1
  196. package/dist/shims/font-google.d.ts +3 -3
  197. package/dist/shims/font-google.generated.d.ts +1928 -1924
  198. package/dist/shims/font-google.generated.js +1928 -2133
  199. package/dist/shims/font-google.generated.js.map +1 -1
  200. package/dist/shims/font-google.js +3 -3
  201. package/dist/shims/font-local.d.ts +28 -26
  202. package/dist/shims/font-local.js +204 -260
  203. package/dist/shims/font-local.js.map +1 -1
  204. package/dist/shims/form.d.ts +13 -27
  205. package/dist/shims/form.js +128 -180
  206. package/dist/shims/form.js.map +1 -1
  207. package/dist/shims/head-state.d.ts +9 -10
  208. package/dist/shims/head-state.js +25 -39
  209. package/dist/shims/head-state.js.map +1 -1
  210. package/dist/shims/head.d.ts +16 -18
  211. package/dist/shims/head.js +185 -153
  212. package/dist/shims/head.js.map +1 -1
  213. package/dist/shims/headers.d.ts +84 -71
  214. package/dist/shims/headers.js +447 -583
  215. package/dist/shims/headers.js.map +1 -1
  216. package/dist/shims/i18n-context.d.ts +23 -0
  217. package/dist/shims/i18n-context.js +44 -0
  218. package/dist/shims/i18n-context.js.map +1 -0
  219. package/dist/shims/i18n-state.d.ts +14 -0
  220. package/dist/shims/i18n-state.js +45 -0
  221. package/dist/shims/i18n-state.js.map +1 -0
  222. package/dist/shims/image-config.d.ts +11 -8
  223. package/dist/shims/image-config.js +50 -83
  224. package/dist/shims/image-config.js.map +1 -1
  225. package/dist/shims/image.d.ts +37 -44
  226. package/dist/shims/image.js +284 -301
  227. package/dist/shims/image.js.map +1 -1
  228. package/dist/shims/internal/api-utils.d.ts +7 -4
  229. package/dist/shims/internal/api-utils.js +0 -6
  230. package/dist/shims/internal/app-router-context.d.ts +22 -17
  231. package/dist/shims/internal/app-router-context.js +17 -13
  232. package/dist/shims/internal/app-router-context.js.map +1 -1
  233. package/dist/shims/internal/cookies.d.ts +2 -9
  234. package/dist/shims/internal/cookies.js +2 -9
  235. package/dist/shims/internal/parse-cookie-header.d.ts +4 -1
  236. package/dist/shims/internal/parse-cookie-header.js +29 -29
  237. package/dist/shims/internal/parse-cookie-header.js.map +1 -1
  238. package/dist/shims/internal/router-context.d.ts +6 -1
  239. package/dist/shims/internal/router-context.js +11 -7
  240. package/dist/shims/internal/router-context.js.map +1 -1
  241. package/dist/shims/internal/utils.d.ts +40 -36
  242. package/dist/shims/internal/utils.js +24 -30
  243. package/dist/shims/internal/utils.js.map +1 -1
  244. package/dist/shims/internal/work-unit-async-storage.d.ts +6 -10
  245. package/dist/shims/internal/work-unit-async-storage.js +14 -11
  246. package/dist/shims/internal/work-unit-async-storage.js.map +1 -1
  247. package/dist/shims/layout-segment-context.d.ts +11 -14
  248. package/dist/shims/layout-segment-context.js +24 -23
  249. package/dist/shims/layout-segment-context.js.map +1 -1
  250. package/dist/shims/legacy-image.d.ts +39 -46
  251. package/dist/shims/legacy-image.js +47 -42
  252. package/dist/shims/legacy-image.js.map +1 -1
  253. package/dist/shims/link.d.ts +32 -36
  254. package/dist/shims/link.js +262 -382
  255. package/dist/shims/link.js.map +1 -1
  256. package/dist/shims/metadata.d.ts +210 -202
  257. package/dist/shims/metadata.js +545 -544
  258. package/dist/shims/metadata.js.map +1 -1
  259. package/dist/shims/navigation-state.d.ts +19 -13
  260. package/dist/shims/navigation-state.js +68 -58
  261. package/dist/shims/navigation-state.js.map +1 -1
  262. package/dist/shims/navigation.d.ts +59 -63
  263. package/dist/shims/navigation.js +508 -690
  264. package/dist/shims/navigation.js.map +1 -1
  265. package/dist/shims/og.d.ts +2 -20
  266. package/dist/shims/og.js +2 -19
  267. package/dist/shims/readonly-url-search-params.d.ts +8 -5
  268. package/dist/shims/readonly-url-search-params.js +26 -22
  269. package/dist/shims/readonly-url-search-params.js.map +1 -1
  270. package/dist/shims/request-context.d.ts +8 -5
  271. package/dist/shims/request-context.js +50 -51
  272. package/dist/shims/request-context.js.map +1 -1
  273. package/dist/shims/request-state-types.d.ts +11 -0
  274. package/dist/shims/request-state-types.js +1 -0
  275. package/dist/shims/router-state.d.ts +15 -1
  276. package/dist/shims/router-state.js +34 -41
  277. package/dist/shims/router-state.js.map +1 -1
  278. package/dist/shims/router.d.ts +81 -81
  279. package/dist/shims/router.js +517 -543
  280. package/dist/shims/router.js.map +1 -1
  281. package/dist/shims/script.d.ts +39 -48
  282. package/dist/shims/script.js +107 -160
  283. package/dist/shims/script.js.map +1 -1
  284. package/dist/shims/server-only.d.ts +1 -19
  285. package/dist/shims/server-only.js +0 -18
  286. package/dist/shims/server.d.ts +175 -157
  287. package/dist/shims/server.js +462 -432
  288. package/dist/shims/server.js.map +1 -1
  289. package/dist/shims/unified-request-context.d.ts +66 -0
  290. package/dist/shims/unified-request-context.js +98 -0
  291. package/dist/shims/unified-request-context.js.map +1 -0
  292. package/dist/shims/url-safety.d.ts +4 -1
  293. package/dist/shims/url-safety.js +15 -11
  294. package/dist/shims/url-safety.js.map +1 -1
  295. package/dist/shims/url-utils.d.ts +8 -5
  296. package/dist/shims/url-utils.js +62 -93
  297. package/dist/shims/url-utils.js.map +1 -1
  298. package/dist/shims/web-vitals.d.ts +10 -8
  299. package/dist/shims/web-vitals.js +9 -15
  300. package/dist/shims/web-vitals.js.map +1 -1
  301. package/dist/utils/base-path.d.ts +5 -2
  302. package/dist/utils/base-path.js +21 -19
  303. package/dist/utils/base-path.js.map +1 -1
  304. package/dist/utils/domain-locale.d.ts +26 -0
  305. package/dist/utils/domain-locale.js +44 -0
  306. package/dist/utils/domain-locale.js.map +1 -0
  307. package/dist/utils/hash.d.ts +4 -1
  308. package/dist/utils/hash.js +19 -17
  309. package/dist/utils/hash.js.map +1 -1
  310. package/dist/utils/manifest-paths.d.ts +6 -3
  311. package/dist/utils/manifest-paths.js +15 -16
  312. package/dist/utils/manifest-paths.js.map +1 -1
  313. package/dist/utils/project.d.ts +13 -11
  314. package/dist/utils/project.js +169 -216
  315. package/dist/utils/project.js.map +1 -1
  316. package/dist/utils/query.d.ts +8 -6
  317. package/dist/utils/query.js +57 -67
  318. package/dist/utils/query.js.map +1 -1
  319. package/package.json +11 -10
  320. package/dist/build/report.d.ts.map +0 -1
  321. package/dist/build/static-export.d.ts.map +0 -1
  322. package/dist/check.d.ts.map +0 -1
  323. package/dist/cli.d.ts.map +0 -1
  324. package/dist/client/entry.d.ts.map +0 -1
  325. package/dist/client/validate-module-path.d.ts.map +0 -1
  326. package/dist/client/vinext-next-data.d.ts.map +0 -1
  327. package/dist/client/vinext-next-data.js.map +0 -1
  328. package/dist/cloudflare/index.d.ts.map +0 -1
  329. package/dist/cloudflare/index.js.map +0 -1
  330. package/dist/cloudflare/kv-cache-handler.d.ts.map +0 -1
  331. package/dist/cloudflare/tpr.d.ts.map +0 -1
  332. package/dist/config/config-matchers.d.ts.map +0 -1
  333. package/dist/config/dotenv.d.ts.map +0 -1
  334. package/dist/config/next-config.d.ts.map +0 -1
  335. package/dist/deploy.d.ts.map +0 -1
  336. package/dist/entries/app-browser-entry.d.ts.map +0 -1
  337. package/dist/entries/app-rsc-entry.d.ts.map +0 -1
  338. package/dist/entries/app-ssr-entry.d.ts.map +0 -1
  339. package/dist/entries/pages-client-entry.d.ts.map +0 -1
  340. package/dist/entries/pages-entry-helpers.d.ts.map +0 -1
  341. package/dist/entries/pages-server-entry.d.ts.map +0 -1
  342. package/dist/index.d.ts.map +0 -1
  343. package/dist/init.d.ts.map +0 -1
  344. package/dist/plugins/async-hooks-stub.d.ts.map +0 -1
  345. package/dist/plugins/client-reference-dedup.d.ts.map +0 -1
  346. package/dist/routing/app-router.d.ts.map +0 -1
  347. package/dist/routing/file-matcher.d.ts.map +0 -1
  348. package/dist/routing/pages-router.d.ts.map +0 -1
  349. package/dist/routing/route-trie.d.ts.map +0 -1
  350. package/dist/routing/route-validation.d.ts.map +0 -1
  351. package/dist/routing/utils.d.ts.map +0 -1
  352. package/dist/server/api-handler.d.ts.map +0 -1
  353. package/dist/server/app-router-entry.d.ts.map +0 -1
  354. package/dist/server/dev-module-runner.d.ts.map +0 -1
  355. package/dist/server/dev-origin-check.d.ts.map +0 -1
  356. package/dist/server/dev-server.d.ts.map +0 -1
  357. package/dist/server/html.d.ts.map +0 -1
  358. package/dist/server/image-optimization.d.ts.map +0 -1
  359. package/dist/server/instrumentation.d.ts.map +0 -1
  360. package/dist/server/isr-cache.d.ts.map +0 -1
  361. package/dist/server/metadata-routes.d.ts.map +0 -1
  362. package/dist/server/middleware-codegen.d.ts.map +0 -1
  363. package/dist/server/middleware-request-headers.d.ts.map +0 -1
  364. package/dist/server/middleware.d.ts.map +0 -1
  365. package/dist/server/normalize-path.d.ts.map +0 -1
  366. package/dist/server/prod-server.d.ts.map +0 -1
  367. package/dist/server/request-log.d.ts.map +0 -1
  368. package/dist/server/request-pipeline.d.ts.map +0 -1
  369. package/dist/server/worker-utils.d.ts.map +0 -1
  370. package/dist/shims/amp.d.ts.map +0 -1
  371. package/dist/shims/app.d.ts.map +0 -1
  372. package/dist/shims/app.js.map +0 -1
  373. package/dist/shims/cache-runtime.d.ts.map +0 -1
  374. package/dist/shims/cache.d.ts.map +0 -1
  375. package/dist/shims/client-only.d.ts.map +0 -1
  376. package/dist/shims/client-only.js.map +0 -1
  377. package/dist/shims/compat-router.d.ts.map +0 -1
  378. package/dist/shims/config.d.ts.map +0 -1
  379. package/dist/shims/constants.d.ts.map +0 -1
  380. package/dist/shims/document.d.ts.map +0 -1
  381. package/dist/shims/dynamic.d.ts.map +0 -1
  382. package/dist/shims/error-boundary.d.ts.map +0 -1
  383. package/dist/shims/error.d.ts.map +0 -1
  384. package/dist/shims/fetch-cache.d.ts.map +0 -1
  385. package/dist/shims/font-google-base.d.ts.map +0 -1
  386. package/dist/shims/font-google.d.ts.map +0 -1
  387. package/dist/shims/font-google.generated.d.ts.map +0 -1
  388. package/dist/shims/font-google.js.map +0 -1
  389. package/dist/shims/font-local.d.ts.map +0 -1
  390. package/dist/shims/form.d.ts.map +0 -1
  391. package/dist/shims/head-state.d.ts.map +0 -1
  392. package/dist/shims/head.d.ts.map +0 -1
  393. package/dist/shims/headers.d.ts.map +0 -1
  394. package/dist/shims/image-config.d.ts.map +0 -1
  395. package/dist/shims/image.d.ts.map +0 -1
  396. package/dist/shims/internal/api-utils.d.ts.map +0 -1
  397. package/dist/shims/internal/api-utils.js.map +0 -1
  398. package/dist/shims/internal/app-router-context.d.ts.map +0 -1
  399. package/dist/shims/internal/cookies.d.ts.map +0 -1
  400. package/dist/shims/internal/cookies.js.map +0 -1
  401. package/dist/shims/internal/parse-cookie-header.d.ts.map +0 -1
  402. package/dist/shims/internal/router-context.d.ts.map +0 -1
  403. package/dist/shims/internal/utils.d.ts.map +0 -1
  404. package/dist/shims/internal/work-unit-async-storage.d.ts.map +0 -1
  405. package/dist/shims/layout-segment-context.d.ts.map +0 -1
  406. package/dist/shims/legacy-image.d.ts.map +0 -1
  407. package/dist/shims/link.d.ts.map +0 -1
  408. package/dist/shims/metadata.d.ts.map +0 -1
  409. package/dist/shims/navigation-state.d.ts.map +0 -1
  410. package/dist/shims/navigation.d.ts.map +0 -1
  411. package/dist/shims/og.d.ts.map +0 -1
  412. package/dist/shims/og.js.map +0 -1
  413. package/dist/shims/readonly-url-search-params.d.ts.map +0 -1
  414. package/dist/shims/request-context.d.ts.map +0 -1
  415. package/dist/shims/router-state.d.ts.map +0 -1
  416. package/dist/shims/router.d.ts.map +0 -1
  417. package/dist/shims/script.d.ts.map +0 -1
  418. package/dist/shims/server-only.d.ts.map +0 -1
  419. package/dist/shims/server-only.js.map +0 -1
  420. package/dist/shims/server.d.ts.map +0 -1
  421. package/dist/shims/url-safety.d.ts.map +0 -1
  422. package/dist/shims/url-utils.d.ts.map +0 -1
  423. package/dist/shims/web-vitals.d.ts.map +0 -1
  424. package/dist/utils/base-path.d.ts.map +0 -1
  425. package/dist/utils/hash.d.ts.map +0 -1
  426. package/dist/utils/manifest-paths.d.ts.map +0 -1
  427. package/dist/utils/project.d.ts.map +0 -1
  428. package/dist/utils/query.d.ts.map +0 -1
@@ -1,639 +1,496 @@
1
- /**
2
- * Extended fetch() with Next.js caching semantics.
3
- *
4
- * Patches `globalThis.fetch` during server rendering to support:
5
- *
6
- * fetch(url, { next: { revalidate: 60, tags: ['posts'] } })
7
- * fetch(url, { cache: 'force-cache' })
8
- * fetch(url, { cache: 'no-store' })
9
- *
10
- * Cached responses are stored via the pluggable CacheHandler, so
11
- * revalidateTag() and revalidatePath() invalidate fetch-level caches.
12
- *
13
- * Usage (in server entry):
14
- * import { withFetchCache, cleanupFetchCache } from './fetch-cache';
15
- * const cleanup = withFetchCache();
16
- * try { ... render ... } finally { cleanup(); }
17
- *
18
- * Or use the async helper:
19
- * await runWithFetchCache(async () => { ... render ... });
20
- */
21
- import { getCacheHandler } from "./cache.js";
1
+ import { getRequestContext, isInsideUnifiedScope, runWithUnifiedStateMutation } from "./unified-request-context.js";
22
2
  import { getRequestExecutionContext } from "./request-context.js";
3
+ import { getCacheHandler } from "./cache.js";
23
4
  import { AsyncLocalStorage } from "node:async_hooks";
24
- // ---------------------------------------------------------------------------
25
- // Cache key generation
26
- // ---------------------------------------------------------------------------
5
+ //#region src/shims/fetch-cache.ts
27
6
  /**
28
- * Headers excluded from the cache key. These are W3C trace context headers
29
- * that can break request caching and deduplication.
30
- * All other headers ARE included in the cache key, matching Next.js behavior.
31
- */
7
+ * Extended fetch() with Next.js caching semantics.
8
+ *
9
+ * Patches `globalThis.fetch` during server rendering to support:
10
+ *
11
+ * fetch(url, { next: { revalidate: 60, tags: ['posts'] } })
12
+ * fetch(url, { cache: 'force-cache' })
13
+ * fetch(url, { cache: 'no-store' })
14
+ *
15
+ * Cached responses are stored via the pluggable CacheHandler, so
16
+ * revalidateTag() and revalidatePath() invalidate fetch-level caches.
17
+ *
18
+ * Usage (in server entry):
19
+ * import { withFetchCache, cleanupFetchCache } from './fetch-cache';
20
+ * const cleanup = withFetchCache();
21
+ * try { ... render ... } finally { cleanup(); }
22
+ *
23
+ * Or use the async helper:
24
+ * await runWithFetchCache(async () => { ... render ... });
25
+ */
26
+ /**
27
+ * Headers excluded from the cache key. These are W3C trace context headers
28
+ * that can break request caching and deduplication.
29
+ * All other headers ARE included in the cache key, matching Next.js behavior.
30
+ */
32
31
  const HEADER_BLOCKLIST = ["traceparent", "tracestate"];
33
- // Cache key version — bump when changing the key format to bust stale entries
34
32
  const CACHE_KEY_PREFIX = "v3";
35
- const MAX_CACHE_KEY_BODY_BYTES = 1024 * 1024; // 1 MiB
36
- class BodyTooLargeForCacheKeyError extends Error {
37
- constructor() {
38
- super("Fetch body too large for cache key generation");
39
- }
40
- }
41
- class SkipCacheKeyGenerationError extends Error {
42
- constructor() {
43
- super("Fetch body could not be serialized for cache key generation");
44
- }
45
- }
33
+ const MAX_CACHE_KEY_BODY_BYTES = 1024 * 1024;
34
+ var BodyTooLargeForCacheKeyError = class extends Error {
35
+ constructor() {
36
+ super("Fetch body too large for cache key generation");
37
+ }
38
+ };
39
+ var SkipCacheKeyGenerationError = class extends Error {
40
+ constructor() {
41
+ super("Fetch body could not be serialized for cache key generation");
42
+ }
43
+ };
46
44
  /**
47
- * Collect all headers from the request, excluding the blocklist.
48
- * Merges headers from both the Request object and the init object,
49
- * with init taking precedence (matching fetch() spec behavior).
50
- */
45
+ * Collect all headers from the request, excluding the blocklist.
46
+ * Merges headers from both the Request object and the init object,
47
+ * with init taking precedence (matching fetch() spec behavior).
48
+ */
51
49
  function collectHeaders(input, init) {
52
- const merged = {};
53
- // Start with headers from Request object (if any)
54
- if (input instanceof Request && input.headers) {
55
- input.headers.forEach((v, k) => {
56
- merged[k] = v;
57
- });
58
- }
59
- // Override with headers from init (init takes precedence per fetch spec)
60
- if (init?.headers) {
61
- const headers = init.headers instanceof Headers ? init.headers : new Headers(init.headers);
62
- headers.forEach((v, k) => {
63
- merged[k] = v;
64
- });
65
- }
66
- // Remove blocklisted headers
67
- for (const blocked of HEADER_BLOCKLIST) {
68
- delete merged[blocked];
69
- }
70
- return merged;
50
+ const merged = {};
51
+ if (input instanceof Request && input.headers) input.headers.forEach((v, k) => {
52
+ merged[k] = v;
53
+ });
54
+ if (init?.headers) (init.headers instanceof Headers ? init.headers : new Headers(init.headers)).forEach((v, k) => {
55
+ merged[k] = v;
56
+ });
57
+ for (const blocked of HEADER_BLOCKLIST) delete merged[blocked];
58
+ return merged;
71
59
  }
72
60
  /**
73
- * Check whether a fetch request carries any per-user auth headers.
74
- * Used for the safety bypass (skip caching when auth headers are present
75
- * without an explicit cache opt-in).
76
- */
77
- const AUTH_HEADERS = ["authorization", "cookie", "x-api-key"];
61
+ * Check whether a fetch request carries any per-user auth headers.
62
+ * Used for the safety bypass (skip caching when auth headers are present
63
+ * without an explicit cache opt-in).
64
+ */
65
+ const AUTH_HEADERS = [
66
+ "authorization",
67
+ "cookie",
68
+ "x-api-key"
69
+ ];
78
70
  function hasAuthHeaders(input, init) {
79
- const headers = collectHeaders(input, init);
80
- return AUTH_HEADERS.some((name) => name in headers);
71
+ const headers = collectHeaders(input, init);
72
+ return AUTH_HEADERS.some((name) => name in headers);
81
73
  }
82
74
  async function serializeFormData(formData, pushBodyChunk, getTotalBodyBytes) {
83
- for (const [key, val] of formData.entries()) {
84
- if (typeof val === "string") {
85
- pushBodyChunk(JSON.stringify([key, { kind: "string", value: val }]));
86
- continue;
87
- }
88
- if (val.size > MAX_CACHE_KEY_BODY_BYTES ||
89
- getTotalBodyBytes() + val.size > MAX_CACHE_KEY_BODY_BYTES) {
90
- throw new BodyTooLargeForCacheKeyError();
91
- }
92
- pushBodyChunk(JSON.stringify([
93
- key,
94
- {
95
- kind: "file",
96
- name: val.name,
97
- type: val.type,
98
- value: await val.text(),
99
- },
100
- ]));
101
- }
75
+ for (const [key, val] of formData.entries()) {
76
+ if (typeof val === "string") {
77
+ pushBodyChunk(JSON.stringify([key, {
78
+ kind: "string",
79
+ value: val
80
+ }]));
81
+ continue;
82
+ }
83
+ if (val.size > MAX_CACHE_KEY_BODY_BYTES || getTotalBodyBytes() + val.size > MAX_CACHE_KEY_BODY_BYTES) throw new BodyTooLargeForCacheKeyError();
84
+ pushBodyChunk(JSON.stringify([key, {
85
+ kind: "file",
86
+ name: val.name,
87
+ type: val.type,
88
+ value: await val.text()
89
+ }]));
90
+ }
102
91
  }
103
92
  function getParsedFormContentType(contentType) {
104
- const mediaType = contentType?.split(";")[0]?.trim().toLowerCase();
105
- if (mediaType === "multipart/form-data" || mediaType === "application/x-www-form-urlencoded") {
106
- return mediaType;
107
- }
108
- return undefined;
93
+ const mediaType = contentType?.split(";")[0]?.trim().toLowerCase();
94
+ if (mediaType === "multipart/form-data" || mediaType === "application/x-www-form-urlencoded") return mediaType;
109
95
  }
110
96
  function stripMultipartBoundary(contentType) {
111
- const [type, ...params] = contentType.split(";");
112
- const keptParams = params
113
- .map((param) => param.trim())
114
- .filter(Boolean)
115
- .filter((param) => !/^boundary\s*=/i.test(param));
116
- const normalizedType = type.trim().toLowerCase();
117
- return keptParams.length > 0 ? `${normalizedType}; ${keptParams.join("; ")}` : normalizedType;
97
+ const [type, ...params] = contentType.split(";");
98
+ const keptParams = params.map((param) => param.trim()).filter(Boolean).filter((param) => !/^boundary\s*=/i.test(param));
99
+ const normalizedType = type.trim().toLowerCase();
100
+ return keptParams.length > 0 ? `${normalizedType}; ${keptParams.join("; ")}` : normalizedType;
118
101
  }
119
102
  async function readRequestBodyChunksWithinLimit(request) {
120
- const contentLengthHeader = request.headers.get("content-length");
121
- if (contentLengthHeader) {
122
- const contentLength = Number(contentLengthHeader);
123
- if (Number.isFinite(contentLength) && contentLength > MAX_CACHE_KEY_BODY_BYTES) {
124
- throw new BodyTooLargeForCacheKeyError();
125
- }
126
- }
127
- const requestClone = request.clone();
128
- const contentType = requestClone.headers.get("content-type") ?? undefined;
129
- const reader = requestClone.body?.getReader();
130
- if (!reader) {
131
- return { chunks: [], contentType };
132
- }
133
- const chunks = [];
134
- let totalBodyBytes = 0;
135
- try {
136
- while (true) {
137
- const { done, value } = await reader.read();
138
- if (done)
139
- break;
140
- totalBodyBytes += value.byteLength;
141
- if (totalBodyBytes > MAX_CACHE_KEY_BODY_BYTES) {
142
- throw new BodyTooLargeForCacheKeyError();
143
- }
144
- chunks.push(value);
145
- }
146
- }
147
- catch (err) {
148
- void reader.cancel().catch(() => { });
149
- throw err;
150
- }
151
- return { chunks, contentType };
103
+ const contentLengthHeader = request.headers.get("content-length");
104
+ if (contentLengthHeader) {
105
+ const contentLength = Number(contentLengthHeader);
106
+ if (Number.isFinite(contentLength) && contentLength > MAX_CACHE_KEY_BODY_BYTES) throw new BodyTooLargeForCacheKeyError();
107
+ }
108
+ const requestClone = request.clone();
109
+ const contentType = requestClone.headers.get("content-type") ?? void 0;
110
+ const reader = requestClone.body?.getReader();
111
+ if (!reader) return {
112
+ chunks: [],
113
+ contentType
114
+ };
115
+ const chunks = [];
116
+ let totalBodyBytes = 0;
117
+ try {
118
+ while (true) {
119
+ const { done, value } = await reader.read();
120
+ if (done) break;
121
+ totalBodyBytes += value.byteLength;
122
+ if (totalBodyBytes > MAX_CACHE_KEY_BODY_BYTES) throw new BodyTooLargeForCacheKeyError();
123
+ chunks.push(value);
124
+ }
125
+ } catch (err) {
126
+ reader.cancel().catch(() => {});
127
+ throw err;
128
+ }
129
+ return {
130
+ chunks,
131
+ contentType
132
+ };
152
133
  }
153
134
  /**
154
- * Serialize request body into string chunks for cache key inclusion.
155
- * Handles all body types: string, Uint8Array, ReadableStream, FormData, Blob,
156
- * and Request object bodies.
157
- * Returns the serialized body chunks and optionally stashes the original body
158
- * on init as `_ogBody` so it can still be used after stream consumption.
159
- */
135
+ * Serialize request body into string chunks for cache key inclusion.
136
+ * Handles all body types: string, Uint8Array, ReadableStream, FormData, Blob,
137
+ * and Request object bodies.
138
+ * Returns the serialized body chunks and optionally stashes the original body
139
+ * on init as `_ogBody` so it can still be used after stream consumption.
140
+ */
160
141
  async function serializeBody(input, init) {
161
- if (!init?.body && !(input instanceof Request && input.body)) {
162
- return { bodyChunks: [] };
163
- }
164
- const bodyChunks = [];
165
- const encoder = new TextEncoder();
166
- const decoder = new TextDecoder();
167
- let totalBodyBytes = 0;
168
- let canonicalizedContentType;
169
- const pushBodyChunk = (chunk) => {
170
- totalBodyBytes += encoder.encode(chunk).byteLength;
171
- if (totalBodyBytes > MAX_CACHE_KEY_BODY_BYTES) {
172
- throw new BodyTooLargeForCacheKeyError();
173
- }
174
- bodyChunks.push(chunk);
175
- };
176
- const getTotalBodyBytes = () => totalBodyBytes;
177
- if (init?.body instanceof Uint8Array) {
178
- if (init.body.byteLength > MAX_CACHE_KEY_BODY_BYTES) {
179
- throw new BodyTooLargeForCacheKeyError();
180
- }
181
- pushBodyChunk(decoder.decode(init.body));
182
- init._ogBody = init.body;
183
- }
184
- else if (init?.body && typeof init.body.getReader === "function") {
185
- // ReadableStream
186
- const readableBody = init.body;
187
- const [bodyForHashing, bodyForFetch] = readableBody.tee();
188
- init._ogBody = bodyForFetch;
189
- const reader = bodyForHashing.getReader();
190
- try {
191
- while (true) {
192
- const { done, value } = await reader.read();
193
- if (done)
194
- break;
195
- if (typeof value === "string") {
196
- pushBodyChunk(value);
197
- }
198
- else {
199
- // Check raw byte size before the expensive decode to prevent
200
- // OOM from a single oversized chunk.
201
- totalBodyBytes += value.byteLength;
202
- if (totalBodyBytes > MAX_CACHE_KEY_BODY_BYTES) {
203
- throw new BodyTooLargeForCacheKeyError();
204
- }
205
- bodyChunks.push(decoder.decode(value, { stream: true }));
206
- }
207
- }
208
- const finalChunk = decoder.decode();
209
- if (finalChunk) {
210
- pushBodyChunk(finalChunk);
211
- }
212
- }
213
- catch (err) {
214
- await reader.cancel();
215
- if (err instanceof BodyTooLargeForCacheKeyError) {
216
- throw err;
217
- }
218
- throw new SkipCacheKeyGenerationError();
219
- }
220
- }
221
- else if (init?.body instanceof URLSearchParams) {
222
- // URLSearchParams .toString() gives a stable serialization
223
- init._ogBody = init.body;
224
- pushBodyChunk(init.body.toString());
225
- }
226
- else if (init?.body && typeof init.body.keys === "function") {
227
- // FormData
228
- const formData = init.body;
229
- init._ogBody = init.body;
230
- await serializeFormData(formData, pushBodyChunk, getTotalBodyBytes);
231
- }
232
- else if (init?.body && typeof init.body.arrayBuffer === "function") {
233
- // Blob
234
- const blob = init.body;
235
- if (blob.size > MAX_CACHE_KEY_BODY_BYTES) {
236
- throw new BodyTooLargeForCacheKeyError();
237
- }
238
- pushBodyChunk(await blob.text());
239
- const arrayBuffer = await blob.arrayBuffer();
240
- init._ogBody = new Blob([arrayBuffer], { type: blob.type });
241
- }
242
- else if (typeof init?.body === "string") {
243
- // String length is always <= UTF-8 byte length, so this is a
244
- // cheap lower-bound check that avoids encoder.encode() for huge strings.
245
- if (init.body.length > MAX_CACHE_KEY_BODY_BYTES) {
246
- throw new BodyTooLargeForCacheKeyError();
247
- }
248
- pushBodyChunk(init.body);
249
- init._ogBody = init.body;
250
- }
251
- else if (input instanceof Request && input.body) {
252
- let chunks;
253
- let contentType;
254
- try {
255
- ({ chunks, contentType } = await readRequestBodyChunksWithinLimit(input));
256
- }
257
- catch (err) {
258
- if (err instanceof BodyTooLargeForCacheKeyError) {
259
- throw err;
260
- }
261
- throw new SkipCacheKeyGenerationError();
262
- }
263
- const formContentType = getParsedFormContentType(contentType);
264
- if (formContentType) {
265
- try {
266
- const boundedRequest = new Request(input.url, {
267
- method: input.method,
268
- headers: contentType ? { "content-type": contentType } : undefined,
269
- body: new Blob(chunks),
270
- });
271
- const formData = await boundedRequest.formData();
272
- await serializeFormData(formData, pushBodyChunk, getTotalBodyBytes);
273
- canonicalizedContentType =
274
- formContentType === "multipart/form-data" && contentType
275
- ? stripMultipartBoundary(contentType)
276
- : undefined;
277
- return { bodyChunks, canonicalizedContentType };
278
- }
279
- catch (err) {
280
- if (err instanceof BodyTooLargeForCacheKeyError) {
281
- throw err;
282
- }
283
- throw new SkipCacheKeyGenerationError();
284
- }
285
- }
286
- for (const chunk of chunks) {
287
- pushBodyChunk(decoder.decode(chunk, { stream: true }));
288
- }
289
- const finalChunk = decoder.decode();
290
- if (finalChunk) {
291
- pushBodyChunk(finalChunk);
292
- }
293
- }
294
- return { bodyChunks, canonicalizedContentType };
142
+ if (!init?.body && !(input instanceof Request && input.body)) return { bodyChunks: [] };
143
+ const bodyChunks = [];
144
+ const encoder = new TextEncoder();
145
+ const decoder = new TextDecoder();
146
+ let totalBodyBytes = 0;
147
+ let canonicalizedContentType;
148
+ const pushBodyChunk = (chunk) => {
149
+ totalBodyBytes += encoder.encode(chunk).byteLength;
150
+ if (totalBodyBytes > MAX_CACHE_KEY_BODY_BYTES) throw new BodyTooLargeForCacheKeyError();
151
+ bodyChunks.push(chunk);
152
+ };
153
+ const getTotalBodyBytes = () => totalBodyBytes;
154
+ if (init?.body instanceof Uint8Array) {
155
+ if (init.body.byteLength > MAX_CACHE_KEY_BODY_BYTES) throw new BodyTooLargeForCacheKeyError();
156
+ pushBodyChunk(decoder.decode(init.body));
157
+ init._ogBody = init.body;
158
+ } else if (init?.body && typeof init.body.getReader === "function") {
159
+ const [bodyForHashing, bodyForFetch] = init.body.tee();
160
+ init._ogBody = bodyForFetch;
161
+ const reader = bodyForHashing.getReader();
162
+ try {
163
+ while (true) {
164
+ const { done, value } = await reader.read();
165
+ if (done) break;
166
+ if (typeof value === "string") pushBodyChunk(value);
167
+ else {
168
+ totalBodyBytes += value.byteLength;
169
+ if (totalBodyBytes > MAX_CACHE_KEY_BODY_BYTES) throw new BodyTooLargeForCacheKeyError();
170
+ bodyChunks.push(decoder.decode(value, { stream: true }));
171
+ }
172
+ }
173
+ const finalChunk = decoder.decode();
174
+ if (finalChunk) pushBodyChunk(finalChunk);
175
+ } catch (err) {
176
+ await reader.cancel();
177
+ if (err instanceof BodyTooLargeForCacheKeyError) throw err;
178
+ throw new SkipCacheKeyGenerationError();
179
+ }
180
+ } else if (init?.body instanceof URLSearchParams) {
181
+ init._ogBody = init.body;
182
+ pushBodyChunk(init.body.toString());
183
+ } else if (init?.body && typeof init.body.keys === "function") {
184
+ const formData = init.body;
185
+ init._ogBody = init.body;
186
+ await serializeFormData(formData, pushBodyChunk, getTotalBodyBytes);
187
+ } else if (init?.body && typeof init.body.arrayBuffer === "function") {
188
+ const blob = init.body;
189
+ if (blob.size > MAX_CACHE_KEY_BODY_BYTES) throw new BodyTooLargeForCacheKeyError();
190
+ pushBodyChunk(await blob.text());
191
+ const arrayBuffer = await blob.arrayBuffer();
192
+ init._ogBody = new Blob([arrayBuffer], { type: blob.type });
193
+ } else if (typeof init?.body === "string") {
194
+ if (init.body.length > MAX_CACHE_KEY_BODY_BYTES) throw new BodyTooLargeForCacheKeyError();
195
+ pushBodyChunk(init.body);
196
+ init._ogBody = init.body;
197
+ } else if (input instanceof Request && input.body) {
198
+ let chunks;
199
+ let contentType;
200
+ try {
201
+ ({chunks, contentType} = await readRequestBodyChunksWithinLimit(input));
202
+ } catch (err) {
203
+ if (err instanceof BodyTooLargeForCacheKeyError) throw err;
204
+ throw new SkipCacheKeyGenerationError();
205
+ }
206
+ const formContentType = getParsedFormContentType(contentType);
207
+ if (formContentType) try {
208
+ await serializeFormData(await new Request(input.url, {
209
+ method: input.method,
210
+ headers: contentType ? { "content-type": contentType } : void 0,
211
+ body: new Blob(chunks)
212
+ }).formData(), pushBodyChunk, getTotalBodyBytes);
213
+ canonicalizedContentType = formContentType === "multipart/form-data" && contentType ? stripMultipartBoundary(contentType) : void 0;
214
+ return {
215
+ bodyChunks,
216
+ canonicalizedContentType
217
+ };
218
+ } catch (err) {
219
+ if (err instanceof BodyTooLargeForCacheKeyError) throw err;
220
+ throw new SkipCacheKeyGenerationError();
221
+ }
222
+ for (const chunk of chunks) pushBodyChunk(decoder.decode(chunk, { stream: true }));
223
+ const finalChunk = decoder.decode();
224
+ if (finalChunk) pushBodyChunk(finalChunk);
225
+ }
226
+ return {
227
+ bodyChunks,
228
+ canonicalizedContentType
229
+ };
295
230
  }
296
231
  /**
297
- * Generate a deterministic cache key from a fetch request.
298
- *
299
- * Matches Next.js behavior: the key is a SHA-256 hash of a JSON array
300
- * containing URL, method, all headers (minus blocklist), all RequestInit
301
- * options, and the serialized body.
302
- */
232
+ * Generate a deterministic cache key from a fetch request.
233
+ *
234
+ * Matches Next.js behavior: the key is a SHA-256 hash of a JSON array
235
+ * containing URL, method, all headers (minus blocklist), all RequestInit
236
+ * options, and the serialized body.
237
+ */
303
238
  async function buildFetchCacheKey(input, init) {
304
- let url;
305
- let method = "GET";
306
- if (typeof input === "string") {
307
- url = input;
308
- }
309
- else if (input instanceof URL) {
310
- url = input.toString();
311
- }
312
- else {
313
- // Request object
314
- url = input.url;
315
- method = input.method || "GET";
316
- }
317
- if (init?.method)
318
- method = init.method;
319
- const headers = collectHeaders(input, init);
320
- const { bodyChunks, canonicalizedContentType } = await serializeBody(input, init);
321
- if (canonicalizedContentType) {
322
- headers["content-type"] = canonicalizedContentType;
323
- }
324
- const cacheString = JSON.stringify([
325
- CACHE_KEY_PREFIX,
326
- url,
327
- method,
328
- headers,
329
- init?.mode,
330
- init?.redirect,
331
- init?.credentials,
332
- init?.referrer,
333
- init?.referrerPolicy,
334
- init?.integrity,
335
- init?.cache,
336
- bodyChunks,
337
- ]);
338
- const encoder = new TextEncoder();
339
- const buffer = encoder.encode(cacheString);
340
- const hashBuffer = await crypto.subtle.digest("SHA-256", buffer);
341
- return Array.prototype.map
342
- .call(new Uint8Array(hashBuffer), (b) => b.toString(16).padStart(2, "0"))
343
- .join("");
239
+ let url;
240
+ let method = "GET";
241
+ if (typeof input === "string") url = input;
242
+ else if (input instanceof URL) url = input.toString();
243
+ else {
244
+ url = input.url;
245
+ method = input.method || "GET";
246
+ }
247
+ if (init?.method) method = init.method;
248
+ const headers = collectHeaders(input, init);
249
+ const { bodyChunks, canonicalizedContentType } = await serializeBody(input, init);
250
+ if (canonicalizedContentType) headers["content-type"] = canonicalizedContentType;
251
+ const cacheString = JSON.stringify([
252
+ CACHE_KEY_PREFIX,
253
+ url,
254
+ method,
255
+ headers,
256
+ init?.mode,
257
+ init?.redirect,
258
+ init?.credentials,
259
+ init?.referrer,
260
+ init?.referrerPolicy,
261
+ init?.integrity,
262
+ init?.cache,
263
+ bodyChunks
264
+ ]);
265
+ const buffer = new TextEncoder().encode(cacheString);
266
+ const hashBuffer = await crypto.subtle.digest("SHA-256", buffer);
267
+ return Array.prototype.map.call(new Uint8Array(hashBuffer), (b) => b.toString(16).padStart(2, "0")).join("");
268
+ }
269
+ const _PENDING_KEY = Symbol.for("vinext.fetchCache.pendingRefetches");
270
+ const _gPending = globalThis;
271
+ const pendingRefetches = _gPending[_PENDING_KEY] ??= /* @__PURE__ */ new Map();
272
+ const DEDUP_TIMEOUT_MS = 6e4;
273
+ /** @internal Reset dedup state — exposed for test isolation only. */
274
+ function _resetPendingRefetches() {
275
+ pendingRefetches.clear();
344
276
  }
345
- // ---------------------------------------------------------------------------
346
- // Patching
347
- // ---------------------------------------------------------------------------
348
- // Capture the real (unpatched) fetch once, shared across Vite's
349
- // multi-environment module instances via Symbol.for().
350
277
  const _ORIG_FETCH_KEY = Symbol.for("vinext.fetchCache.originalFetch");
351
278
  const _gFetch = globalThis;
352
- const originalFetch = (_gFetch[_ORIG_FETCH_KEY] ??=
353
- globalThis.fetch);
279
+ const originalFetch = _gFetch[_ORIG_FETCH_KEY] ??= globalThis.fetch;
354
280
  const _ALS_KEY = Symbol.for("vinext.fetchCache.als");
355
281
  const _FALLBACK_KEY = Symbol.for("vinext.fetchCache.fallback");
356
282
  const _g = globalThis;
357
- const _als = (_g[_ALS_KEY] ??=
358
- new AsyncLocalStorage());
359
- const _fallbackState = (_g[_FALLBACK_KEY] ??= {
360
- currentRequestTags: [],
361
- });
283
+ const _als = _g[_ALS_KEY] ??= new AsyncLocalStorage();
284
+ const _fallbackState = _g[_FALLBACK_KEY] ??= { currentRequestTags: [] };
362
285
  function _getState() {
363
- return _als.getStore() ?? _fallbackState;
286
+ if (isInsideUnifiedScope()) return getRequestContext();
287
+ return _als.getStore() ?? _fallbackState;
364
288
  }
365
289
  /**
366
- * Reset the fallback state for a new request. Used by `withFetchCache()`
367
- * in single-threaded contexts where ALS.run() isn't used.
368
- */
290
+ * Reset the fallback state for a new request. Used by `withFetchCache()`
291
+ * in single-threaded contexts where ALS.run() isn't used.
292
+ */
369
293
  function _resetFallbackState() {
370
- _fallbackState.currentRequestTags = [];
294
+ _fallbackState.currentRequestTags = [];
371
295
  }
372
296
  /**
373
- * Get tags collected during the current render pass.
374
- * Useful for associating page-level cache entries with all the
375
- * fetch tags used during rendering.
376
- */
377
- export function getCollectedFetchTags() {
378
- return [..._getState().currentRequestTags];
297
+ * Get tags collected during the current render pass.
298
+ * Useful for associating page-level cache entries with all the
299
+ * fetch tags used during rendering.
300
+ */
301
+ function getCollectedFetchTags() {
302
+ return [..._getState().currentRequestTags];
379
303
  }
380
304
  /**
381
- * Create a patched fetch function with Next.js caching semantics.
382
- *
383
- * The patched fetch:
384
- * 1. Checks `cache` and `next` options to determine caching behavior
385
- * 2. On cache hit, returns the cached response without hitting the network
386
- * 3. On cache miss, fetches from network, stores in cache, returns response
387
- * 4. Respects `next.revalidate` for TTL-based revalidation
388
- * 5. Respects `next.tags` for tag-based invalidation via revalidateTag()
389
- */
305
+ * Create a patched fetch function with Next.js caching semantics.
306
+ *
307
+ * The patched fetch:
308
+ * 1. Checks `cache` and `next` options to determine caching behavior
309
+ * 2. On cache hit, returns the cached response without hitting the network
310
+ * 3. On cache miss, fetches from network, stores in cache, returns response
311
+ * 4. Respects `next.revalidate` for TTL-based revalidation
312
+ * 5. Respects `next.tags` for tag-based invalidation via revalidateTag()
313
+ */
390
314
  function createPatchedFetch() {
391
- return async function patchedFetch(input, init) {
392
- const nextOpts = init?.next;
393
- const cacheDirective = init?.cache;
394
- // Determine caching behavior:
395
- // - cache: 'no-store' skip cache entirely
396
- // - cache: 'force-cache' cache indefinitely (revalidate = Infinity)
397
- // - next.revalidate: false → same as 'no-store'
398
- // - next.revalidate: 0 same as 'no-store'
399
- // - next.revalidate: N cache for N seconds
400
- // - No cache/next options default behavior (no caching, pass-through)
401
- // If no caching options at all, just pass through to original fetch
402
- if (!nextOpts && !cacheDirective) {
403
- return originalFetch(input, init);
404
- }
405
- // Explicit no-store or no-cache — bypass cache entirely
406
- if (cacheDirective === "no-store" ||
407
- cacheDirective === "no-cache" ||
408
- nextOpts?.revalidate === false ||
409
- nextOpts?.revalidate === 0) {
410
- // Strip the `next` property before passing to real fetch
411
- const cleanInit = stripNextFromInit(init);
412
- return originalFetch(input, cleanInit);
413
- }
414
- // Safety: when per-user auth headers are present and the developer hasn't
415
- // explicitly opted into caching with `cache: 'force-cache'` or an explicit
416
- // `next.revalidate`, skip caching to prevent accidental cross-user data
417
- // leakage. Developers who understand the implications can still force
418
- // caching by using `cache: 'force-cache'` or `next: { revalidate: N }`.
419
- const hasExplicitCacheOpt = cacheDirective === "force-cache" ||
420
- (typeof nextOpts?.revalidate === "number" && nextOpts.revalidate > 0);
421
- if (!hasExplicitCacheOpt && hasAuthHeaders(input, init)) {
422
- const cleanInit = stripNextFromInit(init);
423
- return originalFetch(input, cleanInit);
424
- }
425
- // Determine revalidation period
426
- let revalidateSeconds;
427
- if (cacheDirective === "force-cache") {
428
- // force-cache means cache indefinitely (we use a very large number)
429
- revalidateSeconds =
430
- nextOpts?.revalidate && typeof nextOpts.revalidate === "number"
431
- ? nextOpts.revalidate
432
- : 31536000; // 1 year
433
- }
434
- else if (typeof nextOpts?.revalidate === "number" && nextOpts.revalidate > 0) {
435
- revalidateSeconds = nextOpts.revalidate;
436
- }
437
- else {
438
- // Has `next` options but no explicit revalidate — Next.js defaults to
439
- // caching when `next` is present (force-cache behavior).
440
- // If only tags are specified, cache indefinitely.
441
- if (nextOpts?.tags && nextOpts.tags.length > 0) {
442
- revalidateSeconds = 31536000;
443
- }
444
- else {
445
- // next: {} with no revalidate or tags — pass through
446
- const cleanInit = stripNextFromInit(init);
447
- return originalFetch(input, cleanInit);
448
- }
449
- }
450
- const tags = nextOpts?.tags ?? [];
451
- let cacheKey;
452
- try {
453
- cacheKey = await buildFetchCacheKey(input, init);
454
- }
455
- catch (err) {
456
- if (err instanceof BodyTooLargeForCacheKeyError ||
457
- err instanceof SkipCacheKeyGenerationError) {
458
- const cleanInit = stripNextFromInit(init);
459
- return originalFetch(input, cleanInit);
460
- }
461
- throw err;
462
- }
463
- const handler = getCacheHandler();
464
- // Collect tags for this render pass
465
- const reqTags = _getState().currentRequestTags;
466
- if (tags.length > 0) {
467
- for (const tag of tags) {
468
- if (!reqTags.includes(tag)) {
469
- reqTags.push(tag);
470
- }
471
- }
472
- }
473
- // Try cache first
474
- try {
475
- const cached = await handler.get(cacheKey, { kind: "FETCH", tags });
476
- if (cached?.value && cached.value.kind === "FETCH" && cached.cacheState !== "stale") {
477
- const cachedData = cached.value.data;
478
- // Reconstruct a Response from the cached data
479
- return new Response(cachedData.body, {
480
- status: cachedData.status ?? 200,
481
- headers: cachedData.headers,
482
- });
483
- }
484
- // Stale entry — we could do stale-while-revalidate here, but for fetch()
485
- // the simpler approach is to just re-fetch (the page-level ISR handles SWR).
486
- // However, if we have a stale entry, return it and trigger background refetch.
487
- if (cached?.value && cached.value.kind === "FETCH" && cached.cacheState === "stale") {
488
- const staleData = cached.value.data;
489
- // Background refetch — register with waitUntil so Cloudflare Workers
490
- // keeps the isolate alive until the refetch completes.
491
- const cleanInit = stripNextFromInit(init);
492
- const refetchPromise = originalFetch(input, cleanInit)
493
- .then(async (freshResp) => {
494
- const freshBody = await freshResp.text();
495
- const freshHeaders = {};
496
- freshResp.headers.forEach((v, k) => {
497
- freshHeaders[k] = v;
498
- });
499
- const freshValue = {
500
- kind: "FETCH",
501
- data: {
502
- headers: freshHeaders,
503
- body: freshBody,
504
- url: typeof input === "string"
505
- ? input
506
- : input instanceof URL
507
- ? input.toString()
508
- : input.url,
509
- status: freshResp.status,
510
- },
511
- tags,
512
- revalidate: revalidateSeconds,
513
- };
514
- await handler.set(cacheKey, freshValue, {
515
- fetchCache: true,
516
- tags,
517
- revalidate: revalidateSeconds,
518
- });
519
- })
520
- .catch((err) => {
521
- console.error("[vinext] fetch cache background revalidation failed:", err);
522
- });
523
- getRequestExecutionContext()?.waitUntil(refetchPromise);
524
- // Return stale data immediately
525
- return new Response(staleData.body, {
526
- status: staleData.status ?? 200,
527
- headers: staleData.headers,
528
- });
529
- }
530
- }
531
- catch (cacheErr) {
532
- // Cache read failed — fall through to network
533
- console.error("[vinext] fetch cache read error:", cacheErr);
534
- }
535
- // Cache miss — fetch from network
536
- const cleanInit = stripNextFromInit(init);
537
- const response = await originalFetch(input, cleanInit);
538
- // Only cache successful responses (2xx)
539
- if (response.ok) {
540
- // Clone before reading body
541
- const cloned = response.clone();
542
- const body = await cloned.text();
543
- const headers = {};
544
- cloned.headers.forEach((v, k) => {
545
- headers[k] = v;
546
- });
547
- const cacheValue = {
548
- kind: "FETCH",
549
- data: {
550
- headers,
551
- body,
552
- url: typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url,
553
- status: cloned.status,
554
- },
555
- tags,
556
- revalidate: revalidateSeconds,
557
- };
558
- // Store in cache (fire-and-forget)
559
- handler
560
- .set(cacheKey, cacheValue, {
561
- fetchCache: true,
562
- tags,
563
- revalidate: revalidateSeconds,
564
- })
565
- .catch((err) => {
566
- console.error("[vinext] fetch cache write error:", err);
567
- });
568
- }
569
- return response;
570
- };
315
+ return async function patchedFetch(input, init) {
316
+ const nextOpts = init?.next;
317
+ const cacheDirective = init?.cache;
318
+ if (!nextOpts && !cacheDirective) return originalFetch(input, init);
319
+ if (cacheDirective === "no-store" || cacheDirective === "no-cache" || nextOpts?.revalidate === false || nextOpts?.revalidate === 0) return originalFetch(input, stripNextFromInit(init));
320
+ if (!(cacheDirective === "force-cache" || typeof nextOpts?.revalidate === "number" && nextOpts.revalidate > 0) && hasAuthHeaders(input, init)) return originalFetch(input, stripNextFromInit(init));
321
+ let revalidateSeconds;
322
+ if (cacheDirective === "force-cache") revalidateSeconds = nextOpts?.revalidate && typeof nextOpts.revalidate === "number" ? nextOpts.revalidate : 31536e3;
323
+ else if (typeof nextOpts?.revalidate === "number" && nextOpts.revalidate > 0) revalidateSeconds = nextOpts.revalidate;
324
+ else if (nextOpts?.tags && nextOpts.tags.length > 0) revalidateSeconds = 31536e3;
325
+ else return originalFetch(input, stripNextFromInit(init));
326
+ const tags = nextOpts?.tags ?? [];
327
+ let cacheKey;
328
+ try {
329
+ cacheKey = await buildFetchCacheKey(input, init);
330
+ } catch (err) {
331
+ if (err instanceof BodyTooLargeForCacheKeyError || err instanceof SkipCacheKeyGenerationError) return originalFetch(input, stripNextFromInit(init));
332
+ throw err;
333
+ }
334
+ const handler = getCacheHandler();
335
+ const reqTags = _getState().currentRequestTags;
336
+ if (tags.length > 0) {
337
+ for (const tag of tags) if (!reqTags.includes(tag)) reqTags.push(tag);
338
+ }
339
+ try {
340
+ const cached = await handler.get(cacheKey, {
341
+ kind: "FETCH",
342
+ tags
343
+ });
344
+ if (cached?.value && cached.value.kind === "FETCH" && cached.cacheState !== "stale") {
345
+ const cachedData = cached.value.data;
346
+ return new Response(cachedData.body, {
347
+ status: cachedData.status ?? 200,
348
+ headers: cachedData.headers
349
+ });
350
+ }
351
+ if (cached?.value && cached.value.kind === "FETCH" && cached.cacheState === "stale") {
352
+ const staleData = cached.value.data;
353
+ if (!pendingRefetches.has(cacheKey)) {
354
+ const refetchPromise = originalFetch(input, stripNextFromInit(init)).then(async (freshResp) => {
355
+ if (freshResp.status !== 200) return;
356
+ const freshBody = await freshResp.text();
357
+ const freshHeaders = {};
358
+ freshResp.headers.forEach((v, k) => {
359
+ freshHeaders[k] = v;
360
+ });
361
+ const freshValue = {
362
+ kind: "FETCH",
363
+ data: {
364
+ headers: freshHeaders,
365
+ body: freshBody,
366
+ url: typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url,
367
+ status: freshResp.status
368
+ },
369
+ tags,
370
+ revalidate: revalidateSeconds
371
+ };
372
+ await handler.set(cacheKey, freshValue, {
373
+ fetchCache: true,
374
+ tags,
375
+ revalidate: revalidateSeconds
376
+ });
377
+ }).catch((err) => {
378
+ const url = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
379
+ console.error(`[vinext] fetch cache background revalidation failed for ${url} (key=${cacheKey.slice(0, 12)}...):`, err);
380
+ }).finally(() => {
381
+ if (pendingRefetches.get(cacheKey) === refetchPromise) pendingRefetches.delete(cacheKey);
382
+ clearTimeout(timeoutId);
383
+ });
384
+ pendingRefetches.set(cacheKey, refetchPromise);
385
+ const timeoutId = setTimeout(() => {
386
+ if (pendingRefetches.get(cacheKey) === refetchPromise) pendingRefetches.delete(cacheKey);
387
+ }, DEDUP_TIMEOUT_MS);
388
+ getRequestExecutionContext()?.waitUntil(refetchPromise);
389
+ }
390
+ return new Response(staleData.body, {
391
+ status: staleData.status ?? 200,
392
+ headers: staleData.headers
393
+ });
394
+ }
395
+ } catch (cacheErr) {
396
+ console.error("[vinext] fetch cache read error:", cacheErr);
397
+ }
398
+ const response = await originalFetch(input, stripNextFromInit(init));
399
+ if (response.status === 200) {
400
+ const cloned = response.clone();
401
+ const body = await cloned.text();
402
+ const headers = {};
403
+ cloned.headers.forEach((v, k) => {
404
+ headers[k] = v;
405
+ });
406
+ const cacheValue = {
407
+ kind: "FETCH",
408
+ data: {
409
+ headers,
410
+ body,
411
+ url: typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url,
412
+ status: cloned.status
413
+ },
414
+ tags,
415
+ revalidate: revalidateSeconds
416
+ };
417
+ handler.set(cacheKey, cacheValue, {
418
+ fetchCache: true,
419
+ tags,
420
+ revalidate: revalidateSeconds
421
+ }).catch((err) => {
422
+ console.error("[vinext] fetch cache write error:", err);
423
+ });
424
+ }
425
+ return response;
426
+ };
571
427
  }
572
428
  /**
573
- * Strip the `next` property from RequestInit before passing to real fetch.
574
- * The `next` property is not a standard fetch option and would cause warnings
575
- * in some environments.
576
- */
429
+ * Strip the `next` property from RequestInit before passing to real fetch.
430
+ * The `next` property is not a standard fetch option and would cause warnings
431
+ * in some environments.
432
+ */
577
433
  function stripNextFromInit(init) {
578
- if (!init)
579
- return init;
580
- const castInit = init;
581
- const { next: _next, _ogBody, ...rest } = castInit;
582
- // Restore the original body if it was stashed by serializeBody (e.g. after
583
- // consuming a ReadableStream for cache key generation).
584
- if (_ogBody !== undefined) {
585
- rest.body = _ogBody;
586
- }
587
- return Object.keys(rest).length > 0 ? rest : undefined;
434
+ if (!init) return init;
435
+ const { next: _next, _ogBody, ...rest } = init;
436
+ if (_ogBody !== void 0) rest.body = _ogBody;
437
+ return Object.keys(rest).length > 0 ? rest : void 0;
588
438
  }
589
- // ---------------------------------------------------------------------------
590
- // Public API
591
- // ---------------------------------------------------------------------------
592
- // ---------------------------------------------------------------------------
593
- // Fetch patching — install once, not per-request.
594
- // The patched fetch uses _getState() internally, which reads from ALS
595
- // (concurrent) or _fallbackState (single-threaded), so per-request
596
- // isolation is handled at the state level, not by swapping globalThis.fetch.
597
- // ---------------------------------------------------------------------------
598
439
  const _PATCH_KEY = Symbol.for("vinext.fetchCache.patchInstalled");
599
440
  function _ensurePatchInstalled() {
600
- if (_g[_PATCH_KEY])
601
- return;
602
- _g[_PATCH_KEY] = true;
603
- globalThis.fetch = createPatchedFetch();
441
+ if (_g[_PATCH_KEY]) return;
442
+ _g[_PATCH_KEY] = true;
443
+ globalThis.fetch = createPatchedFetch();
444
+ }
445
+ /**
446
+ * Install the patched fetch and reset per-request tag state.
447
+ * Returns a cleanup function that clears tags.
448
+ *
449
+ * @deprecated Prefer `runWithFetchCache()` which uses `AsyncLocalStorage.run()`
450
+ * for proper per-request isolation in concurrent environments.
451
+ *
452
+ * Usage:
453
+ * const cleanup = withFetchCache();
454
+ * try { await render(); } finally { cleanup(); }
455
+ */
456
+ function withFetchCache() {
457
+ _ensurePatchInstalled();
458
+ _resetFallbackState();
459
+ return () => {
460
+ _resetFallbackState();
461
+ };
604
462
  }
605
463
  /**
606
- * Install the patched fetch and reset per-request tag state.
607
- * Returns a cleanup function that clears tags.
608
- *
609
- * @deprecated Prefer `runWithFetchCache()` which uses `AsyncLocalStorage.run()`
610
- * for proper per-request isolation in concurrent environments.
611
- *
612
- * Usage:
613
- * const cleanup = withFetchCache();
614
- * try { await render(); } finally { cleanup(); }
615
- */
616
- export function withFetchCache() {
617
- _ensurePatchInstalled();
618
- _resetFallbackState();
619
- return () => {
620
- _resetFallbackState();
621
- };
464
+ * Run an async function with patched fetch caching enabled.
465
+ * Uses `AsyncLocalStorage.run()` for proper per-request isolation
466
+ * of collected fetch tags in concurrent server environments.
467
+ */
468
+ async function runWithFetchCache(fn) {
469
+ _ensurePatchInstalled();
470
+ if (isInsideUnifiedScope()) return await runWithUnifiedStateMutation((uCtx) => {
471
+ uCtx.currentRequestTags = [];
472
+ }, fn);
473
+ return _als.run({ currentRequestTags: [] }, fn);
622
474
  }
623
475
  /**
624
- * Run an async function with patched fetch caching enabled.
625
- * Uses `AsyncLocalStorage.run()` for proper per-request isolation
626
- * of collected fetch tags in concurrent server environments.
627
- */
628
- export async function runWithFetchCache(fn) {
629
- _ensurePatchInstalled();
630
- return _als.run({ currentRequestTags: [] }, fn);
476
+ * Install the patched fetch without creating a standalone ALS scope.
477
+ *
478
+ * `runWithFetchCache()` is the standalone helper: it installs the patch and
479
+ * creates an isolated per-request tag store. The unified request context owns
480
+ * that isolation itself via `currentRequestTags`, so callers inside
481
+ * `runWithRequestContext()` only need the process-global fetch monkey-patch.
482
+ */
483
+ function ensureFetchPatch() {
484
+ _ensurePatchInstalled();
631
485
  }
632
486
  /**
633
- * Get the original (unpatched) fetch function.
634
- * Useful for internal code that should bypass caching.
635
- */
636
- export function getOriginalFetch() {
637
- return originalFetch;
487
+ * Get the original (unpatched) fetch function.
488
+ * Useful for internal code that should bypass caching.
489
+ */
490
+ function getOriginalFetch() {
491
+ return originalFetch;
638
492
  }
493
+ //#endregion
494
+ export { _resetPendingRefetches, ensureFetchPatch, getCollectedFetchTags, getOriginalFetch, runWithFetchCache, withFetchCache };
495
+
639
496
  //# sourceMappingURL=fetch-cache.js.map