expo-modules-core 0.7.0 → 0.9.1

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 (129) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/README.md +1 -1
  3. package/android/ExpoModulesCorePlugin.gradle +15 -0
  4. package/android/build.gradle +46 -32
  5. package/android/src/main/java/expo/modules/adapters/react/NativeModulesProxy.java +5 -5
  6. package/android/src/main/java/expo/modules/adapters/react/services/UIManagerModuleWrapper.java +13 -0
  7. package/android/src/main/java/expo/modules/core/ViewManager.java +9 -0
  8. package/android/src/main/java/expo/modules/core/interfaces/JavaScriptContextProvider.java +4 -0
  9. package/android/src/main/java/expo/modules/core/interfaces/ReactActivityHandler.java +37 -1
  10. package/android/src/main/java/expo/modules/core/interfaces/ReactNativeHostHandler.java +30 -0
  11. package/android/src/main/java/expo/modules/core/interfaces/services/UIManager.java +2 -0
  12. package/android/src/main/java/expo/modules/kotlin/AppContext.kt +13 -5
  13. package/android/src/main/java/expo/modules/kotlin/KPromiseWrapper.kt +2 -13
  14. package/android/src/main/java/expo/modules/kotlin/KotlinInteropModuleRegistry.kt +11 -5
  15. package/android/src/main/java/expo/modules/kotlin/ModuleHolder.kt +5 -1
  16. package/android/src/main/java/expo/modules/kotlin/ModuleRegistry.kt +17 -0
  17. package/android/src/main/java/expo/modules/kotlin/callbacks/ViewCallback.kt +14 -3
  18. package/android/src/main/java/expo/modules/kotlin/events/EventEmitter.kt +13 -0
  19. package/android/src/main/java/expo/modules/kotlin/events/KModuleEventEmitterWrapper.kt +102 -0
  20. package/android/src/main/java/expo/modules/kotlin/exception/CodedException.kt +25 -1
  21. package/android/src/main/java/expo/modules/kotlin/{methods/AnyMethod.kt → functions/AnyFunction.kt} +6 -5
  22. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunction.kt +15 -0
  23. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionBuilder.kt +170 -0
  24. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromise.kt +15 -0
  25. package/android/src/main/java/expo/modules/kotlin/functions/AsyncSuspendFunction.kt +36 -0
  26. package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +14 -0
  27. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +374 -41
  28. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionData.kt +2 -2
  29. package/android/src/main/java/expo/modules/kotlin/records/FieldValidator.kt +139 -0
  30. package/android/src/main/java/expo/modules/kotlin/records/Record.kt +0 -39
  31. package/android/src/main/java/expo/modules/kotlin/records/RecordTypeConverter.kt +59 -10
  32. package/android/src/main/java/expo/modules/kotlin/records/Required.kt +5 -0
  33. package/android/src/main/java/expo/modules/kotlin/records/ValidationBinder.kt +110 -0
  34. package/android/src/main/java/expo/modules/kotlin/records/Validators.kt +61 -0
  35. package/android/src/main/java/expo/modules/kotlin/types/JSTypeConverter.kt +35 -0
  36. package/android/src/main/java/expo/modules/kotlin/types/JSTypeConverterHelper.kt +148 -0
  37. package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +9 -1
  38. package/android/src/main/java/expo/modules/kotlin/views/GroupViewManagerWrapper.kt +49 -0
  39. package/android/src/main/java/expo/modules/kotlin/views/ViewGroupDefinition.kt +18 -0
  40. package/android/src/main/java/expo/modules/kotlin/views/ViewGroupDefinitionBuilder.kt +114 -0
  41. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinition.kt +4 -1
  42. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinitionBuilder.kt +56 -5
  43. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerWrapperDelegate.kt +3 -0
  44. package/build/NativeModulesProxy.native.d.ts +0 -4
  45. package/build/NativeModulesProxy.native.d.ts.map +1 -1
  46. package/build/NativeModulesProxy.native.js +1 -14
  47. package/build/NativeModulesProxy.native.js.map +1 -1
  48. package/build/NativeModulesProxy.types.d.ts +0 -3
  49. package/build/NativeModulesProxy.types.d.ts.map +1 -1
  50. package/build/NativeModulesProxy.types.js.map +1 -1
  51. package/build/NativeViewManagerAdapter.native.d.ts.map +1 -1
  52. package/build/NativeViewManagerAdapter.native.js +9 -33
  53. package/build/NativeViewManagerAdapter.native.js.map +1 -1
  54. package/build/sweet/NativeErrorManager.js +1 -1
  55. package/build/sweet/NativeErrorManager.js.map +1 -1
  56. package/ios/AppDelegates/EXAppDelegatesLoader.m +4 -8
  57. package/ios/AppDelegates/ExpoAppDelegate.swift +4 -10
  58. package/ios/EXAppDefines.h +1 -0
  59. package/ios/EXAppDefines.m +6 -0
  60. package/ios/EXUtilities.h +2 -0
  61. package/ios/EXUtilities.m +12 -0
  62. package/ios/ExpoModulesCore.h +4 -0
  63. package/ios/ExpoModulesCore.podspec +4 -2
  64. package/ios/Interfaces/FileSystem/EXFileSystemInterface.h +1 -1
  65. package/ios/Interfaces/TaskManager/EXTaskServiceInterface.h +1 -0
  66. package/ios/JSI/{JSIConversions.h → EXJSIConversions.h} +4 -1
  67. package/ios/JSI/{JSIConversions.mm → EXJSIConversions.mm} +16 -5
  68. package/ios/JSI/{JSIInstaller.h → EXJSIInstaller.h} +3 -3
  69. package/ios/JSI/EXJSIInstaller.mm +17 -0
  70. package/ios/JSI/{ExpoModulesProxySpec.h → EXJSIUtils.h} +0 -9
  71. package/ios/JSI/{ExpoModulesProxySpec.mm → EXJSIUtils.mm} +4 -48
  72. package/ios/JSI/EXJavaScriptObject.h +97 -0
  73. package/ios/JSI/EXJavaScriptObject.mm +121 -0
  74. package/ios/JSI/{JavaScriptRuntime.h → EXJavaScriptRuntime.h} +27 -8
  75. package/ios/JSI/EXJavaScriptRuntime.mm +153 -0
  76. package/ios/JSI/EXJavaScriptValue.h +57 -0
  77. package/ios/JSI/EXJavaScriptValue.mm +166 -0
  78. package/ios/JSI/ExpoModulesHostObject.mm +2 -1
  79. package/ios/JSI/JavaScriptRuntime.swift +32 -0
  80. package/ios/JSI/JavaScriptValue.swift +94 -0
  81. package/ios/ModuleRegistryAdapter/EXModuleRegistryAdapter.m +1 -11
  82. package/ios/NativeModulesProxy/EXNativeModulesProxy.h +2 -2
  83. package/ios/NativeModulesProxy/EXNativeModulesProxy.mm +24 -22
  84. package/ios/ReactDelegates/EXReactCompatibleHelpers.h +18 -0
  85. package/ios/ReactDelegates/EXReactCompatibleHelpers.m +19 -0
  86. package/ios/ReactDelegates/ExpoReactDelegate.swift +2 -2
  87. package/ios/ReactDelegates/ExpoReactDelegateHandler.swift +1 -1
  88. package/ios/Swift/AppContext.swift +21 -2
  89. package/ios/Swift/Arguments/AnyArgumentType.swift +1 -1
  90. package/ios/Swift/Functions/AnyFunction.swift +5 -0
  91. package/ios/Swift/Functions/AsyncFunctionComponent.swift +182 -0
  92. package/ios/Swift/Functions/ConcreteFunction.swift +40 -68
  93. package/ios/Swift/Functions/SyncFunctionComponent.swift +181 -0
  94. package/ios/Swift/JavaScriptUtils.swift +56 -0
  95. package/ios/Swift/ModuleHolder.swift +17 -5
  96. package/ios/Swift/Modules/ModuleDefinitionComponents.swift +66 -44
  97. package/ios/Swift/ModulesProvider.swift +3 -10
  98. package/ios/Swift/Objects/ObjectDefinitionComponents.swift +49 -0
  99. package/ios/Swift/SwiftInteropBridge.swift +14 -5
  100. package/ios/Swift/Views/ComponentData.swift +2 -1
  101. package/ios/Swift/Views/ExpoView.swift +8 -0
  102. package/ios/Swift/Views/ViewManagerDefinitionComponents.swift +23 -0
  103. package/ios/Swift.h +5 -0
  104. package/ios/Tests/ArgumentTypeSpec.swift +2 -3
  105. package/ios/Tests/ConstantsSpec.swift +6 -7
  106. package/ios/Tests/ConvertiblesSpec.swift +2 -3
  107. package/ios/Tests/ExceptionsSpec.swift +2 -3
  108. package/ios/Tests/ExpoModulesSpec.swift +75 -0
  109. package/ios/Tests/FunctionSpec.swift +13 -15
  110. package/ios/Tests/FunctionWithConvertiblesSpec.swift +4 -5
  111. package/ios/Tests/JavaScriptObjectSpec.swift +97 -0
  112. package/ios/Tests/JavaScriptRuntimeSpec.swift +94 -0
  113. package/ios/Tests/ModuleEventListenersSpec.swift +15 -16
  114. package/ios/Tests/ModuleRegistrySpec.swift +2 -3
  115. package/ios/Tests/RecordSpec.swift +2 -3
  116. package/package.json +2 -2
  117. package/src/NativeModulesProxy.native.ts +2 -22
  118. package/src/NativeModulesProxy.types.ts +0 -8
  119. package/src/NativeViewManagerAdapter.native.tsx +12 -28
  120. package/src/sweet/NativeErrorManager.ts +1 -1
  121. package/android/src/main/java/expo/modules/kotlin/events/KEventEmitterWrapper.kt +0 -26
  122. package/android/src/main/java/expo/modules/kotlin/methods/Method.kt +0 -14
  123. package/android/src/main/java/expo/modules/kotlin/methods/PromiseMethod.kt +0 -15
  124. package/ios/JSI/JSIInstaller.mm +0 -34
  125. package/ios/JSI/JavaScriptObject.h +0 -60
  126. package/ios/JSI/JavaScriptObject.mm +0 -93
  127. package/ios/JSI/JavaScriptRuntime.mm +0 -102
  128. package/ios/NativeModulesProxy/EXComponentDataCompatibleWrapper.h +0 -16
  129. package/ios/NativeModulesProxy/EXComponentDataCompatibleWrapper.m +0 -28
