@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
package/src/cli/create.ts CHANGED
@@ -1,43 +1,45 @@
1
- import { existsSync } from 'node:fs';
2
- import { mkdir, readdir } from 'node:fs/promises';
3
- import path from 'node:path';
4
- import { bold, cyan, dim, green } from '../utils/ansi';
1
+ import { existsSync } from 'node:fs'
2
+ import { mkdir, readdir } from 'node:fs/promises'
3
+ import path from 'node:path'
4
+ import { bold, cyan, dim, green } from '../utils/ansi'
5
+ import { pnextVersionRange } from '../utils/fs'
6
+ import { formatDuration } from '../utils/verbose'
5
7
 
6
8
  export interface CreateAppOptions {
7
- install: boolean;
9
+ install: boolean
8
10
  }
9
11
 
10
12
  export async function createApp(dir: string | undefined, options: CreateAppOptions) {
11
13
  if (!dir) {
12
- console.log('Usage: pnext create <directory> [--no-install]');
13
- throw new Error('pnext create requires a directory argument');
14
+ console.log('Usage: pnext create <directory> [--no-install]')
15
+ throw new Error('pnext create requires a directory argument')
14
16
  }
15
17
 
16
- const target = path.resolve(dir);
18
+ const target = path.resolve(dir)
17
19
  if (existsSync(target)) {
18
20
  if ((await readdir(target)).length > 0) {
19
- throw new Error(`Directory already exists and is not empty: ${target}`);
21
+ throw new Error(`Directory already exists and is not empty: ${target}`)
20
22
  }
21
23
  } else {
22
- await mkdir(target, { recursive: true });
24
+ await mkdir(target, { recursive: true })
23
25
  }
24
26
 
25
- const name = sanitizePackageName(path.basename(target));
26
- console.log(`${cyan('▲')} ${bold('pnext create')} ${dim(`— scaffolding ${name}`)}\n`);
27
+ const name = sanitizePackageName(path.basename(target))
28
+ console.log(`${cyan('▲')} ${bold('pnext create')} ${dim(`— scaffolding ${name}`)}\n`)
27
29
 
28
- const files = scaffoldFiles(name);
30
+ const files = scaffoldFiles(name)
29
31
  await Promise.all(
30
32
  Object.entries(files).map(([file, source]) => Bun.write(path.join(target, file), source)),
31
- );
32
- for (const file of Object.keys(files)) console.log(` ${green('+')} ${dim(file)}`);
33
+ )
34
+ for (const file of Object.keys(files)) console.log(` ${green('+')} ${dim(file)}`)
33
35
 
34
- let installed = false;
36
+ let installed = false
35
37
  if (options.install) {
36
- console.log('');
37
- installed = await install(target, dir);
38
+ console.log('')
39
+ installed = await install(target, dir)
38
40
  }
39
41
 
40
- printNextSteps(dir, installed);
42
+ printNextSteps(dir, installed)
41
43
  }
42
44
 
43
45
  // npm package name rules: lowercase, url-safe, no leading dot/underscore.
@@ -46,71 +48,68 @@ function sanitizePackageName(raw: string) {
46
48
  .trim()
47
49
  .toLowerCase()
48
50
  .replace(/[^a-z0-9._-]+/g, '-')
49
- .replace(/^[-._]+|[-._]+$/g, '');
50
- return name || 'pnext-app';
51
+ .replace(/^[-._]+|[-._]+$/g, '')
52
+ return name || 'pnext-app'
51
53
  }
52
54
 
53
55
  async function install(target: string, dir: string) {
54
- const stop = spinner('Installing dependencies...');
55
- const start = Bun.nanoseconds();
56
- const proc = Bun.spawn(['bun', 'install'], { cwd: target, stdout: 'pipe', stderr: 'pipe' });
56
+ const stop = spinner('Installing dependencies...')
57
+ const start = Bun.nanoseconds()
58
+ const proc = Bun.spawn(['bun', 'install'], { cwd: target, stdout: 'pipe', stderr: 'pipe' })
57
59
  // Drain both pipes: an unread pipe can fill and stall the child.
58
60
  const [stderr, , code] = await Promise.all([
59
61
  new Response(proc.stderr).text(),
60
62
  new Response(proc.stdout).text(),
61
63
  proc.exited,
62
- ]);
63
- stop();
64
+ ])
65
+ stop()
64
66
 
65
67
  if (code === 0) {
66
- const durationMs = (Bun.nanoseconds() - start) / 1e6;
67
- console.log(`${green('✓')} ${bold('Installed dependencies')} ${dim(`in ${formatDuration(durationMs)}`)}`);
68
- return true;
68
+ const durationMs = (Bun.nanoseconds() - start) / 1e6
69
+ console.log(
70
+ `${green('✓')} ${bold('Installed dependencies')} ${dim(`in ${formatDuration(durationMs)}`)}`,
71
+ )
72
+ return true
69
73
  }
70
- console.log(`${dim('Install failed. Run it manually:')}`);
71
- console.log(` ${cyan('cd')} ${dir}`);
72
- console.log(` ${cyan('bun install')}`);
73
- if (stderr.trim()) console.log(dim(stderr.trim()));
74
- return false;
74
+ console.log(`${dim('Install failed. Run it manually:')}`)
75
+ console.log(` ${cyan('cd')} ${dir}`)
76
+ console.log(` ${cyan('bun install')}`)
77
+ if (stderr.trim()) console.log(dim(stderr.trim()))
78
+ return false
75
79
  }
76
80
 
77
81
  /** Braille spinner, TTY-only; a plain line prints once and stays put otherwise. */
78
82
  function spinner(label: string) {
79
83
  if (!process.stdout.isTTY) {
80
- console.log(label);
81
- return () => undefined;
84
+ console.log(label)
85
+ return () => undefined
82
86
  }
83
- const frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
84
- let frame = 0;
85
- process.stdout.write(`${cyan(frames[0]!)} ${label}`);
87
+ const frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']
88
+ let frame = 0
89
+ process.stdout.write(`${cyan(frames[0]!)} ${label}`)
86
90
  const timer = setInterval(() => {
87
- frame = (frame + 1) % frames.length;
88
- process.stdout.write(`\r${cyan(frames[frame]!)} ${label}`);
89
- }, 80);
91
+ frame = (frame + 1) % frames.length
92
+ process.stdout.write(`\r${cyan(frames[frame]!)} ${label}`)
93
+ }, 80)
90
94
  return () => {
91
- clearInterval(timer);
92
- process.stdout.write('\r\x1b[K');
93
- };
94
- }
95
-
96
- function formatDuration(durationMs: number) {
97
- const totalSeconds = Math.max(0, durationMs) / 1000;
98
- return `${totalSeconds.toFixed(totalSeconds < 10 ? 2 : 1)}s`;
95
+ clearInterval(timer)
96
+ process.stdout.write('\r\x1b[K')
97
+ }
99
98
  }
100
99
 
101
100
  function printNextSteps(dir: string, installed: boolean) {
102
- const commands = installed ? [`cd ${dir}`, 'bun dev'] : [`cd ${dir}`, 'bun install', 'bun dev'];
103
- const title = 'Next steps';
104
- const width = Math.max(title.length, ...commands.map(c => c.length)) + 2;
101
+ const commands = installed ? [`cd ${dir}`, 'bun dev'] : [`cd ${dir}`, 'bun install', 'bun dev']
102
+ const title = 'Next steps'
103
+ const width = Math.max(title.length, ...commands.map(c => c.length)) + 2
105
104
  const row = (text: string, colorFn: (s: string) => string = s => s) =>
106
- `${dim('│')} ${colorFn(text.padEnd(width))} ${dim('│')}`;
105
+ `${dim('│')} ${colorFn(text.padEnd(width))} ${dim('│')}`
107
106
 
108
- console.log('');
109
- console.log(dim(`┌${'─'.repeat(width + 2)}┐`));
110
- console.log(row(title, bold));
111
- console.log(row(''));
112
- for (const cmd of commands) console.log(row(cmd, cyan));
113
- console.log(dim(`└${'─'.repeat(width + 2)}┘`));
107
+ console.log('')
108
+ console.log(dim(`┌${'─'.repeat(width + 2)}┐`))
109
+ console.log(row(title, bold))
110
+ console.log(row(''))
111
+ for (const cmd of commands) console.log(row(cmd, cyan))
112
+ console.log(dim(`└${'─'.repeat(width + 2)}┘`))
114
113
  }
115
114
 
