import { ControlResponseBuilder } from '../responseGeneration/ControlResponseBuilder'; import { SystemAct } from '../systemActs/SystemAct'; import { StringOrList } from '../utils/BasicTypes'; import { ControlInput } from './ControlInput'; import { ControlResultBuilder } from './ControlResult'; import { IControl } from './interfaces/IControl'; export declare type FunctionProp = (input: ControlInput) => T; /** * Defines the mandatory props of a Control. */ export interface ControlProps { /** * Unique identifier for the control. * * This must be unique within the scope of the entire control tree. */ id: string; } /** * Defines the mandatory state of a Control. */ export interface ControlState { /** * The value managed by a control. * * Usage: * - The value is not necessarily valid, confirmed or otherwise ready for use. Parent * controls and other consumers should `control.isReady()` to determine if the value * is ready for use. */ value: any; /** * Tracks the last initiative act from the control. */ lastInitiative: any; } export interface ControlInputHandler { name: string; canHandle: (this: Control, input: ControlInput) => boolean | Promise; handle: (this: Control, input: ControlInput, resultBuilder: ControlResultBuilder) => void | Promise; } export interface ControlInitiativeHandler { name: string; canTakeInitiative(input: ControlInput): boolean | Promise; takeInitiative(input: ControlInput, resultBuilder: ControlResultBuilder): void | Promise; } /** * Base type for the customHandling Functions of a Control */ export interface ControlInputHandlingProps { /** * Custom handling functions */ customHandlingFuncs?: ControlInputHandler[]; } /** * Abstract base class for Controls. * * Purpose: * - this class provides a simpler way to define a control than direct * implementation of IControl. Various default implementations are provided. * * Usage: * - Define new control types by sub-classing this abstract class and providing * implementations for the abstract methods. * - If the custom control will have children, sub-class `ContainerControl` * instead. */ export declare abstract class Control implements IControl { readonly id: string; state: ControlState; constructor(id: string); /** * Determines if the Control or one of its children can consume a request. * * Returning `true` does not guarantee that the Control will be selected. * * Usage: * * The handling of a request can and should be contextual. That is, a * control should only return `canHandle = true` if the request makes * sense for the current state of the control. * * * A @see ContainerControl should return true if one or more of its * children returns `canHandle = true`. Thus the root of a Control tree * should return `canHandle = true` unless the request cannot be * meaningfully consumed by any Control in the tree. * * * The implementation should be deterministic and effectively memoryless. * i.e. no state changes should be made that would be exposed by * `getSerializableState()`. * * @param input - Input object. `input.request` contains the request to be * handled. * @returns `true` if the Control or one of its children can consume the * entire request, `false` otherwise. */ abstract canHandle(input: ControlInput): boolean | Promise; /** * Handles the request. * * Handling a request involves orchestrating state changes to the Control * (and its children) and adding response items to the * `ControlResultBuilder`. * * @param input - `input.request` contains the request to be handled. * @param resultBuilder - Collect `SystemActs` that represent the system * output. */ abstract handle(input: ControlInput, resultBuilder: ControlResultBuilder): void | Promise; /** * Determines if the Control can take the initiative. * * Usage: * - A control should only return `canTakeInitiative = true` if the control, in its * current state, has something important to ask of the user. This could be a * necessary elicitation, clarification, confirmation or some other activity to * obtain and finalize the information managed by the Control. * * - A @see ContainerControl should return `true` if one of its children returns * `canTakeInitiative = true` or if the container needs to ask the user a question * directly. Thus the root of a Control tree should return `canTakeInitiative = true` * if any control in the entire tree reports `canTakeInitiative = true`. * * - The implementation should be deterministic, idempotent, and effectively * memoryless. Effectively memoryless means that any state changes are temporary and * will not be exposed in the serialized state. * * Framework behavior: * - The initiative phase runs if the handling phase did not produce a responseItem * that has `.takesInitiative = true`. * * @param input - Input object. * @returns `true` if the Control or one of its children can take the initiative, * `false` otherwise. */ abstract canTakeInitiative(input: ControlInput): boolean | Promise; /** * Takes initiative by adding an InitiativeAct to the result. * * Framework behavior: * * The initiative phase runs if the handling phase did not produce a * responseItem that has `.takesInitiative = true`. * * @param input - Input object. * @param resultBuilder - ResultBuilder. Collect `SystemActs` that represent * the system output. */ abstract takeInitiative(input: ControlInput, resultBuilder: ControlResultBuilder): void | Promise; /** * Determines if the Control's value is ready for use by other parts of the skill. * * Note: * - A basic invariant is `isReady === !canTakeInitiative` because `isReady` implies * that no further discussion is required and thus there is no need to take the * initiative. * * @param input - Input object. * @returns `true` if the control has no further questions to ask the user such as * elicitation, clarification or confirmation. */ isReady(input: ControlInput): Promise; /** * Reestablishes the state of the control. * * Default implementations: * - `Control`: reestablishes the state via * `this.setSerializableState(state)`. * - `ContainerControl`: reestablishes the `state` and recursively * reestablishes state for all children. * - `DynamicContainerControl`: reestablishes the `state`, rebuilds any * dynamic child controls, and recursively reestablishes state for all * children. */ reestablishState(state: any, controlStateMap: { [index: string]: any; }): void; /** * Gets the Control's state as an object that is serializable. * * Only durable state should be included and the object should be * serializable with a straightforward application of * `JSON.stringify(object)`. * * Default: `{return this.state;}` * * Usage: * * This method must be idempotent (multiple calls must not change the * result). * * The default is sufficient for Controls that use the `.state` variable * and only store simple data. * * Non-simple data includes functions, and objects with functions, as * these will not survive the round trip. * * Other non-simple data include types with non-enumerable properties. * * It is safe to pass the actual state object as the framework guarantees * to not mutate it. * * Functions that operate on the Control's state should be defined as * member function of the Control type, or as props. * * Framework behavior: * * During the shutdown phase the state of the control tree is collected * by calling this function for each control. * * The framework serializes the data use a simple application of * `JSON.stringify`. * * On the subsequent turn the control tree is rebuilt and the state * objects are re-attached to each Control via * `control.setSerializableState(serializedState)`. * * @returns Serializable object defining the state of the Control */ getSerializableState(): any; /** * Sets the state from a serialized state object. * * Default: `{this.state = serializedState;}` * * Usage: * * This method must be idempotent (multiple calls must not change the * result). * * It is safe to use serializedState without copying as the framework * guarantees to not mutate it. * * Framework behavior: * * During the initialization phase the control tree is rebuilt and state * objects are re-attached to controls by calling this method for each * control. * * @param serializedState - Serializable object defining the state of the * Control */ setSerializableState(serializedState: any): void; /** * Add response content for a system act produced by this control. * * This is intended to be used with the default ControlManager.render() * which implements a simple concatenation strategy to form a complete * response from multiple result items. * * @param act - System act * @param input - Input * @param responseBuilder - Response builder */ renderAct(act: SystemAct, input: ControlInput, responseBuilder: ControlResponseBuilder): Promise; /** * Add response APL component by this control. * * This is intended to be used to provide APL rendering component for a control to process * inputs, provide feedback, elicitation etc through touch events on APL screens. * * @param input - Input * @param responseBuilder - Response builder */ renderAPLComponent(input: ControlInput, responseBuilder: ControlResponseBuilder): Promise<{ [key: string]: any; }>; throwUnhandledActError(act: SystemAct): never; /** * Evaluate a prompt prop. * * @param act - act * @param propValue - Constant or function producing String or * List-of-Strings * @param input - Input object */ evaluatePromptProp(act: SystemAct, propValue: StringOrList | ((act: any, input: ControlInput) => string | string[]), input: ControlInput): string; /** * Evaluate a boolean prop. * * @param propValue - Constant or function producing boolean * @param input - The input object */ evaluateBooleanProp(propValue: boolean | ((input: ControlInput) => boolean), input: ControlInput): boolean; /** * Evaluate an APL document/data source prop. * * @param act - act * @param input - The input object * @param propValue - Constant or function producing a map of key:value pairs */ evaluateAPLProp(act: SystemAct, input: ControlInput, propValue: { [key: string]: any; } | ((act: SystemAct, state: ControlState) => { [key: string]: any; })): { [key: string]: any; }; evaluateFunctionProp(prop: T | ((input: ControlInput) => T), input: ControlInput): T; } //# sourceMappingURL=Control.d.ts.map