@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,165 @@
1
+ import * as t from '@babel/types';
2
+
3
+ /**
4
+ * Wrap batch result with post-processing for filter()
5
+ * Filter must return filtered ITEMS, not boolean results
6
+ */
7
+ export function wrapFilterResult(
8
+ batchCall: t.AwaitExpression,
9
+ array: t.Expression,
10
+ methodId: string
11
+ ): t.Expression {
12
+ const resultsVar = `__filter_results_${methodId}`;
13
+ const indexVar = `__i_${methodId}`;
14
+ const arrayClone = t.cloneNode(array, true);
15
+
16
+ return t.awaitExpression(
17
+ t.callExpression(
18
+ t.arrowFunctionExpression(
19
+ [],
20
+ t.blockStatement([
21
+ t.variableDeclaration('const', [
22
+ t.variableDeclarator(t.identifier(resultsVar), batchCall.argument),
23
+ ]),
24
+ t.returnStatement(
25
+ t.callExpression(t.memberExpression(arrayClone, t.identifier('filter')), [
26
+ t.arrowFunctionExpression(
27
+ [t.identifier('_'), t.identifier(indexVar)],
28
+ t.callExpression(t.identifier('Boolean'), [
29
+ t.memberExpression(t.identifier(resultsVar), t.identifier(indexVar), true),
30
+ ])
31
+ ),
32
+ ])
33
+ ),
34
+ ]),
35
+ true
36
+ ),
37
+ []
38
+ )
39
+ );
40
+ }
41
+
42
+ /**
43
+ * Wrap batch result with post-processing for find()
44
+ * Find must return first matching ITEM (not boolean)
45
+ */
46
+ export function wrapFindResult(
47
+ batchCall: t.AwaitExpression,
48
+ array: t.Expression,
49
+ methodId: string
50
+ ): t.Expression {
51
+ const resultsVar = `__find_results_${methodId}`;
52
+ const arrayClone = t.cloneNode(array, true);
53
+
54
+ return t.awaitExpression(
55
+ t.callExpression(
56
+ t.arrowFunctionExpression(
57
+ [],
58
+ t.blockStatement([
59
+ t.variableDeclaration('const', [
60
+ t.variableDeclarator(t.identifier(resultsVar), batchCall.argument),
61
+ ]),
62
+ t.returnStatement(
63
+ t.callExpression(t.memberExpression(arrayClone, t.identifier('find')), [
64
+ t.arrowFunctionExpression(
65
+ [t.identifier('_'), t.identifier('__i')],
66
+ t.callExpression(t.identifier('Boolean'), [
67
+ t.memberExpression(t.identifier(resultsVar), t.identifier('__i'), true),
68
+ ])
69
+ ),
70
+ ])
71
+ ),
72
+ ]),
73
+ true
74
+ ),
75
+ []
76
+ )
77
+ );
78
+ }
79
+
80
+ /**
81
+ * Wrap batch result with post-processing for some()
82
+ * Some must return boolean: true if ANY result is truthy
83
+ */
84
+ export function wrapSomeResult(batchCall: t.AwaitExpression, methodId: string): t.Expression {
85
+ const resultsVar = `__some_results_${methodId}`;
86
+
87
+ return t.awaitExpression(
88
+ t.callExpression(
89
+ t.arrowFunctionExpression(
90
+ [],
91
+ t.blockStatement([
92
+ t.variableDeclaration('const', [
93
+ t.variableDeclarator(t.identifier(resultsVar), batchCall.argument),
94
+ ]),
95
+ t.returnStatement(
96
+ t.callExpression(t.memberExpression(t.identifier(resultsVar), t.identifier('some')), [
97
+ t.arrowFunctionExpression(
98
+ [t.identifier('r')],
99
+ t.callExpression(t.identifier('Boolean'), [t.identifier('r')])
100
+ ),
101
+ ])
102
+ ),
103
+ ]),
104
+ true
105
+ ),
106
+ []
107
+ )
108
+ );
109
+ }
110
+
111
+ /**
112
+ * Wrap batch result with post-processing for every()
113
+ * Every must return boolean: true if ALL results are truthy
114
+ */
115
+ export function wrapEveryResult(batchCall: t.AwaitExpression, methodId: string): t.Expression {
116
+ const resultsVar = `__every_results_${methodId}`;
117
+
118
+ return t.awaitExpression(
119
+ t.callExpression(
120
+ t.arrowFunctionExpression(
121
+ [],
122
+ t.blockStatement([
123
+ t.variableDeclaration('const', [
124
+ t.variableDeclarator(t.identifier(resultsVar), batchCall.argument),
125
+ ]),
126
+ t.returnStatement(
127
+ t.callExpression(t.memberExpression(t.identifier(resultsVar), t.identifier('every')), [
128
+ t.arrowFunctionExpression(
129
+ [t.identifier('r')],
130
+ t.callExpression(t.identifier('Boolean'), [t.identifier('r')])
131
+ ),
132
+ ])
133
+ ),
134
+ ]),
135
+ true
136
+ ),
137
+ []
138
+ )
139
+ );
140
+ }
141
+
142
+ /**
143
+ * Wrap batch result if method needs post-processing
144
+ */
145
+ export function wrapBatchResultIfNeeded(
146
+ batchCall: t.AwaitExpression,
147
+ methodName: string,
148
+ array: t.Expression,
149
+ methodId: string
150
+ ): t.Expression {
151
+ switch (methodName) {
152
+ case 'filter':
153
+ return wrapFilterResult(batchCall, array, methodId);
154
+ case 'find':
155
+ return wrapFindResult(batchCall, array, methodId);
156
+ case 'some':
157
+ return wrapSomeResult(batchCall, methodId);
158
+ case 'every':
159
+ return wrapEveryResult(batchCall, methodId);
160
+ case 'forEach':
161
+ return batchCall;
162
+ default:
163
+ return batchCall;
164
+ }
165
+ }
@@ -0,0 +1,76 @@
1
+ import * as t from '@babel/types';
2
+ import { BatchOptimizer } from './batch-optimizer.js';
3
+ import { BatchParallelDetector } from './batch-detector.js';
4
+ import { getArrayMethodName, canUseBatchParallel } from './array-transformer-utils.js';
5
+ import { transformToBatchParallel } from './array-transformer-batch.js';
6
+ import { transformToSequential } from './array-transformer-sequential.js';
7
+
8
+ export class ArrayTransformer {
9
+ private transformCount = 0;
10
+ private batchOptimizer: BatchOptimizer;
11
+ private batchDetector: BatchParallelDetector;
12
+ private batchSizeThreshold: number;
13
+
14
+ constructor(batchSizeThreshold: number = 10) {
15
+ this.batchOptimizer = new BatchOptimizer();
16
+ this.batchDetector = new BatchParallelDetector();
17
+ this.batchSizeThreshold = batchSizeThreshold;
18
+ }
19
+
20
+ transformArrayMethod(path: any): boolean {
21
+ const node = path.node as t.CallExpression;
22
+
23
+ const methodName = getArrayMethodName(node);
24
+ if (!methodName) {
25
+ return false;
26
+ }
27
+
28
+ const callback = node.arguments[0];
29
+ if (!callback || !t.isFunction(callback) || !callback.async) {
30
+ return false;
31
+ }
32
+
33
+ const batchResult = this.batchOptimizer.canBatchArrayMethod(callback);
34
+
35
+ if (batchResult.canBatch && canUseBatchParallel(methodName)) {
36
+ const array = (node.callee as t.MemberExpression).object;
37
+ const decision = this.batchOptimizer.makeSmartBatchDecision(
38
+ methodName,
39
+ batchResult,
40
+ array,
41
+ this.batchSizeThreshold
42
+ );
43
+
44
+ if (decision.shouldBatch) {
45
+ return transformToBatchParallel(
46
+ path,
47
+ node,
48
+ methodName,
49
+ callback,
50
+ this.batchDetector,
51
+ () => this.transformCount++,
52
+ () => this.doTransformToSequential(path, node, methodName, callback)
53
+ );
54
+ }
55
+ }
56
+
57
+ return this.doTransformToSequential(path, node, methodName, callback);
58
+ }
59
+
60
+ private doTransformToSequential(
61
+ path: any,
62
+ node: t.CallExpression,
63
+ methodName: string,
64
+ callback: t.Function
65
+ ): boolean {
66
+ return transformToSequential(path, node, methodName, callback, () => this.transformCount++);
67
+ }
68
+
69
+ getTransformCount(): number {
70
+ return this.transformCount;
71
+ }
72
+
73
+ resetTransformCount(): void {
74
+ this.transformCount = 0;
75
+ }
76
+ }
@@ -0,0 +1,166 @@
1
+ import * as t from '@babel/types';
2
+ import type { BatchCallInfo } from '../types.js';
3
+ import { isPausableCallExpression, getMemberExpressionPath } from './utils.js';
4
+
5
+ export class BatchParallelDetector {
6
+ canBatch(promiseAllNode: t.CallExpression): boolean {
7
+ const arrayArg = promiseAllNode.arguments[0];
8
+
9
+ if (!t.isArrayExpression(arrayArg)) {
10
+ return false;
11
+ }
12
+
13
+ if (arrayArg.elements.length === 0) {
14
+ return false;
15
+ }
16
+
17
+ return arrayArg.elements.every((el) => {
18
+ if (!el || t.isSpreadElement(el)) {
19
+ return false;
20
+ }
21
+
22
+ return this.isDirectPausableCall(el);
23
+ });
24
+ }
25
+
26
+ private isDirectPausableCall(node: t.Node): boolean {
27
+ if (t.isAwaitExpression(node)) {
28
+ node = node.argument;
29
+ }
30
+
31
+ if (!t.isCallExpression(node)) {
32
+ return false;
33
+ }
34
+
35
+ return isPausableCallExpression(node);
36
+ }
37
+
38
+ extractBatchCalls(arrayNode: t.ArrayExpression): BatchCallInfo[] {
39
+ const calls: BatchCallInfo[] = [];
40
+
41
+ for (const el of arrayNode.elements) {
42
+ if (!el || t.isSpreadElement(el)) {
43
+ continue;
44
+ }
45
+
46
+ let callNode: t.Node = el;
47
+ if (t.isAwaitExpression(callNode)) {
48
+ callNode = callNode.argument;
49
+ }
50
+
51
+ if (!t.isCallExpression(callNode)) {
52
+ continue;
53
+ }
54
+
55
+ const callInfo = this.extractCallInfo(callNode);
56
+ if (callInfo) {
57
+ calls.push(callInfo);
58
+ }
59
+ }
60
+
61
+ return calls;
62
+ }
63
+
64
+ extractCallInfo(callNode: t.CallExpression): BatchCallInfo | null {
65
+ if (!t.isMemberExpression(callNode.callee)) {
66
+ return null;
67
+ }
68
+
69
+ const path = getMemberExpressionPath(callNode.callee);
70
+ const parts = path.split('.');
71
+
72
+ if (parts.length < 3) {
73
+ return null;
74
+ }
75
+
76
+ const [namespace, service, method] = parts;
77
+ if (namespace !== 'atp' || !method) {
78
+ return null;
79
+ }
80
+
81
+ const type = service as 'llm' | 'approval' | 'embedding';
82
+ const payload = this.extractPayload(callNode.arguments as t.Expression[]);
83
+
84
+ return {
85
+ type,
86
+ operation: method,
87
+ payload,
88
+ };
89
+ }
90
+
91
+ /**
92
+ * Extract payload AST node directly
93
+ */
94
+ extractPayloadNode(callNode: t.CallExpression): t.Expression | null {
95
+ if (callNode.arguments.length === 0) {
96
+ return t.objectExpression([]);
97
+ }
98
+
99
+ const firstArg = callNode.arguments[0];
100
+ if (!firstArg || t.isSpreadElement(firstArg) || !t.isExpression(firstArg)) {
101
+ return null;
102
+ }
103
+
104
+ return firstArg;
105
+ }
106
+
107
+ private extractPayload(args: Array<t.Expression | t.SpreadElement>): Record<string, unknown> {
108
+ if (args.length === 0) {
109
+ return {};
110
+ }
111
+
112
+ const firstArg = args[0];
113
+ if (t.isSpreadElement(firstArg)) {
114
+ return {};
115
+ }
116
+
117
+ if (t.isObjectExpression(firstArg)) {
118
+ return this.objectExpressionToRecord(firstArg);
119
+ }
120
+
121
+ if (t.isStringLiteral(firstArg)) {
122
+ return { message: firstArg.value };
123
+ }
124
+
125
+ return {};
126
+ }
127
+
128
+ private objectExpressionToRecord(obj: t.ObjectExpression): Record<string, unknown> {
129
+ const record: Record<string, unknown> = {};
130
+
131
+ for (const prop of obj.properties) {
132
+ if (t.isObjectProperty(prop) && !prop.computed) {
133
+ const key = t.isIdentifier(prop.key) ? prop.key.name : String(prop.key);
134
+ const value = this.extractValue(prop.value);
135
+ record[key] = value;
136
+ }
137
+ }
138
+
139
+ return record;
140
+ }
141
+
142
+ private extractValue(node: t.Node): unknown {
143
+ if (t.isStringLiteral(node)) {
144
+ return node.value;
145
+ }
146
+ if (t.isNumericLiteral(node)) {
147
+ return node.value;
148
+ }
149
+ if (t.isBooleanLiteral(node)) {
150
+ return node.value;
151
+ }
152
+ if (t.isNullLiteral(node)) {
153
+ return null;
154
+ }
155
+ if (t.isArrayExpression(node)) {
156
+ return node.elements.map((el) =>
157
+ el && !t.isSpreadElement(el) ? this.extractValue(el) : null
158
+ );
159
+ }
160
+ if (t.isObjectExpression(node)) {
161
+ return this.objectExpressionToRecord(node);
162
+ }
163
+
164
+ return undefined;
165
+ }
166
+ }
@@ -0,0 +1,320 @@
1
+ import * as t from '@babel/types';
2
+ import { isPausableCallExpression } from './utils.js';
3
+
4
+ export interface BatchOptimizationResult {
5
+ canBatch: boolean;
6
+ reason?: string;
7
+ llmCallPattern?: 'single' | 'multiple' | 'conditional';
8
+ hasConditionals?: boolean;
9
+ hasLoops?: boolean;
10
+ }
11
+
12
+ export interface SmartBatchDecision {
13
+ shouldBatch: boolean;
14
+ reason: string;
15
+ strategy: 'always-batch' | 'size-dependent' | 'never-batch';
16
+ }
17
+
18
+ export class BatchOptimizer {
19
+ private arrayMethodsWithEarlyExit = ['find', 'some', 'every'];
20
+
21
+ canBatchArrayMethod(callback: t.Function): BatchOptimizationResult {
22
+ if (!callback.async) {
23
+ return { canBatch: false, reason: 'Not async' };
24
+ }
25
+
26
+ const body = callback.body;
27
+
28
+ if (!t.isBlockStatement(body)) {
29
+ if (t.isAwaitExpression(body)) {
30
+ if (this.isDirectPausableCall(body.argument)) {
31
+ return { canBatch: true, llmCallPattern: 'single', hasConditionals: false };
32
+ }
33
+ }
34
+ return { canBatch: false, reason: 'Non-block body without direct call' };
35
+ }
36
+
37
+ const statements = body.body;
38
+
39
+ if (statements.length === 0) {
40
+ return { canBatch: false, reason: 'Empty body' };
41
+ }
42
+
43
+ let hasConditionals = false;
44
+ let hasLoops = false;
45
+ let hasTryCatch = false;
46
+
47
+ for (const stmt of statements) {
48
+ if (t.isIfStatement(stmt) || t.isSwitchStatement(stmt)) {
49
+ hasConditionals = true;
50
+ }
51
+
52
+ if (t.isTryStatement(stmt)) {
53
+ hasTryCatch = true;
54
+ }
55
+
56
+ if (
57
+ t.isForStatement(stmt) ||
58
+ t.isForOfStatement(stmt) ||
59
+ t.isForInStatement(stmt) ||
60
+ t.isWhileStatement(stmt) ||
61
+ t.isDoWhileStatement(stmt)
62
+ ) {
63
+ hasLoops = true;
64
+ }
65
+
66
+ if (t.isBreakStatement(stmt) || t.isContinueStatement(stmt)) {
67
+ return { canBatch: false, reason: 'Contains break/continue' };
68
+ }
69
+
70
+ if (t.isReturnStatement(stmt) && stmt !== statements[statements.length - 1]) {
71
+ return { canBatch: false, reason: 'Early return' };
72
+ }
73
+ }
74
+
75
+ if (hasLoops) {
76
+ return { canBatch: false, reason: 'Contains loops', hasLoops: true };
77
+ }
78
+
79
+ if (hasTryCatch) {
80
+ return { canBatch: false, reason: 'Contains try-catch' };
81
+ }
82
+
83
+ const pausableCalls = this.countPausableCalls(body);
84
+ if (pausableCalls === 0) {
85
+ return { canBatch: false, reason: 'No pausable calls' };
86
+ }
87
+
88
+ if (pausableCalls > 1) {
89
+ return { canBatch: false, reason: 'Multiple pausable calls', llmCallPattern: 'multiple' };
90
+ }
91
+
92
+ if (hasConditionals) {
93
+ return {
94
+ canBatch: true,
95
+ llmCallPattern: 'conditional',
96
+ hasConditionals: true,
97
+ reason: 'Simple conditional - can batch but consider array size',
98
+ };
99
+ }
100
+
101
+ return { canBatch: true, llmCallPattern: 'single', hasConditionals: false };
102
+ }
103
+
104
+ /**
105
+ * Smart decision: Should we batch based on array size and method type?
106
+ */
107
+ makeSmartBatchDecision(
108
+ methodName: string,
109
+ batchResult: BatchOptimizationResult,
110
+ arrayNode: t.Expression,
111
+ threshold: number = 10
112
+ ): SmartBatchDecision {
113
+ if (!batchResult.canBatch) {
114
+ return {
115
+ shouldBatch: false,
116
+ reason: 'Complex callback - use sequential',
117
+ strategy: 'never-batch',
118
+ };
119
+ }
120
+
121
+ if (!batchResult.hasConditionals) {
122
+ return {
123
+ shouldBatch: true,
124
+ reason: 'Simple callback - batching is faster',
125
+ strategy: 'always-batch',
126
+ };
127
+ }
128
+
129
+ const hasEarlyExitBenefit = this.arrayMethodsWithEarlyExit.includes(methodName);
130
+
131
+ if (!hasEarlyExitBenefit) {
132
+ const arraySize = this.estimateArraySize(arrayNode);
133
+
134
+ if (arraySize !== null && arraySize < threshold) {
135
+ return {
136
+ shouldBatch: true,
137
+ reason: `Small array (${arraySize} < ${threshold}) - batch despite conditionals`,
138
+ strategy: 'size-dependent',
139
+ };
140
+ }
141
+
142
+ return {
143
+ shouldBatch: false,
144
+ reason: 'Conditionals + large/unknown array - sequential for safety',
145
+ strategy: 'size-dependent',
146
+ };
147
+ }
148
+
149
+ const arraySize = this.estimateArraySize(arrayNode);
150
+
151
+ if (arraySize !== null && arraySize < threshold) {
152
+ return {
153
+ shouldBatch: true,
154
+ reason: `Small array (${arraySize} < ${threshold}) - batch for speed`,
155
+ strategy: 'size-dependent',
156
+ };
157
+ }
158
+
159
+ if (arraySize !== null && arraySize >= threshold) {
160
+ return {
161
+ shouldBatch: false,
162
+ reason: `Large array (${arraySize} >= ${threshold}) + conditionals - sequential for early-exit savings`,
163
+ strategy: 'size-dependent',
164
+ };
165
+ }
166
+
167
+ if (t.isArrayExpression(arrayNode)) {
168
+ return {
169
+ shouldBatch: true,
170
+ reason: 'Array literal (likely small) - batch',
171
+ strategy: 'size-dependent',
172
+ };
173
+ }
174
+
175
+ return {
176
+ shouldBatch: false,
177
+ reason: 'Unknown array size + conditionals - sequential for safety',
178
+ strategy: 'size-dependent',
179
+ };
180
+ }
181
+
182
+ private estimateArraySize(arrayNode: t.Expression): number | null {
183
+ if (t.isArrayExpression(arrayNode)) {
184
+ return arrayNode.elements.length;
185
+ }
186
+
187
+ return null;
188
+ }
189
+
190
+ canBatchForOfLoop(loopNode: t.ForOfStatement): BatchOptimizationResult {
191
+ const body = loopNode.body;
192
+
193
+ if (!t.isBlockStatement(body)) {
194
+ return { canBatch: false, reason: 'Loop body not a block' };
195
+ }
196
+
197
+ const statements = body.body;
198
+
199
+ if (statements.length === 0) {
200
+ return { canBatch: false, reason: 'Empty loop body' };
201
+ }
202
+
203
+ const hasBreakOrContinue = this.containsBreakOrContinue(body);
204
+ if (hasBreakOrContinue) {
205
+ return { canBatch: false, reason: 'Contains break/continue' };
206
+ }
207
+
208
+ let hasConditionals = false;
209
+
210
+ for (const stmt of statements) {
211
+ if (t.isIfStatement(stmt) || t.isSwitchStatement(stmt)) {
212
+ hasConditionals = true;
213
+ }
214
+
215
+ if (
216
+ t.isForStatement(stmt) ||
217
+ t.isForOfStatement(stmt) ||
218
+ t.isForInStatement(stmt) ||
219
+ t.isWhileStatement(stmt) ||
220
+ t.isDoWhileStatement(stmt)
221
+ ) {
222
+ return { canBatch: false, reason: 'Contains nested loops', hasLoops: true };
223
+ }
224
+ }
225
+
226
+ const pausableCalls = this.countPausableCalls(body);
227
+ if (pausableCalls === 0) {
228
+ return { canBatch: false, reason: 'No pausable calls' };
229
+ }
230
+
231
+ if (pausableCalls > 1) {
232
+ return { canBatch: false, reason: 'Multiple pausable calls', llmCallPattern: 'multiple' };
233
+ }
234
+
235
+ if (hasConditionals) {
236
+ return {
237
+ canBatch: true,
238
+ llmCallPattern: 'conditional',
239
+ hasConditionals: true,
240
+ reason: 'Simple conditional - can batch but consider array size',
241
+ };
242
+ }
243
+
244
+ return { canBatch: true, llmCallPattern: 'single', hasConditionals: false };
245
+ }
246
+
247
+ private containsBreakOrContinue(node: t.Node): boolean {
248
+ let found = false;
249
+
250
+ const visit = (n: t.Node) => {
251
+ if (found) return;
252
+
253
+ if (t.isBreakStatement(n) || t.isContinueStatement(n)) {
254
+ found = true;
255
+ return;
256
+ }
257
+
258
+ if (
259
+ t.isForStatement(n) ||
260
+ t.isForOfStatement(n) ||
261
+ t.isForInStatement(n) ||
262
+ t.isWhileStatement(n) ||
263
+ t.isDoWhileStatement(n)
264
+ ) {
265
+ return;
266
+ }
267
+
268
+ Object.keys(n).forEach((key) => {
269
+ const value = (n as any)[key];
270
+ if (Array.isArray(value)) {
271
+ value.forEach((item) => {
272
+ if (item && typeof item === 'object' && item.type) {
273
+ visit(item);
274
+ }
275
+ });
276
+ } else if (value && typeof value === 'object' && value.type) {
277
+ visit(value);
278
+ }
279
+ });
280
+ };
281
+
282
+ visit(node);
283
+ return found;
284
+ }
285
+
286
+ private isDirectPausableCall(node: t.Node): boolean {
287
+ if (!t.isCallExpression(node)) {
288
+ return false;
289
+ }
290
+
291
+ return isPausableCallExpression(node);
292
+ }
293
+
294
+ private countPausableCalls(body: t.BlockStatement): number {
295
+ let count = 0;
296
+
297
+ const visit = (node: t.Node) => {
298
+ if (t.isAwaitExpression(node) && this.isDirectPausableCall(node.argument)) {
299
+ count++;
300
+ return;
301
+ }
302
+
303
+ Object.keys(node).forEach((key) => {
304
+ const value = (node as any)[key];
305
+ if (Array.isArray(value)) {
306
+ value.forEach((item) => {
307
+ if (item && typeof item === 'object' && item.type) {
308
+ visit(item);
309
+ }
310
+ });
311
+ } else if (value && typeof value === 'object' && value.type) {
312
+ visit(value);
313
+ }
314
+ });
315
+ };
316
+
317
+ visit(body);
318
+ return count;
319
+ }
320
+ }