116
115
  function scaffoldFiles(name: string): Record<string, string> {
@@ -119,9 +118,18 @@ function scaffoldFiles(name: string): Record<string, string> {
119
118
  {
120
119
  name,
121
120
  private: true,
122
- scripts: { dev: 'pnext dev', build: 'pnext build', start: 'pnext start', analyze: 'pnext analyze' },
121
+ scripts: {
122
+ dev: 'pnext dev',
123
+ build: 'pnext build',
124
+ start: 'pnext start',
125
+ analyze: 'pnext analyze',
126
+ },
123
127
  dependencies: { preact: '^10' },
124
- devDependencies: { '@wular/pnext': '^0.0.1', typescript: '^5', '@types/bun': '^1' },
128
+ devDependencies: {
129
+ '@wular/pnext': pnextVersionRange(),
130
+ typescript: '^5',
131
+ '@types/bun': '^1',
132
+ },
125
133
  },
126
134
  null,
127
135
  2,
@@ -141,6 +149,6 @@ function scaffoldFiles(name: string): Record<string, string> {
141
149
  'app/counter.tsx': `'use client';\n\nimport { useState } from 'preact/hooks';\n\nexport default function Counter() {\n const [count, setCount] = useState(0);\n return <button onClick={() => setCount(count + 1)}>Count: {count}</button>;\n}\n`,
142
150
  'app/globals.css': `body {\n margin: 0;\n font-family: system-ui, sans-serif;\n}\n`,
143
151
  '.gitignore': `node_modules\n.pnext\n`,
144
- 'README.md': `# ${name}\n\nA pnext app.\n\n\`\`\`\nbun install\nbun dev\n\`\`\`\n\nDocs: node_modules/@wular/pnext/reference/overview.md\n`,
145
- };
152
+ 'README.md': `# ${name}\n\nA pnext app.\n\n\`\`\`\nbun install\nbun dev\n\`\`\`\n\nDocs: node_modules/@wular/pnext/reference/getting-started.md\n`,
153
+ }
146
154
  }
package/src/cli/dev.ts CHANGED
@@ -1,28 +1,28 @@
1
- import { dim } from '../utils/ansi';
2
- import { moduleGenerationStats } from '../dev/module-generations';
3
- import { markBoot, printBootTrace } from './boot-trace';
4
- import { browserHost, ensurePortFree, openBrowser, printServerReady } from './serve-ui';
1
+ import { dim } from '../utils/ansi'
2
+ import { moduleGenerationStats } from '../runtime/module-generations'
3
+ import { markBoot, printBootTrace } from './boot/trace'
4
+ import { browserHost, ensurePortFree, openBrowser, printServerReady } from './serve/ui'
5
5
 
6
- export const devProcessTitle = 'pnext-dev';
7
- export const devRestartEnv = 'PNEXT_DEV_RESTART';
6
+ export const devProcessTitle = 'pnext-dev'
7
+ export const devRestartEnv = 'PNEXT_DEV_RESTART'
8
8
 
9
- const defaultMaxDevRssMb = 2048;
10
- const defaultMaxEsbuildRssMb = 1024;
9
+ const defaultMaxDevRssMb = 2048
10
+ const defaultMaxEsbuildRssMb = 1024
11
11
  // A leaf edit supersedes a couple of generations, so this caps stale mass at roughly 300 MB -
12
12
  // about one recycle per 75 leaf edits, and one per ~30 on wide-shared-module edits that rename
13
13
  // most of a route graph.
14
- const defaultMaxStaleModules = 150;
14
+ const defaultMaxStaleModules = 150
15
15
  /** How long a recycle waits for in-flight responses before replacing the image. */
16
- const drainTimeoutMs = 5_000;
16
+ const drainTimeoutMs = 5_000
17
17
 
18
18
  export function nameDevProcess() {
19
- process.title = devProcessTitle;
19
+ process.title = devProcessTitle
20
20
  }
21
21
 
22
22
  export interface DevOptions {
23
- root?: string;
24
- port?: number;
25
- hostname?: string;
23
+ root?: string
24
+ port?: number
25
+ hostname?: string
26
26
  }
27
27
 
28
28
  /**
@@ -31,49 +31,49 @@ export interface DevOptions {
31
31
  * place, which frees the module graph without paying a second process spawn on every boot.
32
32
  */
