Repository navigation
signals: fixes and improvements for the Signals inspector #346
Copy link
Copy link
Closed
Labels
bugSomething is broken or shows wrong dataSomething is broken or shows wrong datafeatureA feature request or a pull request that adds oneA feature request or a pull request that adds one
Description
Context
Fixes and improvements from a code audit of the signals inspector, done in October 2026. Roadmap work lives in #340, #341, #342 and #343. Items marked (to confirm) were not reproduced; check them before fixing.
Problems
Medium
- Write hook cost: the write hook serializes every write to every named signal, even when no panel or agent is listening and the signal is not in the reported graph. Hot signals (pointer position, animation frames, typing) pay
serializesynchronously inside Angular's set path. Keep the raw value and version on write and serialize lazily incollect()only for tracks bound to graph nodes, or keep only the latest value per track per microtask (packages/devtools/src/signal-history.ts:58-63, installed inpackages/devtools/src/overlay.ts:250). - Unnamed writes dropped silently:
onWritereturns early whennode.debugNameis missing, so those signals get onlysamplehistory and nothing says why. Only resources show adebugNamehint. Add the same hint on(unnamed)cards and on histories with only sampled entries, and say which Angular version adds names automatically (packages/devtools/src/signal-history.ts:42-43,app/src/pages/signal-inspector.ts:384,:485).
Low
- Track eviction is FIFO, not LRU:
tracks.delete(tracks.keys().next().value!)evicts the oldest created track, and existing tracks are never re-inserted on write, so a signal written constantly loses its exact history once 500 newer signals exist. Re-insert on write and prefer tracks whoseWeakRefis dead (packages/devtools/src/signal-history.ts:56). - History owner ignores injectors: the delta owner is
graph.component?.id ?? '', so switching between environment injector graphs sends a delta, and the server mergesprev?.history?.[id]by node id without checking the owner. Usegraph.component?.id ?? graph.injector?.id ?? '', and drop the previous history on the server when the owner changed (packages/devtools/src/overlay.ts:271,packages/devtools/src/devframe.ts:1446-1449). - Quadratic dependency lookups:
getDependenciesandgetConsumerseach runfindIndexplus an edges filter, and the template calls them up to four times per card. Precompute acomputed()map of id to deps and consumers once per graph (app/src/pages/signal-inspector.ts:498-504,:1637-1655). - Filter matches every resource:
'resource'.includes(q)makes queries such ase,soorourlist all resources. Match the kind only on a prefix of at least 3 characters, or leave it to the kind chips (app/src/pages/signal-inspector.ts:1365). - Peeks only take environment injectors:
toPeekRequestrequiresenv, soinspect-signalstells agents to callpangular:highlightfirst, which moves the user's selection on the Signals page. Accept{ id }or{ selector }inSignalPeekRequest, reuseSignalTarget, and update the tool description (packages/devtools/src/signal-peek.ts:16-41,packages/devtools/src/devframe.ts:1976). - Live nodes not linked to source: the source-scan signals (file, line, component) only show when there is no live graph. Match live nodes to source entries by label and component class name, show
file:lineon the card, and show nothing when the match is ambiguous. Open in editor itself is tracked in phase 1 of 4: safe by default and wired into your workflow #340 (app/src/pages/signal-inspector.ts:283-311). - linkedSignal writes may skip the hook: the history relies only on
setPostSignalSetFn, and no test writes to a namedlinkedSignal. Add a real-Angular test that asserts awriteentry; if it fails, hooklinkedSignalwrites another way or document the limit (packages/devtools/src/signal-history.ts:190-221,packages/devtools/src/__tests__/signal-history.test.ts) (to confirm).
Improvements
- Restore a past value from the history list once signal editing (phase 2 of 4: deeper inspection #341) lands, as a one-click undo (
app/src/pages/signal-inspector.ts,packages/devtools/src/signal-history.ts). - Show a JSON diff between consecutive history entries instead of the full value each time (
app/src/pages/signal-inspector.ts). - Effect run counts and durations per effect node, if Angular exposes a hook, to spot runaway effects (
packages/devtools/src/signal-graph.ts,app/src/pages/signal-inspector.ts). - Count unnamed signals in the
inspect-signalsanswer, so agents can suggest addingdebugName(packages/devtools/src/rpc/signal-tools.ts).
Already tracked elsewhere
- Editing writable signals, models and
linkedSignalfrom the panel and agents: phase 2 of 4: deeper inspection #341. - Hiding framework-internal nodes by default with a hidden count: phase 2 of 4: deeper inspection #341.
- A drawn dependency graph with upstream and downstream highlight (the unused
kindLegendatapp/src/pages/signal-inspector.ts:1358can become its legend): phase 2 of 4: deeper inspection #341. - Opt-in stack capture of who wrote a signal: phase 2 of 4: deeper inspection #341.
- One timeline across signals and other inspectors: phase 3 of 4: a shell you live in #342.
Generated by Claude Code
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething is broken or shows wrong dataSomething is broken or shows wrong datafeatureA feature request or a pull request that adds oneA feature request or a pull request that adds one
Activity
fix: audit findings for components, injectors, signals, pipes and HTTP (