@wular/pnext 0.0.4 → 0.0.6

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 (392) hide show
  1. package/README.md +11 -11
  2. package/bin/pnext +1 -1
  3. package/config/lint/base.js +7 -7
  4. package/config/ts/base.json +2 -4
  5. package/config/ts/react.json +2 -6
  6. package/package.json +23 -2
  7. package/reference/compat.md +1 -1
  8. package/reference/config.md +2 -2
  9. package/reference/css.md +13 -9
  10. package/reference/dev.md +1 -1
  11. package/reference/metadata.md +7 -7
  12. package/reference/navigation.md +35 -28
  13. package/reference/performance.md +70 -70
  14. package/reference/rendering.md +17 -17
  15. package/reference/routing.md +17 -17
  16. package/reference/typegen.md +12 -8
  17. package/src/api/cache.ts +36 -37
  18. package/src/api/client-cache.ts +2 -2
  19. package/src/api/client-navigation.ts +113 -109
  20. package/src/api/dynamic.tsx +58 -55
  21. package/src/api/link.tsx +49 -52
  22. package/src/api/navigation.ts +59 -58
  23. package/src/api/server.ts +152 -144
  24. package/src/api/suspense.ts +4 -4
  25. package/src/cli/adapters/vercel-warm.ts +126 -121
  26. package/src/cli/adapters/vercel.ts +437 -443
  27. package/src/cli/analyze.ts +333 -144
  28. package/src/cli/{named-bin.ts → boot/named-bin.ts} +37 -37
  29. package/src/cli/{boot-trace.ts → boot/trace.ts} +10 -10
  30. package/src/cli/build.ts +976 -978
  31. package/src/cli/create.ts +71 -63
  32. package/src/cli/dev.ts +116 -116
  33. package/src/cli/index.ts +88 -85
  34. package/src/cli/migrate/package-json.ts +73 -71
  35. package/src/cli/migrate/report.ts +32 -33
  36. package/src/cli/migrate/{index.ts → run.ts} +48 -49
  37. package/src/cli/migrate/scan.ts +46 -46
  38. package/src/cli/migrate/spinner.ts +9 -9
  39. package/src/cli/migrate/tsconfig.ts +35 -35
  40. package/src/cli/{server-entry.ts → serve/entry.ts} +57 -57
  41. package/src/cli/{request-pipeline.ts → serve/pipeline.ts} +386 -394
  42. package/src/cli/{serve-ui.ts → serve/ui.ts} +47 -47
  43. package/src/cli/start.ts +65 -66
  44. package/src/{typegen.ts → cli/typegen.ts} +59 -59
  45. package/src/client/build.ts +794 -768
  46. package/src/client/chunk-fold.ts +245 -240
  47. package/src/client/{paths.ts → chunk-name.ts} +6 -6
  48. package/src/client/entry.ts +162 -147
  49. package/src/client/prebuilt.ts +231 -223
  50. package/src/client/profile.ts +29 -29
  51. package/src/client/react-compiler.ts +20 -15
  52. package/src/client/{compat-surface.ts → react-tier.ts} +64 -64
  53. package/src/client/reference-stub.ts +51 -51
  54. package/src/client/reference.ts +19 -19
  55. package/src/{api → client}/router/events.ts +17 -17
  56. package/src/{api → client}/router/history.ts +16 -16
  57. package/src/{api → client}/router/hub.ts +52 -53
  58. package/src/{api/router.ts → client/router/index.ts} +61 -60
  59. package/src/{api → client}/router/policies.ts +24 -24
  60. package/src/{api → client}/router/runtime.ts +1988 -1992
  61. package/src/{api → client}/router/types.ts +93 -98
  62. package/src/compat/actions/client-plugin.ts +42 -43
  63. package/src/compat/actions/client-stub.ts +14 -14
  64. package/src/compat/actions/{action-client.ts → client.ts} +194 -193
  65. package/src/compat/actions/config.ts +63 -64
  66. package/src/compat/actions/detect.ts +68 -68
  67. package/src/compat/actions/discovery.ts +105 -105
  68. package/src/compat/actions/{action-dispatch.ts → dispatch.ts} +277 -274
  69. package/src/compat/actions/early-submit.ts +1 -1
  70. package/src/compat/actions/endpoint.ts +198 -198
  71. package/src/compat/actions/extensions.ts +811 -0
  72. package/src/compat/actions/flight.ts +23 -23
  73. package/src/compat/actions/form-state.ts +34 -34
  74. package/src/compat/actions/hoist.ts +382 -236
  75. package/src/compat/actions/ids.ts +7 -12
  76. package/src/compat/actions/index.ts +8 -8
  77. package/src/compat/actions/instances.ts +46 -46
  78. package/src/compat/actions/origin.ts +47 -48
  79. package/src/compat/actions/protocol.ts +22 -22
  80. package/src/compat/actions/registry.ts +19 -19
  81. package/src/compat/{misc/action-return.ts → actions/return.ts} +60 -57
  82. package/src/compat/actions/rewrite.ts +125 -125
  83. package/src/compat/actions/{action-router.ts → router.ts} +10 -10
  84. package/src/compat/actions/serve.ts +132 -136
  85. package/src/compat/actions/server-tag.ts +4 -4
  86. package/src/compat/actions/{action-shared.ts → shared.ts} +34 -34
  87. package/src/compat/actions/unrecognized-error.ts +4 -4
  88. package/src/compat/{index.ts → aliases.ts} +112 -109
  89. package/src/compat/bundler/bun-externals.ts +18 -18
  90. package/src/compat/bundler/cjs-exports.ts +271 -223
  91. package/src/compat/bundler/config.ts +116 -111
  92. package/src/compat/bundler/externals.ts +12 -12
  93. package/src/compat/bundler/import-meta-url.ts +19 -19
  94. package/src/compat/bundler/modularize-imports.ts +36 -33
  95. package/src/compat/bundler/new-url-asset.ts +22 -24
  96. package/src/compat/bundler/optimize-package-imports.ts +111 -107
  97. package/src/compat/bundler/polyfill.ts +28 -28
  98. package/src/compat/bundler/react-compiler.ts +35 -29
  99. package/src/compat/bundler/react-profiler.tsx +11 -11
  100. package/src/compat/bundler/relay-transform.ts +48 -47
  101. package/src/compat/bundler/require-context.ts +119 -113
  102. package/src/compat/bundler/resolve-extensions.ts +19 -19
  103. package/src/compat/bundler/source-cache.ts +25 -25
  104. package/src/compat/bundler/static-imports.ts +7 -7
  105. package/src/compat/bundler/symlink-imports.ts +46 -46
  106. package/src/compat/bundler/tsconfig-paths.ts +13 -15
  107. package/src/compat/bundler/wasm.ts +58 -60
  108. package/src/compat/bundler/webpack-loaders.ts +254 -241
  109. package/src/compat/bundler/worker.ts +101 -104
  110. package/src/compat/cache/build-flags.ts +29 -29
  111. package/src/compat/cache/build-prerender-errors.ts +40 -44
  112. package/src/compat/cache/custom-handler.ts +60 -53
  113. package/src/compat/cache/fetch-patch.ts +240 -240
  114. package/src/compat/cache/handler.ts +27 -31
  115. package/src/compat/cache/modern-handler.ts +148 -126
  116. package/src/compat/cache/resume-data-cache.ts +47 -45
  117. package/src/compat/cache/revalidate.ts +233 -232
  118. package/src/compat/cache/runtime-error.ts +35 -35
  119. package/src/compat/cache/use-cache-transform.ts +442 -417
  120. package/src/compat/cache/use-cache.ts +650 -614
  121. package/src/compat/cache-control.ts +140 -142
  122. package/src/compat/client/base-path.ts +21 -20
  123. package/src/compat/client/css-order.ts +18 -18
  124. package/src/compat/client/errors/bare-boundary.ts +11 -11
  125. package/src/compat/client/errors/control-flow.ts +23 -23
  126. package/src/compat/client/errors/error-boundary.ts +61 -61
  127. package/src/compat/client/errors/global-error.ts +101 -91
  128. package/src/compat/client/errors/install.ts +71 -72
  129. package/src/compat/client/errors/lazy.ts +23 -23
  130. package/src/compat/client/errors/primitive-throw.ts +47 -45
  131. package/src/compat/client/errors/soft-refresh.ts +4 -4
  132. package/src/compat/client/link-status.ts +33 -33
  133. package/src/compat/client/{nav-compat-runtime.ts → nav-runtime.ts} +20 -20
  134. package/src/compat/client/{nav-compat.ts → nav.ts} +12 -13
  135. package/src/compat/client/navigation-scroll.ts +63 -63
  136. package/src/compat/client/optimistic-routing.ts +93 -88
  137. package/src/compat/client/prefetch-cache.ts +23 -24
  138. package/src/compat/client/route-announcer.ts +35 -35
  139. package/src/compat/client/segment-cache-policy.ts +20 -20
  140. package/src/compat/client/segment-cache.ts +309 -315
  141. package/src/compat/client/segment-prefetch.ts +127 -132
  142. package/src/compat/client/trailing-slash.ts +5 -4
  143. package/src/compat/css/chunking.ts +113 -116
  144. package/src/compat/css/inline-css.ts +21 -21
  145. package/src/compat/css/lightningcss.ts +37 -38
  146. package/src/compat/css/modules.ts +161 -175
  147. package/src/compat/css/nonce.ts +7 -7
  148. package/src/compat/css/sass-plugin.ts +18 -21
  149. package/src/compat/css/sass.ts +150 -152
  150. package/src/compat/css/styled-jsx-runtime.ts +27 -27
  151. package/src/compat/css/styled-jsx.ts +21 -21
  152. package/src/compat/edge-runtime.ts +27 -27
  153. package/src/compat/{adapter → export}/build-complete.ts +72 -75
  154. package/src/compat/export/client.ts +29 -31
  155. package/src/compat/export/{index.ts → emit.ts} +111 -110
  156. package/src/compat/export/standalone.ts +62 -54
  157. package/src/compat/image-optimizer/cache.ts +51 -49
  158. package/src/compat/image-optimizer/detect.ts +52 -52
  159. package/src/compat/image-optimizer/{index.ts → optimize.ts} +189 -194
  160. package/src/compat/image-optimizer/source.ts +77 -80
  161. package/src/compat/lifecycle/after-scope.ts +26 -26
  162. package/src/compat/lifecycle/after.ts +48 -45
  163. package/src/compat/lifecycle/error-funnel.ts +98 -102
  164. package/src/compat/lifecycle/error-serialize.ts +30 -26
  165. package/src/compat/lifecycle/error-ui.ts +67 -32
  166. package/src/compat/lifecycle/instrumentation-client.ts +36 -38
  167. package/src/compat/lifecycle/instrumentation.ts +85 -85
  168. package/src/compat/lifecycle/node-console.ts +11 -11
  169. package/src/compat/lifecycle/testmode.ts +160 -132
  170. package/src/compat/mdx/compile.ts +60 -57
  171. package/src/compat/mdx/plugin.ts +11 -11
  172. package/src/compat/mdx/{next-mdx-stub.ts → stub.ts} +5 -5
  173. package/src/compat/{metadata-route-artifacts.ts → metadata-artifacts.ts} +195 -191
  174. package/src/compat/metadata.ts +75 -81
  175. package/src/compat/next/cache.ts +68 -69
  176. package/src/compat/next/canonical-url.ts +9 -9
  177. package/src/compat/next/client-cache.ts +19 -19
  178. package/src/compat/next/client-navigation.ts +112 -116
  179. package/src/compat/next/client-only.ts +1 -1
  180. package/src/compat/next/client-script.tsx +99 -93
  181. package/src/compat/next/client-server.ts +10 -10
  182. package/src/compat/next/config-loader.ts +176 -173
  183. package/src/compat/next/config.ts +7 -7
  184. package/src/compat/next/constants.cjs +6 -6
  185. package/src/compat/next/constants.ts +6 -6
  186. package/src/compat/next/custom-server.ts +26 -24
  187. package/src/compat/next/dist/client/components/app-router-headers.ts +21 -21
  188. package/src/compat/next/dist/server/app-render/work-unit-async-storage.external.cjs +3 -4
  189. package/src/compat/next/dist/server/web/spec-extension/revalidate.ts +1 -1
  190. package/src/compat/next/dist/server/web/spec-extension/unstable-cache.ts +1 -1
  191. package/src/compat/next/dist/server/web/spec-extension/unstable-no-store.ts +1 -1
  192. package/src/compat/next/dynamic.tsx +21 -18
  193. package/src/compat/next/error.tsx +52 -52
  194. package/src/compat/next/font/cache.ts +74 -74
  195. package/src/compat/next/font/google.ts +2 -2
  196. package/src/compat/next/font/index.ts +1 -1
  197. package/src/compat/next/font/local.ts +3 -3
  198. package/src/compat/next/font/runtime-client.ts +17 -15
  199. package/src/compat/next/font/runtime.ts +443 -408
  200. package/src/compat/next/font/shared.ts +120 -108
  201. package/src/compat/next/form.tsx +63 -63
  202. package/src/compat/next/head.tsx +2 -2
  203. package/src/compat/next/headers.ts +103 -95
  204. package/src/compat/next/image/client.tsx +220 -0
  205. package/src/compat/next/image/config.ts +56 -58
  206. package/src/compat/next/image/optimizer.ts +40 -36
  207. package/src/compat/next/image/patterns.ts +37 -40
  208. package/src/compat/next/{image-props.ts → image/props.ts} +208 -202
  209. package/src/compat/next/image/shared.ts +65 -57
  210. package/src/compat/next/image/static-metadata.ts +98 -107
  211. package/src/compat/next/image/validate.ts +79 -88
  212. package/src/compat/next/image.tsx +19 -23
  213. package/src/compat/next/index.ts +1 -1
  214. package/src/compat/next/legacy-image.tsx +59 -60
  215. package/src/compat/next/{link-validation-transform.ts → link-transform.ts} +95 -96
  216. package/src/compat/next/link.tsx +158 -158
  217. package/src/compat/next/navigation.cjs +12 -3
  218. package/src/compat/next/navigation.ts +48 -50
  219. package/src/compat/next/offline.ts +27 -27
  220. package/src/compat/next/og.ts +121 -124
  221. package/src/compat/next/preferred-region.ts +13 -14
  222. package/src/compat/next/redirects.ts +58 -56
  223. package/src/compat/next/resource-hints.ts +73 -76
  224. package/src/compat/next/rewrites.ts +130 -133
  225. package/src/compat/next/root-params.ts +45 -45
  226. package/src/compat/next/{optimistic-route-state.ts → route-state.ts} +52 -52
  227. package/src/compat/next/router.cjs +4 -2
  228. package/src/compat/next/router.ts +58 -61
  229. package/src/compat/next/script.tsx +108 -108
  230. package/src/compat/next/server-only.ts +1 -1
  231. package/src/compat/next/server.ts +19 -19
  232. package/src/compat/next/svgr.ts +18 -17
  233. package/src/compat/next/telemetry.ts +24 -24
  234. package/src/compat/next/{image-usage.ts → usage.ts} +70 -39
  235. package/src/compat/next/user-agent.ts +53 -49
  236. package/src/compat/next/web-vitals.ts +22 -24
  237. package/src/compat/otel/api.ts +41 -41
  238. package/src/compat/otel/client-trace-metadata.ts +25 -27
  239. package/src/compat/otel/fetch-span.ts +29 -29
  240. package/src/compat/otel/tracer.ts +331 -331
  241. package/src/compat/pages/api.ts +456 -0
  242. package/src/compat/pages/client-plugin.ts +36 -36
  243. package/src/compat/pages/router-state.ts +34 -34
  244. package/src/compat/pages/{index.ts → router.ts} +130 -135
  245. package/src/compat/ppr/io.ts +12 -12
  246. package/src/compat/ppr/missing-root-params.ts +34 -38
  247. package/src/compat/ppr/root-params-scan.ts +66 -66
  248. package/src/compat/ppr/root-params-transform.ts +24 -26
  249. package/src/compat/ppr/root-params.ts +30 -30
  250. package/src/compat/ppr/segment-config-incompat.ts +6 -7
  251. package/src/compat/protocol.ts +71 -70
  252. package/src/compat/react/action-state.ts +47 -48
  253. package/src/compat/react/client-lite.ts +15 -15
  254. package/src/compat/react/client.ts +4 -4
  255. package/src/compat/react/compiler-runtime.ts +11 -11
  256. package/src/compat/react/dom-client.ts +44 -44
  257. package/src/compat/react/dom-react-server.ts +10 -16
  258. package/src/compat/react/dom-server.ts +10 -10
  259. package/src/compat/react/dom.ts +52 -52
  260. package/src/compat/react/hooks-extra.ts +34 -35
  261. package/src/compat/react/parity.ts +64 -61
  262. package/src/compat/react/preact.ts +81 -82
  263. package/src/compat/react/react-server.ts +28 -28
  264. package/src/compat/react/router-shim.ts +1 -1
  265. package/src/compat/react/server-component-use.ts +8 -8
  266. package/src/compat/react/server-inserted-html.ts +30 -31
  267. package/src/compat/react/server.ts +53 -55
  268. package/src/compat/react/use.ts +32 -32
  269. package/src/compat/react/view-transition.ts +20 -20
  270. package/src/compat/register/actions.ts +35 -824
  271. package/src/compat/register/boot.ts +41 -41
  272. package/src/compat/register/build-tier.ts +5 -5
  273. package/src/compat/register/build.ts +74 -70
  274. package/src/compat/register/bundler.ts +161 -156
  275. package/src/compat/register/cache.ts +20 -20
  276. package/src/compat/register/client-errors.ts +3 -3
  277. package/src/compat/register/config.ts +6 -6
  278. package/src/compat/register/css-extras.ts +30 -34
  279. package/src/compat/register/edge-runtime.ts +3 -3
  280. package/src/compat/register/errors.ts +10 -12
  281. package/src/compat/register/export.ts +16 -16
  282. package/src/compat/register/font.ts +11 -11
  283. package/src/compat/register/hooks.ts +2 -2
  284. package/src/compat/register/image.ts +40 -40
  285. package/src/compat/register/index.ts +59 -62
  286. package/src/compat/register/instrumentation-client.ts +10 -10
  287. package/src/compat/register/lifecycle.ts +25 -28
  288. package/src/compat/register/mdx.ts +10 -10
  289. package/src/compat/register/middleware.ts +226 -16
  290. package/src/compat/register/otel.ts +80 -88
  291. package/src/compat/register/pages-api.ts +10 -463
  292. package/src/compat/register/ppr.ts +16 -16
  293. package/src/compat/register/protocol.ts +17 -18
  294. package/src/compat/register/proxy.ts +49 -51
  295. package/src/compat/register/render.ts +79 -76
  296. package/src/compat/register/routing.ts +162 -159
  297. package/src/compat/register/segment.ts +24 -1897
  298. package/src/compat/register/static-image.ts +3 -3
  299. package/src/compat/register/{misc.ts → taint.ts} +9 -9
  300. package/src/compat/register/typed-routes.ts +14 -14
  301. package/src/compat/register/{usecache.ts → use-cache.ts} +39 -39
  302. package/src/compat/register/validation.ts +18 -18
  303. package/src/compat/segment/loading-boundary.ts +43 -45
  304. package/src/compat/segment/page-slot.ts +69 -69
  305. package/src/compat/segment/serve.ts +1884 -0
  306. package/src/compat/segment/tree.ts +113 -112
  307. package/src/compat/segment/vary-key.ts +38 -38
  308. package/src/compat/segment/vary-params.ts +138 -142
  309. package/src/compat/static-params.ts +14 -12
  310. package/src/compat/tsconfig-defaults.ts +87 -91
  311. package/src/compat/typecheck/{index.ts → check.ts} +234 -212
  312. package/src/compat/typecheck/worker.ts +15 -12
  313. package/src/compat/typed-routes/{index.ts → generate.ts} +36 -36
  314. package/src/compat/typed-routes/manifest.ts +174 -170
  315. package/src/compat/typed-routes/typegen.ts +127 -110
  316. package/src/compat/validation/errors.ts +16 -19
  317. package/src/compat/validation/prerender-diagnostics.ts +521 -504
  318. package/src/compat/validation/{index.ts → validate.ts} +647 -648
  319. package/src/compat-bootstrap.ts +16 -16
  320. package/src/config.ts +69 -69
  321. package/src/css/build.ts +230 -227
  322. package/src/css/postcss.ts +79 -80
  323. package/src/css/worker.ts +14 -15
  324. package/src/dev/client-actions.ts +10 -10
  325. package/src/dev/client-chunk-store.ts +27 -27
  326. package/src/dev/{client-key-cache.ts → restart/client-key.ts} +76 -76
  327. package/src/dev/{restart-cache.ts → restart/enabled.ts} +1 -1
  328. package/src/dev/{global-css-cache.ts → restart/global-css.ts} +91 -83
  329. package/src/dev/{node-module-bundle-cache.ts → restart/node-modules.ts} +24 -24
  330. package/src/dev/{route-bundle-key-cache.ts → restart/route-bundle-key.ts} +53 -53
  331. package/src/dev/{route-facts-cache.ts → restart/route-facts.ts} +82 -82
  332. package/src/dev/server.ts +804 -820
  333. package/src/env.ts +46 -43
  334. package/src/extensions.ts +491 -478
  335. package/src/index.ts +8 -8
  336. package/src/internal.ts +20 -23
  337. package/src/{islands → render}/boundary-error.ts +3 -3
  338. package/src/render/hooks.ts +71 -71
  339. package/src/render/island-context.ts +14 -14
  340. package/src/render/metadata.ts +310 -310
  341. package/src/{ppr-postpone.ts → render/postpone.ts} +5 -5
  342. package/src/{ppr.ts → render/ppr.ts} +244 -245
  343. package/src/render/renderer.ts +2076 -2082
  344. package/src/render/resource-hints.ts +16 -17
  345. package/src/render/slots.tsx +224 -235
  346. package/src/{islands → render}/static-children.ts +9 -12
  347. package/src/{islands → render}/static-slots.ts +37 -37
  348. package/src/{cache/context.ts → request/cache.ts} +20 -20
  349. package/src/request/context.ts +107 -107
  350. package/src/{dynamic/source.ts → resolve/dynamic.ts} +139 -139
  351. package/src/resolve/engine.ts +90 -77
  352. package/src/resolve/imports.ts +475 -463
  353. package/src/resolve/scan-facts.ts +318 -296
  354. package/src/resolve/source-text.ts +37 -37
  355. package/src/{dynamic → resolve}/tree-shake.ts +132 -128
  356. package/src/routing/forwarded.ts +19 -19
  357. package/src/routing/handler.ts +84 -91
  358. package/src/routing/href.ts +69 -70
  359. package/src/routing/{metadata.ts → metadata-files.ts} +403 -401
  360. package/src/{proxy.ts → routing/proxy.ts} +306 -312
  361. package/src/routing/{request-runtime.ts → request-environment.ts} +10 -10
  362. package/src/routing/routes.ts +827 -815
  363. package/src/routing/slots.ts +164 -160
  364. package/src/runtime/loader.ts +952 -0
  365. package/src/{dev → runtime}/module-cache.ts +309 -287
  366. package/src/{dev → runtime}/module-generations.ts +9 -9
  367. package/src/{dev → runtime}/module-transform.ts +81 -72
  368. package/src/{dev/imports.ts → runtime/modules.ts} +934 -847
  369. package/src/runtime/{server.ts → vendor-build.ts} +848 -1696
  370. package/src/runtime/vendor.ts +425 -404
  371. package/src/styles.d.ts +9 -0
  372. package/src/types.ts +320 -335
  373. package/src/utils/ansi.ts +5 -5
  374. package/src/utils/{source.ts → code.ts} +15 -12
  375. package/src/utils/content-type.ts +3 -3
  376. package/src/utils/decode.ts +2 -2
  377. package/src/utils/dev-profile.ts +13 -13
  378. package/src/utils/error-log.ts +6 -6
  379. package/src/utils/esbuild.ts +18 -18
  380. package/src/utils/fs-cache.ts +13 -13
  381. package/src/utils/fs.ts +57 -49
  382. package/src/utils/html.ts +20 -24
  383. package/src/utils/native-require.ts +8 -8
  384. package/src/utils/serialize.ts +139 -146
  385. package/src/utils/verbose.ts +18 -18
  386. package/src/cli/analyze-print.ts +0 -181
  387. package/src/compat/middleware/manifest.ts +0 -210
  388. package/src/compat/next/image-client.tsx +0 -215
  389. package/src/compat/next/link-usage.ts +0 -29
  390. package/src/css/index.ts +0 -2
  391. package/src/render/index.ts +0 -1
  392. package/src/style-modules.d.ts +0 -9
