expo-modules-core 0.4.6 → 0.6.0

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.
Files changed (150) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +6 -6
  3. package/android/build.gradle +30 -2
  4. package/android/src/main/java/expo/modules/adapters/react/ModuleRegistryAdapter.java +27 -5
  5. package/android/src/main/java/expo/modules/adapters/react/NativeModulesProxy.java +49 -5
  6. package/android/src/main/java/expo/modules/core/BasePackage.java +6 -0
  7. package/android/src/main/java/expo/modules/core/ModulePriorities.kt +25 -0
  8. package/android/src/main/java/expo/modules/core/interfaces/ActivityEventListener.java +3 -1
  9. package/android/src/main/java/expo/modules/core/interfaces/ApplicationLifecycleListener.java +10 -0
  10. package/android/src/main/java/expo/modules/core/interfaces/Package.java +4 -0
  11. package/android/src/main/java/expo/modules/core/interfaces/ReactActivityHandler.java +21 -0
  12. package/android/src/main/java/expo/modules/core/interfaces/ReactActivityLifecycleListener.java +14 -0
  13. package/android/src/main/java/expo/modules/core/interfaces/ReactNativeHostHandler.java +70 -0
  14. package/android/src/main/java/expo/modules/core/utilities/KotlinUtilities.kt +23 -0
  15. package/android/src/main/java/expo/modules/kotlin/AppContext.kt +166 -0
  16. package/android/src/main/java/expo/modules/kotlin/DynamicExtenstions.kt +9 -0
  17. package/android/src/main/java/expo/modules/kotlin/ExpoModulesHelper.kt +18 -0
  18. package/android/src/main/java/expo/modules/kotlin/KPromiseWrapper.kt +24 -0
  19. package/android/src/main/java/expo/modules/kotlin/KotlinInteropModuleRegistry.kt +98 -0
  20. package/android/src/main/java/expo/modules/kotlin/ModuleHolder.kt +41 -0
  21. package/android/src/main/java/expo/modules/kotlin/ModuleRegistry.kt +56 -0
  22. package/android/src/main/java/expo/modules/kotlin/ModulesProvider.kt +7 -0
  23. package/android/src/main/java/expo/modules/kotlin/Promise.kt +13 -0
  24. package/android/src/main/java/expo/modules/kotlin/ReactLifecycleDelegate.kt +39 -0
  25. package/android/src/main/java/expo/modules/kotlin/ReadableArrayIterator.kt +14 -0
  26. package/android/src/main/java/expo/modules/kotlin/ReadableTypeExtensions.kt +18 -0
  27. package/android/src/main/java/expo/modules/kotlin/allocators/ObjectConstructor.kt +5 -0
  28. package/android/src/main/java/expo/modules/kotlin/allocators/ObjectConstructorFactory.kt +31 -0
  29. package/android/src/main/java/expo/modules/kotlin/allocators/UnsafeAllocator.kt +49 -0
  30. package/android/src/main/java/expo/modules/kotlin/events/EventListener.kt +39 -0
  31. package/android/src/main/java/expo/modules/kotlin/events/EventName.kt +31 -0
  32. package/android/src/main/java/expo/modules/kotlin/events/EventsDefinition.kt +3 -0
  33. package/android/src/main/java/expo/modules/kotlin/events/KEventEmitterWrapper.kt +26 -0
  34. package/android/src/main/java/expo/modules/kotlin/events/OnActivityResultPayload.kt +8 -0
  35. package/android/src/main/java/expo/modules/kotlin/exception/CodedException.kt +70 -0
  36. package/android/src/main/java/expo/modules/kotlin/methods/AnyMethod.kt +50 -0
  37. package/android/src/main/java/expo/modules/kotlin/methods/Method.kt +14 -0
  38. package/android/src/main/java/expo/modules/kotlin/methods/PromiseMethod.kt +15 -0
  39. package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +24 -0
  40. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +227 -0
  41. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionData.kt +16 -0
  42. package/android/src/main/java/expo/modules/kotlin/records/Field.kt +5 -0
  43. package/android/src/main/java/expo/modules/kotlin/records/Record.kt +3 -0
  44. package/android/src/main/java/expo/modules/kotlin/records/RecordTypeConverter.kt +55 -0
  45. package/android/src/main/java/expo/modules/kotlin/types/AnyType.kt +14 -0
  46. package/android/src/main/java/expo/modules/kotlin/types/ArrayTypeConverter.kt +44 -0
  47. package/android/src/main/java/expo/modules/kotlin/types/BasicTypeConverters.kt +60 -0
  48. package/android/src/main/java/expo/modules/kotlin/types/EnumTypeConverter.kt +84 -0
  49. package/android/src/main/java/expo/modules/kotlin/types/ListTypeConverter.kt +25 -0
  50. package/android/src/main/java/expo/modules/kotlin/types/MapTypeConverter.kt +39 -0
  51. package/android/src/main/java/expo/modules/kotlin/types/PairTypeConverter.kt +28 -0
  52. package/android/src/main/java/expo/modules/kotlin/types/TypeConverter.kt +19 -0
  53. package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +107 -0
  54. package/android/src/main/java/expo/modules/kotlin/views/AnyViewProp.kt +10 -0
  55. package/android/src/main/java/expo/modules/kotlin/views/ConcreteViewProp.kt +17 -0
  56. package/android/src/main/java/expo/modules/kotlin/views/GroupViewManagerWrapper.kt +22 -0
  57. package/android/src/main/java/expo/modules/kotlin/views/SimpleViewManagerWrapper.kt +21 -0
  58. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinition.kt +41 -0
  59. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinitionBuilder.kt +40 -0
  60. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerWrapperDelegate.kt +21 -0
  61. package/android/src/main/java/expo/modules/kotlin/views/ViewWrapperDelegateHolder.kt +5 -0
  62. package/build/NativeModulesProxy.native.d.ts +4 -0
  63. package/build/NativeModulesProxy.native.js +14 -1
  64. package/build/NativeModulesProxy.native.js.map +1 -1
  65. package/build/NativeModulesProxy.types.d.ts +3 -0
  66. package/build/NativeModulesProxy.types.js.map +1 -1
  67. package/build/NativeViewManagerAdapter.native.js +1 -1
  68. package/build/NativeViewManagerAdapter.native.js.map +1 -1
  69. package/ios/AppDelegates/EXAppDelegateWrapper.h +19 -0
  70. package/ios/AppDelegates/EXAppDelegateWrapper.m +45 -0
  71. package/ios/AppDelegates/EXAppDelegatesLoader.h +15 -0
  72. package/ios/AppDelegates/EXAppDelegatesLoader.m +30 -0
  73. package/ios/AppDelegates/EXLegacyAppDelegateWrapper.h +16 -0
  74. package/ios/{EXAppDelegateWrapper.m → AppDelegates/EXLegacyAppDelegateWrapper.m} +2 -2
  75. package/ios/AppDelegates/ExpoAppDelegate.swift +282 -0
  76. package/ios/AppDelegates/ExpoAppDelegateSubscriber.swift +24 -0
  77. package/ios/EXAppDefines.h +26 -0
  78. package/ios/EXAppDefines.m +61 -0
  79. package/ios/ExpoModulesCore.podspec +8 -3
  80. package/ios/JSI/ExpoModulesProxySpec.h +24 -0
  81. package/ios/JSI/ExpoModulesProxySpec.mm +135 -0
  82. package/ios/JSI/JSIConversions.h +42 -0
  83. package/ios/JSI/JSIConversions.mm +164 -0
  84. package/ios/JSI/JSIInstaller.h +19 -0
  85. package/ios/JSI/JSIInstaller.mm +22 -0
  86. package/ios/ModuleRegistryAdapter/EXModuleRegistryAdapter.m +1 -6
  87. package/ios/NativeModulesProxy/EXNativeModulesProxy.h +6 -0
  88. package/ios/NativeModulesProxy/{EXNativeModulesProxy.m → EXNativeModulesProxy.mm} +91 -18
  89. package/ios/ReactDelegates/EXRCTBridgeDelegateInterceptor.h +16 -0
  90. package/ios/ReactDelegates/EXRCTBridgeDelegateInterceptor.m +49 -0
  91. package/ios/ReactDelegates/EXReactDelegateWrapper+Private.h +18 -0
  92. package/ios/ReactDelegates/EXReactDelegateWrapper.h +25 -0
  93. package/ios/ReactDelegates/EXReactDelegateWrapper.m +40 -0
  94. package/ios/ReactDelegates/ExpoReactDelegate.swift +37 -0
  95. package/ios/ReactDelegates/ExpoReactDelegateHandler.swift +52 -0
  96. package/ios/ReactDelegates/ModulePriorities.swift +20 -0
  97. package/ios/Services/EXReactNativeEventEmitter.h +6 -0
  98. package/ios/Services/EXReactNativeEventEmitter.m +15 -0
  99. package/ios/Swift/AppContext.swift +14 -1
  100. package/ios/Swift/Arguments/AnyArgument.swift +14 -0
  101. package/ios/Swift/Arguments/AnyArgumentType.swift +13 -0
  102. package/ios/Swift/Arguments/ArgumentType.swift +24 -0
  103. package/ios/Swift/Arguments/ConvertibleArgument.swift +15 -0
  104. package/ios/Swift/Arguments/Convertibles.swift +107 -0
  105. package/ios/Swift/Arguments/Types/ArrayArgumentType.swift +42 -0
  106. package/ios/Swift/Arguments/Types/ConvertibleArgumentType.swift +16 -0
  107. package/ios/Swift/Arguments/Types/EnumArgumentType.swift +105 -0
  108. package/ios/Swift/Arguments/Types/OptionalArgumentType.swift +49 -0
  109. package/ios/Swift/Arguments/Types/PromiseArgumentType.swift +15 -0
  110. package/ios/Swift/Arguments/Types/RawArgumentType.swift +25 -0
  111. package/ios/Swift/Conversions.swift +199 -7
  112. package/ios/Swift/EventListener.swift +37 -5
  113. package/ios/Swift/Functions/AnyFunction.swift +42 -0
  114. package/ios/Swift/{Methods/ConcreteMethod.swift → Functions/ConcreteFunction.swift} +32 -34
  115. package/ios/Swift/ModuleHolder.swift +86 -20
  116. package/ios/Swift/ModuleRegistry.swift +19 -8
  117. package/ios/Swift/Modules/AnyModule.swift +8 -8
  118. package/ios/Swift/Modules/Module.swift +11 -0
  119. package/ios/Swift/Modules/ModuleDefinition.swift +55 -15
  120. package/ios/Swift/Modules/ModuleDefinitionBuilder.swift +1 -1
  121. package/ios/Swift/Modules/ModuleDefinitionComponents.swift +149 -54
  122. package/ios/Swift/ModulesProvider.swift +19 -0
  123. package/ios/Swift/Promise.swift +1 -1
  124. package/ios/Swift/Records/Field.swift +1 -1
  125. package/ios/Swift/Records/Record.swift +8 -1
  126. package/ios/Swift/SwiftInteropBridge.swift +46 -17
  127. package/ios/Swift/Views/AnyViewProp.swift +2 -2
  128. package/ios/Swift/Views/ConcreteViewProp.swift +37 -10
  129. package/ios/Swift/Views/ViewModuleWrapper.swift +9 -4
  130. package/ios/Swift.h +9 -0
  131. package/ios/Tests/ArgumentTypeSpec.swift +145 -0
  132. package/ios/Tests/ConstantsSpec.swift +36 -0
  133. package/ios/Tests/ConvertiblesSpec.swift +265 -0
  134. package/ios/Tests/EXAppDefinesTest.m +99 -0
  135. package/ios/Tests/{MethodSpec.swift → FunctionSpec.swift} +69 -54
  136. package/ios/Tests/FunctionWithConvertiblesSpec.swift +66 -0
  137. package/ios/Tests/Mocks/ModuleMocks.swift +21 -7
  138. package/ios/Tests/ModuleEventListenersSpec.swift +17 -16
  139. package/ios/Tests/ModuleRegistrySpec.swift +4 -7
  140. package/package.json +3 -3
  141. package/src/NativeModulesProxy.native.ts +22 -2
  142. package/src/NativeModulesProxy.types.ts +8 -0
  143. package/src/NativeViewManagerAdapter.native.tsx +1 -1
  144. package/android/src/main/java/expo/modules/core/interfaces/ApplicationLifecycleListener.kt +0 -9
  145. package/android/src/main/java/expo/modules/core/interfaces/ReactActivityLifecycleListener.kt +0 -11
  146. package/android/src/main/java/expo/modules/core/interfaces/ReactNativeHostHandler.kt +0 -51
  147. package/ios/EXAppDelegateWrapper.h +0 -13
  148. package/ios/Swift/Methods/AnyArgumentType.swift +0 -48
  149. package/ios/Swift/Methods/AnyMethod.swift +0 -31
  150. package/ios/Swift/Methods/AnyMethodArgument.swift +0 -13
@@ -0,0 +1,135 @@
1
+ // Copyright 2018-present 650 Industries. All rights reserved.
2
+
3
+ #import <React/RCTUtils.h>
4
+
5
+ #import <ExpoModulesCore/JSIConversions.h>
6
+ #import <ExpoModulesCore/ExpoModulesProxySpec.h>
7
+
8
+ namespace expo {
9
+
10
+ using PromiseInvocationBlock = void (^)(RCTPromiseResolveBlock resolveWrapper, RCTPromiseRejectBlock rejectWrapper);
11
+
12
+ static void callPromiseSetupWithBlock(jsi::Runtime &runtime, std::shared_ptr<CallInvoker> jsInvoker, std::shared_ptr<Promise> promise, PromiseInvocationBlock setupBlock)
13
+ {
14
+ auto weakResolveWrapper = CallbackWrapper::createWeak(promise->resolve_.getFunction(runtime), runtime, jsInvoker);
15
+ auto weakRejectWrapper = CallbackWrapper::createWeak(promise->reject_.getFunction(runtime), runtime, jsInvoker);
16
+
17
+ __block BOOL resolveWasCalled = NO;
18
+ __block BOOL rejectWasCalled = NO;
19
+
20
+ RCTPromiseResolveBlock resolveBlock = ^(id result) {
21
+ if (rejectWasCalled) {
22
+ throw std::runtime_error("Tried to resolve a promise after it's already been rejected.");
23
+ }
24
+
25
+ if (resolveWasCalled) {
26
+ throw std::runtime_error("Tried to resolve a promise more than once.");
27
+ }
28
+
29
+ auto strongResolveWrapper = weakResolveWrapper.lock();
30
+ auto strongRejectWrapper = weakRejectWrapper.lock();
31
+ if (!strongResolveWrapper || !strongRejectWrapper) {
32
+ return;
33
+ }
34
+
35
+ strongResolveWrapper->jsInvoker().invokeAsync([weakResolveWrapper, weakRejectWrapper, result]() {
36
+ auto strongResolveWrapper2 = weakResolveWrapper.lock();
37
+ auto strongRejectWrapper2 = weakRejectWrapper.lock();
38
+ if (!strongResolveWrapper2 || !strongRejectWrapper2) {
39
+ return;
40
+ }
41
+
42
+ jsi::Runtime &rt = strongResolveWrapper2->runtime();
43
+ jsi::Value arg = convertObjCObjectToJSIValue(rt, result);
44
+ strongResolveWrapper2->callback().call(rt, arg);
45
+
46
+ strongResolveWrapper2->destroy();
47
+ strongRejectWrapper2->destroy();
48
+ });
49
+
50
+ resolveWasCalled = YES;
51
+ };
52
+
53
+ RCTPromiseRejectBlock rejectBlock = ^(NSString *code, NSString *message, NSError *error) {
54
+ if (resolveWasCalled) {
55
+ throw std::runtime_error("Tried to reject a promise after it's already been resolved.");
56
+ }
57
+
58
+ if (rejectWasCalled) {
59
+ throw std::runtime_error("Tried to reject a promise more than once.");
60
+ }
61
+
62
+ auto strongResolveWrapper = weakResolveWrapper.lock();
63
+ auto strongRejectWrapper = weakRejectWrapper.lock();
64
+ if (!strongResolveWrapper || !strongRejectWrapper) {
65
+ return;
66
+ }
67
+
68
+ NSDictionary *jsError = RCTJSErrorFromCodeMessageAndNSError(code, message, error);
69
+ strongRejectWrapper->jsInvoker().invokeAsync([weakResolveWrapper, weakRejectWrapper, jsError]() {
70
+ auto strongResolveWrapper2 = weakResolveWrapper.lock();
71
+ auto strongRejectWrapper2 = weakRejectWrapper.lock();
72
+ if (!strongResolveWrapper2 || !strongRejectWrapper2) {
73
+ return;
74
+ }
75
+
76
+ jsi::Runtime &rt = strongRejectWrapper2->runtime();
77
+ jsi::Value arg = convertNSDictionaryToJSIObject(rt, jsError);
78
+ strongRejectWrapper2->callback().call(rt, arg);
79
+
80
+ strongResolveWrapper2->destroy();
81
+ strongRejectWrapper2->destroy();
82
+ });
83
+
84
+ rejectWasCalled = YES;
85
+ };
86
+
87
+ setupBlock(resolveBlock, rejectBlock);
88
+ }
89
+
90
+ static jsi::Value __hostFunction_ExpoModulesProxySpec_callMethodAsync(jsi::Runtime &runtime, TurboModule &turboModule, const jsi::Value *args, size_t count)
91
+ {
92
+ auto expoModulesProxy = static_cast<ExpoModulesProxySpec *>(&turboModule);
93
+
94
+ // The function that is invoked as a setup of the JS `Promise`.
95
+ auto promiseSetupFunc = [expoModulesProxy, args](jsi::Runtime &runtime, std::shared_ptr<Promise> promise) {
96
+ callPromiseSetupWithBlock(runtime, expoModulesProxy->jsInvoker_, promise, ^(RCTPromiseResolveBlock resolver, RCTPromiseRejectBlock rejecter) {
97
+ NSString *moduleName = convertJSIStringToNSString(runtime, args[0].getString(runtime));
98
+ NSString *methodName = convertJSIStringToNSString(runtime, args[1].getString(runtime));
99
+ NSArray *arguments = convertJSIArrayToNSArray(runtime, args[2].getObject(runtime).asArray(runtime), expoModulesProxy->jsInvoker_);
100
+
101
+ [expoModulesProxy->nativeModulesProxy callMethod:moduleName
102
+ methodNameOrKey:methodName
103
+ arguments:arguments
104
+ resolver:resolver
105
+ rejecter:rejecter];
106
+ });
107
+ };
108
+
109
+ return createPromiseAsJSIValue(runtime, promiseSetupFunc);
110
+ }
111
+
112
+ static jsi::Value __hostFunction_ExpoModulesProxySpec_callMethodSync(jsi::Runtime &runtime, TurboModule &turboModule, const jsi::Value *args, size_t count)
113
+ {
114
+ auto expoModulesProxy = static_cast<ExpoModulesProxySpec *>(&turboModule);
115
+ NSString *moduleName = convertJSIStringToNSString(runtime, args[0].getString(runtime));
116
+ NSString *methodName = convertJSIStringToNSString(runtime, args[1].getString(runtime));
117
+ NSArray *arguments = convertJSIArrayToNSArray(runtime, args[2].getObject(runtime).asArray(runtime), expoModulesProxy->jsInvoker_);
118
+
119
+ id result = [expoModulesProxy->nativeModulesProxy callMethodSync:moduleName
120
+ methodName:methodName
121
+ arguments:arguments];
122
+
123
+ return convertObjCObjectToJSIValue(runtime, result);
124
+ }
125
+
126
+ ExpoModulesProxySpec::ExpoModulesProxySpec(std::shared_ptr<CallInvoker> callInvoker, EXNativeModulesProxy *nativeModulesProxy) :
127
+ TurboModule("ExpoModulesProxy", callInvoker),
128
+ nativeModulesProxy(nativeModulesProxy)
129
+ {
130
+ methodMap_["callMethodAsync"] = MethodMetadata {3, __hostFunction_ExpoModulesProxySpec_callMethodAsync};
131
+
132
+ methodMap_["callMethodSync"] = MethodMetadata {3, __hostFunction_ExpoModulesProxySpec_callMethodSync};
133
+ }
134
+
135
+ } // namespace expo
@@ -0,0 +1,42 @@
1
+ // Copyright 2018-present 650 Industries. All rights reserved.
2
+
3
+ #ifdef __cplusplus
4
+
5
+ #import <Foundation/Foundation.h>
6
+
7
+ #import <jsi/jsi.h>
8
+ #import <React/RCTBridgeModule.h>
9
+ #import <ReactCommon/CallInvoker.h>
10
+
11
+ using namespace facebook;
12
+ using namespace react;
13
+
14
+ namespace expo {
15
+
16
+ jsi::Value convertNSNumberToJSIBoolean(jsi::Runtime &runtime, NSNumber *value);
17
+
18
+ jsi::Value convertNSNumberToJSINumber(jsi::Runtime &runtime, NSNumber *value);
19
+
20
+ jsi::String convertNSStringToJSIString(jsi::Runtime &runtime, NSString *value);
21
+
22
+ jsi::Object convertNSDictionaryToJSIObject(jsi::Runtime &runtime, NSDictionary *value);
23
+
24
+ jsi::Array convertNSArrayToJSIArray(jsi::Runtime &runtime, NSArray *value);
25
+
26
+ std::vector<jsi::Value> convertNSArrayToStdVector(jsi::Runtime &runtime, NSArray *value);
27
+
28
+ jsi::Value convertObjCObjectToJSIValue(jsi::Runtime &runtime, id value);
29
+
30
+ NSString *convertJSIStringToNSString(jsi::Runtime &runtime, const jsi::String &value);
31
+
32
+ NSArray *convertJSIArrayToNSArray(jsi::Runtime &runtime, const jsi::Array &value, std::shared_ptr<CallInvoker> jsInvoker);
33
+
34
+ NSDictionary *convertJSIObjectToNSDictionary(jsi::Runtime &runtime, const jsi::Object &value, std::shared_ptr<CallInvoker> jsInvoker);
35
+
36
+ id convertJSIValueToObjCObject(jsi::Runtime &runtime, const jsi::Value &value, std::shared_ptr<CallInvoker> jsInvoker);
37
+
38
+ RCTResponseSenderBlock convertJSIFunctionToCallback(jsi::Runtime &runtime, const jsi::Function &value, std::shared_ptr<CallInvoker> jsInvoker);
39
+
40
+ } // namespace expo
41
+
42
+ #endif
@@ -0,0 +1,164 @@
1
+ // Copyright 2018-present 650 Industries. All rights reserved.
2
+
3
+ #import <ReactCommon/TurboModuleUtils.h>
4
+ #import <ExpoModulesCore/JSIConversions.h>
5
+
6
+ namespace expo {
7
+
8
+ /**
9
+ * All static helper functions are ObjC++ specific.
10
+ */
11
+ jsi::Value convertNSNumberToJSIBoolean(jsi::Runtime &runtime, NSNumber *value)
12
+ {
13
+ return jsi::Value((bool)[value boolValue]);
14
+ }
15
+
16
+ jsi::Value convertNSNumberToJSINumber(jsi::Runtime &runtime, NSNumber *value)
17
+ {
18
+ return jsi::Value([value doubleValue]);
19
+ }
20
+
21
+ jsi::String convertNSStringToJSIString(jsi::Runtime &runtime, NSString *value)
22
+ {
23
+ return jsi::String::createFromUtf8(runtime, [value UTF8String] ?: "");
24
+ }
25
+
26
+ jsi::Object convertNSDictionaryToJSIObject(jsi::Runtime &runtime, NSDictionary *value)
27
+ {
28
+ jsi::Object result = jsi::Object(runtime);
29
+ for (NSString *k in value) {
30
+ result.setProperty(runtime, [k UTF8String], convertObjCObjectToJSIValue(runtime, value[k]));
31
+ }
32
+ return result;
33
+ }
34
+
35
+ jsi::Array convertNSArrayToJSIArray(jsi::Runtime &runtime, NSArray *value)
36
+ {
37
+ jsi::Array result = jsi::Array(runtime, value.count);
38
+ for (size_t i = 0; i < value.count; i++) {
39
+ result.setValueAtIndex(runtime, i, convertObjCObjectToJSIValue(runtime, value[i]));
40
+ }
41
+ return result;
42
+ }
43
+
44
+ std::vector<jsi::Value> convertNSArrayToStdVector(jsi::Runtime &runtime, NSArray *value)
45
+ {
46
+ std::vector<jsi::Value> result;
47
+ for (size_t i = 0; i < value.count; i++) {
48
+ result.emplace_back(convertObjCObjectToJSIValue(runtime, value[i]));
49
+ }
50
+ return result;
51
+ }
52
+
53
+ jsi::Value convertObjCObjectToJSIValue(jsi::Runtime &runtime, id value)
54
+ {
55
+ if ([value isKindOfClass:[NSString class]]) {
56
+ return convertNSStringToJSIString(runtime, (NSString *)value);
57
+ } else if ([value isKindOfClass:[NSNumber class]]) {
58
+ if ([value isKindOfClass:[@YES class]]) {
59
+ return convertNSNumberToJSIBoolean(runtime, (NSNumber *)value);
60
+ }
61
+ return convertNSNumberToJSINumber(runtime, (NSNumber *)value);
62
+ } else if ([value isKindOfClass:[NSDictionary class]]) {
63
+ return convertNSDictionaryToJSIObject(runtime, (NSDictionary *)value);
64
+ } else if ([value isKindOfClass:[NSArray class]]) {
65
+ return convertNSArrayToJSIArray(runtime, (NSArray *)value);
66
+ } else if (value == (id)kCFNull) {
67
+ return jsi::Value::null();
68
+ }
69
+ return jsi::Value::undefined();
70
+ }
71
+
72
+ NSString *convertJSIStringToNSString(jsi::Runtime &runtime, const jsi::String &value)
73
+ {
74
+ return [NSString stringWithUTF8String:value.utf8(runtime).c_str()];
75
+ }
76
+
77
+ NSArray *convertJSIArrayToNSArray(jsi::Runtime &runtime, const jsi::Array &value, std::shared_ptr<CallInvoker> jsInvoker)
78
+ {
79
+ size_t size = value.size(runtime);
80
+ NSMutableArray *result = [NSMutableArray new];
81
+ for (size_t i = 0; i < size; i++) {
82
+ // Insert kCFNull when it's `undefined` value to preserve the indices.
83
+ [result
84
+ addObject:convertJSIValueToObjCObject(runtime, value.getValueAtIndex(runtime, i), jsInvoker) ?: (id)kCFNull];
85
+ }
86
+ return [result copy];
87
+ }
88
+
89
+ NSDictionary *convertJSIObjectToNSDictionary(jsi::Runtime &runtime, const jsi::Object &value, std::shared_ptr<CallInvoker> jsInvoker)
90
+ {
91
+ jsi::Array propertyNames = value.getPropertyNames(runtime);
92
+ size_t size = propertyNames.size(runtime);
93
+ NSMutableDictionary *result = [NSMutableDictionary new];
94
+ for (size_t i = 0; i < size; i++) {
95
+ jsi::String name = propertyNames.getValueAtIndex(runtime, i).getString(runtime);
96
+ NSString *k = convertJSIStringToNSString(runtime, name);
97
+ id v = convertJSIValueToObjCObject(runtime, value.getProperty(runtime, name), jsInvoker);
98
+ if (v) {
99
+ result[k] = v;
100
+ }
101
+ }
102
+ return [result copy];
103
+ }
104
+
105
+ id convertJSIValueToObjCObject(jsi::Runtime &runtime, const jsi::Value &value, std::shared_ptr<CallInvoker> jsInvoker)
106
+ {
107
+ if (value.isUndefined() || value.isNull()) {
108
+ return nil;
109
+ }
110
+ if (value.isBool()) {
111
+ return @(value.getBool());
112
+ }
113
+ if (value.isNumber()) {
114
+ return @(value.getNumber());
115
+ }
116
+ if (value.isString()) {
117
+ return convertJSIStringToNSString(runtime, value.getString(runtime));
118
+ }
119
+ if (value.isObject()) {
120
+ jsi::Object o = value.getObject(runtime);
121
+ if (o.isArray(runtime)) {
122
+ return convertJSIArrayToNSArray(runtime, o.getArray(runtime), jsInvoker);
123
+ }
124
+ if (o.isFunction(runtime)) {
125
+ return convertJSIFunctionToCallback(runtime, std::move(o.getFunction(runtime)), jsInvoker);
126
+ }
127
+ return convertJSIObjectToNSDictionary(runtime, o, jsInvoker);
128
+ }
129
+
130
+ throw std::runtime_error("Unsupported jsi::jsi::Value kind");
131
+ }
132
+
133
+ RCTResponseSenderBlock convertJSIFunctionToCallback(jsi::Runtime &runtime, const jsi::Function &value, std::shared_ptr<CallInvoker> jsInvoker)
134
+ {
135
+ auto weakWrapper = CallbackWrapper::createWeak(value.getFunction(runtime), runtime, jsInvoker);
136
+ BOOL __block wrapperWasCalled = NO;
137
+ RCTResponseSenderBlock callback = ^(NSArray *responses) {
138
+ if (wrapperWasCalled) {
139
+ throw std::runtime_error("callback arg cannot be called more than once");
140
+ }
141
+
142
+ auto strongWrapper = weakWrapper.lock();
143
+ if (!strongWrapper) {
144
+ return;
145
+ }
146
+
147
+ strongWrapper->jsInvoker().invokeAsync([weakWrapper, responses]() {
148
+ auto strongWrapper2 = weakWrapper.lock();
149
+ if (!strongWrapper2) {
150
+ return;
151
+ }
152
+
153
+ std::vector<jsi::Value> args = convertNSArrayToStdVector(strongWrapper2->runtime(), responses);
154
+ strongWrapper2->callback().call(strongWrapper2->runtime(), (const jsi::Value *)args.data(), args.size());
155
+ strongWrapper2->destroy();
156
+ });
157
+
158
+ wrapperWasCalled = YES;
159
+ };
160
+
161
+ return callback;
162
+ }
163
+
164
+ } // namespace expo
@@ -0,0 +1,19 @@
1
+ // Copyright 2018-present 650 Industries. All rights reserved.
2
+
3
+ #ifdef __cplusplus
4
+
5
+ #import <jsi/jsi.h>
6
+ #import <ReactCommon/RCTTurboModule.h>
7
+
8
+ #import <ExpoModulesCore/EXNativeModulesProxy.h>
9
+
10
+ using namespace facebook;
11
+ using namespace react;
12
+
13
+ namespace expo {
14
+
15
+ void installRuntimeObjects(jsi::Runtime &runtime, std::shared_ptr<CallInvoker> callInvoker, EXNativeModulesProxy *nativeModulesProxy);
16
+
17
+ } // namespace expo
18
+
19
+ #endif
@@ -0,0 +1,22 @@
1
+ // Copyright 2018-present 650 Industries. All rights reserved.
2
+
3
+ #import <ExpoModulesCore/JSIInstaller.h>
4
+ #import <ExpoModulesCore/ExpoModulesProxySpec.h>
5
+
6
+ using namespace facebook;
7
+ using namespace react;
8
+
9
+ //using PromiseInvocationBlock = void (^)(RCTPromiseResolveBlock resolveWrapper, RCTPromiseRejectBlock rejectWrapper);
10
+
11
+ namespace expo {
12
+
13
+ void installRuntimeObjects(jsi::Runtime &runtime, std::shared_ptr<CallInvoker> callInvoker, EXNativeModulesProxy *nativeModulesProxy)
14
+ {
15
+ auto expoModulesProxyModule = std::make_shared<ExpoModulesProxySpec>(callInvoker, nativeModulesProxy);
16
+
17
+ runtime
18
+ .global()
19
+ .setProperty(runtime, "ExpoModulesProxy", jsi::Object::createFromHostObject(runtime, expoModulesProxyModule));
20
+ }
21
+
22
+ } // namespace expo
@@ -7,12 +7,7 @@
7
7
  #import <ExpoModulesCore/EXViewManagerAdapterClassesRegistry.h>
