@divmain/jdm-asm 0.2.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 (397) hide show
  1. package/.github/workflows/ci.yml +53 -0
  2. package/.oxfmtrc.json +16 -0
  3. package/.oxlintrc.json +183 -0
  4. package/AGENTS.md +81 -0
  5. package/README.md +769 -0
  6. package/asconfig.json +23 -0
  7. package/benchmarks/fixtures.ts +111 -0
  8. package/benchmarks/input-fixtures.ts +80 -0
  9. package/benchmarks/run.ts +913 -0
  10. package/benchmarks/worker-pool.ts +223 -0
  11. package/benchmarks/worker.ts +374 -0
  12. package/dist/index.d.ts +996 -0
  13. package/dist/index.js +12239 -0
  14. package/dist/index.js.map +1 -0
  15. package/package.json +49 -0
  16. package/scripts/run-all-tests.ts +220 -0
  17. package/src/compiler/EXPRESSION_SUBSETS.md +228 -0
  18. package/src/compiler/asc-compiler.ts +315 -0
  19. package/src/compiler/ast-types.ts +215 -0
  20. package/src/compiler/build.ts +56 -0
  21. package/src/compiler/cache.ts +414 -0
  22. package/src/compiler/code-generators.ts +211 -0
  23. package/src/compiler/codegen/index.ts +15 -0
  24. package/src/compiler/codegen/js-marshal.ts +999 -0
  25. package/src/compiler/codegen/js-validation.ts +243 -0
  26. package/src/compiler/codegen.ts +19 -0
  27. package/src/compiler/compile-time-validation.ts +507 -0
  28. package/src/compiler/cst-visitor.ts +434 -0
  29. package/src/compiler/errors.ts +227 -0
  30. package/src/compiler/expression-parser.ts +536 -0
  31. package/src/compiler/graph.ts +197 -0
  32. package/src/compiler/index.ts +199 -0
  33. package/src/compiler/input-validation.ts +33 -0
  34. package/src/compiler/marshal-gen.ts +21 -0
  35. package/src/compiler/nodes/context-resolvers.ts +197 -0
  36. package/src/compiler/nodes/decision-table.ts +507 -0
  37. package/src/compiler/nodes/decision.ts +292 -0
  38. package/src/compiler/nodes/expression-compiler.ts +526 -0
  39. package/src/compiler/nodes/expression.ts +425 -0
  40. package/src/compiler/nodes/function.ts +316 -0
  41. package/src/compiler/nodes/input.ts +60 -0
  42. package/src/compiler/nodes/switch.ts +547 -0
  43. package/src/compiler/optimizer.ts +948 -0
  44. package/src/compiler/orchestrator.ts +352 -0
  45. package/src/compiler/parser.ts +115 -0
  46. package/src/compiler/result-selection.ts +161 -0
  47. package/src/compiler/runtime/index.ts +26 -0
  48. package/src/compiler/runtime-codegen.ts +211 -0
  49. package/src/compiler/runtime-validation-codegen.ts +294 -0
  50. package/src/compiler/runtime.ts +452 -0
  51. package/src/compiler/schema.ts +245 -0
  52. package/src/compiler/switch-branch-detection.ts +92 -0
  53. package/src/compiler/types.ts +136 -0
  54. package/src/compiler/unary-ast-transforms.ts +148 -0
  55. package/src/compiler/unary-parser.ts +301 -0
  56. package/src/compiler/unary-transform.ts +161 -0
  57. package/src/compiler/utils.ts +27 -0
  58. package/src/compiler/virtual-fs.ts +90 -0
  59. package/src/compiler/wasm-instantiate.ts +127 -0
  60. package/src/index.ts +1 -0
  61. package/src/runtime/arrays.ts +579 -0
  62. package/src/runtime/context.ts +189 -0
  63. package/src/runtime/expressions.ts +1811 -0
  64. package/src/runtime/index.ts +8 -0
  65. package/src/runtime/memory.ts +607 -0
  66. package/src/runtime/strings.ts +260 -0
  67. package/src/runtime/tables.ts +96 -0
  68. package/src/runtime/tsconfig.json +4 -0
  69. package/src/runtime/values.ts +209 -0
  70. package/test-data/README.md +83 -0
  71. package/test-data/decision-tables/basic/8k.json +87992 -0
  72. package/test-data/decision-tables/basic/affiliate-commission-calculator.json +228 -0
  73. package/test-data/decision-tables/basic/airline-loyalty-points-calculations.json +285 -0
  74. package/test-data/decision-tables/basic/airline-upgrade-eligibility.json +466 -0
  75. package/test-data/decision-tables/basic/auto-insurance-premium-calculator.json +412 -0
  76. package/test-data/decision-tables/basic/booking-personalization-system.json +553 -0
  77. package/test-data/decision-tables/basic/care-team-assignment-system.json +585 -0
  78. package/test-data/decision-tables/basic/claim-validation-system.json +307 -0
  79. package/test-data/decision-tables/basic/clinical-lab-result-interpreter.json +433 -0
  80. package/test-data/decision-tables/basic/clinical-treatment-protocol.json +474 -0
  81. package/test-data/decision-tables/basic/credit-limit-adjustment.json +479 -0
  82. package/test-data/decision-tables/basic/customer-eligibility-engine.json +551 -0
  83. package/test-data/decision-tables/basic/customer-lifetime-value.json +200 -0
  84. package/test-data/decision-tables/basic/customer-onboarding-kyc-verification.json +611 -0
  85. package/test-data/decision-tables/basic/customer-service-escalation.json +191 -0
  86. package/test-data/decision-tables/basic/decision-table-discounts.json +168 -0
  87. package/test-data/decision-tables/basic/decision-table-shipping.json +398 -0
  88. package/test-data/decision-tables/basic/delivery-route-optimizer.json +271 -0
  89. package/test-data/decision-tables/basic/device-compatibility-checker.json +303 -0
  90. package/test-data/decision-tables/basic/disaster-relief-fund-allocation.json +296 -0
  91. package/test-data/decision-tables/basic/dynamic-fx-rate-pricing-system.json +237 -0
  92. package/test-data/decision-tables/basic/dynamic-marketplace-comission-calculator.json +242 -0
  93. package/test-data/decision-tables/basic/dynamic-shipping-cost-calculator.json +378 -0
  94. package/test-data/decision-tables/basic/dynamic-tarrif-engine.json +289 -0
  95. package/test-data/decision-tables/basic/dynamic-ticket-pricing.json +325 -0
  96. package/test-data/decision-tables/basic/empty-column-with-space.json +100 -0
  97. package/test-data/decision-tables/basic/empty-column-without-space.json +100 -0
  98. package/test-data/decision-tables/basic/environment-compliance-assessment.json +386 -0
  99. package/test-data/decision-tables/basic/expression-table-map.json +313 -0
  100. package/test-data/decision-tables/basic/flash-sale-eligibility.json +366 -0
  101. package/test-data/decision-tables/basic/flight-dispatch-decision-system.json +455 -0
  102. package/test-data/decision-tables/basic/flight-rebooking-fee-calculator.json +406 -0
  103. package/test-data/decision-tables/basic/government-assistance.json +299 -0
  104. package/test-data/decision-tables/basic/grant-funding-distribution.json +307 -0
  105. package/test-data/decision-tables/basic/hazardous-materials-management-system.json +414 -0
  106. package/test-data/decision-tables/basic/immigration-eligibility-evaluator.json +765 -0
  107. package/test-data/decision-tables/basic/import-duties-calculator.json +318 -0
  108. package/test-data/decision-tables/basic/insurance-agent-commission.json +228 -0
  109. package/test-data/decision-tables/basic/insurance-coverage-calculator.json +362 -0
  110. package/test-data/decision-tables/basic/insurance-underwriting-risk.json +321 -0
  111. package/test-data/decision-tables/basic/international-roaming-policy-manager.json +199 -0
  112. package/test-data/decision-tables/basic/legacy-plan-management.json +434 -0
  113. package/test-data/decision-tables/basic/marketplace-listing-verification-system.json +334 -0
  114. package/test-data/decision-tables/basic/medication-dosage-calculator.json +318 -0
  115. package/test-data/decision-tables/basic/merch-bags.json +171 -0
  116. package/test-data/decision-tables/basic/municipal-permit-evaluation-system.json +364 -0
  117. package/test-data/decision-tables/basic/mvno-partner-enablement.json +313 -0
  118. package/test-data/decision-tables/basic/partner-revenue-sharing.json +244 -0
  119. package/test-data/decision-tables/basic/payment-routing-and-fee-calculator.json +475 -0
  120. package/test-data/decision-tables/basic/policy-discount-calculator.json +307 -0
  121. package/test-data/decision-tables/basic/policy-eligibility-analyzer.json +299 -0
  122. package/test-data/decision-tables/basic/product-listing-scoring.json +358 -0
  123. package/test-data/decision-tables/basic/realtime-fraud-detection.json +235 -0
  124. package/test-data/decision-tables/basic/regional-compliance-manager.json +278 -0
  125. package/test-data/decision-tables/basic/returns-and-refund-policy.json +366 -0
  126. package/test-data/decision-tables/basic/returns-processing-system.json +448 -0
  127. package/test-data/decision-tables/basic/school-district-resource-allocation.json +282 -0
  128. package/test-data/decision-tables/basic/seat-map-optimization.json +325 -0
  129. package/test-data/decision-tables/basic/seller-fee-calculator.json +307 -0
  130. package/test-data/decision-tables/basic/service-level-agreement-enforcement.json +575 -0
  131. package/test-data/decision-tables/basic/smart-financial-product-matcher.json +249 -0
  132. package/test-data/decision-tables/basic/supply-chain-risk.json +316 -0
  133. package/test-data/decision-tables/basic/table-loop.json +93 -0
  134. package/test-data/decision-tables/basic/table.json +76 -0
  135. package/test-data/decision-tables/basic/traffic-violation-penalty-calculator.json +436 -0
  136. package/test-data/decision-tables/basic/transaction-compliance-classifier.json +525 -0
  137. package/test-data/decision-tables/basic/vehicle-claims-resolution.json +310 -0
  138. package/test-data/decision-tables/basic/warehouse-storage-location.json +345 -0
  139. package/test-data/decision-tables/hit-policy-collect/collect-multiple-matches.json +127 -0
  140. package/test-data/decision-tables/hit-policy-collect/collect-no-match.json +95 -0
  141. package/test-data/decision-tables/hit-policy-first/first-match.json +103 -0
  142. package/test-data/decision-tables/hit-policy-first/no-match.json +95 -0
  143. package/test-data/decision-tables/hit-policy-output-order/output-order-respected.json +94 -0
  144. package/test-data/decision-tables/hit-policy-output-order/string-output-order.json +94 -0
  145. package/test-data/decision-tables/hit-policy-priority/priority-respected.json +86 -0
  146. package/test-data/decision-tables/hit-policy-rule-order/rule-order-respected.json +94 -0
  147. package/test-data/decision-tables/hit-policy-unique/all-match-error.json +89 -0
  148. package/test-data/decision-tables/hit-policy-unique/multiple-match-error.json +89 -0
  149. package/test-data/decision-tables/hit-policy-unique/no-match.json +88 -0
  150. package/test-data/decision-tables/hit-policy-unique/unique-match.json +99 -0
  151. package/test-data/expressions/arithmetic/error-cyclic.json +114 -0
  152. package/test-data/expressions/arithmetic/error-missing-input.json +54 -0
  153. package/test-data/expressions/arithmetic/error-missing-output.json +54 -0
  154. package/test-data/expressions/arithmetic/expression-default.json +93 -0
  155. package/test-data/expressions/arithmetic/expression-fields.json +94 -0
  156. package/test-data/expressions/arithmetic/expression-loop.json +94 -0
  157. package/test-data/expressions/arithmetic/expression-passthrough.json +108 -0
  158. package/test-data/expressions/arithmetic/expression.json +69 -0
  159. package/test-data/expressions/arithmetic/nested-request.json +125 -0
  160. package/test-data/expressions/arithmetic/number-function.json +58 -0
  161. package/test-data/expressions/arithmetic/test-number-functions.json +68 -0
  162. package/test-data/expressions/functions/all.json +149 -0
  163. package/test-data/expressions/functions/avg.json +89 -0
  164. package/test-data/expressions/functions/filter.json +109 -0
  165. package/test-data/expressions/functions/flat.json +167 -0
  166. package/test-data/expressions/functions/map-strings.json +65 -0
  167. package/test-data/expressions/functions/map.json +73 -0
  168. package/test-data/expressions/functions/reduce.json +49 -0
  169. package/test-data/expressions/functions/some.json +175 -0
  170. package/test-data/expressions/functions/sort-strings.json +97 -0
  171. package/test-data/expressions/functions/sort.json +97 -0
  172. package/test-data/expressions/logical/logical-and.json +116 -0
  173. package/test-data/expressions/logical/logical-complex.json +260 -0
  174. package/test-data/expressions/logical/logical-not.json +111 -0
  175. package/test-data/expressions/logical/logical-or.json +123 -0
  176. package/test-data/expressions/string/string-comparison.json +128 -0
  177. package/test-data/expressions/string/string-concat.json +106 -0
  178. package/test-data/expressions/string/string-contains.json +125 -0
  179. package/test-data/expressions/string/string-endsWith.json +113 -0
  180. package/test-data/expressions/string/string-indexOf.json +131 -0
  181. package/test-data/expressions/string/string-join.json +92 -0
  182. package/test-data/expressions/string/string-lower.json +94 -0
  183. package/test-data/expressions/string/string-replace.json +130 -0
  184. package/test-data/expressions/string/string-split.json +101 -0
  185. package/test-data/expressions/string/string-startsWith.json +113 -0
  186. package/test-data/expressions/string/string-substring.json +138 -0
  187. package/test-data/expressions/string/string-trim.json +100 -0
  188. package/test-data/expressions/string/string-upper.json +94 -0
  189. package/test-data/other/custom.json +51 -0
  190. package/test-data/other/customer-input-schema.json +34 -0
  191. package/test-data/other/customer-output-schema.json +34 -0
  192. package/test-data/other/passthrough.json +31 -0
  193. package/test-data/sub-decisions/basic/$nodes-child.json +31 -0
  194. package/test-data/sub-decisions/basic/$nodes-parent.json +49 -0
  195. package/test-data/sub-decisions/basic/recursive-table1.json +49 -0
  196. package/test-data/sub-decisions/basic/recursive-table2.json +49 -0
  197. package/test-data/sub-decisions/complex-multi/approval-decision.json +31 -0
  198. package/test-data/sub-decisions/complex-multi/complex-dag.json +175 -0
  199. package/test-data/sub-decisions/complex-multi/credit-check.json +31 -0
  200. package/test-data/sub-decisions/complex-multi/customer-segmentation.json +31 -0
  201. package/test-data/sub-decisions/complex-multi/discount-eligibility.json +31 -0
  202. package/test-data/sub-decisions/complex-multi/eligibility-check.json +31 -0
  203. package/test-data/sub-decisions/complex-multi/final-offer.json +31 -0
  204. package/test-data/sub-decisions/complex-multi/income-verification.json +31 -0
  205. package/test-data/sub-decisions/complex-multi/linear-chain.json +121 -0
  206. package/test-data/sub-decisions/complex-multi/pricing-calculation.json +31 -0
  207. package/test-data/sub-decisions/complex-multi/product-eligibility.json +31 -0
  208. package/test-data/sub-decisions/complex-multi/risk-assessment.json +31 -0
  209. package/test-data/sub-decisions/complex-multi/shared-validation.json +31 -0
  210. package/test-data/sub-decisions/complex-multi/validation.json +31 -0
  211. package/test-data/sub-decisions/diamond/decision-a.json +31 -0
  212. package/test-data/sub-decisions/diamond/decision-b.json +31 -0
  213. package/test-data/sub-decisions/diamond/decision-c.json +31 -0
  214. package/test-data/sub-decisions/diamond/decision-shared.json +31 -0
  215. package/test-data/sub-decisions/diamond/diamond-pattern.json +109 -0
  216. package/test-data/sub-decisions/error-propagation/parent-calls-error.json +44 -0
  217. package/test-data/sub-decisions/error-propagation/sub-decision-with-error.json +60 -0
  218. package/test-data/switch-nodes/basic/account-dormancy-management.json +245 -0
  219. package/test-data/switch-nodes/basic/application-risk-assessment.json +474 -0
  220. package/test-data/switch-nodes/basic/cellular-data-rollover-system.json +281 -0
  221. package/test-data/switch-nodes/basic/clinical-pathway-selection.json +454 -0
  222. package/test-data/switch-nodes/basic/insurance-prior-authorization.json +467 -0
  223. package/test-data/switch-nodes/basic/last-mile-delivery-assignment.json +373 -0
  224. package/test-data/switch-nodes/basic/loan-approval.json +469 -0
  225. package/test-data/switch-nodes/basic/multi-switch.json +498 -0
  226. package/test-data/switch-nodes/basic/online-checkin-eligibility.json +285 -0
  227. package/test-data/switch-nodes/basic/order-consolidation-system.json +493 -0
  228. package/test-data/switch-nodes/basic/seller-approval-workflow.json +383 -0
  229. package/test-data/switch-nodes/basic/set-fee.json +243 -0
  230. package/test-data/switch-nodes/basic/shipping-carrier-selector.json +379 -0
  231. package/test-data/switch-nodes/basic/switch-node.json +167 -0
  232. package/test-data/switch-nodes/basic/switch-performance-2.json +1307 -0
  233. package/test-data/switch-nodes/basic/switch-performance.json +691 -0
  234. package/test-data/switch-nodes/basic/tax-exemption.json +295 -0
  235. package/test-data/switch-nodes/basic/warehouse-cross-docking.json +313 -0
  236. package/test-data/switch-nodes/default-cases/switch-with-default.json +134 -0
  237. package/test-data/zen-reference/$nodes-child.json +69 -0
  238. package/test-data/zen-reference/$nodes-parent.json +34 -0
  239. package/test-data/zen-reference/8k.json +87992 -0
  240. package/test-data/zen-reference/credit-analysis.json +324 -0
  241. package/test-data/zen-reference/custom.json +51 -0
  242. package/test-data/zen-reference/customer-input-schema.json +34 -0
  243. package/test-data/zen-reference/customer-output-schema.json +34 -0
  244. package/test-data/zen-reference/error-cyclic.json +114 -0
  245. package/test-data/zen-reference/error-missing-input.json +54 -0
  246. package/test-data/zen-reference/error-missing-output.json +54 -0
  247. package/test-data/zen-reference/expression.json +69 -0
  248. package/test-data/zen-reference/function-v2.json +48 -0
  249. package/test-data/zen-reference/function.json +46 -0
  250. package/test-data/zen-reference/graphs/account-dormancy-management.json +245 -0
  251. package/test-data/zen-reference/graphs/affiliate-commission-calculator.json +228 -0
  252. package/test-data/zen-reference/graphs/airline-loyalty-points-calculations.json +285 -0
  253. package/test-data/zen-reference/graphs/airline-upgrade-eligibility.json +466 -0
  254. package/test-data/zen-reference/graphs/aml.json +537 -0
  255. package/test-data/zen-reference/graphs/application-risk-assessment.json +474 -0
  256. package/test-data/zen-reference/graphs/auto-insurance-premium-calculator.json +412 -0
  257. package/test-data/zen-reference/graphs/booking-personalization-system.json +553 -0
  258. package/test-data/zen-reference/graphs/care-team-assignment-system.json +585 -0
  259. package/test-data/zen-reference/graphs/cellular-data-rollover-system.json +281 -0
  260. package/test-data/zen-reference/graphs/claim-validation-system.json +307 -0
  261. package/test-data/zen-reference/graphs/clinical-lab-result-interpreter.json +433 -0
  262. package/test-data/zen-reference/graphs/clinical-pathway-selection.json +454 -0
  263. package/test-data/zen-reference/graphs/clinical-treatment-protocol.json +474 -0
  264. package/test-data/zen-reference/graphs/company-analysis.json +390 -0
  265. package/test-data/zen-reference/graphs/credit-limit-adjustment.json +479 -0
  266. package/test-data/zen-reference/graphs/customer-eligibility-engine.json +551 -0
  267. package/test-data/zen-reference/graphs/customer-lifetime-value.json +200 -0
  268. package/test-data/zen-reference/graphs/customer-onboarding-kyc-verification.json +611 -0
  269. package/test-data/zen-reference/graphs/customer-service-escalation.json +191 -0
  270. package/test-data/zen-reference/graphs/decision-table-discounts.json +168 -0
  271. package/test-data/zen-reference/graphs/decision-table-shipping.json +398 -0
  272. package/test-data/zen-reference/graphs/delivery-route-optimizer.json +271 -0
  273. package/test-data/zen-reference/graphs/device-compatibility-checker.json +303 -0
  274. package/test-data/zen-reference/graphs/disaster-relief-fund-allocation.json +296 -0
  275. package/test-data/zen-reference/graphs/dynamic-fx-rate-pricing-system.json +237 -0
  276. package/test-data/zen-reference/graphs/dynamic-marketplace-comission-calculator.json +242 -0
  277. package/test-data/zen-reference/graphs/dynamic-shipping-cost-calculator.json +378 -0
  278. package/test-data/zen-reference/graphs/dynamic-tarrif-engine.json +289 -0
  279. package/test-data/zen-reference/graphs/dynamic-ticket-pricing.json +325 -0
  280. package/test-data/zen-reference/graphs/empty-column-with-space.json +100 -0
  281. package/test-data/zen-reference/graphs/empty-column-without-space.json +100 -0
  282. package/test-data/zen-reference/graphs/environment-compliance-assessment.json +386 -0
  283. package/test-data/zen-reference/graphs/expression-default.json +93 -0
  284. package/test-data/zen-reference/graphs/expression-fields.json +94 -0
  285. package/test-data/zen-reference/graphs/expression-loop.json +94 -0
  286. package/test-data/zen-reference/graphs/expression-passthrough.json +108 -0
  287. package/test-data/zen-reference/graphs/expression-table-map.json +313 -0
  288. package/test-data/zen-reference/graphs/flash-sale-eligibility.json +366 -0
  289. package/test-data/zen-reference/graphs/flight-dispatch-decision-system.json +455 -0
  290. package/test-data/zen-reference/graphs/flight-rebooking-fee-calculator.json +406 -0
  291. package/test-data/zen-reference/graphs/government-assistance.json +299 -0
  292. package/test-data/zen-reference/graphs/grant-funding-distribution.json +307 -0
  293. package/test-data/zen-reference/graphs/hazardous-materials-management-system.json +414 -0
  294. package/test-data/zen-reference/graphs/immigration-eligibility-evaluator.json +765 -0
  295. package/test-data/zen-reference/graphs/import-duties-calculator.json +318 -0
  296. package/test-data/zen-reference/graphs/insurance-agent-commission.json +228 -0
  297. package/test-data/zen-reference/graphs/insurance-breakdown.json +421 -0
  298. package/test-data/zen-reference/graphs/insurance-coverage-calculator.json +362 -0
  299. package/test-data/zen-reference/graphs/insurance-prior-authorization.json +467 -0
  300. package/test-data/zen-reference/graphs/insurance-underwriting-risk.json +321 -0
  301. package/test-data/zen-reference/graphs/international-roaming-policy-manager.json +199 -0
  302. package/test-data/zen-reference/graphs/last-mile-delivery-assignment.json +373 -0
  303. package/test-data/zen-reference/graphs/legacy-plan-management.json +434 -0
  304. package/test-data/zen-reference/graphs/loan-approval.json +469 -0
  305. package/test-data/zen-reference/graphs/marketplace-listing-verification-system.json +334 -0
  306. package/test-data/zen-reference/graphs/medication-dosage-calculator.json +318 -0
  307. package/test-data/zen-reference/graphs/merch-bags.json +171 -0
  308. package/test-data/zen-reference/graphs/multi-switch.json +498 -0
  309. package/test-data/zen-reference/graphs/municipal-permit-evaluation-system.json +364 -0
  310. package/test-data/zen-reference/graphs/mvno-partner-enablement.json +313 -0
  311. package/test-data/zen-reference/graphs/nested-request.json +125 -0
  312. package/test-data/zen-reference/graphs/online-checkin-eligibility.json +285 -0
  313. package/test-data/zen-reference/graphs/order-consolidation-system.json +493 -0
  314. package/test-data/zen-reference/graphs/partner-revenue-sharing.json +244 -0
  315. package/test-data/zen-reference/graphs/payment-routing-and-fee-calculator.json +475 -0
  316. package/test-data/zen-reference/graphs/policy-discount-calculator.json +307 -0
  317. package/test-data/zen-reference/graphs/policy-eligibility-analyzer.json +299 -0
  318. package/test-data/zen-reference/graphs/product-listing-scoring.json +358 -0
  319. package/test-data/zen-reference/graphs/realtime-fraud-detection.json +235 -0
  320. package/test-data/zen-reference/graphs/regional-compliance-manager.json +278 -0
  321. package/test-data/zen-reference/graphs/returns-and-refund-policy.json +366 -0
  322. package/test-data/zen-reference/graphs/returns-processing-system.json +448 -0
  323. package/test-data/zen-reference/graphs/school-district-resource-allocation.json +282 -0
  324. package/test-data/zen-reference/graphs/seat-map-optimization.json +325 -0
  325. package/test-data/zen-reference/graphs/seller-approval-workflow.json +383 -0
  326. package/test-data/zen-reference/graphs/seller-fee-calculator.json +307 -0
  327. package/test-data/zen-reference/graphs/service-level-agreement-enforcement.json +575 -0
  328. package/test-data/zen-reference/graphs/set-fee.json +243 -0
  329. package/test-data/zen-reference/graphs/shipping-carrier-selector.json +379 -0
  330. package/test-data/zen-reference/graphs/smart-financial-product-matcher.json +249 -0
  331. package/test-data/zen-reference/graphs/supply-chain-risk.json +316 -0
  332. package/test-data/zen-reference/graphs/table-loop.json +93 -0
  333. package/test-data/zen-reference/graphs/tax-exemption.json +295 -0
  334. package/test-data/zen-reference/graphs/traffic-violation-penalty-calculator.json +436 -0
  335. package/test-data/zen-reference/graphs/transaction-compliance-classifier.json +525 -0
  336. package/test-data/zen-reference/graphs/vehicle-claims-resolution.json +310 -0
  337. package/test-data/zen-reference/graphs/warehouse-cross-docking.json +313 -0
  338. package/test-data/zen-reference/graphs/warehouse-storage-location.json +345 -0
  339. package/test-data/zen-reference/http-function.json +34 -0
  340. package/test-data/zen-reference/infinite-function.json +46 -0
  341. package/test-data/zen-reference/js/imports.js +25 -0
  342. package/test-data/zen-reference/passthrough.json +31 -0
  343. package/test-data/zen-reference/recursive-table1.json +49 -0
  344. package/test-data/zen-reference/recursive-table2.json +49 -0
  345. package/test-data/zen-reference/sleep-function.json +34 -0
  346. package/test-data/zen-reference/switch-node.json +167 -0
  347. package/test-data/zen-reference/switch-performance-2.json +1307 -0
  348. package/test-data/zen-reference/switch-performance.json +691 -0
  349. package/test-data/zen-reference/table.json +76 -0
  350. package/tests/helpers/index.ts +73 -0
  351. package/tests/helpers/mock-context.ts +231 -0
  352. package/tests/helpers/round-trip.ts +398 -0
  353. package/tests/helpers/test-harness-comparison.ts +325 -0
  354. package/tests/helpers/test-harness-wasm.ts +710 -0
  355. package/tests/helpers/test-harness.ts +28 -0
  356. package/tests/helpers/wasm-test.ts +659 -0
  357. package/tests/integration/compilation-errors.test.ts +864 -0
  358. package/tests/integration/decision-tables.test.ts +531 -0
  359. package/tests/integration/edge-cases.test.ts +787 -0
  360. package/tests/integration/expressions.test.ts +513 -0
  361. package/tests/integration/function-node-integration.test.ts +182 -0
  362. package/tests/integration/sub-decisions.test.ts +108 -0
  363. package/tests/integration/switch-nodes.test.ts +399 -0
  364. package/tests/integration/unary-or-matching.test.ts +53 -0
  365. package/tests/integration/wasm-data-types.test.ts +398 -0
  366. package/tests/integration/wasm-errors.test.ts +199 -0
  367. package/tests/integration/wasm-execution.test.ts +348 -0
  368. package/tests/integration/wasm-memory.test.ts +228 -0
  369. package/tests/scripts/analyze-coverage.ts +166 -0
  370. package/tests/scripts/categorize-tests.ts +396 -0
  371. package/tests/scripts/coverage-analysis.ts +836 -0
  372. package/tests/unit/compiler/cache.test.ts +238 -0
  373. package/tests/unit/compiler/errors.test.ts +316 -0
  374. package/tests/unit/compiler/graph-scalability.test.ts +510 -0
  375. package/tests/unit/compiler/graph.test.ts +878 -0
  376. package/tests/unit/compiler/input-validation.test.ts +447 -0
  377. package/tests/unit/compiler/logical-and-parser.test.ts +143 -0
  378. package/tests/unit/compiler/logical-not-parser.test.ts +107 -0
  379. package/tests/unit/compiler/logical-or-parser.test.ts +236 -0
  380. package/tests/unit/compiler/marshal-gen/marshal-gen.test.ts +97 -0
  381. package/tests/unit/compiler/nodes/decision-table.test.ts +103 -0
  382. package/tests/unit/compiler/nodes/decision.test.ts +182 -0
  383. package/tests/unit/compiler/nodes/function-compile.test.ts +204 -0
  384. package/tests/unit/compiler/nodes/function.test.ts +176 -0
  385. package/tests/unit/compiler/nodes/input.test.ts +30 -0
  386. package/tests/unit/compiler/nodes/switch.test.ts +127 -0
  387. package/tests/unit/compiler/optimizer-cache.test.ts +327 -0
  388. package/tests/unit/compiler/optimizer-implementation.test.ts +625 -0
  389. package/tests/unit/compiler/parser.test.ts +508 -0
  390. package/tests/unit/compiler/runtime-error-cleanup.test.ts +426 -0
  391. package/tests/unit/compiler/runtime-validation.test.ts +303 -0
  392. package/tests/unit/compiler/runtime.test.ts +221 -0
  393. package/tests/unit/compiler/schema/schema.test.ts +248 -0
  394. package/tests/unit/compiler/unary-ast-transforms.test.ts +245 -0
  395. package/tsconfig.json +27 -0
  396. package/tsup.config.ts +11 -0
  397. package/vitest.config.ts +12 -0
@@ -0,0 +1,204 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { compileFunctionNode } from '../../../../src/compiler/nodes/function.js';
3
+ import { CompilationError } from '../../../../src/compiler/errors';
4
+ import { parseJDM } from '../../../../src/compiler/parser.js';
5
+ import { parseStandardExpression } from '../../../../src/compiler/unary-parser.js';
6
+ import { createMockContext } from '../../../helpers';
7
+
8
+ // Helper function to create a counter-based ID generator for testing
9
+ function createCounterIdGenerator() {
10
+ let counter = 0;
11
+ return (prefix: string) => {
12
+ return `${prefix}_${counter++}`;
13
+ };
14
+ }
15
+
16
+ describe('Function Node Compilation', () => {
17
+ it('should compile function node with simple parameter', () => {
18
+ const node = {
19
+ id: 'func1',
20
+ name: 'TestFunction',
21
+ content: {
22
+ source: 'export const handler = (input) => ({ output: input * 2 })',
23
+ },
24
+ parsedContent: {
25
+ source: 'export const handler = (input) => ({ output: input * 2 })',
26
+ parameters: ['input'],
27
+ ast: null,
28
+ },
29
+ };
30
+
31
+ const context = createMockContext({
32
+ nodes: parseJDM('{"nodes": [], "edges": []}').nodes,
33
+ edges: parseJDM('{"nodes": [], "edges": []}').edges,
34
+ options: { optimize: true, debug: false, validate: false },
35
+ parseExpression: parseStandardExpression,
36
+ parseUnaryExpression: (expr: string) => parseStandardExpression(expr),
37
+ getUniqueId: createCounterIdGenerator(),
38
+ loadDecision: () => parseJDM('{"nodes": [], "edges": []}'),
39
+ functionSources: new Map(),
40
+ });
41
+
42
+ const code = compileFunctionNode(node, context);
43
+
44
+ // Verify that the generated code contains the expected structure
45
+ expect(code).toContain('export function evaluateNode_func1(ctx: Context): Value');
46
+ expect(code).toContain('Function node: TestFunction');
47
+ expect(code).toContain('let input = ctx.get("input");');
48
+ expect(code).toContain('let result = Value.Object(mockResult);');
49
+ });
50
+
51
+ it('should compile function node with multiple parameters', () => {
52
+ const node = {
53
+ id: 'func2',
54
+ name: 'MultiParamFunction',
55
+ content: {
56
+ source: 'export const handler = (input, context) => ({ output: input })',
57
+ },
58
+ parsedContent: {
59
+ source: 'export const handler = (input, context) => ({ output: input })',
60
+ parameters: ['input', 'context'],
61
+ ast: null,
62
+ },
63
+ };
64
+
65
+ const context = createMockContext({
66
+ nodes: parseJDM('{"nodes": [], "edges": []}').nodes,
67
+ edges: parseJDM('{"nodes": [], "edges": []}').edges,
68
+ options: { optimize: true, debug: false, validate: false },
69
+ parseExpression: parseStandardExpression,
70
+ parseUnaryExpression: (expr: string) => parseStandardExpression(expr),
71
+ getUniqueId: createCounterIdGenerator(),
72
+ loadDecision: () => parseJDM('{"nodes": [], "edges": []}'),
73
+ functionSources: new Map(),
74
+ });
75
+
76
+ const code = compileFunctionNode(node, context);
77
+
78
+ expect(code).toContain('let input = ctx.get("input");');
79
+ expect(code).toContain('let context = ctx.get("context");');
80
+ expect(code).toContain('_isFunctionNode');
81
+ expect(code).toContain('_nodeName');
82
+ });
83
+
84
+ it('should compile function node with destructured parameters', () => {
85
+ const node = {
86
+ id: 'func3',
87
+ name: 'DestructuredFunction',
88
+ content: {
89
+ source: 'export const handler = ({ input, helpers }) => ({ output: input })',
90
+ },
91
+ parsedContent: {
92
+ source: 'export const handler = ({ input, helpers }) => ({ output: input })',
93
+ parameters: ['input', 'helpers'],
94
+ ast: null,
95
+ },
96
+ };
97
+
98
+ const context = createMockContext({
99
+ nodes: parseJDM('{"nodes": [], "edges": []}').nodes,
100
+ edges: parseJDM('{"nodes": [], "edges": []}').edges,
101
+ options: { optimize: true, debug: false, validate: false },
102
+ parseExpression: parseStandardExpression,
103
+ parseUnaryExpression: (expr: string) => parseStandardExpression(expr),
104
+ getUniqueId: createCounterIdGenerator(),
105
+ loadDecision: () => parseJDM('{"nodes": [], "edges": []}'),
106
+ functionSources: new Map(),
107
+ });
108
+
109
+ const code = compileFunctionNode(node, context);
110
+
111
+ expect(code).toContain('let input = ctx.get("input");');
112
+ expect(code).toContain('let helpers = ctx.get("helpers");');
113
+ });
114
+
115
+ it('should compile function node with no parameters', () => {
116
+ const node = {
117
+ id: 'func4',
118
+ name: 'NoParamFunction',
119
+ content: {
120
+ source: 'export const handler = () => ({ output: "test" })',
121
+ },
122
+ parsedContent: {
123
+ source: 'export const handler = () => ({ output: "test" })',
124
+ parameters: [],
125
+ ast: null,
126
+ },
127
+ };
128
+
129
+ const context = createMockContext({
130
+ nodes: parseJDM('{"nodes": [], "edges": []}').nodes,
131
+ edges: parseJDM('{"nodes": [], "edges": []}').edges,
132
+ options: { optimize: true, debug: false, validate: false },
133
+ parseExpression: parseStandardExpression,
134
+ parseUnaryExpression: (expr: string) => parseStandardExpression(expr),
135
+ getUniqueId: createCounterIdGenerator(),
136
+ loadDecision: () => parseJDM('{"nodes": [], "edges": []}'),
137
+ functionSources: new Map(),
138
+ });
139
+
140
+ const code = compileFunctionNode(node, context);
141
+
142
+ expect(code).toContain('No parameters');
143
+ expect(code).not.toContain('ctx.get("'); // Should have no parameter reads
144
+ expect(code).toContain('let result = Value.Object(mockResult);');
145
+ });
146
+
147
+ it('should store function source in context', () => {
148
+ const node = {
149
+ id: 'func5',
150
+ name: 'SourceStorageFunction',
151
+ content: {
152
+ source: 'export const handler = (input) => ({ output: input })',
153
+ },
154
+ parsedContent: {
155
+ source: 'export const handler = (input) => ({ output: input })',
156
+ parameters: ['input'],
157
+ ast: null,
158
+ },
159
+ };
160
+
161
+ const functionSources = new Map<string, string>();
162
+ const context = createMockContext({
163
+ nodes: parseJDM('{"nodes": [], "edges": []}').nodes,
164
+ edges: parseJDM('{"nodes": [], "edges": []}').edges,
165
+ options: { optimize: true, debug: false, validate: false },
166
+ parseExpression: parseStandardExpression,
167
+ parseUnaryExpression: (expr: string) => parseStandardExpression(expr),
168
+ getUniqueId: createCounterIdGenerator(),
169
+ loadDecision: () => parseJDM('{"nodes": [], "edges": []}'),
170
+ functionSources,
171
+ });
172
+
173
+ compileFunctionNode(node, context);
174
+
175
+ expect(functionSources.has('func5')).toBe(true);
176
+ expect(functionSources.get('func5')).toBe(
177
+ 'export const handler = (input) => ({ output: input })',
178
+ );
179
+ });
180
+
181
+ it('should throw error if parsedContent is missing', () => {
182
+ const node = {
183
+ id: 'func6',
184
+ name: 'UnparsedFunction',
185
+ content: {
186
+ source: 'export const handler = (input) => ({ output: input })',
187
+ },
188
+ };
189
+
190
+ const context = createMockContext({
191
+ nodes: parseJDM('{"nodes": [], "edges": []}').nodes,
192
+ edges: parseJDM('{"nodes": [], "edges": []}').edges,
193
+ options: { optimize: true, debug: false, validate: false },
194
+ parseExpression: parseStandardExpression,
195
+ parseUnaryExpression: (expr: string) => parseStandardExpression(expr),
196
+ getUniqueId: createCounterIdGenerator(),
197
+ loadDecision: () => parseJDM('{"nodes": [], "edges": []}'),
198
+ functionSources: new Map(),
199
+ });
200
+
201
+ expect(() => compileFunctionNode(node, context)).toThrow(CompilationError);
202
+ expect(() => compileFunctionNode(node, context)).toThrow('has not been parsed');
203
+ });
204
+ });
@@ -0,0 +1,176 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import {
3
+ validateFunctionNode,
4
+ extractFunctionSource,
5
+ parseFunctionCode,
6
+ } from '../../../../src/compiler/nodes/function.js';
7
+ import type { FunctionNodeContent } from '../../../../src/compiler/nodes/function.js';
8
+
9
+ describe('Function Node Parsing', () => {
10
+ describe('extractFunctionSource', () => {
11
+ it('should extract source from v2 format (object with source property)', () => {
12
+ const content = {
13
+ source: 'export const handler = (input) => ({ output: input })',
14
+ };
15
+ const source = extractFunctionSource(content);
16
+ expect(source).toBe('export const handler = (input) => ({ output: input })');
17
+ });
18
+
19
+ it('should extract source from legacy format (plain string)', () => {
20
+ const content = 'export const handler = (input) => ({ output: input })';
21
+ const source = extractFunctionSource(content);
22
+ expect(source).toBe('export const handler = (input) => ({ output: input })');
23
+ });
24
+
25
+ it('should throw error for missing content', () => {
26
+ expect(() => extractFunctionSource(null)).toThrow('Function node content is missing');
27
+ expect(() => extractFunctionSource(undefined)).toThrow('Function node content is missing');
28
+ });
29
+
30
+ it('should throw error for invalid content format', () => {
31
+ const content = { invalid: 'format' };
32
+ expect(() => extractFunctionSource(content)).toThrow(
33
+ 'must be either a string or an object with a source property',
34
+ );
35
+ });
36
+
37
+ it('should throw error when source property is not a string', () => {
38
+ const content = { source: 123 };
39
+ expect(() => extractFunctionSource(content)).toThrow('content.source must be a string');
40
+ });
41
+ });
42
+
43
+ describe('parseFunctionCode', () => {
44
+ it('should parse arrow function with single parameter', () => {
45
+ const source = 'export const handler = (input) => ({ output: input })';
46
+ const parsed = parseFunctionCode(source);
47
+ expect(parsed.source).toBe(source);
48
+ expect(parsed.parameters).toEqual(['input']);
49
+ expect(parsed.ast).toBeDefined();
50
+ });
51
+
52
+ it('should parse arrow function with multiple parameters', () => {
53
+ const source = 'export const handler = (input, context) => ({ output: input })';
54
+ const parsed = parseFunctionCode(source);
55
+ expect(parsed.parameters).toEqual(['input', 'context']);
56
+ });
57
+
58
+ it('should parse function declaration', () => {
59
+ const source = 'export function handler(input) { return { output: input }; }';
60
+ const parsed = parseFunctionCode(source);
61
+ expect(parsed.parameters).toEqual(['input']);
62
+ });
63
+
64
+ it('should parse function expression', () => {
65
+ const source = 'export const handler = function(input) { return { output: input }; }';
66
+ const parsed = parseFunctionCode(source);
67
+ expect(parsed.parameters).toEqual(['input']);
68
+ });
69
+
70
+ it('should parse function with destructured parameters', () => {
71
+ const source = 'export const handler = ({ input, context }) => ({ output: input })';
72
+ const parsed = parseFunctionCode(source);
73
+ expect(parsed.parameters).toEqual(['input', 'context']);
74
+ });
75
+
76
+ it('should parse function with array destructuring', () => {
77
+ const source = 'export const handler = ([input, context]) => ({ output: input })';
78
+ const parsed = parseFunctionCode(source);
79
+ expect(parsed.parameters).toEqual(['input', 'context']);
80
+ });
81
+
82
+ it('should handle function with no parameters', () => {
83
+ const source = 'export const handler = () => ({ output: "test" })';
84
+ const parsed = parseFunctionCode(source);
85
+ expect(parsed.parameters).toEqual([]);
86
+ });
87
+
88
+ it('should handle complex function with helpers', () => {
89
+ const source = 'export const handler = (input, { moment, env }) => ({ output: input })';
90
+ const parsed = parseFunctionCode(source);
91
+ expect(parsed.parameters).toEqual(['input', 'moment', 'env']);
92
+ });
93
+
94
+ it('should parse async function', () => {
95
+ const source = 'export const handler = async (input) => ({ output: await fetch(input) })';
96
+ const parsed = parseFunctionCode(source);
97
+ expect(parsed.parameters).toEqual(['input']);
98
+ });
99
+
100
+ it('should throw error for invalid JavaScript syntax', () => {
101
+ const source = 'this is not valid javascript {{{';
102
+ expect(() => parseFunctionCode(source)).toThrow('Failed to parse function code');
103
+ });
104
+
105
+ it('should extract function from mixed module code', () => {
106
+ const source = `
107
+ import { helper } from './helper.js';
108
+
109
+ export const handler = (input) => {
110
+ return helper(input);
111
+ };
112
+ `;
113
+ const parsed = parseFunctionCode(source);
114
+ expect(parsed.parameters).toEqual(['input']);
115
+ });
116
+ });
117
+
118
+ describe('validateFunctionNode', () => {
119
+ it('should validate function node with valid content', () => {
120
+ const node = {
121
+ id: 'func1',
122
+ name: 'TestFunction',
123
+ content: {
124
+ source: 'export const handler = (input) => ({ output: input })',
125
+ },
126
+ };
127
+ const result = validateFunctionNode(node);
128
+ expect(result.source).toContain('export const handler');
129
+ expect(result.parameters).toEqual(['input']);
130
+ expect(result.ast).toBeDefined();
131
+ });
132
+
133
+ it('should throw error for function node with missing content', () => {
134
+ const node = {
135
+ id: 'func1',
136
+ name: 'TestFunction',
137
+ };
138
+ expect(() => validateFunctionNode(node)).toThrow('missing required content field');
139
+ });
140
+
141
+ it('should throw error for function node with invalid syntax', () => {
142
+ const node = {
143
+ id: 'func1',
144
+ name: 'TestFunction',
145
+ content: {
146
+ source: 'invalid javascript syntax {{{',
147
+ },
148
+ };
149
+ expect(() => validateFunctionNode(node)).toThrow('Failed to parse function code');
150
+ });
151
+
152
+ it('should validate legacy format function node', () => {
153
+ const node = {
154
+ id: 'func1',
155
+ name: 'TestFunction',
156
+ content: 'export const handler = (input) => ({ output: input })',
157
+ };
158
+ const result = validateFunctionNode(node);
159
+ expect(result.source).toContain('export const handler');
160
+ expect(result.parameters).toEqual(['input']);
161
+ });
162
+ });
163
+
164
+ describe('FunctionNodeContent interface', () => {
165
+ it('should have correct structure', () => {
166
+ const content: FunctionNodeContent = {
167
+ source: 'test source',
168
+ parameters: ['input', 'context'],
169
+ ast: null,
170
+ };
171
+ expect(content.source).toBe('test source');
172
+ expect(content.parameters).toEqual(['input', 'context']);
173
+ expect(content.ast).toBeNull();
174
+ });
175
+ });
176
+ });
@@ -0,0 +1,30 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { compileInputNode } from '../../../../src/compiler/nodes/input';
3
+ import { NodeType, type JDMNode } from '../../../../src/compiler/parser';
4
+ import { createMockContext } from '../../../helpers';
5
+
6
+ /**
7
+ * Input Node Compilation Tests
8
+ *
9
+ * These tests verify that the input node compiler produces valid output.
10
+ * The actual behavior of the generated code is tested through integration tests.
11
+ */
12
+ describe('Input Node Compilation', () => {
13
+ describe('compileInputNode', () => {
14
+ it('should generate code for an input node', () => {
15
+ const node: JDMNode = {
16
+ id: 'input1',
17
+ type: NodeType.INPUT,
18
+ name: 'Input Node',
19
+ position: { x: 0, y: 0 },
20
+ };
21
+
22
+ const context = createMockContext();
23
+ const code = compileInputNode(node, context);
24
+
25
+ // Verify code is generated
26
+ expect(typeof code).toBe('string');
27
+ expect(code.length).toBeGreaterThan(0);
28
+ });
29
+ });
30
+ });
@@ -0,0 +1,127 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { compileSwitchNode } from '../../../../src/compiler/nodes/switch';
3
+ import { NodeType, type JDMNode } from '../../../../src/compiler/parser';
4
+ import { createMockContext } from '../../../helpers';
5
+
6
+ /**
7
+ * Switch Node Compilation Tests
8
+ *
9
+ * These tests verify the compiler's validation and error handling for switch nodes.
10
+ * The actual code generation behavior is tested through integration tests that compile
11
+ * and execute the generated code.
12
+ */
13
+ describe('Switch Node Compilation', () => {
14
+ describe('compileSwitchNode', () => {
15
+ // Custom parseExpression for switch node tests
16
+ const parseExpression = (expr: string) => {
17
+ // Return a simple AST for basic expressions
18
+ if (expr === 'true' || expr === 'false') {
19
+ return { type: 'BooleanLiteral', value: expr === 'true' };
20
+ }
21
+ if (expr.includes('could not parse')) {
22
+ throw new Error('Parse error');
23
+ }
24
+ // Default to a boolean literal for simplicity in tests
25
+ return { type: 'BooleanLiteral', value: true };
26
+ };
27
+
28
+ const createSwitchNode = (
29
+ id: string,
30
+ statements: Array<{ id: string; condition: string }>,
31
+ hitPolicy?: string,
32
+ extraFields?: Record<string, any>,
33
+ ): JDMNode => ({
34
+ id,
35
+ type: NodeType.SWITCH,
36
+ name: 'Switch Node',
37
+ position: { x: 0, y: 0 },
38
+ content: {
39
+ statements,
40
+ hitPolicy: hitPolicy as any,
41
+ ...extraFields,
42
+ },
43
+ });
44
+
45
+ it('should generate code for a switch node', () => {
46
+ const node = createSwitchNode('switch-1', []);
47
+ const context = createMockContext({ parseExpression });
48
+ const code = compileSwitchNode(node, context);
49
+
50
+ expect(typeof code).toBe('string');
51
+ expect(code.length).toBeGreaterThan(0);
52
+ });
53
+
54
+ it('should generate code with different hit policies', () => {
55
+ const policies = ['first', 'collect', 'ruleOrder', 'outputOrder', 'priority'];
56
+
57
+ for (const policy of policies) {
58
+ const node = createSwitchNode(`switch-${policy}`, [{ id: 'cond1', condition: 'true' }]);
59
+ node.content.hitPolicy = policy;
60
+
61
+ const context = createMockContext({
62
+ parseExpression,
63
+ edges: [
64
+ {
65
+ id: 'edge1',
66
+ type: 'edge',
67
+ sourceId: `switch-${policy}`,
68
+ targetId: 'nodeA',
69
+ sourceHandle: 'cond1',
70
+ },
71
+ ],
72
+ });
73
+
74
+ const code = compileSwitchNode(node, context);
75
+ expect(code.length).toBeGreaterThan(0);
76
+ }
77
+ });
78
+
79
+ it('should gracefully handle parse errors in expressions', () => {
80
+ const node = createSwitchNode('switch-error', [
81
+ { id: 'cond1', condition: 'could not parse' },
82
+ ]);
83
+
84
+ const context = createMockContext({
85
+ parseExpression,
86
+ edges: [
87
+ {
88
+ id: 'edge1',
89
+ type: 'edge',
90
+ sourceId: 'switch-error',
91
+ targetId: 'node1',
92
+ sourceHandle: 'cond1',
93
+ },
94
+ ],
95
+ });
96
+
97
+ const code = compileSwitchNode(node, context);
98
+
99
+ // Should include error comment in generated code
100
+ expect(code).toContain('/* ERROR: Could not parse expression */');
101
+ });
102
+
103
+ it('should compile successfully when RETURN_DEFAULT is used with a value', () => {
104
+ const node = createSwitchNode('switch-no-match-default-with-value', [
105
+ { id: 'cond1', condition: 'false' },
106
+ ]);
107
+ node.content.noMatchBehavior = { type: 'returnDefault', value: 'default-value' };
108
+
109
+ const context = createMockContext({
110
+ parseExpression,
111
+ edges: [
112
+ {
113
+ id: 'edge1',
114
+ type: 'edge',
115
+ sourceId: 'switch-no-match-default-with-value',
116
+ targetId: 'node1',
117
+ sourceHandle: 'cond1',
118
+ },
119
+ ],
120
+ });
121
+
122
+ const code = compileSwitchNode(node, context);
123
+ expect(code).toContain('Value.String("default-value")');
124
+ expect(code).not.toContain('Value.Null()');
125
+ });
126
+ });
127
+ });