/**
 * This file is part of the NocoBase (R) project.
 * Copyright (c) 2020-2024 NocoBase Co., Ltd.
 * Authors: NocoBase Team.
 *
 * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
 * For more information, please refer to: https://www.nocobase.com/agreement.
 */
/// <reference types="node" />
import { Transaction, Transactionable } from '@nocobase/database';
import { Logger } from '@nocobase/logger';
import type Plugin from './Plugin';
import { IJob } from './instructions';
import type { ExecutionModel, FlowNodeModel, JobModel } from './types';
export type ProcessorRunOptions = {
    rerun?: true;
    signal?: AbortSignal;
};
export type ProcessorRerunOptions = {
    nodeId?: string | number;
    overwrite?: boolean;
};
export interface ProcessorOptions extends Transactionable {
    plugin: Plugin;
    [key: string]: any;
}
export type BackgroundAbortHandle = {
    signal: AbortSignal;
    dispose: () => void;
    throwIfAborted: () => void;
};
export type ScopeTransaction = {
    transaction: Transaction;
    dataSource: string;
    isolationLevel?: string;
    closing?: 'commit' | 'rollback';
};
export default class Processor {
    execution: ExecutionModel;
    options: ProcessorOptions;
    static StatusMap: {
        0: 0;
        1: 1;
        [-1]: -1;
        [-2]: -2;
        [-3]: -3;
        [-4]: -4;
        [-5]: -5;
        [-6]: -6;
    };
    logger: Logger;
    /**
     * @experimental
     */
    transaction?: Transaction | null;
    /**
     * @experimental
     */
    nodes: FlowNodeModel[];
    /**
     * @experimental
     */
    nodesMap: Map<string | number, FlowNodeModel>;
    private jobsMapByNodeKey;
    private jobResultsMapByNodeKey;
    private jobsToSave;
    private scopeTransactions;
    private rerunContext;
    /**
     * @experimental
     */
    lastSavedJob: JobModel | null;
    abortController: AbortController;
    timeoutGuard: NodeJS.Timeout | null;
    private runningRegistered;
    private unregisterRunningExecution?;
    private abortReason;
    private aborted;
    constructor(execution: ExecutionModel, options: ProcessorOptions);
    get abortSignal(): AbortSignal;
    setTimeoutGuard(ms: number): void;
    abortExecution(reason?: string): void;
    isTimeoutAborted(): boolean;
    /**
     * Create an independent abort handle for background work that outlives this processor's
     * run loop (e.g. fire-and-forget instructions that resume the job later). It mirrors the
     * current abort state and sets its own timer based on the execution's `expiresAt`, so the
     * timeout still applies after the processor has exited its synchronous run.
     *
     * The caller must invoke `dispose()` once the background work settles to release the timer
     * and the abort listener.
     */
    createBackgroundAbortHandle(): BackgroundAbortHandle;
    /**
     * Reload a job and return it only when it is still pending, otherwise `null`. Background
     * work uses this before resuming so it never overwrites a job that another path (timeout
     * abort, a competing resume) has already settled.
     */
    findPendingJob(jobId: number | string): Promise<JobModel | null>;
    private makeNodes;
    private makeJobs;
    prepare(): Promise<void>;
    start(): Promise<any>;
    resume(job: JobModel): Promise<void>;
    private resolveRerun;
    rerun(options?: ProcessorRerunOptions): Promise<any>;
    private getRerunNode;
    private getRerunInput;
    private exec;
    run(node: FlowNodeModel, input?: JobModel | {
        result: unknown;
    }, options?: ProcessorRunOptions): Promise<any>;
    end(node: FlowNodeModel, job: JobModel): Promise<any>;
    private recall;
    exit(s?: number | true): Promise<any>;
    setScopeTransaction(key: string, info: ScopeTransaction): void;
    getScopeTransactionByKey(key: string): ScopeTransaction;
    clearScopeTransaction(key: string): void;
    markScopeTransactionClosing(key: string, action: 'commit' | 'rollback'): void;
    getScopeTransaction(node: FlowNodeModel, dataSourceName?: string): Transaction | null;
    isInstructionSync(node: FlowNodeModel): boolean;
    private hasOpenScopeTransactions;
    private markOpenScopePendingJobsAsError;
    private cleanupScopeTransactions;
    /**
     * @experimental
     */
    saveJob(payload: JobModel | IJob): JobModel;
    /**
     * @experimental
     */
    getBranches(node: FlowNodeModel): FlowNodeModel[];
    private enterRunningState;
    private shouldContinueExecution;
    private leaveRunningState;
    /**
     * @experimental
     * find the first node in current branch
     */
    findBranchStartNode(node: FlowNodeModel, parent?: FlowNodeModel): FlowNodeModel | null;
    /**
     * @experimental
     * find the node start current branch
     */
    findBranchParentNode(node?: FlowNodeModel): FlowNodeModel | null;
    /**
     * @experimental
     */
    findBranchEndNode(node: FlowNodeModel): FlowNodeModel | null;
    /**
     * @experimental
     */
    findBranchParentJob(job: JobModel, node: FlowNodeModel): JobModel | null;
    /**
     * @experimental
     */
    findBranchLastJob(node: FlowNodeModel, job: JobModel): JobModel | null;
    /**
     * @experimental
     */
    getScope(sourceNodeId?: number | string, includeSelfScope?: boolean): {
        ctx: {
            $context: any;
            $jobsMapByNodeKey: {
                [key: string]: any;
            };
            $system: {};
            $scopes: Record<string, any>;
            $env: {};
        };
        $context: any;
        $jobsMapByNodeKey: {
            [key: string]: any;
        };
        $system: {};
        $scopes: Record<string, any>;
        $env: {};
    };
    /**
     * @experimental
     */
    getParsedValue(value: any, sourceNodeId?: number | string, { additionalScope, includeSelfScope }?: {
        additionalScope?: {};
        includeSelfScope?: boolean;
    }): any;
}
