expo-modules-core 0.6.4 → 0.7.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.
Files changed (159) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +1 -1
  3. package/android/build.gradle +5 -5
  4. package/android/src/main/java/expo/modules/kotlin/AppContext.kt +11 -1
  5. package/android/src/main/java/expo/modules/kotlin/DynamicExtenstions.kt +5 -3
  6. package/android/src/main/java/expo/modules/kotlin/KPromiseWrapper.kt +8 -2
  7. package/android/src/main/java/expo/modules/kotlin/KotlinInteropModuleRegistry.kt +13 -4
  8. package/android/src/main/java/expo/modules/kotlin/ModuleHolder.kt +7 -6
  9. package/android/src/main/java/expo/modules/kotlin/ModuleRegistry.kt +6 -1
  10. package/android/src/main/java/expo/modules/kotlin/Promise.kt +1 -1
  11. package/android/src/main/java/expo/modules/kotlin/callbacks/Callback.kt +5 -0
  12. package/android/src/main/java/expo/modules/kotlin/callbacks/ViewCallback.kt +28 -0
  13. package/android/src/main/java/expo/modules/kotlin/callbacks/ViewCallbackDelegate.kt +27 -0
  14. package/android/src/main/java/expo/modules/kotlin/defaultmodules/ErrorManagerModule.kt +25 -0
  15. package/android/src/main/java/expo/modules/kotlin/exception/CodedException.kt +68 -8
  16. package/android/src/main/java/expo/modules/kotlin/exception/ExceptionDecorator.kt +11 -0
  17. package/android/src/main/java/expo/modules/kotlin/methods/AnyMethod.kt +13 -14
  18. package/android/src/main/java/expo/modules/kotlin/modules/DefinitionMarker.kt +4 -0
  19. package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +3 -2
  20. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +44 -4
  21. package/android/src/main/java/expo/modules/kotlin/records/Record.kt +39 -0
  22. package/android/src/main/java/expo/modules/kotlin/records/RecordTypeConverter.kt +14 -7
  23. package/android/src/main/java/expo/modules/kotlin/types/ArrayTypeConverter.kt +11 -5
  24. package/android/src/main/java/expo/modules/kotlin/types/ListTypeConverter.kt +10 -4
  25. package/android/src/main/java/expo/modules/kotlin/types/MapTypeConverter.kt +12 -6
  26. package/android/src/main/java/expo/modules/kotlin/types/PairTypeConverter.kt +29 -13
  27. package/android/src/main/java/expo/modules/kotlin/types/TypeConverter.kt +2 -1
  28. package/android/src/main/java/expo/modules/kotlin/views/CallbacksDefinition.kt +3 -0
  29. package/android/src/main/java/expo/modules/kotlin/views/GroupViewManagerWrapper.kt +22 -0
  30. package/android/src/main/java/expo/modules/kotlin/views/SimpleViewManagerWrapper.kt +22 -0
  31. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinition.kt +27 -2
  32. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinitionBuilder.kt +29 -1
  33. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerWrapperDelegate.kt +59 -2
  34. package/build/EventEmitter.d.ts +1 -0
  35. package/build/EventEmitter.d.ts.map +1 -0
  36. package/build/NativeModulesProxy.d.ts +1 -0
  37. package/build/NativeModulesProxy.d.ts.map +1 -0
  38. package/build/NativeModulesProxy.native.d.ts +1 -0
  39. package/build/NativeModulesProxy.native.d.ts.map +1 -0
  40. package/build/NativeModulesProxy.types.d.ts +1 -0
  41. package/build/NativeModulesProxy.types.d.ts.map +1 -0
  42. package/build/NativeViewManagerAdapter.d.ts +1 -0
  43. package/build/NativeViewManagerAdapter.d.ts.map +1 -0
  44. package/build/NativeViewManagerAdapter.native.d.ts +1 -0
  45. package/build/NativeViewManagerAdapter.native.d.ts.map +1 -0
  46. package/build/PermissionsHook.d.ts +1 -0
  47. package/build/PermissionsHook.d.ts.map +1 -0
  48. package/build/PermissionsInterface.d.ts +1 -0
  49. package/build/PermissionsInterface.d.ts.map +1 -0
  50. package/build/Platform.d.ts +1 -0
  51. package/build/Platform.d.ts.map +1 -0
  52. package/build/SyntheticPlatformEmitter.d.ts +1 -0
  53. package/build/SyntheticPlatformEmitter.d.ts.map +1 -0
  54. package/build/SyntheticPlatformEmitter.web.d.ts +1 -0
  55. package/build/SyntheticPlatformEmitter.web.d.ts.map +1 -0
  56. package/build/deprecate.d.ts +1 -0
  57. package/build/deprecate.d.ts.map +1 -0
  58. package/build/environment/browser.d.ts +1 -0
  59. package/build/environment/browser.d.ts.map +1 -0
  60. package/build/environment/browser.web.d.ts +1 -0
  61. package/build/environment/browser.web.d.ts.map +1 -0
  62. package/build/errors/CodedError.d.ts +1 -0
  63. package/build/errors/CodedError.d.ts.map +1 -0
  64. package/build/errors/UnavailabilityError.d.ts +1 -0
  65. package/build/errors/UnavailabilityError.d.ts.map +1 -0
  66. package/build/index.d.ts +3 -0
  67. package/build/index.d.ts.map +1 -0
  68. package/build/index.js +2 -0
  69. package/build/index.js.map +1 -1
  70. package/build/requireNativeModule.d.ts +16 -0
  71. package/build/requireNativeModule.d.ts.map +1 -0
  72. package/build/requireNativeModule.js +18 -0
  73. package/build/requireNativeModule.js.map +1 -0
  74. package/build/sweet/NativeErrorManager.d.ts +3 -0
  75. package/build/sweet/NativeErrorManager.d.ts.map +1 -0
  76. package/build/sweet/NativeErrorManager.js +3 -0
  77. package/build/sweet/NativeErrorManager.js.map +1 -0
  78. package/build/sweet/setUpErrorManager.fx.d.ts +2 -0
  79. package/build/sweet/setUpErrorManager.fx.d.ts.map +1 -0
  80. package/build/sweet/setUpErrorManager.fx.js +11 -0
  81. package/build/sweet/setUpErrorManager.fx.js.map +1 -0
  82. package/ios/AppDelegates/ExpoAppDelegate.swift +18 -10
  83. package/ios/JSI/ExpoModulesHostObject.h +33 -0
  84. package/ios/JSI/ExpoModulesHostObject.mm +40 -0
  85. package/ios/JSI/ExpoModulesProxySpec.h +4 -0
  86. package/ios/JSI/ExpoModulesProxySpec.mm +1 -3
  87. package/ios/JSI/JSIConversions.h +2 -0
  88. package/ios/JSI/JSIConversions.mm +9 -0
  89. package/ios/JSI/JSIInstaller.h +10 -0
  90. package/ios/JSI/JSIInstaller.mm +14 -2
  91. package/ios/JSI/JavaScriptObject.h +60 -0
  92. package/ios/JSI/JavaScriptObject.mm +93 -0
  93. package/ios/JSI/JavaScriptRuntime.h +54 -0
  94. package/ios/JSI/JavaScriptRuntime.mm +102 -0
  95. package/ios/ModuleRegistryAdapter/EXModuleRegistryAdapter.m +2 -12
  96. package/ios/NativeModulesProxy/EXComponentDataCompatibleWrapper.h +16 -0
  97. package/ios/NativeModulesProxy/EXComponentDataCompatibleWrapper.m +28 -0
  98. package/ios/NativeModulesProxy/EXNativeModulesProxy.mm +90 -66
  99. package/ios/RCTComponentData+Privates.h +12 -0
  100. package/ios/ReactDelegates/ExpoReactDelegate.swift +2 -2
  101. package/ios/ReactDelegates/ExpoReactDelegateHandler.swift +3 -3
  102. package/ios/ReactDelegates/ModulePriorities.swift +1 -1
  103. package/ios/Swift/AppContext.swift +38 -4
  104. package/ios/Swift/Arguments/ArgumentType.swift +4 -0
  105. package/ios/Swift/Arguments/Convertibles.swift +13 -13
  106. package/ios/Swift/Arguments/Types/EnumArgumentType.swift +11 -17
  107. package/ios/Swift/Arguments/Types/PromiseArgumentType.swift +1 -1
  108. package/ios/Swift/Arguments/Types/RawArgumentType.swift +2 -2
  109. package/ios/Swift/Conversions.swift +51 -56
  110. package/ios/Swift/EventListener.swift +8 -10
  111. package/ios/Swift/Events/Callback.swift +66 -0
  112. package/ios/Swift/Events/Event.swift +43 -0
  113. package/ios/Swift/Exceptions/ChainableException.swift +51 -0
  114. package/ios/Swift/{CodedError.swift → Exceptions/CodedError.swift} +1 -12
  115. package/ios/Swift/Exceptions/Exception.swift +62 -0
  116. package/ios/Swift/Exceptions/ExceptionOrigin.swift +28 -0
  117. package/ios/Swift/Exceptions/GenericException.swift +20 -0
  118. package/ios/Swift/Exceptions/UnexpectedException.swift +16 -0
  119. package/ios/Swift/Functions/AnyFunction.swift +11 -1
  120. package/ios/Swift/Functions/ConcreteFunction.swift +37 -16
  121. package/ios/Swift/JavaScriptUtils.swift +43 -0
  122. package/ios/Swift/ModuleHolder.swift +53 -14
  123. package/ios/Swift/ModuleRegistry.swift +4 -1
  124. package/ios/Swift/Modules/AnyModule.swift +0 -1
  125. package/ios/Swift/Modules/ModuleDefinition.swift +4 -13
  126. package/ios/Swift/Modules/ModuleDefinitionBuilder.swift +0 -1
  127. package/ios/Swift/Modules/ModuleDefinitionComponents.swift +0 -188
  128. package/ios/Swift/ModulesProvider.swift +0 -1
  129. package/ios/Swift/Objects/ObjectDefinition.swift +30 -0
  130. package/ios/Swift/Objects/ObjectDefinitionComponents.swift +208 -0
  131. package/ios/Swift/Promise.swift +8 -3
  132. package/ios/Swift/Records/AnyField.swift +7 -0
  133. package/ios/Swift/Records/Field.swift +24 -19
  134. package/ios/Swift/Records/FieldOption.swift +1 -1
  135. package/ios/Swift/Records/Record.swift +12 -4
  136. package/ios/Swift/SwiftInteropBridge.swift +39 -10
  137. package/ios/Swift/Views/AnyViewProp.swift +1 -1
  138. package/ios/Swift/Views/ComponentData.swift +95 -0
  139. package/ios/Swift/Views/ConcreteViewProp.swift +6 -8
  140. package/ios/Swift/Views/ViewFactory.swift +1 -1
  141. package/ios/Swift/Views/ViewManagerDefinition.swift +23 -2
  142. package/ios/Swift/Views/ViewManagerDefinitionBuilder.swift +0 -1
  143. package/ios/Swift/Views/ViewManagerDefinitionComponents.swift +26 -0
  144. package/ios/Swift/Views/ViewModuleWrapper.swift +5 -2
  145. package/ios/Tests/ArgumentTypeSpec.swift +3 -4
  146. package/ios/Tests/ConstantsSpec.swift +4 -4
  147. package/ios/Tests/ConvertiblesSpec.swift +33 -33
  148. package/ios/Tests/ExceptionsSpec.swift +112 -0
  149. package/ios/Tests/FunctionSpec.swift +20 -22
  150. package/ios/Tests/FunctionWithConvertiblesSpec.swift +2 -2
  151. package/ios/Tests/Mocks/ModuleMocks.swift +1 -1
  152. package/ios/Tests/Mocks/ModulesProviderMock.swift +0 -1
  153. package/ios/Tests/ModuleEventListenersSpec.swift +1 -1
  154. package/ios/Tests/RecordSpec.swift +7 -17
  155. package/package.json +3 -3
  156. package/src/index.ts +4 -0
  157. package/src/requireNativeModule.ts +29 -0
  158. package/src/sweet/NativeErrorManager.ts +2 -0
  159. package/src/sweet/setUpErrorManager.fx.ts +12 -0
@@ -0,0 +1,26 @@
1
+ /// Here we implement the components exclusive for view managers.
2
+
3
+ // MARK: View factory
4
+
5
+ /**
6
+ Defines the factory creating a native view when the module is used as a view.
7
+ */
8
+ public func view(_ closure: @escaping () -> UIView) -> ViewManagerDefinitionComponent {
9
+ return ViewFactory(closure)
10
+ }
11
+
12
+ // MARK: Props
13
+
14
+ /**
15
+ Creates a view prop that defines its name and setter.
16
+ */
17
+ public func prop<ViewType: UIView, PropType: AnyArgument>(
18
+ _ name: String,
19
+ _ setter: @escaping (ViewType, PropType) -> Void
20
+ ) -> ViewManagerDefinitionComponent {
21
+ return ConcreteViewProp(
22
+ name: name,
23
+ propType: ArgumentType(PropType.self),
24
+ setter: setter
25
+ )
26
+ }
@@ -93,7 +93,7 @@ public final class ViewModuleWrapper: RCTViewManager, DynamicModuleWrapperProtoc
93
93
  */
94
94
  @objc
95
95
  public class func propConfig_proxiedProperties() -> [String] {
96
- return ["NSDictionary", "__custom__"];
96
+ return ["NSDictionary", "__custom__"]
97
97
  }
98
98
 
99
99
  /**
@@ -126,7 +126,7 @@ public final class ViewModuleWrapper: RCTViewManager, DynamicModuleWrapperProtoc
126
126
  let prefixedViewName = "ViewManagerAdapter_\(module.name())"
127
127
 
128
128
  return prefixedViewName.withCString { viewNamePtr in
129
- // Create a new meta class that inherits from `ViewModuleWrapper`. The class name passed here, doesn't work for Swift classes,
129
+ // Create a new class that inherits from `ViewModuleWrapper`. The class name passed here, doesn't work for Swift classes,
130
130
  // so we also have to override `moduleName` class method.
131
131
  let wrapperClass: AnyClass? = objc_allocateClassPair(ViewModuleWrapper.self, viewNamePtr, 0)
132
132
 
@@ -141,3 +141,6 @@ public final class ViewModuleWrapper: RCTViewManager, DynamicModuleWrapperProtoc
141
141
  }
142
142
  }
143
143
  }
144
+
145
+ // The direct event implementation can be cached and lazy-loaded (global and static variables are lazy by default in Swift).
146
+ let directEventBlockImplementation = imp_implementationWithBlock({ ["RCTDirectEventBlock"] } as @convention(block) () -> [String])
@@ -7,7 +7,6 @@ import Nimble
7
7
 
8
8
  class ArgumentTypeSpec: QuickSpec {
9
9
  override func spec() {
10
-
11
10
  it("casts primitives") {
12
11
  let type = ArgumentType(Int.self)
13
12
  let value = 123
@@ -34,7 +33,7 @@ class ArgumentTypeSpec: QuickSpec {
34
33
  let value: Double? = nil
35
34
  let anyValue = value as Any
36
35
 
37
- expect { try type.cast(anyValue) }.to(throwError(errorType: Conversions.NullCastError<Double>.self))
36
+ expect { try type.cast(anyValue) }.to(throwError(errorType: Conversions.NullCastException<Double>.self))
38
37
  }
39
38
 
40
39
  it("casts arrays") {
@@ -104,7 +103,7 @@ class ArgumentTypeSpec: QuickSpec {
104
103
 
105
104
  // "841" is not a raw value of any `IntTestEnum` case
106
105
  expect { try type.cast("string instead of int") }.to(throwError {
107
- expect($0).to(beAKindOf(EnumCastingError.self))
106
+ expect($0).to(beAKindOf(EnumCastingException.self))
108
107
  })
109
108
  }
110
109
 
@@ -113,7 +112,7 @@ class ArgumentTypeSpec: QuickSpec {
113
112
 
114
113
  // "841" is not a raw value of any `IntTestEnum` case
115
114
  expect { try type.cast(841) }.to(throwError {
116
- expect($0).to(beAKindOf(EnumNoSuchValueError.self))
115
+ expect($0).to(beAKindOf(EnumNoSuchValueException.self))
117
116
  })
118
117
  }
119
118
 
@@ -9,7 +9,7 @@ class ConstantsSpec: QuickSpec {
9
9
 
10
10
  it("takes closure resolving to dictionary") {
11
11
  let holder = mockModuleHolder(appContext) {
12
- $0.constants {
12
+ constants {
13
13
  return ["test": 123]
14
14
  }
15
15
  }
@@ -18,15 +18,15 @@ class ConstantsSpec: QuickSpec {
18
18
 
19
19
  it("takes the dictionary") {
20
20
  let holder = mockModuleHolder(appContext) {
21
- $0.constants(["test": 123])
21
+ constants(["test": 123])
22
22
  }
23
23
  expect(holder.getConstants()["test"] as? Int) == 123
24
24
  }
25
25
 
26
26
  it("merges multiple constants definitions") {
27
27
  let holder = mockModuleHolder(appContext) {
28
- $0.constants(["test": 456, "test2": 789])
29
- $0.constants(["test": 123])
28
+ constants(["test": 456, "test2": 789])
29
+ constants(["test": 123])
30
30
  }
31
31
  let consts = holder.getConstants()
32
32
  expect(consts["test"] as? Int) == 123
@@ -37,7 +37,7 @@ class ConvertiblesSpec: QuickSpec {
37
37
 
38
38
  it("throws when no string") {
39
39
  expect { try URL.convert(from: 29.5) }.to(
40
- throwError(errorType: Conversions.ConvertingError<URL>.self)
40
+ throwError(errorType: Conversions.ConvertingException<URL>.self)
41
41
  )
42
42
  }
43
43
  }
@@ -61,22 +61,22 @@ class ConvertiblesSpec: QuickSpec {
61
61
  }
62
62
 
63
63
  it("throws when array size is unexpected") { // different than two
64
- expect { try CGPoint.convert(from: []) }.to(throwError(errorType: Conversions.ConvertingError<CGPoint>.self))
65
- expect { try CGPoint.convert(from: [x]) }.to(throwError(errorType: Conversions.ConvertingError<CGPoint>.self))
66
- expect { try CGPoint.convert(from: [x, y, x]) }.to(throwError(errorType: Conversions.ConvertingError<CGPoint>.self))
64
+ expect { try CGPoint.convert(from: []) }.to(throwError(errorType: Conversions.ConvertingException<CGPoint>.self))
65
+ expect { try CGPoint.convert(from: [x]) }.to(throwError(errorType: Conversions.ConvertingException<CGPoint>.self))
66
+ expect { try CGPoint.convert(from: [x, y, x]) }.to(throwError(errorType: Conversions.ConvertingException<CGPoint>.self))
67
67
  }
68
68
 
69
69
  it("throws when dict is missing some keys") {
70
70
  expect { try CGPoint.convert(from: ["test": x]) }.to(throwError {
71
- expect($0).to(beAKindOf(Conversions.MissingKeysError<Double>.self))
72
- expect(($0 as! CodedError).description) == Conversions.MissingKeysError<Double>(keys: ["x", "y"]).description
71
+ expect($0).to(beAKindOf(Conversions.MissingKeysException<Double>.self))
72
+ expect(($0 as! CodedError).description) == Conversions.MissingKeysException<Double>(["x", "y"]).description
73
73
  })
74
74
  }
75
75
 
76
76
  it("throws when dict has uncastable keys") {
77
77
  expect { try CGPoint.convert(from: ["x": x, "y": "string"]) }.to(throwError {
78
- expect($0).to(beAKindOf(Conversions.CastingValuesError<Double>.self))
79
- expect(($0 as! CodedError).description) == Conversions.CastingValuesError<Double>(keys: ["y"]).description
78
+ expect($0).to(beAKindOf(Conversions.CastingValuesException<Double>.self))
79
+ expect(($0 as! CodedError).description) == Conversions.CastingValuesException<Double>(["y"]).description
80
80
  })
81
81
  }
82
82
  }
@@ -100,22 +100,22 @@ class ConvertiblesSpec: QuickSpec {
100
100
  }
101
101
 
102
102
  it("throws when array size is unexpected") { // different than two
103
- expect { try CGSize.convert(from: []) }.to(throwError(errorType: Conversions.ConvertingError<CGSize>.self))
104
- expect { try CGSize.convert(from: [width]) }.to(throwError(errorType: Conversions.ConvertingError<CGSize>.self))
105
- expect { try CGSize.convert(from: [width, height, width]) }.to(throwError(errorType: Conversions.ConvertingError<CGSize>.self))
103
+ expect { try CGSize.convert(from: []) }.to(throwError(errorType: Conversions.ConvertingException<CGSize>.self))
104
+ expect { try CGSize.convert(from: [width]) }.to(throwError(errorType: Conversions.ConvertingException<CGSize>.self))
105
+ expect { try CGSize.convert(from: [width, height, width]) }.to(throwError(errorType: Conversions.ConvertingException<CGSize>.self))
106
106
  }
107
107
 
108
108
  it("throws when dict is missing some keys") {
109
109
  expect { try CGSize.convert(from: ["width": width]) }.to(throwError {
110
- expect($0).to(beAKindOf(Conversions.MissingKeysError<Double>.self))
111
- expect(($0 as! CodedError).description) == Conversions.MissingKeysError<Double>(keys: ["height"]).description
110
+ expect($0).to(beAKindOf(Conversions.MissingKeysException<Double>.self))
111
+ expect(($0 as! CodedError).description) == Conversions.MissingKeysException<Double>(["height"]).description
112
112
  })
113
113
  }
114
114
 
115
115
  it("throws when dict has uncastable keys") {
116
116
  expect { try CGSize.convert(from: ["width": "test", "height": height]) }.to(throwError {
117
- expect($0).to(beAKindOf(Conversions.CastingValuesError<Double>.self))
118
- expect(($0 as! CodedError).description) == Conversions.CastingValuesError<Double>(keys: ["width"]).description
117
+ expect($0).to(beAKindOf(Conversions.CastingValuesException<Double>.self))
118
+ expect(($0 as! CodedError).description) == Conversions.CastingValuesException<Double>(["width"]).description
119
119
  })
120
120
  }
121
121
  }
@@ -139,22 +139,22 @@ class ConvertiblesSpec: QuickSpec {
139
139
  }
140
140
 
141
141
  it("throws when array size is unexpected") { // different than two
142
- expect { try CGVector.convert(from: []) }.to(throwError(errorType: Conversions.ConvertingError<CGVector>.self))
143
- expect { try CGVector.convert(from: [dx]) }.to(throwError(errorType: Conversions.ConvertingError<CGVector>.self))
144
- expect { try CGVector.convert(from: [dx, dy, dx]) }.to(throwError(errorType: Conversions.ConvertingError<CGVector>.self))
142
+ expect { try CGVector.convert(from: []) }.to(throwError(errorType: Conversions.ConvertingException<CGVector>.self))
143
+ expect { try CGVector.convert(from: [dx]) }.to(throwError(errorType: Conversions.ConvertingException<CGVector>.self))
144
+ expect { try CGVector.convert(from: [dx, dy, dx]) }.to(throwError(errorType: Conversions.ConvertingException<CGVector>.self))
145
145
  }
146
146
 
147
147
  it("throws when dict is missing some keys") {
148
148
  expect { try CGVector.convert(from: ["dx": dx]) }.to(throwError {
149
- expect($0).to(beAKindOf(Conversions.MissingKeysError<Double>.self))
150
- expect(($0 as! CodedError).description) == Conversions.MissingKeysError<Double>(keys: ["dy"]).description
149
+ expect($0).to(beAKindOf(Conversions.MissingKeysException<Double>.self))
150
+ expect(($0 as! CodedError).description) == Conversions.MissingKeysException<Double>(["dy"]).description
151
151
  })
152
152
  }
153
153
 
154
154
  it("throws when dict has uncastable keys") {
155
155
  expect { try CGVector.convert(from: ["dx": "dx", "dy": dy]) }.to(throwError {
156
- expect($0).to(beAKindOf(Conversions.CastingValuesError<Double>.self))
157
- expect(($0 as! CodedError).description) == Conversions.CastingValuesError<Double>(keys: ["dx"]).description
156
+ expect($0).to(beAKindOf(Conversions.CastingValuesException<Double>.self))
157
+ expect(($0 as! CodedError).description) == Conversions.CastingValuesException<Double>(["dx"]).description
158
158
  })
159
159
  }
160
160
  }
@@ -184,22 +184,22 @@ class ConvertiblesSpec: QuickSpec {
184
184
  }
185
185
 
186
186
  it("throws when array size is unexpected") { // different than four
187
- expect { try CGRect.convert(from: [x]) }.to(throwError(errorType: Conversions.ConvertingError<CGRect>.self))
188
- expect { try CGRect.convert(from: [x, y]) }.to(throwError(errorType: Conversions.ConvertingError<CGRect>.self))
189
- expect { try CGRect.convert(from: [x, y, width, height, y]) }.to(throwError(errorType: Conversions.ConvertingError<CGRect>.self))
187
+ expect { try CGRect.convert(from: [x]) }.to(throwError(errorType: Conversions.ConvertingException<CGRect>.self))
188
+ expect { try CGRect.convert(from: [x, y]) }.to(throwError(errorType: Conversions.ConvertingException<CGRect>.self))
189
+ expect { try CGRect.convert(from: [x, y, width, height, y]) }.to(throwError(errorType: Conversions.ConvertingException<CGRect>.self))
190
190
  }
191
191
 
192
192
  it("throws when dict is missing some keys") {
193
193
  expect { try CGRect.convert(from: ["x": x]) }.to(throwError {
194
- expect($0).to(beAKindOf(Conversions.MissingKeysError<Double>.self))
195
- expect(($0 as! CodedError).description) == Conversions.MissingKeysError<Double>(keys: ["y", "width", "height"]).description
194
+ expect($0).to(beAKindOf(Conversions.MissingKeysException<Double>.self))
195
+ expect(($0 as! CodedError).description) == Conversions.MissingKeysException<Double>(["y", "width", "height"]).description
196
196
  })
197
197
  }
198
198
 
199
199
  it("throws when dict has uncastable keys") {
200
200
  expect { try CGRect.convert(from: ["x": x, "y": nil, "width": width, "height": "\(height)"]) }.to(throwError {
201
- expect($0).to(beAKindOf(Conversions.CastingValuesError<Double>.self))
202
- expect(($0 as! CodedError).description) == Conversions.CastingValuesError<Double>(keys: ["y", "height"]).description
201
+ expect($0).to(beAKindOf(Conversions.CastingValuesException<Double>.self))
202
+ expect(($0 as! CodedError).description) == Conversions.CastingValuesException<Double>(["y", "height"]).description
203
203
  })
204
204
  }
205
205
  }
@@ -213,8 +213,8 @@ class ConvertiblesSpec: QuickSpec {
213
213
  }
214
214
  func testInvalidHexColor(_ hex: String) {
215
215
  expect { try CGColor.convert(from: hex) }.to(throwError {
216
- expect($0).to(beAKindOf(Conversions.InvalidHexColorError.self))
217
- expect(($0 as! CodedError).description) == Conversions.InvalidHexColorError(hex: hex).description
216
+ expect($0).to(beAKindOf(Conversions.InvalidHexColorException.self))
217
+ expect(($0 as! CodedError).description) == Conversions.InvalidHexColorException(hex).description
218
218
  })
219
219
  }
220
220
 
@@ -256,8 +256,8 @@ class ConvertiblesSpec: QuickSpec {
256
256
  it("throws when int overflows") {
257
257
  let hex = 0xBBAA88FF2
258
258
  expect { try CGColor.convert(from: hex) }.to(throwError {
259
- expect($0).to(beAKindOf(Conversions.HexColorOverflowError.self))
260
- expect(($0 as! CodedError).description) == Conversions.HexColorOverflowError(hex: UInt64(hex)).description
259
+ expect($0).to(beAKindOf(Conversions.HexColorOverflowException.self))
260
+ expect(($0 as! CodedError).description) == Conversions.HexColorOverflowException(UInt64(hex)).description
261
261
  })
262
262
  }
263
263
  }
@@ -0,0 +1,112 @@
1
+ // Copyright 2021-present 650 Industries. All rights reserved.
2
+
3
+ import Quick
4
+ import Nimble
5
+
6
+ @testable import ExpoModulesCore
7
+
8
+ final class ExceptionsSpec: QuickSpec {
9
+ override func spec() {
10
+ it("has name") {
11
+ let error = TestException()
12
+ expect(error.name) == "TestException"
13
+ }
14
+
15
+ it("has code") {
16
+ let error = TestException()
17
+ expect(error.code) == "ERR_TEST"
18
+ }
19
+
20
+ it("has reason") {
21
+ let error = TestException()
22
+ expect(error.reason) == "This is the test exception"
23
+ }
24
+
25
+ it("can be chained once") {
26
+ func throwable() throws {
27
+ do {
28
+ throw TestExceptionCause()
29
+ } catch {
30
+ throw TestException().causedBy(error)
31
+ }
32
+ }
33
+ expect { try throwable() }.to(throwError { error in
34
+ testChainedExceptionTypes(error: error, types: [TestException.self, TestExceptionCause.self])
35
+ })
36
+ }
37
+
38
+ it("can be chained twice") {
39
+ func throwable() throws {
40
+ do {
41
+ do {
42
+ throw TestExceptionCause()
43
+ } catch {
44
+ throw TestExceptionCause().causedBy(error)
45
+ }
46
+ } catch {
47
+ throw TestException().causedBy(error)
48
+ }
49
+ }
50
+ expect { try throwable() }.to(throwError { error in
51
+ testChainedExceptionTypes(error: error, types: [TestException.self, TestExceptionCause.self, TestExceptionCause.self])
52
+ })
53
+ }
54
+
55
+ it("includes cause description") {
56
+ func throwable() throws {
57
+ do {
58
+ throw TestExceptionCause()
59
+ } catch {
60
+ throw TestException().causedBy(error)
61
+ }
62
+ }
63
+ expect { try throwable() }.to(throwError { error in
64
+ if let error = error as? TestException, let cause = error.cause as? TestExceptionCause {
65
+ expect(error.description).to(contain(cause.description))
66
+ } else {
67
+ fail("Error and its cause are not of expected types.")
68
+ }
69
+ })
70
+ }
71
+
72
+ it("has root cause") {
73
+ let a = TestException()
74
+ let b = TestException().causedBy(a)
75
+ let c = TestException().causedBy(b)
76
+
77
+ expect(c.rootCause) === a
78
+ }
79
+ }
80
+ }
81
+
82
+ class TestException: Exception {
83
+ override var reason: String {
84
+ "This is the test exception"
85
+ }
86
+ }
87
+
88
+ class TestExceptionCause: Exception {
89
+ override var reason: String {
90
+ "This is the cause of the test exception"
91
+ }
92
+ }
93
+
94
+ /**
95
+ Tests whether the exception chain matches given types and their order.
96
+ */
97
+ private func testChainedExceptionTypes(error: Error, types: [Error.Type]) {
98
+ var next: Error? = error
99
+
100
+ for errorType in types {
101
+ let expectedErrorTypeName = String(describing: errorType)
102
+ let currentErrorTypeName = String(describing: type(of: next!))
103
+
104
+ expect(currentErrorTypeName).to(equal(expectedErrorTypeName), description: "The cause is not of type \(expectedErrorTypeName)")
105
+
106
+ if let chainableException = next as? ChainableException {
107
+ next = chainableException.cause
108
+ } else {
109
+ next = nil
110
+ }
111
+ }
112
+ }
@@ -11,11 +11,11 @@ class FunctionSpec: QuickSpec {
11
11
  func testFunctionReturning<T: Equatable>(value returnValue: T) {
12
12
  waitUntil { done in
13
13
  mockModuleHolder(appContext) {
14
- $0.function(functionName) {
14
+ function(functionName) {
15
15
  return returnValue
16
16
  }
17
17
  }
18
- .call(function: functionName, args: []) { value, error in
18
+ .call(function: functionName, args: []) { value, _ in
19
19
  expect(value).notTo(beNil())
20
20
  expect(value).to(beAKindOf(T.self))
21
21
  expect(value as? T).to(equal(returnValue))
@@ -27,7 +27,7 @@ class FunctionSpec: QuickSpec {
27
27
  it("is called") {
28
28
  waitUntil { done in
29
29
  mockModuleHolder(appContext) {
30
- $0.function(functionName) {
30
+ function(functionName) {
31
31
  done()
32
32
  }
33
33
  }
@@ -42,7 +42,7 @@ class FunctionSpec: QuickSpec {
42
42
  }
43
43
 
44
44
  it("returns int values") {
45
- testFunctionReturning(value: 1234)
45
+ testFunctionReturning(value: 1_234)
46
46
  testFunctionReturning(value: [2, 1, 3, 7])
47
47
  }
48
48
 
@@ -60,7 +60,7 @@ class FunctionSpec: QuickSpec {
60
60
  let str: String? = nil
61
61
 
62
62
  mockModuleHolder(appContext) {
63
- $0.function(functionName) { (a: String?) in
63
+ function(functionName) { (a: String?) in
64
64
  expect(a == nil) == true
65
65
  }
66
66
  }
@@ -71,7 +71,7 @@ class FunctionSpec: QuickSpec {
71
71
  let array: [[String]] = [["expo"]]
72
72
 
73
73
  mockModuleHolder(appContext) {
74
- $0.function(functionName) { (a: [[String]]) in
74
+ function(functionName) { (a: [[String]]) in
75
75
  expect(a.first!.first) == array.first!.first
76
76
  }
77
77
  }
@@ -81,7 +81,7 @@ class FunctionSpec: QuickSpec {
81
81
  describe("converting dicts to records") {
82
82
  struct TestRecord: Record {
83
83
  @Field var property: String = "expo"
84
- @Field var optionalProperty: Int? = nil
84
+ @Field var optionalProperty: Int?
85
85
  @Field("propertyWithCustomKey") var customKeyProperty: String = "expo"
86
86
  }
87
87
  let dict = [
@@ -92,11 +92,11 @@ class FunctionSpec: QuickSpec {
92
92
  it("converts to simple record when passed as an argument") {
93
93
  waitUntil { done in
94
94
  mockModuleHolder(appContext) {
95
- $0.function(functionName) { (a: TestRecord) in
95
+ function(functionName) { (a: TestRecord) in
96
96
  return a.property
97
97
  }
98
98
  }
99
- .call(function: functionName, args: [dict]) { value, error in
99
+ .call(function: functionName, args: [dict]) { value, _ in
100
100
  expect(value).notTo(beNil())
101
101
  expect(value).to(beAKindOf(String.self))
102
102
  expect(value).to(be(dict["property"]))
@@ -108,11 +108,11 @@ class FunctionSpec: QuickSpec {
108
108
  it("converts to record with custom key") {
109
109
  waitUntil { done in
110
110
  mockModuleHolder(appContext) {
111
- $0.function(functionName) { (a: TestRecord) in
111
+ function(functionName) { (a: TestRecord) in
112
112
  return a.customKeyProperty
113
113
  }
114
114
  }
115
- .call(function: functionName, args: [dict]) { value, error in
115
+ .call(function: functionName, args: [dict]) { value, _ in
116
116
  expect(value).notTo(beNil())
117
117
  expect(value).to(beAKindOf(String.self))
118
118
  expect(value).to(be(dict["propertyWithCustomKey"]))
@@ -124,11 +124,11 @@ class FunctionSpec: QuickSpec {
124
124
  it("returns the record back") {
125
125
  waitUntil { done in
126
126
  mockModuleHolder(appContext) {
127
- $0.function(functionName) { (a: TestRecord) in
127
+ function(functionName) { (a: TestRecord) in
128
128
  return a.toDictionary()
129
129
  }
130
130
  }
131
- .call(function: functionName, args: [dict]) { value, error in
131
+ .call(function: functionName, args: [dict]) { value, _ in
132
132
  expect(value).notTo(beNil())
133
133
  expect(value).to(beAKindOf(Record.Dict.self))
134
134
 
@@ -145,16 +145,15 @@ class FunctionSpec: QuickSpec {
145
145
  it("throws when called with more arguments than expected") {
146
146
  waitUntil { done in
147
147
  mockModuleHolder(appContext) {
148
- $0.function(functionName) { (a: Int) in
148
+ function(functionName) { (_: Int) in
149
149
  return "something"
150
150
  }
151
151
  }
152
152
  // Function expects one argument, let's give it more.
153
- .call(function: functionName, args: [1, 2]) { value, error in
153
+ .call(function: functionName, args: [1, 2]) { _, error in
154
154
  expect(error).notTo(beNil())
155
- expect(error).to(beAKindOf(InvalidArgsNumberError.self))
156
- expect(error?.code).to(equal("ERR_INVALID_ARGS_NUMBER"))
157
- expect(error?.description).to(equal(InvalidArgsNumberError(received: 2, expected: 1).description))
155
+ expect(error).to(beAKindOf(FunctionCallException.self))
156
+ expect((error as! Exception).isCausedBy(InvalidArgsNumberException.self)) == true
158
157
  done()
159
158
  }
160
159
  }
@@ -163,16 +162,15 @@ class FunctionSpec: QuickSpec {
163
162
  it("throws when called with arguments of incompatible types") {
164
163
  waitUntil { done in
165
164
  mockModuleHolder(appContext) {
166
- $0.function(functionName) { (a: String) in
165
+ function(functionName) { (_: String) in
167
166
  return "something"
168
167
  }
169
168
  }
170
169
  // Function expects a string, let's give it a number.
171
170
  .call(function: functionName, args: [1]) { value, error in
172
171
  expect(error).notTo(beNil())
173
- expect(error).to(beAKindOf(Conversions.CastingError<String>.self))
174
- expect(error?.code).to(equal("ERR_CASTING_FAILED"))
175
- expect(error?.description).to(equal(Conversions.CastingError<String>(value: 1).description))
172
+ expect(error).to(beAKindOf(FunctionCallException.self))
173
+ expect((error as! Exception).isCausedBy(Conversions.CastingException<String>.self)) == true
176
174
  done()
177
175
  }
178
176
  }
@@ -18,7 +18,7 @@ class FunctionWithConvertiblesSpec: QuickSpec {
18
18
  let height = 592.1
19
19
 
20
20
  mockModuleHolder(appContext) {
21
- $0.function(functionName) { (point: CGPoint, size: CGSize, vector: CGVector, rect: CGRect) in
21
+ function(functionName) { (point: CGPoint, size: CGSize, vector: CGVector, rect: CGRect) in
22
22
  expect(point.x) == x
23
23
  expect(point.y) == y
24
24
  expect(size.width) == width
@@ -48,7 +48,7 @@ class FunctionWithConvertiblesSpec: QuickSpec {
48
48
  }
49
49
 
50
50
  mockModuleHolder(appContext) {
51
- $0.function(functionName) { (color1: CGColor, color2: CGColor, color3: CGColor, color4: CGColor) in
51
+ function(functionName) { (color1: CGColor, color2: CGColor, color3: CGColor, color4: CGColor) in
52
52
  testColorComponents(color1, 0x2A, 0x4B, 0x5D, 0xFF)
53
53
  testColorComponents(color2, 0x11, 0xFF, 0x00, 0xDD)
54
54
  testColorComponents(color3, 0x66, 0x00, 0xCC, 0xAA)
@@ -32,7 +32,7 @@ class CustomModule: Module {
32
32
  typealias MockedDefinitionFunc = (CustomModule) -> ModuleDefinition
33
33
 
34
34
  func mockModuleHolder(_ appContext: AppContext, @ModuleDefinitionBuilder _ definitionBody: @escaping () -> ModuleDefinition) -> ModuleHolder {
35
- return ModuleHolder(appContext: appContext, module: CustomModule(appContext: appContext, { module in definitionBody() }))
35
+ return ModuleHolder(appContext: appContext, module: CustomModule(appContext: appContext, { _ in definitionBody() }))
36
36
  }
37
37
 
38
38
  func mockModuleHolder(_ appContext: AppContext, @ModuleDefinitionBuilder _ definitionBody: @escaping (CustomModule) -> ModuleDefinition) -> ModuleHolder {
@@ -3,7 +3,6 @@ import ExpoModulesCore
3
3
  public class ModulesProviderMock: ModulesProvider {
4
4
  public override func getModuleClasses() -> [AnyModule.Type] {
5
5
  return [
6
-
7
6
  ]
8
7
  }
9
8
  }
@@ -21,7 +21,7 @@ class ModuleEventListenersSpec: QuickSpec {
21
21
 
22
22
  it("calls onCreate once the module instance is created") {
23
23
  waitUntil { done in
24
- let _ = mockModuleHolder(appContext) {
24
+ _ = mockModuleHolder(appContext) {
25
25
  $0.onCreate {
26
26
  done()
27
27
  }
@@ -7,7 +7,7 @@ class RecordSpec: QuickSpec {
7
7
  override func spec() {
8
8
  it("initializes with empty dictionary") {
9
9
  struct TestRecord: Record { }
10
- let _ = try TestRecord(from: [:])
10
+ _ = try TestRecord(from: [:])
11
11
  }
12
12
 
13
13
  it("works back and forth with a field") {
@@ -37,14 +37,9 @@ class RecordSpec: QuickSpec {
37
37
  @Field(.required) var a: Int
38
38
  }
39
39
 
40
- do {
41
- let _ = try TestRecord(from: [:])
42
- fail()
43
- } catch let error as CodedError {
44
- expect(error).to(beAKindOf(FieldRequiredError.self))
45
- expect(error.code).to(equal("ERR_FIELD_REQUIRED"))
46
- expect(error.description).to(equal(FieldRequiredError(fieldKey: "a").description))
47
- }
40
+ expect { try TestRecord(from: [:]) }.to(throwError { error in
41
+ expect(error).to(beAKindOf(FieldRequiredException.self))
42
+ })
48
43
  }
49
44
 
50
45
  it("throws when casting is not possible") {
@@ -53,14 +48,9 @@ class RecordSpec: QuickSpec {
53
48
  }
54
49
  let dict = ["a": "try with String instead of Int"]
55
50
 
56
- do {
57
- let _ = try TestRecord(from: dict)
58
- fail()
59
- } catch let error as CodedError {
60
- expect(error).to(beAKindOf(FieldInvalidTypeError.self))
61
- expect(error.code).to(equal("ERR_FIELD_INVALID_TYPE"))
62
- expect(error.description).to(equal(FieldInvalidTypeError(fieldKey: "a", value: dict["a"], desiredType: Int.self).description))
63
- }
51
+ expect { try TestRecord(from: dict) }.to(throwError { error in
52
+ expect(error).to(beAKindOf(FieldInvalidTypeException.self))
53
+ })
64
54
  }
65
55
  }
66
56
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-modules-core",
3
- "version": "0.6.4",
3
+ "version": "0.7.0",
4
4
  "description": "The core of Expo Modules architecture",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -30,7 +30,7 @@
30
30
  },
31
31
  "author": "650 Industries, Inc.",
32
32
  "license": "MIT",
33
- "homepage": "https://github.com/expo/expo/tree/master/packages/expo-modules-core",
33
+ "homepage": "https://github.com/expo/expo/tree/main/packages/expo-modules-core",
34
34
  "jest": {
35
35
  "preset": "expo-module-scripts"
36
36
  },
@@ -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": "81d318c3ac2db24ba192d2b3fc5a2dd1bbd8bd4d"
45
+ "gitHead": "e1ff1a3d6bc62f374e6947a5e81428a1bb7cfa34"
46
46
  }
package/src/index.ts CHANGED
@@ -9,6 +9,8 @@ import SyntheticPlatformEmitter from './SyntheticPlatformEmitter';
9
9
  import { CodedError } from './errors/CodedError';
10
10
  import { UnavailabilityError } from './errors/UnavailabilityError';
11
11
 
12
+ import './sweet/setUpErrorManager.fx';
13
+
12
14
  export { default as deprecate } from './deprecate';
13
15
 
14
16
  export {
@@ -25,6 +27,8 @@ export {
25
27
  UnavailabilityError,
26
28
  };
27
29
 
30
+ export * from './requireNativeModule';
31
+
28
32
  /**
29
33
  * @deprecated renamed to `DeviceEventEmitter`
30
34
  */