@nocobase/flow-engine
Version:
A standalone flow engine for NocoBase, managing workflows, models, and actions.
258 lines (256 loc) • 9.38 kB
JavaScript
/**
* 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.
*/
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __typeError = (msg) => {
throw TypeError(msg);
};
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
var forkFlowModel_exports = {};
__export(forkFlowModel_exports, {
ForkFlowModel: () => ForkFlowModel
});
module.exports = __toCommonJS(forkFlowModel_exports);
var import_reactive = require("@formily/reactive");
var import_flowContext = require("../flowContext");
var import_flowEngine = require("../flowEngine");
var _flowContext;
const _ForkFlowModel = class _ForkFlowModel {
constructor(master, initialProps = {}, forkId = 0) {
/** 与 master 相同的 UID,用于日志调试 */
__publicField(this, "uid");
/** 调试标识,便于在日志或断言中快速识别 */
__publicField(this, "isFork", true);
/** 本地覆盖的 props,fork 层面的 UI/状态 */
__publicField(this, "localProps");
/** master 引用 */
__publicField(this, "master");
/** 是否已被释放 */
__publicField(this, "disposed", false);
/** fork 在 master.forks 中的索引 */
__publicField(this, "forkId");
/**
* fork 本地存储的属性,除了共享属性外的所有属性都存储在这里
* 注意:此属性通过 Proxy 在 get/set 陷阱中被动态访问,IDE 可能无法检测到使用, 切勿删除!
*/
__publicField(this, "localProperties", {});
// 不需要定义自己的属性了,现在是SHARED_PROPERTIES中指定的少数几个属性,所有属性设置时会自动添加自己的fork内的独有属性
__privateAdd(this, _flowContext);
void this.localProperties;
this.master = master;
this.uid = master.uid;
this.localProps = { ...initialProps };
this.forkId = forkId;
this.hidden = this.master.hidden;
(0, import_reactive.define)(this, {
localProps: import_reactive.observable,
hidden: import_reactive.observable,
setProps: import_reactive.action
});
return new Proxy(this, {
get: /* @__PURE__ */ __name((target, prop, receiver) => {
var _a;
if (prop === "disposed") return target.disposed;
if (prop === "constructor") {
return target.master.constructor;
}
if (prop === "props") {
return { ...target.master.getProps(), ...target.localProps };
}
if (prop in target) {
return Reflect.get(target, prop, receiver);
}
if (Object.prototype.hasOwnProperty.call(target.localProperties, prop)) {
return target.localProperties[prop];
}
const value = (_a = target.master) == null ? void 0 : _a[prop];
if (typeof value === "function") {
const masterConstructor = target.master.constructor;
return function(...args) {
const contextThis = Object.create(this);
Object.defineProperty(contextThis, "constructor", {
value: masterConstructor,
configurable: true,
enumerable: false,
writable: false
});
return value.apply(contextThis, args);
}.bind(receiver);
}
return value;
}, "get"),
set: /* @__PURE__ */ __name((target, prop, value, receiver) => {
if (prop === "props") {
return true;
}
if (prop in target) {
return Reflect.set(target, prop, value, receiver);
}
const propString = String(prop);
const isSharedProperty = _ForkFlowModel.SHARED_PROPERTIES.includes(propString);
if (isSharedProperty) {
const descriptor = this.getPropertyDescriptor(target.master, prop);
if (descriptor && descriptor.set) {
descriptor.set.call(receiver, value);
return true;
} else {
target.master[prop] = value;
return true;
}
} else {
const descriptor = this.getPropertyDescriptor(target.master, prop);
if (descriptor && descriptor.set) {
descriptor.set.call(receiver, value);
return true;
} else {
target.localProperties[prop] = value;
return true;
}
}
}, "set")
});
}
/**
* 配置需要与 master 共享的属性列表
* @param properties 共享属性名称数组
*/
static setSharedProperties(properties) {
this.SHARED_PROPERTIES = [...properties];
}
/**
* 获取当前配置的共享属性列表
*/
static getSharedProperties() {
return [...this.SHARED_PROPERTIES];
}
get context() {
if (!this["#flowContext"]) {
this["#flowContext"] = new import_flowContext.FlowForkModelContext(this.master, this);
}
return this["#flowContext"];
}
/**
* 获取对象及其原型链上的属性描述符
*/
getPropertyDescriptor(obj, prop) {
let current = obj;
while (current) {
const descriptor = Object.getOwnPropertyDescriptor(current, prop);
if (descriptor) {
return descriptor;
}
current = Object.getPrototypeOf(current);
}
return void 0;
}
/**
* 修改局部 props,仅影响当前 fork
*/
setProps(key, value) {
if (this.disposed) return;
if (typeof key === "string") {
this.localProps[key] = value;
} else {
this.localProps = { ...this.localProps, ...key };
}
}
/**
* render 依旧使用 master 的方法,但合并后的 props 需要透传
*/
render() {
if (this.disposed) return null;
const mergedProps = { ...this.master.getProps(), ...this.localProps };
const originalProps = this.props;
this.props = mergedProps;
try {
return this.master.render.call(this);
} finally {
this.props = originalProps;
}
}
/**
* 自动流程缓存的作用域标识(fork 专用)。
*/
getAutoFlowCacheScope() {
return String(this.forkId);
}
// onUnmount() {
// // 不在此处自动 dispose(避免破坏外部 fork 管理),但应透传到 master 的 onUnmount 钩子,
// // 以便用户在子类覆盖 onUnmount 时依然能在 cleanRun 场景下收到回调。
// try {
// const masterOnUnmount = (this.master as any)?.onUnmount;
// if (typeof masterOnUnmount === 'function') {
// // 使用 fork 作为 this,保持与运行/渲染一致的上下文
// return masterOnUnmount.call(this);
// }
// } catch {
// // 忽略钩子中的异常,保持卸载流程健壮
// }
// }
/**
* 释放 fork:从 master.forks 中移除自身并断开引用
*/
dispose() {
if (this.disposed) return;
this.disposed = true;
if (this.master && this.master.forks) {
const forkCacheKey = import_flowEngine.FlowEngine.generateApplyFlowCacheKey(`${this.forkId}`, "all", this.uid);
this.flowEngine.applyFlowCache.delete(forkCacheKey);
this.master.forks.delete(this);
}
if (this.master && this.master.forkCache) {
const forkCache = this.master.forkCache;
for (const [key, fork] of forkCache.entries()) {
if (fork === this) {
forkCache.delete(key);
break;
}
}
}
}
/**
* 获取合并后的 props(master + localProps,local 优先)
*/
getProps() {
return { ...this.master.getProps(), ...this.localProps };
}
/**
* 检查属性是否为共享属性
*/
isSharedProperty(prop) {
return _ForkFlowModel.SHARED_PROPERTIES.includes(prop);
}
};
_flowContext = new WeakMap();
__name(_ForkFlowModel, "ForkFlowModel");
/** 需要与 master 共享的属性列表 */
__publicField(_ForkFlowModel, "SHARED_PROPERTIES", ["stepParams", "sortIndex"]);
let ForkFlowModel = _ForkFlowModel;
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
ForkFlowModel
});