react-native-ai-debugger 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +303 -0
  3. package/build/core/android.d.ts +108 -0
  4. package/build/core/android.d.ts.map +1 -0
  5. package/build/core/android.js +686 -0
  6. package/build/core/android.js.map +1 -0
  7. package/build/core/connection.d.ts +12 -0
  8. package/build/core/connection.d.ts.map +1 -0
  9. package/build/core/connection.js +242 -0
  10. package/build/core/connection.js.map +1 -0
  11. package/build/core/executor.d.ts +6 -0
  12. package/build/core/executor.d.ts.map +1 -0
  13. package/build/core/executor.js +112 -0
  14. package/build/core/executor.js.map +1 -0
  15. package/build/core/index.d.ts +10 -0
  16. package/build/core/index.d.ts.map +1 -0
  17. package/build/core/index.js +21 -0
  18. package/build/core/index.js.map +1 -0
  19. package/build/core/ios.d.ts +54 -0
  20. package/build/core/ios.d.ts.map +1 -0
  21. package/build/core/ios.js +393 -0
  22. package/build/core/ios.js.map +1 -0
  23. package/build/core/logs.d.ts +27 -0
  24. package/build/core/logs.d.ts.map +1 -0
  25. package/build/core/logs.js +102 -0
  26. package/build/core/logs.js.map +1 -0
  27. package/build/core/metro.d.ts +8 -0
  28. package/build/core/metro.d.ts.map +1 -0
  29. package/build/core/metro.js +79 -0
  30. package/build/core/metro.js.map +1 -0
  31. package/build/core/network.d.ts +37 -0
  32. package/build/core/network.d.ts.map +1 -0
  33. package/build/core/network.js +210 -0
  34. package/build/core/network.js.map +1 -0
  35. package/build/core/state.d.ts +9 -0
  36. package/build/core/state.d.ts.map +1 -0
  37. package/build/core/state.js +16 -0
  38. package/build/core/state.js.map +1 -0
  39. package/build/core/types.d.ts +68 -0
  40. package/build/core/types.d.ts.map +1 -0
  41. package/build/core/types.js +2 -0
  42. package/build/core/types.js.map +1 -0
  43. package/build/index.d.ts +3 -0
  44. package/build/index.d.ts.map +1 -0
  45. package/build/index.js +951 -0
  46. package/build/index.js.map +1 -0
  47. package/package.json +50 -0
