@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
@@ -3,22 +3,22 @@
3
3
  // as the action wire's $$pnext_date) instead of throwing; the client/server
4
4
  // revive the marker back into the original view. assertSerializable accepts
5
5
  // them (they are "serializable" via the marker path) rather than rejecting.
6
- const TYPED_ARRAY_MARKER = '$$pnext_typed_array';
7
- const ARRAY_BUFFER_MARKER = '$$pnext_array_buffer';
6
+ const TYPED_ARRAY_MARKER = '$$pnext_typed_array'
7
+ const ARRAY_BUFFER_MARKER = '$$pnext_array_buffer'
8
8
  // Map/Set are part of React's flight wire vocabulary (client components can receive them as props); pnext
9
9
  // does not stream them as distinct RSC row types yet, so they ride as ordinary marker objects, entries
10
10
  // encoded recursively like the binary markers above, instead of throwing "must be a plain object". Client
11
11
  // code that only round-trips the value sees a marker object rather than a live Map/Set instance - a known
12
12
  // gap, not a full flight-protocol Map/Set.
13
- const MAP_MARKER = '$$pnext_map';
14
- const SET_MARKER = '$$pnext_set';
13
+ const MAP_MARKER = '$$pnext_map'
14
+ const SET_MARKER = '$$pnext_set'
15
15
  // Cyclic props (a client component receiving `obj.self === obj`) are part of React's flight vocabulary:
16
16
  // flight emits a BACK-REFERENCE to the row/path the value was first written at rather than expanding it
17
17
  // forever. Same idea here, scoped to the ancestor chain: an object that reappears INSIDE ITSELF is written as
18
18
  // `{$$pnext_ref: [...path from the props root]}` and the client patches the original object back in,
19
19
  // restoring identity. Only true cycles are encoded this way - a value that merely appears twice in different
20
20
  // branches is still expanded, so every acyclic payload is byte-identical to what it was before.
21
- const REF_MARKER = '$$pnext_ref';
21
+ const REF_MARKER = '$$pnext_ref'
22
22
 
23
23
  type TypedArray =
24
24
  | Int8Array
@@ -31,26 +31,26 @@ type TypedArray =
31
31
  | Float32Array
32
32
  | Float64Array
33
33
  | BigInt64Array
34
- | BigUint64Array;
34
+ | BigUint64Array
35
35
 
36
36
  function isTypedArray(value: unknown): value is TypedArray {
37
- return ArrayBuffer.isView(value) && !(value instanceof DataView);
37
+ return ArrayBuffer.isView(value) && !(value instanceof DataView)
38
38
  }
39
39
 
40
40
  function bytesToBase64(bytes: Uint8Array): string {
41
- if (typeof Buffer !== 'undefined') return Buffer.from(bytes).toString('base64');
42
- let binary = '';
43
- for (const byte of bytes) binary += String.fromCharCode(byte);
44
- return btoa(binary);
41
+ if (typeof Buffer !== 'undefined') return Buffer.from(bytes).toString('base64')
42
+ let binary = ''
43
+ for (const byte of bytes) binary += String.fromCharCode(byte)
44
+ return btoa(binary)
45
45
  }
46
46
 
47
47
  function encodeTypedArray(value: TypedArray) {
48
- const bytes = new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
49
- return { [TYPED_ARRAY_MARKER]: { type: value.constructor.name, data: bytesToBase64(bytes) } };
48
+ const bytes = new Uint8Array(value.buffer, value.byteOffset, value.byteLength)
49
+ return { [TYPED_ARRAY_MARKER]: { type: value.constructor.name, data: bytesToBase64(bytes) } }
50
50
  }
51
51
 
52
52
  function encodeArrayBuffer(value: ArrayBuffer) {
53
- return { [ARRAY_BUFFER_MARKER]: bytesToBase64(new Uint8Array(value)) };
53
+ return { [ARRAY_BUFFER_MARKER]: bytesToBase64(new Uint8Array(value)) }
54
54
  }
55
55
 
56
56
  /**
@@ -66,24 +66,20 @@ function encodeBinary(
66
66
  ancestors = new Map<object, string[]>(),
67
67
  path: string[] = [],
68
68
  ): unknown {
69
- if (value === null || typeof value !== 'object') return value;
70
- if (isTypedArray(value)) return encodeTypedArray(value);
71
- if (value instanceof ArrayBuffer) return encodeArrayBuffer(value);
72
- const ancestorPath = ancestors.get(value);
73
- if (ancestorPath) return { [REF_MARKER]: ancestorPath };
74
- ancestors.set(value, path);
75
- const encoded = encodeContainer(value, ancestors, path);
76
- ancestors.delete(value);
77
- return encoded;
69
+ if (value === null || typeof value !== 'object') return value
70
+ if (isTypedArray(value)) return encodeTypedArray(value)
71
+ if (value instanceof ArrayBuffer) return encodeArrayBuffer(value)
72
+ const ancestorPath = ancestors.get(value)
73
+ if (ancestorPath) return { [REF_MARKER]: ancestorPath }
74
+ ancestors.set(value, path)
75
+ const encoded = encodeContainer(value, ancestors, path)
76
+ ancestors.delete(value)
77
+ return encoded
78
78
  }
79
79
 
80
- function encodeContainer(
81
- value: object,
82
- ancestors: Map<object, string[]>,
83
- path: string[],
84
- ): unknown {
80
+ function encodeContainer(value: object, ancestors: Map<object, string[]>, path: string[]): unknown {
85
81
  if (Array.isArray(value)) {
86
- return value.map((item, index) => encodeBinary(item, ancestors, [...path, String(index)]));
82
+ return value.map((item, index) => encodeBinary(item, ancestors, [...path, String(index)]))
87
83
  }
88
84
  if (value instanceof Map) {
89
85
  return {
@@ -91,22 +87,22 @@ function encodeContainer(
91
87
  encodeBinary(k, ancestors),
92
88
  encodeBinary(v, ancestors),
93
89
  ]),
94
- };
90
+ }
95
91
  }
96
92
  if (value instanceof Set) {
97
- return { [SET_MARKER]: [...value].map(item => encodeBinary(item, ancestors)) };
93
+ return { [SET_MARKER]: [...value].map(item => encodeBinary(item, ancestors)) }
98
94
  }
99
- if (Object.getPrototypeOf(value) !== Object.prototype) return value;
100
- const out: Record<string, unknown> = {};
95
+ if (Object.getPrototypeOf(value) !== Object.prototype) return value
96
+ const out: Record<string, unknown> = {}
101
97
  for (const [key, item] of Object.entries(value)) {
102
- out[key] = encodeBinary(item, ancestors, [...path, key]);
98
+ out[key] = encodeBinary(item, ancestors, [...path, key])
103
99
  }
104
- return out;
100
+ return out
105
101
  }
106
102
 
107
103
  // Errors reach `error.tsx` as props and ride the same marker convention (the
108
104
  // encoder for this one lives on the render side, with the boundary props).
109
- const ERROR_MARKER = '$$pnextError';
105
+ const ERROR_MARKER = '$$pnextError'
110
106
 
111
107
  /**
112
108
  * Revive the wire markers `serializeProps` wrote, IN PLACE:
@@ -124,22 +120,22 @@ export function reviveSerializedRefs<T>(
124
120
  root: T,
125
121
  extra?: (node: Record<string, unknown>) => unknown,
126
122
  ): T {
127
- if (root === null || typeof root !== 'object') return root;
123
+ if (root === null || typeof root !== 'object') return root
128
124
  const visit = (node: Record<string, unknown>): void => {
129
125
  for (const key of Object.keys(node)) {
130
- const item = node[key];
131
- if (item === null || typeof item !== 'object' || ArrayBuffer.isView(item)) continue;
132
- const child = item as Record<string, unknown>;
133
- const revived = refTarget(root, child) ?? extra?.(child) ?? binaryTarget(child);
126
+ const item = node[key]
127
+ if (item === null || typeof item !== 'object' || ArrayBuffer.isView(item)) continue
128
+ const child = item as Record<string, unknown>
129
+ const revived = refTarget(root, child) ?? extra?.(child) ?? binaryTarget(child)
134
130
  if (revived !== undefined) {
135
- node[key] = revived;
136
- continue;
131
+ node[key] = revived
132
+ continue
137
133
  }
138
- visit(child);
134
+ visit(child)
139
135
  }
140
- };
141
- visit(root as Record<string, unknown>);
142
- return root;
136
+ }
137
+ visit(root as Record<string, unknown>)
138
+ return root
143
139
  }
144
140
 
145
141
  /**
@@ -149,17 +145,17 @@ export function reviveSerializedRefs<T>(
149
145
  * untouched when compat is off), and only compat entries import this name.
150
146
  */
