@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,7 +1,7 @@
1
1
  /**
2
2
  * The dispatch half of the client action runtime: argument encoding, the POST wire, redirect/refresh/
3
3
  * error semantics, action-return revival, and the route error.js overlay body. Nothing here can run
4
- * before an action actually fires, so action-client.ts reaches it through a dynamic import() and this
4
+ * before an action actually fires, so client.ts reaches it through a dynamic import() and this
5
5
  * whole module lands in a deferred chunk.
6
6
  *
7
7
  * Wire shape (see compat/actions/protocol.ts): POST to the CURRENT page URL with the action id in the
@@ -13,15 +13,15 @@
13
13
  * content-type throws the "unexpected response" error React shows; a 404 with the not-found marker
14
14
  * swaps in the server-rendered 404 page.
15
15
  */
16
- import { h, render, type ComponentType } from 'preact';
16
+ import { h, render, type ComponentType } from 'preact'
17
17
  import {
18
18
  blockJavascriptUrl,
19
19
  evictClientRouterCache,
20
20
  rearmVisiblePrefetches,
21
21
  softNavigate,
22
- } from '../../api/router';
23
- import { onNavigationStart } from '../../api/router/events';
24
- import { UnrecognizedActionError } from './unrecognized-error';
22
+ } from '../../client/router'
23
+ import { onNavigationStart } from '../../client/router/events'
24
+ import { UnrecognizedActionError } from './unrecognized-error'
25
25
  import {
26
26
  ACTION_ID_FIELD,
27
27
  ARRAY_BUFFER_MARKER,
@@ -32,42 +32,42 @@ import {
32
32
  reviveBinaryMarker,
33
33
  tagActionError,
34
34
  type ActionFunction,
35
- } from './action-shared';
36
-
37
- const ACTION_ID_HEADER = 'next-action';
38
- const ACTION_REDIRECT_HEADER = 'x-action-redirect';
39
- const ACTION_REFRESH_HEADER = 'x-pnext-action-refresh';
40
- const NEXT_ACTION_REVALIDATED_HEADER = 'x-action-revalidated';
41
- const ACTION_NOT_FOUND_HEADER = 'x-pnext-action-not-found';
42
- const NEXT_ACTION_NOT_FOUND_HEADER = 'x-nextjs-action-not-found';
43
- const ACTION_ERROR_DIGEST_HEADER = 'x-pnext-action-error-digest';
44
- const ACTION_FLIGHT_CONTENT_TYPE = 'text/x-component';
45
- const ACTION_ARGS_FIELD = '$pnext_args';
46
- const ARG_FORMDATA_MARKER = '$$pnext_fd';
47
- const ARG_FILE_MARKER = '$$pnext_file';
48
- const ARG_FORMDATA_PREFIX = '$pnext_fd_';
49
- const ARG_FILE_PREFIX = '$pnext_file_';
50
- const ARG_ACTION_MARKER = '$$pnext_action_ref';
51
- const REDIRECT_TYPE_HEADER = 'x-pnext-redirect-type';
52
- const TEMP_REF_MARKER = '$$pnext_temp_ref';
53
- const ACTION_STREAM_CONTENT_TYPE = 'x-component/pnext-stream';
54
- const ACTION_ELEMENT_MARKER = '$$pnext_element';
55
- const ACTION_ELEMENT_HTML_MARKER = '$$pnext_element_html';
35
+ } from './shared'
36
+
37
+ const ACTION_ID_HEADER = 'next-action'
38
+ const ACTION_REDIRECT_HEADER = 'x-action-redirect'
39
+ const ACTION_REFRESH_HEADER = 'x-pnext-action-refresh'
40
+ const NEXT_ACTION_REVALIDATED_HEADER = 'x-action-revalidated'
41
+ const ACTION_NOT_FOUND_HEADER = 'x-pnext-action-not-found'
42
+ const NEXT_ACTION_NOT_FOUND_HEADER = 'x-nextjs-action-not-found'
43
+ const ACTION_ERROR_DIGEST_HEADER = 'x-pnext-action-error-digest'
44
+ const ACTION_FLIGHT_CONTENT_TYPE = 'text/x-component'
45
+ const ACTION_ARGS_FIELD = '$pnext_args'
46
+ const ARG_FORMDATA_MARKER = '$$pnext_fd'
47
+ const ARG_FILE_MARKER = '$$pnext_file'
48
+ const ARG_FORMDATA_PREFIX = '$pnext_fd_'
49
+ const ARG_FILE_PREFIX = '$pnext_file_'
50
+ const ARG_ACTION_MARKER = '$$pnext_action_ref'
51
+ const REDIRECT_TYPE_HEADER = 'x-pnext-redirect-type'
52
+ const TEMP_REF_MARKER = '$$pnext_temp_ref'
53
+ const ACTION_STREAM_CONTENT_TYPE = 'x-component/pnext-stream'
54
+ const ACTION_ELEMENT_MARKER = '$$pnext_element'
55
+ const ACTION_ELEMENT_HTML_MARKER = '$$pnext_element_html'
56
56
 
57
57
  const MASKED_ACTION_ERROR =
58
- 'Minified React error #441; visit https://react.dev/errors/441 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.';
59
- const UNEXPECTED_RESPONSE = 'An unexpected response was received from the server.';
58
+ 'Minified React error #441; visit https://react.dev/errors/441 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.'
59
+ const UNEXPECTED_RESPONSE = 'An unexpected response was received from the server.'
60
60
 
61
61
  // Only compared within a single dispatch, so starting the count when this
62
62
  // module loads (rather than at page load) changes nothing.
63
- let clientNavigationGeneration = 0;
63
+ let clientNavigationGeneration = 0
64
64
  onNavigationStart(() => {
65
- clientNavigationGeneration += 1;
66
- });
65
+ clientNavigationGeneration += 1
66
+ })
67
67
 
68
68
  interface ActionFlightPayload {
69
- a?: unknown;
70
- f?: { kind?: string; html?: string; url?: string } | '';
69
+ a?: unknown
70
+ f?: { kind?: string; html?: string; url?: string } | ''
71
71
  }
