@wular/pnext 0.0.4 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (395) hide show
  1. package/README.md +22 -16
  2. package/bin/pnext +6 -1
  3. package/config/lint/base.js +7 -7
  4. package/config/ts/base.json +2 -4
  5. package/config/ts/react.json +2 -6
  6. package/package.json +23 -2
  7. package/reference/compat.md +87 -22
  8. package/reference/config.md +40 -93
  9. package/reference/css.md +42 -33
  10. package/reference/dev.md +26 -33
  11. package/reference/env.md +18 -20
  12. package/reference/getting-started.md +132 -0
  13. package/reference/metadata.md +31 -46
  14. package/reference/navigation.md +65 -105
  15. package/reference/performance.md +21 -142
  16. package/reference/rendering.md +78 -75
  17. package/reference/routing.md +97 -107
  18. package/reference/typegen.md +27 -29
  19. package/src/api/cache.ts +36 -37
  20. package/src/api/client-cache.ts +2 -2
  21. package/src/api/client-navigation.ts +121 -114
  22. package/src/api/dynamic.tsx +58 -55
  23. package/src/api/link.tsx +52 -53
  24. package/src/api/navigation.ts +59 -58
  25. package/src/api/server.ts +152 -144
  26. package/src/api/suspense.ts +4 -4
  27. package/src/cli/adapters/vercel-warm.ts +126 -121
  28. package/src/cli/adapters/vercel.ts +437 -443
  29. package/src/cli/analyze.ts +333 -144
  30. package/src/cli/{named-bin.ts → boot/named-bin.ts} +37 -37
  31. package/src/cli/{boot-trace.ts → boot/trace.ts} +10 -10
  32. package/src/cli/build.ts +976 -978
  33. package/src/cli/create.ts +72 -64
  34. package/src/cli/dev.ts +116 -116
  35. package/src/cli/index.ts +94 -85
  36. package/src/cli/migrate/package-json.ts +73 -71
  37. package/src/cli/migrate/report.ts +32 -33
  38. package/src/cli/migrate/{index.ts → run.ts} +48 -49
  39. package/src/cli/migrate/scan.ts +46 -46
  40. package/src/cli/migrate/spinner.ts +9 -9
  41. package/src/cli/migrate/tsconfig.ts +35 -35
  42. package/src/cli/{server-entry.ts → serve/entry.ts} +57 -57
  43. package/src/cli/{request-pipeline.ts → serve/pipeline.ts} +386 -394
  44. package/src/cli/{serve-ui.ts → serve/ui.ts} +47 -47
  45. package/src/cli/start.ts +65 -66
  46. package/src/{typegen.ts → cli/typegen.ts} +59 -59
  47. package/src/client/build.ts +802 -768
  48. package/src/client/chunk-fold.ts +245 -240
  49. package/src/client/{paths.ts → chunk-name.ts} +6 -6
  50. package/src/client/entry.ts +162 -147
  51. package/src/client/prebuilt.ts +231 -223
  52. package/src/client/profile.ts +29 -29
  53. package/src/client/react-compiler.ts +20 -15
  54. package/src/client/{compat-surface.ts → react-tier.ts} +64 -64
  55. package/src/client/reference-stub.ts +51 -51
  56. package/src/client/reference.ts +19 -19
  57. package/src/{api → client}/router/events.ts +32 -17
  58. package/src/{api → client}/router/history.ts +16 -16
  59. package/src/{api → client}/router/hub.ts +52 -53
  60. package/src/{api/router.ts → client/router/index.ts} +61 -60
  61. package/src/{api → client}/router/policies.ts +24 -24
  62. package/src/{api → client}/router/runtime.ts +2022 -1995
  63. package/src/{api → client}/router/types.ts +98 -98
  64. package/src/compat/actions/client-plugin.ts +42 -43
  65. package/src/compat/actions/client-stub.ts +14 -14
  66. package/src/compat/actions/{action-client.ts → client.ts} +194 -193
  67. package/src/compat/actions/config.ts +63 -64
  68. package/src/compat/actions/detect.ts +68 -68
  69. package/src/compat/actions/discovery.ts +105 -105
  70. package/src/compat/actions/{action-dispatch.ts → dispatch.ts} +277 -274
  71. package/src/compat/actions/early-submit.ts +1 -1
  72. package/src/compat/actions/endpoint.ts +198 -198
  73. package/src/compat/actions/extensions.ts +811 -0
  74. package/src/compat/actions/flight.ts +23 -23
  75. package/src/compat/actions/form-state.ts +34 -34
  76. package/src/compat/actions/hoist.ts +382 -236
  77. package/src/compat/actions/ids.ts +7 -12
  78. package/src/compat/actions/index.ts +8 -8
  79. package/src/compat/actions/instances.ts +46 -46
  80. package/src/compat/actions/origin.ts +47 -48
  81. package/src/compat/actions/protocol.ts +22 -22
  82. package/src/compat/actions/registry.ts +19 -19
  83. package/src/compat/{misc/action-return.ts → actions/return.ts} +60 -57
  84. package/src/compat/actions/rewrite.ts +125 -125
  85. package/src/compat/actions/{action-router.ts → router.ts} +10 -10
  86. package/src/compat/actions/serve.ts +132 -136
  87. package/src/compat/actions/server-tag.ts +4 -4
  88. package/src/compat/actions/{action-shared.ts → shared.ts} +34 -34
  89. package/src/compat/actions/unrecognized-error.ts +4 -4
  90. package/src/compat/{index.ts → aliases.ts} +112 -109
  91. package/src/compat/bundler/bun-externals.ts +18 -18
  92. package/src/compat/bundler/cjs-exports.ts +271 -223
  93. package/src/compat/bundler/config.ts +116 -111
  94. package/src/compat/bundler/externals.ts +12 -12
  95. package/src/compat/bundler/import-meta-url.ts +19 -19
  96. package/src/compat/bundler/modularize-imports.ts +36 -33
  97. package/src/compat/bundler/new-url-asset.ts +22 -24
  98. package/src/compat/bundler/optimize-package-imports.ts +111 -107
  99. package/src/compat/bundler/polyfill.ts +28 -28
  100. package/src/compat/bundler/react-compiler.ts +35 -29
  101. package/src/compat/bundler/react-profiler.tsx +11 -11
  102. package/src/compat/bundler/relay-transform.ts +48 -47
  103. package/src/compat/bundler/require-context.ts +119 -113
  104. package/src/compat/bundler/resolve-extensions.ts +19 -19
  105. package/src/compat/bundler/source-cache.ts +25 -25
  106. package/src/compat/bundler/static-imports.ts +7 -7
  107. package/src/compat/bundler/symlink-imports.ts +46 -46
  108. package/src/compat/bundler/tsconfig-paths.ts +13 -15
  109. package/src/compat/bundler/wasm.ts +58 -60
  110. package/src/compat/bundler/webpack-loaders.ts +254 -241
  111. package/src/compat/bundler/worker.ts +101 -104
  112. package/src/compat/cache/build-flags.ts +29 -29
  113. package/src/compat/cache/build-prerender-errors.ts +40 -44
  114. package/src/compat/cache/custom-handler.ts +60 -53
  115. package/src/compat/cache/fetch-patch.ts +240 -240
  116. package/src/compat/cache/handler.ts +27 -31
  117. package/src/compat/cache/modern-handler.ts +148 -126
  118. package/src/compat/cache/resume-data-cache.ts +47 -45
  119. package/src/compat/cache/revalidate.ts +233 -232
  120. package/src/compat/cache/runtime-error.ts +35 -35
  121. package/src/compat/cache/use-cache-transform.ts +442 -417
  122. package/src/compat/cache/use-cache.ts +650 -614
  123. package/src/compat/cache-control.ts +140 -142
  124. package/src/compat/client/base-path.ts +21 -20
  125. package/src/compat/client/css-order.ts +18 -18
  126. package/src/compat/client/errors/bare-boundary.ts +11 -11
  127. package/src/compat/client/errors/control-flow.ts +23 -23
  128. package/src/compat/client/errors/error-boundary.ts +61 -61
  129. package/src/compat/client/errors/global-error.ts +101 -91
  130. package/src/compat/client/errors/install.ts +71 -72
  131. package/src/compat/client/errors/lazy.ts +23 -23
  132. package/src/compat/client/errors/primitive-throw.ts +47 -45
  133. package/src/compat/client/errors/soft-refresh.ts +4 -4
  134. package/src/compat/client/link-status.ts +33 -33
  135. package/src/compat/client/{nav-compat-runtime.ts → nav-runtime.ts} +20 -20
  136. package/src/compat/client/{nav-compat.ts → nav.ts} +12 -13
  137. package/src/compat/client/navigation-scroll.ts +63 -63
  138. package/src/compat/client/optimistic-routing.ts +93 -88
  139. package/src/compat/client/prefetch-cache.ts +23 -24
  140. package/src/compat/client/route-announcer.ts +35 -35
  141. package/src/compat/client/segment-cache-policy.ts +20 -20
  142. package/src/compat/client/segment-cache.ts +309 -315
  143. package/src/compat/client/segment-prefetch.ts +127 -132
  144. package/src/compat/client/trailing-slash.ts +5 -4
  145. package/src/compat/css/chunking.ts +113 -116
  146. package/src/compat/css/inline-css.ts +21 -21
  147. package/src/compat/css/lightningcss.ts +37 -38
  148. package/src/compat/css/modules.ts +161 -175
  149. package/src/compat/css/nonce.ts +7 -7
  150. package/src/compat/css/sass-plugin.ts +18 -21
  151. package/src/compat/css/sass.ts +150 -152
  152. package/src/compat/css/styled-jsx-runtime.ts +27 -27
  153. package/src/compat/css/styled-jsx.ts +21 -21
  154. package/src/compat/edge-runtime.ts +27 -27
  155. package/src/compat/{adapter → export}/build-complete.ts +72 -75
  156. package/src/compat/export/client.ts +29 -31
  157. package/src/compat/export/{index.ts → emit.ts} +111 -110
  158. package/src/compat/export/standalone.ts +62 -54
  159. package/src/compat/image-optimizer/cache.ts +51 -49
  160. package/src/compat/image-optimizer/detect.ts +52 -52
  161. package/src/compat/image-optimizer/{index.ts → optimize.ts} +189 -194
  162. package/src/compat/image-optimizer/source.ts +77 -80
  163. package/src/compat/lifecycle/after-scope.ts +26 -26
  164. package/src/compat/lifecycle/after.ts +48 -45
  165. package/src/compat/lifecycle/error-funnel.ts +98 -102
  166. package/src/compat/lifecycle/error-serialize.ts +30 -26
  167. package/src/compat/lifecycle/error-ui.ts +67 -32
  168. package/src/compat/lifecycle/instrumentation-client.ts +36 -38
  169. package/src/compat/lifecycle/instrumentation.ts +85 -85
  170. package/src/compat/lifecycle/node-console.ts +11 -11
  171. package/src/compat/lifecycle/testmode.ts +160 -132
  172. package/src/compat/mdx/compile.ts +60 -57
  173. package/src/compat/mdx/plugin.ts +11 -11
  174. package/src/compat/mdx/{next-mdx-stub.ts → stub.ts} +5 -5
  175. package/src/compat/{metadata-route-artifacts.ts → metadata-artifacts.ts} +195 -191
  176. package/src/compat/metadata.ts +75 -81
  177. package/src/compat/next/cache.ts +68 -69
  178. package/src/compat/next/canonical-url.ts +9 -9
  179. package/src/compat/next/client-cache.ts +19 -19
  180. package/src/compat/next/client-navigation.ts +112 -116
  181. package/src/compat/next/client-only.ts +1 -1
  182. package/src/compat/next/client-script.tsx +99 -93
  183. package/src/compat/next/client-server.ts +10 -10
  184. package/src/compat/next/config-loader.ts +176 -173
  185. package/src/compat/next/config.ts +7 -7
  186. package/src/compat/next/constants.cjs +6 -6
  187. package/src/compat/next/constants.ts +6 -6
  188. package/src/compat/next/custom-server.ts +26 -24
  189. package/src/compat/next/dist/client/components/app-router-headers.ts +21 -21
  190. package/src/compat/next/dist/server/app-render/work-unit-async-storage.external.cjs +3 -4
  191. package/src/compat/next/dist/server/web/spec-extension/revalidate.ts +1 -1
  192. package/src/compat/next/dist/server/web/spec-extension/unstable-cache.ts +1 -1
  193. package/src/compat/next/dist/server/web/spec-extension/unstable-no-store.ts +1 -1
  194. package/src/compat/next/dynamic.tsx +21 -18
  195. package/src/compat/next/error.tsx +52 -52
  196. package/src/compat/next/font/cache.ts +74 -74
  197. package/src/compat/next/font/google.ts +2 -2
  198. package/src/compat/next/font/index.ts +1 -1
  199. package/src/compat/next/font/local.ts +3 -3
  200. package/src/compat/next/font/runtime-client.ts +17 -15
  201. package/src/compat/next/font/runtime.ts +443 -408
  202. package/src/compat/next/font/shared.ts +120 -108
  203. package/src/compat/next/form.tsx +63 -63
  204. package/src/compat/next/head.tsx +2 -2
  205. package/src/compat/next/headers.ts +103 -95
  206. package/src/compat/next/image/client.tsx +220 -0
  207. package/src/compat/next/image/config.ts +56 -58
  208. package/src/compat/next/image/optimizer.ts +40 -36
  209. package/src/compat/next/image/patterns.ts +37 -40
  210. package/src/compat/next/{image-props.ts → image/props.ts} +208 -202
  211. package/src/compat/next/image/shared.ts +65 -57
  212. package/src/compat/next/image/static-metadata.ts +98 -107
  213. package/src/compat/next/image/validate.ts +79 -88
  214. package/src/compat/next/image.tsx +19 -23
  215. package/src/compat/next/index.ts +1 -1
  216. package/src/compat/next/legacy-image.tsx +59 -60
  217. package/src/compat/next/{link-validation-transform.ts → link-transform.ts} +95 -96
  218. package/src/compat/next/link.tsx +158 -158
  219. package/src/compat/next/navigation.cjs +12 -3
  220. package/src/compat/next/navigation.ts +48 -50
  221. package/src/compat/next/offline.ts +27 -27
  222. package/src/compat/next/og.ts +121 -124
  223. package/src/compat/next/preferred-region.ts +13 -14
  224. package/src/compat/next/redirects.ts +58 -56
  225. package/src/compat/next/resource-hints.ts +73 -76
  226. package/src/compat/next/rewrites.ts +130 -133
  227. package/src/compat/next/root-params.ts +45 -45
  228. package/src/compat/next/{optimistic-route-state.ts → route-state.ts} +52 -52
  229. package/src/compat/next/router.cjs +4 -2
  230. package/src/compat/next/router.ts +58 -61
  231. package/src/compat/next/script.tsx +108 -108
  232. package/src/compat/next/server-only.ts +1 -1
  233. package/src/compat/next/server.ts +19 -19
  234. package/src/compat/next/svgr.ts +18 -17
  235. package/src/compat/next/telemetry.ts +24 -24
  236. package/src/compat/next/{image-usage.ts → usage.ts} +70 -39
  237. package/src/compat/next/user-agent.ts +53 -49
  238. package/src/compat/next/web-vitals.ts +22 -24
  239. package/src/compat/otel/api.ts +41 -41
  240. package/src/compat/otel/client-trace-metadata.ts +25 -27
  241. package/src/compat/otel/fetch-span.ts +29 -29
  242. package/src/compat/otel/tracer.ts +331 -331
  243. package/src/compat/pages/api.ts +456 -0
  244. package/src/compat/pages/client-plugin.ts +36 -36
  245. package/src/compat/pages/router-state.ts +34 -34
  246. package/src/compat/pages/{index.ts → router.ts} +130 -135
  247. package/src/compat/ppr/io.ts +12 -12
  248. package/src/compat/ppr/missing-root-params.ts +34 -38
  249. package/src/compat/ppr/root-params-scan.ts +66 -66
  250. package/src/compat/ppr/root-params-transform.ts +24 -26
  251. package/src/compat/ppr/root-params.ts +30 -30
  252. package/src/compat/ppr/segment-config-incompat.ts +6 -7
  253. package/src/compat/protocol.ts +71 -70
  254. package/src/compat/react/action-state.ts +47 -48
  255. package/src/compat/react/client-lite.ts +15 -15
  256. package/src/compat/react/client.ts +4 -4
  257. package/src/compat/react/compiler-runtime.ts +11 -11
  258. package/src/compat/react/dom-client.ts +44 -44
  259. package/src/compat/react/dom-react-server.ts +10 -16
  260. package/src/compat/react/dom-server.ts +10 -10
  261. package/src/compat/react/dom.ts +52 -52
  262. package/src/compat/react/hooks-extra.ts +34 -35
  263. package/src/compat/react/parity.ts +64 -61
  264. package/src/compat/react/preact.ts +81 -82
  265. package/src/compat/react/react-server.ts +28 -28
  266. package/src/compat/react/router-shim.ts +1 -1
  267. package/src/compat/react/server-component-use.ts +8 -8
  268. package/src/compat/react/server-inserted-html.ts +30 -31
  269. package/src/compat/react/server.ts +53 -55
  270. package/src/compat/react/use.ts +32 -32
  271. package/src/compat/react/view-transition.ts +20 -20
  272. package/src/compat/register/actions.ts +35 -824
  273. package/src/compat/register/boot.ts +41 -41
  274. package/src/compat/register/build-tier.ts +5 -5
  275. package/src/compat/register/build.ts +74 -70
  276. package/src/compat/register/bundler.ts +161 -156
  277. package/src/compat/register/cache.ts +20 -20
  278. package/src/compat/register/client-errors.ts +3 -3
  279. package/src/compat/register/config.ts +6 -6
  280. package/src/compat/register/css-extras.ts +30 -34
  281. package/src/compat/register/edge-runtime.ts +3 -3
  282. package/src/compat/register/errors.ts +10 -12
  283. package/src/compat/register/export.ts +16 -16
  284. package/src/compat/register/font.ts +11 -11
  285. package/src/compat/register/hooks.ts +2 -2
  286. package/src/compat/register/image.ts +40 -40
  287. package/src/compat/register/index.ts +59 -62
  288. package/src/compat/register/instrumentation-client.ts +10 -10
  289. package/src/compat/register/lifecycle.ts +25 -28
  290. package/src/compat/register/mdx.ts +10 -10
  291. package/src/compat/register/middleware.ts +226 -16
  292. package/src/compat/register/otel.ts +80 -88
  293. package/src/compat/register/pages-api.ts +10 -463
  294. package/src/compat/register/ppr.ts +16 -16
  295. package/src/compat/register/protocol.ts +17 -18
  296. package/src/compat/register/proxy.ts +49 -51
  297. package/src/compat/register/render.ts +79 -76
  298. package/src/compat/register/routing.ts +162 -159
  299. package/src/compat/register/segment.ts +24 -1897
  300. package/src/compat/register/static-image.ts +3 -3
  301. package/src/compat/register/{misc.ts → taint.ts} +9 -9
  302. package/src/compat/register/typed-routes.ts +14 -14
  303. package/src/compat/register/{usecache.ts → use-cache.ts} +39 -39
  304. package/src/compat/register/validation.ts +18 -18
  305. package/src/compat/segment/loading-boundary.ts +43 -45
  306. package/src/compat/segment/page-slot.ts +69 -69
  307. package/src/compat/segment/serve.ts +1884 -0
  308. package/src/compat/segment/tree.ts +113 -112
  309. package/src/compat/segment/vary-key.ts +38 -38
  310. package/src/compat/segment/vary-params.ts +138 -142
  311. package/src/compat/static-params.ts +14 -12
  312. package/src/compat/tsconfig-defaults.ts +87 -91
  313. package/src/compat/typecheck/{index.ts → check.ts} +234 -212
  314. package/src/compat/typecheck/worker.ts +15 -12
  315. package/src/compat/typed-routes/{index.ts → generate.ts} +36 -36
  316. package/src/compat/typed-routes/manifest.ts +174 -170
  317. package/src/compat/typed-routes/typegen.ts +127 -110
  318. package/src/compat/validation/errors.ts +16 -19
  319. package/src/compat/validation/prerender-diagnostics.ts +521 -504
  320. package/src/compat/validation/{index.ts → validate.ts} +647 -648
  321. package/src/compat-bootstrap.ts +16 -16
  322. package/src/config.ts +86 -69
  323. package/src/css/build.ts +230 -227
  324. package/src/css/postcss.ts +79 -80
  325. package/src/css/worker.ts +14 -15
  326. package/src/dev/client-actions.ts +10 -10
  327. package/src/dev/client-chunk-store.ts +27 -27
  328. package/src/dev/{client-key-cache.ts → restart/client-key.ts} +76 -76
  329. package/src/dev/{restart-cache.ts → restart/enabled.ts} +1 -1
  330. package/src/dev/{global-css-cache.ts → restart/global-css.ts} +91 -83
  331. package/src/dev/{node-module-bundle-cache.ts → restart/node-modules.ts} +24 -24
  332. package/src/dev/{route-bundle-key-cache.ts → restart/route-bundle-key.ts} +53 -53
  333. package/src/dev/{route-facts-cache.ts → restart/route-facts.ts} +82 -82
  334. package/src/dev/server.ts +804 -820
  335. package/src/env.ts +46 -43
  336. package/src/extensions.ts +491 -478
  337. package/src/index.ts +8 -8
  338. package/src/internal.ts +20 -23
  339. package/src/{islands → render}/boundary-error.ts +3 -3
  340. package/src/render/hooks.ts +71 -71
  341. package/src/render/island-context.ts +14 -14
  342. package/src/render/metadata.ts +310 -310
  343. package/src/{ppr-postpone.ts → render/postpone.ts} +5 -5
  344. package/src/{ppr.ts → render/ppr.ts} +244 -245
  345. package/src/render/renderer.ts +2087 -2082
  346. package/src/render/resource-hints.ts +16 -17
  347. package/src/render/slots.tsx +224 -235
  348. package/src/{islands → render}/static-children.ts +9 -12
  349. package/src/{islands → render}/static-slots.ts +37 -37
  350. package/src/{cache/context.ts → request/cache.ts} +20 -20
  351. package/src/request/context.ts +107 -107
  352. package/src/{dynamic/source.ts → resolve/dynamic.ts} +139 -139
  353. package/src/resolve/engine.ts +90 -77
  354. package/src/resolve/imports.ts +475 -463
  355. package/src/resolve/scan-facts.ts +318 -296
  356. package/src/resolve/source-text.ts +37 -37
  357. package/src/{dynamic → resolve}/tree-shake.ts +132 -128
  358. package/src/routing/forwarded.ts +19 -19
  359. package/src/routing/handler.ts +84 -91
  360. package/src/routing/href.ts +87 -70
  361. package/src/routing/{metadata.ts → metadata-files.ts} +403 -401
  362. package/src/{proxy.ts → routing/proxy.ts} +306 -312
  363. package/src/routing/{request-runtime.ts → request-environment.ts} +10 -10
  364. package/src/routing/routes.ts +827 -815
  365. package/src/routing/slots.ts +164 -160
  366. package/src/runtime/loader.ts +954 -0
  367. package/src/{dev → runtime}/module-cache.ts +309 -287
  368. package/src/{dev → runtime}/module-generations.ts +9 -9
  369. package/src/{dev → runtime}/module-transform.ts +81 -72
  370. package/src/{dev/imports.ts → runtime/modules.ts} +934 -847
  371. package/src/runtime/{server.ts → vendor-build.ts} +848 -1696
  372. package/src/runtime/vendor.ts +428 -406
  373. package/src/styles.d.ts +9 -0
  374. package/src/types.ts +324 -335
  375. package/src/utils/ansi.ts +5 -5
  376. package/src/utils/{source.ts → code.ts} +15 -12
  377. package/src/utils/content-type.ts +3 -3
  378. package/src/utils/decode.ts +2 -2
  379. package/src/utils/dev-profile.ts +13 -13
  380. package/src/utils/error-log.ts +6 -6
  381. package/src/utils/esbuild.ts +18 -18
  382. package/src/utils/fs-cache.ts +13 -13
  383. package/src/utils/fs.ts +57 -49
  384. package/src/utils/html.ts +20 -24
  385. package/src/utils/native-require.ts +8 -8
  386. package/src/utils/serialize.ts +139 -146
  387. package/src/utils/verbose.ts +18 -18
  388. package/reference/overview.md +0 -35
  389. package/src/cli/analyze-print.ts +0 -181
  390. package/src/compat/middleware/manifest.ts +0 -210
  391. package/src/compat/next/image-client.tsx +0 -215
  392. package/src/compat/next/link-usage.ts +0 -29
  393. package/src/css/index.ts +0 -2
  394. package/src/render/index.ts +0 -1
  395. package/src/style-modules.d.ts +0 -9
