@wular/pnext 0.0.4 → 0.0.7

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 (395) hide show
  1. package/README.md +22 -16
  2. package/bin/pnext +6 -1
  3. package/config/lint/base.js +7 -7
  4. package/config/ts/base.json +2 -4
  5. package/config/ts/react.json +2 -6
  6. package/package.json +23 -2
  7. package/reference/compat.md +87 -22
  8. package/reference/config.md +40 -93
  9. package/reference/css.md +42 -33
  10. package/reference/dev.md +26 -33
  11. package/reference/env.md +18 -20
  12. package/reference/getting-started.md +132 -0
  13. package/reference/metadata.md +31 -46
  14. package/reference/navigation.md +65 -105
  15. package/reference/performance.md +21 -142
  16. package/reference/rendering.md +78 -75
  17. package/reference/routing.md +97 -107
  18. package/reference/typegen.md +27 -29
  19. package/src/api/cache.ts +36 -37
  20. package/src/api/client-cache.ts +2 -2
  21. package/src/api/client-navigation.ts +121 -114
  22. package/src/api/dynamic.tsx +58 -55
  23. package/src/api/link.tsx +52 -53
  24. package/src/api/navigation.ts +59 -58
  25. package/src/api/server.ts +152 -144
  26. package/src/api/suspense.ts +4 -4
  27. package/src/cli/adapters/vercel-warm.ts +126 -121
  28. package/src/cli/adapters/vercel.ts +437 -443
  29. package/src/cli/analyze.ts +333 -144
  30. package/src/cli/{named-bin.ts → boot/named-bin.ts} +37 -37
  31. package/src/cli/{boot-trace.ts → boot/trace.ts} +10 -10
  32. package/src/cli/build.ts +976 -978
  33. package/src/cli/create.ts +72 -64
  34. package/src/cli/dev.ts +116 -116
  35. package/src/cli/index.ts +94 -85
  36. package/src/cli/migrate/package-json.ts +73 -71
  37. package/src/cli/migrate/report.ts +32 -33
  38. package/src/cli/migrate/{index.ts → run.ts} +48 -49
  39. package/src/cli/migrate/scan.ts +46 -46
  40. package/src/cli/migrate/spinner.ts +9 -9
  41. package/src/cli/migrate/tsconfig.ts +35 -35
  42. package/src/cli/{server-entry.ts → serve/entry.ts} +57 -57
  43. package/src/cli/{request-pipeline.ts → serve/pipeline.ts} +386 -394
  44. package/src/cli/{serve-ui.ts → serve/ui.ts} +47 -47
  45. package/src/cli/start.ts +65 -66
  46. package/src/{typegen.ts → cli/typegen.ts} +59 -59
  47. package/src/client/build.ts +802 -768
  48. package/src/client/chunk-fold.ts +245 -240
  49. package/src/client/{paths.ts → chunk-name.ts} +6 -6
  50. package/src/client/entry.ts +162 -147
  51. package/src/client/prebuilt.ts +231 -223
  52. package/src/client/profile.ts +29 -29
  53. package/src/client/react-compiler.ts +20 -15
  54. package/src/client/{compat-surface.ts → react-tier.ts} +64 -64
  55. package/src/client/reference-stub.ts +51 -51
  56. package/src/client/reference.ts +19 -19
  57. package/src/{api → client}/router/events.ts +32 -17
  58. package/src/{api → client}/router/history.ts +16 -16
  59. package/src/{api → client}/router/hub.ts +52 -53
  60. package/src/{api/router.ts → client/router/index.ts} +61 -60
  61. package/src/{api → client}/router/policies.ts +24 -24
  62. package/src/{api → client}/router/runtime.ts +2022 -1995
  63. package/src/{api → client}/router/types.ts +98 -98
  64. package/src/compat/actions/client-plugin.ts +42 -43
  65. package/src/compat/actions/client-stub.ts +14 -14
  66. package/src/compat/actions/{action-client.ts → client.ts} +194 -193
  67. package/src/compat/actions/config.ts +63 -64
  68. package/src/compat/actions/detect.ts +68 -68
  69. package/src/compat/actions/discovery.ts +105 -105
  70. package/src/compat/actions/{action-dispatch.ts → dispatch.ts} +277 -274
  71. package/src/compat/actions/early-submit.ts +1 -1
  72. package/src/compat/actions/endpoint.ts +198 -198
  73. package/src/compat/actions/extensions.ts +811 -0
  74. package/src/compat/actions/flight.ts +23 -23
  75. package/src/compat/actions/form-state.ts +34 -34
  76. package/src/compat/actions/hoist.ts +382 -236
  77. package/src/compat/actions/ids.ts +7 -12
  78. package/src/compat/actions/index.ts +8 -8
  79. package/src/compat/actions/instances.ts +46 -46
  80. package/src/compat/actions/origin.ts +47 -48
  81. package/src/compat/actions/protocol.ts +22 -22
  82. package/src/compat/actions/registry.ts +19 -19
  83. package/src/compat/{misc/action-return.ts → actions/return.ts} +60 -57
  84. package/src/compat/actions/rewrite.ts +125 -125
  85. package/src/compat/actions/{action-router.ts → router.ts} +10 -10
  86. package/src/compat/actions/serve.ts +132 -136
  87. package/src/compat/actions/server-tag.ts +4 -4
  88. package/src/compat/actions/{action-shared.ts → shared.ts} +34 -34
  89. package/src/compat/actions/unrecognized-error.ts +4 -4
  90. package/src/compat/{index.ts → aliases.ts} +112 -109
  91. package/src/compat/bundler/bun-externals.ts +18 -18
  92. package/src/compat/bundler/cjs-exports.ts +271 -223
  93. package/src/compat/bundler/config.ts +116 -111
  94. package/src/compat/bundler/externals.ts +12 -12
  95. package/src/compat/bundler/import-meta-url.ts +19 -19
  96. package/src/compat/bundler/modularize-imports.ts +36 -33
  97. package/src/compat/bundler/new-url-asset.ts +22 -24
  98. package/src/compat/bundler/optimize-package-imports.ts +111 -107
  99. package/src/compat/bundler/polyfill.ts +28 -28
  100. package/src/compat/bundler/react-compiler.ts +35 -29
  101. package/src/compat/bundler/react-profiler.tsx +11 -11
  102. package/src/compat/bundler/relay-transform.ts +48 -47
  103. package/src/compat/bundler/require-context.ts +119 -113
  104. package/src/compat/bundler/resolve-extensions.ts +19 -19
  105. package/src/compat/bundler/source-cache.ts +25 -25
  106. package/src/compat/bundler/static-imports.ts +7 -7
  107. package/src/compat/bundler/symlink-imports.ts +46 -46
  108. package/src/compat/bundler/tsconfig-paths.ts +13 -15
  109. package/src/compat/bundler/wasm.ts +58 -60
  110. package/src/compat/bundler/webpack-loaders.ts +254 -241
  111. package/src/compat/bundler/worker.ts +101 -104
  112. package/src/compat/cache/build-flags.ts +29 -29
  113. package/src/compat/cache/build-prerender-errors.ts +40 -44
  114. package/src/compat/cache/custom-handler.ts +60 -53
  115. package/src/compat/cache/fetch-patch.ts +240 -240
  116. package/src/compat/cache/handler.ts +27 -31
  117. package/src/compat/cache/modern-handler.ts +148 -126
  118. package/src/compat/cache/resume-data-cache.ts +47 -45
  119. package/src/compat/cache/revalidate.ts +233 -232
  120. package/src/compat/cache/runtime-error.ts +35 -35
  121. package/src/compat/cache/use-cache-transform.ts +442 -417
  122. package/src/compat/cache/use-cache.ts +650 -614
  123. package/src/compat/cache-control.ts +140 -142
  124. package/src/compat/client/base-path.ts +21 -20
  125. package/src/compat/client/css-order.ts +18 -18
  126. package/src/compat/client/errors/bare-boundary.ts +11 -11
  127. package/src/compat/client/errors/control-flow.ts +23 -23
  128. package/src/compat/client/errors/error-boundary.ts +61 -61
  129. package/src/compat/client/errors/global-error.ts +101 -91
  130. package/src/compat/client/errors/install.ts +71 -72
  131. package/src/compat/client/errors/lazy.ts +23 -23
  132. package/src/compat/client/errors/primitive-throw.ts +47 -45
  133. package/src/compat/client/errors/soft-refresh.ts +4 -4
  134. package/src/compat/client/link-status.ts +33 -33
  135. package/src/compat/client/{nav-compat-runtime.ts → nav-runtime.ts} +20 -20
  136. package/src/compat/client/{nav-compat.ts → nav.ts} +12 -13
  137. package/src/compat/client/navigation-scroll.ts +63 -63
  138. package/src/compat/client/optimistic-routing.ts +93 -88
  139. package/src/compat/client/prefetch-cache.ts +23 -24
  140. package/src/compat/client/route-announcer.ts +35 -35
  141. package/src/compat/client/segment-cache-policy.ts +20 -20
  142. package/src/compat/client/segment-cache.ts +309 -315
  143. package/src/compat/client/segment-prefetch.ts +127 -132
  144. package/src/compat/client/trailing-slash.ts +5 -4
  145. package/src/compat/css/chunking.ts +113 -116
  146. package/src/compat/css/inline-css.ts +21 -21
  147. package/src/compat/css/lightningcss.ts +37 -38
  148. package/src/compat/css/modules.ts +161 -175
  149. package/src/compat/css/nonce.ts +7 -7
  150. package/src/compat/css/sass-plugin.ts +18 -21
  151. package/src/compat/css/sass.ts +150 -152
  152. package/src/compat/css/styled-jsx-runtime.ts +27 -27
  153. package/src/compat/css/styled-jsx.ts +21 -21
  154. package/src/compat/edge-runtime.ts +27 -27
  155. package/src/compat/{adapter → export}/build-complete.ts +72 -75
  156. package/src/compat/export/client.ts +29 -31
  157. package/src/compat/export/{index.ts → emit.ts} +111 -110
  158. package/src/compat/export/standalone.ts +62 -54
  159. package/src/compat/image-optimizer/cache.ts +51 -49
  160. package/src/compat/image-optimizer/detect.ts +52 -52
  161. package/src/compat/image-optimizer/{index.ts → optimize.ts} +189 -194
  162. package/src/compat/image-optimizer/source.ts +77 -80
  163. package/src/compat/lifecycle/after-scope.ts +26 -26
  164. package/src/compat/lifecycle/after.ts +48 -45
  165. package/src/compat/lifecycle/error-funnel.ts +98 -102
  166. package/src/compat/lifecycle/error-serialize.ts +30 -26
  167. package/src/compat/lifecycle/error-ui.ts +67 -32
  168. package/src/compat/lifecycle/instrumentation-client.ts +36 -38
  169. package/src/compat/lifecycle/instrumentation.ts +85 -85
  170. package/src/compat/lifecycle/node-console.ts +11 -11
  171. package/src/compat/lifecycle/testmode.ts +160 -132
  172. package/src/compat/mdx/compile.ts +60 -57
  173. package/src/compat/mdx/plugin.ts +11 -11
  174. package/src/compat/mdx/{next-mdx-stub.ts → stub.ts} +5 -5
  175. package/src/compat/{metadata-route-artifacts.ts → metadata-artifacts.ts} +195 -191
  176. package/src/compat/metadata.ts +75 -81
  177. package/src/compat/next/cache.ts +68 -69
  178. package/src/compat/next/canonical-url.ts +9 -9
  179. package/src/compat/next/client-cache.ts +19 -19
  180. package/src/compat/next/client-navigation.ts +112 -116
  181. package/src/compat/next/client-only.ts +1 -1
  182. package/src/compat/next/client-script.tsx +99 -93
  183. package/src/compat/next/client-server.ts +10 -10
  184. package/src/compat/next/config-loader.ts +176 -173
  185. package/src/compat/next/config.ts +7 -7
  186. package/src/compat/next/constants.cjs +6 -6
  187. package/src/compat/next/constants.ts +6 -6
  188. package/src/compat/next/custom-server.ts +26 -24
  189. package/src/compat/next/dist/client/components/app-router-headers.ts +21 -21
  190. package/src/compat/next/dist/server/app-render/work-unit-async-storage.external.cjs +3 -4
  191. package/src/compat/next/dist/server/web/spec-extension/revalidate.ts +1 -1
  192. package/src/compat/next/dist/server/web/spec-extension/unstable-cache.ts +1 -1
  193. package/src/compat/next/dist/server/web/spec-extension/unstable-no-store.ts +1 -1
  194. package/src/compat/next/dynamic.tsx +21 -18
  195. package/src/compat/next/error.tsx +52 -52
  196. package/src/compat/next/font/cache.ts +74 -74
  197. package/src/compat/next/font/google.ts +2 -2
  198. package/src/compat/next/font/index.ts +1 -1
  199. package/src/compat/next/font/local.ts +3 -3
  200. package/src/compat/next/font/runtime-client.ts +17 -15
  201. package/src/compat/next/font/runtime.ts +443 -408
  202. package/src/compat/next/font/shared.ts +120 -108
  203. package/src/compat/next/form.tsx +63 -63
  204. package/src/compat/next/head.tsx +2 -2
  205. package/src/compat/next/headers.ts +103 -95
  206. package/src/compat/next/image/client.tsx +220 -0
  207. package/src/compat/next/image/config.ts +56 -58
  208. package/src/compat/next/image/optimizer.ts +40 -36
  209. package/src/compat/next/image/patterns.ts +37 -40
  210. package/src/compat/next/{image-props.ts → image/props.ts} +208 -202
  211. package/src/compat/next/image/shared.ts +65 -57
  212. package/src/compat/next/image/static-metadata.ts +98 -107
  213. package/src/compat/next/image/validate.ts +79 -88
  214. package/src/compat/next/image.tsx +19 -23
  215. package/src/compat/next/index.ts +1 -1
  216. package/src/compat/next/legacy-image.tsx +59 -60
  217. package/src/compat/next/{link-validation-transform.ts → link-transform.ts} +95 -96
  218. package/src/compat/next/link.tsx +158 -158
  219. package/src/compat/next/navigation.cjs +12 -3
  220. package/src/compat/next/navigation.ts +48 -50
  221. package/src/compat/next/offline.ts +27 -27
  222. package/src/compat/next/og.ts +121 -124
  223. package/src/compat/next/preferred-region.ts +13 -14
  224. package/src/compat/next/redirects.ts +58 -56
  225. package/src/compat/next/resource-hints.ts +73 -76
  226. package/src/compat/next/rewrites.ts +130 -133
  227. package/src/compat/next/root-params.ts +45 -45
  228. package/src/compat/next/{optimistic-route-state.ts → route-state.ts} +52 -52
  229. package/src/compat/next/router.cjs +4 -2
  230. package/src/compat/next/router.ts +58 -61
  231. package/src/compat/next/script.tsx +108 -108
  232. package/src/compat/next/server-only.ts +1 -1
  233. package/src/compat/next/server.ts +19 -19
  234. package/src/compat/next/svgr.ts +18 -17
  235. package/src/compat/next/telemetry.ts +24 -24
  236. package/src/compat/next/{image-usage.ts → usage.ts} +70 -39
  237. package/src/compat/next/user-agent.ts +53 -49
  238. package/src/compat/next/web-vitals.ts +22 -24
  239. package/src/compat/otel/api.ts +41 -41
  240. package/src/compat/otel/client-trace-metadata.ts +25 -27
  241. package/src/compat/otel/fetch-span.ts +29 -29
  242. package/src/compat/otel/tracer.ts +331 -331
  243. package/src/compat/pages/api.ts +456 -0
  244. package/src/compat/pages/client-plugin.ts +36 -36
  245. package/src/compat/pages/router-state.ts +34 -34
  246. package/src/compat/pages/{index.ts → router.ts} +130 -135
  247. package/src/compat/ppr/io.ts +12 -12
  248. package/src/compat/ppr/missing-root-params.ts +34 -38
  249. package/src/compat/ppr/root-params-scan.ts +66 -66
  250. package/src/compat/ppr/root-params-transform.ts +24 -26
  251. package/src/compat/ppr/root-params.ts +30 -30
  252. package/src/compat/ppr/segment-config-incompat.ts +6 -7
  253. package/src/compat/protocol.ts +71 -70
  254. package/src/compat/react/action-state.ts +47 -48
  255. package/src/compat/react/client-lite.ts +15 -15
  256. package/src/compat/react/client.ts +4 -4
  257. package/src/compat/react/compiler-runtime.ts +11 -11
  258. package/src/compat/react/dom-client.ts +44 -44
  259. package/src/compat/react/dom-react-server.ts +10 -16
  260. package/src/compat/react/dom-server.ts +10 -10
  261. package/src/compat/react/dom.ts +52 -52
  262. package/src/compat/react/hooks-extra.ts +34 -35
  263. package/src/compat/react/parity.ts +64 -61
  264. package/src/compat/react/preact.ts +81 -82
  265. package/src/compat/react/react-server.ts +28 -28
  266. package/src/compat/react/router-shim.ts +1 -1
  267. package/src/compat/react/server-component-use.ts +8 -8
  268. package/src/compat/react/server-inserted-html.ts +30 -31
  269. package/src/compat/react/server.ts +53 -55
  270. package/src/compat/react/use.ts +32 -32
  271. package/src/compat/react/view-transition.ts +20 -20
  272. package/src/compat/register/actions.ts +35 -824
  273. package/src/compat/register/boot.ts +41 -41
  274. package/src/compat/register/build-tier.ts +5 -5
  275. package/src/compat/register/build.ts +74 -70
  276. package/src/compat/register/bundler.ts +161 -156
  277. package/src/compat/register/cache.ts +20 -20
  278. package/src/compat/register/client-errors.ts +3 -3
  279. package/src/compat/register/config.ts +6 -6
  280. package/src/compat/register/css-extras.ts +30 -34
  281. package/src/compat/register/edge-runtime.ts +3 -3
  282. package/src/compat/register/errors.ts +10 -12
  283. package/src/compat/register/export.ts +16 -16
  284. package/src/compat/register/font.ts +11 -11
  285. package/src/compat/register/hooks.ts +2 -2
  286. package/src/compat/register/image.ts +40 -40
  287. package/src/compat/register/index.ts +59 -62
  288. package/src/compat/register/instrumentation-client.ts +10 -10
  289. package/src/compat/register/lifecycle.ts +25 -28
  290. package/src/compat/register/mdx.ts +10 -10
  291. package/src/compat/register/middleware.ts +226 -16
  292. package/src/compat/register/otel.ts +80 -88
  293. package/src/compat/register/pages-api.ts +10 -463
  294. package/src/compat/register/ppr.ts +16 -16
  295. package/src/compat/register/protocol.ts +17 -18
  296. package/src/compat/register/proxy.ts +49 -51
  297. package/src/compat/register/render.ts +79 -76
  298. package/src/compat/register/routing.ts +162 -159
  299. package/src/compat/register/segment.ts +24 -1897
  300. package/src/compat/register/static-image.ts +3 -3
  301. package/src/compat/register/{misc.ts → taint.ts} +9 -9
  302. package/src/compat/register/typed-routes.ts +14 -14
  303. package/src/compat/register/{usecache.ts → use-cache.ts} +39 -39
  304. package/src/compat/register/validation.ts +18 -18
  305. package/src/compat/segment/loading-boundary.ts +43 -45
  306. package/src/compat/segment/page-slot.ts +69 -69
  307. package/src/compat/segment/serve.ts +1884 -0
  308. package/src/compat/segment/tree.ts +113 -112
  309. package/src/compat/segment/vary-key.ts +38 -38
  310. package/src/compat/segment/vary-params.ts +138 -142
  311. package/src/compat/static-params.ts +14 -12
  312. package/src/compat/tsconfig-defaults.ts +87 -91
  313. package/src/compat/typecheck/{index.ts → check.ts} +234 -212
  314. package/src/compat/typecheck/worker.ts +15 -12
  315. package/src/compat/typed-routes/{index.ts → generate.ts} +36 -36
  316. package/src/compat/typed-routes/manifest.ts +174 -170
  317. package/src/compat/typed-routes/typegen.ts +127 -110
  318. package/src/compat/validation/errors.ts +16 -19
  319. package/src/compat/validation/prerender-diagnostics.ts +521 -504
  320. package/src/compat/validation/{index.ts → validate.ts} +647 -648
  321. package/src/compat-bootstrap.ts +16 -16
  322. package/src/config.ts +86 -69
  323. package/src/css/build.ts +230 -227
  324. package/src/css/postcss.ts +79 -80
  325. package/src/css/worker.ts +14 -15
  326. package/src/dev/client-actions.ts +10 -10
  327. package/src/dev/client-chunk-store.ts +27 -27
  328. package/src/dev/{client-key-cache.ts → restart/client-key.ts} +76 -76
  329. package/src/dev/{restart-cache.ts → restart/enabled.ts} +1 -1
  330. package/src/dev/{global-css-cache.ts → restart/global-css.ts} +91 -83
  331. package/src/dev/{node-module-bundle-cache.ts → restart/node-modules.ts} +24 -24
  332. package/src/dev/{route-bundle-key-cache.ts → restart/route-bundle-key.ts} +53 -53
  333. package/src/dev/{route-facts-cache.ts → restart/route-facts.ts} +82 -82
  334. package/src/dev/server.ts +804 -820
  335. package/src/env.ts +46 -43
  336. package/src/extensions.ts +491 -478
  337. package/src/index.ts +8 -8
  338. package/src/internal.ts +20 -23
  339. package/src/{islands → render}/boundary-error.ts +3 -3
  340. package/src/render/hooks.ts +71 -71
  341. package/src/render/island-context.ts +14 -14
  342. package/src/render/metadata.ts +310 -310
  343. package/src/{ppr-postpone.ts → render/postpone.ts} +5 -5
  344. package/src/{ppr.ts → render/ppr.ts} +244 -245
  345. package/src/render/renderer.ts +2087 -2082
  346. package/src/render/resource-hints.ts +16 -17
  347. package/src/render/slots.tsx +224 -235
  348. package/src/{islands → render}/static-children.ts +9 -12
  349. package/src/{islands → render}/static-slots.ts +37 -37
  350. package/src/{cache/context.ts → request/cache.ts} +20 -20
  351. package/src/request/context.ts +107 -107
  352. package/src/{dynamic/source.ts → resolve/dynamic.ts} +139 -139
  353. package/src/resolve/engine.ts +90 -77
  354. package/src/resolve/imports.ts +475 -463
  355. package/src/resolve/scan-facts.ts +318 -296
  356. package/src/resolve/source-text.ts +37 -37
  357. package/src/{dynamic → resolve}/tree-shake.ts +132 -128
  358. package/src/routing/forwarded.ts +19 -19
  359. package/src/routing/handler.ts +84 -91
  360. package/src/routing/href.ts +87 -70
  361. package/src/routing/{metadata.ts → metadata-files.ts} +403 -401
  362. package/src/{proxy.ts → routing/proxy.ts} +306 -312
  363. package/src/routing/{request-runtime.ts → request-environment.ts} +10 -10
  364. package/src/routing/routes.ts +827 -815
  365. package/src/routing/slots.ts +164 -160
  366. package/src/runtime/loader.ts +954 -0
  367. package/src/{dev → runtime}/module-cache.ts +309 -287
  368. package/src/{dev → runtime}/module-generations.ts +9 -9
  369. package/src/{dev → runtime}/module-transform.ts +81 -72
  370. package/src/{dev/imports.ts → runtime/modules.ts} +934 -847
  371. package/src/runtime/{server.ts → vendor-build.ts} +848 -1696
  372. package/src/runtime/vendor.ts +428 -406
  373. package/src/styles.d.ts +9 -0
  374. package/src/types.ts +324 -335
  375. package/src/utils/ansi.ts +5 -5
  376. package/src/utils/{source.ts → code.ts} +15 -12
  377. package/src/utils/content-type.ts +3 -3
  378. package/src/utils/decode.ts +2 -2
  379. package/src/utils/dev-profile.ts +13 -13
  380. package/src/utils/error-log.ts +6 -6
  381. package/src/utils/esbuild.ts +18 -18
  382. package/src/utils/fs-cache.ts +13 -13
  383. package/src/utils/fs.ts +57 -49
  384. package/src/utils/html.ts +20 -24
  385. package/src/utils/native-require.ts +8 -8
  386. package/src/utils/serialize.ts +139 -146
  387. package/src/utils/verbose.ts +18 -18
  388. package/reference/overview.md +0 -35
  389. package/src/cli/analyze-print.ts +0 -181
  390. package/src/compat/middleware/manifest.ts +0 -210
  391. package/src/compat/next/image-client.tsx +0 -215
  392. package/src/compat/next/link-usage.ts +0 -29
  393. package/src/css/index.ts +0 -2
  394. package/src/render/index.ts +0 -1
  395. package/src/style-modules.d.ts +0 -9
@@ -1,41 +1,41 @@
1
- import path from 'node:path';
2
- import type { ClientReference } from './reference';
3
- import { ISLAND_STATIC_CHILDREN_ATTRIBUTE } from '../islands/static-children';
1
+ import path from 'node:path'
2
+ import type { ClientReference } from './reference'
3
+ import { ISLAND_STATIC_CHILDREN_ATTRIBUTE } from '../render/static-children'
4
4
  import {
5
5
  ISLAND_BOUNDARY_ERROR_DIGEST_ATTRIBUTE,
6
6
  ISLAND_BOUNDARY_ERROR_ELEMENT,
7
7
  ISLAND_BOUNDARY_ERROR_MESSAGE_ATTRIBUTE,
8
- } from '../islands/boundary-error';
8
+ } from '../render/boundary-error'
9
9
 
10
10
  interface ClientEntryOptions {
11
- pageFile?: string;
12
- clientReferences: ClientReference[];
13
- nextCompat?: boolean;
11
+ pageFile?: string
12
+ clientReferences: ClientReference[]
13
+ nextCompat?: boolean
14
14
  /** See ClientRuntimeFacts.suspense; false drops the Suspense island wrapper (and preact/compat). */
15
- suspense?: boolean;
15
+ suspense?: boolean
16
16
  /**
17
17
  * The app reaches a server action anywhere (build's action manifest, or a route whose scan
18
18
  * recorded the `actions`/`form` client-entry reason). The whole action client runtime - RPC wire,
19
19
  * form interception, prop revival, error overlay - is emitted only then.
20
20
  */
21
- actions?: boolean;
21
+ actions?: boolean
22
22
  /** Route's nearest error.* file: rendered as the action-error overlay (compat). */
23
- errorFile?: string;
23
+ errorFile?: string
24
24
  /** Route's nearest not-found.* file: rendered for client-side notFound(). */
25
- notFoundFile?: string;
25
+ notFoundFile?: string
26
26
  /**
27
27
  * A `'use client'` module in the route graph throws notFound()/forbidden()/
28
28
  * unauthorized(). The boundary then has something to render (its built-in
29
29
  * 404) even with no not-found.* file, so it must ship for this route.
30
30
  */
31
- controlFlow?: boolean;
31
+ controlFlow?: boolean
32
32
  /**
33
33
  * App-root global-error.* file (compat): passed to installClientErrors as the
34
34
  * globalErrorComponent so a user global-error mounts for client throws that
35
35
  * escape every route error boundary. Threaded by client/build.ts; consumed by
36
- * routerImportSource + mountLifecycleSource (mount-section coder owns wiring).
36
+ * routerImportSource + mountLifecycleSource (the mount section owns the wiring).
37
37
  */
38
- globalErrorFile?: string;
38
+ globalErrorFile?: string
39
39
  /**
40
40
  * The route's root layout is itself a `'use client'` component. Only then does the whole document
41
41
  * body need re-rendering through that layout at hydration (the client-shell path, which adopts each
@@ -43,29 +43,29 @@ interface ClientEntryOptions {
43
43
  * client references are ordinary nested/slot islands that mount into their own containers, and
44
44
  * building a shell would wrongly remount the body under one of those islands.
45
45
  */
46
- clientRootLayout?: boolean;
46
+ clientRootLayout?: boolean
47
47
  /**
48
48
  * Some file in this route's closure can reach a soft navigation (a Link, a navigation hook, compat
49
49
  * parity). False means no click on this page can ever start one, so the entry ships no router.
50
50
  */
51
- router?: boolean;
51
+ router?: boolean
52
52
  /**
53
53
  * Layout files outermost-first; the shell nests in this order because
54
54
  * `clientReferences` is path-hash sorted (see build.ts shellLayoutOrder).
55
55
  */
56
- shellLayoutOrder?: string[];
56
+ shellLayoutOrder?: string[]
57
57
  /**
58
58
  * Dev split: the served URL a deferred dynamic reference loads from instead
59
59
  * of bundling its target into this entry (see buildClientDynamicChunk).
60
60
  */
61
- deferredDynamicHref?: (reference: ClientReference) => string | undefined;
61
+ deferredDynamicHref?: (reference: ClientReference) => string | undefined
62
62
  }
63
63
 
64
64
  // The soft-navigation runtime is bundled into every entry from this source
65
65
  // file; esbuild resolves the absolute path, so entries share the module (and
66
66
  // its prefetch/navigation state) through the common chunk graph.
67
67
  function routerModulePath() {
68
- return path.join(import.meta.dirname, '../api/router.ts');
68
+ return path.join(import.meta.dirname, './router/index.ts')
69
69
  }
70
70
 
71
71
  // Server-action client runtime lives in the compat layer (only ever imported
@@ -73,29 +73,29 @@ function routerModulePath() {
73
73
  // core but emits these as generated import strings, gated on nextCompat, so
74
74
  // core carries no static import of compat.
75
75
  function actionRouterModulePath() {
76
- return path.join(import.meta.dirname, '../compat/actions/action-router.ts');
76
+ return path.join(import.meta.dirname, '../compat/actions/router.ts')
77
77
  }
78
78
 
79
79
  function actionClientModulePath() {
80
- return path.join(import.meta.dirname, '../compat/actions/action-client.ts');
80
+ return path.join(import.meta.dirname, '../compat/actions/client.ts')
81
81
  }
82
82
 
83
83
  function navCompatModulePath() {
84
- return path.join(import.meta.dirname, '../compat/client/nav-compat.ts');
84
+ return path.join(import.meta.dirname, '../compat/client/nav.ts')
85
85
  }
86
86
 
87
87
  function islandContextModulePath() {
88
- return path.join(import.meta.dirname, '../render/island-context.ts');
88
+ return path.join(import.meta.dirname, '../render/island-context.ts')
89
89
  }
90
90
 
91
91
  // Wire-marker revival shared with the server encoder (utils/serialize.ts):
92
92
  // island props carrying a CYCLE travel as `$$pnext_ref` back-references.
93
93
  function staticSlotsModulePath() {
94
- return path.join(import.meta.dirname, '../islands/static-slots.ts');
94
+ return path.join(import.meta.dirname, '../render/static-slots.ts')
95
95
  }
96
96
 
97
97
  function serializeModulePath() {
98
- return path.join(import.meta.dirname, '../utils/serialize.ts');
98
+ return path.join(import.meta.dirname, '../utils/serialize.ts')
99
99
  }
100
100
 
101
101
  // Re-provide the per-island layout-segment snapshot (stamped by the renderer as
@@ -103,7 +103,7 @@ function serializeModulePath() {
103
103
  // useSelectedLayoutSegment(s) recomputes live from the layout depth. Emitted
104
104
  // only under next compat (the hooks are compat-only); a no-op wrapper otherwise.
105
105
  function layoutSegmentHelperSource(nextCompat?: boolean) {
106
- if (!nextCompat) return '';
106
+ if (!nextCompat) return ''
107
107
  return `
108
108
  import { LayoutSegmentContext as __PNextLayoutSegmentContext, RouteParamsContext as __PNextRouteParamsContext } from ${JSON.stringify(islandContextModulePath())};
109
109
  function pnextIslandReadJson(root, attr) {
@@ -121,7 +121,7 @@ function pnextIslandVNode(h, Component, props, children, root) {
121
121
  if (params) vnode = h(__PNextRouteParamsContext.Provider, { value: params }, vnode);
122
122
  return vnode;
123
123
  }
124
- `;
124
+ `
125
125
  }
126
126
 
127
127
  function islandVNodeExpr(
@@ -133,7 +133,7 @@ function islandVNodeExpr(
133
133
  ) {
134
134
  return nextCompat
135
135
  ? `pnextIslandVNode(h, ${componentExpr}, ${propsExpr}, ${childrenExpr}, ${rootExpr})`
136
- : `h(${componentExpr}, ${propsExpr}, ${childrenExpr})`;
136
+ : `h(${componentExpr}, ${propsExpr}, ${childrenExpr})`
137
137
  }
138
138
 
139
139
  // Two mount passes can reach the same island root concurrently - mountRoute and the streamed-Suspense
@@ -159,7 +159,7 @@ async function mountIslandOnce(root, mountTree) {
159
159
  if (root.__pnextMounting === mounting) root.__pnextMounting = undefined;
160
160
  }
161
161
  }
162
- `;
162
+ `
163
163
  }
164
164
 
165
165
  // Error seams, imported from their leaf modules rather than through a barrel:
@@ -167,19 +167,19 @@ async function mountIslandOnce(root, mountTree) {
167
167
  // barrel re-export would drag the boundary into first paint even for an entry
168
168
  // that never names it.
169
169
  function clientErrorsInstallPath() {
170
- return path.join(import.meta.dirname, '../compat/client/errors/lazy.ts');
170
+ return path.join(import.meta.dirname, '../compat/client/errors/lazy.ts')
171
171
  }
172
172
 
173
173
  function clientErrorBoundaryPath() {
174
- return path.join(import.meta.dirname, '../compat/client/errors/error-boundary.ts');
174
+ return path.join(import.meta.dirname, '../compat/client/errors/error-boundary.ts')
175
175
  }
176
176
 
177
177
  function softRefreshModulePath() {
178
- return path.join(import.meta.dirname, '../compat/client/errors/soft-refresh.ts');
178
+ return path.join(import.meta.dirname, '../compat/client/errors/soft-refresh.ts')
179
179
  }
180
180
 
181
181
  function bareErrorBoundaryPath() {
182
- return path.join(import.meta.dirname, '../compat/client/errors/bare-boundary.ts');
182
+ return path.join(import.meta.dirname, '../compat/client/errors/bare-boundary.ts')
183
183
  }
184
184
 
185
185
  // The full in-tree ClientErrorBoundary is emitted only for a route that has an
@@ -188,18 +188,18 @@ function bareErrorBoundaryPath() {
188
188
  // window last resort - but only the bare tier, which re-throws and preserves
189
189
  // primitive throws for global-error and carries none of the cluster.
190
190
  function boundaryImportSource(nextCompat?: boolean, boundary?: boolean, builtinNotFound?: boolean) {
191
- if (!nextCompat) return '';
191
+ if (!nextCompat) return ''
192
192
  if (!boundary) {
193
- return `import { BareErrorBoundary } from ${JSON.stringify(bareErrorBoundaryPath())};`;
193
+ return `import { BareErrorBoundary } from ${JSON.stringify(bareErrorBoundaryPath())};`
194
194
  }
195
195
  return `import { ClientErrorBoundary } from ${JSON.stringify(clientErrorBoundaryPath())};
196
196
  import { softRefreshRoute } from ${JSON.stringify(softRefreshModulePath())};${
197
197
  builtinNotFound ? `\n${builtInNotFoundSource()}` : ''
198
- }`;
198
+ }`
199
199
  }
200
200
 
201
201
  function errorUiModulePath() {
202
- return path.join(import.meta.dirname, '../compat/lifecycle/error-ui.ts');
202
+ return path.join(import.meta.dirname, '../compat/lifecycle/error-ui.ts')
203
203
  }
204
204
 
205
205
  // Next's default 404 body, for a client notFound() on a route with no not-found.* of its own.
@@ -209,7 +209,7 @@ function builtInNotFoundSource() {
209
209
  return `import { httpAccessFallbackUi as __pnextHttpAccessFallbackUi } from ${JSON.stringify(errorUiModulePath())};
210
210
  function __PNextBuiltInNotFound() {
211
211
  return __pnextHttpAccessFallbackUi(404, 'This page could not be found.');
212
- }`;
212
+ }`
213
213
  }
214
214
 
215
215
  /**
@@ -227,13 +227,13 @@ type EntryCompatFacts = Pick<
227
227
  | 'notFoundFile'
228
228
  | 'controlFlow'
229
229
  | 'router'
230
- >;
230
+ >
231
231
 
232
232
  /** Whether this route has something for the in-tree boundary to render. */
233
233
  export function hasErrorBoundary(
234
234
  facts: Pick<ClientEntryOptions, 'errorFile' | 'notFoundFile' | 'controlFlow'>,
235
235
  ) {
236
- return Boolean(facts.errorFile ?? facts.notFoundFile) || facts.controlFlow === true;
236
+ return Boolean(facts.errorFile ?? facts.notFoundFile) || facts.controlFlow === true
237
237
  }
238
238
 
239
239
  function routerImportSource({
@@ -249,20 +249,20 @@ function routerImportSource({
249
249
  // guard is the one thing still owed, and it is one window read (autoMountGuard).
250
250
  const base = router
251
251
  ? `import { installRouter, routerImportActive } from ${JSON.stringify(routerModulePath())};`
252
- : '';
253
- if (!nextCompat) return base;
252
+ : ''
253
+ if (!nextCompat) return base
254
254
  const imports = [
255
255
  `${base}
256
256
  import { installNavCompat } from ${JSON.stringify(navCompatModulePath())};
257
257
  import { installClientErrors } from ${JSON.stringify(clientErrorsInstallPath())};`,
258
- ];
258
+ ]
259
259
  if (actions) {
260
260
  // Compat apps may use server actions whose client stub navigates redirects
261
261
  // through window.__PNEXT_ROUTER__; install that global from the entry.
262
262
  imports.push(
263
263
  `import { installActionRouter } from ${JSON.stringify(actionRouterModulePath())};
264
264
  import { isActionError } from ${JSON.stringify(actionClientModulePath())};`,
265
- );
265
+ )
266
266
  }
267
267
  if (errorFile) {
268
268
  // Route error.js: rendered as an overlay when an action error goes uncaught
@@ -270,17 +270,17 @@ import { isActionError } from ${JSON.stringify(actionClientModulePath())};`,
270
270
  if (actions) {
271
271
  imports.push(
272
272
  `import { installActionErrorOverlay } from ${JSON.stringify(actionClientModulePath())};`,
273
- );
273
+ )
274
274
  }
275
- imports.push(`import __PNextRouteErrorComponent from ${JSON.stringify(errorFile)};`);
275
+ imports.push(`import __PNextRouteErrorComponent from ${JSON.stringify(errorFile)};`)
276
276
  }
