Skip to content

store: fixes and improvements for the NgRx inspector #347

Description

@erkamyaman

Context

Fixes and improvements from a code audit of the ngrx 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

  • Long diffs are cut off silently: each entry keeps at most 50 diff rows (MAX_DIFF), and nothing marks the entry as truncated. The panel shows "50 changes" and the rows as if complete, and agents get the same partial diff. Add a diffTruncated count to NgrxLogEntry, and show "N more changes not shown" in the panel and in agent text (packages/devtools/src/ngrx-collector.ts:104, :173-190, :746; packages/devtools/src/ngrx-shared.ts:77; app/src/pages/store-inspector.ts:391, :604-620).
  • Store DevTools history actions are missing: NgrxRequest only has restore, latest, dispatch and dispatch-again. Skip or toggle an action, commit, reset, sweep, pause recording and lock changes are not offered, though Store DevTools already has them (toggleAction, commit, reset, sweep, pauseRecording, lockChanges). Wire them as NgrxRequest types behind the ngrx action gate and list them in ACTION_TOOLS (packages/devtools/src/ngrx-shared.ts:137-141).
  • No call site for any entry: an entry only records origin (dispatch, effect or reactive). There is no stack capture in the dispatch or method wrappers, so you cannot see where an action or patchState came from. Add an opt-in ngrx.trace option that captures new Error().stack, trims devtools and framework frames, redacts it and shows it as a file link (packages/devtools/src/ngrx-collector.ts:836-880).

Low

  • Classic state is serialized twice: logClassic serializes the whole classic state on every action, then report() serializes it again on the next push, and the overlay compares the JSON.stringify body. same() also compares nested objects with JSON.stringify. Cache the serialized state while lastRaw is unchanged by reference, and drop the string compare in same() (packages/devtools/src/ngrx-collector.ts:745, :1164; packages/devtools/src/ngrx-shared.ts:300-304; packages/devtools/src/ngrx-overlay.ts:67).
  • Report entries are not shape-checked: isNgrxReport checks that stores and log are arrays, but not their items, classic or the size. A null log entry throws in mergeNgrxReport (entry.seq), and a large classic or store blob is kept as is. Validate items with valibot like rpc/get-ngrx-store.ts does, drop bad entries, and cap the size per page (packages/devtools/src/rpc/ngrx-tools.ts:32-41, :86-128; packages/devtools/src/devframe.ts:1550).
  • The collector patches store objects: it wraps store methods in Proxies, replaces set and update on state signals, and patches Store.dispatch, next and Dispatcher.dispatch. This adds overhead on every call and may clash with withDevtools from @angular-architects/ngrx-toolkit. Use watchState alone when it is registered, document the interaction, and consider a record toggle that unwraps everything (packages/devtools/src/ngrx-collector.ts:446-512, :672-715, :836-880) (to confirm).

Improvements

  • A slider over the change log to scrub through past states (app/src/pages/store-inspector.ts).
  • Show store state as a collapsible tree with search and "copy path" instead of a <pre> block, and highlight the keys the selected entry changed (app/src/pages/store-inspector.ts:259).
  • An agent tool that explains why a state changed, following causedByEvent, origin and the stack from event to reducer to diff (packages/devtools/src/rpc/ngrx-live-tools.ts, packages/devtools/src/config.ts).
  • An action frequency and duration view per action type, flagging effects that dispatch in a loop (packages/devtools/src/ngrx-collector.ts, app/src/pages/store-inspector.ts).

Already tracked elsewhere


Generated by Claude Code

Activity

  1. added
    bugSomething is broken or shows wrong data
    featureA feature request or a pull request that adds one
    on Oct 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething is broken or shows wrong datafeatureA feature request or a pull request that adds one

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions