expo-modules-core 56.0.3 → 56.0.4

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 CHANGED
@@ -10,6 +10,10 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 56.0.4 — 2026-05-07
14
+
15
+ _This version does not introduce any user-facing changes._
16
+
13
17
  ## 56.0.3 — 2026-05-06
14
18
 
15
19
  _This version does not introduce any user-facing changes._
@@ -29,7 +29,7 @@ if (shouldIncludeCompose) {
29
29
  }
30
30
 
31
31
  group = 'host.exp.exponent'
32
- version = '56.0.3'
32
+ version = '56.0.4'
33
33
 
34
34
  def isExpoModulesCoreTests = {
35
35
  Gradle gradle = getGradle()
@@ -96,7 +96,7 @@ android {
96
96
  defaultConfig {
97
97
  consumerProguardFiles 'proguard-rules.pro'
98
98
  versionCode 1
99
- versionName "56.0.3"
99
+ versionName "56.0.4"
100
100
  buildConfigField "String", "EXPO_MODULES_CORE_VERSION", "\"${versionName}\""
101
101
  buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", "true"
102
102
 
@@ -3,7 +3,6 @@ package expo.modules.kotlin.types
3
3
  import android.net.Uri
4
4
  import android.os.Bundle
5
5
  import expo.modules.kotlin.jni.ReturnType
6
- import expo.modules.kotlin.records.Field
7
6
  import expo.modules.kotlin.records.Record
8
7
  import expo.modules.kotlin.records.formatters.FormattedRecord
9
8
  import expo.modules.kotlin.typedarray.RawTypedArrayHolder
@@ -121,7 +120,7 @@ interface JSTypeConverter<T> {
121
120
  object RecordConverter : JSTypeConverter<Record> {
122
121
  override fun convertToJS(value: Any?): Any? {
123
122
  enforceType<Record?>(value)
124
- return value?.toJSValueExperimental()
123
+ return value?.toJSValueExperimental(null)
125
124
  }
126
125
 
127
126
  override val returnType: ReturnType
@@ -129,49 +128,11 @@ interface JSTypeConverter<T> {
129
128
  }
130
129
 
131
130
  class IntrospectableRecordConverter(
132
- introspectableData: PIntrospectionData<Record>
131
+ private val introspectableData: PIntrospectionData<Record>
133
132
  ) : JSTypeConverter<Record> {
134
- data class Property(
135
- val key: String,
136
- val getter: (Record) -> Any?
137
- )
138
-
139
- private val properties = introspectableData
140
- .properties
141
- .mapNotNull { property ->
142
- val fieldAnnotation = property
143
- .annotations
144
- .firstOrNull { annotation -> annotation.jClass == Field::class.java }
145
- ?: return@mapNotNull null
146
-
147
- val propertyName = (
148
- fieldAnnotation
149
- .arguments
150
- .getOrDefault("key", property.name) as String
151
- )
152
- .ifEmpty { property.name }
153
-
154
- Property(
155
- propertyName,
156
- property::get
157
- )
158
- }
159
-
160
133
  override fun convertToJS(value: Any?): Any? {
161
- if (value == null) {
162
- return null
163
- }
164
-
165
- enforceType<Record>(value)
166
- val result = mutableMapOf<String, Any?>()
167
-
168
- properties.forEach { property ->
169
- val propValue = property.getter(value)
170
- val convertedValue = JSTypeConverterProvider.convertToJSValue(propValue, useExperimentalConverter = true)
171
- result[property.key] = convertedValue
172
- }
173
-
174
- return result
134
+ enforceType<Record?>(value)
135
+ return value?.toJSValueExperimental(introspectableData)
175
136
  }
176
137
 
177
138
  override val returnType: ReturnType
@@ -10,6 +10,9 @@ import expo.modules.kotlin.records.Field
10
10
  import expo.modules.kotlin.records.Record
11
11
  import expo.modules.kotlin.records.formatters.FormattedRecord
12
12
  import expo.modules.kotlin.records.formatters.ValueOrSkip
13
+ import io.github.lukmccall.pika.PIntrospectionData
14
+ import io.github.lukmccall.pika.PIntrospectionProvider
15
+ import io.github.lukmccall.pika.PProperty
13
16
  import java.io.File
14
17
  import java.net.URI
15
18
  import java.net.URL
@@ -20,22 +23,63 @@ import kotlin.reflect.full.memberProperties
20
23
  import kotlin.reflect.full.primaryConstructor
21
24
  import kotlin.reflect.jvm.isAccessible
22
25
 
23
- fun Record.toJSValueExperimental(): Map<String, Any?> {
26
+ /**
27
+ * Returns field key if property is annotated with [Field]
28
+ */
29
+ private fun PProperty<Record, *>.asFieldKey(): String? {
30
+ val fieldAnnotation = annotations
31
+ .firstOrNull { annotation -> annotation.jClass == Field::class.java }
32
+ ?: return null
33
+
34
+ val propertyName = (
35
+ fieldAnnotation
36
+ .arguments
37
+ .getOrDefault("key", name) as String
38
+ )
39
+ .ifEmpty { name }
40
+
41
+ return propertyName
42
+ }
43
+
44
+ private fun Record.getIntrospectionData(): PIntrospectionData<Record>? {
45
+ return if (this is PIntrospectionProvider) {
46
+ @Suppress("UNCHECKED_CAST")
47
+ getIntrospectionData() as? PIntrospectionData<Record>
48
+ } else {
49
+ null
50
+ }
51
+ }
52
+
53
+ fun Record.toJSValueExperimental(
54
+ introspectionData: PIntrospectionData<Record>? = this.getIntrospectionData()
55
+ ): Map<String, Any?> {
24
56
  val result = mutableMapOf<String, Any?>()
25
57
 
26
- javaClass
27
- .kotlin
28
- .memberProperties
29
- .forEach { property ->
30
- val fieldInformation = property.findAnnotation<Field>() ?: return@forEach
31
- val jsKey = fieldInformation.key.takeUnless { it == "" } ?: property.name
58
+ if (introspectionData == null) {
59
+ javaClass
60
+ .kotlin
61
+ .memberProperties
62
+ .forEach { property ->
63
+ val fieldInformation = property.findAnnotation<Field>() ?: return@forEach
64
+ val jsKey = fieldInformation.key.takeUnless { it == "" } ?: property.name
32
65
 
33
- property.isAccessible = true
66
+ property.isAccessible = true
34
67
 
35
- val value = property.get(this)
36
- val convertedValue = JSTypeConverterProvider.convertToJSValue(value, useExperimentalConverter = true)
37
- result[jsKey] = convertedValue
38
- }
68
+ val value = property.get(this)
69
+ val convertedValue = JSTypeConverterProvider.convertToJSValue(value, useExperimentalConverter = true)
70
+ result[jsKey] = convertedValue
71
+ }
72
+ } else {
73
+ introspectionData
74
+ .properties
75
+ .forEach { property ->
76
+ val propertyKey = property.asFieldKey() ?: return@forEach
77
+
78
+ val propValue = property.get(this)
79
+ val convertedValue = JSTypeConverterProvider.convertToJSValue(propValue, useExperimentalConverter = true)
80
+ result[propertyKey] = convertedValue
81
+ }
82
+ }
39
83
 
40
84
  return result
41
85
  }
@@ -74,21 +118,37 @@ fun FormattedRecord<*>.toJSValueExperimental(): Map<String, Any?> {
74
118
  return result
75
119
  }
76
120
 
77
- fun Record.toJSValue(containerProvider: JSTypeConverterProvider.ContainerProvider): WritableMap {
121
+ fun Record.toJSValue(
122
+ containerProvider: JSTypeConverterProvider.ContainerProvider,
123
+ introspectionData: PIntrospectionData<Record>? = this.getIntrospectionData()
124
+ ): WritableMap {
78
125
  val result = containerProvider.createMap()
79
126
 
80
- javaClass
81
- .kotlin
82
- .memberProperties.map { property ->
83
- val fieldInformation = property.findAnnotation<Field>() ?: return@map
84
- val jsKey = fieldInformation.key.takeUnless { it == "" } ?: property.name
127
+ if (introspectionData == null) {
128
+ javaClass
129
+ .kotlin
130
+ .memberProperties
131
+ .forEach { property ->
132
+ val fieldInformation = property.findAnnotation<Field>() ?: return@forEach
133
+ val jsKey = fieldInformation.key.takeUnless { it == "" } ?: property.name
85
134
 
86
- property.isAccessible = true
135
+ property.isAccessible = true
87
136
 
88
- val value = property.get(this)
89
- val convertedValue = JSTypeConverterProvider.legacyConvertToJSValue(value, containerProvider)
90
- result.putGeneric(jsKey, convertedValue)
91
- }
137
+ val value = property.get(this)
138
+ val convertedValue = JSTypeConverterProvider.legacyConvertToJSValue(value, containerProvider)
139
+ result.putGeneric(jsKey, convertedValue)
140
+ }
141
+ } else {
142
+ introspectionData
143
+ .properties
144
+ .forEach { property ->
145
+ val propertyKey = property.asFieldKey() ?: return@forEach
146
+
147
+ val value = property.get(this)
148
+ val convertedValue = JSTypeConverterProvider.legacyConvertToJSValue(value, containerProvider)
149
+ result.putGeneric(propertyKey, convertedValue)
150
+ }
151
+ }
92
152
 
93
153
  return result
94
154
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-modules-core",
3
- "version": "56.0.3",
3
+ "version": "56.0.4",
4
4
  "description": "The core of Expo Modules architecture",
5
5
  "main": "src/index.ts",
6
6
  "types": "build/index.d.ts",
@@ -66,7 +66,7 @@
66
66
  "@types/invariant": "^2.2.33",
67
67
  "expo-module-scripts": "56.0.2"
68
68
  },
69
- "gitHead": "a8ab3da510a34b7bdb2262aa9887d4f78b102280",
69
+ "gitHead": "d7b4e5edff4bf2e619d2c2f16d158798c6d592ef",
70
70
  "scripts": {
71
71
  "build": "expo-module build",
72
72
  "clean": "expo-module clean",