8
8
  #import <ExpoModulesCore/EXModuleRegistryHolderReactModule.h>
9
9
  #import <ExpoModulesCore/EXReactNativeEventEmitter.h>
10
- #if __has_include(<ExpoModulesCore/ExpoModulesCore-Swift.h>)
11
- // For cocoapods framework, the generated swift header will be inside ExpoModulesCore module
12
- #import <ExpoModulesCore/ExpoModulesCore-Swift.h>
13
- #else
14
- #import "ExpoModulesCore-Swift.h"
15
- #endif
10
+ #import <ExpoModulesCore/Swift.h>
16
11
 
17
12
  @interface EXModuleRegistryAdapter ()
18
13
 
@@ -12,6 +12,7 @@
12
12
  // Swift compatibility headers (e.g. `ExpoModulesCore-Swift.h`) are not available in headers,
13
13
  // so we use class forward declaration here. Swift header must be imported in the `.m` file.
14
14
  @class SwiftInteropBridge;
15
+ @protocol ModulesProviderObjCProtocol;
15
16
 
16
17
  NS_SWIFT_NAME(NativeModulesProxy)
17
18
  @interface EXNativeModulesProxy : NSObject <RCTBridgeModule>
@@ -21,4 +22,9 @@ NS_SWIFT_NAME(NativeModulesProxy)
21
22
  - (nonnull instancetype)init;