151
147
  export function reviveSerializedErrorRefs<T>(root: T): T {
152
- return reviveSerializedRefs(root, errorTarget);
148
+ return reviveSerializedRefs(root, errorTarget)
153
149
  }
154
150
 
155
151
  function errorTarget(node: Record<string, unknown>): Error | undefined {
156
- const marker = node[ERROR_MARKER];
157
- if (marker === null || typeof marker !== 'object') return undefined;
158
- const data = marker as { name?: unknown; message?: unknown; digest?: unknown };
159
- const error = new Error(typeof data.message === 'string' ? data.message : '');
160
- if (typeof data.name === 'string') error.name = data.name;
161
- if (typeof data.digest === 'string') (error as Error & { digest?: string }).digest = data.digest;
162
- return error;
152
+ const marker = node[ERROR_MARKER]
153
+ if (marker === null || typeof marker !== 'object') return undefined
154
+ const data = marker as { name?: unknown; message?: unknown; digest?: unknown }
155
+ const error = new Error(typeof data.message === 'string' ? data.message : '')
156
+ if (typeof data.name === 'string') error.name = data.name
157
+ if (typeof data.digest === 'string') (error as Error & { digest?: string }).digest = data.digest
158
+ return error
163
159
  }
164
160
 
165
161
  // The wire carries the view's constructor NAME. Resolved off the global rather than a name-to-constructor
