@rnx-kit/react-native-host 0.4.1 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -16,10 +16,12 @@ preprocessor_definitions = [
16
16
  'FOLLY_MOBILE=1',
17
17
  'FOLLY_NO_CONFIG=1',
18
18
  'FOLLY_USE_LIBCPP=1',
19
+ "USE_HERMES=#{ENV['USE_HERMES'] || '0'}",
19
20
  ]
20
21
  if new_arch_enabled
21
22
  preprocessor_definitions << 'RCT_NEW_ARCH_ENABLED=1'
22
23
  preprocessor_definitions << 'USE_FABRIC=1'
24
+ preprocessor_definitions << 'USE_BRIDGELESS=1' if ENV['USE_BRIDGELESS'] == '1'
23
25
  end
24
26
 
25
27
  Pod::Spec.new do |s|
@@ -0,0 +1,40 @@
1
+ #if USE_BRIDGELESS
2
+
3
+ #import <React/RCTSurfacePresenterBridgeAdapter.h>
4
+ #import <ReactCommon/RCTHost+Internal.h>
5
+ #import <ReactCommon/RCTHost.h>
6
+
7
+ #if USE_HERMES
8
+ #import <ReactCommon/RCTHermesInstance.h>
9
+ #else
10
+ #import <ReactCommon/RCTJscInstance.h>
11
+ #endif // USE_HERMES
12
+
13
+ #import <react/config/ReactNativeConfig.h>
14
+
15
+ #if __has_include(<react/runtime/JSEngineInstance.h>)
16
+ using SharedJSRuntimeFactory = std::shared_ptr<facebook::react::JSEngineInstance>;
17
+ #else
18
+ using SharedJSRuntimeFactory = std::shared_ptr<facebook::react::JSRuntimeFactory>;
19
+ #endif // __has_include(<react/runtime/JSEngineInstance.h>)
20
+
21
+ #elif USE_FABRIC
22
+
23
+ #import <React/RCTSurfacePresenterBridgeAdapter.h>
24
+ #import <react/config/ReactNativeConfig.h>
25
+
26
+ @class RCTHost;
27
+
28
+ #else
29
+
30
+ @class RCTHost;
31
+ @class RCTSurfacePresenterBridgeAdapter;
32
+
33
+ namespace facebook::react
34
+ {
35
+ class EmptyReactNativeConfig
36
+ {
37
+ };
38
+ } // namespace facebook::react
39
+
40
+ #endif // USE_BRIDGELESS
@@ -1,9 +1,11 @@
1
1
  #import <Foundation/Foundation.h>
2
2
 
3
3
  @class RCTBridge;
4
+ @class RCTSurfacePresenterBridgeAdapter;
4
5
 
5
6
  NS_ASSUME_NONNULL_BEGIN
6
7
 
7
- NSObject *RNXInstallSurfacePresenterBridgeAdapter(RCTBridge *bridge);
8
+ RCTSurfacePresenterBridgeAdapter *_Nullable RNXInstallSurfacePresenterBridgeAdapter(
9
+ RCTBridge *bridge);
8
10
 
9
11
  NS_ASSUME_NONNULL_END
@@ -1,6 +1,6 @@
1
1
  #import "RNXFabricAdapter.h"
2
2
 
3
- #ifdef USE_FABRIC
3
+ #if USE_FABRIC && !USE_BRIDGELESS
4
4
  #include "FollyConfig.h"
5
5
  #pragma clang diagnostic push
6
6
  #pragma clang diagnostic ignored "-Wcomma"
@@ -9,11 +9,11 @@
9
9
  #import <React/RCTSurfacePresenterBridgeAdapter.h>
10
10
  #import <react/config/ReactNativeConfig.h>
11
11
  #pragma clang diagnostic pop
12
- #endif // USE_FABRIC
12
+ #endif // USE_FABRIC && !USE_BRIDGELESS
13
13
 
14
- NSObject *RNXInstallSurfacePresenterBridgeAdapter(RCTBridge *bridge)
14
+ RCTSurfacePresenterBridgeAdapter *RNXInstallSurfacePresenterBridgeAdapter(RCTBridge *bridge)
15
15
  {
16
- #ifdef USE_FABRIC
16
+ #if USE_FABRIC && !USE_BRIDGELESS
17
17
  auto contextContainer = std::make_shared<facebook::react::ContextContainer const>();
18
18
  auto reactNativeConfig = std::make_shared<facebook::react::EmptyReactNativeConfig const>();
19
19
  contextContainer->insert("ReactNativeConfig", reactNativeConfig);
@@ -24,5 +24,5 @@ NSObject *RNXInstallSurfacePresenterBridgeAdapter(RCTBridge *bridge)
24
24
  return bridgeAdapter;
25
25
  #else
26
26
  return nil;
27
- #endif // USE_FABRIC
27
+ #endif // USE_FABRIC && !USE_BRIDGELESS
28
28
  }
