1// Copyright 2018-present 650 Industries. All rights reserved.
2
3#import <ABI47_0_0ExpoModulesCore/ABI47_0_0EXJSIInstaller.h>
4#import <ABI47_0_0ExpoModulesCore/ABI47_0_0EXJavaScriptRuntime.h>
5#import <ABI47_0_0ExpoModulesCore/ABI47_0_0ExpoModulesHostObject.h>
6#import <ABI47_0_0ExpoModulesCore/LazyObject.h>
7#import <ABI47_0_0ExpoModulesCore/Swift.h>
8
9namespace jsi = ABI47_0_0facebook::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 ABI47_0_0RCTBridge (ExpoBridgeWithRuntime)
22
23- (void *)runtime;
24- (std::shared_ptr<ABI47_0_0facebook::ABI47_0_0React::CallInvoker>)jsCallInvoker;
25
26@end
27
28@implementation ABI47_0_0EXJavaScriptRuntimeManager
29
30+ (nullable ABI47_0_0EXJavaScriptRuntime *)runtimeFromBridge:(nonnull ABI47_0_0RCTBridge *)bridge
31{
32  jsi::Runtime *jsiRuntime = [bridge respondsToSelector:@selector(runtime)] ? reinterpret_cast<jsi::Runtime *>(bridge.runtime) : nullptr;
33  return jsiRuntime ? [[ABI47_0_0EXJavaScriptRuntime alloc] initWithRuntime:jsiRuntime callInvoker:bridge.jsCallInvoker] : nil;
34}
35
36+ (BOOL)installExpoModulesHostObject:(nonnull ABI47_0_0EXAppContext *)appContext
37{
38  ABI47_0_0EXJavaScriptRuntime *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  ABI47_0_0EXJavaScriptObject *global = [runtime global];
46  ABI47_0_0EXJavaScriptObject *mainObject = [runtime mainObject];
47
48  if ([mainObject hasProperty:modulesHostObjectPropertyName]) {
49    return false;
50  }
51
52  std::shared_ptr<ABI47_0_0expo::ExpoModulesHostObject> modulesHostObjectPtr = std::make_shared<ABI47_0_0expo::ExpoModulesHostObject>(appContext);
53  ABI47_0_0EXJavaScriptObject *modulesHostObject = [runtime createHostObject:modulesHostObjectPtr];
54
55  // Define the `global.expo.modules` object as a non-configurable, read-only and enumerable property.
56  [mainObject defineProperty:modulesHostObjectPropertyName
57                       value:modulesHostObject
58                     options:ABI47_0_0EXJavaScriptObjectPropertyDescriptorEnumerable];
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:ABI47_0_0EXJavaScriptObjectPropertyDescriptorEnumerable];
64  return true;
65}
66
67@end
68