@holoscript/core 7.0.0 → 8.0.1

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 (350) hide show
  1. package/README.md +4 -4
  2. package/bin/holoscript.cjs +3 -0
  3. package/dist/GLTFPipeline-N6B6PJ6G.cjs +38 -0
  4. package/dist/GLTFPipeline-P3WMNYCN.js +17 -0
  5. package/dist/HoloScriptPlusParser-7FBIFUFC.js +693 -0
  6. package/dist/HoloScriptPlusParser-A2W7OCN2.cjs +698 -0
  7. package/dist/HoloScriptPlusParser-F2Z56FJR.js +10 -0
  8. package/dist/HoloScriptPlusParser-WKHRIH6T.cjs +27 -0
  9. package/dist/HoloScriptRuntime-CBYJX3LZ.js +10 -0
  10. package/dist/HoloScriptRuntime-VJ374RER.cjs +19 -0
  11. package/dist/USDZExporter-3FWJ25JI.cjs +1037 -0
  12. package/dist/USDZExporter-D2HQLQYK.js +1035 -0
  13. package/dist/agents/index.cjs +19 -0
  14. package/dist/agents/index.d.ts +100 -0
  15. package/dist/agents/index.js +17 -0
  16. package/dist/chunk-2BSMSUCE.js +1941 -0
  17. package/dist/chunk-2IWC4FP7.cjs +1189 -0
  18. package/dist/chunk-2M2DPHKB.js +762 -0
  19. package/dist/chunk-2X7NGX3M.js +2426 -0
  20. package/dist/chunk-2YSNA2F2.cjs +1274 -0
  21. package/dist/chunk-3FOKASKO.cjs +348 -0
  22. package/dist/chunk-3WZEJHUQ.cjs +116 -0
  23. package/dist/chunk-4C57PR42.js +468 -0
  24. package/dist/chunk-4GU5GCIY.js +1384 -0
  25. package/dist/chunk-4N4SXXWF.js +769 -0
  26. package/dist/chunk-4PDEPEQW.cjs +41 -0
  27. package/dist/chunk-4R6SBXDB.js +45 -0
  28. package/dist/chunk-4SDKXQ4C.js +811 -0
  29. package/dist/chunk-4V2E7U7Q.cjs +2015 -0
  30. package/dist/chunk-5FSKKMR7.cjs +2092 -0
  31. package/dist/chunk-5GLCTO44.js +161 -0
  32. package/dist/chunk-5H2G27PK.cjs +627 -0
  33. package/dist/chunk-5JEU52DW.js +382 -0
  34. package/dist/chunk-5NWINHR5.cjs +689 -0
  35. package/dist/chunk-5S7RKFGR.cjs +446 -0
  36. package/dist/chunk-5WUNN6ZN.cjs +428 -0
  37. package/dist/chunk-6CTRH7HT.cjs +1985 -0
  38. package/dist/chunk-6EX3I5P4.cjs +130 -0
  39. package/dist/chunk-6Q7RC2MK.cjs +1418 -0
  40. package/dist/chunk-7H33U5SM.cjs +413 -0
  41. package/dist/chunk-7M3PNU2M.cjs +672 -0
  42. package/dist/chunk-7T25IEZ2.js +449 -0
  43. package/dist/chunk-7V4JI5TB.cjs +6947 -0
  44. package/dist/chunk-A6KINLZJ.js +236 -0
  45. package/dist/chunk-ADADVMXY.js +404 -0
  46. package/dist/chunk-AIA52I7T.cjs +543 -0
  47. package/dist/chunk-ALC6K7GL.cjs +4402 -0
  48. package/dist/chunk-ANXZFVY2.js +113 -0
  49. package/dist/chunk-AOVGZ25K.cjs +56583 -0
  50. package/dist/chunk-AVJHHUC5.cjs +718 -0
  51. package/dist/chunk-BGY3SDG3.js +4396 -0
  52. package/dist/chunk-BOVPWH4H.js +3857 -0
  53. package/dist/chunk-BRQJKJGT.cjs +20 -0
  54. package/dist/chunk-C37BHB7N.cjs +636 -0
  55. package/dist/chunk-CBJY23VL.js +126 -0
  56. package/dist/chunk-CCATWPXM.js +778 -0
  57. package/dist/chunk-CIWWXYHZ.cjs +50 -0
  58. package/dist/chunk-CMT5NMMS.js +669 -0
  59. package/dist/chunk-CR4FMIWL.cjs +1049 -0
  60. package/dist/chunk-CR7XRXRN.cjs +639 -0
  61. package/dist/chunk-CSD27UNQ.js +2176 -0
  62. package/dist/chunk-D3STJ56J.js +714 -0
  63. package/dist/chunk-DAJXW4KX.js +725 -0
  64. package/dist/chunk-DHO2YRIM.js +756 -0
  65. package/dist/chunk-DTGBOSEM.cjs +319 -0
  66. package/dist/chunk-E6XXE66V.js +2252 -0
  67. package/dist/chunk-E7JP3BS3.cjs +61 -0
  68. package/dist/chunk-EKBKLK7P.js +1169 -0
  69. package/dist/chunk-EKYL4PE3.cjs +404 -0
  70. package/dist/chunk-EXKSFGSX.cjs +274 -0
  71. package/dist/chunk-EXUP2BUM.cjs +1173 -0
  72. package/dist/chunk-FDSGHPAK.js +130 -0
  73. package/dist/chunk-FEWUHQNM.cjs +144 -0
  74. package/dist/chunk-FFAOS5HQ.js +70 -0
  75. package/dist/chunk-FGGJQRLZ.js +270 -0
  76. package/dist/chunk-FHP6LXJS.js +415 -0
  77. package/dist/chunk-FJPADH77.cjs +666 -0
  78. package/dist/chunk-FL33V6U7.js +421 -0
  79. package/dist/chunk-FYSPZT4V.cjs +169 -0
  80. package/dist/chunk-GIOYPNTH.js +5575 -0
  81. package/dist/chunk-GJNCFRJU.cjs +125 -0
  82. package/dist/chunk-GMP623FG.cjs +1508 -0
  83. package/dist/chunk-GQHQOPXZ.cjs +5580 -0
  84. package/dist/chunk-GTU2Z2WW.cjs +262 -0
  85. package/dist/chunk-GYZE55MO.js +2007 -0
  86. package/dist/chunk-GZG4KA4E.js +529 -0
  87. package/dist/chunk-H652NHX5.js +600 -0
  88. package/dist/chunk-HCCQLAA4.cjs +74 -0
  89. package/dist/chunk-HKEXJUWS.cjs +4007 -0
  90. package/dist/chunk-HNDK4IQU.cjs +5737 -0
  91. package/dist/chunk-HR2OSYVQ.js +56165 -0
  92. package/dist/chunk-HYNTS5CP.js +422 -0
  93. package/dist/chunk-I6XZ5DZF.cjs +488 -0
  94. package/dist/chunk-ILRBGFVD.cjs +72 -0
  95. package/dist/chunk-IUDGEUDO.cjs +1409 -0
  96. package/dist/chunk-IUTY5WQ2.cjs +424 -0
  97. package/dist/chunk-IVY74O6C.js +247 -0
  98. package/dist/chunk-IWC5DM2M.cjs +611 -0
  99. package/dist/chunk-J32ZJZJH.js +554 -0
  100. package/dist/chunk-J52VSAQ7.js +6884 -0
  101. package/dist/chunk-J6M4FPK5.js +421 -0
  102. package/dist/chunk-J7XZV333.js +844 -0
  103. package/dist/chunk-JBNDTXXV.cjs +2433 -0
  104. package/dist/chunk-JC5YBPSF.cjs +984 -0
  105. package/dist/chunk-JD7CIZ33.js +1949 -0
  106. package/dist/chunk-JIBL5LRK.js +4287 -0
  107. package/dist/chunk-JIYN45TV.cjs +2525 -0
  108. package/dist/chunk-K574J76X.cjs +457 -0
  109. package/dist/chunk-KHDZJE5D.cjs +2196 -0
  110. package/dist/chunk-KKFZ3B6J.cjs +557 -0
  111. package/dist/chunk-KKP7JKN4.cjs +6002 -0
  112. package/dist/chunk-KPJL34Y7.cjs +186 -0
  113. package/dist/chunk-KQCN6AKJ.cjs +3042 -0
  114. package/dist/chunk-L5LKKENW.cjs +424 -0
  115. package/dist/chunk-LHAXPADA.js +882 -0
  116. package/dist/chunk-LM2VU56C.cjs +37 -0
  117. package/dist/chunk-M56JSP4A.js +400 -0
  118. package/dist/chunk-MBOOR7X4.js +18 -0
  119. package/dist/chunk-MQWAT42R.cjs +4310 -0
  120. package/dist/chunk-MXFUTKCO.js +56 -0
  121. package/dist/chunk-MYY4PMWX.cjs +264 -0
  122. package/dist/chunk-N75IH2HY.js +258 -0
  123. package/dist/chunk-NCWCUZNS.cjs +72 -0
  124. package/dist/chunk-NG77ATEW.cjs +778 -0
  125. package/dist/chunk-NW5G5FBQ.js +215 -0
  126. package/dist/chunk-OBIYPYYS.cjs +1993 -0
  127. package/dist/chunk-OH2FAIVU.js +608 -0
  128. package/dist/chunk-OIQYIIO3.cjs +473 -0
  129. package/dist/chunk-OL46QLBJ.js +61 -0
  130. package/dist/chunk-OMXII44L.js +5386 -0
  131. package/dist/chunk-OSYNRVOV.cjs +243 -0
  132. package/dist/chunk-PGANYCAG.cjs +220 -0
  133. package/dist/chunk-PHENW4MQ.js +65 -0
  134. package/dist/chunk-PY37LNDP.js +686 -0
  135. package/dist/chunk-Q56TT7IL.js +483 -0
  136. package/dist/chunk-QD32ADK6.js +1046 -0
  137. package/dist/chunk-QPOQ7VPI.js +1491 -0
  138. package/dist/chunk-QPSKHBJP.js +5963 -0
  139. package/dist/chunk-QXH7QDSZ.js +1989 -0
  140. package/dist/chunk-R24NNAEG.js +1399 -0
  141. package/dist/chunk-R75BSDH7.cjs +50 -0
  142. package/dist/chunk-RARB3MBR.js +207 -0
  143. package/dist/chunk-ROHLEP2W.cjs +847 -0
  144. package/dist/chunk-S3MDHNKB.cjs +490 -0
  145. package/dist/chunk-S6YWHCKV.cjs +410 -0
  146. package/dist/chunk-SIEXCILW.js +229 -0
  147. package/dist/chunk-SLU6UPJI.cjs +410 -0
  148. package/dist/chunk-SMIWS6DE.cjs +212 -0
  149. package/dist/chunk-T5J7ZKP3.cjs +4885 -0
  150. package/dist/chunk-TDCNJHWO.js +341 -0
  151. package/dist/chunk-TG7O4WBC.js +406 -0
  152. package/dist/chunk-THCK6ECW.js +2085 -0
  153. package/dist/chunk-TJHVSBP2.js +439 -0
  154. package/dist/chunk-TVHSPJ4N.cjs +606 -0
  155. package/dist/chunk-TWUXUCEW.cjs +781 -0
  156. package/dist/chunk-U44IKGG7.cjs +5390 -0
  157. package/dist/chunk-UFZZ7TSN.cjs +886 -0
  158. package/dist/chunk-UJXISJBN.js +487 -0
  159. package/dist/chunk-UOIGFQXC.cjs +9750 -0
  160. package/dist/chunk-URG2SJLK.js +2521 -0
  161. package/dist/chunk-UWJHCOH2.js +623 -0
  162. package/dist/chunk-V6MKC2FZ.js +979 -0
  163. package/dist/chunk-VJ3L7CHT.cjs +169 -0
  164. package/dist/chunk-VMLKSV26.js +1216 -0
  165. package/dist/chunk-VVKVQZI6.js +55 -0
  166. package/dist/chunk-W6RW64BB.cjs +1219 -0
  167. package/dist/chunk-WKX5AMOY.js +309 -0
  168. package/dist/chunk-WNNE3PO3.js +34 -0
  169. package/dist/chunk-WRKUDAZJ.js +3038 -0
  170. package/dist/chunk-WRLUBRKS.cjs +1943 -0
  171. package/dist/chunk-WRNEH5MO.js +3169 -0
  172. package/dist/chunk-WRWEX5ZF.js +658 -0
  173. package/dist/chunk-X3GJPRVK.cjs +3246 -0
  174. package/dist/chunk-X3UVCWNL.cjs +2257 -0
  175. package/dist/chunk-XB274MW5.cjs +814 -0
  176. package/dist/chunk-XHIV6326.cjs +793 -0
  177. package/dist/chunk-XIVIE43A.cjs +729 -0
  178. package/dist/chunk-XJAN7CZG.cjs +432 -0
  179. package/dist/chunk-XKTPFXGA.js +164 -0
  180. package/dist/chunk-XL6INWKT.js +121 -0
  181. package/dist/chunk-XSFNHP2E.js +632 -0
  182. package/dist/chunk-XT6JY5W5.js +9684 -0
  183. package/dist/chunk-XUILI4KB.cjs +430 -0
  184. package/dist/chunk-YF2I3MV3.js +46 -0
  185. package/dist/chunk-YIMN575O.js +4847 -0
  186. package/dist/chunk-YIVFJNYV.js +176 -0
  187. package/dist/chunk-YKGPCZEE.cjs +237 -0
  188. package/dist/chunk-YN2YWTXW.js +5731 -0
  189. package/dist/chunk-YN6V7R3L.cjs +327 -0
  190. package/dist/chunk-YQELFNJV.js +39 -0
  191. package/dist/chunk-YVD3CSO3.js +1183 -0
  192. package/dist/chunk-YVOAF4ML.js +623 -0
  193. package/dist/chunk-YWOBW2PV.cjs +759 -0
  194. package/dist/chunk-YYXH45E2.js +426 -0
  195. package/dist/chunk-ZDSYWBIE.cjs +69 -0
  196. package/dist/chunk-ZU7NIRT6.js +325 -0
  197. package/dist/chunk-ZZ7RO2UQ.js +1243 -0
  198. package/dist/cli/holoscript-runner.cjs +2255 -0
  199. package/dist/cli/holoscript-runner.js +2230 -0
  200. package/dist/codebase/index.cjs +336 -0
  201. package/dist/codebase/index.js +331 -0
  202. package/dist/compiler/agent-inference.cjs +31 -0
  203. package/dist/compiler/agent-inference.js +8 -0
  204. package/dist/compiler/android-xr.cjs +24 -0
  205. package/dist/compiler/android-xr.js +14 -0
  206. package/dist/compiler/android.cjs +24 -0
  207. package/dist/compiler/android.js +14 -0
  208. package/dist/compiler/ar.cjs +23 -0
  209. package/dist/compiler/ar.js +11 -0
  210. package/dist/compiler/babylon.cjs +21 -0
  211. package/dist/compiler/babylon.js +15 -0
  212. package/dist/compiler/business-quest.cjs +43 -0
  213. package/dist/compiler/business-quest.js +4 -0
  214. package/dist/compiler/coco.cjs +27 -0
  215. package/dist/compiler/coco.js +4 -0
  216. package/dist/compiler/context.cjs +25 -0
  217. package/dist/compiler/context.d.ts +28 -0
  218. package/dist/compiler/context.js +8 -0
  219. package/dist/compiler/domain-block-utils.cjs +609 -0
  220. package/dist/compiler/domain-block-utils.js +11 -0
  221. package/dist/compiler/dtdl.cjs +27 -0
  222. package/dist/compiler/dtdl.js +11 -0
  223. package/dist/compiler/gltf-pipeline.cjs +39 -0
  224. package/dist/compiler/gltf-pipeline.js +4 -0
  225. package/dist/compiler/godot.cjs +18 -0
  226. package/dist/compiler/godot.js +12 -0
  227. package/dist/compiler/incremental.cjs +34 -0
  228. package/dist/compiler/incremental.js +9 -0
  229. package/dist/compiler/index.cjs +5408 -0
  230. package/dist/compiler/index.d.ts +334 -21
  231. package/dist/compiler/index.js +5069 -0
  232. package/dist/compiler/ios.cjs +23 -0
  233. package/dist/compiler/ios.js +13 -0
  234. package/dist/compiler/llm-provider-capabilities.cjs +25 -0
  235. package/dist/compiler/llm-provider-capabilities.d.ts +43 -0
  236. package/dist/compiler/llm-provider-capabilities.js +8 -0
  237. package/dist/compiler/multi-layer.cjs +24 -0
  238. package/dist/compiler/multi-layer.js +15 -0
  239. package/dist/compiler/nodetoy.cjs +23 -0
  240. package/dist/compiler/nodetoy.d.ts +69 -0
  241. package/dist/compiler/nodetoy.js +4 -0
  242. package/dist/compiler/openxr.cjs +19 -0
  243. package/dist/compiler/openxr.js +13 -0
  244. package/dist/compiler/playcanvas.cjs +19 -0
  245. package/dist/compiler/playcanvas.js +13 -0
  246. package/dist/compiler/r3f.cjs +39 -0
  247. package/dist/compiler/r3f.d.ts +22 -0
  248. package/dist/compiler/r3f.js +17 -0
  249. package/dist/compiler/remotion.cjs +23 -0
  250. package/dist/compiler/remotion.js +4 -0
  251. package/dist/compiler/reproducibility.cjs +39 -0
  252. package/dist/compiler/reproducibility.js +4 -0
  253. package/dist/compiler/sdf.cjs +24 -0
  254. package/dist/compiler/sdf.js +12 -0
  255. package/dist/compiler/semantic-scene.cjs +31 -0
  256. package/dist/compiler/semantic-scene.js +4 -0
  257. package/dist/compiler/state.cjs +21 -0
  258. package/dist/compiler/state.js +11 -0
  259. package/dist/compiler/trait-composition.cjs +30 -0
  260. package/dist/compiler/trait-composition.js +9 -0
  261. package/dist/compiler/unity.cjs +19 -0
  262. package/dist/compiler/unity.js +13 -0
  263. package/dist/compiler/unreal.cjs +23 -0
  264. package/dist/compiler/unreal.js +13 -0
  265. package/dist/compiler/urdf.cjs +52 -0
  266. package/dist/compiler/urdf.js +12 -0
  267. package/dist/compiler/usd-physics.cjs +26 -0
  268. package/dist/compiler/usd-physics.js +9 -0
  269. package/dist/compiler/visionos.cjs +19 -0
  270. package/dist/compiler/visionos.js +13 -0
  271. package/dist/compiler/vrchat.cjs +22 -0
  272. package/dist/compiler/vrchat.js +12 -0
  273. package/dist/compiler/vrr.cjs +24 -0
  274. package/dist/compiler/vrr.js +12 -0
  275. package/dist/compiler/wasm.cjs +36 -0
  276. package/dist/compiler/wasm.js +12 -0
  277. package/dist/compiler/webgpu.cjs +18 -0
  278. package/dist/compiler/webgpu.js +12 -0
  279. package/dist/coordinators/index.cjs +1266 -0
  280. package/dist/coordinators/index.d.ts +72 -1
  281. package/dist/coordinators/index.js +1259 -0
  282. package/dist/debugger.cjs +24 -0
  283. package/dist/debugger.js +11 -0
  284. package/dist/dist-ACXG6IH5.cjs +3113 -0
  285. package/dist/dist-VD4L6V7Q.js +3076 -0
  286. package/dist/entries/interop.cjs +64 -0
  287. package/dist/entries/interop.js +7 -0
  288. package/dist/entries/scripting.cjs +55 -0
  289. package/dist/entries/scripting.js +10 -0
  290. package/dist/hololand/index.cjs +146 -0
  291. package/dist/hololand/index.d.ts +70 -0
  292. package/dist/hololand/index.js +5 -0
  293. package/dist/index.cjs +44660 -0
  294. package/dist/index.d.ts +978 -21
  295. package/dist/index.js +41422 -0
  296. package/dist/math/tropical-spmv.cjs +45 -0
  297. package/dist/math/tropical-spmv.js +4 -0
  298. package/dist/math/vec3.cjs +57 -0
  299. package/dist/math/vec3.js +4 -0
  300. package/dist/ml-dsa-FSKBTE3W.cjs +1265 -0
  301. package/dist/ml-dsa-Z7JDKW4L.js +1265 -0
  302. package/dist/paper-0c-spike/index.cjs +150 -0
  303. package/dist/paper-0c-spike/index.js +141 -0
  304. package/dist/parser.cjs +61 -0
  305. package/dist/parser.d.ts +11 -0
  306. package/dist/parser.js +12 -0
  307. package/dist/playwright-3AT3AKTV.cjs +98673 -0
  308. package/dist/playwright-VZPDVUEQ.js +98660 -0
  309. package/dist/reconstruction/index.cjs +153 -0
  310. package/dist/reconstruction/index.d.ts +29 -2
  311. package/dist/reconstruction/index.js +8 -0
  312. package/dist/runtime.cjs +316 -0
  313. package/dist/runtime.d.ts +61 -0
  314. package/dist/runtime.js +31 -0
  315. package/dist/self-improvement/index.cjs +563 -0
  316. package/dist/self-improvement/index.js +545 -0
  317. package/dist/src-4ROC227P.cjs +2094 -0
  318. package/dist/src-HCCCSYP7.js +2073 -0
  319. package/dist/storage/index.cjs +38 -0
  320. package/dist/storage/index.js +5 -0
  321. package/dist/testing.cjs +25 -0
  322. package/dist/testing.d.ts +70 -0
  323. package/dist/testing.js +4 -0
  324. package/dist/traitDocs/traitDocs.cjs +33 -0
  325. package/dist/traitDocs/traitDocs.js +7 -0
  326. package/dist/traits/botanical-lotus.cjs +177 -0
  327. package/dist/traits/botanical-lotus.d.ts +502 -0
  328. package/dist/traits/botanical-lotus.js +7 -0
  329. package/dist/traits/engines/index.cjs +520 -0
  330. package/dist/traits/engines/index.js +380 -0
  331. package/dist/traits/index.cjs +24548 -0
  332. package/dist/traits/index.d.ts +171 -35
  333. package/dist/traits/index.js +21638 -0
  334. package/dist/traits/simulation-solver-factory.cjs +13 -0
  335. package/dist/traits/simulation-solver-factory.d.ts +23 -0
  336. package/dist/traits/simulation-solver-factory.js +4 -0
  337. package/dist/traits/webcam-gaze.cjs +35 -0
  338. package/dist/traits/webcam-gaze.d.ts +17 -0
  339. package/dist/traits/webcam-gaze.js +4 -0
  340. package/dist/type-checker.cjs +19 -0
  341. package/dist/type-checker.js +6 -0
  342. package/dist/world/index.cjs +947 -0
  343. package/dist/world/index.d.ts +147 -0
  344. package/dist/world/index.js +939 -0
  345. package/dist/world-model/index.cjs +1446 -0
  346. package/dist/world-model/index.d.ts +119 -0
  347. package/dist/world-model/index.js +1414 -0
  348. package/dist/wot/index.cjs +29 -0
  349. package/dist/wot/index.js +4 -0
  350. package/package.json +93 -49
@@ -0,0 +1,1216 @@
1
+ import { loadConstraintsFromConfig, BUILTIN_CONSTRAINTS } from './chunk-XSFNHP2E.js';
2
+
3
+ // src/types/AdvancedTypeSystem.ts
4
+ var ExhaustivenessChecker = class {
5
+ /**
6
+ * Check if all union members are covered in match statement
7
+ */
8
+ checkMatch(unionType, casePatterns) {
9
+ const patterns = new Set(casePatterns.map((p) => p.toLowerCase()));
10
+ const uncovered = [];
11
+ for (const member of unionType.members) {
12
+ const caseName = this.getCaseName(member);
13
+ if (!patterns.has(caseName.toLowerCase()) && caseName !== "_") {
14
+ uncovered.push(caseName);
15
+ }
16
+ }
17
+ return {
18
+ isExhaustive: uncovered.length === 0 || patterns.has("_"),
19
+ uncoveredCases: uncovered
20
+ };
21
+ }
22
+ getCaseName(type) {
23
+ if (type.kind === "literal") {
24
+ return String(type.value);
25
+ }
26
+ if (type.kind === "custom") {
27
+ return type.name;
28
+ }
29
+ return type.kind;
30
+ }
31
+ };
32
+
33
+ // src/types/TypeAliasRegistry.ts
34
+ var TypeAliasRegistry = class {
35
+ constructor() {
36
+ this.aliases = /* @__PURE__ */ new Map();
37
+ /** Tracks which aliases are currently being expanded (cycle detection) */
38
+ this.expanding = /* @__PURE__ */ new Set();
39
+ }
40
+ // ---------------------------------------------------------------------------
41
+ // Registration
42
+ // ---------------------------------------------------------------------------
43
+ register(decl) {
44
+ this.aliases.set(decl.name, decl);
45
+ }
46
+ has(name) {
47
+ return this.aliases.has(name);
48
+ }
49
+ get(name) {
50
+ return this.aliases.get(name);
51
+ }
52
+ all() {
53
+ return Array.from(this.aliases.values());
54
+ }
55
+ clear() {
56
+ this.aliases.clear();
57
+ this.expanding.clear();
58
+ }
59
+ // ---------------------------------------------------------------------------
60
+ // Parsing helper (parses a `type Foo = ...` source line)
61
+ // ---------------------------------------------------------------------------
62
+ /**
63
+ * Parse a type alias declaration from source text.
64
+ * Recognises:
65
+ * type Name = definition
66
+ * type Name<T, U> = definition
67
+ */
68
+ static parse(source, line) {
69
+ const match = source.match(/^\s*type\s+([A-Z][A-Za-z0-9_]*)(?:<([^>]+)>)?\s*=\s*(.+)$/);
70
+ if (!match) return null;
71
+ const name = match[1];
72
+ const rawParams = match[2];
73
+ const definition = match[3].trim();
74
+ const typeParams = rawParams ? rawParams.split(",").map((p) => p.trim()).filter(Boolean) : [];
75
+ const isUnion = definition.includes("|");
76
+ const kind = typeParams.length > 0 ? "generic" : isUnion ? "union" : "simple";
77
+ return { name, kind, definition, typeParams, line };
78
+ }
79
+ // ---------------------------------------------------------------------------
80
+ // Resolution
81
+ // ---------------------------------------------------------------------------
82
+ /**
83
+ * Resolve an alias by name, substituting type params if provided.
84
+ * Returns null if unknown or recursive.
85
+ *
86
+ * Example:
87
+ * registry.resolve('Optional', ['string'])
88
+ * → 'string | null'
89
+ */
90
+ resolve(name, typeArgs = []) {
91
+ if (this.expanding.has(name)) {
92
+ return null;
93
+ }
94
+ const decl = this.aliases.get(name);
95
+ if (!decl) return null;
96
+ if (this.containsAlias(decl.definition, name)) {
97
+ return null;
98
+ }
99
+ this.expanding.add(name);
100
+ try {
101
+ let expanded = decl.definition;
102
+ if (decl.typeParams && decl.typeParams.length > 0) {
103
+ for (let i = 0; i < decl.typeParams.length; i++) {
104
+ const param = decl.typeParams[i];
105
+ const arg = typeArgs[i] ?? "any";
106
+ expanded = expanded.replace(new RegExp(`\\b${param}\\b`, "g"), arg);
107
+ }
108
+ }
109
+ expanded = this.expandReferences(expanded);
110
+ return expanded;
111
+ } finally {
112
+ this.expanding.delete(name);
113
+ }
114
+ }
115
+ /**
116
+ * Detect recursive/self-referential type aliases.
117
+ */
118
+ isRecursive(name) {
119
+ const decl = this.aliases.get(name);
120
+ if (!decl) return false;
121
+ this.expanding.add(name);
122
+ const result = this.containsAlias(decl.definition, name);
123
+ this.expanding.delete(name);
124
+ return result;
125
+ }
126
+ // ---------------------------------------------------------------------------
127
+ // Private helpers
128
+ // ---------------------------------------------------------------------------
129
+ expandReferences(definition) {
130
+ let result = definition;
131
+ for (const [aliasName, decl] of this.aliases) {
132
+ if (this.expanding.has(aliasName)) continue;
133
+ const pattern = new RegExp(`\\b${aliasName}\\b`, "g");
134
+ if (pattern.test(result)) {
135
+ const resolved = this.resolve(aliasName);
136
+ if (resolved) {
137
+ result = result.replace(new RegExp(`\\b${aliasName}\\b`, "g"), `(${resolved})`);
138
+ }
139
+ }
140
+ }
141
+ return result;
142
+ }
143
+ containsAlias(definition, targetName) {
144
+ const pattern = new RegExp(`\\b${targetName}\\b`);
145
+ return pattern.test(definition);
146
+ }
147
+ };
148
+
149
+ // src/HoloScriptTypeChecker.ts
150
+ var BUILTIN_FUNCTIONS = /* @__PURE__ */ new Map([
151
+ [
152
+ "add",
153
+ {
154
+ type: "function",
155
+ parameters: [
156
+ { name: "a", type: "number" },
157
+ { name: "b", type: "number" }
158
+ ],
159
+ returnType: "number"
160
+ }
161
+ ],
162
+ [
163
+ "subtract",
164
+ {
165
+ type: "function",
166
+ parameters: [
167
+ { name: "a", type: "number" },
168
+ { name: "b", type: "number" }
169
+ ],
170
+ returnType: "number"
171
+ }
172
+ ],
173
+ [
174
+ "multiply",
175
+ {
176
+ type: "function",
177
+ parameters: [
178
+ { name: "a", type: "number" },
179
+ { name: "b", type: "number" }
180
+ ],
181
+ returnType: "number"
182
+ }
183
+ ],
184
+ [
185
+ "divide",
186
+ {
187
+ type: "function",
188
+ parameters: [
189
+ { name: "a", type: "number" },
190
+ { name: "b", type: "number" }
191
+ ],
192
+ returnType: "number"
193
+ }
194
+ ],
195
+ [
196
+ "concat",
197
+ {
198
+ type: "function",
199
+ parameters: [
200
+ { name: "a", type: "string" },
201
+ { name: "b", type: "string" }
202
+ ],
203
+ returnType: "string"
204
+ }
205
+ ],
206
+ [
207
+ "length",
208
+ { type: "function", parameters: [{ name: "value", type: "any" }], returnType: "number" }
209
+ ],
210
+ [
211
+ "push",
212
+ {
213
+ type: "function",
214
+ parameters: [
215
+ { name: "arr", type: "array" },
216
+ { name: "item", type: "any" }
217
+ ],
218
+ returnType: "array"
219
+ }
220
+ ],
221
+ ["pop", { type: "function", parameters: [{ name: "arr", type: "array" }], returnType: "any" }],
222
+ ["log", { type: "function", parameters: [{ name: "message", type: "any" }], returnType: "void" }],
223
+ [
224
+ "print",
225
+ { type: "function", parameters: [{ name: "message", type: "any" }], returnType: "void" }
226
+ ],
227
+ ["show", { type: "function", parameters: [{ name: "target", type: "orb" }], returnType: "void" }],
228
+ ["hide", { type: "function", parameters: [{ name: "target", type: "orb" }], returnType: "void" }],
229
+ [
230
+ "pulse",
231
+ { type: "function", parameters: [{ name: "target", type: "orb" }], returnType: "void" }
232
+ ],
233
+ [
234
+ "animate",
235
+ {
236
+ type: "function",
237
+ parameters: [
238
+ { name: "target", type: "orb" },
239
+ { name: "config", type: "object" }
240
+ ],
241
+ returnType: "void"
242
+ }
243
+ ],
244
+ [
245
+ "spawn",
246
+ {
247
+ type: "function",
248
+ parameters: [
249
+ { name: "type", type: "string" },
250
+ { name: "position", type: "object" }
251
+ ],
252
+ returnType: "orb"
253
+ }
254
+ ],
255
+ [
256
+ "isNumber",
257
+ { type: "function", parameters: [{ name: "value", type: "any" }], returnType: "boolean" }
258
+ ],
259
+ [
260
+ "isString",
261
+ { type: "function", parameters: [{ name: "value", type: "any" }], returnType: "boolean" }
262
+ ],
263
+ [
264
+ "isArray",
265
+ { type: "function", parameters: [{ name: "value", type: "any" }], returnType: "boolean" }
266
+ ],
267
+ // Simulation built-in functions (v4.2)
268
+ [
269
+ "createCollider",
270
+ {
271
+ type: "function",
272
+ parameters: [
273
+ { name: "shape", type: "string" },
274
+ { name: "config", type: "object" }
275
+ ],
276
+ returnType: "object"
277
+ }
278
+ ],
279
+ [
280
+ "createRigidbody",
281
+ {
282
+ type: "function",
283
+ parameters: [
284
+ { name: "mass", type: "number" },
285
+ { name: "config", type: "object" }
286
+ ],
287
+ returnType: "object"
288
+ }
289
+ ],
290
+ [
291
+ "createMaterial",
292
+ {
293
+ type: "function",
294
+ parameters: [
295
+ { name: "name", type: "string" },
296
+ { name: "preset", type: "string" }
297
+ ],
298
+ returnType: "object"
299
+ }
300
+ ],
301
+ [
302
+ "createParticleSystem",
303
+ { type: "function", parameters: [{ name: "config", type: "object" }], returnType: "object" }
304
+ ],
305
+ [
306
+ "applyForce",
307
+ {
308
+ type: "function",
309
+ parameters: [
310
+ { name: "target", type: "orb" },
311
+ { name: "force", type: "vec3" }
312
+ ],
313
+ returnType: "void"
314
+ }
315
+ ],
316
+ [
317
+ "raycast",
318
+ {
319
+ type: "function",
320
+ parameters: [
321
+ { name: "origin", type: "vec3" },
322
+ { name: "direction", type: "vec3" },
323
+ { name: "maxDistance", type: "number" }
324
+ ],
325
+ returnType: "object"
326
+ }
327
+ ],
328
+ [
329
+ "playAudio",
330
+ {
331
+ type: "function",
332
+ parameters: [
333
+ { name: "clip", type: "string" },
334
+ { name: "config", type: "object" }
335
+ ],
336
+ returnType: "void"
337
+ }
338
+ ],
339
+ [
340
+ "setWeather",
341
+ { type: "function", parameters: [{ name: "preset", type: "string" }], returnType: "void" }
342
+ ],
343
+ [
344
+ "generateTerrain",
345
+ { type: "function", parameters: [{ name: "config", type: "object" }], returnType: "object" }
346
+ ],
347
+ [
348
+ "navigate",
349
+ {
350
+ type: "function",
351
+ parameters: [
352
+ { name: "agent", type: "orb" },
353
+ { name: "target", type: "vec3" }
354
+ ],
355
+ returnType: "void"
356
+ }
357
+ ],
358
+ [
359
+ "distance",
360
+ {
361
+ type: "function",
362
+ parameters: [
363
+ { name: "a", type: "vec3" },
364
+ { name: "b", type: "vec3" }
365
+ ],
366
+ returnType: "number"
367
+ }
368
+ ]
369
+ ]);
370
+ var HoloScriptTypeChecker = class {
371
+ constructor() {
372
+ this.typeMap = /* @__PURE__ */ new Map();
373
+ this.diagnostics = [];
374
+ this.currentLine = 0;
375
+ this.currentColumn = 0;
376
+ /** Registry for user-defined union types (e.g., type State = "idle" | "loading" | "error") */
377
+ this.unionTypes = /* @__PURE__ */ new Map();
378
+ /** Type alias registry (type Color = string | number[], type List<T> = T[]) */
379
+ this.typeAliasRegistry = new TypeAliasRegistry();
380
+ /** Custom constraints merged from holoscript.config.json */
381
+ this.customConstraints = [];
382
+ /** Diagnostics accumulated before check() so they survive the diagnostics reset */
383
+ this.preCheckDiagnostics = [];
384
+ BUILTIN_FUNCTIONS.forEach((type, name) => {
385
+ this.typeMap.set(name, type);
386
+ });
387
+ this.exhaustivenessChecker = new ExhaustivenessChecker();
388
+ }
389
+ /**
390
+ * Merge custom constraints from a parsed config object.
391
+ * Call before check() when you have a holoscript.config.json.
392
+ */
393
+ loadConfig(config) {
394
+ this.customConstraints = loadConstraintsFromConfig(config);
395
+ }
396
+ /**
397
+ * Register a type alias (e.g. from a `type Foo = ...` declaration in source).
398
+ */
399
+ registerTypeAlias(decl) {
400
+ this.typeAliasRegistry.register(decl);
401
+ if (this.typeAliasRegistry.isRecursive(decl.name)) {
402
+ this.preCheckDiagnostics.push({
403
+ severity: "error",
404
+ message: `Type alias '${decl.name}' is recursive and cannot be expanded.`,
405
+ line: decl.line ?? 0,
406
+ column: 0,
407
+ code: "HSP020",
408
+ suggestions: [`Remove the self-reference in '${decl.name}' definition.`]
409
+ });
410
+ }
411
+ }
412
+ /**
413
+ * Type check an AST
414
+ */
415
+ check(ast) {
416
+ this.diagnostics = [...this.preCheckDiagnostics];
417
+ for (const node of ast) {
418
+ this.collectDeclaration(node);
419
+ }
420
+ this.checkBlock(ast);
421
+ return {
422
+ valid: this.diagnostics.filter((d) => d.severity === "error").length === 0,
423
+ diagnostics: this.diagnostics,
424
+ typeMap: new Map(this.typeMap)
425
+ };
426
+ }
427
+ /**
428
+ * Collect type declarations
429
+ */
430
+ collectDeclaration(node) {
431
+ switch (node.type) {
432
+ case "orb":
433
+ this.collectOrbDeclaration(node);
434
+ break;
435
+ case "method":
436
+ this.collectMethodDeclaration(node);
437
+ break;
438
+ case "variable-declaration":
439
+ this.collectVariableDeclaration(node);
440
+ break;
441
+ case "stream":
442
+ this.collectStreamDeclaration(node);
443
+ break;
444
+ case "template":
445
+ this.collectTemplateDeclaration(node);
446
+ break;
447
+ }
448
+ }
449
+ collectTemplateDeclaration(node) {
450
+ this.typeMap.set(node.name, {
451
+ type: "object"
452
+ // We could try to infer properties from body if structure allows,
453
+ // but for now simple registration is enough to pass "Unknown variable" checks
454
+ });
455
+ }
456
+ collectOrbDeclaration(node) {
457
+ const properties = /* @__PURE__ */ new Map();
458
+ properties.set("position", { type: "vec3" });
459
+ properties.set("rotation", { type: "euler" });
460
+ properties.set("scale", { type: "vec3" });
461
+ properties.set("color", { type: "color" });
462
+ properties.set("glow", { type: "boolean" });
463
+ properties.set("interactive", { type: "boolean" });
464
+ properties.set("visible", { type: "boolean" });
465
+ for (const [key, value] of Object.entries(node.properties)) {
466
+ const expectedType = properties.get(key);
467
+ properties.set(key, this.inferTypeWithContext(value, expectedType));
468
+ }
469
+ this.typeMap.set(node.name, {
470
+ type: "orb",
471
+ properties
472
+ });
473
+ }
474
+ collectMethodDeclaration(node) {
475
+ const parameters = node.parameters.map((p) => ({
476
+ name: p.name,
477
+ type: this.parseTypeString(p.dataType),
478
+ optional: p.defaultValue !== void 0,
479
+ defaultValue: p.defaultValue
480
+ }));
481
+ this.typeMap.set(node.name, {
482
+ type: "function",
483
+ parameters,
484
+ returnType: node.returnType ? this.parseTypeString(node.returnType) : "void"
485
+ });
486
+ }
487
+ collectVariableDeclaration(node) {
488
+ let typeInfo = { type: "any" };
489
+ if (node.dataType) {
490
+ typeInfo = { type: this.parseTypeString(node.dataType) };
491
+ if (node.value !== void 0) {
492
+ this.inferTypeWithContext(node.value, typeInfo);
493
+ }
494
+ } else if (node.value !== void 0) {
495
+ typeInfo = this.inferType(node.value);
496
+ }
497
+ this.typeMap.set(node.name, typeInfo);
498
+ }
499
+ collectStreamDeclaration(node) {
500
+ this.typeMap.set(node.name, {
501
+ type: "stream",
502
+ properties: /* @__PURE__ */ new Map([
503
+ ["source", { type: "string" }],
504
+ ["result", { type: "any" }]
505
+ ])
506
+ });
507
+ }
508
+ /**
509
+ * Check a node for type errors
510
+ */
511
+ checkNode(node) {
512
+ this.currentLine = node.position?.[0] ?? 0;
513
+ this.currentColumn = node.position?.[1] ?? 0;
514
+ switch (node.type) {
515
+ case "connection":
516
+ this.checkConnection(node);
517
+ break;
518
+ case "gate":
519
+ this.checkGate(node);
520
+ break;
521
+ case "for-loop":
522
+ this.checkForLoop(node);
523
+ break;
524
+ case "while-loop":
525
+ this.checkWhileLoop(node);
526
+ break;
527
+ case "foreach-loop":
528
+ this.checkForEachLoop(node);
529
+ break;
530
+ case "import":
531
+ this.checkImport(node);
532
+ break;
533
+ case "export":
534
+ this.checkExport(node);
535
+ break;
536
+ case "type-guard":
537
+ this.checkTypeGuard(node);
538
+ break;
539
+ case "variable-declaration":
540
+ this.checkVariableDeclaration(node);
541
+ break;
542
+ case "method":
543
+ this.checkBlock(node.body);
544
+ break;
545
+ case "orb":
546
+ this.validateTraitConstraints(node);
547
+ this.checkBlock(node.children || []);
548
+ break;
549
+ case "template":
550
+ this.validateTraitConstraints(node);
551
+ this.checkBlock(node.children || []);
552
+ break;
553
+ case "spread":
554
+ this.checkSpread(node);
555
+ break;
556
+ case "nullCoalescingAssignment":
557
+ this.checkNullCoalescingAssignment(node);
558
+ break;
559
+ case "match":
560
+ this.checkMatchExpression(node);
561
+ break;
562
+ }
563
+ }
564
+ checkNullCoalescingAssignment(node) {
565
+ if (!node.target) {
566
+ this.addDiagnostic("error", `Null coalescing assignment missing target`, "E104");
567
+ return;
568
+ }
569
+ const targetStr = typeof node.target === "string" ? node.target : node.target?.__ref || node.target?.name;
570
+ if (!targetStr) {
571
+ this.addDiagnostic(
572
+ "error",
573
+ `Null coalescing assignment to non-assignable expression`,
574
+ "E105"
575
+ );
576
+ return;
577
+ }
578
+ const targetType = this.typeMap.get(targetStr);
579
+ const valueType = node.value ? this.inferType(node.value) : "unknown";
580
+ this.typeMap.set(
581
+ targetStr,
582
+ targetType || { type: valueType, nullable: false }
583
+ );
584
+ }
585
+ checkSpread(node) {
586
+ if (!node.target) {
587
+ this.addDiagnostic("error", `Spread expression missing target`, "E102");
588
+ return;
589
+ }
590
+ if (!this.typeMap.has(node.target)) {
591
+ this.addDiagnostic("error", `Unknown template or object '${node.target}' in spread`, "E102");
592
+ } else {
593
+ const type = this.typeMap.get(node.target);
594
+ if (type && type.type !== "object" && type.type !== "orb" && type.type !== "any") {
595
+ this.addDiagnostic(
596
+ "error",
597
+ `Cannot spread '${node.target}' type '${type.type}', must be object or template`,
598
+ "E103"
599
+ );
600
+ }
601
+ }
602
+ }
603
+ /**
604
+ * Check a match expression for:
605
+ * 1. Valid subject expression
606
+ * 2. Exhaustiveness - all union cases are covered
607
+ * 3. Unreachable patterns (after wildcard)
608
+ * 4. Type consistency in case bodies
609
+ */
610
+ checkMatchExpression(node) {
611
+ if (!node.subject) {
612
+ this.addDiagnostic("error", "Match expression missing subject", "E200");
613
+ return;
614
+ }
615
+ if (!node.cases || node.cases.length === 0) {
616
+ this.addDiagnostic("error", "Match expression has no cases", "E201");
617
+ return;
618
+ }
619
+ const subjectId = typeof node.subject === "string" ? node.subject : node.subject?.__ref || node.subject?.name;
620
+ let unionType;
621
+ if (subjectId && this.unionTypes.has(subjectId)) {
622
+ unionType = this.unionTypes.get(subjectId);
623
+ }
624
+ const casePatterns = [];
625
+ let hasWildcard = false;
626
+ let wildcardIndex = -1;
627
+ for (let i = 0; i < node.cases.length; i++) {
628
+ const matchCase = node.cases[i];
629
+ const pattern = matchCase.pattern;
630
+ if (!pattern) {
631
+ this.addDiagnostic("error", `Match case ${i + 1} has no pattern`, "E202");
632
+ continue;
633
+ }
634
+ if (pattern.type === "wildcard-pattern") {
635
+ if (hasWildcard) {
636
+ this.addDiagnostic(
637
+ "warning",
638
+ `Duplicate wildcard pattern at case ${i + 1} - only the first wildcard will be reached`,
639
+ "W200"
640
+ );
641
+ } else {
642
+ hasWildcard = true;
643
+ wildcardIndex = i;
644
+ }
645
+ casePatterns.push("_");
646
+ } else if (pattern.type === "literal-pattern") {
647
+ const value = String(pattern.value);
648
+ if (casePatterns.includes(value)) {
649
+ this.addDiagnostic(
650
+ "warning",
651
+ `Duplicate pattern "${value}" at case ${i + 1} - this case will never be reached`,
652
+ "W201"
653
+ );
654
+ }
655
+ casePatterns.push(value);
656
+ } else if (pattern.type === "binding-pattern") {
657
+ casePatterns.push(pattern.name);
658
+ }
659
+ if (hasWildcard && i > wildcardIndex) {
660
+ this.addDiagnostic(
661
+ "warning",
662
+ `Unreachable pattern at case ${i + 1} - previous wildcard (_) matches all remaining cases`,
663
+ "W202",
664
+ ["Remove this case or reorder patterns"]
665
+ );
666
+ }
667
+ if (Array.isArray(matchCase.body)) {
668
+ this.checkBlock(matchCase.body);
669
+ }
670
+ }
671
+ if (unionType) {
672
+ const result = this.exhaustivenessChecker.checkMatch(unionType, casePatterns);
673
+ if (!result.isExhaustive && !hasWildcard) {
674
+ const missingCases = result.uncoveredCases.map((c) => `"${c}"`).join(", ");
675
+ this.addDiagnostic(
676
+ "error",
677
+ `Non-exhaustive match. Missing cases: ${missingCases}`,
678
+ "E203",
679
+ result.uncoveredCases.map((c) => `Add case: "${c}" => ...`)
680
+ );
681
+ }
682
+ } else if (!hasWildcard && subjectId) {
683
+ this.addDiagnostic(
684
+ "info",
685
+ `Match expression on '${subjectId}' may be non-exhaustive. Consider adding a wildcard (_) case.`,
686
+ "I200"
687
+ );
688
+ }
689
+ }
690
+ /**
691
+ * Register a union type for exhaustiveness checking
692
+ * Example: type State = "idle" | "loading" | "success" | "error"
693
+ */
694
+ registerUnionType(name, members) {
695
+ const unionMembers = members.map((m) => ({
696
+ kind: "literal",
697
+ value: m
698
+ }));
699
+ this.unionTypes.set(name, {
700
+ kind: "union",
701
+ members: unionMembers
702
+ });
703
+ }
704
+ /**
705
+ * Get the union type for a registered name
706
+ */
707
+ getUnionType(name) {
708
+ return this.unionTypes.get(name);
709
+ }
710
+ /**
711
+ * Check if a match expression is exhaustive given the union type.
712
+ * Returns HSP021 diagnostics for missing cases.
713
+ */
714
+ checkExhaustiveMatch(matchExpr) {
715
+ const decl = this.typeAliasRegistry.get(matchExpr.typeName);
716
+ if (!decl) return [];
717
+ if (decl.kind !== "union" && decl.kind !== "simple") return [];
718
+ if (matchExpr.coveredPatterns.includes("_")) return [];
719
+ const members = this.extractUnionMembers(decl.definition);
720
+ if (members.length === 0) return [];
721
+ const coveredSet = new Set(matchExpr.coveredPatterns);
722
+ const missing = members.filter((m) => !coveredSet.has(m));
723
+ if (missing.length === 0) return [];
724
+ const missingStr = missing.map((m) => '"' + m + '"').join(", ");
725
+ return [
726
+ {
727
+ code: "HSP021",
728
+ message: "Non-exhaustive match on '" + matchExpr.typeName + "'. Missing: " + missingStr,
729
+ severity: "error",
730
+ line: matchExpr.line ?? 0,
731
+ column: matchExpr.column ?? 0,
732
+ suggestions: missing.map((m) => "Add case: " + m + " => ...")
733
+ }
734
+ ];
735
+ }
736
+ /**
737
+ * Extract individual members from a union type definition string.
738
+ * Handles string literals, number literals, and identifiers.
739
+ */
740
+ extractUnionMembers(definition) {
741
+ const parts = definition.split("|").map((p) => p.trim()).filter(Boolean);
742
+ const members = [];
743
+ for (const part of parts) {
744
+ const strMatch = part.match(/^["'](.+?)["']$/);
745
+ if (strMatch) {
746
+ members.push(strMatch[1]);
747
+ continue;
748
+ }
749
+ if (/^-?\d+(\.\d+)?$/.test(part)) {
750
+ members.push(part);
751
+ continue;
752
+ }
753
+ }
754
+ return members;
755
+ }
756
+ checkBlock(nodes) {
757
+ if (!nodes) return;
758
+ for (const node of nodes) {
759
+ this.checkNode(node);
760
+ if (node.type === "expression-statement" && typeof node.expression === "string") {
761
+ const varName = node.expression;
762
+ const typeInfo = this.typeMap.get(varName);
763
+ if (typeInfo) {
764
+ this.addDiagnostic("info", `Type of '${varName}' is ${typeInfo.type}`, "DEBUG");
765
+ }
766
+ }
767
+ }
768
+ }
769
+ /**
770
+ * Check if two types are compatible
771
+ */
772
+ isCompatible(source, target) {
773
+ if (source.type === "any" || target.type === "any") return true;
774
+ if (source.type === target.type) return true;
775
+ if (target.type === "vec3" && source.type === "euler") return true;
776
+ if (target.type === "euler" && source.type === "vec3") return true;
777
+ if (target.type === "vec4" && source.type === "quat") return true;
778
+ if (target.type === "quat" && source.type === "vec4") return true;
779
+ return false;
780
+ }
781
+ checkConnection(node) {
782
+ const fromType = this.typeMap.get(node.from);
783
+ const toType = this.typeMap.get(node.to);
784
+ if (!fromType) {
785
+ this.addDiagnostic("error", `Unknown source '${node.from}' in connection`, "E001");
786
+ }
787
+ if (!toType) {
788
+ this.addDiagnostic("error", `Unknown target '${node.to}' in connection`, "E002");
789
+ }
790
+ if (fromType && toType && node.dataType !== "any") {
791
+ if (!this.isCompatible(fromType, toType)) {
792
+ this.addDiagnostic(
793
+ "warning",
794
+ `Connection from '${node.from}' (${fromType.type}) to '${node.to}' (${toType.type}) may be incompatible`,
795
+ "W001",
796
+ [`Consider using 'as "any"' to bypass type checking`]
797
+ );
798
+ }
799
+ }
800
+ }
801
+ checkGate(node) {
802
+ let narrowedVar;
803
+ let narrowedType;
804
+ if (typeof node.condition === "string") {
805
+ const conditionVars = this.extractVariables(node.condition);
806
+ for (const varName of conditionVars) {
807
+ if (!this.typeMap.has(varName) && !this.isLiteral(varName)) {
808
+ this.addDiagnostic("error", `Unknown variable '${varName}' in gate condition`, "E003");
809
+ }
810
+ }
811
+ } else if (node.condition.type === "type-guard") {
812
+ narrowedVar = node.condition.subject;
813
+ narrowedType = { type: this.parseTypeString(node.condition.guardType) };
814
+ this.checkTypeGuard(node.condition);
815
+ }
816
+ if (narrowedVar && narrowedType) {
817
+ const originalType = this.typeMap.get(narrowedVar);
818
+ this.typeMap.set(narrowedVar, narrowedType);
819
+ this.addDiagnostic("info", `Type of '${narrowedVar}' is ${narrowedType.type}`, "DEBUG");
820
+ this.checkBlock(node.truePath);
821
+ if (originalType) this.typeMap.set(narrowedVar, originalType);
822
+ else this.typeMap.delete(narrowedVar);
823
+ } else {
824
+ this.checkBlock(node.truePath);
825
+ }
826
+ if (node.falsePath && node.falsePath.length > 0) {
827
+ this.checkBlock(node.falsePath);
828
+ }
829
+ }
830
+ checkTypeGuard(node) {
831
+ if (!this.typeMap.has(node.subject)) {
832
+ this.addDiagnostic("error", `Unknown variable '${node.subject}' in type guard`, "E101");
833
+ }
834
+ }
835
+ checkVariableDeclaration(node) {
836
+ const typeInfo = this.typeMap.get(node.name);
837
+ if (typeInfo && node.value !== void 0 && !node.isExpression) {
838
+ const inferredValueType = this.inferTypeWithContext(node.value, typeInfo);
839
+ if (!this.isCompatible(inferredValueType, typeInfo)) {
840
+ this.addDiagnostic(
841
+ "error",
842
+ `Type mismatch: cannot assign ${inferredValueType.type} to ${typeInfo.type}`,
843
+ "E102"
844
+ );
845
+ }
846
+ }
847
+ if (node.isExpression && typeof node.value === "string") {
848
+ const vars = this.extractVariables(node.value);
849
+ for (const v of vars) {
850
+ if (!this.typeMap.has(v) && !this.isLiteral(v) && !BUILTIN_FUNCTIONS.has(v)) {
851
+ this.addDiagnostic(
852
+ "warning",
853
+ `Reference to potentially undeclared variable '${v}'`,
854
+ "W101"
855
+ );
856
+ }
857
+ }
858
+ }
859
+ }
860
+ checkForLoop(node) {
861
+ const initVars = this.extractVariables(node.init);
862
+ for (const varName of initVars) {
863
+ if (!this.typeMap.has(varName)) {
864
+ this.typeMap.set(varName, { type: "number" });
865
+ }
866
+ }
867
+ if (typeof node.condition === "string") {
868
+ const condVars = this.extractVariables(node.condition);
869
+ for (const varName of condVars) {
870
+ if (!this.typeMap.has(varName) && !this.isLiteral(varName)) {
871
+ this.addDiagnostic(
872
+ "error",
873
+ `Unknown variable '${varName}' in for loop condition`,
874
+ "E004"
875
+ );
876
+ }
877
+ }
878
+ } else {
879
+ this.checkTypeGuard(node.condition);
880
+ }
881
+ this.checkBlock(node.body);
882
+ }
883
+ checkWhileLoop(node) {
884
+ if (typeof node.condition === "string") {
885
+ const condVars = this.extractVariables(node.condition);
886
+ for (const varName of condVars) {
887
+ if (!this.typeMap.has(varName) && !this.isLiteral(varName)) {
888
+ this.addDiagnostic(
889
+ "error",
890
+ `Unknown variable '${varName}' in while loop condition`,
891
+ "E005"
892
+ );
893
+ }
894
+ }
895
+ } else {
896
+ this.checkTypeGuard(node.condition);
897
+ }
898
+ this.checkBlock(node.body);
899
+ }
900
+ checkForEachLoop(node) {
901
+ if (!this.typeMap.has(node.collection)) {
902
+ this.addDiagnostic(
903
+ "error",
904
+ `Unknown collection '${node.collection}' in forEach loop`,
905
+ "E006"
906
+ );
907
+ } else {
908
+ const collectionType2 = this.typeMap.get(node.collection);
909
+ if (collectionType2 && collectionType2.type !== "array" && collectionType2.type !== "any") {
910
+ this.addDiagnostic(
911
+ "error",
912
+ `'${node.collection}' is not iterable (type: ${collectionType2.type})`,
913
+ "E007"
914
+ );
915
+ }
916
+ }
917
+ const collectionType = this.typeMap.get(node.collection);
918
+ const itemType = collectionType?.type === "array" && collectionType.elementType ? collectionType.elementType : "any";
919
+ const originalType = this.typeMap.get(node.variable);
920
+ this.typeMap.set(node.variable, { type: itemType });
921
+ this.checkBlock(node.body);
922
+ if (originalType) this.typeMap.set(node.variable, originalType);
923
+ else this.typeMap.delete(node.variable);
924
+ }
925
+ checkImport(node) {
926
+ if (!node.modulePath) {
927
+ this.addDiagnostic("error", "Import statement missing module path", "E008");
928
+ }
929
+ for (const name of node.imports) {
930
+ this.typeMap.set(name, { type: "any" });
931
+ }
932
+ if (node.defaultImport) {
933
+ this.typeMap.set(node.defaultImport, { type: "any" });
934
+ }
935
+ }
936
+ checkExport(node) {
937
+ if (node.exports) {
938
+ for (const name of node.exports) {
939
+ if (!this.typeMap.has(name)) {
940
+ this.addDiagnostic("error", `Cannot export unknown identifier '${name}'`, "E009");
941
+ }
942
+ }
943
+ }
944
+ }
945
+ /**
946
+ * Infer type from a value
947
+ */
948
+ inferType(value) {
949
+ if (value === null || value === void 0) {
950
+ return { type: "any", nullable: true };
951
+ }
952
+ if (typeof value === "function") {
953
+ const fn = value;
954
+ return {
955
+ type: "function",
956
+ parameters: Array.from({ length: fn.length }, (_, i) => ({
957
+ name: `arg${i}`,
958
+ type: "any"
959
+ })),
960
+ returnType: "void"
961
+ };
962
+ }
963
+ if (typeof value === "number") {
964
+ return { type: "number" };
965
+ }
966
+ if (typeof value === "string") {
967
+ if (/^\(.*\)\s*=>/.test(value) || /^\w+\s*=>/.test(value)) {
968
+ const arrowMatch = value.match(/=>\s*(.+)$/s);
969
+ let returnType = "void";
970
+ if (arrowMatch) {
971
+ const body = arrowMatch[1].trim();
972
+ if (/^["']/.test(body)) returnType = "string";
973
+ else if (/^-?\d/.test(body)) returnType = "number";
974
+ else if (body === "true" || body === "false") returnType = "boolean";
975
+ else if (/^\[/.test(body)) returnType = "array";
976
+ else if (/^\{/.test(body) && !body.startsWith("{\n")) returnType = "object";
977
+ else if (body !== "" && !body.startsWith("{")) returnType = "any";
978
+ }
979
+ return { type: "function", parameters: [], returnType };
980
+ }
981
+ if (/^#([A-Fa-f0-9]{3}){1,2}$/.test(value)) return { type: "color" };
982
+ if (/^rgba?\s*\(/.test(value)) return { type: "color" };
983
+ return { type: "string" };
984
+ }
985
+ if (typeof value === "boolean") {
986
+ return { type: "boolean" };
987
+ }
988
+ if (Array.isArray(value)) {
989
+ if (value.length === 2 && value.every((v) => typeof v === "number")) return { type: "vec2" };
990
+ if (value.length === 3 && value.every((v) => typeof v === "number")) return { type: "vec3" };
991
+ if (value.length === 4 && value.every((v) => typeof v === "number")) return { type: "vec4" };
992
+ const elementType = value.length > 0 ? this.inferType(value[0]).type : "any";
993
+ return { type: "array", elementType };
994
+ }
995
+ if (typeof value === "object") {
996
+ if ("x" in value && "y" in value) {
997
+ if ("z" in value) return { type: "vec3" };
998
+ return { type: "vec2" };
999
+ }
1000
+ const properties = /* @__PURE__ */ new Map();
1001
+ for (const [key, val] of Object.entries(value)) {
1002
+ properties.set(key, this.inferType(val));
1003
+ }
1004
+ return { type: "object", properties };
1005
+ }
1006
+ return { type: "any" };
1007
+ }
1008
+ /**
1009
+ * Infer type with context
1010
+ */
1011
+ inferTypeWithContext(value, expectedType) {
1012
+ if (!expectedType) return this.inferType(value);
1013
+ const baseInferred = this.inferType(value);
1014
+ if (expectedType.type === "color" && typeof value === "string") {
1015
+ return { type: "color" };
1016
+ }
1017
+ if (expectedType.type === "euler" && Array.isArray(value) && value.length === 3) {
1018
+ return { type: "euler" };
1019
+ }
1020
+ if (expectedType.type === "quat" && Array.isArray(value) && value.length === 4) {
1021
+ return { type: "quat" };
1022
+ }
1023
+ if (expectedType.type === "vec3" && Array.isArray(value) && value.length === 3) {
1024
+ return { type: "vec3" };
1025
+ }
1026
+ return baseInferred;
1027
+ }
1028
+ /**
1029
+ * Parse type string to HoloScriptType
1030
+ */
1031
+ parseTypeString(typeStr) {
1032
+ const normalized = typeStr.toLowerCase().trim();
1033
+ const validTypes = [
1034
+ "number",
1035
+ "string",
1036
+ "boolean",
1037
+ "array",
1038
+ "object",
1039
+ "function",
1040
+ "void",
1041
+ "any",
1042
+ "unknown",
1043
+ "never",
1044
+ "orb",
1045
+ "stream",
1046
+ "connection",
1047
+ "gate",
1048
+ "vec2",
1049
+ "vec3",
1050
+ "vec4",
1051
+ "color",
1052
+ "euler",
1053
+ "quat",
1054
+ "mat4"
1055
+ ];
1056
+ if (validTypes.includes(normalized)) {
1057
+ return normalized;
1058
+ }
1059
+ return "any";
1060
+ }
1061
+ /**
1062
+ * Extract variable names from an expression string
1063
+ */
1064
+ extractVariables(expr) {
1065
+ const varPattern = /\b([a-zA-Z_][a-zA-Z0-9_]*)\b/g;
1066
+ const matches = expr.match(varPattern) || [];
1067
+ const keywords = ["true", "false", "null", "undefined", "if", "else", "for", "while", "return"];
1068
+ return matches.filter((m) => !keywords.includes(m));
1069
+ }
1070
+ /**
1071
+ * Check if string is a literal
1072
+ */
1073
+ isLiteral(str) {
1074
+ if (/^-?\d+(\.\d+)?$/.test(str)) return true;
1075
+ if (str === "true" || str === "false") return true;
1076
+ if (/^["'].*["']$/.test(str)) return true;
1077
+ return false;
1078
+ }
1079
+ validateTraitConstraints(node) {
1080
+ const traitsMap = node.traits;
1081
+ if (!traitsMap || traitsMap.size === 0) {
1082
+ return;
1083
+ }
1084
+ const traitNames = Array.from(traitsMap.keys());
1085
+ const allConstraints = [...BUILTIN_CONSTRAINTS, ...this.customConstraints];
1086
+ for (const constraint of allConstraints) {
1087
+ if (constraint.type === "requires") {
1088
+ if (traitNames.includes(constraint.source)) {
1089
+ for (const target of constraint.targets) {
1090
+ if (!traitNames.includes(target)) {
1091
+ const suggestions = constraint.suggestion ? [constraint.suggestion] : [`Add @${target} to the same orb as @${constraint.source}.`];
1092
+ this.addDiagnostic(
1093
+ "error",
1094
+ constraint.message || `Trait @${constraint.source} requires @${target}.`,
1095
+ "HSP014",
1096
+ suggestions
1097
+ );
1098
+ }
1099
+ }
1100
+ }
1101
+ } else if (constraint.type === "conflicts") {
1102
+ if (traitNames.includes(constraint.source)) {
1103
+ for (const target of constraint.targets) {
1104
+ if (traitNames.includes(target)) {
1105
+ const suggestions = constraint.suggestion ? [constraint.suggestion] : [`Remove either @${constraint.source} or @${target} from the orb.`];
1106
+ this.addDiagnostic(
1107
+ "error",
1108
+ constraint.message || `Trait @${constraint.source} conflicts with @${target}.`,
1109
+ "HSP014",
1110
+ suggestions
1111
+ );
1112
+ }
1113
+ }
1114
+ }
1115
+ } else if (constraint.type === "oneof") {
1116
+ const matches = traitNames.filter((t) => constraint.targets.includes(t));
1117
+ if (matches.length > 1) {
1118
+ const suggestions = constraint.suggestion ? [constraint.suggestion] : [`Keep only one of: ${matches.map((t) => "@" + t).join(", ")}. Remove the others.`];
1119
+ this.addDiagnostic(
1120
+ "error",
1121
+ constraint.message || `Only one of the following traits can be used at a time: ${constraint.targets.map((t) => "@" + t).join(", ")}.`,
1122
+ "HSP014",
1123
+ suggestions
1124
+ );
1125
+ }
1126
+ }
1127
+ }
1128
+ }
1129
+ /**
1130
+ * Add a diagnostic
1131
+ */
1132
+ addDiagnostic(severity, message, code, suggestions) {
1133
+ this.diagnostics.push({
1134
+ severity,
1135
+ message,
1136
+ line: this.currentLine,
1137
+ column: this.currentColumn,
1138
+ code,
1139
+ suggestions
1140
+ });
1141
+ }
1142
+ /**
1143
+ * Get type info for a name
1144
+ */
1145
+ getType(name) {
1146
+ return this.typeMap.get(name);
1147
+ }
1148
+ /**
1149
+ * Get all registered types
1150
+ */
1151
+ getAllTypes() {
1152
+ return new Map(this.typeMap);
1153
+ }
1154
+ /**
1155
+ * Reset the type checker
1156
+ */
1157
+ reset() {
1158
+ this.typeMap.clear();
1159
+ this.diagnostics = [];
1160
+ this.unionTypes.clear();
1161
+ BUILTIN_FUNCTIONS.forEach((type, name) => {
1162
+ this.typeMap.set(name, type);
1163
+ });
1164
+ }
1165
+ /**
1166
+ * Get all registered union types
1167
+ */
1168
+ getAllUnionTypes() {
1169
+ return new Map(this.unionTypes);
1170
+ }
1171
+ /**
1172
+ * Sprint 5 — String-based type inference.
1173
+ *
1174
+ * Infers a simplified HoloScript type name from an expression string.
1175
+ * This is a lightweight syntactic analysis that does NOT require the AST:
1176
+ *
1177
+ * | Expression | Inferred type |
1178
+ * |---------------------------|---------------|
1179
+ * | `[0, 1, 0]` | `'vec3'` |
1180
+ * | `[0, 1]` | `'vec2'` |
1181
+ * | `3.14` | `'float'` |
1182
+ * | `42`, `0` | `'int'` |
1183
+ * | `true` / `false` | `'bool'` |
1184
+ * | `"hello"` / `'world'` | `'string'` |
1185
+ * | anything else | `'any'` |
1186
+ *
1187
+ * @param expr Raw expression string (trimmed)
1188
+ */
1189
+ inferTypeExpression(expr) {
1190
+ const s = expr.trim();
1191
+ if (!s) return "any";
1192
+ if (s === "true" || s === "false") return "bool";
1193
+ if (s.startsWith('"') && s.endsWith('"') || s.startsWith("'") && s.endsWith("'"))
1194
+ return "string";
1195
+ if (/^-?\d+$/.test(s)) return "int";
1196
+ if (/^-?\d+\.\d+$/.test(s)) return "float";
1197
+ if (s.startsWith("[") && s.endsWith("]")) {
1198
+ const inner = s.slice(1, -1).trim();
1199
+ if (!inner) return "any";
1200
+ const parts = inner.split(",").map((p) => p.trim());
1201
+ const allNumeric = parts.every((p) => /^-?\d+(\.\d+)?$/.test(p));
1202
+ if (allNumeric) {
1203
+ if (parts.length === 2) return "vec2";
1204
+ if (parts.length === 3) return "vec3";
1205
+ }
1206
+ }
1207
+ return "any";
1208
+ }
1209
+ };
1210
+ function createTypeChecker() {
1211
+ return new HoloScriptTypeChecker();
1212
+ }
1213
+
1214
+ export { HoloScriptTypeChecker, createTypeChecker };
1215
+ //# sourceMappingURL=chunk-VMLKSV26.js.map
1216
+ //# sourceMappingURL=chunk-VMLKSV26.js.map