Circuit-Editor and Visualization Re-Architecting and Tests - #3425
Circuit-Editor and Visualization Re-Architecting and Tests#3425ScottCarda-MS wants to merge 28 commits into
Conversation
…g references to planning docs
amcasey
left a comment
There was a problem hiding this comment.
As discussed, I focused my review on the tests, since I understand the rest is basically just shuffling code around.
I was a little surprised not to see more validation of our handling of bad input, given that users and copilot can directly edit qsc files.
|
Here are some findings from AI-assisted review.
For 4-5, I asked Copilot to find what this PR does beyond pure refactoring. Ideally, I'd suggest having a PR doing pure refactoring, and then add new features in a follow-up PR(s), to minimize risk of bugs in the large refactoring PR. I am not asking to do the split, just review these items and make sure these do not introduce bugs. For 6, I asked Copilot to suggest what tests could be added, so feel free to ignore it. |
I fixed Bug 1. 2 is intentional behavior, the host will not change its behavior on whether it supports running or not between redraws. For 3, I have updated to try to make a more clear separation between the DOM-enabled layer and the DOM-disabled layers. |
Circuit Editor Re-Architecture: Layered Foundation (Data → Actions → Renderer → Editor)
At a glance
source/npm/qsharp/ux/circuit-vis/**+source/npm/qsharp/test/**only.mjstests. No Rust, no VS Code host changes.index.tsexports the same surfaceWhat this PR does
Splits the monoliths into a layered architecture. The old editor was
four large files with tangled responsibilities. They are removed and
replaced with a strict, one-directional layering:
The hard rule:
data/andactions/never touch the DOM. The rendererreads data to produce SVG; the editor glues DOM events to action calls.
Adds group-aware editing foundations. Editing inside expanded groups,
the group structure and add/remove/ancestor-refresh/collision-split
behaviors, single-leg move and control-drag paths, and the dropzone geometry
the editor is built on.
Hardens classical-register / measurement integrity. Moving or deleting a
measurement that later gates depend on now cascades correctly (with a confirm
prompt) instead of crashing or leaving dangling classical references.
Persists view state. Group expand/collapse and related view state survive
re-render via the
ViewStatetype threaded throughsqore.ts.Adds an in-tree architecture guide. A new
ux/circuit-vis/ARCHITECTURE.mddocuments the layering, the render/click flows, and the module invariants —
useful for this review and as durable documentation afterward.
Files removed (old monoliths)
circuitManipulation.tsevents.tspanel.tsdraggable.ts(old version)contextMenu.ts(old version)Their responsibilities now live in the layered modules.
How to review this efficiently
This PR adds a structural walkthrough alongside the code:
ux/circuit-vis/ARCHITECTURE.md.Read its TL;DR and module map first — it explains the layering, has diagrams of
a render and a click flow, and lists the invariants. Then follow the order
below.
Suggested order and natural stopping points:
data/) — small, pure value types (Location,CircuitModel,ViewState). The vocabulary everything else is written in.actions/+actions/circuit-actions/) — pure mutations;the correctness core. Cross-reference the
test/circuit-editor/circuit-actions/suite as you go.→ Good checkpoint: you've now seen the entire pure core.
renderer/) —Circuit→ SVG; reads data, never mutates.editor/+editor/controllers/) — DOM glue. Read the sharedInteractionContextfirst, then the controllers.→ Good checkpoint: trace one end-to-end flow from ARCHITECTURE.md.
sqore.ts,utils.ts,index.ts) — ties it together.state-viz/) — parallel subsystem, only import-path updateshere; safe to skim last.
What to focus your scrutiny on
You don't need prior familiarity with this code to review it well. If you only
have time for a few things, these are the questions worth asking — each one is
answerable by reading a file or two:
what the editor does. The tests are the contract: if the suite is green and
the snapshot fixtures are unchanged, existing behavior is preserved. Skim the
test names in
test/circuit-editor/to see what's covered.one-way dependency: the pure logic (
data/,actions/) computes circuitchanges, and only the
editor/layer touches the browser/DOM. Spot-check acouple of
data/andactions/files — they should have no DOM orbrowser-API calls. If they don't, the separation holds.
the render path in
sqore.tsworks on a copy, so the caller's circuit objectis left untouched.
the audience the new layout is meant to help. If a folder or file name doesn't
match what's inside, that's useful feedback.
Everything else (cache-consistency details, controller wiring, drag cleanup) is
covered by the test suite.
What you can safely skim
state-viz/diffs — mechanical import-path updates from the move.test/circuits-cases/— generated.Testing
392 circuit-editor tests across 28
.mjsfiles, all passing (data,actions/circuit-actions,renderer, controllers,sqore), plus snapshotfixtures under
test/circuits-cases/.The action layer is the most heavily covered: the
test/circuit-editor/circuit-actions/suite pins the single-leg move /control / classical-ref-remap / group-structure paths.
Run locally from
source/npm/qsharp/: