expo-modules-core 1.2.7 → 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 +28 -5
- 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 +8 -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 +30 -23
- package/android/src/main/java/expo/modules/kotlin/ModuleRegistry.kt +0 -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 -3
- 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 +6 -7
- 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
|
@@ -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
|
}
|
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
A protocol that allows custom classes or structs to be used as function arguments.
|
|
5
|
-
It requires static `convert(from:)` function that knows how to convert incoming
|
|
5
|
+
It requires static `convert(from:appContext:)` function that knows how to convert incoming
|
|
6
6
|
value of `Any` type to the type implemented by this protocol. It should throw an error
|
|
7
7
|
when the value is not recognized, is invalid or doesn't meet type requirements.
|
|
8
8
|
*/
|
|
9
9
|
public protocol Convertible: AnyArgument {
|
|
10
10
|
/**
|
|
11
|
-
Converts any value to the instance of its class (or struct).
|
|
11
|
+
Converts any value to the instance of its class (or struct) in the given app context.
|
|
12
12
|
Throws an error when given value cannot be converted.
|
|
13
13
|
*/
|
|
14
|
-
static func convert(from value: Any
|
|
14
|
+
static func convert(from value: Any?, appContext: AppContext) throws -> Self
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
@available(*, deprecated, renamed: "Convertible")
|
|
@@ -12,7 +12,7 @@ import CoreGraphics
|
|
|
12
12
|
// MARK: - Foundation
|
|
13
13
|
|
|
14
14
|
extension URL: Convertible {
|
|
15
|
-
public static func convert(from value: Any
|
|
15
|
+
public static func convert(from value: Any?, appContext: AppContext) throws -> Self {
|
|
16
16
|
guard let value = value as? String else {
|
|
17
17
|
throw Conversions.ConvertingException<URL>(value)
|
|
18
18
|
}
|
|
@@ -47,7 +47,7 @@ internal class UrlContainsInvalidCharactersException: Exception {
|
|
|
47
47
|
// MARK: - CoreGraphics
|
|
48
48
|
|
|
49
49
|
extension CGPoint: Convertible {
|
|
50
|
-
public static func convert(from value: Any
|
|
50
|
+
public static func convert(from value: Any?, appContext: AppContext) throws -> CGPoint {
|
|
51
51
|
if let value = value as? [Double], value.count == 2 {
|
|
52
52
|
return CGPoint(x: value[0], y: value[1])
|
|
53
53
|
}
|
|
@@ -60,7 +60,7 @@ extension CGPoint: Convertible {
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
extension CGSize: Convertible {
|
|
63
|
-
public static func convert(from value: Any
|
|
63
|
+
public static func convert(from value: Any?, appContext: AppContext) throws -> CGSize {
|
|
64
64
|
if let value = value as? [Double], value.count == 2 {
|
|
65
65
|
return CGSize(width: value[0], height: value[1])
|
|
66
66
|
}
|
|
@@ -73,7 +73,7 @@ extension CGSize: Convertible {
|
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
extension CGVector: Convertible {
|
|
76
|
-
public static func convert(from value: Any
|
|
76
|
+
public static func convert(from value: Any?, appContext: AppContext) throws -> CGVector {
|
|
77
77
|
if let value = value as? [Double], value.count == 2 {
|
|
78
78
|
return CGVector(dx: value[0], dy: value[1])
|
|
79
79
|
}
|
|
@@ -86,7 +86,7 @@ extension CGVector: Convertible {
|
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
extension CGRect: Convertible {
|
|
89
|
-
public static func convert(from value: Any
|
|
89
|
+
public static func convert(from value: Any?, appContext: AppContext) throws -> CGRect {
|
|
90
90
|
if let value = value as? [Double], value.count == 4 {
|
|
91
91
|
return CGRect(x: value[0], y: value[1], width: value[2], height: value[3])
|
|
92
92
|
}
|
|
@@ -37,35 +37,41 @@ public final class ClassComponent: ObjectDefinition {
|
|
|
37
37
|
|
|
38
38
|
// MARK: - JavaScriptObjectBuilder
|
|
39
39
|
|
|
40
|
-
public override func build(
|
|
41
|
-
let klass = runtime.createClass(name) { [weak self, weak
|
|
42
|
-
guard let self = self, let
|
|
40
|
+
public override func build(appContext: AppContext) throws -> JavaScriptObject {
|
|
41
|
+
let klass = try appContext.runtime.createClass(name) { [weak self, weak appContext] this, arguments in
|
|
42
|
+
guard let self = self, let appContext else {
|
|
43
43
|
// TODO: Throw an exception? (@tsapeta)
|
|
44
44
|
return
|
|
45
45
|
}
|
|
46
|
-
// The properties can't go into the prototype as they would be shared across all instances.
|
|
47
|
-
// Instead, we decorate the instance object on initialization.
|
|
48
|
-
self.decorateWithProperties(runtime: runtime, object: this)
|
|
49
46
|
|
|
50
47
|
// Call the native constructor when defined.
|
|
51
|
-
let result = try? self.constructor?.call(by: this, withArguments: arguments)
|
|
48
|
+
let result = try? self.constructor?.call(by: this, withArguments: arguments, appContext: appContext)
|
|
52
49
|
|
|
53
50
|
// Register the shared object if returned by the constructor.
|
|
54
51
|
if let result = result as? SharedObject {
|
|
55
52
|
SharedObjectRegistry.add(native: result, javaScript: this)
|
|
56
53
|
}
|
|
57
54
|
}
|
|
58
|
-
|
|
55
|
+
|
|
56
|
+
try decorate(object: klass, appContext: appContext)
|
|
57
|
+
|
|
58
|
+
// Register the JS class and its associated native type.
|
|
59
|
+
if let sharedObjectType = associatedType as? DynamicSharedObjectType {
|
|
60
|
+
appContext.classRegistry.register(nativeClassId: sharedObjectType.typeIdentifier, javaScriptClass: klass)
|
|
61
|
+
}
|
|
62
|
+
|
|
59
63
|
return klass
|
|
60
64
|
}
|
|
61
65
|
|
|
62
|
-
public override func decorate(object: JavaScriptObject,
|
|
66
|
+
public override func decorate(object: JavaScriptObject, appContext: AppContext) throws {
|
|
63
67
|
// Here we actually don't decorate the input object (constructor) but its prototype.
|
|
64
68
|
// Properties are intentionally skipped here — they have to decorate an instance instead of the prototype.
|
|
65
69
|
let prototype = object.getProperty("prototype").getObject()
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
70
|
+
|
|
71
|
+
decorateWithConstants(object: prototype)
|
|
72
|
+
try decorateWithFunctions(object: prototype, appContext: appContext)
|
|
73
|
+
try decorateWithClasses(object: prototype, appContext: appContext)
|
|
74
|
+
try decorateWithProperties(object: prototype, appContext: appContext)
|
|
69
75
|
}
|
|
70
76
|
}
|
|
71
77
|
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// Copyright 2023-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
internal final class ClassRegistry {
|
|
4
|
+
var nativeToJS = [ObjectIdentifier: JavaScriptWeakObject]()
|
|
5
|
+
|
|
6
|
+
// MARK: - Accessing
|
|
7
|
+
|
|
8
|
+
func getJavaScriptClass(nativeClassId: ObjectIdentifier) -> JavaScriptObject? {
|
|
9
|
+
return nativeToJS[nativeClassId]?.lock()
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
func getJavaScriptClass(nativeClass: SharedObject.Type) -> JavaScriptObject? {
|
|
13
|
+
let nativeClassId = ObjectIdentifier(nativeClass)
|
|
14
|
+
return getJavaScriptClass(nativeClassId: nativeClassId)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// MARK: - Registration
|
|
18
|
+
|
|
19
|
+
func register(nativeClassId: ObjectIdentifier, javaScriptClass: JavaScriptObject) {
|
|
20
|
+
nativeToJS[nativeClassId] = javaScriptClass.createWeak()
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
func register(nativeClass: SharedObject.Type, javaScriptClass: JavaScriptObject) {
|
|
24
|
+
let nativeClassId = ObjectIdentifier(nativeClass)
|
|
25
|
+
register(nativeClassId: nativeClassId, javaScriptClass: javaScriptClass)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
internal func clear() {
|
|
29
|
+
nativeToJS.removeAll()
|
|
30
|
+
}
|
|
31
|
+
}
|