@wular/pnext 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (371) hide show
  1. package/README.md +153 -0
  2. package/bin/pnext +67 -0
  3. package/config/lint/base.js +48 -0
  4. package/config/ts/base.json +26 -0
  5. package/config/ts/react.json +13 -0
  6. package/package.json +70 -0
  7. package/reference/compat.md +63 -0
  8. package/reference/config.md +120 -0
  9. package/reference/css.md +58 -0
  10. package/reference/dev.md +69 -0
  11. package/reference/env.md +40 -0
  12. package/reference/metadata.md +86 -0
  13. package/reference/navigation.md +149 -0
  14. package/reference/overview.md +35 -0
  15. package/reference/performance.md +97 -0
  16. package/reference/rendering.md +127 -0
  17. package/reference/routing.md +167 -0
  18. package/reference/typegen.md +64 -0
  19. package/src/api/cache.ts +80 -0
  20. package/src/api/client-cache.ts +9 -0
  21. package/src/api/client-navigation.ts +279 -0
  22. package/src/api/dynamic.tsx +102 -0
  23. package/src/api/link.tsx +119 -0
  24. package/src/api/navigation.ts +198 -0
  25. package/src/api/router/events.ts +53 -0
  26. package/src/api/router/history.ts +70 -0
  27. package/src/api/router/hub.ts +194 -0
  28. package/src/api/router/policies.ts +107 -0
  29. package/src/api/router/runtime.ts +5238 -0
  30. package/src/api/router/types.ts +299 -0
  31. package/src/api/router.ts +167 -0
  32. package/src/api/server.ts +323 -0
  33. package/src/api/suspense.ts +16 -0
  34. package/src/cache/context.ts +61 -0
  35. package/src/cli/adapters/vercel-warm.ts +375 -0
  36. package/src/cli/adapters/vercel.ts +1310 -0
  37. package/src/cli/analyze-print.ts +181 -0
  38. package/src/cli/analyze.ts +328 -0
  39. package/src/cli/boot-trace.ts +29 -0
  40. package/src/cli/build.ts +3114 -0
  41. package/src/cli/dev.ts +276 -0
  42. package/src/cli/index.ts +196 -0
  43. package/src/cli/named-bin.ts +119 -0
  44. package/src/cli/serve-ui.ts +160 -0
  45. package/src/cli/start.ts +1425 -0
  46. package/src/client/build.ts +2136 -0
  47. package/src/client/chunk-fold.ts +526 -0
  48. package/src/client/entry.ts +1525 -0
  49. package/src/client/paths.ts +22 -0
  50. package/src/client/prebuilt.ts +621 -0
  51. package/src/client/profile.ts +75 -0
  52. package/src/client/react-compiler.ts +94 -0
  53. package/src/client/reference-stub.ts +145 -0
  54. package/src/client/reference.ts +47 -0
  55. package/src/compat/actions/action-client.ts +531 -0
  56. package/src/compat/actions/action-dispatch.ts +676 -0
  57. package/src/compat/actions/action-router.ts +40 -0
  58. package/src/compat/actions/action-shared.ts +95 -0
  59. package/src/compat/actions/client-plugin.ts +135 -0
  60. package/src/compat/actions/client-stub.ts +65 -0
  61. package/src/compat/actions/config.ts +164 -0
  62. package/src/compat/actions/detect.ts +208 -0
  63. package/src/compat/actions/discovery.ts +244 -0
  64. package/src/compat/actions/early-submit.ts +40 -0
  65. package/src/compat/actions/endpoint.ts +602 -0
  66. package/src/compat/actions/flight.ts +52 -0
  67. package/src/compat/actions/form-state.ts +73 -0
  68. package/src/compat/actions/hoist.ts +485 -0
  69. package/src/compat/actions/ids.ts +39 -0
  70. package/src/compat/actions/index.ts +41 -0
  71. package/src/compat/actions/instances.ts +144 -0
  72. package/src/compat/actions/origin.ts +109 -0
  73. package/src/compat/actions/protocol.ts +125 -0
  74. package/src/compat/actions/registry.ts +74 -0
  75. package/src/compat/actions/rewrite.ts +282 -0
  76. package/src/compat/actions/serve.ts +414 -0
  77. package/src/compat/actions/server-tag.ts +21 -0
  78. package/src/compat/actions/unrecognized-error.ts +30 -0
  79. package/src/compat/adapter/build-complete.ts +257 -0
  80. package/src/compat/bundler/bun-externals.ts +53 -0
  81. package/src/compat/bundler/cjs-exports.ts +542 -0
  82. package/src/compat/bundler/config.ts +363 -0
  83. package/src/compat/bundler/externals.ts +34 -0
  84. package/src/compat/bundler/import-meta-url.ts +60 -0
  85. package/src/compat/bundler/modularize-imports.ts +119 -0
  86. package/src/compat/bundler/new-url-asset.ts +87 -0
  87. package/src/compat/bundler/optimize-package-imports.ts +273 -0
  88. package/src/compat/bundler/polyfill.ts +88 -0
  89. package/src/compat/bundler/react-compiler.ts +61 -0
  90. package/src/compat/bundler/react-profiler.tsx +25 -0
  91. package/src/compat/bundler/relay-transform.ts +116 -0
  92. package/src/compat/bundler/require-context.ts +281 -0
  93. package/src/compat/bundler/resolve-extensions.ts +75 -0
  94. package/src/compat/bundler/source-cache.ts +61 -0
  95. package/src/compat/bundler/static-imports.ts +25 -0
  96. package/src/compat/bundler/symlink-imports.ts +119 -0
  97. package/src/compat/bundler/tsconfig-paths.ts +50 -0
  98. package/src/compat/bundler/wasm.ts +153 -0
  99. package/src/compat/bundler/webpack-loaders.ts +685 -0
  100. package/src/compat/bundler/worker.ts +278 -0
  101. package/src/compat/cache/build-flags.ts +81 -0
  102. package/src/compat/cache/build-prerender-errors.ts +163 -0
  103. package/src/compat/cache/custom-handler.ts +159 -0
  104. package/src/compat/cache/fetch-patch.ts +745 -0
  105. package/src/compat/cache/handler.ts +100 -0
  106. package/src/compat/cache/modern-handler.ts +275 -0
  107. package/src/compat/cache/resume-data-cache.ts +143 -0
  108. package/src/compat/cache/revalidate.ts +759 -0
  109. package/src/compat/cache/runtime-error.ts +124 -0
  110. package/src/compat/cache/use-cache-transform.ts +961 -0
  111. package/src/compat/cache/use-cache.ts +1695 -0
  112. package/src/compat/cache-control.ts +269 -0
  113. package/src/compat/client/base-path.ts +64 -0
  114. package/src/compat/client/css-order.ts +36 -0
  115. package/src/compat/client/errors/control-flow.ts +92 -0
  116. package/src/compat/client/errors/error-boundary.ts +222 -0
  117. package/src/compat/client/errors/global-error.ts +238 -0
  118. package/src/compat/client/errors/install.ts +217 -0
  119. package/src/compat/client/errors/lazy.ts +53 -0
  120. package/src/compat/client/errors/primitive-throw.ts +126 -0
  121. package/src/compat/client/errors/soft-refresh.ts +14 -0
  122. package/src/compat/client/link-status.ts +86 -0
  123. package/src/compat/client/nav-compat-runtime.ts +57 -0
  124. package/src/compat/client/nav-compat.ts +42 -0
  125. package/src/compat/client/navigation-scroll.ts +154 -0
  126. package/src/compat/client/optimistic-routing.ts +206 -0
  127. package/src/compat/client/prefetch-cache.ts +111 -0
  128. package/src/compat/client/route-announcer.ts +72 -0
  129. package/src/compat/client/segment-cache-policy.ts +159 -0
  130. package/src/compat/client/segment-cache.ts +1077 -0
  131. package/src/compat/client/segment-prefetch.ts +375 -0
  132. package/src/compat/client/trailing-slash.ts +24 -0
  133. package/src/compat/css/chunking.ts +254 -0
  134. package/src/compat/css/inline-css.ts +73 -0
  135. package/src/compat/css/lightningcss.ts +90 -0
  136. package/src/compat/css/modules.ts +373 -0
  137. package/src/compat/css/nonce.ts +30 -0
  138. package/src/compat/css/sass-plugin.ts +65 -0
  139. package/src/compat/css/sass.ts +392 -0
  140. package/src/compat/css/styled-jsx-runtime.ts +80 -0
  141. package/src/compat/css/styled-jsx.ts +49 -0
  142. package/src/compat/edge-runtime.ts +71 -0
  143. package/src/compat/export/client.ts +112 -0
  144. package/src/compat/export/index.ts +272 -0
  145. package/src/compat/export/standalone.ts +207 -0
  146. package/src/compat/image-optimizer/cache.ts +119 -0
  147. package/src/compat/image-optimizer/detect.ts +143 -0
  148. package/src/compat/image-optimizer/index.ts +601 -0
  149. package/src/compat/image-optimizer/source.ts +243 -0
  150. package/src/compat/index.ts +458 -0
  151. package/src/compat/lifecycle/after-scope.ts +86 -0
  152. package/src/compat/lifecycle/after.ts +173 -0
  153. package/src/compat/lifecycle/error-funnel.ts +306 -0
  154. package/src/compat/lifecycle/error-serialize.ts +87 -0
  155. package/src/compat/lifecycle/error-ui.ts +167 -0
  156. package/src/compat/lifecycle/instrumentation-client.ts +138 -0
  157. package/src/compat/lifecycle/instrumentation.ts +277 -0
  158. package/src/compat/lifecycle/node-console.ts +19 -0
  159. package/src/compat/lifecycle/testmode.ts +263 -0
  160. package/src/compat/mdx/compile.ts +219 -0
  161. package/src/compat/mdx/next-mdx-stub.ts +46 -0
  162. package/src/compat/mdx/plugin.ts +37 -0
  163. package/src/compat/metadata-route-artifacts.ts +458 -0
  164. package/src/compat/metadata.ts +295 -0
  165. package/src/compat/middleware/manifest.ts +210 -0
  166. package/src/compat/misc/action-return.ts +173 -0
  167. package/src/compat/next/cache.ts +211 -0
  168. package/src/compat/next/canonical-url.ts +35 -0
  169. package/src/compat/next/client-cache.ts +57 -0
  170. package/src/compat/next/client-navigation.ts +313 -0
  171. package/src/compat/next/client-only.ts +3 -0
  172. package/src/compat/next/client-script.tsx +215 -0
  173. package/src/compat/next/client-server.ts +39 -0
  174. package/src/compat/next/config-loader.ts +569 -0
  175. package/src/compat/next/config.ts +29 -0
  176. package/src/compat/next/constants.cjs +6 -0
  177. package/src/compat/next/constants.ts +6 -0
  178. package/src/compat/next/custom-server.ts +236 -0
  179. package/src/compat/next/dist/client/components/app-router-headers.ts +32 -0
  180. package/src/compat/next/dist/server/app-render/work-unit-async-storage.external.cjs +38 -0
  181. package/src/compat/next/dist/server/web/spec-extension/revalidate.ts +1 -0
  182. package/src/compat/next/dist/server/web/spec-extension/unstable-cache.ts +1 -0
  183. package/src/compat/next/dist/server/web/spec-extension/unstable-no-store.ts +1 -0
  184. package/src/compat/next/dynamic.tsx +46 -0
  185. package/src/compat/next/error.tsx +148 -0
  186. package/src/compat/next/font/cache.ts +171 -0
  187. package/src/compat/next/font/google.ts +2 -0
  188. package/src/compat/next/font/index.ts +8 -0
  189. package/src/compat/next/font/local.ts +5 -0
  190. package/src/compat/next/font/runtime-client.ts +71 -0
  191. package/src/compat/next/font/runtime.ts +974 -0
  192. package/src/compat/next/font/shared.ts +281 -0
  193. package/src/compat/next/form.tsx +156 -0
  194. package/src/compat/next/head.tsx +10 -0
  195. package/src/compat/next/headers.ts +247 -0
  196. package/src/compat/next/image/config.ts +196 -0
  197. package/src/compat/next/image/optimizer.ts +96 -0
  198. package/src/compat/next/image/patterns.ts +103 -0
  199. package/src/compat/next/image/shared.ts +141 -0
  200. package/src/compat/next/image/static-metadata.ts +283 -0
  201. package/src/compat/next/image/validate.ts +269 -0
  202. package/src/compat/next/image-client.tsx +215 -0
  203. package/src/compat/next/image-props.ts +575 -0
  204. package/src/compat/next/image-usage.ts +102 -0
  205. package/src/compat/next/image.tsx +56 -0
  206. package/src/compat/next/index.ts +1 -0
  207. package/src/compat/next/legacy-image.tsx +97 -0
  208. package/src/compat/next/link-usage.ts +29 -0
  209. package/src/compat/next/link-validation-transform.ts +200 -0
  210. package/src/compat/next/link.tsx +466 -0
  211. package/src/compat/next/navigation.cjs +21 -0
  212. package/src/compat/next/navigation.ts +188 -0
  213. package/src/compat/next/offline.ts +51 -0
  214. package/src/compat/next/og.ts +324 -0
  215. package/src/compat/next/optimistic-route-state.ts +188 -0
  216. package/src/compat/next/preferred-region.ts +39 -0
  217. package/src/compat/next/redirects.ts +131 -0
  218. package/src/compat/next/resource-hints.ts +136 -0
  219. package/src/compat/next/rewrites.ts +350 -0
  220. package/src/compat/next/root-params.ts +142 -0
  221. package/src/compat/next/router.cjs +49 -0
  222. package/src/compat/next/router.ts +143 -0
  223. package/src/compat/next/script.tsx +355 -0
  224. package/src/compat/next/server-only.ts +3 -0
  225. package/src/compat/next/server.ts +28 -0
  226. package/src/compat/next/svgr.ts +58 -0
  227. package/src/compat/next/telemetry.ts +77 -0
  228. package/src/compat/next/user-agent.ts +100 -0
  229. package/src/compat/next/web-vitals.ts +56 -0
  230. package/src/compat/otel/api.ts +95 -0
  231. package/src/compat/otel/client-trace-metadata.ts +71 -0
  232. package/src/compat/otel/fetch-span.ts +77 -0
  233. package/src/compat/otel/tracer.ts +944 -0
  234. package/src/compat/pages/client-plugin.ts +108 -0
  235. package/src/compat/pages/index.ts +527 -0
  236. package/src/compat/pages/router-state.ts +94 -0
  237. package/src/compat/ppr/io.ts +38 -0
  238. package/src/compat/ppr/missing-root-params.ts +105 -0
  239. package/src/compat/ppr/root-params-scan.ts +164 -0
  240. package/src/compat/ppr/root-params-transform.ts +75 -0
  241. package/src/compat/ppr/root-params.ts +129 -0
  242. package/src/compat/ppr/segment-config-incompat.ts +34 -0
  243. package/src/compat/protocol.ts +202 -0
  244. package/src/compat/react/client.ts +59 -0
  245. package/src/compat/react/compiler-runtime.ts +60 -0
  246. package/src/compat/react/dom-client.ts +115 -0
  247. package/src/compat/react/dom-react-server.ts +20 -0
  248. package/src/compat/react/dom-server.ts +40 -0
  249. package/src/compat/react/dom.ts +154 -0
  250. package/src/compat/react/preact.ts +522 -0
  251. package/src/compat/react/react-server.ts +84 -0
  252. package/src/compat/react/router-shim.ts +26 -0
  253. package/src/compat/react/server-component-use.ts +48 -0
  254. package/src/compat/react/server-inserted-html.ts +87 -0
  255. package/src/compat/react/server.ts +156 -0
  256. package/src/compat/react/view-transition.ts +60 -0
  257. package/src/compat/register/actions.ts +875 -0
  258. package/src/compat/register/boot.ts +141 -0
  259. package/src/compat/register/build-tier.ts +11 -0
  260. package/src/compat/register/build.ts +182 -0
  261. package/src/compat/register/bundler.ts +587 -0
  262. package/src/compat/register/cache.ts +85 -0
  263. package/src/compat/register/client-errors.ts +18 -0
  264. package/src/compat/register/config.ts +17 -0
  265. package/src/compat/register/css-extras.ts +120 -0
  266. package/src/compat/register/edge-runtime.ts +6 -0
  267. package/src/compat/register/errors.ts +46 -0
  268. package/src/compat/register/export.ts +23 -0
  269. package/src/compat/register/font.ts +36 -0
  270. package/src/compat/register/hooks.ts +34 -0
  271. package/src/compat/register/image.ts +133 -0
  272. package/src/compat/register/index.ts +111 -0
  273. package/src/compat/register/instrumentation-client.ts +35 -0
  274. package/src/compat/register/lifecycle.ts +86 -0
  275. package/src/compat/register/mdx.ts +48 -0
  276. package/src/compat/register/middleware.ts +36 -0
  277. package/src/compat/register/misc.ts +44 -0
  278. package/src/compat/register/otel.ts +288 -0
  279. package/src/compat/register/pages-api.ts +473 -0
  280. package/src/compat/register/ppr.ts +56 -0
  281. package/src/compat/register/protocol.ts +57 -0
  282. package/src/compat/register/proxy.ts +127 -0
  283. package/src/compat/register/render.ts +268 -0
  284. package/src/compat/register/routing.ts +410 -0
  285. package/src/compat/register/segment.ts +1903 -0
  286. package/src/compat/register/static-image.ts +21 -0
  287. package/src/compat/register/typed-routes.ts +35 -0
  288. package/src/compat/register/usecache.ts +131 -0
  289. package/src/compat/register/validation.ts +56 -0
  290. package/src/compat/segment/loading-boundary.ts +113 -0
  291. package/src/compat/segment/page-slot.ts +200 -0
  292. package/src/compat/segment/tree.ts +481 -0
  293. package/src/compat/segment/vary-key.ts +102 -0
  294. package/src/compat/segment/vary-params.ts +551 -0
  295. package/src/compat/static-params.ts +33 -0
  296. package/src/compat/tsconfig-defaults.ts +301 -0
  297. package/src/compat/typecheck/index.ts +1481 -0
  298. package/src/compat/typecheck/worker.ts +26 -0
  299. package/src/compat/typed-routes/index.ts +92 -0
  300. package/src/compat/typed-routes/manifest.ts +356 -0
  301. package/src/compat/typed-routes/typegen.ts +566 -0
  302. package/src/compat/validation/errors.ts +159 -0
  303. package/src/compat/validation/index.ts +1770 -0
  304. package/src/compat/validation/prerender-diagnostics.ts +1508 -0
  305. package/src/compat-bootstrap.ts +67 -0
  306. package/src/config.ts +218 -0
  307. package/src/css/build.ts +697 -0
  308. package/src/css/index.ts +2 -0
  309. package/src/css/postcss.ts +236 -0
  310. package/src/css/worker.ts +34 -0
  311. package/src/dev/client-actions.ts +35 -0
  312. package/src/dev/client-chunk-store.ts +92 -0
  313. package/src/dev/client-key-cache.ts +178 -0
  314. package/src/dev/global-css-cache.ts +212 -0
  315. package/src/dev/imports.ts +2430 -0
  316. package/src/dev/module-cache.ts +721 -0
  317. package/src/dev/module-generations.ts +38 -0
  318. package/src/dev/module-transform.ts +188 -0
  319. package/src/dev/node-module-bundle-cache.ts +63 -0
  320. package/src/dev/restart-cache.ts +10 -0
  321. package/src/dev/route-bundle-key-cache.ts +154 -0
  322. package/src/dev/route-facts-cache.ts +223 -0
  323. package/src/dev/server.ts +1710 -0
  324. package/src/dynamic/source.ts +307 -0
  325. package/src/dynamic/tree-shake.ts +262 -0
  326. package/src/env.ts +92 -0
  327. package/src/extensions.ts +1898 -0
  328. package/src/index.ts +34 -0
  329. package/src/internal.ts +43 -0
  330. package/src/islands/boundary-error.ts +8 -0
  331. package/src/islands/static-children.ts +37 -0
  332. package/src/islands/static-slots.ts +106 -0
  333. package/src/ppr-postpone.ts +24 -0
  334. package/src/ppr.ts +784 -0
  335. package/src/proxy.ts +752 -0
  336. package/src/render/hooks.ts +384 -0
  337. package/src/render/index.ts +1 -0
  338. package/src/render/island-context.ts +47 -0
  339. package/src/render/metadata.ts +857 -0
  340. package/src/render/renderer.ts +7391 -0
  341. package/src/render/resource-hints.ts +44 -0
  342. package/src/render/slots.tsx +679 -0
  343. package/src/request/context.ts +396 -0
  344. package/src/resolve/engine.ts +219 -0
  345. package/src/resolve/imports.ts +1104 -0
  346. package/src/resolve/scan-facts.ts +474 -0
  347. package/src/resolve/source-text.ts +86 -0
  348. package/src/routing/forwarded.ts +41 -0
  349. package/src/routing/handler.ts +271 -0
  350. package/src/routing/href.ts +203 -0
  351. package/src/routing/metadata.ts +1018 -0
  352. package/src/routing/request-runtime.ts +43 -0
  353. package/src/routing/routes.ts +2560 -0
  354. package/src/routing/slots.ts +432 -0
  355. package/src/runtime/server.ts +3453 -0
  356. package/src/runtime/vendor.ts +1160 -0
  357. package/src/style-modules.d.ts +9 -0
  358. package/src/typegen.ts +151 -0
  359. package/src/types.ts +725 -0
  360. package/src/utils/ansi.ts +9 -0
  361. package/src/utils/content-type.ts +31 -0
  362. package/src/utils/decode.ts +7 -0
  363. package/src/utils/dev-profile.ts +31 -0
  364. package/src/utils/error-log.ts +29 -0
  365. package/src/utils/fs-cache.ts +31 -0
  366. package/src/utils/fs.ts +119 -0
  367. package/src/utils/html.ts +46 -0
  368. package/src/utils/serialize.ts +378 -0
  369. package/src/utils/source.ts +35 -0
  370. package/src/utils/verbose.ts +39 -0
  371. package/tsconfig.json +10 -0
