expo-modules-core 0.8.0 → 0.9.2

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 (26) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/android/build.gradle +2 -2
  3. package/android/src/main/java/expo/modules/core/interfaces/ReactNativeHostHandler.java +11 -0
  4. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionBuilder.kt +127 -18
  5. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +210 -26
  6. package/android/src/main/java/expo/modules/kotlin/views/ViewGroupDefinitionBuilder.kt +55 -5
  7. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinitionBuilder.kt +43 -5
  8. package/ios/NativeModulesProxy/EXNativeModulesProxy.mm +3 -0
  9. package/ios/Swift/AppContext.swift +1 -8
  10. package/ios/Swift/Arguments/AnyArgumentType.swift +1 -1
  11. package/ios/Swift/Functions/AnyFunction.swift +5 -0
  12. package/ios/Swift/Functions/AsyncFunctionComponent.swift +182 -0
  13. package/ios/Swift/Functions/ConcreteFunction.swift +34 -67
  14. package/ios/Swift/Functions/SyncFunctionComponent.swift +181 -0
  15. package/ios/Swift/JavaScriptUtils.swift +51 -6
  16. package/ios/Swift/ModuleHolder.swift +11 -10
  17. package/ios/Swift/Modules/ModuleDefinitionComponents.swift +66 -44
  18. package/ios/Swift/Objects/ObjectDefinitionComponents.swift +45 -172
  19. package/ios/Swift/Views/ViewManagerDefinitionComponents.swift +23 -0
  20. package/ios/Tests/ConstantsSpec.swift +4 -4
  21. package/ios/Tests/ExpoModulesSpec.swift +3 -4
  22. package/ios/Tests/FunctionSpec.swift +11 -12
  23. package/ios/Tests/FunctionWithConvertiblesSpec.swift +2 -2
  24. package/ios/Tests/ModuleEventListenersSpec.swift +13 -13
  25. package/package.json +2 -2
  26. package/ios/Swift/Functions/AsyncFunction.swift +0 -17
@@ -1,4 +1,5 @@
1
1
  @file:OptIn(ExperimentalStdlibApi::class)
2
+ @file:Suppress("FunctionName")
2
3
 
3
4
  package expo.modules.kotlin.views
4
5
 
