@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,384 @@
1
+ // Render-layer extension points (CORE - imports ZERO compat).
2
+ //
3
+ // The foundation registry (src/extensions.ts) owns the four cross-cutting render hooks. This module holds
4
+ // the render-ONLY companion hooks that render/index.tsx needs but that do not belong in the shared
5
+ // registry: the font scope/asset collector, the compat Suspense identity, and the server-action
6
+ // module-tagging lifecycle.
7
+ //
8
+ // Every hook ships a working NO-OP / pass-through default so a pure-core app renders unchanged. Compat
9
+ // populates them from src/compat/register/render.ts at the gated bootstrap seam; the dependency edge is
10
+ // inverted - core never imports compat. Types stay structural so core carries no type dependency on any
11
+ // compat module.
12
+
13
+ import type { ResolvedConfig } from '../config';
14
+ import type { Metadata, MetadataLink, PageProps, Viewport } from '../types';
15
+ import { restoreWithExtensionHost } from '../extensions';
16
+
17
+ // ---------------------------------------------------------------------------
18
+ // Compat enablement gates (pure config reads; kept in core so render never
19
+ // imports compat/index just to branch on the mode). MUST stay in sync with
20
+ // compat/index.ts reactCompatEnabled / nextCompatEnabled and the inlined gate
21
+ // in compat-bootstrap.ts.
22
+ // ---------------------------------------------------------------------------
23
+
24
+ /** Next compat is on (server actions, next/* modules, authInterrupts). */
25
+ export function nextCompatEnabled(config: ResolvedConfig): boolean {
26
+ return Boolean(config.compat?.next);
27
+ }
28
+
29
+ /** React compat is on (next implies react; react/react-dom aliasing, use() replay). */
30
+ export function reactCompatEnabled(config: ResolvedConfig): boolean {
31
+ return Boolean(config.compat?.next || config.compat?.react || config.compat?.reactCompiler);
32
+ }
33
+
34
+ // ---------------------------------------------------------------------------
35
+ // Font extensions — populated by compat/next/font/runtime (registerRender-
36
+ // Extensions). Core renders no fonts; the whole subsystem is next-compat.
37
+ // ---------------------------------------------------------------------------
38
+
39
+ /** Resolved next/font CSS + preload links for a render (mirrors ResolvedFontAssets). */
40
+ export interface RenderFontAssets {
41
+ css: string;
42
+ preloads: MetadataLink[];
43
+ }
44
+
45
+ export interface FontExtensions {
46
+ /**
47
+ * Wrap a render in a font-collection scope so next/font `.className` getters
48
+ * register their definitions. Compat installs the AsyncLocalStorage scope
49
+ * (compat/next/font/runtime runWithFontScope). Default: run untouched.
50
+ */
51
+ runWithFontScope: <T>(callback: () => T) => T;
52
+
53
+ /**
54
+ * Emit the CSS + preload links for the fonts registered during the current
55
+ * render scope. Compat supplies fontAssets(config, options). Default: none.
56
+ */
57
+ collectFontAssets: (
58
+ config: ResolvedConfig,
59
+ options: { dev?: boolean },
60
+ ) => Promise<RenderFontAssets>;
61
+
62
+ /**
63
+ * Resolve every font declared by modules loaded so far, without waiting for a render to register
64
+ * them. `collectFontAssets` is network-bound on a cold checkout and sits at the very END of the
65
+ * render, so it serializes behind everything. Called off the request's critical path, it lands in
66
+ * the same memo the render reads. Default: none.
67
+ */
68
+ prewarmFontAssets: (config: ResolvedConfig, options: { dev?: boolean }) => Promise<void>;
69
+ }
70
+
71
+ const fontExtensions: FontExtensions = {
72
+ runWithFontScope: callback => callback(),
73
+ collectFontAssets: () => Promise.resolve({ css: '', preloads: [] }),
74
+ prewarmFontAssets: () => Promise.resolve(),
75
+ };
76
+
77
+ export function getFontExtensions(): FontExtensions {
78
+ return fontExtensions;
79
+ }
80
+
81
+ export function setFontExtensions(overrides: Partial<FontExtensions>): void {
82
+ Object.assign(fontExtensions, overrides);
83
+ }
84
+
85
+ // Suspense identity - compat apps render React's Suspense (preact/compat), which streaming must recognize
86
+ // alongside core's own Suspense marker. Loaded lazily so core apps never pull preact/compat into the server
87
+ // process.
88
+
89
+ export interface SuspenseExtensions {
90
+ /**
91
+ * Lazily resolve the compat Suspense component type (preact/compat) once, so the streaming tree walker can
92
+ * treat it as a boundary. Default is a noop - core streaming uses its own Suspense marker only.
93
+ */
94
+ ensureCompatSuspense: (config: ResolvedConfig) => Promise<void>;
95
+ /** The resolved compat Suspense type, or undefined for a pure-core render. */
96
+ compatSuspenseType: () => unknown;
97
+ }
98
+
99
+ const suspenseExtensions: SuspenseExtensions = {
100
+ ensureCompatSuspense: () => Promise.resolve(),
101
+ compatSuspenseType: () => undefined,
102
+ };
103
+
104
+ export function getSuspenseExtensions(): SuspenseExtensions {
105
+ return suspenseExtensions;
106
+ }
107
+
108
+ export function setSuspenseExtensions(overrides: Partial<SuspenseExtensions>): void {
109
+ Object.assign(suspenseExtensions, overrides);
110
+ }
111
+
112
+ export interface StreamRouteExtensions {
113
+ canStreamRoute: (input: {
114
+ config: ResolvedConfig;
115
+ route: { client?: boolean; stream?: unknown };
116
+ }) => boolean;
117
+ /**
118
+ * True when the route must stream through a SINGLE preact render (suspending
119
+ * in place) rather than the out-of-order resolve walk, because an ancestor
120
+ * layout/template is a client component whose provider context a separately
121
+ * rendered replacement chunk would lose. See renderClientPageStreamShell.
122
+ */
123
+ inlineSuspenseStream: (input: {
124
+ config: ResolvedConfig;
125
+ route: { client?: boolean; stream?: unknown };
126
+ }) => boolean;
127
+ }
128
+
129
+ const streamRouteExtensions: StreamRouteExtensions = {
130
+ canStreamRoute: () => true,
131
+ inlineSuspenseStream: () => false,
132
+ };
133
+
134
+ export function getStreamRouteExtensions(): StreamRouteExtensions {
135
+ return streamRouteExtensions;
136
+ }
137
+
138
+ export function setStreamRouteExtensions(overrides: Partial<StreamRouteExtensions>): void {
139
+ Object.assign(streamRouteExtensions, overrides);
140
+ }
141
+
142
+ export interface StreamBoundaryExtensions {
143
+ onStreamBoundaryError: (error: unknown) => void | Promise<void>;
144
+ }
145
+
146
+ const streamBoundaryExtensions: StreamBoundaryExtensions = {
147
+ onStreamBoundaryError: () => undefined,
148
+ };
149
+
150
+ export function getStreamBoundaryExtensions(): StreamBoundaryExtensions {
151
+ return streamBoundaryExtensions;
152
+ }
153
+
154
+ export function setStreamBoundaryExtensions(overrides: Partial<StreamBoundaryExtensions>): void {
155
+ Object.assign(streamBoundaryExtensions, overrides);
156
+ }
157
+
158
+ export function reportStreamBoundaryError(error: unknown): void {
159
+ try {
160
+ const result = streamBoundaryExtensions.onStreamBoundaryError(error);
161
+ if (isThenable(result)) {
162
+ void Promise.resolve(result).catch(reportError => {
163
+ console.error('stream boundary error hook failed:', reportError);
164
+ });
165
+ }
166
+ } catch (reportError) {
167
+ console.error('stream boundary error hook failed:', reportError);
168
+ }
169
+ }
170
+
171
+ function isThenable(value: unknown): value is PromiseLike<unknown> {
172
+ return typeof (value as { then?: unknown } | null | undefined)?.then === 'function';
173
+ }
174
+
175
+ // Metadata resolver - core handles static/build-time metadata. Compat registers request-time/streaming-
176
+ // compatible metadata resolvers here without adding a core-to-compat import edge.
177
+
178
+ export interface MetadataExtensions {
179
+ enabled: (config: ResolvedConfig) => boolean;
180
+ hasRuntimeMetadata: (module: Record<string, unknown>) => boolean;
181
+ readModuleMetadata: (
182
+ module: Record<string, unknown>,
183
+ props: PageProps,
184
+ parent: Metadata,
185
+ modulePath?: string,
186
+ ) => Promise<Metadata | undefined>;
187
+ readModuleViewport: (
188
+ module: Record<string, unknown>,
189
+ props: PageProps,
190
+ ) => Promise<Viewport | undefined>;
191
+ shouldRenderMetadataInBody: (input: { config: ResolvedConfig; request?: Request }) => boolean;
192
+ }
193
+
194
+ const metadataExtensions: Partial<MetadataExtensions> = {};
195
+
196
+ export function getMetadataExtensions(): Partial<MetadataExtensions> {
197
+ return metadataExtensions;
198
+ }
199
+
200
+ export function getActiveMetadataExtensions(config: ResolvedConfig): Partial<MetadataExtensions> {
201
+ return metadataExtensions.enabled?.(config) ? metadataExtensions : {};
202
+ }
203
+
204
+ export function setMetadataExtensions(overrides: Partial<MetadataExtensions>): void {
205
+ Object.assign(metadataExtensions, overrides);
206
+ }
207
+
208
+ // ---------------------------------------------------------------------------
209
+ // Document script injection — compat appends inline scripts to the streamed
210
+ // document body (e.g. Next's window.next router shim). Core injects nothing.
211
+ // ---------------------------------------------------------------------------
212
+
213
+ export interface DocumentScriptExtensions {
214
+ /** Optional precedence assigned to renderer-managed stylesheet links. */
215
+ stylesheetPrecedence: (config: ResolvedConfig) => string | undefined;
216
+
217
+ /**
218
+ * Inline scripts compat injects near the end of the document body, before the
219
+ * props/route/client scripts. Compat (react) returns Next's window.next router
220
+ * shim. Default: '' (core injects no compat scripts).
221
+ */
222
+ documentBodyScripts: (config: ResolvedConfig) => string;
223
+
224
+ /**
225
+ * Inline tags compat injects into the document `<head>` once per document
226
+ * render. `ctx.dynamic` is true for a request-dependent render (a prod static
227
+ * page is `false` so `next start` skips it; dev renders are always dynamic),
228
+ * while `ctx.rsc` identifies a client navigation/prefetch render. Compat
229
+ * (otel) composes clientTraceMetadata `<meta>` tags here. Default: '' (core
230
+ * injects no compat head tags).
231
+ */
232
+ documentHeadTags?: (config: ResolvedConfig, ctx: { dynamic: boolean; rsc: boolean }) => string;
233
+
234
+ /** Tags collected after the document shell has flushed. */
235
+ streamInsertedHTML?: () => string;
236
+ }
237
+
238
+ const documentScriptExtensions: DocumentScriptExtensions = {
239
+ stylesheetPrecedence: () => undefined,
240
+ documentBodyScripts: () => '',
241
+ };
242
+
243
+ export function getDocumentScriptExtensions(): DocumentScriptExtensions {
244
+ return documentScriptExtensions;
245
+ }
246
+
247
+ export function setDocumentScriptExtensions(overrides: Partial<DocumentScriptExtensions>): void {
248
+ Object.assign(documentScriptExtensions, overrides);
249
+ }
250
+
251
+ // ---------------------------------------------------------------------------
252
+ // Static params module normalization — core reads params(). Next compat
253
+ // registers a module wrapper that exposes generateStaticParams as params().
254
+ // ---------------------------------------------------------------------------
255
+
256
+ export interface StaticParamsExtensions {
257
+ normalizeModule: (module: Record<string, unknown>) => Record<string, unknown>;
258
+ }
259
+
260
+ const staticParamsExtensions: StaticParamsExtensions = {
261
+ normalizeModule: module =>
262
+ typeof module.params === 'function' || typeof module.generateStaticParams !== 'function'
263
+ ? module
264
+ : { ...module, params: module.generateStaticParams },
265
+ };
266
+
267
+ export function getStaticParamsExtensions(): StaticParamsExtensions {
268
+ return staticParamsExtensions;
269
+ }
270
+
271
+ export function setStaticParamsExtensions(overrides: Partial<StaticParamsExtensions>): void {
272
+ Object.assign(staticParamsExtensions, overrides);
273
+ }
274
+
275
+ // Server-action module tagging - when a server render imports a 'use server' module, compat tags each
276
+ // exported function with its wire id so `<form action={fn}>` can progressively enhance without JS. Both
277
+ // hooks are no-ops for a pure-core app.
278
+
279
+ export interface ActionModuleExtensions {
280
+ /**
281
+ * Eagerly import + tag every discovered action module before a page renders,
282
+ * so a <form action={serverAction}> whose action came from a normal import in
283
+ * the page (same module singleton) sees a tagged function. `importModule` is
284
+ * core's own loader, passed in so tagging reuses the render's module cache.
285
+ * Compat supplies the discovery-driven implementation. Default: noop.
286
+ */
287
+ tagActionModulesForRender: (
288
+ config: ResolvedConfig,
289
+ importModule: (file: string) => Promise<Record<string, unknown>>,
290
+ ) => Promise<void>;
291
+
292
+ /**
293
+ * Tag the exports of a freshly imported module when it is a discovered action
294
+ * module. Core calls this from importModule for every module it loads. Compat
295
+ * gates on isClientActionModule + tags each function export. Default: noop.
296
+ */
297
+ tagActionModuleExports: (
298
+ config: ResolvedConfig,
299
+ file: string,
300
+ module: Record<string, unknown>,
301
+ ) => void;
302
+ }
303
+
304
+ const actionModuleExtensions: ActionModuleExtensions = {
305
+ tagActionModulesForRender: () => Promise.resolve(),
306
+ tagActionModuleExports: () => undefined,
307
+ };
308
+
309
+ export function getActionModuleExtensions(): ActionModuleExtensions {
310
+ return actionModuleExtensions;
311
+ }
312
+
313
+ export function setActionModuleExtensions(overrides: Partial<ActionModuleExtensions>): void {
314
+ Object.assign(actionModuleExtensions, overrides);
315
+ }
316
+
317
+ // Render span seam - compat (otel) wraps the render-body and route-resolution phases in OpenTelemetry
318
+ // spans. Every hook is a pass-through so a pure-core render is untouched; compat threads parenting through
319
+ // its own work-unit ALS, never OTel's ContextManager. Callbacks are invoked exactly once around the wrapped
320
+ // work and their result returned verbatim.
321
+
322
+ export interface RenderSpanExtensions {
323
+ /**
324
+ * Wrap the body render (renderTree) so compat emits the
325
+ * `render route (app) <route>` span (`AppRender.getBodyResult`). `route` is
326
+ * the route PATTERN. Default: run `fn` untouched.
327
+ */
328
+ withRenderBodySpan: <T>(route: string, fn: () => Promise<T>) => Promise<T>;
329
+
330
+ /**
331
+ * Wrap route-component resolution (page module import) so compat emits the
332
+ * `resolve page components` span (`NextNodeServer.findPageComponents`,
333
+ * sibling of the render-body span under the root). Default: run `fn`.
334
+ */
335
+ withFindPageComponentsSpan: <T>(route: string, fn: () => Promise<T>) => Promise<T>;
336
+
337
+ /**
338
+ * Emit a cheap leaf `resolve segment modules` span
339
+ * (`NextNodeServer.getLayoutOrPageModule`, `next.segment`) for a resolved
340
+ * page/layout segment, nested under the render-body span. `segment` is
341
+ * `__PAGE__` for the leaf page or the dynamic/literal dir label for a layout.
342
+ * Default: noop.
343
+ */
344
+ emitResolveSegmentSpan: (segment: string) => void;
345
+
346
+ /**
347
+ * Wrap a route-handler invocation so compat emits the
348
+ * `executing api route (app) <route>` span (`AppRouteRouteHandlers.
349
+ * runHandler`). `route` is the core route PATTERN. Default: run `fn`.
350
+ */
351
+ withRouteHandlerSpan: <T>(route: string, fn: () => Promise<T>) => Promise<T>;
352
+ }
353
+
354
+ const renderSpanExtensions: RenderSpanExtensions = {
355
+ withRenderBodySpan: (_route, fn) => fn(),
356
+ withFindPageComponentsSpan: (_route, fn) => fn(),
357
+ emitResolveSegmentSpan: () => undefined,
358
+ withRouteHandlerSpan: (_route, fn) => fn(),
359
+ };
360
+
361
+ export function getRenderSpanExtensions(): RenderSpanExtensions {
362
+ return renderSpanExtensions;
363
+ }
364
+
365
+ export function setRenderSpanExtensions(overrides: Partial<RenderSpanExtensions>): void {
366
+ Object.assign(renderSpanExtensions, overrides);
367
+ }
368
+
369
+ // Compat populates every registry above at the bootstrap seam, exactly as it
370
+ // does the ones in src/extensions.ts — so they return to their core defaults
371
+ // with the extension host (one process serving two apps must not blend them).
372
+ for (const registry of [
373
+ fontExtensions,
374
+ suspenseExtensions,
375
+ streamRouteExtensions,
376
+ streamBoundaryExtensions,
377
+ metadataExtensions,
378
+ documentScriptExtensions,
379
+ staticParamsExtensions,
380
+ actionModuleExtensions,
381
+ renderSpanExtensions,
382
+ ]) {
383
+ restoreWithExtensionHost(registry);
384
+ }
@@ -0,0 +1 @@
1
+ export * from './renderer';
@@ -0,0 +1,47 @@
1
+ import { createContext } from 'preact';
2
+
3
+ // ---------------------------------------------------------------------------
4
+ // Per-island layout-segment context (CORE seam for compat useSelectedLayout-
5
+ // Segment(s), sibling to the layout-segment scope in render/slots.ts).
6
+ //
7
+ // A `'use client'` layout is hydrated as an island and so has no server-side
8
+ // layout-segment scope on the client. The renderer stamps each island rendered
9
+ // INSIDE a layout scope with a snapshot of that layout's position in the route
10
+ // (its `depth` = segments consumed at/above the layout, the resolved `segments`
11
+ // below it, and its parallel-route slot segments). The compat hook reads this
12
+ // context: on the server render it returns the resolved `segments`/`slots`
13
+ // (byte-exact SSR); on the client it recomputes the suffix live from `depth`
14
+ // and the current path so soft navigations (which keep a shared layout's island
15
+ // mounted and merely re-render it) stay correct.
16
+ //
17
+ // Kept in core (imports only `preact`) so both the renderer's SSR wrap and the
18
+ // entry's client mount reference the SAME context object without the core ->
19
+ // compat boundary edge, exactly like the currentLayoutSegments core seam.
20
+ // ---------------------------------------------------------------------------
21
+
22
+ export interface LayoutSegmentSnapshot {
23
+ /** Segments consumed AT or ABOVE the owning layout's directory. */
24
+ depth: number;
25
+ /** Resolved URL segments below the owning layout (server-side truth). */
26
+ segments: string[];
27
+ /** Resolved segments per parallel-route slot key (server-side truth). */
28
+ slots: Record<string, string[]>;
29
+ }
30
+
31
+ export const LayoutSegmentContext = createContext<LayoutSegmentSnapshot | null>(null);
32
+
33
+ // Per-island params snapshot (CORE seam for compat useParams).
34
+ //
35
+ // A `'use client'` component rendered inside a parallel-route slot subtree is SSR'd and hydrated as an
36
+ // island. Its useParams() must see the params visible at that point in the route - route params PLUS the
37
+ // enclosing slot's own dynamic/catch-all params - but the client island only carries the global route
38
+ // params, so the slot's params never reach it. The renderer stamps each island created inside a slot's
39
+ // params scope with a snapshot of the resolved params and re-provides it here; compat's useParams prefers
40
+ // this context when present.
41
+ //
42
+ // Kept in core (imports only `preact`) so both the renderer's SSR wrap and the entry's client mount
43
+ // reference the SAME context object, exactly like LayoutSegmentContext above.
44
+
45
+ export type RouteParamsSnapshot = Record<string, string | string[]>;
46
+
47
+ export const RouteParamsContext = createContext<RouteParamsSnapshot | null>(null);