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