vsn 0.1.148 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (587) hide show
  1. package/README.md +7 -6
  2. package/dist/index.cjs +5011 -0
  3. package/dist/index.cjs.map +1 -0
  4. package/dist/index.d.cts +630 -0
  5. package/dist/index.d.ts +630 -0
  6. package/dist/index.js +4942 -0
  7. package/dist/index.js.map +1 -0
  8. package/dist/index.min.js +9 -0
  9. package/dist/index.min.js.map +1 -0
  10. package/package.json +30 -48
  11. package/.gitattributes +0 -2
  12. package/.travis.yml +0 -28
  13. package/demo/demo.html +0 -237
  14. package/demo/examples/cascading-function-sheets.html +0 -39
  15. package/demo/examples/component-slots.html +0 -29
  16. package/demo/examples/events.html +0 -21
  17. package/demo/examples/item-filtering.html +0 -45
  18. package/demo/examples/loop.html +0 -21
  19. package/demo/examples/persist.html +0 -17
  20. package/demo/examples/replace-html.html +0 -19
  21. package/demo/markup-default.html +0 -2
  22. package/demo/markup.html +0 -2
  23. package/demo/memory-leak-test.html +0 -82
  24. package/demo/named-stack.html +0 -34
  25. package/demo/resources/xhr-animations.html +0 -24
  26. package/demo/resources/xhr-cfs.html +0 -1
  27. package/demo/resources/xhr-html.html +0 -1
  28. package/demo/resources/xhr-lazy.html +0 -60
  29. package/demo/resources/xhr-memory-leak-test.html +0 -14
  30. package/demo/resources/xhr-persist.html +0 -40
  31. package/demo/resources/xhr-test-component.html +0 -4
  32. package/demo/service.html +0 -22
  33. package/demo/silly-animations.html +0 -27
  34. package/demo/vsn.js +0 -3
  35. package/demo/xhr-response.html +0 -1
  36. package/demo/xhr-test.html +0 -32
  37. package/dist/AST/ArithmeticNode.d.ts +0 -15
  38. package/dist/AST/ArithmeticNode.js +0 -114
  39. package/dist/AST/ArithmeticNode.js.map +0 -1
  40. package/dist/AST/ArrayNode.d.ts +0 -14
  41. package/dist/AST/ArrayNode.js +0 -166
  42. package/dist/AST/ArrayNode.js.map +0 -1
  43. package/dist/AST/AsNode.d.ts +0 -13
  44. package/dist/AST/AsNode.js +0 -92
  45. package/dist/AST/AsNode.js.map +0 -1
  46. package/dist/AST/AssignmentNode.d.ts +0 -24
  47. package/dist/AST/AssignmentNode.js +0 -392
  48. package/dist/AST/AssignmentNode.js.map +0 -1
  49. package/dist/AST/BlockNode.d.ts +0 -11
  50. package/dist/AST/BlockNode.js +0 -114
  51. package/dist/AST/BlockNode.js.map +0 -1
  52. package/dist/AST/BooleanLiteralNode.d.ts +0 -5
  53. package/dist/AST/BooleanLiteralNode.js +0 -31
  54. package/dist/AST/BooleanLiteralNode.js.map +0 -1
  55. package/dist/AST/ClassNode.d.ts +0 -47
  56. package/dist/AST/ClassNode.js +0 -593
  57. package/dist/AST/ClassNode.js.map +0 -1
  58. package/dist/AST/ComparisonNode.d.ts +0 -15
  59. package/dist/AST/ComparisonNode.js +0 -120
  60. package/dist/AST/ComparisonNode.js.map +0 -1
  61. package/dist/AST/ConditionalNode.d.ts +0 -13
  62. package/dist/AST/ConditionalNode.js +0 -95
  63. package/dist/AST/ConditionalNode.js.map +0 -1
  64. package/dist/AST/DispatchEventNode.d.ts +0 -17
  65. package/dist/AST/DispatchEventNode.js +0 -152
  66. package/dist/AST/DispatchEventNode.js.map +0 -1
  67. package/dist/AST/ElementAttributeNode.d.ts +0 -20
  68. package/dist/AST/ElementAttributeNode.js +0 -242
  69. package/dist/AST/ElementAttributeNode.js.map +0 -1
  70. package/dist/AST/ElementQueryNode.d.ts +0 -17
  71. package/dist/AST/ElementQueryNode.js +0 -148
  72. package/dist/AST/ElementQueryNode.js.map +0 -1
  73. package/dist/AST/ElementStyleNode.d.ts +0 -20
  74. package/dist/AST/ElementStyleNode.js +0 -205
  75. package/dist/AST/ElementStyleNode.js.map +0 -1
  76. package/dist/AST/ForStatementNode.d.ts +0 -17
  77. package/dist/AST/ForStatementNode.js +0 -121
  78. package/dist/AST/ForStatementNode.js.map +0 -1
  79. package/dist/AST/FunctionArgumentNode.d.ts +0 -11
  80. package/dist/AST/FunctionArgumentNode.js +0 -142
  81. package/dist/AST/FunctionArgumentNode.js.map +0 -1
  82. package/dist/AST/FunctionCallNode.d.ts +0 -14
  83. package/dist/AST/FunctionCallNode.js +0 -241
  84. package/dist/AST/FunctionCallNode.js.map +0 -1
  85. package/dist/AST/FunctionNode.d.ts +0 -20
  86. package/dist/AST/FunctionNode.js +0 -220
  87. package/dist/AST/FunctionNode.js.map +0 -1
  88. package/dist/AST/IfStatementNode.d.ts +0 -14
  89. package/dist/AST/IfStatementNode.js +0 -168
  90. package/dist/AST/IfStatementNode.js.map +0 -1
  91. package/dist/AST/InNode.d.ts +0 -15
  92. package/dist/AST/InNode.js +0 -107
  93. package/dist/AST/InNode.js.map +0 -1
  94. package/dist/AST/IndexNode.d.ts +0 -16
  95. package/dist/AST/IndexNode.js +0 -152
  96. package/dist/AST/IndexNode.js.map +0 -1
  97. package/dist/AST/LiteralNode.d.ts +0 -10
  98. package/dist/AST/LiteralNode.js +0 -74
  99. package/dist/AST/LiteralNode.js.map +0 -1
  100. package/dist/AST/LoopNode.d.ts +0 -12
  101. package/dist/AST/LoopNode.js +0 -121
  102. package/dist/AST/LoopNode.js.map +0 -1
  103. package/dist/AST/ModifierNode.d.ts +0 -14
  104. package/dist/AST/ModifierNode.js +0 -90
  105. package/dist/AST/ModifierNode.js.map +0 -1
  106. package/dist/AST/NamedStackNode.d.ts +0 -28
  107. package/dist/AST/NamedStackNode.js +0 -142
  108. package/dist/AST/NamedStackNode.js.map +0 -1
  109. package/dist/AST/Node.d.ts +0 -28
  110. package/dist/AST/Node.js +0 -263
  111. package/dist/AST/Node.js.map +0 -1
  112. package/dist/AST/NotNode.d.ts +0 -12
  113. package/dist/AST/NotNode.js +0 -103
  114. package/dist/AST/NotNode.js.map +0 -1
  115. package/dist/AST/NumberLiteralNode.d.ts +0 -5
  116. package/dist/AST/NumberLiteralNode.js +0 -36
  117. package/dist/AST/NumberLiteralNode.js.map +0 -1
  118. package/dist/AST/ObjectNode.d.ts +0 -14
  119. package/dist/AST/ObjectNode.js +0 -147
  120. package/dist/AST/ObjectNode.js.map +0 -1
  121. package/dist/AST/OnNode.d.ts +0 -9
  122. package/dist/AST/OnNode.js +0 -129
  123. package/dist/AST/OnNode.js.map +0 -1
  124. package/dist/AST/RootScopeMemberNode.d.ts +0 -12
  125. package/dist/AST/RootScopeMemberNode.js +0 -90
  126. package/dist/AST/RootScopeMemberNode.js.map +0 -1
  127. package/dist/AST/ScopeMemberNode.d.ts +0 -13
  128. package/dist/AST/ScopeMemberNode.js +0 -165
  129. package/dist/AST/ScopeMemberNode.js.map +0 -1
  130. package/dist/AST/ScopeNodeAbstract.d.ts +0 -8
  131. package/dist/AST/ScopeNodeAbstract.js +0 -105
  132. package/dist/AST/ScopeNodeAbstract.js.map +0 -1
  133. package/dist/AST/StringFormatNode.d.ts +0 -18
  134. package/dist/AST/StringFormatNode.js +0 -151
  135. package/dist/AST/StringFormatNode.js.map +0 -1
  136. package/dist/AST/UnitLiteralNode.d.ts +0 -15
  137. package/dist/AST/UnitLiteralNode.js +0 -72
  138. package/dist/AST/UnitLiteralNode.js.map +0 -1
  139. package/dist/AST/WASM/Context.d.ts +0 -4
  140. package/dist/AST/WASM/Context.js +0 -18
  141. package/dist/AST/WASM/Context.js.map +0 -1
  142. package/dist/AST/WASM/Function.d.ts +0 -22
  143. package/dist/AST/WASM/Function.js +0 -126
  144. package/dist/AST/WASM/Function.js.map +0 -1
  145. package/dist/AST/WASM/Memory.d.ts +0 -12
  146. package/dist/AST/WASM/Memory.js +0 -22
  147. package/dist/AST/WASM/Memory.js.map +0 -1
  148. package/dist/AST/WASM/Section.d.ts +0 -5
  149. package/dist/AST/WASM/Section.js +0 -11
  150. package/dist/AST/WASM/Section.js.map +0 -1
  151. package/dist/AST/WASM.d.ts +0 -58
  152. package/dist/AST/WASM.js +0 -293
  153. package/dist/AST/WASM.js.map +0 -1
  154. package/dist/AST/WithNode.d.ts +0 -15
  155. package/dist/AST/WithNode.js +0 -197
  156. package/dist/AST/WithNode.js.map +0 -1
  157. package/dist/AST/XHRNode.d.ts +0 -15
  158. package/dist/AST/XHRNode.js +0 -151
  159. package/dist/AST/XHRNode.js.map +0 -1
  160. package/dist/AST.d.ts +0 -160
  161. package/dist/AST.js +0 -1156
  162. package/dist/AST.js.map +0 -1
  163. package/dist/Attribute.d.ts +0 -46
  164. package/dist/Attribute.js +0 -262
  165. package/dist/Attribute.js.map +0 -1
  166. package/dist/Bencmark.d.ts +0 -14
  167. package/dist/Bencmark.js +0 -236
  168. package/dist/Bencmark.js.map +0 -1
  169. package/dist/Component.d.ts +0 -7
  170. package/dist/Component.js +0 -179
  171. package/dist/Component.js.map +0 -1
  172. package/dist/Configuration.d.ts +0 -12
  173. package/dist/Configuration.js +0 -64
  174. package/dist/Configuration.js.map +0 -1
  175. package/dist/Controller.d.ts +0 -13
  176. package/dist/Controller.js +0 -60
  177. package/dist/Controller.js.map +0 -1
  178. package/dist/DOM/AbstractDOM.d.ts +0 -56
  179. package/dist/DOM/AbstractDOM.js +0 -1038
  180. package/dist/DOM/AbstractDOM.js.map +0 -1
  181. package/dist/DOM/DOMObject.d.ts +0 -33
  182. package/dist/DOM/DOMObject.js +0 -152
  183. package/dist/DOM/DOMObject.js.map +0 -1
  184. package/dist/DOM/ShadowDOM.d.ts +0 -5
  185. package/dist/DOM/ShadowDOM.js +0 -32
  186. package/dist/DOM/ShadowDOM.js.map +0 -1
  187. package/dist/DOM/WrappedDocument.d.ts +0 -5
  188. package/dist/DOM/WrappedDocument.js +0 -34
  189. package/dist/DOM/WrappedDocument.js.map +0 -1
  190. package/dist/DOM/WrappedWindow.d.ts +0 -6
  191. package/dist/DOM/WrappedWindow.js +0 -45
  192. package/dist/DOM/WrappedWindow.js.map +0 -1
  193. package/dist/DOM.d.ts +0 -5
  194. package/dist/DOM.js +0 -37
  195. package/dist/DOM.js.map +0 -1
  196. package/dist/EventDispatcher.d.ts +0 -36
  197. package/dist/EventDispatcher.js +0 -393
  198. package/dist/EventDispatcher.js.map +0 -1
  199. package/dist/Formats.d.ts +0 -5
  200. package/dist/Formats.js +0 -47
  201. package/dist/Formats.js.map +0 -1
  202. package/dist/MessageList.d.ts +0 -15
  203. package/dist/MessageList.js +0 -127
  204. package/dist/MessageList.js.map +0 -1
  205. package/dist/Model.d.ts +0 -12
  206. package/dist/Model.js +0 -92
  207. package/dist/Model.js.map +0 -1
  208. package/dist/Modifiers.d.ts +0 -17
  209. package/dist/Modifiers.js +0 -100
  210. package/dist/Modifiers.js.map +0 -1
  211. package/dist/Query.d.ts +0 -4
  212. package/dist/Query.js +0 -66
  213. package/dist/Query.js.map +0 -1
  214. package/dist/Registry.d.ts +0 -41
  215. package/dist/Registry.js +0 -165
  216. package/dist/Registry.js.map +0 -1
  217. package/dist/Scope/DynamicScopeData.d.ts +0 -6
  218. package/dist/Scope/DynamicScopeData.js +0 -83
  219. package/dist/Scope/DynamicScopeData.js.map +0 -1
  220. package/dist/Scope/ObjectAccessor.d.ts +0 -7
  221. package/dist/Scope/ObjectAccessor.js +0 -40
  222. package/dist/Scope/ObjectAccessor.js.map +0 -1
  223. package/dist/Scope/QueryReference.d.ts +0 -10
  224. package/dist/Scope/QueryReference.js +0 -103
  225. package/dist/Scope/QueryReference.js.map +0 -1
  226. package/dist/Scope/ScopeAbstract.d.ts +0 -9
  227. package/dist/Scope/ScopeAbstract.js +0 -28
  228. package/dist/Scope/ScopeAbstract.js.map +0 -1
  229. package/dist/Scope/ScopeData.d.ts +0 -4
  230. package/dist/Scope/ScopeData.js +0 -60
  231. package/dist/Scope/ScopeData.js.map +0 -1
  232. package/dist/Scope/ScopeDataAbstract.d.ts +0 -30
  233. package/dist/Scope/ScopeDataAbstract.js +0 -303
  234. package/dist/Scope/ScopeDataAbstract.js.map +0 -1
  235. package/dist/Scope/ScopeObject.d.ts +0 -3
  236. package/dist/Scope/ScopeObject.js +0 -28
  237. package/dist/Scope/ScopeObject.js.map +0 -1
  238. package/dist/Scope/ScopeReference.d.ts +0 -10
  239. package/dist/Scope/ScopeReference.js +0 -73
  240. package/dist/Scope/ScopeReference.js.map +0 -1
  241. package/dist/Scope/ScopedVariableType.d.ts +0 -6
  242. package/dist/Scope/ScopedVariableType.js +0 -14
  243. package/dist/Scope/ScopedVariableType.js.map +0 -1
  244. package/dist/Scope/WrappedArray.d.ts +0 -21
  245. package/dist/Scope/WrappedArray.js +0 -252
  246. package/dist/Scope/WrappedArray.js.map +0 -1
  247. package/dist/Scope/properties/ArrayProperty.d.ts +0 -12
  248. package/dist/Scope/properties/ArrayProperty.js +0 -88
  249. package/dist/Scope/properties/ArrayProperty.js.map +0 -1
  250. package/dist/Scope/properties/FloatProperty.d.ts +0 -4
  251. package/dist/Scope/properties/FloatProperty.js +0 -30
  252. package/dist/Scope/properties/FloatProperty.js.map +0 -1
  253. package/dist/Scope/properties/IntegerProperty.d.ts +0 -4
  254. package/dist/Scope/properties/IntegerProperty.js +0 -30
  255. package/dist/Scope/properties/IntegerProperty.js.map +0 -1
  256. package/dist/Scope/properties/Property.d.ts +0 -30
  257. package/dist/Scope/properties/Property.js +0 -205
  258. package/dist/Scope/properties/Property.js.map +0 -1
  259. package/dist/Scope/properties/_imports.d.ts +0 -4
  260. package/dist/Scope/properties/_imports.js +0 -13
  261. package/dist/Scope/properties/_imports.js.map +0 -1
  262. package/dist/Scope.d.ts +0 -39
  263. package/dist/Scope.js +0 -434
  264. package/dist/Scope.js.map +0 -1
  265. package/dist/Service.d.ts +0 -9
  266. package/dist/Service.js +0 -49
  267. package/dist/Service.js.map +0 -1
  268. package/dist/Tag/ShadowRootTag.d.ts +0 -3
  269. package/dist/Tag/ShadowRootTag.js +0 -28
  270. package/dist/Tag/ShadowRootTag.js.map +0 -1
  271. package/dist/Tag/SlotTag.d.ts +0 -3
  272. package/dist/Tag/SlotTag.js +0 -28
  273. package/dist/Tag/SlotTag.js.map +0 -1
  274. package/dist/Tag/SlottedTag.d.ts +0 -7
  275. package/dist/Tag/SlottedTag.js +0 -78
  276. package/dist/Tag/SlottedTag.js.map +0 -1
  277. package/dist/Tag/TagList.d.ts +0 -13
  278. package/dist/Tag/TagList.js +0 -104
  279. package/dist/Tag/TagList.js.map +0 -1
  280. package/dist/Tag.d.ts +0 -117
  281. package/dist/Tag.js +0 -1471
  282. package/dist/Tag.js.map +0 -1
  283. package/dist/Types.d.ts +0 -8
  284. package/dist/Types.js +0 -54
  285. package/dist/Types.js.map +0 -1
  286. package/dist/Validators.d.ts +0 -7
  287. package/dist/Validators.js +0 -54
  288. package/dist/Validators.js.map +0 -1
  289. package/dist/attributes/AddClassIf.d.ts +0 -4
  290. package/dist/attributes/AddClassIf.js +0 -93
  291. package/dist/attributes/AddClassIf.js.map +0 -1
  292. package/dist/attributes/Bind.d.ts +0 -24
  293. package/dist/attributes/Bind.js +0 -273
  294. package/dist/attributes/Bind.js.map +0 -1
  295. package/dist/attributes/ComponentAttribute.d.ts +0 -5
  296. package/dist/attributes/ComponentAttribute.js +0 -110
  297. package/dist/attributes/ComponentAttribute.js.map +0 -1
  298. package/dist/attributes/ControllerAttribute.d.ts +0 -11
  299. package/dist/attributes/ControllerAttribute.js +0 -127
  300. package/dist/attributes/ControllerAttribute.js.map +0 -1
  301. package/dist/attributes/DisableIf.d.ts +0 -5
  302. package/dist/attributes/DisableIf.js +0 -94
  303. package/dist/attributes/DisableIf.js.map +0 -1
  304. package/dist/attributes/Exec.d.ts +0 -10
  305. package/dist/attributes/Exec.js +0 -133
  306. package/dist/attributes/Exec.js.map +0 -1
  307. package/dist/attributes/Format.d.ts +0 -5
  308. package/dist/attributes/Format.js +0 -99
  309. package/dist/attributes/Format.js.map +0 -1
  310. package/dist/attributes/If.d.ts +0 -11
  311. package/dist/attributes/If.js +0 -159
  312. package/dist/attributes/If.js.map +0 -1
  313. package/dist/attributes/JSONAttribute.d.ts +0 -5
  314. package/dist/attributes/JSONAttribute.js +0 -119
  315. package/dist/attributes/JSONAttribute.js.map +0 -1
  316. package/dist/attributes/KeyAbstract.d.ts +0 -7
  317. package/dist/attributes/KeyAbstract.js +0 -117
  318. package/dist/attributes/KeyAbstract.js.map +0 -1
  319. package/dist/attributes/KeyDown.d.ts +0 -4
  320. package/dist/attributes/KeyDown.js +0 -88
  321. package/dist/attributes/KeyDown.js.map +0 -1
  322. package/dist/attributes/KeyUp.d.ts +0 -4
  323. package/dist/attributes/KeyUp.js +0 -88
  324. package/dist/attributes/KeyUp.js.map +0 -1
  325. package/dist/attributes/LazyAttribute.d.ts +0 -8
  326. package/dist/attributes/LazyAttribute.js +0 -122
  327. package/dist/attributes/LazyAttribute.js.map +0 -1
  328. package/dist/attributes/List.d.ts +0 -18
  329. package/dist/attributes/List.js +0 -396
  330. package/dist/attributes/List.js.map +0 -1
  331. package/dist/attributes/ListItem.d.ts +0 -12
  332. package/dist/attributes/ListItem.js +0 -119
  333. package/dist/attributes/ListItem.js.map +0 -1
  334. package/dist/attributes/ListItemModel.d.ts +0 -4
  335. package/dist/attributes/ListItemModel.js +0 -39
  336. package/dist/attributes/ListItemModel.js.map +0 -1
  337. package/dist/attributes/ModelAttribute.d.ts +0 -5
  338. package/dist/attributes/ModelAttribute.js +0 -41
  339. package/dist/attributes/ModelAttribute.js.map +0 -1
  340. package/dist/attributes/Name.d.ts +0 -6
  341. package/dist/attributes/Name.js +0 -88
  342. package/dist/attributes/Name.js.map +0 -1
  343. package/dist/attributes/On.d.ts +0 -9
  344. package/dist/attributes/On.js +0 -135
  345. package/dist/attributes/On.js.map +0 -1
  346. package/dist/attributes/PersistAttribute.d.ts +0 -15
  347. package/dist/attributes/PersistAttribute.js +0 -215
  348. package/dist/attributes/PersistAttribute.js.map +0 -1
  349. package/dist/attributes/Referenced.d.ts +0 -3
  350. package/dist/attributes/Referenced.js +0 -38
  351. package/dist/attributes/Referenced.js.map +0 -1
  352. package/dist/attributes/RootAttribute.d.ts +0 -7
  353. package/dist/attributes/RootAttribute.js +0 -141
  354. package/dist/attributes/RootAttribute.js.map +0 -1
  355. package/dist/attributes/ScopeAttribute.d.ts +0 -9
  356. package/dist/attributes/ScopeAttribute.js +0 -152
  357. package/dist/attributes/ScopeAttribute.js.map +0 -1
  358. package/dist/attributes/ScopeChange.d.ts +0 -10
  359. package/dist/attributes/ScopeChange.js +0 -153
  360. package/dist/attributes/ScopeChange.js.map +0 -1
  361. package/dist/attributes/ScriptAttribute.d.ts +0 -4
  362. package/dist/attributes/ScriptAttribute.js +0 -45
  363. package/dist/attributes/ScriptAttribute.js.map +0 -1
  364. package/dist/attributes/ServiceAttribute.d.ts +0 -7
  365. package/dist/attributes/ServiceAttribute.js +0 -45
  366. package/dist/attributes/ServiceAttribute.js.map +0 -1
  367. package/dist/attributes/SetAttribute.d.ts +0 -11
  368. package/dist/attributes/SetAttribute.js +0 -146
  369. package/dist/attributes/SetAttribute.js.map +0 -1
  370. package/dist/attributes/StandardAttribute.d.ts +0 -15
  371. package/dist/attributes/StandardAttribute.js +0 -170
  372. package/dist/attributes/StandardAttribute.js.map +0 -1
  373. package/dist/attributes/StyleAttribute.d.ts +0 -14
  374. package/dist/attributes/StyleAttribute.js +0 -218
  375. package/dist/attributes/StyleAttribute.js.map +0 -1
  376. package/dist/attributes/StyleVarAttribute.d.ts +0 -11
  377. package/dist/attributes/StyleVarAttribute.js +0 -124
  378. package/dist/attributes/StyleVarAttribute.js.map +0 -1
  379. package/dist/attributes/TemplateAttribute.d.ts +0 -5
  380. package/dist/attributes/TemplateAttribute.js +0 -89
  381. package/dist/attributes/TemplateAttribute.js.map +0 -1
  382. package/dist/attributes/TypeAttribute.d.ts +0 -5
  383. package/dist/attributes/TypeAttribute.js +0 -104
  384. package/dist/attributes/TypeAttribute.js.map +0 -1
  385. package/dist/attributes/XHRAttribute.d.ts +0 -14
  386. package/dist/attributes/XHRAttribute.js +0 -242
  387. package/dist/attributes/XHRAttribute.js.map +0 -1
  388. package/dist/attributes/_imports.d.ts +0 -32
  389. package/dist/attributes/_imports.js +0 -68
  390. package/dist/attributes/_imports.js.map +0 -1
  391. package/dist/contrib/XHR.d.ts +0 -21
  392. package/dist/contrib/XHR.js +0 -78
  393. package/dist/contrib/XHR.js.map +0 -1
  394. package/dist/contrib/_imports.d.ts +0 -1
  395. package/dist/contrib/_imports.js +0 -6
  396. package/dist/contrib/_imports.js.map +0 -1
  397. package/dist/custom-elements.d.ts +0 -9
  398. package/dist/custom-elements.js +0 -44
  399. package/dist/custom-elements.js.map +0 -1
  400. package/dist/demo/ServiceDemo.d.ts +0 -5
  401. package/dist/demo/ServiceDemo.js +0 -87
  402. package/dist/demo/ServiceDemo.js.map +0 -1
  403. package/dist/demo.d.ts +0 -2
  404. package/dist/demo.js +0 -17
  405. package/dist/demo.js.map +0 -1
  406. package/dist/helpers/DOMHelper.d.ts +0 -3
  407. package/dist/helpers/DOMHelper.js +0 -81
  408. package/dist/helpers/DOMHelper.js.map +0 -1
  409. package/dist/helpers/ElementHelper.d.ts +0 -4
  410. package/dist/helpers/ElementHelper.js +0 -53
  411. package/dist/helpers/ElementHelper.js.map +0 -1
  412. package/dist/helpers/VisionHelper.d.ts +0 -13
  413. package/dist/helpers/VisionHelper.js +0 -148
  414. package/dist/helpers/VisionHelper.js.map +0 -1
  415. package/dist/helpers/decorators.d.ts +0 -5
  416. package/dist/helpers/decorators.js +0 -59
  417. package/dist/helpers/decorators.js.map +0 -1
  418. package/dist/version.d.ts +0 -1
  419. package/dist/version.js +0 -5
  420. package/dist/version.js.map +0 -1
  421. package/dist/vsn.d.ts +0 -36
  422. package/dist/vsn.js +0 -201
  423. package/dist/vsn.js.map +0 -1
  424. package/karma.conf.js +0 -34
  425. package/src/AST/ArithmeticNode.ts +0 -52
  426. package/src/AST/ArrayNode.ts +0 -39
  427. package/src/AST/AsNode.ts +0 -32
  428. package/src/AST/AssignmentNode.ts +0 -256
  429. package/src/AST/BlockNode.ts +0 -25
  430. package/src/AST/BooleanLiteralNode.ts +0 -10
  431. package/src/AST/ClassNode.ts +0 -267
  432. package/src/AST/ComparisonNode.ts +0 -57
  433. package/src/AST/ConditionalNode.ts +0 -36
  434. package/src/AST/DispatchEventNode.ts +0 -58
  435. package/src/AST/ElementAttributeNode.ts +0 -97
  436. package/src/AST/ElementQueryNode.ts +0 -48
  437. package/src/AST/ElementStyleNode.ts +0 -74
  438. package/src/AST/ForStatementNode.ts +0 -59
  439. package/src/AST/FunctionArgumentNode.ts +0 -27
  440. package/src/AST/FunctionCallNode.ts +0 -93
  441. package/src/AST/FunctionNode.ts +0 -82
  442. package/src/AST/IfStatementNode.ts +0 -67
  443. package/src/AST/InNode.ts +0 -46
  444. package/src/AST/IndexNode.ts +0 -64
  445. package/src/AST/LiteralNode.ts +0 -17
  446. package/src/AST/LoopNode.ts +0 -35
  447. package/src/AST/ModifierNode.ts +0 -32
  448. package/src/AST/NamedStackNode.ts +0 -83
  449. package/src/AST/Node.ts +0 -104
  450. package/src/AST/NotNode.ts +0 -41
  451. package/src/AST/NumberLiteralNode.ts +0 -14
  452. package/src/AST/ObjectNode.ts +0 -55
  453. package/src/AST/OnNode.ts +0 -23
  454. package/src/AST/RootScopeMemberNode.ts +0 -27
  455. package/src/AST/ScopeMemberNode.ts +0 -63
  456. package/src/AST/ScopeNodeAbstract.ts +0 -21
  457. package/src/AST/StringFormatNode.ts +0 -43
  458. package/src/AST/UnitLiteralNode.ts +0 -51
  459. package/src/AST/WASM/Context.ts +0 -12
  460. package/src/AST/WASM/Function.ts +0 -67
  461. package/src/AST/WASM/Memory.ts +0 -21
  462. package/src/AST/WASM/Section.ts +0 -6
  463. package/src/AST/WASM.ts +0 -244
  464. package/src/AST/WithNode.ts +0 -68
  465. package/src/AST/XHRNode.ts +0 -85
  466. package/src/AST.ts +0 -969
  467. package/src/Attribute.ts +0 -130
  468. package/src/Bencmark.ts +0 -184
  469. package/src/Component.ts +0 -63
  470. package/src/Configuration.ts +0 -47
  471. package/src/Controller.ts +0 -36
  472. package/src/DOM/AbstractDOM.ts +0 -462
  473. package/src/DOM/DOMObject.ts +0 -77
  474. package/src/DOM/ShadowDOM.ts +0 -15
  475. package/src/DOM/WrappedDocument.ts +0 -9
  476. package/src/DOM/WrappedWindow.ts +0 -21
  477. package/src/DOM.ts +0 -13
  478. package/src/EventDispatcher.ts +0 -234
  479. package/src/Formats.ts +0 -33
  480. package/src/MessageList.ts +0 -85
  481. package/src/Model.ts +0 -44
  482. package/src/Modifiers.ts +0 -54
  483. package/src/Query.ts +0 -17
  484. package/src/Registry.ts +0 -141
  485. package/src/Scope/DynamicScopeData.ts +0 -27
  486. package/src/Scope/ObjectAccessor.ts +0 -21
  487. package/src/Scope/QueryReference.ts +0 -29
  488. package/src/Scope/ScopeAbstract.ts +0 -11
  489. package/src/Scope/ScopeData.ts +0 -20
  490. package/src/Scope/ScopeDataAbstract.ts +0 -200
  491. package/src/Scope/ScopeObject.ts +0 -3
  492. package/src/Scope/ScopeReference.ts +0 -30
  493. package/src/Scope/ScopedVariableType.ts +0 -7
  494. package/src/Scope/WrappedArray.ts +0 -134
  495. package/src/Scope/properties/ArrayProperty.ts +0 -46
  496. package/src/Scope/properties/FloatProperty.ts +0 -5
  497. package/src/Scope/properties/IntegerProperty.ts +0 -5
  498. package/src/Scope/properties/Property.ts +0 -173
  499. package/src/Scope/properties/_imports.ts +0 -4
  500. package/src/Scope.ts +0 -333
  501. package/src/Service.ts +0 -24
  502. package/src/Tag/ShadowRootTag.ts +0 -5
  503. package/src/Tag/SlotTag.ts +0 -5
  504. package/src/Tag/SlottedTag.ts +0 -17
  505. package/src/Tag/TagList.ts +0 -52
  506. package/src/Tag.ts +0 -838
  507. package/src/Types.ts +0 -34
  508. package/src/Validators.ts +0 -45
  509. package/src/attributes/AddClassIf.ts +0 -14
  510. package/src/attributes/Bind.ts +0 -144
  511. package/src/attributes/ComponentAttribute.ts +0 -23
  512. package/src/attributes/ControllerAttribute.ts +0 -50
  513. package/src/attributes/DisableIf.ts +0 -16
  514. package/src/attributes/Exec.ts +0 -32
  515. package/src/attributes/Format.ts +0 -18
  516. package/src/attributes/If.ts +0 -40
  517. package/src/attributes/JSONAttribute.ts +0 -40
  518. package/src/attributes/KeyAbstract.ts +0 -28
  519. package/src/attributes/KeyDown.ts +0 -10
  520. package/src/attributes/KeyUp.ts +0 -10
  521. package/src/attributes/LazyAttribute.ts +0 -30
  522. package/src/attributes/List.ts +0 -210
  523. package/src/attributes/ListItem.ts +0 -30
  524. package/src/attributes/ListItemModel.ts +0 -7
  525. package/src/attributes/ModelAttribute.ts +0 -8
  526. package/src/attributes/Name.ts +0 -16
  527. package/src/attributes/On.ts +0 -39
  528. package/src/attributes/PersistAttribute.ts +0 -83
  529. package/src/attributes/Referenced.ts +0 -5
  530. package/src/attributes/RootAttribute.ts +0 -24
  531. package/src/attributes/ScopeAttribute.ts +0 -40
  532. package/src/attributes/ScopeChange.ts +0 -35
  533. package/src/attributes/ScriptAttribute.ts +0 -9
  534. package/src/attributes/ServiceAttribute.ts +0 -13
  535. package/src/attributes/SetAttribute.ts +0 -44
  536. package/src/attributes/StandardAttribute.ts +0 -72
  537. package/src/attributes/StyleAttribute.ts +0 -90
  538. package/src/attributes/StyleVarAttribute.ts +0 -40
  539. package/src/attributes/TemplateAttribute.ts +0 -12
  540. package/src/attributes/TypeAttribute.ts +0 -23
  541. package/src/attributes/XHRAttribute.ts +0 -109
  542. package/src/attributes/_imports.ts +0 -32
  543. package/src/contrib/XHR.ts +0 -46
  544. package/src/contrib/_imports.ts +0 -1
  545. package/src/custom-elements.ts +0 -46
  546. package/src/demo/ServiceDemo.ts +0 -12
  547. package/src/demo.ts +0 -2
  548. package/src/helpers/DOMHelper.ts +0 -17
  549. package/src/helpers/ElementHelper.ts +0 -26
  550. package/src/helpers/VisionHelper.ts +0 -88
  551. package/src/helpers/decorators.ts +0 -11
  552. package/src/version.ts +0 -2
  553. package/src/vsn.ts +0 -106
  554. package/test/AST/ArithmeticAssignmentNode.spec.ts +0 -45
  555. package/test/AST/ClassNode.spec.ts +0 -175
  556. package/test/AST/FunctionNode.spec.ts +0 -51
  557. package/test/AST/StringFormatNode.spec.ts +0 -12
  558. package/test/AST/WASM.spec.ts +0 -63
  559. package/test/AST/XHRNode.spec.ts +0 -10
  560. package/test/AST.spec.ts +0 -353
  561. package/test/Controller.spec.ts +0 -42
  562. package/test/DOM.spec.ts +0 -63
  563. package/test/EventDispatcher.spec.ts +0 -191
  564. package/test/MessageList.spec.ts +0 -101
  565. package/test/Model/DataModel.spec.ts +0 -0
  566. package/test/Scope/DynamicScopeData.spec.ts +0 -141
  567. package/test/Scope/ScopeData.spec.ts +0 -58
  568. package/test/Scope/WrappedArray.spec.ts +0 -11
  569. package/test/Scope/properties/ArrayProperty.spec.ts +0 -23
  570. package/test/Scope.spec.ts +0 -69
  571. package/test/Tag/TagList.spec.ts +0 -21
  572. package/test/Tag.spec.ts +0 -4
  573. package/test/attributes/Bind.spec.ts +0 -174
  574. package/test/attributes/JSONAttribute.spec.ts +0 -91
  575. package/test/attributes/ListItem.spec.ts +0 -118
  576. package/test/attributes/ScopeAttribute.spec.ts +0 -35
  577. package/test/attributes/ServiceAttribute.spec.ts +0 -41
  578. package/test/attributes/SetAttribute.spec.ts +0 -55
  579. package/test/attributes/Styles.spec.ts +0 -43
  580. package/test/globals.js +0 -2
  581. package/tsconfig.base.json +0 -17
  582. package/tsconfig.json +0 -6
  583. package/tsconfig.test.json +0 -7
  584. package/types/vsn-component.d.ts +0 -5
  585. package/webpack.config.js +0 -48
  586. package/webpack.development.js +0 -6
  587. package/webpack.production.js +0 -5