33
33
  export async function dev(options: DevOptions = {}) {
34
- nameDevProcess();
34
+ nameDevProcess()
35
35
  // Loaded lazily so config resolution and the server graph start in parallel.
36
36
  const [{ loadConfig }, { startDevServer }] = await Promise.all([
37
37
  import('../config'),
38
38
  import('../dev/server'),
39
- ]);
40
- markBoot('dev:imports');
41
- const config = await loadConfig(options.root, { dev: true });
42
- markBoot('dev:config');
43
- const port = options.port ?? 3000;
44
- const hostname = options.hostname ?? 'localhost';
39
+ ])
40
+ markBoot('dev:imports')
41
+ const config = await loadConfig(options.root, { dev: true })
42
+ markBoot('dev:config')
43
+ const port = options.port ?? 3000
44
+ const hostname = options.hostname ?? 'localhost'
45
45
  // A memory-triggered restart can briefly race the previous listener's
46
46
  // shutdown, so give the port a moment to free before failing.
47
- await ensurePortFree(port, hostname, { attempts: 10 });
48
- markBoot('dev:port');
49
- const start = Date.now();
47
+ await ensurePortFree(port, hostname, { attempts: 10 })
48
+ markBoot('dev:port')
49
+ const start = Date.now()
50
50
  // Bisect switch, same role `PNEXT_DEV_RESTART_CACHE=0` plays for the restart
51
51
  // caches: turns the boot warm-up off so a measurement can price it.
52
52
  // eslint-disable-next-line turbo/no-undeclared-env-vars
53
- const warm = process.env.PNEXT_DEV_WARM !== '0';
54
- const server = await startDevServer({ config, port, hostname, warm });
55
- markBoot('dev:server');
56
- const elapsedMs = Date.now() - start;
57
- const url = `http://${browserHost(hostname)}:${server.port ?? port}`;
58
- printServerReady({ mode: 'dev', hostname, port: server.port ?? port, elapsedMs });
59
- printBootTrace();
53
+ const warm = process.env.PNEXT_DEV_WARM !== '0'
54
+ const server = await startDevServer({ config, port, hostname, warm })
55
+ markBoot('dev:server')
56
+ const elapsedMs = Date.now() - start
57
+ const url = `http://${browserHost(hostname)}:${server.port ?? port}`
58
+ printServerReady({ mode: 'dev', hostname, port: server.port ?? port, elapsedMs })
59
+ printBootTrace()
60
60
  // Boot compiles nothing (config loads natively), so the first compile would pay esbuild's service
61
61
  // spawn. Warm it here, after the banner - readiness must not wait on it. PNEXT_DEV_ESBUILD_WARM=0 opts out.
62
62
  // eslint-disable-next-line turbo/no-undeclared-env-vars
63
63
  if (process.env.PNEXT_DEV_ESBUILD_WARM !== '0') {
64
- void import('../utils/esbuild').then(module => module.warmEsbuildService());
64
+ void import('../utils/esbuild').then(module => module.warmEsbuildService())
65
65
  }
66
- registerShutdown(server);
67
- watchServerMemory(server);
68
- watchStaleModules(server);
69
- watchEsbuildMemory();
66
+ registerShutdown(server)
67
+ watchServerMemory(server)
68
+ watchStaleModules(server)
69
+ watchEsbuildMemory()
70
70
  // Hold the browser until the entry route has compiled, so it opens onto an
71
71
  // already-built page instead of a multi-second cold compile.
72
- if (server.warmup) console.log(dim('Warming up and opening the browser...'));
73
- await server.warmup;
72
+ if (server.warmup) console.log(dim('Warming up and opening the browser...'))
73
+ await server.warmup
74
74
  // A memory-triggered restart should refresh silently, not open another tab.
75
- if (process.env[devRestartEnv] !== '1') openBrowser(url);
76
- return server;
75
+ if (process.env[devRestartEnv] !== '1') openBrowser(url)
76
+ return server
77
77
  }
78
78
 
79
79
  // Every dev reload imports changed modules under fresh URLs, and the ES module
@@ -82,22 +82,22 @@ export async function dev(options: DevOptions = {}) {
82
82
  // preserved on disk) for getting the memory back.
83
83
  function watchServerMemory(server: DevServerHandle) {
84
84
  // eslint-disable-next-line turbo/no-undeclared-env-vars
85
- const limitMb = Number(process.env.PNEXT_DEV_MAX_RSS_MB || defaultMaxDevRssMb);
86
- if (!Number.isFinite(limitMb) || limitMb <= 0) return;
87
- const limitBytes = limitMb * 1024 * 1024;
85
+ const limitMb = Number(process.env.PNEXT_DEV_MAX_RSS_MB || defaultMaxDevRssMb)
86
+ if (!Number.isFinite(limitMb) || limitMb <= 0) return
87
+ const limitBytes = limitMb * 1024 * 1024
88
88
  const timer = setInterval(() => {
89
- const rss = process.memoryUsage.rss();
90
- if (rss < limitBytes) return;
91
- clearInterval(timer);
92
- const usedMb = Math.round(rss / (1024 * 1024));
89
+ const rss = process.memoryUsage.rss()
90
+ if (rss < limitBytes) return
91
+ clearInterval(timer)
92
+ const usedMb = Math.round(rss / (1024 * 1024))
93
93
  console.log(
94
94
  dim(
95
95
  `Dev server reached ${usedMb}MB of memory (limit ${limitMb}MB, set PNEXT_DEV_MAX_RSS_MB to change); restarting to release stale modules...`,
96
96
  ),
97
- );
98
- void restartDevProcess(server);
99
- }, 15_000);
100
- timer.unref();
97
+ )
98
+ void restartDevProcess(server)
99
+ }, 15_000)
100
+ timer.unref()
101
101
  }
102
102
 
103
103
  // The esbuild Go service self-drains its heap when idle, so two consecutive readings above the
@@ -105,35 +105,35 @@ function watchServerMemory(server: DevServerHandle) {
105
105
  // builds, never incremental contexts. A stop that races an in-flight build fails that one build;
106
106
  // dev asset caches drop failed builds, so the next request retries.
107
107
  function watchEsbuildMemory() {
108
- if (process.platform === 'win32') return;
108
+ if (process.platform === 'win32') return
109
109
  // eslint-disable-next-line turbo/no-undeclared-env-vars
110
- const limitMb = Number(process.env.PNEXT_DEV_MAX_ESBUILD_RSS_MB || defaultMaxEsbuildRssMb);
111
- if (!Number.isFinite(limitMb) || limitMb <= 0) return;
112
- let highTicks = 0;
110
+ const limitMb = Number(process.env.PNEXT_DEV_MAX_ESBUILD_RSS_MB || defaultMaxEsbuildRssMb)
111
+ if (!Number.isFinite(limitMb) || limitMb <= 0) return
112
+ let highTicks = 0
113
113
  const timer = setInterval(() => {
114
- const rssMb = esbuildServiceRssMb();
115
- highTicks = rssMb > limitMb ? highTicks + 1 : 0;
116
- if (highTicks < 2) return;
117
- highTicks = 0;
114
+ const rssMb = esbuildServiceRssMb()
115
+ highTicks = rssMb > limitMb ? highTicks + 1 : 0
116
+ if (highTicks < 2) return
117
+ highTicks = 0
118
118
  console.log(
119
119
  dim(
120
120
  `esbuild reached ${Math.round(rssMb)}MB of memory (limit ${limitMb}MB, set PNEXT_DEV_MAX_ESBUILD_RSS_MB to change); restarting it to release the heap...`,
121
121
  ),
122
- );
122
+ )
123
123
  void (async () => {
124
124
  try {
125
- const esbuild = await import('esbuild');
126
- await esbuild.stop();
125
+ const esbuild = await import('esbuild')
126
+ await esbuild.stop()
127
127
  } catch {
128
128
  // ignore: the service may already be gone
129
129
  }
130
130
  // stop() can strand in-flight build promises unsettled; fail their
131
131
  // waiters so requests retry against the respawned service.
132
- const { failInFlightClientBuilds } = await import('../dev/server');
133
- failInFlightClientBuilds('esbuild service restarted by the memory watchdog');
134
- })();
135
- }, 15_000);
136
- timer.unref();
132
+ const { failInFlightClientBuilds } = await import('../dev/server')
133
+ failInFlightClientBuilds('esbuild service restarted by the memory watchdog')
134
+ })()
135
+ }, 15_000)
136
+ timer.unref()
137
137
  }
138
138
 
139
139
  /**
@@ -146,48 +146,48 @@ function watchEsbuildMemory() {
146
146
  */
