expo-modules-core 1.2.6 → 1.3.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 -4
- package/ExpoModulesCore.podspec +1 -0
- package/README.md +1 -1
- package/android/ExpoModulesCorePlugin.gradle +16 -0
- package/android/build.gradle +3 -2
- package/android/src/main/cpp/Exceptions.cpp +8 -0
- package/android/src/main/cpp/Exceptions.h +11 -0
- package/android/src/main/cpp/ExpoModulesHostObject.cpp +22 -5
- package/android/src/main/cpp/ExpoModulesHostObject.h +5 -0
- package/android/src/main/cpp/JNIInjector.cpp +2 -0
- package/android/src/main/cpp/JSIInteropModuleRegistry.cpp +25 -1
- package/android/src/main/cpp/JSIInteropModuleRegistry.h +14 -0
- package/android/src/main/cpp/JSIObjectWrapper.h +15 -4
- package/android/src/main/cpp/JSITypeConverter.h +3 -2
- package/android/src/main/cpp/JavaReferencesCache.cpp +2 -0
- package/android/src/main/cpp/JavaScriptFunction.cpp +56 -0
- package/android/src/main/cpp/JavaScriptFunction.h +54 -0
- package/android/src/main/cpp/JavaScriptModuleObject.cpp +225 -105
- package/android/src/main/cpp/JavaScriptModuleObject.h +67 -34
- package/android/src/main/cpp/JavaScriptObject.cpp +55 -1
- package/android/src/main/cpp/JavaScriptObject.h +17 -13
- package/android/src/main/cpp/JavaScriptRuntime.cpp +12 -3
- package/android/src/main/cpp/JavaScriptRuntime.h +9 -1
- package/android/src/main/cpp/JavaScriptValue.cpp +9 -0
- package/android/src/main/cpp/JavaScriptValue.h +4 -0
- package/android/src/main/cpp/MethodMetadata.cpp +66 -87
- package/android/src/main/cpp/MethodMetadata.h +18 -16
- package/android/src/main/cpp/ObjectDeallocator.h +25 -0
- package/android/src/main/cpp/WeakRuntimeHolder.cpp +7 -0
- package/android/src/main/cpp/WeakRuntimeHolder.h +4 -0
- package/android/src/main/cpp/types/CppType.h +4 -1
- package/android/src/main/cpp/types/FrontendConverter.cpp +58 -0
- package/android/src/main/cpp/types/FrontendConverter.h +45 -0
- package/android/src/main/cpp/types/FrontendConverterProvider.cpp +3 -0
- package/android/src/main/cpp/types/JNIToJSIConverter.cpp +88 -0
- package/android/src/main/cpp/types/JNIToJSIConverter.h +22 -0
- package/android/src/main/java/com/facebook/react/uimanager/ReactStylesDiffMapHelper.kt +10 -0
- package/android/src/main/java/expo/modules/kotlin/AppContext.kt +18 -25
- package/android/src/main/java/expo/modules/kotlin/FilteredIterator.kt +37 -0
- package/android/src/main/java/expo/modules/kotlin/KotlinInteropModuleRegistry.kt +1 -1
- package/android/src/main/java/expo/modules/kotlin/ModuleHolder.kt +34 -21
- package/android/src/main/java/expo/modules/kotlin/ModuleRegistry.kt +13 -3
- package/android/src/main/java/expo/modules/kotlin/Utils.kt +21 -0
- package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultCaller.kt +21 -1
- package/android/src/main/java/expo/modules/kotlin/classcomponent/ClassComponentBuilder.kt +112 -0
- package/android/src/main/java/expo/modules/kotlin/classcomponent/ClassDefinitionData.kt +10 -0
- package/android/src/main/java/expo/modules/kotlin/exception/CodedException.kt +21 -0
- package/android/src/main/java/expo/modules/kotlin/exception/CommonExceptions.kt +15 -0
- package/android/src/main/java/expo/modules/kotlin/functions/AnyFunction.kt +17 -4
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunction.kt +38 -8
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionComponent.kt +3 -2
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromiseComponent.kt +3 -2
- package/android/src/main/java/expo/modules/kotlin/functions/SuspendFunctionComponent.kt +1 -0
- package/android/src/main/java/expo/modules/kotlin/functions/SyncFunctionComponent.kt +18 -11
- package/android/src/main/java/expo/modules/kotlin/jni/CppType.kt +4 -1
- package/android/src/main/java/expo/modules/kotlin/jni/JNIDeallocator.kt +73 -0
- package/android/src/main/java/expo/modules/kotlin/jni/JSIInteropModuleRegistry.kt +28 -2
- package/android/src/main/java/expo/modules/kotlin/jni/JavaCallback.kt +8 -1
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptFunction.kt +48 -0
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptModuleObject.kt +40 -3
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptObject.kt +23 -3
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptValue.kt +26 -1
- package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +0 -11
- package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +26 -16
- package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionData.kt +3 -1
- package/android/src/main/java/expo/modules/kotlin/sharedobjects/SharedObject.kt +12 -0
- package/android/src/main/java/expo/modules/kotlin/sharedobjects/SharedObjectRegistry.kt +62 -0
- package/android/src/main/java/expo/modules/kotlin/sharedobjects/SharedObjectTypeConverter.kt +27 -0
- package/android/src/main/java/expo/modules/kotlin/types/AnyType.kt +2 -1
- package/android/src/main/java/expo/modules/kotlin/types/EitherTypeConverter.kt +7 -6
- package/android/src/main/java/expo/modules/kotlin/types/JavaScriptFunctionTypeConverter.kt +22 -0
- package/android/src/main/java/expo/modules/kotlin/types/TypeConverter.kt +30 -24
- package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +45 -1
- package/android/src/main/java/expo/modules/kotlin/types/TypedArrayTypeConverter.kt +3 -2
- package/android/src/main/java/expo/modules/kotlin/views/AnyViewProp.kt +3 -1
- package/android/src/main/java/expo/modules/kotlin/views/ConcreteViewProp.kt +3 -3
- package/android/src/main/java/expo/modules/kotlin/views/FilteredReadableMap.kt +53 -0
- package/android/src/main/java/expo/modules/kotlin/views/GroupViewManagerWrapper.kt +25 -5
- package/android/src/main/java/expo/modules/kotlin/views/SimpleViewManagerWrapper.kt +25 -5
- package/android/src/main/java/expo/modules/kotlin/views/ViewDefinitionBuilder.kt +161 -10
- package/android/src/main/java/expo/modules/kotlin/views/ViewGroupDefinitionBuilder.kt +0 -67
- package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinition.kt +7 -8
- package/android/src/main/java/expo/modules/kotlin/views/ViewManagerWrapperDelegate.kt +40 -3
- package/android/src/main/java/expo/modules/kotlin/views/ViewTypeConverter.kt +44 -0
- package/android-annotation/build.gradle +45 -0
- package/android-annotation/src/main/java/expo/modules/annotation/Config.kt +7 -0
- package/android-annotation/src/main/java/expo/modules/annotation/ConverterBinder.kt +7 -0
- package/android-annotation-processor/build.gradle +51 -0
- package/android-annotation-processor/src/main/java/expo/modules/annotationprocessor/ExpoSymbolProcessor.kt +175 -0
- package/android-annotation-processor/src/main/java/expo/modules/annotationprocessor/ExpoSymbolProcessorProvider.kt +10 -0
- package/android-annotation-processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider +1 -0
- package/build/NativeViewManagerAdapter.native.d.ts.map +1 -1
- package/build/NativeViewManagerAdapter.native.js +36 -23
- package/build/NativeViewManagerAdapter.native.js.map +1 -1
- package/build/requireNativeModule.js +2 -2
- package/build/requireNativeModule.js.map +1 -1
- package/common/cpp/fabric/ExpoViewProps.cpp +18 -3
- package/common/cpp/fabric/ExpoViewProps.h +4 -1
- package/ios/Fabric/ExpoFabricView.swift +10 -10
- package/ios/Fabric/ExpoFabricViewObjC.h +2 -0
- package/ios/Fabric/ExpoFabricViewObjC.mm +17 -2
- package/ios/JSI/EXJSIInstaller.mm +1 -1
- package/ios/JSI/EXJSIUtils.h +5 -0
- package/ios/JSI/EXJSIUtils.mm +17 -0
- package/ios/JSI/EXJavaScriptRuntime.h +5 -0
- package/ios/JSI/EXJavaScriptRuntime.mm +6 -0
- package/ios/JSI/EXJavaScriptValue.h +2 -0
- package/ios/JSI/EXJavaScriptValue.mm +8 -0
- package/ios/JSI/EXJavaScriptWeakObject.mm +29 -8
- package/ios/JSI/EXRawJavaScriptFunction.h +24 -0
- package/ios/JSI/EXRawJavaScriptFunction.mm +52 -0
- package/ios/JSI/ExpoModulesHostObject.mm +1 -1
- package/ios/JSI/JavaScriptValue.swift +28 -1
- package/ios/ModuleRegistry/EXModuleRegistry.h +0 -4
- package/ios/ModuleRegistry/EXModuleRegistry.m +0 -23
- package/ios/ModuleRegistryAdapter/EXModuleRegistryAdapter.m +0 -16
- package/ios/ModuleRegistryProvider/EXModuleRegistryProvider.m +0 -6
- package/ios/NativeModulesProxy/EXNativeModulesProxy.mm +1 -31
- package/ios/Swift/AppContext.swift +46 -6
- package/ios/Swift/Arguments/Convertible.swift +3 -3
- package/ios/Swift/Arguments/Convertibles.swift +5 -5
- package/ios/Swift/Classes/ClassComponent.swift +18 -12
- package/ios/Swift/Classes/ClassRegistry.swift +31 -0
- package/ios/Swift/Conversions.swift +19 -3
- package/ios/Swift/Convertibles/Convertibles+Color.swift +3 -3
- package/ios/Swift/Convertibles/Either.swift +6 -4
- package/ios/Swift/DynamicTypes/AnyDynamicType.swift +18 -2
- package/ios/Swift/DynamicTypes/DynamicArrayType.swift +3 -3
- package/ios/Swift/DynamicTypes/DynamicConvertibleType.swift +2 -2
- package/ios/Swift/DynamicTypes/DynamicEnumType.swift +1 -1
- package/ios/Swift/DynamicTypes/DynamicJavaScriptType.swift +27 -0
- package/ios/Swift/DynamicTypes/DynamicOptionalType.swift +9 -2
- package/ios/Swift/DynamicTypes/DynamicRawType.swift +1 -1
- package/ios/Swift/DynamicTypes/DynamicSharedObjectType.swift +16 -2
- package/ios/Swift/DynamicTypes/DynamicType.swift +6 -0
- package/ios/Swift/DynamicTypes/DynamicTypedArrayType.swift +15 -4
- package/ios/Swift/DynamicTypes/DynamicViewType.swift +68 -0
- package/ios/Swift/ExpoBridgeModule.swift +1 -1
- package/ios/Swift/Functions/AnyFunction.swift +5 -4
- package/ios/Swift/Functions/AsyncFunctionComponent.swift +22 -19
- package/ios/Swift/Functions/ConcurrentFunctionDefinition.swift +29 -13
- package/ios/Swift/Functions/SyncFunctionComponent.swift +26 -15
- package/ios/Swift/JavaScriptFunction.swift +68 -0
- package/ios/Swift/JavaScriptUtils.swift +57 -18
- package/ios/Swift/ModuleHolder.swift +22 -10
- package/ios/Swift/Modules/ModuleDefinition.swift +8 -2
- package/ios/Swift/Objects/JavaScriptObjectBuilder.swift +8 -8
- package/ios/Swift/Objects/ObjectDefinition.swift +17 -15
- package/ios/Swift/Objects/PropertyComponent.swift +23 -17
- package/ios/Swift/Records/AnyField.swift +1 -1
- package/ios/Swift/Records/Field.swift +2 -2
- package/ios/Swift/Records/Record.swift +5 -5
- package/ios/Swift/SharedObjects/SharedObjectRegistry.swift +4 -0
- package/ios/Swift/Views/AnyViewProp.swift +1 -1
- package/ios/Swift/Views/ComponentData.swift +37 -2
- package/ios/Swift/Views/ConcreteViewProp.swift +2 -2
- package/ios/Swift/Views/ViewDefinition.swift +39 -0
- package/ios/Swift/Views/ViewModuleWrapper.swift +0 -29
- package/ios/Tests/ClassComponentSpec.swift +39 -27
- package/ios/Tests/ConvertiblesSpec.swift +75 -49
- package/ios/Tests/DynamicTypeSpec.swift +29 -27
- package/ios/Tests/EitherSpec.swift +9 -7
- package/ios/Tests/ExpoModulesSpec.swift +13 -13
- package/ios/Tests/FunctionSpec.swift +38 -22
- package/ios/Tests/JavaScriptRuntimeSpec.swift +4 -0
- package/ios/Tests/PropertyComponentSpec.swift +33 -30
- package/ios/Tests/RecordSpec.swift +7 -5
- package/ios/Tests/SharedObjectRegistrySpec.swift +12 -12
- package/ios/Tests/TypedArraysSpec.swift +1 -1
- package/ios/Tests/ViewDefinitionSpec.swift +4 -2
- package/package.json +2 -2
- package/src/NativeViewManagerAdapter.native.tsx +33 -29
- package/src/requireNativeModule.ts +2 -2
- package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinitionBuilder.kt +0 -132
- package/ios/EXViewManager.h +0 -21
- package/ios/EXViewManager.m +0 -128
- package/ios/ModuleRegistryAdapter/EXViewManagerAdapterClassesRegistry.h +0 -17
- package/ios/ModuleRegistryAdapter/EXViewManagerAdapterClassesRegistry.m +0 -67
- package/ios/ViewManagerAdapter/EXViewManagerAdapter.h +0 -17
- package/ios/ViewManagerAdapter/EXViewManagerAdapter.m +0 -45
|
@@ -140,9 +140,18 @@ static std::unordered_map<std::string, ExpoViewComponentDescriptor::Flavor> _com
|
|
|
140
140
|
- (void)updateProps:(const facebook::react::Props::Shared &)props oldProps:(const facebook::react::Props::Shared &)oldProps
|
|
141
141
|
{
|
|
142
142
|
const auto &newViewProps = *std::static_pointer_cast<ExpoViewProps const>(props);
|
|
143
|
-
|
|
143
|
+
NSMutableDictionary<NSString *, id> *propsMap = [[NSMutableDictionary alloc] init];
|
|
144
144
|
|
|
145
|
-
|
|
145
|
+
for (const auto &item : newViewProps.propsMap) {
|
|
146
|
+
NSString *propName = [NSString stringWithUTF8String:item.first.c_str()];
|
|
147
|
+
|
|
148
|
+
// Ignore props inherited from the base view and Yoga.
|
|
149
|
+
if ([self supportsPropWithName:propName]) {
|
|
150
|
+
propsMap[propName] = convertFollyDynamicToId(item.second);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
[self updateProps:propsMap];
|
|
146
155
|
[super updateProps:props oldProps:oldProps];
|
|
147
156
|
[self viewDidUpdateProps];
|
|
148
157
|
}
|
|
@@ -174,6 +183,12 @@ static std::unordered_map<std::string, ExpoViewComponentDescriptor::Flavor> _com
|
|
|
174
183
|
// Implemented in `ExpoFabricView.swift`
|
|
175
184
|
}
|
|
176
185
|
|
|
186
|
+
- (BOOL)supportsPropWithName:(nonnull NSString *)name
|
|
187
|
+
{
|
|
188
|
+
// Implemented in `ExpoFabricView.swift`
|
|
189
|
+
return NO;
|
|
190
|
+
}
|
|
191
|
+
|
|
177
192
|
#pragma mark - Methods to override in the subclass
|
|
178
193
|
|
|
179
194
|
- (nullable EXAppContext *)__injectedAppContext
|
|
@@ -35,7 +35,7 @@ static NSString *modulesHostObjectLegacyPropertyName = @"ExpoModules";
|
|
|
35
35
|
|
|
36
36
|
+ (BOOL)installExpoModulesHostObject:(nonnull EXAppContext *)appContext
|
|
37
37
|
{
|
|
38
|
-
EXJavaScriptRuntime *runtime = [appContext
|
|
38
|
+
EXJavaScriptRuntime *runtime = [appContext _runtime];
|
|
39
39
|
|
|
40
40
|
// The runtime may be unavailable, e.g. remote debugger is enabled or it hasn't been set yet.
|
|
41
41
|
if (!runtime) {
|
package/ios/JSI/EXJSIUtils.h
CHANGED
|
@@ -26,6 +26,11 @@ using ClassConstructor = std::function<void(jsi::Runtime &runtime, const jsi::Va
|
|
|
26
26
|
|
|
27
27
|
std::shared_ptr<jsi::Function> createClass(jsi::Runtime &runtime, const char *name, ClassConstructor constructor);
|
|
28
28
|
|
|
29
|
+
/**
|
|
30
|
+
Creates a new object, using the provided object as the prototype.
|
|
31
|
+
*/
|
|
32
|
+
std::shared_ptr<jsi::Object> createObjectWithPrototype(jsi::Runtime &runtime, std::shared_ptr<jsi::Object> prototype);
|
|
33
|
+
|
|
29
34
|
#pragma mark - Weak objects
|
|
30
35
|
|
|
31
36
|
/**
|
package/ios/JSI/EXJSIUtils.mm
CHANGED
|
@@ -115,6 +115,23 @@ std::shared_ptr<jsi::Function> createClass(jsi::Runtime &runtime, const char *na
|
|
|
115
115
|
return std::make_shared<jsi::Function>(klass.asFunction(runtime));
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
+
std::shared_ptr<jsi::Object> createObjectWithPrototype(jsi::Runtime &runtime, std::shared_ptr<jsi::Object> prototype) {
|
|
119
|
+
// Get the "Object" class.
|
|
120
|
+
jsi::Object objectClass = runtime
|
|
121
|
+
.global()
|
|
122
|
+
.getPropertyAsObject(runtime, "Object");
|
|
123
|
+
|
|
124
|
+
// Call "Object.create(prototype)" to create an object with the given prototype without calling the constructor.
|
|
125
|
+
jsi::Object object = objectClass
|
|
126
|
+
.getPropertyAsFunction(runtime, "create")
|
|
127
|
+
.callWithThis(runtime, objectClass, {
|
|
128
|
+
jsi::Value(runtime, *prototype)
|
|
129
|
+
})
|
|
130
|
+
.asObject(runtime);
|
|
131
|
+
|
|
132
|
+
return std::make_shared<jsi::Object>(std::move(object));
|
|
133
|
+
}
|
|
134
|
+
|
|
118
135
|
#pragma mark - Weak objects
|
|
119
136
|
|
|
120
137
|
bool isWeakRefSupported(jsi::Runtime &runtime) {
|
|
@@ -103,6 +103,11 @@ typedef void (^ClassConstructorBlock)(EXJavaScriptObject * _Nonnull thisValue, N
|
|
|
103
103
|
- (nonnull EXJavaScriptObject *)createClass:(nonnull NSString *)name
|
|
104
104
|
constructor:(nonnull ClassConstructorBlock)constructor;
|
|
105
105
|
|
|
106
|
+
/**
|
|
107
|
+
Creates a new object, using the provided object as the prototype.
|
|
108
|
+
*/
|
|
109
|
+
- (nullable EXJavaScriptObject *)createObjectWithPrototype:(nonnull EXJavaScriptObject *)prototype;
|
|
110
|
+
|
|
106
111
|
#pragma mark - Script evaluation
|
|
107
112
|
|
|
108
113
|
/**
|
|
@@ -160,6 +160,12 @@ static NSString *mainObjectPropertyName = @"expo";
|
|
|
160
160
|
return [[EXJavaScriptObject alloc] initWith:klass runtime:self];
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
+
- (nullable EXJavaScriptObject *)createObjectWithPrototype:(nonnull EXJavaScriptObject *)prototype
|
|
164
|
+
{
|
|
165
|
+
std::shared_ptr<jsi::Object> object = expo::createObjectWithPrototype(*_runtime, [prototype getShared]);
|
|
166
|
+
return object ? [[EXJavaScriptObject alloc] initWith:object runtime:self] : nil;
|
|
167
|
+
}
|
|
168
|
+
|
|
163
169
|
#pragma mark - Script evaluation
|
|
164
170
|
|
|
165
171
|
- (nonnull EXJavaScriptValue *)evaluateScript:(nonnull NSString *)scriptSource
|
|
@@ -9,6 +9,7 @@ namespace jsi = facebook::jsi;
|
|
|
9
9
|
#endif // __cplusplus
|
|
10
10
|
|
|
11
11
|
@class EXJavaScriptRuntime;
|
|
12
|
+
@class EXRawJavaScriptFunction;
|
|
12
13
|
@class EXJavaScriptTypedArray;
|
|
13
14
|
|
|
14
15
|
/**
|
|
@@ -49,6 +50,7 @@ NS_SWIFT_NAME(JavaScriptValue)
|
|
|
49
50
|
- (nonnull NSArray<EXJavaScriptValue *> *)getArray;
|
|
50
51
|
- (nonnull NSDictionary<NSString *, id> *)getDictionary;
|
|
51
52
|
- (nonnull EXJavaScriptObject *)getObject;
|
|
53
|
+
- (nonnull EXRawJavaScriptFunction *)getFunction;
|
|
52
54
|
- (nullable EXJavaScriptTypedArray *)getTypedArray;
|
|
53
55
|
|
|
54
56
|
#pragma mark - Helpers
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
#import <ExpoModulesCore/EXJSIConversions.h>
|
|
4
4
|
#import <ExpoModulesCore/EXJavaScriptValue.h>
|
|
5
5
|
#import <ExpoModulesCore/EXJavaScriptRuntime.h>
|
|
6
|
+
#import <ExpoModulesCore/EXRawJavaScriptFunction.h>
|
|
6
7
|
#import <ExpoModulesCore/EXJavaScriptTypedArray.h>
|
|
7
8
|
#import <ExpoModulesCore/TypedArray.h>
|
|
8
9
|
|
|
@@ -142,6 +143,13 @@
|
|
|
142
143
|
return [[EXJavaScriptObject alloc] initWith:objectPtr runtime:_runtime];
|
|
143
144
|
}
|
|
144
145
|
|
|
146
|
+
- (nonnull EXRawJavaScriptFunction *)getFunction
|
|
147
|
+
{
|
|
148
|
+
jsi::Runtime *runtime = [_runtime get];
|
|
149
|
+
std::shared_ptr<jsi::Function> functionPtr = std::make_shared<jsi::Function>(_value->asObject(*runtime).asFunction(*runtime));
|
|
150
|
+
return [[EXRawJavaScriptFunction alloc] initWith:functionPtr runtime:_runtime];
|
|
151
|
+
}
|
|
152
|
+
|
|
145
153
|
- (nullable EXJavaScriptTypedArray *)getTypedArray
|
|
146
154
|
{
|
|
147
155
|
if (![self isTypedArray]) {
|
|
@@ -12,10 +12,17 @@
|
|
|
12
12
|
*/
|
|
13
13
|
__weak EXJavaScriptRuntime *_runtime;
|
|
14
14
|
|
|
15
|
+
#if __has_include(<reacthermes/HermesExecutorFactory.h>)
|
|
15
16
|
/**
|
|
16
|
-
|
|
17
|
+
A weak reference to a JS object. Available only on Hermes engine.
|
|
17
18
|
*/
|
|
18
|
-
std::shared_ptr<jsi::
|
|
19
|
+
std::shared_ptr<jsi::WeakObject> _weakObject;
|
|
20
|
+
#else
|
|
21
|
+
/**
|
|
22
|
+
Shared pointer to the `WeakRef` JS object. Available only on JSC engine.
|
|
23
|
+
*/
|
|
24
|
+
std::shared_ptr<jsi::Object> _weakObject;
|
|
25
|
+
#endif
|
|
19
26
|
}
|
|
20
27
|
|
|
21
28
|
- (nonnull instancetype)initWith:(std::shared_ptr<jsi::Object>)jsObject
|
|
@@ -24,15 +31,18 @@
|
|
|
24
31
|
if (self = [super init]) {
|
|
25
32
|
_runtime = runtime;
|
|
26
33
|
|
|
34
|
+
#if __has_include(<reacthermes/HermesExecutorFactory.h>)
|
|
35
|
+
_weakObject = std::make_shared<jsi::WeakObject>(*[runtime get], *jsObject);
|
|
36
|
+
#else
|
|
27
37
|
// Check whether the runtime supports `WeakRef` objects. If it does not,
|
|
28
38
|
// we consciously hold a strong reference to the object and cause memory leaks.
|
|
29
|
-
// This is the case on
|
|
30
|
-
// TODO: (@tsapeta) Use `jsi::WeakObject` on hermes
|
|
39
|
+
// This is the case on JSC prior to iOS 14.5.
|
|
31
40
|
if (expo::isWeakRefSupported(*[runtime get])) {
|
|
32
|
-
|
|
41
|
+
_weakObject = expo::createWeakRef(*[runtime get], jsObject);
|
|
33
42
|
} else {
|
|
34
|
-
|
|
43
|
+
_weakObject = jsObject;
|
|
35
44
|
}
|
|
45
|
+
#endif
|
|
36
46
|
}
|
|
37
47
|
return self;
|
|
38
48
|
}
|
|
@@ -40,9 +50,20 @@
|
|
|
40
50
|
- (nullable EXJavaScriptObject *)lock
|
|
41
51
|
{
|
|
42
52
|
jsi::Runtime *runtime = [_runtime get];
|
|
53
|
+
|
|
54
|
+
#if __has_include(<reacthermes/HermesExecutorFactory.h>)
|
|
55
|
+
jsi::Value value = _weakObject->lock(*runtime);
|
|
56
|
+
|
|
57
|
+
// `lock` returns an undefined value if the underlying object no longer exists.
|
|
58
|
+
if (value.isUndefined()) {
|
|
59
|
+
return nil;
|
|
60
|
+
}
|
|
61
|
+
std::shared_ptr<jsi::Object> objectPtr = std::make_shared<jsi::Object>(value.asObject(*runtime));
|
|
62
|
+
#else
|
|
43
63
|
std::shared_ptr<jsi::Object> objectPtr = expo::isWeakRefSupported(*runtime)
|
|
44
|
-
? expo::derefWeakRef(*runtime,
|
|
45
|
-
:
|
|
64
|
+
? expo::derefWeakRef(*runtime, _weakObject)
|
|
65
|
+
: _weakObject;
|
|
66
|
+
#endif
|
|
46
67
|
|
|
47
68
|
if (!objectPtr) {
|
|
48
69
|
return nil;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// Copyright 2023-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
#import <Foundation/Foundation.h>
|
|
4
|
+
#import <ExpoModulesCore/EXJavaScriptRuntime.h>
|
|
5
|
+
|
|
6
|
+
#ifdef __cplusplus
|
|
7
|
+
#import <jsi/jsi.h>
|
|
8
|
+
|
|
9
|
+
namespace jsi = facebook::jsi;
|
|
10
|
+
#endif // __cplusplus
|
|
11
|
+
|
|
12
|
+
NS_SWIFT_NAME(RawJavaScriptFunction)
|
|
13
|
+
@interface EXRawJavaScriptFunction : NSObject
|
|
14
|
+
|
|
15
|
+
#ifdef __cplusplus
|
|
16
|
+
- (nonnull instancetype)initWith:(std::shared_ptr<jsi::Function>)function
|
|
17
|
+
runtime:(nonnull EXJavaScriptRuntime *)runtime;
|
|
18
|
+
#endif // __cplusplus
|
|
19
|
+
|
|
20
|
+
- (nonnull EXJavaScriptValue *)callWithArguments:(nonnull NSArray<id> *)arguments
|
|
21
|
+
thisObject:(nullable EXJavaScriptObject *)thisObject
|
|
22
|
+
asConstructor:(BOOL)asConstructor;
|
|
23
|
+
|
|
24
|
+
@end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// Copyright 2023-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
#import <ExpoModulesCore/EXJSIConversions.h>
|
|
4
|
+
#import <ExpoModulesCore/EXRawJavaScriptFunction.h>
|
|
5
|
+
|
|
6
|
+
@implementation EXRawJavaScriptFunction {
|
|
7
|
+
/**
|
|
8
|
+
Pointer to the `EXJavaScriptRuntime` wrapper.
|
|
9
|
+
|
|
10
|
+
\note It must be weak because only then the original runtime can be safely deallocated
|
|
11
|
+
when the JS engine wants to without unsetting it on each created object.
|
|
12
|
+
*/
|
|
13
|
+
__weak EXJavaScriptRuntime *_runtime;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
Shared pointer to the underlying JSI function.
|
|
17
|
+
*/
|
|
18
|
+
std::shared_ptr<jsi::Function> _function;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
- (nonnull instancetype)initWith:(std::shared_ptr<jsi::Function>)function
|
|
22
|
+
runtime:(nonnull EXJavaScriptRuntime *)runtime
|
|
23
|
+
{
|
|
24
|
+
if (self = [super init]) {
|
|
25
|
+
_runtime = runtime;
|
|
26
|
+
_function = function;
|
|
27
|
+
}
|
|
28
|
+
return self;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
- (nonnull EXJavaScriptValue *)callWithArguments:(nonnull NSArray<id> *)arguments
|
|
32
|
+
thisObject:(nullable EXJavaScriptObject *)thisObject
|
|
33
|
+
asConstructor:(BOOL)asConstructor
|
|
34
|
+
{
|
|
35
|
+
jsi::Runtime *runtime = [_runtime get];
|
|
36
|
+
std::vector<jsi::Value> vector = expo::convertNSArrayToStdVector(*runtime, arguments);
|
|
37
|
+
const jsi::Value *data = vector.data();
|
|
38
|
+
jsi::Value result;
|
|
39
|
+
|
|
40
|
+
if (asConstructor) {
|
|
41
|
+
result = _function->callAsConstructor(*runtime, data, arguments.count);
|
|
42
|
+
} else if (thisObject) {
|
|
43
|
+
result = _function->callWithThis(*runtime, *[thisObject get], data, arguments.count);
|
|
44
|
+
} else {
|
|
45
|
+
result = _function->call(*runtime, data, arguments.count);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
std::shared_ptr<jsi::Value> resultPtr = std::make_shared<jsi::Value>(*runtime, result);
|
|
49
|
+
return [[EXJavaScriptValue alloc] initWithRuntime:_runtime value:resultPtr];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
@end
|
|
@@ -11,7 +11,7 @@ ExpoModulesHostObject::ExpoModulesHostObject(EXAppContext *appContext) : appCont
|
|
|
11
11
|
|
|
12
12
|
ExpoModulesHostObject::~ExpoModulesHostObject() {
|
|
13
13
|
modulesCache.clear();
|
|
14
|
-
|
|
14
|
+
appContext._runtime = nil;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
jsi::Value ExpoModulesHostObject::get(jsi::Runtime &runtime, const jsi::PropNameID &name) {
|
|
@@ -15,7 +15,17 @@ public enum JavaScriptValueKind: String {
|
|
|
15
15
|
case object
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
/**
|
|
19
|
+
A protocol that JavaScript values, objects and functions can conform to.
|
|
20
|
+
*/
|
|
21
|
+
protocol AnyJavaScriptValue {
|
|
22
|
+
/**
|
|
23
|
+
Tries to convert a raw JavaScript value to the conforming type.
|
|
24
|
+
*/
|
|
25
|
+
static func convert(from value: JavaScriptValue, appContext: AppContext) throws -> Self
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
extension JavaScriptValue: AnyJavaScriptValue {
|
|
19
29
|
var kind: JavaScriptValueKind {
|
|
20
30
|
switch true {
|
|
21
31
|
case isUndefined():
|
|
@@ -86,12 +96,29 @@ public extension JavaScriptValue {
|
|
|
86
96
|
throw JavaScriptValueConversionException((kind: kind, target: "Object"))
|
|
87
97
|
}
|
|
88
98
|
|
|
99
|
+
func asFunction() throws -> RawJavaScriptFunction {
|
|
100
|
+
if isFunction() {
|
|
101
|
+
return getFunction()
|
|
102
|
+
}
|
|
103
|
+
throw JavaScriptValueConversionException((kind: kind, target: "Function"))
|
|
104
|
+
}
|
|
105
|
+
|
|
89
106
|
func asTypedArray() throws -> JavaScriptTypedArray {
|
|
90
107
|
if let typedArray = getTypedArray() {
|
|
91
108
|
return typedArray
|
|
92
109
|
}
|
|
93
110
|
throw JavaScriptValueConversionException((kind: kind, target: "TypedArray"))
|
|
94
111
|
}
|
|
112
|
+
|
|
113
|
+
// MARK: - AnyJavaScriptValue
|
|
114
|
+
|
|
115
|
+
internal static func convert(from value: JavaScriptValue, appContext: AppContext) throws -> Self {
|
|
116
|
+
// It's already a `JavaScriptValue` so it should always pass through.
|
|
117
|
+
if let value = value as? Self {
|
|
118
|
+
return value
|
|
119
|
+
}
|
|
120
|
+
throw JavaScriptValueConversionException((kind: value.kind, target: String(describing: Self.self)))
|
|
121
|
+
}
|
|
95
122
|
}
|
|
96
123
|
|
|
97
124
|
internal final class JavaScriptValueConversionException: GenericException<(kind: JavaScriptValueKind, target: String)> {
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
|
|
5
5
|
#import <ExpoModulesCore/EXInternalModule.h>
|
|
6
6
|
#import <ExpoModulesCore/EXExportedModule.h>
|
|
7
|
-
#import <ExpoModulesCore/EXViewManager.h>
|
|
8
7
|
#import <ExpoModulesCore/EXModuleRegistryDelegate.h>
|
|
9
8
|
|
|
10
9
|
NS_ASSUME_NONNULL_BEGIN
|
|
@@ -13,12 +12,10 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
13
12
|
|
|
14
13
|
- (instancetype)initWithInternalModules:(NSSet<id<EXInternalModule>> *)internalModules
|
|
15
14
|
exportedModules:(NSSet<EXExportedModule *> *)exportedModules
|
|
16
|
-
viewManagers:(NSSet<EXViewManager *> *)viewManagers
|
|
17
15
|
singletonModules:(NSSet *)singletonModules;
|
|
18
16
|
|
|
19
17
|
- (void)registerInternalModule:(id<EXInternalModule>)internalModule;
|
|
20
18
|
- (void)registerExportedModule:(EXExportedModule *)exportedModule;
|
|
21
|
-
- (void)registerViewManager:(EXViewManager *)viewManager;
|
|
22
19
|
|
|
23
20
|
- (void)setDelegate:(id<EXModuleRegistryDelegate>)delegate;
|
|
24
21
|
|
|
@@ -32,7 +29,6 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
32
29
|
|
|
33
30
|
- (NSArray<id<EXInternalModule>> *)getAllInternalModules;
|
|
34
31
|
- (NSArray<EXExportedModule *> *)getAllExportedModules;
|
|
35
|
-
- (NSArray<EXViewManager *> *)getAllViewManagers;
|
|
36
32
|
- (NSArray *)getAllSingletonModules;
|
|
37
33
|
|
|
38
34
|
@end
|
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
@property NSMapTable<Protocol *, NSMutableArray<id<EXInternalModule>> *> *internalModulesPreResolution;
|
|
15
15
|
@property NSMapTable<Class, EXExportedModule *> *exportedModulesByClass;
|
|
16
16
|
@property NSMutableDictionary<const NSString *, EXExportedModule *> *exportedModules;
|
|
17
|
-
@property NSMutableDictionary<const NSString *, EXViewManager *> *viewManagerModules;
|
|
18
17
|
@property NSMutableDictionary<const NSString *, id> *singletonModules;
|
|
19
18
|
|
|
20
19
|
@property NSPointerArray *registryConsumers;
|
|
@@ -31,7 +30,6 @@
|
|
|
31
30
|
_internalModulesPreResolution = [NSMapTable weakToStrongObjectsMapTable];
|
|
32
31
|
_exportedModulesByClass = [NSMapTable weakToWeakObjectsMapTable];
|
|
33
32
|
_exportedModules = [NSMutableDictionary dictionary];
|
|
34
|
-
_viewManagerModules = [NSMutableDictionary dictionary];
|
|
35
33
|
_singletonModules = [NSMutableDictionary dictionary];
|
|
36
34
|
_registryConsumers = [NSPointerArray weakObjectsPointerArray];
|
|
37
35
|
}
|
|
@@ -40,7 +38,6 @@
|
|
|
40
38
|
|
|
41
39
|
- (instancetype)initWithInternalModules:(NSSet<id<EXInternalModule>> *)internalModules
|
|
42
40
|
exportedModules:(NSSet<EXExportedModule *> *)exportedModules
|
|
43
|
-
viewManagers:(NSSet<EXViewManager *> *)viewManagers
|
|
44
41
|
singletonModules:(NSSet *)singletonModules
|
|
45
42
|
{
|
|
46
43
|
if (self = [self init]) {
|
|
@@ -52,10 +49,6 @@
|
|
|
52
49
|
[self registerExportedModule:exportedModule];
|
|
53
50
|
}
|
|
54
51
|
|
|
55
|
-
for (EXViewManager *viewManager in viewManagers) {
|
|
56
|
-
[self registerViewManager:viewManager];
|
|
57
|
-
}
|
|
58
|
-
|
|
59
52
|
for (id singletonModule in singletonModules) {
|
|
60
53
|
[self registerSingletonModule:singletonModule];
|
|
61
54
|
}
|
|
@@ -140,17 +133,6 @@
|
|
|
140
133
|
[self maybeAddRegistryConsumer:exportedModule];
|
|
141
134
|
}
|
|
142
135
|
|
|
143
|
-
- (void)registerViewManager:(EXViewManager *)viewManager
|
|
144
|
-
{
|
|
145
|
-
const NSString *exportedModuleName = [[viewManager class] exportedModuleName];
|
|
146
|
-
if (_viewManagerModules[exportedModuleName]) {
|
|
147
|
-
EXLogInfo(@"View manager %@ overrides %@ as the module exported as %@.", viewManager, _viewManagerModules[exportedModuleName], exportedModuleName);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
_viewManagerModules[exportedModuleName] = viewManager;
|
|
151
|
-
[self maybeAddRegistryConsumer:viewManager];
|
|
152
|
-
}
|
|
153
|
-
|
|
154
136
|
- (void)registerSingletonModule:(id)singletonModule
|
|
155
137
|
{
|
|
156
138
|
if ([[singletonModule class] respondsToSelector:@selector(name)]) {
|
|
@@ -216,11 +198,6 @@
|
|
|
216
198
|
return [_exportedModules allValues];
|
|
217
199
|
}
|
|
218
200
|
|
|
219
|
-
- (NSArray<EXViewManager *> *)getAllViewManagers
|
|
220
|
-
{
|
|
221
|
-
return [_viewManagerModules allValues];
|
|
222
|
-
}
|
|
223
|
-
|
|
224
201
|
- (NSArray *)getAllSingletonModules
|
|
225
202
|
{
|
|
226
203
|
return [_singletonModules allValues];
|
|
@@ -1,17 +1,14 @@
|
|
|
1
1
|
// Copyright 2018-present 650 Industries. All rights reserved.
|
|
2
2
|
|
|
3
3
|
#import <ExpoModulesCore/EXNativeModulesProxy.h>
|
|
4
|
-
#import <ExpoModulesCore/EXViewManagerAdapter.h>
|
|
5
4
|
#import <ExpoModulesCore/EXModuleRegistryAdapter.h>
|
|
6
5
|
#import <ExpoModulesCore/EXModuleRegistryProvider.h>
|
|
7
|
-
#import <ExpoModulesCore/EXViewManagerAdapterClassesRegistry.h>
|
|
8
6
|
#import <ExpoModulesCore/EXModuleRegistryHolderReactModule.h>
|
|
9
7
|
#import <ExpoModulesCore/EXReactNativeEventEmitter.h>
|
|
10
8
|
|
|
11
9
|
@interface EXModuleRegistryAdapter ()
|
|
12
10
|
|
|
13
11
|
@property (nonatomic, strong) EXModuleRegistryProvider *moduleRegistryProvider;
|
|
14
|
-
@property (nonatomic, strong) EXViewManagerAdapterClassesRegistry *viewManagersClassesRegistry;
|
|
15
12
|
|
|
16
13
|
@end
|
|
17
14
|
|
|
@@ -21,7 +18,6 @@
|
|
|
21
18
|
{
|
|
22
19
|
if (self = [super init]) {
|
|
23
20
|
_moduleRegistryProvider = moduleRegistryProvider;
|
|
24
|
-
_viewManagersClassesRegistry = [[EXViewManagerAdapterClassesRegistry alloc] init];
|
|
25
21
|
}
|
|
26
22
|
return self;
|
|
27
23
|
}
|
|
@@ -43,18 +39,6 @@
|
|
|
43
39
|
EXReactNativeEventEmitter *eventEmitter = [EXReactNativeEventEmitter new];
|
|
44
40
|
[moduleRegistry registerInternalModule:eventEmitter];
|
|
45
41
|
|
|
46
|
-
for (EXViewManager *viewManager in [moduleRegistry getAllViewManagers]) {
|
|
47
|
-
Class viewManagerAdapterClass = [EXViewManagerAdapterClassesRegistry createViewManagerAdapterClassForViewManager:viewManager];
|
|
48
|
-
[extraModules addObject:[[viewManagerAdapterClass alloc] init]];
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// Silence React Native warning `Base module "%s" does not exist`
|
|
52
|
-
// occurring when view manager class is subclassing another class
|
|
53
|
-
// that is not RCTViewManager (in our case all the view manager adapters
|
|
54
|
-
// subclass EXViewManagerAdapter, so RN expects to find EXViewManagerAdapter
|
|
55
|
-
// exported.
|
|
56
|
-
[extraModules addObject:[[EXViewManagerAdapter alloc] init]];
|
|
57
|
-
|
|
58
42
|
// It is possible that among internal modules there are some RCTBridgeModules --
|
|
59
43
|
// let's add them to extraModules here.
|
|
60
44
|
for (id<EXInternalModule> module in [moduleRegistry getAllInternalModules]) {
|
|
@@ -110,7 +110,6 @@ void (^EXinitializeGlobalSingletonModulesSet)(void) = ^{
|
|
|
110
110
|
{
|
|
111
111
|
NSMutableSet<id<EXInternalModule>> *internalModules = [NSMutableSet set];
|
|
112
112
|
NSMutableSet<EXExportedModule *> *exportedModules = [NSMutableSet set];
|
|
113
|
-
NSMutableSet<EXViewManager *> *viewManagerModules = [NSMutableSet set];
|
|
114
113
|
|
|
115
114
|
for (Class klass in [self.class getModulesClasses]) {
|
|
116
115
|
if (![klass conformsToProtocol:@protocol(EXInternalModule)]) {
|
|
@@ -127,15 +126,10 @@ void (^EXinitializeGlobalSingletonModulesSet)(void) = ^{
|
|
|
127
126
|
if ([instance isKindOfClass:[EXExportedModule class]]) {
|
|
128
127
|
[exportedModules addObject:(EXExportedModule *)instance];
|
|
129
128
|
}
|
|
130
|
-
|
|
131
|
-
if ([instance isKindOfClass:[EXViewManager class]]) {
|
|
132
|
-
[viewManagerModules addObject:(EXViewManager *)instance];
|
|
133
|
-
}
|
|
134
129
|
}
|
|
135
130
|
|
|
136
131
|
EXModuleRegistry *moduleRegistry = [[EXModuleRegistry alloc] initWithInternalModules:internalModules
|
|
137
132
|
exportedModules:exportedModules
|
|
138
|
-
viewManagers:viewManagerModules
|
|
139
133
|
singletonModules:_singletonModules];
|
|
140
134
|
[moduleRegistry setDelegate:_moduleRegistryDelegate];
|
|
141
135
|
return moduleRegistry;
|
|
@@ -16,9 +16,6 @@
|
|
|
16
16
|
|
|
17
17
|
#import <ExpoModulesCore/EXNativeModulesProxy.h>
|
|
18
18
|
#import <ExpoModulesCore/EXEventEmitter.h>
|
|
19
|
-
#import <ExpoModulesCore/EXViewManager.h>
|
|
20
|
-
#import <ExpoModulesCore/EXViewManagerAdapter.h>
|
|
21
|
-
#import <ExpoModulesCore/EXViewManagerAdapterClassesRegistry.h>
|
|
22
19
|
#import <ExpoModulesCore/EXModuleRegistryProvider.h>
|
|
23
20
|
#import <ExpoModulesCore/EXReactNativeEventEmitter.h>
|
|
24
21
|
#import <ExpoModulesCore/EXJSIInstaller.h>
|
|
@@ -178,19 +175,9 @@ RCT_EXPORT_MODULE(NativeUnimoduleProxy)
|
|
|
178
175
|
[self assignExportedMethodsKeys:exportedMethodsNamesAccumulator[exportedModuleName] forModuleName:exportedModuleName];
|
|
179
176
|
}
|
|
180
177
|
|
|
181
|
-
// Also, add `viewManagersMetadata` for sanity check and testing purposes -- with names we know what managers to mock on UIManager
|
|
182
|
-
NSArray<EXViewManager *> *viewManagers = [_exModuleRegistry getAllViewManagers];
|
|
183
|
-
NSMutableDictionary<NSString *, NSDictionary *> *viewManagersMetadata = [[NSMutableDictionary alloc] initWithCapacity:[viewManagers count]];
|
|
184
|
-
|
|
185
|
-
for (EXViewManager *viewManager in viewManagers) {
|
|
186
|
-
viewManagersMetadata[viewManager.viewName] = @{
|
|
187
|
-
@"propsNames": [[viewManager getPropsNames] allKeys]
|
|
188
|
-
};
|
|
189
|
-
}
|
|
190
|
-
|
|
191
178
|
EXModulesProxyConfig *config = [[EXModulesProxyConfig alloc] initWithConstants:exportedModulesConstants
|
|
192
179
|
methodNames:exportedMethodsNamesAccumulator
|
|
193
|
-
viewManagers:
|
|
180
|
+
viewManagers:[NSMutableDictionary new]];
|
|
194
181
|
// decorate legacy config with sweet expo-modules config
|
|
195
182
|
[config addEntriesFromConfig:[_appContext expoModulesConfig]];
|
|
196
183
|
|
|
@@ -289,23 +276,6 @@ RCT_EXPORT_METHOD(callMethod:(NSString *)moduleName methodNameOrKey:(id)methodNa
|
|
|
289
276
|
|
|
290
277
|
// Add modules from legacy module registry only when the NativeModulesProxy owns the registry.
|
|
291
278
|
if (ownsModuleRegistry) {
|
|
292
|
-
// Add dynamic wrappers for the classic view managers.
|
|
293
|
-
for (EXViewManager *viewManager in [_exModuleRegistry getAllViewManagers]) {
|
|
294
|
-
if (![visitedSweetModules containsObject:viewManager.viewName]) {
|
|
295
|
-
Class viewManagerWrapperClass = [EXViewManagerAdapterClassesRegistry createViewManagerAdapterClassForViewManager:viewManager];
|
|
296
|
-
[additionalModuleClasses addObject:viewManagerWrapperClass];
|
|
297
|
-
[self registerLegacyComponentData:viewManagerWrapperClass inBridge:bridge];
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
// View manager wrappers don't have their own prop configs, so we must register
|
|
302
|
-
// their base view managers that provides common props such as `proxiedProperties`.
|
|
303
|
-
// Otherwise, React Native may treat these props as invalid in subclassing views.
|
|
304
|
-
[additionalModuleClasses addObject:[EXViewManagerAdapter class]];
|
|
305
|
-
// Also, we have to register component data for the View Adapter.
|
|
306
|
-
// Otherwise, it won't be recognized by the UIManager.
|
|
307
|
-
[self registerLegacyComponentData:[EXViewManagerAdapter class] inBridge:bridge];
|
|
308
|
-
|
|
309
279
|
// Some modules might need access to the bridge.
|
|
310
280
|
for (id module in [_exModuleRegistry getAllInternalModules]) {
|
|
311
281
|
if ([module conformsToProtocol:@protocol(RCTBridgeModule)]) {
|
|
@@ -8,7 +8,7 @@ public final class AppContext: NSObject {
|
|
|
8
8
|
internal static func create() -> AppContext {
|
|
9
9
|
let appContext = AppContext()
|
|
10
10
|
|
|
11
|
-
appContext.
|
|
11
|
+
appContext._runtime = JavaScriptRuntime()
|
|
12
12
|
return appContext
|
|
13
13
|
}
|
|
14
14
|
|
|
@@ -41,17 +41,17 @@ public final class AppContext: NSObject {
|
|
|
41
41
|
public internal(set) weak var reactBridge: RCTBridge?
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
|
-
JSI runtime of the running app.
|
|
44
|
+
Underlying JSI runtime of the running app.
|
|
45
45
|
*/
|
|
46
46
|
@objc
|
|
47
|
-
public var
|
|
47
|
+
public var _runtime: JavaScriptRuntime? {
|
|
48
48
|
didSet {
|
|
49
|
-
if
|
|
49
|
+
if _runtime == nil {
|
|
50
50
|
// When the runtime is unpinned from the context (e.g. deallocated),
|
|
51
51
|
// we should make sure to release all JS objects from the memory.
|
|
52
52
|
// Otherwise the JSCRuntime asserts may fail on deallocation.
|
|
53
53
|
releaseRuntimeObjects()
|
|
54
|
-
} else if
|
|
54
|
+
} else if _runtime != oldValue {
|
|
55
55
|
// Try to install ExpoModules host object automatically when the runtime changes.
|
|
56
56
|
// TODO: Should we uninstall in the old runtime? (@tsapeta)
|
|
57
57
|
try? installExpoModulesHostObject()
|
|
@@ -59,6 +59,18 @@ public final class AppContext: NSObject {
|
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
/**
|
|
63
|
+
JSI runtime of the running app.
|
|
64
|
+
*/
|
|
65
|
+
public var runtime: JavaScriptRuntime {
|
|
66
|
+
get throws {
|
|
67
|
+
if let runtime = _runtime {
|
|
68
|
+
return runtime
|
|
69
|
+
}
|
|
70
|
+
throw Exceptions.RuntimeLost()
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
62
74
|
/**
|
|
63
75
|
Designated initializer without modules provider.
|
|
64
76
|
*/
|
|
@@ -100,6 +112,29 @@ public final class AppContext: NSObject {
|
|
|
100
112
|
reactBridge?.dispatchBlock(runBlock, queue: RCTJSThread)
|
|
101
113
|
}
|
|
102
114
|
|
|
115
|
+
// MARK: - Classes
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
A registry containing references to JavaScript classes.
|
|
119
|
+
- ToDo: Make one registry per module, not the entire app context.
|
|
120
|
+
Perhaps it should be kept by the `ModuleHolder`.
|
|
121
|
+
*/
|
|
122
|
+
internal let classRegistry = ClassRegistry()
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
Creates a new JavaScript object with the class prototype associated with the given native class.
|
|
126
|
+
- ToDo: Move this to `ModuleHolder` along the `classRegistry` property.
|
|
127
|
+
*/
|
|
128
|
+
internal func newObject(nativeClassId: ObjectIdentifier) throws -> JavaScriptObject? {
|
|
129
|
+
guard let jsClass = classRegistry.getJavaScriptClass(nativeClassId: nativeClassId) else {
|
|
130
|
+
return nil
|
|
131
|
+
}
|
|
132
|
+
let prototype = try jsClass.getProperty("prototype").asObject()
|
|
133
|
+
let object = try runtime.createObject(withPrototype: prototype)
|
|
134
|
+
|
|
135
|
+
return object
|
|
136
|
+
}
|
|
137
|
+
|
|
103
138
|
// MARK: - Legacy modules
|
|
104
139
|
|
|
105
140
|
/**
|
|
@@ -308,7 +343,7 @@ public final class AppContext: NSObject {
|
|
|
308
343
|
// MARK: - Runtime
|
|
309
344
|
|
|
310
345
|
internal func installExpoModulesHostObject() throws {
|
|
311
|
-
guard
|
|
346
|
+
guard _runtime != nil else {
|
|
312
347
|
throw RuntimeLostException()
|
|
313
348
|
}
|
|
314
349
|
EXJavaScriptRuntimeManager.installExpoModulesHostObject(self)
|
|
@@ -318,6 +353,11 @@ public final class AppContext: NSObject {
|
|
|
318
353
|
Unsets runtime objects that we hold for each module.
|
|
319
354
|
*/
|
|
320
355
|
private func releaseRuntimeObjects() {
|
|
356
|
+
// FIXME: Release objects only from the current context.
|
|
357
|
+
// Making the registry non-global (similarly to the class registry) would fix it.
|
|
358
|
+
SharedObjectRegistry.clear()
|
|
359
|
+
classRegistry.clear()
|
|
360
|
+
|
|
321
361
|
for module in moduleRegistry {
|
|
322
362
|
module.javaScriptObject = nil
|
|
323
363
|
}
|