@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
@@ -7,11 +7,11 @@
7
7
  * `<form action={fn}>` vnode hook, progressive-form enhancement, and synchronous island-prop revival.
8
8
  * Everything that can only run once an action has fired - argument encoding, the POST wire,
9
9
  * redirect/refresh/error semantics, action-return revival, the error overlay body - lives in
10
- * action-dispatch.ts and is reached through import(), so it rides a deferred chunk whose fetch
10
+ * dispatch.ts and is reached through import(), so it rides a deferred chunk whose fetch
11
11
  * overlaps the action's own round trip.
12
12
  */
13
- import { options as preactOptions, type ComponentType, type VNode } from 'preact';
14
- import { __pnextPushFormStatus } from '../react/dom';
13
+ import { options as preactOptions, type ComponentType, type VNode } from 'preact'
14
+ import { __pnextPushFormStatus } from '../react/dom'
15
15
  import {
16
16
  ACTION_ID_FIELD,
17
17
  FORM_STATE_FIELD,
@@ -20,7 +20,7 @@ import {
20
20
  isActionError,
21
21
  reviveBinaryMarker,
22
22
  type ActionFunction,
23
- } from './action-shared';
23
+ } from './shared'
24
24
 
25
25
  // Out-of-band carrier for a plain server-action form's id once the client
26
26
  // runtime is up. React strips the progressive `$ACTION_ID` hidden inputs from a
@@ -29,12 +29,12 @@ import {
29
29
  // `form.innerHTML` leaks `<input name="$pnext_action_id" ...>`. We move the id
30
30
  // to this attribute and drop the hidden input (see stripProgressiveActionIds),
31
31
  // keeping submission working via the fallbacks that read it.
32
- const ACTION_ID_ATTR = 'data-pnext-action-id';
33
- const PROP_ACTION_MARKER = '$$pnextAction';
34
- const ACTION_CLICK_ID_ATTR = 'data-pnext-action-click';
35
- const PROP_ERROR_RESET_MARKER = '$$pnextErrorReset';
32
+ const ACTION_ID_ATTR = 'data-pnext-action-id'
33
+ const PROP_ACTION_MARKER = '$$pnextAction'
34
+ const ACTION_CLICK_ID_ATTR = 'data-pnext-action-click'
35
+ const PROP_ERROR_RESET_MARKER = '$$pnextErrorReset'
36
36
 
37
- export { isActionError };
37
+ export { isActionError }
38
38
 
39
39
  // ---------------------------------------------------------------------------
40
40
  // dispatch entry point (the wire itself is deferred)
@@ -45,28 +45,28 @@ export { isActionError };
45
45
  // fetched-and-evaluated chunk lands behind the frame and a driver reading the DOM the instant
46
46
  // `click()` resolves sees no request. Warm on `pnext:hydrated` and remember the entry point, so the
47
47
  // warm call is a microtask that drains in the click's own task.
48
- const dispatchRuntime = () => import('./action-dispatch');
48
+ const dispatchRuntime = () => import('./dispatch')
49
49
 
50
- let warmDispatch: ((id: string, args: unknown[]) => Promise<unknown>) | undefined;
50
+ let warmDispatch: ((id: string, args: unknown[]) => Promise<unknown>) | undefined
51
51
 
52
- const loadDispatch = () => dispatchRuntime().then(module => (warmDispatch = module.callAction));
52
+ const loadDispatch = () => dispatchRuntime().then(module => (warmDispatch = module.callAction))
53
53
 
54
54
  // Warming is speculative: offline (or any failed chunk fetch) must not surface as an unhandled
55
55
  // rejection, which the client error last-resort escalates to the global-error document. A real
56
56
  // action call still awaits - and rejects through - loadDispatch.
57
57
  const warmDispatchChunk = () => {
58
- void loadDispatch().catch(() => undefined);
59
- };
58
+ void loadDispatch().catch(() => undefined)
59
+ }
60
60
 
61
61
  function callAction(id: string, args: unknown[]): Promise<unknown> {
62
- return warmDispatch ? warmDispatch(id, args) : loadDispatch().then(call => call(id, args));
62
+ return warmDispatch ? warmDispatch(id, args) : loadDispatch().then(call => call(id, args))
63
63
  }
64
64
 
65
65
  function registerClientReference(
66
66
  id: string,
67
67
  component: ComponentType<Record<string, unknown>>,
68
68
  ): void {
69
- actionReturnClientReferences.set(id, component);
69
+ actionReturnClientReferences.set(id, component)
70
70
  }
71
71
 
72
72
  // ---------------------------------------------------------------------------
@@ -74,44 +74,44 @@ function registerClientReference(
74
74
  // ---------------------------------------------------------------------------
75
75
 
76
76
  function reviveProps<T>(value: T): T {
77
- return reviveValue(value) as T;
77
+ return reviveValue(value) as T
78
78
  }
79
79
 
80
80
  function reviveValue(value: unknown): unknown {
81
- if (value === null || typeof value !== 'object') return value;
82
- if (Array.isArray(value)) return value.map(reviveValue);
83
- const record = value as Record<string, unknown>;
84
- const error = reviveErrorMarker(record);
85
- if (error) return error;
86
- if (record[PROP_ERROR_RESET_MARKER] === true) return refreshCurrentRoute;
81
+ if (value === null || typeof value !== 'object') return value
82
+ if (Array.isArray(value)) return value.map(reviveValue)
83
+ const record = value as Record<string, unknown>
84
+ const error = reviveErrorMarker(record)
85
+ if (error) return error
86
+ if (record[PROP_ERROR_RESET_MARKER] === true) return refreshCurrentRoute
87
87
  if (typeof record[PROP_ACTION_MARKER] === 'string') {
88
- return createAction(record[PROP_ACTION_MARKER]);
88
+ return createAction(record[PROP_ACTION_MARKER])
89
89
  }
90
- const binary = reviveBinaryMarker(record);
91
- if (binary !== undefined) return binary;
92
- const revived: Record<string, unknown> = {};
93
- for (const [key, item] of Object.entries(record)) revived[key] = reviveValue(item);
94
- return revived;
90
+ const binary = reviveBinaryMarker(record)
91
+ if (binary !== undefined) return binary
92
+ const revived: Record<string, unknown> = {}
93
+ for (const [key, item] of Object.entries(record)) revived[key] = reviveValue(item)
94
+ return revived
95
95
  }
96
96
 
97
97
  function reviveErrorMarker(record: Record<string, unknown>): Error | undefined {
98
- const marker = record.$$pnextError;
99
- if (marker === null || typeof marker !== 'object') return undefined;
100
- const data = marker as Record<string, unknown>;
101
- const error = new Error(typeof data.message === 'string' ? data.message : '');
102
- if (typeof data.name === 'string') error.name = data.name;
103
- if (typeof data.digest === 'string') (error as Error & { digest?: string }).digest = data.digest;
104
- return error;
98
+ const marker = record.$$pnextError
99
+ if (marker === null || typeof marker !== 'object') return undefined
100
+ const data = marker as Record<string, unknown>
101
+ const error = new Error(typeof data.message === 'string' ? data.message : '')
102
+ if (typeof data.name === 'string') error.name = data.name
103
+ if (typeof data.digest === 'string') (error as Error & { digest?: string }).digest = data.digest
104
+ return error
105
105
  }
106
106
 
107
107
  function refreshCurrentRoute(): void {
108
- location.reload();
108
+ location.reload()
109
109
  }
110
110
 
111
111
  function createAction(id: string): ActionFunction {
112
- const action: ActionFunction = async (...args: unknown[]) => callAction(id, args);
113
- action.$$pnextActionId = id;
114
- return action;
112
+ const action: ActionFunction = async (...args: unknown[]) => callAction(id, args)
113
+ action.$$pnextActionId = id
114
+ return action
115
115
  }
116
116
 
117
117
  // ---------------------------------------------------------------------------
@@ -119,7 +119,7 @@ function createAction(id: string): ActionFunction {
119
119
  // ---------------------------------------------------------------------------
120
120
 
121
121
  interface ActionDomNode extends Element {
122
- __pnextFormAction?: (formData: FormData) => unknown;
122
+ __pnextFormAction?: (formData: FormData) => unknown
123
123
  }
124
124
 
125
125
  // ---------------------------------------------------------------------------
@@ -132,18 +132,18 @@ interface ActionDomNode extends Element {
132
132
  * time (including the submitter's pair) parked on the form node.
133
133
  */
134
134
  interface QueuedSubmission {
135
- data: FormData;
136
- submitter: ActionDomNode | null;
135
+ data: FormData
136
+ submitter: ActionDomNode | null
137
137
  }
138
138
 
139
139
  interface QueuedForm extends HTMLFormElement {
140
- __pnextQueuedSubmit?: QueuedSubmission;
140
+ __pnextQueuedSubmit?: QueuedSubmission
141
141
  }
142
142
 
143
143
  function takeQueuedSubmission(form: HTMLFormElement): QueuedSubmission | undefined {
144
- const queued = (form as QueuedForm).__pnextQueuedSubmit;
145
- if (queued) delete (form as QueuedForm).__pnextQueuedSubmit;
146
- return queued;
144
+ const queued = (form as QueuedForm).__pnextQueuedSubmit
145
+ if (queued) delete (form as QueuedForm).__pnextQueuedSubmit
146
+ return queued
147
147
  }
148
148
 
149
149
  /** Dispatch a captured submission with form-status + post-action reset (the
@@ -153,47 +153,49 @@ function runFormSubmission(
153
153
  formData: FormData,
154
154
  dispatch: (formData: FormData) => unknown,
155
155
  ): void {
156
- const pop = pushFormStatus(form, formData);
156
+ const pop = pushFormStatus(form, formData)
157
157
  void Promise.resolve(dispatch(formData))
158
158
  .then(() => {
159
159
  // React resets uncontrolled fields after a completed form action.
160
- form.reset();
160
+ form.reset()
161
161
  })
162
162
  .catch(error => {
163
- if (!throwActionErrorAt(form, error)) throw error;
163
+ if (!throwActionErrorAt(form, error)) throw error
164
164
  })
165
- .finally(pop);
165
+ .finally(pop)
166
166
  }
167
167
 
168
168
  function throwActionErrorAt(node: Element, error: unknown): boolean {
169
- const root = node.closest('pnext-client');
170
- const rootVNode = (root as unknown as { __k?: VNode } | null)?.__k;
171
- const vnode = rootVNode ? findVNodeForElement(rootVNode, node) : undefined;
172
- const handler = (preactOptions as typeof preactOptions & {
173
- __e?: (error: unknown, vnode: VNode, oldVNode: VNode) => void;
174
- }).__e;
175
- if (!vnode || !handler) return false;
176
- handler(error, vnode, vnode);
177
- return true;
169
+ const root = node.closest('pnext-client')
170
+ const rootVNode = (root as unknown as { __k?: VNode } | null)?.__k
171
+ const vnode = rootVNode ? findVNodeForElement(rootVNode, node) : undefined
172
+ const handler = (
173
+ preactOptions as typeof preactOptions & {
174
+ __e?: (error: unknown, vnode: VNode, oldVNode: VNode) => void
175
+ }
176
+ ).__e
177
+ if (!vnode || !handler) return false
178
+ handler(error, vnode, vnode)
179
+ return true
178
180
  }
179
181
 
180
182
  function findVNodeForElement(vnode: VNode, element: Element): VNode | undefined {
181
- if ((vnode as VNode & { __e?: unknown }).__e === element) return vnode;
182
- const children = (vnode as VNode & { __k?: (VNode | null)[] }).__k;
183
- if (!children) return undefined;
183
+ if ((vnode as VNode & { __e?: unknown }).__e === element) return vnode
184
+ const children = (vnode as VNode & { __k?: (VNode | null)[] }).__k
185
+ if (!children) return undefined
184
186
  for (const child of children) {
185
- if (!child) continue;
186
- const found = findVNodeForElement(child, element);
187
- if (found) return found;
187
+ if (!child) continue
188
+ const found = findVNodeForElement(child, element)
189
+ if (found) return found
188
190
  }
189
- return undefined;
191
+ return undefined
190
192
  }
191
193
 
192
194
  /** Replay a pre-hydration submission the moment the form's function action
193
195
  * hydrates (called from the stashed ref below). */
194
196
  function replayQueuedSubmission(form: HTMLFormElement, fn: (formData: FormData) => unknown): void {
195
- const queued = takeQueuedSubmission(form);
196
- if (queued) runFormSubmission(form, queued.data, fn);
197
+ const queued = takeQueuedSubmission(form)
198
+ if (queued) runFormSubmission(form, queued.data, fn)
197
199
  }
198
200
 
199
201
  /**
@@ -204,74 +206,73 @@ function replayQueuedSubmission(form: HTMLFormElement, fn: (formData: FormData)
204
206
  */
205
207
  function adoptEarlySubmissions(): void {
206
208
  const holder = window as typeof window & {
207
- __pnextEarlySubmits?: HTMLFormElement[];
208
- __pnextRemoveEarlySubmit?: () => void;
209
- };
210
- holder.__pnextRemoveEarlySubmit?.();
211
- const forms = holder.__pnextEarlySubmits;
212
- if (!forms?.length) return;
209
+ __pnextEarlySubmits?: HTMLFormElement[]
210
+ __pnextRemoveEarlySubmit?: () => void
211
+ }
212
+ holder.__pnextRemoveEarlySubmit?.()
213
+ const forms = holder.__pnextEarlySubmits
214
+ if (!forms?.length) return
213
215
  const flush = () => {
214
216
  for (const form of forms.splice(0)) {
215
- const queued = takeQueuedSubmission(form);
216
- if (!queued) continue; // hydration replayed it already
217
+ const queued = takeQueuedSubmission(form)
218
+ if (!queued) continue // hydration replayed it already
217
219
  const stashed =
218
- queued.submitter?.__pnextFormAction ??
219
- (form as unknown as ActionDomNode).__pnextFormAction;
220
+ queued.submitter?.__pnextFormAction ?? (form as unknown as ActionDomNode).__pnextFormAction
220
221
  if (stashed) {
221
- runFormSubmission(form, queued.data, stashed);
222
- continue;
222
+ runFormSubmission(form, queued.data, stashed)
223
+ continue
223
224
  }
224
225
  const submitterId =
225
226
  queued.submitter?.getAttribute('name') === SUBMIT_ACTION_ID_FIELD
226
227
  ? queued.submitter.getAttribute('value')
227
- : null;
228
+ : null
228
229
  const id =
229
230
  submitterId ??
230
231
  form.querySelector<HTMLInputElement>(`input[name="${cssEscape(ACTION_ID_FIELD)}"]`)
231
232
  ?.value ??
232
233
  form.getAttribute(ACTION_ID_ATTR) ??
233
- undefined;
234
+ undefined
234
235
  const hasFormState = Boolean(
235
236
  form.querySelector(`input[name="${cssEscape(FORM_STATE_FIELD)}"]`),
236
- );
237
+ )
237
238
  if (id && !hasFormState) {
238
239
  // Server-only progressive form (no live state to update): dispatch the
239
240
  // RPC directly, like the live listener's unhydrated-form branch.
240
- runFormSubmission(form, queued.data, formData => callAction(id, [formData]));
241
+ runFormSubmission(form, queued.data, formData => callAction(id, [formData]))
241
242
  } else if (form.isConnected) {
242
243
  // A useActionState form whose island never hydrated (or an unknown
243
244
  // shape): give it the native progressive POST the capture prevented.
244
- form.submit();
245
+ form.submit()
245
246
  }
246
247
  }
247
- };
248
+ }
248
249
  // Islands hydrate asynchronously after this runtime installs; give their
249
250
  // refs (replayQueuedSubmission) first claim before falling back.
250
- setTimeout(flush, 300);
251
+ setTimeout(flush, 300)
251
252
  }
252
253
 
253
254
  type FunctionActionProps = Record<string, unknown> & {
254
- action?: unknown;
255
- formAction?: unknown;
256
- ref?: unknown;
257
- };
255
+ action?: unknown
256
+ formAction?: unknown
257
+ ref?: unknown
258
+ }
258
259
 
