@@ -95,6 +95,90 @@ function convertResultToError(result) {
9595 return err ;
9696}
9797
98+ class RemoteObject {
99+ constructor ( attributes ) {
100+ Object . assign ( this , attributes ) ;
101+ if ( this . type === 'number' ) {
102+ this . value = this . unserializableValue ? + this . unserializableValue : + this . value ;
103+ }
104+ }
105+
106+ [ util . inspect . custom ] ( depth , opts ) {
107+ function formatProperty ( prop ) {
108+ switch ( prop . type ) {
109+ case 'string' :
110+ case 'undefined' :
111+ return util . inspect ( prop . value , opts ) ;
112+
113+ case 'number' :
114+ case 'boolean' :
115+ return opts . stylize ( prop . value , prop . type ) ;
116+
117+ case 'object' :
118+ case 'symbol' :
119+ if ( prop . subtype === 'date' ) {
120+ return util . inspect ( new Date ( prop . value ) , opts ) ;
121+ }
122+ if ( prop . subtype === 'array' ) {
123+ return opts . stylize ( prop . value , 'special' ) ;
124+ }
125+ return opts . stylize ( prop . value , prop . subtype || 'special' ) ;
126+
127+ default :
128+ return prop . value ;
129+ }
130+ }
131+ switch ( this . type ) {
132+ case 'boolean' :
133+ case 'number' :
134+ case 'string' :
135+ case 'undefined' :
136+ return util . inspect ( this . value , opts ) ;
137+
138+ case 'symbol' :
139+ return opts . stylize ( this . description , 'special' ) ;
140+
141+ case 'object' :
142+ switch ( this . subtype ) {
143+ case 'date' :
144+ return util . inspect ( new Date ( this . description ) , opts ) ;
145+
146+ case 'null' :
147+ return util . inspect ( null , opts ) ;
148+
149+ case 'regexp' :
150+ return opts . stylize ( this . description , 'regexp' ) ;
151+
152+ default :
153+ break ;
154+ }
155+ if ( this . preview ) {
156+ const props = this . preview . properties
157+ . map ( ( prop , idx ) => {
158+ const value = formatProperty ( prop ) ;
159+ if ( prop . name === `${ idx } ` ) return value ;
160+ return `${ prop . name } : ${ value } ` ;
161+ } ) ;
162+ if ( this . preview . overflow ) {
163+ props . push ( '...' ) ;
164+ }
165+ const singleLine = props . join ( ', ' ) ;
166+ const propString = singleLine . length > 60 ? props . join ( ',\n ' ) : singleLine ;
167+ return this . subtype === 'array' ? `[ ${ propString } ]` : `{ ${ propString } }` ;
168+ }
169+ return this . description ;
170+
171+ default :
172+ return this . description ;
173+ }
174+ }
175+ }
176+
177+ function convertResultToRemoteObject ( { result, wasThrown } ) {
178+ if ( wasThrown ) return convertResultToError ( result ) ;
179+ return new RemoteObject ( result ) ;
180+ }
181+
98182function copyOwnProperties ( target , source ) {
99183 Object . getOwnPropertyNames ( source ) . forEach ( ( prop ) => {
100184 Object . defineProperty ( target , prop , Object . getOwnPropertyDescriptor ( source , prop ) ) ;
@@ -122,6 +206,11 @@ function createRepl(inspector) {
122206
123207 const print = inspector . print . bind ( inspector ) ;
124208
209+ const INSPECT_OPTIONS = { colors : inspector . stdout . isTTY } ;
210+ function inspect ( value ) {
211+ return util . inspect ( value , INSPECT_OPTIONS ) ;
212+ }
213+
125214 function isCurrentScript ( script ) {
126215 return selectedFrame && selectedFrame . location . scriptId === script . scriptId ;
127216 }
@@ -199,8 +288,49 @@ function createRepl(inspector) {
199288 }
200289 }
201290
202- function watchers ( ) {
203- return Promise . resolve ( watchedExpressions ) ;
291+ function debugEval ( code ) {
292+ // Repl asked for scope variables
293+ if ( code === '.scope' ) {
294+ return Promise . reject ( 'client.reqScopes not implemented' ) ;
295+ }
296+
297+ const params = {
298+ callFrameId : selectedFrame . callFrameId ,
299+ expression : code ,
300+ objectGroup : 'node-inspect' ,
301+ generatePreview : true ,
302+ } ;
303+
304+ return Debugger . evaluateOnCallFrame ( params )
305+ . then ( convertResultToRemoteObject ) ;
306+ }
307+
308+ function watchers ( verbose = false ) {
309+ if ( ! watchedExpressions . length ) {
310+ return Promise . resolve ( ) ;
311+ }
312+
313+ const inspectValue = expr =>
314+ debugEval ( expr )
315+ // .then(formatValue)
316+ . catch ( error => `<${ error . message } >` ) ;
317+
318+ return Promise . all ( watchedExpressions . map ( inspectValue ) )
319+ . then ( values => {
320+ if ( verbose ) print ( 'Watchers:' ) ;
321+
322+ watchedExpressions . forEach ( ( expr , idx ) => {
323+ const prefix = `${ leftPad ( idx , ' ' , watchedExpressions . length - 1 ) } : ${ expr } =` ;
324+ const value = inspect ( values [ idx ] , { colors : true } ) ;
325+ if ( value . indexOf ( '\n' ) === - 1 ) {
326+ print ( `${ prefix } ${ value } ` ) ;
327+ } else {
328+ print ( `${ prefix } \n ${ value . split ( '\n' ) . join ( '\n ' ) } ` ) ;
329+ }
330+ } ) ;
331+
332+ if ( verbose ) print ( '' ) ;
333+ } ) ;
204334 }
205335
206336 // List source code
@@ -414,6 +544,27 @@ function createRepl(inspector) {
414544 return listBreakpoints ( ) ;
415545 } ,
416546
547+ exec ( expr ) {
548+ return debugEval ( expr ) ;
549+ } ,
550+
551+ get watchers ( ) {
552+ return watchers ( ) ;
553+ } ,
554+
555+ watch ( expr ) {
556+ watchedExpressions . push ( expr ) ;
557+ } ,
558+
559+ unwatch ( expr ) {
560+ const index = watchedExpressions . indexOf ( expr ) ;
561+
562+ // Unwatch by expression
563+ // or
564+ // Unwatch by watcher number
565+ watchedExpressions . splice ( index !== - 1 ? index : + expr , 1 ) ;
566+ } ,
567+
417568 scripts : listScripts ,
418569 setBreakpoint,
419570 list,
0 commit comments