@@ -10,6 +10,9 @@ NS_ASSUME_NONNULL_BEGIN
10
10
 
11
11
  @optional
12
12
 
13
+ /// Returns whether the new initialization layer is enabled.
14
+ @property (nonatomic, readonly) BOOL isBridgelessEnabled;
15
+
13
16
  /// Returns whether the loading view should be visible while loading JavaScript.
14
17
  @property (nonatomic, readonly) BOOL isDevLoadingViewEnabled;
15
18
 
@@ -67,13 +67,13 @@
67
67
 
68
68
  // MARK: - RCTTurboModuleManagerDelegate details
69
69
 
70
- - (Class)getModuleClassFromName:(const char *)name
70
+ - (Class)getModuleClassFromName:(char const *)name
71
71
  {
72
72
  return RCTCoreModulesClassProvider(name);
73
73
  }
74
74
 
75
75
  - (std::shared_ptr<facebook::react::TurboModule>)
76
- getTurboModule:(const std::string &)name
76
+ getTurboModule:(std::string const &)name
77
77
  jsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker
78
78
  {
79
79
  return nullptr;
@@ -0,0 +1,16 @@
1
+ #import "ReactNativeHost.h"
2
+
3
+ @class RCTSurfacePresenter;
4
+
5
+ NS_ASSUME_NONNULL_BEGIN
6
+
7
+ @interface ReactNativeHost (Private)
8
+
9
+ /// Returns the current ``RCTSurfacePresenter`` instance.
10
+ ///
11
+ /// - Note: Returns `nil` if New Architecture is not enabled.
12
+ @property (nonatomic, readonly, nullable) RCTSurfacePresenter *surfacePresenter;
13
+
14
+ @end
15
+
16
+ NS_ASSUME_NONNULL_END
@@ -1,4 +1,4 @@
1
- #import "ReactNativeHost.h"
1
+ #import "ReactNativeHost+Private.h"
2
2
 
3
3
  #ifdef USE_FABRIC
4
4
  #if __has_include(<React/RCTFabricSurfaceHostingProxyRootView.h>)
@@ -7,6 +7,7 @@
7
7
  #import <React/RCTFabricSurface.h>
8
8
  #import <React/RCTSurfaceHostingProxyRootView.h>
9
9
  #endif // __has_include(<React/RCTFabricSurfaceHostingProxyRootView.h>)
10
+ static NSString *const kReactConcurrentRoot = @"concurrentRoot";
10
11
  #else
11
12
  #import <React/RCTRootView.h>
12
13
  #endif // USE_FABRIC
@@ -36,14 +37,27 @@
36
37
  initialProperties:(NSDictionary *)initialProperties;
37
38
  {
38
39
  #ifdef USE_FABRIC
40
+ // Having `concurrentRoot` disabled when Fabric is enabled is not recommended:
41
+ // https://github.com/facebook/react-native/commit/7eaabfb174b14a30c30c7017195e8110348e5f44
42
+ // As of 0.74, it won't be possible to opt-out:
43
+ // https://github.com/facebook/react-native/commit/30d186c3683228d4fb7a42f804eb2fdfa7c8ac03
44
+ NSMutableDictionary *initialProps =
45
+ initialProperties == nil
46
+ ? [NSMutableDictionary dictionaryWithObjectsAndKeys:@YES, kReactConcurrentRoot, nil]
47
+ : [initialProperties mutableCopy];
48
+ if (initialProps[kReactConcurrentRoot] == nil) {
49
+ initialProps[kReactConcurrentRoot] = @YES;
50
+ }
51
+
39
52
  #if __has_include(<React/RCTFabricSurfaceHostingProxyRootView.h>)
40
53
  return [[RCTFabricSurfaceHostingProxyRootView alloc] initWithBridge:self.bridge
41
54
  moduleName:moduleName
42
- initialProperties:initialProperties];
55
+ initialProperties:initialProps];
43
56
  #else
44
- RCTFabricSurface *surface = [[RCTFabricSurface alloc] initWithBridge:self.bridge
45
- moduleName:moduleName
46
- initialProperties:initialProperties];
57
+ RCTFabricSurface *surface =
58
+ [[RCTFabricSurface alloc] initWithSurfacePresenter:self.surfacePresenter
59
+ moduleName:moduleName
60
+ initialProperties:initialProps];
47
61
  return [[RCTSurfaceHostingProxyRootView alloc] initWithSurface:surface];
48
62
  #endif // __has_include(<React/RCTFabricSurfaceHostingProxyRootView.h>)
49
63
  #else
@@ -17,7 +17,7 @@ NS_ASSUME_NONNULL_BEGIN
17
17
  /// Hosts a React Native instance.
18
18
  @interface ReactNativeHost : NSObject <RCTBridgeDelegate>
19
19
 
20
- /// Returns the current `RCTBridge` instance.
20
+ /// Returns the current ``RCTBridge`` instance.
21
21
  ///
22
22
  /// - Note: This is not forwards compatible and will be removed in the future.
23
23
  @property (nonatomic, readonly, nullable) RCTBridge *bridge;
@@ -12,21 +12,32 @@
12
12
  #import <React/RCTDevLoadingViewSetEnabled.h>
13
13
  #import <React/RCTUtils.h>
14
14
 
15
+ #import "RNXBridgelessHeaders.h"
15
16
  #import "RNXFabricAdapter.h"
16
17
  #import "RNXHostConfig.h"
17
18
  #import "RNXHostReleaser.h"
18
19
  #import "RNXTurboModuleAdapter.h"
19
20
 
21
+ @class RCTSurfacePresenter;
22
+
23
+ using ReactNativeConfig = facebook::react::EmptyReactNativeConfig const;
24
+
25
+ #if USE_BRIDGELESS
26
+ @interface ReactNativeHost () <RCTContextContainerHandling>
27
+ #else
20
28
  @interface ReactNativeHost () <RCTCxxBridgeDelegate>
29
+ #endif // USE_BRIDGELESS
21
30
  @end
22
31
 
23
32
  @implementation ReactNativeHost {
24
33
  __weak id<RNXHostConfig> _config;
25
34
  RNXTurboModuleAdapter *_turboModuleAdapter;
26
- NSObject *_surfacePresenterBridgeAdapter;
35
+ RCTSurfacePresenterBridgeAdapter *_surfacePresenterBridgeAdapter;
27
36
  RCTBridge *_bridge;
37
+ RCTHost *_reactHost;
28
38
  NSLock *_isShuttingDown;
29
39
  RNXHostReleaser *_hostReleaser;
40
+ std::shared_ptr<ReactNativeConfig> _reactNativeConfig;
30
41
  }
31
42
 
32
43
  - (instancetype)initWithConfig:(id<RNXHostConfig>)config
@@ -53,9 +64,7 @@
53
64
  }