@@ -7,18 +7,18 @@
7
7
  * they were revalidated; consumers compare against their stored-at time.
8
8
  */
9
9
 
10
- import { AsyncLocalStorage } from 'node:async_hooks';
11
- import { currentRequest, getWorkUnit } from '../../request/context';
12
- import { realNow, trackPrerenderCacheFill } from '../../ppr';
13
- import { cacheHandlerRevalidateTag } from './handler';
14
- import { modernCacheUpdateTags } from './modern-handler';
15
- import { escapeRegex } from '../../utils/source';
10
+ import { AsyncLocalStorage } from 'node:async_hooks'
11
+ import { currentRequest, getWorkUnit } from '../../request/context'
12
+ import { realNow, trackPrerenderCacheFill } from '../../render/ppr'
13
+ import { cacheHandlerRevalidateTag } from './handler'
14
+ import { modernCacheUpdateTags } from './modern-handler'
15
+ import { escapeRegex } from '../../utils/code'
16
16
  import {
17
17
  prerenderErrorCollectionActive,
18
18
  recordPrerenderError,
19
19
  unstableCacheDynamicApiMessage,
20
20
  useCacheDynamicApiMessage,
21
- } from './build-prerender-errors';
21
+ } from './build-prerender-errors'
22
22
 
23
23
  /**
24
24
  * Draft mode (a __prerender_bypass cookie on the active request) bypasses
@@ -26,7 +26,7 @@ import {
26
26
  * cached values untouched (Next semantics).
27
27
  */
