Skip to content

feat(react): backport React 19 client Actions - #34

Draft
christopher-buss wants to merge 20 commits into
Roblox:mainfrom
christopher-buss:backport-react-19-async-actions
Draft

christopher-buss wants to merge 20 commits into
Roblox:mainfrom
christopher-buss:backport-react-19-async-actions

Conversation

@christopher-buss

@christopher-buss christopher-buss commented Aug 31, 2026

Copy link
Copy Markdown

Summary

  • backport React 19.2 client Actions, including async transition entanglement and pending lifetime
  • add useOptimistic with revert-lane rebasing and useActionState with serialized Action queues
  • align global and hook transition error behavior, Debug Tools, shallow rendering, and public types
  • port all 25 renderer-independent ReactAsyncActions cases and all 13 public useActionState cases in upstream order

Dependencies

This branch contains the exact public heads of:

After each dependency lands, rebase this branch onto main and drop that dependency's commits while preserving the same canonical seams.

#28 owns the parsed-stack ancestor guard and scalar display of a single packed Luau useMemo return. This branch temporarily carries those two minimal Debug Tools adapters so its Actions inspection tests run independently; whichever pull request lands second removes the duplicates.

#33 is a sibling rather than a merge-order dependency. It owns the common component-wakeable boundaryless-suspension substrate shared with this branch. The implementations are not byte-identical: this branch additionally permits an Action wakeable thrown by HostRoot's nil-parent update queue. After either sibling lands, drop the duplicate common ReactFiberThrow, Work Loop suspension, and HostRoot capture hunks while preserving that Action-specific HostRoot extension and both additive HostRoot begin-work behaviors.

Upstream

The source and test ledger is pinned to React v19.2.0 commit ae74234eae6ebd62f19190731278e20bc1c37d51. docs/react-19-actions-backport.md records the behavior-bearing history, capability boundaries, translated tests, and site-level deviations.

Verification

  • hardened public package-identity probe: 1/1 passed
  • ReactAsyncActions: 25/25 passed
  • ReactActionState: 13/13 passed
  • Debug Tools Actions inspection: 2/2 passed
  • ReactStartTransition: 3/3 passed
  • repository-pinned StyLua 0.18.1: all 43 changed Luau files passed
  • Selene 0.28.0: 0 errors, 0 warnings, 0 parse errors
  • Rojo 7.2.1: tests.project.json built successfully
  • git diff --check: passed

The hardened runtime archive used SHA-256 prefix 75F1ABC9, project prefix B81E4801, config prefix 79EB73E6, and alias-generator prefix 15D6CA78. Its tested tree (e3a779273c3117415f996789a10ecb4dc6c85124) is identical to the pushed squashed commit.

Generated with Codex.

Adds startTransition, useTransition, and useDeferredValue with transition lane scheduling, queue entanglement, debug inspection, and upstream-derived coverage.

Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <noreply@openai.com>
Expose configurable caught, uncaught, and recoverable handlers on ReactRoblox roots and route Fiber errors through the owning root. Preserve React 17 internal renderer throw behavior while public roots use the React 19 global reporting model.

Port the applicable upstream callback tests and document the pinned source ledger and capability exclusions.

Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <noreply@openai.com>
Pin stable source links to the annotated v19.2.0 tag commit and distinguish it from its scheduler-version parent.

Co-authored-by: Codex <noreply@openai.com>
Port async transition entanglement, optimistic state, and serialized action-state queues from React 19.2. Add the full renderer-independent Actions and action-state coverage with an upstream/deviation ledger.

Co-authored-by: Codex <noreply@openai.com>
Load the thenable helper inside the two error paths so Studio debug.loadmodule can compile the near-limit WorkLoop chunk.

Co-authored-by: Codex <noreply@openai.com>
Keep React 17's synchronous internal-renderer console and throw contract while public roots retain React 19 error callbacks. Document the upstream deviations and preserve callback error identity.

Co-authored-by: Codex <noreply@openai.com>
Document the React 17 replay and thenable-tracking divergences, correct pinned source ranges, and make the test ledger match the actual port.

Port the fulfilled-thenable regression and preserve observable scheduler yield order across the translated use cases.

Co-authored-by: Codex <noreply@openai.com>
Record that React 17 performs hydration fallback at the retry callers rather than inside the modern recovery helper.

Co-authored-by: Codex <noreply@openai.com>
Keep concurrent transition UI mounted when an Action wakeable has no Suspense boundary.

Co-authored-by: Codex <noreply@openai.com>
Preserve hook traversal and restore interrupted fibers before concurrent Action retries.

Co-authored-by: Codex <noreply@openai.com>
Skip the HostRoot error-capture pass when a concurrent Action suspends without a boundary.

Co-authored-by: Codex <noreply@openai.com>
christopher-buss added a commit to christopher-buss/react-luau that referenced this pull request Aug 31, 2026
Mirror the generic concurrent-root suspension substrate also carried by Roblox#34 so deferred tasks can retain committed UI without a Suspense boundary. Consolidate the duplicate hunks when either pull request lands.

Co-authored-by: Codex <noreply@openai.com>
Store React 19 recovery bookkeeping on the existing private module table and avoid extra WorkLoop imports so Roblox Studio can load the reconciler.

Co-authored-by: Codex <noreply@openai.com>
Allow non-legacy roots to suspend when their update queue throws an Action wakeable.

Co-authored-by: Codex <noreply@openai.com>
Integrate the canonical React 19 root error callback dependency for Actions.

Co-authored-by: Codex <noreply@openai.com>
Restore rendered output, queued dispatch, hook traversal, and source-ledger coverage.

Co-authored-by: Codex <noreply@openai.com>
Integrate the canonical React 19 use dependency for Actions.

Co-authored-by: Codex <noreply@openai.com>
Use the canonical thenable and global reporter seams, restore test parity, and preserve sibling identity.

Co-authored-by: Codex <noreply@openai.com>
Preserve upstream transition error delivery, repair translated renderer and inspection output, and retain React 17's boundaryless retry and fallback timing semantics.

Co-authored-by: Codex <noreply@openai.com>
@christopher-buss
christopher-buss force-pushed the backport-react-19-async-actions branch 2 times, most recently from 3f67985 to 1a818c7 Compare September 6, 2026 17:20
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.

1 participant