Skip to content
This repository was archived by the owner on Feb 1, 2022. It is now read-only.

Commit 481693f

Browse files
author
Jan Krems
committed
feat: Connect debug client
1 parent b39b3bc commit 481693f

File tree

4 files changed

+90
-20
lines changed

4 files changed

+90
-20
lines changed

Diff for: lib/internal/inspect-protocol.js

+9-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
* IN THE SOFTWARE.
2121
*/
2222
'use strict';
23+
const crypto = require('crypto');
2324
const { EventEmitter } = require('events');
2425
const http = require('http');
2526
const util = require('util');
@@ -271,8 +272,14 @@ class Client extends EventEmitter {
271272
this.emit('error', error);
272273
});
273274
};
274-
httpReq.on('upgrade', handshakeListener);
275-
httpReq.end();
275+
276+
return new Promise((resolve, reject) => {
277+
this.once('error', reject);
278+
this.once('ready', resolve);
279+
280+
httpReq.on('upgrade', handshakeListener);
281+
httpReq.end();
282+
});
276283
}
277284
}
278285
module.exports = Client;

Diff for: lib/node-inspect.js

+49-10
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,32 @@ function throwUnexpectedError(error) {
3131
process.nextTick(() => { throw error; });
3232
}
3333

34-
function runScript(script, scriptArgs, inspectPort) {
34+
function delay(ms) {
35+
return new Promise((resolve) => setTimeout(resolve, ms));
36+
}
37+
38+
function runScript(script, scriptArgs, inspectPort, childPrint) {
3539
return new Promise((resolve) => {
3640
const args = [
3741
'--inspect',
3842
`--debug-brk=${inspectPort}`,
3943
].concat([script], scriptArgs);
4044
const child = spawn(process.execPath, args);
41-
resolve(child);
45+
child.stdout.setEncoding('utf8');
46+
child.stderr.setEncoding('utf8');
47+
child.stdout.on('data', childPrint);
48+
child.stderr.on('data', childPrint);
49+
50+
let output = '';
51+
function waitForListenHint(text) {
52+
output += text;
53+
if (/chrome-devtools:\/\//.test(output)) {
54+
child.stderr.removeListener('data', waitForListenHint);
55+
resolve(child);
56+
}
57+
}
58+
59+
child.stderr.on('data', waitForListenHint);
4260
});
4361
}
4462

@@ -48,12 +66,15 @@ class NodeInspector {
4866
this.stdin = stdin;
4967
this.stdout = stdout;
5068

51-
this.paused = false;
69+
this.paused = true;
5270
this.child = null;
5371

5472
this._runScript = options.script ?
55-
runScript.bind(null, options.script, options.scriptArgs, options.port) :
56-
Promise.resolve.bind(null, null);
73+
runScript.bind(null,
74+
options.script, options.scriptArgs,
75+
options.port,
76+
this.childPrint.bind(this)
77+
) : () => Promise.resolve(null);
5778

5879
this.client = new ProtocolClient(options.port, options.host);
5980

@@ -82,6 +103,7 @@ class NodeInspector {
82103
this.repl.on('exit', () => {
83104
process.exit(0);
84105
});
106+
this.paused = false;
85107
}
86108

87109
killChild() {
@@ -96,12 +118,29 @@ class NodeInspector {
96118
this.killChild();
97119
return this._runScript().then((child) => {
98120
this.child = child;
99-
this.child.stdout.on('data', text => this.childPrint(text));
100-
this.child.stderr.on('data', text => this.childPrint(text));
121+
122+
let connectionAttempts = 0;
123+
const attemptConnect = () => {
124+
++connectionAttempts;
125+
this.stdout.write('.');
126+
this.client.connect()
127+
.then(null, () => {
128+
// If it's failed to connect 10 times then print failed message
129+
if (connectionAttempts >= 10) {
130+
this.print(' failed to connect, please retry');
131+
process.exit(1);
132+
}
133+
return delay(500).then(() => attemptConnect());
134+
});
135+
};
136+
137+
const { host, port } = this.options;
138+
this.print(`connecting to ${host}:${port} ..`, true);
139+
return attemptConnect();
101140
});
102141
}
103142

104-
clearline() {
143+
clearLine() {
105144
if (this.stdout.isTTY) {
106145
this.stdout.cursorTo(0);
107146
this.stdout.clearLine(1);
@@ -111,8 +150,8 @@ class NodeInspector {
111150
}
112151

113152
print(text, oneline = false) {
114-
this.clearline();
115-
this.stdout.write(oneline ? `${text}\n` : text);
153+
this.clearLine();
154+
this.stdout.write(oneline ? text : `${text}\n`);
116155
}
117156

118157
childPrint(text) {

Diff for: test/cli/launch.test.js

+1-5
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,9 @@ const tap = require('tap');
33

44
const startCLI = require('./start-cli');
55

6-
function delay(t) {
7-
return new Promise((resolve) => setTimeout(resolve, t));
8-
}
9-
106
tap.test('examples/empty.js', (t) => {
117
const cli = startCLI(['examples/empty.js']);
12-
return delay(1000)
8+
return cli.waitForPrompt()
139
.then(() => cli.quit())
1410
.then((code) => {
1511
t.match(cli.output, 'debug>', 'prints a prompt');

Diff for: test/cli/start-cli.js

+31-3
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,26 @@ const CLI = require.resolve('../../cli.js');
55

66
function startCLI(args) {
77
const child = spawn(process.execPath, [CLI, ...args]);
8+
let isFirstStdoutChunk = true;
89

910
const outputBuffer = [];
1011
function bufferOutput(chunk) {
11-
outputBuffer.push(chunk);
12+
if (isFirstStdoutChunk) {
13+
isFirstStdoutChunk = false;
14+
outputBuffer.push(chunk.replace(/^debug>\s*/, ''));
15+
} else {
16+
outputBuffer.push(chunk);
17+
}
1218
}
1319

20+
function getOutput() {
21+
return outputBuffer.join('').toString()
22+
.replace(/^[^\n]*[\b]/mg, '\n');
23+
}
24+
25+
child.stdout.setEncoding('utf8');
1426
child.stdout.on('data', bufferOutput);
27+
child.stderr.setEncoding('utf8');
1528
child.stderr.on('data', bufferOutput);
1629

1730
if (process.env.VERBOSE === '1') {
@@ -26,9 +39,24 @@ function startCLI(args) {
2639
return output;
2740
},
2841

42+
waitForPrompt() {
43+
return new Promise((resolve, reject) => {
44+
function checkOutput() {
45+
if (/debug>\s*$/.test(getOutput())) {
46+
child.stdout.removeListener('data', checkOutput);
47+
resolve();
48+
}
49+
}
50+
child.on('exit', () => {
51+
reject(new Error('Child quit while waiting for prompt'));
52+
});
53+
child.stdout.on('data', checkOutput);
54+
checkOutput();
55+
});
56+
},
57+
2958
get output() {
30-
return Buffer.concat(outputBuffer).toString()
31-
.replace(/^[^\n]*[\b]/mg, '\n');
59+
return getOutput();
3260
},
3361

3462
quit() {

0 commit comments

Comments
 (0)