@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
@@ -1,710 +0,0 @@
1
- import type { TSchema } from '@sinclair/typebox';
2
- import { compile as compileWasm, type CompilationResult } from '../../src/compiler';
3
- import { ensureMemory } from '../../src/compiler/runtime';
4
-
5
- export { compileWasm as compile };
6
-
7
- /**
8
- * Compare actual result against expected, but only check keys present in expected.
9
- * This allows actual to have extra fields (e.g., passthrough fields).
10
- */
11
- function expectPartialMatch(actual: unknown, expected: unknown, message: string): void {
12
- if (expected === actual) {
13
- return;
14
- }
15
-
16
- if (typeof expected !== typeof actual) {
17
- throw new Error(
18
- `${message}: type mismatch (expected ${typeof expected}, got ${typeof actual})`,
19
- );
20
- }
21
-
22
- if (expected === null || actual === null) {
23
- if (expected !== actual) {
24
- throw new Error(`${message}: null mismatch`);
25
- }
26
- return;
27
- }
28
-
29
- if (Array.isArray(expected)) {
30
- if (!Array.isArray(actual)) {
31
- throw new Error(`${message}: expected array, got ${typeof actual}`);
32
- }
33
- if (expected.length !== actual.length) {
34
- throw new Error(`${message}: array length mismatch (${expected.length} vs ${actual.length})`);
35
- }
36
- for (let i = 0; i < expected.length; i++) {
37
- expectPartialMatch(actual[i], expected[i], `${message}[${i}]`);
38
- }
39
- return;
40
- }
41
-
42
- if (typeof expected === 'object') {
43
- if (typeof actual !== 'object') {
44
- throw new Error(`${message}: expected object, got ${typeof actual}`);
45
- }
46
- const expectedKeys = Object.keys(expected);
47
-
48
- for (const key of expectedKeys) {
49
- const expectedValue = (expected as Record<string, unknown>)[key];
50
- if (!(key in (actual as object))) {
51
- throw new Error(`${message}: missing key "${key}"`);
52
- }
53
- expectPartialMatch(
54
- (actual as Record<string, unknown>)[key],
55
- expectedValue,
56
- `${message}.${key}`,
57
- );
58
- }
59
- return;
60
- }
61
-
62
- // Primitive comparison
63
- if (expected !== actual) {
64
- // Check if this looks like a timestamp comparison (Unix timestamps are large numbers)
65
- const expectedNum = typeof expected === 'number';
66
- const actualNum = typeof actual === 'number';
67
- const isTimestamp =
68
- expectedNum && actualNum && expected > 1_000_000_000 && actual > 1_000_000_000;
69
-
70
- if (isTimestamp) {
71
- // Skip exact timestamp comparison - just verify both are timestamps
72
- return;
73
- }
74
-
75
- // For floating point numbers, allow small precision differences
76
- if (expectedNum && actualNum) {
77
- const relativeError =
78
- Math.abs((expected as number) - (actual as number)) /
79
- Math.max(Math.abs(expected as number), Math.abs(actual as number), 1e-15);
80
- if (relativeError < 1e-14) {
81
- return;
82
- }
83
- }
84
-
85
- throw new Error(`${message}: value mismatch (expected ${expected}, got ${actual})`);
86
- }
87
- }
88
-
89
- /**
90
- * WASM-only test configuration (no zen-engine comparison)
91
- */
92
- export interface WasmTestConfig {
93
- name: string;
94
- jdm: string | object;
95
- inputSchema: TSchema;
96
- outputSchema: TSchema;
97
- input?: Record<string, unknown>;
98
- expected?: Record<string, unknown> | unknown[];
99
- unsupported?: string[];
100
- }
101
-
102
- /**
103
- * Simplified WASM test config without explicit schemas.
104
- * Schemas are inferred from input/expected shapes.
105
- */
106
- export interface SimpleWasmTestConfig {
107
- name: string;
108
- jdm: string | object;
109
- input?: Record<string, unknown>;
110
- expected?: Record<string, unknown> | unknown[];
111
- unsupported?: string[];
112
- }
113
-
114
- /**
115
- * Evaluate a compiled WASM module with the given input.
116
- */
117
- export async function evaluateCompiled(
118
- compiled: CompilationResult,
119
- input: Record<string, unknown>,
120
- ): Promise<Record<string, unknown>> {
121
- // Simple helper to marshal input as a Map (for marshaling when schema has no fixed fields)
122
- function marshalMapInput(
123
- data: Record<string, unknown>,
124
- memory: WebAssembly.Memory,
125
- basePtr: number,
126
- ): number {
127
- const view = new DataView(memory.buffer);
128
- const entries = Object.entries(data);
129
- const length = entries.length;
130
-
131
- // Write map length at basePtr
132
- view.setUint32(basePtr, length, true);
133
-
134
- // Allocate and write keys and values
135
- let currentOffset = basePtr + 4 + length * 8; // Skip map structure
136
-
137
- const writeValue = (value: unknown): number => {
138
- // Returns pointer to a fully allocated Value structure
139
- const valuePtr = currentOffset;
140
-
141
- if (value === null || value === undefined) {
142
- // Value.Null: [type: u32=0]
143
- view.setUint32(valuePtr, 0, true); // TAG_NULL = 0
144
- currentOffset += 4;
145
- } else if (typeof value === 'boolean') {
146
- // Value.Bool: [type: u32=1][value: u8]
147
- view.setUint32(valuePtr, 1, true); // TAG_BOOLEAN = 1
148
- view.setUint8(valuePtr + 4, value ? 1 : 0);
149
- currentOffset += 5;
150
- } else if (typeof value === 'number') {
151
- // Value.Float: [type: u32=3][value: f64]
152
- view.setUint32(valuePtr, 3, true); // TAG_FLOAT = 3
153
- view.setFloat64(valuePtr + 4, value, true);
154
- currentOffset += 12;
155
- } else if (typeof value === 'string') {
156
- // Value.String: [type: u32=4][stringPtr: u32]
157
- // Allocate space for the Value structure
158
- view.setUint32(valuePtr, 4, true); // TAG_STRING = 4
159
-
160
- // Skip to allocate string data
161
- currentOffset += 8;
162
- const stringDataPtr = currentOffset;
163
-
164
- // Write string data: [length: u32][utf16 chars...]
165
- const len = value.length;
166
- view.setUint32(stringDataPtr, len, true);
167
- for (let i = 0; i < len; i++) {
168
- view.setUint16(stringDataPtr + 4 + i * 2, value.charCodeAt(i), true);
169
- }
170
-
171
- currentOffset += 4 + len * 2; // length + UTF-16 chars
172
-
173
- // Write pointer back to Value structure
174
- view.setUint32(valuePtr + 4, stringDataPtr, true);
175
- } else if (Array.isArray(value)) {
176
- const arrLength = value.length;
177
-
178
- // Skip past the Value structure (will fill in later)
179
- const _tempOffset = currentOffset;
180
- currentOffset += 8;
181
-
182
- // Allocate space for array structure: [length: u32][elementPtr1: u32][elementPtr2: u32]...
183
- const arrayPtr = currentOffset;
184
- currentOffset += 4 + arrLength * 4; // length field + element pointers
185
-
186
- // Write array structure with value pointers
187
- view.setUint32(arrayPtr, arrLength, true); // Array length
188
-
189
- // Write each element pointer
190
- let ptrOffset = arrayPtr + 4;
191
- for (let i = 0; i < arrLength; i++) {
192
- const elemPtr = writeValue(value[i]);
193
- view.setUint32(ptrOffset, elemPtr, true);
194
- ptrOffset += 4;
195
- }
196
-
197
- // Now write the Value pointing to this array
198
- view.setUint32(valuePtr, 5, true); // TAG_ARRAY = 5
199
- view.setUint32(valuePtr + 4, arrayPtr, true); // Pointer to array data
200
- } else if (typeof value === 'object') {
201
- // Value.Object: [type: u32=6][mapPtr: u32]
202
- const obj = value as Record<string, unknown>;
203
- const objEntries = Object.entries(obj);
204
-
205
- // Skip past the Value structure (will fill in later)
206
- currentOffset += 8;
207
-
208
- // Allocate space for map structure: [length: u32][keyPtr1: u32][valuePtr1: u32]...
209
- const mapPtr = currentOffset;
210
- currentOffset += 4 + objEntries.length * 8; // length field + key/value pointer pairs
211
-
212
- // Write map structure with key/value pointers
213
- view.setUint32(mapPtr, objEntries.length, true); // Number of properties
214
-
215
- // Write each key/value pair
216
- let ptrOffset = mapPtr + 4;
217
- for (const [key, val] of objEntries) {
218
- // Write key: treat string as raw key string data (not a Value structure)
219
- const keyStrPtr = currentOffset;
220
- const keyLen = key.length;
221
- // Allocate space for key string data: [length: u32][utf16 chars...]
222
- view.setUint32(keyStrPtr, keyLen, true);
223
- for (let i = 0; i < keyLen; i++) {
224
- view.setUint16(keyStrPtr + 4 + i * 2, key.charCodeAt(i), true);
225
- }
226
- currentOffset += 4 + keyLen * 2;
227
- view.setUint32(ptrOffset, keyStrPtr, true);
228
-
229
- // Write value pointer
230
- const nestedValuePtr = writeValue(val);
231
- view.setUint32(ptrOffset + 4, nestedValuePtr, true);
232
-
233
- ptrOffset += 8;
234
- }
235
-
236
- // Now write the Value pointing to this map
237
- view.setUint32(valuePtr, 6, true); // TAG_OBJECT = 6
238
- view.setUint32(valuePtr + 4, mapPtr, true); // Pointer to map data
239
- } else {
240
- throw new Error(`Unsupported type: ${typeof value}`);
241
- }
242
-
243
- return valuePtr;
244
- };
245
-
246
- // Write map structure: [length: u32][keyPtr1: u32][valuePtr1: u32]...
247
- // Note: writeString now returns a pointer to the string DATA, not the full Value structure
248
- let ptrOffset = basePtr + 4;
249
- for (let i = 0; i < length; i++) {
250
- const [key, value] = entries[i];
251
- const keyStrPtr = currentOffset; // Pointer to the string data
252
- const keyLen = key.length;
253
- // Write key as raw string data (not a Value): [length: u32][utf16 chars...]
254
- view.setUint32(keyStrPtr, keyLen, true);
255
- for (let j = 0; j < keyLen; j++) {
256
- view.setUint16(keyStrPtr + 4 + j * 2, key.charCodeAt(j), true);
257
- }
258
- currentOffset += 4 + keyLen * 2;
259
-
260
- const valuePtr = writeValue(value);
261
- view.setUint32(ptrOffset, keyStrPtr, true);
262
- view.setUint32(ptrOffset + 4, valuePtr, true);
263
- ptrOffset += 8;
264
- }
265
-
266
- return basePtr;
267
- }
268
-
269
- // Instantiate WASM module
270
- const wasmArray = new Uint8Array(compiled.wasm);
271
- const buffer = wasmArray.buffer.slice(
272
- wasmArray.byteOffset,
273
- wasmArray.byteOffset + wasmArray.byteLength,
274
- );
275
- const wasmModule = await WebAssembly.compile(buffer as ArrayBuffer);
276
- const instance = await WebAssembly.instantiate(wasmModule, {
277
- env: {
278
- abort: () => {
279
- throw new Error('WASM abort called');
280
- },
281
- 'Date.now': () => Date.now(),
282
- },
283
- });
284
-
285
- const memory = instance.exports.memory as WebAssembly.Memory;
286
- const evaluate = instance.exports.evaluate as (ptr: number) => number;
287
-
288
- // Create a simple bump allocator for marshaling
289
- // Start after the AssemblyScript data section (static strings, etc.)
290
- // The AS compiler places static data around 1036-16000 for typical modules
291
- // We use 192KB offset to give the AS runtime plenty of room for heap allocations
292
- // during reading of complex nested data structures
293
-
294
- // Start at 192KB to avoid AS runtime heap growth - AssemblyScript allocates its own heap
295
- // starting around 1KB-16KB, and complex nested structures during evaluation may cause heap
296
- // expansion. 192KB gives sufficient headroom to prevent collision between our marshal buffer
297
- // and AS runtime heap.
298
- let heapOffset = 192 * 1024;
299
- const allocate = (size: number) => {
300
- const ptr = heapOffset;
301
- heapOffset += size;
302
- return ptr;
303
- };
304
-
305
- // Load the generated marshal code
306
- const cleanedCode = compiled.marshalCode
307
- .replace(/^export function marshalInput/gm, 'function marshalInput')
308
- .replace(/^export function unmarshalOutput/gm, 'function unmarshalOutput')
309
- .replace(/^export function readString/gm, 'function readString')
310
- .replace(/^export function readArray/gm, 'function readArray')
311
- .replace(/^export function readValue/gm, 'function readValue');
312
-
313
- const marshalCodeModule: any = {};
314
- try {
315
- const executeCode = new Function(
316
- 'module',
317
- cleanedCode +
318
- '\nmodule.marshalInput = marshalInput;\nmodule.unmarshalOutput = unmarshalOutput;\nmodule.readString = readString;\nmodule.readArray = readArray;\nmodule.readValue = readValue;',
319
- );
320
- executeCode(marshalCodeModule);
321
- } catch (e: unknown) {
322
- console.error('Generated marshal code:');
323
- console.error(cleanedCode);
324
- console.error('---');
325
- throw e;
326
- }
327
-
328
- if (!marshalCodeModule.marshalInput || !marshalCodeModule.unmarshalOutput) {
329
- throw new Error('Failed to load marshal functions');
330
- }
331
-
332
- // Allocate memory and marshal input
333
- // Use manual Map marshaling for now since schema has no fixed-size fields
334
- const inputAllocSize = 1024 * 128; // 128KB - increase for complex nested objects
335
-
336
- // Ensure we have enough memory for:
337
- // 1. AS runtime heap (0 - ~128KB depending on evaluation complexity)
338
- // 2. Input data buffer at heapOffset (192KB) with inputAllocSize (128KB)
339
- // 3. WASM custom heap for output marshaling (starts at 512KB in WASM code)
340
- // 4. Output data (variable, but usually <100KB)
341
- // Total: 512KB + 128KB = 640KB minimum, use 768KB for headroom
342
- const requiredMemory = 768 * 1024;
343
- ensureMemory(memory, requiredMemory);
344
-
345
- const inputPtr = allocate(inputAllocSize);
346
- marshalMapInput(input, memory, inputPtr);
347
-
348
- const outputPtr = evaluate(inputPtr);
349
- return (marshalCodeModule.unmarshalOutput as Function)(outputPtr, memory);
350
- }
351
-
352
- /**
353
- * Infer a TypeBox schema from a value (runtime inference).
354
- * Less type-safe than explicit schemas, but useful for porting existing tests.
355
- */
356
- export function inferSchema(value: unknown): TSchema {
357
- if (value === null) {
358
- return { type: 'null' } as unknown as TSchema;
359
- }
360
- if (typeof value === 'boolean') {
361
- return { type: 'boolean' } as unknown as TSchema;
362
- }
363
- if (typeof value === 'number') {
364
- return { type: 'number' } as unknown as TSchema;
365
- }
366
- if (typeof value === 'string') {
367
- return { type: 'string' } as unknown as TSchema;
368
- }
369
- if (Array.isArray(value)) {
370
- if (value.length === 0) {
371
- return { type: 'array', items: {} } as unknown as TSchema;
372
- }
373
- return { type: 'array', items: inferSchema(value[0]) } as unknown as TSchema;
374
- }
375
- if (typeof value === 'object') {
376
- const properties: Record<string, unknown> = {};
377
- for (const [key, val] of Object.entries(value)) {
378
- properties[key] = inferSchema(val);
379
- }
380
- return { type: 'object', properties } as unknown as TSchema;
381
- }
382
- return {} as unknown as TSchema;
383
- }
384
-
385
- /**
386
- * Run a WASM-only test (no zen-engine comparison).
387
- */
388
- export async function runWasmTest(config: WasmTestConfig): Promise<void> {
389
- // Skip if tests reference unsupported features
390
- if (config.unsupported?.length) {
391
- console.log(`⏭️ Skipping ${config.name} (unsupported: ${config.unsupported.join(', ')})`);
392
- return;
393
- }
394
-
395
- // Convert string JDM to object if needed
396
- const jdmContent = typeof config.jdm === 'string' ? JSON.parse(config.jdm) : config.jdm;
397
-
398
- type TestCase = {
399
- input: Record<string, unknown>;
400
- output: Record<string, unknown>;
401
- };
402
-
403
- type JDMWithTests = typeof jdmContent & { tests?: TestCase[] };
404
-
405
- const jdm = jdmContent as JDMWithTests;
406
-
407
- // If JDM has embedded tests array, use those
408
- const testCases = jdm.tests
409
- ? jdm.tests
410
- : config.input && config.expected
411
- ? [{ input: config.input, output: config.expected }]
412
- : [];
413
-
414
- if (testCases.length === 0) {
415
- console.log(`⏭️ Skipping ${config.name} (no test cases)`);
416
- return;
417
- }
418
-
419
- // WASM compilation takes ~250ms per decision, so compiling once and reusing the module
420
- // for all test cases dramatically speeds up test execution (seconds vs minutes).
421
- let compiled: CompilationResult | null = null;
422
- let compilationError: Error | null = null;
423
- try {
424
- compiled = await compileWasm({
425
- jdm: config.jdm as any,
426
- inputSchema: config.inputSchema,
427
- outputSchema: config.outputSchema,
428
- debug: true,
429
- });
430
- // Debug: dump generated code for specific tests
431
- if (config.name.includes('customer-eligibility') && compiled.assemblyScript) {
432
- require('fs').writeFileSync('/tmp/eligibility-debug.ts', compiled.assemblyScript);
433
- }
434
- } catch (error: unknown) {
435
- compilationError = error instanceof Error ? error : new Error(String(error));
436
- }
437
-
438
- for (let i = 0; i < testCases.length; i++) {
439
- const testCase = testCases[i];
440
- const testName = jdm.tests ? `${config.name} [test ${i + 1}/${testCases.length}]` : config.name;
441
-
442
- // Run with our implementation
443
- try {
444
- // Handle compilation errors
445
- if (compilationError) {
446
- const message = compilationError.message;
447
- if (message.includes('Function node')) {
448
- console.log(`⏭️ Skipping ${testName} (function node not yet supported)`);
449
- continue;
450
- } else if (message.includes('compile() not yet implemented')) {
451
- console.log(`⏭️ Skipping ${testName} (compile() not yet implemented)`);
452
- continue;
453
- } else {
454
- throw compilationError;
455
- }
456
- }
457
-
458
- const asmResult = await evaluateCompiled(compiled!, testCase.input);
459
-
460
- // Compare against expected output - only check keys present in expected
461
- expectPartialMatch(asmResult, testCase.output, `${testName} - jdm-asm mismatch`);
462
- console.log(`✅ ${testName}`);
463
- } catch (error: unknown) {
464
- const message = error instanceof Error ? error.message : String(error);
465
- if (message.includes('Function node')) {
466
- console.log(`⏭️ Skipping ${testName} (function node not yet supported)`);
467
- } else if (message.includes('compile() not yet implemented')) {
468
- console.log(`⏭️ Skipping ${testName} (compile() not yet implemented)`);
469
- } else {
470
- throw error;
471
- }
472
- }
473
- }
474
- }
475
-
476
- /**
477
- * Convenience wrapper for WASM tests without explicit schemas.
478
- * Infers schemas from the input/expected shapes.
479
- */
480
- export async function runSimpleWasmTest(config: SimpleWasmTestConfig): Promise<void> {
481
- const inputSchema = inferSchema(config.input || {});
482
- const outputSchema = inferSchema(config.expected || {});
483
-
484
- return runWasmTest({
485
- ...config,
486
- inputSchema,
487
- outputSchema,
488
- });
489
- }
490
-
491
- /**
492
- * Reusable WASM evaluator that pre-instantiates the module once.
493
- * Use this for benchmarking hot path performance where WASM instantiation
494
- * should not be included in the timing.
495
- */
496
- export class ReusableWasmEvaluator {
497
- private instance: WebAssembly.Instance | null = null;
498
- private memory: WebAssembly.Memory | null = null;
499
- private evaluate: ((ptr: number) => number) | null = null;
500
- private collect: (() => void) | null = null;
501
- private unmarshalOutput:
502
- | ((ptr: number, memory: WebAssembly.Memory) => Record<string, unknown>)
503
- | null = null;
504
- private marshalMapInput:
505
- | ((data: Record<string, unknown>, memory: WebAssembly.Memory, basePtr: number) => number)
506
- | null = null;
507
-
508
- constructor(private compiled: CompilationResult) {}
509
-
510
- /**
511
- * Initialize the WASM instance. Call this once before evaluating.
512
- */
513
- async initialize(): Promise<void> {
514
- if (this.instance !== null) {
515
- return;
516
- }
517
-
518
- // Instantiate WASM module
519
- const wasmArray = new Uint8Array(this.compiled.wasm);
520
- const buffer = wasmArray.buffer.slice(
521
- wasmArray.byteOffset,
522
- wasmArray.byteOffset + wasmArray.byteLength,
523
- );
524
- const wasmModule = await WebAssembly.compile(buffer as ArrayBuffer);
525
- this.instance = await WebAssembly.instantiate(wasmModule, {
526
- env: {
527
- abort: () => {
528
- throw new Error('WASM abort called');
529
- },
530
- 'Date.now': () => Date.now(),
531
- },
532
- });
533
-
534
- this.memory = this.instance.exports.memory as WebAssembly.Memory;
535
- this.evaluate = this.instance.exports.evaluate as (ptr: number) => number;
536
- this.collect = this.instance.exports.__collect as () => void;
537
-
538
- // Load the generated marshal code
539
- const cleanedCode = this.compiled.marshalCode
540
- .replace(/^export function marshalInput/gm, 'function marshalInput')
541
- .replace(/^export function unmarshalOutput/gm, 'function unmarshalOutput')
542
- .replace(/^export function readString/gm, 'function readString')
543
- .replace(/^export function readArray/gm, 'function readArray')
544
- .replace(/^export function readValue/gm, 'function readValue');
545
-
546
- const marshalCodeModule: any = {};
547
- const executeCode = new Function(
548
- 'module',
549
- cleanedCode +
550
- '\nmodule.marshalInput = marshalInput;\nmodule.unmarshalOutput = unmarshalOutput;\nmodule.readString = readString;\nmodule.readArray = readArray;\nmodule.readValue = readValue;',
551
- );
552
- executeCode(marshalCodeModule);
553
-
554
- this.unmarshalOutput = marshalCodeModule.unmarshalOutput;
555
-
556
- // Create the marshalMapInput function (inline copy from evaluateCompiled)
557
- this.marshalMapInput = this.createMarshalMapInput();
558
-
559
- // Ensure enough memory
560
- const requiredMemory = 768 * 1024;
561
- ensureMemory(this.memory, requiredMemory);
562
- }
563
-
564
- /**
565
- * Evaluate with the given input. The WASM instance is reused.
566
- */
567
- run(input: Record<string, unknown>): Record<string, unknown> {
568
- if (
569
- !this.instance ||
570
- !this.memory ||
571
- !this.evaluate ||
572
- !this.unmarshalOutput ||
573
- !this.marshalMapInput
574
- ) {
575
- throw new Error('ReusableWasmEvaluator not initialized. Call initialize() first.');
576
- }
577
-
578
- // Place input data at 640KB - after the custom heap region (512KB+)
579
- // Memory layout:
580
- // - Static data: 0 - ~50KB
581
- // - AS runtime heap: ~50KB - 192KB (grows during evaluation, stub runtime has no GC)
582
- // - Reserved: 192KB - 512KB
583
- // - Custom heap (output): 512KB - 640KB
584
- // - Input data: 640KB - 768KB
585
- // The stub runtime heap grows without GC, so putting input above the output heap
586
- // ensures no collision even after many evaluations.
587
- const inputPtr = 640 * 1024;
588
-
589
- this.marshalMapInput(input, this.memory, inputPtr);
590
- const outputPtr = this.evaluate(inputPtr);
591
- const result = this.unmarshalOutput(outputPtr, this.memory);
592
-
593
- // Run garbage collection to free memory used during evaluation
594
- // Without this, AS runtime heap grows until it conflicts with our input buffer
595
- if (this.collect) {
596
- this.collect();
597
- }
598
-
599
- return result;
600
- }
601
-
602
- /**
603
- * Create the marshalMapInput function (same logic as in evaluateCompiled).
604
- */
605
- private createMarshalMapInput(): (
606
- data: Record<string, unknown>,
607
- memory: WebAssembly.Memory,
608
- basePtr: number,
609
- ) => number {
610
- return (data: Record<string, unknown>, memory: WebAssembly.Memory, basePtr: number): number => {
611
- const view = new DataView(memory.buffer);
612
- const entries = Object.entries(data);
613
- const length = entries.length;
614
-
615
- // Write map length at basePtr
616
- view.setUint32(basePtr, length, true);
617
-
618
- // Allocate and write keys and values
619
- let currentOffset = basePtr + 4 + length * 8; // Skip map structure
620
-
621
- const writeValue = (value: unknown): number => {
622
- // Returns pointer to a fully allocated Value structure
623
- const valuePtr = currentOffset;
624
-
625
- if (value === null || value === undefined) {
626
- view.setUint32(valuePtr, 0, true); // TAG_NULL = 0
627
- currentOffset += 4;
628
- } else if (typeof value === 'boolean') {
629
- view.setUint32(valuePtr, 1, true); // TAG_BOOLEAN = 1
630
- view.setUint8(valuePtr + 4, value ? 1 : 0);
631
- currentOffset += 5;
632
- } else if (typeof value === 'number') {
633
- view.setUint32(valuePtr, 3, true); // TAG_FLOAT = 3
634
- view.setFloat64(valuePtr + 4, value, true);
635
- currentOffset += 12;
636
- } else if (typeof value === 'string') {
637
- view.setUint32(valuePtr, 4, true); // TAG_STRING = 4
638
- currentOffset += 8;
639
- const stringDataPtr = currentOffset;
640
- const len = value.length;
641
- view.setUint32(stringDataPtr, len, true);
642
- for (let i = 0; i < len; i++) {
643
- view.setUint16(stringDataPtr + 4 + i * 2, value.charCodeAt(i), true);
644
- }
645
- currentOffset += 4 + len * 2;
646
- view.setUint32(valuePtr + 4, stringDataPtr, true);
647
- } else if (Array.isArray(value)) {
648
- const arrLength = value.length;
649
- currentOffset += 8;
650
- const arrayPtr = currentOffset;
651
- currentOffset += 4 + arrLength * 4;
652
- view.setUint32(arrayPtr, arrLength, true);
653
- let ptrOffset = arrayPtr + 4;
654
- for (let i = 0; i < arrLength; i++) {
655
- const elemPtr = writeValue(value[i]);
656
- view.setUint32(ptrOffset, elemPtr, true);
657
- ptrOffset += 4;
658
- }
659
- view.setUint32(valuePtr, 5, true); // TAG_ARRAY = 5
660
- view.setUint32(valuePtr + 4, arrayPtr, true);
661
- } else if (typeof value === 'object') {
662
- const obj = value as Record<string, unknown>;
663
- const objEntries = Object.entries(obj);
664
- currentOffset += 8;
665
- const mapPtr = currentOffset;
666
- currentOffset += 4 + objEntries.length * 8;
667
- view.setUint32(mapPtr, objEntries.length, true);
668
- let ptrOffset = mapPtr + 4;
669
- for (const [key, val] of objEntries) {
670
- const keyStrPtr = currentOffset;
671
- const keyLen = key.length;
672
- view.setUint32(keyStrPtr, keyLen, true);
673
- for (let i = 0; i < keyLen; i++) {
674
- view.setUint16(keyStrPtr + 4 + i * 2, key.charCodeAt(i), true);
675
- }
676
- currentOffset += 4 + keyLen * 2;
677
- view.setUint32(ptrOffset, keyStrPtr, true);
678
- const nestedValuePtr = writeValue(val);
679
- view.setUint32(ptrOffset + 4, nestedValuePtr, true);
680
- ptrOffset += 8;
681
- }
682
- view.setUint32(valuePtr, 6, true); // TAG_OBJECT = 6
683
- view.setUint32(valuePtr + 4, mapPtr, true);
684
- } else {
685
- throw new Error(`Unsupported type: ${typeof value}`);
686
- }
687
-
688
- return valuePtr;
689
- };
690
-
691
- let ptrOffset = basePtr + 4;
692
- for (let i = 0; i < length; i++) {
693
- const [key, value] = entries[i];
694
- const keyStrPtr = currentOffset;
695
- const keyLen = key.length;
696
- view.setUint32(keyStrPtr, keyLen, true);
697
- for (let j = 0; j < keyLen; j++) {
698
- view.setUint16(keyStrPtr + 4 + j * 2, key.charCodeAt(j), true);
699
- }
700
- currentOffset += 4 + keyLen * 2;
701
- const valuePtr = writeValue(value);
702
- view.setUint32(ptrOffset, keyStrPtr, true);
703
- view.setUint32(ptrOffset + 4, valuePtr, true);
704
- ptrOffset += 8;
705
- }
706
-
707
- return basePtr;
708
- };
709
- }
710
- }