@@ -167,48 +163,48 @@ function errorTarget(node: Record<string, unknown>): Error | undefined {
167
163
  // so any other name - including one that resolves to something else entirely - resolves to undefined and the
168
164
  // marker is left alone.
169
165
  function typedArrayConstructor(name: string) {
170
- const constructor = (globalThis as unknown as Record<string, unknown>)[name];
166
+ const constructor = (globalThis as unknown as Record<string, unknown>)[name]
171
167
  return typeof constructor === 'function' && 'BYTES_PER_ELEMENT' in constructor
172
168
  ? (constructor as unknown as new (buffer: ArrayBuffer) => TypedArray)
173
- : undefined;
169
+ : undefined
174
170
  }
175
171
 
176
172
  // Decode side is client-only (the encoder is what runs on the server), so no
177
173
  // Buffer fast path — `atob` is global in every runtime that reaches this.
178
174
  function base64ToBytes(data: string): Uint8Array {
179
- return Uint8Array.from(atob(data), character => character.charCodeAt(0));
175
+ return Uint8Array.from(atob(data), character => character.charCodeAt(0))
180
176
  }
181
177
 
182
178
  function binaryTarget(node: Record<string, unknown>): TypedArray | ArrayBuffer | undefined {
183
- const buffer = node[ARRAY_BUFFER_MARKER];
184
- if (typeof buffer === 'string') return base64ToBytes(buffer).buffer as ArrayBuffer;
185
- const typed = node[TYPED_ARRAY_MARKER];
186
- if (typed === null || typeof typed !== 'object') return undefined;
187
- const { type, data } = typed as { type?: unknown; data?: unknown };
188
- if (typeof type !== 'string' || typeof data !== 'string') return undefined;
189
- const Constructor = typedArrayConstructor(type);
190
- return Constructor ? new Constructor(base64ToBytes(data).buffer as ArrayBuffer) : undefined;
179
+ const buffer = node[ARRAY_BUFFER_MARKER]
180
+ if (typeof buffer === 'string') return base64ToBytes(buffer).buffer as ArrayBuffer
181
+ const typed = node[TYPED_ARRAY_MARKER]
182
+ if (typed === null || typeof typed !== 'object') return undefined
183
+ const { type, data } = typed as { type?: unknown; data?: unknown }
184
+ if (typeof type !== 'string' || typeof data !== 'string') return undefined
185
+ const Constructor = typedArrayConstructor(type)
186
+ return Constructor ? new Constructor(base64ToBytes(data).buffer as ArrayBuffer) : undefined
191
187
  }
192
188
 
193
189
  function refTarget(root: unknown, node: Record<string, unknown>): unknown {
194
- const path = node[REF_MARKER];
195
- if (!Array.isArray(path)) return undefined;
196
- let current: unknown = root;
190
+ const path = node[REF_MARKER]
191
+ if (!Array.isArray(path)) return undefined
192
+ let current: unknown = root
197
193
  for (const key of path) {
198
- if (current === null || typeof current !== 'object') return undefined;
199
- current = (current as Record<string, unknown>)[String(key)];
194
+ if (current === null || typeof current !== 'object') return undefined
195
+ current = (current as Record<string, unknown>)[String(key)]
200
196
  }
201
- return current;
197
+ return current
202
198
  }
203
199
 
204
200
  /** A preact vnode: `h` sets `constructor` to undefined on every one it makes. */
205
201
  export function isElementLike(value: unknown): boolean {
206
- if (value === null || typeof value !== 'object') return false;
202
+ if (value === null || typeof value !== 'object') return false
207
203
  return (
208
204
  (value as { constructor?: unknown }).constructor === undefined &&
209
205
  'type' in value &&
210
206
  'props' in value
211
- );
207
+ )
212
208
  }
213
209
 
