@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,67 @@
1
+ // THE SINGLE COMPAT SEAM (CORE). The ONLY core module permitted a reference to the compat layer,
2
+ // and it does so through gated dynamic imports. Every other core file imports ZERO compat; they
3
+ // read behavior from the extension registry (src/extensions.ts) which compat populates here.
4
+ //
5
+ // Registration comes in two tiers, because importing the compat implementation graph costs far
6
+ // more than running the registrars themselves:
7
+ //
8
+ // bootstrapCompatBoot(config) - loads ./compat/register/boot ONLY: the facts core reads before
9
+ // it compiles anything (route conventions, page/CSS extensions, bare-specifier aliases, proxy
10
+ // file names, lifecycle hooks).
11
+ // bootstrapCompat(config) - loads ./compat/register/index: the full graph and every remaining
12
+ // registrar. Chains the boot tier first. `{ serve: true }` drops the build-only domains.
13
+ //
14
+ // Composition roots: build() and start() take the full tier; dev takes the boot tier at startup and
15
+ // the full tier on the first request. Both are idempotent under repeated and concurrent calls.
16
+ //
17
+ // The enablement gate is inlined here (a pure read of config.compat) rather than imported from
18
+ // compat, so this file carries no static edge into compat. It must stay in sync with
19
+ // compat/index.ts reactCompatEnabled/nextCompatEnabled.
20
+
21
+ import type { ResolvedConfig } from './config';
22
+ import { onExtensionHostReset } from './extensions';
23
+
24
+ /** True when either Next or React compatibility (or the React compiler) is on. */
25
+ function compatEnabled(config: ResolvedConfig): boolean {
26
+ const compat = config.compat;
27
+ return Boolean(compat?.next || compat?.react || compat?.reactCompiler);
28
+ }
29
+
30
+ let bootRegistration: Promise<void> | undefined;
31
+ let registration: Promise<void> | undefined;
32
+
33
+ // A fresh host has none of compat's registrations, so the "already registered"
34
+ // memo has to go with it — otherwise the next bootstrap call is a no-op and the
35
+ // host stays empty for the rest of the process.
36
+ onExtensionHostReset(() => {
37
+ bootRegistration = undefined;
38
+ registration = undefined;
39
+ });
40
+
41
+ /**
42
+ * Register the boot tier: the compat facts core consults before the first
43
+ * compile. No-op (and no compat code loaded) for a pure-core app.
44
+ */
45
+ export function bootstrapCompatBoot(config: ResolvedConfig): Promise<void> {
46
+ if (!compatEnabled(config)) return Promise.resolve();
47
+ bootRegistration ??= import('./compat/register/boot').then(module =>
48
+ module.registerCompatBootExtensions(config),
49
+ );
50
+ return bootRegistration;
51
+ }
52
+
53
+ /**
54
+ * Populate the core extension registries with compat behavior when compat is enabled. No-op, and no compat
55
+ * code loaded, for a pure-core app. Idempotent - the underlying dynamic import and registration run at most
56
+ * once per process.
57
+ */
58
+ export function bootstrapCompat(
59
+ config: ResolvedConfig,
60
+ options: { serve?: boolean } = {},
61
+ ): Promise<void> {
62
+ if (!compatEnabled(config)) return Promise.resolve();
63
+ registration ??= bootstrapCompatBoot(config)
64
+ .then(() => import('./compat/register/index'))
65
+ .then(module => module.registerCompatExtensions(config, options));
66
+ return registration;
67
+ }
package/src/config.ts ADDED
@@ -0,0 +1,218 @@
1
+ import { existsSync, realpathSync } from 'node:fs';
2
+ import { fileURLToPath, pathToFileURL } from 'node:url';
3
+ import path from 'node:path';
4
+ import { loadEnv } from './env';
5
+ import { findWorkspaceRoot } from './resolve/imports';
6
+ import type { PNextConfig } from './types';
7
+ import { setCacheComponents } from './ppr';
8
+
9
+ export type ResolvedConfig = Required<Pick<PNextConfig, 'outDir' | 'basePath'>> &
10
+ Omit<PNextConfig, 'outDir' | 'basePath'> & {
11
+ root: string;
12
+ workspaceRoot: string;
13
+ appDir: string;
14
+ publicDir: 'public';
15
+ appPath: string;
16
+ publicPath: string;
17
+ outPath: string;
18
+ };
19
+
20
+ const defaultConfig = {
21
+ outDir: '.pnext',
22
+ basePath: '',
23
+ } satisfies Required<Pick<PNextConfig, 'outDir' | 'basePath'>>;
24
+
25
+ // configSources seam. Core owns the shape; compat populates it.
26
+ //
27
+ // A configSource loads an external framework config (Next's next.config.*), applies its side effects (env,
28
+ // say), and returns the subset that maps onto pnext's core config. loadConfig invokes the registered
29
+ // source, if any, after resolving the pnext config and merges its overrides on top of the defaults.
30
+ //
31
+ // The Next source is registered from src/compat/register/config.ts. Because loadConfig runs at each
32
+ // composition root *before* bootstrapCompat, it also lazily loads that source itself through one gated
33
+ // dynamic import when compat.next is enabled - mirroring the compat-bootstrap gate so core keeps no static
34
+ // edge into compat.
35
+ export interface ConfigSourceOverrides {
36
+ basePath?: string;
37
+ trailingSlash?: boolean;
38
+ skipTrailingSlashRedirect?: boolean;
39
+ outDir?: string;
40
+ assetPrefix?: string;
41
+ productionBrowserSourceMaps?: boolean;
42
+ }
43
+ export type ConfigSource = (
44
+ root: string,
45
+ options: { dev?: boolean },
46
+ ) => Promise<ConfigSourceOverrides>;
47
+
48
+ let configSource: ConfigSource | undefined;
49
+
50
+ export function registerConfigSource(source: ConfigSource): void {
51
+ configSource = source;
52
+ }
53
+
54
+ async function resolveConfigSource(
55
+ config: PNextConfig,
56
+ root: string,
57
+ options: { dev?: boolean },
58
+ ): Promise<ConfigSourceOverrides> {
59
+ if (!config.compat?.next) return {};
60
+ if (!configSource) {
61
+ await import('./compat/register/config').then(module => module.registerConfigSource());
62
+ }
63
+ if (!configSource) return {};
64
+ return configSource(root, options);
65
+ }
66
+
67
+ export async function loadConfig(
68
+ rootInput = process.cwd(),
69
+ options: { dev?: boolean } = {},
70
+ ): Promise<ResolvedConfig> {
71
+ const root = canonicalRoot(path.resolve(rootInput));
72
+ await loadEnv(root, options);
73
+ const configPath = path.join(root, 'pnext.config.ts');
74
+ const loadedConfig = existsSync(configPath)
75
+ ? ((await import(pathToFileHref(configPath))) as { default?: PNextConfig })
76
+ : {};
77
+ const config: PNextConfig = {
78
+ ...(loadedConfig.default ?? {}),
79
+ // eslint-disable-next-line turbo/no-undeclared-env-vars
80
+ ...(process.env.PNEXT_COMPAT === 'next'
81
+ ? { compat: { ...(loadedConfig.default?.compat ?? {}), next: true } }
82
+ : {}),
83
+ };
84
+ // cacheComponents is a per-app flag on a process-global cell: clear it before
85
+ // the next.config source re-derives it, so a pure-core (or flag-off) app
86
+ // loaded after a cacheComponents app never inherits the previous build's flag.
87
+ setCacheComponents(false);
88
+ const sourceOverrides = stripUndefined(await resolveConfigSource(config, root, options));
89
+ const merged = { ...defaultConfig, ...config, ...sourceOverrides };
90
+ const appPath = await resolveAppPath(root, config);
91
+ const workspaceRoot = canonicalRoot(
92
+ config.workspaceRoot
93
+ ? path.resolve(root, config.workspaceRoot)
94
+ : (findWorkspaceRoot(root) ?? root),
95
+ );
96
+
97
+ return {
98
+ ...config,
99
+ trailingSlash: merged.trailingSlash ?? config.trailingSlash,
100
+ productionBrowserSourceMaps:
101
+ merged.productionBrowserSourceMaps ?? config.productionBrowserSourceMaps,
102
+ skipTrailingSlashRedirect: merged.skipTrailingSlashRedirect ?? config.skipTrailingSlashRedirect,
103
+ appDir: path.relative(root, appPath),
104
+ publicDir: 'public',
105
+ outDir: merged.outDir,
106
+ basePath: merged.basePath,
107
+ // Assets are addressed under basePath (the server 404s outside it), so an
108
+ // app that sets basePath without an explicit assetPrefix serves assets at
109
+ // `${basePath}/assets/...` — Next's default (assetPrefix falls back to
110
+ // basePath).
111
+ assetPrefix: merged.assetPrefix ?? merged.basePath,
112
+ root,
113
+ workspaceRoot,
114
+ appPath,
115
+ publicPath: path.resolve(root, 'public'),
116
+ outPath: path.resolve(root, merged.outDir),
117
+ };
118
+ }
119
+
120
+ // Relative-import resolution realpaths the importing file (so a materialized shim resolves `./sibling`
121
+ // against real source), so every containment check against root/workspaceRoot compares realpaths.
122
+ // Canonicalize the roots to match - otherwise an app served through a symlinked directory (a macOS
123
+ // tmpdir, a pnpm-linked checkout) reads as "outside the workspace" and its own source files stop
124
+ // resolving. A no-op when the path holds no symlinks.
125
+ function canonicalRoot(dir: string) {
126
+ try {
127
+ return realpathSync(dir);
128
+ } catch {
129
+ return dir;
130
+ }
131
+ }
132
+
133
+ function stripUndefined<T extends object>(value: T): T {
134
+ return Object.fromEntries(Object.entries(value).filter(([, v]) => v !== undefined)) as T;
135
+ }
136
+
137
+ export function pathToFileHref(filePath: string) {
138
+ // pathToFileURL percent-encodes literal special characters (notably `%`, so a
139
+ // directory physically named `%5Ffoo` on disk stays `%255Ffoo` in the href and
140
+ // import() decodes it back to the literal `%5Ffoo` rather than to `_foo`).
141
+ return pathToFileURL(path.resolve(filePath)).href;
142
+ }
143
+
144
+ export function publicEnvDefines() {
145
+ return Object.fromEntries(
146
+ [
147
+ // eslint-disable-next-line turbo/no-undeclared-env-vars
148
+ ['NODE_ENV', process.env.NODE_ENV ?? 'production'],
149
+ ...Object.entries(process.env).filter(
150
+ ([key]) => key.startsWith('NEXT_PUBLIC_') || key.startsWith('PNEXT_PUBLIC_'),
151
+ ),
152
+ ].map(([key, value]) => [
153
+ `process.env.${key}`,
154
+ value === undefined ? 'undefined' : JSON.stringify(value),
155
+ ]),
156
+ );
157
+ }
158
+
159
+ type FrameworkRuntimeAlias =
160
+ | 'preact'
161
+ | 'preact/hooks'
162
+ | 'preact/compat'
163
+ | 'preact/compat/client'
164
+ | 'preact/jsx-runtime'
165
+ | 'preact/jsx-dev-runtime'
166
+ | 'react-compiler-runtime';
167
+
168
+ export type CompatAliasTarget = 'server' | 'client';
169
+
170
+ /**
171
+ * Seven `import.meta.resolve` calls against the framework's OWN install - the answer cannot change for the
172
+ * life of the process, and every esbuild build builds an alias map (a vendor pass runs hundreds of those).
173
+ */
174
+ let frameworkRuntimeAliases: Record<FrameworkRuntimeAlias, string> | undefined;
175
+
176
+ export function frameworkRuntimeAliasEntries(): Record<FrameworkRuntimeAlias, string> {
177
+ frameworkRuntimeAliases ??= {
178
+ preact: resolveRuntimeModule('preact'),
179
+ 'preact/hooks': resolveRuntimeModule('preact/hooks'),
180
+ 'preact/compat': resolveRuntimeModule('preact/compat'),
181
+ 'preact/compat/client': resolveRuntimeModule('preact/compat/client'),
182
+ 'preact/jsx-runtime': resolveRuntimeModule('preact/jsx-runtime'),
183
+ 'preact/jsx-dev-runtime': resolveRuntimeModule('preact/jsx-dev-runtime'),
184
+ 'react-compiler-runtime': resolveRuntimeModule('react-compiler-runtime'),
185
+ };
186
+ return frameworkRuntimeAliases;
187
+ }
188
+
189
+ function resolveRuntimeModule(specifier: string) {
190
+ return fileURLToPath(import.meta.resolve(specifier));
191
+ }
192
+
193
+ export function pnextAliases(target: CompatAliasTarget): Record<string, string> {
194
+ if (target !== 'client') return {};
195
+ return {
196
+ '@wular/pnext/cache': path.resolve(import.meta.dirname, 'api/client-cache.ts'),
197
+ };
198
+ }
199
+
200
+ async function resolveAppPath(root: string, config: PNextConfig) {
201
+ const rootApp = path.join(root, 'app');
202
+ if (config.compat?.next) {
203
+ const pagesPath = path.join(root, 'pages');
204
+ const hasPages = existsSync(pagesPath);
205
+ if (existsSync(rootApp)) {
206
+ if (hasPages) {
207
+ const { materializePagesApp } = await import('./compat/pages');
208
+ const hybrid = await materializePagesApp(root);
209
+ if (hybrid) return hybrid;
210
+ }
211
+ return rootApp;
212
+ }
213
+ const { materializePagesApp } = await import('./compat/pages');
214
+ const pagesApp = await materializePagesApp(root);
215
+ if (pagesApp) return pagesApp;
216
+ } else if (existsSync(rootApp)) return rootApp;
217
+ return path.join(root, 'src', 'app');
218
+ }