277
277
  if (globalErrorFile) {
278
- imports.push(`import __PNextGlobalErrorComponent from ${JSON.stringify(globalErrorFile)};`);
278
+ imports.push(`import __PNextGlobalErrorComponent from ${JSON.stringify(globalErrorFile)};`)
279
279
  }
280
280
  if (notFoundFile) {
281
- imports.push(`import __PNextRouteNotFoundComponent from ${JSON.stringify(notFoundFile)};`);
281
+ imports.push(`import __PNextRouteNotFoundComponent from ${JSON.stringify(notFoundFile)};`)
282
282
  }
283
- return imports.join('\n');
283
+ return imports.join('\n')
284
284
  }
285
285
 
286
286
  // Island props may carry serialized server-action references; the action runtime revives them into
@@ -289,7 +289,7 @@ import { isActionError } from ${JSON.stringify(actionClientModulePath())};`,
289
289
  // untouched when next compat is off - so core and react entries import the ref+binary reviver and the
290
290
  // error branch never ships.
291
291
  function propsParserSource(nextCompat?: boolean) {
292
- const revive = nextCompat ? 'reviveSerializedErrorRefs' : 'reviveSerializedRefs';
292
+ const revive = nextCompat ? 'reviveSerializedErrorRefs' : 'reviveSerializedRefs'
293
293
  return `
