@elaraai/east 0.0.1-beta.9 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (410) hide show
  1. package/LICENSE.md +15 -666
  2. package/README.md +113 -88
  3. package/dist/src/analyze.d.ts +3 -0
  4. package/dist/src/analyze.d.ts.map +1 -1
  5. package/dist/src/analyze.js +223 -111
  6. package/dist/src/analyze.js.map +1 -1
  7. package/dist/src/analyze.spec.d.ts +2 -0
  8. package/dist/src/analyze.spec.d.ts.map +1 -0
  9. package/dist/src/analyze.spec.js +445 -0
  10. package/dist/src/analyze.spec.js.map +1 -0
  11. package/dist/src/ast.d.ts +54 -35
  12. package/dist/src/ast.d.ts.map +1 -1
  13. package/dist/src/ast_to_ir.coerce_to.spec.d.ts +15 -0
  14. package/dist/src/ast_to_ir.coerce_to.spec.d.ts.map +1 -0
  15. package/dist/src/ast_to_ir.coerce_to.spec.js +420 -0
  16. package/dist/src/ast_to_ir.coerce_to.spec.js.map +1 -0
  17. package/dist/src/ast_to_ir.d.ts +18 -4
  18. package/dist/src/ast_to_ir.d.ts.map +1 -1
  19. package/dist/src/ast_to_ir.js +233 -178
  20. package/dist/src/ast_to_ir.js.map +1 -1
  21. package/dist/src/builtins.d.ts +1 -1
  22. package/dist/src/builtins.d.ts.map +1 -1
  23. package/dist/src/builtins.js +194 -2
  24. package/dist/src/builtins.js.map +1 -1
  25. package/dist/src/comparison.d.ts +2 -2
  26. package/dist/src/comparison.d.ts.map +1 -1
  27. package/dist/src/comparison.js +115 -40
  28. package/dist/src/comparison.js.map +1 -1
  29. package/dist/src/comparison.spec.d.ts +2 -0
  30. package/dist/src/comparison.spec.d.ts.map +1 -0
  31. package/dist/src/comparison.spec.js +1200 -0
  32. package/dist/src/comparison.spec.js.map +1 -0
  33. package/dist/src/compile.d.ts +31 -9
  34. package/dist/src/compile.d.ts.map +1 -1
  35. package/dist/src/compile.js +1048 -548
  36. package/dist/src/compile.js.map +1 -1
  37. package/dist/src/containers/matrix.d.ts +15 -0
  38. package/dist/src/containers/matrix.d.ts.map +1 -0
  39. package/dist/src/containers/matrix.js +15 -0
  40. package/dist/src/containers/matrix.js.map +1 -0
  41. package/dist/src/containers/ref.d.ts.map +1 -1
  42. package/dist/src/containers/ref.js +1 -1
  43. package/dist/src/containers/ref.js.map +1 -1
  44. package/dist/src/containers/sortedmap.spec.d.ts +2 -0
  45. package/dist/src/containers/sortedmap.spec.d.ts.map +1 -0
  46. package/dist/src/containers/sortedmap.spec.js +180 -0
  47. package/dist/src/containers/sortedmap.spec.js.map +1 -0
  48. package/dist/src/containers/sortedset.spec.d.ts +2 -0
  49. package/dist/src/containers/sortedset.spec.d.ts.map +1 -0
  50. package/dist/src/containers/sortedset.spec.js +228 -0
  51. package/dist/src/containers/sortedset.spec.js.map +1 -0
  52. package/dist/src/containers/variant.d.ts.map +1 -1
  53. package/dist/src/containers/variant.js +1 -1
  54. package/dist/src/containers/variant.js.map +1 -1
  55. package/dist/src/containers/variant.spec.d.ts +2 -0
  56. package/dist/src/containers/variant.spec.d.ts.map +1 -0
  57. package/dist/src/containers/variant.spec.js +217 -0
  58. package/dist/src/containers/variant.spec.js.map +1 -0
  59. package/dist/src/datetime_format/parse.spec.d.ts +6 -0
  60. package/dist/src/datetime_format/parse.spec.d.ts.map +1 -0
  61. package/dist/src/datetime_format/parse.spec.js +379 -0
  62. package/dist/src/datetime_format/parse.spec.js.map +1 -0
  63. package/dist/src/datetime_format/print.spec.d.ts +6 -0
  64. package/dist/src/datetime_format/print.spec.d.ts.map +1 -0
  65. package/dist/src/datetime_format/print.spec.js +257 -0
  66. package/dist/src/datetime_format/print.spec.js.map +1 -0
  67. package/dist/src/datetime_format/tokenize.spec.d.ts +2 -0
  68. package/dist/src/datetime_format/tokenize.spec.d.ts.map +1 -0
  69. package/dist/src/datetime_format/tokenize.spec.js +508 -0
  70. package/dist/src/datetime_format/tokenize.spec.js.map +1 -0
  71. package/dist/src/datetime_format/types.d.ts +23 -23
  72. package/dist/src/default.d.ts.map +1 -1
  73. package/dist/src/default.js +33 -0
  74. package/dist/src/default.js.map +1 -1
  75. package/dist/src/default.spec.d.ts +2 -0
  76. package/dist/src/default.spec.d.ts.map +1 -0
  77. package/dist/src/default.spec.js +178 -0
  78. package/dist/src/default.spec.js.map +1 -0
  79. package/dist/src/eastir.d.ts +7 -0
  80. package/dist/src/eastir.d.ts.map +1 -1
  81. package/dist/src/eastir.js +55 -7
  82. package/dist/src/eastir.js.map +1 -1
  83. package/dist/src/error.d.ts +14 -4
  84. package/dist/src/error.d.ts.map +1 -1
  85. package/dist/src/error.js +28 -3
  86. package/dist/src/error.js.map +1 -1
  87. package/dist/src/example.d.ts +87 -0
  88. package/dist/src/example.d.ts.map +1 -0
  89. package/dist/src/example.js +18 -0
  90. package/dist/src/example.js.map +1 -0
  91. package/dist/src/expr/array.d.ts +43 -1
  92. package/dist/src/expr/array.d.ts.map +1 -1
  93. package/dist/src/expr/array.js +103 -53
  94. package/dist/src/expr/array.js.map +1 -1
  95. package/dist/src/expr/ast.d.ts +1 -1
  96. package/dist/src/expr/ast.d.ts.map +1 -1
  97. package/dist/src/expr/ast.js +112 -54
  98. package/dist/src/expr/ast.js.map +1 -1
  99. package/dist/src/expr/asyncfunction.d.ts.map +1 -1
  100. package/dist/src/expr/asyncfunction.js +6 -4
  101. package/dist/src/expr/asyncfunction.js.map +1 -1
  102. package/dist/src/expr/blob.d.ts +48 -0
  103. package/dist/src/expr/blob.d.ts.map +1 -1
  104. package/dist/src/expr/blob.js +63 -8
  105. package/dist/src/expr/blob.js.map +1 -1
  106. package/dist/src/expr/block.d.ts +213 -12
  107. package/dist/src/expr/block.d.ts.map +1 -1
  108. package/dist/src/expr/block.js +796 -293
  109. package/dist/src/expr/block.js.map +1 -1
  110. package/dist/src/expr/boolean.d.ts +44 -0
  111. package/dist/src/expr/boolean.d.ts.map +1 -1
  112. package/dist/src/expr/boolean.js +58 -6
  113. package/dist/src/expr/boolean.js.map +1 -1
  114. package/dist/src/expr/datetime.d.ts +135 -0
  115. package/dist/src/expr/datetime.d.ts.map +1 -1
  116. package/dist/src/expr/datetime.js +184 -34
  117. package/dist/src/expr/datetime.js.map +1 -1
  118. package/dist/src/expr/dict.d.ts +47 -2
  119. package/dist/src/expr/dict.d.ts.map +1 -1
  120. package/dist/src/expr/dict.js +122 -61
  121. package/dist/src/expr/dict.js.map +1 -1
  122. package/dist/src/expr/expr.d.ts +3 -1
  123. package/dist/src/expr/expr.d.ts.map +1 -1
  124. package/dist/src/expr/expr.js +4 -3
  125. package/dist/src/expr/expr.js.map +1 -1
  126. package/dist/src/expr/float.d.ts +153 -0
  127. package/dist/src/expr/float.d.ts.map +1 -1
  128. package/dist/src/expr/float.js +191 -17
  129. package/dist/src/expr/float.js.map +1 -1
  130. package/dist/src/expr/function.d.ts +7 -2
  131. package/dist/src/expr/function.d.ts.map +1 -1
  132. package/dist/src/expr/function.js +6 -4
  133. package/dist/src/expr/function.js.map +1 -1
  134. package/dist/src/expr/index.d.ts +186 -2
  135. package/dist/src/expr/index.d.ts.map +1 -1
  136. package/dist/src/expr/index.js +183 -2
  137. package/dist/src/expr/index.js.map +1 -1
  138. package/dist/src/expr/integer.d.ts +180 -0
  139. package/dist/src/expr/integer.d.ts.map +1 -1
  140. package/dist/src/expr/integer.js +189 -18
  141. package/dist/src/expr/integer.js.map +1 -1
  142. package/dist/src/expr/libs/array.js +3 -3
  143. package/dist/src/expr/libs/array.js.map +1 -1
  144. package/dist/src/expr/libs/blob.js +3 -3
  145. package/dist/src/expr/libs/blob.js.map +1 -1
  146. package/dist/src/expr/libs/dict.js +1 -1
  147. package/dist/src/expr/libs/dict.js.map +1 -1
  148. package/dist/src/expr/libs/matrix.d.ts +17 -0
  149. package/dist/src/expr/libs/matrix.d.ts.map +1 -0
  150. package/dist/src/expr/libs/matrix.js +60 -0
  151. package/dist/src/expr/libs/matrix.js.map +1 -0
  152. package/dist/src/expr/libs/set.js +1 -1
  153. package/dist/src/expr/libs/set.js.map +1 -1
  154. package/dist/src/expr/libs/string.d.ts.map +1 -1
  155. package/dist/src/expr/libs/string.js +2 -1
  156. package/dist/src/expr/libs/string.js.map +1 -1
  157. package/dist/src/expr/libs/vector.d.ts +16 -0
  158. package/dist/src/expr/libs/vector.d.ts.map +1 -0
  159. package/dist/src/expr/libs/vector.js +44 -0
  160. package/dist/src/expr/libs/vector.js.map +1 -0
  161. package/dist/src/expr/matrix.d.ts +109 -0
  162. package/dist/src/expr/matrix.d.ts.map +1 -0
  163. package/dist/src/expr/matrix.js +224 -0
  164. package/dist/src/expr/matrix.js.map +1 -0
  165. package/dist/src/expr/recursive.d.ts +83 -0
  166. package/dist/src/expr/recursive.d.ts.map +1 -0
  167. package/dist/src/expr/recursive.js +99 -0
  168. package/dist/src/expr/recursive.js.map +1 -0
  169. package/dist/src/expr/ref.js +5 -5
  170. package/dist/src/expr/ref.js.map +1 -1
  171. package/dist/src/expr/set.d.ts +44 -2
  172. package/dist/src/expr/set.d.ts.map +1 -1
  173. package/dist/src/expr/set.js +102 -52
  174. package/dist/src/expr/set.js.map +1 -1
  175. package/dist/src/expr/string.d.ts +134 -0
  176. package/dist/src/expr/string.d.ts.map +1 -1
  177. package/dist/src/expr/string.js +173 -23
  178. package/dist/src/expr/string.js.map +1 -1
  179. package/dist/src/expr/struct.d.ts +1 -1
  180. package/dist/src/expr/struct.d.ts.map +1 -1
  181. package/dist/src/expr/struct.js +2 -2
  182. package/dist/src/expr/struct.js.map +1 -1
  183. package/dist/src/expr/types.d.ts +12 -9
  184. package/dist/src/expr/types.d.ts.map +1 -1
  185. package/dist/src/expr/variant.d.ts +108 -11
  186. package/dist/src/expr/variant.d.ts.map +1 -1
  187. package/dist/src/expr/variant.js +76 -38
  188. package/dist/src/expr/variant.js.map +1 -1
  189. package/dist/src/expr/vector.d.ts +102 -0
  190. package/dist/src/expr/vector.d.ts.map +1 -0
  191. package/dist/src/expr/vector.js +202 -0
  192. package/dist/src/expr/vector.js.map +1 -0
  193. package/dist/src/fuzz.d.ts +36 -2
  194. package/dist/src/fuzz.d.ts.map +1 -1
  195. package/dist/src/fuzz.js +409 -77
  196. package/dist/src/fuzz.js.map +1 -1
  197. package/dist/src/index.d.ts +4 -0
  198. package/dist/src/index.d.ts.map +1 -1
  199. package/dist/src/index.js +4 -0
  200. package/dist/src/index.js.map +1 -1
  201. package/dist/src/internal.d.ts +12 -2
  202. package/dist/src/internal.d.ts.map +1 -1
  203. package/dist/src/internal.js +13 -2
  204. package/dist/src/internal.js.map +1 -1
  205. package/dist/src/ir.d.ts +1754 -1484
  206. package/dist/src/ir.d.ts.map +1 -1
  207. package/dist/src/ir.js +51 -34
  208. package/dist/src/ir.js.map +1 -1
  209. package/dist/src/ir.spec.d.ts +2 -0
  210. package/dist/src/ir.spec.d.ts.map +1 -0
  211. package/dist/src/ir.spec.js +35 -0
  212. package/dist/src/ir.spec.js.map +1 -0
  213. package/dist/src/location.d.ts +56 -17
  214. package/dist/src/location.d.ts.map +1 -1
  215. package/dist/src/location.js +226 -29
  216. package/dist/src/location.js.map +1 -1
  217. package/dist/src/location.spec.d.ts +2 -0
  218. package/dist/src/location.spec.d.ts.map +1 -0
  219. package/dist/src/location.spec.js +102 -0
  220. package/dist/src/location.spec.js.map +1 -0
  221. package/dist/src/patch/apply.d.ts +15 -0
  222. package/dist/src/patch/apply.d.ts.map +1 -0
  223. package/dist/src/patch/apply.js +352 -0
  224. package/dist/src/patch/apply.js.map +1 -0
  225. package/dist/src/patch/compose.d.ts +15 -0
  226. package/dist/src/patch/compose.d.ts.map +1 -0
  227. package/dist/src/patch/compose.js +448 -0
  228. package/dist/src/patch/compose.js.map +1 -0
  229. package/dist/src/patch/diff.d.ts +15 -0
  230. package/dist/src/patch/diff.d.ts.map +1 -0
  231. package/dist/src/patch/diff.js +347 -0
  232. package/dist/src/patch/diff.js.map +1 -0
  233. package/dist/src/patch/fuzz.d.ts +73 -0
  234. package/dist/src/patch/fuzz.d.ts.map +1 -0
  235. package/dist/src/patch/fuzz.js +159 -0
  236. package/dist/src/patch/fuzz.js.map +1 -0
  237. package/dist/src/patch/index.d.ts +32 -0
  238. package/dist/src/patch/index.d.ts.map +1 -0
  239. package/dist/src/patch/index.js +48 -0
  240. package/dist/src/patch/index.js.map +1 -0
  241. package/dist/src/patch/invert.d.ts +15 -0
  242. package/dist/src/patch/invert.d.ts.map +1 -0
  243. package/dist/src/patch/invert.js +284 -0
  244. package/dist/src/patch/invert.js.map +1 -0
  245. package/dist/src/patch/merge.d.ts +56 -0
  246. package/dist/src/patch/merge.d.ts.map +1 -0
  247. package/dist/src/patch/merge.js +586 -0
  248. package/dist/src/patch/merge.js.map +1 -0
  249. package/dist/src/patch/merge.spec.d.ts +2 -0
  250. package/dist/src/patch/merge.spec.d.ts.map +1 -0
  251. package/dist/src/patch/merge.spec.js +1139 -0
  252. package/dist/src/patch/merge.spec.js.map +1 -0
  253. package/dist/src/patch/patch.spec.d.ts +2 -0
  254. package/dist/src/patch/patch.spec.d.ts.map +1 -0
  255. package/dist/src/patch/patch.spec.js +452 -0
  256. package/dist/src/patch/patch.spec.js.map +1 -0
  257. package/dist/src/patch/path.d.ts +115 -0
  258. package/dist/src/patch/path.d.ts.map +1 -0
  259. package/dist/src/patch/path.js +192 -0
  260. package/dist/src/patch/path.js.map +1 -0
  261. package/dist/src/patch/path.spec.d.ts +6 -0
  262. package/dist/src/patch/path.spec.d.ts.map +1 -0
  263. package/dist/src/patch/path.spec.js +322 -0
  264. package/dist/src/patch/path.spec.js.map +1 -0
  265. package/dist/src/patch/prune.d.ts +77 -0
  266. package/dist/src/patch/prune.d.ts.map +1 -0
  267. package/dist/src/patch/prune.js +115 -0
  268. package/dist/src/patch/prune.js.map +1 -0
  269. package/dist/src/patch/prune.spec.d.ts +6 -0
  270. package/dist/src/patch/prune.spec.d.ts.map +1 -0
  271. package/dist/src/patch/prune.spec.js +473 -0
  272. package/dist/src/patch/prune.spec.js.map +1 -0
  273. package/dist/src/patch/type_of_patch.d.ts +25 -0
  274. package/dist/src/patch/type_of_patch.d.ts.map +1 -0
  275. package/dist/src/patch/type_of_patch.js +144 -0
  276. package/dist/src/patch/type_of_patch.js.map +1 -0
  277. package/dist/src/patch/types.d.ts +220 -0
  278. package/dist/src/patch/types.d.ts.map +1 -0
  279. package/dist/src/patch/types.js +62 -0
  280. package/dist/src/patch/types.js.map +1 -0
  281. package/dist/src/patch/validate.d.ts +44 -0
  282. package/dist/src/patch/validate.d.ts.map +1 -0
  283. package/dist/src/patch/validate.js +190 -0
  284. package/dist/src/patch/validate.js.map +1 -0
  285. package/dist/src/patch/validate.spec.d.ts +6 -0
  286. package/dist/src/patch/validate.spec.d.ts.map +1 -0
  287. package/dist/src/patch/validate.spec.js +225 -0
  288. package/dist/src/patch/validate.spec.js.map +1 -0
  289. package/dist/src/patch/walk.d.ts +121 -0
  290. package/dist/src/patch/walk.d.ts.map +1 -0
  291. package/dist/src/patch/walk.js +385 -0
  292. package/dist/src/patch/walk.js.map +1 -0
  293. package/dist/src/patch/walk.spec.d.ts +6 -0
  294. package/dist/src/patch/walk.spec.d.ts.map +1 -0
  295. package/dist/src/patch/walk.spec.js +621 -0
  296. package/dist/src/patch/walk.spec.js.map +1 -0
  297. package/dist/src/platform.d.ts +6 -0
  298. package/dist/src/platform.d.ts.map +1 -1
  299. package/dist/src/platform.spec.d.ts +2 -0
  300. package/dist/src/platform.spec.d.ts.map +1 -0
  301. package/dist/src/platform.spec.js +330 -0
  302. package/dist/src/platform.spec.js.map +1 -0
  303. package/dist/src/serialization/beast.d.ts.map +1 -1
  304. package/dist/src/serialization/beast.js +12 -0
  305. package/dist/src/serialization/beast.js.map +1 -1
  306. package/dist/src/serialization/beast.spec.d.ts +6 -0
  307. package/dist/src/serialization/beast.spec.d.ts.map +1 -0
  308. package/dist/src/serialization/beast.spec.js +406 -0
  309. package/dist/src/serialization/beast.spec.js.map +1 -0
  310. package/dist/src/serialization/beast2/index.d.ts +50 -0
  311. package/dist/src/serialization/beast2/index.d.ts.map +1 -0
  312. package/dist/src/serialization/beast2/index.js +756 -0
  313. package/dist/src/serialization/beast2/index.js.map +1 -0
  314. package/dist/src/serialization/beast2/index.spec.d.ts +6 -0
  315. package/dist/src/serialization/beast2/index.spec.d.ts.map +1 -0
  316. package/dist/src/serialization/beast2/index.spec.js +528 -0
  317. package/dist/src/serialization/beast2/index.spec.js.map +1 -0
  318. package/dist/src/serialization/beast2/sourcemap-table.d.ts +29 -0
  319. package/dist/src/serialization/beast2/sourcemap-table.d.ts.map +1 -0
  320. package/dist/src/serialization/beast2/sourcemap-table.js +82 -0
  321. package/dist/src/serialization/beast2/sourcemap-table.js.map +1 -0
  322. package/dist/src/serialization/beast2/string-table.d.ts +16 -0
  323. package/dist/src/serialization/beast2/string-table.d.ts.map +1 -0
  324. package/dist/src/serialization/beast2/string-table.js +38 -0
  325. package/dist/src/serialization/beast2/string-table.js.map +1 -0
  326. package/dist/src/serialization/beast2/type-table.d.ts +86 -0
  327. package/dist/src/serialization/beast2/type-table.d.ts.map +1 -0
  328. package/dist/src/serialization/beast2/type-table.js +618 -0
  329. package/dist/src/serialization/beast2/type-table.js.map +1 -0
  330. package/dist/src/serialization/beast2/value-table.d.ts +40 -0
  331. package/dist/src/serialization/beast2/value-table.d.ts.map +1 -0
  332. package/dist/src/serialization/beast2/value-table.js +157 -0
  333. package/dist/src/serialization/beast2/value-table.js.map +1 -0
  334. package/dist/src/serialization/binary-utils.d.ts +33 -0
  335. package/dist/src/serialization/binary-utils.d.ts.map +1 -1
  336. package/dist/src/serialization/binary-utils.js +157 -0
  337. package/dist/src/serialization/binary-utils.js.map +1 -1
  338. package/dist/src/serialization/csv.d.ts +17 -17
  339. package/dist/src/serialization/csv.d.ts.map +1 -1
  340. package/dist/src/serialization/csv.js +10 -8
  341. package/dist/src/serialization/csv.js.map +1 -1
  342. package/dist/src/serialization/csv.spec.d.ts +2 -0
  343. package/dist/src/serialization/csv.spec.d.ts.map +1 -0
  344. package/dist/src/serialization/csv.spec.js +556 -0
  345. package/dist/src/serialization/csv.spec.js.map +1 -0
  346. package/dist/src/serialization/east-inferred.spec.d.ts +2 -0
  347. package/dist/src/serialization/east-inferred.spec.d.ts.map +1 -0
  348. package/dist/src/serialization/east-inferred.spec.js +322 -0
  349. package/dist/src/serialization/east-inferred.spec.js.map +1 -0
  350. package/dist/src/serialization/east.d.ts +1 -1
  351. package/dist/src/serialization/east.d.ts.map +1 -1
  352. package/dist/src/serialization/east.js +178 -26
  353. package/dist/src/serialization/east.js.map +1 -1
  354. package/dist/src/serialization/east.spec.d.ts +2 -0
  355. package/dist/src/serialization/east.spec.d.ts.map +1 -0
  356. package/dist/src/serialization/east.spec.js +1548 -0
  357. package/dist/src/serialization/east.spec.js.map +1 -0
  358. package/dist/src/serialization/index.d.ts +1 -2
  359. package/dist/src/serialization/index.d.ts.map +1 -1
  360. package/dist/src/serialization/index.js +1 -2
  361. package/dist/src/serialization/index.js.map +1 -1
  362. package/dist/src/serialization/json.d.ts +1 -1
  363. package/dist/src/serialization/json.d.ts.map +1 -1
  364. package/dist/src/serialization/json.js +123 -24
  365. package/dist/src/serialization/json.js.map +1 -1
  366. package/dist/src/serialization/json.spec.d.ts +2 -0
  367. package/dist/src/serialization/json.spec.d.ts.map +1 -0
  368. package/dist/src/serialization/json.spec.js +1297 -0
  369. package/dist/src/serialization/json.spec.js.map +1 -0
  370. package/dist/src/type_of_type.d.ts +72 -35
  371. package/dist/src/type_of_type.d.ts.map +1 -1
  372. package/dist/src/type_of_type.is_data.spec.d.ts +6 -0
  373. package/dist/src/type_of_type.is_data.spec.d.ts.map +1 -0
  374. package/dist/src/type_of_type.is_data.spec.js +221 -0
  375. package/dist/src/type_of_type.is_data.spec.js.map +1 -0
  376. package/dist/src/type_of_type.js +355 -80
  377. package/dist/src/type_of_type.js.map +1 -1
  378. package/dist/src/type_of_type.to_etv.spec.d.ts +6 -0
  379. package/dist/src/type_of_type.to_etv.spec.d.ts.map +1 -0
  380. package/dist/src/type_of_type.to_etv.spec.js +263 -0
  381. package/dist/src/type_of_type.to_etv.spec.js.map +1 -0
  382. package/dist/src/types.d.ts +82 -12
  383. package/dist/src/types.d.ts.map +1 -1
  384. package/dist/src/types.error.spec.d.ts +2 -0
  385. package/dist/src/types.error.spec.d.ts.map +1 -0
  386. package/dist/src/types.error.spec.js +665 -0
  387. package/dist/src/types.error.spec.js.map +1 -0
  388. package/dist/src/types.js +663 -156
  389. package/dist/src/types.js.map +1 -1
  390. package/dist/src/types.spec.d.ts +2 -0
  391. package/dist/src/types.spec.d.ts.map +1 -0
  392. package/dist/src/types.spec.js +946 -0
  393. package/dist/src/types.spec.js.map +1 -0
  394. package/dist/src/walker.d.ts +65 -0
  395. package/dist/src/walker.d.ts.map +1 -0
  396. package/dist/src/walker.js +165 -0
  397. package/dist/src/walker.js.map +1 -0
  398. package/dist/src/walker.spec.d.ts +6 -0
  399. package/dist/src/walker.spec.d.ts.map +1 -0
  400. package/dist/src/walker.spec.js +109 -0
  401. package/dist/src/walker.spec.js.map +1 -0
  402. package/package.json +16 -38
  403. package/dist/src/serialization/beast2-stream.d.ts +0 -38
  404. package/dist/src/serialization/beast2-stream.d.ts.map +0 -1
  405. package/dist/src/serialization/beast2-stream.js +0 -670
  406. package/dist/src/serialization/beast2-stream.js.map +0 -1
  407. package/dist/src/serialization/beast2.d.ts +0 -41
  408. package/dist/src/serialization/beast2.d.ts.map +0 -1
  409. package/dist/src/serialization/beast2.js +0 -495
  410. package/dist/src/serialization/beast2.js.map +0 -1
@@ -0,0 +1,946 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
4
+ */
5
+ import { describe, test } from "node:test";
6
+ import util from "node:util";
7
+ import assert from "node:assert";
8
+ import { NeverType, NullType, BooleanType, IntegerType, FloatType, StringType, DateTimeType, BlobType, ArrayType, SetType, DictType, StructType, VariantType, FunctionType, AsyncFunctionType, OptionType, SomeType, isDataType, isImmutableType, isTypeEqual, isSubtype, isValueOf, printType, printIdentifier, TypeUnion, TypeIntersect, TypeEqual, EastTypeOf, RecursiveType, } from "./types.js";
9
+ import { variant, some, none } from "./containers/variant.js";
10
+ // Force node test to show full stack traces for easier debugging
11
+ Error.stackTraceLimit = Infinity;
12
+ // Force node to print full objects in console.log output
13
+ util.inspect.defaultOptions.depth = null;
14
+ describe("Type constructors", () => {
15
+ test("ArrayType should create array types", () => {
16
+ const type = ArrayType(IntegerType);
17
+ assert.strictEqual(type.type, "Array");
18
+ assert.strictEqual(type.value, IntegerType);
19
+ });
20
+ test("SetType should create set types", () => {
21
+ const type = SetType(StringType);
22
+ assert.strictEqual(type.type, "Set");
23
+ assert.strictEqual(type.key, StringType);
24
+ });
25
+ test("SetType should throw for mutable key types", () => {
26
+ assert.throws(() => SetType(ArrayType(IntegerType)), /Set key type must be an immutable type/);
27
+ });
28
+ test("DictType should create dict types", () => {
29
+ const type = DictType(StringType, IntegerType);
30
+ assert.strictEqual(type.type, "Dict");
31
+ assert.strictEqual(type.key, StringType);
32
+ assert.strictEqual(type.value, IntegerType);
33
+ });
34
+ test("DictType should throw for mutable key types", () => {
35
+ assert.throws(() => DictType(ArrayType(IntegerType), StringType), /Dict key type must be an immutable type/);
36
+ });
37
+ test("StructType should create struct types", () => {
38
+ const type = StructType({ x: IntegerType, y: FloatType });
39
+ assert.strictEqual(type.type, "Struct");
40
+ assert.strictEqual(type.fields.x, IntegerType);
41
+ assert.strictEqual(type.fields.y, FloatType);
42
+ });
43
+ test("VariantType should create variant types with sorted cases", () => {
44
+ const type = VariantType({ b: IntegerType, a: StringType });
45
+ assert.strictEqual(type.type, "Variant");
46
+ // Cases should be sorted alphabetically
47
+ const keys = Object.keys(type.cases);
48
+ assert.deepStrictEqual(keys, ["a", "b"]);
49
+ });
50
+ test("FunctionType should create function types", () => {
51
+ const type = FunctionType([IntegerType, StringType], BooleanType);
52
+ assert.strictEqual(type.type, "Function");
53
+ assert.deepStrictEqual(type.inputs, [IntegerType, StringType]);
54
+ assert.strictEqual(type.output, BooleanType);
55
+ });
56
+ test("AsyncFunctionType should create async function types", () => {
57
+ const type = AsyncFunctionType([IntegerType, StringType], BooleanType);
58
+ assert.strictEqual(type.type, "AsyncFunction");
59
+ assert.deepStrictEqual(type.inputs, [IntegerType, StringType]);
60
+ assert.strictEqual(type.output, BooleanType);
61
+ });
62
+ test("OptionType should create option types", () => {
63
+ const type = OptionType(IntegerType);
64
+ assert.strictEqual(type.type, "Variant");
65
+ assert.strictEqual(type.cases.none, NullType);
66
+ assert.strictEqual(type.cases.some, IntegerType);
67
+ });
68
+ });
69
+ describe("isDataType", () => {
70
+ test("should return true for primitive data types", () => {
71
+ assert.strictEqual(isDataType(NeverType), true);
72
+ assert.strictEqual(isDataType(NullType), true);
73
+ assert.strictEqual(isDataType(BooleanType), true);
74
+ assert.strictEqual(isDataType(IntegerType), true);
75
+ assert.strictEqual(isDataType(FloatType), true);
76
+ assert.strictEqual(isDataType(StringType), true);
77
+ assert.strictEqual(isDataType(DateTimeType), true);
78
+ assert.strictEqual(isDataType(BlobType), true);
79
+ });
80
+ test("should return true for collection data types", () => {
81
+ assert.strictEqual(isDataType(ArrayType(IntegerType)), true);
82
+ assert.strictEqual(isDataType(SetType(StringType)), true);
83
+ assert.strictEqual(isDataType(DictType(StringType, IntegerType)), true);
84
+ });
85
+ test("should return true for struct with data fields", () => {
86
+ assert.strictEqual(isDataType(StructType({ x: IntegerType, y: FloatType })), true);
87
+ });
88
+ test("should return false for struct with function field", () => {
89
+ assert.strictEqual(isDataType(StructType({ x: IntegerType, f: FunctionType([], NullType) })), false);
90
+ });
91
+ test("should return true for variant with data cases", () => {
92
+ assert.strictEqual(isDataType(VariantType({ none: NullType, some: IntegerType })), true);
93
+ });
94
+ test("should return false for variant with function case", () => {
95
+ assert.strictEqual(isDataType(VariantType({ data: IntegerType, func: FunctionType([], NullType) })), false);
96
+ });
97
+ test("should return false for function types", () => {
98
+ assert.strictEqual(isDataType(FunctionType([], NullType)), false);
99
+ });
100
+ test("should return false for async function types", () => {
101
+ assert.strictEqual(isDataType(AsyncFunctionType([], NullType)), false);
102
+ });
103
+ });
104
+ describe("isImmutableType", () => {
105
+ test("should return true for primitive immutable types", () => {
106
+ assert.strictEqual(isImmutableType(NeverType), true);
107
+ assert.strictEqual(isImmutableType(NullType), true);
108
+ assert.strictEqual(isImmutableType(BooleanType), true);
109
+ assert.strictEqual(isImmutableType(IntegerType), true);
110
+ assert.strictEqual(isImmutableType(FloatType), true);
111
+ assert.strictEqual(isImmutableType(StringType), true);
112
+ assert.strictEqual(isImmutableType(DateTimeType), true);
113
+ assert.strictEqual(isImmutableType(BlobType), true);
114
+ });
115
+ test("should return false for mutable collection types", () => {
116
+ assert.strictEqual(isImmutableType(ArrayType(IntegerType)), false);
117
+ assert.strictEqual(isImmutableType(SetType(StringType)), false);
118
+ assert.strictEqual(isImmutableType(DictType(StringType, IntegerType)), false);
119
+ });
120
+ test("should return true for struct with immutable fields", () => {
121
+ assert.strictEqual(isImmutableType(StructType({ x: IntegerType, y: StringType })), true);
122
+ });
123
+ test("should return false for struct with mutable field", () => {
124
+ assert.strictEqual(isImmutableType(StructType({ x: IntegerType, arr: ArrayType(IntegerType) })), false);
125
+ });
126
+ test("should return true for variant with immutable cases", () => {
127
+ assert.strictEqual(isImmutableType(VariantType({ none: NullType, some: IntegerType })), true);
128
+ });
129
+ test("should return false for variant with mutable case", () => {
130
+ assert.strictEqual(isImmutableType(VariantType({ data: IntegerType, list: ArrayType(IntegerType) })), false);
131
+ });
132
+ test("should return false for function types", () => {
133
+ assert.strictEqual(isImmutableType(FunctionType([], NullType)), false);
134
+ });
135
+ test("should return false for async function types", () => {
136
+ assert.strictEqual(isImmutableType(AsyncFunctionType([], NullType)), false);
137
+ });
138
+ });
139
+ describe("isValueOf", () => {
140
+ test("should validate primitive values", () => {
141
+ assert.strictEqual(isValueOf(null, NullType), true);
142
+ assert.strictEqual(isValueOf(true, BooleanType), true);
143
+ assert.strictEqual(isValueOf(false, BooleanType), true);
144
+ assert.strictEqual(isValueOf(42n, IntegerType), true);
145
+ assert.strictEqual(isValueOf(3.14, FloatType), true);
146
+ assert.strictEqual(isValueOf("hello", StringType), true);
147
+ assert.strictEqual(isValueOf(new Date(), DateTimeType), true);
148
+ assert.strictEqual(isValueOf(new Uint8Array([1, 2, 3]), BlobType), true);
149
+ });
150
+ test("should reject wrong primitive values", () => {
151
+ assert.strictEqual(isValueOf(42, IntegerType), false); // number not bigint
152
+ assert.strictEqual(isValueOf(42n, FloatType), false); // bigint not number
153
+ assert.strictEqual(isValueOf("hello", IntegerType), false);
154
+ });
155
+ test("should return false for Never type", () => {
156
+ assert.strictEqual(isValueOf(null, NeverType), false);
157
+ assert.strictEqual(isValueOf(42, NeverType), false);
158
+ });
159
+ test("should validate array values", () => {
160
+ assert.strictEqual(isValueOf([1n, 2n, 3n], ArrayType(IntegerType)), true);
161
+ assert.strictEqual(isValueOf([], ArrayType(IntegerType)), true);
162
+ assert.strictEqual(isValueOf([1, 2, 3], ArrayType(IntegerType)), false); // numbers not bigints
163
+ assert.strictEqual(isValueOf("not array", ArrayType(IntegerType)), false);
164
+ });
165
+ test("should validate set values", () => {
166
+ assert.strictEqual(isValueOf(new Set(["a", "b"]), SetType(StringType)), true);
167
+ assert.strictEqual(isValueOf(new Set([1, 2]), SetType(StringType)), false); // numbers not strings
168
+ });
169
+ test("should validate dict values", () => {
170
+ assert.strictEqual(isValueOf(new Map([["a", 1n]]), DictType(StringType, IntegerType)), true);
171
+ assert.strictEqual(isValueOf(new Map([[1, "a"]]), DictType(StringType, IntegerType)), false); // wrong key type
172
+ });
173
+ test("should validate struct values", () => {
174
+ const type = StructType({ x: IntegerType, y: StringType });
175
+ assert.strictEqual(isValueOf({ x: 42n, y: "hello" }, type), true);
176
+ assert.strictEqual(isValueOf({ x: 42, y: "hello" }, type), false); // wrong field type
177
+ assert.strictEqual(isValueOf({ x: 42n }, type), false); // missing field
178
+ });
179
+ test("should validate variant values", () => {
180
+ const type = VariantType({ none: NullType, some: IntegerType });
181
+ assert.strictEqual(isValueOf(none, type), true);
182
+ assert.strictEqual(isValueOf(some(42n), type), true);
183
+ assert.strictEqual(isValueOf(variant("other", null), type), false); // wrong tag
184
+ });
185
+ test("should throw for Function type", () => {
186
+ assert.throws(() => isValueOf(() => { }, FunctionType([], NullType)), /Javascript functions cannot be converted to East functions/);
187
+ });
188
+ test("should throw for AsyncFunction type", () => {
189
+ assert.throws(() => isValueOf(() => { }, AsyncFunctionType([], NullType)), /Javascript functions cannot be converted to East async functions/);
190
+ });
191
+ });
192
+ describe("isTypeEqual", () => {
193
+ test("should compare primitive types", () => {
194
+ assert.strictEqual(isTypeEqual(NullType, NullType), true);
195
+ assert.strictEqual(isTypeEqual(IntegerType, IntegerType), true);
196
+ assert.strictEqual(isTypeEqual(IntegerType, FloatType), false);
197
+ });
198
+ test("should compare array types", () => {
199
+ assert.strictEqual(isTypeEqual(ArrayType(IntegerType), ArrayType(IntegerType)), true);
200
+ assert.strictEqual(isTypeEqual(ArrayType(IntegerType), ArrayType(FloatType)), false);
201
+ assert.strictEqual(isTypeEqual(ArrayType(IntegerType), IntegerType), false);
202
+ });
203
+ test("should compare set types", () => {
204
+ assert.strictEqual(isTypeEqual(SetType(StringType), SetType(StringType)), true);
205
+ assert.strictEqual(isTypeEqual(SetType(StringType), SetType(IntegerType)), false);
206
+ });
207
+ test("should compare dict types", () => {
208
+ assert.strictEqual(isTypeEqual(DictType(StringType, IntegerType), DictType(StringType, IntegerType)), true);
209
+ assert.strictEqual(isTypeEqual(DictType(StringType, IntegerType), DictType(IntegerType, StringType)), false);
210
+ });
211
+ test("should compare struct types", () => {
212
+ const t1 = StructType({ x: IntegerType, y: FloatType });
213
+ const t2 = StructType({ x: IntegerType, y: FloatType });
214
+ const t3 = StructType({ x: IntegerType, y: StringType });
215
+ assert.strictEqual(isTypeEqual(t1, t2), true);
216
+ assert.strictEqual(isTypeEqual(t1, t3), false);
217
+ });
218
+ test("should compare variant types", () => {
219
+ const t1 = VariantType({ none: NullType, some: IntegerType });
220
+ const t2 = VariantType({ none: NullType, some: IntegerType });
221
+ const t3 = VariantType({ none: NullType, some: FloatType });
222
+ assert.strictEqual(isTypeEqual(t1, t2), true);
223
+ assert.strictEqual(isTypeEqual(t1, t3), false);
224
+ });
225
+ test("should compare function types", () => {
226
+ const t1 = FunctionType([IntegerType], StringType);
227
+ const t2 = FunctionType([IntegerType], StringType);
228
+ const t3 = FunctionType([FloatType], StringType);
229
+ assert.strictEqual(isTypeEqual(t1, t2), true);
230
+ assert.strictEqual(isTypeEqual(t1, t3), false);
231
+ });
232
+ test("should compare async function types", () => {
233
+ const t1 = AsyncFunctionType([IntegerType], StringType);
234
+ const t2 = AsyncFunctionType([IntegerType], StringType);
235
+ const t3 = AsyncFunctionType([FloatType], StringType);
236
+ assert.strictEqual(isTypeEqual(t1, t2), true);
237
+ assert.strictEqual(isTypeEqual(t1, t3), false);
238
+ });
239
+ test("should distinguish sync and async function types", () => {
240
+ const syncFn = FunctionType([IntegerType], StringType);
241
+ const asyncFn = AsyncFunctionType([IntegerType], StringType);
242
+ assert.strictEqual(isTypeEqual(syncFn, asyncFn), false);
243
+ assert.strictEqual(isTypeEqual(asyncFn, syncFn), false);
244
+ });
245
+ });
246
+ describe("isSubtype", () => {
247
+ test("Never is subtype of everything", () => {
248
+ assert.strictEqual(isSubtype(NeverType, NullType), true);
249
+ assert.strictEqual(isSubtype(NeverType, IntegerType), true);
250
+ assert.strictEqual(isSubtype(NeverType, FunctionType([], NullType)), true);
251
+ });
252
+ test("primitive types are only subtypes of themselves", () => {
253
+ assert.strictEqual(isSubtype(IntegerType, IntegerType), true);
254
+ assert.strictEqual(isSubtype(IntegerType, FloatType), false);
255
+ });
256
+ test("variant subtyping - fewer cases is subtype", () => {
257
+ const t1 = VariantType({ a: IntegerType, b: StringType, c: FloatType });
258
+ const t2 = VariantType({ a: IntegerType, b: StringType });
259
+ assert.strictEqual(isSubtype(t1, t2), false);
260
+ assert.strictEqual(isSubtype(t2, t1), true);
261
+ });
262
+ test("struct subtyping is structural", () => {
263
+ const t1 = StructType({ x: IntegerType, y: FloatType });
264
+ const t2 = StructType({ x: IntegerType, y: FloatType });
265
+ assert.strictEqual(isSubtype(t1, t2), true);
266
+ });
267
+ test("function subtyping - contravariant inputs, covariant output", () => {
268
+ const t1 = FunctionType([IntegerType], NeverType);
269
+ const t2 = FunctionType([IntegerType], IntegerType);
270
+ // t1 has output Never which is subtype of Integer, so t1 <: t2
271
+ assert.strictEqual(isSubtype(t1, t2), true);
272
+ });
273
+ test("sync function is subtype of async function", () => {
274
+ const syncFn = FunctionType([IntegerType], StringType);
275
+ const asyncFn = AsyncFunctionType([IntegerType], StringType);
276
+ // sync <: async - a sync function can be used where async is expected
277
+ assert.strictEqual(isSubtype(syncFn, asyncFn), true);
278
+ });
279
+ test("async function is NOT subtype of sync function", () => {
280
+ const syncFn = FunctionType([IntegerType], StringType);
281
+ const asyncFn = AsyncFunctionType([IntegerType], StringType);
282
+ // async is NOT subtype of sync - async cannot be used where sync is required
283
+ assert.strictEqual(isSubtype(asyncFn, syncFn), false);
284
+ });
285
+ test("Never is subtype of async function", () => {
286
+ assert.strictEqual(isSubtype(NeverType, AsyncFunctionType([], NullType)), true);
287
+ });
288
+ test("async function subtyping respects contravariance and covariance", () => {
289
+ // Contravariant inputs: wider input -> subtype
290
+ const t1 = AsyncFunctionType([NeverType], IntegerType);
291
+ const t2 = AsyncFunctionType([IntegerType], IntegerType);
292
+ // t1 accepts Never (nothing), t2 accepts Integer
293
+ // For contravariance: t2's input (Integer) is supertype of t1's input (Never)
294
+ // So t1 is NOT a subtype of t2 (t1 is more restrictive on inputs)
295
+ assert.strictEqual(isSubtype(t1, t2), false);
296
+ // Covariant output: narrower output -> subtype
297
+ const t3 = AsyncFunctionType([IntegerType], NeverType);
298
+ const t4 = AsyncFunctionType([IntegerType], IntegerType);
299
+ // t3 outputs Never, t4 outputs Integer
300
+ // Never <: Integer, so t3 <: t4
301
+ assert.strictEqual(isSubtype(t3, t4), true);
302
+ });
303
+ test("sync function subtyping combined with async - sync with narrower output is subtype of async", () => {
304
+ const syncFn = FunctionType([IntegerType], NeverType);
305
+ const asyncFn = AsyncFunctionType([IntegerType], IntegerType);
306
+ // sync <: async AND Never <: Integer for output
307
+ assert.strictEqual(isSubtype(syncFn, asyncFn), true);
308
+ });
309
+ test("async function types with different signatures are not subtypes", () => {
310
+ const t1 = AsyncFunctionType([IntegerType], StringType);
311
+ const t2 = AsyncFunctionType([StringType], StringType);
312
+ assert.strictEqual(isSubtype(t1, t2), false);
313
+ assert.strictEqual(isSubtype(t2, t1), false);
314
+ });
315
+ });
316
+ describe("printType", () => {
317
+ test("should print primitive types", () => {
318
+ assert.strictEqual(printType(NeverType), ".Never");
319
+ assert.strictEqual(printType(NullType), ".Null");
320
+ assert.strictEqual(printType(BooleanType), ".Boolean");
321
+ assert.strictEqual(printType(IntegerType), ".Integer");
322
+ assert.strictEqual(printType(FloatType), ".Float");
323
+ assert.strictEqual(printType(StringType), ".String");
324
+ assert.strictEqual(printType(DateTimeType), ".DateTime");
325
+ assert.strictEqual(printType(BlobType), ".Blob");
326
+ });
327
+ test("should print collection types", () => {
328
+ assert.strictEqual(printType(ArrayType(IntegerType)), ".Array .Integer");
329
+ assert.strictEqual(printType(SetType(StringType)), ".Set .String");
330
+ assert.strictEqual(printType(DictType(StringType, IntegerType)), ".Dict (key=.String, value=.Integer)");
331
+ });
332
+ test("should print struct types", () => {
333
+ assert.strictEqual(printType(StructType({ x: IntegerType })), `.Struct [(name="x", type=.Integer)]`);
334
+ assert.strictEqual(printType(StructType({ x: IntegerType, y: FloatType })), `.Struct [(name="x", type=.Integer), (name="y", type=.Float)]`);
335
+ });
336
+ test("should print variant types", () => {
337
+ assert.strictEqual(printType(VariantType({ none: NullType })), `.Variant [(name="none", type=.Null)]`);
338
+ assert.strictEqual(printType(VariantType({ none: NullType, some: IntegerType })), `.Variant [(name="none", type=.Null), (name="some", type=.Integer)]`);
339
+ });
340
+ test("should print function types", () => {
341
+ assert.strictEqual(printType(FunctionType([], NullType)), ".Function (inputs=[], output=.Null)");
342
+ assert.strictEqual(printType(FunctionType([IntegerType, StringType], BooleanType)), ".Function (inputs=[.Integer, .String], output=.Boolean)");
343
+ });
344
+ test("should print async function types", () => {
345
+ assert.strictEqual(printType(AsyncFunctionType([], NullType)), ".AsyncFunction (inputs=[], output=.Null)");
346
+ assert.strictEqual(printType(AsyncFunctionType([IntegerType, StringType], BooleanType)), ".AsyncFunction (inputs=[.Integer, .String], output=.Boolean)");
347
+ });
348
+ });
349
+ describe("printIdentifier", () => {
350
+ test("should print valid identifiers as-is", () => {
351
+ assert.strictEqual(printIdentifier("foo"), "foo");
352
+ assert.strictEqual(printIdentifier("_bar"), "_bar");
353
+ assert.strictEqual(printIdentifier("foo123"), "foo123");
354
+ });
355
+ test("should escape invalid identifiers", () => {
356
+ assert.strictEqual(printIdentifier("foo bar"), "`foo bar`");
357
+ assert.strictEqual(printIdentifier("123"), "`123`");
358
+ assert.strictEqual(printIdentifier("foo-bar"), "`foo-bar`");
359
+ });
360
+ test("should escape special characters in identifiers", () => {
361
+ assert.strictEqual(printIdentifier("foo`bar"), "`foo\\`bar`");
362
+ assert.strictEqual(printIdentifier("foo\\bar"), "`foo\\\\bar`");
363
+ });
364
+ });
365
+ describe("TypeUnion", () => {
366
+ test("Never is identity for union", () => {
367
+ assert.deepStrictEqual(TypeUnion(NeverType, IntegerType), IntegerType);
368
+ assert.deepStrictEqual(TypeUnion(IntegerType, NeverType), IntegerType);
369
+ });
370
+ test("should union same primitive types", () => {
371
+ assert.deepStrictEqual(TypeUnion(IntegerType, IntegerType), IntegerType);
372
+ });
373
+ test("should throw for different primitive types", () => {
374
+ assert.throws(() => TypeUnion(IntegerType, FloatType), /expected \.Integer but got \.Float: incompatible types/);
375
+ });
376
+ test("should union array types with same element type", () => {
377
+ const result = TypeUnion(ArrayType(IntegerType), ArrayType(IntegerType));
378
+ assert.strictEqual(result.type, "Array");
379
+ });
380
+ test("should throw for array types with different element types", () => {
381
+ assert.throws(() => TypeUnion(ArrayType(IntegerType), ArrayType(FloatType)), /expected \.Integer but got \.Float: incompatible types/);
382
+ });
383
+ test("should union variant types", () => {
384
+ const t1 = VariantType({ a: IntegerType, b: StringType });
385
+ const t2 = VariantType({ b: StringType, c: FloatType });
386
+ const result = TypeUnion(t1, t2);
387
+ assert.strictEqual(result.type, "Variant");
388
+ // Should have all cases: a, b (unioned), c
389
+ assert.ok(result.cases.a);
390
+ assert.ok(result.cases.b);
391
+ assert.ok(result.cases.c);
392
+ });
393
+ test("should union struct types", () => {
394
+ const t1 = StructType({ x: IntegerType, y: FloatType });
395
+ const t2 = StructType({ x: IntegerType, y: FloatType });
396
+ const result = TypeUnion(t1, t2);
397
+ assert.strictEqual(result.type, "Struct");
398
+ });
399
+ test("should throw for structs with different field count", () => {
400
+ const t1 = StructType({ x: IntegerType });
401
+ const t2 = StructType({ x: IntegerType, y: FloatType });
402
+ // t1 has 1 field, t2 has 2 fields
403
+ assert.throws(() => TypeUnion(t1, t2), /TypeMismatchError.*structs contain different number of fields/);
404
+ });
405
+ test("should throw for structs with different field names at position 0", () => {
406
+ const t1 = StructType({ x: IntegerType });
407
+ const t2 = StructType({ y: IntegerType });
408
+ // Field at position 0: 'x' vs 'y'
409
+ assert.throws(() => TypeUnion(t1, t2), /TypeMismatchError.*struct field 0 has mismatched names x and y/);
410
+ });
411
+ test("should throw for structs with mismatched field names in multi-field structs", () => {
412
+ const t1 = StructType({ a: IntegerType, b: StringType, c: FloatType });
413
+ const t2 = StructType({ a: IntegerType, x: StringType, c: FloatType });
414
+ // Field at position 1: 'b' vs 'x'
415
+ assert.throws(() => TypeUnion(t1, t2), /TypeMismatchError.*struct field 1 has mismatched names b and x/);
416
+ });
417
+ test("should union function types", () => {
418
+ const t1 = FunctionType([IntegerType], IntegerType);
419
+ const t2 = FunctionType([IntegerType], FloatType);
420
+ assert.throws(() => TypeUnion(t1, t2), /TypeMismatchError.*expected \.Integer but got \.Float: incompatible types/);
421
+ });
422
+ test("should union sync and async function types - result is async", () => {
423
+ const syncFn = FunctionType([IntegerType], StringType);
424
+ const asyncFn = AsyncFunctionType([IntegerType], StringType);
425
+ const result = TypeUnion(syncFn, asyncFn);
426
+ assert.strictEqual(result.type, "AsyncFunction");
427
+ });
428
+ test("should union two sync function types - result is sync", () => {
429
+ const t1 = FunctionType([IntegerType], StringType);
430
+ const t2 = FunctionType([IntegerType], StringType);
431
+ const result = TypeUnion(t1, t2);
432
+ assert.strictEqual(result.type, "Function");
433
+ });
434
+ test("should union two async function types - result is async", () => {
435
+ const t1 = AsyncFunctionType([IntegerType], StringType);
436
+ const t2 = AsyncFunctionType([IntegerType], StringType);
437
+ const result = TypeUnion(t1, t2);
438
+ assert.strictEqual(result.type, "AsyncFunction");
439
+ });
440
+ test("should union identical struct types containing RecursiveType fields", () => {
441
+ const RecType = RecursiveType(self => VariantType({ leaf: NullType, node: StructType({ child: self }) }));
442
+ const T = StructType({ label: StringType, value: RecType });
443
+ // This should not throw — both args are the same object
444
+ const result = TypeUnion(T, T);
445
+ assert.strictEqual(result.type, "Struct");
446
+ });
447
+ test("should union identical RecursiveType values", () => {
448
+ const RecType = RecursiveType(self => VariantType({ leaf: NullType, node: StructType({ child: self }) }));
449
+ const result = TypeUnion(RecType, RecType);
450
+ assert.strictEqual(result.type, "Recursive");
451
+ });
452
+ test("should union 3+ structurally-equal structs with shared RecursiveType (pairwise fold)", () => {
453
+ // Reproduces the real bug: East.value([item1, item2, item3]) folds TypeUnion
454
+ // pairwise. The first union creates a NEW RecursiveType wrapper. The second
455
+ // union then compares the new wrapper against the original — cycle detection
456
+ // in TypeEqual fails because the new wrapper has different identity.
457
+ const RecType = RecursiveType(self => VariantType({ leaf: NullType, node: StructType({ child: self }) }));
458
+ const S1 = StructType({ label: StringType, value: RecType });
459
+ const S2 = StructType({ label: StringType, value: RecType });
460
+ const S3 = StructType({ label: StringType, value: RecType });
461
+ // First union succeeds but returns a new struct with a new RecursiveType inside
462
+ const u1 = TypeUnion(S1, S2);
463
+ // Second union fails: TypeEqual(NEW_RecType, ORIGINAL_RecType) breaks cycle detection
464
+ const u2 = TypeUnion(u1, S3);
465
+ assert.strictEqual(u2.type, "Struct");
466
+ });
467
+ });
468
+ describe("TypeIntersect", () => {
469
+ test("Never is absorbing for intersection", () => {
470
+ assert.deepStrictEqual(TypeIntersect(NeverType, IntegerType), NeverType);
471
+ assert.deepStrictEqual(TypeIntersect(IntegerType, NeverType), NeverType);
472
+ });
473
+ test("should intersect same primitive types", () => {
474
+ assert.deepStrictEqual(TypeIntersect(IntegerType, IntegerType), IntegerType);
475
+ });
476
+ test("should throw for different primitive types", () => {
477
+ assert.throws(() => TypeIntersect(IntegerType, FloatType), /expected \.Integer but got \.Float: incompatible types/);
478
+ });
479
+ test("should intersect variant types", () => {
480
+ const t1 = VariantType({ a: IntegerType, b: StringType, c: FloatType });
481
+ const t2 = VariantType({ b: StringType, c: FloatType, d: BooleanType });
482
+ const result = TypeIntersect(t1, t2);
483
+ assert.strictEqual(result.type, "Variant");
484
+ // TypeIntersect for variants keeps cases in t1 that are also in t2
485
+ assert.deepStrictEqual(result.cases, { b: StringType, c: FloatType });
486
+ });
487
+ test("should throw for variants with no overlapping cases", () => {
488
+ const t1 = VariantType({ a: IntegerType });
489
+ const t2 = VariantType({ b: StringType });
490
+ // Returns t1's cases that are not in t2 (i.e., all of t1's cases)
491
+ assert.throws(() => TypeIntersect(t1, t2));
492
+ });
493
+ test("should intersect sync and async function types - result is sync", () => {
494
+ const syncFn = FunctionType([IntegerType], StringType);
495
+ const asyncFn = AsyncFunctionType([IntegerType], StringType);
496
+ const result = TypeIntersect(syncFn, asyncFn);
497
+ // Intersection: both must be async for result to be async
498
+ // sync ∩ async = sync (the more restrictive type)
499
+ assert.strictEqual(result.type, "Function");
500
+ });
501
+ test("should intersect two sync function types - result is sync", () => {
502
+ const t1 = FunctionType([IntegerType], StringType);
503
+ const t2 = FunctionType([IntegerType], StringType);
504
+ const result = TypeIntersect(t1, t2);
505
+ assert.strictEqual(result.type, "Function");
506
+ });
507
+ test("should intersect two async function types - result is async", () => {
508
+ const t1 = AsyncFunctionType([IntegerType], StringType);
509
+ const t2 = AsyncFunctionType([IntegerType], StringType);
510
+ const result = TypeIntersect(t1, t2);
511
+ assert.strictEqual(result.type, "AsyncFunction");
512
+ });
513
+ test("should intersect identical RecursiveType values", () => {
514
+ const RecType = RecursiveType(self => VariantType({ leaf: NullType, node: StructType({ child: self }) }));
515
+ const result = TypeIntersect(RecType, RecType);
516
+ assert.strictEqual(result.type, "Recursive");
517
+ });
518
+ test("should intersect pairwise-equal structs with shared RecursiveType after prior intersect", () => {
519
+ const RecType = RecursiveType(self => VariantType({ leaf: NullType, node: StructType({ child: self }) }));
520
+ const S1 = StructType({ label: StringType, value: RecType });
521
+ const S2 = StructType({ label: StringType, value: RecType });
522
+ const S3 = StructType({ label: StringType, value: RecType });
523
+ const i1 = TypeIntersect(S1, S2);
524
+ const i2 = TypeIntersect(i1, S3);
525
+ assert.strictEqual(i2.type, "Struct");
526
+ });
527
+ });
528
+ describe("TypeEqual", () => {
529
+ test("should accept equal primitive types", () => {
530
+ assert.deepStrictEqual(TypeEqual(IntegerType, IntegerType), IntegerType);
531
+ });
532
+ test("should throw for unequal primitive types", () => {
533
+ assert.throws(() => TypeEqual(IntegerType, FloatType), /expected \.Integer but got \.Float: incompatible types/);
534
+ });
535
+ test("should accept equal array types", () => {
536
+ const result = TypeEqual(ArrayType(IntegerType), ArrayType(IntegerType));
537
+ assert.strictEqual(result.type, "Array");
538
+ });
539
+ test("should throw for unequal variant case names", () => {
540
+ const t1 = VariantType({ a: IntegerType, c: StringType });
541
+ const t2 = VariantType({ a: IntegerType, b: StringType });
542
+ assert.throws(() => TypeEqual(t1, t2), /variant case .* is not present in both variants/);
543
+ });
544
+ test("should throw for variants with different case count", () => {
545
+ const t1 = VariantType({ a: IntegerType });
546
+ const t2 = VariantType({ a: IntegerType, b: StringType });
547
+ assert.throws(() => TypeEqual(t1, t2), /variants contain different number of cases/);
548
+ });
549
+ test("should throw for functions with different argument count", () => {
550
+ const t1 = FunctionType([IntegerType], NullType);
551
+ const t2 = FunctionType([IntegerType, StringType], NullType);
552
+ assert.throws(() => TypeEqual(t1, t2), /functions take different number of arguments/);
553
+ });
554
+ test("should throw for sync vs async function types", () => {
555
+ const syncFn = FunctionType([IntegerType], StringType);
556
+ const asyncFn = AsyncFunctionType([IntegerType], StringType);
557
+ assert.throws(() => TypeEqual(syncFn, asyncFn), /expected.*\.Function.*but got.*\.AsyncFunction.*incompatible types/);
558
+ });
559
+ test("should accept equal async function types", () => {
560
+ const t1 = AsyncFunctionType([IntegerType, StringType], FloatType);
561
+ const t2 = AsyncFunctionType([IntegerType, StringType], FloatType);
562
+ const result = TypeEqual(t1, t2);
563
+ assert.strictEqual(result.type, "AsyncFunction");
564
+ });
565
+ test("should accept identical RecursiveType values", () => {
566
+ const RecType = RecursiveType(self => VariantType({ leaf: NullType, node: StructType({ child: self }) }));
567
+ const result = TypeEqual(RecType, RecType);
568
+ assert.strictEqual(result.type, "Recursive");
569
+ });
570
+ test("should accept pairwise-equal structs with shared RecursiveType after prior TypeEqual", () => {
571
+ // TypeEqual(S1, S2) creates a new RecursiveType wrapper inside the result struct.
572
+ // TypeEqual(result, S3) then compares new wrapper vs original — cycle detection breaks.
573
+ const RecType = RecursiveType(self => VariantType({ leaf: NullType, node: StructType({ child: self }) }));
574
+ const S1 = StructType({ label: StringType, value: RecType });
575
+ const S2 = StructType({ label: StringType, value: RecType });
576
+ const S3 = StructType({ label: StringType, value: RecType });
577
+ const eq1 = TypeEqual(S1, S2);
578
+ const eq2 = TypeEqual(eq1, S3);
579
+ assert.strictEqual(eq2.type, "Struct");
580
+ });
581
+ });
582
+ describe("EastTypeOf", () => {
583
+ test("should infer primitive types", () => {
584
+ assert.deepStrictEqual(EastTypeOf(null), NullType);
585
+ assert.deepStrictEqual(EastTypeOf(true), BooleanType);
586
+ assert.deepStrictEqual(EastTypeOf(42n), IntegerType);
587
+ assert.deepStrictEqual(EastTypeOf(3.14), FloatType);
588
+ assert.deepStrictEqual(EastTypeOf("hello"), StringType);
589
+ });
590
+ test("should infer Date type", () => {
591
+ assert.deepStrictEqual(EastTypeOf(new Date()), DateTimeType);
592
+ });
593
+ test("should infer Blob type", () => {
594
+ assert.deepStrictEqual(EastTypeOf(new Uint8Array([1, 2, 3])), BlobType);
595
+ });
596
+ test("should infer array types", () => {
597
+ const type = EastTypeOf([1n, 2n, 3n]);
598
+ assert.strictEqual(type.type, "Array");
599
+ assert.deepStrictEqual(type.value, IntegerType);
600
+ });
601
+ test("should infer struct types", () => {
602
+ const type = EastTypeOf({ x: 42n, y: "hello" });
603
+ assert.strictEqual(type.type, "Struct");
604
+ assert.deepStrictEqual(type.fields.x, IntegerType);
605
+ assert.deepStrictEqual(type.fields.y, StringType);
606
+ });
607
+ test("should throw for functions", () => {
608
+ assert.throws(() => EastTypeOf(() => { }), /Javascript functions cannot be converted to East functions/);
609
+ });
610
+ test("should throw for unknown values", () => {
611
+ // Symbol causes a TypeError when converted to string in the error message
612
+ assert.throws(() => EastTypeOf(Symbol("test")), /TypeError.*Cannot convert a Symbol value to a string/);
613
+ });
614
+ });
615
+ describe("AsyncFunctionType", () => {
616
+ test("sync function in struct field can widen to async", () => {
617
+ // A struct containing a sync callback
618
+ const syncStruct = StructType({ callback: FunctionType([IntegerType], StringType) });
619
+ // A struct expecting an async callback
620
+ const asyncStruct = StructType({ callback: AsyncFunctionType([IntegerType], StringType) });
621
+ // sync struct should be subtype of async struct (covariant in struct fields)
622
+ assert.strictEqual(isSubtype(syncStruct, asyncStruct), true);
623
+ });
624
+ test("async function in struct field cannot narrow to sync", () => {
625
+ const asyncStruct = StructType({ callback: AsyncFunctionType([IntegerType], StringType) });
626
+ const syncStruct = StructType({ callback: FunctionType([IntegerType], StringType) });
627
+ // async struct is NOT subtype of sync struct
628
+ assert.strictEqual(isSubtype(asyncStruct, syncStruct), false);
629
+ });
630
+ test("higher-order function: accepting async callback is supertype of accepting sync callback", () => {
631
+ // Function that takes a sync callback
632
+ const takesSyncCallback = FunctionType([FunctionType([IntegerType], StringType)], NullType);
633
+ // Function that takes an async callback
634
+ const takesAsyncCallback = FunctionType([AsyncFunctionType([IntegerType], StringType)], NullType);
635
+ // Due to contravariance: if you accept async (supertype), you're a subtype
636
+ // takesSyncCallback accepts narrower input, so it's NOT a subtype of takesAsyncCallback
637
+ assert.strictEqual(isSubtype(takesSyncCallback, takesAsyncCallback), false);
638
+ // takesAsyncCallback accepts wider input, so it IS a subtype of takesSyncCallback
639
+ assert.strictEqual(isSubtype(takesAsyncCallback, takesSyncCallback), true);
640
+ });
641
+ test("TypeUnion of functions returning sync vs async callbacks", () => {
642
+ // Function returning a sync callback
643
+ const returnsSync = FunctionType([], FunctionType([IntegerType], StringType));
644
+ // Function returning an async callback
645
+ const returnsAsync = FunctionType([], AsyncFunctionType([IntegerType], StringType));
646
+ // Union should have async callback output (covariant: sync ∪ async = async)
647
+ const result = TypeUnion(returnsSync, returnsAsync);
648
+ assert.strictEqual(result.type, "Function");
649
+ assert.strictEqual(result.output.type, "AsyncFunction");
650
+ });
651
+ test("TypeIntersect of functions accepting sync vs async callbacks", () => {
652
+ // Function that takes a sync callback
653
+ const takesSyncCallback = AsyncFunctionType([FunctionType([IntegerType], StringType)], NullType);
654
+ // Function that takes an async callback
655
+ const takesAsyncCallback = AsyncFunctionType([AsyncFunctionType([IntegerType], StringType)], NullType);
656
+ // Intersection of inputs (contravariant): sync ∪ async = async for what can be passed
657
+ // But TypeIntersect operates on the function types themselves
658
+ const result = TypeIntersect(takesSyncCallback, takesAsyncCallback);
659
+ assert.strictEqual(result.type, "AsyncFunction");
660
+ // Input intersection: sync ∩ async = sync (the more restrictive)
661
+ assert.strictEqual(result.inputs[0].type, "AsyncFunction");
662
+ });
663
+ });
664
+ describe("Additional coverage tests", () => {
665
+ test("TypeEqual should handle k1 > k2 variant case mismatch", () => {
666
+ const t1 = VariantType({ a: IntegerType, c: StringType });
667
+ const t2 = VariantType({ a: IntegerType, b: StringType });
668
+ assert.throws(() => TypeEqual(t1, t2), /TypeMismatchError.*variant case b is not present in both variants/);
669
+ });
670
+ test("TypeEqual should succeed for equal variant types", () => {
671
+ const t1 = VariantType({ a: IntegerType, b: StringType });
672
+ const t2 = VariantType({ a: IntegerType, b: StringType });
673
+ const result = TypeEqual(t1, t2);
674
+ assert.strictEqual(result.type, "Variant");
675
+ });
676
+ test("TypeEqual should succeed for equal function types", () => {
677
+ const t1 = FunctionType([IntegerType, StringType], FloatType);
678
+ const t2 = FunctionType([IntegerType, StringType], FloatType);
679
+ const result = TypeEqual(t1, t2);
680
+ assert.strictEqual(result.type, "Function");
681
+ });
682
+ test("TypeEqual should propagate errors from nested types", () => {
683
+ const t1 = ArrayType(IntegerType);
684
+ const t2 = ArrayType(FloatType);
685
+ assert.throws(() => TypeEqual(t1, t2), /TypeMismatchError/);
686
+ });
687
+ test("SomeType should create option variant with some case", () => {
688
+ const type = SomeType(IntegerType);
689
+ assert.strictEqual(type.type, "Variant");
690
+ assert.deepStrictEqual(type.cases.some, IntegerType);
691
+ });
692
+ test("OptionType should create variant with none and some cases", () => {
693
+ const type = OptionType(IntegerType);
694
+ assert.strictEqual(type.type, "Variant");
695
+ assert.deepStrictEqual(type.cases.none, NullType);
696
+ assert.deepStrictEqual(type.cases.some, IntegerType);
697
+ });
698
+ test("TypeEqual should handle variant case where k1 < k2", () => {
699
+ const t1 = VariantType({ a: IntegerType, b: StringType });
700
+ const t2 = VariantType({ a: IntegerType, c: StringType });
701
+ assert.throws(() => TypeEqual(t1, t2), /TypeMismatchError.*variant case b is not present in both variants/);
702
+ });
703
+ test("TypeIntersect should throw for functions with different argument counts", () => {
704
+ const t1 = FunctionType([IntegerType], NullType);
705
+ const t2 = FunctionType([IntegerType, StringType], NullType);
706
+ assert.throws(() => TypeIntersect(t1, t2), /TypeMismatchError.*functions take different number of arguments/);
707
+ });
708
+ test("TypeEqual with nested type mismatch in array", () => {
709
+ const t1 = StructType({ x: ArrayType(IntegerType) });
710
+ const t2 = StructType({ x: ArrayType(FloatType) });
711
+ assert.throws(() => TypeEqual(t1, t2), /TypeMismatchError/);
712
+ });
713
+ test("TypeEqual should throw when comparing Variant with non-Variant", () => {
714
+ const t1 = VariantType({ a: IntegerType });
715
+ const t2 = IntegerType;
716
+ assert.throws(() => TypeEqual(t1, t2), /TypeMismatchError.*expected.*but got.*incompatible types/);
717
+ });
718
+ test("TypeEqual should throw when comparing Function with non-Function", () => {
719
+ const t1 = FunctionType([IntegerType], NullType);
720
+ const t2 = IntegerType;
721
+ assert.throws(() => TypeEqual(t1, t2), /TypeMismatchError.*expected.*but got.*incompatible types/);
722
+ });
723
+ test("TypeEqual should succeed for equal Dict types", () => {
724
+ const t1 = DictType(StringType, IntegerType);
725
+ const t2 = DictType(StringType, IntegerType);
726
+ const result = TypeEqual(t1, t2);
727
+ assert.strictEqual(result.type, "Dict");
728
+ });
729
+ test("TypeEqual should throw when comparing Dict with non-Dict", () => {
730
+ const t1 = DictType(StringType, IntegerType);
731
+ const t2 = IntegerType;
732
+ assert.throws(() => TypeEqual(t1, t2), /TypeMismatchError.*expected.*but got.*incompatible types/);
733
+ });
734
+ test("TypeEqual should succeed for equal Struct types", () => {
735
+ const t1 = StructType({ x: IntegerType, y: StringType });
736
+ const t2 = StructType({ x: IntegerType, y: StringType });
737
+ const result = TypeEqual(t1, t2);
738
+ assert.strictEqual(result.type, "Struct");
739
+ });
740
+ test("TypeEqual should throw when comparing Struct with non-Struct", () => {
741
+ const t1 = StructType({ x: IntegerType });
742
+ const t2 = IntegerType;
743
+ assert.throws(() => TypeEqual(t1, t2), /TypeMismatchError.*expected.*but got.*incompatible types/);
744
+ });
745
+ test("TypeEqual should throw when comparing Array with non-Array", () => {
746
+ const t1 = ArrayType(IntegerType);
747
+ const t2 = IntegerType;
748
+ assert.throws(() => TypeEqual(t1, t2), /TypeMismatchError.*expected.*but got.*incompatible types/);
749
+ });
750
+ test("TypeEqual should succeed for equal Set types", () => {
751
+ const t1 = SetType(StringType);
752
+ const t2 = SetType(StringType);
753
+ const result = TypeEqual(t1, t2);
754
+ assert.strictEqual(result.type, "Set");
755
+ });
756
+ test("TypeEqual should throw when comparing Set with non-Set", () => {
757
+ const t1 = SetType(StringType);
758
+ const t2 = IntegerType;
759
+ assert.throws(() => TypeEqual(t1, t2), /TypeMismatchError.*expected.*but got.*incompatible types/);
760
+ });
761
+ test("TypeIntersect should succeed for compatible function types", () => {
762
+ const t1 = FunctionType([IntegerType], FloatType);
763
+ const t2 = FunctionType([IntegerType], FloatType);
764
+ const result = TypeIntersect(t1, t2);
765
+ assert.strictEqual(result.type, "Function");
766
+ });
767
+ test("TypeIntersect should succeed for compatible async function types", () => {
768
+ const t1 = AsyncFunctionType([IntegerType], FloatType);
769
+ const t2 = AsyncFunctionType([IntegerType], FloatType);
770
+ const result = TypeIntersect(t1, t2);
771
+ assert.strictEqual(result.type, "AsyncFunction");
772
+ });
773
+ test("TypeIntersect should throw when intersecting Function with non-Function", () => {
774
+ const t1 = FunctionType([IntegerType], NullType);
775
+ const t2 = IntegerType;
776
+ assert.throws(() => TypeIntersect(t1, t2), /TypeMismatchError.*expected.*but got.*incompatible types/);
777
+ });
778
+ test("TypeIntersect should throw when intersecting AsyncFunction with non-Function", () => {
779
+ const t1 = AsyncFunctionType([IntegerType], NullType);
780
+ const t2 = IntegerType;
781
+ assert.throws(() => TypeIntersect(t1, t2), /TypeMismatchError.*expected.*but got.*incompatible types/);
782
+ });
783
+ test("TypeIntersect catch block with nested type error", () => {
784
+ const t1 = ArrayType(IntegerType);
785
+ const t2 = ArrayType(FloatType);
786
+ assert.throws(() => TypeIntersect(t1, t2), /TypeMismatchError/);
787
+ });
788
+ test("TypeEqual catch block with deeply nested error", () => {
789
+ const t1 = DictType(StringType, ArrayType(IntegerType));
790
+ const t2 = DictType(StringType, ArrayType(FloatType));
791
+ assert.throws(() => TypeEqual(t1, t2), /TypeMismatchError/);
792
+ });
793
+ test("TypeIntersect should throw when intersecting Variant with non-Variant", () => {
794
+ const t1 = VariantType({ a: IntegerType });
795
+ const t2 = IntegerType;
796
+ assert.throws(() => TypeIntersect(t1, t2), /TypeMismatchError.*expected.*but got.*incompatible types/);
797
+ });
798
+ test("TypeIntersect should succeed for compatible struct types", () => {
799
+ const t1 = StructType({ x: IntegerType, y: StringType });
800
+ const t2 = StructType({ x: IntegerType, y: StringType });
801
+ const result = TypeIntersect(t1, t2);
802
+ assert.strictEqual(result.type, "Struct");
803
+ });
804
+ test("TypeIntersect should throw when intersecting Struct with non-Struct", () => {
805
+ const t1 = StructType({ x: IntegerType });
806
+ const t2 = IntegerType;
807
+ assert.throws(() => TypeIntersect(t1, t2), /TypeMismatchError.*expected.*but got.*incompatible types/);
808
+ });
809
+ test("TypeIntersect should succeed for compatible dict types", () => {
810
+ const t1 = DictType(StringType, IntegerType);
811
+ const t2 = DictType(StringType, IntegerType);
812
+ const result = TypeIntersect(t1, t2);
813
+ assert.strictEqual(result.type, "Dict");
814
+ });
815
+ test("TypeIntersect should throw when intersecting Dict with non-Dict", () => {
816
+ const t1 = DictType(StringType, IntegerType);
817
+ const t2 = IntegerType;
818
+ assert.throws(() => TypeIntersect(t1, t2), /TypeMismatchError.*expected.*but got.*incompatible types/);
819
+ });
820
+ test("TypeIntersect should succeed for compatible set types", () => {
821
+ const t1 = SetType(StringType);
822
+ const t2 = SetType(StringType);
823
+ const result = TypeIntersect(t1, t2);
824
+ assert.strictEqual(result.type, "Set");
825
+ });
826
+ test("TypeIntersect should throw when intersecting Set with non-Set", () => {
827
+ const t1 = SetType(StringType);
828
+ const t2 = IntegerType;
829
+ assert.throws(() => TypeIntersect(t1, t2), /TypeMismatchError.*expected.*but got.*incompatible types/);
830
+ });
831
+ test("TypeIntersect should succeed for compatible array types", () => {
832
+ const t1 = ArrayType(IntegerType);
833
+ const t2 = ArrayType(IntegerType);
834
+ const result = TypeIntersect(t1, t2);
835
+ assert.strictEqual(result.type, "Array");
836
+ });
837
+ test("TypeIntersect should throw when intersecting Array with non-Array", () => {
838
+ const t1 = ArrayType(IntegerType);
839
+ const t2 = IntegerType;
840
+ assert.throws(() => TypeIntersect(t1, t2), /TypeMismatchError.*expected.*but got.*incompatible types/);
841
+ });
842
+ test("TypeIntersect should handle malformed types and wrap errors", () => {
843
+ const malformedType = { type: "Array", value: null };
844
+ assert.throws(() => TypeIntersect(malformedType, IntegerType));
845
+ });
846
+ test("TypeEqual should handle malformed types and wrap errors", () => {
847
+ const malformedType = { type: "Array", value: null };
848
+ assert.throws(() => TypeEqual(malformedType, IntegerType));
849
+ });
850
+ test("TypeUnion should throw for functions with different argument counts", () => {
851
+ const t1 = FunctionType([IntegerType], NullType);
852
+ const t2 = FunctionType([IntegerType, StringType], NullType);
853
+ assert.throws(() => TypeUnion(t1, t2), /TypeMismatchError.*functions take different number of arguments/);
854
+ });
855
+ test("TypeUnion should throw when unioning Function with non-Function", () => {
856
+ const t1 = FunctionType([IntegerType], NullType);
857
+ const t2 = IntegerType;
858
+ assert.throws(() => TypeUnion(t1, t2), /TypeMismatchError.*expected.*but got.*incompatible types/);
859
+ });
860
+ test("TypeUnion should throw when unioning AsyncFunction with non-Function", () => {
861
+ const t1 = AsyncFunctionType([IntegerType], NullType);
862
+ const t2 = IntegerType;
863
+ assert.throws(() => TypeUnion(t1, t2), /TypeMismatchError.*expected.*but got.*incompatible types/);
864
+ });
865
+ test("TypeUnion should handle malformed types and wrap errors", () => {
866
+ const malformedType = { type: "Array", value: null };
867
+ assert.throws(() => TypeUnion(malformedType, IntegerType));
868
+ });
869
+ test("TypeUnion should throw when unioning Dict with non-Dict", () => {
870
+ const t1 = DictType(StringType, IntegerType);
871
+ const t2 = IntegerType;
872
+ assert.throws(() => TypeUnion(t1, t2), /TypeMismatchError.*expected.*but got.*incompatible types/);
873
+ });
874
+ test("TypeUnion should throw when unioning Struct with non-Struct", () => {
875
+ const t1 = StructType({ x: IntegerType });
876
+ const t2 = IntegerType;
877
+ assert.throws(() => TypeUnion(t1, t2), /TypeMismatchError.*expected.*but got.*incompatible types/);
878
+ });
879
+ test("TypeUnion should throw when unioning Variant with non-Variant", () => {
880
+ const t1 = VariantType({ a: IntegerType });
881
+ const t2 = IntegerType;
882
+ assert.throws(() => TypeUnion(t1, t2), /TypeMismatchError.*expected.*but got.*incompatible types/);
883
+ });
884
+ test("TypeUnion should throw when unioning Set with non-Set", () => {
885
+ const t1 = SetType(StringType);
886
+ const t2 = IntegerType;
887
+ assert.throws(() => TypeUnion(t1, t2), /TypeMismatchError.*expected.*but got.*incompatible types/);
888
+ });
889
+ test("isSubtype should return false for incompatible variant types", () => {
890
+ const t1 = VariantType({ a: IntegerType });
891
+ const t2 = IntegerType;
892
+ assert.strictEqual(isSubtype(t1, t2), false);
893
+ });
894
+ test("isSubtype should return false for incompatible function types", () => {
895
+ const t1 = FunctionType([IntegerType], NullType);
896
+ const t2 = IntegerType;
897
+ assert.strictEqual(isSubtype(t1, t2), false);
898
+ });
899
+ test("isSubtype should return false for async function compared to non-Function", () => {
900
+ const t1 = AsyncFunctionType([IntegerType], NullType);
901
+ const t2 = IntegerType;
902
+ assert.strictEqual(isSubtype(t1, t2), false);
903
+ });
904
+ test("isSubtype should return false for Set compared to non-Set", () => {
905
+ const t1 = SetType(StringType);
906
+ const t2 = IntegerType;
907
+ assert.strictEqual(isSubtype(t1, t2), false);
908
+ });
909
+ test("isSubtype should return false for Dict compared to non-Dict", () => {
910
+ const t1 = DictType(StringType, IntegerType);
911
+ const t2 = IntegerType;
912
+ assert.strictEqual(isSubtype(t1, t2), false);
913
+ });
914
+ test("isSubtype should return false for Struct compared to non-Struct", () => {
915
+ const t1 = StructType({ x: IntegerType });
916
+ const t2 = IntegerType;
917
+ assert.strictEqual(isSubtype(t1, t2), false);
918
+ });
919
+ test("isTypeEqual should return false for Function compared to non-Function", () => {
920
+ const t1 = FunctionType([IntegerType], NullType);
921
+ const t2 = IntegerType;
922
+ assert.strictEqual(isTypeEqual(t1, t2), false);
923
+ });
924
+ test("isTypeEqual should return false for AsyncFunction compared to non-Function", () => {
925
+ const t1 = AsyncFunctionType([IntegerType], NullType);
926
+ const t2 = IntegerType;
927
+ assert.strictEqual(isTypeEqual(t1, t2), false);
928
+ });
929
+ test("isTypeEqual should return false for sync vs async function", () => {
930
+ const t1 = FunctionType([IntegerType], NullType);
931
+ const t2 = AsyncFunctionType([IntegerType], NullType);
932
+ assert.strictEqual(isTypeEqual(t1, t2), false);
933
+ });
934
+ test("isValueOf should return false for non-Set value with Set type", () => {
935
+ assert.strictEqual(isValueOf([], SetType(IntegerType)), false);
936
+ });
937
+ test("isValueOf should return false for non-Map value with Dict type", () => {
938
+ assert.strictEqual(isValueOf([], DictType(StringType, IntegerType)), false);
939
+ });
940
+ test("isSubtype should return false for Array compared to non-Array", () => {
941
+ const t1 = ArrayType(IntegerType);
942
+ const t2 = IntegerType;
943
+ assert.strictEqual(isSubtype(t1, t2), false);
944
+ });
945
+ });
946
+ //# sourceMappingURL=types.spec.js.map