expo-modules-core 0.9.2 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. package/CHANGELOG.md +33 -3
  2. package/README.md +3 -3
  3. package/android/CMakeLists.txt +163 -0
  4. package/android/build.gradle +343 -5
  5. package/android/src/main/cpp/CachedReferencesRegistry.cpp +65 -0
  6. package/android/src/main/cpp/CachedReferencesRegistry.h +80 -0
  7. package/android/src/main/cpp/Exceptions.cpp +22 -0
  8. package/android/src/main/cpp/Exceptions.h +38 -0
  9. package/android/src/main/cpp/ExpoModulesHostObject.cpp +47 -0
  10. package/android/src/main/cpp/ExpoModulesHostObject.h +32 -0
  11. package/android/src/main/cpp/JNIFunctionBody.cpp +44 -0
  12. package/android/src/main/cpp/JNIFunctionBody.h +50 -0
  13. package/android/src/main/cpp/JNIInjector.cpp +23 -0
  14. package/android/src/main/cpp/JSIInteropModuleRegistry.cpp +122 -0
  15. package/android/src/main/cpp/JSIInteropModuleRegistry.h +96 -0
  16. package/android/src/main/cpp/JSIObjectWrapper.h +33 -0
  17. package/android/src/main/cpp/JSITypeConverter.h +84 -0
  18. package/android/src/main/cpp/JavaScriptModuleObject.cpp +219 -0
  19. package/android/src/main/cpp/JavaScriptModuleObject.h +144 -0
  20. package/android/src/main/cpp/JavaScriptObject.cpp +125 -0
  21. package/android/src/main/cpp/JavaScriptObject.h +131 -0
  22. package/android/src/main/cpp/JavaScriptRuntime.cpp +127 -0
  23. package/android/src/main/cpp/JavaScriptRuntime.h +87 -0
  24. package/android/src/main/cpp/JavaScriptValue.cpp +172 -0
  25. package/android/src/main/cpp/JavaScriptValue.h +78 -0
  26. package/android/src/main/cpp/MethodMetadata.cpp +340 -0
  27. package/android/src/main/cpp/MethodMetadata.h +131 -0
  28. package/android/src/main/java/expo/modules/adapters/react/NativeModulesProxy.java +2 -0
  29. package/android/src/main/java/expo/modules/core/errors/ContextDestroyedException.kt +7 -0
  30. package/android/src/main/java/expo/modules/interfaces/permissions/Permissions.java +30 -0
  31. package/android/src/main/java/expo/modules/kotlin/AppContext.kt +98 -3
  32. package/android/src/main/java/expo/modules/kotlin/ConcatIterator.kt +18 -0
  33. package/android/src/main/java/expo/modules/kotlin/KotlinInteropModuleRegistry.kt +15 -12
  34. package/android/src/main/java/expo/modules/kotlin/ModuleHolder.kt +45 -3
  35. package/android/src/main/java/expo/modules/kotlin/activityaware/AppCompatActivityAware.kt +49 -0
  36. package/android/src/main/java/expo/modules/kotlin/activityaware/AppCompatActivityAwareHelper.kt +43 -0
  37. package/android/src/main/java/expo/modules/kotlin/activityaware/OnActivityAvailableListener.kt +18 -0
  38. package/android/src/main/java/expo/modules/kotlin/activityresult/ActivityResultsManager.kt +99 -0
  39. package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultCaller.kt +25 -0
  40. package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultContract.kt +27 -0
  41. package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultFallbackCallback.kt +17 -0
  42. package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultLauncher.kt +30 -0
  43. package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultRegistry.kt +358 -0
  44. package/android/src/main/java/expo/modules/kotlin/activityresult/DataPersistor.kt +135 -0
  45. package/android/src/main/java/expo/modules/kotlin/defaultmodules/ErrorManagerModule.kt +2 -2
  46. package/android/src/main/java/expo/modules/kotlin/exception/CodedException.kt +13 -0
  47. package/android/src/main/java/expo/modules/kotlin/exception/ExceptionDecorator.kt +2 -0
  48. package/android/src/main/java/expo/modules/kotlin/functions/AnyFunction.kt +53 -15
  49. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunction.kt +35 -7
  50. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionBuilder.kt +13 -121
  51. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionComponent.kt +21 -0
  52. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromiseComponent.kt +21 -0
  53. package/android/src/main/java/expo/modules/kotlin/functions/SuspendFunctionComponent.kt +63 -0
  54. package/android/src/main/java/expo/modules/kotlin/functions/SyncFunctionComponent.kt +36 -0
  55. package/android/src/main/java/expo/modules/kotlin/jni/CppType.kt +19 -0
  56. package/android/src/main/java/expo/modules/kotlin/jni/JNIFunctionBody.kt +39 -0
  57. package/android/src/main/java/expo/modules/kotlin/jni/JSIInteropModuleRegistry.kt +89 -0
  58. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptModuleObject.kt +46 -0
  59. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptObject.kt +113 -0
  60. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptValue.kt +35 -0
  61. package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +16 -6
  62. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +5 -500
  63. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionData.kt +30 -5
  64. package/android/src/main/java/expo/modules/kotlin/objects/ObjectDefinitionBuilder.kt +271 -0
  65. package/android/src/main/java/expo/modules/kotlin/objects/ObjectDefinitionData.kt +21 -0
  66. package/android/src/main/java/expo/modules/kotlin/objects/PropertyComponent.kt +54 -0
  67. package/android/src/main/java/expo/modules/kotlin/objects/PropertyComponentBuilder.kt +32 -0
  68. package/android/src/main/java/expo/modules/kotlin/providers/AppContextProvider.kt +14 -0
  69. package/android/src/main/java/expo/modules/kotlin/providers/CurrentActivityProvider.kt +22 -0
  70. package/android/src/main/java/expo/modules/kotlin/records/RecordTypeConverter.kt +19 -2
  71. package/android/src/main/java/expo/modules/kotlin/types/AnyType.kt +3 -2
  72. package/android/src/main/java/expo/modules/kotlin/types/AnyTypeConverter.kt +36 -0
  73. package/android/src/main/java/expo/modules/kotlin/types/ArrayTypeConverter.kt +7 -2
  74. package/android/src/main/java/expo/modules/kotlin/types/BasicTypeConverters.kt +68 -20
  75. package/android/src/main/java/expo/modules/kotlin/types/EnumTypeConverter.kt +50 -22
  76. package/android/src/main/java/expo/modules/kotlin/types/ListTypeConverter.kt +18 -2
  77. package/android/src/main/java/expo/modules/kotlin/types/MapTypeConverter.kt +18 -2
  78. package/android/src/main/java/expo/modules/kotlin/types/PairTypeConverter.kt +17 -2
  79. package/android/src/main/java/expo/modules/kotlin/types/TypeConverter.kt +43 -3
  80. package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +12 -0
  81. package/android/src/main/java/expo/modules/kotlin/views/ViewGroupDefinitionBuilder.kt +0 -41
  82. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinitionBuilder.kt +0 -33
  83. package/build/NativeModulesProxy.native.d.ts.map +1 -1
  84. package/build/NativeModulesProxy.native.js +9 -3
  85. package/build/NativeModulesProxy.native.js.map +1 -1
  86. package/build/PermissionsInterface.d.ts +29 -0
  87. package/build/PermissionsInterface.d.ts.map +1 -1
  88. package/build/PermissionsInterface.js +9 -0
  89. package/build/PermissionsInterface.js.map +1 -1
  90. package/ios/AppDelegates/EXAppDelegatesLoader.m +1 -2
  91. package/ios/ExpoModulesCore.podspec +3 -2
  92. package/ios/JSI/EXJSIConversions.mm +6 -0
  93. package/ios/JSI/EXJSIInstaller.h +15 -21
  94. package/ios/JSI/EXJSIInstaller.mm +39 -3
  95. package/ios/JSI/EXJSIUtils.h +48 -3
  96. package/ios/JSI/EXJSIUtils.mm +88 -4
  97. package/ios/JSI/EXJavaScriptObject.h +11 -18
  98. package/ios/JSI/EXJavaScriptObject.mm +37 -18
  99. package/ios/JSI/EXJavaScriptRuntime.h +43 -9
  100. package/ios/JSI/EXJavaScriptRuntime.mm +70 -27
  101. package/ios/JSI/EXJavaScriptTypedArray.h +30 -0
  102. package/ios/JSI/EXJavaScriptTypedArray.mm +29 -0
  103. package/ios/JSI/EXJavaScriptValue.h +3 -2
  104. package/ios/JSI/EXJavaScriptValue.mm +17 -20
  105. package/ios/JSI/EXJavaScriptWeakObject.h +23 -0
  106. package/ios/JSI/EXJavaScriptWeakObject.mm +53 -0
  107. package/ios/JSI/EXObjectDeallocator.h +27 -0
  108. package/ios/JSI/ExpoModulesHostObject.h +3 -3
  109. package/ios/JSI/ExpoModulesHostObject.mm +4 -4
  110. package/ios/JSI/JavaScriptRuntime.swift +38 -1
  111. package/ios/JSI/JavaScriptValue.swift +7 -0
  112. package/ios/JSI/TypedArray.cpp +67 -0
  113. package/ios/JSI/TypedArray.h +46 -0
  114. package/ios/ModuleRegistryAdapter/EXModuleRegistryAdapter.m +0 -11
  115. package/ios/NativeModulesProxy/EXNativeModulesProxy.h +17 -10
  116. package/ios/NativeModulesProxy/EXNativeModulesProxy.mm +86 -77
  117. package/ios/NativeModulesProxy/NativeModulesProxyModule.swift +17 -0
  118. package/ios/Services/EXReactNativeEventEmitter.h +2 -2
  119. package/ios/Services/EXReactNativeEventEmitter.m +11 -6
  120. package/ios/Swift/AppContext.swift +206 -28
  121. package/ios/Swift/Arguments/AnyArgument.swift +18 -0
  122. package/ios/Swift/Arguments/{Types/EnumArgumentType.swift → EnumArgument.swift} +2 -17
  123. package/ios/Swift/Classes/ClassComponent.swift +95 -0
  124. package/ios/Swift/Classes/ClassComponentElement.swift +33 -0
  125. package/ios/Swift/Classes/ClassComponentElementsBuilder.swift +34 -0
  126. package/ios/Swift/Classes/ClassComponentFactories.swift +96 -0
  127. package/ios/Swift/DynamicTypes/AnyDynamicType.swift +44 -0
  128. package/ios/Swift/DynamicTypes/DynamicArrayType.swift +56 -0
  129. package/ios/Swift/DynamicTypes/DynamicConvertibleType.swift +27 -0
  130. package/ios/Swift/DynamicTypes/DynamicEnumType.swift +27 -0
  131. package/ios/Swift/DynamicTypes/DynamicOptionalType.swift +63 -0
  132. package/ios/Swift/DynamicTypes/DynamicRawType.swift +33 -0
  133. package/ios/Swift/DynamicTypes/DynamicSharedObjectType.swift +37 -0
  134. package/ios/Swift/DynamicTypes/DynamicType.swift +39 -0
  135. package/ios/Swift/DynamicTypes/DynamicTypedArrayType.swift +46 -0
  136. package/ios/Swift/Exceptions/ChainableException.swift +3 -3
  137. package/ios/Swift/Exceptions/CodedError.swift +1 -1
  138. package/ios/Swift/Exceptions/Exception.swift +8 -6
  139. package/ios/Swift/Exceptions/UnexpectedException.swift +2 -1
  140. package/ios/Swift/ExpoBridgeModule.m +5 -0
  141. package/ios/Swift/ExpoBridgeModule.swift +79 -0
  142. package/ios/Swift/Functions/AnyFunction.swift +33 -31
  143. package/ios/Swift/Functions/AsyncFunctionComponent.swift +196 -59
  144. package/ios/Swift/Functions/SyncFunctionComponent.swift +142 -58
  145. package/ios/Swift/JavaScriptUtils.swift +32 -57
  146. package/ios/Swift/Logging/LogHandlers.swift +39 -0
  147. package/ios/Swift/Logging/LogType.swift +62 -0
  148. package/ios/Swift/Logging/Logger.swift +201 -0
  149. package/ios/Swift/ModuleHolder.swift +19 -54
  150. package/ios/Swift/ModuleRegistry.swift +7 -1
  151. package/ios/Swift/Modules/AnyModule.swift +3 -3
  152. package/ios/Swift/ModulesProvider.swift +2 -0
  153. package/ios/Swift/Objects/JavaScriptObjectBuilder.swift +37 -0
  154. package/ios/Swift/Objects/ObjectDefinition.swift +74 -1
  155. package/ios/Swift/Objects/ObjectDefinitionComponents.swift +77 -68
  156. package/ios/Swift/Objects/PropertyComponent.swift +147 -0
  157. package/ios/Swift/Promise.swift +17 -4
  158. package/ios/Swift/Records/Field.swift +2 -2
  159. package/ios/Swift/SharedObjects/SharedObject.swift +20 -0
  160. package/ios/Swift/SharedObjects/SharedObjectRegistry.swift +129 -0
  161. package/ios/Swift/TypedArrays/AnyTypedArray.swift +11 -0
  162. package/ios/Swift/TypedArrays/ConcreteTypedArrays.swift +56 -0
  163. package/ios/Swift/TypedArrays/GenericTypedArray.swift +49 -0
  164. package/ios/Swift/TypedArrays/TypedArray.swift +80 -0
  165. package/ios/Swift/Utilities.swift +28 -0
  166. package/ios/Swift/Views/ConcreteViewProp.swift +3 -3
  167. package/ios/Swift/Views/ViewManagerDefinitionComponents.swift +2 -2
  168. package/ios/Tests/ClassComponentSpec.swift +210 -0
  169. package/ios/Tests/DynamicTypeSpec.swift +336 -0
  170. package/ios/Tests/EnumArgumentSpec.swift +48 -0
  171. package/ios/Tests/ExpoModulesSpec.swift +17 -3
  172. package/ios/Tests/FunctionSpec.swift +167 -118
  173. package/ios/Tests/Mocks/ModuleMocks.swift +1 -1
  174. package/ios/Tests/PropertyComponentSpec.swift +95 -0
  175. package/ios/Tests/SharedObjectRegistrySpec.swift +109 -0
  176. package/ios/Tests/TypedArraysSpec.swift +136 -0
  177. package/package.json +2 -2
  178. package/src/NativeModulesProxy.native.ts +13 -3
  179. package/src/PermissionsInterface.ts +29 -0
  180. package/src/ts-declarations/ExpoModules.d.ts +7 -0
  181. package/tsconfig.json +1 -1
  182. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromise.kt +0 -15
  183. package/android/src/main/java/expo/modules/kotlin/functions/AsyncSuspendFunction.kt +0 -36
  184. package/ios/Swift/Arguments/AnyArgumentType.swift +0 -13
  185. package/ios/Swift/Arguments/ArgumentType.swift +0 -28
  186. package/ios/Swift/Arguments/Types/ArrayArgumentType.swift +0 -42
  187. package/ios/Swift/Arguments/Types/ConvertibleArgumentType.swift +0 -16
  188. package/ios/Swift/Arguments/Types/OptionalArgumentType.swift +0 -49
  189. package/ios/Swift/Arguments/Types/PromiseArgumentType.swift +0 -15
  190. package/ios/Swift/Arguments/Types/RawArgumentType.swift +0 -25
  191. package/ios/Swift/Functions/ConcreteFunction.swift +0 -103
  192. package/ios/Swift/SwiftInteropBridge.swift +0 -155
  193. package/ios/Tests/ArgumentTypeSpec.swift +0 -143
@@ -1,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, std::shared_ptr<react::CallInvoker> callInvoker, NSArray<EXJavaScriptValue *> * _Nonnull arguments);
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
- - (jsi::Function)createSyncFunction:(nonnull NSString *)name
86
- argsCount:(NSInteger)argsCount
87
- block:(nonnull JSSyncFunctionBlock)block
85
+ - (nonnull EXJavaScriptObject *)createSyncFunction:(nonnull NSString *)name
86
+ argsCount:(NSInteger)argsCount
87
+ block:(nonnull JSSyncFunctionBlock)block
88
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
- }];
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
- - (jsi::Function)createAsyncFunction:(nonnull NSString *)name
95
- argsCount:(NSInteger)argsCount
96
- block:(nonnull JSAsyncFunctionBlock)block
106
+ - (nonnull EXJavaScriptObject *)createAsyncFunction:(nonnull NSString *)name
107
+ argsCount:(NSInteger)argsCount
108
+ block:(nonnull JSAsyncFunctionBlock)block
97
109
  {
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
- });
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
- return createPromiseAsJSIValue(runtime, promiseSetup);
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
- - (jsi::Function)createHostFunction:(nonnull NSString *)name
138
- argsCount:(NSInteger)argsCount
139
- block:(nonnull JSHostFunctionBlock)block
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
- return block(runtime, callInvoker, arguments);
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
- return jsi::Function::createFromHostFunction(*_runtime, propNameId, (unsigned int)argsCount, function);
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
- + (nonnull NSString *)kindOf:(nonnull EXJavaScriptValue *)value
75
+ - (BOOL)isTypedArray
74
76
  {
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";
77
+ if (_value->isObject()) {
78
+ jsi::Runtime *runtime = [_runtime get];
79
+ return expo::isTypedArray(*runtime, _value->getObject(*runtime));
92
80
  }
93
- assert([value isObject] && "Expecting object.");
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 SwiftInteropBridge;
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(SwiftInteropBridge *interopBridge);
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
- SwiftInteropBridge *swiftInterop;
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(SwiftInteropBridge *swiftInterop) : swiftInterop(swiftInterop) {}
9
+ ExpoModulesHostObject::ExpoModulesHostObject(EXAppContext *appContext) : appContext(appContext) {}
10
10
 
11
11
  ExpoModulesHostObject::~ExpoModulesHostObject() {
12
- [swiftInterop setRuntime:nil];
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 = [swiftInterop getNativeModuleObject:moduleName];
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 = [swiftInterop getModuleNames];
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.evaluateScript(source)
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