72
72
 
73
73
  // ---------------------------------------------------------------------------
@@ -75,69 +75,67 @@ interface ActionFlightPayload {
75
75
  // ---------------------------------------------------------------------------
76
76
 
77
77
  function isPlainSerializable(value: unknown, depth = 0): boolean {
78
- if (value === null || value === undefined) return true;
79
- const type = typeof value;
80
- if (type === 'string' || type === 'number' || type === 'boolean') return true;
81
- if (type !== 'object') return false;
82
- if (depth > 32) return false;
83
- if (isBinary(value)) return true; // marker-encoded on the wire
84
- if (Array.isArray(value)) return value.every(item => isPlainSerializable(item, depth + 1));
85
- if (value instanceof FormData || isFileLike(value)) return false; // handled by caller
86
- if (value instanceof Date) return true;
87
- if (typeof (value as PromiseLike<unknown>).then === 'function') return true;
78
+ if (value === null || value === undefined) return true
79
+ const type = typeof value
80
+ if (type === 'string' || type === 'number' || type === 'boolean') return true
81
+ if (type !== 'object') return false
82
+ if (depth > 32) return false
83
+ if (isBinary(value)) return true // marker-encoded on the wire
84
+ if (Array.isArray(value)) return value.every(item => isPlainSerializable(item, depth + 1))
85
+ if (value instanceof FormData || isFileLike(value)) return false // handled by caller
86
+ if (value instanceof Date) return true
87
+ if (typeof (value as PromiseLike<unknown>).then === 'function') return true
88
88
  if (value instanceof Map) {
89
89
  return [...value.entries()].every(
90
90
  ([k, v]) => isPlainSerializable(k, depth + 1) && isPlainSerializable(v, depth + 1),
91
- );
91
+ )
92
92
  }
93
- if (value instanceof Set) return [...value].every(item => isPlainSerializable(item, depth + 1));
94
- const proto = Object.getPrototypeOf(value) as object | null;
95
- if (proto !== Object.prototype && proto !== null) return false;
93
+ if (value instanceof Set) return [...value].every(item => isPlainSerializable(item, depth + 1))
94
+ const proto = Object.getPrototypeOf(value) as object | null
95
+ if (proto !== Object.prototype && proto !== null) return false
96
96
  return Object.values(value as Record<string, unknown>).every(item =>
97
97
  isPlainSerializable(item, depth + 1),
98
- );
98
+ )
99
99
  }
100
100
 
101
101
  function isFileLike(value: unknown): value is Blob {
102
- return typeof Blob !== 'undefined' && value instanceof Blob;
102
+ return typeof Blob !== 'undefined' && value instanceof Blob
103
103
  }
104
104
 
105
105
  function isBinary(value: unknown): value is ArrayBufferView | ArrayBuffer {
106
- return (
107
- value instanceof ArrayBuffer || (ArrayBuffer.isView(value) && !(value instanceof DataView))
108
- );
106
+ return value instanceof ArrayBuffer || (ArrayBuffer.isView(value) && !(value instanceof DataView))
109
107
  }
110
108
 
111
109
  function bytesToBase64(bytes: Uint8Array): string {
112
110
  if (typeof btoa === 'function') {
113
- let binary = '';
114
- for (const byte of bytes) binary += String.fromCharCode(byte);
115
- return btoa(binary);
111
+ let binary = ''
112
+ for (const byte of bytes) binary += String.fromCharCode(byte)
113
+ return btoa(binary)
116
114
  }
117
- return Buffer.from(bytes).toString('base64');
115
+ return Buffer.from(bytes).toString('base64')
118
116
  }
119
117
 
120
118
  function encodeBinaryValue(value: ArrayBufferView | ArrayBuffer): unknown {
121
119
  if (value instanceof ArrayBuffer) {
122
- return { [ARRAY_BUFFER_MARKER]: bytesToBase64(new Uint8Array(value)) };
120
+ return { [ARRAY_BUFFER_MARKER]: bytesToBase64(new Uint8Array(value)) }
123
121
  }
124
- const bytes = new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
125
- return { [TYPED_ARRAY_MARKER]: { type: value.constructor.name, data: bytesToBase64(bytes) } };
122
+ const bytes = new Uint8Array(value.buffer, value.byteOffset, value.byteLength)
123
+ return { [TYPED_ARRAY_MARKER]: { type: value.constructor.name, data: bytesToBase64(bytes) } }
126
124
  }
127
125
 
128
126
  function containsSpecial(value: unknown): boolean {
129
- if (value instanceof FormData || isFileLike(value)) return true;
130
- if (Array.isArray(value)) return value.some(containsSpecial);
127
+ if (value instanceof FormData || isFileLike(value)) return true
128
+ if (Array.isArray(value)) return value.some(containsSpecial)
131
129
  if (value !== null && typeof value === 'object') {
132
- return Object.values(value as Record<string, unknown>).some(containsSpecial);
130
+ return Object.values(value as Record<string, unknown>).some(containsSpecial)
133
131
  }
134
- return false;
132
+ return false
135
133
  }
136
134
 
137
135
  function isActionReference(value: unknown): value is ActionFunction {
138
136
  return (
139
137
  typeof value === 'function' && typeof (value as ActionFunction).$$pnextActionId === 'string'
140
- );
138
+ )
141
139
  }
142
140
 
143
141
  /**
@@ -146,16 +144,16 @@ function isActionReference(value: unknown): value is ActionFunction {
146
144
  * undefined, and promises (awaited, like React's encodeReply).
147
145
  */
148
146
  function isThenable(value: unknown): value is PromiseLike<unknown> {
149
- return Boolean(value) && typeof (value as PromiseLike<unknown>).then === 'function';
147
+ return Boolean(value) && typeof (value as PromiseLike<unknown>).then === 'function'
150
148
  }
151
149
 
152
150
  async function encodeSpecialValues(value: unknown): Promise<unknown> {
153
- if (isActionReference(value)) return { [ARG_ACTION_MARKER]: value.$$pnextActionId };
154
- if (value === undefined) return { $$pnext_undefined: true };
155
- if (isBinary(value)) return encodeBinaryValue(value);
156
- if (value instanceof Date) return { $$pnext_date: value.toISOString() };
151
+ if (isActionReference(value)) return { [ARG_ACTION_MARKER]: value.$$pnextActionId }
152
+ if (value === undefined) return { $$pnext_undefined: true }
153
+ if (isBinary(value)) return encodeBinaryValue(value)
154
+ if (value instanceof Date) return { $$pnext_date: value.toISOString() }
157
155
  if (isThenable(value)) {
158
- return encodeSpecialValues(await value);
156
+ return encodeSpecialValues(await value)
159
157
  }
160
158
  if (value instanceof Map) {
161
159
  return {
@@ -165,48 +163,48 @@ async function encodeSpecialValues(value: unknown): Promise<unknown> {
165
163
  await encodeSpecialValues(v),
166
164
  ]),
167
165
  ),
168
- };
166
+ }
169
167
  }
170
168
  if (value instanceof Set) {
171
- return { $$pnext_set: await Promise.all([...value].map(encodeSpecialValues)) };
169
+ return { $$pnext_set: await Promise.all([...value].map(encodeSpecialValues)) }
172
170
  }
173
- if (Array.isArray(value)) return Promise.all(value.map(encodeSpecialValues));
171
+ if (Array.isArray(value)) return Promise.all(value.map(encodeSpecialValues))
174
172
  if (
175
173
  value !== null &&
176
174
  typeof value === 'object' &&
177
175
  !(value instanceof FormData) &&
178
176
  !isFileLike(value)
179
177
  ) {
180
- const proto = Object.getPrototypeOf(value) as object | null;
178
+ const proto = Object.getPrototypeOf(value) as object | null
181
179
  if (proto === Object.prototype || proto === null) {
182
- const out: Record<string, unknown> = {};
180
+ const out: Record<string, unknown> = {}
183
181
  for (const [key, item] of Object.entries(value as Record<string, unknown>)) {
184
- out[key] = await encodeSpecialValues(item);
182
+ out[key] = await encodeSpecialValues(item)
185
183
  }
186
- return out;
184
+ return out
187
185
  }
188
186
  }
189
- return value;
187
+ return value
190
188
  }
191
189
 
192
190
  function assertSerializableArg(value: unknown) {
193
- if (value instanceof FormData || isFileLike(value)) return;
194
- if (isActionReference(value)) return;
195
- if (isPlainSerializable(value)) return;
191
+ if (value instanceof FormData || isFileLike(value)) return
192
+ if (isActionReference(value)) return
193
+ if (isPlainSerializable(value)) return
196
194
  // eslint-disable-next-line turbo/no-undeclared-env-vars
197
- const dev = typeof process !== 'undefined' && process.env.NODE_ENV !== 'production';
195
+ const dev = typeof process !== 'undefined' && process.env.NODE_ENV !== 'production'
198
196
  throw tagActionError(
199
197
  new Error(
200
198
  dev
201
199
  ? 'Cannot access value on the server. Only plain objects can be passed to Server Actions from Client Components.'
202
200
  : MASKED_ACTION_ERROR,
203
201
  ),
204
- );
202
+ )
205
203
  }
206
204
 
207
205
  interface EncodedBody {
208
- body: BodyInit | undefined;
209
- contentType?: string;
206
+ body: BodyInit | undefined
207
+ contentType?: string
210
208
  }
211
209
 
212
210
  /**
@@ -216,9 +214,9 @@ interface EncodedBody {
216
214
  * only, never the caller's originals, and the returned map resolves markers on the response.
217
215
  */
218
216
  function tagTempRefs(originals: unknown[], encoded: unknown[]): Map<string, object> {
219
- const registry = new Map<string, object>();
220
- let counter = 0;
221
- const seen = new Set<unknown>();
217
+ const registry = new Map<string, object>()
218
+ let counter = 0
219
+ const seen = new Set<unknown>()
222
220
  const walk = (original: unknown, wire: unknown): void => {
223
221
  if (
224
222
  original === null ||
@@ -226,25 +224,25 @@ function tagTempRefs(originals: unknown[], encoded: unknown[]): Map<string, obje
226
224
  wire === null ||
227
225
  typeof wire !== 'object'
228
226
  ) {
229
- return;
227
+ return
230
228
  }
231
- if (seen.has(wire)) return;
232
- seen.add(wire);
229
+ if (seen.has(wire)) return
230
+ seen.add(wire)
233
231
  if (Array.isArray(original) && Array.isArray(wire)) {
234
- for (let i = 0; i < wire.length; i++) walk(original[i], wire[i]);
235
- return;
232
+ for (let i = 0; i < wire.length; i++) walk(original[i], wire[i])
233
+ return
236
234
  }
237
- const proto = Object.getPrototypeOf(original) as object | null;
238
- if (proto !== Object.prototype && proto !== null) return;
239
- const id = `t${counter++}`;
240
- registry.set(id, original);
241
- (wire as Record<string, unknown>)[TEMP_REF_MARKER] = id;
235
+ const proto = Object.getPrototypeOf(original) as object | null
236
+ if (proto !== Object.prototype && proto !== null) return
237
+ const id = `t${counter++}`
238
+ registry.set(id, original)
239
+ ;(wire as Record<string, unknown>)[TEMP_REF_MARKER] = id
242
240
  for (const key of Object.keys(original)) {
243
- walk((original as Record<string, unknown>)[key], (wire as Record<string, unknown>)[key]);
241
+ walk((original as Record<string, unknown>)[key], (wire as Record<string, unknown>)[key])
244
242
  }
245
- };
246
- for (let i = 0; i < encoded.length; i++) walk(originals[i], encoded[i]);
247
- return registry;
243
+ }
244
+ for (let i = 0; i < encoded.length; i++) walk(originals[i], encoded[i])
245
+ return registry
248
246
  }