259
260
  function installVNodeHook() {
260
- const previous = preactOptions.vnode?.bind(preactOptions);
261
+ const previous = preactOptions.vnode?.bind(preactOptions)
261
262
  preactOptions.vnode = (vnode: VNode) => {
262
- previous?.(vnode);
263
- if (typeof vnode.type !== 'string') return;
264
- const props = vnode.props as FunctionActionProps;
263
+ previous?.(vnode)
264
+ if (typeof vnode.type !== 'string') return
265
+ const props = vnode.props as FunctionActionProps
265
266
  if (vnode.type === 'form' && typeof props.action === 'function') {
266
- stashFunctionAction(vnode, props, 'action');
267
+ stashFunctionAction(vnode, props, 'action')
267
268
  }
268
269
  if (
269
270
  (vnode.type === 'button' || vnode.type === 'input') &&
270
271
  typeof props.formAction === 'function'
271
272
  ) {
272
- stashFunctionAction(vnode, props, 'formAction');
273
+ stashFunctionAction(vnode, props, 'formAction')
273
274
  }
274
- };
275
+ }
275
276
  }
276
277
 
277
278
  /**
@@ -287,33 +288,33 @@ function stashFunctionAction(
287
288
  props: FunctionActionProps,
288
289
  key: 'action' | 'formAction',
289
290
  ) {
290
- const fn = props[key] as (formData: FormData) => unknown;
291
- delete props[key];
292
- const existingRef = (vnode as { ref?: unknown }).ref;
293
- (vnode as { ref?: unknown }).ref = (node: ActionDomNode | null) => {
291
+ const fn = props[key] as (formData: FormData) => unknown
292
+ delete props[key]
293
+ const existingRef = (vnode as { ref?: unknown }).ref
294
+ ;(vnode as { ref?: unknown }).ref = (node: ActionDomNode | null) => {
294
295
  if (node) {
295
- node.__pnextFormAction = fn;
296
+ node.__pnextFormAction = fn
296
297
  if (key === 'action' && node instanceof HTMLFormElement) {
297
- enhanceProgressiveForm(node, fn);
298
- replayQueuedSubmission(node, fn);
298
+ enhanceProgressiveForm(node, fn)
299
+ replayQueuedSubmission(node, fn)
299
300
  }
300
301
  if (key === 'formAction' && node instanceof HTMLElement) {
301
- const form = (node as { form?: HTMLFormElement | null }).form ?? null;
302
- const queued = form && (form as QueuedForm).__pnextQueuedSubmit;
302
+ const form = (node as { form?: HTMLFormElement | null }).form ?? null
303
+ const queued = form && (form as QueuedForm).__pnextQueuedSubmit
303
304
  if (form && queued?.submitter === node) {
304
- delete (form as QueuedForm).__pnextQueuedSubmit;
305
- runFormSubmission(form, queued.data, fn);
305
+ delete (form as QueuedForm).__pnextQueuedSubmit
306
+ runFormSubmission(form, queued.data, fn)
306
307
  }
307
308
  }
308
309
  }
309
- applyRef(existingRef, node);
310
- };
310
+ applyRef(existingRef, node)
311
+ }
311
312
  }
312
313
 
313
314
  interface FormStateMeta {
314
- action?: { $$pnextActionId?: string };
315
- state?: unknown;
316
- permalink?: string;
315
+ action?: { $$pnextActionId?: string }
316
+ state?: unknown
317
+ permalink?: string
317
318
  }
318
319
 
319
320
  /**
@@ -323,88 +324,88 @@ interface FormStateMeta {
323
324
  * every render, keeping the state field current.
324
325
  */
