expo-modules-core 0.9.2 → 0.10.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 (167) hide show
  1. package/CHANGELOG.md +18 -5
  2. package/android/CMakeLists.txt +154 -0
  3. package/android/build.gradle +293 -5
  4. package/android/src/main/cpp/Exceptions.cpp +22 -0
  5. package/android/src/main/cpp/Exceptions.h +38 -0
  6. package/android/src/main/cpp/ExpoModulesHostObject.cpp +47 -0
  7. package/android/src/main/cpp/ExpoModulesHostObject.h +32 -0
  8. package/android/src/main/cpp/JNIFunctionBody.cpp +29 -0
  9. package/android/src/main/cpp/JNIFunctionBody.h +50 -0
  10. package/android/src/main/cpp/JNIInjector.cpp +19 -0
  11. package/android/src/main/cpp/JSIInteropModuleRegistry.cpp +122 -0
  12. package/android/src/main/cpp/JSIInteropModuleRegistry.h +96 -0
  13. package/android/src/main/cpp/JSIObjectWrapper.h +33 -0
  14. package/android/src/main/cpp/JSITypeConverter.h +84 -0
  15. package/android/src/main/cpp/JavaScriptModuleObject.cpp +138 -0
  16. package/android/src/main/cpp/JavaScriptModuleObject.h +122 -0
  17. package/android/src/main/cpp/JavaScriptObject.cpp +125 -0
  18. package/android/src/main/cpp/JavaScriptObject.h +131 -0
  19. package/android/src/main/cpp/JavaScriptRuntime.cpp +127 -0
  20. package/android/src/main/cpp/JavaScriptRuntime.h +87 -0
  21. package/android/src/main/cpp/JavaScriptValue.cpp +172 -0
  22. package/android/src/main/cpp/JavaScriptValue.h +78 -0
  23. package/android/src/main/cpp/MethodMetadata.cpp +230 -0
  24. package/android/src/main/cpp/MethodMetadata.h +92 -0
  25. package/android/src/main/java/expo/modules/adapters/react/NativeModulesProxy.java +2 -0
  26. package/android/src/main/java/expo/modules/core/errors/ContextDestroyedException.kt +7 -0
  27. package/android/src/main/java/expo/modules/interfaces/permissions/Permissions.java +30 -0
  28. package/android/src/main/java/expo/modules/kotlin/AppContext.kt +49 -1
  29. package/android/src/main/java/expo/modules/kotlin/ConcatIterator.kt +18 -0
  30. package/android/src/main/java/expo/modules/kotlin/KotlinInteropModuleRegistry.kt +15 -12
  31. package/android/src/main/java/expo/modules/kotlin/ModuleHolder.kt +39 -3
  32. package/android/src/main/java/expo/modules/kotlin/defaultmodules/ErrorManagerModule.kt +2 -2
  33. package/android/src/main/java/expo/modules/kotlin/exception/CodedException.kt +13 -0
  34. package/android/src/main/java/expo/modules/kotlin/exception/ExceptionDecorator.kt +2 -0
  35. package/android/src/main/java/expo/modules/kotlin/functions/AnyFunction.kt +19 -14
  36. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunction.kt +29 -7
  37. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionBuilder.kt +13 -13
  38. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionComponent.kt +18 -0
  39. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromiseComponent.kt +18 -0
  40. package/android/src/main/java/expo/modules/kotlin/functions/SuspendFunctionComponent.kt +56 -0
  41. package/android/src/main/java/expo/modules/kotlin/functions/SyncFunctionComponent.kt +28 -0
  42. package/android/src/main/java/expo/modules/kotlin/jni/CppType.kt +18 -0
  43. package/android/src/main/java/expo/modules/kotlin/jni/JNIFunctionBody.kt +39 -0
  44. package/android/src/main/java/expo/modules/kotlin/jni/JSIInteropModuleRegistry.kt +89 -0
  45. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptModuleObject.kt +44 -0
  46. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptObject.kt +113 -0
  47. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptValue.kt +35 -0
  48. package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +15 -5
  49. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +65 -111
  50. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionData.kt +35 -2
  51. package/android/src/main/java/expo/modules/kotlin/providers/AppContextProvider.kt +14 -0
  52. package/android/src/main/java/expo/modules/kotlin/providers/CurrentActivityProvider.kt +22 -0
  53. package/android/src/main/java/expo/modules/kotlin/records/RecordTypeConverter.kt +19 -2
  54. package/android/src/main/java/expo/modules/kotlin/types/AnyType.kt +3 -2
  55. package/android/src/main/java/expo/modules/kotlin/types/ArrayTypeConverter.kt +7 -2
  56. package/android/src/main/java/expo/modules/kotlin/types/BasicTypeConverters.kt +68 -20
  57. package/android/src/main/java/expo/modules/kotlin/types/EnumTypeConverter.kt +50 -22
  58. package/android/src/main/java/expo/modules/kotlin/types/ListTypeConverter.kt +18 -2
  59. package/android/src/main/java/expo/modules/kotlin/types/MapTypeConverter.kt +18 -2
  60. package/android/src/main/java/expo/modules/kotlin/types/PairTypeConverter.kt +17 -2
  61. package/android/src/main/java/expo/modules/kotlin/types/TypeConverter.kt +43 -3
  62. package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +5 -0
  63. package/build/NativeModulesProxy.native.d.ts.map +1 -1
  64. package/build/NativeModulesProxy.native.js +9 -3
  65. package/build/NativeModulesProxy.native.js.map +1 -1
  66. package/ios/AppDelegates/EXAppDelegatesLoader.m +1 -2
  67. package/ios/ExpoModulesCore.podspec +1 -1
  68. package/ios/JSI/EXJSIConversions.mm +6 -0
  69. package/ios/JSI/EXJSIInstaller.h +15 -21
  70. package/ios/JSI/EXJSIInstaller.mm +39 -3
  71. package/ios/JSI/EXJSIUtils.h +47 -3
  72. package/ios/JSI/EXJSIUtils.mm +88 -4
  73. package/ios/JSI/EXJavaScriptObject.h +11 -18
  74. package/ios/JSI/EXJavaScriptObject.mm +37 -18
  75. package/ios/JSI/EXJavaScriptRuntime.h +43 -9
  76. package/ios/JSI/EXJavaScriptRuntime.mm +70 -27
  77. package/ios/JSI/EXJavaScriptTypedArray.h +30 -0
  78. package/ios/JSI/EXJavaScriptTypedArray.mm +29 -0
  79. package/ios/JSI/EXJavaScriptValue.h +3 -2
  80. package/ios/JSI/EXJavaScriptValue.mm +17 -20
  81. package/ios/JSI/EXJavaScriptWeakObject.h +23 -0
  82. package/ios/JSI/EXJavaScriptWeakObject.mm +53 -0
  83. package/ios/JSI/EXObjectDeallocator.h +27 -0
  84. package/ios/JSI/ExpoModulesHostObject.h +3 -3
  85. package/ios/JSI/ExpoModulesHostObject.mm +4 -4
  86. package/ios/JSI/JavaScriptRuntime.swift +38 -1
  87. package/ios/JSI/JavaScriptValue.swift +7 -0
  88. package/ios/JSI/TypedArray.cpp +67 -0
  89. package/ios/JSI/TypedArray.h +46 -0
  90. package/ios/ModuleRegistryAdapter/EXModuleRegistryAdapter.m +0 -11
  91. package/ios/NativeModulesProxy/EXNativeModulesProxy.h +17 -10
  92. package/ios/NativeModulesProxy/EXNativeModulesProxy.mm +85 -77
  93. package/ios/NativeModulesProxy/NativeModulesProxyModule.swift +17 -0
  94. package/ios/Services/EXReactNativeEventEmitter.h +2 -2
  95. package/ios/Services/EXReactNativeEventEmitter.m +11 -6
  96. package/ios/Swift/AppContext.swift +208 -28
  97. package/ios/Swift/Arguments/AnyArgument.swift +18 -0
  98. package/ios/Swift/Arguments/{Types/EnumArgumentType.swift → EnumArgument.swift} +2 -17
  99. package/ios/Swift/Classes/ClassComponent.swift +95 -0
  100. package/ios/Swift/Classes/ClassComponentElement.swift +33 -0
  101. package/ios/Swift/Classes/ClassComponentElementsBuilder.swift +34 -0
  102. package/ios/Swift/Classes/ClassComponentFactories.swift +96 -0
  103. package/ios/Swift/DynamicTypes/AnyDynamicType.swift +44 -0
  104. package/ios/Swift/DynamicTypes/DynamicArrayType.swift +56 -0
  105. package/ios/Swift/DynamicTypes/DynamicConvertibleType.swift +27 -0
  106. package/ios/Swift/DynamicTypes/DynamicEnumType.swift +27 -0
  107. package/ios/Swift/DynamicTypes/DynamicOptionalType.swift +63 -0
  108. package/ios/Swift/DynamicTypes/DynamicRawType.swift +33 -0
  109. package/ios/Swift/DynamicTypes/DynamicSharedObjectType.swift +37 -0
  110. package/ios/Swift/DynamicTypes/DynamicType.swift +39 -0
  111. package/ios/Swift/DynamicTypes/DynamicTypedArrayType.swift +46 -0
  112. package/ios/Swift/Exceptions/CodedError.swift +1 -1
  113. package/ios/Swift/Exceptions/Exception.swift +8 -6
  114. package/ios/Swift/Exceptions/UnexpectedException.swift +2 -1
  115. package/ios/Swift/ExpoBridgeModule.m +5 -0
  116. package/ios/Swift/ExpoBridgeModule.swift +65 -0
  117. package/ios/Swift/Functions/AnyFunction.swift +33 -31
  118. package/ios/Swift/Functions/AsyncFunctionComponent.swift +196 -59
  119. package/ios/Swift/Functions/SyncFunctionComponent.swift +142 -58
  120. package/ios/Swift/JavaScriptUtils.swift +32 -57
  121. package/ios/Swift/Logging/LogHandlers.swift +39 -0
  122. package/ios/Swift/Logging/LogType.swift +62 -0
  123. package/ios/Swift/Logging/Logger.swift +198 -0
  124. package/ios/Swift/ModuleHolder.swift +19 -54
  125. package/ios/Swift/ModuleRegistry.swift +7 -1
  126. package/ios/Swift/Modules/AnyModule.swift +3 -3
  127. package/ios/Swift/ModulesProvider.swift +2 -0
  128. package/ios/Swift/Objects/JavaScriptObjectBuilder.swift +37 -0
  129. package/ios/Swift/Objects/ObjectDefinition.swift +74 -1
  130. package/ios/Swift/Objects/ObjectDefinitionComponents.swift +77 -68
  131. package/ios/Swift/Objects/PropertyComponent.swift +147 -0
  132. package/ios/Swift/Promise.swift +12 -3
  133. package/ios/Swift/Records/Field.swift +2 -2
  134. package/ios/Swift/SharedObjects/SharedObject.swift +20 -0
  135. package/ios/Swift/SharedObjects/SharedObjectRegistry.swift +129 -0
  136. package/ios/Swift/TypedArrays/AnyTypedArray.swift +11 -0
  137. package/ios/Swift/TypedArrays/ConcreteTypedArrays.swift +56 -0
  138. package/ios/Swift/TypedArrays/GenericTypedArray.swift +49 -0
  139. package/ios/Swift/TypedArrays/TypedArray.swift +80 -0
  140. package/ios/Swift/Utilities.swift +28 -0
  141. package/ios/Swift/Views/ConcreteViewProp.swift +3 -3
  142. package/ios/Swift/Views/ViewManagerDefinitionComponents.swift +2 -2
  143. package/ios/Tests/ClassComponentSpec.swift +210 -0
  144. package/ios/Tests/DynamicTypeSpec.swift +336 -0
  145. package/ios/Tests/EnumArgumentSpec.swift +48 -0
  146. package/ios/Tests/ExpoModulesSpec.swift +17 -3
  147. package/ios/Tests/FunctionSpec.swift +167 -118
  148. package/ios/Tests/Mocks/ModuleMocks.swift +1 -1
  149. package/ios/Tests/PropertyComponentSpec.swift +95 -0
  150. package/ios/Tests/SharedObjectRegistrySpec.swift +109 -0
  151. package/ios/Tests/TypedArraysSpec.swift +136 -0
  152. package/package.json +2 -2
  153. package/src/NativeModulesProxy.native.ts +13 -3
  154. package/src/ts-declarations/ExpoModules.d.ts +7 -0
  155. package/tsconfig.json +1 -1
  156. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromise.kt +0 -15
  157. package/android/src/main/java/expo/modules/kotlin/functions/AsyncSuspendFunction.kt +0 -36
  158. package/ios/Swift/Arguments/AnyArgumentType.swift +0 -13
  159. package/ios/Swift/Arguments/ArgumentType.swift +0 -28
  160. package/ios/Swift/Arguments/Types/ArrayArgumentType.swift +0 -42
  161. package/ios/Swift/Arguments/Types/ConvertibleArgumentType.swift +0 -16
  162. package/ios/Swift/Arguments/Types/OptionalArgumentType.swift +0 -49
  163. package/ios/Swift/Arguments/Types/PromiseArgumentType.swift +0 -15
  164. package/ios/Swift/Arguments/Types/RawArgumentType.swift +0 -25
  165. package/ios/Swift/Functions/ConcreteFunction.swift +0 -103
  166. package/ios/Swift/SwiftInteropBridge.swift +0 -155
  167. package/ios/Tests/ArgumentTypeSpec.swift +0 -143
@@ -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
  )
@@ -1,97 +1,72 @@
1
1
  // Copyright 2022-present 650 Industries. All rights reserved.
2
2
 
3
- // FIXME: Calling module's functions needs solid refactoring to not reference the module holder.
4
- // Instead, it should be possible to directly call the function instance from here. (added by @tsapeta)
5
-
6
- /**
7
- Creates a block that is executed when the module's async function is called.
8
- */
9
- internal func createAsyncFunctionBlock(holder: ModuleHolder, name functionName: String) -> JSAsyncFunctionBlock {
10
- let moduleName = holder.name
11
- return { [weak holder, moduleName] args, resolve, reject in
12
- guard let holder = holder else {
13
- let exception = ModuleUnavailableException(moduleName)
14
- reject(exception.code, exception.description, exception)
15
- return
16
- }
17
- holder.call(function: functionName, args: args) { result, error in
18
- if let error = error {
19
- reject(error.code, error.description, error)
20
- } else {
21
- resolve(result)
22
- }
23
- }
24
- }
25
- }
26
-
27
- /**
28
- Creates a block that is executed when the module's sync function is called.
29
- */
30
- internal func createSyncFunctionBlock(holder: ModuleHolder, name functionName: String) -> JSSyncFunctionBlock {
31
- return { [weak holder] args in
32
- guard let holder = holder else {
33
- return nil
34
- }
35
- return holder.callSync(function: functionName, args: args)
36
- }
37
- }
38
-
39
3
  // MARK: - Arguments
40
4
 
41
5
  /**
42
- Tries to cast given argument to the type that is wrapped by the argument type.
6
+ Tries to cast a given value to the type that is wrapped by the dynamic type.
43
7
  - Parameters:
44
- - argument: A value to be cast. If it's a ``JavaScriptValue``, it's first unpacked to the raw value.
45
- - argumentType: Something that implements ``AnyArgumentType`` and knows how to cast the argument.
46
- - Returns: A new value converted according to the argument type.
47
- - Throws: Rethrows various exceptions that could be thrown by the argument type wrappers.
8
+ - value: A value to be cast. If it's a ``JavaScriptValue``, it's first unpacked to the raw value.
9
+ - type: Something that implements ``AnyDynamicType`` and knows how to cast the argument.
10
+ - Returns: A new value converted according to the dynamic type.
11
+ - Throws: Rethrows various exceptions that could be thrown by the dynamic types.
48
12
  */
49
- internal func castArgument(_ argument: Any, toType argumentType: AnyArgumentType) throws -> Any {
13
+ internal func cast(_ value: Any, toType type: AnyDynamicType) throws -> Any {
50
14
  // TODO: Accept JavaScriptValue and JavaScriptObject as argument types.
51
- if let argument = argument as? JavaScriptValue {
52
- return try argumentType.cast(argument.getRaw())
15
+ if !(type is DynamicTypedArrayType), let value = value as? JavaScriptValue {
16
+ return try type.cast(value.getRaw())
53
17
  }
54
- return try argumentType.cast(argument)
18
+ return try type.cast(value)
55
19
  }
56
20
 
57
21
  /**
58
- Same as ``castArgument(_:argumentType:)`` but for an array of arguments.
22
+ Tries to cast the given arguments to the types expected by the function.
59
23
  - Parameters:
60
24
  - arguments: An array of arguments to be cast.
61
- - argumentTypes: An array of argument types in the same order as the array of arguments.
25
+ - function: A function for which to cast the arguments.
62
26
  - Returns: An array of arguments after casting. Its size is the same as the input arrays.
63
- - Throws: ``InvalidArgsNumberException`` when the sizes of arrays passed as parameters are not equal.
64
- Rethrows exceptions thrown by ``castArgument(_:argumentType:)``.
27
+ - Throws: `InvalidArgsNumberException` when the number of arguments is not equal to the actual number
28
+ of function's arguments (without an owner and promise). Rethrows exceptions thrown by `cast(_:toType:)`.
65
29
  */
66
- internal func castArguments(_ arguments: [Any], toTypes argumentTypes: [AnyArgumentType]) throws -> [Any] {
67
- if arguments.count != argumentTypes.count {
68
- throw InvalidArgsNumberException((received: arguments.count, expected: argumentTypes.count))
30
+ internal func cast(arguments: [Any], forFunction function: AnyFunction) throws -> [Any] {
31
+ if arguments.count != function.argumentsCount {
32
+ throw InvalidArgsNumberException((received: arguments.count, expected: function.argumentsCount))
69
33
  }
34
+ let argumentTypeOffset = function.takesOwner ? 1 : 0
70
35
  return try arguments.enumerated().map { index, argument in
71
- let argumentType = argumentTypes[index]
36
+ let argumentType = function.dynamicArgumentTypes[index + argumentTypeOffset]
72
37
 
73
38
  do {
74
- return try castArgument(argument, toType: argumentType)
39
+ return try cast(argument, toType: argumentType)
75
40
  } catch {
76
41
  throw ArgumentCastException((index: index, type: argumentType)).causedBy(error)
77
42
  }
78
43
  }
79
44
  }
80
45
 
46
+ /**
47
+ Prepends the owner to the array of arguments if the given function can take it.
48
+ */
49
+ internal func concat(arguments: [Any], withOwner owner: AnyObject?, forFunction function: AnyFunction) -> [Any] {
50
+ if function.takesOwner, let owner = try? function.dynamicArgumentTypes.first?.cast(owner) {
51
+ return [owner] + arguments
52
+ }
53
+ return arguments
54
+ }
55
+
56
+ // MARK: - Exceptions
57
+
81
58
  internal class InvalidArgsNumberException: GenericException<(received: Int, expected: Int)> {
82
59
  override var reason: String {
83
60
  "Received \(param.received) arguments, but \(param.expected) was expected"
84
61
  }
85
62
  }
86
63
 
87
- internal class ArgumentCastException: GenericException<(index: Int, type: AnyArgumentType)> {
64
+ internal class ArgumentCastException: GenericException<(index: Int, type: AnyDynamicType)> {
88
65
  override var reason: String {
89
66
  "Argument at index '\(param.index)' couldn't be cast to type \(param.type.description)"
90
67
  }
91
68
  }
92
69
 
93
- // MARK: - Exceptions
94
-
95
70
  private class ModuleUnavailableException: GenericException<String> {
96
71
  override var reason: String {
97
72
  "Module '\(param)' is no longer available"
@@ -0,0 +1,39 @@
1
+ // Copyright 2022-present 650 Industries. All rights reserved.
2
+
3
+ import os.log
4
+
5
+ /**
6
+ The protocol that needs to be implemented by log handlers.
7
+ */
8
+ internal protocol LogHandler {
9
+ init(category: String)
10
+
11
+ func log(type: LogType, _ message: String)
12
+ }
13
+
14
+ /**
15
+ The log handler that uses the new `os.Logger` API.
16
+ */
17
+ @available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
18
+ internal class OSLogHandler: LogHandler {
19
+ private let osLogger: os.Logger
20
+
21
+ required init(category: String) {
22
+ osLogger = os.Logger(subsystem: "dev.expo.modules", category: category)
23
+ }
24
+
25
+ func log(type: LogType, _ message: String) {
26
+ osLogger.log(level: type.toOSLogType(), "\(message)")
27
+ }
28
+ }
29
+
30
+ /**
31
+ Simple log handler that forwards all logs to `print` function.
32
+ */
33
+ internal class PrintLogHandler: LogHandler {
34
+ required init(category: String) {}
35
+
36
+ func log(type: LogType, _ message: String) {
37
+ print(message)
38
+ }
39
+ }
@@ -0,0 +1,62 @@
1
+ // Copyright 2022-present 650 Industries. All rights reserved.
2
+
3
+ import os.log
4
+
5
+ /**
6
+ An enum with available log types.
7
+ */
8
+ public enum LogType: Int {
9
+ case trace = 0
10
+ case timer = 1
11
+ case stacktrace = 2
12
+ case debug = 3
13
+ case info = 4
14
+ case warn = 5
15
+ case error = 6
16
+ case fatal = 7
17
+
18
+ /**
19
+ The string that is used to prefix the messages of this log type.
20
+ Logs in Xcode and Console apps are always with the white text,
21
+ so we use colored circle emojis to distinguish different types of logs.
22
+ */
23
+ var prefix: String {
24
+ switch self {
25
+ case .trace:
26
+ return "⚪️"
27
+ case .timer:
28
+ return "🟤"
29
+ case .stacktrace:
30
+ return "🟣"
31
+ case .debug:
32
+ return "🔵"
33
+ case .info:
34
+ return "🟢"
35
+ case .warn:
36
+ return "🟡"
37
+ case .error:
38
+ return "🟠"
39
+ case .fatal:
40
+ return "🔴"
41
+ }
42
+ }
43
+
44
+ /**
45
+ Maps the log types to the log types used by the `os.log` logger.
46
+ */
47
+ @available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
48
+ func toOSLogType() -> OSLogType {
49
+ switch self {
50
+ case .trace, .timer, .stacktrace, .debug:
51
+ return .debug
52
+ case .info:
53
+ return .info
54
+ case .warn:
55
+ return .default
56
+ case .error:
57
+ return .error
58
+ case .fatal:
59
+ return .fault
60
+ }
61
+ }
62
+ }