or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli-interface.mddevice-management.mdindex.mdinspector-proxy.md

device-management.mddocs/

0

# Device Management

1

2

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.

3

4

## Capabilities

5

6

### Device Class

7

8

Represents single device connection to Inspector Proxy. Each device can have multiple inspectable pages and handles debugger session management.

9

10

```javascript { .api }

11

/**

12

* Device class represents single device connection to Inspector Proxy

13

* @param id - Device ID

14

* @param name - Device name

15

* @param app - Package name of the app

16

* @param socket - WebSocket connection to device

17

* @param projectRoot - Root of the project used for relative to absolute source path conversion

18

*/

19

class Device {

20

constructor(

21

id: string,

22

name: string,

23

app: string,

24

socket: WS,

25

projectRoot: string

26

);

27

28

/**

29

* Returns device name

30

* @returns Device name string

31

*/

32

getName(): string;

33

34

/**

35

* Returns app package name

36

* @returns App package name string

37

*/

38

getApp(): string;

39

40

/**

41

* Returns list of inspectable pages from this device

42

* @returns Array of Page objects

43

*/

44

getPagesList(): Array<Page>;

45

46

/**

47

* Handles new debugger connection to this device

48

* @param socket - WebSocket connection from debugger

49

* @param pageId - ID of the page to debug

50

*/

51

handleDebuggerConnection(socket: WS, pageId: string): void;

52

53

/**

54

* Handles cleaning up a duplicate device connection

55

* @param newDevice - New device instance attempting to connect

56

*/

57

handleDuplicateDeviceConnection(newDevice: Device): void;

58

}

59

```

60

61

**Usage Examples:**

62

63

```javascript

64

const Device = require("metro-inspector-proxy/src/Device");

65

const WebSocket = require("ws");

66

67

// Device instances are typically created automatically by InspectorProxy

68

// when React Native apps connect to /inspector/device WebSocket endpoint

69

70

// Example of how devices are created internally:

71

const deviceSocket = new WebSocket("ws://localhost:8081/inspector/device?device=myphone&name=iPhone&app=MyApp");

72

const device = new Device(

73

"myphone", // device ID

74

"iPhone", // device name

75

"MyApp", // app name

76

deviceSocket, // WebSocket connection

77

"/path/to/project" // project root

78

);

79

80

// Get device information

81

console.log(device.getName()); // "iPhone"

82

console.log(device.getApp()); // "MyApp"

83

84

// Get available pages for debugging

85

const pages = device.getPagesList();

86

console.log(pages); // Array of Page objects

87

```

88

89

### Page Information

90

91

Page objects represent individual JavaScript contexts that can be debugged.

92

93

```javascript { .api }

94

interface Page {

95

id: string; // Unique page identifier

96

title: string; // Page title (usually "React Native")

97

vm: string; // JavaScript engine name (e.g., "Hermes", "JSC")

98

app: string; // App name

99

}

100

```

101

102

### Debugger Connection Handling

103

104

When a debugger (Chrome DevTools) connects to debug a specific page:

105

106

```javascript

107

// Debugger connects to WebSocket endpoint with device and page IDs

108

const debuggerSocket = new WebSocket("ws://localhost:8081/inspector/debug?device=myphone&page=1");

109

110

// Device handles the debugger connection internally

111

device.handleDebuggerConnection(debuggerSocket, "1");

112

```

113

114

The Device class:

115

1. Disconnects any existing debugger for this device

116

2. Sets up message forwarding between debugger and device

117

3. Sends connect event to the React Native app

118

4. Handles Chrome DevTools Protocol message transformation

119

120

### Message Processing

121

122

The Device class handles bidirectional message forwarding and transformation:

123

124

#### Messages from Device to Debugger

125

- **getPages responses**: Updates local page list

126

- **wrappedEvent messages**: Chrome DevTools Protocol messages forwarded to debugger

127

- **disconnect events**: Handles page reloads and app disconnections

128

129

