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
@@ -0,0 +1,271 @@
1
+ /**
2
+ * We used a function from the experimental STD API - typeOf (see kotlinlang.org/api/latest/jvm/stdlib/kotlin.reflect/type-of.html).
3
+ * We shouldn't have any problem with that function, cause it's widely used in other libraries created by JetBrains like kotlinx-serializer.
4
+ * This function is super handy if we want to receive a collection type.
5
+ * For example, it's very hard to obtain the generic parameter type from the list class.
6
+ * In plain Java, it's almost impossible. There is a trick to getting such information using something called TypeToken.
7
+ * For instance, the Gson library uses this workaround. But there still will be a problem with nullability.
8
+ * We didn't find a good solution to distinguish between List<Any?> and List<Any>.
9
+ * Mainly because from the JVM perspective it's the same type.
10
+ * That's why we used typeOf. It solves all problems described above.
11
+ */
12
+ @file:OptIn(ExperimentalStdlibApi::class)
13
+ @file:Suppress("FunctionName")
14
+
15
+ package expo.modules.kotlin.objects
16
+
17
+ import expo.modules.kotlin.Promise
18
+ import expo.modules.kotlin.events.EventsDefinition
19
+ import expo.modules.kotlin.functions.AsyncFunction
20
+ import expo.modules.kotlin.functions.AsyncFunctionBuilder
21
+ import expo.modules.kotlin.functions.AsyncFunctionComponent
22
+ import expo.modules.kotlin.functions.AsyncFunctionWithPromiseComponent
23
+ import expo.modules.kotlin.functions.SyncFunctionComponent
24
+ import expo.modules.kotlin.types.toAnyType
25
+ import kotlin.reflect.typeOf
26
+
27
+ /**
28
+ * Base class for other definitions representing an object, such as `ModuleDefinition`.
29
+ */
30
+ open class ObjectDefinitionBuilder {
31
+ private var constantsProvider = { emptyMap<String, Any?>() }
32
+ private var eventsDefinition: EventsDefinition? = null
33
+
34
+ @PublishedApi
35
+ internal var syncFunctions = mutableMapOf<String, SyncFunctionComponent>()
36
+
37
+ @PublishedApi
38
+ internal var asyncFunctions = mutableMapOf<String, AsyncFunction>()
39
+
40
+ private var functionBuilders = mutableMapOf<String, AsyncFunctionBuilder>()
41
+
42
+ @PublishedApi
43
+ internal var properties = mutableMapOf<String, PropertyComponentBuilder>()
44
+
45
+ fun buildObject(): ObjectDefinitionData {
46
+ return ObjectDefinitionData(
47
+ constantsProvider,
48
+ syncFunctions,
49
+ asyncFunctions,
50
+ functionBuilders.mapValues { (_, value) -> value.build() },
51
+ eventsDefinition,
52
+ properties.mapValues { (_, value) -> value.build() }
53
+ )
54
+ }
55
+
56
+ /**
57
+ * Definition function setting the module's constants to export.
58
+ */
59
+ fun Constants(constantsProvider: () -> Map<String, Any?>) {
60
+ this.constantsProvider = constantsProvider
61
+ }
62
+
63
+ /**
64
+ * Definition of the module's constants to export.
65
+ */
66
+ fun Constants(vararg constants: Pair<String, Any?>) {
67
+ constantsProvider = { constants.toMap() }
68
+ }
69
+
70
+ @JvmName("FunctionWithoutArgs")
71
+ inline fun Function(
72
+ name: String,
73
+ crossinline body: () -> Any?
74
+ ) {
75
+ SyncFunctionComponent(name, arrayOf()) { body() }.also {
76
+ syncFunctions[name] = it
77
+ }
78
+ }
79
+
80
+ inline fun <reified R> Function(
81
+ name: String,
82
+ crossinline body: () -> R
83
+ ) {
84
+ SyncFunctionComponent(name, arrayOf()) { body() }.also {
85
+ syncFunctions[name] = it
86
+ }
87
+ }
88
+
89
+ inline fun <reified R, reified P0> Function(
90
+ name: String,
91
+ crossinline body: (p0: P0) -> R
92
+ ) {
93
+ SyncFunctionComponent(name, arrayOf(typeOf<P0>().toAnyType())) { body(it[0] as P0) }.also {
94
+ syncFunctions[name] = it
95
+ }
96
+ }
97
+
98
+ inline fun <reified R, reified P0, reified P1> Function(
99
+ name: String,
100
+ crossinline body: (p0: P0, p1: P1) -> R
101
+ ) {
102
+ SyncFunctionComponent(name, arrayOf(typeOf<P0>().toAnyType(), typeOf<P1>().toAnyType())) { body(it[0] as P0, it[1] as P1) }.also {
103
+ syncFunctions[name] = it
104
+ }
105
+ }
106
+
107
+ inline fun <reified R, reified P0, reified P1, reified P2> Function(
108
+ name: String,
109
+ crossinline body: (p0: P0, p1: P1, p2: P2) -> R
110
+ ) {
111
+ SyncFunctionComponent(name, arrayOf(typeOf<P0>().toAnyType(), typeOf<P1>().toAnyType(), typeOf<P2>().toAnyType())) { body(it[0] as P0, it[1] as P1, it[2] as P2) }.also {
112
+ syncFunctions[name] = it
113
+ }
114
+ }
115
+
116
+ inline fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4, reified P5> Function(
117
+ name: String,
118
+ crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5) -> R
119
+ ) {
120
+ SyncFunctionComponent(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) }.also {
121
+ syncFunctions[name] = it
122
+ }
123
+ }
124
+
125
+ @JvmName("AsyncFunctionWithoutArgs")
126
+ inline fun AsyncFunction(
127
+ name: String,
128
+ crossinline body: () -> Any?
129
+ ) {
130
+ asyncFunctions[name] = AsyncFunctionComponent(name, arrayOf()) { body() }
131
+ }
132
+
133
+ inline fun <reified R> AsyncFunction(
134
+ name: String,
135
+ crossinline body: () -> R
136
+ ) {
137
+ asyncFunctions[name] = AsyncFunctionComponent(name, arrayOf()) { body() }
138
+ }
139
+
140
+ inline fun <reified R, reified P0> AsyncFunction(
141
+ name: String,
142
+ crossinline body: (p0: P0) -> R
143
+ ) {
144
+ asyncFunctions[name] = if (P0::class == Promise::class) {
145
+ AsyncFunctionWithPromiseComponent(name, arrayOf()) { _, promise -> body(promise as P0) }
146
+ } else {
147
+ AsyncFunctionComponent(name, arrayOf(typeOf<P0>().toAnyType())) { body(it[0] as P0) }
148
+ }
149
+ }
150
+
151
+ inline fun <reified R, reified P0, reified P1> AsyncFunction(
152
+ name: String,
153
+ crossinline body: (p0: P0, p1: P1) -> R
154
+ ) {
155
+ asyncFunctions[name] = if (P1::class == Promise::class) {
156
+ AsyncFunctionWithPromiseComponent(name, arrayOf(typeOf<P0>().toAnyType())) { args, promise -> body(args[0] as P0, promise as P1) }
157
+ } else {
158
+ AsyncFunctionComponent(name, arrayOf(typeOf<P0>().toAnyType(), typeOf<P1>().toAnyType())) { body(it[0] as P0, it[1] as P1) }
159
+ }
160
+ }
161
+
162
+ inline fun <reified R, reified P0, reified P1, reified P2> AsyncFunction(
163
+ name: String,
164
+ crossinline body: (p0: P0, p1: P1, p2: P2) -> R
165
+ ) {
166
+ asyncFunctions[name] = if (P2::class == Promise::class) {
167
+ AsyncFunctionWithPromiseComponent(name, arrayOf(typeOf<P0>().toAnyType(), typeOf<P1>().toAnyType())) { args, promise -> body(args[0] as P0, args[1] as P1, promise as P2) }
168
+ } else {
169
+ 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) }
170
+ }
171
+ }
172
+
173
+ inline fun <reified R, reified P0, reified P1, reified P2, reified P3> AsyncFunction(
174
+ name: String,
175
+ crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3) -> R
176
+ ) {
177
+ asyncFunctions[name] = if (P3::class == Promise::class) {
178
+ 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) }
179
+ } else {
180
+ 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) }
181
+ }
182
+ }
183
+
184
+ inline fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4> AsyncFunction(
185
+ name: String,
186
+ crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4) -> R
187
+ ) {
188
+ asyncFunctions[name] = if (P4::class == Promise::class) {
189
+ 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) }
190
+ } else {
191
+ 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) }
192
+ }
193
+ }
194
+
195
+ inline fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4, reified P5> AsyncFunction(
196
+ name: String,
197
+ crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5) -> R
198
+ ) {
199
+ asyncFunctions[name] = if (P5::class == Promise::class) {
200
+ 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) }
201
+ } else {
202
+ 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) }
203
+ }
204
+ }
205
+
206
+ inline fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4, reified P5, reified P6> AsyncFunction(
207
+ name: String,
208
+ crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6) -> R
209
+ ) {
210
+ asyncFunctions[name] = if (P6::class == Promise::class) {
211
+ 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) }
212
+ } else {
213
+ 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) }
214
+ }
215
+ }
216
+
217
+ inline fun <reified R, reified P0, reified P1, reified P2, reified P3, reified P4, reified P5, reified P6, reified P7> AsyncFunction(
218
+ name: String,
219
+ crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7) -> R
220
+ ) {
221
+ asyncFunctions[name] = if (P7::class == Promise::class) {
222
+ 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) }
223
+ } else {
224
+ 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) }
225
+ }
226
+ }
227
+
228
+ fun AsyncFunction(
229
+ name: String
230
+ ) = AsyncFunctionBuilder(name).also { functionBuilders[name] = it }
231
+
232
+ /**
233
+ * Defines event names that this module can send to JavaScript.
234
+ */
235
+ fun Events(vararg events: String) {
236
+ eventsDefinition = EventsDefinition(events)
237
+ }
238
+
239
+ /**
240
+ * Creates module's lifecycle listener that is called right after the first event listener is added.
241
+ */
242
+ inline fun OnStartObserving(crossinline body: () -> Unit) {
243
+ AsyncFunction("startObserving", body)
244
+ }
245
+
246
+ /**
247
+ * Creates module's lifecycle listener that is called right after all event listeners are removed.
248
+ */
249
+ inline fun OnStopObserving(crossinline body: () -> Unit) {
250
+ AsyncFunction("stopObserving", body)
251
+ }
252
+
253
+ /**
254
+ * Creates the property with given name. The component is basically no-op if you don't call `.get()` or `.set()` on it.
255
+ */
256
+ fun Property(name: String): PropertyComponentBuilder {
257
+ return PropertyComponentBuilder(name).also {
258
+ properties[name] = it
259
+ }
260
+ }
261
+
262
+ /**
263
+ * Creates the read-only property whose getter doesn't take the caller as an argument.
264
+ */
265
+ inline fun <T> Property(name: String, crossinline body: () -> T): PropertyComponentBuilder {
266
+ return PropertyComponentBuilder(name).also {
267
+ it.get(body)
268
+ properties[name] = it
269
+ }
270
+ }
271
+ }
@@ -0,0 +1,21 @@
1
+ package expo.modules.kotlin.objects
2
+
3
+ import expo.modules.kotlin.ModuleHolder
4
+ import expo.modules.kotlin.events.EventsDefinition
5
+ import expo.modules.kotlin.functions.AsyncFunction
6
+ import expo.modules.kotlin.functions.SuspendFunctionComponent
7
+ import expo.modules.kotlin.functions.SuspendFunctionComponentBuilder
8
+ import expo.modules.kotlin.functions.SyncFunctionComponent
9
+
10
+ class ObjectDefinitionData(
11
+ val constantsProvider: () -> Map<String, Any?>,
12
+ val syncFunctions: Map<String, SyncFunctionComponent>,
13
+ val asyncFunctions: Map<String, AsyncFunction>,
14
+ val suspendFunctionBuilders: Map<String, SuspendFunctionComponentBuilder>,
15
+ val eventsDefinition: EventsDefinition?,
16
+ val properties: Map<String, PropertyComponent>
17
+ ) {
18
+ fun buildSuspendFunctions(moduleHolder: ModuleHolder): Map<String, SuspendFunctionComponent> {
19
+ return suspendFunctionBuilders.mapValues { (_, value) -> value.build(moduleHolder) }
20
+ }
21
+ }
@@ -0,0 +1,54 @@
1
+ package expo.modules.kotlin.objects
2
+
3
+ import com.facebook.react.bridge.Arguments
4
+ import expo.modules.kotlin.functions.SyncFunctionComponent
5
+ import expo.modules.kotlin.jni.CppType
6
+ import expo.modules.kotlin.jni.JNIFunctionBody
7
+ import expo.modules.kotlin.jni.JavaScriptModuleObject
8
+
9
+ class PropertyComponent(
10
+ /**
11
+ * Name of the property.
12
+ */
13
+ val name: String,
14
+
15
+ /**
16
+ * Synchronous function that is called when the property is being accessed.
17
+ */
18
+ val getter: SyncFunctionComponent? = null,
19
+
20
+ /**
21
+ * Synchronous function that is called when the property is being set.
22
+ */
23
+ val setter: SyncFunctionComponent? = null
24
+ ) {
25
+ /**
26
+ * Attaches property to the provided js object.
27
+ */
28
+ fun attachToJSObject(jsObject: JavaScriptModuleObject) {
29
+ val jniGetter = if (getter != null) {
30
+ JNIFunctionBody {
31
+ val result = getter.call(emptyArray())
32
+ return@JNIFunctionBody Arguments.fromJavaArgs(arrayOf(result))
33
+ }
34
+ } else {
35
+ null
36
+ }
37
+
38
+ val jniSetter = if (setter != null) {
39
+ JNIFunctionBody { args ->
40
+ setter.call(args)
41
+ return@JNIFunctionBody null
42
+ }
43
+ } else {
44
+ null
45
+ }
46
+
47
+ jsObject.registerProperty(
48
+ name,
49
+ setter?.getCppRequiredTypes()?.first() ?: CppType.NONE.value,
50
+ jniGetter,
51
+ jniSetter
52
+ )
53
+ }
54
+ }
@@ -0,0 +1,32 @@
1
+ @file:OptIn(ExperimentalStdlibApi::class)
2
+
3
+ package expo.modules.kotlin.objects
4
+
5
+ import expo.modules.kotlin.functions.SyncFunctionComponent
6
+ import expo.modules.kotlin.types.toAnyType
7
+ import kotlin.reflect.typeOf
8
+
9
+ class PropertyComponentBuilder(
10
+ val name: String
11
+ ) {
12
+ var getter: SyncFunctionComponent? = null
13
+ var setter: SyncFunctionComponent? = null
14
+
15
+ /**
16
+ * Modifier that sets property getter that has no arguments (the caller is not used).
17
+ */
18
+ inline fun <T> get(crossinline body: () -> T) = apply {
19
+ getter = SyncFunctionComponent("get", arrayOf()) { body() }
20
+ }
21
+
22
+ /**
23
+ * Modifier that sets property setter that receives only the new value as an argument.
24
+ */
25
+ inline fun <reified T> set(crossinline body: (newValue: T) -> Unit) = apply {
26
+ setter = SyncFunctionComponent("set", arrayOf(typeOf<T>().toAnyType())) { body(it[0] as T) }
27
+ }
28
+
29
+ fun build(): PropertyComponent {
30
+ return PropertyComponent(name, getter, setter)
31
+ }
32
+ }
@@ -0,0 +1,36 @@
1
+ package expo.modules.kotlin.types
2
+
3
+ import com.facebook.react.bridge.Dynamic
4
+ import com.facebook.react.bridge.ReadableType
5
+ import expo.modules.kotlin.jni.CppType
6
+
7
+ /**
8
+ * Type converter that handles conversion from [Any] or [Dynamic] to [Any].
9
+ * In the first case, it will just pass provided value.
10
+ * In case when it receives [Dynamic], it will unpack the provided value.
11
+ * In that way, we produce the same output for JSI and bridge implementation.
12
+ */
13
+ class AnyTypeConverter(isOptional: Boolean) : DynamicAwareTypeConverters<Any>(isOptional) {
14
+ override fun convertFromDynamic(value: Dynamic): Any {
15
+ return when (value.type) {
16
+ ReadableType.Boolean -> value.asBoolean()
17
+ ReadableType.Number -> value.asDouble()
18
+ ReadableType.String -> value.asString()
19
+ ReadableType.Map -> value.asMap()
20
+ ReadableType.Array -> value.asArray()
21
+ else -> error("Unknown dynamic type: ${value.type}")
22
+ }
23
+ }
24
+
25
+ override fun convertFromAny(value: Any): Any {
26
+ return value
27
+ }
28
+
29
+ override fun getCppRequiredTypes(): List<CppType> = listOf(
30
+ CppType.READABLE_MAP,
31
+ CppType.READABLE_ARRAY,
32
+ CppType.STRING,
33
+ CppType.BOOLEAN,
34
+ CppType.DOUBLE
35
+ )
36
+ }
@@ -30,6 +30,11 @@ inline fun <reified T> convert(value: Dynamic): T {
30
30
  return converter.convert(value) as T
31
31
  }
