expo-modules-core 1.2.6 → 1.3.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 +33 -4
- package/ExpoModulesCore.podspec +1 -0
- package/README.md +1 -1
- package/android/ExpoModulesCorePlugin.gradle +16 -0
- package/android/build.gradle +3 -2
- package/android/src/main/cpp/Exceptions.cpp +8 -0
- package/android/src/main/cpp/Exceptions.h +11 -0
- package/android/src/main/cpp/ExpoModulesHostObject.cpp +22 -5
- package/android/src/main/cpp/ExpoModulesHostObject.h +5 -0
- package/android/src/main/cpp/JNIInjector.cpp +2 -0
- package/android/src/main/cpp/JSIInteropModuleRegistry.cpp +25 -1
- package/android/src/main/cpp/JSIInteropModuleRegistry.h +14 -0
- package/android/src/main/cpp/JSIObjectWrapper.h +15 -4
- package/android/src/main/cpp/JSITypeConverter.h +3 -2
- package/android/src/main/cpp/JavaReferencesCache.cpp +2 -0
- package/android/src/main/cpp/JavaScriptFunction.cpp +56 -0
- package/android/src/main/cpp/JavaScriptFunction.h +54 -0
- package/android/src/main/cpp/JavaScriptModuleObject.cpp +225 -105
- package/android/src/main/cpp/JavaScriptModuleObject.h +67 -34
- package/android/src/main/cpp/JavaScriptObject.cpp +55 -1
- package/android/src/main/cpp/JavaScriptObject.h +17 -13
- package/android/src/main/cpp/JavaScriptRuntime.cpp +12 -3
- package/android/src/main/cpp/JavaScriptRuntime.h +9 -1
- package/android/src/main/cpp/JavaScriptValue.cpp +9 -0
- package/android/src/main/cpp/JavaScriptValue.h +4 -0
- package/android/src/main/cpp/MethodMetadata.cpp +66 -87
- package/android/src/main/cpp/MethodMetadata.h +18 -16
- package/android/src/main/cpp/ObjectDeallocator.h +25 -0
- package/android/src/main/cpp/WeakRuntimeHolder.cpp +7 -0
- package/android/src/main/cpp/WeakRuntimeHolder.h +4 -0
- package/android/src/main/cpp/types/CppType.h +4 -1
- package/android/src/main/cpp/types/FrontendConverter.cpp +58 -0
- package/android/src/main/cpp/types/FrontendConverter.h +45 -0
- package/android/src/main/cpp/types/FrontendConverterProvider.cpp +3 -0
- package/android/src/main/cpp/types/JNIToJSIConverter.cpp +88 -0
- package/android/src/main/cpp/types/JNIToJSIConverter.h +22 -0
- package/android/src/main/java/com/facebook/react/uimanager/ReactStylesDiffMapHelper.kt +10 -0
- package/android/src/main/java/expo/modules/kotlin/AppContext.kt +18 -25
- package/android/src/main/java/expo/modules/kotlin/FilteredIterator.kt +37 -0
- package/android/src/main/java/expo/modules/kotlin/KotlinInteropModuleRegistry.kt +1 -1
- package/android/src/main/java/expo/modules/kotlin/ModuleHolder.kt +34 -21
- package/android/src/main/java/expo/modules/kotlin/ModuleRegistry.kt +13 -3
- package/android/src/main/java/expo/modules/kotlin/Utils.kt +21 -0
- package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultCaller.kt +21 -1
- package/android/src/main/java/expo/modules/kotlin/classcomponent/ClassComponentBuilder.kt +112 -0
- package/android/src/main/java/expo/modules/kotlin/classcomponent/ClassDefinitionData.kt +10 -0
- package/android/src/main/java/expo/modules/kotlin/exception/CodedException.kt +21 -0
- package/android/src/main/java/expo/modules/kotlin/exception/CommonExceptions.kt +15 -0
- package/android/src/main/java/expo/modules/kotlin/functions/AnyFunction.kt +17 -4
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunction.kt +38 -8
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionComponent.kt +3 -2
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromiseComponent.kt +3 -2
- package/android/src/main/java/expo/modules/kotlin/functions/SuspendFunctionComponent.kt +1 -0
- package/android/src/main/java/expo/modules/kotlin/functions/SyncFunctionComponent.kt +18 -11
- package/android/src/main/java/expo/modules/kotlin/jni/CppType.kt +4 -1
- package/android/src/main/java/expo/modules/kotlin/jni/JNIDeallocator.kt +73 -0
- package/android/src/main/java/expo/modules/kotlin/jni/JSIInteropModuleRegistry.kt +28 -2
- package/android/src/main/java/expo/modules/kotlin/jni/JavaCallback.kt +8 -1
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptFunction.kt +48 -0
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptModuleObject.kt +40 -3
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptObject.kt +23 -3
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptValue.kt +26 -1
- package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +0 -11
- package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +26 -16
- package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionData.kt +3 -1
- package/android/src/main/java/expo/modules/kotlin/sharedobjects/SharedObject.kt +12 -0
- package/android/src/main/java/expo/modules/kotlin/sharedobjects/SharedObjectRegistry.kt +62 -0
- package/android/src/main/java/expo/modules/kotlin/sharedobjects/SharedObjectTypeConverter.kt +27 -0
- package/android/src/main/java/expo/modules/kotlin/types/AnyType.kt +2 -1
- package/android/src/main/java/expo/modules/kotlin/types/EitherTypeConverter.kt +7 -6
- package/android/src/main/java/expo/modules/kotlin/types/JavaScriptFunctionTypeConverter.kt +22 -0
- package/android/src/main/java/expo/modules/kotlin/types/TypeConverter.kt +30 -24
- package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +45 -1
- package/android/src/main/java/expo/modules/kotlin/types/TypedArrayTypeConverter.kt +3 -2
- package/android/src/main/java/expo/modules/kotlin/views/AnyViewProp.kt +3 -1
- package/android/src/main/java/expo/modules/kotlin/views/ConcreteViewProp.kt +3 -3
- package/android/src/main/java/expo/modules/kotlin/views/FilteredReadableMap.kt +53 -0
- package/android/src/main/java/expo/modules/kotlin/views/GroupViewManagerWrapper.kt +25 -5
- package/android/src/main/java/expo/modules/kotlin/views/SimpleViewManagerWrapper.kt +25 -5
- package/android/src/main/java/expo/modules/kotlin/views/ViewDefinitionBuilder.kt +161 -10
- package/android/src/main/java/expo/modules/kotlin/views/ViewGroupDefinitionBuilder.kt +0 -67
- package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinition.kt +7 -8
- package/android/src/main/java/expo/modules/kotlin/views/ViewManagerWrapperDelegate.kt +40 -3
- package/android/src/main/java/expo/modules/kotlin/views/ViewTypeConverter.kt +44 -0
- package/android-annotation/build.gradle +45 -0
- package/android-annotation/src/main/java/expo/modules/annotation/Config.kt +7 -0
- package/android-annotation/src/main/java/expo/modules/annotation/ConverterBinder.kt +7 -0
- package/android-annotation-processor/build.gradle +51 -0
- package/android-annotation-processor/src/main/java/expo/modules/annotationprocessor/ExpoSymbolProcessor.kt +175 -0
- package/android-annotation-processor/src/main/java/expo/modules/annotationprocessor/ExpoSymbolProcessorProvider.kt +10 -0
- package/android-annotation-processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider +1 -0
- package/build/NativeViewManagerAdapter.native.d.ts.map +1 -1
- package/build/NativeViewManagerAdapter.native.js +36 -23
- package/build/NativeViewManagerAdapter.native.js.map +1 -1
- package/build/requireNativeModule.js +2 -2
- package/build/requireNativeModule.js.map +1 -1
- package/common/cpp/fabric/ExpoViewProps.cpp +18 -3
- package/common/cpp/fabric/ExpoViewProps.h +4 -1
- package/ios/Fabric/ExpoFabricView.swift +10 -10
- package/ios/Fabric/ExpoFabricViewObjC.h +2 -0
- package/ios/Fabric/ExpoFabricViewObjC.mm +17 -2
- package/ios/JSI/EXJSIInstaller.mm +1 -1
- package/ios/JSI/EXJSIUtils.h +5 -0
- package/ios/JSI/EXJSIUtils.mm +17 -0
- package/ios/JSI/EXJavaScriptRuntime.h +5 -0
- package/ios/JSI/EXJavaScriptRuntime.mm +6 -0
- package/ios/JSI/EXJavaScriptValue.h +2 -0
- package/ios/JSI/EXJavaScriptValue.mm +8 -0
- package/ios/JSI/EXJavaScriptWeakObject.mm +29 -8
- package/ios/JSI/EXRawJavaScriptFunction.h +24 -0
- package/ios/JSI/EXRawJavaScriptFunction.mm +52 -0
- package/ios/JSI/ExpoModulesHostObject.mm +1 -1
- package/ios/JSI/JavaScriptValue.swift +28 -1
- package/ios/ModuleRegistry/EXModuleRegistry.h +0 -4
- package/ios/ModuleRegistry/EXModuleRegistry.m +0 -23
- package/ios/ModuleRegistryAdapter/EXModuleRegistryAdapter.m +0 -16
- package/ios/ModuleRegistryProvider/EXModuleRegistryProvider.m +0 -6
- package/ios/NativeModulesProxy/EXNativeModulesProxy.mm +1 -31
- package/ios/Swift/AppContext.swift +46 -6
- package/ios/Swift/Arguments/Convertible.swift +3 -3
- package/ios/Swift/Arguments/Convertibles.swift +5 -5
- package/ios/Swift/Classes/ClassComponent.swift +18 -12
- package/ios/Swift/Classes/ClassRegistry.swift +31 -0
- package/ios/Swift/Conversions.swift +19 -3
- package/ios/Swift/Convertibles/Convertibles+Color.swift +3 -3
- package/ios/Swift/Convertibles/Either.swift +6 -4
- package/ios/Swift/DynamicTypes/AnyDynamicType.swift +18 -2
- package/ios/Swift/DynamicTypes/DynamicArrayType.swift +3 -3
- package/ios/Swift/DynamicTypes/DynamicConvertibleType.swift +2 -2
- package/ios/Swift/DynamicTypes/DynamicEnumType.swift +1 -1
- package/ios/Swift/DynamicTypes/DynamicJavaScriptType.swift +27 -0
- package/ios/Swift/DynamicTypes/DynamicOptionalType.swift +9 -2
- package/ios/Swift/DynamicTypes/DynamicRawType.swift +1 -1
- package/ios/Swift/DynamicTypes/DynamicSharedObjectType.swift +16 -2
- package/ios/Swift/DynamicTypes/DynamicType.swift +6 -0
- package/ios/Swift/DynamicTypes/DynamicTypedArrayType.swift +15 -4
- package/ios/Swift/DynamicTypes/DynamicViewType.swift +68 -0
- package/ios/Swift/ExpoBridgeModule.swift +1 -1
- package/ios/Swift/Functions/AnyFunction.swift +5 -4
- package/ios/Swift/Functions/AsyncFunctionComponent.swift +22 -19
- package/ios/Swift/Functions/ConcurrentFunctionDefinition.swift +29 -13
- package/ios/Swift/Functions/SyncFunctionComponent.swift +26 -15
- package/ios/Swift/JavaScriptFunction.swift +68 -0
- package/ios/Swift/JavaScriptUtils.swift +57 -18
- package/ios/Swift/ModuleHolder.swift +22 -10
- package/ios/Swift/Modules/ModuleDefinition.swift +8 -2
- package/ios/Swift/Objects/JavaScriptObjectBuilder.swift +8 -8
- package/ios/Swift/Objects/ObjectDefinition.swift +17 -15
- package/ios/Swift/Objects/PropertyComponent.swift +23 -17
- package/ios/Swift/Records/AnyField.swift +1 -1
- package/ios/Swift/Records/Field.swift +2 -2
- package/ios/Swift/Records/Record.swift +5 -5
- package/ios/Swift/SharedObjects/SharedObjectRegistry.swift +4 -0
- package/ios/Swift/Views/AnyViewProp.swift +1 -1
- package/ios/Swift/Views/ComponentData.swift +37 -2
- package/ios/Swift/Views/ConcreteViewProp.swift +2 -2
- package/ios/Swift/Views/ViewDefinition.swift +39 -0
- package/ios/Swift/Views/ViewModuleWrapper.swift +0 -29
- package/ios/Tests/ClassComponentSpec.swift +39 -27
- package/ios/Tests/ConvertiblesSpec.swift +75 -49
- package/ios/Tests/DynamicTypeSpec.swift +29 -27
- package/ios/Tests/EitherSpec.swift +9 -7
- package/ios/Tests/ExpoModulesSpec.swift +13 -13
- package/ios/Tests/FunctionSpec.swift +38 -22
- package/ios/Tests/JavaScriptRuntimeSpec.swift +4 -0
- package/ios/Tests/PropertyComponentSpec.swift +33 -30
- package/ios/Tests/RecordSpec.swift +7 -5
- package/ios/Tests/SharedObjectRegistrySpec.swift +12 -12
- package/ios/Tests/TypedArraysSpec.swift +1 -1
- package/ios/Tests/ViewDefinitionSpec.swift +4 -2
- package/package.json +2 -2
- package/src/NativeViewManagerAdapter.native.tsx +33 -29
- package/src/requireNativeModule.ts +2 -2
- package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinitionBuilder.kt +0 -132
- package/ios/EXViewManager.h +0 -21
- package/ios/EXViewManager.m +0 -128
- package/ios/ModuleRegistryAdapter/EXViewManagerAdapterClassesRegistry.h +0 -17
- package/ios/ModuleRegistryAdapter/EXViewManagerAdapterClassesRegistry.m +0 -67
- package/ios/ViewManagerAdapter/EXViewManagerAdapter.h +0 -17
- package/ios/ViewManagerAdapter/EXViewManagerAdapter.m +0 -45
|
@@ -128,11 +128,15 @@ class FunctionSpec: ExpoSpec {
|
|
|
128
128
|
|
|
129
129
|
it("returns the record back (sync)") {
|
|
130
130
|
let result = try Function(functionName) { (record: TestRecord) in record }
|
|
131
|
-
.call(by: nil, withArguments: [dict]) as? TestRecord
|
|
131
|
+
.call(by: nil, withArguments: [dict], appContext: appContext) as? TestRecord
|
|
132
|
+
|
|
133
|
+
guard let result = Conversions.convertFunctionResult(result, appContext: appContext) as? TestRecord.Dict else {
|
|
134
|
+
return fail()
|
|
135
|
+
}
|
|
132
136
|
|
|
133
137
|
expect(result).notTo(beNil())
|
|
134
|
-
expect(result
|
|
135
|
-
expect(result
|
|
138
|
+
expect(result["property"] as? String).to(equal(dict["property"]))
|
|
139
|
+
expect(result["propertyWithCustomKey"] as? String).to(equal(dict["propertyWithCustomKey"]))
|
|
136
140
|
}
|
|
137
141
|
|
|
138
142
|
it("returns the record back (async)") {
|
|
@@ -186,11 +190,11 @@ class FunctionSpec: ExpoSpec {
|
|
|
186
190
|
return returnedValue
|
|
187
191
|
}
|
|
188
192
|
|
|
189
|
-
expect({ try fn.call(by: nil, withArguments: ["test"]) })
|
|
193
|
+
expect({ try fn.call(by: nil, withArguments: ["test"], appContext: appContext) })
|
|
190
194
|
.notTo(throwError())
|
|
191
195
|
.to(be(returnedValue))
|
|
192
196
|
|
|
193
|
-
expect({ try fn.call(by: nil, withArguments: ["test", 3]) })
|
|
197
|
+
expect({ try fn.call(by: nil, withArguments: ["test", 3], appContext: appContext) })
|
|
194
198
|
.notTo(throwError())
|
|
195
199
|
.to(be(returnedValue))
|
|
196
200
|
}
|
|
@@ -200,7 +204,7 @@ class FunctionSpec: ExpoSpec {
|
|
|
200
204
|
return "something"
|
|
201
205
|
}
|
|
202
206
|
|
|
203
|
-
expect({ try fn.call(by: nil, withArguments: []) })
|
|
207
|
+
expect({ try fn.call(by: nil, withArguments: [], appContext: appContext) })
|
|
204
208
|
.to(throwError(errorType: FunctionCallException.self) { error in
|
|
205
209
|
expect(error.rootCause).to(beAKindOf(InvalidArgsNumberException.self))
|
|
206
210
|
let exception = error.rootCause as! InvalidArgsNumberException
|
|
@@ -222,7 +226,8 @@ class FunctionSpec: ExpoSpec {
|
|
|
222
226
|
switch result {
|
|
223
227
|
case .failure(let error):
|
|
224
228
|
expect(error).notTo(beNil())
|
|
225
|
-
expect(error).to(beAKindOf(
|
|
229
|
+
expect(error).to(beAKindOf(FunctionCallException.self))
|
|
230
|
+
expect(error.isCausedBy(ArgumentCastException.self)) == true
|
|
226
231
|
expect(error.isCausedBy(Conversions.CastingException<String>.self)) == true
|
|
227
232
|
case .success(_):
|
|
228
233
|
fail()
|
|
@@ -232,20 +237,20 @@ class FunctionSpec: ExpoSpec {
|
|
|
232
237
|
}
|
|
233
238
|
}
|
|
234
239
|
}
|
|
235
|
-
|
|
240
|
+
|
|
236
241
|
context("JavaScript") {
|
|
237
|
-
let runtime = appContext.runtime
|
|
238
|
-
|
|
242
|
+
let runtime = try! appContext.runtime
|
|
243
|
+
|
|
239
244
|
beforeSuite {
|
|
240
245
|
appContext.moduleRegistry.register(holder: mockModuleHolder(appContext) {
|
|
241
246
|
Name("TestModule")
|
|
242
247
|
|
|
243
248
|
Function("returnPi") { Double.pi }
|
|
244
|
-
|
|
249
|
+
|
|
245
250
|
Function("returnNull") { () -> Double? in
|
|
246
251
|
return nil
|
|
247
252
|
}
|
|
248
|
-
|
|
253
|
+
|
|
249
254
|
Function("isArgNull") { (arg: Double?) -> Bool in
|
|
250
255
|
return arg == nil
|
|
251
256
|
}
|
|
@@ -260,30 +265,41 @@ class FunctionSpec: ExpoSpec {
|
|
|
260
265
|
}
|
|
261
266
|
}
|
|
262
267
|
}
|
|
268
|
+
|
|
269
|
+
Function("withFunction") { (fn: JavaScriptFunction<String>) -> String in
|
|
270
|
+
return try fn.call("foo", "bar")
|
|
271
|
+
}
|
|
263
272
|
})
|
|
264
273
|
}
|
|
265
274
|
|
|
266
275
|
it("returns values") {
|
|
267
|
-
expect(try runtime
|
|
268
|
-
expect(try runtime
|
|
276
|
+
expect(try runtime.eval("expo.modules.TestModule.returnPi()").asDouble()) == Double.pi
|
|
277
|
+
expect(try runtime.eval("expo.modules.TestModule.returnNull()").isNull()) == true
|
|
269
278
|
}
|
|
270
279
|
|
|
271
280
|
it("accepts optional arguments") {
|
|
272
|
-
expect(try runtime
|
|
273
|
-
expect(try runtime
|
|
281
|
+
expect(try runtime.eval("expo.modules.TestModule.isArgNull(3.14)").asBool()) == false
|
|
282
|
+
expect(try runtime.eval("expo.modules.TestModule.isArgNull(null)").asBool()) == true
|
|
274
283
|
}
|
|
275
284
|
|
|
276
285
|
it("returns object made from definition") {
|
|
277
286
|
let initialValue = Int.random(in: 1..<100)
|
|
278
|
-
let object = try runtime
|
|
287
|
+
let object = try runtime.eval("object = expo.modules.TestModule.returnObjectDefinition(\(initialValue))")
|
|
288
|
+
|
|
289
|
+
expect(object.kind) == .object
|
|
290
|
+
expect(object.getObject().hasProperty("increment")) == true
|
|
279
291
|
|
|
280
|
-
|
|
281
|
-
|
|
292
|
+
let result = try runtime.eval("object.increment()")
|
|
293
|
+
|
|
294
|
+
expect(result.kind) == .number
|
|
295
|
+
expect(result.getInt()) == initialValue + 1
|
|
296
|
+
}
|
|
282
297
|
|
|
283
|
-
|
|
298
|
+
it("takes JavaScriptFunction argument") {
|
|
299
|
+
let value = try runtime.eval("expo.modules.TestModule.withFunction((a, b) => a + b)")
|
|
284
300
|
|
|
285
|
-
expect(
|
|
286
|
-
expect(
|
|
301
|
+
expect(value.kind) == .string
|
|
302
|
+
expect(value.getString()) == "foobar"
|
|
287
303
|
}
|
|
288
304
|
}
|
|
289
305
|
}
|
|
@@ -86,7 +86,11 @@ class JavaScriptRuntimeSpec: ExpoSpec {
|
|
|
86
86
|
it("throws evaluation exception") {
|
|
87
87
|
expect({ try runtime.eval("foo") }).to(throwError { error in
|
|
88
88
|
expect(error).to(beAKindOf(JavaScriptEvalException.self))
|
|
89
|
+
#if canImport(reacthermes)
|
|
90
|
+
expect((error as! JavaScriptEvalException).reason).to(contain("Property 'foo' doesn't exist"))
|
|
91
|
+
#else
|
|
89
92
|
expect((error as! JavaScriptEvalException).reason).to(contain("Can't find variable: foo"))
|
|
93
|
+
#endif
|
|
90
94
|
})
|
|
91
95
|
}
|
|
92
96
|
}
|
|
@@ -5,9 +5,12 @@ import ExpoModulesTestCore
|
|
|
5
5
|
class PropertyComponentSpec: ExpoSpec {
|
|
6
6
|
override func spec() {
|
|
7
7
|
describe("property") {
|
|
8
|
+
let appContext = AppContext.create()
|
|
9
|
+
let runtime = try! appContext.runtime
|
|
10
|
+
|
|
8
11
|
it("gets the value") {
|
|
9
12
|
let property = Property("test") { return "expo" }
|
|
10
|
-
expect(try property.getValue()) == "expo"
|
|
13
|
+
expect(try property.getValue(appContext: appContext)) == "expo"
|
|
11
14
|
}
|
|
12
15
|
|
|
13
16
|
it("sets the value") {
|
|
@@ -19,39 +22,39 @@ class PropertyComponentSpec: ExpoSpec {
|
|
|
19
22
|
}
|
|
20
23
|
|
|
21
24
|
let newValue = Int.random(in: 0..<100)
|
|
22
|
-
property.setValue(newValue)
|
|
25
|
+
property.setValue(newValue, appContext: appContext)
|
|
23
26
|
|
|
24
|
-
expect(try property.getValue()) == value
|
|
27
|
+
expect(try property.getValue(appContext: appContext)) == value
|
|
25
28
|
expect(value) == newValue
|
|
26
29
|
}
|
|
27
30
|
}
|
|
28
31
|
|
|
29
32
|
describe("module property") {
|
|
30
33
|
let appContext = AppContext.create()
|
|
31
|
-
let runtime = appContext.runtime
|
|
34
|
+
let runtime = try! appContext.runtime
|
|
32
35
|
|
|
33
36
|
beforeSuite {
|
|
34
37
|
appContext.moduleRegistry.register(moduleType: PropertyTestModule.self)
|
|
35
38
|
}
|
|
36
39
|
|
|
37
40
|
it("gets read-only property") {
|
|
38
|
-
let value = try runtime
|
|
39
|
-
expect(value
|
|
41
|
+
let value = try runtime.eval("expo.modules.PropertyTest.readOnly")
|
|
42
|
+
expect(value.getString()) == "foo"
|
|
40
43
|
}
|
|
41
44
|
|
|
42
45
|
it("gets writable property") {
|
|
43
|
-
let value = try runtime
|
|
44
|
-
expect(value
|
|
46
|
+
let value = try runtime.eval("expo.modules.PropertyTest.writable")
|
|
47
|
+
expect(value.getInt()) == 444
|
|
45
48
|
}
|
|
46
49
|
|
|
47
50
|
it("sets writable property") {
|
|
48
|
-
try runtime
|
|
49
|
-
let value = try runtime
|
|
50
|
-
expect(value
|
|
51
|
+
try runtime.eval("expo.modules.PropertyTest.writable = 777")
|
|
52
|
+
let value = try runtime.eval("expo.modules.PropertyTest.writable")
|
|
53
|
+
expect(value.getInt()) == 777
|
|
51
54
|
}
|
|
52
55
|
|
|
53
56
|
it("is enumerable") {
|
|
54
|
-
let keys = try runtime
|
|
57
|
+
let keys = try runtime.eval("Object.keys(expo.modules.PropertyTest)").getArray().map { $0.getString() } ?? []
|
|
55
58
|
expect(keys).to(contain("readOnly", "writable", "undefined"))
|
|
56
59
|
}
|
|
57
60
|
|
|
@@ -62,73 +65,73 @@ class PropertyComponentSpec: ExpoSpec {
|
|
|
62
65
|
// }
|
|
63
66
|
|
|
64
67
|
it("returns undefined when getter is not specified") {
|
|
65
|
-
let value = try runtime
|
|
66
|
-
expect(value
|
|
68
|
+
let value = try runtime.eval("expo.modules.PropertyTest.undefined")
|
|
69
|
+
expect(value.isUndefined()) == true
|
|
67
70
|
}
|
|
68
71
|
}
|
|
69
72
|
|
|
70
73
|
describe("class property") {
|
|
71
74
|
let appContext = AppContext.create()
|
|
72
|
-
let runtime = appContext.runtime
|
|
75
|
+
let runtime = try! appContext.runtime
|
|
73
76
|
|
|
74
77
|
beforeSuite {
|
|
75
78
|
appContext.moduleRegistry.register(moduleType: PropertyTestModule.self)
|
|
76
79
|
}
|
|
77
80
|
|
|
78
81
|
it("gets the value") {
|
|
79
|
-
let value = try runtime
|
|
82
|
+
let value = try runtime.eval("new expo.modules.PropertyTest.TestClass().someValue")
|
|
80
83
|
|
|
81
|
-
expect(value
|
|
82
|
-
expect(value
|
|
84
|
+
expect(value.kind) == .number
|
|
85
|
+
expect(value.getInt()) == TestClass.constantValue
|
|
83
86
|
}
|
|
84
87
|
|
|
85
88
|
it("sets the value") {
|
|
86
89
|
let newValue = Int.random(in: 1..<100)
|
|
87
|
-
let value = try runtime
|
|
90
|
+
let value = try runtime.eval([
|
|
88
91
|
"object = new expo.modules.PropertyTest.TestClass()",
|
|
89
92
|
"object.someValue = \(newValue)",
|
|
90
93
|
"object.someValue"
|
|
91
94
|
])
|
|
92
95
|
|
|
93
|
-
expect(value
|
|
94
|
-
expect(value
|
|
96
|
+
expect(value.kind) == .number
|
|
97
|
+
expect(value.getInt()) == newValue
|
|
95
98
|
}
|
|
96
99
|
|
|
97
100
|
// Tests for accessing shared object properties through KeyPath and ReferenceWritableKeyPath
|
|
98
101
|
describe("key path") {
|
|
99
102
|
it("gets immutable property") {
|
|
100
|
-
let value = try runtime
|
|
103
|
+
let value = try runtime.eval([
|
|
101
104
|
"object = new expo.modules.PropertyTest.TestClass()",
|
|
102
105
|
"object.immutableKeyPathProperty"
|
|
103
106
|
])
|
|
104
107
|
|
|
105
|
-
expect(value
|
|
106
|
-
expect(value
|
|
108
|
+
expect(value.kind) == .number
|
|
109
|
+
expect(value.getInt()) == TestClass.constantValue
|
|
107
110
|
}
|
|
108
111
|
|
|
109
112
|
it("cannot set immutable property") {
|
|
110
113
|
let newValue = Int.random(in: 100..<200)
|
|
111
|
-
let value = try runtime
|
|
114
|
+
let value = try runtime.eval([
|
|
112
115
|
"object = new expo.modules.PropertyTest.TestClass()",
|
|
113
116
|
"object.immutableKeyPathProperty = \(newValue)",
|
|
114
117
|
"object.immutableKeyPathProperty"
|
|
115
118
|
])
|
|
116
119
|
|
|
117
120
|
// Returned value didn't change, it doesn't equal to `newValue`
|
|
118
|
-
expect(value
|
|
119
|
-
expect(value
|
|
121
|
+
expect(value.kind) == .number
|
|
122
|
+
expect(value.getInt()) == TestClass.constantValue
|
|
120
123
|
}
|
|
121
124
|
|
|
122
125
|
it("sets mutable property") {
|
|
123
126
|
let newValue = Int.random(in: 100..<200)
|
|
124
|
-
let value = try runtime
|
|
127
|
+
let value = try runtime.eval([
|
|
125
128
|
"object = new expo.modules.PropertyTest.TestClass()",
|
|
126
129
|
"object.mutableKeyPathProperty = \(newValue)",
|
|
127
130
|
"object.mutableKeyPathProperty"
|
|
128
131
|
])
|
|
129
132
|
|
|
130
|
-
expect(value
|
|
131
|
-
expect(value
|
|
133
|
+
expect(value.kind) == .number
|
|
134
|
+
expect(value.getInt()) == newValue
|
|
132
135
|
}
|
|
133
136
|
}
|
|
134
137
|
}
|
|
@@ -4,9 +4,11 @@ import ExpoModulesTestCore
|
|
|
4
4
|
|
|
5
5
|
class RecordSpec: ExpoSpec {
|
|
6
6
|
override func spec() {
|
|
7
|
+
let appContext = AppContext.create()
|
|
8
|
+
|
|
7
9
|
it("initializes with empty dictionary") {
|
|
8
10
|
struct TestRecord: Record { }
|
|
9
|
-
_ = try TestRecord(from: [:])
|
|
11
|
+
_ = try TestRecord(from: [:], appContext: appContext)
|
|
10
12
|
}
|
|
11
13
|
|
|
12
14
|
it("works back and forth with a field") {
|
|
@@ -14,7 +16,7 @@ class RecordSpec: ExpoSpec {
|
|
|
14
16
|
@Field var a: String?
|
|
15
17
|
}
|
|
16
18
|
let dict = ["a": "b"]
|
|
17
|
-
let record = try TestRecord(from: dict)
|
|
19
|
+
let record = try TestRecord(from: dict, appContext: appContext)
|
|
18
20
|
|
|
19
21
|
expect(record.a).to(be(dict["a"]))
|
|
20
22
|
expect(record.toDictionary()["a"]).to(be(dict["a"]))
|
|
@@ -25,7 +27,7 @@ class RecordSpec: ExpoSpec {
|
|
|
25
27
|
@Field("key") var a: String?
|
|
26
28
|
}
|
|
27
29
|
let dict = ["key": "b"]
|
|
28
|
-
let record = try TestRecord(from: dict)
|
|
30
|
+
let record = try TestRecord(from: dict, appContext: appContext)
|
|
29
31
|
|
|
30
32
|
expect(record.a).to(be(dict["key"]))
|
|
31
33
|
expect(record.toDictionary()["key"]).to(be(dict["key"]))
|
|
@@ -36,7 +38,7 @@ class RecordSpec: ExpoSpec {
|
|
|
36
38
|
@Field(.required) var a: Int
|
|
37
39
|
}
|
|
38
40
|
|
|
39
|
-
expect { try TestRecord(from: [:]) }.to(throwError { error in
|
|
41
|
+
expect { try TestRecord(from: [:], appContext: appContext) }.to(throwError { error in
|
|
40
42
|
expect(error).to(beAKindOf(FieldRequiredException.self))
|
|
41
43
|
})
|
|
42
44
|
}
|
|
@@ -47,7 +49,7 @@ class RecordSpec: ExpoSpec {
|
|
|
47
49
|
}
|
|
48
50
|
let dict = ["a": "try with String instead of Int"]
|
|
49
51
|
|
|
50
|
-
expect { try TestRecord(from: dict) }.to(throwError { error in
|
|
52
|
+
expect { try TestRecord(from: dict, appContext: appContext) }.to(throwError { error in
|
|
51
53
|
expect(error).to(beAKindOf(FieldInvalidTypeException.self))
|
|
52
54
|
})
|
|
53
55
|
}
|
|
@@ -7,7 +7,7 @@ import ExpoModulesTestCore
|
|
|
7
7
|
final class SharedObjectRegistrySpec: ExpoSpec {
|
|
8
8
|
override func spec() {
|
|
9
9
|
let appContext = AppContext.create()
|
|
10
|
-
let runtime = appContext.runtime
|
|
10
|
+
let runtime = try! appContext.runtime
|
|
11
11
|
|
|
12
12
|
describe("pullNextId") {
|
|
13
13
|
it("returns nextId") {
|
|
@@ -29,28 +29,28 @@ final class SharedObjectRegistrySpec: ExpoSpec {
|
|
|
29
29
|
describe("add") {
|
|
30
30
|
it("adds using nextId") {
|
|
31
31
|
let nextId = SharedObjectRegistry.nextId
|
|
32
|
-
let id = SharedObjectRegistry.add(native: TestSharedObject(), javaScript: runtime
|
|
32
|
+
let id = SharedObjectRegistry.add(native: TestSharedObject(), javaScript: runtime.createObject())
|
|
33
33
|
expect(nextId) == id
|
|
34
34
|
}
|
|
35
35
|
it("is increasing size") {
|
|
36
36
|
let size = SharedObjectRegistry.size
|
|
37
|
-
SharedObjectRegistry.add(native: TestSharedObject(), javaScript: runtime
|
|
37
|
+
SharedObjectRegistry.add(native: TestSharedObject(), javaScript: runtime.createObject())
|
|
38
38
|
expect(SharedObjectRegistry.size) == size + 1
|
|
39
39
|
}
|
|
40
40
|
it("assigns id on native object") {
|
|
41
41
|
let nativeObject = TestSharedObject()
|
|
42
|
-
let id = SharedObjectRegistry.add(native: nativeObject, javaScript: runtime
|
|
42
|
+
let id = SharedObjectRegistry.add(native: nativeObject, javaScript: runtime.createObject())
|
|
43
43
|
expect(nativeObject.sharedObjectId) == id
|
|
44
44
|
}
|
|
45
45
|
it("assigns id on JS object") {
|
|
46
|
-
let jsObject = runtime
|
|
46
|
+
let jsObject = runtime.createObject()
|
|
47
47
|
let id = SharedObjectRegistry.add(native: TestSharedObject(), javaScript: jsObject)
|
|
48
48
|
expect(jsObject.hasProperty(sharedObjectIdPropertyName)) == true
|
|
49
49
|
expect(try! jsObject.getProperty(sharedObjectIdPropertyName).asInt()) == id
|
|
50
50
|
}
|
|
51
51
|
it("saves objects pair") {
|
|
52
52
|
let nativeObject = TestSharedObject()
|
|
53
|
-
let jsObject = runtime
|
|
53
|
+
let jsObject = runtime.createObject()
|
|
54
54
|
let id = SharedObjectRegistry.add(native: nativeObject, javaScript: jsObject)
|
|
55
55
|
let pair = SharedObjectRegistry.get(id)
|
|
56
56
|
expect(pair?.native) === nativeObject
|
|
@@ -60,18 +60,18 @@ final class SharedObjectRegistrySpec: ExpoSpec {
|
|
|
60
60
|
|
|
61
61
|
describe("delete") {
|
|
62
62
|
it("deletes objects pair") {
|
|
63
|
-
let id = SharedObjectRegistry.add(native: TestSharedObject(), javaScript: runtime
|
|
63
|
+
let id = SharedObjectRegistry.add(native: TestSharedObject(), javaScript: runtime.createObject())
|
|
64
64
|
SharedObjectRegistry.delete(id)
|
|
65
65
|
expect(SharedObjectRegistry.get(id)).to(beNil())
|
|
66
66
|
}
|
|
67
67
|
it("resets id on native object") {
|
|
68
68
|
let nativeObject = TestSharedObject()
|
|
69
|
-
let id = SharedObjectRegistry.add(native: nativeObject, javaScript: runtime
|
|
69
|
+
let id = SharedObjectRegistry.add(native: nativeObject, javaScript: runtime.createObject())
|
|
70
70
|
SharedObjectRegistry.delete(id)
|
|
71
71
|
expect(nativeObject.sharedObjectId) == 0
|
|
72
72
|
}
|
|
73
73
|
it("resets id on JS object") {
|
|
74
|
-
let jsObject = runtime
|
|
74
|
+
let jsObject = runtime.createObject()
|
|
75
75
|
let id = SharedObjectRegistry.add(native: TestSharedObject(), javaScript: jsObject)
|
|
76
76
|
SharedObjectRegistry.delete(id)
|
|
77
77
|
expect(try! jsObject.getProperty(sharedObjectIdPropertyName).asInt()) == 0
|
|
@@ -81,12 +81,12 @@ final class SharedObjectRegistrySpec: ExpoSpec {
|
|
|
81
81
|
describe("toNativeObject") {
|
|
82
82
|
it("returns native object") {
|
|
83
83
|
let nativeObject = TestSharedObject()
|
|
84
|
-
let jsObject = runtime
|
|
84
|
+
let jsObject = runtime.createObject()
|
|
85
85
|
SharedObjectRegistry.add(native: nativeObject, javaScript: jsObject)
|
|
86
86
|
expect(SharedObjectRegistry.toNativeObject(jsObject)) === nativeObject
|
|
87
87
|
}
|
|
88
88
|
it("returns nil") {
|
|
89
|
-
let jsObject = runtime
|
|
89
|
+
let jsObject = runtime.createObject()
|
|
90
90
|
expect(SharedObjectRegistry.toNativeObject(jsObject)).to(beNil())
|
|
91
91
|
}
|
|
92
92
|
}
|
|
@@ -94,7 +94,7 @@ final class SharedObjectRegistrySpec: ExpoSpec {
|
|
|
94
94
|
describe("toJavaScriptObject") {
|
|
95
95
|
it("returns JS object") {
|
|
96
96
|
let nativeObject = TestSharedObject()
|
|
97
|
-
let jsObject = runtime
|
|
97
|
+
let jsObject = runtime.createObject()
|
|
98
98
|
SharedObjectRegistry.add(native: nativeObject, javaScript: jsObject)
|
|
99
99
|
expect(SharedObjectRegistry.toJavaScriptObject(nativeObject)) == jsObject
|
|
100
100
|
}
|
|
@@ -8,7 +8,7 @@ final class TypedArraysSpec: ExpoSpec {
|
|
|
8
8
|
override func spec() {
|
|
9
9
|
describe("module") {
|
|
10
10
|
let appContext = AppContext.create()
|
|
11
|
-
let runtime = appContext.runtime
|
|
11
|
+
let runtime = try! appContext.runtime
|
|
12
12
|
|
|
13
13
|
beforeSuite {
|
|
14
14
|
appContext.moduleRegistry.register(moduleType: TypedArraysModule.self)
|
|
@@ -15,6 +15,8 @@ final class ViewDefinitionSpec: ExpoSpec {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
describe("Prop") {
|
|
18
|
+
let appContext = AppContext.create()
|
|
19
|
+
|
|
18
20
|
it("sets the prop") {
|
|
19
21
|
let textView = UITextView()
|
|
20
22
|
let content = "hello"
|
|
@@ -23,7 +25,7 @@ final class ViewDefinitionSpec: ExpoSpec {
|
|
|
23
25
|
view.text = value
|
|
24
26
|
}
|
|
25
27
|
}
|
|
26
|
-
try definition.propsDict()["content"]?.set(value: content, onView: textView)
|
|
28
|
+
try definition.propsDict()["content"]?.set(value: content, onView: textView, appContext: appContext)
|
|
27
29
|
expect(textView.text) == content
|
|
28
30
|
}
|
|
29
31
|
|
|
@@ -36,7 +38,7 @@ final class ViewDefinitionSpec: ExpoSpec {
|
|
|
36
38
|
expect(view).to(beAKindOf(UITextView.self))
|
|
37
39
|
}
|
|
38
40
|
}
|
|
39
|
-
try definition.propsDict()["content"]?.set(value: content, onView: textView)
|
|
41
|
+
try definition.propsDict()["content"]?.set(value: content, onView: textView, appContext: appContext)
|
|
40
42
|
}
|
|
41
43
|
}
|
|
42
44
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-modules-core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "The core of Expo Modules architecture",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -42,5 +42,5 @@
|
|
|
42
42
|
"@testing-library/react-hooks": "^7.0.1",
|
|
43
43
|
"expo-module-scripts": "^3.0.0"
|
|
44
44
|
},
|
|
45
|
-
"gitHead": "
|
|
45
|
+
"gitHead": "4ba50c428c8369bb6b3a51a860d4898ad4ccbe78"
|
|
46
46
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { NativeModules, requireNativeComponent, HostComponent } from 'react-native';
|
|
2
|
+
import { findNodeHandle, NativeModules, requireNativeComponent, HostComponent } from 'react-native';
|
|
3
|
+
|
|
4
|
+
import { requireNativeModule } from './requireNativeModule';
|
|
3
5
|
|
|
4
6
|
// To make the transition from React Native's `requireNativeComponent` to Expo's
|
|
5
7
|
// `requireNativeViewManager` as easy as possible, `requireNativeViewManager` is a drop-in
|
|
@@ -10,10 +12,6 @@ import { NativeModules, requireNativeComponent, HostComponent } from 'react-nati
|
|
|
10
12
|
// passed to React Native's View (ex: style, testID) and custom view props, which are passed to the
|
|
11
13
|
// adapter view component in a prop called `proxiedProperties`.
|
|
12
14
|
|
|
13
|
-
type NativeExpoComponentProps = {
|
|
14
|
-
proxiedProperties: object;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
15
|
/**
|
|
18
16
|
* A map that caches registered native components.
|
|
19
17
|
*/
|
|
@@ -52,33 +50,39 @@ export function requireNativeViewManager<P>(viewName: string): React.ComponentTy
|
|
|
52
50
|
// Set up the React Native native component, which is an adapter to the universal module's view
|
|
53
51
|
// manager
|
|
54
52
|
const reactNativeViewName = `ViewManagerAdapter_${viewName}`;
|
|
55
|
-
const ReactNativeComponent =
|
|
56
|
-
requireCachedNativeComponent<NativeExpoComponentProps>(reactNativeViewName);
|
|
57
|
-
const proxiedPropsNames = viewManagerConfig?.propsNames ?? [];
|
|
53
|
+
const ReactNativeComponent = requireCachedNativeComponent(reactNativeViewName);
|
|
58
54
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
55
|
+
class NativeComponent extends React.PureComponent<P> {
|
|
56
|
+
static displayName = viewName;
|
|
57
|
+
|
|
58
|
+
// This will be accessed from native when the prototype functions are called,
|
|
59
|
+
// in order to find the associated native view.
|
|
60
|
+
nativeTag: number | null = null;
|
|
61
|
+
|
|
62
|
+
componentDidMount(): void {
|
|
63
|
+
this.nativeTag = findNodeHandle(this);
|
|
64
|
+
}
|
|
68
65
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
delete copied[propName];
|
|
66
|
+
render(): React.ReactNode {
|
|
67
|
+
return <ReactNativeComponent {...this.props} />;
|
|
68
|
+
}
|
|
73
69
|
}
|
|
74
|
-
return copied;
|
|
75
|
-
}
|
|
76
70
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
71
|
+
try {
|
|
72
|
+
const nativeModule = requireNativeModule(viewName);
|
|
73
|
+
const nativeViewPrototype = nativeModule.ViewPrototype;
|
|
74
|
+
|
|
75
|
+
if (nativeViewPrototype) {
|
|
76
|
+
// Assign native view functions to the component prototype so they can be accessed from the ref.
|
|
77
|
+
Object.assign(NativeComponent.prototype, nativeViewPrototype);
|
|
81
78
|
}
|
|
82
|
-
|
|
83
|
-
|
|
79
|
+
} catch {
|
|
80
|
+
// `requireNativeModule` may throw an error when the native module cannot be found.
|
|
81
|
+
// In some tests we don't mock the entire modules, but we do want to mock native views. For now,
|
|
82
|
+
// until we still have to support the legacy modules proxy and don't have better ways to mock,
|
|
83
|
+
// let's just gracefully skip assigning the prototype functions.
|
|
84
|
+
// See: https://github.com/expo/expo/blob/main/packages/expo-modules-core/src/__tests__/NativeViewManagerAdapter-test.native.tsx
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return NativeComponent;
|
|
84
88
|
}
|
|
@@ -34,8 +34,8 @@ declare global {
|
|
|
34
34
|
*/
|
|
35
35
|
export function requireNativeModule<ModuleType = any>(moduleName: string): ModuleType {
|
|
36
36
|
const nativeModule: ModuleType =
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
globalThis.expo?.modules?.[moduleName] ??
|
|
38
|
+
globalThis.ExpoModules?.[moduleName] ??
|
|
39
39
|
NativeModulesProxy[moduleName];
|
|
40
40
|
|
|
41
41
|
if (!nativeModule) {
|