expo-modules-core 0.7.0 → 0.8.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.
- package/CHANGELOG.md +33 -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 +19 -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 +61 -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 +176 -27
- 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 +64 -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 +15 -2
- 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 +27 -1
- package/ios/Swift/Functions/AsyncFunction.swift +17 -0
- package/ios/Swift/Functions/ConcreteFunction.swift +6 -1
- package/ios/Swift/JavaScriptUtils.swift +11 -0
- package/ios/Swift/ModuleHolder.swift +14 -3
- package/ios/Swift/ModulesProvider.swift +3 -10
- package/ios/Swift/Objects/ObjectDefinitionComponents.swift +176 -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.h +5 -0
- package/ios/Tests/ArgumentTypeSpec.swift +2 -3
- package/ios/Tests/ConstantsSpec.swift +2 -3
- package/ios/Tests/ConvertiblesSpec.swift +2 -3
- package/ios/Tests/ExceptionsSpec.swift +2 -3
- package/ios/Tests/ExpoModulesSpec.swift +76 -0
- package/ios/Tests/FunctionSpec.swift +2 -3
- package/ios/Tests/FunctionWithConvertiblesSpec.swift +2 -3
- package/ios/Tests/JavaScriptObjectSpec.swift +97 -0
- package/ios/Tests/JavaScriptRuntimeSpec.swift +94 -0
- package/ios/Tests/ModuleEventListenersSpec.swift +2 -3
- 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,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
|
*/
|
|
@@ -97,6 +104,13 @@ public final class AppContext {
|
|
|
97
104
|
return legacyModule(implementing: EXEventEmitterService.self)
|
|
98
105
|
}
|
|
99
106
|
|
|
107
|
+
/**
|
|
108
|
+
Provides access to the logger from legacy module registry.
|
|
109
|
+
*/
|
|
110
|
+
public var logger: EXLogManager? {
|
|
111
|
+
return legacyModuleRegistry?.getSingletonModule(forName: EXLogManager.name()) as? EXLogManager
|
|
112
|
+
}
|
|
113
|
+
|
|
100
114
|
/**
|
|
101
115
|
Starts listening to `UIApplication` notifications.
|
|
102
116
|
*/
|
|
@@ -129,6 +143,12 @@ public final class AppContext {
|
|
|
129
143
|
|
|
130
144
|
// MARK: - Runtime
|
|
131
145
|
|
|
146
|
+
internal func installExpoModulesHostObject(_ interopBridge: SwiftInteropBridge) throws {
|
|
147
|
+
guard let runtime = runtime else {
|
|
148
|
+
throw UndefinedRuntimeException()
|
|
149
|
+
}
|
|
150
|
+
EXJavaScriptRuntimeManager.installExpoModules(to: runtime, withSwiftInterop: interopBridge)
|
|
151
|
+
}
|
|
132
152
|
/**
|
|
133
153
|
Unsets runtime objects that we hold for each module.
|
|
134
154
|
*/
|
|
@@ -152,7 +172,13 @@ public final class AppContext {
|
|
|
152
172
|
|
|
153
173
|
class DeallocatedAppContextException: Exception {
|
|
154
174
|
override var reason: String {
|
|
155
|
-
"The
|
|
175
|
+
"The AppContext has been deallocated"
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
class UndefinedRuntimeException: Exception {
|
|
180
|
+
override var reason: String {
|
|
181
|
+
"The AppContext has undefined runtime"
|
|
156
182
|
}
|
|
157
183
|
}
|
|
158
184
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Copyright 2022-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
Represents a function that can only be called asynchronously, thus its JavaScript equivalent returns a Promise.
|
|
5
|
+
|
|
6
|
+
- ToDo: Move some asynchronous logic from `ConcreteFunction` (like `call(args:promise:)`) to this class and drop the `isAsync` property.
|
|
7
|
+
*/
|
|
8
|
+
public final class AsyncFunction<Args, ReturnType>: ConcreteFunction<Args, ReturnType> {
|
|
9
|
+
override init(
|
|
10
|
+
_ name: String,
|
|
11
|
+
argTypes: [AnyArgumentType],
|
|
12
|
+
_ closure: @escaping ConcreteFunction<Args, ReturnType>.ClosureType
|
|
13
|
+
) {
|
|
14
|
+
super.init(name, argTypes: argTypes, closure)
|
|
15
|
+
self.isAsync = true
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import Dispatch
|
|
2
2
|
|
|
3
|
-
public
|
|
3
|
+
public class ConcreteFunction<Args, ReturnType>: AnyFunction {
|
|
4
4
|
public typealias ClosureType = (Args) throws -> ReturnType
|
|
5
5
|
|
|
6
6
|
public let name: String
|
|
@@ -29,6 +29,11 @@ public final class ConcreteFunction<Args, ReturnType>: AnyFunction {
|
|
|
29
29
|
self.name = name
|
|
30
30
|
self.argTypes = argTypes
|
|
31
31
|
self.closure = closure
|
|
32
|
+
|
|
33
|
+
// This is temporary solution to keep backwards compatibility for existing functions — they all end with "Async".
|
|
34
|
+
// `function` component that we've used so far was async by default, but we decided to replace it with `asyncFunction`
|
|
35
|
+
// and make `function`s synchronous. Introduced in SDK45, can be removed in SDK46 after migrating all modules.
|
|
36
|
+
self.isAsync = name.hasSuffix("Async")
|
|
32
37
|
}
|
|
33
38
|
|
|
34
39
|
public func call(args: [Any], promise: Promise) {
|
|
@@ -36,6 +36,17 @@ internal func createSyncFunctionBlock(holder: ModuleHolder, name functionName: S
|
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
/**
|
|
40
|
+
If given argument is a JavaScriptValue, it's unpacked and converted to corresponding Foundation type.
|
|
41
|
+
Otherwise, the argument is returned as is.
|
|
42
|
+
*/
|
|
43
|
+
internal func unpackIfJavaScriptValue(_ value: Any) -> Any {
|
|
44
|
+
if let value = value as? JavaScriptValue {
|
|
45
|
+
return value.getRaw() as Any
|
|
46
|
+
}
|
|
47
|
+
return value
|
|
48
|
+
}
|
|
49
|
+
|
|
39
50
|
private class ModuleUnavailableException: GenericException<String> {
|
|
40
51
|
override var reason: String {
|
|
41
52
|
"Module '\(param)' is no longer available"
|
|
@@ -70,8 +70,16 @@ public final class ModuleHolder {
|
|
|
70
70
|
}
|
|
71
71
|
let queue = function.queue ?? DispatchQueue.global(qos: .default)
|
|
72
72
|
|
|
73
|
+
// Given arguments can be:
|
|
74
|
+
// - Swift primitives when invoked through the bridge and in unit tests
|
|
75
|
+
// - `JavaScriptValue`s when the function is called through the JSI
|
|
76
|
+
// The latter need to be unpacked to Swift primitives on the JS thread,
|
|
77
|
+
// so before the function call is scheduled on the queue.
|
|
78
|
+
// TODO: Move arguments conversion mechanism to JS thread and allow JS types as function arguments.
|
|
79
|
+
let unpackedArgs = args.map { arg in unpackIfJavaScriptValue(arg) }
|
|
80
|
+
|
|
73
81
|
queue.async {
|
|
74
|
-
function.call(args:
|
|
82
|
+
function.call(args: unpackedArgs, promise: promise)
|
|
75
83
|
}
|
|
76
84
|
} catch let error as CodedError {
|
|
77
85
|
promise.reject(error)
|
|
@@ -92,7 +100,10 @@ public final class ModuleHolder {
|
|
|
92
100
|
@discardableResult
|
|
93
101
|
func callSync(function functionName: String, args: [Any]) -> Any? {
|
|
94
102
|
if let function = definition.functions[functionName] {
|
|
95
|
-
|
|
103
|
+
// The comment in `call(function:args:promise)` is partially applicable here as well.
|
|
104
|
+
// TODO: Move unpacking JS values to `callSync` in function's instance
|
|
105
|
+
let unpackedArgs = args.map { arg in unpackIfJavaScriptValue(arg) }
|
|
106
|
+
return function.callSync(args: unpackedArgs)
|
|
96
107
|
}
|
|
97
108
|
return nil
|
|
98
109
|
}
|
|
@@ -113,7 +124,7 @@ public final class ModuleHolder {
|
|
|
113
124
|
|
|
114
125
|
// Fill in with constants
|
|
115
126
|
for (key, value) in getConstants() {
|
|
116
|
-
object
|
|
127
|
+
object.setProperty(key, value: value)
|
|
117
128
|
}
|
|
118
129
|
|
|
119
130
|
// Fill in with functions
|
|
@@ -1,16 +1,9 @@
|
|
|
1
1
|
import Foundation
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
|
|
5
|
-
In Objective-C code we do not do anything with it except passing it back to the Swift light side.
|
|
4
|
+
Swift protocol defining the requirements for modules providers.
|
|
6
5
|
*/
|
|
7
|
-
|
|
8
|
-
public protocol ModulesProviderObjCProtocol {}
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
Swift protocol defining the requirements for modules providers. Extends its Objective-C counterpart `ModulesProviderObjCProtocol`.
|
|
12
|
-
*/
|
|
13
|
-
public protocol ModulesProviderProtocol: ModulesProviderObjCProtocol {
|
|
6
|
+
public protocol ModulesProviderProtocol {
|
|
14
7
|
func getModuleClasses() -> [AnyModule.Type]
|
|
15
8
|
|
|
16
9
|
/**
|
|
@@ -30,7 +23,7 @@ public protocol ModulesProviderProtocol: ModulesProviderObjCProtocol {
|
|
|
30
23
|
The proper implementation is generated by autolinking as part of `pod install` command.
|
|
31
24
|
*/
|
|
32
25
|
@objc
|
|
33
|
-
open class ModulesProvider: NSObject, ModulesProviderProtocol
|
|
26
|
+
open class ModulesProvider: NSObject, ModulesProviderProtocol {
|
|
34
27
|
open func getModuleClasses() -> [AnyModule.Type] {
|
|
35
28
|
return []
|
|
36
29
|
}
|