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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (656) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/dev/src/components/AccessExpression.test.js +30 -38
  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 +16 -18
  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 +5 -5
  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/children.test.js +9 -11
  88. package/dist/dev/test/children.test.js.map +1 -1
  89. package/dist/dev/test/components/append-file.test.js +26 -27
  90. package/dist/dev/test/components/append-file.test.js.map +1 -1
  91. package/dist/dev/test/components/block.test.js +9 -11
  92. package/dist/dev/test/components/block.test.js.map +1 -1
  93. package/dist/dev/test/components/copy-file.test.js +1 -2
  94. package/dist/dev/test/components/copy-file.test.js.map +1 -1
  95. package/dist/dev/test/components/declaration.test.js +2 -2
  96. package/dist/dev/test/components/declaration.test.js.map +1 -1
  97. package/dist/dev/test/components/list.test.js +41 -43
  98. package/dist/dev/test/components/list.test.js.map +1 -1
  99. package/dist/dev/test/components/prose.test.js +4 -5
  100. package/dist/dev/test/components/prose.test.js.map +1 -1
  101. package/dist/dev/test/components/reference-or-content.test.js +32 -33
  102. package/dist/dev/test/components/reference-or-content.test.js.map +1 -1
  103. package/dist/dev/test/components/source-file.test.js +8 -7
  104. package/dist/dev/test/components/source-file.test.js.map +1 -1
  105. package/dist/dev/test/components/template-file.test.js +16 -17
  106. package/dist/dev/test/components/template-file.test.js.map +1 -1
  107. package/dist/dev/test/components/update-file.test.js +11 -12
  108. package/dist/dev/test/components/update-file.test.js.map +1 -1
  109. package/dist/dev/test/components/wrap.test.js +6 -8
  110. package/dist/dev/test/components/wrap.test.js.map +1 -1
  111. package/dist/dev/test/control-flow/for.test.js +58 -42
  112. package/dist/dev/test/control-flow/for.test.js.map +1 -1
  113. package/dist/dev/test/control-flow/match.test.js +15 -17
  114. package/dist/dev/test/control-flow/match.test.js.map +1 -1
  115. package/dist/dev/test/control-flow/show.test.js +5 -8
  116. package/dist/dev/test/control-flow/show.test.js.map +1 -1
  117. package/dist/dev/test/lazy-isempty.test.js +29 -31
  118. package/dist/dev/test/lazy-isempty.test.js.map +1 -1
  119. package/dist/dev/test/name-policy.test.js +2 -3
  120. package/dist/dev/test/name-policy.test.js.map +1 -1
  121. package/dist/dev/test/node.test.js +80 -0
  122. package/dist/dev/test/node.test.js.map +1 -0
  123. package/dist/dev/test/output-e2e.test.js +194 -0
  124. package/dist/dev/test/output-e2e.test.js.map +1 -0
  125. package/dist/dev/test/reactivity/circular-reactives.test.js +9 -9
  126. package/dist/dev/test/reactivity/circular-reactives.test.js.map +1 -1
  127. package/dist/dev/test/reactivity/cleanup.test.js +5 -6
  128. package/dist/dev/test/reactivity/cleanup.test.js.map +1 -1
  129. package/dist/dev/test/reactivity/ref-rendering.test.js +15 -15
  130. package/dist/dev/test/reactivity/ref-rendering.test.js.map +1 -1
  131. package/dist/dev/test/reactivity/test.test.js +18 -18
  132. package/dist/dev/test/reactivity/test.test.js.map +1 -1
  133. package/dist/dev/test/rendering/basic.test.js +18 -19
  134. package/dist/dev/test/rendering/basic.test.js.map +1 -1
  135. package/dist/dev/test/rendering/code.test.js +2 -3
  136. package/dist/dev/test/rendering/code.test.js.map +1 -1
  137. package/dist/dev/test/rendering/formatting.test.js +115 -121
  138. package/dist/dev/test/rendering/formatting.test.js.map +1 -1
  139. package/dist/dev/test/rendering/indent.test.js +23 -24
  140. package/dist/dev/test/rendering/indent.test.js.map +1 -1
  141. package/dist/dev/test/rendering/memoization.test.js +9 -5
  142. package/dist/dev/test/rendering/memoization.test.js.map +1 -1
  143. package/dist/dev/test/rendering/print-render-stack.test.js +20 -21
  144. package/dist/dev/test/rendering/print-render-stack.test.js.map +1 -1
  145. package/dist/dev/test/rendering/refkeys.test.js +1 -2
  146. package/dist/dev/test/rendering/refkeys.test.js.map +1 -1
  147. package/dist/dev/test/rendering/render-output-diagnostics.test.js +102 -0
  148. package/dist/dev/test/rendering/render-output-diagnostics.test.js.map +1 -0
  149. package/dist/dev/test/runtime.test.js +385 -0
  150. package/dist/dev/test/runtime.test.js.map +1 -0
  151. package/dist/dev/test/stc.test.js +0 -1
  152. package/dist/dev/test/stc.test.js.map +1 -1
  153. package/dist/dev/test/tree-test-utils.js +16 -0
  154. package/dist/dev/test/tree-test-utils.js.map +1 -0
  155. package/dist/dev/test/utils.test.js +34 -33
  156. package/dist/dev/test/utils.test.js.map +1 -1
  157. package/dist/dev/test/vitest.setup.js +2 -0
  158. package/dist/dev/test/vitest.setup.js.map +1 -0
  159. package/dist/dev/testing/devtools-utils.js +1 -1
  160. package/dist/dev/testing/devtools-utils.js.map +1 -1
  161. package/dist/dev/testing/extend-expect.js +30 -34
  162. package/dist/dev/testing/extend-expect.js.map +1 -1
  163. package/dist/dev/testing/render.js +7 -17
  164. package/dist/dev/testing/render.js.map +1 -1
  165. package/dist/devtools/index.html +17 -17
  166. package/dist/src/components/AccessExpression.test.d.ts +1 -1
  167. package/dist/src/components/AccessExpression.test.d.ts.map +1 -1
  168. package/dist/src/components/AccessExpression.test.js +5 -13
  169. package/dist/src/components/AccessExpression.test.js.map +1 -1
  170. package/dist/src/components/Output.d.ts +1 -1
  171. package/dist/src/components/Output.d.ts.map +1 -1
  172. package/dist/src/components/Output.js +2 -1
  173. package/dist/src/components/Output.js.map +1 -1
  174. package/dist/src/components/ReferenceOrContent.d.ts +1 -1
  175. package/dist/src/components/ReferenceOrContent.d.ts.map +1 -1
  176. package/dist/src/components/SourceFile.d.ts +1 -1
  177. package/dist/src/components/SourceFile.d.ts.map +1 -1
  178. package/dist/src/components/SourceFile.js.map +1 -1
  179. package/dist/src/content-slot.test.d.ts +1 -1
  180. package/dist/src/content-slot.test.d.ts.map +1 -1
  181. package/dist/src/content-slot.test.js +8 -10
  182. package/dist/src/content-slot.test.js.map +1 -1
  183. package/dist/src/context/format-options.d.ts +1 -1
  184. package/dist/src/context/format-options.d.ts.map +1 -1
  185. package/dist/src/context.d.ts +9 -1
  186. package/dist/src/context.d.ts.map +1 -1
  187. package/dist/src/context.js +30 -3
  188. package/dist/src/context.js.map +1 -1
  189. package/dist/src/debug/diagnostics.test.js +1 -1
  190. package/dist/src/debug/diagnostics.test.js.map +1 -1
  191. package/dist/src/debug/effects.test.js +1 -1
  192. package/dist/src/debug/effects.test.js.map +1 -1
  193. package/dist/src/debug/file-streaming.d.ts +22 -0
  194. package/dist/src/debug/file-streaming.d.ts.map +1 -0
  195. package/dist/src/debug/file-streaming.js +103 -0
  196. package/dist/src/debug/file-streaming.js.map +1 -0
  197. package/dist/src/debug/files.test.js +4 -5
  198. package/dist/src/debug/files.test.js.map +1 -1
  199. package/dist/src/debug/index.d.ts +5 -7
  200. package/dist/src/debug/index.d.ts.map +1 -1
  201. package/dist/src/debug/index.js +4 -6
  202. package/dist/src/debug/index.js.map +1 -1
  203. package/dist/src/debug/message-format.test.js +16 -18
  204. package/dist/src/debug/message-format.test.js.map +1 -1
  205. package/dist/src/debug/render-tree-orphans.test.js +8 -18
  206. package/dist/src/debug/render-tree-orphans.test.js.map +1 -1
  207. package/dist/src/debug/render.d.ts +71 -21
  208. package/dist/src/debug/render.d.ts.map +1 -1
  209. package/dist/src/debug/render.js +529 -352
  210. package/dist/src/debug/render.js.map +1 -1
  211. package/dist/src/debug/render.test.js +137 -74
  212. package/dist/src/debug/render.test.js.map +1 -1
  213. package/dist/src/debug/trace-writer.d.ts +6 -1
  214. package/dist/src/debug/trace-writer.d.ts.map +1 -1
  215. package/dist/src/debug/trace-writer.js +127 -15
  216. package/dist/src/debug/trace-writer.js.map +1 -1
  217. package/dist/src/debug/trace.d.ts +0 -36
  218. package/dist/src/debug/trace.d.ts.map +1 -1
  219. package/dist/src/debug/trace.js +0 -36
  220. package/dist/src/debug/trace.js.map +1 -1
  221. package/dist/src/devtools/devtools-protocol.d.ts +34 -1
  222. package/dist/src/devtools/devtools-protocol.d.ts.map +1 -1
  223. package/dist/src/devtools/devtools-server.d.ts.map +1 -1
  224. package/dist/src/devtools/devtools-server.js +55 -32
  225. package/dist/src/devtools/devtools-server.js.map +1 -1
  226. package/dist/src/devtools-entry.browser.d.ts +1 -1
  227. package/dist/src/devtools-entry.browser.d.ts.map +1 -1
  228. package/dist/src/devtools-entry.browser.js.map +1 -1
  229. package/dist/src/devtools-entry.d.ts +1 -1
  230. package/dist/src/devtools-entry.d.ts.map +1 -1
  231. package/dist/src/devtools-entry.js.map +1 -1
  232. package/dist/src/diagnostics.d.ts +4 -0
  233. package/dist/src/diagnostics.d.ts.map +1 -1
  234. package/dist/src/diagnostics.js +19 -1
  235. package/dist/src/diagnostics.js.map +1 -1
  236. package/dist/src/index.d.ts +5 -2
  237. package/dist/src/index.d.ts.map +1 -1
  238. package/dist/src/index.js +5 -2
  239. package/dist/src/index.js.map +1 -1
  240. package/dist/src/jsx-runtime.d.ts +13 -4
  241. package/dist/src/jsx-runtime.d.ts.map +1 -1
  242. package/dist/src/jsx-runtime.js +14 -8
  243. package/dist/src/jsx-runtime.js.map +1 -1
  244. package/dist/src/output-types.d.ts +40 -0
  245. package/dist/src/output-types.d.ts.map +1 -0
  246. package/dist/src/output-types.js +2 -0
  247. package/dist/src/output-types.js.map +1 -0
  248. package/dist/src/reactivity.d.ts +49 -18
  249. package/dist/src/reactivity.d.ts.map +1 -1
  250. package/dist/src/reactivity.js +155 -13
  251. package/dist/src/reactivity.js.map +1 -1
  252. package/dist/src/render/get-string-width.d.ts +19 -0
  253. package/dist/src/render/get-string-width.d.ts.map +1 -0
  254. package/dist/src/render/get-string-width.js +61 -0
  255. package/dist/src/render/get-string-width.js.map +1 -0
  256. package/dist/src/render/index.d.ts +2 -0
  257. package/dist/src/render/index.d.ts.map +1 -0
  258. package/dist/src/render/index.js +2 -0
  259. package/dist/src/render/index.js.map +1 -0
  260. package/dist/src/render/node-context.d.ts +5 -0
  261. package/dist/src/render/node-context.d.ts.map +1 -0
  262. package/dist/src/render/node-context.js +7 -0
  263. package/dist/src/render/node-context.js.map +1 -0
  264. package/dist/src/render/node.d.ts +146 -0
  265. package/dist/src/render/node.d.ts.map +1 -0
  266. package/dist/src/render/node.js +386 -0
  267. package/dist/src/render/node.js.map +1 -0
  268. package/dist/src/render/printer-support.d.ts +50 -0
  269. package/dist/src/render/printer-support.d.ts.map +1 -0
  270. package/dist/src/render/printer-support.js +180 -0
  271. package/dist/src/render/printer-support.js.map +1 -0
  272. package/dist/src/render/printer.d.ts +35 -0
  273. package/dist/src/render/printer.d.ts.map +1 -0
  274. package/dist/src/render/printer.js +797 -0
  275. package/dist/src/render/printer.js.map +1 -0
  276. package/dist/src/render-error.d.ts +4 -0
  277. package/dist/src/render-error.d.ts.map +1 -0
  278. package/dist/src/render-error.js +79 -0
  279. package/dist/src/render-error.js.map +1 -0
  280. package/dist/src/render-output.d.ts +42 -0
  281. package/dist/src/render-output.d.ts.map +1 -0
  282. package/dist/src/render-output.js +209 -0
  283. package/dist/src/render-output.js.map +1 -0
  284. package/dist/src/runtime/component.d.ts +2 -2
  285. package/dist/src/runtime/component.d.ts.map +1 -1
  286. package/dist/src/runtime/create-intrinsic.d.ts +28 -0
  287. package/dist/src/runtime/create-intrinsic.d.ts.map +1 -0
  288. package/dist/src/runtime/create-intrinsic.js +53 -0
  289. package/dist/src/runtime/create-intrinsic.js.map +1 -0
  290. package/dist/src/runtime/fragment.d.ts +16 -0
  291. package/dist/src/runtime/fragment.d.ts.map +1 -0
  292. package/dist/src/runtime/fragment.js +21 -0
  293. package/dist/src/runtime/fragment.js.map +1 -0
  294. package/dist/src/runtime/index.d.ts +12 -0
  295. package/dist/src/runtime/index.d.ts.map +1 -0
  296. package/dist/src/runtime/index.js +13 -0
  297. package/dist/src/runtime/index.js.map +1 -0
  298. package/dist/src/runtime/insert.d.ts +29 -0
  299. package/dist/src/runtime/insert.d.ts.map +1 -0
  300. package/dist/src/runtime/insert.js +453 -0
  301. package/dist/src/runtime/insert.js.map +1 -0
  302. package/dist/src/runtime/intrinsic.d.ts +12 -29
  303. package/dist/src/runtime/intrinsic.d.ts.map +1 -1
  304. package/dist/src/runtime/intrinsic.js +1 -11
  305. package/dist/src/runtime/intrinsic.js.map +1 -1
  306. package/dist/src/scheduler.d.ts.map +1 -1
  307. package/dist/src/scheduler.js +38 -14
  308. package/dist/src/scheduler.js.map +1 -1
  309. package/dist/src/stc.d.ts.map +1 -1
  310. package/dist/src/stc.js +2 -0
  311. package/dist/src/stc.js.map +1 -1
  312. package/dist/src/sti.d.ts +7 -6
  313. package/dist/src/sti.d.ts.map +1 -1
  314. package/dist/src/sti.js +1 -1
  315. package/dist/src/sti.js.map +1 -1
  316. package/dist/src/symbols/symbol-slot.test.js +5 -5
  317. package/dist/src/symbols/symbol-slot.test.js.map +1 -1
  318. package/dist/src/test-render.d.ts +31 -0
  319. package/dist/src/test-render.d.ts.map +1 -0
  320. package/dist/src/test-render.js +78 -0
  321. package/dist/src/test-render.js.map +1 -0
  322. package/dist/src/utils.d.ts +1 -1
  323. package/dist/src/utils.d.ts.map +1 -1
  324. package/dist/src/utils.js +40 -28
  325. package/dist/src/utils.js.map +1 -1
  326. package/dist/src/write-output.d.ts +1 -1
  327. package/dist/src/write-output.d.ts.map +1 -1
  328. package/dist/test/babel-e2e.test.d.ts +13 -0
  329. package/dist/test/babel-e2e.test.d.ts.map +1 -0
  330. package/dist/test/babel-e2e.test.js +218 -0
  331. package/dist/test/babel-e2e.test.js.map +1 -0
  332. package/dist/test/children.test.js +5 -7
  333. package/dist/test/children.test.js.map +1 -1
  334. package/dist/test/components/append-file.test.d.ts +1 -1
  335. package/dist/test/components/append-file.test.d.ts.map +1 -1
  336. package/dist/test/components/append-file.test.js +0 -1
  337. package/dist/test/components/append-file.test.js.map +1 -1
  338. package/dist/test/components/block.test.d.ts +1 -1
  339. package/dist/test/components/block.test.d.ts.map +1 -1
  340. package/dist/test/components/block.test.js +4 -6
  341. package/dist/test/components/block.test.js.map +1 -1
  342. package/dist/test/components/copy-file.test.d.ts +1 -1
  343. package/dist/test/components/copy-file.test.d.ts.map +1 -1
  344. package/dist/test/components/copy-file.test.js +1 -2
  345. package/dist/test/components/copy-file.test.js.map +1 -1
  346. package/dist/test/components/declaration.test.js +2 -2
  347. package/dist/test/components/declaration.test.js.map +1 -1
  348. package/dist/test/components/list.test.d.ts +1 -1
  349. package/dist/test/components/list.test.d.ts.map +1 -1
  350. package/dist/test/components/list.test.js +20 -22
  351. package/dist/test/components/list.test.js.map +1 -1
  352. package/dist/test/components/prose.test.d.ts +1 -1
  353. package/dist/test/components/prose.test.d.ts.map +1 -1
  354. package/dist/test/components/prose.test.js +0 -1
  355. package/dist/test/components/prose.test.js.map +1 -1
  356. package/dist/test/components/reference-or-content.test.js +8 -9
  357. package/dist/test/components/reference-or-content.test.js.map +1 -1
  358. package/dist/test/components/source-file.test.d.ts +1 -1
  359. package/dist/test/components/source-file.test.d.ts.map +1 -1
  360. package/dist/test/components/source-file.test.js +5 -4
  361. package/dist/test/components/source-file.test.js.map +1 -1
  362. package/dist/test/components/template-file.test.d.ts +1 -1
  363. package/dist/test/components/template-file.test.d.ts.map +1 -1
  364. package/dist/test/components/template-file.test.js +0 -1
  365. package/dist/test/components/template-file.test.js.map +1 -1
  366. package/dist/test/components/update-file.test.d.ts +1 -1
  367. package/dist/test/components/update-file.test.d.ts.map +1 -1
  368. package/dist/test/components/update-file.test.js +1 -2
  369. package/dist/test/components/update-file.test.js.map +1 -1
  370. package/dist/test/components/wrap.test.d.ts +1 -1
  371. package/dist/test/components/wrap.test.d.ts.map +1 -1
  372. package/dist/test/components/wrap.test.js +3 -5
  373. package/dist/test/components/wrap.test.js.map +1 -1
  374. package/dist/test/control-flow/for.test.d.ts +1 -1
  375. package/dist/test/control-flow/for.test.d.ts.map +1 -1
  376. package/dist/test/control-flow/for.test.js +40 -24
  377. package/dist/test/control-flow/for.test.js.map +1 -1
  378. package/dist/test/control-flow/match.test.d.ts +1 -1
  379. package/dist/test/control-flow/match.test.d.ts.map +1 -1
  380. package/dist/test/control-flow/match.test.js +4 -6
  381. package/dist/test/control-flow/match.test.js.map +1 -1
  382. package/dist/test/control-flow/show.test.d.ts +1 -1
  383. package/dist/test/control-flow/show.test.d.ts.map +1 -1
  384. package/dist/test/control-flow/show.test.js +3 -6
  385. package/dist/test/control-flow/show.test.js.map +1 -1
  386. package/dist/test/lazy-isempty.test.d.ts +1 -1
  387. package/dist/test/lazy-isempty.test.d.ts.map +1 -1
  388. package/dist/test/lazy-isempty.test.js +16 -18
  389. package/dist/test/lazy-isempty.test.js.map +1 -1
  390. package/dist/test/name-policy.test.d.ts +1 -1
  391. package/dist/test/name-policy.test.d.ts.map +1 -1
  392. package/dist/test/name-policy.test.js +0 -1
  393. package/dist/test/name-policy.test.js.map +1 -1
  394. package/dist/test/node.test.d.ts +2 -0
  395. package/dist/test/node.test.d.ts.map +1 -0
  396. package/dist/test/node.test.js +80 -0
  397. package/dist/test/node.test.js.map +1 -0
  398. package/dist/test/output-e2e.test.d.ts +13 -0
  399. package/dist/test/output-e2e.test.d.ts.map +1 -0
  400. package/dist/test/output-e2e.test.js +194 -0
  401. package/dist/test/output-e2e.test.js.map +1 -0
  402. package/dist/test/reactivity/circular-reactives.test.js +6 -6
  403. package/dist/test/reactivity/circular-reactives.test.js.map +1 -1
  404. package/dist/test/reactivity/cleanup.test.js +2 -3
  405. package/dist/test/reactivity/cleanup.test.js.map +1 -1
  406. package/dist/test/reactivity/ref-rendering.test.js +15 -15
  407. package/dist/test/reactivity/ref-rendering.test.js.map +1 -1
  408. package/dist/test/reactivity/test.test.js +15 -15
  409. package/dist/test/reactivity/test.test.js.map +1 -1
  410. package/dist/test/rendering/basic.test.d.ts +1 -1
  411. package/dist/test/rendering/basic.test.d.ts.map +1 -1
  412. package/dist/test/rendering/basic.test.js +0 -1
  413. package/dist/test/rendering/basic.test.js.map +1 -1
  414. package/dist/test/rendering/code.test.d.ts +1 -1
  415. package/dist/test/rendering/code.test.d.ts.map +1 -1
  416. package/dist/test/rendering/code.test.js +0 -1
  417. package/dist/test/rendering/code.test.js.map +1 -1
  418. package/dist/test/rendering/formatting.test.d.ts +1 -1
  419. package/dist/test/rendering/formatting.test.d.ts.map +1 -1
  420. package/dist/test/rendering/formatting.test.js +17 -23
  421. package/dist/test/rendering/formatting.test.js.map +1 -1
  422. package/dist/test/rendering/indent.test.d.ts +1 -1
  423. package/dist/test/rendering/indent.test.d.ts.map +1 -1
  424. package/dist/test/rendering/indent.test.js +0 -1
  425. package/dist/test/rendering/indent.test.js.map +1 -1
  426. package/dist/test/rendering/memoization.test.js +7 -3
  427. package/dist/test/rendering/memoization.test.js.map +1 -1
  428. package/dist/test/rendering/print-render-stack.test.d.ts +1 -1
  429. package/dist/test/rendering/print-render-stack.test.d.ts.map +1 -1
  430. package/dist/test/rendering/print-render-stack.test.js +0 -1
  431. package/dist/test/rendering/print-render-stack.test.js.map +1 -1
  432. package/dist/test/rendering/refkeys.test.d.ts +1 -1
  433. package/dist/test/rendering/refkeys.test.d.ts.map +1 -1
  434. package/dist/test/rendering/refkeys.test.js +0 -1
  435. package/dist/test/rendering/refkeys.test.js.map +1 -1
  436. package/dist/test/rendering/render-output-diagnostics.test.d.ts +2 -0
  437. package/dist/test/rendering/render-output-diagnostics.test.d.ts.map +1 -0
  438. package/dist/test/rendering/render-output-diagnostics.test.js +82 -0
  439. package/dist/test/rendering/render-output-diagnostics.test.js.map +1 -0
  440. package/dist/test/runtime.test.d.ts +11 -0
  441. package/dist/test/runtime.test.d.ts.map +1 -0
  442. package/dist/test/runtime.test.js +385 -0
  443. package/dist/test/runtime.test.js.map +1 -0
  444. package/dist/test/stc.test.d.ts +1 -1
  445. package/dist/test/stc.test.d.ts.map +1 -1
  446. package/dist/test/stc.test.js +0 -1
  447. package/dist/test/stc.test.js.map +1 -1
  448. package/dist/test/tree-test-utils.d.ts +3 -0
  449. package/dist/test/tree-test-utils.d.ts.map +1 -0
  450. package/dist/test/tree-test-utils.js +16 -0
  451. package/dist/test/tree-test-utils.js.map +1 -0
  452. package/dist/test/utils.test.d.ts +1 -1
  453. package/dist/test/utils.test.d.ts.map +1 -1
  454. package/dist/test/utils.test.js +12 -11
  455. package/dist/test/utils.test.js.map +1 -1
  456. package/dist/test/vitest.setup.d.ts +2 -0
  457. package/dist/test/vitest.setup.d.ts.map +1 -0
  458. package/dist/test/vitest.setup.js +2 -0
  459. package/dist/test/vitest.setup.js.map +1 -0
  460. package/dist/testing/devtools-utils.d.ts.map +1 -1
  461. package/dist/testing/devtools-utils.js +1 -1
  462. package/dist/testing/devtools-utils.js.map +1 -1
  463. package/dist/testing/extend-expect.d.ts.map +1 -1
  464. package/dist/testing/extend-expect.js +30 -34
  465. package/dist/testing/extend-expect.js.map +1 -1
  466. package/dist/testing/render.d.ts +7 -9
  467. package/dist/testing/render.d.ts.map +1 -1
  468. package/dist/testing/render.js +7 -17
  469. package/dist/testing/render.js.map +1 -1
  470. package/dist/tsconfig.tsbuildinfo +1 -1
  471. package/docs/api/components/Output.md +0 -3
  472. package/docs/api/components/SourceFile.md +0 -3
  473. package/docs/api/functions/createComment.md +18 -0
  474. package/docs/api/functions/createElement.md +19 -0
  475. package/docs/api/functions/createFragment.md +17 -0
  476. package/docs/api/functions/createTextNode.md +18 -0
  477. package/docs/api/functions/emitDiagnosticForTree.md +19 -0
  478. package/docs/api/functions/ensureIsEmpty.md +1 -1
  479. package/docs/api/functions/getContextForNode.md +18 -0
  480. package/docs/api/functions/getContextForRenderNode.md +4 -4
  481. package/docs/api/functions/getDiagnosticsForTree.md +7 -5
  482. package/docs/api/functions/getRegisteredDiagnosticsForTree.md +18 -0
  483. package/docs/api/functions/index.md +17 -12
  484. package/docs/api/functions/isCustomContext.md +4 -4
  485. package/docs/api/functions/notifyContentState.md +6 -0
  486. package/docs/api/functions/printTree.md +6 -16
  487. package/docs/api/functions/registerDiagnosticsForTree.md +19 -0
  488. package/docs/api/functions/render.md +1 -2
  489. package/docs/api/functions/renderAsync.md +1 -2
  490. package/docs/api/functions/renderTree.md +8 -5
  491. package/docs/api/functions/reportDiagnosticsForTree.md +18 -0
  492. package/docs/api/functions/runInContext.md +28 -0
  493. package/docs/api/functions/sourceFilesForTree.md +6 -16
  494. package/docs/api/index.md +3 -3
  495. package/docs/api/testing/functions/index.md +1 -1
  496. package/docs/api/testing/functions/renderToString.md +1 -1
  497. package/docs/api/types/AlloyNode.md +22 -0
  498. package/docs/api/types/Child.md +1 -1
  499. package/docs/api/types/CommentNode.md +15 -0
  500. package/docs/api/types/Context.md +13 -15
  501. package/docs/api/types/ElementNode.md +18 -0
  502. package/docs/api/types/FragmentNode.md +12 -0
  503. package/docs/api/types/Insertable.md +7 -0
  504. package/docs/api/types/NodeType.md +5 -0
  505. package/docs/api/types/OutputDirectory.md +0 -50
  506. package/docs/api/types/PrintTreeOptions.md +0 -1
  507. package/docs/api/types/RenderTreeOptions.md +7 -0
  508. package/docs/api/types/StiComponentCreator.md +4 -4
  509. package/docs/api/types/StiSignature.md +1 -1
  510. package/docs/api/types/TextNode.md +16 -0
  511. package/docs/api/types/index.md +10 -28
  512. package/docs/api/variables/COMMENT_NODE.md +5 -0
  513. package/docs/api/variables/ELEMENT_NODE.md +11 -0
  514. package/docs/api/variables/FRAGMENT_NODE.md +5 -0
  515. package/docs/api/variables/TEXT_NODE.md +5 -0
  516. package/docs/api/variables/index.md +4 -2
  517. package/docs/formatting.md +1 -1
  518. package/docs/rendering.md +4 -4
  519. package/package.json +6 -6
  520. package/src/components/AccessExpression.test.tsx +5 -13
  521. package/src/components/Output.tsx +2 -1
  522. package/src/components/SourceFile.tsx +1 -1
  523. package/src/content-slot.test.tsx +8 -10
  524. package/src/context/format-options.ts +1 -1
  525. package/src/context.ts +37 -4
  526. package/src/debug/diagnostics.test.tsx +1 -1
  527. package/src/debug/effects.test.tsx +1 -1
  528. package/src/debug/file-streaming.ts +115 -0
  529. package/src/debug/files.test.tsx +15 -11
  530. package/src/debug/index.ts +11 -11
  531. package/src/debug/message-format.test.tsx +32 -19
  532. package/src/debug/render-tree-orphans.test.tsx +10 -19
  533. package/src/debug/render.test.tsx +206 -78
  534. package/src/debug/render.ts +642 -495
  535. package/src/debug/trace-writer.ts +168 -14
  536. package/src/debug/trace.ts +0 -20
  537. package/src/devtools/devtools-protocol.ts +43 -0
  538. package/src/devtools/devtools-server.ts +57 -32
  539. package/src/devtools-entry.browser.ts +5 -0
  540. package/src/devtools-entry.ts +5 -0
  541. package/src/diagnostics.ts +31 -0
  542. package/src/index.ts +66 -2
  543. package/src/jsx-runtime.ts +16 -14
  544. package/src/output-types.ts +47 -0
  545. package/src/reactivity.ts +186 -40
  546. package/src/render/get-string-width.ts +201 -0
  547. package/src/render/index.ts +1 -0
  548. package/src/render/node-context.ts +14 -0
  549. package/src/render/node.ts +442 -0
  550. package/src/render/printer-support.ts +209 -0
  551. package/src/render/printer.ts +817 -0
  552. package/src/render-error.ts +98 -0
  553. package/src/render-output.ts +243 -0
  554. package/src/runtime/component.ts +2 -2
  555. package/src/runtime/create-intrinsic.ts +56 -0
  556. package/src/runtime/fragment.ts +22 -0
  557. package/src/runtime/index.ts +12 -0
  558. package/src/runtime/insert.ts +569 -0
  559. package/src/runtime/intrinsic.ts +14 -70
  560. package/src/scheduler.ts +40 -25
  561. package/src/stc.ts +3 -0
  562. package/src/sti.ts +17 -20
  563. package/src/symbols/symbol-slot.test.tsx +5 -5
  564. package/src/test-render.ts +103 -0
  565. package/src/utils.tsx +55 -37
  566. package/src/write-output.ts +1 -1
  567. package/temp/api-testing.json +390 -14
  568. package/temp/api.json +4320 -4144
  569. package/test/babel-e2e.test.ts +224 -0
  570. package/test/children.test.tsx +4 -7
  571. package/test/components/append-file.test.tsx +0 -1
  572. package/test/components/block.test.tsx +4 -6
  573. package/test/components/copy-file.test.tsx +2 -2
  574. package/test/components/declaration.test.tsx +2 -2
  575. package/test/components/list.test.tsx +20 -29
  576. package/test/components/prose.test.tsx +0 -1
  577. package/test/components/reference-or-content.test.tsx +8 -9
  578. package/test/components/source-file.test.tsx +4 -4
  579. package/test/components/template-file.test.tsx +0 -1
  580. package/test/components/update-file.test.tsx +1 -2
  581. package/test/components/wrap.test.tsx +3 -5
  582. package/test/control-flow/for.test.tsx +39 -31
  583. package/test/control-flow/match.test.tsx +4 -6
  584. package/test/control-flow/show.test.tsx +3 -6
  585. package/test/lazy-isempty.test.tsx +17 -19
  586. package/test/name-policy.test.tsx +0 -1
  587. package/test/node.test.ts +90 -0
  588. package/test/output-e2e.test.ts +198 -0
  589. package/test/reactivity/circular-reactives.test.tsx +6 -6
  590. package/test/reactivity/cleanup.test.tsx +2 -3
  591. package/test/reactivity/ref-rendering.test.tsx +15 -15
  592. package/test/reactivity/test.test.tsx +14 -14
  593. package/test/rendering/basic.test.tsx +0 -1
  594. package/test/rendering/code.test.tsx +0 -1
  595. package/test/rendering/formatting.test.tsx +21 -29
  596. package/test/rendering/indent.test.tsx +0 -1
  597. package/test/rendering/memoization.test.tsx +7 -3
  598. package/test/rendering/print-render-stack.test.tsx +0 -1
  599. package/test/rendering/refkeys.test.tsx +0 -1
  600. package/test/rendering/render-output-diagnostics.test.tsx +120 -0
  601. package/test/runtime.test.ts +448 -0
  602. package/test/stc.test.tsx +0 -1
  603. package/test/tree-test-utils.ts +23 -0
  604. package/test/utils.test.tsx +10 -9
  605. package/test/vitest.setup.ts +1 -0
  606. package/testing/devtools-utils.ts +2 -0
  607. package/testing/extend-expect.ts +32 -47
  608. package/testing/render.ts +17 -21
  609. package/vitest.config.ts +3 -0
  610. package/dist/dev/src/print-hook.js +0 -10
  611. package/dist/dev/src/print-hook.js.map +0 -1
  612. package/dist/dev/src/render.js +0 -872
  613. package/dist/dev/src/render.js.map +0 -1
  614. package/dist/src/print-hook.d.ts +0 -14
  615. package/dist/src/print-hook.d.ts.map +0 -1
  616. package/dist/src/print-hook.js +0 -10
  617. package/dist/src/print-hook.js.map +0 -1
  618. package/dist/src/render.d.ts +0 -155
  619. package/dist/src/render.d.ts.map +0 -1
  620. package/dist/src/render.js +0 -872
  621. package/dist/src/render.js.map +0 -1
  622. package/docs/api/functions/createIntrinsic.md +0 -19
  623. package/docs/api/functions/createRenderTreeHook.md +0 -19
  624. package/docs/api/functions/getElementCache.md +0 -17
  625. package/docs/api/functions/isIntrinsicElement.md +0 -18
  626. package/docs/api/functions/isPrintHook.md +0 -18
  627. package/docs/api/types/AlignIntrinsicElement.md +0 -5
  628. package/docs/api/types/BrIntrinsicElement.md +0 -5
  629. package/docs/api/types/BreakParentIntrinsicElement.md +0 -5
  630. package/docs/api/types/DedentIntrinsicElement.md +0 -5
  631. package/docs/api/types/DedentToRootIntrinsicElement.md +0 -5
  632. package/docs/api/types/ElementCache.md +0 -5
  633. package/docs/api/types/ElementCacheKey.md +0 -5
  634. package/docs/api/types/FillIntrinsicElement.md +0 -5
  635. package/docs/api/types/GroupIntrinsicElement.md +0 -5
  636. package/docs/api/types/HardlineIntrinsicElement.md +0 -5
  637. package/docs/api/types/HbrIntrinsicElement.md +0 -5
  638. package/docs/api/types/IfBreakIntrinsicElement.md +0 -5
  639. package/docs/api/types/IndentIfBreakIntrinsicElement.md +0 -5
  640. package/docs/api/types/IndentIntrinsicElement.md +0 -5
  641. package/docs/api/types/IntrinsicElement.md +0 -5
  642. package/docs/api/types/IntrinsicElementBase.md +0 -9
  643. package/docs/api/types/LbrIntrinsicElement.md +0 -5
  644. package/docs/api/types/LineIntrinsicElement.md +0 -5
  645. package/docs/api/types/LineSuffixBoundaryIntrinsicElement.md +0 -5
  646. package/docs/api/types/LineSuffixIntrinsicElement.md +0 -5
  647. package/docs/api/types/LiterallineIntrinsicElement.md +0 -5
  648. package/docs/api/types/MarkAsRootIntrinsicElement.md +0 -5
  649. package/docs/api/types/PrintHook.md +0 -10
  650. package/docs/api/types/RenderedTextTree.md +0 -5
  651. package/docs/api/types/SbrIntrinsicElement.md +0 -5
  652. package/docs/api/types/SoftlineIntrinsicElement.md +0 -5
  653. package/docs/api/variables/intrinsicElementKey.md +0 -5
  654. package/docs/api/variables/printHookTag.md +0 -7
  655. package/src/print-hook.ts +0 -22
  656. package/src/render.ts +0 -1154
