expo-modules-core 0.9.2 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. package/CHANGELOG.md +33 -3
  2. package/README.md +3 -3
  3. package/android/CMakeLists.txt +163 -0
  4. package/android/build.gradle +343 -5
  5. package/android/src/main/cpp/CachedReferencesRegistry.cpp +65 -0
  6. package/android/src/main/cpp/CachedReferencesRegistry.h +80 -0
  7. package/android/src/main/cpp/Exceptions.cpp +22 -0
  8. package/android/src/main/cpp/Exceptions.h +38 -0
  9. package/android/src/main/cpp/ExpoModulesHostObject.cpp +47 -0
  10. package/android/src/main/cpp/ExpoModulesHostObject.h +32 -0
  11. package/android/src/main/cpp/JNIFunctionBody.cpp +44 -0
  12. package/android/src/main/cpp/JNIFunctionBody.h +50 -0
  13. package/android/src/main/cpp/JNIInjector.cpp +23 -0
  14. package/android/src/main/cpp/JSIInteropModuleRegistry.cpp +122 -0
  15. package/android/src/main/cpp/JSIInteropModuleRegistry.h +96 -0
  16. package/android/src/main/cpp/JSIObjectWrapper.h +33 -0
  17. package/android/src/main/cpp/JSITypeConverter.h +84 -0
  18. package/android/src/main/cpp/JavaScriptModuleObject.cpp +219 -0
  19. package/android/src/main/cpp/JavaScriptModuleObject.h +144 -0
  20. package/android/src/main/cpp/JavaScriptObject.cpp +125 -0
  21. package/android/src/main/cpp/JavaScriptObject.h +131 -0
  22. package/android/src/main/cpp/JavaScriptRuntime.cpp +127 -0
  23. package/android/src/main/cpp/JavaScriptRuntime.h +87 -0
  24. package/android/src/main/cpp/JavaScriptValue.cpp +172 -0
  25. package/android/src/main/cpp/JavaScriptValue.h +78 -0
  26. package/android/src/main/cpp/MethodMetadata.cpp +340 -0
  27. package/android/src/main/cpp/MethodMetadata.h +131 -0
  28. package/android/src/main/java/expo/modules/adapters/react/NativeModulesProxy.java +2 -0
  29. package/android/src/main/java/expo/modules/core/errors/ContextDestroyedException.kt +7 -0
  30. package/android/src/main/java/expo/modules/interfaces/permissions/Permissions.java +30 -0
  31. package/android/src/main/java/expo/modules/kotlin/AppContext.kt +98 -3
  32. package/android/src/main/java/expo/modules/kotlin/ConcatIterator.kt +18 -0
  33. package/android/src/main/java/expo/modules/kotlin/KotlinInteropModuleRegistry.kt +15 -12
  34. package/android/src/main/java/expo/modules/kotlin/ModuleHolder.kt +45 -3
  35. package/android/src/main/java/expo/modules/kotlin/activityaware/AppCompatActivityAware.kt +49 -0
  36. package/android/src/main/java/expo/modules/kotlin/activityaware/AppCompatActivityAwareHelper.kt +43 -0
  37. package/android/src/main/java/expo/modules/kotlin/activityaware/OnActivityAvailableListener.kt +18 -0
  38. package/android/src/main/java/expo/modules/kotlin/activityresult/ActivityResultsManager.kt +99 -0
  39. package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultCaller.kt +25 -0
  40. package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultContract.kt +27 -0
  41. package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultFallbackCallback.kt +17 -0
  42. package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultLauncher.kt +30 -0
  43. package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultRegistry.kt +358 -0
  44. package/android/src/main/java/expo/modules/kotlin/activityresult/DataPersistor.kt +135 -0
  45. package/android/src/main/java/expo/modules/kotlin/defaultmodules/ErrorManagerModule.kt +2 -2
  46. package/android/src/main/java/expo/modules/kotlin/exception/CodedException.kt +13 -0
  47. package/android/src/main/java/expo/modules/kotlin/exception/ExceptionDecorator.kt +2 -0
  48. package/android/src/main/java/expo/modules/kotlin/functions/AnyFunction.kt +53 -15
  49. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunction.kt +35 -7
  50. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionBuilder.kt +13 -121
  51. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionComponent.kt +21 -0
  52. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromiseComponent.kt +21 -0
  53. package/android/src/main/java/expo/modules/kotlin/functions/SuspendFunctionComponent.kt +63 -0
  54. package/android/src/main/java/expo/modules/kotlin/functions/SyncFunctionComponent.kt +36 -0
  55. package/android/src/main/java/expo/modules/kotlin/jni/CppType.kt +19 -0
  56. package/android/src/main/java/expo/modules/kotlin/jni/JNIFunctionBody.kt +39 -0
  57. package/android/src/main/java/expo/modules/kotlin/jni/JSIInteropModuleRegistry.kt +89 -0
  58. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptModuleObject.kt +46 -0
  59. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptObject.kt +113 -0
  60. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptValue.kt +35 -0
  61. package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +16 -6
  62. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +5 -500
  63. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionData.kt +30 -5
  64. package/android/src/main/java/expo/modules/kotlin/objects/ObjectDefinitionBuilder.kt +271 -0
  65. package/android/src/main/java/expo/modules/kotlin/objects/ObjectDefinitionData.kt +21 -0
  66. package/android/src/main/java/expo/modules/kotlin/objects/PropertyComponent.kt +54 -0
  67. package/android/src/main/java/expo/modules/kotlin/objects/PropertyComponentBuilder.kt +32 -0
  68. package/android/src/main/java/expo/modules/kotlin/providers/AppContextProvider.kt +14 -0
  69. package/android/src/main/java/expo/modules/kotlin/providers/CurrentActivityProvider.kt +22 -0
  70. package/android/src/main/java/expo/modules/kotlin/records/RecordTypeConverter.kt +19 -2
  71. package/android/src/main/java/expo/modules/kotlin/types/AnyType.kt +3 -2
  72. package/android/src/main/java/expo/modules/kotlin/types/AnyTypeConverter.kt +36 -0
  73. package/android/src/main/java/expo/modules/kotlin/types/ArrayTypeConverter.kt +7 -2
  74. package/android/src/main/java/expo/modules/kotlin/types/BasicTypeConverters.kt +68 -20
  75. package/android/src/main/java/expo/modules/kotlin/types/EnumTypeConverter.kt +50 -22
  76. package/android/src/main/java/expo/modules/kotlin/types/ListTypeConverter.kt +18 -2
  77. package/android/src/main/java/expo/modules/kotlin/types/MapTypeConverter.kt +18 -2
  78. package/android/src/main/java/expo/modules/kotlin/types/PairTypeConverter.kt +17 -2
  79. package/android/src/main/java/expo/modules/kotlin/types/TypeConverter.kt +43 -3
  80. package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +12 -0
  81. package/android/src/main/java/expo/modules/kotlin/views/ViewGroupDefinitionBuilder.kt +0 -41
  82. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinitionBuilder.kt +0 -33
  83. package/build/NativeModulesProxy.native.d.ts.map +1 -1
  84. package/build/NativeModulesProxy.native.js +9 -3
  85. package/build/NativeModulesProxy.native.js.map +1 -1
  86. package/build/PermissionsInterface.d.ts +29 -0
  87. package/build/PermissionsInterface.d.ts.map +1 -1
  88. package/build/PermissionsInterface.js +9 -0
  89. package/build/PermissionsInterface.js.map +1 -1
  90. package/ios/AppDelegates/EXAppDelegatesLoader.m +1 -2
  91. package/ios/ExpoModulesCore.podspec +3 -2
  92. package/ios/JSI/EXJSIConversions.mm +6 -0
  93. package/ios/JSI/EXJSIInstaller.h +15 -21
  94. package/ios/JSI/EXJSIInstaller.mm +39 -3
  95. package/ios/JSI/EXJSIUtils.h +48 -3
  96. package/ios/JSI/EXJSIUtils.mm +88 -4
  97. package/ios/JSI/EXJavaScriptObject.h +11 -18
  98. package/ios/JSI/EXJavaScriptObject.mm +37 -18
  99. package/ios/JSI/EXJavaScriptRuntime.h +43 -9
  100. package/ios/JSI/EXJavaScriptRuntime.mm +70 -27
  101. package/ios/JSI/EXJavaScriptTypedArray.h +30 -0
  102. package/ios/JSI/EXJavaScriptTypedArray.mm +29 -0
  103. package/ios/JSI/EXJavaScriptValue.h +3 -2
  104. package/ios/JSI/EXJavaScriptValue.mm +17 -20
  105. package/ios/JSI/EXJavaScriptWeakObject.h +23 -0
  106. package/ios/JSI/EXJavaScriptWeakObject.mm +53 -0
  107. package/ios/JSI/EXObjectDeallocator.h +27 -0
  108. package/ios/JSI/ExpoModulesHostObject.h +3 -3
  109. package/ios/JSI/ExpoModulesHostObject.mm +4 -4
  110. package/ios/JSI/JavaScriptRuntime.swift +38 -1
  111. package/ios/JSI/JavaScriptValue.swift +7 -0
  112. package/ios/JSI/TypedArray.cpp +67 -0
  113. package/ios/JSI/TypedArray.h +46 -0
  114. package/ios/ModuleRegistryAdapter/EXModuleRegistryAdapter.m +0 -11
  115. package/ios/NativeModulesProxy/EXNativeModulesProxy.h +17 -10
  116. package/ios/NativeModulesProxy/EXNativeModulesProxy.mm +86 -77
  117. package/ios/NativeModulesProxy/NativeModulesProxyModule.swift +17 -0
  118. package/ios/Services/EXReactNativeEventEmitter.h +2 -2
  119. package/ios/Services/EXReactNativeEventEmitter.m +11 -6
  120. package/ios/Swift/AppContext.swift +206 -28
  121. package/ios/Swift/Arguments/AnyArgument.swift +18 -0
  122. package/ios/Swift/Arguments/{Types/EnumArgumentType.swift → EnumArgument.swift} +2 -17
  123. package/ios/Swift/Classes/ClassComponent.swift +95 -0
  124. package/ios/Swift/Classes/ClassComponentElement.swift +33 -0
  125. package/ios/Swift/Classes/ClassComponentElementsBuilder.swift +34 -0
  126. package/ios/Swift/Classes/ClassComponentFactories.swift +96 -0
  127. package/ios/Swift/DynamicTypes/AnyDynamicType.swift +44 -0
  128. package/ios/Swift/DynamicTypes/DynamicArrayType.swift +56 -0
  129. package/ios/Swift/DynamicTypes/DynamicConvertibleType.swift +27 -0
  130. package/ios/Swift/DynamicTypes/DynamicEnumType.swift +27 -0
  131. package/ios/Swift/DynamicTypes/DynamicOptionalType.swift +63 -0
  132. package/ios/Swift/DynamicTypes/DynamicRawType.swift +33 -0
  133. package/ios/Swift/DynamicTypes/DynamicSharedObjectType.swift +37 -0
  134. package/ios/Swift/DynamicTypes/DynamicType.swift +39 -0
  135. package/ios/Swift/DynamicTypes/DynamicTypedArrayType.swift +46 -0
  136. package/ios/Swift/Exceptions/ChainableException.swift +3 -3
  137. package/ios/Swift/Exceptions/CodedError.swift +1 -1
  138. package/ios/Swift/Exceptions/Exception.swift +8 -6
  139. package/ios/Swift/Exceptions/UnexpectedException.swift +2 -1
  140. package/ios/Swift/ExpoBridgeModule.m +5 -0
  141. package/ios/Swift/ExpoBridgeModule.swift +79 -0
  142. package/ios/Swift/Functions/AnyFunction.swift +33 -31
  143. package/ios/Swift/Functions/AsyncFunctionComponent.swift +196 -59
  144. package/ios/Swift/Functions/SyncFunctionComponent.swift +142 -58
  145. package/ios/Swift/JavaScriptUtils.swift +32 -57
  146. package/ios/Swift/Logging/LogHandlers.swift +39 -0
  147. package/ios/Swift/Logging/LogType.swift +62 -0
  148. package/ios/Swift/Logging/Logger.swift +201 -0
  149. package/ios/Swift/ModuleHolder.swift +19 -54
  150. package/ios/Swift/ModuleRegistry.swift +7 -1
  151. package/ios/Swift/Modules/AnyModule.swift +3 -3
  152. package/ios/Swift/ModulesProvider.swift +2 -0
  153. package/ios/Swift/Objects/JavaScriptObjectBuilder.swift +37 -0
  154. package/ios/Swift/Objects/ObjectDefinition.swift +74 -1
  155. package/ios/Swift/Objects/ObjectDefinitionComponents.swift +77 -68
  156. package/ios/Swift/Objects/PropertyComponent.swift +147 -0
  157. package/ios/Swift/Promise.swift +17 -4
  158. package/ios/Swift/Records/Field.swift +2 -2
  159. package/ios/Swift/SharedObjects/SharedObject.swift +20 -0
  160. package/ios/Swift/SharedObjects/SharedObjectRegistry.swift +129 -0
  161. package/ios/Swift/TypedArrays/AnyTypedArray.swift +11 -0
  162. package/ios/Swift/TypedArrays/ConcreteTypedArrays.swift +56 -0
  163. package/ios/Swift/TypedArrays/GenericTypedArray.swift +49 -0
  164. package/ios/Swift/TypedArrays/TypedArray.swift +80 -0
  165. package/ios/Swift/Utilities.swift +28 -0
  166. package/ios/Swift/Views/ConcreteViewProp.swift +3 -3
  167. package/ios/Swift/Views/ViewManagerDefinitionComponents.swift +2 -2
  168. package/ios/Tests/ClassComponentSpec.swift +210 -0
  169. package/ios/Tests/DynamicTypeSpec.swift +336 -0
  170. package/ios/Tests/EnumArgumentSpec.swift +48 -0
  171. package/ios/Tests/ExpoModulesSpec.swift +17 -3
  172. package/ios/Tests/FunctionSpec.swift +167 -118
  173. package/ios/Tests/Mocks/ModuleMocks.swift +1 -1
  174. package/ios/Tests/PropertyComponentSpec.swift +95 -0
  175. package/ios/Tests/SharedObjectRegistrySpec.swift +109 -0
  176. package/ios/Tests/TypedArraysSpec.swift +136 -0
  177. package/package.json +2 -2
  178. package/src/NativeModulesProxy.native.ts +13 -3
  179. package/src/PermissionsInterface.ts +29 -0
  180. package/src/ts-declarations/ExpoModules.d.ts +7 -0
  181. package/tsconfig.json +1 -1
  182. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromise.kt +0 -15
  183. package/android/src/main/java/expo/modules/kotlin/functions/AsyncSuspendFunction.kt +0 -36
  184. package/ios/Swift/Arguments/AnyArgumentType.swift +0 -13
  185. package/ios/Swift/Arguments/ArgumentType.swift +0 -28
  186. package/ios/Swift/Arguments/Types/ArrayArgumentType.swift +0 -42
  187. package/ios/Swift/Arguments/Types/ConvertibleArgumentType.swift +0 -16
  188. package/ios/Swift/Arguments/Types/OptionalArgumentType.swift +0 -49
  189. package/ios/Swift/Arguments/Types/PromiseArgumentType.swift +0 -15
  190. package/ios/Swift/Arguments/Types/RawArgumentType.swift +0 -25
  191. package/ios/Swift/Functions/ConcreteFunction.swift +0 -103
  192. package/ios/Swift/SwiftInteropBridge.swift +0 -155
  193. package/ios/Tests/ArgumentTypeSpec.swift +0 -143
@@ -1,31 +1,160 @@
1
1
  // Copyright 2022-present 650 Industries. All rights reserved.
2
2
 
3
+ import Dispatch
4
+
3
5
  /**
4
- Represents a function that can only be called asynchronously, thus its JavaScript equivalent returns a Promise.
6
+ Type-erased protocol for asynchronous functions.
7
+ */
8
+ internal protocol AnyAsyncFunctionComponent: AnyFunction {
9
+ /**
10
+ Specifies on which queue the function should run.
11
+ */
12
+ func runOnQueue(_ queue: DispatchQueue?) -> Self
13
+ }
5
14
 
6
- - ToDo: Move some asynchronous logic from `ConcreteFunction` (like `call(args:promise:)`) to this class and drop the `isAsync` property.
15
+ /**
16
+ Represents a function that can only be called asynchronously, thus its JavaScript equivalent returns a Promise.
7
17
  */
8
- internal final class AsyncFunctionComponent<Args, ReturnType>: ConcreteFunction<Args, ReturnType> {
9
- override init(
18
+ public final class AsyncFunctionComponent<Args, FirstArgType, ReturnType>: AnyAsyncFunctionComponent {
19
+ typealias ClosureType = (Args) throws -> ReturnType
20
+
21
+ /**
22
+ The underlying closure to run when the function is called.
23
+ */
24
+ let body: ClosureType
25
+
26
+ /**
27
+ Bool value indicating whether the function takes promise as the last argument.
28
+ */
29
+ let takesPromise: Bool
30
+
31
+ /**
32
+ Dispatch queue on which each function's call is run.
33
+ */
34
+ var queue: DispatchQueue?
35
+
36
+ init(
10
37
  _ name: String,
11
- argTypes: [AnyArgumentType],
12
- _ closure: @escaping ConcreteFunction<Args, ReturnType>.ClosureType
38
+ firstArgType: FirstArgType.Type,
39
+ dynamicArgumentTypes: [AnyDynamicType],
40
+ _ body: @escaping ClosureType
13
41
  ) {
14
- super.init(name, argTypes: argTypes, closure)
15
- self.isAsync = true
42
+ self.name = name
43
+ self.takesPromise = dynamicArgumentTypes.last?.wraps(Promise.self) ?? false
44
+ self.body = body
45
+
46
+ // Drop the last argument type if it's the `Promise`.
47
+ self.dynamicArgumentTypes = takesPromise ? dynamicArgumentTypes.dropLast(1) : dynamicArgumentTypes
48
+ }
49
+
50
+ // MARK: - AnyFunction
51
+
52
+ let name: String
53
+
54
+ let dynamicArgumentTypes: [AnyDynamicType]
55
+
56
+ var argumentsCount: Int {
57
+ return dynamicArgumentTypes.count - (takesOwner ? 1 : 0)
58
+ }
59
+
60
+ var takesOwner: Bool = false
61
+
62
+ func call(by owner: AnyObject?, withArguments args: [Any], callback: @escaping (FunctionCallResult) -> ()) {
63
+ let promise = Promise { value in
64
+ callback(.success(value as Any))
65
+ } rejecter: { exception in
66
+ callback(.failure(exception))
67
+ }
68
+ var arguments: [Any] = []
69
+
70
+ do {
71
+ arguments = concat(
72
+ arguments: try cast(arguments: args, forFunction: self),
73
+ withOwner: owner,
74
+ forFunction: self
75
+ )
76
+ } catch let error as Exception {
77
+ callback(.failure(error))
78
+ return
79
+ } catch {
80
+ callback(.failure(UnexpectedException(error)))
81
+ return
82
+ }
83
+
84
+ // Add promise to the array of arguments if necessary.
85
+ if takesPromise {
86
+ arguments.append(promise)
87
+ }
88
+
89
+ let queue = queue ?? DispatchQueue.global(qos: .default)
90
+
91
+ queue.async { [body, name] in
92
+ let returnedValue: ReturnType?
93
+
94
+ do {
95
+ let argumentsTuple = try Conversions.toTuple(arguments) as! Args
96
+ returnedValue = try body(argumentsTuple)
97
+ } catch let error as Exception {
98
+ promise.reject(FunctionCallException(name).causedBy(error))
99
+ return
100
+ } catch {
101
+ promise.reject(UnexpectedException(error))
102
+ return
103
+ }
104
+ if !self.takesPromise {
105
+ promise.resolve(returnedValue)
106
+ }
107
+ }
108
+ }
109
+
110
+ // MARK: - JavaScriptObjectBuilder
111
+
112
+ func build(inRuntime runtime: JavaScriptRuntime) -> JavaScriptObject {
113
+ return runtime.createAsyncFunction(name, argsCount: argumentsCount) { [weak self, name] this, args, resolve, reject in
114
+ guard let self = self else {
115
+ let exception = NativeFunctionUnavailableException(name)
116
+ return reject(exception.code, exception.description, nil)
117
+ }
118
+ self.call(by: this, withArguments: args) { result in
119
+ switch result {
120
+ case .failure(let error):
121
+ reject(error.code, error.description, nil)
122
+ case .success(let value):
123
+ resolve(value)
124
+ }
125
+ }
126
+ }
127
+ }
128
+
129
+ // MARK: - AnyAsyncFunctionComponent
130
+
131
+ public func runOnQueue(_ queue: DispatchQueue?) -> Self {
132
+ self.queue = queue
133
+ return self
134
+ }
135
+ }
136
+
137
+ // MARK: - Exceptions
138
+
139
+ internal final class NativeFunctionUnavailableException: GenericException<String> {
140
+ override var reason: String {
141
+ return "Native function '\(param)' is no longer available in memory"
16
142
  }
17
143
  }
18
144
 
145
+ // MARK: - Factories
146
+
19
147
  /**
20
148
  Asynchronous function without arguments.
21
149
  */
22
150
  public func AsyncFunction<R>(
23
151
  _ name: String,
24
152
  _ closure: @escaping () throws -> R
25
- ) -> AnyFunction {
153
+ ) -> AsyncFunctionComponent<(), Void, R> {
26
154
  return AsyncFunctionComponent(
27
155
  name,
28
- argTypes: [],
156
+ firstArgType: Void.self,
157
+ dynamicArgumentTypes: [],
29
158
  closure
30
159
  )
31
160
  }
@@ -36,10 +165,11 @@ public func AsyncFunction<R>(
36
165
  public func AsyncFunction<R, A0: AnyArgument>(
37
166
  _ name: String,
38
167
  _ closure: @escaping (A0) throws -> R
39
- ) -> AnyFunction {
168
+ ) -> AsyncFunctionComponent<(A0), A0, R> {
40
169
  return AsyncFunctionComponent(
41
170
  name,
42
- argTypes: [ArgumentType(A0.self)],
171
+ firstArgType: A0.self,
172
+ dynamicArgumentTypes: [~A0.self],
43
173
  closure
44
174
  )
45
175
  }
@@ -50,10 +180,11 @@ public func AsyncFunction<R, A0: AnyArgument>(
50
180
  public func AsyncFunction<R, A0: AnyArgument, A1: AnyArgument>(
51
181
  _ name: String,
52
182
  _ closure: @escaping (A0, A1) throws -> R
53
- ) -> AnyFunction {
183
+ ) -> AsyncFunctionComponent<(A0, A1), A0, R> {
54
184
  return AsyncFunctionComponent(
55
185
  name,
56
- argTypes: [ArgumentType(A0.self), ArgumentType(A1.self)],
186
+ firstArgType: A0.self,
187
+ dynamicArgumentTypes: [~A0.self, ~A1.self],
57
188
  closure
58
189
  )
59
190
  }
@@ -64,13 +195,14 @@ public func AsyncFunction<R, A0: AnyArgument, A1: AnyArgument>(
64
195
  public func AsyncFunction<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument>(
65
196
  _ name: String,
66
197
  _ closure: @escaping (A0, A1, A2) throws -> R
67
- ) -> AnyFunction {
198
+ ) -> AsyncFunctionComponent<(A0, A1, A2), A0, R> {
68
199
  return AsyncFunctionComponent(
69
200
  name,
70
- argTypes: [
71
- ArgumentType(A0.self),
72
- ArgumentType(A1.self),
73
- ArgumentType(A2.self)
201
+ firstArgType: A0.self,
202
+ dynamicArgumentTypes: [
203
+ ~A0.self,
204
+ ~A1.self,
205
+ ~A2.self
74
206
  ],
75
207
  closure
76
208
  )
@@ -82,14 +214,15 @@ public func AsyncFunction<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument>(
82
214
  public func AsyncFunction<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument>(
83
215
  _ name: String,
84
216
  _ closure: @escaping (A0, A1, A2, A3) throws -> R
85
- ) -> AnyFunction {
217
+ ) -> AsyncFunctionComponent<(A0, A1, A2, A3), A0, R> {
86
218
  return AsyncFunctionComponent(
87
219
  name,
88
- argTypes: [
89
- ArgumentType(A0.self),
90
- ArgumentType(A1.self),
91
- ArgumentType(A2.self),
92
- ArgumentType(A3.self)
220
+ firstArgType: A0.self,
221
+ dynamicArgumentTypes: [
222
+ ~A0.self,
223
+ ~A1.self,
224
+ ~A2.self,
225
+ ~A3.self
93
226
  ],
94
227
  closure
95
228
  )
@@ -101,15 +234,16 @@ public func AsyncFunction<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument,
101
234
  public func AsyncFunction<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument, A4: AnyArgument>(
102
235
  _ name: String,
103
236
  _ closure: @escaping (A0, A1, A2, A3, A4) throws -> R
104
- ) -> AnyFunction {
237
+ ) -> AsyncFunctionComponent<(A0, A1, A2, A3, A4), A0, R> {
105
238
  return AsyncFunctionComponent(
106
239
  name,
107
- argTypes: [
108
- ArgumentType(A0.self),
109
- ArgumentType(A1.self),
110
- ArgumentType(A2.self),
111
- ArgumentType(A3.self),
112
- ArgumentType(A4.self)
240
+ firstArgType: A0.self,
241
+ dynamicArgumentTypes: [
242
+ ~A0.self,
243
+ ~A1.self,
244
+ ~A2.self,
245
+ ~A3.self,
246
+ ~A4.self
113
247
  ],
114
248
  closure
115
249
  )
@@ -121,16 +255,17 @@ public func AsyncFunction<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument,
121
255
  public func AsyncFunction<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument, A4: AnyArgument, A5: AnyArgument>(
122
256
  _ name: String,
123
257
  _ closure: @escaping (A0, A1, A2, A3, A4, A5) throws -> R
124
- ) -> AnyFunction {
258
+ ) -> AsyncFunctionComponent<(A0, A1, A2, A3, A4, A5), A0, R> {
125
259
  return AsyncFunctionComponent(
126
260
  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)
261
+ firstArgType: A0.self,
262
+ dynamicArgumentTypes: [
263
+ ~A0.self,
264
+ ~A1.self,
265
+ ~A2.self,
266
+ ~A3.self,
267
+ ~A4.self,
268
+ ~A5.self
134
269
  ],
135
270
  closure
136
271
  )
@@ -142,17 +277,18 @@ public func AsyncFunction<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument,
142
277
  public func AsyncFunction<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument, A4: AnyArgument, A5: AnyArgument, A6: AnyArgument>(
143
278
  _ name: String,
144
279
  _ closure: @escaping (A0, A1, A2, A3, A4, A5, A6) throws -> R
145
- ) -> AnyFunction {
280
+ ) -> AsyncFunctionComponent<(A0, A1, A2, A3, A4, A5, A6), A0, R> {
146
281
  return AsyncFunctionComponent(
147
282
  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)
283
+ firstArgType: A0.self,
284
+ dynamicArgumentTypes: [
285
+ ~A0.self,
286
+ ~A1.self,
287
+ ~A2.self,
288
+ ~A3.self,
289
+ ~A4.self,
290
+ ~A5.self,
291
+ ~A6.self
156
292
  ],
157
293
  closure
158
294
  )
@@ -164,18 +300,19 @@ public func AsyncFunction<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument,
164
300
  public func AsyncFunction<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument, A4: AnyArgument, A5: AnyArgument, A6: AnyArgument, A7: AnyArgument>(
165
301
  _ name: String,
166
302
  _ closure: @escaping (A0, A1, A2, A3, A4, A5, A6, A7) throws -> R
167
- ) -> AnyFunction {
303
+ ) -> AsyncFunctionComponent<(A0, A1, A2, A3, A4, A5, A6, A7), A0, R> {
168
304
  return AsyncFunctionComponent(
169
305
  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)
306
+ firstArgType: A0.self,
307
+ dynamicArgumentTypes: [
308
+ ~A0.self,
309
+ ~A1.self,
310
+ ~A2.self,
311
+ ~A3.self,
312
+ ~A4.self,
313
+ ~A5.self,
314
+ ~A6.self,
315
+ ~A7.self
179
316
  ],
180
317
  closure
181
318
  )
@@ -1,17 +1,92 @@
1
1
  // Copyright 2022-present 650 Industries. All rights reserved.
2
2
 
3
+ /**
4
+ Type-erased protocol for synchronous functions.
5
+ */
6
+ internal protocol AnySyncFunctionComponent: AnyFunction {
7
+ /**
8
+ Calls the function synchronously with given arguments.
9
+ - Parameters:
10
+ - owner: An object that calls this function. If the `takesOwner` property is true
11
+ and type of the first argument matches the owner type, it's being passed as the argument.
12
+ - args: An array of arguments to pass to the function. The arguments must be of the same type as in the underlying closure.
13
+ - Returns: A value returned by the called function when succeeded or an error when it failed.
14
+ */
15
+ func call(by owner: AnyObject?, withArguments args: [Any]) throws -> Any
16
+ }
17
+
3
18
  /**
4
19
  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
20
  */
7
- internal final class SyncFunctionComponent<Args, ReturnType>: ConcreteFunction<Args, ReturnType> {
8
- override init(
21
+ public final class SyncFunctionComponent<Args, FirstArgType, ReturnType>: AnySyncFunctionComponent {
22
+ typealias ClosureType = (Args) throws -> ReturnType
23
+
24
+ /**
25
+ The underlying closure to run when the function is called.
26
+ */
27
+ let body: ClosureType
28
+
29
+ init(
9
30
  _ name: String,
10
- argTypes: [AnyArgumentType],
11
- _ closure: @escaping ConcreteFunction<Args, ReturnType>.ClosureType
31
+ firstArgType: FirstArgType.Type,
32
+ dynamicArgumentTypes: [AnyDynamicType],
33
+ _ body: @escaping ClosureType
12
34
  ) {
13
- super.init(name, argTypes: argTypes, closure)
14
- self.isAsync = false
35
+ self.name = name
36
+ self.dynamicArgumentTypes = dynamicArgumentTypes
37
+ self.body = body
38
+ }
39
+
40
+ // MARK: - AnyFunction
41
+
42
+ let name: String
43
+
44
+ let dynamicArgumentTypes: [AnyDynamicType]
45
+
46
+ var argumentsCount: Int {
47
+ return dynamicArgumentTypes.count - (takesOwner ? 1 : 0)
48
+ }
49
+
50
+ var takesOwner: Bool = false
51
+
52
+ func call(by owner: AnyObject?, withArguments args: [Any], callback: @escaping (FunctionCallResult) -> ()) {
53
+ do {
54
+ let result = try call(by: owner, withArguments: args)
55
+ callback(.success(result))
56
+ } catch let error as Exception {
57
+ callback(.failure(error))
58
+ } catch {
59
+ callback(.failure(UnexpectedException(error)))
60
+ }
61
+ }
62
+
63
+ // MARK: - AnySyncFunctionComponent
64
+
65
+ func call(by owner: AnyObject?, withArguments args: [Any]) throws -> Any {
66
+ do {
67
+ let arguments = concat(
68
+ arguments: try cast(arguments: args, forFunction: self),
69
+ withOwner: owner,
70
+ forFunction: self
71
+ )
72
+ let argumentsTuple = try Conversions.toTuple(arguments) as! Args
73
+ return try body(argumentsTuple)
74
+ } catch let error as Exception {
75
+ throw FunctionCallException(name).causedBy(error)
76
+ } catch {
77
+ throw UnexpectedException(error)
78
+ }
79
+ }
80
+
81
+ // MARK: - JavaScriptObjectBuilder
82
+
83
+ func build(inRuntime runtime: JavaScriptRuntime) -> JavaScriptObject {
84
+ return runtime.createSyncFunction(name, argsCount: argumentsCount) { [weak self, name] this, args in
85
+ guard let self = self else {
86
+ throw NativeFunctionUnavailableException(name)
87
+ }
88
+ return try self.call(by: this, withArguments: args)
89
+ }
15
90
  }
16
91
  }
17
92
 
@@ -21,10 +96,11 @@ internal final class SyncFunctionComponent<Args, ReturnType>: ConcreteFunction<A
21
96
  public func Function<R>(
22
97
  _ name: String,
23
98
  _ closure: @escaping () throws -> R
24
- ) -> AnyFunction {
99
+ ) -> SyncFunctionComponent<(), Void, R> {
25
100
  return SyncFunctionComponent(
26
101
  name,
27
- argTypes: [],
102
+ firstArgType: Void.self,
103
+ dynamicArgumentTypes: [],
28
104
  closure
29
105
  )
30
106
  }
@@ -35,10 +111,11 @@ public func Function<R>(
35
111
  public func Function<R, A0: AnyArgument>(
36
112
  _ name: String,
37
113
  _ closure: @escaping (A0) throws -> R
38
- ) -> AnyFunction {
114
+ ) -> SyncFunctionComponent<(A0), A0, R> {
39
115
  return SyncFunctionComponent(
40
116
  name,
41
- argTypes: [ArgumentType(A0.self)],
117
+ firstArgType: A0.self,
118
+ dynamicArgumentTypes: [~A0.self],
42
119
  closure
43
120
  )
44
121
  }
@@ -49,10 +126,11 @@ public func Function<R, A0: AnyArgument>(
49
126
  public func Function<R, A0: AnyArgument, A1: AnyArgument>(
50
127
  _ name: String,
51
128
  _ closure: @escaping (A0, A1) throws -> R
52
- ) -> AnyFunction {
129
+ ) -> SyncFunctionComponent<(A0, A1), A0, R> {
53
130
  return SyncFunctionComponent(
54
131
  name,
55
- argTypes: [ArgumentType(A0.self), ArgumentType(A1.self)],
132
+ firstArgType: A0.self,
133
+ dynamicArgumentTypes: [~A0.self, ~A1.self],
56
134
  closure
57
135
  )
58
136
  }
@@ -63,13 +141,14 @@ public func Function<R, A0: AnyArgument, A1: AnyArgument>(
63
141
  public func Function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument>(
64
142
  _ name: String,
65
143
  _ closure: @escaping (A0, A1, A2) throws -> R
66
- ) -> AnyFunction {
144
+ ) -> SyncFunctionComponent<(A0, A1, A2), A0, R> {
67
145
  return SyncFunctionComponent(
68
146
  name,
69
- argTypes: [
70
- ArgumentType(A0.self),
71
- ArgumentType(A1.self),
72
- ArgumentType(A2.self)
147
+ firstArgType: A0.self,
148
+ dynamicArgumentTypes: [
149
+ ~A0.self,
150
+ ~A1.self,
151
+ ~A2.self
73
152
  ],
74
153
  closure
75
154
  )
@@ -81,14 +160,15 @@ public func Function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument>(
81
160
  public func Function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument>(
82
161
  _ name: String,
83
162
  _ closure: @escaping (A0, A1, A2, A3) throws -> R
84
- ) -> AnyFunction {
163
+ ) -> SyncFunctionComponent<(A0, A1, A2, A3), A0, R> {
85
164
  return SyncFunctionComponent(
86
165
  name,
87
- argTypes: [
88
- ArgumentType(A0.self),
89
- ArgumentType(A1.self),
90
- ArgumentType(A2.self),
91
- ArgumentType(A3.self)
166
+ firstArgType: A0.self,
167
+ dynamicArgumentTypes: [
168
+ ~A0.self,
169
+ ~A1.self,
170
+ ~A2.self,
171
+ ~A3.self
92
172
  ],
93
173
  closure
94
174
  )
@@ -100,15 +180,16 @@ public func Function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: A
100
180
  public func Function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument, A4: AnyArgument>(
101
181
  _ name: String,
102
182
  _ closure: @escaping (A0, A1, A2, A3, A4) throws -> R
103
- ) -> AnyFunction {
183
+ ) -> SyncFunctionComponent<(A0, A1, A2, A3, A4), A0, R> {
104
184
  return SyncFunctionComponent(
105
185
  name,
106
- argTypes: [
107
- ArgumentType(A0.self),
108
- ArgumentType(A1.self),
109
- ArgumentType(A2.self),
110
- ArgumentType(A3.self),
111
- ArgumentType(A4.self)
186
+ firstArgType: A0.self,
187
+ dynamicArgumentTypes: [
188
+ ~A0.self,
189
+ ~A1.self,
190
+ ~A2.self,
191
+ ~A3.self,
192
+ ~A4.self
112
193
  ],
113
194
  closure
114
195
  )
@@ -120,16 +201,17 @@ public func Function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: A
120
201
  public func Function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument, A4: AnyArgument, A5: AnyArgument>(
121
202
  _ name: String,
122
203
  _ closure: @escaping (A0, A1, A2, A3, A4, A5) throws -> R
123
- ) -> AnyFunction {
204
+ ) -> SyncFunctionComponent<(A0, A1, A2, A3, A4, A5), A0, R> {
124
205
  return SyncFunctionComponent(
125
206
  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)
207
+ firstArgType: A0.self,
208
+ dynamicArgumentTypes: [
209
+ ~A0.self,
210
+ ~A1.self,
211
+ ~A2.self,
212
+ ~A3.self,
213
+ ~A4.self,
214
+ ~A5.self
133
215
  ],
134
216
  closure
135
217
  )
@@ -141,17 +223,18 @@ public func Function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: A
141
223
  public func Function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument, A4: AnyArgument, A5: AnyArgument, A6: AnyArgument>(
142
224
  _ name: String,
143
225
  _ closure: @escaping (A0, A1, A2, A3, A4, A5, A6) throws -> R
144
- ) -> AnyFunction {
226
+ ) -> SyncFunctionComponent<(A0, A1, A2, A3, A4, A5, A6), A0, R> {
145
227
  return SyncFunctionComponent(
146
228
  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)
229
+ firstArgType: A0.self,
230
+ dynamicArgumentTypes: [
231
+ ~A0.self,
232
+ ~A1.self,
233
+ ~A2.self,
234
+ ~A3.self,
235
+ ~A4.self,
236
+ ~A5.self,
237
+ ~A6.self
155
238
  ],
156
239
  closure
157
240
  )
@@ -163,18 +246,19 @@ public func Function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: A
163
246
  public func Function<R, A0: AnyArgument, A1: AnyArgument, A2: AnyArgument, A3: AnyArgument, A4: AnyArgument, A5: AnyArgument, A6: AnyArgument, A7: AnyArgument>(
164
247
  _ name: String,
165
248
  _ closure: @escaping (A0, A1, A2, A3, A4, A5, A6, A7) throws -> R
166
- ) -> AnyFunction {
249
+ ) -> SyncFunctionComponent<(A0, A1, A2, A3, A4, A5, A6, A7), A0, R> {
167
250
  return SyncFunctionComponent(
168
251
  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)
252
+ firstArgType: A0.self,
253
+ dynamicArgumentTypes: [
254
+ ~A0.self,
255
+ ~A1.self,
256
+ ~A2.self,
257
+ ~A3.self,
258
+ ~A4.self,
259
+ ~A5.self,
260
+ ~A6.self,
261
+ ~A7.self
178
262
  ],
179
263
  closure
180
264
  )