expo-modules-core 2.3.13 → 2.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/android/build.gradle +3 -2
- package/android/src/main/java/expo/modules/kotlin/classcomponent/ClassComponentBuilder.kt +22 -11
- package/android/src/main/java/expo/modules/kotlin/events/EventsDefinition.kt +9 -1
- package/android/src/main/java/expo/modules/kotlin/exception/CodedException.kt +6 -0
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionBuilder.kt +28 -24
- package/android/src/main/java/expo/modules/kotlin/jni/ExpectedType.kt +122 -5
- package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +6 -1
- package/android/src/main/java/expo/modules/kotlin/modules/ModuleConvertersBuilder.kt +50 -0
- package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +31 -7
- package/android/src/main/java/expo/modules/kotlin/objects/ObjectDefinitionBuilder.kt +28 -30
- package/android/src/main/java/expo/modules/kotlin/objects/ObjectDefinitionData.kt +15 -0
- package/android/src/main/java/expo/modules/kotlin/traits/SavableTrait.kt +57 -0
- package/android/src/main/java/expo/modules/kotlin/traits/Trait.kt +8 -0
- package/android/src/main/java/expo/modules/kotlin/types/AnyType.kt +9 -0
- package/android/src/main/java/expo/modules/kotlin/types/EitherTypeConverter.kt +3 -3
- package/android/src/main/java/expo/modules/kotlin/types/ExpoDynamic.kt +57 -0
- package/android/src/main/java/expo/modules/kotlin/types/TypeConverterCollection.kt +81 -0
- package/android/src/main/java/expo/modules/kotlin/views/ConcreteViewProp.kt +18 -3
- package/android/src/main/java/expo/modules/kotlin/views/ViewDefinitionBuilder.kt +40 -25
- package/ios/Api/Factories/ViewFactories.swift +16 -0
- package/ios/Core/Conversions.swift +51 -7
- package/ios/Core/Convertibles/Convertibles+Color.swift +1 -1
- package/ios/Core/DynamicTypes/DynamicSharedObjectType.swift +25 -14
- package/ios/Core/Functions/AsyncFunctionDefinition.swift +1 -1
- package/ios/Core/Promise.swift +0 -11
- package/ios/Core/Views/ConcreteViewProp.swift +16 -0
- package/ios/Core/Views/SwiftUI/Convertibles+SwiftUI.swift +62 -0
- package/ios/Core/Views/SwiftUI/SwiftUIHostingView.swift +7 -0
- package/ios/DevTools/ExpoRequestInterceptorProtocol.swift +14 -4
- package/ios/DevTools/ModuleDefinitionEncoder.swift +182 -0
- package/ios/ReactDelegates/ExpoReactDelegate.swift +2 -2
- package/ios/ReactDelegates/ExpoReactDelegateHandler.swift +1 -1
- package/ios/Tests/FunctionSpec.swift +27 -1
- package/package.json +3 -3
|
@@ -17,6 +17,8 @@ import expo.modules.kotlin.events.OnActivityResultPayload
|
|
|
17
17
|
import expo.modules.kotlin.objects.ObjectDefinitionBuilder
|
|
18
18
|
import expo.modules.kotlin.sharedobjects.SharedObject
|
|
19
19
|
import expo.modules.kotlin.types.LazyKType
|
|
20
|
+
import expo.modules.kotlin.types.TypeConverterProvider
|
|
21
|
+
import expo.modules.kotlin.types.mergeWithDefault
|
|
20
22
|
import expo.modules.kotlin.types.toAnyType
|
|
21
23
|
import expo.modules.kotlin.views.ModuleDefinitionBuilderWithCompose
|
|
22
24
|
import expo.modules.kotlin.views.ViewDefinitionBuilder
|
|
@@ -33,10 +35,10 @@ class ModuleDefinitionBuilder(
|
|
|
33
35
|
|
|
34
36
|
@DefinitionMarker
|
|
35
37
|
open class InternalModuleDefinitionBuilder(
|
|
36
|
-
@PublishedApi internal val module: Module? = null
|
|
38
|
+
@PublishedApi internal val module: Module? = null,
|
|
39
|
+
converters: TypeConverterProvider? = module?.converters()?.mergeWithDefault()
|
|
37
40
|
) : ObjectDefinitionBuilder(
|
|
38
|
-
|
|
39
|
-
?.customConverterProvider()
|
|
41
|
+
converters
|
|
40
42
|
) {
|
|
41
43
|
@PublishedApi
|
|
42
44
|
internal var name: String? = null
|
|
@@ -89,7 +91,11 @@ open class InternalModuleDefinitionBuilder(
|
|
|
89
91
|
* Creates the view manager definition that scopes other view-related definitions.
|
|
90
92
|
*/
|
|
91
93
|
inline fun <reified T : View> View(viewClass: KClass<T>, body: ViewDefinitionBuilder<T>.() -> Unit) {
|
|
92
|
-
val viewDefinitionBuilder = ViewDefinitionBuilder(
|
|
94
|
+
val viewDefinitionBuilder = ViewDefinitionBuilder(
|
|
95
|
+
viewClass,
|
|
96
|
+
LazyKType(classifier = T::class, kTypeProvider = { typeOf<T>() }),
|
|
97
|
+
converters
|
|
98
|
+
)
|
|
93
99
|
|
|
94
100
|
viewDefinitionBuilder.UseCSSProps()
|
|
95
101
|
|
|
@@ -162,7 +168,13 @@ open class InternalModuleDefinitionBuilder(
|
|
|
162
168
|
}
|
|
163
169
|
|
|
164
170
|
inline fun Class(name: String, body: ClassComponentBuilder<Unit>.() -> Unit = {}) {
|
|
165
|
-
val clazzBuilder = ClassComponentBuilder(
|
|
171
|
+
val clazzBuilder = ClassComponentBuilder(
|
|
172
|
+
requireNotNull(module).appContext,
|
|
173
|
+
name,
|
|
174
|
+
Unit::class,
|
|
175
|
+
toAnyType<Unit>(),
|
|
176
|
+
converters
|
|
177
|
+
)
|
|
166
178
|
body.invoke(clazzBuilder)
|
|
167
179
|
classData.add(clazzBuilder.buildClass())
|
|
168
180
|
}
|
|
@@ -172,7 +184,13 @@ open class InternalModuleDefinitionBuilder(
|
|
|
172
184
|
sharedObjectClass: KClass<SharedObjectType> = SharedObjectType::class,
|
|
173
185
|
body: ClassComponentBuilder<SharedObjectType>.() -> Unit = {}
|
|
174
186
|
) {
|
|
175
|
-
val clazzBuilder = ClassComponentBuilder(
|
|
187
|
+
val clazzBuilder = ClassComponentBuilder(
|
|
188
|
+
requireNotNull(module).appContext,
|
|
189
|
+
name,
|
|
190
|
+
sharedObjectClass,
|
|
191
|
+
toAnyType<SharedObjectType>(),
|
|
192
|
+
converters
|
|
193
|
+
)
|
|
176
194
|
body.invoke(clazzBuilder)
|
|
177
195
|
classData.add(clazzBuilder.buildClass())
|
|
178
196
|
}
|
|
@@ -181,7 +199,13 @@ open class InternalModuleDefinitionBuilder(
|
|
|
181
199
|
sharedObjectClass: KClass<SharedObjectType> = SharedObjectType::class,
|
|
182
200
|
body: ClassComponentBuilder<SharedObjectType>.() -> Unit = {}
|
|
183
201
|
) {
|
|
184
|
-
val clazzBuilder = ClassComponentBuilder(
|
|
202
|
+
val clazzBuilder = ClassComponentBuilder(
|
|
203
|
+
requireNotNull(module).appContext,
|
|
204
|
+
sharedObjectClass.java.simpleName,
|
|
205
|
+
sharedObjectClass,
|
|
206
|
+
toAnyType<SharedObjectType>(),
|
|
207
|
+
converters
|
|
208
|
+
)
|
|
185
209
|
body.invoke(clazzBuilder)
|
|
186
210
|
classData.add(clazzBuilder.buildClass())
|
|
187
211
|
}
|
|
@@ -22,7 +22,6 @@ import expo.modules.kotlin.modules.convertEnumToString
|
|
|
22
22
|
import expo.modules.kotlin.types.Enumerable
|
|
23
23
|
import expo.modules.kotlin.types.TypeConverterProvider
|
|
24
24
|
import expo.modules.kotlin.types.enforceType
|
|
25
|
-
import expo.modules.kotlin.types.mergeWithDefault
|
|
26
25
|
import expo.modules.kotlin.types.toArgsArray
|
|
27
26
|
import expo.modules.kotlin.types.toReturnType
|
|
28
27
|
import kotlin.reflect.full.declaredMemberProperties
|
|
@@ -31,10 +30,9 @@ import kotlin.reflect.full.primaryConstructor
|
|
|
31
30
|
/**
|
|
32
31
|
* Base class for other definitions representing an object, such as `ModuleDefinition`.
|
|
33
32
|
*/
|
|
34
|
-
open class ObjectDefinitionBuilder(
|
|
35
|
-
@PublishedApi
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
open class ObjectDefinitionBuilder(
|
|
34
|
+
@PublishedApi internal val converters: TypeConverterProvider? = null
|
|
35
|
+
) {
|
|
38
36
|
private var legacyConstantsProvider = { emptyMap<String, Any?>() }
|
|
39
37
|
|
|
40
38
|
@PublishedApi
|
|
@@ -126,7 +124,7 @@ open class ObjectDefinitionBuilder(customConverter: TypeConverterProvider? = nul
|
|
|
126
124
|
name: String,
|
|
127
125
|
crossinline body: (p0: P0) -> R
|
|
128
126
|
): SyncFunctionComponent {
|
|
129
|
-
return SyncFunctionComponent(name, toArgsArray<P0>(converterProvider =
|
|
127
|
+
return SyncFunctionComponent(name, toArgsArray<P0>(converterProvider = converters), toReturnType<R>()) { (p0) ->
|
|
130
128
|
enforceType<P0>(p0)
|
|
131
129
|
body(p0)
|
|
132
130
|
}.also {
|
|
@@ -138,7 +136,7 @@ open class ObjectDefinitionBuilder(customConverter: TypeConverterProvider? = nul
|
|
|
138
136
|
name: String,
|
|
139
137
|
crossinline body: (p0: P0, p1: P1) -> R
|
|
140
138
|
): SyncFunctionComponent {
|
|
141
|
-
return SyncFunctionComponent(name, toArgsArray<P0, P1>(), toReturnType<R>()) { (p0, p1) ->
|
|
139
|
+
return SyncFunctionComponent(name, toArgsArray<P0, P1>(converterProvider = converters), toReturnType<R>()) { (p0, p1) ->
|
|
142
140
|
enforceType<P0, P1>(p0, p1)
|
|
143
141
|
body(p0, p1)
|
|
144
142
|
}.also {
|
|
@@ -150,7 +148,7 @@ open class ObjectDefinitionBuilder(customConverter: TypeConverterProvider? = nul
|
|
|
150
148
|
name: String,
|
|
151
149
|
crossinline body: (p0: P0, p1: P1, p2: P2) -> R
|
|
152
150
|
): SyncFunctionComponent {
|
|
153
|
-
return SyncFunctionComponent(name, toArgsArray<P0, P1, P2>(), toReturnType<R>()) { (p0, p1, p2) ->
|
|
151
|
+
return SyncFunctionComponent(name, toArgsArray<P0, P1, P2>(converterProvider = converters), toReturnType<R>()) { (p0, p1, p2) ->
|
|
154
152
|
enforceType<P0, P1, P2>(p0, p1, p2)
|
|
155
153
|
body(p0, p1, p2)
|
|
156
154
|
}.also {
|
|
@@ -162,7 +160,7 @@ open class ObjectDefinitionBuilder(customConverter: TypeConverterProvider? = nul
|
|
|
162
160
|
name: String,
|
|
163
161
|
crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3) -> R
|
|
164
162
|
): SyncFunctionComponent {
|
|
165
|
-
return SyncFunctionComponent(name, toArgsArray<P0, P1, P2, P3>(), toReturnType<R>()) { (p0, p1, p2, p3) ->
|
|
163
|
+
return SyncFunctionComponent(name, toArgsArray<P0, P1, P2, P3>(converterProvider = converters), toReturnType<R>()) { (p0, p1, p2, p3) ->
|
|
166
164
|
enforceType<P0, P1, P2, P3>(p0, p1, p2, p3)
|
|
167
165
|
body(p0, p1, p2, p3)
|
|
168
166
|
}.also {
|
|
@@ -174,7 +172,7 @@ open class ObjectDefinitionBuilder(customConverter: TypeConverterProvider? = nul
|
|
|
174
172
|
name: String,
|
|
175
173
|
crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4) -> R
|
|
176
174
|
): SyncFunctionComponent {
|
|
177
|
-
return SyncFunctionComponent(name, toArgsArray<P0, P1, P2, P3, P4>(), toReturnType<R>()) { (p0, p1, p2, p3, p4) ->
|
|
175
|
+
return SyncFunctionComponent(name, toArgsArray<P0, P1, P2, P3, P4>(converterProvider = converters), toReturnType<R>()) { (p0, p1, p2, p3, p4) ->
|
|
178
176
|
enforceType<P0, P1, P2, P3, P4>(p0, p1, p2, p3, p4)
|
|
179
177
|
body(p0, p1, p2, p3, p4)
|
|
180
178
|
}.also {
|
|
@@ -186,7 +184,7 @@ open class ObjectDefinitionBuilder(customConverter: TypeConverterProvider? = nul
|
|
|
186
184
|
name: String,
|
|
187
185
|
crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5) -> R
|
|
188
186
|
): SyncFunctionComponent {
|
|
189
|
-
return SyncFunctionComponent(name, toArgsArray<P0, P1, P2, P3, P4, P5>(), toReturnType<R>()) { (p0, p1, p2, p3, p4, p5) ->
|
|
187
|
+
return SyncFunctionComponent(name, toArgsArray<P0, P1, P2, P3, P4, P5>(converterProvider = converters), toReturnType<R>()) { (p0, p1, p2, p3, p4, p5) ->
|
|
190
188
|
enforceType<P0, P1, P2, P3, P4, P5>(p0, p1, p2, p3, p4, p5)
|
|
191
189
|
body(p0, p1, p2, p3, p4, p5)
|
|
192
190
|
}.also {
|
|
@@ -198,7 +196,7 @@ open class ObjectDefinitionBuilder(customConverter: TypeConverterProvider? = nul
|
|
|
198
196
|
name: String,
|
|
199
197
|
crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6) -> R
|
|
200
198
|
): SyncFunctionComponent {
|
|
201
|
-
return SyncFunctionComponent(name, toArgsArray<P0, P1, P2, P3, P4, P5, P6>(), toReturnType<R>()) { (p0, p1, p2, p3, p4, p5, p6) ->
|
|
199
|
+
return SyncFunctionComponent(name, toArgsArray<P0, P1, P2, P3, P4, P5, P6>(converterProvider = converters), toReturnType<R>()) { (p0, p1, p2, p3, p4, p5, p6) ->
|
|
202
200
|
enforceType<P0, P1, P2, P3, P4, P5, P6>(p0, p1, p2, p3, p4, p5, p6)
|
|
203
201
|
body(p0, p1, p2, p3, p4, p5, p6)
|
|
204
202
|
}.also {
|
|
@@ -210,7 +208,7 @@ open class ObjectDefinitionBuilder(customConverter: TypeConverterProvider? = nul
|
|
|
210
208
|
name: String,
|
|
211
209
|
crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7) -> R
|
|
212
210
|
): SyncFunctionComponent {
|
|
213
|
-
return SyncFunctionComponent(name, toArgsArray<P0, P1, P2, P3, P4, P5, P6, P7>(), toReturnType<R>()) { (p0, p1, p2, p3, p4, p5, p6, p7) ->
|
|
211
|
+
return SyncFunctionComponent(name, toArgsArray<P0, P1, P2, P3, P4, P5, P6, P7>(converterProvider = converters), toReturnType<R>()) { (p0, p1, p2, p3, p4, p5, p6, p7) ->
|
|
214
212
|
enforceType<P0, P1, P2, P3, P4, P5, P6, P7>(p0, p1, p2, p3, p4, p5, p6, p7)
|
|
215
213
|
body(p0, p1, p2, p3, p4, p5, p6, p7)
|
|
216
214
|
}.also {
|
|
@@ -245,7 +243,7 @@ open class ObjectDefinitionBuilder(customConverter: TypeConverterProvider? = nul
|
|
|
245
243
|
return if (P0::class.java == Promise::class.java) {
|
|
246
244
|
AsyncFunctionWithPromiseComponent(name, arrayOf()) { _, promise -> body(promise as P0) }
|
|
247
245
|
} else {
|
|
248
|
-
createAsyncFunctionComponent(name, toArgsArray<P0>()) { (p0) ->
|
|
246
|
+
createAsyncFunctionComponent(name, toArgsArray<P0>(converterProvider = converters)) { (p0) ->
|
|
249
247
|
enforceType<P0>(p0)
|
|
250
248
|
body(p0)
|
|
251
249
|
}
|
|
@@ -258,7 +256,7 @@ open class ObjectDefinitionBuilder(customConverter: TypeConverterProvider? = nul
|
|
|
258
256
|
name: String,
|
|
259
257
|
crossinline body: (p0: P0, p1: P1) -> R
|
|
260
258
|
): AsyncFunctionComponent {
|
|
261
|
-
return createAsyncFunctionComponent(name, toArgsArray<P0, P1>()) { (p0, p1) ->
|
|
259
|
+
return createAsyncFunctionComponent(name, toArgsArray<P0, P1>(converterProvider = converters)) { (p0, p1) ->
|
|
262
260
|
enforceType<P0, P1>(p0, p1)
|
|
263
261
|
body(p0, p1)
|
|
264
262
|
}.also {
|
|
@@ -271,7 +269,7 @@ open class ObjectDefinitionBuilder(customConverter: TypeConverterProvider? = nul
|
|
|
271
269
|
name: String,
|
|
272
270
|
crossinline body: (p0: P0, p1: Promise) -> R
|
|
273
271
|
): AsyncFunctionComponent {
|
|
274
|
-
return AsyncFunctionWithPromiseComponent(name, toArgsArray<P0>()) { (p0), promise ->
|
|
272
|
+
return AsyncFunctionWithPromiseComponent(name, toArgsArray<P0>(converterProvider = converters)) { (p0), promise ->
|
|
275
273
|
enforceType<P0>(p0)
|
|
276
274
|
body(p0, promise)
|
|
277
275
|
}.also {
|
|
@@ -283,7 +281,7 @@ open class ObjectDefinitionBuilder(customConverter: TypeConverterProvider? = nul
|
|
|
283
281
|
name: String,
|
|
284
282
|
crossinline body: (p0: P0, p1: P1, p2: P2) -> R
|
|
285
283
|
): AsyncFunctionComponent {
|
|
286
|
-
return createAsyncFunctionComponent(name, toArgsArray<P0, P1, P2>()) { (p0, p1, p2) ->
|
|
284
|
+
return createAsyncFunctionComponent(name, toArgsArray<P0, P1, P2>(converterProvider = converters)) { (p0, p1, p2) ->
|
|
287
285
|
enforceType<P0, P1, P2>(p0, p1, p2)
|
|
288
286
|
body(p0, p1, p2)
|
|
289
287
|
}.also {
|
|
@@ -296,7 +294,7 @@ open class ObjectDefinitionBuilder(customConverter: TypeConverterProvider? = nul
|
|
|
296
294
|
name: String,
|
|
297
295
|
crossinline body: (p0: P0, p1: P1, p2: Promise) -> R
|
|
298
296
|
): AsyncFunctionComponent {
|
|
299
|
-
return AsyncFunctionWithPromiseComponent(name, toArgsArray<P0, P1>()) { (p0, p1), promise ->
|
|
297
|
+
return AsyncFunctionWithPromiseComponent(name, toArgsArray<P0, P1>(converterProvider = converters)) { (p0, p1), promise ->
|
|
300
298
|
enforceType<P0, P1>(p0, p1)
|
|
301
299
|
body(p0, p1, promise)
|
|
302
300
|
}.also {
|
|
@@ -308,7 +306,7 @@ open class ObjectDefinitionBuilder(customConverter: TypeConverterProvider? = nul
|
|
|
308
306
|
name: String,
|
|
309
307
|
crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3) -> R
|
|
310
308
|
): AsyncFunctionComponent {
|
|
311
|
-
return createAsyncFunctionComponent(name, toArgsArray<P0, P1, P2, P3>()) { (p0, p1, p2, p3) ->
|
|
309
|
+
return createAsyncFunctionComponent(name, toArgsArray<P0, P1, P2, P3>(converterProvider = converters)) { (p0, p1, p2, p3) ->
|
|
312
310
|
enforceType<P0, P1, P2, P3>(p0, p1, p2, p3)
|
|
313
311
|
body(p0, p1, p2, p3)
|
|
314
312
|
}.also {
|
|
@@ -321,7 +319,7 @@ open class ObjectDefinitionBuilder(customConverter: TypeConverterProvider? = nul
|
|
|
321
319
|
name: String,
|
|
322
320
|
crossinline body: (p0: P0, p1: P1, p2: P2, p3: Promise) -> R
|
|
323
321
|
): AsyncFunctionComponent {
|
|
324
|
-
return AsyncFunctionWithPromiseComponent(name, toArgsArray<P0, P1, P2>()) { (p0, p1, p2), promise ->
|
|
322
|
+
return AsyncFunctionWithPromiseComponent(name, toArgsArray<P0, P1, P2>(converterProvider = converters)) { (p0, p1, p2), promise ->
|
|
325
323
|
enforceType<P0, P1, P2>(p0, p1, p2)
|
|
326
324
|
body(p0, p1, p2, promise)
|
|
327
325
|
}.also {
|
|
@@ -333,7 +331,7 @@ open class ObjectDefinitionBuilder(customConverter: TypeConverterProvider? = nul
|
|
|
333
331
|
name: String,
|
|
334
332
|
crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4) -> R
|
|
335
333
|
): AsyncFunctionComponent {
|
|
336
|
-
return createAsyncFunctionComponent(name, toArgsArray<P0, P1, P2, P3, P4>()) { (p0, p1, p2, p3, p4) ->
|
|
334
|
+
return createAsyncFunctionComponent(name, toArgsArray<P0, P1, P2, P3, P4>(converterProvider = converters)) { (p0, p1, p2, p3, p4) ->
|
|
337
335
|
enforceType<P0, P1, P2, P3, P4>(p0, p1, p2, p3, p4)
|
|
338
336
|
body(p0, p1, p2, p3, p4)
|
|
339
337
|
}.also {
|
|
@@ -346,7 +344,7 @@ open class ObjectDefinitionBuilder(customConverter: TypeConverterProvider? = nul
|
|
|
346
344
|
name: String,
|
|
347
345
|
crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3, p4: Promise) -> R
|
|
348
346
|
): AsyncFunctionComponent {
|
|
349
|
-
return AsyncFunctionWithPromiseComponent(name, toArgsArray<P0, P1, P2, P3>()) { (p0, p1, p2, p3), promise ->
|
|
347
|
+
return AsyncFunctionWithPromiseComponent(name, toArgsArray<P0, P1, P2, P3>(converterProvider = converters)) { (p0, p1, p2, p3), promise ->
|
|
350
348
|
enforceType<P0, P1, P2, P3>(p0, p1, p2, p3)
|
|
351
349
|
body(p0, p1, p2, p3, promise)
|
|
352
350
|
}.also {
|
|
@@ -358,7 +356,7 @@ open class ObjectDefinitionBuilder(customConverter: TypeConverterProvider? = nul
|
|
|
358
356
|
name: String,
|
|
359
357
|
crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5) -> R
|
|
360
358
|
): AsyncFunctionComponent {
|
|
361
|
-
return createAsyncFunctionComponent(name, toArgsArray<P0, P1, P2, P3, P4, P5>()) { (p0, p1, p2, p3, p4, p5) ->
|
|
359
|
+
return createAsyncFunctionComponent(name, toArgsArray<P0, P1, P2, P3, P4, P5>(converterProvider = converters)) { (p0, p1, p2, p3, p4, p5) ->
|
|
362
360
|
enforceType<P0, P1, P2, P3, P4, P5>(p0, p1, p2, p3, p4, p5)
|
|
363
361
|
body(p0, p1, p2, p3, p4, p5)
|
|
364
362
|
}.also {
|
|
@@ -371,7 +369,7 @@ open class ObjectDefinitionBuilder(customConverter: TypeConverterProvider? = nul
|
|
|
371
369
|
name: String,
|
|
372
370
|
crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: Promise) -> R
|
|
373
371
|
): AsyncFunctionComponent {
|
|
374
|
-
return AsyncFunctionWithPromiseComponent(name, toArgsArray<P0, P1, P2, P3, P4>()) { (p0, p1, p2, p3, p4), promise ->
|
|
372
|
+
return AsyncFunctionWithPromiseComponent(name, toArgsArray<P0, P1, P2, P3, P4>(converterProvider = converters)) { (p0, p1, p2, p3, p4), promise ->
|
|
375
373
|
enforceType<P0, P1, P2, P3, P4>(p0, p1, p2, p3, p4)
|
|
376
374
|
body(p0, p1, p2, p3, p4, promise)
|
|
377
375
|
}.also {
|
|
@@ -383,7 +381,7 @@ open class ObjectDefinitionBuilder(customConverter: TypeConverterProvider? = nul
|
|
|
383
381
|
name: String,
|
|
384
382
|
crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6) -> R
|
|
385
383
|
): AsyncFunctionComponent {
|
|
386
|
-
return createAsyncFunctionComponent(name, toArgsArray<P0, P1, P2, P3, P4, P5, P6>()) { (p0, p1, p2, p3, p4, p5, p6) ->
|
|
384
|
+
return createAsyncFunctionComponent(name, toArgsArray<P0, P1, P2, P3, P4, P5, P6>(converterProvider = converters)) { (p0, p1, p2, p3, p4, p5, p6) ->
|
|
387
385
|
enforceType<P0, P1, P2, P3, P4, P5, P6>(p0, p1, p2, p3, p4, p5, p6)
|
|
388
386
|
body(p0, p1, p2, p3, p4, p5, p6)
|
|
389
387
|
}.also {
|
|
@@ -396,7 +394,7 @@ open class ObjectDefinitionBuilder(customConverter: TypeConverterProvider? = nul
|
|
|
396
394
|
name: String,
|
|
397
395
|
crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: Promise) -> R
|
|
398
396
|
): AsyncFunctionComponent {
|
|
399
|
-
return AsyncFunctionWithPromiseComponent(name, toArgsArray<P0, P1, P2, P3, P4, P5>()) { (p0, p1, p2, p3, p4, p5), promise ->
|
|
397
|
+
return AsyncFunctionWithPromiseComponent(name, toArgsArray<P0, P1, P2, P3, P4, P5>(converterProvider = converters)) { (p0, p1, p2, p3, p4, p5), promise ->
|
|
400
398
|
enforceType<P0, P1, P2, P3, P4, P5>(p0, p1, p2, p3, p4, p5)
|
|
401
399
|
body(p0, p1, p2, p3, p4, p5, promise)
|
|
402
400
|
}.also {
|
|
@@ -408,7 +406,7 @@ open class ObjectDefinitionBuilder(customConverter: TypeConverterProvider? = nul
|
|
|
408
406
|
name: String,
|
|
409
407
|
crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7) -> R
|
|
410
408
|
): AsyncFunctionComponent {
|
|
411
|
-
return createAsyncFunctionComponent(name, toArgsArray<P0, P1, P2, P3, P4, P5, P6, P7>()) { (p0, p1, p2, p3, p4, p5, p6, p7) ->
|
|
409
|
+
return createAsyncFunctionComponent(name, toArgsArray<P0, P1, P2, P3, P4, P5, P6, P7>(converterProvider = converters)) { (p0, p1, p2, p3, p4, p5, p6, p7) ->
|
|
412
410
|
enforceType<P0, P1, P2, P3, P4, P5, P6, P7>(p0, p1, p2, p3, p4, p5, p6, p7)
|
|
413
411
|
body(p0, p1, p2, p3, p4, p5, p6, p7)
|
|
414
412
|
}.also {
|
|
@@ -421,7 +419,7 @@ open class ObjectDefinitionBuilder(customConverter: TypeConverterProvider? = nul
|
|
|
421
419
|
name: String,
|
|
422
420
|
crossinline body: (p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: Promise) -> R
|
|
423
421
|
): AsyncFunctionComponent {
|
|
424
|
-
return AsyncFunctionWithPromiseComponent(name, toArgsArray<P0, P1, P2, P3, P4, P5, P6>()) { (p0, p1, p2, p3, p4, p5, p6), promise ->
|
|
422
|
+
return AsyncFunctionWithPromiseComponent(name, toArgsArray<P0, P1, P2, P3, P4, P5, P6>(converterProvider = converters)) { (p0, p1, p2, p3, p4, p5, p6), promise ->
|
|
425
423
|
enforceType<P0, P1, P2, P3, P4, P5, P6>(p0, p1, p2, p3, p4, p5, p6)
|
|
426
424
|
body(p0, p1, p2, p3, p4, p5, p6, promise)
|
|
427
425
|
}.also {
|
|
@@ -431,13 +429,13 @@ open class ObjectDefinitionBuilder(customConverter: TypeConverterProvider? = nul
|
|
|
431
429
|
|
|
432
430
|
fun AsyncFunction(
|
|
433
431
|
name: String
|
|
434
|
-
) = AsyncFunctionBuilder(name).also { asyncFunctionBuilders[name] = it }
|
|
432
|
+
) = AsyncFunctionBuilder(name, converters).also { asyncFunctionBuilders[name] = it }
|
|
435
433
|
|
|
436
434
|
/**
|
|
437
435
|
* Defines event names that this module can send to JavaScript.
|
|
438
436
|
*/
|
|
439
437
|
fun Events(vararg events: String) {
|
|
440
|
-
eventsDefinition = EventsDefinition(events)
|
|
438
|
+
eventsDefinition = EventsDefinition(events.asList().toTypedArray())
|
|
441
439
|
}
|
|
442
440
|
|
|
443
441
|
/**
|
|
@@ -15,4 +15,19 @@ class ObjectDefinitionData(
|
|
|
15
15
|
) {
|
|
16
16
|
val functions
|
|
17
17
|
get() = ConcatIterator(syncFunctions.values.iterator(), asyncFunctions.values.iterator())
|
|
18
|
+
|
|
19
|
+
operator fun plus(other: ObjectDefinitionData?): ObjectDefinitionData {
|
|
20
|
+
if (other == null) {
|
|
21
|
+
return this
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return ObjectDefinitionData(
|
|
25
|
+
legacyConstantsProvider = { legacyConstantsProvider() + other.legacyConstantsProvider() },
|
|
26
|
+
syncFunctions = syncFunctions + other.syncFunctions,
|
|
27
|
+
asyncFunctions = asyncFunctions + other.asyncFunctions,
|
|
28
|
+
eventsDefinition = eventsDefinition?.plus(other.eventsDefinition),
|
|
29
|
+
properties = properties + other.properties,
|
|
30
|
+
constants = constants + other.constants
|
|
31
|
+
)
|
|
32
|
+
}
|
|
18
33
|
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
package expo.modules.kotlin.traits
|
|
2
|
+
|
|
3
|
+
import android.graphics.Bitmap
|
|
4
|
+
import expo.modules.kotlin.AppContext
|
|
5
|
+
import expo.modules.kotlin.exception.Exceptions
|
|
6
|
+
import expo.modules.kotlin.objects.ObjectDefinitionBuilder
|
|
7
|
+
import expo.modules.kotlin.objects.ObjectDefinitionData
|
|
8
|
+
import expo.modules.kotlin.records.Record
|
|
9
|
+
import expo.modules.kotlin.sharedobjects.SharedRef
|
|
10
|
+
import expo.modules.kotlin.weak
|
|
11
|
+
import java.io.File
|
|
12
|
+
import java.util.UUID
|
|
13
|
+
import kotlin.reflect.KClass
|
|
14
|
+
|
|
15
|
+
class SavableTrait<InputType> @PublishedApi internal constructor(
|
|
16
|
+
val exportImpl: (AppContext) -> ObjectDefinitionData
|
|
17
|
+
) : Trait<InputType> {
|
|
18
|
+
override fun export(appContext: AppContext) = exportImpl(appContext)
|
|
19
|
+
|
|
20
|
+
companion object {
|
|
21
|
+
data class SavableBitmapOptions(
|
|
22
|
+
val compression: Int = 100
|
|
23
|
+
) : Record
|
|
24
|
+
|
|
25
|
+
@PublishedApi
|
|
26
|
+
internal inline fun <reified InputType, reified OptionType> createImplementation(
|
|
27
|
+
appContext: AppContext,
|
|
28
|
+
crossinline saveToFile: (file: File, input: InputType, options: OptionType) -> Unit
|
|
29
|
+
): ObjectDefinitionData {
|
|
30
|
+
val appContextWeakRef = appContext.weak()
|
|
31
|
+
|
|
32
|
+
return ObjectDefinitionBuilder().apply {
|
|
33
|
+
AsyncFunction("saveAsync") { input: InputType, options: OptionType ->
|
|
34
|
+
val context = appContextWeakRef.get() ?: throw Exceptions.AppContextLost()
|
|
35
|
+
val outputFile = File(context.cacheDirectory, UUID.randomUUID().toString())
|
|
36
|
+
outputFile.createNewFile()
|
|
37
|
+
|
|
38
|
+
saveToFile(outputFile, input, options)
|
|
39
|
+
}
|
|
40
|
+
}.buildObject()
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
inline fun <reified T : SharedRef<Bitmap>> create(klass: KClass<T> = T::class) =
|
|
44
|
+
SavableTrait<T>(
|
|
45
|
+
exportImpl = { appContext ->
|
|
46
|
+
createImplementation<T, SavableBitmapOptions>(appContext) { file, input, options ->
|
|
47
|
+
input.appContext
|
|
48
|
+
input.ref.compress(
|
|
49
|
+
Bitmap.CompressFormat.PNG,
|
|
50
|
+
options.compression,
|
|
51
|
+
file.outputStream()
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -145,6 +145,15 @@ object AnyTypeProvider {
|
|
|
145
145
|
}
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
+
inline fun <reified T> lazyTypeOf() = { typeOf<T>() }.toLazyType<T>()
|
|
149
|
+
|
|
150
|
+
inline fun <reified T> (() -> KType).toLazyType() =
|
|
151
|
+
LazyKType(
|
|
152
|
+
classifier = T::class,
|
|
153
|
+
isMarkedNullable = null is T,
|
|
154
|
+
kTypeProvider = this
|
|
155
|
+
)
|
|
156
|
+
|
|
148
157
|
inline fun <reified T> (() -> KType).toAnyType(converterProvider: TypeConverterProvider? = null) =
|
|
149
158
|
AnyType(
|
|
150
159
|
LazyKType(
|
|
@@ -98,7 +98,7 @@ class EitherTypeConverter<FirstType : Any, SecondType : Any>(
|
|
|
98
98
|
)
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
override fun getCppRequiredTypes(): ExpectedType = firstType
|
|
101
|
+
override fun getCppRequiredTypes(): ExpectedType = ExpectedType.merge(firstType, secondType)
|
|
102
102
|
|
|
103
103
|
override fun isTrivial(): Boolean = false
|
|
104
104
|
}
|
|
@@ -144,7 +144,7 @@ class EitherOfThreeTypeConverter<FirstType : Any, SecondType : Any, ThirdType :
|
|
|
144
144
|
)
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
-
override fun getCppRequiredTypes(): ExpectedType = firstType
|
|
147
|
+
override fun getCppRequiredTypes(): ExpectedType = ExpectedType.merge(firstType, secondType, thirdType)
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
@EitherType
|
|
@@ -194,5 +194,5 @@ class EitherOfFourTypeConverter<FirstType : Any, SecondType : Any, ThirdType : A
|
|
|
194
194
|
)
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
-
override fun getCppRequiredTypes(): ExpectedType = firstType
|
|
197
|
+
override fun getCppRequiredTypes(): ExpectedType = ExpectedType.merge(firstType, secondType, thirdType, fourthType)
|
|
198
198
|
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
package expo.modules.kotlin.types
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.Dynamic
|
|
4
|
+
|
|
5
|
+
class ExpoDynamic(private val dynamic: Dynamic) {
|
|
6
|
+
enum class Type {
|
|
7
|
+
Boolean,
|
|
8
|
+
Number,
|
|
9
|
+
String,
|
|
10
|
+
Map,
|
|
11
|
+
Array
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
val type: Type
|
|
15
|
+
get() {
|
|
16
|
+
return when (dynamic.type) {
|
|
17
|
+
com.facebook.react.bridge.ReadableType.Null -> throw IllegalStateException("ExpoDynamic is null")
|
|
18
|
+
com.facebook.react.bridge.ReadableType.Boolean -> Type.Boolean
|
|
19
|
+
com.facebook.react.bridge.ReadableType.Number -> Type.Number
|
|
20
|
+
com.facebook.react.bridge.ReadableType.String -> Type.String
|
|
21
|
+
com.facebook.react.bridge.ReadableType.Map -> Type.Map
|
|
22
|
+
com.facebook.react.bridge.ReadableType.Array -> Type.Array
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
val isNull: Boolean
|
|
27
|
+
get() {
|
|
28
|
+
if (dynamic.isNull) {
|
|
29
|
+
throw IllegalStateException("ExpoDynamic is null")
|
|
30
|
+
}
|
|
31
|
+
return false
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
fun asArray(): List<Any?> {
|
|
35
|
+
return dynamic.asArray().toArrayList()
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
fun asBoolean(): Boolean {
|
|
39
|
+
return dynamic.asBoolean()
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
fun asDouble(): Double {
|
|
43
|
+
return dynamic.asDouble()
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
fun asInt(): Int {
|
|
47
|
+
return dynamic.asInt()
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
fun asMap(): Map<String, Any?> {
|
|
51
|
+
return dynamic.asMap().toHashMap()
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
fun asString(): String {
|
|
55
|
+
return dynamic.asString()
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
package expo.modules.kotlin.types
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.Dynamic
|
|
4
|
+
import expo.modules.kotlin.AppContext
|
|
5
|
+
import expo.modules.kotlin.exception.MissingTypeConverter
|
|
6
|
+
import expo.modules.kotlin.jni.ExpectedType
|
|
7
|
+
import kotlin.reflect.KClass
|
|
8
|
+
import kotlin.reflect.KType
|
|
9
|
+
import kotlin.reflect.typeOf
|
|
10
|
+
|
|
11
|
+
class TypeConverterComponent<Type : Any>(val notNullableType: KType, val nullableType: KType) {
|
|
12
|
+
val nonNullableConverter = lazy { TypeConverterCollection<Type>(notNullableType, false) }
|
|
13
|
+
val nullableConverter = lazy { TypeConverterCollection<Type>(nullableType, true) }
|
|
14
|
+
|
|
15
|
+
inline fun <reified P0 : Any> from(crossinline body: (p0: P0) -> Type): TypeConverterComponent<Type> {
|
|
16
|
+
nonNullableConverter.value.from(body)
|
|
17
|
+
nullableConverter.value.from(body)
|
|
18
|
+
return this
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
fun build(): List<Pair<KType, TypeConverter<*>>> {
|
|
22
|
+
if (nonNullableConverter.isInitialized() && nullableConverter.isInitialized()) {
|
|
23
|
+
return listOf(
|
|
24
|
+
notNullableType to nonNullableConverter.value,
|
|
25
|
+
nullableType to nullableConverter.value
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return emptyList()
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
class TypeConverterCollection<Type : Any>(
|
|
34
|
+
val type: KType,
|
|
35
|
+
isOptional: Boolean
|
|
36
|
+
) : NullAwareTypeConverter<Type>(isOptional) {
|
|
37
|
+
@PublishedApi
|
|
38
|
+
internal var converters: MutableMap<KType, (Any?) -> Type> = mutableMapOf()
|
|
39
|
+
|
|
40
|
+
inline fun <reified P0> from(crossinline body: (p0: P0) -> Type): TypeConverterCollection<Type> {
|
|
41
|
+
converters[typeOf<P0>()] = { value ->
|
|
42
|
+
enforceType<P0>(value)
|
|
43
|
+
body(value)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return this
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
override fun convertNonOptional(value: Any, context: AppContext?): Type {
|
|
50
|
+
val possibleConverters = converters
|
|
51
|
+
.map { (key, converter) -> key to converter }
|
|
52
|
+
.filter { (key, _) ->
|
|
53
|
+
val kClass = key.classifier as? KClass<*>
|
|
54
|
+
kClass?.isInstance(value) == true
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (possibleConverters.isEmpty()) {
|
|
58
|
+
// We don't have a converter for Dynamic, but we can try to convert it to ExpoDynamic
|
|
59
|
+
// and see if we have a converter for that.
|
|
60
|
+
if (value is Dynamic) {
|
|
61
|
+
return convertNonOptional(ExpoDynamic(value), context)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
throw MissingTypeConverter(type)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (possibleConverters.size > 1) {
|
|
68
|
+
throw TypeCastException("Cannot cast '$value' to '$type'. Type converters conflict")
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return possibleConverters.first().second.invoke(value)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
override fun getCppRequiredTypes(): ExpectedType {
|
|
75
|
+
return ExpectedType.merge(
|
|
76
|
+
*converters.keys.map { key ->
|
|
77
|
+
ExpectedType.fromKType(key)
|
|
78
|
+
}.toTypedArray()
|
|
79
|
+
)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -7,12 +7,11 @@ import expo.modules.kotlin.exception.PropSetException
|
|
|
7
7
|
import expo.modules.kotlin.exception.exceptionDecorator
|
|
8
8
|
import expo.modules.kotlin.types.AnyType
|
|
9
9
|
|
|
10
|
-
class ConcreteViewProp<ViewType : View, PropType>(
|
|
10
|
+
open class ConcreteViewProp<ViewType : View, PropType>(
|
|
11
11
|
name: String,
|
|
12
12
|
propType: AnyType,
|
|
13
|
-
|
|
13
|
+
protected val setter: (view: ViewType, prop: PropType) -> Unit
|
|
14
14
|
) : AnyViewProp(name, propType) {
|
|
15
|
-
|
|
16
15
|
@Suppress("UNCHECKED_CAST")
|
|
17
16
|
override fun set(prop: Dynamic, onView: View, appContext: AppContext?) {
|
|
18
17
|
exceptionDecorator({
|
|
@@ -24,3 +23,19 @@ class ConcreteViewProp<ViewType : View, PropType>(
|
|
|
24
23
|
|
|
25
24
|
override val isNullable: Boolean = propType.kType.isMarkedNullable
|
|
26
25
|
}
|
|
26
|
+
|
|
27
|
+
class ConcreteViewPropWithDefault<ViewType : View, PropType>(
|
|
28
|
+
name: String,
|
|
29
|
+
propType: AnyType,
|
|
30
|
+
setter: (view: ViewType, prop: PropType) -> Unit,
|
|
31
|
+
private val defaultValue: PropType
|
|
32
|
+
) : ConcreteViewProp<ViewType, PropType>(name, propType, setter) {
|
|
33
|
+
@Suppress("UNCHECKED_CAST")
|
|
34
|
+
override fun set(prop: Dynamic, onView: View, appContext: AppContext?) {
|
|
35
|
+
if (prop.isNull) {
|
|
36
|
+
setter(onView as ViewType, defaultValue)
|
|
37
|
+
return
|
|
38
|
+
}
|
|
39
|
+
super.set(prop, onView, appContext)
|
|
40
|
+
}
|
|
41
|
+
}
|