expo-modules-core 0.6.5 → 0.9.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.
- package/CHANGELOG.md +57 -0
- package/README.md +1 -1
- package/android/ExpoModulesCorePlugin.gradle +15 -0
- package/android/build.gradle +31 -15
- package/android/src/main/java/expo/modules/adapters/react/NativeModulesProxy.java +5 -5
- package/android/src/main/java/expo/modules/adapters/react/services/UIManagerModuleWrapper.java +13 -0
- package/android/src/main/java/expo/modules/core/ViewManager.java +9 -0
- package/android/src/main/java/expo/modules/core/interfaces/JavaScriptContextProvider.java +4 -0
- package/android/src/main/java/expo/modules/core/interfaces/ReactActivityHandler.java +37 -1
- package/android/src/main/java/expo/modules/core/interfaces/ReactNativeHostHandler.java +30 -0
- package/android/src/main/java/expo/modules/core/interfaces/services/UIManager.java +2 -0
- package/android/src/main/java/expo/modules/kotlin/AppContext.kt +23 -5
- package/android/src/main/java/expo/modules/kotlin/DynamicExtenstions.kt +5 -3
- package/android/src/main/java/expo/modules/kotlin/KPromiseWrapper.kt +3 -8
- package/android/src/main/java/expo/modules/kotlin/KotlinInteropModuleRegistry.kt +24 -9
- package/android/src/main/java/expo/modules/kotlin/ModuleHolder.kt +12 -7
- package/android/src/main/java/expo/modules/kotlin/ModuleRegistry.kt +23 -1
- package/android/src/main/java/expo/modules/kotlin/Promise.kt +1 -1
- package/android/src/main/java/expo/modules/kotlin/callbacks/Callback.kt +5 -0
- package/android/src/main/java/expo/modules/kotlin/callbacks/ViewCallback.kt +39 -0
- package/android/src/main/java/expo/modules/kotlin/callbacks/ViewCallbackDelegate.kt +27 -0
- package/android/src/main/java/expo/modules/kotlin/defaultmodules/ErrorManagerModule.kt +25 -0
- package/android/src/main/java/expo/modules/kotlin/events/EventEmitter.kt +13 -0
- package/android/src/main/java/expo/modules/kotlin/events/KModuleEventEmitterWrapper.kt +102 -0
- package/android/src/main/java/expo/modules/kotlin/exception/CodedException.kt +93 -9
- package/android/src/main/java/expo/modules/kotlin/exception/ExceptionDecorator.kt +11 -0
- package/android/src/main/java/expo/modules/kotlin/{methods/AnyMethod.kt → functions/AnyFunction.kt} +18 -18
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunction.kt +15 -0
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionBuilder.kt +170 -0
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromise.kt +15 -0
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncSuspendFunction.kt +36 -0
- package/android/src/main/java/expo/modules/kotlin/modules/DefinitionMarker.kt +4 -0
- package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +17 -2
- package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +416 -43
- package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionData.kt +2 -2
- package/android/src/main/java/expo/modules/kotlin/records/FieldValidator.kt +139 -0
- package/android/src/main/java/expo/modules/kotlin/records/RecordTypeConverter.kt +71 -15
- package/android/src/main/java/expo/modules/kotlin/records/Required.kt +5 -0
- package/android/src/main/java/expo/modules/kotlin/records/ValidationBinder.kt +110 -0
- package/android/src/main/java/expo/modules/kotlin/records/Validators.kt +61 -0
- package/android/src/main/java/expo/modules/kotlin/types/ArrayTypeConverter.kt +11 -5
- package/android/src/main/java/expo/modules/kotlin/types/JSTypeConverter.kt +35 -0
- package/android/src/main/java/expo/modules/kotlin/types/JSTypeConverterHelper.kt +148 -0
- package/android/src/main/java/expo/modules/kotlin/types/ListTypeConverter.kt +10 -4
- package/android/src/main/java/expo/modules/kotlin/types/MapTypeConverter.kt +12 -6
- package/android/src/main/java/expo/modules/kotlin/types/PairTypeConverter.kt +29 -13
- package/android/src/main/java/expo/modules/kotlin/types/TypeConverter.kt +2 -1
- package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +9 -1
- package/android/src/main/java/expo/modules/kotlin/views/CallbacksDefinition.kt +3 -0
- package/android/src/main/java/expo/modules/kotlin/views/GroupViewManagerWrapper.kt +71 -0
- package/android/src/main/java/expo/modules/kotlin/views/SimpleViewManagerWrapper.kt +22 -0
- package/android/src/main/java/expo/modules/kotlin/views/ViewGroupDefinition.kt +18 -0
- package/android/src/main/java/expo/modules/kotlin/views/ViewGroupDefinitionBuilder.kt +114 -0
- package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinition.kt +30 -2
- package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinitionBuilder.kt +81 -2
- package/android/src/main/java/expo/modules/kotlin/views/ViewManagerWrapperDelegate.kt +62 -2
- package/build/EventEmitter.d.ts +1 -0
- package/build/EventEmitter.d.ts.map +1 -0
- package/build/NativeModulesProxy.d.ts +1 -0
- package/build/NativeModulesProxy.d.ts.map +1 -0
- package/build/NativeModulesProxy.native.d.ts +1 -4
- package/build/NativeModulesProxy.native.d.ts.map +1 -0
- package/build/NativeModulesProxy.native.js +1 -14
- package/build/NativeModulesProxy.native.js.map +1 -1
- package/build/NativeModulesProxy.types.d.ts +1 -3
- package/build/NativeModulesProxy.types.d.ts.map +1 -0
- package/build/NativeModulesProxy.types.js.map +1 -1
- package/build/NativeViewManagerAdapter.d.ts +1 -0
- package/build/NativeViewManagerAdapter.d.ts.map +1 -0
- package/build/NativeViewManagerAdapter.native.d.ts +1 -0
- package/build/NativeViewManagerAdapter.native.d.ts.map +1 -0
- package/build/NativeViewManagerAdapter.native.js +9 -33
- package/build/NativeViewManagerAdapter.native.js.map +1 -1
- package/build/PermissionsHook.d.ts +1 -0
- package/build/PermissionsHook.d.ts.map +1 -0
- package/build/PermissionsInterface.d.ts +1 -0
- package/build/PermissionsInterface.d.ts.map +1 -0
- package/build/Platform.d.ts +1 -0
- package/build/Platform.d.ts.map +1 -0
- package/build/SyntheticPlatformEmitter.d.ts +1 -0
- package/build/SyntheticPlatformEmitter.d.ts.map +1 -0
- package/build/SyntheticPlatformEmitter.web.d.ts +1 -0
- package/build/SyntheticPlatformEmitter.web.d.ts.map +1 -0
- package/build/deprecate.d.ts +1 -0
- package/build/deprecate.d.ts.map +1 -0
- package/build/environment/browser.d.ts +1 -0
- package/build/environment/browser.d.ts.map +1 -0
- package/build/environment/browser.web.d.ts +1 -0
- package/build/environment/browser.web.d.ts.map +1 -0
- package/build/errors/CodedError.d.ts +1 -0
- package/build/errors/CodedError.d.ts.map +1 -0
- package/build/errors/UnavailabilityError.d.ts +1 -0
- package/build/errors/UnavailabilityError.d.ts.map +1 -0
- package/build/index.d.ts +3 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +2 -0
- package/build/index.js.map +1 -1
- package/build/requireNativeModule.d.ts +16 -0
- package/build/requireNativeModule.d.ts.map +1 -0
- package/build/requireNativeModule.js +18 -0
- package/build/requireNativeModule.js.map +1 -0
- package/build/sweet/NativeErrorManager.d.ts +3 -0
- package/build/sweet/NativeErrorManager.d.ts.map +1 -0
- package/build/sweet/NativeErrorManager.js +3 -0
- package/build/sweet/NativeErrorManager.js.map +1 -0
- package/build/sweet/setUpErrorManager.fx.d.ts +2 -0
- package/build/sweet/setUpErrorManager.fx.d.ts.map +1 -0
- package/build/sweet/setUpErrorManager.fx.js +11 -0
- package/build/sweet/setUpErrorManager.fx.js.map +1 -0
- package/ios/AppDelegates/EXAppDelegatesLoader.m +4 -8
- package/ios/AppDelegates/ExpoAppDelegate.swift +22 -20
- package/ios/EXAppDefines.h +1 -0
- package/ios/EXAppDefines.m +6 -0
- package/ios/EXUtilities.h +2 -0
- package/ios/EXUtilities.m +12 -0
- package/ios/ExpoModulesCore.h +4 -0
- package/ios/ExpoModulesCore.podspec +4 -2
- package/ios/Interfaces/FileSystem/EXFileSystemInterface.h +1 -1
- package/ios/Interfaces/TaskManager/EXTaskServiceInterface.h +1 -0
- package/ios/JSI/{JSIConversions.h → EXJSIConversions.h} +5 -0
- package/ios/JSI/{JSIConversions.mm → EXJSIConversions.mm} +21 -1
- package/ios/JSI/{JSIInstaller.h → EXJSIInstaller.h} +10 -0
- package/ios/JSI/EXJSIInstaller.mm +17 -0
- package/ios/JSI/EXJSIUtils.h +19 -0
- package/ios/JSI/EXJSIUtils.mm +89 -0
- package/ios/JSI/EXJavaScriptObject.h +97 -0
- package/ios/JSI/EXJavaScriptObject.mm +121 -0
- package/ios/JSI/EXJavaScriptRuntime.h +73 -0
- package/ios/JSI/EXJavaScriptRuntime.mm +153 -0
- package/ios/JSI/EXJavaScriptValue.h +57 -0
- package/ios/JSI/EXJavaScriptValue.mm +166 -0
- package/ios/JSI/ExpoModulesHostObject.h +33 -0
- package/ios/JSI/ExpoModulesHostObject.mm +41 -0
- package/ios/JSI/JavaScriptRuntime.swift +32 -0
- package/ios/JSI/JavaScriptValue.swift +94 -0
- package/ios/ModuleRegistryAdapter/EXModuleRegistryAdapter.m +3 -23
- package/ios/NativeModulesProxy/EXNativeModulesProxy.h +2 -2
- package/ios/NativeModulesProxy/EXNativeModulesProxy.mm +101 -75
- package/ios/RCTComponentData+Privates.h +12 -0
- package/ios/ReactDelegates/EXReactCompatibleHelpers.h +18 -0
- package/ios/ReactDelegates/EXReactCompatibleHelpers.m +19 -0
- package/ios/ReactDelegates/ExpoReactDelegate.swift +3 -3
- package/ios/ReactDelegates/ExpoReactDelegateHandler.swift +4 -4
- package/ios/ReactDelegates/ModulePriorities.swift +1 -1
- package/ios/Swift/AppContext.swift +57 -4
- package/ios/Swift/Arguments/AnyArgumentType.swift +1 -1
- package/ios/Swift/Arguments/ArgumentType.swift +4 -0
- package/ios/Swift/Arguments/Convertibles.swift +13 -13
- package/ios/Swift/Arguments/Types/EnumArgumentType.swift +11 -17
- package/ios/Swift/Arguments/Types/PromiseArgumentType.swift +1 -1
- package/ios/Swift/Arguments/Types/RawArgumentType.swift +2 -2
- package/ios/Swift/Conversions.swift +51 -56
- package/ios/Swift/EventListener.swift +8 -10
- package/ios/Swift/Events/Callback.swift +66 -0
- package/ios/Swift/Events/Event.swift +43 -0
- package/ios/Swift/Exceptions/ChainableException.swift +51 -0
- package/ios/Swift/{CodedError.swift → Exceptions/CodedError.swift} +1 -12
- package/ios/Swift/Exceptions/Exception.swift +62 -0
- package/ios/Swift/Exceptions/ExceptionOrigin.swift +28 -0
- package/ios/Swift/Exceptions/GenericException.swift +20 -0
- package/ios/Swift/Exceptions/UnexpectedException.swift +16 -0
- package/ios/Swift/Functions/AnyFunction.swift +16 -1
- package/ios/Swift/Functions/AsyncFunctionComponent.swift +182 -0
- package/ios/Swift/Functions/ConcreteFunction.swift +52 -59
- package/ios/Swift/Functions/SyncFunctionComponent.swift +181 -0
- package/ios/Swift/JavaScriptUtils.swift +99 -0
- package/ios/Swift/ModuleHolder.swift +69 -18
- package/ios/Swift/ModuleRegistry.swift +4 -1
- package/ios/Swift/Modules/AnyModule.swift +0 -1
- package/ios/Swift/Modules/ModuleDefinition.swift +4 -13
- package/ios/Swift/Modules/ModuleDefinitionBuilder.swift +0 -1
- package/ios/Swift/Modules/ModuleDefinitionComponents.swift +54 -220
- package/ios/Swift/ModulesProvider.swift +3 -11
- package/ios/Swift/Objects/ObjectDefinition.swift +30 -0
- package/ios/Swift/Objects/ObjectDefinitionComponents.swift +257 -0
- package/ios/Swift/Promise.swift +8 -3
- package/ios/Swift/Records/AnyField.swift +7 -0
- package/ios/Swift/Records/Field.swift +24 -19
- package/ios/Swift/Records/FieldOption.swift +1 -1
- package/ios/Swift/Records/Record.swift +12 -4
- package/ios/Swift/SwiftInteropBridge.swift +53 -15
- package/ios/Swift/Views/AnyViewProp.swift +1 -1
- package/ios/Swift/Views/ComponentData.swift +96 -0
- package/ios/Swift/Views/ConcreteViewProp.swift +6 -8
- package/ios/Swift/Views/ExpoView.swift +8 -0
- package/ios/Swift/Views/ViewFactory.swift +1 -1
- package/ios/Swift/Views/ViewManagerDefinition.swift +23 -2
- package/ios/Swift/Views/ViewManagerDefinitionBuilder.swift +0 -1
- package/ios/Swift/Views/ViewManagerDefinitionComponents.swift +49 -0
- package/ios/Swift/Views/ViewModuleWrapper.swift +5 -2
- package/ios/Swift.h +5 -0
- package/ios/Tests/ArgumentTypeSpec.swift +5 -7
- package/ios/Tests/ConstantsSpec.swift +6 -7
- package/ios/Tests/ConvertiblesSpec.swift +35 -36
- package/ios/Tests/ExceptionsSpec.swift +111 -0
- package/ios/Tests/ExpoModulesSpec.swift +75 -0
- package/ios/Tests/FunctionSpec.swift +21 -25
- package/ios/Tests/FunctionWithConvertiblesSpec.swift +4 -5
- package/ios/Tests/JavaScriptObjectSpec.swift +97 -0
- package/ios/Tests/JavaScriptRuntimeSpec.swift +94 -0
- package/ios/Tests/Mocks/ModuleMocks.swift +1 -1
- package/ios/Tests/Mocks/ModulesProviderMock.swift +0 -1
- package/ios/Tests/ModuleEventListenersSpec.swift +16 -17
- package/ios/Tests/ModuleRegistrySpec.swift +2 -3
- package/ios/Tests/RecordSpec.swift +9 -20
- package/package.json +3 -3
- package/src/NativeModulesProxy.native.ts +2 -22
- package/src/NativeModulesProxy.types.ts +0 -8
- package/src/NativeViewManagerAdapter.native.tsx +12 -28
- package/src/index.ts +4 -0
- package/src/requireNativeModule.ts +29 -0
- package/src/sweet/NativeErrorManager.ts +2 -0
- package/src/sweet/setUpErrorManager.fx.ts +12 -0
- package/android/src/main/java/expo/modules/kotlin/events/KEventEmitterWrapper.kt +0 -26
- package/android/src/main/java/expo/modules/kotlin/methods/Method.kt +0 -14
- package/android/src/main/java/expo/modules/kotlin/methods/PromiseMethod.kt +0 -15
- package/ios/JSI/ExpoModulesProxySpec.h +0 -24
- package/ios/JSI/ExpoModulesProxySpec.mm +0 -135
- package/ios/JSI/JSIInstaller.mm +0 -22
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// Copyright 2022-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
Represents the place in code where the exception was created.
|
|
5
|
+
*/
|
|
6
|
+
public struct ExceptionOrigin: CustomStringConvertible {
|
|
7
|
+
/**
|
|
8
|
+
The path to the file in which the exception was created.
|
|
9
|
+
*/
|
|
10
|
+
let file: String
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
The line number on which the exception was created.
|
|
14
|
+
*/
|
|
15
|
+
let line: UInt
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
The name (selector) of the declaration in which the exception was created.
|
|
19
|
+
*/
|
|
20
|
+
let function: String
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
Stringified representation of the exception origin.
|
|
24
|
+
*/
|
|
25
|
+
public var description: String {
|
|
26
|
+
"at \(file):\(line) in \(function)"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Copyright 2022-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
The exception that needs some additional parameters to be best described.
|
|
5
|
+
*/
|
|
6
|
+
open class GenericException<ParamType>: Exception {
|
|
7
|
+
/**
|
|
8
|
+
The additional parameter passed to the initializer.
|
|
9
|
+
*/
|
|
10
|
+
public let param: ParamType
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
The default initializer that takes a param and captures the place in the code where the exception was created.
|
|
14
|
+
- Warning: Call it only with one argument! If you need to pass more parameters, use a tuple instead.
|
|
15
|
+
*/
|
|
16
|
+
public init(_ param: ParamType, file: String = #fileID, line: UInt = #line, function: String = #function) {
|
|
17
|
+
self.param = param
|
|
18
|
+
super.init(file: file, line: line, function: function)
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Copyright 2022-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
Exception wrapper used to handle unexpected internal native errors.
|
|
5
|
+
*/
|
|
6
|
+
public class UnexpectedException: Exception {
|
|
7
|
+
private let errorDescription: String
|
|
8
|
+
|
|
9
|
+
public init(_ error: Error) {
|
|
10
|
+
self.errorDescription = error.localizedDescription
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
public override var reason: String {
|
|
14
|
+
return errorDescription
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -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
|
*/
|
|
@@ -24,10 +29,15 @@ public protocol AnyFunction: AnyDefinition {
|
|
|
24
29
|
*/
|
|
25
30
|
var queue: DispatchQueue? { get }
|
|
26
31
|
|
|
32
|
+
/**
|
|
33
|
+
Whether the function needs to be called asynchronously from JavaScript.
|
|
34
|
+
*/
|
|
35
|
+
var isAsync: Bool { get }
|
|
36
|
+
|
|
27
37
|
/**
|
|
28
38
|
Calls the function on given module with arguments and a promise.
|
|
29
39
|
*/
|
|
30
|
-
func call(args: [Any], promise: Promise)
|
|
40
|
+
func call(args: [Any], promise: Promise)
|
|
31
41
|
|
|
32
42
|
/**
|
|
33
43
|
Synchronously calls the function with given arguments. If the function takes a promise,
|
|
@@ -39,4 +49,9 @@ public protocol AnyFunction: AnyDefinition {
|
|
|
39
49
|
Specifies on which queue the function should run.
|
|
40
50
|
*/
|
|
41
51
|
func runOnQueue(_ queue: DispatchQueue?) -> Self
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
Makes the JavaScript function synchronous.
|
|
55
|
+
*/
|
|
56
|
+
func runSynchronously() -> Self
|
|
42
57
|
}
|
|
@@ -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
|
+
}
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
import Dispatch
|
|
2
2
|
|
|
3
|
-
public
|
|
4
|
-
public typealias ClosureType = (Args) -> ReturnType
|
|
3
|
+
public class ConcreteFunction<Args, ReturnType>: AnyFunction {
|
|
4
|
+
public typealias ClosureType = (Args) throws -> ReturnType
|
|
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
|
|
11
|
+
return argumentTypes.count
|
|
14
12
|
}
|
|
15
13
|
|
|
16
14
|
public var queue: DispatchQueue?
|
|
17
15
|
|
|
16
|
+
public var isAsync: Bool = true
|
|
17
|
+
|
|
18
18
|
let closure: ClosureType
|
|
19
19
|
|
|
20
|
-
let
|
|
20
|
+
public let argumentTypes: [AnyArgumentType]
|
|
21
21
|
|
|
22
22
|
init(
|
|
23
23
|
_ name: String,
|
|
@@ -25,28 +25,38 @@ public final class ConcreteFunction<Args, ReturnType>: AnyFunction {
|
|
|
25
25
|
_ closure: @escaping ClosureType
|
|
26
26
|
) {
|
|
27
27
|
self.name = name
|
|
28
|
-
self.
|
|
28
|
+
self.takesPromise = argTypes.last is PromiseArgumentType
|
|
29
29
|
self.closure = closure
|
|
30
|
+
|
|
31
|
+
// Drop the last argument type if it's the `Promise`.
|
|
32
|
+
self.argumentTypes = takesPromise ? argTypes.dropLast(1) : argTypes
|
|
33
|
+
|
|
34
|
+
// This is temporary solution to keep backwards compatibility for existing functions — they all end with "Async".
|
|
35
|
+
// `function` component that we've used so far was async by default, but we decided to replace it with `asyncFunction`
|
|
36
|
+
// and make `function`s synchronous. Introduced in SDK45, can be removed in SDK46 after migrating all modules.
|
|
37
|
+
self.isAsync = name.hasSuffix("Async")
|
|
30
38
|
}
|
|
31
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
|
+
*/
|
|
32
47
|
public func call(args: [Any], promise: Promise) {
|
|
33
|
-
|
|
48
|
+
// Add promise to the array of arguments if necessary.
|
|
49
|
+
let arguments = takesPromise ? args + [promise] : args
|
|
34
50
|
let returnedValue: ReturnType?
|
|
35
51
|
|
|
36
52
|
do {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if takesPromise {
|
|
40
|
-
finalArgs.append(promise)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
let tuple = try Conversions.toTuple(finalArgs) as! Args
|
|
44
|
-
returnedValue = closure(tuple)
|
|
53
|
+
let argumentsTuple = try Conversions.toTuple(arguments) as! Args
|
|
54
|
+
returnedValue = try closure(argumentsTuple)
|
|
45
55
|
} catch let error as CodedError {
|
|
46
|
-
promise.reject(error)
|
|
56
|
+
promise.reject(FunctionCallException(name).causedBy(error))
|
|
47
57
|
return
|
|
48
|
-
} catch
|
|
49
|
-
promise.reject(
|
|
58
|
+
} catch {
|
|
59
|
+
promise.reject(UnexpectedException(error))
|
|
50
60
|
return
|
|
51
61
|
}
|
|
52
62
|
if !takesPromise {
|
|
@@ -54,28 +64,24 @@ public final class ConcreteFunction<Args, ReturnType>: AnyFunction {
|
|
|
54
64
|
}
|
|
55
65
|
}
|
|
56
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
|
+
*/
|
|
57
74
|
public func callSync(args: [Any]) -> Any {
|
|
58
75
|
if takesPromise {
|
|
59
|
-
|
|
60
|
-
let
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
call(args: args, promise: promise)
|
|
69
|
-
semaphore.wait()
|
|
70
|
-
return result as Any
|
|
71
|
-
} else {
|
|
72
|
-
do {
|
|
73
|
-
let finalArgs = try castArguments(args)
|
|
74
|
-
let tuple = try Conversions.toTuple(finalArgs) as! Args
|
|
75
|
-
return closure(tuple)
|
|
76
|
-
} catch let error {
|
|
77
|
-
return error
|
|
78
|
-
}
|
|
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
|
|
79
85
|
}
|
|
80
86
|
}
|
|
81
87
|
|
|
@@ -84,27 +90,14 @@ public final class ConcreteFunction<Args, ReturnType>: AnyFunction {
|
|
|
84
90
|
return self
|
|
85
91
|
}
|
|
86
92
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
private func castArguments(_ args: [Any]) throws -> [Any] {
|
|
92
|
-
if args.count != argumentsCount {
|
|
93
|
-
throw InvalidArgsNumberError(received: args.count, expected: argumentsCount)
|
|
94
|
-
}
|
|
95
|
-
return try args.enumerated().map { (index, arg) in
|
|
96
|
-
let expectedType = argumentType(atIndex: index)
|
|
97
|
-
|
|
98
|
-
// It's safe to unwrap since the arguments count matches.
|
|
99
|
-
return try expectedType!.cast(arg)
|
|
100
|
-
}
|
|
93
|
+
public func runSynchronously() -> Self {
|
|
94
|
+
self.isAsync = false
|
|
95
|
+
return self
|
|
101
96
|
}
|
|
102
97
|
}
|
|
103
98
|
|
|
104
|
-
internal
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
var description: String {
|
|
108
|
-
"Received \(received) arguments, but \(expected) was expected."
|
|
99
|
+
internal class FunctionCallException: GenericException<String> {
|
|
100
|
+
override var reason: String {
|
|
101
|
+
"Call to function '\(param)' has been rejected"
|
|
109
102
|
}
|
|
110
103
|
}
|
|
@@ -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
|
+
}
|