@@ -12,12 +13,16 @@ import kotlin.reflect.typeOf
12
13
  class ViewManagerDefinitionBuilder {
13
14
  @PublishedApi
14
15
  internal var viewFactory: ((Context) -> View)? = null
16
+
15
17
  @PublishedApi
16
18
  internal var viewType: Class<out View>? = null
19
+
17
20
  @PublishedApi
18
21
  internal var props = mutableMapOf<String, AnyViewProp>()
22
+
19
23
  @PublishedApi
20
24
  internal var onViewDestroys: ((View) -> Unit)? = null
25
+
21
26
  @PublishedApi
22
27
  internal var viewGroupDefinition: ViewGroupDefinition? = null
23
28
  private var callbacksDefinition: CallbacksDefinition? = null
@@ -32,25 +37,46 @@ class ViewManagerDefinitionBuilder {
32
37
  viewGroupDefinition
33
38
  )
34
39
 
40
+ @Deprecated(
41
+ message = "The 'view' component was renamed to 'View'.",
42
+ replaceWith = ReplaceWith("View(body)")
43
+ )
44
+ inline fun <reified ViewType : View> view(noinline body: (Context) -> ViewType) = View(body)
45
+
35
46
  /**
36
47
  * Defines the factory creating a native view when the module is used as a view.
37
48
  */
38
- inline fun <reified ViewType : View> view(noinline body: (Context) -> ViewType) {
49
+ inline fun <reified ViewType : View> View(noinline body: (Context) -> ViewType) {
39
50
  viewType = ViewType::class.java
40
51
  viewFactory = body
41
52
  }
42
53
 
54
+ @Deprecated(
55
+ message = "The 'onViewDestroys' component was renamed to 'OnViewDestroys'.",
56
+ replaceWith = ReplaceWith("OnViewDestroys(body)")
57
+ )
58
+ inline fun <reified ViewType : View> onViewDestroys(noinline body: (view: ViewType) -> Unit) = OnViewDestroys(body)
59
+
43
60
  /**
44
61
  * Creates view's lifecycle listener that is called right after the view isn't longer used by React Native.
45
62
  */
46
- inline fun <reified ViewType : View> onViewDestroys(noinline body: (view: ViewType) -> Unit) {
63
+ inline fun <reified ViewType : View> OnViewDestroys(noinline body: (view: ViewType) -> Unit) {
47
64
  onViewDestroys = { body(it as ViewType) }
48
65
  }
49
66
 
67
+ @Deprecated(
68
+ message = "The 'prop' component was renamed to 'Prop'.",
69
+ replaceWith = ReplaceWith("Prop(body)")
70
+ )
71
+ inline fun <reified ViewType : View, reified PropType> prop(
72
+ name: String,
73
+ noinline body: (view: ViewType, prop: PropType) -> Unit
74
+ ) = Prop(name, body)
75
+
50
76
  /**
51
77
  * Creates a view prop that defines its name and setter.
52
78
  */
53
- inline fun <reified ViewType : View, reified PropType> prop(
79
+ inline fun <reified ViewType : View, reified PropType> Prop(
54
80
  name: String,
55
81
  noinline body: (view: ViewType, prop: PropType) -> Unit
56
82
  ) {
@@ -61,17 +87,29 @@ class ViewManagerDefinitionBuilder {
61
87
  )
62
88
  }
63
89
 
90
+ @Deprecated(
91
+ message = "The 'events' component was renamed to 'Events'.",
92
+ replaceWith = ReplaceWith("Events(callbacks)")
93
+ )
94
+ fun events(vararg callbacks: String) = Events(*callbacks)
95
+
64
96
  /**
65
97
  * Defines prop names that should be treated as callbacks.
66
98
  */
67
- fun events(vararg callbacks: String) {
99
+ fun Events(vararg callbacks: String) {
68
100
  callbacksDefinition = CallbacksDefinition(callbacks)
69
101
  }
70
102
 
103
+ @Deprecated(
104
+ message = "The 'groupView' component was renamed to 'GroupView'.",
105
+ replaceWith = ReplaceWith("GroupView(callbacks)")
106
+ )
107
+ inline fun groupView(body: ViewGroupDefinitionBuilder.() -> Unit) = GroupView(body)
108
+
71
109
  /**
72
110
  * Creates the group view definition that scopes group view-related definitions.
73
111
  */
74
- inline fun groupView(body: ViewGroupDefinitionBuilder.() -> Unit) {
112
+ inline fun GroupView(body: ViewGroupDefinitionBuilder.() -> Unit) {
75
113
  require(viewGroupDefinition == null) { "The viewManager definition may have exported only one groupView definition." }
76
114
 
77
115
  val groupViewDefinitionBuilder = ViewGroupDefinitionBuilder()
@@ -278,6 +278,9 @@ RCT_EXPORT_METHOD(callMethod:(NSString *)moduleName methodNameOrKey:(id)methodNa
278
278
  // their base view managers that provides common props such as `proxiedProperties`.
279
279
  // Otherwise, React Native may treat these props as invalid in subclassing views.
280
280
  [additionalModuleClasses addObject:[EXViewManagerAdapter class]];
281
+ // Also, we have to register component data for the View Adapter.
282
+ // Otherwise, it won't be recognized by the UIManager.
283
+ [self registerLegacyComponentData:[EXViewManagerAdapter class] inBridge:bridge];
281
284
 
282
285
  // Some modules might need access to the bridge.
283
286
  for (id module in [_exModuleRegistry getAllInternalModules]) {
@@ -18,7 +18,7 @@ public final class AppContext {
18
18
  /**
19
19
  The legacy module registry with modules written in the old-fashioned way.
20
20
  */
21
- public private(set) var legacyModuleRegistry: EXModuleRegistry?
21
+ public private(set) weak var legacyModuleRegistry: EXModuleRegistry?
22
22
 
23
23
  /**
24
24
  React bridge of the context's app.
@@ -104,13 +104,6 @@ public final class AppContext {
104
104
  return legacyModule(implementing: EXEventEmitterService.self)
105
105
  }
106
106
 
107
- /**
108
- Provides access to the logger from legacy module registry.
109
- */
110
- public var logger: EXLogManager? {
111
- return legacyModuleRegistry?.getSingletonModule(forName: EXLogManager.name()) as? EXLogManager
112
- }
113
-
114
107
  /**
115
108
  Starts listening to `UIApplication` notifications.
116
109
  */
@@ -4,7 +4,7 @@
4
4
  A protocol whose intention is to wrap function's argument type
5
5
  to keep its real signature and not type-erase it by the compiler.
6
6
  */
7
- internal protocol AnyArgumentType: CustomStringConvertible {
7
+ public protocol AnyArgumentType: CustomStringConvertible {
8
8
  /**
9
9
  Casts given any value to the wrapped type and returns as `Any`.
10
10
  NOTE: It may not be just simple type-casting (e.g. when the wrapped type conforms to `ConvertibleArgument`).
@@ -14,6 +14,11 @@ public protocol AnyFunction: AnyDefinition {
14
14
  */
15
15
  var takesPromise: Bool { get }
16
16
 
17
+ /**
18
+ An array of argument types that the function takes. If the last type is `Promise`, it's not included.
19
+ */
20
+ var argumentTypes: [AnyArgumentType] { get }
21
+
17
22
  /**
18
23
  A number of arguments the function takes. If the last argument is of type `Promise`, it is not counted.
19
24
  */
@@ -0,0 +1,182 @@
1
+ // Copyright 2022-present 650 Industries. All rights reserved.
2
+
3
+ /**
4
+ Represents a function that can only be called asynchronously, thus its JavaScript equivalent returns a Promise.
5
+
6
+ - ToDo: Move some asynchronous logic from `ConcreteFunction` (like `call(args:promise:)`) to this class and drop the `isAsync` property.
7
+ */
8
+ internal final class AsyncFunctionComponent<Args, ReturnType>: ConcreteFunction<Args, ReturnType> {
9
+ override init(
10
+ _ name: String,
11
+ argTypes: [AnyArgumentType],
12
+ _ closure: @escaping ConcreteFunction<Args, ReturnType>.ClosureType
13
+ ) {
14
+ super.init(name, argTypes: argTypes, closure)
15
+ self.isAsync = true
16
+ }
17
+ }
18
+
19
+ /**
20
+ Asynchronous function without arguments.
21
+ */
22
+ public func AsyncFunction<R>(
23
+ _ name: String,
24
+ _ closure: @escaping () throws -> R
25
+ ) -> AnyFunction {
26
+ return AsyncFunctionComponent(
27
+ name,
28
+ argTypes: [],
29
+ closure
30
+ )
31
+ }
32
+
33
+ /**
34
+ Asynchronous function with one argument.
35
+ */
36
+ public func AsyncFunction<R, A0: AnyArgument>(
37
+ _ name: String,
38
+ _ closure: @escaping (A0) throws -> R
39
+ ) -> AnyFunction {
40
+ return AsyncFunctionComponent(
41
+ name,
42
+ argTypes: [ArgumentType(A0.self)],
43
+ closure
44
+ )
45
+ }
46
+
47
+ /**
48
+ Asynchronous function with two arguments.
49
+ */
50
+ public func AsyncFunction<R, A0: AnyArgument, A1: AnyArgument>(
51
+ _ name: String,
52
+ _ closure: @escaping (A0, A1) throws -> R
53
+ ) -> AnyFunction {
54
+ return AsyncFunctionComponent(
55
+ name,
56
+ argTypes: [ArgumentType(A0.self), ArgumentType(A1.self)],
57
+ closure
58
+ )
59
+ }
60
+
61
+ /**
62
+ Asynchronous function with three arguments.
63
+ */
64
+ public func AsyncFunction<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument>(
65
+ _ name: String,
66
+ _ closure: @escaping (A0, A1, A2) throws -> R
67
+ ) -> AnyFunction {
68
+ return AsyncFunctionComponent(
69
+ name,
70
+ argTypes: [
71
+ ArgumentType(A0.self),
72
+ ArgumentType(A1.self),
73
+ ArgumentType(A2.self)
74
+ ],
75
+ closure
76
+ )
77
+ }
78
+
79
+ /**
80
+ Asynchronous function with four arguments.
81
+ */
82
+ public func AsyncFunction<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument>(
83
+ _ name: String,
84
+ _ closure: @escaping (A0, A1, A2, A3) throws -> R
85
+ ) -> AnyFunction {
86
+ return AsyncFunctionComponent(
87
+ name,
88
+ argTypes: [
89
+ ArgumentType(A0.self),
90
+ ArgumentType(A1.self),
91
+ ArgumentType(A2.self),
92
+ ArgumentType(A3.self)
93
+ ],
94
+ closure
95
+ )
96
+ }
97
+
98
+ /**
99
+ Asynchronous function with five arguments.
100
+ */
101
+ public func AsyncFunction<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument, A4: AnyArgument>(
102
+ _ name: String,
103
+ _ closure: @escaping (A0, A1, A2, A3, A4) throws -> R
104
+ ) -> AnyFunction {
105
+ return AsyncFunctionComponent(
106
+ name,
107
+ argTypes: [
108
+ ArgumentType(A0.self),
109
+ ArgumentType(A1.self),
110
+ ArgumentType(A2.self),
111
+ ArgumentType(A3.self),
112
+ ArgumentType(A4.self)
113
+ ],
114
+ closure
115
+ )
116
+ }
117
+
118
+ /**
119
+ Asynchronous function with six arguments.
120
+ */
121
+ public func AsyncFunction<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument, A4: AnyArgument, A5: AnyArgument>(
122
+ _ name: String,
123
+ _ closure: @escaping (A0, A1, A2, A3, A4, A5) throws -> R
124
+ ) -> AnyFunction {
125
+ return AsyncFunctionComponent(
126
+ name,
127
+ argTypes: [
128
+ ArgumentType(A0.self),
129
+ ArgumentType(A1.self),
130
+ ArgumentType(A2.self),
131
+ ArgumentType(A3.self),
132
+ ArgumentType(A4.self),
133
+ ArgumentType(A5.self)
134
+ ],
135
+ closure
136
+ )
137
+ }
138
+
139
+ /**
140
+ Asynchronous function with seven arguments.
141
+ */
142
+ public func AsyncFunction<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument, A4: AnyArgument, A5: AnyArgument, A6: AnyArgument>(
143
+ _ name: String,
144
+ _ closure: @escaping (A0, A1, A2, A3, A4, A5, A6) throws -> R
145
+ ) -> AnyFunction {
146
+ return AsyncFunctionComponent(
147
+ name,
148
+ argTypes: [
149
+ ArgumentType(A0.self),
150
+ ArgumentType(A1.self),
151
+ ArgumentType(A2.self),
152
+ ArgumentType(A3.self),
153
+ ArgumentType(A4.self),
154
+ ArgumentType(A5.self),
155
+ ArgumentType(A6.self)
156
+ ],
157
+ closure
158
+ )
159
+ }
160
+
161
+ /**
162
+ Asynchronous function with eight arguments.
163
+ */
164
+ public func AsyncFunction<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument, A4: AnyArgument, A5: AnyArgument, A6: AnyArgument, A7: AnyArgument>(
165
+ _ name: String,
166
+ _ closure: @escaping (A0, A1, A2, A3, A4, A5, A6, A7) throws -> R
167
+ ) -> AnyFunction {
168
+ return AsyncFunctionComponent(
169
+ name,
170
+ argTypes: [
171
+ ArgumentType(A0.self),
172
+ ArgumentType(A1.self),
173
+ ArgumentType(A2.self),
174
+ ArgumentType(A3.self),
175
+ ArgumentType(A4.self),
176
+ ArgumentType(A5.self),
177
+ ArgumentType(A6.self),
178
+ ArgumentType(A7.self)
179
+ ],
180
+ closure
181
+ )
182
+ }
@@ -5,12 +5,10 @@ public class ConcreteFunction<Args, ReturnType>: AnyFunction {
5
5
 
6
6
  public let name: String
7
7
 
8
- public var takesPromise: Bool {
9
- return argTypes.last is PromiseArgumentType
10
- }
8
+ public var takesPromise: Bool
11
9
 
12
10
  public var argumentsCount: Int {
13
- return argTypes.count - (takesPromise ? 1 : 0)
11
+ return argumentTypes.count
14
12
  }
15
13
 
16
14
  public var queue: DispatchQueue?
@@ -19,7 +17,7 @@ public class ConcreteFunction<Args, ReturnType>: AnyFunction {
19
17
 
20
18
  let closure: ClosureType
21
19
 
22
- let argTypes: [AnyArgumentType]
20
+ public let argumentTypes: [AnyArgumentType]
23
21
 
24
22
  init(
25
23
  _ name: String,
@@ -27,28 +25,33 @@ public class ConcreteFunction<Args, ReturnType>: AnyFunction {
27
25
  _ closure: @escaping ClosureType
28
26
  ) {
29
27
  self.name = name
30
- self.argTypes = argTypes
28
+ self.takesPromise = argTypes.last is PromiseArgumentType
31
29
  self.closure = closure
32
30
 
31
+ // Drop the last argument type if it's the `Promise`.
32
+ self.argumentTypes = takesPromise ? argTypes.dropLast(1) : argTypes
33
+
33
34
  // This is temporary solution to keep backwards compatibility for existing functions — they all end with "Async".
34
35
  // `function` component that we've used so far was async by default, but we decided to replace it with `asyncFunction`
35
36
  // and make `function`s synchronous. Introduced in SDK45, can be removed in SDK46 after migrating all modules.
36
37
  self.isAsync = name.hasSuffix("Async")
37
38
  }
38
39
 
40
+ /**
41
+ Calls the function with given arguments.
42
+ - Parameters:
43
+ - args: An array of arguments to pass to the function. The arguments must be of the same type as in the underlying ``closure``.
44
+ - promise: A promise to resolve or reject by the async ``closure`` when it finishes execution.
45
+ - ToDo: Make it internal.
46
+ */
39
47
  public func call(args: [Any], promise: Promise) {
40
- let takesPromise = self.takesPromise
48
+ // Add promise to the array of arguments if necessary.
49
+ let arguments = takesPromise ? args + [promise] : args
41
50
  let returnedValue: ReturnType?
42
51
 
43
52
  do {
44
- var finalArgs = try castArguments(args)
45
-
46
- if takesPromise {
47
- finalArgs.append(promise)
48
- }
49
-
50
- let tuple = try Conversions.toTuple(finalArgs) as! Args
51
- returnedValue = try closure(tuple)
53
+ let argumentsTuple = try Conversions.toTuple(arguments) as! Args
54
+ returnedValue = try closure(argumentsTuple)
52
55
  } catch let error as CodedError {
53
56
  promise.reject(FunctionCallException(name).causedBy(error))
54
57
  return
@@ -61,28 +64,24 @@ public class ConcreteFunction<Args, ReturnType>: AnyFunction {
61
64
  }
62
65
  }
63
66
 
67
+ /**
68
+ Calls the function synchronously with given arguments.
69
+ - Parameters:
70
+ - args: An array of arguments to pass to the function. The arguments must be of the same type as in the underlying ``closure``.
71
+ - Returns: A value returned by the called function when succeeded or an error when it failed.
72
+ - ToDo: Make it internal.
73
+ */
64
74
  public func callSync(args: [Any]) -> Any {
65
75
  if takesPromise {
66
- var result: Any?
67
- let semaphore = DispatchSemaphore(value: 0)
68
-
69
- let promise = Promise {
70
- result = $0
71
- semaphore.signal()
72
- } rejecter: { _ in
73
- semaphore.signal()
74
- }
75
- call(args: args, promise: promise)
76
- semaphore.wait()
77
- return result as Any
78
- } else {
79
- do {
80
- let finalArgs = try castArguments(args)
81
- let tuple = try Conversions.toTuple(finalArgs) as! Args
82
- return try closure(tuple)
83
- } catch let error {
84
- return error
85
- }
76
+ // Using `Promise` in the synchronous function is prohibited. Probably should throw an exception here,
77
+ // but for now let's return nil until we split async and sync functions.
78
+ return Optional<Any>.none as Any
79
+ }
80
+ do {
81
+ let argumentsTuple = try Conversions.toTuple(args) as! Args
82
+ return try closure(argumentsTuple)
83
+ } catch let error {
84
+ return error
86
85
  }
87
86
  }
88
87
 
@@ -95,38 +94,6 @@ public class ConcreteFunction<Args, ReturnType>: AnyFunction {
95
94
  self.isAsync = false
96
95
  return self
97
96
  }
98
-
99
- private func argumentType(atIndex index: Int) -> AnyArgumentType? {
100
- return (0..<argTypes.count).contains(index) ? argTypes[index] : nil
101
- }
102
-
103
- private func castArguments(_ args: [Any]) throws -> [Any] {
104
- if args.count != argumentsCount {
105
- throw InvalidArgsNumberException((received: args.count, expected: argumentsCount))
106
- }
107
- return try args.enumerated().map { index, arg in
108
- let expectedType = argumentType(atIndex: index)
109
-
110
- do {
111
- // It's safe to unwrap since the arguments count matches.
112
- return try expectedType!.cast(arg)
113
- } catch {
114
- throw ArgumentCastException((index: index, type: expectedType!)).causedBy(error)
115
- }
116
- }
117
- }
118
- }
119
-
120
- internal class InvalidArgsNumberException: GenericException<(received: Int, expected: Int)> {
121
- override var reason: String {
122
- "Received \(param.received) arguments, but \(param.expected) was expected"
123
- }
124
- }
125
-
126
- internal class ArgumentCastException: GenericException<(index: Int, type: AnyArgumentType)> {
127
- override var reason: String {
128
- "Argument at index '\(param.index)' couldn't be cast to type \(param.type.description)"
129
- }
130
97
  }
131
98
 
132
99
  internal class FunctionCallException: GenericException<String> {
@@ -0,0 +1,181 @@
1
+ // Copyright 2022-present 650 Industries. All rights reserved.
2
+
3
+ /**
4
+ Represents a function that can only be called synchronously.
5
+ - ToDo: Move some synchronous logic from `ConcreteFunction` (like `call(args:)`) to this class and drop the `isAsync` property.
6
+ */
7
+ internal final class SyncFunctionComponent<Args, ReturnType>: ConcreteFunction<Args, ReturnType> {
8
+ override init(
9
+ _ name: String,
10
+ argTypes: [AnyArgumentType],
11
+ _ closure: @escaping ConcreteFunction<Args, ReturnType>.ClosureType
12
+ ) {
13
+ super.init(name, argTypes: argTypes, closure)
14
+ self.isAsync = false
15
+ }
16
+ }
17
+
18
+ /**
19
+ Synchronous function without arguments.
20
+ */
21
+ public func Function<R>(
22
+ _ name: String,
23
+ _ closure: @escaping () throws -> R
24
+ ) -> AnyFunction {
25
+ return SyncFunctionComponent(
26
+ name,
27
+ argTypes: [],
28
+ closure
29
+ )
30
+ }
31
+
32
+ /**
33
+ Synchronous function with one argument.
34
+ */
35
+ public func Function<R, A0: AnyArgument>(
36
+ _ name: String,
37
+ _ closure: @escaping (A0) throws -> R
38
+ ) -> AnyFunction {
39
+ return SyncFunctionComponent(
40
+ name,
41
+ argTypes: [ArgumentType(A0.self)],
42
+ closure
43
+ )
44
+ }
45
+
46
+ /**
47
+ Synchronous function with two arguments.
48
+ */
49
+ public func Function<R, A0: AnyArgument, A1: AnyArgument>(
50
+ _ name: String,
51
+ _ closure: @escaping (A0, A1) throws -> R
52
+ ) -> AnyFunction {
53
+ return SyncFunctionComponent(
54
+ name,
55
+ argTypes: [ArgumentType(A0.self), ArgumentType(A1.self)],
56
+ closure
57
+ )
58
+ }
59
+
60
+ /**
61
+ Synchronous function with three arguments.
62
+ */
63
+ public func Function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument>(
64
+ _ name: String,
65
+ _ closure: @escaping (A0, A1, A2) throws -> R
66
+ ) -> AnyFunction {
67
+ return SyncFunctionComponent(
68
+ name,
69
+ argTypes: [
70
+ ArgumentType(A0.self),
71
+ ArgumentType(A1.self),
72
+ ArgumentType(A2.self)
73
+ ],
74
+ closure
75
+ )
76
+ }
77
+
78
+ /**
79
+ Synchronous function with four arguments.
80
+ */
81
+ public func Function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument>(
82
+ _ name: String,
83
+ _ closure: @escaping (A0, A1, A2, A3) throws -> R
84
+ ) -> AnyFunction {
85
+ return SyncFunctionComponent(
86
+ name,
87
+ argTypes: [
88
+ ArgumentType(A0.self),
89
+ ArgumentType(A1.self),
90
+ ArgumentType(A2.self),
91
+ ArgumentType(A3.self)
92
+ ],
93
+ closure
94
+ )
95
+ }
96
+
97
+ /**
98
+ Synchronous function with five arguments.
99
+ */
100
+ public func Function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument, A4: AnyArgument>(
101
+ _ name: String,
102
+ _ closure: @escaping (A0, A1, A2, A3, A4) throws -> R
103
+ ) -> AnyFunction {
104
+ return SyncFunctionComponent(
105
+ name,
106
+ argTypes: [
107
+ ArgumentType(A0.self),
108
+ ArgumentType(A1.self),
109
+ ArgumentType(A2.self),
110
+ ArgumentType(A3.self),
111
+ ArgumentType(A4.self)
112
+ ],
113
+ closure
114
+ )
115
+ }
116
+
117
+ /**
118
+ Synchronous function with six arguments.
119
+ */
120
+ public func Function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument, A4: AnyArgument, A5: AnyArgument>(
121
+ _ name: String,
122
+ _ closure: @escaping (A0, A1, A2, A3, A4, A5) throws -> R
123
+ ) -> AnyFunction {
124
+ return SyncFunctionComponent(
125
+ name,
126
+ argTypes: [
127
+ ArgumentType(A0.self),
128
+ ArgumentType(A1.self),
129
+ ArgumentType(A2.self),
130
+ ArgumentType(A3.self),
131
+ ArgumentType(A4.self),
132
+ ArgumentType(A5.self)
133
+ ],
134
+ closure
135
+ )
136
+ }
137
+
138
+ /**
139
+ Synchronous function with seven arguments.
140
+ */
141
+ public func Function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument, A4: AnyArgument, A5: AnyArgument, A6: AnyArgument>(
142
+ _ name: String,
143
+ _ closure: @escaping (A0, A1, A2, A3, A4, A5, A6) throws -> R
144
+ ) -> AnyFunction {
145
+ return SyncFunctionComponent(
146
+ name,
147
+ argTypes: [
148
+ ArgumentType(A0.self),
149
+ ArgumentType(A1.self),
150
+ ArgumentType(A2.self),
151
+ ArgumentType(A3.self),
152
+ ArgumentType(A4.self),
153
+ ArgumentType(A5.self),
154
+ ArgumentType(A6.self)
155
+ ],
156
+ closure
157
+ )
158
+ }
159
+
160
+ /**
161
+ Synchronous function with eight arguments.
162
+ */
163
+ public func Function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument, A4: AnyArgument, A5: AnyArgument, A6: AnyArgument, A7: AnyArgument>(
164
+ _ name: String,
165
+ _ closure: @escaping (A0, A1, A2, A3, A4, A5, A6, A7) throws -> R
166
+ ) -> AnyFunction {
167
+ return SyncFunctionComponent(
168
+ name,
169
+ argTypes: [
170
+ ArgumentType(A0.self),
171
+ ArgumentType(A1.self),
172
+ ArgumentType(A2.self),
173
+ ArgumentType(A3.self),
174
+ ArgumentType(A4.self),
175
+ ArgumentType(A5.self),
176
+ ArgumentType(A6.self),
177
+ ArgumentType(A7.self)
178
+ ],
179
+ closure
180
+ )
181
+ }