249
247
 
250
248
  // Temp-ref revival is folded into reviveActionReturn's single walk: a marker
@@ -259,81 +257,81 @@ function tagTempRefs(originals: unknown[], encoded: unknown[]): Map<string, obje
259
257
  */
260
258
  function reviveActionReturn(value: unknown, tempRefs?: Map<string, object>): unknown {
261
259
  const walk = (input: unknown): unknown => {
262
- if (input === null || typeof input !== 'object') return input;
263
- if (Array.isArray(input)) return input.map(walk);
264
- const record = input as Record<string, unknown>;
265
- const tempId = record[TEMP_REF_MARKER];
266
- if (typeof tempId === 'string' && tempRefs?.has(tempId)) return tempRefs.get(tempId);
267
- const binary = reviveBinaryMarker(record);
268
- if (binary !== undefined) return binary;
260
+ if (input === null || typeof input !== 'object') return input
261
+ if (Array.isArray(input)) return input.map(walk)
262
+ const record = input as Record<string, unknown>
263
+ const tempId = record[TEMP_REF_MARKER]
264
+ if (typeof tempId === 'string' && tempRefs?.has(tempId)) return tempRefs.get(tempId)
265
+ const binary = reviveBinaryMarker(record)
266
+ if (binary !== undefined) return binary
269
267
  // A server-rendered element tree the action returned (host elements / async
270
268
  // server components): revive it into a renderable node whose innerHTML is
271
269
  // the server markup, so useActionState can drop it straight into the tree.
272
- const elementHtml = record[ACTION_ELEMENT_HTML_MARKER];
270
+ const elementHtml = record[ACTION_ELEMENT_HTML_MARKER]
273
271
  if (typeof elementHtml === 'string') {
274
- return h('span', { dangerouslySetInnerHTML: { __html: elementHtml } });
272
+ return h('span', { dangerouslySetInnerHTML: { __html: elementHtml } })
275
273
  }
276
- const encoded = record[ACTION_ELEMENT_MARKER];
274
+ const encoded = record[ACTION_ELEMENT_MARKER]
277
275
  if (encoded && typeof encoded === 'object') {
278
- const { id, props, key } = encoded as { id?: unknown; props?: unknown; key?: unknown };
279
- const component = typeof id === 'string' ? actionReturnClientReferences.get(id) : undefined;
276
+ const { id, props, key } = encoded as { id?: unknown; props?: unknown; key?: unknown }
277
+ const component = typeof id === 'string' ? actionReturnClientReferences.get(id) : undefined
280
278
  if (!component) {
281
279
  throw tagActionError(
282
280
  new Error(`Missing client component reference for action return: ${String(id)}`),
283
- );
281
+ )
284
282
  }
285
- const revivedProps = walk(props);
283
+ const revivedProps = walk(props)
286
284
  const componentProps =
287
285
  revivedProps && typeof revivedProps === 'object'
288
286
  ? (revivedProps as Record<string, unknown>)
289
- : {};
290
- return h(component, key === undefined ? componentProps : { ...componentProps, key });
287
+ : {}
288
+ return h(component, key === undefined ? componentProps : { ...componentProps, key })
291
289
  }
292
- const out: Record<string, unknown> = {};
293
- for (const [key, item] of Object.entries(record)) out[key] = walk(item);
294
- return out;
295
- };
296
- return walk(value);
290
+ const out: Record<string, unknown> = {}
291
+ for (const [key, item] of Object.entries(record)) out[key] = walk(item)
292
+ return out
293
+ }
294
+ return walk(value)
297
295
  }
298
296
 
299
297
  async function encodeArgs(
300
298
  rawArgs: unknown[],
301
299
  ): Promise<EncodedBody & { tempRefs?: Map<string, object> }> {
302
- if (rawArgs.length === 0) return { body: '[]', contentType: 'text/plain;charset=UTF-8' };
303
- for (const arg of rawArgs) assertSerializableArg(arg);
304
- const args = await Promise.all(rawArgs.map(encodeSpecialValues));
300
+ if (rawArgs.length === 0) return { body: '[]', contentType: 'text/plain;charset=UTF-8' }
301
+ for (const arg of rawArgs) assertSerializableArg(arg)
302
+ const args = await Promise.all(rawArgs.map(encodeSpecialValues))
305
303
 
306
304
  // The common form shape: exactly one FormData argument posts as-is.
307
305
  if (args.length === 1 && args[0] instanceof FormData) {
308
- return { body: stripActionFields(args[0]) };
306
+ return { body: stripActionFields(args[0]) }
309
307
  }
310
308
 
311
309
  if (!args.some(containsSpecial)) {
312
- const tempRefs = tagTempRefs(rawArgs, args);
313
- return { body: JSON.stringify(args), contentType: 'text/plain;charset=UTF-8', tempRefs };
310
+ const tempRefs = tagTempRefs(rawArgs, args)
311
+ return { body: JSON.stringify(args), contentType: 'text/plain;charset=UTF-8', tempRefs }
314
312
  }
315
313
 
316
314
  // Mixed args: multipart with a JSON descriptor referencing part slots.
317
- const form = new FormData();
318
- let formDataSlots = 0;
319
- let fileSlots = 0;
315
+ const form = new FormData()
316
+ let formDataSlots = 0
317
+ let fileSlots = 0
320
318
  const encoded = args.map(arg => {
321
319
  if (arg instanceof FormData) {
322
- const slot = formDataSlots++;
320
+ const slot = formDataSlots++
323
321
  for (const [key, item] of stripActionFields(arg).entries()) {
324
- form.append(`${ARG_FORMDATA_PREFIX}${slot}:${key}`, item);
322
+ form.append(`${ARG_FORMDATA_PREFIX}${slot}:${key}`, item)
325
323
  }
326
- return { [ARG_FORMDATA_MARKER]: slot };
324
+ return { [ARG_FORMDATA_MARKER]: slot }
327
325
  }
328
326
  if (isFileLike(arg)) {
329
- const slot = fileSlots++;
330
- form.append(`${ARG_FILE_PREFIX}${slot}`, arg);
331
- return { [ARG_FILE_MARKER]: slot };
327
+ const slot = fileSlots++
328
+ form.append(`${ARG_FILE_PREFIX}${slot}`, arg)
329
+ return { [ARG_FILE_MARKER]: slot }
332
330
  }
333
- return arg;
334
- });
335
- form.append(ACTION_ARGS_FIELD, JSON.stringify(encoded));
336
- return { body: form };
331
+ return arg
332
+ })
333
+ form.append(ACTION_ARGS_FIELD, JSON.stringify(encoded))
334
+ return { body: form }
337
335
  }
338
336
 
339
337
  function stripActionFields(form: FormData): FormData {
@@ -342,13 +340,13 @@ function stripActionFields(form: FormData): FormData {
342
340
  !form.has(SUBMIT_ACTION_ID_FIELD) &&
343
341
  !form.has(FORM_STATE_FIELD)
344
342
  )
345
- return form;
346
- const stripped = new FormData();
343
+ return form
344
+ const stripped = new FormData()
347
345
  for (const [key, item] of form.entries()) {
348
346
  if (key !== ACTION_ID_FIELD && key !== SUBMIT_ACTION_ID_FIELD && key !== FORM_STATE_FIELD)
349
- stripped.append(key, item);
347
+ stripped.append(key, item)
350
348
  }
351
- return stripped;
349
+ return stripped
352
350
  }
353
351
 
354
352
  // ---------------------------------------------------------------------------
@@ -356,27 +354,27 @@ function stripActionFields(form: FormData): FormData {
356
354
  // ---------------------------------------------------------------------------
357
355
 
358
356
  export async function callAction(id: string, args: unknown[]): Promise<unknown> {
359
- if (typeof Event !== 'undefined' && args.at(-1) instanceof Event) args = args.slice(0, -1);
360
- const navigationGenerationAtDispatch = clientNavigationGeneration;
361
- const { body, contentType, tempRefs } = await encodeArgs(args);
357
+ if (typeof Event !== 'undefined' && args.at(-1) instanceof Event) args = args.slice(0, -1)
358
+ const navigationGenerationAtDispatch = clientNavigationGeneration
359
+ const { body, contentType, tempRefs } = await encodeArgs(args)
362
360
  // accept mirrors Next's flight wire; app code observes it via headers().
363
361
  const headers: Record<string, string> = {
364
362
  [ACTION_ID_HEADER]: id,
365
363
  accept: 'text/x-component',
366
- };
367
- if (contentType) headers['content-type'] = contentType;
364
+ }
365
+ if (contentType) headers['content-type'] = contentType
368
366
 
369
- let response: Response;
367
+ let response: Response
370
368
  try {
371
- response = await fetch(location.href, { method: 'POST', headers, body });
369
+ response = await fetch(location.href, { method: 'POST', headers, body })
372
370
  } catch (error) {
373
- throw tagActionError(error);
371
+ throw tagActionError(error)
374
372
  }
375
373
 
376
374
  // notFound() thrown inside the action: swap in the server-rendered 404 page.
377
375
  if (response.status === 404 && response.headers.get(ACTION_NOT_FOUND_HEADER)) {
378
- await swapDocument(response);
379
- return undefined;
376
+ await swapDocument(response)
377
+ return undefined
380
378
  }
381
379
 
382
380
  // Version skew: the server did not recognize the action id. React routes this
@@ -384,136 +382,136 @@ export async function callAction(id: string, args: unknown[]): Promise<unknown>
384
382
  // unstable_isUnrecognizedActionError catches it), NOT a page swap — the 404
385
383
  // body here is a plain text/plain message, not renderable HTML.
386
384
  if (response.status === 404 && response.headers.get(NEXT_ACTION_NOT_FOUND_HEADER) === '1') {
387
- const message = await response.text().catch(() => '');
385
+ const message = await response.text().catch(() => '')
388
386
  throw tagActionError(
389
387
  new UnrecognizedActionError(
390
388
  message ||
391
389
  `Server Action "${id}" was not found on the server. \nRead more: https://nextjs.org/docs/messages/failed-to-find-server-action`,
392
390
  ),
393
- );
391
+ )
394
392
  }
395
393
 
396
394
  // Single-pass redirect: a 303 with no Location (fetch would have followed
397
395
  // one) carrying the destination page HTML. Push history and swap the
398
396
  // document — no follow-up request.
399
397
  if (response.status === 303) {
400
- const rearm = hasActionRevalidated(response) ? deferActionPrefetches() : undefined;
398
+ const rearm = hasActionRevalidated(response) ? deferActionPrefetches() : undefined
401
399
  try {
402
- const target = response.headers.get(ACTION_REDIRECT_HEADER);
403
- if (target && blockJavascriptUrl(target)) return undefined;
404
- const contentType = response.headers.get('content-type') ?? '';
405
- const replace = response.headers.get(REDIRECT_TYPE_HEADER) === 'replace';
400
+ const target = response.headers.get(ACTION_REDIRECT_HEADER)
401
+ if (target && blockJavascriptUrl(target)) return undefined
402
+ const contentType = response.headers.get('content-type') ?? ''
403
+ const replace = response.headers.get(REDIRECT_TYPE_HEADER) === 'replace'
406
404
  // Single-pass flight redirect: the 303 carries the destination page HTML in
407
405
  // the flight envelope. Push history and swap the document in one round trip.
408
406
  if (target && contentType.includes(ACTION_FLIGHT_CONTENT_TYPE)) {
409
- const payload = await readActionFlightPayload(response);
410
- const flightHtml = payloadHtml(payload);
407
+ const payload = await readActionFlightPayload(response)
408
+ const flightHtml = payloadHtml(payload)
411
409
  if (flightHtml) {
412
- await replaceDocument(flightHtml, target, replace, hasActionRevalidated(response));
413
- return undefined;
410
+ await replaceDocument(flightHtml, target, replace, hasActionRevalidated(response))
411
+ return undefined
414
412
  }
415
- await navigate(target, replace);
416
- return undefined;
413
+ await navigate(target, replace)
414
+ return undefined
417
415
  }
418
416
  if (target && contentType.includes('text/html')) {
419
- const html = await response.text();
420
- await replaceDocument(html, target, replace, hasActionRevalidated(response));
421
- return undefined;
417
+ const html = await response.text()
418
+ await replaceDocument(html, target, replace, hasActionRevalidated(response))
419
+ return undefined
422
420
  }
423
421
  if (target) {
424
- await navigate(target, replace);
425
- return undefined;
422
+ await navigate(target, replace)
423
+ return undefined
426
424
  }
427
425
  } finally {
428
- rearm?.();
426
+ rearm?.()
429
427
  }
430
428
  }
