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.
- package/CHANGELOG.md +49 -0
- package/README.md +1 -1
- package/android/ExpoModulesCorePlugin.gradle +15 -0
- package/android/build.gradle +46 -32
- package/android/src/main/java/expo/modules/adapters/react/NativeModulesProxy.java +5 -5
- package/android/src/main/java/expo/modules/adapters/react/services/UIManagerModuleWrapper.java +13 -0
- package/android/src/main/java/expo/modules/core/ViewManager.java +9 -0
- package/android/src/main/java/expo/modules/core/interfaces/JavaScriptContextProvider.java +4 -0
- package/android/src/main/java/expo/modules/core/interfaces/ReactActivityHandler.java +37 -1
- package/android/src/main/java/expo/modules/core/interfaces/ReactNativeHostHandler.java +30 -0
- package/android/src/main/java/expo/modules/core/interfaces/services/UIManager.java +2 -0
- package/android/src/main/java/expo/modules/kotlin/AppContext.kt +13 -5
- package/android/src/main/java/expo/modules/kotlin/KPromiseWrapper.kt +2 -13
- package/android/src/main/java/expo/modules/kotlin/KotlinInteropModuleRegistry.kt +11 -5
- package/android/src/main/java/expo/modules/kotlin/ModuleHolder.kt +5 -1
- package/android/src/main/java/expo/modules/kotlin/ModuleRegistry.kt +17 -0
- package/android/src/main/java/expo/modules/kotlin/callbacks/ViewCallback.kt +14 -3
- package/android/src/main/java/expo/modules/kotlin/events/EventEmitter.kt +13 -0
- package/android/src/main/java/expo/modules/kotlin/events/KModuleEventEmitterWrapper.kt +102 -0
- package/android/src/main/java/expo/modules/kotlin/exception/CodedException.kt +25 -1
- package/android/src/main/java/expo/modules/kotlin/{methods/AnyMethod.kt → functions/AnyFunction.kt} +6 -5
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunction.kt +15 -0
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionBuilder.kt +170 -0
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromise.kt +15 -0
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncSuspendFunction.kt +36 -0
- package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +14 -0
- package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +374 -41
- package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionData.kt +2 -2
- package/android/src/main/java/expo/modules/kotlin/records/FieldValidator.kt +139 -0
- package/android/src/main/java/expo/modules/kotlin/records/Record.kt +0 -39
- package/android/src/main/java/expo/modules/kotlin/records/RecordTypeConverter.kt +59 -10
- package/android/src/main/java/expo/modules/kotlin/records/Required.kt +5 -0
- package/android/src/main/java/expo/modules/kotlin/records/ValidationBinder.kt +110 -0
- package/android/src/main/java/expo/modules/kotlin/records/Validators.kt +61 -0
- package/android/src/main/java/expo/modules/kotlin/types/JSTypeConverter.kt +35 -0
- package/android/src/main/java/expo/modules/kotlin/types/JSTypeConverterHelper.kt +148 -0
- package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +9 -1
- package/android/src/main/java/expo/modules/kotlin/views/GroupViewManagerWrapper.kt +49 -0
- package/android/src/main/java/expo/modules/kotlin/views/ViewGroupDefinition.kt +18 -0
- package/android/src/main/java/expo/modules/kotlin/views/ViewGroupDefinitionBuilder.kt +114 -0
- package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinition.kt +4 -1
- package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinitionBuilder.kt +56 -5
- package/android/src/main/java/expo/modules/kotlin/views/ViewManagerWrapperDelegate.kt +3 -0
- package/build/NativeModulesProxy.native.d.ts +0 -4
- package/build/NativeModulesProxy.native.d.ts.map +1 -1
- package/build/NativeModulesProxy.native.js +1 -14
- package/build/NativeModulesProxy.native.js.map +1 -1
- package/build/NativeModulesProxy.types.d.ts +0 -3
- package/build/NativeModulesProxy.types.d.ts.map +1 -1
- package/build/NativeModulesProxy.types.js.map +1 -1
- package/build/NativeViewManagerAdapter.native.d.ts.map +1 -1
- package/build/NativeViewManagerAdapter.native.js +9 -33
- package/build/NativeViewManagerAdapter.native.js.map +1 -1
- package/build/sweet/NativeErrorManager.js +1 -1
- package/build/sweet/NativeErrorManager.js.map +1 -1
- package/ios/AppDelegates/EXAppDelegatesLoader.m +4 -8
- package/ios/AppDelegates/ExpoAppDelegate.swift +4 -10
- package/ios/EXAppDefines.h +1 -0
- package/ios/EXAppDefines.m +6 -0
- package/ios/EXUtilities.h +2 -0
- package/ios/EXUtilities.m +12 -0
- package/ios/ExpoModulesCore.h +4 -0
- package/ios/ExpoModulesCore.podspec +4 -2
- package/ios/Interfaces/FileSystem/EXFileSystemInterface.h +1 -1
- package/ios/Interfaces/TaskManager/EXTaskServiceInterface.h +1 -0
- package/ios/JSI/{JSIConversions.h → EXJSIConversions.h} +4 -1
- package/ios/JSI/{JSIConversions.mm → EXJSIConversions.mm} +16 -5
- package/ios/JSI/{JSIInstaller.h → EXJSIInstaller.h} +3 -3
- package/ios/JSI/EXJSIInstaller.mm +17 -0
- package/ios/JSI/{ExpoModulesProxySpec.h → EXJSIUtils.h} +0 -9
- package/ios/JSI/{ExpoModulesProxySpec.mm → EXJSIUtils.mm} +4 -48
- package/ios/JSI/EXJavaScriptObject.h +97 -0
- package/ios/JSI/EXJavaScriptObject.mm +121 -0
- package/ios/JSI/{JavaScriptRuntime.h → EXJavaScriptRuntime.h} +27 -8
- package/ios/JSI/EXJavaScriptRuntime.mm +153 -0
- package/ios/JSI/EXJavaScriptValue.h +57 -0
- package/ios/JSI/EXJavaScriptValue.mm +166 -0
- package/ios/JSI/ExpoModulesHostObject.mm +2 -1
- package/ios/JSI/JavaScriptRuntime.swift +32 -0
- package/ios/JSI/JavaScriptValue.swift +94 -0
- package/ios/ModuleRegistryAdapter/EXModuleRegistryAdapter.m +1 -11
- package/ios/NativeModulesProxy/EXNativeModulesProxy.h +2 -2
- package/ios/NativeModulesProxy/EXNativeModulesProxy.mm +24 -22
- package/ios/ReactDelegates/EXReactCompatibleHelpers.h +18 -0
- package/ios/ReactDelegates/EXReactCompatibleHelpers.m +19 -0
- package/ios/ReactDelegates/ExpoReactDelegate.swift +2 -2
- package/ios/ReactDelegates/ExpoReactDelegateHandler.swift +1 -1
- package/ios/Swift/AppContext.swift +21 -2
- package/ios/Swift/Arguments/AnyArgumentType.swift +1 -1
- package/ios/Swift/Functions/AnyFunction.swift +5 -0
- package/ios/Swift/Functions/AsyncFunctionComponent.swift +182 -0
- package/ios/Swift/Functions/ConcreteFunction.swift +40 -68
- package/ios/Swift/Functions/SyncFunctionComponent.swift +181 -0
- package/ios/Swift/JavaScriptUtils.swift +56 -0
- package/ios/Swift/ModuleHolder.swift +17 -5
- package/ios/Swift/Modules/ModuleDefinitionComponents.swift +66 -44
- package/ios/Swift/ModulesProvider.swift +3 -10
- package/ios/Swift/Objects/ObjectDefinitionComponents.swift +49 -0
- package/ios/Swift/SwiftInteropBridge.swift +14 -5
- package/ios/Swift/Views/ComponentData.swift +2 -1
- package/ios/Swift/Views/ExpoView.swift +8 -0
- package/ios/Swift/Views/ViewManagerDefinitionComponents.swift +23 -0
- package/ios/Swift.h +5 -0
- package/ios/Tests/ArgumentTypeSpec.swift +2 -3
- package/ios/Tests/ConstantsSpec.swift +6 -7
- package/ios/Tests/ConvertiblesSpec.swift +2 -3
- package/ios/Tests/ExceptionsSpec.swift +2 -3
- package/ios/Tests/ExpoModulesSpec.swift +75 -0
- package/ios/Tests/FunctionSpec.swift +13 -15
- package/ios/Tests/FunctionWithConvertiblesSpec.swift +4 -5
- package/ios/Tests/JavaScriptObjectSpec.swift +97 -0
- package/ios/Tests/JavaScriptRuntimeSpec.swift +94 -0
- package/ios/Tests/ModuleEventListenersSpec.swift +15 -16
- package/ios/Tests/ModuleRegistrySpec.swift +2 -3
- package/ios/Tests/RecordSpec.swift +2 -3
- package/package.json +2 -2
- package/src/NativeModulesProxy.native.ts +2 -22
- package/src/NativeModulesProxy.types.ts +0 -8
- package/src/NativeViewManagerAdapter.native.tsx +12 -28
- package/src/sweet/NativeErrorManager.ts +1 -1
- package/android/src/main/java/expo/modules/kotlin/events/KEventEmitterWrapper.kt +0 -26
- package/android/src/main/java/expo/modules/kotlin/methods/Method.kt +0 -14
- package/android/src/main/java/expo/modules/kotlin/methods/PromiseMethod.kt +0 -15
- package/ios/JSI/JSIInstaller.mm +0 -34
- package/ios/JSI/JavaScriptObject.h +0 -60
- package/ios/JSI/JavaScriptObject.mm +0 -93
- package/ios/JSI/JavaScriptRuntime.mm +0 -102
- package/ios/NativeModulesProxy/EXComponentDataCompatibleWrapper.h +0 -16
- 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
|
-
|
|
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)
|
|
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
|
-
@
|
|
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
|
-
+ (
|
|
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/
|
|
20
|
+
#import <ExpoModulesCore/EXJSIInstaller.h>
|
|
22
21
|
#import <ExpoModulesCore/Swift.h>
|
|
23
22
|
|
|
24
23
|
static const NSString *exportedMethodsNamesKeyPath = @"exportedMethods";
|
|
25
|
-
static const NSString *
|
|
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
|
|
95
|
-
|
|
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 `
|
|
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
|
-
|
|
129
|
+
NSMutableDictionary<NSString *, NSDictionary *> *viewManagersMetadata = [[NSMutableDictionary alloc] initWithCapacity:[viewManagers count]];
|
|
130
|
+
|
|
130
131
|
for (EXViewManager *viewManager in viewManagers) {
|
|
131
|
-
[
|
|
132
|
+
viewManagersMetadata[viewManager.viewName] = @{
|
|
133
|
+
@"propsNames": [[viewManager getPropsNames] allKeys]
|
|
134
|
+
};
|
|
132
135
|
}
|
|
133
136
|
|
|
134
|
-
|
|
137
|
+
// Add entries from Swift view managers
|
|
138
|
+
[viewManagersMetadata addEntriesFromDictionary:[_swiftInteropBridge viewManagersMetadata]];
|
|
135
139
|
|
|
136
140
|
NSMutableDictionary <NSString *, id> *constantsAccumulator = [NSMutableDictionary dictionary];
|
|
137
|
-
constantsAccumulator[
|
|
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
|
-
+ (
|
|
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 = [[
|
|
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
|
|
406
|
+
Installs ExpoModules host object in the runtime that the current bridge operates on.
|
|
403
407
|
*/
|
|
404
|
-
- (void)
|
|
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
|
-
|
|
413
|
+
EXJavaScriptRuntime *runtime = [[EXJavaScriptRuntime alloc] initWithRuntime:jsiRuntime callInvoker:_bridge.jsCallInvoker];
|
|
410
414
|
|
|
411
|
-
[
|
|
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]?) ->
|
|
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 }) ??
|
|
28
|
+
.first(where: { _ in true }) ?? EXAppSetupDefaultRootView(bridge, moduleName, initialProperties)
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
@objc
|
|
@@ -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
|
|
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
|
-
|
|
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
|
*/
|