@lokascript/semantic 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 (435) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +686 -0
  3. package/dist/browser-ar.ar.global.js +2 -0
  4. package/dist/browser-core.core.global.js +2 -0
  5. package/dist/browser-de.de.global.js +2 -0
  6. package/dist/browser-east-asian.east-asian.global.js +2 -0
  7. package/dist/browser-en-tr.en-tr.global.js +2 -0
  8. package/dist/browser-en.en.global.js +2 -0
  9. package/dist/browser-es-en.es-en.global.js +2 -0
  10. package/dist/browser-es.es.global.js +2 -0
  11. package/dist/browser-fr.fr.global.js +2 -0
  12. package/dist/browser-id.id.global.js +2 -0
  13. package/dist/browser-ja.ja.global.js +2 -0
  14. package/dist/browser-ko.ko.global.js +2 -0
  15. package/dist/browser-lazy.lazy.global.js +2 -0
  16. package/dist/browser-priority.priority.global.js +2 -0
  17. package/dist/browser-pt.pt.global.js +2 -0
  18. package/dist/browser-qu.qu.global.js +2 -0
  19. package/dist/browser-sw.sw.global.js +2 -0
  20. package/dist/browser-tr.tr.global.js +2 -0
  21. package/dist/browser-western.western.global.js +2 -0
  22. package/dist/browser-zh.zh.global.js +2 -0
  23. package/dist/browser.global.js +3 -0
  24. package/dist/browser.global.js.map +1 -0
  25. package/dist/index.cjs +35051 -0
  26. package/dist/index.cjs.map +1 -0
  27. package/dist/index.d.cts +3426 -0
  28. package/dist/index.d.ts +3426 -0
  29. package/dist/index.js +34890 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/languages/ar.d.ts +78 -0
  32. package/dist/languages/ar.js +1622 -0
  33. package/dist/languages/ar.js.map +1 -0
  34. package/dist/languages/de.d.ts +38 -0
  35. package/dist/languages/de.js +1168 -0
  36. package/dist/languages/de.js.map +1 -0
  37. package/dist/languages/en.d.ts +44 -0
  38. package/dist/languages/en.js +3491 -0
  39. package/dist/languages/en.js.map +1 -0
  40. package/dist/languages/es.d.ts +52 -0
  41. package/dist/languages/es.js +1493 -0
  42. package/dist/languages/es.js.map +1 -0
  43. package/dist/languages/fr.d.ts +37 -0
  44. package/dist/languages/fr.js +1159 -0
  45. package/dist/languages/fr.js.map +1 -0
  46. package/dist/languages/id.d.ts +35 -0
  47. package/dist/languages/id.js +1152 -0
  48. package/dist/languages/id.js.map +1 -0
  49. package/dist/languages/ja.d.ts +53 -0
  50. package/dist/languages/ja.js +1430 -0
  51. package/dist/languages/ja.js.map +1 -0
  52. package/dist/languages/ko.d.ts +51 -0
  53. package/dist/languages/ko.js +1729 -0
  54. package/dist/languages/ko.js.map +1 -0
  55. package/dist/languages/pt.d.ts +37 -0
  56. package/dist/languages/pt.js +1127 -0
  57. package/dist/languages/pt.js.map +1 -0
  58. package/dist/languages/qu.d.ts +36 -0
  59. package/dist/languages/qu.js +1143 -0
  60. package/dist/languages/qu.js.map +1 -0
  61. package/dist/languages/sw.d.ts +35 -0
  62. package/dist/languages/sw.js +1147 -0
  63. package/dist/languages/sw.js.map +1 -0
  64. package/dist/languages/tr.d.ts +45 -0
  65. package/dist/languages/tr.js +1529 -0
  66. package/dist/languages/tr.js.map +1 -0
  67. package/dist/languages/zh.d.ts +58 -0
  68. package/dist/languages/zh.js +1257 -0
  69. package/dist/languages/zh.js.map +1 -0
  70. package/dist/types-C4dcj53L.d.ts +600 -0
  71. package/package.json +202 -0
  72. package/src/__test-utils__/index.ts +7 -0
  73. package/src/__test-utils__/test-helpers.ts +8 -0
  74. package/src/__types__/test-helpers.ts +122 -0
  75. package/src/analysis/index.ts +479 -0
  76. package/src/ast-builder/command-mappers.ts +1133 -0
  77. package/src/ast-builder/expression-parser/index.ts +41 -0
  78. package/src/ast-builder/expression-parser/parser.ts +563 -0
  79. package/src/ast-builder/expression-parser/tokenizer.ts +394 -0
  80. package/src/ast-builder/expression-parser/types.ts +208 -0
  81. package/src/ast-builder/index.ts +536 -0
  82. package/src/ast-builder/value-converters.ts +172 -0
  83. package/src/bridge.ts +275 -0
  84. package/src/browser-ar.ts +162 -0
  85. package/src/browser-core.ts +231 -0
  86. package/src/browser-de.ts +162 -0
  87. package/src/browser-east-asian.ts +173 -0
  88. package/src/browser-en-tr.ts +165 -0
  89. package/src/browser-en.ts +157 -0
  90. package/src/browser-es-en.ts +200 -0
  91. package/src/browser-es.ts +170 -0
  92. package/src/browser-fr.ts +162 -0
  93. package/src/browser-id.ts +162 -0
  94. package/src/browser-ja.ts +162 -0
  95. package/src/browser-ko.ts +162 -0
  96. package/src/browser-lazy.ts +189 -0
  97. package/src/browser-priority.ts +214 -0
  98. package/src/browser-pt.ts +162 -0
  99. package/src/browser-qu.ts +162 -0
  100. package/src/browser-sw.ts +162 -0
  101. package/src/browser-tr.ts +162 -0
  102. package/src/browser-western.ts +181 -0
  103. package/src/browser-zh.ts +162 -0
  104. package/src/browser.ts +268 -0
  105. package/src/cache/index.ts +14 -0
  106. package/src/cache/semantic-cache.ts +344 -0
  107. package/src/core-bridge.ts +372 -0
  108. package/src/explicit/converter.ts +258 -0
  109. package/src/explicit/index.ts +18 -0
  110. package/src/explicit/parser.ts +236 -0
  111. package/src/explicit/renderer.ts +424 -0
  112. package/src/generators/command-schemas.ts +1636 -0
  113. package/src/generators/event-handler-generator.ts +109 -0
  114. package/src/generators/index.ts +117 -0
  115. package/src/generators/language-profiles.ts +139 -0
  116. package/src/generators/pattern-generator.ts +537 -0
  117. package/src/generators/profiles/arabic.ts +131 -0
  118. package/src/generators/profiles/bengali.ts +132 -0
  119. package/src/generators/profiles/chinese.ts +124 -0
  120. package/src/generators/profiles/english.ts +113 -0
  121. package/src/generators/profiles/french.ts +125 -0
  122. package/src/generators/profiles/german.ts +126 -0
  123. package/src/generators/profiles/hindi.ts +146 -0
  124. package/src/generators/profiles/index.ts +46 -0
  125. package/src/generators/profiles/indonesian.ts +125 -0
  126. package/src/generators/profiles/italian.ts +139 -0
  127. package/src/generators/profiles/japanese.ts +149 -0
  128. package/src/generators/profiles/korean.ts +127 -0
  129. package/src/generators/profiles/marker-templates.ts +288 -0
  130. package/src/generators/profiles/ms.ts +130 -0
  131. package/src/generators/profiles/polish.ts +249 -0
  132. package/src/generators/profiles/portuguese.ts +115 -0
  133. package/src/generators/profiles/quechua.ts +113 -0
  134. package/src/generators/profiles/russian.ts +260 -0
  135. package/src/generators/profiles/spanish.ts +130 -0
  136. package/src/generators/profiles/swahili.ts +129 -0
  137. package/src/generators/profiles/thai.ts +132 -0
  138. package/src/generators/profiles/tl.ts +128 -0
  139. package/src/generators/profiles/turkish.ts +124 -0
  140. package/src/generators/profiles/types.ts +165 -0
  141. package/src/generators/profiles/ukrainian.ts +270 -0
  142. package/src/generators/profiles/vietnamese.ts +133 -0
  143. package/src/generators/schema-error-codes.ts +160 -0
  144. package/src/generators/schema-validator.ts +391 -0
  145. package/src/index.ts +429 -0
  146. package/src/language-building-schema.ts +3170 -0
  147. package/src/language-loader.ts +394 -0
  148. package/src/languages/_all.ts +65 -0
  149. package/src/languages/ar.ts +15 -0
  150. package/src/languages/bn.ts +16 -0
  151. package/src/languages/de.ts +15 -0
  152. package/src/languages/en.ts +29 -0
  153. package/src/languages/es.ts +15 -0
  154. package/src/languages/fr.ts +15 -0
  155. package/src/languages/hi.ts +26 -0
  156. package/src/languages/id.ts +15 -0
  157. package/src/languages/index.ts +18 -0
  158. package/src/languages/it.ts +15 -0
  159. package/src/languages/ja.ts +15 -0
  160. package/src/languages/ko.ts +15 -0
  161. package/src/languages/ms.ts +16 -0
  162. package/src/languages/pl.ts +18 -0
  163. package/src/languages/pt.ts +15 -0
  164. package/src/languages/qu.ts +15 -0
  165. package/src/languages/ru.ts +26 -0
  166. package/src/languages/sw.ts +15 -0
  167. package/src/languages/th.ts +16 -0
  168. package/src/languages/tl.ts +16 -0
  169. package/src/languages/tr.ts +15 -0
  170. package/src/languages/uk.ts +26 -0
  171. package/src/languages/vi.ts +16 -0
  172. package/src/languages/zh.ts +15 -0
  173. package/src/parser/index.ts +15 -0
  174. package/src/parser/pattern-matcher.ts +1181 -0
  175. package/src/parser/semantic-parser.ts +573 -0
  176. package/src/parser/utils/index.ts +35 -0
  177. package/src/parser/utils/marker-resolution.ts +111 -0
  178. package/src/parser/utils/possessive-keywords.ts +43 -0
  179. package/src/parser/utils/role-positioning.ts +70 -0
  180. package/src/parser/utils/type-validation.ts +134 -0
  181. package/src/patterns/add/ar.ts +71 -0
  182. package/src/patterns/add/bn.ts +70 -0
  183. package/src/patterns/add/hi.ts +69 -0
  184. package/src/patterns/add/index.ts +87 -0
  185. package/src/patterns/add/it.ts +61 -0
  186. package/src/patterns/add/ja.ts +93 -0
  187. package/src/patterns/add/ko.ts +74 -0
  188. package/src/patterns/add/ms.ts +30 -0
  189. package/src/patterns/add/pl.ts +62 -0
  190. package/src/patterns/add/ru.ts +62 -0
  191. package/src/patterns/add/th.ts +49 -0
  192. package/src/patterns/add/tl.ts +30 -0
  193. package/src/patterns/add/tr.ts +71 -0
  194. package/src/patterns/add/uk.ts +62 -0
  195. package/src/patterns/add/vi.ts +61 -0
  196. package/src/patterns/add/zh.ts +71 -0
  197. package/src/patterns/builders.ts +207 -0
  198. package/src/patterns/decrement/bn.ts +70 -0
  199. package/src/patterns/decrement/de.ts +42 -0
  200. package/src/patterns/decrement/hi.ts +68 -0
  201. package/src/patterns/decrement/index.ts +79 -0
  202. package/src/patterns/decrement/it.ts +69 -0
  203. package/src/patterns/decrement/ms.ts +30 -0
  204. package/src/patterns/decrement/pl.ts +58 -0
  205. package/src/patterns/decrement/ru.ts +58 -0
  206. package/src/patterns/decrement/th.ts +49 -0
  207. package/src/patterns/decrement/tl.ts +30 -0
  208. package/src/patterns/decrement/tr.ts +48 -0
  209. package/src/patterns/decrement/uk.ts +58 -0
  210. package/src/patterns/decrement/vi.ts +61 -0
  211. package/src/patterns/decrement/zh.ts +32 -0
  212. package/src/patterns/en.ts +302 -0
  213. package/src/patterns/event-handler/ar.ts +151 -0
  214. package/src/patterns/event-handler/bn.ts +72 -0
  215. package/src/patterns/event-handler/de.ts +117 -0
  216. package/src/patterns/event-handler/en.ts +117 -0
  217. package/src/patterns/event-handler/es.ts +136 -0
  218. package/src/patterns/event-handler/fr.ts +117 -0
  219. package/src/patterns/event-handler/hi.ts +64 -0
  220. package/src/patterns/event-handler/id.ts +117 -0
  221. package/src/patterns/event-handler/index.ts +119 -0
  222. package/src/patterns/event-handler/it.ts +54 -0
  223. package/src/patterns/event-handler/ja.ts +118 -0
  224. package/src/patterns/event-handler/ko.ts +133 -0
  225. package/src/patterns/event-handler/ms.ts +30 -0
  226. package/src/patterns/event-handler/pl.ts +62 -0
  227. package/src/patterns/event-handler/pt.ts +117 -0
  228. package/src/patterns/event-handler/qu.ts +66 -0
  229. package/src/patterns/event-handler/ru.ts +62 -0
  230. package/src/patterns/event-handler/shared.ts +270 -0
  231. package/src/patterns/event-handler/sw.ts +117 -0
  232. package/src/patterns/event-handler/th.ts +53 -0
  233. package/src/patterns/event-handler/tl.ts +30 -0
  234. package/src/patterns/event-handler/tr.ts +170 -0
  235. package/src/patterns/event-handler/uk.ts +62 -0
  236. package/src/patterns/event-handler/vi.ts +61 -0
  237. package/src/patterns/event-handler/zh.ts +150 -0
  238. package/src/patterns/get/ar.ts +49 -0
  239. package/src/patterns/get/bn.ts +47 -0
  240. package/src/patterns/get/de.ts +32 -0
  241. package/src/patterns/get/hi.ts +52 -0
  242. package/src/patterns/get/index.ts +83 -0
  243. package/src/patterns/get/it.ts +56 -0
  244. package/src/patterns/get/ja.ts +53 -0
  245. package/src/patterns/get/ko.ts +53 -0
  246. package/src/patterns/get/ms.ts +30 -0
  247. package/src/patterns/get/pl.ts +57 -0
  248. package/src/patterns/get/ru.ts +57 -0
  249. package/src/patterns/get/th.ts +29 -0
  250. package/src/patterns/get/tl.ts +30 -0
  251. package/src/patterns/get/uk.ts +57 -0
  252. package/src/patterns/get/vi.ts +48 -0
  253. package/src/patterns/grammar-transformed/index.ts +39 -0
  254. package/src/patterns/grammar-transformed/ja.ts +1713 -0
  255. package/src/patterns/grammar-transformed/ko.ts +1311 -0
  256. package/src/patterns/grammar-transformed/tr.ts +1067 -0
  257. package/src/patterns/hide/ar.ts +67 -0
  258. package/src/patterns/hide/bn.ts +47 -0
  259. package/src/patterns/hide/de.ts +36 -0
  260. package/src/patterns/hide/hi.ts +61 -0
  261. package/src/patterns/hide/index.ts +91 -0
  262. package/src/patterns/hide/it.ts +56 -0
  263. package/src/patterns/hide/ja.ts +69 -0
  264. package/src/patterns/hide/ko.ts +69 -0
  265. package/src/patterns/hide/ms.ts +30 -0
  266. package/src/patterns/hide/pl.ts +57 -0
  267. package/src/patterns/hide/ru.ts +57 -0
  268. package/src/patterns/hide/th.ts +29 -0
  269. package/src/patterns/hide/tl.ts +30 -0
  270. package/src/patterns/hide/tr.ts +65 -0
  271. package/src/patterns/hide/uk.ts +57 -0
  272. package/src/patterns/hide/vi.ts +56 -0
  273. package/src/patterns/hide/zh.ts +68 -0
  274. package/src/patterns/increment/bn.ts +70 -0
  275. package/src/patterns/increment/de.ts +36 -0
  276. package/src/patterns/increment/hi.ts +68 -0
  277. package/src/patterns/increment/index.ts +79 -0
  278. package/src/patterns/increment/it.ts +69 -0
  279. package/src/patterns/increment/ms.ts +30 -0
  280. package/src/patterns/increment/pl.ts +58 -0
  281. package/src/patterns/increment/ru.ts +58 -0
  282. package/src/patterns/increment/th.ts +49 -0
  283. package/src/patterns/increment/tl.ts +30 -0
  284. package/src/patterns/increment/tr.ts +52 -0
  285. package/src/patterns/increment/uk.ts +58 -0
  286. package/src/patterns/increment/vi.ts +61 -0
  287. package/src/patterns/increment/zh.ts +32 -0
  288. package/src/patterns/index.ts +84 -0
  289. package/src/patterns/languages/en/control-flow.ts +93 -0
  290. package/src/patterns/languages/en/fetch.ts +62 -0
  291. package/src/patterns/languages/en/index.ts +42 -0
  292. package/src/patterns/languages/en/repeat.ts +67 -0
  293. package/src/patterns/languages/en/set.ts +48 -0
  294. package/src/patterns/languages/en/swap.ts +38 -0
  295. package/src/patterns/languages/en/temporal.ts +57 -0
  296. package/src/patterns/put/ar.ts +74 -0
  297. package/src/patterns/put/bn.ts +53 -0
  298. package/src/patterns/put/en.ts +74 -0
  299. package/src/patterns/put/es.ts +74 -0
  300. package/src/patterns/put/hi.ts +69 -0
  301. package/src/patterns/put/id.ts +96 -0
  302. package/src/patterns/put/index.ts +99 -0
  303. package/src/patterns/put/it.ts +56 -0
  304. package/src/patterns/put/ja.ts +75 -0
  305. package/src/patterns/put/ko.ts +67 -0
  306. package/src/patterns/put/ms.ts +30 -0
  307. package/src/patterns/put/pl.ts +81 -0
  308. package/src/patterns/put/ru.ts +85 -0
  309. package/src/patterns/put/th.ts +32 -0
  310. package/src/patterns/put/tl.ts +30 -0
  311. package/src/patterns/put/tr.ts +67 -0
  312. package/src/patterns/put/uk.ts +85 -0
  313. package/src/patterns/put/vi.ts +72 -0
  314. package/src/patterns/put/zh.ts +62 -0
  315. package/src/patterns/registry.ts +163 -0
  316. package/src/patterns/remove/ar.ts +71 -0
  317. package/src/patterns/remove/bn.ts +68 -0
  318. package/src/patterns/remove/hi.ts +69 -0
  319. package/src/patterns/remove/index.ts +87 -0
  320. package/src/patterns/remove/it.ts +69 -0
  321. package/src/patterns/remove/ja.ts +74 -0
  322. package/src/patterns/remove/ko.ts +78 -0
  323. package/src/patterns/remove/ms.ts +30 -0
  324. package/src/patterns/remove/pl.ts +62 -0
  325. package/src/patterns/remove/ru.ts +62 -0
  326. package/src/patterns/remove/th.ts +49 -0
  327. package/src/patterns/remove/tl.ts +30 -0
  328. package/src/patterns/remove/tr.ts +78 -0
  329. package/src/patterns/remove/uk.ts +62 -0
  330. package/src/patterns/remove/vi.ts +61 -0
  331. package/src/patterns/remove/zh.ts +72 -0
  332. package/src/patterns/set/ar.ts +84 -0
  333. package/src/patterns/set/bn.ts +53 -0
  334. package/src/patterns/set/de.ts +84 -0
  335. package/src/patterns/set/es.ts +92 -0
  336. package/src/patterns/set/fr.ts +88 -0
  337. package/src/patterns/set/hi.ts +56 -0
  338. package/src/patterns/set/id.ts +84 -0
  339. package/src/patterns/set/index.ts +107 -0
  340. package/src/patterns/set/it.ts +56 -0
  341. package/src/patterns/set/ja.ts +86 -0
  342. package/src/patterns/set/ko.ts +85 -0
  343. package/src/patterns/set/ms.ts +30 -0
  344. package/src/patterns/set/pl.ts +57 -0
  345. package/src/patterns/set/pt.ts +84 -0
  346. package/src/patterns/set/ru.ts +57 -0
  347. package/src/patterns/set/th.ts +31 -0
  348. package/src/patterns/set/tl.ts +30 -0
  349. package/src/patterns/set/tr.ts +107 -0
  350. package/src/patterns/set/uk.ts +57 -0
  351. package/src/patterns/set/vi.ts +53 -0
  352. package/src/patterns/set/zh.ts +84 -0
  353. package/src/patterns/show/ar.ts +67 -0
  354. package/src/patterns/show/bn.ts +47 -0
  355. package/src/patterns/show/de.ts +32 -0
  356. package/src/patterns/show/fr.ts +32 -0
  357. package/src/patterns/show/hi.ts +61 -0
  358. package/src/patterns/show/index.ts +95 -0
  359. package/src/patterns/show/it.ts +56 -0
  360. package/src/patterns/show/ja.ts +69 -0
  361. package/src/patterns/show/ko.ts +73 -0
  362. package/src/patterns/show/ms.ts +30 -0
  363. package/src/patterns/show/pl.ts +57 -0
  364. package/src/patterns/show/ru.ts +57 -0
  365. package/src/patterns/show/th.ts +29 -0
  366. package/src/patterns/show/tl.ts +30 -0
  367. package/src/patterns/show/tr.ts +65 -0
  368. package/src/patterns/show/uk.ts +57 -0
  369. package/src/patterns/show/vi.ts +56 -0
  370. package/src/patterns/show/zh.ts +68 -0
  371. package/src/patterns/take/ar.ts +51 -0
  372. package/src/patterns/take/index.ts +31 -0
  373. package/src/patterns/toggle/ar.ts +61 -0
  374. package/src/patterns/toggle/bn.ts +70 -0
  375. package/src/patterns/toggle/en.ts +61 -0
  376. package/src/patterns/toggle/es.ts +61 -0
  377. package/src/patterns/toggle/hi.ts +80 -0
  378. package/src/patterns/toggle/index.ts +95 -0
  379. package/src/patterns/toggle/it.ts +69 -0
  380. package/src/patterns/toggle/ja.ts +156 -0
  381. package/src/patterns/toggle/ko.ts +113 -0
  382. package/src/patterns/toggle/ms.ts +30 -0
  383. package/src/patterns/toggle/pl.ts +62 -0
  384. package/src/patterns/toggle/ru.ts +62 -0
  385. package/src/patterns/toggle/th.ts +50 -0
  386. package/src/patterns/toggle/tl.ts +30 -0
  387. package/src/patterns/toggle/tr.ts +88 -0
  388. package/src/patterns/toggle/uk.ts +62 -0
  389. package/src/patterns/toggle/vi.ts +61 -0
  390. package/src/patterns/toggle/zh.ts +99 -0
  391. package/src/public-api.ts +286 -0
  392. package/src/registry.ts +441 -0
  393. package/src/tokenizers/arabic.ts +723 -0
  394. package/src/tokenizers/base.ts +1300 -0
  395. package/src/tokenizers/bengali.ts +289 -0
  396. package/src/tokenizers/chinese.ts +481 -0
  397. package/src/tokenizers/english.ts +416 -0
  398. package/src/tokenizers/french.ts +326 -0
  399. package/src/tokenizers/german.ts +324 -0
  400. package/src/tokenizers/hindi.ts +319 -0
  401. package/src/tokenizers/index.ts +127 -0
  402. package/src/tokenizers/indonesian.ts +306 -0
  403. package/src/tokenizers/italian.ts +458 -0
  404. package/src/tokenizers/japanese.ts +447 -0
  405. package/src/tokenizers/korean.ts +642 -0
  406. package/src/tokenizers/morphology/arabic-normalizer.ts +242 -0
  407. package/src/tokenizers/morphology/french-normalizer.ts +268 -0
  408. package/src/tokenizers/morphology/german-normalizer.ts +256 -0
  409. package/src/tokenizers/morphology/index.ts +46 -0
  410. package/src/tokenizers/morphology/italian-normalizer.ts +329 -0
  411. package/src/tokenizers/morphology/japanese-normalizer.ts +288 -0
  412. package/src/tokenizers/morphology/korean-normalizer.ts +428 -0
  413. package/src/tokenizers/morphology/polish-normalizer.ts +264 -0
  414. package/src/tokenizers/morphology/portuguese-normalizer.ts +310 -0
  415. package/src/tokenizers/morphology/spanish-normalizer.ts +327 -0
  416. package/src/tokenizers/morphology/turkish-normalizer.ts +412 -0
  417. package/src/tokenizers/morphology/types.ts +211 -0
  418. package/src/tokenizers/ms.ts +198 -0
  419. package/src/tokenizers/polish.ts +354 -0
  420. package/src/tokenizers/portuguese.ts +304 -0
  421. package/src/tokenizers/quechua.ts +339 -0
  422. package/src/tokenizers/russian.ts +375 -0
  423. package/src/tokenizers/spanish.ts +403 -0
  424. package/src/tokenizers/swahili.ts +303 -0
  425. package/src/tokenizers/thai.ts +236 -0
  426. package/src/tokenizers/tl.ts +198 -0
  427. package/src/tokenizers/turkish.ts +411 -0
  428. package/src/tokenizers/ukrainian.ts +369 -0
  429. package/src/tokenizers/vietnamese.ts +410 -0
  430. package/src/types/grammar-types.ts +617 -0
  431. package/src/types/unified-profile.ts +267 -0
  432. package/src/types.ts +709 -0
  433. package/src/utils/confidence-calculator.ts +147 -0
  434. package/src/validators/command-validator.ts +380 -0
  435. package/src/validators/index.ts +15 -0