@@ -0,0 +1,211 @@
1
+ import {
2
+ bumpRevalidationEvent,
3
+ cachedData,
4
+ currentRenderCacheMeta,
5
+ insideDataCacheProducer,
6
+ insideUnstableCacheProducer,
7
+ markPathRevalidated,
8
+ markTagRevalidated,
9
+ markTagStale,
10
+ recordCacheNoStore,
11
+ recordCacheRevalidate,
12
+ recordCacheTags,
13
+ } from '../cache/revalidate';
14
+ import { recordUseCacheLife, recordUseCacheTags } from '../cache/use-cache';
15
+ import { currentRequest, getWorkUnit } from '../../request/context';
16
+ import { getNextConfig } from './config-loader';
17
+ import { isPrerendering, PostponeError } from '../../ppr';
18
+ export { io } from '../ppr/io';
19
+
20
+ export function refresh() {
21
+ const phase = getWorkUnit()?.phase;
22
+ if (phase !== 'action' || insideDataCacheProducer()) {
23
+ throw new Error('refresh can only be called from within a Server Action');
24
+ }
25
+ bumpRevalidationEvent();
26
+ }
27
+
28
+ export const unstable_refresh = refresh;
29
+
30
+ /**
31
+ * Revalidation is a side effect and must never run during a render or inside a cached function. At
32
+ * request time a render-phase call throws Next's exact error (the page shows its error UI and the
33
+ * message reaches the server log); during a build prerender the route simply becomes dynamic
34
+ * (postpone). Actions, route handlers and after() are the supported call sites and pass through.
35
+ */
36
+ function assertRevalidateOutsideRender(expression: string): void {
37
+ const route = currentRenderCacheMeta()?.route ?? '/';
38
+ const suffix =
39
+ 'which is unsupported. To ensure revalidation is performed consistently it must always ' +
40
+ 'happen outside of renders and cached functions. See more info here: ' +
41
+ 'https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering';
42
+ if (insideDataCacheProducer()) {
43
+ throw new Error(
44
+ insideUnstableCacheProducer()
45
+ ? `Route ${route} used "${expression}" inside a function cached with "unstable_cache(...)" ${suffix}`
46
+ : `Route ${route} used "${expression}" inside a "use cache" ${suffix}`,
47
+ );
48
+ }
49
+ // Live request renders only: build prerenders (and their after() drains,
50
+ // which run with the work-unit phase still 'render') keep their existing
51
+ // skip-to-dynamic behavior rather than throwing here.
52
+ if (getWorkUnit()?.phase !== 'render' || isPrerendering()) return;
53
+ throw new Error(`Route ${route} used "${expression}" during render ${suffix}`);
54
+ }
55
+
56
+ export function revalidatePath(path: string, type?: 'page' | 'layout') {
57
+ assertRevalidateOutsideRender(`revalidatePath ${path}`);
58
+ markPathRevalidated(path, type);
59
+ }
60
+
61
+ export function revalidateTag(tag: string, profile?: string | CacheLifeProfile) {
62
+ assertRevalidateOutsideRender(`revalidateTag ${tag}`);
63
+ if (profile === undefined) {
64
+ console.warn(
65
+ 'Warning: "revalidateTag" without the second argument is now deprecated. Use updateTag(tag) for read-your-writes semantics, or pass a cache profile (e.g. revalidateTag(tag, \'max\')).',
66
+ );
67
+ markTagRevalidated(tag);
68
+ return;
69
+ }
70
+ // A cache-life profile whose expiry has already elapsed (the built-in `expireNow`, or any profile with
71
+ // expire/revalidate 0) is an immediate hard expiry, not stale-while-revalidate: the next read must
72
+ // recompute inline and observe a fresh value. Softer profiles keep SWR semantics.
73
+ //
74
+ // The profile is either a cacheLife name or an inline `{ expire }` object. An unknown name is treated
75
+ // as immediate expiry too - Next only softens the invalidation when the profile RESOLVES to a nonzero
76
+ // expiry, so failing hard keeps revalidation observable.
77
+ const resolved = typeof profile === 'string' ? resolveCacheLifeProfile(profile) : profile;
78
+ if (!resolved || resolved.expire === 0 || resolved.revalidate === 0) {
79
+ markTagRevalidated(tag);
80
+ return;
81
+ }
82
+ markTagStale(tag);
83
+ }
84
+
85
+ /** updateTag is Server-Action-only in Next (read-your-writes expiry). */
86
+ export function updateTag(tag: string) {
87
+ const request = currentRequest();
88
+ const inServerAction =
89
+ request?.method?.toUpperCase?.() === 'POST' && Boolean(request.headers?.get?.('next-action'));
90
+ if (!inServerAction) {
91
+ throw new Error(
92
+ 'updateTag can only be called from within a Server Action. Use revalidateTag or expireTag for other contexts.',
93
+ );
94
+ }
95
+ markTagRevalidated(tag);
96
+ }
97
+
98
+ // Newer names for the same operations.
99
+ export const unstable_expirePath = revalidatePath;
100
+ export const unstable_expireTag = (tag: string) => {
101
+ assertRevalidateOutsideRender(`expireTag ${tag}`);
102
+ markTagRevalidated(tag);
103
+ };
104
+ export const expirePath = revalidatePath;
105
+ export const expireTag = unstable_expireTag;
106
+
107
+ export interface UnstableCacheOptions {
108
+ revalidate?: number | false;
109
+ tags?: string[];
110
+ }
111
+
112
+ export function unstable_cache<Args extends unknown[], Result>(
113
+ fn: (...args: Args) => Promise<Result>,
114
+ keyParts?: string[],
115
+ options: UnstableCacheOptions = {},
116
+ ): (...args: Args) => Promise<Result> {
117
+ const { revalidate } = options;
118
+ if (
119
+ revalidate !== undefined &&
120
+ revalidate !== false &&
121
+ (typeof revalidate !== 'number' || revalidate < 0 || !Number.isFinite(revalidate))
122
+ ) {
123
+ throw new Error(
124
+ `Invalid revalidate value "${String(revalidate)}" on "unstable_cache(${fn.toString().slice(0, 60)})", must be a non-negative number or false`,
125
+ );
126
+ }
127
+ const baseKey = keyParts?.length ? keyParts.join(',') : fn.toString();
128
+ return (...args: Args) => {
129
+ // Surrounding prerender/ISR writes inherit this entry's tags and TTL.
130
+ recordCacheTags(options.tags ?? []);
131
+ if (typeof options.revalidate === 'number') recordCacheRevalidate(options.revalidate);
132
+ return cachedData(`${baseKey}:${JSON.stringify(args)}`, () => fn(...args), {
133
+ tags: options.tags,
134
+ revalidateSeconds: typeof options.revalidate === 'number' ? options.revalidate : undefined,
135
+ }) as Promise<Result>;
136
+ };
137
+ }
138
+
139
+ /** Opt the surrounding render out of prebuilt static output (Next semantics). */
140
+ export function unstable_noStore() {
141
+ recordCacheNoStore();
142
+ }
143
+
144
+ // 'use cache' directive companions: tag/bound the active use-cache entry
145
+ // (see cache/use-cache.ts) and propagate to the surrounding render meta so
146
+ // prerendered pages inherit tags/TTL.
147
+ export function cacheTag(...tags: string[]) {
148
+ recordUseCacheTags(tags);
149
+ recordCacheTags(tags);
150
+ }
151
+
152
+ // Built-in cacheLife profiles (Next defaults). `expire` defaults to the
153
+ // config's `expireTime` (one year) when a profile omits it; `stale` feeds the
154
+ // `x-nextjs-stale-time` header.
155
+ interface CacheLifeProfile {
156
+ revalidate?: number;
157
+ expire?: number;
158
+ stale?: number;
159
+ }
160
+
161
+ const DEFAULT_EXPIRE_TIME = 31536000; // one year, Next's default expireTime.
162
+
163
+ const builtInCacheLifeProfiles: Record<string, CacheLifeProfile> = {
164
+ default: { revalidate: 900, expire: DEFAULT_EXPIRE_TIME, stale: 300 },
165
+ seconds: { revalidate: 1, expire: 60, stale: 30 },
166
+ minutes: { revalidate: 60, expire: 3600, stale: 300 },
167
+ hours: { revalidate: 3600, expire: 86400, stale: 300 },
168
+ days: { revalidate: 86400, expire: 604800, stale: 300 },
169
+ weeks: { revalidate: 604800, expire: 2592000, stale: 300 },
170
+ max: { revalidate: 2592000, expire: DEFAULT_EXPIRE_TIME, stale: 300 },
171
+ };
172
+
173
+ /** Resolve a cacheLife profile name against config `cacheLife` overrides. */
174
+ function resolveCacheLifeProfile(name: string): CacheLifeProfile | undefined {
175
+ const config = getNextConfig();
176
+ const overrides = config.cacheLife as Record<string, CacheLifeProfile> | undefined;
177
+ const custom = overrides?.[name];
178
+ const builtIn = builtInCacheLifeProfiles[name];
179
+ if (!custom && !builtIn) return undefined;
180
+ const expireTime =
181
+ typeof config.expireTime === 'number' ? config.expireTime : DEFAULT_EXPIRE_TIME;
182
+ const merged = { ...builtIn, ...custom };
183
+ return {
184
+ ...merged,
185
+ expire: merged.expire ?? expireTime,
186
+ };
187
+ }
188
+
189
+ export function cacheLife(
190
+ profile: string | { revalidate?: number; stale?: number; expire?: number },
191
+ ) {
192
+ const resolved =
193
+ typeof profile === 'string'
194
+ ? resolveCacheLifeProfile(profile)
195
+ : {
196
+ revalidate: typeof profile?.revalidate === 'number' ? profile.revalidate : undefined,
197
+ expire: typeof profile?.expire === 'number' ? profile.expire : undefined,
198
+ stale: typeof profile?.stale === 'number' ? profile.stale : undefined,
199
+ };
200
+ if (!resolved) return;
201
+ const { revalidate, expire, stale } = resolved;
202
+ recordUseCacheLife({
203
+ ...(revalidate !== undefined ? { revalidateSeconds: revalidate } : {}),
204
+ ...(expire !== undefined ? { expireSeconds: expire } : {}),
205
+ ...(stale !== undefined ? { staleSeconds: stale } : {}),
206
+ });
207
+ if (revalidate !== undefined) recordCacheRevalidate(revalidate);
208
+ if (isPrerendering() && stale === 0) throw new PostponeError('cacheLife');
209
+ }
210
+ export const unstable_cacheTag = cacheTag;
211
+ export const unstable_cacheLife = cacheLife;
@@ -0,0 +1,35 @@
1
+ // Canonical (as-requested) URL tracking for next/navigation hooks (COMPAT).
2
+ //
3
+ // After a config or middleware rewrite, the downstream render sees the DESTINATION URL (the rewrite
4
+ // mutates the forwarded request's URL). But Next's usePathname()/useSearchParams() must return the
5
+ // CANONICAL URL the browser asked for. This module stashes that original URL on the per-request work
6
+ // unit so the SSR hooks can return it.
7
+ //
8
+ // The setter is invoked from the rewrite observer: when a same-origin rewrite fires, the original URL is
9
+ // remembered here. When nothing sets it, the hooks fall back to the request URL.
10
+
11
+ import { getWorkUnit } from '../../request/context';
12
+
13
+ const CANONICAL_URL_KEY = Symbol.for('pnext.compat.navigation.canonicalUrl');
14
+
15
+ /**
16
+ * Record the canonical (original, as-requested) URL for the active request,
17
+ * before a rewrite replaces it with the destination. A no-op outside a request
18
+ * work unit. `from` is the URL the client asked for.
19
+ */
20
+ export function recordCanonicalUrl(from: URL): void {
21
+ const unit = getWorkUnit();
22
+ if (!unit) return;
23
+ const compat = (unit.compat ??= {});
24
+ // Chained rewrites (middleware → next.config) record in sequence; the
25
+ // canonical URL is what the BROWSER asked for, so only the first wins — a
26
+ // later record's `from` is itself a rewrite destination.
27
+ if (typeof compat[CANONICAL_URL_KEY] === 'string') return;
28
+ compat[CANONICAL_URL_KEY] = from.href;
29
+ }
30
+
31
+ /** The canonical URL recorded for the active request, or undefined. */
32
+ export function canonicalUrlHref(): string | undefined {
33
+ const value = getWorkUnit()?.compat?.[CANONICAL_URL_KEY];
34
+ return typeof value === 'string' ? value : undefined;
35
+ }
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Client-bundle variant of next/cache. These APIs are server-only in Next;
3
+ * client references exist mostly so modules shared with server code parse.
4
+ * Revalidation calls throw (as in Next), unstable_cache degrades to a
5
+ * pass-through, and the 'use cache' companions are no-ops.
6
+ */
7
+
8
+ function serverOnly(name: string): never {
9
+ throw new Error(`${name} can only be called from a Server Component or server function.`);
10
+ }
11
+
12
+ export function revalidatePath(_path: string, _type?: 'page' | 'layout') {
13
+ serverOnly('revalidatePath');
14
+ }
15
+
16
+ export function revalidateTag(_tag: string) {
17
+ serverOnly('revalidateTag');
18
+ }
19
+
20
+ export const unstable_expirePath = revalidatePath;
21
+ export const unstable_expireTag = revalidateTag;
22
+ export const expirePath = revalidatePath;
23
+ export const expireTag = revalidateTag;
24
+ export const updateTag = revalidateTag;
25
+
26
+ export function refresh() {
27
+ serverOnly('refresh');
28
+ }
29
+ export const unstable_refresh = refresh;
30
+
31
+ export interface UnstableCacheOptions {
32
+ revalidate?: number | false;
33
+ tags?: string[];
34
+ }
35
+
36
+ export function unstable_cache<Args extends unknown[], Result>(
37
+ fn: (...args: Args) => Promise<Result>,
38
+ _keyParts?: string[],
39
+ _options: UnstableCacheOptions = {},
40
+ ): (...args: Args) => Promise<Result> {
41
+ return fn;
42
+ }
43
+
44
+ export function unstable_noStore() {
45
+ return undefined;
46
+ }
47
+ export function io(): Promise<void> {
48
+ return Promise.resolve();
49
+ }
50
+ export function cacheTag(..._tags: string[]) {
51
+ return undefined;
52
+ }
53
+ export function cacheLife(_profile: string | Record<string, unknown>) {
54
+ return undefined;
55
+ }
56
+ export const unstable_cacheTag = cacheTag;
57
+ export const unstable_cacheLife = cacheLife;
@@ -0,0 +1,313 @@
1
+ import { useContext } from 'preact/hooks';
2
+ import {
3
+ ReadonlyURLSearchParams,
4
+ useParams as usePNextParams,
5
+ usePathname,
6
+ useRouter as usePNextRouter,
7
+ useSearchParams,
8
+ } from '../../api/client-navigation';
9
+ import {
10
+ LayoutSegmentContext,
11
+ type LayoutSegmentSnapshot,
12
+ RouteParamsContext,
13
+ } from '../../render/island-context';
14
+ import { blockJavascriptUrl } from '../../api/router';
15
+ import { isUnrecognizedActionError } from '../actions/unrecognized-error';
16
+ import {
17
+ forbidden,
18
+ notFound,
19
+ PNextForbiddenError,
20
+ PNextNotFoundError,
21
+ PNextRedirectError,
22
+ PNextUnauthorizedError,
23
+ unauthorized,
24
+ type RedirectStatus,
25
+ } from '../../api/navigation';
26
+
27
+ export {
28
+ forbidden,
29
+ notFound,
30
+ PNextForbiddenError,
31
+ PNextNotFoundError,
32
+ PNextRedirectError,
33
+ PNextUnauthorizedError,
34
+ unauthorized,
35
+ ReadonlyURLSearchParams,
36
+ usePathname,
37
+ useSearchParams,
38
+ };
39
+ export type { RedirectStatus };
40
+
41
+ export const RedirectType = {
42
+ push: 'push',
43
+ replace: 'replace',
44
+ } as const;
45
+
46
+ export type RedirectType = (typeof RedirectType)[keyof typeof RedirectType];
47
+
48
+ let pendingRedirectHref: string | undefined;
49
+
50
+ export function redirect(location: string, type: RedirectType = RedirectType.replace): never {
51
+ redirectInBrowser(location, type);
52
+ return undefined as never;
53
+ }
54
+
55
+ export function permanentRedirect(
56
+ location: string,
57
+ type: RedirectType = RedirectType.replace,
58
+ ): never {
59
+ redirectInBrowser(location, type);
60
+ return undefined as never;
61
+ }
62
+
63
+ function redirectInBrowser(location: string, mode: RedirectType) {
64
+ if (!process.browser && typeof window === 'undefined') return;
65
+
66
+ const href = new URL(location, window.location.href).href;
67
+ if (pendingRedirectHref === href) return;
68
+ pendingRedirectHref = href;
69
+ if (mode === RedirectType.push) window.location.assign(href);
70
+ else window.location.replace(href);
71
+ }
72
+
73
+ export interface NavigateOptions {
74
+ scroll?: boolean;
75
+ }
76
+
77
+ export interface PrefetchOptions {
78
+ kind?: 'auto' | 'full';
79
+ onInvalidate?: () => void;
80
+ }
81
+
82
+ export interface AppRouterInstance {
83
+ push(href: string, options?: NavigateOptions): void;
84
+ replace(href: string, options?: NavigateOptions): void;
85
+ prefetch(href: string, options?: PrefetchOptions): void;
86
+ refresh(): void;
87
+ back(): void;
88
+ forward(): void;
89
+ /**
90
+ * React Gesture Transitions (`experimental.gestureTransition`): commit the target route OPTIMISTICALLY
91
+ * while a gesture is still in flight, ahead of the canonical `push` the gesture's completion issues.
92
+ * pnext has no partially-committed render state, so the optimistic commit is the same soft navigation
93
+ * - the canonical push that follows re-renders the already current URL.
94
+ */
95
+ experimental_gesturePush(href: string, options?: NavigateOptions): void;
96
+ bfcacheId: string;
97
+ }
98
+
99
+ // Next's useRouter returns a stable instance across renders. The wrapper is
100
+ // stateless (it delegates to core's singleton router), so build it once and
101
+ // reuse it — callers rely on referential identity (deps arrays, memoization).
102
+ let cachedRouter: AppRouterInstance | undefined;
103
+ let refreshSuppressed = false;
104
+
105
+ function suppressSameTickRefresh() {
106
+ refreshSuppressed = true;
107
+ queueMicrotask(() => {
108
+ refreshSuppressed = false;
109
+ });
110
+ }
111
+
112
+ export function useRouter(): AppRouterInstance {
113
+ const router = usePNextRouter();
114
+ const pathname = usePathname();
115
+ const snapshot = useContext(LayoutSegmentContext);
116
+ const bfcacheId = scopedBfcacheId(pathname, snapshot, router.bfcacheId);
117
+ cachedRouter ??= {
118
+ push: (href, options) => {
119
+ if (blockJavascriptUrl(href)) return;
120
+ suppressSameTickRefresh();
121
+ router.push(href as never, options as never);
122
+ },
123
+ replace: (href, options) => {
124
+ if (blockJavascriptUrl(href)) return;
125
+ suppressSameTickRefresh();
126
+ router.replace(href as never, options as never);
127
+ },
128
+ prefetch: (href, options) => {
129
+ if (blockJavascriptUrl(href)) return;
130
+ router.prefetch(href as never, options as never);
131
+ },
132
+ refresh: () => {
133
+ if (refreshSuppressed) return;
134
+ router.refresh();
135
+ },
136
+ back: () => router.back(),
137
+ forward: () => router.forward(),
138
+ experimental_gesturePush: (href, options) => {
139
+ if (blockJavascriptUrl(href)) return;
140
+ suppressSameTickRefresh();
141
+ // A gesture commits the target route optimistically: the address bar moves as soon as the gesture
142
+ // starts, ahead of the render landing. Start the navigation FIRST (its synchronous prologue reads
143
+ // the current location to key the departing route), as a `replace` so the entry pushed just below
144
+ // is the one it commits into - one new history entry, showing the target URL immediately.
145
+ router.replace(href as never, options as never);
146
+ pushOptimisticEntry(href);
147
+ },
148
+ bfcacheId: '',
149
+ };
150
+ cachedRouter.bfcacheId = bfcacheId;
151
+ return cachedRouter;
152
+ }
153
+
154
+ // The optimistic history entry a gesture push commits before its render lands.
155
+ // Same-origin only; the in-flight soft navigation replaces this entry with the
156
+ // committed one (and the patched pushState broadcasts the location change, so
157
+ // usePathname/useSearchParams see the target route right away).
158
+ function pushOptimisticEntry(href: string) {
159
+ if (!process.browser && typeof window === 'undefined') return;
160
+ const target = new URL(href, window.location.href);
161
+ if (target.origin !== window.location.origin) return;
162
+ if (target.href === window.location.href) return;
163
+ window.history.pushState(window.history.state, '', target.href);
164
+ }
165
+
166
+ export function useParams<
167
+ T extends Record<string, string | string[]> = Record<string, string | string[]>,
168
+ >() {
169
+ // An island rendered inside a parallel-route slot is stamped with the slot's
170
+ // own params (route params + the slot's dynamic/catch-all captures) via
171
+ // RouteParamsContext — window.__PNEXT_ROUTE__.params only carries the global
172
+ // route params. Prefer the island-scoped snapshot when present.
173
+ const scoped = useContext(RouteParamsContext);
174
+ const params = usePNextParams();
175
+ return (scoped ?? params) as T;
176
+ }
177
+
178
+ interface DocumentNavState {
179
+ children?: string;
180
+ slots?: Record<string, string>;
181
+ /** Children rendered `default.*` (Next's `__DEFAULT__`) — no selected segment. */
182
+ childrenDefault?: boolean;
183
+ }
184
+
185
+ export function useSelectedLayoutSegment(parallelRoutesKey?: string): string | null {
186
+ const segments = clientSelectedSegments(parallelRoutesKey);
187
+ return segments[parallelRoutesKey ? segments.length - 1 : 0] ?? null;
188
+ }
189
+
190
+ export function useSelectedLayoutSegments(parallelRoutesKey?: string): string[] {
191
+ return clientSelectedSegments(parallelRoutesKey);
192
+ }
193
+
194
+ /**
195
+ * Client implementation of useSelectedLayoutSegment(s). A `'use client'` layout
196
+ * hydrates as an island with no per-layout server scope; the renderer stamps it
197
+ * with a LayoutSegmentContext snapshot (render/island-context.ts) carrying the
198
+ * layout's `depth` plus the server-resolved segments.
199
+ *
200
+ * - Server render (SSR of the island): return the resolved `segments`/`slots`
201
+ * from the snapshot so the emitted HTML is byte-exact.
202
+ * - Client render: recompute the suffix live from the layout `depth` and the
203
+ * current path. `depth` is stable for a given layout, so a shared layout's
204
+ * island stays correct across soft navigations even when it is preserved and
205
+ * merely re-rendered (usePathname subscribes, driving the recompute).
206
+ *
207
+ * Without a snapshot (e.g. a client PAGE island, which has no layout scope) it
208
+ * falls back to deriving segments from the server-embedded nav state.
209
+ */
210
+ function clientSelectedSegments(parallelRoutesKey?: string): string[] {
211
+ usePathname();
212
+ const snapshot = useContext(LayoutSegmentContext);
213
+
214
+ if (!process.browser && typeof window === 'undefined') {
215
+ if (snapshot) {
216
+ return parallelRoutesKey ? (snapshot.slots[parallelRoutesKey] ?? []) : snapshot.segments;
217
+ }
218
+ return [];
219
+ }
220
+
221
+ const navState = documentNavState();
222
+ // A defaulted children slot (Next's `__DEFAULT__`) selects nothing: the URL's
223
+ // segments were matched by a PARALLEL slot, not by children.
224
+ const childrenSegments = () =>
225
+ navState.childrenDefault
226
+ ? []
227
+ : routePatternSegments(navState.children ?? window.location.pathname);
228
+
229
+ if (snapshot) {
230
+ if (parallelRoutesKey) return pathSegments(slotPath(parallelRoutesKey) ?? '');
231
+ return childrenSegments().slice(snapshot.depth);
232
+ }
233
+
234
+ if (parallelRoutesKey) return pathSegments(slotPath(parallelRoutesKey) ?? '');
235
+ return childrenSegments();
236
+ }
237
+
238
+ function routePatternSegments(pathname: string): string[] {
239
+ const pattern = window.__PNEXT_ROUTE__?.route;
240
+ const segments = pathSegments(pathname);
241
+ if (!pattern) return segments;
242
+ const patternSegments = pattern.split('/').filter(Boolean);
243
+ // Colon form: a catch-all segment is `:slug*` (both `[...slug]` and
244
+ // `[[...slug]]` collapse the trailing group the same way here).
245
+ const catchAllIndex = patternSegments.findIndex(part => /^:[\w$]+\*$/.test(part));
246
+ if (catchAllIndex === -1) return segments;
247
+ const head = segments.slice(0, catchAllIndex);
248
+ const tail = segments.slice(catchAllIndex);
249
+ return tail.length > 0 ? [...head, tail.join('/')] : head;
250
+ }
251
+
252
+ function pathSegments(pathname: string): string[] {
253
+ return pathname.split('/').filter(Boolean).map(decodeSegment);
254
+ }
255
+
256
+ function slotPath(parallelRoutesKey: string): string | undefined {
257
+ const slotName = `@${parallelRoutesKey}`;
258
+ for (const [dir, pathname] of Object.entries(documentNavState().slots ?? {})) {
259
+ const parts = dir.split(/[\\/]/);
260
+ if (parts[parts.length - 1] === slotName) return pathname;
261
+ }
262
+ return undefined;
263
+ }
264
+
265
+ function documentNavState(): DocumentNavState {
266
+ const text = document.getElementById('__PNEXT_NAV_STATE__')?.textContent;
267
+ if (!text) return {};
268
+ try {
269
+ return JSON.parse(text) as DocumentNavState;
270
+ } catch {
271
+ return {};
272
+ }
273
+ }
274
+
275
+ function decodeSegment(segment: string): string {
276
+ try {
277
+ return decodeURIComponent(segment);
278
+ } catch {
279
+ return segment;
280
+ }
281
+ }
282
+
283
+ // A layout's bfcacheId must stay stable across a sibling leaf navigation: the shared layout is
284
+ // preserved live, so its own form/DOM state must not reset just because the leaf below it navigated.
285
+ // The per-history-entry `baseId` changes on every path-changing push, so it cannot be part of a
286
+ // layout's key - concatenating it would make the layout's scoped id churn on every sibling nav,
287
+ // defeating the whole point of the scope. Instead the layout's id is derived purely from its own scope
288
+ // (the path segments it actually owns), stable across siblings and naturally different when the
289
+ // scope's own segment changes.
290
+ function scopedBfcacheId(
291
+ pathname: string,
292
+ snapshot: LayoutSegmentSnapshot | null,
293
+ baseId: string,
294
+ ) {
295
+ if (!baseId) return '';
296
+ if (!snapshot || snapshot.depth <= 0) return baseId;
297
+ const segments = pathname.split('/').filter(Boolean);
298
+ if (!segments.length) return baseId;
299
+ const scope = segments.slice(0, Math.min(snapshot.depth, segments.length)).join('/');
300
+ return scope ? `layout:${scope}` : baseId;
301
+ }
302
+
303
+ export { useLinkStatus } from './link';
304
+ export { useServerInsertedHTML } from '../react/server-inserted-html';
305
+
306
+ /**
307
+ * True for the error a server-action dispatch throws when the server no longer
308
+ * recognizes the action id (version skew). Matches the message the pnext
309
+ * action endpoint sends for an unknown id.
310
+ */
311
+ export function unstable_isUnrecognizedActionError(error: unknown): boolean {
312
+ return isUnrecognizedActionError(error);
313
+ }
@@ -0,0 +1,3 @@
1
+ // client-only import marker: valid in client modules (browser bundle); the
2
+ // server bundler keeps the real package error path. Mirror of server-only.ts.
3
+ export {};