@wular/pnext 0.0.3 → 0.0.6

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 (392) hide show
  1. package/README.md +11 -11
  2. package/bin/pnext +1 -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 +1 -1
  8. package/reference/config.md +2 -2
  9. package/reference/css.md +13 -9
  10. package/reference/dev.md +1 -1
  11. package/reference/metadata.md +7 -7
  12. package/reference/navigation.md +35 -28
  13. package/reference/performance.md +70 -70
  14. package/reference/rendering.md +17 -17
  15. package/reference/routing.md +17 -17
  16. package/reference/typegen.md +12 -8
  17. package/src/api/cache.ts +36 -37
  18. package/src/api/client-cache.ts +2 -2
  19. package/src/api/client-navigation.ts +113 -109
  20. package/src/api/dynamic.tsx +58 -55
  21. package/src/api/link.tsx +49 -52
  22. package/src/api/navigation.ts +59 -58
  23. package/src/api/server.ts +152 -144
  24. package/src/api/suspense.ts +4 -4
  25. package/src/cli/adapters/vercel-warm.ts +126 -121
  26. package/src/cli/adapters/vercel.ts +437 -443
  27. package/src/cli/analyze.ts +333 -144
  28. package/src/cli/{named-bin.ts → boot/named-bin.ts} +37 -37
  29. package/src/cli/{boot-trace.ts → boot/trace.ts} +10 -10
  30. package/src/cli/build.ts +976 -978
  31. package/src/cli/create.ts +71 -63
  32. package/src/cli/dev.ts +116 -116
  33. package/src/cli/index.ts +88 -85
  34. package/src/cli/migrate/package-json.ts +73 -71
  35. package/src/cli/migrate/report.ts +32 -33
  36. package/src/cli/migrate/{index.ts → run.ts} +48 -49
  37. package/src/cli/migrate/scan.ts +46 -46
  38. package/src/cli/migrate/spinner.ts +9 -9
  39. package/src/cli/migrate/tsconfig.ts +35 -35
  40. package/src/cli/{server-entry.ts → serve/entry.ts} +57 -57
  41. package/src/cli/{request-pipeline.ts → serve/pipeline.ts} +386 -394
  42. package/src/cli/{serve-ui.ts → serve/ui.ts} +47 -47
  43. package/src/cli/start.ts +65 -66
  44. package/src/{typegen.ts → cli/typegen.ts} +59 -59
  45. package/src/client/build.ts +794 -768
  46. package/src/client/chunk-fold.ts +245 -240
  47. package/src/client/{paths.ts → chunk-name.ts} +6 -6
  48. package/src/client/entry.ts +162 -147
  49. package/src/client/prebuilt.ts +231 -223
  50. package/src/client/profile.ts +29 -29
  51. package/src/client/react-compiler.ts +20 -15
  52. package/src/client/{compat-surface.ts → react-tier.ts} +64 -64
  53. package/src/client/reference-stub.ts +51 -51
  54. package/src/client/reference.ts +19 -19
  55. package/src/{api → client}/router/events.ts +17 -17
  56. package/src/{api → client}/router/history.ts +16 -16
  57. package/src/{api → client}/router/hub.ts +52 -53
  58. package/src/{api/router.ts → client/router/index.ts} +61 -60
  59. package/src/{api → client}/router/policies.ts +24 -24
  60. package/src/{api → client}/router/runtime.ts +1988 -1961
  61. package/src/{api → client}/router/types.ts +93 -98
  62. package/src/compat/actions/client-plugin.ts +42 -43
  63. package/src/compat/actions/client-stub.ts +14 -14
  64. package/src/compat/actions/{action-client.ts → client.ts} +194 -193
  65. package/src/compat/actions/config.ts +63 -64
  66. package/src/compat/actions/detect.ts +68 -68
  67. package/src/compat/actions/discovery.ts +105 -105
  68. package/src/compat/actions/{action-dispatch.ts → dispatch.ts} +277 -274
  69. package/src/compat/actions/early-submit.ts +1 -1
  70. package/src/compat/actions/endpoint.ts +198 -198
  71. package/src/compat/actions/extensions.ts +811 -0
  72. package/src/compat/actions/flight.ts +23 -23
  73. package/src/compat/actions/form-state.ts +34 -34
  74. package/src/compat/actions/hoist.ts +382 -236
  75. package/src/compat/actions/ids.ts +7 -12
  76. package/src/compat/actions/index.ts +8 -8
  77. package/src/compat/actions/instances.ts +46 -46
  78. package/src/compat/actions/origin.ts +47 -48
  79. package/src/compat/actions/protocol.ts +22 -22
  80. package/src/compat/actions/registry.ts +19 -19
  81. package/src/compat/{misc/action-return.ts → actions/return.ts} +60 -57
  82. package/src/compat/actions/rewrite.ts +125 -125
  83. package/src/compat/actions/{action-router.ts → router.ts} +10 -10
  84. package/src/compat/actions/serve.ts +132 -136
  85. package/src/compat/actions/server-tag.ts +4 -4
  86. package/src/compat/actions/{action-shared.ts → shared.ts} +34 -34
  87. package/src/compat/actions/unrecognized-error.ts +4 -4
  88. package/src/compat/{index.ts → aliases.ts} +112 -109
  89. package/src/compat/bundler/bun-externals.ts +18 -18
  90. package/src/compat/bundler/cjs-exports.ts +271 -223
  91. package/src/compat/bundler/config.ts +116 -111
  92. package/src/compat/bundler/externals.ts +12 -12
  93. package/src/compat/bundler/import-meta-url.ts +19 -19
  94. package/src/compat/bundler/modularize-imports.ts +36 -33
  95. package/src/compat/bundler/new-url-asset.ts +22 -24
  96. package/src/compat/bundler/optimize-package-imports.ts +111 -107
  97. package/src/compat/bundler/polyfill.ts +28 -28
  98. package/src/compat/bundler/react-compiler.ts +35 -29
  99. package/src/compat/bundler/react-profiler.tsx +11 -11
  100. package/src/compat/bundler/relay-transform.ts +48 -47
  101. package/src/compat/bundler/require-context.ts +119 -113
  102. package/src/compat/bundler/resolve-extensions.ts +19 -19
  103. package/src/compat/bundler/source-cache.ts +25 -25
  104. package/src/compat/bundler/static-imports.ts +7 -7
  105. package/src/compat/bundler/symlink-imports.ts +46 -46
  106. package/src/compat/bundler/tsconfig-paths.ts +13 -15
  107. package/src/compat/bundler/wasm.ts +58 -60
  108. package/src/compat/bundler/webpack-loaders.ts +254 -241
  109. package/src/compat/bundler/worker.ts +101 -104
  110. package/src/compat/cache/build-flags.ts +29 -29
  111. package/src/compat/cache/build-prerender-errors.ts +40 -44
  112. package/src/compat/cache/custom-handler.ts +60 -53
  113. package/src/compat/cache/fetch-patch.ts +240 -240
  114. package/src/compat/cache/handler.ts +27 -31
  115. package/src/compat/cache/modern-handler.ts +148 -126
  116. package/src/compat/cache/resume-data-cache.ts +47 -45
  117. package/src/compat/cache/revalidate.ts +233 -232
  118. package/src/compat/cache/runtime-error.ts +35 -35
  119. package/src/compat/cache/use-cache-transform.ts +442 -417
  120. package/src/compat/cache/use-cache.ts +650 -614
  121. package/src/compat/cache-control.ts +140 -142
  122. package/src/compat/client/base-path.ts +21 -20
  123. package/src/compat/client/css-order.ts +18 -18
  124. package/src/compat/client/errors/bare-boundary.ts +11 -11
  125. package/src/compat/client/errors/control-flow.ts +23 -23
  126. package/src/compat/client/errors/error-boundary.ts +61 -61
  127. package/src/compat/client/errors/global-error.ts +101 -91
  128. package/src/compat/client/errors/install.ts +71 -72
  129. package/src/compat/client/errors/lazy.ts +23 -23
  130. package/src/compat/client/errors/primitive-throw.ts +47 -45
  131. package/src/compat/client/errors/soft-refresh.ts +4 -4
  132. package/src/compat/client/link-status.ts +33 -33
  133. package/src/compat/client/{nav-compat-runtime.ts → nav-runtime.ts} +20 -20
  134. package/src/compat/client/{nav-compat.ts → nav.ts} +12 -13
  135. package/src/compat/client/navigation-scroll.ts +63 -63
  136. package/src/compat/client/optimistic-routing.ts +93 -88
  137. package/src/compat/client/prefetch-cache.ts +23 -24
  138. package/src/compat/client/route-announcer.ts +35 -35
  139. package/src/compat/client/segment-cache-policy.ts +20 -20
  140. package/src/compat/client/segment-cache.ts +309 -315
  141. package/src/compat/client/segment-prefetch.ts +127 -132
  142. package/src/compat/client/trailing-slash.ts +5 -4
  143. package/src/compat/css/chunking.ts +113 -116
  144. package/src/compat/css/inline-css.ts +21 -21
  145. package/src/compat/css/lightningcss.ts +37 -38
  146. package/src/compat/css/modules.ts +161 -175
  147. package/src/compat/css/nonce.ts +7 -7
  148. package/src/compat/css/sass-plugin.ts +18 -21
  149. package/src/compat/css/sass.ts +150 -152
  150. package/src/compat/css/styled-jsx-runtime.ts +27 -27
  151. package/src/compat/css/styled-jsx.ts +21 -21
  152. package/src/compat/edge-runtime.ts +27 -27
  153. package/src/compat/{adapter → export}/build-complete.ts +72 -75
  154. package/src/compat/export/client.ts +29 -31
  155. package/src/compat/export/{index.ts → emit.ts} +111 -110
  156. package/src/compat/export/standalone.ts +62 -54
  157. package/src/compat/image-optimizer/cache.ts +51 -49
  158. package/src/compat/image-optimizer/detect.ts +52 -52
  159. package/src/compat/image-optimizer/{index.ts → optimize.ts} +189 -194
  160. package/src/compat/image-optimizer/source.ts +77 -80
  161. package/src/compat/lifecycle/after-scope.ts +26 -26
  162. package/src/compat/lifecycle/after.ts +48 -45
  163. package/src/compat/lifecycle/error-funnel.ts +98 -102
  164. package/src/compat/lifecycle/error-serialize.ts +30 -26
  165. package/src/compat/lifecycle/error-ui.ts +67 -32
  166. package/src/compat/lifecycle/instrumentation-client.ts +36 -38
  167. package/src/compat/lifecycle/instrumentation.ts +85 -85
  168. package/src/compat/lifecycle/node-console.ts +11 -11
  169. package/src/compat/lifecycle/testmode.ts +160 -132
  170. package/src/compat/mdx/compile.ts +60 -57
  171. package/src/compat/mdx/plugin.ts +11 -11
  172. package/src/compat/mdx/{next-mdx-stub.ts → stub.ts} +5 -5
  173. package/src/compat/{metadata-route-artifacts.ts → metadata-artifacts.ts} +195 -191
  174. package/src/compat/metadata.ts +75 -81
  175. package/src/compat/next/cache.ts +68 -69
  176. package/src/compat/next/canonical-url.ts +9 -9
  177. package/src/compat/next/client-cache.ts +19 -19
  178. package/src/compat/next/client-navigation.ts +112 -116
  179. package/src/compat/next/client-only.ts +1 -1
  180. package/src/compat/next/client-script.tsx +99 -93
  181. package/src/compat/next/client-server.ts +10 -10
  182. package/src/compat/next/config-loader.ts +176 -173
  183. package/src/compat/next/config.ts +7 -7
  184. package/src/compat/next/constants.cjs +6 -6
  185. package/src/compat/next/constants.ts +6 -6
  186. package/src/compat/next/custom-server.ts +26 -24
  187. package/src/compat/next/dist/client/components/app-router-headers.ts +21 -21
  188. package/src/compat/next/dist/server/app-render/work-unit-async-storage.external.cjs +3 -4
  189. package/src/compat/next/dist/server/web/spec-extension/revalidate.ts +1 -1
  190. package/src/compat/next/dist/server/web/spec-extension/unstable-cache.ts +1 -1
  191. package/src/compat/next/dist/server/web/spec-extension/unstable-no-store.ts +1 -1
  192. package/src/compat/next/dynamic.tsx +21 -18
  193. package/src/compat/next/error.tsx +52 -52
  194. package/src/compat/next/font/cache.ts +74 -74
  195. package/src/compat/next/font/google.ts +2 -2
  196. package/src/compat/next/font/index.ts +1 -1
  197. package/src/compat/next/font/local.ts +3 -3
  198. package/src/compat/next/font/runtime-client.ts +17 -15
  199. package/src/compat/next/font/runtime.ts +443 -408
  200. package/src/compat/next/font/shared.ts +120 -108
  201. package/src/compat/next/form.tsx +63 -63
  202. package/src/compat/next/head.tsx +2 -2
  203. package/src/compat/next/headers.ts +103 -95
  204. package/src/compat/next/image/client.tsx +220 -0
  205. package/src/compat/next/image/config.ts +56 -58
  206. package/src/compat/next/image/optimizer.ts +40 -36
  207. package/src/compat/next/image/patterns.ts +37 -40
  208. package/src/compat/next/{image-props.ts → image/props.ts} +208 -202
  209. package/src/compat/next/image/shared.ts +65 -57
  210. package/src/compat/next/image/static-metadata.ts +98 -107
  211. package/src/compat/next/image/validate.ts +79 -88
  212. package/src/compat/next/image.tsx +19 -23
  213. package/src/compat/next/index.ts +1 -1
  214. package/src/compat/next/legacy-image.tsx +59 -60
  215. package/src/compat/next/{link-validation-transform.ts → link-transform.ts} +95 -96
  216. package/src/compat/next/link.tsx +158 -158
  217. package/src/compat/next/navigation.cjs +12 -3
  218. package/src/compat/next/navigation.ts +48 -50
  219. package/src/compat/next/offline.ts +27 -27
  220. package/src/compat/next/og.ts +121 -124
  221. package/src/compat/next/preferred-region.ts +13 -14
  222. package/src/compat/next/redirects.ts +58 -56
  223. package/src/compat/next/resource-hints.ts +73 -76
  224. package/src/compat/next/rewrites.ts +130 -133
  225. package/src/compat/next/root-params.ts +45 -45
  226. package/src/compat/next/{optimistic-route-state.ts → route-state.ts} +52 -52
  227. package/src/compat/next/router.cjs +4 -2
  228. package/src/compat/next/router.ts +58 -61
  229. package/src/compat/next/script.tsx +108 -108
  230. package/src/compat/next/server-only.ts +1 -1
  231. package/src/compat/next/server.ts +19 -19
  232. package/src/compat/next/svgr.ts +18 -17
  233. package/src/compat/next/telemetry.ts +24 -24
  234. package/src/compat/next/{image-usage.ts → usage.ts} +70 -39
  235. package/src/compat/next/user-agent.ts +53 -49
  236. package/src/compat/next/web-vitals.ts +22 -24
  237. package/src/compat/otel/api.ts +41 -41
  238. package/src/compat/otel/client-trace-metadata.ts +25 -27
  239. package/src/compat/otel/fetch-span.ts +29 -29
  240. package/src/compat/otel/tracer.ts +331 -331
  241. package/src/compat/pages/api.ts +456 -0
  242. package/src/compat/pages/client-plugin.ts +36 -36
  243. package/src/compat/pages/router-state.ts +34 -34
  244. package/src/compat/pages/{index.ts → router.ts} +130 -135
  245. package/src/compat/ppr/io.ts +12 -12
  246. package/src/compat/ppr/missing-root-params.ts +34 -38
  247. package/src/compat/ppr/root-params-scan.ts +66 -66
  248. package/src/compat/ppr/root-params-transform.ts +24 -26
  249. package/src/compat/ppr/root-params.ts +30 -30
  250. package/src/compat/ppr/segment-config-incompat.ts +6 -7
  251. package/src/compat/protocol.ts +71 -70
  252. package/src/compat/react/action-state.ts +47 -48
  253. package/src/compat/react/client-lite.ts +15 -15
  254. package/src/compat/react/client.ts +4 -4
  255. package/src/compat/react/compiler-runtime.ts +11 -11
  256. package/src/compat/react/dom-client.ts +44 -44
  257. package/src/compat/react/dom-react-server.ts +10 -16
  258. package/src/compat/react/dom-server.ts +10 -10
  259. package/src/compat/react/dom.ts +52 -52
  260. package/src/compat/react/hooks-extra.ts +34 -35
  261. package/src/compat/react/parity.ts +64 -61
  262. package/src/compat/react/preact.ts +81 -82
  263. package/src/compat/react/react-server.ts +28 -28
  264. package/src/compat/react/router-shim.ts +1 -1
  265. package/src/compat/react/server-component-use.ts +8 -8
  266. package/src/compat/react/server-inserted-html.ts +30 -31
  267. package/src/compat/react/server.ts +53 -55
  268. package/src/compat/react/use.ts +32 -32
  269. package/src/compat/react/view-transition.ts +20 -20
  270. package/src/compat/register/actions.ts +35 -824
  271. package/src/compat/register/boot.ts +41 -41
  272. package/src/compat/register/build-tier.ts +5 -5
  273. package/src/compat/register/build.ts +74 -70
  274. package/src/compat/register/bundler.ts +161 -156
  275. package/src/compat/register/cache.ts +20 -20
  276. package/src/compat/register/client-errors.ts +3 -3
  277. package/src/compat/register/config.ts +6 -6
  278. package/src/compat/register/css-extras.ts +30 -34
  279. package/src/compat/register/edge-runtime.ts +3 -3
  280. package/src/compat/register/errors.ts +10 -12
  281. package/src/compat/register/export.ts +16 -16
  282. package/src/compat/register/font.ts +11 -11
  283. package/src/compat/register/hooks.ts +2 -2
  284. package/src/compat/register/image.ts +40 -40
  285. package/src/compat/register/index.ts +59 -62
  286. package/src/compat/register/instrumentation-client.ts +10 -10
  287. package/src/compat/register/lifecycle.ts +25 -28
  288. package/src/compat/register/mdx.ts +10 -10
  289. package/src/compat/register/middleware.ts +226 -16
  290. package/src/compat/register/otel.ts +80 -88
  291. package/src/compat/register/pages-api.ts +10 -463
  292. package/src/compat/register/ppr.ts +16 -16
  293. package/src/compat/register/protocol.ts +17 -18
  294. package/src/compat/register/proxy.ts +49 -51
  295. package/src/compat/register/render.ts +79 -76
  296. package/src/compat/register/routing.ts +162 -159
  297. package/src/compat/register/segment.ts +24 -1887
  298. package/src/compat/register/static-image.ts +3 -3
  299. package/src/compat/register/{misc.ts → taint.ts} +9 -9
  300. package/src/compat/register/typed-routes.ts +14 -14
  301. package/src/compat/register/{usecache.ts → use-cache.ts} +39 -39
  302. package/src/compat/register/validation.ts +18 -18
  303. package/src/compat/segment/loading-boundary.ts +43 -45
  304. package/src/compat/segment/page-slot.ts +69 -69
  305. package/src/compat/segment/serve.ts +1884 -0
  306. package/src/compat/segment/tree.ts +113 -112
  307. package/src/compat/segment/vary-key.ts +38 -38
  308. package/src/compat/segment/vary-params.ts +138 -142
  309. package/src/compat/static-params.ts +14 -12
  310. package/src/compat/tsconfig-defaults.ts +87 -91
  311. package/src/compat/typecheck/{index.ts → check.ts} +234 -212
  312. package/src/compat/typecheck/worker.ts +15 -12
  313. package/src/compat/typed-routes/{index.ts → generate.ts} +36 -36
  314. package/src/compat/typed-routes/manifest.ts +174 -170
  315. package/src/compat/typed-routes/typegen.ts +127 -110
  316. package/src/compat/validation/errors.ts +16 -19
  317. package/src/compat/validation/prerender-diagnostics.ts +521 -504
  318. package/src/compat/validation/{index.ts → validate.ts} +647 -648
  319. package/src/compat-bootstrap.ts +16 -16
  320. package/src/config.ts +69 -69
  321. package/src/css/build.ts +230 -227
  322. package/src/css/postcss.ts +79 -80
  323. package/src/css/worker.ts +14 -15
  324. package/src/dev/client-actions.ts +10 -10
  325. package/src/dev/client-chunk-store.ts +27 -27
  326. package/src/dev/{client-key-cache.ts → restart/client-key.ts} +76 -76
  327. package/src/dev/{restart-cache.ts → restart/enabled.ts} +1 -1
  328. package/src/dev/{global-css-cache.ts → restart/global-css.ts} +91 -83
  329. package/src/dev/{node-module-bundle-cache.ts → restart/node-modules.ts} +24 -24
  330. package/src/dev/{route-bundle-key-cache.ts → restart/route-bundle-key.ts} +53 -53
  331. package/src/dev/{route-facts-cache.ts → restart/route-facts.ts} +82 -82
  332. package/src/dev/server.ts +804 -820
  333. package/src/env.ts +46 -43
  334. package/src/extensions.ts +491 -478
  335. package/src/index.ts +8 -8
  336. package/src/internal.ts +20 -23
  337. package/src/{islands → render}/boundary-error.ts +3 -3
  338. package/src/render/hooks.ts +71 -71
  339. package/src/render/island-context.ts +14 -14
  340. package/src/render/metadata.ts +310 -310
  341. package/src/{ppr-postpone.ts → render/postpone.ts} +5 -5
  342. package/src/{ppr.ts → render/ppr.ts} +244 -245
  343. package/src/render/renderer.ts +2076 -2082
  344. package/src/render/resource-hints.ts +16 -17
  345. package/src/render/slots.tsx +224 -235
  346. package/src/{islands → render}/static-children.ts +9 -12
  347. package/src/{islands → render}/static-slots.ts +37 -37
  348. package/src/{cache/context.ts → request/cache.ts} +20 -20
  349. package/src/request/context.ts +107 -107
  350. package/src/{dynamic/source.ts → resolve/dynamic.ts} +152 -143
  351. package/src/resolve/engine.ts +90 -77
  352. package/src/resolve/imports.ts +475 -463
  353. package/src/resolve/scan-facts.ts +442 -186
  354. package/src/resolve/source-text.ts +37 -37
  355. package/src/{dynamic → resolve}/tree-shake.ts +132 -128
  356. package/src/routing/forwarded.ts +19 -19
  357. package/src/routing/handler.ts +84 -91
  358. package/src/routing/href.ts +69 -70
  359. package/src/routing/{metadata.ts → metadata-files.ts} +403 -401
  360. package/src/{proxy.ts → routing/proxy.ts} +306 -312
  361. package/src/routing/{request-runtime.ts → request-environment.ts} +10 -10
  362. package/src/routing/routes.ts +833 -848
  363. package/src/routing/slots.ts +164 -160
  364. package/src/runtime/loader.ts +952 -0
  365. package/src/{dev → runtime}/module-cache.ts +309 -287
  366. package/src/{dev → runtime}/module-generations.ts +9 -9
  367. package/src/{dev → runtime}/module-transform.ts +81 -72
  368. package/src/{dev/imports.ts → runtime/modules.ts} +934 -847
  369. package/src/runtime/{server.ts → vendor-build.ts} +848 -1696
  370. package/src/runtime/vendor.ts +425 -404
  371. package/src/styles.d.ts +9 -0
  372. package/src/types.ts +320 -335
  373. package/src/utils/ansi.ts +5 -5
  374. package/src/utils/{source.ts → code.ts} +15 -12
  375. package/src/utils/content-type.ts +3 -3
  376. package/src/utils/decode.ts +2 -2
  377. package/src/utils/dev-profile.ts +13 -13
  378. package/src/utils/error-log.ts +6 -6
  379. package/src/utils/esbuild.ts +18 -18
  380. package/src/utils/fs-cache.ts +13 -13
  381. package/src/utils/fs.ts +57 -49
  382. package/src/utils/html.ts +20 -24
  383. package/src/utils/native-require.ts +8 -8
  384. package/src/utils/serialize.ts +139 -146
  385. package/src/utils/verbose.ts +18 -18
  386. package/src/cli/analyze-print.ts +0 -181
  387. package/src/compat/middleware/manifest.ts +0 -210
  388. package/src/compat/next/image-client.tsx +0 -215
  389. package/src/compat/next/link-usage.ts +0 -29
  390. package/src/css/index.ts +0 -2
  391. package/src/render/index.ts +0 -1
  392. package/src/style-modules.d.ts +0 -9