147
147
  function watchStaleModules(server: DevServerHandle) {
148
148
  // eslint-disable-next-line turbo/no-undeclared-env-vars
149
- const limit = Number(process.env.PNEXT_DEV_MAX_STALE_MODULES || defaultMaxStaleModules);
150
- if (!Number.isFinite(limit) || limit <= 0) return;
149
+ const limit = Number(process.env.PNEXT_DEV_MAX_STALE_MODULES || defaultMaxStaleModules)
150
+ if (!Number.isFinite(limit) || limit <= 0) return
151
151
  const timer = setInterval(() => {
152
- const { stale } = moduleGenerationStats();
153
- if (stale < limit) return;
154
- clearInterval(timer);
152
+ const { stale } = moduleGenerationStats()
153
+ if (stale < limit) return
154
+ clearInterval(timer)
155
155
  console.log(
156
156
  dim(
157
157
  `Dev server is holding ${stale} superseded module generations (limit ${limit}, set PNEXT_DEV_MAX_STALE_MODULES to change); restarting to release them...`,
158
158
  ),
159
- );
160
- void restartDevProcess(server);
161
- }, 15_000);
162
- timer.unref();
159
+ )
160
+ void restartDevProcess(server)
161
+ }, 15_000)
162
+ timer.unref()
163
163
  }
164
164
 
165
165
  // Our esbuild service children: [pid, RSS in MB] per process.
166
166
  function esbuildServices(): [number, number][] {
167
- const found: [number, number][] = [];
167
+ const found: [number, number][] = []
168
168
  try {
169
- const stdout = Bun.spawnSync(['ps', '-ax', '-o', 'pid=,ppid=,rss=,ucomm=']).stdout.toString();
169
+ const stdout = Bun.spawnSync(['ps', '-ax', '-o', 'pid=,ppid=,rss=,ucomm=']).stdout.toString()
170
170
  for (const line of stdout.split('\n')) {
171
- const [pid, ppid, rss, ...name] = line.trim().split(/\s+/);
171
+ const [pid, ppid, rss, ...name] = line.trim().split(/\s+/)
172
172
  if (Number(ppid) === process.pid && name.join(' ').includes('esbuild')) {
173
- found.push([Number(pid), Number(rss) / 1024]);
173
+ found.push([Number(pid), Number(rss) / 1024])
174
174
  }
175
175
  }
176
176
  } catch {
177
177
  // ignore: no ps available means no monitoring, not a broken dev server
178
178
  }
179
- return found;
179
+ return found
180
180
  }
181
181
 
182
182
  // RSS of our esbuild service, in MB (0 when not running).
183
183
  function esbuildServiceRssMb() {
184
- return esbuildServices().reduce((total, [, rssMb]) => total + rssMb, 0);
184
+ return esbuildServices().reduce((total, [, rssMb]) => total + rssMb, 0)
185
185
  }
186
186
 
187
187
  interface DevServerHandle {
188
- stop(closeActiveConnections?: boolean): unknown;
188
+ stop(closeActiveConnections?: boolean): unknown
189
189
  /** Resolves once nothing is being served (or the timeout elapses). */
190
- drain?(timeoutMs: number): Promise<boolean>;
190
+ drain?(timeoutMs: number): Promise<boolean>
191
191
  }
192
192
 
