UNPKG

botbuilder-dialogs

Version:

A dialog stack based conversation manager for Microsoft BotBuilder.

348 lines 14.4 kB
"use strict"; 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