@alloy-js/core 0.24.0-dev.2 → 0.24.0-dev.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (506) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/dev/src/components/AccessExpression.test.js +1 -1
  3. package/dist/dev/src/components/AccessExpression.test.js.map +1 -1
  4. package/dist/dev/src/components/Output.js +3 -2
  5. package/dist/dev/src/components/Output.js.map +1 -1
  6. package/dist/dev/src/components/SourceFile.js.map +1 -1
  7. package/dist/dev/src/content-slot.test.js +1 -1
  8. package/dist/dev/src/content-slot.test.js.map +1 -1
  9. package/dist/dev/src/context.js +30 -3
  10. package/dist/dev/src/context.js.map +1 -1
  11. package/dist/dev/src/debug/diagnostics.test.js +1 -1
  12. package/dist/dev/src/debug/diagnostics.test.js.map +1 -1
  13. package/dist/dev/src/debug/effects.test.js +1 -1
  14. package/dist/dev/src/debug/effects.test.js.map +1 -1
  15. package/dist/dev/src/debug/file-streaming.js +103 -0
  16. package/dist/dev/src/debug/file-streaming.js.map +1 -0
  17. package/dist/dev/src/debug/files.test.js +4 -5
  18. package/dist/dev/src/debug/files.test.js.map +1 -1
  19. package/dist/dev/src/debug/index.js +4 -6
  20. package/dist/dev/src/debug/index.js.map +1 -1
  21. package/dist/dev/src/debug/message-format.test.js +50 -52
  22. package/dist/dev/src/debug/message-format.test.js.map +1 -1
  23. package/dist/dev/src/debug/render-tree-orphans.test.js +13 -23
  24. package/dist/dev/src/debug/render-tree-orphans.test.js.map +1 -1
  25. package/dist/dev/src/debug/render.js +529 -352
  26. package/dist/dev/src/debug/render.js.map +1 -1
  27. package/dist/dev/src/debug/render.test.js +171 -92
  28. package/dist/dev/src/debug/render.test.js.map +1 -1
  29. package/dist/dev/src/debug/trace-writer.js +127 -15
  30. package/dist/dev/src/debug/trace-writer.js.map +1 -1
  31. package/dist/dev/src/debug/trace.js +0 -36
  32. package/dist/dev/src/debug/trace.js.map +1 -1
  33. package/dist/dev/src/devtools/devtools-server.js +55 -32
  34. package/dist/dev/src/devtools/devtools-server.js.map +1 -1
  35. package/dist/dev/src/devtools-entry.browser.js.map +1 -1
  36. package/dist/dev/src/devtools-entry.js.map +1 -1
  37. package/dist/dev/src/diagnostics.js +19 -1
  38. package/dist/dev/src/diagnostics.js.map +1 -1
  39. package/dist/dev/src/index.js +5 -2
  40. package/dist/dev/src/index.js.map +1 -1
  41. package/dist/dev/src/jsx-runtime.js +14 -8
  42. package/dist/dev/src/jsx-runtime.js.map +1 -1
  43. package/dist/dev/src/output-types.js +2 -0
  44. package/dist/dev/src/output-types.js.map +1 -0
  45. package/dist/dev/src/reactivity.js +155 -13
  46. package/dist/dev/src/reactivity.js.map +1 -1
  47. package/dist/dev/src/render/get-string-width.js +61 -0
  48. package/dist/dev/src/render/get-string-width.js.map +1 -0
  49. package/dist/dev/src/render/index.js +2 -0
  50. package/dist/dev/src/render/index.js.map +1 -0
  51. package/dist/dev/src/render/node-context.js +7 -0
  52. package/dist/dev/src/render/node-context.js.map +1 -0
  53. package/dist/dev/src/render/node.js +386 -0
  54. package/dist/dev/src/render/node.js.map +1 -0
  55. package/dist/dev/src/render/printer-support.js +180 -0
  56. package/dist/dev/src/render/printer-support.js.map +1 -0
  57. package/dist/dev/src/render/printer.js +797 -0
  58. package/dist/dev/src/render/printer.js.map +1 -0
  59. package/dist/dev/src/render-error.js +79 -0
  60. package/dist/dev/src/render-error.js.map +1 -0
  61. package/dist/dev/src/render-output.js +209 -0
  62. package/dist/dev/src/render-output.js.map +1 -0
  63. package/dist/dev/src/runtime/create-intrinsic.js +53 -0
  64. package/dist/dev/src/runtime/create-intrinsic.js.map +1 -0
  65. package/dist/dev/src/runtime/fragment.js +21 -0
  66. package/dist/dev/src/runtime/fragment.js.map +1 -0
  67. package/dist/dev/src/runtime/index.js +13 -0
  68. package/dist/dev/src/runtime/index.js.map +1 -0
  69. package/dist/dev/src/runtime/insert.js +453 -0
  70. package/dist/dev/src/runtime/insert.js.map +1 -0
  71. package/dist/dev/src/runtime/intrinsic.js +1 -11
  72. package/dist/dev/src/runtime/intrinsic.js.map +1 -1
  73. package/dist/dev/src/scheduler.js +38 -14
  74. package/dist/dev/src/scheduler.js.map +1 -1
  75. package/dist/dev/src/stc.js +2 -0
  76. package/dist/dev/src/stc.js.map +1 -1
  77. package/dist/dev/src/sti.js +1 -1
  78. package/dist/dev/src/sti.js.map +1 -1
  79. package/dist/dev/src/symbols/symbol-slot.test.js +1 -1
  80. package/dist/dev/src/symbols/symbol-slot.test.js.map +1 -1
  81. package/dist/dev/src/test-render.js +78 -0
  82. package/dist/dev/src/test-render.js.map +1 -0
  83. package/dist/dev/src/utils.js +47 -35
  84. package/dist/dev/src/utils.js.map +1 -1
  85. package/dist/dev/test/babel-e2e.test.js +218 -0
  86. package/dist/dev/test/babel-e2e.test.js.map +1 -0
  87. package/dist/dev/test/components/block.test.js +1 -1
  88. package/dist/dev/test/components/block.test.js.map +1 -1
  89. package/dist/dev/test/components/copy-file.test.js +7 -7
  90. package/dist/dev/test/components/copy-file.test.js.map +1 -1
  91. package/dist/dev/test/components/update-file.test.js +1 -1
  92. package/dist/dev/test/components/update-file.test.js.map +1 -1
  93. package/dist/dev/test/components/wrap.test.js +1 -1
  94. package/dist/dev/test/components/wrap.test.js.map +1 -1
  95. package/dist/dev/test/control-flow/match.test.js +1 -1
  96. package/dist/dev/test/control-flow/match.test.js.map +1 -1
  97. package/dist/dev/test/control-flow/show.test.js +1 -1
  98. package/dist/dev/test/control-flow/show.test.js.map +1 -1
  99. package/dist/dev/test/lazy-isempty.test.js +6 -6
  100. package/dist/dev/test/lazy-isempty.test.js.map +1 -1
  101. package/dist/dev/test/node.test.js +80 -0
  102. package/dist/dev/test/node.test.js.map +1 -0
  103. package/dist/dev/test/output-e2e.test.js +194 -0
  104. package/dist/dev/test/output-e2e.test.js.map +1 -0
  105. package/dist/dev/test/reactivity/circular-reactives.test.js +1 -1
  106. package/dist/dev/test/reactivity/circular-reactives.test.js.map +1 -1
  107. package/dist/dev/test/reactivity/cleanup.test.js +1 -1
  108. package/dist/dev/test/reactivity/cleanup.test.js.map +1 -1
  109. package/dist/dev/test/rendering/memoization.test.js +6 -1
  110. package/dist/dev/test/rendering/memoization.test.js.map +1 -1
  111. package/dist/dev/test/rendering/render-output-diagnostics.test.js +102 -0
  112. package/dist/dev/test/rendering/render-output-diagnostics.test.js.map +1 -0
  113. package/dist/dev/test/runtime.test.js +385 -0
  114. package/dist/dev/test/runtime.test.js.map +1 -0
  115. package/dist/dev/test/tree-test-utils.js +16 -0
  116. package/dist/dev/test/tree-test-utils.js.map +1 -0
  117. package/dist/dev/test/utils.test.js +1 -1
  118. package/dist/dev/test/utils.test.js.map +1 -1
  119. package/dist/dev/testing/devtools-utils.js +1 -1
  120. package/dist/dev/testing/devtools-utils.js.map +1 -1
  121. package/dist/dev/testing/extend-expect.js +7 -33
  122. package/dist/dev/testing/extend-expect.js.map +1 -1
  123. package/dist/dev/testing/render.js +7 -17
  124. package/dist/dev/testing/render.js.map +1 -1
  125. package/dist/devtools/index.html +17 -17
  126. package/dist/src/components/AccessExpression.test.js +1 -1
  127. package/dist/src/components/AccessExpression.test.js.map +1 -1
  128. package/dist/src/components/Output.d.ts +1 -1
  129. package/dist/src/components/Output.d.ts.map +1 -1
  130. package/dist/src/components/Output.js +2 -1
  131. package/dist/src/components/Output.js.map +1 -1
  132. package/dist/src/components/ReferenceOrContent.d.ts +1 -1
  133. package/dist/src/components/ReferenceOrContent.d.ts.map +1 -1
  134. package/dist/src/components/SourceFile.d.ts +1 -1
  135. package/dist/src/components/SourceFile.d.ts.map +1 -1
  136. package/dist/src/components/SourceFile.js.map +1 -1
  137. package/dist/src/content-slot.test.js +1 -1
  138. package/dist/src/content-slot.test.js.map +1 -1
  139. package/dist/src/context/format-options.d.ts +1 -1
  140. package/dist/src/context/format-options.d.ts.map +1 -1
  141. package/dist/src/context.d.ts +9 -1
  142. package/dist/src/context.d.ts.map +1 -1
  143. package/dist/src/context.js +30 -3
  144. package/dist/src/context.js.map +1 -1
  145. package/dist/src/debug/diagnostics.test.js +1 -1
  146. package/dist/src/debug/diagnostics.test.js.map +1 -1
  147. package/dist/src/debug/effects.test.js +1 -1
  148. package/dist/src/debug/effects.test.js.map +1 -1
  149. package/dist/src/debug/file-streaming.d.ts +22 -0
  150. package/dist/src/debug/file-streaming.d.ts.map +1 -0
  151. package/dist/src/debug/file-streaming.js +103 -0
  152. package/dist/src/debug/file-streaming.js.map +1 -0
  153. package/dist/src/debug/files.test.js +4 -5
  154. package/dist/src/debug/files.test.js.map +1 -1
  155. package/dist/src/debug/index.d.ts +5 -7
  156. package/dist/src/debug/index.d.ts.map +1 -1
  157. package/dist/src/debug/index.js +4 -6
  158. package/dist/src/debug/index.js.map +1 -1
  159. package/dist/src/debug/message-format.test.js +16 -18
  160. package/dist/src/debug/message-format.test.js.map +1 -1
  161. package/dist/src/debug/render-tree-orphans.test.js +8 -18
  162. package/dist/src/debug/render-tree-orphans.test.js.map +1 -1
  163. package/dist/src/debug/render.d.ts +71 -21
  164. package/dist/src/debug/render.d.ts.map +1 -1
  165. package/dist/src/debug/render.js +529 -352
  166. package/dist/src/debug/render.js.map +1 -1
  167. package/dist/src/debug/render.test.js +137 -74
  168. package/dist/src/debug/render.test.js.map +1 -1
  169. package/dist/src/debug/trace-writer.d.ts +6 -1
  170. package/dist/src/debug/trace-writer.d.ts.map +1 -1
  171. package/dist/src/debug/trace-writer.js +127 -15
  172. package/dist/src/debug/trace-writer.js.map +1 -1
  173. package/dist/src/debug/trace.d.ts +0 -36
  174. package/dist/src/debug/trace.d.ts.map +1 -1
  175. package/dist/src/debug/trace.js +0 -36
  176. package/dist/src/debug/trace.js.map +1 -1
  177. package/dist/src/devtools/devtools-protocol.d.ts +34 -1
  178. package/dist/src/devtools/devtools-protocol.d.ts.map +1 -1
  179. package/dist/src/devtools/devtools-server.d.ts.map +1 -1
  180. package/dist/src/devtools/devtools-server.js +55 -32
  181. package/dist/src/devtools/devtools-server.js.map +1 -1
  182. package/dist/src/devtools-entry.browser.d.ts +1 -1
  183. package/dist/src/devtools-entry.browser.d.ts.map +1 -1
  184. package/dist/src/devtools-entry.browser.js.map +1 -1
  185. package/dist/src/devtools-entry.d.ts +1 -1
  186. package/dist/src/devtools-entry.d.ts.map +1 -1
  187. package/dist/src/devtools-entry.js.map +1 -1
  188. package/dist/src/diagnostics.d.ts +4 -0
  189. package/dist/src/diagnostics.d.ts.map +1 -1
  190. package/dist/src/diagnostics.js +19 -1
  191. package/dist/src/diagnostics.js.map +1 -1
  192. package/dist/src/index.d.ts +5 -2
  193. package/dist/src/index.d.ts.map +1 -1
  194. package/dist/src/index.js +5 -2
  195. package/dist/src/index.js.map +1 -1
  196. package/dist/src/jsx-runtime.d.ts +13 -4
  197. package/dist/src/jsx-runtime.d.ts.map +1 -1
  198. package/dist/src/jsx-runtime.js +14 -8
  199. package/dist/src/jsx-runtime.js.map +1 -1
  200. package/dist/src/output-types.d.ts +40 -0
  201. package/dist/src/output-types.d.ts.map +1 -0
  202. package/dist/src/output-types.js +2 -0
  203. package/dist/src/output-types.js.map +1 -0
  204. package/dist/src/reactivity.d.ts +49 -18
  205. package/dist/src/reactivity.d.ts.map +1 -1
  206. package/dist/src/reactivity.js +155 -13
  207. package/dist/src/reactivity.js.map +1 -1
  208. package/dist/src/render/get-string-width.d.ts +19 -0
  209. package/dist/src/render/get-string-width.d.ts.map +1 -0
  210. package/dist/src/render/get-string-width.js +61 -0
  211. package/dist/src/render/get-string-width.js.map +1 -0
  212. package/dist/src/render/index.d.ts +2 -0
  213. package/dist/src/render/index.d.ts.map +1 -0
  214. package/dist/src/render/index.js +2 -0
  215. package/dist/src/render/index.js.map +1 -0
  216. package/dist/src/render/node-context.d.ts +5 -0
  217. package/dist/src/render/node-context.d.ts.map +1 -0
  218. package/dist/src/render/node-context.js +7 -0
  219. package/dist/src/render/node-context.js.map +1 -0
  220. package/dist/src/render/node.d.ts +146 -0
  221. package/dist/src/render/node.d.ts.map +1 -0
  222. package/dist/src/render/node.js +386 -0
  223. package/dist/src/render/node.js.map +1 -0
  224. package/dist/src/render/printer-support.d.ts +50 -0
  225. package/dist/src/render/printer-support.d.ts.map +1 -0
  226. package/dist/src/render/printer-support.js +180 -0
  227. package/dist/src/render/printer-support.js.map +1 -0
  228. package/dist/src/render/printer.d.ts +35 -0
  229. package/dist/src/render/printer.d.ts.map +1 -0
  230. package/dist/src/render/printer.js +797 -0
  231. package/dist/src/render/printer.js.map +1 -0
  232. package/dist/src/render-error.d.ts +4 -0
  233. package/dist/src/render-error.d.ts.map +1 -0
  234. package/dist/src/render-error.js +79 -0
  235. package/dist/src/render-error.js.map +1 -0
  236. package/dist/src/render-output.d.ts +42 -0
  237. package/dist/src/render-output.d.ts.map +1 -0
  238. package/dist/src/render-output.js +209 -0
  239. package/dist/src/render-output.js.map +1 -0
  240. package/dist/src/runtime/component.d.ts +2 -2
  241. package/dist/src/runtime/component.d.ts.map +1 -1
  242. package/dist/src/runtime/create-intrinsic.d.ts +28 -0
  243. package/dist/src/runtime/create-intrinsic.d.ts.map +1 -0
  244. package/dist/src/runtime/create-intrinsic.js +53 -0
  245. package/dist/src/runtime/create-intrinsic.js.map +1 -0
  246. package/dist/src/runtime/fragment.d.ts +16 -0
  247. package/dist/src/runtime/fragment.d.ts.map +1 -0
  248. package/dist/src/runtime/fragment.js +21 -0
  249. package/dist/src/runtime/fragment.js.map +1 -0
  250. package/dist/src/runtime/index.d.ts +12 -0
  251. package/dist/src/runtime/index.d.ts.map +1 -0
  252. package/dist/src/runtime/index.js +13 -0
  253. package/dist/src/runtime/index.js.map +1 -0
  254. package/dist/src/runtime/insert.d.ts +29 -0
  255. package/dist/src/runtime/insert.d.ts.map +1 -0
  256. package/dist/src/runtime/insert.js +453 -0
  257. package/dist/src/runtime/insert.js.map +1 -0
  258. package/dist/src/runtime/intrinsic.d.ts +12 -29
  259. package/dist/src/runtime/intrinsic.d.ts.map +1 -1
  260. package/dist/src/runtime/intrinsic.js +1 -11
  261. package/dist/src/runtime/intrinsic.js.map +1 -1
  262. package/dist/src/scheduler.d.ts.map +1 -1
  263. package/dist/src/scheduler.js +38 -14
  264. package/dist/src/scheduler.js.map +1 -1
  265. package/dist/src/stc.d.ts.map +1 -1
  266. package/dist/src/stc.js +2 -0
  267. package/dist/src/stc.js.map +1 -1
  268. package/dist/src/sti.d.ts +7 -6
  269. package/dist/src/sti.d.ts.map +1 -1
  270. package/dist/src/sti.js +1 -1
  271. package/dist/src/sti.js.map +1 -1
  272. package/dist/src/symbols/symbol-slot.test.js +1 -1
  273. package/dist/src/symbols/symbol-slot.test.js.map +1 -1
  274. package/dist/src/test-render.d.ts +31 -0
  275. package/dist/src/test-render.d.ts.map +1 -0
  276. package/dist/src/test-render.js +78 -0
  277. package/dist/src/test-render.js.map +1 -0
  278. package/dist/src/utils.d.ts +1 -1
  279. package/dist/src/utils.d.ts.map +1 -1
  280. package/dist/src/utils.js +40 -28
  281. package/dist/src/utils.js.map +1 -1
  282. package/dist/src/write-output.d.ts +1 -1
  283. package/dist/src/write-output.d.ts.map +1 -1
  284. package/dist/test/babel-e2e.test.d.ts +13 -0
  285. package/dist/test/babel-e2e.test.d.ts.map +1 -0
  286. package/dist/test/babel-e2e.test.js +218 -0
  287. package/dist/test/babel-e2e.test.js.map +1 -0
  288. package/dist/test/components/block.test.js +1 -1
  289. package/dist/test/components/block.test.js.map +1 -1
  290. package/dist/test/components/copy-file.test.d.ts.map +1 -1
  291. package/dist/test/components/copy-file.test.js +1 -1
  292. package/dist/test/components/copy-file.test.js.map +1 -1
  293. package/dist/test/components/update-file.test.js +1 -1
  294. package/dist/test/components/update-file.test.js.map +1 -1
  295. package/dist/test/components/wrap.test.js +1 -1
  296. package/dist/test/components/wrap.test.js.map +1 -1
  297. package/dist/test/control-flow/match.test.js +1 -1
  298. package/dist/test/control-flow/match.test.js.map +1 -1
  299. package/dist/test/control-flow/show.test.js +1 -1
  300. package/dist/test/control-flow/show.test.js.map +1 -1
  301. package/dist/test/lazy-isempty.test.js +6 -6
  302. package/dist/test/lazy-isempty.test.js.map +1 -1
  303. package/dist/test/node.test.d.ts +2 -0
  304. package/dist/test/node.test.d.ts.map +1 -0
  305. package/dist/test/node.test.js +80 -0
  306. package/dist/test/node.test.js.map +1 -0
  307. package/dist/test/output-e2e.test.d.ts +13 -0
  308. package/dist/test/output-e2e.test.d.ts.map +1 -0
  309. package/dist/test/output-e2e.test.js +194 -0
  310. package/dist/test/output-e2e.test.js.map +1 -0
  311. package/dist/test/reactivity/circular-reactives.test.js +1 -1
  312. package/dist/test/reactivity/circular-reactives.test.js.map +1 -1
  313. package/dist/test/reactivity/cleanup.test.js +1 -1
  314. package/dist/test/reactivity/cleanup.test.js.map +1 -1
  315. package/dist/test/rendering/memoization.test.js +6 -1
  316. package/dist/test/rendering/memoization.test.js.map +1 -1
  317. package/dist/test/rendering/render-output-diagnostics.test.d.ts +2 -0
  318. package/dist/test/rendering/render-output-diagnostics.test.d.ts.map +1 -0
  319. package/dist/test/rendering/render-output-diagnostics.test.js +82 -0
  320. package/dist/test/rendering/render-output-diagnostics.test.js.map +1 -0
  321. package/dist/test/runtime.test.d.ts +11 -0
  322. package/dist/test/runtime.test.d.ts.map +1 -0
  323. package/dist/test/runtime.test.js +385 -0
  324. package/dist/test/runtime.test.js.map +1 -0
  325. package/dist/test/tree-test-utils.d.ts +3 -0
  326. package/dist/test/tree-test-utils.d.ts.map +1 -0
  327. package/dist/test/tree-test-utils.js +16 -0
  328. package/dist/test/tree-test-utils.js.map +1 -0
  329. package/dist/test/utils.test.js +1 -1
  330. package/dist/test/utils.test.js.map +1 -1
  331. package/dist/testing/devtools-utils.d.ts.map +1 -1
  332. package/dist/testing/devtools-utils.js +1 -1
  333. package/dist/testing/devtools-utils.js.map +1 -1
  334. package/dist/testing/extend-expect.d.ts.map +1 -1
  335. package/dist/testing/extend-expect.js +7 -33
  336. package/dist/testing/extend-expect.js.map +1 -1
  337. package/dist/testing/render.d.ts +7 -9
  338. package/dist/testing/render.d.ts.map +1 -1
  339. package/dist/testing/render.js +7 -17
  340. package/dist/testing/render.js.map +1 -1
  341. package/dist/tsconfig.tsbuildinfo +1 -1
  342. package/docs/api/components/Output.md +0 -3
  343. package/docs/api/components/SourceFile.md +0 -3
  344. package/docs/api/functions/createComment.md +18 -0
  345. package/docs/api/functions/createElement.md +19 -0
  346. package/docs/api/functions/createFragment.md +17 -0
  347. package/docs/api/functions/createTextNode.md +18 -0
  348. package/docs/api/functions/emitDiagnosticForTree.md +19 -0
  349. package/docs/api/functions/ensureIsEmpty.md +1 -1
  350. package/docs/api/functions/getContextForNode.md +18 -0
  351. package/docs/api/functions/getContextForRenderNode.md +4 -4
  352. package/docs/api/functions/getDiagnosticsForTree.md +7 -5
  353. package/docs/api/functions/getRegisteredDiagnosticsForTree.md +18 -0
  354. package/docs/api/functions/index.md +17 -12
  355. package/docs/api/functions/isCustomContext.md +4 -4
  356. package/docs/api/functions/notifyContentState.md +6 -0
  357. package/docs/api/functions/printTree.md +6 -16
  358. package/docs/api/functions/registerDiagnosticsForTree.md +19 -0
  359. package/docs/api/functions/render.md +1 -2
  360. package/docs/api/functions/renderAsync.md +1 -2
  361. package/docs/api/functions/renderTree.md +8 -5
  362. package/docs/api/functions/reportDiagnosticsForTree.md +18 -0
  363. package/docs/api/functions/runInContext.md +28 -0
  364. package/docs/api/functions/sourceFilesForTree.md +6 -16
  365. package/docs/api/index.md +3 -3
  366. package/docs/api/testing/functions/index.md +1 -1
  367. package/docs/api/testing/functions/renderToString.md +1 -1
  368. package/docs/api/types/AlloyNode.md +22 -0
  369. package/docs/api/types/Child.md +1 -1
  370. package/docs/api/types/CommentNode.md +15 -0
  371. package/docs/api/types/Context.md +13 -15
  372. package/docs/api/types/ElementNode.md +18 -0
  373. package/docs/api/types/FragmentNode.md +12 -0
  374. package/docs/api/types/Insertable.md +7 -0
  375. package/docs/api/types/NodeType.md +5 -0
  376. package/docs/api/types/OutputDirectory.md +0 -50
  377. package/docs/api/types/PrintTreeOptions.md +0 -1
  378. package/docs/api/types/RenderTreeOptions.md +7 -0
  379. package/docs/api/types/StiComponentCreator.md +4 -4
  380. package/docs/api/types/StiSignature.md +1 -1
  381. package/docs/api/types/TextNode.md +16 -0
  382. package/docs/api/types/index.md +10 -28
  383. package/docs/api/variables/COMMENT_NODE.md +5 -0
  384. package/docs/api/variables/ELEMENT_NODE.md +11 -0
  385. package/docs/api/variables/FRAGMENT_NODE.md +5 -0
  386. package/docs/api/variables/TEXT_NODE.md +5 -0
  387. package/docs/api/variables/index.md +4 -2
  388. package/docs/formatting.md +1 -1
  389. package/docs/rendering.md +4 -4
  390. package/package.json +6 -6
  391. package/src/components/AccessExpression.test.tsx +1 -1
  392. package/src/components/Output.tsx +2 -1
  393. package/src/components/SourceFile.tsx +1 -1
  394. package/src/content-slot.test.tsx +1 -1
  395. package/src/context/format-options.ts +1 -1
  396. package/src/context.ts +37 -4
  397. package/src/debug/diagnostics.test.tsx +1 -1
  398. package/src/debug/effects.test.tsx +1 -1
  399. package/src/debug/file-streaming.ts +115 -0
  400. package/src/debug/files.test.tsx +15 -11
  401. package/src/debug/index.ts +11 -11
  402. package/src/debug/message-format.test.tsx +32 -19
  403. package/src/debug/render-tree-orphans.test.tsx +10 -19
  404. package/src/debug/render.test.tsx +206 -78
  405. package/src/debug/render.ts +642 -495
  406. package/src/debug/trace-writer.ts +168 -14
  407. package/src/debug/trace.ts +0 -20
  408. package/src/devtools/devtools-protocol.ts +43 -0
  409. package/src/devtools/devtools-server.ts +57 -32
  410. package/src/devtools-entry.browser.ts +5 -0
  411. package/src/devtools-entry.ts +5 -0
  412. package/src/diagnostics.ts +31 -0
  413. package/src/index.ts +66 -2
  414. package/src/jsx-runtime.ts +16 -14
  415. package/src/output-types.ts +47 -0
  416. package/src/reactivity.ts +186 -40
  417. package/src/render/get-string-width.ts +201 -0
  418. package/src/render/index.ts +1 -0
  419. package/src/render/node-context.ts +14 -0
  420. package/src/render/node.ts +442 -0
  421. package/src/render/printer-support.ts +209 -0
  422. package/src/render/printer.ts +817 -0
  423. package/src/render-error.ts +98 -0
  424. package/src/render-output.ts +243 -0
  425. package/src/runtime/component.ts +2 -2
  426. package/src/runtime/create-intrinsic.ts +56 -0
  427. package/src/runtime/fragment.ts +22 -0
  428. package/src/runtime/index.ts +12 -0
  429. package/src/runtime/insert.ts +569 -0
  430. package/src/runtime/intrinsic.ts +14 -70
  431. package/src/scheduler.ts +40 -25
  432. package/src/stc.ts +3 -0
  433. package/src/sti.ts +17 -20
  434. package/src/symbols/symbol-slot.test.tsx +1 -1
  435. package/src/test-render.ts +103 -0
  436. package/src/utils.tsx +55 -37
  437. package/src/write-output.ts +1 -1
  438. package/temp/api-testing.json +390 -14
  439. package/temp/api.json +4320 -4144
  440. package/test/babel-e2e.test.ts +224 -0
  441. package/test/components/block.test.tsx +1 -1
  442. package/test/components/copy-file.test.tsx +2 -1
  443. package/test/components/update-file.test.tsx +1 -1
  444. package/test/components/wrap.test.tsx +1 -1
  445. package/test/control-flow/match.test.tsx +1 -1
  446. package/test/control-flow/show.test.tsx +1 -1
  447. package/test/lazy-isempty.test.tsx +6 -6
  448. package/test/node.test.ts +90 -0
  449. package/test/output-e2e.test.ts +198 -0
  450. package/test/reactivity/circular-reactives.test.tsx +1 -1
  451. package/test/reactivity/cleanup.test.tsx +1 -1
  452. package/test/rendering/memoization.test.tsx +6 -1
  453. package/test/rendering/render-output-diagnostics.test.tsx +120 -0
  454. package/test/runtime.test.ts +448 -0
  455. package/test/tree-test-utils.ts +23 -0
  456. package/test/utils.test.tsx +1 -1
  457. package/testing/devtools-utils.ts +2 -0
  458. package/testing/extend-expect.ts +8 -46
  459. package/testing/render.ts +17 -21
  460. package/dist/dev/src/print-hook.js +0 -10
  461. package/dist/dev/src/print-hook.js.map +0 -1
  462. package/dist/dev/src/render.js +0 -872
  463. package/dist/dev/src/render.js.map +0 -1
  464. package/dist/src/print-hook.d.ts +0 -14
  465. package/dist/src/print-hook.d.ts.map +0 -1
  466. package/dist/src/print-hook.js +0 -10
  467. package/dist/src/print-hook.js.map +0 -1
  468. package/dist/src/render.d.ts +0 -155
  469. package/dist/src/render.d.ts.map +0 -1
  470. package/dist/src/render.js +0 -872
  471. package/dist/src/render.js.map +0 -1
  472. package/docs/api/functions/createIntrinsic.md +0 -19
  473. package/docs/api/functions/createRenderTreeHook.md +0 -19
  474. package/docs/api/functions/getElementCache.md +0 -17
  475. package/docs/api/functions/isIntrinsicElement.md +0 -18
  476. package/docs/api/functions/isPrintHook.md +0 -18
  477. package/docs/api/types/AlignIntrinsicElement.md +0 -5
  478. package/docs/api/types/BrIntrinsicElement.md +0 -5
  479. package/docs/api/types/BreakParentIntrinsicElement.md +0 -5
  480. package/docs/api/types/DedentIntrinsicElement.md +0 -5
  481. package/docs/api/types/DedentToRootIntrinsicElement.md +0 -5
  482. package/docs/api/types/ElementCache.md +0 -5
  483. package/docs/api/types/ElementCacheKey.md +0 -5
  484. package/docs/api/types/FillIntrinsicElement.md +0 -5
  485. package/docs/api/types/GroupIntrinsicElement.md +0 -5
  486. package/docs/api/types/HardlineIntrinsicElement.md +0 -5
  487. package/docs/api/types/HbrIntrinsicElement.md +0 -5
  488. package/docs/api/types/IfBreakIntrinsicElement.md +0 -5
  489. package/docs/api/types/IndentIfBreakIntrinsicElement.md +0 -5
  490. package/docs/api/types/IndentIntrinsicElement.md +0 -5
  491. package/docs/api/types/IntrinsicElement.md +0 -5
  492. package/docs/api/types/IntrinsicElementBase.md +0 -9
  493. package/docs/api/types/LbrIntrinsicElement.md +0 -5
  494. package/docs/api/types/LineIntrinsicElement.md +0 -5
  495. package/docs/api/types/LineSuffixBoundaryIntrinsicElement.md +0 -5
  496. package/docs/api/types/LineSuffixIntrinsicElement.md +0 -5
  497. package/docs/api/types/LiterallineIntrinsicElement.md +0 -5
  498. package/docs/api/types/MarkAsRootIntrinsicElement.md +0 -5
  499. package/docs/api/types/PrintHook.md +0 -10
  500. package/docs/api/types/RenderedTextTree.md +0 -5
  501. package/docs/api/types/SbrIntrinsicElement.md +0 -5
  502. package/docs/api/types/SoftlineIntrinsicElement.md +0 -5
  503. package/docs/api/variables/intrinsicElementKey.md +0 -5
  504. package/docs/api/variables/printHookTag.md +0 -7
  505. package/src/print-hook.ts +0 -22
  506. package/src/render.ts +0 -1154
@@ -0,0 +1,569 @@
1
+ /**
2
+ * Polymorphic child insertion — the single entry point for "put this thing
3
+ * into this AlloyNode". The babel-emitted compiled output calls `insert`
4
+ * for every JSX child slot.
5
+ *
6
+ * When the child is a `ComponentCreator` thunk, we invoke it synchronously
7
+ * inside a freshly-pushed owner Context via {@link runInContext}. No Vue
8
+ * effect is allocated for component invocation.
9
+ *
10
+ * Reactive bindings (function children, refs, refkeys) get a bracketed
11
+ * region between two comment markers and a single Vue `effect` that
12
+ * rewrites the bracketed range on re-fire.
13
+ */
14
+ import { isRef, type Ref } from "@vue/reactivity";
15
+ import { useContext } from "../context.js";
16
+ import { SourceFileContext } from "../context/source-file.js";
17
+ import { debug, type RenderNodeActions } from "../debug/index.js";
18
+ import {
19
+ contentAdded,
20
+ contentRemoved,
21
+ effect,
22
+ getContext,
23
+ isCustomContext,
24
+ notifyContentState,
25
+ runInContext,
26
+ runInContextWithDisposer,
27
+ untrack,
28
+ type CustomContext,
29
+ type Disposable,
30
+ } from "../reactivity.js";
31
+ import { isRefkey, isRefkeyable, toRefkey, type Refkey } from "../refkey.js";
32
+ import { notifyRenderError } from "../render-error.js";
33
+ import { popStack, pushStack } from "../render-stack.js";
34
+ import { setContextForNode } from "../render/node-context.js";
35
+ import {
36
+ AlloyNode,
37
+ CommentNode,
38
+ createComment,
39
+ createElement,
40
+ ElementNode,
41
+ TextNode,
42
+ } from "../render/node.js";
43
+ import {
44
+ isComponentCreator,
45
+ isRenderableObject,
46
+ RENDERABLE,
47
+ type Children,
48
+ type ComponentCreator,
49
+ } from "./component.js";
50
+
51
+ /**
52
+ * Insert `child` into `parent`. If `marker` is provided, insert
53
+ * immediately before `marker`; otherwise append at the end of
54
+ * `parent`'s children.
55
+ *
56
+ * Recognized child shapes (in order):
57
+ * - `null` / `undefined` / `boolean` — no-op.
58
+ * - `string` — appended/inserted as a text node.
59
+ * - `number` — coerced to text.
60
+ * - `AlloyNode` — appended/inserted directly (Fragment children are
61
+ * spliced; see {@link AlloyNode.append}).
62
+ * - `Array` — each element is recursively inserted in order.
63
+ * - `ComponentCreator` (thunk from `createComponent`) — invoked inside
64
+ * `runInContext`; the returned `Children` value is recursively
65
+ * inserted. **No Vue effect is allocated.**
66
+ * - `Ref` — wrapped as a reactive accessor (`() => ref.value`) and
67
+ * inserted as a reactive binding.
68
+ * - `Refkey` / RefkeyableObject — resolved against the active
69
+ * `SourceFileContext.reference` inside an effect.
70
+ * - RenderableObject (with `[RENDERABLE]` method) — reactive binding
71
+ * over the method's return value.
72
+ * - `function` — reactive binding; the function is invoked inside an
73
+ * effect, the result is recursively inserted, and the bracketed
74
+ * range is rewritten on re-fire.
75
+ * - other — coerced via `String()` as a fallback.
76
+ */
77
+ export function insert(
78
+ parent: AlloyNode,
79
+ child: unknown,
80
+ marker: AlloyNode | null = null,
81
+ ): void {
82
+ if (child === null || child === undefined || typeof child === "boolean") {
83
+ return;
84
+ }
85
+
86
+ if (typeof child === "string") {
87
+ insertNode(parent, child, marker);
88
+ return;
89
+ }
90
+
91
+ if (typeof child === "number") {
92
+ insertNode(parent, String(child), marker);
93
+ return;
94
+ }
95
+
96
+ if (child instanceof AlloyNode) {
97
+ // Stateless intrinsic trees (mapJoin joiners, cached `<hbr/>`s,
98
+ // etc.) may flow through multiple insertion points sharing the
99
+ // same value reference. AlloyNode is a real tree (one parent), so
100
+ // clone on re-parent rather than steal from the prior insertion.
101
+ const node = child.parentNode !== null ? child.cloneNode() : child;
102
+ insertNode(parent, node, marker);
103
+ return;
104
+ }
105
+
106
+ if (Array.isArray(child)) {
107
+ for (let i = 0, len = child.length; i < len; i++) {
108
+ insert(parent, child[i], marker);
109
+ }
110
+ return;
111
+ }
112
+
113
+ if (isCustomContext(child)) {
114
+ insertCustomContext(parent, child, marker);
115
+ return;
116
+ }
117
+
118
+ if (isComponentCreator(child)) {
119
+ insertComponent(parent, child as ComponentCreator, marker);
120
+ return;
121
+ }
122
+
123
+ if (isRef(child)) {
124
+ insertReactive(parent, () => (child as Ref).value, marker);
125
+ return;
126
+ }
127
+
128
+ if (isRefkey(child) || isRefkeyable(child)) {
129
+ insertRefkey(parent, child as Refkey, marker);
130
+ return;
131
+ }
132
+
133
+ if (isRenderableObject(child)) {
134
+ insertReactive(parent, () => child[RENDERABLE](), marker);
135
+ return;
136
+ }
137
+
138
+ if (typeof child === "function") {
139
+ insertReactive(parent, child as () => unknown, marker);
140
+ return;
141
+ }
142
+
143
+ // Fallback — coerce to string.
144
+ insertNode(parent, String(child), marker);
145
+ }
146
+
147
+ /**
148
+ * Invoke a component thunk inside a fresh owner Context (synchronous,
149
+ * no Vue effect) and recursively insert its return value.
150
+ *
151
+ * A `<Foo bar={x} />` JSX site compiled to `createComponent(Foo, props)`
152
+ * arrives here, and `Foo`'s body runs only at this insertion point —
153
+ * preserving conditional skip, render-time refkey resolution, and
154
+ * context-flow-from-the-rendering-position semantics.
155
+ */
156
+ function insertComponent(
157
+ parent: AlloyNode,
158
+ thunk: ComponentCreator,
159
+ marker: AlloyNode | null,
160
+ ): void {
161
+ if (!debug.render.isRerenderEnabled()) {
162
+ renderComponent(parent, thunk, marker);
163
+ return;
164
+ }
165
+
166
+ const start: CommentNode = createComment("component:start");
167
+ const end: CommentNode = createComment("component:end");
168
+ insertNode(parent, start, marker);
169
+ insertNode(parent, end, marker);
170
+
171
+ let disposeCurrentContext: Disposable | undefined;
172
+ const rerender = (withBreak: boolean) => {
173
+ if (withBreak) {
174
+ // eslint-disable-next-line no-debugger
175
+ debugger;
176
+ }
177
+ if (start.parentNode !== parent || end.parentNode !== parent) return;
178
+ untrack(() => {
179
+ disposeCurrentContext?.();
180
+ disposeCurrentContext = undefined;
181
+ clearRange(start, end);
182
+ disposeCurrentContext = renderComponent(
183
+ parent,
184
+ thunk,
185
+ end,
186
+ actions,
187
+ true,
188
+ );
189
+ });
190
+ };
191
+ const actions: RenderNodeActions = {
192
+ rerender: () => rerender(false),
193
+ rerenderAndBreak: () => rerender(true),
194
+ };
195
+
196
+ disposeCurrentContext = renderComponent(parent, thunk, end, actions, true);
197
+ }
198
+
199
+ function renderComponent(
200
+ parent: AlloyNode,
201
+ thunk: ComponentCreator,
202
+ marker: AlloyNode | null,
203
+ actions?: RenderNodeActions,
204
+ captureDisposer = false,
205
+ ): Disposable | undefined {
206
+ let disposeComponentContext: Disposable | undefined;
207
+ const execute = (dispose?: Disposable) => {
208
+ disposeComponentContext = dispose;
209
+ renderComponentBody(parent, thunk, marker, actions);
210
+ };
211
+
212
+ // Keep the component's pushed Context live while children are
213
+ // recursively inserted: any reactive bindings (effects) created for
214
+ // children must capture the component's context as their owner so
215
+ // that `useContext(...)` walks find values set by Context.Providers
216
+ // and other parent components.
217
+ if (captureDisposer) {
218
+ runInContextWithDisposer(execute);
219
+ } else {
220
+ runInContext(() => execute());
221
+ }
222
+ return disposeComponentContext;
223
+ }
224
+
225
+ function renderComponentBody(
226
+ parent: AlloyNode,
227
+ thunk: ComponentCreator,
228
+ marker: AlloyNode | null,
229
+ actions?: RenderNodeActions,
230
+ ): void {
231
+ pushStack(thunk.component, thunk.props, thunk.source);
232
+ const session = debug.render.beginComponent({
233
+ component: thunk as ComponentCreator<unknown>,
234
+ propsSource: thunk.props as Record<string, unknown> | undefined,
235
+ source: thunk.source,
236
+ parent,
237
+ actions,
238
+ });
239
+ let result: unknown;
240
+ try {
241
+ result = untrack(thunk);
242
+ } catch (error) {
243
+ notifyRenderError(error);
244
+ session.dispose();
245
+ popStack();
246
+ throw error;
247
+ }
248
+ try {
249
+ const ctx = getContext()!;
250
+ // Carry component identity for error stacks.
251
+ if (ctx.meta && result instanceof AlloyNode) {
252
+ (ctx.meta as { renderNode?: AlloyNode }).renderNode = result;
253
+ }
254
+ const meta = ctx.meta as
255
+ | { sourceFile?: unknown; directory?: unknown; copyFile?: unknown }
256
+ | undefined;
257
+ if (meta?.sourceFile || meta?.directory || meta?.copyFile) {
258
+ if (meta.sourceFile) {
259
+ const sf = meta.sourceFile as { path: string; filetype: string };
260
+ session.recordFile(sf.path, sf.filetype);
261
+ } else if (meta.directory) {
262
+ const d = meta.directory as { path: string };
263
+ session.recordDirectory(d.path);
264
+ }
265
+ const localName =
266
+ meta.sourceFile ? "alloy:source-file"
267
+ : meta.directory ? "alloy:directory"
268
+ : "alloy:copy-file";
269
+ if (result instanceof ElementNode && result.localName === localName) {
270
+ setContextForNode(result, ctx);
271
+ insertNode(parent, result, marker);
272
+ return;
273
+ }
274
+ const wrapper: ElementNode = createElement(localName);
275
+ setContextForNode(wrapper, ctx);
276
+ try {
277
+ insert(wrapper, result as Children, null);
278
+ } catch (error) {
279
+ notifyRenderError(error);
280
+ throw error;
281
+ }
282
+ insertNode(parent, wrapper, marker);
283
+ return;
284
+ }
285
+ if (result instanceof AlloyNode) {
286
+ setContextForNode(result, ctx);
287
+ }
288
+ try {
289
+ insert(parent, result as Children, marker);
290
+ } catch (error) {
291
+ notifyRenderError(error);
292
+ throw error;
293
+ }
294
+ } finally {
295
+ session.dispose();
296
+ popStack();
297
+ }
298
+ }
299
+
300
+ function clearRange(start: CommentNode, end: CommentNode): void {
301
+ let n = start.nextSibling;
302
+ let removedCount = 0;
303
+ while (n !== null && n !== end) {
304
+ const next = n.nextSibling;
305
+ if (countsAsContent(n)) removedCount++;
306
+ n.remove();
307
+ n = next;
308
+ }
309
+ if (removedCount > 0) {
310
+ for (let i = 0; i < removedCount; i++) contentRemoved();
311
+ notifyContentState();
312
+ }
313
+ }
314
+
315
+ /**
316
+ * Wrap `accessor` in an effect; bracket its produced content between two
317
+ * comment markers and replace the bracketed range on re-fire.
318
+ *
319
+ * On initial run the markers are inserted into `parent` (before
320
+ * `marker` if given, else appended). Each effect invocation:
321
+ * 1. Removes everything between `start` and `end`.
322
+ * 2. Calls `accessor()` (tracking) to get the new content.
323
+ * 3. Inserts the new content via `insert(parent, content, end)` so it
324
+ * lands inside the bracketed range.
325
+ */
326
+ function insertReactive(
327
+ parent: AlloyNode,
328
+ accessor: () => unknown,
329
+ marker: AlloyNode | null,
330
+ ): void {
331
+ const start: CommentNode = createComment("slot:start");
332
+ const end: CommentNode = createComment("slot:end");
333
+ insertNode(parent, start, marker);
334
+ insertNode(parent, end, marker);
335
+
336
+ // Tracks the previous accessor result when it was an array, so we can
337
+ // do identity-keyed reconciliation rather than clear-and-reinsert.
338
+ let prevSlots: Map<unknown, [CommentNode, CommentNode]> | null = null;
339
+
340
+ effect(() => {
341
+ const value = accessor();
342
+
343
+ if (Array.isArray(value)) {
344
+ untrack(() => {
345
+ reconcileArray(parent, start, end, value);
346
+ });
347
+ return;
348
+ }
349
+
350
+ untrack(() => {
351
+ if (prevSlots) {
352
+ prevSlots = null;
353
+ }
354
+ let n = start.nextSibling;
355
+ let removedCount = 0;
356
+ while (n !== null && n !== end) {
357
+ const next = n.nextSibling;
358
+ if (countsAsContent(n)) removedCount++;
359
+ n.remove();
360
+ n = next;
361
+ }
362
+ if (removedCount > 0) {
363
+ for (let i = 0; i < removedCount; i++) contentRemoved();
364
+ notifyContentState();
365
+ }
366
+ insert(parent, value, end);
367
+ });
368
+ });
369
+
370
+ function reconcileArray(
371
+ parent: AlloyNode,
372
+ start: CommentNode,
373
+ end: CommentNode,
374
+ next: unknown[],
375
+ ): void {
376
+ const prevSlotMap = prevSlots ?? new Map();
377
+ const newSlots = new Map<unknown, [CommentNode, CommentNode]>();
378
+ const used = new Set<unknown>();
379
+
380
+ let cursor: AlloyNode = start;
381
+ for (let i = 0; i < next.length; i++) {
382
+ const entry = next[i];
383
+ const reusable =
384
+ entry !== null &&
385
+ (typeof entry === "object" || typeof entry === "function") &&
386
+ (isCustomContext(entry) || isComponentCreator(entry)) &&
387
+ prevSlotMap.has(entry) &&
388
+ !used.has(entry);
389
+ if (reusable) {
390
+ const [slotStart, slotEnd] = prevSlotMap.get(entry)!;
391
+ moveRange(slotStart, slotEnd, cursor);
392
+ used.add(entry);
393
+ newSlots.set(entry, [slotStart, slotEnd]);
394
+ cursor = slotEnd;
395
+ continue;
396
+ }
397
+
398
+ const sStart = createComment("slot:item:start");
399
+ const sEnd = createComment("slot:item:end");
400
+ cursor.after(sEnd);
401
+ sEnd.before(sStart);
402
+ insert(parent, entry, sEnd);
403
+ if (
404
+ entry !== null &&
405
+ (typeof entry === "object" || typeof entry === "function") &&
406
+ (isCustomContext(entry) || isComponentCreator(entry))
407
+ ) {
408
+ newSlots.set(entry, [sStart, sEnd]);
409
+ }
410
+ cursor = sEnd;
411
+ }
412
+
413
+ if (prevSlotMap.size > 0) {
414
+ for (const [entry, [s, e]] of prevSlotMap) {
415
+ if (used.has(entry)) continue;
416
+ removeRange(s, e);
417
+ }
418
+ }
419
+
420
+ let n = cursor.nextSibling;
421
+ while (n !== null && n !== end) {
422
+ const nx = n.nextSibling;
423
+ if (countsAsContent(n)) contentRemoved();
424
+ n.remove();
425
+ n = nx;
426
+ }
427
+ notifyContentState();
428
+
429
+ prevSlots = newSlots;
430
+ }
431
+
432
+ function moveRange(s: CommentNode, e: CommentNode, after: AlloyNode): void {
433
+ if (s.previousSibling === after) return;
434
+ const nodes: AlloyNode[] = [];
435
+ let n: AlloyNode | null = s;
436
+ while (n !== null) {
437
+ nodes.push(n);
438
+ if (n === e) break;
439
+ n = n.nextSibling;
440
+ }
441
+ for (const node of nodes) node.remove();
442
+ let anchor = after;
443
+ for (const node of nodes) {
444
+ anchor.after(node);
445
+ anchor = node;
446
+ }
447
+ }
448
+
449
+ function removeRange(s: CommentNode, e: CommentNode): void {
450
+ let n: AlloyNode | null = s;
451
+ let removed = 0;
452
+ while (n !== null) {
453
+ const nx: AlloyNode | null = n.nextSibling;
454
+ if (countsAsContent(n)) removed++;
455
+ n.remove();
456
+ if (n === e) break;
457
+ n = nx;
458
+ }
459
+ if (removed > 0) {
460
+ for (let i = 0; i < removed; i++) contentRemoved();
461
+ }
462
+ }
463
+ }
464
+
465
+ /**
466
+ * Refkey insertion — resolve against the active SourceFileContext and
467
+ * wrap in a reactive binding so the produced Reference content updates
468
+ * if the binder updates.
469
+ */
470
+ function insertRefkey(
471
+ parent: AlloyNode,
472
+ key: Refkey,
473
+ marker: AlloyNode | null,
474
+ ): void {
475
+ const refkey = isRefkey(key) ? key : toRefkey(key);
476
+ insertReactive(
477
+ parent,
478
+ () => {
479
+ const sf = useContext(SourceFileContext);
480
+ if (!sf || !sf.reference) {
481
+ throw new Error("Can only emit references inside of source files");
482
+ }
483
+ return sf.reference({ refkey });
484
+ },
485
+ marker,
486
+ );
487
+ }
488
+
489
+ /**
490
+ * Low-level: insert `node` (or wrap `text` as a TextNode) into `parent`,
491
+ * either before `marker` or at the end. Updates the surrounding
492
+ * Context's `childrenWithContent` accounting so reactive observers
493
+ * (`ContentSlot.isEmpty`, `mapJoin`, `Block`, etc.) see content as it
494
+ * lands.
495
+ */
496
+ function insertNode(
497
+ parent: AlloyNode,
498
+ nodeOrText: AlloyNode | string,
499
+ marker: AlloyNode | null,
500
+ ): void {
501
+ if (marker !== null) {
502
+ marker.before(nodeOrText);
503
+ } else {
504
+ parent.append(nodeOrText);
505
+ }
506
+
507
+ if (countsAsContent(nodeOrText)) {
508
+ contentAdded();
509
+ notifyContentState();
510
+ }
511
+ }
512
+
513
+ function countsAsContent(nodeOrText: AlloyNode | string): boolean {
514
+ if (typeof nodeOrText === "string") return nodeOrText !== "";
515
+ // Comment markers (slot:start/slot:end, ctx:start/ctx:end) are
516
+ // bookkeeping only — they never produce visible output and must not
517
+ // count toward emptiness tracking.
518
+ if (nodeOrText instanceof CommentNode) return false;
519
+ if (nodeOrText instanceof TextNode) return nodeOrText.data !== "";
520
+ // ElementNode / FragmentNode: these are structural wrappers. They
521
+ // count as content iff their subtree has any text descendant.
522
+ // Pre-built JSX fragments (e.g. `<>{p}</>` evaluated outside a
523
+ // mapJoin slot) carry their text payload as already-attached
524
+ // descendants — we have to peek into the subtree because those
525
+ // descendants didn't go through this insertNode path inside the
526
+ // slot's context. An empty intrinsic like `<hbr/>` correctly
527
+ // reports `false` so mapJoin suppresses joiners around it
528
+ // (matches legacy main-branch semantics).
529
+ return hasTextDescendant(nodeOrText);
530
+ }
531
+
532
+ function hasTextDescendant(node: AlloyNode): boolean {
533
+ for (let c = node.firstChild; c !== null; c = c.nextSibling) {
534
+ if (c instanceof TextNode) {
535
+ if (c.data !== "") return true;
536
+ } else if (c instanceof CommentNode) {
537
+ // skip
538
+ } else if (hasTextDescendant(c)) {
539
+ return true;
540
+ }
541
+ }
542
+ return false;
543
+ }
544
+
545
+ /**
546
+ * Insert a `CustomContext` (the wrapper produced by `createCustomContext`,
547
+ * e.g. by `mapJoin`'s per-item slots).
548
+ *
549
+ * The custom-context object exposes `useCustomContext(cb)` — invoking it
550
+ * runs whatever owner-context setup the producer wants (e.g. `mapJoin`'s
551
+ * `root(...)` + `effect(...)` for per-item disposers and isEmpty tracking)
552
+ * and then yields the rendered Children back to `cb`. We bracket the
553
+ * insertion site with comment markers so any later mutation by enclosing
554
+ * reactive bindings doesn't disturb our region, and we recursively
555
+ * `insert` the produced children before the end marker.
556
+ */
557
+ function insertCustomContext(
558
+ parent: AlloyNode,
559
+ ctx: CustomContext,
560
+ marker: AlloyNode | null,
561
+ ): void {
562
+ const start = createComment("ctx:start");
563
+ const end = createComment("ctx:end");
564
+ insertNode(parent, start, marker);
565
+ insertNode(parent, end, marker);
566
+ ctx.useCustomContext((children) => {
567
+ insert(parent, children as Children, end);
568
+ });
569
+ }
@@ -1,4 +1,18 @@
1
+ /**
2
+ * JSX intrinsic element type table.
3
+ *
4
+ * The interface enumerates every Alloy primitive layout element
5
+ * (`<group>`, `<indent>`, `<hardline>`, `<ifBreak>`, …) along with
6
+ * its prop shape, so TS can type-check JSX uses like `<group
7
+ * shouldBreak>{...}</group>`. There are no runtime values in this
8
+ * file: at JSX-compile time `<group ...>` becomes `createIntrinsic(
9
+ * "group", props)` (see {@link runtime/create-intrinsic}), which
10
+ * lowers directly into an `ElementNode` whose `localName` is the
11
+ * intrinsic kind.
12
+ */
13
+
1
14
  import type { Children } from "./component.js";