294
294
  import { ${revive} as __pnextReviveSerializedRefs } from ${JSON.stringify(serializeModulePath())};
295
295
  import { hasIslandStaticSlots as __pnextHasIslandSlots, reviveIslandStaticSlots as __pnextReviveIslandSlots } from ${JSON.stringify(staticSlotsModulePath())};
@@ -332,7 +332,7 @@ function pnextFulfilled(value) {
332
332
  promise.value = value;
333
333
  return promise;
334
334
  }
335
- `;
335
+ `
336
336
  }
337
337
 
338
338
  // Entries auto-mount only when loaded as the document's own module script.
@@ -443,14 +443,16 @@ function keepsMountedRoot(root, keep) {
443
443
  }
444
444
  return false;
445
445
  }
446
- `;
446
+ `
447
447
  }
448
448
 
449
449
  // The per-route half of the lifecycle, closing over the route's own mount
450
450
  // state. mountRoute runs the steps the route actually has: an island scan, the
451
451
  // client-shell hydration, the client page.
452
452
  function routeLifecycleSource({ nextCompat, islands, page, shell }: ClientRuntimeFacts) {
453
- const gate = nextCompat ? ' pnextGate(markRouteHydrated, pnextIslandMounts, pnextVisibleMount);\n' : '';
453
+ const gate = nextCompat
454
+ ? ' pnextGate(markRouteHydrated, pnextIslandMounts, pnextVisibleMount);\n'
455
+ : ''
454
456
  const mountBody = [
455
457
  islands
456
458
  ? ` if (islands.length > 0) {
@@ -467,7 +469,7 @@ function routeLifecycleSource({ nextCompat, islands, page, shell }: ClientRuntim
467
469
  : '',
468
470
  ]
469
471
  .filter(Boolean)
470
- .join('\n');
472
+ .join('\n')
471
473
  return `
472
474
  function mountRoute() {
473
475
  ${mountBody}
@@ -508,7 +510,7 @@ ${gate} return pnextIslandMounts;
508
510
  }
509
511
 
510
512
  return { mountRoute, remountRoute, unmountRoute };
511
- `;
513
+ `
512
514
  }
513
515
 
514
516
  /**
@@ -529,7 +531,7 @@ function markRouteHydrated() {
529
531
  window.dispatchEvent(new Event('pnext:hydrated'));
530
532
  }
531
533
  `
532
- : '';
534
+ : ''
533
535
  return `
534
536
  ${routerImportSource(facts)}
535
537
  ${mark}
@@ -542,12 +544,12 @@ export function unmountRoute() {}
542
544
  ${installRouterCall(facts.router)}${installCallsSource(facts)}
543
545
  if (${autoMountGuard(facts.router)}) mountRoute();
544
546
  if (window.__PNEXT_REGISTER_ENTRY__) window.__PNEXT_REGISTER_ENTRY__(import.meta.url, { mountRoute, unmountRoute });
545
- `;
547
+ `
546
548
  }
547
549
 
548
550
  /** `installRouter()`, or nothing when the route can never soft-navigate. */
549
551
  function installRouterCall(router?: boolean) {
550
- return router ? 'installRouter();\n' : '';
552
+ return router ? 'installRouter();\n' : ''
551
553
  }
552
554
 
553
555
  /**
@@ -556,7 +558,7 @@ function installRouterCall(router?: boolean) {
556
558
  * `routerImportActive` - that one import would pull the whole first-paint hub back onto the page.
557
559
  */
558
560
  function autoMountGuard(router?: boolean) {
559
- return router ? '!routerImportActive()' : '!((window.__PNEXT_ROUTER_IMPORTS__ ?? 0) > 0)';
561
+ return router ? '!routerImportActive()' : '!((window.__PNEXT_ROUTER_IMPORTS__ ?? 0) > 0)'
560
562
  }
561
563
 
562
564
  // The compat install calls that follow installRouter() in every entry shape.
@@ -567,8 +569,9 @@ function installCallsSource({
567
569
  globalErrorFile,
568
570
  notFoundFile,
569
571
  }: EntryCompatFacts) {
570
- if (!nextCompat) return '';
571
- const overlay = actions && errorFile ? 'installActionErrorOverlay(__PNextRouteErrorComponent);\n' : '';
572
+ if (!nextCompat) return ''
573
+ const overlay =
574
+ actions && errorFile ? 'installActionErrorOverlay(__PNextRouteErrorComponent);\n' : ''
572
575
  return `${actions ? 'installActionRouter();\n' : ''}installNavCompat();
573
576
  ${overlay}installClientErrors({ errorComponent: ${
574
577
  errorFile ? '__PNextRouteErrorComponent' : 'undefined'
@@ -576,7 +579,7 @@ ${overlay}installClientErrors({ errorComponent: ${
576
579
  globalErrorFile ? '__PNextGlobalErrorComponent' : 'undefined'
577
580
  }, notFoundComponent: ${
578
581
  notFoundFile ? '__PNextRouteNotFoundComponent' : 'undefined'
579
- }, isActionError: ${actions ? 'isActionError' : 'undefined'} });`;
582
+ }, isActionError: ${actions ? 'isActionError' : 'undefined'} });`
580
583
  }
581
584
 
582
585
  /**
@@ -584,29 +587,29 @@ ${overlay}installClientErrors({ errorComponent: ${
584
587
  * ships only when some route in the app can actually use it.
585
588
  */
586
589
  export interface ClientRuntimeFacts {
587
- nextCompat?: boolean;
590
+ nextCompat?: boolean
588
591
  /** Any route mounts islands (island scan, revival, static children). */
589
- islands?: boolean;
592
+ islands?: boolean
590
593
  /** Any route is a whole-page `'use client'` component. */
591
- page?: boolean;
594
+ page?: boolean
592
595
  /** Any route hydrates a client root layout as the document shell. */
593
- shell?: boolean;
596
+ shell?: boolean
594
597
  /** Any route has a `dynamic(..., { ssr: false })` island (DeferredIsland). */
595
- deferredIslands?: boolean;
598
+ deferredIslands?: boolean
596
599
  /** Any island loads on visibility (IntersectionObserver tier). */
597
- visibleIslands?: boolean;
600
+ visibleIslands?: boolean
598
601
  /**
599
602
  * Compat runtime must support suspension (Suspense island wrapper, preact/compat). False only when
600
603
  * the app's client graph provably never suspends (see clientCompatSurface); undefined outside compat.
601
604
  */
602
- suspense?: boolean;
605
+ suspense?: boolean
603
606
  }
604
607
 
605
608
  /** Module specifier the generated route stubs import their runtime from. */
606
- export const CLIENT_RUNTIME_MODULE = 'pnext-client-runtime';
609
+ export const CLIENT_RUNTIME_MODULE = 'pnext-client-runtime'
607
610
 
608
611
  /** Dev split: single-instance vendor modules the entry shares with on-demand chunks. */
609
- export const DYN_SHARED_GLOBAL = '__PNEXT_DYN_SHARED__';
612
+ export const DYN_SHARED_GLOBAL = '__PNEXT_DYN_SHARED__'
610
613
  export function dynSharedSpecifiers(nextCompat?: boolean) {
611
614
  return nextCompat
612
615
  ? [
@@ -617,7 +620,7 @@ export function dynSharedSpecifiers(nextCompat?: boolean) {
617
620
  'preact/jsx-runtime',
618
621
  'preact/jsx-dev-runtime',
619
622
  ]
620
- : ['preact', 'preact/hooks', 'preact/jsx-runtime'];
623
+ : ['preact', 'preact/hooks', 'preact/jsx-runtime']
621
624
  }
622
625
 
623
626
  // A separately-built dynamic chunk must render with THIS entry's preact (hooks
@@ -629,15 +632,15 @@ function dynSharedTableSource(
629
632
  nextCompat?: boolean,
630
633
  deferredDynamicHref?: (reference: ClientReference) => string | undefined,
631
634
  ) {
632
- if (!deferredDynamicHref) return '';
633
- const specifiers = dynSharedSpecifiers(nextCompat);
635
+ if (!deferredDynamicHref) return ''
636
+ const specifiers = dynSharedSpecifiers(nextCompat)
634
637
  const imports = specifiers.map(
635
638
  (specifier, index) => `import * as __pnextDynShared${index} from ${JSON.stringify(specifier)};`,
636
- );
639
+ )
637
640
  const entries = specifiers.map(
638
641
  (specifier, index) => `${JSON.stringify(specifier)}: __pnextDynShared${index}`,
639
- );
640
- return `${imports.join('\n')}\nwindow.${DYN_SHARED_GLOBAL} = { ${entries.join(', ')} };\n`;
642
+ )
643
+ return `${imports.join('\n')}\nwindow.${DYN_SHARED_GLOBAL} = { ${entries.join(', ')} };\n`
641
644
  }
642
645
 
643
646
  export function clientRuntimeFacts(
@@ -645,21 +648,21 @@ export function clientRuntimeFacts(
645
648
  nextCompat?: boolean,
646
649
  suspense?: boolean,
647
650
  ): ClientRuntimeFacts {
648
- const references = routes.flatMap(({ route }) => route.clientReferences);
651
+ const references = routes.flatMap(({ route }) => route.clientReferences)
649
652
  return {
650
653
  nextCompat,
651
- suspense: nextCompat ? suspense ?? true : undefined,
654
+ suspense: nextCompat ? (suspense ?? true) : undefined,
652
655
  islands: references.length > 0,
653
656
  page: routes.some(({ route }) => route.client),
654
657
  shell: routes.some(entry => entry.shell),
655
658
  deferredIslands: references.some(reference => reference.dynamic?.ssr === false),
656
659
  visibleIslands: references.some(reference => reference.dynamic?.load === 'visible'),
657
- };
660
+ }
658
661
  }
659
662
 
660
663
  interface RouteFacts {
661
- client?: boolean;
662
- clientReferences: ClientReference[];
664
+ client?: boolean
665
+ clientReferences: ClientReference[]
663
666
  }
664
667
 
665
668
  /**
@@ -668,11 +671,11 @@ interface RouteFacts {
668
671
  * Route-specific values (islands, the client page, shell layouts, error components) arrive as config.
669
672
  */
670
673
  export function clientRuntimeSource(facts: ClientRuntimeFacts) {
671
- const { nextCompat, deferredIslands, page, shell } = facts;
672
- const suspense = nextCompat && facts.suspense !== false;
674
+ const { nextCompat, deferredIslands, page, shell } = facts
675
+ const suspense = nextCompat && facts.suspense !== false
673
676
  // The shell re-renders the whole document through the client root layout, so
674
677
  // it revives island DOM exactly like an island mount does.
675
- const revival = Boolean(facts.islands || shell);
678
+ const revival = Boolean(facts.islands || shell)
676
679
  return `
677
680
  import { h, hydrate, render } from 'preact';
678
681
  ${nextCompat ? "import { options as __pnextPreactOptions } from 'preact';" : ''}
@@ -699,12 +702,19 @@ ${shell ? hydrateClientShellSource(nextCompat) : ''}
699
702
  ${page ? hydratePageSource(nextCompat) : ''}
700
703
  ${routeLifecycleSource(facts)}
701
704
  }
702
- `;
705
+ `
703
706
  }
704
707
 
705
708
  export function clientEntrySource(options: ClientEntryOptions) {
706
- const { pageFile, clientReferences, nextCompat, errorFile, notFoundFile, clientRootLayout, shellLayoutOrder } =
707
- options;
709
+ const {
710
+ pageFile,
711
+ clientReferences,
712
+ nextCompat,
713
+ errorFile,
714
+ notFoundFile,
715
+ clientRootLayout,
716
+ shellLayoutOrder,
717
+ } = options
708
718
  const facts: EntryCompatFacts = {
709
719
  nextCompat,
710
720
  suspense: options.suspense,
@@ -715,27 +725,31 @@ export function clientEntrySource(options: ClientEntryOptions) {
715
725
  controlFlow: options.controlFlow,
716
726
  // The router-only entry shape exists BECAUSE this route needs the router.
717
727
  router: options.router || (!pageFile && clientReferences.length === 0),
718
- };
728
+ }
719
729
  if (!pageFile && clientReferences.length === 0) {
720
- return routerOnlyEntrySource(facts);
730
+ return routerOnlyEntrySource(facts)
721
731
  }
722
- if (!pageFile && clientReferences.length > 0 && clientReferences.every(isVisibleDynamicReference)) {
723
- return visibleDynamicIslandEntrySource(clientReferences, facts, options.deferredDynamicHref);
732
+ if (
733
+ !pageFile &&
734
+ clientReferences.length > 0 &&
735
+ clientReferences.every(isVisibleDynamicReference)
736
+ ) {
737
+ return visibleDynamicIslandEntrySource(clientReferences, facts, options.deferredDynamicHref)
724
738
  }
725
739
 
726
740
  const imports = clientReferences
727
741
  .map((reference, index) => {
728
- if (reference.dynamic) return null;
742
+ if (reference.dynamic) return null
729
743
  // A side-effect-only client module (bare `import './client-only'`) is
730
744
  // bundled and run for its top-level code but never mounted as an island —
731
745
  // webpack-style eager initialization of all client references.
732
- if (reference.sideEffect) return `import ${JSON.stringify(reference.file)};`;
746
+ if (reference.sideEffect) return `import ${JSON.stringify(reference.file)};`
733
747
  return reference.exportName === 'default'
734
748
  ? `import Island${index} from ${JSON.stringify(reference.file)};`
735
- : `import { ${reference.exportName} as Island${index} } from ${JSON.stringify(reference.file)};`;
749
+ : `import { ${reference.exportName} as Island${index} } from ${JSON.stringify(reference.file)};`
736
750
  })
737
751
  .filter((item): item is string => Boolean(item))
738
- .join('\n');
752
+ .join('\n')
739
753
  const islandManifest = clientReferences
740
754
  .map((reference, index) =>
741
755
  reference.sideEffect
@@ -745,27 +759,27 @@ export function clientEntrySource(options: ClientEntryOptions) {
745
759
  : `{ id: ${JSON.stringify(reference.id)}, Component: Island${index} }`,
746
760
  )
747
761
  .filter((item): item is string => item !== null)
748
- .join(',\n ');
762
+ .join(',\n ')
749
763
 
750
764
  // Island bindings are named by position in the FULL reference array (see
751
765
  // `imports` above), so the shell must carry those names rather than re-index
752
766
  // its own filtered/reordered view.
753
767
  const islandNames = new Map(
754
768
  clientReferences.map((reference, index) => [reference, `Island${index}`]),
755
- );
769
+ )
756
770
  const shellReferences = shellClientReferences(
757
771
  clientReferences,
758
772
  errorFile,
759
773
  notFoundFile,
760
774
  shellLayoutOrder,
761
- );
775
+ )
762
776
  const shellNames =
763
777
  !pageFile && clientRootLayout && shellReferences.some(reference => !reference.dynamic)
764
778
  ? shellReferences
765
779
  .map(reference => (reference.dynamic ? undefined : islandNames.get(reference)))
766
780
  .filter((name): name is string => Boolean(name))
767
- : undefined;
768
- const needsCss = clientReferences.some(reference => referenceCssHref(reference));
781
+ : undefined
782
+ const needsCss = clientReferences.some(reference => referenceCssHref(reference))
769
783
 
770
784
  return `
771
785
  import { bootstrapRoute${needsCss ? ', loadIslandCss' : ''} } from ${JSON.stringify(CLIENT_RUNTIME_MODULE)};
@@ -785,7 +799,7 @@ export { mountRoute, remountRoute, unmountRoute };
785
799
  ${installRouterCall(facts.router)}${installCallsSource(facts)}
786
800
  if (${autoMountGuard(facts.router)}) void mountRoute();
787
801
  if (window.__PNEXT_REGISTER_ENTRY__) window.__PNEXT_REGISTER_ENTRY__(import.meta.url, { mountRoute, unmountRoute });
788
- `;
802
+ `
789
803
  }
790
804
 
791
805
  /**
@@ -795,14 +809,14 @@ if (window.__PNEXT_REGISTER_ENTRY__) window.__PNEXT_REGISTER_ENTRY__(import.meta
795
809
  * the app-wide runtime chunk.
796
810
  */
797
811
  function boundaryConfigSource(facts: EntryCompatFacts) {
798
- if (!facts.nextCompat) return '';
812
+ if (!facts.nextCompat) return ''
799
813
  const base = `\n errorComponent: ${facts.errorFile ? '__PNextRouteErrorComponent' : 'undefined'},\n notFoundComponent: ${
800
814
  facts.notFoundFile ? '__PNextRouteNotFoundComponent' : 'undefined'
801
- },`;
802
- if (!hasErrorBoundary(facts)) return `${base}\n errorBoundary: BareErrorBoundary,`;
815
+ },`
816
+ if (!hasErrorBoundary(facts)) return `${base}\n errorBoundary: BareErrorBoundary,`
803
817
  return `${base}\n errorBoundary: ClientErrorBoundary,\n onBoundaryReset: softRefreshRoute,${
804
818
  facts.notFoundFile ? '' : '\n builtInNotFound: __PNextBuiltInNotFound,'
805
- }`;
819
+ }`
806
820
  }
807
821
 
808
822
  function shellClientReferences(
@@ -813,31 +827,29 @@ function shellClientReferences(
813
827
  ) {
814
828
  const shell = clientReferences.filter(
815
829
  reference =>
816
- !reference.sideEffect &&
817
- reference.file !== errorFile &&
818
- reference.file !== notFoundFile,
819
- );
830
+ !reference.sideEffect && reference.file !== errorFile && reference.file !== notFoundFile,
831
+ )
820
832
  // The shell nests outermost-first, but `clientReferences` is path-hash
821
833
  // sorted — layouts must lead in hierarchy order or a non-layout reference
822
834
  // can end up outermost and silently drop the layout subtree. Non-layout
823
835
  // references keep their relative order behind the chain.
824
- if (!shellLayoutOrder?.length) return shell;
825
- const rank = new Map(shellLayoutOrder.map((file, index) => [file, index]));
836
+ if (!shellLayoutOrder?.length) return shell
837
+ const rank = new Map(shellLayoutOrder.map((file, index) => [file, index]))
826
838
  return shell
827
839
  .map((reference, index) => ({ reference, index }))
828
840
  .sort((a, b) => {
829
- const aRank = rank.get(a.reference.file);
830
- const bRank = rank.get(b.reference.file);
831
- if (aRank !== undefined && bRank !== undefined) return aRank - bRank;
832
- if (aRank !== undefined) return -1;
833
- if (bRank !== undefined) return 1;
834
- return a.index - b.index;
841
+ const aRank = rank.get(a.reference.file)
842
+ const bRank = rank.get(b.reference.file)
843
+ if (aRank !== undefined && bRank !== undefined) return aRank - bRank
844
+ if (aRank !== undefined) return -1
845
+ if (bRank !== undefined) return 1
846
+ return a.index - b.index
835
847
  })
836
- .map(entry => entry.reference);
848
+ .map(entry => entry.reference)
837
849
  }
838
850
 
839
851
  function isVisibleDynamicReference(reference: ClientReference) {
840
- return reference.dynamic?.load === 'visible';
852
+ return reference.dynamic?.load === 'visible'
841
853
  }
842
854
 
843
855
  function visibleDynamicIslandEntrySource(
@@ -845,11 +857,14 @@ function visibleDynamicIslandEntrySource(
845
857
  facts: EntryCompatFacts,
846
858
  deferredDynamicHref?: (reference: ClientReference) => string | undefined,
847
859
  ) {
848
- const { nextCompat, errorFile, notFoundFile } = facts;
849
- const boundary = hasErrorBoundary(facts);
860
+ const { nextCompat, errorFile, notFoundFile } = facts
861
+ const boundary = hasErrorBoundary(facts)
850
862
  const islandManifest = clientReferences
851
- .map(reference => `{ id: ${JSON.stringify(reference.id)}, ${visibleDynamicLoader(reference, deferredDynamicHref?.(reference))} }`)
852
- .join(',\n ');
863
+ .map(
864
+ reference =>
865
+ `{ id: ${JSON.stringify(reference.id)}, ${visibleDynamicLoader(reference, deferredDynamicHref?.(reference))} }`,
866
+ )
867
+ .join(',\n ')
853
868
 
854
869
  const compatBoundary = !nextCompat
855
870
  ? ''
@@ -868,7 +883,7 @@ function visibleDynamicIslandEntrySource(
868
883
  `function pnextClientBoundary(h, vnode) {
869
884
  return h(BareErrorBoundary, null, vnode);
870
885
  }
871
- `;
886
+ `
872
887
 
873
888
  return `
874
889
  ${nextCompat ? "import { options as __pnextPreactOptions } from 'preact';" : ''}
@@ -1088,27 +1103,25 @@ function domProps(element) {
1088
1103
  function isNestedIslandRoot(root) {
1089
1104
  return root.parentElement?.closest('pnext-client') != null;
1090
1105
  }
1091
- `;
1106
+ `
1092
1107
  }
1093
1108
 
1094
1109
  function visibleDynamicLoader(reference: ClientReference, href?: string) {
1095
- return `options: ${JSON.stringify(reference.dynamic ?? {})}, ${dynamicLoader(reference, href)}`;
1110
+ return `options: ${JSON.stringify(reference.dynamic ?? {})}, ${dynamicLoader(reference, href)}`
1096
1111
  }
1097
1112
 
1098
1113
  function dynamicLoader(reference: ClientReference, href?: string) {
1099
1114
  const imported =
1100
- reference.exportName === 'default'
1101
- ? 'module.default'
1102
- : `module.${reference.exportName}`;
1103
- const importExpression = `import(${JSON.stringify(href ?? reference.file)}).then(module => ${imported})`;
1104
- const cssHref = referenceCssHref(reference);
1115
+ reference.exportName === 'default' ? 'module.default' : `module.${reference.exportName}`
1116
+ const importExpression = `import(${JSON.stringify(href ?? reference.file)}).then(module => ${imported})`
1117
+ const cssHref = referenceCssHref(reference)
1105
1118
  return cssHref
1106
1119
  ? `load: () => Promise.all([${importExpression}, loadIslandCss(${JSON.stringify(cssHref)})]).then(([module]) => module)`
1107
- : `load: () => ${importExpression}`;
1120
+ : `load: () => ${importExpression}`
1108
1121
  }
1109
1122
 
1110
1123
  function referenceCssHref(reference: ClientReference) {
1111
- return reference.cssImports?.length ? `/assets/${reference.id}.css` : undefined;
1124
+ return reference.cssImports?.length ? `/assets/${reference.id}.css` : undefined
1112
1125
  }
1113
1126
 
1114
1127
  // The island's stylesheet loads with the island, not with the route: a
@@ -1128,7 +1141,7 @@ export function loadIslandCss(href) {
1128
1141
  document.head.append(link);
1129
1142
  });
1130
1143
  }
1131
- `;
1144
+ `
1132
1145
  }
1133
1146
 
1134
1147
  function mountSource() {
@@ -1146,7 +1159,7 @@ function mount(root, vnode) {
1146
1159
  root.__pnextLive = render;
1147
1160
  pnextMountedRoots.add(root);
1148
1161
  }
1149
- `;
1162
+ `
1150
1163
  }
1151
1164
 
1152
1165
  function hydratePageSource(nextCompat?: boolean) {
@@ -1255,7 +1268,7 @@ function pageMarkerContainer(open, close, parent) {
1255
1268
  closest(selector) { return parent.closest ? parent.closest(selector) : null; },
1256
1269
  };
1257
1270
  }
1258
- `;
1271
+ `
1259
1272
  }
1260
1273
 
1261
1274
  // Under next compat every hydrated island and the page mount wraps in the in-tree
@@ -1263,7 +1276,7 @@ function pageMarkerContainer(open, close, parent) {
1263
1276
  // without Suspense kills the Preact tree). The boundary renders the route error.js and reset() soft-
1264
1277
  // refreshes.
1265
1278
  function wrapInBoundary(vnodeExpression: string, nextCompat?: boolean) {
1266
- return nextCompat ? `pnextBoundary(${vnodeExpression})` : vnodeExpression;
1279
+ return nextCompat ? `pnextBoundary(${vnodeExpression})` : vnodeExpression
1267
1280
  }
1268
1281
 
1269
1282
  // Emits the per-route boundary helper referenced by wrapInBoundary. The Suspense wrapper is
@@ -1272,7 +1285,7 @@ function wrapInBoundary(vnodeExpression: string, nextCompat?: boolean) {
1272
1285
  // shared app-wide, so naming the full boundary would put the whole cluster - and its built-in 404 UI -
1273
1286
  // on the first paint of every route in an app where any single route has an error file.
1274
1287
  function clientBoundaryHelperSource(nextCompat?: boolean, suspense?: boolean) {
1275
- if (!nextCompat) return '';
1288
+ if (!nextCompat) return ''
1276
1289
  // A suspense-free app (no lazy/use/async components anywhere in its client graph) keeps the error
1277
1290
  // boundary but drops the Suspense wrapper - and preact/compat with it.
1278
1291
  const boundary = `h(config.errorBoundary, {
@@ -1280,12 +1293,12 @@ function clientBoundaryHelperSource(nextCompat?: boolean, suspense?: boolean) {
1280
1293
  notFoundComponent: config.notFoundComponent,
1281
1294
  builtInNotFound: config.builtInNotFound,
1282
1295
  onReset: config.onBoundaryReset,
1283
- }, vnode)`;
1296
+ }, vnode)`
1284
1297
  return `
1285
1298
  function pnextBoundary(vnode) {
1286
1299
  return ${suspense ? `h(Suspense, { fallback: null }, ${boundary})` : boundary};
1287
1300
  }
1288
- `;
1301
+ `
1289
1302
  }
1290
1303
 
1291
1304
  function hydrateIslandsSource({ nextCompat, visibleIslands, deferredIslands }: ClientRuntimeFacts) {
@@ -1339,8 +1352,10 @@ function mountIsland(root, island) {
1339
1352
 
1340
1353
  async function mountIslandTree(root, island) {
1341
1354
  const Component = island.Component ?? await island.load();${
1342
- nextCompat ? `
1343
- window.__PNEXT_ACTIONS__?.registerClientReference(island.id, Component);` : ''
1355
+ nextCompat
1356
+ ? `
1357
+ window.__PNEXT_ACTIONS__?.registerClientReference(island.id, Component);`
1358
+ : ''
1344
1359
  }
1345
1360
  const rawProps = root.getAttribute('data-pnext-props') ?? '{}';
1346
1361
  const incoming = root.__pnextIncoming;
@@ -1442,7 +1457,7 @@ async function domNode(node) {
1442
1457
 
1443
1458
  return h(element.localName, domProps(element), await domChildren(element));
1444
1459
  }
1445
- `;
1460
+ `
1446
1461
  }
1447
1462
 
1448
1463
  // Helpers with no per-route state: they live once in the shared runtime module,
@@ -1496,7 +1511,7 @@ function DeferredIsland({ load, props, children }) {
1496
1511
  }
1497
1512
  `
1498
1513
  : ''
1499
- }`;
1514
+ }`
1500
1515
  }
1501
1516
 
1502
1517
  function hydrateClientShellSource(nextCompat?: boolean) {
@@ -1505,7 +1520,7 @@ function hydrateClientShellSource(nextCompat?: boolean) {
1505
1520
  const shell = `shell.reduceRight(
1506
1521
  (children, Component, index) => h(Component, index === 0 ? slotProps : null, children),
1507
1522
  page,
1508
- )`;
1523
+ )`
1509
1524
 
1510
1525
  return `
1511
1526
  // A client root layout is re-rendered whole here, but its parallel-route slot
@@ -1536,5 +1551,5 @@ async function hydrateClientShell() {
1536
1551
  const slotProps = await collectRootSlotProps();
1537
1552
  mount(document.body, ${wrapInBoundary(shell, nextCompat)});
1538
1553
  }
1539
- `;
1554
+ `
1540
1555
  }