325
326
  function enhanceProgressiveForm(form: HTMLFormElement, fn: unknown) {
326
- const meta = (fn as { $$pnextFormState?: FormStateMeta }).$$pnextFormState;
327
- if (!meta) return;
328
- const id = meta.action?.$$pnextActionId;
329
- if (!id) return;
330
- form.setAttribute('method', 'post');
331
- form.setAttribute('enctype', 'multipart/form-data');
332
- if (meta.permalink) form.setAttribute('action', meta.permalink);
333
- setHiddenField(form, ACTION_ID_FIELD, id);
327
+ const meta = (fn as { $$pnextFormState?: FormStateMeta }).$$pnextFormState
328
+ if (!meta) return
329
+ const id = meta.action?.$$pnextActionId
330
+ if (!id) return
331
+ form.setAttribute('method', 'post')
332
+ form.setAttribute('enctype', 'multipart/form-data')
333
+ if (meta.permalink) form.setAttribute('action', meta.permalink)
334
+ setHiddenField(form, ACTION_ID_FIELD, id)
334
335
  // Non-JSON-serializable state (an action can return React elements, Maps,
335
336
  // circular structures, ...) cannot ride the progressive wire; fall back to
336
337
  // null rather than throwing inside the render's ref (which would take the
337
338
  // whole island down with it).
338
- let serializedState = 'null';
339
+ let serializedState = 'null'
339
340
  try {
340
- serializedState = JSON.stringify(meta.state ?? null) ?? 'null';
341
+ serializedState = JSON.stringify(meta.state ?? null) ?? 'null'
341
342
  } catch {
342
- serializedState = 'null';
343
+ serializedState = 'null'
343
344
  }
344
- setHiddenField(form, FORM_STATE_FIELD, serializedState);
345
+ setHiddenField(form, FORM_STATE_FIELD, serializedState)
345
346
  }
