1// Copyright 2018-present 650 Industries. All rights reserved. 2 3#import <ExpoModulesCore/EXJSIInstaller.h> 4#import <ExpoModulesCore/EXJavaScriptRuntime.h> 5#import <ExpoModulesCore/ExpoModulesHostObject.h> 6#import <ExpoModulesCore/LazyObject.h> 7#import <ExpoModulesCore/Swift.h> 8 9namespace jsi = facebook::jsi; 10 11/** 12 Property name used to define the modules host object in the main object of the Expo JS runtime. 13 */ 14static NSString *modulesHostObjectPropertyName = @"modules"; 15 16/** 17 Property name used to define the modules host object in the global object of the Expo JS runtime (legacy). 18 */ 19static NSString *modulesHostObjectLegacyPropertyName = @"ExpoModules"; 20 21@interface RCTBridge (ExpoBridgeWithRuntime) 22 23- (void *)runtime; 24- (std::shared_ptr<facebook::react::CallInvoker>)jsCallInvoker; 25 26@end 27 28@implementation EXJavaScriptRuntimeManager 29 30+ (nullable EXRuntime *)runtimeFromBridge:(nonnull RCTBridge *)bridge 31{ 32 jsi::Runtime *jsiRuntime = [bridge respondsToSelector:@selector(runtime)] ? reinterpret_cast<jsi::Runtime *>(bridge.runtime) : nullptr; 33 return jsiRuntime ? [[EXRuntime alloc] initWithRuntime:jsiRuntime callInvoker:bridge.jsCallInvoker] : nil; 34} 35 36+ (BOOL)installExpoModulesHostObject:(nonnull EXAppContext *)appContext 37{ 38 EXRuntime *runtime = [appContext _runtime]; 39 40 // The runtime may be unavailable, e.g. remote debugger is enabled or it hasn't been set yet. 41 if (!runtime) { 42 return false; 43 } 44 45 EXJavaScriptObject *global = [runtime global]; 46 EXJavaScriptObject *coreObject = [runtime coreObject]; 47 48 if ([coreObject hasProperty:modulesHostObjectPropertyName]) { 49 return false; 50 } 51 52 std::shared_ptr<expo::ExpoModulesHostObject> modulesHostObjectPtr = std::make_shared<expo::ExpoModulesHostObject>(appContext); 53 EXJavaScriptObject *modulesHostObject = [runtime createHostObject:modulesHostObjectPtr]; 54 55 // Define the `global.expo.modules` object as a non-configurable, read-only and enumerable property. 56 [coreObject defineProperty:modulesHostObjectPropertyName 57 value:modulesHostObject 58 options:EXJavaScriptObjectPropertyDescriptorEnumerable]; 59 60 // Also define `global.ExpoModules` for backwards compatibility (used before SDK47, can be removed in SDK48). 61 [global defineProperty:modulesHostObjectLegacyPropertyName 62 value:modulesHostObject 63 options:EXJavaScriptObjectPropertyDescriptorEnumerable]; 64 return true; 65} 66 67@end 68