1import type { DebuggerInfo, Device as MetroDevice } from 'metro-inspector-proxy'; 2import type WS from 'ws'; 3 4import { NetworkResponseHandler } from './handlers/NetworkResponse'; 5import { VscodeCompatHandler } from './handlers/VscodeCompat'; 6import { DeviceRequest, InspectorHandler, DebuggerRequest } from './handlers/types'; 7 8export function createInspectorDeviceClass(MetroDeviceClass: typeof MetroDevice) { 9 return class ExpoInspectorDevice extends MetroDeviceClass implements InspectorHandler { 10 /** All handlers that should be used to intercept or reply to CDP events */ 11 public handlers: InspectorHandler[] = [new NetworkResponseHandler(), new VscodeCompatHandler()]; 12 13 onDeviceMessage(message: any, info: DebuggerInfo): boolean { 14 return this.handlers.some((handler) => handler.onDeviceMessage?.(message, info) ?? false); 15 } 16 17 onDebuggerMessage(message: any, info: DebuggerInfo): boolean { 18 return this.handlers.some((handler) => handler.onDebuggerMessage?.(message, info) ?? false); 19 } 20 21 /** Hook into the message life cycle to answer more complex CDP messages */ 22 async _processMessageFromDevice(message: DeviceRequest<any>, info: DebuggerInfo) { 23 if (!this.onDeviceMessage(message, info)) { 24 await super._processMessageFromDevice(message, info); 25 } 26 } 27 28 /** Hook into the message life cycle to answer more complex CDP messages */ 29 _interceptMessageFromDebugger( 30 request: DebuggerRequest, 31 info: DebuggerInfo, 32 socket: WS 33 ): boolean { 34 // Note, `socket` is the exact same as `info.socket` 35 if (this.onDebuggerMessage(request, info)) { 36 return true; 37 } 38 39 return super._interceptMessageFromDebugger(request, info, socket); 40 } 41 }; 42} 43