@nifrajs/web 4.0.0 → 5.0.0

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 (388) hide show
  1. package/README.md +11 -0
  2. package/dist/build-vite.d.ts +19 -0
  3. package/dist/build-vite.d.ts.map +1 -1
  4. package/dist/build-vite.js +31 -10
  5. package/dist/build-vite.js.map +1 -1
  6. package/dist/build.d.ts +8 -10
  7. package/dist/build.d.ts.map +1 -1
  8. package/dist/build.js +90 -31
  9. package/dist/build.js.map +1 -1
  10. package/dist/cdn.d.ts +8 -0
  11. package/dist/cdn.d.ts.map +1 -1
  12. package/dist/cdn.js +14 -15
  13. package/dist/cdn.js.map +1 -1
  14. package/dist/client.d.ts +1 -1
  15. package/dist/client.d.ts.map +1 -1
  16. package/dist/client.js +49 -26
  17. package/dist/client.js.map +1 -1
  18. package/dist/deferred.d.ts +2 -2
  19. package/dist/deferred.d.ts.map +1 -1
  20. package/dist/deferred.js +28 -7
  21. package/dist/deferred.js.map +1 -1
  22. package/dist/dev-feed.d.ts.map +1 -1
  23. package/dist/dev-feed.js +24 -5
  24. package/dist/dev-feed.js.map +1 -1
  25. package/dist/dev-session.d.ts.map +1 -1
  26. package/dist/dev-session.js +4 -14
  27. package/dist/dev-session.js.map +1 -1
  28. package/dist/dev.d.ts +7 -17
  29. package/dist/dev.d.ts.map +1 -1
  30. package/dist/dev.js +13 -1
  31. package/dist/dev.js.map +1 -1
  32. package/dist/draft.d.ts +8 -5
  33. package/dist/draft.d.ts.map +1 -1
  34. package/dist/draft.js +30 -13
  35. package/dist/draft.js.map +1 -1
  36. package/dist/fonts-google.d.ts.map +1 -1
  37. package/dist/fonts-google.js +7 -0
  38. package/dist/fonts-google.js.map +1 -1
  39. package/dist/index.d.ts +2 -2
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.js +2 -2
  42. package/dist/index.js.map +1 -1
  43. package/dist/internal/codegen.d.ts +1 -0
  44. package/dist/internal/codegen.d.ts.map +1 -1
  45. package/dist/internal/codegen.js +56 -29
  46. package/dist/internal/codegen.js.map +1 -1
  47. package/dist/internal/disposable-dir.d.ts +8 -0
  48. package/dist/internal/disposable-dir.d.ts.map +1 -0
  49. package/dist/internal/disposable-dir.js +25 -0
  50. package/dist/internal/disposable-dir.js.map +1 -0
  51. package/dist/internal/entry-chunks.d.ts +9 -0
  52. package/dist/internal/entry-chunks.d.ts.map +1 -0
  53. package/dist/internal/entry-chunks.js +15 -0
  54. package/dist/internal/entry-chunks.js.map +1 -0
  55. package/dist/internal/evidence-traversal.d.ts +12 -0
  56. package/dist/internal/evidence-traversal.d.ts.map +1 -0
  57. package/dist/internal/evidence-traversal.js +48 -0
  58. package/dist/internal/evidence-traversal.js.map +1 -0
  59. package/dist/internal/head-merge.d.ts +6 -0
  60. package/dist/internal/head-merge.d.ts.map +1 -1
  61. package/dist/internal/head-merge.js +9 -0
  62. package/dist/internal/head-merge.js.map +1 -1
  63. package/dist/internal/js-string.d.ts +2 -0
  64. package/dist/internal/js-string.d.ts.map +1 -1
  65. package/dist/internal/js-string.js +5 -1
  66. package/dist/internal/js-string.js.map +1 -1
  67. package/dist/internal/mount-shadow.js +1 -1
  68. package/dist/internal/mount-shadow.js.map +1 -1
  69. package/dist/internal/output-guard.d.ts +7 -0
  70. package/dist/internal/output-guard.d.ts.map +1 -1
  71. package/dist/internal/output-guard.js +80 -8
  72. package/dist/internal/output-guard.js.map +1 -1
  73. package/dist/internal/page-execution.d.ts +6 -0
  74. package/dist/internal/page-execution.d.ts.map +1 -1
  75. package/dist/internal/page-execution.js +377 -108
  76. package/dist/internal/page-execution.js.map +1 -1
  77. package/dist/internal/progressive-cookies.d.ts +14 -0
  78. package/dist/internal/progressive-cookies.d.ts.map +1 -0
  79. package/dist/internal/progressive-cookies.js +43 -0
  80. package/dist/internal/progressive-cookies.js.map +1 -0
  81. package/dist/internal/public-env.d.ts +2 -0
  82. package/dist/internal/public-env.d.ts.map +1 -0
  83. package/dist/internal/public-env.js +13 -0
  84. package/dist/internal/public-env.js.map +1 -0
  85. package/dist/internal/render-document.d.ts +1 -0
  86. package/dist/internal/render-document.d.ts.map +1 -1
  87. package/dist/internal/render-document.js +28 -5
  88. package/dist/internal/render-document.js.map +1 -1
  89. package/dist/internal/response-controls.d.ts +2 -0
  90. package/dist/internal/response-controls.d.ts.map +1 -1
  91. package/dist/internal/response-controls.js +26 -16
  92. package/dist/internal/response-controls.js.map +1 -1
  93. package/dist/internal/revive-dates.d.ts +16 -0
  94. package/dist/internal/revive-dates.d.ts.map +1 -0
  95. package/dist/internal/revive-dates.js +32 -0
  96. package/dist/internal/revive-dates.js.map +1 -0
  97. package/dist/internal/route-path.d.ts +8 -0
  98. package/dist/internal/route-path.d.ts.map +1 -0
  99. package/dist/internal/route-path.js +8 -0
  100. package/dist/internal/route-path.js.map +1 -0
  101. package/dist/internal/secret-scan.d.ts.map +1 -1
  102. package/dist/internal/secret-scan.js +105 -19
  103. package/dist/internal/secret-scan.js.map +1 -1
  104. package/dist/internal/server-boundary.d.ts.map +1 -1
  105. package/dist/internal/server-boundary.js +33 -5
  106. package/dist/internal/server-boundary.js.map +1 -1
  107. package/dist/internal/web-app.d.ts +21 -16
  108. package/dist/internal/web-app.d.ts.map +1 -1
  109. package/dist/internal/web-app.js +73 -21
  110. package/dist/internal/web-app.js.map +1 -1
  111. package/dist/internal/wire-date.d.ts +3 -0
  112. package/dist/internal/wire-date.d.ts.map +1 -0
  113. package/dist/internal/wire-date.js +14 -0
  114. package/dist/internal/wire-date.js.map +1 -0
  115. package/dist/internal/zone-graph.d.ts +4 -0
  116. package/dist/internal/zone-graph.d.ts.map +1 -1
  117. package/dist/internal/zone-graph.js +54 -14
  118. package/dist/internal/zone-graph.js.map +1 -1
  119. package/dist/isr.d.ts +58 -2
  120. package/dist/isr.d.ts.map +1 -1
  121. package/dist/isr.js +296 -39
  122. package/dist/isr.js.map +1 -1
  123. package/dist/llms-txt.d.ts +2 -0
  124. package/dist/llms-txt.d.ts.map +1 -1
  125. package/dist/llms-txt.js +29 -3
  126. package/dist/llms-txt.js.map +1 -1
  127. package/dist/manifest.d.ts +28 -4
  128. package/dist/manifest.d.ts.map +1 -1
  129. package/dist/manifest.js +14 -3
  130. package/dist/manifest.js.map +1 -1
  131. package/dist/open-resolved.d.ts +18 -0
  132. package/dist/open-resolved.d.ts.map +1 -0
  133. package/dist/open-resolved.js +62 -0
  134. package/dist/open-resolved.js.map +1 -0
  135. package/dist/plugins/kit.d.ts +1 -0
  136. package/dist/plugins/kit.d.ts.map +1 -1
  137. package/dist/plugins/kit.js +26 -11
  138. package/dist/plugins/kit.js.map +1 -1
  139. package/dist/plugins/vite-leak-guard.d.ts +3 -1
  140. package/dist/plugins/vite-leak-guard.d.ts.map +1 -1
  141. package/dist/plugins/vite-leak-guard.js +4 -0
  142. package/dist/plugins/vite-leak-guard.js.map +1 -1
  143. package/dist/plugins/zone-guard.d.ts.map +1 -1
  144. package/dist/plugins/zone-guard.js +10 -2
  145. package/dist/plugins/zone-guard.js.map +1 -1
  146. package/dist/public-dir.d.ts +8 -1
  147. package/dist/public-dir.d.ts.map +1 -1
  148. package/dist/public-dir.js +17 -6
  149. package/dist/public-dir.js.map +1 -1
  150. package/dist/query.d.ts +13 -4
  151. package/dist/query.d.ts.map +1 -1
  152. package/dist/query.js +89 -26
  153. package/dist/query.js.map +1 -1
  154. package/dist/render-seam.d.ts +2 -0
  155. package/dist/render-seam.d.ts.map +1 -1
  156. package/dist/render-seam.js +1 -0
  157. package/dist/render-seam.js.map +1 -1
  158. package/dist/route-types.d.ts.map +1 -1
  159. package/dist/route-types.js +20 -9
  160. package/dist/route-types.js.map +1 -1
  161. package/dist/router.d.ts +9 -2
  162. package/dist/router.d.ts.map +1 -1
  163. package/dist/router.js +39 -46
  164. package/dist/router.js.map +1 -1
  165. package/dist/server-components/build-info.d.ts +3 -0
  166. package/dist/server-components/build-info.d.ts.map +1 -0
  167. package/dist/server-components/build-info.js +7 -0
  168. package/dist/server-components/build-info.js.map +1 -0
  169. package/dist/server-components/build-target.d.ts +12 -0
  170. package/dist/server-components/build-target.d.ts.map +1 -0
  171. package/dist/server-components/build-target.js +153 -0
  172. package/dist/server-components/build-target.js.map +1 -0
  173. package/dist/server-components/build.d.ts +24 -0
  174. package/dist/server-components/build.d.ts.map +1 -0
  175. package/dist/server-components/build.js +366 -0
  176. package/dist/server-components/build.js.map +1 -0
  177. package/dist/server-components/bundle-proof.d.ts +3 -0
  178. package/dist/server-components/bundle-proof.d.ts.map +1 -0
  179. package/dist/server-components/bundle-proof.js +23 -0
  180. package/dist/server-components/bundle-proof.js.map +1 -0
  181. package/dist/server-components/client.d.ts +46 -0
  182. package/dist/server-components/client.d.ts.map +1 -0
  183. package/dist/server-components/client.js +594 -0
  184. package/dist/server-components/client.js.map +1 -0
  185. package/dist/server-components/definition.d.ts +11 -0
  186. package/dist/server-components/definition.d.ts.map +1 -0
  187. package/dist/server-components/definition.js +94 -0
  188. package/dist/server-components/definition.js.map +1 -0
  189. package/dist/server-components/dev-http.d.ts +5 -0
  190. package/dist/server-components/dev-http.d.ts.map +1 -0
  191. package/dist/server-components/dev-http.js +71 -0
  192. package/dist/server-components/dev-http.js.map +1 -0
  193. package/dist/server-components/error.d.ts +9 -0
  194. package/dist/server-components/error.d.ts.map +1 -0
  195. package/dist/server-components/error.js +24 -0
  196. package/dist/server-components/error.js.map +1 -0
  197. package/dist/server-components/frames.d.ts +7 -0
  198. package/dist/server-components/frames.d.ts.map +1 -0
  199. package/dist/server-components/frames.js +169 -0
  200. package/dist/server-components/frames.js.map +1 -0
  201. package/dist/server-components/html-policy.d.ts +6 -0
  202. package/dist/server-components/html-policy.d.ts.map +1 -0
  203. package/dist/server-components/html-policy.js +75 -0
  204. package/dist/server-components/html-policy.js.map +1 -0
  205. package/dist/server-components/html.d.ts +4 -0
  206. package/dist/server-components/html.d.ts.map +1 -0
  207. package/dist/server-components/html.js +67 -0
  208. package/dist/server-components/html.js.map +1 -0
  209. package/dist/server-components/islands.d.ts +44 -0
  210. package/dist/server-components/islands.d.ts.map +1 -0
  211. package/dist/server-components/islands.js +42 -0
  212. package/dist/server-components/islands.js.map +1 -0
  213. package/dist/server-components/native.d.ts +4 -0
  214. package/dist/server-components/native.d.ts.map +1 -0
  215. package/dist/server-components/native.js +81 -0
  216. package/dist/server-components/native.js.map +1 -0
  217. package/dist/server-components/portal.d.ts +6 -0
  218. package/dist/server-components/portal.d.ts.map +1 -0
  219. package/dist/server-components/portal.js +35 -0
  220. package/dist/server-components/portal.js.map +1 -0
  221. package/dist/server-components/props.d.ts +3 -0
  222. package/dist/server-components/props.d.ts.map +1 -0
  223. package/dist/server-components/props.js +14 -0
  224. package/dist/server-components/props.js.map +1 -0
  225. package/dist/server-components/protocol.d.ts +44 -0
  226. package/dist/server-components/protocol.d.ts.map +1 -0
  227. package/dist/server-components/protocol.js +139 -0
  228. package/dist/server-components/protocol.js.map +1 -0
  229. package/dist/server-components/range.d.ts +24 -0
  230. package/dist/server-components/range.d.ts.map +1 -0
  231. package/dist/server-components/range.js +263 -0
  232. package/dist/server-components/range.js.map +1 -0
  233. package/dist/server-components/registry.d.ts +6 -0
  234. package/dist/server-components/registry.d.ts.map +1 -0
  235. package/dist/server-components/registry.js +30 -0
  236. package/dist/server-components/registry.js.map +1 -0
  237. package/dist/server-components/response.d.ts +4 -0
  238. package/dist/server-components/response.d.ts.map +1 -0
  239. package/dist/server-components/response.js +32 -0
  240. package/dist/server-components/response.js.map +1 -0
  241. package/dist/server-components/router-integration.d.ts +9 -0
  242. package/dist/server-components/router-integration.d.ts.map +1 -0
  243. package/dist/server-components/router-integration.js +29 -0
  244. package/dist/server-components/router-integration.js.map +1 -0
  245. package/dist/server-components/runtime.d.ts +14 -0
  246. package/dist/server-components/runtime.d.ts.map +1 -0
  247. package/dist/server-components/runtime.js +276 -0
  248. package/dist/server-components/runtime.js.map +1 -0
  249. package/dist/server-components/scheduler.d.ts +14 -0
  250. package/dist/server-components/scheduler.d.ts.map +1 -0
  251. package/dist/server-components/scheduler.js +74 -0
  252. package/dist/server-components/scheduler.js.map +1 -0
  253. package/dist/server-components/schema.d.ts +4 -0
  254. package/dist/server-components/schema.d.ts.map +1 -0
  255. package/dist/server-components/schema.js +77 -0
  256. package/dist/server-components/schema.js.map +1 -0
  257. package/dist/server-components/server-entry.d.ts +12 -0
  258. package/dist/server-components/server-entry.d.ts.map +1 -0
  259. package/dist/server-components/server-entry.js +90 -0
  260. package/dist/server-components/server-entry.js.map +1 -0
  261. package/dist/server-components/source.d.ts +15 -0
  262. package/dist/server-components/source.d.ts.map +1 -0
  263. package/dist/server-components/source.js +269 -0
  264. package/dist/server-components/source.js.map +1 -0
  265. package/dist/server-components/state.d.ts +4 -0
  266. package/dist/server-components/state.d.ts.map +1 -0
  267. package/dist/server-components/state.js +123 -0
  268. package/dist/server-components/state.js.map +1 -0
  269. package/dist/server-components/stream.d.ts +6 -0
  270. package/dist/server-components/stream.d.ts.map +1 -0
  271. package/dist/server-components/stream.js +70 -0
  272. package/dist/server-components/stream.js.map +1 -0
  273. package/dist/server-components/trusted-html.d.ts +3 -0
  274. package/dist/server-components/trusted-html.d.ts.map +1 -0
  275. package/dist/server-components/trusted-html.js +14 -0
  276. package/dist/server-components/trusted-html.js.map +1 -0
  277. package/dist/server-components/types.d.ts +107 -0
  278. package/dist/server-components/types.d.ts.map +1 -0
  279. package/dist/server-components/types.js +2 -0
  280. package/dist/server-components/types.js.map +1 -0
  281. package/dist/server-components/typescript.d.ts +11 -0
  282. package/dist/server-components/typescript.d.ts.map +1 -0
  283. package/dist/server-components/typescript.js +28 -0
  284. package/dist/server-components/typescript.js.map +1 -0
  285. package/dist/server-components/value.d.ts +5 -0
  286. package/dist/server-components/value.d.ts.map +1 -0
  287. package/dist/server-components/value.js +77 -0
  288. package/dist/server-components/value.js.map +1 -0
  289. package/dist/server-components/vite.d.ts +12 -0
  290. package/dist/server-components/vite.d.ts.map +1 -0
  291. package/dist/server-components/vite.js +197 -0
  292. package/dist/server-components/vite.js.map +1 -0
  293. package/dist/server-components.d.ts +5 -0
  294. package/dist/server-components.d.ts.map +1 -0
  295. package/dist/server-components.js +4 -0
  296. package/dist/server-components.js.map +1 -0
  297. package/dist/service-worker.d.ts +8 -1
  298. package/dist/service-worker.d.ts.map +1 -1
  299. package/dist/service-worker.js +20 -6
  300. package/dist/service-worker.js.map +1 -1
  301. package/dist/vite.d.ts +12 -0
  302. package/dist/vite.d.ts.map +1 -1
  303. package/dist/vite.js +77 -17
  304. package/dist/vite.js.map +1 -1
  305. package/dist/zones.d.ts +40 -0
  306. package/dist/zones.d.ts.map +1 -1
  307. package/dist/zones.js +170 -6
  308. package/dist/zones.js.map +1 -1
  309. package/package.json +97 -4
  310. package/src/build-vite.ts +31 -9
  311. package/src/build.ts +109 -31
  312. package/src/cdn.ts +18 -12
  313. package/src/client.ts +48 -23
  314. package/src/deferred.ts +27 -9
  315. package/src/dev-feed.ts +24 -5
  316. package/src/dev-session.ts +4 -13
  317. package/src/dev.ts +29 -1
  318. package/src/draft.ts +35 -14
  319. package/src/fonts-google.ts +10 -0
  320. package/src/index.ts +3 -2
  321. package/src/internal/codegen.ts +60 -29
  322. package/src/internal/disposable-dir.ts +24 -0
  323. package/src/internal/entry-chunks.ts +18 -0
  324. package/src/internal/evidence-traversal.ts +57 -0
  325. package/src/internal/head-merge.ts +16 -0
  326. package/src/internal/js-string.ts +6 -1
  327. package/src/internal/mount-shadow.ts +1 -1
  328. package/src/internal/output-guard.ts +88 -7
  329. package/src/internal/page-execution.ts +506 -108
  330. package/src/internal/progressive-cookies.ts +60 -0
  331. package/src/internal/public-env.ts +14 -0
  332. package/src/internal/render-document.ts +26 -11
  333. package/src/internal/response-controls.ts +31 -14
  334. package/src/internal/revive-dates.ts +35 -0
  335. package/src/internal/route-path.ts +8 -0
  336. package/src/internal/secret-scan.ts +104 -17
  337. package/src/internal/server-boundary.ts +29 -5
  338. package/src/internal/web-app.ts +116 -37
  339. package/src/internal/wire-date.ts +16 -0
  340. package/src/internal/zone-graph.ts +59 -19
  341. package/src/isr.ts +351 -43
  342. package/src/llms-txt.ts +32 -3
  343. package/src/manifest.ts +43 -7
  344. package/src/open-resolved.ts +64 -0
  345. package/src/plugins/kit.ts +31 -11
  346. package/src/plugins/vite-leak-guard.ts +5 -1
  347. package/src/plugins/zone-guard.ts +11 -2
  348. package/src/public-dir.ts +27 -8
  349. package/src/query.ts +107 -26
  350. package/src/render-seam.ts +2 -0
  351. package/src/route-types.ts +34 -7
  352. package/src/router.ts +58 -55
  353. package/src/server-components/build-info.ts +11 -0
  354. package/src/server-components/build-target.ts +194 -0
  355. package/src/server-components/build.ts +419 -0
  356. package/src/server-components/bundle-proof.ts +33 -0
  357. package/src/server-components/client.ts +663 -0
  358. package/src/server-components/definition.ts +125 -0
  359. package/src/server-components/dev-http.ts +75 -0
  360. package/src/server-components/error.ts +24 -0
  361. package/src/server-components/frames.ts +181 -0
  362. package/src/server-components/html-policy.ts +94 -0
  363. package/src/server-components/html.ts +81 -0
  364. package/src/server-components/islands.ts +111 -0
  365. package/src/server-components/native.ts +101 -0
  366. package/src/server-components/portal.ts +42 -0
  367. package/src/server-components/props.ts +19 -0
  368. package/src/server-components/protocol.ts +167 -0
  369. package/src/server-components/range.ts +313 -0
  370. package/src/server-components/registry.ts +34 -0
  371. package/src/server-components/response.ts +44 -0
  372. package/src/server-components/router-integration.ts +40 -0
  373. package/src/server-components/runtime.ts +376 -0
  374. package/src/server-components/scheduler.ts +84 -0
  375. package/src/server-components/schema.ts +69 -0
  376. package/src/server-components/server-entry.ts +98 -0
  377. package/src/server-components/source.ts +324 -0
  378. package/src/server-components/state.ts +143 -0
  379. package/src/server-components/stream.ts +71 -0
  380. package/src/server-components/trusted-html.ts +21 -0
  381. package/src/server-components/types.ts +138 -0
  382. package/src/server-components/typescript.ts +39 -0
  383. package/src/server-components/value.ts +82 -0
  384. package/src/server-components/vite.ts +242 -0
  385. package/src/server-components.ts +32 -0
  386. package/src/service-worker.ts +24 -7
  387. package/src/vite.ts +68 -17
  388. package/src/zones.ts +208 -7
@@ -0,0 +1,94 @@
1
+ import { narrowCapabilityContext } from "@nifrajs/core/capabilities";
2
+ import { validateStandard } from "@nifrajs/core/schema";
3
+ import { outputGuard, runGuard } from "../internal/output-guard.js";
4
+ import { isControlFlow, isStatusSignal } from "../internal/render-document.js";
5
+ import { ServerComponentError } from "./error.js";
6
+ import { assertComponentSchema, componentValue } from "./schema.js";
7
+ const definitions = new WeakMap();
8
+ const authorizations = new WeakMap();
9
+ export function defineServerComponent(definition, reference) {
10
+ if (typeof definition.authorize !== "function" || typeof definition.load !== "function")
11
+ throw new ServerComponentError("component_contract");
12
+ assertComponentSchema(definition.input);
13
+ assertComponentSchema(definition.props);
14
+ const component = {
15
+ view: definition.view,
16
+ input: definition.input,
17
+ props: definition.props,
18
+ };
19
+ if (reference !== undefined)
20
+ Object.assign(component, { reference });
21
+ Object.freeze(component);
22
+ definitions.set(component, {
23
+ authorize: definition.authorize,
24
+ load: definition.load,
25
+ guard: outputGuard(definition.props, "server component", "props"),
26
+ capabilities: Object.freeze([...(definition.capabilities ?? [])]),
27
+ });
28
+ return component;
29
+ }
30
+ export function isServerComponent(value) {
31
+ return typeof value === "object" && value !== null && definitions.has(value);
32
+ }
33
+ export function serverComponentCapabilities(component) {
34
+ const definition = definitions.get(component);
35
+ if (definition === undefined)
36
+ throw new ServerComponentError("component_contract");
37
+ return definition.capabilities;
38
+ }
39
+ export function inheritOwnerAuthorization() { }
40
+ /** Used for whole-owner preflight so an invalid sibling cannot follow successful work. */
41
+ export async function validateServerComponentInput(component, input) {
42
+ if (!definitions.has(component))
43
+ throw new ServerComponentError("component_unavailable", 404);
44
+ componentValue(input, 1024);
45
+ const parsed = await validateStandard(component.input, input);
46
+ if (!parsed.ok)
47
+ throw new ServerComponentError("component_input", 422);
48
+ componentValue(parsed.value, 1024);
49
+ }
50
+ export async function prepareServerComponent(component, input, ctx) {
51
+ // biome-ignore lint/plugin/requireSafetyCommentForTypeAssertion: The private definition registry binds each schema to its callbacks; validation and authorization precede this erased generic invocation.
52
+ return (await prepareAuthorizedServerComponent(
53
+ // biome-ignore lint/plugin/requireSafetyCommentForTypeAssertion: The private definition registry binds each schema to its callbacks; validation and authorization precede this erased generic invocation.
54
+ await authorizeServerComponent(component, input, ctx)));
55
+ }
56
+ export async function authorizeServerComponent(component, input, ctx) {
57
+ const definition = definitions.get(component);
58
+ if (definition === undefined)
59
+ throw new ServerComponentError("component_unavailable", 404);
60
+ if (ctx.signal.aborted)
61
+ throw new ServerComponentError("component_cancelled", 499);
62
+ componentValue(input, 1024);
63
+ const parsed = await validateStandard(component.input, input);
64
+ if (!parsed.ok)
65
+ throw new ServerComponentError("component_input", 422);
66
+ // biome-ignore lint/plugin/requireSafetyCommentForTypeAssertion: The private definition registry binds each schema to its callbacks; validation and authorization precede this erased generic invocation.
67
+ const scope = narrowCapabilityContext(ctx, definition.capabilities);
68
+ // biome-ignore lint/plugin/requireSafetyCommentForTypeAssertion: The private definition registry binds each schema to its callbacks; validation and authorization precede this erased generic invocation.
69
+ await definition.authorize(scope, parsed.value);
70
+ if (ctx.signal.aborted)
71
+ throw new ServerComponentError("component_cancelled", 499);
72
+ const token = Object.freeze({});
73
+ authorizations.set(token, { component, definition, input: parsed.value, scope });
74
+ return token;
75
+ }
76
+ export async function prepareAuthorizedServerComponent(token) {
77
+ const authorized = authorizations.get(token);
78
+ if (authorized === undefined)
79
+ throw new ServerComponentError("component_contract");
80
+ authorizations.delete(token);
81
+ const { component, definition, scope, input } = authorized;
82
+ if (scope.signal.aborted)
83
+ throw new ServerComponentError("component_cancelled", 499);
84
+ // biome-ignore lint/plugin/requireSafetyCommentForTypeAssertion: The private definition registry binds each schema to its callbacks; validation and authorization precede this erased generic invocation.
85
+ const data = await definition.load(scope, input);
86
+ if (isControlFlow(data) || isStatusSignal(data))
87
+ throw data;
88
+ if (scope.signal.aborted)
89
+ throw new ServerComponentError("component_cancelled", 499);
90
+ const props = await runGuard(definition.guard, data, "server component props");
91
+ const publicProps = componentValue(props);
92
+ return { props: publicProps, view: component.view };
93
+ }
94
+ //# sourceMappingURL=definition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definition.js","sourceRoot":"","sources":["../../src/server-components/definition.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { ViteDevServer } from "vite";
2
+ import type { ComponentPipelineOptions } from "./build.js";
3
+ /** The native dev path serves the same factory and Fetch handler as production. */
4
+ export declare function installComponentDevHandler(server: ViteDevServer, options: ComponentPipelineOptions): void;
5
+ //# sourceMappingURL=dev-http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev-http.d.ts","sourceRoot":"","sources":["../../src/server-components/dev-http.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAA;AACzC,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAA;AAE1D,mFAAmF;AACnF,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,wBAAwB,GAChC,IAAI,CAiEN"}
@@ -0,0 +1,71 @@
1
+ import { Readable } from "node:stream";
2
+ import { pipeline } from "node:stream/promises";
3
+ /** The native dev path serves the same factory and Fetch handler as production. */
4
+ export function installComponentDevHandler(server, options) {
5
+ if (options.adapter === "react")
6
+ return; // plugin-rsc owns the SSR request entry in React dev.
7
+ server.middlewares.use(async (req, res, next) => {
8
+ const path = req.url ?? "/";
9
+ if (path.startsWith("/@") ||
10
+ path.startsWith("/node_modules/") ||
11
+ /\.(?:[cm]?[jt]sx?|vue|svelte|css)(?:\?|$)/.test(path)) {
12
+ next();
13
+ return;
14
+ }
15
+ const abort = new AbortController();
16
+ const close = () => {
17
+ if (!res.writableEnded)
18
+ abort.abort();
19
+ };
20
+ res.on("close", close);
21
+ try {
22
+ const module = await server.ssrLoadModule(options.entries.ssr);
23
+ if (typeof module.createApp !== "function")
24
+ throw new Error("[nifra/components] The SSR entry must export createApp(clientEntry, assets)");
25
+ const app = await module.createApp(`/${options.entries.client.replace(/^\.\//, "")}`, {
26
+ styles: [],
27
+ });
28
+ if (typeof app?.fetch !== "function")
29
+ throw new Error("component_contract");
30
+ const headers = new Headers();
31
+ for (let i = 0; i < req.rawHeaders.length; i += 2)
32
+ headers.append(req.rawHeaders[i], req.rawHeaders[i + 1]);
33
+ const method = req.method ?? "GET";
34
+ const init = { method, headers, signal: abort.signal };
35
+ if (!["GET", "HEAD"].includes(method)) {
36
+ // biome-ignore lint/plugin/requireSafetyCommentForTypeAssertion lint/plugin/noChainedTypeAssertions: Node and Bun name the same WHATWG stream API differently; this zero-copy bridge preserves that ABI.
37
+ init.body = Readable.toWeb(req);
38
+ init.duplex = "half";
39
+ }
40
+ const request = new Request(new URL(path, `http://${req.headers.host ?? "localhost"}`), init);
41
+ const response = await app.fetch(request);
42
+ if (abort.signal.aborted || res.destroyed) {
43
+ await response.body?.cancel();
44
+ return;
45
+ }
46
+ res.statusCode = response.status;
47
+ for (const [name, value] of response.headers)
48
+ if (name !== "set-cookie")
49
+ res.setHeader(name, value);
50
+ const cookies = response.headers.getSetCookie();
51
+ if (cookies.length > 0)
52
+ res.setHeader("set-cookie", cookies);
53
+ // The runtime stream implements Node's Web Streams API despite the distinct TS declarations.
54
+ if (response.body !== null && method !== "HEAD")
55
+ await pipeline(Readable.fromWeb(
56
+ // biome-ignore lint/plugin/requireSafetyCommentForTypeAssertion lint/plugin/noChainedTypeAssertions: Node and Bun name the same WHATWG stream API differently; this bridge preserves the stream without copying or decoding.
57
+ response.body), res);
58
+ else
59
+ res.end();
60
+ }
61
+ catch (error) {
62
+ // A disconnected read has no response destination and must not broadcast a Vite error overlay.
63
+ if (!abort.signal.aborted && !res.destroyed)
64
+ next(error);
65
+ }
66
+ finally {
67
+ res.off("close", close);
68
+ }
69
+ });
70
+ }
71
+ //# sourceMappingURL=dev-http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev-http.js","sourceRoot":"","sources":["../../src/server-components/dev-http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAI/C,mFAAmF;AACnF,MAAM,UAAU,0BAA0B,CACxC,MAAqB,EACrB,OAAiC;IAEjC,IAAI,OAAO,CAAC,OAAO,KAAK,OAAO;QAAE,OAAM,CAAC,sDAAsD;IAC9F,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QAC9C,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,CAAA;QAC3B,IACE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YACrB,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC;YACjC,2CAA2C,CAAC,IAAI,CAAC,IAAI,CAAC,EACtD,CAAC;YACD,IAAI,EAAE,CAAA;YACN,OAAM;QACR,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,eAAe,EAAE,CAAA;QACnC,MAAM,KAAK,GAAG,GAAS,EAAE;YACvB,IAAI,CAAC,GAAG,CAAC,aAAa;gBAAE,KAAK,CAAC,KAAK,EAAE,CAAA;QACvC,CAAC,CAAA;QACD,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;QACtB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;YAC9D,IAAI,OAAO,MAAM,CAAC,SAAS,KAAK,UAAU;gBACxC,MAAM,IAAI,KAAK,CACb,6EAA6E,CAC9E,CAAA;YACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,EAAE;gBACpF,MAAM,EAAE,EAAE;aACX,CAAC,CAAA;YACF,IAAI,OAAO,GAAG,EAAE,KAAK,KAAK,UAAU;gBAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAA;YAC3E,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAA;YAC7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC;gBAC/C,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAE,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC,CAAA;YAC5D,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,KAAK,CAAA;YAClC,MAAM,IAAI,GAAsC,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAA;YACzF,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBACtC,yMAAyM;gBACzM,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAA0C,CAAA;gBACxE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;YACtB,CAAC;YACD,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,IAAI,GAAG,CAAC,IAAI,EAAE,UAAU,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,WAAW,EAAE,CAAC,EAAE,IAAI,CAAC,CAAA;YAC7F,MAAM,QAAQ,GAAa,MAAM,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;YACnD,IAAI,KAAK,CAAC,MAAM,CAAC,OAAO,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;gBAC1C,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAA;gBAC7B,OAAM;YACR,CAAC;YACD,GAAG,CAAC,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAA;YAChC,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,QAAQ,CAAC,OAAO;gBAC1C,IAAI,IAAI,KAAK,YAAY;oBAAE,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;YACvD,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,YAAY,EAAE,CAAA;YAC/C,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;gBAAE,GAAG,CAAC,SAAS,CAAC,YAAY,EAAE,OAAO,CAAC,CAAA;YAC5D,6FAA6F;YAC7F,IAAI,QAAQ,CAAC,IAAI,KAAK,IAAI,IAAI,MAAM,KAAK,MAAM;gBAC7C,MAAM,QAAQ,CACZ,QAAQ,CAAC,OAAO;gBACd,6NAA6N;gBAC7N,QAAQ,CAAC,IAAuE,CACjF,EACD,GAAG,CACJ,CAAA;;gBACE,GAAG,CAAC,GAAG,EAAE,CAAA;QAChB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,+FAA+F;YAC/F,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,SAAS;gBAAE,IAAI,CAAC,KAAK,CAAC,CAAA;QAC1D,CAAC;gBAAS,CAAC;YACT,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;QACzB,CAAC;IACH,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,9 @@
1
+ export declare const COMPONENT_ERROR_CODES: readonly ["component_contract", "component_input", "component_protocol", "component_limit", "component_denied", "component_unavailable", "component_version", "component_busy", "component_timeout", "component_failed", "component_cancelled"];
2
+ export type ComponentErrorCode = (typeof COMPONENT_ERROR_CODES)[number];
3
+ export declare class ServerComponentError extends Error {
4
+ readonly code: ComponentErrorCode;
5
+ readonly status: number;
6
+ readonly name = "ServerComponentError";
7
+ constructor(code: ComponentErrorCode, status?: number);
8
+ }
9
+ //# sourceMappingURL=error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../src/server-components/error.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,qBAAqB,iPAYxB,CAAA;AACV,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAA;AAEvE,qBAAa,oBAAqB,SAAQ,KAAK;IAG3C,QAAQ,CAAC,IAAI,EAAE,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM;IAHzB,SAAkB,IAAI,0BAAyB;gBAEpC,IAAI,EAAE,kBAAkB,EACxB,MAAM,GAAE,MAAY;CAIhC"}
@@ -0,0 +1,24 @@
1
+ export const COMPONENT_ERROR_CODES = [
2
+ "component_contract",
3
+ "component_input",
4
+ "component_protocol",
5
+ "component_limit",
6
+ "component_denied",
7
+ "component_unavailable",
8
+ "component_version",
9
+ "component_busy",
10
+ "component_timeout",
11
+ "component_failed",
12
+ "component_cancelled",
13
+ ];
14
+ export class ServerComponentError extends Error {
15
+ code;
16
+ status;
17
+ name = "ServerComponentError";
18
+ constructor(code, status = 500) {
19
+ super(`[nifra/web] ${code}`);
20
+ this.code = code;
21
+ this.status = status;
22
+ }
23
+ }
24
+ //# sourceMappingURL=error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.js","sourceRoot":"","sources":["../../src/server-components/error.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,oBAAoB;IACpB,iBAAiB;IACjB,oBAAoB;IACpB,iBAAiB;IACjB,kBAAkB;IAClB,uBAAuB;IACvB,mBAAmB;IACnB,gBAAgB;IAChB,mBAAmB;IACnB,kBAAkB;IAClB,qBAAqB;CACb,CAAA;AAGV,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAGlC;IACA;IAHO,IAAI,GAAG,sBAAsB,CAAA;IAC/C,YACW,IAAwB,EACxB,SAAiB,GAAG;QAE7B,KAAK,CAAC,eAAe,IAAI,EAAE,CAAC,CAAA;QAHnB,SAAI,GAAJ,IAAI,CAAoB;QACxB,WAAM,GAAN,MAAM,CAAc;IAG/B,CAAC;CACF"}
@@ -0,0 +1,7 @@
1
+ export declare function componentFrames(metadata: unknown, value: unknown, maxBytes?: 1048576): ReadableStream<Uint8Array>;
2
+ export interface DecodedComponentFrames {
3
+ readonly metadata: unknown;
4
+ readonly value: unknown;
5
+ }
6
+ export declare function readComponentFrames(stream: ReadableStream<Uint8Array>, signal: AbortSignal, maxBytes?: 1048576): Promise<DecodedComponentFrames>;
7
+ //# sourceMappingURL=frames.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frames.d.ts","sourceRoot":"","sources":["../../src/server-components/frames.ts"],"names":[],"mappings":"AAeA,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,OAAO,EACjB,KAAK,EAAE,OAAO,EACd,QAAQ,UAA+B,GACtC,cAAc,CAAC,UAAU,CAAC,CA4B5B;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC1B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CACxB;AAED,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,EAClC,MAAM,EAAE,WAAW,EACnB,QAAQ,UAA+B,GACtC,OAAO,CAAC,sBAAsB,CAAC,CA0HjC"}
@@ -0,0 +1,169 @@
1
+ import { ServerComponentError } from "./error.js";
2
+ import { COMPONENT_LIMITS } from "./protocol.js";
3
+ const magic = new Uint8Array([78, 83, 67, 49]);
4
+ const encoder = new TextEncoder();
5
+ const decoder = new TextDecoder("utf-8", { fatal: true });
6
+ function frame(type, data) {
7
+ const bytes = new Uint8Array(data.length + 5);
8
+ bytes[0] = type;
9
+ new DataView(bytes.buffer).setUint32(1, data.length);
10
+ bytes.set(data, 5);
11
+ return bytes;
12
+ }
13
+ export function componentFrames(metadata, value, maxBytes = COMPONENT_LIMITS.outputBytes) {
14
+ const meta = encoder.encode(JSON.stringify(metadata));
15
+ const body = encoder.encode(JSON.stringify(value));
16
+ if (meta.length > COMPONENT_LIMITS.frameBytes || body.length + meta.length > maxBytes)
17
+ throw new ServerComponentError("component_limit", 413);
18
+ let position = -2;
19
+ return new ReadableStream({
20
+ pull(controller) {
21
+ if (position === -2) {
22
+ controller.enqueue(magic);
23
+ position++;
24
+ return;
25
+ }
26
+ if (position === -1) {
27
+ controller.enqueue(frame(1, meta));
28
+ position++;
29
+ return;
30
+ }
31
+ if (position < body.length) {
32
+ const end = Math.min(body.length, position + 65536);
33
+ controller.enqueue(frame(2, body.subarray(position, end)));
34
+ position = end;
35
+ return;
36
+ }
37
+ controller.enqueue(frame(3, new Uint8Array()));
38
+ controller.close();
39
+ },
40
+ });
41
+ }
42
+ export async function readComponentFrames(stream, signal, maxBytes = COMPONENT_LIMITS.outputBytes) {
43
+ const reader = stream.getReader();
44
+ const header = new Uint8Array(5);
45
+ let magicOffset = 0;
46
+ let headerOffset = 0;
47
+ let payload;
48
+ let payloadOffset = 0;
49
+ let type = 0;
50
+ let metadata;
51
+ let gotMetadata = false;
52
+ let terminal = false;
53
+ let bytes = 0;
54
+ let bodyBytes = 0;
55
+ let metadataBytes = 0;
56
+ const body = [];
57
+ const deadline = AbortSignal.any([signal, AbortSignal.timeout(COMPONENT_LIMITS.operationMs)]);
58
+ const cancel = () => {
59
+ void reader.cancel().catch(() => {
60
+ /* The original read failure is authoritative. */
61
+ });
62
+ };
63
+ deadline.addEventListener("abort", cancel, { once: true });
64
+ const consume = (data) => {
65
+ if (type === 1) {
66
+ if (gotMetadata || bodyBytes !== 0)
67
+ throw new ServerComponentError("component_protocol", 400);
68
+ metadataBytes = data.length;
69
+ metadata = JSON.parse(decoder.decode(data));
70
+ gotMetadata = true;
71
+ }
72
+ else if (type === 2) {
73
+ if (!gotMetadata || data.length === 0)
74
+ throw new ServerComponentError("component_protocol", 400);
75
+ bodyBytes += data.length;
76
+ if (bodyBytes + metadataBytes > maxBytes)
77
+ throw new ServerComponentError("component_limit", 413);
78
+ body.push(data);
79
+ }
80
+ else {
81
+ if (!gotMetadata || bodyBytes === 0 || data.length !== 0)
82
+ throw new ServerComponentError("component_protocol", 400);
83
+ terminal = true;
84
+ }
85
+ };
86
+ try {
87
+ while (true) {
88
+ if (deadline.aborted)
89
+ throw new ServerComponentError(signal.aborted ? "component_cancelled" : "component_timeout", 504);
90
+ let timeout;
91
+ const next = await Promise.race([
92
+ reader.read(),
93
+ new Promise((_, reject) => {
94
+ timeout = setTimeout(() => {
95
+ reject(new ServerComponentError("component_timeout", 504));
96
+ // Publish the timeout before cancellation can resolve reader.read() as ordinary EOF.
97
+ cancel();
98
+ }, COMPONENT_LIMITS.idleMs);
99
+ }),
100
+ ]).finally(() => clearTimeout(timeout));
101
+ if (next.done)
102
+ break;
103
+ if (terminal || next.value.length === 0)
104
+ throw new ServerComponentError("component_protocol", 400);
105
+ bytes += next.value.length;
106
+ if (bytes > maxBytes + 4096)
107
+ throw new ServerComponentError("component_limit", 413);
108
+ let offset = 0;
109
+ while (offset < next.value.length) {
110
+ if (terminal)
111
+ throw new ServerComponentError("component_protocol", 400);
112
+ if (magicOffset < magic.length) {
113
+ if (next.value[offset++] !== magic[magicOffset++])
114
+ throw new ServerComponentError("component_protocol", 400);
115
+ continue;
116
+ }
117
+ if (headerOffset < header.length) {
118
+ const size = Math.min(header.length - headerOffset, next.value.length - offset);
119
+ header.set(next.value.subarray(offset, offset + size), headerOffset);
120
+ offset += size;
121
+ headerOffset += size;
122
+ if (headerOffset < header.length)
123
+ continue;
124
+ type = header[0];
125
+ const length = new DataView(header.buffer).getUint32(1);
126
+ if (length > COMPONENT_LIMITS.frameBytes || ![1, 2, 3].includes(type))
127
+ throw new ServerComponentError("component_protocol", 400);
128
+ payload = new Uint8Array(length);
129
+ payloadOffset = 0;
130
+ }
131
+ // A frame allocates once. Arbitrarily split transport chunks are copied exactly once.
132
+ const data = payload;
133
+ const size = Math.min(data.length - payloadOffset, next.value.length - offset);
134
+ data.set(next.value.subarray(offset, offset + size), payloadOffset);
135
+ offset += size;
136
+ payloadOffset += size;
137
+ if (payloadOffset === data.length) {
138
+ consume(data);
139
+ headerOffset = 0;
140
+ payload = undefined;
141
+ }
142
+ }
143
+ }
144
+ if (deadline.aborted)
145
+ throw new ServerComponentError(signal.aborted ? "component_cancelled" : "component_timeout", 504);
146
+ if (!terminal || headerOffset !== 0 || payload !== undefined)
147
+ throw new ServerComponentError("component_protocol", 400);
148
+ const merged = new Uint8Array(bodyBytes);
149
+ let offset = 0;
150
+ for (const chunk of body) {
151
+ merged.set(chunk, offset);
152
+ offset += chunk.length;
153
+ }
154
+ return { metadata, value: JSON.parse(decoder.decode(merged)) };
155
+ }
156
+ catch (error) {
157
+ await reader.cancel().catch(() => {
158
+ /* Preserve the first protocol/read failure. */
159
+ });
160
+ if (error instanceof ServerComponentError)
161
+ throw error;
162
+ throw new ServerComponentError("component_protocol", 400);
163
+ }
164
+ finally {
165
+ deadline.removeEventListener("abort", cancel);
166
+ reader.releaseLock();
167
+ }
168
+ }
169
+ //# sourceMappingURL=frames.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frames.js","sourceRoot":"","sources":["../../src/server-components/frames.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /** The same decoded-attribute policy applies before SSR and before DOM insertion. */
2
+ export declare function validateComponentTag(tag: string, attributes: readonly {
3
+ name: string;
4
+ value: string;
5
+ }[], assets?: ReadonlySet<string>): void;
6
+ //# sourceMappingURL=html-policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html-policy.d.ts","sourceRoot":"","sources":["../../src/server-components/html-policy.ts"],"names":[],"mappings":"AA0DA,qFAAqF;AACrF,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,SAAS;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,EACtD,MAAM,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,GAC3B,IAAI,CA8BN"}
@@ -0,0 +1,75 @@
1
+ import { ServerComponentError } from "./error.js";
2
+ const forbidden = new Set([
3
+ "script",
4
+ "iframe",
5
+ "object",
6
+ "embed",
7
+ "applet",
8
+ "base",
9
+ "meta",
10
+ "link",
11
+ "style",
12
+ "template",
13
+ "noscript",
14
+ "xmp",
15
+ "noembed",
16
+ "noframes",
17
+ "plaintext",
18
+ "frame",
19
+ "frameset",
20
+ "animate",
21
+ "animatemotion",
22
+ "animatetransform",
23
+ "set",
24
+ ]);
25
+ const urls = new Set([
26
+ "href",
27
+ "src",
28
+ "xlink:href",
29
+ "action",
30
+ "formaction",
31
+ "poster",
32
+ "background",
33
+ "cite",
34
+ "data",
35
+ "codebase",
36
+ ]);
37
+ const fail = () => {
38
+ throw new ServerComponentError("component_protocol", 400);
39
+ };
40
+ function css(value) {
41
+ return (value
42
+ .replace(/\/\*[\s\S]*?\*\//g, "")
43
+ .replace(/\\([0-9a-f]{1,6})\s?|\\([^\r\n])/gi, (_all, hex, char) => hex === undefined
44
+ ? (char ?? "")
45
+ : String.fromCodePoint(Math.min(parseInt(hex, 16), 0x10ffff)))
46
+ // biome-ignore lint/suspicious/noControlCharactersInRegex: URL/CSS schemes must be checked after stripping ASCII controls.
47
+ .replace(/[\u0000-\u0020\u007f]/g, "")
48
+ .toLowerCase());
49
+ }
50
+ /** The same decoded-attribute policy applies before SSR and before DOM insertion. */
51
+ export function validateComponentTag(tag, attributes, assets) {
52
+ if (tag.toLowerCase() === "link" && assets !== undefined) {
53
+ const attrs = new Map(attributes.map((attribute) => [attribute.name.toLowerCase(), attribute.value]));
54
+ if (!["preload", "modulepreload"].includes(attrs.get("rel") ?? "") ||
55
+ !assets.has(attrs.get("href") ?? "") ||
56
+ [...attrs.keys()].some((name) => !["rel", "href", "as", "crossorigin", "fetchpriority"].includes(name)))
57
+ fail();
58
+ return;
59
+ }
60
+ if (forbidden.has(tag.toLowerCase()))
61
+ fail();
62
+ for (const attribute of attributes) {
63
+ const name = attribute.name.toLowerCase();
64
+ // biome-ignore lint/suspicious/noControlCharactersInRegex: Browsers discard these controls when interpreting URL schemes.
65
+ const value = attribute.value.replace(/[\u0000-\u0020\u007f]/g, "").toLowerCase();
66
+ if (name.startsWith("on") || ["srcdoc", "is", "srcset", "ping"].includes(name))
67
+ fail();
68
+ if (urls.has(name) && /^(?:javascript|vbscript|data):/.test(value))
69
+ fail();
70
+ if (name === "style" &&
71
+ /expression\(|@import|(?:javascript|vbscript|data):|-moz-binding|behavior:/.test(css(attribute.value)))
72
+ fail();
73
+ }
74
+ }
75
+ //# sourceMappingURL=html-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html-policy.js","sourceRoot":"","sources":["../../src/server-components/html-policy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare function validateComponentHTML(html: string, assets?: ReadonlySet<string>): void;
2
+ /** React may produce resource hints while decoding Flight. They are not owned range nodes. */
3
+ export declare function componentRangeHTML(html: string, assets: ReadonlySet<string>): string;
4
+ //# sourceMappingURL=html.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../src/server-components/html.ts"],"names":[],"mappings":"AAgEA,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,IAAI,CAEtF;AAED,8FAA8F;AAC9F,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,MAAM,CAWpF"}
@@ -0,0 +1,67 @@
1
+ import { Tokenizer } from "parse5";
2
+ import { ServerComponentError } from "./error.js";
3
+ import { validateComponentTag } from "./html-policy.js";
4
+ import { COMPONENT_LIMITS } from "./protocol.js";
5
+ /**
6
+ * A browser reads `title` and `textarea` content as RCDATA, where `<!--` and tags are text, but
7
+ * only in an HTML context; a bare tokenizer never switches. Content holding no `<` before its own
8
+ * end tag tokenizes the same either way, so requiring that keeps this check exact wherever the
9
+ * HTML is inserted. Every other text-mode element is forbidden outright.
10
+ */
11
+ function closesAsText(html, tag, from) {
12
+ const next = html.indexOf("<", from);
13
+ const after = next + 2 + tag.length;
14
+ return (next !== -1 &&
15
+ html.slice(next, after).toLowerCase() === `</${tag}` &&
16
+ /^[\t\n\f />]$/.test(html[after] ?? ""));
17
+ }
18
+ /** Tokenization validates attributes even in SVG/table contexts a document parser may discard. */
19
+ function tokenize(html, assets, hints) {
20
+ if (new TextEncoder().encode(html).length > COMPONENT_LIMITS.outputBytes)
21
+ throw new ServerComponentError("component_limit", 413);
22
+ const tokenizer = new Tokenizer({ sourceCodeLocationInfo: true }, {
23
+ onStartTag(token) {
24
+ validateComponentTag(token.tagName, token.attrs, assets);
25
+ if ((token.tagName === "title" || token.tagName === "textarea") &&
26
+ (token.location === null || !closesAsText(html, token.tagName, token.location.endOffset)))
27
+ throw new ServerComponentError("component_protocol", 400);
28
+ if (token.tagName === "link" && token.location !== null)
29
+ hints?.push({ start: token.location.startOffset, end: token.location.endOffset });
30
+ },
31
+ onEndTag() { },
32
+ onComment() { },
33
+ onEof() { },
34
+ onCharacter() { },
35
+ onWhitespaceCharacter() { },
36
+ onNullCharacter() {
37
+ throw new ServerComponentError("component_protocol", 400);
38
+ },
39
+ onDoctype() {
40
+ throw new ServerComponentError("component_protocol", 400);
41
+ },
42
+ onParseError(error) {
43
+ // `<!>` (Solid's template markers, `<!$>` and `<!/>` too) is a comment to the tokenizer and to
44
+ // every browser alike; any other parse error is refused.
45
+ if (error.code !== "incorrectly-opened-comment")
46
+ throw new ServerComponentError("component_protocol", 400);
47
+ },
48
+ });
49
+ tokenizer.write(html, true);
50
+ }
51
+ export function validateComponentHTML(html, assets) {
52
+ tokenize(html, assets);
53
+ }
54
+ /** React may produce resource hints while decoding Flight. They are not owned range nodes. */
55
+ export function componentRangeHTML(html, assets) {
56
+ const hints = [];
57
+ tokenize(html, assets, hints);
58
+ const parts = [];
59
+ let offset = 0;
60
+ for (const hint of hints) {
61
+ parts.push(html.slice(offset, hint.start));
62
+ offset = hint.end;
63
+ }
64
+ parts.push(html.slice(offset));
65
+ return parts.join("");
66
+ }
67
+ //# sourceMappingURL=html.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/server-components/html.ts"],"names":[],"mappings":"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"}