expo-modules-core 0.9.0 → 0.10.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 +25 -0
- package/android/CMakeLists.txt +154 -0
- package/android/build.gradle +293 -5
- package/android/src/main/cpp/Exceptions.cpp +22 -0
- package/android/src/main/cpp/Exceptions.h +38 -0
- package/android/src/main/cpp/ExpoModulesHostObject.cpp +47 -0
- package/android/src/main/cpp/ExpoModulesHostObject.h +32 -0
- package/android/src/main/cpp/JNIFunctionBody.cpp +29 -0
- package/android/src/main/cpp/JNIFunctionBody.h +50 -0
- package/android/src/main/cpp/JNIInjector.cpp +19 -0
- package/android/src/main/cpp/JSIInteropModuleRegistry.cpp +122 -0
- package/android/src/main/cpp/JSIInteropModuleRegistry.h +96 -0
- package/android/src/main/cpp/JSIObjectWrapper.h +33 -0
- package/android/src/main/cpp/JSITypeConverter.h +84 -0
- package/android/src/main/cpp/JavaScriptModuleObject.cpp +138 -0
- package/android/src/main/cpp/JavaScriptModuleObject.h +122 -0
- package/android/src/main/cpp/JavaScriptObject.cpp +125 -0
- package/android/src/main/cpp/JavaScriptObject.h +131 -0
- package/android/src/main/cpp/JavaScriptRuntime.cpp +127 -0
- package/android/src/main/cpp/JavaScriptRuntime.h +87 -0
- package/android/src/main/cpp/JavaScriptValue.cpp +172 -0
- package/android/src/main/cpp/JavaScriptValue.h +78 -0
- package/android/src/main/cpp/MethodMetadata.cpp +230 -0
- package/android/src/main/cpp/MethodMetadata.h +92 -0
- package/android/src/main/java/expo/modules/adapters/react/NativeModulesProxy.java +2 -0
- package/android/src/main/java/expo/modules/core/errors/ContextDestroyedException.kt +7 -0
- package/android/src/main/java/expo/modules/interfaces/permissions/Permissions.java +30 -0
- package/android/src/main/java/expo/modules/kotlin/AppContext.kt +49 -1
- package/android/src/main/java/expo/modules/kotlin/ConcatIterator.kt +18 -0
- package/android/src/main/java/expo/modules/kotlin/KotlinInteropModuleRegistry.kt +15 -12
- package/android/src/main/java/expo/modules/kotlin/ModuleHolder.kt +39 -3
- package/android/src/main/java/expo/modules/kotlin/defaultmodules/ErrorManagerModule.kt +2 -2
- package/android/src/main/java/expo/modules/kotlin/exception/CodedException.kt +13 -0
- package/android/src/main/java/expo/modules/kotlin/exception/ExceptionDecorator.kt +2 -0
- package/android/src/main/java/expo/modules/kotlin/functions/AnyFunction.kt +19 -14
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunction.kt +29 -7
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionBuilder.kt +13 -13
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionComponent.kt +18 -0
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromiseComponent.kt +18 -0
- package/android/src/main/java/expo/modules/kotlin/functions/SuspendFunctionComponent.kt +56 -0
- package/android/src/main/java/expo/modules/kotlin/functions/SyncFunctionComponent.kt +28 -0
- package/android/src/main/java/expo/modules/kotlin/jni/CppType.kt +18 -0
- package/android/src/main/java/expo/modules/kotlin/jni/JNIFunctionBody.kt +39 -0
- package/android/src/main/java/expo/modules/kotlin/jni/JSIInteropModuleRegistry.kt +89 -0
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptModuleObject.kt +44 -0
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptObject.kt +113 -0
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptValue.kt +35 -0
- package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +15 -5
- package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +65 -111
- package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionData.kt +35 -2
- package/android/src/main/java/expo/modules/kotlin/providers/AppContextProvider.kt +14 -0
- package/android/src/main/java/expo/modules/kotlin/providers/CurrentActivityProvider.kt +22 -0
- package/android/src/main/java/expo/modules/kotlin/records/RecordTypeConverter.kt +19 -2
- package/android/src/main/java/expo/modules/kotlin/types/AnyType.kt +3 -2
- package/android/src/main/java/expo/modules/kotlin/types/ArrayTypeConverter.kt +7 -2
- package/android/src/main/java/expo/modules/kotlin/types/BasicTypeConverters.kt +68 -20
- package/android/src/main/java/expo/modules/kotlin/types/EnumTypeConverter.kt +50 -22
- package/android/src/main/java/expo/modules/kotlin/types/ListTypeConverter.kt +18 -2
- package/android/src/main/java/expo/modules/kotlin/types/MapTypeConverter.kt +18 -2
- package/android/src/main/java/expo/modules/kotlin/types/PairTypeConverter.kt +17 -2
- package/android/src/main/java/expo/modules/kotlin/types/TypeConverter.kt +43 -3
- package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +5 -0
- package/build/NativeModulesProxy.native.d.ts.map +1 -1
- package/build/NativeModulesProxy.native.js +9 -3
- package/build/NativeModulesProxy.native.js.map +1 -1
- package/ios/AppDelegates/EXAppDelegatesLoader.m +1 -2
- package/ios/ExpoModulesCore.podspec +1 -1
- package/ios/JSI/EXJSIConversions.mm +6 -0
- package/ios/JSI/EXJSIInstaller.h +15 -21
- package/ios/JSI/EXJSIInstaller.mm +39 -3
- package/ios/JSI/EXJSIUtils.h +47 -3
- package/ios/JSI/EXJSIUtils.mm +88 -4
- package/ios/JSI/EXJavaScriptObject.h +11 -18
- package/ios/JSI/EXJavaScriptObject.mm +37 -18
- package/ios/JSI/EXJavaScriptRuntime.h +43 -9
- package/ios/JSI/EXJavaScriptRuntime.mm +70 -27
- package/ios/JSI/EXJavaScriptTypedArray.h +30 -0
- package/ios/JSI/EXJavaScriptTypedArray.mm +29 -0
- package/ios/JSI/EXJavaScriptValue.h +3 -2
- package/ios/JSI/EXJavaScriptValue.mm +17 -20
- package/ios/JSI/EXJavaScriptWeakObject.h +23 -0
- package/ios/JSI/EXJavaScriptWeakObject.mm +53 -0
- package/ios/JSI/EXObjectDeallocator.h +27 -0
- package/ios/JSI/ExpoModulesHostObject.h +3 -3
- package/ios/JSI/ExpoModulesHostObject.mm +4 -4
- package/ios/JSI/JavaScriptRuntime.swift +38 -1
- package/ios/JSI/JavaScriptValue.swift +7 -0
- package/ios/JSI/TypedArray.cpp +67 -0
- package/ios/JSI/TypedArray.h +46 -0
- package/ios/ModuleRegistryAdapter/EXModuleRegistryAdapter.m +0 -11
- package/ios/NativeModulesProxy/EXNativeModulesProxy.h +17 -10
- package/ios/NativeModulesProxy/EXNativeModulesProxy.mm +88 -77
- package/ios/NativeModulesProxy/NativeModulesProxyModule.swift +17 -0
- package/ios/Services/EXReactNativeEventEmitter.h +2 -2
- package/ios/Services/EXReactNativeEventEmitter.m +11 -6
- package/ios/Swift/AppContext.swift +208 -28
- package/ios/Swift/Arguments/AnyArgument.swift +18 -0
- package/ios/Swift/Arguments/{Types/EnumArgumentType.swift → EnumArgument.swift} +2 -17
- package/ios/Swift/Classes/ClassComponent.swift +95 -0
- package/ios/Swift/Classes/ClassComponentElement.swift +33 -0
- package/ios/Swift/Classes/ClassComponentElementsBuilder.swift +34 -0
- package/ios/Swift/Classes/ClassComponentFactories.swift +96 -0
- package/ios/Swift/DynamicTypes/AnyDynamicType.swift +44 -0
- package/ios/Swift/DynamicTypes/DynamicArrayType.swift +56 -0
- package/ios/Swift/DynamicTypes/DynamicConvertibleType.swift +27 -0
- package/ios/Swift/DynamicTypes/DynamicEnumType.swift +27 -0
- package/ios/Swift/DynamicTypes/DynamicOptionalType.swift +63 -0
- package/ios/Swift/DynamicTypes/DynamicRawType.swift +33 -0
- package/ios/Swift/DynamicTypes/DynamicSharedObjectType.swift +37 -0
- package/ios/Swift/DynamicTypes/DynamicType.swift +39 -0
- package/ios/Swift/DynamicTypes/DynamicTypedArrayType.swift +46 -0
- package/ios/Swift/Exceptions/CodedError.swift +1 -1
- package/ios/Swift/Exceptions/Exception.swift +8 -6
- package/ios/Swift/Exceptions/UnexpectedException.swift +2 -1
- package/ios/Swift/ExpoBridgeModule.m +5 -0
- package/ios/Swift/ExpoBridgeModule.swift +65 -0
- package/ios/Swift/Functions/AnyFunction.swift +33 -31
- package/ios/Swift/Functions/AsyncFunctionComponent.swift +196 -59
- package/ios/Swift/Functions/SyncFunctionComponent.swift +142 -58
- package/ios/Swift/JavaScriptUtils.swift +32 -57
- package/ios/Swift/Logging/LogHandlers.swift +39 -0
- package/ios/Swift/Logging/LogType.swift +62 -0
- package/ios/Swift/Logging/Logger.swift +198 -0
- package/ios/Swift/ModuleHolder.swift +19 -54
- package/ios/Swift/ModuleRegistry.swift +7 -1
- package/ios/Swift/Modules/AnyModule.swift +3 -3
- package/ios/Swift/ModulesProvider.swift +2 -0
- package/ios/Swift/Objects/JavaScriptObjectBuilder.swift +37 -0
- package/ios/Swift/Objects/ObjectDefinition.swift +74 -1
- package/ios/Swift/Objects/ObjectDefinitionComponents.swift +77 -68
- package/ios/Swift/Objects/PropertyComponent.swift +147 -0
- package/ios/Swift/Promise.swift +12 -3
- package/ios/Swift/Records/Field.swift +2 -2
- package/ios/Swift/SharedObjects/SharedObject.swift +20 -0
- package/ios/Swift/SharedObjects/SharedObjectRegistry.swift +129 -0
- package/ios/Swift/TypedArrays/AnyTypedArray.swift +11 -0
- package/ios/Swift/TypedArrays/ConcreteTypedArrays.swift +56 -0
- package/ios/Swift/TypedArrays/GenericTypedArray.swift +49 -0
- package/ios/Swift/TypedArrays/TypedArray.swift +80 -0
- package/ios/Swift/Utilities.swift +28 -0
- package/ios/Swift/Views/ConcreteViewProp.swift +3 -3
- package/ios/Swift/Views/ViewManagerDefinitionComponents.swift +2 -2
- package/ios/Tests/ClassComponentSpec.swift +210 -0
- package/ios/Tests/DynamicTypeSpec.swift +336 -0
- package/ios/Tests/EnumArgumentSpec.swift +48 -0
- package/ios/Tests/ExpoModulesSpec.swift +17 -3
- package/ios/Tests/FunctionSpec.swift +167 -118
- package/ios/Tests/Mocks/ModuleMocks.swift +1 -1
- package/ios/Tests/PropertyComponentSpec.swift +95 -0
- package/ios/Tests/SharedObjectRegistrySpec.swift +109 -0
- package/ios/Tests/TypedArraysSpec.swift +136 -0
- package/package.json +2 -2
- package/src/NativeModulesProxy.native.ts +13 -3
- package/src/ts-declarations/ExpoModules.d.ts +7 -0
- package/tsconfig.json +1 -1
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromise.kt +0 -15
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncSuspendFunction.kt +0 -36
- package/ios/Swift/Arguments/AnyArgumentType.swift +0 -13
- package/ios/Swift/Arguments/ArgumentType.swift +0 -28
- package/ios/Swift/Arguments/Types/ArrayArgumentType.swift +0 -42
- package/ios/Swift/Arguments/Types/ConvertibleArgumentType.swift +0 -16
- package/ios/Swift/Arguments/Types/OptionalArgumentType.swift +0 -49
- package/ios/Swift/Arguments/Types/PromiseArgumentType.swift +0 -15
- package/ios/Swift/Arguments/Types/RawArgumentType.swift +0 -25
- package/ios/Swift/Functions/ConcreteFunction.swift +0 -103
- package/ios/Swift/SwiftInteropBridge.swift +0 -155
- package/ios/Tests/ArgumentTypeSpec.swift +0 -143
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
package expo.modules.kotlin.records
|
|
2
2
|
|
|
3
3
|
import com.facebook.react.bridge.Dynamic
|
|
4
|
+
import com.facebook.react.bridge.ReadableMap
|
|
4
5
|
import expo.modules.kotlin.allocators.ObjectConstructor
|
|
5
6
|
import expo.modules.kotlin.allocators.ObjectConstructorFactory
|
|
6
7
|
import expo.modules.kotlin.exception.FieldCastException
|
|
7
8
|
import expo.modules.kotlin.exception.FieldRequiredException
|
|
8
9
|
import expo.modules.kotlin.exception.RecordCastException
|
|
9
10
|
import expo.modules.kotlin.exception.exceptionDecorator
|
|
11
|
+
import expo.modules.kotlin.jni.CppType
|
|
10
12
|
import expo.modules.kotlin.recycle
|
|
13
|
+
import expo.modules.kotlin.types.DynamicAwareTypeConverters
|
|
11
14
|
import expo.modules.kotlin.types.TypeConverter
|
|
12
15
|
import expo.modules.kotlin.types.TypeConverterProvider
|
|
13
16
|
import kotlin.reflect.KClass
|
|
@@ -21,7 +24,7 @@ import kotlin.reflect.jvm.javaField
|
|
|
21
24
|
class RecordTypeConverter<T : Record>(
|
|
22
25
|
private val converterProvider: TypeConverterProvider,
|
|
23
26
|
val type: KType,
|
|
24
|
-
) :
|
|
27
|
+
) : DynamicAwareTypeConverters<T>(type.isMarkedNullable) {
|
|
25
28
|
private val objectConstructorFactory = ObjectConstructorFactory()
|
|
26
29
|
private val propertyDescriptors: Map<KProperty1<out Any, *>, PropertyDescriptor> =
|
|
27
30
|
(type.classifier as KClass<*>)
|
|
@@ -40,9 +43,23 @@ class RecordTypeConverter<T : Record>(
|
|
|
40
43
|
.filterNotNull()
|
|
41
44
|
.toMap()
|
|
42
45
|
|
|
43
|
-
override fun
|
|
46
|
+
override fun convertFromDynamic(value: Dynamic): T = exceptionDecorator({ cause -> RecordCastException(type, cause) }) {
|
|
44
47
|
val jsMap = value.asMap()
|
|
48
|
+
return convertFromReadableMap(jsMap)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
override fun convertFromAny(value: Any): T {
|
|
52
|
+
if (value is ReadableMap) {
|
|
53
|
+
return convertFromReadableMap(value)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@Suppress("UNCHECKED_CAST")
|
|
57
|
+
return value as T
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
override fun getCppRequiredTypes(): List<CppType> = listOf(CppType.READABLE_MAP)
|
|
45
61
|
|
|
62
|
+
private fun convertFromReadableMap(jsMap: ReadableMap): T {
|
|
46
63
|
val kClass = type.classifier as KClass<*>
|
|
47
64
|
val instance = getObjectConstructor(kClass.java).construct()
|
|
48
65
|
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
package expo.modules.kotlin.types
|
|
2
2
|
|
|
3
|
-
import com.facebook.react.bridge.Dynamic
|
|
4
3
|
import kotlin.reflect.KType
|
|
5
4
|
|
|
6
5
|
fun KType.toAnyType(): AnyType = AnyType(this)
|
|
@@ -10,5 +9,7 @@ class AnyType(val kType: KType) {
|
|
|
10
9
|
TypeConverterProviderImpl.obtainTypeConverter(kType)
|
|
11
10
|
}
|
|
12
11
|
|
|
13
|
-
fun convert(value:
|
|
12
|
+
fun convert(value: Any?): Any? = converter.convert(value)
|
|
13
|
+
|
|
14
|
+
fun getCppRequiredTypes(): Int = converter.getCppRequiredTypes().fold(0) { acc, current -> acc or current.value }
|
|
14
15
|
}
|
|
@@ -3,6 +3,7 @@ package expo.modules.kotlin.types
|
|
|
3
3
|
import com.facebook.react.bridge.Dynamic
|
|
4
4
|
import expo.modules.kotlin.exception.CollectionElementCastException
|
|
5
5
|
import expo.modules.kotlin.exception.exceptionDecorator
|
|
6
|
+
import expo.modules.kotlin.jni.CppType
|
|
6
7
|
import expo.modules.kotlin.recycle
|
|
7
8
|
import kotlin.reflect.KClass
|
|
8
9
|
import kotlin.reflect.KType
|
|
@@ -10,14 +11,14 @@ import kotlin.reflect.KType
|
|
|
10
11
|
class ArrayTypeConverter(
|
|
11
12
|
converterProvider: TypeConverterProvider,
|
|
12
13
|
private val arrayType: KType,
|
|
13
|
-
) :
|
|
14
|
+
) : DynamicAwareTypeConverters<Array<*>>(arrayType.isMarkedNullable) {
|
|
14
15
|
private val arrayElementConverter = converterProvider.obtainTypeConverter(
|
|
15
16
|
requireNotNull(arrayType.arguments.first().type) {
|
|
16
17
|
"The array type should contain the type of the elements."
|
|
17
18
|
}
|
|
18
19
|
)
|
|
19
20
|
|
|
20
|
-
override fun
|
|
21
|
+
override fun convertFromDynamic(value: Dynamic): Array<*> {
|
|
21
22
|
val jsArray = value.asArray()
|
|
22
23
|
val array = createTypedArray(jsArray.size())
|
|
23
24
|
for (i in 0 until jsArray.size()) {
|
|
@@ -34,6 +35,8 @@ class ArrayTypeConverter(
|
|
|
34
35
|
return array
|
|
35
36
|
}
|
|
36
37
|
|
|
38
|
+
override fun convertFromAny(value: Any): Array<*> = value as Array<*>
|
|
39
|
+
|
|
37
40
|
/**
|
|
38
41
|
* We can't use a Array<Any?> here. We have to create a typed array.
|
|
39
42
|
* Otherwise, cast which is done before calling lambda provided by the user will always fail.
|
|
@@ -47,4 +50,6 @@ class ArrayTypeConverter(
|
|
|
47
50
|
size
|
|
48
51
|
) as Array<Any?>
|
|
49
52
|
}
|
|
53
|
+
|
|
54
|
+
override fun getCppRequiredTypes(): List<CppType> = listOf(CppType.READABLE_ARRAY)
|
|
50
55
|
}
|
|
@@ -3,58 +3,106 @@ package expo.modules.kotlin.types
|
|
|
3
3
|
import com.facebook.react.bridge.Dynamic
|
|
4
4
|
import com.facebook.react.bridge.ReadableArray
|
|
5
5
|
import com.facebook.react.bridge.ReadableMap
|
|
6
|
+
import expo.modules.kotlin.jni.CppType
|
|
7
|
+
import expo.modules.kotlin.jni.JavaScriptObject
|
|
8
|
+
import expo.modules.kotlin.jni.JavaScriptValue
|
|
6
9
|
|
|
7
|
-
class IntTypeConverter(isOptional: Boolean) :
|
|
8
|
-
override fun
|
|
10
|
+
class IntTypeConverter(isOptional: Boolean) : DynamicAwareTypeConverters<Int>(isOptional) {
|
|
11
|
+
override fun convertFromDynamic(value: Dynamic): Int = value.asInt()
|
|
12
|
+
override fun convertFromAny(value: Any): Int = when (value) {
|
|
13
|
+
is Number -> value.toInt()
|
|
14
|
+
else -> value as Int
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
override fun getCppRequiredTypes(): List<CppType> = listOf(CppType.DOUBLE)
|
|
9
18
|
}
|
|
10
19
|
|
|
11
|
-
class DoubleTypeConverter(isOptional: Boolean) :
|
|
12
|
-
override fun
|
|
20
|
+
class DoubleTypeConverter(isOptional: Boolean) : DynamicAwareTypeConverters<Double>(isOptional) {
|
|
21
|
+
override fun convertFromDynamic(value: Dynamic): Double = value.asDouble()
|
|
22
|
+
override fun convertFromAny(value: Any): Double = when (value) {
|
|
23
|
+
is Number -> value.toDouble()
|
|
24
|
+
else -> value as Double
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
override fun getCppRequiredTypes(): List<CppType> = listOf(CppType.DOUBLE)
|
|
13
28
|
}
|
|
14
29
|
|
|
15
|
-
class FloatTypeConverter(isOptional: Boolean) :
|
|
16
|
-
override fun
|
|
30
|
+
class FloatTypeConverter(isOptional: Boolean) : DynamicAwareTypeConverters<Float>(isOptional) {
|
|
31
|
+
override fun convertFromDynamic(value: Dynamic): Float = value.asDouble().toFloat()
|
|
32
|
+
override fun convertFromAny(value: Any): Float = when (value) {
|
|
33
|
+
is Number -> value.toFloat()
|
|
34
|
+
else -> value as Float
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
override fun getCppRequiredTypes(): List<CppType> = listOf(CppType.DOUBLE)
|
|
17
38
|
}
|
|
18
39
|
|
|
19
|
-
class BoolTypeConverter(isOptional: Boolean) :
|
|
20
|
-
override fun
|
|
40
|
+
class BoolTypeConverter(isOptional: Boolean) : DynamicAwareTypeConverters<Boolean>(isOptional) {
|
|
41
|
+
override fun convertFromDynamic(value: Dynamic): Boolean = value.asBoolean()
|
|
42
|
+
override fun convertFromAny(value: Any): Boolean = value as Boolean
|
|
43
|
+
override fun getCppRequiredTypes(): List<CppType> = listOf(CppType.BOOLEAN)
|
|
21
44
|
}
|
|
22
45
|
|
|
23
|
-
class StringTypeConverter(isOptional: Boolean) :
|
|
24
|
-
override fun
|
|
46
|
+
class StringTypeConverter(isOptional: Boolean) : DynamicAwareTypeConverters<String>(isOptional) {
|
|
47
|
+
override fun convertFromDynamic(value: Dynamic): String = value.asString()
|
|
48
|
+
override fun convertFromAny(value: Any): String = value as String
|
|
49
|
+
override fun getCppRequiredTypes(): List<CppType> = listOf(CppType.STRING)
|
|
25
50
|
}
|
|
26
51
|
|
|
27
|
-
class ReadableArrayTypeConverter(isOptional: Boolean) :
|
|
28
|
-
override fun
|
|
52
|
+
class ReadableArrayTypeConverter(isOptional: Boolean) : DynamicAwareTypeConverters<ReadableArray>(isOptional) {
|
|
53
|
+
override fun convertFromDynamic(value: Dynamic): ReadableArray = value.asArray()
|
|
54
|
+
override fun convertFromAny(value: Any): ReadableArray = value as ReadableArray
|
|
55
|
+
override fun getCppRequiredTypes(): List<CppType> = listOf(CppType.READABLE_ARRAY)
|
|
29
56
|
}
|
|
30
57
|
|
|
31
|
-
class ReadableMapTypeConverter(isOptional: Boolean) :
|
|
32
|
-
override fun
|
|
58
|
+
class ReadableMapTypeConverter(isOptional: Boolean) : DynamicAwareTypeConverters<ReadableMap>(isOptional) {
|
|
59
|
+
override fun convertFromDynamic(value: Dynamic): ReadableMap = value.asMap()
|
|
60
|
+
override fun convertFromAny(value: Any): ReadableMap = value as ReadableMap
|
|
61
|
+
override fun getCppRequiredTypes(): List<CppType> = listOf(CppType.READABLE_MAP)
|
|
33
62
|
}
|
|
34
63
|
|
|
35
|
-
class PrimitiveIntArrayTypeConverter(isOptional: Boolean) :
|
|
36
|
-
override fun
|
|
64
|
+
class PrimitiveIntArrayTypeConverter(isOptional: Boolean) : DynamicAwareTypeConverters<IntArray>(isOptional) {
|
|
65
|
+
override fun convertFromDynamic(value: Dynamic): IntArray {
|
|
37
66
|
val jsArray = value.asArray()
|
|
38
67
|
return IntArray(jsArray.size()) { index ->
|
|
39
68
|
jsArray.getInt(index)
|
|
40
69
|
}
|
|
41
70
|
}
|
|
71
|
+
|
|
72
|
+
override fun convertFromAny(value: Any): IntArray = value as IntArray
|
|
73
|
+
override fun getCppRequiredTypes(): List<CppType> = listOf(CppType.READABLE_ARRAY)
|
|
42
74
|
}
|
|
43
75
|
|
|
44
|
-
class PrimitiveDoubleArrayTypeConverter(isOptional: Boolean) :
|
|
45
|
-
override fun
|
|
76
|
+
class PrimitiveDoubleArrayTypeConverter(isOptional: Boolean) : DynamicAwareTypeConverters<DoubleArray>(isOptional) {
|
|
77
|
+
override fun convertFromDynamic(value: Dynamic): DoubleArray {
|
|
46
78
|
val jsArray = value.asArray()
|
|
47
79
|
return DoubleArray(jsArray.size()) { index ->
|
|
48
80
|
jsArray.getDouble(index)
|
|
49
81
|
}
|
|
50
82
|
}
|
|
83
|
+
|
|
84
|
+
override fun convertFromAny(value: Any): DoubleArray = value as DoubleArray
|
|
85
|
+
override fun getCppRequiredTypes(): List<CppType> = listOf(CppType.READABLE_ARRAY)
|
|
51
86
|
}
|
|
52
87
|
|
|
53
|
-
class PrimitiveFloatArrayTypeConverter(isOptional: Boolean) :
|
|
54
|
-
override fun
|
|
88
|
+
class PrimitiveFloatArrayTypeConverter(isOptional: Boolean) : DynamicAwareTypeConverters<FloatArray>(isOptional) {
|
|
89
|
+
override fun convertFromDynamic(value: Dynamic): FloatArray {
|
|
55
90
|
val jsArray = value.asArray()
|
|
56
91
|
return FloatArray(jsArray.size()) { index ->
|
|
57
92
|
jsArray.getDouble(index).toFloat()
|
|
58
93
|
}
|
|
59
94
|
}
|
|
95
|
+
|
|
96
|
+
override fun convertFromAny(value: Any): FloatArray = value as FloatArray
|
|
97
|
+
override fun getCppRequiredTypes(): List<CppType> = listOf(CppType.READABLE_ARRAY)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
class JavaScriptValueTypeConvert(isOptional: Boolean) : TypeConverter<JavaScriptValue>(isOptional) {
|
|
101
|
+
override fun convertNonOptional(value: Any): JavaScriptValue = value as JavaScriptValue
|
|
102
|
+
override fun getCppRequiredTypes(): List<CppType> = CppType.values().toList()
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
class JavaScriptObjectTypeConverter(isOptional: Boolean) : TypeConverter<JavaScriptObject>(isOptional) {
|
|
106
|
+
override fun convertNonOptional(value: Any): JavaScriptObject = value as JavaScriptObject
|
|
107
|
+
override fun getCppRequiredTypes(): List<CppType> = listOf(CppType.JS_OBJECT)
|
|
60
108
|
}
|
|
@@ -2,6 +2,7 @@ package expo.modules.kotlin.types
|
|
|
2
2
|
|
|
3
3
|
import com.facebook.react.bridge.Dynamic
|
|
4
4
|
import expo.modules.kotlin.exception.IncompatibleArgTypeException
|
|
5
|
+
import expo.modules.kotlin.jni.CppType
|
|
5
6
|
import expo.modules.kotlin.toKType
|
|
6
7
|
import kotlin.reflect.KClass
|
|
7
8
|
import kotlin.reflect.full.createType
|
|
@@ -11,22 +12,24 @@ import kotlin.reflect.full.primaryConstructor
|
|
|
11
12
|
class EnumTypeConverter(
|
|
12
13
|
private val enumClass: KClass<Enum<*>>,
|
|
13
14
|
isOptional: Boolean
|
|
14
|
-
) :
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
require(enumConstants.isNotEmpty()) {
|
|
21
|
-
"Passed enum type is empty."
|
|
15
|
+
) : DynamicAwareTypeConverters<Enum<*>>(isOptional) {
|
|
16
|
+
private val enumConstants = requireNotNull(enumClass.java.enumConstants) {
|
|
17
|
+
"Passed type is not an enum type"
|
|
18
|
+
}.also {
|
|
19
|
+
require(it.isNotEmpty()) {
|
|
20
|
+
"Passed enum type is empty"
|
|
22
21
|
}
|
|
22
|
+
}
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
private val primaryConstructor = requireNotNull(enumClass.primaryConstructor) {
|
|
25
|
+
"Cannot convert js value to enum without the primary constructor"
|
|
26
|
+
}
|
|
27
27
|
|
|
28
|
+
override fun getCppRequiredTypes(): List<CppType> = listOf(CppType.READABLE_MAP)
|
|
29
|
+
|
|
30
|
+
override fun convertFromDynamic(value: Dynamic): Enum<*> {
|
|
28
31
|
if (primaryConstructor.parameters.isEmpty()) {
|
|
29
|
-
return convertEnumWithoutParameter(value, enumConstants)
|
|
32
|
+
return convertEnumWithoutParameter(value.asString(), enumConstants)
|
|
30
33
|
} else if (primaryConstructor.parameters.size == 1) {
|
|
31
34
|
return convertEnumWithParameter(
|
|
32
35
|
value,
|
|
@@ -38,18 +41,31 @@ class EnumTypeConverter(
|
|
|
38
41
|
throw IncompatibleArgTypeException(value.type.toKType(), enumClass.createType())
|
|
39
42
|
}
|
|
40
43
|
|
|
44
|
+
override fun convertFromAny(value: Any): Enum<*> {
|
|
45
|
+
if (primaryConstructor.parameters.isEmpty()) {
|
|
46
|
+
return convertEnumWithoutParameter(value as String, enumConstants)
|
|
47
|
+
} else if (primaryConstructor.parameters.size == 1) {
|
|
48
|
+
return convertEnumWithParameter(
|
|
49
|
+
value,
|
|
50
|
+
enumConstants,
|
|
51
|
+
primaryConstructor.parameters.first().name!!
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
throw IncompatibleArgTypeException(value::class.createType(), enumClass.createType())
|
|
56
|
+
}
|
|
57
|
+
|
|
41
58
|
/**
|
|
42
59
|
* If the primary constructor doesn't take any parameters, we treat the name of each enum as a value.
|
|
43
60
|
* So the jsValue has to contain string.
|
|
44
61
|
*/
|
|
45
62
|
private fun convertEnumWithoutParameter(
|
|
46
|
-
|
|
63
|
+
stringRepresentation: String,
|
|
47
64
|
enumConstants: Array<out Enum<*>>
|
|
48
65
|
): Enum<*> {
|
|
49
|
-
val unwrappedJsValue = jsValue.asString()
|
|
50
66
|
return requireNotNull(
|
|
51
|
-
enumConstants.find { it.name ==
|
|
52
|
-
) { "Couldn't convert $
|
|
67
|
+
enumConstants.find { it.name == stringRepresentation }
|
|
68
|
+
) { "Couldn't convert '$stringRepresentation' to ${enumClass.simpleName}" }
|
|
53
69
|
}
|
|
54
70
|
|
|
55
71
|
/**
|
|
@@ -57,7 +73,7 @@ class EnumTypeConverter(
|
|
|
57
73
|
* In that case, we handles two different types: Int and String.
|
|
58
74
|
*/
|
|
59
75
|
private fun convertEnumWithParameter(
|
|
60
|
-
jsValue:
|
|
76
|
+
jsValue: Any,
|
|
61
77
|
enumConstants: Array<out Enum<*>>,
|
|
62
78
|
parameterName: String
|
|
63
79
|
): Enum<*> {
|
|
@@ -66,19 +82,31 @@ class EnumTypeConverter(
|
|
|
66
82
|
val parameterProperty = enumClass
|
|
67
83
|
.declaredMemberProperties
|
|
68
84
|
.find { it.name == parameterName }
|
|
69
|
-
requireNotNull(parameterProperty) { "Cannot find a property for $parameterName parameter
|
|
85
|
+
requireNotNull(parameterProperty) { "Cannot find a property for $parameterName parameter" }
|
|
70
86
|
|
|
71
87
|
val parameterType = parameterProperty.returnType.classifier
|
|
72
|
-
val jsUnwrapValue = if (
|
|
73
|
-
|
|
88
|
+
val jsUnwrapValue = if (jsValue is Dynamic) {
|
|
89
|
+
if (parameterType == String::class) {
|
|
90
|
+
jsValue.asString()
|
|
91
|
+
} else {
|
|
92
|
+
jsValue.asInt()
|
|
93
|
+
}
|
|
74
94
|
} else {
|
|
75
|
-
|
|
95
|
+
if (parameterType == String::class) {
|
|
96
|
+
jsValue as String
|
|
97
|
+
} else {
|
|
98
|
+
if (jsValue is Double) {
|
|
99
|
+
jsValue.toInt()
|
|
100
|
+
} else {
|
|
101
|
+
jsValue as Int
|
|
102
|
+
}
|
|
103
|
+
}
|
|
76
104
|
}
|
|
77
105
|
|
|
78
106
|
return requireNotNull(
|
|
79
107
|
enumConstants.find {
|
|
80
108
|
parameterProperty.get(it) == jsUnwrapValue
|
|
81
109
|
}
|
|
82
|
-
) { "Couldn't convert $
|
|
110
|
+
) { "Couldn't convert '$jsValue' to ${enumClass.simpleName} where $parameterName is the enum parameter" }
|
|
83
111
|
}
|
|
84
112
|
}
|
|
@@ -1,23 +1,37 @@
|
|
|
1
1
|
package expo.modules.kotlin.types
|
|
2
2
|
|
|
3
3
|
import com.facebook.react.bridge.Dynamic
|
|
4
|
+
import com.facebook.react.bridge.ReadableArray
|
|
4
5
|
import expo.modules.kotlin.exception.CollectionElementCastException
|
|
5
6
|
import expo.modules.kotlin.exception.exceptionDecorator
|
|
7
|
+
import expo.modules.kotlin.jni.CppType
|
|
6
8
|
import expo.modules.kotlin.recycle
|
|
7
9
|
import kotlin.reflect.KType
|
|
8
10
|
|
|
9
11
|
class ListTypeConverter(
|
|
10
12
|
converterProvider: TypeConverterProvider,
|
|
11
13
|
private val listType: KType,
|
|
12
|
-
) :
|
|
14
|
+
) : DynamicAwareTypeConverters<List<*>>(listType.isMarkedNullable) {
|
|
13
15
|
private val elementConverter = converterProvider.obtainTypeConverter(
|
|
14
16
|
requireNotNull(listType.arguments.first().type) {
|
|
15
17
|
"The list type should contain the type of elements."
|
|
16
18
|
}
|
|
17
19
|
)
|
|
18
20
|
|
|
19
|
-
override fun
|
|
21
|
+
override fun convertFromDynamic(value: Dynamic): List<*> {
|
|
20
22
|
val jsArray = value.asArray()
|
|
23
|
+
return convertFromReadableArray(jsArray)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
override fun convertFromAny(value: Any): List<*> {
|
|
27
|
+
if (value is ReadableArray) {
|
|
28
|
+
return convertFromReadableArray(value)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return value as List<*>
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
private fun convertFromReadableArray(jsArray: ReadableArray): List<*> {
|
|
21
35
|
return List(jsArray.size()) { index ->
|
|
22
36
|
jsArray.getDynamic(index).recycle {
|
|
23
37
|
exceptionDecorator({ cause ->
|
|
@@ -28,4 +42,6 @@ class ListTypeConverter(
|
|
|
28
42
|
}
|
|
29
43
|
}
|
|
30
44
|
}
|
|
45
|
+
|
|
46
|
+
override fun getCppRequiredTypes(): List<CppType> = listOf(CppType.READABLE_ARRAY)
|
|
31
47
|
}
|
|
@@ -4,8 +4,10 @@ package expo.modules.kotlin.types
|
|
|
4
4
|
|
|
5
5
|
import com.facebook.react.bridge.Dynamic
|
|
6
6
|
import com.facebook.react.bridge.DynamicFromObject
|
|
7
|
+
import com.facebook.react.bridge.ReadableMap
|
|
7
8
|
import expo.modules.kotlin.exception.CollectionElementCastException
|
|
8
9
|
import expo.modules.kotlin.exception.exceptionDecorator
|
|
10
|
+
import expo.modules.kotlin.jni.CppType
|
|
9
11
|
import expo.modules.kotlin.recycle
|
|
10
12
|
import kotlin.reflect.KType
|
|
11
13
|
import kotlin.reflect.typeOf
|
|
@@ -13,7 +15,7 @@ import kotlin.reflect.typeOf
|
|
|
13
15
|
class MapTypeConverter(
|
|
14
16
|
converterProvider: TypeConverterProvider,
|
|
15
17
|
private val mapType: KType
|
|
16
|
-
) :
|
|
18
|
+
) : DynamicAwareTypeConverters<Map<*, *>>(mapType.isMarkedNullable) {
|
|
17
19
|
init {
|
|
18
20
|
require(mapType.arguments.first().type == typeOf<String>()) {
|
|
19
21
|
"The map key type should be String, but received ${mapType.arguments.first()}."
|
|
@@ -26,8 +28,20 @@ class MapTypeConverter(
|
|
|
26
28
|
}
|
|
27
29
|
)
|
|
28
30
|
|
|
29
|
-
override fun
|
|
31
|
+
override fun convertFromDynamic(value: Dynamic): Map<*, *> {
|
|
30
32
|
val jsMap = value.asMap()
|
|
33
|
+
return convertFromReadableMap(jsMap)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
override fun convertFromAny(value: Any): Map<*, *> {
|
|
37
|
+
if (value is ReadableMap) {
|
|
38
|
+
return convertFromReadableMap(value)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return value as Map<*, *>
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
private fun convertFromReadableMap(jsMap: ReadableMap): Map<*, *> {
|
|
31
45
|
val result = mutableMapOf<String, Any?>()
|
|
32
46
|
|
|
33
47
|
jsMap.entryIterator.forEach { (key, value) ->
|
|
@@ -42,4 +56,6 @@ class MapTypeConverter(
|
|
|
42
56
|
|
|
43
57
|
return result
|
|
44
58
|
}
|
|
59
|
+
|
|
60
|
+
override fun getCppRequiredTypes(): List<CppType> = listOf(CppType.READABLE_MAP)
|
|
45
61
|
}
|
|
@@ -4,13 +4,14 @@ import com.facebook.react.bridge.Dynamic
|
|
|
4
4
|
import com.facebook.react.bridge.ReadableArray
|
|
5
5
|
import expo.modules.kotlin.exception.CollectionElementCastException
|
|
6
6
|
import expo.modules.kotlin.exception.exceptionDecorator
|
|
7
|
+
import expo.modules.kotlin.jni.CppType
|
|
7
8
|
import expo.modules.kotlin.recycle
|
|
8
9
|
import kotlin.reflect.KType
|
|
9
10
|
|
|
10
11
|
class PairTypeConverter(
|
|
11
12
|
converterProvider: TypeConverterProvider,
|
|
12
13
|
private val pairType: KType,
|
|
13
|
-
) :
|
|
14
|
+
) : DynamicAwareTypeConverters<Pair<*, *>>(pairType.isMarkedNullable) {
|
|
14
15
|
private val converters = listOf(
|
|
15
16
|
converterProvider.obtainTypeConverter(
|
|
16
17
|
requireNotNull(pairType.arguments.getOrNull(0)?.type) {
|
|
@@ -24,8 +25,20 @@ class PairTypeConverter(
|
|
|
24
25
|
)
|
|
25
26
|
)
|
|
26
27
|
|
|
27
|
-
override fun
|
|
28
|
+
override fun convertFromDynamic(value: Dynamic): Pair<*, *> {
|
|
28
29
|
val jsArray = value.asArray()
|
|
30
|
+
return convertFromReadableArray(jsArray)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
override fun convertFromAny(value: Any): Pair<*, *> {
|
|
34
|
+
if (value is ReadableArray) {
|
|
35
|
+
return convertFromReadableArray(value)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return value as Pair<*, *>
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
private fun convertFromReadableArray(jsArray: ReadableArray): Pair<*, *> {
|
|
29
42
|
return Pair(
|
|
30
43
|
convertElement(jsArray, 0),
|
|
31
44
|
convertElement(jsArray, 1)
|
|
@@ -41,4 +54,6 @@ class PairTypeConverter(
|
|
|
41
54
|
}
|
|
42
55
|
}
|
|
43
56
|
}
|
|
57
|
+
|
|
58
|
+
override fun getCppRequiredTypes(): List<CppType> = listOf(CppType.READABLE_ARRAY)
|
|
44
59
|
}
|
|
@@ -2,12 +2,23 @@ package expo.modules.kotlin.types
|
|
|
2
2
|
|
|
3
3
|
import com.facebook.react.bridge.Dynamic
|
|
4
4
|
import expo.modules.kotlin.exception.NullArgumentException
|
|
5
|
+
import expo.modules.kotlin.jni.CppType
|
|
5
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Basic type converter. It has to handle two different inputs - [Dynamic] and [Any].
|
|
9
|
+
* The first one is used in the bridge implementation. The second one is used in the JSI.
|
|
10
|
+
*/
|
|
6
11
|
abstract class TypeConverter<Type : Any>(
|
|
12
|
+
/**
|
|
13
|
+
* Whether `null` can be assigned to the desired type.
|
|
14
|
+
*/
|
|
7
15
|
private val isOptional: Boolean
|
|
8
16
|
) {
|
|
9
|
-
|
|
10
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Tries to convert from [Any]? (can be also [Dynamic]) to the desired type.
|
|
19
|
+
*/
|
|
20
|
+
fun convert(value: Any?): Type? {
|
|
21
|
+
if (value == null || value is Dynamic && value.isNull) {
|
|
11
22
|
if (isOptional) {
|
|
12
23
|
return null
|
|
13
24
|
}
|
|
@@ -16,5 +27,34 @@ abstract class TypeConverter<Type : Any>(
|
|
|
16
27
|
return convertNonOptional(value)
|
|
17
28
|
}
|
|
18
29
|
|
|
19
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Tries to convert from [Any] to the desired type.
|
|
32
|
+
* We know in that place that we're not dealing with `null`.
|
|
33
|
+
*/
|
|
34
|
+
abstract fun convertNonOptional(value: Any): Type
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Returns a list of C++ types that can be converted to the desired type.
|
|
38
|
+
* Sometimes we have a choice between multiple representations of the same value.
|
|
39
|
+
* For instance js object can be pass as [Map] or [expo.modules.kotlin.jni.JavaScriptObject].
|
|
40
|
+
* This value tells us which one we should choose.
|
|
41
|
+
*/
|
|
42
|
+
abstract fun getCppRequiredTypes(): List<CppType>
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* A helper class to make a clear separation between [Any] and [Dynamic].
|
|
47
|
+
* Right it is used as a default base class for all converters, but this will change when we
|
|
48
|
+
* stop using the bridge to pass data between JS and Kotlin.
|
|
49
|
+
*/
|
|
50
|
+
abstract class DynamicAwareTypeConverters<T : Any>(isOptional: Boolean) : TypeConverter<T>(isOptional) {
|
|
51
|
+
override fun convertNonOptional(value: Any): T =
|
|
52
|
+
if (value is Dynamic) {
|
|
53
|
+
convertFromDynamic(value)
|
|
54
|
+
} else {
|
|
55
|
+
convertFromAny(value)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
abstract fun convertFromDynamic(value: Dynamic): T
|
|
59
|
+
abstract fun convertFromAny(value: Any): T
|
|
20
60
|
}
|
|
@@ -6,6 +6,8 @@ import com.facebook.react.bridge.Dynamic
|
|
|
6
6
|
import com.facebook.react.bridge.ReadableArray
|
|
7
7
|
import com.facebook.react.bridge.ReadableMap
|
|
8
8
|
import expo.modules.kotlin.exception.MissingTypeConverter
|
|
9
|
+
import expo.modules.kotlin.jni.JavaScriptObject
|
|
10
|
+
import expo.modules.kotlin.jni.JavaScriptValue
|
|
9
11
|
import expo.modules.kotlin.records.Record
|
|
10
12
|
import expo.modules.kotlin.records.RecordTypeConverter
|
|
11
13
|
import kotlin.reflect.KClass
|
|
@@ -110,6 +112,9 @@ object TypeConverterProviderImpl : TypeConverterProvider {
|
|
|
110
112
|
IntArray::class.createType(nullable = isOptional) to PrimitiveIntArrayTypeConverter(isOptional),
|
|
111
113
|
DoubleArray::class.createType(nullable = isOptional) to PrimitiveDoubleArrayTypeConverter(isOptional),
|
|
112
114
|
FloatArray::class.createType(nullable = isOptional) to PrimitiveFloatArrayTypeConverter(isOptional),
|
|
115
|
+
|
|
116
|
+
JavaScriptValue::class.createType(nullable = isOptional) to JavaScriptValueTypeConvert(isOptional),
|
|
117
|
+
JavaScriptObject::class.createType(nullable = isOptional) to JavaScriptObjectTypeConverter(isOptional),
|
|
113
118
|
)
|
|
114
119
|
}
|
|
115
120
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NativeModulesProxy.native.d.ts","sourceRoot":"","sources":["../src/NativeModulesProxy.native.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"NativeModulesProxy.native.d.ts","sourceRoot":"","sources":["../src/NativeModulesProxy.native.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAQ/D,QAAA,MAAM,kBAAkB,EAAE;IAAE,CAAC,UAAU,EAAE,MAAM,GAAG,iBAAiB,CAAA;CAAO,CAAC;AA0D3E,eAAe,kBAAkB,CAAC"}
|
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
import { NativeModules } from 'react-native';
|
|
2
|
-
const
|
|
2
|
+
const ExpoNativeProxy = global.ExpoModules?.NativeModulesProxy;
|
|
3
|
+
const LegacyNativeProxy = NativeModules.NativeUnimoduleProxy;
|
|
3
4
|
const modulesConstantsKey = 'modulesConstants';
|
|
4
5
|
const exportedMethodsKey = 'exportedMethods';
|
|
5
6
|
const NativeModulesProxy = {};
|
|
6
|
-
if (
|
|
7
|
+
if (LegacyNativeProxy) {
|
|
8
|
+
// use JSI proxy if available, fallback to legacy RN proxy
|
|
9
|
+
const NativeProxy = ExpoNativeProxy ?? LegacyNativeProxy;
|
|
7
10
|
Object.keys(NativeProxy[exportedMethodsKey]).forEach((moduleName) => {
|
|
11
|
+
// copy constants
|
|
8
12
|
NativeModulesProxy[moduleName] = NativeProxy[modulesConstantsKey][moduleName] || {};
|
|
13
|
+
// copy methods
|
|
9
14
|
NativeProxy[exportedMethodsKey][moduleName].forEach((methodInfo) => {
|
|
10
15
|
NativeModulesProxy[moduleName][methodInfo.name] = (...args) => {
|
|
11
16
|
const { key, argumentsCount } = methodInfo;
|
|
12
17
|
if (argumentsCount !== args.length) {
|
|
13
18
|
return Promise.reject(new Error(`Native method ${moduleName}.${methodInfo.name} expects ${argumentsCount} ${argumentsCount === 1 ? 'argument' : 'arguments'} but received ${args.length}`));
|
|
14
19
|
}
|
|
15
|
-
|
|
20
|
+
// We still want to call methods using the legacy proxy in SDK 46
|
|
21
|
+
return LegacyNativeProxy.callMethod(moduleName, key, args);
|
|
16
22
|
};
|
|
17
23
|
});
|
|
18
24
|
// These are called by EventEmitter (which is a wrapper for NativeEventEmitter)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NativeModulesProxy.native.js","sourceRoot":"","sources":["../src/NativeModulesProxy.native.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAI7C,MAAM,WAAW,GAAG,aAAa,CAAC,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"NativeModulesProxy.native.js","sourceRoot":"","sources":["../src/NativeModulesProxy.native.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAI7C,MAAM,eAAe,GAAG,MAAM,CAAC,WAAW,EAAE,kBAAkB,CAAC;AAC/D,MAAM,iBAAiB,GAAG,aAAa,CAAC,oBAAoB,CAAC;AAE7D,MAAM,mBAAmB,GAAG,kBAAkB,CAAC;AAC/C,MAAM,kBAAkB,GAAG,iBAAiB,CAAC;AAE7C,MAAM,kBAAkB,GAAgD,EAAE,CAAC;AAE3E,IAAI,iBAAiB,EAAE;IACrB,0DAA0D;IAC1D,MAAM,WAAW,GAAG,eAAe,IAAI,iBAAiB,CAAC;IAEzD,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,EAAE;QAClE,iBAAiB;QACjB,kBAAkB,CAAC,UAAU,CAAC,GAAG,WAAW,CAAC,mBAAmB,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;QAEpF,eAAe;QACf,WAAW,CAAC,kBAAkB,CAAC,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,EAAE;YACjE,kBAAkB,CAAC,UAAU,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAe,EAAgB,EAAE;gBACrF,MAAM,EAAE,GAAG,EAAE,cAAc,EAAE,GAAG,UAAU,CAAC;gBAC3C,IAAI,cAAc,KAAK,IAAI,CAAC,MAAM,EAAE;oBAClC,OAAO,OAAO,CAAC,MAAM,CACnB,IAAI,KAAK,CACP,iBAAiB,UAAU,IAAI,UAAU,CAAC,IAAI,YAAY,cAAc,IACtE,cAAc,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,WACtC,iBAAiB,IAAI,CAAC,MAAM,EAAE,CAC/B,CACF,CAAC;iBACH;gBAED,iEAAiE;gBACjE,OAAO,iBAAiB,CAAC,UAAU,CAAC,UAAU,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;YAC7D,CAAC,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,+EAA+E;QAC/E,kFAAkF;QAClF,EAAE;QACF,wEAAwE;QACxE,gDAAgD;QAChD,EAAE;QACF,6GAA6G;QAC7G,gGAAgG;QAChG,4HAA4H;QAC5H,qCAAqC;QACrC,IAAI,aAAa,CAAC,yBAAyB,EAAE;YAC3C,kBAAkB,CAAC,UAAU,CAAC,CAAC,WAAW,GAAG,CAAC,GAAG,IAAI,EAAE,EAAE,CACvD,aAAa,CAAC,yBAAyB,CAAC,kBAAkB,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,CAAC;YAClF,kBAAkB,CAAC,UAAU,CAAC,CAAC,eAAe,GAAG,CAAC,GAAG,IAAI,EAAE,EAAE,CAC3D,aAAa,CAAC,yBAAyB,CAAC,sBAAsB,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,CAAC;SACvF;aAAM;YACL,oBAAoB;YACpB,kHAAkH;YAClH,sHAAsH;YACtH,kBAAkB,CAAC,UAAU,CAAC,CAAC,WAAW,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;YACtD,kBAAkB,CAAC,UAAU,CAAC,CAAC,eAAe,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;SAC3D;IACH,CAAC,CAAC,CAAC;CACJ;KAAM;IACL,OAAO,CAAC,IAAI,CACV,gJAAgJ,CACjJ,CAAC;CACH;AAED,eAAe,kBAAkB,CAAC","sourcesContent":["import { NativeModules } from 'react-native';\n\nimport { ProxyNativeModule } from './NativeModulesProxy.types';\n\nconst ExpoNativeProxy = global.ExpoModules?.NativeModulesProxy;\nconst LegacyNativeProxy = NativeModules.NativeUnimoduleProxy;\n\nconst modulesConstantsKey = 'modulesConstants';\nconst exportedMethodsKey = 'exportedMethods';\n\nconst NativeModulesProxy: { [moduleName: string]: ProxyNativeModule } = {};\n\nif (LegacyNativeProxy) {\n // use JSI proxy if available, fallback to legacy RN proxy\n const NativeProxy = ExpoNativeProxy ?? LegacyNativeProxy;\n\n Object.keys(NativeProxy[exportedMethodsKey]).forEach((moduleName) => {\n // copy constants\n NativeModulesProxy[moduleName] = NativeProxy[modulesConstantsKey][moduleName] || {};\n\n // copy methods\n NativeProxy[exportedMethodsKey][moduleName].forEach((methodInfo) => {\n NativeModulesProxy[moduleName][methodInfo.name] = (...args: unknown[]): Promise<any> => {\n const { key, argumentsCount } = methodInfo;\n if (argumentsCount !== args.length) {\n return Promise.reject(\n new Error(\n `Native method ${moduleName}.${methodInfo.name} expects ${argumentsCount} ${\n argumentsCount === 1 ? 'argument' : 'arguments'\n } but received ${args.length}`\n )\n );\n }\n\n // We still want to call methods using the legacy proxy in SDK 46\n return LegacyNativeProxy.callMethod(moduleName, key, args);\n };\n });\n\n // These are called by EventEmitter (which is a wrapper for NativeEventEmitter)\n // only on iOS and they use iOS-specific native module, EXReactNativeEventEmitter.\n //\n // On Android only {start,stop}Observing are called on the native module\n // and these should be exported as Expo methods.\n //\n // Before the RN 65, addListener/removeListeners weren't called on Android. However, it no longer stays true.\n // See https://github.com/facebook/react-native/commit/f5502fbda9fe271ff6e1d0da773a3a8ee206a453.\n // That's why, we check if the `EXReactNativeEventEmitter` exists and only if yes, we use it in the listener implementation.\n // Otherwise, those methods are NOOP.\n if (NativeModules.EXReactNativeEventEmitter) {\n NativeModulesProxy[moduleName].addListener = (...args) =>\n NativeModules.EXReactNativeEventEmitter.addProxiedListener(moduleName, ...args);\n NativeModulesProxy[moduleName].removeListeners = (...args) =>\n NativeModules.EXReactNativeEventEmitter.removeProxiedListeners(moduleName, ...args);\n } else {\n // Fixes on Android:\n // WARN `new NativeEventEmitter()` was called with a non-null argument without the required `addListener` method.\n // WARN `new NativeEventEmitter()` was called with a non-null argument without the required `removeListeners` method.\n NativeModulesProxy[moduleName].addListener = () => {};\n NativeModulesProxy[moduleName].removeListeners = () => {};\n }\n });\n} else {\n console.warn(\n `The \"EXNativeModulesProxy\" native module is not exported through NativeModules; verify that expo-modules-core's native code is linked properly`\n );\n}\n\nexport default NativeModulesProxy;\n"]}
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
#import <ExpoModulesCore/EXLegacyAppDelegateWrapper.h>
|
|
4
4
|
|
|
5
5
|
#import <ExpoModulesCore/EXAppDelegatesLoader.h>
|
|
6
|
-
#import <ExpoModulesCore/EXNativeModulesProxy.h>
|
|
7
6
|
#import <ExpoModulesCore/Swift.h>
|
|
8
7
|
|
|
9
8
|
// Make the legacy wrapper conform to the protocol for subscribers.
|
|
@@ -17,7 +16,7 @@
|
|
|
17
16
|
// and before any code is executed, so we switch back to Objective-C just to do this one thing.
|
|
18
17
|
+ (void)load
|
|
19
18
|
{
|
|
20
|
-
ModulesProvider *modulesProvider = [
|
|
19
|
+
ModulesProvider *modulesProvider = [EXAppContext modulesProviderWithName:@"ExpoModulesProvider"];
|
|
21
20
|
[EXExpoAppDelegate registerSubscriber:[[EXLegacyAppDelegateWrapper alloc] init]];
|
|
22
21
|
[EXExpoAppDelegate registerSubscribersFromModulesProvider:modulesProvider];
|
|
23
22
|
[EXExpoAppDelegate registerReactDelegateHandlersFromModulesProvider:modulesProvider];
|