/// <reference types="node" />
import * as events from 'events';
import type Engine from '../index';
interface ResultItem {
    outputType: string;
    outputValue: Record<string, unknown>;
}
declare class QueueOutputDelegate {
    private _queue;
    constructor();
    [Symbol.asyncIterator](): AsyncIterator<ResultItem | Error>;
    next(): Promise<IteratorResult<ResultItem | Error>>;
    done(): void;
    output(outputType: string, outputValue: Record<string, unknown>): void;
    notifyError(error: Error): void;
}
interface AppMeta {
    icon?: string | null;
    conversation?: string;
    description?: string;
}
/**
 * The representation of a currently executing ThingTalk program.
 *
 * A ThingTalk program can consist of multiple commands and rules.
 * Each is mapped to a separate {@ link ExecWrapper}, but they are grouped
 * under this object.
 */
export default class AppExecutor extends events.EventEmitter {
    uniqueId: string | undefined;
    engine: Engine;
    code: string;
    icon: string | null;
    name: string;
    description: string;
    mainOutput: QueueOutputDelegate;
    private _notificationOutput;
    isRunning: boolean;
    isEnabled: boolean;
    private compiler;
    private _ast;
    private _error;
    private _meta;
    private command;
    private rules;
    private _states;
    private _finished;
    private _finishedRules;
    /**
     * Construct a new app executor.
     *
     * @param {Engine} engine - the engine that owns this app executor
     * @param {string} code - the full ThingTalk program to execute
     * @param {Object} meta - app meta information
     * @param {string} [meta.icon] - the app icon
     * @param {string} [meta.conversation] - the ID of the conversation associated with this app
     * @param {string} name - the app name
     * @param {string} description - the app description
     * @package
     */
    constructor(engine: Engine, code: string, meta: AppMeta, name: string | undefined, description: string | undefined);
    get metadata(): AppMeta;
    private _updateNameDescription;
    /**
     * The last error reported by this app.
     * @type {string}
     */
    get error(): string | null;
    setError(e: Error | null): void;
    reportError(error: Error): void;
    get hasRule(): boolean;
    /**
     * Complete abrupt termination of this app.
     *
     * This method should be called in case the user stopped the app,
     * after all commands have been stopped.
     *
     * @package
     * @async
     */
    destroy(): Promise<void>;
    /**
     * Stop and delete this app.
     * @async
     */
    removeSelf(): Promise<void>;
    /**
     * Attempt compilation of this app.
     *
     * This method must be called before running the app through {@link AppExecutor#runCommand}
     * or {@link AppExecutor#start}.
     *
     * On failure, this method will set {@link AppExecutor#error}.
     * @async
     */
    compile(): Promise<void>;
    /**
     * Execute all immediate commands in this app.
     *
     * This method will execute the portion of the app that uses the `now =>` stream.
     * It should be called only for a newly created app, not for an app that was loaded from
     * disk after a restart.
     *
     * This method must not be called on an app returned by {@link Engine#createApp} or
     * {@link AppDatabase#createApp}, as those methods will already call this one.
     */
    runCommand(): Promise<void>;
    /**
     * Await natural termination of this app.
     *
     * This method returns a promise that is fulfilled when the app terminates normally,
     * either because it has no streams and all immediate commands terminated, or because
     * all streams terminated.
     */
    waitFinished(): Promise<void>;
    private _getState;
    readState(stateId: number): any;
    writeState(stateId: number, state: unknown): any;
    /**
     * Start execution of this app in background.
     */
    start(): Promise<void>;
    /**
     * Pause execution of this app.
     *
     * This method pauses the app temporarily, and is called when the engine is terminating.
     * The app will be restarted the next time the engine is restarted. To stop the app
     * permanently, use {@link AppDatabase#removeApp} or {@link AppExecutor#removeSelf}.
     */
    stop(): Promise<void>;
}
export {};
