expo-modules-core 0.10.0 → 0.11.2

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 (63) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +3 -3
  3. package/android/CMakeLists.txt +14 -5
  4. package/android/build.gradle +78 -28
  5. package/android/src/main/cpp/CachedReferencesRegistry.cpp +67 -0
  6. package/android/src/main/cpp/CachedReferencesRegistry.h +80 -0
  7. package/android/src/main/cpp/JNIFunctionBody.cpp +28 -12
  8. package/android/src/main/cpp/JNIFunctionBody.h +2 -2
  9. package/android/src/main/cpp/JNIInjector.cpp +4 -0
  10. package/android/src/main/cpp/JavaScriptModuleObject.cpp +86 -5
  11. package/android/src/main/cpp/JavaScriptModuleObject.h +27 -5
  12. package/android/src/main/cpp/JavaScriptRuntime.cpp +10 -12
  13. package/android/src/main/cpp/MethodMetadata.cpp +181 -40
  14. package/android/src/main/cpp/MethodMetadata.h +43 -3
  15. package/android/src/main/java/expo/modules/kotlin/AppContext.kt +63 -10
  16. package/android/src/main/java/expo/modules/kotlin/ModuleHolder.kt +6 -0
  17. package/android/src/main/java/expo/modules/kotlin/activityaware/AppCompatActivityAware.kt +49 -0
  18. package/android/src/main/java/expo/modules/kotlin/activityaware/AppCompatActivityAwareHelper.kt +43 -0
  19. package/android/src/main/java/expo/modules/kotlin/activityaware/OnActivityAvailableListener.kt +18 -0
  20. package/android/src/main/java/expo/modules/kotlin/activityresult/ActivityResultsManager.kt +99 -0
  21. package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultCaller.kt +25 -0
  22. package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultContract.kt +27 -0
  23. package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultFallbackCallback.kt +17 -0
  24. package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultLauncher.kt +30 -0
  25. package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultRegistry.kt +358 -0
  26. package/android/src/main/java/expo/modules/kotlin/activityresult/DataPersistor.kt +135 -0
  27. package/android/src/main/java/expo/modules/kotlin/functions/AnyFunction.kt +34 -1
  28. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunction.kt +7 -1
  29. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionBuilder.kt +0 -108
  30. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionComponent.kt +5 -2
  31. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromiseComponent.kt +5 -2
  32. package/android/src/main/java/expo/modules/kotlin/functions/SuspendFunctionComponent.kt +9 -2
  33. package/android/src/main/java/expo/modules/kotlin/functions/SyncFunctionComponent.kt +9 -1
  34. package/android/src/main/java/expo/modules/kotlin/jni/CppType.kt +1 -0
  35. package/android/src/main/java/expo/modules/kotlin/jni/JNIFunctionBody.kt +2 -2
  36. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptModuleObject.kt +4 -2
  37. package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +1 -1
  38. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +5 -454
  39. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionData.kt +7 -15
  40. package/android/src/main/java/expo/modules/kotlin/objects/ObjectDefinitionBuilder.kt +271 -0
  41. package/android/src/main/java/expo/modules/kotlin/objects/ObjectDefinitionData.kt +21 -0
  42. package/android/src/main/java/expo/modules/kotlin/objects/PropertyComponent.kt +54 -0
  43. package/android/src/main/java/expo/modules/kotlin/objects/PropertyComponentBuilder.kt +32 -0
  44. package/android/src/main/java/expo/modules/kotlin/types/AnyTypeConverter.kt +36 -0
  45. package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +7 -0
  46. package/android/src/main/java/expo/modules/kotlin/views/ViewGroupDefinitionBuilder.kt +0 -41
  47. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinitionBuilder.kt +0 -33
  48. package/build/PermissionsInterface.d.ts +29 -0
  49. package/build/PermissionsInterface.d.ts.map +1 -1
  50. package/build/PermissionsInterface.js +9 -0
  51. package/build/PermissionsInterface.js.map +1 -1
  52. package/ios/ExpoModulesCore.podspec +2 -1
  53. package/ios/JSI/EXJSIInstaller.mm +2 -0
  54. package/ios/JSI/EXJSIUtils.h +1 -0
  55. package/ios/NativeModulesProxy/EXNativeModulesProxy.mm +4 -3
  56. package/ios/Swift/AppContext.swift +2 -4
  57. package/ios/Swift/Classes/ClassComponentElementsBuilder.swift +2 -2
  58. package/ios/Swift/Exceptions/ChainableException.swift +3 -3
  59. package/ios/Swift/ExpoBridgeModule.swift +16 -2
  60. package/ios/Swift/Logging/Logger.swift +3 -0
  61. package/ios/Swift/Promise.swift +5 -1
  62. package/package.json +2 -2
  63. package/src/PermissionsInterface.ts +29 -0
@@ -10,92 +10,38 @@ class AsyncFunctionBuilder(@PublishedApi internal val name: String) {
10
10
  @PublishedApi
11
11
  internal var functionBuilder: SuspendFunctionComponentBuilder? = null
12
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
13
  inline fun <reified R> SuspendBody(crossinline block: suspend () -> R) {
20
14
  functionBuilder = SuspendFunctionComponentBuilder(name, arrayOf()) { block() }
21
15
  }
22
16
 
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
17
  inline fun <reified R, reified P0> SuspendBody(crossinline block: suspend (p0: P0) -> R) {
30
18
  functionBuilder = SuspendFunctionComponentBuilder(name, arrayOf(typeOf<P0>().toAnyType())) { block(it[0] as P0) }
31
19
  }
32
20
 
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
21
  inline fun <reified R, reified P0, reified P1> SuspendBody(crossinline block: suspend (p0: P0, p1: P1) -> R) {
40
22
  functionBuilder = SuspendFunctionComponentBuilder(name, arrayOf(typeOf<P0>().toAnyType())) { block(it[0] as P0, it[0] as P1) }
41
23
  }
42
24
 
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
25
  inline fun <reified R, reified P0, reified P1, reified P2> SuspendBody(crossinline block: suspend (p0: P0, p1: P1, p2: P2) -> R) {
50
26
  functionBuilder = SuspendFunctionComponentBuilder(name, arrayOf(typeOf<P0>().toAnyType())) { block(it[0] as P0, it[1] as P1, it[2] as P2) }
51
27
  }
52
28
 
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
29
  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
30
  functionBuilder = SuspendFunctionComponentBuilder(name, arrayOf(typeOf<P0>().toAnyType())) { block(it[0] as P0, it[1] as P1, it[2] as P2, it[3] as P3) }
61
31
  }
62
32
 
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
33
  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
34
  functionBuilder = SuspendFunctionComponentBuilder(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
35
  }
72
36
 
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
37
  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
38
  functionBuilder = SuspendFunctionComponentBuilder(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
39
  }
82
40
 
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
41
  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
42
  functionBuilder = SuspendFunctionComponentBuilder(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
43
  }
92
44
 
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
45
  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
46
  functionBuilder = SuspendFunctionComponentBuilder(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
47
  }
@@ -105,60 +51,6 @@ class AsyncFunctionBuilder(@PublishedApi internal val name: String) {
105
51
  }
106
52
  }
107
53
 
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
54
  inline infix fun <reified R> AsyncFunctionBuilder.Coroutine(crossinline block: suspend () -> R) = SuspendBody(block)
163
55
  inline infix fun <reified R, reified P0> AsyncFunctionBuilder.Coroutine(crossinline block: suspend (P0) -> R) = SuspendBody(block)
164
56
  inline infix fun <reified R, reified P0, reified P1> AsyncFunctionBuilder.Coroutine(crossinline block: suspend (P0, P1) -> R) = SuspendBody(block)
@@ -12,7 +12,10 @@ class AsyncFunctionComponent(
12
12
  ) : AsyncFunction(name, desiredArgsTypes) {
13
13
  @Throws(CodedException::class)
14
14
  override fun call(args: ReadableArray, promise: Promise) {
15
- val convertedArgs = convertArgs(args)
16
- promise.resolve(body(convertedArgs))
15
+ promise.resolve(body(convertArgs(args)))
16
+ }
17
+
18
+ override fun call(args: Array<Any?>, promise: Promise) {
19
+ promise.resolve(body(convertArgs(args)))
17
20
  }
18
21
  }
@@ -12,7 +12,10 @@ class AsyncFunctionWithPromiseComponent(
12
12
  ) : AsyncFunction(name, desiredArgsTypes) {
13
13
  @Throws(CodedException::class)
14
14
  override fun call(args: ReadableArray, promise: Promise) {
15
- val convertedArgs = convertArgs(args)
16
- body(convertedArgs, promise)
15
+ body(convertArgs(args), promise)
16
+ }
17
+
18
+ override fun call(args: Array<Any?>, promise: Promise) {
19
+ body(convertArgs(args), promise)
17
20
  }
18
21
  }
@@ -12,7 +12,6 @@ import kotlinx.coroutines.CoroutineScope
12
12
  import kotlinx.coroutines.isActive
13
13
  import kotlinx.coroutines.launch
14
14
  import java.lang.ref.WeakReference
15
- import kotlin.jvm.Throws
16
15
 
17
16
  /**
18
17
  * We can't construct a `SuspendFunctionComponent` in the build phase, because it has to have access to module coroutine scope.
@@ -35,9 +34,17 @@ class SuspendFunctionComponent(
35
34
  ) : AsyncFunction(name, desiredArgsTypes) {
36
35
  @Throws(CodedException::class)
37
36
  override fun call(args: ReadableArray, promise: Promise) {
37
+ callWithConvertedArguments(convertArgs(args), promise)
38
+ }
39
+
40
+ override fun call(args: Array<Any?>, promise: Promise) {
41
+ callWithConvertedArguments(convertArgs(args), promise)
42
+ }
43
+
44
+ private fun callWithConvertedArguments(convertedArgs: Array<out Any?>, promise: Promise) {
38
45
  val holder = moduleHolderRef.get() ?: return
39
46
  val scope = holder.module.coroutineScopeDelegate.value
40
- val convertedArgs = convertArgs(args)
47
+
41
48
  scope.launch {
42
49
  try {
43
50
  val result = exceptionDecorator({ cause -> FunctionCallException(name, holder.name, cause) }) {
@@ -18,8 +18,16 @@ class SyncFunctionComponent(
18
18
  return body(convertArgs(args))
19
19
  }
20
20
 
21
+ fun call(args: Array<Any?>): Any? {
22
+ return body(convertArgs(args))
23
+ }
24
+
21
25
  override fun attachToJSObject(appContext: AppContext, jsObject: JavaScriptModuleObject) {
22
- jsObject.registerSyncFunction(name, argsCount) { args ->
26
+ jsObject.registerSyncFunction(
27
+ name,
28
+ argsCount,
29
+ getCppRequiredTypes()
30
+ ) { args ->
23
31
  val result = call(args)
24
32
  val convertedResult = JSTypeConverter.convertToJSValue(result)
25
33
  return@registerSyncFunction Arguments.fromJavaArgs(arrayOf(convertedResult))
@@ -8,6 +8,7 @@ private fun nextValue(): Int = (1 shl nextValue).also { nextValue++ }
8
8
  * Enum that represents Cpp types. Objects of those types can be obtained via JNI.
9
9
  */
10
10
  enum class CppType(val value: Int) {
11
+ NONE(0),
11
12
  DOUBLE(nextValue()),
12
13
  BOOLEAN(nextValue()),
13
14
  STRING(nextValue()),
@@ -18,7 +18,7 @@ fun interface JNIFunctionBody {
18
18
  * In the future, we may want to swap it for something else.
19
19
  */
20
20
  @DoNotStrip
21
- fun invoke(args: ReadableNativeArray): ReadableNativeArray?
21
+ fun invoke(args: Array<Any?>): ReadableNativeArray?
22
22
  }
23
23
 
24
24
  /**
@@ -35,5 +35,5 @@ fun interface JNIAsyncFunctionBody {
35
35
  * This is dictated by the fact that [com.facebook.react.bridge.Promise] isn't a hybrid object of jni::HybridClass.
36
36
  */
37
37
  @DoNotStrip
38
- fun invoke(args: ReadableNativeArray, bridgePromise: Any)
38
+ fun invoke(args: Array<Any?>, bridgePromise: Any)
39
39
  }
@@ -29,13 +29,15 @@ class JavaScriptModuleObject {
29
29
  * Register a promise-less function on the CPP module representation.
30
30
  * After calling this function, user can access the exported function in the JS code.
31
31
  */
32
- external fun registerSyncFunction(name: String, args: Int, body: JNIFunctionBody)
32
+ external fun registerSyncFunction(name: String, args: Int, desiredTypes: IntArray, body: JNIFunctionBody)
33
33
 
34
34
  /**
35
35
  * Register a promise function on the CPP module representation.
36
36
  * After calling this function, user can access the exported function in the JS code.
37
37
  */
38
- external fun registerAsyncFunction(name: String, args: Int, body: JNIAsyncFunctionBody)
38
+ external fun registerAsyncFunction(name: String, args: Int, desiredTypes: IntArray, body: JNIAsyncFunctionBody)
39
+
40
+ external fun registerProperty(name: String, desiredType: Int, getter: JNIFunctionBody?, setter: JNIFunctionBody?)
39
41
 
40
42
  @Throws(Throwable::class)
41
43
  protected fun finalize() {
@@ -45,5 +45,5 @@ abstract class Module : AppContextProvider {
45
45
 
46
46
  @Suppress("FunctionName")
47
47
  inline fun Module.ModuleDefinition(block: ModuleDefinitionBuilder.() -> Unit): ModuleDefinitionData {
48
- return ModuleDefinitionBuilder(this).also(block).build()
48
+ return ModuleDefinitionBuilder(this).also(block).buildModule()
49
49
  }