@mondaydotcomorg/atp-compiler 0.19.23 → 0.19.26

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.
package/dist/index.cjs CHANGED
@@ -863,15 +863,102 @@ var BatchParallelDetector = class {
863
863
  return void 0;
864
864
  }
865
865
  };
866
- function findLLMCallExpression(body) {
867
- let found = null;
866
+ function collectReferencedIdentifiers(node) {
867
+ const identifiers = /* @__PURE__ */ new Set();
868
+ const visit = /* @__PURE__ */ __name((n) => {
869
+ if (t7__namespace.isIdentifier(n)) {
870
+ identifiers.add(n.name);
871
+ }
872
+ Object.keys(n).forEach((key) => {
873
+ if (key === "type" || key === "loc" || key === "start" || key === "end") return;
874
+ const value = n[key];
875
+ if (Array.isArray(value)) {
876
+ value.forEach((item) => {
877
+ if (item && typeof item === "object" && item.type) {
878
+ visit(item);
879
+ }
880
+ });
881
+ } else if (value && typeof value === "object" && value.type) {
882
+ visit(value);
883
+ }
884
+ });
885
+ }, "visit");
886
+ visit(node);
887
+ return identifiers;
888
+ }
889
+ __name(collectReferencedIdentifiers, "collectReferencedIdentifiers");
890
+ function collectLocalVariables(body) {
891
+ const locals = /* @__PURE__ */ new Set();
892
+ const visit = /* @__PURE__ */ __name((node) => {
893
+ if (t7__namespace.isVariableDeclaration(node)) {
894
+ for (const decl of node.declarations) {
895
+ if (t7__namespace.isIdentifier(decl.id)) {
896
+ locals.add(decl.id.name);
897
+ } else if (t7__namespace.isObjectPattern(decl.id)) {
898
+ for (const prop of decl.id.properties) {
899
+ if (t7__namespace.isObjectProperty(prop) && t7__namespace.isIdentifier(prop.value)) {
900
+ locals.add(prop.value.name);
901
+ } else if (t7__namespace.isRestElement(prop) && t7__namespace.isIdentifier(prop.argument)) {
902
+ locals.add(prop.argument.name);
903
+ }
904
+ }
905
+ } else if (t7__namespace.isArrayPattern(decl.id)) {
906
+ for (const elem of decl.id.elements) {
907
+ if (t7__namespace.isIdentifier(elem)) {
908
+ locals.add(elem.name);
909
+ }
910
+ }
911
+ }
912
+ }
913
+ }
914
+ if (t7__namespace.isFunction(node)) {
915
+ return;
916
+ }
917
+ Object.keys(node).forEach((key) => {
918
+ if (key === "type" || key === "loc" || key === "start" || key === "end") return;
919
+ const value = node[key];
920
+ if (Array.isArray(value)) {
921
+ value.forEach((item) => {
922
+ if (item && typeof item === "object" && item.type) {
923
+ visit(item);
924
+ }
925
+ });
926
+ } else if (value && typeof value === "object" && value.type) {
927
+ visit(value);
928
+ }
929
+ });
930
+ }, "visit");
931
+ visit(body);
932
+ return locals;
933
+ }
934
+ __name(collectLocalVariables, "collectLocalVariables");
935
+ function hasLLMCallDependencies(body, batchDetector, itemParamName) {
936
+ const localVariables = collectLocalVariables(body);
937
+ if (localVariables.size === 0) {
938
+ return false;
939
+ }
940
+ const allCalls = findAllAwaitedMemberCalls(body);
941
+ for (const call of allCalls) {
942
+ const payloadNode = batchDetector.extractPayloadNode(call);
943
+ if (payloadNode) {
944
+ const referencedIds = collectReferencedIdentifiers(payloadNode);
945
+ for (const id of referencedIds) {
946
+ if (localVariables.has(id) && id !== itemParamName) {
947
+ return true;
948
+ }
949
+ }
950
+ }
951
+ }
952
+ return false;
953
+ }
954
+ __name(hasLLMCallDependencies, "hasLLMCallDependencies");
955
+ function findAllAwaitedMemberCalls(body) {
956
+ const calls = [];
868
957
  const visit = /* @__PURE__ */ __name((node) => {
869
- if (found) return;
870
958
  if (t7__namespace.isAwaitExpression(node) && t7__namespace.isCallExpression(node.argument)) {
871
959
  const call = node.argument;
872
960
  if (t7__namespace.isMemberExpression(call.callee)) {
873
- found = call;
874
- return;
961
+ calls.push(call);
875
962
  }
876
963
  }
877
964
  Object.keys(node).forEach((key) => {
@@ -888,7 +975,30 @@ function findLLMCallExpression(body) {
888
975
  });
889
976
  }, "visit");
890
977
  visit(body);
891
- return found;
978
+ return calls;
979
+ }
980
+ __name(findAllAwaitedMemberCalls, "findAllAwaitedMemberCalls");
981
+ function findAllLLMCallExpressions(body, batchDetector) {
982
+ const allCalls = findAllAwaitedMemberCalls(body);
983
+ const llmCalls = [];
984
+ for (const call of allCalls) {
985
+ const callInfo = batchDetector.extractCallInfo(call);
986
+ const payloadNode = batchDetector.extractPayloadNode(call);
987
+ if (callInfo && payloadNode) {
988
+ llmCalls.push({
989
+ callNode: call,
990
+ callInfo,
991
+ payloadNode,
992
+ key: `${callInfo.type}:${callInfo.operation}`
993
+ });
994
+ }
995
+ }
996
+ return llmCalls;
997
+ }
998
+ __name(findAllLLMCallExpressions, "findAllLLMCallExpressions");
999
+ function findLLMCallExpression(body) {
1000
+ const calls = findAllAwaitedMemberCalls(body);
1001
+ return calls[0] ?? null;
892
1002
  }
893
1003
  __name(findLLMCallExpression, "findLLMCallExpression");
894
1004
  function getArrayMethodName(node) {
@@ -1276,54 +1386,72 @@ function transformToBatchWithReconstruction(path, node, methodName, callback, ba
1276
1386
  }
1277
1387
  const param = paramName.name;
1278
1388
  const array = node.callee.object;
1279
- const llmCall = findLLMCallExpression(callback.body);
1280
- if (!llmCall) {
1281
- return false;
1282
- }
1283
- const callInfo = batchDetector.extractCallInfo(llmCall);
1284
- if (!callInfo) {
1285
- return false;
1286
- }
1287
- const payloadNode = batchDetector.extractPayloadNode(llmCall);
1288
- if (!payloadNode) {
1389
+ const llmCalls = findAllLLMCallExpressions(callback.body, batchDetector);
1390
+ if (llmCalls.length === 0) {
1289
1391
  return false;
1290
1392
  }
1291
1393
  const methodId = generateUniqueId(`${methodName}_batch_reconstruct`);
1292
- const resultsVar = `__batch_results_${methodId.replace(/[^a-zA-Z0-9]/g, "_")}`;
1293
- const indexVar = "__idx";
1294
- const payloadMapper = t7__namespace.arrowFunctionExpression([
1295
- t7__namespace.identifier(param)
1296
- ], t7__namespace.objectExpression([
1297
- t7__namespace.objectProperty(t7__namespace.identifier("type"), t7__namespace.stringLiteral(callInfo.type)),
1298
- t7__namespace.objectProperty(t7__namespace.identifier("operation"), t7__namespace.stringLiteral(callInfo.operation)),
1299
- t7__namespace.objectProperty(t7__namespace.identifier("payload"), t7__namespace.cloneNode(payloadNode, true))
1300
- ]));
1394
+ const originalIndexParam = callback.params[1];
1395
+ const indexVar = originalIndexParam && t7__namespace.isIdentifier(originalIndexParam) ? originalIndexParam.name : "__idx";
1396
+ const batchDeclarations = [];
1397
+ const resultVarByCallIndex = /* @__PURE__ */ new Map();
1398
+ for (let i = 0; i < llmCalls.length; i++) {
1399
+ const call = llmCalls[i];
1400
+ const resultsVar = `__batch_results_${i}_${methodId.replace(/[^a-zA-Z0-9]/g, "_")}`;
1401
+ resultVarByCallIndex.set(i, resultsVar);
1402
+ const payloadMapper = t7__namespace.arrowFunctionExpression([
1403
+ t7__namespace.identifier(param)
1404
+ ], t7__namespace.objectExpression([
1405
+ t7__namespace.objectProperty(t7__namespace.identifier("type"), t7__namespace.stringLiteral(call.callInfo.type)),
1406
+ t7__namespace.objectProperty(t7__namespace.identifier("operation"), t7__namespace.stringLiteral(call.callInfo.operation)),
1407
+ t7__namespace.objectProperty(t7__namespace.identifier("payload"), t7__namespace.cloneNode(call.payloadNode, true))
1408
+ ]));
1409
+ const batchCall = t7__namespace.awaitExpression(t7__namespace.callExpression(t7__namespace.memberExpression(t7__namespace.identifier("__runtime"), t7__namespace.identifier("batchParallel")), [
1410
+ t7__namespace.callExpression(t7__namespace.memberExpression(t7__namespace.cloneNode(array, true), t7__namespace.identifier("map")), [
1411
+ payloadMapper
1412
+ ]),
1413
+ t7__namespace.stringLiteral(`${methodId}_${i}`)
1414
+ ]));
1415
+ batchDeclarations.push(t7__namespace.variableDeclaration("const", [
1416
+ t7__namespace.variableDeclarator(t7__namespace.identifier(resultsVar), batchCall)
1417
+ ]));
1418
+ }
1301
1419
  const clonedBody = t7__namespace.cloneNode(callback.body, true);
1302
- const resultAccess = t7__namespace.memberExpression(t7__namespace.identifier(resultsVar), t7__namespace.identifier(indexVar), true);
1303
1420
  let traversableNode;
1304
1421
  if (t7__namespace.isBlockStatement(clonedBody)) {
1305
1422
  traversableNode = t7__namespace.functionDeclaration(t7__namespace.identifier("__temp"), [], clonedBody);
1306
1423
  } else {
1307
1424
  traversableNode = t7__namespace.expressionStatement(clonedBody);
1308
1425
  }
1309
- let replaced = false;
1426
+ let replacementCount = 0;
1310
1427
  traverse2(t7__namespace.file(t7__namespace.program([
1311
1428
  traversableNode
1312
1429
  ])), {
1313
1430
  AwaitExpression(awaitPath) {
1314
- if (replaced) return;
1315
1431
  const arg = awaitPath.node.argument;
1316
- if (t7__namespace.isCallExpression(arg)) {
1317
- const info = batchDetector.extractCallInfo(arg);
1318
- if (info && info.type === callInfo.type && info.operation === callInfo.operation) {
1319
- awaitPath.replaceWith(resultAccess);
1320
- replaced = true;
1432
+ if (!t7__namespace.isCallExpression(arg)) return;
1433
+ const info = batchDetector.extractCallInfo(arg);
1434
+ if (!info) return;
1435
+ const key = `${info.type}:${info.operation}`;
1436
+ let matchedIndex = -1;
1437
+ for (let i = 0; i < llmCalls.length; i++) {
1438
+ const original = llmCalls[i];
1439
+ if (original.key === key && resultVarByCallIndex.has(i)) {
1440
+ matchedIndex = i;
1441
+ break;
1321
1442
  }
1322
1443
  }
1444
+ if (matchedIndex === -1) return;
1445
+ const resultsVar = resultVarByCallIndex.get(matchedIndex);
1446
+ if (!resultsVar) return;
1447
+ resultVarByCallIndex.delete(matchedIndex);
1448
+ const resultAccess = t7__namespace.memberExpression(t7__namespace.identifier(resultsVar), t7__namespace.identifier(indexVar), true);
1449
+ awaitPath.replaceWith(resultAccess);
1450
+ replacementCount++;
1323
1451
  },
1324
1452
  noScope: true
1325
1453
  });
1326
- if (!replaced) {
1454
+ if (replacementCount === 0) {
1327
1455
  return false;
1328
1456
  }
1329
1457
  let reconstructBody;
@@ -1337,22 +1465,18 @@ function transformToBatchWithReconstruction(path, node, methodName, callback, ba
1337
1465
  t7__namespace.identifier(indexVar)
1338
1466
  ], reconstructBody);
1339
1467
  reconstructMapper.async = false;
1340
- const batchCall = t7__namespace.awaitExpression(t7__namespace.callExpression(t7__namespace.memberExpression(t7__namespace.identifier("__runtime"), t7__namespace.identifier("batchParallel")), [
1341
- t7__namespace.callExpression(t7__namespace.memberExpression(t7__namespace.cloneNode(array, true), t7__namespace.identifier("map")), [
1342
- payloadMapper
1343
- ]),
1344
- t7__namespace.stringLiteral(methodId)
1345
- ]));
1346
- const resultsDeclaration = t7__namespace.variableDeclaration("const", [
1347
- t7__namespace.variableDeclarator(t7__namespace.identifier(resultsVar), batchCall)
1348
- ]);
1349
1468
  const reconstructCall = t7__namespace.callExpression(t7__namespace.memberExpression(t7__namespace.cloneNode(array, true), t7__namespace.identifier("map")), [
1350
1469
  reconstructMapper
1351
1470
  ]);
1352
- const iife = t7__namespace.callExpression(t7__namespace.arrowFunctionExpression([], t7__namespace.blockStatement([
1353
- resultsDeclaration,
1354
- t7__namespace.returnStatement(reconstructCall)
1355
- ]), true), []);
1471
+ const iife = t7__namespace.callExpression(t7__namespace.arrowFunctionExpression(
1472
+ [],
1473
+ t7__namespace.blockStatement([
1474
+ ...batchDeclarations,
1475
+ t7__namespace.returnStatement(reconstructCall)
1476
+ ]),
1477
+ true
1478
+ // async
1479
+ ), []);
1356
1480
  const awaitIife = t7__namespace.awaitExpression(iife);
1357
1481
  path.replaceWith(awaitIife);
1358
1482
  onTransform();
@@ -1387,10 +1511,13 @@ var ArrayTransformer = class {
1387
1511
  const batchResult = this.batchOptimizer.canBatchArrayMethod(callback);
1388
1512
  if (!batchResult.canBatch && methodName === "map") {
1389
1513
  const reason = batchResult.reason || "";
1390
- const hasObjectOrArrayReturn = reason.includes("object expression") || reason.includes("array expression");
1391
- if (hasObjectOrArrayReturn) {
1514
+ const canTryBatchReconstruct = reason.includes("object expression") || reason.includes("array expression") || reason.includes("Multiple pausable calls");
1515
+ if (canTryBatchReconstruct) {
1392
1516
  const llmCall = findLLMCallExpression(callback.body);
1393
- if (llmCall) {
1517
+ const itemParam = callback.params[0];
1518
+ const itemParamName = t7__namespace.isIdentifier(itemParam) ? itemParam.name : void 0;
1519
+ const hasDependencies = hasLLMCallDependencies(callback.body, this.batchDetector, itemParamName);
1520
+ if (llmCall && !hasDependencies) {
1394
1521
  const success = transformToBatchWithReconstruction(path, node, methodName, callback, this.batchDetector, () => this.transformCount++);
1395
1522
  if (success) {
1396
1523
  return true;