1import { DeviceEventEmitter, NativeModules, EventSubscription, Platform } from 'react-native';
2
3export type JSEngine = 'Hermes' | 'JSC';
4
5export type AppInfo = {
6  appIcon?: string;
7  appVersion?: string;
8  hostUrl?: string;
9  appName?: string;
10  sdkVersion?: string;
11  runtimeVersion?: string;
12  engine?: JSEngine;
13};
14
15export type DevSettings = {
16  isDebuggingRemotely?: boolean;
17  isElementInspectorShown?: boolean;
18  isHotLoadingEnabled?: boolean;
19  isPerfMonitorShown?: boolean;
20  isRemoteDebuggingAvailable?: boolean;
21  isElementInspectorAvailable?: boolean;
22  isHotLoadingAvailable?: boolean;
23  isPerfMonitorAvailable?: boolean;
24  isJSInspectorAvailable?: boolean;
25};
26
27export type MenuPreferences = {
28  isOnboardingFinished?: boolean;
29};
30
31const DevMenu = NativeModules.ExpoDevMenuInternal;
32
33export async function dispatchCallableAsync(
34  callableId: string,
35  args: object | null = null
36): Promise<void> {
37  return await DevMenu.dispatchCallableAsync(callableId, args);
38}
39
40export function hideMenu(): void {
41  DevMenu.hideMenu();
42}
43
44export function subscribeToCloseEvents(listener: () => void): EventSubscription {
45  return DeviceEventEmitter.addListener('closeDevMenu', listener);
46}
47
48export function subscribeToOpenEvents(listener: () => void): EventSubscription {
49  return DeviceEventEmitter.addListener('openDevMenu', listener);
50}
51
52export function openDevMenuFromReactNative() {
53  DevMenu.openDevMenuFromReactNative();
54}
55
56export async function togglePerformanceMonitorAsync() {
57  return await dispatchCallableAsync('performance-monitor');
58}
59
60export async function toggleElementInspectorAsync() {
61  return await dispatchCallableAsync('inspector');
62}
63
64export async function reloadAsync() {
65  return await dispatchCallableAsync('reload');
66}
67
68export async function toggleDebugRemoteJSAsync() {
69  return await dispatchCallableAsync('remote-debug');
70}
71
72export async function toggleFastRefreshAsync() {
73  return await dispatchCallableAsync('fast-refresh');
74}
75
76export async function openJSInspector() {
77  if (Platform.OS !== 'android') {
78    return;
79  }
80  return await dispatchCallableAsync('js-inspector');
81}
82
83export async function copyToClipboardAsync(content: string) {
84  return await DevMenu.copyToClipboardAsync(content);
85}
86
87export async function setOnboardingFinishedAsync(isFinished: boolean) {
88  return await DevMenu.setOnboardingFinished(isFinished);
89}
90
91export async function loadFontsAsync() {
92  return await DevMenu.loadFontsAsync();
93}
94
95export async function fireCallbackAsync(name: string) {
96  return await DevMenu.fireCallback(name).catch((error) => console.warn(error.message));
97}
98