@@ -0,0 +1,393 @@
1
+ import { exec } from "child_process";
2
+ import { promisify } from "util";
3
+ import { existsSync } from "fs";
4
+ import path from "path";
5
+ import os from "os";
6
+ import sharp from "sharp";
7
+ const execAsync = promisify(exec);
8
+ // simctl command timeout in milliseconds
9
+ const SIMCTL_TIMEOUT = 30000;
10
+ /**
11
+ * Check if simctl is available
12
+ */
13
+ export async function isSimctlAvailable() {
14
+ try {
15
+ await execAsync("xcrun simctl help", { timeout: 5000 });
16
+ return true;
17
+ }
18
+ catch {
19
+ return false;
20
+ }
21
+ }
22
+ /**
23
+ * List iOS simulators
24
+ */
25
+ export async function listIOSSimulators(onlyBooted = false) {
26
+ try {
27
+ const simctlAvailable = await isSimctlAvailable();
28
+ if (!simctlAvailable) {
29
+ return {
30
+ success: false,
31
+ error: "Xcode command line tools not available. Install Xcode from the App Store."
32
+ };
33
+ }
34
+ const { stdout } = await execAsync("xcrun simctl list devices -j", {
35
+ timeout: SIMCTL_TIMEOUT
36
+ });
37
+ const data = JSON.parse(stdout);
38
+ const simulators = [];
39
+ // Parse devices from each runtime
40
+ for (const [runtime, devices] of Object.entries(data.devices)) {
41
+ if (!Array.isArray(devices))
42
+ continue;
43
+ for (const device of devices) {
44
+ if (!device.isAvailable)
45
+ continue;
46
+ if (onlyBooted && device.state !== "Booted")
47
+ continue;
48
+ // Extract iOS version from runtime string
49
+ const runtimeMatch = runtime.match(/iOS[- ](\d+[.-]\d+)/i);
50
+ const runtimeVersion = runtimeMatch ? `iOS ${runtimeMatch[1].replace("-", ".")}` : runtime;
51
+ simulators.push({
52
+ udid: device.udid,
53
+ name: device.name,
54
+ state: device.state,
55
+ runtime: runtimeVersion,
56
+ deviceType: device.deviceTypeIdentifier,
57
+ isAvailable: device.isAvailable
58
+ });
59
+ }
60
+ }
61
+ if (simulators.length === 0) {
62
+ return {
63
+ success: true,
64
+ result: onlyBooted
65
+ ? "No booted iOS simulators. Start a simulator first."
66
+ : "No available iOS simulators found."
67
+ };
68
+ }
69
+ // Sort: Booted first, then by name
70
+ simulators.sort((a, b) => {
71
+ if (a.state === "Booted" && b.state !== "Booted")
72
+ return -1;
73
+ if (a.state !== "Booted" && b.state === "Booted")
74
+ return 1;
75
+ return a.name.localeCompare(b.name);
76
+ });
77
+ const formatted = simulators
78
+ .map((s) => {
79
+ const status = s.state === "Booted" ? "🟢 Booted" : "⚪ Shutdown";
80
+ return `${s.name} (${s.runtime}) - ${status}\n UDID: ${s.udid}`;
81
+ })
82
+ .join("\n\n");
83
+ return {
84
+ success: true,
85
+ result: `iOS Simulators:\n\n${formatted}`
86
+ };
87
+ }
88
+ catch (error) {
89
+ return {
90
+ success: false,
91
+ error: `Failed to list simulators: ${error instanceof Error ? error.message : String(error)}`
92
+ };
93
+ }
94
+ }
95
+ /**
96
+ * Get the booted simulator UDID
97
+ */
98
+ export async function getBootedSimulatorUdid() {
99
+ try {
100
+ const { stdout } = await execAsync("xcrun simctl list devices booted -j", {
101
+ timeout: SIMCTL_TIMEOUT
102
+ });
103
+ const data = JSON.parse(stdout);
104
+ for (const devices of Object.values(data.devices)) {
105
+ if (!Array.isArray(devices))
106
+ continue;
107
+ for (const device of devices) {
108
+ if (device.state === "Booted") {
109
+ return device.udid;
110
+ }
111
+ }
112
+ }
113
+ return null;
114
+ }
115
+ catch {
116
+ return null;
117
+ }
118
+ }
119
+ /**
120
+ * Build device selector for simctl command
121
+ */
122
+ function buildDeviceArg(udid) {
123
+ return udid || "booted";
124
+ }
125
+ /**
126
+ * Take a screenshot from an iOS simulator
127
+ */
128
+ export async function iosScreenshot(outputPath, udid) {
129
+ try {
130
+ const simctlAvailable = await isSimctlAvailable();
131
+ if (!simctlAvailable) {
132
+ return {
133
+ success: false,
134
+ error: "Xcode command line tools not available. Install Xcode from the App Store."
135
+ };
136
+ }
137
+ const deviceArg = buildDeviceArg(udid);
138
+ // Check if a simulator is booted
139
+ if (!udid) {
140
+ const bootedUdid = await getBootedSimulatorUdid();
141
+ if (!bootedUdid) {
142
+ return {
143
+ success: false,
144
+ error: "No iOS simulator is currently running. Start a simulator first."
145
+ };
146
+ }
147
+ }
148
+ // Generate output path if not provided
149
+ const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
150
+ const finalOutputPath = outputPath || path.join(os.tmpdir(), `ios-screenshot-${timestamp}.png`);
151
+ await execAsync(`xcrun simctl io ${deviceArg} screenshot "${finalOutputPath}"`, {
152
+ timeout: SIMCTL_TIMEOUT
153
+ });
154
+ // Resize image if needed (API limit: 2000px max for multi-image requests)
155
+ // Return scale factor so AI can convert image coords to device coords
156
+ const MAX_DIMENSION = 2000;
157
+ const image = sharp(finalOutputPath);
158
+ const metadata = await image.metadata();
159
+ const originalWidth = metadata.width || 0;
160
+ const originalHeight = metadata.height || 0;
161
+ let imageData;
162
+ let scaleFactor = 1;
163
+ if (originalWidth > MAX_DIMENSION || originalHeight > MAX_DIMENSION) {
164
+ // Calculate scale to fit within MAX_DIMENSION
165
+ scaleFactor = Math.max(originalWidth, originalHeight) / MAX_DIMENSION;
166
+ imageData = await image
167
+ .resize(MAX_DIMENSION, MAX_DIMENSION, {
168
+ fit: "inside",
169
+ withoutEnlargement: true
170
+ })
171
+ .png({ compressionLevel: 9 })
172
+ .toBuffer();
173
+ }
174
+ else {
175
+ imageData = await image
176
+ .png({ compressionLevel: 9 })
177
+ .toBuffer();
178
+ }
179
+ return {
180
+ success: true,
181
+ result: finalOutputPath,
182
+ data: imageData,
183
+ scaleFactor,
184
+ originalWidth,
185
+ originalHeight
186
+ };
187
+ }
188
+ catch (error) {
189
+ return {
190
+ success: false,
191
+ error: `Failed to capture screenshot: ${error instanceof Error ? error.message : String(error)}`
192
+ };
193
+ }
194
+ }
195
+ /**
196
+ * Install an app on an iOS simulator
197
+ */
198
+ export async function iosInstallApp(appPath, udid) {
199
+ try {
200
+ const simctlAvailable = await isSimctlAvailable();
201
+ if (!simctlAvailable) {
202
+ return {
203
+ success: false,
204
+ error: "Xcode command line tools not available. Install Xcode from the App Store."
205
+ };
206
+ }
207
+ // Verify app exists
208
+ if (!existsSync(appPath)) {
209
+ return {
210
+ success: false,
211
+ error: `App bundle not found: ${appPath}`
212
+ };
213
+ }
214
+ const deviceArg = buildDeviceArg(udid);
215
+ // Check if a simulator is booted
216
+ if (!udid) {
217
+ const bootedUdid = await getBootedSimulatorUdid();
218
+ if (!bootedUdid) {
219
+ return {
220
+ success: false,
221
+ error: "No iOS simulator is currently running. Start a simulator first."
222
+ };
223
+ }
224
+ }
225
+ await execAsync(`xcrun simctl install ${deviceArg} "${appPath}"`, {
226
+ timeout: 120000 // 2 minute timeout for install
227
+ });
228
+ return {
229
+ success: true,
230
+ result: `Successfully installed ${path.basename(appPath)}`
231
+ };
232
+ }
233
+ catch (error) {
234
+ return {
235
+ success: false,
236
+ error: `Failed to install app: ${error instanceof Error ? error.message : String(error)}`
237
+ };
238
+ }
239
+ }
240
+ /**
241
+ * Launch an app on an iOS simulator
242
+ */
243
+ export async function iosLaunchApp(bundleId, udid) {
244
+ try {
245
+ const simctlAvailable = await isSimctlAvailable();
246
+ if (!simctlAvailable) {
247
+ return {
248
+ success: false,
249
+ error: "Xcode command line tools not available. Install Xcode from the App Store."
250
+ };
251
+ }
252
+ const deviceArg = buildDeviceArg(udid);
253
+ // Check if a simulator is booted
254
+ if (!udid) {
255
+ const bootedUdid = await getBootedSimulatorUdid();
256
+ if (!bootedUdid) {
257
+ return {
258
+ success: false,
259
+ error: "No iOS simulator is currently running. Start a simulator first."
260
+ };
261
+ }
262
+ }
263
+ await execAsync(`xcrun simctl launch ${deviceArg} ${bundleId}`, {
264
+ timeout: SIMCTL_TIMEOUT
265
+ });
266
+ return {
267
+ success: true,
268
+ result: `Launched ${bundleId}`
269
+ };
270
+ }
271
+ catch (error) {
272
+ return {
273
+ success: false,
274
+ error: `Failed to launch app: ${error instanceof Error ? error.message : String(error)}`
275
+ };
276
+ }
277
+ }
278
+ /**
279
+ * Open a URL in the iOS simulator
280
+ */
281
+ export async function iosOpenUrl(url, udid) {
282
+ try {
283
+ const simctlAvailable = await isSimctlAvailable();
284
+ if (!simctlAvailable) {
285
+ return {
286
+ success: false,
287
+ error: "Xcode command line tools not available. Install Xcode from the App Store."
288
+ };
289
+ }
290
+ const deviceArg = buildDeviceArg(udid);
291
+ // Check if a simulator is booted
292
+ if (!udid) {
293
+ const bootedUdid = await getBootedSimulatorUdid();
294
+ if (!bootedUdid) {
295
+ return {
296
+ success: false,
297
+ error: "No iOS simulator is currently running. Start a simulator first."
298
+ };
299
+ }
300
+ }
301
+ await execAsync(`xcrun simctl openurl ${deviceArg} "${url}"`, {
302
+ timeout: SIMCTL_TIMEOUT
303
+ });
304
+ return {
305
+ success: true,
306
+ result: `Opened URL: ${url}`
307
+ };
308
+ }
309
+ catch (error) {
310
+ return {
311
+ success: false,
312
+ error: `Failed to open URL: ${error instanceof Error ? error.message : String(error)}`
313
+ };
314
+ }
315
+ }
316
+ /**
317
+ * Terminate an app on an iOS simulator
318
+ */
319
+ export async function iosTerminateApp(bundleId, udid) {
320
+ try {
321
+ const simctlAvailable = await isSimctlAvailable();
322
+ if (!simctlAvailable) {
323
+ return {
324
+ success: false,
325
+ error: "Xcode command line tools not available. Install Xcode from the App Store."
326
+ };
327
+ }
328
+ const deviceArg = buildDeviceArg(udid);
329
+ // Check if a simulator is booted
330
+ if (!udid) {
331
+ const bootedUdid = await getBootedSimulatorUdid();
332
+ if (!bootedUdid) {
333
+ return {
334
+ success: false,
335
+ error: "No iOS simulator is currently running. Start a simulator first."
336
+ };
337
+ }
338
+ }
339
+ await execAsync(`xcrun simctl terminate ${deviceArg} ${bundleId}`, {
340
+ timeout: SIMCTL_TIMEOUT
341
+ });
342
+ return {
343
+ success: true,
344
+ result: `Terminated ${bundleId}`
345
+ };
346
+ }
347
+ catch (error) {
348
+ return {
349
+ success: false,
350
+ error: `Failed to terminate app: ${error instanceof Error ? error.message : String(error)}`
351
+ };
352
+ }
353
+ }
354
+ /**
355
+ * Boot an iOS simulator
356
+ */
357
+ export async function iosBootSimulator(udid) {
358
+ try {
359
+ const simctlAvailable = await isSimctlAvailable();
360
+ if (!simctlAvailable) {
361
+ return {
362
+ success: false,
363
+ error: "Xcode command line tools not available. Install Xcode from the App Store."
364
+ };
365
+ }
366
+ await execAsync(`xcrun simctl boot ${udid}`, {
367
+ timeout: 60000 // 1 minute timeout for boot
368
+ });
369
+ // Open Simulator app
370
+ await execAsync("open -a Simulator", { timeout: 10000 }).catch(() => {
371
+ // Ignore if Simulator app doesn't open
372
+ });
373
+ return {
374
+ success: true,
375
+ result: `Simulator ${udid} is now booting`
376
+ };
377
+ }
378
+ catch (error) {
379
+ const errorMessage = error instanceof Error ? error.message : String(error);
380
+ // Already booted is not an error
381
+ if (errorMessage.includes("Unable to boot device in current state: Booted")) {
382
+ return {
383
+ success: true,
384
+ result: "Simulator is already booted"
385
+ };
386
+ }
387
+ return {
388
+ success: false,
389
+ error: `Failed to boot simulator: ${errorMessage}`
390
+ };
391
+ }
392
+ }
393
+ //# sourceMappingURL=ios.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ios.js","sourceRoot":"","sources":["../../src/core/ios.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import { LogEntry, LogLevel } from "./types.js";
2
+ export declare class LogBuffer {
3
+ private logs;
4
+ private maxSize;
5
+ constructor(maxSize?: number);
6
+ add(entry: LogEntry): void;
7
+ get(count?: number, level?: string, startFromText?: string): LogEntry[];
8
+ search(text: string, maxResults?: number): LogEntry[];
9
+ clear(): number;
10
+ get size(): number;
11
+ getAll(): LogEntry[];
12
+ }
13
+ export declare function mapConsoleType(type: string): LogEntry["level"];
14
+ export declare function formatLogs(logs: LogEntry[]): string;
15
+ export declare function getLogs(logBuffer: LogBuffer, options?: {
16
+ maxLogs?: number;
17
+ level?: LogLevel;
18
+ startFromText?: string;
19
+ }): {
20
+ logs: LogEntry[];
21
+ formatted: string;
22
+ };
23
+ export declare function searchLogs(logBuffer: LogBuffer, text: string, maxResults?: number): {
24
+ logs: LogEntry[];
25
+ formatted: string;
26
+ };
27
+ //# sourceMappingURL=logs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../src/core/logs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGhD,qBAAa,SAAS;IAClB,OAAO,CAAC,IAAI,CAAkB;IAC9B,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,GAAE,MAAa;IAIlC,GAAG,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;IAO1B,GAAG,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,QAAQ,EAAE;IA4BvE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,QAAQ,EAAE;IAUrD,KAAK,IAAI,MAAM;IAMf,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,MAAM,IAAI,QAAQ,EAAE;CAGvB;AAGD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,CAc9D;AAGD,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,MAAM,CAYnD;AAGD,wBAAgB,OAAO,CACnB,SAAS,EAAE,SAAS,EACpB,OAAO,GAAE;IACL,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;CACrB,GACP;IAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAOzC;AAGD,wBAAgB,UAAU,CACtB,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,MAAM,EACZ,UAAU,GAAE,MAAW,GACxB;IAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAMzC"}
@@ -0,0 +1,102 @@
1
+ // Circular buffer for storing logs
2
+ export class LogBuffer {
3
+ logs = [];
4
+ maxSize;
5
+ constructor(maxSize = 1000) {
6
+ this.maxSize = maxSize;
7
+ }
8
+ add(entry) {
9
+ this.logs.push(entry);
10
+ if (this.logs.length > this.maxSize) {
11
+ this.logs.shift();
12
+ }
13
+ }
14
+ get(count, level, startFromText) {
15
+ let filtered = this.logs;
16
+ // If startFromText is provided, find the LAST matching line and start from there
17
+ if (startFromText) {
18
+ let startIndex = -1;
19
+ for (let i = filtered.length - 1; i >= 0; i--) {
20
+ if (filtered[i].message.includes(startFromText)) {
21
+ startIndex = i;
22
+ break;
23
+ }
24
+ }
25
+ if (startIndex !== -1) {
26
+ filtered = filtered.slice(startIndex);
27
+ }
28
+ }
29
+ if (level && level !== "all") {
30
+ filtered = filtered.filter((log) => log.level === level);
31
+ }
32
+ if (count && count > 0) {
33
+ filtered = filtered.slice(0, count);
34
+ }
35
+ return filtered;
36
+ }
37
+ search(text, maxResults) {
38
+ const results = this.logs.filter((log) => log.message.toLowerCase().includes(text.toLowerCase()));
39
+ if (maxResults && maxResults > 0) {
40
+ return results.slice(0, maxResults);
41
+ }
42
+ return results;
43
+ }
44
+ clear() {
45
+ const count = this.logs.length;
46
+ this.logs = [];
47
+ return count;
48
+ }
49
+ get size() {
50
+ return this.logs.length;
51
+ }
52
+ getAll() {
53
+ return [...this.logs];
54
+ }
55
+ }
56
+ // Map console type to log level
57
+ export function mapConsoleType(type) {
58
+ switch (type) {
59
+ case "error":
60
+ return "error";
61
+ case "warning":
62
+ case "warn":
63
+ return "warn";
64
+ case "info":
65
+ return "info";
66
+ case "debug":
67
+ return "debug";
68
+ default:
69
+ return "log";
70
+ }
71
+ }
72
+ // Format logs for text output
73
+ export function formatLogs(logs) {
74
+ if (logs.length === 0) {
75
+ return "No logs captured yet. Make sure Metro is running and the app is connected.";
76
+ }
77
+ return logs
78
+ .map((log) => {
79
+ const time = log.timestamp.toLocaleTimeString();
80
+ const levelTag = `[${log.level.toUpperCase()}]`;
81
+ return `${time} ${levelTag} ${log.message}`;
82
+ })
83
+ .join("\n");
84
+ }
85
+ // Get logs with formatting
86
+ export function getLogs(logBuffer, options = {}) {
87
+ const { maxLogs = 50, level = "all", startFromText } = options;
88
+ const logs = logBuffer.get(maxLogs, level, startFromText);
89
+ return {
90
+ logs,
91
+ formatted: formatLogs(logs)
92
+ };
93
+ }
94
+ // Search logs with formatting
95
+ export function searchLogs(logBuffer, text, maxResults = 50) {
96
+ const logs = logBuffer.search(text, maxResults);
97
+ return {
98
+ logs,
99
+ formatted: formatLogs(logs)
100
+ };
101
+ }
102
+ //# sourceMappingURL=logs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.js","sourceRoot":"","sources":["../../src/core/logs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { DeviceInfo } from "./types.js";
2
+ export declare const COMMON_PORTS: number[];
3
+ export declare function isPortOpen(port: number, host?: string): Promise<boolean>;
4
+ export declare function scanMetroPorts(startPort?: number, endPort?: number): Promise<number[]>;
5
+ export declare function fetchDevices(port: number): Promise<DeviceInfo[]>;
6
+ export declare function selectMainDevice(devices: DeviceInfo[]): DeviceInfo | null;
7
+ export declare function discoverMetroDevices(startPort?: number, endPort?: number): Promise<Map<number, DeviceInfo[]>>;
8
+ //# sourceMappingURL=metro.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metro.d.ts","sourceRoot":"","sources":["../../src/core/metro.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAGxC,eAAO,MAAM,YAAY,UAAoC,CAAC;AAG9D,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,MAAoB,GAAG,OAAO,CAAC,OAAO,CAAC,CAsB3F;AAGD,wBAAsB,cAAc,CAChC,SAAS,GAAE,MAAa,EACxB,OAAO,GAAE,MAAc,GACxB,OAAO,CAAC,MAAM,EAAE,CAAC,CAenB;AAGD,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAWtE;AAGD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,UAAU,GAAG,IAAI,CAmBzE;AAGD,wBAAsB,oBAAoB,CACtC,SAAS,GAAE,MAAa,EACxB,OAAO,GAAE,MAAc,GACxB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC,CAYpC"}
@@ -0,0 +1,79 @@
1
+ import * as net from "net";
2
+ // Common Metro ports
3
+ export const COMMON_PORTS = [8081, 8082, 19000, 19001, 19002];
4
+ // Check if a port is open
5
+ export async function isPortOpen(port, host = "localhost") {
6
+ return new Promise((resolve) => {
7
+ const socket = new net.Socket();
8
+ socket.setTimeout(1000);
9
+ socket.on("connect", () => {
10
+ socket.destroy();
11
+ resolve(true);
12
+ });
13
+ socket.on("timeout", () => {
14
+ socket.destroy();
15
+ resolve(false);
16
+ });
17
+ socket.on("error", () => {
18
+ socket.destroy();
19
+ resolve(false);
20
+ });
21
+ socket.connect(port, host);
22
+ });
23
+ }
24
+ // Scan for running Metro servers
25
+ export async function scanMetroPorts(startPort = 8081, endPort = 19002) {
26
+ const portsToCheck = startPort === 8081 && endPort === 19002
27
+ ? COMMON_PORTS
28
+ : Array.from({ length: endPort - startPort + 1 }, (_, i) => startPort + i);
29
+ const openPorts = [];
30
+ for (const port of portsToCheck) {
31
+ if (await isPortOpen(port)) {
32
+ openPorts.push(port);
33
+ }
34
+ }
35
+ return openPorts;
36
+ }
37
+ // Fetch connected devices from Metro /json endpoint
38
+ export async function fetchDevices(port) {
39
+ try {
40
+ const response = await fetch(`http://localhost:${port}/json`);
41
+ if (!response.ok) {
42
+ return [];
43
+ }
44
+ const devices = (await response.json());
45
+ return devices.filter((d) => d.webSocketDebuggerUrl);
46
+ }
47
+ catch {
48
+ return [];
49
+ }
50
+ }
51
+ // Select the main JS runtime device from a list of devices (priority order)
52
+ export function selectMainDevice(devices) {
53
+ if (devices.length === 0) {
54
+ return null;
55
+ }
56
+ return (
57
+ // SDK 54+ uses "React Native Bridgeless" in description
58
+ devices.find((d) => d.description.includes("React Native Bridgeless")) ||
59
+ // Hermes runtime (RN 0.70+)
60
+ devices.find((d) => d.title === "Hermes React Native" || d.title.includes("Hermes")) ||
61
+ // Fallback: any React Native in title, excluding Reanimated/Experimental
62
+ devices.find((d) => d.title.includes("React Native") &&
63
+ !d.title.includes("Reanimated") &&
64
+ !d.title.includes("Experimental")) ||
65
+ devices[0]);
66
+ }
67
+ // Scan for Metro and return all devices grouped by port
68
+ export async function discoverMetroDevices(startPort = 8081, endPort = 19002) {
69
+ const openPorts = await scanMetroPorts(startPort, endPort);
70
+ const result = new Map();
71
+ for (const port of openPorts) {
72
+ const devices = await fetchDevices(port);
73
+ if (devices.length > 0) {
74
+ result.set(port, devices);
75
+ }
76
+ }
77
+ return result;
78
+ }
79
+ //# sourceMappingURL=metro.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metro.js","sourceRoot":"","sources":["../../src/core/metro.ts"],"names":[],"mappings":"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"}