28
28
  export function draftModeBypassActive() {
29
- return currentRequest()?.cookies?.has('__prerender_bypass') ?? false;
29
+ return currentRequest()?.cookies?.has('__prerender_bypass') ?? false
30
30
  }
31
31
 
32
32
  // Cross-instance singletons. The `'use cache'` transform pulls this module (and use-cache.ts) into the
@@ -35,22 +35,22 @@ export function draftModeBypassActive() {
35
35
  // module-level Map/counter/ALS - the producer scope a cached render enters would be invisible to the
36
36
  // runtime fetch patch, and a revalidatePath() written by one copy's registry would never be seen by the
37
37
  // other's staleness reader. Anchor all process-wide state on globalThis so both copies share it.
38
- const REVALIDATE_GLOBALS = Symbol.for('pnext.compat.revalidateGlobals');
39
- const USE_CACHE_ENTRIES = Symbol.for('pnext.compat.useCacheEntries');
38
+ const REVALIDATE_GLOBALS = Symbol.for('pnext.compat.revalidateGlobals')
39
+ const USE_CACHE_ENTRIES = Symbol.for('pnext.compat.useCacheEntries')
40
40
 
41
41
  function revalidateGlobal<T>(name: string, create: () => T): T {
42
- const root = globalThis as Record<PropertyKey, unknown>;
43
- const container = (root[REVALIDATE_GLOBALS] ??= {}) as Record<string, unknown>;
44
- if (!(name in container)) container[name] = create();
45
- return container[name] as T;
42
+ const root = globalThis as Record<PropertyKey, unknown>
43
+ const container = (root[REVALIDATE_GLOBALS] ??= {}) as Record<string, unknown>
44
+ if (!(name in container)) container[name] = create()
45
+ return container[name] as T
46
46
  }
47
47
 
48
- const revalidatedPaths = revalidateGlobal('revalidatedPaths', () => new Map<string, number>());
48
+ const revalidatedPaths = revalidateGlobal('revalidatedPaths', () => new Map<string, number>())
49
49
  const revalidatedPathReasons = revalidateGlobal(
50
50
  'revalidatedPathReasons',
51
51
  () => new Map<string, 'stale' | 'on-demand'>(),
52
- );
53
- const revalidatedTags = revalidateGlobal('revalidatedTags', () => new Map<string, number>());
52
+ )
53
+ const revalidatedTags = revalidateGlobal('revalidatedTags', () => new Map<string, number>())
54
54
  // Monotonic counters stamped/sampled across the module. Held on a shared object