22
23
  - (nonnull instancetype)initWithModuleRegistry:(nullable EXModuleRegistry *)moduleRegistry;
23
24
 
25
+ - (void)callMethod:(NSString *)moduleName methodNameOrKey:(id)methodNameOrKey arguments:(NSArray *)arguments resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject;
26
+ - (id)callMethodSync:(NSString *)moduleName methodName:(NSString *)methodName arguments:(NSArray *)arguments;
27
+
28
+ + (id<ModulesProviderObjCProtocol>)getExpoModulesProvider;
29
+
24
30
  @end
@@ -8,6 +8,8 @@
8
8
  #import <React/RCTModuleData.h>
9
9
  #import <React/RCTEventDispatcherProtocol.h>
10
10
 
11
+ #import <jsi/jsi.h>
12
+
11
13
  #import <ExpoModulesCore/EXNativeModulesProxy.h>
12
14
  #import <ExpoModulesCore/EXEventEmitter.h>
13
15
  #import <ExpoModulesCore/EXViewManager.h>
@@ -15,12 +17,8 @@
15
17
  #import <ExpoModulesCore/EXViewManagerAdapterClassesRegistry.h>
16
18
  #import <ExpoModulesCore/EXModuleRegistryProvider.h>
17
19
  #import <ExpoModulesCore/EXReactNativeEventEmitter.h>
18
- #if __has_include(<ExpoModulesCore/ExpoModulesCore-Swift.h>)
19
- // For cocoapods framework, the generated swift header will be inside ExpoModulesCore module
20
- #import <ExpoModulesCore/ExpoModulesCore-Swift.h>
21
- #else
22
- #import "ExpoModulesCore-Swift.h"
23
- #endif
20
+ #import <ExpoModulesCore/JSIInstaller.h>
21
+ #import <ExpoModulesCore/Swift.h>
24
22
 
25
23
  static const NSString *exportedMethodsNamesKeyPath = @"exportedMethods";
26
24
  static const NSString *viewManagersNamesKeyPath = @"viewManagersNames";
@@ -32,10 +30,17 @@ static const NSString *methodInfoArgumentsCountKey = @"argumentsCount";
32
30
 
33
31
  @interface RCTBridge (RegisterAdditionalModuleClasses)
34
32
 
33
+ - (NSArray<RCTModuleData *> *)registerModulesForClasses:(NSArray<Class> *)moduleClasses;
35
34
  - (void)registerAdditionalModuleClasses:(NSArray<Class> *)modules;
36
35
 
37
36
  @end
38
37
 
38
+ @interface RCTBridge (JSIRuntime)
39
+
40
+ - (void *)runtime;
41
+
42
+ @end
43
+
39
44
  @interface RCTComponentData (EXNativeModulesProxy)