package/dist/index.cjs ADDED
@@ -0,0 +1,5011 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ ArrayExpression: () => ArrayExpression,
24
+ ArrayPattern: () => ArrayPattern,
25
+ AssignmentNode: () => AssignmentNode,
26
+ AwaitExpression: () => AwaitExpression,
27
+ BaseNode: () => BaseNode,
28
+ BehaviorNode: () => BehaviorNode,
29
+ BinaryExpression: () => BinaryExpression,
30
+ BlockNode: () => BlockNode,
31
+ CallExpression: () => CallExpression,
32
+ DeclarationNode: () => DeclarationNode,
33
+ DirectiveExpression: () => DirectiveExpression,
34
+ Engine: () => Engine,
35
+ ForNode: () => ForNode,
36
+ FunctionDeclarationNode: () => FunctionDeclarationNode,
37
+ FunctionExpression: () => FunctionExpression,
38
+ IdentifierExpression: () => IdentifierExpression,
39
+ IfNode: () => IfNode,
40
+ IndexExpression: () => IndexExpression,
41
+ Lexer: () => Lexer,
42
+ LiteralExpression: () => LiteralExpression,
43
+ MemberExpression: () => MemberExpression,
44
+ ObjectExpression: () => ObjectExpression,
45
+ ObjectPattern: () => ObjectPattern,
46
+ OnBlockNode: () => OnBlockNode,
47
+ Parser: () => Parser,
48
+ ProgramNode: () => ProgramNode,
49
+ QueryExpression: () => QueryExpression,
50
+ RestElement: () => RestElement,
51
+ ReturnNode: () => ReturnNode,
52
+ SelectorNode: () => SelectorNode,
53
+ SpreadElement: () => SpreadElement,
54
+ StateBlockNode: () => StateBlockNode,
55
+ StateEntryNode: () => StateEntryNode,
56
+ TemplateExpression: () => TemplateExpression,
57
+ TernaryExpression: () => TernaryExpression,
58
+ TokenType: () => TokenType,
59
+ TryNode: () => TryNode,
60
+ UnaryExpression: () => UnaryExpression,
61
+ UseNode: () => UseNode,
62
+ VERSION: () => VERSION,
63
+ WhileNode: () => WhileNode,
64
+ autoMount: () => autoMount,
65
+ parseCFS: () => parseCFS
66
+ });
67
+ module.exports = __toCommonJS(index_exports);
68
+
69
+ // src/parser/token.ts
70
+ var TokenType = /* @__PURE__ */ ((TokenType2) => {
71
+ TokenType2["Whitespace"] = "Whitespace";
72
+ TokenType2["Identifier"] = "Identifier";
73
+ TokenType2["Number"] = "Number";
74
+ TokenType2["String"] = "String";
75
+ TokenType2["Template"] = "Template";
76
+ TokenType2["Boolean"] = "Boolean";
77
+ TokenType2["Null"] = "Null";
78
+ TokenType2["Behavior"] = "Behavior";
79
+ TokenType2["Use"] = "Use";
80
+ TokenType2["State"] = "State";
81
+ TokenType2["On"] = "On";
82
+ TokenType2["Construct"] = "Construct";
83
+ TokenType2["Destruct"] = "Destruct";
84
+ TokenType2["Return"] = "Return";
85
+ TokenType2["If"] = "If";
86
+ TokenType2["Else"] = "Else";
87
+ TokenType2["For"] = "For";
88
+ TokenType2["While"] = "While";
89
+ TokenType2["Try"] = "Try";
90
+ TokenType2["Catch"] = "Catch";
91
+ TokenType2["LBrace"] = "LBrace";
92
+ TokenType2["RBrace"] = "RBrace";
93
+ TokenType2["LParen"] = "LParen";
94
+ TokenType2["RParen"] = "RParen";
95
+ TokenType2["LBracket"] = "LBracket";
96
+ TokenType2["RBracket"] = "RBracket";
97
+ TokenType2["Colon"] = "Colon";
98
+ TokenType2["Semicolon"] = "Semicolon";
99
+ TokenType2["Comma"] = "Comma";
100
+ TokenType2["Ellipsis"] = "Ellipsis";
101
+ TokenType2["Dot"] = "Dot";
102
+ TokenType2["Hash"] = "Hash";
103
+ TokenType2["Greater"] = "Greater";
104
+ TokenType2["Less"] = "Less";
105
+ TokenType2["Plus"] = "Plus";
106
+ TokenType2["Minus"] = "Minus";
107
+ TokenType2["Tilde"] = "Tilde";
108
+ TokenType2["Star"] = "Star";
109
+ TokenType2["Slash"] = "Slash";
110
+ TokenType2["Percent"] = "Percent";
111
+ TokenType2["Equals"] = "Equals";
112
+ TokenType2["Arrow"] = "Arrow";
113
+ TokenType2["DoubleEquals"] = "DoubleEquals";
114
+ TokenType2["TripleEquals"] = "TripleEquals";
115
+ TokenType2["NotEquals"] = "NotEquals";
116
+ TokenType2["StrictNotEquals"] = "StrictNotEquals";
117
+ TokenType2["LessEqual"] = "LessEqual";
118
+ TokenType2["GreaterEqual"] = "GreaterEqual";
119
+ TokenType2["And"] = "And";
120
+ TokenType2["Or"] = "Or";
121
+ TokenType2["Pipe"] = "Pipe";
122
+ TokenType2["NullishCoalesce"] = "NullishCoalesce";
123
+ TokenType2["OptionalChain"] = "OptionalChain";
124
+ TokenType2["Bang"] = "Bang";
125
+ TokenType2["At"] = "At";
126
+ TokenType2["Dollar"] = "Dollar";
127
+ TokenType2["Question"] = "Question";
128
+ return TokenType2;
129
+ })(TokenType || {});
130
+
131
+ // src/parser/lexer.ts
132
+ var KEYWORDS = {
133
+ behavior: "Behavior" /* Behavior */,
134
+ use: "Use" /* Use */,
135
+ state: "State" /* State */,
136
+ on: "On" /* On */,
137
+ construct: "Construct" /* Construct */,
138
+ destruct: "Destruct" /* Destruct */,
139
+ return: "Return" /* Return */,
140
+ if: "If" /* If */,
141
+ else: "Else" /* Else */,
142
+ for: "For" /* For */,
143
+ while: "While" /* While */,
144
+ try: "Try" /* Try */,
145
+ catch: "Catch" /* Catch */,
146
+ true: "Boolean" /* Boolean */,
147
+ false: "Boolean" /* Boolean */,
148
+ null: "Null" /* Null */
149
+ };
150
+ var Lexer = class {
151
+ constructor(input) {
152
+ this.input = input;
153
+ }
154
+ index = 0;
155
+ line = 1;
156
+ column = 1;
157
+ pendingTokens = [];
158
+ templateMode = false;
159
+ templateExpressionMode = false;
160
+ templateBraceDepth = 0;
161
+ tokenize() {
162
+ const tokens = [];
163
+ while (!this.eof()) {
164
+ if (this.pendingTokens.length > 0) {
165
+ const pending = this.pendingTokens.shift();
166
+ if (pending) {
167
+ tokens.push(pending);
168
+ this.trackTemplateBrace(pending);
169
+ continue;
170
+ }
171
+ }
172
+ if (this.templateMode) {
173
+ const chunk = this.readTemplateChunk();
174
+ tokens.push(chunk);
175
+ continue;
176
+ }
177
+ const ch = this.peek();
178
+ if (this.isWhitespace(ch)) {
179
+ tokens.push(this.readWhitespace());
180
+ continue;
181
+ }
182
+ if (ch === "`") {
183
+ this.next();
184
+ this.templateMode = true;
185
+ continue;
186
+ }
187
+ if (ch === "/" && this.peek(1) === "/") {
188
+ this.readLineComment();
189
+ continue;
190
+ }
191
+ if (ch === "/" && this.peek(1) === "*") {
192
+ this.readBlockComment();
193
+ continue;
194
+ }
195
+ if (this.isAlpha(ch) || ch === "_") {
196
+ tokens.push(this.readIdentifier());
197
+ continue;
198
+ }
199
+ if (this.isDigit(ch) || ch === "-" && this.isDigit(this.peek(1))) {
200
+ tokens.push(this.readNumber());
201
+ continue;
202
+ }
203
+ if (ch === '"' || ch === "'") {
204
+ tokens.push(this.readString());
205
+ continue;
206
+ }
207
+ const punct = this.readPunctuator();
208
+ if (punct) {
209
+ tokens.push(punct);
210
+ this.trackTemplateBrace(punct);
211
+ continue;
212
+ }
213
+ throw new Error(`Unexpected character '${ch}' at ${this.line}:${this.column}`);
214
+ }
215
+ return tokens;
216
+ }
217
+ readWhitespace() {
218
+ const start = this.position();
219
+ let value = "";
220
+ while (!this.eof() && this.isWhitespace(this.peek())) {
221
+ value += this.next();
222
+ }
223
+ return this.token("Whitespace" /* Whitespace */, value, start);
224
+ }
225
+ readLineComment() {
226
+ this.next();
227
+ this.next();
228
+ while (!this.eof() && this.peek() !== "\n") {
229
+ this.next();
230
+ }
231
+ }
232
+ readBlockComment() {
233
+ this.next();
234
+ this.next();
235
+ while (!this.eof()) {
236
+ if (this.peek() === "*" && this.peek(1) === "/") {
237
+ this.next();
238
+ this.next();
239
+ return;
240
+ }
241
+ this.next();
242
+ }
243
+ }
244
+ readIdentifier() {
245
+ const start = this.position();
246
+ let value = "";
247
+ while (!this.eof() && (this.isAlphaNumeric(this.peek()) || this.peek() === "_" || this.peek() === "-")) {
248
+ value += this.next();
249
+ }
250
+ const keywordType = KEYWORDS[value];
251
+ if (keywordType) {
252
+ return this.token(keywordType, value, start);
253
+ }
254
+ return this.token("Identifier" /* Identifier */, value, start);
255
+ }
256
+ readNumber() {
257
+ const start = this.position();
258
+ let value = "";
259
+ if (this.peek() === "-") {
260
+ value += this.next();
261
+ }
262
+ while (!this.eof() && this.isDigit(this.peek())) {
263
+ value += this.next();
264
+ }
265
+ if (this.peek() === ".") {
266
+ value += this.next();
267
+ while (!this.eof() && this.isDigit(this.peek())) {
268
+ value += this.next();
269
+ }
270
+ }
271
+ return this.token("Number" /* Number */, value, start);
272
+ }
273
+ readString() {
274
+ const quote = this.next();
275
+ const start = this.position();
276
+ let value = "";
277
+ while (!this.eof()) {
278
+ const ch = this.next();
279
+ if (ch === "\\") {
280
+ const escaped = this.next();
281
+ value += escaped;
282
+ continue;
283
+ }
284
+ if (ch === quote) {
285
+ return this.token("String" /* String */, value, start);
286
+ }
287
+ value += ch;
288
+ }
289
+ throw new Error(`Unterminated string at ${start.line}:${start.column}`);
290
+ }
291
+ readTemplateChunk() {
292
+ const start = this.position();
293
+ let value = "";
294
+ while (!this.eof()) {
295
+ const ch = this.peek();
296
+ if (ch === "`") {
297
+ this.next();
298
+ this.templateMode = false;
299
+ return this.token("Template" /* Template */, value, start);
300
+ }
301
+ if (ch === "$" && this.peek(1) === "{") {
302
+ const dollarStart = this.position();
303
+ this.next();
304
+ const braceStart = this.position();
305
+ this.next();
306
+ this.templateMode = false;
307
+ this.templateExpressionMode = true;
308
+ this.templateBraceDepth = 0;
309
+ this.pendingTokens.push(this.token("Dollar" /* Dollar */, "$", dollarStart));
310
+ this.pendingTokens.push(this.token("LBrace" /* LBrace */, "{", braceStart));
311
+ return this.token("Template" /* Template */, value, start);
312
+ }
313
+ if (ch === "\\") {
314
+ this.next();
315
+ const escaped = this.next();
316
+ value += escaped;
317
+ continue;
318
+ }
319
+ value += this.next();
320
+ }
321
+ throw new Error(`Unterminated template literal at ${start.line}:${start.column}`);
322
+ }
323
+ readPunctuator() {
324
+ const start = this.position();
325
+ const ch = this.peek();
326
+ const next = this.peek(1);
327
+ if (ch === "=" && next === "=" && this.peek(2) === "=") {
328
+ this.next();
329
+ this.next();
330
+ this.next();
331
+ return this.token("TripleEquals" /* TripleEquals */, "===", start);
332
+ }
333
+ if (ch === "=" && next === "=") {
334
+ this.next();
335
+ this.next();
336
+ return this.token("DoubleEquals" /* DoubleEquals */, "==", start);
337
+ }
338
+ if (ch === "=" && next === ">") {
339
+ this.next();
340
+ this.next();
341
+ return this.token("Arrow" /* Arrow */, "=>", start);
342
+ }
343
+ if (ch === "!" && next === "=" && this.peek(2) === "=") {
344
+ this.next();
345
+ this.next();
346
+ this.next();
347
+ return this.token("StrictNotEquals" /* StrictNotEquals */, "!==", start);
348
+ }
349
+ if (ch === "!" && next === "=") {
350
+ this.next();
351
+ this.next();
352
+ return this.token("NotEquals" /* NotEquals */, "!=", start);
353
+ }
354
+ if (ch === "<" && next === "=") {
355
+ this.next();
356
+ this.next();
357
+ return this.token("LessEqual" /* LessEqual */, "<=", start);
358
+ }
359
+ if (ch === ">" && next === "=") {
360
+ this.next();
361
+ this.next();
362
+ return this.token("GreaterEqual" /* GreaterEqual */, ">=", start);
363
+ }
364
+ if (ch === "&" && next === "&") {
365
+ this.next();
366
+ this.next();
367
+ return this.token("And" /* And */, "&&", start);
368
+ }
369
+ if (ch === "|" && next === "|") {
370
+ this.next();
371
+ this.next();
372
+ return this.token("Or" /* Or */, "||", start);
373
+ }
374
+ if (ch === "?" && next === "?") {
375
+ this.next();
376
+ this.next();
377
+ return this.token("NullishCoalesce" /* NullishCoalesce */, "??", start);
378
+ }
379
+ if (ch === "?" && next === ".") {
380
+ this.next();
381
+ this.next();
382
+ return this.token("OptionalChain" /* OptionalChain */, "?.", start);
383
+ }
384
+ if (ch === "|" && next === ">") {
385
+ this.next();
386
+ this.next();
387
+ return this.token("Pipe" /* Pipe */, "|>", start);
388
+ }
389
+ if (ch === "." && next === "." && this.peek(2) === ".") {
390
+ this.next();
391
+ this.next();
392
+ this.next();
393
+ return this.token("Ellipsis" /* Ellipsis */, "...", start);
394
+ }
395
+ const punctMap = {
396
+ "{": "LBrace" /* LBrace */,
397
+ "}": "RBrace" /* RBrace */,
398
+ "(": "LParen" /* LParen */,
399
+ ")": "RParen" /* RParen */,
400
+ "[": "LBracket" /* LBracket */,
401
+ "]": "RBracket" /* RBracket */,
402
+ ":": "Colon" /* Colon */,
403
+ ";": "Semicolon" /* Semicolon */,
404
+ ",": "Comma" /* Comma */,
405
+ ".": "Dot" /* Dot */,
406
+ "#": "Hash" /* Hash */,
407
+ ">": "Greater" /* Greater */,
408
+ "<": "Less" /* Less */,
409
+ "+": "Plus" /* Plus */,
410
+ "-": "Minus" /* Minus */,
411
+ "~": "Tilde" /* Tilde */,
412
+ "*": "Star" /* Star */,
413
+ "/": "Slash" /* Slash */,
414
+ "%": "Percent" /* Percent */,
415
+ "=": "Equals" /* Equals */,
416
+ "!": "Bang" /* Bang */,
417
+ "@": "At" /* At */,
418
+ "$": "Dollar" /* Dollar */,
419
+ "?": "Question" /* Question */
420
+ };
421
+ const type = punctMap[ch];
422
+ if (!type) {
423
+ return null;
424
+ }
425
+ this.next();
426
+ return this.token(type, ch, start);
427
+ }
428
+ trackTemplateBrace(token) {
429
+ if (!this.templateExpressionMode) {
430
+ return;
431
+ }
432
+ if (token.type === "LBrace" /* LBrace */) {
433
+ this.templateBraceDepth += 1;
434
+ } else if (token.type === "RBrace" /* RBrace */) {
435
+ this.templateBraceDepth -= 1;
436
+ if (this.templateBraceDepth <= 0) {
437
+ this.templateExpressionMode = false;
438
+ this.templateMode = true;
439
+ }
440
+ }
441
+ }
442
+ token(type, value, start) {
443
+ return {
444
+ type,
445
+ value,
446
+ start,
447
+ end: this.position()
448
+ };
449
+ }
450
+ position() {
451
+ return { index: this.index, line: this.line, column: this.column };
452
+ }
453
+ peek(offset = 0) {
454
+ return this.input[this.index + offset] ?? "";
455
+ }
456
+ next() {
457
+ const ch = this.input[this.index++] ?? "";
458
+ if (ch === "\n") {
459
+ this.line += 1;
460
+ this.column = 1;
461
+ } else {
462
+ this.column += 1;
463
+ }
464
+ return ch;
465
+ }
466
+ eof() {
467
+ return this.index >= this.input.length;
468
+ }
469
+ isWhitespace(ch) {
470
+ return ch === " " || ch === " " || ch === "\n" || ch === "\r";
471
+ }
472
+ isAlpha(ch) {
473
+ return ch >= "a" && ch <= "z" || ch >= "A" && ch <= "Z";
474
+ }
475
+ isDigit(ch) {
476
+ return ch >= "0" && ch <= "9";
477
+ }
478
+ isAlphaNumeric(ch) {
479
+ return this.isAlpha(ch) || this.isDigit(ch);
480
+ }
481
+ };
482
+
483
+ // src/ast/nodes.ts
484
+ var BaseNode = class {
485
+ constructor(type) {
486
+ this.type = type;
487
+ }
488
+ async prepare(_context) {
489
+ return;
490
+ }
491
+ async evaluate(_context) {
492
+ return void 0;
493
+ }
494
+ };
495
+ async function evaluateWithChildScope(context, block) {
496
+ const scope = context.scope;
497
+ if (!scope || !scope.createChild) {
498
+ return block.evaluate(context);
499
+ }
500
+ const previousScope = context.scope;
501
+ context.scope = scope.createChild();
502
+ try {
503
+ return await block.evaluate(context);
504
+ } finally {
505
+ context.scope = previousScope;
506
+ }
507
+ }
508
+ var ProgramNode = class extends BaseNode {
509
+ constructor(behaviors, uses = []) {
510
+ super("Program");
511
+ this.behaviors = behaviors;
512
+ this.uses = uses;
513
+ }
514
+ };
515
+ var UseNode = class extends BaseNode {
516
+ constructor(name, alias) {
517
+ super("Use");
518
+ this.name = name;
519
+ this.alias = alias;
520
+ }
521
+ };
522
+ var BlockNode = class extends BaseNode {
523
+ constructor(statements) {
524
+ super("Block");
525
+ this.statements = statements;
526
+ }
527
+ async evaluate(context) {
528
+ for (const statement of this.statements) {
529
+ if (context.returning) {
530
+ break;
531
+ }
532
+ if (statement && typeof statement.evaluate === "function") {
533
+ await statement.evaluate(context);
534
+ }
535
+ }
536
+ }
537
+ };
538
+ var SelectorNode = class extends BaseNode {
539
+ constructor(selectorText) {
540
+ super("Selector");
541
+ this.selectorText = selectorText;
542
+ }
543
+ };
544
+ var BehaviorNode = class extends BaseNode {
545
+ constructor(selector, body) {
546
+ super("Behavior");
547
+ this.selector = selector;
548
+ this.body = body;
549
+ }
550
+ };
551
+ var StateEntryNode = class extends BaseNode {
552
+ constructor(name, value, important) {
553
+ super("StateEntry");
554
+ this.name = name;
555
+ this.value = value;
556
+ this.important = important;
557
+ }
558
+ };
559
+ var StateBlockNode = class extends BaseNode {
560
+ constructor(entries) {
561
+ super("StateBlock");
562
+ this.entries = entries;
563
+ }
564
+ };
565
+ var OnBlockNode = class extends BaseNode {
566
+ constructor(eventName, args, body, modifiers = []) {
567
+ super("OnBlock");
568
+ this.eventName = eventName;
569
+ this.args = args;
570
+ this.body = body;
571
+ this.modifiers = modifiers;
572
+ }
573
+ };
574
+ var AssignmentNode = class extends BaseNode {
575
+ constructor(target, value) {
576
+ super("Assignment");
577
+ this.target = target;
578
+ this.value = value;
579
+ }
580
+ async evaluate(context) {
581
+ if (!context.scope || !context.scope.setPath) {
582
+ return void 0;
583
+ }
584
+ const value = await this.value.evaluate(context);
585
+ if (this.target instanceof IdentifierExpression && this.target.name.startsWith("root.") && context.rootScope) {
586
+ const path = this.target.name.slice("root.".length);
587
+ context.rootScope.setPath?.(`self.${path}`, value);
588
+ return value;
589
+ }
590
+ this.assignTarget(context, this.target, value);
591
+ return value;
592
+ }
593
+ assignTarget(context, target, value) {
594
+ if (!context.scope || !context.scope.setPath) {
595
+ return;
596
+ }
597
+ if (target instanceof IdentifierExpression) {
598
+ context.scope.setPath(target.name, value);
599
+ return;
600
+ }
601
+ if (target instanceof ArrayPattern) {
602
+ const source = Array.isArray(value) ? value : [];
603
+ let index = 0;
604
+ for (const element of target.elements) {
605
+ if (element instanceof RestElement) {
606
+ context.scope.setPath(element.target.name, source.slice(index));
607
+ return;
608
+ }
609
+ if (element === null) {
610
+ index += 1;
611
+ continue;
612
+ }
613
+ this.assignTarget(context, element, source[index]);
614
+ index += 1;
615
+ }
616
+ return;
617
+ }
618
+ if (target instanceof ObjectPattern) {
619
+ const source = value && typeof value === "object" ? value : {};
620
+ const usedKeys = /* @__PURE__ */ new Set();
621
+ for (const entry of target.entries) {
622
+ if ("rest" in entry) {
623
+ const rest = {};
624
+ for (const key of Object.keys(source)) {
625
+ if (!usedKeys.has(key)) {
626
+ rest[key] = source[key];
627
+ }
628
+ }
629
+ context.scope.setPath(entry.rest.name, rest);
630
+ continue;
631
+ }
632
+ usedKeys.add(entry.key);
633
+ this.assignTarget(context, entry.target, source[entry.key]);
634
+ }
635
+ return;
636
+ }
637
+ }
638
+ };
639
+ var ReturnNode = class extends BaseNode {
640
+ constructor(value) {
641
+ super("Return");
642
+ this.value = value;
643
+ }
644
+ async evaluate(context) {
645
+ if (context.returning) {
646
+ return context.returnValue;
647
+ }
648
+ context.returnValue = this.value ? await this.value.evaluate(context) : void 0;
649
+ context.returning = true;
650
+ return context.returnValue;
651
+ }
652
+ };
653
+ var IfNode = class extends BaseNode {
654
+ constructor(test, consequent, alternate) {
655
+ super("If");
656
+ this.test = test;
657
+ this.consequent = consequent;
658
+ this.alternate = alternate;
659
+ }
660
+ async evaluate(context) {
661
+ const condition = await this.test.evaluate(context);
662
+ if (condition) {
663
+ return evaluateWithChildScope(context, this.consequent);
664
+ }
665
+ if (this.alternate) {
666
+ return evaluateWithChildScope(context, this.alternate);
667
+ }
668
+ }
669
+ };
670
+ var WhileNode = class extends BaseNode {
671
+ constructor(test, body) {
672
+ super("While");
673
+ this.test = test;
674
+ this.body = body;
675
+ }
676
+ async evaluate(context) {
677
+ const previousScope = context.scope;
678
+ if (context.scope?.createChild) {
679
+ context.scope = context.scope.createChild();
680
+ }
681
+ try {
682
+ while (await this.test.evaluate(context)) {
683
+ await this.body.evaluate(context);
684
+ if (context.returning) {
685
+ break;
686
+ }
687
+ }
688
+ } finally {
689
+ context.scope = previousScope;
690
+ }
691
+ }
692
+ };
693
+ var ForNode = class extends BaseNode {
694
+ constructor(init, test, update, body) {
695
+ super("For");
696
+ this.init = init;
697
+ this.test = test;
698
+ this.update = update;
699
+ this.body = body;
700
+ }
701
+ async evaluate(context) {
702
+ if (this.init) {
703
+ await this.init.evaluate(context);
704
+ }
705
+ const previousScope = context.scope;
706
+ let bodyScope = context.scope;
707
+ if (context.scope?.createChild) {
708
+ bodyScope = context.scope.createChild();
709
+ }
710
+ while (this.test ? await this.test.evaluate(context) : true) {
711
+ context.scope = bodyScope;
712
+ await this.body.evaluate(context);
713
+ if (context.returning) {
714
+ break;
715
+ }
716
+ context.scope = previousScope;
717
+ if (this.update) {
718
+ await this.update.evaluate(context);
719
+ }
720
+ }
721
+ context.scope = previousScope;
722
+ }
723
+ };
724
+ var TryNode = class extends BaseNode {
725
+ constructor(body, errorName, handler) {
726
+ super("Try");
727
+ this.body = body;
728
+ this.errorName = errorName;
729
+ this.handler = handler;
730
+ }
731
+ async evaluate(context) {
732
+ try {
733
+ return await evaluateWithChildScope(context, this.body);
734
+ } catch (error) {
735
+ if (context.returning) {
736
+ return context.returnValue;
737
+ }
738
+ const previousScope = context.scope;
739
+ let handlerScope = context.scope;
740
+ if (context.scope?.createChild) {
741
+ handlerScope = context.scope.createChild();
742
+ }
743
+ context.scope = handlerScope;
744
+ const scope = context.scope;
745
+ let previous = void 0;
746
+ if (scope) {
747
+ previous = scope.getPath(this.errorName);
748
+ if (scope.setPath) {
749
+ scope.setPath(`self.${this.errorName}`, error);
750
+ }
751
+ }
752
+ await this.handler.evaluate(context);
753
+ if (scope && scope.setPath && handlerScope === previousScope) {
754
+ scope.setPath(this.errorName, previous);
755
+ }
756
+ context.scope = previousScope;
757
+ }
758
+ }
759
+ };
760
+ var FunctionDeclarationNode = class extends BaseNode {
761
+ constructor(name, params, body, isAsync = false) {
762
+ super("FunctionDeclaration");
763
+ this.name = name;
764
+ this.params = params;
765
+ this.body = body;
766
+ this.isAsync = isAsync;
767
+ }
768
+ };
769
+ var FunctionExpression = class extends BaseNode {
770
+ constructor(params, body, isAsync = false) {
771
+ super("FunctionExpression");
772
+ this.params = params;
773
+ this.body = body;
774
+ this.isAsync = isAsync;
775
+ }
776
+ async evaluate(context) {
777
+ const scope = context.scope;
778
+ const globals = context.globals;
779
+ const element = context.element;
780
+ return async (...args) => {
781
+ const activeScope = scope?.createChild ? scope.createChild() : scope;
782
+ const inner = {
783
+ scope: activeScope,
784
+ rootScope: context.rootScope,
785
+ ...globals ? { globals } : {},
786
+ ...element ? { element } : {},
787
+ returnValue: void 0,
788
+ returning: false
789
+ };
790
+ if (activeScope) {
791
+ const previousValues = /* @__PURE__ */ new Map();
792
+ await this.applyParams(activeScope, previousValues, inner, args);
793
+ await this.body.evaluate(inner);
794
+ if (activeScope === scope) {
795
+ this.restoreParams(activeScope, previousValues);
796
+ }
797
+ } else {
798
+ await this.body.evaluate(inner);
799
+ }
800
+ return inner.returnValue;
801
+ };
802
+ }
803
+ async applyParams(scope, previousValues, context, args) {
804
+ if (!scope || !scope.setPath) {
805
+ return;
806
+ }
807
+ let argIndex = 0;
808
+ for (const param of this.params) {
809
+ const name = param.name;
810
+ if (!name) {
811
+ continue;
812
+ }
813
+ previousValues.set(name, scope.getPath(name));
814
+ if (param.rest) {
815
+ scope.setPath(`self.${name}`, args.slice(argIndex));
816
+ argIndex = args.length;
817
+ continue;
818
+ }
819
+ let value = args[argIndex];
820
+ if (value === void 0 && param.defaultValue) {
821
+ value = await param.defaultValue.evaluate(context);
822
+ }
823
+ scope.setPath(`self.${name}`, value);
824
+ argIndex += 1;
825
+ }
826
+ }
827
+ restoreParams(scope, previousValues) {
828
+ if (!scope || !scope.setPath) {
829
+ return;
830
+ }
831
+ for (const param of this.params) {
832
+ const name = param.name;
833
+ if (!name) {
834
+ continue;
835
+ }
836
+ scope.setPath(name, previousValues.get(name));
837
+ }
838
+ }
839
+ };
840
+ var DeclarationNode = class extends BaseNode {
841
+ constructor(target, operator, value, flags, flagArgs) {
842
+ super("Declaration");
843
+ this.target = target;
844
+ this.operator = operator;
845
+ this.value = value;
846
+ this.flags = flags;
847
+ this.flagArgs = flagArgs;
848
+ }
849
+ };
850
+ var IdentifierExpression = class extends BaseNode {
851
+ constructor(name) {
852
+ super("Identifier");
853
+ this.name = name;
854
+ }
855
+ async evaluate(context) {
856
+ if (this.name.startsWith("root.") && context.rootScope) {
857
+ const path = this.name.slice("root.".length);
858
+ return context.rootScope.getPath(`self.${path}`);
859
+ }
860
+ if (context.scope) {
861
+ const value = context.scope.getPath(this.name);
862
+ const root = this.name.split(".")[0];
863
+ const explicit = this.name.startsWith("parent.") || this.name.startsWith("root.") || this.name.startsWith("self.");
864
+ if (explicit || value !== void 0 || root && context.scope.hasKey?.(root)) {
865
+ return value;
866
+ }
867
+ }
868
+ return context.globals ? context.globals[this.name] : void 0;
869
+ }
870
+ };
871
+ var SpreadElement = class extends BaseNode {
872
+ constructor(value) {
873
+ super("SpreadElement");
874
+ this.value = value;
875
+ }
876
+ };
877
+ var RestElement = class extends BaseNode {
878
+ constructor(target) {
879
+ super("RestElement");
880
+ this.target = target;
881
+ }
882
+ };
883
+ var ArrayPattern = class extends BaseNode {
884
+ constructor(elements) {
885
+ super("ArrayPattern");
886
+ this.elements = elements;
887
+ }
888
+ };
889
+ var ObjectPattern = class extends BaseNode {
890
+ constructor(entries) {
891
+ super("ObjectPattern");
892
+ this.entries = entries;
893
+ }
894
+ };
895
+ var LiteralExpression = class extends BaseNode {
896
+ constructor(value) {
897
+ super("Literal");
898
+ this.value = value;
899
+ }
900
+ async evaluate() {
901
+ return this.value;
902
+ }
903
+ };
904
+ var TemplateExpression = class extends BaseNode {
905
+ constructor(parts) {
906
+ super("TemplateExpression");
907
+ this.parts = parts;
908
+ }
909
+ async evaluate(context) {
910
+ let result = "";
911
+ for (const part of this.parts) {
912
+ const value = await part.evaluate(context);
913
+ result += value == null ? "" : String(value);
914
+ }
915
+ return result;
916
+ }
917
+ };
918
+ var UnaryExpression = class extends BaseNode {
919
+ constructor(operator, argument) {
920
+ super("UnaryExpression");
921
+ this.operator = operator;
922
+ this.argument = argument;
923
+ }
924
+ async evaluate(context) {
925
+ const value = await this.argument.evaluate(context);
926
+ if (this.operator === "!") {
927
+ return !value;
928
+ }
929
+ if (this.operator === "-") {
930
+ return -value;
931
+ }
932
+ return value;
933
+ }
934
+ };
935
+ var BinaryExpression = class extends BaseNode {
936
+ constructor(operator, left, right) {
937
+ super("BinaryExpression");
938
+ this.operator = operator;
939
+ this.left = left;
940
+ this.right = right;
941
+ }
942
+ async evaluate(context) {
943
+ if (this.operator === "&&") {
944
+ const leftValue = await this.left.evaluate(context);
945
+ return leftValue && await this.right.evaluate(context);
946
+ }
947
+ if (this.operator === "||") {
948
+ const leftValue = await this.left.evaluate(context);
949
+ return leftValue || await this.right.evaluate(context);
950
+ }
951
+ if (this.operator === "??") {
952
+ const leftValue = await this.left.evaluate(context);
953
+ return leftValue ?? await this.right.evaluate(context);
954
+ }
955
+ const left = await this.left.evaluate(context);
956
+ const right = await this.right.evaluate(context);
957
+ if (this.operator === "+") {
958
+ return left + right;
959
+ }
960
+ if (this.operator === "-") {
961
+ return left - right;
962
+ }
963
+ if (this.operator === "*") {
964
+ return left * right;
965
+ }
966
+ if (this.operator === "/") {
967
+ return left / right;
968
+ }
969
+ if (this.operator === "%") {
970
+ return left % right;
971
+ }
972
+ if (this.operator === "==") {
973
+ return left == right;
974
+ }
975
+ if (this.operator === "!=") {
976
+ return left != right;
977
+ }
978
+ if (this.operator === "===") {
979
+ return left === right;
980
+ }
981
+ if (this.operator === "!==") {
982
+ return left !== right;
983
+ }
984
+ if (this.operator === "<") {
985
+ return left < right;
986
+ }
987
+ if (this.operator === ">") {
988
+ return left > right;
989
+ }
990
+ if (this.operator === "<=") {
991
+ return left <= right;
992
+ }
993
+ if (this.operator === ">=") {
994
+ return left >= right;
995
+ }
996
+ return void 0;
997
+ }
998
+ };
999
+ var TernaryExpression = class extends BaseNode {
1000
+ constructor(test, consequent, alternate) {
1001
+ super("TernaryExpression");
1002
+ this.test = test;
1003
+ this.consequent = consequent;
1004
+ this.alternate = alternate;
1005
+ }
1006
+ async evaluate(context) {
1007
+ const condition = await this.test.evaluate(context);
1008
+ if (condition) {
1009
+ return this.consequent.evaluate(context);
1010
+ }
1011
+ return this.alternate.evaluate(context);
1012
+ }
1013
+ };
1014
+ var MemberExpression = class _MemberExpression extends BaseNode {
1015
+ constructor(target, property, optional = false) {
1016
+ super("MemberExpression");
1017
+ this.target = target;
1018
+ this.property = property;
1019
+ this.optional = optional;
1020
+ }
1021
+ async evaluate(context) {
1022
+ const resolved = await this.resolve(context);
1023
+ return resolved?.value;
1024
+ }
1025
+ async resolve(context) {
1026
+ const path = this.getIdentifierPath();
1027
+ if (path) {
1028
+ const resolved = this.resolveFromScope(context, path);
1029
+ if (resolved) {
1030
+ return resolved;
1031
+ }
1032
+ const resolvedGlobal = this.resolveFromGlobals(context, path);
1033
+ if (resolvedGlobal) {
1034
+ return resolvedGlobal;
1035
+ }
1036
+ }
1037
+ const target = await this.target.evaluate(context);
1038
+ if (target == null) {
1039
+ return { value: void 0, target, optional: this.optional };
1040
+ }
1041
+ return { value: target[this.property], target, optional: this.optional };
1042
+ }
1043
+ getIdentifierPath() {
1044
+ const targetPath = this.getTargetIdentifierPath();
1045
+ if (!targetPath) {
1046
+ return void 0;
1047
+ }
1048
+ const path = `${targetPath.path}.${this.property}`;
1049
+ return { path, root: targetPath.root };
1050
+ }
1051
+ getTargetIdentifierPath() {
1052
+ if (this.target instanceof IdentifierExpression) {
1053
+ const name = this.target.name;
1054
+ const root = name.split(".")[0];
1055
+ if (!root) {
1056
+ return void 0;
1057
+ }
1058
+ return { path: name, root };
1059
+ }
1060
+ if (this.target instanceof _MemberExpression) {
1061
+ return this.target.getIdentifierPath();
1062
+ }
1063
+ return void 0;
1064
+ }
1065
+ resolveFromScope(context, path) {
1066
+ if (!context.scope) {
1067
+ return void 0;
1068
+ }
1069
+ if (path.path.startsWith("root.") && context.rootScope) {
1070
+ const localPath = path.path.slice("root.".length);
1071
+ const value2 = context.rootScope.getPath(`self.${localPath}`);
1072
+ const targetPath2 = localPath.split(".").slice(0, -1).join(".");
1073
+ const target2 = targetPath2 ? context.rootScope.getPath(`self.${targetPath2}`) : context.rootScope;
1074
+ return { value: value2, target: target2, optional: this.optional };
1075
+ }
1076
+ const value = context.scope.getPath(path.path);
1077
+ const explicit = path.path.startsWith("parent.") || path.path.startsWith("root.") || path.path.startsWith("self.");
1078
+ if (!explicit && value === void 0 && !context.scope.hasKey?.(path.root)) {
1079
+ return void 0;
1080
+ }
1081
+ const targetPath = this.getTargetPath(path.path);
1082
+ const target = targetPath ? context.scope.getPath(targetPath) : void 0;
1083
+ return { value, target, optional: this.optional };
1084
+ }
1085
+ resolveFromGlobals(context, path) {
1086
+ const globals = context.globals ?? {};
1087
+ if (!path.root || !(path.root in globals)) {
1088
+ return void 0;
1089
+ }
1090
+ let value = globals[path.root];
1091
+ let parent = void 0;
1092
+ const parts = path.path.split(".");
1093
+ for (let i = 1; i < parts.length; i += 1) {
1094
+ parent = value;
1095
+ const part = parts[i];
1096
+ if (!part) {
1097
+ return { value: void 0, target: parent, optional: this.optional };
1098
+ }
1099
+ value = value?.[part];
1100
+ }
1101
+ return { value, target: parent, optional: this.optional };
1102
+ }
1103
+ getTargetPath(path) {
1104
+ const parts = path.split(".");
1105
+ if (parts.length <= 1) {
1106
+ return void 0;
1107
+ }
1108
+ return parts.slice(0, -1).join(".");
1109
+ }
1110
+ };
1111
+ var CallExpression = class extends BaseNode {
1112
+ constructor(callee, args) {
1113
+ super("CallExpression");
1114
+ this.callee = callee;
1115
+ this.args = args;
1116
+ }
1117
+ async evaluate(context) {
1118
+ const resolved = await this.resolveCallee(context);
1119
+ const fn = resolved?.fn ?? await this.callee.evaluate(context);
1120
+ if (typeof fn !== "function") {
1121
+ return void 0;
1122
+ }
1123
+ const values = [];
1124
+ for (const arg of this.args) {
1125
+ values.push(await arg.evaluate(context));
1126
+ }
1127
+ return fn.apply(resolved?.thisArg, values);
1128
+ }
1129
+ async resolveCallee(context) {
1130
+ if (this.callee instanceof MemberExpression) {
1131
+ const resolved = await this.callee.resolve(context);
1132
+ if (!resolved) {
1133
+ return void 0;
1134
+ }
1135
+ return { fn: resolved.value, thisArg: resolved.target };
1136
+ }
1137
+ if (!(this.callee instanceof IdentifierExpression)) {
1138
+ return void 0;
1139
+ }
1140
+ const name = this.callee.name;
1141
+ const globals = context.globals ?? {};
1142
+ const parts = name.split(".");
1143
+ const root = parts[0];
1144
+ if (!root || !(root in globals)) {
1145
+ if (parts.length > 1 && context.scope) {
1146
+ const parentPath = parts.slice(0, -1).join(".");
1147
+ const methodName = parts[parts.length - 1];
1148
+ if (!methodName) {
1149
+ return void 0;
1150
+ }
1151
+ const parentValue = context.scope.getPath(parentPath);
1152
+ if (parentValue == null) {
1153
+ return void 0;
1154
+ }
1155
+ return { fn: parentValue?.[methodName], thisArg: parentValue };
1156
+ }
1157
+ return void 0;
1158
+ }
1159
+ let value = globals[root];
1160
+ let parent = void 0;
1161
+ for (let i = 1; i < parts.length; i += 1) {
1162
+ parent = value;
1163
+ const part = parts[i];
1164
+ if (!part) {
1165
+ return void 0;
1166
+ }
1167
+ value = value?.[part];
1168
+ }
1169
+ return { fn: value, thisArg: parent };
1170
+ }
1171
+ };
1172
+ var ArrayExpression = class extends BaseNode {
1173
+ constructor(elements) {
1174
+ super("ArrayExpression");
1175
+ this.elements = elements;
1176
+ }
1177
+ async evaluate(context) {
1178
+ const values = [];
1179
+ for (const element of this.elements) {
1180
+ if (element instanceof SpreadElement) {
1181
+ const spreadValue = await element.value.evaluate(context);
1182
+ if (spreadValue == null) {
1183
+ continue;
1184
+ }
1185
+ const iterator = spreadValue[Symbol.iterator];
1186
+ if (typeof iterator === "function") {
1187
+ for (const entry of spreadValue) {
1188
+ values.push(entry);
1189
+ }
1190
+ } else {
1191
+ values.push(spreadValue);
1192
+ }
1193
+ continue;
1194
+ }
1195
+ values.push(await element.evaluate(context));
1196
+ }
1197
+ return values;
1198
+ }
1199
+ };
1200
+ var ObjectExpression = class extends BaseNode {
1201
+ constructor(entries) {
1202
+ super("ObjectExpression");
1203
+ this.entries = entries;
1204
+ }
1205
+ async evaluate(context) {
1206
+ const result = {};
1207
+ for (const entry of this.entries) {
1208
+ if ("spread" in entry) {
1209
+ const spreadValue = await entry.spread.evaluate(context);
1210
+ if (spreadValue != null) {
1211
+ Object.assign(result, spreadValue);
1212
+ }
1213
+ continue;
1214
+ }
1215
+ if ("computed" in entry && entry.computed) {
1216
+ const keyValue = await entry.keyExpr.evaluate(context);
1217
+ result[String(keyValue)] = await entry.value.evaluate(context);
1218
+ } else {
1219
+ result[entry.key] = await entry.value.evaluate(context);
1220
+ }
1221
+ }
1222
+ return result;
1223
+ }
1224
+ };
1225
+ var IndexExpression = class extends BaseNode {
1226
+ constructor(target, index) {
1227
+ super("IndexExpression");
1228
+ this.target = target;
1229
+ this.index = index;
1230
+ }
1231
+ async evaluate(context) {
1232
+ const target = await this.target.evaluate(context);
1233
+ if (target == null) {
1234
+ return void 0;
1235
+ }
1236
+ const index = await this.index.evaluate(context);
1237
+ if (index == null) {
1238
+ return void 0;
1239
+ }
1240
+ return target[index];
1241
+ }
1242
+ };
1243
+ var DirectiveExpression = class extends BaseNode {
1244
+ constructor(kind, name) {
1245
+ super("Directive");
1246
+ this.kind = kind;
1247
+ this.name = name;
1248
+ }
1249
+ async evaluate(context) {
1250
+ const element = context.element;
1251
+ if (!element) {
1252
+ return `${this.kind}:${this.name}`;
1253
+ }
1254
+ if (this.kind === "attr") {
1255
+ if (this.name === "value") {
1256
+ if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement) {
1257
+ return element.value;
1258
+ }
1259
+ if (element instanceof HTMLSelectElement) {
1260
+ return element.value;
1261
+ }
1262
+ }
1263
+ if (this.name === "checked" && element instanceof HTMLInputElement) {
1264
+ return element.checked;
1265
+ }
1266
+ if (this.name === "html" && element instanceof HTMLElement) {
1267
+ return element.innerHTML;
1268
+ }
1269
+ return element.getAttribute(this.name) ?? void 0;
1270
+ }
1271
+ if (this.kind === "style" && element instanceof HTMLElement) {
1272
+ return element.style.getPropertyValue(this.name) ?? void 0;
1273
+ }
1274
+ return void 0;
1275
+ }
1276
+ };
1277
+ var AwaitExpression = class extends BaseNode {
1278
+ constructor(argument) {
1279
+ super("AwaitExpression");
1280
+ this.argument = argument;
1281
+ }
1282
+ async evaluate(context) {
1283
+ const value = await this.argument.evaluate(context);
1284
+ return await value;
1285
+ }
1286
+ };
1287
+ var QueryExpression = class extends BaseNode {
1288
+ constructor(direction, selector) {
1289
+ super("Query");
1290
+ this.direction = direction;
1291
+ this.selector = selector;
1292
+ }
1293
+ async evaluate(context) {
1294
+ const selector = this.selector.trim();
1295
+ if (!selector) {
1296
+ return [];
1297
+ }
1298
+ if (this.direction === "ancestor") {
1299
+ const results = [];
1300
+ let cursor = context.element?.parentElement;
1301
+ while (cursor) {
1302
+ if (cursor.matches(selector)) {
1303
+ results.push(cursor);
1304
+ }
1305
+ cursor = cursor.parentElement;
1306
+ }
1307
+ return results;
1308
+ }
1309
+ const root = this.direction === "descendant" ? context.element ?? (typeof document !== "undefined" ? document : void 0) : typeof document !== "undefined" ? document : void 0;
1310
+ if (!root || !("querySelectorAll" in root)) {
1311
+ return [];
1312
+ }
1313
+ return Array.from(root.querySelectorAll(selector));
1314
+ }
1315
+ };
1316
+
1317
+ // src/parser/token-stream.ts
1318
+ var TokenStream = class {
1319
+ constructor(tokens) {
1320
+ this.tokens = tokens;
1321
+ }
1322
+ index = 0;
1323
+ peek(offset = 0) {
1324
+ return this.tokens[this.index + offset] ?? null;
1325
+ }
1326
+ next() {
1327
+ const token = this.tokens[this.index++];
1328
+ if (!token) {
1329
+ throw new Error("Unexpected end of input");
1330
+ }
1331
+ return token;
1332
+ }
1333
+ eof() {
1334
+ return this.index >= this.tokens.length;
1335
+ }
1336
+ match(type) {
1337
+ if (this.peek()?.type === type) {
1338
+ this.next();
1339
+ return true;
1340
+ }
1341
+ return false;
1342
+ }
1343
+ expect(type) {
1344
+ const token = this.next();
1345
+ if (token.type !== type) {
1346
+ throw new Error(`Expected ${type} but got ${token.type}`);
1347
+ }
1348
+ return token;
1349
+ }
1350
+ skipWhitespace() {
1351
+ while (this.peek()?.type === "Whitespace" /* Whitespace */) {
1352
+ this.next();
1353
+ }
1354
+ }
1355
+ peekNonWhitespace(offset = 0) {
1356
+ let count = 0;
1357
+ for (let i = this.index; i < this.tokens.length; i++) {
1358
+ const token = this.tokens[i];
1359
+ if (token.type === "Whitespace" /* Whitespace */) {
1360
+ continue;
1361
+ }
1362
+ if (count === offset) {
1363
+ return token;
1364
+ }
1365
+ count += 1;
1366
+ }
1367
+ return null;
1368
+ }
1369
+ };
1370
+
1371
+ // src/parser/parser.ts
1372
+ var Parser = class _Parser {
1373
+ stream;
1374
+ source;
1375
+ customFlags;
1376
+ allowImplicitSemicolon = false;
1377
+ awaitStack = [];
1378
+ constructor(input, options) {
1379
+ this.source = input;
1380
+ this.customFlags = options?.customFlags ?? /* @__PURE__ */ new Set();
1381
+ const lexer = new Lexer(input);
1382
+ this.stream = new TokenStream(lexer.tokenize());
1383
+ }
1384
+ static parseInline(code) {
1385
+ const parser = new _Parser(`{${code}}`);
1386
+ return parser.parseInlineBlock();
1387
+ }
1388
+ parseProgram() {
1389
+ return this.wrapErrors(() => {
1390
+ const behaviors = [];
1391
+ const uses = [];
1392
+ this.stream.skipWhitespace();
1393
+ while (!this.stream.eof()) {
1394
+ const next = this.stream.peek();
1395
+ if (!next) {
1396
+ break;
1397
+ }
1398
+ if (next.type === "Use" /* Use */) {
1399
+ uses.push(this.parseUseStatement());
1400
+ } else {
1401
+ behaviors.push(this.parseBehavior());
1402
+ }
1403
+ this.stream.skipWhitespace();
1404
+ }
1405
+ return new ProgramNode(behaviors, uses);
1406
+ });
1407
+ }
1408
+ parseInlineBlock() {
1409
+ return this.wrapErrors(() => {
1410
+ this.stream.skipWhitespace();
1411
+ this.allowImplicitSemicolon = true;
1412
+ return this.parseBlock({ allowDeclarations: false });
1413
+ });
1414
+ }
1415
+ parseBehavior() {
1416
+ return this.wrapErrors(() => {
1417
+ this.stream.skipWhitespace();
1418
+ this.stream.expect("Behavior" /* Behavior */);
1419
+ const selector = this.parseSelector();
1420
+ const body = this.parseBlock({ allowDeclarations: true });
1421
+ return new BehaviorNode(selector, body);
1422
+ });
1423
+ }
1424
+ parseSelector() {
1425
+ let selectorText = "";
1426
+ let sawNonWhitespace = false;
1427
+ while (true) {
1428
+ const token = this.stream.peek();
1429
+ if (!token) {
1430
+ break;
1431
+ }
1432
+ if (token.type === "LBrace" /* LBrace */) {
1433
+ break;
1434
+ }
1435
+ if (token.type === "Whitespace" /* Whitespace */) {
1436
+ this.stream.next();
1437
+ if (sawNonWhitespace && selectorText[selectorText.length - 1] !== " ") {
1438
+ selectorText += " ";
1439
+ }
1440
+ continue;
1441
+ }
1442
+ sawNonWhitespace = true;
1443
+ selectorText += this.stream.next().value;
1444
+ }
1445
+ if (!selectorText.trim()) {
1446
+ throw new Error("Behavior selector is required");
1447
+ }
1448
+ return new SelectorNode(selectorText.trim());
1449
+ }
1450
+ parseUseStatement() {
1451
+ return this.wrapErrors(() => {
1452
+ this.stream.expect("Use" /* Use */);
1453
+ this.stream.skipWhitespace();
1454
+ const name = this.parseIdentifierPath();
1455
+ this.stream.skipWhitespace();
1456
+ let alias = name;
1457
+ const next = this.stream.peek();
1458
+ if (next?.type === "Identifier" /* Identifier */ && next.value === "as") {
1459
+ this.stream.next();
1460
+ this.stream.skipWhitespace();
1461
+ alias = this.stream.expect("Identifier" /* Identifier */).value;
1462
+ }
1463
+ this.stream.skipWhitespace();
1464
+ this.stream.expect("Semicolon" /* Semicolon */);
1465
+ return new UseNode(name, alias);
1466
+ });
1467
+ }
1468
+ wrapErrors(fn) {
1469
+ try {
1470
+ return fn();
1471
+ } catch (error) {
1472
+ if (error instanceof Error && !/\(line\s+\d+, column\s+\d+\)/i.test(error.message)) {
1473
+ throw new Error(this.formatError(error.message));
1474
+ }
1475
+ throw error;
1476
+ }
1477
+ }
1478
+ formatError(message) {
1479
+ const token = this.stream.peek() ?? this.stream.peekNonWhitespace(0);
1480
+ if (!token) {
1481
+ return `Parse error: ${message}`;
1482
+ }
1483
+ const line = token.start.line;
1484
+ const column = token.start.column;
1485
+ const snippet = this.getLineSnippet(line, column);
1486
+ return `Parse error (line ${line}, column ${column}): ${message}
1487
+ ${snippet}`;
1488
+ }
1489
+ getLineSnippet(line, column) {
1490
+ const lines = this.source.split(/\r?\n/);
1491
+ const content = lines[line - 1] ?? "";
1492
+ const caret = `${" ".repeat(Math.max(column - 1, 0))}^`;
1493
+ return `${content}
1494
+ ${caret}`;
1495
+ }
1496
+ parseBlock(options) {
1497
+ const allowDeclarations = options?.allowDeclarations ?? false;
1498
+ this.stream.skipWhitespace();
1499
+ this.stream.expect("LBrace" /* LBrace */);
1500
+ const statements = [];
1501
+ let declarationsOpen = allowDeclarations;
1502
+ let sawConstruct = false;
1503
+ let sawFunctionOrOn = false;
1504
+ let sawNestedBehavior = false;
1505
+ while (true) {
1506
+ this.stream.skipWhitespace();
1507
+ const next = this.stream.peek();
1508
+ if (!next) {
1509
+ throw new Error("Unterminated block");
1510
+ }
1511
+ if (next.type === "RBrace" /* RBrace */) {
1512
+ this.stream.next();
1513
+ break;
1514
+ }
1515
+ if (allowDeclarations && next.type === "Behavior" /* Behavior */) {
1516
+ sawNestedBehavior = true;
1517
+ }
1518
+ if (allowDeclarations && sawNestedBehavior && next.type !== "Behavior" /* Behavior */) {
1519
+ throw new Error("Nested behaviors must appear after construct, function, and on blocks");
1520
+ }
1521
+ const isFunctionDeclaration = allowDeclarations && this.isFunctionDeclarationStart();
1522
+ if (isFunctionDeclaration) {
1523
+ if (!sawConstruct) {
1524
+ sawFunctionOrOn = true;
1525
+ }
1526
+ statements.push(this.parseFunctionDeclaration());
1527
+ continue;
1528
+ }
1529
+ const isFunctionExpressionAssignment = allowDeclarations && this.isFunctionExpressionAssignmentStart();
1530
+ if (isFunctionExpressionAssignment) {
1531
+ if (!declarationsOpen) {
1532
+ throw new Error("Declarations must appear before blocks");
1533
+ }
1534
+ statements.push(this.parseAssignment());
1535
+ continue;
1536
+ }
1537
+ const isDeclaration = this.isDeclarationStart();
1538
+ if (isDeclaration) {
1539
+ if (!allowDeclarations) {
1540
+ throw new Error("Declarations are only allowed at the behavior root");
1541
+ }
1542
+ if (!declarationsOpen) {
1543
+ throw new Error("Declarations must appear before blocks");
1544
+ }
1545
+ statements.push(this.parseDeclaration());
1546
+ } else {
1547
+ if (declarationsOpen) {
1548
+ declarationsOpen = false;
1549
+ }
1550
+ if (allowDeclarations && next.type === "On" /* On */ && !sawConstruct) {
1551
+ sawFunctionOrOn = true;
1552
+ }
1553
+ if (allowDeclarations && next.type === "Construct" /* Construct */) {
1554
+ if (sawFunctionOrOn) {
1555
+ throw new Error("Construct blocks must appear before functions and on blocks");
1556
+ }
1557
+ sawConstruct = true;
1558
+ }
1559
+ statements.push(this.parseStatement());
1560
+ }
1561
+ }
1562
+ return new BlockNode(statements);
1563
+ }
1564
+ parseStatement(options) {
1565
+ this.stream.skipWhitespace();
1566
+ const next = this.stream.peek();
1567
+ if (!next) {
1568
+ throw new Error("Unexpected end of input");
1569
+ }
1570
+ const allowBlocks = options?.allowBlocks ?? true;
1571
+ const allowReturn = options?.allowReturn ?? false;
1572
+ if (next.type === "Return" /* Return */) {
1573
+ if (!allowReturn) {
1574
+ throw new Error("Return is only allowed inside functions");
1575
+ }
1576
+ return this.parseReturnStatement();
1577
+ }
1578
+ if (allowBlocks && next.type === "On" /* On */) {
1579
+ return this.parseOnBlock();
1580
+ }
1581
+ if (allowBlocks && next.type === "If" /* If */) {
1582
+ return this.parseIfBlock();
1583
+ }
1584
+ if (allowBlocks && next.type === "For" /* For */) {
1585
+ return this.parseForBlock();
1586
+ }
1587
+ if (allowBlocks && next.type === "While" /* While */) {
1588
+ return this.parseWhileBlock();
1589
+ }
1590
+ if (allowBlocks && next.type === "Try" /* Try */) {
1591
+ return this.parseTryBlock();
1592
+ }
1593
+ if (allowBlocks && next.type === "Construct" /* Construct */) {
1594
+ return this.parseConstructBlock();
1595
+ }
1596
+ if (allowBlocks && next.type === "Destruct" /* Destruct */) {
1597
+ return this.parseDestructBlock();
1598
+ }
1599
+ if (allowBlocks && next.type === "Behavior" /* Behavior */) {
1600
+ return this.parseBehavior();
1601
+ }
1602
+ if (this.isAwaitAllowed() && next.type === "Identifier" /* Identifier */ && next.value === "await") {
1603
+ return this.parseExpressionStatement();
1604
+ }
1605
+ if (this.isAssignmentStart()) {
1606
+ return this.parseAssignment();
1607
+ }
1608
+ if (this.isExpressionStatementStart()) {
1609
+ return this.parseExpressionStatement();
1610
+ }
1611
+ throw new Error(`Unexpected token ${next.type}`);
1612
+ }
1613
+ parseStateBlock() {
1614
+ this.stream.expect("State" /* State */);
1615
+ this.stream.skipWhitespace();
1616
+ this.stream.expect("LBrace" /* LBrace */);
1617
+ const entries = [];
1618
+ while (true) {
1619
+ this.stream.skipWhitespace();
1620
+ const next = this.stream.peek();
1621
+ if (!next) {
1622
+ throw new Error("Unterminated state block");
1623
+ }
1624
+ if (next.type === "RBrace" /* RBrace */) {
1625
+ this.stream.next();
1626
+ break;
1627
+ }
1628
+ const nameToken = this.stream.expect("Identifier" /* Identifier */);
1629
+ this.stream.skipWhitespace();
1630
+ this.stream.expect("Colon" /* Colon */);
1631
+ this.stream.skipWhitespace();
1632
+ const value = this.parseExpression();
1633
+ this.stream.skipWhitespace();
1634
+ let important = false;
1635
+ if (this.stream.peek()?.type === "Bang" /* Bang */) {
1636
+ this.stream.next();
1637
+ this.stream.skipWhitespace();
1638
+ const importantToken = this.stream.next();
1639
+ if (importantToken.type === "Identifier" /* Identifier */ && importantToken.value === "important") {
1640
+ important = true;
1641
+ } else {
1642
+ throw new Error("Expected 'important' after '!'");
1643
+ }
1644
+ }
1645
+ this.stream.skipWhitespace();
1646
+ this.stream.expect("Semicolon" /* Semicolon */);
1647
+ entries.push(new StateEntryNode(nameToken.value, value, important));
1648
+ }
1649
+ return new StateBlockNode(entries);
1650
+ }
1651
+ parseOnBlock() {
1652
+ this.stream.expect("On" /* On */);
1653
+ this.stream.skipWhitespace();
1654
+ const event = this.parseIdentifierPath();
1655
+ this.stream.skipWhitespace();
1656
+ this.stream.expect("LParen" /* LParen */);
1657
+ const args = [];
1658
+ while (true) {
1659
+ this.stream.skipWhitespace();
1660
+ const next = this.stream.peek();
1661
+ if (!next) {
1662
+ throw new Error("Unterminated on() arguments");
1663
+ }
1664
+ if (next.type === "RParen" /* RParen */) {
1665
+ this.stream.next();
1666
+ break;
1667
+ }
1668
+ if (next.type === "Identifier" /* Identifier */) {
1669
+ args.push(this.stream.next().value);
1670
+ this.stream.skipWhitespace();
1671
+ if (this.stream.peek()?.type === "Comma" /* Comma */) {
1672
+ this.stream.next();
1673
+ }
1674
+ continue;
1675
+ }
1676
+ throw new Error(`Unexpected token in on() args: ${next.type}`);
1677
+ }
1678
+ const modifiers = this.parseOnModifiers();
1679
+ const body = this.parseBlock({ allowDeclarations: false });
1680
+ return new OnBlockNode(event, args, body, modifiers);
1681
+ }
1682
+ parseOnModifiers() {
1683
+ const modifiers = [];
1684
+ while (true) {
1685
+ this.stream.skipWhitespace();
1686
+ if (this.stream.peek()?.type !== "Bang" /* Bang */) {
1687
+ break;
1688
+ }
1689
+ this.stream.next();
1690
+ const name = this.stream.expect("Identifier" /* Identifier */).value;
1691
+ modifiers.push(name);
1692
+ }
1693
+ return modifiers;
1694
+ }
1695
+ parseAssignment() {
1696
+ const target = this.parseAssignmentTarget();
1697
+ this.stream.skipWhitespace();
1698
+ this.stream.expect("Equals" /* Equals */);
1699
+ this.stream.skipWhitespace();
1700
+ const value = this.parseExpression();
1701
+ this.consumeStatementTerminator();
1702
+ return new AssignmentNode(target, value);
1703
+ }
1704
+ parseExpression() {
1705
+ return this.parsePipeExpression();
1706
+ }
1707
+ parsePipeExpression() {
1708
+ let expr = this.parseTernaryExpression();
1709
+ while (true) {
1710
+ this.stream.skipWhitespace();
1711
+ if (this.stream.peek()?.type !== "Pipe" /* Pipe */) {
1712
+ break;
1713
+ }
1714
+ this.stream.next();
1715
+ this.stream.skipWhitespace();
1716
+ let awaitStage = false;
1717
+ const next = this.stream.peek();
1718
+ if (this.isAwaitAllowed() && next?.type === "Identifier" /* Identifier */ && next.value === "await") {
1719
+ this.stream.next();
1720
+ this.stream.skipWhitespace();
1721
+ awaitStage = true;
1722
+ }
1723
+ const stage = this.parseCallExpression();
1724
+ const call = this.buildPipeCall(expr, stage);
1725
+ expr = awaitStage ? new AwaitExpression(call) : call;
1726
+ }
1727
+ return expr;
1728
+ }
1729
+ buildPipeCall(input, stage) {
1730
+ if (stage instanceof CallExpression) {
1731
+ return new CallExpression(stage.callee, [input, ...stage.args]);
1732
+ }
1733
+ if (stage instanceof IdentifierExpression || stage instanceof MemberExpression) {
1734
+ return new CallExpression(stage, [input]);
1735
+ }
1736
+ throw new Error("Pipe operator requires a function call");
1737
+ }
1738
+ parseTernaryExpression() {
1739
+ let test = this.parseNullishExpression();
1740
+ this.stream.skipWhitespace();
1741
+ if (this.stream.peek()?.type !== "Question" /* Question */) {
1742
+ return test;
1743
+ }
1744
+ this.stream.next();
1745
+ this.stream.skipWhitespace();
1746
+ const consequent = this.parseExpression();
1747
+ this.stream.skipWhitespace();
1748
+ this.stream.expect("Colon" /* Colon */);
1749
+ this.stream.skipWhitespace();
1750
+ const alternate = this.parseExpression();
1751
+ return new TernaryExpression(test, consequent, alternate);
1752
+ }
1753
+ parseNullishExpression() {
1754
+ let expr = this.parseLogicalOrExpression();
1755
+ while (true) {
1756
+ this.stream.skipWhitespace();
1757
+ if (this.stream.peek()?.type !== "NullishCoalesce" /* NullishCoalesce */) {
1758
+ break;
1759
+ }
1760
+ this.stream.next();
1761
+ this.stream.skipWhitespace();
1762
+ const right = this.parseLogicalOrExpression();
1763
+ expr = new BinaryExpression("??", expr, right);
1764
+ }
1765
+ return expr;
1766
+ }
1767
+ parseLogicalOrExpression() {
1768
+ let left = this.parseLogicalAndExpression();
1769
+ this.stream.skipWhitespace();
1770
+ while (true) {
1771
+ const next = this.stream.peekNonWhitespace(0);
1772
+ if (!next || next.type !== "Or" /* Or */) {
1773
+ break;
1774
+ }
1775
+ this.stream.skipWhitespace();
1776
+ this.stream.next();
1777
+ this.stream.skipWhitespace();
1778
+ const right = this.parseLogicalAndExpression();
1779
+ this.stream.skipWhitespace();
1780
+ left = new BinaryExpression("||", left, right);
1781
+ }
1782
+ return left;
1783
+ }
1784
+ parseLogicalAndExpression() {
1785
+ let left = this.parseEqualityExpression();
1786
+ this.stream.skipWhitespace();
1787
+ while (true) {
1788
+ const next = this.stream.peekNonWhitespace(0);
1789
+ if (!next || next.type !== "And" /* And */) {
1790
+ break;
1791
+ }
1792
+ this.stream.skipWhitespace();
1793
+ this.stream.next();
1794
+ this.stream.skipWhitespace();
1795
+ const right = this.parseEqualityExpression();
1796
+ this.stream.skipWhitespace();
1797
+ left = new BinaryExpression("&&", left, right);
1798
+ }
1799
+ return left;
1800
+ }
1801
+ parseEqualityExpression() {
1802
+ let left = this.parseComparisonExpression();
1803
+ this.stream.skipWhitespace();
1804
+ while (true) {
1805
+ const next = this.stream.peekNonWhitespace(0);
1806
+ if (!next || next.type !== "DoubleEquals" /* DoubleEquals */ && next.type !== "NotEquals" /* NotEquals */ && next.type !== "TripleEquals" /* TripleEquals */ && next.type !== "StrictNotEquals" /* StrictNotEquals */) {
1807
+ break;
1808
+ }
1809
+ this.stream.skipWhitespace();
1810
+ const op = this.stream.next();
1811
+ this.stream.skipWhitespace();
1812
+ const right = this.parseComparisonExpression();
1813
+ this.stream.skipWhitespace();
1814
+ let operator = "==";
1815
+ if (op.type === "NotEquals" /* NotEquals */) {
1816
+ operator = "!=";
1817
+ } else if (op.type === "TripleEquals" /* TripleEquals */) {
1818
+ operator = "===";
1819
+ } else if (op.type === "StrictNotEquals" /* StrictNotEquals */) {
1820
+ operator = "!==";
1821
+ }
1822
+ left = new BinaryExpression(operator, left, right);
1823
+ }
1824
+ return left;
1825
+ }
1826
+ parseComparisonExpression() {
1827
+ let left = this.parseAdditiveExpression();
1828
+ this.stream.skipWhitespace();
1829
+ while (true) {
1830
+ const next = this.stream.peekNonWhitespace(0);
1831
+ if (!next) {
1832
+ break;
1833
+ }
1834
+ if (next.type !== "Less" /* Less */ && next.type !== "Greater" /* Greater */ && next.type !== "LessEqual" /* LessEqual */ && next.type !== "GreaterEqual" /* GreaterEqual */) {
1835
+ break;
1836
+ }
1837
+ this.stream.skipWhitespace();
1838
+ const op = this.stream.next();
1839
+ this.stream.skipWhitespace();
1840
+ const right = this.parseAdditiveExpression();
1841
+ this.stream.skipWhitespace();
1842
+ let operator = "<";
1843
+ if (op.type === "Greater" /* Greater */) {
1844
+ operator = ">";
1845
+ } else if (op.type === "LessEqual" /* LessEqual */) {
1846
+ operator = "<=";
1847
+ } else if (op.type === "GreaterEqual" /* GreaterEqual */) {
1848
+ operator = ">=";
1849
+ }
1850
+ left = new BinaryExpression(operator, left, right);
1851
+ }
1852
+ return left;
1853
+ }
1854
+ parseMultiplicativeExpression() {
1855
+ let left = this.parseUnaryExpression();
1856
+ this.stream.skipWhitespace();
1857
+ while (true) {
1858
+ const next = this.stream.peekNonWhitespace(0);
1859
+ if (!next) {
1860
+ break;
1861
+ }
1862
+ if (next.type !== "Star" /* Star */ && next.type !== "Slash" /* Slash */ && next.type !== "Percent" /* Percent */) {
1863
+ break;
1864
+ }
1865
+ this.stream.skipWhitespace();
1866
+ const op = this.stream.next();
1867
+ this.stream.skipWhitespace();
1868
+ const right = this.parseUnaryExpression();
1869
+ this.stream.skipWhitespace();
1870
+ let operator = "*";
1871
+ if (op.type === "Slash" /* Slash */) {
1872
+ operator = "/";
1873
+ } else if (op.type === "Percent" /* Percent */) {
1874
+ operator = "%";
1875
+ }
1876
+ left = new BinaryExpression(operator, left, right);
1877
+ }
1878
+ return left;
1879
+ }
1880
+ parseAdditiveExpression() {
1881
+ let left = this.parseMultiplicativeExpression();
1882
+ this.stream.skipWhitespace();
1883
+ while (true) {
1884
+ const next = this.stream.peekNonWhitespace(0);
1885
+ if (!next || next.type !== "Plus" /* Plus */ && next.type !== "Minus" /* Minus */) {
1886
+ break;
1887
+ }
1888
+ this.stream.skipWhitespace();
1889
+ const op = this.stream.next();
1890
+ this.stream.skipWhitespace();
1891
+ const right = this.parseMultiplicativeExpression();
1892
+ this.stream.skipWhitespace();
1893
+ left = new BinaryExpression(op.type === "Plus" /* Plus */ ? "+" : "-", left, right);
1894
+ }
1895
+ return left;
1896
+ }
1897
+ parseUnaryExpression() {
1898
+ this.stream.skipWhitespace();
1899
+ const token = this.stream.peek();
1900
+ if (!token) {
1901
+ throw new Error("Expected expression");
1902
+ }
1903
+ if (token.type === "Bang" /* Bang */) {
1904
+ this.stream.next();
1905
+ const argument = this.parseUnaryExpression();
1906
+ return new UnaryExpression("!", argument);
1907
+ }
1908
+ if (token.type === "Minus" /* Minus */) {
1909
+ this.stream.next();
1910
+ const argument = this.parseUnaryExpression();
1911
+ return new UnaryExpression("-", argument);
1912
+ }
1913
+ if (this.isAwaitAllowed() && token.type === "Identifier" /* Identifier */ && token.value === "await") {
1914
+ this.stream.next();
1915
+ const argument = this.parseUnaryExpression();
1916
+ return new AwaitExpression(argument);
1917
+ }
1918
+ return this.parseCallExpression();
1919
+ }
1920
+ parseCallExpression() {
1921
+ let expr = this.parsePrimaryExpression();
1922
+ while (true) {
1923
+ this.stream.skipWhitespace();
1924
+ const next = this.stream.peek();
1925
+ if (!next) {
1926
+ break;
1927
+ }
1928
+ if (next.type === "LParen" /* LParen */) {
1929
+ this.stream.next();
1930
+ const args = [];
1931
+ while (true) {
1932
+ this.stream.skipWhitespace();
1933
+ const argToken = this.stream.peek();
1934
+ if (!argToken) {
1935
+ throw new Error("Unterminated call expression");
1936
+ }
1937
+ if (argToken.type === "RParen" /* RParen */) {
1938
+ this.stream.next();
1939
+ break;
1940
+ }
1941
+ args.push(this.parseExpression());
1942
+ this.stream.skipWhitespace();
1943
+ if (this.stream.peek()?.type === "Comma" /* Comma */) {
1944
+ this.stream.next();
1945
+ continue;
1946
+ }
1947
+ if (this.stream.peek()?.type === "RParen" /* RParen */) {
1948
+ this.stream.next();
1949
+ break;
1950
+ }
1951
+ throw new Error("Expected ',' or ')' in call arguments");
1952
+ }
1953
+ expr = new CallExpression(expr, args);
1954
+ continue;
1955
+ }
1956
+ if (next.type === "OptionalChain" /* OptionalChain */) {
1957
+ this.stream.next();
1958
+ this.stream.skipWhitespace();
1959
+ const chained = this.stream.peek();
1960
+ if (!chained) {
1961
+ throw new Error("Expected property or call after ?.");
1962
+ }
1963
+ if (chained.type === "LParen" /* LParen */) {
1964
+ this.stream.next();
1965
+ const args = [];
1966
+ while (true) {
1967
+ this.stream.skipWhitespace();
1968
+ const argToken = this.stream.peek();
1969
+ if (!argToken) {
1970
+ throw new Error("Unterminated call expression");
1971
+ }
1972
+ if (argToken.type === "RParen" /* RParen */) {
1973
+ this.stream.next();
1974
+ break;
1975
+ }
1976
+ args.push(this.parseExpression());
1977
+ this.stream.skipWhitespace();
1978
+ if (this.stream.peek()?.type === "Comma" /* Comma */) {
1979
+ this.stream.next();
1980
+ continue;
1981
+ }
1982
+ if (this.stream.peek()?.type === "RParen" /* RParen */) {
1983
+ this.stream.next();
1984
+ break;
1985
+ }
1986
+ throw new Error("Expected ',' or ')' in call arguments");
1987
+ }
1988
+ expr = new CallExpression(expr, args);
1989
+ continue;
1990
+ }
1991
+ if (chained.type === "Identifier" /* Identifier */) {
1992
+ const name = this.stream.next();
1993
+ expr = new MemberExpression(expr, name.value, true);
1994
+ continue;
1995
+ }
1996
+ throw new Error("Expected property or call after ?.");
1997
+ }
1998
+ if (next.type === "Dot" /* Dot */) {
1999
+ this.stream.next();
2000
+ const name = this.stream.expect("Identifier" /* Identifier */);
2001
+ expr = new MemberExpression(expr, name.value);
2002
+ continue;
2003
+ }
2004
+ if (next.type === "LBracket" /* LBracket */) {
2005
+ this.stream.next();
2006
+ this.stream.skipWhitespace();
2007
+ const index = this.parseExpression();
2008
+ this.stream.skipWhitespace();
2009
+ this.stream.expect("RBracket" /* RBracket */);
2010
+ expr = new IndexExpression(expr, index);
2011
+ continue;
2012
+ }
2013
+ break;
2014
+ }
2015
+ return expr;
2016
+ }
2017
+ parsePrimaryExpression() {
2018
+ this.stream.skipWhitespace();
2019
+ const token = this.stream.peek();
2020
+ if (!token) {
2021
+ throw new Error("Expected expression");
2022
+ }
2023
+ if (token.type === "At" /* At */ || token.type === "Dollar" /* Dollar */) {
2024
+ const kind = token.type === "At" /* At */ ? "attr" : "style";
2025
+ this.stream.next();
2026
+ const name = this.stream.expect("Identifier" /* Identifier */);
2027
+ return new DirectiveExpression(kind, name.value);
2028
+ }
2029
+ if (token.type === "Question" /* Question */) {
2030
+ return this.parseQueryExpression();
2031
+ }
2032
+ if (token.type === "LBracket" /* LBracket */) {
2033
+ return this.parseArrayExpression();
2034
+ }
2035
+ if (token.type === "LBrace" /* LBrace */) {
2036
+ return this.parseObjectExpression();
2037
+ }
2038
+ if (token.type === "LParen" /* LParen */) {
2039
+ if (this.isArrowFunctionStart()) {
2040
+ return this.parseArrowFunctionExpression();
2041
+ }
2042
+ this.stream.next();
2043
+ const value = this.parseExpression();
2044
+ this.stream.skipWhitespace();
2045
+ this.stream.expect("RParen" /* RParen */);
2046
+ return value;
2047
+ }
2048
+ if (token.type === "Identifier" /* Identifier */) {
2049
+ if (this.isAsyncToken(token) && this.isAsyncArrowFunctionStart()) {
2050
+ this.stream.next();
2051
+ this.stream.skipWhitespace();
2052
+ return this.parseArrowFunctionExpression(true);
2053
+ }
2054
+ return new IdentifierExpression(this.stream.next().value);
2055
+ }
2056
+ if (token.type === "Boolean" /* Boolean */) {
2057
+ return new LiteralExpression(this.stream.next().value === "true");
2058
+ }
2059
+ if (token.type === "Null" /* Null */) {
2060
+ this.stream.next();
2061
+ return new LiteralExpression(null);
2062
+ }
2063
+ if (token.type === "Number" /* Number */) {
2064
+ return new LiteralExpression(Number(this.stream.next().value));
2065
+ }
2066
+ if (token.type === "String" /* String */) {
2067
+ return new LiteralExpression(this.stream.next().value);
2068
+ }
2069
+ if (token.type === "Template" /* Template */) {
2070
+ return this.parseTemplateExpression();
2071
+ }
2072
+ throw new Error(`Unsupported expression token ${token.type}`);
2073
+ }
2074
+ parseArrayExpression() {
2075
+ this.stream.expect("LBracket" /* LBracket */);
2076
+ const elements = [];
2077
+ while (true) {
2078
+ this.stream.skipWhitespace();
2079
+ const next = this.stream.peek();
2080
+ if (!next) {
2081
+ throw new Error("Unterminated array literal");
2082
+ }
2083
+ if (next.type === "RBracket" /* RBracket */) {
2084
+ this.stream.next();
2085
+ break;
2086
+ }
2087
+ if (next.type === "Ellipsis" /* Ellipsis */) {
2088
+ this.stream.next();
2089
+ this.stream.skipWhitespace();
2090
+ const value = this.parseExpression();
2091
+ elements.push(new SpreadElement(value));
2092
+ } else {
2093
+ elements.push(this.parseExpression());
2094
+ }
2095
+ this.stream.skipWhitespace();
2096
+ if (this.stream.peek()?.type === "Comma" /* Comma */) {
2097
+ this.stream.next();
2098
+ this.stream.skipWhitespace();
2099
+ if (this.stream.peek()?.type === "RBracket" /* RBracket */) {
2100
+ this.stream.next();
2101
+ break;
2102
+ }
2103
+ continue;
2104
+ }
2105
+ if (this.stream.peek()?.type === "RBracket" /* RBracket */) {
2106
+ this.stream.next();
2107
+ break;
2108
+ }
2109
+ throw new Error("Expected ',' or ']' in array literal");
2110
+ }
2111
+ return new ArrayExpression(elements);
2112
+ }
2113
+ parseTemplateExpression() {
2114
+ const parts = [];
2115
+ while (true) {
2116
+ const token = this.stream.peek();
2117
+ if (!token) {
2118
+ throw new Error("Unterminated template literal");
2119
+ }
2120
+ if (token.type !== "Template" /* Template */) {
2121
+ throw new Error("Expected template literal");
2122
+ }
2123
+ const literal = this.stream.next().value;
2124
+ if (literal) {
2125
+ parts.push(new LiteralExpression(literal));
2126
+ }
2127
+ const next = this.stream.peek();
2128
+ if (!next || next.type !== "Dollar" /* Dollar */) {
2129
+ break;
2130
+ }
2131
+ this.stream.next();
2132
+ this.stream.expect("LBrace" /* LBrace */);
2133
+ this.stream.skipWhitespace();
2134
+ const expr = this.parseExpression();
2135
+ this.stream.skipWhitespace();
2136
+ this.stream.expect("RBrace" /* RBrace */);
2137
+ parts.push(expr);
2138
+ }
2139
+ return new TemplateExpression(parts);
2140
+ }
2141
+ parseObjectExpression() {
2142
+ this.stream.expect("LBrace" /* LBrace */);
2143
+ const entries = [];
2144
+ while (true) {
2145
+ this.stream.skipWhitespace();
2146
+ const next = this.stream.peek();
2147
+ if (!next) {
2148
+ throw new Error("Unterminated object literal");
2149
+ }
2150
+ if (next.type === "RBrace" /* RBrace */) {
2151
+ this.stream.next();
2152
+ break;
2153
+ }
2154
+ let value;
2155
+ let entry;
2156
+ if (next.type === "Ellipsis" /* Ellipsis */) {
2157
+ this.stream.next();
2158
+ this.stream.skipWhitespace();
2159
+ entry = { spread: this.parseExpression() };
2160
+ } else if (next.type === "LBracket" /* LBracket */) {
2161
+ this.stream.next();
2162
+ this.stream.skipWhitespace();
2163
+ const keyExpr = this.parseExpression();
2164
+ this.stream.skipWhitespace();
2165
+ this.stream.expect("RBracket" /* RBracket */);
2166
+ this.stream.skipWhitespace();
2167
+ this.stream.expect("Colon" /* Colon */);
2168
+ this.stream.skipWhitespace();
2169
+ value = this.parseExpression();
2170
+ entry = { keyExpr, value, computed: true };
2171
+ } else if (next.type === "Identifier" /* Identifier */) {
2172
+ const name = this.stream.next().value;
2173
+ this.stream.skipWhitespace();
2174
+ if (this.stream.peek()?.type === "Colon" /* Colon */) {
2175
+ this.stream.next();
2176
+ this.stream.skipWhitespace();
2177
+ value = this.parseExpression();
2178
+ } else {
2179
+ value = new IdentifierExpression(name);
2180
+ }
2181
+ entry = { key: name, value };
2182
+ } else if (next.type === "String" /* String */) {
2183
+ const key = this.stream.next().value;
2184
+ this.stream.skipWhitespace();
2185
+ this.stream.expect("Colon" /* Colon */);
2186
+ this.stream.skipWhitespace();
2187
+ value = this.parseExpression();
2188
+ entry = { key, value };
2189
+ } else {
2190
+ throw new Error(`Unexpected token in object literal: ${next.type}`);
2191
+ }
2192
+ if (!entry) {
2193
+ throw new Error("Invalid object literal entry");
2194
+ }
2195
+ entries.push(entry);
2196
+ this.stream.skipWhitespace();
2197
+ if (this.stream.peek()?.type === "Comma" /* Comma */) {
2198
+ this.stream.next();
2199
+ this.stream.skipWhitespace();
2200
+ if (this.stream.peek()?.type === "RBrace" /* RBrace */) {
2201
+ this.stream.next();
2202
+ break;
2203
+ }
2204
+ continue;
2205
+ }
2206
+ if (this.stream.peek()?.type === "RBrace" /* RBrace */) {
2207
+ this.stream.next();
2208
+ break;
2209
+ }
2210
+ throw new Error("Expected ',' or '}' in object literal");
2211
+ }
2212
+ return new ObjectExpression(entries);
2213
+ }
2214
+ consumeStatementTerminator() {
2215
+ this.stream.skipWhitespace();
2216
+ const next = this.stream.peek();
2217
+ if (next?.type === "Semicolon" /* Semicolon */) {
2218
+ this.stream.next();
2219
+ return;
2220
+ }
2221
+ if (this.allowImplicitSemicolon && next?.type === "RBrace" /* RBrace */) {
2222
+ return;
2223
+ }
2224
+ this.stream.expect("Semicolon" /* Semicolon */);
2225
+ }
2226
+ parseFunctionBlockWithAwait(allowAwait) {
2227
+ this.stream.expect("LBrace" /* LBrace */);
2228
+ const statements = [];
2229
+ this.awaitStack.push(allowAwait);
2230
+ try {
2231
+ while (true) {
2232
+ this.stream.skipWhitespace();
2233
+ const next = this.stream.peek();
2234
+ if (!next) {
2235
+ throw new Error("Unterminated function block");
2236
+ }
2237
+ if (next.type === "RBrace" /* RBrace */) {
2238
+ this.stream.next();
2239
+ break;
2240
+ }
2241
+ statements.push(this.parseStatement({ allowBlocks: false, allowReturn: true }));
2242
+ }
2243
+ } finally {
2244
+ this.awaitStack.pop();
2245
+ }
2246
+ return new BlockNode(statements);
2247
+ }
2248
+ isAsyncToken(token) {
2249
+ return token?.type === "Identifier" /* Identifier */ && token.value === "async";
2250
+ }
2251
+ isAwaitAllowed() {
2252
+ if (this.awaitStack.length === 0) {
2253
+ return false;
2254
+ }
2255
+ return this.awaitStack[this.awaitStack.length - 1] === true;
2256
+ }
2257
+ parseArrowExpressionBody(allowAwait) {
2258
+ this.awaitStack.push(allowAwait);
2259
+ try {
2260
+ const expression = this.parseExpression();
2261
+ return new BlockNode([new ReturnNode(expression)]);
2262
+ } finally {
2263
+ this.awaitStack.pop();
2264
+ }
2265
+ }
2266
+ parseAssignmentTarget() {
2267
+ const token = this.stream.peek();
2268
+ if (!token) {
2269
+ throw new Error("Expected assignment target");
2270
+ }
2271
+ if (token.type === "At" /* At */ || token.type === "Dollar" /* Dollar */) {
2272
+ const kind = token.type === "At" /* At */ ? "attr" : "style";
2273
+ this.stream.next();
2274
+ const name = this.stream.expect("Identifier" /* Identifier */);
2275
+ return new DirectiveExpression(kind, name.value);
2276
+ }
2277
+ if (token.type === "LBracket" /* LBracket */) {
2278
+ return this.parseArrayPattern();
2279
+ }
2280
+ if (token.type === "LBrace" /* LBrace */) {
2281
+ return this.parseObjectPattern();
2282
+ }
2283
+ if (token.type === "Identifier" /* Identifier */) {
2284
+ return new IdentifierExpression(this.parseIdentifierPath());
2285
+ }
2286
+ throw new Error(`Invalid assignment target ${token.type}`);
2287
+ }
2288
+ parseArrayPattern() {
2289
+ this.stream.expect("LBracket" /* LBracket */);
2290
+ const elements = [];
2291
+ let sawRest = false;
2292
+ while (true) {
2293
+ this.stream.skipWhitespace();
2294
+ const next = this.stream.peek();
2295
+ if (!next) {
2296
+ throw new Error("Unterminated array pattern");
2297
+ }
2298
+ if (next.type === "RBracket" /* RBracket */) {
2299
+ this.stream.next();
2300
+ break;
2301
+ }
2302
+ if (next.type === "Comma" /* Comma */) {
2303
+ this.stream.next();
2304
+ elements.push(null);
2305
+ continue;
2306
+ }
2307
+ if (next.type === "Ellipsis" /* Ellipsis */) {
2308
+ if (sawRest) {
2309
+ throw new Error("Array patterns can only include one rest element");
2310
+ }
2311
+ this.stream.next();
2312
+ this.stream.skipWhitespace();
2313
+ const name = this.stream.expect("Identifier" /* Identifier */);
2314
+ elements.push(new RestElement(new IdentifierExpression(name.value)));
2315
+ sawRest = true;
2316
+ } else if (next.type === "LBracket" /* LBracket */) {
2317
+ elements.push(this.parseArrayPattern());
2318
+ } else if (next.type === "LBrace" /* LBrace */) {
2319
+ elements.push(this.parseObjectPattern());
2320
+ } else if (next.type === "Identifier" /* Identifier */) {
2321
+ elements.push(new IdentifierExpression(this.parseIdentifierPath()));
2322
+ } else {
2323
+ throw new Error(`Unexpected token in array pattern: ${next.type}`);
2324
+ }
2325
+ this.stream.skipWhitespace();
2326
+ if (this.stream.peek()?.type === "Comma" /* Comma */) {
2327
+ this.stream.next();
2328
+ continue;
2329
+ }
2330
+ if (this.stream.peek()?.type === "RBracket" /* RBracket */) {
2331
+ this.stream.next();
2332
+ break;
2333
+ }
2334
+ throw new Error("Expected ',' or ']' in array pattern");
2335
+ }
2336
+ if (sawRest) {
2337
+ const last = elements[elements.length - 1];
2338
+ if (!(last instanceof RestElement)) {
2339
+ throw new Error("Rest element must be last in array pattern");
2340
+ }
2341
+ }
2342
+ return new ArrayPattern(elements);
2343
+ }
2344
+ parseObjectPattern() {
2345
+ this.stream.expect("LBrace" /* LBrace */);
2346
+ const entries = [];
2347
+ let rest;
2348
+ while (true) {
2349
+ this.stream.skipWhitespace();
2350
+ const next = this.stream.peek();
2351
+ if (!next) {
2352
+ throw new Error("Unterminated object pattern");
2353
+ }
2354
+ if (next.type === "RBrace" /* RBrace */) {
2355
+ this.stream.next();
2356
+ break;
2357
+ }
2358
+ if (next.type === "Ellipsis" /* Ellipsis */) {
2359
+ if (rest) {
2360
+ throw new Error("Object patterns can only include one rest element");
2361
+ }
2362
+ this.stream.next();
2363
+ this.stream.skipWhitespace();
2364
+ const name = this.stream.expect("Identifier" /* Identifier */);
2365
+ rest = new IdentifierExpression(name.value);
2366
+ this.stream.skipWhitespace();
2367
+ if (this.stream.peek()?.type === "Comma" /* Comma */) {
2368
+ this.stream.next();
2369
+ this.stream.skipWhitespace();
2370
+ }
2371
+ if (this.stream.peek()?.type !== "RBrace" /* RBrace */) {
2372
+ throw new Error("Rest element must be last in object pattern");
2373
+ }
2374
+ this.stream.next();
2375
+ break;
2376
+ } else if (next.type === "Identifier" /* Identifier */ || next.type === "String" /* String */) {
2377
+ const keyToken = this.stream.next();
2378
+ const key = keyToken.value;
2379
+ this.stream.skipWhitespace();
2380
+ let target;
2381
+ if (this.stream.peek()?.type === "Colon" /* Colon */) {
2382
+ this.stream.next();
2383
+ this.stream.skipWhitespace();
2384
+ const valueToken = this.stream.peek();
2385
+ if (!valueToken) {
2386
+ throw new Error("Expected object pattern target");
2387
+ }
2388
+ if (valueToken.type === "LBracket" /* LBracket */) {
2389
+ target = this.parseArrayPattern();
2390
+ } else if (valueToken.type === "LBrace" /* LBrace */) {
2391
+ target = this.parseObjectPattern();
2392
+ } else if (valueToken.type === "Identifier" /* Identifier */) {
2393
+ target = new IdentifierExpression(this.parseIdentifierPath());
2394
+ } else {
2395
+ throw new Error(`Unexpected token in object pattern: ${valueToken.type}`);
2396
+ }
2397
+ } else {
2398
+ target = new IdentifierExpression(key);
2399
+ }
2400
+ entries.push({ key, target });
2401
+ } else {
2402
+ throw new Error(`Unexpected token in object pattern: ${next.type}`);
2403
+ }
2404
+ this.stream.skipWhitespace();
2405
+ if (this.stream.peek()?.type === "Comma" /* Comma */) {
2406
+ this.stream.next();
2407
+ this.stream.skipWhitespace();
2408
+ if (this.stream.peek()?.type === "RBrace" /* RBrace */) {
2409
+ this.stream.next();
2410
+ break;
2411
+ }
2412
+ continue;
2413
+ }
2414
+ if (this.stream.peek()?.type === "RBrace" /* RBrace */) {
2415
+ this.stream.next();
2416
+ break;
2417
+ }
2418
+ throw new Error("Expected ',' or '}' in object pattern");
2419
+ }
2420
+ const patternEntries = rest ? [...entries, { rest }] : entries;
2421
+ if (rest && entries.length === 0) {
2422
+ return new ObjectPattern([{ rest }]);
2423
+ }
2424
+ return new ObjectPattern(patternEntries);
2425
+ }
2426
+ parseDeclaration() {
2427
+ const target = this.parseDeclarationTarget();
2428
+ this.stream.skipWhitespace();
2429
+ const operator = this.parseDeclarationOperator();
2430
+ this.stream.skipWhitespace();
2431
+ const value = this.parseExpression();
2432
+ const { flags, flagArgs } = this.parseFlags();
2433
+ this.stream.skipWhitespace();
2434
+ this.stream.expect("Semicolon" /* Semicolon */);
2435
+ return new DeclarationNode(target, operator, value, flags, flagArgs);
2436
+ }
2437
+ parseDeclarationTarget() {
2438
+ const token = this.stream.peek();
2439
+ if (!token) {
2440
+ throw new Error("Expected declaration target");
2441
+ }
2442
+ if (token.type === "At" /* At */ || token.type === "Dollar" /* Dollar */) {
2443
+ const kind = token.type === "At" /* At */ ? "attr" : "style";
2444
+ this.stream.next();
2445
+ const name = this.stream.expect("Identifier" /* Identifier */);
2446
+ return new DirectiveExpression(kind, name.value);
2447
+ }
2448
+ if (token.type === "Identifier" /* Identifier */) {
2449
+ return new IdentifierExpression(this.stream.next().value);
2450
+ }
2451
+ throw new Error(`Invalid declaration target ${token.type}`);
2452
+ }
2453
+ parseDeclarationOperator() {
2454
+ this.stream.expect("Colon" /* Colon */);
2455
+ const next = this.stream.peek();
2456
+ if (!next) {
2457
+ return ":";
2458
+ }
2459
+ if (next.type === "Equals" /* Equals */) {
2460
+ this.stream.next();
2461
+ return ":=";
2462
+ }
2463
+ if (next.type === "Less" /* Less */) {
2464
+ this.stream.next();
2465
+ return ":<";
2466
+ }
2467
+ if (next.type === "Greater" /* Greater */) {
2468
+ this.stream.next();
2469
+ return ":>";
2470
+ }
2471
+ return ":";
2472
+ }
2473
+ parseFlags() {
2474
+ const flags = {};
2475
+ const flagArgs = {};
2476
+ while (true) {
2477
+ this.stream.skipWhitespace();
2478
+ if (this.stream.peek()?.type !== "Bang" /* Bang */) {
2479
+ break;
2480
+ }
2481
+ this.stream.next();
2482
+ const name = this.stream.expect("Identifier" /* Identifier */).value;
2483
+ if (name === "important") {
2484
+ flags.important = true;
2485
+ } else if (name === "trusted") {
2486
+ flags.trusted = true;
2487
+ } else if (name === "debounce") {
2488
+ flags.debounce = true;
2489
+ if (this.stream.peek()?.type === "LParen" /* LParen */) {
2490
+ this.stream.next();
2491
+ this.stream.skipWhitespace();
2492
+ const numberToken = this.stream.expect("Number" /* Number */);
2493
+ flagArgs.debounce = Number(numberToken.value);
2494
+ this.stream.skipWhitespace();
2495
+ this.stream.expect("RParen" /* RParen */);
2496
+ } else {
2497
+ flagArgs.debounce = 200;
2498
+ }
2499
+ } else if (this.customFlags.has(name)) {
2500
+ flags[name] = true;
2501
+ const customArg = this.parseCustomFlagArg();
2502
+ if (customArg !== void 0) {
2503
+ flagArgs[name] = customArg;
2504
+ }
2505
+ } else {
2506
+ throw new Error(`Unknown flag ${name}`);
2507
+ }
2508
+ }
2509
+ return { flags, flagArgs };
2510
+ }
2511
+ parseCustomFlagArg() {
2512
+ if (this.stream.peek()?.type !== "LParen" /* LParen */) {
2513
+ return void 0;
2514
+ }
2515
+ this.stream.next();
2516
+ this.stream.skipWhitespace();
2517
+ const token = this.stream.peek();
2518
+ if (!token) {
2519
+ throw new Error("Unterminated flag arguments");
2520
+ }
2521
+ let value;
2522
+ if (token.type === "Number" /* Number */) {
2523
+ value = Number(this.stream.next().value);
2524
+ } else if (token.type === "String" /* String */) {
2525
+ value = this.stream.next().value;
2526
+ } else if (token.type === "Boolean" /* Boolean */) {
2527
+ value = this.stream.next().value === "true";
2528
+ } else if (token.type === "Identifier" /* Identifier */) {
2529
+ value = this.stream.next().value;
2530
+ } else {
2531
+ throw new Error(`Unsupported flag argument ${token.type}`);
2532
+ }
2533
+ this.stream.skipWhitespace();
2534
+ this.stream.expect("RParen" /* RParen */);
2535
+ return value;
2536
+ }
2537
+ isDeclarationStart() {
2538
+ const first = this.stream.peekNonWhitespace(0);
2539
+ if (!first) {
2540
+ return false;
2541
+ }
2542
+ if (first.type === "Identifier" /* Identifier */) {
2543
+ const second = this.stream.peekNonWhitespace(1);
2544
+ return second?.type === "Colon" /* Colon */;
2545
+ }
2546
+ if (first.type === "At" /* At */ || first.type === "Dollar" /* Dollar */) {
2547
+ const second = this.stream.peekNonWhitespace(1);
2548
+ const third = this.stream.peekNonWhitespace(2);
2549
+ return second?.type === "Identifier" /* Identifier */ && third?.type === "Colon" /* Colon */;
2550
+ }
2551
+ return false;
2552
+ }
2553
+ isAssignmentStart() {
2554
+ const first = this.stream.peekNonWhitespace(0);
2555
+ if (!first) {
2556
+ return false;
2557
+ }
2558
+ if (first.type === "Identifier" /* Identifier */) {
2559
+ let index = 1;
2560
+ while (this.stream.peekNonWhitespace(index)?.type === "Dot" /* Dot */ && this.stream.peekNonWhitespace(index + 1)?.type === "Identifier" /* Identifier */) {
2561
+ index += 2;
2562
+ }
2563
+ return this.stream.peekNonWhitespace(index)?.type === "Equals" /* Equals */;
2564
+ }
2565
+ if (first.type === "At" /* At */ || first.type === "Dollar" /* Dollar */) {
2566
+ const second = this.stream.peekNonWhitespace(1);
2567
+ const third = this.stream.peekNonWhitespace(2);
2568
+ return second?.type === "Identifier" /* Identifier */ && third?.type === "Equals" /* Equals */;
2569
+ }
2570
+ if (first.type === "LBrace" /* LBrace */ || first.type === "LBracket" /* LBracket */) {
2571
+ const stack = [];
2572
+ let index = 0;
2573
+ while (true) {
2574
+ const token = this.stream.peekNonWhitespace(index);
2575
+ if (!token) {
2576
+ return false;
2577
+ }
2578
+ if (token.type === "LBrace" /* LBrace */ || token.type === "LBracket" /* LBracket */) {
2579
+ stack.push(token.type);
2580
+ } else if (token.type === "RBrace" /* RBrace */ || token.type === "RBracket" /* RBracket */) {
2581
+ stack.pop();
2582
+ if (stack.length === 0) {
2583
+ return this.stream.peekNonWhitespace(index + 1)?.type === "Equals" /* Equals */;
2584
+ }
2585
+ }
2586
+ index += 1;
2587
+ }
2588
+ }
2589
+ return false;
2590
+ }
2591
+ isCallStart() {
2592
+ const first = this.stream.peekNonWhitespace(0);
2593
+ if (!first || first.type !== "Identifier" /* Identifier */) {
2594
+ return false;
2595
+ }
2596
+ let index = 1;
2597
+ while (this.stream.peekNonWhitespace(index)?.type === "Dot" /* Dot */ && this.stream.peekNonWhitespace(index + 1)?.type === "Identifier" /* Identifier */) {
2598
+ index += 2;
2599
+ }
2600
+ return this.stream.peekNonWhitespace(index)?.type === "LParen" /* LParen */;
2601
+ }
2602
+ isExpressionStatementStart() {
2603
+ const first = this.stream.peekNonWhitespace(0);
2604
+ if (!first) {
2605
+ return false;
2606
+ }
2607
+ if (first.type === "Identifier" /* Identifier */) {
2608
+ return true;
2609
+ }
2610
+ return first.type === "Number" /* Number */ || first.type === "String" /* String */ || first.type === "Boolean" /* Boolean */ || first.type === "Null" /* Null */ || first.type === "LParen" /* LParen */ || first.type === "LBracket" /* LBracket */ || first.type === "LBrace" /* LBrace */ || first.type === "At" /* At */ || first.type === "Dollar" /* Dollar */ || first.type === "Question" /* Question */ || first.type === "Bang" /* Bang */ || first.type === "Minus" /* Minus */;
2611
+ }
2612
+ isFunctionDeclarationStart() {
2613
+ const first = this.stream.peekNonWhitespace(0);
2614
+ if (!first) {
2615
+ return false;
2616
+ }
2617
+ let index = 0;
2618
+ if (this.isAsyncToken(first)) {
2619
+ const next = this.stream.peekNonWhitespace(1);
2620
+ if (!next || next.type !== "Identifier" /* Identifier */) {
2621
+ return false;
2622
+ }
2623
+ index = 1;
2624
+ } else if (first.type !== "Identifier" /* Identifier */) {
2625
+ return false;
2626
+ }
2627
+ index += 1;
2628
+ if (this.stream.peekNonWhitespace(index)?.type !== "LParen" /* LParen */) {
2629
+ return false;
2630
+ }
2631
+ index += 1;
2632
+ let depth = 1;
2633
+ while (true) {
2634
+ const token = this.stream.peekNonWhitespace(index);
2635
+ if (!token) {
2636
+ return false;
2637
+ }
2638
+ if (token.type === "LParen" /* LParen */) {
2639
+ depth += 1;
2640
+ } else if (token.type === "RParen" /* RParen */) {
2641
+ depth -= 1;
2642
+ if (depth === 0) {
2643
+ index += 1;
2644
+ break;
2645
+ }
2646
+ }
2647
+ index += 1;
2648
+ }
2649
+ return this.stream.peekNonWhitespace(index)?.type === "LBrace" /* LBrace */;
2650
+ }
2651
+ isArrowFunctionStart() {
2652
+ const first = this.stream.peekNonWhitespace(0);
2653
+ if (!first || first.type !== "LParen" /* LParen */) {
2654
+ return false;
2655
+ }
2656
+ let index = 1;
2657
+ let depth = 1;
2658
+ while (true) {
2659
+ const token = this.stream.peekNonWhitespace(index);
2660
+ if (!token) {
2661
+ return false;
2662
+ }
2663
+ if (token.type === "LParen" /* LParen */) {
2664
+ depth += 1;
2665
+ } else if (token.type === "RParen" /* RParen */) {
2666
+ depth -= 1;
2667
+ if (depth === 0) {
2668
+ index += 1;
2669
+ break;
2670
+ }
2671
+ }
2672
+ index += 1;
2673
+ }
2674
+ return this.stream.peekNonWhitespace(index)?.type === "Arrow" /* Arrow */;
2675
+ }
2676
+ isAsyncArrowFunctionStart() {
2677
+ const first = this.stream.peekNonWhitespace(0);
2678
+ if (!this.isAsyncToken(first)) {
2679
+ return false;
2680
+ }
2681
+ if (this.stream.peekNonWhitespace(1)?.type !== "LParen" /* LParen */) {
2682
+ return false;
2683
+ }
2684
+ let index = 2;
2685
+ let depth = 1;
2686
+ while (true) {
2687
+ const token = this.stream.peekNonWhitespace(index);
2688
+ if (!token) {
2689
+ return false;
2690
+ }
2691
+ if (token.type === "LParen" /* LParen */) {
2692
+ depth += 1;
2693
+ } else if (token.type === "RParen" /* RParen */) {
2694
+ depth -= 1;
2695
+ if (depth === 0) {
2696
+ index += 1;
2697
+ break;
2698
+ }
2699
+ }
2700
+ index += 1;
2701
+ }
2702
+ return this.stream.peekNonWhitespace(index)?.type === "Arrow" /* Arrow */;
2703
+ }
2704
+ isFunctionExpressionAssignmentStart() {
2705
+ const first = this.stream.peekNonWhitespace(0);
2706
+ if (!first || first.type !== "Identifier" /* Identifier */) {
2707
+ return false;
2708
+ }
2709
+ if (this.stream.peekNonWhitespace(1)?.type !== "Equals" /* Equals */) {
2710
+ return false;
2711
+ }
2712
+ let index = 2;
2713
+ if (this.isAsyncToken(this.stream.peekNonWhitespace(index))) {
2714
+ index += 1;
2715
+ }
2716
+ if (this.stream.peekNonWhitespace(index)?.type !== "LParen" /* LParen */) {
2717
+ return false;
2718
+ }
2719
+ index += 1;
2720
+ let depth = 1;
2721
+ while (true) {
2722
+ const token = this.stream.peekNonWhitespace(index);
2723
+ if (!token) {
2724
+ return false;
2725
+ }
2726
+ if (token.type === "LParen" /* LParen */) {
2727
+ depth += 1;
2728
+ } else if (token.type === "RParen" /* RParen */) {
2729
+ depth -= 1;
2730
+ if (depth === 0) {
2731
+ index += 1;
2732
+ break;
2733
+ }
2734
+ }
2735
+ index += 1;
2736
+ }
2737
+ return this.stream.peekNonWhitespace(index)?.type === "Arrow" /* Arrow */;
2738
+ }
2739
+ parseExpressionStatement() {
2740
+ const expr = this.parseExpression();
2741
+ this.consumeStatementTerminator();
2742
+ return expr;
2743
+ }
2744
+ parseIfBlock() {
2745
+ this.stream.expect("If" /* If */);
2746
+ this.stream.skipWhitespace();
2747
+ this.stream.expect("LParen" /* LParen */);
2748
+ this.stream.skipWhitespace();
2749
+ const test = this.parseExpression();
2750
+ this.stream.skipWhitespace();
2751
+ this.stream.expect("RParen" /* RParen */);
2752
+ const consequent = this.parseBlock({ allowDeclarations: false });
2753
+ this.stream.skipWhitespace();
2754
+ let alternate;
2755
+ if (this.stream.peek()?.type === "Else" /* Else */) {
2756
+ this.stream.next();
2757
+ this.stream.skipWhitespace();
2758
+ if (this.stream.peek()?.type === "If" /* If */) {
2759
+ const nested = this.parseIfBlock();
2760
+ alternate = new BlockNode([nested]);
2761
+ } else {
2762
+ alternate = this.parseBlock({ allowDeclarations: false });
2763
+ }
2764
+ }
2765
+ return new IfNode(test, consequent, alternate);
2766
+ }
2767
+ parseWhileBlock() {
2768
+ this.stream.expect("While" /* While */);
2769
+ this.stream.skipWhitespace();
2770
+ this.stream.expect("LParen" /* LParen */);
2771
+ this.stream.skipWhitespace();
2772
+ const test = this.parseExpression();
2773
+ this.stream.skipWhitespace();
2774
+ this.stream.expect("RParen" /* RParen */);
2775
+ const body = this.parseBlock({ allowDeclarations: false });
2776
+ return new WhileNode(test, body);
2777
+ }
2778
+ parseForBlock() {
2779
+ this.stream.expect("For" /* For */);
2780
+ this.stream.skipWhitespace();
2781
+ this.stream.expect("LParen" /* LParen */);
2782
+ this.stream.skipWhitespace();
2783
+ let init;
2784
+ if (this.stream.peek()?.type !== "Semicolon" /* Semicolon */) {
2785
+ init = this.parseForClause();
2786
+ }
2787
+ this.stream.skipWhitespace();
2788
+ this.stream.expect("Semicolon" /* Semicolon */);
2789
+ this.stream.skipWhitespace();
2790
+ let test;
2791
+ if (this.stream.peek()?.type !== "Semicolon" /* Semicolon */) {
2792
+ test = this.parseExpression();
2793
+ }
2794
+ this.stream.skipWhitespace();
2795
+ this.stream.expect("Semicolon" /* Semicolon */);
2796
+ this.stream.skipWhitespace();
2797
+ let update;
2798
+ if (this.stream.peek()?.type !== "RParen" /* RParen */) {
2799
+ update = this.parseForClause();
2800
+ }
2801
+ this.stream.skipWhitespace();
2802
+ this.stream.expect("RParen" /* RParen */);
2803
+ const body = this.parseBlock({ allowDeclarations: false });
2804
+ return new ForNode(init, test, update, body);
2805
+ }
2806
+ parseForClause() {
2807
+ if (this.isAssignmentStart()) {
2808
+ return this.parseAssignmentExpression();
2809
+ }
2810
+ return this.parseExpression();
2811
+ }
2812
+ parseAssignmentExpression() {
2813
+ const target = this.parseAssignmentTarget();
2814
+ this.stream.skipWhitespace();
2815
+ this.stream.expect("Equals" /* Equals */);
2816
+ this.stream.skipWhitespace();
2817
+ const value = this.parseExpression();
2818
+ return new AssignmentNode(target, value);
2819
+ }
2820
+ parseTryBlock() {
2821
+ this.stream.expect("Try" /* Try */);
2822
+ const body = this.parseBlock({ allowDeclarations: false });
2823
+ this.stream.skipWhitespace();
2824
+ this.stream.expect("Catch" /* Catch */);
2825
+ this.stream.skipWhitespace();
2826
+ this.stream.expect("LParen" /* LParen */);
2827
+ this.stream.skipWhitespace();
2828
+ const errorName = this.stream.expect("Identifier" /* Identifier */).value;
2829
+ this.stream.skipWhitespace();
2830
+ this.stream.expect("RParen" /* RParen */);
2831
+ const handler = this.parseBlock({ allowDeclarations: false });
2832
+ return new TryNode(body, errorName, handler);
2833
+ }
2834
+ parseConstructBlock() {
2835
+ this.stream.expect("Construct" /* Construct */);
2836
+ const body = this.parseBlock({ allowDeclarations: false });
2837
+ body.type = "Construct";
2838
+ return body;
2839
+ }
2840
+ parseDestructBlock() {
2841
+ this.stream.expect("Destruct" /* Destruct */);
2842
+ const body = this.parseBlock({ allowDeclarations: false });
2843
+ body.type = "Destruct";
2844
+ return body;
2845
+ }
2846
+ parseQueryExpression() {
2847
+ this.stream.expect("Question" /* Question */);
2848
+ let direction = "self";
2849
+ if (this.stream.peek()?.type === "Greater" /* Greater */) {
2850
+ this.stream.next();
2851
+ direction = "descendant";
2852
+ } else if (this.stream.peek()?.type === "Less" /* Less */) {
2853
+ this.stream.next();
2854
+ direction = "ancestor";
2855
+ }
2856
+ this.stream.skipWhitespace();
2857
+ this.stream.expect("LParen" /* LParen */);
2858
+ const selector = this.readSelectorUntil("RParen" /* RParen */);
2859
+ return new QueryExpression(direction, selector);
2860
+ }
2861
+ parseFunctionDeclaration() {
2862
+ let isAsync = false;
2863
+ const first = this.stream.peekNonWhitespace(0);
2864
+ if (this.isAsyncToken(first)) {
2865
+ this.stream.next();
2866
+ this.stream.skipWhitespace();
2867
+ isAsync = true;
2868
+ }
2869
+ const name = this.stream.expect("Identifier" /* Identifier */).value;
2870
+ this.stream.skipWhitespace();
2871
+ const params = this.parseFunctionParams();
2872
+ this.stream.skipWhitespace();
2873
+ const body = this.parseFunctionBlockWithAwait(isAsync);
2874
+ return new FunctionDeclarationNode(name, params, body, isAsync);
2875
+ }
2876
+ parseFunctionBlock() {
2877
+ return this.parseFunctionBlockWithAwait(false);
2878
+ }
2879
+ parseReturnStatement() {
2880
+ this.stream.expect("Return" /* Return */);
2881
+ this.stream.skipWhitespace();
2882
+ if (this.stream.peek()?.type === "Semicolon" /* Semicolon */) {
2883
+ this.stream.next();
2884
+ return new ReturnNode();
2885
+ }
2886
+ const value = this.parseExpression();
2887
+ this.stream.skipWhitespace();
2888
+ this.stream.expect("Semicolon" /* Semicolon */);
2889
+ return new ReturnNode(value);
2890
+ }
2891
+ parseArrowFunctionExpression(isAsync = false) {
2892
+ const params = this.parseFunctionParams();
2893
+ this.stream.skipWhitespace();
2894
+ this.stream.expect("Arrow" /* Arrow */);
2895
+ this.stream.skipWhitespace();
2896
+ if (this.stream.peek()?.type === "LBrace" /* LBrace */) {
2897
+ const body2 = this.parseFunctionBlockWithAwait(isAsync);
2898
+ return new FunctionExpression(params, body2, isAsync);
2899
+ }
2900
+ const body = this.parseArrowExpressionBody(isAsync);
2901
+ return new FunctionExpression(params, body, isAsync);
2902
+ }
2903
+ parseFunctionParams() {
2904
+ this.stream.expect("LParen" /* LParen */);
2905
+ const params = [];
2906
+ let sawRest = false;
2907
+ while (true) {
2908
+ this.stream.skipWhitespace();
2909
+ const next = this.stream.peek();
2910
+ if (!next) {
2911
+ throw new Error("Unterminated function parameters");
2912
+ }
2913
+ if (next.type === "RParen" /* RParen */) {
2914
+ this.stream.next();
2915
+ break;
2916
+ }
2917
+ if (next.type === "Ellipsis" /* Ellipsis */) {
2918
+ if (sawRest) {
2919
+ throw new Error("Function parameters can only include one rest parameter");
2920
+ }
2921
+ this.stream.next();
2922
+ this.stream.skipWhitespace();
2923
+ const name2 = this.stream.expect("Identifier" /* Identifier */).value;
2924
+ params.push({ name: name2, rest: true });
2925
+ sawRest = true;
2926
+ this.stream.skipWhitespace();
2927
+ if (this.stream.peek()?.type === "Comma" /* Comma */) {
2928
+ throw new Error("Rest parameter must be last in function parameters");
2929
+ }
2930
+ this.stream.expect("RParen" /* RParen */);
2931
+ break;
2932
+ }
2933
+ const name = this.stream.expect("Identifier" /* Identifier */).value;
2934
+ this.stream.skipWhitespace();
2935
+ let defaultValue;
2936
+ if (this.stream.peek()?.type === "Equals" /* Equals */) {
2937
+ this.stream.next();
2938
+ this.stream.skipWhitespace();
2939
+ defaultValue = this.parseExpression();
2940
+ }
2941
+ params.push(defaultValue ? { name, defaultValue } : { name });
2942
+ this.stream.skipWhitespace();
2943
+ if (this.stream.peek()?.type === "Comma" /* Comma */) {
2944
+ this.stream.next();
2945
+ continue;
2946
+ }
2947
+ if (this.stream.peek()?.type === "RParen" /* RParen */) {
2948
+ this.stream.next();
2949
+ break;
2950
+ }
2951
+ throw new Error("Expected ',' or ')' in function parameters");
2952
+ }
2953
+ return params;
2954
+ }
2955
+ readSelectorUntil(terminator) {
2956
+ let selectorText = "";
2957
+ let sawNonWhitespace = false;
2958
+ while (true) {
2959
+ const token = this.stream.peek();
2960
+ if (!token) {
2961
+ throw new Error("Unterminated selector");
2962
+ }
2963
+ if (token.type === terminator) {
2964
+ this.stream.next();
2965
+ break;
2966
+ }
2967
+ if (token.type === "Whitespace" /* Whitespace */) {
2968
+ this.stream.next();
2969
+ if (sawNonWhitespace && selectorText[selectorText.length - 1] !== " ") {
2970
+ selectorText += " ";
2971
+ }
2972
+ continue;
2973
+ }
2974
+ sawNonWhitespace = true;
2975
+ selectorText += this.stream.next().value;
2976
+ }
2977
+ return selectorText.trim();
2978
+ }
2979
+ parseIdentifierPath() {
2980
+ let value = this.stream.expect("Identifier" /* Identifier */).value;
2981
+ while (this.stream.peek()?.type === "Dot" /* Dot */) {
2982
+ this.stream.next();
2983
+ const part = this.stream.expect("Identifier" /* Identifier */).value;
2984
+ value = `${value}.${part}`;
2985
+ }
2986
+ return value;
2987
+ }
2988
+ };
2989
+
2990
+ // src/runtime/scope.ts
2991
+ var Scope = class _Scope {
2992
+ constructor(parent) {
2993
+ this.parent = parent;
2994
+ this.root = parent ? parent.root : this;
2995
+ }
2996
+ data = /* @__PURE__ */ new Map();
2997
+ root;
2998
+ listeners = /* @__PURE__ */ new Map();
2999
+ anyListeners = /* @__PURE__ */ new Set();
3000
+ createChild() {
3001
+ return new _Scope(this);
3002
+ }
3003
+ get(key) {
3004
+ return this.getPath(key);
3005
+ }
3006
+ set(key, value) {
3007
+ this.setPath(key, value);
3008
+ }
3009
+ hasKey(path) {
3010
+ const parts = path.split(".");
3011
+ const root = parts[0];
3012
+ if (!root) {
3013
+ return false;
3014
+ }
3015
+ return this.data.has(root);
3016
+ }
3017
+ getPath(path) {
3018
+ const explicit = path.startsWith("parent.") || path.startsWith("root.") || path.startsWith("self.");
3019
+ const { targetScope, targetPath } = this.resolveScope(path);
3020
+ if (!targetScope || !targetPath) {
3021
+ return void 0;
3022
+ }
3023
+ const localValue = this.getLocalPathValue(targetScope, targetPath);
3024
+ if (explicit || localValue !== void 0) {
3025
+ return localValue;
3026
+ }
3027
+ let cursor = targetScope.parent;
3028
+ while (cursor) {
3029
+ const value = this.getLocalPathValue(cursor, targetPath);
3030
+ if (value !== void 0) {
3031
+ return value;
3032
+ }
3033
+ cursor = cursor.parent;
3034
+ }
3035
+ return void 0;
3036
+ }
3037
+ setPath(path, value) {
3038
+ const explicit = path.startsWith("parent.") || path.startsWith("root.") || path.startsWith("self.");
3039
+ const { targetScope, targetPath } = this.resolveScope(path);
3040
+ if (!targetScope || !targetPath) {
3041
+ return;
3042
+ }
3043
+ const scopeForSet = explicit ? targetScope : this.findNearestScopeWithKey(targetScope, targetPath) ?? targetScope;
3044
+ const parts = targetPath.split(".");
3045
+ const root = parts[0];
3046
+ if (!root) {
3047
+ return;
3048
+ }
3049
+ if (parts.length === 1) {
3050
+ scopeForSet.data.set(root, value);
3051
+ scopeForSet.emitChange(targetPath);
3052
+ return;
3053
+ }
3054
+ let obj = scopeForSet.data.get(root);
3055
+ if (obj == null || typeof obj !== "object") {
3056
+ obj = {};
3057
+ scopeForSet.data.set(root, obj);
3058
+ }
3059
+ let cursor = obj;
3060
+ for (let i = 1; i < parts.length - 1; i += 1) {
3061
+ const key = parts[i];
3062
+ if (!key) {
3063
+ return;
3064
+ }
3065
+ if (cursor[key] == null || typeof cursor[key] !== "object") {
3066
+ cursor[key] = {};
3067
+ }
3068
+ cursor = cursor[key];
3069
+ }
3070
+ const lastKey = parts[parts.length - 1];
3071
+ if (!lastKey) {
3072
+ return;
3073
+ }
3074
+ cursor[lastKey] = value;
3075
+ scopeForSet.emitChange(targetPath);
3076
+ }
3077
+ on(path, handler) {
3078
+ const key = path.trim();
3079
+ if (!key) {
3080
+ return;
3081
+ }
3082
+ const set = this.listeners.get(key) ?? /* @__PURE__ */ new Set();
3083
+ set.add(handler);
3084
+ this.listeners.set(key, set);
3085
+ }
3086
+ off(path, handler) {
3087
+ const key = path.trim();
3088
+ const set = this.listeners.get(key);
3089
+ if (!set) {
3090
+ return;
3091
+ }
3092
+ set.delete(handler);
3093
+ if (set.size === 0) {
3094
+ this.listeners.delete(key);
3095
+ }
3096
+ }
3097
+ onAny(handler) {
3098
+ this.anyListeners.add(handler);
3099
+ }
3100
+ offAny(handler) {
3101
+ this.anyListeners.delete(handler);
3102
+ }
3103
+ emitChange(path) {
3104
+ const key = path.trim();
3105
+ if (!key) {
3106
+ return;
3107
+ }
3108
+ this.listeners.get(key)?.forEach((fn) => fn());
3109
+ const rootKey = key.split(".")[0];
3110
+ if (rootKey && rootKey !== key) {
3111
+ this.listeners.get(rootKey)?.forEach((fn) => fn());
3112
+ }
3113
+ this.anyListeners.forEach((fn) => fn());
3114
+ }
3115
+ resolveScope(path) {
3116
+ let targetScope = this;
3117
+ let targetPath = path;
3118
+ while (targetPath.startsWith("parent.")) {
3119
+ targetScope = targetScope?.parent;
3120
+ targetPath = targetPath.slice("parent.".length);
3121
+ }
3122
+ if (targetPath.startsWith("root.")) {
3123
+ targetScope = targetScope?.root;
3124
+ targetPath = targetPath.slice("root.".length);
3125
+ }
3126
+ while (targetPath.startsWith("self.")) {
3127
+ targetScope = targetScope ?? this;
3128
+ targetPath = targetPath.slice("self.".length);
3129
+ }
3130
+ return { targetScope, targetPath };
3131
+ }
3132
+ getLocalPathValue(scope, path) {
3133
+ const parts = path.split(".");
3134
+ const root = parts[0];
3135
+ if (!root) {
3136
+ return void 0;
3137
+ }
3138
+ let value = scope.data.get(root);
3139
+ for (let i = 1; i < parts.length; i += 1) {
3140
+ if (value == null) {
3141
+ return void 0;
3142
+ }
3143
+ const key = parts[i];
3144
+ if (!key) {
3145
+ return void 0;
3146
+ }
3147
+ value = value[key];
3148
+ }
3149
+ return value;
3150
+ }
3151
+ findNearestScopeWithKey(start, path) {
3152
+ const root = path.split(".")[0];
3153
+ if (!root) {
3154
+ return void 0;
3155
+ }
3156
+ let cursor = start;
3157
+ while (cursor) {
3158
+ if (cursor.data.has(root)) {
3159
+ return cursor;
3160
+ }
3161
+ cursor = cursor.parent;
3162
+ }
3163
+ return void 0;
3164
+ }
3165
+ };
3166
+
3167
+ // src/runtime/bindings.ts
3168
+ function getElementValue(element) {
3169
+ if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement) {
3170
+ return element.value;
3171
+ }
3172
+ if (element instanceof HTMLSelectElement) {
3173
+ return element.value;
3174
+ }
3175
+ return element.textContent ?? "";
3176
+ }
3177
+ function setElementValue(element, value) {
3178
+ if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement) {
3179
+ element.value = value;
3180
+ element.setAttribute("value", value);
3181
+ return;
3182
+ }
3183
+ if (element instanceof HTMLSelectElement) {
3184
+ element.value = value;
3185
+ return;
3186
+ }
3187
+ if (element instanceof HTMLElement && element.querySelector("*")) {
3188
+ return;
3189
+ }
3190
+ element.textContent = value;
3191
+ }
3192
+ function applyBindToScope(element, expression, scope) {
3193
+ const key = expression.trim();
3194
+ if (!key) {
3195
+ return;
3196
+ }
3197
+ const value = getElementValue(element);
3198
+ scope.set(key, value);
3199
+ }
3200
+ function applyBindToElement(element, expression, scope) {
3201
+ const key = expression.trim();
3202
+ if (!key) {
3203
+ return;
3204
+ }
3205
+ const value = scope.get(key);
3206
+ if (value == null) {
3207
+ return;
3208
+ }
3209
+ setElementValue(element, String(value));
3210
+ }
3211
+
3212
+ // src/runtime/conditionals.ts
3213
+ function readCondition(expression, scope) {
3214
+ const key = expression.trim();
3215
+ if (!key) {
3216
+ return false;
3217
+ }
3218
+ return !!scope.get(key);
3219
+ }
3220
+ function applyIf(element, expression, scope) {
3221
+ element.style.display = readCondition(expression, scope) ? "" : "none";
3222
+ }
3223
+ function applyShow(element, expression, scope) {
3224
+ element.style.display = readCondition(expression, scope) ? "" : "none";
3225
+ }
3226
+
3227
+ // src/runtime/html.ts
3228
+ function sanitizeHtml(value) {
3229
+ return value.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gi, "");
3230
+ }
3231
+ function applyHtml(element, expression, scope, trusted) {
3232
+ const key = expression.trim();
3233
+ if (!key) {
3234
+ return;
3235
+ }
3236
+ const value = scope.get(key);
3237
+ const html = value == null ? "" : String(value);
3238
+ element.innerHTML = trusted ? html : sanitizeHtml(html);
3239
+ }
3240
+
3241
+ // src/runtime/http.ts
3242
+ async function applyGet(element, config, scope, onHtmlApplied) {
3243
+ if (!globalThis.fetch) {
3244
+ throw new Error("fetch is not available");
3245
+ }
3246
+ const response = await globalThis.fetch(config.url);
3247
+ if (!response || !response.ok) {
3248
+ return;
3249
+ }
3250
+ const html = await response.text();
3251
+ const target = resolveTarget(element, config.targetSelector);
3252
+ if (!target) {
3253
+ element.dispatchEvent(new CustomEvent("vsn:targetError", { detail: { selector: config.targetSelector } }));
3254
+ return;
3255
+ }
3256
+ if (config.swap === "outer") {
3257
+ const wrapper = document.createElement("div");
3258
+ applyHtml(wrapper, "__html", { get: () => html }, config.trusted);
3259
+ const replacement = wrapper.firstElementChild;
3260
+ if (replacement && target.parentNode) {
3261
+ target.parentNode.replaceChild(replacement, target);
3262
+ onHtmlApplied?.(replacement);
3263
+ }
3264
+ return;
3265
+ }
3266
+ applyHtml(target, "__html", { get: () => html }, config.trusted);
3267
+ onHtmlApplied?.(target);
3268
+ }
3269
+ function resolveTarget(element, selector) {
3270
+ if (!selector) {
3271
+ return element;
3272
+ }
3273
+ return element.ownerDocument.querySelector(selector);
3274
+ }
3275
+
3276
+ // src/runtime/debounce.ts
3277
+ function debounce(fn, waitMs) {
3278
+ let timer;
3279
+ return (...args) => {
3280
+ if (timer) {
3281
+ clearTimeout(timer);
3282
+ }
3283
+ timer = setTimeout(() => {
3284
+ timer = void 0;
3285
+ fn(...args);
3286
+ }, waitMs);
3287
+ };
3288
+ }
3289
+
3290
+ // src/runtime/engine.ts
3291
+ var Engine = class _Engine {
3292
+ static activeEngines = /* @__PURE__ */ new WeakMap();
3293
+ scopes = /* @__PURE__ */ new WeakMap();
3294
+ bindBindings = /* @__PURE__ */ new WeakMap();
3295
+ ifBindings = /* @__PURE__ */ new WeakMap();
3296
+ showBindings = /* @__PURE__ */ new WeakMap();
3297
+ htmlBindings = /* @__PURE__ */ new WeakMap();
3298
+ getBindings = /* @__PURE__ */ new WeakMap();
3299
+ eachBindings = /* @__PURE__ */ new WeakMap();
3300
+ lifecycleBindings = /* @__PURE__ */ new WeakMap();
3301
+ behaviorRegistry = [];
3302
+ behaviorBindings = /* @__PURE__ */ new WeakMap();
3303
+ behaviorListeners = /* @__PURE__ */ new WeakMap();
3304
+ behaviorId = 0;
3305
+ codeCache = /* @__PURE__ */ new Map();
3306
+ behaviorCache = /* @__PURE__ */ new Map();
3307
+ observer;
3308
+ observerRoot;
3309
+ attributeHandlers = [];
3310
+ globals = {};
3311
+ importantFlags = /* @__PURE__ */ new WeakMap();
3312
+ inlineDeclarations = /* @__PURE__ */ new WeakMap();
3313
+ flagHandlers = /* @__PURE__ */ new Map();
3314
+ pendingAdded = /* @__PURE__ */ new Set();
3315
+ pendingRemoved = /* @__PURE__ */ new Set();
3316
+ pendingUpdated = /* @__PURE__ */ new Set();
3317
+ observerFlush;
3318
+ ignoredAdded = /* @__PURE__ */ new WeakMap();
3319
+ diagnostics;
3320
+ logger;
3321
+ constructor(options = {}) {
3322
+ this.diagnostics = options.diagnostics ?? false;
3323
+ this.logger = options.logger ?? console;
3324
+ this.registerGlobal("console", console);
3325
+ this.registerGlobal("list", {
3326
+ async map(items, fn) {
3327
+ if (!Array.isArray(items) || typeof fn !== "function") {
3328
+ return [];
3329
+ }
3330
+ const results = [];
3331
+ for (let i = 0; i < items.length; i += 1) {
3332
+ results.push(await fn(items[i], i));
3333
+ }
3334
+ return results;
3335
+ },
3336
+ async filter(items, fn) {
3337
+ if (!Array.isArray(items) || typeof fn !== "function") {
3338
+ return [];
3339
+ }
3340
+ const results = [];
3341
+ for (let i = 0; i < items.length; i += 1) {
3342
+ if (await fn(items[i], i)) {
3343
+ results.push(items[i]);
3344
+ }
3345
+ }
3346
+ return results;
3347
+ },
3348
+ async reduce(items, fn, initial) {
3349
+ if (!Array.isArray(items) || typeof fn !== "function") {
3350
+ return initial;
3351
+ }
3352
+ const hasInitial = arguments.length > 2;
3353
+ let acc = hasInitial ? initial : items[0];
3354
+ let start = hasInitial ? 0 : 1;
3355
+ for (let i = start; i < items.length; i += 1) {
3356
+ acc = await fn(acc, items[i], i);
3357
+ }
3358
+ return acc;
3359
+ }
3360
+ });
3361
+ this.registerDefaultAttributeHandlers();
3362
+ }
3363
+ async mount(root) {
3364
+ const documentRoot = root.ownerDocument;
3365
+ const active = _Engine.activeEngines.get(documentRoot);
3366
+ if (active && active !== this) {
3367
+ active.disconnectObserver();
3368
+ }
3369
+ _Engine.activeEngines.set(documentRoot, this);
3370
+ const elements = [root, ...Array.from(root.querySelectorAll("*"))];
3371
+ for (const element of elements) {
3372
+ if (!this.hasVsnAttributes(element)) {
3373
+ continue;
3374
+ }
3375
+ const parentScope = this.findParentScope(element);
3376
+ this.getScope(element, parentScope);
3377
+ this.attachAttributes(element);
3378
+ this.runConstruct(element);
3379
+ }
3380
+ await this.applyBehaviors(root);
3381
+ this.attachObserver(root);
3382
+ }
3383
+ unmount(element) {
3384
+ this.runDestruct(element);
3385
+ this.disconnectObserver();
3386
+ }
3387
+ registerBehaviors(source) {
3388
+ const program = new Parser(source, { customFlags: new Set(this.flagHandlers.keys()) }).parseProgram();
3389
+ for (const use of program.uses) {
3390
+ const value = this.resolveGlobalPath(use.name);
3391
+ if (value === void 0) {
3392
+ console.warn(`vsn: global '${use.name}' not found`);
3393
+ continue;
3394
+ }
3395
+ this.registerGlobal(use.alias, value);
3396
+ }
3397
+ for (const behavior of program.behaviors) {
3398
+ this.collectBehavior(behavior);
3399
+ }
3400
+ }
3401
+ registerGlobal(name, value) {
3402
+ this.globals[name] = value;
3403
+ }
3404
+ registerGlobals(values) {
3405
+ Object.assign(this.globals, values);
3406
+ }
3407
+ registerFlag(name, handler = {}) {
3408
+ const reserved = /* @__PURE__ */ new Set(["important", "trusted", "debounce"]);
3409
+ if (reserved.has(name)) {
3410
+ throw new Error(`Flag '${name}' is reserved`);
3411
+ }
3412
+ this.flagHandlers.set(name, handler);
3413
+ }
3414
+ getRegistryStats() {
3415
+ return {
3416
+ behaviorCount: this.behaviorRegistry.length,
3417
+ behaviorCacheSize: this.behaviorCache.size
3418
+ };
3419
+ }
3420
+ registerAttributeHandler(handler) {
3421
+ this.attributeHandlers.push(handler);
3422
+ }
3423
+ resolveGlobalPath(name) {
3424
+ const parts = name.split(".");
3425
+ const root = parts[0];
3426
+ if (!root) {
3427
+ return void 0;
3428
+ }
3429
+ let value = globalThis[root];
3430
+ for (let i = 1; i < parts.length; i += 1) {
3431
+ const part = parts[i];
3432
+ if (!part) {
3433
+ return void 0;
3434
+ }
3435
+ value = value?.[part];
3436
+ }
3437
+ return value;
3438
+ }
3439
+ getScope(element, parentScope) {
3440
+ const existing = this.scopes.get(element);
3441
+ if (existing) {
3442
+ return existing;
3443
+ }
3444
+ const scope = new Scope(parentScope ?? this.findParentScope(element));
3445
+ this.scopes.set(element, scope);
3446
+ return scope;
3447
+ }
3448
+ evaluate(element) {
3449
+ const scope = this.getScope(element);
3450
+ const bindConfig = this.bindBindings.get(element);
3451
+ if (bindConfig && (bindConfig.direction === "from" || bindConfig.direction === "both")) {
3452
+ applyBindToElement(element, bindConfig.expr, scope);
3453
+ }
3454
+ const ifExpr = this.ifBindings.get(element);
3455
+ if (ifExpr && element instanceof HTMLElement) {
3456
+ applyIf(element, ifExpr, scope);
3457
+ }
3458
+ const showExpr = this.showBindings.get(element);
3459
+ if (showExpr && element instanceof HTMLElement) {
3460
+ applyShow(element, showExpr, scope);
3461
+ }
3462
+ const htmlBinding = this.htmlBindings.get(element);
3463
+ if (htmlBinding && element instanceof HTMLElement) {
3464
+ applyHtml(element, htmlBinding.expr, scope, htmlBinding.trusted);
3465
+ if (htmlBinding.trusted) {
3466
+ this.handleTrustedHtml(element);
3467
+ }
3468
+ }
3469
+ }
3470
+ attachObserver(root) {
3471
+ if (this.observer) {
3472
+ return;
3473
+ }
3474
+ this.observerRoot = root;
3475
+ this.observerFlush = debounce(() => this.flushObserverQueue(), 10);
3476
+ this.observer = new MutationObserver((mutations) => {
3477
+ for (const mutation of mutations) {
3478
+ if (mutation.type === "attributes" && mutation.target instanceof Element) {
3479
+ this.pendingUpdated.add(mutation.target);
3480
+ }
3481
+ for (const node of Array.from(mutation.addedNodes)) {
3482
+ if (node && node.nodeType === 1) {
3483
+ const element = node;
3484
+ if (this.ignoredAdded.has(element)) {
3485
+ this.ignoredAdded.delete(element);
3486
+ continue;
3487
+ }
3488
+ this.pendingAdded.add(element);
3489
+ }
3490
+ }
3491
+ for (const node of Array.from(mutation.removedNodes)) {
3492
+ if (node && node.nodeType === 1) {
3493
+ this.pendingRemoved.add(node);
3494
+ }
3495
+ }
3496
+ }
3497
+ this.observerFlush?.();
3498
+ });
3499
+ this.observer.observe(root, { childList: true, subtree: true, attributes: true, attributeFilter: ["class"] });
3500
+ }
3501
+ disconnectObserver() {
3502
+ this.observer?.disconnect();
3503
+ this.observer = void 0;
3504
+ this.observerRoot = void 0;
3505
+ this.pendingAdded.clear();
3506
+ this.pendingRemoved.clear();
3507
+ this.pendingUpdated.clear();
3508
+ }
3509
+ flushObserverQueue() {
3510
+ const removed = Array.from(this.pendingRemoved);
3511
+ this.pendingRemoved.clear();
3512
+ for (const node of removed) {
3513
+ this.handleRemovedNode(node);
3514
+ }
3515
+ const updated = Array.from(this.pendingUpdated);
3516
+ this.pendingUpdated.clear();
3517
+ for (const node of updated) {
3518
+ this.handleUpdatedNode(node);
3519
+ }
3520
+ const added = Array.from(this.pendingAdded);
3521
+ this.pendingAdded.clear();
3522
+ for (const node of added) {
3523
+ this.handleAddedNode(node);
3524
+ }
3525
+ }
3526
+ handleRemovedNode(node) {
3527
+ if (this.lifecycleBindings.has(node)) {
3528
+ this.runDestruct(node);
3529
+ }
3530
+ if (this.behaviorBindings.has(node)) {
3531
+ this.runBehaviorDestruct(node);
3532
+ }
3533
+ for (const child of Array.from(node.querySelectorAll("*"))) {
3534
+ if (this.lifecycleBindings.has(child)) {
3535
+ this.runDestruct(child);
3536
+ }
3537
+ if (this.behaviorBindings.has(child)) {
3538
+ this.runBehaviorDestruct(child);
3539
+ }
3540
+ }
3541
+ }
3542
+ handleAddedNode(node) {
3543
+ const elements = [node, ...Array.from(node.querySelectorAll("*"))];
3544
+ for (const element of elements) {
3545
+ if (!this.hasVsnAttributes(element)) {
3546
+ continue;
3547
+ }
3548
+ const parentScope = this.findParentScope(element);
3549
+ this.getScope(element, parentScope);
3550
+ this.attachAttributes(element);
3551
+ this.runConstruct(element);
3552
+ }
3553
+ void this.applyBehaviors(node);
3554
+ }
3555
+ handleUpdatedNode(node) {
3556
+ const elements = [node, ...Array.from(node.querySelectorAll("*"))];
3557
+ for (const element of elements) {
3558
+ void this.reapplyBehaviorsForElement(element);
3559
+ }
3560
+ }
3561
+ async applyBehaviors(root) {
3562
+ if (this.behaviorRegistry.length === 0) {
3563
+ return;
3564
+ }
3565
+ const elements = [root, ...Array.from(root.querySelectorAll("*"))];
3566
+ for (const element of elements) {
3567
+ await this.reapplyBehaviorsForElement(element);
3568
+ }
3569
+ }
3570
+ async reapplyBehaviorsForElement(element) {
3571
+ if (this.behaviorRegistry.length === 0) {
3572
+ return;
3573
+ }
3574
+ const bound = this.behaviorBindings.get(element) ?? /* @__PURE__ */ new Set();
3575
+ const scope = this.getScope(element);
3576
+ const matched = this.behaviorRegistry.filter((behavior) => element.matches(behavior.selector)).sort((a, b) => {
3577
+ if (a.specificity !== b.specificity) {
3578
+ return a.specificity - b.specificity;
3579
+ }
3580
+ return a.order - b.order;
3581
+ });
3582
+ for (const behavior of matched) {
3583
+ if (!bound.has(behavior.id)) {
3584
+ await this.applyBehaviorForElement(behavior, element, scope, bound);
3585
+ }
3586
+ }
3587
+ const matchedIds = new Set(matched.map((behavior) => behavior.id));
3588
+ for (const behavior of this.behaviorRegistry) {
3589
+ if (bound.has(behavior.id) && !matchedIds.has(behavior.id)) {
3590
+ this.unbindBehaviorForElement(behavior, element, scope, bound);
3591
+ }
3592
+ }
3593
+ this.behaviorBindings.set(element, bound);
3594
+ }
3595
+ async applyBehaviorForElement(behavior, element, scope, bound) {
3596
+ bound.add(behavior.id);
3597
+ const rootScope = this.getBehaviorRootScope(element, behavior);
3598
+ this.applyBehaviorFunctions(element, scope, behavior.functions, rootScope);
3599
+ await this.applyBehaviorDeclarations(element, scope, behavior.declarations, rootScope);
3600
+ if (behavior.construct) {
3601
+ await this.safeExecuteBlock(behavior.construct, scope, element, rootScope);
3602
+ }
3603
+ for (const onBlock of behavior.onBlocks) {
3604
+ this.attachBehaviorOnHandler(
3605
+ element,
3606
+ onBlock.event,
3607
+ onBlock.body,
3608
+ onBlock.modifiers,
3609
+ onBlock.args,
3610
+ behavior.id,
3611
+ rootScope
3612
+ );
3613
+ }
3614
+ this.logDiagnostic("bind", element, behavior);
3615
+ }
3616
+ unbindBehaviorForElement(behavior, element, scope, bound) {
3617
+ bound.delete(behavior.id);
3618
+ if (behavior.destruct) {
3619
+ const rootScope = this.getBehaviorRootScope(element, behavior);
3620
+ void this.safeExecuteBlock(behavior.destruct, scope, element, rootScope);
3621
+ }
3622
+ const listenerMap = this.behaviorListeners.get(element);
3623
+ const listeners = listenerMap?.get(behavior.id);
3624
+ if (listeners) {
3625
+ for (const listener of listeners) {
3626
+ listener.target.removeEventListener(listener.event, listener.handler, listener.options);
3627
+ }
3628
+ listenerMap?.delete(behavior.id);
3629
+ }
3630
+ this.logDiagnostic("unbind", element, behavior);
3631
+ }
3632
+ runBehaviorDestruct(element) {
3633
+ const bound = this.behaviorBindings.get(element);
3634
+ if (!bound) {
3635
+ return;
3636
+ }
3637
+ const scope = this.getScope(element);
3638
+ for (const behavior of this.behaviorRegistry) {
3639
+ if (!bound.has(behavior.id) || !behavior.destruct) {
3640
+ continue;
3641
+ }
3642
+ const rootScope = this.getBehaviorRootScope(element, behavior);
3643
+ void this.safeExecuteBlock(behavior.destruct, scope, element, rootScope);
3644
+ }
3645
+ }
3646
+ attachAttributes(element) {
3647
+ const scope = this.getScope(element);
3648
+ for (const name of element.getAttributeNames()) {
3649
+ if (!name.startsWith("vsn-")) {
3650
+ continue;
3651
+ }
3652
+ const value = element.getAttribute(name) ?? "";
3653
+ for (const handler of this.attributeHandlers) {
3654
+ if (!handler.match(name)) {
3655
+ continue;
3656
+ }
3657
+ const handled = handler.handle(element, name, value, scope);
3658
+ if (handled !== false) {
3659
+ break;
3660
+ }
3661
+ }
3662
+ }
3663
+ }
3664
+ setLifecycle(element, patch) {
3665
+ const current = this.lifecycleBindings.get(element) ?? {};
3666
+ this.lifecycleBindings.set(element, { ...current, ...patch });
3667
+ }
3668
+ runConstruct(element) {
3669
+ const config = this.lifecycleBindings.get(element);
3670
+ if (!config?.construct) {
3671
+ return;
3672
+ }
3673
+ const scope = this.getScope(element);
3674
+ void this.safeExecute(config.construct, scope, element);
3675
+ }
3676
+ runDestruct(element) {
3677
+ const config = this.lifecycleBindings.get(element);
3678
+ if (!config?.destruct) {
3679
+ return;
3680
+ }
3681
+ const scope = this.getScope(element);
3682
+ void this.safeExecute(config.destruct, scope, element);
3683
+ }
3684
+ parseEachExpression(value) {
3685
+ const [listPart, rest] = value.split(/\s+as\s+/);
3686
+ if (!listPart || !rest) {
3687
+ return null;
3688
+ }
3689
+ const listExpr = listPart.trim();
3690
+ const names = rest.split(",").map((entry) => entry.trim()).filter(Boolean);
3691
+ if (!listExpr || names.length === 0) {
3692
+ return null;
3693
+ }
3694
+ const itemName = names[0] ?? "";
3695
+ const indexName = names[1];
3696
+ return { listExpr, itemName, ...indexName ? { indexName } : {} };
3697
+ }
3698
+ renderEach(element) {
3699
+ const binding = this.eachBindings.get(element);
3700
+ if (!binding) {
3701
+ return;
3702
+ }
3703
+ if (!(element instanceof HTMLTemplateElement)) {
3704
+ return;
3705
+ }
3706
+ const parent = element.parentElement;
3707
+ if (!parent) {
3708
+ return;
3709
+ }
3710
+ for (const node of binding.rendered) {
3711
+ this.handleRemovedNode(node);
3712
+ if (node.parentNode) {
3713
+ node.parentNode.removeChild(node);
3714
+ }
3715
+ }
3716
+ binding.rendered = [];
3717
+ const scope = this.getScope(element);
3718
+ const list = scope.get(binding.listExpr);
3719
+ if (!Array.isArray(list)) {
3720
+ return;
3721
+ }
3722
+ const rendered = [];
3723
+ list.forEach((item, index) => {
3724
+ const fragment = element.content.cloneNode(true);
3725
+ const roots = Array.from(fragment.children);
3726
+ const itemScope = new Scope(scope);
3727
+ itemScope.setPath(`self.${binding.itemName}`, item);
3728
+ if (binding.indexName) {
3729
+ itemScope.setPath(`self.${binding.indexName}`, index);
3730
+ }
3731
+ for (const root of roots) {
3732
+ this.getScope(root, itemScope);
3733
+ }
3734
+ parent.insertBefore(fragment, element);
3735
+ for (const root of roots) {
3736
+ this.ignoredAdded.set(root, true);
3737
+ rendered.push(root);
3738
+ this.handleAddedNode(root);
3739
+ this.evaluate(root);
3740
+ for (const child of Array.from(root.querySelectorAll("*"))) {
3741
+ this.evaluate(child);
3742
+ }
3743
+ }
3744
+ });
3745
+ binding.rendered = rendered;
3746
+ }
3747
+ attachBindInputHandler(element, expr) {
3748
+ if (!(element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement || element instanceof HTMLSelectElement)) {
3749
+ return;
3750
+ }
3751
+ const handler = () => {
3752
+ const scope = this.getScope(element);
3753
+ applyBindToScope(element, expr, scope);
3754
+ };
3755
+ element.addEventListener("input", handler);
3756
+ element.addEventListener("change", handler);
3757
+ }
3758
+ parseBindDirection(name) {
3759
+ if (name.includes(":from")) {
3760
+ return "from";
3761
+ }
3762
+ if (name.includes(":to")) {
3763
+ return "to";
3764
+ }
3765
+ return "both";
3766
+ }
3767
+ hasVsnAttributes(element) {
3768
+ return element.getAttributeNames().some((name) => name.startsWith("vsn-"));
3769
+ }
3770
+ markInlineDeclaration(element, key) {
3771
+ const set = this.inlineDeclarations.get(element) ?? /* @__PURE__ */ new Set();
3772
+ set.add(key);
3773
+ this.inlineDeclarations.set(element, set);
3774
+ }
3775
+ isInlineDeclaration(element, key) {
3776
+ const set = this.inlineDeclarations.get(element);
3777
+ return set ? set.has(key) : false;
3778
+ }
3779
+ findParentScope(element) {
3780
+ let parent = element.parentElement;
3781
+ while (parent) {
3782
+ const scope = this.scopes.get(parent);
3783
+ if (scope) {
3784
+ return scope;
3785
+ }
3786
+ parent = parent.parentElement;
3787
+ }
3788
+ return void 0;
3789
+ }
3790
+ watch(scope, expr, handler) {
3791
+ const key = expr.trim();
3792
+ if (!key) {
3793
+ return;
3794
+ }
3795
+ const root = key.split(".")[0];
3796
+ if (!root) {
3797
+ return;
3798
+ }
3799
+ let target = scope;
3800
+ while (target && !target.hasKey(root)) {
3801
+ target = target.parent;
3802
+ }
3803
+ if (target) {
3804
+ target.on(key, handler);
3805
+ return;
3806
+ }
3807
+ let cursor = scope;
3808
+ while (cursor) {
3809
+ cursor.on(key, handler);
3810
+ cursor = cursor.parent;
3811
+ }
3812
+ }
3813
+ watchWithDebounce(scope, expr, handler, debounceMs) {
3814
+ if (debounceMs) {
3815
+ this.watch(scope, expr, debounce(handler, debounceMs));
3816
+ } else {
3817
+ this.watch(scope, expr, handler);
3818
+ }
3819
+ }
3820
+ watchAllScopes(scope, handler, debounceMs) {
3821
+ const effectiveHandler = debounceMs ? debounce(handler, debounceMs) : handler;
3822
+ let cursor = scope;
3823
+ while (cursor) {
3824
+ cursor.onAny(effectiveHandler);
3825
+ cursor = cursor.parent;
3826
+ }
3827
+ }
3828
+ parseOnAttribute(name, value) {
3829
+ if (!name.startsWith("vsn-on:")) {
3830
+ return null;
3831
+ }
3832
+ const eventWithFlags = name.slice("vsn-on:".length);
3833
+ const [event, ...flags] = eventWithFlags.split("!");
3834
+ if (!event) {
3835
+ return null;
3836
+ }
3837
+ const descriptor = this.parseEventDescriptor(event);
3838
+ if (!descriptor.event) {
3839
+ return null;
3840
+ }
3841
+ let debounceMs;
3842
+ const modifiers = [];
3843
+ for (const flag of flags) {
3844
+ if (flag.startsWith("debounce")) {
3845
+ const match = flag.match(/debounce\((\d+)\)/);
3846
+ debounceMs = match ? Number(match[1]) : 200;
3847
+ continue;
3848
+ }
3849
+ modifiers.push(flag);
3850
+ }
3851
+ const combinedModifiers = [...modifiers, ...descriptor.modifiers];
3852
+ const config = {
3853
+ event: descriptor.event,
3854
+ code: value,
3855
+ ...debounceMs !== void 0 ? { debounceMs } : {},
3856
+ ...combinedModifiers.length > 0 ? { modifiers: combinedModifiers } : {},
3857
+ ...descriptor.keyModifiers.length > 0 ? { keyModifiers: descriptor.keyModifiers } : {}
3858
+ };
3859
+ return config;
3860
+ }
3861
+ parseEventDescriptor(raw) {
3862
+ const parts = raw.split(".").map((part) => part.trim()).filter(Boolean);
3863
+ const event = parts.shift() ?? "";
3864
+ const modifiers = [];
3865
+ const keyModifiers = [];
3866
+ const modifierSet = /* @__PURE__ */ new Set(["outside", "self"]);
3867
+ for (const part of parts) {
3868
+ if (modifierSet.has(part)) {
3869
+ modifiers.push(part);
3870
+ } else {
3871
+ keyModifiers.push(part);
3872
+ }
3873
+ }
3874
+ return { event, keyModifiers, modifiers };
3875
+ }
3876
+ matchesKeyModifiers(event, keyModifiers) {
3877
+ if (!keyModifiers || keyModifiers.length === 0) {
3878
+ return true;
3879
+ }
3880
+ if (!(event instanceof KeyboardEvent)) {
3881
+ return false;
3882
+ }
3883
+ const modifierChecks = {
3884
+ shift: event.shiftKey,
3885
+ ctrl: event.ctrlKey,
3886
+ control: event.ctrlKey,
3887
+ alt: event.altKey,
3888
+ meta: event.metaKey
3889
+ };
3890
+ const keyAliases = {
3891
+ esc: "escape",
3892
+ escape: "escape",
3893
+ enter: "enter",
3894
+ tab: "tab",
3895
+ space: "space",
3896
+ spacebar: "space",
3897
+ up: "arrowup",
3898
+ down: "arrowdown",
3899
+ left: "arrowleft",
3900
+ right: "arrowright",
3901
+ arrowup: "arrowup",
3902
+ arrowdown: "arrowdown",
3903
+ arrowleft: "arrowleft",
3904
+ arrowright: "arrowright",
3905
+ delete: "delete",
3906
+ backspace: "backspace"
3907
+ };
3908
+ let key = event.key?.toLowerCase() ?? "";
3909
+ if (key === " ") {
3910
+ key = "space";
3911
+ }
3912
+ for (const rawModifier of keyModifiers) {
3913
+ const modifier = rawModifier.toLowerCase();
3914
+ if (modifier in modifierChecks) {
3915
+ if (!modifierChecks[modifier]) {
3916
+ return false;
3917
+ }
3918
+ continue;
3919
+ }
3920
+ const expectedKey = keyAliases[modifier] ?? modifier;
3921
+ if (key !== expectedKey) {
3922
+ return false;
3923
+ }
3924
+ }
3925
+ return true;
3926
+ }
3927
+ matchesTargetModifiers(element, event, modifiers) {
3928
+ if (!modifiers || modifiers.length === 0) {
3929
+ return true;
3930
+ }
3931
+ const target = event?.target;
3932
+ if (!target || !(target instanceof Node)) {
3933
+ return !modifiers.includes("self") && !modifiers.includes("outside");
3934
+ }
3935
+ if (modifiers.includes("self") && target !== element) {
3936
+ return false;
3937
+ }
3938
+ if (modifiers.includes("outside") && element.contains(target)) {
3939
+ return false;
3940
+ }
3941
+ return true;
3942
+ }
3943
+ describeElement(element) {
3944
+ const tag = element.tagName.toLowerCase();
3945
+ const id = element.id ? `#${element.id}` : "";
3946
+ const classes = element.classList.length > 0 ? `.${Array.from(element.classList).join(".")}` : "";
3947
+ return `${tag}${id}${classes}`;
3948
+ }
3949
+ logDiagnostic(type, element, behavior) {
3950
+ if (!this.diagnostics || !this.logger.info) {
3951
+ return;
3952
+ }
3953
+ this.logger.info(`vsn:${type}`, {
3954
+ element: this.describeElement(element),
3955
+ selector: behavior.selector,
3956
+ behaviorId: behavior.id
3957
+ });
3958
+ }
3959
+ emitError(element, error) {
3960
+ const selector = this.describeElement(element);
3961
+ this.logger.warn?.("vsn:error", { error, selector });
3962
+ element.dispatchEvent(
3963
+ new CustomEvent("vsn:error", {
3964
+ detail: { error, selector },
3965
+ bubbles: true
3966
+ })
3967
+ );
3968
+ }
3969
+ attachOnHandler(element, config) {
3970
+ const options = this.getListenerOptions(config.modifiers);
3971
+ const listenerTarget = config.modifiers?.includes("outside") ? element.ownerDocument : element;
3972
+ let effectiveHandler;
3973
+ const handler = async (event) => {
3974
+ if (!element.isConnected) {
3975
+ listenerTarget.removeEventListener(config.event, effectiveHandler, options);
3976
+ return;
3977
+ }
3978
+ if (!this.matchesKeyModifiers(event, config.keyModifiers)) {
3979
+ return;
3980
+ }
3981
+ if (!this.matchesTargetModifiers(element, event, config.modifiers)) {
3982
+ return;
3983
+ }
3984
+ this.applyEventModifiers(event, config.modifiers);
3985
+ const scope = this.getScope(element);
3986
+ try {
3987
+ await this.execute(config.code, scope, element);
3988
+ this.evaluate(element);
3989
+ } catch (error) {
3990
+ this.emitError(element, error);
3991
+ }
3992
+ };
3993
+ effectiveHandler = config.debounceMs ? debounce(handler, config.debounceMs) : handler;
3994
+ listenerTarget.addEventListener(config.event, effectiveHandler, options);
3995
+ }
3996
+ attachBehaviorOnHandler(element, event, body, modifiers, args, behaviorId, rootScope) {
3997
+ const descriptor = this.parseEventDescriptor(event);
3998
+ const combinedModifiers = modifiers ? [...modifiers, ...descriptor.modifiers] : descriptor.modifiers.length > 0 ? [...descriptor.modifiers] : void 0;
3999
+ const listenerTarget = combinedModifiers?.includes("outside") ? element.ownerDocument : element;
4000
+ const handler = async (evt) => {
4001
+ if (!this.matchesKeyModifiers(evt, descriptor.keyModifiers)) {
4002
+ return;
4003
+ }
4004
+ if (!this.matchesTargetModifiers(element, evt, combinedModifiers)) {
4005
+ return;
4006
+ }
4007
+ this.applyEventModifiers(evt, combinedModifiers);
4008
+ const scope = this.getScope(element);
4009
+ const previousValues = /* @__PURE__ */ new Map();
4010
+ if (args && args.length > 0) {
4011
+ const argName = args[0];
4012
+ if (argName) {
4013
+ previousValues.set(argName, scope.getPath(argName));
4014
+ scope.setPath(argName, evt);
4015
+ }
4016
+ }
4017
+ let failed = false;
4018
+ try {
4019
+ await this.executeBlock(body, scope, element, rootScope);
4020
+ } catch (error) {
4021
+ failed = true;
4022
+ this.emitError(element, error);
4023
+ } finally {
4024
+ for (const [name, value] of previousValues.entries()) {
4025
+ scope.setPath(name, value);
4026
+ }
4027
+ }
4028
+ if (!failed) {
4029
+ this.evaluate(element);
4030
+ }
4031
+ };
4032
+ const options = this.getListenerOptions(combinedModifiers);
4033
+ listenerTarget.addEventListener(descriptor.event, handler, options);
4034
+ const listenerMap = this.behaviorListeners.get(element) ?? /* @__PURE__ */ new Map();
4035
+ const listeners = listenerMap.get(behaviorId) ?? [];
4036
+ listeners.push({ target: listenerTarget, event: descriptor.event, handler, options });
4037
+ listenerMap.set(behaviorId, listeners);
4038
+ this.behaviorListeners.set(element, listenerMap);
4039
+ }
4040
+ attachGetHandler(element, autoLoad = false) {
4041
+ const handler = async () => {
4042
+ const config = this.getBindings.get(element);
4043
+ if (!config) {
4044
+ return;
4045
+ }
4046
+ try {
4047
+ await applyGet(element, config, this.getScope(element), (target) => {
4048
+ if (config.trusted) {
4049
+ this.handleTrustedHtml(target);
4050
+ }
4051
+ });
4052
+ } catch (error) {
4053
+ console.warn("vsn:getError", error);
4054
+ element.dispatchEvent(new CustomEvent("vsn:getError", { detail: { error }, bubbles: true }));
4055
+ }
4056
+ };
4057
+ element.addEventListener("click", (event) => {
4058
+ if (event.target !== element) {
4059
+ return;
4060
+ }
4061
+ void handler();
4062
+ });
4063
+ if (autoLoad) {
4064
+ Promise.resolve().then(handler);
4065
+ }
4066
+ }
4067
+ applyEventModifiers(event, modifiers) {
4068
+ if (!event || !modifiers || modifiers.length === 0) {
4069
+ return;
4070
+ }
4071
+ for (const modifier of modifiers) {
4072
+ if (modifier === "prevent") {
4073
+ event.preventDefault();
4074
+ } else if (modifier === "stop") {
4075
+ event.stopPropagation();
4076
+ }
4077
+ }
4078
+ }
4079
+ getListenerOptions(modifiers) {
4080
+ if (!modifiers || modifiers.length === 0) {
4081
+ return void 0;
4082
+ }
4083
+ const options = {};
4084
+ if (modifiers.includes("once")) {
4085
+ options.once = true;
4086
+ }
4087
+ if (modifiers.includes("passive")) {
4088
+ options.passive = true;
4089
+ }
4090
+ if (modifiers.includes("capture")) {
4091
+ options.capture = true;
4092
+ }
4093
+ return Object.keys(options).length > 0 ? options : void 0;
4094
+ }
4095
+ async execute(code, scope, element, rootScope) {
4096
+ let block = this.codeCache.get(code);
4097
+ if (!block) {
4098
+ block = Parser.parseInline(code);
4099
+ this.codeCache.set(code, block);
4100
+ }
4101
+ const context = {
4102
+ scope,
4103
+ rootScope,
4104
+ globals: this.globals,
4105
+ ...element ? { element } : {}
4106
+ };
4107
+ await block.evaluate(context);
4108
+ }
4109
+ async executeBlock(block, scope, element, rootScope) {
4110
+ const context = {
4111
+ scope,
4112
+ rootScope,
4113
+ globals: this.globals,
4114
+ ...element ? { element } : {}
4115
+ };
4116
+ await block.evaluate(context);
4117
+ }
4118
+ async safeExecute(code, scope, element, rootScope) {
4119
+ try {
4120
+ await this.execute(code, scope, element, rootScope);
4121
+ } catch (error) {
4122
+ if (element) {
4123
+ this.emitError(element, error);
4124
+ }
4125
+ }
4126
+ }
4127
+ async safeExecuteBlock(block, scope, element, rootScope) {
4128
+ try {
4129
+ await this.executeBlock(block, scope, element, rootScope);
4130
+ } catch (error) {
4131
+ if (element) {
4132
+ this.emitError(element, error);
4133
+ }
4134
+ }
4135
+ }
4136
+ collectBehavior(behavior, parentSelector, rootSelectorOverride) {
4137
+ const selector = parentSelector ? `${parentSelector} ${behavior.selector.selectorText}` : behavior.selector.selectorText;
4138
+ const rootSelector = rootSelectorOverride ?? (parentSelector ?? behavior.selector.selectorText);
4139
+ const cached = this.getCachedBehavior(behavior);
4140
+ this.behaviorRegistry.push({
4141
+ id: this.behaviorId += 1,
4142
+ selector,
4143
+ rootSelector,
4144
+ specificity: this.computeSpecificity(selector),
4145
+ order: this.behaviorRegistry.length,
4146
+ ...cached
4147
+ });
4148
+ this.collectNestedBehaviors(behavior.body, selector, rootSelector);
4149
+ }
4150
+ collectNestedBehaviors(block, parentSelector, rootSelector) {
4151
+ for (const statement of block.statements) {
4152
+ if (statement instanceof BehaviorNode) {
4153
+ this.collectBehavior(statement, parentSelector, rootSelector);
4154
+ continue;
4155
+ }
4156
+ if (statement instanceof OnBlockNode) {
4157
+ this.collectNestedBehaviors(statement.body, parentSelector, rootSelector);
4158
+ continue;
4159
+ }
4160
+ if (statement instanceof BlockNode) {
4161
+ this.collectNestedBehaviors(statement, parentSelector, rootSelector);
4162
+ }
4163
+ }
4164
+ }
4165
+ computeSpecificity(selector) {
4166
+ const idMatches = selector.match(/#[\w-]+/g)?.length ?? 0;
4167
+ const classMatches = selector.match(/\.[\w-]+/g)?.length ?? 0;
4168
+ const attrMatches = selector.match(/\[[^\]]+\]/g)?.length ?? 0;
4169
+ const pseudoMatches = selector.match(/:[\w-]+/g)?.length ?? 0;
4170
+ const elementMatches = selector.match(/(^|[\s>+~])([a-zA-Z][\w-]*)/g)?.length ?? 0;
4171
+ return idMatches * 100 + (classMatches + attrMatches + pseudoMatches) * 10 + elementMatches;
4172
+ }
4173
+ getBehaviorRootScope(element, behavior) {
4174
+ const rootElement = element.closest(behavior.rootSelector) ?? element;
4175
+ return this.getScope(rootElement);
4176
+ }
4177
+ getImportantKey(declaration) {
4178
+ if (declaration.target instanceof IdentifierExpression) {
4179
+ return `state:${declaration.target.name}`;
4180
+ }
4181
+ if (declaration.target instanceof DirectiveExpression) {
4182
+ return `${declaration.target.kind}:${declaration.target.name}`;
4183
+ }
4184
+ return void 0;
4185
+ }
4186
+ isImportant(element, key) {
4187
+ const set = this.importantFlags.get(element);
4188
+ return set ? set.has(key) : false;
4189
+ }
4190
+ markImportant(element, key) {
4191
+ const set = this.importantFlags.get(element) ?? /* @__PURE__ */ new Set();
4192
+ set.add(key);
4193
+ this.importantFlags.set(element, set);
4194
+ }
4195
+ extractLifecycle(body) {
4196
+ let construct;
4197
+ let destruct;
4198
+ for (const statement of body.statements) {
4199
+ if (!(statement instanceof BlockNode)) {
4200
+ continue;
4201
+ }
4202
+ if (statement.type === "Construct") {
4203
+ construct = statement;
4204
+ } else if (statement.type === "Destruct") {
4205
+ destruct = statement;
4206
+ }
4207
+ }
4208
+ return {
4209
+ ...construct ? { construct } : {},
4210
+ ...destruct ? { destruct } : {}
4211
+ };
4212
+ }
4213
+ extractOnBlocks(body) {
4214
+ const blocks = [];
4215
+ for (const statement of body.statements) {
4216
+ if (statement instanceof OnBlockNode) {
4217
+ blocks.push({
4218
+ event: statement.eventName,
4219
+ body: statement.body,
4220
+ modifiers: statement.modifiers,
4221
+ args: statement.args
4222
+ });
4223
+ }
4224
+ }
4225
+ return blocks;
4226
+ }
4227
+ extractDeclarations(body) {
4228
+ const declarations = [];
4229
+ for (const statement of body.statements) {
4230
+ if (statement instanceof DeclarationNode) {
4231
+ declarations.push(statement);
4232
+ }
4233
+ }
4234
+ return declarations;
4235
+ }
4236
+ extractFunctionDeclarations(body) {
4237
+ const functions = [];
4238
+ for (const statement of body.statements) {
4239
+ if (statement instanceof FunctionDeclarationNode) {
4240
+ functions.push({ name: statement.name, params: statement.params, body: statement.body });
4241
+ continue;
4242
+ }
4243
+ if (statement instanceof AssignmentNode) {
4244
+ if (statement.target instanceof IdentifierExpression && statement.value instanceof FunctionExpression) {
4245
+ functions.push({
4246
+ name: statement.target.name,
4247
+ params: statement.value.params,
4248
+ body: statement.value.body
4249
+ });
4250
+ }
4251
+ }
4252
+ }
4253
+ return functions;
4254
+ }
4255
+ getCachedBehavior(behavior) {
4256
+ const hash = this.hashBehavior(behavior);
4257
+ const cached = this.behaviorCache.get(hash);
4258
+ if (cached) {
4259
+ return cached;
4260
+ }
4261
+ const lifecycle = this.extractLifecycle(behavior.body);
4262
+ const fresh = {
4263
+ onBlocks: this.extractOnBlocks(behavior.body),
4264
+ declarations: this.extractDeclarations(behavior.body),
4265
+ functions: this.extractFunctionDeclarations(behavior.body),
4266
+ ...lifecycle
4267
+ };
4268
+ this.behaviorCache.set(hash, fresh);
4269
+ return fresh;
4270
+ }
4271
+ hashBehavior(behavior) {
4272
+ const normalized = this.normalizeNode(behavior);
4273
+ const json = JSON.stringify(normalized);
4274
+ return this.hashString(json);
4275
+ }
4276
+ normalizeNode(node) {
4277
+ if (!node || typeof node !== "object") {
4278
+ return node;
4279
+ }
4280
+ const type = node.type ?? "Unknown";
4281
+ if (type === "Behavior") {
4282
+ return {
4283
+ type,
4284
+ selector: node.selector?.selectorText ?? "",
4285
+ body: this.normalizeNode(node.body)
4286
+ };
4287
+ }
4288
+ if (type === "Selector") {
4289
+ return { type, selectorText: node.selectorText ?? "" };
4290
+ }
4291
+ if (type === "Block" || type === "Construct" || type === "Destruct") {
4292
+ return {
4293
+ type,
4294
+ statements: Array.isArray(node.statements) ? node.statements.map((statement) => this.normalizeNode(statement)) : []
4295
+ };
4296
+ }
4297
+ if (type === "OnBlock") {
4298
+ return {
4299
+ type,
4300
+ eventName: node.eventName ?? "",
4301
+ args: Array.isArray(node.args) ? node.args : [],
4302
+ body: this.normalizeNode(node.body)
4303
+ };
4304
+ }
4305
+ if (type === "Declaration") {
4306
+ return {
4307
+ type,
4308
+ target: this.normalizeNode(node.target),
4309
+ operator: node.operator ?? "",
4310
+ value: this.normalizeNode(node.value),
4311
+ flags: node.flags ?? {},
4312
+ flagArgs: node.flagArgs ?? {}
4313
+ };
4314
+ }
4315
+ if (type === "Assignment") {
4316
+ return {
4317
+ type,
4318
+ target: this.normalizeNode(node.target),
4319
+ value: this.normalizeNode(node.value)
4320
+ };
4321
+ }
4322
+ if (type === "StateBlock") {
4323
+ return {
4324
+ type,
4325
+ entries: Array.isArray(node.entries) ? node.entries.map((entry) => this.normalizeNode(entry)) : []
4326
+ };
4327
+ }
4328
+ if (type === "StateEntry") {
4329
+ return {
4330
+ type,
4331
+ name: node.name ?? "",
4332
+ value: this.normalizeNode(node.value),
4333
+ important: Boolean(node.important)
4334
+ };
4335
+ }
4336
+ if (type === "FunctionDeclaration") {
4337
+ return {
4338
+ type,
4339
+ name: node.name ?? "",
4340
+ params: Array.isArray(node.params) ? node.params.map((param) => ({
4341
+ name: param?.name ?? "",
4342
+ rest: Boolean(param?.rest),
4343
+ defaultValue: this.normalizeNode(param?.defaultValue ?? null)
4344
+ })) : [],
4345
+ body: this.normalizeNode(node.body),
4346
+ isAsync: Boolean(node.isAsync)
4347
+ };
4348
+ }
4349
+ if (type === "FunctionExpression") {
4350
+ return {
4351
+ type,
4352
+ params: Array.isArray(node.params) ? node.params.map((param) => ({
4353
+ name: param?.name ?? "",
4354
+ rest: Boolean(param?.rest),
4355
+ defaultValue: this.normalizeNode(param?.defaultValue ?? null)
4356
+ })) : [],
4357
+ body: this.normalizeNode(node.body),
4358
+ isAsync: Boolean(node.isAsync)
4359
+ };
4360
+ }
4361
+ if (type === "Return") {
4362
+ return {
4363
+ type,
4364
+ value: this.normalizeNode(node.value ?? null)
4365
+ };
4366
+ }
4367
+ if (type === "If") {
4368
+ return {
4369
+ type,
4370
+ test: this.normalizeNode(node.test),
4371
+ consequent: this.normalizeNode(node.consequent),
4372
+ alternate: this.normalizeNode(node.alternate ?? null)
4373
+ };
4374
+ }
4375
+ if (type === "While") {
4376
+ return {
4377
+ type,
4378
+ test: this.normalizeNode(node.test),
4379
+ body: this.normalizeNode(node.body)
4380
+ };
4381
+ }
4382
+ if (type === "For") {
4383
+ return {
4384
+ type,
4385
+ init: this.normalizeNode(node.init ?? null),
4386
+ test: this.normalizeNode(node.test ?? null),
4387
+ update: this.normalizeNode(node.update ?? null),
4388
+ body: this.normalizeNode(node.body)
4389
+ };
4390
+ }
4391
+ if (type === "Try") {
4392
+ return {
4393
+ type,
4394
+ errorName: node.errorName ?? "",
4395
+ body: this.normalizeNode(node.body),
4396
+ handler: this.normalizeNode(node.handler)
4397
+ };
4398
+ }
4399
+ if (type === "Identifier") {
4400
+ return { type, name: node.name ?? "" };
4401
+ }
4402
+ if (type === "Literal") {
4403
+ return { type, value: node.value };
4404
+ }
4405
+ if (type === "TemplateExpression") {
4406
+ return {
4407
+ type,
4408
+ parts: Array.isArray(node.parts) ? node.parts.map((part) => this.normalizeNode(part)) : []
4409
+ };
4410
+ }
4411
+ if (type === "UnaryExpression") {
4412
+ return {
4413
+ type,
4414
+ operator: node.operator ?? "",
4415
+ argument: this.normalizeNode(node.argument)
4416
+ };
4417
+ }
4418
+ if (type === "BinaryExpression") {
4419
+ return {
4420
+ type,
4421
+ operator: node.operator ?? "",
4422
+ left: this.normalizeNode(node.left),
4423
+ right: this.normalizeNode(node.right)
4424
+ };
4425
+ }
4426
+ if (type === "TernaryExpression") {
4427
+ return {
4428
+ type,
4429
+ test: this.normalizeNode(node.test),
4430
+ consequent: this.normalizeNode(node.consequent),
4431
+ alternate: this.normalizeNode(node.alternate)
4432
+ };
4433
+ }
4434
+ if (type === "MemberExpression") {
4435
+ return {
4436
+ type,
4437
+ target: this.normalizeNode(node.target),
4438
+ property: node.property ?? "",
4439
+ optional: Boolean(node.optional)
4440
+ };
4441
+ }
4442
+ if (type === "CallExpression") {
4443
+ return {
4444
+ type,
4445
+ callee: this.normalizeNode(node.callee),
4446
+ args: Array.isArray(node.args) ? node.args.map((arg) => this.normalizeNode(arg)) : []
4447
+ };
4448
+ }
4449
+ if (type === "AwaitExpression") {
4450
+ return {
4451
+ type,
4452
+ argument: this.normalizeNode(node.argument)
4453
+ };
4454
+ }
4455
+ if (type === "Directive") {
4456
+ return { type, kind: node.kind ?? "", name: node.name ?? "" };
4457
+ }
4458
+ if (type === "Query") {
4459
+ return { type, direction: node.direction ?? "", selector: node.selector ?? "" };
4460
+ }
4461
+ if (type === "ArrayExpression") {
4462
+ return {
4463
+ type,
4464
+ elements: Array.isArray(node.elements) ? node.elements.map((element) => this.normalizeNode(element)) : []
4465
+ };
4466
+ }
4467
+ if (type === "ObjectExpression") {
4468
+ return {
4469
+ type,
4470
+ entries: Array.isArray(node.entries) ? node.entries.map((entry) => ({
4471
+ key: entry?.key ?? "",
4472
+ computed: Boolean(entry?.computed),
4473
+ keyExpr: entry?.keyExpr ? this.normalizeNode(entry.keyExpr) : null,
4474
+ value: this.normalizeNode(entry?.value)
4475
+ })) : []
4476
+ };
4477
+ }
4478
+ if (type === "IndexExpression") {
4479
+ return {
4480
+ type,
4481
+ target: this.normalizeNode(node.target),
4482
+ index: this.normalizeNode(node.index)
4483
+ };
4484
+ }
4485
+ return { type };
4486
+ }
4487
+ hashString(value) {
4488
+ let hash = 5381;
4489
+ for (let i = 0; i < value.length; i += 1) {
4490
+ hash = (hash << 5) + hash + value.charCodeAt(i);
4491
+ hash |= 0;
4492
+ }
4493
+ return (hash >>> 0).toString(16);
4494
+ }
4495
+ applyBehaviorFunctions(element, scope, functions, rootScope) {
4496
+ for (const declaration of functions) {
4497
+ this.applyBehaviorFunction(element, scope, declaration, rootScope);
4498
+ }
4499
+ }
4500
+ applyBehaviorFunction(element, scope, declaration, rootScope) {
4501
+ const existing = scope.getPath(declaration.name);
4502
+ if (existing !== void 0 && typeof existing !== "function") {
4503
+ throw new Error(`Cannot override non-function '${declaration.name}' with a function`);
4504
+ }
4505
+ const fn = async (...args) => {
4506
+ const callScope = scope.createChild ? scope.createChild() : scope;
4507
+ const context = {
4508
+ scope: callScope,
4509
+ rootScope: rootScope ?? callScope,
4510
+ globals: this.globals,
4511
+ element,
4512
+ returnValue: void 0,
4513
+ returning: false
4514
+ };
4515
+ const previousValues = /* @__PURE__ */ new Map();
4516
+ await this.applyFunctionParams(callScope, declaration.params, previousValues, context, args);
4517
+ await declaration.body.evaluate(context);
4518
+ if (callScope === scope) {
4519
+ this.restoreFunctionParams(callScope, declaration.params, previousValues);
4520
+ }
4521
+ return context.returnValue;
4522
+ };
4523
+ scope.setPath(declaration.name, fn);
4524
+ }
4525
+ async applyFunctionParams(scope, params, previousValues, context, args) {
4526
+ let argIndex = 0;
4527
+ for (const param of params) {
4528
+ const name = param.name;
4529
+ if (!name) {
4530
+ continue;
4531
+ }
4532
+ previousValues.set(name, scope.getPath(name));
4533
+ if (param.rest) {
4534
+ scope.setPath(`self.${name}`, args.slice(argIndex));
4535
+ argIndex = args.length;
4536
+ continue;
4537
+ }
4538
+ let value = args[argIndex];
4539
+ if (value === void 0 && param.defaultValue) {
4540
+ value = await param.defaultValue.evaluate(context);
4541
+ }
4542
+ scope.setPath(`self.${name}`, value);
4543
+ argIndex += 1;
4544
+ }
4545
+ }
4546
+ restoreFunctionParams(scope, params, previousValues) {
4547
+ for (const param of params) {
4548
+ const name = param.name;
4549
+ if (!name) {
4550
+ continue;
4551
+ }
4552
+ scope.setPath(name, previousValues.get(name));
4553
+ }
4554
+ }
4555
+ async applyBehaviorDeclarations(element, scope, declarations, rootScope) {
4556
+ for (const declaration of declarations) {
4557
+ await this.applyBehaviorDeclaration(element, scope, declaration, rootScope);
4558
+ }
4559
+ }
4560
+ async applyBehaviorDeclaration(element, scope, declaration, rootScope) {
4561
+ const context = { scope, rootScope, element };
4562
+ const operator = declaration.operator;
4563
+ const debounceMs = declaration.flags.debounce ? declaration.flagArgs.debounce ?? 200 : void 0;
4564
+ const importantKey = this.getImportantKey(declaration);
4565
+ if (!declaration.flags.important && importantKey && this.isImportant(element, importantKey)) {
4566
+ return;
4567
+ }
4568
+ if (importantKey && this.isInlineDeclaration(element, importantKey)) {
4569
+ return;
4570
+ }
4571
+ this.applyCustomFlags(element, scope, declaration);
4572
+ if (declaration.target instanceof IdentifierExpression) {
4573
+ const value = await declaration.value.evaluate(context);
4574
+ scope.setPath(declaration.target.name, value);
4575
+ if (declaration.flags.important && importantKey) {
4576
+ this.markImportant(element, importantKey);
4577
+ }
4578
+ return;
4579
+ }
4580
+ if (!(declaration.target instanceof DirectiveExpression)) {
4581
+ return;
4582
+ }
4583
+ const target = declaration.target;
4584
+ const exprIdentifier = declaration.value instanceof IdentifierExpression ? declaration.value.name : void 0;
4585
+ if (operator === ":>") {
4586
+ if (exprIdentifier) {
4587
+ this.applyDirectiveToScope(element, target, exprIdentifier, scope, debounceMs, rootScope);
4588
+ }
4589
+ if (declaration.flags.important && importantKey) {
4590
+ this.markImportant(element, importantKey);
4591
+ }
4592
+ return;
4593
+ }
4594
+ if (operator === ":=" && exprIdentifier) {
4595
+ this.applyDirectiveToScope(element, target, exprIdentifier, scope, debounceMs, rootScope);
4596
+ }
4597
+ if (!exprIdentifier) {
4598
+ const value = await declaration.value.evaluate(context);
4599
+ this.setDirectiveValue(element, target, value, declaration.flags.trusted);
4600
+ const shouldWatch2 = operator === ":<" || operator === ":=";
4601
+ if (shouldWatch2) {
4602
+ this.applyDirectiveFromExpression(
4603
+ element,
4604
+ target,
4605
+ declaration.value,
4606
+ scope,
4607
+ declaration.flags.trusted,
4608
+ debounceMs,
4609
+ rootScope
4610
+ );
4611
+ }
4612
+ if (declaration.flags.important && importantKey) {
4613
+ this.markImportant(element, importantKey);
4614
+ }
4615
+ return;
4616
+ }
4617
+ const shouldWatch = operator === ":<" || operator === ":=";
4618
+ this.applyDirectiveFromScope(
4619
+ element,
4620
+ target,
4621
+ exprIdentifier,
4622
+ scope,
4623
+ declaration.flags.trusted,
4624
+ debounceMs,
4625
+ shouldWatch,
4626
+ rootScope
4627
+ );
4628
+ if (declaration.flags.important && importantKey) {
4629
+ this.markImportant(element, importantKey);
4630
+ }
4631
+ }
4632
+ applyCustomFlags(element, scope, declaration) {
4633
+ if (this.flagHandlers.size === 0) {
4634
+ return;
4635
+ }
4636
+ for (const [name, handler] of this.flagHandlers) {
4637
+ if (!declaration.flags[name]) {
4638
+ continue;
4639
+ }
4640
+ handler.onApply?.({
4641
+ name,
4642
+ args: declaration.flagArgs[name],
4643
+ element,
4644
+ scope,
4645
+ declaration
4646
+ });
4647
+ }
4648
+ }
4649
+ applyDirectiveFromScope(element, target, expr, scope, trusted, debounceMs, watch = true, rootScope) {
4650
+ if (target.kind === "attr" && target.name === "html" && element instanceof HTMLElement) {
4651
+ const handler2 = () => {
4652
+ const useRoot = expr.startsWith("root.") && rootScope;
4653
+ const sourceScope = useRoot ? rootScope : scope;
4654
+ const localExpr = useRoot ? `self.${expr.slice("root.".length)}` : expr;
4655
+ applyHtml(element, localExpr, sourceScope, Boolean(trusted));
4656
+ };
4657
+ handler2();
4658
+ if (trusted) {
4659
+ this.handleTrustedHtml(element);
4660
+ }
4661
+ if (watch) {
4662
+ const useRoot = expr.startsWith("root.") && rootScope;
4663
+ const sourceScope = useRoot ? rootScope : scope;
4664
+ const watchExpr = useRoot ? expr.slice("root.".length) : expr;
4665
+ this.watchWithDebounce(sourceScope, watchExpr, handler2, debounceMs);
4666
+ }
4667
+ return;
4668
+ }
4669
+ const handler = () => {
4670
+ const useRoot = expr.startsWith("root.") && rootScope;
4671
+ const sourceScope = useRoot ? rootScope : scope;
4672
+ const localExpr = useRoot ? `self.${expr.slice("root.".length)}` : expr;
4673
+ const value = sourceScope.get(localExpr);
4674
+ if (value == null) {
4675
+ return;
4676
+ }
4677
+ this.setDirectiveValue(element, target, value, trusted);
4678
+ };
4679
+ handler();
4680
+ if (watch) {
4681
+ const useRoot = expr.startsWith("root.") && rootScope;
4682
+ const sourceScope = useRoot ? rootScope : scope;
4683
+ const watchExpr = useRoot ? expr.slice("root.".length) : expr;
4684
+ this.watchWithDebounce(sourceScope, watchExpr, handler, debounceMs);
4685
+ }
4686
+ }
4687
+ applyDirectiveFromExpression(element, target, expr, scope, trusted, debounceMs, rootScope) {
4688
+ const handler = async () => {
4689
+ const context = { scope, rootScope, element };
4690
+ const value = await expr.evaluate(context);
4691
+ this.setDirectiveValue(element, target, value, trusted);
4692
+ };
4693
+ void handler();
4694
+ this.watchAllScopes(scope, () => {
4695
+ void handler();
4696
+ }, debounceMs);
4697
+ }
4698
+ applyDirectiveToScope(element, target, expr, scope, debounceMs, rootScope) {
4699
+ const useRoot = expr.startsWith("root.") && rootScope;
4700
+ const targetScope = useRoot ? rootScope : scope;
4701
+ const targetExpr = useRoot ? `self.${expr.slice("root.".length)}` : expr;
4702
+ if (target.kind === "attr" && target.name === "value") {
4703
+ this.applyValueBindingToScope(element, targetExpr, debounceMs, targetScope);
4704
+ return;
4705
+ }
4706
+ if (target.kind === "attr" && target.name === "checked") {
4707
+ this.applyCheckedBindingToScope(element, targetExpr, debounceMs, targetScope);
4708
+ return;
4709
+ }
4710
+ const value = this.getDirectiveValue(element, target);
4711
+ if (value != null) {
4712
+ targetScope.set(targetExpr, value);
4713
+ }
4714
+ }
4715
+ applyCheckedBindingToScope(element, expr, debounceMs, scope) {
4716
+ if (!(element instanceof HTMLInputElement)) {
4717
+ return;
4718
+ }
4719
+ const handler = () => {
4720
+ const targetScope = scope ?? this.getScope(element);
4721
+ targetScope.set(expr, element.checked);
4722
+ };
4723
+ const effectiveHandler = debounceMs ? debounce(handler, debounceMs) : handler;
4724
+ effectiveHandler();
4725
+ element.addEventListener("change", effectiveHandler);
4726
+ element.addEventListener("input", effectiveHandler);
4727
+ }
4728
+ applyValueBindingToScope(element, expr, debounceMs, scope) {
4729
+ if (!(element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement || element instanceof HTMLSelectElement)) {
4730
+ return;
4731
+ }
4732
+ const handler = () => {
4733
+ const targetScope = scope ?? this.getScope(element);
4734
+ applyBindToScope(element, expr, targetScope);
4735
+ };
4736
+ const effectiveHandler = debounceMs ? debounce(handler, debounceMs) : handler;
4737
+ effectiveHandler();
4738
+ element.addEventListener("input", effectiveHandler);
4739
+ element.addEventListener("change", effectiveHandler);
4740
+ }
4741
+ setDirectiveValue(element, target, value, trusted) {
4742
+ if (target.kind === "attr" && target.name === "html" && element instanceof HTMLElement) {
4743
+ const html = value == null ? "" : String(value);
4744
+ element.innerHTML = trusted ? html : html.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gi, "");
4745
+ if (trusted) {
4746
+ this.handleTrustedHtml(element);
4747
+ }
4748
+ return;
4749
+ }
4750
+ if (target.kind === "attr") {
4751
+ if (target.name === "value") {
4752
+ if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement) {
4753
+ element.value = value == null ? "" : String(value);
4754
+ element.setAttribute("value", element.value);
4755
+ return;
4756
+ }
4757
+ if (element instanceof HTMLSelectElement) {
4758
+ element.value = value == null ? "" : String(value);
4759
+ return;
4760
+ }
4761
+ }
4762
+ if (target.name === "checked" && element instanceof HTMLInputElement) {
4763
+ const checked = value === true || value === "true" || value === 1 || value === "1";
4764
+ element.checked = checked;
4765
+ if (checked) {
4766
+ element.setAttribute("checked", "");
4767
+ } else {
4768
+ element.removeAttribute("checked");
4769
+ }
4770
+ return;
4771
+ }
4772
+ element.setAttribute(target.name, value == null ? "" : String(value));
4773
+ return;
4774
+ }
4775
+ if (target.kind === "style" && element instanceof HTMLElement) {
4776
+ element.style.setProperty(target.name, value == null ? "" : String(value));
4777
+ }
4778
+ }
4779
+ getDirectiveValue(element, target) {
4780
+ if (target.kind === "attr") {
4781
+ if (target.name === "value") {
4782
+ if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement) {
4783
+ return element.value;
4784
+ }
4785
+ if (element instanceof HTMLSelectElement) {
4786
+ return element.value;
4787
+ }
4788
+ }
4789
+ if (target.name === "checked" && element instanceof HTMLInputElement) {
4790
+ return element.checked;
4791
+ }
4792
+ return element.getAttribute(target.name) ?? void 0;
4793
+ }
4794
+ if (target.kind === "style" && element instanceof HTMLElement) {
4795
+ return element.style.getPropertyValue(target.name) ?? void 0;
4796
+ }
4797
+ return void 0;
4798
+ }
4799
+ handleTrustedHtml(root) {
4800
+ const scripts = Array.from(root.querySelectorAll('script[type="text/vsn"]'));
4801
+ if (scripts.length === 0) {
4802
+ return;
4803
+ }
4804
+ const source = scripts.map((script) => script.textContent ?? "").join("\n");
4805
+ if (!source.trim()) {
4806
+ return;
4807
+ }
4808
+ this.registerBehaviors(source);
4809
+ void this.applyBehaviors(root);
4810
+ }
4811
+ registerDefaultAttributeHandlers() {
4812
+ this.registerAttributeHandler({
4813
+ id: "vsn-bind",
4814
+ match: (name) => name.startsWith("vsn-bind"),
4815
+ handle: (element, name, value, scope) => {
4816
+ const direction = this.parseBindDirection(name);
4817
+ this.bindBindings.set(element, { expr: value, direction });
4818
+ if (direction === "to" || direction === "both") {
4819
+ this.markInlineDeclaration(element, `state:${value}`);
4820
+ }
4821
+ if (direction === "to" || direction === "both") {
4822
+ applyBindToScope(element, value, scope);
4823
+ this.attachBindInputHandler(element, value);
4824
+ }
4825
+ if (direction === "from" || direction === "both") {
4826
+ this.watch(scope, value, () => applyBindToElement(element, value, scope));
4827
+ }
4828
+ }
4829
+ });
4830
+ this.registerAttributeHandler({
4831
+ id: "vsn-if",
4832
+ match: (name) => name === "vsn-if",
4833
+ handle: (element, _name, value, scope) => {
4834
+ this.ifBindings.set(element, value);
4835
+ if (element instanceof HTMLElement) {
4836
+ applyIf(element, value, scope);
4837
+ }
4838
+ this.watch(scope, value, () => this.evaluate(element));
4839
+ }
4840
+ });
4841
+ this.registerAttributeHandler({
4842
+ id: "vsn-show",
4843
+ match: (name) => name === "vsn-show",
4844
+ handle: (element, _name, value, scope) => {
4845
+ this.showBindings.set(element, value);
4846
+ if (element instanceof HTMLElement) {
4847
+ applyShow(element, value, scope);
4848
+ }
4849
+ this.watch(scope, value, () => this.evaluate(element));
4850
+ }
4851
+ });
4852
+ this.registerAttributeHandler({
4853
+ id: "vsn-html",
4854
+ match: (name) => name.startsWith("vsn-html"),
4855
+ handle: (element, name, value, scope) => {
4856
+ const trusted = name.includes("!trusted");
4857
+ this.htmlBindings.set(element, { expr: value, trusted });
4858
+ this.markInlineDeclaration(element, "attr:html");
4859
+ if (element instanceof HTMLElement) {
4860
+ applyHtml(element, value, scope, trusted);
4861
+ if (trusted) {
4862
+ this.handleTrustedHtml(element);
4863
+ }
4864
+ }
4865
+ this.watch(scope, value, () => this.evaluate(element));
4866
+ }
4867
+ });
4868
+ this.registerAttributeHandler({
4869
+ id: "vsn-each",
4870
+ match: (name) => name === "vsn-each",
4871
+ handle: (element, _name, value, scope) => {
4872
+ const config = this.parseEachExpression(value);
4873
+ if (!config) {
4874
+ return;
4875
+ }
4876
+ this.eachBindings.set(element, { ...config, rendered: [] });
4877
+ this.renderEach(element);
4878
+ this.watch(scope, config.listExpr, () => this.renderEach(element));
4879
+ }
4880
+ });
4881
+ this.registerAttributeHandler({
4882
+ id: "vsn-get",
4883
+ match: (name) => name.startsWith("vsn-get"),
4884
+ handle: (element, name) => {
4885
+ const trusted = name.includes("!trusted");
4886
+ const autoLoad = name.includes("!load");
4887
+ const url = element.getAttribute(name) ?? "";
4888
+ const target = element.getAttribute("vsn-target") ?? void 0;
4889
+ const swap = element.getAttribute("vsn-swap") ?? "inner";
4890
+ const config = {
4891
+ url,
4892
+ swap,
4893
+ trusted,
4894
+ ...target ? { targetSelector: target } : {}
4895
+ };
4896
+ this.getBindings.set(element, config);
4897
+ this.attachGetHandler(element, autoLoad);
4898
+ }
4899
+ });
4900
+ this.registerAttributeHandler({
4901
+ id: "vsn-construct",
4902
+ match: (name) => name === "vsn-construct",
4903
+ handle: (element, _name, value) => {
4904
+ this.setLifecycle(element, { construct: value });
4905
+ }
4906
+ });
4907
+ this.registerAttributeHandler({
4908
+ id: "vsn-destruct",
4909
+ match: (name) => name === "vsn-destruct",
4910
+ handle: (element, _name, value) => {
4911
+ this.setLifecycle(element, { destruct: value });
4912
+ }
4913
+ });
4914
+ this.registerAttributeHandler({
4915
+ id: "vsn-on",
4916
+ match: (name) => name.startsWith("vsn-on:"),
4917
+ handle: (element, name, value) => {
4918
+ const onConfig = this.parseOnAttribute(name, value);
4919
+ if (onConfig) {
4920
+ this.attachOnHandler(element, onConfig);
4921
+ }
4922
+ }
4923
+ });
4924
+ }
4925
+ };
4926
+
4927
+ // src/index.ts
4928
+ var VERSION = "0.1.0";
4929
+ function parseCFS(source) {
4930
+ const parser = new Parser(source);
4931
+ return parser.parseProgram();
4932
+ }
4933
+ function autoMount(root = document) {
4934
+ if (typeof document === "undefined") {
4935
+ return null;
4936
+ }
4937
+ const engine = new Engine();
4938
+ const startTime = typeof performance !== "undefined" && performance.now ? performance.now() : Date.now();
4939
+ const mount = () => {
4940
+ const target = root instanceof Document ? root.body : root;
4941
+ if (target) {
4942
+ const sources = Array.from(document.querySelectorAll('script[type="text/vsn"]')).map((script) => script.textContent ?? "").join("\n");
4943
+ if (sources.trim()) {
4944
+ engine.registerBehaviors(sources);
4945
+ }
4946
+ engine.mount(target);
4947
+ const endTime = typeof performance !== "undefined" && performance.now ? performance.now() : Date.now();
4948
+ const elapsedMs = Math.round(endTime - startTime);
4949
+ console.log(`Took ${elapsedMs}ms to start up VSN.js. https://www.vsnjs.com/ v${VERSION}`);
4950
+ }
4951
+ };
4952
+ if (document.readyState === "loading") {
4953
+ document.addEventListener("DOMContentLoaded", mount, { once: true });
4954
+ } else {
4955
+ mount();
4956
+ }
4957
+ return engine;
4958
+ }
4959
+ if (typeof document !== "undefined") {
4960
+ const scriptTag = document.querySelector("script[auto-mount]");
4961
+ if (scriptTag) {
4962
+ autoMount();
4963
+ }
4964
+ }
4965
+ // Annotate the CommonJS export names for ESM import in node:
4966
+ 0 && (module.exports = {
4967
+ ArrayExpression,
4968
+ ArrayPattern,
4969
+ AssignmentNode,
4970
+ AwaitExpression,
4971
+ BaseNode,
4972
+ BehaviorNode,
4973
+ BinaryExpression,
4974
+ BlockNode,
4975
+ CallExpression,
4976
+ DeclarationNode,
4977
+ DirectiveExpression,
4978
+ Engine,
4979
+ ForNode,
4980
+ FunctionDeclarationNode,
4981
+ FunctionExpression,
4982
+ IdentifierExpression,
4983
+ IfNode,
4984
+ IndexExpression,
4985
+ Lexer,
4986
+ LiteralExpression,
4987
+ MemberExpression,
4988
+ ObjectExpression,
4989
+ ObjectPattern,
4990
+ OnBlockNode,
4991
+ Parser,
4992
+ ProgramNode,
4993
+ QueryExpression,
4994
+ RestElement,
4995
+ ReturnNode,
4996
+ SelectorNode,
4997
+ SpreadElement,
4998
+ StateBlockNode,
4999
+ StateEntryNode,
5000
+ TemplateExpression,
5001
+ TernaryExpression,
5002
+ TokenType,
5003
+ TryNode,
5004
+ UnaryExpression,
5005
+ UseNode,
5006
+ VERSION,
5007
+ WhileNode,
5008
+ autoMount,
5009
+ parseCFS
5010
+ });
5011
+ //# sourceMappingURL=index.cjs.map