@@ -1,167 +1,157 @@
1
1
  # Routing
2
2
 
3
- ## Files
3
+ Routes come from the file tree under `app/`. Directories make the URL path, and a `page` file inside one renders it as its default export.
4
4
 
5
- - `app/**/page` defines a UI route.
6
- - `app/**/layout` exports metadata and can wrap descendant pages.
7
- - `app/**/route` defines HTTP handlers.
8
- - `proxy` or `middleware` runs before route matching.
9
- - `app/**/loading` defines a Suspense fallback for the segment.
10
- - `app/**/error` defines fallback UI for server render failures in the segment.
11
- - `app/**/not-found` defines fallback UI.
5
+ ## Path patterns
12
6
 
13
- Convention files are matched across `.tsx`, `.ts`, `.jsx`, `.js`, and `.mjs`.
14
- `.tsx`/`.ts` are tried first, so an all-`.tsx` app resolves on the first
15
- candidate. Route handlers (`route`) match `.ts`, `.tsx`, `.js`, `.mjs`.
7
+ | Directory | Serves |
8
+ | -------------------------- | --------------------------------------- |
9
+ | `app/about/` | `/about` |
10
+ | `app/users/[id]/` | `/users/:id` |
11
+ | `app/docs/[...slug]/` | `/docs/*` |
12
+ | `app/docs/[[...slug]]/` | `/docs` and `/docs/*` |
13
+ | `app/(marketing)/pricing/` | `/pricing`, the group adds no segment |
14
+ | `app/dashboard/@team/` | a slot of `/dashboard`, no path segment |
16
15
 
