Skip to content

Commit 3140463

Browse files
committed
fix(cli): support multiple debug targets
1 parent 4b6ba94 commit 3140463

File tree

4 files changed

+91
-19
lines changed

4 files changed

+91
-19
lines changed

.changeset/calm-adults-provide.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@rnx-kit/cli": patch
3+
---
4+
5+
Support multiple debug targets

packages/cli/src/serve/keyboard.ts

Lines changed: 74 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,93 @@
11
import { info } from "@rnx-kit/console";
22
import type { MetroTerminal } from "@rnx-kit/metro-service";
3+
import * as fs from "node:fs";
4+
import type { Server } from "node:http";
5+
import * as path from "node:path";
36
import readline from "node:readline";
47
import qrcode from "qrcode";
58
import type { DevServerMiddleware } from "./types";
69

7-
type Options = {
10+
type OpenDebuggerKeyboardHandler = {
11+
handleOpenDebugger: () => Promise<void>;
12+
maybeHandleTargetSelection: (key: string) => boolean;
13+
dismiss: () => void;
14+
};
15+
16+
type Params = {
817
devServerUrl: string;
918
help: () => void;
1019
messageSocketEndpoint: DevServerMiddleware["messageSocketEndpoint"];
11-
terminal: MetroTerminal["terminal"];
20+
metroTerminal: MetroTerminal;
21+
reactNativePath: string;
1222
};
1323

14-
export function attachKeyHandlers({
24+
function createOpenDebuggerKeyboardHandler({
1525
devServerUrl,
16-
help,
17-
messageSocketEndpoint,
18-
terminal,
19-
}: Options) {
26+
metroTerminal: { reporter },
27+
reactNativePath,
28+
}: Params): OpenDebuggerKeyboardHandler {
29+
const resolvedPath = fs.lstatSync(reactNativePath).isSymbolicLink()
30+
? path.resolve(
31+
path.dirname(reactNativePath),
32+
fs.readlinkSync(reactNativePath)
33+
)
34+
: reactNativePath;
35+
try {
36+
// Available starting with 0.76
37+
const cliPlugin = require.resolve(
38+
"@react-native/community-cli-plugin/package.json",
39+
{ paths: [resolvedPath] }
40+
);
41+
const OpenDebuggerKeyboardHandler = require(
42+
`${path.dirname(cliPlugin)}/dist/commands/start/OpenDebuggerKeyboardHandler`
43+
);
44+
return new OpenDebuggerKeyboardHandler({ devServerUrl, reporter });
45+
} catch (_) {
46+
return {
47+
handleOpenDebugger: () => {
48+
info("Opening debugger...");
49+
fetch(devServerUrl + "/open-debugger", { method: "POST" });
50+
return Promise.resolve();
51+
},
52+
maybeHandleTargetSelection: (_: string): boolean => false,
53+
dismiss: () => undefined,
54+
};
55+
}
56+
}
57+
58+
export function attachKeyHandlers(server: Server, params: Params) {
59+
const openDebuggerKeyboardHandler = createOpenDebuggerKeyboardHandler(params);
60+
const {
61+
devServerUrl,
62+
help,
63+
messageSocketEndpoint,
64+
metroTerminal: { terminal },
65+
} = params;
66+
67+
process.on("SIGINT", () => {
68+
openDebuggerKeyboardHandler.dismiss();
69+
process.stdin.pause();
70+
process.stdin.setRawMode(false);
71+
info("Exiting...");
72+
server.close();
73+
server.closeAllConnections?.(); // This method was added in Node v18.2.0
74+
75+
// Even when we close all connections, clients may keep the server alive.
76+
process.exit();
77+
});
78+
2079
process.stdin.setRawMode(true);
2180
process.stdin.on("keypress", (_key, data) => {
2281
const { ctrl, name } = data;
82+
if (openDebuggerKeyboardHandler.maybeHandleTargetSelection(name)) {
83+
return;
84+
}
85+
2386
if (ctrl === true) {
2487
switch (name) {
2588
case "c":
26-
info("Exiting...");
27-
process.exit();
28-
break;
29-
case "z":
30-
process.emit("SIGTSTP", "SIGTSTP");
89+
case "d":
90+
process.emit("SIGINT");
3191
break;
3292
}
3393
} else {
@@ -41,11 +101,9 @@ export function attachKeyHandlers({
41101
help();
42102
break;
43103

44-
case "j": {
45-
info("Opening debugger...");
46-
fetch(devServerUrl + "/open-debugger", { method: "POST" });
104+
case "j":
105+
openDebuggerKeyboardHandler.handleOpenDebugger();
47106
break;
48-
}
49107

50108
case "q": {
51109
const url = `${devServerUrl}/index.bundle`;

packages/cli/src/start.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,16 @@ export async function rnxStart(
225225
// in interactive mode, listen for keyboard events from stdin and bind
226226
// them to specific actions.
227227
if (interactive) {
228-
attachKeyHandlers({ devServerUrl, help, messageSocketEndpoint, terminal });
228+
attachKeyHandlers(serverInstance, {
229+
devServerUrl,
230+
help,
231+
messageSocketEndpoint,
232+
metroTerminal: {
233+
terminal,
234+
reporter: terminalReporter,
235+
},
236+
reactNativePath: ctx.reactNativePath,
237+
});
229238
}
230239
}
231240

packages/test-app/ios/Podfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1484,7 +1484,7 @@ PODS:
14841484
- ReactTestApp-MSAL (4.0.0):
14851485
- MSAL
14861486
- ReactTestApp-Resources (1.0.0-dev)
1487-
- RNWWebStorage (0.3.0):
1487+
- RNWWebStorage (0.3.1):
14881488
- DoubleConversion
14891489
- glog
14901490
- RCT-Folly (= 2024.01.01.00)
@@ -1786,7 +1786,7 @@ SPEC CHECKSUMS:
17861786
ReactTestApp-DevSupport: 74676edd899013becce4eaecc5eabba1fc51e26e
17871787
ReactTestApp-MSAL: a7ac8e821fce95fc4e27cd91cf2a931b277ffef3
17881788
ReactTestApp-Resources: a4cc1f968cd26bdbd18ee0bfbd0ab8dd0ea90101
1789-
RNWWebStorage: 39af6c7aa24a9360372280338e0f5900630779a2
1789+
RNWWebStorage: 16ea67c1467a5b91c2859c490bec800f001adf78
17901790
RNXAuth: 7716515bc74149d226d798138f2d76af9f34427f
17911791
SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d
17921792
Yoga: 4ef80d96a5534f0e01b3055f17d1e19a9fc61b63

0 commit comments

Comments
 (0)