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.
Files changed (180) hide show
  1. package/CHANGELOG.md +33 -4
  2. package/ExpoModulesCore.podspec +1 -0
  3. package/README.md +1 -1
  4. package/android/ExpoModulesCorePlugin.gradle +16 -0
  5. package/android/build.gradle +3 -2
  6. package/android/src/main/cpp/Exceptions.cpp +8 -0
  7. package/android/src/main/cpp/Exceptions.h +11 -0
  8. package/android/src/main/cpp/ExpoModulesHostObject.cpp +22 -5
  9. package/android/src/main/cpp/ExpoModulesHostObject.h +5 -0
  10. package/android/src/main/cpp/JNIInjector.cpp +2 -0
  11. package/android/src/main/cpp/JSIInteropModuleRegistry.cpp +25 -1
  12. package/android/src/main/cpp/JSIInteropModuleRegistry.h +14 -0
  13. package/android/src/main/cpp/JSIObjectWrapper.h +15 -4
  14. package/android/src/main/cpp/JSITypeConverter.h +3 -2
  15. package/android/src/main/cpp/JavaReferencesCache.cpp +2 -0
  16. package/android/src/main/cpp/JavaScriptFunction.cpp +56 -0
  17. package/android/src/main/cpp/JavaScriptFunction.h +54 -0
  18. package/android/src/main/cpp/JavaScriptModuleObject.cpp +225 -105
  19. package/android/src/main/cpp/JavaScriptModuleObject.h +67 -34
  20. package/android/src/main/cpp/JavaScriptObject.cpp +55 -1
  21. package/android/src/main/cpp/JavaScriptObject.h +17 -13
  22. package/android/src/main/cpp/JavaScriptRuntime.cpp +12 -3
  23. package/android/src/main/cpp/JavaScriptRuntime.h +9 -1
  24. package/android/src/main/cpp/JavaScriptValue.cpp +9 -0
  25. package/android/src/main/cpp/JavaScriptValue.h +4 -0
  26. package/android/src/main/cpp/MethodMetadata.cpp +66 -87
  27. package/android/src/main/cpp/MethodMetadata.h +18 -16
  28. package/android/src/main/cpp/ObjectDeallocator.h +25 -0
  29. package/android/src/main/cpp/WeakRuntimeHolder.cpp +7 -0
  30. package/android/src/main/cpp/WeakRuntimeHolder.h +4 -0
  31. package/android/src/main/cpp/types/CppType.h +4 -1
  32. package/android/src/main/cpp/types/FrontendConverter.cpp +58 -0
  33. package/android/src/main/cpp/types/FrontendConverter.h +45 -0
  34. package/android/src/main/cpp/types/FrontendConverterProvider.cpp +3 -0
  35. package/android/src/main/cpp/types/JNIToJSIConverter.cpp +88 -0
  36. package/android/src/main/cpp/types/JNIToJSIConverter.h +22 -0
  37. package/android/src/main/java/com/facebook/react/uimanager/ReactStylesDiffMapHelper.kt +10 -0
  38. package/android/src/main/java/expo/modules/kotlin/AppContext.kt +18 -25
  39. package/android/src/main/java/expo/modules/kotlin/FilteredIterator.kt +37 -0
  40. package/android/src/main/java/expo/modules/kotlin/KotlinInteropModuleRegistry.kt +1 -1
  41. package/android/src/main/java/expo/modules/kotlin/ModuleHolder.kt +34 -21
  42. package/android/src/main/java/expo/modules/kotlin/ModuleRegistry.kt +13 -3
  43. package/android/src/main/java/expo/modules/kotlin/Utils.kt +21 -0
  44. package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultCaller.kt +21 -1
  45. package/android/src/main/java/expo/modules/kotlin/classcomponent/ClassComponentBuilder.kt +112 -0
  46. package/android/src/main/java/expo/modules/kotlin/classcomponent/ClassDefinitionData.kt +10 -0
  47. package/android/src/main/java/expo/modules/kotlin/exception/CodedException.kt +21 -0
  48. package/android/src/main/java/expo/modules/kotlin/exception/CommonExceptions.kt +15 -0
  49. package/android/src/main/java/expo/modules/kotlin/functions/AnyFunction.kt +17 -4
  50. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunction.kt +38 -8
  51. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionComponent.kt +3 -2
  52. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromiseComponent.kt +3 -2
  53. package/android/src/main/java/expo/modules/kotlin/functions/SuspendFunctionComponent.kt +1 -0
  54. package/android/src/main/java/expo/modules/kotlin/functions/SyncFunctionComponent.kt +18 -11
  55. package/android/src/main/java/expo/modules/kotlin/jni/CppType.kt +4 -1
  56. package/android/src/main/java/expo/modules/kotlin/jni/JNIDeallocator.kt +73 -0
  57. package/android/src/main/java/expo/modules/kotlin/jni/JSIInteropModuleRegistry.kt +28 -2
  58. package/android/src/main/java/expo/modules/kotlin/jni/JavaCallback.kt +8 -1
  59. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptFunction.kt +48 -0
  60. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptModuleObject.kt +40 -3
  61. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptObject.kt +23 -3
  62. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptValue.kt +26 -1
  63. package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +0 -11
  64. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +26 -16
  65. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionData.kt +3 -1
  66. package/android/src/main/java/expo/modules/kotlin/sharedobjects/SharedObject.kt +12 -0
  67. package/android/src/main/java/expo/modules/kotlin/sharedobjects/SharedObjectRegistry.kt +62 -0
  68. package/android/src/main/java/expo/modules/kotlin/sharedobjects/SharedObjectTypeConverter.kt +27 -0
  69. package/android/src/main/java/expo/modules/kotlin/types/AnyType.kt +2 -1
  70. package/android/src/main/java/expo/modules/kotlin/types/EitherTypeConverter.kt +7 -6
  71. package/android/src/main/java/expo/modules/kotlin/types/JavaScriptFunctionTypeConverter.kt +22 -0
  72. package/android/src/main/java/expo/modules/kotlin/types/TypeConverter.kt +30 -24
  73. package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +45 -1
  74. package/android/src/main/java/expo/modules/kotlin/types/TypedArrayTypeConverter.kt +3 -2
  75. package/android/src/main/java/expo/modules/kotlin/views/AnyViewProp.kt +3 -1
  76. package/android/src/main/java/expo/modules/kotlin/views/ConcreteViewProp.kt +3 -3
  77. package/android/src/main/java/expo/modules/kotlin/views/FilteredReadableMap.kt +53 -0
  78. package/android/src/main/java/expo/modules/kotlin/views/GroupViewManagerWrapper.kt +25 -5
  79. package/android/src/main/java/expo/modules/kotlin/views/SimpleViewManagerWrapper.kt +25 -5
  80. package/android/src/main/java/expo/modules/kotlin/views/ViewDefinitionBuilder.kt +161 -10
  81. package/android/src/main/java/expo/modules/kotlin/views/ViewGroupDefinitionBuilder.kt +0 -67
  82. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinition.kt +7 -8
  83. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerWrapperDelegate.kt +40 -3
  84. package/android/src/main/java/expo/modules/kotlin/views/ViewTypeConverter.kt +44 -0
  85. package/android-annotation/build.gradle +45 -0
  86. package/android-annotation/src/main/java/expo/modules/annotation/Config.kt +7 -0
  87. package/android-annotation/src/main/java/expo/modules/annotation/ConverterBinder.kt +7 -0
  88. package/android-annotation-processor/build.gradle +51 -0
  89. package/android-annotation-processor/src/main/java/expo/modules/annotationprocessor/ExpoSymbolProcessor.kt +175 -0
  90. package/android-annotation-processor/src/main/java/expo/modules/annotationprocessor/ExpoSymbolProcessorProvider.kt +10 -0
  91. package/android-annotation-processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider +1 -0
  92. package/build/NativeViewManagerAdapter.native.d.ts.map +1 -1
  93. package/build/NativeViewManagerAdapter.native.js +36 -23
  94. package/build/NativeViewManagerAdapter.native.js.map +1 -1
  95. package/build/requireNativeModule.js +2 -2
  96. package/build/requireNativeModule.js.map +1 -1
  97. package/common/cpp/fabric/ExpoViewProps.cpp +18 -3
  98. package/common/cpp/fabric/ExpoViewProps.h +4 -1
  99. package/ios/Fabric/ExpoFabricView.swift +10 -10
  100. package/ios/Fabric/ExpoFabricViewObjC.h +2 -0
  101. package/ios/Fabric/ExpoFabricViewObjC.mm +17 -2
  102. package/ios/JSI/EXJSIInstaller.mm +1 -1
  103. package/ios/JSI/EXJSIUtils.h +5 -0
  104. package/ios/JSI/EXJSIUtils.mm +17 -0
  105. package/ios/JSI/EXJavaScriptRuntime.h +5 -0
  106. package/ios/JSI/EXJavaScriptRuntime.mm +6 -0
  107. package/ios/JSI/EXJavaScriptValue.h +2 -0
  108. package/ios/JSI/EXJavaScriptValue.mm +8 -0
  109. package/ios/JSI/EXJavaScriptWeakObject.mm +29 -8
  110. package/ios/JSI/EXRawJavaScriptFunction.h +24 -0
  111. package/ios/JSI/EXRawJavaScriptFunction.mm +52 -0
  112. package/ios/JSI/ExpoModulesHostObject.mm +1 -1
  113. package/ios/JSI/JavaScriptValue.swift +28 -1
  114. package/ios/ModuleRegistry/EXModuleRegistry.h +0 -4
  115. package/ios/ModuleRegistry/EXModuleRegistry.m +0 -23
  116. package/ios/ModuleRegistryAdapter/EXModuleRegistryAdapter.m +0 -16
  117. package/ios/ModuleRegistryProvider/EXModuleRegistryProvider.m +0 -6
  118. package/ios/NativeModulesProxy/EXNativeModulesProxy.mm +1 -31
  119. package/ios/Swift/AppContext.swift +46 -6
  120. package/ios/Swift/Arguments/Convertible.swift +3 -3
  121. package/ios/Swift/Arguments/Convertibles.swift +5 -5
  122. package/ios/Swift/Classes/ClassComponent.swift +18 -12
  123. package/ios/Swift/Classes/ClassRegistry.swift +31 -0
  124. package/ios/Swift/Conversions.swift +19 -3
  125. package/ios/Swift/Convertibles/Convertibles+Color.swift +3 -3
  126. package/ios/Swift/Convertibles/Either.swift +6 -4
  127. package/ios/Swift/DynamicTypes/AnyDynamicType.swift +18 -2
  128. package/ios/Swift/DynamicTypes/DynamicArrayType.swift +3 -3
  129. package/ios/Swift/DynamicTypes/DynamicConvertibleType.swift +2 -2
  130. package/ios/Swift/DynamicTypes/DynamicEnumType.swift +1 -1
  131. package/ios/Swift/DynamicTypes/DynamicJavaScriptType.swift +27 -0
  132. package/ios/Swift/DynamicTypes/DynamicOptionalType.swift +9 -2
  133. package/ios/Swift/DynamicTypes/DynamicRawType.swift +1 -1
  134. package/ios/Swift/DynamicTypes/DynamicSharedObjectType.swift +16 -2
  135. package/ios/Swift/DynamicTypes/DynamicType.swift +6 -0
  136. package/ios/Swift/DynamicTypes/DynamicTypedArrayType.swift +15 -4
  137. package/ios/Swift/DynamicTypes/DynamicViewType.swift +68 -0
  138. package/ios/Swift/ExpoBridgeModule.swift +1 -1
  139. package/ios/Swift/Functions/AnyFunction.swift +5 -4
  140. package/ios/Swift/Functions/AsyncFunctionComponent.swift +22 -19
  141. package/ios/Swift/Functions/ConcurrentFunctionDefinition.swift +29 -13
  142. package/ios/Swift/Functions/SyncFunctionComponent.swift +26 -15
  143. package/ios/Swift/JavaScriptFunction.swift +68 -0
  144. package/ios/Swift/JavaScriptUtils.swift +57 -18
  145. package/ios/Swift/ModuleHolder.swift +22 -10
  146. package/ios/Swift/Modules/ModuleDefinition.swift +8 -2
  147. package/ios/Swift/Objects/JavaScriptObjectBuilder.swift +8 -8
  148. package/ios/Swift/Objects/ObjectDefinition.swift +17 -15
  149. package/ios/Swift/Objects/PropertyComponent.swift +23 -17
  150. package/ios/Swift/Records/AnyField.swift +1 -1
  151. package/ios/Swift/Records/Field.swift +2 -2
  152. package/ios/Swift/Records/Record.swift +5 -5
  153. package/ios/Swift/SharedObjects/SharedObjectRegistry.swift +4 -0
  154. package/ios/Swift/Views/AnyViewProp.swift +1 -1
  155. package/ios/Swift/Views/ComponentData.swift +37 -2
  156. package/ios/Swift/Views/ConcreteViewProp.swift +2 -2
  157. package/ios/Swift/Views/ViewDefinition.swift +39 -0
  158. package/ios/Swift/Views/ViewModuleWrapper.swift +0 -29
  159. package/ios/Tests/ClassComponentSpec.swift +39 -27
  160. package/ios/Tests/ConvertiblesSpec.swift +75 -49
  161. package/ios/Tests/DynamicTypeSpec.swift +29 -27
  162. package/ios/Tests/EitherSpec.swift +9 -7
  163. package/ios/Tests/ExpoModulesSpec.swift +13 -13
  164. package/ios/Tests/FunctionSpec.swift +38 -22
  165. package/ios/Tests/JavaScriptRuntimeSpec.swift +4 -0
  166. package/ios/Tests/PropertyComponentSpec.swift +33 -30
  167. package/ios/Tests/RecordSpec.swift +7 -5
  168. package/ios/Tests/SharedObjectRegistrySpec.swift +12 -12
  169. package/ios/Tests/TypedArraysSpec.swift +1 -1
  170. package/ios/Tests/ViewDefinitionSpec.swift +4 -2
  171. package/package.json +2 -2
  172. package/src/NativeViewManagerAdapter.native.tsx +33 -29
  173. package/src/requireNativeModule.ts +2 -2
  174. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinitionBuilder.kt +0 -132
  175. package/ios/EXViewManager.h +0 -21
  176. package/ios/EXViewManager.m +0 -128
  177. package/ios/ModuleRegistryAdapter/EXViewManagerAdapterClassesRegistry.h +0 -17
  178. package/ios/ModuleRegistryAdapter/EXViewManagerAdapterClassesRegistry.m +0 -67
  179. package/ios/ViewManagerAdapter/EXViewManagerAdapter.h +0 -17
  180. package/ios/ViewManagerAdapter/EXViewManagerAdapter.m +0 -45