346
347
 
347
348
  function setHiddenField(form: HTMLFormElement, name: string, value: string) {
348
349
  let input = form.querySelector<HTMLInputElement>(
349
350
  `input[type="hidden"][name="${cssEscape(name)}"]`,
350
- );
351
+ )
351
352
  if (!input) {
352
- input = document.createElement('input');
353
- input.type = 'hidden';
354
- input.name = name;
355
- form.appendChild(input);
353
+ input = document.createElement('input')
354
+ input.type = 'hidden'
355
+ input.name = name
356
+ form.appendChild(input)
356
357
  }
357
- input.value = value;
358
+ input.value = value
358
359
  }
359
360
 
360
361
  function applyRef(ref: unknown, node: Element | null) {
361
- if (typeof ref === 'function') (ref as (node: Element | null) => void)(node);
362
- else if (ref && typeof ref === 'object') (ref as { current: Element | null }).current = node;
362
+ if (typeof ref === 'function') (ref as (node: Element | null) => void)(node)
363
+ else if (ref && typeof ref === 'object') (ref as { current: Element | null }).current = node
363
364
  }
364
365
 
365
366
  function installSubmitListener() {
366
367
  document.addEventListener(
367
368
  'submit',
368
369
  event => {
369
- const form = event.target as HTMLFormElement | null;
370
- if (!form || !(form instanceof HTMLFormElement)) return;
371
- const submitter = event.submitter as ActionDomNode | null;
370
+ const form = event.target as HTMLFormElement | null
371
+ if (!form || !(form instanceof HTMLFormElement)) return
372
+ const submitter = event.submitter as ActionDomNode | null
372
373
 
373
374
  const fn =
374
- submitter?.__pnextFormAction || (form as unknown as ActionDomNode).__pnextFormAction;
375
+ submitter?.__pnextFormAction || (form as unknown as ActionDomNode).__pnextFormAction
375
376
 
376
- let dispatch: ((formData: FormData) => unknown) | undefined = fn;
377
+ let dispatch: ((formData: FormData) => unknown) | undefined = fn
377
378
  if (!dispatch) {
378
379
  // A useActionState form that never hydrated (rendered by a server
379
380
  // component or an unhydrated client layout) has no live state to
380
381
  // update — let the native progressive POST run so the server
381
382
  // re-renders the page with the new form state.
382
- if (form.querySelector(`input[name="${cssEscape(FORM_STATE_FIELD)}"]`)) return;
383
+ if (form.querySelector(`input[name="${cssEscape(FORM_STATE_FIELD)}"]`)) return
383
384
  // Server-rendered progressive form: the id travels in a hidden field
384
385
  // (or the submitter button's own name/value pair under its distinct
385
386
  // field name, which overrides the form-level default).
386
387
  const submitterId =
387
388
  submitter?.getAttribute('name') === SUBMIT_ACTION_ID_FIELD
388
389
  ? submitter.getAttribute('value')
389
- : null;
390
+ : null
390
391
  const field = form.querySelector<HTMLInputElement>(
391
392
  `input[name="${cssEscape(ACTION_ID_FIELD)}"]`,
392
- );
393
+ )
393
394
  // The hidden id may have been moved out-of-band (stripProgressiveActionIds).
394
- const id = submitterId ?? field?.value ?? form.getAttribute(ACTION_ID_ATTR);
395
- if (!id) return; // not an action form; let the browser submit it
396
- dispatch = formData => callAction(id, [formData]);
395
+ const id = submitterId ?? field?.value ?? form.getAttribute(ACTION_ID_ATTR)
396
+ if (!id) return // not an action form; let the browser submit it
397
+ dispatch = formData => callAction(id, [formData])
397
398
  }
398
399
 
399
- event.preventDefault();
400
- const formData = new FormData(form, (submitter ?? undefined) as HTMLElement | undefined);
401
- runFormSubmission(form, formData, dispatch);
400
+ event.preventDefault()
401
+ const formData = new FormData(form, (submitter ?? undefined) as HTMLElement | undefined)
402
+ runFormSubmission(form, formData, dispatch)
402
403
  },
403
404
  // Bubble phase, so app-level onSubmit handlers that preventDefault
404
405
  // themselves run first and can opt out of the default action behavior.
405
406
  false,
406
- );
407
- adoptEarlySubmissions();
407
+ )
408
+ adoptEarlySubmissions()
408
409
  }