193
193
  /**
@@ -201,9 +201,9 @@ async function restartDevProcess(server: DevServerHandle): Promise<void> {
201
201
  try {
202
202
  // Stop accepting, then let what is already being served finish: an exec
203
203
  // mid-response would leave the browser with a truncated page and no error.
204
- server.stop(false);
205
- await server.drain?.(drainTimeoutMs);
206
- server.stop(true);
204
+ server.stop(false)
205
+ await server.drain?.(drainTimeoutMs)
206
+ server.stop(true)
207
207
  } catch {
208
208
  // ignore: we are being replaced regardless
209
209
  }
@@ -211,72 +211,72 @@ async function restartDevProcess(server: DevServerHandle): Promise<void> {
211
211
  // image that owned it — with exactly the heap this restart is reclaiming.
212
212
  for (const [pid] of esbuildServices()) {
213
213
  try {
214
- process.kill(pid, 'SIGTERM');
214
+ process.kill(pid, 'SIGTERM')
215
215
  } catch {
216
216
  // ignore: already gone
217
217
  }
218
218
  }
219
- const argv = [process.execPath, '--conditions=react-server', ...process.argv.slice(1)];
220
- const env = { ...process.env, [devRestartEnv]: '1' };
219
+ const argv = [process.execPath, '--conditions=react-server', ...process.argv.slice(1)]
220
+ const env = { ...process.env, [devRestartEnv]: '1' }
221
221
  try {
222
- await execSelf(argv, env);
222
+ await execSelf(argv, env)
223
223
  } catch {
224
224
  // ignore: fall through to the spawn path
225
225
  }
226
226
  // Only reached when exec is unavailable or failed.
227
- Bun.spawn(argv, { stdin: 'inherit', stdout: 'inherit', stderr: 'inherit', env });
228
- process.exit(0);
227
+ Bun.spawn(argv, { stdin: 'inherit', stdout: 'inherit', stderr: 'inherit', env })
228
+ process.exit(0)
229
229
  }
230
230
 
231
231
  // execve(2) via libc. argv/envp are NUL-terminated C string arrays, and the
232
232
  // pointer array must stay reachable until the call returns (it never does on
233
233
  // success).
234
234
  async function execSelf(argv: string[], env: Record<string, string | undefined>): Promise<void> {
235
- if (process.platform === 'win32') return;
236
- const { dlopen, FFIType, ptr, suffix } = await import('bun:ffi');
237
- const libc = process.platform === 'darwin' ? '/usr/lib/libSystem.B.dylib' : `libc.${suffix}.6`;
235
+ if (process.platform === 'win32') return
236
+ const { dlopen, FFIType, ptr, suffix } = await import('bun:ffi')
237
+ const libc = process.platform === 'darwin' ? '/usr/lib/libSystem.B.dylib' : `libc.${suffix}.6`
238
238
  const { symbols } = dlopen(libc, {
239
239
  execve: {
240
240
  args: [FFIType.cstring, FFIType.ptr, FFIType.ptr],
241
241
  returns: FFIType.i32,
242
242
  },
243
- });
244
- const encoder = new TextEncoder();
245
- const cString = (value: string) => encoder.encode(`${value}\0`);
243
+ })
244
+ const encoder = new TextEncoder()
245
+ const cString = (value: string) => encoder.encode(`${value}\0`)
246
246
  const cArray = (values: string[]) => {
247
- const cells = values.map(cString);
248
- const array = new BigInt64Array(cells.length + 1);
247
+ const cells = values.map(cString)
248
+ const array = new BigInt64Array(cells.length + 1)
249
249
  cells.forEach((cell, index) => {
250
- array[index] = BigInt(ptr(cell));
251
- });
252
- return { array, cells };
253
- };
254
- const args = cArray(argv);
250
+ array[index] = BigInt(ptr(cell))
251
+ })
252
+ return { array, cells }
253
+ }
254
+ const args = cArray(argv)
255
255
  const envp = cArray(
256
256
  Object.entries(env)
257
257
  .filter(([, value]) => value !== undefined)
258
258
  .map(([key, value]) => `${key}=${value}`),
259
- );
260
- symbols.execve(cString(argv[0]!), ptr(args.array), ptr(envp.array));
259
+ )
260
+ symbols.execve(cString(argv[0]!), ptr(args.array), ptr(envp.array))
261
261
  // execve only returns on failure; keep the buffers alive until then.
262
- void [args.cells, envp.cells];
262
+ void [args.cells, envp.cells]
263
263
  }
264
264
 
265
265
  // Stop the server and run process `exit` handlers on a terminating signal,
266
266
  // so killing the dev server never leaves orphaned subprocesses behind.
267
267
  function registerShutdown(server: DevServerHandle) {
268
- let closing = false;
268
+ let closing = false
269
269
  const shutdown = () => {
270
- if (closing) return;
271
- closing = true;
270
+ if (closing) return
271
+ closing = true
272
272
  try {
273
- server.stop(true);
273
+ server.stop(true)
274
274
  } catch {
275
275
  // ignore: process is exiting regardless
276
276
  }
277
- process.exit(0);
278
- };
277
+ process.exit(0)
278
+ }
279
279
  for (const signal of ['SIGINT', 'SIGTERM', 'SIGHUP'] as const) {
280
- process.once(signal, shutdown);
280
+ process.once(signal, shutdown)
281
281
  }
282
282
  }