expo-modules-core 0.7.0 → 0.9.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.
Files changed (129) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/README.md +1 -1
  3. package/android/ExpoModulesCorePlugin.gradle +15 -0
  4. package/android/build.gradle +46 -32
  5. package/android/src/main/java/expo/modules/adapters/react/NativeModulesProxy.java +5 -5
  6. package/android/src/main/java/expo/modules/adapters/react/services/UIManagerModuleWrapper.java +13 -0
  7. package/android/src/main/java/expo/modules/core/ViewManager.java +9 -0
  8. package/android/src/main/java/expo/modules/core/interfaces/JavaScriptContextProvider.java +4 -0
  9. package/android/src/main/java/expo/modules/core/interfaces/ReactActivityHandler.java +37 -1
  10. package/android/src/main/java/expo/modules/core/interfaces/ReactNativeHostHandler.java +30 -0
  11. package/android/src/main/java/expo/modules/core/interfaces/services/UIManager.java +2 -0
  12. package/android/src/main/java/expo/modules/kotlin/AppContext.kt +13 -5
  13. package/android/src/main/java/expo/modules/kotlin/KPromiseWrapper.kt +2 -13
  14. package/android/src/main/java/expo/modules/kotlin/KotlinInteropModuleRegistry.kt +11 -5
  15. package/android/src/main/java/expo/modules/kotlin/ModuleHolder.kt +5 -1
  16. package/android/src/main/java/expo/modules/kotlin/ModuleRegistry.kt +17 -0
  17. package/android/src/main/java/expo/modules/kotlin/callbacks/ViewCallback.kt +14 -3
  18. package/android/src/main/java/expo/modules/kotlin/events/EventEmitter.kt +13 -0
  19. package/android/src/main/java/expo/modules/kotlin/events/KModuleEventEmitterWrapper.kt +102 -0
  20. package/android/src/main/java/expo/modules/kotlin/exception/CodedException.kt +25 -1
  21. package/android/src/main/java/expo/modules/kotlin/{methods/AnyMethod.kt → functions/AnyFunction.kt} +6 -5
  22. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunction.kt +15 -0
  23. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionBuilder.kt +170 -0
  24. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromise.kt +15 -0
  25. package/android/src/main/java/expo/modules/kotlin/functions/AsyncSuspendFunction.kt +36 -0
  26. package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +14 -0
  27. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +374 -41
  28. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionData.kt +2 -2
  29. package/android/src/main/java/expo/modules/kotlin/records/FieldValidator.kt +139 -0
  30. package/android/src/main/java/expo/modules/kotlin/records/Record.kt +0 -39
  31. package/android/src/main/java/expo/modules/kotlin/records/RecordTypeConverter.kt +59 -10
  32. package/android/src/main/java/expo/modules/kotlin/records/Required.kt +5 -0
  33. package/android/src/main/java/expo/modules/kotlin/records/ValidationBinder.kt +110 -0
  34. package/android/src/main/java/expo/modules/kotlin/records/Validators.kt +61 -0
  35. package/android/src/main/java/expo/modules/kotlin/types/JSTypeConverter.kt +35 -0
  36. package/android/src/main/java/expo/modules/kotlin/types/JSTypeConverterHelper.kt +148 -0
  37. package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +9 -1
  38. package/android/src/main/java/expo/modules/kotlin/views/GroupViewManagerWrapper.kt +49 -0
  39. package/android/src/main/java/expo/modules/kotlin/views/ViewGroupDefinition.kt +18 -0
  40. package/android/src/main/java/expo/modules/kotlin/views/ViewGroupDefinitionBuilder.kt +114 -0
  41. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinition.kt +4 -1
  42. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinitionBuilder.kt +56 -5
  43. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerWrapperDelegate.kt +3 -0
  44. package/build/NativeModulesProxy.native.d.ts +0 -4
  45. package/build/NativeModulesProxy.native.d.ts.map +1 -1
  46. package/build/NativeModulesProxy.native.js +1 -14
  47. package/build/NativeModulesProxy.native.js.map +1 -1
  48. package/build/NativeModulesProxy.types.d.ts +0 -3
  49. package/build/NativeModulesProxy.types.d.ts.map +1 -1
  50. package/build/NativeModulesProxy.types.js.map +1 -1
  51. package/build/NativeViewManagerAdapter.native.d.ts.map +1 -1
  52. package/build/NativeViewManagerAdapter.native.js +9 -33
  53. package/build/NativeViewManagerAdapter.native.js.map +1 -1
  54. package/build/sweet/NativeErrorManager.js +1 -1
  55. package/build/sweet/NativeErrorManager.js.map +1 -1
  56. package/ios/AppDelegates/EXAppDelegatesLoader.m +4 -8
  57. package/ios/AppDelegates/ExpoAppDelegate.swift +4 -10
  58. package/ios/EXAppDefines.h +1 -0
  59. package/ios/EXAppDefines.m +6 -0
  60. package/ios/EXUtilities.h +2 -0
  61. package/ios/EXUtilities.m +12 -0
  62. package/ios/ExpoModulesCore.h +4 -0
  63. package/ios/ExpoModulesCore.podspec +4 -2
  64. package/ios/Interfaces/FileSystem/EXFileSystemInterface.h +1 -1
  65. package/ios/Interfaces/TaskManager/EXTaskServiceInterface.h +1 -0
  66. package/ios/JSI/{JSIConversions.h → EXJSIConversions.h} +4 -1
  67. package/ios/JSI/{JSIConversions.mm → EXJSIConversions.mm} +16 -5
  68. package/ios/JSI/{JSIInstaller.h → EXJSIInstaller.h} +3 -3
  69. package/ios/JSI/EXJSIInstaller.mm +17 -0
  70. package/ios/JSI/{ExpoModulesProxySpec.h → EXJSIUtils.h} +0 -9
  71. package/ios/JSI/{ExpoModulesProxySpec.mm → EXJSIUtils.mm} +4 -48
  72. package/ios/JSI/EXJavaScriptObject.h +97 -0
  73. package/ios/JSI/EXJavaScriptObject.mm +121 -0
  74. package/ios/JSI/{JavaScriptRuntime.h → EXJavaScriptRuntime.h} +27 -8
  75. package/ios/JSI/EXJavaScriptRuntime.mm +153 -0
  76. package/ios/JSI/EXJavaScriptValue.h +57 -0
  77. package/ios/JSI/EXJavaScriptValue.mm +166 -0
  78. package/ios/JSI/ExpoModulesHostObject.mm +2 -1
  79. package/ios/JSI/JavaScriptRuntime.swift +32 -0
  80. package/ios/JSI/JavaScriptValue.swift +94 -0
  81. package/ios/ModuleRegistryAdapter/EXModuleRegistryAdapter.m +1 -11
  82. package/ios/NativeModulesProxy/EXNativeModulesProxy.h +2 -2
  83. package/ios/NativeModulesProxy/EXNativeModulesProxy.mm +24 -22
  84. package/ios/ReactDelegates/EXReactCompatibleHelpers.h +18 -0
  85. package/ios/ReactDelegates/EXReactCompatibleHelpers.m +19 -0
  86. package/ios/ReactDelegates/ExpoReactDelegate.swift +2 -2
  87. package/ios/ReactDelegates/ExpoReactDelegateHandler.swift +1 -1
  88. package/ios/Swift/AppContext.swift +21 -2
  89. package/ios/Swift/Arguments/AnyArgumentType.swift +1 -1
  90. package/ios/Swift/Functions/AnyFunction.swift +5 -0
  91. package/ios/Swift/Functions/AsyncFunctionComponent.swift +182 -0
  92. package/ios/Swift/Functions/ConcreteFunction.swift +40 -68
  93. package/ios/Swift/Functions/SyncFunctionComponent.swift +181 -0
  94. package/ios/Swift/JavaScriptUtils.swift +56 -0
  95. package/ios/Swift/ModuleHolder.swift +17 -5
  96. package/ios/Swift/Modules/ModuleDefinitionComponents.swift +66 -44
  97. package/ios/Swift/ModulesProvider.swift +3 -10
  98. package/ios/Swift/Objects/ObjectDefinitionComponents.swift +49 -0
  99. package/ios/Swift/SwiftInteropBridge.swift +14 -5
  100. package/ios/Swift/Views/ComponentData.swift +2 -1
  101. package/ios/Swift/Views/ExpoView.swift +8 -0
  102. package/ios/Swift/Views/ViewManagerDefinitionComponents.swift +23 -0
  103. package/ios/Swift.h +5 -0
  104. package/ios/Tests/ArgumentTypeSpec.swift +2 -3
  105. package/ios/Tests/ConstantsSpec.swift +6 -7
  106. package/ios/Tests/ConvertiblesSpec.swift +2 -3
  107. package/ios/Tests/ExceptionsSpec.swift +2 -3
  108. package/ios/Tests/ExpoModulesSpec.swift +75 -0
  109. package/ios/Tests/FunctionSpec.swift +13 -15
  110. package/ios/Tests/FunctionWithConvertiblesSpec.swift +4 -5
  111. package/ios/Tests/JavaScriptObjectSpec.swift +97 -0
  112. package/ios/Tests/JavaScriptRuntimeSpec.swift +94 -0
  113. package/ios/Tests/ModuleEventListenersSpec.swift +15 -16
  114. package/ios/Tests/ModuleRegistrySpec.swift +2 -3
  115. package/ios/Tests/RecordSpec.swift +2 -3
  116. package/package.json +2 -2
  117. package/src/NativeModulesProxy.native.ts +2 -22
  118. package/src/NativeModulesProxy.types.ts +0 -8
  119. package/src/NativeViewManagerAdapter.native.tsx +12 -28
  120. package/src/sweet/NativeErrorManager.ts +1 -1
  121. package/android/src/main/java/expo/modules/kotlin/events/KEventEmitterWrapper.kt +0 -26
  122. package/android/src/main/java/expo/modules/kotlin/methods/Method.kt +0 -14
  123. package/android/src/main/java/expo/modules/kotlin/methods/PromiseMethod.kt +0 -15
  124. package/ios/JSI/JSIInstaller.mm +0 -34
  125. package/ios/JSI/JavaScriptObject.h +0 -60
  126. package/ios/JSI/JavaScriptObject.mm +0 -93
  127. package/ios/JSI/JavaScriptRuntime.mm +0 -102
  128. package/ios/NativeModulesProxy/EXComponentDataCompatibleWrapper.h +0 -16
  129. package/ios/NativeModulesProxy/EXComponentDataCompatibleWrapper.m +0 -28
@@ -1,9 +1,8 @@
1
- import Quick
2
- import Nimble
1
+ import ExpoModulesTestCore
3
2
 
4
3
  @testable import ExpoModulesCore
5
4
 
6
- class FunctionSpec: QuickSpec {
5
+ class FunctionSpec: ExpoSpec {
7
6
  override func spec() {
8
7
  let appContext = AppContext()
9
8
  let functionName = "test function name"
@@ -11,7 +10,7 @@ class FunctionSpec: QuickSpec {
11
10
  func testFunctionReturning<T: Equatable>(value returnValue: T) {
12
11
  waitUntil { done in
13
12
  mockModuleHolder(appContext) {
14
- function(functionName) {
13
+ AsyncFunction(functionName) {
15
14
  return returnValue
16
15
  }
17
16
  }
@@ -27,7 +26,7 @@ class FunctionSpec: QuickSpec {
27
26
  it("is called") {
28
27
  waitUntil { done in
29
28
  mockModuleHolder(appContext) {
30
- function(functionName) {
29
+ AsyncFunction(functionName) {
31
30
  done()
32
31
  }
33
32
  }
@@ -60,7 +59,7 @@ class FunctionSpec: QuickSpec {
60
59
  let str: String? = nil
61
60
 
62
61
  mockModuleHolder(appContext) {
63
- function(functionName) { (a: String?) in
62
+ AsyncFunction(functionName) { (a: String?) in
64
63
  expect(a == nil) == true
65
64
  }
66
65
  }
@@ -71,7 +70,7 @@ class FunctionSpec: QuickSpec {
71
70
  let array: [[String]] = [["expo"]]
72
71
 
73
72
  mockModuleHolder(appContext) {
74
- function(functionName) { (a: [[String]]) in
73
+ AsyncFunction(functionName) { (a: [[String]]) in
75
74
  expect(a.first!.first) == array.first!.first
76
75
  }
77
76
  }
@@ -92,7 +91,7 @@ class FunctionSpec: QuickSpec {
92
91
  it("converts to simple record when passed as an argument") {
93
92
  waitUntil { done in
94
93
  mockModuleHolder(appContext) {
95
- function(functionName) { (a: TestRecord) in
94
+ AsyncFunction(functionName) { (a: TestRecord) in
96
95
  return a.property
97
96
  }
98
97
  }
@@ -108,7 +107,7 @@ class FunctionSpec: QuickSpec {
108
107
  it("converts to record with custom key") {
109
108
  waitUntil { done in
110
109
  mockModuleHolder(appContext) {
111
- function(functionName) { (a: TestRecord) in
110
+ AsyncFunction(functionName) { (a: TestRecord) in
112
111
  return a.customKeyProperty
113
112
  }
114
113
  }
@@ -124,7 +123,7 @@ class FunctionSpec: QuickSpec {
124
123
  it("returns the record back") {
125
124
  waitUntil { done in
126
125
  mockModuleHolder(appContext) {
127
- function(functionName) { (a: TestRecord) in
126
+ AsyncFunction(functionName) { (a: TestRecord) in
128
127
  return a.toDictionary()
129
128
  }
130
129
  }
@@ -145,15 +144,14 @@ class FunctionSpec: QuickSpec {
145
144
  it("throws when called with more arguments than expected") {
146
145
  waitUntil { done in
147
146
  mockModuleHolder(appContext) {
148
- function(functionName) { (_: Int) in
147
+ AsyncFunction(functionName) { (_: Int) in
149
148
  return "something"
150
149
  }
151
150
  }
152
151
  // Function expects one argument, let's give it more.
153
152
  .call(function: functionName, args: [1, 2]) { _, error in
154
153
  expect(error).notTo(beNil())
155
- expect(error).to(beAKindOf(FunctionCallException.self))
156
- expect((error as! Exception).isCausedBy(InvalidArgsNumberException.self)) == true
154
+ expect(error).to(beAKindOf(InvalidArgsNumberException.self))
157
155
  done()
158
156
  }
159
157
  }
@@ -162,14 +160,14 @@ class FunctionSpec: QuickSpec {
162
160
  it("throws when called with arguments of incompatible types") {
163
161
  waitUntil { done in
164
162
  mockModuleHolder(appContext) {
165
- function(functionName) { (_: String) in
163
+ AsyncFunction(functionName) { (_: String) in
166
164
  return "something"
167
165
  }
168
166
  }
169
167
  // Function expects a string, let's give it a number.
170
168
  .call(function: functionName, args: [1]) { value, error in
171
169
  expect(error).notTo(beNil())
172
- expect(error).to(beAKindOf(FunctionCallException.self))
170
+ expect(error).to(beAKindOf(ArgumentCastException.self))
173
171
  expect((error as! Exception).isCausedBy(Conversions.CastingException<String>.self)) == true
174
172
  done()
175
173
  }
@@ -1,12 +1,11 @@
1
1
  // Copyright 2018-present 650 Industries. All rights reserved.
2
2
 
3
3
  import CoreGraphics
4
- import Quick
5
- import Nimble
4
+ import ExpoModulesTestCore
6
5
 
7
6
  @testable import ExpoModulesCore
8
7
 
9
- class FunctionWithConvertiblesSpec: QuickSpec {
8
+ class FunctionWithConvertiblesSpec: ExpoSpec {
10
9
  override func spec() {
11
10
  let appContext = AppContext()
12
11
  let functionName = "function"
@@ -18,7 +17,7 @@ class FunctionWithConvertiblesSpec: QuickSpec {
18
17
  let height = 592.1
19
18
 
20
19
  mockModuleHolder(appContext) {
21
- function(functionName) { (point: CGPoint, size: CGSize, vector: CGVector, rect: CGRect) in
20
+ AsyncFunction(functionName) { (point: CGPoint, size: CGSize, vector: CGVector, rect: CGRect) in
22
21
  expect(point.x) == x
23
22
  expect(point.y) == y
24
23
  expect(size.width) == width
@@ -48,7 +47,7 @@ class FunctionWithConvertiblesSpec: QuickSpec {
48
47
  }
49
48
 
50
49
  mockModuleHolder(appContext) {
51
- function(functionName) { (color1: CGColor, color2: CGColor, color3: CGColor, color4: CGColor) in
50
+ AsyncFunction(functionName) { (color1: CGColor, color2: CGColor, color3: CGColor, color4: CGColor) in
52
51
  testColorComponents(color1, 0x2A, 0x4B, 0x5D, 0xFF)
53
52
  testColorComponents(color2, 0x11, 0xFF, 0x00, 0xDD)
54
53
  testColorComponents(color3, 0x66, 0x00, 0xCC, 0xAA)
@@ -0,0 +1,97 @@
1
+ // Copyright 2022-present 650 Industries. All rights reserved.
2
+
3
+ import ExpoModulesTestCore
4
+
5
+ @testable import ExpoModulesCore
6
+
7
+ final class JavaScriptObjectSpec: ExpoSpec {
8
+ override func spec() {
9
+ let runtime = JavaScriptRuntime()
10
+ var object: JavaScriptObject?
11
+
12
+ let key = "expo"
13
+ let value1 = "💙"
14
+ let value2 = "💛"
15
+
16
+ beforeEach {
17
+ object = runtime.createObject()
18
+ }
19
+
20
+ describe("hasProperty") {
21
+ it("returns false when the property is missing") {
22
+ expect(object?.hasProperty(key)) == false
23
+ }
24
+
25
+ it("returns true when the property exists") {
26
+ object?.setProperty(key, value: value1)
27
+ expect(object?.hasProperty(key)) == true
28
+ }
29
+
30
+ it("returns true when the property is explicitly set to undefined") {
31
+ object?.setProperty(key, value: nil)
32
+ expect(object?.hasProperty(key)) == true
33
+ expect(object?.getProperty(key).isUndefined()) == true
34
+ }
35
+ }
36
+
37
+ describe("getProperty") {
38
+ it("returns correct value") {
39
+ object?.setProperty(key, value: value1)
40
+ expect(try! object?.getProperty(key).asString()) == value1
41
+ }
42
+
43
+ it("returns undefined") {
44
+ expect(object?.getProperty("bar").isUndefined()) == true
45
+ }
46
+ }
47
+
48
+ describe("setProperty") {
49
+ it("sets") {
50
+ object?.setProperty(key, value: value1)
51
+ expect(try! object?.getProperty(key).asString()) == value1
52
+ }
53
+
54
+ it("overrides") {
55
+ object?.setProperty(key, value: value1)
56
+ object?.setProperty(key, value: value2)
57
+ expect(try! object?.getProperty(key).asString()) == value2
58
+ }
59
+
60
+ it("unsets") {
61
+ object?.setProperty(key, value: nil)
62
+ expect(object?.getProperty(key).isUndefined()) == true
63
+ }
64
+ }
65
+
66
+ describe("defineProperty") {
67
+ it("defines non-enumerable property") {
68
+ object?.defineProperty(key, value: value1, options: [])
69
+ expect(try! object?.getProperty(key).asString()) == value1
70
+ expect(object?.getPropertyNames()).notTo(contain(key))
71
+ }
72
+
73
+ it("defines enumerable property") {
74
+ // When the property is enumerable, it is listed in the property names
75
+ object?.defineProperty(key, value: value1, options: .enumerable)
76
+ expect(try! object?.getProperty(key).asString()) == value1
77
+ expect(object?.getPropertyNames()).to(contain(key))
78
+ }
79
+
80
+ it("defines configurable property") {
81
+ // Configurable allows to redefine the property
82
+ object?.defineProperty(key, value: value1, options: .configurable)
83
+ expect(try! object?.getProperty(key).asString()) == value1
84
+ object?.defineProperty(key, value: value2, options: [])
85
+ expect(try! object?.getProperty(key).asString()) == value2
86
+ }
87
+
88
+ it("defines writable property") {
89
+ // Writable allows changing the property
90
+ object?.defineProperty(key, value: value1, options: .writable)
91
+ expect(try! object?.getProperty(key).asString()) == value1
92
+ object?.setProperty(key, value: value2)
93
+ expect(try! object?.getProperty(key).asString()) == value2
94
+ }
95
+ }
96
+ }
97
+ }
@@ -0,0 +1,94 @@
1
+ import ExpoModulesTestCore
2
+
3
+ @testable import ExpoModulesCore
4
+
5
+ class JavaScriptRuntimeSpec: ExpoSpec {
6
+ override func spec() {
7
+ let runtime = JavaScriptRuntime()
8
+
9
+ it("has global object accessible") {
10
+ expect(runtime.global) !== nil
11
+ }
12
+
13
+ describe("eval") {
14
+ it("returns undefined") {
15
+ let undefined = try! runtime.eval("undefined")
16
+ expect(undefined.isUndefined()) == true
17
+ expect(undefined.kind) == .undefined
18
+ expect(undefined.isNull()) == false
19
+ expect(undefined.getRaw()).to(beNil())
20
+ }
21
+
22
+ it("returns null") {
23
+ let null = try! runtime.eval("null")
24
+ expect(null.isNull()) == true
25
+ expect(null.kind) == .null
26
+ expect(null.getRaw()).to(beNil())
27
+ }
28
+
29
+ it("returns bool") {
30
+ let boolTrue = try! runtime.eval("true")
31
+ let boolFalse = try! runtime.eval("false")
32
+ expect(boolTrue.isBool()) == true
33
+ expect(boolFalse.isBool()) == true
34
+ expect(boolTrue.kind) == .bool
35
+ expect(boolFalse.kind) == .bool
36
+ expect(try! boolTrue.asBool()) == true
37
+ expect(try! boolFalse.asBool()) == false
38
+ }
39
+
40
+ it("returns number") {
41
+ let number = try! runtime.eval("1.23")
42
+ expect(number.isNumber()) == true
43
+ expect(number.kind) == .number
44
+ expect(try! number.asInt()) == 1
45
+ expect(try! number.asDouble()) == 1.23
46
+ }
47
+
48
+ it("returns string") {
49
+ let string = try! runtime.eval("'foobar'")
50
+ expect(string.isString()) == true
51
+ expect(string.kind) == .string
52
+ expect(try! string.asString()) == "foobar"
53
+ }
54
+
55
+ it("returns array") {
56
+ let array = try! runtime.eval("(['foo', 'bar'])")
57
+ expect(array.isObject()) == true
58
+ expect(array.kind) == .object
59
+ expect(try! array.asArray().map { try $0?.asString() }) == ["foo", "bar"]
60
+ }
61
+
62
+ it("returns dict") {
63
+ let dict1 = try! runtime.eval("({ 'foo': 123 })")
64
+ let dict2 = try! runtime.eval("({ 'foo': 'bar' })")
65
+ expect(dict1.isObject()) == true
66
+ expect(dict2.isObject()) == true
67
+ expect(dict1.kind) == .object
68
+ expect(dict2.kind) == .object
69
+ expect(try! dict1.asDict() as? [String: Int]) == ["foo": 123]
70
+ expect(try! dict2.asDict() as? [String: String]) == ["foo": "bar"]
71
+ }
72
+
73
+ it("returns function") {
74
+ let function = try! runtime.eval("(function() {})")
75
+ expect(function.isObject()) == true
76
+ expect(function.isFunction()) == true
77
+ expect(function.kind) == .function
78
+ }
79
+
80
+ it("returns symbol") {
81
+ let symbol = try! runtime.eval("Symbol('foo')")
82
+ expect(symbol.isSymbol()) == true
83
+ expect(symbol.kind) == .symbol
84
+ }
85
+
86
+ it("throws evaluation exception") {
87
+ expect({ try runtime.eval("foo") }).to(throwError { error in
88
+ expect(error).to(beAKindOf(JavaScriptEvalException.self))
89
+ expect((error as! JavaScriptEvalException).reason).to(contain("Can't find variable: foo"))
90
+ })
91
+ }
92
+ }
93
+ }
94
+ }
@@ -1,5 +1,4 @@
1
- import Quick
2
- import Nimble
1
+ import ExpoModulesTestCore
3
2
 
4
3
  @testable import ExpoModulesCore
5
4
 
@@ -11,7 +10,7 @@ import Nimble
11
10
 
12
11
  NOTE: Each test registers the module because only registered modules can capture events.
13
12
  */
14
- class ModuleEventListenersSpec: QuickSpec {
13
+ class ModuleEventListenersSpec: ExpoSpec {
15
14
  override func spec() {
16
15
  var appContext: AppContext!
17
16
 
@@ -19,22 +18,22 @@ class ModuleEventListenersSpec: QuickSpec {
19
18
  appContext = AppContext()
20
19
  }
21
20
 
22
- it("calls onCreate once the module instance is created") {
21
+ it("calls OnCreate once the module instance is created") {
23
22
  waitUntil { done in
24
23
  _ = mockModuleHolder(appContext) {
25
- $0.onCreate {
24
+ OnCreate {
26
25
  done()
27
26
  }
28
27
  }
29
28
  }
30
29
  }
31
30
 
32
- it("calls onDestroy once the module is about to be deallocated") {
31
+ it("calls OnDestroy once the module is about to be deallocated") {
33
32
  waitUntil { done in
34
33
  let moduleName = "mockedModule"
35
34
  let holder = mockModuleHolder(appContext) {
36
- $0.name(moduleName)
37
- $0.onDestroy {
35
+ Name(moduleName)
36
+ OnDestroy {
38
37
  done()
39
38
  }
40
39
  }
@@ -45,10 +44,10 @@ class ModuleEventListenersSpec: QuickSpec {
45
44
  }
46
45
  }
47
46
 
48
- it("calls onAppContextDestroys once the context destroys") {
47
+ it("calls OnAppContextDestroys once the context destroys") {
49
48
  waitUntil { done in
50
49
  let holder = mockModuleHolder(appContext) {
51
- $0.onAppContextDestroys {
50
+ OnAppContextDestroys {
52
51
  done()
53
52
  }
54
53
  }
@@ -70,10 +69,10 @@ class ModuleEventListenersSpec: QuickSpec {
70
69
  }
71
70
  }
72
71
 
73
- it("calls onAppEntersForeground when system's willEnterForegroundNotification is sent") {
72
+ it("calls OnAppEntersForeground when system's willEnterForegroundNotification is sent") {
74
73
  waitUntil { done in
75
74
  let holder = mockModuleHolder(appContext) {
76
- $0.onAppEntersForeground {
75
+ OnAppEntersForeground {
77
76
  done()
78
77
  }
79
78
  }
@@ -82,10 +81,10 @@ class ModuleEventListenersSpec: QuickSpec {
82
81
  }
83
82
  }
84
83
 
85
- it("calls onAppBecomesActive when system's didBecomeActiveNotification is sent") {
84
+ it("calls OnAppBecomesActive when system's didBecomeActiveNotification is sent") {
86
85
  waitUntil { done in
87
86
  let holder = mockModuleHolder(appContext) {
88
- $0.onAppBecomesActive {
87
+ OnAppBecomesActive {
89
88
  done()
90
89
  }
91
90
  }
@@ -94,10 +93,10 @@ class ModuleEventListenersSpec: QuickSpec {
94
93
  }
95
94
  }
96
95
 
97
- it("calls onAppEntersBackground when system's didEnterBackgroundNotification is sent") {
96
+ it("calls OnAppEntersBackground when system's didEnterBackgroundNotification is sent") {
98
97
  waitUntil { done in
99
98
  let holder = mockModuleHolder(appContext) {
100
- $0.onAppEntersBackground {
99
+ OnAppEntersBackground {
101
100
  done()
102
101
  }
103
102
  }
@@ -1,9 +1,8 @@
1
- import Quick
2
- import Nimble
1
+ import ExpoModulesTestCore
3
2
 
4
3
  @testable import ExpoModulesCore
5
4
 
6
- class ModuleRegistrySpec: QuickSpec {
5
+ class ModuleRegistrySpec: ExpoSpec {
7
6
  override func spec() {
8
7
  let appContext = AppContext()
9
8
 
@@ -1,9 +1,8 @@
1
- import Quick
2
- import Nimble
1
+ import ExpoModulesTestCore
3
2
 
4
3
  @testable import ExpoModulesCore
5
4
 
6
- class RecordSpec: QuickSpec {
5
+ class RecordSpec: ExpoSpec {
7
6
  override func spec() {
8
7
  it("initializes with empty dictionary") {
9
8
  struct TestRecord: Record { }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-modules-core",
3
- "version": "0.7.0",
3
+ "version": "0.9.1",
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": "^2.0.0"
44
44
  },
45
- "gitHead": "e1ff1a3d6bc62f374e6947a5e81428a1bb7cfa34"
45
+ "gitHead": "b9d655c1bed682ad8919e071dd923968773f05b5"
46
46
  }
@@ -1,11 +1,6 @@
1
1
  import { NativeModules } from 'react-native';
2
2
 
3
- import { ProxyNativeModule, TurboNativeModuleProxy } from './NativeModulesProxy.types';
4
-
5
- // `ExpoModulesProxy` is not declared in TypeScript yet. It's installed via JSI.
6
- declare namespace global {
7
- const ExpoModulesProxy: TurboNativeModuleProxy;
8
- }
3
+ import { ProxyNativeModule } from './NativeModulesProxy.types';
9
4
 
10
5
  const NativeProxy = NativeModules.NativeUnimoduleProxy;
11
6
  const modulesConstantsKey = 'modulesConstants';
@@ -13,16 +8,6 @@ const exportedMethodsKey = 'exportedMethods';
13
8
 
14
9
  const NativeModulesProxy: { [moduleName: string]: ProxyNativeModule } = {};
15
10
 
16
- // Keep it opt-in for now. It's too risky without proper and thorough testing.
17
- let canUseExpoTurboModules = false;
18
-
19
- /**
20
- * Sets whether to use a TurboModule version of the proxy.
21
- */
22
- export function useExpoTurboModules(state: boolean = true) {
23
- canUseExpoTurboModules = state;
24
- }
25
-
26
11
  if (NativeProxy) {
27
12
  Object.keys(NativeProxy[exportedMethodsKey]).forEach((moduleName) => {
28
13
  NativeModulesProxy[moduleName] = NativeProxy[modulesConstantsKey][moduleName] || {};
@@ -38,12 +23,7 @@ if (NativeProxy) {
38
23
  )
39
24
  );
40
25
  }
41
-
42
- if (canUseExpoTurboModules && global.ExpoModulesProxy) {
43
- return global.ExpoModulesProxy.callMethodAsync(moduleName, methodInfo.name, args);
44
- } else {
45
- return NativeProxy.callMethod(moduleName, key, args);
46
- }
26
+ return NativeProxy.callMethod(moduleName, key, args);
47
27
  };
48
28
  });
49
29
 
@@ -3,11 +3,3 @@ export type ProxyNativeModule = {
3
3
  addListener: (eventName: string) => void;
4
4
  removeListeners: (count: number) => void;
5
5
  };
6
-
7
- export type TurboNativeModuleProxy = {
8
- callMethodAsync: <ReturnType>(
9
- moduleName: string,
10
- methodName: string,
11
- args: any[]
12
- ) => Promise<ReturnType>;
13
- };
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { NativeModules, UIManager, ViewPropTypes, requireNativeComponent } from 'react-native';
2
+ import { NativeModules, requireNativeComponent } from 'react-native';
3
3
 
4
4
  // To make the transition from React Native's `requireNativeComponent` to Expo's
5
5
  // `requireNativeViewManager` as easy as possible, `requireNativeViewManager` is a drop-in
@@ -10,11 +10,6 @@ import { NativeModules, UIManager, ViewPropTypes, requireNativeComponent } from
10
10
  // passed to React Native's View (ex: style, testID) and custom view props, which are passed to the
11
11
  // adapter view component in a prop called `proxiedProperties`.
12
12
 
13
- // NOTE: React Native is moving away from runtime PropTypes and may remove ViewPropTypes, in which
14
- // case we will need another way to separate standard React Native view props from other props,
15
- // which we proxy through the adapter
16
- const ViewPropTypesKeys = Object.keys(ViewPropTypes);
17
-
18
13
  type NativeExpoComponentProps = {
19
14
  proxiedProperties: object;
20
15
  };
@@ -23,14 +18,14 @@ type NativeExpoComponentProps = {
23
18
  * A drop-in replacement for `requireNativeComponent`.
24
19
  */
25
20
  export function requireNativeViewManager<P = any>(viewName: string): React.ComponentType<P> {
26
- if (__DEV__) {
27
- const { NativeUnimoduleProxy } = NativeModules;
28
- if (!NativeUnimoduleProxy.viewManagersNames.includes(viewName)) {
29
- const exportedViewManagerNames = NativeUnimoduleProxy.viewManagersNames.join(', ');
30
- console.warn(
31
- `The native view manager required by name (${viewName}) from NativeViewManagerAdapter isn't exported by expo-modules-core. Views of this type may not render correctly. Exported view managers: [${exportedViewManagerNames}].`
32
- );
33
- }
21
+ const { viewManagersMetadata } = NativeModules.NativeUnimoduleProxy;
22
+ const viewManagerConfig = viewManagersMetadata?.[viewName];
23
+
24
+ if (__DEV__ && !viewManagerConfig) {
25
+ const exportedViewManagerNames = Object.keys(viewManagersMetadata).join(', ');
26
+ console.warn(
27
+ `The native view manager required by name (${viewName}) from NativeViewManagerAdapter isn't exported by expo-modules-core. Views of this type may not render correctly. Exported view managers: [${exportedViewManagerNames}].`
28
+ );
34
29
  }
35
30
 
36
31
  // Set up the React Native native component, which is an adapter to the universal module's view
@@ -38,23 +33,12 @@ export function requireNativeViewManager<P = any>(viewName: string): React.Compo
38
33
  const reactNativeViewName = `ViewManagerAdapter_${viewName}`;
39
34
  const ReactNativeComponent =
40
35
  requireNativeComponent<NativeExpoComponentProps>(reactNativeViewName);
41
- const reactNativeUIConfiguration = (UIManager.getViewManagerConfig
42
- ? UIManager.getViewManagerConfig(reactNativeViewName)
43
- : UIManager[reactNativeViewName]) || {
44
- NativeProps: {},
45
- directEventTypes: {},
46
- };
47
- const reactNativeComponentPropNames = [
48
- 'children',
49
- ...ViewPropTypesKeys,
50
- ...Object.keys(reactNativeUIConfiguration.NativeProps),
51
- ...Object.keys(reactNativeUIConfiguration.directEventTypes),
52
- ];
36
+ const proxiedPropsNames = viewManagerConfig?.propsNames ?? [];
53
37
 
54
38
  // Define a component for universal-module authors to access their native view manager
55
39
  function NativeComponentAdapter(props, ref) {
56
- const nativeProps = pick(props, reactNativeComponentPropNames);
57
- const proxiedProps = omit(props, reactNativeComponentPropNames);
40
+ const nativeProps = omit(props, proxiedPropsNames);
41
+ const proxiedProps = pick(props, proxiedPropsNames);
58
42
  return <ReactNativeComponent {...nativeProps} proxiedProperties={proxiedProps} ref={ref} />;
59
43
  }
60
44
  NativeComponentAdapter.displayName = `Adapter<${viewName}>`;
@@ -1,2 +1,2 @@
1
- import { NativeModulesProxy } from '..';
1
+ import NativeModulesProxy from '../NativeModulesProxy';
2
2
  export default NativeModulesProxy.ExpoModulesCoreErrorManager;
@@ -1,26 +0,0 @@
1
- package expo.modules.kotlin.events
2
-
3
- import android.os.Bundle
4
- import expo.modules.core.interfaces.services.EventEmitter
5
- import expo.modules.kotlin.ModuleHolder
6
-
7
- /**
8
- * In Swift, we check if the event is supported. Otherwise, we can't send such event through the bridge.
9
- * However, in Kotlin this is unnecessary, but to make our API consistent, we added similar check.
10
- * But because of that, we had to create a wrapper for EventEmitter.
11
- */
12
- class KEventEmitterWrapper(
13
- private val moduleHolder: ModuleHolder,
14
- private val legacyEventEmitter: EventEmitter
15
- ) : EventEmitter by legacyEventEmitter {
16
- override fun emit(eventName: String, eventBody: Bundle?) {
17
- require(
18
- moduleHolder
19
- .definition
20
- .eventsDefinition
21
- ?.names
22
- ?.contains(eventName) == true
23
- ) { "Unsupported event: $eventName." }
24
- legacyEventEmitter.emit(eventName, eventBody)
25
- }
26
- }
@@ -1,14 +0,0 @@
1
- package expo.modules.kotlin.methods
2
-
3
- import expo.modules.kotlin.Promise
4
- import expo.modules.kotlin.types.AnyType
5
-
6
- class Method(
7
- name: String,
8
- argsType: Array<AnyType>,
9
- private val body: (args: Array<out Any?>) -> Any?
10
- ) : AnyMethod(name, argsType) {
11
- override fun callImplementation(args: Array<out Any?>, promise: Promise) {
12
- promise.resolve(body(args))
13
- }
14
- }
@@ -1,15 +0,0 @@
1
- package expo.modules.kotlin.methods
2
-
3
- import expo.modules.kotlin.Promise
4
- import expo.modules.kotlin.types.AnyType
5
-
6
- class PromiseMethod(
7
- name: String,
8
- argsType: Array<AnyType>,
9
- private val body: (args: Array<out Any?>, promise: Promise) -> Unit
10
- ) : AnyMethod(name, argsType) {
11
-
12
- override fun callImplementation(args: Array<out Any?>, promise: Promise) {
13
- body(args, promise)
14
- }
15
- }