@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.
package/dist/index.js CHANGED
@@ -1051,6 +1051,34 @@ function objectExpressionToRecord(node, scope, source) {
1051
1051
  function isGsapTimelineCall(node) {
1052
1052
  return node?.type === "CallExpression" && node.callee?.type === "MemberExpression" && node.callee.object?.name === "gsap" && node.callee.property?.name === "timeline";
1053
1053
  }
1054
+ function staticMemberKey(node) {
1055
+ if (!node || node.type !== "MemberExpression") return null;
1056
+ if (node.computed) {
1057
+ const p = node.property;
1058
+ if (p?.type === "Literal" && typeof p.value === "string") return p.value;
1059
+ return null;
1060
+ }
1061
+ return node.property?.type === "Identifier" ? node.property.name : null;
1062
+ }
1063
+ function isStaticMemberRef(node) {
1064
+ return node?.type === "MemberExpression" && staticMemberKey(node) !== null;
1065
+ }
1066
+ function sameMemberAccess(a, b) {
1067
+ if (a?.type !== "MemberExpression" || b?.type !== "MemberExpression") return false;
1068
+ if (staticMemberKey(a) !== staticMemberKey(b) || staticMemberKey(a) === null) return false;
1069
+ const ao = a.object;
1070
+ const bo = b.object;
1071
+ if (ao?.type === "Identifier" && bo?.type === "Identifier") return ao.name === bo.name;
1072
+ if (ao?.type === "MemberExpression" && bo?.type === "MemberExpression")
1073
+ return sameMemberAccess(ao, bo);
1074
+ return false;
1075
+ }
1076
+ function timelineRootSource(ref, script) {
1077
+ return ref.kind === "identifier" ? ref.name : script.slice(ref.node.start, ref.node.end);
1078
+ }
1079
+ function escapeRegExp(s) {
1080
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1081
+ }
1054
1082
  function extractTimelineDefaults(callNode, scope) {
1055
1083
  const arg = callNode.arguments?.[0];
1056
1084
  if (!arg || arg.type !== "ObjectExpression") return void 0;
@@ -1070,6 +1098,7 @@ function extractTimelineDefaults(callNode, scope) {
1070
1098
  }
1071
1099
  function findTimelineVar(ast, scope) {
1072
1100
  let timelineVar = null;
1101
+ let ref = null;
1073
1102
  let timelineCount = 0;
1074
1103
  let defaults;
1075
1104
  const emptyScope = scope ?? /* @__PURE__ */ new Map();
@@ -1077,8 +1106,9 @@ function findTimelineVar(ast, scope) {
1077
1106
  VariableDeclarator(node) {
1078
1107
  if (isGsapTimelineCall(node.init)) {
1079
1108
  timelineCount += 1;
1080
- if (!timelineVar) {
1081
- timelineVar = node.id?.name ?? null;
1109
+ if (!ref && node.id?.type === "Identifier") {
1110
+ timelineVar = node.id.name;
1111
+ ref = { kind: "identifier", name: node.id.name };
1082
1112
  defaults = extractTimelineDefaults(node.init, emptyScope);
1083
1113
  }
1084
1114
  }
@@ -1086,15 +1116,21 @@ function findTimelineVar(ast, scope) {
1086
1116
  AssignmentExpression(node) {
1087
1117
  if (isGsapTimelineCall(node.right)) {
1088
1118
  timelineCount += 1;
1089
- if (!timelineVar) {
1119
+ if (!ref) {
1090
1120
  const left = node.left;
1091
- if (left?.type === "Identifier") timelineVar = left.name;
1092
- defaults = extractTimelineDefaults(node.right, emptyScope);
1121
+ if (left?.type === "Identifier") {
1122
+ timelineVar = left.name;
1123
+ ref = { kind: "identifier", name: left.name };
1124
+ defaults = extractTimelineDefaults(node.right, emptyScope);
1125
+ } else if (isStaticMemberRef(left)) {
1126
+ ref = { kind: "member", node: left };
1127
+ defaults = extractTimelineDefaults(node.right, emptyScope);
1128
+ }
1093
1129
  }
1094
1130
  }
1095
1131
  }
1096
1132
  });
1097
- return { timelineVar, timelineCount, defaults };
1133
+ return { timelineVar, ref, timelineCount, defaults };
1098
1134
  }
1099
1135
  var BUILTIN_VAR_KEYS = /* @__PURE__ */ new Set(["duration", "ease", "delay"]);
1100
1136
  var DROPPED_VAR_KEYS = /* @__PURE__ */ new Set(["onComplete", "onStart", "onUpdate", "onRepeat"]);
@@ -1107,14 +1143,15 @@ var EXTRAS_KEYS = /* @__PURE__ */ new Set([
1107
1143
  "overwrite",
1108
1144
  "immediateRender"
1109
1145
  ]);
1110
- function isTimelineRootedCall(callNode, timelineVar) {
1146
+ function isTimelineRootedCall(callNode, ref) {
1111
1147
  let obj = callNode.callee?.object;
1112
1148
  while (obj?.type === "CallExpression") {
1113
1149
  obj = obj.callee?.object;
1114
1150
  }
1115
- return obj?.type === "Identifier" && obj.name === timelineVar;
1151
+ if (ref.kind === "identifier") return obj?.type === "Identifier" && obj.name === ref.name;
1152
+ return sameMemberAccess(obj, ref.node);
1116
1153
  }
1117
- function findAllTweenCalls(ast, timelineVar, scope, targetBindings) {
1154
+ function findAllTweenCalls(ast, ref, scope, targetBindings) {
1118
1155
  const results = [];
1119
1156
  function visit(node, ancestors) {
1120
1157
  if (!node || typeof node !== "object") return;
@@ -1123,7 +1160,7 @@ function findAllTweenCalls(ast, timelineVar, scope, targetBindings) {
1123
1160
  const callee = node.callee;
1124
1161
  const gsapSetArg = node.arguments?.[0];
1125
1162
  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");
1126
- if (callee?.type === "MemberExpression" && callee.property?.type === "Identifier" && (isTimelineRootedCall(node, timelineVar) || isGlobalSet) && GSAP_METHODS2.has(callee.property.name)) {
1163
+ if (callee?.type === "MemberExpression" && callee.property?.type === "Identifier" && (isTimelineRootedCall(node, ref) || isGlobalSet) && GSAP_METHODS2.has(callee.property.name)) {
1127
1164
  const method = callee.property.name;
1128
1165
  const args = node.arguments;
1129
1166
  const selectorValue = args.length >= 1 ? resolveTargetSelector(args[0], nodeAncestors, scope, targetBindings) ?? "__unresolved__" : "__unresolved__";
@@ -1576,8 +1613,9 @@ function parseGsapScriptAcornForWrite(script) {
1576
1613
  const scope = collectScopeBindings(ast);
1577
1614
  const targetBindings = collectTargetBindings(ast, scope);
1578
1615
  const detection = findTimelineVar(ast, scope);
1579
- const timelineVar = detection.timelineVar ?? "tl";
1580
- const calls = findAllTweenCalls(ast, timelineVar, scope, targetBindings);
1616
+ const ref = detection.ref ?? { kind: "identifier", name: "tl" };
1617
+ const timelineVar = timelineRootSource(ref, script);
1618
+ const calls = findAllTweenCalls(ast, ref, scope, targetBindings);
1581
1619
  sortBySourcePosition(calls);
1582
1620
  const rawAnims = calls.map((call) => tweenCallToAnimation(call, scope, script));
1583
1621
  applyTimelineDefaults(rawAnims, detection.defaults);
@@ -1588,7 +1626,7 @@ function parseGsapScriptAcornForWrite(script) {
1588
1626
  call,
1589
1627
  animation: animations[i]
1590
1628
  }));
1591
- return { ast, timelineVar, hasTimeline: detection.timelineVar !== null, located };
1629
+ return { ast, timelineVar, hasTimeline: detection.ref !== null, located };
1592
1630
  } catch {
1593
1631
  return null;
1594
1632
  }
@@ -1602,24 +1640,25 @@ function parseGsapScriptAcorn(script) {
1602
1640
  });
1603
1641
  const scope = collectScopeBindings(ast);
1604
1642
  const detection = findTimelineVar(ast, scope);
1605
- const timelineVar = detection.timelineVar ?? "tl";
1606
- try {
1607
- inlineComputedTimelines(ast, timelineVar, (node) => resolveNode(node, scope));
1608
- } catch {
1643
+ const ref = detection.ref ?? { kind: "identifier", name: "tl" };
1644
+ const timelineVar = timelineRootSource(ref, script);
1645
+ if (ref.kind === "identifier") {
1646
+ try {
1647
+ inlineComputedTimelines(ast, timelineVar, (node) => resolveNode(node, scope));
1648
+ } catch {
1649
+ }
1609
1650
  }
1610
1651
  const targetBindings = collectTargetBindings(ast, scope);
1611
- const calls = findAllTweenCalls(ast, timelineVar, scope, targetBindings);
1652
+ const calls = findAllTweenCalls(ast, ref, scope, targetBindings);
1612
1653
  sortBySourcePosition(calls);
1613
1654
  const rawAnims = calls.map((call) => tweenCallToAnimation(call, scope, script));
1614
1655
  applyTimelineDefaults(rawAnims, detection.defaults);
1615
1656
  resolveTimelinePositions(rawAnims);
1616
1657
  const animations = assignStableIds(rawAnims);
1617
- const timelineMatch = script.match(
1618
- new RegExp(
1619
- `^[\\s\\S]*?(?:const|let|var)\\s+${timelineVar}\\s*=\\s*gsap\\.timeline\\s*\\([^)]*\\)\\s*;?`
1620
- )
1621
- );
1622
- const preamble = timelineMatch?.[0] ?? `const ${timelineVar} = gsap.timeline({ paused: true });`;
1658
+ const declPattern = ref.kind === "identifier" ? `(?:const|let|var)\\s+${timelineVar}\\s*=\\s*gsap\\.timeline\\s*\\([^)]*\\)\\s*;?` : `${escapeRegExp(timelineVar)}\\s*=\\s*gsap\\.timeline\\s*\\([^)]*\\)\\s*;?`;
1659
+ const timelineMatch = script.match(new RegExp(`^[\\s\\S]*?${declPattern}`));
1660
+ const fallbackPreamble = ref.kind === "identifier" ? `const ${timelineVar} = gsap.timeline({ paused: true });` : `${timelineVar} = gsap.timeline({ paused: true });`;
1661
+ const preamble = timelineMatch?.[0] ?? fallbackPreamble;
1623
1662
  const lastCallIdx = script.lastIndexOf(`${timelineVar}.`);
1624
1663
  let postamble = "";
1625
1664
  if (lastCallIdx !== -1) {
@@ -1631,7 +1670,7 @@ function parseGsapScriptAcorn(script) {
1631
1670
  }
1632
1671
  const result = { animations, timelineVar, preamble, postamble };
1633
1672
  if (detection.timelineCount > 1) result.multipleTimelines = true;
1634
- if (detection.timelineCount > 0 && detection.timelineVar === null)
1673
+ if (detection.timelineCount > 0 && detection.ref === null)
1635
1674
  result.unsupportedTimelinePattern = true;
1636
1675
  return result;
1637
1676
  } catch {