Time-travel debugger: correctness, lifecycle & architecture issues before merge to master

Open
#685 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
25/100
Issue type
Refactor
Clarity
Needs clarification
Activity status
Quiet
Tech stack
javascript
Domain
devtools

Research direction

Start with src/ext/debugger.js on the debugger branch and review the unchecked correctness, lifecycle, performance, and architecture items against the Discord discussion. The work should be split into focused PRs, with the recorder lifecycle, state capture, DOM-XSS, and extension/core API concerns each resolved or explicitly documented before merge to master.

Written by the indexing model from the issue text.

Description

Tracking issue for the time-travel debugger (src/ext/debugger.js) on the debugger branch. Collects the correctness, lifecycle, and architecture problems found while reviewing the implementation against the Discord discussion, so we can land them as focused PRs before this hits master.

Grouped by severity. Checkboxes track what's fixed.

Conceptual / time-travel correctness

  • 1. Time-travel is lossy by design. The whole rewind rides on MutationObserver, which only sees childList, attributes, and characterData. Anything outside those three is never recorded, so there is nothing to roll back.
  • 2. Form state is not restored. value / checked / selectedIndex are properties, not attributes, so the observer never sees them. Step back over a field change and it doesn't come back, and that's the #1 thing people do in hyperscript. Same story for dialogs, popovers, iframes, scroll, focus, canvas, media. These are the "trap doors" called out back in March, not fixable with the current mechanism.
  • 3. State capture is too shallow. Snapshots are one level deep, so before/after share the same nested objects and the variable diff isn't trustworthy. This is the deep clone wanted back in April, still shallow.
  • 4. No real call stack. Step-over fakes depth from the AST (command.parent) and breaks the moment execution crosses into a call, function, or behavior.
  • 5. Honesty of scope. Until per-step capture of the invisible state lands, this has to ship as experimental with a loud, visible note on what it does NOT restore. A debugger that quietly lies is worse than no time travel: people trust it and chase ghosts.
Proposed path for 1/2

Keep the mutation deltas we already have for structure, but also explicitly snapshot per step the state the observer can't see (input values, checked boxes, selected options, scroll, focus, active element) and replay those alongside the mutations on rewind. Serializing the whole DOM per step is the other option but it's heavy, still misses live form values, and loses node identity. Hybrid is the cheaper, correct path and covers the form-state case that hurts most.

Concrete bugs

  • 6. Breakpoint line-mismatch (the "breakpoints sometimes work" bug). The editor reformats the script for display, but breakpoints and the paused-line highlight match against the tokenizer's original line numbers. A leading blank line shifts the display, so gutter clicks and the highlight land on the wrong line. Setting breakpoints from code works, which matches what was observed. (Fixed by the first PR linked below; also fixes the paused line not highlighting on the first break.)
  • 7. DOM-XSS in the element list. Element id and class are written into the panel without escaping. The timeline already escapes; this spot was missed. Debugging a page with user content in those attributes runs it inside the panel.

Performance / lifecycle

  • 8. The recorder never stops. Closing the panel doesn't pause it and debugMode never turns back off. After one open, every command keeps firing events and taking snapshots forever, even with the panel closed. The off switch is fake.
  • 9. Leak + event storm. Removed DOM nodes are held for 10k steps so they never get freed (slow leak on busy pages), and an event is dispatched up the whole tree on every command, so a tight loop turns into tens of thousands of dispatches.

Architecture

  • 10. Two debuggers that don't talk. The browser extension still polls the old hdb API every 250ms, but that's gone and the core now exposes a different API. The extension is dead against the current core. We should pick one.
  • 11. Shadow DOM was dropped in favor of global styles + prefixes. On a real page styles can leak both ways. Shadow DOM or properly scoped styles removes the whole class of problem.
Dominant language
JavaScript
Stars
3.8k
Forks
171
PR merge metrics
No merged PRs in 30d

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from bigskysoftware/_hyperscript

All issues in bigskysoftware/_hyperscript

Similar issues

More JavaScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.