431
429
 
432
430
  if (!response.ok) {
433
- const responseContentType = response.headers.get('content-type') ?? '';
431
+ const responseContentType = response.headers.get('content-type') ?? ''
434
432
  if (responseContentType.startsWith('text/plain')) {
435
- const error = new Error(await response.text()) as Error & { digest?: string };
433
+ const error = new Error(await response.text()) as Error & { digest?: string }
436
434
  // The masked prod body hides the message; the digest rides a header so a
437
435
  // caught action error still exposes `error.digest` (Next parity).
438
- const digest = response.headers.get(ACTION_ERROR_DIGEST_HEADER);
439
- if (digest) error.digest = digest;
440
- throw tagActionError(error);
436
+ const digest = response.headers.get(ACTION_ERROR_DIGEST_HEADER)
437
+ if (digest) error.digest = digest
438
+ throw tagActionError(error)
441
439
  }
442
- throw tagActionError(new Error(UNEXPECTED_RESPONSE));
440
+ throw tagActionError(new Error(UNEXPECTED_RESPONSE))
443
441
  }
444
442
 
445
- const responseContentType = response.headers.get('content-type') ?? '';
443
+ const responseContentType = response.headers.get('content-type') ?? ''
446
444
  // A streamed action return (actions-streaming): the body IS a ReadableStream
447
445
  // the caller reads with getReader(). Return it live, unbuffered.
448
446
  if (responseContentType.includes(ACTION_STREAM_CONTENT_TYPE)) {
449
447
  if (hasActionRevalidated(response)) {
450
- const rearm = deferActionPrefetches();
451
- void refresh().finally(rearm);
448
+ const rearm = deferActionPrefetches()
449
+ void refresh().finally(rearm)
452
450
  }
453
- return response.body;
451
+ return response.body
454
452
  }
455
453
  if (responseContentType.includes(ACTION_FLIGHT_CONTENT_TYPE)) {
456
- const payload = await readActionFlightPayload(response);
457
- const revalidated = hasActionRevalidated(response);
458
- const discarded = clientNavigationGeneration !== navigationGenerationAtDispatch;
459
- const rearm = revalidated ? deferActionPrefetches() : undefined;
454
+ const payload = await readActionFlightPayload(response)
455
+ const revalidated = hasActionRevalidated(response)
456
+ const discarded = clientNavigationGeneration !== navigationGenerationAtDispatch
457
+ const rearm = revalidated ? deferActionPrefetches() : undefined
460
458
  try {
461
- const target = response.headers.get(ACTION_REDIRECT_HEADER);
462
- if (target && blockJavascriptUrl(target)) return undefined;
463
- const replace = response.headers.get(REDIRECT_TYPE_HEADER) === 'replace';
464
- const flightHtml = payloadHtml(payload);
459
+ const target = response.headers.get(ACTION_REDIRECT_HEADER)
460
+ if (target && blockJavascriptUrl(target)) return undefined
461
+ const replace = response.headers.get(REDIRECT_TYPE_HEADER) === 'replace'
462
+ const flightHtml = payloadHtml(payload)
465
463
  if (target && flightHtml) {
466
- await replaceDocument(flightHtml, target, replace, revalidated);
467
- return undefined;
464
+ await replaceDocument(flightHtml, target, replace, revalidated)
465
+ return undefined
468
466
  }
469
467
  // A completed action's value must reach client state. If navigation
470
468
  // superseded it, that value is discarded, so refresh the now-current route.
471
469
  if (revalidated && discarded) {
472
- await refresh();
470
+ await refresh()
473
471
  } else if (revalidated && flightHtml && payload.a === undefined) {
474
- await replaceDocument(flightHtml);
472
+ await replaceDocument(flightHtml)
475
473
  } else if (revalidated) {
476
474
  // Revalidation always re-renders the current route (Next applies the
477
475
  // revalidated flight even when the action returned a value). No
478
476
  // embedded HTML to swap in — refresh through the soft-nav pipeline so
479
477
  // every active parallel slot (intercepted modals included) refetches.
480
- await refresh();
478
+ await refresh()
481
479
  }
482
- return reviveActionReturn(payload.a, tempRefs);
480
+ return reviveActionReturn(payload.a, tempRefs)
483
481
  } finally {
484
- rearm?.();
482
+ rearm?.()
485
483
  }
486
484
  }
487
485
  if (!responseContentType.includes('application/json')) {
488
- throw tagActionError(new Error(UNEXPECTED_RESPONSE));
486
+ throw tagActionError(new Error(UNEXPECTED_RESPONSE))
489
487
  }
490
488
 
491
- const revalidated = hasActionRevalidated(response);
492
- const rearm = revalidated ? deferActionPrefetches() : undefined;
489
+ const revalidated = hasActionRevalidated(response)
490
+ const rearm = revalidated ? deferActionPrefetches() : undefined
493
491
  try {
494
- const payload = (await response.json()) as { data?: unknown; redirect?: string };
492
+ const payload = (await response.json()) as { data?: unknown; redirect?: string }
495
493
  if (typeof payload.redirect === 'string') {
496
- if (blockJavascriptUrl(payload.redirect)) return undefined;
497
- await navigate(payload.redirect, response.headers.get(REDIRECT_TYPE_HEADER) === 'replace');
498
- return undefined;
494
+ if (blockJavascriptUrl(payload.redirect)) return undefined
495
+ await navigate(payload.redirect, response.headers.get(REDIRECT_TYPE_HEADER) === 'replace')
496
+ return undefined
499
497
  }
500
498
  // Revive binary, temporary-reference, and client-component element markers.
501
- const data = reviveActionReturn(payload.data, tempRefs);
499
+ const data = reviveActionReturn(payload.data, tempRefs)
502
500
  // Revalidation always re-renders the current route, even when the action
503
501
  // returned a value (Next parity: revalidatePath/Tag in an action refreshes
504
502
  // every active parallel slot, intercepted modals included).
505
- if (revalidated) await refresh();
506
- return data;
503
+ if (revalidated) await refresh()
504
+ return data
507
505
  } finally {
508
- rearm?.();
506
+ rearm?.()
509
507
  }
510
508
  }
511
509
 
512
510
  function deferActionPrefetches(): () => void {
513
511
  // The eviction and the later re-arm both queue behind the router runtime's
514
512
  // single load promise, so they still land in this order.
515
- void evictClientRouterCache({ rearmVisiblePrefetches: false });
516
- return rearmVisiblePrefetches;
513
+ void evictClientRouterCache({ rearmVisiblePrefetches: false })
514
+ return rearmVisiblePrefetches
517
515
  }
518
516
 
519
517
  /**
@@ -521,60 +519,65 @@ function deferActionPrefetches(): () => void {
521
519
  * useActionState shim uses it to restore initial state in a preserved layout.
522
520
  */
523
521
  function markActionRedirected(): void {
524
- const holder = globalThis as { __pnextActionRedirects?: number };
525
- holder.__pnextActionRedirects = (holder.__pnextActionRedirects ?? 0) + 1;
522
+ const holder = globalThis as { __pnextActionRedirects?: number }
523
+ holder.__pnextActionRedirects = (holder.__pnextActionRedirects ?? 0) + 1
526
524
  }
527
525
 
528
526
  async function navigate(href: string, replace = false) {
529
- markActionRedirected();
530
- const url = new URL(href, location.href);
527
+ markActionRedirected()
528
+ const url = new URL(href, location.href)
531
529
  if (url.origin !== location.origin) {
532
- location.assign(url.href);
533
- return;
530
+ location.assign(url.href)
531
+ return
534
532
  }
535
533
  try {
536
- await softNavigate(url.href, replace ? { replace: true } : undefined);
534
+ await softNavigate(url.href, replace ? { replace: true } : undefined)
537
535
  } catch (error) {
538
536
  // A router failure must never strand an action redirect on the old page —
539
537
  // fall back to a full browser navigation (Next's MPA fallback shape).
540
- console.error(error);
541
- if (replace) location.replace(url.href);
542
- else location.assign(url.href);
538
+ console.error(error)
539
+ if (replace) location.replace(url.href)
540
+ else location.assign(url.href)
543
541
  }
544
542
  }
545
543
 
546
544
  async function refresh() {
547
545
  try {
548
- await softNavigate(location.href, { replace: true, scroll: false });
546
+ await softNavigate(location.href, { replace: true, scroll: false })
549
547
  } catch (error) {
550
548
  // A failed refresh must not reject the dispatch: the action's return value
551
549
  // still has to reach the caller (the refresh is a best-effort re-render).
552
- console.error(error);
550
+ console.error(error)
553
551
  }
554
552
  }
555
553
 
556
554
  async function swapDocument(response: Response) {
557
- const html = await response.text();
555
+ const html = await response.text()
558
556
  // Next renders an action's notFound() in place, so a robots meta the page
559
557
  // itself declared survives it. Our swap rewrites the document: carry the live
560
558
  // tag over, replacing the server's fallback noindex when one was injected.
561
- const robots = document.querySelector('meta[name="robots"]')?.outerHTML;
562
- const pattern = /<meta[^>]+name=["']robots["'][^>]*\/?>/i;
559
+ const robots = document.querySelector('meta[name="robots"]')?.outerHTML
560
+ const pattern = /<meta[^>]+name=["']robots["'][^>]*\/?>/i
563
561
  const withRobots = robots
564
562
  ? pattern.test(html)
565
563
  ? html.replace(pattern, robots)
566
564
  : html.replace('</head>', `${robots}</head>`)
567
- : html;
568
- await replaceDocument(withRobots);
565
+ : html
566
+ await replaceDocument(withRobots)
569
567
  }
570
568
 
571
569
  /**
572
570
  * `freshSegments`: the action revalidated, so this HTML is the freshly rendered destination - its
573
571
  * layouts carry the write and must replace the live ones instead of being grafted over.
574
572
  */
575
- async function replaceDocument(html: string, href?: string, replace = false, freshSegments = false) {
573
+ async function replaceDocument(
574
+ html: string,
575
+ href?: string,
576
+ replace = false,
577
+ freshSegments = false,
578
+ ) {
576
579
  if (href) {
577
- markActionRedirected();
580
+ markActionRedirected()
578
581
  // Route the single-pass redirect's destination HTML through the normal
579
582
  // soft-nav pipeline (as a "cached page" so it skips the fetch) instead of
580
583
  // `document.write`-ing a whole new document. `document.write` resets the
@@ -592,95 +595,95 @@ async function replaceDocument(html: string, href?: string, replace = false, fre
592
595
  replace,
593
596
  cachedPage: { html: actionRedirectPage(html), finalUrl: href, ok: true },
594
597
  ...(freshSegments ? { freshSegments: true } : {}),
595
- });
598
+ })
596
599
  } catch (error) {
597
600
  // Single-pass redirect swap failed in the router: land on the target
598
601
  // with a full navigation rather than stranding the user (and the test's
599
602
  // waitForElementByCss) on the origin page.
600
- console.error(error);
601
- if (replace) location.replace(new URL(href, location.href).href);
602
- else location.assign(new URL(href, location.href).href);
603
+ console.error(error)
604
+ if (replace) location.replace(new URL(href, location.href).href)
605
+ else location.assign(new URL(href, location.href).href)
603
606
  }
604
- return;
607
+ return
605
608
  }
606
- document.open();
607
- document.write(html);
608
- document.close();
609
+ document.open()
610
+ document.write(html)
611
+ document.close()
609
612
  }
610
613
 
611
614
  function actionRedirectPage(html: string): string {
612
615
  // A server-only destination does not need its route entry. Avoid importing
613
616
  // it so the inline action flight remains the redirect's only request.
614
- if (/<pnext-client(?:\s|>)/.test(html) || html.includes('<!--pnext-client:')) return html;
617
+ if (/<pnext-client(?:\s|>)/.test(html) || html.includes('<!--pnext-client:')) return html
615
618
  const entryScript =
616
- /\s*<script\b[^>]*\btype=["']module["'][^>]*\bsrc=["'][^"']*-pnext-client\.js["'][^>]*><\/script>/gi;
617
- return html.replace(entryScript, '');
619
+ /\s*<script\b[^>]*\btype=["']module["'][^>]*\bsrc=["'][^"']*-pnext-client\.js["'][^>]*><\/script>/gi
620
+ return html.replace(entryScript, '')
618
621
  }
619
622
 
620
623
  async function readActionFlightPayload(response: Response): Promise<ActionFlightPayload> {
621
624
  try {
622
- const parsed = JSON.parse(await response.text()) as unknown;
623
- return isActionFlightPayload(parsed) ? parsed : {};
625
+ const parsed = JSON.parse(await response.text()) as unknown
626
+ return isActionFlightPayload(parsed) ? parsed : {}
624
627
  } catch {
625
- throw tagActionError(new Error(UNEXPECTED_RESPONSE));
628
+ throw tagActionError(new Error(UNEXPECTED_RESPONSE))
626
629
  }
627
630
  }
628
631
 
629
632
  function isActionFlightPayload(value: unknown): value is ActionFlightPayload {
630
- return value !== null && typeof value === 'object';
633
+ return value !== null && typeof value === 'object'
631
634
  }
632
635
 
633
636
  function payloadHtml(payload: ActionFlightPayload): string | undefined {
634
- const flight = payload.f;
635
- if (!flight || typeof flight !== 'object') return undefined;
636
- return flight.kind === 'pnext-html' && typeof flight.html === 'string' ? flight.html : undefined;
637
+ const flight = payload.f
638
+ if (!flight || typeof flight !== 'object') return undefined
639
+ return flight.kind === 'pnext-html' && typeof flight.html === 'string' ? flight.html : undefined
637
640
  }
638
641
 
639
642
  function hasActionRevalidated(response: Response): boolean {
640
643
  return (
641
644
  response.headers.has(ACTION_REFRESH_HEADER) ||
642
645
  response.headers.has(NEXT_ACTION_REVALIDATED_HEADER)
643
- );
646
+ )
644
647
  }
645
648
 
646
649
  // ---------------------------------------------------------------------------
647
650
  // error boundary overlay body (route error.js support for action failures)
648
651
  // ---------------------------------------------------------------------------
649
652
 
650
- type ErrorComponentType = ComponentType<{ error: Error; reset: () => void }>;
653
+ type ErrorComponentType = ComponentType<{ error: Error; reset: () => void }>
651
654
 
652
655
  interface HiddenElement extends HTMLElement {
653
- __pnextPrevDisplay?: string;
656
+ __pnextPrevDisplay?: string
654
657
  }
655
658
 
656
- let overlayRoot: HTMLElement | null = null;
659
+ let overlayRoot: HTMLElement | null = null
657
660
 
658
661
  /**
659
662
  * Hide the page and render the route's error component over it. Callers
660
- * serialize their calls (action-client chains them), so the `overlayRoot` guard
663
+ * serialize their calls (client.ts chains them), so the `overlayRoot` guard
661
664
  * still holds across the dynamic import that reaches this module.
662
665
  */
663
666
  export function showActionErrorOverlay(Component: ErrorComponentType, reason: unknown) {
664
- if (overlayRoot) return;
665
- const error = reason instanceof Error ? reason : new Error(String(reason));
666
- const hidden: HiddenElement[] = [];
667
- overlayRoot = document.createElement('div');
667
+ if (overlayRoot) return
668
+ const error = reason instanceof Error ? reason : new Error(String(reason))
669
+ const hidden: HiddenElement[] = []
670
+ overlayRoot = document.createElement('div')
668
671
  for (const child of [...document.body.children]) {
669
- if (!(child instanceof HTMLElement)) continue;
670
- if (child.tagName === 'SCRIPT') continue;
671
- const element = child as HiddenElement;
672
- element.__pnextPrevDisplay = element.style.display;
673
- element.style.display = 'none';
674
- hidden.push(element);
672
+ if (!(child instanceof HTMLElement)) continue
673
+ if (child.tagName === 'SCRIPT') continue
674
+ const element = child as HiddenElement
675
+ element.__pnextPrevDisplay = element.style.display
676
+ element.style.display = 'none'
677
+ hidden.push(element)
675
678
  }
676
- document.body.appendChild(overlayRoot);
679
+ document.body.appendChild(overlayRoot)
677
680
  const reset = () => {
678
- if (!overlayRoot) return;
679
- render(null, overlayRoot);
680
- overlayRoot.remove();
681
- overlayRoot = null;
682
- for (const element of hidden) element.style.display = element.__pnextPrevDisplay ?? '';
683
- void refresh();
684
- };
685
- render(h(Component, { error, reset }), overlayRoot);
681
+ if (!overlayRoot) return
682
+ render(null, overlayRoot)
683
+ overlayRoot.remove()
684
+ overlayRoot = null
685
+ for (const element of hidden) element.style.display = element.__pnextPrevDisplay ?? ''
686
+ void refresh()
687
+ }
688
+ render(h(Component, { error, reset }), overlayRoot)
686
689
  }