botbuilder-dialogs-adaptive
Version:
Rule system for the Microsoft BotBuilder dialog system.
118 lines (107 loc) • 4.02 kB
text/typescript
/**
* @module botbuilder-dialogs-adaptive
*/
/**
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
import { DialogContext, DialogSet, DialogState } from 'botbuilder-dialogs';
import { ActionState } from './actionState';
import { ActionChangeList } from './actionChangeList';
import { ActionChangeType } from './actionChangeType';
/**
* Extends the [DialogContext](xref:botbuilder-dialogs.DialogContext) with additional methods for manipulating the
* executing sequence of actions for an [AdaptiveDialog](xref:botbuilder-dialogs-adaptive.AdaptiveDialog).
*/
export class ActionContext extends DialogContext {
private readonly _changeKey: symbol;
/**
* Initializes a new instance of the [ActionContext](xref:botbuilder-dialogs-adaptive.ActionContext) class
*
* @param dialogs The dialog set to create the action context for.
* @param parentDialogContext Parent dialog context.
* @param state Current dialog state.
* @param actions Current list of remaining actions to execute.
* @param changeKey TurnState key for where to persist any changes.
*/
constructor(
dialogs: DialogSet,
parentDialogContext: DialogContext,
state: DialogState,
actions: ActionState[],
changeKey: symbol,
) {
super(dialogs, parentDialogContext, state);
this.actions = actions;
this._changeKey = changeKey;
}
/**
* List of actions being executed.
*/
actions: ActionState[];
/**
* Gets list of changes that are queued to be applied.
*
* @returns The list of changes queued.
*/
get changes(): ActionChangeList[] {
return this.context.turnState.get(this._changeKey) || [];
}
/**
* Queues up a set of changes that will be applied when applyChanges() is called.
*
* @param changes Plan changes to queue up.
*/
queueChanges(changes: ActionChangeList): void {
const queue = this.changes;
queue.push(changes);
this.context.turnState.set(this._changeKey, queue);
}
/**
* Applies any queued up changes.
*
* @returns True if there were any changes to apply.
*/
async applyChanges(): Promise<boolean> {
// Retrieve queued change list
const changes = this.changes;
if (changes.length > 0) {
// Clear current change list
this.context.turnState.delete(this._changeKey);
// Apply each queued set of changes
for (let i = 0; i < changes.length; i++) {
const change = changes[i];
// Apply memory changes to turn state
if (change.turn) {
for (const key in change.turn) {
this.state.setValue(`turn.${key}`, change.turn[key]);
}
}
// Update sequence
switch (change.changeType) {
case ActionChangeType.insertActions:
this.actions.unshift(...change.actions);
break;
case ActionChangeType.appendActions:
this.actions.push(...change.actions);
break;
case ActionChangeType.endSequence:
if (this.actions.length > 0) {
this.actions.splice(0, this.actions.length);
}
break;
case ActionChangeType.replaceSequence:
if (this.actions.length > 0) {
this.actions.splice(0, this.actions.length);
}
this.actions.push(...change.actions);
break;
}
}
// Apply any queued up changes
await this.applyChanges();
return true;
}
return false;
}
}