54
65
 
55
66
  _config = config;
56
- #if USE_FABRIC
57
- _turboModuleAdapter = [[RNXTurboModuleAdapter alloc] init];
58
- #endif
67
+ [self enableTurboModule];
59
68
  _isShuttingDown = [[NSLock alloc] init];
60
69
 
61
70
  if ([config respondsToSelector:@selector(shouldReleaseBridgeWhenBackgrounded)] &&
@@ -63,13 +72,16 @@
63
72
  _hostReleaser = [[RNXHostReleaser alloc] initWithHost:self];
64
73
  }
65
74
 
66
- (void)self.bridge; // Initialize the bridge now
75
+ [self initializeReactHost];
67
76
  }
68
77
  return self;
69
78
  }
70
79
 
71
80
  - (RCTBridge *)bridge
72
81
  {
82
+ #if USE_BRIDGELESS
83
+ return nil;
84
+ #else
73
85
  if (![_isShuttingDown tryLock]) {
74
86
  NSAssert(NO, @"Tried to access the bridge while shutting down");
75
87
  return nil;
@@ -86,6 +98,18 @@
86
98
  } @finally {
87
99
  [_isShuttingDown unlock];
88
100
  }
101
+ #endif // USE_BRIDGELESS
102
+ }
103
+
104
+ - (RCTSurfacePresenter *)surfacePresenter
105
+ {
106
+ #if USE_BRIDGELESS
107
+ return [_reactHost getSurfacePresenter];
108
+ #elif USE_FABRIC
109
+ return [_surfacePresenterBridgeAdapter surfacePresenter];
110
+ #else
111
+ return nil;
112
+ #endif
89
113
  }
90
114
 
91
115
  - (void)shutdown
@@ -102,11 +126,11 @@
102
126
 