32
32
 
33
+ inline fun <reified T> convert(value: Any?): T {
34
+ val converter = TypeConverterProviderImpl.obtainTypeConverter(typeOf<T>())
35
+ return converter.convert(value) as T
36
+ }
37
+
33
38
  fun convert(value: Dynamic, type: KType): Any? {
34
39
  val converter = TypeConverterProviderImpl.obtainTypeConverter(type)
35
40
  return converter.convert(value)
@@ -115,6 +120,8 @@ object TypeConverterProviderImpl : TypeConverterProvider {
115
120
 
116
121
  JavaScriptValue::class.createType(nullable = isOptional) to JavaScriptValueTypeConvert(isOptional),
117
122
  JavaScriptObject::class.createType(nullable = isOptional) to JavaScriptObjectTypeConverter(isOptional),
123
+
124
+ Any::class.createType(nullable = isOptional) to AnyTypeConverter(isOptional),
118
125
  )
119
126
  }
120
127
  }
@@ -1,4 +1,3 @@
1
- @file:OptIn(ExperimentalStdlibApi::class)
2
1
  @file:Suppress("FunctionName")
3
2
 
4
3
  package expo.modules.kotlin.views
@@ -32,14 +31,6 @@ class ViewGroupDefinitionBuilder {
32
31
  removeViewAtAction
33
32
  )
34
33
 
35
- @Deprecated(
36
- message = "The 'addChildView' component was renamed to 'AddChildView'.",
37
- replaceWith = ReplaceWith("AddChildView(body)")
38
- )
39
- inline fun <reified ParentViewType : ViewGroup, reified ChildViewType : View> addChildView(
40
- noinline body: (parent: ParentViewType, child: ChildViewType, index: Int) -> Unit
41
- ) = AddChildView(body)
42
-
43
34
  inline fun <reified ParentViewType : ViewGroup, reified ChildViewType : View> AddChildView(
44
35
  noinline body: (parent: ParentViewType, child: ChildViewType, index: Int) -> Unit
45
36
  ) {
@@ -48,14 +39,6 @@ class ViewGroupDefinitionBuilder {
48
39
  }
49
40
  }
50
41
 
51
- @Deprecated(
52
- message = "The 'getChildCount' component was renamed to 'GetChildCount'.",
53
- replaceWith = ReplaceWith("GetChildCount(body)")
54
- )
55
- inline fun <reified ParentViewType : ViewGroup> getChildCount(
56
- noinline body: (view: ParentViewType) -> Int
57
- ) = GetChildCount(body)
58
-
59
42
  inline fun <reified ParentViewType : ViewGroup> GetChildCount(
60
43
  noinline body: (view: ParentViewType) -> Int
61
44
  ) {
@@ -64,14 +47,6 @@ class ViewGroupDefinitionBuilder {
64
47
  }
65
48
  }
66
49
 
67
- @Deprecated(
68
- message = "The 'getChildViewAt' component was renamed to 'GetChildViewAt'.",
69
- replaceWith = ReplaceWith("GetChildViewAt(body)")
70
- )
71
- inline fun <reified ParentViewType : ViewGroup, reified ChildViewType : View> getChildViewAt(
72
- noinline body: (view: ParentViewType, index: Int) -> ChildViewType?
73
- ) = GetChildViewAt(body)
74
-
75
50
  inline fun <reified ParentViewType : ViewGroup, reified ChildViewType : View> GetChildViewAt(
76
51
  noinline body: (view: ParentViewType, index: Int) -> ChildViewType?
77
52
  ) {
@@ -80,14 +55,6 @@ class ViewGroupDefinitionBuilder {
80
55
  }
81
56
  }
82
57
 
83
- @Deprecated(
84
- message = "The 'removeChildViewAt' component was renamed to 'RemoveChildViewAt'.",
85
- replaceWith = ReplaceWith("RemoveChildViewAt(body)")
86
- )
87
- inline fun <reified ParentViewType : ViewGroup> removeChildViewAt(
88
- noinline body: (view: ParentViewType, index: Int) -> Unit
89
- ) = RemoveChildViewAt(body)
90
-
91
58
  inline fun <reified ParentViewType : ViewGroup> RemoveChildViewAt(
92
59
  noinline body: (view: ParentViewType, index: Int) -> Unit
93
60
  ) {
@@ -96,14 +63,6 @@ class ViewGroupDefinitionBuilder {
96
63
  }
97
64
  }
98
65
 
99
- @Deprecated(
100
- message = "The 'removeChildView' component was renamed to 'RemoveChildView'.",
101
- replaceWith = ReplaceWith("RemoveChildView(body)")
102
- )
103
- inline fun <reified ParentViewType : ViewGroup, reified ChildViewType : View> removeChildView(
104
- noinline body: (parent: ParentViewType, child: ChildViewType) -> Unit
105
- ) = RemoveChildView(body)
106
-
107
66
  inline fun <reified ParentViewType : ViewGroup, reified ChildViewType : View> RemoveChildView(
108
67
  noinline body: (parent: ParentViewType, child: ChildViewType) -> Unit
109
68
  ) {
@@ -37,12 +37,6 @@ class ViewManagerDefinitionBuilder {
37
37
  viewGroupDefinition
38
38
  )
39
39
 
40
- @Deprecated(
41
- message = "The 'view' component was renamed to 'View'.",
42
- replaceWith = ReplaceWith("View(body)")
43
- )
44
- inline fun <reified ViewType : View> view(noinline body: (Context) -> ViewType) = View(body)
45
-
46
40
  /**
47
41
  * Defines the factory creating a native view when the module is used as a view.
48
42
  */
@@ -51,12 +45,6 @@ class ViewManagerDefinitionBuilder {
51
45
  viewFactory = body
52
46
  }
53
47
 
54
- @Deprecated(
55
- message = "The 'onViewDestroys' component was renamed to 'OnViewDestroys'.",
56
- replaceWith = ReplaceWith("OnViewDestroys(body)")
57
- )
58
- inline fun <reified ViewType : View> onViewDestroys(noinline body: (view: ViewType) -> Unit) = OnViewDestroys(body)
59
-
60
48
  /**
61
49
  * Creates view's lifecycle listener that is called right after the view isn't longer used by React Native.
62
50
  */
@@ -64,15 +52,6 @@ class ViewManagerDefinitionBuilder {
64
52
  onViewDestroys = { body(it as ViewType) }
65
53
  }
66
54
 
67
- @Deprecated(
68
- message = "The 'prop' component was renamed to 'Prop'.",
69
- replaceWith = ReplaceWith("Prop(body)")
70
- )
71
- inline fun <reified ViewType : View, reified PropType> prop(
72
- name: String,
73
- noinline body: (view: ViewType, prop: PropType) -> Unit
74
- ) = Prop(name, body)
75
-
76
55
  /**
77
56
  * Creates a view prop that defines its name and setter.
78
57
  */
@@ -87,12 +66,6 @@ class ViewManagerDefinitionBuilder {
87
66
  )
88
67
  }
89
68
 
90
- @Deprecated(
91
- message = "The 'events' component was renamed to 'Events'.",
92
- replaceWith = ReplaceWith("Events(callbacks)")
93
- )
94
- fun events(vararg callbacks: String) = Events(*callbacks)
95
-
96
69
  /**
97
70
  * Defines prop names that should be treated as callbacks.
98
71
  */
@@ -100,12 +73,6 @@ class ViewManagerDefinitionBuilder {
100
73
  callbacksDefinition = CallbacksDefinition(callbacks)
101
74
  }
102
75
 
103
- @Deprecated(
104
- message = "The 'groupView' component was renamed to 'GroupView'.",
105
- replaceWith = ReplaceWith("GroupView(callbacks)")
106
- )
107
- inline fun groupView(body: ViewGroupDefinitionBuilder.() -> Unit) = GroupView(body)
108
-
109
76
  /**
110
77
  * Creates the group view definition that scopes group view-related definitions.
111
78
  */
@@ -1,13 +1,42 @@
1
1
  export declare enum PermissionStatus {
2
+ /**
3
+ * User has granted the permission.
4
+ */
2
5
  GRANTED = "granted",
6
+ /**
7
+ * User hasn't granted or denied the permission yet.
8
+ */
3
9
  UNDETERMINED = "undetermined",
10
+ /**
11
+ * User has denied the permission.
12
+ */
4
13
  DENIED = "denied"
5
14
  }
15
+ /**
16
+ * Permission expiration time. Currently, all permissions are granted permamently.
17
+ */
6
18
  export declare type PermissionExpiration = 'never' | number;
19
+ /**
20
+ * An object obtained by `getPermissionsAsync` and `requestPermissionsAsync` functions.
21
+ */
7
22
  export interface PermissionResponse {
23
+ /**
24
+ * Determines the status of the permission.
25
+ */
8
26
  status: PermissionStatus;
27
+ /**
28
+ * Determines time when the permission expires.
29
+ */
9
30
  expires: PermissionExpiration;
31
+ /**
32
+ * A convenience boolean that indicates if the permission is granted.
33
+ */
10
34
  granted: boolean;
35
+ /**
36
+ * Indicates if user can be asked again for specific permission.
37
+ * If not, one should be directed to the Settings app
38
+ * in order to enable/disable the permission.
39
+ */
11
40
  canAskAgain: boolean;
12
41
  }
13
42
  //# sourceMappingURL=PermissionsInterface.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"PermissionsInterface.d.ts","sourceRoot":"","sources":["../src/PermissionsInterface.ts"],"names":[],"mappings":"AAAA,oBAAY,gBAAgB;IAC1B,OAAO,YAAY;IACnB,YAAY,iBAAiB;IAC7B,MAAM,WAAW;CAClB;AAED,oBAAY,oBAAoB,GAAG,OAAO,GAAG,MAAM,CAAC;AAEpD,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,gBAAgB,CAAC;IACzB,OAAO,EAAE,oBAAoB,CAAC;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;CACtB"}
1
+ {"version":3,"file":"PermissionsInterface.d.ts","sourceRoot":"","sources":["../src/PermissionsInterface.ts"],"names":[],"mappings":"AAAA,oBAAY,gBAAgB;IAC1B;;OAEG;IACH,OAAO,YAAY;IACnB;;OAEG;IACH,YAAY,iBAAiB;IAC7B;;OAEG;IACH,MAAM,WAAW;CAClB;AAED;;GAEG;AACH,oBAAY,oBAAoB,GAAG,OAAO,GAAG,MAAM,CAAC;AAEpD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,MAAM,EAAE,gBAAgB,CAAC;IACzB;;OAEG;IACH,OAAO,EAAE,oBAAoB,CAAC;IAC9B;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,WAAW,EAAE,OAAO,CAAC;CACtB"}
@@ -1,7 +1,16 @@
1
1
  export var PermissionStatus;
2
2
  (function (PermissionStatus) {
3
+ /**
4
+ * User has granted the permission.
5
+ */
3
6
  PermissionStatus["GRANTED"] = "granted";
7
+ /**
8
+ * User hasn't granted or denied the permission yet.
9
+ */
4
10
  PermissionStatus["UNDETERMINED"] = "undetermined";
11
+ /**
12
+ * User has denied the permission.
13
+ */
5
14
  PermissionStatus["DENIED"] = "denied";
6
15
  })(PermissionStatus || (PermissionStatus = {}));
7
16
  //# sourceMappingURL=PermissionsInterface.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PermissionsInterface.js","sourceRoot":"","sources":["../src/PermissionsInterface.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,gBAIX;AAJD,WAAY,gBAAgB;IAC1B,uCAAmB,CAAA;IACnB,iDAA6B,CAAA;IAC7B,qCAAiB,CAAA;AACnB,CAAC,EAJW,gBAAgB,KAAhB,gBAAgB,QAI3B","sourcesContent":["export enum PermissionStatus {\n GRANTED = 'granted',\n UNDETERMINED = 'undetermined',\n DENIED = 'denied',\n}\n\nexport type PermissionExpiration = 'never' | number;\n\nexport interface PermissionResponse {\n status: PermissionStatus;\n expires: PermissionExpiration;\n granted: boolean;\n canAskAgain: boolean;\n}\n"]}
1
+ {"version":3,"file":"PermissionsInterface.js","sourceRoot":"","sources":["../src/PermissionsInterface.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,gBAaX;AAbD,WAAY,gBAAgB;IAC1B;;OAEG;IACH,uCAAmB,CAAA;IACnB;;OAEG;IACH,iDAA6B,CAAA;IAC7B;;OAEG;IACH,qCAAiB,CAAA;AACnB,CAAC,EAbW,gBAAgB,KAAhB,gBAAgB,QAa3B","sourcesContent":["export enum PermissionStatus {\n /**\n * User has granted the permission.\n */\n GRANTED = 'granted',\n /**\n * User hasn't granted or denied the permission yet.\n */\n UNDETERMINED = 'undetermined',\n /**\n * User has denied the permission.\n */\n DENIED = 'denied',\n}\n\n/**\n * Permission expiration time. Currently, all permissions are granted permamently.\n */\nexport type PermissionExpiration = 'never' | number;\n\n/**\n * An object obtained by `getPermissionsAsync` and `requestPermissionsAsync` functions.\n */\nexport interface PermissionResponse {\n /**\n * Determines the status of the permission.\n */\n status: PermissionStatus;\n /**\n * Determines time when the permission expires.\n */\n expires: PermissionExpiration;\n /**\n * A convenience boolean that indicates if the permission is granted.\n */\n granted: boolean;\n /**\n * Indicates if user can be asked again for specific permission.\n * If not, one should be directed to the Settings app\n * in order to enable/disable the permission.\n */\n canAskAgain: boolean;\n}\n"]}
@@ -22,9 +22,10 @@ Pod::Spec.new do |s|
22
22
  'DEFINES_MODULE' => 'YES',
23
23
  'CLANG_CXX_LANGUAGE_STANDARD' => 'c++14',
24
24
  'SWIFT_COMPILATION_MODE' => 'wholemodule',
25
+ 'HEADER_SEARCH_PATHS' => "\"$(PODS_ROOT)/Headers/Private/React-bridging/react/bridging\" \"$(PODS_CONFIGURATION_BUILD_DIR)/React-bridging/react_bridging.framework/Headers\"",
25
26
  }
26
27
  s.user_target_xcconfig = {
27
- "HEADER_SEARCH_PATHS" => "\"${PODS_CONFIGURATION_BUILD_DIR}/ExpoModulesCore/Swift Compatibility Header\"",
28
+ "HEADER_SEARCH_PATHS" => "\"${PODS_CONFIGURATION_BUILD_DIR}/ExpoModulesCore/Swift Compatibility Header\" \"$(PODS_ROOT)/Headers/Private/React-bridging/react/bridging\" \"$(PODS_CONFIGURATION_BUILD_DIR)/React-bridging/react_bridging.framework/Headers\"",
28
29
  }
29
30
 
30
31
  s.dependency 'React-Core'