40
45
 
41
46
  - (instancetype)initWithManagerClass:(Class)managerClass bridge:(RCTBridge *)bridge eventDispatcher:(id<RCTEventDispatcherProtocol>) eventDispatcher; // available in RN 0.65+
@@ -67,7 +72,7 @@ RCT_EXPORT_MODULE(NativeUnimoduleProxy)
67
72
  {
68
73
  if (self = [super init]) {
69
74
  _exModuleRegistry = moduleRegistry != nil ? moduleRegistry : [[EXModuleRegistryProvider new] moduleRegistry];
70
- _swiftInteropBridge = [[SwiftInteropBridge alloc] initWithModulesProvider:[self getExpoModulesProvider] legacyModuleRegistry:_exModuleRegistry];
75
+ _swiftInteropBridge = [[SwiftInteropBridge alloc] initWithModulesProvider:[EXNativeModulesProxy getExpoModulesProvider] legacyModuleRegistry:_exModuleRegistry];
71
76
  _exportedMethodsKeys = [NSMutableDictionary dictionary];
72
77
  _exportedMethodsReverseKeys = [NSMutableDictionary dictionary];
73
78
  _ownsModuleRegistry = moduleRegistry == nil;
@@ -92,6 +97,9 @@ RCT_EXPORT_MODULE(NativeUnimoduleProxy)
92
97
 
93
98
  - (NSDictionary *)constantsToExport
94
99
  {
100
+ // Install the TurboModule implementation of the proxy.
101
+ [self installExpoTurboModules];
102
+
95
103
  NSMutableDictionary <NSString *, id> *exportedModulesConstants = [NSMutableDictionary dictionary];
96
104
  // Grab all the constants exported by modules
97
105
  for (EXExportedModule *exportedModule in [_exModuleRegistry getAllExportedModules]) {
@@ -120,7 +128,7 @@ RCT_EXPORT_MODULE(NativeUnimoduleProxy)
120
128
  }
121
129
 
122
130
  // Add entries from Swift modules
123
- [exportedMethodsNamesAccumulator addEntriesFromDictionary:[_swiftInteropBridge exportedMethodNames]];
131
+ [exportedMethodsNamesAccumulator addEntriesFromDictionary:[_swiftInteropBridge exportedFunctionNames]];
124
132
 
125
133
  // Also, add `viewManagersNames` for sanity check and testing purposes -- with names we know what managers to mock on UIManager
126
134
  NSArray<EXViewManager *> *viewManagers = [_exModuleRegistry getAllViewManagers];
@@ -150,7 +158,7 @@ RCT_EXPORT_MODULE(NativeUnimoduleProxy)
150
158
  RCT_EXPORT_METHOD(callMethod:(NSString *)moduleName methodNameOrKey:(id)methodNameOrKey arguments:(NSArray *)arguments resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
151
159
  {
152
160
  if ([_swiftInteropBridge hasModule:moduleName]) {
153
- [_swiftInteropBridge callMethod:methodNameOrKey onModule:moduleName withArgs:arguments resolve:resolve reject:reject];
161
+ [_swiftInteropBridge callFunction:methodNameOrKey onModule:moduleName withArgs:arguments resolve:resolve reject:reject];
154
162
  return;
155
163
  }
156
164
  EXExportedModule *module = [_exModuleRegistry getExportedModuleForName:moduleName];
@@ -185,19 +193,44 @@ RCT_EXPORT_METHOD(callMethod:(NSString *)moduleName methodNameOrKey:(id)methodNa
185
193
  });
186
194
  }
187
195
 
188
- #pragma mark - Privates
196
+ - (id)callMethodSync:(NSString *)moduleName methodName:(NSString *)methodName arguments:(NSArray *)arguments
197
+ {
198
+ if ([_swiftInteropBridge hasModule:moduleName]) {
199
+ return [_swiftInteropBridge callFunctionSync:methodName onModule:moduleName withArgs:arguments];
200
+ }
201
+ return (id)kCFNull;
202
+ }
203
+
204
+ #pragma mark - Statics
189
205
 
190
- - (id<ModulesProviderObjCProtocol>)getExpoModulesProvider
206
+ + (id<ModulesProviderObjCProtocol>)getExpoModulesProvider
191
207
  {
192
- Class generatedExpoModulesProvider = NSClassFromString(@"ExpoModulesProvider");
193
- // Checks if `ExpoModulesProvider` was generated
194
- if (generatedExpoModulesProvider) {
208
+ // Dynamically gets the modules provider class.
209
+ // NOTE: This needs to be versioned in Expo Go.
210
+ Class generatedExpoModulesProvider;
211
+
212
+ // [0] When ExpoModulesCore is built as separated framework/module,
213
+ // we should explicitly load main bundle's `ExpoModulesProvider` class.
214
+ NSString *bundleName = NSBundle.mainBundle.infoDictionary[@"CFBundleName"];
215
+ if (bundleName != nil) {
216
+ generatedExpoModulesProvider = NSClassFromString([NSString stringWithFormat:@"%@.ExpoModulesProvider", bundleName]);
217
+ if (generatedExpoModulesProvider != nil) {
218
+ return [generatedExpoModulesProvider new];
219
+ }
220
+ }
221
+
222
+ // [1] Fallback to load `ExpoModulesProvider` class from the current module.
223
+ generatedExpoModulesProvider = NSClassFromString(@"ExpoModulesProvider");
224
+ if (generatedExpoModulesProvider != nil) {
195
225
  return [generatedExpoModulesProvider new];
196
- } else {
197
- return [ModulesProvider new];
198
226
  }
227
+
228
+ // [2] Fallback to load `ModulesProvider` if `ExpoModulesProvider` was not generated
229
+ return [ModulesProvider new];
199
230
  }
200
231
 
232
+ #pragma mark - Privates
233
+
201
234
  - (void)registerExpoModulesInBridge:(RCTBridge *)bridge
202
235
  {
203
236
  // Registering expo modules in bridge is needed only when the proxy module owns the registry
@@ -248,14 +281,16 @@ RCT_EXPORT_METHOD(callMethod:(NSString *)moduleName methodNameOrKey:(id)methodNa
248
281
  [bridge uiManager];
249
282
 
250
283
  // Register the view managers as additional modules.
251
- [bridge registerAdditionalModuleClasses:additionalModuleClasses];
284
+ [self registerAdditionalModuleClasses:additionalModuleClasses inBridge:bridge];
252
285
 
253
286
  // Bridge's `registerAdditionalModuleClasses:` method doesn't register
254
287
  // components in UIManager — we need to register them on our own.
255
288
  [self registerComponentDataForModuleClasses:additionalModuleClasses inBridge:bridge];
256
289
 
257
- // Get the newly created instance of `EXReactEventEmitter` bridge module and register it in expo modules registry.
290
+ // Get the newly created instance of `EXReactEventEmitter` bridge module,
291
+ // pass event names supported by Swift modules and register it in legacy modules registry.
258
292
  EXReactNativeEventEmitter *eventEmitter = [bridge moduleForClass:[EXReactNativeEventEmitter class]];
293
+ [eventEmitter setSwiftInteropBridge:_swiftInteropBridge];
259
294
  [_exModuleRegistry registerInternalModule:eventEmitter];
260
295
 
261
296
  // Let the modules consume the registry :)
@@ -263,6 +298,32 @@ RCT_EXPORT_METHOD(callMethod:(NSString *)moduleName methodNameOrKey:(id)methodNa
263
298
  [_exModuleRegistry initialize];
264
299
  }
265
300
 
301
+ - (void)registerAdditionalModuleClasses:(NSArray<Class> *)moduleClasses inBridge:(RCTBridge *)bridge
302
+ {
303
+ // In remote debugging mode, i.e. executorClass is `RCTWebSocketExecutor`,
304
+ // there is a deadlock issue in `registerAdditionalModuleClasses:` and causes app freezed.
305
+ // - The JS thread acquired the `RCTCxxBridge._moduleRegistryLock` lock in `RCTCxxBridge._initializeBridgeLocked`
306
+ // = it further goes into RCTObjcExecutor and tries to get module config from main thread
307
+ // - The main thread is pending in `RCTCxxBridge.registerAdditionalModuleClasses` where trying to acquire the same lock.
308
+ // To workaround the deadlock, we tend to use the non-locked registration and mutate the bridge internal module data.
309
+ // Since JS thread in this situation is waiting for main thread, it's safe to mutate module data without lock.
310
+ // The only risk should be the internal `_moduleRegistryCreated` flag without lock protection.
311
+ // As we just workaround in `RCTWebSocketExecutor` case, the risk of `_moduleRegistryCreated` race condition should be lower.
312
+ //
313
+ // Learn more about the non-locked initialization:
314
+ // https://github.com/facebook/react-native/blob/757bb75fbf837714725d7b2af62149e8e2a7ee51/React/CxxBridge/RCTCxxBridge.mm#L922-L935
315
+ // See the `_moduleRegistryCreated` false case
316
+ if ([NSStringFromClass([bridge executorClass]) isEqualToString:@"RCTWebSocketExecutor"]) {
317
+ NSNumber *moduleRegistryCreated = [bridge valueForKey:@"_moduleRegistryCreated"];
318
+ if (![moduleRegistryCreated boolValue]) {
319
+ [bridge registerModulesForClasses:moduleClasses];
320
+ return;
321
+ }
322
+ }
323
+
324
+ [bridge registerAdditionalModuleClasses:moduleClasses];
325
+ }
326
+
266
327
  - (void)registerComponentDataForModuleClasses:(NSArray<Class> *)moduleClasses inBridge:(RCTBridge *)bridge
267
328
  {
268
329
  // Hacky way to get a dictionary with `RCTComponentData` from UIManager.
@@ -318,4 +379,16 @@ RCT_EXPORT_METHOD(callMethod:(NSString *)moduleName methodNameOrKey:(id)methodNa
318
379
  }
319
380
  }
320
381
 
382
+ /**
383
+ Installs expo modules in JSI runtime.
384
+ */
385
+ - (void)installExpoTurboModules
386
+ {
387
+ facebook::jsi::Runtime *runtime = [_bridge respondsToSelector:@selector(runtime)] ? reinterpret_cast<facebook::jsi::Runtime *>(_bridge.runtime) : NULL;
388
+
389
+ if (runtime) {
390
+ expo::installRuntimeObjects(*runtime, _bridge.jsCallInvoker, self);
391
+ }
392
+ }
393
+
321
394
  @end
@@ -0,0 +1,16 @@
1
+ // Copyright 2018-present 650 Industries. All rights reserved.
2
+
3
+ #import <React/RCTBridgeDelegate.h>
4
+
5
+ NS_ASSUME_NONNULL_BEGIN
6
+
7
+ @interface EXRCTBridgeDelegateInterceptor : NSObject<RCTBridgeDelegate>
8
+
9
+ @property (nonatomic, weak) id<RCTBridgeDelegate> bridgeDelegate;
10
+ @property (nonatomic, weak) id<RCTBridgeDelegate> interceptor;
11
+
12
+ - (instancetype)initWithBridgeDelegate:(id<RCTBridgeDelegate>)bridgeDelegate interceptor:(id<RCTBridgeDelegate>)interceptor;
13
+
14
+ @end
15
+
16
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,49 @@
1
+ // Copyright 2018-present 650 Industries. All rights reserved.
2
+
3
+ #import <ExpoModulesCore/EXRCTBridgeDelegateInterceptor.h>
4
+
5
+ @implementation EXRCTBridgeDelegateInterceptor
6
+
7
+ - (instancetype)initWithBridgeDelegate:(id<RCTBridgeDelegate>)bridgeDelegate interceptor:(id<RCTBridgeDelegate>)interceptor
8
+ {
9
+ if (self = [super init]) {
10
+ self.bridgeDelegate = bridgeDelegate;
11
+ self.interceptor = interceptor;
12
+ }
13
+ return self;
14
+ }
15
+
16
+ - (BOOL)conformsToProtocol:(Protocol *)protocol
17
+ {
18
+ return [self.bridgeDelegate conformsToProtocol:protocol];
19
+ }
20
+
21
+ - (id)forwardingTargetForSelector:(SEL)selector
22
+ {
23
+ if ([self isInterceptedSelector:selector]) {
24
+ return self;
25
+ }
26
+ return self.bridgeDelegate;
27
+ }
28
+
29
+ - (BOOL)respondsToSelector:(SEL)selector
30
+ {
31
+ if ([self isInterceptedSelector:selector]) {
32
+ return YES;
33
+ }
34
+ return [self.bridgeDelegate respondsToSelector:selector];
35
+ }
36
+
37
+ - (BOOL)isInterceptedSelector:(SEL)selector
38
+ {
39
+ if ([self.interceptor respondsToSelector:selector]) {
40
+ return YES;
41
+ }
42
+ return NO;
43
+ }
44
+
45
+ - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge {
46
+ return [self.interceptor sourceURLForBridge:bridge];
47
+ }
48
+
49
+ @end