@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,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
  }