@@ -1,6 +1,6 @@
1
- import { runAction, type RunActionOptions } from './endpoint';
2
- import { ACTION_FLIGHT_CONTENT_TYPE, createActionFlightResponse } from './flight';
3
- import { INVALID_ORIGIN_MESSAGE, isActionOriginAllowed } from './origin';
1
+ import { runAction, type RunActionOptions } from './endpoint'
2
+ import { ACTION_FLIGHT_CONTENT_TYPE, createActionFlightResponse } from './flight'
3
+ import { INVALID_ORIGIN_MESSAGE, isActionOriginAllowed } from './origin'
4
4
  import {
5
5
  ACTION_ID_FIELD,
6
6
  SUBMIT_ACTION_ID_FIELD,
@@ -14,9 +14,9 @@ import {
14
14
  MASKED_ACTION_ERROR,
15
15
  REDIRECT_TYPE_HEADER,
16
16
  type ActionSuccessBody,
17
- } from './protocol';
17
+ } from './protocol'
18
18
 
19
- export { ACTION_REFRESH_HEADER, ACTION_ID_FIELD };
19
+ export { ACTION_REFRESH_HEADER, ACTION_ID_FIELD }
20
20
 
21
21
  /**
22
22
  * Server-action dispatch for the pnext servers. Actions POST to the page's own
@@ -34,7 +34,7 @@ export { ACTION_REFRESH_HEADER, ACTION_ID_FIELD };
34
34
 
35
35
  /** True when a request is a JS-client action RPC (id in header). */
