@divmain/jdm-asm 0.2.1 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (395) hide show
  1. package/dist/index.js +2227 -29
  2. package/dist/index.js.map +1 -1
  3. package/package.json +8 -2
  4. package/.github/workflows/ci.yml +0 -53
  5. package/.oxfmtrc.json +0 -16
  6. package/.oxlintrc.json +0 -183
  7. package/AGENTS.md +0 -81
  8. package/asconfig.json +0 -23
  9. package/benchmarks/fixtures.ts +0 -111
  10. package/benchmarks/input-fixtures.ts +0 -80
  11. package/benchmarks/run.ts +0 -913
  12. package/benchmarks/worker-pool.ts +0 -223
  13. package/benchmarks/worker.ts +0 -374
  14. package/scripts/run-all-tests.ts +0 -220
  15. package/src/compiler/EXPRESSION_SUBSETS.md +0 -228
  16. package/src/compiler/asc-compiler.ts +0 -315
  17. package/src/compiler/ast-types.ts +0 -215
  18. package/src/compiler/build.ts +0 -56
  19. package/src/compiler/cache.ts +0 -414
  20. package/src/compiler/code-generators.ts +0 -211
  21. package/src/compiler/codegen/index.ts +0 -15
  22. package/src/compiler/codegen/js-marshal.ts +0 -999
  23. package/src/compiler/codegen/js-validation.ts +0 -243
  24. package/src/compiler/codegen.ts +0 -19
  25. package/src/compiler/compile-time-validation.ts +0 -507
  26. package/src/compiler/cst-visitor.ts +0 -434
  27. package/src/compiler/errors.ts +0 -227
  28. package/src/compiler/expression-parser.ts +0 -536
  29. package/src/compiler/graph.ts +0 -197
  30. package/src/compiler/index.ts +0 -199
  31. package/src/compiler/input-validation.ts +0 -33
  32. package/src/compiler/marshal-gen.ts +0 -21
  33. package/src/compiler/nodes/context-resolvers.ts +0 -197
  34. package/src/compiler/nodes/decision-table.ts +0 -507
  35. package/src/compiler/nodes/decision.ts +0 -292
  36. package/src/compiler/nodes/expression-compiler.ts +0 -526
  37. package/src/compiler/nodes/expression.ts +0 -425
  38. package/src/compiler/nodes/function.ts +0 -316
  39. package/src/compiler/nodes/input.ts +0 -60
  40. package/src/compiler/nodes/switch.ts +0 -547
  41. package/src/compiler/optimizer.ts +0 -948
  42. package/src/compiler/orchestrator.ts +0 -352
  43. package/src/compiler/parser.ts +0 -115
  44. package/src/compiler/result-selection.ts +0 -161
  45. package/src/compiler/runtime/index.ts +0 -26
  46. package/src/compiler/runtime-codegen.ts +0 -211
  47. package/src/compiler/runtime-validation-codegen.ts +0 -294
  48. package/src/compiler/runtime.ts +0 -452
  49. package/src/compiler/schema.ts +0 -245
  50. package/src/compiler/switch-branch-detection.ts +0 -92
  51. package/src/compiler/types.ts +0 -136
  52. package/src/compiler/unary-ast-transforms.ts +0 -148
  53. package/src/compiler/unary-parser.ts +0 -301
  54. package/src/compiler/unary-transform.ts +0 -161
  55. package/src/compiler/utils.ts +0 -27
  56. package/src/compiler/virtual-fs.ts +0 -90
  57. package/src/compiler/wasm-instantiate.ts +0 -127
  58. package/src/index.ts +0 -1
  59. package/src/runtime/arrays.ts +0 -579
  60. package/src/runtime/context.ts +0 -189
  61. package/src/runtime/expressions.ts +0 -1811
  62. package/src/runtime/index.ts +0 -8
  63. package/src/runtime/memory.ts +0 -607
  64. package/src/runtime/strings.ts +0 -260
  65. package/src/runtime/tables.ts +0 -96
  66. package/src/runtime/tsconfig.json +0 -4
  67. package/src/runtime/values.ts +0 -209
  68. package/test-data/README.md +0 -83
  69. package/test-data/decision-tables/basic/8k.json +0 -87992
  70. package/test-data/decision-tables/basic/affiliate-commission-calculator.json +0 -228
  71. package/test-data/decision-tables/basic/airline-loyalty-points-calculations.json +0 -285
  72. package/test-data/decision-tables/basic/airline-upgrade-eligibility.json +0 -466
  73. package/test-data/decision-tables/basic/auto-insurance-premium-calculator.json +0 -412
  74. package/test-data/decision-tables/basic/booking-personalization-system.json +0 -553
  75. package/test-data/decision-tables/basic/care-team-assignment-system.json +0 -585
  76. package/test-data/decision-tables/basic/claim-validation-system.json +0 -307
  77. package/test-data/decision-tables/basic/clinical-lab-result-interpreter.json +0 -433
  78. package/test-data/decision-tables/basic/clinical-treatment-protocol.json +0 -474
  79. package/test-data/decision-tables/basic/credit-limit-adjustment.json +0 -479
  80. package/test-data/decision-tables/basic/customer-eligibility-engine.json +0 -551
  81. package/test-data/decision-tables/basic/customer-lifetime-value.json +0 -200
  82. package/test-data/decision-tables/basic/customer-onboarding-kyc-verification.json +0 -611
  83. package/test-data/decision-tables/basic/customer-service-escalation.json +0 -191
  84. package/test-data/decision-tables/basic/decision-table-discounts.json +0 -168
  85. package/test-data/decision-tables/basic/decision-table-shipping.json +0 -398
  86. package/test-data/decision-tables/basic/delivery-route-optimizer.json +0 -271
  87. package/test-data/decision-tables/basic/device-compatibility-checker.json +0 -303
  88. package/test-data/decision-tables/basic/disaster-relief-fund-allocation.json +0 -296
  89. package/test-data/decision-tables/basic/dynamic-fx-rate-pricing-system.json +0 -237
  90. package/test-data/decision-tables/basic/dynamic-marketplace-comission-calculator.json +0 -242
  91. package/test-data/decision-tables/basic/dynamic-shipping-cost-calculator.json +0 -378
  92. package/test-data/decision-tables/basic/dynamic-tarrif-engine.json +0 -289
  93. package/test-data/decision-tables/basic/dynamic-ticket-pricing.json +0 -325
  94. package/test-data/decision-tables/basic/empty-column-with-space.json +0 -100
  95. package/test-data/decision-tables/basic/empty-column-without-space.json +0 -100
  96. package/test-data/decision-tables/basic/environment-compliance-assessment.json +0 -386
  97. package/test-data/decision-tables/basic/expression-table-map.json +0 -313
  98. package/test-data/decision-tables/basic/flash-sale-eligibility.json +0 -366
  99. package/test-data/decision-tables/basic/flight-dispatch-decision-system.json +0 -455
  100. package/test-data/decision-tables/basic/flight-rebooking-fee-calculator.json +0 -406
  101. package/test-data/decision-tables/basic/government-assistance.json +0 -299
  102. package/test-data/decision-tables/basic/grant-funding-distribution.json +0 -307
  103. package/test-data/decision-tables/basic/hazardous-materials-management-system.json +0 -414
  104. package/test-data/decision-tables/basic/immigration-eligibility-evaluator.json +0 -765
  105. package/test-data/decision-tables/basic/import-duties-calculator.json +0 -318
  106. package/test-data/decision-tables/basic/insurance-agent-commission.json +0 -228
  107. package/test-data/decision-tables/basic/insurance-coverage-calculator.json +0 -362
  108. package/test-data/decision-tables/basic/insurance-underwriting-risk.json +0 -321
  109. package/test-data/decision-tables/basic/international-roaming-policy-manager.json +0 -199
  110. package/test-data/decision-tables/basic/legacy-plan-management.json +0 -434
  111. package/test-data/decision-tables/basic/marketplace-listing-verification-system.json +0 -334
  112. package/test-data/decision-tables/basic/medication-dosage-calculator.json +0 -318
  113. package/test-data/decision-tables/basic/merch-bags.json +0 -171
  114. package/test-data/decision-tables/basic/municipal-permit-evaluation-system.json +0 -364
  115. package/test-data/decision-tables/basic/mvno-partner-enablement.json +0 -313
  116. package/test-data/decision-tables/basic/partner-revenue-sharing.json +0 -244
  117. package/test-data/decision-tables/basic/payment-routing-and-fee-calculator.json +0 -475
  118. package/test-data/decision-tables/basic/policy-discount-calculator.json +0 -307
  119. package/test-data/decision-tables/basic/policy-eligibility-analyzer.json +0 -299
  120. package/test-data/decision-tables/basic/product-listing-scoring.json +0 -358
  121. package/test-data/decision-tables/basic/realtime-fraud-detection.json +0 -235
  122. package/test-data/decision-tables/basic/regional-compliance-manager.json +0 -278
  123. package/test-data/decision-tables/basic/returns-and-refund-policy.json +0 -366
  124. package/test-data/decision-tables/basic/returns-processing-system.json +0 -448
  125. package/test-data/decision-tables/basic/school-district-resource-allocation.json +0 -282
  126. package/test-data/decision-tables/basic/seat-map-optimization.json +0 -325
  127. package/test-data/decision-tables/basic/seller-fee-calculator.json +0 -307
  128. package/test-data/decision-tables/basic/service-level-agreement-enforcement.json +0 -575
  129. package/test-data/decision-tables/basic/smart-financial-product-matcher.json +0 -249
  130. package/test-data/decision-tables/basic/supply-chain-risk.json +0 -316
  131. package/test-data/decision-tables/basic/table-loop.json +0 -93
  132. package/test-data/decision-tables/basic/table.json +0 -76
  133. package/test-data/decision-tables/basic/traffic-violation-penalty-calculator.json +0 -436
  134. package/test-data/decision-tables/basic/transaction-compliance-classifier.json +0 -525
  135. package/test-data/decision-tables/basic/vehicle-claims-resolution.json +0 -310
  136. package/test-data/decision-tables/basic/warehouse-storage-location.json +0 -345
  137. package/test-data/decision-tables/hit-policy-collect/collect-multiple-matches.json +0 -127
  138. package/test-data/decision-tables/hit-policy-collect/collect-no-match.json +0 -95
  139. package/test-data/decision-tables/hit-policy-first/first-match.json +0 -103
  140. package/test-data/decision-tables/hit-policy-first/no-match.json +0 -95
  141. package/test-data/decision-tables/hit-policy-output-order/output-order-respected.json +0 -94
  142. package/test-data/decision-tables/hit-policy-output-order/string-output-order.json +0 -94
  143. package/test-data/decision-tables/hit-policy-priority/priority-respected.json +0 -86
  144. package/test-data/decision-tables/hit-policy-rule-order/rule-order-respected.json +0 -94
  145. package/test-data/decision-tables/hit-policy-unique/all-match-error.json +0 -89
  146. package/test-data/decision-tables/hit-policy-unique/multiple-match-error.json +0 -89
  147. package/test-data/decision-tables/hit-policy-unique/no-match.json +0 -88
  148. package/test-data/decision-tables/hit-policy-unique/unique-match.json +0 -99
  149. package/test-data/expressions/arithmetic/error-cyclic.json +0 -114
  150. package/test-data/expressions/arithmetic/error-missing-input.json +0 -54
  151. package/test-data/expressions/arithmetic/error-missing-output.json +0 -54
  152. package/test-data/expressions/arithmetic/expression-default.json +0 -93
  153. package/test-data/expressions/arithmetic/expression-fields.json +0 -94
  154. package/test-data/expressions/arithmetic/expression-loop.json +0 -94
  155. package/test-data/expressions/arithmetic/expression-passthrough.json +0 -108
  156. package/test-data/expressions/arithmetic/expression.json +0 -69
  157. package/test-data/expressions/arithmetic/nested-request.json +0 -125
  158. package/test-data/expressions/arithmetic/number-function.json +0 -58
  159. package/test-data/expressions/arithmetic/test-number-functions.json +0 -68
  160. package/test-data/expressions/functions/all.json +0 -149
  161. package/test-data/expressions/functions/avg.json +0 -89
  162. package/test-data/expressions/functions/filter.json +0 -109
  163. package/test-data/expressions/functions/flat.json +0 -167
  164. package/test-data/expressions/functions/map-strings.json +0 -65
  165. package/test-data/expressions/functions/map.json +0 -73
  166. package/test-data/expressions/functions/reduce.json +0 -49
  167. package/test-data/expressions/functions/some.json +0 -175
  168. package/test-data/expressions/functions/sort-strings.json +0 -97
  169. package/test-data/expressions/functions/sort.json +0 -97
  170. package/test-data/expressions/logical/logical-and.json +0 -116
  171. package/test-data/expressions/logical/logical-complex.json +0 -260
  172. package/test-data/expressions/logical/logical-not.json +0 -111
  173. package/test-data/expressions/logical/logical-or.json +0 -123
  174. package/test-data/expressions/string/string-comparison.json +0 -128
  175. package/test-data/expressions/string/string-concat.json +0 -106
  176. package/test-data/expressions/string/string-contains.json +0 -125
  177. package/test-data/expressions/string/string-endsWith.json +0 -113
  178. package/test-data/expressions/string/string-indexOf.json +0 -131
  179. package/test-data/expressions/string/string-join.json +0 -92
  180. package/test-data/expressions/string/string-lower.json +0 -94
  181. package/test-data/expressions/string/string-replace.json +0 -130
  182. package/test-data/expressions/string/string-split.json +0 -101
  183. package/test-data/expressions/string/string-startsWith.json +0 -113
  184. package/test-data/expressions/string/string-substring.json +0 -138
  185. package/test-data/expressions/string/string-trim.json +0 -100
  186. package/test-data/expressions/string/string-upper.json +0 -94
  187. package/test-data/other/custom.json +0 -51
  188. package/test-data/other/customer-input-schema.json +0 -34
  189. package/test-data/other/customer-output-schema.json +0 -34
  190. package/test-data/other/passthrough.json +0 -31
  191. package/test-data/sub-decisions/basic/$nodes-child.json +0 -31
  192. package/test-data/sub-decisions/basic/$nodes-parent.json +0 -49
  193. package/test-data/sub-decisions/basic/recursive-table1.json +0 -49
  194. package/test-data/sub-decisions/basic/recursive-table2.json +0 -49
  195. package/test-data/sub-decisions/complex-multi/approval-decision.json +0 -31
  196. package/test-data/sub-decisions/complex-multi/complex-dag.json +0 -175
  197. package/test-data/sub-decisions/complex-multi/credit-check.json +0 -31
  198. package/test-data/sub-decisions/complex-multi/customer-segmentation.json +0 -31
  199. package/test-data/sub-decisions/complex-multi/discount-eligibility.json +0 -31
  200. package/test-data/sub-decisions/complex-multi/eligibility-check.json +0 -31
  201. package/test-data/sub-decisions/complex-multi/final-offer.json +0 -31
  202. package/test-data/sub-decisions/complex-multi/income-verification.json +0 -31
  203. package/test-data/sub-decisions/complex-multi/linear-chain.json +0 -121
  204. package/test-data/sub-decisions/complex-multi/pricing-calculation.json +0 -31
  205. package/test-data/sub-decisions/complex-multi/product-eligibility.json +0 -31
  206. package/test-data/sub-decisions/complex-multi/risk-assessment.json +0 -31
  207. package/test-data/sub-decisions/complex-multi/shared-validation.json +0 -31
  208. package/test-data/sub-decisions/complex-multi/validation.json +0 -31
  209. package/test-data/sub-decisions/diamond/decision-a.json +0 -31
  210. package/test-data/sub-decisions/diamond/decision-b.json +0 -31
  211. package/test-data/sub-decisions/diamond/decision-c.json +0 -31
  212. package/test-data/sub-decisions/diamond/decision-shared.json +0 -31
  213. package/test-data/sub-decisions/diamond/diamond-pattern.json +0 -109
  214. package/test-data/sub-decisions/error-propagation/parent-calls-error.json +0 -44
  215. package/test-data/sub-decisions/error-propagation/sub-decision-with-error.json +0 -60
  216. package/test-data/switch-nodes/basic/account-dormancy-management.json +0 -245
  217. package/test-data/switch-nodes/basic/application-risk-assessment.json +0 -474
  218. package/test-data/switch-nodes/basic/cellular-data-rollover-system.json +0 -281
  219. package/test-data/switch-nodes/basic/clinical-pathway-selection.json +0 -454
  220. package/test-data/switch-nodes/basic/insurance-prior-authorization.json +0 -467
  221. package/test-data/switch-nodes/basic/last-mile-delivery-assignment.json +0 -373
  222. package/test-data/switch-nodes/basic/loan-approval.json +0 -469
  223. package/test-data/switch-nodes/basic/multi-switch.json +0 -498
  224. package/test-data/switch-nodes/basic/online-checkin-eligibility.json +0 -285
  225. package/test-data/switch-nodes/basic/order-consolidation-system.json +0 -493
  226. package/test-data/switch-nodes/basic/seller-approval-workflow.json +0 -383
  227. package/test-data/switch-nodes/basic/set-fee.json +0 -243
  228. package/test-data/switch-nodes/basic/shipping-carrier-selector.json +0 -379
  229. package/test-data/switch-nodes/basic/switch-node.json +0 -167
  230. package/test-data/switch-nodes/basic/switch-performance-2.json +0 -1307
  231. package/test-data/switch-nodes/basic/switch-performance.json +0 -691
  232. package/test-data/switch-nodes/basic/tax-exemption.json +0 -295
  233. package/test-data/switch-nodes/basic/warehouse-cross-docking.json +0 -313
  234. package/test-data/switch-nodes/default-cases/switch-with-default.json +0 -134
  235. package/test-data/zen-reference/$nodes-child.json +0 -69
  236. package/test-data/zen-reference/$nodes-parent.json +0 -34
  237. package/test-data/zen-reference/8k.json +0 -87992
  238. package/test-data/zen-reference/credit-analysis.json +0 -324
  239. package/test-data/zen-reference/custom.json +0 -51
  240. package/test-data/zen-reference/customer-input-schema.json +0 -34
  241. package/test-data/zen-reference/customer-output-schema.json +0 -34
  242. package/test-data/zen-reference/error-cyclic.json +0 -114
  243. package/test-data/zen-reference/error-missing-input.json +0 -54
  244. package/test-data/zen-reference/error-missing-output.json +0 -54
  245. package/test-data/zen-reference/expression.json +0 -69
  246. package/test-data/zen-reference/function-v2.json +0 -48
  247. package/test-data/zen-reference/function.json +0 -46
  248. package/test-data/zen-reference/graphs/account-dormancy-management.json +0 -245
  249. package/test-data/zen-reference/graphs/affiliate-commission-calculator.json +0 -228
  250. package/test-data/zen-reference/graphs/airline-loyalty-points-calculations.json +0 -285
  251. package/test-data/zen-reference/graphs/airline-upgrade-eligibility.json +0 -466
  252. package/test-data/zen-reference/graphs/aml.json +0 -537
  253. package/test-data/zen-reference/graphs/application-risk-assessment.json +0 -474
  254. package/test-data/zen-reference/graphs/auto-insurance-premium-calculator.json +0 -412
  255. package/test-data/zen-reference/graphs/booking-personalization-system.json +0 -553
  256. package/test-data/zen-reference/graphs/care-team-assignment-system.json +0 -585
  257. package/test-data/zen-reference/graphs/cellular-data-rollover-system.json +0 -281
  258. package/test-data/zen-reference/graphs/claim-validation-system.json +0 -307
  259. package/test-data/zen-reference/graphs/clinical-lab-result-interpreter.json +0 -433
  260. package/test-data/zen-reference/graphs/clinical-pathway-selection.json +0 -454
  261. package/test-data/zen-reference/graphs/clinical-treatment-protocol.json +0 -474
  262. package/test-data/zen-reference/graphs/company-analysis.json +0 -390
  263. package/test-data/zen-reference/graphs/credit-limit-adjustment.json +0 -479
  264. package/test-data/zen-reference/graphs/customer-eligibility-engine.json +0 -551
  265. package/test-data/zen-reference/graphs/customer-lifetime-value.json +0 -200
  266. package/test-data/zen-reference/graphs/customer-onboarding-kyc-verification.json +0 -611
  267. package/test-data/zen-reference/graphs/customer-service-escalation.json +0 -191
  268. package/test-data/zen-reference/graphs/decision-table-discounts.json +0 -168
  269. package/test-data/zen-reference/graphs/decision-table-shipping.json +0 -398
  270. package/test-data/zen-reference/graphs/delivery-route-optimizer.json +0 -271
  271. package/test-data/zen-reference/graphs/device-compatibility-checker.json +0 -303
  272. package/test-data/zen-reference/graphs/disaster-relief-fund-allocation.json +0 -296
  273. package/test-data/zen-reference/graphs/dynamic-fx-rate-pricing-system.json +0 -237
  274. package/test-data/zen-reference/graphs/dynamic-marketplace-comission-calculator.json +0 -242
  275. package/test-data/zen-reference/graphs/dynamic-shipping-cost-calculator.json +0 -378
  276. package/test-data/zen-reference/graphs/dynamic-tarrif-engine.json +0 -289
  277. package/test-data/zen-reference/graphs/dynamic-ticket-pricing.json +0 -325
  278. package/test-data/zen-reference/graphs/empty-column-with-space.json +0 -100
  279. package/test-data/zen-reference/graphs/empty-column-without-space.json +0 -100
  280. package/test-data/zen-reference/graphs/environment-compliance-assessment.json +0 -386
  281. package/test-data/zen-reference/graphs/expression-default.json +0 -93
  282. package/test-data/zen-reference/graphs/expression-fields.json +0 -94
  283. package/test-data/zen-reference/graphs/expression-loop.json +0 -94
  284. package/test-data/zen-reference/graphs/expression-passthrough.json +0 -108
  285. package/test-data/zen-reference/graphs/expression-table-map.json +0 -313
  286. package/test-data/zen-reference/graphs/flash-sale-eligibility.json +0 -366
  287. package/test-data/zen-reference/graphs/flight-dispatch-decision-system.json +0 -455
  288. package/test-data/zen-reference/graphs/flight-rebooking-fee-calculator.json +0 -406
  289. package/test-data/zen-reference/graphs/government-assistance.json +0 -299
  290. package/test-data/zen-reference/graphs/grant-funding-distribution.json +0 -307
  291. package/test-data/zen-reference/graphs/hazardous-materials-management-system.json +0 -414
  292. package/test-data/zen-reference/graphs/immigration-eligibility-evaluator.json +0 -765
  293. package/test-data/zen-reference/graphs/import-duties-calculator.json +0 -318
  294. package/test-data/zen-reference/graphs/insurance-agent-commission.json +0 -228
  295. package/test-data/zen-reference/graphs/insurance-breakdown.json +0 -421
  296. package/test-data/zen-reference/graphs/insurance-coverage-calculator.json +0 -362
  297. package/test-data/zen-reference/graphs/insurance-prior-authorization.json +0 -467
  298. package/test-data/zen-reference/graphs/insurance-underwriting-risk.json +0 -321
  299. package/test-data/zen-reference/graphs/international-roaming-policy-manager.json +0 -199
  300. package/test-data/zen-reference/graphs/last-mile-delivery-assignment.json +0 -373
  301. package/test-data/zen-reference/graphs/legacy-plan-management.json +0 -434
  302. package/test-data/zen-reference/graphs/loan-approval.json +0 -469
  303. package/test-data/zen-reference/graphs/marketplace-listing-verification-system.json +0 -334
  304. package/test-data/zen-reference/graphs/medication-dosage-calculator.json +0 -318
  305. package/test-data/zen-reference/graphs/merch-bags.json +0 -171
  306. package/test-data/zen-reference/graphs/multi-switch.json +0 -498
  307. package/test-data/zen-reference/graphs/municipal-permit-evaluation-system.json +0 -364
  308. package/test-data/zen-reference/graphs/mvno-partner-enablement.json +0 -313
  309. package/test-data/zen-reference/graphs/nested-request.json +0 -125
  310. package/test-data/zen-reference/graphs/online-checkin-eligibility.json +0 -285
  311. package/test-data/zen-reference/graphs/order-consolidation-system.json +0 -493
  312. package/test-data/zen-reference/graphs/partner-revenue-sharing.json +0 -244
  313. package/test-data/zen-reference/graphs/payment-routing-and-fee-calculator.json +0 -475
  314. package/test-data/zen-reference/graphs/policy-discount-calculator.json +0 -307
  315. package/test-data/zen-reference/graphs/policy-eligibility-analyzer.json +0 -299
  316. package/test-data/zen-reference/graphs/product-listing-scoring.json +0 -358
  317. package/test-data/zen-reference/graphs/realtime-fraud-detection.json +0 -235
  318. package/test-data/zen-reference/graphs/regional-compliance-manager.json +0 -278
  319. package/test-data/zen-reference/graphs/returns-and-refund-policy.json +0 -366
  320. package/test-data/zen-reference/graphs/returns-processing-system.json +0 -448
  321. package/test-data/zen-reference/graphs/school-district-resource-allocation.json +0 -282
  322. package/test-data/zen-reference/graphs/seat-map-optimization.json +0 -325
  323. package/test-data/zen-reference/graphs/seller-approval-workflow.json +0 -383
  324. package/test-data/zen-reference/graphs/seller-fee-calculator.json +0 -307
  325. package/test-data/zen-reference/graphs/service-level-agreement-enforcement.json +0 -575
  326. package/test-data/zen-reference/graphs/set-fee.json +0 -243
  327. package/test-data/zen-reference/graphs/shipping-carrier-selector.json +0 -379
  328. package/test-data/zen-reference/graphs/smart-financial-product-matcher.json +0 -249
  329. package/test-data/zen-reference/graphs/supply-chain-risk.json +0 -316
  330. package/test-data/zen-reference/graphs/table-loop.json +0 -93
  331. package/test-data/zen-reference/graphs/tax-exemption.json +0 -295
  332. package/test-data/zen-reference/graphs/traffic-violation-penalty-calculator.json +0 -436
  333. package/test-data/zen-reference/graphs/transaction-compliance-classifier.json +0 -525
  334. package/test-data/zen-reference/graphs/vehicle-claims-resolution.json +0 -310
  335. package/test-data/zen-reference/graphs/warehouse-cross-docking.json +0 -313
  336. package/test-data/zen-reference/graphs/warehouse-storage-location.json +0 -345
  337. package/test-data/zen-reference/http-function.json +0 -34
  338. package/test-data/zen-reference/infinite-function.json +0 -46
  339. package/test-data/zen-reference/js/imports.js +0 -25
  340. package/test-data/zen-reference/passthrough.json +0 -31
  341. package/test-data/zen-reference/recursive-table1.json +0 -49
  342. package/test-data/zen-reference/recursive-table2.json +0 -49
  343. package/test-data/zen-reference/sleep-function.json +0 -34
  344. package/test-data/zen-reference/switch-node.json +0 -167
  345. package/test-data/zen-reference/switch-performance-2.json +0 -1307
  346. package/test-data/zen-reference/switch-performance.json +0 -691
  347. package/test-data/zen-reference/table.json +0 -76
  348. package/tests/helpers/index.ts +0 -73
  349. package/tests/helpers/mock-context.ts +0 -231
  350. package/tests/helpers/round-trip.ts +0 -398
  351. package/tests/helpers/test-harness-comparison.ts +0 -325
  352. package/tests/helpers/test-harness-wasm.ts +0 -710
  353. package/tests/helpers/test-harness.ts +0 -28
  354. package/tests/helpers/wasm-test.ts +0 -659
  355. package/tests/integration/compilation-errors.test.ts +0 -864
  356. package/tests/integration/decision-tables.test.ts +0 -531
  357. package/tests/integration/edge-cases.test.ts +0 -787
  358. package/tests/integration/expressions.test.ts +0 -513
  359. package/tests/integration/function-node-integration.test.ts +0 -182
  360. package/tests/integration/sub-decisions.test.ts +0 -108
  361. package/tests/integration/switch-nodes.test.ts +0 -399
  362. package/tests/integration/unary-or-matching.test.ts +0 -53
  363. package/tests/integration/wasm-data-types.test.ts +0 -398
  364. package/tests/integration/wasm-errors.test.ts +0 -199
  365. package/tests/integration/wasm-execution.test.ts +0 -348
  366. package/tests/integration/wasm-memory.test.ts +0 -228
  367. package/tests/scripts/analyze-coverage.ts +0 -166
  368. package/tests/scripts/categorize-tests.ts +0 -396
  369. package/tests/scripts/coverage-analysis.ts +0 -836
  370. package/tests/unit/compiler/cache.test.ts +0 -238
  371. package/tests/unit/compiler/errors.test.ts +0 -316
  372. package/tests/unit/compiler/graph-scalability.test.ts +0 -510
  373. package/tests/unit/compiler/graph.test.ts +0 -878
  374. package/tests/unit/compiler/input-validation.test.ts +0 -447
  375. package/tests/unit/compiler/logical-and-parser.test.ts +0 -143
  376. package/tests/unit/compiler/logical-not-parser.test.ts +0 -107
  377. package/tests/unit/compiler/logical-or-parser.test.ts +0 -236
  378. package/tests/unit/compiler/marshal-gen/marshal-gen.test.ts +0 -97
  379. package/tests/unit/compiler/nodes/decision-table.test.ts +0 -103
  380. package/tests/unit/compiler/nodes/decision.test.ts +0 -182
  381. package/tests/unit/compiler/nodes/function-compile.test.ts +0 -204
  382. package/tests/unit/compiler/nodes/function.test.ts +0 -176
  383. package/tests/unit/compiler/nodes/input.test.ts +0 -30
  384. package/tests/unit/compiler/nodes/switch.test.ts +0 -127
  385. package/tests/unit/compiler/optimizer-cache.test.ts +0 -327
  386. package/tests/unit/compiler/optimizer-implementation.test.ts +0 -625
  387. package/tests/unit/compiler/parser.test.ts +0 -508
  388. package/tests/unit/compiler/runtime-error-cleanup.test.ts +0 -426
  389. package/tests/unit/compiler/runtime-validation.test.ts +0 -303
  390. package/tests/unit/compiler/runtime.test.ts +0 -221
  391. package/tests/unit/compiler/schema/schema.test.ts +0 -248
  392. package/tests/unit/compiler/unary-ast-transforms.test.ts +0 -245
  393. package/tsconfig.json +0 -27
  394. package/tsup.config.ts +0 -11
  395. package/vitest.config.ts +0 -12
package/benchmarks/run.ts DELETED
@@ -1,913 +0,0 @@
1
- /**
2
- * Performance Benchmark Runner
3
- *
4
- * Runs performance benchmarks comparing zen-engine vs jdm-asm using Mitata.
5
- * Supports both single-threaded and multi-threaded (concurrent) benchmarks.
6
- */
7
-
8
- import { readFileSync } from 'node:fs';
9
- import { cpus } from 'node:os';
10
- import { styleText } from 'node:util';
11
-
12
- import { run, bench, group, summary } from 'mitata';
13
- import { ZenEngine } from '@gorules/zen-engine';
14
- import { compile, type CompilationResult } from '../src/compiler';
15
- import { ReusableWasmEvaluator, inferSchema } from '../tests/helpers/test-harness-wasm';
16
- import { simpleInput, moderateInput, complexInput } from './input-fixtures';
17
- import { WorkerPool, LatencyTracker } from './worker-pool';
18
-
19
- // Uses simple string equality and numeric outputs
20
- const simpleJdm = readFileSync('test-data/decision-tables/basic/merch-bags.json', 'utf-8');
21
-
22
- // Uses more complex expressions like sum(map(...)) and contains($, ...)
23
- const moderateJdm = readFileSync('test-data/decision-tables/basic/decision-table-shipping.json', 'utf-8');
24
-
25
- // Complex: Large decision table with 8000+ rules
26
- const complexJdm = readFileSync('test-data/decision-tables/basic/8k.json', 'utf-8');
27
-
28
- // Initialize zen-engine
29
- console.log('Initializing benchmark engines...\n');
30
- const zenEngine = new ZenEngine();
31
-
32
- // Create zen-engine decisions (done once, outside benchmarks)
33
- console.log(' Loading zen-engine decisions...');
34
- const zenSimple = zenEngine.createDecision(JSON.parse(simpleJdm));
35
- const zenModerate = zenEngine.createDecision(JSON.parse(moderateJdm));
36
- const zenComplex = zenEngine.createDecision(JSON.parse(complexJdm));
37
-
38
- // Compiled jdm-asm decisions (using ReusableWasmEvaluator for proper hot path benchmarking)
39
- let asmSimple: ReusableWasmEvaluator;
40
- let asmModerate: ReusableWasmEvaluator;
41
- let asmComplex: ReusableWasmEvaluator;
42
-
43
- // Store compilation results for worker pool initialization
44
- let compiledSimpleResult: CompilationResult;
45
- let compiledModerateResult: CompilationResult;
46
- let compiledComplexResult: CompilationResult;
47
-
48
- // Worker pools for concurrent benchmarks
49
- let workerPoolSimple: WorkerPool | null = null;
50
- let workerPoolModerate: WorkerPool | null = null;
51
- let workerPoolComplex: WorkerPool | null = null;
52
-
53
- // Round-trip latency trackers (fair comparison - main thread perspective)
54
- const rtLatencyTrackerSimple = new LatencyTracker();
55
- const rtLatencyTrackerModerate = new LatencyTracker();
56
- const rtLatencyTrackerComplex = new LatencyTracker();
57
-
58
- // Execution latency trackers (worker-side only, for analysis)
59
- const execLatencyTrackerSimple = new LatencyTracker();
60
- const execLatencyTrackerModerate = new LatencyTracker();
61
- const execLatencyTrackerComplex = new LatencyTracker();
62
-
63
- // zen-engine latency (individual call latency, not queued)
64
- const zenLatencyTrackerSimple = new LatencyTracker();
65
- const zenLatencyTrackerModerate = new LatencyTracker();
66
- const zenLatencyTrackerComplex = new LatencyTracker();
67
-
68
- // In-thread latency trackers (jdm-asm running in main thread, no workers)
69
- const inThreadLatencyTrackerSimple = new LatencyTracker();
70
- const inThreadLatencyTrackerModerate = new LatencyTracker();
71
- const inThreadLatencyTrackerComplex = new LatencyTracker();
72
-
73
- // Track if complex compiled successfully
74
- let complexCompiled = false;
75
-
76
- // Batch size for concurrent benchmarks
77
- const CONCURRENT_BATCH_SIZE = 1000;
78
-
79
- /**
80
- * Format a number with thousands separators
81
- */
82
- function formatNumber(n: number): string {
83
- return n.toLocaleString('en-US');
84
- }
85
-
86
- /**
87
- * Format milliseconds as human-readable string
88
- */
89
- function formatMs(ms: number): string {
90
- if (ms < 1000) {
91
- return `${ms.toFixed(0)} ms`;
92
- } else {
93
- return `${(ms / 1000).toFixed(2)} s`;
94
- }
95
- }
96
-
97
- // Warm up and verify
98
- console.log('\nRunning warm-up validation...\n');
99
-
100
- async function warmup() {
101
- // Verify zen-engine
102
- await zenSimple.evaluate(simpleInput);
103
- console.log(' zen-engine simple: ready');
104
-
105
- await zenModerate.evaluate(moderateInput);
106
- console.log(' zen-engine moderate: ready');
107
-
108
- // Complex might take longer, just log
109
- try {
110
- await zenComplex.evaluate(complexInput);
111
- console.log(' zen-engine complex: ready');
112
- } catch (_err) {
113
- console.log(' zen-engine complex warm-up skipped (large file)');
114
- }
115
-
116
- // Compile jdm-asm and measure compilation times
117
- console.log('\nCompiling jdm-asm modules...\n');
118
-
119
- const simpleStart = performance.now();
120
- compiledSimpleResult = await compile({
121
- inputSchema: inferSchema(simpleInput),
122
- outputSchema: inferSchema({}),
123
- jdm: simpleJdm,
124
- optimize: true,
125
- });
126
- const simpleCompileTime = performance.now() - simpleStart;
127
- asmSimple = new ReusableWasmEvaluator(compiledSimpleResult);
128
- await asmSimple.initialize();
129
- asmSimple.run(simpleInput); // Verify output
130
- console.log(` Simple: ${formatNumber(compiledSimpleResult.wasm.length).padStart(12)} bytes in ${formatMs(simpleCompileTime).padStart(8)}`);
131
-
132
- const moderateStart = performance.now();
133
- compiledModerateResult = await compile({
134
- inputSchema: inferSchema(moderateInput),
135
- outputSchema: inferSchema({}),
136
- jdm: moderateJdm,
137
- optimize: true,
138
- });
139
- const moderateCompileTime = performance.now() - moderateStart;
140
- asmModerate = new ReusableWasmEvaluator(compiledModerateResult);
141
- await asmModerate.initialize();
142
- asmModerate.run(moderateInput); // Verify output
143
- console.log(` Moderate: ${formatNumber(compiledModerateResult.wasm.length).padStart(12)} bytes in ${formatMs(moderateCompileTime).padStart(8)}`);
144
-
145
- try {
146
- const complexStart = performance.now();
147
- compiledComplexResult = await compile({
148
- inputSchema: inferSchema(complexInput),
149
- outputSchema: inferSchema({}),
150
- jdm: complexJdm,
151
- optimize: true,
152
- });
153
- const complexCompileTime = performance.now() - complexStart;
154
- asmComplex = new ReusableWasmEvaluator(compiledComplexResult);
155
- await asmComplex.initialize();
156
- asmComplex.run(complexInput); // Verify output
157
- complexCompiled = true;
158
- console.log(` Complex: ${formatNumber(compiledComplexResult.wasm.length).padStart(12)} bytes in ${formatMs(complexCompileTime).padStart(8)}`);
159
- } catch (e) {
160
- console.log(' Complex compilation skipped:', (e as Error).message.slice(0, 80));
161
- // Fallback to simple for benchmarking structure
162
- asmComplex = asmSimple;
163
- }
164
-
165
- console.log('\nWarm-up complete\n');
166
- }
167
-
168
- /**
169
- * Initialize worker pools for concurrent benchmarks
170
- */
171
- async function initializeWorkerPools() {
172
- const workerCount = cpus().length;
173
- console.log(`\nInitializing worker pools (${workerCount} threads)...`);
174
-
175
- console.log(' Initializing simple worker pool...');
176
- workerPoolSimple = new WorkerPool(
177
- new Uint8Array(compiledSimpleResult.wasm),
178
- compiledSimpleResult.marshalCode
179
- );
180
- await workerPoolSimple.initialize();
181
- console.log(` Simple pool ready with ${workerPoolSimple.getWorkerCount()} workers`);
182
-
183
- console.log(' Initializing moderate worker pool...');
184
- workerPoolModerate = new WorkerPool(
185
- new Uint8Array(compiledModerateResult.wasm),
186
- compiledModerateResult.marshalCode
187
- );
188
- await workerPoolModerate.initialize();
189
- console.log(` Moderate pool ready with ${workerPoolModerate.getWorkerCount()} workers`);
190
-
191
- if (complexCompiled) {
192
- console.log(' Initializing complex worker pool...');
193
- workerPoolComplex = new WorkerPool(
194
- new Uint8Array(compiledComplexResult.wasm),
195
- compiledComplexResult.marshalCode
196
- );
197
- await workerPoolComplex.initialize();
198
- console.log(` Complex pool ready with ${workerPoolComplex.getWorkerCount()} workers`);
199
- }
200
-
201
- console.log('Worker pools initialized\n');
202
- }
203
-
204
- /**
205
- * Shutdown worker pools
206
- */
207
- async function shutdownWorkerPools() {
208
- if (workerPoolSimple) {
209
- await workerPoolSimple.shutdown();
210
- workerPoolSimple = null;
211
- }
212
- if (workerPoolModerate) {
213
- await workerPoolModerate.shutdown();
214
- workerPoolModerate = null;
215
- }
216
- if (workerPoolComplex) {
217
- await workerPoolComplex.shutdown();
218
- workerPoolComplex = null;
219
- }
220
- }
221
-
222
- /**
223
- * Format nanoseconds as human-readable string
224
- */
225
- function formatNs(ns: number): string {
226
- if (ns < 1000) {
227
- return `${ns.toFixed(1)} ns`;
228
- } else if (ns < 1_000_000) {
229
- return `${(ns / 1000).toFixed(1)} µs`;
230
- } else if (ns < 1_000_000_000) {
231
- return `${(ns / 1_000_000).toFixed(1)} ms`;
232
- } else {
233
- return `${(ns / 1_000_000_000).toFixed(2)} s`;
234
- }
235
- }
236
-
237
- /**
238
- * Print latency percentiles summary
239
- */
240
- function printLatencySummary() {
241
- const workerCount = cpus().length;
242
-
243
- console.log();
244
- console.log(styleText('red', '=============== Per-Request Latency Percentiles ==============='));
245
-
246
- // Round-trip latency section (fair comparison)
247
- console.log();
248
- console.log(styleText('green', 'Round-Trip Latency (concurrent, main thread perspective)'));
249
- console.log(' p50 p95 p99');
250
-
251
- // jdm-asm simple round-trip
252
- const rtSimpleReport = rtLatencyTrackerSimple.report();
253
- console.log(
254
- `jdm-asm simple (${workerCount} thr)`.padEnd(25) +
255
- formatNs(rtSimpleReport.p50).padStart(10) +
256
- formatNs(rtSimpleReport.p95).padStart(11) +
257
- formatNs(rtSimpleReport.p99).padStart(11)
258
- );
259
-
260
- // zen-engine simple
261
- const zenSimpleReport = zenLatencyTrackerSimple.report();
262
- console.log(
263
- 'zen-engine simple'.padEnd(25) +
264
- formatNs(zenSimpleReport.p50).padStart(10) +
265
- formatNs(zenSimpleReport.p95).padStart(11) +
266
- formatNs(zenSimpleReport.p99).padStart(11)
267
- );
268
-
269
- // jdm-asm moderate round-trip
270
- const rtModerateReport = rtLatencyTrackerModerate.report();
271
- console.log(
272
- `jdm-asm moderate (${workerCount} thr)`.padEnd(25) +
273
- formatNs(rtModerateReport.p50).padStart(10) +
274
- formatNs(rtModerateReport.p95).padStart(11) +
275
- formatNs(rtModerateReport.p99).padStart(11)
276
- );
277
-
278
- // zen-engine moderate
279
- const zenModerateReport = zenLatencyTrackerModerate.report();
280
- console.log(
281
- 'zen-engine moderate'.padEnd(25) +
282
- formatNs(zenModerateReport.p50).padStart(10) +
283
- formatNs(zenModerateReport.p95).padStart(11) +
284
- formatNs(zenModerateReport.p99).padStart(11)
285
- );
286
-
287
- // jdm-asm complex round-trip (only if complex was compiled)
288
- if (complexCompiled) {
289
- const rtComplexReport = rtLatencyTrackerComplex.report();
290
- if (rtComplexReport.p50 > 0) {
291
- console.log(
292
- `jdm-asm complex (${workerCount} thr)`.padEnd(25) +
293
- formatNs(rtComplexReport.p50).padStart(10) +
294
- formatNs(rtComplexReport.p95).padStart(11) +
295
- formatNs(rtComplexReport.p99).padStart(11)
296
- );
297
-
298
- // zen-engine complex
299
- const zenComplexReport = zenLatencyTrackerComplex.report();
300
- console.log(
301
- 'zen-engine complex'.padEnd(25) +
302
- formatNs(zenComplexReport.p50).padStart(10) +
303
- formatNs(zenComplexReport.p95).padStart(11) +
304
- formatNs(zenComplexReport.p99).padStart(11)
305
- );
306
- }
307
- }
308
-
309
- // In-thread latency section (jdm-asm in main thread, no workers)
310
- console.log();
311
- console.log(styleText('green', 'In-Thread Latency (jdm-asm in main thread, no worker overhead)'));
312
- console.log(' p50 p95 p99');
313
-
314
- const inThreadSimpleReport = inThreadLatencyTrackerSimple.report();
315
- console.log(
316
- 'jdm-asm simple'.padEnd(25) +
317
- formatNs(inThreadSimpleReport.p50).padStart(10) +
318
- formatNs(inThreadSimpleReport.p95).padStart(11) +
319
- formatNs(inThreadSimpleReport.p99).padStart(11)
320
- );
321
-
322
- const inThreadModerateReport = inThreadLatencyTrackerModerate.report();
323
- console.log(
324
- 'jdm-asm moderate'.padEnd(25) +
325
- formatNs(inThreadModerateReport.p50).padStart(10) +
326
- formatNs(inThreadModerateReport.p95).padStart(11) +
327
- formatNs(inThreadModerateReport.p99).padStart(11)
328
- );
329
-
330
- if (complexCompiled) {
331
- const inThreadComplexReport = inThreadLatencyTrackerComplex.report();
332
- if (inThreadComplexReport.p50 > 0) {
333
- console.log(
334
- 'jdm-asm complex'.padEnd(25) +
335
- formatNs(inThreadComplexReport.p50).padStart(10) +
336
- formatNs(inThreadComplexReport.p95).padStart(11) +
337
- formatNs(inThreadComplexReport.p99).padStart(11)
338
- );
339
- }
340
- }
341
-
342
- console.log();
343
- }
344
-
345
- /**
346
- * Format throughput as human-readable string
347
- */
348
- function formatThroughput(decisionsPerSecond: number): string {
349
- if (decisionsPerSecond >= 1_000_000) {
350
- return `${(decisionsPerSecond / 1_000_000).toFixed(2)}M`;
351
- } else if (decisionsPerSecond >= 1_000) {
352
- return `${(decisionsPerSecond / 1_000).toFixed(1)}K`;
353
- } else {
354
- return `${decisionsPerSecond.toFixed(0)}`;
355
- }
356
- }
357
-
358
- /**
359
- * Print throughput summary from benchmark results
360
- */
361
- function printThroughputSummary(results: unknown) {
362
- const workerCount = cpus().length;
363
-
364
- // Extract benchmark data from mitata results
365
- // Mitata returns { benchmarks: [{ alias, runs: [{ name, stats: { avg } }] }, ...] }
366
- const mitataResults = results as {
367
- benchmarks?: Array<{
368
- alias?: string;
369
- group?: number;
370
- runs?: Array<{
371
- name?: string;
372
- stats?: { avg?: number };
373
- }>;
374
- }>;
375
- };
376
- if (!mitataResults?.benchmarks || !Array.isArray(mitataResults.benchmarks)) {
377
- console.log('\n(Throughput summary unavailable - results format not recognized)');
378
- return;
379
- }
380
-
381
- // Build an array of benchmark results (since names can duplicate across groups)
382
- const benchmarkResults: Array<{ name: string; group: number; avgNs: number }> = [];
383
- for (const b of mitataResults.benchmarks) {
384
- const name = b.alias ?? b.runs?.[0]?.name;
385
- const avgNs = b.runs?.[0]?.stats?.avg ?? 0;
386
- const group = b.group ?? 0;
387
- if (avgNs > 0 && name) {
388
- benchmarkResults.push({ name, group, avgNs });
389
- }
390
- }
391
-
392
- // Helper to find benchmark by name and optionally group index
393
- const findBenchmark = (name: string, groupIndex?: number): { avgNs: number } | null => {
394
- const matches = benchmarkResults.filter(b => b.name === name);
395
- if (matches.length === 0) return null;
396
- if (groupIndex !== undefined && groupIndex < matches.length) {
397
- return matches[groupIndex];
398
- }
399
- return matches[0];
400
- };
401
-
402
- // Helper to calculate throughput (avgNs is in nanoseconds)
403
- const calcThroughput = (avgNs: number, batchSize: number): number => {
404
- const avgSeconds = avgNs / 1_000_000_000;
405
- return batchSize / avgSeconds;
406
- };
407
-
408
- console.log();
409
- console.log(styleText('red', '======== Throughput Summary (decisions per second) ========'));
410
-
411
- // Single-decision throughput (batch size = 1)
412
- // Group 0 = Simple Rules, Group 1 = Moderate Rules
413
- console.log();
414
- console.log(styleText('green', 'Single-Decision (no concurrency)'));
415
- console.log(` ${styleText('yellow', 'zen-engine')} ${styleText('yellow', 'jdm-asm')}`);
416
-
417
- const zenSimple = findBenchmark('zen-engine', 0);
418
- const asmSimple = findBenchmark('jdm-asm', 0);
419
- if (zenSimple && asmSimple) {
420
- console.log(
421
- 'Simple Rules'.padEnd(18) +
422
- (formatThroughput(calcThroughput(zenSimple.avgNs, 1)) + '/sec').padStart(14) +
423
- (formatThroughput(calcThroughput(asmSimple.avgNs, 1)) + '/sec').padStart(14)
424
- );
425
- }
426
-
427
- const zenModerate = findBenchmark('zen-engine', 1);
428
- const asmModerate = findBenchmark('jdm-asm', 1);
429
- if (zenModerate && asmModerate) {
430
- console.log(
431
- 'Moderate Rules'.padEnd(18) +
432
- (formatThroughput(calcThroughput(zenModerate.avgNs, 1)) + '/sec').padStart(14) +
433
- (formatThroughput(calcThroughput(asmModerate.avgNs, 1)) + '/sec').padStart(14)
434
- );
435
- }
436
-
437
- if (complexCompiled) {
438
- const zenComplex = findBenchmark('zen-engine', 2);
439
- const asmComplex = findBenchmark('jdm-asm', 2);
440
- if (zenComplex && asmComplex) {
441
- console.log(
442
- 'Complex Rules'.padEnd(18) +
443
- (formatThroughput(calcThroughput(zenComplex.avgNs, 1)) + '/sec').padStart(14) +
444
- (formatThroughput(calcThroughput(asmComplex.avgNs, 1)) + '/sec').padStart(14)
445
- );
446
- }
447
- }
448
-
449
- // Single-thread batch throughput
450
- const zenSimpleBatch = findBenchmark(`zen-engine (${CONCURRENT_BATCH_SIZE}-decision batch)`, 0);
451
- const asmSimpleBatch = findBenchmark(`jdm-asm (${CONCURRENT_BATCH_SIZE}-decision batch)`, 0);
452
- if (zenSimpleBatch && asmSimpleBatch) {
453
- console.log();
454
- console.log(styleText('green', `Single-Thread Batch (${CONCURRENT_BATCH_SIZE} simultaneous decisions)`));
455
- console.log(` ${styleText('yellow', 'zen-engine')} ${styleText('yellow', 'jdm-asm')}`);
456
-
457
- console.log(
458
- 'Simple Rules'.padEnd(18) +
459
- (formatThroughput(calcThroughput(zenSimpleBatch.avgNs, CONCURRENT_BATCH_SIZE)) + '/sec').padStart(14) +
460
- (formatThroughput(calcThroughput(asmSimpleBatch.avgNs, CONCURRENT_BATCH_SIZE)) + '/sec').padStart(14)
461
- );
462
-
463
- const zenModerateBatch = findBenchmark(`zen-engine (${CONCURRENT_BATCH_SIZE}-decision batch)`, 1);
464
- const asmModerateBatch = findBenchmark(`jdm-asm (${CONCURRENT_BATCH_SIZE}-decision batch)`, 1);
465
- if (zenModerateBatch && asmModerateBatch) {
466
- console.log(
467
- 'Moderate Rules'.padEnd(18) +
468
- (formatThroughput(calcThroughput(zenModerateBatch.avgNs, CONCURRENT_BATCH_SIZE)) + '/sec').padStart(14) +
469
- (formatThroughput(calcThroughput(asmModerateBatch.avgNs, CONCURRENT_BATCH_SIZE)) + '/sec').padStart(14)
470
- );
471
- }
472
-
473
- if (complexCompiled) {
474
- const zenComplexBatch = findBenchmark(`zen-engine (${CONCURRENT_BATCH_SIZE}-decision batch)`, 2);
475
- const asmComplexBatch = findBenchmark(`jdm-asm (${CONCURRENT_BATCH_SIZE}-decision batch)`, 2);
476
- if (zenComplexBatch && asmComplexBatch) {
477
- console.log(
478
- 'Complex Rules'.padEnd(18) +
479
- (formatThroughput(calcThroughput(zenComplexBatch.avgNs, CONCURRENT_BATCH_SIZE)) + '/sec').padStart(14) +
480
- (formatThroughput(calcThroughput(asmComplexBatch.avgNs, CONCURRENT_BATCH_SIZE)) + '/sec').padStart(14)
481
- );
482
- }
483
- }
484
- }
485
-
486
- // Multi-thread batch throughput
487
- const zenSimpleMulti = findBenchmark(`zen-engine (${CONCURRENT_BATCH_SIZE}-decision batch, main thread)`, 0);
488
- const asmSimpleMulti = findBenchmark(`jdm-asm (${CONCURRENT_BATCH_SIZE}-decision batch, ${workerCount} threads)`, 0);
489
- if (zenSimpleMulti && asmSimpleMulti) {
490
- console.log();
491
- console.log(styleText('green', `Multi-Thread Batch (${workerCount} threads, ${CONCURRENT_BATCH_SIZE} simultaneous decisions)`));
492
- console.log(` ${styleText('yellow', 'zen-engine')} ${styleText('yellow', 'jdm-asm')}`);
493
-
494
- console.log(
495
- 'Simple Rules'.padEnd(18) +
496
- (formatThroughput(calcThroughput(zenSimpleMulti.avgNs, CONCURRENT_BATCH_SIZE)) + '/sec').padStart(14) +
497
- (formatThroughput(calcThroughput(asmSimpleMulti.avgNs, CONCURRENT_BATCH_SIZE)) + '/sec').padStart(14)
498
- );
499
-
500
- const zenModerateMulti = findBenchmark(`zen-engine (${CONCURRENT_BATCH_SIZE}-decision batch, main thread)`, 1);
501
- const asmModerateMulti = findBenchmark(`jdm-asm (${CONCURRENT_BATCH_SIZE}-decision batch, ${workerCount} threads)`, 1);
502
- if (zenModerateMulti && asmModerateMulti) {
503
- console.log(
504
- 'Moderate Rules'.padEnd(18) +
505
- (formatThroughput(calcThroughput(zenModerateMulti.avgNs, CONCURRENT_BATCH_SIZE)) + '/sec').padStart(14) +
506
- (formatThroughput(calcThroughput(asmModerateMulti.avgNs, CONCURRENT_BATCH_SIZE)) + '/sec').padStart(14)
507
- );
508
- }
509
-
510
- if (complexCompiled) {
511
- const zenComplexMulti = findBenchmark(`zen-engine (${CONCURRENT_BATCH_SIZE}-decision batch, main thread)`, 2);
512
- const asmComplexMulti = findBenchmark(`jdm-asm (${CONCURRENT_BATCH_SIZE}-decision batch, ${workerCount} threads)`, 2);
513
- if (zenComplexMulti && asmComplexMulti) {
514
- console.log(
515
- 'Complex Rules'.padEnd(18) +
516
- (formatThroughput(calcThroughput(zenComplexMulti.avgNs, CONCURRENT_BATCH_SIZE)) + '/sec').padStart(14) +
517
- (formatThroughput(calcThroughput(asmComplexMulti.avgNs, CONCURRENT_BATCH_SIZE)) + '/sec').padStart(14)
518
- );
519
- }
520
- }
521
- }
522
-
523
- console.log();
524
- }
525
-
526
- /**
527
- * Print the guide explaining how to interpret benchmark results
528
- */
529
- function printBenchmarkGuide(workerCount: number) {
530
- console.log(`\
531
- ${styleText('green', '========== Performance Benchmarks: zen-engine vs jdm-asm ==========')}
532
-
533
- This benchmark compares zen-engine (JavaScript/Rust) against jdm-asm
534
- (WebAssembly). Results are organized into several sections.
535
-
536
- ${styleText('yellow', '1. Single-Decision Latency (Simple/Moderate/Complex Rules)')}
537
- Measures time to evaluate ONE decision. This is raw execution speed
538
- with no concurrency. Lower time = faster. Use this to compare the
539
- baseline performance of each engine.
540
-
541
- ${styleText('yellow', '2. Single-Thread Batch')}
542
- Measures total time to evaluate ${CONCURRENT_BATCH_SIZE} decisions sequentially in the
543
- main thread. Despite using Promise.all, jdm-asm is synchronous so
544
- there is no parallelism - decisions run one after another. The
545
- reported time is for the ENTIRE batch, not per-decision.
546
-
547
- ${styleText('yellow', '3. Multi-Thread Batch')}
548
- Measures total time to evaluate ${CONCURRENT_BATCH_SIZE} decisions using ${workerCount} worker
549
- threads. jdm-asm distributes work across threads for true parallelism,
550
- while zen-engine runs in the main thread (its async API provides no
551
- parallelism). Compare to single-thread batch to see parallelization
552
- benefits. Includes IPC overhead for jdm-asm workers.
553
-
554
- ${styleText('yellow', '4. Latency Percentiles')}
555
- Per-request latency distribution from the multi-thread batch runs.
556
- Shows p50/p95/p99 latencies for individual requests within the batch.
557
-
558
- ${styleText('yellow', '5. Throughput Summary')}
559
- Decisions per second derived from the benchmark timings. Higher = better.
560
-
561
- ${styleText('green', '========================== Test Scenarios ==========================')}
562
-
563
- ${styleText('yellow', 'Simple:')} Airline bag fee lookup. 3 input fields (origin, destination,
564
- class), 5 rules. Tests basic string matching with first-hit
565
- policy - the lightest realistic workload.
566
-
567
- ${styleText('yellow', 'Moderate:')} E-commerce shipping calculator. Nested input with cart items
568
- and customer data. Uses sum() and map() to compute cart total,
569
- contains() for tag checks. 12 rules across 4 region groups.
570
- Represents typical business logic complexity.
571
-
572
- ${styleText('yellow', 'Complex:')} Stress test with ~8000 rules. 6 input fields across customer/
573
- product domains. Heavy use of string functions (endsWith) and
574
- comparisons. Tests rule engine scalability - how performance
575
- degrades as decision tables grow.
576
-
577
- ----------------------------------------------------------------------------`);
578
- }
579
-
580
- /**
581
- * Define single-threaded benchmarks
582
- */
583
- function defineSingleThreadedBenchmarks() {
584
- // Define benchmark groups
585
- summary(() => {
586
- group('Simple Rules (5-10 fields)', () => {
587
- bench('zen-engine', async () => {
588
- return zenSimple.evaluate(simpleInput);
589
- });
590
-
591
- bench('jdm-asm', () => {
592
- return asmSimple.run(simpleInput);
593
- });
594
- });
595
- });
596
-
597
- summary(() => {
598
- group('Moderate Rules (20-30 fields)', () => {
599
- bench('zen-engine', async () => {
600
- return zenModerate.evaluate(moderateInput);
601
- });
602
-
603
- bench('jdm-asm', () => {
604
- return asmModerate.run(moderateInput);
605
- });
606
- });
607
- });
608
-
609
- if (complexCompiled) {
610
- summary(() => {
611
- group('Complex Rules (40+ fields)', () => {
612
- bench('zen-engine', async () => {
613
- try {
614
- return await zenComplex.evaluate(complexInput);
615
- } catch {
616
- return { result: 0 }; // Fallback
617
- }
618
- });
619
-
620
- bench('jdm-asm', () => {
621
- return asmComplex.run(complexInput);
622
- });
623
- });
624
- });
625
- } else {
626
- console.log('Note: Complex benchmark skipped (jdm-asm compilation failed)\n');
627
- }
628
- }
629
-
630
- /**
631
- * Define in-thread concurrent benchmarks (no worker threads)
632
- */
633
- function defineInThreadConcurrentBenchmarks() {
634
- // Generate batch inputs (same input repeated for statistical significance)
635
- const simpleBatchInputs = Array(CONCURRENT_BATCH_SIZE).fill(simpleInput);
636
- const moderateBatchInputs = Array(CONCURRENT_BATCH_SIZE).fill(moderateInput);
637
-
638
- summary(() => {
639
- group(`Single-Thread Batch: Simple Rules (${CONCURRENT_BATCH_SIZE} decisions)`, () => {
640
- bench(`zen-engine (${CONCURRENT_BATCH_SIZE}-decision batch)`, async () => {
641
- const results = await Promise.all(
642
- simpleBatchInputs.map(async (input) => {
643
- return zenSimple.evaluate(input);
644
- })
645
- );
646
- return results.length;
647
- });
648
-
649
- bench(`jdm-asm (${CONCURRENT_BATCH_SIZE}-decision batch)`, async () => {
650
- const results = await Promise.all(
651
- simpleBatchInputs.map(async (input) => {
652
- const startTime = process.hrtime.bigint();
653
- const result = asmSimple.run(input);
654
- const latencyNs = Number(process.hrtime.bigint() - startTime);
655
- inThreadLatencyTrackerSimple.record(latencyNs);
656
- return result;
657
- })
658
- );
659
- return results.length;
660
- });
661
- });
662
- });
663
-
664
- summary(() => {
665
- group(`Single-Thread Batch: Moderate Rules (${CONCURRENT_BATCH_SIZE} decisions)`, () => {
666
- bench(`zen-engine (${CONCURRENT_BATCH_SIZE}-decision batch)`, async () => {
667
- const results = await Promise.all(
668
- moderateBatchInputs.map(async (input) => {
669
- return zenModerate.evaluate(input);
670
- })
671
- );
672
- return results.length;
673
- });
674
-
675
- bench(`jdm-asm (${CONCURRENT_BATCH_SIZE}-decision batch)`, async () => {
676
- const results = await Promise.all(
677
- moderateBatchInputs.map(async (input) => {
678
- const startTime = process.hrtime.bigint();
679
- const result = asmModerate.run(input);
680
- const latencyNs = Number(process.hrtime.bigint() - startTime);
681
- inThreadLatencyTrackerModerate.record(latencyNs);
682
- return result;
683
- })
684
- );
685
- return results.length;
686
- });
687
- });
688
- });
689
-
690
- if (complexCompiled) {
691
- const complexBatchInputs = Array(CONCURRENT_BATCH_SIZE).fill(complexInput);
692
-
693
- summary(() => {
694
- group(`Single-Thread Batch: Complex Rules (${CONCURRENT_BATCH_SIZE} decisions)`, () => {
695
- bench(`zen-engine (${CONCURRENT_BATCH_SIZE}-decision batch)`, async () => {
696
- const results = await Promise.all(
697
- complexBatchInputs.map(async (input) => {
698
- try {
699
- return await zenComplex.evaluate(input);
700
- } catch {
701
- return { result: 0 };
702
- }
703
- })
704
- );
705
- return results.length;
706
- });
707
-
708
- bench(`jdm-asm (${CONCURRENT_BATCH_SIZE}-decision batch)`, async () => {
709
- const results = await Promise.all(
710
- complexBatchInputs.map(async (input) => {
711
- const startTime = process.hrtime.bigint();
712
- const result = asmComplex.run(input);
713
- const latencyNs = Number(process.hrtime.bigint() - startTime);
714
- inThreadLatencyTrackerComplex.record(latencyNs);
715
- return result;
716
- })
717
- );
718
- return results.length;
719
- });
720
- });
721
- });
722
- }
723
- }
724
-
725
- /**
726
- * Define multi-threaded concurrent benchmarks (with worker threads)
727
- */
728
- function defineMultiThreadedConcurrentBenchmarks() {
729
- const workerCount = cpus().length;
730
-
731
- // Generate batch inputs (same input repeated for statistical significance)
732
- const simpleBatchInputs = Array(CONCURRENT_BATCH_SIZE).fill(simpleInput);
733
- const moderateBatchInputs = Array(CONCURRENT_BATCH_SIZE).fill(moderateInput);
734
-
735
- summary(() => {
736
- group(`Multi-Thread Batch: Simple Rules (${CONCURRENT_BATCH_SIZE} decisions, ${workerCount} threads)`, () => {
737
- bench(`zen-engine (${CONCURRENT_BATCH_SIZE}-decision batch, main thread)`, async () => {
738
- const results = await Promise.all(
739
- simpleBatchInputs.map(async (input) => {
740
- const startTime = process.hrtime.bigint();
741
- const result = await zenSimple.evaluate(input);
742
- const latencyNs = Number(process.hrtime.bigint() - startTime);
743
- zenLatencyTrackerSimple.record(latencyNs);
744
- return result;
745
- })
746
- );
747
- return results.length;
748
- });
749
-
750
- bench(`jdm-asm (${CONCURRENT_BATCH_SIZE}-decision batch, ${workerCount} threads)`, async () => {
751
- const { roundTripLatencies, executionLatencies } = await workerPoolSimple!.evaluateBatch(simpleBatchInputs);
752
- // Record latencies for percentile reporting
753
- for (const latency of roundTripLatencies) {
754
- rtLatencyTrackerSimple.record(latency);
755
- }
756
- for (const latency of executionLatencies) {
757
- execLatencyTrackerSimple.record(latency);
758
- }
759
- return roundTripLatencies.length;
760
- });
761
- });
762
- });
763
-
764
- summary(() => {
765
- group(`Multi-Thread Batch: Moderate Rules (${CONCURRENT_BATCH_SIZE} decisions, ${workerCount} threads)`, () => {
766
- bench(`zen-engine (${CONCURRENT_BATCH_SIZE}-decision batch, main thread)`, async () => {
767
- const results = await Promise.all(
768
- moderateBatchInputs.map(async (input) => {
769
- const startTime = process.hrtime.bigint();
770
- const result = await zenModerate.evaluate(input);
771
- const latencyNs = Number(process.hrtime.bigint() - startTime);
772
- zenLatencyTrackerModerate.record(latencyNs);
773
- return result;
774
- })
775
- );
776
- return results.length;
777
- });
778
-
779
- bench(`jdm-asm (${CONCURRENT_BATCH_SIZE}-decision batch, ${workerCount} threads)`, async () => {
780
- const { roundTripLatencies, executionLatencies } = await workerPoolModerate!.evaluateBatch(moderateBatchInputs);
781
- // Record latencies for percentile reporting
782
- for (const latency of roundTripLatencies) {
783
- rtLatencyTrackerModerate.record(latency);
784
- }
785
- for (const latency of executionLatencies) {
786
- execLatencyTrackerModerate.record(latency);
787
- }
788
- return roundTripLatencies.length;
789
- });
790
- });
791
- });
792
-
793
- if (complexCompiled && workerPoolComplex) {
794
- const complexBatchInputs = Array(CONCURRENT_BATCH_SIZE).fill(complexInput);
795
-
796
- summary(() => {
797
- group(`Multi-Thread Batch: Complex Rules (${CONCURRENT_BATCH_SIZE} decisions, ${workerCount} threads)`, () => {
798
- bench(`zen-engine (${CONCURRENT_BATCH_SIZE}-decision batch, main thread)`, async () => {
799
- const results = await Promise.all(
800
- complexBatchInputs.map(async (input) => {
801
- const startTime = process.hrtime.bigint();
802
- try {
803
- const result = await zenComplex.evaluate(input);
804
- const latencyNs = Number(process.hrtime.bigint() - startTime);
805
- zenLatencyTrackerComplex.record(latencyNs);
806
- return result;
807
- } catch {
808
- return { result: 0 };
809
- }
810
- })
811
- );
812
- return results.length;
813
- });
814
-
815
- bench(`jdm-asm (${CONCURRENT_BATCH_SIZE}-decision batch, ${workerCount} threads)`, async () => {
816
- const { roundTripLatencies, executionLatencies } = await workerPoolComplex!.evaluateBatch(complexBatchInputs);
817
- // Record latencies for percentile reporting
818
- for (const latency of roundTripLatencies) {
819
- rtLatencyTrackerComplex.record(latency);
820
- }
821
- for (const latency of executionLatencies) {
822
- execLatencyTrackerComplex.record(latency);
823
- }
824
- return roundTripLatencies.length;
825
- });
826
- });
827
- });
828
- }
829
- }
830
-
831
- /**
832
- * Define all benchmarks
833
- */
834
- async function defineBenchmarks(options: { concurrent: boolean }) {
835
- const workerCount = cpus().length;
836
-
837
- // Print the guide at the start
838
- printBenchmarkGuide(workerCount);
839
-
840
- defineSingleThreadedBenchmarks();
841
-
842
- if (options.concurrent) {
843
- // In-thread concurrent benchmarks (no worker overhead)
844
- defineInThreadConcurrentBenchmarks();
845
-
846
- // Multi-threaded concurrent benchmarks (with worker pool)
847
- await initializeWorkerPools();
848
- defineMultiThreadedConcurrentBenchmarks();
849
- }
850
-
851
- console.log('Running benchmarks...\n');
852
- }
853
-
854
- /**
855
- * Main benchmark runner
856
- */
857
- export async function runBenchmarks(options: { format?: 'mitata' | 'json'; json?: boolean; concurrent?: boolean } = {}) {
858
- const concurrent = options.concurrent ?? true;
859
- const wantJson = options.json || options.format === 'json';
860
-
861
- try {
862
- await warmup();
863
- await defineBenchmarks({ concurrent });
864
-
865
- // Always run with default format for nice console output
866
- // Then run again with JSON to get structured results for throughput calculation
867
- const runOptions: Parameters<typeof run>[0] = {
868
- format: wantJson ? 'json' : (options.format || 'mitata'),
869
- };
870
-
871
- const results = await run(runOptions);
872
-
873
- // Print latency percentiles if concurrent benchmarks were run
874
- if (concurrent) {
875
- printLatencySummary();
876
- }
877
-
878
- // Print throughput summary
879
- printThroughputSummary(results);
880
-
881
- // Shutdown worker pools
882
- if (concurrent) {
883
- await shutdownWorkerPools();
884
- }
885
-
886
- return results;
887
- } catch (error) {
888
- console.error();
889
- console.error('Benchmark failed:', error);
890
- // Ensure worker pools are cleaned up on error
891
- await shutdownWorkerPools();
892
- throw error;
893
- }
894
- }
895
-
896
- // Run if executed directly
897
- if (import.meta.url === `file://${process.argv[1]}`) {
898
- const args = process.argv.slice(2);
899
- const json = args.includes('--json');
900
- const concurrent = !args.includes('--no-concurrent');
901
-
902
- runBenchmarks({ json, concurrent })
903
- .then((results) => {
904
- if (json) {
905
- console.log('\n' + JSON.stringify(results, null, 2));
906
- }
907
- process.exit(0);
908
- })
909
- .catch((error) => {
910
- console.error(error);
911
- process.exit(1);
912
- });
913
- }