55
55
  // (not module `let`s) so both module copies read and bump the same values:
56
56
  // - tagSeq: stamped on every hard tag revalidation. In-memory cache entries
@@ -64,40 +64,38 @@ const revalidatedTags = revalidateGlobal('revalidatedTags', () => new Map<string
64
64
  // - events: monotonic count of revalidation events (path or tag). Server
65
65
  // actions sample it before/after an action to decide whether the client's
66
66
  // view needs a refresh (Next invalidates its client router cache).
67
- const counters = revalidateGlobal('counters', () => ({ tagSeq: 0, lastPathAt: 0, events: 0 }));
68
- const revalidatedTagSeq = revalidateGlobal('revalidatedTagSeq', () => new Map<string, number>());
67
+ const counters = revalidateGlobal('counters', () => ({ tagSeq: 0, lastPathAt: 0, events: 0 }))
68
+ const revalidatedTagSeq = revalidateGlobal('revalidatedTagSeq', () => new Map<string, number>())
69
69
  const revalidatedTagReasons = revalidateGlobal(
70
70
  'revalidatedTagReasons',
71
71
  () => new Map<string, 'stale' | 'on-demand'>(),
72
- );
73
- const staleTags = revalidateGlobal('staleTags', () => new Map<string, number>());
74
- const dataCacheInvalidators = revalidateGlobal('dataCacheInvalidators', () => new Set<() => void>());
72
+ )
73
+ const staleTags = revalidateGlobal('staleTags', () => new Map<string, number>())
74
+ const dataCacheInvalidators = revalidateGlobal('dataCacheInvalidators', () => new Set<() => void>())
75
75
  export type RevalidationInvalidation =
76
- | { kind: 'path'; path: string }
77
- | { kind: 'tag'; tag: string; stale: boolean };
76
+ { kind: 'path'; path: string } | { kind: 'tag'; tag: string; stale: boolean }
78
77
 
79
78
  const revalidationInvalidators = revalidateGlobal(
80
79
  'revalidationInvalidators',
81
80
  () => new Set<(invalidation: RevalidationInvalidation) => void>(),
82
- );
81
+ )
83
82
 
84
83
  interface RevalidatableUseCacheEntry {
85
- tags: string[];
86
- route?: string;
87
- storedAt: number;
84
+ tags: string[]
85
+ route?: string
86
+ storedAt: number
88
87
  }
89
88
 
90
89
  function evictUseCacheEntries(invalidation: RevalidationInvalidation) {
91
90
  const entries = (globalThis as Record<PropertyKey, unknown>)[USE_CACHE_ENTRIES] as
92
- | Map<string, RevalidatableUseCacheEntry>
93
- | undefined;
94
- if (!entries || (invalidation.kind === 'tag' && invalidation.stale)) return;
91
+ Map<string, RevalidatableUseCacheEntry> | undefined
92
+ if (!entries || (invalidation.kind === 'tag' && invalidation.stale)) return
95
93
  for (const [key, entry] of entries) {
96
94
  const matches =
97
95
  invalidation.kind === 'tag'
98
96
  ? entry.tags.includes(invalidation.tag)
99
- : pathScopeRevalidated(entry.route, entry.storedAt);
100
- if (matches) entries.delete(key);
97
+ : pathScopeRevalidated(entry.route, entry.storedAt)
98
+ if (matches) entries.delete(key)
101
99
  }
102
100
  }
103
101
  // Pattern marks: revalidatePath('/x', 'layout') covers the whole subtree, and
@@ -105,11 +103,11 @@ function evictUseCacheEntries(invalidation: RevalidationInvalidation) {
105
103
  const revalidatedPatterns = revalidateGlobal(
106
104
  'revalidatedPatterns',
107
105
  () => [] as { regex: RegExp; at: number; reason: 'stale' | 'on-demand' }[],
108
- );
109
- const revalidatedPatternsLimit = 256;
106
+ )
107
+ const revalidatedPatternsLimit = 256
110
108
 
111
109
  export function revalidationEventCount() {
112
- return counters.events;
110
+ return counters.events
113
111
  }
114
112
 
115
113
  /**
@@ -119,66 +117,69 @@ export function revalidationEventCount() {
119
117
  * header, so bumping the counter is enough.
120
118
  */
121
119
  export function bumpRevalidationEvent() {
122
- counters.events += 1;
120
+ counters.events += 1
123
121
  }
124
122
 
125
123
  export function normalizeRevalidatePath(path: string) {
126
- let pathname = path.split('?')[0] ?? path;
124
+ let pathname = path.split('?')[0] ?? path
127
125
  try {
128
- pathname = decodeURI(pathname);
126
+ pathname = decodeURI(pathname)
129
127
  } catch {
130
128
  // Keep malformed escape sequences unchanged.
131
129
  }
132
- const trimmed = pathname.replace(/\/+$/, '');
133
- return trimmed === '' ? '/' : trimmed;
130
+ const trimmed = pathname.replace(/\/+$/, '')
131
+ return trimmed === '' ? '/' : trimmed
134
132
  }
135
133
 