36
36
  export function isActionRequest(request: Request): boolean {
37
- return request.method.toUpperCase() === 'POST' && request.headers.has(ACTION_ID_HEADER);
37
+ return request.method.toUpperCase() === 'POST' && request.headers.has(ACTION_ID_HEADER)
38
38
  }
39
39
 
40
40
  /**
@@ -43,28 +43,27 @@ export function isActionRequest(request: Request): boolean {
43
43
  * stays consumable. Non-form POSTs and forms without the field return false.
44
44
  */
45
45
  export async function isProgressiveActionRequest(request: Request): Promise<boolean> {
46
- if (request.method.toUpperCase() !== 'POST') return false;
47
- if (request.headers.has(ACTION_ID_HEADER)) return false;
48
- const contentType = request.headers.get('content-type') ?? '';
46
+ if (request.method.toUpperCase() !== 'POST') return false
47
+ if (request.headers.has(ACTION_ID_HEADER)) return false
48
+ const contentType = request.headers.get('content-type') ?? ''
49
49
  const isForm =
50
- contentType.includes('multipart/form-data') || contentType.includes('form-urlencoded');
51
- if (!isForm) return false;
50
+ contentType.includes('multipart/form-data') || contentType.includes('form-urlencoded')
51
+ if (!isForm) return false
52
52
  try {
53
- const form = await request.clone().formData();
53
+ const form = await request.clone().formData()
54
54
  // A form-level action (ACTION_ID_FIELD) OR a bare submitter override
55
55
  // (SUBMIT_ACTION_ID_FIELD, e.g. <form><button formAction={fn}> with no form
56
56
  // action) both count as a progressive action submission.
57
- const id =
58
- lastFieldValue(form, SUBMIT_ACTION_ID_FIELD) ?? lastFieldValue(form, ACTION_ID_FIELD);
59
- return typeof id === 'string' && id !== '';
57
+ const id = lastFieldValue(form, SUBMIT_ACTION_ID_FIELD) ?? lastFieldValue(form, ACTION_ID_FIELD)
58
+ return typeof id === 'string' && id !== ''
60
59
  } catch {
61
- return false;
60
+ return false
62
61
  }
63
62
  }