214
210
  export function assertSerializable(
@@ -219,59 +215,59 @@ export function assertSerializable(
219
215
  // static-slots), so they are serializable there. Server-action args/returns keep throwing.
220
216
  allowElements = false,
221
217
  ) {
222
- if (value == null) return;
223
- if (allowElements && isElementLike(value)) return;
224
- const type = typeof value;
225
- if (type === 'string' || type === 'number' || type === 'boolean') return;
218
+ if (value == null) return
219
+ if (allowElements && isElementLike(value)) return
220
+ const type = typeof value
221
+ if (type === 'string' || type === 'number' || type === 'boolean') return
226
222
  if (type === 'function' || type === 'symbol' || type === 'bigint' || type === 'undefined') {
227
- throw new Error(`${path} is not serializable: ${type}`);
223
+ throw new Error(`${path} is not serializable: ${type}`)
228
224
  }
229
225
  // Typed arrays / ArrayBuffers are serializable via the binary marker path.
230
- if (isTypedArray(value) || value instanceof ArrayBuffer) return;
226
+ if (isTypedArray(value) || value instanceof ArrayBuffer) return
231
227
  if (value instanceof Date || value instanceof URL) {
232
- throw new Error(`${path} must be a plain JSON value`);
228
+ throw new Error(`${path} must be a plain JSON value`)
233
229
  }
234
- if (typeof value !== 'object') return;
230
+ if (typeof value !== 'object') return
235
231
  // A value that contains ITSELF is serializable: encodeBinary writes it as a
236
232
  // `$$pnext_ref` back-reference (React flight does the same), so stop walking
237
233
  // rather than rejecting the props.
238
- if (seen.has(value)) return;
239
- seen.add(value);
234
+ if (seen.has(value)) return
235
+ seen.add(value)
240
236
 
241
237
  if (Array.isArray(value)) {
242
238
  value.forEach((item, index) =>
243
239
  assertSerializable(item, `${path}[${index}]`, seen, allowElements),
244
- );
245
- return;
240
+ )
241
+ return
246
242
  }
247
243
 
248
- // The slot walk (islands/static-slots) never enters Map/Set, so elements inside them must
244
+ // The slot walk (render/static-slots) never enters Map/Set, so elements inside them must
249
245
  // still throw rather than ship mangled.
250
246
  if (value instanceof Map) {
251
- let index = 0;
247
+ let index = 0
252
248
  for (const [key, item] of value.entries()) {
253
- assertSerializable(key, `${path}<Map key ${index}>`, seen);
254
- assertSerializable(item, `${path}<Map value ${index}>`, seen);
255
- index++;
249
+ assertSerializable(key, `${path}<Map key ${index}>`, seen)
250
+ assertSerializable(item, `${path}<Map value ${index}>`, seen)
251
+ index++
256
252
  }
257
- return;
253
+ return
258
254
  }
259
255
 
260
256
  if (value instanceof Set) {
261
- let index = 0;
257
+ let index = 0
262
258
  for (const item of value) {
263
- assertSerializable(item, `${path}<Set item ${index}>`, seen);
264
- index++;
259
+ assertSerializable(item, `${path}<Set item ${index}>`, seen)
260
+ index++
265
261
  }
266
- return;
262
+ return
267
263
  }
268
264
 
269
265
  if (Object.getPrototypeOf(value) !== Object.prototype) {
270
- throw new Error(`${path} must be a plain object`);
266
+ throw new Error(`${path} must be a plain object`)
271
267
  }
272
268
 
273
269
  for (const [key, item] of Object.entries(value)) {
274
- assertSerializable(item, `${path}.${key}`, seen, allowElements);
270
+ assertSerializable(item, `${path}.${key}`, seen, allowElements)
275
271
  }
276
272
  }
277
273
 
@@ -291,26 +287,26 @@ export function assertSerializable(
291
287
  // original) must not split the tainted set.
292
288
  // ---------------------------------------------------------------------------
293
289
 
294
- const TAINT_REGISTRY_KEY = '__pnext_tainted_values__';
290
+ const TAINT_REGISTRY_KEY = '__pnext_tainted_values__'
295
291
 
296
292
  /** Dev message plus the redacted text prod shows in its place. */
297
293
  export interface TaintMessages {
298
- dev: string;
299
- prod: string;
294
+ dev: string
295
+ prod: string
300
296
  }
301
297
 
302
298
  function taintRegistry(): Map<object, TaintMessages> {
303
- const host = globalThis as { [TAINT_REGISTRY_KEY]?: Map<object, TaintMessages> };
304
- const existing = host[TAINT_REGISTRY_KEY];
305
- if (existing) return existing;
306
- const created = new Map<object, TaintMessages>();
307
- host[TAINT_REGISTRY_KEY] = created;
308
- return created;
299
+ const host = globalThis as { [TAINT_REGISTRY_KEY]?: Map<object, TaintMessages> }
300
+ const existing = host[TAINT_REGISTRY_KEY]
301
+ if (existing) return existing
302
+ const created = new Map<object, TaintMessages>()
303
+ host[TAINT_REGISTRY_KEY] = created
304
+ return created
309
305
  }
310
306
 
311
307
  /** Register `value` as unsafe to pass to a client component. */
312
308
  export function taintObjectReference(messages: TaintMessages, value: object): void {
313
- taintRegistry().set(value, messages);
309
+ taintRegistry().set(value, messages)
314
310
  }
315
311
 
316
312
  /**
@@ -319,60 +315,57 @@ export function taintObjectReference(messages: TaintMessages, value: object): vo
319
315
  * identity the check relies on).
320
316
  */
321
317
  export function assertNotTainted(value: unknown, seen = new Set<unknown>()): void {
322
- const registry = taintRegistry();
323
- if (registry.size === 0) return;
324
- if (value === null || typeof value !== 'object') return;
325
- const messages = registry.get(value);
318
+ const registry = taintRegistry()
319
+ if (registry.size === 0) return
320
+ if (value === null || typeof value !== 'object') return
321
+ const messages = registry.get(value)
326
322
  if (messages !== undefined) {
327
323
  // Next surfaces the explanatory message in dev only; prod renders React's
328
324
  // redacted RSC error text in the nearest error boundary.
329
325
  throw new Error(
330
326
  // eslint-disable-next-line turbo/no-undeclared-env-vars
331
327
  process.env.NODE_ENV === 'development' ? messages.dev : messages.prod,
332
- );
328
+ )
333
329
  }
334
- if (seen.has(value)) return;
335
- seen.add(value);
330
+ if (seen.has(value)) return
331
+ seen.add(value)
336
332
  if (Array.isArray(value)) {
337
- for (const item of value) assertNotTainted(item, seen);
338
- return;
333
+ for (const item of value) assertNotTainted(item, seen)
334
+ return
339
335
  }
340
336
  if (value instanceof Map) {
341
337
  for (const [key, item] of value.entries()) {
342
- assertNotTainted(key, seen);
343
- assertNotTainted(item, seen);
338
+ assertNotTainted(key, seen)
339
+ assertNotTainted(item, seen)
344
340
  }
345
- return;
341
+ return
346
342
  }
347
343
  if (value instanceof Set) {
348
- for (const item of value) assertNotTainted(item, seen);
349
- return;
344
+ for (const item of value) assertNotTainted(item, seen)
345
+ return
350
346
  }
351
- const proto = Object.getPrototypeOf(value) as object | null;
352
- if (proto !== Object.prototype && proto !== null) return;
353
- for (const item of Object.values(value)) assertNotTainted(item, seen);
347
+ const proto = Object.getPrototypeOf(value) as object | null
348
+ if (proto !== Object.prototype && proto !== null) return
349
+ for (const item of Object.values(value)) assertNotTainted(item, seen)
354
350
  }
355
351
 
356
352
  export function serializeProps(value: unknown, options?: { allowElements?: boolean }) {
357
- assertNotTainted(value);
358
- assertSerializable(value, 'props', new Set(), options?.allowElements);
359
- return JSON.stringify(encodeBinary(value)).replace(
360
- /[<>&\u2028\u2029]/g,
361
- char => {
362
- switch (char) {
363
- case '<':
364
- return '\\u003c';
365
- case '>':
366
- return '\\u003e';
367
- case '&':
368
- return '\\u0026';
369
- case '\u2028':
370
- return '\\u2028';
371
- case '\u2029':
372
- return '\\u2029';
373
- default:
374
- return char;
375
- }
376
- },
377
- );
353
+ assertNotTainted(value)
354
+ assertSerializable(value, 'props', new Set(), options?.allowElements)
355
+ return JSON.stringify(encodeBinary(value)).replace(/[<>&\u2028\u2029]/g, char => {
356
+ switch (char) {
357
+ case '<':
358
+ return '\\u003c'
359
+ case '>':
360
+ return '\\u003e'
361
+ case '&':
362
+ return '\\u0026'
363
+ case '\u2028':
364
+ return '\\u2028'
365
+ case '\u2029':
366
+ return '\\u2029'
367
+ default:
368
+ return char
369
+ }
370
+ })
378
371
  }
@@ -1,39 +1,39 @@
1
- import { dim } from './ansi';
1
+ import { dim } from './ansi'
2
2
 
3
3
  export interface VerboseLogger {
4
- readonly enabled: boolean;
5
- log(message: string): void;
6
- step<T>(label: string, task: () => Promise<T>): Promise<T>;
4
+ readonly enabled: boolean
5
+ log(message: string): void
6
+ step<T>(label: string, task: () => Promise<T>): Promise<T>
7
7
  }
8
8
 
