Skip to content

Conversation

@AbanoubGhadban
Copy link
Collaborator

@AbanoubGhadban AbanoubGhadban commented Nov 20, 2025

Summary

Remove this paragraph and provide a general description of the code changes in your pull
request... were there any bugs you had fixed? If so, mention them. If
these bugs have open GitHub issues, be sure to tag them here as well,
to keep the conversation linked together.

Pull Request checklist

Remove this line after checking all the items here. If the item is not applicable to the PR, both check it out and wrap it by ~.

  • Add/update test to cover these changes
  • Update documentation
  • Update CHANGELOG file

Add the CHANGELOG entry at the top of the file.

Other Information

Remove this paragraph and mention any other important and relevant information such as benchmarks.

Summary by CodeRabbit

  • New Features

    • Added asynchronous props capability for RSC components enabling dynamic prop resolution
    • Added incremental HTML streaming support for real-time rendering updates
    • Enhanced asset upload functionality with improved bundle handling and validation
  • Bug Fixes

    • Improved bundle existence validation and error reporting
    • Enhanced authentication and protocol version checking
  • Tests

    • Expanded test coverage for incremental rendering and streaming scenarios

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 20, 2025

Caution

Review failed

Failed to post review comments

Walkthrough

This PR introduces async props capabilities for React Server Components through a new AsyncPropsManager abstraction, refactors RSC payload generation from a global function to per-instance injection, implements incremental rendering with streaming support, restructures VM execution context management, and updates related type definitions and test infrastructure across core and pro packages.

Changes

Cohort / File(s) Summary
Core AsyncProps Type System
packages/react-on-rails/src/types/index.ts
Added new exported types: AsyncPropsManager, GenerateRSCPayloadFunction, and WithAsyncProps<> utility type for extending component props with async getters. Extended Params with optional generateRSCPayload and ReactOnRailsInternal with addAsyncPropsCapabilityToComponentProps method.
Core ReactOnRails Proxy
packages/react-on-rails/src/createReactOnRails.ts, packages/react-on-rails/src/base/client.ts
Added stub addAsyncPropsCapabilityToComponentProps method that throws requiring pro package; updated BaseClientObjectType to omit this method from exported API surface.
Pro AsyncProps Implementation
packages/react-on-rails-pro/src/AsyncPropsManager.ts
New class managing asynchronous property promises with getProp(), setProp(), and endStream() methods; maintains promise controllers and rejects unresolved promises on stream close.
Pro RSC and Streaming
packages/react-on-rails-pro/src/ReactOnRailsRSC.ts, packages/react-on-rails-pro/src/RSCRequestTracker.ts, packages/react-on-rails-pro/src/streamingUtils.ts
Updated RSCRequestTracker to accept injected generateRSCPayload function; added addAsyncPropsCapabilityToComponentProps as static method on ReactOnRails; wired function through streaming pipeline.
Pro Core Creation
packages/react-on-rails-pro/src/createReactOnRailsPro.ts
Added addAsyncPropsCapabilityToComponentProps to ReactOnRailsProSpecificFunctions type and implementation with proxy stub.
Pro Tests
packages/react-on-rails-pro/tests/AsyncPropManager.test.ts, packages/react-on-rails-pro/tests/testUtils.ts
New comprehensive test suite for AsyncPropsManager covering promise lifecycle, concurrent access, and error handling; updated test utility types to use unknown instead of Buffer.
Ruby Bundle and Stream Handling
react_on_rails_pro/lib/react_on_rails_pro/request.rb, react_on_rails_pro/lib/react_on_rails_pro/server_rendering_js_code.rb
Updated asset upload workflow; changed streaming mechanism to :stream_bidi; moved generateRSCPayload from global guard to local scoped function with conditional passing.
Node Renderer VM Execution Refactoring
react_on_rails_pro/packages/node-renderer/src/worker/vm.ts, react_on_rails_pro/packages/node-renderer/src/worker/handleRenderRequest.ts
Introduced ExecutionContext abstraction wrapping multiple VM contexts; added buildExecutionContext() to build and manage VMs for bundles; updated handleRenderRequest return type to include optional executionContext.
Node Renderer Request Prechecks
react_on_rails_pro/packages/node-renderer/src/worker/authHandler.ts, react_on_rails_pro/packages/node-renderer/src/worker/checkProtocolVersionHandler.ts, react_on_rails_pro/packages/node-renderer/src/worker/requestPrechecks.ts
Refactored auth and protocol handlers from FastifyRequest-dependent to plain object consumers; consolidated prechecks into unified performRequestPrechecks() function.
Incremental Render Handlers
react_on_rails_pro/packages/node-renderer/src/worker/handleIncrementalRenderRequest.ts, react_on_rails_pro/packages/node-renderer/src/worker/handleIncrementalRenderStream.ts, react_on_rails_pro/packages/node-renderer/src/shared/utils.ts
New incremental render infrastructure with handleIncrementalRenderRequest(), handleIncrementalRenderStream() for NDJSON streaming, and validateBundlesExist() utility.
Node Renderer Worker Integration
react_on_rails_pro/packages/node-renderer/src/worker.ts
Integrated incremental render endpoints; added NDJSON content-type parser; refactored request prechecks flow; enhanced asset upload to recognize bundle-prefixed assets; updated auth and response handling patterns.
Node Renderer Test Helpers
react_on_rails_pro/packages/node-renderer/tests/helper.ts, react_on_rails_pro/packages/node-renderer/tests/testingNodeRendererConfigs.ts, react_on_rails_pro/packages/node-renderer/tests/testingNodeRendererConfigs.js, react_on_rails_pro/packages/node-renderer/tests/httpRequestUtils.ts
Added createTestConfig() factory replacing default config export; introduced incremental fixture helpers; added buildExecutionContext usage; added streaming chunk utilities (getNextChunk, getNextChunkInternal); removed old JS config file.
Node Renderer VM Tests
react_on_rails_pro/packages/node-renderer/tests/vm.test.ts, react_on_rails_pro/packages/node-renderer/tests/serverRenderRSCReactComponent.test.js
Updated to use new buildExecutionContext() API; replaced buildVM and direct VM access with context-based patterns.
Node Renderer Incremental Tests
react_on_rails_pro/packages/node-renderer/tests/incrementalRender.test.ts, react_on_rails_pro/packages/node-renderer/tests/incrementalHtmlStreaming.test.ts
New comprehensive test suites for incremental NDJSON rendering and HTTP/2 streaming with error handling, auth, protocol checks, and concurrent scenarios.
Node Renderer Test Config Updates
react_on_rails_pro/packages/node-renderer/tests/concurrentHtmlStreaming.test.ts, react_on_rails_pro/packages/node-renderer/tests/htmlStreaming.test.js, react_on_rails_pro/packages/node-renderer/tests/handleRenderRequest.test.ts, react_on_rails_pro/packages/node-renderer/tests/worker.test.ts
Updated to use createTestConfig() factory; adjusted result assertions to account for wrapped response structure; added helper functions.
Test Fixtures
react_on_rails_pro/packages/node-renderer/tests/fixtures/bundle-incremental.js, react_on_rails_pro/packages/node-renderer/tests/fixtures/secondary-bundle-incremental.js, react_on_rails_pro/packages/node-renderer/tests/fixtures/projects/spec-dummy/asyncComponentsTreeForTestingRenderingRequest.js
New and updated fixtures supporting incremental rendering with stream management and async props capability integration.
Example Component
react_on_rails_pro/spec/dummy/client/app/ror-auto-load-components/AsyncPropsComponent.tsx
New example React component demonstrating async props consumption via getReactOnRailsAsyncProp.
Ruby Specs
react_on_rails_pro/spec/react_on_rails_pro/request_spec.rb
Updated bundle upload test assertions to verify multipart form data sent to /upload-assets endpoint rather than embedded in render request.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Worker as Node Renderer Worker
    participant VM as Execution Context / VM
    participant Handler as Render Handler

    Client->>Worker: POST /bundles/:bundleTimestamp/incremental-render<br/>(NDJSON stream)
    Worker->>Worker: performRequestPrechecks()
    Worker->>Handler: handleIncrementalRenderRequest(first chunk)
    Handler->>VM: buildExecutionContext([bundlePath])
    Handler->>Handler: handleRenderRequest()
    Handler->>VM: executionContext.runInVM(code)
    VM-->>Handler: { response, executionContext }
    Handler-->>Worker: { response, sink }
    Worker->>Client: stream response
    
    loop for each update chunk
        Client->>Worker: send update chunk (NDJSON)
        Worker->>Handler: sink.add(chunk)
        Handler->>VM: executionContext.runInVM(updateCode)
        VM-->>Handler: result
        Worker->>Client: stream update
    end
    
    Client->>Worker: close stream
    Worker->>Handler: sink.handleRequestClosed()
    Handler->>VM: executionContext.runInVM(closeCode)
    VM-->>Handler: result
    Worker->>Client: stream end
Loading
sequenceDiagram
    participant RSC as RSC Component
    participant AsyncMgr as AsyncPropsManager
    participant Tracker as RSCRequestTracker

    RSC->>AsyncMgr: addAsyncPropsCapabilityToComponentProps(props)
    AsyncMgr->>AsyncMgr: create new AsyncPropsManager instance
    AsyncMgr-->>RSC: { asyncPropManager, props: {..., getReactOnRailsAsyncProp} }
    
    RSC->>RSC: render with getReactOnRailsAsyncProp
    RSC->>AsyncMgr: getReactOnRailsAsyncProp('propName')
    AsyncMgr->>AsyncMgr: getProp('propName') creates Promise
    AsyncMgr-->>RSC: Promise<unknown>
    
    Tracker->>Tracker: stream sends data
    Tracker->>AsyncMgr: setProp('propName', value)
    AsyncMgr->>AsyncMgr: resolve Promise with value
    
    RSC->>RSC: await promise resolves
    RSC-->>RSC: render with prop value
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Areas requiring extra attention:

  • AsyncPropsManager.ts: Promise controller lifecycle, resolved flag management, and error rejection logic during stream closure
  • vm.ts refactoring: ExecutionContext abstraction, VM context lifecycle management, and consolidation of multi-bundle VM access patterns
  • handleIncrementalRenderStream.ts and handleIncrementalRenderRequest.ts: NDJSON parsing, error handling distinctions between first and subsequent chunks, stream lifecycle coordination with sink callbacks
  • worker.ts integration: Refactored request precheck flow, incremental render endpoint routing, asset/bundle upload separation logic, and response wrapping patterns
  • Type propagation: Verify GenerateRSCPayloadFunction and async props types flow correctly through all injection points (RSCRequestTracker, streamingUtils, ReactOnRailsRSC)
  • Test config factory pattern: Ensure createTestConfig() properly isolates test bundles and cleanup, verify backward compatibility with existing test expectations
  • Return type changes: handleRenderRequest now returns wrapped response; verify all callers adapted (especially handleRenderRequest.test.ts assertions)

Possibly related PRs

Suggested labels

review-needed, full-ci

Suggested reviewers

  • ihabadham
  • Judahmeek
  • justin808

Poem

🐰 A rabbit's ode to async props and streams so fine,
ExecutionContexts dance in VM design.
With AsyncPropsManager as guide so true,
Incremental renders bloom—old bundles anew! 🌱

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 21.43% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'Add support for incremental rendering at ruby side' clearly and concisely summarizes the main change—adding incremental rendering support on the Ruby side of the react-on-rails system.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch add-support-for-incremental-rendering-at-ruby-side

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 and usage tips.

@AbanoubGhadban AbanoubGhadban changed the base branch from master to abanoubghadban/pro509/make-renderer-use-ndjson-for-communication November 20, 2025 17:54
@claude
Copy link

claude bot commented Nov 20, 2025

Code Review for PR #2076

Summary

This PR changes the HTTPX plugin from :stream to :stream_bidi for the HTTP connection used in the Node Renderer request handling (react_on_rails_pro/lib/react_on_rails_pro/request.rb:269).


Critical Issues

1. Missing PR Description

The PR description is incomplete - it still contains the template placeholders. Please provide:

2. Missing Tests

The PR checklist indicates tests need to be added, but I only see one file changed:

  • Are there existing tests that cover this plugin change?
  • Do we need new tests to verify bidirectional streaming works correctly?
  • Should we test the difference in behavior between :stream and :stream_bidi?

The existing tests in spec/react_on_rails_pro/request_spec.rb mock the streaming plugin, but they may not catch issues specific to :stream_bidi.

3. Missing CHANGELOG Entry

Per CLAUDE.md guidelines, this appears to be a user-visible change (enabling incremental rendering) and should have a CHANGELOG entry in /react_on_rails_pro/CHANGELOG.md (Pro-only feature).

4. Missing Documentation

  • What does stream_bidi enable that stream does not?
  • Are there any breaking changes or migration steps for users?
  • Does this require a specific HTTPX version? (Currently ~> 1.5 per the gemspec)

Technical Considerations

Understanding the Change

Based on HTTP/2 bidirectional streaming capabilities, :stream_bidi likely enables:

  • Server push during streaming
  • Bidirectional communication between Rails and Node Renderer
  • Incremental rendering where the server can send data while still receiving

However, without documentation or context, I cannot verify:

  1. Whether this is a compatible change (does it work with existing code?)
  2. What specific HTTPX version introduced :stream_bidi
  3. Whether this affects the retry logic (lines 235-268)
  4. Whether the connection pooling behavior changes

Potential Impact Areas

Unlikely to break (based on code analysis):

  • The change is in the connection setup, not the request handling logic
  • Existing error handling should still work
  • The perform_request method does not depend on plugin-specific features

Needs verification:

  • Does :stream_bidi work with the existing retry logic?
  • Does it interact differently with the @react_on_rails_received_first_chunk flag (line 248)?
  • Are there performance implications (better or worse)?

Action Items

Before this PR can be merged:

  • Fill out the PR description with clear explanation of the change
  • Add or update tests to verify bidirectional streaming behavior
  • Update CHANGELOG in react_on_rails_pro/CHANGELOG.md
  • Add code comments explaining why :stream_bidi is used (line 269)
  • Verify HTTPX version requirement - does :stream_bidi require a newer version?
  • Test with actual Node Renderer - ensure incremental rendering works as expected
  • Document any breaking changes or migration steps if applicable

Suggestions

  1. Add a comment at line 269 explaining why stream_bidi is used for incremental rendering

  2. Consider adding integration tests that specifically test incremental rendering scenarios

  3. Update the related issue Add support for incremental rendering at ruby side #2075 with more details about the implementation


What Looks Good

  • The change is minimal and focused
  • No changes to critical error handling logic
  • The location of the change makes sense for enabling a new protocol feature

Overall Assessment: The code change itself appears safe, but the PR lacks essential context, documentation, and testing. Please address the action items above before merging.

cc @AbanoubGhadban

@claude
Copy link

claude bot commented Nov 20, 2025

Code Review for PR #2076

Thank you for working on incremental rendering support! I've reviewed the changes and have the following feedback:

🔴 Critical Issues

1. Incomplete PR Description

The PR description still contains placeholder text and doesn't explain:

  • What problem this change solves
  • Why stream_bidi is needed instead of stream
  • What the difference is between these two HTTPX plugins
  • How this relates to "incremental rendering at ruby side"

Action Required: Please update the PR description with:

  • Clear explanation of what stream_bidi does vs stream
  • Why this change is necessary for incremental rendering
  • Link to any related issues or documentation

2. Missing Test Updates

The code changes the streaming plugin from :stream to :stream_bidi, but the test file spec/react_on_rails_pro/stream_spec.rb still uses .plugin(:stream) at line 40.

Action Required: Update the test to use :stream_bidi to match the production code:

# In react_on_rails_pro/spec/react_on_rails_pro/stream_spec.rb:40
.plugin(:stream_bidi)  # Changed from .plugin(:stream)

3. Pull Request Checklist Not Completed

All three checklist items are unchecked:

  • Add/update test to cover these changes
  • Update documentation
  • Update CHANGELOG file

Action Required:

  • Update or verify tests work with stream_bidi
  • Document the change (if user-facing)
  • Add CHANGELOG entry if this affects gem users

⚠️ Questions & Concerns

4. Bidirectional Streaming Implications

The stream_bidi plugin suggests bidirectional streaming (client ↔ server), while :stream is typically unidirectional (server → client).

Questions:

  • Does incremental rendering require sending data back to the server while receiving streamed responses?
  • Are there any performance implications of using bidirectional streaming?
  • Is this a breaking change that requires version bump or migration guide?

5. HTTPX Plugin Compatibility

Question: Have you verified that:

  • The stream_bidi plugin is available in all supported HTTPX versions?
  • This doesn't introduce any new gem dependencies?
  • The plugin works correctly with HTTP/2 (fallback_protocol: "h2" on line 269)?

6. Mock Plugin Compatibility

The tests use a custom :mock_stream plugin (line 38 in stream_spec.rb).

Question: Does the mock plugin need updates to support bidirectional streaming behavior?

📝 Recommendations

  1. Add inline comment explaining why stream_bidi is used:

    # Use bidirectional streaming to support incremental rendering,
    # where the client sends updates while receiving streamed responses
    .plugin(:stream_bidi)
  2. Integration test: Consider adding an integration test that specifically exercises the bidirectional streaming behavior for incremental rendering.

  3. Error handling: Verify that existing error handling and retry logic (lines 240-262) work correctly with bidirectional streams.

  4. Documentation: Update any developer docs or API documentation that reference the streaming implementation.

📚 References

Per CLAUDE.md guidelines:

  • ⚠️ MANDATORY BEFORE COMMIT: Run bundle exec rubocop and fix all violations
  • ⚠️ MANDATORY: Ensure file ends with newline character
  • See CLAUDE.md sections on changelog management for Pro features
  • This is a Pro-only feature, so update CHANGELOG_PRO.md if user-facing

Summary

This appears to be a single-line change with significant implications. Before merging:

  1. ✅ Explain the rationale in PR description
  2. ✅ Update tests to match
  3. ✅ Complete PR checklist
  4. ✅ Verify HTTPX compatibility
  5. ✅ Update CHANGELOG_PRO.md if user-facing

Looking forward to understanding the context better! Once these items are addressed, this should be good to merge.

@claude
Copy link

claude bot commented Nov 21, 2025

Code Review - PR #2076: Add support for incremental rendering at ruby side

Thank you for working on this incremental rendering feature! I've reviewed the changes and have several important observations and recommendations.

🔍 Summary of Change

This PR changes a single line in react_on_rails_pro/lib/react_on_rails_pro/request.rb:

  • Before: .plugin(:stream)
  • After: .plugin(:stream_bidi)

This change appears to be part of the larger incremental rendering work tracked in issue #2075 and the async props implementation in PR #1853.


⚠️ Critical Issues

1. Incomplete PR Description

The PR template has not been filled out. Based on CLAUDE.md guidelines, the description should include:

Recommendation: Update the PR description to explain:

2. Missing Tests

The checklist item "Add/update test to cover these changes" is unchecked. Currently:

  • stream_spec.rb tests the :stream plugin behavior
  • ❌ No tests verify :stream_bidi functionality
  • ❌ No tests demonstrate bidirectional communication

Recommendation: Add tests that verify:

  • Bidirectional streaming works correctly
  • Update chunks can be sent while receiving responses
  • The connection handles concurrent read/write operations
  • Error handling for bidirectional communication

3. Missing Documentation

The checklist item "Update documentation" is unchecked.

Recommendation: Document:

  • The :stream_bidi plugin usage in relevant docs
  • How this enables incremental rendering
  • Any configuration changes needed

4. Missing CHANGELOG Entry

