Inspector proxy for React Native and dev tools integration that bridges React Native apps and Chrome DevTools.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Device connection handling for React Native apps that connect to the proxy. Each device represents a single React Native application connection and can have multiple inspectable pages (JavaScript contexts). The Device class manages debugger sessions, message forwarding, and handles Chrome DevTools Protocol communication.
Represents single device connection to Inspector Proxy. Each device can have multiple inspectable pages and handles debugger session management.
/**
* Device class represents single device connection to Inspector Proxy
* @param id - Device ID
* @param name - Device name
* @param app - Package name of the app
* @param socket - WebSocket connection to device
* @param projectRoot - Root of the project used for relative to absolute source path conversion
*/
class Device {
constructor(
id: string,
name: string,
app: string,
socket: WS,
projectRoot: string
);
/**
* Returns device name
* @returns Device name string
*/
getName(): string;
/**
* Returns app package name
* @returns App package name string
*/
getApp(): string;
/**
* Returns list of inspectable pages from this device
* @returns Array of Page objects
*/
getPagesList(): Array<Page>;
/**
* Handles new debugger connection to this device
* @param socket - WebSocket connection from debugger
* @param pageId - ID of the page to debug
*/
handleDebuggerConnection(socket: WS, pageId: string): void;
/**
* Handles cleaning up a duplicate device connection
* @param newDevice - New device instance attempting to connect
*/
handleDuplicateDeviceConnection(newDevice: Device): void;
}Usage Examples:
const Device = require("metro-inspector-proxy/src/Device");
const WebSocket = require("ws");
// Device instances are typically created automatically by InspectorProxy
// when React Native apps connect to /inspector/device WebSocket endpoint
// Example of how devices are created internally:
const deviceSocket = new WebSocket("ws://localhost:8081/inspector/device?device=myphone&name=iPhone&app=MyApp");
const device = new Device(
"myphone", // device ID
"iPhone", // device name
"MyApp", // app name
deviceSocket, // WebSocket connection
"/path/to/project" // project root
);
// Get device information
console.log(device.getName()); // "iPhone"
console.log(device.getApp()); // "MyApp"
// Get available pages for debugging
const pages = device.getPagesList();
console.log(pages); // Array of Page objectsPage objects represent individual JavaScript contexts that can be debugged.
interface Page {
id: string; // Unique page identifier
title: string; // Page title (usually "React Native")
vm: string; // JavaScript engine name (e.g., "Hermes", "JSC")
app: string; // App name
}When a debugger (Chrome DevTools) connects to debug a specific page:
// Debugger connects to WebSocket endpoint with device and page IDs
const debuggerSocket = new WebSocket("ws://localhost:8081/inspector/debug?device=myphone&page=1");
// Device handles the debugger connection internally
device.handleDebuggerConnection(debuggerSocket, "1");The Device class:
The Device class handles bidirectional message forwarding and transformation:
Debugger.setBreakpointByUrl: URL transformation for Android emulator addressesDebugger.getScriptSource: Local file serving and HTTP source map fetchingThe Device class provides special handling for React Native app reloads:
// Special page ID for reloadable React Native debugging
const REACT_NATIVE_RELOADABLE_PAGE_ID = "-1";
// When available, this creates a special page entry:
{
id: "-1",
title: "React Native Experimental (Improved Chrome Reloads)",
vm: "don't use",
app: "MyApp"
}This allows debuggers to maintain connections across React Native app reloads.
When the same device attempts to reconnect (common during app reloads):
// If same device and app reconnect
if (oldDevice.getApp() === newDevice.getApp() &&
oldDevice.getName() === newDevice.getName()) {
// Reuse existing debugger connection with new device socket
olddevice.handleDuplicateDeviceConnection(newDevice);
} else {
// Different app/device - close old connections
oldDevice.close();
}The Device class handles source path resolution for debugging:
// Translates Android emulator addresses to localhost for Chrome DevTools
const EMULATOR_LOCALHOST_ADDRESSES = ["10.0.2.2", "10.0.3.2"];
// Example: "http://10.0.2.2:8081/bundle.js" becomes "http://localhost:8081/bundle.js"// Adds file:// prefix to alphanumeric script IDs for Chrome DevTools compatibility
const FILE_PREFIX = "file://";
// Example: "12abc34" becomes "file://12abc34"Debugger.getScriptSource requestsThe Device class provides error handling and debugging support:
/**
* Sends error message to connected debugger console
* @param message - Error message to display in debugger console
*/
_sendErrorToDebugger(message: string): void;
/**
* Sends message to connected device
* @param message - Message to send to device
*/
_sendMessageToDevice(message: MessageToDevice): void;
/**
* Processes message from device, handling special cases like getPages and wrappedEvent
* @param message - Message received from device
*/
_handleMessageFromDevice(message: MessageFromDevice): void;
/**
* Processes messages from device with source path transformation
* @param payload - Message payload with method and params
* @param debuggerInfo - Information about current debugger connection
*/
_processMessageFromDevice(
payload: { method: string, params: { sourceMapURL: string, url: string } },
debuggerInfo: DebuggerInfo
): Promise<void>;
/**
* Intercepts and processes messages from debugger before forwarding to device
* @param req - Debugger request
* @param debuggerInfo - Information about current debugger connection
* @param socket - WebSocket connection to debugger
* @returns Whether message was handled locally (true) or should be forwarded (false)
*/
_interceptMessageFromDebugger(
req: DebuggerRequest,
debuggerInfo: DebuggerInfo,
socket: WS
): boolean;Errors are sent to the debugger as Runtime.consoleAPICalled events with type 'error', appearing in the Chrome DevTools console.