@@ -4,17 +4,22 @@ package expo.modules.kotlin.types
4
4
 
5
5
  import android.graphics.Color
6
6
  import android.net.Uri
7
+ import android.view.View
7
8
  import com.facebook.react.bridge.Dynamic
8
9
  import com.facebook.react.bridge.ReadableArray
9
10
  import com.facebook.react.bridge.ReadableMap
11
+ import expo.modules.annotation.Config
10
12
  import expo.modules.kotlin.apifeatures.EitherType
11
13
  import expo.modules.kotlin.exception.MissingTypeConverter
12
14
  import expo.modules.kotlin.jni.CppType
13
15
  import expo.modules.kotlin.jni.ExpectedType
16
+ import expo.modules.kotlin.jni.JavaScriptFunction
14
17
  import expo.modules.kotlin.jni.JavaScriptObject
15
18
  import expo.modules.kotlin.jni.JavaScriptValue
16
19
  import expo.modules.kotlin.records.Record
17
20
  import expo.modules.kotlin.records.RecordTypeConverter
21
+ import expo.modules.kotlin.sharedobjects.SharedObject
22
+ import expo.modules.kotlin.sharedobjects.SharedObjectTypeConverter
18
23
  import expo.modules.kotlin.typedarray.BigInt64Array
19
24
  import expo.modules.kotlin.typedarray.BigUint64Array
20
25
  import expo.modules.kotlin.typedarray.Float32Array
@@ -32,6 +37,7 @@ import expo.modules.kotlin.types.io.PathTypeConverter
32
37
  import expo.modules.kotlin.types.net.JavaURITypeConverter
33
38
  import expo.modules.kotlin.types.net.URLTypConverter
34
39
  import expo.modules.kotlin.types.net.UriTypeConverter
40
+ import expo.modules.kotlin.views.ViewTypeConverter
35
41
  import java.io.File
36
42
  import java.net.URI
37
43
  import java.net.URL
@@ -69,6 +75,7 @@ fun convert(value: Dynamic, type: KType): Any? {
69
75
  object TypeConverterProviderImpl : TypeConverterProvider {
70
76
  private val cachedConverters = createCashedConverters(false) + createCashedConverters(true)
71
77
  private val cachedRecordConverters = mutableMapOf<KClass<*>, TypeConverter<*>>()
78
+ private val cachedCustomConverters = mutableMapOf<KType, TypeConverter<*>>()
72
79
 
73
80
  override fun obtainTypeConverter(type: KType): TypeConverter<*> {
74
81
  cachedConverters[type]?.let {
@@ -113,7 +120,21 @@ object TypeConverterProviderImpl : TypeConverterProvider {
113
120
  return converter
114
121
  }
115
122
 
116
- return handelEither(type, kClass) ?: throw MissingTypeConverter(type)
123
+ if (kClass.isSubclassOf(View::class)) {
124
+ return ViewTypeConverter<View>(type)
125
+ }
126
+
127
+ if (kClass.isSubclassOf(SharedObject::class)) {
128
+ return SharedObjectTypeConverter<SharedObject>(type)
129
+ }
130
+
131
+ if (kClass.isSubclassOf(JavaScriptFunction::class)) {
132
+ return JavaScriptFunctionTypeConverter<Any>(type)
133
+ }
134
+
135
+ return handelEither(type, kClass)
136
+ ?: handelCustomConverter(type, kClass)
137
+ ?: throw MissingTypeConverter(type)
117
138
  }
118
139
 
119
140
  @OptIn(EitherType::class)
@@ -131,6 +152,29 @@ object TypeConverterProviderImpl : TypeConverterProvider {
131
152
  return null
132
153
  }
133
154
 
155
+ private fun handelCustomConverter(type: KType, kClass: KClass<*>): TypeConverter<*>? {
156
+ val cachedConverter = cachedCustomConverters[type]
157
+ if (cachedConverter != null) {
158
+ return cachedConverter
159
+ }
160
+
161
+ val typeName = kClass.java.canonicalName ?: return null
162
+
163
+ val converterProviderName = "${Config.packageNamePrefix}$typeName${Config.classNameSuffix}"
164
+ return try {
165
+ val converterClazz = Class.forName(converterProviderName)
166
+ val converterProvider = converterClazz.newInstance()
167
+ val method = converterProvider.javaClass.getMethod(Config.converterProviderFunctionName, KType::class.java)
168
+
169
+ (method.invoke(converterProvider, type) as TypeConverter<*>)
170
+ .also {
171
+ cachedCustomConverters[type] = it
172
+ }
173
+ } catch (e: Throwable) {
174
+ null
175
+ }
176
+ }
177
+
134
178
  private fun createCashedConverters(isOptional: Boolean): Map<KType, TypeConverter<*>> {
135
179
  val intTypeConverter = createTrivialTypeConverter(
136
180
  isOptional, ExpectedType(CppType.INT)
@@ -1,5 +1,6 @@
1
1
  package expo.modules.kotlin.types
2
2
 
3
+ import expo.modules.kotlin.AppContext
3
4
  import expo.modules.kotlin.jni.CppType
4
5
  import expo.modules.kotlin.jni.ExpectedType
5
6
  import expo.modules.kotlin.jni.JavaScriptTypedArray
@@ -16,8 +17,8 @@ import expo.modules.kotlin.typedarray.Uint32Array
16
17
  import expo.modules.kotlin.typedarray.Uint8Array
17
18
  import expo.modules.kotlin.typedarray.Uint8ClampedArray
18
19
 
19
- abstract class BaseTypeArrayConverter<T : TypedArray>(isOptional: Boolean) : TypeConverter<T>(isOptional) {
20
- override fun convertNonOptional(value: Any): T = wrapJavaScriptTypedArray(value as JavaScriptTypedArray)
20
+ abstract class BaseTypeArrayConverter<T : TypedArray>(isOptional: Boolean) : NullAwareTypeConverter<T>(isOptional) {
21
+ override fun convertNonOptional(value: Any, context: AppContext?): T = wrapJavaScriptTypedArray(value as JavaScriptTypedArray)
21
22
  override fun getCppRequiredTypes(): ExpectedType = ExpectedType(CppType.TYPED_ARRAY)
22
23
  override fun isTrivial() = false
23
24
 
@@ -2,9 +2,11 @@ package expo.modules.kotlin.views
2
2
 
3
3
  import android.view.View
4
4
  import com.facebook.react.bridge.Dynamic
5
+ import expo.modules.kotlin.types.AnyType
5
6
 
6
7
  abstract class AnyViewProp(
7
- val name: String
8
+ val name: String,
9
+ internal val type: AnyType
8
10
  ) {
9
11
  abstract fun set(prop: Dynamic, onView: View)
10
12
 
@@ -8,16 +8,16 @@ import expo.modules.kotlin.types.AnyType
8
8
 
9
9
  class ConcreteViewProp<ViewType : View, PropType>(
10
10
  name: String,
11
- private val propType: AnyType,
11
+ propType: AnyType,
12
12
  private val setter: (view: ViewType, prop: PropType) -> Unit,
13
- ) : AnyViewProp(name) {
13
+ ) : AnyViewProp(name, propType) {
14
14
 
15
15
  @Suppress("UNCHECKED_CAST")
16
16
  override fun set(prop: Dynamic, onView: View) {
17
17
  exceptionDecorator({
18
18
  PropSetException(name, onView::class, it)
19
19
  }) {
20
- setter(onView as ViewType, propType.convert(prop) as PropType)
20
+ setter(onView as ViewType, type.convert(prop) as PropType)
21
21
  }
22
22
  }
23
23
 
@@ -0,0 +1,53 @@
1
+ package expo.modules.kotlin.views
2
+
3
+ import com.facebook.react.bridge.ReadableMap
4
+ import com.facebook.react.bridge.ReadableMapKeySetIterator
5
+ import expo.modules.kotlin.Filter
6
+ import expo.modules.kotlin.FilteredIterator
7
+
8
+ class FilteredReadableMapKeySetIterator(
9
+ private val iterator: ReadableMapKeySetIterator,
10
+ private val filter: Filter<String>
11
+ ) : ReadableMapKeySetIterator {
12
+ private var next: String? = null
13
+
14
+ init {
15
+ this.findNext()
16
+ }
17
+
18
+ override fun hasNextKey(): Boolean {
19
+ return next != null
20
+ }
21
+
22
+ override fun nextKey(): String {
23
+ val returnValue = next!!
24
+ this.findNext()
25
+ return returnValue
26
+ }
27
+
28
+ private fun findNext() {
29
+ while (iterator.hasNextKey()) {
30
+ val next = iterator.nextKey()
31
+ this.next = next
32
+ if (filter.apply(next)) {
33
+ return
34
+ }
35
+ }
36
+ next = null
37
+ }
38
+ }
39
+
40
+ class FilteredReadableMap(
41
+ private val backingMap: ReadableMap,
42
+ private val filteredKeys: List<String>
43
+ ) : ReadableMap by backingMap {
44
+ override fun getEntryIterator(): Iterator<Map.Entry<String, Any>> =
45
+ FilteredIterator(backingMap.entryIterator) {
46
+ !filteredKeys.contains(it.key)
47
+ }
48
+
49
+ override fun keySetIterator(): ReadableMapKeySetIterator =
50
+ FilteredReadableMapKeySetIterator(backingMap.keySetIterator()) {
51
+ !filteredKeys.contains(it)
52
+ }
53
+ }
@@ -2,11 +2,11 @@ package expo.modules.kotlin.views
2
2
 
3
3
  import android.view.View
4
4
  import android.view.ViewGroup
5
- import com.facebook.react.bridge.ReadableMap
6
5
  import com.facebook.react.common.MapBuilder
6
+ import com.facebook.react.uimanager.ReactStylesDiffMap
7
7
  import com.facebook.react.uimanager.ThemedReactContext
8
8
  import com.facebook.react.uimanager.ViewGroupManager
9
- import com.facebook.react.uimanager.annotations.ReactProp
9
+ import com.facebook.react.uimanager.getBackingMap
10
10
  import expo.modules.core.utilities.ifNull
11
11
 
12
12
  class GroupViewManagerWrapper(
@@ -17,9 +17,29 @@ class GroupViewManagerWrapper(
17
17
  override fun createViewInstance(reactContext: ThemedReactContext): ViewGroup =
18
18
  viewWrapperDelegate.createView(reactContext) as ViewGroup
19
19
 
20
- @ReactProp(name = "proxiedProperties")
21
- fun setProxiedProperties(view: View, proxiedProperties: ReadableMap) {
22
- viewWrapperDelegate.setProxiedProperties(view, proxiedProperties)
20
+ override fun updateProperties(viewToUpdate: ViewGroup, props: ReactStylesDiffMap) {
21
+ val propsMap = props.getBackingMap()
22
+ // Updates expo related properties.
23
+ val handledProps = viewWrapperDelegate.updateProperties(viewToUpdate, propsMap)
24
+ // Updates remaining props using RN implementation.
25
+ // To not triggered undefined setters we filtrated already handled properties.
26
+ super.updateProperties(
27
+ viewToUpdate,
28
+ ReactStylesDiffMap(FilteredReadableMap(propsMap, handledProps))
29
+ )
30
+ }
31
+
32
+ override fun onAfterUpdateTransaction(view: ViewGroup) {
33
+ super.onAfterUpdateTransaction(view)
34
+ viewWrapperDelegate.onViewDidUpdateProps(view)
35
+ }
36
+
37
+ override fun getNativeProps(): MutableMap<String, String> {
38
+ val props = super.getNativeProps()
39
+ viewWrapperDelegate.props.forEach { (key, prop) ->
40
+ props[key] = prop.type.kType.toString()
41
+ }
42
+ return props
23
43
  }
24
44
 
25
45
  override fun onDropViewInstance(view: ViewGroup) {
@@ -1,11 +1,11 @@
1
1
  package expo.modules.kotlin.views
2
2
 
3
3
  import android.view.View
4
- import com.facebook.react.bridge.ReadableMap
5
4
  import com.facebook.react.common.MapBuilder
5
+ import com.facebook.react.uimanager.ReactStylesDiffMap
6
6
  import com.facebook.react.uimanager.SimpleViewManager
7
7
  import com.facebook.react.uimanager.ThemedReactContext
8
- import com.facebook.react.uimanager.annotations.ReactProp
8
+ import com.facebook.react.uimanager.getBackingMap
9
9
 
10
10
  class SimpleViewManagerWrapper(
11
11
  override val viewWrapperDelegate: ViewManagerWrapperDelegate
@@ -15,9 +15,29 @@ class SimpleViewManagerWrapper(
15
15
  override fun createViewInstance(reactContext: ThemedReactContext): View =
16
16
  viewWrapperDelegate.createView(reactContext)
17
17
 
18
- @ReactProp(name = "proxiedProperties")
19
- fun setProxiedProperties(view: View, proxiedProperties: ReadableMap) {
20
- viewWrapperDelegate.setProxiedProperties(view, proxiedProperties)
18
+ override fun updateProperties(viewToUpdate: View, props: ReactStylesDiffMap) {
19
+ val propsMap = props.getBackingMap()
20
+ // Updates expo related properties.
21
+ val handledProps = viewWrapperDelegate.updateProperties(viewToUpdate, propsMap)
22
+ // Updates remaining props using RN implementation.
23
+ // To not triggered undefined setters we filtrated already handled properties.
24
+ super.updateProperties(
25
+ viewToUpdate,
26
+ ReactStylesDiffMap(FilteredReadableMap(propsMap, handledProps))
27
+ )
28
+ }
29
+
30
+ override fun onAfterUpdateTransaction(view: View) {
31
+ super.onAfterUpdateTransaction(view)
32
+ viewWrapperDelegate.onViewDidUpdateProps(view)
33
+ }
34
+
35
+ override fun getNativeProps(): MutableMap<String, String> {
36
+ val props = super.getNativeProps()
37
+ viewWrapperDelegate.props.forEach { (key, prop) ->
38
+ props[key] = prop.type.kType.toString()
39
+ }
40
+ return props
21
41
  }
22
42
 
23
43
  override fun onDropViewInstance(view: View) {
@@ -8,17 +8,27 @@ import android.util.Log
8
8
  import android.view.View
9
9
  import android.view.ViewGroup
10
10
  import expo.modules.kotlin.AppContext
11
+ import expo.modules.kotlin.Promise
11
12
  import expo.modules.kotlin.exception.CodedException
12
13
  import expo.modules.kotlin.exception.UnexpectedException
14
+ import expo.modules.kotlin.functions.AsyncFunction
15
+ import expo.modules.kotlin.functions.AsyncFunctionBuilder
16
+ import expo.modules.kotlin.functions.AsyncFunctionComponent
17
+ import expo.modules.kotlin.functions.AsyncFunctionWithPromiseComponent
18
+ import expo.modules.kotlin.functions.Queues
13
19
  import expo.modules.kotlin.modules.DefinitionMarker
14
20
  import expo.modules.kotlin.types.toAnyType
15
21
  import kotlin.reflect.KClass
16
22
  import kotlin.reflect.KFunction
23
+ import kotlin.reflect.KType
17
24
  import kotlin.reflect.full.primaryConstructor
18
25
  import kotlin.reflect.typeOf
19
26
 
20
27
  @DefinitionMarker
21
- class ViewDefinitionBuilder<T : View>(@PublishedApi internal val viewType: KClass<T>) {
28
+ class ViewDefinitionBuilder<T : View>(
29
+ @PublishedApi internal val viewClass: KClass<T>,
30
+ @PublishedApi internal val viewType: KType
31
+ ) {
22
32
  @PublishedApi
23
33
  internal var props = mutableMapOf<String, AnyViewProp>()
24
34
 
@@ -32,16 +42,29 @@ class ViewDefinitionBuilder<T : View>(@PublishedApi internal val viewType: KClas
32
42
  internal var viewGroupDefinition: ViewGroupDefinition? = null
33
43
  private var callbacksDefinition: CallbacksDefinition? = null
34
44
 
35
- fun build(): ViewManagerDefinition =
36
- ViewManagerDefinition(
45
+ @PublishedApi
46
+ internal var asyncFunctions = mutableMapOf<String, AsyncFunction>()
47
+
48
+ private var functionBuilders = mutableMapOf<String, AsyncFunctionBuilder>()
49
+
50
+ fun build(): ViewManagerDefinition {
51
+ val asyncFunctions = asyncFunctions + functionBuilders.mapValues { (_, value) -> value.build() }
52
+ asyncFunctions.forEach { (_, function) ->
53
+ function.runOnQueue(Queues.MAIN)
54
+ function.ownerType = viewType
55
+ }
56
+
57
+ return ViewManagerDefinition(
37
58
  viewFactory = createViewFactory(),
38
- viewType = viewType.java,
59
+ viewType = viewClass.java,
39
60
  props = props,
40
61
  onViewDestroys = onViewDestroys,
41
62
  callbacksDefinition = callbacksDefinition,
42
63
  viewGroupDefinition = viewGroupDefinition,
43
- onViewDidUpdateProps = onViewDidUpdateProps
64
+ onViewDidUpdateProps = onViewDidUpdateProps,
65
+ asyncFunctions = asyncFunctions.values.toList(),
44
66
  )
67
+ }
45
68
 
46
69
  /**
47
70
  * Creates view's lifecycle listener that is called right after the view isn't longer used by React Native.
@@ -127,7 +150,7 @@ class ViewDefinitionBuilder<T : View>(@PublishedApi internal val viewType: KClas
127
150
  * Creates the group view definition that scopes group view-related definitions.
128
151
  */
129
152
  inline fun <reified ParentType : ViewGroup> GroupView(body: ViewGroupDefinitionBuilder<ParentType>.() -> Unit) {
130
- assert(viewType == ParentType::class) { "Provided type and view type have to be the same." }
153
+ assert(viewClass == ParentType::class) { "Provided type and view type have to be the same." }
131
154
  require(viewGroupDefinition == null) { "The viewManager definition may have exported only one groupView definition." }
132
155
 
133
156
  val groupViewDefinitionBuilder = ViewGroupDefinitionBuilder<ParentType>()
@@ -135,8 +158,136 @@ class ViewDefinitionBuilder<T : View>(@PublishedApi internal val viewType: KClas
135
158
  viewGroupDefinition = groupViewDefinitionBuilder.build()
136
159
  }
137
160
 
161
+ @JvmName("AsyncFunctionWithoutArgs")
162
+ inline fun AsyncFunction(
163
+ name: String,
164
+ crossinline body: () -> Any?
165
+ ): AsyncFunction {
166
+ return AsyncFunctionComponent(name, arrayOf()) { body() }.also {
167
+ asyncFunctions[name] = it
168
+ }
169
+ }
170
+
171
+ inline fun <reified R> AsyncFunction(
172
+ name: String,
173
+ crossinline body: () -> R
174
+ ): AsyncFunction {
175
+ return AsyncFunctionComponent(name, arrayOf()) { body() }.also {
176
+ asyncFunctions[name] = it
177
+ }
178
+ }
179
+
180
+ inline fun <reified R, reified P0> AsyncFunction(
181
+ name: String,
182
+ crossinline body: (p0: P0) -> R
183
+ ): AsyncFunction {
184
+ return if (P0::class == Promise::class) {
185
+ AsyncFunctionWithPromiseComponent(name, arrayOf()) { _, promise -> body(promise as P0) }
186
+ } else {
187
+ AsyncFunctionComponent(name, arrayOf(typeOf<P0>().toAnyType())) { body(it[0] as P0) }
188
+ }.also {
189
+ it.ownerType = viewType
190
+ asyncFunctions[name] = it
191
+ }
192
+ }
193
+
194
+ inline fun <reified R, reified P0, reified P1> AsyncFunction(
195
+ name: String,
196
+ crossinline body: (p0: P0, p1: P1) -> R
197
+ ): AsyncFunction {
198
+ return if (P1::class == Promise::class) {
199
+ AsyncFunctionWithPromiseComponent(name, arrayOf(typeOf<P0>().toAnyType())) { args, promise -> body(args[0] as P0, promise as P1) }
200
+ } else {
201
+ AsyncFunctionComponent(name, arrayOf(typeOf<P0>().toAnyType(), typeOf<P1>().toAnyType())) { body(it[0] as P0, it[1] as P1) }
202
+ }.also {
203
+ asyncFunctions[name] = it
204
+ }
205
+ }
206
+
207
+ inline fun <reified R, reified P0, reified P1, reified P2> AsyncFunction(
208
+ name: String,
209
+ crossinline body: (p0: P0, p1: P1, p2: P2) -> R
210
+ ): AsyncFunction {
211
+ return if (P2::class == Promise::class) {
212
+ AsyncFunctionWithPromiseComponent(name, arrayOf(typeOf<P0>().toAnyType(), typeOf<P1>().toAnyType())) { args, promise -> body(args[0] as P0, args[1] as P1, promise as P2) }
213
+ } else {
214
+ AsyncFunctionComponent(name, arrayOf(typeOf<P0>().toAnyType(), typeOf<P1>().toAnyType(), typeOf<P2>().toAnyType())) { body(it[0] as P0, it[1] as P1, it[2] as P2) }
215
+ }.also {
216
+ asyncFunctions[name] = it
217
+ }
218
+ }
219
+
220
+ inline fun <reified R, reified P0, reified P1, reified P2, reified P3> AsyncFunction(
221
+ name: String,
222
+ crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3) -> R
223
+ ): AsyncFunction {
224
+ return if (P3::class == Promise::class) {
225
+ AsyncFunctionWithPromiseComponent(name, arrayOf(typeOf<P0>().toAnyType(), typeOf<P1>().toAnyType(), typeOf<P2>().toAnyType())) { args, promise -> body(args[0] as P0, args[1] as P1, args[2] as P2, promise as P3) }
226
+ } else {
227
+ AsyncFunctionComponent(name, arrayOf(typeOf<P0>().toAnyType(), typeOf<P1>().toAnyType(), typeOf<P2>().toAnyType(), typeOf<P3>().toAnyType())) { body(it[0] as P0, it[1] as P1, it[2] as P2, it[3] as P3) }
228
+ }.also {
229
+ asyncFunctions[name] = it
230
+ }
231
+ }
232
+
233
+ inline fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4> AsyncFunction(
234
+ name: String,
235
+ crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4) -> R
236
+ ): AsyncFunction {
237
+ return if (P4::class == Promise::class) {
238
+ AsyncFunctionWithPromiseComponent(name, arrayOf(typeOf<P0>().toAnyType(), typeOf<P1>().toAnyType(), typeOf<P2>().toAnyType(), typeOf<P3>().toAnyType())) { args, promise -> body(args[0] as P0, args[1] as P1, args[2] as P2, args[3] as P3, promise as P4) }
239
+ } else {
240
+ AsyncFunctionComponent(name, arrayOf(typeOf<P0>().toAnyType(), typeOf<P1>().toAnyType(), typeOf<P2>().toAnyType(), typeOf<P3>().toAnyType(), typeOf<P4>().toAnyType())) { body(it[0] as P0, it[1] as P1, it[2] as P2, it[3] as P3, it[4] as P4) }
241
+ }.also {
242
+ asyncFunctions[name] = it
243
+ }
244
+ }
245
+
246
+ inline fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4, reified P5> AsyncFunction(
247
+ name: String,
248
+ crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5) -> R
249
+ ): AsyncFunction {
250
+ return if (P5::class == Promise::class) {
251
+ AsyncFunctionWithPromiseComponent(name, arrayOf(typeOf<P0>().toAnyType(), typeOf<P1>().toAnyType(), typeOf<P2>().toAnyType(), typeOf<P3>().toAnyType(), typeOf<P4>().toAnyType())) { args, promise -> body(args[0] as P0, args[1] as P1, args[2] as P2, args[3] as P3, args[4] as P4, promise as P5) }
252
+ } else {
253
+ AsyncFunctionComponent(name, arrayOf(typeOf<P0>().toAnyType(), typeOf<P1>().toAnyType(), typeOf<P2>().toAnyType(), typeOf<P3>().toAnyType(), typeOf<P4>().toAnyType(), typeOf<P5>().toAnyType())) { body(it[0] as P0, it[1] as P1, it[2] as P2, it[3] as P3, it[4] as P4, it[5] as P5) }
254
+ }.also {
255
+ asyncFunctions[name] = it
256
+ }
257
+ }
258
+
259
+ inline fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4, reified P5, reified P6> AsyncFunction(
260
+ name: String,
261
+ crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6) -> R
262
+ ): AsyncFunction {
263
+ return if (P6::class == Promise::class) {
264
+ AsyncFunctionWithPromiseComponent(name, arrayOf(typeOf<P0>().toAnyType(), typeOf<P1>().toAnyType(), typeOf<P2>().toAnyType(), typeOf<P3>().toAnyType(), typeOf<P4>().toAnyType(), typeOf<P5>().toAnyType())) { args, promise -> body(args[0] as P0, args[1] as P1, args[2] as P2, args[3] as P3, args[4] as P4, args[5] as P5, promise as P6) }
265
+ } else {
266
+ AsyncFunctionComponent(name, arrayOf(typeOf<P0>().toAnyType(), typeOf<P1>().toAnyType(), typeOf<P2>().toAnyType(), typeOf<P3>().toAnyType(), typeOf<P4>().toAnyType(), typeOf<P5>().toAnyType(), typeOf<P6>().toAnyType())) { body(it[0] as P0, it[1] as P1, it[2] as P2, it[3] as P3, it[4] as P4, it[5] as P5, it[6] as P6) }
267
+ }.also {
268
+ asyncFunctions[name] = it
269
+ }
270
+ }
271
+
272
+ inline fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4, reified P5, reified P6, reified P7> AsyncFunction(
273
+ name: String,
274
+ crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7) -> R
275
+ ): AsyncFunction {
276
+ return if (P7::class == Promise::class) {
277
+ AsyncFunctionWithPromiseComponent(name, arrayOf(typeOf<P0>().toAnyType(), typeOf<P1>().toAnyType(), typeOf<P2>().toAnyType(), typeOf<P3>().toAnyType(), typeOf<P4>().toAnyType(), typeOf<P5>().toAnyType(), typeOf<P6>().toAnyType())) { args, promise -> body(args[0] as P0, args[1] as P1, args[2] as P2, args[3] as P3, args[4] as P4, args[5] as P5, args[6] as P6, promise as P7) }
278
+ } else {
279
+ AsyncFunctionComponent(name, arrayOf(typeOf<P0>().toAnyType(), typeOf<P1>().toAnyType(), typeOf<P2>().toAnyType(), typeOf<P3>().toAnyType(), typeOf<P4>().toAnyType(), typeOf<P5>().toAnyType(), typeOf<P6>().toAnyType(), typeOf<P7>().toAnyType())) { body(it[0] as P0, it[1] as P1, it[2] as P2, it[3] as P3, it[4] as P4, it[5] as P5, it[6] as P6, it[7] as P7) }
280
+ }.also {
281
+ asyncFunctions[name] = it
282
+ }
283
+ }
284
+
285
+ fun AsyncFunction(
286
+ name: String
287
+ ) = AsyncFunctionBuilder(name).also { functionBuilders[name] = it }
288
+
138
289
  private fun createViewFactory(): (Context, AppContext) -> View = viewFactory@{ context: Context, appContext: AppContext ->
139
- val primaryConstructor = requireNotNull(getPrimaryConstructor()) { "$viewType doesn't have a primary constructor" }
290
+ val primaryConstructor = requireNotNull(getPrimaryConstructor()) { "$viewClass doesn't have a primary constructor" }
140
291
  val args = primaryConstructor.parameters
141
292
 
142
293
  if (args.isEmpty()) {
@@ -174,7 +325,7 @@ class ViewDefinitionBuilder<T : View>(@PublishedApi internal val viewType: KClas
174
325
  }
175
326
 
176
327
  private fun handleFailureDuringViewCreation(context: Context, appContext: AppContext, e: Throwable): View {
177
- Log.e("ExpoModulesCore", "Couldn't create view of type $viewType", e)
328
+ Log.e("ExpoModulesCore", "Couldn't create view of type $viewClass", e)
178
329
 
179
330
  appContext.errorManager?.reportExceptionToLogBox(
180
331
  if (e is CodedException) {
@@ -187,12 +338,12 @@ class ViewDefinitionBuilder<T : View>(@PublishedApi internal val viewType: KClas
187
338
  }
188
339
 
189
340
  private fun getPrimaryConstructor(): KFunction<T>? {
190
- val kotlinContractor = viewType.primaryConstructor
341
+ val kotlinContractor = viewClass.primaryConstructor
191
342
  if (kotlinContractor != null) {
192
343
  return kotlinContractor
193
344
  }
194
345
 
195
346
  // Add compatibility with Java
196
- return viewType.constructors.firstOrNull()
347
+ return viewClass.constructors.firstOrNull()
197
348
  }
198
349
  }
@@ -76,70 +76,3 @@ class ViewGroupDefinitionBuilder<ParentType : ViewGroup> {
76
76
  }
77
77
  }
78
78
  }
79
-
80
- @Deprecated("Use `ViewGroupDefinitionBuilder` instead.")
81
- @DefinitionMarker
82
- class ViewGroupDefinitionLegacyBuilder {
83
- @PublishedApi
84
- internal var addViewAction: AddViewAction? = null
85
-
86
- @PublishedApi
87
- internal var getChildAtAction: GetChildAtAction? = null
88
-
89
- @PublishedApi
90
- internal var getChildCountAction: GetChildCountAction? = null
91
-
92
- @PublishedApi
93
- internal var removeViewAction: RemoveViewAction? = null
94
-
95
- @PublishedApi
96
- internal var removeViewAtAction: RemoveViewAtAction? = null
97
-
98
- fun build() = ViewGroupDefinition(
99
- addViewAction,
100
- getChildAtAction,
101
- getChildCountAction,
102
- removeViewAction,
103
- removeViewAtAction
104
- )
105
-
106
- inline fun <reified ParentViewType : ViewGroup, reified ChildViewType : View> AddChildView(
107
- noinline body: (parent: ParentViewType, child: ChildViewType, index: Int) -> Unit
108
- ) {
109
- addViewAction = { parent, child, index ->
110
- body(parent as ParentViewType, child as ChildViewType, index)
111
- }
112
- }
113
-
114
- inline fun <reified ParentViewType : ViewGroup> GetChildCount(
115
- noinline body: (view: ParentViewType) -> Int
116
- ) {
117
- getChildCountAction = { view ->
118
- body(view as ParentViewType)
119
- }
120
- }
121
-
122
- inline fun <reified ParentViewType : ViewGroup, reified ChildViewType : View> GetChildViewAt(
123
- noinline body: (view: ParentViewType, index: Int) -> ChildViewType?
124
- ) {
125
- getChildAtAction = { view, index ->
126
- body(view as ParentViewType, index)
127
- }
128
- }
129
-
130
- inline fun <reified ParentViewType : ViewGroup> RemoveChildViewAt(
131
- noinline body: (view: ParentViewType, index: Int) -> Unit
132
- ) {
133
- removeViewAtAction = { view, index ->
134
- body(view as ParentViewType, index)
135
- }
136
- }
137
-
138
- inline fun <reified ParentViewType : ViewGroup, reified ChildViewType : View> RemoveChildView(
139
- noinline body: (parent: ParentViewType, child: ChildViewType) -> Unit
140
- ) {
141
- removeViewAction = { view, child ->
142
- body(view as ParentViewType, child as ChildViewType)
143
- }
144
- }
145
- }
@@ -10,18 +10,20 @@ import expo.modules.core.ViewManager
10
10
  import expo.modules.kotlin.AppContext
11
11
  import expo.modules.kotlin.DynamicNull
12
12
  import expo.modules.kotlin.exception.CodedException
13
- import expo.modules.kotlin.exception.UnexpectedException
13
+ import expo.modules.kotlin.exception.toCodedException
14
+ import expo.modules.kotlin.functions.BaseAsyncFunctionComponent
14
15
  import expo.modules.kotlin.logger
15
16
  import expo.modules.kotlin.recycle
16
17
 
17
18
  class ViewManagerDefinition(
18
19
  private val viewFactory: (Context, AppContext) -> View,
19
- private val viewType: Class<out View>,
20
- private val props: Map<String, AnyViewProp>,
20
+ internal val viewType: Class<out View>,
21
+ internal val props: Map<String, AnyViewProp>,
21
22
  val onViewDestroys: ((View) -> Unit)? = null,
22
23
  val callbacksDefinition: CallbacksDefinition? = null,
23
24
  val viewGroupDefinition: ViewGroupDefinition? = null,
24
- val onViewDidUpdateProps: ((View) -> Unit)? = null
25
+ val onViewDidUpdateProps: ((View) -> Unit)? = null,
26
+ val asyncFunctions: List<BaseAsyncFunctionComponent> = emptyList()
25
27
  ) {
26
28
 
27
29
  fun createView(context: Context, appContext: AppContext): View = viewFactory(context, appContext)
@@ -53,10 +55,7 @@ class ViewManagerDefinition(
53
55
 
54
56
  handleException(
55
57
  onView,
56
- when (exception) {
57
- is CodedException -> exception
58
- else -> UnexpectedException(exception)
59
- }
58
+ exception.toCodedException()
60
59
  )
61
60
  }
62
61
  }