@hyperframes/parsers 0.7.15 → 0.7.16

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.
@@ -978,6 +978,34 @@ function objectExpressionToRecord(node, scope, source) {
978
978
  function isGsapTimelineCall(node) {
979
979
  return node?.type === "CallExpression" && node.callee?.type === "MemberExpression" && node.callee.object?.name === "gsap" && node.callee.property?.name === "timeline";
980
980
  }
981
+ function staticMemberKey(node) {
982
+ if (!node || node.type !== "MemberExpression") return null;
983
+ if (node.computed) {
984
+ const p = node.property;
985
+ if (p?.type === "Literal" && typeof p.value === "string") return p.value;
986
+ return null;
987
+ }
988
+ return node.property?.type === "Identifier" ? node.property.name : null;
989
+ }
990
+ function isStaticMemberRef(node) {
991
+ return node?.type === "MemberExpression" && staticMemberKey(node) !== null;
992
+ }
993
+ function sameMemberAccess(a, b) {
994
+ if (a?.type !== "MemberExpression" || b?.type !== "MemberExpression") return false;
995
+ if (staticMemberKey(a) !== staticMemberKey(b) || staticMemberKey(a) === null) return false;
996
+ const ao = a.object;
997
+ const bo = b.object;
998
+ if (ao?.type === "Identifier" && bo?.type === "Identifier") return ao.name === bo.name;
999
+ if (ao?.type === "MemberExpression" && bo?.type === "MemberExpression")
1000
+ return sameMemberAccess(ao, bo);
1001
+ return false;
1002
+ }
1003
+ function timelineRootSource(ref, script) {
1004
+ return ref.kind === "identifier" ? ref.name : script.slice(ref.node.start, ref.node.end);
1005
+ }
1006
+ function escapeRegExp(s) {
1007
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1008
+ }
981
1009
  function extractTimelineDefaults(callNode, scope) {
982
1010
  const arg = callNode.arguments?.[0];
983
1011
  if (!arg || arg.type !== "ObjectExpression") return void 0;
@@ -997,6 +1025,7 @@ function extractTimelineDefaults(callNode, scope) {
997
1025
  }
998
1026
  function findTimelineVar(ast, scope) {
999
1027
  let timelineVar = null;
1028
+ let ref = null;
1000
1029
  let timelineCount = 0;
1001
1030
  let defaults;
1002
1031
  const emptyScope = scope ?? /* @__PURE__ */ new Map();
@@ -1004,8 +1033,9 @@ function findTimelineVar(ast, scope) {
1004
1033
  VariableDeclarator(node) {
1005
1034
  if (isGsapTimelineCall(node.init)) {
1006
1035
  timelineCount += 1;
1007
- if (!timelineVar) {
1008
- timelineVar = node.id?.name ?? null;
1036
+ if (!ref && node.id?.type === "Identifier") {
1037
+ timelineVar = node.id.name;
1038
+ ref = { kind: "identifier", name: node.id.name };
1009
1039
  defaults = extractTimelineDefaults(node.init, emptyScope);
1010
1040
  }
1011
1041
  }
@@ -1013,15 +1043,21 @@ function findTimelineVar(ast, scope) {
1013
1043
  AssignmentExpression(node) {
1014
1044
  if (isGsapTimelineCall(node.right)) {
1015
1045
  timelineCount += 1;
1016
- if (!timelineVar) {
1046
+ if (!ref) {
1017
1047
  const left = node.left;
1018
- if (left?.type === "Identifier") timelineVar = left.name;
1019
- defaults = extractTimelineDefaults(node.right, emptyScope);
1048
+ if (left?.type === "Identifier") {
1049
+ timelineVar = left.name;
1050
+ ref = { kind: "identifier", name: left.name };
1051
+ defaults = extractTimelineDefaults(node.right, emptyScope);
1052
+ } else if (isStaticMemberRef(left)) {
1053
+ ref = { kind: "member", node: left };
1054
+ defaults = extractTimelineDefaults(node.right, emptyScope);
1055
+ }
1020
1056
  }
1021
1057
  }
1022
1058
  }
1023
1059
  });
1024
- return { timelineVar, timelineCount, defaults };
1060
+ return { timelineVar, ref, timelineCount, defaults };
1025
1061
  }
1026
1062
  var BUILTIN_VAR_KEYS = /* @__PURE__ */ new Set(["duration", "ease", "delay"]);
1027
1063
  var DROPPED_VAR_KEYS = /* @__PURE__ */ new Set(["onComplete", "onStart", "onUpdate", "onRepeat"]);
@@ -1034,14 +1070,15 @@ var EXTRAS_KEYS = /* @__PURE__ */ new Set([
1034
1070
  "overwrite",
1035
1071
  "immediateRender"
1036
1072
  ]);
1037
- function isTimelineRootedCall(callNode, timelineVar) {
1073
+ function isTimelineRootedCall(callNode, ref) {
1038
1074
  let obj = callNode.callee?.object;
1039
1075
  while (obj?.type === "CallExpression") {
1040
1076
  obj = obj.callee?.object;
1041
1077
  }
1042
- return obj?.type === "Identifier" && obj.name === timelineVar;
1078
+ if (ref.kind === "identifier") return obj?.type === "Identifier" && obj.name === ref.name;
1079
+ return sameMemberAccess(obj, ref.node);
1043
1080
  }
1044
- function findAllTweenCalls(ast, timelineVar, scope, targetBindings) {
1081
+ function findAllTweenCalls(ast, ref, scope, targetBindings) {
1045
1082
  const results = [];
1046
1083
  function visit(node, ancestors) {
1047
1084
  if (!node || typeof node !== "object") return;
@@ -1050,7 +1087,7 @@ function findAllTweenCalls(ast, timelineVar, scope, targetBindings) {
1050
1087
  const callee = node.callee;
1051
1088
  const gsapSetArg = node.arguments?.[0];
1052
1089
  const isGlobalSet = callee?.type === "MemberExpression" && callee.object?.type === "Identifier" && callee.object.name === "gsap" && callee.property?.type === "Identifier" && callee.property.name === "set" && (gsapSetArg?.type === "StringLiteral" || gsapSetArg?.type === "Literal" && typeof gsapSetArg.value === "string");
1053
- if (callee?.type === "MemberExpression" && callee.property?.type === "Identifier" && (isTimelineRootedCall(node, timelineVar) || isGlobalSet) && GSAP_METHODS2.has(callee.property.name)) {
1090
+ if (callee?.type === "MemberExpression" && callee.property?.type === "Identifier" && (isTimelineRootedCall(node, ref) || isGlobalSet) && GSAP_METHODS2.has(callee.property.name)) {
1054
1091
  const method = callee.property.name;
1055
1092
  const args = node.arguments;
1056
1093
  const selectorValue = args.length >= 1 ? resolveTargetSelector(args[0], nodeAncestors, scope, targetBindings) ?? "__unresolved__" : "__unresolved__";
@@ -1502,24 +1539,25 @@ function parseGsapScriptAcorn(script) {
1502
1539
  });
1503
1540
  const scope = collectScopeBindings(ast);
1504
1541
  const detection = findTimelineVar(ast, scope);
1505
- const timelineVar = detection.timelineVar ?? "tl";
1506
- try {
1507
- inlineComputedTimelines(ast, timelineVar, (node) => resolveNode(node, scope));
1508
- } catch {
1542
+ const ref = detection.ref ?? { kind: "identifier", name: "tl" };
1543
+ const timelineVar = timelineRootSource(ref, script);
1544
+ if (ref.kind === "identifier") {
1545
+ try {
1546
+ inlineComputedTimelines(ast, timelineVar, (node) => resolveNode(node, scope));
1547
+ } catch {
1548
+ }
1509
1549
  }
1510
1550
  const targetBindings = collectTargetBindings(ast, scope);
1511
- const calls = findAllTweenCalls(ast, timelineVar, scope, targetBindings);
1551
+ const calls = findAllTweenCalls(ast, ref, scope, targetBindings);
1512
1552
  sortBySourcePosition(calls);
1513
1553
  const rawAnims = calls.map((call) => tweenCallToAnimation(call, scope, script));
1514
1554
  applyTimelineDefaults(rawAnims, detection.defaults);
1515
1555
  resolveTimelinePositions(rawAnims);
1516
1556
  const animations = assignStableIds(rawAnims);
1517
- const timelineMatch = script.match(
1518
- new RegExp(
1519
- `^[\\s\\S]*?(?:const|let|var)\\s+${timelineVar}\\s*=\\s*gsap\\.timeline\\s*\\([^)]*\\)\\s*;?`
1520
- )
1521
- );
1522
- const preamble = timelineMatch?.[0] ?? `const ${timelineVar} = gsap.timeline({ paused: true });`;
1557
+ const declPattern = ref.kind === "identifier" ? `(?:const|let|var)\\s+${timelineVar}\\s*=\\s*gsap\\.timeline\\s*\\([^)]*\\)\\s*;?` : `${escapeRegExp(timelineVar)}\\s*=\\s*gsap\\.timeline\\s*\\([^)]*\\)\\s*;?`;
1558
+ const timelineMatch = script.match(new RegExp(`^[\\s\\S]*?${declPattern}`));
1559
+ const fallbackPreamble = ref.kind === "identifier" ? `const ${timelineVar} = gsap.timeline({ paused: true });` : `${timelineVar} = gsap.timeline({ paused: true });`;
1560
+ const preamble = timelineMatch?.[0] ?? fallbackPreamble;
1523
1561
  const lastCallIdx = script.lastIndexOf(`${timelineVar}.`);
1524
1562
  let postamble = "";
1525
1563
  if (lastCallIdx !== -1) {
@@ -1531,7 +1569,7 @@ function parseGsapScriptAcorn(script) {
1531
1569
  }
1532
1570
  const result = { animations, timelineVar, preamble, postamble };
1533
1571
  if (detection.timelineCount > 1) result.multipleTimelines = true;
1534
- if (detection.timelineCount > 0 && detection.timelineVar === null)
1572
+ if (detection.timelineCount > 0 && detection.ref === null)
1535
1573
  result.unsupportedTimelinePattern = true;
1536
1574
  return result;
1537
1575
  } catch {