expo-modules-core 0.6.5 → 0.9.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 (219) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/README.md +1 -1
  3. package/android/ExpoModulesCorePlugin.gradle +15 -0
  4. package/android/build.gradle +31 -15
  5. package/android/src/main/java/expo/modules/adapters/react/NativeModulesProxy.java +5 -5
  6. package/android/src/main/java/expo/modules/adapters/react/services/UIManagerModuleWrapper.java +13 -0
  7. package/android/src/main/java/expo/modules/core/ViewManager.java +9 -0
  8. package/android/src/main/java/expo/modules/core/interfaces/JavaScriptContextProvider.java +4 -0
  9. package/android/src/main/java/expo/modules/core/interfaces/ReactActivityHandler.java +37 -1
  10. package/android/src/main/java/expo/modules/core/interfaces/ReactNativeHostHandler.java +30 -0
  11. package/android/src/main/java/expo/modules/core/interfaces/services/UIManager.java +2 -0
  12. package/android/src/main/java/expo/modules/kotlin/AppContext.kt +23 -5
  13. package/android/src/main/java/expo/modules/kotlin/DynamicExtenstions.kt +5 -3
  14. package/android/src/main/java/expo/modules/kotlin/KPromiseWrapper.kt +3 -8
  15. package/android/src/main/java/expo/modules/kotlin/KotlinInteropModuleRegistry.kt +24 -9
  16. package/android/src/main/java/expo/modules/kotlin/ModuleHolder.kt +12 -7
  17. package/android/src/main/java/expo/modules/kotlin/ModuleRegistry.kt +23 -1
  18. package/android/src/main/java/expo/modules/kotlin/Promise.kt +1 -1
  19. package/android/src/main/java/expo/modules/kotlin/callbacks/Callback.kt +5 -0
  20. package/android/src/main/java/expo/modules/kotlin/callbacks/ViewCallback.kt +39 -0
  21. package/android/src/main/java/expo/modules/kotlin/callbacks/ViewCallbackDelegate.kt +27 -0
  22. package/android/src/main/java/expo/modules/kotlin/defaultmodules/ErrorManagerModule.kt +25 -0
  23. package/android/src/main/java/expo/modules/kotlin/events/EventEmitter.kt +13 -0
  24. package/android/src/main/java/expo/modules/kotlin/events/KModuleEventEmitterWrapper.kt +102 -0
  25. package/android/src/main/java/expo/modules/kotlin/exception/CodedException.kt +93 -9
  26. package/android/src/main/java/expo/modules/kotlin/exception/ExceptionDecorator.kt +11 -0
  27. package/android/src/main/java/expo/modules/kotlin/{methods/AnyMethod.kt → functions/AnyFunction.kt} +18 -18
  28. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunction.kt +15 -0
  29. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionBuilder.kt +170 -0
  30. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromise.kt +15 -0
  31. package/android/src/main/java/expo/modules/kotlin/functions/AsyncSuspendFunction.kt +36 -0
  32. package/android/src/main/java/expo/modules/kotlin/modules/DefinitionMarker.kt +4 -0
  33. package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +17 -2
  34. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +416 -43
  35. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionData.kt +2 -2
  36. package/android/src/main/java/expo/modules/kotlin/records/FieldValidator.kt +139 -0
  37. package/android/src/main/java/expo/modules/kotlin/records/RecordTypeConverter.kt +71 -15
  38. package/android/src/main/java/expo/modules/kotlin/records/Required.kt +5 -0
  39. package/android/src/main/java/expo/modules/kotlin/records/ValidationBinder.kt +110 -0
  40. package/android/src/main/java/expo/modules/kotlin/records/Validators.kt +61 -0
  41. package/android/src/main/java/expo/modules/kotlin/types/ArrayTypeConverter.kt +11 -5
  42. package/android/src/main/java/expo/modules/kotlin/types/JSTypeConverter.kt +35 -0
  43. package/android/src/main/java/expo/modules/kotlin/types/JSTypeConverterHelper.kt +148 -0
  44. package/android/src/main/java/expo/modules/kotlin/types/ListTypeConverter.kt +10 -4
  45. package/android/src/main/java/expo/modules/kotlin/types/MapTypeConverter.kt +12 -6
  46. package/android/src/main/java/expo/modules/kotlin/types/PairTypeConverter.kt +29 -13
  47. package/android/src/main/java/expo/modules/kotlin/types/TypeConverter.kt +2 -1
  48. package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +9 -1
  49. package/android/src/main/java/expo/modules/kotlin/views/CallbacksDefinition.kt +3 -0
  50. package/android/src/main/java/expo/modules/kotlin/views/GroupViewManagerWrapper.kt +71 -0
  51. package/android/src/main/java/expo/modules/kotlin/views/SimpleViewManagerWrapper.kt +22 -0
  52. package/android/src/main/java/expo/modules/kotlin/views/ViewGroupDefinition.kt +18 -0
  53. package/android/src/main/java/expo/modules/kotlin/views/ViewGroupDefinitionBuilder.kt +114 -0
  54. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinition.kt +30 -2
  55. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinitionBuilder.kt +81 -2
  56. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerWrapperDelegate.kt +62 -2
  57. package/build/EventEmitter.d.ts +1 -0
  58. package/build/EventEmitter.d.ts.map +1 -0
  59. package/build/NativeModulesProxy.d.ts +1 -0
  60. package/build/NativeModulesProxy.d.ts.map +1 -0
  61. package/build/NativeModulesProxy.native.d.ts +1 -4
  62. package/build/NativeModulesProxy.native.d.ts.map +1 -0
  63. package/build/NativeModulesProxy.native.js +1 -14
  64. package/build/NativeModulesProxy.native.js.map +1 -1
  65. package/build/NativeModulesProxy.types.d.ts +1 -3
  66. package/build/NativeModulesProxy.types.d.ts.map +1 -0
  67. package/build/NativeModulesProxy.types.js.map +1 -1
  68. package/build/NativeViewManagerAdapter.d.ts +1 -0
  69. package/build/NativeViewManagerAdapter.d.ts.map +1 -0
  70. package/build/NativeViewManagerAdapter.native.d.ts +1 -0
  71. package/build/NativeViewManagerAdapter.native.d.ts.map +1 -0
  72. package/build/NativeViewManagerAdapter.native.js +9 -33
  73. package/build/NativeViewManagerAdapter.native.js.map +1 -1
  74. package/build/PermissionsHook.d.ts +1 -0
  75. package/build/PermissionsHook.d.ts.map +1 -0
  76. package/build/PermissionsInterface.d.ts +1 -0
  77. package/build/PermissionsInterface.d.ts.map +1 -0
  78. package/build/Platform.d.ts +1 -0
  79. package/build/Platform.d.ts.map +1 -0
  80. package/build/SyntheticPlatformEmitter.d.ts +1 -0
  81. package/build/SyntheticPlatformEmitter.d.ts.map +1 -0
  82. package/build/SyntheticPlatformEmitter.web.d.ts +1 -0
  83. package/build/SyntheticPlatformEmitter.web.d.ts.map +1 -0
  84. package/build/deprecate.d.ts +1 -0
  85. package/build/deprecate.d.ts.map +1 -0
  86. package/build/environment/browser.d.ts +1 -0
  87. package/build/environment/browser.d.ts.map +1 -0
  88. package/build/environment/browser.web.d.ts +1 -0
  89. package/build/environment/browser.web.d.ts.map +1 -0
  90. package/build/errors/CodedError.d.ts +1 -0
  91. package/build/errors/CodedError.d.ts.map +1 -0
  92. package/build/errors/UnavailabilityError.d.ts +1 -0
  93. package/build/errors/UnavailabilityError.d.ts.map +1 -0
  94. package/build/index.d.ts +3 -0
  95. package/build/index.d.ts.map +1 -0
  96. package/build/index.js +2 -0
  97. package/build/index.js.map +1 -1
  98. package/build/requireNativeModule.d.ts +16 -0
  99. package/build/requireNativeModule.d.ts.map +1 -0
  100. package/build/requireNativeModule.js +18 -0
  101. package/build/requireNativeModule.js.map +1 -0
  102. package/build/sweet/NativeErrorManager.d.ts +3 -0
  103. package/build/sweet/NativeErrorManager.d.ts.map +1 -0
  104. package/build/sweet/NativeErrorManager.js +3 -0
  105. package/build/sweet/NativeErrorManager.js.map +1 -0
  106. package/build/sweet/setUpErrorManager.fx.d.ts +2 -0
  107. package/build/sweet/setUpErrorManager.fx.d.ts.map +1 -0
  108. package/build/sweet/setUpErrorManager.fx.js +11 -0
  109. package/build/sweet/setUpErrorManager.fx.js.map +1 -0
  110. package/ios/AppDelegates/EXAppDelegatesLoader.m +4 -8
  111. package/ios/AppDelegates/ExpoAppDelegate.swift +22 -20
  112. package/ios/EXAppDefines.h +1 -0
  113. package/ios/EXAppDefines.m +6 -0
  114. package/ios/EXUtilities.h +2 -0
  115. package/ios/EXUtilities.m +12 -0
  116. package/ios/ExpoModulesCore.h +4 -0
  117. package/ios/ExpoModulesCore.podspec +4 -2
  118. package/ios/Interfaces/FileSystem/EXFileSystemInterface.h +1 -1
  119. package/ios/Interfaces/TaskManager/EXTaskServiceInterface.h +1 -0
  120. package/ios/JSI/{JSIConversions.h → EXJSIConversions.h} +5 -0
  121. package/ios/JSI/{JSIConversions.mm → EXJSIConversions.mm} +21 -1
  122. package/ios/JSI/{JSIInstaller.h → EXJSIInstaller.h} +10 -0
  123. package/ios/JSI/EXJSIInstaller.mm +17 -0
  124. package/ios/JSI/EXJSIUtils.h +19 -0
  125. package/ios/JSI/EXJSIUtils.mm +89 -0
  126. package/ios/JSI/EXJavaScriptObject.h +97 -0
  127. package/ios/JSI/EXJavaScriptObject.mm +121 -0
  128. package/ios/JSI/EXJavaScriptRuntime.h +73 -0
  129. package/ios/JSI/EXJavaScriptRuntime.mm +153 -0
  130. package/ios/JSI/EXJavaScriptValue.h +57 -0
  131. package/ios/JSI/EXJavaScriptValue.mm +166 -0
  132. package/ios/JSI/ExpoModulesHostObject.h +33 -0
  133. package/ios/JSI/ExpoModulesHostObject.mm +41 -0
  134. package/ios/JSI/JavaScriptRuntime.swift +32 -0
  135. package/ios/JSI/JavaScriptValue.swift +94 -0
  136. package/ios/ModuleRegistryAdapter/EXModuleRegistryAdapter.m +3 -23
  137. package/ios/NativeModulesProxy/EXNativeModulesProxy.h +2 -2
  138. package/ios/NativeModulesProxy/EXNativeModulesProxy.mm +101 -75
  139. package/ios/RCTComponentData+Privates.h +12 -0
  140. package/ios/ReactDelegates/EXReactCompatibleHelpers.h +18 -0
  141. package/ios/ReactDelegates/EXReactCompatibleHelpers.m +19 -0
  142. package/ios/ReactDelegates/ExpoReactDelegate.swift +3 -3
  143. package/ios/ReactDelegates/ExpoReactDelegateHandler.swift +4 -4
  144. package/ios/ReactDelegates/ModulePriorities.swift +1 -1
  145. package/ios/Swift/AppContext.swift +57 -4
  146. package/ios/Swift/Arguments/AnyArgumentType.swift +1 -1
  147. package/ios/Swift/Arguments/ArgumentType.swift +4 -0
  148. package/ios/Swift/Arguments/Convertibles.swift +13 -13
  149. package/ios/Swift/Arguments/Types/EnumArgumentType.swift +11 -17
  150. package/ios/Swift/Arguments/Types/PromiseArgumentType.swift +1 -1
  151. package/ios/Swift/Arguments/Types/RawArgumentType.swift +2 -2
  152. package/ios/Swift/Conversions.swift +51 -56
  153. package/ios/Swift/EventListener.swift +8 -10
  154. package/ios/Swift/Events/Callback.swift +66 -0
  155. package/ios/Swift/Events/Event.swift +43 -0
  156. package/ios/Swift/Exceptions/ChainableException.swift +51 -0
  157. package/ios/Swift/{CodedError.swift → Exceptions/CodedError.swift} +1 -12
  158. package/ios/Swift/Exceptions/Exception.swift +62 -0
  159. package/ios/Swift/Exceptions/ExceptionOrigin.swift +28 -0
  160. package/ios/Swift/Exceptions/GenericException.swift +20 -0
  161. package/ios/Swift/Exceptions/UnexpectedException.swift +16 -0
  162. package/ios/Swift/Functions/AnyFunction.swift +16 -1
  163. package/ios/Swift/Functions/AsyncFunctionComponent.swift +182 -0
  164. package/ios/Swift/Functions/ConcreteFunction.swift +52 -59
  165. package/ios/Swift/Functions/SyncFunctionComponent.swift +181 -0
  166. package/ios/Swift/JavaScriptUtils.swift +99 -0
  167. package/ios/Swift/ModuleHolder.swift +69 -18
  168. package/ios/Swift/ModuleRegistry.swift +4 -1
  169. package/ios/Swift/Modules/AnyModule.swift +0 -1
  170. package/ios/Swift/Modules/ModuleDefinition.swift +4 -13
  171. package/ios/Swift/Modules/ModuleDefinitionBuilder.swift +0 -1
  172. package/ios/Swift/Modules/ModuleDefinitionComponents.swift +54 -220
  173. package/ios/Swift/ModulesProvider.swift +3 -11
  174. package/ios/Swift/Objects/ObjectDefinition.swift +30 -0
  175. package/ios/Swift/Objects/ObjectDefinitionComponents.swift +257 -0
  176. package/ios/Swift/Promise.swift +8 -3
  177. package/ios/Swift/Records/AnyField.swift +7 -0
  178. package/ios/Swift/Records/Field.swift +24 -19
  179. package/ios/Swift/Records/FieldOption.swift +1 -1
  180. package/ios/Swift/Records/Record.swift +12 -4
  181. package/ios/Swift/SwiftInteropBridge.swift +53 -15
  182. package/ios/Swift/Views/AnyViewProp.swift +1 -1
  183. package/ios/Swift/Views/ComponentData.swift +96 -0
  184. package/ios/Swift/Views/ConcreteViewProp.swift +6 -8
  185. package/ios/Swift/Views/ExpoView.swift +8 -0
  186. package/ios/Swift/Views/ViewFactory.swift +1 -1
  187. package/ios/Swift/Views/ViewManagerDefinition.swift +23 -2
  188. package/ios/Swift/Views/ViewManagerDefinitionBuilder.swift +0 -1
  189. package/ios/Swift/Views/ViewManagerDefinitionComponents.swift +49 -0
  190. package/ios/Swift/Views/ViewModuleWrapper.swift +5 -2
  191. package/ios/Swift.h +5 -0
  192. package/ios/Tests/ArgumentTypeSpec.swift +5 -7
  193. package/ios/Tests/ConstantsSpec.swift +6 -7
  194. package/ios/Tests/ConvertiblesSpec.swift +35 -36
  195. package/ios/Tests/ExceptionsSpec.swift +111 -0
  196. package/ios/Tests/ExpoModulesSpec.swift +75 -0
  197. package/ios/Tests/FunctionSpec.swift +21 -25
  198. package/ios/Tests/FunctionWithConvertiblesSpec.swift +4 -5
  199. package/ios/Tests/JavaScriptObjectSpec.swift +97 -0
  200. package/ios/Tests/JavaScriptRuntimeSpec.swift +94 -0
  201. package/ios/Tests/Mocks/ModuleMocks.swift +1 -1
  202. package/ios/Tests/Mocks/ModulesProviderMock.swift +0 -1
  203. package/ios/Tests/ModuleEventListenersSpec.swift +16 -17
  204. package/ios/Tests/ModuleRegistrySpec.swift +2 -3
  205. package/ios/Tests/RecordSpec.swift +9 -20
  206. package/package.json +3 -3
  207. package/src/NativeModulesProxy.native.ts +2 -22
  208. package/src/NativeModulesProxy.types.ts +0 -8
  209. package/src/NativeViewManagerAdapter.native.tsx +12 -28
  210. package/src/index.ts +4 -0
  211. package/src/requireNativeModule.ts +29 -0
  212. package/src/sweet/NativeErrorManager.ts +2 -0
  213. package/src/sweet/setUpErrorManager.fx.ts +12 -0
  214. package/android/src/main/java/expo/modules/kotlin/events/KEventEmitterWrapper.kt +0 -26
  215. package/android/src/main/java/expo/modules/kotlin/methods/Method.kt +0 -14
  216. package/android/src/main/java/expo/modules/kotlin/methods/PromiseMethod.kt +0 -15
  217. package/ios/JSI/ExpoModulesProxySpec.h +0 -24
  218. package/ios/JSI/ExpoModulesProxySpec.mm +0 -135
  219. package/ios/JSI/JSIInstaller.mm +0 -22
