feat(macos): port RedBox 2.0 to macOS (AppKit)#3027
Open
Saadnajmi wants to merge 118 commits into
Open
Conversation
Summary: Pull Request resolved: react#54385 Changelog: [Internal] `test-release-local` shouldn't be changing the hermes version stored in `version.properties` as this script should be called on a cut branch with hermes already bumped. Reviewed By: cipolleschi Differential Revision: D86105703 fbshipit-source-id: 5a1edd9f7a6cd756521749c2b0023ea683dadf82
#publish-packages-to-npm&next
Summary: Pull Request resolved: react#54419 Changelog: [Internal] React Native uses `files` field in `package.json` to list everything that should end up in the apckage. `.hermesv1version` file was missing from that list, which is fixed by this diff. Reviewed By: huntie, cipolleschi Differential Revision: D86295805 fbshipit-source-id: 8a17191f26f9536884e4aaf09447121c020d1212
…eact#54421) Summary: OSS community shared with me that we have a circular dependency in React-utils.podspec that prevent them from building with JSC. While fixing it, I realized that the dynamic framework build was broken. So I fixed them both. ## Changelog: [iOS][Fixed] - Fixed build with dynamic frameworks Pull Request resolved: react#54421 Test Plan: Build RNTester locally with USE_FRAMEWORKS=dynamic Reviewed By: javache Differential Revision: D86309592 Pulled By: cipolleschi fbshipit-source-id: f2995332ae135ce951480b353df7d597ff8a85ec
Summary: When RCT_SYMBOLICATE_PREBUILT_FRAMEWORKS is enabled, source file paths in dSYMs were incorrectly resolved with extra path segments: double node_modules (e.g., /path/node_modules/node_modules/...) The root cause was using File.expand_path(@react_native_path) without the correct base directory. The path was first expanded without a base (causing double node_modules), then fixed to use project_pods_root (ios/Pods/), which still resulted in incorrect paths with an extra ios/ folder. Fixed by expanding the path relative to Pod::Config.instance.installation_root, which correctly points to the ios/ directory, allowing relative paths like ../node_modules/react-native to resolve properly to the project root's node_modules directory. ## Changelog: [IOS] [FIXED] - Fix incorrect source path resolution in dSYM remapping in precompiled framework scripts Pull Request resolved: react#54470 Test Plan: ``` rm -rf ./Pods pod cache clean --all RCT_USE_RN_DEP=1 RCT_USE_PREBUILT_RNCORE=1 RCT_SYMBOLICATE_PREBUILT_FRAMEWORKS=1 bundle exec pod install ``` ✅ Tested with RN-Tester ✅ Tested in 0.83.rc0 project Reviewed By: huntie Differential Revision: D86667786 Pulled By: cipolleschi fbshipit-source-id: cd6279d02d5ed7188e282e4491c05de35f17a8f1
Summary: Pull Request resolved: react#54479 Fixes failing CI jobs on `0.83-stable`, e.g. https://github.com/facebook/react-native/actions/runs/19234912061/job/54982161510. **Changes** - Simplify main package `package.json` file read with existing `getWorkspaceRoot` util. - Fix test by mocking `getWorkspaceRoot` (previously: read the real filesystem and caused test breakage outside `main`). - Add additional `RC0 → RC1` test case. Changelog: [Internal] Reviewed By: cipolleschi Differential Revision: D86674348 fbshipit-source-id: 0b8feb4cbf7b1ac7cf4cc560f066a0a10aec1b5f
Summary: Pull Request resolved: react#54407 Introduces a new `InspectorSystemState` object and `ReactNativeApplication.systemStateChanged` CDP event, used to assert whether more than one React Native Host has been registered for the current app lifetime. This will be used to disable the Performance and Network features in React Native DevTools when the debugger backend is in this currently unsupported state. We intend to implement host lifecycle correctness across all features soon. Changelog: [Internal] Reviewed By: cipolleschi Differential Revision: D86201689 fbshipit-source-id: b8525359fc01eb7ae666879f2c0fd4c94f0af81a
…act#54408) Summary: Pull Request resolved: react#54408 Follows from the parent commit. This will prevent 3P CDP clients from using the `Tracing` or `Network` domains when we are in an unsupported multi React Native Host setup. Changelog: [Internal] Reviewed By: hoxyq Differential Revision: D86201688 fbshipit-source-id: 052d563a371fd77c1a05ad8518e222d6bc1eb372
Local sync from 0.83-stable branch
#publish-packages-to-npm&next
Summary: Pull Request resolved: react#54454 Changelog: [Internal] - Add feature flag around IntersectionObserver for canary Reviewed By: rubennorte, cipolleschi Differential Revision: D86547485 fbshipit-source-id: 0c6d84e276d1f6337a8da0bea141cc371010cd75
…0.83-stable branch. Changelog: [General][Added] - React Native DevTools: Enable Network inspection features
#publish-packages-to-npm&next
#publish-packages-to-npm&next
react#56597) Summary: Pull Request resolved: react#55919 Changelog: [internal] Adds a new feature flag to enable the experimental and partial implementation of `MutationObserver` Reviewed By: Abbondanzo, sammy-SC, javache Differential Revision: D95223862 fbshipit-source-id: e19dd163e5f7fecd9ef28b79be61455f0993a3c4
#publish-packages-to-npm&0.83-stable
Summary: Pull Request resolved: react#56211 The `removeClippedSubviews` prop toggle path in `RCTViewComponentView` did not handle being turned off: children that were clipped (removed from superview) remained invisible, and `_reactSubviews` became stale. This diff: - Adds `_updateRemoveClippedSubviewsState` helper that ensures consistent state when toggling. On toggle-off, re-mounts all children from `_reactSubviews` in the correct order and clears the tracking array. - Makes the unmount path resilient by cleaning up `_reactSubviews` even when `removeClippedSubviews` is off. - Splits the unmount assert into two distinct messages: "not mounted" vs "mounted inside a different view". - Adds unit tests covering toggle-off re-mounting, ordering, cleanup, and unmount-after-toggle scenarios. Changelog: [iOS][Fixed] Fixes crash when changing the value of `removeClippedSubviews` Reviewed By: sbuggay Differential Revision: D97971845 fbshipit-source-id: c5d0a99e632a23613cc5e05bcf00c2985c30d5b4
This reverts commit b7288ce.
* Limit WebSocket queue size for packager connection (react#54300) Summary: Pull Request resolved: react#54300 Establishes a queue mechanism on top of the OkHttp's WebSocket implementation. This mechanism will control the queue size and guarantee that we don't have more than 16MB scheduled. This prevents the scenario of when OkHttp forces WS disconnection because of this threshold. Reviewed By: motiz88, alanleedev Differential Revision: D85581509 fbshipit-source-id: ac3e830c935c1301b674739c96fcbe18446eaa71 * Bump chunk size for android (react#54301) Summary: Pull Request resolved: react#54301 # Changelog: [Internal] Previously, we would read every single kilobyte and do Java -> C++ call with `jni`. For big objects, like source maps, this means that we were doing at least 1024 calls for a single megabyte of incoming data. From my observations, some source maps on Twilight could reach 30Mb+. There is a trade-off between how much of memory we want to allocate while reading a stream and a runtime. I didn't notice any differences while changing the chunk size from 8Kb to 1Mb and some values in between; in the end it purely depends on the OkHttp's or Okio's implementation of the stream, looks like it uses 8Kb as a chunk size by default: {F1983042734} Reviewed By: huntie Differential Revision: D85652217 fbshipit-source-id: 68474f0b7eece13a0a1c8ea9e617b99a26d81ff9 * Increase the size of the chunk of ProfileChunk events (react#54352) Summary: Pull Request resolved: react#54352 # Changelog: [Internal] Since we can now avoid disconnections, it should be safe to increase the chunk size. This should improve the trace loading time. Reviewed By: huntie Differential Revision: D85937959 fbshipit-source-id: 4f0ef023a4d756217de0c756dbc1decbd99698d4 --------- Co-authored-by: Ruslan Lesiutin <hoxy@meta.com>
…nes (react#56994) Summary: Two sources of non-determinism cause `Podfile.lock` SPEC CHECKSUMS to differ between machines, breaking `pod install --deployment` in CI and creating unnecessary churn in PRs. ### Fix 1: Sort `Dir.glob` results in `Yoga.podspec` `Dir.glob` returns files in filesystem-dependent order (varies across macOS APFS volumes, case sensitivity settings, and Linux ext4/xfs). Since CocoaPods evaluates the podspec at install time, the resulting array order differs between machines, producing different spec checksums. ```ruby # Before spec.private_header_files = Dir.glob(all_header_files) - Dir.glob(public_header_files) # After spec.private_header_files = Dir.glob(all_header_files).sort - Dir.glob(public_header_files).sort ``` ### Fix 2: Use a Pods-relative path in `hermes-engine.podspec` `require.resolve` with `__dir__` resolves to an absolute path containing the developer's home directory (e.g., `/Users/alice/project/node_modules/...`). This absolute path gets baked into `user_target_xcconfig`, which differs per machine. Instead of hardcoding a relative path (which assumes a specific project layout), we dynamically compute the relative path from `Pod::Config.instance.sandbox.root` to the resolved `hermes-compiler` location. This supports any project layout (standard apps, monorepos, RNTester, etc.) while keeping the xcconfig deterministic. ```ruby # Before — absolute path baked in spec.user_target_xcconfig = { 'HERMES_CLI_PATH' => "#{hermes_compiler_path}/hermesc/osx-bin/hermesc" } # After — dynamic relative path via $(PODS_ROOT) pods_root = Pod::Config.instance.sandbox.root relative_hermesc = Pathname.new(hermesc_path).relative_path_from(pods_root) spec.user_target_xcconfig = { 'HERMES_CLI_PATH' => "$(PODS_ROOT)/#{relative_hermesc}" } ``` bypass-github-export-checks ## Changelog: [IOS] [FIXED] - Make Podfile.lock SPEC CHECKSUMS deterministic across machines by sorting Dir.glob results in Yoga.podspec and using a dynamically computed Pods-relative path in hermes-engine.podspec Pull Request resolved: react#56994 Test Plan: 1. Run `pod install` on machine A, record `Podfile.lock` 2. Run `pod install` on machine B (different username/home directory) 3. Verify SPEC CHECKSUMS are identical between both runs We have verified this fix in our production app — after patching, running `pod install` consecutively produces zero diff in `Podfile.lock`. Supersedes react#56977 (closed due to force-push history issue). Fixes react#56975 Made with [Cursor](https://cursor.com) Reviewed By: cortinico Differential Revision: D107362027 Pulled By: cipolleschi fbshipit-source-id: 8330b99bcd17098f0bcc337ef44372ee9a3e68be
react#57241) * Expose cleanupContentsNodesRecursively for backport Backport prerequisite: make cleanupContentsNodesRecursively externally linkable and declare it in CalculateLayout.h so AbsoluteLayout.cpp can call it. This mirrors the relevant slice of react#55876 (26cef64), which is not present on this branch, and is required before applying react#56422 and react#57103. * Fix node ownership when `display: contents` is used (react#56422) Summary: Pull Request resolved: react#56422 Changelog: [GENERAL][FIXED] Fixed Yoga node ownership when `display: contents` is used in absolutely positioned subtrees Fixes an edge case where nodes with `display: contents` weren't cloned properly inside absolutely positioned subtrees. Adds a test case covering this scenario. X-link: react/yoga#1924 Reviewed By: NickGerleman Differential Revision: D100581579 Pulled By: j-piasecki fbshipit-source-id: e05e9a4076bd11a71be438ef910a262044659a9b * Fix `display: contents` nodes having `hasNewLayout` set incorrectly (react#57103) Summary: Pull Request resolved: react#57103 Changelog: [General][Fixed] Fixed `display: contents` nodes having `hasNewLayout` set incorrectly `cleanupContentsNodesRecursively` unconditionally sets `hasNewLayout=true` on `display: contents` children, including on code paths where their parent's layout was not actually performed in this pass. The stale flag can survive across layout passes and, in clone-on-write renderers (e.g. React Native Fabric), be observed by a subsequent pass whose parent was cloned but whose layout was served from cache, leaving the contents child's owner pointing at the previous parent revision. There are two paths through which the cleanup could stamp a contents child whose parent's `hasNewLayout` would end up false: 1. Measure-phase visit. Inside `calculateLayoutImpl`, the cleanup ran with no knowledge of `performLayout`. When the parent's `calculateLayoutImpl` was invoked only with `performLayout=false` (cache miss on measure, cache hit on layout), the cleanup stamped contents children even though the parent itself never had its `hasNewLayout` set. 2. Absolute-layout walk. `layoutAbsoluteDescendants` walks every static layout descendant of the containing block - including ones whose own `calculateLayoutImpl` was skipped via the layout-phase cache. The cleanup invoked along that walk unconditionally stamped contents children, but the parent's `hasNewLayout` was only updated when the recursion actually found new layout downstream. In both cases, the result is the same invariant violation: a contents node with `hasNewLayout=true` whose parent has `hasNewLayout=false`. A consumer iterating the tree via `hasNewLayout` skips the parent and never clears the stale flag. X-link: react/yoga#1970 Test Plan: Added `YGContentsNodeHasNewLayoutTest.cpp` with regression tests: - `contents_child_hasNewLayout_not_stamped_on_measure_only_visit` - pins the measure-phase fix - `absolute_descendant_through_contents_is_reachable_via_hasNewLayout` - pins the positive case for absolute-layout path - `absolute_phase_cleanup_does_not_stamp_when_parent_layout_skipped` - pins the negative case for absolute-layout path Reviewed By: javache Differential Revision: D107854528 Pulled By: j-piasecki fbshipit-source-id: cae5e889622296e8b6380a6428509b5ffea3e9ae
Summary: Pull Request resolved: react#54784 This is a follow-up to D86201689 following user feedback on `0.83.0-rc.2`: react-native-community/discussions-and-proposals#954 (reply in thread). The problem was that we were incorrectly attributing any and all `IInspector::addPage()` calls to represent a new React Native Host being registered. However, this API also remains common to the legacy Hermes `ConnectionDemux` runtime target setup (which does not represent a host target). We now fork this code path internally based on `InspectorTargetCapabilities.prefersFuseboxFrontend`, in order to track `registeredHostsCount` accurately (i.e. **only** for HostTarget page registrations). Changelog: [General][Fixed] - React Native DevTools: Fix a bug where we would incorrectly flag apps using additonal Hermes runtimes (e.g. Reanimated) as being multi-host Reviewed By: hoxyq Differential Revision: D88386623 fbshipit-source-id: 49a82faa6c857de41e8e9a757f5fdd850f09c3dd
…. (react#55251) Summary: This fixes a regression introduced by b18cd58 by including the final, redirected to URL in the response object. [ANDROID][FIXED] fetch() response URL is incorrect after redirect (react#55248) Pull Request resolved: react#55251 Test Plan: Testing using the reproducer from issue react#55248. Reviewed By: cortinico Differential Revision: D91046809 Pulled By: javache fbshipit-source-id: 314419304f18325e6273ae9ed6a828d32abd68ac
* Update React Native GitHub repo slug * Fix repo slug test formatting * Use available runner for Android build * Use available Ubuntu runners in workflows
…act#57023) * Make removeClippedSubviews toggle-resilient (react#56211) Summary: Pull Request resolved: react#56211 The `removeClippedSubviews` prop toggle path in `RCTViewComponentView` did not handle being turned off: children that were clipped (removed from superview) remained invisible, and `_reactSubviews` became stale. This diff: - Adds `_updateRemoveClippedSubviewsState` helper that ensures consistent state when toggling. On toggle-off, re-mounts all children from `_reactSubviews` in the correct order and clears the tracking array. - Makes the unmount path resilient by cleaning up `_reactSubviews` even when `removeClippedSubviews` is off. - Splits the unmount assert into two distinct messages: "not mounted" vs "mounted inside a different view". - Adds unit tests covering toggle-off re-mounting, ordering, cleanup, and unmount-after-toggle scenarios. Changelog: [iOS][Fixed] Fixes crash when changing the value of `removeClippedSubviews` Reviewed By: sbuggay Differential Revision: D97971845 fbshipit-source-id: c5d0a99e632a23613cc5e05bcf00c2985c30d5b4 * Update React Native GitHub repo slug * Fix repo slug test formatting * Use available runner for Android build * Use available Ubuntu runners in workflows --------- Co-authored-by: Pieter De Baets <pieterdb@meta.com>
…ve (react#56844) * Cache prebuilt iOS binaries in ~/Library/Caches/ReactNative Currently, Hermes, ReactNativeDependencies, and ReactNativeCore tarballs are cached only inside the Pods/ directory. This means every clean `pod install` (or deleting the Pods folder) triggers a full re-download from Maven, even if the same version was already downloaded before. This adds a shared cache layer at ~/Library/Caches/ReactNative/. On first download, tarballs are saved to the shared cache. On subsequent pod installs, if the local Pods cache is empty but the shared cache has the tarball, it is copied locally instead of re-downloaded. This benefits: - Clean installs after deleting Pods/ - Multiple projects using the same React Native version - CI environments with a persistent home directory Added descriptive log messages for each scenario (local hit, shared cache hit, cache miss + download) to aid debugging. * Update React Native GitHub repo slug * Use available runner for Android build * Use available Ubuntu runners in workflows * Fix repo slug test formatting
#publish-packages-to-npm&0.83-stable
…mi/merge-0.83.10 # Conflicts: # .github/ISSUE_TEMPLATE.md # .gitignore # README.md # package.json # packages/assets/package.json # packages/babel-plugin-codegen/package.json # packages/community-cli-plugin/package.json # packages/core-cli-utils/package.json # packages/debugger-frontend/package.json # packages/dev-middleware/package.json # packages/eslint-config-react-native/package.json # packages/eslint-plugin-react-native/package.json # packages/eslint-plugin-specs/package.json # packages/gradle-plugin/package.json # packages/metro-config/package.json # packages/new-app-screen/package.json # packages/normalize-color/package.json # packages/polyfills/package.json # packages/react-native-babel-preset/package.json # packages/react-native-babel-transformer/package.json # packages/react-native-codegen/package.json # packages/react-native-compatibility-check/package.json # packages/react-native-popup-menu-android/package.json # packages/react-native/Package.swift # packages/react-native/React/CoreModules/RCTRedBox.mm # packages/react-native/React/CoreModules/RCTWebSocketModule.mm # packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm # packages/react-native/gradle/libs.versions.toml # packages/react-native/package.json # packages/react-native/sdks/.hermesv1version # packages/react-native/sdks/.hermesversion # packages/react-native/sdks/hermes-engine/version.properties # packages/react-native/third-party-podspecs/RCT-Folly.podspec # packages/react-native/third-party-podspecs/fmt.podspec # packages/rn-tester/Podfile.lock # packages/rn-tester/package.json # packages/typescript-config/package.json # packages/virtualized-lists/package.json # private/helloworld/package.json # private/react-native-codegen-typescript-test/package.json # scripts/releases/ios-prebuild/configuration.js # yarn.lock
First react-native-macos 0.83 release, syncing to upstream React Native 0.83.10. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace the nx version-plan with a Changesets entry (react-native-macos: minor), matching the changesets release tooling this branch inherited from main (microsoft#2839). This is the first 0.83 release of react-native-macos, syncing to RN 0.83.10. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- RCTFrameTimingsObserver: the new upstream screenshot observer uses UIKit-only APIs (UIScene/UIWindowScene/UIGraphicsImageRenderer/drawViewHierarchyInRect) and is only instantiated on iOS (RCTHost.mm, TARGET_OS_IPHONE). Compile a no-op stub on macOS so React-Core (static + SwiftPM prebuild) builds. - yarn.lock: the merge deduped @typescript-eslint/eslint-plugin to 8.36.0 while @typescript-eslint/parser resolved to 8.38.0, breaking the transitive @typescript-eslint/types link under the pnpm nodeLinker (ESLint failed to load the plugin). Re-resolve both root ^8.36.0 deps to a consistent 8.63.0. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
export-versions.mts coerced dependencies['@react-native/codegen'], which is 'workspace:*' in the dev tree, producing the invalid 'workspace:*.0' passed to the test-app integration's set-react-version. Read peerDependencies['react-native'] instead (the real upstream RN version, e.g. 0.83.10 -> 0.83), matching how the react-native-macos init workflow derives its version. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The init and test-app integration gates (which only run on *-stable base branches) pack react-native-macos and install it standalone, but its @react-native-macos/virtualized-lists workspace dependency is not published at the 1000.0.0 dev version, so the install failed to resolve it. Pack virtualized-lists alongside react-native-macos and install/override it: - init: npm install both tarballs together (npm satisfies the 1000.0.0 dep from the local tarball). - test-app: add it to the set-react-version --overrides map. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@react-native/tester (the private RNTester app) is pinned to the upstream snapshot version 0.83.0-main, which Changesets graduates to a phantom major (1.0.0) bump in the release plan, tripping the 'no major bumps' guard in the changesets check. It is never published, so add it to the changeset ignore list. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
RN 0.83.10 added a -dealloc that hid the loading window via UIWindow/.hidden. Use the RCTPlatformWindow ivar type and hide via -orderOut: on macOS (NSWindow), mirroring the existing #if !TARGET_OS_OSX carve-out in -hide. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
change.mts getBaseBranch() derived the git remote from package.json repository.url, but the monorepo root package.json has no repository field, so repoPath was empty and `(repoPath && ...) ?? 'origin'` evaluated to an empty string (?? doesn't catch ''), yielding base ref '/0.83-stable'. changeset status then failed to find the divergence point. Use || so an empty match falls back to 'origin' (=> origin/<base>). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
set-react-version --overrides only covers the direct react-native-macos dep, so yarn still tried to fetch the unpublished @react-native-macos/virtualized-lists@1000.0.0 transitively. Add a root resolutions entry pointing at the packed tarball, using the same mechanism as the @types/react pin. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Ports upstream RN 0.83.10's RedBox 2.0 refactor to macOS, completing the deferral from the 0.83.10 merge (microsoft#3022) which kept the old monolithic macOS RCTRedBox and omitted the 11 new iOS-only RedBox2 files. - Adopts upstream's thin RCTRedBox.mm coordinator that selects a controller via ReactNativeFeatureFlags::redBoxV2IOS() (RCTRedBox2Controller when true, else RCTRedBoxController), plus the extracted AnsiParser/ErrorParser/HMRClient. - RCTRedBoxController.mm: mechanical port — the carve-outs were transferred from our already-macOS-ported inline controller in the old RCTRedBox.mm. - RCTRedBox2Controller.mm: genuinely new AppKit UI. NSTableView (no sections) flattens the Message/Source/CallStack sections into rows with header rows; NSButton footer with key equivalents; NSPasteboard copy; sheet presentation. - Carve-outs follow fork convention: additive `#if !TARGET_OS_OSX // [macOS]` branches with RCTUIColor/RCTPlatformView compat types; iOS branches are byte-identical to upstream (verified via unifdef). - Build wiring is automatic via the CoreModules glob (podspec + Package.swift). Verified: RNTester-macOS Debug build = BUILD SUCCEEDED. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ease The 'Test react-native-macos init' and 'react-native-test-app integration' gates integration-test react-native-macos as a real project consumes it, which requires the target minor to be published to npm: react-native-macos-init installs a published react-native-macos (falling back to the previous published minor and conflicting on the react-native peer), and react-native-test-app declares a supported react-native-macos version range. Neither can be satisfied for the very first release of a new minor, before anything is published. Add a check-release-published gate that queries npm for the target minor and skips both integration jobs when it is not yet published. They self-heal and run normally for later patch releases once the minor is on npm. The failures occur at yarn/npm install (before any bundling/pod/build), so this only skips the pre-publish window, not real integration coverage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…i/0-83-saadnajmi-redbox2-macos
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Ports upstream React Native 0.83.10's RedBox 2.0 refactor to macOS.
RedBox 2.0 is upstream's redesigned red error screen:
RCTRedBox.mmbecomes a thin coordinator that picks a controller based on theReactNativeFeatureFlags::redBoxV2IOS()feature flag — the newRCTRedBox2Controller(redesigned UI with a header bar, parsed error title/category, syntax-highlighted code frame, a native HMR auto-reload client, and auto-retry) when the flag is on, or the classicRCTRedBoxControllerwhen off. The refactor also splits out helper classes:RCTRedBox2AnsiParser,RCTRedBox2ErrorParser, andRCTRedBoxHMRClient.RCTRedBox.mm/.hand omitted the 11 new iOS-only RedBox2 files to keep the merge buildable. This PR adds them.0.83-stable; this is stacked on the 0.83.10 merge, so once chore(0.83): merge up to 0.83.10 from upstream branch #3022 lands the diff cleans up to just the RedBox2 changes.Files added (11) + coordinator
RCTRedBox2ErrorParser(+Internal.h/.mm),RCTRedBoxHMRClient(+Internal.h/.mm)RCTRedBox+Internal.hRCTUIColorbranch:RCTRedBox2AnsiParser(+Internal.h/.mm)NSViewController/NSTableView):RCTRedBoxController+Internal.h,RCTRedBox2Controller+Internal.hRCTRedBoxController.mm— the classic controller. The macOS carve-outs were transferred from our existing, already-macOS-ported inlineRCTRedBoxControllerin the old monolithicRCTRedBox.mm.RCTRedBox2Controller.mm— the new RedBox 2.0 UI, which we have never shipped on macOS. Since AppKitNSTableViewhas no sections, the Message/Source/Call Stack sections are flattened into a single row list with lightweight header rows; footer usesNSButtonwith key equivalents; copy usesNSPasteboard; presentation uses a sheet.RCTRedBox.mm: replaced our old monolith with upstream's ~383-line coordinator; the only macOS carve-out is a no-oploadExtraDataViewController(matching current fork behavior —RCTRedBoxExtraDataViewControllerpresentation is iOS-only).RCTRedBox.hneeded no change (already the coordinator header with a Foundation carve-out).Carve-out approach
#if !TARGET_OS_OSX // [macOS] ... #else // [macOS] ... #endif // macOS]clauses only; iOS branches are kept byte-identical to upstream (verified withunifdef -DTARGET_OS_OSX=0againstfacebook/0.83-stable— the only diffs are sanctioned additive|| TARGET_OS_OSXclauses and UIKit→<React/RCTUIKit.h>import swaps).RCTUIColor/RCTPlatformViewand theUIViewController/UIFontaliases.React-CoreModules.podspec) and SwiftPM (Package.swiftreactCoreModules) includeReact/CoreModulesby glob, so simply adding the files compiles them.Verification
cd packages/rn-tester && bundle exec pod installxcodebuild -workspace RNTesterPods.xcworkspace -scheme RNTester-macOS -destination 'generic/platform=macOS' -configuration Debug build→ BUILD SUCCEEDED (all 8 RedBox.mm/.mcompiled on macOS).redBoxV2IOS()still defaults tofalse, so the macOS RedBox2 UI is inactive by default (parity with iOS); the classic controller remains the active path until the flag is flipped.