17
- ## Segments
16
+ ## Convention files
18
17
 
19
- - `app/about/page.tsx` -> `/about`
20
- - `app/users/[id]/page.tsx` -> `/users/:id`
21
- - `app/docs/[...slug]/page.tsx` -> `/docs/*`
22
- - `app/docs/[[...slug]]/page.tsx` -> matches `/docs` AND `/docs/*` (the base path is included)
23
- - `app/(marketing)/pricing/page.tsx` -> `/pricing`
24
- - `app/dashboard/@team/page.tsx` -> a `@slot` directory adds no path segment; it is rendered as a slot of `/dashboard`
18
+ | File | What it does |
19
+ | -------------- | --------------------------------------------------------- |
20
+ | `page` | Renders a UI route. |
21
+ | `layout` | Exports metadata and can wrap descendant pages. |
22
+ | `route` | Defines HTTP handlers. |
23
+ | `loading` | Suspense fallback for the segment. |
24
+ | `error` | Fallback UI when server rendering throws in the segment. |
25
+ | `not-found` | Fallback UI for `notFound()` and unmatched URLs. |
26
+ | `template` | Wraps children like a layout, but re-renders per request. |
27
+ | `default` | Fallback for a parallel slot with no page match. |
28
+ | `global-error` | Replaces the whole document for an uncaught root error. |
25
29
 