64
63
 
65
64
  export interface ServeActionOptions extends RunActionOptions {
66
65
  /** Render the app's 404 page for a notFound() result (progressive + RPC). */
67
- renderNotFound?: (request: Request) => Promise<Response>;
66
+ renderNotFound?: (request: Request) => Promise<Response>
68
67
  /**
69
68
  * Progressive useActionState submissions: re-render the posted page with the
70
69
  * action's result as the form's state (published via the consumed-once
@@ -74,22 +73,22 @@ export interface ServeActionOptions extends RunActionOptions {
74
73
  request: Request,
75
74
  state: unknown,
76
75
  actionId: string,
77
- ) => Promise<Response | null>;
76
+ ) => Promise<Response | null>
78
77
  /**
79
78
  * Single-pass redirects: render the redirect target's page for an RPC redirect so the 303 response
80
79
  * carries the destination HTML and the client swaps it in without a follow-up GET. The request passed
81
80
  * already carries the action's cookie mutations. Null falls back to the JSON redirect envelope.
82
81
  */
83
- renderRedirectTarget?: (request: Request, target: URL) => Promise<Response | null>;
82
+ renderRedirectTarget?: (request: Request, target: URL) => Promise<Response | null>
84
83
  /** Render a page payload for a JS action Flight response. */
85
- renderActionFlight?: (request: Request, target: URL) => Promise<Response | null>;
84
+ renderActionFlight?: (request: Request, target: URL) => Promise<Response | null>
86
85
  /**
87
86
  * Next "forwarded action" discrimination: true when the POSTed route's module graph does NOT contain
88
87
  * the action (the client dispatched it after navigating away from the page that owns it). Next
89
88
  * forwards such requests to the owning worker and relays the inner response's HEADERS but not its
90
89
  * status, so the browser observes 200 + `x-action-redirect` instead of the direct-dispatch 303.
91
90
  */
92
- isForwardedAction?: (id: string) => boolean;
91
+ isForwardedAction?: (id: string) => boolean
93
92
  }
94
93
 
95
94
  /** Serve a server-action request (either kind). */
@@ -97,7 +96,7 @@ export async function serveAction(
97
96
  request: Request,
98
97
  options: ServeActionOptions,
99
98
  ): Promise<Response> {
100
- const progressive = !request.headers.has(ACTION_ID_HEADER);
99
+ const progressive = !request.headers.has(ACTION_ID_HEADER)
101
100
 
102
101
  // CSRF origin check runs before the action executes: a mismatched origin must
103
102
  // never run the action. JS clients get the error as a text/plain body (thrown
@@ -107,16 +106,16 @@ export async function serveAction(
107
106
  return new Response('Internal Server Error', {
108
107
  status: 500,
109
108
  headers: { 'content-type': 'text/plain; charset=utf-8' },
110
- });
109
+ })
111
110
  }
112
111
  return new Response(options.dev ? INVALID_ORIGIN_MESSAGE : MASKED_ACTION_ERROR, {
113
112
  status: 500,
114
113
  headers: { 'content-type': 'text/plain; charset=utf-8' },
115
- });
114
+ })
116
115
  }
117
116
 
118
- const promoted = progressive ? await promoteFormActionId(request) : undefined;
119
- const prepared = promoted?.request ?? request;
117
+ const promoted = progressive ? await promoteFormActionId(request) : undefined
118
+ const prepared = promoted?.request ?? request
120
119
 
121
120
  // A form POST to a page carrying no recognizable action id is an
122
121
  // unrecognized MPA action: 404 + Next's marker header and log, rather than a
@@ -125,64 +124,64 @@ export async function serveAction(
125
124
  console.error(
126
125
  'Failed to find Server Action. This request might be from an older or newer deployment.\n' +
127
126
  'Read more: https://nextjs.org/docs/messages/failed-to-find-server-action',
128
- );
127
+ )
129
128
  return new Response('Server action not found.', {
130
129
  status: 404,
131
130
  headers: {
132
131
  'content-type': 'text/plain; charset=utf-8',
133
132
  [NEXT_ACTION_NOT_FOUND_HEADER]: '1',
134
133
  },
135
- });
134
+ })
136
135
  }
137
136
 
138
- const response = await runAction(prepared, options);
137
+ const response = await runAction(prepared, options)
139
138
 
140
139
  if (response.headers.has(ACTION_NOT_FOUND_HEADER) && options.renderNotFound) {
141
140
  // Serve the real 404 page HTML with a 404 status and the marker header. A
142
141
  // progressive submit shows it directly; the JS client runtime detects the
143
- // 404 + marker and swaps the document in place (action-client.ts). Returning
142
+ // 404 + marker and swaps the document in place (client.ts). Returning
144
143
  // an empty 200 JSON here would leave the JS client with nothing to render.
145
- const notFound = await options.renderNotFound(request);
146
- const headers = new Headers(notFound.headers);
147
- headers.set(ACTION_NOT_FOUND_HEADER, '1');
148
- copySetCookies(response.headers, headers);
149
- return new Response(notFound.body, { status: 404, headers });
144
+ const notFound = await options.renderNotFound(request)
145
+ const headers = new Headers(notFound.headers)
146
+ headers.set(ACTION_NOT_FOUND_HEADER, '1')
147
+ copySetCookies(response.headers, headers)
148
+ return new Response(notFound.body, { status: 404, headers })
150
149
  }
151
150
 
152
151
  if (!progressive) {
153
- const wantsFlight = acceptsActionFlight(request);
152
+ const wantsFlight = acceptsActionFlight(request)
154
153
  if (response.status === 303 && response.headers.has(ACTION_REDIRECT_HEADER)) {
155
- const target = response.headers.get(ACTION_REDIRECT_HEADER)!;
156
- const headers = new Headers();
157
- if (response.headers.has(ACTION_REFRESH_HEADER)) headers.set(ACTION_REFRESH_HEADER, '1');
158
- const revalidated = response.headers.get(NEXT_ACTION_REVALIDATED_HEADER);
159
- if (revalidated) headers.set(NEXT_ACTION_REVALIDATED_HEADER, revalidated);
160
- const redirectType = response.headers.get(REDIRECT_TYPE_HEADER);
161
- if (redirectType) headers.set(REDIRECT_TYPE_HEADER, redirectType);
162
- copySetCookies(response.headers, headers);
154
+ const target = response.headers.get(ACTION_REDIRECT_HEADER)!
155
+ const headers = new Headers()
156
+ if (response.headers.has(ACTION_REFRESH_HEADER)) headers.set(ACTION_REFRESH_HEADER, '1')
157
+ const revalidated = response.headers.get(NEXT_ACTION_REVALIDATED_HEADER)
158
+ if (revalidated) headers.set(NEXT_ACTION_REVALIDATED_HEADER, revalidated)
159
+ const redirectType = response.headers.get(REDIRECT_TYPE_HEADER)
160
+ if (redirectType) headers.set(REDIRECT_TYPE_HEADER, redirectType)
161
+ copySetCookies(response.headers, headers)
163
162
 
164
163
  // Forwarded action (dispatched from a page that does not own it): Next
165
164
  // relays the owning worker's headers on a 200 — no single-pass 303.
166
165
  // The JSON envelope makes the client soft-navigate to the target.
167
- const actionId = prepared.headers.get(ACTION_ID_HEADER);
166
+ const actionId = prepared.headers.get(ACTION_ID_HEADER)
168
167
  if (actionId && options.isForwardedAction?.(actionId)) {
169
- headers.set(ACTION_REDIRECT_HEADER, target);
170
- headers.set('content-type', 'application/json; charset=utf-8');
171
- return new Response(JSON.stringify({ redirect: target }), { status: 200, headers });
168
+ headers.set(ACTION_REDIRECT_HEADER, target)
169
+ headers.set('content-type', 'application/json; charset=utf-8')
170
+ return new Response(JSON.stringify({ redirect: target }), { status: 200, headers })
172
171
  }
173
172
 
174
173
  // Same-origin targets: single-pass redirect. The 303 has NO location
175
174
  // header (fetch would transparently follow one) and carries the
176
175
  // destination page HTML; the client pushes history and swaps the
177
176
  // document in one round trip, like Next's flight redirects.
178
- const targetUrl = resolveRedirectTarget(request, target);
177
+ const targetUrl = resolveRedirectTarget(request, target)
179
178
  if (targetUrl && (options.renderActionFlight || options.renderRedirectTarget)) {
180
179
  const rendered = await options
181
180
  .renderActionFlight?.(
182
181
  requestWithAppliedCookies(request, targetUrl, response.headers),
183
182
  targetUrl,
184
183
  )
185
- .catch(() => null);
184
+ .catch(() => null)
186
185
  if (wantsFlight && rendered?.status === 200) {
187
186
  return createActionFlightResponse({
188
187
  pageResponse: rendered,
@@ -190,7 +189,7 @@ export async function serveAction(
190
189
  actionHeaders: response.headers,
191
190
  redirect: targetUrl.pathname + targetUrl.search,
192
191
  ...(redirectType ? { redirectType } : {}),
193
- });
192
+ })
194
193
  }
195
194
  const htmlRendered = rendered
196
195
  ? rendered
@@ -199,32 +198,32 @@ export async function serveAction(
199
198
  requestWithAppliedCookies(request, targetUrl, response.headers),
200
199
  targetUrl,
201
200
  )
202
- .catch(() => null);
201
+ .catch(() => null)
203
202
  if (htmlRendered?.status === 200) {
204
- headers.set(ACTION_REDIRECT_HEADER, targetUrl.pathname + targetUrl.search);
203
+ headers.set(ACTION_REDIRECT_HEADER, targetUrl.pathname + targetUrl.search)
205
204
  headers.set(
206
205
  'content-type',
207
206
  htmlRendered.headers.get('content-type') ?? 'text/html; charset=utf-8',
208
- );
209
- return new Response(htmlRendered.body, { status: 303, headers });
207
+ )
208
+ return new Response(htmlRendered.body, { status: 303, headers })
210
209
  }
211
210
  // Same host, but the app cannot render it in-process (a path outside basePath, a rewrite to
212
211
  // another origin). Next still answers the action with a redirect status, so send the bare 303
213
212
  // plus marker and let the client make the follow-up request.
214
- headers.set(ACTION_REDIRECT_HEADER, targetUrl.pathname + targetUrl.search);
215
- return new Response(null, { status: 303, headers });
213
+ headers.set(ACTION_REDIRECT_HEADER, targetUrl.pathname + targetUrl.search)
214
+ return new Response(null, { status: 303, headers })
216
215
  }