103
127
  - (void)usingModule:(Class)moduleClass block:(void (^)(id<RCTBridgeModule> _Nullable))block
104
128
  {
105
- const BOOL requiresMainQueueSetup =
129
+ BOOL const requiresMainQueueSetup =
106
130
  [moduleClass respondsToSelector:@selector(requiresMainQueueSetup)] &&
107
131
  [moduleClass requiresMainQueueSetup];
108
132
  if (requiresMainQueueSetup && !RCTIsMainQueue()) {
109
- __weak id weakSelf = self;
133
+ __weak __typeof(self) weakSelf = self;
110
134
  dispatch_async(dispatch_get_main_queue(), ^{
111
135
  [weakSelf usingModule:moduleClass block:block];
112
136
  });
@@ -139,6 +163,18 @@
139
163
  : @[];
140
164
  }
141
165
 
166
+ #if USE_BRIDGELESS
167
+
168
+ // MARK: - RCTContextContainerHandling details
169
+
170
+ - (void)didCreateContextContainer:
171
+ (std::shared_ptr<facebook::react::ContextContainer>)contextContainer
172
+ {
173
+ contextContainer->insert("ReactNativeConfig", _reactNativeConfig);
174
+ }
175
+
176
+ #else // USE_BRIDGELESS
177
+
142
178
  // MARK: - RCTCxxBridgeDelegate details
143
179
 
144
180
  - (std::unique_ptr<facebook::react::JSExecutorFactory>)jsExecutorFactoryForBridge:
@@ -153,6 +189,61 @@
153
189
  #endif // USE_FABRIC
154
190
  }
155
191
 
192
+ #endif // USE_BRIDGELESS
193
+
156
194
  // MARK: - Private
157
195
 
196
+ - (void)enableTurboModule
197
+ {
198
+ #if USE_FABRIC
199
+ _turboModuleAdapter = [[RNXTurboModuleAdapter alloc] init];
200
+ RCTEnableTurboModule(true);
201
+ #endif
202
+ }
203
+
204
+ - (void)initializeReactHost
205
+ {
206
+ #if USE_BRIDGELESS
207
+ // Bridgeless mode is enabled if it was turned on with a build flag, unless
208
+ // `isBridgelessEnabled` is explicitly implemented and returns false.
209
+ if ([_config respondsToSelector:@selector(isBridgelessEnabled)] &&
210
+ ![_config isBridgelessEnabled]) {
211
+ (void)self.bridge; // Initialize the bridge now
212
+ return;
213
+ }
214
+
215
+ RCTSetUseNativeViewConfigsInBridgelessMode(YES);
216
+ RCTEnableTurboModuleInterop(YES);
217
+ RCTEnableTurboModuleInteropBridgeProxy(YES);
218
+
219
+ _reactNativeConfig = std::make_shared<ReactNativeConfig>();
220
+ std::weak_ptr<ReactNativeConfig> reactNativeConfig{_reactNativeConfig};
221
+
222
+ SharedJSRuntimeFactory (^jsEngineProvider)() = ^SharedJSRuntimeFactory {
223
+ #if USE_HERMES
224
+ auto config = reactNativeConfig.lock();
225
+ NSAssert(config, @"Expected nonnull ReactNativeConfig instance");
226
+ return std::make_shared<facebook::react::RCTHermesInstance>(config, nullptr);
227
+ #else
228
+ return std::make_shared<facebook::react::RCTJscInstance>();
229
+ #endif // USE_HERMES
230
+ };
231
+
232
+ _reactHost = [[RCTHost alloc] initWithBundleURL:[self sourceURLForBridge:nil]
233
+ hostDelegate:nil
234
+ turboModuleManagerDelegate:_turboModuleAdapter
235
+ jsEngineProvider:jsEngineProvider];
236
+
237
+ __weak __typeof(self) weakSelf = self;
238
+ [_reactHost setBundleURLProvider:^NSURL *() {
239
+ return [weakSelf sourceURLForBridge:nil];
240
+ }];
241
+
242
+ [_reactHost setContextContainerHandler:self];
243
+ [_reactHost start];
244
+ #else
245
+ (void)self.bridge;
246
+ #endif // USE_BRIDGELESS
247
+ }
248
+
158
249
  @end
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rnx-kit/react-native-host",
3
- "version": "0.4.1",
3
+ "version": "0.4.3",
4
4
  "description": "Simplify React Native initialization",
5
5
  "homepage": "https://github.com/microsoft/rnx-kit/tree/main/packages/react-native-host#readme",
6
6
  "license": "MIT",