fix: preserve AsyncLocalStorage context across React scheduler boundaries
## Problem
When React's server-side renderer schedules work via microtasks or setImmediate,
the Node.js AsyncLocalStorage context is lost. This causes Next.js's
`workUnitAsyncStorage` to return `undefined` when components call sync IO APIs
(like `Date.now()`) after awaiting runtime APIs (like `params`, `cookies()`, etc.).
This resulted in flaky tests because:
1. The `io()` function couldn't detect sync IO access (context was lost)
2. No abort was triggered, so `serverIsDynamic` stayed `false`
3. `isPartial` was incorrectly set to `false` in RSC responses
4. Client router thought cached data was complete
5. Navigation requests weren't made, causing test timeouts
## Solution
Use `AsyncLocalStorage.snapshot()` to capture the full async context when
`startWork()` is called, then restore it when React's scheduler continues
work via `pingTask()`. This ensures Next.js's AsyncLocalStorage contexts
are preserved across React's scheduler boundaries.
Changes made to vendored React files:
- Added `asyncContextSnapshot` property to request object
- Capture snapshot in `startWork()` using `AsyncLocalStorage.snapshot()`
- Added `runInAsyncContext()` helper to restore context
- Wrapped `scheduleMicrotask` and `setImmediate` callbacks in `pingTask()`
to use the captured snapshot
## Files Patched
- react-server-dom-webpack (dev & prod)
- react-server-dom-webpack-experimental (dev & prod)
- react-server-dom-turbopack (dev & prod)
- react-server-dom-turbopack-experimental (dev & prod)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>