217
216
 
218
217
  // Fallback: JSON envelope; the client soft-navigates (or hard-navigates
219
218
  // for external origins).
220
- headers.set('content-type', 'application/json; charset=utf-8');
221
- return new Response(JSON.stringify({ redirect: target }), { status: 200, headers });
219
+ headers.set('content-type', 'application/json; charset=utf-8')
220
+ return new Response(JSON.stringify({ redirect: target }), { status: 200, headers })
222
221
  }
223
222
  // A non-redirect action returns its plain JSON envelope. When it also revalidated (or mutated
224
223
  // cookies), the refresh header rides along and the JS client soft-refreshes the current route in
225
224
  // place, preserving hydrated island state. Wrapping the return in a full-page flight envelope here
226
225
  // would force the client to rewrite the document, discarding that live state.
227
- return response;
226
+ return response
228
227
  }
229
228
 
230
229
  // Progressive success: a useActionState form re-renders the page with the
@@ -234,15 +233,15 @@ export async function serveAction(
234
233
  if (response.status === 200) {
235
234
  if (promoted?.hasFormState && options.renderPageForFormState) {
236
235
  try {
237
- const body = (await response.clone().json()) as ActionSuccessBody;
236
+ const body = (await response.clone().json()) as ActionSuccessBody
238
237
  const page = await options.renderPageForFormState(
239
238
  request,
240
239
  body.data,
241
240
  prepared.headers.get(ACTION_ID_HEADER)!,
242
- );
241
+ )
243
242
  if (page) {
244
- copySetCookies(response.headers, page.headers);
245
- return page;
243
+ copySetCookies(response.headers, page.headers)
244
+ return page
246
245
  }
247
246
  } catch {
248
247
  // fall through to the 303
@@ -255,43 +254,41 @@ export async function serveAction(
255
254
  // that observes the just-applied invalidations and cookie mutations) and return it as the POST
256
255
  // response, matching the single-pass render the flight client path already performs.
257
256
  if (response.headers.has(ACTION_REFRESH_HEADER) && options.renderRedirectTarget) {
258
- const pageUrl = new URL(request.url);
259
- const refreshRequest = requestWithAppliedCookies(request, pageUrl, response.headers);
260
- refreshRequest.headers.set('x-pnext-soft-nav', '1');
261
- const rendered = await options
262
- .renderRedirectTarget(refreshRequest, pageUrl)
263
- .catch(() => null);
257
+ const pageUrl = new URL(request.url)
258
+ const refreshRequest = requestWithAppliedCookies(request, pageUrl, response.headers)
259
+ refreshRequest.headers.set('x-pnext-soft-nav', '1')
260
+ const rendered = await options.renderRedirectTarget(refreshRequest, pageUrl).catch(() => null)
264
261
  if (rendered?.status === 200) {
265
- const headers = new Headers(rendered.headers);
266
- copySetCookies(response.headers, headers);
267
- return new Response(rendered.body, { status: 200, headers });
262
+ const headers = new Headers(rendered.headers)
263
+ copySetCookies(response.headers, headers)
264
+ return new Response(rendered.body, { status: 200, headers })
268
265
  }
269
266
  }
270
- const headers = new Headers({ location: progressiveReturnTarget(request) });
271
- copySetCookies(response.headers, headers);
272
- return new Response(null, { status: 303, headers });
267
+ const headers = new Headers({ location: progressiveReturnTarget(request) })
268
+ copySetCookies(response.headers, headers)
269
+ return new Response(null, { status: 303, headers })
273
270
  }
274
271
  // Progressive unknown-id: mirror Next's MPA behavior (a plain 500).
275
272
  if (response.status === 404 && !response.headers.has(ACTION_NOT_FOUND_HEADER)) {
276
273
  console.error(
277
274
  'Error: Failed to find Server Action. This request might be from an older or newer deployment',
278
- );
275
+ )
279
276
  return new Response('Internal Server Error', {
280
277
  status: 500,
281
278
  headers: { 'content-type': 'text/plain; charset=utf-8' },
282
- });
279
+ })
283
280
  }
284
- return response;
281
+ return response
285
282
  }
286
283
 
287
284
  function progressiveReturnTarget(request: Request): string {
288
- const referer = request.headers.get('referer');
289
- if (referer) return referer;
290
- return new URL(request.url).pathname || '/';
285
+ const referer = request.headers.get('referer')
286
+ if (referer) return referer
287
+ return new URL(request.url).pathname || '/'
291
288
  }
292
289
 
293
290
  function acceptsActionFlight(request: Request): boolean {
294
- return request.headers.get('accept')?.includes(ACTION_FLIGHT_CONTENT_TYPE) ?? false;
291
+ return request.headers.get('accept')?.includes(ACTION_FLIGHT_CONTENT_TYPE) ?? false
295
292
  }
296
293
 
