@alloy-js/core 0.24.0-dev.1 → 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 (532) 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/cli.browser.js +14 -0
  12. package/dist/dev/src/debug/cli.browser.js.map +1 -0
  13. package/dist/dev/src/debug/diagnostics.test.js +1 -1
  14. package/dist/dev/src/debug/diagnostics.test.js.map +1 -1
  15. package/dist/dev/src/debug/effects.test.js +1 -1
  16. package/dist/dev/src/debug/effects.test.js.map +1 -1
  17. package/dist/dev/src/debug/file-streaming.js +103 -0
  18. package/dist/dev/src/debug/file-streaming.js.map +1 -0
  19. package/dist/dev/src/debug/files.test.js +4 -5
  20. package/dist/dev/src/debug/files.test.js.map +1 -1
  21. package/dist/dev/src/debug/index.js +4 -6
  22. package/dist/dev/src/debug/index.js.map +1 -1
  23. package/dist/dev/src/debug/message-format.test.js +50 -52
  24. package/dist/dev/src/debug/message-format.test.js.map +1 -1
  25. package/dist/dev/src/debug/render-tree-orphans.test.js +13 -23
  26. package/dist/dev/src/debug/render-tree-orphans.test.js.map +1 -1
  27. package/dist/dev/src/debug/render.js +529 -352
  28. package/dist/dev/src/debug/render.js.map +1 -1
  29. package/dist/dev/src/debug/render.test.js +171 -92
  30. package/dist/dev/src/debug/render.test.js.map +1 -1
  31. package/dist/dev/src/debug/trace-db.browser.js +11 -0
  32. package/dist/dev/src/debug/trace-db.browser.js.map +1 -0
  33. package/dist/dev/src/debug/trace-db.js +40 -0
  34. package/dist/dev/src/debug/trace-db.js.map +1 -0
  35. package/dist/dev/src/debug/trace-writer.js +130 -39
  36. package/dist/dev/src/debug/trace-writer.js.map +1 -1
  37. package/dist/dev/src/debug/trace.js +0 -36
  38. package/dist/dev/src/debug/trace.js.map +1 -1
  39. package/dist/dev/src/devtools/devtools-server.js +55 -32
  40. package/dist/dev/src/devtools/devtools-server.js.map +1 -1
  41. package/dist/dev/src/devtools-entry.browser.js.map +1 -1
  42. package/dist/dev/src/devtools-entry.js.map +1 -1
  43. package/dist/dev/src/diagnostics.js +19 -1
  44. package/dist/dev/src/diagnostics.js.map +1 -1
  45. package/dist/dev/src/index.js +5 -2
  46. package/dist/dev/src/index.js.map +1 -1
  47. package/dist/dev/src/jsx-runtime.js +14 -8
  48. package/dist/dev/src/jsx-runtime.js.map +1 -1
  49. package/dist/dev/src/output-types.js +2 -0
  50. package/dist/dev/src/output-types.js.map +1 -0
  51. package/dist/dev/src/reactivity.js +155 -13
  52. package/dist/dev/src/reactivity.js.map +1 -1
  53. package/dist/dev/src/render/get-string-width.js +61 -0
  54. package/dist/dev/src/render/get-string-width.js.map +1 -0
  55. package/dist/dev/src/render/index.js +2 -0
  56. package/dist/dev/src/render/index.js.map +1 -0
  57. package/dist/dev/src/render/node-context.js +7 -0
  58. package/dist/dev/src/render/node-context.js.map +1 -0
  59. package/dist/dev/src/render/node.js +386 -0
  60. package/dist/dev/src/render/node.js.map +1 -0
  61. package/dist/dev/src/render/printer-support.js +180 -0
  62. package/dist/dev/src/render/printer-support.js.map +1 -0
  63. package/dist/dev/src/render/printer.js +797 -0
  64. package/dist/dev/src/render/printer.js.map +1 -0
  65. package/dist/dev/src/render-error.js +79 -0
  66. package/dist/dev/src/render-error.js.map +1 -0
  67. package/dist/dev/src/render-output.js +209 -0
  68. package/dist/dev/src/render-output.js.map +1 -0
  69. package/dist/dev/src/runtime/create-intrinsic.js +53 -0
  70. package/dist/dev/src/runtime/create-intrinsic.js.map +1 -0
  71. package/dist/dev/src/runtime/fragment.js +21 -0
  72. package/dist/dev/src/runtime/fragment.js.map +1 -0
  73. package/dist/dev/src/runtime/index.js +13 -0
  74. package/dist/dev/src/runtime/index.js.map +1 -0
  75. package/dist/dev/src/runtime/insert.js +453 -0
  76. package/dist/dev/src/runtime/insert.js.map +1 -0
  77. package/dist/dev/src/runtime/intrinsic.js +1 -11
  78. package/dist/dev/src/runtime/intrinsic.js.map +1 -1
  79. package/dist/dev/src/scheduler.js +38 -14
  80. package/dist/dev/src/scheduler.js.map +1 -1
  81. package/dist/dev/src/stc.js +2 -0
  82. package/dist/dev/src/stc.js.map +1 -1
  83. package/dist/dev/src/sti.js +1 -1
  84. package/dist/dev/src/sti.js.map +1 -1
  85. package/dist/dev/src/symbols/symbol-slot.test.js +1 -1
  86. package/dist/dev/src/symbols/symbol-slot.test.js.map +1 -1
  87. package/dist/dev/src/test-render.js +78 -0
  88. package/dist/dev/src/test-render.js.map +1 -0
  89. package/dist/dev/src/utils.js +47 -35
  90. package/dist/dev/src/utils.js.map +1 -1
  91. package/dist/dev/test/babel-e2e.test.js +218 -0
  92. package/dist/dev/test/babel-e2e.test.js.map +1 -0
  93. package/dist/dev/test/browser-build.test.js +70 -9
  94. package/dist/dev/test/browser-build.test.js.map +1 -1
  95. package/dist/dev/test/components/block.test.js +1 -1
  96. package/dist/dev/test/components/block.test.js.map +1 -1
  97. package/dist/dev/test/components/copy-file.test.js +7 -7
  98. package/dist/dev/test/components/copy-file.test.js.map +1 -1
  99. package/dist/dev/test/components/update-file.test.js +1 -1
  100. package/dist/dev/test/components/update-file.test.js.map +1 -1
  101. package/dist/dev/test/components/wrap.test.js +1 -1
  102. package/dist/dev/test/components/wrap.test.js.map +1 -1
  103. package/dist/dev/test/control-flow/match.test.js +1 -1
  104. package/dist/dev/test/control-flow/match.test.js.map +1 -1
  105. package/dist/dev/test/control-flow/show.test.js +1 -1
  106. package/dist/dev/test/control-flow/show.test.js.map +1 -1
  107. package/dist/dev/test/lazy-isempty.test.js +6 -6
  108. package/dist/dev/test/lazy-isempty.test.js.map +1 -1
  109. package/dist/dev/test/node.test.js +80 -0
  110. package/dist/dev/test/node.test.js.map +1 -0
  111. package/dist/dev/test/output-e2e.test.js +194 -0
  112. package/dist/dev/test/output-e2e.test.js.map +1 -0
  113. package/dist/dev/test/reactivity/circular-reactives.test.js +1 -1
  114. package/dist/dev/test/reactivity/circular-reactives.test.js.map +1 -1
  115. package/dist/dev/test/reactivity/cleanup.test.js +1 -1
  116. package/dist/dev/test/reactivity/cleanup.test.js.map +1 -1
  117. package/dist/dev/test/rendering/memoization.test.js +6 -1
  118. package/dist/dev/test/rendering/memoization.test.js.map +1 -1
  119. package/dist/dev/test/rendering/render-output-diagnostics.test.js +102 -0
  120. package/dist/dev/test/rendering/render-output-diagnostics.test.js.map +1 -0
  121. package/dist/dev/test/runtime.test.js +385 -0
  122. package/dist/dev/test/runtime.test.js.map +1 -0
  123. package/dist/dev/test/tree-test-utils.js +16 -0
  124. package/dist/dev/test/tree-test-utils.js.map +1 -0
  125. package/dist/dev/test/utils.test.js +1 -1
  126. package/dist/dev/test/utils.test.js.map +1 -1
  127. package/dist/dev/testing/devtools-utils.js +1 -1
  128. package/dist/dev/testing/devtools-utils.js.map +1 -1
  129. package/dist/dev/testing/extend-expect.js +7 -33
  130. package/dist/dev/testing/extend-expect.js.map +1 -1
  131. package/dist/dev/testing/render.js +7 -17
  132. package/dist/dev/testing/render.js.map +1 -1
  133. package/dist/devtools/index.html +17 -17
  134. package/dist/src/components/AccessExpression.test.js +1 -1
  135. package/dist/src/components/AccessExpression.test.js.map +1 -1
  136. package/dist/src/components/Output.d.ts +1 -1
  137. package/dist/src/components/Output.d.ts.map +1 -1
  138. package/dist/src/components/Output.js +2 -1
  139. package/dist/src/components/Output.js.map +1 -1
  140. package/dist/src/components/ReferenceOrContent.d.ts +1 -1
  141. package/dist/src/components/ReferenceOrContent.d.ts.map +1 -1
  142. package/dist/src/components/SourceFile.d.ts +1 -1
  143. package/dist/src/components/SourceFile.d.ts.map +1 -1
  144. package/dist/src/components/SourceFile.js.map +1 -1
  145. package/dist/src/content-slot.test.js +1 -1
  146. package/dist/src/content-slot.test.js.map +1 -1
  147. package/dist/src/context/format-options.d.ts +1 -1
  148. package/dist/src/context/format-options.d.ts.map +1 -1
  149. package/dist/src/context.d.ts +9 -1
  150. package/dist/src/context.d.ts.map +1 -1
  151. package/dist/src/context.js +30 -3
  152. package/dist/src/context.js.map +1 -1
  153. package/dist/src/debug/cli.browser.d.ts +13 -0
  154. package/dist/src/debug/cli.browser.d.ts.map +1 -0
  155. package/dist/src/debug/cli.browser.js +14 -0
  156. package/dist/src/debug/cli.browser.js.map +1 -0
  157. package/dist/src/debug/diagnostics.test.js +1 -1
  158. package/dist/src/debug/diagnostics.test.js.map +1 -1
  159. package/dist/src/debug/effects.test.js +1 -1
  160. package/dist/src/debug/effects.test.js.map +1 -1
  161. package/dist/src/debug/file-streaming.d.ts +22 -0
  162. package/dist/src/debug/file-streaming.d.ts.map +1 -0
  163. package/dist/src/debug/file-streaming.js +103 -0
  164. package/dist/src/debug/file-streaming.js.map +1 -0
  165. package/dist/src/debug/files.test.js +4 -5
  166. package/dist/src/debug/files.test.js.map +1 -1
  167. package/dist/src/debug/index.d.ts +5 -7
  168. package/dist/src/debug/index.d.ts.map +1 -1
  169. package/dist/src/debug/index.js +4 -6
  170. package/dist/src/debug/index.js.map +1 -1
  171. package/dist/src/debug/message-format.test.js +16 -18
  172. package/dist/src/debug/message-format.test.js.map +1 -1
  173. package/dist/src/debug/render-tree-orphans.test.js +8 -18
  174. package/dist/src/debug/render-tree-orphans.test.js.map +1 -1
  175. package/dist/src/debug/render.d.ts +71 -21
  176. package/dist/src/debug/render.d.ts.map +1 -1
  177. package/dist/src/debug/render.js +529 -352
  178. package/dist/src/debug/render.js.map +1 -1
  179. package/dist/src/debug/render.test.js +137 -74
  180. package/dist/src/debug/render.test.js.map +1 -1
  181. package/dist/src/debug/trace-db.browser.d.ts +9 -0
  182. package/dist/src/debug/trace-db.browser.d.ts.map +1 -0
  183. package/dist/src/debug/trace-db.browser.js +11 -0
  184. package/dist/src/debug/trace-db.browser.js.map +1 -0
  185. package/dist/src/debug/trace-db.d.ts +16 -0
  186. package/dist/src/debug/trace-db.d.ts.map +1 -0
  187. package/dist/src/debug/trace-db.js +40 -0
  188. package/dist/src/debug/trace-db.js.map +1 -0
  189. package/dist/src/debug/trace-writer.d.ts +6 -1
  190. package/dist/src/debug/trace-writer.d.ts.map +1 -1
  191. package/dist/src/debug/trace-writer.js +130 -39
  192. package/dist/src/debug/trace-writer.js.map +1 -1
  193. package/dist/src/debug/trace.d.ts +0 -36
  194. package/dist/src/debug/trace.d.ts.map +1 -1
  195. package/dist/src/debug/trace.js +0 -36
  196. package/dist/src/debug/trace.js.map +1 -1
  197. package/dist/src/devtools/devtools-protocol.d.ts +34 -1
  198. package/dist/src/devtools/devtools-protocol.d.ts.map +1 -1
  199. package/dist/src/devtools/devtools-server.d.ts.map +1 -1
  200. package/dist/src/devtools/devtools-server.js +55 -32
  201. package/dist/src/devtools/devtools-server.js.map +1 -1
  202. package/dist/src/devtools-entry.browser.d.ts +1 -1
  203. package/dist/src/devtools-entry.browser.d.ts.map +1 -1
  204. package/dist/src/devtools-entry.browser.js.map +1 -1
  205. package/dist/src/devtools-entry.d.ts +1 -1
  206. package/dist/src/devtools-entry.d.ts.map +1 -1
  207. package/dist/src/devtools-entry.js.map +1 -1
  208. package/dist/src/diagnostics.d.ts +4 -0
  209. package/dist/src/diagnostics.d.ts.map +1 -1
  210. package/dist/src/diagnostics.js +19 -1
  211. package/dist/src/diagnostics.js.map +1 -1
  212. package/dist/src/index.d.ts +5 -2
  213. package/dist/src/index.d.ts.map +1 -1
  214. package/dist/src/index.js +5 -2
  215. package/dist/src/index.js.map +1 -1
  216. package/dist/src/jsx-runtime.d.ts +13 -4
  217. package/dist/src/jsx-runtime.d.ts.map +1 -1
  218. package/dist/src/jsx-runtime.js +14 -8
  219. package/dist/src/jsx-runtime.js.map +1 -1
  220. package/dist/src/output-types.d.ts +40 -0
  221. package/dist/src/output-types.d.ts.map +1 -0
  222. package/dist/src/output-types.js +2 -0
  223. package/dist/src/output-types.js.map +1 -0
  224. package/dist/src/reactivity.d.ts +49 -18
  225. package/dist/src/reactivity.d.ts.map +1 -1
  226. package/dist/src/reactivity.js +155 -13
  227. package/dist/src/reactivity.js.map +1 -1
  228. package/dist/src/render/get-string-width.d.ts +19 -0
  229. package/dist/src/render/get-string-width.d.ts.map +1 -0
  230. package/dist/src/render/get-string-width.js +61 -0
  231. package/dist/src/render/get-string-width.js.map +1 -0
  232. package/dist/src/render/index.d.ts +2 -0
  233. package/dist/src/render/index.d.ts.map +1 -0
  234. package/dist/src/render/index.js +2 -0
  235. package/dist/src/render/index.js.map +1 -0
  236. package/dist/src/render/node-context.d.ts +5 -0
  237. package/dist/src/render/node-context.d.ts.map +1 -0
  238. package/dist/src/render/node-context.js +7 -0
  239. package/dist/src/render/node-context.js.map +1 -0
  240. package/dist/src/render/node.d.ts +146 -0
  241. package/dist/src/render/node.d.ts.map +1 -0
  242. package/dist/src/render/node.js +386 -0
  243. package/dist/src/render/node.js.map +1 -0
  244. package/dist/src/render/printer-support.d.ts +50 -0
  245. package/dist/src/render/printer-support.d.ts.map +1 -0
  246. package/dist/src/render/printer-support.js +180 -0
  247. package/dist/src/render/printer-support.js.map +1 -0
  248. package/dist/src/render/printer.d.ts +35 -0
  249. package/dist/src/render/printer.d.ts.map +1 -0
  250. package/dist/src/render/printer.js +797 -0
  251. package/dist/src/render/printer.js.map +1 -0
  252. package/dist/src/render-error.d.ts +4 -0
  253. package/dist/src/render-error.d.ts.map +1 -0
  254. package/dist/src/render-error.js +79 -0
  255. package/dist/src/render-error.js.map +1 -0
  256. package/dist/src/render-output.d.ts +42 -0
  257. package/dist/src/render-output.d.ts.map +1 -0
  258. package/dist/src/render-output.js +209 -0
  259. package/dist/src/render-output.js.map +1 -0
  260. package/dist/src/runtime/component.d.ts +2 -2
  261. package/dist/src/runtime/component.d.ts.map +1 -1
  262. package/dist/src/runtime/create-intrinsic.d.ts +28 -0
  263. package/dist/src/runtime/create-intrinsic.d.ts.map +1 -0
  264. package/dist/src/runtime/create-intrinsic.js +53 -0
  265. package/dist/src/runtime/create-intrinsic.js.map +1 -0
  266. package/dist/src/runtime/fragment.d.ts +16 -0
  267. package/dist/src/runtime/fragment.d.ts.map +1 -0
  268. package/dist/src/runtime/fragment.js +21 -0
  269. package/dist/src/runtime/fragment.js.map +1 -0
  270. package/dist/src/runtime/index.d.ts +12 -0
  271. package/dist/src/runtime/index.d.ts.map +1 -0
  272. package/dist/src/runtime/index.js +13 -0
  273. package/dist/src/runtime/index.js.map +1 -0
  274. package/dist/src/runtime/insert.d.ts +29 -0
  275. package/dist/src/runtime/insert.d.ts.map +1 -0
  276. package/dist/src/runtime/insert.js +453 -0
  277. package/dist/src/runtime/insert.js.map +1 -0
  278. package/dist/src/runtime/intrinsic.d.ts +12 -29
  279. package/dist/src/runtime/intrinsic.d.ts.map +1 -1
  280. package/dist/src/runtime/intrinsic.js +1 -11
  281. package/dist/src/runtime/intrinsic.js.map +1 -1
  282. package/dist/src/scheduler.d.ts.map +1 -1
  283. package/dist/src/scheduler.js +38 -14
  284. package/dist/src/scheduler.js.map +1 -1
  285. package/dist/src/stc.d.ts.map +1 -1
  286. package/dist/src/stc.js +2 -0
  287. package/dist/src/stc.js.map +1 -1
  288. package/dist/src/sti.d.ts +7 -6
  289. package/dist/src/sti.d.ts.map +1 -1
  290. package/dist/src/sti.js +1 -1
  291. package/dist/src/sti.js.map +1 -1
  292. package/dist/src/symbols/symbol-slot.test.js +1 -1
  293. package/dist/src/symbols/symbol-slot.test.js.map +1 -1
  294. package/dist/src/test-render.d.ts +31 -0
  295. package/dist/src/test-render.d.ts.map +1 -0
  296. package/dist/src/test-render.js +78 -0
  297. package/dist/src/test-render.js.map +1 -0
  298. package/dist/src/utils.d.ts +1 -1
  299. package/dist/src/utils.d.ts.map +1 -1
  300. package/dist/src/utils.js +40 -28
  301. package/dist/src/utils.js.map +1 -1
  302. package/dist/src/write-output.d.ts +1 -1
  303. package/dist/src/write-output.d.ts.map +1 -1
  304. package/dist/test/babel-e2e.test.d.ts +13 -0
  305. package/dist/test/babel-e2e.test.d.ts.map +1 -0
  306. package/dist/test/babel-e2e.test.js +218 -0
  307. package/dist/test/babel-e2e.test.js.map +1 -0
  308. package/dist/test/browser-build.test.js +70 -9
  309. package/dist/test/browser-build.test.js.map +1 -1
  310. package/dist/test/components/block.test.js +1 -1
  311. package/dist/test/components/block.test.js.map +1 -1
  312. package/dist/test/components/copy-file.test.d.ts.map +1 -1
  313. package/dist/test/components/copy-file.test.js +1 -1
  314. package/dist/test/components/copy-file.test.js.map +1 -1
  315. package/dist/test/components/update-file.test.js +1 -1
  316. package/dist/test/components/update-file.test.js.map +1 -1
  317. package/dist/test/components/wrap.test.js +1 -1
  318. package/dist/test/components/wrap.test.js.map +1 -1
  319. package/dist/test/control-flow/match.test.js +1 -1
  320. package/dist/test/control-flow/match.test.js.map +1 -1
  321. package/dist/test/control-flow/show.test.js +1 -1
  322. package/dist/test/control-flow/show.test.js.map +1 -1
  323. package/dist/test/lazy-isempty.test.js +6 -6
  324. package/dist/test/lazy-isempty.test.js.map +1 -1
  325. package/dist/test/node.test.d.ts +2 -0
  326. package/dist/test/node.test.d.ts.map +1 -0
  327. package/dist/test/node.test.js +80 -0
  328. package/dist/test/node.test.js.map +1 -0
  329. package/dist/test/output-e2e.test.d.ts +13 -0
  330. package/dist/test/output-e2e.test.d.ts.map +1 -0
  331. package/dist/test/output-e2e.test.js +194 -0
  332. package/dist/test/output-e2e.test.js.map +1 -0
  333. package/dist/test/reactivity/circular-reactives.test.js +1 -1
  334. package/dist/test/reactivity/circular-reactives.test.js.map +1 -1
  335. package/dist/test/reactivity/cleanup.test.js +1 -1
  336. package/dist/test/reactivity/cleanup.test.js.map +1 -1
  337. package/dist/test/rendering/memoization.test.js +6 -1
  338. package/dist/test/rendering/memoization.test.js.map +1 -1
  339. package/dist/test/rendering/render-output-diagnostics.test.d.ts +2 -0
  340. package/dist/test/rendering/render-output-diagnostics.test.d.ts.map +1 -0
  341. package/dist/test/rendering/render-output-diagnostics.test.js +82 -0
  342. package/dist/test/rendering/render-output-diagnostics.test.js.map +1 -0
  343. package/dist/test/runtime.test.d.ts +11 -0
  344. package/dist/test/runtime.test.d.ts.map +1 -0
  345. package/dist/test/runtime.test.js +385 -0
  346. package/dist/test/runtime.test.js.map +1 -0
  347. package/dist/test/tree-test-utils.d.ts +3 -0
  348. package/dist/test/tree-test-utils.d.ts.map +1 -0
  349. package/dist/test/tree-test-utils.js +16 -0
  350. package/dist/test/tree-test-utils.js.map +1 -0
  351. package/dist/test/utils.test.js +1 -1
  352. package/dist/test/utils.test.js.map +1 -1
  353. package/dist/testing/devtools-utils.d.ts.map +1 -1
  354. package/dist/testing/devtools-utils.js +1 -1
  355. package/dist/testing/devtools-utils.js.map +1 -1
  356. package/dist/testing/extend-expect.d.ts.map +1 -1
  357. package/dist/testing/extend-expect.js +7 -33
  358. package/dist/testing/extend-expect.js.map +1 -1
  359. package/dist/testing/render.d.ts +7 -9
  360. package/dist/testing/render.d.ts.map +1 -1
  361. package/dist/testing/render.js +7 -17
  362. package/dist/testing/render.js.map +1 -1
  363. package/dist/tsconfig.tsbuildinfo +1 -1
  364. package/docs/api/components/Output.md +0 -3
  365. package/docs/api/components/SourceFile.md +0 -3
  366. package/docs/api/functions/createComment.md +18 -0
  367. package/docs/api/functions/createElement.md +19 -0
  368. package/docs/api/functions/createFragment.md +17 -0
  369. package/docs/api/functions/createTextNode.md +18 -0
  370. package/docs/api/functions/emitDiagnosticForTree.md +19 -0
  371. package/docs/api/functions/ensureIsEmpty.md +1 -1
  372. package/docs/api/functions/getContextForNode.md +18 -0
  373. package/docs/api/functions/getContextForRenderNode.md +4 -4
  374. package/docs/api/functions/getDiagnosticsForTree.md +7 -5
  375. package/docs/api/functions/getRegisteredDiagnosticsForTree.md +18 -0
  376. package/docs/api/functions/index.md +17 -12
  377. package/docs/api/functions/isCustomContext.md +4 -4
  378. package/docs/api/functions/notifyContentState.md +6 -0
  379. package/docs/api/functions/printTree.md +6 -16
  380. package/docs/api/functions/registerDiagnosticsForTree.md +19 -0
  381. package/docs/api/functions/render.md +1 -2
  382. package/docs/api/functions/renderAsync.md +1 -2
  383. package/docs/api/functions/renderTree.md +8 -5
  384. package/docs/api/functions/reportDiagnosticsForTree.md +18 -0
  385. package/docs/api/functions/runInContext.md +28 -0
  386. package/docs/api/functions/sourceFilesForTree.md +6 -16
  387. package/docs/api/index.md +3 -3
  388. package/docs/api/testing/functions/index.md +1 -1
  389. package/docs/api/testing/functions/renderToString.md +1 -1
  390. package/docs/api/types/AlloyNode.md +22 -0
  391. package/docs/api/types/Child.md +1 -1
  392. package/docs/api/types/CommentNode.md +15 -0
  393. package/docs/api/types/Context.md +13 -15
  394. package/docs/api/types/ElementNode.md +18 -0
  395. package/docs/api/types/FragmentNode.md +12 -0
  396. package/docs/api/types/Insertable.md +7 -0
  397. package/docs/api/types/NodeType.md +5 -0
  398. package/docs/api/types/OutputDirectory.md +0 -50
  399. package/docs/api/types/PrintTreeOptions.md +0 -1
  400. package/docs/api/types/RenderTreeOptions.md +7 -0
  401. package/docs/api/types/StiComponentCreator.md +4 -4
  402. package/docs/api/types/StiSignature.md +1 -1
  403. package/docs/api/types/TextNode.md +16 -0
  404. package/docs/api/types/index.md +10 -28
  405. package/docs/api/variables/COMMENT_NODE.md +5 -0
  406. package/docs/api/variables/ELEMENT_NODE.md +11 -0
  407. package/docs/api/variables/FRAGMENT_NODE.md +5 -0
  408. package/docs/api/variables/TEXT_NODE.md +5 -0
  409. package/docs/api/variables/index.md +4 -2
  410. package/docs/formatting.md +1 -1
  411. package/docs/rendering.md +4 -4
  412. package/package.json +11 -7
  413. package/src/components/AccessExpression.test.tsx +1 -1
  414. package/src/components/Output.tsx +2 -1
  415. package/src/components/SourceFile.tsx +1 -1
  416. package/src/content-slot.test.tsx +1 -1
  417. package/src/context/format-options.ts +1 -1
  418. package/src/context.ts +37 -4
  419. package/src/debug/cli.browser.ts +17 -0
  420. package/src/debug/diagnostics.test.tsx +1 -1
  421. package/src/debug/effects.test.tsx +1 -1
  422. package/src/debug/file-streaming.ts +115 -0
  423. package/src/debug/files.test.tsx +15 -11
  424. package/src/debug/index.ts +11 -11
  425. package/src/debug/message-format.test.tsx +32 -19
  426. package/src/debug/render-tree-orphans.test.tsx +10 -19
  427. package/src/debug/render.test.tsx +206 -78
  428. package/src/debug/render.ts +642 -495
  429. package/src/debug/trace-db.browser.ts +12 -0
  430. package/src/debug/trace-db.ts +42 -0
  431. package/src/debug/trace-writer.ts +173 -41
  432. package/src/debug/trace.ts +0 -20
  433. package/src/devtools/devtools-protocol.ts +43 -0
  434. package/src/devtools/devtools-server.ts +57 -32
  435. package/src/devtools-entry.browser.ts +5 -0
  436. package/src/devtools-entry.ts +5 -0
  437. package/src/diagnostics.ts +31 -0
  438. package/src/index.ts +66 -2
  439. package/src/jsx-runtime.ts +16 -14
  440. package/src/output-types.ts +47 -0
  441. package/src/reactivity.ts +186 -40
  442. package/src/render/get-string-width.ts +201 -0
  443. package/src/render/index.ts +1 -0
  444. package/src/render/node-context.ts +14 -0
  445. package/src/render/node.ts +442 -0
  446. package/src/render/printer-support.ts +209 -0
  447. package/src/render/printer.ts +817 -0
  448. package/src/render-error.ts +98 -0
  449. package/src/render-output.ts +243 -0
  450. package/src/runtime/component.ts +2 -2
  451. package/src/runtime/create-intrinsic.ts +56 -0
  452. package/src/runtime/fragment.ts +22 -0
  453. package/src/runtime/index.ts +12 -0
  454. package/src/runtime/insert.ts +569 -0
  455. package/src/runtime/intrinsic.ts +14 -70
  456. package/src/scheduler.ts +40 -25
  457. package/src/stc.ts +3 -0
  458. package/src/sti.ts +17 -20
  459. package/src/symbols/symbol-slot.test.tsx +1 -1
  460. package/src/test-render.ts +103 -0
  461. package/src/utils.tsx +55 -37
  462. package/src/write-output.ts +1 -1
  463. package/temp/api-testing.json +390 -14
  464. package/temp/api.json +4320 -4144
  465. package/test/babel-e2e.test.ts +224 -0
  466. package/test/browser-build.test.ts +81 -9
  467. package/test/components/block.test.tsx +1 -1
  468. package/test/components/copy-file.test.tsx +2 -1
  469. package/test/components/update-file.test.tsx +1 -1
  470. package/test/components/wrap.test.tsx +1 -1
  471. package/test/control-flow/match.test.tsx +1 -1
  472. package/test/control-flow/show.test.tsx +1 -1
  473. package/test/lazy-isempty.test.tsx +6 -6
  474. package/test/node.test.ts +90 -0
  475. package/test/output-e2e.test.ts +198 -0
  476. package/test/reactivity/circular-reactives.test.tsx +1 -1
  477. package/test/reactivity/cleanup.test.tsx +1 -1
  478. package/test/rendering/memoization.test.tsx +6 -1
  479. package/test/rendering/render-output-diagnostics.test.tsx +120 -0
  480. package/test/runtime.test.ts +448 -0
  481. package/test/tree-test-utils.ts +23 -0
  482. package/test/utils.test.tsx +1 -1
  483. package/testing/devtools-utils.ts +2 -0
  484. package/testing/extend-expect.ts +8 -46
  485. package/testing/render.ts +17 -21
  486. package/dist/dev/src/print-hook.js +0 -10
  487. package/dist/dev/src/print-hook.js.map +0 -1
  488. package/dist/dev/src/render.js +0 -872
  489. package/dist/dev/src/render.js.map +0 -1
  490. package/dist/src/print-hook.d.ts +0 -14
  491. package/dist/src/print-hook.d.ts.map +0 -1
  492. package/dist/src/print-hook.js +0 -10
  493. package/dist/src/print-hook.js.map +0 -1
  494. package/dist/src/render.d.ts +0 -155
  495. package/dist/src/render.d.ts.map +0 -1
  496. package/dist/src/render.js +0 -872
  497. package/dist/src/render.js.map +0 -1
  498. package/docs/api/functions/createIntrinsic.md +0 -19
  499. package/docs/api/functions/createRenderTreeHook.md +0 -19
  500. package/docs/api/functions/getElementCache.md +0 -17
  501. package/docs/api/functions/isIntrinsicElement.md +0 -18
  502. package/docs/api/functions/isPrintHook.md +0 -18
  503. package/docs/api/types/AlignIntrinsicElement.md +0 -5
  504. package/docs/api/types/BrIntrinsicElement.md +0 -5
  505. package/docs/api/types/BreakParentIntrinsicElement.md +0 -5
  506. package/docs/api/types/DedentIntrinsicElement.md +0 -5
  507. package/docs/api/types/DedentToRootIntrinsicElement.md +0 -5
  508. package/docs/api/types/ElementCache.md +0 -5
  509. package/docs/api/types/ElementCacheKey.md +0 -5
  510. package/docs/api/types/FillIntrinsicElement.md +0 -5
  511. package/docs/api/types/GroupIntrinsicElement.md +0 -5
  512. package/docs/api/types/HardlineIntrinsicElement.md +0 -5
  513. package/docs/api/types/HbrIntrinsicElement.md +0 -5
  514. package/docs/api/types/IfBreakIntrinsicElement.md +0 -5
  515. package/docs/api/types/IndentIfBreakIntrinsicElement.md +0 -5
  516. package/docs/api/types/IndentIntrinsicElement.md +0 -5
  517. package/docs/api/types/IntrinsicElement.md +0 -5
  518. package/docs/api/types/IntrinsicElementBase.md +0 -9
  519. package/docs/api/types/LbrIntrinsicElement.md +0 -5
  520. package/docs/api/types/LineIntrinsicElement.md +0 -5
  521. package/docs/api/types/LineSuffixBoundaryIntrinsicElement.md +0 -5
  522. package/docs/api/types/LineSuffixIntrinsicElement.md +0 -5
  523. package/docs/api/types/LiterallineIntrinsicElement.md +0 -5
  524. package/docs/api/types/MarkAsRootIntrinsicElement.md +0 -5
  525. package/docs/api/types/PrintHook.md +0 -10
  526. package/docs/api/types/RenderedTextTree.md +0 -5
  527. package/docs/api/types/SbrIntrinsicElement.md +0 -5
  528. package/docs/api/types/SoftlineIntrinsicElement.md +0 -5
  529. package/docs/api/variables/intrinsicElementKey.md +0 -5
  530. package/docs/api/variables/printHookTag.md +0 -7
  531. package/src/print-hook.ts +0 -22
  532. package/src/render.ts +0 -1154
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Browser stub for trace database initialization.
3
+ *
4
+ * Replaces `trace-db.ts` in browser builds. Returns null so that
5
+ * all trace-writer functions (which guard on `if (!db) return`) become no-ops.
6
+ */
7
+
8
+ export type DatabaseSync = null;
9
+
10
+ export async function openTraceDatabase(_path: string): Promise<null> {
11
+ return null;
12
+ }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Database initialization for the trace writer.
3
+ *
4
+ * Isolates the `node:sqlite` and `node:fs` dependencies so that
5
+ * `trace-writer.ts` itself remains browser-safe (all functions no-op
6
+ * when db is null). In browser builds this module is replaced by
7
+ * `trace-db.browser.ts` which always returns null.
8
+ */
9
+ import type { DatabaseSync as DatabaseSyncType } from "node:sqlite";
10
+
11
+ export type { DatabaseSyncType as DatabaseSync };
12
+
13
+ /**
14
+ * Opens a fresh SQLite database at the given path, removing any existing file.
15
+ * Returns the opened database instance.
16
+ */
17
+ export async function openTraceDatabase(
18
+ path: string,
19
+ ): Promise<DatabaseSyncType> {
20
+ const { DatabaseSync } = await import("node:sqlite");
21
+ const fs = await import("node:fs");
22
+ // Remove existing trace file so each run starts fresh
23
+ try {
24
+ fs.unlinkSync(path);
25
+ } catch {
26
+ /* ignore missing */
27
+ }
28
+ try {
29
+ fs.unlinkSync(path + "-wal");
30
+ } catch {
31
+ /* ignore missing */
32
+ }
33
+ try {
34
+ fs.unlinkSync(path + "-shm");
35
+ } catch {
36
+ /* ignore missing */
37
+ }
38
+ const db = new DatabaseSync(path);
39
+ db.exec("PRAGMA journal_mode=WAL");
40
+ db.exec("PRAGMA synchronous=NORMAL");
41
+ return db;
42
+ }
@@ -5,12 +5,10 @@
5
5
  * built-in `node:sqlite` module. The database can be queried by the