26
- ### Intercepting markers
30
+ Convention files are matched across `.tsx`, `.ts`, `.jsx`, `.js`, and `.mjs`, with the TypeScript extensions tried first. Route handlers are the exception: they do not match `.jsx`. A proxy file lives at the project root rather than in a segment, and is covered under [Proxy](#proxy).
27
31
 
28
- A marker prefixes a segment to intercept a route from another level. The marker
29
- is stripped from the resulting path. See [Intercepting routes](#intercepting-routes).
32
+ Behavior worth knowing:
30
33
 
31
- - `(.)segment` -> same level.
32
- - `(..)segment` -> one level up.
33
- - `(..)(..)segment` -> two levels up.
34
- - `(...)segment` -> from the app root.
34
+ - `loading`: static builds wait for the final HTML, while dev and server responses can stream the fallback first.
35
+ - `error`: receives `error`, `reset`, and `unstable_retry`. Both callbacks refresh the current route in `compat.next` apps.
36
+ - `not-found`: `pnext build` also writes `404.html` when the app root has one.
37
+ - `global-error`: renders its own `<html>` and `<body>`, so pnext serves that markup instead of the normal document shell. A nearer error boundary wins, and a `"use client"` directive opts the file out.
38
+ - `template`: nesting order is layout, then template, then children. A segment with no layout still applies its template.
39
+ - `forbidden` and `unauthorized`: experimental `compat.next` boundaries that render 403 and 401 responses. Without compat, the thrown errors take the normal error path. The `forbidden()` and `unauthorized()` functions are core exports either way. See [Navigation](./navigation.md#auth-interrupts).
35
40
 
36
- ## Page Props
41
+ To leave a route, use `redirect()` or `notFound()`. See [Navigation](./navigation.md#redirects-and-not-found).
42
+
43
+ ## Page props
37
44
 
38
45
  Pages receive explicit props:
39
46
 
40
47
  ```ts
41
48
  type PageProps<P = Record<string, string | string[]>> = {
42
- params: Promise<P>;
43
- searchParams: Promise<Record<string, string | string[] | undefined>>;
44
- request?: NextRequest;
45
- };
49
+ params: Promise<P>
50
+ searchParams: Promise<Record<string, string | string[] | undefined>>
51
+ request?: NextRequest
52
+ }
46
53
  ```
47
54
 
48
- Request data is read from `props.request`.
55
+ Read request data from the request prop. Typed per-route versions of these props are generated for you; see [Type Safety](./typegen.md).
49
56
 
50
- ## Route Handlers
57
+ ## Route handlers
51
58
 
52
- Route handlers use the Next-compatible `(request, context)` shape:
59
+ A `route` file exports one function per HTTP method. The request extends the standard `Request` with convenience access for cookies and `nextUrl`, and the context carries the route params.
53
60
 
54
61
  ```ts
55
- import type { RouteContext } from '#gen/app/api/users/[id]/route';
56
- import type { NextRequest } from '@wular/pnext/server';
57
-
58
- export async function GET(request: NextRequest, { params }: RouteContext) {
59
- const { id } = await params;
60
- return Response.json({
61
- id,
62
- q: request.nextUrl.searchParams.get('q'),
63
- });
62
+ export async function GET(
63
+ request: NextRequest,
64
+ { params }: RouteContext,
65
+ ) {
66
+ const { id } = await params
67
+ return Response.json({ id })
64
68
  }
65
69
  ```
66
70
 
67
- `request` is a `NextRequest` compatible object. It extends the standard `Request` with convenience access for cookies and `nextUrl`.
68
-
69
- If `OPTIONS` is not exported, pnext returns an automatic `OPTIONS` response with an `Allow` header. Unsupported methods return `405 Method Not Allowed` with the same `Allow` header.
71
+ If a handler does not export `OPTIONS`, pnext answers with an automatic response carrying an `Allow` header. Unsupported methods get a 405 with that same header.
70
72
 
71
- Static `GET` route handlers are written as files during `pnext build`. Dynamic route handlers can export `params()` to write selected param outputs at build time.
73
+ Static `GET` handlers are written as files during the build. A dynamic handler can export `params()` to write selected param outputs at build time.
72
74
 
73
- `generateStaticParams()` is supported in Next compat mode.
75
+ ## Static and dynamic routes
74
76
 
75
- ## Route Rendering
77
+ pnext infers rendering from what a route uses:
76
78
 
77
- pnext infers route rendering separately from hydration:
79
+ - Static: no dynamic params and no request prop usage.
80
+ - Dynamic: request prop usage or dynamic route segments.
78
81
 
79
- - `static`: no dynamic params and no request prop usage.
80
- - `dynamic`: request prop usage or dynamic route segments.
82
+ Segment config overrides the inference. Hydration is inferred separately, from `"use client"`.
81
83
 
82
- Route segment config overrides the inference. Hydration is controlled by `"use client"`.
84
+ ## Route segment config
83
85
 
84
- ## Route Segment Config
85
-
86
- Pages, layouts, and route handlers can export segment config. Values must be literals — they are read from the source, not evaluated.
86
+ Pages, layouts, and route handlers can export segment config. Values must be literals, because they are read from the source rather than evaluated.
87
87
 
88
88
  ```ts
89
- export const dynamic = 'force-dynamic';
90
- export const maxDuration = 60;
89
+ export const dynamic = 'force-dynamic'
90
+ export const maxDuration = 60
91
91
  ```
92
92
 
93
- Recognized: `dynamic` (`auto` | `force-dynamic` | `force-static` | `error`), `revalidate` (a non-negative number or `false`), `fetchCache`, `dynamicParams`, `runtime` (`edge` | `nodejs`), `prefetch`, and `maxDuration`.
93
+ - `dynamic`: `auto`, `force-dynamic`, `force-static`, or `error`.
94
+ - `revalidate`: a non-negative number, or `false`.
95
+ - `dynamicParams`: `false` restricts the route to its generated params.
96
+ - `runtime`: `edge` or `nodejs`.
97
+ - `maxDuration`: seconds, copied into the generated Vercel Node function metadata.
98
+ - `fetchCache`: `auto`, `default-cache`, `only-cache`, `force-cache`, `force-no-store`, `default-no-store`, or `only-no-store`.
99
+ - `prefetch`: `allow-runtime`, `partial`, or `unstable_eager`.
100
+ - `unstable_instant`: experimental, described below.
101
+
102
+ Config merges across the route's own file and its layout chain, leaf-first, so the nearest declaration wins. Two values behave differently: `force-dynamic` on any segment forces the whole route, and the lowest declared `revalidate` wins.
94
103
 
95
- Config merges across the route's own file and its layout chain, leaf-first: the nearest declaration wins, except `force-dynamic` (any segment forces the whole route) and `revalidate` (the lowest declared number wins).
104
+ Setting `dynamicParams` to false applies to the dynamic segment declared by that file. When every dynamic segment has static params, requests must match a generated param tuple. Otherwise pnext drops the restriction and renders the route on demand. A page-level static params export makes this check apply to the complete param tuple.
96
105
 
97
- When building with `pnext build --adapter vercel`, `maxDuration` is copied to the generated Vercel Node function metadata.
106
+ `unstable_instant` is experimental. Set it to `true` or to an object of samples to opt in, and a leaf `false` overrides a layout opt-in. A full prefetch of such a route uses sampled request data and leaves `connection()`-gated content out of that prefetch render.
98
107
 
99
- ## File Conventions
108
+ `experimental_ppr` is also experimental. For a request-using page without dynamic route segments, it records the page as a partial-prerendering candidate. See [Rendering](./rendering.md#experimental-partial-prerendering-and-cachecomponents).
100
109
 
101
- `proxy.ts` and `middleware.ts` run before static files, pages, and route handlers. Use `proxy.ts` for new code. `middleware.ts` is supported for compatibility. If both exist, `proxy.ts` wins.
110
+ `preferredRegion` is a `compat.next`-only export. It accepts a string or string array and is written to compat deployment metadata.
111
+
112
+ ## Proxy
113
+
114
+ A `proxy` file at the project root runs before static files, pages, and route handlers.
102
115
 
103
116
  ```ts
104
- import { NextResponse, type NextRequest } from '@wular/pnext/server';
117
+ import { NextResponse, type NextRequest } from '@wular/pnext/server'
105
118
 
106
- export const config = {
107
- matcher: ['/admin/:path*'],
108
- };
119
+ export const config = { matcher: ['/admin/:path*'] }
109
120
 
110
121
  export function proxy(request: NextRequest) {
111
122
  if (!request.cookies.has('session')) {
112
- return NextResponse.redirect(new URL('/login', request.url));
123
+ return NextResponse.redirect(new URL('/login', request.url))
113
124
  }
114
- return NextResponse.next();
125
+ return NextResponse.next()
115
126
  }
116
127
  ```
117
128
 
118
- Supported responses:
119
-
120
- - `NextResponse.next()` continues to the matched static file, page, or route handler.
121
- - `NextResponse.redirect(url)` returns a redirect response.
122
- - `NextResponse.rewrite(url)` serves another path without changing the browser URL.
123
- - `new Response(...)` returns a custom response directly.
124
-
125
- `config.matcher` takes a string, a string array, or objects with `source` plus `has`/`missing` conditions (`header`, `query`, `cookie`, `host`). Patterns support exact paths, `:param`, `:path*`, and regex. With no `matcher`, every request runs through the proxy.
129
+ Return one of:
126
130
 
127
- `loading.tsx` is used as the fallback for automatically wrapped server Suspense boundaries. Static builds wait for final HTML; dev and server responses can stream the fallback first.
131
+ - `NextResponse.next()` to continue to the matched static file, page, or route handler.
132
+ - `NextResponse.redirect(url)` for a redirect response.
133
+ - `NextResponse.rewrite(url)` to serve another path without changing the browser URL.
134
+ - `new Response(...)` for a custom response.
128
135
 
129
- `not-found.tsx` is rendered when a route calls `notFound()` or when no route matches. `pnext build` also writes `404.html` when root `app/not-found.tsx` exists.
136
+ The matcher accepts a string, an array of strings, or objects with a source pattern plus `has` and `missing` conditions on header, query, cookie, and host. Patterns support exact paths, `:param`, `:path*`, and regex. Without a matcher, every request runs through the proxy.
130
137
 
131
- `global-error.tsx` at the app root replaces the entire document when an unhandled error reaches the root uncaught. It renders its own `<html>` and `<body>`, so pnext skips the normal document shell and serves its markup directly. It only takes over when no nearer `error.tsx` boundary catches first, and a `"use client"` directive opts the file out.
138
+ A `middleware` file works the same way and is supported for compatibility. Use a proxy file for new code, and note that it wins if both exist.
132
139
 
133
- `redirect()` and `permanentRedirect()` stop rendering and return redirect responses. They can be called from pages, server components, route handlers, and server helpers used during rendering.
134
- Validate redirect targets that come from user input.
140
+ ## Static params
135
141
 
136
- `error.tsx` is rendered when server rendering throws. It receives `error`, `reset`, and `unstable_retry`; `reset()`/`unstable_retry()` refresh the current route in `compat.next` apps.
142
+ Export `params()` from a dynamic route to choose which params `pnext build` writes as static HTML. See the typed example in [Type Safety](./typegen.md). Under `compat.next`, `generateStaticParams()` fills the same role when a module has no `params()` export.
137
143
 
138
- `template.tsx` wraps the segment's children like a layout, but the segment re-renders per request where a layout persists. Nesting order is layout > template > children. A segment without a layout still applies its template.
144
+ ## Parallel routes
139
145
 
140
- `default.tsx` is the fallback rendered for a parallel `@slot` that has no page match.
146
+ A slot directory such as `@team` contributes no path segment. Its content is rendered and passed to the owning segment's layout as a prop named after the slot, alongside `children`. A slot uses its `page` when present, then its `default` fallback, and otherwise renders nothing. A slot's `loading` file wraps its content in a Suspense boundary.
141
147
 
142
- `forbidden.tsx` and `unauthorized.tsx` render at 403/401 when `forbidden()` / `unauthorized()` is thrown. These are COMPAT-only (require `compat.next`) and experimental (`authInterrupts`); without compat they fall through to the normal error page.
148
+ ## Intercepting routes
143
149
 
144
- ### Parallel routes
150
+ A marker prefixed to a segment intercepts a route from another level, and is stripped from the resulting path:
145
151
 
146
- A `@slot` directory (e.g. `@team`) contributes no path segment. Its content is rendered and passed to the owning segment's layout as a prop keyed by the slot name (without the `@`), alongside `children`. A slot uses its `page` when present, else its `default` fallback, else renders nothing. A slot's `loading` wraps its content in a Suspense boundary.
152
+ - `(.)segment` intercepts from the same level.
153
+ - `(..)segment` intercepts from one level up.
154
+ - `(..)(..)segment` intercepts from two levels up.
155
+ - `(...)segment` intercepts from the app root.
147
156
 
148
- ### Intercepting routes
149
-
150
- An interception marker (`(.)`, `(..)`, `(..)(..)`, `(...)`) makes the route respond to soft navigations toward the marked target from the intercepting level, usually rendered into a parallel `@slot`. Hard requests render the non-intercepted target. Intercepting routes are always dynamic and never take static params.
151
-
152
- ## Static Params
153
-
154
- Use `params()` on a dynamic route to choose params that `pnext build` should write as static HTML.
155
- Requests outside the returned list keep using dynamic rendering.
156
-
157
- ```tsx
158
- import type { PageProps, StaticParams } from '#gen/app/users/[id]/page';
159
-
160
- export function params(): StaticParams {
161
- return [{ id: 'ada' }, { id: 'grace' }];
162
- }
163
-
164
- export default async function Page({ params }: PageProps) {
165
- return <p>{(await params).id}</p>;
166
- }
167
- ```
157
+ The intercepting route answers soft navigations toward the marked target, usually rendering into a parallel slot. A hard request renders the non-intercepted target instead. Intercepting routes are always dynamic and never take static params.
@@ -1,57 +1,49 @@
1
1
  # Type Safety
2
2
 
3
- pnext generates route types from the `app/` tree. These types check route params, static params, route handlers, and typed navigation.
3
+ pnext generates types from the `app/` tree so route params, static params, route handler context, and links are all checked.
4
4
 
5
- ## Route Types
5
+ ## Route types
6
6
 
7
- Import generated types for the current route. pnext validates those exports against the route inferred from the file path, so a wrong param name, static param shape, or route handler context fails TypeScript.
7
+ Each route imports the types generated for its own file path. pnext validates the exports against the route inferred from that path, so a wrong param name, a bad static param shape, or the wrong handler context fails TypeScript.
8
8
 
9
9
  ```tsx
10
10
  // app/users/[id]/page.tsx
11
- import type { PageProps, StaticParams } from '#gen/app/users/[id]/page';
11
+ import type {
12
+ PageProps,
13
+ StaticParams,
14
+ } from '#gen/app/users/[id]/page'
12
15
 
13
16
  export function params(): StaticParams {
14
- return [{ id: 'ada' }];
17
+ return [{ id: 'ada' }]
15
18
  }
16
19
 
17
20
  export default async function Page({ params }: PageProps) {
18
- return <p>{(await params).id}</p>;
21
+ return <p>{(await params).id}</p>
19
22
  }
20
23
  ```
21
24
 
22
- Route handlers use generated `RouteContext` for the second argument:
25
+ A route handler takes its generated context type as the second argument.
23
26
 
24
27
  ```ts
25
28
  // app/users/[id]/route.ts
26
- import type { RouteContext } from '#gen/app/users/[id]/route';
27
- import type { NextRequest } from '@wular/pnext/server';
28
-
29
- export async function GET(request: NextRequest, { params }: RouteContext) {
30
- return Response.json({ id: (await params).id });
29
+ import type { RouteContext } from '#gen/app/users/[id]/route'
30
+ import type { NextRequest } from '@wular/pnext/server'
31
+
32
+ export async function GET(
33
+ request: NextRequest,
34
+ { params }: RouteContext,
35
+ ) {
36
+ return Response.json({ id: (await params).id })
31
37
  }
32
38
  ```
33
39
 
34
40
  ## Links
35
41
 
36
- Typed links use typed `href` and `params`:
37
-
38
- ```tsx
39
- import { Link } from '@wular/pnext/link';
40
-
41
- export function Nav() {
42
- return <Link href="/users/[id]" params={{ id: 'ada' }}>Ada</Link>;
43
- }
44
- ```
45
-
46
- Use a normal `<a>` for external URLs or intentionally untyped links.
47
-
48
- ## Generated Types
49
-
50
- `pnext dev` and `pnext build` refresh generated types automatically. Use `pnext typegen` to refresh them manually.
42
+ `<Link>` and `href()` check their route template and params against the same generated types. See [Navigation](./navigation.md).
51
43
 
52
- Generated files live in `.pnext/types` and should not be edited. Include `.pnext/types/**/*.ts` in the app TypeScript project for editor and `tsc` visibility.
44
+ ## Setup
53
45
 
54
- Use a TypeScript path alias for generated imports:
46
+ Apps from `pnext create` are already set up. The package ships the `@wular/pnext/config/ts/react.json` preset, which the scaffold puts in `extends` alongside the alias for generated types:
55
47
 
56
48
  ```json
57
49
  {
@@ -62,3 +54,9 @@ Use a TypeScript path alias for generated imports:
62
54
  }
63
55
  }
64
56
  ```
57
+
58
+ Include `.pnext/types/**/*.ts` in the app TypeScript project so the editor and `tsc` can see the generated files. `pnext migrate` repoints existing include paths there, but it does not add the alias.
59
+
60
+ ## Regenerating
61
+
62
+ The dev server and the build refresh generated types on their own. Run `pnext typegen` to refresh them by hand. The files live in `.pnext/types` and should not be edited.
package/src/api/cache.ts CHANGED
@@ -1,80 +1,79 @@
1
- import { currentCacheScope, type CacheNode } from '../cache/context';
1
+ import { currentCacheScope, type CacheNode } from '../request/cache'
2
2
 
3
3
  export function cache<Args extends unknown[], Result>(
4
4
  fn: (...args: Args) => Result,
5
5
  ): (...args: Args) => Result {
6
6
  return (...args: Args) => {
7
- const scope = currentCacheScope();
8
- if (!scope) return fn(...args);
7
+ const scope = currentCacheScope()
8
+ if (!scope) return fn(...args)
9
9
 
10
- let root = scope.functions.get(fn);
10
+ let root = scope.functions.get(fn)
11
11
  if (!root) {
12
- root = cacheNode();
13
- scope.functions.set(fn, root);
12
+ root = cacheNode()
13
+ scope.functions.set(fn, root)
14
14
  }
15
15
 
16
- const node = cacheNodeForArgs(root, args);
17
- const record = node.record;
16
+ const node = cacheNodeForArgs(root, args)
17
+ const record = node.record
18
18
  if (record) {
19
19
  if (record.status === 'rejected') {
20
20
  if (record.async) {
21
21
  return Promise.resolve().then(() => {
22
- throw record.error;
23
- }) as Result;
22
+ throw record.error
23
+ }) as Result
24
24
  }
25
- throw record.error;
25
+ throw record.error
26
26
  }
27
- if (record.status === 'resolved' && record.async) return Promise.resolve(record.value) as Result;
28
- return record.value as Result;
27
+ if (record.status === 'resolved' && record.async)
28
+ return Promise.resolve(record.value) as Result
29
+ return record.value as Result
29
30
  }
30
31
 
31
32
  try {
32
- const value = fn(...args);
33
+ const value = fn(...args)
33
34
  if (isPromiseLike(value)) {
34
35
  const promise = Promise.resolve(value).then(
35
36
  result => {
36
- node.record = { status: 'resolved', value: result, async: true };
37
- return result;
37
+ node.record = { status: 'resolved', value: result, async: true }
38
+ return result
38
39
  },
39
40
  error => {
40
- node.record = { status: 'rejected', error, async: true };
41
- throw error;
41
+ node.record = { status: 'rejected', error, async: true }
42
+ throw error
42
43
  },
43
- );
44
- node.record = { status: 'pending', value: promise };
45
- return promise as Result;
44
+ )
45
+ node.record = { status: 'pending', value: promise }
46
+ return promise as Result
46
47
  }
47
48
 
48
- node.record = { status: 'resolved', value, async: false };
49
- return value;
49
+ node.record = { status: 'resolved', value, async: false }
50
+ return value
50
51
  } catch (error) {
51
- node.record = { status: 'rejected', error, async: false };
52
- throw error;
52
+ node.record = { status: 'rejected', error, async: false }
53
+ throw error
53
54
  }
54
- };
55
+ }
55
56
  }
56
57
 
57
58
  function cacheNode(): CacheNode {
58
- return { children: new Map() };
59
+ return { children: new Map() }
59
60
  }
60
61
 
61
62
  function cacheNodeForArgs(root: CacheNode, args: unknown[]) {
62
- let node = root;
63
+ let node = root
63
64
  for (const arg of args) {
64
- let child = node.children.get(arg);
65
+ let child = node.children.get(arg)
65
66
  if (!child) {
66
- child = cacheNode();
67
- node.children.set(arg, child);
67
+ child = cacheNode()
68
+ node.children.set(arg, child)
68
69
  }
69
- node = child;
70
+ node = child
70
71
  }
71
- return node;
72
+ return node
72
73
  }
73
74
 
74
75
  function isPromiseLike(value: unknown): value is PromiseLike<unknown> {
75
76
  return (
76
- (typeof value === 'object' || typeof value === 'function') &&
77
- value !== null &&
78
- 'then' in value
79
- );
77
+ (typeof value === 'object' || typeof value === 'function') && value !== null && 'then' in value
78
+ )
80
79
  }
@@ -1,9 +1,9 @@
1
1
  export function cache<Args extends unknown[], Result>(
2
2
  fn: (...args: Args) => Result,
3
3
  ): (...args: Args) => Result {
4
- return (...args: Args) => fn(...args);
4
+ return (...args: Args) => fn(...args)
5
5
  }
6
6
 
7
7
  export function cacheSignal() {
8
- return null;
8
+ return null
9
9
  }