@@ -0,0 +1,57 @@
1
+ // Copyright 2022-present 650 Industries. All rights reserved.
2
+
3
+ #import <Foundation/Foundation.h>
4
+ #import <ExpoModulesCore/EXJavaScriptObject.h>
5
+
6
+ #ifdef __cplusplus
7
+ #import <jsi/jsi.h>
8
+ namespace jsi = facebook::jsi;
9
+ #endif // __cplusplus
10
+
11
+ @class EXJavaScriptRuntime;
12
+
13
+ /**
14
+ Represents any JavaScript value. Its purpose is to exposes `facebook::jsi::Value` API back to Swift.
15
+ */
16
+ NS_SWIFT_NAME(JavaScriptValue)
17
+ @interface EXJavaScriptValue : NSObject
18
+
19
+ #ifdef __cplusplus
20
+ - (nonnull instancetype)initWithRuntime:(nonnull EXJavaScriptRuntime *)runtime
21
+ value:(std::shared_ptr<jsi::Value>)value;
22
+
23
+ /**
24
+ \return the underlying `jsi::Value`.
25
+ */
26
+ - (nonnull jsi::Value *)get;
27
+ #endif // __cplusplus
28
+
29
+ #pragma mark - Type checking
30
+
31
+ - (BOOL)isUndefined;
32
+ - (BOOL)isNull;
33
+ - (BOOL)isBool;
34
+ - (BOOL)isNumber;
35
+ - (BOOL)isString;
36
+ - (BOOL)isSymbol;
37
+ - (BOOL)isObject;
38
+ - (BOOL)isFunction;
39
+
40
+ + (nonnull NSString *)kindOf:(nonnull EXJavaScriptValue *)value;
41
+
42
+ #pragma mark - Type casting
43
+
44
+ - (nullable id)getRaw;
45
+ - (BOOL)getBool;
46
+ - (NSInteger)getInt;
47
+ - (double)getDouble;
48
+ - (nonnull NSString *)getString;
49
+ - (nonnull NSArray<EXJavaScriptValue *> *)getArray;
50
+ - (nonnull NSDictionary<NSString *, id> *)getDictionary;
51
+ - (nonnull EXJavaScriptObject *)getObject;
52
+
53
+ #pragma mark - Helpers
54
+
55
+ - (nonnull NSString *)toString;
56
+
57
+ @end
@@ -0,0 +1,166 @@
1
+ // Copyright 2022-present 650 Industries. All rights reserved.
2
+
3
+ #import <ExpoModulesCore/EXJSIConversions.h>
4
+ #import <ExpoModulesCore/EXJavaScriptValue.h>
5
+ #import <ExpoModulesCore/EXJavaScriptRuntime.h>
6
+
7
+ @implementation EXJavaScriptValue {
8
+ __weak EXJavaScriptRuntime *_runtime;
9
+ std::shared_ptr<jsi::Value> _value;
10
+ }
11
+
12
+ - (nonnull instancetype)initWithRuntime:(nonnull EXJavaScriptRuntime *)runtime
13
+ value:(std::shared_ptr<jsi::Value>)value
14
+ {
15
+ if (self = [super init]) {
16
+ _runtime = runtime;
17
+ _value = value;
18
+ }
19
+ return self;
20
+ }
21
+
22
+ - (nonnull jsi::Value *)get
23
+ {
24
+ return _value.get();
25
+ }
26
+
27
+ #pragma mark - Type checking
28
+
29
+ - (BOOL)isUndefined
30
+ {
31
+ return _value->isUndefined();
32
+ }
33
+
34
+ - (BOOL)isNull
35
+ {
36
+ return _value->isNull();
37
+ }
38
+
39
+ - (BOOL)isBool
40
+ {
41
+ return _value->isBool();
42
+ }
43
+
44
+ - (BOOL)isNumber
45
+ {
46
+ return _value->isNumber();
47
+ }
48
+
49
+ - (BOOL)isString
50
+ {
51
+ return _value->isString();
52
+ }
53
+
54
+ - (BOOL)isSymbol
55
+ {
56
+ return _value->isSymbol();
57
+ }
58
+
59
+ - (BOOL)isObject
60
+ {
61
+ return _value->isObject();
62
+ }
63
+
64
+ - (BOOL)isFunction
65
+ {
66
+ if (_value->isObject()) {
67
+ jsi::Runtime *runtime = [_runtime get];
68
+ return _value->getObject(*runtime).isFunction(*runtime);
69
+ }
70
+ return false;
71
+ }
72
+
73
+ + (nonnull NSString *)kindOf:(nonnull EXJavaScriptValue *)value
74
+ {
75
+ if ([value isUndefined]) {
76
+ return @"undefined";
77
+ }
78
+ if ([value isNull]) {
79
+ return @"null";
80
+ }
81
+ if ([value isBool]) {
82
+ return @"boolean";
83
+ }
84
+ if ([value isNumber]) {
85
+ return @"number";
86
+ }
87
+ if ([value isString]) {
88
+ return @"string";
89
+ }
90
+ if ([value isFunction]) {
91
+ return @"function";
92
+ }
93
+ assert([value isObject] && "Expecting object.");
94
+ return @"object";
95
+ }
96
+
97
+ #pragma mark - Type casting
98
+
99
+ - (nullable id)getRaw
100
+ {
101
+ return expo::convertJSIValueToObjCObject(*[_runtime get], *_value, [_runtime callInvoker]);
102
+ }
103
+
104
+ - (BOOL)getBool
105
+ {
106
+ return _value->getBool();
107
+ }
108
+
109
+ - (NSInteger)getInt
110
+ {
111
+ return _value->getNumber();
112
+ }
113
+
114
+ - (double)getDouble
115
+ {
116
+ return _value->getNumber();
117
+ }
118
+
119
+ - (nonnull NSString *)getString
120
+ {
121
+ jsi::Runtime *runtime = [_runtime get];
122
+ return expo::convertJSIStringToNSString(*runtime, _value->getString(*runtime));
123
+ }
124
+
125
+ - (nonnull NSArray<EXJavaScriptValue *> *)getArray
126
+ {
127
+ jsi::Runtime *runtime = [_runtime get];
128
+ jsi::Array jsiArray = _value->getObject(*runtime).getArray(*runtime);
129
+ size_t arraySize = jsiArray.size(*runtime);
130
+ NSMutableArray *result = [NSMutableArray arrayWithCapacity:arraySize];
131
+
132
+ for (size_t i = 0; i < arraySize; i++) {
133
+ jsi::Value item = jsiArray.getValueAtIndex(*runtime, i);
134
+
135
+ if (item.isUndefined() || item.isNull()) {
136
+ [result addObject:(id)kCFNull];
137
+ } else {
138
+ std::shared_ptr<jsi::Value> valuePtr = std::make_shared<jsi::Value>(*runtime, item);
139
+ [result addObject:[[EXJavaScriptValue alloc] initWithRuntime:_runtime value:valuePtr]];
140
+ }
141
+ }
142
+ return result;
143
+ }
144
+
145
+ - (nonnull NSDictionary<NSString *, id> *)getDictionary
146
+ {
147
+ jsi::Runtime *runtime = [_runtime get];
148
+ return expo::convertJSIObjectToNSDictionary(*runtime, _value->getObject(*runtime), [_runtime callInvoker]);
149
+ }
150
+
151
+ - (nonnull EXJavaScriptObject *)getObject
152
+ {
153
+ jsi::Runtime *runtime = [_runtime get];
154
+ std::shared_ptr<jsi::Object> objectPtr = std::make_shared<jsi::Object>(_value->asObject(*runtime));
155
+ return [[EXJavaScriptObject alloc] initWith:objectPtr runtime:_runtime];
156
+ }
157
+
158
+ #pragma mark - Helpers
159
+
160
+ - (nonnull NSString *)toString
161
+ {
162
+ jsi::Runtime *runtime = [_runtime get];
163
+ return expo::convertJSIStringToNSString(*runtime, _value->toString(*runtime));
164
+ }
165
+
166
+ @end
@@ -1,6 +1,7 @@
1
1
  // Copyright 2022-present 650 Industries. All rights reserved.