409
410
 
410
411
  /**
@@ -421,18 +422,18 @@ function installSubmitListener() {
421
422
  * POST fallback (installSubmitListener bails to native for form-state forms).
422
423
  */
423
424
  function stripProgressiveActionIds() {
424
- if (typeof document === 'undefined') return;
425
+ if (typeof document === 'undefined') return
425
426
  const inputs = document.querySelectorAll<HTMLInputElement>(
426
427
  `input[type="hidden"][name="${cssEscape(ACTION_ID_FIELD)}"]`,
427
- );
428
+ )
428
429
  for (const input of inputs) {
429
- const form = input.form;
430
- if (!form) continue;
431
- if (form.querySelector(`input[name="${cssEscape(FORM_STATE_FIELD)}"]`)) continue;
430
+ const form = input.form
431
+ if (!form) continue
432
+ if (form.querySelector(`input[name="${cssEscape(FORM_STATE_FIELD)}"]`)) continue
432
433
  if (input.value && !form.hasAttribute(ACTION_ID_ATTR)) {
433
- form.setAttribute(ACTION_ID_ATTR, input.value);
434
+ form.setAttribute(ACTION_ID_ATTR, input.value)
434
435
  }
435
- input.remove();
436
+ input.remove()
436
437
  }
437
438
  }
438
439
 
@@ -441,18 +442,18 @@ function installClickActionListener() {
441
442
  const target =
442
443
  event.target instanceof Element
443
444
  ? event.target.closest<HTMLElement>(`[${ACTION_CLICK_ID_ATTR}]`)
444
- : null;
445
- if (!target || (target instanceof HTMLButtonElement && target.disabled)) return;
446
- const id = target.getAttribute(ACTION_CLICK_ID_ATTR);
447
- if (!id) return;
448
- event.preventDefault();
449
- void callAction(id, []);
450
- });
445
+ : null
446
+ if (!target || (target instanceof HTMLButtonElement && target.disabled)) return
447
+ const id = target.getAttribute(ACTION_CLICK_ID_ATTR)
448
+ if (!id) return
449
+ event.preventDefault()
450
+ void callAction(id, [])
451
+ })
451
452
  }
452
453
 
453
454
  function cssEscape(value: string) {
454
- const escape = (globalThis as { CSS?: { escape?: (v: string) => string } }).CSS?.escape;
455
- return escape ? escape(value) : value.replace(/[^a-zA-Z0-9_-]/g, match => `\\${match}`);
455
+ const escape = (globalThis as { CSS?: { escape?: (v: string) => string } }).CSS?.escape
456
+ return escape ? escape(value) : value.replace(/[^a-zA-Z0-9_-]/g, match => `\\${match}`)
456
457
  }
457
458
 
458
459
  // Form-status feed for useFormStatus (react-dom compat).
@@ -463,9 +464,9 @@ function pushFormStatus(form: HTMLFormElement, data: FormData): () => void {
463
464
  data,
464
465
  method: (form.getAttribute('method') || 'get').toLowerCase(),
465
466
  action: form.getAttribute('action') ?? '',
466
- });
467
+ })
467
468
  } catch {
468
- return () => undefined;
469
+ return () => undefined
469
470
  }
470
471
  }
471
472
 
@@ -477,35 +478,35 @@ function pushFormStatus(form: HTMLFormElement, data: FormData): () => void {
477
478
  // pnext's server-rendered pages have no client-side boundary components, so the compat entry installs
478
479
  // the route's error.js as an overlay. Only the listeners are initial - the overlay body, which needs
479
480
  // preact's renderer and the refresh path, rides the deferred dispatch chunk.
480
- type ErrorComponentType = ComponentType<{ error: Error; reset: () => void }>;
481
+ type ErrorComponentType = ComponentType<{ error: Error; reset: () => void }>
481
482
 
482
- let overlayInstalled = false;
483
+ let overlayInstalled = false
483
484
 
484
485
  export function installActionErrorOverlay(Component: ErrorComponentType) {
485
- if ((!process.browser && typeof window === 'undefined') || overlayInstalled) return;
486
- overlayInstalled = true;
486
+ if ((!process.browser && typeof window === 'undefined') || overlayInstalled) return
487
+ overlayInstalled = true
487
488
 
488
489
  // Chained, not concurrent: two errors arriving before the chunk lands must
489
490
  // still see each other's effect on the overlay's "already showing" guard.
490
- let chain: Promise<unknown> = Promise.resolve();
491
+ let chain: Promise<unknown> = Promise.resolve()
491
492
  const show = (reason: unknown) => {
492
493
  chain = chain.then(async () => {
493
- const { showActionErrorOverlay } = await dispatchRuntime();
494
- showActionErrorOverlay(Component, reason);
495
- });
496
- };
494
+ const { showActionErrorOverlay } = await dispatchRuntime()
495
+ showActionErrorOverlay(Component, reason)
496
+ })
497
+ }
497
498
 
498
499
  window.addEventListener('unhandledrejection', event => {
499
- if (isActionError(event.reason)) show(event.reason);
500
- });
500
+ if (isActionError(event.reason)) show(event.reason)
501
+ })
501
502
  // useActionState rethrows action errors during render; without a class
502
503
  // error boundary in the tree the uncaught render error lands here.
503
504
  window.addEventListener('error', event => {
504
- if (isActionError(event.error)) show(event.error);
505
- });
505
+ if (isActionError(event.error)) show(event.error)
506
+ })
506
507
  window.addEventListener('pnext:action-error', event => {
507
- show((event as CustomEvent).detail);
508
- });
508
+ show((event as CustomEvent).detail)
509
+ })
509
510
  }
510
511
 
511
512
  // ---------------------------------------------------------------------------
@@ -513,26 +514,26 @@ export function installActionErrorOverlay(Component: ErrorComponentType) {
513
514
  // ---------------------------------------------------------------------------
514
515
 
515
516
  export function installActionRuntime() {
516
- if (!process.browser && typeof window === 'undefined') return;
517
+ if (!process.browser && typeof window === 'undefined') return
517
518
  if (!window.__PNEXT_ACTIONS__) {
518
519
  window.__PNEXT_ACTIONS__ = {
519
520
  call: callAction,
520
521
  createAction,
521
522
  registerClientReference,
522
523
  reviveProps,
523
- };
524
- installSubmitListener();
525
- installClickActionListener();
524
+ }
525
+ installSubmitListener()
526
+ installClickActionListener()
526
527
  // Every mountRoute (initial hydration + each soft-nav commit) fires
527
528
  // `pnext:hydrated`; strip leaked progressive action-id inputs from the
528
529
  // freshly committed DOM so a hydrated form matches React (no `$ACTION_ID`).
529
530
  // Hydration is also where the dispatch chunk gets warmed (see loadDispatch):
530
531
  // past first paint, before any click, and `import()` dedups the repeats.
531
- window.addEventListener('pnext:hydrated', stripProgressiveActionIds);
532
- window.addEventListener('pnext:hydrated', warmDispatchChunk);
533
- stripProgressiveActionIds();
532
+ window.addEventListener('pnext:hydrated', stripProgressiveActionIds)
533
+ window.addEventListener('pnext:hydrated', warmDispatchChunk)
534
+ stripProgressiveActionIds()
534
535
  }
535
- installVNodeHook();
536
+ installVNodeHook()
536
537
  }
537
538
 
538
- export { createAction, callAction, registerClientReference, reviveProps };
539
+ export { createAction, callAction, registerClientReference, reviveProps }