@@ -10,6 +10,7 @@ const WebSocket = require('ws');
10
10
const api = require ( './api.js' ) ;
11
11
const defaults = require ( './defaults.js' ) ;
12
12
const devtools = require ( './devtools.js' ) ;
13
+ const StdioWrapper = require ( './stdio-wrapper.js' ) ;
13
14
14
15
class ProtocolError extends Error {
15
16
constructor ( request , response ) {
@@ -55,8 +56,9 @@ class Chrome extends EventEmitter {
55
56
this . useHostName = ! ! ( options . useHostName ) ;
56
57
this . alterPath = options . alterPath || ( ( path ) => path ) ;
57
58
this . protocol = options . protocol ;
58
- this . local = ! ! ( options . local ) ;
59
+ this . local = ! ! ( options . local || options . process ) ;
59
60
this . target = options . target || defaultTarget ;
61
+ this . process = options . process ;
60
62
// locals
61
63
this . _notifier = notifier ;
62
64
this . _callbacks = { } ;
@@ -101,26 +103,12 @@ class Chrome extends EventEmitter {
101
103
}
102
104
103
105
close ( callback ) {
104
- const closeWebSocket = ( callback ) => {
105
- // don't close if it's already closed
106
- if ( this . _ws . readyState === 3 ) {
107
- callback ( ) ;
108
- } else {
109
- // don't notify on user-initiated shutdown ('disconnect' event)
110
- this . _ws . removeAllListeners ( 'close' ) ;
111
- this . _ws . once ( 'close' , ( ) => {
112
- this . _ws . removeAllListeners ( ) ;
113
- callback ( ) ;
114
- } ) ;
115
- this . _ws . close ( ) ;
116
- }
117
- } ;
118
106
if ( typeof callback === 'function' ) {
119
- closeWebSocket ( callback ) ;
107
+ this . _close ( callback ) ;
120
108
return undefined ;
121
109
} else {
122
110
return new Promise ( ( fulfill , reject ) => {
123
- closeWebSocket ( fulfill ) ;
111
+ this . _close ( fulfill ) ;
124
112
} ) ;
125
113
}
126
114
}
@@ -135,20 +123,22 @@ class Chrome extends EventEmitter {
135
123
alterPath : this . alterPath
136
124
} ;
137
125
try {
138
- // fetch the WebSocket debugger URL
139
- const url = await this . _fetchDebuggerURL ( options ) ;
140
- // allow the user to alter the URL
141
- const urlObject = parseUrl ( url ) ;
142
- urlObject . pathname = options . alterPath ( urlObject . pathname ) ;
143
- this . webSocketUrl = formatUrl ( urlObject ) ;
144
- // update the connection parameters using the debugging URL
145
- options . host = urlObject . hostname ;
146
- options . port = urlObject . port || options . port ;
126
+ if ( ! this . process ) {
127
+ // fetch the WebSocket debugger URL
128
+ const url = await this . _fetchDebuggerURL ( options ) ;
129
+ // allow the user to alter the URL
130
+ const urlObject = parseUrl ( url ) ;
131
+ urlObject . pathname = options . alterPath ( urlObject . pathname ) ;
132
+ this . webSocketUrl = formatUrl ( urlObject ) ;
133
+ // update the connection parameters using the debugging URL
134
+ options . host = urlObject . hostname ;
135
+ options . port = urlObject . port || options . port ;
136
+ }
147
137
// fetch the protocol and prepare the API
148
138
const protocol = await this . _fetchProtocol ( options ) ;
149
139
api . prepare ( this , protocol ) ;
150
- // finally connect to the WebSocket
151
- await this . _connectToWebSocket ( ) ;
140
+ // finally connect to the WebSocket or stdio
141
+ await this . _connect ( ) ;
152
142
// since the handler is executed synchronously, the emit() must be
153
143
// performed in the next tick so that uncaught errors in the client code
154
144
// are not intercepted by the Promise mechanism and therefore reported
@@ -211,32 +201,59 @@ class Chrome extends EventEmitter {
211
201
}
212
202
}
213
203
214
- // establish the WebSocket connection and start processing user commands
215
- _connectToWebSocket ( ) {
204
+ _createStdioWrapper ( ) {
205
+ const stdio = new StdioWrapper ( this . process . stdio [ 3 ] , this . process . stdio [ 4 ] ) ;
206
+ this . _close = stdio . close . bind ( stdio ) ;
207
+ this . _send = stdio . send . bind ( stdio ) ;
208
+ return stdio ;
209
+ }
210
+
211
+ _createWebSocketWrapper ( ) {
212
+ if ( this . secure ) {
213
+ this . webSocketUrl = this . webSocketUrl . replace ( / ^ w s : / i, 'wss:' ) ;
214
+ }
215
+ const ws = new WebSocket ( this . webSocketUrl ) ;
216
+ this . _close = ( callback ) => {
217
+ // don't close if it's already closed
218
+ if ( ws . readyState === 3 ) {
219
+ callback ( ) ;
220
+ } else {
221
+ // don't notify on user-initiated shutdown ('disconnect' event)
222
+ ws . removeAllListeners ( 'close' ) ;
223
+ ws . once ( 'close' , ( ) => {
224
+ ws . removeAllListeners ( ) ;
225
+ callback ( ) ;
226
+ } ) ;
227
+ ws . close ( ) ;
228
+ }
229
+ } ;
230
+ this . _send = ws . send . bind ( ws ) ;
231
+ return ws ;
232
+ }
233
+
234
+ // establish the connection wrapper and start processing user commands
235
+ _connect ( ) {
216
236
return new Promise ( ( fulfill , reject ) => {
217
- // create the WebSocket
237
+ let wrapper ;
218
238
try {
219
- if ( this . secure ) {
220
- this . webSocketUrl = this . webSocketUrl . replace ( / ^ w s : / i, 'wss:' ) ;
221
- }
222
- this . _ws = new WebSocket ( this . webSocketUrl ) ;
239
+ wrapper = this . process ? this . _createStdioWrapper ( ) : this . _createWebSocketWrapper ( ) ;
223
240
} catch ( err ) {
224
- // handles bad URLs
241
+ // handle missing stdio streams, bad URLs...
225
242
reject ( err ) ;
226
243
return ;
227
244
}
228
245
// set up event handlers
229
- this . _ws . on ( 'open' , ( ) => {
246
+ wrapper . on ( 'open' , ( ) => {
230
247
fulfill ( ) ;
231
248
} ) ;
232
- this . _ws . on ( 'message' , ( data ) => {
249
+ wrapper . on ( 'message' , ( data ) => {
233
250
const message = JSON . parse ( data ) ;
234
251
this . _handleMessage ( message ) ;
235
252
} ) ;
236
- this . _ws . on ( 'close' , ( code ) => {
253
+ wrapper . on ( 'close' , ( code ) => {
237
254
this . emit ( 'disconnect' ) ;
238
255
} ) ;
239
- this . _ws . on ( 'error' , ( err ) => {
256
+ wrapper . on ( 'error' , ( err ) => {
240
257
reject ( err ) ;
241
258
} ) ;
242
259
} ) ;
@@ -278,7 +295,7 @@ class Chrome extends EventEmitter {
278
295
id, method,
279
296
params : params || { }
280
297
} ;
281
- this . _ws . send ( JSON . stringify ( message ) , ( err ) => {
298
+ this . _send ( JSON . stringify ( message ) , ( err ) => {
282
299
if ( err ) {
283
300
// handle low-level WebSocket errors
284
301
if ( typeof callback === 'function' ) {
0 commit comments