Skip to content

fix(store): log a pending patchState before a method or restore in the same tick - #277

Merged
erkamyaman merged 1 commit into
mainfrom
fix/h-ngrx
Oct 11, 2026
Merged

erkamyaman merged 1 commit into
mainfrom
fix/h-ngrx

Conversation

@erkamyaman

@erkamyaman erkamyaman commented Oct 11, 2026 •

Copy link
Copy Markdown
Member

What and why

When an app hasn't registered watchState (the default), writes to a signal store outside a method are grouped per microtask into one patchState entry. onWrite takes a snapshot before the first write and queues a microtask that diffs against it.

A store method (wrapMethod) or a signal restore that runs in the same tick takes its own snapshot and logs its own entry without settling the pending one. When the microtask runs, it diffs the old snapshot against the current state, so the method's change lands in the patchState entry too. As a result:

  • the method's change shows up twice in the change log (panel and pangular:ngrx-store)
  • the entries are out of order: the method first, then a patchState claiming the method's change
  • restoring that patchState entry puts back the state after the method, not after the outside write

The fix adds flushPending, which logs the pending patchState entry right away. It runs at the start of an outermost method call and before a signal restore takes its snapshot. Stores watched through watchState never have a pending entry, so they're unchanged.

How it was verified

New test in ngrx-collector.test.ts: patchState outside a method, then a method call in the same tick. On main the log is setQuery {query} followed by patchState {query, saved}. With the fix it's patchState {saved} followed by setQuery {query}. All package tests pass.

  • pnpm commit:check (commit messages follow the guidelines)
  • pnpm format:check
  • pnpm typecheck (includes the ngc template checks)
  • pnpm test:devtools (all passing)
  • pnpm skills:check (when .claude/ changed): not changed
  • No docs change needed: the fix makes the code match existing docs (no-docs)
  • pnpm extension:build and extension/ui committed (when app/ changed): not changed
  • Checked in the browser with axe (when the UI changed): no UI change

Summary by CodeRabbit

  • Bug Fixes
    • Signal-store changes made in the same tick are now logged as separate entries, with restoring an earlier entry preserving unrelated state.

…e same tick

Without watchState, writes outside a store method are grouped per
microtask into one patchState entry, starting from a snapshot taken at the
first write. A method call or a signal restore in the same tick logged its
own entry without settling that snapshot first, so when the microtask ran
its diff also contained the method's change. The change was logged twice,
out of order, and restoring the patchState entry put back the state after
the method. The pending entry is now logged before an outermost method
call or a restore takes its own snapshot.
@erkamyaman erkamyaman added the no-docs This pull request needs no docs change (the reason is in the description) label Oct 11, 2026
@github-actions github-actions Bot added the area: package The ng-devtools package (packages/ng-devtools) label Oct 11, 2026
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

🚀 Deploying Preview to Cloudflare 🚀

Preview Deployments by commit

Status Deployment URL Commit Updated (UTC) See this deployment's details
  • Build: Failed ❌

View logs ↗
284ba14 2026-10-11T03:02:38.183Z View logs ↗

@coderabbitai

coderabbitai Bot commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: cc78ef98-62cf-44dc-a989-15be449e4517

📥 Commits

Reviewing files that changed from the base of the PR and between 58273c6 and 284ba14.


📒 Files selected for processing (2)
  • packages/devtools/src/__tests__/ngrx-collector.test.ts
  • packages/devtools/src/ngrx-collector.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 5 remain after this review.



📝 Walkthrough

Walkthrough

The collector now flushes pending patchState writes before outermost method snapshots and restore snapshots. A regression test checks that same-tick writes produce separate entries and that restoring the earlier entry preserves unrelated state.

Changes

Signal-store logging

Layer / File(s) Summary
Pending patchState entry boundaries
packages/devtools/src/ngrx-collector.ts, packages/devtools/src/__tests__/ngrx-collector.test.ts
The collector flushes pending patchState entries before outermost method calls and restore snapshots. The regression test checks separate diffs and confirms that restoring the earlier entry resets query while preserving saved.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix


Merge Risk: ⚪ Minimal · up to 284ba

The change appears mergeable after normal checks; no concrete remaining risk was identified.

Architecture Summary

Architecture risk: 🟡 Medium · up to 284ba

The change affects 1 system.

Changed systems: packages/devtools

Architecture concerns
No architecture-level concerns identified.

Review details

Systems and components

  • observed — packages/devtools (library) was modified; 2 changed files map to changed impact.

Before / after behavior

  • observed — Modified behavior in packages/devtools/src/tests/ngrx-collector.test.ts: Adds a same-tick regression test asserting that an external patchState update and a setQuery method update produce separate log entries with distinct diffs. Restoring sequence 1 must reset query to its initial value while leaving saved unchanged.
  • observed — Modified behavior in packages/devtools/src/ngrx-collector.ts: Added flushPending, which clears a tracked store’s pending snapshot and logs it through finish as a patchState entry when present.
  • observed — Modified behavior in packages/devtools/src/ngrx-collector.ts: The outermost wrapped method call now flushes a pending patchState entry before taking the method’s before-snapshot; nested calls do not flush.
  • observed — Modified behavior in packages/devtools/src/ngrx-collector.ts: Signal-store restore now flushes a pending patchState entry before capturing the restore’s before-snapshot.

Reliability and maintainability

  • inferred — Risk-relevant change factors for packages/devtools: blast_radius_2; direct_dependents_2

Pre-merge checks | Passed 4 | Failed 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 2 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: logging a pending patchState before a same-tick method call or restore.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 2
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR


🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

🛠️ Fix failing CI checks 💡
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@erkamyaman
erkamyaman merged commit 538bfe5 into main Oct 11, 2026
7 of 9 checks passed
@erkamyaman
erkamyaman deleted the fix/h-ngrx branch October 11, 2026 07:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: package The ng-devtools package (packages/ng-devtools) no-docs This pull request needs no docs change (the reason is in the description)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant