vinext 0.0.30 → 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 (435) 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 -571
  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 -380
  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 +442 -211
  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 +84 -113
  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 -3133
  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 +560 -670
  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 -14
  112. package/dist/server/dev-server.js +542 -869
  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 +181 -210
  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 +106 -128
  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 +270 -317
  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 +61 -61
  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 +273 -404
  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 +38 -30
  142. package/dist/server/pages-i18n.js +112 -139
  143. package/dist/server/pages-i18n.js.map +1 -1
  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 +20 -45
  162. package/dist/shims/cache-runtime.js +271 -422
  163. package/dist/shims/cache-runtime.js.map +1 -1
  164. package/dist/shims/cache.d.ts +130 -121
  165. package/dist/shims/cache.js +339 -427
  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 -164
  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 +16 -14
  191. package/dist/shims/fetch-cache.js +437 -645
  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 +8 -13
  208. package/dist/shims/head-state.js +25 -42
  209. package/dist/shims/head-state.js.map +1 -1
  210. package/dist/shims/head.d.ts +16 -20
  211. package/dist/shims/head.js +172 -250
  212. package/dist/shims/head.js.map +1 -1
  213. package/dist/shims/headers.d.ts +84 -78
  214. package/dist/shims/headers.js +447 -575
  215. package/dist/shims/headers.js.map +1 -1
  216. package/dist/shims/i18n-context.d.ts +16 -20
  217. package/dist/shims/i18n-context.js +35 -48
  218. package/dist/shims/i18n-context.js.map +1 -1
  219. package/dist/shims/i18n-state.d.ts +8 -14
  220. package/dist/shims/i18n-state.js +34 -42
  221. package/dist/shims/i18n-state.js.map +1 -1
  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 -46
  226. package/dist/shims/image.js +283 -308
  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 -37
  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 +255 -391
  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 -546
  258. package/dist/shims/metadata.js.map +1 -1
  259. package/dist/shims/navigation-state.d.ts +10 -18
  260. package/dist/shims/navigation-state.js +66 -74
  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 +505 -704
  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 -60
  272. package/dist/shims/request-context.js.map +1 -1
  273. package/dist/shims/request-state-types.d.ts +11 -11
  274. package/dist/shims/request-state-types.js +0 -1
  275. package/dist/shims/router-state.d.ts +13 -10
  276. package/dist/shims/router-state.js +34 -43
  277. package/dist/shims/router-state.js.map +1 -1
  278. package/dist/shims/router.d.ts +81 -85
  279. package/dist/shims/router.js +506 -628
  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 -164
  287. package/dist/shims/server.js +462 -478
  288. package/dist/shims/server.js.map +1 -1
  289. package/dist/shims/unified-request-context.d.ts +20 -20
  290. package/dist/shims/unified-request-context.js +81 -99
  291. package/dist/shims/unified-request-context.js.map +1 -1
  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 +17 -9
  305. package/dist/utils/domain-locale.js +36 -56
  306. package/dist/utils/domain-locale.js.map +1 -1
  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 +10 -9
  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/pages-i18n.d.ts.map +0 -1
  367. package/dist/server/prod-server.d.ts.map +0 -1
  368. package/dist/server/request-log.d.ts.map +0 -1
  369. package/dist/server/request-pipeline.d.ts.map +0 -1
  370. package/dist/server/worker-utils.d.ts.map +0 -1
  371. package/dist/shims/amp.d.ts.map +0 -1
  372. package/dist/shims/app.d.ts.map +0 -1
  373. package/dist/shims/app.js.map +0 -1
  374. package/dist/shims/cache-runtime.d.ts.map +0 -1
  375. package/dist/shims/cache.d.ts.map +0 -1
  376. package/dist/shims/client-only.d.ts.map +0 -1
  377. package/dist/shims/client-only.js.map +0 -1
  378. package/dist/shims/compat-router.d.ts.map +0 -1
  379. package/dist/shims/config.d.ts.map +0 -1
  380. package/dist/shims/constants.d.ts.map +0 -1
  381. package/dist/shims/document.d.ts.map +0 -1
  382. package/dist/shims/dynamic.d.ts.map +0 -1
  383. package/dist/shims/error-boundary.d.ts.map +0 -1
  384. package/dist/shims/error.d.ts.map +0 -1
  385. package/dist/shims/fetch-cache.d.ts.map +0 -1
  386. package/dist/shims/font-google-base.d.ts.map +0 -1
  387. package/dist/shims/font-google.d.ts.map +0 -1
  388. package/dist/shims/font-google.generated.d.ts.map +0 -1
  389. package/dist/shims/font-google.js.map +0 -1
  390. package/dist/shims/font-local.d.ts.map +0 -1
  391. package/dist/shims/form.d.ts.map +0 -1
  392. package/dist/shims/head-state.d.ts.map +0 -1
  393. package/dist/shims/head.d.ts.map +0 -1
  394. package/dist/shims/headers.d.ts.map +0 -1
  395. package/dist/shims/i18n-context.d.ts.map +0 -1
  396. package/dist/shims/i18n-state.d.ts.map +0 -1
  397. package/dist/shims/image-config.d.ts.map +0 -1
  398. package/dist/shims/image.d.ts.map +0 -1
  399. package/dist/shims/internal/api-utils.d.ts.map +0 -1
  400. package/dist/shims/internal/api-utils.js.map +0 -1
  401. package/dist/shims/internal/app-router-context.d.ts.map +0 -1
  402. package/dist/shims/internal/cookies.d.ts.map +0 -1
  403. package/dist/shims/internal/cookies.js.map +0 -1
  404. package/dist/shims/internal/parse-cookie-header.d.ts.map +0 -1
  405. package/dist/shims/internal/router-context.d.ts.map +0 -1
  406. package/dist/shims/internal/utils.d.ts.map +0 -1
  407. package/dist/shims/internal/work-unit-async-storage.d.ts.map +0 -1
  408. package/dist/shims/layout-segment-context.d.ts.map +0 -1
  409. package/dist/shims/legacy-image.d.ts.map +0 -1
  410. package/dist/shims/link.d.ts.map +0 -1
  411. package/dist/shims/metadata.d.ts.map +0 -1
  412. package/dist/shims/navigation-state.d.ts.map +0 -1
  413. package/dist/shims/navigation.d.ts.map +0 -1
  414. package/dist/shims/og.d.ts.map +0 -1
  415. package/dist/shims/og.js.map +0 -1
  416. package/dist/shims/readonly-url-search-params.d.ts.map +0 -1
  417. package/dist/shims/request-context.d.ts.map +0 -1
  418. package/dist/shims/request-state-types.d.ts.map +0 -1
  419. package/dist/shims/request-state-types.js.map +0 -1
  420. package/dist/shims/router-state.d.ts.map +0 -1
  421. package/dist/shims/router.d.ts.map +0 -1
  422. package/dist/shims/script.d.ts.map +0 -1
  423. package/dist/shims/server-only.d.ts.map +0 -1
  424. package/dist/shims/server-only.js.map +0 -1
  425. package/dist/shims/server.d.ts.map +0 -1
  426. package/dist/shims/unified-request-context.d.ts.map +0 -1
  427. package/dist/shims/url-safety.d.ts.map +0 -1
  428. package/dist/shims/url-utils.d.ts.map +0 -1
  429. package/dist/shims/web-vitals.d.ts.map +0 -1
  430. package/dist/utils/base-path.d.ts.map +0 -1
  431. package/dist/utils/domain-locale.d.ts.map +0 -1
  432. package/dist/utils/hash.d.ts.map +0 -1
  433. package/dist/utils/manifest-paths.d.ts.map +0 -1
  434. package/dist/utils/project.d.ts.map +0 -1
  435. package/dist/utils/query.d.ts.map +0 -1
@@ -1,411 +1,385 @@
1
- /**
2
- * Cloudflare KV-backed CacheHandler for vinext.
3
- *
4
- * Provides persistent ISR caching on Cloudflare Workers using KV as the
5
- * storage backend. Supports time-based expiry (stale-while-revalidate)
6
- * and tag-based invalidation.
7
- *
8
- * Usage in worker/index.ts:
9
- *
10
- * import { KVCacheHandler } from "vinext/cloudflare";
11
- * import { setCacheHandler } from "vinext/shims/cache";
12
- *
13
- * export default {
14
- * async fetch(request: Request, env: Env, ctx: ExecutionContext) {
15
- * setCacheHandler(new KVCacheHandler(env.VINEXT_CACHE));
16
- * // ctx is propagated automatically via runWithExecutionContext in
17
- * // the vinext handler — no need to pass it to KVCacheHandler.
18
- * // ... rest of worker handler
19
- * }
20
- * };
21
- *
22
- * Wrangler config (wrangler.jsonc):
23
- *
24
- * {
25
- * "kv_namespaces": [
26
- * { "binding": "VINEXT_CACHE", "id": "<your-kv-namespace-id>" }
27
- * ]
28
- * }
29
- */
30
- import { Buffer } from "node:buffer";
31
1
  import { getRequestExecutionContext } from "../shims/request-context.js";
2
+ import { Buffer } from "node:buffer";
3
+ //#region src/cloudflare/kv-cache-handler.ts
4
+ /**
5
+ * Cloudflare KV-backed CacheHandler for vinext.
6
+ *
7
+ * Provides persistent ISR caching on Cloudflare Workers using KV as the
8
+ * storage backend. Supports time-based expiry (stale-while-revalidate)
9
+ * and tag-based invalidation.
10
+ *
11
+ * Usage in worker/index.ts:
12
+ *
13
+ * import { KVCacheHandler } from "vinext/cloudflare";
14
+ * import { setCacheHandler } from "vinext/shims/cache";
15
+ *
16
+ * export default {
17
+ * async fetch(request: Request, env: Env, ctx: ExecutionContext) {
18
+ * setCacheHandler(new KVCacheHandler(env.VINEXT_CACHE));
19
+ * // ctx is propagated automatically via runWithExecutionContext in
20
+ * // the vinext handler — no need to pass it to KVCacheHandler.
21
+ * // ... rest of worker handler
22
+ * }
23
+ * };
24
+ *
25
+ * Wrangler config (wrangler.jsonc):
26
+ *
27
+ * {
28
+ * "kv_namespaces": [
29
+ * { "binding": "VINEXT_CACHE", "id": "<your-kv-namespace-id>" }
30
+ * ]
31
+ * }
32
+ */
32
33
  /** Key prefix for tag invalidation timestamps. */
33
34
  const TAG_PREFIX = "__tag:";
34
35
  /** Key prefix for cache entries. */
35
36
  const ENTRY_PREFIX = "cache:";
37
+ /** Prefix used by revalidatePath for path-based tags. */
38
+ const PATH_TAG_PREFIX = "_N_T_";
36
39
  /** Max tag length to prevent KV key abuse. */
37
40
  const MAX_TAG_LENGTH = 256;
38
41
  /** Matches a valid base64 string (standard alphabet with optional padding). */
39
42
  const BASE64_RE = /^[A-Za-z0-9+/]*={0,2}$/;
40
43
  /**
41
- * Validate a cache tag. Returns null if invalid.
42
- * Note: `:` is rejected because TAG_PREFIX and ENTRY_PREFIX use `:` as a
43
- * separator — allowing `:` in user tags could cause ambiguous key lookups.
44
- */
44
+ * Validate a cache tag. Returns null if invalid.
45
+ * Note: `:` is rejected because TAG_PREFIX and ENTRY_PREFIX use `:` as a
46
+ * separator — allowing `:` in user tags could cause ambiguous key lookups.
47
+ */
45
48
  function validateTag(tag) {
46
- if (typeof tag !== "string" || tag.length === 0 || tag.length > MAX_TAG_LENGTH)
47
- return null;
48
- // Block control characters and reserved separators used in our own key format.
49
- // Slash is allowed because revalidatePath() relies on pathname tags like
50
- // "/posts/hello" and "_N_T_/posts/hello".
51
- // eslint-disable-next-line no-control-regex -- intentional: reject control chars in tags
52
- if (/[\x00-\x1f\\:]/.test(tag))
53
- return null;
54
- return tag;
49
+ if (typeof tag !== "string" || tag.length === 0 || tag.length > MAX_TAG_LENGTH) return null;
50
+ if (/[\x00-\x1f\\:]/.test(tag)) return null;
51
+ return tag;
55
52
  }
56
- export class KVCacheHandler {
57
- kv;
58
- prefix;
59
- ctx;
60
- ttlSeconds;
61
- /** Local in-memory cache for tag invalidation timestamps. Avoids redundant KV reads. */
62
- _tagCache = new Map();
63
- /** TTL (ms) for local tag cache entries. After this, re-fetch from KV. */
64
- _tagCacheTtl;
65
- constructor(kvNamespace, options) {
66
- this.kv = kvNamespace;
67
- this.prefix = options?.appPrefix ? `${options.appPrefix}:` : "";
68
- this.ctx = options?.ctx;
69
- this.ttlSeconds = options?.ttlSeconds ?? 30 * 24 * 3600;
70
- this._tagCacheTtl = options?.tagCacheTtlMs ?? 5_000;
71
- }
72
- async get(key, _ctx) {
73
- const kvKey = this.prefix + ENTRY_PREFIX + key;
74
- const raw = await this.kv.get(kvKey);
75
- if (!raw)
76
- return null;
77
- let parsed;
78
- try {
79
- parsed = JSON.parse(raw);
80
- }
81
- catch {
82
- // Corrupted JSON — fire cleanup delete in the background and treat as miss.
83
- // Using waitUntil ensures the delete isn't killed when the Response is returned.
84
- this._deleteInBackground(kvKey);
85
- return null;
86
- }
87
- // Validate deserialized shape before using
88
- const entry = validateCacheEntry(parsed);
89
- if (!entry) {
90
- console.error("[vinext] Invalid cache entry shape for key:", key);
91
- this._deleteInBackground(kvKey);
92
- return null;
93
- }
94
- // Restore ArrayBuffer fields that were base64-encoded for JSON storage
95
- let restoredValue = null;
96
- if (entry.value) {
97
- restoredValue = restoreArrayBuffers(entry.value);
98
- if (!restoredValue) {
99
- // base64 decode failed — corrupted entry, treat as miss
100
- this._deleteInBackground(kvKey);
101
- return null;
102
- }
103
- }
104
- // Check tag-based invalidation.
105
- // Uses a local in-memory cache to avoid redundant KV reads for recently-seen tags.
106
- if (entry.tags.length > 0) {
107
- const now = Date.now();
108
- const uncachedTags = [];
109
- // First pass: check local cache for each tag.
110
- // Delete expired entries to prevent unbounded Map growth in long-lived isolates.
111
- for (const tag of entry.tags) {
112
- const cached = this._tagCache.get(tag);
113
- if (cached && now - cached.fetchedAt < this._tagCacheTtl) {
114
- // Local cache hit — check invalidation inline
115
- if (Number.isNaN(cached.timestamp) || cached.timestamp >= entry.lastModified) {
116
- this._deleteInBackground(kvKey);
117
- return null;
118
- }
119
- }
120
- else {
121
- // Expired or absent — evict stale entry and re-fetch from KV
122
- if (cached)
123
- this._tagCache.delete(tag);
124
- uncachedTags.push(tag);
125
- }
126
- }
127
- // Second pass: fetch uncached tags from KV in parallel.
128
- // Populate the local cache for ALL fetched tags before checking invalidation,
129
- // so that KV round-trips are not wasted when an earlier tag triggers an
130
- // early return — subsequent get() calls benefit from the already-fetched results.
131
- if (uncachedTags.length > 0) {
132
- const tagResults = await Promise.all(uncachedTags.map((tag) => this.kv.get(this.prefix + TAG_PREFIX + tag)));
133
- // Populate cache for all results first, then check for invalidation.
134
- // Two-loop structure ensures all tag results are cached even when an
135
- // earlier tag would cause an early return — so subsequent get() calls
136
- // for entries sharing those tags don't redundantly re-fetch from KV.
137
- for (let i = 0; i < uncachedTags.length; i++) {
138
- const tagTime = tagResults[i];
139
- const tagTimestamp = tagTime ? Number(tagTime) : 0;
140
- this._tagCache.set(uncachedTags[i], { timestamp: tagTimestamp, fetchedAt: now });
141
- }
142
- // Then check for invalidation using the now-cached timestamps
143
- for (const tag of uncachedTags) {
144
- const cached = this._tagCache.get(tag);
145
- if (cached.timestamp !== 0) {
146
- if (Number.isNaN(cached.timestamp) || cached.timestamp >= entry.lastModified) {
147
- this._deleteInBackground(kvKey);
148
- return null;
149
- }
150
- }
151
- }
152
- }
153
- }
154
- // Check time-based expiry — return stale with cacheState
155
- if (entry.revalidateAt !== null && Date.now() > entry.revalidateAt) {
156
- return {
157
- lastModified: entry.lastModified,
158
- value: restoredValue,
159
- cacheState: "stale",
160
- };
161
- }
162
- return {
163
- lastModified: entry.lastModified,
164
- value: restoredValue,
165
- };
166
- }
167
- set(key, data, ctx) {
168
- // Collect, validate, and dedupe tags from data and context
169
- const tagSet = new Set();
170
- if (data && "tags" in data && Array.isArray(data.tags)) {
171
- for (const t of data.tags) {
172
- const validated = validateTag(t);
173
- if (validated)
174
- tagSet.add(validated);
175
- }
176
- }
177
- if (ctx && "tags" in ctx && Array.isArray(ctx.tags)) {
178
- for (const t of ctx.tags) {
179
- const validated = validateTag(t);
180
- if (validated)
181
- tagSet.add(validated);
182
- }
183
- }
184
- const tags = [...tagSet];
185
- // Resolve effective revalidate — data overrides ctx.
186
- // revalidate: 0 means "don't cache", so skip storage entirely.
187
- let effectiveRevalidate;
188
- if (ctx) {
189
- const revalidate = ctx.cacheControl?.revalidate ?? ctx.revalidate;
190
- if (typeof revalidate === "number") {
191
- effectiveRevalidate = revalidate;
192
- }
193
- }
194
- if (data && "revalidate" in data && typeof data.revalidate === "number") {
195
- effectiveRevalidate = data.revalidate;
196
- }
197
- if (effectiveRevalidate === 0)
198
- return Promise.resolve();
199
- const revalidateAt = typeof effectiveRevalidate === "number" && effectiveRevalidate > 0
200
- ? Date.now() + effectiveRevalidate * 1000
201
- : null;
202
- // Prepare entry — convert ArrayBuffers to base64 for JSON storage
203
- const serializable = data ? serializeForJSON(data) : null;
204
- const entry = {
205
- value: serializable,
206
- tags,
207
- lastModified: Date.now(),
208
- revalidateAt,
209
- };
210
- // KV TTL is decoupled from the revalidation period.
211
- //
212
- // Staleness (when to trigger background regen) is tracked by `revalidateAt`
213
- // in the stored JSON — not by KV eviction. KV eviction is purely a storage
214
- // hygiene mechanism and must never be the reason a stale entry disappears.
215
- //
216
- // If KV TTL were tied to the revalidate window (e.g. 10x), a page with
217
- // revalidate=5 would be evicted after ~50 seconds of no traffic, causing the
218
- // next request to block on a fresh render instead of serving stale content.
219
- //
220
- // Fix: always keep entries for 30 days regardless of revalidate frequency.
221
- // Background regen overwrites the key with a fresh entry + new revalidateAt,
222
- // so active pages always have something to serve. Entries only disappear after
223
- // 30 days of zero traffic, or when explicitly deleted via tag invalidation.
224
- const expirationTtl = revalidateAt !== null ? this.ttlSeconds : undefined;
225
- return this._put(this.prefix + ENTRY_PREFIX + key, JSON.stringify(entry), {
226
- expirationTtl,
227
- });
228
- }
229
- async revalidateTag(tags, _durations) {
230
- const tagList = Array.isArray(tags) ? tags : [tags];
231
- const now = Date.now();
232
- const validTags = tagList.filter((t) => validateTag(t) !== null);
233
- // Store invalidation timestamp for each tag
234
- // Use a long TTL (30 days) so recent invalidations are always found
235
- await Promise.all(validTags.map((tag) => this.kv.put(this.prefix + TAG_PREFIX + tag, String(now), {
236
- expirationTtl: 30 * 24 * 3600,
237
- })));
238
- // Update local tag cache immediately so invalidations are reflected
239
- // without waiting for the TTL to expire
240
- for (const tag of validTags) {
241
- this._tagCache.set(tag, { timestamp: now, fetchedAt: now });
242
- }
243
- }
244
- /**
245
- * Clear the in-memory tag cache for this KVCacheHandler instance.
246
- *
247
- * Note: KVCacheHandler instances are typically reused across multiple
248
- * requests in a Cloudflare Worker. The `_tagCache` is intentionally
249
- * cross-request — it reduces redundant KV reads for recently-seen tags
250
- * across all requests hitting the same isolate, bounded by `tagCacheTtlMs`
251
- * (default 5s). vinext does NOT call this method per request.
252
- *
253
- * This is an opt-in escape hatch for callers that need stricter isolation
254
- * (e.g., tests, or environments with custom lifecycle management).
255
- * Callers that require per-request isolation should either construct a
256
- * fresh KVCacheHandler per request or invoke this method explicitly.
257
- */
258
- resetRequestCache() {
259
- this._tagCache.clear();
260
- }
261
- /**
262
- * Fire a KV delete in the background.
263
- * Prefers the per-request ExecutionContext from ALS (set by
264
- * runWithExecutionContext in the worker entry) so that background KV
265
- * operations are registered with the correct request's waitUntil().
266
- * Falls back to the constructor-provided ctx for callers that set it
267
- * explicitly, and to fire-and-forget when neither is available (Node.js dev).
268
- */
269
- _deleteInBackground(kvKey) {
270
- const promise = this.kv.delete(kvKey);
271
- const ctx = getRequestExecutionContext() ?? this.ctx;
272
- if (ctx) {
273
- ctx.waitUntil(promise);
274
- }
275
- // else: fire-and-forget on Node.js
276
- }
277
- /**
278
- * Execute a KV put and return the promise so callers can await completion.
279
- * Also registers with ctx.waitUntil() so the Workers runtime keeps the
280
- * isolate alive even if the caller does not await the returned promise.
281
- */
282
- _put(kvKey, value, options) {
283
- const promise = this.kv.put(kvKey, value, options);
284
- const ctx = getRequestExecutionContext() ?? this.ctx;
285
- if (ctx) {
286
- ctx.waitUntil(promise);
287
- }
288
- return promise;
289
- }
53
+ /**
54
+ * Segment-aware path prefix check. Returns true if `path` is equal to
55
+ * `prefix` or is a child route (next char after prefix is `/`).
56
+ * Prevents `/dashboard` from matching `/dashboard-admin`.
57
+ */
58
+ function isPathChildOf(path, prefix) {
59
+ if (prefix === "/") return path.startsWith("/");
60
+ if (path === prefix) return true;
61
+ return path.startsWith(prefix + "/");
290
62
  }
291
- // ---------------------------------------------------------------------------
292
- // Validation helpers
293
- // ---------------------------------------------------------------------------
294
- const VALID_KINDS = new Set(["FETCH", "APP_PAGE", "PAGES", "APP_ROUTE", "REDIRECT", "IMAGE"]);
63
+ var KVCacheHandler = class {
64
+ kv;
65
+ prefix;
66
+ ctx;
67
+ ttlSeconds;
68
+ /** Local in-memory cache for tag invalidation timestamps. Avoids redundant KV reads. */
69
+ _tagCache = /* @__PURE__ */ new Map();
70
+ /** TTL (ms) for local tag cache entries. After this, re-fetch from KV. */
71
+ _tagCacheTtl;
72
+ constructor(kvNamespace, options) {
73
+ this.kv = kvNamespace;
74
+ this.prefix = options?.appPrefix ? `${options.appPrefix}:` : "";
75
+ this.ctx = options?.ctx;
76
+ this.ttlSeconds = options?.ttlSeconds ?? 720 * 3600;
77
+ this._tagCacheTtl = options?.tagCacheTtlMs ?? 5e3;
78
+ }
79
+ async get(key, _ctx) {
80
+ const kvKey = this.prefix + ENTRY_PREFIX + key;
81
+ const raw = await this.kv.get(kvKey);
82
+ if (!raw) return null;
83
+ let parsed;
84
+ try {
85
+ parsed = JSON.parse(raw);
86
+ } catch {
87
+ this._deleteInBackground(kvKey);
88
+ return null;
89
+ }
90
+ const entry = validateCacheEntry(parsed);
91
+ if (!entry) {
92
+ console.error("[vinext] Invalid cache entry shape for key:", key);
93
+ this._deleteInBackground(kvKey);
94
+ return null;
95
+ }
96
+ let restoredValue = null;
97
+ if (entry.value) {
98
+ restoredValue = restoreArrayBuffers(entry.value);
99
+ if (!restoredValue) {
100
+ this._deleteInBackground(kvKey);
101
+ return null;
102
+ }
103
+ }
104
+ if (entry.tags.length > 0) {
105
+ const now = Date.now();
106
+ const uncachedTags = [];
107
+ for (const tag of entry.tags) {
108
+ const cached = this._tagCache.get(tag);
109
+ if (cached && now - cached.fetchedAt < this._tagCacheTtl) {
110
+ if (Number.isNaN(cached.timestamp) || cached.timestamp >= entry.lastModified) {
111
+ this._deleteInBackground(kvKey);
112
+ return null;
113
+ }
114
+ } else {
115
+ if (cached) this._tagCache.delete(tag);
116
+ uncachedTags.push(tag);
117
+ }
118
+ }
119
+ if (uncachedTags.length > 0) {
120
+ const tagResults = await Promise.all(uncachedTags.map((tag) => this.kv.get(this.prefix + TAG_PREFIX + tag)));
121
+ for (let i = 0; i < uncachedTags.length; i++) {
122
+ const tagTime = tagResults[i];
123
+ const tagTimestamp = tagTime ? Number(tagTime) : 0;
124
+ this._tagCache.set(uncachedTags[i], {
125
+ timestamp: tagTimestamp,
126
+ fetchedAt: now
127
+ });
128
+ }
129
+ for (const tag of uncachedTags) {
130
+ const cached = this._tagCache.get(tag);
131
+ if (cached.timestamp !== 0) {
132
+ if (Number.isNaN(cached.timestamp) || cached.timestamp >= entry.lastModified) {
133
+ this._deleteInBackground(kvKey);
134
+ return null;
135
+ }
136
+ }
137
+ }
138
+ }
139
+ }
140
+ if (entry.revalidateAt !== null && Date.now() > entry.revalidateAt) return {
141
+ lastModified: entry.lastModified,
142
+ value: restoredValue,
143
+ cacheState: "stale"
144
+ };
145
+ return {
146
+ lastModified: entry.lastModified,
147
+ value: restoredValue
148
+ };
149
+ }
150
+ set(key, data, ctx) {
151
+ const tagSet = /* @__PURE__ */ new Set();
152
+ if (data && "tags" in data && Array.isArray(data.tags)) for (const t of data.tags) {
153
+ const validated = validateTag(t);
154
+ if (validated) tagSet.add(validated);
155
+ }
156
+ if (ctx && "tags" in ctx && Array.isArray(ctx.tags)) for (const t of ctx.tags) {
157
+ const validated = validateTag(t);
158
+ if (validated) tagSet.add(validated);
159
+ }
160
+ const tags = [...tagSet];
161
+ let effectiveRevalidate;
162
+ if (ctx) {
163
+ const revalidate = ctx.cacheControl?.revalidate ?? ctx.revalidate;
164
+ if (typeof revalidate === "number") effectiveRevalidate = revalidate;
165
+ }
166
+ if (data && "revalidate" in data && typeof data.revalidate === "number") effectiveRevalidate = data.revalidate;
167
+ if (effectiveRevalidate === 0) return Promise.resolve();
168
+ const revalidateAt = typeof effectiveRevalidate === "number" && effectiveRevalidate > 0 ? Date.now() + effectiveRevalidate * 1e3 : null;
169
+ const entry = {
170
+ value: data ? serializeForJSON(data) : null,
171
+ tags,
172
+ lastModified: Date.now(),
173
+ revalidateAt
174
+ };
175
+ const expirationTtl = revalidateAt !== null ? this.ttlSeconds : void 0;
176
+ const metadata = JSON.stringify({ tags }).length <= 1024 ? { tags } : void 0;
177
+ return this._put(this.prefix + ENTRY_PREFIX + key, JSON.stringify(entry), {
178
+ expirationTtl,
179
+ metadata
180
+ });
181
+ }
182
+ async revalidateTag(tags, _durations) {
183
+ const tagList = Array.isArray(tags) ? tags : [tags];
184
+ const now = Date.now();
185
+ const validTags = tagList.filter((t) => validateTag(t) !== null);
186
+ await Promise.all(validTags.map((tag) => this.kv.put(this.prefix + TAG_PREFIX + tag, String(now), { expirationTtl: 720 * 3600 })));
187
+ for (const tag of validTags) this._tagCache.set(tag, {
188
+ timestamp: now,
189
+ fetchedAt: now
190
+ });
191
+ }
192
+ /**
193
+ * Invalidate all cache entries whose path tags fall under `pathPrefix`.
194
+ *
195
+ * Uses KV list metadata to discover tags without fetching entry values —
196
+ * entries written by `set()` store their tags in KV metadata, so
197
+ * `kv.list()` returns them inline with each key. This makes prefix
198
+ * invalidation O(list_pages) instead of O(entries × get).
199
+ *
200
+ * Entries written before metadata was added (no metadata.tags) are
201
+ * gracefully skipped — they'll be picked up on next `set()` which
202
+ * writes metadata.
203
+ *
204
+ * When present, this method fully replaces the `revalidateTag` call
205
+ * path in `revalidatePath()` — implementors own all path-based tag
206
+ * handling.
207
+ */
208
+ async revalidateByPathPrefix(pathPrefix) {
209
+ const tagsToInvalidate = /* @__PURE__ */ new Set();
210
+ let cursor;
211
+ const listPrefix = this.prefix + ENTRY_PREFIX;
212
+ do {
213
+ const page = await this.kv.list({
214
+ prefix: listPrefix,
215
+ cursor
216
+ });
217
+ for (const key of page.keys) {
218
+ const tags = key.metadata?.tags;
219
+ if (!Array.isArray(tags)) continue;
220
+ for (const tag of tags) {
221
+ if (typeof tag !== "string") continue;
222
+ const rawPath = tag.startsWith(PATH_TAG_PREFIX) ? tag.slice(5) : tag;
223
+ if (rawPath.startsWith("/") && isPathChildOf(rawPath, pathPrefix)) tagsToInvalidate.add(tag);
224
+ }
225
+ }
226
+ cursor = page.list_complete ? void 0 : page.cursor;
227
+ } while (cursor);
228
+ if (tagsToInvalidate.size > 0) await this.revalidateTag([...tagsToInvalidate]);
229
+ }
230
+ /**
231
+ * Clear the in-memory tag cache for this KVCacheHandler instance.
232
+ *
233
+ * Note: KVCacheHandler instances are typically reused across multiple
234
+ * requests in a Cloudflare Worker. The `_tagCache` is intentionally
235
+ * cross-request — it reduces redundant KV reads for recently-seen tags
236
+ * across all requests hitting the same isolate, bounded by `tagCacheTtlMs`
237
+ * (default 5s). vinext does NOT call this method per request.
238
+ *
239
+ * This is an opt-in escape hatch for callers that need stricter isolation
240
+ * (e.g., tests, or environments with custom lifecycle management).
241
+ * Callers that require per-request isolation should either construct a
242
+ * fresh KVCacheHandler per request or invoke this method explicitly.
243
+ */
244
+ resetRequestCache() {
245
+ this._tagCache.clear();
246
+ }
247
+ /**
248
+ * Fire a KV delete in the background.
249
+ * Prefers the per-request ExecutionContext from ALS (set by
250
+ * runWithExecutionContext in the worker entry) so that background KV
251
+ * operations are registered with the correct request's waitUntil().
252
+ * Falls back to the constructor-provided ctx for callers that set it
253
+ * explicitly, and to fire-and-forget when neither is available (Node.js dev).
254
+ */
255
+ _deleteInBackground(kvKey) {
256
+ const promise = this.kv.delete(kvKey);
257
+ const ctx = getRequestExecutionContext() ?? this.ctx;
258
+ if (ctx) ctx.waitUntil(promise);
259
+ }
260
+ /**
261
+ * Execute a KV put and return the promise so callers can await completion.
262
+ * Also registers with ctx.waitUntil() so the Workers runtime keeps the
263
+ * isolate alive even if the caller does not await the returned promise.
264
+ */
265
+ _put(kvKey, value, options) {
266
+ const promise = this.kv.put(kvKey, value, options);
267
+ const ctx = getRequestExecutionContext() ?? this.ctx;
268
+ if (ctx) ctx.waitUntil(promise);
269
+ return promise;
270
+ }
271
+ };
272
+ const VALID_KINDS = new Set([
273
+ "FETCH",
274
+ "APP_PAGE",
275
+ "PAGES",
276
+ "APP_ROUTE",
277
+ "REDIRECT",
278
+ "IMAGE"
279
+ ]);
295
280
  /**
296
- * Validate that a parsed JSON value has the expected KVCacheEntry shape.
297
- * Returns the validated entry or null if the shape is invalid.
298
- */
281
+ * Validate that a parsed JSON value has the expected KVCacheEntry shape.
282
+ * Returns the validated entry or null if the shape is invalid.
283
+ */
299
284
  function validateCacheEntry(raw) {
300
- if (!raw || typeof raw !== "object")
301
- return null;
302
- const obj = raw;
303
- // Required fields
304
- if (typeof obj.lastModified !== "number")
305
- return null;
306
- if (!Array.isArray(obj.tags))
307
- return null;
308
- if (obj.revalidateAt !== null && typeof obj.revalidateAt !== "number")
309
- return null;
310
- // value must be null or a valid cache value object with a known kind
311
- if (obj.value !== null) {
312
- if (!obj.value || typeof obj.value !== "object")
313
- return null;
314
- const value = obj.value;
315
- if (typeof value.kind !== "string" || !VALID_KINDS.has(value.kind))
316
- return null;
317
- }
318
- return raw;
285
+ if (!raw || typeof raw !== "object") return null;
286
+ const obj = raw;
287
+ if (typeof obj.lastModified !== "number") return null;
288
+ if (!Array.isArray(obj.tags)) return null;
289
+ if (obj.revalidateAt !== null && typeof obj.revalidateAt !== "number") return null;
290
+ if (obj.value !== null) {
291
+ if (!obj.value || typeof obj.value !== "object") return null;
292
+ const value = obj.value;
293
+ if (typeof value.kind !== "string" || !VALID_KINDS.has(value.kind)) return null;
294
+ }
295
+ return raw;
319
296
  }
320
- // ---------------------------------------------------------------------------
321
- // ArrayBuffer serialization helpers
322
- // ---------------------------------------------------------------------------
323
297
  /**
324
- * Deep-clone a cache value, converting ArrayBuffer fields to base64 strings
325
- * so the entire structure can be JSON.stringify'd for KV storage.
326
- */
298
+ * Deep-clone a cache value, converting ArrayBuffer fields to base64 strings
299
+ * so the entire structure can be JSON.stringify'd for KV storage.
300
+ */
327
301
  function serializeForJSON(value) {
328
- if (value.kind === "APP_PAGE") {
329
- return {
330
- ...value,
331
- rscData: value.rscData ? arrayBufferToBase64(value.rscData) : undefined,
332
- };
333
- }
334
- if (value.kind === "APP_ROUTE") {
335
- return {
336
- ...value,
337
- body: arrayBufferToBase64(value.body),
338
- };
339
- }
340
- if (value.kind === "IMAGE") {
341
- return {
342
- ...value,
343
- buffer: arrayBufferToBase64(value.buffer),
344
- };
345
- }
346
- return value;
302
+ if (value.kind === "APP_PAGE") return {
303
+ ...value,
304
+ rscData: value.rscData ? arrayBufferToBase64(value.rscData) : void 0
305
+ };
306
+ if (value.kind === "APP_ROUTE") return {
307
+ ...value,
308
+ body: arrayBufferToBase64(value.body)
309
+ };
310
+ if (value.kind === "IMAGE") return {
311
+ ...value,
312
+ buffer: arrayBufferToBase64(value.buffer)
313
+ };
314
+ return value;
347
315
  }
348
316
  /**
349
- * Restore base64 strings back to ArrayBuffers after JSON.parse.
350
- * Returns the restored `IncrementalCacheValue`, or `null` if any base64
351
- * decode fails (corrupted entry).
352
- */
317
+ * Restore base64 strings back to ArrayBuffers after JSON.parse.
318
+ * Returns the restored `IncrementalCacheValue`, or `null` if any base64
319
+ * decode fails (corrupted entry).
320
+ */
353
321
  function restoreArrayBuffers(value) {
354
- if (value.kind === "APP_PAGE") {
355
- if (typeof value.rscData === "string") {
356
- const decoded = safeBase64ToArrayBuffer(value.rscData);
357
- if (!decoded)
358
- return null;
359
- return { ...value, rscData: decoded };
360
- }
361
- return value;
362
- }
363
- if (value.kind === "APP_ROUTE") {
364
- if (typeof value.body === "string") {
365
- const decoded = safeBase64ToArrayBuffer(value.body);
366
- if (!decoded)
367
- return null;
368
- return { ...value, body: decoded };
369
- }
370
- return value;
371
- }
372
- if (value.kind === "IMAGE") {
373
- if (typeof value.buffer === "string") {
374
- const decoded = safeBase64ToArrayBuffer(value.buffer);
375
- if (!decoded)
376
- return null;
377
- return { ...value, buffer: decoded };
378
- }
379
- return value;
380
- }
381
- return value;
322
+ if (value.kind === "APP_PAGE") {
323
+ if (typeof value.rscData === "string") {
324
+ const decoded = safeBase64ToArrayBuffer(value.rscData);
325
+ if (!decoded) return null;
326
+ return {
327
+ ...value,
328
+ rscData: decoded
329
+ };
330
+ }
331
+ return value;
332
+ }
333
+ if (value.kind === "APP_ROUTE") {
334
+ if (typeof value.body === "string") {
335
+ const decoded = safeBase64ToArrayBuffer(value.body);
336
+ if (!decoded) return null;
337
+ return {
338
+ ...value,
339
+ body: decoded
340
+ };
341
+ }
342
+ return value;
343
+ }
344
+ if (value.kind === "IMAGE") {
345
+ if (typeof value.buffer === "string") {
346
+ const decoded = safeBase64ToArrayBuffer(value.buffer);
347
+ if (!decoded) return null;
348
+ return {
349
+ ...value,
350
+ buffer: decoded
351
+ };
352
+ }
353
+ return value;
354
+ }
355
+ return value;
382
356
  }
383
357
  function arrayBufferToBase64(buffer) {
384
- return Buffer.from(buffer).toString("base64");
358
+ return Buffer.from(buffer).toString("base64");
385
359
  }
386
360
  /**
387
- * Decode a base64 string to an ArrayBuffer.
388
- * Validates the input against the base64 alphabet before decoding,
389
- * since Buffer.from(str, "base64") silently ignores invalid characters.
390
- */
361
+ * Decode a base64 string to an ArrayBuffer.
362
+ * Validates the input against the base64 alphabet before decoding,
363
+ * since Buffer.from(str, "base64") silently ignores invalid characters.
364
+ */
391
365
  function base64ToArrayBuffer(base64) {
392
- if (!BASE64_RE.test(base64) || base64.length % 4 !== 0) {
393
- throw new Error("Invalid base64 string");
394
- }
395
- const buf = Buffer.from(base64, "base64");
396
- return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
366
+ if (!BASE64_RE.test(base64) || base64.length % 4 !== 0) throw new Error("Invalid base64 string");
367
+ const buf = Buffer.from(base64, "base64");
368
+ return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
397
369
  }
398
370
  /**
399
- * Safely decode base64 to ArrayBuffer. Returns null on invalid input
400
- * instead of throwing.
401
- */
371
+ * Safely decode base64 to ArrayBuffer. Returns null on invalid input
372
+ * instead of throwing.
373
+ */
402
374
  function safeBase64ToArrayBuffer(base64) {
403
- try {
404
- return base64ToArrayBuffer(base64);
405
- }
406
- catch {
407
- console.error("[vinext] Invalid base64 in cache entry");
408
- return null;
409
- }
375
+ try {
376
+ return base64ToArrayBuffer(base64);
377
+ } catch {
378
+ console.error("[vinext] Invalid base64 in cache entry");
379
+ return null;
380
+ }
410
381
  }
382
+ //#endregion
383
+ export { KVCacheHandler };
384
+
411
385
  //# sourceMappingURL=kv-cache-handler.js.map