Skip to content

Commit 01039fa

Browse files
committed
feat(core): acorn GSAP write path — magic-string offset-splice (T6c)
1 parent 213cd0d commit 01039fa

5 files changed

Lines changed: 704 additions & 10 deletions

File tree

bun.lock

Lines changed: 10 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/core/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@
202202
"@chenglou/pretext": "^0.0.5",
203203
"acorn": "^8.17.0",
204204
"acorn-walk": "^8.3.5",
205+
"magic-string": "^0.30.21",
205206
"postcss": "^8.5.8",
206207
"postcss-selector-parser": "^7.1.2",
207208
"recast": "^0.23.11"

packages/core/src/parsers/gsapParserAcorn.ts

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,7 @@ const EXTRAS_KEYS = new Set([
419419
"immediateRender",
420420
]);
421421

422-
interface TweenCallInfo {
422+
export interface TweenCallInfo {
423423
node: any;
424424
/** acorn-walk ancestor array at the call site (root→call, call is last). */
425425
ancestors: any[];
@@ -1041,6 +1041,46 @@ function assignStableIds(anims: Omit<GsapAnimation, "id">[]): GsapAnimation[] {
10411041
});
10421042
}
10431043

1044+
// ── Write-path internal parse ─────────────────────────────────────────────────
1045+
1046+
export interface ParsedGsapAcornForWrite {
1047+
ast: any;
1048+
timelineVar: string;
1049+
located: Array<{ id: string; call: TweenCallInfo; animation: GsapAnimation }>;
1050+
}
1051+
1052+
/**
1053+
* Parse a GSAP script and return internal AST + call nodes for the write path.
1054+
* Consumed by gsapWriterAcorn.ts (magic-string offset-splice).
1055+
*/
1056+
export function parseGsapScriptAcornForWrite(script: string): ParsedGsapAcornForWrite | null {
1057+
try {
1058+
const ast = acorn.parse(script, {
1059+
ecmaVersion: "latest",
1060+
sourceType: "script",
1061+
locations: true,
1062+
});
1063+
const scope = collectScopeBindings(ast);
1064+
const targetBindings = collectTargetBindings(ast, scope);
1065+
const detection = findTimelineVar(ast, scope);
1066+
const timelineVar = detection.timelineVar ?? "tl";
1067+
const calls = findAllTweenCalls(ast, timelineVar, scope, targetBindings);
1068+
sortBySourcePosition(calls);
1069+
const rawAnims = calls.map((call) => tweenCallToAnimation(call, scope, script));
1070+
applyTimelineDefaults(rawAnims, detection.defaults);
1071+
resolveTimelinePositions(rawAnims);
1072+
const animations = assignStableIds(rawAnims);
1073+
const located = calls.map((call, i) => ({
1074+
id: animations[i]!.id,
1075+
call,
1076+
animation: animations[i]!,
1077+
}));
1078+
return { ast, timelineVar, located };
1079+
} catch {
1080+
return null;
1081+
}
1082+
}
1083+
10441084
// ── Public API ────────────────────────────────────────────────────────────────
10451085

10461086
/**

0 commit comments

Comments
 (0)