Skip to content

Commit c288e54

Browse files
authored
refactor: RN$Bridgeless as isFabric (#7043)
## Summary Since Bridgeless by default `RN$Bridgeless` global property is injected before any library code is executed. We don't support "Bridgeful" mode anymore so we can depend on this variable to detect the architecture. ## Test plan See that `console.log(globalThis.RN$Bridgeless);` yields `true` when added in top-level scope of any file.
1 parent 2b6fc94 commit c288e54

File tree

16 files changed

+44
-25
lines changed

16 files changed

+44
-25
lines changed

packages/react-native-reanimated/src/AnimatedPropsRegistry.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ export function removeFromPropsRegistry(viewTag: number) {
1212
}
1313
}
1414

15+
const IS_FABRIC = isFabric();
16+
1517
function flush() {
16-
if (__DEV__ && !isFabric()) {
18+
if (__DEV__ && !IS_FABRIC) {
1719
throw new ReanimatedError(
1820
'AnimatedPropsRegistry is only available on Fabric.'
1921
);

packages/react-native-reanimated/src/PlatformChecker.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export function shouldBeUseWeb() {
3535
}
3636

3737
export function isFabric() {
38-
return !!(global as localGlobal)._IS_FABRIC;
38+
return !!globalThis.RN$Bridgeless;
3939
}
4040

4141
export function isWindowAvailable() {

packages/react-native-reanimated/src/ReanimatedModule/NativeReanimated.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import type {
3232
} from './reanimatedModuleProxy';
3333

3434
const IS_WEB = shouldBeUseWeb();
35+
const IS_FABRIC = isFabric();
3536

3637
export function createNativeReanimatedModule(): IReanimatedModule {
3738
return new NativeReanimatedModule();
@@ -73,7 +74,7 @@ class NativeReanimatedModule implements IReanimatedModule {
7374
See https://docs.swmansion.com/react-native-reanimated/docs/guides/troubleshooting#native-part-of-reanimated-doesnt-seem-to-be-initialized for more details.`
7475
);
7576
}
76-
if (!isFabric() && !IS_WEB) {
77+
if (!IS_FABRIC && !IS_WEB) {
7778
throw new ReanimatedError(
7879
'Reanimated 4 supports only the React Native New Architecture and web.'
7980
);
@@ -130,7 +131,7 @@ See https://docs.swmansion.com/react-native-reanimated/docs/guides/troubleshooti
130131
callback?: (result: T) => void
131132
) {
132133
let shadowNodeWrapper;
133-
if (isFabric()) {
134+
if (IS_FABRIC) {
134135
shadowNodeWrapper = getShadowNodeWrapperFromRef(
135136
component as React.Component
136137
);

packages/react-native-reanimated/src/UpdateLayoutAnimations.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import {
1212
} from './core';
1313
import { isFabric, shouldBeUseWeb } from './PlatformChecker';
1414

15+
const IS_FABRIC = isFabric();
16+
1517
function createUpdateManager() {
1618
const animations: LayoutAnimationBatchItem[] = [];
1719
// When a stack is rerendered we reconfigure all the shared elements.
@@ -27,7 +29,7 @@ function createUpdateManager() {
2729
animations.push(batchItem);
2830
}
2931
if (animations.length + deferredAnimations.length === 1) {
30-
isFabric() ? this.flush() : setImmediate(this.flush);
32+
IS_FABRIC ? this.flush() : setImmediate(this.flush);
3133
}
3234
},
3335
flush(this: void) {

packages/react-native-reanimated/src/core.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export {
3434

3535
const EDGE_TO_EDGE = isEdgeToEdge();
3636
const SHOULD_BE_USE_WEB = shouldBeUseWeb();
37+
const IS_FABRIC = isFabric();
3738

3839
/** @returns `true` in Reanimated 3, doesn't exist in Reanimated 2 or 1 */
3940
export const isReanimated3 = () => true;
@@ -53,7 +54,7 @@ export function getViewProp<T>(
5354
propName: string,
5455
component?: React.Component // required on Fabric
5556
): Promise<T> {
56-
if (isFabric() && !component) {
57+
if (IS_FABRIC && !component) {
5758
throw new ReanimatedError(
5859
'Function `getViewProp` requires a component to be passed as an argument on Fabric.'
5960
);

packages/react-native-reanimated/src/createAnimatedComponent/AnimatedComponent.tsx

+7-6
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ let id = 0;
4646
const IS_WEB = isWeb();
4747
const IS_JEST = isJest();
4848
const SHOULD_BE_USE_WEB = shouldBeUseWeb();
49+
const IS_FABRIC = isFabric();
4950

5051
if (IS_WEB) {
5152
configureWebLayoutAnimations();
@@ -98,7 +99,7 @@ export default class AnimatedComponent
9899
!entering ||
99100
getReducedMotionFromConfig(entering as CustomConfig) ||
100101
skipEntering ||
101-
!isFabric()
102+
!IS_FABRIC
102103
) {
103104
return;
104105
}
@@ -184,7 +185,7 @@ export default class AnimatedComponent
184185
this._componentDOMRef as ReanimatedHTMLElement,
185186
LayoutAnimationType.EXITING
186187
);
187-
} else if (exiting && !IS_WEB && !isFabric()) {
188+
} else if (exiting && !IS_WEB && !IS_FABRIC) {
188189
const reduceMotionInExiting =
189190
'getReduceMotion' in exiting &&
190191
typeof exiting.getReduceMotion === 'function'
@@ -209,7 +210,7 @@ export default class AnimatedComponent
209210
if (this.props.animatedProps?.viewDescriptors) {
210211
this.props.animatedProps.viewDescriptors.remove(viewTag);
211212
}
212-
if (isFabric()) {
213+
if (IS_FABRIC) {
213214
removeFromPropsRegistry(viewTag);
214215
}
215216
}
@@ -404,7 +405,7 @@ export default class AnimatedComponent
404405
if (sharedTransitionTag) {
405406
this._configureSharedTransition();
406407
}
407-
if (exiting && isFabric()) {
408+
if (exiting && IS_FABRIC) {
408409
const reduceMotionInExiting =
409410
'getReduceMotion' in exiting &&
410411
typeof exiting.getReduceMotion === 'function'
@@ -420,7 +421,7 @@ export default class AnimatedComponent
420421
}
421422

422423
const skipEntering = this.context?.current;
423-
if (entering && !isFabric() && !skipEntering && !IS_WEB) {
424+
if (entering && !IS_FABRIC && !skipEntering && !IS_WEB) {
424425
updateLayoutAnimations(
425426
tag,
426427
LayoutAnimationType.ENTERING,
@@ -468,7 +469,7 @@ export default class AnimatedComponent
468469

469470
const skipEntering = this.context?.current;
470471
const nativeID =
471-
skipEntering || !isFabric() ? undefined : `${this.reanimatedID}`;
472+
skipEntering || !IS_FABRIC ? undefined : `${this.reanimatedID}`;
472473

473474
const jestProps = IS_JEST
474475
? {

packages/react-native-reanimated/src/createAnimatedComponent/JSPropsUpdater.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type { NativeModule } from 'react-native';
33
import { NativeEventEmitter, Platform } from 'react-native';
44

55
import type { StyleProps } from '../commonTypes';
6-
import { shouldBeUseWeb } from '../PlatformChecker';
6+
import { isFabric, shouldBeUseWeb } from '../PlatformChecker';
77
import NativeReanimatedModule from '../specs/NativeReanimatedModule';
88
import { runOnJS, runOnUIImmediately } from '../WorkletsResolver';
99
import type {
@@ -147,7 +147,7 @@ type JSPropsUpdaterOptions =
147147
let JSPropsUpdater: JSPropsUpdaterOptions;
148148
if (SHOULD_BE_USE_WEB) {
149149
JSPropsUpdater = JSPropsUpdaterWeb;
150-
} else if (global._IS_FABRIC) {
150+
} else if (isFabric()) {
151151
JSPropsUpdater = JSPropsUpdaterFabric;
152152
} else {
153153
JSPropsUpdater = JSPropsUpdaterPaper;

packages/react-native-reanimated/src/css/component/AnimatedComponent.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { filterNonCSSStyleProps } from './utils';
2121

2222
const SHOULD_BE_USE_WEB = shouldBeUseWeb();
2323
const IS_WEB = isWeb();
24+
const IS_FABRIC = isFabric();
2425

2526
export type AnimatedComponentProps = Record<string, unknown> & {
2627
ref?: Ref<Component>;
@@ -98,7 +99,7 @@ export default class AnimatedComponent<
9899
viewTag = viewInfo.viewTag;
99100
viewName = viewInfo.viewName;
100101
viewConfig = viewInfo.viewConfig;
101-
shadowNodeWrapper = isFabric()
102+
shadowNodeWrapper = IS_FABRIC
102103
? getShadowNodeWrapperFromRef(this, hostInstance)
103104
: null;
104105
}
@@ -155,7 +156,7 @@ export default class AnimatedComponent<
155156
componentDidMount() {
156157
this._updateStyles(this.props);
157158

158-
if (isFabric() || IS_WEB) {
159+
if (IS_FABRIC || IS_WEB) {
159160
this._CSSManager = new CSSManager(this._getViewInfo());
160161
this._CSSManager?.attach(this._cssStyle);
161162
}

packages/react-native-reanimated/src/hook/useAnimatedRef.ts

+6-5
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import type { AnimatedRef, AnimatedRefOnUI } from './commonTypes';
1616
import { useSharedValue } from './useSharedValue';
1717

1818
const IS_WEB = isWeb();
19+
const IS_FABRIC = isFabric();
1920

2021
interface MaybeScrollableComponent extends Component {
2122
getNativeScrollRef?: FlatList['getNativeScrollRef'];
@@ -28,9 +29,9 @@ interface MaybeScrollableComponent extends Component {
2829
}
2930

3031
function getComponentOrScrollable(component: MaybeScrollableComponent) {
31-
if (isFabric() && component.getNativeScrollRef) {
32+
if (IS_FABRIC && component.getNativeScrollRef) {
3233
return component.getNativeScrollRef();
33-
} else if (!isFabric() && component.getScrollableNode) {
34+
} else if (!IS_FABRIC && component.getScrollableNode) {
3435
return component.getScrollableNode();
3536
}
3637
return component;
@@ -57,7 +58,7 @@ export function useAnimatedRef<
5758
) => {
5859
// enters when ref is set by attaching to a component
5960
if (component) {
60-
const getTagValueFunction = isFabric()
61+
const getTagValueFunction = IS_FABRIC
6162
? getShadowNodeWrapperFromRef
6263
: findNodeHandle;
6364

@@ -70,13 +71,13 @@ export function useAnimatedRef<
7071
tag.value = getTagOrShadowNodeWrapper();
7172

7273
// On Fabric we have to unwrap the tag from the shadow node wrapper
73-
fun.getTag = isFabric()
74+
fun.getTag = IS_FABRIC
7475
? () => findNodeHandle(getComponentOrScrollable(component))
7576
: getTagOrShadowNodeWrapper;
7677

7778
fun.current = component;
7879
// viewName is required only on iOS with Paper
79-
if (Platform.OS === 'ios' && !isFabric()) {
80+
if (Platform.OS === 'ios' && !IS_FABRIC) {
8081
viewName.value =
8182
(component as MaybeScrollableComponent)?.viewConfig
8283
?.uiViewClassName || 'RCTView';

packages/react-native-reanimated/src/platform-specific/findHostInstance.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,13 @@ function findHostInstanceFastPath(maybeNativeRef: HostInstance | undefined) {
3939
return undefined;
4040
}
4141

42+
const IS_FABRIC = isFabric();
43+
4244
function resolveFindHostInstance_DEPRECATED() {
4345
if (findHostInstance_DEPRECATED !== undefined) {
4446
return;
4547
}
46-
if (isFabric()) {
48+
if (IS_FABRIC) {
4749
try {
4850
const ReactFabric = require('react-native/Libraries/Renderer/shims/ReactFabric');
4951
// Since RN 0.77 ReactFabric exports findHostInstance_DEPRECATED in default object so we're trying to
@@ -86,7 +88,7 @@ export function findHostInstance(
8688
a valid React ref.
8789
*/
8890
return findHostInstance_DEPRECATED(
89-
!isFabric() || (component as IAnimatedComponentInternal).hasAnimatedRef()
91+
!IS_FABRIC || (component as IAnimatedComponentInternal).hasAnimatedRef()
9092
? (component as IAnimatedComponentInternal)._componentRef
9193
: component
9294
);

packages/react-native-reanimated/src/privateGlobals.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import type { UpdatePropsManager } from './UpdateProps';
2323
declare global {
2424
var __DISALLOW_WORKLETS_IMPORT: boolean | undefined;
2525
var _REANIMATED_IS_REDUCED_MOTION: boolean | undefined;
26-
var _IS_FABRIC: boolean | undefined;
2726
var _REANIMATED_VERSION_CPP: string | undefined;
2827
var _REANIMATED_VERSION_JS: string | undefined;
2928
var __reanimatedModuleProxy: ReanimatedModuleProxy | undefined;
@@ -88,4 +87,5 @@ declare global {
8887
shadowNodeWrapper: ShadowNodeWrapper,
8988
propName: string
9089
) => string;
90+
var RN$Bridgeless: boolean | undefined;
9191
}

packages/react-native-reanimated/src/publicGlobals.ts

+3
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,7 @@ declare global {
2020
* Reanimated UI runtime.
2121
*/
2222
var _WORKLET_RUNTIME: ArrayBuffer;
23+
24+
/** @deprecated Don't use. */
25+
var _IS_FABRIC: boolean | undefined;
2326
}

packages/react-native-worklets/Common/cpp/worklets/WorkletRuntime/RNRuntimeWorkletDecorator.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ void RNRuntimeWorkletDecorator::decorate(
77
const std::shared_ptr<WorkletsModuleProxy> &workletsModuleProxy) {
88
rnRuntime.global().setProperty(rnRuntime, "_WORKLET", false);
99

10+
// TODO: Remove _IS_FABRIC sometime in the future
11+
// react-native-screens 4.9.0 depends on it
1012
#ifdef RCT_NEW_ARCH_ENABLED
1113
constexpr auto isFabric = true;
1214
#else

packages/react-native-worklets/Common/cpp/worklets/WorkletRuntime/WorkletRuntimeDecorator.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ void WorkletRuntimeDecorator::decorate(
4747

4848
rt.global().setProperty(rt, "_LABEL", jsi::String::createFromAscii(rt, name));
4949

50+
// TODO: Remove _IS_FABRIC sometime in the future
51+
// react-native-screens 4.9.0 depends on it
5052
#ifdef RCT_NEW_ARCH_ENABLED
5153
constexpr auto isFabric = true;
5254
#else

packages/react-native-worklets/src/worklets/PlatformChecker.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export function shouldBeUseWeb() {
3535
}
3636

3737
export function isFabric() {
38-
return !!(global as localGlobal)._IS_FABRIC;
38+
return !!globalThis.RN$Bridgeless;
3939
}
4040

4141
export function isWindowAvailable() {

packages/react-native-worklets/src/worklets/privateGlobals.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,5 @@ declare global {
3838
runtime: WorkletRuntime,
3939
worklet: ShareableRef<() => void>
4040
) => void;
41+
var RN$Bridgeless: boolean | undefined;
4142
}

0 commit comments

Comments
 (0)