6
6
  * `alloy-trace` CLI or the devtools WebSocket server.
7
7
  */
8
- import type {
9
- DatabaseSync as DatabaseSyncType,
10
- StatementSync,
11
- } from "node:sqlite";
8
+ import type { StatementSync } from "node:sqlite";
9
+ import { type DatabaseSync, openTraceDatabase } from "./trace-db.js";
12
10
 
13
- let db: DatabaseSyncType | null = null;
11
+ let db: DatabaseSync | null = null;
14
12
  let seq = 0;
15
13
 
16
14
  // Prepared statements (initialized in initTrace)
@@ -25,6 +23,11 @@ let stmtInsertRenderNode: StatementSync;
25
23
  let stmtUpdateRenderNode: StatementSync;
26
24
  let stmtUpdateRenderNodeContext: StatementSync;
27
25
  let stmtDeleteRenderNode: StatementSync;
26
+ let stmtInsertComponentInstance: StatementSync;
27
+ let stmtUpdateComponentInstanceProps: StatementSync;
28
+ let stmtDeleteComponentInstance: StatementSync;
29
+ let stmtInsertComponentRoot: StatementSync;
30
+ let stmtDeleteComponentRoot: StatementSync;
28
31
  let stmtInsertSymbol: StatementSync;
29
32
  let stmtUpdateSymbol: StatementSync;
