{"version":3,"sources":["../src/object/mixinObject.ts"],"names":["syncObjectProperty","key","target","source","conflict","conflictValue","isPlainObject","isPropertyMethod","targetFunc","sourceFunc","isAsyncFunction","args","desc","mixinObject","options","excludes","injectStatic","isClass"],"mappings":"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","file":"chunk-R6H6EHUW.mjs","sourcesContent":["/**\r\n * \r\n * 在混入对象\r\n * \r\n */\r\n\r\nimport { isPropertyMethod } from \"../classs/isPropertyMethod\"\r\nimport { isAsyncFunction } from \"../typecheck/isAsyncFunction\"\r\nimport { isClass } from \"../typecheck/isClass\"\r\nimport { isPlainObject } from \"../typecheck/isPlainObject\"\r\n\r\n\r\n\r\n// 冲突策略\r\nexport type ConflictStrategy ='ignore' | 'replace' | 'merge' | 'error' | ((key:string, target:object, source:object)=>'ignore' | 'replace' | 'merge' | 'error' | undefined)\r\n\r\nexport interface MixinObjectOptions{\r\n    excludes?: string[]                                             // 排除的字段名称列表\r\n    injectStatic?:boolean                                           // 是否注入静态变量,当source是一个类时,确认如何处理静态变量\r\n    conflict?: ConflictStrategy                                     // 冲突处理策略\r\n}\r\n\r\n/**\r\n * \r\n * 同步两个对象的成员值，\r\n * \r\n * 将source成员同步到target中\r\n * \r\n * 按一定的策略对指定的字段进行混入同步处理\r\n * \r\n * -  \r\n * @param {*} key \r\n * @param {*} target \r\n * @param {*} source \r\n * @param {*} param3 \r\n * @returns \r\n */\r\n function syncObjectProperty(key:string, target:any, source:any, { conflict }:{conflict:ConflictStrategy}) {\r\n    if (key in target) {\r\n        const conflictValue = (typeof (conflict) == \"function\" ? conflict(key,target,source) : conflict) || 'ignore'\r\n\r\n        if (conflictValue === 'ignore') {                                      // 跳过\r\n            return\r\n        } else if (conflictValue === 'replace') {                               // 替换\r\n            Object.defineProperty(target, key,Object.getOwnPropertyDescriptor(source, key) as any) \r\n        } else if (conflictValue === 'merge') {                               // 合并\r\n            if (isPlainObject(target[key]) && isPlainObject(source[key])) {         // 数组合并\r\n                target[key] = { ...target[key], ...source[key] }\r\n            } else if (Array.isArray(target[key]) && Array.isArray(source[key])) {  // 对象合并\r\n                target[key] = [...new Set([...target[key], ...source[key]])]\r\n            } else if (isPropertyMethod(target, key) && isPropertyMethod(source, key)) { // 属性替换\r\n                Object.defineProperty(target, key,Object.getOwnPropertyDescriptor(source, key) as any)\r\n            } else if (typeof (target[key]) === \"function\" && typeof (source[key]) === \"function\") {  \r\n                // 将两个冲突的函数合并在一起，使两个函数均可以得到执行                \r\n                let targetFunc = target[key], sourceFunc = source[key]\r\n                if(isAsyncFunction(targetFunc) && isAsyncFunction(sourceFunc)){\r\n                    target[key] = async function () {\r\n                        return await Promise.all([targetFunc.call(this, ...arguments), sourceFunc.call(this, ...arguments)])\r\n                    }\r\n                }else{\r\n                    target[key] = function (...args:any[]) {\r\n                        return  Promise.allSettled([\r\n                            ()=>targetFunc.apply(this, args),\r\n                            ()=>sourceFunc.apply(this, args)\r\n                        ]) \r\n                    }\r\n                }                \r\n            }\r\n        }else if (conflictValue === 'error') { \r\n            throw new Error(`Mixin ${String(source)}.${key} to ${String(target)}.${key} conflict`)\r\n        }       \r\n    } else {\r\n        let desc = Object.getOwnPropertyDescriptor(source, key) || Object.getOwnPropertyDescriptor(source.prototype, key)\r\n        if (desc && !(key in target)) {\r\n            Object.defineProperty(target, key, desc)\r\n        }\r\n    }\r\n}\r\n\r\n\r\n\r\n\r\n/**\r\n * \r\n *   本方法可以用来为类或实例混入属性/方法等\r\n *   将source混入到target *  \r\n * \r\n * @param {Object} target        目标对象\r\n * @param {Object} source        将source混入到target\r\n * @param {Array } excludes      排除的字段名称列表\r\n * @param {Boolean} injectStatic  是否注入静态变量,当source是一个类时,确认如何处理静态变量\r\n *                   如果target和source均是一个类，则source的静态属性也混入到target的构造中\r\n *                  如果target是一个实例，则source的静态属性应该混入到哪里比较合理？\r\n *                      - 如果混入到target.construct，则会影响到target类的所有实例，明显是比较不合理的,会对其他实例产生不可预知的影响，因此默认将不会混入\r\n *                      - 但是如果target是一个单例，则混入不会产生重大影响\r\n *              因此通过一个参数injectStatic来配置当target是一个实例时是否将静态属性混入到其构造中，一般仅仅在target是一个单例时使用\r\n *              当injectStatic=true时,会将source的静态属性和方法均混入到target.construct\r\n *  \r\n * @param {*} conflict      冲突处理策略\r\n *      0：忽略,即不进行混入         \r\n *      1：替换，用source中的字段替换target中的\r\n *      2：合并，按一定策略进行合并\r\n *           - 如果两者均是{}，则进行深度合并\r\n *           - 如果两者均是[]，则进行合并去重\r\n *           - 如果两者均是类属性，则采用替换方式\r\n *           - 如果两者均是函数，则生成一个()=>Promise.all([source fn],[target fn])的函数，即会同时执行这两个函数并返回结果集\r\n *      3: 出错,直接抛出错误导致混入过程中断\r\n *      Function：自定义混入策略, 调用(key,target,source)返回合并后的结果\r\n *                 conflict(key,target,source){\r\n *                      - 定义新的属性： Object.defineProperty(target, key,descript)\r\n *                      - 返回默认的冲空处理策略： return <0|1|2|3>\r\n *                 }\r\n *       4. \r\n *                                         \r\n * \r\n */\r\n\r\n\r\n export function mixinObject(target:any, source:any,  options?:MixinObjectOptions) {\r\n    const { excludes = [], conflict = 'merge',injectStatic=false }  = Object.assign({},options) as Required<MixinObjectOptions>\r\n    excludes.push(...['constructor', 'prototype', 'name', 'length'])\r\n    for (let key of Reflect.ownKeys(source)) {\r\n        if (excludes.includes(String(key))) continue\r\n        syncObjectProperty(String(key), target, source, { conflict})\r\n    }\r\n    if (source.constructor && source.constructor !== Object) {\r\n        for (let key of Reflect.ownKeys(source.constructor)) {\r\n            if (excludes.includes(String(key))) continue\r\n            if(isClass(target) || injectStatic){\r\n                syncObjectProperty(String(key), target.constructor, source.constructor, { conflict })\r\n            }            \r\n        }\r\n    }\r\n    // 复制原型链上的数据\r\n    if (source.prototype) {\r\n        mixinObject(target, source.prototype, { excludes, conflict,injectStatic })\r\n    } else if (source.__proto__ && source.__proto__ != (Function as any).__proto__ && source.__proto__ != Object.prototype) {\r\n        mixinObject(target, source.__proto__, { excludes, conflict,injectStatic})\r\n    }\r\n}\r\n\r\n"]}