botbuilder-dialogs
Version:
A dialog stack based conversation manager for Microsoft BotBuilder.
348 lines • 14.4 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Dialog = exports.DialogTurnStatus = exports.DialogReason = void 0;
/**
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
const botbuilder_core_1 = require("botbuilder-core");
const configurable_1 = require("./configurable");
/**
* Indicates why a dialog method is being called.
*
* @remarks
* Use a dialog context to control the dialogs in a dialog set. The dialog context will pass a reference to itself
* to the dialog method it calls. It also passes in the _reason_ why the specific method is being called.
*
* **See also**
* - [DialogContext](xref:botbuilder-dialogs.DialogContext)
* - [DialogSet](xref:botbuilder-dialogs.DialogSet)
* - [Dialog](xref:botbuilder-dialogs.Dialog)
*/
var DialogReason;
(function (DialogReason) {
/**
* The dialog is being started from
* [DialogContext.beginDialog](xref:botbuilder-dialogs.DialogContext.beginDialog) or
* [DialogContext.replaceDialog](xref:botbuilder-dialogs.DialogContext.replaceDialog).
*/
DialogReason["beginCalled"] = "beginCalled";
/**
* The dialog is being continued from
* [DialogContext.continueDialog](xref:botbuilder-dialogs.DialogContext.continueDialog).
*/
DialogReason["continueCalled"] = "continueCalled";
/**
* The dialog is being ended from
* [DialogContext.endDialog](xref:botbuilder-dialogs.DialogContext.endDialog).
*/
DialogReason["endCalled"] = "endCalled";
/**
* The dialog is being ended from
* [DialogContext.replaceDialog](xref:botbuilder-dialogs.DialogContext.replaceDialog).
*/
DialogReason["replaceCalled"] = "replaceCalled";
/**
* The dialog is being cancelled from
* [DialogContext.cancelAllDialogs](xref:botbuilder-dialogs.DialogContext.cancelAllDialogs).
*/
DialogReason["cancelCalled"] = "cancelCalled";
/**
* A step in a [WaterfallDialog](xref:botbuilder-dialogs.WaterfallDialog) is being called
* because the previous step in the waterfall dialog called
* [WaterfallStepContext.next](xref:botbuilder-dialogs.WaterfallStepContext.next).
*/
DialogReason["nextCalled"] = "nextCalled";
})(DialogReason = exports.DialogReason || (exports.DialogReason = {}));
/**
* Represents the state of the dialog stack after a dialog context attempts to begin, continue,
* or otherwise manipulate one or more dialogs.
*
* **See also**
* - [DialogContext](xref:botbuilder-dialogs.DialogContext)
* - [Dialog](xref:botbuilder-dialogs.Dialog)
*/
var DialogTurnStatus;
(function (DialogTurnStatus) {
/**
* The dialog stack is empty.
*
* @remarks
* Indicates that the dialog stack was initially empty when the operation was attempted.
*/
DialogTurnStatus["empty"] = "empty";
/**
* The active dialog on top of the stack is waiting for a response from the user.
*/
DialogTurnStatus["waiting"] = "waiting";
/**
* The last dialog on the stack completed successfully.
*
* @remarks
* Indicates that a result might be available and the stack is now empty.
*
* **See also**
* - [DialogTurnResult.result](xref:botbuilder-dialogs.DialogTurnResult.result)
*/
DialogTurnStatus["complete"] = "complete";
/**
* All dialogs on the stack were cancelled and the stack is empty.
*/
DialogTurnStatus["cancelled"] = "cancelled";
/**
* Current dialog completed successfully, but turn should end.
*/
DialogTurnStatus["completeAndWait"] = "completeAndWait";
})(DialogTurnStatus = exports.DialogTurnStatus || (exports.DialogTurnStatus = {}));
/**
* Defines the core behavior for all dialogs.
*/
class Dialog extends configurable_1.Configurable {
/**
* Creates a new instance of the [Dialog](xref:botbuilder-dialogs.Dialog) class.
*
* @param dialogId Optional. unique ID of the dialog.
*/
constructor(dialogId) {
super();
/**
* The telemetry client for logging events.
* Default this to the NullTelemetryClient, which does nothing.
*/
this._telemetryClient = new botbuilder_core_1.NullTelemetryClient();
this.id = dialogId;
}
/**
* Unique ID of the dialog.
*
* @remarks
* This will be automatically generated if not specified.
* @returns The Id for the dialog.
*/
get id() {
if (this._id === undefined) {
this._id = this.onComputeId();
}
return this._id;
}
/**
* Sets the unique ID of the dialog.
*/
set id(value) {
this._id = value;
}
/**
* Gets the telemetry client for this dialog.
*
* @returns The [BotTelemetryClient](xref:botbuilder.BotTelemetryClient) to use for logging.
*/
get telemetryClient() {
return this._telemetryClient;
}
/**
* Sets the telemetry client for this dialog.
*/
set telemetryClient(client) {
this._telemetryClient = client ? client : new botbuilder_core_1.NullTelemetryClient();
}
/**
* An encoded string used to aid in the detection of bot changes on re-deployment.
*
* @remarks
* This defaults to returning the dialogs [id](#id) but can be overridden to provide more
* precise change detection logic. Any dialog on the stack that has its version change will
* result in a `versionChanged` event will be raised. If this event is not handled by the bot,
* an error will be thrown resulting in the bots error handler logic being run.
*
* Returning an empty string will disable version tracking for the component all together.
* @returns Unique string which should only change when dialog has changed in a way that should restart the dialog.
*/
getVersion() {
return this.id;
}
/**
* When overridden in a derived class, continues the dialog.
*
* @param dc The context for the current dialog turn.
*
* @remarks
* Derived dialogs that support multiple-turn conversations should override this method.
* By default, this method signals that the dialog is complete and returns.
*
* The [DialogContext](xref:botbuilder-dialogs.DialogContext) calls this method when it continues
* the dialog.
*
* To signal to the dialog context that this dialog has completed, await
* [DialogContext.endDialog](xref:botbuilder-dialogs.DialogContext.endDialog) before exiting this method.
*
* **See also**
* - [DialogContext.continueDialog](xref:botbuilder-dialogs.DialogContext.continueDialog)
* @returns {Promise<DialogTurnResult>} A promise resolving to the dialog turn result.
*/
continueDialog(dc) {
return __awaiter(this, void 0, void 0, function* () {
// By default just end the current dialog.
return dc.endDialog();
});
}
/**
* When overridden in a derived class, resumes the dialog after the dialog above it on the stack completes.
*
* @param dc The context for the current dialog turn.
* @param reason The reason the dialog is resuming. This will typically be
* [DialogReason.endCalled](xref:botbuilder-dialogs.DialogReason.endCalled)
* @param result Optional. The return value, if any, from the dialog that ended.
*
* @remarks
* Derived dialogs that support multiple-turn conversations should override this method.
* By default, this method signals that the dialog is complete and returns.
*
* The [DialogContext](xref:botbuilder-dialogs.DialogContext) calls this method when it resumes
* the dialog. If the previous dialog on the stack returned a value, that value is in the `result`
* parameter.
*
* To start a _child_ dialog, use [DialogContext.beginDialog](xref:botbuilder-dialogs.DialogContext.beginDialog)
* or [DialogContext.prompt](xref:botbuilder-dialogs.DialogContext.prompt); however, this dialog will not
* necessarily be the one that started the child dialog.
* To signal to the dialog context that this dialog has completed, await
* [DialogContext.endDialog](xref:botbuilder-dialogs.DialogContext.endDialog) before exiting this method.
*
* **See also**
* - [DialogContext.endDialog](xref:botbuilder-dialogs.DialogContext.endDialog)
* @returns {Promise<DialogTurnResult>} A promise resolving to the dialog turn result.
*/
resumeDialog(dc, reason, result) {
return __awaiter(this, void 0, void 0, function* () {
// By default just end the current dialog and return result to parent.
return dc.endDialog(result);
});
}
/**
* When overridden in a derived class, reprompts the user for input.
*
* @param _context The context object for the turn.
* @param _instance Current state information for this dialog.
*
* @remarks
* Derived dialogs that support validation and re-prompt logic should override this method.
* By default, this method has no effect.
*
* The [DialogContext](xref:botbuilder-dialogs.DialogContext) calls this method when the current
* dialog should re-request input from the user. This method is implemented for prompt dialogs.
*
* **See also**
* - [DialogContext.repromptDialog](xref:botbuilder-dialogs.DialogContext.repromptDialog)
* - [Prompt](xref:botbuilder-dialogs.Prompt)
*/
repromptDialog(_context, _instance) {
return __awaiter(this, void 0, void 0, function* () {
// No-op by default
});
}
/**
* When overridden in a derived class, performs clean up for the dialog before it ends.
*
* @param _context The context object for the turn.
* @param _instance Current state information for this dialog.
* @param _reason The reason the dialog is ending.
*
* @remarks
* Derived dialogs that need to perform logging or cleanup before ending should override this method.
* By default, this method has no effect.
*
* The [DialogContext](xref:botbuilder-dialogs.DialogContext) calls this method when the current
* dialog is ending.
*
* **See also**
* - [DialogContext.cancelAllDialogs](xref:botbuilder-dialogs.DialogContext.cancelAllDialogs)
* - [DialogContext.endDialog](xref:botbuilder-dialogs.DialogContext.endDialog)
* - [DialogContext.replaceDialog](xref:botbuilder-dialogs.DialogContext.replaceDialog)
*/
endDialog(_context, _instance, _reason) {
return __awaiter(this, void 0, void 0, function* () {
// No-op by default
});
}
/**
* Called when an event has been raised, using `DialogContext.emitEvent()`, by either the current dialog or a dialog that the current dialog started.
*
* @param dc - The dialog context for the current turn of conversation.
* @param e - The event being raised.
* @returns True if the event is handled by the current dialog and bubbling should stop.
*/
onDialogEvent(dc, e) {
return __awaiter(this, void 0, void 0, function* () {
// Before bubble
let handled = yield this.onPreBubbleEvent(dc, e);
// Bubble as needed
if (!handled && e.bubble && dc.parent != undefined) {
handled = yield dc.parent.emitEvent(e.name, e.value, true, false);
}
// Post bubble
if (!handled) {
handled = yield this.onPostBubbleEvent(dc, e);
}
return handled;
});
}
/**
* Called before an event is bubbled to its parent.
*
* @remarks
* This is a good place to perform interception of an event as returning `true` will prevent
* any further bubbling of the event to the dialogs parents and will also prevent any child
* dialogs from performing their default processing.
* @param _dc The dialog context for the current turn of conversation.
* @param _e The event being raised.
* @returns Whether the event is handled by the current dialog and further processing should stop.
*/
onPreBubbleEvent(_dc, _e) {
return __awaiter(this, void 0, void 0, function* () {
return false;
});
}
/**
* Called after an event was bubbled to all parents and wasn't handled.
*
* @remarks
* This is a good place to perform default processing logic for an event. Returning `true` will
* prevent any processing of the event by child dialogs.
* @param _dc The dialog context for the current turn of conversation.
* @param _e The event being raised.
* @returns Whether the event is handled by the current dialog and further processing should stop.
*/
onPostBubbleEvent(_dc, _e) {
return __awaiter(this, void 0, void 0, function* () {
return false;
});
}
/**
* Called when a unique ID needs to be computed for a dialog.
*
* @remarks
* SHOULD be overridden to provide a more contextually relevant ID. The preferred pattern for
* ID's is `<dialog type>(this.hashedLabel('<dialog args>'))`.
*/
onComputeId() {
throw new Error('Dialog.onComputeId(): not implemented.');
}
}
exports.Dialog = Dialog;
/**
* Gets a default end-of-turn result.
*
* @remarks
* This result indicates that a dialog (or a logical step within a dialog) has completed
* processing for the current turn, is still active, and is waiting for more input.
*/
Dialog.EndOfTurn = { status: DialogTurnStatus.waiting };
//# sourceMappingURL=dialog.js.map
;