136
134
  export function markPathRevalidated(path: string, type?: 'page' | 'layout') {
137
- counters.events += 1;
135
+ counters.events += 1
138
136
  // fetch/data cache entries carry the route they were produced under (Next's
139
137
  // implicit `_N_T_/route` soft tag). Revalidating a path only invalidates the
140
138
  // entries owned by matching routes (see pathScopeRevalidated); route-less
141
139
  // entries (produced outside a render) fall back to this global timestamp.
142
- counters.lastPathAt = Date.now();
143
- const normalized = normalizeRevalidatePath(path);
144
- void modernCacheUpdateTags([`_N_T_${normalized}`]);
145
- const reason = getWorkUnit()?.phase === 'action' ? 'stale' : 'on-demand';
140
+ counters.lastPathAt = Date.now()
141
+ const normalized = normalizeRevalidatePath(path)
142
+ void modernCacheUpdateTags([`_N_T_${normalized}`])
143
+ const reason = getWorkUnit()?.phase === 'action' ? 'stale' : 'on-demand'
146
144
  if (normalized.includes('[') || type === 'layout') {
147
145
  const source = normalized
148
146
  .split('/')
149
147
  .map(segment =>
150
- /^\[?\[\.\.\./.test(segment) ? '.+' : segment.startsWith('[') ? '[^/]+' : escapeRegex(segment),
148
+ /^\[?\[\.\.\./.test(segment)
149
+ ? '.+'
150
+ : segment.startsWith('[')
151
+ ? '[^/]+'
152
+ : escapeRegex(segment),
151
153
  )
152
- .join('/');
153
- const base = normalized === '/' ? '' : source;
154
- const regex =
155
- type === 'layout' ? new RegExp(`^${base}(?:/.*)?$`) : new RegExp(`^${source}$`);
156
- revalidatedPatterns.push({ regex, at: Date.now(), reason });
157
- if (revalidatedPatterns.length > revalidatedPatternsLimit) revalidatedPatterns.shift();
158
- const invalidation = { kind: 'path', path: normalized } as const;
159
- evictUseCacheEntries(invalidation);
160
- notifyRevalidationInvalidators(invalidation);
161
- return;
154
+ .join('/')
155
+ const base = normalized === '/' ? '' : source
156
+ const regex = type === 'layout' ? new RegExp(`^${base}(?:/.*)?$`) : new RegExp(`^${source}$`)
157
+ revalidatedPatterns.push({ regex, at: Date.now(), reason })
158
+ if (revalidatedPatterns.length > revalidatedPatternsLimit) revalidatedPatterns.shift()
159
+ const invalidation = { kind: 'path', path: normalized } as const
160
+ evictUseCacheEntries(invalidation)
161
+ notifyRevalidationInvalidators(invalidation)
162
+ return
162
163
  }
163
- revalidatedPaths.set(normalized, Date.now());
164
- revalidatedPathReasons.set(normalized, reason);
165
- const invalidation = { kind: 'path', path: normalized } as const;
166
- evictUseCacheEntries(invalidation);
167
- notifyRevalidationInvalidators(invalidation);
164
+ revalidatedPaths.set(normalized, Date.now())
165
+ revalidatedPathReasons.set(normalized, reason)
166
+ const invalidation = { kind: 'path', path: normalized } as const
167
+ evictUseCacheEntries(invalidation)
168
+ notifyRevalidationInvalidators(invalidation)
168
169
  }
169
170
 
170
171
  export function markTagRevalidated(tag: string) {
171
- counters.events += 1;
172
- revalidatedTags.set(tag, Date.now());
173
- revalidatedTagSeq.set(tag, ++counters.tagSeq);
174
- revalidatedTagReasons.set(tag, getWorkUnit()?.phase === 'action' ? 'stale' : 'on-demand');
172
+ counters.events += 1
173
+ revalidatedTags.set(tag, Date.now())
174
+ revalidatedTagSeq.set(tag, ++counters.tagSeq)
175
+ revalidatedTagReasons.set(tag, getWorkUnit()?.phase === 'action' ? 'stale' : 'on-demand')
175
176
  // Forward to a configured cache handler so a persistent backend drops the
176
177
  // entry too (best-effort; the in-memory marks are authoritative).
177
- void cacheHandlerRevalidateTag(tag);
178
- void modernCacheUpdateTags([tag]);
179
- const invalidation = { kind: 'tag', tag, stale: false } as const;
180
- evictUseCacheEntries(invalidation);
181
- notifyRevalidationInvalidators(invalidation);
178
+ void cacheHandlerRevalidateTag(tag)
179
+ void modernCacheUpdateTags([tag])
180
+ const invalidation = { kind: 'tag', tag, stale: false } as const
181
+ evictUseCacheEntries(invalidation)
182
+ notifyRevalidationInvalidators(invalidation)
182
183
  }
183
184
 
184
185
  export function markTagStale(tag: string) {
@@ -186,38 +187,38 @@ export function markTagStale(tag: string) {
186
187
  // stale-while-revalidate - the client keeps showing its current (stale) view and must NOT be told to
187
188
  // refresh after the action. Fresh data appears only on the next navigation/refresh, which serves stale
188
189
  // and regenerates in the background.
189
- staleTags.set(tag, Date.now());
190
- void cacheHandlerRevalidateTag(tag);
191
- void modernCacheUpdateTags([tag]);
192
- notifyRevalidationInvalidators({ kind: 'tag', tag, stale: true });
190
+ staleTags.set(tag, Date.now())
191
+ void cacheHandlerRevalidateTag(tag)
192
+ void modernCacheUpdateTags([tag])
193
+ notifyRevalidationInvalidators({ kind: 'tag', tag, stale: true })
193
194
  }
194
195
 
195
196
  // Marks are integer Date.now() while file mtimes carry fractional
196
197
  // milliseconds; truncate so a mark landing in the same millisecond as the
197
198
  // write still counts as newer (worst case: one redundant regeneration).
198
199
  function markedAfter(at: number | undefined, time: number) {
199
- return at !== undefined && at >= Math.trunc(time) && at > time - 1;
200
+ return at !== undefined && at >= Math.trunc(time) && at > time - 1
200
201
  }
201
202
 
202
203
  export function pathRevalidatedSince(path: string, time: number) {
203
- const normalized = normalizeRevalidatePath(path);
204
- if (markedAfter(revalidatedPaths.get(normalized), time)) return true;
204
+ const normalized = normalizeRevalidatePath(path)
205
+ if (markedAfter(revalidatedPaths.get(normalized), time)) return true
205
206
  return revalidatedPatterns.some(
206
207
  pattern => markedAfter(pattern.at, time) && pattern.regex.test(normalized),
207
- );
208
+ )
208
209
  }
209
210
 
210
211
  export function pathRevalidationReasonSince(
211
212
  path: string,
212
213
  time: number,
213
214
  ): 'stale' | 'on-demand' | undefined {
214
- const normalized = normalizeRevalidatePath(path);
215
+ const normalized = normalizeRevalidatePath(path)
215
216
  if (markedAfter(revalidatedPaths.get(normalized), time)) {
216
- return revalidatedPathReasons.get(normalized) ?? 'on-demand';
217
+ return revalidatedPathReasons.get(normalized) ?? 'on-demand'
217
218
  }
218
219
  return revalidatedPatterns.find(
219
220
  pattern => markedAfter(pattern.at, time) && pattern.regex.test(normalized),
220
- )?.reason;
221
+ )?.reason
221
222
  }
222
223
 
223
224
  /**
@@ -228,17 +229,17 @@ export function pathRevalidationReasonSince(
228
229
  * entries are invalidated by any path revalidation.
229
230
  */
230
231
  export function pathScopeRevalidated(route: string | undefined, time: number): boolean {
231
- if (route === undefined) return markedAfter(counters.lastPathAt || undefined, time);
232
- return pathRevalidatedSince(route, time);
232
+ if (route === undefined) return markedAfter(counters.lastPathAt || undefined, time)
233
+ return pathRevalidatedSince(route, time)
233
234
  }
234
235
 
235
236
  export function tagsRevalidatedSince(tags: readonly string[], time: number) {
236
- return tags.some(tag => markedAfter(revalidatedTags.get(tag), time));
237
+ return tags.some(tag => markedAfter(revalidatedTags.get(tag), time))
237
238
  }
238
239
 
239
240
  /** Current hard-tag-revalidation sequence, stamped on an entry at production. */
240
241
  export function currentTagRevalidationSeq() {
241
- return counters.tagSeq;
242
+ return counters.tagSeq
242
243
  }
243
244
 
244
245
  /**
@@ -250,7 +251,7 @@ export function rdcProcessId(): string {
250
251
  return revalidateGlobal(
251
252
  'rdcProcessId',
252
253
  () => `${process.pid}:${Date.now()}:${Math.random().toString(36).slice(2)}`,
253
- );
254
+ )
254
255
  }
255
256
 
256
257
  /**
@@ -267,8 +268,8 @@ export function rdcProcessId(): string {
267
268
  * reset), so a shell regenerated right after a revalidation is not immediately re-invalidated by it.
268
269
  */
269
270
  export function rebaseRdcTagSeq(record: { tagSeq: number; pid?: string }): number {
270
- if (record.pid !== rdcProcessId()) return 0;
271
- return Math.min(record.tagSeq, counters.tagSeq);
271
+ if (record.pid !== rdcProcessId()) return 0
272
+ return Math.min(record.tagSeq, counters.tagSeq)
272
273
  }
273
274
 
274
275
  /**
@@ -279,7 +280,7 @@ export function rebaseRdcTagSeq(record: { tagSeq: number; pid?: string }): numbe
279
280
  * request reliably see the invalidation exactly once.
280
281
  */
281
282
  export function tagsRevalidatedAfterSeq(tags: readonly string[], seq: number) {
282
- return tags.some(tag => (revalidatedTagSeq.get(tag) ?? 0) > seq);
283
+ return tags.some(tag => (revalidatedTagSeq.get(tag) ?? 0) > seq)
283
284
  }
284
285
 
285
286
  export function tagsRevalidationReasonSince(
@@ -288,46 +289,46 @@ export function tagsRevalidationReasonSince(
288
289
  ): 'stale' | 'on-demand' | undefined {
289
290
  for (const tag of tags) {
290
291
  if (markedAfter(revalidatedTags.get(tag), time)) {
291
- return revalidatedTagReasons.get(tag) ?? 'on-demand';
292
+ return revalidatedTagReasons.get(tag) ?? 'on-demand'
292
293
  }
293
294
  }
294
- return undefined;
295
+ return undefined
295
296
  }
296
297
 
297
298
  export function tagsStaleSince(tags: readonly string[], time: number) {
298
- return tags.some(tag => markedAfter(staleTags.get(tag), time));
299
+ return tags.some(tag => markedAfter(staleTags.get(tag), time))
299
300
  }
300
301
 
301
302
  interface DataCacheEntry {
302
- value: Promise<unknown>;
303
- storedAt: number;
304
- tags: readonly string[];
305
- revalidateSeconds?: number;
303
+ value: Promise<unknown>
304
+ storedAt: number
305
+ tags: readonly string[]
306
+ revalidateSeconds?: number
306
307
  /** A background stale-while-revalidate refresh is already in flight. */
307
- refreshing?: boolean;
308
+ refreshing?: boolean
308
309
  /** Pathname of the render that produced this entry (path-revalidation scope). */
309
- route?: string;
310
+ route?: string
310
311
  /**
311
312
  * The render cache-meta this entry was produced under: an on-demand
312
313
  * regeneration (refreshFetches) re-produces each entry once per render, then
313
314
  * repeated reads dedupe against it.
314
315
  */
315
- refreshedIn?: object;
316
+ refreshedIn?: object
316
317
  }
317
318
 
318
- const dataCache = revalidateGlobal('dataCache', () => new Map<string, DataCacheEntry>());
319
- const dataCacheLimit = 1024;
319
+ const dataCache = revalidateGlobal('dataCache', () => new Map<string, DataCacheEntry>())
320
+ const dataCacheLimit = 1024
320
321
 
321
322
  function dataCacheEntryExpired(entry: DataCacheEntry) {
322
323
  return (
323
324
  entry.revalidateSeconds !== undefined &&
324
325
  realNow() - entry.storedAt >= entry.revalidateSeconds * 1000
325
- );
326
+ )
326
327
  }
327
328
 
328
329
  export interface DataCacheOptions {
329
- tags?: string[];
330
- revalidateSeconds?: number;
330
+ tags?: string[]
331
+ revalidateSeconds?: number
331
332
  }
332
333
 
333
334
  /**
@@ -342,9 +343,9 @@ export function cachedData(
342
343
  produce: () => Promise<unknown>,
343
344
  options: DataCacheOptions = {},
344
345
  ): Promise<unknown> {
345
- if (draftModeBypassActive()) return produce();
346
- const entry = dataCache.get(key);
347
- const meta = cacheMetaStorage.getStore();
346
+ if (draftModeBypassActive()) return produce()
347
+ const entry = dataCache.get(key)
348
+ const meta = cacheMetaStorage.getStore()
348
349
  // On-demand revalidation re-produces each entry ONCE per render (Next skips the cache read entirely
349
350
  // under isOnDemandRevalidate), then dedupes via refreshedIn - but only entries the revalidation
350
351
  // actually reached. See the matching gate in use-cache.ts: a still-marked route re-renders many times
@@ -356,29 +357,29 @@ export function cachedData(
356
357
  (tagsRevalidatedSince(entry.tags, entry.storedAt) ||
357
358
  pathScopeRevalidated(entry.route, entry.storedAt) ||
358
359
  tagsStaleSince(entry.tags, entry.storedAt) ||
359
- dataCacheEntryExpired(entry));
360
+ dataCacheEntryExpired(entry))
360
361
  if (
361
362
  entry &&
362
363
  !refresh &&
363
364
  !tagsRevalidatedSince(entry.tags, entry.storedAt) &&
364
365
  !pathScopeRevalidated(entry.route, entry.storedAt)
365
366
  ) {
366
- recordCacheTags(entry.tags);
367
+ recordCacheTags(entry.tags)
367
368
  if (entry.revalidateSeconds !== undefined) {
368
- recordCacheRevalidate(entry.revalidateSeconds);
369
+ recordCacheRevalidate(entry.revalidateSeconds)
369
370
  }
370
- const tagStale = tagsStaleSince(entry.tags, entry.storedAt);
371
- if (!tagStale && !dataCacheEntryExpired(entry)) return entry.value;
371
+ const tagStale = tagsStaleSince(entry.tags, entry.storedAt)
372
+ if (!tagStale && !dataCacheEntryExpired(entry)) return entry.value
372
373
  // ISR regeneration renders refetch expired entries inline.
373
374
  if (cacheMetaStorage.getStore()?.blockingStaleFetches !== true) {
374
375
  if (!entry.refreshing) {
375
- entry.refreshing = true;
376
- void storeDataCacheEntry(key, produce, options, entry);
376
+ entry.refreshing = true
377
+ void storeDataCacheEntry(key, produce, options, entry)
377
378
  }
378
- return entry.value;
379
+ return entry.value
379
380
  }
380
381
  }
381
- return storeDataCacheEntry(key, produce, options);
382
+ return storeDataCacheEntry(key, produce, options)
382
383
  }
383
384
 
384
385
  function storeDataCacheEntry(
@@ -390,16 +391,14 @@ function storeDataCacheEntry(
390
391
  // Collect the tags of fetches/nested caches produced inside this entry so it
391
392
  // inherits them (revalidateTag can then invalidate it), and propagate the
392
393
  // aggregate up to an enclosing producer once settled.
393
- const parentProducerTags = producerTagsStorage.getStore();
394
- const producerTags = new Set<string>(options.tags ?? []);
395
- const value = producerTagsStorage.run(producerTags, () =>
396
- runInsideUnstableCacheProducer(produce),
397
- );
394
+ const parentProducerTags = producerTagsStorage.getStore()
395
+ const producerTags = new Set<string>(options.tags ?? [])
396
+ const value = producerTagsStorage.run(producerTags, () => runInsideUnstableCacheProducer(produce))
398
397
  // Same contract as the 'use cache' fill: a build prerender's task boundary
399
398
  // waits for an in-flight data-cache fill rather than cutting it short, so
400
399
  // cached IO still lands in the static shell (core ppr).
401
- void trackPrerenderCacheFill(value);
402
- const producingMeta = cacheMetaStorage.getStore();
400
+ void trackPrerenderCacheFill(value)
401
+ const producingMeta = cacheMetaStorage.getStore()
403
402
  const stored: DataCacheEntry = {
404
403
  value,
405
404
  storedAt: realNow(),
@@ -411,68 +410,68 @@ function storeDataCacheEntry(
411
410
  : producingMeta?.route !== undefined
412
411
  ? { route: producingMeta.route }
413
412
  : {}),
414
- };
413
+ }
415
414
  const applyInheritedTags = () => {
416
- stored.tags = [...producerTags];
417
- if (parentProducerTags) for (const tag of producerTags) parentProducerTags.add(tag);
418
- };
415
+ stored.tags = [...producerTags]
416
+ if (parentProducerTags) for (const tag of producerTags) parentProducerTags.add(tag)
417
+ }
419
418
  if (serveStale) {
420
419
  // Background refresh: only replace the stale entry once the new value
421
420
  // settles, so concurrent readers keep getting the stale value instantly.
422
421
  value.then(
423
422
  () => {
424
- applyInheritedTags();
425
- dataCache.set(key, stored);
423
+ applyInheritedTags()
424
+ dataCache.set(key, stored)
426
425
  },
427
426
  () => {
428
- serveStale.refreshing = false;
427
+ serveStale.refreshing = false
429
428
  },
430
- );
431
- return value;
429
+ )
430
+ return value
432
431
  }
433
432
  if (dataCache.size >= dataCacheLimit) {
434
- const oldest = dataCache.keys().next().value;
435
- if (oldest !== undefined) dataCache.delete(oldest);
433
+ const oldest = dataCache.keys().next().value
434
+ if (oldest !== undefined) dataCache.delete(oldest)
436
435
  }
437
- dataCache.set(key, stored);
436
+ dataCache.set(key, stored)
438
437
  value.then(applyInheritedTags, () => {
439
- if (dataCache.get(key)?.value === value) dataCache.delete(key);
440
- });
441
- return value;
438
+ if (dataCache.get(key)?.value === value) dataCache.delete(key)
439
+ })
440
+ return value
442
441
  }
443
442
 
444
443
  export function clearRevalidationState() {
445
- revalidatedPaths.clear();
446
- revalidatedPathReasons.clear();
447
- revalidatedTags.clear();
448
- revalidatedTagSeq.clear();
449
- counters.tagSeq = 0;
450
- revalidatedTagReasons.clear();
451
- staleTags.clear();
452
- revalidatedPatterns.length = 0;
453
- counters.lastPathAt = 0;
454
- dataCache.clear();
455
- for (const invalidate of dataCacheInvalidators) invalidate();
444
+ revalidatedPaths.clear()
445
+ revalidatedPathReasons.clear()
446
+ revalidatedTags.clear()
447
+ revalidatedTagSeq.clear()
448
+ counters.tagSeq = 0
449
+ revalidatedTagReasons.clear()
450
+ staleTags.clear()
451
+ revalidatedPatterns.length = 0
452
+ counters.lastPathAt = 0
453
+ dataCache.clear()
454
+ for (const invalidate of dataCacheInvalidators) invalidate()
456
455
  }
457
456
 
458
457
  export function registerDataCacheInvalidator(invalidate: () => void): () => void {
459
- dataCacheInvalidators.add(invalidate);
458
+ dataCacheInvalidators.add(invalidate)
460
459
  return () => {
461
- dataCacheInvalidators.delete(invalidate);
462
- };
460
+ dataCacheInvalidators.delete(invalidate)
461
+ }
463
462
  }
464
463
 
465
464
  export function registerRevalidationInvalidator(
466
465
  invalidate: (invalidation: RevalidationInvalidation) => void,
467
466
  ): () => void {
468
- revalidationInvalidators.add(invalidate);
467
+ revalidationInvalidators.add(invalidate)
469
468
  return () => {
470
- revalidationInvalidators.delete(invalidate);
471
- };
469
+ revalidationInvalidators.delete(invalidate)
470
+ }
472
471
  }
473
472
 
474
473
  function notifyRevalidationInvalidators(invalidation: RevalidationInvalidation) {
475
- for (const invalidate of revalidationInvalidators) invalidate(invalidation);
474
+ for (const invalidate of revalidationInvalidators) invalidate(invalidation)
476
475
  }
477
476
 
478
477
  /**
@@ -482,8 +481,8 @@ function notifyRevalidationInvalidators(invalidation: RevalidationInvalidation)
482
481
  * the route's `fetchCache` segment config for cache-mode defaults.
483
482
  */
484
483
  export interface RenderCacheMeta {
485
- tags: Set<string>;
486
- revalidateSeconds?: number;
484
+ tags: Set<string>
485
+ revalidateSeconds?: number
487
486
  /**
488
487
  * Effective `use cache` cacheLife expire/stale windows aggregated across the
489
488
  * render's cache scopes (min of each). Recorded alongside revalidateSeconds so
@@ -491,56 +490,56 @@ export interface RenderCacheMeta {
491
490
  * x-nextjs-stale-time even when the work-unit stash (used by the live-render
492
491
  * response finalizer) is not in scope during the async cache propagation.
493
492
  */
494
- expireSeconds?: number;
495
- staleSeconds?: number;
496
- fetchCache?: string;
493
+ expireSeconds?: number
494
+ staleSeconds?: number
495
+ fetchCache?: string
497
496
  /** Route path label for error messages (e.g. invalid fetch revalidate). */
498
- route?: string;
497
+ route?: string
499
498
  /** On-demand revalidation render: data caches must refetch and overwrite. */
500
- refreshFetches?: boolean;
499
+ refreshFetches?: boolean
501
500
  /**
502
501
  * ISR regeneration render: TTL-expired data-cache entries refetch inline
503
502
  * (blocking) instead of serving stale, so the regenerated page carries
504
503
  * fresh data instead of lagging one generation behind.
505
504
  */
506
- blockingStaleFetches?: boolean;
505
+ blockingStaleFetches?: boolean
507
506
  /**
508
507
  * The render used an explicit no-store signal (fetch cache:'no-store'/
509
508
  * 'no-cache', next.revalidate 0, or unstable_noStore()): the route must not
510
509
  * be served from prebuilt output.
511
510
  */
512
- noStore?: boolean;
511
+ noStore?: boolean
513
512
  /**
514
513
  * Static-generation render (build prerender or ISR regeneration): a plain
515
514
  * fetch with no explicit cache option defaults to caching (Next's
516
515
  * force-cache-during-static-generation semantics) instead of per-request.
517
516
  */
518
- prerender?: boolean;
517
+ prerender?: boolean
519
518
  /**
520
519
  * True when the surrounding render is a route handler. Route handlers are
521
520
  * dynamic by default (Next): an explicitly-uncached fetch (cache:'default')
522
521
  * opts the handler out of prebuilt static output, whereas a page with the
523
522
  * same fetch simply freezes at prerender time.
524
523
  */
525
- handler?: boolean;
524
+ handler?: boolean
526
525
  /** True when `dynamic = 'error'` must reject request API access. */
527
- dynamicError?: boolean;
526
+ dynamicError?: boolean
528
527
  /**
529
528
  * after() work queued during a static-generation render. There is no response close to flush against,
530
529
  * so the render itself drains the queue once `produce` settles - Next's semantics: a build prerender
531
530
  * waits for after() callbacks, and a rejection fails that page's prerender. Compat's after() enqueues;
532
531
  * nothing in the cache layer knows what the tasks are.
533
532
  */
534
- afterTasks?: (() => Promise<void>)[];
533
+ afterTasks?: (() => Promise<void>)[]
535
534
  }
536
535
 
537
536
  const cacheMetaStorage = revalidateGlobal(
538
537
  'cacheMetaStorage',
539
538
  () => new AsyncLocalStorage<RenderCacheMeta>(),
540
- );
539
+ )
541
540
 
542
541
  export function currentRenderCacheMeta() {
543
- return cacheMetaStorage.getStore();
542
+ return cacheMetaStorage.getStore()
544
543
  }
545
544
 
546
545
  /**
@@ -549,19 +548,19 @@ export function currentRenderCacheMeta() {
549
548
  * static-generation force-cache default.
550
549
  */
551
550
  export function currentRenderIsStaticGeneration(): boolean {
552
- const meta = cacheMetaStorage.getStore();
553
- return meta?.prerender === true || meta?.blockingStaleFetches === true;
551
+ const meta = cacheMetaStorage.getStore()
552
+ return meta?.prerender === true || meta?.blockingStaleFetches === true
554
553
  }
555
554
 
556
555
  export function recordCacheTags(tags: readonly string[]) {
557
556
  // Inside an unstable_cache producer, inner fetch/cache tags are inherited by
558
557
  // the producing entry (Next semantics: an unstable_cache boundary collects the
559
558
  // tags of every fetch made inside it, so revalidateTag invalidates the entry).
560
- const producerTags = producerTagsStorage.getStore();
561
- if (producerTags) for (const tag of tags) producerTags.add(tag);
562
- const meta = cacheMetaStorage.getStore();
563
- if (!meta) return;
564
- for (const tag of tags) meta.tags.add(tag);
559
+ const producerTags = producerTagsStorage.getStore()
560
+ if (producerTags) for (const tag of tags) producerTags.add(tag)
561
+ const meta = cacheMetaStorage.getStore()
562
+ if (!meta) return
563
+ for (const tag of tags) meta.tags.add(tag)
565
564
  }
566
565
 
567
566
  // Hook into the active `use cache` producer scope (registered by use-cache.ts;
@@ -572,58 +571,58 @@ export function recordCacheTags(tags: readonly string[]) {
572
571
  // just the surrounding route.
573
572
  const useCacheRevalidateSink = revalidateGlobal('useCacheRevalidateSink', () => ({
574
573
  current: undefined as ((seconds: number) => void) | undefined,
575
- }));
574
+ }))
576
575
 
577
576
  export function setUseCacheRevalidateSink(sink: (seconds: number) => void) {
578
- useCacheRevalidateSink.current = sink;
577
+ useCacheRevalidateSink.current = sink
579
578
  }
580
579
 
581
580
  export function recordCacheRevalidate(seconds: number) {
582
- useCacheRevalidateSink.current?.(seconds);
583
- const meta = cacheMetaStorage.getStore();
584
- if (!meta) return;
581
+ useCacheRevalidateSink.current?.(seconds)
582
+ const meta = cacheMetaStorage.getStore()
583
+ if (!meta) return
585
584
  meta.revalidateSeconds =
586
- meta.revalidateSeconds === undefined ? seconds : Math.min(meta.revalidateSeconds, seconds);
585
+ meta.revalidateSeconds === undefined ? seconds : Math.min(meta.revalidateSeconds, seconds)
587
586
  }
588
587
 
589
588
  /** Record a `use cache` entry's expire window on the render meta (min-combined). */
590
589
  export function recordCacheExpire(seconds: number) {
591
- const meta = cacheMetaStorage.getStore();
592
- if (!meta) return;
590
+ const meta = cacheMetaStorage.getStore()
591
+ if (!meta) return
593
592
  meta.expireSeconds =
594
- meta.expireSeconds === undefined ? seconds : Math.min(meta.expireSeconds, seconds);
593
+ meta.expireSeconds === undefined ? seconds : Math.min(meta.expireSeconds, seconds)
595
594
  }
