expo-modules-core 0.4.6 → 0.6.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 (150) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +6 -6
  3. package/android/build.gradle +30 -2
  4. package/android/src/main/java/expo/modules/adapters/react/ModuleRegistryAdapter.java +27 -5
  5. package/android/src/main/java/expo/modules/adapters/react/NativeModulesProxy.java +49 -5
  6. package/android/src/main/java/expo/modules/core/BasePackage.java +6 -0
  7. package/android/src/main/java/expo/modules/core/ModulePriorities.kt +25 -0
  8. package/android/src/main/java/expo/modules/core/interfaces/ActivityEventListener.java +3 -1
  9. package/android/src/main/java/expo/modules/core/interfaces/ApplicationLifecycleListener.java +10 -0
  10. package/android/src/main/java/expo/modules/core/interfaces/Package.java +4 -0
  11. package/android/src/main/java/expo/modules/core/interfaces/ReactActivityHandler.java +21 -0
  12. package/android/src/main/java/expo/modules/core/interfaces/ReactActivityLifecycleListener.java +14 -0
  13. package/android/src/main/java/expo/modules/core/interfaces/ReactNativeHostHandler.java +70 -0
  14. package/android/src/main/java/expo/modules/core/utilities/KotlinUtilities.kt +23 -0
  15. package/android/src/main/java/expo/modules/kotlin/AppContext.kt +166 -0
  16. package/android/src/main/java/expo/modules/kotlin/DynamicExtenstions.kt +9 -0
  17. package/android/src/main/java/expo/modules/kotlin/ExpoModulesHelper.kt +18 -0
  18. package/android/src/main/java/expo/modules/kotlin/KPromiseWrapper.kt +24 -0
  19. package/android/src/main/java/expo/modules/kotlin/KotlinInteropModuleRegistry.kt +98 -0
  20. package/android/src/main/java/expo/modules/kotlin/ModuleHolder.kt +41 -0
  21. package/android/src/main/java/expo/modules/kotlin/ModuleRegistry.kt +56 -0
  22. package/android/src/main/java/expo/modules/kotlin/ModulesProvider.kt +7 -0
  23. package/android/src/main/java/expo/modules/kotlin/Promise.kt +13 -0
  24. package/android/src/main/java/expo/modules/kotlin/ReactLifecycleDelegate.kt +39 -0
  25. package/android/src/main/java/expo/modules/kotlin/ReadableArrayIterator.kt +14 -0
  26. package/android/src/main/java/expo/modules/kotlin/ReadableTypeExtensions.kt +18 -0
  27. package/android/src/main/java/expo/modules/kotlin/allocators/ObjectConstructor.kt +5 -0
  28. package/android/src/main/java/expo/modules/kotlin/allocators/ObjectConstructorFactory.kt +31 -0
  29. package/android/src/main/java/expo/modules/kotlin/allocators/UnsafeAllocator.kt +49 -0
  30. package/android/src/main/java/expo/modules/kotlin/events/EventListener.kt +39 -0
  31. package/android/src/main/java/expo/modules/kotlin/events/EventName.kt +31 -0
  32. package/android/src/main/java/expo/modules/kotlin/events/EventsDefinition.kt +3 -0
  33. package/android/src/main/java/expo/modules/kotlin/events/KEventEmitterWrapper.kt +26 -0
  34. package/android/src/main/java/expo/modules/kotlin/events/OnActivityResultPayload.kt +8 -0
  35. package/android/src/main/java/expo/modules/kotlin/exception/CodedException.kt +70 -0
  36. package/android/src/main/java/expo/modules/kotlin/methods/AnyMethod.kt +50 -0
  37. package/android/src/main/java/expo/modules/kotlin/methods/Method.kt +14 -0
  38. package/android/src/main/java/expo/modules/kotlin/methods/PromiseMethod.kt +15 -0
  39. package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +24 -0
  40. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +227 -0
  41. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionData.kt +16 -0
  42. package/android/src/main/java/expo/modules/kotlin/records/Field.kt +5 -0
  43. package/android/src/main/java/expo/modules/kotlin/records/Record.kt +3 -0
  44. package/android/src/main/java/expo/modules/kotlin/records/RecordTypeConverter.kt +55 -0
  45. package/android/src/main/java/expo/modules/kotlin/types/AnyType.kt +14 -0
  46. package/android/src/main/java/expo/modules/kotlin/types/ArrayTypeConverter.kt +44 -0
  47. package/android/src/main/java/expo/modules/kotlin/types/BasicTypeConverters.kt +60 -0
  48. package/android/src/main/java/expo/modules/kotlin/types/EnumTypeConverter.kt +84 -0
  49. package/android/src/main/java/expo/modules/kotlin/types/ListTypeConverter.kt +25 -0
  50. package/android/src/main/java/expo/modules/kotlin/types/MapTypeConverter.kt +39 -0
  51. package/android/src/main/java/expo/modules/kotlin/types/PairTypeConverter.kt +28 -0
  52. package/android/src/main/java/expo/modules/kotlin/types/TypeConverter.kt +19 -0
  53. package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +107 -0
  54. package/android/src/main/java/expo/modules/kotlin/views/AnyViewProp.kt +10 -0
  55. package/android/src/main/java/expo/modules/kotlin/views/ConcreteViewProp.kt +17 -0
  56. package/android/src/main/java/expo/modules/kotlin/views/GroupViewManagerWrapper.kt +22 -0
  57. package/android/src/main/java/expo/modules/kotlin/views/SimpleViewManagerWrapper.kt +21 -0
  58. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinition.kt +41 -0
  59. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinitionBuilder.kt +40 -0
  60. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerWrapperDelegate.kt +21 -0
  61. package/android/src/main/java/expo/modules/kotlin/views/ViewWrapperDelegateHolder.kt +5 -0
  62. package/build/NativeModulesProxy.native.d.ts +4 -0
  63. package/build/NativeModulesProxy.native.js +14 -1
  64. package/build/NativeModulesProxy.native.js.map +1 -1
  65. package/build/NativeModulesProxy.types.d.ts +3 -0
  66. package/build/NativeModulesProxy.types.js.map +1 -1
  67. package/build/NativeViewManagerAdapter.native.js +1 -1
  68. package/build/NativeViewManagerAdapter.native.js.map +1 -1
  69. package/ios/AppDelegates/EXAppDelegateWrapper.h +19 -0
  70. package/ios/AppDelegates/EXAppDelegateWrapper.m +45 -0
  71. package/ios/AppDelegates/EXAppDelegatesLoader.h +15 -0
  72. package/ios/AppDelegates/EXAppDelegatesLoader.m +30 -0
  73. package/ios/AppDelegates/EXLegacyAppDelegateWrapper.h +16 -0
  74. package/ios/{EXAppDelegateWrapper.m → AppDelegates/EXLegacyAppDelegateWrapper.m} +2 -2
  75. package/ios/AppDelegates/ExpoAppDelegate.swift +282 -0
  76. package/ios/AppDelegates/ExpoAppDelegateSubscriber.swift +24 -0
  77. package/ios/EXAppDefines.h +26 -0
  78. package/ios/EXAppDefines.m +61 -0
  79. package/ios/ExpoModulesCore.podspec +8 -3
  80. package/ios/JSI/ExpoModulesProxySpec.h +24 -0
  81. package/ios/JSI/ExpoModulesProxySpec.mm +135 -0
  82. package/ios/JSI/JSIConversions.h +42 -0
  83. package/ios/JSI/JSIConversions.mm +164 -0
  84. package/ios/JSI/JSIInstaller.h +19 -0
  85. package/ios/JSI/JSIInstaller.mm +22 -0
  86. package/ios/ModuleRegistryAdapter/EXModuleRegistryAdapter.m +1 -6
  87. package/ios/NativeModulesProxy/EXNativeModulesProxy.h +6 -0
  88. package/ios/NativeModulesProxy/{EXNativeModulesProxy.m → EXNativeModulesProxy.mm} +91 -18
  89. package/ios/ReactDelegates/EXRCTBridgeDelegateInterceptor.h +16 -0
  90. package/ios/ReactDelegates/EXRCTBridgeDelegateInterceptor.m +49 -0
  91. package/ios/ReactDelegates/EXReactDelegateWrapper+Private.h +18 -0
  92. package/ios/ReactDelegates/EXReactDelegateWrapper.h +25 -0
  93. package/ios/ReactDelegates/EXReactDelegateWrapper.m +40 -0
  94. package/ios/ReactDelegates/ExpoReactDelegate.swift +37 -0
  95. package/ios/ReactDelegates/ExpoReactDelegateHandler.swift +52 -0
  96. package/ios/ReactDelegates/ModulePriorities.swift +20 -0
  97. package/ios/Services/EXReactNativeEventEmitter.h +6 -0
  98. package/ios/Services/EXReactNativeEventEmitter.m +15 -0
  99. package/ios/Swift/AppContext.swift +14 -1
  100. package/ios/Swift/Arguments/AnyArgument.swift +14 -0
  101. package/ios/Swift/Arguments/AnyArgumentType.swift +13 -0
  102. package/ios/Swift/Arguments/ArgumentType.swift +24 -0
  103. package/ios/Swift/Arguments/ConvertibleArgument.swift +15 -0
  104. package/ios/Swift/Arguments/Convertibles.swift +107 -0
  105. package/ios/Swift/Arguments/Types/ArrayArgumentType.swift +42 -0
  106. package/ios/Swift/Arguments/Types/ConvertibleArgumentType.swift +16 -0
  107. package/ios/Swift/Arguments/Types/EnumArgumentType.swift +105 -0
  108. package/ios/Swift/Arguments/Types/OptionalArgumentType.swift +49 -0
  109. package/ios/Swift/Arguments/Types/PromiseArgumentType.swift +15 -0
  110. package/ios/Swift/Arguments/Types/RawArgumentType.swift +25 -0
  111. package/ios/Swift/Conversions.swift +199 -7
  112. package/ios/Swift/EventListener.swift +37 -5
  113. package/ios/Swift/Functions/AnyFunction.swift +42 -0
  114. package/ios/Swift/{Methods/ConcreteMethod.swift → Functions/ConcreteFunction.swift} +32 -34
  115. package/ios/Swift/ModuleHolder.swift +86 -20
  116. package/ios/Swift/ModuleRegistry.swift +19 -8
  117. package/ios/Swift/Modules/AnyModule.swift +8 -8
  118. package/ios/Swift/Modules/Module.swift +11 -0
  119. package/ios/Swift/Modules/ModuleDefinition.swift +55 -15
  120. package/ios/Swift/Modules/ModuleDefinitionBuilder.swift +1 -1
  121. package/ios/Swift/Modules/ModuleDefinitionComponents.swift +149 -54
  122. package/ios/Swift/ModulesProvider.swift +19 -0
  123. package/ios/Swift/Promise.swift +1 -1
  124. package/ios/Swift/Records/Field.swift +1 -1
  125. package/ios/Swift/Records/Record.swift +8 -1
  126. package/ios/Swift/SwiftInteropBridge.swift +46 -17
  127. package/ios/Swift/Views/AnyViewProp.swift +2 -2
  128. package/ios/Swift/Views/ConcreteViewProp.swift +37 -10
  129. package/ios/Swift/Views/ViewModuleWrapper.swift +9 -4
  130. package/ios/Swift.h +9 -0
  131. package/ios/Tests/ArgumentTypeSpec.swift +145 -0
  132. package/ios/Tests/ConstantsSpec.swift +36 -0
  133. package/ios/Tests/ConvertiblesSpec.swift +265 -0
  134. package/ios/Tests/EXAppDefinesTest.m +99 -0
  135. package/ios/Tests/{MethodSpec.swift → FunctionSpec.swift} +69 -54
  136. package/ios/Tests/FunctionWithConvertiblesSpec.swift +66 -0
  137. package/ios/Tests/Mocks/ModuleMocks.swift +21 -7
  138. package/ios/Tests/ModuleEventListenersSpec.swift +17 -16
  139. package/ios/Tests/ModuleRegistrySpec.swift +4 -7
  140. package/package.json +3 -3
  141. package/src/NativeModulesProxy.native.ts +22 -2
  142. package/src/NativeModulesProxy.types.ts +8 -0
  143. package/src/NativeViewManagerAdapter.native.tsx +1 -1
  144. package/android/src/main/java/expo/modules/core/interfaces/ApplicationLifecycleListener.kt +0 -9
  145. package/android/src/main/java/expo/modules/core/interfaces/ReactActivityLifecycleListener.kt +0 -11
  146. package/android/src/main/java/expo/modules/core/interfaces/ReactNativeHostHandler.kt +0 -51
  147. package/ios/EXAppDelegateWrapper.h +0 -13
  148. package/ios/Swift/Methods/AnyArgumentType.swift +0 -48
  149. package/ios/Swift/Methods/AnyMethod.swift +0 -31
  150. package/ios/Swift/Methods/AnyMethodArgument.swift +0 -13
@@ -1,8 +1,8 @@
1
1
 
2
2
  /**
3
- A protocol for any type-erased module that provides methods used by the core.
3
+ A protocol for any type-erased module that provides functions used by the core.
4
4
  */
5
- public protocol AnyModule: AnyObject {
5
+ public protocol AnyModule: AnyObject, AnyArgument {
6
6
  /**
7
7
  The default initializer. Must be public, but the module class does *not* need to
8
8
  define it as it is implemented in protocol composition, see `BaseModule` class.
@@ -10,7 +10,7 @@ public protocol AnyModule: AnyObject {
10
10
  init(appContext: AppContext)
11
11
 
12
12
  /**
13
- A DSL-like function that returns a `ModuleDefinition` which can be built up from module's name, constants or methods.
13
+ A DSL-like function that returns a `ModuleDefinition` which can be built up from module's name, constants or functions.
14
14
  The `@ModuleDefinitionBuilder` wrapper is *not* required in the implementation — it is implicitly taken from the protocol.
15
15
 
16
16
  # Example
@@ -18,7 +18,7 @@ public protocol AnyModule: AnyObject {
18
18
  ```
19
19
  public func definition() -> ModuleDefinition {
20
20
  name("MyModule")
21
- method("myMethod") { (a: String, b: String) in
21
+ function("myFunction") { (a: String, b: String) in
22
22
  "\(a) \(b)"
23
23
  }
24
24
  }
@@ -29,16 +29,16 @@ public protocol AnyModule: AnyObject {
29
29
  ```javascript
30
30
  import { NativeModulesProxy } from 'expo-modules-core';
31
31
 
32
- await NativeModulesProxy.MyModule.myMethod('Hello', 'World!'); // -> 'Hello World!'
32
+ await NativeModulesProxy.MyModule.myFunction('Hello', 'World!'); // -> 'Hello World!'
33
33
  ```
34
34
 
35
- # Method's result obtained asynchronously
35
+ # Function's result obtained asynchronously
36
36
 
37
37
  If you need to run some async code to get the proper value that you want to return to JavaScript,
38
- just specify an argument of type `Promise` as the last one and use its `resolve` or `reject` methods.
38
+ just specify an argument of type `Promise` as the last one and use its `resolve` or `reject` functions.
39
39
 
40
40
  ```
41
- method("myMethod") { (promise: Promise) in
41
+ function("myFunction") { (promise: Promise) in
42
42
  DispatchQueue.main.async {
43
43
  promise.resolve("return value obtained in async callback")
44
44
  }
@@ -1,3 +1,4 @@
1
+ // Copyright 2021-present 650 Industries. All rights reserved.
1
2
 
2
3
  /**
3
4
  `BaseModule` is just a stub class that fulfils `AnyModule` protocol requirement of public default initializer,
@@ -7,9 +8,19 @@
7
8
  open class BaseModule {
8
9
  public private(set) weak var appContext: AppContext?
9
10
 
11
+ @available(*, unavailable, message: "Module's initializer cannot be overriden, use \"onCreate\" definition component instead.")
12
+ public init() {}
13
+
10
14
  required public init(appContext: AppContext) {
11
15
  self.appContext = appContext
12
16
  }
17
+
18
+ /**
19
+ Sends an event with given name and body to JavaScript.
20
+ */
21
+ public func sendEvent(_ eventName: String, _ body: [String: Any?] = [:]) {
22
+ appContext?.eventEmitter?.sendEvent(withName: eventName, body: body)
23
+ }
13
24
  }
14
25
 
15
26
  /**
@@ -9,36 +9,69 @@ public protocol AnyDefinition {}
9
9
  of the module and what it exports to the JavaScript world.
10
10
  See `ModuleDefinitionBuilder` for more details on how to create it.
11
11
  */
12
- public struct ModuleDefinition: AnyDefinition {
13
- let name: String?
14
- let methods: [String : AnyMethod]
15
- let constants: [String : Any?]
12
+ public final class ModuleDefinition: AnyDefinition {
13
+ /**
14
+ The module's type associated with the definition. It's used to create the module instance.
15
+ */
16
+ var type: AnyModule.Type?
17
+
18
+ /**
19
+ Name of the defined module. Falls back to the type name if not provided in the definition.
20
+ */
21
+ var name: String
22
+
23
+ let functions: [String : AnyFunction]
24
+ let constants: [ConstantsDefinition]
16
25
  let eventListeners: [EventListener]
17
26
  let viewManager: ViewManagerDefinition?
18
27
 
28
+ /**
29
+ Names of the events that the module can send to JavaScript.
30
+ */
31
+ let eventNames: [String]
32
+
33
+ /**
34
+ Initializer that is called by the `ModuleDefinitionBuilder` results builder.
35
+ */
19
36
  init(definitions: [AnyDefinition]) {
20
37
  self.name = definitions
21
38
  .compactMap { $0 as? ModuleNameDefinition }
22
39
  .last?
23
- .name
40
+ .name ?? ""
24
41
 
25
- self.methods = definitions
26
- .compactMap { $0 as? AnyMethod }
27
- .reduce(into: [String : AnyMethod]()) { dict, method in
28
- dict[method.name] = method
42
+ self.functions = definitions
43
+ .compactMap { $0 as? AnyFunction }
44
+ .reduce(into: [String : AnyFunction]()) { dict, function in
45
+ dict[function.name] = function
29
46
  }
30
47
 
31
- self.constants = definitions
32
- .compactMap { $0 as? ConstantsDefinition }
33
- .reduce(into: [String : Any?]()) { dict, definition in
34
- dict.merge(definition.constants) { $1 }
35
- }
48
+ self.constants = definitions.compactMap { $0 as? ConstantsDefinition }
36
49
 
37
50
  self.eventListeners = definitions.compactMap { $0 as? EventListener }
38
51
 
39
52
  self.viewManager = definitions
40
53
  .compactMap { $0 as? ViewManagerDefinition }
41
54
  .last
55
+
56
+ self.eventNames = Array(
57
+ definitions
58
+ .compactMap { ($0 as? EventsDefinition)?.names }
59
+ .joined()
60
+ )
61
+ }
62
+
63
+ /**
64
+ Sets the module type that the definition is associated with. We can't pass this in the initializer
65
+ as it's called by the results builder that doesn't have access to the type.
66
+ */
67
+ func withType(_ type: AnyModule.Type) -> Self {
68
+ self.type = type
69
+
70
+ // Use the type name if the name is not in the definition or was defined empty.
71
+ if name.isEmpty {
72
+ name = String(describing: type)
73
+ }
74
+ return self
42
75
  }
43
76
  }
44
77
 
@@ -53,5 +86,12 @@ internal struct ModuleNameDefinition: AnyDefinition {
53
86
  A definition for module's constants. Returned by `constants(() -> SomeType)` in module's definition.
54
87
  */
55
88
  internal struct ConstantsDefinition: AnyDefinition {
56
- let constants: [String : Any?]
89
+ let body: () -> [String: Any?]
90
+ }
91
+
92
+ /**
93
+ A definition for module's events that can be sent to JavaScript.
94
+ */
95
+ internal struct EventsDefinition: AnyDefinition {
96
+ let names: [String]
57
97
  }
@@ -2,7 +2,7 @@
2
2
  #if swift(>=5.4)
3
3
  /**
4
4
  A function builder that provides DSL-like syntax. Thanks to this, the function doesn't need to explicitly return an array,
5
- but can just return multiple methods one after another. This works similarly to SwiftUI's `body` block.
5
+ but can just return multiple components one after another. This works similarly to SwiftUI's `body` block.
6
6
  */
7
7
  @resultBuilder
8
8
  public struct ModuleDefinitionBuilder {
@@ -7,6 +7,8 @@ import UIKit
7
7
  will be implemented in the future.
8
8
  */
9
9
  extension AnyModule {
10
+ // MARK: - Module name
11
+
10
12
  /**
11
13
  Sets the name of the module that is exported to the JavaScript world.
12
14
  */
@@ -14,21 +16,32 @@ extension AnyModule {
14
16
  return ModuleNameDefinition(name: name)
15
17
  }
16
18
 
19
+ // MARK: - Constants
20
+
21
+ /**
22
+ Definition function setting the module's constants to export.
23
+ */
24
+ public func constants(_ body: @escaping () -> [String: Any?]) -> AnyDefinition {
25
+ return ConstantsDefinition(body: body)
26
+ }
27
+
17
28
  /**
18
29
  Definition function setting the module's constants to export.
19
30
  */
20
- public func constants(_ closure: () -> [String : Any?]) -> AnyDefinition {
21
- return ConstantsDefinition(constants: closure())
31
+ public func constants(_ body: @autoclosure @escaping () -> [String: Any?]) -> AnyDefinition {
32
+ return ConstantsDefinition(body: body)
22
33
  }
23
34
 
35
+ // MARK: - Functions
36
+
24
37
  /**
25
- Factory function for methods without arguments.
38
+ Function without arguments.
26
39
  */
27
- public func method<R>(
40
+ public func function<R>(
28
41
  _ name: String,
29
42
  _ closure: @escaping () -> R
30
- ) -> AnyMethod {
31
- return ConcreteMethod(
43
+ ) -> AnyFunction {
44
+ return ConcreteFunction(
32
45
  name,
33
46
  argTypes: [],
34
47
  closure
@@ -36,117 +49,119 @@ extension AnyModule {
36
49
  }
37
50
 
38
51
  /**
39
- Factory function for methods with one argument.
52
+ Function with one argument.
40
53
  */
41
- public func method<R, A0: AnyMethodArgument>(
54
+ public func function<R, A0: AnyArgument>(
42
55
  _ name: String,
43
56
  _ closure: @escaping (A0) -> R
44
- ) -> AnyMethod {
45
- return ConcreteMethod(
57
+ ) -> AnyFunction {
58
+ return ConcreteFunction(
46
59
  name,
47
- argTypes: [AnyArgumentType(A0.self)],
60
+ argTypes: [ArgumentType(A0.self)],
48
61
  closure
49
62
  )
50
63
  }
51
64
 
52
65
  /**
53
- Factory function for methods with 2 arguments.
66
+ Function with two arguments.
54
67
  */
55
- public func method<R, A0: AnyMethodArgument, A1: AnyMethodArgument>(
68
+ public func function<R, A0: AnyArgument, A1: AnyArgument>(
56
69
  _ name: String,
57
70
  _ closure: @escaping (A0, A1) -> R
58
- ) -> AnyMethod {
59
- return ConcreteMethod(
71
+ ) -> AnyFunction {
72
+ return ConcreteFunction(
60
73
  name,
61
- argTypes: [AnyArgumentType(A0.self), AnyArgumentType(A1.self)],
74
+ argTypes: [ArgumentType(A0.self), ArgumentType(A1.self)],
62
75
  closure
63
76
  )
64
77
  }
65
78
 
66
79
  /**
67
- Factory function for methods with 3 arguments.
80
+ Function with three arguments.
68
81
  */
69
- public func method<R, A0: AnyMethodArgument, A1: AnyMethodArgument, A2: AnyMethodArgument>(
82
+ public func function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument>(
70
83
  _ name: String,
71
84
  _ closure: @escaping (A0, A1, A2) -> R
72
- ) -> AnyMethod {
73
- return ConcreteMethod(
85
+ ) -> AnyFunction {
86
+ return ConcreteFunction(
74
87
  name,
75
- argTypes: [AnyArgumentType(A0.self), AnyArgumentType(A1.self), AnyArgumentType(A2.self)],
88
+ argTypes: [ArgumentType(A0.self), ArgumentType(A1.self), ArgumentType(A2.self)],
76
89
  closure
77
90
  )
78
91
  }
79
92
 
80
93
  /**
81
- Factory function for methods with 4 arguments.
94
+ Function with four arguments.
82
95
  */
83
- public func method<R, A0: AnyMethodArgument, A1: AnyMethodArgument, A2: AnyMethodArgument, A3: AnyMethodArgument>(
96
+ public func function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument>(
84
97
  _ name: String,
85
98
  _ closure: @escaping (A0, A1, A2, A3) -> R
86
- ) -> AnyMethod {
87
- return ConcreteMethod(
99
+ ) -> AnyFunction {
100
+ return ConcreteFunction(
88
101
  name,
89
- argTypes: [AnyArgumentType(A0.self), AnyArgumentType(A1.self), AnyArgumentType(A2.self), AnyArgumentType(A3.self)],
102
+ argTypes: [ArgumentType(A0.self), ArgumentType(A1.self), ArgumentType(A2.self), ArgumentType(A3.self)],
90
103
  closure
91
104
  )
92
105
  }
93
106
 
94
107
  /**
95
- Factory function for methods with 5 arguments.
108
+ Function with five arguments.
96
109
  */
97
- public func method<R, A0: AnyMethodArgument, A1: AnyMethodArgument, A2: AnyMethodArgument, A3: AnyMethodArgument, A4: AnyMethodArgument>(
110
+ public func function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument, A4: AnyArgument>(
98
111
  _ name: String,
99
112
  _ closure: @escaping (A0, A1, A2, A3, A4) -> R
100
- ) -> AnyMethod {
101
- return ConcreteMethod(
113
+ ) -> AnyFunction {
114
+ return ConcreteFunction(
102
115
  name,
103
- argTypes: [AnyArgumentType(A0.self), AnyArgumentType(A1.self), AnyArgumentType(A2.self), AnyArgumentType(A3.self), AnyArgumentType(A4.self)],
116
+ argTypes: [ArgumentType(A0.self), ArgumentType(A1.self), ArgumentType(A2.self), ArgumentType(A3.self), ArgumentType(A4.self)],
104
117
  closure
105
118
  )
106
119
  }
107
120
 
108
121
  /**
109
- Factory function for methods with 6 arguments.
122
+ Function with six arguments.
110
123
  */
111
- public func method<R, A0: AnyMethodArgument, A1: AnyMethodArgument, A2: AnyMethodArgument, A3: AnyMethodArgument, A4: AnyMethodArgument, A5: AnyMethodArgument>(
124
+ public func function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument, A4: AnyArgument, A5: AnyArgument>(
112
125
  _ name: String,
113
126
  _ closure: @escaping (A0, A1, A2, A3, A4, A5) -> R
114
- ) -> AnyMethod {
115
- return ConcreteMethod(
127
+ ) -> AnyFunction {
128
+ return ConcreteFunction(
116
129
  name,
117
- argTypes: [AnyArgumentType(A0.self), AnyArgumentType(A1.self), AnyArgumentType(A2.self), AnyArgumentType(A3.self), AnyArgumentType(A4.self), AnyArgumentType(A5.self)],
130
+ argTypes: [ArgumentType(A0.self), ArgumentType(A1.self), ArgumentType(A2.self), ArgumentType(A3.self), ArgumentType(A4.self), ArgumentType(A5.self)],
118
131
  closure
119
132
  )
120
133
  }
121
134
 
122
135
  /**
123
- Factory function for methods with 7 arguments.
136
+ Function with seven arguments.
124
137
  */
125
- public func method<R, A0: AnyMethodArgument, A1: AnyMethodArgument, A2: AnyMethodArgument, A3: AnyMethodArgument, A4: AnyMethodArgument, A5: AnyMethodArgument, A6: AnyMethodArgument>(
138
+ public func function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument, A4: AnyArgument, A5: AnyArgument, A6: AnyArgument>(
126
139
  _ name: String,
127
140
  _ closure: @escaping (A0, A1, A2, A3, A4, A5, A6) -> R
128
- ) -> AnyMethod {
129
- return ConcreteMethod(
141
+ ) -> AnyFunction {
142
+ return ConcreteFunction(
130
143
  name,
131
- argTypes: [AnyArgumentType(A0.self), AnyArgumentType(A1.self), AnyArgumentType(A2.self), AnyArgumentType(A3.self), AnyArgumentType(A4.self), AnyArgumentType(A5.self), AnyArgumentType(A6.self)],
144
+ argTypes: [ArgumentType(A0.self), ArgumentType(A1.self), ArgumentType(A2.self), ArgumentType(A3.self), ArgumentType(A4.self), ArgumentType(A5.self), ArgumentType(A6.self)],
132
145
  closure
133
146
  )
134
147
  }
135
148
 
136
149
  /**
137
- Factory function for methods with 8 arguments.
150
+ Function with eight arguments.
138
151
  */
139
- public func method<R, A0: AnyMethodArgument, A1: AnyMethodArgument, A2: AnyMethodArgument, A3: AnyMethodArgument, A4: AnyMethodArgument, A5: AnyMethodArgument, A6: AnyMethodArgument, A7: AnyMethodArgument>(
152
+ public func function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument, A4: AnyArgument, A5: AnyArgument, A6: AnyArgument, A7: AnyArgument>(
140
153
  _ name: String,
141
154
  _ closure: @escaping (A0, A1, A2, A3, A4, A5, A6, A7) -> R
142
- ) -> AnyMethod {
143
- return ConcreteMethod(
155
+ ) -> AnyFunction {
156
+ return ConcreteFunction(
144
157
  name,
145
- argTypes: [AnyArgumentType(A0.self), AnyArgumentType(A1.self), AnyArgumentType(A2.self), AnyArgumentType(A3.self), AnyArgumentType(A4.self), AnyArgumentType(A5.self), AnyArgumentType(A6.self), AnyArgumentType(A7.self)],
158
+ argTypes: [ArgumentType(A0.self), ArgumentType(A1.self), ArgumentType(A2.self), ArgumentType(A3.self), ArgumentType(A4.self), ArgumentType(A5.self), ArgumentType(A6.self), ArgumentType(A7.self)],
146
159
  closure
147
160
  )
148
161
  }
149
162
 
163
+ // MARK: - Module's lifecycle
164
+
150
165
  /**
151
166
  Creates module's lifecycle listener that is called right after module initialization.
152
167
  */
@@ -188,13 +203,38 @@ extension AnyModule {
188
203
  public func onAppEntersBackground(_ closure: @escaping () -> Void) -> AnyDefinition {
189
204
  return EventListener(.appEntersBackground, closure)
190
205
  }
191
- }
192
206
 
193
- /**
194
- Creates the view manager definition that scopes other view-related definitions.
195
- */
196
- public func viewManager(@ViewManagerDefinitionBuilder _ closure: @escaping () -> ViewManagerDefinition) -> AnyDefinition {
197
- return closure()
207
+ // MARK: - View Manager
208
+
209
+ /**
210
+ Creates the view manager definition that scopes other view-related definitions.
211
+ */
212
+ public func viewManager(@ViewManagerDefinitionBuilder _ closure: @escaping () -> ViewManagerDefinition) -> AnyDefinition {
213
+ return closure()
214
+ }
215
+
216
+ // MARK: - Events
217
+
218
+ /**
219
+ Defines event names that this module can send to JavaScript.
220
+ */
221
+ public func events(_ names: String...) -> AnyDefinition {
222
+ return EventsDefinition(names: names)
223
+ }
224
+
225
+ /**
226
+ Function that is invoked when the first event listener is added.
227
+ */
228
+ public func onStartObserving(_ body: @escaping () -> ()) -> AnyFunction {
229
+ return ConcreteFunction("startObserving", argTypes: [], body)
230
+ }
231
+
232
+ /**
233
+ Function that is invoked when all event listeners are removed.
234
+ */
235
+ public func onStopObserving(_ body: @escaping () -> ()) -> AnyFunction {
236
+ return ConcreteFunction("stopObserving", argTypes: [], body)
237
+ }
198
238
  }
199
239
 
200
240
  /**
@@ -207,6 +247,61 @@ public func view(_ closure: @escaping () -> UIView) -> AnyDefinition {
207
247
  /**
208
248
  Creates a view prop that defines its name and setter.
209
249
  */
210
- public func prop<ViewType: UIView, PropType>(_ name: String, _ setter: @escaping (ViewType, PropType) -> Void) -> AnyDefinition {
211
- return ConcreteViewProp(name, setter)
250
+ public func prop<ViewType: UIView, PropType: AnyArgument>(
251
+ _ name: String,
252
+ _ setter: @escaping (ViewType, PropType) -> Void
253
+ ) -> AnyDefinition {
254
+ return ConcreteViewProp(
255
+ name: name,
256
+ propType: ArgumentType(PropType.self),
257
+ setter: setter
258
+ )
259
+ }
260
+
261
+ // TODO: - Remove deprecated `method` component once SDK44 is out.
262
+ public extension AnyModule {
263
+ /**
264
+ Function without arguments.
265
+ */
266
+ @available(*, deprecated, renamed: "function")
267
+ func method<R>(
268
+ _ name: String,
269
+ _ closure: @escaping () -> R
270
+ ) -> AnyFunction {
271
+ return ConcreteFunction(
272
+ name,
273
+ argTypes: [],
274
+ closure
275
+ )
276
+ }
277
+
278
+ /**
279
+ Function with one argument.
280
+ */
281
+ @available(*, deprecated, renamed: "function")
282
+ func method<R, A0: AnyArgument>(
283
+ _ name: String,
284
+ _ closure: @escaping (A0) -> R
285
+ ) -> AnyFunction {
286
+ return ConcreteFunction(
287
+ name,
288
+ argTypes: [ArgumentType(A0.self)],
289
+ closure
290
+ )
291
+ }
292
+
293
+ /**
294
+ Function with two arguments.
295
+ */
296
+ @available(*, deprecated, renamed: "function")
297
+ func method<R, A0: AnyArgument, A1: AnyArgument>(
298
+ _ name: String,
299
+ _ closure: @escaping (A0, A1) -> R
300
+ ) -> AnyFunction {
301
+ return ConcreteFunction(
302
+ name,
303
+ argTypes: [ArgumentType(A0.self), ArgumentType(A1.self)],
304
+ closure
305
+ )
306
+ }
212
307
  }
@@ -13,6 +13,17 @@ public protocol ModulesProviderObjCProtocol {}
13
13
  */
14
14
  public protocol ModulesProviderProtocol: ModulesProviderObjCProtocol {
15
15
  func getModuleClasses() -> [AnyModule.Type]
16
+
17
+ /**
18
+ Returns an array of classes that hooks into `ExpoAppDelegate` to receive app delegate events.
19
+ */
20
+ func getAppDelegateSubscribers() -> [ExpoAppDelegateSubscriber.Type]
21
+
22
+ typealias ExpoReactDelegateHandlerTupleType = (packageName: String, handler: ExpoReactDelegateHandler.Type)
23
+ /**
24
+ Returns an array of `ExpoReactDelegateHandlerTupleType` for `ReactDelegate` to hook React instance creation.
25
+ */
26
+ func getReactDelegateHandlers() -> [ExpoReactDelegateHandlerTupleType]
16
27
  }
17
28
 
18
29
  /**
@@ -24,4 +35,12 @@ open class ModulesProvider: NSObject, ModulesProviderProtocol, ModulesProviderOb
24
35
  open func getModuleClasses() -> [AnyModule.Type] {
25
36
  return []
26
37
  }
38
+
39
+ open func getAppDelegateSubscribers() -> [ExpoAppDelegateSubscriber.Type] {
40
+ return []
41
+ }
42
+
43
+ open func getReactDelegateHandlers() -> [ExpoReactDelegateHandlerTupleType] {
44
+ return []
45
+ }
27
46
  }
@@ -1,5 +1,5 @@
1
1
 
2
- public struct Promise: AnyMethodArgument {
2
+ public struct Promise: AnyArgument {
3
3
  public typealias ResolveClosure = (Any?) -> Void
4
4
  public typealias RejectClosure = (CodedError) -> Void
5
5
 
@@ -2,7 +2,7 @@
2
2
  Property wrapper for `Record`'s data members that takes part in the process of serialization to and deserialization from the dictionary.
3
3
  */
4
4
  @propertyWrapper
5
- public class Field<Type>: AnyFieldInternal {
5
+ public final class Field<Type>: AnyFieldInternal {
6
6
  /**
7
7
  The wrapped value.
8
8
  */
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  A protocol that allows initializing the object with a dictionary.
3
3
  */
4
- public protocol Record: AnyMethodArgument {
4
+ public protocol Record: ConvertibleArgument {
5
5
  /**
6
6
  The dictionary type that the record can be created from or converted back.
7
7
  */
@@ -27,6 +27,13 @@ public protocol Record: AnyMethodArgument {
27
27
  Provides the default implementation of `Record` protocol.
28
28
  */
29
29
  public extension Record {
30
+ static func convert(from value: Any?) throws -> Self {
31
+ if let value = value as? Dict {
32
+ return try Self(from: value)
33
+ }
34
+ throw Conversions.ConvertingError<Self>(value: value)
35
+ }
36
+
30
37
  init(from dict: Dict) throws {
31
38
  self.init()
32
39
 
@@ -2,7 +2,7 @@
2
2
  import Foundation
3
3
 
4
4
  @objc
5
- public class SwiftInteropBridge: NSObject {
5
+ public final class SwiftInteropBridge: NSObject {
6
6
  let appContext: AppContext
7
7
 
8
8
  var registry: ModuleRegistry {
@@ -21,15 +21,15 @@ public class SwiftInteropBridge: NSObject {
21
21
  }
22
22
 
23
23
  @objc
24
- public func callMethod(_ methodName: String,
25
- onModule moduleName: String,
26
- withArgs args: [Any],
27
- resolve: @escaping EXPromiseResolveBlock,
28
- reject: @escaping EXPromiseRejectBlock) {
24
+ public func callFunction(_ functionName: String,
25
+ onModule moduleName: String,
26
+ withArgs args: [Any],
27
+ resolve: @escaping EXPromiseResolveBlock,
28
+ reject: @escaping EXPromiseRejectBlock) {
29
29
  registry
30
30
  .get(moduleHolderForName: moduleName)?
31
- .call(method: methodName, args: args) { value, error in
32
- if let error = error as? CodedError {
31
+ .call(function: functionName, args: args) { value, error in
32
+ if let error = error {
33
33
  reject(error.code, error.description, error)
34
34
  } else if let error = error {
35
35
  reject("ERR_UNKNOWN_ERROR", error.localizedDescription, error)
@@ -40,18 +40,24 @@ public class SwiftInteropBridge: NSObject {
40
40
  }
41
41
 
42
42
  @objc
43
- public func exportedMethodNames() -> [String: [[String: Any]]] {
43
+ public func callFunctionSync(_ functionName: String,
44
+ onModule moduleName: String,
45
+ withArgs args: [Any]) -> Any? {
46
+ return registry
47
+ .get(moduleHolderForName: moduleName)?
48
+ .callSync(function: functionName, args: args)
49
+ }
50
+
51
+ @objc
52
+ public func exportedFunctionNames() -> [String: [[String: Any]]] {
44
53
  var constants = [String: [[String: Any]]]()
45
54
 
46
55
  for holder in registry {
47
- var index = -1
48
-
49
- constants[holder.name] = holder.definition.methods.map({ (methodName, method) in
50
- index += 1
56
+ constants[holder.name] = holder.definition.functions.map({ (functionName, function) in
51
57
  return [
52
- "name": methodName,
53
- "argumentsCount": method.argumentsCount,
54
- "key": methodName,
58
+ "name": functionName,
59
+ "argumentsCount": function.argumentsCount,
60
+ "key": functionName,
55
61
  ]
56
62
  })
57
63
  }
@@ -61,7 +67,7 @@ public class SwiftInteropBridge: NSObject {
61
67
  @objc
62
68
  public func exportedModulesConstants() -> [String: Any] {
63
69
  return registry.reduce(into: [String: Any]()) { acc, holder in
64
- acc[holder.name] = holder.definition.constants
70
+ acc[holder.name] = holder.getConstants()
65
71
  }
66
72
  }
67
73
 
@@ -85,4 +91,27 @@ public class SwiftInteropBridge: NSObject {
85
91
  }
86
92
  }
87
93
  }
94
+
95
+ // MARK: - Events
96
+
97
+ /**
98
+ Returns an array of event names supported by all Swift modules.
99
+ */
100
+ @objc
101
+ public func getSupportedEvents() -> [String] {
102
+ return registry.reduce(into: [String]()) { events, holder in
103
+ events.append(contentsOf: holder.definition.eventNames)
104
+ }
105
+ }
106
+
107
+ /**
108
+ Modifies listeners count for module with given name. Depending on the listeners count,
109
+ `onStartObserving` and `onStopObserving` are called.
110
+ */
111
+ @objc
112
+ public func modifyEventListenersCount(_ moduleName: String, count: Int) {
113
+ registry
114
+ .get(moduleHolderForName: moduleName)?
115
+ .modifyListenersCount(count)
116
+ }
88
117
  }