297
294
  /**
@@ -303,73 +300,72 @@ function acceptsActionFlight(request: Request): boolean {
303
300
  async function promoteFormActionId(
304
301
  request: Request,
305
302
  ): Promise<{ request: Request; hasFormState: boolean }> {
306
- const contentType = request.headers.get('content-type') ?? '';
303
+ const contentType = request.headers.get('content-type') ?? ''
307
304
  const isForm =
308
- contentType.includes('multipart/form-data') || contentType.includes('form-urlencoded');
309
- if (!isForm) return { request, hasFormState: false };
305
+ contentType.includes('multipart/form-data') || contentType.includes('form-urlencoded')
306
+ if (!isForm) return { request, hasFormState: false }
310
307
 
311
- let form: FormData;
308
+ let form: FormData
312
309
  try {
313
- form = await request.clone().formData();
310
+ form = await request.clone().formData()
314
311
  } catch {
315
312
  // Unparseable body (e.g. a mismatched multipart boundary): no id to promote;
316
313
  // the caller treats it as an unrecognized MPA action.
317
- return { request, hasFormState: false };
314
+ return { request, hasFormState: false }
318
315
  }
319
316
  // A per-button formAction override (SUBMIT_ACTION_ID_FIELD) wins over the
320
317
  // form's default action (ACTION_ID_FIELD), unambiguously and independent of
321
318
  // field order — a no-JS submit has no event.submitter to tell them apart, and
322
319
  // the form-level hidden field can render either before or after the button.
323
- const submitId = firstFieldValue(form, SUBMIT_ACTION_ID_FIELD);
324
- const formActionId = firstFieldValue(form, ACTION_ID_FIELD);
325
- const id = submitId ?? formActionId;
326
- if (typeof id !== 'string' || id === '') return { request, hasFormState: false };
327
- form.delete(SUBMIT_ACTION_ID_FIELD);
320
+ const submitId = firstFieldValue(form, SUBMIT_ACTION_ID_FIELD)
321
+ const formActionId = firstFieldValue(form, ACTION_ID_FIELD)
322
+ const id = submitId ?? formActionId
323
+ if (typeof id !== 'string' || id === '') return { request, hasFormState: false }
324
+ form.delete(SUBMIT_ACTION_ID_FIELD)
328
325
  // Form state only applies to the form's own useActionState action, never a
329
326
  // plain submitter override (which runs as action(formData), not (state, fd)).
330
- const hasFormState =
331
- submitId === undefined && typeof form.get(FORM_STATE_FIELD) === 'string';
332
- if (!hasFormState) form.delete(FORM_STATE_FIELD);
327
+ const hasFormState = submitId === undefined && typeof form.get(FORM_STATE_FIELD) === 'string'
328
+ if (!hasFormState) form.delete(FORM_STATE_FIELD)
333
329
 
334
- const headers = new Headers(request.headers);
335
- headers.set(ACTION_ID_HEADER, id);
330
+ const headers = new Headers(request.headers)
331
+ headers.set(ACTION_ID_HEADER, id)
336
332
  // Drop the stale content-type/length; the runtime derives a fresh multipart
337
333
  // content-type (with a new boundary) from the FormData body below.
338
- headers.delete('content-type');
339
- headers.delete('content-length');
334
+ headers.delete('content-type')
335
+ headers.delete('content-length')
340
336
  return {
341
337
  request: new Request(request.url, { method: 'POST', headers, body: form }),
342
338
  hasFormState,
343
- };
339
+ }
344
340
  }
345
341
 
346
342
  function lastFieldValue(form: FormData, name: string) {
347
- const values = form.getAll(name);
348
- return values.length > 0 ? values[values.length - 1] : undefined;
343
+ const values = form.getAll(name)
344
+ return values.length > 0 ? values[values.length - 1] : undefined
349
345
  }
350
346
 
351
347
  function firstFieldValue(form: FormData, name: string) {
352
- const values = form.getAll(name);
353
- return values.length > 0 ? values[0] : undefined;
348
+ const values = form.getAll(name)
349
+ return values.length > 0 ? values[0] : undefined
354
350
  }
355
351
 
356
352
  function copySetCookies(from: Headers, to: Headers) {
357
- const setCookies = (from as Headers & { getSetCookie?: () => string[] }).getSetCookie?.() ?? [];
358
- for (const cookie of setCookies) to.append('set-cookie', cookie);
353
+ const setCookies = (from as Headers & { getSetCookie?: () => string[] }).getSetCookie?.() ?? []
354
+ for (const cookie of setCookies) to.append('set-cookie', cookie)
359
355
  }
360
356
 
361
357
  /** Same-origin redirect target URL, or undefined for external redirects. */
362
358
  function resolveRedirectTarget(request: Request, target: string): URL | undefined {
363
359
  try {
364
- const requestUrl = new URL(request.url);
365
- const relativeBase = new URL(requestUrl);
360
+ const requestUrl = new URL(request.url)
361
+ const relativeBase = new URL(requestUrl)
366
362
  if (!target.startsWith('/') && !/^[a-z][a-z0-9+.-]*:/i.test(target)) {
367
- relativeBase.pathname = `${relativeBase.pathname.replace(/\/+$/, '')}/`;
363
+ relativeBase.pathname = `${relativeBase.pathname.replace(/\/+$/, '')}/`
368
364
  }
369
- const url = new URL(target, relativeBase);
370
- return url.origin === requestUrl.origin ? url : undefined;
365
+ const url = new URL(target, relativeBase)
366
+ return url.origin === requestUrl.origin ? url : undefined
371
367
  } catch {
372
- return undefined;
368
+ return undefined
373
369
  }
374
370
  }
375
371
 
@@ -380,35 +376,35 @@ function resolveRedirectTarget(request: Request, target: string): URL | undefine
380
376
  * browser following the redirect would send.
381
377
  */
382
378
  function requestWithAppliedCookies(request: Request, target: URL, actionHeaders: Headers): Request {
383
- const headers = new Headers(request.headers);
384
- headers.delete('content-type');
385
- headers.delete('content-length');
386
- headers.delete(ACTION_ID_HEADER);
379
+ const headers = new Headers(request.headers)
380
+ headers.delete('content-type')
381
+ headers.delete('content-length')
382
+ headers.delete(ACTION_ID_HEADER)
387
383
 
388
384
  const setCookies =
389
- (actionHeaders as Headers & { getSetCookie?: () => string[] }).getSetCookie?.() ?? [];
385
+ (actionHeaders as Headers & { getSetCookie?: () => string[] }).getSetCookie?.() ?? []
390
386
  if (setCookies.length > 0) {
391
- const jar = new Map<string, string>();
392
- const existing = headers.get('cookie') ?? '';
387
+ const jar = new Map<string, string>()
388
+ const existing = headers.get('cookie') ?? ''
393
389
  for (const part of existing.split(';')) {
394
- const eq = part.indexOf('=');
395
- if (eq === -1) continue;
396
- jar.set(part.slice(0, eq).trim(), part.slice(eq + 1).trim());
390
+ const eq = part.indexOf('=')
391
+ if (eq === -1) continue
392
+ jar.set(part.slice(0, eq).trim(), part.slice(eq + 1).trim())
397
393
  }
398
394
  for (const setCookie of setCookies) {
399
- const [pair, ...attributes] = setCookie.split(';');
400
- const eq = (pair ?? '').indexOf('=');
401
- if (eq === -1) continue;
402
- const name = pair!.slice(0, eq).trim();
403
- const value = pair!.slice(eq + 1).trim();
404
- const expired = attributes.some(attr => /^\s*max-age\s*=\s*0*\s*$/i.test(attr));
405
- if (expired) jar.delete(name);
406
- else jar.set(name, value);
395
+ const [pair, ...attributes] = setCookie.split(';')
396
+ const eq = (pair ?? '').indexOf('=')
397
+ if (eq === -1) continue
398
+ const name = pair!.slice(0, eq).trim()
399
+ const value = pair!.slice(eq + 1).trim()
400
+ const expired = attributes.some(attr => /^\s*max-age\s*=\s*0*\s*$/i.test(attr))
401
+ if (expired) jar.delete(name)
402
+ else jar.set(name, value)
407
403
  }
408
- const cookieHeader = [...jar.entries()].map(([name, value]) => `${name}=${value}`).join('; ');
409
- if (cookieHeader) headers.set('cookie', cookieHeader);
410
- else headers.delete('cookie');
404
+ const cookieHeader = [...jar.entries()].map(([name, value]) => `${name}=${value}`).join('; ')
405
+ if (cookieHeader) headers.set('cookie', cookieHeader)
406
+ else headers.delete('cookie')
411
407
  }
412
408
 
413
- return new Request(target.href, { headers });
409
+ return new Request(target.href, { headers })
414
410
  }
@@ -9,13 +9,13 @@
9
9
  * don't retain modules. Best-effort: an untagged action function renders as a
10
10
  * normal form (the client stub still POSTs it when JS runs).
11
11
  */
12
- const actionIds = new WeakMap<object, string>();
12
+ const actionIds = new WeakMap<object, string>()
13
13
 
14
14
  export function tagServerAction(fn: unknown, id: string): void {
15
- if (typeof fn === 'function') actionIds.set(fn, id);
15
+ if (typeof fn === 'function') actionIds.set(fn, id)
16
16
  }
17
17
 
18
18
  export function serverActionId(fn: unknown): string | undefined {
19
- if (typeof fn !== 'function') return undefined;
20
- return actionIds.get(fn);
19
+ if (typeof fn !== 'function') return undefined
20
+ return actionIds.get(fn)
21
21
  }
@@ -1,58 +1,58 @@
1
1
  /**
2
- * The sliver of the client action runtime both tiers need: the install-time half (action-client.ts)
3
- * and the dispatch half (action-dispatch.ts, loaded on the first action call). Keep this module small
2
+ * The sliver of the client action runtime both tiers need: the install-time half (client.ts)
3
+ * and the dispatch half (dispatch.ts, loaded on the first action call). Keep this module small
4
4
  * - every byte here ships at first paint on any page that uses a server action.
5
5
  */
6
- import type { ComponentType } from 'preact';
6
+ import type { ComponentType } from 'preact'
7
7
 
8
8
  // Progressive-enhancement form fields: written by the server renderer, read by
9
9
  // the submit listener (initial) and stripped off the wire by the encoder.
10
- export const ACTION_ID_FIELD = '$pnext_action_id';
11
- export const SUBMIT_ACTION_ID_FIELD = '$pnext_submit_action_id';
12
- export const FORM_STATE_FIELD = '$pnext_form_state';
10
+ export const ACTION_ID_FIELD = '$pnext_action_id'
11
+ export const SUBMIT_ACTION_ID_FIELD = '$pnext_submit_action_id'
12
+ export const FORM_STATE_FIELD = '$pnext_form_state'
13
13
 
14
14
  // Binary wire markers: encoded by the dispatch half, revived by both (island
15
15
  // props can carry typed arrays before any action has run).
16
- export const TYPED_ARRAY_MARKER = '$$pnext_typed_array';
17
- export const ARRAY_BUFFER_MARKER = '$$pnext_array_buffer';
16
+ export const TYPED_ARRAY_MARKER = '$$pnext_typed_array'
17
+ export const ARRAY_BUFFER_MARKER = '$$pnext_array_buffer'
18
18
 
19
19
  export interface ActionFunction {
20
- (...args: unknown[]): Promise<unknown>;
21
- $$pnextActionId?: string;
20
+ (...args: unknown[]): Promise<unknown>
21
+ $$pnextActionId?: string
22
22
  }
23
23
 
24
24
  export interface ActionRuntime {
25
- call(id: string, args: unknown[]): Promise<unknown>;
26
- createAction(id: string): ActionFunction;
27
- registerClientReference(id: string, component: ComponentType<Record<string, unknown>>): void;
28
- reviveProps<T>(value: T): T;
25
+ call(id: string, args: unknown[]): Promise<unknown>
26
+ createAction(id: string): ActionFunction
27
+ registerClientReference(id: string, component: ComponentType<Record<string, unknown>>): void
28
+ reviveProps<T>(value: T): T
29
29
  }
30
30
 
31
31
  declare global {
32
32
  interface Window {
33
- __PNEXT_ACTIONS__?: ActionRuntime;
33
+ __PNEXT_ACTIONS__?: ActionRuntime
34
34
  }
35
35
  }
36
36
 
37
37
  interface PNextActionError extends Error {
38
- $$pnextActionError?: boolean;
38
+ $$pnextActionError?: boolean
39
39
  }
40
40
 
41
41
  export function tagActionError(error: unknown): unknown {
42
- if (error instanceof Error) (error as PNextActionError).$$pnextActionError = true;
43
- return error;
42
+ if (error instanceof Error) (error as PNextActionError).$$pnextActionError = true
43
+ return error
44
44
  }
45
45
 
46
46
  /** True for errors produced by an action dispatch (boundary channel filter). */
47
47
  export function isActionError(error: unknown): boolean {
48
- return Boolean(error instanceof Error && (error as PNextActionError).$$pnextActionError);
48
+ return Boolean(error instanceof Error && (error as PNextActionError).$$pnextActionError)
49
49
  }
50
50
 
51
51
  /** Client components an action return may reference by id (element markers). */
52
52
  export const actionReturnClientReferences = new Map<
53
53
  string,
54
54
  ComponentType<Record<string, unknown>>
55
- >();
55
+ >()
56
56
 
57
57
  const TYPED_ARRAY_CTORS: Record<string, new (buffer: ArrayBuffer) => ArrayBufferView> = {
58
58
  Int8Array,
@@ -66,30 +66,30 @@ const TYPED_ARRAY_CTORS: Record<string, new (buffer: ArrayBuffer) => ArrayBuffer
66
66
  Float64Array,
67
67
  BigInt64Array,
68
68
  BigUint64Array,
69
- };
69
+ }
70
70
 
71
71
  export function base64ToArrayBuffer(base64: string): ArrayBuffer {
72
72
  if (typeof atob === 'function') {
73
- const binary = atob(base64);
74
- const bytes = new Uint8Array(binary.length);
75
- for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
76
- return bytes.buffer;
73
+ const binary = atob(base64)
74
+ const bytes = new Uint8Array(binary.length)
75
+ for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i)
76
+ return bytes.buffer
77
77
  }
78
- const buf = Buffer.from(base64, 'base64');
79
- return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
78
+ const buf = Buffer.from(base64, 'base64')
79
+ return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength)
80
80
  }
81
81
 
82
82
  /** Revive a typed-array / ArrayBuffer wire marker, else undefined. */
83
83
  export function reviveBinaryMarker(record: Record<string, unknown>): unknown {
84
- const typed = record[TYPED_ARRAY_MARKER];
84
+ const typed = record[TYPED_ARRAY_MARKER]
85
85
  if (typed && typeof typed === 'object') {
86
- const { type, data } = typed as { type?: string; data?: string };
87
- const Ctor = type ? TYPED_ARRAY_CTORS[type] : undefined;
86
+ const { type, data } = typed as { type?: string; data?: string }
87
+ const Ctor = type ? TYPED_ARRAY_CTORS[type] : undefined
88
88
  if (Ctor && typeof data === 'string') {
89
- return new Ctor(base64ToArrayBuffer(data));
89
+ return new Ctor(base64ToArrayBuffer(data))
90
90
  }
91
91
  }
92
- const buffer = record[ARRAY_BUFFER_MARKER];
93
- if (typeof buffer === 'string') return base64ToArrayBuffer(buffer);
94
- return undefined;
92
+ const buffer = record[ARRAY_BUFFER_MARKER]
93
+ if (typeof buffer === 'string') return base64ToArrayBuffer(buffer)
94
+ return undefined
95
95
  }