Skip to content

fix(store): async batch() freezes application state updates during await - #3245

Open
Unnati1007 wants to merge 1 commit into
Karanjot786:mainfrom
Unnati1007:fix/store-async-batch
Open

fix(store): async batch() freezes application state updates during await#3245
Unnati1007 wants to merge 1 commit into
Karanjot786:mainfrom
Unnati1007:fix/store-async-batch

Conversation

@Unnati1007

@Unnati1007 Unnati1007 commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

fix(store): async batch() freezes application state updates during await

Closes #3244

GSSoC'26

Description

This PR fixes a critical bug where passing an async function to batch() would freeze the entire application's UI updates during await.

Because JS is single-threaded and batch relies on a global _batchDepth counter, suspending the batch meant that all unrelated state updates happening globally (from networking, user input, background timers, etc.) were accidentally intercepted and buffered until the original Promise resolved.

batch() has now been aligned with standard React/Zustand behavior: it only batches synchronous operations. The Promise interception logic has been stripped, ensuring batch() decrements its depth immediately upon function return, allowing the event loop to continue unhindered.

Related Issue

Closes #3244

Which package(s)?

@termuijs/store

Type of Change

  • 🐛 Bug fix (type:bug)
  • ✨ Feature (type:feature)
  • 📝 Docs (type:docs)
  • 🧪 Tests (type:testing)
  • ♻️ Refactor (type:refactor)
  • 🎨 Design / UX (type:design)
  • ♿ Accessibility (type:accessibility)
  • ⚡ Performance (type:performance)
  • 🔧 DevOps / CI (type:devops)
  • 🔒 Security (type:security)

Checklist

  • ⭐ You starred the repo. The needs-star check blocks your merge otherwise.
  • Tests pass locally: bun vitest run
  • Build passes: bun run build
  • Typecheck passes: bun run typecheck
  • You read CONTRIBUTING.md.
  • Your PR title follows type: short description.
  • Widget state mutators call markDirty() (if your change affects rendering).
  • No new any types without an inline comment explaining why.
  • No unrelated refactors bundled into this PR.

GSSoC 2026 Participation

  • You are a GSSoC 2026 contributor.
  • Your GSSoC profile: https://gssoc.girlscript.org/profile/Unnati1007

Screenshots / Recordings (UI changes)

N/A - Core architecture fix.

Notes for the Reviewer

Removed the batch.test.ts and store.test.ts tests that specifically attempted to assert that batch could span Promises, as this behavior is fundamentally broken and impossible to do safely in a JS environment without heavily utilizing AsyncLocalStorage.

Summary by CodeRabbit

  • Bug Fixes

    • Updated batched state updates to flush notifications synchronously when callbacks return, including callbacks that return promises.
    • Simplified rollback and notification timing for asynchronous batch operations.
  • Tests

    • Removed tests covering asynchronous batch rollback, nested batches, stale microtasks, and concurrency scenarios.

@Unnati1007
Unnati1007 requested a review from Karanjot786 as a code owner July 28, 2026 19:18
@github-actions github-actions Bot added type:bug +10 pts. Bug fix. type:testing +10 pts. Tests. and removed type:bug +10 pts. Bug fix. labels Jul 28, 2026
@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 562a07d7-93c3-4fa8-8410-03f7d7717727

📥 Commits

Reviewing files that changed from the base of the PR and between 48f63a1 and 7cd5a3f.

📒 Files selected for processing (3)
  • packages/store/src/batch.test.ts
  • packages/store/src/store.test.ts
  • packages/store/src/store.ts
💤 Files with no reviewable changes (2)
  • packages/store/src/batch.test.ts
  • packages/store/src/store.test.ts

📝 Walkthrough

Walkthrough

batch() now treats Promise-returning callbacks as synchronous batch scopes: it decrements depth and flushes when the callback returns. Async batch tests covering rollback, commit, nesting, stale microtasks, and interleaving updates were removed.

Changes

Store batch control flow

Layer / File(s) Summary
Synchronous batch lifecycle
packages/store/src/store.ts, packages/store/src/store.test.ts
batch() immediately decrements _batchDepth, flushes the outermost batch, and returns the callback result directly. Tests for asynchronous batch settlement and interleaving behavior are removed.

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

Possibly related PRs

Suggested labels: type:bug, area:store, quality:clean, level:intermediate

Suggested reviewers: karanjot786, ionfwsrijan

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise, specific, and accurately summarizes the async batch() bug fix.
Description check ✅ Passed The PR description matches the template and includes the required issue, package, change type, checklist, and reviewer notes.
Linked Issues check ✅ Passed The code changes address #3244 by making batch() synchronous-only and removing Promise-spanning behavior.
Out of Scope Changes check ✅ Passed The changes stay focused on the batch() async behavior and related tests, with no clear unrelated additions.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@Unnati1007

Copy link
Copy Markdown
Contributor Author

@Karanjot786 Please review the PR, do lemme know if any changes needed and merge it under GSSoC'26

@github-actions github-actions Bot added the type:bug +10 pts. Bug fix. label Jul 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type:bug +10 pts. Bug fix. type:testing +10 pts. Tests.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[bug] fix(store): async batch() freezes application state updates during await

1 participant