UNPKG

botbuilder-dialogs-adaptive

Version:

Rule system for the Microsoft BotBuilder dialog system.

186 lines • 7.67 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.OnCondition = void 0; const actionChangeType_1 = require("../actionChangeType"); const actionScope_1 = require("../actions/actionScope"); const adaptiveDialog_1 = require("../adaptiveDialog"); const converters_1 = require("../converters"); const adaptive_expressions_1 = require("adaptive-expressions"); const botbuilder_dialogs_1 = require("botbuilder-dialogs"); /** * Actions triggered when condition is true. */ class OnCondition extends botbuilder_dialogs_1.Configurable { /** * @protected * Gets the action scope. * * @returns The scope obtained from the action. */ get actionScope() { if (!this._actionScope) { this._actionScope = new actionScope_1.ActionScope(this.actions); } return this._actionScope; } /** * Create a new `OnCondition` instance. * * @param condition (Optional) The condition which needs to be met for the actions to be executed. * @param actions (Optional) The actions to add to the plan when the rule constraints are met. */ constructor(condition, actions = []) { super(); this._extraConstraints = []; /** * Gets or sets the actions to add to the plan when the rule constraints are met. */ this.actions = []; /** * Get or sets the rule priority expression where 0 is the highest and less than 0 is ignored. */ this.priority = new adaptive_expressions_1.NumberExpression(0.0); this.condition = condition ? new adaptive_expressions_1.BoolExpression(condition) : undefined; this.actions = actions; } /** * @param property The key of the conditional selector configuration. * @returns The converter for the selector configuration. */ getConverter(property) { switch (property) { case 'condition': return new adaptive_expressions_1.BoolExpressionConverter(); case 'actions': return converters_1.DialogListConverter; case 'priority': return new adaptive_expressions_1.NumberExpressionConverter(); default: return super.getConverter(property); } } /** * Get the cached expression for this condition. * * @returns Cached expression used to evaluate this condition. */ getExpression() { if (!this._fullConstraint) { this._fullConstraint = this.createExpression(); } return this._fullConstraint; } /** * Compute the current value of the priority expression and return it. * * @param actionContext Context to use for evaluation. * @returns Computed priority. */ currentPriority(actionContext) { const { value: priority, error } = this.priority.tryGetValue(actionContext.state); if (error) { return -1; } return priority; } /** * Add external condition to the OnCondition * * @param condition External constraint to add, it will be AND'ed to all other constraints. */ addExternalCondition(condition) { if (condition) { try { const parser = new adaptive_expressions_1.ExpressionParser(); this._extraConstraints.push(parser.parse(condition)); this._fullConstraint = undefined; } catch (err) { throw Error(`Invalid constraint expression: ${condition}, ${err.toString()}`); } } } /** * Method called to execute the condition's actions. * * @param actionContext Context. * @returns A promise with plan change list. */ execute(actionContext) { return __awaiter(this, void 0, void 0, function* () { if (this.runOnce) { const count = actionContext.state.getValue(botbuilder_dialogs_1.DialogPath.eventCounter); actionContext.state.setValue(`${adaptiveDialog_1.AdaptiveDialog.conditionTracker}.${this.id}.lastRun`, count); } return [this.onCreateChangeList(actionContext)]; }); } /** * Get child dialog dependencies so they can be added to the containers dialogset. * * @returns A list of [Dialog](xref:botbuilder-dialogs.Dialog). */ getDependencies() { return [this.actionScope]; } /** * Create the expression for this condition. * * @returns {Expression} Expression used to evaluate this rule. */ createExpression() { var _a; const allExpressions = []; if (this.condition) { allExpressions.push(this.condition.toExpression()); } if ((_a = this._extraConstraints) === null || _a === void 0 ? void 0 : _a.length) { allExpressions.push(...this._extraConstraints); } if (this.runOnce) { const evaluator = new adaptive_expressions_1.ExpressionEvaluator(`runOnce${this.id}`, (_expression, state, _) => { const basePath = `${adaptiveDialog_1.AdaptiveDialog.conditionTracker}.${this.id}.`; const lastRun = state.getValue(basePath + 'lastRun'); const paths = state.getValue(basePath + 'paths'); const changed = state.anyPathChanged(lastRun, paths); return { value: changed, error: undefined }; }, adaptive_expressions_1.ReturnType.Boolean, adaptive_expressions_1.FunctionUtils.validateUnary); allExpressions.push(new adaptive_expressions_1.Expression(adaptive_expressions_1.ExpressionType.Ignore, adaptive_expressions_1.Expression.lookup(adaptive_expressions_1.ExpressionType.Ignore), new adaptive_expressions_1.Expression(evaluator.type, evaluator))); } if (allExpressions.length) { return adaptive_expressions_1.Expression.andExpression(...allExpressions); } return new adaptive_expressions_1.Constant(true); } /** * @protected * Called when a change list is created. * @param actionContext [ActionContext](xref:botbuilder-dialogs-adaptive.ActionContext) to use for evaluation. * @param dialogOptions Optional. Object with dialog options. * @returns An [ActionChangeList](xref:botbuilder-dialogs-adaptive.ActionChangeList) with the list of actions. */ onCreateChangeList(actionContext, dialogOptions) { const actionState = { dialogId: this.actionScope.id, options: dialogOptions, dialogStack: [], }; const changeList = { changeType: actionChangeType_1.ActionChangeType.insertActions, actions: [actionState], }; return changeList; } } exports.OnCondition = OnCondition; OnCondition.$kind = 'Microsoft.OnCondition'; //# sourceMappingURL=onCondition.js.map