vp migrate beta test#10
Conversation
There was a problem hiding this comment.
Code Review
This pull request applies extensive formatting, style normalization, and configuration updates across the monorepo, including transitioning to vite-plus and standardizing JS/TS syntax with double quotes and semicolons. The code review identified several critical issues in the runtime implementation: treating valid null component resolutions as errors, breaking synchronous rendering by forcing React.cache to always return async promises, potential crashes from unsafe direct access to globalThis['~rsc'], scheduling process.nextTick as a macrotask instead of a microtask, and passing unnormalized HTTP methods to the Request constructor.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| if (resolvedElement === undefined || resolvedElement === null) { | ||
| return { | ||
| success: false, | ||
| boundary_id: boundaryId, | ||
| error: "Promise resolved to null/undefined", | ||
| errorName: "InvalidPromiseResolution", | ||
| errorStack: "No stack trace", | ||
| }; | ||
| } |
There was a problem hiding this comment.
In React, returning null is a perfectly valid way for a component to render nothing. However, the current check treats any null resolution as an error ("Promise resolved to null/undefined"), which will cause valid components returning null to fail. We should only throw an error if the resolved element is undefined.
| if (resolvedElement === undefined || resolvedElement === null) { | |
| return { | |
| success: false, | |
| boundary_id: boundaryId, | |
| error: "Promise resolved to null/undefined", | |
| errorName: "InvalidPromiseResolution", | |
| errorStack: "No stack trace", | |
| }; | |
| } | |
| if (resolvedElement === undefined) { | |
| return { | |
| success: false, | |
| boundary_id: boundaryId, | |
| error: "Promise resolved to undefined", | |
| errorName: "InvalidPromiseResolution", | |
| errorStack: "No stack trace", | |
| }; | |
| } |
| return async function cachedFunction(...args) { | ||
| const cacheKey = generateCacheKey(fn, args) | ||
| const cacheKey = generateCacheKey(fn, args); | ||
|
|
||
| const cached = ops.op_cache_get(cacheKey) | ||
| const cached = ops.op_cache_get(cacheKey); | ||
| if (cached !== null && cached !== undefined) { | ||
| return cached | ||
| return cached; | ||
| } | ||
|
|
||
| const result = await fn(...args) | ||
| const result = await fn(...args); | ||
|
|
||
| ops.op_cache_set(cacheKey, result) | ||
| ops.op_cache_set(cacheKey, result); | ||
|
|
||
| return result | ||
| } | ||
| return result; | ||
| }; |
There was a problem hiding this comment.
React.cache always returns an async function (returning a Promise), even if the wrapped function fn is synchronous. This breaks synchronous rendering of components that use React.cache. We should preserve the synchronous/asynchronous nature of the wrapped function.
return function cachedFunction(...args) {
const cacheKey = generateCacheKey(fn, args);
const cached = ops.op_cache_get(cacheKey);
if (cached !== null && cached !== undefined) {
return cached;
}
const result = fn(...args);
if (result && typeof result.then === "function") {
return result.then((resolved) => {
ops.op_cache_set(cacheKey, resolved);
return resolved;
});
}
ops.op_cache_set(cacheKey, result);
return result;
};| for (const loadingPath of loadingPaths) { | ||
| if (globalThis['~rsc'].modules && globalThis['~rsc'].modules[loadingPath]) { | ||
| const LoadingModule = globalThis['~rsc'].modules[loadingPath] | ||
| const LoadingComp = LoadingModule.default || LoadingModule | ||
| if (typeof LoadingComp === 'function') { | ||
| if (globalThis["~rsc"].modules && globalThis["~rsc"].modules[loadingPath]) { |
There was a problem hiding this comment.
Defensive programming: globalThis["~rsc"] is accessed directly as globalThis["~rsc"].modules on line 113, which will crash if globalThis["~rsc"] is undefined. It should use optional chaining globalThis["~rsc"]?.modules like it does on line 32.
| for (const loadingPath of loadingPaths) { | |
| if (globalThis['~rsc'].modules && globalThis['~rsc'].modules[loadingPath]) { | |
| const LoadingModule = globalThis['~rsc'].modules[loadingPath] | |
| const LoadingComp = LoadingModule.default || LoadingModule | |
| if (typeof LoadingComp === 'function') { | |
| if (globalThis["~rsc"].modules && globalThis["~rsc"].modules[loadingPath]) { | |
| for (const loadingPath of loadingPaths) { | |
| if (globalThis["~rsc"]?.modules && globalThis["~rsc"].modules[loadingPath]) { |
| for (const loadingPath of loadingPaths) { | ||
| if (globalThis['~rsc'].modules && globalThis['~rsc'].modules[loadingPath]) { | ||
| const LoadingModule = globalThis['~rsc'].modules[loadingPath] | ||
| const LoadingComp = LoadingModule.default || LoadingModule | ||
| if (typeof LoadingComp === 'function') { | ||
| if (globalThis["~rsc"].modules && globalThis["~rsc"].modules[loadingPath]) { |
There was a problem hiding this comment.
Defensive programming: globalThis["~rsc"] is accessed directly as globalThis["~rsc"].modules on line 217, which will crash if globalThis["~rsc"] is undefined. It should use optional chaining globalThis["~rsc"]?.modules like it does on line 32.
| for (const loadingPath of loadingPaths) { | |
| if (globalThis['~rsc'].modules && globalThis['~rsc'].modules[loadingPath]) { | |
| const LoadingModule = globalThis['~rsc'].modules[loadingPath] | |
| const LoadingComp = LoadingModule.default || LoadingModule | |
| if (typeof LoadingComp === 'function') { | |
| if (globalThis["~rsc"].modules && globalThis["~rsc"].modules[loadingPath]) { | |
| for (const loadingPath of loadingPaths) { | |
| if (globalThis["~rsc"]?.modules && globalThis["~rsc"].modules[loadingPath]) { |
| } | ||
| }, | ||
| nextTick: fn => setTimeout(fn, 0), | ||
| nextTick: (fn) => setTimeout(fn, 0), |
There was a problem hiding this comment.
| const request = new Request(url.toString(), { | ||
| method: requestData.method, | ||
| headers, | ||
| body, | ||
| }) | ||
| }); |
There was a problem hiding this comment.
The Request constructor is called with requestData.method (which might be lowercase), but the body is determined using the uppercase method. It's safer and more standard to pass the normalized uppercase method to the Request constructor.
| const request = new Request(url.toString(), { | |
| method: requestData.method, | |
| headers, | |
| body, | |
| }) | |
| }); | |
| const request = new Request(url.toString(), { | |
| method, | |
| headers, | |
| body, | |
| }); |
| if (typeof globalThis["{component_id}"] === "function") { | ||
| Component = globalThis["{component_id}"]; | ||
| componentSource = "global.{component_id}"; | ||
| } else if (globalThis["~rsc"].modules && globalThis["~rsc"].modules["{component_id}"]) { |
There was a problem hiding this comment.
Defensive programming: globalThis["~rsc"] is accessed directly as globalThis["~rsc"].modules on line 13, which will crash if globalThis["~rsc"] is undefined. It should use optional chaining globalThis["~rsc"]?.modules.
| } else if (globalThis["~rsc"].modules && globalThis["~rsc"].modules["{component_id}"]) { | |
| } else if (globalThis["~rsc"]?.modules && globalThis["~rsc"].modules["{component_id}"]) { |
| if (globalThis["~rsc"].modules && globalThis["~rsc"].modules[componentId]) { | ||
| delete globalThis["~rsc"].modules[componentId]; | ||
| clearedCount++; | ||
| } | ||
|
|
||
| if (globalThis['~rsc'].functions && globalThis['~rsc'].functions[componentId]) { | ||
| delete globalThis['~rsc'].functions[componentId] | ||
| clearedCount++ | ||
| if (globalThis["~rsc"].functions && globalThis["~rsc"].functions[componentId]) { | ||
| delete globalThis["~rsc"].functions[componentId]; | ||
| clearedCount++; | ||
| } |
There was a problem hiding this comment.
Defensive programming: globalThis["~rsc"] is accessed directly as globalThis["~rsc"].modules and globalThis["~rsc"].functions, which will crash if globalThis["~rsc"] is undefined. It should use optional chaining globalThis["~rsc"]?.modules and globalThis["~rsc"]?.functions.
| if (globalThis["~rsc"].modules && globalThis["~rsc"].modules[componentId]) { | |
| delete globalThis["~rsc"].modules[componentId]; | |
| clearedCount++; | |
| } | |
| if (globalThis['~rsc'].functions && globalThis['~rsc'].functions[componentId]) { | |
| delete globalThis['~rsc'].functions[componentId] | |
| clearedCount++ | |
| if (globalThis["~rsc"].functions && globalThis["~rsc"].functions[componentId]) { | |
| delete globalThis["~rsc"].functions[componentId]; | |
| clearedCount++; | |
| } | |
| if (globalThis["~rsc"]?.modules && globalThis["~rsc"].modules[componentId]) { | |
| delete globalThis["~rsc"].modules[componentId]; | |
| clearedCount++; | |
| } | |
| if (globalThis["~rsc"]?.functions && globalThis["~rsc"].functions[componentId]) { | |
| delete globalThis["~rsc"].functions[componentId]; | |
| clearedCount++; | |
| } |
Pull Request Description
Summary
Type of Change
Related Issues
Motivation and Context
Changes Made
Code Changes
API Changes
Configuration Changes
Testing
Test Coverage
Test Results
Manual Testing Steps
Performance Impact
Performance Considerations
Benchmarks
Breaking Changes
Breaking Changes Details
Migration Guide
Documentation
Documentation Updates
Documentation Links
Checklist
General
Rust-specific (if applicable)
cargo build)cargo test)cargo fmt)cargo clippy)TypeScript-specific (if applicable)
Build & Release
Security
Additional Context
Screenshots
Related Work
Future Work
Notes for Reviewers
Reviewer Instructions: