Skip to content

Backport useSyncExternalStoreWithSelector - #29

Draft
christopher-buss wants to merge 10 commits into
Roblox:mainfrom
christopher-buss:backport-react-use-sync-external-store-with-selector
Draft

Backport useSyncExternalStoreWithSelector#29
christopher-buss wants to merge 10 commits into
Roblox:mainfrom
christopher-buss:backport-react-use-sync-external-store-with-selector

Conversation

@christopher-buss

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

Copy link
Copy Markdown

Summary

Backports React 19.2's use-sync-external-store/with-selector user-space companion as a standalone React-Luau package.

Depends on #24. This branch is intentionally stacked on that PR's sync-external-store commit, so the draft diff against main includes the native hook dependency. Ownership of the native useSyncExternalStore commit remains entirely in #24.

Changes

  • adds a Rotriever/Wally UseSyncExternalStore companion package
  • mirrors the React 19.2 memoized selector and custom equality contract
  • includes the c5eca9b0 memoized-snapshot retention correction
  • ports the complete selector-specific upstream tests in source order
  • records source commits, test ownership, exclusions, and Luau adaptations in the package README

No dispatcher, reconciler, or Fiber behavior is added. The package composes the native hook from #24.

Exact runtime provenance

  • commit: 7e45ca2e49b32cbd228a968fbcb359e39978f2d4
  • tree: ee2f0b89b95fdad54969e588aa20b9fd344693d8
  • source tar SHA-256: 259ACCB11F413070E3D97F4CF90FBFB49AD45EE096B684B6C3ACAD250B2E582B
  • hardened project SHA-256: 7B92C92679557FFAF5130321478B12044917F9E50E2040159CD8977FE35FA269
  • harness config SHA-256: BF688B19990D08032F978BF9C5E18C29D9748D632334829ACADEF63B403FC068
  • source-identity probe: 1/1 passed; Jest SHA-256 51E0CEBB32637D06D8CADD77510400B46090A02A371C7C22CEF3E9E8699C5FBF

Testing

  • StyLua 0.18.1 --check modules/use-sync-external-store — passed
  • Selene 0.28.0 --config selene.toml modules/use-sync-external-store — passed, 0 errors/warnings
  • luau-compile on runtime and test files — passed
  • Rojo 7.3 test-place build — passed
  • exact-source identity probe — passed 1/1
  • memoized selectors are only called once per update — passed 1/1, 4 skipped; Jest SHA-256 02108E6061C6AC058DE92603F70AE3690A4C4DB3A1F72BCC56EF5D7FFD873299
  • Using isEqual to bailout — passed 1/1, 4 skipped; Jest SHA-256 A95CA69944F754301AF3FFB6F76816DBA083BBD5CF64589814A761FAA725155D
  • compares selection to rendered selection even if selector changes — passed 1/1, 4 skipped; Jest SHA-256 865AEA98DA40151EF45451C824CBDA111A8CD2F4C8654F3062C5748EC5CAC17C
  • selector can throw on update — passed 1/1, 4 skipped; Jest SHA-256 43A840967410533FD4DC5969FDA9D5BD42B639763945EBD58C226C511ECEB23F
  • isEqual can throw on update — passed 1/1, 4 skipped; Jest SHA-256 22DC59BC3E9A17A23BEF9359976C3AFC87C008349089E0F6E5090FCDAD73C548

The combined five-test file reached RUN / instrument / run tests 1 project, then produced no result envelope before the public Studio backend's 180,000 ms timeout. This is classified as a backend teardown timeout, not as an assertion failure or a passing full-file result. The five exact public test names above are the assertion evidence.

The repository's built-in DEV/release runner remains unavailable locally because robloxdev-cli/roblox-cli is not installed; bin/testing.sh reproduces roblox-cli: command not found.

Generated with Codex.

Co-authored-by: Codex <noreply@openai.com>
Port the memoized selector path over the native external-store hook and
cover the upstream single-evaluation contract with ReactNoop.

Co-authored-by: Codex <noreply@openai.com>
Port the upstream custom equality bailout and advance the memoized snapshot
when an equal selection reuses the previous value.

Co-authored-by: Codex <noreply@openai.com>
Reuse the committed selection when a changed selector computes an equal value,
matching the upstream downstream-memoization contract.

Co-authored-by: Codex <noreply@openai.com>
Preserve upstream selector and equality failures through React's error boundary
path using the ReactNoop renderer adaptation.

Co-authored-by: Codex <noreply@openai.com>
Publish the selector companion through the React-Luau package boundaries and
record pinned source history, test coverage, and platform deviations.

Co-authored-by: Codex <noreply@openai.com>
Restore the upstream suite hierarchy and explanatory comments, and batch store listener notifications through the ReactNoop renderer.

Co-authored-by: Codex <noreply@openai.com>
Run translated renders and store writes through ReactNoop act, then assert already-flushed Scheduler yields before inspecting host output.

Co-authored-by: Codex <noreply@openai.com>
Assert multi-subscriber host text through ReactNoop props and account for the concurrent renderer's duplicate error recovery diagnostic.

Co-authored-by: Codex <noreply@openai.com>
Record both Scheduler yields produced when React 17 retries concurrent error recovery after selector and equality failures.

Co-authored-by: Codex <noreply@openai.com>
@christopher-buss
christopher-buss force-pushed the backport-react-use-sync-external-store-with-selector branch 2 times, most recently from e18e6ca to 7e45ca2 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