@nifrajs/web 4.0.2 → 5.1.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 (426) hide show
  1. package/README.md +19 -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 +6 -6
  15. package/dist/client.d.ts.map +1 -1
  16. package/dist/client.js +46 -18
  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-port.d.ts +3 -2
  26. package/dist/dev-port.d.ts.map +1 -1
  27. package/dist/dev-port.js +2 -6
  28. package/dist/dev-port.js.map +1 -1
  29. package/dist/dev-session.d.ts.map +1 -1
  30. package/dist/dev-session.js +4 -14
  31. package/dist/dev-session.js.map +1 -1
  32. package/dist/dev.d.ts +7 -17
  33. package/dist/dev.d.ts.map +1 -1
  34. package/dist/dev.js +13 -1
  35. package/dist/dev.js.map +1 -1
  36. package/dist/draft.d.ts +8 -5
  37. package/dist/draft.d.ts.map +1 -1
  38. package/dist/draft.js +30 -13
  39. package/dist/draft.js.map +1 -1
  40. package/dist/fonts-google.d.ts.map +1 -1
  41. package/dist/fonts-google.js +7 -0
  42. package/dist/fonts-google.js.map +1 -1
  43. package/dist/index.d.ts +5 -4
  44. package/dist/index.d.ts.map +1 -1
  45. package/dist/index.js +4 -3
  46. package/dist/index.js.map +1 -1
  47. package/dist/internal/codegen.d.ts +1 -0
  48. package/dist/internal/codegen.d.ts.map +1 -1
  49. package/dist/internal/codegen.js +56 -29
  50. package/dist/internal/codegen.js.map +1 -1
  51. package/dist/internal/disposable-dir.d.ts +8 -0
  52. package/dist/internal/disposable-dir.d.ts.map +1 -0
  53. package/dist/internal/disposable-dir.js +25 -0
  54. package/dist/internal/disposable-dir.js.map +1 -0
  55. package/dist/internal/entry-chunks.d.ts +9 -0
  56. package/dist/internal/entry-chunks.d.ts.map +1 -0
  57. package/dist/internal/entry-chunks.js +15 -0
  58. package/dist/internal/entry-chunks.js.map +1 -0
  59. package/dist/internal/evidence-traversal.d.ts +12 -0
  60. package/dist/internal/evidence-traversal.d.ts.map +1 -0
  61. package/dist/internal/evidence-traversal.js +48 -0
  62. package/dist/internal/evidence-traversal.js.map +1 -0
  63. package/dist/internal/head-merge.d.ts +6 -0
  64. package/dist/internal/head-merge.d.ts.map +1 -1
  65. package/dist/internal/head-merge.js +9 -0
  66. package/dist/internal/head-merge.js.map +1 -1
  67. package/dist/internal/js-string.d.ts +2 -0
  68. package/dist/internal/js-string.d.ts.map +1 -1
  69. package/dist/internal/js-string.js +5 -1
  70. package/dist/internal/js-string.js.map +1 -1
  71. package/dist/internal/mount-shadow.js +1 -1
  72. package/dist/internal/mount-shadow.js.map +1 -1
  73. package/dist/internal/output-guard.d.ts +7 -0
  74. package/dist/internal/output-guard.d.ts.map +1 -1
  75. package/dist/internal/output-guard.js +80 -8
  76. package/dist/internal/output-guard.js.map +1 -1
  77. package/dist/internal/package-entries.d.ts +34 -0
  78. package/dist/internal/package-entries.d.ts.map +1 -0
  79. package/dist/internal/package-entries.js +324 -0
  80. package/dist/internal/package-entries.js.map +1 -0
  81. package/dist/internal/page-execution.d.ts +6 -0
  82. package/dist/internal/page-execution.d.ts.map +1 -1
  83. package/dist/internal/page-execution.js +437 -114
  84. package/dist/internal/page-execution.js.map +1 -1
  85. package/dist/internal/parity.d.ts.map +1 -1
  86. package/dist/internal/parity.js +15 -2
  87. package/dist/internal/parity.js.map +1 -1
  88. package/dist/internal/private-env.d.ts +8 -0
  89. package/dist/internal/private-env.d.ts.map +1 -1
  90. package/dist/internal/private-env.js +25 -10
  91. package/dist/internal/private-env.js.map +1 -1
  92. package/dist/internal/progressive-cookies.d.ts +14 -0
  93. package/dist/internal/progressive-cookies.d.ts.map +1 -0
  94. package/dist/internal/progressive-cookies.js +43 -0
  95. package/dist/internal/progressive-cookies.js.map +1 -0
  96. package/dist/internal/public-env.d.ts +2 -0
  97. package/dist/internal/public-env.d.ts.map +1 -0
  98. package/dist/internal/public-env.js +13 -0
  99. package/dist/internal/public-env.js.map +1 -0
  100. package/dist/internal/render-document.d.ts +5 -44
  101. package/dist/internal/render-document.d.ts.map +1 -1
  102. package/dist/internal/render-document.js +51 -63
  103. package/dist/internal/render-document.js.map +1 -1
  104. package/dist/internal/response-controls.d.ts +2 -0
  105. package/dist/internal/response-controls.d.ts.map +1 -1
  106. package/dist/internal/response-controls.js +26 -16
  107. package/dist/internal/response-controls.js.map +1 -1
  108. package/dist/internal/revive-dates.d.ts +16 -0
  109. package/dist/internal/revive-dates.d.ts.map +1 -0
  110. package/dist/internal/revive-dates.js +32 -0
  111. package/dist/internal/revive-dates.js.map +1 -0
  112. package/dist/internal/route-path.d.ts +14 -0
  113. package/dist/internal/route-path.d.ts.map +1 -0
  114. package/dist/internal/route-path.js +19 -0
  115. package/dist/internal/route-path.js.map +1 -0
  116. package/dist/internal/secret-scan.d.ts.map +1 -1
  117. package/dist/internal/secret-scan.js +190 -20
  118. package/dist/internal/secret-scan.js.map +1 -1
  119. package/dist/internal/server-boundary.d.ts.map +1 -1
  120. package/dist/internal/server-boundary.js +33 -5
  121. package/dist/internal/server-boundary.js.map +1 -1
  122. package/dist/internal/web-app.d.ts +25 -18
  123. package/dist/internal/web-app.d.ts.map +1 -1
  124. package/dist/internal/web-app.js +81 -24
  125. package/dist/internal/web-app.js.map +1 -1
  126. package/dist/internal/wire-date.d.ts +3 -0
  127. package/dist/internal/wire-date.d.ts.map +1 -0
  128. package/dist/internal/wire-date.js +14 -0
  129. package/dist/internal/wire-date.js.map +1 -0
  130. package/dist/internal/without-query.d.ts +4 -0
  131. package/dist/internal/without-query.d.ts.map +1 -0
  132. package/dist/internal/without-query.js +9 -0
  133. package/dist/internal/without-query.js.map +1 -0
  134. package/dist/internal/zone-graph.d.ts +4 -0
  135. package/dist/internal/zone-graph.d.ts.map +1 -1
  136. package/dist/internal/zone-graph.js +71 -20
  137. package/dist/internal/zone-graph.js.map +1 -1
  138. package/dist/isr.d.ts +59 -3
  139. package/dist/isr.d.ts.map +1 -1
  140. package/dist/isr.js +311 -41
  141. package/dist/isr.js.map +1 -1
  142. package/dist/llms-txt.d.ts +2 -0
  143. package/dist/llms-txt.d.ts.map +1 -1
  144. package/dist/llms-txt.js +29 -3
  145. package/dist/llms-txt.js.map +1 -1
  146. package/dist/manifest.d.ts +37 -4
  147. package/dist/manifest.d.ts.map +1 -1
  148. package/dist/manifest.js +4 -0
  149. package/dist/manifest.js.map +1 -1
  150. package/dist/open-resolved.d.ts +18 -0
  151. package/dist/open-resolved.d.ts.map +1 -0
  152. package/dist/open-resolved.js +62 -0
  153. package/dist/open-resolved.js.map +1 -0
  154. package/dist/plugins/kit.d.ts +1 -0
  155. package/dist/plugins/kit.d.ts.map +1 -1
  156. package/dist/plugins/kit.js +26 -11
  157. package/dist/plugins/kit.js.map +1 -1
  158. package/dist/plugins/vite-leak-guard.d.ts +9 -1
  159. package/dist/plugins/vite-leak-guard.d.ts.map +1 -1
  160. package/dist/plugins/vite-leak-guard.js +84 -7
  161. package/dist/plugins/vite-leak-guard.js.map +1 -1
  162. package/dist/plugins/vite-zone-guard.d.ts.map +1 -1
  163. package/dist/plugins/vite-zone-guard.js +17 -21
  164. package/dist/plugins/vite-zone-guard.js.map +1 -1
  165. package/dist/plugins/zone-guard.d.ts.map +1 -1
  166. package/dist/plugins/zone-guard.js +44 -3
  167. package/dist/plugins/zone-guard.js.map +1 -1
  168. package/dist/prerender.d.ts +5 -1
  169. package/dist/prerender.d.ts.map +1 -1
  170. package/dist/prerender.js +41 -19
  171. package/dist/prerender.js.map +1 -1
  172. package/dist/public-dir.d.ts +8 -1
  173. package/dist/public-dir.d.ts.map +1 -1
  174. package/dist/public-dir.js +17 -6
  175. package/dist/public-dir.js.map +1 -1
  176. package/dist/query.d.ts +13 -4
  177. package/dist/query.d.ts.map +1 -1
  178. package/dist/query.js +89 -26
  179. package/dist/query.js.map +1 -1
  180. package/dist/render-seam.d.ts +25 -2
  181. package/dist/render-seam.d.ts.map +1 -1
  182. package/dist/render-seam.js +1 -0
  183. package/dist/render-seam.js.map +1 -1
  184. package/dist/route-types.d.ts.map +1 -1
  185. package/dist/route-types.js +20 -9
  186. package/dist/route-types.js.map +1 -1
  187. package/dist/router.d.ts +9 -2
  188. package/dist/router.d.ts.map +1 -1
  189. package/dist/router.js +47 -50
  190. package/dist/router.js.map +1 -1
  191. package/dist/seo.d.ts +49 -0
  192. package/dist/seo.d.ts.map +1 -0
  193. package/dist/seo.js +48 -0
  194. package/dist/seo.js.map +1 -0
  195. package/dist/server-components/build-info.d.ts +3 -0
  196. package/dist/server-components/build-info.d.ts.map +1 -0
  197. package/dist/server-components/build-info.js +7 -0
  198. package/dist/server-components/build-info.js.map +1 -0
  199. package/dist/server-components/build-target.d.ts +12 -0
  200. package/dist/server-components/build-target.d.ts.map +1 -0
  201. package/dist/server-components/build-target.js +153 -0
  202. package/dist/server-components/build-target.js.map +1 -0
  203. package/dist/server-components/build.d.ts +24 -0
  204. package/dist/server-components/build.d.ts.map +1 -0
  205. package/dist/server-components/build.js +366 -0
  206. package/dist/server-components/build.js.map +1 -0
  207. package/dist/server-components/bundle-proof.d.ts +3 -0
  208. package/dist/server-components/bundle-proof.d.ts.map +1 -0
  209. package/dist/server-components/bundle-proof.js +23 -0
  210. package/dist/server-components/bundle-proof.js.map +1 -0
  211. package/dist/server-components/client.d.ts +46 -0
  212. package/dist/server-components/client.d.ts.map +1 -0
  213. package/dist/server-components/client.js +594 -0
  214. package/dist/server-components/client.js.map +1 -0
  215. package/dist/server-components/definition.d.ts +11 -0
  216. package/dist/server-components/definition.d.ts.map +1 -0
  217. package/dist/server-components/definition.js +94 -0
  218. package/dist/server-components/definition.js.map +1 -0
  219. package/dist/server-components/dev-http.d.ts +5 -0
  220. package/dist/server-components/dev-http.d.ts.map +1 -0
  221. package/dist/server-components/dev-http.js +71 -0
  222. package/dist/server-components/dev-http.js.map +1 -0
  223. package/dist/server-components/error.d.ts +9 -0
  224. package/dist/server-components/error.d.ts.map +1 -0
  225. package/dist/server-components/error.js +24 -0
  226. package/dist/server-components/error.js.map +1 -0
  227. package/dist/server-components/frames.d.ts +7 -0
  228. package/dist/server-components/frames.d.ts.map +1 -0
  229. package/dist/server-components/frames.js +169 -0
  230. package/dist/server-components/frames.js.map +1 -0
  231. package/dist/server-components/html-policy.d.ts +6 -0
  232. package/dist/server-components/html-policy.d.ts.map +1 -0
  233. package/dist/server-components/html-policy.js +75 -0
  234. package/dist/server-components/html-policy.js.map +1 -0
  235. package/dist/server-components/html.d.ts +4 -0
  236. package/dist/server-components/html.d.ts.map +1 -0
  237. package/dist/server-components/html.js +67 -0
  238. package/dist/server-components/html.js.map +1 -0
  239. package/dist/server-components/islands.d.ts +44 -0
  240. package/dist/server-components/islands.d.ts.map +1 -0
  241. package/dist/server-components/islands.js +42 -0
  242. package/dist/server-components/islands.js.map +1 -0
  243. package/dist/server-components/native.d.ts +4 -0
  244. package/dist/server-components/native.d.ts.map +1 -0
  245. package/dist/server-components/native.js +81 -0
  246. package/dist/server-components/native.js.map +1 -0
  247. package/dist/server-components/portal.d.ts +6 -0
  248. package/dist/server-components/portal.d.ts.map +1 -0
  249. package/dist/server-components/portal.js +35 -0
  250. package/dist/server-components/portal.js.map +1 -0
  251. package/dist/server-components/props.d.ts +3 -0
  252. package/dist/server-components/props.d.ts.map +1 -0
  253. package/dist/server-components/props.js +14 -0
  254. package/dist/server-components/props.js.map +1 -0
  255. package/dist/server-components/protocol.d.ts +44 -0
  256. package/dist/server-components/protocol.d.ts.map +1 -0
  257. package/dist/server-components/protocol.js +139 -0
  258. package/dist/server-components/protocol.js.map +1 -0
  259. package/dist/server-components/range.d.ts +24 -0
  260. package/dist/server-components/range.d.ts.map +1 -0
  261. package/dist/server-components/range.js +263 -0
  262. package/dist/server-components/range.js.map +1 -0
  263. package/dist/server-components/registry.d.ts +6 -0
  264. package/dist/server-components/registry.d.ts.map +1 -0
  265. package/dist/server-components/registry.js +30 -0
  266. package/dist/server-components/registry.js.map +1 -0
  267. package/dist/server-components/response.d.ts +4 -0
  268. package/dist/server-components/response.d.ts.map +1 -0
  269. package/dist/server-components/response.js +32 -0
  270. package/dist/server-components/response.js.map +1 -0
  271. package/dist/server-components/router-integration.d.ts +9 -0
  272. package/dist/server-components/router-integration.d.ts.map +1 -0
  273. package/dist/server-components/router-integration.js +29 -0
  274. package/dist/server-components/router-integration.js.map +1 -0
  275. package/dist/server-components/runtime.d.ts +14 -0
  276. package/dist/server-components/runtime.d.ts.map +1 -0
  277. package/dist/server-components/runtime.js +276 -0
  278. package/dist/server-components/runtime.js.map +1 -0
  279. package/dist/server-components/scheduler.d.ts +14 -0
  280. package/dist/server-components/scheduler.d.ts.map +1 -0
  281. package/dist/server-components/scheduler.js +74 -0
  282. package/dist/server-components/scheduler.js.map +1 -0
  283. package/dist/server-components/schema.d.ts +4 -0
  284. package/dist/server-components/schema.d.ts.map +1 -0
  285. package/dist/server-components/schema.js +77 -0
  286. package/dist/server-components/schema.js.map +1 -0
  287. package/dist/server-components/server-entry.d.ts +12 -0
  288. package/dist/server-components/server-entry.d.ts.map +1 -0
  289. package/dist/server-components/server-entry.js +90 -0
  290. package/dist/server-components/server-entry.js.map +1 -0
  291. package/dist/server-components/source.d.ts +15 -0
  292. package/dist/server-components/source.d.ts.map +1 -0
  293. package/dist/server-components/source.js +269 -0
  294. package/dist/server-components/source.js.map +1 -0
  295. package/dist/server-components/state.d.ts +4 -0
  296. package/dist/server-components/state.d.ts.map +1 -0
  297. package/dist/server-components/state.js +123 -0
  298. package/dist/server-components/state.js.map +1 -0
  299. package/dist/server-components/stream.d.ts +6 -0
  300. package/dist/server-components/stream.d.ts.map +1 -0
  301. package/dist/server-components/stream.js +70 -0
  302. package/dist/server-components/stream.js.map +1 -0
  303. package/dist/server-components/trusted-html.d.ts +3 -0
  304. package/dist/server-components/trusted-html.d.ts.map +1 -0
  305. package/dist/server-components/trusted-html.js +14 -0
  306. package/dist/server-components/trusted-html.js.map +1 -0
  307. package/dist/server-components/types.d.ts +107 -0
  308. package/dist/server-components/types.d.ts.map +1 -0
  309. package/dist/server-components/types.js +2 -0
  310. package/dist/server-components/types.js.map +1 -0
  311. package/dist/server-components/typescript.d.ts +11 -0
  312. package/dist/server-components/typescript.d.ts.map +1 -0
  313. package/dist/server-components/typescript.js +28 -0
  314. package/dist/server-components/typescript.js.map +1 -0
  315. package/dist/server-components/value.d.ts +5 -0
  316. package/dist/server-components/value.d.ts.map +1 -0
  317. package/dist/server-components/value.js +77 -0
  318. package/dist/server-components/value.js.map +1 -0
  319. package/dist/server-components/vite.d.ts +12 -0
  320. package/dist/server-components/vite.d.ts.map +1 -0
  321. package/dist/server-components/vite.js +197 -0
  322. package/dist/server-components/vite.js.map +1 -0
  323. package/dist/server-components.d.ts +5 -0
  324. package/dist/server-components.d.ts.map +1 -0
  325. package/dist/server-components.js +4 -0
  326. package/dist/server-components.js.map +1 -0
  327. package/dist/service-worker.d.ts +8 -1
  328. package/dist/service-worker.d.ts.map +1 -1
  329. package/dist/service-worker.js +20 -6
  330. package/dist/service-worker.js.map +1 -1
  331. package/dist/vite.d.ts +12 -0
  332. package/dist/vite.d.ts.map +1 -1
  333. package/dist/vite.js +7 -1
  334. package/dist/vite.js.map +1 -1
  335. package/dist/zones.d.ts +64 -2
  336. package/dist/zones.d.ts.map +1 -1
  337. package/dist/zones.js +331 -28
  338. package/dist/zones.js.map +1 -1
  339. package/package.json +102 -4
  340. package/src/build-vite.ts +31 -9
  341. package/src/build.ts +109 -31
  342. package/src/cdn.ts +18 -12
  343. package/src/client.ts +48 -17
  344. package/src/deferred.ts +27 -9
  345. package/src/dev-feed.ts +24 -5
  346. package/src/dev-port.ts +4 -10
  347. package/src/dev-session.ts +4 -13
  348. package/src/dev.ts +29 -1
  349. package/src/draft.ts +35 -14
  350. package/src/fonts-google.ts +10 -0
  351. package/src/index.ts +5 -6
  352. package/src/internal/codegen.ts +60 -29
  353. package/src/internal/disposable-dir.ts +24 -0
  354. package/src/internal/entry-chunks.ts +18 -0
  355. package/src/internal/evidence-traversal.ts +57 -0
  356. package/src/internal/head-merge.ts +16 -0
  357. package/src/internal/js-string.ts +6 -1
  358. package/src/internal/mount-shadow.ts +1 -1
  359. package/src/internal/output-guard.ts +88 -7
  360. package/src/internal/package-entries.ts +331 -0
  361. package/src/internal/page-execution.ts +573 -114
  362. package/src/internal/parity.ts +15 -2
  363. package/src/internal/private-env.ts +27 -13
  364. package/src/internal/progressive-cookies.ts +60 -0
  365. package/src/internal/public-env.ts +14 -0
  366. package/src/internal/render-document.ts +66 -89
  367. package/src/internal/response-controls.ts +31 -14
  368. package/src/internal/revive-dates.ts +35 -0
  369. package/src/internal/route-path.ts +24 -0
  370. package/src/internal/secret-scan.ts +190 -18
  371. package/src/internal/server-boundary.ts +29 -5
  372. package/src/internal/web-app.ts +126 -42
  373. package/src/internal/wire-date.ts +16 -0
  374. package/src/internal/without-query.ts +8 -0
  375. package/src/internal/zone-graph.ts +78 -25
  376. package/src/isr.ts +364 -45
  377. package/src/llms-txt.ts +32 -3
  378. package/src/manifest.ts +38 -4
  379. package/src/open-resolved.ts +64 -0
  380. package/src/plugins/kit.ts +31 -11
  381. package/src/plugins/vite-leak-guard.ts +104 -8
  382. package/src/plugins/vite-zone-guard.ts +21 -19
  383. package/src/plugins/zone-guard.ts +41 -2
  384. package/src/prerender.ts +39 -18
  385. package/src/public-dir.ts +27 -8
  386. package/src/query.ts +107 -26
  387. package/src/render-seam.ts +30 -2
  388. package/src/route-types.ts +34 -7
  389. package/src/router.ts +66 -59
  390. package/src/seo.ts +68 -0
  391. package/src/server-components/build-info.ts +11 -0
  392. package/src/server-components/build-target.ts +194 -0
  393. package/src/server-components/build.ts +419 -0
  394. package/src/server-components/bundle-proof.ts +33 -0
  395. package/src/server-components/client.ts +663 -0
  396. package/src/server-components/definition.ts +125 -0
  397. package/src/server-components/dev-http.ts +75 -0
  398. package/src/server-components/error.ts +24 -0
  399. package/src/server-components/frames.ts +181 -0
  400. package/src/server-components/html-policy.ts +94 -0
  401. package/src/server-components/html.ts +81 -0
  402. package/src/server-components/islands.ts +111 -0
  403. package/src/server-components/native.ts +101 -0
  404. package/src/server-components/portal.ts +42 -0
  405. package/src/server-components/props.ts +19 -0
  406. package/src/server-components/protocol.ts +167 -0
  407. package/src/server-components/range.ts +313 -0
  408. package/src/server-components/registry.ts +34 -0
  409. package/src/server-components/response.ts +44 -0
  410. package/src/server-components/router-integration.ts +40 -0
  411. package/src/server-components/runtime.ts +376 -0
  412. package/src/server-components/scheduler.ts +84 -0
  413. package/src/server-components/schema.ts +69 -0
  414. package/src/server-components/server-entry.ts +98 -0
  415. package/src/server-components/source.ts +324 -0
  416. package/src/server-components/state.ts +143 -0
  417. package/src/server-components/stream.ts +71 -0
  418. package/src/server-components/trusted-html.ts +21 -0
  419. package/src/server-components/types.ts +138 -0
  420. package/src/server-components/typescript.ts +39 -0
  421. package/src/server-components/value.ts +82 -0
  422. package/src/server-components/vite.ts +242 -0
  423. package/src/server-components.ts +32 -0
  424. package/src/service-worker.ts +24 -7
  425. package/src/vite.ts +8 -1
  426. package/src/zones.ts +418 -32
@@ -0,0 +1,419 @@
1
+ import { createHash, randomBytes } from "node:crypto"
2
+ import { existsSync, readdirSync, readFileSync } from "node:fs"
3
+ import { mkdtemp, rename, rm } from "node:fs/promises"
4
+ import { relative, resolve } from "node:path"
5
+ import { fileURLToPath } from "node:url"
6
+ import {
7
+ createBuilder,
8
+ createServer,
9
+ loadEnv,
10
+ type Plugin,
11
+ type PluginOption,
12
+ type UserConfig,
13
+ version as viteVersion,
14
+ } from "vite"
15
+ import { codeUnitOrder } from "../internal/code-unit-order.ts"
16
+ import { assertDisposableDir } from "../internal/disposable-dir.ts"
17
+ import { publicEnvDefines } from "../internal/public-env.ts"
18
+ import { buildEnvironment } from "../internal/secret-scan.ts"
19
+ import { vitePublicEnvPrefix } from "../internal/server-boundary.ts"
20
+ import { unsupportedBuiltin } from "../internal/target-compat.ts"
21
+ import {
22
+ viteAssetUrlGuard,
23
+ viteBareBuiltinExternal,
24
+ viteLeakGuard,
25
+ viteServerZoneGuard,
26
+ } from "../plugins/vite-leak-guard.ts"
27
+ import { viteServerFnStub } from "../plugins/vite-server-fn.ts"
28
+ import { viteZoneGuard } from "../plugins/vite-zone-guard.ts"
29
+ import { assembleComponentTarget, type ComponentBuildResult } from "./build-target.ts"
30
+ import { componentBundleImports } from "./bundle-proof.ts"
31
+ import { installComponentDevHandler } from "./dev-http.ts"
32
+ import { serverComponentsPlugin } from "./vite.ts"
33
+
34
+ const sourceProofs = new WeakMap<UserConfig, ReadonlyMap<string, string>>()
35
+
36
+ function compilerGeneration(): string {
37
+ const extension = import.meta.url.endsWith(".ts") ? "ts" : "js"
38
+ const hash = createHash("sha256").update(viteVersion)
39
+ // Compiler-only modules do not enter the application graph, but their changes invalidate its ABI.
40
+ for (const name of ["build", "vite", "source", "build-target", "bundle-proof", "server-entry"])
41
+ hash.update(readFileSync(fileURLToPath(new URL(`./${name}.${extension}`, import.meta.url))))
42
+ return hash.digest("hex")
43
+ }
44
+
45
+ export interface ComponentPipelineOptions {
46
+ readonly root: string
47
+ readonly adapter: "react" | "vue" | "svelte" | "solid" | "preact"
48
+ readonly entries: { readonly client: string; readonly ssr: string; readonly rsc?: string }
49
+ readonly plugins?: readonly PluginOption[]
50
+ readonly outDir?: string
51
+ readonly port?: number
52
+ readonly publicEnvPrefix?: string
53
+ /** The deployment target (default `"bun"`, as `nifra build`'s): compiled for and assembled as one. */
54
+ readonly target?: "bun" | "node" | "deno" | "cloudflare" | "vercel"
55
+ }
56
+
57
+ /** One content-derived generation for every environment; no payloads or paths are published. */
58
+ export function componentBuildId(root: string, outDir = "dist"): string {
59
+ const digest = createHash("sha256").update("nifra-components-v1")
60
+ const output = resolve(root, outDir)
61
+ let count = 0
62
+ const walk = (directory: string): void => {
63
+ for (const entry of readdirSync(directory, { withFileTypes: true }).sort((a, b) =>
64
+ codeUnitOrder(a.name, b.name),
65
+ )) {
66
+ if (entry.name.startsWith(".") || ["node_modules", "dist", "build"].includes(entry.name))
67
+ continue
68
+ const file = resolve(directory, entry.name)
69
+ if (file === output) continue
70
+ if (entry.isDirectory()) walk(file)
71
+ else if (entry.isFile() && /\.(?:[cm]?[jt]sx?|vue|svelte|css|json|lock)$/.test(entry.name)) {
72
+ if (++count > 10000)
73
+ throw new Error("[nifra/components] Component source graph exceeds 10000 files")
74
+ digest
75
+ .update(relative(root, file).replaceAll("\\", "/"))
76
+ .update("\0")
77
+ .update(readFileSync(file))
78
+ .update("\0")
79
+ }
80
+ }
81
+ }
82
+ walk(resolve(root))
83
+ return `c_${digest.digest("hex")}`
84
+ }
85
+
86
+ /** Coordinated Vite 8 build/dev configuration with the ordinary Nifra boundary guards. */
87
+ export async function serverComponentsConfig(
88
+ options: ComponentPipelineOptions,
89
+ generationId?: string,
90
+ ): Promise<UserConfig> {
91
+ const root = resolve(options.root)
92
+ if (
93
+ !["react", "vue", "svelte", "solid", "preact"].includes(options.adapter) ||
94
+ (options.target !== undefined &&
95
+ !["bun", "node", "deno", "cloudflare", "vercel"].includes(options.target))
96
+ )
97
+ throw new Error("[nifra/components] Unsupported component adapter or deployment target")
98
+ const out = resolve(root, options.outDir ?? "dist")
99
+ if (out === root)
100
+ throw new Error("[nifra/components] The output directory must differ from the application root")
101
+ const entries = Object.fromEntries(
102
+ Object.entries(options.entries).map(([name, file]) => [name, resolve(root, file)]),
103
+ )
104
+ if (
105
+ typeof entries.client !== "string" ||
106
+ typeof entries.ssr !== "string" ||
107
+ Object.values(entries).some((file) => !existsSync(file))
108
+ )
109
+ throw new Error(
110
+ "[nifra/components] Declare existing client and SSR entries; the SSR entry must export createApp(clientEntry, assets)",
111
+ )
112
+ let build = generationId ?? componentBuildId(root, options.outDir)
113
+ const sources = new Map<string, string>()
114
+ const target = options.target ?? "bun"
115
+ const edge = target === "cloudflare"
116
+ const generatedFiles = Object.values(entries)
117
+ const guards = {
118
+ appRoot: root,
119
+ root,
120
+ generatedFiles: [entries.client!],
121
+ publicEnvPrefix: options.publicEnvPrefix ?? "PUBLIC_",
122
+ }
123
+ const compiler = serverComponentsPlugin({ root, adapter: options.adapter })
124
+ // Vite reads `.env.production` too; a value only there is still the app's secret to keep.
125
+ const client = viteLeakGuard({
126
+ ...guards,
127
+ outDir: resolve(out, "client"),
128
+ secrets: { env: { ...loadEnv("production", root, ""), ...buildEnvironment() } },
129
+ })
130
+ const server = viteServerZoneGuard({
131
+ ...guards,
132
+ generatedFiles,
133
+ componentModules: compiler.api.componentModules,
134
+ })
135
+ const generation: Plugin & { api: { readonly componentSources: ReadonlyMap<string, string> } } = {
136
+ api: { componentSources: sources },
137
+ name: "nifra:component-generation",
138
+ config(_config, env) {
139
+ if (env.command === "serve") build = `d_${randomBytes(16).toString("hex")}`
140
+ const config: UserConfig = {
141
+ define: {
142
+ "process.env.NODE_ENV": JSON.stringify(
143
+ env.command === "build" ? "production" : "development",
144
+ ),
145
+ },
146
+ }
147
+ // Vue's Node entry reexports CommonJS; native loading preserves its development SSR runtime.
148
+ if (env.command === "serve" && options.adapter === "vue")
149
+ config.ssr = { external: ["vue", "@vue/server-renderer"] }
150
+ return config
151
+ },
152
+ configEnvironment(name) {
153
+ return {
154
+ define: {
155
+ __NIFRA_COMPONENT_BROWSER__: JSON.stringify(name === "client"),
156
+ __NIFRA_COMPONENT_BUILD__: JSON.stringify(build),
157
+ },
158
+ }
159
+ },
160
+ resolveId(source) {
161
+ if (source === "virtual:nifra-component-build") return "\0nifra-component-build"
162
+ return null
163
+ },
164
+ load(id) {
165
+ if (id === "\0nifra-component-build")
166
+ return `export const componentBuild = ${JSON.stringify(build)}`
167
+ return null
168
+ },
169
+ transform(source, id) {
170
+ const file = id.split("?")[0]!
171
+ if (!file.startsWith("\0") && existsSync(file)) {
172
+ if (sources.size >= 10000 && !sources.has(file))
173
+ throw new Error("[nifra/components] Component source graph exceeds 10000 modules")
174
+ sources.set(file, createHash("sha256").update(readFileSync(file)).digest("hex"))
175
+ }
176
+ if (id.split("?")[0] === entries.ssr && this.environment.name === "ssr")
177
+ return {
178
+ code:
179
+ source +
180
+ '\nexport { componentBuild as __nifraComponentBuild } from "@nifrajs/web/server-components/build-info";\n',
181
+ map: null,
182
+ }
183
+ return null
184
+ },
185
+ async handleHotUpdate(context) {
186
+ // Recreate all environments together so no warm module retains an earlier generation.
187
+ context.server.ws.send({ type: "full-reload" })
188
+ await context.server.restart()
189
+ return []
190
+ },
191
+ }
192
+ const proof: Plugin = {
193
+ name: "nifra:component-build-proof",
194
+ generateBundle(output, bundle) {
195
+ const guard = this.environment.name === "client" ? client : server
196
+ guard.generateBundle.call(this, output, bundle)
197
+ if (this.environment.name !== "client")
198
+ for (const chunk of Object.values(bundle)) {
199
+ if (chunk.type === "chunk")
200
+ for (const specifier of componentBundleImports(chunk.code)) {
201
+ if (
202
+ unsupportedBuiltin(specifier, edge ? "browser" : target === "bun" ? "bun" : "node")
203
+ ) {
204
+ const importers = [...this.getModuleIds()].filter((id) =>
205
+ this.getModuleInfo(id)?.importedIds.includes(specifier),
206
+ )
207
+ throw new Error(
208
+ `[nifra/components] ${specifier} is unsupported on ${target}; imported by ${importers.join(", ") || chunk.fileName}`,
209
+ )
210
+ }
211
+ }
212
+ }
213
+ },
214
+ }
215
+ const builtinGuard: Plugin = {
216
+ name: "nifra:component-client-builtins",
217
+ enforce: "pre",
218
+ resolveId(source, importer) {
219
+ if (this.environment.name === "client" && source.startsWith("node:"))
220
+ throw new Error(
221
+ `[nifra/components] ${source} may not reach the browser; imported by ${importer ?? "the client entry"}`,
222
+ )
223
+ return null
224
+ },
225
+ }
226
+ const plugins: UserConfig["plugins"] = [
227
+ compiler,
228
+ generation,
229
+ // biome-ignore lint/plugin/requireSafetyCommentForTypeAssertion: The shared compiler guards implement Vite hooks; the shim differs only in optional hook metadata.
230
+ viteServerFnStub() as Plugin,
231
+ builtinGuard,
232
+ // biome-ignore lint/plugin/requireSafetyCommentForTypeAssertion: The shared compiler guards implement Vite hooks; the shim differs only in optional hook metadata.
233
+ viteBareBuiltinExternal() as Plugin,
234
+ // biome-ignore lint/plugin/requireSafetyCommentForTypeAssertion: The shared compiler guards implement Vite hooks; the shim differs only in optional hook metadata.
235
+ viteAssetUrlGuard(guards) as Plugin,
236
+ // biome-ignore lint/plugin/requireSafetyCommentForTypeAssertion: The shared compiler guards implement Vite hooks; the shim differs only in optional hook metadata.
237
+ viteZoneGuard(guards) as Plugin,
238
+ ...(options.plugins ?? []),
239
+ proof,
240
+ ]
241
+ if (options.adapter === "react") {
242
+ if (entries.rsc === undefined) throw new Error("[nifra/components] React requires an RSC entry")
243
+ const { default: rsc } = await import("@vitejs/plugin-rsc")
244
+ plugins.push(rsc({ entries: { client: entries.client!, ssr: entries.ssr!, rsc: entries.rsc } }))
245
+ } else if (entries.rsc !== undefined)
246
+ throw new Error("[nifra/components] Only React uses an RSC environment")
247
+ const serverConditions = edge
248
+ ? ["module", "workerd", "edge-light", "node", "development|production"]
249
+ : ["module", "node", "development|production"]
250
+ const config: UserConfig = {
251
+ root,
252
+ plugins,
253
+ publicDir: false,
254
+ cacheDir: resolve(root, ".nifra/cache/components-vite"),
255
+ // Without it Vite inlines every `VITE_*` value from the app's .env files into client code.
256
+ envPrefix: vitePublicEnvPrefix(options.publicEnvPrefix),
257
+ define: {
258
+ ...publicEnvDefines(options.publicEnvPrefix ?? "PUBLIC_", process.env),
259
+ "process.env.NIFRA_SSR_BUNDLED": '"1"',
260
+ "globalThis.__NIFRA_EDGE_RUNTIME__": edge ? "true" : "false",
261
+ __NIFRA_COMPONENT_BUILD__: JSON.stringify(build),
262
+ },
263
+ resolve: {
264
+ dedupe: [
265
+ "react",
266
+ "react-dom",
267
+ "react-server-dom-webpack",
268
+ "vue",
269
+ "svelte",
270
+ "solid-js",
271
+ "preact",
272
+ "@nifrajs/web",
273
+ "@nifrajs/core",
274
+ ],
275
+ },
276
+ ssr: {
277
+ noExternal: true,
278
+ target: edge ? "webworker" : "node",
279
+ resolve: { conditions: serverConditions },
280
+ },
281
+ ...(options.adapter === "preact"
282
+ ? { oxc: { jsx: { runtime: "automatic", importSource: "preact" } } }
283
+ : { esbuild: { jsx: "automatic" } }),
284
+ build: { outDir: out, sourcemap: false, manifest: true, minify: true },
285
+ environments: {
286
+ client: {
287
+ consumer: "client",
288
+ build: { outDir: resolve(out, "client"), manifest: true, emptyOutDir: true },
289
+ },
290
+ ssr: {
291
+ consumer: "server",
292
+ build: {
293
+ outDir: resolve(out, options.adapter === "react" ? "ssr" : "server"),
294
+ emptyOutDir: true,
295
+ },
296
+ },
297
+ },
298
+ server: { host: "127.0.0.1", port: options.port ?? 3000, strictPort: true },
299
+ }
300
+ // These environments were constructed above; only the compiler's selected entry lane adds inputs.
301
+ const environments = config.environments!
302
+ if (edge) environments.ssr!.resolve = { conditions: serverConditions }
303
+ // Rune modules need the native TS transform before Svelte compiles them; prebundling skips it.
304
+ if (options.adapter === "svelte") config.optimizeDeps = { exclude: ["@nifrajs/web-svelte"] }
305
+ if (options.adapter === "react") {
306
+ environments.rsc = { build: { outDir: resolve(out, "rsc"), emptyOutDir: true } }
307
+ } else {
308
+ environments.client!.build!.rollupOptions = { input: entries.client! }
309
+ Object.assign(environments.ssr!.build!, {
310
+ ssr: entries.ssr!,
311
+ rollupOptions: { output: { entryFileNames: "index.js" } },
312
+ })
313
+ config.builder = {
314
+ async buildApp(builder) {
315
+ await builder.build(builder.environments.client!)
316
+ await builder.build(builder.environments.ssr!)
317
+ },
318
+ }
319
+ }
320
+ sourceProofs.set(config, sources)
321
+ return config
322
+ }
323
+
324
+ export async function buildServerComponents(
325
+ options: ComponentPipelineOptions,
326
+ ): Promise<ComponentBuildResult> {
327
+ const out = resolve(options.root, options.outDir ?? "dist")
328
+ const root = resolve(options.root)
329
+ assertDisposableDir("outDir", out, [
330
+ root,
331
+ process.cwd(),
332
+ ...Object.values(options.entries).map((file) => resolve(root, file)),
333
+ ])
334
+ const parent = resolve(out, "..")
335
+ const { mkdir } = await import("node:fs/promises")
336
+ await mkdir(parent, { recursive: true })
337
+ const stage = await mkdtemp(resolve(parent, ".nifra-components-"))
338
+ const backup = `${stage}-previous`
339
+ let previous = false
340
+ try {
341
+ const buildId = componentBuildId(options.root, options.outDir)
342
+ const compilerId = compilerGeneration()
343
+ let config = await serverComponentsConfig({ ...options, outDir: stage }, buildId)
344
+ await (await createBuilder({ ...config, configFile: false })).buildApp()
345
+ const snapshot = (value: UserConfig): ReadonlyMap<string, string> => {
346
+ const sources = sourceProofs.get(value)
347
+ if (sources === undefined) throw new Error("[nifra/components] Missing generation proof")
348
+ return sources
349
+ }
350
+ const graphId = (modules: ReadonlyMap<string, string>): string => {
351
+ const digest = createHash("sha256")
352
+ .update(buildId)
353
+ .update(compilerId)
354
+ .update(
355
+ JSON.stringify({
356
+ adapter: options.adapter,
357
+ target: options.target ?? "bun",
358
+ env: publicEnvDefines(options.publicEnvPrefix ?? "PUBLIC_", process.env),
359
+ }),
360
+ )
361
+ for (const [file, hash] of [...modules].sort(([a], [b]) => codeUnitOrder(a, b)))
362
+ digest.update(relative(options.root, file).replaceAll("\\", "/")).update("\0").update(hash)
363
+ return `c_${digest.digest("hex")}`
364
+ }
365
+ const modules = snapshot(config)
366
+ const generationId = graphId(modules)
367
+ // The analysis output is never published. Compile again with the complete dependency graph's generation.
368
+ config = await serverComponentsConfig({ ...options, outDir: stage }, generationId)
369
+ await (await createBuilder({ ...config, configFile: false })).buildApp()
370
+ if (
371
+ graphId(snapshot(config)) !== generationId ||
372
+ [...modules].some(
373
+ ([file, hash]) => createHash("sha256").update(readFileSync(file)).digest("hex") !== hash,
374
+ )
375
+ )
376
+ throw new Error("[nifra/components] Sources changed during the coordinated build")
377
+ if (buildId !== componentBuildId(options.root, options.outDir))
378
+ throw new Error(
379
+ "[nifra/components] Sources changed during the build; rebuild one complete generation",
380
+ )
381
+ if (compilerId !== compilerGeneration())
382
+ throw new Error(
383
+ "[nifra/components] Compiler changed during the build; rebuild one complete generation",
384
+ )
385
+ const result = await assembleComponentTarget({ ...options, outDir: stage }, generationId)
386
+ if (existsSync(out)) {
387
+ await rename(out, backup)
388
+ previous = true
389
+ }
390
+ try {
391
+ await rename(stage, out)
392
+ } catch (error) {
393
+ if (previous) await rename(backup, out)
394
+ throw error
395
+ }
396
+ if (previous) await rm(backup, { recursive: true, force: true })
397
+ return { ...result, outDir: out }
398
+ } catch (error) {
399
+ await rm(stage, { recursive: true, force: true })
400
+ throw error
401
+ }
402
+ }
403
+ export async function devServerComponents(
404
+ options: ComponentPipelineOptions,
405
+ ): Promise<Awaited<ReturnType<typeof createServer>>> {
406
+ const config = await serverComponentsConfig(options)
407
+ config.plugins = [
408
+ ...(config.plugins ?? []),
409
+ {
410
+ name: "nifra:component-dev-handler",
411
+ configureServer(server) {
412
+ installComponentDevHandler(server, options)
413
+ },
414
+ },
415
+ ]
416
+ const server = await createServer({ ...config, configFile: false })
417
+ await server.listen()
418
+ return server
419
+ }
@@ -0,0 +1,33 @@
1
+ import type * as TS from "typescript"
2
+ import { ts } from "./typescript.ts"
3
+
4
+ /** RSC rewrites chunks after linking; inspect emitted imports rather than stale chunk metadata. */
5
+ export function componentBundleImports(code: string): readonly string[] {
6
+ const imports = new Set<string>()
7
+ const source = ts.createSourceFile(
8
+ "component-bundle.js",
9
+ code,
10
+ ts.ScriptTarget.Latest,
11
+ true,
12
+ ts.ScriptKind.JS,
13
+ )
14
+ const visit = (node: TS.Node): void => {
15
+ if (
16
+ (ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) &&
17
+ node.moduleSpecifier !== undefined &&
18
+ ts.isStringLiteral(node.moduleSpecifier)
19
+ )
20
+ imports.add(node.moduleSpecifier.text)
21
+ if (
22
+ ts.isCallExpression(node) &&
23
+ (node.expression.kind === ts.SyntaxKind.ImportKeyword ||
24
+ (ts.isIdentifier(node.expression) && node.expression.text === "require"))
25
+ ) {
26
+ const argument = node.arguments[0]
27
+ if (argument !== undefined && ts.isStringLiteralLike(argument)) imports.add(argument.text)
28
+ }
29
+ ts.forEachChild(node, visit)
30
+ }
31
+ visit(source)
32
+ return [...imports]
33
+ }