596
595
 
597
596
  /** Record a `use cache` entry's stale window on the render meta (min-combined). */
598
597
  export function recordCacheStale(seconds: number) {
599
- const meta = cacheMetaStorage.getStore();
600
- if (!meta) return;
598
+ const meta = cacheMetaStorage.getStore()
599
+ if (!meta) return
601
600
  meta.staleSeconds =
602
- meta.staleSeconds === undefined ? seconds : Math.min(meta.staleSeconds, seconds);
601
+ meta.staleSeconds === undefined ? seconds : Math.min(meta.staleSeconds, seconds)
603
602
  }
604
603
 
605
604
  export function recordCacheNoStore() {
606
605
  // Inside a data-cache producer (unstable_cache / 'use cache') the cache
607
606
  // boundary wins: no-store signals do not leak out to the route.
608
- if (insideProducerStorage.getStore()) return;
609
- const meta = cacheMetaStorage.getStore();
610
- if (meta) meta.noStore = true;
607
+ if (insideProducerStorage.getStore()) return
608
+ const meta = cacheMetaStorage.getStore()
609
+ if (meta) meta.noStore = true
611
610
  }
612
611
 
613
612
  const insideProducerStorage = revalidateGlobal(
614
613
  'insideProducerStorage',
615
614
  () => new AsyncLocalStorage<boolean>(),
616
- );
615
+ )
617
616
  const producerKindStorage = revalidateGlobal(
618
617
  'producerKindStorage',
619
618
  () => new AsyncLocalStorage<'use-cache' | 'unstable-cache'>(),
620
- );
619
+ )
621
620
  // Tags accumulated by fetches/nested caches inside the currently-producing
