feat: reactivity graph panel - #18
Open
lxsmnsyc wants to merge 5 commits into
Open
Conversation
The toolbar gains a third panel that maps the running reactive graph. - Signals, memos and effects are nodes, and an edge points from a source to the computation that reads it. - Hovering a node shows its value, type, state, owner path and edge counts. - Selecting a node highlights everything upstream and downstream of it and lists its sources and observers. - Nodes pulse and count changes while the app updates. - The graph can be filtered by kind, searched by name, value or owner, paused, panned and zoomed. The panel reads the graph through the development hooks in solid-js, so it stays empty in a production build of the runtime. It only installs those hooks while it is open. The toolbar marks its own scope so its signals never show up in the graph, and marks the scope that owns the app so the wrapped app still does. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
examples/demo is an orders dashboard that exercises every toolbar panel. Run it with `pnpm demo`. - It is built with @solidjs/vite-plugin in start mode, so the plugin owns the entries and mounts the toolbar. - Signals, memos and effects are named, so the reactivity graph reads as the app's own data flow. - An async memo calls a "use server" function, which shows the pending state in the graph and a request and response in the server function panel. - A button throws so the error panel has a source-mapped frame to show. The demo reports its own server function calls through `pushServerFunctionCall`, because @solidjs/web 2.0.0-rc.0 does not report them to the toolbar yet. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
The reactivity panel showed the selected node's value as pretty printed JSON, which dropped everything JSON cannot hold. It now uses the same expandable tree the server function panel uses for serialized values. - The row primitives move from the seroval viewer to `src/ui/ValueTree.tsx`, so both panels share one look. - `ValueInspector` walks live values. It handles arrays, maps, sets, typed arrays, errors, DOM nodes, functions and class instances, and marks values that point back up the branch as circular. - Children are built when a row opens, so a deep object costs nothing until it is inspected. - Getters are reported, never called, so inspecting a value cannot run app code. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Member
Author
|
Pushed
Covered by 12 new unit tests on the entry helpers and an end to end assertion that expands a node's value and reads its keys. |
Member
Author
An effect with no sources has no incoming edges, so the layout put it in the first column together with the signals. That column should be about where data comes from, and such an effect reads nothing. Effects with no sources now get a column of their own before the signals, and every other node shifts one column to the right. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The layout was rebuilt from scratch on every snapshot, so one new node could reorder a column and shift every other column, moving nodes out from under the pointer. - Each layout is seeded with the one it replaces. Nodes keep the slot they had, and the crossing sweeps can no longer reorder them. - New nodes are inserted where the sweeps put them, so they still land near what they read. - Columns hang from the top instead of being centred, so a column that grows no longer moves the others. Adding two rows to the demo now moves 13 of 72 surviving nodes, each by one or two slots because a new node landed above them, and none of them change order. Co-Authored-By: Claude Opus 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.

Adds a third panel to the dev toolbar that maps the running reactive graph, and a demo app that exercises every panel.
The panel
It reads the graph through the development hooks in
solid-js(DEV.hooks,getSources,getObservers,getChildren,getSignals), so it stays empty in a production build of the runtime, and it installs those hooks only while it is open. Nodes are discovered from hook registrations plus an owner-tree walk from every known root, so nodes created before the panel opened still appear.Two details worth review:
AppScopemarks the scope that ownsprops.childrenas app code, and the nearest marker wins during the owner walk.Internal flag bits from
@solidjs/signals(REACTIVE_DIRTY,STATUS_PENDING,EFFECT_USERand friends) are copied into the registry, because the runtime does not export them. Every read is defensive.The demo
examples/demois an orders dashboard, run withpnpm demo. It is built with@solidjs/vite-pluginin start mode, so the plugin owns the entries and mounts the toolbar. Signals, memos and effects are named, an async memo calls a"use server"function for the pending state, and a button throws for the error panel.The demo reports its own server function calls through the exported
pushServerFunctionCall, because@solidjs/web2.0.0-rc.0 does not shipobserveServerFunctionCallsyet, which leaves the toolbar's auto-capture inert against that version.Testing
pnpm build,pnpm typecheckandpnpm format:checkare clean.POST loadRate 200, and the thrown error resolves to a source-mapped frame.🤖 Generated with Claude Code