Add time-travel debugging (record button + timeline slider)#2774
Draft
NullVoxPopuli-ai-agent wants to merge 1 commit into
Draft
Add time-travel debugging (record button + timeline slider)#2774NullVoxPopuli-ai-agent wants to merge 1 commit into
NullVoxPopuli-ai-agent wants to merge 1 commit into
Conversation
Adds a Time Travel tab to the inspector with a record button and a timeline slider. While recording, ember_debug captures a snapshot of every serializable property of the app's services and controllers at the end of each runloop (deduplicating unchanged states). Dragging the slider writes a snapshot's values back through set()/tracked setters, which triggers Glimmer revalidation and re-renders the app at that point in time. Only plainly serializable values (primitives, dates, plain arrays and objects) are recorded and restored. Component-local state, Ember Data records, and the router URL are not restored; the URL is captured for display in the timeline. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Time-travel debugging
This PR adds a Time Travel tab to the inspector: a record button and a timeline slider that scrubs the inspected app's state back and forth.
(mp4 / webm versions of the demo)
How it works
Ember has no single state atom, but long-lived app state overwhelmingly lives in tracked/settable properties on container-managed singletons. The new
ember-debug/time-travel-debug.jsmodule:_backburner.on('end')(the same "runloop settled" signal render-debug uses) and captures a snapshot of every serializable property of allservice:/controller:singletons in the container cache. Consecutive identical states are deduplicated; the buffer is capped at 200 snapshots.set()/ tracked setters (only properties that actually differ), which triggers Glimmer revalidation — the app re-renders itself at that point in time. A guard prevents the restore's own runloops from being recorded.@trackedproduces). Getter-only accessors are derived state and are skipped. Only plainly serializable values (primitives, dates, plain arrays/objects) are recorded — class instances are rejected so restoring can never corrupt identity-bearing objects.The UI side is a standard tab (route/controller/template + nav entry) talking over the existing port protocol (
timeTravel:*messages). The record button and clear button live in the toolbar; the slider sendstimeTravel:travelon input, so scrubbing restores state live as you drag. The timeline shows the snapshot index, capture time, and the URL it was captured at.Known limitations (also explained in the tab's empty state)
Testing
tests/ember_debug/time-travel-debug-test.js: records tracked controller state, travels back/forward and asserts values are restored, verifies dedup of unchanged runloops andclear.Notes from building the demo
The demo runs the bookmarklet build injected into
classic-test-app(Ember 7). Two pre-existing issues bite late injection into webpack-built Ember 7 apps and had to be worked around in the demo harness (not addressed in this PR):entrypoints/utils/has-ember.jsnever resolves: there is noemberbarrel module and nowindow.Emberin Ember 7, and theEmberwindow event fired long before injection.object-inspector.js'sGlimmerValidator.tagFor/trackedDatapatching throws (Cannot set property tagFor of #<Object> which has only a getter) because the webpack module namespace is getter-only — same problem the Vite guard (globalThis.emberInspectorApps) already dodges.Happy to file these separately.
🤖 Generated with Claude Code