#### Messages from Debugger to Device

130

- **Chrome DevTools Protocol messages**: Forwarded as wrappedEvent to device

131

- **Special handling for**:

132

- `Debugger.setBreakpointByUrl`: URL transformation for Android emulator addresses

133

- `Debugger.getScriptSource`: Local file serving and HTTP source map fetching

134

135

### React Native Reloadable Page

136

137

The Device class provides special handling for React Native app reloads:

138

139

```javascript { .api }

140

// Special page ID for reloadable React Native debugging

141

const REACT_NATIVE_RELOADABLE_PAGE_ID = "-1";

142

143

// When available, this creates a special page entry:

144

{

145

id: "-1",

146

title: "React Native Experimental (Improved Chrome Reloads)",

147

vm: "don't use",

148

app: "MyApp"

149

}

150

```

151

152

This allows debuggers to maintain connections across React Native app reloads.

153

154

### Duplicate Connection Handling

155

156

When the same device attempts to reconnect (common during app reloads):

157

158

```javascript

159

// If same device and app reconnect

160

if (oldDevice.getApp() === newDevice.getApp() &&

161

oldDevice.getName() === newDevice.getName()) {

162

// Reuse existing debugger connection with new device socket

163

olddevice.handleDuplicateDeviceConnection(newDevice);

164

} else {

165

// Different app/device - close old connections

166

oldDevice.close();

167

}

168

```

169

170

### Source Path Resolution

171

172

The Device class handles source path resolution for debugging:

173

174

#### Android Emulator Address Translation

175

```javascript

176

// Translates Android emulator addresses to localhost for Chrome DevTools

177

const EMULATOR_LOCALHOST_ADDRESSES = ["10.0.2.2", "10.0.3.2"];

178

179

// Example: "http://10.0.2.2:8081/bundle.js" becomes "http://localhost:8081/bundle.js"

180

```

181

182

#### File URL Handling

183

```javascript

184

// Adds file:// prefix to alphanumeric script IDs for Chrome DevTools compatibility

185

const FILE_PREFIX = "file://";

186

187

// Example: "12abc34" becomes "file://12abc34"

188

```

189

190

#### Source Map Processing

191

- Fetches HTTP-based source maps and converts to data URLs

192

- Handles local file reading for source content

193

- Maintains script ID to source path mapping for `Debugger.getScriptSource` requests

194

195

### Error Handling

196

197

The Device class provides error handling and debugging support:

198

199

```javascript { .api }

200

/**

201

* Sends error message to connected debugger console

202

* @param message - Error message to display in debugger console

203

*/

204

_sendErrorToDebugger(message: string): void;

205

206

/**

207

* Sends message to connected device

208

* @param message - Message to send to device

209

*/

210

_sendMessageToDevice(message: MessageToDevice): void;

211

212

/**

213

* Processes message from device, handling special cases like getPages and wrappedEvent

214

* @param message - Message received from device

215

*/

216

_handleMessageFromDevice(message: MessageFromDevice): void;

217

218

/**

219

* Processes messages from device with source path transformation

220

* @param payload - Message payload with method and params

221

* @param debuggerInfo - Information about current debugger connection

222

*/

223

_processMessageFromDevice(

224

payload: { method: string, params: { sourceMapURL: string, url: string } },

225

debuggerInfo: DebuggerInfo

226

): Promise<void>;

227

228

/**

229

* Intercepts and processes messages from debugger before forwarding to device

230

* @param req - Debugger request

231

* @param debuggerInfo - Information about current debugger connection

232

* @param socket - WebSocket connection to debugger

233

* @returns Whether message was handled locally (true) or should be forwarded (false)

234

*/

235

_interceptMessageFromDebugger(

236

req: DebuggerRequest,

237

debuggerInfo: DebuggerInfo,

238

socket: WS

239

): boolean;

240

```

241

242

Errors are sent to the debugger as `Runtime.consoleAPICalled` events with type 'error', appearing in the Chrome DevTools console.