@@ -0,0 +1,1133 @@
1
+ /**
2
+ * Command-specific AST Mappers
3
+ *
4
+ * Each command can have a custom mapper that knows how to convert
5
+ * its semantic roles to the appropriate AST structure.
6
+ */
7
+
8
+ import type { CommandSemanticNode, ActionType, SemanticValue, SemanticRole } from '../types';
9
+ import { convertValue } from './value-converters';
10
+ import type { ASTBuilder, CommandNode } from './index';
11
+ import type { ExpressionNode } from './expression-parser';
12
+
13
+ // =============================================================================
14
+ // Command Mapper Interface
15
+ // =============================================================================
16
+
17
+ /**
18
+ * Result from command mapping, including the AST and any warnings.
19
+ */
20
+ export interface CommandMapperResult {
21
+ ast: CommandNode;
22
+ warnings: string[];
23
+ }
24
+
25
+ /**
26
+ * Interface for command-specific AST mappers.
27
+ */
28
+ export interface CommandMapper {
29
+ /**
30
+ * The action type this mapper handles.
31
+ */
32
+ readonly action: ActionType;
33
+
34
+ /**
35
+ * Convert a CommandSemanticNode to a CommandNode.
36
+ *
37
+ * @param node - The semantic command node
38
+ * @param builder - The AST builder (for recursive building if needed)
39
+ * @returns The AST command node with any warnings, or just the AST node for backward compatibility
40
+ */
41
+ toAST(node: CommandSemanticNode, builder: ASTBuilder): CommandMapperResult | CommandNode;
42
+ }
43
+
44
+ // =============================================================================
45
+ // Helper Functions
46
+ // =============================================================================
47
+
48
+ /**
49
+ * Get a semantic value from a node's roles, returning undefined if not present.
50
+ */
51
+ function getRole(node: CommandSemanticNode, role: SemanticRole): SemanticValue | undefined {
52
+ return node.roles.get(role);
53
+ }
54
+
55
+ /**
56
+ * Convert a semantic value to an AST expression, or return undefined.
57
+ *
58
+ * @param node - The semantic node containing roles
59
+ * @param role - The semantic role to extract
60
+ * @param warnings - Optional array to collect warnings
61
+ */
62
+ function convertRoleValue(
63
+ node: CommandSemanticNode,
64
+ role: SemanticRole,
65
+ warnings?: string[]
66
+ ): ExpressionNode | undefined {
67
+ const value = getRole(node, role);
68
+ return value ? convertValue(value, warnings) : undefined;
69
+ }
70
+
71
+ /**
72
+ * Create a basic command node with standard structure.
73
+ * Handles exactOptionalPropertyTypes by not including undefined properties.
74
+ */
75
+ function createCommandNode(
76
+ name: string,
77
+ args: ExpressionNode[] = [],
78
+ modifiers?: Record<string, ExpressionNode>,
79
+ options: { isBlocking?: boolean; implicitTarget?: ExpressionNode } = {}
80
+ ): CommandNode {
81
+ const result: CommandNode = {
82
+ type: 'command',
83
+ name,
84
+ args,
85
+ };
86
+
87
+ // Only add optional properties if they have values (exactOptionalPropertyTypes)
88
+ if (modifiers && Object.keys(modifiers).length > 0) {
89
+ (result as { modifiers: Record<string, ExpressionNode> }).modifiers = modifiers;
90
+ }
91
+
92
+ if (options.isBlocking) {
93
+ (result as { isBlocking: boolean }).isBlocking = options.isBlocking;
94
+ }
95
+
96
+ if (options.implicitTarget) {
97
+ (result as { implicitTarget: ExpressionNode }).implicitTarget = options.implicitTarget;
98
+ }
99
+
100
+ return result;
101
+ }
102
+
103
+ // =============================================================================
104
+ // Command Mappers
105
+ // =============================================================================
106
+
107
+ /**
108
+ * Toggle command mapper.
109
+ *
110
+ * Semantic: toggle patient:.active destination:#button
111
+ * AST: { name: 'toggle', args: ['.active'], modifiers: { on: '#button' } }
112
+ */
113
+ const toggleMapper: CommandMapper = {
114
+ action: 'toggle',
115
+ toAST(node, _builder) {
116
+ const patient = convertRoleValue(node, 'patient');
117
+ const destination = convertRoleValue(node, 'destination');
118
+ const duration = convertRoleValue(node, 'duration');
119
+
120
+ const args: ExpressionNode[] = patient ? [patient] : [];
121
+ const modifiers: Record<string, ExpressionNode> = {};
122
+
123
+ if (destination) modifiers['on'] = destination;
124
+ if (duration) modifiers['for'] = duration;
125
+
126
+ return createCommandNode('toggle', args, modifiers);
127
+ },
128
+ };
129
+
130
+ /**
131
+ * Add command mapper.
132
+ *
133
+ * Semantic: add patient:.active destination:#button
134
+ * AST: { name: 'add', args: ['.active'], modifiers: { to: '#button' } }
135
+ */
136
+ const addMapper: CommandMapper = {
137
+ action: 'add',
138
+ toAST(node, _builder) {
139
+ const patient = convertRoleValue(node, 'patient');
140
+ const destination = convertRoleValue(node, 'destination');
141
+
142
+ const args: ExpressionNode[] = patient ? [patient] : [];
143
+ const modifiers: Record<string, ExpressionNode> = {};
144
+
145
+ if (destination) modifiers['to'] = destination;
146
+
147
+ return createCommandNode('add', args, modifiers);
148
+ },
149
+ };
150
+
151
+ /**
152
+ * Remove command mapper.
153
+ *
154
+ * Semantic: remove patient:.active source:#button
155
+ * AST: { name: 'remove', args: ['.active'], modifiers: { from: '#button' } }
156
+ */
157
+ const removeMapper: CommandMapper = {
158
+ action: 'remove',
159
+ toAST(node, _builder) {
160
+ const patient = convertRoleValue(node, 'patient');
161
+ const source = convertRoleValue(node, 'source');
162
+
163
+ const args: ExpressionNode[] = patient ? [patient] : [];
164
+ const modifiers: Record<string, ExpressionNode> = {};
165
+
166
+ if (source) modifiers['from'] = source;
167
+
168
+ return createCommandNode('remove', args, modifiers);
169
+ },
170
+ };
171
+
172
+ /**
173
+ * Set command mapper.
174
+ *
175
+ * Semantic: set destination:#element's value patient:"hello"
176
+ * AST: { name: 'set', args: [#element's value], modifiers: { to: "hello" } }
177
+ *
178
+ * Note: The destination typically includes the property path (e.g., #element's value)
179
+ * and patient is the value being set.
180
+ */
181
+ const setMapper: CommandMapper = {
182
+ action: 'set',
183
+ toAST(node, _builder) {
184
+ const destination = convertRoleValue(node, 'destination');
185
+ const patient = convertRoleValue(node, 'patient');
186
+
187
+ const args: ExpressionNode[] = [];
188
+ const modifiers: Record<string, ExpressionNode> = {};
189
+
190
+ // The destination is typically the property path to set
191
+ if (destination) {
192
+ args.push(destination);
193
+ }
194
+
195
+ // The patient is the value being set
196
+ if (patient) modifiers['to'] = patient;
197
+
198
+ return createCommandNode('set', args, modifiers);
199
+ },
200
+ };
201
+
202
+ /**
203
+ * Show command mapper.
204
+ */
205
+ const showMapper: CommandMapper = {
206
+ action: 'show',
207
+ toAST(node, _builder) {
208
+ const destination = convertRoleValue(node, 'destination');
209
+ const patient = convertRoleValue(node, 'patient');
210
+ const duration = convertRoleValue(node, 'duration');
211
+
212
+ const args: ExpressionNode[] = [];
213
+ const modifiers: Record<string, ExpressionNode> = {};
214
+
215
+ // Target can be in destination or patient
216
+ const target = destination ?? patient;
217
+ if (target) args.push(target);
218
+ if (duration) modifiers['with'] = duration;
219
+
220
+ return createCommandNode('show', args, modifiers);
221
+ },
222
+ };
223
+
224
+ /**
225
+ * Hide command mapper.
226
+ */
227
+ const hideMapper: CommandMapper = {
228
+ action: 'hide',
229
+ toAST(node, _builder) {
230
+ const destination = convertRoleValue(node, 'destination');
231
+ const patient = convertRoleValue(node, 'patient');
232
+ const duration = convertRoleValue(node, 'duration');
233
+
234
+ const args: ExpressionNode[] = [];
235
+ const modifiers: Record<string, ExpressionNode> = {};
236
+
237
+ const target = destination ?? patient;
238
+ if (target) args.push(target);
239
+ if (duration) modifiers['with'] = duration;
240
+
241
+ return createCommandNode('hide', args, modifiers);
242
+ },
243
+ };
244
+
245
+ /**
246
+ * Increment command mapper.
247
+ *
248
+ * Semantic: increment patient:#count quantity:5
249
+ * AST: { name: 'increment', args: [#count], modifiers: { by: 5 } }
250
+ */
251
+ const incrementMapper: CommandMapper = {
252
+ action: 'increment',
253
+ toAST(node, _builder) {
254
+ const destination = convertRoleValue(node, 'destination');
255
+ const patient = convertRoleValue(node, 'patient');
256
+ const quantity = convertRoleValue(node, 'quantity'); // Amount
257
+
258
+ const args: ExpressionNode[] = [];
259
+ const modifiers: Record<string, ExpressionNode> = {};
260
+
261
+ const target = destination ?? patient;
262
+ if (target) args.push(target);
263
+ if (quantity) modifiers['by'] = quantity;
264
+
265
+ return createCommandNode('increment', args, modifiers);
266
+ },
267
+ };
268
+
269
+ /**
270
+ * Decrement command mapper.
271
+ *
272
+ * Semantic: decrement patient:#count quantity:5
273
+ * AST: { name: 'decrement', args: [#count], modifiers: { by: 5 } }
274
+ */
275
+ const decrementMapper: CommandMapper = {
276
+ action: 'decrement',
277
+ toAST(node, _builder) {
278
+ const destination = convertRoleValue(node, 'destination');
279
+ const patient = convertRoleValue(node, 'patient');
280
+ const quantity = convertRoleValue(node, 'quantity');
281
+
282
+ const args: ExpressionNode[] = [];
283
+ const modifiers: Record<string, ExpressionNode> = {};
284
+
285
+ const target = destination ?? patient;
286
+ if (target) args.push(target);
287
+ if (quantity) modifiers['by'] = quantity;
288
+
289
+ return createCommandNode('decrement', args, modifiers);
290
+ },
291
+ };
292
+
293
+ /**
294
+ * Wait command mapper.
295
+ */
296
+ const waitMapper: CommandMapper = {
297
+ action: 'wait',
298
+ toAST(node, _builder) {
299
+ const duration = convertRoleValue(node, 'duration');
300
+
301
+ const args: ExpressionNode[] = duration ? [duration] : [];
302
+
303
+ return createCommandNode('wait', args, undefined, { isBlocking: true });
304
+ },
305
+ };
306
+
307
+ /**
308
+ * Log command mapper.
309
+ *
310
+ * Semantic: log patient:"hello"
311
+ * AST: { name: 'log', args: ["hello"] }
312
+ */
313
+ const logMapper: CommandMapper = {
314
+ action: 'log',
315
+ toAST(node, _builder) {
316
+ const patient = convertRoleValue(node, 'patient');
317
+
318
+ const args: ExpressionNode[] = [];
319
+ if (patient) args.push(patient);
320
+
321
+ return createCommandNode('log', args);
322
+ },
323
+ };
324
+
325
+ /**
326
+ * Put command mapper.
327
+ *
328
+ * Semantic: put patient:"hello" destination:#output method:into
329
+ * AST: { name: 'put', args: ["hello"], modifiers: { into: #output } }
330
+ */
331
+ const putMapper: CommandMapper = {
332
+ action: 'put',
333
+ toAST(node, _builder) {
334
+ const patient = convertRoleValue(node, 'patient');
335
+ const destination = convertRoleValue(node, 'destination');
336
+ const method = getRole(node, 'method'); // before, after, into, etc.
337
+
338
+ const args: ExpressionNode[] = patient ? [patient] : [];
339
+ const modifiers: Record<string, ExpressionNode> = {};
340
+
341
+ if (destination) {
342
+ // Determine the preposition based on method or default to 'into'
343
+ const prep = method?.type === 'literal' ? String(method.value) : 'into';
344
+ modifiers[prep] = destination;
345
+ }
346
+
347
+ return createCommandNode('put', args, modifiers);
348
+ },
349
+ };
350
+
351
+ /**
352
+ * Fetch command mapper.
353
+ *
354
+ * Semantic: fetch source:"/api/data" responseType:json method:GET
355
+ * AST: { name: 'fetch', args: ["/api/data"], modifiers: { as: json, with: GET } }
356
+ */
357
+ const fetchMapper: CommandMapper = {
358
+ action: 'fetch',
359
+ toAST(node, _builder) {
360
+ const source = convertRoleValue(node, 'source'); // URL
361
+ const method = convertRoleValue(node, 'method'); // GET, POST, etc.
362
+ const responseType = convertRoleValue(node, 'responseType'); // json, text, etc.
363
+ const patient = convertRoleValue(node, 'patient'); // Body
364
+
365
+ const args: ExpressionNode[] = source ? [source] : [];
366
+ const modifiers: Record<string, ExpressionNode> = {};
367
+
368
+ if (method) modifiers['with'] = method;
369
+ if (responseType) modifiers['as'] = responseType;
370
+ if (patient) modifiers['body'] = patient;
371
+
372
+ return createCommandNode('fetch', args, modifiers, { isBlocking: true });
373
+ },
374
+ };
375
+
376
+ /**
377
+ * Append command mapper.
378
+ *
379
+ * Semantic: append patient:"text" destination:#output
380
+ * AST: { name: 'append', args: ["text"], modifiers: { to: #output } }
381
+ */
382
+ const appendMapper: CommandMapper = {
383
+ action: 'append',
384
+ toAST(node, _builder) {
385
+ const patient = convertRoleValue(node, 'patient');
386
+ const destination = convertRoleValue(node, 'destination');
387
+
388
+ const args: ExpressionNode[] = patient ? [patient] : [];
389
+ const modifiers: Record<string, ExpressionNode> = {};
390
+
391
+ if (destination) modifiers['to'] = destination;
392
+
393
+ return createCommandNode('append', args, modifiers);
394
+ },
395
+ };
396
+
397
+ /**
398
+ * Prepend command mapper.
399
+ *
400
+ * Semantic: prepend patient:"text" destination:#output
401
+ * AST: { name: 'prepend', args: ["text"], modifiers: { to: #output } }
402
+ */
403
+ const prependMapper: CommandMapper = {
404
+ action: 'prepend',
405
+ toAST(node, _builder) {
406
+ const patient = convertRoleValue(node, 'patient');
407
+ const destination = convertRoleValue(node, 'destination');
408
+
409
+ const args: ExpressionNode[] = patient ? [patient] : [];
410
+ const modifiers: Record<string, ExpressionNode> = {};
411
+
412
+ if (destination) modifiers['to'] = destination;
413
+
414
+ return createCommandNode('prepend', args, modifiers);
415
+ },
416
+ };
417
+
418
+ /**
419
+ * Trigger command mapper.
420
+ *
421
+ * Semantic: trigger event:click destination:#button
422
+ * AST: { name: 'trigger', args: [click], modifiers: { on: #button } }
423
+ */
424
+ const triggerMapper: CommandMapper = {
425
+ action: 'trigger',
426
+ toAST(node, _builder) {
427
+ const event = convertRoleValue(node, 'event');
428
+ const destination = convertRoleValue(node, 'destination');
429
+
430
+ const args: ExpressionNode[] = event ? [event] : [];
431
+ const modifiers: Record<string, ExpressionNode> = {};
432
+
433
+ if (destination) modifiers['on'] = destination;
434
+
435
+ return createCommandNode('trigger', args, modifiers);
436
+ },
437
+ };
438
+
439
+ /**
440
+ * Send command mapper.
441
+ *
442
+ * Semantic: send event:customEvent destination:#target patient:{detail}
443
+ * AST: { name: 'send', args: [customEvent], modifiers: { to: #target, detail: ... } }
444
+ */
445
+ const sendMapper: CommandMapper = {
446
+ action: 'send',
447
+ toAST(node, _builder) {
448
+ const event = convertRoleValue(node, 'event');
449
+ const destination = convertRoleValue(node, 'destination');
450
+ const patient = convertRoleValue(node, 'patient');
451
+
452
+ const args: ExpressionNode[] = event ? [event] : [];
453
+ const modifiers: Record<string, ExpressionNode> = {};
454
+
455
+ if (destination) modifiers['to'] = destination;
456
+ if (patient) modifiers['detail'] = patient;
457
+
458
+ return createCommandNode('send', args, modifiers);
459
+ },
460
+ };
461
+
462
+ /**
463
+ * Go command mapper (navigation).
464
+ *
465
+ * Semantic: go source:/page destination:url
466
+ * AST: { name: 'go', args: [/page], modifiers: { to: url } }
467
+ */
468
+ const goMapper: CommandMapper = {
469
+ action: 'go',
470
+ toAST(node, _builder) {
471
+ const source = convertRoleValue(node, 'source');
472
+ const destination = convertRoleValue(node, 'destination');
473
+
474
+ const args: ExpressionNode[] = [];
475
+ const modifiers: Record<string, ExpressionNode> = {};
476
+
477
+ // Source is the URL/location to navigate to
478
+ if (source) args.push(source);
479
+ if (destination) modifiers['to'] = destination;
480
+
481
+ return createCommandNode('go', args, modifiers);
482
+ },
483
+ };
484
+
485
+ /**
486
+ * Transition command mapper.
487
+ *
488
+ * Semantic: transition patient:*background-color goal:'red' duration:500ms destination:#element
489
+ * AST: { name: 'transition', args: [*background-color], modifiers: { to: 'red', over: 500ms, on: #element } }
490
+ */
491
+ const transitionMapper: CommandMapper = {
492
+ action: 'transition',
493
+ toAST(node, _builder) {
494
+ const patient = convertRoleValue(node, 'patient');
495
+ const goal = convertRoleValue(node, 'goal');
496
+ const duration = convertRoleValue(node, 'duration');
497
+ const destination = convertRoleValue(node, 'destination');
498
+
499
+ const args: ExpressionNode[] = patient ? [patient] : [];
500
+ const modifiers: Record<string, ExpressionNode> = {};
501
+
502
+ if (goal) modifiers['to'] = goal;
503
+ if (duration) modifiers['over'] = duration;
504
+ if (destination) modifiers['on'] = destination;
505
+
506
+ return createCommandNode('transition', args, modifiers);
507
+ },
508
+ };
509
+
510
+ /**
511
+ * Focus command mapper.
512
+ *
513
+ * Semantic: focus destination:#input
514
+ * AST: { name: 'focus', args: [], modifiers: { on: #input } }
515
+ */
516
+ const focusMapper: CommandMapper = {
517
+ action: 'focus',
518
+ toAST(node, _builder) {
519
+ const destination = convertRoleValue(node, 'destination');
520
+ const patient = convertRoleValue(node, 'patient');
521
+
522
+ const args: ExpressionNode[] = [];
523
+ const modifiers: Record<string, ExpressionNode> = {};
524
+
525
+ // Target can be in destination or patient
526
+ const target = destination ?? patient;
527
+ if (target) args.push(target);
528
+
529
+ return createCommandNode('focus', args, modifiers);
530
+ },
531
+ };
532
+
533
+ /**
534
+ * Blur command mapper.
535
+ *
536
+ * Semantic: blur destination:#input
537
+ * AST: { name: 'blur', args: [#input] }
538
+ */
539
+ const blurMapper: CommandMapper = {
540
+ action: 'blur',
541
+ toAST(node, _builder) {
542
+ const destination = convertRoleValue(node, 'destination');
543
+ const patient = convertRoleValue(node, 'patient');
544
+
545
+ const args: ExpressionNode[] = [];
546
+ const target = destination ?? patient;
547
+ if (target) args.push(target);
548
+
549
+ return createCommandNode('blur', args);
550
+ },
551
+ };
552
+
553
+ /**
554
+ * Get command mapper.
555
+ *
556
+ * Semantic: get source:myValue
557
+ * AST: { name: 'get', args: [myValue] }
558
+ */
559
+ const getMapper: CommandMapper = {
560
+ action: 'get',
561
+ toAST(node, _builder) {
562
+ const source = convertRoleValue(node, 'source');
563
+ const patient = convertRoleValue(node, 'patient');
564
+
565
+ const args: ExpressionNode[] = [];
566
+ const value = source ?? patient;
567
+ if (value) args.push(value);
568
+
569
+ return createCommandNode('get', args);
570
+ },
571
+ };
572
+
573
+ /**
574
+ * Take command mapper.
575
+ *
576
+ * Semantic: take patient:.active source:#parent
577
+ * AST: { name: 'take', args: [.active], modifiers: { from: #parent } }
578
+ */
579
+ const takeMapper: CommandMapper = {
580
+ action: 'take',
581
+ toAST(node, _builder) {
582
+ const patient = convertRoleValue(node, 'patient');
583
+ const source = convertRoleValue(node, 'source');
584
+
585
+ const args: ExpressionNode[] = patient ? [patient] : [];
586
+ const modifiers: Record<string, ExpressionNode> = {};
587
+
588
+ if (source) modifiers['from'] = source;
589
+
590
+ return createCommandNode('take', args, modifiers);
591
+ },
592
+ };
593
+
594
+ /**
595
+ * Call command mapper.
596
+ *
597
+ * Semantic: call patient:functionName
598
+ * AST: { name: 'call', args: [functionName] }
599
+ */
600
+ const callMapper: CommandMapper = {
601
+ action: 'call',
602
+ toAST(node, _builder) {
603
+ const patient = convertRoleValue(node, 'patient');
604
+
605
+ const args: ExpressionNode[] = patient ? [patient] : [];
606
+
607
+ return createCommandNode('call', args);
608
+ },
609
+ };
610
+
611
+ /**
612
+ * Return command mapper.
613
+ *
614
+ * Semantic: return patient:value
615
+ * AST: { name: 'return', args: [value] }
616
+ */
617
+ const returnMapper: CommandMapper = {
618
+ action: 'return',
619
+ toAST(node, _builder) {
620
+ const patient = convertRoleValue(node, 'patient');
621
+
622
+ const args: ExpressionNode[] = patient ? [patient] : [];
623
+
624
+ return createCommandNode('return', args);
625
+ },
626
+ };
627
+
628
+ /**
629
+ * Halt command mapper.
630
+ *
631
+ * Semantic: halt
632
+ * AST: { name: 'halt', args: [] }
633
+ */
634
+ const haltMapper: CommandMapper = {
635
+ action: 'halt',
636
+ toAST(_node, _builder) {
637
+ return createCommandNode('halt', []);
638
+ },
639
+ };
640
+
641
+ /**
642
+ * Throw command mapper.
643
+ *
644
+ * Semantic: throw patient:"error message"
645
+ * AST: { name: 'throw', args: ["error message"] }
646
+ */
647
+ const throwMapper: CommandMapper = {
648
+ action: 'throw',
649
+ toAST(node, _builder) {
650
+ const patient = convertRoleValue(node, 'patient');
651
+
652
+ const args: ExpressionNode[] = patient ? [patient] : [];
653
+
654
+ return createCommandNode('throw', args);
655
+ },
656
+ };
657
+
658
+ /**
659
+ * Settle command mapper.
660
+ *
661
+ * Semantic: settle destination:#element
662
+ * AST: { name: 'settle', args: [#element] }
663
+ */
664
+ const settleMapper: CommandMapper = {
665
+ action: 'settle',
666
+ toAST(node, _builder) {
667
+ const destination = convertRoleValue(node, 'destination');
668
+ const patient = convertRoleValue(node, 'patient');
669
+
670
+ const args: ExpressionNode[] = [];
671
+ const target = destination ?? patient;
672
+ if (target) args.push(target);
673
+
674
+ return createCommandNode('settle', args, undefined, { isBlocking: true });
675
+ },
676
+ };
677
+
678
+ // =============================================================================
679
+ // Tier 3: Advanced Commands
680
+ // =============================================================================
681
+
682
+ /**
683
+ * Swap command mapper.
684
+ *
685
+ * Semantic: swap patient:innerHTML destination:#element source:"<p>new</p>"
686
+ * AST: { name: 'swap', args: [innerHTML, "<p>new</p>"], modifiers: { on: #element } }
687
+ */
688
+ const swapMapper: CommandMapper = {
689
+ action: 'swap',
690
+ toAST(node, _builder) {
691
+ const patient = convertRoleValue(node, 'patient'); // What to swap (e.g., innerHTML)
692
+ const source = convertRoleValue(node, 'source'); // New content
693
+ const destination = convertRoleValue(node, 'destination'); // Target element
694
+ const style = convertRoleValue(node, 'style'); // Swap strategy (innerHTML, outerHTML, etc.)
695
+
696
+ const args: ExpressionNode[] = [];
697
+ const modifiers: Record<string, ExpressionNode> = {};
698
+
699
+ if (patient) args.push(patient);
700
+ if (source) args.push(source);
701
+ if (destination) modifiers['on'] = destination;
702
+ if (style) modifiers['with'] = style;
703
+
704
+ return createCommandNode('swap', args, modifiers);
705
+ },
706
+ };
707
+
708
+ /**
709
+ * Morph command mapper.
710
+ *
711
+ * Semantic: morph destination:#element source:"<div>new</div>"
712
+ * AST: { name: 'morph', args: ["<div>new</div>"], modifiers: { on: #element } }
713
+ */
714
+ const morphMapper: CommandMapper = {
715
+ action: 'morph',
716
+ toAST(node, _builder) {
717
+ const source = convertRoleValue(node, 'source'); // New HTML
718
+ const destination = convertRoleValue(node, 'destination'); // Target element
719
+ const patient = convertRoleValue(node, 'patient');
720
+
721
+ const args: ExpressionNode[] = [];
722
+ const modifiers: Record<string, ExpressionNode> = {};
723
+
724
+ const content = source ?? patient;
725
+ if (content) args.push(content);
726
+ if (destination) modifiers['on'] = destination;
727
+
728
+ return createCommandNode('morph', args, modifiers);
729
+ },
730
+ };
731
+
732
+ /**
733
+ * Clone command mapper.
734
+ *
735
+ * Semantic: clone source:#template destination:#container
736
+ * AST: { name: 'clone', args: [#template], modifiers: { into: #container } }
737
+ */
738
+ const cloneMapper: CommandMapper = {
739
+ action: 'clone',
740
+ toAST(node, _builder) {
741
+ const source = convertRoleValue(node, 'source'); // Element to clone
742
+ const destination = convertRoleValue(node, 'destination'); // Where to put clone
743
+ const patient = convertRoleValue(node, 'patient');
744
+
745
+ const args: ExpressionNode[] = [];
746
+ const modifiers: Record<string, ExpressionNode> = {};
747
+
748
+ const target = source ?? patient;
749
+ if (target) args.push(target);
750
+ if (destination) modifiers['into'] = destination;
751
+
752
+ return createCommandNode('clone', args, modifiers);
753
+ },
754
+ };
755
+
756
+ /**
757
+ * Make command mapper.
758
+ *
759
+ * Semantic: make patient:Date
760
+ * AST: { name: 'make', args: [Date] }
761
+ */
762
+ const makeMapper: CommandMapper = {
763
+ action: 'make',
764
+ toAST(node, _builder) {
765
+ const patient = convertRoleValue(node, 'patient'); // Constructor/type
766
+
767
+ const args: ExpressionNode[] = patient ? [patient] : [];
768
+
769
+ return createCommandNode('make', args);
770
+ },
771
+ };
772
+
773
+ /**
774
+ * Measure command mapper.
775
+ *
776
+ * Semantic: measure destination:#element patient:width
777
+ * AST: { name: 'measure', args: [width], modifiers: { of: #element } }
778
+ */
779
+ const measureMapper: CommandMapper = {
780
+ action: 'measure',
781
+ toAST(node, _builder) {
782
+ const patient = convertRoleValue(node, 'patient'); // What to measure
783
+ const destination = convertRoleValue(node, 'destination'); // Element
784
+ const source = convertRoleValue(node, 'source');
785
+
786
+ const args: ExpressionNode[] = [];
787
+ const modifiers: Record<string, ExpressionNode> = {};
788
+
789
+ if (patient) args.push(patient);
790
+ const element = destination ?? source;
791
+ if (element) modifiers['of'] = element;
792
+
793
+ return createCommandNode('measure', args, modifiers);
794
+ },
795
+ };
796
+
797
+ /**
798
+ * Tell command mapper.
799
+ *
800
+ * Semantic: tell destination:#element
801
+ * AST: { name: 'tell', args: [#element] }
802
+ */
803
+ const tellMapper: CommandMapper = {
804
+ action: 'tell',
805
+ toAST(node, _builder) {
806
+ const destination = convertRoleValue(node, 'destination');
807
+ const patient = convertRoleValue(node, 'patient');
808
+
809
+ const args: ExpressionNode[] = [];
810
+ const target = destination ?? patient;
811
+ if (target) args.push(target);
812
+
813
+ return createCommandNode('tell', args);
814
+ },
815
+ };
816
+
817
+ /**
818
+ * JS command mapper (inline JavaScript).
819
+ *
820
+ * Semantic: js patient:"console.log('hello')"
821
+ * AST: { name: 'js', args: ["console.log('hello')"] }
822
+ */
823
+ const jsMapper: CommandMapper = {
824
+ action: 'js',
825
+ toAST(node, _builder) {
826
+ const patient = convertRoleValue(node, 'patient'); // JS code
827
+
828
+ const args: ExpressionNode[] = patient ? [patient] : [];
829
+
830
+ return createCommandNode('js', args);
831
+ },
832
+ };
833
+
834
+ /**
835
+ * Async command mapper.
836
+ *
837
+ * Semantic: async
838
+ * AST: { name: 'async', args: [] }
839
+ */
840
+ const asyncMapper: CommandMapper = {
841
+ action: 'async',
842
+ toAST(_node, _builder) {
843
+ return createCommandNode('async', []);
844
+ },
845
+ };
846
+
847
+ /**
848
+ * If command mapper.
849
+ *
850
+ * Semantic: if condition:x > 5
851
+ * AST: { name: 'if', args: [], modifiers: { condition: x > 5 } }
852
+ */
853
+ const ifMapper: CommandMapper = {
854
+ action: 'if',
855
+ toAST(node, _builder) {
856
+ const condition = convertRoleValue(node, 'condition');
857
+
858
+ const args: ExpressionNode[] = condition ? [condition] : [];
859
+
860
+ return createCommandNode('if', args);
861
+ },
862
+ };
863
+
864
+ /**
865
+ * Unless command mapper.
866
+ *
867
+ * Semantic: unless condition:x < 5
868
+ * AST: { name: 'unless', args: [x < 5] }
869
+ */
870
+ const unlessMapper: CommandMapper = {
871
+ action: 'unless',
872
+ toAST(node, _builder) {
873
+ const condition = convertRoleValue(node, 'condition');
874
+
875
+ const args: ExpressionNode[] = condition ? [condition] : [];
876
+
877
+ return createCommandNode('unless', args);
878
+ },
879
+ };
880
+
881
+ /**
882
+ * Repeat command mapper.
883
+ *
884
+ * Semantic: repeat quantity:5
885
+ * AST: { name: 'repeat', args: [5] }
886
+ */
887
+ const repeatMapper: CommandMapper = {
888
+ action: 'repeat',
889
+ toAST(node, _builder) {
890
+ const quantity = convertRoleValue(node, 'quantity');
891
+ const patient = convertRoleValue(node, 'patient');
892
+
893
+ const args: ExpressionNode[] = [];
894
+ const count = quantity ?? patient;
895
+ if (count) args.push(count);
896
+
897
+ return createCommandNode('repeat', args);
898
+ },
899
+ };
900
+
901
+ /**
902
+ * For command mapper.
903
+ *
904
+ * Semantic: for patient:item source:items
905
+ * AST: { name: 'for', args: [item], modifiers: { in: items } }
906
+ */
907
+ const forMapper: CommandMapper = {
908
+ action: 'for',
909
+ toAST(node, _builder) {
910
+ const patient = convertRoleValue(node, 'patient'); // Loop variable
911
+ const source = convertRoleValue(node, 'source'); // Collection
912
+
913
+ const args: ExpressionNode[] = patient ? [patient] : [];
914
+ const modifiers: Record<string, ExpressionNode> = {};
915
+
916
+ if (source) modifiers['in'] = source;
917
+
918
+ return createCommandNode('for', args, modifiers);
919
+ },
920
+ };
921
+
922
+ /**
923
+ * While command mapper.
924
+ *
925
+ * Semantic: while condition:x < 10
926
+ * AST: { name: 'while', args: [x < 10] }
927
+ */
928
+ const whileMapper: CommandMapper = {
929
+ action: 'while',
930
+ toAST(node, _builder) {
931
+ const condition = convertRoleValue(node, 'condition');
932
+
933
+ const args: ExpressionNode[] = condition ? [condition] : [];
934
+
935
+ return createCommandNode('while', args);
936
+ },
937
+ };
938
+
939
+ /**
940
+ * Continue command mapper.
941
+ *
942
+ * Semantic: continue
943
+ * AST: { name: 'continue', args: [] }
944
+ */
945
+ const continueMapper: CommandMapper = {
946
+ action: 'continue',
947
+ toAST(_node, _builder) {
948
+ return createCommandNode('continue', []);
949
+ },
950
+ };
951
+
952
+ /**
953
+ * Default command mapper.
954
+ *
955
+ * Semantic: default patient:myVar source:0
956
+ * AST: { name: 'default', args: [myVar], modifiers: { to: 0 } }
957
+ */
958
+ const defaultMapper: CommandMapper = {
959
+ action: 'default',
960
+ toAST(node, _builder) {
961
+ const patient = convertRoleValue(node, 'patient'); // Variable
962
+ const source = convertRoleValue(node, 'source'); // Default value
963
+
964
+ const args: ExpressionNode[] = patient ? [patient] : [];
965
+ const modifiers: Record<string, ExpressionNode> = {};
966
+
967
+ if (source) modifiers['to'] = source;
968
+
969
+ return createCommandNode('default', args, modifiers);
970
+ },
971
+ };
972
+
973
+ /**
974
+ * Init command mapper.
975
+ *
976
+ * Semantic: init
977
+ * AST: { name: 'init', args: [] }
978
+ */
979
+ const initMapper: CommandMapper = {
980
+ action: 'init',
981
+ toAST(_node, _builder) {
982
+ return createCommandNode('init', []);
983
+ },
984
+ };
985
+
986
+ /**
987
+ * Behavior command mapper.
988
+ *
989
+ * Semantic: behavior patient:MyBehavior
990
+ * AST: { name: 'behavior', args: [MyBehavior] }
991
+ */
992
+ const behaviorMapper: CommandMapper = {
993
+ action: 'behavior',
994
+ toAST(node, _builder) {
995
+ const patient = convertRoleValue(node, 'patient'); // Behavior name
996
+
997
+ const args: ExpressionNode[] = patient ? [patient] : [];
998
+
999
+ return createCommandNode('behavior', args);
1000
+ },
1001
+ };
1002
+
1003
+ /**
1004
+ * Install command mapper.
1005
+ *
1006
+ * Semantic: install patient:MyBehavior destination:#element
1007
+ * AST: { name: 'install', args: [MyBehavior], modifiers: { on: #element } }
1008
+ */
1009
+ const installMapper: CommandMapper = {
1010
+ action: 'install',
1011
+ toAST(node, _builder) {
1012
+ const patient = convertRoleValue(node, 'patient'); // Behavior to install
1013
+ const destination = convertRoleValue(node, 'destination'); // Target element
1014
+
1015
+ const args: ExpressionNode[] = patient ? [patient] : [];
1016
+ const modifiers: Record<string, ExpressionNode> = {};
1017
+
1018
+ if (destination) modifiers['on'] = destination;
1019
+
1020
+ return createCommandNode('install', args, modifiers);
1021
+ },
1022
+ };
1023
+
1024
+ /**
1025
+ * On command mapper (event handler declaration).
1026
+ *
1027
+ * Semantic: on event:click
1028
+ * AST: { name: 'on', args: [click] }
1029
+ */
1030
+ const onMapper: CommandMapper = {
1031
+ action: 'on',
1032
+ toAST(node, _builder) {
1033
+ const event = convertRoleValue(node, 'event');
1034
+ const source = convertRoleValue(node, 'source'); // 'from' clause
1035
+
1036
+ const args: ExpressionNode[] = event ? [event] : [];
1037
+ const modifiers: Record<string, ExpressionNode> = {};
1038
+
1039
+ if (source) modifiers['from'] = source;
1040
+
1041
+ return createCommandNode('on', args, modifiers);
1042
+ },
1043
+ };
1044
+
1045
+ // =============================================================================
1046
+ // Mapper Registry
1047
+ // =============================================================================
1048
+
1049
+ const mappers: Map<ActionType, CommandMapper> = new Map([
1050
+ // Tier 1: Core commands
1051
+ ['toggle', toggleMapper],
1052
+ ['add', addMapper],
1053
+ ['remove', removeMapper],
1054
+ ['set', setMapper],
1055
+ ['show', showMapper],
1056
+ ['hide', hideMapper],
1057
+ ['increment', incrementMapper],
1058
+ ['decrement', decrementMapper],
1059
+ ['wait', waitMapper],
1060
+ ['log', logMapper],
1061
+ ['put', putMapper],
1062
+ ['fetch', fetchMapper],
1063
+ // Tier 2: Content manipulation
1064
+ ['append', appendMapper],
1065
+ ['prepend', prependMapper],
1066
+ ['get', getMapper],
1067
+ ['take', takeMapper],
1068
+ // Tier 2: Events
1069
+ ['trigger', triggerMapper],
1070
+ ['send', sendMapper],
1071
+ ['on', onMapper],
1072
+ // Tier 2: Navigation & DOM
1073
+ ['go', goMapper],
1074
+ ['transition', transitionMapper],
1075
+ ['focus', focusMapper],
1076
+ ['blur', blurMapper],
1077
+ // Tier 2: Control flow
1078
+ ['call', callMapper],
1079
+ ['return', returnMapper],
1080
+ ['halt', haltMapper],
1081
+ ['throw', throwMapper],
1082
+ ['settle', settleMapper],
1083
+ // Tier 3: Advanced DOM
1084
+ ['swap', swapMapper],
1085
+ ['morph', morphMapper],
1086
+ ['clone', cloneMapper],
1087
+ ['measure', measureMapper],
1088
+ // Tier 3: Object/Types
1089
+ ['make', makeMapper],
1090
+ ['tell', tellMapper],
1091
+ ['default', defaultMapper],
1092
+ // Tier 3: JavaScript integration
1093
+ ['js', jsMapper],
1094
+ ['async', asyncMapper],
1095
+ // Tier 3: Conditionals
1096
+ ['if', ifMapper],
1097
+ ['unless', unlessMapper],
1098
+ // Tier 3: Loops
1099
+ ['repeat', repeatMapper],
1100
+ ['for', forMapper],
1101
+ ['while', whileMapper],
1102
+ ['continue', continueMapper],
1103
+ // Tier 3: Behaviors
1104
+ ['init', initMapper],
1105
+ ['behavior', behaviorMapper],
1106
+ ['install', installMapper],
1107
+ ]);
1108
+
1109
+ /**
1110
+ * Get the command mapper for an action type.
1111
+ *
1112
+ * @param action - The action type
1113
+ * @returns The mapper, or undefined if no specific mapper exists
1114
+ */
1115
+ export function getCommandMapper(action: ActionType): CommandMapper | undefined {
1116
+ return mappers.get(action);
1117
+ }
1118
+
1119
+ /**
1120
+ * Register a custom command mapper.
1121
+ *
1122
+ * @param mapper - The command mapper to register
1123
+ */
1124
+ export function registerCommandMapper(mapper: CommandMapper): void {
1125
+ mappers.set(mapper.action, mapper);
1126
+ }
1127
+
1128
+ /**
1129
+ * Get all registered command mappers.
1130
+ */
1131
+ export function getRegisteredMappers(): Map<ActionType, CommandMapper> {
1132
+ return new Map(mappers);
1133
+ }