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,73 @@
|
|
|
1
|
+
// Copyright 2018-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
#import <ExpoModulesCore/EXJavaScriptValue.h>
|
|
4
|
+
#import <ExpoModulesCore/EXJavaScriptObject.h>
|
|
5
|
+
|
|
6
|
+
#ifdef __cplusplus
|
|
7
|
+
#import <ReactCommon/CallInvoker.h>
|
|
8
|
+
|
|
9
|
+
namespace jsi = facebook::jsi;
|
|
10
|
+
namespace react = facebook::react;
|
|
11
|
+
#endif // __cplusplus
|
|
12
|
+
|
|
13
|
+
@class EXJavaScriptValue;
|
|
14
|
+
@class EXJavaScriptObject;
|
|
15
|
+
|
|
16
|
+
#ifdef __cplusplus
|
|
17
|
+
typedef jsi::Value (^JSHostFunctionBlock)(jsi::Runtime &runtime, std::shared_ptr<react::CallInvoker> callInvoker, NSArray<EXJavaScriptValue *> * _Nonnull arguments);
|
|
18
|
+
#endif // __cplusplus
|
|
19
|
+
|
|
20
|
+
NS_SWIFT_NAME(JavaScriptRuntime)
|
|
21
|
+
@interface EXJavaScriptRuntime : NSObject
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
Creates a new JavaScript runtime.
|
|
25
|
+
*/
|
|
26
|
+
- (nonnull instancetype)init;
|
|
27
|
+
|
|
28
|
+
#ifdef __cplusplus
|
|
29
|
+
- (nonnull instancetype)initWithRuntime:(nonnull jsi::Runtime *)runtime
|
|
30
|
+
callInvoker:(std::shared_ptr<react::CallInvoker>)callInvoker;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
Returns the underlying runtime object.
|
|
34
|
+
*/
|
|
35
|
+
- (nonnull jsi::Runtime *)get;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
Returns the call invoker the runtime was initialized with.
|
|
39
|
+
*/
|
|
40
|
+
- (std::shared_ptr<react::CallInvoker>)callInvoker;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
Wraps given host object to `EXJavaScriptObject`.
|
|
44
|
+
*/
|
|
45
|
+
- (nonnull EXJavaScriptObject *)createHostObject:(std::shared_ptr<jsi::HostObject>)jsiHostObjectPtr;
|
|
46
|
+
|
|
47
|
+
- (jsi::Function)createSyncFunction:(nonnull NSString *)name
|
|
48
|
+
argsCount:(NSInteger)argsCount
|
|
49
|
+
block:(nonnull JSSyncFunctionBlock)block;
|
|
50
|
+
|
|
51
|
+
- (jsi::Function)createAsyncFunction:(nonnull NSString *)name
|
|
52
|
+
argsCount:(NSInteger)argsCount
|
|
53
|
+
block:(nonnull JSAsyncFunctionBlock)block;
|
|
54
|
+
#endif // __cplusplus
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
Returns the runtime global object for use in Swift.
|
|
58
|
+
*/
|
|
59
|
+
- (nonnull EXJavaScriptObject *)global;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
Creates a new object for use in Swift.
|
|
63
|
+
*/
|
|
64
|
+
- (nonnull EXJavaScriptObject *)createObject;
|
|
65
|
+
|
|
66
|
+
#pragma mark - Script evaluation
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
Evaluates given JavaScript source code.
|
|
70
|
+
*/
|
|
71
|
+
- (nonnull EXJavaScriptValue *)evaluateScript:(nonnull NSString *)scriptSource;
|
|
72
|
+
|
|
73
|
+
@end
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
// Copyright 2018-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
#import <jsi/jsi.h>
|
|
4
|
+
|
|
5
|
+
#if __has_include(<reacthermes/HermesExecutorFactory.h>)
|
|
6
|
+
#import <reacthermes/HermesExecutorFactory.h>
|
|
7
|
+
#elif __has_include(<hermes/hermes.h>)
|
|
8
|
+
#import <hermes/hermes.h>
|
|
9
|
+
#else
|
|
10
|
+
#import <jsi/JSCRuntime.h>
|
|
11
|
+
#endif
|
|
12
|
+
|
|
13
|
+
#import <ExpoModulesCore/EXJavaScriptRuntime.h>
|
|
14
|
+
#import <ExpoModulesCore/ExpoModulesHostObject.h>
|
|
15
|
+
#import <ExpoModulesCore/EXJSIUtils.h>
|
|
16
|
+
#import <ExpoModulesCore/EXJSIConversions.h>
|
|
17
|
+
#import <ExpoModulesCore/Swift.h>
|
|
18
|
+
|
|
19
|
+
using namespace facebook;
|
|
20
|
+
|
|
21
|
+
@implementation EXJavaScriptRuntime {
|
|
22
|
+
std::shared_ptr<jsi::Runtime> _runtime;
|
|
23
|
+
std::shared_ptr<react::CallInvoker> _jsCallInvoker;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
Initializes a runtime that is independent from React Native and its runtime initialization.
|
|
28
|
+
This flow is mostly intended for tests. The JS call invoker is unavailable thus calling async functions is not supported.
|
|
29
|
+
TODO: Implement the call invoker when it becomes necessary.
|
|
30
|
+
*/
|
|
31
|
+
- (nonnull instancetype)init
|
|
32
|
+
{
|
|
33
|
+
if (self = [super init]) {
|
|
34
|
+
#if __has_include(<reacthermes/HermesExecutorFactory.h>) || __has_include(<hermes/hermes.h>)
|
|
35
|
+
_runtime = hermes::makeHermesRuntime();
|
|
36
|
+
#else
|
|
37
|
+
_runtime = jsc::makeJSCRuntime();
|
|
38
|
+
#endif
|
|
39
|
+
_jsCallInvoker = nil;
|
|
40
|
+
}
|
|
41
|
+
return self;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
- (nonnull instancetype)initWithRuntime:(nonnull jsi::Runtime *)runtime
|
|
45
|
+
callInvoker:(std::shared_ptr<react::CallInvoker>)callInvoker
|
|
46
|
+
{
|
|
47
|
+
if (self = [super init]) {
|
|
48
|
+
// Creating a shared pointer that points to the runtime but doesn't own it, thus doesn't release it.
|
|
49
|
+
// In this code flow, the runtime should be owned by something else like the RCTBridge.
|
|
50
|
+
// See explanation for constructor (8): https://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr
|
|
51
|
+
_runtime = std::shared_ptr<jsi::Runtime>(std::shared_ptr<jsi::Runtime>(), runtime);
|
|
52
|
+
_jsCallInvoker = callInvoker;
|
|
53
|
+
}
|
|
54
|
+
return self;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
- (nonnull jsi::Runtime *)get
|
|
58
|
+
{
|
|
59
|
+
return _runtime.get();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
- (std::shared_ptr<react::CallInvoker>)callInvoker
|
|
63
|
+
{
|
|
64
|
+
return _jsCallInvoker;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
- (nonnull EXJavaScriptObject *)createObject
|
|
68
|
+
{
|
|
69
|
+
auto jsObjectPtr = std::make_shared<jsi::Object>(*_runtime);
|
|
70
|
+
return [[EXJavaScriptObject alloc] initWith:jsObjectPtr runtime:self];
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
- (nonnull EXJavaScriptObject *)createHostObject:(std::shared_ptr<jsi::HostObject>)jsiHostObjectPtr
|
|
74
|
+
{
|
|
75
|
+
auto jsObjectPtr = std::make_shared<jsi::Object>(jsi::Object::createFromHostObject(*_runtime, jsiHostObjectPtr));
|
|
76
|
+
return [[EXJavaScriptObject alloc] initWith:jsObjectPtr runtime:self];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
- (nonnull EXJavaScriptObject *)global
|
|
80
|
+
{
|
|
81
|
+
auto jsGlobalPtr = std::make_shared<jsi::Object>(_runtime->global());
|
|
82
|
+
return [[EXJavaScriptObject alloc] initWith:jsGlobalPtr runtime:self];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
- (jsi::Function)createSyncFunction:(nonnull NSString *)name
|
|
86
|
+
argsCount:(NSInteger)argsCount
|
|
87
|
+
block:(nonnull JSSyncFunctionBlock)block
|
|
88
|
+
{
|
|
89
|
+
return [self createHostFunction:name argsCount:argsCount block:^jsi::Value(jsi::Runtime &runtime, std::shared_ptr<react::CallInvoker> callInvoker, NSArray * _Nonnull arguments) {
|
|
90
|
+
return expo::convertObjCObjectToJSIValue(runtime, block(arguments));
|
|
91
|
+
}];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
- (jsi::Function)createAsyncFunction:(nonnull NSString *)name
|
|
95
|
+
argsCount:(NSInteger)argsCount
|
|
96
|
+
block:(nonnull JSAsyncFunctionBlock)block
|
|
97
|
+
{
|
|
98
|
+
return [self createHostFunction:name argsCount:argsCount block:^jsi::Value(jsi::Runtime &runtime, std::shared_ptr<react::CallInvoker> callInvoker, NSArray *arguments) {
|
|
99
|
+
if (!callInvoker) {
|
|
100
|
+
// In mocked environment the call invoker may be null so it's not supported to call async functions.
|
|
101
|
+
// Testing async functions is a bit more complicated anyway. See `init` description for more.
|
|
102
|
+
throw jsi::JSError(runtime, "Calling async functions is not supported when the call invoker is unavailable");
|
|
103
|
+
}
|
|
104
|
+
// The function that is invoked as a setup of the EXJavaScript `Promise`.
|
|
105
|
+
auto promiseSetup = [callInvoker, block, arguments](jsi::Runtime &runtime, std::shared_ptr<Promise> promise) {
|
|
106
|
+
expo::callPromiseSetupWithBlock(runtime, callInvoker, promise, ^(RCTPromiseResolveBlock resolver, RCTPromiseRejectBlock rejecter) {
|
|
107
|
+
block(arguments, resolver, rejecter);
|
|
108
|
+
});
|
|
109
|
+
};
|
|
110
|
+
return createPromiseAsJSIValue(runtime, promiseSetup);
|
|
111
|
+
}];
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
#pragma mark - Script evaluation
|
|
115
|
+
|
|
116
|
+
- (nonnull EXJavaScriptValue *)evaluateScript:(nonnull NSString *)scriptSource
|
|
117
|
+
{
|
|
118
|
+
std::shared_ptr<jsi::StringBuffer> scriptBuffer = std::make_shared<jsi::StringBuffer>([scriptSource UTF8String]);
|
|
119
|
+
std::shared_ptr<jsi::Value> result;
|
|
120
|
+
|
|
121
|
+
try {
|
|
122
|
+
result = std::make_shared<jsi::Value>(_runtime->evaluateJavaScript(scriptBuffer, "<<evaluated>>"));
|
|
123
|
+
} catch (jsi::JSError &error) {
|
|
124
|
+
NSString *reason = [NSString stringWithUTF8String:error.getMessage().c_str()];
|
|
125
|
+
NSString *stack = [NSString stringWithUTF8String:error.getStack().c_str()];
|
|
126
|
+
|
|
127
|
+
@throw [NSException exceptionWithName:@"ScriptEvaluationException" reason:reason userInfo:@{
|
|
128
|
+
@"message": reason,
|
|
129
|
+
@"stack": stack,
|
|
130
|
+
}];
|
|
131
|
+
}
|
|
132
|
+
return [[EXJavaScriptValue alloc] initWithRuntime:self value:result];
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
#pragma mark - Private
|
|
136
|
+
|
|
137
|
+
- (jsi::Function)createHostFunction:(nonnull NSString *)name
|
|
138
|
+
argsCount:(NSInteger)argsCount
|
|
139
|
+
block:(nonnull JSHostFunctionBlock)block
|
|
140
|
+
{
|
|
141
|
+
jsi::PropNameID propNameId = jsi::PropNameID::forAscii(*_runtime, [name UTF8String], [name length]);
|
|
142
|
+
std::weak_ptr<react::CallInvoker> weakCallInvoker = _jsCallInvoker;
|
|
143
|
+
jsi::HostFunctionType function = [weakCallInvoker, block, self](jsi::Runtime &runtime, const jsi::Value &thisVal, const jsi::Value *args, size_t count) -> jsi::Value {
|
|
144
|
+
// Theoretically should check here whether the call invoker isn't null, but in mocked environment
|
|
145
|
+
// there is no need to care about that for synchronous calls, so it's ensured in `createAsyncFunction` instead.
|
|
146
|
+
auto callInvoker = weakCallInvoker.lock();
|
|
147
|
+
NSArray<EXJavaScriptValue *> *arguments = expo::convertJSIValuesToNSArray(self, args, count);
|
|
148
|
+
return block(runtime, callInvoker, arguments);
|
|
149
|
+
};
|
|
150
|
+
return jsi::Function::createFromHostFunction(*_runtime, propNameId, (unsigned int)argsCount, function);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
@end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// Copyright 2022-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
#import <Foundation/Foundation.h>
|
|
4
|
+
#import <ExpoModulesCore/EXJavaScriptObject.h>
|
|
5
|
+
|
|
6
|
+
#ifdef __cplusplus
|
|
7
|
+
#import <jsi/jsi.h>
|
|
8
|
+
namespace jsi = facebook::jsi;
|
|
9
|
+
#endif // __cplusplus
|
|
10
|
+
|
|
11
|
+
@class EXJavaScriptRuntime;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
Represents any JavaScript value. Its purpose is to exposes `facebook::jsi::Value` API back to Swift.
|
|
15
|
+
*/
|
|
16
|
+
NS_SWIFT_NAME(JavaScriptValue)
|
|
17
|
+
@interface EXJavaScriptValue : NSObject
|
|
18
|
+
|
|
19
|
+
#ifdef __cplusplus
|
|
20
|
+
- (nonnull instancetype)initWithRuntime:(nonnull EXJavaScriptRuntime *)runtime
|
|
21
|
+
value:(std::shared_ptr<jsi::Value>)value;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
\return the underlying `jsi::Value`.
|
|
25
|
+
*/
|
|
26
|
+
- (nonnull jsi::Value *)get;
|
|
27
|
+
#endif // __cplusplus
|
|
28
|
+
|
|
29
|
+
#pragma mark - Type checking
|
|
30
|
+
|
|
31
|
+
- (BOOL)isUndefined;
|
|
32
|
+
- (BOOL)isNull;
|
|
33
|
+
- (BOOL)isBool;
|
|
34
|
+
- (BOOL)isNumber;
|
|
35
|
+
- (BOOL)isString;
|
|
36
|
+
- (BOOL)isSymbol;
|
|
37
|
+
- (BOOL)isObject;
|
|
38
|
+
- (BOOL)isFunction;
|
|
39
|
+
|
|
40
|
+
+ (nonnull NSString *)kindOf:(nonnull EXJavaScriptValue *)value;
|
|
41
|
+
|
|
42
|
+
#pragma mark - Type casting
|
|
43
|
+
|
|
44
|
+
- (nullable id)getRaw;
|
|
45
|
+
- (BOOL)getBool;
|
|
46
|
+
- (NSInteger)getInt;
|
|
47
|
+
- (double)getDouble;
|
|
48
|
+
- (nonnull NSString *)getString;
|
|
49
|
+
- (nonnull NSArray<EXJavaScriptValue *> *)getArray;
|
|
50
|
+
- (nonnull NSDictionary<NSString *, id> *)getDictionary;
|
|
51
|
+
- (nonnull EXJavaScriptObject *)getObject;
|
|
52
|
+
|
|
53
|
+
#pragma mark - Helpers
|
|
54
|
+
|
|
55
|
+
- (nonnull NSString *)toString;
|
|
56
|
+
|
|
57
|
+
@end
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
// Copyright 2022-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
#import <ExpoModulesCore/EXJSIConversions.h>
|
|
4
|
+
#import <ExpoModulesCore/EXJavaScriptValue.h>
|
|
5
|
+
#import <ExpoModulesCore/EXJavaScriptRuntime.h>
|
|
6
|
+
|
|
7
|
+
@implementation EXJavaScriptValue {
|
|
8
|
+
__weak EXJavaScriptRuntime *_runtime;
|
|
9
|
+
std::shared_ptr<jsi::Value> _value;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
- (nonnull instancetype)initWithRuntime:(nonnull EXJavaScriptRuntime *)runtime
|
|
13
|
+
value:(std::shared_ptr<jsi::Value>)value
|
|
14
|
+
{
|
|
15
|
+
if (self = [super init]) {
|
|
16
|
+
_runtime = runtime;
|
|
17
|
+
_value = value;
|
|
18
|
+
}
|
|
19
|
+
return self;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
- (nonnull jsi::Value *)get
|
|
23
|
+
{
|
|
24
|
+
return _value.get();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
#pragma mark - Type checking
|
|
28
|
+
|
|
29
|
+
- (BOOL)isUndefined
|
|
30
|
+
{
|
|
31
|
+
return _value->isUndefined();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
- (BOOL)isNull
|
|
35
|
+
{
|
|
36
|
+
return _value->isNull();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
- (BOOL)isBool
|
|
40
|
+
{
|
|
41
|
+
return _value->isBool();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
- (BOOL)isNumber
|
|
45
|
+
{
|
|
46
|
+
return _value->isNumber();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
- (BOOL)isString
|
|
50
|
+
{
|
|
51
|
+
return _value->isString();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
- (BOOL)isSymbol
|
|
55
|
+
{
|
|
56
|
+
return _value->isSymbol();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
- (BOOL)isObject
|
|
60
|
+
{
|
|
61
|
+
return _value->isObject();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
- (BOOL)isFunction
|
|
65
|
+
{
|
|
66
|
+
if (_value->isObject()) {
|
|
67
|
+
jsi::Runtime *runtime = [_runtime get];
|
|
68
|
+
return _value->getObject(*runtime).isFunction(*runtime);
|
|
69
|
+
}
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
+ (nonnull NSString *)kindOf:(nonnull EXJavaScriptValue *)value
|
|
74
|
+
{
|
|
75
|
+
if ([value isUndefined]) {
|
|
76
|
+
return @"undefined";
|
|
77
|
+
}
|
|
78
|
+
if ([value isNull]) {
|
|
79
|
+
return @"null";
|
|
80
|
+
}
|
|
81
|
+
if ([value isBool]) {
|
|
82
|
+
return @"boolean";
|
|
83
|
+
}
|
|
84
|
+
if ([value isNumber]) {
|
|
85
|
+
return @"number";
|
|
86
|
+
}
|
|
87
|
+
if ([value isString]) {
|
|
88
|
+
return @"string";
|
|
89
|
+
}
|
|
90
|
+
if ([value isFunction]) {
|
|
91
|
+
return @"function";
|
|
92
|
+
}
|
|
93
|
+
assert([value isObject] && "Expecting object.");
|
|
94
|
+
return @"object";
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
#pragma mark - Type casting
|
|
98
|
+
|
|
99
|
+
- (nullable id)getRaw
|
|
100
|
+
{
|
|
101
|
+
return expo::convertJSIValueToObjCObject(*[_runtime get], *_value, [_runtime callInvoker]);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
- (BOOL)getBool
|
|
105
|
+
{
|
|
106
|
+
return _value->getBool();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
- (NSInteger)getInt
|
|
110
|
+
{
|
|
111
|
+
return _value->getNumber();
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
- (double)getDouble
|
|
115
|
+
{
|
|
116
|
+
return _value->getNumber();
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
- (nonnull NSString *)getString
|
|
120
|
+
{
|
|
121
|
+
jsi::Runtime *runtime = [_runtime get];
|
|
122
|
+
return expo::convertJSIStringToNSString(*runtime, _value->getString(*runtime));
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
- (nonnull NSArray<EXJavaScriptValue *> *)getArray
|
|
126
|
+
{
|
|
127
|
+
jsi::Runtime *runtime = [_runtime get];
|
|
128
|
+
jsi::Array jsiArray = _value->getObject(*runtime).getArray(*runtime);
|
|
129
|
+
size_t arraySize = jsiArray.size(*runtime);
|
|
130
|
+
NSMutableArray *result = [NSMutableArray arrayWithCapacity:arraySize];
|
|
131
|
+
|
|
132
|
+
for (size_t i = 0; i < arraySize; i++) {
|
|
133
|
+
jsi::Value item = jsiArray.getValueAtIndex(*runtime, i);
|
|
134
|
+
|
|
135
|
+
if (item.isUndefined() || item.isNull()) {
|
|
136
|
+
[result addObject:(id)kCFNull];
|
|
137
|
+
} else {
|
|
138
|
+
std::shared_ptr<jsi::Value> valuePtr = std::make_shared<jsi::Value>(*runtime, item);
|
|
139
|
+
[result addObject:[[EXJavaScriptValue alloc] initWithRuntime:_runtime value:valuePtr]];
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return result;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
- (nonnull NSDictionary<NSString *, id> *)getDictionary
|
|
146
|
+
{
|
|
147
|
+
jsi::Runtime *runtime = [_runtime get];
|
|
148
|
+
return expo::convertJSIObjectToNSDictionary(*runtime, _value->getObject(*runtime), [_runtime callInvoker]);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
- (nonnull EXJavaScriptObject *)getObject
|
|
152
|
+
{
|
|
153
|
+
jsi::Runtime *runtime = [_runtime get];
|
|
154
|
+
std::shared_ptr<jsi::Object> objectPtr = std::make_shared<jsi::Object>(_value->asObject(*runtime));
|
|
155
|
+
return [[EXJavaScriptObject alloc] initWith:objectPtr runtime:_runtime];
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
#pragma mark - Helpers
|
|
159
|
+
|
|
160
|
+
- (nonnull NSString *)toString
|
|
161
|
+
{
|
|
162
|
+
jsi::Runtime *runtime = [_runtime get];
|
|
163
|
+
return expo::convertJSIStringToNSString(*runtime, _value->toString(*runtime));
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
@end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Copyright 2022-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
#ifdef __cplusplus
|
|
4
|
+
|
|
5
|
+
#import <vector>
|
|
6
|
+
#import <jsi/jsi.h>
|
|
7
|
+
|
|
8
|
+
namespace jsi = facebook::jsi;
|
|
9
|
+
|
|
10
|
+
@class SwiftInteropBridge;
|
|
11
|
+
|
|
12
|
+
namespace expo {
|
|
13
|
+
|
|
14
|
+
class JSI_EXPORT ExpoModulesHostObject : public jsi::HostObject {
|
|
15
|
+
public:
|
|
16
|
+
ExpoModulesHostObject(SwiftInteropBridge *interopBridge);
|
|
17
|
+
|
|
18
|
+
virtual ~ExpoModulesHostObject();
|
|
19
|
+
|
|
20
|
+
jsi::Value get(jsi::Runtime &, const jsi::PropNameID &name) override;
|
|
21
|
+
|
|
22
|
+
void set(jsi::Runtime &, const jsi::PropNameID &name, const jsi::Value &value) override;
|
|
23
|
+
|
|
24
|
+
std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime &rt) override;
|
|
25
|
+
|
|
26
|
+
private:
|
|
27
|
+
SwiftInteropBridge *swiftInterop;
|
|
28
|
+
|
|
29
|
+
}; // class ExpoModulesHostObject
|
|
30
|
+
|
|
31
|
+
} // namespace expo
|
|
32
|
+
|
|
33
|
+
#endif
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// Copyright 2022-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
#import <ExpoModulesCore/ExpoModulesHostObject.h>
|
|
4
|
+
#import <ExpoModulesCore/EXJavaScriptObject.h>
|
|
5
|
+
#import <ExpoModulesCore/Swift.h>
|
|
6
|
+
|
|
7
|
+
namespace expo {
|
|
8
|
+
|
|
9
|
+
ExpoModulesHostObject::ExpoModulesHostObject(SwiftInteropBridge *swiftInterop) : swiftInterop(swiftInterop) {}
|
|
10
|
+
|
|
11
|
+
ExpoModulesHostObject::~ExpoModulesHostObject() {
|
|
12
|
+
[swiftInterop setRuntime:nil];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
jsi::Value ExpoModulesHostObject::get(jsi::Runtime &runtime, const jsi::PropNameID &name) {
|
|
16
|
+
NSString *moduleName = [NSString stringWithUTF8String:name.utf8(runtime).c_str()];
|
|
17
|
+
EXJavaScriptObject *nativeObject = [swiftInterop getNativeModuleObject:moduleName];
|
|
18
|
+
|
|
19
|
+
return nativeObject ? jsi::Value(runtime, *[nativeObject get]) : jsi::Value::undefined();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
void ExpoModulesHostObject::set(jsi::Runtime &runtime, const jsi::PropNameID &name, const jsi::Value &value) {
|
|
23
|
+
std::string message("RuntimeError: Cannot override the host object for expo module '");
|
|
24
|
+
message += name.utf8(runtime);
|
|
25
|
+
message += "'.";
|
|
26
|
+
throw jsi::JSError(runtime, message);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
std::vector<jsi::PropNameID> ExpoModulesHostObject::getPropertyNames(jsi::Runtime &runtime) {
|
|
30
|
+
NSArray<NSString *> *moduleNames = [swiftInterop getModuleNames];
|
|
31
|
+
std::vector<jsi::PropNameID> propertyNames;
|
|
32
|
+
|
|
33
|
+
propertyNames.reserve([moduleNames count]);
|
|
34
|
+
|
|
35
|
+
for (NSString *moduleName in moduleNames) {
|
|
36
|
+
propertyNames.push_back(jsi::PropNameID::forAscii(runtime, [moduleName UTF8String]));
|
|
37
|
+
}
|
|
38
|
+
return propertyNames;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
} // namespace expo
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// Copyright 2022-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
public extension JavaScriptRuntime {
|
|
4
|
+
/**
|
|
5
|
+
Evaluates JavaScript code represented as a string.
|
|
6
|
+
|
|
7
|
+
- Parameter source: A string representing a JavaScript expression, statement, or sequence of statements.
|
|
8
|
+
The expression can include variables and properties of existing objects.
|
|
9
|
+
- Returns: The completion value of evaluating the given code represented as `JavaScriptValue`.
|
|
10
|
+
If the completion value is empty, `undefined` is returned.
|
|
11
|
+
- Throws: `JavaScriptEvalException` when evaluated code has invalid syntax or throws an error.
|
|
12
|
+
- Note: It wraps the original `evaluateScript` to better handle and rethrow exceptions.
|
|
13
|
+
*/
|
|
14
|
+
func eval(_ source: String) throws -> JavaScriptValue {
|
|
15
|
+
do {
|
|
16
|
+
var result: JavaScriptValue?
|
|
17
|
+
try EXUtilities.catchException {
|
|
18
|
+
result = self.evaluateScript(source)
|
|
19
|
+
}
|
|
20
|
+
// There is no risk to force unwrapping as long as the `evaluateScript` returns nonnull value.
|
|
21
|
+
return result!
|
|
22
|
+
} catch {
|
|
23
|
+
throw JavaScriptEvalException(error as NSError)
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
internal final class JavaScriptEvalException: GenericException<NSError> {
|
|
29
|
+
override var reason: String {
|
|
30
|
+
return param.userInfo["message"] as? String ?? "unknown reason"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// Copyright 2022-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
Enum with available kinds of values. It's almost the same as a result of "typeof"
|
|
5
|
+
in JavaScript, however `null` has its own kind (typeof null == "object").
|
|
6
|
+
*/
|
|
7
|
+
public enum JavaScriptValueKind: String {
|
|
8
|
+
case undefined
|
|
9
|
+
case null
|
|
10
|
+
case bool
|
|
11
|
+
case number
|
|
12
|
+
case symbol
|
|
13
|
+
case string
|
|
14
|
+
case function
|
|
15
|
+
case object
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
public extension JavaScriptValue {
|
|
19
|
+
var kind: JavaScriptValueKind {
|
|
20
|
+
switch true {
|
|
21
|
+
case isUndefined():
|
|
22
|
+
return .undefined
|
|
23
|
+
case isNull():
|
|
24
|
+
return .null
|
|
25
|
+
case isBool():
|
|
26
|
+
return .bool
|
|
27
|
+
case isNumber():
|
|
28
|
+
return .number
|
|
29
|
+
case isSymbol():
|
|
30
|
+
return .symbol
|
|
31
|
+
case isString():
|
|
32
|
+
return .string
|
|
33
|
+
case isFunction():
|
|
34
|
+
return .function
|
|
35
|
+
default:
|
|
36
|
+
return .object
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
func asBool() throws -> Bool {
|
|
41
|
+
if isBool() {
|
|
42
|
+
return getBool()
|
|
43
|
+
}
|
|
44
|
+
throw JavaScriptValueConversionException((kind: kind, target: "Bool"))
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
func asInt() throws -> Int {
|
|
48
|
+
if isNumber() {
|
|
49
|
+
return getInt()
|
|
50
|
+
}
|
|
51
|
+
throw JavaScriptValueConversionException((kind: kind, target: "Int"))
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
func asDouble() throws -> Double {
|
|
55
|
+
if isNumber() {
|
|
56
|
+
return getDouble()
|
|
57
|
+
}
|
|
58
|
+
throw JavaScriptValueConversionException((kind: kind, target: "Double"))
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
func asString() throws -> String {
|
|
62
|
+
if isString() {
|
|
63
|
+
return getString()
|
|
64
|
+
}
|
|
65
|
+
throw JavaScriptValueConversionException((kind: kind, target: "String"))
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
func asArray() throws -> [JavaScriptValue?] {
|
|
69
|
+
if isObject() {
|
|
70
|
+
return getArray()
|
|
71
|
+
}
|
|
72
|
+
throw JavaScriptValueConversionException((kind: kind, target: "Array"))
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
func asDict() throws -> [String: Any] {
|
|
76
|
+
if isObject() {
|
|
77
|
+
return getDictionary()
|
|
78
|
+
}
|
|
79
|
+
throw JavaScriptValueConversionException((kind: kind, target: "Dict"))
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
func asObject() throws -> JavaScriptObject {
|
|
83
|
+
if isObject() {
|
|
84
|
+
return getObject()
|
|
85
|
+
}
|
|
86
|
+
throw JavaScriptValueConversionException((kind: kind, target: "Object"))
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
internal final class JavaScriptValueConversionException: GenericException<(kind: JavaScriptValueKind, target: String)> {
|
|
91
|
+
override var reason: String {
|
|
92
|
+
"Cannot represent a value of kind '\(param.kind)' as \(param.target)"
|
|
93
|
+
}
|
|
94
|
+
}
|