Lifecycle harness
Reproduce the LiveView integration bugs that break animation hooks — before the team hits them.
–
FLIP-tracked
(_layoutElements.size)
(_layoutElements.size)
–
Mounted hooks
([data-lm-config])
([data-lm-config])
0
Spawn/clear
cycles
cycles
Leak harness — 0 live element(s)
pulse loop (setTimeout timer)
in_view fade (IntersectionObserver)
destroyed() cleanup & leaks
- What
- Removing a motion element must run destroyed(): clear the loop timer, run all _cleanups, disconnect observers, and untrack FLIP.
- Why risky
- Leaked IntersectionObservers, event listeners, or an orphaned setTimeout loop accumulate over a long session.
- How to trigger
- Spawn a batch of elements (in_view + loop + hover + layout all set), then destroy them. Repeat several cycles.
- Expected
- After Clear all, the FLIP-tracking map returns to 0 and mounted-hook count returns to baseline; nothing climbs monotonically across cycles.
- Failure looks like
- Counters climb every cycle → a leak to fix before rollout.
- Code
-
assets/js/live_animate.js:257 (destroyed)assets/js/live_animate.js:477 (IntersectionObserver)
Exit-race harness — 0 item(s)
Exit animation race (rapid add/remove)
- What
- Exit uses the phx-remove transition binding (time = duration + 50) plus a MutationObserver on the lm-animating-exit class.
- Why risky
- Removing many elements in one batch, or re-adding an element with the same id mid-exit, can race the observer or strand a position:fixed clone.
- How to trigger
- Add a batch, then Remove all (fast); or Remove + re-add same id, which re-adds 50ms into the exit.
- Expected
- Every exiting element animates out and is fully removed; no ghost fixed clones; the re-added id animates in cleanly.
- Failure looks like
- Leftover fixed-position ghosts, elements that vanish with no exit, or a re-added id that never animates.
- Code
-
assets/js/live_animate.js:326 (_setupExit)assets/js/live_animate.js:355 (exit observer)