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