dehub
Version:
Data&Event MessageHub.
344 lines (343 loc) • 10.2 kB
JavaScript
;
/**
* DEHub类型定义模块
* 包含了DEHub系统中使用的所有类型定义、接口和工具函数
* @module DETypes
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.DataProxy = exports.rejectedCheck = exports.sleep = exports.getDiff = exports.clearNullNodes = exports.mergeObject = exports.TagsSerializer = exports.EventStage = exports.ObjectStatus = exports.EventNames = exports.Tag = void 0;
;
/**
* 标签类
* 用于管理对象标签,提供标签比较和序列化功能
*/
class Tag {
#tag;
#path;
#keys;
constructor(tag) {
this.#tag = tag;
this.#keys = Object.keys(tag);
this.#path = exports.TagsSerializer.toPath(tag);
}
/**
* 获取标签成员
*/
get members() {
return this.#tag;
}
/**
* 获取标签路径
*/
get path() {
return this.#path;
}
/**
* 获取标签键列表
*/
get keys() {
return this.#keys;
}
/**
* 比较标签是否相等
* @param others - 要比较的标签,可以是Tag对象、ObjTag对象或字符串
* @returns 是否相等
*/
equal(others) {
const otherType = typeof others;
if (otherType === 'string') {
return others === this.#path;
}
else if (others instanceof Tag) {
return others.path === this.#path;
}
if (Object.keys(others).length !== this.#keys.length) {
return false;
}
for (const key of this.#keys) {
if (this.#tag[key] !== others[key]) {
return false;
}
}
return true;
}
toString() {
return this.#path;
}
}
exports.Tag = Tag;
/**
* 系统事件名称枚举
*/
var EventNames;
(function (EventNames) {
/** 值改变事件 */
EventNames["ValueChanged"] = "$valueChanged";
/** 状态改变事件 */
EventNames["StatusChanging"] = "$statusChanged";
/** 提交事件 */
EventNames["Submit"] = "$submit";
/** 状态改变事件 */
EventNames["StateChanging"] = "$stateChanged";
/** 组件挂载事件 */
EventNames["Mounting"] = "$mount";
/** 组件注册事件 */
EventNames["Registration"] = "$reg";
/** 组件卸载事件 */
EventNames["WillUnmount"] = "$unmount";
/** 所有组件加载完成事件 */
EventNames["ComponentsLoaded"] = "$allCmpLoaded";
/** 异常事件 */
EventNames["Exception"] = "$error";
})(EventNames = exports.EventNames || (exports.EventNames = {}));
/**
* 数据对象状态枚举
*/
var ObjectStatus;
(function (ObjectStatus) {
/** 新对象,未开始加载 */
ObjectStatus["New"] = "new";
/** 正常可用 */
ObjectStatus["Ready"] = "ready";
/** 加载中 */
ObjectStatus["Loading"] = "loading";
/** 已清空 */
ObjectStatus["Clear"] = "clear";
/** 已重置 */
ObjectStatus["Reset"] = "reset";
/** 正在上传 */
ObjectStatus["Uploading"] = "uploading";
/** 标记为删除 */
ObjectStatus["Deleting"] = "deleting";
/** 已删除 */
ObjectStatus["Deleted"] = "deleted";
/** 加载失败 */
ObjectStatus["Failed"] = "failed";
/** 加载超时 */
ObjectStatus["Timeout"] = "Timeout";
})(ObjectStatus = exports.ObjectStatus || (exports.ObjectStatus = {}));
/**
* 事件阶段枚举
*/
var EventStage;
(function (EventStage) {
/** 操作前阶段 */
EventStage["PreOperation"] = "pre";
/** 操作后阶段 */
EventStage["PostOperation"] = "post";
})(EventStage = exports.EventStage || (exports.EventStage = {}));
/**
* 标签序列化工具对象
*/
exports.TagsSerializer = {
/**
* 将标签对象转换为路径字符串
* @param tag 标签对象
* @returns 路径字符串
*/
toPath: (tag) => {
// 对象键的排序
const sortedKeys = Object.keys(tag).sort();
let queryString = '';
// 构建查询字符串
for (let key of sortedKeys) {
if (tag[key] !== undefined) {
let value = tag[key] === null ? '' : tag[key];
queryString += `${key}=${value}&`;
}
}
// 去除最后一个 '&' 符号
return queryString.slice(0, -1);
},
/**
* 获取标签及其所有子标签
* @param baseTags 基础标签
* @returns 标签路径数组
*/
selfAndChildTags: (baseTags) => {
let result = [];
const keys = Object.keys(baseTags.members);
const n = keys.length;
// 生成所有可能的组合
for (let i = 1; i < (1 << n); i++) {
let gVal = {};
for (let j = 0; j < n; j++) {
if (i & (1 << j)) {
gVal[keys[j]] = baseTags.members[keys[j]];
}
}
result.push(exports.TagsSerializer.toPath(gVal));
}
return result;
},
/**
* 从路径字符串解析标签对象
* @param path 路径字符串
* @returns 标签对象
*/
fromPath: (path) => {
const obj = {};
const paramsArr = path.split('&');
for (let param of paramsArr) {
const [key, value] = param.split('=');
obj[key] = value;
}
return obj;
}
};
/**
* 合并对象工具函数
* @param objA 基础对象
* @param objB 主要合并对象
* @param deep 是否深度合并
* @returns 合并后的对象
*/
const mergeObject = (objA, objB, deep = false) => {
if (objA === null && objB === null) {
return null;
}
if (objB === null) {
return objB;
}
if (objA == null || objB == null) {
return objB ?? objA ?? undefined;
}
if (typeof objA !== 'object' || typeof objB !== 'object') {
return objA ?? objB;
}
let mergedObj = {};
let allKeys = Array.from(new Set(Object.keys(objA).concat(Object.keys(objB))));
if (allKeys.length > 0) {
allKeys.forEach(ak => {
if (Array.isArray(objA[ak]) && !Array.isArray(objB[ak])) {
mergedObj[ak] = objA[ak];
}
else if (deep === true &&
!Array.isArray(objA[ak]) && !Array.isArray(objB[ak])
&& typeof objA[ak] === 'object' && typeof objB[ak] === 'object') {
mergedObj[ak] = (0, exports.mergeObject)(objA[ak], objB[ak], deep);
}
else {
mergedObj[ak] = objB[ak] === undefined ? objA[ak] : objB[ak];
}
});
}
else {
mergedObj = objB;
}
return mergedObj;
};
exports.mergeObject = mergeObject;
/**
* 清除对象中的空节点
* @param obj 要清理的对象
* @returns 清理后的对象
*/
const clearNullNodes = (obj) => {
if (obj != null && typeof obj === 'object') {
const nullKeys = []; // 需要删除的键的列表
for (const [okey, oval] of Object.entries(obj)) {
if (oval == null) {
nullKeys.push(okey); // 先记住要删除的键
}
else if (typeof oval === 'object') {
(0, exports.clearNullNodes)(oval);
}
}
nullKeys.forEach(key => delete obj[key]); // 删除找到的所有空键
}
return obj;
};
exports.clearNullNodes = clearNullNodes;
/**
* 获取两个对象之间的差异
* @param obj1 目标对象
* @param obj2 对比对象
* @returns 差异对象
*/
const getDiff = (obj1, obj2) => {
const updated = {};
Object.keys(obj1).forEach(key => {
if (!obj2.hasOwnProperty(key)) {
updated[key] = obj1[key];
}
else {
const value1 = obj1[key];
const value2 = obj2[key];
// 如果属性值都是对象,则递归调用 getDiff 函数
if (typeof value1 === "object" && typeof value2 === "object"
&& !Array.isArray(value1) && !Array.isArray(value2)) {
const childDiff = (0, exports.getDiff)(value1, value2);
if (Object.keys(childDiff).length > 0) {
updated[key] = childDiff;
}
}
else if (value1 !== value2) {
updated[key] = value1;
}
}
});
// 将 obj2 中 obj1 没有的属性添加到差集对象中
Object.keys(obj2).forEach(key => {
if (!obj1.hasOwnProperty(key)) {
updated[key] = undefined;
}
});
return updated;
};
exports.getDiff = getDiff;
/**
* 延时函数
* @param millisecond 延时毫秒数
* @returns Promise<void>
*/
const sleep = (millisecond) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve();
}, millisecond);
});
};
exports.sleep = sleep;
/**
* 检查Promise结果中的rejected项
* @param results Promise结果数组
* @throws 如果存在rejected的Promise
*/
const rejectedCheck = (results) => {
const rejectedItems = results.filter(r => r.status === 'rejected');
if (rejectedItems.length > 0) {
throw rejectedItems;
}
};
exports.rejectedCheck = rejectedCheck;
/**
* 创建数据对象的代理
* 提供不区分大小写的属性访问
* @param obj 要代理的对象
* @returns Proxy对象
*/
const DataProxy = (obj) => new Proxy(obj, {
get(target, property) {
const propertyStr = property.toString();
if (propertyStr in target) {
return target[propertyStr];
}
// 只有在原始属性不存在时才进行不区分大小写的查找
const mKey = Object.keys(target).find(key => key.toLowerCase() === propertyStr.toLowerCase());
return mKey ? target[mKey] : null;
},
set(target, property, value) {
const propertyStr = property.toString();
// 如果存在不区分大小写的键,则使用原始的键
const mKey = Object.keys(target).find(key => key.toLowerCase() === propertyStr.toLowerCase());
if (mKey) {
target[mKey] = value;
}
else {
target[propertyStr] = value;
}
return true;
}
});
exports.DataProxy = DataProxy;