622
621
  // unstable_cache entry (see recordCacheTags / storeDataCacheEntry).
623
622
  const producerTagsStorage = revalidateGlobal(
624
623
  'producerTagsStorage',
625
624
  () => new AsyncLocalStorage<Set<string>>(),
626
- );
625
+ )
627
626
  // A dedicated marker for `unstable_cache` specifically (a subset of the general
628
627
  // data-cache-producer scope, which `use cache` also enters). Root params read
629
628
  // inside a `use cache` NESTED within an `unstable_cache` are E1140, which needs
@@ -631,40 +630,42 @@ const producerTagsStorage = revalidateGlobal(
631
630
  const insideUnstableCacheStorage = revalidateGlobal(
632
631
  'insideUnstableCacheStorage',
633
632
  () => new AsyncLocalStorage<boolean>(),
634
- );
633
+ )
635
634
 
636
635
  /** Mark fn as running inside a data-cache producer (see recordCacheNoStore). */
637
636
  export function runInsideDataCacheProducer<T>(
638
637
  fn: () => T,
639
638
  kind: 'use-cache' | 'unstable-cache' = 'use-cache',
640
639
  ): T {
641
- return producerKindStorage.run(kind, () => insideProducerStorage.run(true, fn));
640
+ return producerKindStorage.run(kind, () => insideProducerStorage.run(true, fn))
642
641
  }
643
642
 
644
643
  /** Mark fn as running specifically inside an `unstable_cache` producer. */
645
644
  export function runInsideUnstableCacheProducer<T>(fn: () => T): T {
646
- return insideUnstableCacheStorage.run(true, () => runInsideDataCacheProducer(fn, 'unstable-cache'));
645
+ return insideUnstableCacheStorage.run(true, () =>
646
+ runInsideDataCacheProducer(fn, 'unstable-cache'),
647
+ )
647
648
  }
648
649
 
649
650
  /** True while executing inside an unstable_cache / 'use cache' producer. */
650
651
  export function insideDataCacheProducer(): boolean {
651
- return insideProducerStorage.getStore() === true;
652
+ return insideProducerStorage.getStore() === true
652
653
  }
653
654
 
654
655
  /** True while executing specifically inside an `unstable_cache` producer. */
655
656
  export function insideUnstableCacheProducer(): boolean {
656
- return insideUnstableCacheStorage.getStore() === true;
657
+ return insideUnstableCacheStorage.getStore() === true
657
658
  }
658
659
 
659
660
  export function insidePublicUseCacheProducer(): boolean {
660
- return producerKindStorage.getStore() === 'use-cache';
661
+ return producerKindStorage.getStore() === 'use-cache'
661
662
  }
662
663
 
663
664
  /**
664
665
  * Fail a build prerender when a dynamic request API (`cookies()`/`headers()`/
665
666
  * `connection()`) is invoked inside a function cached with `unstable_cache()`.
666
667
  * Called from the compat request-API seams (next/headers, next/server). Records
667
- * Next's exact E838 error so the build aborts (register-usecache) and throws so
668
+ * Next's exact E838 error so the build aborts (register/use-cache) and throws so
668
669
  * the offending fill unwinds. A no-op outside an armed build prerender and
669
670
  * outside an unstable_cache producer, so serving-runtime/dev calls are untouched
670
671
  * (there, the same APIs simply read live request data).
@@ -672,12 +673,12 @@ export function insidePublicUseCacheProducer(): boolean {
672
673
  export function assertNoDynamicApiInsideCache(
673
674
  api: 'cookies()' | 'headers()' | 'connection()',
674
675
  ): void {
675
- if (!insideDataCacheProducer()) return;
676
- const route = cacheMetaStorage.getStore()?.route ?? '';
677
- const unstable = insideUnstableCacheProducer();
676
+ if (!insideDataCacheProducer()) return
677
+ const route = cacheMetaStorage.getStore()?.route ?? ''
678
+ const unstable = insideUnstableCacheProducer()
678
679
  const message = unstable
679
680
  ? unstableCacheDynamicApiMessage(route, api)
680
- : useCacheDynamicApiMessage(route, api);
681
+ : useCacheDynamicApiMessage(route, api)
681
682
  // Build-time prerenders record the error for the build log; the throw itself
682
683
  // is unconditional — Next rejects dynamic data inside a cache scope at
683
684
  // request time too (500 / generic RSC error in prod).
@@ -686,29 +687,29 @@ export function assertNoDynamicApiInsideCache(
686
687
  kind: unstable ? 'unstable-cache-dynamic' : 'use-cache-dynamic',
687
688
  route,
688
689
  consoleBlock: `Error: ${message}`,
689
- });
690
+ })
690
691
  }
691
- throw new Error(message);
692
+ throw new Error(message)
692
693
  }
693
694
 
694
695
  export async function collectRenderCacheMeta<T>(
695
696
  produce: () => Promise<T>,
696
697
  options: {
697
- fetchCache?: string;
698
- refreshFetches?: boolean;
699
- blockingStaleFetches?: boolean;
700
- route?: string;
701
- prerender?: boolean;
702
- handler?: boolean;
703
- dynamicError?: boolean;
698
+ fetchCache?: string
699
+ refreshFetches?: boolean
700
+ blockingStaleFetches?: boolean
701
+ route?: string
702
+ prerender?: boolean
703
+ handler?: boolean
704
+ dynamicError?: boolean
704
705
  } = {},
705
706
  ): Promise<{
706
- value: T;
707
- tags: string[];
708
- revalidateSeconds?: number;
709
- expireSeconds?: number;
710
- staleSeconds?: number;
711
- noStore?: boolean;
707
+ value: T
708
+ tags: string[]
709
+ revalidateSeconds?: number
710
+ expireSeconds?: number
711
+ staleSeconds?: number
712
+ noStore?: boolean
712
713
  }> {
713
714
  const meta: RenderCacheMeta = {
714
715
  tags: new Set(),
@@ -719,9 +720,9 @@ export async function collectRenderCacheMeta<T>(
719
720
  prerender: options.prerender,
720
721
  handler: options.handler,
721
722
  dynamicError: options.dynamicError,
722
- };
723
- const value = await cacheMetaStorage.run(meta, produce);
724
- await drainStaticAfterTasks(meta);
723
+ }
724
+ const value = await cacheMetaStorage.run(meta, produce)
725
+ await drainStaticAfterTasks(meta)
725
726
  return {
726
727
  value,
727
728
  tags: [...meta.tags],
@@ -729,7 +730,7 @@ export async function collectRenderCacheMeta<T>(
729
730
  ...(meta.expireSeconds !== undefined ? { expireSeconds: meta.expireSeconds } : {}),
730
731
  ...(meta.staleSeconds !== undefined ? { staleSeconds: meta.staleSeconds } : {}),
731
732
  ...(meta.noStore ? { noStore: true } : {}),
732
- };
733
+ }
733
734
  }
734
735
 
735
736
  /**
@@ -743,16 +744,16 @@ export async function collectRenderCacheMeta<T>(
743
744
  */
744
745
  async function drainStaticAfterTasks(meta: RenderCacheMeta): Promise<void> {
745
746
  while (meta.afterTasks?.length) {
746
- const tasks = meta.afterTasks;
747
- meta.afterTasks = [];
747
+ const tasks = meta.afterTasks
748
+ meta.afterTasks = []
748
749
  for (const task of tasks) {
749
750
  try {
750
- await cacheMetaStorage.run(meta, task);
751
+ await cacheMetaStorage.run(meta, task)
751
752
  } catch (error) {
752
753
  console.error(
753
754
  `Error occurred prerendering page "${meta.route ?? '/'}". Read more: https://nextjs.org/docs/messages/prerender-error`,
754
- );
755
- throw error;
755
+ )
756
+ throw error
756
757
  }
757
758
  }
758
759
  }