The checklist item "Update CHANGELOG file" is unchecked. Per CLAUDE.md:

  • This is a Pro-only feature → Update CHANGELOG_PRO.md
  • Format: [PR 2076](https://github.com/shakacode/react_on_rails/pull/2076) by [AbanoubGhadban](https://github.com/AbanoubGhadban)

Recommendation: Add a changelog entry explaining the feature:

#### Pro Features
[PR 2076](https://github.com/shakacode/react_on_rails/pull/2076) by [AbanoubGhadban](https://github.com/AbanoubGhadban): Enable bidirectional streaming for incremental rendering support. _AbanoubGhadban_

5. CI Failures

Two test jobs are failing:

  • rspec-dummy-app-node-renderer
  • dummy-app-node-renderer-e2e-tests

These failures may be related to the streaming change. Per CLAUDE.md guidelines:

CRITICAL: NEVER wait for CI to verify fixes. Always replicate failures locally first.

Recommendation:

  1. Replicate the failures locally: bin/ci-rerun-failures 2076
  2. Investigate if failures are related to the :stream_bidi change
  3. Ensure all tests pass before requesting review

🔧 Technical Concerns

6. HTTPx Plugin Compatibility

The :stream_bidi plugin may have different requirements or behavior than :stream:

  • Stream: Unidirectional response streaming
  • Stream_bidi (presumed): Bidirectional request/response streaming

Questions to address:

  • Does :stream_bidi require HTTP/2? (The config already sets fallback_protocol: "h2", so this should be fine)
  • Are there any additional configuration options needed?
  • Does this change affect the existing streaming behavior in render_code_as_stream?

Recommendation: Verify that:

  • Existing streaming functionality still works
  • The Node renderer supports bidirectional streaming
  • HTTP/2 is consistently used (the config looks good for this)

7. Dependency on Node Renderer Changes

Based on PR #1853, the bidirectional streaming requires Node renderer support for:

  • NDJSON streaming endpoint
  • handleIncrementalRenderStream for parsing chunks
  • sharedExecutionContext for managing update chunks

Recommendation: Verify that:

  • The Node renderer changes are already merged or included
  • The /bundles/{bundleTimestamp}/incremental-render/{pathSuffix} endpoint exists
  • Integration tests cover the full bidirectional flow

📋 Code Quality Assessment

Positive Aspects ✅

  • Minimal, focused change
  • Follows existing code style
  • HTTPx plugin architecture makes this a clean swap
  • No breaking changes to existing functionality

Areas for Improvement 📝

  • Documentation: Needs explanation of why this change is necessary
  • Testing: Needs tests demonstrating bidirectional behavior
  • Context: PR description should explain the broader feature

🎯 Recommendations Summary

Before merging, please address:

  1. Fill out PR description explaining the change and linking to Add support for incremental rendering at ruby side #2075
  2. Fix CI failures - investigate and resolve the two failing test jobs
  3. Add tests for bidirectional streaming behavior
  4. Update CHANGELOG_PRO.md with appropriate entry
  5. Verify Node renderer compatibility - ensure the backend supports this
  6. Document the change if it affects configuration or usage

Testing commands (per CLAUDE.md):

# Replicate CI failures locally
bin/ci-rerun-failures 2076

# Run Pro integration tests
cd react_on_rails_pro/spec/dummy
bundle exec rake run_rspec:dummy

# Run E2E tests
yarn test:e2e

💡 Additional Context

Based on PR #1853's detailed architecture, this change is a foundational piece for the async props feature. The bidirectional streaming enables:

  • Rails to send initial render request
  • Node renderer to stream back HTML chunks
  • Rails to send update chunks with async props
  • Node renderer to incorporate updates into the stream

This is an exciting feature! Looking forward to seeing the complete implementation.

Questions? Feel free to ask if you need clarification on any of the feedback above.


Review generated following CLAUDE.md guidelines for React on Rails Pro package.

@claude
Copy link

claude bot commented Nov 21, 2025

Code Review for PR #2076

Overview

This PR changes the httpx plugin from :stream to :stream_bidi (bidirectional streaming) to enable incremental rendering support. This is a critical infrastructure change for async props and incremental rendering (related to #1853).

Positive Aspects

  1. Small, focused change - A single-line modification makes it easy to review and reduces risk
  2. Aligns with architecture - This change is necessary for the bidirectional HTTP streaming required by async props (as documented in PR feat: Implement async props with incremental rendering for React Server Components #1853)
  3. No breaking changes expected - The :stream_bidi plugin is a superset of :stream functionality

Critical Issues

1. Missing PR Description

The PR description template was not filled out. Please complete it with:

  • Summary of why :stream_bidi is needed vs :stream
  • Reference to the async props/incremental rendering feature
  • Testing strategy

2. Checklist Not Completed

Per CLAUDE.md, all checklist items must be completed. None are checked.

3. Test Coverage Concerns

The test file react_on_rails_pro/spec/react_on_rails_pro/stream_spec.rb:40 still uses .plugin(:stream), but production code now uses .plugin(:stream_bidi). These need to match.

4. Missing CHANGELOG Entry

This needs an entry in CHANGELOG_PRO.md (Pro-only change)

5. CI Failures

The PR shows 2 test failures that must be fixed:

  • rspec-dummy-app-node-renderer - FAILURE
  • dummy-app-node-renderer-e2e-tests - FAILURE

Per CLAUDE.md master health monitoring guidelines, never merge with failing tests.

6. Documentation Needed

Consider adding an inline comment in request.rb explaining why stream_bidi is used for incremental rendering.

Code Quality Assessment

  • httpx plugin compatibility: The :stream_bidi plugin is well-documented in httpx (v1.5+)
  • Security: No security concerns
  • Performance: Minimal impact expected
  • Backwards compatibility: Should be compatible

Required Actions Before Merge

  1. Fill out PR description explaining the change and referencing feat: Implement async props with incremental rendering for React Server Components #1853
  2. Fix failing CI tests - investigate and resolve the 2 test failures
  3. Update test file - Change stream_spec.rb:40 to use .plugin(:stream_bidi)
  4. Add CHANGELOG_PRO.md entry
  5. Add inline comment in request.rb explaining why stream_bidi is used
  6. Run RuboCop - bundle exec rubocop must pass
  7. Verify files end with newlines

Summary

This is an important infrastructure change that blocks async props functionality. The code change itself is correct and necessary, but the PR needs improvements in documentation, testing, and changelog entries before merge.

Merge recommendation: Do not merge until:

  • CI tests pass
  • Tests updated
  • CHANGELOG updated
  • PR description completed

Once addressed, this will be ready to merge. Great work on identifying the need for bidirectional streaming!

Review completed following React on Rails CLAUDE.md guidelines

@claude
Copy link

claude bot commented Nov 21, 2025

Code Review Feedback

Summary

This PR changes the HTTPX plugin from :stream to :stream_bidi in the Node Renderer HTTP connection setup. While this is a minimal change (1 line), it has significant implications for the streaming functionality.


🔴 Critical Issues

1. Incomplete PR Description

The PR description is completely unfilled - it still contains the template text. For a change affecting streaming behavior, we need:

  • What is the problem this solves?
  • Why is stream_bidi needed instead of stream?
  • What are the behavioral differences between the two plugins?
  • What testing was performed to validate this change?

2. Missing Test Updates

The test file spec/react_on_rails_pro/stream_spec.rb:40 still uses .plugin(:stream). If this change is correct for production code, the tests should also be updated to use :stream_bidi to accurately reflect the real configuration.

Location: spec/react_on_rails_pro/stream_spec.rb:40

3. No CHANGELOG Entry

According to CLAUDE.md, user-visible changes require CHANGELOG updates. This affects the Pro package, so it should be documented in the appropriate Pro changelog. The checklist item is unchecked.

4. CI Failures

The PR has failing CI jobs:

  • rspec-dummy-app-node-renderer - FAILURE
  • dummy-app-node-renderer-e2e-tests - FAILURE

These failures need to be investigated and resolved before merging. They may be related to this plugin change.


⚠️ Code Quality Concerns

5. Lack of Context

The commit message "Update HTTPX plugin to use stream_bidi for improved streaming capabil…" is cut off and does not explain:

  • What specific streaming capabilities are improved?
  • Is this fixing a bug or adding a feature?
  • What version of HTTPX introduced stream_bidi?
  • Are there any breaking changes or behavioral differences?

6. Potential Breaking Change

Switching HTTP streaming plugins could be a breaking change if:

  • The API differs between plugins
  • Response handling behaves differently
  • Error handling changes
  • The new plugin requires different HTTPX versions

This should be clearly documented and tested.


📋 Missing Checklist Items

From the PR template, these items are unchecked:

  • Add/update test to cover these changes
  • Update documentation
  • Update CHANGELOG file

🔍 Questions to Answer

Before this can be merged, please clarify:

  1. What specific issue does this solve? Is there a bug with :stream plugin? Performance problem? Missing feature?

  2. What is stream_bidi? Based on the name, it sounds like bidirectional streaming. Does the current :stream plugin not support bidirectional communication?

  3. Compatibility: What version of HTTPX is required for stream_bidi? The gemspec shows ~> 1.5 - does this support stream_bidi?

  4. Testing: How was this tested? The CI failures suggest it may not be working as expected.

  5. Incremental rendering: The PR title mentions "incremental rendering at ruby side" but the description does not explain how changing the HTTP plugin enables this.


📝 Recommendations

  1. Fill out the PR description with:

    • Problem statement
    • Solution explanation
    • Testing performed
    • Any breaking changes or migration notes
  2. Update the test file to use :stream_bidi if that is the correct configuration

  3. Add CHANGELOG entry documenting this change (Pro changelog)

  4. Fix CI failures - investigate why the tests are failing

  5. Add inline comments in the code explaining why stream_bidi is used instead of stream

  6. Document behavioral differences if any exist between the two plugins

  7. Consider adding integration tests that specifically verify the incremental rendering behavior mentioned in the title


📚 Repository Guidelines Reference

Per CLAUDE.md:

  • MANDATORY BEFORE COMMIT: Run bundle exec rubocop and fix all violations
  • CHANGELOG: Update appropriate changelog for user-visible changes
  • Tests: Add/update tests to cover changes
  • CI: Never wait for CI to verify fixes - replicate failures locally first

Verdict

❌ Not ready to merge due to:

  • Incomplete PR description
  • Failing CI tests
  • Missing test updates
  • Missing CHANGELOG entry
  • Unclear rationale for the change

Please address the critical issues and questions above before this can be reviewed for merge.

@claude
Copy link

claude bot commented Nov 21, 2025

Code Review: PR #2076 - Add support for incremental rendering at ruby side

Summary

This PR changes the HTTPX plugin from :stream to :stream_bidi in the Pro package's HTTP connection configuration. This appears to be enabling bidirectional streaming support for incremental rendering.


⚠️ Critical Issues

1. Missing Documentation and Context

  • Issue: The PR description is completely blank (still contains the template text). There's no explanation of:
    • What problem this solves
    • Why :stream_bidi is needed instead of :stream
    • What "incremental rendering at ruby side" means in this context
    • How this relates to the existing streaming functionality
  • Impact: Makes it impossible to understand the motivation, verify correctness, or assess risks
  • Recommendation: Update the PR description with:

2. Missing Tests

  • Issue: The PR checklist shows unchecked items:
    • Add/update test to cover these changes
    • Update documentation
    • Update CHANGELOG file
  • Impact: No test coverage for the new plugin behavior
  • Recommendation:
    • Update spec/react_on_rails_pro/stream_spec.rb to use .plugin(:stream_bidi) (currently line 40 uses :stream)
    • Update spec/react_on_rails_pro/request_spec.rb tests to verify bidirectional streaming works
    • Add tests that demonstrate the incremental rendering use case

3. Missing Changelog Entry

  • Issue: No entry in CHANGELOG_PRO.md per project guidelines
  • Impact: Users won't know about this change or how it affects them
  • Recommendation: Add changelog entry explaining:
    • What incremental rendering feature this enables
    • Whether this is a breaking change
    • Any performance or behavioral implications

4. Incomplete Test Mock Updates

  • Issue: The mock streaming helper in tests uses :mock_stream plugin, but there's no verification that this mock plugin is compatible with :stream_bidi
  • Files affected:
    • spec/react_on_rails_pro/stream_spec.rb:40 - still uses .plugin(:stream)
    • spec/react_on_rails_pro/request_spec.rb:28 - uses mock_stream wrapper
  • Recommendation: Update test files to use :stream_bidi and verify mocks work correctly

📋 Code Quality Issues

5. httpx Gem Version Compatibility

  • Current version: httpx ~> 1.5 (Gemfile.lock shows 1.5.1)
  • Question: Is :stream_bidi plugin available in httpx 1.5.x?
  • Recommendation: Verify plugin availability in the gemspec-required version, or update version constraint if needed

6. No Incremental Migration Path

  • Issue: Direct plugin swap without feature flag or graceful fallback
  • Risk: If :stream_bidi has different behavior or requirements, existing functionality could break
  • Recommendation: Consider whether a feature flag is appropriate, especially if this relates to experimental RSC features

🔍 Questions for Author

  1. What specific incremental rendering feature does this enable? Is this for React Server Components async props (PR feat: Implement async props with incremental rendering for React Server Components #1853)?

  2. Why is bidirectional streaming required? What data flows from server → client vs client → server?

  3. Is this a breaking change? Does existing streaming code continue to work, or does it require changes in consuming code?

  4. Have you tested this manually? Specifically:

    • Run rake run_rspec:gem to test Pro package
    • Test incremental rendering in the dummy app
    • Verify no regressions in existing streaming features
  5. Performance implications? Does bidirectional streaming have different performance characteristics?


What's Good

  • Small, focused change: Single-line change is easy to review
  • Strategic location: Properly placed in the connection configuration
  • Existing streaming infrastructure: The codebase already has good streaming test coverage to build on

📝 Before Merging - Mandatory Checklist

Based on CLAUDE.md guidelines:

  • Update PR description with proper context and motivation
  • Add/update tests in stream_spec.rb and request_spec.rb
  • Update CHANGELOG_PRO.md with user-facing description
  • Run bundle exec rubocop and fix all violations (CRITICAL per CLAUDE.md)
  • Ensure trailing newlines in all modified files
  • Run tests: rake run_rspec:gem (for Pro package tests)
  • Test manually with incremental rendering use case
  • Update documentation if this affects user-facing APIs
  • Verify httpx gem version supports :stream_bidi plugin

🎯 Recommendation

❌ Request Changes - This PR cannot be merged in its current state due to:

  1. Completely missing PR description/context
  2. No test coverage
  3. No changelog entry
  4. Checklist items unchecked

Please address the critical issues above, particularly adding proper context so reviewers can understand what this change enables and verify its correctness.


Note: This appears related to React Server Components incremental rendering, which is an exciting feature! However, we need proper documentation and testing to ensure it works reliably and doesn't break existing functionality.

@claude
Copy link

claude bot commented Nov 21, 2025

Code Review - Plugin Change: stream → stream_bidi

Overview

This PR changes the HTTPX plugin from :stream to :stream_bidi to support incremental rendering functionality described in PR #1853. This is a critical change that enables bidirectional HTTP streaming for async props.


What's Good

  1. Aligned with Architecture: This change is essential for the incremental rendering feature (PR feat: Implement async props with incremental rendering for React Server Components #1853), which requires bidirectional streaming to send props from Rails to the Node renderer while receiving rendered chunks back.

  2. Minimal Surface Area: Single-line change reduces risk and makes the purpose clear.


Issues and Concerns

1. Missing Test Updates (HIGH PRIORITY)

The test file spec/react_on_rails_pro/stream_spec.rb still uses .plugin(:stream) on line 40. This needs updating to match production code.

Impact: Tests won't match production behavior, potentially missing bugs.

2. Incomplete PR Description (MEDIUM PRIORITY)

The PR description is entirely placeholder text. For a critical infrastructure change like this, please provide:

3. Changelog Update Missing (REQUIRED)

Per CLAUDE.md guidelines, this change should be documented in CHANGELOG_PRO.md since it affects Pro functionality.

4. No Verification of Plugin Availability (LOW PRIORITY)

HTTPx 1.5.1 is in use (per Gemfile.lock). While :stream_bidi should be available, it would be good to confirm:

  • Is this plugin available in httpx 1.5.1?
  • Are there any API differences from :stream that might affect error handling?

Security Considerations

No apparent security issues - the plugin change maintains the same security posture as the existing streaming implementation.


Required Actions Before Merge

  1. Update test file: Change .plugin(:stream) to .plugin(:stream_bidi) in stream_spec.rb:40
  2. Update CHANGELOG_PRO.md: Add entry under [Unreleased] section
  3. Run full test suite: Confirm all specs pass with new plugin
  4. Update PR description: Explain the purpose and link to PR feat: Implement async props with incremental rendering for React Server Components #1853
  5. Verify linting: Run bundle exec rubocop (as per CLAUDE.md requirements)

Testing Recommendations

Since this changes core streaming behavior, please verify:

  • All existing streaming specs pass
  • No regressions in error handling (lines 106-111 in stream_request.rb)
  • Timeout behavior works correctly (ReadTimeoutError handling)
  • Response status checking works within streaming context

Summary

Recommendation: Request changes - The core change is sound and necessary, but test coverage and documentation must be updated before merging. This is infrastructure code that affects all incremental rendering functionality, so we need complete test alignment.

Risk Level: Medium (tests don't match production, but change itself is straightforward)


Reviewed with repository guidelines from CLAUDE.md

@claude
Copy link

claude bot commented Nov 21, 2025

Code Review for PR #2076: Add support for incremental rendering at ruby side

Overview

This PR makes a single-line change to the HTTPX plugin configuration, changing from .plugin(:stream) to .plugin(:stream_bidi). While the change appears minimal, it has significant architectural implications for bidirectional streaming support.


⚠️ Critical Issues

1. Missing Documentation

  • Issue: The PR description is incomplete (still contains placeholder text from the template)
  • Impact: Reviewers and future maintainers cannot understand the rationale for this change
  • Required Action:
    • Explain why bidirectional streaming is needed
    • Clarify how this relates to "incremental rendering"
    • Document what capabilities :stream_bidi adds over :stream

2. No Test Coverage

  • Issue: No tests verify that bidirectional streaming works as intended
  • Observation: The existing test suite in stream_spec.rb only uses .plugin(:stream), not :stream_bidi
  • Required Action:
    • Add tests that exercise bidirectional streaming
    • Verify that existing streaming tests still pass with this change
    • Test incremental rendering scenarios mentioned in the PR title

3. No CHANGELOG Entry

  • Issue: Missing CHANGELOG entry for a user-visible change
  • Per CLAUDE.md: "Update CHANGELOG.md for user-visible changes only"
  • Required Action: Add entry to CHANGELOG_PRO.md (this is Pro-only functionality)

4. HTTPX Plugin Compatibility Unknown

  • Issue: No verification that :stream_bidi plugin exists in httpx 1.5+
  • Risk: This could break at runtime if the plugin does not exist or requires a different version
  • Required Action:
    • Verify the plugin is available in httpx ~> 1.5 (from gemspec)
    • Check HTTPX documentation for any behavioral differences
    • Consider version constraint updates if needed

🔍 Code Quality Observations

Positive Aspects ✅

  • Change is surgical and well-targeted
  • Location in create_connection method is appropriate
  • Existing retry and error handling logic remains intact

Concerns 🚨

1. Behavioral Changes
The switch from unidirectional to bidirectional streaming may affect:

  • Connection lifecycle management
  • Error handling patterns (especially the retry logic around lines 242-262)
  • Stream closure behavior (line 118-119 has special handling for stream errors)

2. Incomplete PR Context
Based on the CodeRabbit summary, this PR appears to be part of a larger feature set including:

  • AsyncPropsManager
  • Incremental HTML streaming
  • RSC payload generation changes

Question: Is this PR intended to be merged standalone, or is it dependent on other changes?


📋 Testing Requirements

Before merging, the following must be tested:

  1. Functional Testing: Run rake run_rspec:dummy to verify bidirectional streaming works

  2. Integration Testing:

    • Test with actual Node Renderer
    • Verify incremental rendering scenarios
    • Test error conditions (connection drops, timeouts)
  3. Compatibility Testing:

    • Verify :stream:stream_bidi does not break existing functionality
    • Test with both HTTP/1.1 and HTTP/2 (note: fallback_protocol: "h2" on line 269)

🎯 Recommendations

Priority 1 (Blocking):

  1. ✅ Complete the PR description with full context
  2. ✅ Add CHANGELOG entry to CHANGELOG_PRO.md
  3. ✅ Verify :stream_bidi plugin availability in httpx 1.5+
  4. ✅ Add test coverage for bidirectional streaming

Priority 2 (High):

  1. Document the relationship between this change and "incremental rendering"
  2. Update stream_spec.rb to use :stream_bidi if that is the new standard
  3. Add inline comment explaining why bidirectional streaming is required

Priority 3 (Nice to Have):

  1. Document any performance implications
  2. Add example usage or integration test showing bidirectional capability

🔗 Related Files to Review

Based on the codebase structure, these files should be checked for compatibility:

  • react_on_rails_pro/lib/react_on_rails_pro/stream_request.rb (line 5 requires this file)
  • react_on_rails_pro/spec/react_on_rails_pro/stream_spec.rb (tests streaming behavior)
  • Any integration tests using render_code_as_stream method

📝 Suggested Commit Message

Switch to bidirectional streaming for incremental rendering

Changes HTTPX plugin from :stream to :stream_bidi to enable
bidirectional communication with the Node Renderer. This is required
for incremental rendering where the client can send updates while
receiving streaming responses.

The :stream_bidi plugin provides:
- Ability to send requests while receiving response body
- Better backpressure handling for long-running streams
- Support for incremental payload updates during SSR

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>

Summary

This change enables an important new capability (bidirectional streaming), but the PR needs significant additional work before it is ready to merge:

  • PR description is incomplete
  • Missing test coverage
  • No CHANGELOG entry
  • ⚠️ Plugin availability not verified
  • ⚠️ Integration impact unclear

Verdict: Request Changes - This needs the blocking issues addressed before merging.


Note: This review follows the guidelines in CLAUDE.md for React on Rails Pro package changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants