@hyperframes/parsers 0.8.126 → 0.8.128

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.
@@ -1,5 +1,19 @@
1
- export { A as ArcPathConfig, a as ArcPathSegment, G as GsapAnimation, b as GsapKeyframesData, c as GsapMethod, d as GsapPercentageKeyframe, e as GsapProvenance, f as GsapProvenanceKind, K as KeyframeEditability, P as PROPERTY_GROUPS, g as ParsedGsap, h as PropertyGroupName, S as SUPPORTED_EASES, i as SUPPORTED_PROPS, j as SourcedGsapPercentageKeyframe, k as SplitAnimationsOptions, l as SplitAnimationsResult, m as classifyPropertyGroup, n as classifyTweenPropertyGroup, o as editabilityForProvenance, p as getAnimationsForElementId, q as gsapAnimationsToKeyframes, r as keyframesToGsapAnimations, s as serializeGsapAnimations, v as validateCompositionGsap } from './gsapSerialize-CVwsMItk.js';
1
+ export { A as ArcPathConfig, b as ArcPathSegment, u as GSAP_DEFAULT_DURATION, a as GsapAnimation, h as GsapKeyframesData, G as GsapMethod, i as GsapPercentageKeyframe, c as GsapProvenance, d as GsapProvenanceKind, K as KeyframeEditability, j as PROPERTY_GROUPS, P as ParsedGsap, k as PropertyGroupName, S as SUPPORTED_EASES, l as SUPPORTED_PROPS, w as SourcedGsapPercentageKeyframe, r as SplitAnimationsOptions, t as SplitAnimationsResult, m as classifyPropertyGroup, n as classifyTweenPropertyGroup, f as editabilityForProvenance, o as getAnimationsForElementId, p as gsapAnimationsToKeyframes, q as keyframesToGsapAnimations, s as serializeGsapAnimations, v as validateCompositionGsap } from './gsapSerialize-CfSXM_Ez.js';
2
2
  export { isStudioHoldSet } from './gsapParser.js';
3
3
  export { SPRING_PRESETS, SpringPreset, generateSpringEaseData } from './springEase.js';
4
4
  export { parseGsapScriptAcorn as parseGsapScript } from './gsapParserAcorn.js';
5
5
  import './types-Ejqndkej.js';
6
+
7
+ interface ObjectArrayKeyframeTiming {
8
+ percentages: number[];
9
+ totalDuration: number;
10
+ }
11
+ /**
12
+ * Resolve GSAP object-array keyframe positions exactly once for parsers and writers.
13
+ * Each step's keyframe sits at its cumulative end; a step without a duration plays
14
+ * GSAP's default. A non-positive or unresolved duration leaves the timing unresolved:
15
+ * callers must preserve the source rather than silently invent different timing.
16
+ */
17
+ declare function getObjectArrayKeyframeTiming(durations: ReadonlyArray<unknown>): ObjectArrayKeyframeTiming | null;
18
+
19
+ export { getObjectArrayKeyframeTiming };
@@ -1,4 +1,5 @@
1
1
  // src/gsapConstants.ts
2
+ var GSAP_DEFAULT_DURATION = 0.5;
2
3
  var SUPPORTED_PROPS = [
3
4
  // 2D Transforms
4
5
  "x",
@@ -39,6 +40,22 @@ var SUPPORTED_PROPS = [
39
40
  // DOM content (number counters, text roll-ups)
40
41
  "innerText"
41
42
  ];
43
+ var BUILTIN_VAR_KEYS = /* @__PURE__ */ new Set(["duration", "ease", "delay"]);
44
+ var DROPPED_VAR_KEYS = /* @__PURE__ */ new Set([
45
+ "onComplete",
46
+ "onStart",
47
+ "onUpdate",
48
+ "onRepeat"
49
+ ]);
50
+ var EXTRAS_KEYS = /* @__PURE__ */ new Set([
51
+ "stagger",
52
+ "yoyo",
53
+ "repeat",
54
+ "repeatDelay",
55
+ "snap",
56
+ "overwrite",
57
+ "immediateRender"
58
+ ]);
42
59
  var PROPERTY_GROUPS = {
43
60
  position: /* @__PURE__ */ new Set(["x", "y", "xPercent", "yPercent"]),
44
61
  scale: /* @__PURE__ */ new Set(["scale", "scaleX", "scaleY"]),
@@ -329,28 +346,20 @@ import { parse as babelParse } from "@babel/parser";
329
346
  // src/gsapObjectArrayTiming.ts
330
347
  var roundPercentage = (percentage) => Math.round(percentage * 10) / 10;
331
348
  function getObjectArrayKeyframeTiming(durations) {
332
- const hasAuthoredDuration = durations.some((duration) => duration !== void 0);
333
- if (hasAuthoredDuration) {
334
- if (!durations.every(
335
- (duration) => typeof duration === "number" && Number.isFinite(duration) && duration > 0
336
- )) {
337
- return null;
338
- }
339
- const totalDuration = durations.reduce((sum, duration) => sum + duration, 0);
340
- let cumulative = 0;
341
- return {
342
- percentages: durations.map((duration) => {
343
- cumulative += duration;
344
- return roundPercentage(cumulative / totalDuration * 100);
345
- }),
346
- totalDuration
347
- };
349
+ const steps = durations.map((duration) => duration ?? GSAP_DEFAULT_DURATION);
350
+ if (!steps.every(
351
+ (duration) => typeof duration === "number" && Number.isFinite(duration) && duration > 0
352
+ )) {
353
+ return null;
348
354
  }
349
- const lastIndex = durations.length - 1;
355
+ const totalDuration = steps.reduce((sum, duration) => sum + duration, 0);
356
+ let cumulative = 0;
350
357
  return {
351
- percentages: durations.map(
352
- (_, index) => lastIndex > 0 ? roundPercentage(index / lastIndex * 100) : 0
353
- )
358
+ percentages: steps.map((duration) => {
359
+ cumulative += duration;
360
+ return roundPercentage(cumulative / totalDuration * 100);
361
+ }),
362
+ totalDuration
354
363
  };
355
364
  }
356
365
 
@@ -1445,17 +1454,6 @@ function findTimelineVar(ast, scope) {
1445
1454
  });
1446
1455
  return { timelineVar, ref, timelineCount, defaults };
1447
1456
  }
1448
- var BUILTIN_VAR_KEYS = /* @__PURE__ */ new Set(["duration", "ease", "delay"]);
1449
- var DROPPED_VAR_KEYS = /* @__PURE__ */ new Set(["onComplete", "onStart", "onUpdate", "onRepeat"]);
1450
- var EXTRAS_KEYS = /* @__PURE__ */ new Set([
1451
- "stagger",
1452
- "yoyo",
1453
- "repeat",
1454
- "repeatDelay",
1455
- "snap",
1456
- "overwrite",
1457
- "immediateRender"
1458
- ]);
1459
1457
  function isTimelineRootedCall(callNode, ref) {
1460
1458
  let obj = callNode.callee?.object;
1461
1459
  while (obj?.type === "CallExpression") {
@@ -1534,6 +1532,7 @@ function parsePercentageKeyframes(node, scope, source) {
1534
1532
  if (typeof key !== "string") continue;
1535
1533
  const pctMatch = PERCENTAGE_KEY_RE.exec(key);
1536
1534
  if (pctMatch) {
1535
+ if (!isPlainStep(prop.value)) return void 0;
1537
1536
  const percentage = Number.parseFloat(pctMatch[1] ?? "0");
1538
1537
  const record = objectExpressionToRecord(prop.value, scope, source);
1539
1538
  const properties = {};
@@ -1552,6 +1551,8 @@ function parsePercentageKeyframes(node, scope, source) {
1552
1551
  ease = tryResolveStringProp(prop.value, scope, source) ?? ease;
1553
1552
  } else if (key === "easeEach") {
1554
1553
  easeEach = tryResolveStringProp(prop.value, scope, source) ?? easeEach;
1554
+ } else {
1555
+ return void 0;
1555
1556
  }
1556
1557
  }
1557
1558
  keyframes.sort((a, b) => a.percentage - b.percentage);
@@ -1575,11 +1576,19 @@ function computeKeyframesTotalDuration(varsNode, scope, source) {
1575
1576
  }
1576
1577
  return getObjectArrayKeyframeTiming(durations)?.totalDuration;
1577
1578
  }
1579
+ function staticKeyName(prop) {
1580
+ if (prop.type !== "ObjectProperty" && prop.type !== "Property") return void 0;
1581
+ if (prop.method || prop.kind && prop.kind !== "init") return void 0;
1582
+ const key = prop.computed ? prop.key?.type === "Literal" && prop.key.value : prop.key?.name ?? prop.key?.value;
1583
+ return typeof key === "string" ? key : void 0;
1584
+ }
1585
+ var isPlainObject = (node) => node?.type === "ObjectExpression" && (node.properties ?? []).every((p) => staticKeyName(p) !== void 0);
1586
+ var isPlainStep = (node) => node?.type === "Literal" || isPlainObject(node);
1578
1587
  function parseObjectArrayKeyframes(node, scope, source) {
1579
1588
  const elements = node.elements ?? [];
1580
1589
  const raw = [];
1581
1590
  for (const el of elements) {
1582
- if (!el || el.type !== "ObjectExpression") continue;
1591
+ if (!isPlainObject(el)) return void 0;
1583
1592
  const record = objectExpressionToRecord(el, scope, source);
1584
1593
  const properties = {};
1585
1594
  let duration;
@@ -1591,6 +1600,8 @@ function parseObjectArrayKeyframes(node, scope, source) {
1591
1600
  ease = v;
1592
1601
  } else if (typeof v === "number" || typeof v === "string") {
1593
1602
  properties[k] = v;
1603
+ } else {
1604
+ return void 0;
1594
1605
  }
1595
1606
  }
1596
1607
  raw.push({ properties, duration, ease });
@@ -1616,9 +1627,8 @@ function parseSimpleArrayKeyframes(node, scope) {
1616
1627
  const values = [];
1617
1628
  for (const el of prop.value.elements ?? []) {
1618
1629
  const val = resolveNode(el, scope);
1619
- if (typeof val === "number" || typeof val === "string") {
1620
- values.push(val);
1621
- }
1630
+ if (typeof val !== "number" && typeof val !== "string") return void 0;
1631
+ values.push(val);
1622
1632
  }
1623
1633
  if (values.length > 0) arrayProps.set(key, values);
1624
1634
  } else if (key === "ease") {
@@ -1651,6 +1661,7 @@ function parseKeyframesNode(node, scope, source) {
1651
1661
  }
1652
1662
  if (node.type !== "ObjectExpression") return void 0;
1653
1663
  const props = node.properties ?? [];
1664
+ if (!props.every((p) => staticKeyName(p) !== void 0)) return void 0;
1654
1665
  let hasPercentageKey = false;
1655
1666
  let hasArrayValue = false;
1656
1667
  for (const prop of props) {
@@ -1751,7 +1762,7 @@ function tweenCallToAnimation(call, scope, source, identifierBindings) {
1751
1762
  percentage: waypoints.length > 1 ? Math.round(i / (waypoints.length - 1) * 100) : 0,
1752
1763
  properties: { x: wp.x, y: wp.y }
1753
1764
  }));
1754
- keyframesData = { format: "percentage", keyframes: kf };
1765
+ keyframesData = { format: "percentage", keyframes: kf, fromMotionPath: true };
1755
1766
  } else {
1756
1767
  const kfs = keyframesData.keyframes;
1757
1768
  if (kfs.length === waypoints.length) {
@@ -1781,10 +1792,10 @@ function tweenCallToAnimation(call, scope, source, identifierBindings) {
1781
1792
  const position = typeof posVal === "number" ? posVal : typeof posVal === "string" ? posVal : hasPositionArg ? `__raw:${source.slice(call.positionArg.start, call.positionArg.end)}` : 0;
1782
1793
  let duration = typeof vars.duration === "number" ? vars.duration : void 0;
1783
1794
  const ease = typeof vars.ease === "string" ? vars.ease : void 0;
1784
- if (duration === void 0 && keyframesData) {
1795
+ const durationUnresolved = call.method !== "set" && duration === void 0 && hasUnknownDuration(call.varsArg, scope);
1796
+ if (duration === void 0 && keyframesData && !durationUnresolved) {
1785
1797
  duration = computeKeyframesTotalDuration(call.varsArg, scope, source);
1786
1798
  }
1787
- const durationUnresolved = call.method !== "set" && duration === void 0 && hasUnknownDuration(call.varsArg, scope);
1788
1799
  let selector = call.selector;
1789
1800
  let targetIdentity;
1790
1801
  if (selector === "__unresolved__") {
@@ -1879,7 +1890,6 @@ function annotateStaggeredCollections(anims) {
1879
1890
  anim.keyframes = { format: "percentage", keyframes: staggeredKeyframes(anim, each) };
1880
1891
  }
1881
1892
  }
1882
- var GSAP_DEFAULT_DURATION = 0.5;
1883
1893
  function resolvePositionString(pos, cursor, prevStart) {
1884
1894
  const trimmed = pos.trim();
1885
1895
  if (trimmed === "") return cursor;
@@ -1961,7 +1971,7 @@ function applyTimelineDefaults(anims, defaults) {
1961
1971
  if (defaults.duration !== void 0) anim.duration = defaults.duration;
1962
1972
  else if (defaults.durationUnresolved) anim.durationUnresolved = true;
1963
1973
  }
1964
- if (anim.ease === void 0 && defaults.ease !== void 0 && !anim.keyframes) {
1974
+ if (anim.ease === void 0 && defaults.ease !== void 0 && (!anim.keyframes || anim.keyframes.fromMotionPath)) {
1965
1975
  anim.ease = defaults.ease;
1966
1976
  }
1967
1977
  }
@@ -2152,6 +2162,7 @@ function parseGsapScriptAcornUncached(script) {
2152
2162
  }
2153
2163
  }
2154
2164
  export {
2165
+ GSAP_DEFAULT_DURATION,
2155
2166
  PROPERTY_GROUPS,
2156
2167
  SPRING_PRESETS,
2157
2168
  SUPPORTED_EASES,
@@ -2161,6 +2172,7 @@ export {
2161
2172
  editabilityForProvenance,
2162
2173
  generateSpringEaseData,
2163
2174
  getAnimationsForElementId,
2175
+ getObjectArrayKeyframeTiming,
2164
2176
  gsapAnimationsToKeyframes,
2165
2177
  isStudioHoldSet,
2166
2178
  keyframesToGsapAnimations,