@mondaydotcomorg/atp-compiler 0.17.14

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 (285) hide show
  1. package/README.md +382 -0
  2. package/__tests__/integration/all-array-methods-native.test.ts +321 -0
  3. package/__tests__/integration/all-callback-types.test.ts +406 -0
  4. package/__tests__/integration/comprehensive-edge-cases.test.ts +701 -0
  5. package/__tests__/integration/native-behavior-verification.test.ts +340 -0
  6. package/__tests__/integration/semantic-correctness.test.ts +354 -0
  7. package/__tests__/integration/threshold-tests.test.ts +529 -0
  8. package/__tests__/unit/batch-optimizer.test.ts +253 -0
  9. package/__tests__/unit/checkpoint-manager.test.ts +145 -0
  10. package/__tests__/unit/detector.test.ts +346 -0
  11. package/dist/atp-compiler/src/index.d.ts +6 -0
  12. package/dist/atp-compiler/src/index.d.ts.map +1 -0
  13. package/dist/atp-compiler/src/index.js +6 -0
  14. package/dist/atp-compiler/src/index.js.map +1 -0
  15. package/dist/atp-compiler/src/runtime/batch-parallel.d.ts +3 -0
  16. package/dist/atp-compiler/src/runtime/batch-parallel.d.ts.map +1 -0
  17. package/dist/atp-compiler/src/runtime/batch-parallel.js +13 -0
  18. package/dist/atp-compiler/src/runtime/batch-parallel.js.map +1 -0
  19. package/dist/atp-compiler/src/runtime/checkpoint-manager.d.ts +19 -0
  20. package/dist/atp-compiler/src/runtime/checkpoint-manager.d.ts.map +1 -0
  21. package/dist/atp-compiler/src/runtime/checkpoint-manager.js +81 -0
  22. package/dist/atp-compiler/src/runtime/checkpoint-manager.js.map +1 -0
  23. package/dist/atp-compiler/src/runtime/context.d.ts +8 -0
  24. package/dist/atp-compiler/src/runtime/context.d.ts.map +1 -0
  25. package/dist/atp-compiler/src/runtime/context.js +25 -0
  26. package/dist/atp-compiler/src/runtime/context.js.map +1 -0
  27. package/dist/atp-compiler/src/runtime/errors.d.ts +38 -0
  28. package/dist/atp-compiler/src/runtime/errors.d.ts.map +1 -0
  29. package/dist/atp-compiler/src/runtime/errors.js +61 -0
  30. package/dist/atp-compiler/src/runtime/errors.js.map +1 -0
  31. package/dist/atp-compiler/src/runtime/index.d.ts +16 -0
  32. package/dist/atp-compiler/src/runtime/index.d.ts.map +1 -0
  33. package/dist/atp-compiler/src/runtime/index.js +20 -0
  34. package/dist/atp-compiler/src/runtime/index.js.map +1 -0
  35. package/dist/atp-compiler/src/runtime/resumable-arrays.d.ts +9 -0
  36. package/dist/atp-compiler/src/runtime/resumable-arrays.d.ts.map +1 -0
  37. package/dist/atp-compiler/src/runtime/resumable-arrays.js +179 -0
  38. package/dist/atp-compiler/src/runtime/resumable-arrays.js.map +1 -0
  39. package/dist/atp-compiler/src/runtime/resumable-loops.d.ts +4 -0
  40. package/dist/atp-compiler/src/runtime/resumable-loops.d.ts.map +1 -0
  41. package/dist/atp-compiler/src/runtime/resumable-loops.js +61 -0
  42. package/dist/atp-compiler/src/runtime/resumable-loops.js.map +1 -0
  43. package/dist/atp-compiler/src/runtime/resumable-parallel.d.ts +3 -0
  44. package/dist/atp-compiler/src/runtime/resumable-parallel.d.ts.map +1 -0
  45. package/dist/atp-compiler/src/runtime/resumable-parallel.js +44 -0
  46. package/dist/atp-compiler/src/runtime/resumable-parallel.js.map +1 -0
  47. package/dist/atp-compiler/src/transformer/array-transformer-batch.d.ts +13 -0
  48. package/dist/atp-compiler/src/transformer/array-transformer-batch.d.ts.map +1 -0
  49. package/dist/atp-compiler/src/transformer/array-transformer-batch.js +55 -0
  50. package/dist/atp-compiler/src/transformer/array-transformer-batch.js.map +1 -0
  51. package/dist/atp-compiler/src/transformer/array-transformer-sequential.d.ts +6 -0
  52. package/dist/atp-compiler/src/transformer/array-transformer-sequential.d.ts.map +1 -0
  53. package/dist/atp-compiler/src/transformer/array-transformer-sequential.js +23 -0
  54. package/dist/atp-compiler/src/transformer/array-transformer-sequential.js.map +1 -0
  55. package/dist/atp-compiler/src/transformer/array-transformer-utils.d.ts +18 -0
  56. package/dist/atp-compiler/src/transformer/array-transformer-utils.d.ts.map +1 -0
  57. package/dist/atp-compiler/src/transformer/array-transformer-utils.js +69 -0
  58. package/dist/atp-compiler/src/transformer/array-transformer-utils.js.map +1 -0
  59. package/dist/atp-compiler/src/transformer/array-transformer-wrappers.d.ts +26 -0
  60. package/dist/atp-compiler/src/transformer/array-transformer-wrappers.d.ts.map +1 -0
  61. package/dist/atp-compiler/src/transformer/array-transformer-wrappers.js +88 -0
  62. package/dist/atp-compiler/src/transformer/array-transformer-wrappers.js.map +1 -0
  63. package/dist/atp-compiler/src/transformer/array-transformer.d.ts +12 -0
  64. package/dist/atp-compiler/src/transformer/array-transformer.d.ts.map +1 -0
  65. package/dist/atp-compiler/src/transformer/array-transformer.js +47 -0
  66. package/dist/atp-compiler/src/transformer/array-transformer.js.map +1 -0
  67. package/dist/atp-compiler/src/transformer/batch-detector.d.ts +16 -0
  68. package/dist/atp-compiler/src/transformer/batch-detector.d.ts.map +1 -0
  69. package/dist/atp-compiler/src/transformer/batch-detector.js +131 -0
  70. package/dist/atp-compiler/src/transformer/batch-detector.js.map +1 -0
  71. package/dist/atp-compiler/src/transformer/batch-optimizer.d.ts +27 -0
  72. package/dist/atp-compiler/src/transformer/batch-optimizer.d.ts.map +1 -0
  73. package/dist/atp-compiler/src/transformer/batch-optimizer.js +244 -0
  74. package/dist/atp-compiler/src/transformer/batch-optimizer.js.map +1 -0
  75. package/dist/atp-compiler/src/transformer/detector.d.ts +9 -0
  76. package/dist/atp-compiler/src/transformer/detector.d.ts.map +1 -0
  77. package/dist/atp-compiler/src/transformer/detector.js +141 -0
  78. package/dist/atp-compiler/src/transformer/detector.js.map +1 -0
  79. package/dist/atp-compiler/src/transformer/index.d.ts +22 -0
  80. package/dist/atp-compiler/src/transformer/index.d.ts.map +1 -0
  81. package/dist/atp-compiler/src/transformer/index.js +132 -0
  82. package/dist/atp-compiler/src/transformer/index.js.map +1 -0
  83. package/dist/atp-compiler/src/transformer/loop-transformer.d.ts +25 -0
  84. package/dist/atp-compiler/src/transformer/loop-transformer.d.ts.map +1 -0
  85. package/dist/atp-compiler/src/transformer/loop-transformer.js +193 -0
  86. package/dist/atp-compiler/src/transformer/loop-transformer.js.map +1 -0
  87. package/dist/atp-compiler/src/transformer/promise-transformer.d.ts +17 -0
  88. package/dist/atp-compiler/src/transformer/promise-transformer.d.ts.map +1 -0
  89. package/dist/atp-compiler/src/transformer/promise-transformer.js +132 -0
  90. package/dist/atp-compiler/src/transformer/promise-transformer.js.map +1 -0
  91. package/dist/atp-compiler/src/transformer/utils.d.ts +15 -0
  92. package/dist/atp-compiler/src/transformer/utils.d.ts.map +1 -0
  93. package/dist/atp-compiler/src/transformer/utils.js +118 -0
  94. package/dist/atp-compiler/src/transformer/utils.js.map +1 -0
  95. package/dist/atp-compiler/src/types.d.ts +57 -0
  96. package/dist/atp-compiler/src/types.d.ts.map +1 -0
  97. package/dist/atp-compiler/src/types.js +23 -0
  98. package/dist/atp-compiler/src/types.js.map +1 -0
  99. package/dist/protocol/src/auth.d.ts +173 -0
  100. package/dist/protocol/src/auth.d.ts.map +1 -0
  101. package/dist/protocol/src/auth.js +202 -0
  102. package/dist/protocol/src/auth.js.map +1 -0
  103. package/dist/protocol/src/index.d.ts +7 -0
  104. package/dist/protocol/src/index.d.ts.map +1 -0
  105. package/dist/protocol/src/index.js +7 -0
  106. package/dist/protocol/src/index.js.map +1 -0
  107. package/dist/protocol/src/oauth.d.ts +63 -0
  108. package/dist/protocol/src/oauth.d.ts.map +1 -0
  109. package/dist/protocol/src/oauth.js +5 -0
  110. package/dist/protocol/src/oauth.js.map +1 -0
  111. package/dist/protocol/src/providers.d.ts +167 -0
  112. package/dist/protocol/src/providers.d.ts.map +1 -0
  113. package/dist/protocol/src/providers.js +33 -0
  114. package/dist/protocol/src/providers.js.map +1 -0
  115. package/dist/protocol/src/schemas.d.ts +6 -0
  116. package/dist/protocol/src/schemas.d.ts.map +1 -0
  117. package/dist/protocol/src/schemas.js +51 -0
  118. package/dist/protocol/src/schemas.js.map +1 -0
  119. package/dist/protocol/src/types.d.ts +489 -0
  120. package/dist/protocol/src/types.d.ts.map +1 -0
  121. package/dist/protocol/src/types.js +88 -0
  122. package/dist/protocol/src/types.js.map +1 -0
  123. package/dist/protocol/src/validation.d.ts +76 -0
  124. package/dist/protocol/src/validation.d.ts.map +1 -0
  125. package/dist/protocol/src/validation.js +129 -0
  126. package/dist/protocol/src/validation.js.map +1 -0
  127. package/dist/provenance/src/ast/instrumentor.d.ts +37 -0
  128. package/dist/provenance/src/ast/instrumentor.d.ts.map +1 -0
  129. package/dist/provenance/src/ast/instrumentor.js +299 -0
  130. package/dist/provenance/src/ast/instrumentor.js.map +1 -0
  131. package/dist/provenance/src/index.d.ts +7 -0
  132. package/dist/provenance/src/index.d.ts.map +1 -0
  133. package/dist/provenance/src/index.js +7 -0
  134. package/dist/provenance/src/index.js.map +1 -0
  135. package/dist/provenance/src/policies/engine.d.ts +71 -0
  136. package/dist/provenance/src/policies/engine.d.ts.map +1 -0
  137. package/dist/provenance/src/policies/engine.js +433 -0
  138. package/dist/provenance/src/policies/engine.js.map +1 -0
  139. package/dist/provenance/src/registry.d.ts +94 -0
  140. package/dist/provenance/src/registry.d.ts.map +1 -0
  141. package/dist/provenance/src/registry.js +445 -0
  142. package/dist/provenance/src/registry.js.map +1 -0
  143. package/dist/provenance/src/tokens.d.ts +49 -0
  144. package/dist/provenance/src/tokens.d.ts.map +1 -0
  145. package/dist/provenance/src/tokens.js +239 -0
  146. package/dist/provenance/src/tokens.js.map +1 -0
  147. package/dist/provenance/src/types.d.ts +150 -0
  148. package/dist/provenance/src/types.d.ts.map +1 -0
  149. package/dist/provenance/src/types.js +47 -0
  150. package/dist/provenance/src/types.js.map +1 -0
  151. package/dist/runtime/src/approval/handler.d.ts +12 -0
  152. package/dist/runtime/src/approval/handler.d.ts.map +1 -0
  153. package/dist/runtime/src/approval/handler.js +17 -0
  154. package/dist/runtime/src/approval/handler.js.map +1 -0
  155. package/dist/runtime/src/approval/index.d.ts +17 -0
  156. package/dist/runtime/src/approval/index.d.ts.map +1 -0
  157. package/dist/runtime/src/approval/index.js +94 -0
  158. package/dist/runtime/src/approval/index.js.map +1 -0
  159. package/dist/runtime/src/approval/types.d.ts +21 -0
  160. package/dist/runtime/src/approval/types.d.ts.map +1 -0
  161. package/dist/runtime/src/approval/types.js +5 -0
  162. package/dist/runtime/src/approval/types.js.map +1 -0
  163. package/dist/runtime/src/cache/backends.d.ts +39 -0
  164. package/dist/runtime/src/cache/backends.d.ts.map +1 -0
  165. package/dist/runtime/src/cache/backends.js +167 -0
  166. package/dist/runtime/src/cache/backends.js.map +1 -0
  167. package/dist/runtime/src/cache/index.d.ts +32 -0
  168. package/dist/runtime/src/cache/index.d.ts.map +1 -0
  169. package/dist/runtime/src/cache/index.js +103 -0
  170. package/dist/runtime/src/cache/index.js.map +1 -0
  171. package/dist/runtime/src/cache/types.d.ts +20 -0
  172. package/dist/runtime/src/cache/types.d.ts.map +1 -0
  173. package/dist/runtime/src/cache/types.js +2 -0
  174. package/dist/runtime/src/cache/types.js.map +1 -0
  175. package/dist/runtime/src/embedding/index.d.ts +39 -0
  176. package/dist/runtime/src/embedding/index.d.ts.map +1 -0
  177. package/dist/runtime/src/embedding/index.js +162 -0
  178. package/dist/runtime/src/embedding/index.js.map +1 -0
  179. package/dist/runtime/src/embedding/types.d.ts +28 -0
  180. package/dist/runtime/src/embedding/types.d.ts.map +1 -0
  181. package/dist/runtime/src/embedding/types.js +5 -0
  182. package/dist/runtime/src/embedding/types.js.map +1 -0
  183. package/dist/runtime/src/embedding/utils.d.ts +11 -0
  184. package/dist/runtime/src/embedding/utils.d.ts.map +1 -0
  185. package/dist/runtime/src/embedding/utils.js +30 -0
  186. package/dist/runtime/src/embedding/utils.js.map +1 -0
  187. package/dist/runtime/src/embedding/vector-store.d.ts +64 -0
  188. package/dist/runtime/src/embedding/vector-store.d.ts.map +1 -0
  189. package/dist/runtime/src/embedding/vector-store.js +142 -0
  190. package/dist/runtime/src/embedding/vector-store.js.map +1 -0
  191. package/dist/runtime/src/index.d.ts +18 -0
  192. package/dist/runtime/src/index.d.ts.map +1 -0
  193. package/dist/runtime/src/index.js +17 -0
  194. package/dist/runtime/src/index.js.map +1 -0
  195. package/dist/runtime/src/llm/callback.d.ts +13 -0
  196. package/dist/runtime/src/llm/callback.d.ts.map +1 -0
  197. package/dist/runtime/src/llm/callback.js +19 -0
  198. package/dist/runtime/src/llm/callback.js.map +1 -0
  199. package/dist/runtime/src/llm/index.d.ts +29 -0
  200. package/dist/runtime/src/llm/index.d.ts.map +1 -0
  201. package/dist/runtime/src/llm/index.js +118 -0
  202. package/dist/runtime/src/llm/index.js.map +1 -0
  203. package/dist/runtime/src/llm/replay.d.ts +47 -0
  204. package/dist/runtime/src/llm/replay.d.ts.map +1 -0
  205. package/dist/runtime/src/llm/replay.js +114 -0
  206. package/dist/runtime/src/llm/replay.js.map +1 -0
  207. package/dist/runtime/src/llm/types.d.ts +24 -0
  208. package/dist/runtime/src/llm/types.d.ts.map +1 -0
  209. package/dist/runtime/src/llm/types.js +2 -0
  210. package/dist/runtime/src/llm/types.js.map +1 -0
  211. package/dist/runtime/src/log/index.d.ts +12 -0
  212. package/dist/runtime/src/log/index.d.ts.map +1 -0
  213. package/dist/runtime/src/log/index.js +166 -0
  214. package/dist/runtime/src/log/index.js.map +1 -0
  215. package/dist/runtime/src/log/types.d.ts +19 -0
  216. package/dist/runtime/src/log/types.d.ts.map +1 -0
  217. package/dist/runtime/src/log/types.js +5 -0
  218. package/dist/runtime/src/log/types.js.map +1 -0
  219. package/dist/runtime/src/metadata/decorators.d.ts +27 -0
  220. package/dist/runtime/src/metadata/decorators.d.ts.map +1 -0
  221. package/dist/runtime/src/metadata/decorators.js +38 -0
  222. package/dist/runtime/src/metadata/decorators.js.map +1 -0
  223. package/dist/runtime/src/metadata/generated.d.ts +18 -0
  224. package/dist/runtime/src/metadata/generated.d.ts.map +1 -0
  225. package/dist/runtime/src/metadata/generated.js +290 -0
  226. package/dist/runtime/src/metadata/generated.js.map +1 -0
  227. package/dist/runtime/src/metadata/index.d.ts +11 -0
  228. package/dist/runtime/src/metadata/index.d.ts.map +1 -0
  229. package/dist/runtime/src/metadata/index.js +45 -0
  230. package/dist/runtime/src/metadata/index.js.map +1 -0
  231. package/dist/runtime/src/metadata/types.d.ts +22 -0
  232. package/dist/runtime/src/metadata/types.d.ts.map +1 -0
  233. package/dist/runtime/src/metadata/types.js +6 -0
  234. package/dist/runtime/src/metadata/types.js.map +1 -0
  235. package/dist/runtime/src/pause/index.d.ts +11 -0
  236. package/dist/runtime/src/pause/index.d.ts.map +1 -0
  237. package/dist/runtime/src/pause/index.js +15 -0
  238. package/dist/runtime/src/pause/index.js.map +1 -0
  239. package/dist/runtime/src/pause/types.d.ts +46 -0
  240. package/dist/runtime/src/pause/types.d.ts.map +1 -0
  241. package/dist/runtime/src/pause/types.js +57 -0
  242. package/dist/runtime/src/pause/types.js.map +1 -0
  243. package/dist/runtime/src/progress/index.d.ts +19 -0
  244. package/dist/runtime/src/progress/index.d.ts.map +1 -0
  245. package/dist/runtime/src/progress/index.js +61 -0
  246. package/dist/runtime/src/progress/index.js.map +1 -0
  247. package/dist/runtime/src/progress/types.d.ts +7 -0
  248. package/dist/runtime/src/progress/types.d.ts.map +1 -0
  249. package/dist/runtime/src/progress/types.js +2 -0
  250. package/dist/runtime/src/progress/types.js.map +1 -0
  251. package/dist/runtime/src/registry.d.ts +16 -0
  252. package/dist/runtime/src/registry.d.ts.map +1 -0
  253. package/dist/runtime/src/registry.js +16 -0
  254. package/dist/runtime/src/registry.js.map +1 -0
  255. package/dist/runtime/src/utils.d.ts +11 -0
  256. package/dist/runtime/src/utils.d.ts.map +1 -0
  257. package/dist/runtime/src/utils.js +31 -0
  258. package/dist/runtime/src/utils.js.map +1 -0
  259. package/dist/tsconfig.tsbuildinfo +1 -0
  260. package/jest.config.js +29 -0
  261. package/package.json +56 -0
  262. package/project.json +31 -0
  263. package/src/index.ts +6 -0
  264. package/src/runtime/batch-parallel.ts +22 -0
  265. package/src/runtime/checkpoint-manager.ts +105 -0
  266. package/src/runtime/context.ts +33 -0
  267. package/src/runtime/errors.ts +79 -0
  268. package/src/runtime/index.ts +35 -0
  269. package/src/runtime/resumable-arrays.ts +253 -0
  270. package/src/runtime/resumable-loops.ts +93 -0
  271. package/src/runtime/resumable-parallel.ts +57 -0
  272. package/src/transformer/array-transformer-batch.ts +86 -0
  273. package/src/transformer/array-transformer-sequential.ts +38 -0
  274. package/src/transformer/array-transformer-utils.ts +80 -0
  275. package/src/transformer/array-transformer-wrappers.ts +165 -0
  276. package/src/transformer/array-transformer.ts +76 -0
  277. package/src/transformer/batch-detector.ts +166 -0
  278. package/src/transformer/batch-optimizer.ts +320 -0
  279. package/src/transformer/detector.ts +171 -0
  280. package/src/transformer/index.ts +155 -0
  281. package/src/transformer/loop-transformer.ts +285 -0
  282. package/src/transformer/promise-transformer.ts +194 -0
  283. package/src/transformer/utils.ts +147 -0
  284. package/src/types.ts +101 -0
  285. package/tsconfig.json +12 -0
@@ -0,0 +1,529 @@
1
+ /**
2
+ * SMART BATCHING THRESHOLD TESTS
3
+ *
4
+ * Tests the configurable batchSizeThreshold feature to ensure:
5
+ * 1. Simple callbacks always batch (no conditionals)
6
+ * 2. Conditional callbacks respect array size threshold
7
+ * 3. Unknown-size arrays with conditionals use sequential
8
+ */
9
+
10
+ import { describe, test, expect, beforeEach } from '@jest/globals';
11
+ import { ATPCompiler } from '../../src/transformer/index';
12
+
13
+ describe('Smart Batching Threshold Tests', () => {
14
+ describe('Simple Callbacks (No Conditionals) - ALWAYS Batch', () => {
15
+ test('Small array + simple callback - BATCH', () => {
16
+ const compiler = new ATPCompiler({ enableBatchParallel: true, batchSizeThreshold: 10 });
17
+ const code = `
18
+ const results = await [1, 2, 3].map(async (x) => {
19
+ return await atp.llm.call({ prompt: String(x) });
20
+ });
21
+ `;
22
+ const result = compiler.transform(code);
23
+
24
+ expect(result.transformed).toBe(true);
25
+ expect(result.code).toContain('batchParallel');
26
+ expect(result.code).not.toContain('resumableMap');
27
+ });
28
+
29
+ test('Large array + simple callback - BATCH', () => {
30
+ const compiler = new ATPCompiler({ enableBatchParallel: true, batchSizeThreshold: 10 });
31
+ const code = `
32
+ const results = await [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15].map(async (x) => {
33
+ return await atp.llm.call({ prompt: String(x) });
34
+ });
35
+ `;
36
+ const result = compiler.transform(code);
37
+
38
+ // Simple callback always batches regardless of size
39
+ expect(result.transformed).toBe(true);
40
+ expect(result.code).toContain('batchParallel');
41
+ expect(result.code).not.toContain('resumableMap');
42
+ });
43
+
44
+ test('Unknown size + simple callback - BATCH', () => {
45
+ const compiler = new ATPCompiler({ enableBatchParallel: true, batchSizeThreshold: 10 });
46
+ const code = `
47
+ const results = await items.map(async (x) => {
48
+ return await atp.llm.call({ prompt: String(x) });
49
+ });
50
+ `;
51
+ const result = compiler.transform(code);
52
+
53
+ // Simple callback always batches even with unknown size
54
+ expect(result.transformed).toBe(true);
55
+ expect(result.code).toContain('batchParallel');
56
+ expect(result.code).not.toContain('resumableMap');
57
+ });
58
+ });
59
+
60
+ describe('Conditional Callbacks - Size-Based Decisions', () => {
61
+ describe('Small Arrays (< threshold)', () => {
62
+ test('Size 3 < threshold 10 - BATCH', () => {
63
+ const compiler = new ATPCompiler({ enableBatchParallel: true, batchSizeThreshold: 10 });
64
+ const code = `
65
+ const found = await [1, 2, 3].find(async (x) => {
66
+ if (x > 1) {
67
+ return await atp.llm.call({ prompt: String(x) });
68
+ }
69
+ return false;
70
+ });
71
+ `;
72
+ const result = compiler.transform(code);
73
+
74
+ expect(result.transformed).toBe(true);
75
+ expect(result.code).toContain('batchParallel');
76
+ expect(result.code).not.toContain('resumableFind');
77
+ });
78
+
79
+ test('Size 5 < threshold 10 - BATCH', () => {
80
+ const compiler = new ATPCompiler({ enableBatchParallel: true, batchSizeThreshold: 10 });
81
+ const code = `
82
+ const results = await [1,2,3,4,5].filter(async (x) => {
83
+ if (x % 2 === 0) {
84
+ return await atp.llm.call({ prompt: String(x) });
85
+ }
86
+ return false;
87
+ });
88
+ `;
89
+ const result = compiler.transform(code);
90
+
91
+ expect(result.transformed).toBe(true);
92
+ expect(result.code).toContain('batchParallel');
93
+ expect(result.code).not.toContain('resumableFilter');
94
+ });
95
+
96
+ test('Size 9 < threshold 10 - BATCH', () => {
97
+ const compiler = new ATPCompiler({ enableBatchParallel: true, batchSizeThreshold: 10 });
98
+ const code = `
99
+ const hasAny = await [1,2,3,4,5,6,7,8,9].some(async (x) => {
100
+ if (x > 5) {
101
+ return await atp.llm.call({ prompt: String(x) });
102
+ }
103
+ return false;
104
+ });
105
+ `;
106
+ const result = compiler.transform(code);
107
+
108
+ expect(result.transformed).toBe(true);
109
+ expect(result.code).toContain('batchParallel');
110
+ expect(result.code).not.toContain('resumableSome');
111
+ });
112
+ });
113
+
114
+ describe('Large Arrays (>= threshold)', () => {
115
+ test('Size 10 >= threshold 10 - SEQUENTIAL', () => {
116
+ const compiler = new ATPCompiler({ enableBatchParallel: true, batchSizeThreshold: 10 });
117
+ const code = `
118
+ const found = await [1,2,3,4,5,6,7,8,9,10].find(async (x) => {
119
+ if (x > 5) {
120
+ return await atp.llm.call({ prompt: String(x) });
121
+ }
122
+ return false;
123
+ });
124
+ `;
125
+ const result = compiler.transform(code);
126
+
127
+ expect(result.transformed).toBe(true);
128
+ expect(result.code).toContain('resumableFind');
129
+ expect(result.code).not.toContain('batchParallel');
130
+ });
131
+
132
+ test('Size 15 >= threshold 10 - SEQUENTIAL', () => {
133
+ const compiler = new ATPCompiler({ enableBatchParallel: true, batchSizeThreshold: 10 });
134
+ const code = `
135
+ const results = await [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15].filter(async (x) => {
136
+ if (x % 2 === 0) {
137
+ return await atp.llm.call({ prompt: String(x) });
138
+ }
139
+ return false;
140
+ });
141
+ `;
142
+ const result = compiler.transform(code);
143
+
144
+ expect(result.transformed).toBe(true);
145
+ expect(result.code).toContain('resumableFilter');
146
+ expect(result.code).not.toContain('batchParallel');
147
+ });
148
+
149
+ test('Size 20 >= threshold 10 - SEQUENTIAL', () => {
150
+ const compiler = new ATPCompiler({ enableBatchParallel: true, batchSizeThreshold: 10 });
151
+ const array = Array.from({ length: 20 }, (_, i) => i + 1).join(',');
152
+ const code = `
153
+ const allValid = await [${array}].every(async (x) => {
154
+ if (x < 15) {
155
+ return await atp.llm.call({ prompt: String(x) });
156
+ }
157
+ return false;
158
+ });
159
+ `;
160
+ const result = compiler.transform(code);
161
+
162
+ expect(result.transformed).toBe(true);
163
+ expect(result.code).toContain('resumableEvery');
164
+ expect(result.code).not.toContain('batchParallel');
165
+ });
166
+ });
167
+
168
+ describe('Unknown Size Arrays', () => {
169
+ test('Variable array + conditional - SEQUENTIAL (conservative)', () => {
170
+ const compiler = new ATPCompiler({ enableBatchParallel: true, batchSizeThreshold: 10 });
171
+ const code = `
172
+ const found = await items.find(async (x) => {
173
+ if (x > 5) {
174
+ return await atp.llm.call({ prompt: String(x) });
175
+ }
176
+ return false;
177
+ });
178
+ `;
179
+ const result = compiler.transform(code);
180
+
181
+ // Unknown size + conditional → sequential for safety
182
+ expect(result.transformed).toBe(true);
183
+ expect(result.code).toContain('resumableFind');
184
+ expect(result.code).not.toContain('batchParallel');
185
+ });
186
+
187
+ test('Variable array filter + conditional - SEQUENTIAL', () => {
188
+ const compiler = new ATPCompiler({ enableBatchParallel: true, batchSizeThreshold: 10 });
189
+ const code = `
190
+ const results = await items.filter(async (item) => {
191
+ if (item.priority > 5) {
192
+ return await atp.llm.call({ prompt: item.name });
193
+ }
194
+ return false;
195
+ });
196
+ `;
197
+ const result = compiler.transform(code);
198
+
199
+ expect(result.transformed).toBe(true);
200
+ expect(result.code).toContain('resumableFilter');
201
+ expect(result.code).not.toContain('batchParallel');
202
+ });
203
+ });
204
+ });
205
+
206
+ describe('Different Threshold Values', () => {
207
+ test('Conservative threshold (5) - More sequential', () => {
208
+ const compiler = new ATPCompiler({ enableBatchParallel: true, batchSizeThreshold: 5 });
209
+
210
+ // 7 items > threshold 5
211
+ const code = `
212
+ const found = await [1,2,3,4,5,6,7].find(async (x) => {
213
+ if (x > 3) {
214
+ return await atp.llm.call({ prompt: String(x) });
215
+ }
216
+ return false;
217
+ });
218
+ `;
219
+ const result = compiler.transform(code);
220
+
221
+ expect(result.transformed).toBe(true);
222
+ expect(result.code).toContain('resumableFind');
223
+ expect(result.code).not.toContain('batchParallel');
224
+ });
225
+
226
+ test('Aggressive threshold (20) - More batching', () => {
227
+ const compiler = new ATPCompiler({ enableBatchParallel: true, batchSizeThreshold: 20 });
228
+
229
+ // 15 items < threshold 20
230
+ const code = `
231
+ const found = await [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15].find(async (x) => {
232
+ if (x > 10) {
233
+ return await atp.llm.call({ prompt: String(x) });
234
+ }
235
+ return false;
236
+ });
237
+ `;
238
+ const result = compiler.transform(code);
239
+
240
+ expect(result.transformed).toBe(true);
241
+ expect(result.code).toContain('batchParallel');
242
+ expect(result.code).not.toContain('resumableFind');
243
+ });
244
+
245
+ test('Very aggressive threshold (50) - Almost always batch', () => {
246
+ const compiler = new ATPCompiler({ enableBatchParallel: true, batchSizeThreshold: 50 });
247
+
248
+ // 30 items < threshold 50
249
+ const array = Array.from({ length: 30 }, (_, i) => i + 1).join(',');
250
+ const code = `
251
+ const results = await [${array}].filter(async (x) => {
252
+ if (x % 2 === 0) {
253
+ return await atp.llm.call({ prompt: String(x) });
254
+ }
255
+ return false;
256
+ });
257
+ `;
258
+ const result = compiler.transform(code);
259
+
260
+ expect(result.transformed).toBe(true);
261
+ expect(result.code).toContain('batchParallel');
262
+ expect(result.code).not.toContain('resumableFilter');
263
+ });
264
+
265
+ test('Threshold at exact boundary', () => {
266
+ const compiler = new ATPCompiler({ enableBatchParallel: true, batchSizeThreshold: 10 });
267
+
268
+ // Exactly 10 items = threshold
269
+ const code = `
270
+ const found = await [1,2,3,4,5,6,7,8,9,10].find(async (x) => {
271
+ if (x > 5) {
272
+ return await atp.llm.call({ prompt: String(x) });
273
+ }
274
+ return false;
275
+ });
276
+ `;
277
+ const result = compiler.transform(code);
278
+
279
+ // >= threshold → sequential
280
+ expect(result.transformed).toBe(true);
281
+ expect(result.code).toContain('resumableFind');
282
+ expect(result.code).not.toContain('batchParallel');
283
+ });
284
+ });
285
+
286
+ describe('All Array Methods', () => {
287
+ const compiler = new ATPCompiler({ enableBatchParallel: true, batchSizeThreshold: 10 });
288
+
289
+ test('map() - respects threshold', () => {
290
+ const code = `
291
+ const results = await [1,2,3,4,5,6,7,8,9,10,11,12].map(async (x) => {
292
+ if (x > 5) {
293
+ return await atp.llm.call({ prompt: String(x) });
294
+ }
295
+ return x;
296
+ });
297
+ `;
298
+ const result = compiler.transform(code);
299
+
300
+ // 12 >= 10 + conditional → sequential
301
+ expect(result.code).toContain('resumableMap');
302
+ });
303
+
304
+ test('forEach() - respects threshold', () => {
305
+ const code = `
306
+ await [1,2,3,4,5,6,7,8,9,10,11,12].forEach(async (x) => {
307
+ if (x > 5) {
308
+ await atp.llm.call({ prompt: String(x) });
309
+ }
310
+ });
311
+ `;
312
+ const result = compiler.transform(code);
313
+
314
+ // 12 >= 10 + conditional → sequential
315
+ expect(result.code).toContain('resumableForEach');
316
+ });
317
+
318
+ test('filter() - respects threshold', () => {
319
+ const code = `
320
+ const valid = await [1,2,3].filter(async (x) => {
321
+ if (x > 1) {
322
+ return await atp.llm.call({ prompt: String(x) });
323
+ }
324
+ return false;
325
+ });
326
+ `;
327
+ const result = compiler.transform(code);
328
+
329
+ // 3 < 10 + conditional → batch
330
+ expect(result.code).toContain('batchParallel');
331
+ });
332
+
333
+ test('find() - respects threshold', () => {
334
+ const code = `
335
+ const found = await [1,2,3].find(async (x) => {
336
+ if (x === 2) {
337
+ return await atp.llm.call({ prompt: String(x) });
338
+ }
339
+ return false;
340
+ });
341
+ `;
342
+ const result = compiler.transform(code);
343
+
344
+ // 3 < 10 + conditional → batch
345
+ expect(result.code).toContain('batchParallel');
346
+ });
347
+
348
+ test('some() - respects threshold', () => {
349
+ const code = `
350
+ const hasAny = await [1,2,3,4,5,6,7,8,9,10,11,12].some(async (x) => {
351
+ if (x > 10) {
352
+ return await atp.llm.call({ prompt: String(x) });
353
+ }
354
+ return false;
355
+ });
356
+ `;
357
+ const result = compiler.transform(code);
358
+
359
+ // 12 >= 10 + conditional → sequential
360
+ expect(result.code).toContain('resumableSome');
361
+ });
362
+
363
+ test('every() - respects threshold', () => {
364
+ const code = `
365
+ const allValid = await [1,2,3].every(async (x) => {
366
+ if (x > 0) {
367
+ return await atp.llm.call({ prompt: String(x) });
368
+ }
369
+ return false;
370
+ });
371
+ `;
372
+ const result = compiler.transform(code);
373
+
374
+ // 3 < 10 + conditional → batch
375
+ expect(result.code).toContain('batchParallel');
376
+ });
377
+ });
378
+
379
+ describe('Edge Cases', () => {
380
+ test('Empty array - still transforms', () => {
381
+ const compiler = new ATPCompiler({ enableBatchParallel: true, batchSizeThreshold: 10 });
382
+ const code = `
383
+ const results = await [].map(async (x) => {
384
+ return await atp.llm.call({ prompt: String(x) });
385
+ });
386
+ `;
387
+ const result = compiler.transform(code);
388
+
389
+ // 0 < 10 → batch (even though empty)
390
+ expect(result.transformed).toBe(true);
391
+ expect(result.code).toContain('batchParallel');
392
+ });
393
+
394
+ test('Single item - batches if simple', () => {
395
+ const compiler = new ATPCompiler({ enableBatchParallel: true, batchSizeThreshold: 10 });
396
+ const code = `
397
+ const result = await [1].map(async (x) => {
398
+ return await atp.llm.call({ prompt: String(x) });
399
+ });
400
+ `;
401
+ const result_transform = compiler.transform(code);
402
+
403
+ expect(result_transform.transformed).toBe(true);
404
+ expect(result_transform.code).toContain('batchParallel');
405
+ });
406
+
407
+ test('Threshold = 0 means always sequential for conditionals', () => {
408
+ const compiler = new ATPCompiler({ enableBatchParallel: true, batchSizeThreshold: 0 });
409
+ const code = `
410
+ const found = await [1].find(async (x) => {
411
+ if (x > 0) {
412
+ return await atp.llm.call({ prompt: String(x) });
413
+ }
414
+ return false;
415
+ });
416
+ `;
417
+ const result = compiler.transform(code);
418
+
419
+ // Even 1 item >= 0 → sequential with threshold 0
420
+ expect(result.transformed).toBe(true);
421
+ expect(result.code).toContain('resumableFind');
422
+ });
423
+
424
+ test('Very high threshold means almost always batch', () => {
425
+ const compiler = new ATPCompiler({ enableBatchParallel: true, batchSizeThreshold: 1000 });
426
+ const array = Array.from({ length: 100 }, (_, i) => i + 1).join(',');
427
+ const code = `
428
+ const found = await [${array}].find(async (x) => {
429
+ if (x > 50) {
430
+ return await atp.llm.call({ prompt: String(x) });
431
+ }
432
+ return false;
433
+ });
434
+ `;
435
+ const result = compiler.transform(code);
436
+
437
+ // 100 < 1000 → batch
438
+ expect(result.transformed).toBe(true);
439
+ expect(result.code).toContain('batchParallel');
440
+ });
441
+ });
442
+ });
443
+
444
+ describe('for...of loop threshold tests', () => {
445
+ const compiler = new ATPCompiler({ enableBatchParallel: true, batchSizeThreshold: 10 });
446
+
447
+ it('should batch simple for...of (no conditionals) regardless of size', () => {
448
+ const code = `
449
+ async function test(items) {
450
+ for (const item of items) {
451
+ await atp.llm.call({ prompt: item });
452
+ }
453
+ }
454
+ `;
455
+
456
+ const result = compiler.transform(code);
457
+ expect(result.code).toContain('batchParallel');
458
+ expect(result.code).not.toContain('resumableForOf');
459
+ });
460
+
461
+ it('should batch for...of with conditional and literal small array', () => {
462
+ const code = `
463
+ async function test() {
464
+ for (const item of [1, 2, 3, 4, 5]) {
465
+ if (item > 2) {
466
+ await atp.llm.call({ prompt: String(item) });
467
+ }
468
+ }
469
+ }
470
+ `;
471
+
472
+ const result = compiler.transform(code);
473
+ // Small literal array (5 < 10) → Batch
474
+ expect(result.code).toContain('batchParallel');
475
+ expect(result.code).not.toContain('resumableForOf');
476
+ });
477
+
478
+ it('should use sequential for...of with conditional and literal large array', () => {
479
+ const code = `
480
+ async function test() {
481
+ for (const item of [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]) {
482
+ if (item > 5) {
483
+ await atp.llm.call({ prompt: String(item) });
484
+ }
485
+ }
486
+ }
487
+ `;
488
+
489
+ const result = compiler.transform(code);
490
+ // Large literal array (15 >= 10) → Sequential
491
+ expect(result.code).toContain('resumableForOf');
492
+ expect(result.code).not.toContain('batchParallel');
493
+ });
494
+
495
+ it('should use sequential for...of with conditional and variable array', () => {
496
+ const code = `
497
+ async function test(items) {
498
+ for (const item of items) {
499
+ if (item.active) {
500
+ await atp.llm.call({ prompt: item.name });
501
+ }
502
+ }
503
+ }
504
+ `;
505
+
506
+ const result = compiler.transform(code);
507
+ // Unknown size + conditionals → Sequential (conservative)
508
+ expect(result.code).toContain('resumableForOf');
509
+ expect(result.code).not.toContain('batchParallel');
510
+ });
511
+
512
+ it('should use sequential for...of with break statement', () => {
513
+ const code = `
514
+ async function test(items) {
515
+ for (const item of items) {
516
+ if (item.done) break;
517
+ await atp.llm.call({ prompt: item });
518
+ }
519
+ }
520
+ `;
521
+
522
+ const result = compiler.transform(code);
523
+ // break prevents batching
524
+ expect(result.code).toContain('resumableForOf');
525
+ expect(result.code).not.toContain('batchParallel');
526
+ });
527
+ });
528
+
529
+ console.log('\n✅ SMART BATCHING THRESHOLD - ALL TESTS COMPLETE!\n');