Skip to content

Conversation

@zth
Copy link
Owner

@zth zth commented Dec 5, 2025

More enhancements to provide a way to run RescriptRelay cleanly without depending on React.


Note

Introduce a React-free mode and move all React-specific APIs to RescriptRelayReact, updating PPX/codegen, runtime modules, tests, and peer deps.

  • Modes & Config:
    • Add NonReact mode: compiler config rescriptRelayMode: "Default" | "NonReact" and PPX flag -non-react.
  • API Split (BREAKING):
    • Extract React APIs from RescriptRelay into RescriptRelayReact (Context Provider, useEnvironmentFromContext, useSubscribeToInvalidationState, loadQuery).
    • Remove these from RescriptRelay and reference new module across codebase.
  • Runtime (NonReact):
    • New modules: RescriptRelay_QueryNonReact (fetch, fetchPromised, retain, commitLocalPayload), RescriptRelay_MutationNonReact (commitMutation), RescriptRelay_FragmentNonReact (read, readInlineData, waitForFragmentData).
  • PPX/Codegen:
    • Generate React vs NonReact bindings conditionally via NonReactUtils; switch Fragment, Query, Mutation outputs to *_NonReact implementations when enabled.
    • Minor internal refactors (enabled.contents).
  • Tests/Generated Artifacts:
    • Update all usages to RescriptRelayReact.* and RescriptRelayReact.loadQuery.
  • Dependencies:
    • Mark @rescript/react and react-relay as optional peer deps for non‑React usage.
  • Docs/Changelog:
    • Document migration steps and new config in CHANGELOG.md.

Written by Cursor Bugbot for commit ff8c28a. This will update automatically on new commits. Configure here.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 18 to 20
@module("relay-runtime")
external commitMutation: (RescriptRelay.Environment.t, 'config) => unit = "commitMutation"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve disposable from NonReact commitMutation

In the new NonReact mutation runtime, commitMutation is bound as returning unit instead of the disposable Relay emits (RescriptRelay_MutationNonReact.res lines 18-19). The React binding still returns Disposable.t, so when -non-react is enabled any generated mutation helpers now drop the disposable and callers can’t unsubscribe or cancel an in-flight mutation, leading to potential leaks or duplicate callbacks.

Useful? React with 👍 / 👎.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@codex change the signature to return a disposable please.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Testing

  • Not run (not requested)

View task →

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is being reviewed by Cursor Bugbot

Details

You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

~fRef:
(fRef
|. [%e valFromGeneratedModule ["getFragmentRef"]])
(fRef |. [%e valFromGeneratedModule ["getFragmentRef"]])
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Dead code: readInline never generated in NonReact mode

The readInline function is never generated for inline fragments when NonReact mode is enabled. The outer match on line 143-144 returns an empty list when !NonReactUtils.enabled is true (| true, _ -> []), so the code block at lines 145-163 only executes when !NonReactUtils.enabled is false. Inside that block, the inner if !NonReactUtils.enabled check on line 147 can never be true, making the RescriptRelay_FragmentNonReact.readInlineData_ branch dead code. Users in NonReact mode with inline directive fragments will not have access to readInline.

Fix in Cursor Fix in Web

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix this.

"waitForFragmentData"

let read = (~node, ~convertFragment: 'fragment => 'fragment, ~fRef) =>
fRef->readFragment_(node)->convertFragment
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Arguments reversed in NonReact fragment read functions

The read and readInlineData_ functions pass arguments to the external runtime functions in the wrong order. The external readFragment_ expects (node, fRef) but fRef->readFragment_(node) translates to readFragment_(fRef, node). Similarly, readInlineData expects (node, fRef) but the call passes (fRef, node). This would cause the Relay runtime to receive incorrect argument types, resulting in runtime errors when reading fragment data in non-React mode.

Additional Locations (1)

Fix in Cursor Fix in Web

@zth zth merged commit 83c94d4 into master Dec 5, 2025
7 checks passed
@zth zth deleted the non-required-react- branch December 5, 2025 15:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants