expo-modules-core 2.3.13 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/android/build.gradle +2 -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 +2 -2
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
class ModuleDefinitionEncoder: Encodable {
|
|
2
|
+
private let definition: ModuleDefinition
|
|
3
|
+
|
|
4
|
+
init(_ definition: ModuleDefinition) {
|
|
5
|
+
self.definition = definition
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
enum CodingKeys: String, CodingKey {
|
|
9
|
+
case name
|
|
10
|
+
case functions
|
|
11
|
+
case properties
|
|
12
|
+
case constants
|
|
13
|
+
case views
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
func encode(to encoder: Encoder) throws {
|
|
17
|
+
var container = encoder.container(keyedBy: CodingKeys.self)
|
|
18
|
+
try container.encode(definition.name, forKey: .name)
|
|
19
|
+
try container.encode(definition.legacyConstants.map({ LegacyConstantsDefinitionEncoder($0) }), forKey: .constants)
|
|
20
|
+
try container.encode(definition.properties.values.map({ PropertyDefinitionEncoder($0) }), forKey: .properties)
|
|
21
|
+
try container.encode(definition.functions.values.map({ FunctionDefinitionEncoder($0) }), forKey: .functions)
|
|
22
|
+
try container.encode(definition.views.values.map({ ViewDefinitionEncoder($0) }), forKey: .views)
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public class ModuleRegistryEncoder: Encodable {
|
|
27
|
+
private let registry: ModuleRegistry
|
|
28
|
+
|
|
29
|
+
public init(_ registry: ModuleRegistry) {
|
|
30
|
+
self.registry = registry
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
public func encode(to encoder: Encoder) throws {
|
|
34
|
+
var container = encoder.unkeyedContainer()
|
|
35
|
+
registry.getModuleNames().forEach {
|
|
36
|
+
guard let definition = registry.get(moduleWithName: $0)?.definition() else {
|
|
37
|
+
return
|
|
38
|
+
}
|
|
39
|
+
try? container.encode(ModuleDefinitionEncoder(definition))
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
class FunctionDefinitionEncoder: Encodable {
|
|
45
|
+
private let definition: any AnyFunctionDefinition
|
|
46
|
+
|
|
47
|
+
init(_ definition: any AnyFunctionDefinition) {
|
|
48
|
+
self.definition = definition
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
enum CodingKeys: String, CodingKey {
|
|
52
|
+
case name
|
|
53
|
+
case argumentsCount
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
func encode(to encoder: Encoder) throws {
|
|
57
|
+
var container = encoder.container(keyedBy: CodingKeys.self)
|
|
58
|
+
try container.encode(definition.name, forKey: .name)
|
|
59
|
+
try container.encode(definition.argumentsCount, forKey: .argumentsCount)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
class ViewDefinitionEncoder: Encodable {
|
|
64
|
+
private let definition: any AnyViewDefinition
|
|
65
|
+
|
|
66
|
+
init(_ definition: any AnyViewDefinition) {
|
|
67
|
+
self.definition = definition
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
enum CodingKeys: String, CodingKey {
|
|
71
|
+
case name
|
|
72
|
+
case props
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
func encode(to encoder: Encoder) throws {
|
|
76
|
+
var container = encoder.container(keyedBy: CodingKeys.self)
|
|
77
|
+
try container.encode(definition.name, forKey: .name)
|
|
78
|
+
try container.encode(definition.props.map({ ViewPropEncoder($0) }), forKey: .props)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
class ViewPropEncoder: Encodable {
|
|
83
|
+
private let definition: AnyViewProp
|
|
84
|
+
|
|
85
|
+
init(_ definition: AnyViewProp) {
|
|
86
|
+
self.definition = definition
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
enum CodingKeys: String, CodingKey {
|
|
90
|
+
case name
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
func encode(to encoder: Encoder) throws {
|
|
94
|
+
var container = encoder.container(keyedBy: CodingKeys.self)
|
|
95
|
+
try container.encode(definition.name, forKey: .name)
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
class ConstantEncoder: Encodable {
|
|
100
|
+
private let key: String
|
|
101
|
+
private let value: Any?
|
|
102
|
+
|
|
103
|
+
init(_ key: String, value: Any?) {
|
|
104
|
+
self.key = key
|
|
105
|
+
self.value = value
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
enum CodingKeys: String, CodingKey {
|
|
109
|
+
case name
|
|
110
|
+
case value
|
|
111
|
+
case type
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
func encode(to encoder: Encoder) throws {
|
|
115
|
+
var container = encoder.container(keyedBy: CodingKeys.self)
|
|
116
|
+
try container.encode(key, forKey: .name)
|
|
117
|
+
switch value {
|
|
118
|
+
case let value as String:
|
|
119
|
+
try container.encode(value, forKey: .value)
|
|
120
|
+
try container.encode("string", forKey: .type)
|
|
121
|
+
case let value as Bool:
|
|
122
|
+
try container.encode(value, forKey: .value)
|
|
123
|
+
try container.encode("boolean", forKey: .type)
|
|
124
|
+
case let value as Int:
|
|
125
|
+
try container.encode(value, forKey: .value)
|
|
126
|
+
try container.encode("number", forKey: .type)
|
|
127
|
+
case let value as Double:
|
|
128
|
+
try container.encode(value, forKey: .value)
|
|
129
|
+
try container.encode("number", forKey: .type)
|
|
130
|
+
case nil:
|
|
131
|
+
try container.encodeNil(forKey: .value)
|
|
132
|
+
try container.encode("null", forKey: .type)
|
|
133
|
+
case let value as Dictionary<String, Any>:
|
|
134
|
+
try container.encodeNil(forKey: .value)
|
|
135
|
+
try container.encode("object", forKey: .type)
|
|
136
|
+
case let value as Array<Any>:
|
|
137
|
+
try container.encodeNil(forKey: .value)
|
|
138
|
+
try container.encode("array", forKey: .type)
|
|
139
|
+
default:
|
|
140
|
+
try container.encodeNil(forKey: .value)
|
|
141
|
+
try container.encode("unknown", forKey: .type)
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
class LegacyConstantsDefinitionEncoder: Encodable {
|
|
147
|
+
private let definition: ConstantsDefinition
|
|
148
|
+
|
|
149
|
+
init(_ definition: ConstantsDefinition) {
|
|
150
|
+
self.definition = definition
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
enum CodingKeys: String, CodingKey {
|
|
154
|
+
case name
|
|
155
|
+
case value
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
func encode(to encoder: Encoder) throws {
|
|
159
|
+
var container = encoder.unkeyedContainer()
|
|
160
|
+
let constants = definition.body()
|
|
161
|
+
for (key, value) in constants {
|
|
162
|
+
try container.encode(ConstantEncoder(key, value: value))
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
class PropertyDefinitionEncoder: Encodable {
|
|
168
|
+
private let definition: any AnyPropertyDefinition
|
|
169
|
+
|
|
170
|
+
init(_ definition: any AnyPropertyDefinition) {
|
|
171
|
+
self.definition = definition
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
enum CodingKeys: String, CodingKey {
|
|
175
|
+
case name
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
func encode(to encoder: Encoder) throws {
|
|
179
|
+
var container = encoder.container(keyedBy: CodingKeys.self)
|
|
180
|
+
try container.encode(definition.name, forKey: .name)
|
|
181
|
+
}
|
|
182
|
+
}
|
|
@@ -17,7 +17,7 @@ public class ExpoReactDelegate: NSObject {
|
|
|
17
17
|
initialProperties: [AnyHashable: Any]?,
|
|
18
18
|
launchOptions: [UIApplication.LaunchOptionsKey: Any]?
|
|
19
19
|
) -> UIView {
|
|
20
|
-
return self.handlers
|
|
20
|
+
return self.handlers
|
|
21
21
|
.compactMap { $0.createReactRootView(reactDelegate: self, moduleName: moduleName, initialProperties: initialProperties, launchOptions: launchOptions) }
|
|
22
22
|
.first(where: { _ in true })
|
|
23
23
|
?? {
|
|
@@ -45,7 +45,7 @@ public class ExpoReactDelegate: NSObject {
|
|
|
45
45
|
@objc
|
|
46
46
|
public func createRootViewController() -> UIViewController {
|
|
47
47
|
return self.handlers.lazy
|
|
48
|
-
.compactMap { $0.createRootViewController(
|
|
48
|
+
.compactMap { $0.createRootViewController() }
|
|
49
49
|
.first(where: { _ in true }) ?? UIViewController()
|
|
50
50
|
}
|
|
51
51
|
}
|
|
@@ -35,7 +35,7 @@ open class ExpoReactDelegateHandler: NSObject {
|
|
|
35
35
|
Otherwise return nil.
|
|
36
36
|
*/
|
|
37
37
|
@objc
|
|
38
|
-
open func createRootViewController(
|
|
38
|
+
open func createRootViewController() -> UIViewController? {
|
|
39
39
|
return nil
|
|
40
40
|
}
|
|
41
41
|
}
|
|
@@ -297,7 +297,11 @@ class FunctionSpec: ExpoSpec {
|
|
|
297
297
|
AsyncFunction("withSharedObjectAsync") {
|
|
298
298
|
return SharedString("Test")
|
|
299
299
|
}
|
|
300
|
-
|
|
300
|
+
|
|
301
|
+
AsyncFunction("withArrayOfSharedObjectsAsync") {
|
|
302
|
+
return [SharedString("Test1"), SharedString("Test2"), SharedString("Test3")]
|
|
303
|
+
}
|
|
304
|
+
|
|
301
305
|
AsyncFunction("withSharedObjectPromise") { (p: Promise) in
|
|
302
306
|
p.resolve(SharedString("Test with Promise"))
|
|
303
307
|
}
|
|
@@ -382,6 +386,28 @@ class FunctionSpec: ExpoSpec {
|
|
|
382
386
|
expect(result.getString()) == "Test"
|
|
383
387
|
}
|
|
384
388
|
|
|
389
|
+
it("returns an Array of SharedObjects (async)") {
|
|
390
|
+
try runtime
|
|
391
|
+
.eval(
|
|
392
|
+
"expo.modules.TestModule.withArrayOfSharedObjectsAsync().then((result) => { globalThis.resultArray = result; })"
|
|
393
|
+
)
|
|
394
|
+
|
|
395
|
+
expect(safeBoolEval("globalThis.resultArray != null")).toEventually(beTrue(), timeout: .milliseconds(2000))
|
|
396
|
+
let object = try runtime.eval("object = globalThis.resultArray")
|
|
397
|
+
|
|
398
|
+
expect(object.kind) == .object
|
|
399
|
+
expect(object.getObject().hasProperty("length")) == true
|
|
400
|
+
|
|
401
|
+
let result = object.getArray()
|
|
402
|
+
try result.enumerated().forEach { index, element in
|
|
403
|
+
expect(element.kind) == .object
|
|
404
|
+
expect(element.getObject().hasProperty("value")) == true
|
|
405
|
+
let value = try runtime.eval("object[\(index)].value")
|
|
406
|
+
expect(value.kind) == .string
|
|
407
|
+
expect(value.getString()) == "Test\(index + 1)"
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
|
|
385
411
|
it("returns a SharedObject with Promise") {
|
|
386
412
|
try runtime
|
|
387
413
|
.eval(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-modules-core",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"description": "The core of Expo Modules architecture",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -44,5 +44,5 @@
|
|
|
44
44
|
"@testing-library/react-native": "^13.1.0",
|
|
45
45
|
"expo-module-scripts": "^4.1.7"
|
|
46
46
|
},
|
|
47
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "7638c800b57fe78f57cc7f129022f58e84a523c5"
|
|
48
48
|
}
|