@@ -1,9 +1,7 @@
1
1
  import { ref } from "@vue/reactivity";
2
2
  import { expect, it } from "vitest";
3
- import "../testing/extend-expect.js";
4
3
  import { Show } from "./components/Show.jsx";
5
4
  import { createContentSlot } from "./content-slot.jsx";
6
- import { printTree, renderTree } from "./render.js";
7
5
 
8
6
  it("knows when its empty", () => {
9
7
  const ContentSlot = createContentSlot();
@@ -31,35 +29,35 @@ it("is reactive", () => {
31
29
  const ContentSlot = createContentSlot();
32
30
  const showContent = ref(false);
33
31
 
34
- const tree = renderTree(
32
+ const tree = (
35
33
  <>
36
34
  {ContentSlot.isEmpty && "It's empty!"}
37
35
  <ContentSlot>
38
36
  <Show when={showContent.value}>Content!</Show>
39
37
  </ContentSlot>
40
- </>,
38
+ </>
41
39
  );
42
40
 
43
- expect(printTree(tree)).toBe(`It's empty!`);
41
+ expect(tree).toRenderTo("It's empty!");
44
42
  showContent.value = true;
45
- expect(printTree(tree)).toBe(`Content!`);
43
+ expect(tree).toRenderTo("Content!");
46
44
  });
47
45
 
48
46
  it("works with WhenEmpty and WhenHasContent", () => {
49
47
  const ContentSlot = createContentSlot();
50
48
  const showContent = ref(false);
51
49
 
52
- const tree = renderTree(
50
+ const tree = (
53
51
  <>
54
52
  <ContentSlot.WhenEmpty>It's empty!</ContentSlot.WhenEmpty>
55
53
  <ContentSlot.WhenHasContent>Has content!</ContentSlot.WhenHasContent>
56
54
  <ContentSlot>
57
55
  <Show when={showContent.value}>Content!</Show>
58
56
  </ContentSlot>
59
- </>,
57
+ </>
60
58
  );
61
59
 
62
- expect(printTree(tree)).toBe(`It's empty!`);
60
+ expect(tree).toRenderTo("It's empty!");
63
61
  showContent.value = true;
64
- expect(printTree(tree)).toBe(`Has content!Content!`);
62
+ expect(tree).toRenderTo("Has content!Content!");
65
63
  });
@@ -1,5 +1,5 @@
1
1
  import { createNamedContext, useContext } from "../context.js";
2
- import { PrintTreeOptions } from "../render.js";
2
+ import { PrintTreeOptions } from "../output-types.js";
3
3
 
4
4
  export interface CommonFormatOptions extends PrintTreeOptions {}
5
5
 
package/src/context.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { shallowRef } from "@vue/reactivity";
2
2
  import { effect, getContext } from "./reactivity.js";
3
3
  import type { Children, ComponentDefinition } from "./runtime/component.js";
4
- import { stc, type StcSignature } from "./stc.js";
4
+ import type { StcSignature } from "./stc.js";
5
5
 
6
6
  export interface ComponentContext<T> {
7
7
  id: symbol;
@@ -11,6 +11,23 @@ export interface ComponentContext<T> {
11
11
  name?: string;
12
12
  }
13
13
 
14
+ let _stcImpl:
15
+ | (<T extends {}>(Component: ComponentDefinition<T>) => StcSignature<T>)
16
+ | null = null;
17
+
18
+ /**
19
+ * Registers the {@link stc} factory used to lazily build `ProviderStc`.
20
+ * Called once by `stc.ts` at module initialization to break the
21
+ * `context.ts ↔ stc.ts` import cycle.
22
+ *
23
+ * @internal
24
+ */
25
+ export function _registerStcImpl(
26
+ impl: <T extends {}>(Component: ComponentDefinition<T>) => StcSignature<T>,
27
+ ): void {
28
+ _stcImpl = impl;
29
+ }
30
+
14
31
  export interface ContextProviderProps<T = unknown> {
15
32
  value?: T;
16
33
  children?: Children;
@@ -57,13 +74,29 @@ export function createContext<T = unknown>(
57
74
 
58
75
  return rendered.value;
59
76
  }
60
- const ctx = {
77
+ const ctx: ComponentContext<T> = {
61
78
  id,
62
79
  default: defaultValue,
63
80
  name,
64
81
  Provider,
65
- ProviderStc: stc(Provider),
66
- };
82
+ } as ComponentContext<T>;
83
+ Object.defineProperty(ctx, "ProviderStc", {
84
+ configurable: true,
85
+ enumerable: true,
86
+ get() {
87
+ if (_stcImpl === null) {
88
+ throw new Error("ProviderStc accessed before stc module initialized.");
89
+ }
90
+ const value = _stcImpl(Provider);
91
+ Object.defineProperty(this, "ProviderStc", {
92
+ value,
93
+ enumerable: true,
94
+ writable: true,
95
+ configurable: true,
96
+ });
97
+ return value;
98
+ },
99
+ });
67
100
  (Provider as any).contextName = name;
68
101
  contextsByKey.set(id, ctx);
69
102
  return ctx;
@@ -10,7 +10,7 @@ import {
10
10
  resetDevtoolsServerForTests,
11
11
  } from "../devtools/devtools-server.js";
12
12
  import { DiagnosticsCollector } from "../diagnostics.js";
13
- import { renderAsync } from "../render.js";
13
+ import { renderAsync } from "../render-output.js";
14
14
 
15
15
  let socket: WebSocket | undefined;
16
16
 
@@ -11,7 +11,7 @@ import {
11
11
  resetDevtoolsServerForTests,
12
12
  } from "../devtools/devtools-server.js";
13
13
  import { effect, memo, ref } from "../reactivity.js";
14
- import { renderAsync } from "../render.js";
14
+ import { renderAsync } from "../render-output.js";
15
15
  import { flushJobsAsync } from "../scheduler.js";
16
16
  import { debug } from "./index.js";
17
17
 
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Throttled file-content streaming for devtools.
3
+ *
4
+ * As the render tree mutates, the debug system finds the enclosing
5
+ * `alloy:source-file` wrapper for the changed node and marks it dirty.
6
+ * When a devtools client is connected, dirty files are re-printed at
7
+ * most once per second so users can watch file content build up during
8
+ * rendering. When devtools is not connected, dirty files are flushed
9
+ * once at the end of render via {@link flushAllDirtyFiles}.
10
+ */
11
+
12
+ import { isDevtoolsConnected } from "../devtools/devtools-server.js";
13
+ import type { PrintTreeOptions } from "../output-types.js";
14
+ import { getContextForNode } from "../render/node-context.js";
15
+ import { ElementNode, type AlloyNode } from "../render/node.js";
16
+ import { printNodeToString } from "../render/printer.js";
17
+ import { updated as filesUpdated } from "./files.js";
18
+ import { isDebugEnabled } from "./trace.js";
19
+
20
+ const DEVTOOLS_FLUSH_INTERVAL_MS = 1000;
21
+
22
+ const dirtyFiles = new Set<ElementNode>();
23
+ const lastFlushTimeByFile = new Map<string, number>();
24
+
25
+ /** Find the nearest alloy:source-file ancestor (inclusive). */
26
+ function findSourceFileWrapper(node: AlloyNode): ElementNode | undefined {
27
+ let cur: AlloyNode | null = node;
28
+ while (cur !== null) {
29
+ if (cur instanceof ElementNode && cur.localName === "alloy:source-file") {
30
+ return cur;
31
+ }
32
+ cur = cur.parentNode;
33
+ }
34
+ return undefined;
35
+ }
36
+
37
+ interface SourceFileMeta {
38
+ path: string;
39
+ filetype: string;
40
+ }
41
+
42
+ function getSourceFileMeta(wrapper: ElementNode): SourceFileMeta | undefined {
43
+ const ctx = getContextForNode(wrapper);
44
+ const meta = ctx?.meta as
45
+ | {
46
+ sourceFile?: SourceFileMeta;
47
+ sourceFileReady?: boolean;
48
+ printOptions?: PrintTreeOptions;
49
+ }
50
+ | undefined;
51
+ if (meta?.sourceFileReady === false) return undefined;
52
+ return meta?.sourceFile;
53
+ }
54
+
55
+ function getPrintOptions(wrapper: ElementNode): PrintTreeOptions | undefined {
56
+ const ctx = getContextForNode(wrapper);
57
+ const meta = ctx?.meta as { printOptions?: PrintTreeOptions } | undefined;
58
+ return meta?.printOptions;
59
+ }
60
+
61
+ function flushFile(wrapper: ElementNode): void {
62
+ const sf = getSourceFileMeta(wrapper);
63
+ if (!sf) return;
64
+ const printOpts = getPrintOptions(wrapper);
65
+ let contents: string;
66
+ try {
67
+ contents = printNodeToString(wrapper, {
68
+ printWidth: printOpts?.printWidth ?? 80,
69
+ tabWidth: printOpts?.tabWidth ?? 2,
70
+ useTabs: printOpts?.useTabs ?? false,
71
+ }).formatted;
72
+ } catch {
73
+ // Mid-render the tree may be in an inconsistent state — skip this
74
+ // flush attempt and pick it up on the next mutation.
75
+ return;
76
+ }
77
+ if (printOpts?.insertFinalNewLine !== false && !contents.endsWith("\n")) {
78
+ contents += "\n";
79
+ }
80
+ filesUpdated({ path: sf.path, filetype: sf.filetype, contents });
81
+ lastFlushTimeByFile.set(sf.path, Date.now());
82
+ dirtyFiles.delete(wrapper);
83
+ }
84
+
85
+ /**
86
+ * Mark the source file containing `node` as dirty. When devtools is
87
+ * connected and at least 1s has elapsed since this file was last flushed,
88
+ * print and broadcast its content immediately.
89
+ */
90
+ export function markFileDirtyForNode(node: AlloyNode): void {
91
+ if (!isDebugEnabled()) return;
92
+ const wrapper = findSourceFileWrapper(node);
93
+ if (!wrapper) return;
94
+ dirtyFiles.add(wrapper);
95
+ if (!isDevtoolsConnected()) return;
96
+ const sf = getSourceFileMeta(wrapper);
97
+ if (!sf) return;
98
+ const last = lastFlushTimeByFile.get(sf.path) ?? 0;
99
+ if (Date.now() - last < DEVTOOLS_FLUSH_INTERVAL_MS) return;
100
+ flushFile(wrapper);
101
+ }
102
+
103
+ /** Flush every dirty file. Called at end of render. */
104
+ export function flushAllDirtyFiles(): void {
105
+ if (dirtyFiles.size === 0) return;
106
+ for (const wrapper of [...dirtyFiles]) {
107
+ flushFile(wrapper);
108
+ }
109
+ }
110
+
111
+ /** Reset all streaming state. Called when a new render begins. */
112
+ export function reset(): void {
113
+ dirtyFiles.clear();
114
+ lastFlushTimeByFile.clear();
115
+ }
@@ -11,7 +11,7 @@ import {
11
11
  enableDevtools,
12
12
  resetDevtoolsServerForTests,
13
13
  } from "../devtools/devtools-server.js";
14
- import { renderAsync } from "../render.js";
14
+ import { renderAsync } from "../render-output.js";
15
15
 
16
16
  let socket: WebSocket | undefined;
17
17
 
@@ -61,16 +61,20 @@ it("emits file and directory add/update/remove messages", async () => {
61
61
  type: "directory:added",
62
62
  path: "src",
63
63
  });
64
- expect(initialFiles[2]).toMatchObject({
65
- type: "file:added",
66
- path: "src/index.ts",
67
- filetype: "ts",
68
- });
69
- expect(initialFiles[3]).toMatchObject({
70
- type: "file:updated",
71
- path: "src/index.ts",
72
- content: expect.any(String),
73
- });
64
+ expect(initialFiles).toEqual(
65
+ expect.arrayContaining([
66
+ expect.objectContaining({
67
+ type: "file:added",
68
+ path: "src/index.ts",
69
+ filetype: "ts",
70
+ }),
71
+ expect.objectContaining({
72
+ type: "file:updated",
73
+ path: "src/index.ts",
74
+ content: expect.any(String),
75
+ }),
76
+ ]),
77
+ );
74
78
 
75
79
  collector.stop();
76
80
  });
@@ -27,16 +27,14 @@ import {
27
27
  updated,
28
28
  } from "./files.js";
29
29
  import {
30
- appendCustomContext,
31
- appendFragmentChild,
32
- appendPrintHook,
33
- appendTextNode,
34
30
  beginComponent,
35
31
  complete,
36
32
  error,
37
33
  flushJobsComplete,
38
34
  initialize,
39
- prepareMemoNode,
35
+ isRerenderEnabled,
36
+ nodeAttached,
37
+ nodeDetached,
40
38
  } from "./render.js";
41
39
  import {
42
40
  registerScope,
@@ -55,7 +53,11 @@ export type {
55
53
  EffectEdgeDebugInfo,
56
54
  RefDebugInfo,
57
55
  } from "./effects.js";
58
- export { getRenderNodeId, type RenderTreeNodeInfo } from "./render.js";
56
+ export {
57
+ getRenderNodeId,
58
+ type RenderNodeActions,
59
+ type RenderTreeNodeInfo,
60
+ } from "./render.js";
59
61
  export type {
60
62
  BeginComponentOptions,
61
63
  ComponentDebugSession,
@@ -94,12 +96,10 @@ export const debug = {
94
96
  },
95
97
  render: {
96
98
  initialize,
97
- appendTextNode,
98
- appendCustomContext,
99
- appendPrintHook,
100
- appendFragmentChild,
99
+ nodeAttached,
100
+ nodeDetached,
101
101
  beginComponent,
102
- prepareMemoNode,
102
+ isRerenderEnabled,
103
103
  error,
104
104
  complete,
105
105
  flushJobsComplete,
@@ -22,7 +22,7 @@ import {
22
22
  resetDevtoolsServerForTests,
23
23
  } from "../devtools/devtools-server.js";
24
24
  import { effect, ref } from "../reactivity.js";
25
- import { renderAsync } from "../render.js";
25
+ import { renderAsync } from "../render-output.js";
26
26
  import { flushJobsAsync } from "../scheduler.js";
27
27
  import { debug } from "./index.js";
28
28
 
@@ -56,7 +56,10 @@ afterEach(async () => {
56
56
  describe("subscriptions", () => {
57
57
  it("only receives messages for subscribed channels", async () => {
58
58
  // Subscribe to render only — should NOT see effects, refs, etc.
59
- const collector = await createMessageCollector(socket!, ["render"]);
59
+ const collector = await createMessageCollector(socket!, [
60
+ "render",
61
+ "components",
62
+ ]);
60
63
  await renderAsync(<Output>hello</Output>);
61
64
  const messages = await collector.waitForRender();
62
65
  collector.stop();
@@ -107,7 +110,10 @@ describe("subscriptions", () => {
107
110
 
108
111
  describe("render:node_added", () => {
109
112
  it("root node has null parent_id and kind 'root'", async () => {
110
- const collector = await createMessageCollector(socket!, ["render"]);
113
+ const collector = await createMessageCollector(socket!, [
114
+ "render",
115
+ "components",
116
+ ]);
111
117
  await renderAsync(<Output />);
112
118
  const messages = await collector.waitForRender();
113
119
  collector.stop();
@@ -124,20 +130,22 @@ describe("render:node_added", () => {
124
130
  });
125
131
  });
126
132
 
127
- it("component node has numeric id, parent_id, and name", async () => {
128
- const collector = await createMessageCollector(socket!, ["render"]);
133
+ it("component instance has numeric id, parent_id, and name", async () => {
134
+ const collector = await createMessageCollector(socket!, [
135
+ "render",
136
+ "components",
137
+ ]);
129
138
  await renderAsync(<Output />);
130
139
  const messages = await collector.waitForRender();
131
140
  collector.stop();
132
141
 
133
142
  const output = messages.find(
134
- (m) => m.type === "render:node_added" && m.name === "Output",
143
+ (m) => m.type === "component:added" && m.name === "Output",
135
144
  );
136
145
  expect(output).toMatchObject({
137
- type: "render:node_added",
146
+ type: "component:added",
138
147
  id: expect.any(Number),
139
- parent_id: expect.any(Number),
140
- kind: "component",
148
+ parent_id: null,
141
149
  name: "Output",
142
150
  });
143
151
  });
@@ -156,23 +164,26 @@ describe("render:node_added", () => {
156
164
  expect(text!.parent_id).toEqual(expect.any(Number));
157
165
  });
158
166
 
159
- it("non-text node has null value (not undefined)", async () => {
167
+ it("non-text render node has null value (not undefined)", async () => {
160
168
  const collector = await createMessageCollector(socket!, ["render"]);
161
169
  await renderAsync(<Output>hello</Output>);
162
170
  const messages = await collector.waitForRender();
163
171
  collector.stop();
164
172
 
165
- const component = messages.find(
166
- (m) => m.type === "render:node_added" && m.kind === "component",
173
+ const nonText = messages.find(
174
+ (m) => m.type === "render:node_added" && m.kind === "directory",
167
175
  );
168
- expect(component!.value).toBeNull();
176
+ expect(nonText!.value).toBeNull();
169
177
  });
170
178
  });
171
179
 
172
180
  describe("render:node_removed", () => {
173
181
  it("is emitted when a reactive component removes children", async () => {
174
182
  const show = ref(true);
175
- const collector = await createMessageCollector(socket!, ["render"]);
183
+ const collector = await createMessageCollector(socket!, [
184
+ "render",
185
+ "components",
186
+ ]);
176
187
 
177
188
  function Conditional() {
178
189
  return () => (show.value ? "visible" : "");
@@ -691,7 +702,10 @@ describe("debugger:info", () => {
691
702
 
692
703
  describe("null vs undefined contract", () => {
693
704
  it("nullable fields arrive as null (not undefined or missing)", async () => {
694
- const collector = await createMessageCollector(socket!, ["render"]);
705
+ const collector = await createMessageCollector(socket!, [
706
+ "render",
707
+ "components",
708
+ ]);
695
709
  await renderAsync(<Output>hello</Output>);
696
710
  const messages = await collector.waitForRender();
697
711
  collector.stop();
@@ -705,14 +719,13 @@ describe("null vs undefined contract", () => {
705
719
  expect(root!.parent_id).toBeNull();
706
720
  expect("parent_id" in root!).toBe(true);
707
721
 
708
- // Component node: value should be null, not undefined
722
+ // Component facts are not render nodes.
709
723
  const component = messages.find(
710
724
  (m: DevtoolsMessage) =>
711
- m.type === "render:node_added" && m.kind === "component",
725
+ m.type === "component:added" && m.name === "Output",
712
726
  );
713
727
  expect(component).toBeDefined();
714
- expect(component!.value).toBeNull();
715
- expect("value" in component!).toBe(true);
728
+ expect(component!.parent_id).toBeNull();
716
729
 
717
730
  // source_file is nullable
718
731
  expect("source_file" in root!).toBe(true);
@@ -13,7 +13,7 @@ import {
13
13
  resetDevtoolsServerForTests,
14
14
  } from "../devtools/devtools-server.js";
15
15
  import { ref } from "../reactivity.js";
16
- import { renderAsync } from "../render.js";
16
+ import { renderAsync } from "../render-output.js";
17
17
  import { flushJobsAsync } from "../scheduler.js";
18
18
 
19
19
  /**
@@ -242,28 +242,19 @@ describe("render tree node orphans", () => {
242
242
 
243
243
  expect(orphans).toEqual([]);
244
244
 
245
- // No duplicate text nodes under the same parent
246
- const textByParent = new Map<number, string[]>();
247
- for (const [_id, node] of active) {
248
- if (node.kind === "text" && node.value && node.parentId !== null) {
249
- const list = textByParent.get(node.parentId) ?? [];
250
- list.push(node.value);
251
- textByParent.set(node.parentId, list);
252
- }
253
- }
254
- for (const [parentId, values] of textByParent) {
255
- const dupes = values.filter((v, i) => values.indexOf(v) !== i);
256
- expect(dupes, `Duplicate text nodes under parent ${parentId}`).toEqual(
257
- [],
258
- );
259
- }
245
+ const textValues = [...active.values()]
246
+ .filter((node) => node.kind === "text")
247
+ .map((node) => node.value);
248
+ expect(textValues).toEqual(expect.arrayContaining(["a", "y", "z"]));
249
+ expect(textValues).not.toEqual(expect.arrayContaining(["b", "c", "x"]));
260
250
 
261
251
  collector.stop();
262
252
  });
263
253
 
264
254
  it("no orphans when For with separators re-renders and keeps some items", async () => {
265
255
  // mapJoin creates separator/joiner slots between items. These separators
266
- // contain printHook subtrees that are part of the cached element tree.
256
+ // contain nested formatter-control subtrees that are part of the cached
257
+ // element tree.
267
258
  // When items change, the cached subtree is re-added but separator fragments
268
259
  // from previous renders must be properly cascade-deleted.
269
260
  //
@@ -285,8 +276,8 @@ describe("render tree node orphans", () => {
285
276
  const items = ref(["a", "b", "c", "d"]);
286
277
  const collector = await createMessageCollector(socket!);
287
278
 
288
- // Nested blocks simulate the deeply nested printHook trees
289
- // found in real emitters (e.g., flight-instructor)
279
+ // Nested blocks simulate the deeply nested formatter-control trees found in
280
+ // real emitters (e.g., flight-instructor).
290
281
  function Item(props: { value: string }) {
291
282
  return (
292
283
  <Block>