15
+
2
16
  export interface IntrinsicElements {
3
17
  /**
4
18
  * Attempt to render the children on a single line if possible. If a group
@@ -127,73 +141,3 @@ export interface IntrinsicElements {
127
141
  */
128
142
  dedentToRoot: { children: Children };
129
143
  }
130
- export interface IntrinsicElementBase<
131
- TKey extends keyof IntrinsicElements = keyof IntrinsicElements,
132
- > {
133
- [intrinsicElementKey]: true;
134
- name: TKey;
135
- props: IntrinsicElements[TKey];
136
- }
137
-
138
- export function createIntrinsic<TKey extends keyof IntrinsicElements>(
139
- name: TKey,
140
- props: IntrinsicElements[TKey],
141
- ): IntrinsicElementBase<TKey> {
142
- return {
143
- [intrinsicElementKey]: true,
144
- name,
145
- props,
146
- };
147
- }
148
-
149
- export function isIntrinsicElement(type: unknown): type is IntrinsicElement {
150
- return (
151
- typeof type === "object" && type !== null && intrinsicElementKey in type
152
- );
153
- }
154
-
155
- export const intrinsicElementKey = Symbol();
156
- export type IndentIntrinsicElement = IntrinsicElementBase<"indent">;
157
- export type IndentIfBreakIntrinsicElement =
158
- IntrinsicElementBase<"indentIfBreak">;
159
- export type BrIntrinsicElement = IntrinsicElementBase<"br">;
160
- export type LineIntrinsicElement = IntrinsicElementBase<"line">;
161
- export type HbrIntrinsicElement = IntrinsicElementBase<"hbr">;
162
- export type HardlineIntrinsicElement = IntrinsicElementBase<"hardline">;
163
- export type SbrIntrinsicElement = IntrinsicElementBase<"sbr">;
164
- export type SoftlineIntrinsicElement = IntrinsicElementBase<"softline">;
165
- export type GroupIntrinsicElement = IntrinsicElementBase<"group">;
166
- export type AlignIntrinsicElement = IntrinsicElementBase<"align">;
167
- export type FillIntrinsicElement = IntrinsicElementBase<"fill">;
168
- export type BreakParentIntrinsicElement = IntrinsicElementBase<"breakParent">;
169
- export type LineSuffixIntrinsicElement = IntrinsicElementBase<"lineSuffix">;
170
- export type LineSuffixBoundaryIntrinsicElement =
171
- IntrinsicElementBase<"lineSuffixBoundary">;
172
- export type DedentIntrinsicElement = IntrinsicElementBase<"dedent">;
173
- export type DedentToRootIntrinsicElement = IntrinsicElementBase<"dedentToRoot">;
174
- export type MarkAsRootIntrinsicElement = IntrinsicElementBase<"markAsRoot">;
175
- export type LiterallineIntrinsicElement = IntrinsicElementBase<"literalline">;
176
- export type LbrIntrinsicElement = IntrinsicElementBase<"lbr">;
177
- export type IfBreakIntrinsicElement = IntrinsicElementBase<"ifBreak">;
178
-
179
- export type IntrinsicElement =
180
- | IndentIntrinsicElement
181
- | IndentIfBreakIntrinsicElement
182
- | BrIntrinsicElement
183
- | LineIntrinsicElement
184
- | HbrIntrinsicElement
185
- | HardlineIntrinsicElement
186
- | SbrIntrinsicElement
187
- | SoftlineIntrinsicElement
188
- | GroupIntrinsicElement
189
- | AlignIntrinsicElement
190
- | FillIntrinsicElement
191
- | BreakParentIntrinsicElement
192
- | LineSuffixIntrinsicElement
193
- | LineSuffixBoundaryIntrinsicElement
194
- | DedentIntrinsicElement
195
- | LiterallineIntrinsicElement
196
- | LbrIntrinsicElement
197
- | DedentToRootIntrinsicElement
198
- | MarkAsRootIntrinsicElement
199
- | IfBreakIntrinsicElement;