solve-engine 1.1.1 → 2.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 (395) hide show
  1. package/README.md +12 -17
  2. package/dist/{BytecodeBuilder-Bp9xeTmX.d.cts → BytecodeBuilder-DGGeByAP.d.cts} +18 -0
  3. package/dist/{BytecodeBuilder-Bp9xeTmX.d.ts → BytecodeBuilder-DGGeByAP.d.ts} +18 -0
  4. package/dist/{Configuration-C9W8tJv_.d.cts → Configuration-B6W0-T67.d.cts} +17 -4
  5. package/dist/{Configuration-C9W8tJv_.d.ts → Configuration-B6W0-T67.d.ts} +17 -4
  6. package/dist/{EngineError-B61GS1jp.d.cts → EngineError-Ce1lPkjZ.d.cts} +8 -0
  7. package/dist/{EngineError-B61GS1jp.d.ts → EngineError-Ce1lPkjZ.d.ts} +8 -0
  8. package/dist/{Lexer-BOs7euZe.d.cts → Lexer-B4C1qHXu.d.cts} +1 -1
  9. package/dist/{Lexer-CSI_lwbW.d.ts → Lexer-DKMlj7Sy.d.ts} +1 -1
  10. package/dist/{PackageCompatibility-B-7rK1TD.d.cts → PackageCompatibility-Bn5jnBtA.d.cts} +2 -2
  11. package/dist/{PackageCompatibility-Dh59eF-X.d.ts → PackageCompatibility-CIvq2MP5.d.ts} +2 -2
  12. package/dist/{PackageRegistry-_8rDlvxI.d.ts → PackageRegistry-DzeiWcv4.d.ts} +143 -175
  13. package/dist/{PackageRegistry-BHWJP83F.d.cts → PackageRegistry-dpdurBVO.d.cts} +143 -175
  14. package/dist/{Parselet-BBT8riYh.d.ts → Parselet-B-zoPrTa.d.ts} +9 -6
  15. package/dist/{Parselet-BHcgK9S7.d.cts → Parselet-C4Wu055_.d.cts} +9 -6
  16. package/dist/{ScopeManager-CxA24W5n.d.ts → ScopeManager-C2LDOrDx.d.ts} +14 -16
  17. package/dist/{ScopeManager-8vf02dwj.d.cts → ScopeManager-D7uMXbhS.d.cts} +14 -16
  18. package/dist/{Token-B1hdkedD.d.cts → Token-CbP_OutD.d.cts} +9 -0
  19. package/dist/{Token-B1hdkedD.d.ts → Token-CbP_OutD.d.ts} +9 -0
  20. package/dist/{TokenNormalizer-C6VzZgHa.d.ts → TokenNormalizer-DCWdZjGz.d.ts} +1 -1
  21. package/dist/{TokenNormalizer-DRc1Js1V.d.cts → TokenNormalizer-DnlL7_8c.d.cts} +1 -1
  22. package/dist/{VMCheckpoints-MK--EBH2.d.ts → VMCheckpoints-CGyFhivM.d.ts} +3 -3
  23. package/dist/{VMCheckpoints-ELYqITdF.d.cts → VMCheckpoints-I9jg3jWR.d.cts} +3 -3
  24. package/dist/{Value-BUi1RA3S.d.cts → Value-CCi_Eecs.d.cts} +72 -5
  25. package/dist/{Value-BUi1RA3S.d.ts → Value-CCi_Eecs.d.ts} +72 -5
  26. package/dist/{WorkerError-gzmaopj2.d.cts → WorkerError-B4p6PNfx.d.cts} +1 -1
  27. package/dist/{WorkerError-_-RkoQ5P.d.ts → WorkerError-Dhj9BQ_A.d.ts} +1 -1
  28. package/dist/chunk-2JMFUQZH.js +2 -0
  29. package/dist/chunk-2JMFUQZH.js.map +1 -0
  30. package/dist/chunk-2RWAXT6O.js +0 -1
  31. package/dist/chunk-4BZIYU7S.cjs +3 -0
  32. package/dist/chunk-4BZIYU7S.cjs.map +1 -0
  33. package/dist/chunk-4J7XZSZJ.cjs +5 -0
  34. package/dist/chunk-4J7XZSZJ.cjs.map +1 -0
  35. package/dist/chunk-4QVBSG6B.cjs +2 -0
  36. package/dist/chunk-4QVBSG6B.cjs.map +1 -0
  37. package/dist/chunk-5IJD5L3O.cjs +2 -0
  38. package/dist/chunk-5IJD5L3O.cjs.map +1 -0
  39. package/dist/chunk-62LMTO4F.js +2 -0
  40. package/dist/chunk-62LMTO4F.js.map +1 -0
  41. package/dist/chunk-6CY44ZPG.js +2 -0
  42. package/dist/chunk-6CY44ZPG.js.map +1 -0
  43. package/dist/chunk-6G3PMEPA.js +2 -0
  44. package/dist/chunk-6G3PMEPA.js.map +1 -0
  45. package/dist/chunk-6INX773F.cjs +2 -0
  46. package/dist/chunk-6INX773F.cjs.map +1 -0
  47. package/dist/chunk-6KFVG6UY.cjs +2 -0
  48. package/dist/chunk-6KFVG6UY.cjs.map +1 -0
  49. package/dist/chunk-76F3LCIL.js +4 -0
  50. package/dist/chunk-76F3LCIL.js.map +1 -0
  51. package/dist/chunk-7GK3XEZF.js +2 -0
  52. package/dist/chunk-7GK3XEZF.js.map +1 -0
  53. package/dist/chunk-APN442VD.cjs +2 -0
  54. package/dist/chunk-APN442VD.cjs.map +1 -0
  55. package/dist/chunk-AXMQG5TS.cjs +2 -0
  56. package/dist/chunk-AXMQG5TS.cjs.map +1 -0
  57. package/dist/chunk-CIQOK7Q4.cjs +2 -0
  58. package/dist/chunk-CIQOK7Q4.cjs.map +1 -0
  59. package/dist/chunk-E6Z4NQAS.js +2 -0
  60. package/dist/chunk-E6Z4NQAS.js.map +1 -0
  61. package/dist/chunk-EFJCC6FJ.cjs +2 -0
  62. package/dist/chunk-EFJCC6FJ.cjs.map +1 -0
  63. package/dist/chunk-ESUN2THE.cjs +2 -0
  64. package/dist/chunk-ESUN2THE.cjs.map +1 -0
  65. package/dist/chunk-EVAOPEO4.js +2 -0
  66. package/dist/chunk-EVAOPEO4.js.map +1 -0
  67. package/dist/chunk-EYRBENHC.js +3 -0
  68. package/dist/chunk-EYRBENHC.js.map +1 -0
  69. package/dist/chunk-FDE5HWDI.cjs +2 -0
  70. package/dist/chunk-FDE5HWDI.cjs.map +1 -0
  71. package/dist/chunk-FWW3M36J.cjs +2 -0
  72. package/dist/chunk-FWW3M36J.cjs.map +1 -0
  73. package/dist/chunk-GOIQYUWV.js +2 -0
  74. package/dist/chunk-GOIQYUWV.js.map +1 -0
  75. package/dist/chunk-HFKDWQUL.js +2 -0
  76. package/dist/chunk-HFKDWQUL.js.map +1 -0
  77. package/dist/chunk-HLBYHXQD.cjs +3 -0
  78. package/dist/chunk-HLBYHXQD.cjs.map +1 -0
  79. package/dist/chunk-IANAMBJQ.cjs +2 -0
  80. package/dist/chunk-IANAMBJQ.cjs.map +1 -0
  81. package/dist/chunk-IJMNVBIS.js +2 -0
  82. package/dist/chunk-IJMNVBIS.js.map +1 -0
  83. package/dist/chunk-J4LZD4ZY.js +3 -0
  84. package/dist/chunk-J4LZD4ZY.js.map +1 -0
  85. package/dist/chunk-JAK3RAFA.cjs +2 -0
  86. package/dist/chunk-JAK3RAFA.cjs.map +1 -0
  87. package/dist/chunk-JFAJN3C2.cjs +2 -0
  88. package/dist/chunk-JFAJN3C2.cjs.map +1 -0
  89. package/dist/chunk-JPFCXLJV.js +2 -0
  90. package/dist/chunk-JPFCXLJV.js.map +1 -0
  91. package/dist/chunk-JSPKKNPQ.js +3 -0
  92. package/dist/chunk-JSPKKNPQ.js.map +1 -0
  93. package/dist/chunk-L3FPQSGN.js +2 -0
  94. package/dist/chunk-L3FPQSGN.js.map +1 -0
  95. package/dist/chunk-LR4E4A4W.cjs +2 -0
  96. package/dist/chunk-LR4E4A4W.cjs.map +1 -0
  97. package/dist/chunk-MIQBJGGR.js +2 -0
  98. package/dist/chunk-MIQBJGGR.js.map +1 -0
  99. package/dist/chunk-MPB7KUN5.js +3 -0
  100. package/dist/chunk-MPB7KUN5.js.map +1 -0
  101. package/dist/chunk-MSYX32PF.cjs +2 -0
  102. package/dist/chunk-MSYX32PF.cjs.map +1 -0
  103. package/dist/chunk-MVZUTETT.js +2 -0
  104. package/dist/chunk-MVZUTETT.js.map +1 -0
  105. package/dist/chunk-N7N7MPMK.cjs +2 -0
  106. package/dist/chunk-N7N7MPMK.cjs.map +1 -0
  107. package/dist/chunk-NGBBNL4K.cjs +1 -3
  108. package/dist/chunk-P6WPEUAJ.cjs +2 -0
  109. package/dist/chunk-P6WPEUAJ.cjs.map +1 -0
  110. package/dist/chunk-PS272DZJ.cjs +2 -0
  111. package/dist/chunk-PS272DZJ.cjs.map +1 -0
  112. package/dist/chunk-QXQE7X4S.js +2 -0
  113. package/dist/chunk-QXQE7X4S.js.map +1 -0
  114. package/dist/chunk-R2ENWQ76.js +2 -0
  115. package/dist/chunk-R2ENWQ76.js.map +1 -0
  116. package/dist/chunk-R2SZFJTT.cjs +2 -0
  117. package/dist/chunk-R2SZFJTT.cjs.map +1 -0
  118. package/dist/chunk-RAF57WYO.js +2 -0
  119. package/dist/chunk-RAF57WYO.js.map +1 -0
  120. package/dist/chunk-RSF25YSJ.js +2 -0
  121. package/dist/chunk-RSF25YSJ.js.map +1 -0
  122. package/dist/chunk-SOMGSIO4.cjs +3 -0
  123. package/dist/chunk-SOMGSIO4.cjs.map +1 -0
  124. package/dist/chunk-SUXRZWH2.cjs +3 -0
  125. package/dist/chunk-SUXRZWH2.cjs.map +1 -0
  126. package/dist/chunk-SYYE3QAX.cjs +2 -0
  127. package/dist/chunk-SYYE3QAX.cjs.map +1 -0
  128. package/dist/chunk-SZGK6RIP.cjs +2 -0
  129. package/dist/chunk-SZGK6RIP.cjs.map +1 -0
  130. package/dist/chunk-TCZSPH4A.js +2 -0
  131. package/dist/chunk-TCZSPH4A.js.map +1 -0
  132. package/dist/chunk-TLG7VZRX.cjs +2 -0
  133. package/dist/chunk-TLG7VZRX.cjs.map +1 -0
  134. package/dist/chunk-TRBXW6HW.js +2 -0
  135. package/dist/{chunk-AQNHHJMJ.cjs.map → chunk-TRBXW6HW.js.map} +1 -1
  136. package/dist/chunk-TTFO4YDP.cjs +2 -0
  137. package/dist/chunk-TTFO4YDP.cjs.map +1 -0
  138. package/dist/chunk-TWC7K3ZX.js +2 -0
  139. package/dist/chunk-TWC7K3ZX.js.map +1 -0
  140. package/dist/chunk-UDQ57ZRX.cjs +2 -0
  141. package/dist/chunk-UDQ57ZRX.cjs.map +1 -0
  142. package/dist/chunk-UI6IFGBT.js +2 -0
  143. package/dist/chunk-UI6IFGBT.js.map +1 -0
  144. package/dist/chunk-UURM7P3P.cjs +4 -0
  145. package/dist/chunk-UURM7P3P.cjs.map +1 -0
  146. package/dist/chunk-W2JAR233.js +2 -0
  147. package/dist/chunk-W2JAR233.js.map +1 -0
  148. package/dist/chunk-WGZ3FNHI.js +2 -0
  149. package/dist/chunk-WGZ3FNHI.js.map +1 -0
  150. package/dist/chunk-WN5CMP4T.cjs +3 -0
  151. package/dist/chunk-WN5CMP4T.cjs.map +1 -0
  152. package/dist/chunk-XEIDV5JP.js +2 -0
  153. package/dist/chunk-XEIDV5JP.js.map +1 -0
  154. package/dist/chunk-XNIWQHXY.js +2 -0
  155. package/dist/chunk-XNIWQHXY.js.map +1 -0
  156. package/dist/chunk-XR7HEC7B.js +5 -0
  157. package/dist/chunk-XR7HEC7B.js.map +1 -0
  158. package/dist/chunk-Y7O4D3BJ.cjs +2 -0
  159. package/dist/chunk-Y7O4D3BJ.cjs.map +1 -0
  160. package/dist/chunk-YAYBVVG2.js +3 -0
  161. package/dist/chunk-YAYBVVG2.js.map +1 -0
  162. package/dist/chunk-YJ2OPULK.js +2 -0
  163. package/dist/chunk-YJ2OPULK.js.map +1 -0
  164. package/dist/chunk-YVKHEAFT.js +2 -0
  165. package/dist/chunk-YVKHEAFT.js.map +1 -0
  166. package/dist/chunk-ZCNBT44X.cjs +2 -0
  167. package/dist/chunk-ZCNBT44X.cjs.map +1 -0
  168. package/dist/chunk-ZLRJ7TDP.cjs +2 -0
  169. package/dist/chunk-ZLRJ7TDP.cjs.map +1 -0
  170. package/dist/constants.cjs +1 -21
  171. package/dist/constants.d.cts +1 -1
  172. package/dist/constants.d.ts +1 -1
  173. package/dist/constants.js +1 -4
  174. package/dist/engine.cjs +1 -94
  175. package/dist/engine.d.cts +29 -14
  176. package/dist/engine.d.ts +29 -14
  177. package/dist/engine.js +1 -37
  178. package/dist/errors.cjs +1 -105
  179. package/dist/errors.d.cts +3 -3
  180. package/dist/errors.d.ts +3 -3
  181. package/dist/errors.js +1 -4
  182. package/dist/format.cjs +1 -26
  183. package/dist/format.d.cts +2 -2
  184. package/dist/format.d.ts +2 -2
  185. package/dist/format.js +1 -9
  186. package/dist/index.cjs +1 -314
  187. package/dist/index.cjs.map +1 -1
  188. package/dist/index.d.cts +55 -23
  189. package/dist/index.d.ts +55 -23
  190. package/dist/index.js +1 -278
  191. package/dist/index.js.map +1 -1
  192. package/dist/language.cjs +1 -369
  193. package/dist/language.cjs.map +1 -1
  194. package/dist/language.d.cts +12 -13
  195. package/dist/language.d.ts +12 -13
  196. package/dist/language.js +1 -348
  197. package/dist/language.js.map +1 -1
  198. package/dist/lexer.cjs +1 -63
  199. package/dist/lexer.d.cts +3 -3
  200. package/dist/lexer.d.ts +3 -3
  201. package/dist/lexer.js +1 -10
  202. package/dist/normalizer.cjs +1 -39
  203. package/dist/normalizer.d.cts +3 -3
  204. package/dist/normalizer.d.ts +3 -3
  205. package/dist/normalizer.js +1 -10
  206. package/dist/packages.cjs +1 -128
  207. package/dist/packages.d.cts +39 -14
  208. package/dist/packages.d.ts +39 -14
  209. package/dist/packages.js +1 -23
  210. package/dist/parser.cjs +1 -54
  211. package/dist/parser.d.cts +9 -9
  212. package/dist/parser.d.ts +9 -9
  213. package/dist/parser.js +1 -9
  214. package/dist/{pipeline-CtfJtPQc.d.cts → pipeline-72QmQlGx.d.ts} +3 -3
  215. package/dist/{pipeline-DCd5M6Gk.d.ts → pipeline-DCQicwWX.d.cts} +3 -3
  216. package/dist/resolvers.cjs +1 -12
  217. package/dist/resolvers.d.cts +3 -3
  218. package/dist/resolvers.d.ts +3 -3
  219. package/dist/resolvers.js +1 -3
  220. package/dist/services.cjs +1 -20
  221. package/dist/services.js +1 -3
  222. package/dist/testing.cjs +3 -477
  223. package/dist/testing.cjs.map +1 -1
  224. package/dist/testing.d.cts +12 -13
  225. package/dist/testing.d.ts +12 -13
  226. package/dist/testing.js +3 -469
  227. package/dist/testing.js.map +1 -1
  228. package/dist/uom.cjs +1 -55
  229. package/dist/uom.d.cts +3 -3
  230. package/dist/uom.d.ts +3 -3
  231. package/dist/uom.js +1 -10
  232. package/dist/utilities.cjs +1 -36
  233. package/dist/utilities.js +1 -7
  234. package/dist/vm.cjs +1 -295
  235. package/dist/vm.cjs.map +1 -1
  236. package/dist/vm.d.cts +22 -10
  237. package/dist/vm.d.ts +22 -10
  238. package/dist/vm.js +1 -193
  239. package/dist/vm.js.map +1 -1
  240. package/dist/worker.cjs +2 -492
  241. package/dist/worker.cjs.map +1 -1
  242. package/dist/worker.d.cts +19 -20
  243. package/dist/worker.d.ts +19 -20
  244. package/dist/worker.js +2 -483
  245. package/dist/worker.js.map +1 -1
  246. package/package.json +1 -13
  247. package/dist/chunk-267JPOTF.js +0 -406
  248. package/dist/chunk-267JPOTF.js.map +0 -1
  249. package/dist/chunk-2TZKENDH.cjs +0 -448
  250. package/dist/chunk-2TZKENDH.cjs.map +0 -1
  251. package/dist/chunk-3BOK2LDK.js +0 -17
  252. package/dist/chunk-3BOK2LDK.js.map +0 -1
  253. package/dist/chunk-3OWCDIPN.js +0 -215
  254. package/dist/chunk-3OWCDIPN.js.map +0 -1
  255. package/dist/chunk-3VGDNEE3.js +0 -84
  256. package/dist/chunk-3VGDNEE3.js.map +0 -1
  257. package/dist/chunk-4D6NIHE2.js +0 -451
  258. package/dist/chunk-4D6NIHE2.js.map +0 -1
  259. package/dist/chunk-4HQKTMWG.js +0 -7985
  260. package/dist/chunk-4HQKTMWG.js.map +0 -1
  261. package/dist/chunk-536WPM2V.cjs +0 -283
  262. package/dist/chunk-536WPM2V.cjs.map +0 -1
  263. package/dist/chunk-5HRB36DK.js +0 -405
  264. package/dist/chunk-5HRB36DK.js.map +0 -1
  265. package/dist/chunk-5ON7PUAZ.js +0 -12
  266. package/dist/chunk-5ON7PUAZ.js.map +0 -1
  267. package/dist/chunk-7KYSUDQO.js +0 -109
  268. package/dist/chunk-7KYSUDQO.js.map +0 -1
  269. package/dist/chunk-7ZX6B7SY.cjs +0 -3222
  270. package/dist/chunk-7ZX6B7SY.cjs.map +0 -1
  271. package/dist/chunk-ADBA3XBE.cjs +0 -20
  272. package/dist/chunk-ADBA3XBE.cjs.map +0 -1
  273. package/dist/chunk-ALYRJ72W.cjs +0 -434
  274. package/dist/chunk-ALYRJ72W.cjs.map +0 -1
  275. package/dist/chunk-AMOJYLG2.cjs +0 -1692
  276. package/dist/chunk-AMOJYLG2.cjs.map +0 -1
  277. package/dist/chunk-AQNHHJMJ.cjs +0 -261
  278. package/dist/chunk-B4HBEFTB.cjs +0 -375
  279. package/dist/chunk-B4HBEFTB.cjs.map +0 -1
  280. package/dist/chunk-B7LXJ6LC.cjs +0 -36
  281. package/dist/chunk-B7LXJ6LC.cjs.map +0 -1
  282. package/dist/chunk-B7NLZMQ3.cjs +0 -74
  283. package/dist/chunk-B7NLZMQ3.cjs.map +0 -1
  284. package/dist/chunk-BLI4NIQY.js +0 -98
  285. package/dist/chunk-BLI4NIQY.js.map +0 -1
  286. package/dist/chunk-BYJBUL7U.js +0 -499
  287. package/dist/chunk-BYJBUL7U.js.map +0 -1
  288. package/dist/chunk-CCBZZQAE.js +0 -312
  289. package/dist/chunk-CCBZZQAE.js.map +0 -1
  290. package/dist/chunk-CKQMXMHR.cjs +0 -219
  291. package/dist/chunk-CKQMXMHR.cjs.map +0 -1
  292. package/dist/chunk-CUR2WLI4.cjs +0 -507
  293. package/dist/chunk-CUR2WLI4.cjs.map +0 -1
  294. package/dist/chunk-DLEBSLF4.js +0 -336
  295. package/dist/chunk-DLEBSLF4.js.map +0 -1
  296. package/dist/chunk-E23GZEWL.cjs +0 -209
  297. package/dist/chunk-E23GZEWL.cjs.map +0 -1
  298. package/dist/chunk-EJ3ILXX6.cjs +0 -223
  299. package/dist/chunk-EJ3ILXX6.cjs.map +0 -1
  300. package/dist/chunk-ENKKJYD3.js +0 -333
  301. package/dist/chunk-ENKKJYD3.js.map +0 -1
  302. package/dist/chunk-ENRIK36Q.cjs +0 -94
  303. package/dist/chunk-ENRIK36Q.cjs.map +0 -1
  304. package/dist/chunk-ERCOHGXD.js +0 -356
  305. package/dist/chunk-ERCOHGXD.js.map +0 -1
  306. package/dist/chunk-FD5ZZHEU.js +0 -92
  307. package/dist/chunk-FD5ZZHEU.js.map +0 -1
  308. package/dist/chunk-FEAIOR7N.cjs +0 -91
  309. package/dist/chunk-FEAIOR7N.cjs.map +0 -1
  310. package/dist/chunk-GCM5JHMX.js +0 -88
  311. package/dist/chunk-GCM5JHMX.js.map +0 -1
  312. package/dist/chunk-GLA4JXBO.js +0 -204
  313. package/dist/chunk-GLA4JXBO.js.map +0 -1
  314. package/dist/chunk-HIQ5HSZL.cjs +0 -1923
  315. package/dist/chunk-HIQ5HSZL.cjs.map +0 -1
  316. package/dist/chunk-HVRVSI2Z.cjs +0 -829
  317. package/dist/chunk-HVRVSI2Z.cjs.map +0 -1
  318. package/dist/chunk-I4GAWIPW.js +0 -825
  319. package/dist/chunk-I4GAWIPW.js.map +0 -1
  320. package/dist/chunk-J45BCEZ4.cjs +0 -339
  321. package/dist/chunk-J45BCEZ4.cjs.map +0 -1
  322. package/dist/chunk-JG6ZJ2WU.js +0 -1513
  323. package/dist/chunk-JG6ZJ2WU.js.map +0 -1
  324. package/dist/chunk-L2TE7PMO.cjs +0 -14
  325. package/dist/chunk-L2TE7PMO.cjs.map +0 -1
  326. package/dist/chunk-LHZ6VOA7.js +0 -1764
  327. package/dist/chunk-LHZ6VOA7.js.map +0 -1
  328. package/dist/chunk-MN3LHRGV.cjs +0 -8012
  329. package/dist/chunk-MN3LHRGV.cjs.map +0 -1
  330. package/dist/chunk-MVTOCRV2.js +0 -213
  331. package/dist/chunk-MVTOCRV2.js.map +0 -1
  332. package/dist/chunk-N5NNW4VG.cjs +0 -341
  333. package/dist/chunk-N5NNW4VG.cjs.map +0 -1
  334. package/dist/chunk-N7FNVFXW.cjs +0 -32
  335. package/dist/chunk-N7FNVFXW.cjs.map +0 -1
  336. package/dist/chunk-NKW7LKYU.js +0 -3185
  337. package/dist/chunk-NKW7LKYU.js.map +0 -1
  338. package/dist/chunk-NLNDMWZC.js +0 -31
  339. package/dist/chunk-NLNDMWZC.js.map +0 -1
  340. package/dist/chunk-NNQ2TYDF.js +0 -1848
  341. package/dist/chunk-NNQ2TYDF.js.map +0 -1
  342. package/dist/chunk-NNZAEUDW.js +0 -6792
  343. package/dist/chunk-NNZAEUDW.js.map +0 -1
  344. package/dist/chunk-OUHT5Z36.cjs +0 -393
  345. package/dist/chunk-OUHT5Z36.cjs.map +0 -1
  346. package/dist/chunk-QFTDTX6K.cjs +0 -457
  347. package/dist/chunk-QFTDTX6K.cjs.map +0 -1
  348. package/dist/chunk-SBUFNJVE.js +0 -258
  349. package/dist/chunk-SBUFNJVE.js.map +0 -1
  350. package/dist/chunk-SRGQ72IR.cjs +0 -2800
  351. package/dist/chunk-SRGQ72IR.cjs.map +0 -1
  352. package/dist/chunk-SSV46KFA.cjs +0 -112
  353. package/dist/chunk-SSV46KFA.cjs.map +0 -1
  354. package/dist/chunk-T6ZYQJ63.cjs +0 -6807
  355. package/dist/chunk-T6ZYQJ63.cjs.map +0 -1
  356. package/dist/chunk-UKQHXPGW.js +0 -30
  357. package/dist/chunk-UKQHXPGW.js.map +0 -1
  358. package/dist/chunk-UO6BUV6K.js +0 -278
  359. package/dist/chunk-UO6BUV6K.js.map +0 -1
  360. package/dist/chunk-V4XG5QF6.js +0 -1685
  361. package/dist/chunk-V4XG5QF6.js.map +0 -1
  362. package/dist/chunk-VEKIWQ3F.cjs +0 -39
  363. package/dist/chunk-VEKIWQ3F.cjs.map +0 -1
  364. package/dist/chunk-WWQEY7BV.js +0 -67
  365. package/dist/chunk-WWQEY7BV.js.map +0 -1
  366. package/dist/chunk-WXEHD6TT.js +0 -2795
  367. package/dist/chunk-WXEHD6TT.js.map +0 -1
  368. package/dist/chunk-X6K3HUOY.cjs +0 -86
  369. package/dist/chunk-X6K3HUOY.cjs.map +0 -1
  370. package/dist/chunk-XA4CKRML.cjs +0 -316
  371. package/dist/chunk-XA4CKRML.cjs.map +0 -1
  372. package/dist/chunk-XBTEO4OB.js +0 -391
  373. package/dist/chunk-XBTEO4OB.js.map +0 -1
  374. package/dist/chunk-XIYYHA65.cjs +0 -101
  375. package/dist/chunk-XIYYHA65.cjs.map +0 -1
  376. package/dist/chunk-YLJ4XMA6.js +0 -33
  377. package/dist/chunk-YLJ4XMA6.js.map +0 -1
  378. package/dist/chunk-YRIKITGF.cjs +0 -1768
  379. package/dist/chunk-YRIKITGF.cjs.map +0 -1
  380. package/dist/chunk-Z2XP767T.cjs +0 -35
  381. package/dist/chunk-Z2XP767T.cjs.map +0 -1
  382. package/dist/chunk-Z4X2RWOF.js +0 -37
  383. package/dist/chunk-Z4X2RWOF.js.map +0 -1
  384. package/dist/chunk-Z7XGGLI2.js +0 -455
  385. package/dist/chunk-Z7XGGLI2.js.map +0 -1
  386. package/dist/chunk-ZMW6NU2K.cjs +0 -1516
  387. package/dist/chunk-ZMW6NU2K.cjs.map +0 -1
  388. package/dist/chunk-ZVTWQLK4.cjs +0 -459
  389. package/dist/chunk-ZVTWQLK4.cjs.map +0 -1
  390. package/dist/variables.cjs +0 -17
  391. package/dist/variables.cjs.map +0 -1
  392. package/dist/variables.d.cts +0 -87
  393. package/dist/variables.d.ts +0 -87
  394. package/dist/variables.js +0 -4
  395. package/dist/variables.js.map +0 -1
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/api/PackageRegistry.ts","../src/api/defineFunction.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { sharedParseletRegistry } from \"@solve-js/parser/registry/ParseletRegistry\";\nimport { PrefixParselet, InfixParselet } from \"@solve-js/parser/Parselet\";\nimport { Value } from \"@solve-js/vm/Value\";\nimport { IVariableSource } from \"@solve-js/variables/IVariableSource\";\nimport { sharedVariableResolver } from \"@solve-js/variables/VariableResolver\";\nimport { sharedLexer } from \"@solve-js/lexer/Lexer\";\nimport type { LexerVocabulary } from \"@solve-js/lexer/ExpressionLexer\";\nimport type { IAsyncResolver } from \"@solve-js/resolvers/ResolverRegistry\";\nimport type { NormalizerRule } from \"@solve-js/normalizer/NormalizerRule\";\nimport type { TokenCategory } from \"@solve-js/language/TokenCategory\";\nimport type { CompletionItem } from \"@solve-js/language/LanguageService\";\nimport type { LineExecutionContext } from \"@solve-js/vm/VM\";\nimport { assertEngineVersionCompatible } from \"./EngineVersionCompatibility\";\n\n/**\n * Public API for registering plugins with the solve-js engine.\n *\n * All registration goes through this interface, parselets, variable\n * sources, and full packages. The default implementation is\n * {@link PackageRegistry} (singleton via {@link packageRegistry}).\n *\n * @example\n * ```typescript\n * import { packageRegistry } from \"solve-engine\";\n * packageRegistry.registerPackage(myCustomPackage);\n * ```\n */\nexport interface IPackageRegistry {\n /** Register a prefix parselet (e.g., `GE`, `NOW`, `floor`). */\n registerPrefixParselet(tokenType: string, parselet: PrefixParselet): void;\n /** Register an infix parselet (e.g., `+`, `in`, `to`). */\n registerInfixParselet(tokenType: string, parselet: InfixParselet): void;\n /** @deprecated Has no effect. See {@link IEnginePackage.variableSources}. */\n registerVariableSource(source: IVariableSource): void;\n /** Register a complete package (parselets + variable sources). */\n registerPackage(pkg: IEnginePackage): void;\n /** Convenience reference to the Value class for creating typed values. */\n Value: typeof Value;\n}\n\n/**\n * Package descriptor for registering a complete provider with the engine.\n *\n * A package bundles all the pieces needed for a domain-specific provider:\n * lexer plugins for custom token recognition, parselets for Pratt parsing,\n * plugin functions dispatched via CALL_PLUGIN bytecode, variable sources,\n * and optional async resolvers for data that loads asynchronously (e.g.,\n * exchange rates, game prices).\n *\n * @example\n * ```typescript\n * const myPackage: IEnginePackage = {\n * name: \"MyProvider\",\n * lexerVocabulary: myLexerVocabulary,\n * prefixParselets: [{ tokenType: \"MY_FUNC\", parselet: new MyParselet() }],\n * pluginFunctions: [{ index: MY_FN_IDX, handler: myHandler }],\n * asyncResolvers: [myAsyncResolver],\n * };\n * packageRegistry.registerPackage(myPackage);\n * ```\n */\nexport interface IEnginePackage {\n /** Human-readable name for debugging and error attribution. */\n name: string;\n /**\n * Semver range of `solve-engine` versions this package is compatible with\n * (e.g. `\"^0.1.0\"`, `\">=0.1.0 <0.3.0\"`), checked against the engine's own\n * running version ({@link ENGINE_VERSION}, `@solve-js/constants/version`)\n * via `checkEngineVersionCompatibility()`/`assertEngineVersionCompatible()`\n * (`@solve-js/api/EngineVersionCompatibility`) at registration time.\n *\n * Optional, omitted means \"no declared constraint,\" so every package\n * that predates this field (all built-ins, `examples/osrs`) keeps\n * registering exactly as before.\n *\n * Unlike every other compatibility signal in this codebase (e.g.\n * `checkPackageCompatibility()`'s sibling-package collision warnings,\n * which always log and proceed. See `api/PackageCompatibility.ts`), a\n * declared `engineVersion` range the running engine does NOT satisfy is\n * a deliberate, hard REJECTION: `registerPackage()` throws rather than\n * warning. See `ARCHITECTURE.md` §5.3.\n */\n engineVersion?: string;\n /** Optional lexer vocabulary (keywords/operators/units) for recognizing custom tokens (e.g., `GE`, `£`). */\n lexerVocabulary?: LexerVocabulary;\n /** Prefix parselets for this package's custom functions/operators. */\n prefixParselets?: Array<{ tokenType: string; parselet: PrefixParselet }>;\n /** Infix parselets for this package's custom binary operators. */\n infixParselets?: Array<{ tokenType: string; parselet: InfixParselet }>;\n /**\n * Functions dispatched via CALL_PLUGIN bytecode (emitted by this package's\n * parselets with `builder.emitIndex(index)`).\n *\n * Each entry's `index` MUST come from {@link allocatePluginFunctionIndex}\n * (`@solve-js/vm/VMBuiltins`), never hardcode a number. Two packages\n * independently picking the same index would silently overwrite each\n * other's handler in the shared registry.\n *\n * The handler's optional second parameter, `context`, carries the\n * current line's {@link LineExecutionContext} (line number, and, only\n * inside a real document, never `evaluateExpression()`'s single-shot\n * path, closures for reading another line's cached result). Every\n * handler that doesn't need cross-line data can ignore it entirely.\n *\n * @example\n * ```ts\n * const MY_FN_IDX = allocatePluginFunctionIndex();\n * // In a parselet's parse(): builder.emitOpcode(OpCode.CALL_PLUGIN); builder.emitIndex(MY_FN_IDX); builder.emitIndex(argCount);\n * pluginFunctions: [{ index: MY_FN_IDX, handler: myHandler }]\n * ```\n */\n pluginFunctions?: Array<{ index: number; handler: (args: Value[], context?: LineExecutionContext) => Value | Promise<Value> }>;\n /**\n * Named-variable sources.\n *\n * @deprecated Currently has no effect. Sources declared here are registered\n * into the engine's {@link EngineContext} and unregistered again on package\n * removal, but no evaluation path ever calls `VariableResolver.resolve()`, so\n * a variable a source provides is never found. Verified by searching every\n * use of `IVariableSource` outside its own declaration: they are all\n * registration bookkeeping.\n *\n * Declared here rather than deleted because removing a public field is a\n * breaking change and the intended behaviour is worth keeping. Documented as\n * dead so a package author does not spend an afternoon working out why their\n * variables resolve to nothing. To expose a value today, contribute a plugin\n * function through {@link IEnginePackage.pluginFunctions}.\n */\n variableSources?: IVariableSource[];\n /**\n * Async resolvers for this package's domain.\n * When set, the ExpressionEngine runs preflight() before VM execution\n * for each resolver. If async data is needed, a Pending result is\n * returned immediately and the line re-evaluates when the data resolves.\n *\n * Each resolver must have a unique `namespace`, the ResolverRegistry\n * is keyed by namespace. Multiple resolvers let a package handle\n * distinct async operations (e.g., `fetch`, `wait`, `poll`) in\n * separate, focused classes rather than one monolithic preflight().\n */\n asyncResolvers?: IAsyncResolver[];\n /**\n * Multi-word phrases to fuse into single compound tokens.\n * Each key is a space-separated phrase (e.g., \"to the power of\"),\n * each value is the target token type after fusion (e.g., \"CARET\").\n *\n * Registered into the engine's {@link PhraseTrie} for single-pass\n * O(depth) matching, no separate rule scanning per phrase.\n *\n * @example\n * ```ts\n * phrases: {\n * \"to the power of\": \"CARET\",\n * \"abyssal whip\": \"ITEM\",\n * }\n * ```\n */\n phrases?: Record<string, string>;\n /**\n * Normalizer rules for post-lexer token transformation.\n * Applied by the TokenNormalizer between lexing and parsing.\n * For phrase fusion, prefer the declarative {@link phrases} field\n * which uses the faster PhraseTrie. Use this for non-phrase rules\n * like implicit operator insertion.\n */\n normalizerRules?: NormalizerRule[];\n /**\n * Semantic highlight categories for this package's custom token types\n * (introduced via {@link lexerVocabulary} or {@link normalizerRules}), the\n * plugin-facing half of solve-js's editor-agnostic language service (see\n * `language/TokenCategoryMap.ts`). Without an entry here, a package's\n * custom tokens (e.g. a game-item name fused from several identifiers)\n * are still lexed and parsed correctly, but render with no highlight\n * category in any editor integration.\n *\n * @example\n * ```ts\n * tokenCategories: { MY_KEYWORD: \"keyword\", MY_ITEM: \"my-plugin-item\" }\n * ```\n */\n tokenCategories?: Record<string, TokenCategory>;\n /**\n * Completion candidates for this package, the plugin-facing half of\n * solve-js's editor-agnostic completions API\n * (`LanguageService.getCompletions()`). A package's single-word\n * keywords (via {@link lexerVocabulary}) already flow into completions\n * automatically; this field is for candidates that AREN'T lexer\n * keywords, such as a vocabulary of item/entity names. A plain,\n * pre-built list, not a callback, completion candidate lists are\n * meant to be cheap and static within one engine configuration.\n *\n * @example\n * ```ts\n * completionItems: [{ label: \"Abyssal whip\", category: \"my-plugin-item\", detail: \"Item\" }]\n * ```\n */\n completionItems?: CompletionItem[];\n /**\n * Custom `as <name>` converters, the extension point for the\n * Converters package's general `<expr> as <type>` grammar (e.g.\n * `50% as decimal`, `255 as hex`). The built-in converter names\n * (`percent`, `decimal`, `hex`, `fraction`, `multiplier`, `sci`,\n * `binary`, `octal`, ...) dispatch to dedicated fast opcodes; anything\n * else, including any name a third-party package registers here\n * resolves through `OpCode.CALL_AS_CONVERTER` against\n * `vm/VMBuiltins.ts`'s `asConverterRegistry` at runtime. No lexer\n * keyword registration is needed for a custom name: the AS parselet\n * accepts any bare-word token after \"as\" and reads its raw text.\n *\n * Each handler is a pure, synchronous `(value: Value) => Value`, for\n * async conversions (e.g. a live currency-style lookup), use\n * {@link asyncResolvers} instead.\n *\n * @example\n * ```ts\n * asConverters: { roman: (v) => stringValue(toRomanNumeral(v.toNumber())) }\n * ```\n */\n asConverters?: Record<string, (value: Value) => Value>;\n}\n\n/**\n * Default implementation of {@link IPackageRegistry}, the plugin registration API.\n *\n * All registrations delegate to shared singletons (parselet registry,\n * variable resolver, lexer). This ensures that packages registered through\n * any PackageRegistry instance are visible engine-wide.\n *\n * @example\n * ```typescript\n * import { packageRegistry } from \"solve-engine\";\n *\n * // Register a complete provider package\n * packageRegistry.registerPackage({\n * name: \"MyProvider\",\n * prefixParselets: [{ tokenType: \"MY_FUNC\", parselet: new MyParselet() }],\n * });\n * ```\n *\n * @deprecated Register on an engine instead:\n * `engine.registerPackage(pkg)`.\n *\n * This class writes into process-wide singletons, which is incompatible with an\n * engine owning its own registries. Since the introduction of\n * {@link EngineContext}, an engine reads plugin functions, opcode handlers and\n * variable sources from its own context, so a package registered here is not\n * visible to any engine. Parselets and lexer vocabulary registered here reach\n * the shared registries, which an engine also does not read: it builds its own\n * `ParseletRegistry` and its own `Lexer`.\n *\n * In other words this path registers into state nothing evaluates against. It\n * remains exported because removing it is a breaking change, and it is where\n * the singletons that survive are still written from, but it should not be used\n * in new code and will be removed before 1.0 proper.\n */\nexport class PackageRegistry implements IPackageRegistry {\n Value = Value;\n\n registerPrefixParselet(tokenType: string, parselet: PrefixParselet): void {\n sharedParseletRegistry.registerPrefix(tokenType, parselet);\n }\n\n registerInfixParselet(tokenType: string, parselet: InfixParselet): void {\n sharedParseletRegistry.registerInfix(tokenType, parselet);\n }\n\n registerVariableSource(source: IVariableSource): void {\n sharedVariableResolver.registerSource(source);\n }\n\n registerPackage(pkg: IEnginePackage): void {\n // Same hard engine-version gate ExpressionEngine.registerPackage() uses\n // (see its own comment and ARCHITECTURE.md §5.3). This weaker\n // shared-singleton path had no compatibility checking of any kind\n // before this, so without this call the version gate would be\n // trivially bypassable through this entry point.\n assertEngineVersionCompatible(pkg);\n\n if (pkg.lexerVocabulary) {\n sharedLexer.registerVocabulary(pkg.lexerVocabulary);\n }\n if (pkg.prefixParselets) {\n for (const pp of pkg.prefixParselets) {\n this.registerPrefixParselet(pp.tokenType, pp.parselet);\n }\n }\n if (pkg.infixParselets) {\n for (const ip of pkg.infixParselets) {\n this.registerInfixParselet(ip.tokenType, ip.parselet);\n }\n }\n if (pkg.variableSources) {\n for (const vs of pkg.variableSources) {\n this.registerVariableSource(vs);\n }\n }\n // Note: asyncResolvers are NOT registered here, the shared PackageRegistry singleton\n // doesn't have a ResolverRegistry (that lives inside ExpressionEngine).\n // Use ExpressionEngine.registerPackage() directly if you need async resolvers.\n }\n}\n\n/**\n * Singleton PackageRegistry instance, the default plugin registration API.\n *\n * All packages should register through this instance. The underlying registries\n * are shared singletons, so multiple PackageRegistry instances would be redundant.\n */\nexport const packageRegistry = new PackageRegistry();\n","import type { IEnginePackage } from \"@solve-js/api/PackageRegistry\";\nimport type { PrefixParselet } from \"@solve-js/parser/Parselet\";\nimport type { Parser } from \"@solve-js/parser/Parser\";\nimport type { Token } from \"@solve-js/lexer/Token\";\nimport type { BytecodeBuilder } from \"@solve-js/parser/BytecodeBuilder\";\nimport { OpCode } from \"@solve-js/parser/OpCode\";\nimport { BindingPower } from \"@solve-js/parser/BindingPower\";\nimport { allocatePluginFunctionIndex } from \"@solve-js/vm/VMBuiltins\";\nimport {\n Value,\n ValueType,\n numberValue,\n stringValue,\n boolValue,\n} from \"@solve-js/vm/Value\";\nimport { ErrorFactory } from \"@solve-js/errors/UnifiedErrorFramework\";\n\n/**\n * A higher-level, declarative way to contribute a single `name(args)`\n * function, sitting ON TOP OF the package contract rather than replacing it.\n *\n * The low-level contract (allocate a plugin function index, write a parselet,\n * emit `CALL_PLUGIN`) stays exactly as it was and remains the way to add\n * anything that needs custom parsing. This module derives that same wiring\n * from a declaration for the common case, a function called with parenthesised\n * arguments, so adding `vat(x)` costs a spec object rather than an\n * understanding of the parser and the VM. See `defineFunction`.\n */\n\n/** The value types a declared argument or return may take. */\nexport type FunctionValueType = \"number\" | \"string\" | \"boolean\";\n\n/** The JavaScript type a {@link FunctionValueType} maps to at the `call` boundary. */\ntype JsValue<T extends FunctionValueType> = T extends \"number\"\n ? number\n : T extends \"string\"\n ? string\n : boolean;\n\n/** One declared parameter: a name (for error messages) and a value type. */\nexport interface FunctionArg {\n /** Parameter name, used only in the generated type-mismatch messages. */\n name: string;\n /** The value type this parameter accepts. */\n type: FunctionValueType;\n}\n\n/** Map a tuple of {@link FunctionArg} specs to the tuple of JS values `call` receives. */\ntype CallArgs<A extends readonly FunctionArg[]> = {\n [K in keyof A]: JsValue<A[K][\"type\"]>;\n};\n\n/**\n * A declarative function definition.\n *\n * `A` and `R` are inferred from the literal `args`/`returns` (via\n * `defineFunction`'s `const` type parameter), so `call`'s parameters and\n * return are typed from the declaration with no annotations: an\n * `{ type: \"number\" }` argument arrives as a `number`, and a `returns:\n * \"string\"` demands a `string` back.\n */\nexport interface FunctionSpec<\n A extends readonly FunctionArg[] = readonly FunctionArg[],\n R extends FunctionValueType = FunctionValueType,\n> {\n /**\n * The call name, a single identifier (`/^[a-z_][a-z0-9_]*$/i`). Registered\n * as a lexer keyword, so it is matched case-insensitively and cannot collide\n * with a built-in keyword (that collision throws at registration time).\n */\n name: string;\n /** The parameters, in order. A fixed-length list: variadic and optional args are out of scope (see {@link defineFunction}). */\n args: A;\n /** The value type the function returns. */\n returns: R;\n /** The implementation, receiving plain JS values and returning one. Must be synchronous (see {@link defineFunction}). */\n call: (...args: CallArgs<A>) => JsValue<R>;\n}\n\n/**\n * Error codes the declarative function API raises. Kept as a co-located const\n * (the convention `errors/ErrorCode.ts` documents for a domain's own codes) so\n * the strings have one source of truth.\n */\nexport const DefineFunctionErrorCodes = {\n /** The spec's `name` is not a single identifier. Thrown by `defineFunction`, before any engine sees it. */\n DEFINE_FUNCTION_INVALID_NAME: \"DEFINE_FUNCTION_INVALID_NAME\",\n /** The spec is otherwise malformed (bad `args`, unsupported type, missing `call`). Thrown by `defineFunction`. */\n DEFINE_FUNCTION_INVALID_SPEC: \"DEFINE_FUNCTION_INVALID_SPEC\",\n /** The call site passed the wrong number of arguments. Raised at evaluation time. */\n DEFINE_FUNCTION_ARITY_MISMATCH: \"DEFINE_FUNCTION_ARITY_MISMATCH\",\n /** An argument was the wrong value type. Raised at evaluation time. */\n DEFINE_FUNCTION_ARGUMENT_TYPE: \"DEFINE_FUNCTION_ARGUMENT_TYPE\",\n /** The `call` implementation returned a value that did not match `returns`. Raised at evaluation time, an authoring bug rather than a user one. */\n DEFINE_FUNCTION_RETURN_TYPE: \"DEFINE_FUNCTION_RETURN_TYPE\",\n} as const;\n\n/** A single identifier: a letter or underscore, then letters, digits, or underscores. */\nconst NAME_PATTERN = /^[a-z_][a-z0-9_]*$/i;\n\nconst SUPPORTED_TYPES: ReadonlySet<string> = new Set([\"number\", \"string\", \"boolean\"]);\n\n/** \"1 argument\" / \"2 arguments\", so a count reads as English either way. Mirrors `VMBuiltinArity.ts`. */\nfunction plural(count: number): string {\n return count === 1 ? \"1 argument\" : `${count} arguments`;\n}\n\n/**\n * A human noun for the type a Value actually carries, for the \"was given ...\"\n * half of a mismatch message. Covers the three declarable types by their own\n * names and everything else by a readable category, so the message never reads\n * \"given a 6\".\n */\nfunction describeValueType(v: Value): string {\n switch (v.type) {\n case ValueType.Number:\n case ValueType.Hex:\n return \"a number\";\n case ValueType.String:\n return \"a string\";\n case ValueType.Boolean:\n return \"a boolean\";\n case ValueType.BigInt:\n return \"a big integer\";\n case ValueType.Percentage:\n return \"a percentage\";\n case ValueType.Uom:\n return \"a value with a unit\";\n case ValueType.Datetime:\n return \"a date\";\n case ValueType.Matrix:\n return \"a matrix\";\n case ValueType.Range:\n return \"a range\";\n case ValueType.Symbolic:\n return \"a symbolic expression\";\n default:\n return \"an unsupported value\";\n }\n}\n\n/**\n * Read one runtime Value as the JS primitive its declared type promises, or\n * raise the engine's structured type error.\n *\n * A \"number\" accepts a plain number or a based literal (`0xFF`), both of which\n * ARE numbers written differently, and reads it with `toNumber()`. Nothing\n * else is coerced: a percentage, a unit-bearing value or a string is a\n * genuinely different kind of value, and silently reinterpreting it is the\n * class of wrong-answer this API exists to avoid.\n */\nfunction coerceArgument(\n value: Value,\n arg: FunctionArg,\n fnName: string,\n): number | string | boolean {\n switch (arg.type) {\n case \"number\":\n // Hex is a number in another base (see `hexValue`), so it reads as one here.\n if (value.type === ValueType.Number || value.type === ValueType.Hex) {\n return value.toNumber();\n }\n break;\n case \"string\":\n if (value.type === ValueType.String) return value.value as string;\n break;\n case \"boolean\":\n if (value.type === ValueType.Boolean) return value.value as boolean;\n break;\n }\n throw ErrorFactory.execution({\n code: DefineFunctionErrorCodes.DEFINE_FUNCTION_ARGUMENT_TYPE,\n message: `${fnName}() expects \"${arg.name}\" to be a ${arg.type}, but was given ${describeValueType(value)}`,\n expected: `a ${arg.type}`,\n found: describeValueType(value),\n context: { functionName: fnName, argName: arg.name, expectedType: arg.type },\n });\n}\n\n/**\n * Wrap the `call` result back into a Value of the declared return type, or\n * raise a structured error if the implementation handed back something else.\n *\n * The type check here catches an authoring mistake (a function declared to\n * return a number that returns `undefined`, or a Promise from an accidental\n * `async`), turning it into a named error rather than a Value that lies about\n * its own type downstream.\n */\nfunction wrapReturn(result: unknown, returns: FunctionValueType, fnName: string): Value {\n switch (returns) {\n case \"number\":\n if (typeof result === \"number\") return numberValue(result);\n break;\n case \"string\":\n if (typeof result === \"string\") return stringValue(result);\n break;\n case \"boolean\":\n if (typeof result === \"boolean\") return boolValue(result);\n break;\n }\n throw ErrorFactory.internal({\n code: DefineFunctionErrorCodes.DEFINE_FUNCTION_RETURN_TYPE,\n message: `${fnName}() is declared to return a ${returns}, but its implementation returned ${typeof result}`,\n expected: `a ${returns}`,\n found: typeof result,\n context: { functionName: fnName, expectedType: returns },\n });\n}\n\n/**\n * The call-syntax parselet generated for one declared function.\n *\n * Identical in shape to the built-in `FunctionCallParselet`: consume the open\n * paren, parse a comma-separated argument list, then emit `CALL_PLUGIN` with\n * the function's index and the argument count. The count is whatever was\n * written, arity is checked at the dispatch point (see {@link makeHandler}),\n * the same place the built-in arity check lives.\n */\nclass DefinedFunctionParselet implements PrefixParselet {\n readonly category = \"Function\";\n\n constructor(\n private readonly fnIndex: number,\n private readonly fnName: string,\n ) {}\n\n parse(parser: Parser, _token: Token, builder: BytecodeBuilder): void {\n parser.consume(\"LPAREN\");\n\n let argCount = 0;\n if (parser.peek()?.type !== \"RPAREN\") {\n parser.parseExpression(BindingPower.Lowest, builder);\n argCount++;\n while (parser.match(\"COMMA\")) {\n parser.parseExpression(BindingPower.Lowest, builder);\n argCount++;\n }\n }\n\n parser.consume(\"RPAREN\");\n\n builder.emitOpcode(OpCode.CALL_PLUGIN);\n builder.emitIndex(this.fnIndex);\n builder.emitIndex(argCount);\n }\n}\n\n/**\n * Build the plugin function that checks arity and argument types, calls the\n * host implementation, and wraps the result.\n *\n * The VM has already screened out faulted arguments (an errored or still\n * pending operand short-circuits before the handler runs, see\n * `VM.ts`'s `CALL_PLUGIN` case), so every Value reaching here carries a real\n * result. Arity is checked first, before any argument is read, so a wrong\n * count is reported as a wrong count rather than as a type error on a missing\n * argument.\n */\nfunction makeHandler(spec: FunctionSpec): (args: Value[]) => Value {\n const arity = spec.args.length;\n return (args: Value[]): Value => {\n if (args.length !== arity) {\n throw ErrorFactory.execution({\n code: DefineFunctionErrorCodes.DEFINE_FUNCTION_ARITY_MISMATCH,\n message: `${spec.name}() takes ${plural(arity)}, but was given ${args.length === 0 ? \"none\" : plural(args.length)}`,\n expected: plural(arity),\n found: args.length === 0 ? \"none\" : plural(args.length),\n context: { functionName: spec.name, expected: arity, actual: args.length },\n });\n }\n\n const jsArgs: (number | string | boolean)[] = new Array(arity);\n for (let i = 0; i < arity; i++) {\n jsArgs[i] = coerceArgument(args[i], spec.args[i], spec.name);\n }\n\n const result = (spec.call as (...a: (number | string | boolean)[]) => unknown)(...jsArgs);\n return wrapReturn(result, spec.returns, spec.name);\n };\n}\n\n/** Reject a spec that could not produce a working function, before any engine sees it. */\nfunction validateSpec(spec: FunctionSpec): void {\n if (typeof spec?.name !== \"string\" || !NAME_PATTERN.test(spec.name)) {\n throw ErrorFactory.config({\n code: DefineFunctionErrorCodes.DEFINE_FUNCTION_INVALID_NAME,\n message: `defineFunction: name must be a single identifier, got ${JSON.stringify(spec?.name)}`,\n suggestion: 'e.g. \"vat\" or \"net_price\"',\n context: { name: spec?.name },\n });\n }\n if (!Array.isArray(spec.args)) {\n throw ErrorFactory.config({\n code: DefineFunctionErrorCodes.DEFINE_FUNCTION_INVALID_SPEC,\n message: `defineFunction: \"${spec.name}\" args must be an array`,\n context: { name: spec.name },\n });\n }\n for (const arg of spec.args) {\n if (typeof arg?.name !== \"string\" || arg.name.length === 0) {\n throw ErrorFactory.config({\n code: DefineFunctionErrorCodes.DEFINE_FUNCTION_INVALID_SPEC,\n message: `defineFunction: \"${spec.name}\" has an argument with no name`,\n context: { name: spec.name },\n });\n }\n if (!SUPPORTED_TYPES.has(arg.type)) {\n throw ErrorFactory.config({\n code: DefineFunctionErrorCodes.DEFINE_FUNCTION_INVALID_SPEC,\n message: `defineFunction: \"${spec.name}\" argument \"${arg.name}\" has unsupported type ${JSON.stringify(arg.type)}`,\n suggestion: \"supported argument types are number, string, boolean\",\n context: { name: spec.name, argName: arg.name, type: arg.type },\n });\n }\n }\n if (!SUPPORTED_TYPES.has(spec.returns)) {\n throw ErrorFactory.config({\n code: DefineFunctionErrorCodes.DEFINE_FUNCTION_INVALID_SPEC,\n message: `defineFunction: \"${spec.name}\" has unsupported return type ${JSON.stringify(spec.returns)}`,\n suggestion: \"supported return types are number, string, boolean\",\n context: { name: spec.name, returns: spec.returns },\n });\n }\n if (typeof spec.call !== \"function\") {\n throw ErrorFactory.config({\n code: DefineFunctionErrorCodes.DEFINE_FUNCTION_INVALID_SPEC,\n message: `defineFunction: \"${spec.name}\" is missing a call implementation`,\n context: { name: spec.name },\n });\n }\n}\n\n/**\n * Turn a declarative {@link FunctionSpec} into a ready-to-register\n * {@link IEnginePackage}.\n *\n * This is the higher-level API from issue #102. It derives, from the\n * declaration alone, everything the low-level contract asks an author to write\n * by hand: a plugin function index ({@link allocatePluginFunctionIndex}), a\n * lexer keyword so the name tokenises, a call-syntax parselet emitting\n * `CALL_PLUGIN`, and a handler that checks arity and argument types (yielding\n * the engine's own structured errors) before invoking `call` and wrapping its\n * result. Anything needing custom parsing keeps writing a raw parselet exactly\n * as before, this sits on top of that contract and does not change it.\n *\n * @example\n * ```ts\n * const engine = new ExpressionEngine(\"en\", false, undefined, undefined, [\n * ...BUILTIN_PACKAGES,\n * defineFunction({\n * name: \"vat\",\n * args: [{ name: \"amount\", type: \"number\" }],\n * returns: \"number\",\n * call: (amount) => amount * 1.2,\n * }),\n * ]);\n * engine.evaluateExpression(\"vat(100)\"); // 120\n * ```\n *\n * The returned package is self-contained and composes with any others through\n * the engine's `packages` array; register several functions by passing several\n * packages. Its name is `solve-fn-<name>`.\n *\n * Scope: arguments are a fixed-length list of `number`/`string`/`boolean`, and\n * `call` is synchronous. Variadic and optional arguments, other value types\n * (units, percentages, dates, matrices), and async work are deliberately out\n * of scope, a function needing any of those keeps using the low-level\n * contract, whose parselets and async resolvers are unchanged.\n *\n * @throws {EngineError} (category CONFIG) if the spec is malformed, at the\n * point `defineFunction` is called, before the package reaches an engine.\n */\nexport function defineFunction<\n const A extends readonly FunctionArg[],\n R extends FunctionValueType,\n>(spec: FunctionSpec<A, R>): IEnginePackage {\n validateSpec(spec as FunctionSpec);\n\n const name = spec.name;\n // Uppercased so the generated type is a valid, collision-resistant token\n // type; the name pattern guarantees it forms one. Distinct from the\n // built-in FUNC type, so this never routes through the builtin name map.\n const tokenType = `DEFINE_FN_${name.toUpperCase()}`;\n // Allocated at definition time (not module load), so importing this module\n // consumes no index and the export stays side-effect free.\n const index = allocatePluginFunctionIndex();\n\n return {\n name: `solve-fn-${name}`,\n lexerVocabulary: {\n // Lowercased because the lexer lowercases input before lookup, so the\n // call is matched case-insensitively.\n keywords: { [name.toLowerCase()]: tokenType },\n },\n prefixParselets: [\n { tokenType, parselet: new DefinedFunctionParselet(index, name) },\n ],\n pluginFunctions: [\n { index, handler: makeHandler(spec as FunctionSpec) },\n ],\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/api/defineFunction.ts","../src/api/createEngine.ts"],"names":["DefineFunctionErrorCodes","NAME_PATTERN","SUPPORTED_TYPES","plural","count","describeValueType","v","coerceArgument","value","arg","fnName","ErrorFactory","wrapReturn","result","returns","numberValue","stringValue","boolValue","DefinedFunctionParselet","parser","_token","builder","argCount","BindingPower","makeHandler","spec","arity","args","jsArgs","i","validateSpec","defineFunction","name","tokenType","createEngine","options","extraPackages","engineOptions","ExpressionEngine","BUILTIN_PACKAGES"],"mappings":"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","file":"index.js","sourcesContent":["import type { IEnginePackage } from \"@solve-js/api/PackageRegistry\";\nimport type { PrefixParselet } from \"@solve-js/parser/Parselet\";\nimport type { Parser } from \"@solve-js/parser/Parser\";\nimport type { Token } from \"@solve-js/lexer/Token\";\nimport type { BytecodeBuilder } from \"@solve-js/parser/BytecodeBuilder\";\nimport { BindingPower } from \"@solve-js/parser/BindingPower\";\nimport {\n Value,\n ValueType,\n numberValue,\n stringValue,\n boolValue,\n} from \"@solve-js/vm/Value\";\nimport { ErrorFactory } from \"@solve-js/errors/UnifiedErrorFramework\";\n\n/**\n * A higher-level, declarative way to contribute a single `name(args)`\n * function, sitting ON TOP OF the package contract rather than replacing it.\n *\n * The low-level contract (allocate a plugin function index, write a parselet,\n * emit `CALL_PLUGIN`) stays exactly as it was and remains the way to add\n * anything that needs custom parsing. This module derives that same wiring\n * from a declaration for the common case, a function called with parenthesised\n * arguments, so adding `vat(x)` costs a spec object rather than an\n * understanding of the parser and the VM. See `defineFunction`.\n */\n\n/** The value types a declared argument or return may take. */\nexport type FunctionValueType = \"number\" | \"string\" | \"boolean\";\n\n/** The JavaScript type a {@link FunctionValueType} maps to at the `call` boundary. */\ntype JsValue<T extends FunctionValueType> = T extends \"number\"\n ? number\n : T extends \"string\"\n ? string\n : boolean;\n\n/** One declared parameter: a name (for error messages) and a value type. */\nexport interface FunctionArg {\n /** Parameter name, used only in the generated type-mismatch messages. */\n name: string;\n /** The value type this parameter accepts. */\n type: FunctionValueType;\n}\n\n/** Map a tuple of {@link FunctionArg} specs to the tuple of JS values `call` receives. */\ntype CallArgs<A extends readonly FunctionArg[]> = {\n [K in keyof A]: JsValue<A[K][\"type\"]>;\n};\n\n/**\n * A declarative function definition.\n *\n * `A` and `R` are inferred from the literal `args`/`returns` (via\n * `defineFunction`'s `const` type parameter), so `call`'s parameters and\n * return are typed from the declaration with no annotations: an\n * `{ type: \"number\" }` argument arrives as a `number`, and a `returns:\n * \"string\"` demands a `string` back.\n */\nexport interface FunctionSpec<\n A extends readonly FunctionArg[] = readonly FunctionArg[],\n R extends FunctionValueType = FunctionValueType,\n> {\n /**\n * The call name, a single identifier (`/^[a-z_][a-z0-9_]*$/i`). Registered\n * as a lexer keyword, so it is matched case-insensitively and cannot collide\n * with a built-in keyword (that collision throws at registration time).\n */\n name: string;\n /** The parameters, in order. A fixed-length list: variadic and optional args are out of scope (see {@link defineFunction}). */\n args: A;\n /** The value type the function returns. */\n returns: R;\n /** The implementation, receiving plain JS values and returning one. Must be synchronous (see {@link defineFunction}). */\n call: (...args: CallArgs<A>) => JsValue<R>;\n}\n\n/**\n * Error codes the declarative function API raises. Kept as a co-located const\n * (the convention `errors/ErrorCode.ts` documents for a domain's own codes) so\n * the strings have one source of truth.\n */\nexport const DefineFunctionErrorCodes = {\n /** The spec's `name` is not a single identifier. Thrown by `defineFunction`, before any engine sees it. */\n DEFINE_FUNCTION_INVALID_NAME: \"DEFINE_FUNCTION_INVALID_NAME\",\n /** The spec is otherwise malformed (bad `args`, unsupported type, missing `call`). Thrown by `defineFunction`. */\n DEFINE_FUNCTION_INVALID_SPEC: \"DEFINE_FUNCTION_INVALID_SPEC\",\n /** The call site passed the wrong number of arguments. Raised at evaluation time. */\n DEFINE_FUNCTION_ARITY_MISMATCH: \"DEFINE_FUNCTION_ARITY_MISMATCH\",\n /** An argument was the wrong value type. Raised at evaluation time. */\n DEFINE_FUNCTION_ARGUMENT_TYPE: \"DEFINE_FUNCTION_ARGUMENT_TYPE\",\n /** The `call` implementation returned a value that did not match `returns`. Raised at evaluation time, an authoring bug rather than a user one. */\n DEFINE_FUNCTION_RETURN_TYPE: \"DEFINE_FUNCTION_RETURN_TYPE\",\n} as const;\n\n/** A single identifier: a letter or underscore, then letters, digits, or underscores. */\nconst NAME_PATTERN = /^[a-z_][a-z0-9_]*$/i;\n\nconst SUPPORTED_TYPES: ReadonlySet<string> = new Set([\"number\", \"string\", \"boolean\"]);\n\n/** \"1 argument\" / \"2 arguments\", so a count reads as English either way. Mirrors `VMBuiltinArity.ts`. */\nfunction plural(count: number): string {\n return count === 1 ? \"1 argument\" : `${count} arguments`;\n}\n\n/**\n * A human noun for the type a Value actually carries, for the \"was given ...\"\n * half of a mismatch message. Covers the three declarable types by their own\n * names and everything else by a readable category, so the message never reads\n * \"given a 6\".\n */\nfunction describeValueType(v: Value): string {\n switch (v.type) {\n case ValueType.Number:\n case ValueType.Hex:\n return \"a number\";\n case ValueType.String:\n return \"a string\";\n case ValueType.Boolean:\n return \"a boolean\";\n case ValueType.BigInt:\n return \"a big integer\";\n case ValueType.Percentage:\n return \"a percentage\";\n case ValueType.Uom:\n return \"a value with a unit\";\n case ValueType.Datetime:\n return \"a date\";\n case ValueType.Matrix:\n return \"a matrix\";\n case ValueType.Range:\n return \"a range\";\n case ValueType.Symbolic:\n return \"a symbolic expression\";\n default:\n return \"an unsupported value\";\n }\n}\n\n/**\n * Read one runtime Value as the JS primitive its declared type promises, or\n * raise the engine's structured type error.\n *\n * A \"number\" accepts a plain number or a based literal (`0xFF`), both of which\n * ARE numbers written differently, and reads it with `toNumber()`. Nothing\n * else is coerced: a percentage, a unit-bearing value or a string is a\n * genuinely different kind of value, and silently reinterpreting it is the\n * class of wrong-answer this API exists to avoid.\n */\nfunction coerceArgument(\n value: Value,\n arg: FunctionArg,\n fnName: string,\n): number | string | boolean {\n switch (arg.type) {\n case \"number\":\n // Hex is a number in another base (see `hexValue`), so it reads as one here.\n if (value.type === ValueType.Number || value.type === ValueType.Hex) {\n return value.toNumber();\n }\n break;\n case \"string\":\n if (value.type === ValueType.String) return value.value as string;\n break;\n case \"boolean\":\n if (value.type === ValueType.Boolean) return value.value as boolean;\n break;\n }\n throw ErrorFactory.execution({\n code: DefineFunctionErrorCodes.DEFINE_FUNCTION_ARGUMENT_TYPE,\n message: `${fnName}() expects \"${arg.name}\" to be a ${arg.type}, but was given ${describeValueType(value)}`,\n expected: `a ${arg.type}`,\n found: describeValueType(value),\n context: { functionName: fnName, argName: arg.name, expectedType: arg.type },\n });\n}\n\n/**\n * Wrap the `call` result back into a Value of the declared return type, or\n * raise a structured error if the implementation handed back something else.\n *\n * The type check here catches an authoring mistake (a function declared to\n * return a number that returns `undefined`, or a Promise from an accidental\n * `async`), turning it into a named error rather than a Value that lies about\n * its own type downstream.\n */\nfunction wrapReturn(result: unknown, returns: FunctionValueType, fnName: string): Value {\n switch (returns) {\n case \"number\":\n if (typeof result === \"number\") return numberValue(result);\n break;\n case \"string\":\n if (typeof result === \"string\") return stringValue(result);\n break;\n case \"boolean\":\n if (typeof result === \"boolean\") return boolValue(result);\n break;\n }\n throw ErrorFactory.internal({\n code: DefineFunctionErrorCodes.DEFINE_FUNCTION_RETURN_TYPE,\n message: `${fnName}() is declared to return a ${returns}, but its implementation returned ${typeof result}`,\n expected: `a ${returns}`,\n found: typeof result,\n context: { functionName: fnName, expectedType: returns },\n });\n}\n\n/**\n * The call-syntax parselet generated for one declared function.\n *\n * Identical in shape to the built-in `FunctionCallParselet`: consume the open\n * paren, parse a comma-separated argument list, then emit `CALL_PLUGIN` with\n * the function's index and the argument count. The count is whatever was\n * written, arity is checked at the dispatch point (see {@link makeHandler}),\n * the same place the built-in arity check lives.\n */\nclass DefinedFunctionParselet implements PrefixParselet {\n readonly category = \"Function\";\n\n constructor(\n private readonly fnName: string,\n ) {}\n\n parse(parser: Parser, _token: Token, builder: BytecodeBuilder): void {\n parser.consume(\"LPAREN\");\n\n let argCount = 0;\n if (parser.peek()?.type !== \"RPAREN\") {\n parser.parseExpression(BindingPower.Lowest, builder);\n argCount++;\n while (parser.match(\"COMMA\")) {\n parser.parseExpression(BindingPower.Lowest, builder);\n argCount++;\n }\n }\n\n parser.consume(\"RPAREN\");\n\n builder.emitPluginCall(this.fnName, argCount);\n }\n}\n\n/**\n * Build the plugin function that checks arity and argument types, calls the\n * host implementation, and wraps the result.\n *\n * The VM has already screened out faulted arguments (an errored or still\n * pending operand short-circuits before the handler runs, see\n * `VM.ts`'s `CALL_PLUGIN` case), so every Value reaching here carries a real\n * result. Arity is checked first, before any argument is read, so a wrong\n * count is reported as a wrong count rather than as a type error on a missing\n * argument.\n */\nfunction makeHandler(spec: FunctionSpec): (args: Value[]) => Value {\n const arity = spec.args.length;\n return (args: Value[]): Value => {\n if (args.length !== arity) {\n throw ErrorFactory.execution({\n code: DefineFunctionErrorCodes.DEFINE_FUNCTION_ARITY_MISMATCH,\n message: `${spec.name}() takes ${plural(arity)}, but was given ${args.length === 0 ? \"none\" : plural(args.length)}`,\n expected: plural(arity),\n found: args.length === 0 ? \"none\" : plural(args.length),\n context: { functionName: spec.name, expected: arity, actual: args.length },\n });\n }\n\n const jsArgs: (number | string | boolean)[] = new Array(arity);\n for (let i = 0; i < arity; i++) {\n jsArgs[i] = coerceArgument(args[i], spec.args[i], spec.name);\n }\n\n const result = (spec.call as (...a: (number | string | boolean)[]) => unknown)(...jsArgs);\n return wrapReturn(result, spec.returns, spec.name);\n };\n}\n\n/** Reject a spec that could not produce a working function, before any engine sees it. */\nfunction validateSpec(spec: FunctionSpec): void {\n if (typeof spec?.name !== \"string\" || !NAME_PATTERN.test(spec.name)) {\n throw ErrorFactory.config({\n code: DefineFunctionErrorCodes.DEFINE_FUNCTION_INVALID_NAME,\n message: `defineFunction: name must be a single identifier, got ${JSON.stringify(spec?.name)}`,\n suggestion: 'e.g. \"vat\" or \"net_price\"',\n context: { name: spec?.name },\n });\n }\n if (!Array.isArray(spec.args)) {\n throw ErrorFactory.config({\n code: DefineFunctionErrorCodes.DEFINE_FUNCTION_INVALID_SPEC,\n message: `defineFunction: \"${spec.name}\" args must be an array`,\n context: { name: spec.name },\n });\n }\n for (const arg of spec.args) {\n if (typeof arg?.name !== \"string\" || arg.name.length === 0) {\n throw ErrorFactory.config({\n code: DefineFunctionErrorCodes.DEFINE_FUNCTION_INVALID_SPEC,\n message: `defineFunction: \"${spec.name}\" has an argument with no name`,\n context: { name: spec.name },\n });\n }\n if (!SUPPORTED_TYPES.has(arg.type)) {\n throw ErrorFactory.config({\n code: DefineFunctionErrorCodes.DEFINE_FUNCTION_INVALID_SPEC,\n message: `defineFunction: \"${spec.name}\" argument \"${arg.name}\" has unsupported type ${JSON.stringify(arg.type)}`,\n suggestion: \"supported argument types are number, string, boolean\",\n context: { name: spec.name, argName: arg.name, type: arg.type },\n });\n }\n }\n if (!SUPPORTED_TYPES.has(spec.returns)) {\n throw ErrorFactory.config({\n code: DefineFunctionErrorCodes.DEFINE_FUNCTION_INVALID_SPEC,\n message: `defineFunction: \"${spec.name}\" has unsupported return type ${JSON.stringify(spec.returns)}`,\n suggestion: \"supported return types are number, string, boolean\",\n context: { name: spec.name, returns: spec.returns },\n });\n }\n if (typeof spec.call !== \"function\") {\n throw ErrorFactory.config({\n code: DefineFunctionErrorCodes.DEFINE_FUNCTION_INVALID_SPEC,\n message: `defineFunction: \"${spec.name}\" is missing a call implementation`,\n context: { name: spec.name },\n });\n }\n}\n\n/**\n * Turn a declarative {@link FunctionSpec} into a ready-to-register\n * {@link IEnginePackage}.\n *\n * This is the higher-level API from issue #102. It derives, from the\n * declaration alone, everything the low-level contract asks an author to write\n * by hand: a named plugin function (the engine assigns its `CALL_PLUGIN`\n * index), a lexer keyword so the name tokenises, a call-syntax parselet emitting\n * that call by name, and a handler that checks arity and argument types (yielding\n * the engine's own structured errors) before invoking `call` and wrapping its\n * result. Anything needing custom parsing keeps writing a raw parselet exactly\n * as before, this sits on top of that contract and does not change it.\n *\n * @example\n * ```ts\n * const engine = new ExpressionEngine({ packages: [\n * ...BUILTIN_PACKAGES,\n * defineFunction({\n * name: \"vat\",\n * args: [{ name: \"amount\", type: \"number\" }],\n * returns: \"number\",\n * call: (amount) => amount * 1.2,\n * }),\n * ] });\n * engine.evaluateExpression(\"vat(100)\"); // 120\n * ```\n *\n * The returned package is self-contained and composes with any others through\n * the engine's `packages` array; register several functions by passing several\n * packages. Its name is `solve-fn-<name>`.\n *\n * Scope: arguments are a fixed-length list of `number`/`string`/`boolean`, and\n * `call` is synchronous. Variadic and optional arguments, other value types\n * (units, percentages, dates, matrices), and async work are deliberately out\n * of scope, a function needing any of those keeps using the low-level\n * contract, whose parselets and async resolvers are unchanged.\n *\n * @throws {EngineError} (category CONFIG) if the spec is malformed, at the\n * point `defineFunction` is called, before the package reaches an engine.\n */\nexport function defineFunction<\n const A extends readonly FunctionArg[],\n R extends FunctionValueType,\n>(spec: FunctionSpec<A, R>): IEnginePackage {\n validateSpec(spec as FunctionSpec);\n\n const name = spec.name;\n // Uppercased so the generated type is a valid, collision-resistant token\n // type; the name pattern guarantees it forms one. Distinct from the\n // built-in FUNC type, so this never routes through the builtin name map.\n const tokenType = `DEFINE_FN_${name.toUpperCase()}`;\n\n return {\n name: `solve-fn-${name}`,\n lexerVocabulary: {\n // Lowercased because the lexer lowercases input before lookup, so the\n // call is matched case-insensitively.\n keywords: { [name.toLowerCase()]: tokenType },\n },\n prefixParselets: {\n [tokenType]: new DefinedFunctionParselet(name),\n },\n pluginFunctions: {\n [name]: makeHandler(spec as FunctionSpec),\n },\n };\n}\n","import { ExpressionEngine, type EngineOptions } from \"@solve-js/engine/ExpressionEngine\";\nimport { BUILTIN_PACKAGES } from \"@solve-js/packages/builtins\";\nimport type { IEnginePackage } from \"@solve-js/api/PackageRegistry\";\n\n/** Options for {@link createEngine}: the engine options, minus `packages` (the\n * built-in set is always registered), plus `extraPackages` to add your own. */\nexport interface CreateEngineOptions extends Omit<EngineOptions, \"packages\"> {\n\t/** Packages to register ON TOP of the built-in set (e.g. an OSRS or stocks package). */\n\textraPackages?: IEnginePackage[];\n}\n\n/**\n * A batteries-included {@link ExpressionEngine} with every built-in package\n * registered.\n *\n * The constructor registers only the packages it is given, so a consumer's\n * bundler can tree-shake away the built-ins they never use: an engine built\n * with `new ExpressionEngine({ packages: [ARITHMETIC_PACKAGE] })` carries no\n * finance, colour or weather code. This convenience is the opposite trade: it\n * pulls the FULL built-in set (`BUILTIN_PACKAGES`) for the common \"I want\n * everything\" case, so importing it defeats that tree-shaking. Reach for the\n * constructor with an explicit package list when bundle size matters, and for\n * `createEngine` when it does not.\n *\n * @param options - Engine options ({@link EngineOptions}) minus `packages`, plus\n * an optional `extraPackages` to register alongside the built-in set.\n * @returns An engine with the built-in packages (and any extras) registered.\n *\n * @example\n * ```typescript\n * import { createEngine } from \"solve-engine\";\n * const engine = createEngine();\n * const value = engine.evaluateExpression(\"2 + 2 * 10\");\n * console.log(value.toNumber()); // 22\n * ```\n */\nexport function createEngine(options: CreateEngineOptions = {}): ExpressionEngine {\n\tconst { extraPackages = [], ...engineOptions } = options;\n\treturn new ExpressionEngine({\n\t\t...engineOptions,\n\t\tpackages: extraPackages.length > 0 ? [...BUILTIN_PACKAGES, ...extraPackages] : BUILTIN_PACKAGES,\n\t});\n}\n"]}
package/dist/language.cjs CHANGED
@@ -1,370 +1,2 @@
1
- 'use strict';
2
-
3
- var chunkEJ3ILXX6_cjs = require('./chunk-EJ3ILXX6.cjs');
4
- var chunk536WPM2V_cjs = require('./chunk-536WPM2V.cjs');
5
- var chunkAQNHHJMJ_cjs = require('./chunk-AQNHHJMJ.cjs');
6
- require('./chunk-AMOJYLG2.cjs');
7
- require('./chunk-B7LXJ6LC.cjs');
8
-
9
- // src/language/LanguageService.ts
10
- var MAX_COMPLETIONS = 50;
11
- var CATEGORY_TIER = {
12
- variable: 0,
13
- function: 1,
14
- keyword: 1,
15
- operator: 1,
16
- comparison: 1,
17
- bitwise: 1,
18
- datetime: 1,
19
- vector: 1,
20
- unit: 2
21
- };
22
- var MAX_CACHED_LINES = 2e3;
23
- var LanguageService = class {
24
- constructor(engine, options) {
25
- // Bounded cache keyed by line number ALONE, not `${lineNumber}:${lineText}`
26
- // as an earlier version of this class did. A line's previous text state is
27
- // never useful once it changes, so keying on text too was pure waste:
28
- // every keystroke on a line minted a brand-new, never-reclaimed cache
29
- // entry (an effective per-keystroke memory leak over a long editing
30
- // session). Keying on line number alone makes "same line, new text" a
31
- // cheap overwrite instead.
32
- //
33
- // Eviction is oldest-inserted (Map iteration order) when at capacity
34
- // mirroring the same bounded-cache pattern ExpressionEngine's own
35
- // bytecodeCache already uses elsewhere in this codebase. Deliberately
36
- // NOT an LFU (least-frequently-used) policy: LFU would keep resisting
37
- // eviction of old, once-popular lines while punishing a line that just
38
- // scrolled into view (frequency 1), the opposite of what a "currently
39
- // visible" cache should prioritize.
40
- this.cache = /* @__PURE__ */ new Map();
41
- // Keyword/unit/package-contributed completion candidates don't depend
42
- // on any particular line, built lazily on first getCompletions() call
43
- // and reused after that, since a package registration is the only thing
44
- // that could ever change this list mid-session (see invalidateCache()).
45
- // Variable-name candidates are NOT part of this, they're read fresh on
46
- // every call from variableNameSource(), since those genuinely change on
47
- // every edit.
48
- this.staticCompletionCandidates = null;
49
- // The same candidates, bucketed by their lowercased first character with the
50
- // lowercased label precomputed. getCompletions() runs on every keystroke and
51
- // only ever wants candidates sharing the prefix's first character, so
52
- // scanning the whole list and lowercasing each label per call was doing two
53
- // avoidable things: touching entries that could not possibly match, and
54
- // allocating a string per candidate per keystroke. That was affordable when
55
- // the vocabulary was a few hundred entries. Deriving the unit list from the
56
- // conversion tables took it past a thousand, and the warm completion
57
- // benchmarks regressed roughly 2.9x until this was added.
58
- this.staticCompletionIndex = null;
59
- this.engine = engine ?? null;
60
- this.variableNameSource = options?.variableNameSource ?? (() => this.defaultVariableNames());
61
- this.normalizeForHighlighting = options?.normalizeForHighlighting ?? false;
62
- }
63
- defaultVariableNames() {
64
- if (!this.engine) return [];
65
- const snapshot = this.engine.getDag().getSnapshot();
66
- const names = new Set(Object.keys(snapshot.consumers));
67
- for (const written of Object.values(snapshot.writes)) {
68
- for (const name of written) names.add(name);
69
- }
70
- return names;
71
- }
72
- /**
73
- * Lex a line, normalize it, and place every resulting token back in the
74
- * source text.
75
- *
76
- * ## Why placing them back is the hard part
77
- *
78
- * Normalization produces three kinds of token and only one of them can be
79
- * highlighted the obvious way.
80
- *
81
- * A token the normalizer left alone still describes its own text, so its
82
- * span is `offset` to `offset + text.length`, exactly as before.
83
- *
84
- * A FUSED token does not. `10 frames` becomes a FRAME_COUNT whose value is
85
- * `10`, and a timecode becomes a token whose value is a comma-separated
86
- * tuple appearing nowhere on the line. Those carry `sourceEnd`, set by
87
- * `createFusedToken`, which is the only place that knows where the fusion
88
- * ended.
89
- *
90
- * An INSERTED token has no text at all. Implicit multiplication puts a STAR
91
- * at the following token's offset, so `5(3)` gains a `*` sitting exactly
92
- * where the `(` is. Painting it would colour a character the reader never
93
- * typed as an operator, and would overlap the token that really is there.
94
- * These are dropped, detected by the one test that needs no cooperation
95
- * from any rule: a token with no recorded fusion span must match the text
96
- * at its own offset, and an inserted one does not.
97
- *
98
- * @param lineText - The raw line.
99
- * @returns Spans in the same shape `Lexer.getHighlightTokens` returns.
100
- */
101
- classifyNormalized(lineText) {
102
- const lexer = this.engine.getLexer();
103
- const raw = lexer.getHighlightTokenObjects(lineText);
104
- if (raw.length === 0) return [];
105
- const source = lineText.startsWith("> ") && lexer.classifyLine(lineText).skip ? lineText.slice(2) : lineText;
106
- let normalized;
107
- try {
108
- normalized = this.engine.getNormalizer().normalize(raw);
109
- } catch {
110
- normalized = raw;
111
- }
112
- const out = [];
113
- for (const token of normalized) {
114
- let end;
115
- if (token.sourceEnd !== void 0) {
116
- end = token.sourceEnd;
117
- } else if (source.startsWith(token.text, token.offset)) {
118
- end = token.offset + token.text.length;
119
- } else {
120
- continue;
121
- }
122
- out.push({
123
- type: token.type,
124
- value: token.value,
125
- offset: token.offset,
126
- col: token.col,
127
- length: end - token.offset,
128
- category: chunk536WPM2V_cjs.getTokenCategory(token.type)
129
- });
130
- }
131
- return out;
132
- }
133
- /**
134
- * Classify every recognized token on one line.
135
- *
136
- * @param lineText - The raw line text (may be a markdown-structural line
137
- * the engine's classifier skips, that's handled by the underlying
138
- * lexer, which returns no tokens for those).
139
- * @param lineNumber - 1-based line number, used purely as a cache key.
140
- */
141
- getSemanticTokens(lineText, lineNumber) {
142
- const cached = this.cache.get(lineNumber);
143
- if (cached && cached.text === lineText) {
144
- if (cached.bareWordCandidate !== void 0) {
145
- return this.isKnownVariable(cached.bareWordCandidate) ? cached.tokens : [];
146
- }
147
- return cached.tokens;
148
- }
149
- if (!this.engine) {
150
- return [];
151
- }
152
- const lexer = this.engine.getLexer();
153
- const lexed = this.normalizeForHighlighting ? this.classifyNormalized(lineText) : lexer.getHighlightTokens(lineText);
154
- if (lexed.length === 0) {
155
- this.putCache(lineNumber, lineText, []);
156
- return [];
157
- }
158
- const classification = lexer.classifyLine(lineText);
159
- const tokens = [];
160
- if (classification.hasInlineSolve) {
161
- const validSpans = lexer.findInlineSolves(lineText).filter((span) => this.parsesAsExpression(span.expression)).map((span) => ({ from: span.start, to: span.end }));
162
- for (const token of lexed) {
163
- if (!token.category) continue;
164
- const from = token.offset;
165
- const to = token.offset + token.length;
166
- if (!validSpans.some((s) => from >= s.from && to <= s.to)) continue;
167
- tokens.push({ from, to, category: token.category });
168
- }
169
- } else {
170
- const text = lineText.startsWith("> ") && classification.skip ? lineText.slice(2) : lineText;
171
- if (this.parsesAsExpression(text)) {
172
- for (const token of lexed) {
173
- if (!token.category) continue;
174
- tokens.push({ from: token.offset, to: token.offset + token.length, category: token.category });
175
- }
176
- }
177
- }
178
- if (tokens.length === 1 && tokens[0].category === "variable") {
179
- const name = lineText.slice(tokens[0].from, tokens[0].to);
180
- this.putCache(lineNumber, lineText, tokens, name);
181
- return this.isKnownVariable(name) ? tokens : [];
182
- }
183
- this.putCache(lineNumber, lineText, tokens);
184
- return tokens;
185
- }
186
- /**
187
- * Completion candidates for the identifier prefix immediately before
188
- * `cursorOffset` on `lineText`. Deliberately simple prefix matching, not
189
- * parser-driven "what's grammatically valid here" prediction, a
190
- * half-typed expression almost never parses, so gating on parse
191
- * validity (the way `getSemanticTokens` does) would suppress
192
- * completions almost always. This is the safest, fastest option that
193
- * still delivers real value.
194
- *
195
- * Candidates come from three sources: keywords (which already include
196
- * function names. See `ExpressionLexer.getKeywords()`'s doc comment)
197
- * and units, both static per engine configuration and cached lazily;
198
- * package-contributed items (`IEnginePackage.completionItems`), same
199
- * cache; and variable names, read fresh from `variableNameSource()` on
200
- * every call since those change on every edit.
201
- */
202
- getCompletions(lineText, cursorOffset) {
203
- const prefixMatch = /[A-Za-z0-9_]+$/.exec(lineText.slice(0, cursorOffset));
204
- if (!prefixMatch) return [];
205
- const prefix = prefixMatch[0].toLowerCase();
206
- if (!this.engine) return [];
207
- const matches = [];
208
- for (const name of this.variableNameSource()) {
209
- if (name.toLowerCase().startsWith(prefix)) {
210
- matches.push({ label: name, category: "variable" });
211
- }
212
- }
213
- const bucket = this.getStaticCompletionIndex().get(prefix[0]);
214
- if (bucket) {
215
- for (const candidate of bucket) {
216
- if (candidate.lowerLabel.startsWith(prefix)) matches.push(candidate.item);
217
- }
218
- }
219
- matches.sort((a, b) => {
220
- const tierDiff = (CATEGORY_TIER[a.category] ?? 3) - (CATEGORY_TIER[b.category] ?? 3);
221
- if (tierDiff !== 0) return tierDiff;
222
- return a.label.localeCompare(b.label);
223
- });
224
- return matches.slice(0, MAX_COMPLETIONS);
225
- }
226
- /** Lazily builds and caches the keyword/unit/package-item candidate list. See `staticCompletionCandidates`. */
227
- getStaticCompletionCandidates() {
228
- if (this.staticCompletionCandidates) return this.staticCompletionCandidates;
229
- const items = [];
230
- for (const [word, tokenType] of Object.entries(this.engine.getLexer().getKeywords())) {
231
- const category = chunk536WPM2V_cjs.getTokenCategory(tokenType);
232
- if (!category) continue;
233
- items.push({ label: word, category });
234
- }
235
- for (const unit of chunkAQNHHJMJ_cjs.knownUnits) {
236
- items.push({ label: unit, category: "unit", detail: chunkEJ3ILXX6_cjs.getMeasure(unit) });
237
- }
238
- items.push(...this.engine.getPackageCompletionItems());
239
- this.staticCompletionCandidates = items;
240
- return items;
241
- }
242
- /**
243
- * The static candidates bucketed by lowercased first character, built once
244
- * from {@link getStaticCompletionCandidates} and invalidated alongside it.
245
- */
246
- getStaticCompletionIndex() {
247
- if (this.staticCompletionIndex) return this.staticCompletionIndex;
248
- const index = /* @__PURE__ */ new Map();
249
- for (const item of this.getStaticCompletionCandidates()) {
250
- const lowerLabel = item.label.toLowerCase();
251
- const firstCharacter = lowerLabel[0];
252
- if (firstCharacter === void 0) continue;
253
- let bucket = index.get(firstCharacter);
254
- if (bucket === void 0) {
255
- bucket = [];
256
- index.set(firstCharacter, bucket);
257
- }
258
- bucket.push({ item, lowerLabel });
259
- }
260
- this.staticCompletionIndex = index;
261
- return index;
262
- }
263
- isKnownVariable(name) {
264
- for (const known of this.variableNameSource()) {
265
- if (known === name) return true;
266
- }
267
- return false;
268
- }
269
- /**
270
- * Whether the engine's parser actually accepts a piece of text as a
271
- * well-formed expression, not merely whether it lexes into individually
272
- * recognized token types. See the class doc comment's prose example.
273
- * `tryCompileExpression` is compile-only (lex → normalize → parse →
274
- * cache bytecode, no VM execution, no network/async side effects) and
275
- * reuses the engine's existing bytecode cache, so text that's already
276
- * been evaluated (or previously highlight-checked) is a cache hit here
277
- * too.
278
- *
279
- * Deliberately calls the non-throwing `tryCompileExpression` rather than
280
- * try/catching `compileExpression`. This runs on every visible line on
281
- * every keystroke, and the common case for a real markdown document is
282
- * lines that DON'T parse (prose), not lines that do. Throwing there would
283
- * mean constructing a EngineError (with V8 stack-trace capture) for the
284
- * common case instead of the rare one.
285
- */
286
- parsesAsExpression(text) {
287
- return this.engine.tryCompileExpression(text);
288
- }
289
- putCache(lineNumber, text, tokens, bareWordCandidate) {
290
- if (!this.cache.has(lineNumber) && this.cache.size >= MAX_CACHED_LINES) {
291
- const oldestKey = this.cache.keys().next().value;
292
- if (oldestKey !== void 0) this.cache.delete(oldestKey);
293
- }
294
- this.cache.set(lineNumber, { text, tokens, bareWordCandidate });
295
- }
296
- /**
297
- * Evict specific lines (e.g. the lines actually touched by a CodeMirror
298
- * change set) instead of the whole cache, the surgical counterpart to
299
- * {@link invalidateCache}, letting a single-line edit stay cheap even in
300
- * a large document: every other cached line is untouched and still hits
301
- * on the next call.
302
- */
303
- invalidateLines(lineNumbers) {
304
- for (const lineNumber of lineNumbers) {
305
- this.cache.delete(lineNumber);
306
- }
307
- }
308
- /**
309
- * Full cache clear. Reserved for cases with no meaningful "which lines
310
- * changed" (e.g. the document was swapped wholesale, or a package was
311
- * registered/unregistered mid-session, changing what categories exist).
312
- * Prefer {@link invalidateLines} for ordinary edits. Also rebuilds the
313
- * lazily-cached keyword/unit/package-item completion candidates on next
314
- * use, the only thing that can change that list mid-session.
315
- */
316
- invalidateCache() {
317
- this.cache.clear();
318
- this.staticCompletionCandidates = null;
319
- this.staticCompletionIndex = null;
320
- }
321
- };
322
-
323
- // src/language/tokenClassName.ts
324
- var DEFAULT_TOKEN_CLASS_PREFIX = "solve-";
325
- function tokenClassName(category, prefix = DEFAULT_TOKEN_CLASS_PREFIX) {
326
- return `${prefix}${category}`;
327
- }
328
- function createTokenClassName(prefix) {
329
- return (category) => `${prefix}${category}`;
330
- }
331
-
332
- // src/language/adapters/codemirror.ts
333
- var CATEGORY_TO_COMPLETION_TYPE = {
334
- keyword: "keyword",
335
- operator: "keyword",
336
- comparison: "keyword",
337
- bitwise: "keyword",
338
- function: "function",
339
- variable: "variable",
340
- unit: "type",
341
- datetime: "keyword",
342
- vector: "type"
343
- };
344
- function completionItemToOption(item) {
345
- return { label: item.label, type: CATEGORY_TO_COMPLETION_TYPE[item.category] ?? "text", detail: item.detail };
346
- }
347
-
348
- Object.defineProperty(exports, "UNCATEGORIZED_TOKEN_TYPES", {
349
- enumerable: true,
350
- get: function () { return chunk536WPM2V_cjs.UNCATEGORIZED_TOKEN_TYPES; }
351
- });
352
- Object.defineProperty(exports, "getTokenCategory", {
353
- enumerable: true,
354
- get: function () { return chunk536WPM2V_cjs.getTokenCategory; }
355
- });
356
- Object.defineProperty(exports, "registerTokenCategory", {
357
- enumerable: true,
358
- get: function () { return chunk536WPM2V_cjs.registerTokenCategory; }
359
- });
360
- Object.defineProperty(exports, "unregisterTokenCategory", {
361
- enumerable: true,
362
- get: function () { return chunk536WPM2V_cjs.unregisterTokenCategory; }
363
- });
364
- exports.DEFAULT_TOKEN_CLASS_PREFIX = DEFAULT_TOKEN_CLASS_PREFIX;
365
- exports.LanguageService = LanguageService;
366
- exports.completionItemToOption = completionItemToOption;
367
- exports.createTokenClassName = createTokenClassName;
368
- exports.tokenClassName = tokenClassName;
369
- //# sourceMappingURL=language.cjs.map
1
+ 'use strict';var chunkIANAMBJQ_cjs=require('./chunk-IANAMBJQ.cjs'),chunkY7O4D3BJ_cjs=require('./chunk-Y7O4D3BJ.cjs'),chunkFWW3M36J_cjs=require('./chunk-FWW3M36J.cjs');require('./chunk-CIQOK7Q4.cjs');var I=50,C={variable:0,function:1,keyword:1,operator:1,comparison:1,bitwise:1,datetime:1,vector:1,unit:2},T=2e3,p=class{constructor(e,o){this.cache=new Map;this.staticCompletionCandidates=null;this.staticCompletionIndex=null;this.engine=e??null,this.variableNameSource=o?.variableNameSource??(()=>this.defaultVariableNames()),this.normalizeForHighlighting=o?.normalizeForHighlighting??false;}defaultVariableNames(){if(!this.engine)return [];let e=this.engine.getDag().getSnapshot(),o=new Set(Object.keys(e.consumers));for(let n of Object.values(e.writes))for(let i of n)o.add(i);return o}classifyNormalized(e){let o=this.engine.getLexer(),n=o.getHighlightTokenObjects(e);if(n.length===0)return [];let i=e.startsWith("> ")&&o.classifyLine(e).skip?e.slice(2):e,r;try{r=this.engine.getNormalizer().normalize(n);}catch{r=n;}let l=[];for(let t of r){let s;if(t.sourceEnd!==void 0)s=t.sourceEnd;else if(i.startsWith(t.text,t.offset))s=t.offset+t.text.length;else continue;l.push({type:t.type,value:t.value,offset:t.offset,col:t.col,length:s-t.offset,category:chunkY7O4D3BJ_cjs.d(t.type)});}return l}getSemanticTokens(e,o){let n=this.cache.get(o);if(n&&n.text===e)return n.bareWordCandidate!==void 0?this.isKnownVariable(n.bareWordCandidate)?n.tokens:[]:n.tokens;if(!this.engine)return [];let i=this.engine.getLexer(),r=this.normalizeForHighlighting?this.classifyNormalized(e):i.getHighlightTokens(e);if(r.length===0)return this.putCache(o,e,[]),[];let l=i.classifyLine(e),t=[];if(l.hasInlineSolve){let s=i.findInlineSolves(e).filter(a=>this.parsesAsExpression(a.expression)).map(a=>({from:a.start,to:a.end}));for(let a of r){if(!a.category)continue;let m=a.offset,f=a.offset+a.length;s.some(u=>m>=u.from&&f<=u.to)&&t.push({from:m,to:f,category:a.category});}}else {let s=e.startsWith("> ")&&l.skip?e.slice(2):e;if(this.parsesAsExpression(s))for(let a of r)a.category&&t.push({from:a.offset,to:a.offset+a.length,category:a.category});}if(t.length===1&&t[0].category==="variable"){let s=e.slice(t[0].from,t[0].to);return this.putCache(o,e,t,s),this.isKnownVariable(s)?t:[]}return this.putCache(o,e,t),t}getCompletions(e,o){let n=/[A-Za-z0-9_]+$/.exec(e.slice(0,o));if(!n)return [];let i=n[0].toLowerCase();if(!this.engine)return [];let r=[];for(let t of this.variableNameSource())t.toLowerCase().startsWith(i)&&r.push({label:t,category:"variable"});let l=this.getStaticCompletionIndex().get(i[0]);if(l)for(let t of l)t.lowerLabel.startsWith(i)&&r.push(t.item);return r.sort((t,s)=>{let a=(C[t.category]??3)-(C[s.category]??3);return a!==0?a:t.label.localeCompare(s.label)}),r.slice(0,I)}getStaticCompletionCandidates(){if(this.staticCompletionCandidates)return this.staticCompletionCandidates;let e=[];for(let[o,n]of Object.entries(this.engine.getLexer().getKeywords())){let i=chunkY7O4D3BJ_cjs.d(n);i&&e.push({label:o,category:i});}for(let o of chunkFWW3M36J_cjs.a)e.push({label:o,category:"unit",detail:chunkIANAMBJQ_cjs.c(o)});return e.push(...this.engine.getPackageCompletionItems()),this.staticCompletionCandidates=e,e}getStaticCompletionIndex(){if(this.staticCompletionIndex)return this.staticCompletionIndex;let e=new Map;for(let o of this.getStaticCompletionCandidates()){let n=o.label.toLowerCase(),i=n[0];if(i===void 0)continue;let r=e.get(i);r===void 0&&(r=[],e.set(i,r)),r.push({item:o,lowerLabel:n});}return this.staticCompletionIndex=e,e}isKnownVariable(e){for(let o of this.variableNameSource())if(o===e)return true;return false}parsesAsExpression(e){return this.engine.tryCompileExpression(e)}putCache(e,o,n,i){if(!this.cache.has(e)&&this.cache.size>=T){let r=this.cache.keys().next().value;r!==void 0&&this.cache.delete(r);}this.cache.set(e,{text:o,tokens:n,bareWordCandidate:i});}invalidateLines(e){for(let o of e)this.cache.delete(o);}invalidateCache(){this.cache.clear(),this.staticCompletionCandidates=null,this.staticCompletionIndex=null;}};var y="solve-";function x(c,e=y){return `${e}${c}`}function E(c){return e=>`${c}${e}`}var S={keyword:"keyword",operator:"keyword",comparison:"keyword",bitwise:"keyword",function:"function",variable:"variable",unit:"type",datetime:"keyword",vector:"type"};function w(c){return {label:c.label,type:S[c.category]??"text",detail:c.detail}}Object.defineProperty(exports,"UNCATEGORIZED_TOKEN_TYPES",{enumerable:true,get:function(){return chunkY7O4D3BJ_cjs.a}});Object.defineProperty(exports,"getTokenCategory",{enumerable:true,get:function(){return chunkY7O4D3BJ_cjs.d}});Object.defineProperty(exports,"registerTokenCategory",{enumerable:true,get:function(){return chunkY7O4D3BJ_cjs.b}});Object.defineProperty(exports,"unregisterTokenCategory",{enumerable:true,get:function(){return chunkY7O4D3BJ_cjs.c}});exports.DEFAULT_TOKEN_CLASS_PREFIX=y;exports.LanguageService=p;exports.completionItemToOption=w;exports.createTokenClassName=E;exports.tokenClassName=x;//# sourceMappingURL=language.cjs.map
370
2
  //# sourceMappingURL=language.cjs.map