Skip to content

Commit cdfdc2c

Browse files
committed
inspect: add promisified result for session.post
1 parent 472edc7 commit cdfdc2c

File tree

3 files changed

+90
-3
lines changed

3 files changed

+90
-3
lines changed

doc/api/inspector.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,15 +183,27 @@ changes:
183183
* `method` {string}
184184
* `params` {Object}
185185
* `callback` {Function}
186+
* Returns: {Promise|undefined}
186187

187188
Posts a message to the inspector back-end. `callback` will be notified when
188189
a response is received. `callback` is a function that accepts two optional
189190
arguments: error and message-specific result.
190191

192+
If the `callback` is not passed, then it'll return a Promise result.
193+
191194
```js
192195
session.post('Runtime.evaluate', { expression: '2 + 2' },
193196
(error, { result }) => console.log(result));
194197
// Output: { type: 'number', value: 4, description: '4' }
198+
199+
// or for promise
200+
session.post('Runtime.evaluate', { expression: '2 + 2' })
201+
.then((result) => {
202+
console.log(result);
203+
})
204+
.catch((error) => console.error(error));
205+
206+
// Output: { type: 'number', value: 4, description: '4' }
195207
```
196208

197209
The latest version of the V8 inspector protocol is published on the

lib/inspector.js

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const { hasInspector } = internalBinding('config');
2222
if (!hasInspector)
2323
throw new ERR_INSPECTOR_NOT_AVAILABLE();
2424

25+
const { promisify } = require('util');
2526
const EventEmitter = require('events');
2627
const { queueMicrotask } = require('internal/process/task_queues');
2728
const {
@@ -108,7 +109,7 @@ class Session extends EventEmitter {
108109
* @param {string} method
109110
* @param {Record<unknown, unknown>} [params]
110111
* @param {Function} [callback]
111-
* @returns {void}
112+
* @returns {void | Promise}
112113
*/
113114
post(method, params, callback) {
114115
validateString(method, 'method');
@@ -128,13 +129,26 @@ class Session extends EventEmitter {
128129
}
129130
const id = this[nextIdSymbol]++;
130131
const message = { id, method };
132+
const configureCbAndDispatch = (cb) => {
133+
this[messageCallbacksSymbol].set(id, cb);
134+
this[connectionSymbol].dispatch(JSONStringify(message));
135+
};
136+
131137
if (params) {
132138
message.params = params;
133139
}
134140
if (callback) {
135-
this[messageCallbacksSymbol].set(id, callback);
141+
configureCbAndDispatch(callback);
142+
return;
136143
}
137-
this[connectionSymbol].dispatch(JSONStringify(message));
144+
145+
const event = new EventEmitter();
146+
const kOnFinish = Symbol('kOnFinish');
147+
const promisifiedResult = promisify(event.once.bind(event))(kOnFinish);
148+
const cb = (err, res) => event.emit(kOnFinish, err, res);
149+
configureCbAndDispatch(cb);
150+
151+
return promisifiedResult;
138152
}
139153

140154
/**
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
common.skipIfInspectorDisabled();
5+
6+
const assert = require('assert');
7+
const {
8+
Session
9+
} = require('inspector');
10+
const {
11+
basename
12+
} = require('path');
13+
const currentFilename = basename(__filename);
14+
15+
{
16+
// Ensure that given a callback to session.post it won't return a promise result
17+
const session = new Session();
18+
session.connect();
19+
20+
const postResult = session.post('Profiler.enable', () => {
21+
session.post('Profiler.start', () => {
22+
session.post('Profiler.stop', (err, { profile }) => {
23+
24+
const { callFrame: { url } } = profile.nodes.find(({
25+
callFrame
26+
}) => callFrame.url.includes(currentFilename));
27+
session.disconnect();
28+
assert.deepStrictEqual(basename(url), currentFilename);
29+
});
30+
});
31+
});
32+
33+
assert.strictEqual(postResult, undefined);
34+
}
35+
36+
(async () => {
37+
{
38+
// Ensure that session.post returns a valid promisified result
39+
const session = new Session();
40+
session.connect();
41+
42+
await session.post('Profiler.enable');
43+
await session.post('Profiler.start');
44+
45+
const {
46+
profile
47+
} = await session.post('Profiler.stop');
48+
49+
const {
50+
callFrame: {
51+
url
52+
}
53+
} = profile.nodes.find(({
54+
callFrame
55+
}) => {
56+
return callFrame.url.includes(currentFilename);
57+
});
58+
session.disconnect();
59+
assert.deepStrictEqual(basename(url), currentFilename);
60+
}
61+
})().then(common.mustCall());

0 commit comments

Comments
 (0)