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#import <ExpoModulesCore/EXRawJavaScriptFunction.h> 7#import <ExpoModulesCore/EXJavaScriptTypedArray.h> 8#import <ExpoModulesCore/TypedArray.h> 9 10@implementation EXJavaScriptValue { 11 __weak EXJavaScriptRuntime *_runtime; 12 std::shared_ptr<jsi::Value> _value; 13} 14 15- (nonnull instancetype)initWithRuntime:(nonnull EXJavaScriptRuntime *)runtime 16 value:(std::shared_ptr<jsi::Value>)value 17{ 18 if (self = [super init]) { 19 _runtime = runtime; 20 _value = value; 21 } 22 return self; 23} 24 25- (nonnull jsi::Value *)get 26{ 27 return _value.get(); 28} 29 30#pragma mark - Type checking 31 32- (BOOL)isUndefined 33{ 34 return _value->isUndefined(); 35} 36 37- (BOOL)isNull 38{ 39 return _value->isNull(); 40} 41 42- (BOOL)isBool 43{ 44 return _value->isBool(); 45} 46 47- (BOOL)isNumber 48{ 49 return _value->isNumber(); 50} 51 52- (BOOL)isString 53{ 54 return _value->isString(); 55} 56 57- (BOOL)isSymbol 58{ 59 return _value->isSymbol(); 60} 61 62- (BOOL)isObject 63{ 64 return _value->isObject(); 65} 66 67- (BOOL)isFunction 68{ 69 if (_value->isObject()) { 70 jsi::Runtime *runtime = [_runtime get]; 71 return _value->getObject(*runtime).isFunction(*runtime); 72 } 73 return false; 74} 75 76- (BOOL)isTypedArray 77{ 78 if (_value->isObject()) { 79 jsi::Runtime *runtime = [_runtime get]; 80 return expo::isTypedArray(*runtime, _value->getObject(*runtime)); 81 } 82 return false; 83} 84 85#pragma mark - Type casting 86 87- (nullable id)getRaw 88{ 89 return expo::convertJSIValueToObjCObject(*[_runtime get], *_value, [_runtime callInvoker]); 90} 91 92- (BOOL)getBool 93{ 94 return _value->getBool(); 95} 96 97- (NSInteger)getInt 98{ 99 return _value->getNumber(); 100} 101 102- (double)getDouble 103{ 104 return _value->getNumber(); 105} 106 107- (nonnull NSString *)getString 108{ 109 jsi::Runtime *runtime = [_runtime get]; 110 return expo::convertJSIStringToNSString(*runtime, _value->getString(*runtime)); 111} 112 113- (nonnull NSArray<EXJavaScriptValue *> *)getArray 114{ 115 jsi::Runtime *runtime = [_runtime get]; 116 jsi::Array jsiArray = _value->getObject(*runtime).getArray(*runtime); 117 size_t arraySize = jsiArray.size(*runtime); 118 NSMutableArray *result = [NSMutableArray arrayWithCapacity:arraySize]; 119 120 for (size_t i = 0; i < arraySize; i++) { 121 jsi::Value item = jsiArray.getValueAtIndex(*runtime, i); 122 123 if (item.isUndefined() || item.isNull()) { 124 [result addObject:(id)kCFNull]; 125 } else { 126 std::shared_ptr<jsi::Value> valuePtr = std::make_shared<jsi::Value>(*runtime, item); 127 [result addObject:[[EXJavaScriptValue alloc] initWithRuntime:_runtime value:valuePtr]]; 128 } 129 } 130 return result; 131} 132 133- (nonnull NSDictionary<NSString *, id> *)getDictionary 134{ 135 jsi::Runtime *runtime = [_runtime get]; 136 return expo::convertJSIObjectToNSDictionary(*runtime, _value->getObject(*runtime), [_runtime callInvoker]); 137} 138 139- (nonnull EXJavaScriptObject *)getObject 140{ 141 jsi::Runtime *runtime = [_runtime get]; 142 std::shared_ptr<jsi::Object> objectPtr = std::make_shared<jsi::Object>(_value->asObject(*runtime)); 143 return [[EXJavaScriptObject alloc] initWith:objectPtr runtime:_runtime]; 144} 145 146- (nonnull EXRawJavaScriptFunction *)getFunction 147{ 148 jsi::Runtime *runtime = [_runtime get]; 149 std::shared_ptr<jsi::Function> functionPtr = std::make_shared<jsi::Function>(_value->asObject(*runtime).asFunction(*runtime)); 150 return [[EXRawJavaScriptFunction alloc] initWith:functionPtr runtime:_runtime]; 151} 152 153- (nullable EXJavaScriptTypedArray *)getTypedArray 154{ 155 if (![self isTypedArray]) { 156 return nil; 157 } 158 jsi::Runtime *runtime = [_runtime get]; 159 std::shared_ptr<jsi::Object> objectPtr = std::make_shared<jsi::Object>(_value->asObject(*runtime)); 160 return [[EXJavaScriptTypedArray alloc] initWith:objectPtr runtime:_runtime]; 161} 162 163#pragma mark - Helpers 164 165- (nonnull NSString *)toString 166{ 167 jsi::Runtime *runtime = [_runtime get]; 168 return expo::convertJSIStringToNSString(*runtime, _value->toString(*runtime)); 169} 170 171@end 172