@nocobase/flow-engine
Version:
A standalone flow engine for NocoBase, managing workflows, models, and actions.
345 lines (344 loc) • 16.3 kB
TypeScript
/**
* 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.
*/
import React from 'react';
import { Emitter } from '../emitter';
import { InstanceFlowRegistry } from '../flow-registry/InstanceFlowRegistry';
import { FlowContext, FlowModelContext, FlowRuntimeContext } from '../flowContext';
import { FlowEngine } from '../flowEngine';
import type { ActionDefinition, ArrayElementType, CreateModelOptions, CreateSubModelOptions, DefaultStructure, FlowDefinitionOptions, FlowModelMeta, FlowModelOptions, ModelConstructor, ParamObject, ParentFlowModel, PersistOptions, StepParams } from '../types';
import { IModelComponentProps, ReadonlyModelProps } from '../types';
import { ModelActionRegistry } from '../action-registry/ModelActionRegistry';
import { ModelEventRegistry } from '../event-registry/ModelEventRegistry';
import { GlobalFlowRegistry } from '../flow-registry/GlobalFlowRegistry';
import { FlowDefinition } from '../FlowDefinition';
import { FlowSettingsOpenOptions } from '../flowSettings';
import type { EventDefinition } from '../types';
import { ForkFlowModel } from './forkFlowModel';
export declare enum ModelRenderMode {
ReactElement = "reactElement",
RenderFunction = "renderFunction"
}
export declare class FlowModel<Structure extends DefaultStructure = DefaultStructure> {
#private;
/**
* 当 flowSettings.enabled 且 model.hidden 为 true 时用于渲染设置态组件(实例方法,子类可覆盖)。
* 基类默认仅返回一个透明度降低的占位元素
*/
protected renderHiddenInConfig(): React.ReactNode | undefined;
readonly uid: string;
sortIndex: number;
hidden: boolean;
props: IModelComponentProps;
stepParams: StepParams;
flowEngine: FlowEngine;
parent: ParentFlowModel<Structure>;
subModels: Structure['subModels'];
private _options;
protected _title: string;
isNew: boolean;
/**
* 所有 fork 实例的引用集合。
* 使用 Set 便于在销毁时主动遍历并调用 dispose,避免悬挂引用。
*/
forks: Set<ForkFlowModel<any>>;
emitter: Emitter;
/**
* 基于 key 的 fork 实例缓存,用于复用 fork 实例
*/
private forkCache;
/**
* 上一次 applyAutoFlows 的执行参数
*/
private _lastAutoRunParams;
protected observerDispose: () => void;
/**
* 原始 render 方法的引用
*/
private _originalRender;
/**
* 缓存的响应式包装器组件(每个实例一个)
*/
private _reactiveWrapperCache?;
flowRegistry: InstanceFlowRegistry;
private _cleanRun?;
/**
* 声明渲染模式:
* - 'renderElement': render 返回 React 节点,框架会用 observer 包装以获得响应式;
* - 'renderFunction': render 返回渲染函数(例如表格单元格渲染器),不做包装也不预调用;
*/
static renderMode: ModelRenderMode;
constructor(options: FlowModelOptions<Structure>);
/**
* 对外暴露的上下文:
*/
get context(): FlowModelContext;
on(eventName: string, listener: (...args: any[]) => void): void;
onInit(options: any): void;
/**
* 通过 AddSubModelButton 添加为子模型后调用(子类可覆盖)
*/
afterAddAsSubModel(): Promise<void>;
get async(): boolean;
get use(): string;
get subKey(): string;
get subType(): "object" | "array";
get reactView(): import("../ReactView").ReactView;
get parentId(): string;
static get meta(): FlowModelMeta;
static get globalFlowRegistry(): GlobalFlowRegistry;
protected static get actionRegistry(): ModelActionRegistry;
protected static get eventRegistry(): ModelEventRegistry;
/**
* 注册仅当前 FlowModel 类及其子类可用的 Action。
* 该注册是类级别的,不会影响全局(FlowEngine)的 Action 注册。
*/
static registerAction<TModel extends FlowModel = FlowModel>(definition: ActionDefinition<TModel>): void;
/**
* 批量注册仅当前 FlowModel 类及其子类可用的 Actions。
*/
static registerActions<TModel extends FlowModel = FlowModel>(actions: Record<string, ActionDefinition<TModel>>): void;
/**
* 注册仅当前 FlowModel 类及其子类可用的 Event。
* 该注册是类级别的,不会影响全局(FlowEngine)的 Event 注册。
*/
static registerEvent<TModel extends FlowModel = FlowModel>(definition: EventDefinition<TModel>): void;
/**
* 批量注册仅当前 FlowModel 类及其子类可用的 Events。
*/
static registerEvents<TModel extends FlowModel = FlowModel>(events: Record<string, EventDefinition<TModel>>): void;
static buildChildrenFromModels(ctx: any, Models: Array<any>): import("..").SubModelItem[];
get title(): any;
setTitle(value: string): void;
setHidden(value: boolean): void;
_createSubModels(subModels: Record<string, CreateSubModelOptions | CreateSubModelOptions[]>): void;
invalidateAutoFlowCache(deep?: boolean): void;
/**
* 设置FlowEngine实例
* @param {FlowEngine} flowEngine FlowEngine实例
*/
setFlowEngine(flowEngine: FlowEngine): void;
static define(meta: FlowModelMeta): void;
/**
* 注册一个 Flow。
* @template TModel 具体的FlowModel子类类型
* @param {string | FlowDefinitionOptions<TModel>} keyOrDefinition 流程的 Key 或 FlowDefinitionOptions 对象。
* 如果为字符串,则为流程 Key,需要配合 flowDefinition 参数。
* 如果为对象,则为包含 key 属性的完整 FlowDefinitionOptions。
* @param {FlowDefinitionOptions<TModel>} [flowDefinition] 当第一个参数为流程 Key 时,此参数为流程的定义。
* @returns {void}
*/
static registerFlow<TClass extends ModelConstructor, TModel extends InstanceType<TClass> = InstanceType<TClass>>(this: TClass, keyOrDefinition: string | FlowDefinitionOptions<TModel>, flowDefinition?: Omit<FlowDefinitionOptions<TModel>, 'key'> & {
key?: string;
}): void;
/**
* 获取已注册的流程定义。
* 如果当前类不存在对应的flow,会继续往父类查找。
* @param {string} key 流程 Key。
* @returns {FlowDefinition | undefined} 流程定义,如果未找到则返回 undefined。
*/
getFlow(key: string): FlowDefinition | undefined;
/**
* 注册一个实例级别的流程定义。
* @template TModel 具体的FlowModel子类类型
* @param {string | FlowDefinitionOptions<TModel>} keyOrDefinition 流程的 Key 或 FlowDefinitionOptions 对象。
* @param {FlowDefinitionOptions<TModel>} [flowDefinition] 当第一个参数为流程 Key 时,此参数为流程的定义。
* @returns {FlowDefinition} 注册的流程定义实例
*/
registerFlow<TModel extends FlowModel = this>(keyOrDefinition: string | FlowDefinitionOptions<TModel>, flowDefinition?: Omit<FlowDefinitionOptions<TModel>, 'key'> & {
key?: string;
}): FlowDefinition;
/**
* 获取当前模型可用的所有 Actions:
* - 包含全局(FlowEngine)注册的 Actions;
* - 合并类级(FlowModel.registerAction(s))注册的 Actions,并考虑继承(子类覆盖父类同名 Action)。
*/
getActions<TModel extends FlowModel = this, TCtx extends FlowContext = FlowRuntimeContext<TModel>>(): Map<string, ActionDefinition<TModel, TCtx>>;
/**
* 获取当前模型可用的所有 Events:
* - 包含全局(FlowEngine)注册的 Events;
* - 合并类级(FlowModel.registerEvent(s))注册的 Events,并考虑继承(子类覆盖父类同名 Event)。
*/
getEvents<TModel extends FlowModel = this>(): Map<string, EventDefinition<TModel>>;
/**
* 获取指定名称的 Event(优先返回类级注册的,未找到则回退到全局)。
*/
getEvent<TModel extends FlowModel = this>(name: string): EventDefinition<TModel> | undefined;
/**
* 获取指定名称的 Action(优先返回类级注册的,未找到则回退到全局)。
*/
getAction<TModel extends FlowModel = this, TCtx extends FlowContext = FlowRuntimeContext<TModel>>(name: string): ActionDefinition<TModel, TCtx> | undefined;
getFlows(): Map<string, FlowDefinition>;
setProps(props: IModelComponentProps): void;
setProps(key: string, value: any): void;
getProps(): ReadonlyModelProps;
setStepParams(flowKey: string, stepKey: string, params: ParamObject): void;
setStepParams(flowKey: string, stepParams: Record<string, ParamObject>): void;
setStepParams(allParams: StepParams): void;
getStepParams(flowKey: string, stepKey: string): any | undefined;
getStepParams(flowKey: string): Record<string, any> | undefined;
getStepParams(): StepParams;
applyFlow(flowKey: string, inputArgs?: Record<string, any>, runId?: string): Promise<any>;
private _dispatchEvent;
private _dispatchEventWithDebounce;
dispatchEvent(eventName: string, inputArgs?: Record<string, any>, options?: {
/**
* 是否要开启防抖功能
*/
debounce: boolean;
}): Promise<void>;
/**
* 获取所有自动应用流程定义(保持 getFlows 的顺序,即按 sort 排序)
* @returns {FlowDefinition[]} 自动应用流程定义数组(已按 sort 排序)
*/
getAutoFlows(): FlowDefinition[];
/**
* 重新执行上一次的 applyAutoFlows,保持参数一致
* 如果之前没有执行过,则直接跳过
* 使用 lodash debounce 避免频繁调用
*/
private _rerunLastAutoRun;
/**
* 自动流程执行前钩子。
* 子类可覆盖;可抛出 FlowExitException 提前终止。
*/
onBeforeAutoFlows(inputArgs?: Record<string, any>): Promise<void>;
/**
* 自动流程执行后钩子。
* 子类可覆盖。
*/
onAfterAutoFlows(results: any[], inputArgs?: Record<string, any>): Promise<void>;
/**
* 自动流程错误钩子。
* 子类可覆盖。
*/
onAutoFlowsError(error: Error, inputArgs?: Record<string, any>): Promise<void>;
useHooksBeforeRender(): void;
/**
* 执行所有自动应用流程
* @param {Record<string, any>} [inputArgs] 可选的运行时参数
* @param {boolean} [useCache=true] 是否使用缓存机制,默认为 true
* @returns {Promise<any[]>} 所有自动应用流程的执行结果数组
*/
applyAutoFlows(inputArgs?: Record<string, any>, useCache?: boolean): Promise<any[]>;
/**
* 智能检测是否应该跳过响应式包装
* 说明:
* - 仅基于标记判断,不会执行 render,避免出现“预调用 render”带来的副作用和双调用问题。
* - 当子类需要返回函数(如表格列的单元格渲染器),应在子类上设置静态属性 `renderReturnsFunction = true`。
*/
private shouldSkipReactiveWrapping;
/**
* 设置 render 方法的响应式包装
* @private
*/
private setupReactiveRender;
get cleanRun(): boolean;
setCleanRun(value: boolean): void;
/**
* 组件挂载时的生命周期钩子
* 子类可以重写此方法来添加挂载时的逻辑
* @protected
*/
protected onMount(): void;
/**
* 组件卸载时的生命周期钩子
* 子类可以重写此方法来添加卸载时的逻辑
* @protected
*/
protected onUnmount(): void;
/**
* 有权限时的渲染逻辑。
* 这是一个抽象方法,所有子类都必须实现,用于返回自己的正常 UI。
*
* @returns {React.ReactNode} 有权限时的渲染结果
*/
render(): any;
rerender(): Promise<void>;
/**
* 自动流程缓存的作用域标识;fork 实例可覆盖以区分缓存。
*/
getAutoFlowCacheScope(): string;
setParent(parent: FlowModel): void;
removeParentDelegate(): void;
addSubModel<T extends FlowModel>(subKey: string, options: CreateModelOptions | T): T;
setSubModel(subKey: string, options: CreateModelOptions | FlowModel): FlowModel<DefaultStructure>;
filterSubModels<K extends keyof Structure['subModels'], R>(subKey: K, callback: (model: ArrayElementType<Structure['subModels'][K]>, index: number) => boolean): ArrayElementType<Structure['subModels'][K]>[];
mapSubModels<K extends keyof Structure['subModels'], R>(subKey: K, callback: (model: ArrayElementType<Structure['subModels'][K]>, index: number) => R): R[];
hasSubModel<K extends keyof Structure['subModels']>(subKey: K): boolean;
findSubModel<K extends keyof Structure['subModels'], R>(subKey: K, callback: (model: ArrayElementType<Structure['subModels'][K]>) => R): ArrayElementType<Structure['subModels'][K]> | null;
createRootModel(options: any): FlowModel<DefaultStructure>;
applySubModelsAutoFlows<K extends keyof Structure['subModels']>(subKey: K, inputArgs?: Record<string, any>, shared?: Record<string, any>): Promise<void>;
/**
* 创建一个 fork 实例,实现"一份数据(master)多视图(fork)"的能力。
* @param {IModelComponentProps} [localProps={}] fork 专属的局部 props,优先级高于 master.props
* @param {string} [key] 可选的 key,用于复用 fork 实例。如果提供了 key,会尝试复用已存在的 fork
* @returns {ForkFlowModel<this>} 创建的 fork 实例
*/
createFork(localProps?: IModelComponentProps, key?: string, options?: {
sharedProperties?: string[];
register?: boolean;
}): ForkFlowModel<this>;
clearForks(): void;
getFork(key: string): ForkFlowModel<any>;
/**
* 移动当前模型到目标模型的位置
* @param {FlowModel} targetModel 目标模型
* @param {PersistOptions} [options] 可选的持久化选项
* @returns {boolean} 是否成功移动
*/
moveTo(targetModel: FlowModel, options?: PersistOptions): Promise<void>;
remove(): boolean;
save(): Promise<any>;
saveStepParams(): Promise<any>;
destroy(): Promise<boolean>;
/**
* @deprecated
* 打开步骤设置对话框
* 用于配置流程中特定步骤的参数和设置
* @param {string} flowKey 流程的唯一标识符
* @param {string} stepKey 步骤的唯一标识符
* @returns {void}
*/
openStepSettingsDialog(flowKey: string, stepKey: string): Promise<any>;
/**
* 配置必填步骤参数
* 用于在一个分步表单中配置所有需要参数的步骤
* @param {number | string} [dialogWidth=800] 对话框宽度,默认为800
* @param {string} [dialogTitle='步骤参数配置'] 对话框标题,默认为'步骤参数配置'
* @returns {Promise<any>} 返回表单提交的值
*/
configureRequiredSteps(dialogWidth?: number | string, dialogTitle?: string): Promise<any>;
/**
* @deprecated
* @param dialogWidth
* @param dialogTitle
* @returns
*/
openPresetStepSettingsDialog(dialogWidth?: number | string, dialogTitle?: string): Promise<any>;
openFlowStepSettingsDialog(options: {
flowKey?: string;
stepKey?: string;
preset?: boolean;
uiMode?: 'drawer' | 'dialog';
}): Promise<void>;
get translate(): any;
serialize(): Record<string, any>;
/**
* Opens the flow settings dialog for this flow model.
* @param options - Configuration options for opening flow settings, excluding the model property
* @returns A promise that resolves when the flow settings dialog is opened
*/
openFlowSettings(options?: Omit<FlowSettingsOpenOptions, 'model'>): Promise<boolean>;
}
export declare class ErrorFlowModel extends FlowModel {
errorMessage: string;
setErrorMessage(msg: string): void;
render(): React.JSX.Element;
}
export declare function defineFlow<TModel extends FlowModel = FlowModel>(definition: FlowDefinitionOptions): FlowDefinitionOptions<TModel>;