9
9
  export function createVerboseLogger(enabled: boolean, scope: string): VerboseLogger {
10
- const prefix = dim(`pnext ${scope}`);
10
+ const prefix = dim(`pnext ${scope}`)
11
11
  // Stamp every line with time-since-process-start: once stages run in
12
12
  // parallel their lines interleave, and only the stamps say what overlapped.
13
13
  const write = (message: string) =>
14
- console.log(`${prefix} ${dim(`@${(performance.now() / 1000).toFixed(2)}s`)} ${message}`);
14
+ console.log(`${prefix} ${dim(`@${(performance.now() / 1000).toFixed(2)}s`)} ${message}`)
15
15
 
16
16
  return {
17
17
  enabled,
18
18
  log(message) {
19
- if (enabled) write(message);
19
+ if (enabled) write(message)
20
20
  },
21
21
  async step(label, task) {
22
- if (!enabled) return task();
23
- write(label);
24
- const start = performance.now();
22
+ if (!enabled) return task()
23
+ write(label)
24
+ const start = performance.now()
25
25
  try {
26
- return await task();
26
+ return await task()
27
27
  } finally {
28
- write(` ${dim(`↳ ${label} ${formatDuration(performance.now() - start)}`)}`);
28
+ write(` ${dim(`↳ ${label} ${formatDuration(performance.now() - start)}`)}`)
29
29
  }
30
30
  },
31
- };
31
+ }
32
32
  }
33
33
 
34
- function formatDuration(durationMs: number) {
35
- const ms = Math.max(0, durationMs);
36
- if (ms < 10) return `${ms.toFixed(1)}ms`;
37
- if (ms < 1000) return `${Math.round(ms)}ms`;
38
- return `${(ms / 1000).toFixed(ms < 10000 ? 2 : 1)}s`;
34
+ export function formatDuration(durationMs: number) {
35
+ const ms = Math.max(0, durationMs)
36
+ if (ms < 10) return `${ms.toFixed(1)}ms`
37
+ if (ms < 1000) return `${Math.round(ms)}ms`
38
+ return `${(ms / 1000).toFixed(ms < 10000 ? 2 : 1)}s`
39
39
  }
@@ -1,35 +0,0 @@
1
- # pnext
2
-
3
- pnext is a Preact framework for file-routed applications. It keeps familiar Next-style routing and rendering semantics where they help, and diverges where pnext needs a simpler or smaller model.
4
-
5
- It renders on the server by default, passes request data through explicit props, provides strong generated route type safety, and ships client JavaScript only for components that opt into running in the browser.
6
-
7
- ## Core Model
8
-
9
- - Routes live in an `app/` directory.
10
- - `page.tsx` files define UI routes.
11
- - `layout.tsx` files export metadata, viewport, and can wrap descendant pages.
12
- - `route.ts` files define HTTP handlers.
13
- - `proxy.ts` or `middleware.ts` can run before route matching.
14
- - `loading.tsx`, `error.tsx`, and `not-found.tsx` define route fallbacks.
15
- - Pages and layouts are pnext Server Components by default.
16
- - Server components can be async.
17
- - Pages without client components emit HTML without pnext client JavaScript.
18
- - Client Components can be loaded with `dynamic({ load: 'visible' })` and deferred until visible.
19
- - React compatibility mode supported via `compat.react`.
20
- - Next compatibility mode supported via `compat.next`.
21
- - Experimental React Compiler support for React-style Client Components via `compat.reactCompiler`.
22
-
23
- ## References
24
-
25
- - [Config](./config.md)
26
- - [Routing](./routing.md)
27
- - [Metadata](./metadata.md)
28
- - [Navigation](./navigation.md)
29
- - [Rendering](./rendering.md)
30
- - [CSS](./css.md)
31
- - [Environment Variables](./env.md)
32
- - [Compatibility](./compat.md)
33
- - [Typegen](./typegen.md)
34
- - [Dev Server](./dev.md)
35
- - [Performance](./performance.md)