@@ -9,6 +9,7 @@ var sprintf = require('sprintf-js');
9
9
var events = require ( 'events' ) ;
10
10
var msg = require ( './Message' ) ;
11
11
var logger = require ( './logger' ) ;
12
+ var async = require ( 'async' ) ;
12
13
var Session = ( function ( _super ) {
13
14
__extends ( Session , _super ) ;
14
15
function Session ( options ) {
@@ -109,6 +110,15 @@ var Session = (function (_super) {
109
110
this . startBatch ( ) ;
110
111
return this ;
111
112
} ;
113
+ Session . prototype . sendTyping = function ( ) {
114
+ this . msgSent = true ;
115
+ var m = { type : 'typing' } ;
116
+ this . prepareMessage ( m ) ;
117
+ this . batch . push ( m ) ;
118
+ logger . info ( this , 'session.sendTyping()' ) ;
119
+ this . startBatch ( ) ;
120
+ return this ;
121
+ } ;
112
122
Session . prototype . messageSent = function ( ) {
113
123
return this . msgSent ;
114
124
} ;
@@ -174,61 +184,83 @@ var Session = (function (_super) {
174
184
return this . endDialogWithResult ( message ) ;
175
185
}
176
186
var cur = this . curDialog ( ) ;
177
- if ( ! cur ) {
178
- console . error ( 'ERROR: Too many calls to session.endDialog().' ) ;
179
- return this ;
180
- }
181
- var m ;
182
- if ( message ) {
183
- if ( typeof message == 'string' || Array . isArray ( message ) ) {
184
- m = this . createMessage ( message , args ) ;
185
- }
186
- else if ( message . toMessage ) {
187
- m = message . toMessage ( ) ;
188
- }
189
- else {
190
- m = message ;
191
- }
192
- this . msgSent = true ;
193
- this . prepareMessage ( m ) ;
194
- this . batch . push ( m ) ;
195
- }
196
- logger . info ( this , 'session.endDialog()' ) ;
197
- var childId = cur . id ;
198
- cur = this . popDialog ( ) ;
199
- this . startBatch ( ) ;
200
187
if ( cur ) {
201
- var dialog = this . findDialog ( cur . id ) ;
202
- if ( dialog ) {
203
- dialog . dialogResumed ( this , { resumed : dlg . ResumeReason . completed , response : true , childId : childId } ) ;
188
+ var m ;
189
+ if ( message ) {
190
+ if ( typeof message == 'string' || Array . isArray ( message ) ) {
191
+ m = this . createMessage ( message , args ) ;
192
+ }
193
+ else if ( message . toMessage ) {
194
+ m = message . toMessage ( ) ;
195
+ }
196
+ else {
197
+ m = message ;
198
+ }
199
+ this . msgSent = true ;
200
+ this . prepareMessage ( m ) ;
201
+ this . batch . push ( m ) ;
204
202
}
205
- else {
206
- this . error ( new Error ( "ERROR: Can't resume missing parent dialog '" + cur . id + "'." ) ) ;
203
+ logger . info ( this , 'session.endDialog()' ) ;
204
+ var childId = cur . id ;
205
+ cur = this . popDialog ( ) ;
206
+ this . startBatch ( ) ;
207
+ if ( cur ) {
208
+ var dialog = this . findDialog ( cur . id ) ;
209
+ if ( dialog ) {
210
+ dialog . dialogResumed ( this , { resumed : dlg . ResumeReason . completed , response : true , childId : childId } ) ;
211
+ }
212
+ else {
213
+ this . error ( new Error ( "Can't resume missing parent dialog '" + cur . id + "'." ) ) ;
214
+ }
207
215
}
208
216
}
209
217
return this ;
210
218
} ;
211
219
Session . prototype . endDialogWithResult = function ( result ) {
212
220
var cur = this . curDialog ( ) ;
213
- if ( ! cur ) {
214
- console . error ( 'ERROR: Too many calls to session.endDialog().' ) ;
215
- return this ;
216
- }
217
- result = result || { } ;
218
- if ( ! result . hasOwnProperty ( 'resumed' ) ) {
219
- result . resumed = dlg . ResumeReason . completed ;
220
- }
221
- result . childId = cur . id ;
222
- logger . info ( this , 'session.endDialogWithResult()' ) ;
223
- cur = this . popDialog ( ) ;
224
- this . startBatch ( ) ;
225
221
if ( cur ) {
226
- var dialog = this . findDialog ( cur . id ) ;
227
- if ( dialog ) {
228
- dialog . dialogResumed ( this , result ) ;
222
+ result = result || { } ;
223
+ if ( ! result . hasOwnProperty ( 'resumed' ) ) {
224
+ result . resumed = dlg . ResumeReason . completed ;
229
225
}
230
- else {
231
- this . error ( new Error ( "ERROR: Can't resume missing parent dialog '" + cur . id + "'." ) ) ;
226
+ result . childId = cur . id ;
227
+ logger . info ( this , 'session.endDialogWithResult()' ) ;
228
+ cur = this . popDialog ( ) ;
229
+ this . startBatch ( ) ;
230
+ if ( cur ) {
231
+ var dialog = this . findDialog ( cur . id ) ;
232
+ if ( dialog ) {
233
+ dialog . dialogResumed ( this , result ) ;
234
+ }
235
+ else {
236
+ this . error ( new Error ( "Can't resume missing parent dialog '" + cur . id + "'." ) ) ;
237
+ }
238
+ }
239
+ }
240
+ return this ;
241
+ } ;
242
+ Session . prototype . cancelDialog = function ( dialogId , replaceWithId , replaceWithArgs ) {
243
+ var childId = typeof dialogId === 'number' ? this . sessionState . callstack [ dialogId ] . id : dialogId ;
244
+ var cur = this . deleteDialogs ( dialogId ) ;
245
+ if ( replaceWithId ) {
246
+ logger . info ( this , 'session.cancelDialog(%s)' , replaceWithId ) ;
247
+ var id = this . resolveDialogId ( replaceWithId ) ;
248
+ var dialog = this . findDialog ( id ) ;
249
+ this . pushDialog ( { id : id , state : { } } ) ;
250
+ this . startBatch ( ) ;
251
+ dialog . begin ( this , replaceWithArgs ) ;
252
+ }
253
+ else {
254
+ logger . info ( this , 'session.cancelDialog()' ) ;
255
+ this . startBatch ( ) ;
256
+ if ( cur ) {
257
+ var dialog = this . findDialog ( cur . id ) ;
258
+ if ( dialog ) {
259
+ dialog . dialogResumed ( this , { resumed : dlg . ResumeReason . canceled , response : null , childId : childId } ) ;
260
+ }
261
+ else {
262
+ this . error ( new Error ( "Can't resume missing parent dialog '" + cur . id + "'." ) ) ;
263
+ }
232
264
}
233
265
}
234
266
return this ;
@@ -313,20 +345,106 @@ var Session = (function (_super) {
313
345
}
314
346
} ;
315
347
Session . prototype . routeMessage = function ( ) {
316
- var cur = this . curDialog ( ) ;
317
- if ( ! cur ) {
318
- this . beginDialog ( this . options . dialogId , this . options . dialogArgs ) ;
348
+ var _this = this ;
349
+ var _that = this ;
350
+ function routeToDialog ( recognizeResult ) {
351
+ var cur = _that . curDialog ( ) ;
352
+ if ( ! cur ) {
353
+ _that . beginDialog ( _that . options . dialogId , _that . options . dialogArgs ) ;
354
+ }
355
+ else {
356
+ var dialog = _that . findDialog ( cur . id ) ;
357
+ _that . dialogData = cur . state ;
358
+ dialog . replyReceived ( _that , recognizeResult ) ;
359
+ }
319
360
}
320
- else if ( this . validateCallstack ( ) ) {
321
- var dialog = this . findDialog ( cur . id ) ;
322
- this . dialogData = cur . state ;
323
- dialog . replyReceived ( this ) ;
361
+ if ( this . validateCallstack ( ) ) {
362
+ this . recognizeCurDialog ( function ( err , dialogResult ) {
363
+ if ( err ) {
364
+ _this . error ( err ) ;
365
+ }
366
+ else if ( dialogResult . score < 1.0 ) {
367
+ _this . recognizeCallstackActions ( function ( err , actionResult ) {
368
+ if ( err ) {
369
+ _this . error ( err ) ;
370
+ }
371
+ else if ( actionResult . score > dialogResult . score ) {
372
+ if ( actionResult . dialogId ) {
373
+ var dialog = _this . findDialog ( actionResult . dialogId ) ;
374
+ dialog . invokeAction ( _this , actionResult ) ;
375
+ }
376
+ else {
377
+ _this . options . actions . invokeAction ( _this , actionResult ) ;
378
+ }
379
+ }
380
+ else {
381
+ routeToDialog ( dialogResult ) ;
382
+ }
383
+ } ) ;
384
+ }
385
+ else {
386
+ routeToDialog ( dialogResult ) ;
387
+ }
388
+ } ) ;
324
389
}
325
390
else {
326
- console . warn ( 'Callstack is invalid, resetting session.' ) ;
391
+ logger . warn ( this , 'Callstack is invalid, resetting session.' ) ;
327
392
this . reset ( this . options . dialogId , this . options . dialogArgs ) ;
328
393
}
329
394
} ;
395
+ Session . prototype . recognizeCurDialog = function ( done ) {
396
+ var cur = this . curDialog ( ) ;
397
+ if ( cur && this . message . text . indexOf ( 'action?' ) !== 0 ) {
398
+ var dialog = this . findDialog ( cur . id ) ;
399
+ dialog . recognize ( { message : this . message , dialogData : cur . state , activeDialog : true } , done ) ;
400
+ }
401
+ else {
402
+ done ( null , { score : 0.0 } ) ;
403
+ }
404
+ } ;
405
+ Session . prototype . recognizeCallstackActions = function ( done ) {
406
+ var _this = this ;
407
+ var ss = this . sessionState ;
408
+ var i = ss . callstack . length - 1 ;
409
+ var result = { score : 0.0 } ;
410
+ async . whilst ( function ( ) {
411
+ return ( i >= 0 && result . score < 1.0 ) ;
412
+ } , function ( cb ) {
413
+ try {
414
+ var index = i -- ;
415
+ var cur = ss . callstack [ index ] ;
416
+ var dialog = _this . findDialog ( cur . id ) ;
417
+ dialog . recognizeAction ( _this . message , function ( err , r ) {
418
+ if ( ! err && r && r . score > result . score ) {
419
+ result = r ;
420
+ result . dialogId = cur . id ;
421
+ result . dialogIndex = index ;
422
+ }
423
+ cb ( err ) ;
424
+ } ) ;
425
+ }
426
+ catch ( e ) {
427
+ cb ( e ) ;
428
+ }
429
+ } , function ( err ) {
430
+ if ( ! err ) {
431
+ if ( result . score < 1.0 && _this . options . actions ) {
432
+ _this . options . actions . recognizeAction ( _this . message , function ( err , r ) {
433
+ if ( ! err && r && r . score > result . score ) {
434
+ result = r ;
435
+ }
436
+ done ( err , result ) ;
437
+ } ) ;
438
+ }
439
+ else {
440
+ done ( null , result ) ;
441
+ }
442
+ }
443
+ else {
444
+ done ( err instanceof Error ? err : new Error ( err . toString ( ) ) , null ) ;
445
+ }
446
+ } ) ;
447
+ } ;
330
448
Session . prototype . vgettext = function ( messageid , args ) {
331
449
var tmpl ;
332
450
if ( this . options . localizer && this . message ) {
@@ -378,6 +496,28 @@ var Session = (function (_super) {
378
496
this . dialogData = cur ? cur . state : null ;
379
497
return cur ;
380
498
} ;
499
+ Session . prototype . deleteDialogs = function ( dialogId ) {
500
+ var ss = this . sessionState ;
501
+ var index = - 1 ;
502
+ if ( typeof dialogId === 'string' ) {
503
+ for ( var i = ss . callstack . length - 1 ; i >= 0 ; i -- ) {
504
+ if ( ss . callstack [ i ] . id == dialogId ) {
505
+ index = i ;
506
+ break ;
507
+ }
508
+ }
509
+ }
510
+ else {
511
+ index = dialogId ;
512
+ }
513
+ if ( index < 0 && index < ss . callstack . length ) {
514
+ throw new Error ( 'Unable to cancel dialog. Dialog[' + dialogId + '] not found.' ) ;
515
+ }
516
+ ss . callstack . splice ( index ) ;
517
+ var cur = this . curDialog ( ) ;
518
+ this . dialogData = cur ? cur . state : null ;
519
+ return cur ;
520
+ } ;
381
521
Session . prototype . curDialog = function ( ) {
382
522
var cur ;
383
523
var ss = this . sessionState ;
0 commit comments