2
2
 
3
3
  #import <ExpoModulesCore/ExpoModulesHostObject.h>
4
+ #import <ExpoModulesCore/EXJavaScriptObject.h>
4
5
  #import <ExpoModulesCore/Swift.h>
5
6
 
6
7
  namespace expo {
@@ -13,7 +14,7 @@ ExpoModulesHostObject::~ExpoModulesHostObject() {
13
14
 
14
15
  jsi::Value ExpoModulesHostObject::get(jsi::Runtime &runtime, const jsi::PropNameID &name) {
15
16
  NSString *moduleName = [NSString stringWithUTF8String:name.utf8(runtime).c_str()];
16
- JavaScriptObject *nativeObject = [swiftInterop getNativeModuleObject:moduleName];
17
+ EXJavaScriptObject *nativeObject = [swiftInterop getNativeModuleObject:moduleName];
17
18
 
18
19
  return nativeObject ? jsi::Value(runtime, *[nativeObject get]) : jsi::Value::undefined();
19
20
  }
@@ -0,0 +1,32 @@
1
+ // Copyright 2022-present 650 Industries. All rights reserved.
2
+
3
+ public extension JavaScriptRuntime {
4
+ /**
5
+ Evaluates JavaScript code represented as a string.
6
+
7
+ - Parameter source: A string representing a JavaScript expression, statement, or sequence of statements.
8
+ The expression can include variables and properties of existing objects.
9
+ - Returns: The completion value of evaluating the given code represented as `JavaScriptValue`.
10
+ If the completion value is empty, `undefined` is returned.
11
+ - Throws: `JavaScriptEvalException` when evaluated code has invalid syntax or throws an error.
12
+ - Note: It wraps the original `evaluateScript` to better handle and rethrow exceptions.
13
+ */
14
+ func eval(_ source: String) throws -> JavaScriptValue {
15
+ do {
16
+ var result: JavaScriptValue?
17
+ try EXUtilities.catchException {
18
+ result = self.evaluateScript(source)
19
+ }
20
+ // There is no risk to force unwrapping as long as the `evaluateScript` returns nonnull value.
21
+ return result!
22
+ } catch {
23
+ throw JavaScriptEvalException(error as NSError)
24
+ }
25
+ }
26
+ }
27
+
28
+ internal final class JavaScriptEvalException: GenericException<NSError> {
29
+ override var reason: String {
30
+ return param.userInfo["message"] as? String ?? "unknown reason"
31
+ }
32
+ }
@@ -0,0 +1,94 @@
1
+ // Copyright 2022-present 650 Industries. All rights reserved.
2
+
3
+ /**
4
+ Enum with available kinds of values. It's almost the same as a result of "typeof"
5
+ in JavaScript, however `null` has its own kind (typeof null == "object").
6
+ */
7
+ public enum JavaScriptValueKind: String {
8
+ case undefined
9
+ case null
10
+ case bool
11
+ case number
12
+ case symbol
13
+ case string
14
+ case function
15
+ case object
16
+ }
17
+
18
+ public extension JavaScriptValue {
19
+ var kind: JavaScriptValueKind {
20
+ switch true {
21
+ case isUndefined():
22
+ return .undefined
23
+ case isNull():
24
+ return .null
25
+ case isBool():
26
+ return .bool
27
+ case isNumber():
28
+ return .number
29
+ case isSymbol():
30
+ return .symbol
31
+ case isString():
32
+ return .string
33
+ case isFunction():
34
+ return .function
35
+ default:
36
+ return .object
37
+ }
38
+ }
39
+
40
+ func asBool() throws -> Bool {
41
+ if isBool() {
42
+ return getBool()
43
+ }
44
+ throw JavaScriptValueConversionException((kind: kind, target: "Bool"))
45
+ }
46
+
47
+ func asInt() throws -> Int {
48
+ if isNumber() {
49
+ return getInt()
50
+ }
51
+ throw JavaScriptValueConversionException((kind: kind, target: "Int"))
52
+ }
53
+
54
+ func asDouble() throws -> Double {
55
+ if isNumber() {
56
+ return getDouble()
57
+ }
58
+ throw JavaScriptValueConversionException((kind: kind, target: "Double"))
59
+ }
60
+
61
+ func asString() throws -> String {
62
+ if isString() {
63
+ return getString()
64
+ }
65
+ throw JavaScriptValueConversionException((kind: kind, target: "String"))
66
+ }
67
+
68
+ func asArray() throws -> [JavaScriptValue?] {
69
+ if isObject() {
70
+ return getArray()
71
+ }
72
+ throw JavaScriptValueConversionException((kind: kind, target: "Array"))
73
+ }
74
+
75
+ func asDict() throws -> [String: Any] {
76
+ if isObject() {
77
+ return getDictionary()
78
+ }
79
+ throw JavaScriptValueConversionException((kind: kind, target: "Dict"))
80
+ }
81
+
82
+ func asObject() throws -> JavaScriptObject {
83
+ if isObject() {
84
+ return getObject()
85
+ }
86
+ throw JavaScriptValueConversionException((kind: kind, target: "Object"))
87
+ }
88
+ }
89
+
90
+ internal final class JavaScriptValueConversionException: GenericException<(kind: JavaScriptValueKind, target: String)> {
91
+ override var reason: String {
92
+ "Cannot represent a value of kind '\(param.kind)' as \(param.target)"
93
+ }
94
+ }
@@ -13,7 +13,7 @@
13
13
 
14
14
  @property (nonatomic, strong) EXModuleRegistryProvider *moduleRegistryProvider;
15
15
  @property (nonatomic, strong) EXViewManagerAdapterClassesRegistry *viewManagersClassesRegistry;
16
- @property (nonatomic, strong, nullable) id<ModulesProviderObjCProtocol> swiftModulesProvider;
16
+ @property (nonatomic, strong, nullable) ModulesProvider *swiftModulesProvider;
17
17
 
18
18
  @end
19
19
 
@@ -28,16 +28,6 @@
28
28
  return self;
29
29
  }
30
30
 
31
- - (instancetype)initWithModuleRegistryProvider:(EXModuleRegistryProvider *)moduleRegistryProvider swiftModulesProviderClass:(nullable Class)swiftModulesProviderClass
32
- {
33
- if (self = [self initWithModuleRegistryProvider:moduleRegistryProvider]) {
34
- if ([swiftModulesProviderClass conformsToProtocol:@protocol(ModulesProviderObjCProtocol)]) {
35
- _swiftModulesProvider = [swiftModulesProviderClass new];
36
- }
37
- }
38
- return self;
39
- }
40
-
41
31
  - (NSArray<id<RCTBridgeModule>> *)extraModulesForBridge:(RCTBridge *)bridge
42
32
  {
43
33
  return [self extraModulesForModuleRegistry:[_moduleRegistryProvider moduleRegistry]];
@@ -12,7 +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
+ @class ModulesProvider;
16
16
 
17
17
  NS_SWIFT_NAME(NativeModulesProxy)
18
18
  @interface EXNativeModulesProxy : NSObject <RCTBridgeModule>
@@ -25,6 +25,6 @@ NS_SWIFT_NAME(NativeModulesProxy)
25
25
  - (void)callMethod:(NSString *)moduleName methodNameOrKey:(id)methodNameOrKey arguments:(NSArray *)arguments resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject;
26
26
  - (id)callMethodSync:(NSString *)moduleName methodName:(NSString *)methodName arguments:(NSArray *)arguments;
27
27
 
28
- + (id<ModulesProviderObjCProtocol>)getExpoModulesProvider;
28
+ + (ModulesProvider *)getExpoModulesProvider;
29
29
 
30
30
  @end
@@ -10,7 +10,6 @@
10
10
 
11
11
  #import <jsi/jsi.h>
12
12
 
13
- #import <ExpoModulesCore/EXComponentDataCompatibleWrapper.h>
14
13
  #import <ExpoModulesCore/EXNativeModulesProxy.h>
15
14
  #import <ExpoModulesCore/EXEventEmitter.h>
16
15
  #import <ExpoModulesCore/EXViewManager.h>
@@ -18,11 +17,11 @@
18
17
  #import <ExpoModulesCore/EXViewManagerAdapterClassesRegistry.h>
19
18
  #import <ExpoModulesCore/EXModuleRegistryProvider.h>
20
19
  #import <ExpoModulesCore/EXReactNativeEventEmitter.h>
21
- #import <ExpoModulesCore/JSIInstaller.h>
20
+ #import <ExpoModulesCore/EXJSIInstaller.h>
22
21
  #import <ExpoModulesCore/Swift.h>
23
22
 
24
23
  static const NSString *exportedMethodsNamesKeyPath = @"exportedMethods";
25
- static const NSString *viewManagersNamesKeyPath = @"viewManagersNames";
24
+ static const NSString *viewManagersMetadataKeyPath = @"viewManagersMetadata";
26
25
  static const NSString *exportedConstantsKeyPath = @"modulesConstants";
27
26
 
28
27
  static const NSString *methodInfoKeyKey = @"key";
@@ -91,8 +90,9 @@ RCT_EXPORT_MODULE(NativeUnimoduleProxy)
91
90
 
92
91
  - (NSDictionary *)constantsToExport
93
92
  {
94
- // Install the TurboModule implementation of the proxy.
95
- [self installExpoTurboModules];
93
+ // Install ExpoModules host object in the runtime. It's probably not the right place,
94
+ // but it's the earliest moment in bridge's lifecycle when we have access to the runtime.
95
+ [self installExpoModulesHostObject];
96
96
 
97
97
  NSMutableDictionary <NSString *, id> *exportedModulesConstants = [NSMutableDictionary dictionary];
98
98
  // Grab all the constants exported by modules
@@ -124,17 +124,21 @@ RCT_EXPORT_MODULE(NativeUnimoduleProxy)
124
124
  // Add entries from Swift modules
125
125
  [exportedMethodsNamesAccumulator addEntriesFromDictionary:[_swiftInteropBridge exportedFunctionNames]];
126
126
 
127
- // Also, add `viewManagersNames` for sanity check and testing purposes -- with names we know what managers to mock on UIManager
127
+ // Also, add `viewManagersMetadata` for sanity check and testing purposes -- with names we know what managers to mock on UIManager
128
128
  NSArray<EXViewManager *> *viewManagers = [_exModuleRegistry getAllViewManagers];
129
- NSMutableArray<NSString *> *viewManagersNames = [NSMutableArray arrayWithCapacity:[viewManagers count]];
129
+ NSMutableDictionary<NSString *, NSDictionary *> *viewManagersMetadata = [[NSMutableDictionary alloc] initWithCapacity:[viewManagers count]];
130
+
130
131
  for (EXViewManager *viewManager in viewManagers) {
131
- [viewManagersNames addObject:[viewManager viewName]];
132
+ viewManagersMetadata[viewManager.viewName] = @{
133
+ @"propsNames": [[viewManager getPropsNames] allKeys]
134
+ };
132
135
  }
133
136
 
134
- [viewManagersNames addObjectsFromArray:[_swiftInteropBridge exportedViewManagersNames]];
137
+ // Add entries from Swift view managers
138
+ [viewManagersMetadata addEntriesFromDictionary:[_swiftInteropBridge viewManagersMetadata]];
135
139
 
136
140
  NSMutableDictionary <NSString *, id> *constantsAccumulator = [NSMutableDictionary dictionary];
137
- constantsAccumulator[viewManagersNamesKeyPath] = viewManagersNames;
141
+ constantsAccumulator[viewManagersMetadataKeyPath] = viewManagersMetadata;
138
142
  constantsAccumulator[exportedConstantsKeyPath] = exportedModulesConstants;
139
143
  constantsAccumulator[exportedMethodsNamesKeyPath] = exportedMethodsNamesAccumulator;
140
144
 
@@ -207,7 +211,7 @@ RCT_EXPORT_METHOD(callMethod:(NSString *)moduleName methodNameOrKey:(id)methodNa
207
211
 
208
212
  #pragma mark - Statics
209
213
 
210
- + (id<ModulesProviderObjCProtocol>)getExpoModulesProvider
214
+ + (ModulesProvider *)getExpoModulesProvider
211
215
  {
212
216
  // Dynamically gets the modules provider class.
213
217
  // NOTE: This needs to be versioned in Expo Go.
@@ -291,13 +295,13 @@ RCT_EXPORT_METHOD(callMethod:(NSString *)moduleName methodNameOrKey:(id)methodNa
291
295
  // Register the view managers as additional modules.
292
296
  [self registerAdditionalModuleClasses:additionalModuleClasses inBridge:bridge];
293
297
 
298
+ // Get the instance of `EXReactEventEmitter` bridge module and give it access to the interop bridge.
299
+ EXReactNativeEventEmitter *eventEmitter = [bridge moduleForClass:[EXReactNativeEventEmitter class]];
300
+ [eventEmitter setSwiftInteropBridge:_swiftInteropBridge];
301
+
294
302
  // As the last step, when the registry is owned,
295
303
  // register the event emitter and initialize the registry.
296
304
  if (ownsModuleRegistry) {
297
- // Get the newly created instance of `EXReactEventEmitter` bridge module,
298
- // pass event names supported by Swift modules and register it in legacy modules registry.
299
- EXReactNativeEventEmitter *eventEmitter = [bridge moduleForClass:[EXReactNativeEventEmitter class]];
300
- [eventEmitter setSwiftInteropBridge:_swiftInteropBridge];
301
305
  [_exModuleRegistry registerInternalModule:eventEmitter];
302
306
 
303
307
  // Let the modules consume the registry :)
@@ -362,7 +366,7 @@ RCT_EXPORT_METHOD(callMethod:(NSString *)moduleName methodNameOrKey:(id)methodNa
362
366
  NSString *className = NSStringFromClass(moduleClass);
363
367
 
364
368
  if ([moduleClass isSubclassOfClass:[RCTViewManager class]] && !componentDataByName[className]) {
365
- RCTComponentData *componentData = [[EXComponentDataCompatibleWrapper alloc] initWithManagerClass:moduleClass bridge:bridge eventDispatcher:bridge.eventDispatcher];
369
+ RCTComponentData *componentData = [[RCTComponentData alloc] initWithManagerClass:moduleClass bridge:bridge eventDispatcher:bridge.eventDispatcher];
366
370
  componentDataByName[className] = componentData;
367
371
  }
368
372
  }
@@ -399,19 +403,17 @@ RCT_EXPORT_METHOD(callMethod:(NSString *)moduleName methodNameOrKey:(id)methodNa
399
403
  }
400
404
 
401
405
  /**
402
- Installs expo modules in JSI runtime.
406
+ Installs ExpoModules host object in the runtime that the current bridge operates on.
403
407
  */
404
- - (void)installExpoTurboModules
408
+ - (void)installExpoModulesHostObject
405
409
  {
406
410
  facebook::jsi::Runtime *jsiRuntime = [_bridge respondsToSelector:@selector(runtime)] ? reinterpret_cast<facebook::jsi::Runtime *>(_bridge.runtime) : nullptr;
407
411
 
408
412
  if (jsiRuntime) {
409
- JavaScriptRuntime *runtime = [[JavaScriptRuntime alloc] initWithRuntime:*jsiRuntime callInvoker:_bridge.jsCallInvoker];
413
+ EXJavaScriptRuntime *runtime = [[EXJavaScriptRuntime alloc] initWithRuntime:jsiRuntime callInvoker:_bridge.jsCallInvoker];
410
414
 
411
- [JavaScriptRuntimeManager installExpoModulesToRuntime:runtime withSwiftInterop:_swiftInteropBridge];
415
+ [EXJavaScriptRuntimeManager installExpoModulesToRuntime:runtime withSwiftInterop:_swiftInteropBridge];
412
416
  [_swiftInteropBridge setRuntime:runtime];
413
-
414
- expo::installRuntimeObjects(*jsiRuntime, _bridge.jsCallInvoker, self);
415
417
  }
416
418
  }
417
419
 
@@ -0,0 +1,18 @@
1
+ // Copyright 2018-present 650 Industries. All rights reserved.
2
+
3
+ #import <UIKit/UIKit.h>
4
+
5
+ #import <ExpoModulesCore/EXDefines.h>
6
+ #import <React/RCTBridge.h>
7
+
8
+
9
+ EX_EXTERN_C_BEGIN
10
+
11
+ /**
12
+ * Backward compatible version of `RCTAppSetupDefaultRootView`.
13
+ *
14
+ * `RCTAppSetupDefaultRootView` is introduced in react-native 0.68. To make `expo-modules-core` compatible with older react-native, introduces this compatible helper.
15
+ */
16
+ UIView *EXAppSetupDefaultRootView(RCTBridge *bridge, NSString *moduleName, NSDictionary *initialProperties);
17
+
18
+ EX_EXTERN_C_END
@@ -0,0 +1,19 @@
1
+ // Copyright 2018-present 650 Industries. All rights reserved.
2
+
3
+ #import <ExpoModulesCore/EXReactCompatibleHelpers.h>
4
+
5
+ #import <React/RCTRootView.h>
6
+
7
+ #if __has_include(<React/RCTAppSetupUtils.h>)
8
+ #import <React/RCTAppSetupUtils.h>
9
+ #endif
10
+
11
+ UIView *EXAppSetupDefaultRootView(RCTBridge *bridge, NSString *moduleName, NSDictionary *initialProperties)
12
+ {
13
+ #if __has_include(<React/RCTAppSetupUtils.h>)
14
+ return RCTAppSetupDefaultRootView(bridge, moduleName, initialProperties);
15
+ #else
16
+ return [[RCTRootView alloc] initWithBridge:bridge moduleName:moduleName initialProperties:initialProperties];
17
+ #endif
18
+ }
19
+
@@ -22,10 +22,10 @@ public class ExpoReactDelegate: NSObject {
22
22
  }
23
23
 
24
24
  @objc
25
- public func createRootView(bridge: RCTBridge, moduleName: String, initialProperties: [AnyHashable: Any]?) -> RCTRootView {
25
+ public func createRootView(bridge: RCTBridge, moduleName: String, initialProperties: [AnyHashable: Any]?) -> UIView {
26
26
  return self.handlers.lazy
27
27
  .compactMap { $0.createRootView(reactDelegate: self, bridge: bridge, moduleName: moduleName, initialProperties: initialProperties) }
28
- .first(where: { _ in true }) ?? RCTRootView(bridge: bridge, moduleName: moduleName, initialProperties: initialProperties)
28
+ .first(where: { _ in true }) ?? EXAppSetupDefaultRootView(bridge, moduleName, initialProperties)
29
29
  }
30
30
 
31
31
  @objc
@@ -1,6 +1,6 @@
1
1
  // Copyright 2018-present 650 Industries. All rights reserved.
2
2
 
3
- import Foundation
3
+ import React
4
4
 
5
5
  /**
6
6
  The handler for `ExpoReactDelegate`. A module can implement a handler to process react instance creation.
@@ -3,6 +3,13 @@ import UIKit
3
3
  The app context is an interface to a single Expo app.
4
4
  */
5
5
  public final class AppContext {
6
+ internal static func create() -> AppContext {
7
+ let appContext = AppContext()
8
+
9
+ appContext.runtime = JavaScriptRuntime()
10
+ return appContext
11
+ }
12
+
6
13
  /**
7
14
  The module registry for the app context.
8
15
  */
@@ -11,7 +18,7 @@ public final class AppContext {
11
18
  /**
12
19
  The legacy module registry with modules written in the old-fashioned way.
13
20
  */
14
- public private(set) var legacyModuleRegistry: EXModuleRegistry?
21
+ public private(set) weak var legacyModuleRegistry: EXModuleRegistry?
15
22
 
16
23
  /**
17
24
  React bridge of the context's app.
@@ -129,6 +136,12 @@ public final class AppContext {
129
136
 
130
137
  // MARK: - Runtime
131
138
 
139
+ internal func installExpoModulesHostObject(_ interopBridge: SwiftInteropBridge) throws {
140
+ guard let runtime = runtime else {
141
+ throw UndefinedRuntimeException()
142
+ }
143
+ EXJavaScriptRuntimeManager.installExpoModules(to: runtime, withSwiftInterop: interopBridge)
144
+ }
132
145
  /**
133
146
  Unsets runtime objects that we hold for each module.
134
147
  */
@@ -152,7 +165,13 @@ public final class AppContext {
152
165
 
153
166
  class DeallocatedAppContextException: Exception {
154
167
  override var reason: String {
155
- "The app context has been deallocated"
168
+ "The AppContext has been deallocated"
169
+ }
170
+ }
171
+
172
+ class UndefinedRuntimeException: Exception {
173
+ override var reason: String {
174
+ "The AppContext has undefined runtime"
156
175
  }
157
176
  }
158
177
  }
@@ -4,7 +4,7 @@
4
4
  A protocol whose intention is to wrap function's argument type
5
5
  to keep its real signature and not type-erase it by the compiler.
6
6
  */
7
- internal protocol AnyArgumentType: CustomStringConvertible {
7
+ public protocol AnyArgumentType: CustomStringConvertible {
8
8
  /**
9
9
  Casts given any value to the wrapped type and returns as `Any`.
10
10
  NOTE: It may not be just simple type-casting (e.g. when the wrapped type conforms to `ConvertibleArgument`).
@@ -14,6 +14,11 @@ public protocol AnyFunction: AnyDefinition {
14
14
  */
15
15
  var takesPromise: Bool { get }
16
16
 
17
+ /**
18
+ An array of argument types that the function takes. If the last type is `Promise`, it's not included.
19
+ */
20
+ var argumentTypes: [AnyArgumentType] { get }
21
+
17
22
  /**
18
23
  A number of arguments the function takes. If the last argument is of type `Promise`, it is not counted.
19
24
  */