Skip to content

feat(sdk): stage 4 — canUndo/canRedo, removeElement GSAP cascade, override-set cleanup#1431

Open
vanceingalls wants to merge 1 commit into
06-13-feat_sdk_can_returns_canresult_t4_dispatch-boundary_testsfrom
06-14-feat_sdk_stage_4_canundo_canredo_removeelement_gsap_cascade_override-set_cleanup
Open

feat(sdk): stage 4 — canUndo/canRedo, removeElement GSAP cascade, override-set cleanup#1431
vanceingalls wants to merge 1 commit into
06-13-feat_sdk_can_returns_canresult_t4_dispatch-boundary_testsfrom
06-14-feat_sdk_stage_4_canundo_canredo_removeelement_gsap_cascade_override-set_cleanup

Conversation

@vanceingalls

@vanceingalls vanceingalls commented Jun 14, 2026

Copy link
Copy Markdown
Collaborator

What

Stage 4 of the SDK — three features that complete the public history/editing API:

  1. canUndo() / canRedo() on Composition — exposes the history module's existing state predicates on the public interface so hosts can enable/disable undo buttons without keeping their own patch counter.

  2. removeElement GSAP cascade — when removing an element, its targeting GSAP animations are also removed from the script and the change is folded into the same forward/inverse patch pair. Undo restores both the element and its animations atomically.

  3. Override-set orphan cleanup — after removing an element, its per-property override-set keys (hf-x.style.fontSize, hf-x.text, etc.) are purged. Keeps T3 serialized override-sets compact and avoids stale key replay on future session opens.

Also extracted selectorMatchesId / cascadeRemoveAnimations helpers to deduplicate the GSAP-target-matching pattern from handleSetTiming and reduce cognitive complexity.

Why

  • canUndo/canRedo are needed for Studio toolbar state and any playground UI.
  • Without the GSAP cascade, removing a composition element leaves dangling animation code in the script — those animations would run against a null target and generate console errors at runtime.
  • Without override-set cleanup, a T3 session opened with stale property keys tries (harmlessly but wastefully) to apply styles to non-existent elements on every open.

Changes

File Change
src/types.ts Add canUndo(): boolean / canRedo(): boolean to Composition interface
src/session.ts Implement canUndo/canRedo delegating to historyModule; add override-set orphan purge in _dispatch
src/engine/mutate.ts handleRemoveElement GSAP cascade via new cascadeRemoveAnimations / selectorMatchesId helpers; same helpers used by handleSetTiming to eliminate duplication
src/session.test.ts canUndo/canRedo lifecycle tests (6 cases); override-set orphan cleanup tests (2 cases)
src/engine/mutate.gsap.test.ts removeElement GSAP cascade tests (5 cases)

Test plan

  • bun run test in packages/sdk — 156 tests pass
  • Remove an element with targeting GSAP tweens; verify script no longer references that element
  • Undo the removal; verify element AND script are restored atomically
  • comp.setStyle(id, ...) then comp.removeElement(id); verify getOverrides() shows no id.* keys
  • comp.canUndo() returns false before mutations, true after, false after undo back to start

🤖 Generated with Claude Code

@vanceingalls vanceingalls changed the base branch from 06-13-docs_sdk-playground_accurate_readme_with_stage_coverage_and_canresult to graphite-base/1431 June 14, 2026 07:31
@vanceingalls vanceingalls force-pushed the 06-14-feat_sdk_stage_4_canundo_canredo_removeelement_gsap_cascade_override-set_cleanup branch from 04ba6aa to ff4dca2 Compare June 14, 2026 07:31
@vanceingalls vanceingalls changed the base branch from graphite-base/1431 to 06-13-feat_sdk_can_returns_canresult_t4_dispatch-boundary_tests June 14, 2026 07:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant