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