30
33
  let stmtDeleteSymbol: StatementSync;
@@ -49,9 +52,7 @@ export function nextSeq(): number {
49
52
  return seq++;
50
53
  }
51
54
 
52
- // ─────────────────────────────────────────────────────────────────────────────
53
- // Change notification bus — streams SQLite changes to devtools WS server
54
- // ─────────────────────────────────────────────────────────────────────────────
55
+ // #region Change notification bus
55
56
 
56
57
  export type ChangeChannel =
57
58
  | "render"
@@ -65,7 +66,9 @@ export type ChangeChannel =
65
66
  | "diagnostics"
66
67
  | "errors"
67
68
  | "lifecycle"
68
- | "scheduler";
69
+ | "scheduler"
70
+ | "components"
71
+ | "component_roots";
69
72
 
70
73
  export const ALL_CHANNELS: ChangeChannel[] = [
71
74
  "render",
@@ -80,6 +83,8 @@ export const ALL_CHANNELS: ChangeChannel[] = [
80
83
  "errors",
81
84
  "lifecycle",
82
85
  "scheduler",
86
+ "components",
87
+ "component_roots",
83
88
  ];
84
89
 
85
90
  export interface ChangeEvent {
@@ -117,6 +122,8 @@ const channelTableMap: Record<string, string> = {
117
122
  diagnostics: "diagnostics",
118
123
  errors: "render_errors",
119
124
  scheduler: "scheduler_jobs",
125
+ components: "component_instances",
126
+ component_roots: "component_roots",
120
127
  };
121
128
 
122
129
  export function queryChannel(
@@ -126,35 +133,15 @@ export function queryChannel(
126
133
  const table = channelTableMap[channel];
127
134
  if (!table) return [];
128
135
  if (!/^[a-z_]+$/.test(table)) return [];
129
- return db.prepare(`SELECT * FROM ${table}`).all() as Record<
136
+ return db.prepare(`SELECT * FROM ${table} ORDER BY seq`).all() as Record<
130
137
  string,
131
138
  unknown
132
139
  >[];
133
140
  }
134
141
 
135
142
  export async function initTrace(path: string): Promise<void> {
136
- // Dynamic import to avoid failing in environments without node:sqlite
137
- const { DatabaseSync } = await import("node:sqlite");
138
- const fs = await import("node:fs");
139
- // Remove existing trace file so each run starts fresh
140
- try {
141
- fs.unlinkSync(path);
142
- } catch {
143
- /* ignore missing */
144
- }
145
- try {
146
- fs.unlinkSync(path + "-wal");
147
- } catch {
148
- /* ignore missing */
149
- }
150
- try {
151
- fs.unlinkSync(path + "-shm");
152
- } catch {
153
- /* ignore missing */
154
- }
155
- db = new DatabaseSync(path);
156
- db.exec("PRAGMA journal_mode=WAL");
157
- db.exec("PRAGMA synchronous=NORMAL");
143
+ db = await openTraceDatabase(path);
144
+ if (!db) return;
158
145
  createSchema();
159
146
  prepareStatements();
160
147
  }
@@ -237,6 +224,31 @@ function createSchema(): void {
237
224
  CREATE INDEX IF NOT EXISTS idx_render_nodes_parent ON render_nodes(parent_id);
238
225
  CREATE INDEX IF NOT EXISTS idx_render_nodes_context ON render_nodes(context_id);
239
226
 
227
+ CREATE TABLE IF NOT EXISTS component_instances (
228
+ id INTEGER PRIMARY KEY,
229
+ parent_id INTEGER,
230
+ name TEXT NOT NULL,
231
+ props TEXT,
232
+ source_file TEXT,
233
+ source_line INTEGER,
234
+ source_col INTEGER,
235
+ context_id INTEGER,
236
+ seq INTEGER
237
+ );
238
+ CREATE INDEX IF NOT EXISTS idx_component_instances_parent ON component_instances(parent_id);
239
+ CREATE INDEX IF NOT EXISTS idx_component_instances_name ON component_instances(name);
240
+ CREATE INDEX IF NOT EXISTS idx_component_instances_context ON component_instances(context_id);
241
+
242
+ CREATE TABLE IF NOT EXISTS component_roots (
243
+ component_id INTEGER NOT NULL,
244
+ render_node_id INTEGER NOT NULL,
245
+ ordinal INTEGER NOT NULL,
246
+ seq INTEGER,
247
+ PRIMARY KEY (component_id, render_node_id)
248
+ );
249
+ CREATE INDEX IF NOT EXISTS idx_component_roots_component ON component_roots(component_id);
250
+ CREATE INDEX IF NOT EXISTS idx_component_roots_node ON component_roots(render_node_id);
251
+
240
252
  CREATE TABLE IF NOT EXISTS symbols (
241
253
  id INTEGER PRIMARY KEY,
242
254
  name TEXT NOT NULL,
@@ -361,6 +373,23 @@ function prepareStatements(): void {
361
373
  `UPDATE render_nodes SET context_id = ? WHERE id = ?`,
362
374
  );
363
375
  stmtDeleteRenderNode = db!.prepare(`DELETE FROM render_nodes WHERE id = ?`);
376
+ stmtInsertComponentInstance = db!.prepare(
377
+ `INSERT OR REPLACE INTO component_instances (id, parent_id, name, props, source_file, source_line, source_col, context_id, seq)
378
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
379
+ );
380
+ stmtUpdateComponentInstanceProps = db!.prepare(
381
+ `UPDATE component_instances SET props = ? WHERE id = ?`,
382
+ );
383
+ stmtDeleteComponentInstance = db!.prepare(
384
+ `DELETE FROM component_instances WHERE id = ?`,
385
+ );
386
+ stmtInsertComponentRoot = db!.prepare(
387
+ `INSERT OR REPLACE INTO component_roots (component_id, render_node_id, ordinal, seq)
388
+ VALUES (?, ?, ?, ?)`,
389
+ );
390
+ stmtDeleteComponentRoot = db!.prepare(
391
+ `DELETE FROM component_roots WHERE component_id = ? AND render_node_id = ?`,
392
+ );
364
393
  stmtInsertSymbol = db!.prepare(
365
394
  `INSERT OR REPLACE INTO symbols (id, name, original_name, scope_id, owner_symbol_id, render_node_id, is_member, is_transient, is_alias, metadata, seq)
366
395
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
@@ -407,9 +436,9 @@ function prepareStatements(): void {
407
436
  );
408
437
  }
409
438
 
410
- // ─────────────────────────────────────────────────────────────────────────────
411
- // Insert methods
412
- // ─────────────────────────────────────────────────────────────────────────────
439
+ // #endregion
440
+
441
+ // #region Insert methods
413
442
 
414
443
  export function insertEffect(
415
444
  id: number,
@@ -558,6 +587,10 @@ export function insertSchedulerFlush(jobsRun: number): void {
558
587
  stmtInsertSchedulerFlush.run(nextSeq(), jobsRun);
559
588
  }
560
589
 
590
+ // Track live render IDs and parent -> children edges so duplicate removals are
591
+ // ignored and child sets stay consistent with render-layer lifecycle events.
592
+ const renderChildren = new Map<number, Set<number>>();
593
+ const liveRenderIds = new Set<number>();
561
594
  export function insertRenderNode(
562
595
  id: number,
563
596
  parentId: number | null,
@@ -572,6 +605,15 @@ export function insertRenderNode(
572
605
  ): void {
573
606
  if (!db) return;
574
607
  const s = nextSeq();
608
+ if (parentId !== null) {
609
+ let set = renderChildren.get(parentId);
610
+ if (!set) {
611
+ set = new Set();
612
+ renderChildren.set(parentId, set);
613
+ }
614
+ set.add(id);
615
+ }
616
+ liveRenderIds.add(id);
575
617
  stmtInsertRenderNode.run(
576
618
  id,
577
619
  parentId,
@@ -617,10 +659,94 @@ export function updateRenderNodeContext(id: number, contextId: number): void {
617
659
 
618
660
  export function deleteRenderNode(id: number): void {
619
661
  if (!db) return;
662
+ if (!liveRenderIds.has(id)) return;
663
+ liveRenderIds.delete(id);
664
+ // Detach from parent's child set.
665
+ for (const set of renderChildren.values()) set.delete(id);
666
+ renderChildren.delete(id);
620
667
  stmtDeleteRenderNode.run(id);
621
668
  notifyChange("render", "removed", { id });
622
669
  }
623
670
 
671
+ export function insertComponentInstance(
672
+ id: number,
673
+ parentId: number | null,
674
+ name: string,
675
+ props: string | undefined,
676
+ sourceFile: string | undefined,
677
+ sourceLine: number | undefined,
678
+ sourceCol: number | undefined,
679
+ contextId: number | null,
680
+ ): void {
681
+ if (!db) return;
682
+ const s = nextSeq();
683
+ stmtInsertComponentInstance.run(
684
+ id,
685
+ parentId,
686
+ name,
687
+ props ?? null,
688
+ sourceFile ?? null,
689
+ sourceLine ?? null,
690
+ sourceCol ?? null,
691
+ contextId,
692
+ s,
693
+ );
694
+ notifyChange("components", "added", {
695
+ id,
696
+ parent_id: parentId,
697
+ name,
698
+ props: props ?? null,
699
+ source_file: sourceFile ?? null,
700
+ source_line: sourceLine ?? null,
701
+ source_col: sourceCol ?? null,
702
+ context_id: contextId,
703
+ seq: s,
704
+ });
705
+ }
706
+
707
+ export function updateComponentInstanceProps(
708
+ id: number,
709
+ props: string | undefined,
710
+ ): void {
711
+ if (!db) return;
712
+ stmtUpdateComponentInstanceProps.run(props ?? null, id);
713
+ notifyChange("components", "updated", { id, props: props ?? null });
714
+ }
715
+
716
+ export function deleteComponentInstance(id: number): void {
717
+ if (!db) return;
718
+ stmtDeleteComponentInstance.run(id);
719
+ notifyChange("components", "removed", { id });
720
+ }
721
+
722
+ export function insertComponentRoot(
723
+ componentId: number,
724
+ renderNodeId: number,
725
+ ordinal: number,
726
+ ): void {
727
+ if (!db) return;
728
+ const s = nextSeq();
729
+ stmtInsertComponentRoot.run(componentId, renderNodeId, ordinal, s);
730
+ notifyChange("component_roots", "added", {
731
+ component_id: componentId,
732
+ render_node_id: renderNodeId,
733
+ ordinal,
734
+ seq: s,
735
+ });
736
+ }
737
+
738
+ export function deleteComponentRoot(
739
+ componentId: number,
740
+ renderNodeId: number,
741
+ ): void {
742
+ if (!db) return;
743
+ stmtDeleteComponentRoot.run(componentId, renderNodeId);
744
+ notifyChange("component_roots", "removed", {
745
+ component_id: componentId,
746
+ render_node_id: renderNodeId,
747
+ });
748
+ }
749
+
624
750
  export function insertSymbol(
625
751
  id: number,
626
752
  name: string,
@@ -943,9 +1069,9 @@ export function insertSourceMap(
943
1069
  stmtInsertSourceMap.run(outputPath, mapJson, outputText ?? null);
944
1070
  }
945
1071
 
946
- // ─────────────────────────────────────────────────────────────────────────────
947
- // Transaction helpers
948
- // ─────────────────────────────────────────────────────────────────────────────
1072
+ // #endregion
1073
+
1074
+ // #region Transaction helpers
949
1075
 
950
1076
  export function beginTransaction(): void {
951
1077
  if (!db) return;
@@ -961,15 +1087,19 @@ export function closeTrace(): void {
961
1087
  db?.close();
962
1088
  db = null;
963
1089
  stmtDeleteDiagnostic = undefined;
1090
+ renderChildren.clear();
1091
+ liveRenderIds.clear();
964
1092
  }
965
1093
 
966
1094
  export function resetTrace(): void {
967
1095
  seq = 0;
1096
+ renderChildren.clear();
1097
+ liveRenderIds.clear();
968
1098
  }
969
1099
 
970
- // ─────────────────────────────────────────────────────────────────────────────
971
- // Lifecycle signals — broadcast to all WS clients regardless of subscription
972
- // ─────────────────────────────────────────────────────────────────────────────
1100
+ // #endregion
1101
+
1102
+ // #region Lifecycle signals
973
1103
 
974
1104
  export function notifyRenderReset(): void {
975
1105
  notifyChange("render", "reset", { _signal: "render:reset" } as any);
@@ -982,3 +1112,5 @@ export function notifyRenderComplete(): void {
982
1112
  export function notifyFlushComplete(): void {
983
1113
  notifyChange("lifecycle", "added", { _signal: "flushJobs:complete" } as any);
984
1114
  }
1115
+
1116
+ // #endregion
@@ -197,26 +197,6 @@ export const TracePhase = {
197
197
  subarea: "appendChild",
198
198
  bg: { r: 100, g: 50, b: 0 },
199
199
  },
200
- appendTextNode: {
201
- area: "render",
202
- subarea: "appendChild.textNode",
203
- bg: { r: 100, g: 50, b: 0 },
204
- },
205
- appendCachedFragment: {
206
- area: "render",
207
- subarea: "appendChild.cachedFragment",
208
- bg: { r: 100, g: 50, b: 0 },
209
- },
210
- appendCustomContext: {
211
- area: "render",
212
- subarea: "appendChild.customContext",
213
- bg: { r: 100, g: 50, b: 0 },
214
- },
215
- appendPrintHook: {
216
- area: "render",
217
- subarea: "appendChild.printHook",
218
- bg: { r: 100, g: 50, b: 0 },
219
- },
220
200
  appendComponent: {
221
201
  area: "render",
222
202
  subarea: "appendChild.component",
@@ -209,6 +209,44 @@ export interface RenderNodeRemovedMessage {
209
209
  id: number;
210
210
  }
211
211
 
212
+ export interface ComponentAddedMessage {
213
+ type: "component:added";
214
+ id: number;
215
+ parent_id: number | null;
216
+ name: string;
217
+ props?: string;
218
+ source_file?: string;
219
+ source_line?: number;
220
+ source_col?: number;
221
+ context_id?: number | null;
222
+ seq: number;
223
+ }
224
+
225
+ export interface ComponentUpdatedMessage {
226
+ type: "component:updated";
227
+ id: number;
228
+ props?: string;
229
+ }
230
+
231
+ export interface ComponentRemovedMessage {
232
+ type: "component:removed";
233
+ id: number;
234
+ }
235
+
236
+ export interface ComponentRootAddedMessage {
237
+ type: "component:root_added";
238
+ component_id: number;
239
+ render_node_id: number;
240
+ ordinal: number;
241
+ seq: number;
242
+ }
243
+
244
+ export interface ComponentRootRemovedMessage {
245
+ type: "component:root_removed";
246
+ component_id: number;
247
+ render_node_id: number;
248
+ }
249
+
212
250
  export interface RenderErrorMessage {
213
251
  type: "render:error";
214
252
  name?: string;
@@ -443,6 +481,11 @@ export type ServerToClientMessage =
443
481
  | RenderNodeAddedMessage
444
482
  | RenderNodeUpdatedMessage
445
483
  | RenderNodeRemovedMessage
484
+ | ComponentAddedMessage
485
+ | ComponentUpdatedMessage
486
+ | ComponentRemovedMessage
487
+ | ComponentRootAddedMessage
488
+ | ComponentRootRemovedMessage
446
489
  | RenderErrorMessage
447
490
  | RenderCompleteMessage
448
491
  | FlushJobsCompleteMessage
@@ -20,9 +20,7 @@ import {
20
20
  type DevtoolsTransportState,
21
21
  } from "./devtools-transport.js";
22
22
 
23
- // ─────────────────────────────────────────────────────────────────────────────
24
- // Public types
25
- // ─────────────────────────────────────────────────────────────────────────────
23
+ // #region Public types
26
24
 
27
25
  export interface DevtoolsIncomingMessage {
28
26
  type: string;
@@ -39,9 +37,9 @@ export interface EnableDevtoolsOptions {
39
37
  port?: number;
40
38
  }
41
39
 
42
- // ─────────────────────────────────────────────────────────────────────────────
43
- // Session state
44
- // ─────────────────────────────────────────────────────────────────────────────
40
+ // #endregion
41
+
42
+ // #region Session state
45
43
 
46
44
  let transportState: DevtoolsTransportState | null = null;
47
45
  let transportPromise: Promise<DevtoolsTransportState> | null = null;
@@ -55,9 +53,9 @@ let tempDbPath: string | null = null;
55
53
  let subscribedPromise: Promise<void> | null = null;
56
54
  let resolveSubscribed: (() => void) | null = null;
57
55
 
58
- // ─────────────────────────────────────────────────────────────────────────────
59
- // Per-client subscription state
60
- // ─────────────────────────────────────────────────────────────────────────────
56
+ // #endregion
57
+
58
+ // #region Per-client subscription state
61
59
 
62
60
  interface ClientState {
63
61
  subscriptions: Set<ChangeChannel>;
@@ -73,6 +71,15 @@ function eventToMessageType(event: ChangeEvent): string {
73
71
  removed: "render:node_removed",
74
72
  reset: "render:reset",
75
73
  },
74
+ components: {
75
+ added: "component:added",
76
+ updated: "component:updated",
77
+ removed: "component:removed",
78
+ },
79
+ component_roots: {
80
+ added: "component:root_added",
81
+ removed: "component:root_removed",
82
+ },
76
83
  effects: { added: "effect:added", updated: "effect:updated" },
77
84
  refs: { added: "ref:added" },
78
85
  edges: { added: `edge:${(event.data as any).edge_type ?? "track"}` },
@@ -108,6 +115,8 @@ function channelToInitialMessageType(
108
115
  ): string {
109
116
  const map: Record<string, string> = {
110
117
  render: "render:node_added",
118
+ components: "component:added",
119
+ component_roots: "component:root_added",
111
120
  effects: "effect:added",
112
121
  refs: "ref:added",
113
122
  symbols: "symbol:added",
@@ -141,9 +150,9 @@ function sendInitialState(socket: any, channels: ChangeChannel[]): void {
141
150
  }
142
151
  }
143
152
 
144
- // ─────────────────────────────────────────────────────────────────────────────
145
- // Environment helpers
146
- // ─────────────────────────────────────────────────────────────────────────────
153
+ // #endregion
154
+
155
+ // #region Environment helpers
147
156
 
148
157
  function isNodeEnvironment() {
149
158
  return (
@@ -158,12 +167,24 @@ function isNodeEnvironment() {
158
167
  let _envDebugEnabled: boolean =
159
168
  isNodeEnvironment() && Boolean(process.env.ALLOY_DEBUG);
160
169
 
170
+ // Cached value of `devtoolsExplicitlyEnabled || _envDebugEnabled`. This
171
+ // function is called on hot paths (every effect/scheduler tick), so we
172
+ // avoid recomputing the OR + the `isNodeEnvironment` check on every call.
173
+ // The cache is invalidated whenever either underlying flag mutates.
174
+ let _devtoolsEnabledCache: boolean = isNodeEnvironment() && _envDebugEnabled;
175
+
176
+ function refreshDevtoolsEnabledCache(): void {
177
+ _devtoolsEnabledCache =
178
+ isNodeEnvironment() && (devtoolsExplicitlyEnabled || _envDebugEnabled);
179
+ }
180
+
161
181
  /**
162
182
  * Invalidates the cached env-var result for isDevtoolsEnabled(). Call this in
163
183
  * test beforeEach hooks after modifying process.env.ALLOY_DEBUG.
164
184
  */
165
185
  export function refreshDebugState(): void {
166
186
  _envDebugEnabled = isNodeEnvironment() && Boolean(process.env.ALLOY_DEBUG);
187
+ refreshDevtoolsEnabledCache();
167
188
  }
168
189
 
169
190
  function getCwd() {
@@ -183,14 +204,13 @@ function resolveDebugPort() {
183
204
  return parsed;
184
205
  }
185
206
 
186
- // ─────────────────────────────────────────────────────────────────────────────
187
- // Query functions
188
- // ─────────────────────────────────────────────────────────────────────────────
207
+ // #endregion
208
+
209
+ // #region Query functions
189
210
 
190
211
  /** Returns true when devtools are enabled (via env var or explicit call). */
191
212
  export function isDevtoolsEnabled() {
192
- if (!isNodeEnvironment()) return false;
193
- return devtoolsExplicitlyEnabled || _envDebugEnabled;
213
+ return _devtoolsEnabledCache;
194
214
  }
195
215
 
196
216
  /** Returns true when a devtools client is currently connected. */
@@ -204,9 +224,9 @@ export function getDevtoolsServerInfo(): DevtoolsServerInfo | null {
204
224
  return { port: transportState.port, connected: transportState.connected };
205
225
  }
206
226
 
207
- // ─────────────────────────────────────────────────────────────────────────────
208
- // Temp SQLite for devtools
209
- // ─────────────────────────────────────────────────────────────────────────────
227
+ // #endregion
228
+
229
+ // #region Temp SQLite for devtools
210
230
 
211
231
  async function ensureSqliteForDevtools(): Promise<void> {
212
232
  if (isTraceEnabled()) return;
@@ -236,9 +256,9 @@ async function ensureSqliteForDevtools(): Promise<void> {
236
256
  });
237
257
  }
238
258
 
239
- // ─────────────────────────────────────────────────────────────────────────────
240
- // Server lifecycle
241
- // ─────────────────────────────────────────────────────────────────────────────
259
+ // #endregion
260
+
261
+ // #region Server lifecycle
242
262
 
243
263
  async function ensureServer(): Promise<DevtoolsTransportState> {
244
264
  if (transportState) return transportState;
@@ -350,9 +370,9 @@ async function ensureServer(): Promise<DevtoolsTransportState> {
350
370
  return transportPromise;
351
371
  }
352
372
 
353
- // ─────────────────────────────────────────────────────────────────────────────
354
- // Public API
355
- // ─────────────────────────────────────────────────────────────────────────────
373
+ // #endregion
374
+
375
+ // #region Public API
356
376
 
357
377
  /**
358
378
  * Wait for a devtools client to connect before proceeding.
@@ -371,6 +391,7 @@ async function ensureServer(): Promise<DevtoolsTransportState> {
371
391
  */
372
392
  export async function waitForDevtoolsConnection(): Promise<void> {
373
393
  devtoolsExplicitlyEnabled = true;
394
+ refreshDevtoolsEnabledCache();
374
395
  const server = await ensureServer();
375
396
  if (!server.connected) {
376
397
  await server.ready;
@@ -392,6 +413,7 @@ export async function enableDevtools(
392
413
  options?: EnableDevtoolsOptions,
393
414
  ): Promise<DevtoolsServerInfo> {
394
415
  devtoolsExplicitlyEnabled = true;
416
+ refreshDevtoolsEnabledCache();
395
417
  devtoolsInitialized = true;
396
418
  if (options?.port !== undefined) {
397
419
  configuredPort = options.port;
@@ -435,9 +457,9 @@ export async function enableDevtoolsAndConnect(
435
457
  return { port: transportState!.port, connected: true };
436
458
  }
437
459
 
438
- // ─────────────────────────────────────────────────────────────────────────────
439
- // Messaging
440
- // ─────────────────────────────────────────────────────────────────────────────
460
+ // #endregion
461
+
462
+ // #region Messaging
441
463
 
442
464
  /** Register a handler for incoming devtools messages. Returns an unsubscribe function. */
443
465
  export function registerDevtoolsMessageHandler(
@@ -457,9 +479,9 @@ export function assertDevtoolsConnectedForSyncRender() {
457
479
  }
458
480
  }
459
481
 
460
- // ─────────────────────────────────────────────────────────────────────────────
461
- // Test utilities
462
- // ─────────────────────────────────────────────────────────────────────────────
482
+ // #endregion
483
+
484
+ // #region Test utilities
463
485
 
464
486
  /** Reset all devtools state. For use in tests only. */
465
487
  export async function resetDevtoolsServerForTests() {
@@ -471,6 +493,7 @@ export async function resetDevtoolsServerForTests() {
471
493
  transportState = null;
472
494
  transportPromise = null;
473
495
  devtoolsExplicitlyEnabled = false;
496
+ refreshDevtoolsEnabledCache();
474
497
  devtoolsInitialized = false;
475
498
  configuredPort = undefined;
476
499
  loggedDevtoolsLinks = false;
@@ -481,3 +504,5 @@ export async function resetDevtoolsServerForTests() {
481
504
  // Close the trace DB so each test starts fresh
482
505
  closeTrace();
483
506
  }
507
+
508
+ // #endregion