expo-modules-core 0.9.2 → 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +33 -3
- package/README.md +3 -3
- package/android/CMakeLists.txt +163 -0
- package/android/build.gradle +343 -5
- package/android/src/main/cpp/CachedReferencesRegistry.cpp +65 -0
- package/android/src/main/cpp/CachedReferencesRegistry.h +80 -0
- package/android/src/main/cpp/Exceptions.cpp +22 -0
- package/android/src/main/cpp/Exceptions.h +38 -0
- package/android/src/main/cpp/ExpoModulesHostObject.cpp +47 -0
- package/android/src/main/cpp/ExpoModulesHostObject.h +32 -0
- package/android/src/main/cpp/JNIFunctionBody.cpp +44 -0
- package/android/src/main/cpp/JNIFunctionBody.h +50 -0
- package/android/src/main/cpp/JNIInjector.cpp +23 -0
- package/android/src/main/cpp/JSIInteropModuleRegistry.cpp +122 -0
- package/android/src/main/cpp/JSIInteropModuleRegistry.h +96 -0
- package/android/src/main/cpp/JSIObjectWrapper.h +33 -0
- package/android/src/main/cpp/JSITypeConverter.h +84 -0
- package/android/src/main/cpp/JavaScriptModuleObject.cpp +219 -0
- package/android/src/main/cpp/JavaScriptModuleObject.h +144 -0
- package/android/src/main/cpp/JavaScriptObject.cpp +125 -0
- package/android/src/main/cpp/JavaScriptObject.h +131 -0
- package/android/src/main/cpp/JavaScriptRuntime.cpp +127 -0
- package/android/src/main/cpp/JavaScriptRuntime.h +87 -0
- package/android/src/main/cpp/JavaScriptValue.cpp +172 -0
- package/android/src/main/cpp/JavaScriptValue.h +78 -0
- package/android/src/main/cpp/MethodMetadata.cpp +340 -0
- package/android/src/main/cpp/MethodMetadata.h +131 -0
- package/android/src/main/java/expo/modules/adapters/react/NativeModulesProxy.java +2 -0
- package/android/src/main/java/expo/modules/core/errors/ContextDestroyedException.kt +7 -0
- package/android/src/main/java/expo/modules/interfaces/permissions/Permissions.java +30 -0
- package/android/src/main/java/expo/modules/kotlin/AppContext.kt +98 -3
- package/android/src/main/java/expo/modules/kotlin/ConcatIterator.kt +18 -0
- package/android/src/main/java/expo/modules/kotlin/KotlinInteropModuleRegistry.kt +15 -12
- package/android/src/main/java/expo/modules/kotlin/ModuleHolder.kt +45 -3
- package/android/src/main/java/expo/modules/kotlin/activityaware/AppCompatActivityAware.kt +49 -0
- package/android/src/main/java/expo/modules/kotlin/activityaware/AppCompatActivityAwareHelper.kt +43 -0
- package/android/src/main/java/expo/modules/kotlin/activityaware/OnActivityAvailableListener.kt +18 -0
- package/android/src/main/java/expo/modules/kotlin/activityresult/ActivityResultsManager.kt +99 -0
- package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultCaller.kt +25 -0
- package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultContract.kt +27 -0
- package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultFallbackCallback.kt +17 -0
- package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultLauncher.kt +30 -0
- package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultRegistry.kt +358 -0
- package/android/src/main/java/expo/modules/kotlin/activityresult/DataPersistor.kt +135 -0
- package/android/src/main/java/expo/modules/kotlin/defaultmodules/ErrorManagerModule.kt +2 -2
- package/android/src/main/java/expo/modules/kotlin/exception/CodedException.kt +13 -0
- package/android/src/main/java/expo/modules/kotlin/exception/ExceptionDecorator.kt +2 -0
- package/android/src/main/java/expo/modules/kotlin/functions/AnyFunction.kt +53 -15
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunction.kt +35 -7
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionBuilder.kt +13 -121
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionComponent.kt +21 -0
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromiseComponent.kt +21 -0
- package/android/src/main/java/expo/modules/kotlin/functions/SuspendFunctionComponent.kt +63 -0
- package/android/src/main/java/expo/modules/kotlin/functions/SyncFunctionComponent.kt +36 -0
- package/android/src/main/java/expo/modules/kotlin/jni/CppType.kt +19 -0
- package/android/src/main/java/expo/modules/kotlin/jni/JNIFunctionBody.kt +39 -0
- package/android/src/main/java/expo/modules/kotlin/jni/JSIInteropModuleRegistry.kt +89 -0
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptModuleObject.kt +46 -0
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptObject.kt +113 -0
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptValue.kt +35 -0
- package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +16 -6
- package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +5 -500
- package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionData.kt +30 -5
- package/android/src/main/java/expo/modules/kotlin/objects/ObjectDefinitionBuilder.kt +271 -0
- package/android/src/main/java/expo/modules/kotlin/objects/ObjectDefinitionData.kt +21 -0
- package/android/src/main/java/expo/modules/kotlin/objects/PropertyComponent.kt +54 -0
- package/android/src/main/java/expo/modules/kotlin/objects/PropertyComponentBuilder.kt +32 -0
- package/android/src/main/java/expo/modules/kotlin/providers/AppContextProvider.kt +14 -0
- package/android/src/main/java/expo/modules/kotlin/providers/CurrentActivityProvider.kt +22 -0
- package/android/src/main/java/expo/modules/kotlin/records/RecordTypeConverter.kt +19 -2
- package/android/src/main/java/expo/modules/kotlin/types/AnyType.kt +3 -2
- package/android/src/main/java/expo/modules/kotlin/types/AnyTypeConverter.kt +36 -0
- package/android/src/main/java/expo/modules/kotlin/types/ArrayTypeConverter.kt +7 -2
- package/android/src/main/java/expo/modules/kotlin/types/BasicTypeConverters.kt +68 -20
- package/android/src/main/java/expo/modules/kotlin/types/EnumTypeConverter.kt +50 -22
- package/android/src/main/java/expo/modules/kotlin/types/ListTypeConverter.kt +18 -2
- package/android/src/main/java/expo/modules/kotlin/types/MapTypeConverter.kt +18 -2
- package/android/src/main/java/expo/modules/kotlin/types/PairTypeConverter.kt +17 -2
- package/android/src/main/java/expo/modules/kotlin/types/TypeConverter.kt +43 -3
- package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +12 -0
- package/android/src/main/java/expo/modules/kotlin/views/ViewGroupDefinitionBuilder.kt +0 -41
- package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinitionBuilder.kt +0 -33
- package/build/NativeModulesProxy.native.d.ts.map +1 -1
- package/build/NativeModulesProxy.native.js +9 -3
- package/build/NativeModulesProxy.native.js.map +1 -1
- package/build/PermissionsInterface.d.ts +29 -0
- package/build/PermissionsInterface.d.ts.map +1 -1
- package/build/PermissionsInterface.js +9 -0
- package/build/PermissionsInterface.js.map +1 -1
- package/ios/AppDelegates/EXAppDelegatesLoader.m +1 -2
- package/ios/ExpoModulesCore.podspec +3 -2
- package/ios/JSI/EXJSIConversions.mm +6 -0
- package/ios/JSI/EXJSIInstaller.h +15 -21
- package/ios/JSI/EXJSIInstaller.mm +39 -3
- package/ios/JSI/EXJSIUtils.h +48 -3
- package/ios/JSI/EXJSIUtils.mm +88 -4
- package/ios/JSI/EXJavaScriptObject.h +11 -18
- package/ios/JSI/EXJavaScriptObject.mm +37 -18
- package/ios/JSI/EXJavaScriptRuntime.h +43 -9
- package/ios/JSI/EXJavaScriptRuntime.mm +70 -27
- package/ios/JSI/EXJavaScriptTypedArray.h +30 -0
- package/ios/JSI/EXJavaScriptTypedArray.mm +29 -0
- package/ios/JSI/EXJavaScriptValue.h +3 -2
- package/ios/JSI/EXJavaScriptValue.mm +17 -20
- package/ios/JSI/EXJavaScriptWeakObject.h +23 -0
- package/ios/JSI/EXJavaScriptWeakObject.mm +53 -0
- package/ios/JSI/EXObjectDeallocator.h +27 -0
- package/ios/JSI/ExpoModulesHostObject.h +3 -3
- package/ios/JSI/ExpoModulesHostObject.mm +4 -4
- package/ios/JSI/JavaScriptRuntime.swift +38 -1
- package/ios/JSI/JavaScriptValue.swift +7 -0
- package/ios/JSI/TypedArray.cpp +67 -0
- package/ios/JSI/TypedArray.h +46 -0
- package/ios/ModuleRegistryAdapter/EXModuleRegistryAdapter.m +0 -11
- package/ios/NativeModulesProxy/EXNativeModulesProxy.h +17 -10
- package/ios/NativeModulesProxy/EXNativeModulesProxy.mm +86 -77
- package/ios/NativeModulesProxy/NativeModulesProxyModule.swift +17 -0
- package/ios/Services/EXReactNativeEventEmitter.h +2 -2
- package/ios/Services/EXReactNativeEventEmitter.m +11 -6
- package/ios/Swift/AppContext.swift +206 -28
- package/ios/Swift/Arguments/AnyArgument.swift +18 -0
- package/ios/Swift/Arguments/{Types/EnumArgumentType.swift → EnumArgument.swift} +2 -17
- package/ios/Swift/Classes/ClassComponent.swift +95 -0
- package/ios/Swift/Classes/ClassComponentElement.swift +33 -0
- package/ios/Swift/Classes/ClassComponentElementsBuilder.swift +34 -0
- package/ios/Swift/Classes/ClassComponentFactories.swift +96 -0
- package/ios/Swift/DynamicTypes/AnyDynamicType.swift +44 -0
- package/ios/Swift/DynamicTypes/DynamicArrayType.swift +56 -0
- package/ios/Swift/DynamicTypes/DynamicConvertibleType.swift +27 -0
- package/ios/Swift/DynamicTypes/DynamicEnumType.swift +27 -0
- package/ios/Swift/DynamicTypes/DynamicOptionalType.swift +63 -0
- package/ios/Swift/DynamicTypes/DynamicRawType.swift +33 -0
- package/ios/Swift/DynamicTypes/DynamicSharedObjectType.swift +37 -0
- package/ios/Swift/DynamicTypes/DynamicType.swift +39 -0
- package/ios/Swift/DynamicTypes/DynamicTypedArrayType.swift +46 -0
- package/ios/Swift/Exceptions/ChainableException.swift +3 -3
- package/ios/Swift/Exceptions/CodedError.swift +1 -1
- package/ios/Swift/Exceptions/Exception.swift +8 -6
- package/ios/Swift/Exceptions/UnexpectedException.swift +2 -1
- package/ios/Swift/ExpoBridgeModule.m +5 -0
- package/ios/Swift/ExpoBridgeModule.swift +79 -0
- package/ios/Swift/Functions/AnyFunction.swift +33 -31
- package/ios/Swift/Functions/AsyncFunctionComponent.swift +196 -59
- package/ios/Swift/Functions/SyncFunctionComponent.swift +142 -58
- package/ios/Swift/JavaScriptUtils.swift +32 -57
- package/ios/Swift/Logging/LogHandlers.swift +39 -0
- package/ios/Swift/Logging/LogType.swift +62 -0
- package/ios/Swift/Logging/Logger.swift +201 -0
- package/ios/Swift/ModuleHolder.swift +19 -54
- package/ios/Swift/ModuleRegistry.swift +7 -1
- package/ios/Swift/Modules/AnyModule.swift +3 -3
- package/ios/Swift/ModulesProvider.swift +2 -0
- package/ios/Swift/Objects/JavaScriptObjectBuilder.swift +37 -0
- package/ios/Swift/Objects/ObjectDefinition.swift +74 -1
- package/ios/Swift/Objects/ObjectDefinitionComponents.swift +77 -68
- package/ios/Swift/Objects/PropertyComponent.swift +147 -0
- package/ios/Swift/Promise.swift +17 -4
- package/ios/Swift/Records/Field.swift +2 -2
- package/ios/Swift/SharedObjects/SharedObject.swift +20 -0
- package/ios/Swift/SharedObjects/SharedObjectRegistry.swift +129 -0
- package/ios/Swift/TypedArrays/AnyTypedArray.swift +11 -0
- package/ios/Swift/TypedArrays/ConcreteTypedArrays.swift +56 -0
- package/ios/Swift/TypedArrays/GenericTypedArray.swift +49 -0
- package/ios/Swift/TypedArrays/TypedArray.swift +80 -0
- package/ios/Swift/Utilities.swift +28 -0
- package/ios/Swift/Views/ConcreteViewProp.swift +3 -3
- package/ios/Swift/Views/ViewManagerDefinitionComponents.swift +2 -2
- package/ios/Tests/ClassComponentSpec.swift +210 -0
- package/ios/Tests/DynamicTypeSpec.swift +336 -0
- package/ios/Tests/EnumArgumentSpec.swift +48 -0
- package/ios/Tests/ExpoModulesSpec.swift +17 -3
- package/ios/Tests/FunctionSpec.swift +167 -118
- package/ios/Tests/Mocks/ModuleMocks.swift +1 -1
- package/ios/Tests/PropertyComponentSpec.swift +95 -0
- package/ios/Tests/SharedObjectRegistrySpec.swift +109 -0
- package/ios/Tests/TypedArraysSpec.swift +136 -0
- package/package.json +2 -2
- package/src/NativeModulesProxy.native.ts +13 -3
- package/src/PermissionsInterface.ts +29 -0
- package/src/ts-declarations/ExpoModules.d.ts +7 -0
- package/tsconfig.json +1 -1
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromise.kt +0 -15
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncSuspendFunction.kt +0 -36
- package/ios/Swift/Arguments/AnyArgumentType.swift +0 -13
- package/ios/Swift/Arguments/ArgumentType.swift +0 -28
- package/ios/Swift/Arguments/Types/ArrayArgumentType.swift +0 -42
- package/ios/Swift/Arguments/Types/ConvertibleArgumentType.swift +0 -16
- package/ios/Swift/Arguments/Types/OptionalArgumentType.swift +0 -49
- package/ios/Swift/Arguments/Types/PromiseArgumentType.swift +0 -15
- package/ios/Swift/Arguments/Types/RawArgumentType.swift +0 -25
- package/ios/Swift/Functions/ConcreteFunction.swift +0 -103
- package/ios/Swift/SwiftInteropBridge.swift +0 -155
- package/ios/Tests/ArgumentTypeSpec.swift +0 -143
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
// Copyright 2018-present 650 Industries. All rights reserved.
|
|
2
2
|
|
|
3
|
+
#import <Foundation/Foundation.h>
|
|
3
4
|
#import <ExpoModulesCore/EXJavaScriptValue.h>
|
|
4
5
|
#import <ExpoModulesCore/EXJavaScriptObject.h>
|
|
6
|
+
#import <React/RCTBridgeModule.h>
|
|
5
7
|
|
|
6
8
|
#ifdef __cplusplus
|
|
7
9
|
#import <ReactCommon/CallInvoker.h>
|
|
@@ -13,8 +15,20 @@ namespace react = facebook::react;
|
|
|
13
15
|
@class EXJavaScriptValue;
|
|
14
16
|
@class EXJavaScriptObject;
|
|
15
17
|
|
|
18
|
+
typedef void (^JSAsyncFunctionBlock)(EXJavaScriptValue * _Nonnull thisValue,
|
|
19
|
+
NSArray<EXJavaScriptValue *> * _Nonnull arguments,
|
|
20
|
+
RCTPromiseResolveBlock _Nonnull resolve,
|
|
21
|
+
RCTPromiseRejectBlock _Nonnull reject);
|
|
22
|
+
|
|
23
|
+
typedef id _Nullable (^JSSyncFunctionBlock)(EXJavaScriptValue * _Nonnull thisValue,
|
|
24
|
+
NSArray<EXJavaScriptValue *> * _Nonnull arguments,
|
|
25
|
+
NSError * _Nullable __autoreleasing * _Nullable error);
|
|
26
|
+
|
|
16
27
|
#ifdef __cplusplus
|
|
17
|
-
typedef jsi::Value (^JSHostFunctionBlock)(jsi::Runtime &runtime,
|
|
28
|
+
typedef jsi::Value (^JSHostFunctionBlock)(jsi::Runtime &runtime,
|
|
29
|
+
std::shared_ptr<react::CallInvoker> callInvoker,
|
|
30
|
+
EXJavaScriptValue * _Nonnull thisValue,
|
|
31
|
+
NSArray<EXJavaScriptValue *> * _Nonnull arguments);
|
|
18
32
|
#endif // __cplusplus
|
|
19
33
|
|
|
20
34
|
NS_SWIFT_NAME(JavaScriptRuntime)
|
|
@@ -26,6 +40,7 @@ NS_SWIFT_NAME(JavaScriptRuntime)
|
|
|
26
40
|
- (nonnull instancetype)init;
|
|
27
41
|
|
|
28
42
|
#ifdef __cplusplus
|
|
43
|
+
|
|
29
44
|
- (nonnull instancetype)initWithRuntime:(nonnull jsi::Runtime *)runtime
|
|
30
45
|
callInvoker:(std::shared_ptr<react::CallInvoker>)callInvoker;
|
|
31
46
|
|
|
@@ -44,13 +59,6 @@ NS_SWIFT_NAME(JavaScriptRuntime)
|
|
|
44
59
|
*/
|
|
45
60
|
- (nonnull EXJavaScriptObject *)createHostObject:(std::shared_ptr<jsi::HostObject>)jsiHostObjectPtr;
|
|
46
61
|
|
|
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
62
|
#endif // __cplusplus
|
|
55
63
|
|
|
56
64
|
/**
|
|
@@ -63,11 +71,37 @@ NS_SWIFT_NAME(JavaScriptRuntime)
|
|
|
63
71
|
*/
|
|
64
72
|
- (nonnull EXJavaScriptObject *)createObject;
|
|
65
73
|
|
|
74
|
+
/**
|
|
75
|
+
Creates a synchronous host function that runs given block when it's called.
|
|
76
|
+
The value returned by the block is synchronously returned to JS.
|
|
77
|
+
\return A JavaScript function represented as a `JavaScriptObject`.
|
|
78
|
+
*/
|
|
79
|
+
- (nonnull EXJavaScriptObject *)createSyncFunction:(nonnull NSString *)name
|
|
80
|
+
argsCount:(NSInteger)argsCount
|
|
81
|
+
block:(nonnull JSSyncFunctionBlock)block NS_REFINED_FOR_SWIFT;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
Creates an asynchronous host function that runs given block when it's called.
|
|
85
|
+
The block receives a resolver that you should call when the asynchronous operation
|
|
86
|
+
succeeds and a rejecter to call whenever it fails.
|
|
87
|
+
\return A JavaScript function represented as a `JavaScriptObject`.
|
|
88
|
+
*/
|
|
89
|
+
- (nonnull EXJavaScriptObject *)createAsyncFunction:(nonnull NSString *)name
|
|
90
|
+
argsCount:(NSInteger)argsCount
|
|
91
|
+
block:(nonnull JSAsyncFunctionBlock)block;
|
|
92
|
+
|
|
93
|
+
#pragma mark - Classes
|
|
94
|
+
|
|
95
|
+
typedef void (^ClassConstructorBlock)(EXJavaScriptObject * _Nonnull thisValue, NSArray<EXJavaScriptValue *> * _Nonnull arguments);
|
|
96
|
+
|
|
97
|
+
- (nonnull EXJavaScriptObject *)createClass:(nonnull NSString *)name
|
|
98
|
+
constructor:(nonnull ClassConstructorBlock)constructor;
|
|
99
|
+
|
|
66
100
|
#pragma mark - Script evaluation
|
|
67
101
|
|
|
68
102
|
/**
|
|
69
103
|
Evaluates given JavaScript source code.
|
|
70
104
|
*/
|
|
71
|
-
- (nonnull EXJavaScriptValue *)evaluateScript:(nonnull NSString *)scriptSource;
|
|
105
|
+
- (nonnull EXJavaScriptValue *)evaluateScript:(nonnull NSString *)scriptSource NS_REFINED_FOR_SWIFT;
|
|
72
106
|
|
|
73
107
|
@end
|
|
@@ -82,33 +82,66 @@ using namespace facebook;
|
|
|
82
82
|
return [[EXJavaScriptObject alloc] initWith:jsGlobalPtr runtime:self];
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
- (
|
|
86
|
-
|
|
87
|
-
|
|
85
|
+
- (nonnull EXJavaScriptObject *)createSyncFunction:(nonnull NSString *)name
|
|
86
|
+
argsCount:(NSInteger)argsCount
|
|
87
|
+
block:(nonnull JSSyncFunctionBlock)block
|
|
88
88
|
{
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
89
|
+
JSHostFunctionBlock hostFunctionBlock = ^jsi::Value(
|
|
90
|
+
jsi::Runtime &runtime,
|
|
91
|
+
std::shared_ptr<react::CallInvoker> callInvoker,
|
|
92
|
+
EXJavaScriptValue * _Nonnull thisValue,
|
|
93
|
+
NSArray<EXJavaScriptValue *> * _Nonnull arguments) {
|
|
94
|
+
NSError *error;
|
|
95
|
+
id result = block(thisValue, arguments, &error);
|
|
96
|
+
|
|
97
|
+
if (error == nil) {
|
|
98
|
+
return expo::convertObjCObjectToJSIValue(runtime, result);
|
|
99
|
+
} else {
|
|
100
|
+
throw jsi::JSError(runtime, [error.userInfo[@"message"] UTF8String]);
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
return [self createHostFunction:name argsCount:argsCount block:hostFunctionBlock];
|
|
92
104
|
}
|
|
93
105
|
|
|
94
|
-
- (
|
|
95
|
-
|
|
96
|
-
|
|
106
|
+
- (nonnull EXJavaScriptObject *)createAsyncFunction:(nonnull NSString *)name
|
|
107
|
+
argsCount:(NSInteger)argsCount
|
|
108
|
+
block:(nonnull JSAsyncFunctionBlock)block
|
|
97
109
|
{
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
110
|
+
JSHostFunctionBlock hostFunctionBlock = ^jsi::Value(
|
|
111
|
+
jsi::Runtime &runtime,
|
|
112
|
+
std::shared_ptr<react::CallInvoker> callInvoker,
|
|
113
|
+
EXJavaScriptValue * _Nonnull thisValue,
|
|
114
|
+
NSArray<EXJavaScriptValue *> * _Nonnull arguments) {
|
|
115
|
+
if (!callInvoker) {
|
|
116
|
+
// In mocked environment the call invoker may be null so it's not supported to call async functions.
|
|
117
|
+
// Testing async functions is a bit more complicated anyway. See `init` description for more.
|
|
118
|
+
throw jsi::JSError(runtime, "Calling async functions is not supported when the call invoker is unavailable");
|
|
119
|
+
}
|
|
120
|
+
// The function that is invoked as a setup of the EXJavaScript `Promise`.
|
|
121
|
+
auto promiseSetup = [callInvoker, block, thisValue, arguments](jsi::Runtime &runtime, std::shared_ptr<Promise> promise) {
|
|
122
|
+
expo::callPromiseSetupWithBlock(runtime, callInvoker, promise, ^(RCTPromiseResolveBlock resolver, RCTPromiseRejectBlock rejecter) {
|
|
123
|
+
block(thisValue, arguments, resolver, rejecter);
|
|
124
|
+
});
|
|
125
|
+
};
|
|
126
|
+
return createPromiseAsJSIValue(runtime, promiseSetup);
|
|
109
127
|
};
|
|
110
|
-
|
|
111
|
-
|
|
128
|
+
return [self createHostFunction:name argsCount:argsCount block:hostFunctionBlock];
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
#pragma mark - Classes
|
|
132
|
+
|
|
133
|
+
- (nonnull EXJavaScriptObject *)createClass:(nonnull NSString *)name
|
|
134
|
+
constructor:(nonnull ClassConstructorBlock)constructor
|
|
135
|
+
{
|
|
136
|
+
expo::ClassConstructor jsConstructor = [self, constructor](jsi::Runtime &runtime, const jsi::Value &thisValue, const jsi::Value *args, size_t count) {
|
|
137
|
+
std::shared_ptr<jsi::Object> thisPtr = std::make_shared<jsi::Object>(thisValue.asObject(runtime));
|
|
138
|
+
EXJavaScriptObject *caller = [[EXJavaScriptObject alloc] initWith:thisPtr runtime:self];
|
|
139
|
+
NSArray<EXJavaScriptValue *> *arguments = expo::convertJSIValuesToNSArray(self, args, count);
|
|
140
|
+
|
|
141
|
+
constructor(caller, arguments);
|
|
142
|
+
};
|
|
143
|
+
std::shared_ptr<jsi::Function> klass = expo::createClass(*_runtime, [name UTF8String], jsConstructor);
|
|
144
|
+
return [[EXJavaScriptObject alloc] initWith:klass runtime:self];
|
|
112
145
|
}
|
|
113
146
|
|
|
114
147
|
#pragma mark - Script evaluation
|
|
@@ -128,15 +161,21 @@ using namespace facebook;
|
|
|
128
161
|
@"message": reason,
|
|
129
162
|
@"stack": stack,
|
|
130
163
|
}];
|
|
164
|
+
} catch (jsi::JSIException &error) {
|
|
165
|
+
NSString *reason = [NSString stringWithUTF8String:error.what()];
|
|
166
|
+
|
|
167
|
+
@throw [NSException exceptionWithName:@"ScriptEvaluationException" reason:reason userInfo:@{
|
|
168
|
+
@"message": reason
|
|
169
|
+
}];
|
|
131
170
|
}
|
|
132
171
|
return [[EXJavaScriptValue alloc] initWithRuntime:self value:result];
|
|
133
172
|
}
|
|
134
173
|
|
|
135
174
|
#pragma mark - Private
|
|
136
175
|
|
|
137
|
-
- (
|
|
138
|
-
|
|
139
|
-
|
|
176
|
+
- (nonnull EXJavaScriptObject *)createHostFunction:(nonnull NSString *)name
|
|
177
|
+
argsCount:(NSInteger)argsCount
|
|
178
|
+
block:(nonnull JSHostFunctionBlock)block
|
|
140
179
|
{
|
|
141
180
|
jsi::PropNameID propNameId = jsi::PropNameID::forAscii(*_runtime, [name UTF8String], [name length]);
|
|
142
181
|
std::weak_ptr<react::CallInvoker> weakCallInvoker = _jsCallInvoker;
|
|
@@ -145,9 +184,13 @@ using namespace facebook;
|
|
|
145
184
|
// there is no need to care about that for synchronous calls, so it's ensured in `createAsyncFunction` instead.
|
|
146
185
|
auto callInvoker = weakCallInvoker.lock();
|
|
147
186
|
NSArray<EXJavaScriptValue *> *arguments = expo::convertJSIValuesToNSArray(self, args, count);
|
|
148
|
-
|
|
187
|
+
std::shared_ptr<jsi::Value> thisValPtr = std::make_shared<jsi::Value>(runtime, std::move(thisVal));
|
|
188
|
+
EXJavaScriptValue *thisValue = [[EXJavaScriptValue alloc] initWithRuntime:self value:thisValPtr];
|
|
189
|
+
|
|
190
|
+
return block(runtime, callInvoker, thisValue, arguments);
|
|
149
191
|
};
|
|
150
|
-
|
|
192
|
+
std::shared_ptr<jsi::Object> fnPtr = std::make_shared<jsi::Object>(jsi::Function::createFromHostFunction(*_runtime, propNameId, (unsigned int)argsCount, function));
|
|
193
|
+
return [[EXJavaScriptObject alloc] initWith:fnPtr runtime:self];
|
|
151
194
|
}
|
|
152
195
|
|
|
153
196
|
@end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Copyright 2022-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
#import <Foundation/Foundation.h>
|
|
4
|
+
#import <ExpoModulesCore/EXJavaScriptObject.h>
|
|
5
|
+
#import <ExpoModulesCore/EXJavaScriptRuntime.h>
|
|
6
|
+
|
|
7
|
+
// We need to redefine the C++ enum (see TypedArray.h) in an Objective-C way to expose it to Swift.
|
|
8
|
+
// Please keep them in-sync!
|
|
9
|
+
typedef NS_ENUM(NSInteger, EXTypedArrayKind) {
|
|
10
|
+
Int8Array = 1,
|
|
11
|
+
Int16Array = 2,
|
|
12
|
+
Int32Array = 3,
|
|
13
|
+
Uint8Array = 4,
|
|
14
|
+
Uint8ClampedArray = 5,
|
|
15
|
+
Uint16Array = 6,
|
|
16
|
+
Uint32Array = 7,
|
|
17
|
+
Float32Array = 8,
|
|
18
|
+
Float64Array = 9,
|
|
19
|
+
BigInt64Array = 10,
|
|
20
|
+
BigUint64Array = 11,
|
|
21
|
+
} NS_SWIFT_NAME(TypedArrayKind);
|
|
22
|
+
|
|
23
|
+
NS_SWIFT_NAME(JavaScriptTypedArray)
|
|
24
|
+
@interface EXJavaScriptTypedArray : EXJavaScriptObject
|
|
25
|
+
|
|
26
|
+
@property (nonatomic) EXTypedArrayKind kind;
|
|
27
|
+
|
|
28
|
+
- (nonnull void *)getUnsafeMutableRawPointer;
|
|
29
|
+
|
|
30
|
+
@end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Copyright 2022-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
#import <ExpoModulesCore/EXJavaScriptTypedArray.h>
|
|
4
|
+
#import <ExpoModulesCore/TypedArray.h>
|
|
5
|
+
|
|
6
|
+
@implementation EXJavaScriptTypedArray {
|
|
7
|
+
__weak EXJavaScriptRuntime *_runtime;
|
|
8
|
+
|
|
9
|
+
std::shared_ptr<expo::TypedArray> _typedArrayPtr;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
- (nonnull instancetype)initWith:(std::shared_ptr<jsi::Object>)jsObjectPtr
|
|
13
|
+
runtime:(EXJavaScriptRuntime *)runtime
|
|
14
|
+
{
|
|
15
|
+
if (self = [super initWith:jsObjectPtr runtime:runtime]) {
|
|
16
|
+
jsi::Runtime *rt = [runtime get];
|
|
17
|
+
_runtime = runtime;
|
|
18
|
+
_typedArrayPtr = std::make_shared<expo::TypedArray>(*rt, *jsObjectPtr.get());
|
|
19
|
+
_kind = (EXTypedArrayKind)_typedArrayPtr->getKind(*rt);
|
|
20
|
+
}
|
|
21
|
+
return self;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
- (nonnull void *)getUnsafeMutableRawPointer
|
|
25
|
+
{
|
|
26
|
+
return _typedArrayPtr->getRawPointer(*[_runtime get]);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@end
|
|
@@ -9,6 +9,7 @@ namespace jsi = facebook::jsi;
|
|
|
9
9
|
#endif // __cplusplus
|
|
10
10
|
|
|
11
11
|
@class EXJavaScriptRuntime;
|
|
12
|
+
@class EXJavaScriptTypedArray;
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
Represents any JavaScript value. Its purpose is to exposes `facebook::jsi::Value` API back to Swift.
|
|
@@ -36,8 +37,7 @@ NS_SWIFT_NAME(JavaScriptValue)
|
|
|
36
37
|
- (BOOL)isSymbol;
|
|
37
38
|
- (BOOL)isObject;
|
|
38
39
|
- (BOOL)isFunction;
|
|
39
|
-
|
|
40
|
-
+ (nonnull NSString *)kindOf:(nonnull EXJavaScriptValue *)value;
|
|
40
|
+
- (BOOL)isTypedArray;
|
|
41
41
|
|
|
42
42
|
#pragma mark - Type casting
|
|
43
43
|
|
|
@@ -49,6 +49,7 @@ NS_SWIFT_NAME(JavaScriptValue)
|
|
|
49
49
|
- (nonnull NSArray<EXJavaScriptValue *> *)getArray;
|
|
50
50
|
- (nonnull NSDictionary<NSString *, id> *)getDictionary;
|
|
51
51
|
- (nonnull EXJavaScriptObject *)getObject;
|
|
52
|
+
- (nullable EXJavaScriptTypedArray *)getTypedArray;
|
|
52
53
|
|
|
53
54
|
#pragma mark - Helpers
|
|
54
55
|
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
#import <ExpoModulesCore/EXJSIConversions.h>
|
|
4
4
|
#import <ExpoModulesCore/EXJavaScriptValue.h>
|
|
5
5
|
#import <ExpoModulesCore/EXJavaScriptRuntime.h>
|
|
6
|
+
#import <ExpoModulesCore/EXJavaScriptTypedArray.h>
|
|
7
|
+
#import <ExpoModulesCore/TypedArray.h>
|
|
6
8
|
|
|
7
9
|
@implementation EXJavaScriptValue {
|
|
8
10
|
__weak EXJavaScriptRuntime *_runtime;
|
|
@@ -70,28 +72,13 @@
|
|
|
70
72
|
return false;
|
|
71
73
|
}
|
|
72
74
|
|
|
73
|
-
|
|
75
|
+
- (BOOL)isTypedArray
|
|
74
76
|
{
|
|
75
|
-
if (
|
|
76
|
-
|
|
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";
|
|
77
|
+
if (_value->isObject()) {
|
|
78
|
+
jsi::Runtime *runtime = [_runtime get];
|
|
79
|
+
return expo::isTypedArray(*runtime, _value->getObject(*runtime));
|
|
92
80
|
}
|
|
93
|
-
|
|
94
|
-
return @"object";
|
|
81
|
+
return false;
|
|
95
82
|
}
|
|
96
83
|
|
|
97
84
|
#pragma mark - Type casting
|
|
@@ -155,6 +142,16 @@
|
|
|
155
142
|
return [[EXJavaScriptObject alloc] initWith:objectPtr runtime:_runtime];
|
|
156
143
|
}
|
|
157
144
|
|
|
145
|
+
- (nullable EXJavaScriptTypedArray *)getTypedArray
|
|
146
|
+
{
|
|
147
|
+
if (![self isTypedArray]) {
|
|
148
|
+
return nil;
|
|
149
|
+
}
|
|
150
|
+
jsi::Runtime *runtime = [_runtime get];
|
|
151
|
+
std::shared_ptr<jsi::Object> objectPtr = std::make_shared<jsi::Object>(_value->asObject(*runtime));
|
|
152
|
+
return [[EXJavaScriptTypedArray alloc] initWith:objectPtr runtime:_runtime];
|
|
153
|
+
}
|
|
154
|
+
|
|
158
155
|
#pragma mark - Helpers
|
|
159
156
|
|
|
160
157
|
- (nonnull NSString *)toString
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Copyright 2022-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
#import <Foundation/Foundation.h>
|
|
4
|
+
#import <ExpoModulesCore/EXJavaScriptValue.h>
|
|
5
|
+
#import <ExpoModulesCore/EXJavaScriptRuntime.h>
|
|
6
|
+
|
|
7
|
+
#ifdef __cplusplus
|
|
8
|
+
#import <jsi/jsi.h>
|
|
9
|
+
|
|
10
|
+
namespace jsi = facebook::jsi;
|
|
11
|
+
#endif // __cplusplus
|
|
12
|
+
|
|
13
|
+
NS_SWIFT_NAME(JavaScriptWeakObject)
|
|
14
|
+
@interface EXJavaScriptWeakObject : NSObject
|
|
15
|
+
|
|
16
|
+
#ifdef __cplusplus
|
|
17
|
+
- (nonnull instancetype)initWith:(std::shared_ptr<jsi::Object>)jsObject
|
|
18
|
+
runtime:(nonnull EXJavaScriptRuntime *)runtime;
|
|
19
|
+
#endif // __cplusplus
|
|
20
|
+
|
|
21
|
+
- (nullable EXJavaScriptObject *)lock;
|
|
22
|
+
|
|
23
|
+
@end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// Copyright 2022-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
#import <ExpoModulesCore/EXJSIUtils.h>
|
|
4
|
+
#import <ExpoModulesCore/EXJavaScriptWeakObject.h>
|
|
5
|
+
|
|
6
|
+
@implementation EXJavaScriptWeakObject {
|
|
7
|
+
/**
|
|
8
|
+
Pointer to the `EXJavaScriptRuntime` wrapper.
|
|
9
|
+
|
|
10
|
+
\note It must be weak because only then the original runtime can be safely deallocated
|
|
11
|
+
when the JS engine wants to without unsetting it on each created object.
|
|
12
|
+
*/
|
|
13
|
+
__weak EXJavaScriptRuntime *_runtime;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
Shared pointer to the `WeakRef` JS object.
|
|
17
|
+
*/
|
|
18
|
+
std::shared_ptr<jsi::Object> _jsObject;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
- (nonnull instancetype)initWith:(std::shared_ptr<jsi::Object>)jsObject
|
|
22
|
+
runtime:(nonnull EXJavaScriptRuntime *)runtime
|
|
23
|
+
{
|
|
24
|
+
if (self = [super init]) {
|
|
25
|
+
_runtime = runtime;
|
|
26
|
+
|
|
27
|
+
// Check whether the runtime supports `WeakRef` objects. If it does not,
|
|
28
|
+
// we consciously hold a strong reference to the object and cause memory leaks.
|
|
29
|
+
// This is the case on hermes and JSC prior to iOS 14.5.
|
|
30
|
+
// TODO: (@tsapeta) Use `jsi::WeakObject` on hermes
|
|
31
|
+
if (expo::isWeakRefSupported(*[runtime get])) {
|
|
32
|
+
_jsObject = expo::createWeakRef(*[runtime get], jsObject);
|
|
33
|
+
} else {
|
|
34
|
+
_jsObject = jsObject;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return self;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
- (nullable EXJavaScriptObject *)lock
|
|
41
|
+
{
|
|
42
|
+
jsi::Runtime *runtime = [_runtime get];
|
|
43
|
+
std::shared_ptr<jsi::Object> objectPtr = expo::isWeakRefSupported(*runtime)
|
|
44
|
+
? expo::derefWeakRef(*runtime, _jsObject)
|
|
45
|
+
: _jsObject;
|
|
46
|
+
|
|
47
|
+
if (!objectPtr) {
|
|
48
|
+
return nil;
|
|
49
|
+
}
|
|
50
|
+
return [[EXJavaScriptObject alloc] initWith:objectPtr runtime:_runtime];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
@end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// Copyright 2022-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
#ifdef __cplusplus
|
|
4
|
+
|
|
5
|
+
#import <jsi/jsi.h>
|
|
6
|
+
|
|
7
|
+
namespace jsi = facebook::jsi;
|
|
8
|
+
|
|
9
|
+
namespace expo {
|
|
10
|
+
|
|
11
|
+
typedef void (^ObjectDeallocatorBlock)();
|
|
12
|
+
|
|
13
|
+
class JSI_EXPORT ObjectDeallocator : public jsi::HostObject {
|
|
14
|
+
public:
|
|
15
|
+
ObjectDeallocator(const ObjectDeallocatorBlock deallocator) : deallocator(deallocator) {};
|
|
16
|
+
|
|
17
|
+
virtual ~ObjectDeallocator() {
|
|
18
|
+
deallocator();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const ObjectDeallocatorBlock deallocator;
|
|
22
|
+
|
|
23
|
+
}; // class ObjectDeallocator
|
|
24
|
+
|
|
25
|
+
} // namespace expo
|
|
26
|
+
|
|
27
|
+
#endif
|
|
@@ -7,13 +7,13 @@
|
|
|
7
7
|
|
|
8
8
|
namespace jsi = facebook::jsi;
|
|
9
9
|
|
|
10
|
-
@class
|
|
10
|
+
@class EXAppContext;
|
|
11
11
|
|
|
12
12
|
namespace expo {
|
|
13
13
|
|
|
14
14
|
class JSI_EXPORT ExpoModulesHostObject : public jsi::HostObject {
|
|
15
15
|
public:
|
|
16
|
-
ExpoModulesHostObject(
|
|
16
|
+
ExpoModulesHostObject(EXAppContext *appContext);
|
|
17
17
|
|
|
18
18
|
virtual ~ExpoModulesHostObject();
|
|
19
19
|
|
|
@@ -24,7 +24,7 @@ public:
|
|
|
24
24
|
std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime &rt) override;
|
|
25
25
|
|
|
26
26
|
private:
|
|
27
|
-
|
|
27
|
+
EXAppContext *appContext;
|
|
28
28
|
|
|
29
29
|
}; // class ExpoModulesHostObject
|
|
30
30
|
|
|
@@ -6,15 +6,15 @@
|
|
|
6
6
|
|
|
7
7
|
namespace expo {
|
|
8
8
|
|
|
9
|
-
ExpoModulesHostObject::ExpoModulesHostObject(
|
|
9
|
+
ExpoModulesHostObject::ExpoModulesHostObject(EXAppContext *appContext) : appContext(appContext) {}
|
|
10
10
|
|
|
11
11
|
ExpoModulesHostObject::~ExpoModulesHostObject() {
|
|
12
|
-
[
|
|
12
|
+
[appContext setRuntime:nil];
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
jsi::Value ExpoModulesHostObject::get(jsi::Runtime &runtime, const jsi::PropNameID &name) {
|
|
16
16
|
NSString *moduleName = [NSString stringWithUTF8String:name.utf8(runtime).c_str()];
|
|
17
|
-
EXJavaScriptObject *nativeObject = [
|
|
17
|
+
EXJavaScriptObject *nativeObject = [appContext getNativeModuleObject:moduleName];
|
|
18
18
|
|
|
19
19
|
return nativeObject ? jsi::Value(runtime, *[nativeObject get]) : jsi::Value::undefined();
|
|
20
20
|
}
|
|
@@ -27,7 +27,7 @@ void ExpoModulesHostObject::set(jsi::Runtime &runtime, const jsi::PropNameID &na
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
std::vector<jsi::PropNameID> ExpoModulesHostObject::getPropertyNames(jsi::Runtime &runtime) {
|
|
30
|
-
NSArray<NSString *> *moduleNames = [
|
|
30
|
+
NSArray<NSString *> *moduleNames = [appContext getModuleNames];
|
|
31
31
|
std::vector<jsi::PropNameID> propertyNames;
|
|
32
32
|
|
|
33
33
|
propertyNames.reserve([moduleNames count]);
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
// Copyright 2022-present 650 Industries. All rights reserved.
|
|
2
2
|
|
|
3
3
|
public extension JavaScriptRuntime {
|
|
4
|
+
/**
|
|
5
|
+
A type of the closure that you pass to the `createSyncFunction` function.
|
|
6
|
+
*/
|
|
7
|
+
typealias SyncFunctionClosure = (_ this: JavaScriptValue, _ arguments: [JavaScriptValue]) throws -> Any
|
|
8
|
+
|
|
4
9
|
/**
|
|
5
10
|
Evaluates JavaScript code represented as a string.
|
|
6
11
|
|
|
@@ -11,11 +16,12 @@ public extension JavaScriptRuntime {
|
|
|
11
16
|
- Throws: `JavaScriptEvalException` when evaluated code has invalid syntax or throws an error.
|
|
12
17
|
- Note: It wraps the original `evaluateScript` to better handle and rethrow exceptions.
|
|
13
18
|
*/
|
|
19
|
+
@discardableResult
|
|
14
20
|
func eval(_ source: String) throws -> JavaScriptValue {
|
|
15
21
|
do {
|
|
16
22
|
var result: JavaScriptValue?
|
|
17
23
|
try EXUtilities.catchException {
|
|
18
|
-
result = self.
|
|
24
|
+
result = self.__evaluateScript(source)
|
|
19
25
|
}
|
|
20
26
|
// There is no risk to force unwrapping as long as the `evaluateScript` returns nonnull value.
|
|
21
27
|
return result!
|
|
@@ -23,6 +29,37 @@ public extension JavaScriptRuntime {
|
|
|
23
29
|
throw JavaScriptEvalException(error as NSError)
|
|
24
30
|
}
|
|
25
31
|
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
Evaluates the JavaScript code made by joining an array of strings with a newline separator.
|
|
35
|
+
See the other ``eval(_:)`` for more details.
|
|
36
|
+
*/
|
|
37
|
+
@discardableResult
|
|
38
|
+
func eval(_ source: [String]) throws -> JavaScriptValue {
|
|
39
|
+
try eval(source.joined(separator: "\n"))
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
Creates a synchronous host function that runs the given closure when it's called.
|
|
44
|
+
The value returned by the closure is synchronously returned to JS.
|
|
45
|
+
- Returns: A JavaScript function represented as a `JavaScriptObject`.
|
|
46
|
+
- Note: It refines the ObjC implementation from `EXJavaScriptRuntime` to properly catch Swift errors and rethrow them as ObjC `NSError`.
|
|
47
|
+
*/
|
|
48
|
+
func createSyncFunction(_ name: String, argsCount: Int = 0, closure: @escaping SyncFunctionClosure) -> JavaScriptObject {
|
|
49
|
+
return __createSyncFunction(name, argsCount: argsCount) { this, args, errorPointer in
|
|
50
|
+
do {
|
|
51
|
+
return try runWithErrorPointer(errorPointer) {
|
|
52
|
+
return try closure(this, args)
|
|
53
|
+
}
|
|
54
|
+
} catch {
|
|
55
|
+
// Nicely log all errors to the console.
|
|
56
|
+
log.error(error)
|
|
57
|
+
|
|
58
|
+
// Can return anything as the error will be caught through the error pointer already.
|
|
59
|
+
return nil
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
26
63
|
}
|
|
27
64
|
|
|
28
65
|
internal final class JavaScriptEvalException: GenericException<NSError> {
|
|
@@ -85,6 +85,13 @@ public extension JavaScriptValue {
|
|
|
85
85
|
}
|
|
86
86
|
throw JavaScriptValueConversionException((kind: kind, target: "Object"))
|
|
87
87
|
}
|
|
88
|
+
|
|
89
|
+
func asTypedArray() throws -> JavaScriptTypedArray {
|
|
90
|
+
if let typedArray = getTypedArray() {
|
|
91
|
+
return typedArray
|
|
92
|
+
}
|
|
93
|
+
throw JavaScriptValueConversionException((kind: kind, target: "TypedArray"))
|
|
94
|
+
}
|
|
88
95
|
}
|
|
89
96
|
|
|
90
97
|
internal final class JavaScriptValueConversionException: GenericException<(kind: JavaScriptValueKind, target: String)> {
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// Copyright 2022-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
#include <unordered_map>
|
|
4
|
+
#include "TypedArray.h"
|
|
5
|
+
|
|
6
|
+
namespace expo {
|
|
7
|
+
|
|
8
|
+
std::unordered_map<std::string, TypedArrayKind> nameToKindMap = {
|
|
9
|
+
{"Int8Array", TypedArrayKind::Int8Array},
|
|
10
|
+
{"Int16Array", TypedArrayKind::Int16Array},
|
|
11
|
+
{"Int32Array", TypedArrayKind::Int32Array},
|
|
12
|
+
{"Uint8Array", TypedArrayKind::Uint8Array},
|
|
13
|
+
{"Uint8ClampedArray", TypedArrayKind::Uint8ClampedArray},
|
|
14
|
+
{"Uint16Array", TypedArrayKind::Uint16Array},
|
|
15
|
+
{"Uint32Array", TypedArrayKind::Uint32Array},
|
|
16
|
+
{"Float32Array", TypedArrayKind::Float32Array},
|
|
17
|
+
{"Float64Array", TypedArrayKind::Float64Array},
|
|
18
|
+
{"BigInt64Array", TypedArrayKind::BigInt64Array},
|
|
19
|
+
{"BigUint64Array", TypedArrayKind::BigUint64Array},
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
TypedArrayKind getTypedArrayKindForName(const std::string &name) {
|
|
23
|
+
return nameToKindMap.at(name);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
TypedArray::TypedArray(jsi::Runtime &runtime, const jsi::Object &obj)
|
|
27
|
+
: jsi::Object(jsi::Value(runtime, obj).asObject(runtime)) {}
|
|
28
|
+
|
|
29
|
+
TypedArrayKind TypedArray::getKind(jsi::Runtime &runtime) const {
|
|
30
|
+
auto constructorName = this->getPropertyAsObject(runtime, "constructor")
|
|
31
|
+
.getProperty(runtime, "name")
|
|
32
|
+
.asString(runtime)
|
|
33
|
+
.utf8(runtime);
|
|
34
|
+
return getTypedArrayKindForName(constructorName);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
size_t TypedArray::byteOffset(jsi::Runtime &runtime) const {
|
|
38
|
+
return getProperty(runtime, "byteOffset").asNumber();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
jsi::ArrayBuffer TypedArray::getBuffer(jsi::Runtime &runtime) const {
|
|
42
|
+
auto buffer = getProperty(runtime, "buffer");
|
|
43
|
+
if (buffer.isObject() && buffer.asObject(runtime).isArrayBuffer(runtime)) {
|
|
44
|
+
return buffer.asObject(runtime).getArrayBuffer(runtime);
|
|
45
|
+
} else {
|
|
46
|
+
throw std::runtime_error("no ArrayBuffer attached");
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
void* TypedArray::getRawPointer(jsi::Runtime &runtime) {
|
|
51
|
+
return reinterpret_cast<void *>(getBuffer(runtime).data(runtime) + byteOffset(runtime));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
bool isTypedArray(jsi::Runtime &runtime, const jsi::Object &jsObj) {
|
|
55
|
+
jsi::Object ArrayBuffer = runtime
|
|
56
|
+
.global()
|
|
57
|
+
.getPropertyAsObject(runtime, "ArrayBuffer");
|
|
58
|
+
|
|
59
|
+
jsi::Value isViewResult = ArrayBuffer
|
|
60
|
+
.getPropertyAsFunction(runtime, "isView")
|
|
61
|
+
.callWithThis(runtime, ArrayBuffer, {jsi::Value(runtime, jsObj)});
|
|
62
|
+
|
|
63
|
+
assert(isViewResult.isBool());
|
|
64
|
+
return isViewResult.getBool();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
} // namespace expo
|