@@ -8,6 +8,6 @@ interface Promise {
8
8
  fun reject(code: String, message: String?, cause: Throwable?)
9
9
 
10
10
  fun reject(exception: CodedException) {
11
- reject(exception.code, exception.message, exception.cause)
11
+ reject(exception.code, exception.localizedMessage, exception.cause)
12
12
  }
13
13
  }
@@ -0,0 +1,5 @@
1
+ package expo.modules.kotlin.callbacks
2
+
3
+ fun interface Callback<T> {
4
+ operator fun invoke(arg: T)
5
+ }
@@ -0,0 +1,39 @@
1
+ package expo.modules.kotlin.callbacks
2
+
3
+ import android.view.View
4
+ import com.facebook.react.bridge.ReactContext
5
+ import com.facebook.react.bridge.WritableMap
6
+ import expo.modules.adapters.react.NativeModulesProxy
7
+ import expo.modules.kotlin.modules.Module
8
+ import expo.modules.kotlin.types.JSTypeConverter
9
+ import expo.modules.kotlin.types.putGeneric
10
+ import kotlin.reflect.KType
11
+
12
+ class ViewCallback<T>(
13
+ private val name: String,
14
+ private val type: KType,
15
+ private val view: View
16
+ ) : Callback<T> {
17
+ internal lateinit var module: Module
18
+
19
+ override operator fun invoke(arg: T) {
20
+ val reactContext = view.context as ReactContext
21
+ val nativeModulesProxy = reactContext
22
+ .catalystInstance
23
+ ?.getNativeModule("NativeUnimoduleProxy") as? NativeModulesProxy
24
+ ?: return
25
+ val appContext = nativeModulesProxy.kotlinInteropModuleRegistry.appContext
26
+
27
+ appContext.callbackInvoker?.emit(view.id, name, convertEventBody(arg))
28
+ }
29
+
30
+ private fun convertEventBody(arg: T): WritableMap? {
31
+ return when (val converted = JSTypeConverter.convertToJSValue(arg)) {
32
+ is Unit, null -> null
33
+ is WritableMap -> converted
34
+ else -> JSTypeConverter.DefaultContainerProvider.createMap().apply {
35
+ putGeneric("payload", converted)
36
+ }
37
+ }
38
+ }
39
+ }
@@ -0,0 +1,27 @@
1
+ @file:OptIn(ExperimentalStdlibApi::class)
2
+
3
+ package expo.modules.kotlin.callbacks
4
+
5
+ import android.view.View
6
+ import java.lang.ref.WeakReference
7
+ import kotlin.reflect.KProperty
8
+ import kotlin.reflect.KType
9
+ import kotlin.reflect.typeOf
10
+
11
+ class ViewCallbackDelegate<T>(private val type: KType, view: View) {
12
+ private val viewHolder = WeakReference(view)
13
+ internal var isValidated = false
14
+
15
+ operator fun getValue(thisRef: View, property: KProperty<*>): Callback<T> {
16
+ if (!isValidated) {
17
+ throw IllegalStateException("You have to export this property as a callback in the `ViewManager`.")
18
+ }
19
+
20
+ val view = viewHolder.get() ?: throw IllegalStateException("Can't send an event from the view that is deallocated.")
21
+ return ViewCallback(property.name, type, view)
22
+ }
23
+ }
24
+
25
+ inline fun <reified T> View.callback(): ViewCallbackDelegate<T> {
26
+ return ViewCallbackDelegate(typeOf<T>(), this)
27
+ }
@@ -0,0 +1,25 @@
1
+ package expo.modules.kotlin.defaultmodules
2
+
3
+ import android.os.Bundle
4
+ import expo.modules.kotlin.exception.CodedException
5
+ import expo.modules.kotlin.modules.Module
6
+ import expo.modules.kotlin.modules.ModuleDefinition
7
+
8
+ private const val onNewException = "ExpoModulesCoreErrorManager.onNewException"
9
+
10
+ class ErrorManagerModule : Module() {
11
+ override fun definition() = ModuleDefinition {
12
+ name("ExpoModulesCoreErrorManager")
13
+ events(onNewException)
14
+ }
15
+
16
+ fun reportExceptionToLogBox(codedException: CodedException) {
17
+ val eventEmitter = appContext.eventEmitter(this) ?: return
18
+ eventEmitter.emit(
19
+ onNewException,
20
+ Bundle().apply {
21
+ putString("message", codedException.message ?: codedException.toString())
22
+ }
23
+ )
24
+ }
25
+ }
@@ -0,0 +1,13 @@
1
+ package expo.modules.kotlin.events
2
+
3
+ import com.facebook.react.bridge.WritableMap
4
+ import expo.modules.kotlin.records.Record
5
+
6
+ // We want to decorate a legacy event emitter interface to support advanced conversion between types in events.
7
+ // For instance, users will be able to create `Callback<Record>` that will be converted to the `WritableMap`.
8
+ interface EventEmitter : expo.modules.core.interfaces.services.EventEmitter {
9
+ fun emit(eventName: String, eventBody: WritableMap?)
10
+ fun emit(eventName: String, eventBody: Record?)
11
+ fun emit(eventName: String, eventBody: Map<*, *>?)
12
+ fun emit(viewId: Int, eventName: String, eventBody: WritableMap?)
13
+ }
@@ -0,0 +1,102 @@
1
+ package expo.modules.kotlin.events
2
+
3
+ import android.os.Bundle
4
+ import com.facebook.react.bridge.ReactApplicationContext
5
+ import com.facebook.react.bridge.WritableMap
6
+ import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter
7
+ import com.facebook.react.uimanager.UIManagerModule
8
+ import com.facebook.react.uimanager.events.EventDispatcher
9
+ import com.facebook.react.uimanager.events.RCTEventEmitter
10
+ import expo.modules.kotlin.ModuleHolder
11
+ import expo.modules.kotlin.records.Record
12
+ import expo.modules.kotlin.types.JSTypeConverter
13
+ import java.lang.ref.WeakReference
14
+
15
+ /**
16
+ * In Swift, we check if the event is supported. Otherwise, we can't send such event through the bridge.
17
+ * However, in Kotlin this is unnecessary, but to make our API consistent, we added similar check.
18
+ * But because of that, we had to create a wrapper for EventEmitter.
19
+ */
20
+ class KModuleEventEmitterWrapper(
21
+ private val moduleHolder: ModuleHolder,
22
+ legacyEventEmitter: expo.modules.core.interfaces.services.EventEmitter,
23
+ reactContextHolder: WeakReference<ReactApplicationContext>
24
+ ) : KEventEmitterWrapper(legacyEventEmitter, reactContextHolder) {
25
+ override fun emit(eventName: String, eventBody: Bundle?) {
26
+ checkIfEventWasExported(eventName)
27
+ super.emit(eventName, eventBody)
28
+ }
29
+
30
+ override fun emit(eventName: String, eventBody: WritableMap?) {
31
+ checkIfEventWasExported(eventName)
32
+ super.emit(eventName, eventBody)
33
+ }
34
+
35
+ override fun emit(eventName: String, eventBody: Record?) {
36
+ checkIfEventWasExported(eventName)
37
+ super.emit(eventName, eventBody)
38
+ }
39
+
40
+ override fun emit(eventName: String, eventBody: Map<*, *>?) {
41
+ checkIfEventWasExported(eventName)
42
+ super.emit(eventName, eventBody)
43
+ }
44
+
45
+ private fun checkIfEventWasExported(eventName: String) {
46
+ require(
47
+ moduleHolder
48
+ .definition
49
+ .eventsDefinition
50
+ ?.names
51
+ ?.contains(eventName) == true
52
+ ) { "Unsupported event: $eventName." }
53
+ }
54
+ }
55
+
56
+ open class KEventEmitterWrapper(
57
+ private val legacyEventEmitter: expo.modules.core.interfaces.services.EventEmitter,
58
+ private val reactContextHolder: WeakReference<ReactApplicationContext>
59
+ ) : EventEmitter, expo.modules.core.interfaces.services.EventEmitter by legacyEventEmitter {
60
+ private val deviceEventEmitter: RCTDeviceEventEmitter?
61
+ get() = reactContextHolder
62
+ .get()
63
+ ?.getJSModule(RCTDeviceEventEmitter::class.java)
64
+
65
+ private val uiEventDispatcher: EventDispatcher?
66
+ get() = reactContextHolder
67
+ .get()
68
+ ?.getNativeModule(UIManagerModule::class.java)
69
+ ?.eventDispatcher
70
+
71
+ override fun emit(eventName: String, eventBody: WritableMap?) {
72
+ deviceEventEmitter
73
+ ?.emit(eventName, eventBody)
74
+ }
75
+ override fun emit(eventName: String, eventBody: Record?) {
76
+ deviceEventEmitter
77
+ ?.emit(eventName, JSTypeConverter.convertToJSValue(eventBody))
78
+ }
79
+
80
+ override fun emit(eventName: String, eventBody: Map<*, *>?) {
81
+ deviceEventEmitter
82
+ ?.emit(eventName, JSTypeConverter.convertToJSValue(eventBody))
83
+ }
84
+
85
+ override fun emit(viewId: Int, eventName: String, eventBody: WritableMap?) {
86
+ uiEventDispatcher
87
+ ?.dispatchEvent(UIEvent(viewId, eventName, eventBody))
88
+ }
89
+
90
+ private class UIEvent(
91
+ private val viewId: Int,
92
+ private val eventName: String,
93
+ private val eventBody: WritableMap?
94
+ ) : com.facebook.react.uimanager.events.Event<UIEvent>(viewId) {
95
+ override fun getEventName(): String = eventName
96
+ override fun canCoalesce(): Boolean = false
97
+ override fun getCoalescingKey(): Short = 0
98
+ override fun dispatch(rctEventEmitter: RCTEventEmitter) {
99
+ rctEventEmitter.receiveEvent(viewId, eventName, eventBody)
100
+ }
101
+ }
102
+ }
@@ -1,6 +1,8 @@
1
1
  package expo.modules.kotlin.exception
2
2
 
3
+ import com.facebook.react.bridge.ReadableType
3
4
  import java.util.*
5
+ import kotlin.reflect.KProperty1
4
6
  import kotlin.reflect.KType
5
7
 
6
8
  /**
@@ -17,7 +19,7 @@ open class CodedException(
17
19
  val code
18
20
  get() = providedCode ?: inferCode(javaClass)
19
21
 
20
- constructor(code: String, message: String, cause: Throwable?) : this(message, cause) {
22
+ constructor(code: String, message: String?, cause: Throwable?) : this(message, cause) {
21
23
  providedCode = code
22
24
  }
23
25
 
@@ -31,9 +33,11 @@ open class CodedException(
31
33
  /**
32
34
  * The code is inferred from the class name — e.g. the code of `ModuleNotFoundException` becomes `ERR_MODULE_NOT_FOUND`.
33
35
  */
34
- private fun inferCode(clazz: Class<*>): String {
36
+ @PublishedApi
37
+ internal fun inferCode(clazz: Class<*>): String {
35
38
  val name = requireNotNull(clazz.simpleName) { "Cannot infer code name from class name. We don't support anonymous classes." }
36
39
 
40
+ @Suppress("Deprecation")
37
41
  return "ERR_" + name
38
42
  .replace("(Exception)$".toRegex(), "")
39
43
  .replace("(.)([A-Z])".toRegex(), "$1_$2")
@@ -42,29 +46,109 @@ open class CodedException(
42
46
  }
43
47
  }
44
48
 
49
+ /**
50
+ * Infers error code from the exception class name -
51
+ * e.g. the code of `ModuleNotFoundException` becomes `ERR_MODULE_NOT_FOUND`.
52
+ *
53
+ * Example:
54
+ * ```kt
55
+ * class NoPermissionException : CodedException()
56
+ * val errorCode = errorCodeOf<NoPermissionException>() // ERR_NO_PERMISSION
57
+ * ```
58
+ *
59
+ * **Note**: This works only if the exception class didn't overwrite the error code manually.
60
+ */
61
+ inline fun <reified T : CodedException> errorCodeOf(): String =
62
+ CodedException.inferCode(T::class.java)
63
+
45
64
  internal class IncompatibleArgTypeException(
46
65
  argumentType: KType,
47
66
  desiredType: KType,
48
67
  cause: Throwable? = null
49
68
  ) : CodedException(
50
- message = "Argument type $argumentType is not compatible with expected type $desiredType.",
69
+ message = "Argument type '$argumentType' is not compatible with expected type '$desiredType'.",
51
70
  cause = cause
52
71
  )
53
72
 
54
73
  internal class MissingTypeConverter(
55
74
  forType: KType
56
75
  ) : CodedException(
57
- message = "Cannot find type converter for $forType.",
76
+ message = "Cannot find type converter for '$forType'.",
58
77
  )
59
78
 
60
79
  internal class InvalidArgsNumberException(received: Int, expected: Int) :
61
80
  CodedException(message = "Received $received arguments, but $expected was expected.")
62
81
 
63
- internal class MethodNotFoundException(methodName: String, moduleName: String) :
64
- CodedException(message = "Cannot fund method $methodName in module $moduleName")
82
+ internal class MethodNotFoundException :
83
+ CodedException(message = "Method does not exist.")
65
84
 
66
- internal class NullArgumentException(desiredType: KType) :
67
- CodedException(message = "Cannot assigned null to not nullable type $desiredType")
85
+ internal class NullArgumentException :
86
+ CodedException(message = "Cannot assigned null to not nullable type.")
87
+
88
+ internal class FieldRequiredException(property: KProperty1<*, *>) :
89
+ CodedException(message = "Value for field '$property' is required, got nil")
68
90
 
69
91
  internal class UnexpectedException(val throwable: Throwable) :
70
- CodedException(throwable)
92
+ CodedException(message = throwable.toString(), throwable)
93
+
94
+ internal class ValidationException(message: String) :
95
+ CodedException(message = message)
96
+
97
+ /**
98
+ * A base class for all exceptions used in `exceptionDecorator` function.
99
+ */
100
+ internal open class DecoratedException(
101
+ message: String,
102
+ cause: CodedException,
103
+ ) : CodedException(
104
+ cause.code,
105
+ message = "$message${System.lineSeparator()}→ Caused by: ${cause.localizedMessage ?: cause}",
106
+ cause
107
+ )
108
+
109
+ internal class FunctionCallException(
110
+ methodName: String,
111
+ moduleName: String,
112
+ cause: CodedException
113
+ ) : DecoratedException(
114
+ message = "Call to function '$moduleName.$methodName' has been rejected.",
115
+ cause,
116
+ )
117
+
118
+ internal class ArgumentCastException(
119
+ argDesiredType: KType,
120
+ argIndex: Int,
121
+ providedType: ReadableType,
122
+ cause: CodedException,
123
+ ) : DecoratedException(
124
+ message = "Argument at index '$argIndex' couldn't be casted to type '$argDesiredType' (received '$providedType').",
125
+ cause,
126
+ )
127
+
128
+ internal class FieldCastException(
129
+ fieldName: String,
130
+ fieldType: KType,
131
+ providedType: ReadableType,
132
+ cause: CodedException
133
+ ) : DecoratedException(
134
+ message = "Cannot cast '${providedType.name}' for field '$fieldName' ('$fieldType').",
135
+ cause
136
+ )
137
+
138
+ internal class RecordCastException(
139
+ recordType: KType,
140
+ cause: CodedException
141
+ ) : DecoratedException(
142
+ message = "Cannot create a record of the type: '$recordType'.",
143
+ cause
144
+ )
145
+
146
+ internal class CollectionElementCastException(
147
+ collectionType: KType,
148
+ elementType: KType,
149
+ providedType: ReadableType,
150
+ cause: CodedException
151
+ ) : DecoratedException(
152
+ message = "Cannot cast '${providedType.name}' to '$elementType' required by the collection of type: '$collectionType'.",
153
+ cause
154
+ )
@@ -0,0 +1,11 @@
1
+ package expo.modules.kotlin.exception
2
+
3
+ internal inline fun <T> exceptionDecorator(decoratorBlock: (e: CodedException) -> Throwable, block: () -> T): T {
4
+ return try {
5
+ block()
6
+ } catch (e: CodedException) {
7
+ throw decoratorBlock(e)
8
+ } catch (e: Throwable) {
9
+ throw decoratorBlock(UnexpectedException(e))
10
+ }
11
+ }
@@ -1,36 +1,32 @@
1
- package expo.modules.kotlin.methods
1
+ package expo.modules.kotlin.functions
2
2
 
3
3
  import com.facebook.react.bridge.ReadableArray
4
+ import expo.modules.kotlin.ModuleHolder
4
5
  import expo.modules.kotlin.Promise
6
+ import expo.modules.kotlin.exception.ArgumentCastException
5
7
  import expo.modules.kotlin.exception.CodedException
6
8
  import expo.modules.kotlin.exception.InvalidArgsNumberException
7
- import expo.modules.kotlin.exception.UnexpectedException
9
+ import expo.modules.kotlin.exception.exceptionDecorator
8
10
  import expo.modules.kotlin.iterator
9
11
  import expo.modules.kotlin.recycle
10
12
  import expo.modules.kotlin.types.AnyType
11
- import kotlin.jvm.Throws
12
13
 
13
- abstract class AnyMethod(
14
+ abstract class AnyFunction(
14
15
  protected val name: String,
15
16
  private val desiredArgsTypes: Array<AnyType>
16
17
  ) {
17
- fun call(args: ReadableArray, promise: Promise) {
18
+ @Throws(CodedException::class)
19
+ fun call(module: ModuleHolder, args: ReadableArray, promise: Promise) {
18
20
  if (desiredArgsTypes.size != args.size()) {
19
- promise.reject(InvalidArgsNumberException(args.size(), desiredArgsTypes.size))
20
- return
21
- }
22
- try {
23
- val convertedArgs = convertArgs(args)
24
- callImplementation(convertedArgs, promise)
25
- } catch (codedError: CodedException) {
26
- promise.reject(codedError)
27
- } catch (e: Throwable) {
28
- promise.reject(UnexpectedException(e))
21
+ throw InvalidArgsNumberException(args.size(), desiredArgsTypes.size)
29
22
  }
23
+
24
+ val convertedArgs = convertArgs(args)
25
+ callImplementation(module, convertedArgs, promise)
30
26
  }
31
27
 
32
28
  @Throws(CodedException::class)
33
- internal abstract fun callImplementation(args: Array<out Any?>, promise: Promise)
29
+ internal abstract fun callImplementation(holder: ModuleHolder, args: Array<out Any?>, promise: Promise)
34
30
 
35
31
  val argsCount get() = desiredArgsTypes.size
36
32
 
@@ -40,9 +36,13 @@ abstract class AnyMethod(
40
36
  val argIterator = args.iterator()
41
37
  desiredArgsTypes
42
38
  .withIndex()
43
- .forEach { (index, type) ->
39
+ .forEach { (index, desiredType) ->
44
40
  argIterator.next().recycle {
45
- finalArgs[index] = type.convert(this)
41
+ exceptionDecorator({ cause ->
42
+ ArgumentCastException(desiredType.kType, index, type, cause)
43
+ }) {
44
+ finalArgs[index] = desiredType.convert(this)
45
+ }
46
46
  }
47
47
  }
48
48
  return finalArgs
@@ -0,0 +1,15 @@
1
+ package expo.modules.kotlin.functions
2
+
3
+ import expo.modules.kotlin.ModuleHolder
4
+ import expo.modules.kotlin.Promise
5
+ import expo.modules.kotlin.types.AnyType
6
+
7
+ class AsyncFunction(
8
+ name: String,
9
+ argsType: Array<AnyType>,
10
+ private val body: (args: Array<out Any?>) -> Any?
11
+ ) : AnyFunction(name, argsType) {
12
+ override fun callImplementation(holder: ModuleHolder, args: Array<out Any?>, promise: Promise) {
13
+ promise.resolve(body(args))
14
+ }
15
+ }
@@ -0,0 +1,170 @@
1
+ @file:OptIn(ExperimentalStdlibApi::class)
2
+ @file:Suppress("FunctionName")
3
+
4
+ package expo.modules.kotlin.functions
5
+
6
+ import expo.modules.kotlin.types.toAnyType
7
+ import kotlin.reflect.typeOf
8
+
9
+ class AsyncFunctionBuilder(val name: String) {
10
+ @PublishedApi
11
+ internal var function: AnyFunction? = null
12
+
13
+ @Deprecated(
14
+ message = "The 'suspendBody' component was renamed to 'SuspendBody'.",
15
+ replaceWith = ReplaceWith("SuspendBody(block)")
16
+ )
17
+ inline fun <reified R> suspendBody(crossinline block: suspend () -> R) = SuspendBody(block)
18
+
19
+ inline fun <reified R> SuspendBody(crossinline block: suspend () -> R) {
20
+ function = AsyncSuspendFunction(name, arrayOf()) { block() }
21
+ }
22
+
23
+ @Deprecated(
24
+ message = "The 'suspendBody' component was renamed to 'SuspendBody'.",
25
+ replaceWith = ReplaceWith("SuspendBody(block)")
26
+ )
27
+ inline fun <reified R, reified P0> suspendBody(crossinline block: suspend (p0: P0) -> R) = SuspendBody(block)
28
+
29
+ inline fun <reified R, reified P0> SuspendBody(crossinline block: suspend (p0: P0) -> R) {
30
+ function = AsyncSuspendFunction(name, arrayOf(typeOf<P0>().toAnyType())) { block(it[0] as P0) }
31
+ }
32
+
33
+ @Deprecated(
34
+ message = "The 'suspendBody' component was renamed to 'SuspendBody'.",
35
+ replaceWith = ReplaceWith("SuspendBody(block)")
36
+ )
37
+ inline fun <reified R, reified P0, reified P1> suspendBody(crossinline block: suspend (p0: P0, p1: P1) -> R) = SuspendBody(block)
38
+
39
+ inline fun <reified R, reified P0, reified P1> SuspendBody(crossinline block: suspend (p0: P0, p1: P1) -> R) {
40
+ function = AsyncSuspendFunction(name, arrayOf(typeOf<P0>().toAnyType())) { block(it[0] as P0, it[0] as P1) }
41
+ }
42
+
43
+ @Deprecated(
44
+ message = "The 'suspendBody' component was renamed to 'SuspendBody'.",
45
+ replaceWith = ReplaceWith("SuspendBody(block)")
46
+ )
47
+ inline fun <reified R, reified P0, reified P1, reified P2> suspendBody(crossinline block: suspend (p0: P0, p1: P1, p2: P2) -> R) = SuspendBody(block)
48
+
49
+ inline fun <reified R, reified P0, reified P1, reified P2> SuspendBody(crossinline block: suspend (p0: P0, p1: P1, p2: P2) -> R) {
50
+ function = AsyncSuspendFunction(name, arrayOf(typeOf<P0>().toAnyType())) { block(it[0] as P0, it[1] as P1, it[2] as P2) }
51
+ }
52
+
53
+ @Deprecated(
54
+ message = "The 'suspendBody' component was renamed to 'SuspendBody'.",
55
+ replaceWith = ReplaceWith("SuspendBody(block)")
56
+ )
57
+ inline fun <reified R, reified P0, reified P1, reified P2, reified P3> suspendBody(crossinline block: suspend (p0: P0, p1: P1, p2: P2, p3: P3) -> R) = SuspendBody(block)
58
+
59
+ inline fun <reified R, reified P0, reified P1, reified P2, reified P3> SuspendBody(crossinline block: suspend (p0: P0, p1: P1, p2: P2, p3: P3) -> R) {
60
+ function = AsyncSuspendFunction(name, arrayOf(typeOf<P0>().toAnyType())) { block(it[0] as P0, it[1] as P1, it[2] as P2, it[3] as P3) }
61
+ }
62
+
63
+ @Deprecated(
64
+ message = "The 'suspendBody' component was renamed to 'SuspendBody'.",
65
+ replaceWith = ReplaceWith("SuspendBody(block)")
66
+ )
67
+ inline fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4> suspendBody(crossinline block: suspend (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4) -> R) = SuspendBody(block)
68
+
69
+ inline fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4> SuspendBody(crossinline block: suspend (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4) -> R) {
70
+ function = AsyncSuspendFunction(name, arrayOf(typeOf<P0>().toAnyType())) { block(it[0] as P0, it[1] as P1, it[2] as P2, it[3] as P3, it[4] as P4) }
71
+ }
72
+
73
+ @Deprecated(
74
+ message = "The 'suspendBody' component was renamed to 'SuspendBody'.",
75
+ replaceWith = ReplaceWith("SuspendBody(block)")
76
+ )
77
+ inline fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4, reified P5> suspendBody(crossinline block: suspend (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5) -> R) = SuspendBody(block)
78
+
79
+ inline fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4, reified P5> SuspendBody(crossinline block: suspend (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5) -> R) {
80
+ function = AsyncSuspendFunction(name, arrayOf(typeOf<P0>().toAnyType())) { block(it[0] as P0, it[1] as P1, it[2] as P2, it[3] as P3, it[4] as P4, it[5] as P5) }
81
+ }
82
+
83
+ @Deprecated(
84
+ message = "The 'suspendBody' component was renamed to 'SuspendBody'.",
85
+ replaceWith = ReplaceWith("SuspendBody(block)")
86
+ )
87
+ inline fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4, reified P5, reified P6> suspendBody(crossinline block: suspend (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6) -> R) = SuspendBody(block)
88
+
89
+ inline fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4, reified P5, reified P6> SuspendBody(crossinline block: suspend (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6) -> R) {
90
+ function = AsyncSuspendFunction(name, arrayOf(typeOf<P0>().toAnyType())) { block(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) }
91
+ }
92
+
93
+ @Deprecated(
94
+ message = "The 'suspendBody' component was renamed to 'SuspendBody'.",
95
+ replaceWith = ReplaceWith("SuspendBody(block)")
96
+ )
97
+ inline fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4, reified P5, reified P6, reified P7> suspendBody(crossinline block: suspend (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7) -> R) = SuspendBody(block)
98
+
99
+ inline fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4, reified P5, reified P6, reified P7> SuspendBody(crossinline block: suspend (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7) -> R) {
100
+ function = AsyncSuspendFunction(name, arrayOf(typeOf<P0>().toAnyType())) { block(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) }
101
+ }
102
+
103
+ internal fun build(): Pair<String, AnyFunction> {
104
+ return name to requireNotNull(function)
105
+ }
106
+ }
107
+
108
+ @Deprecated(
109
+ message = "The 'coroutine' component was renamed to 'Coroutine'.",
110
+ replaceWith = ReplaceWith("Coroutine(block)")
111
+ )
112
+ inline infix fun <reified R> AsyncFunctionBuilder.coroutine(crossinline block: suspend () -> R) = Coroutine(block)
113
+
114
+ @Deprecated(
115
+ message = "The 'coroutine' component was renamed to 'Coroutine'.",
116
+ replaceWith = ReplaceWith("Coroutine(block)")
117
+ )
118
+ inline infix fun <reified R, reified P0> AsyncFunctionBuilder.coroutine(crossinline block: suspend (P0) -> R) = Coroutine(block)
119
+
120
+ @Deprecated(
121
+ message = "The 'coroutine' component was renamed to 'Coroutine'.",
122
+ replaceWith = ReplaceWith("Coroutine(block)")
123
+ )
124
+ inline infix fun <reified R, reified P0, reified P1> AsyncFunctionBuilder.coroutine(crossinline block: suspend (P0, P1) -> R) = Coroutine(block)
125
+
126
+ @Deprecated(
127
+ message = "The 'coroutine' component was renamed to 'Coroutine'.",
128
+ replaceWith = ReplaceWith("Coroutine(block)")
129
+ )
130
+ inline infix fun <reified R, reified P0, reified P1, reified P2> AsyncFunctionBuilder.coroutine(crossinline block: suspend (P0, P1, P2) -> R) = Coroutine(block)
131
+
132
+ @Deprecated(
133
+ message = "The 'coroutine' component was renamed to 'Coroutine'.",
134
+ replaceWith = ReplaceWith("Coroutine(block)")
135
+ )
136
+ inline infix fun <reified R, reified P0, reified P1, reified P2, reified P3> AsyncFunctionBuilder.coroutine(crossinline block: suspend (P0, P1, P2, P3) -> R) = Coroutine(block)
137
+
138
+ @Deprecated(
139
+ message = "The 'coroutine' component was renamed to 'Coroutine'.",
140
+ replaceWith = ReplaceWith("Coroutine(block)")
141
+ )
142
+ inline infix fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4> AsyncFunctionBuilder.coroutine(crossinline block: suspend (P0, P1, P2, P3, P4) -> R) = Coroutine(block)
143
+
144
+ @Deprecated(
145
+ message = "The 'coroutine' component was renamed to 'Coroutine'.",
146
+ replaceWith = ReplaceWith("Coroutine(block)")
147
+ )
148
+ inline infix fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4, reified P5> AsyncFunctionBuilder.coroutine(crossinline block: suspend (P0, P1, P2, P3, P4, P5) -> R) = Coroutine(block)
149
+
150
+ @Deprecated(
151
+ message = "The 'coroutine' component was renamed to 'Coroutine'.",
152
+ replaceWith = ReplaceWith("Coroutine(block)")
153
+ )
154
+ inline infix fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4, reified P5, reified P6> AsyncFunctionBuilder.coroutine(crossinline block: suspend (P0, P1, P2, P3, P4, P5, P6) -> R) = Coroutine(block)
155
+
156
+ @Deprecated(
157
+ message = "The 'coroutine' component was renamed to 'Coroutine'.",
158
+ replaceWith = ReplaceWith("Coroutine(block)")
159
+ )
160
+ inline infix fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4, reified P5, reified P6, reified P7> AsyncFunctionBuilder.coroutine(crossinline block: suspend (P0, P1, P2, P3, P4, P5, P6, P7) -> R) = Coroutine(block)
161
+
162
+ inline infix fun <reified R> AsyncFunctionBuilder.Coroutine(crossinline block: suspend () -> R) = SuspendBody(block)
163
+ inline infix fun <reified R, reified P0> AsyncFunctionBuilder.Coroutine(crossinline block: suspend (P0) -> R) = SuspendBody(block)
164
+ inline infix fun <reified R, reified P0, reified P1> AsyncFunctionBuilder.Coroutine(crossinline block: suspend (P0, P1) -> R) = SuspendBody(block)
165
+ inline infix fun <reified R, reified P0, reified P1, reified P2> AsyncFunctionBuilder.Coroutine(crossinline block: suspend (P0, P1, P2) -> R) = SuspendBody(block)
166
+ inline infix fun <reified R, reified P0, reified P1, reified P2, reified P3> AsyncFunctionBuilder.Coroutine(crossinline block: suspend (P0, P1, P2, P3) -> R) = SuspendBody(block)
167
+ inline infix fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4> AsyncFunctionBuilder.Coroutine(crossinline block: suspend (P0, P1, P2, P3, P4) -> R) = SuspendBody(block)
168
+ inline infix fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4, reified P5> AsyncFunctionBuilder.Coroutine(crossinline block: suspend (P0, P1, P2, P3, P4, P5) -> R) = SuspendBody(block)
169
+ inline infix fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4, reified P5, reified P6> AsyncFunctionBuilder.Coroutine(crossinline block: suspend (P0, P1, P2, P3, P4, P5, P6) -> R) = SuspendBody(block)
170
+ inline infix fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4, reified P5, reified P6, reified P7> AsyncFunctionBuilder.Coroutine(crossinline block: suspend (P0, P1, P2, P3, P4, P5, P6, P7) -> R) = SuspendBody(block)
@@ -0,0 +1,15 @@
1
+ package expo.modules.kotlin.functions
2
+
3
+ import expo.modules.kotlin.ModuleHolder
4
+ import expo.modules.kotlin.Promise
5
+ import expo.modules.kotlin.types.AnyType
6
+
7
+ class AsyncFunctionWithPromise(
8
+ name: String,
9
+ argsType: Array<AnyType>,
10
+ private val body: (args: Array<out Any?>, promise: Promise) -> Unit
11
+ ) : AnyFunction(name, argsType) {
12
+ override fun callImplementation(holder: ModuleHolder, args: Array<out Any?>, promise: Promise) {
13
+ body(args, promise)
14
+ }
15
+ }