UNPKG

limu

Version:

A fast js lib of immutable data, based on shallow copy on read and mark modified on write mechanism

133 lines (132 loc) 3.92 kB
import { ARR_DESC, desc2dataType, FN_DESC, IS_RAW, MAP_DESC, META_VER, OBJ_DESC, SET_DESC } from './consts'; export const toString = Object.prototype.toString; const canUseReflect = !!Reflect; const hasProp = Object.prototype.hasOwnProperty; export function has(obj, key) { if (canUseReflect) { return Reflect.has(obj, key); } return hasProp.call(obj, key); } export function deepDrill(obj, parentObj, key, subObjCb) { const list = []; const innerDeep = (obj, parentObj, key) => { if (isPrimitive(obj)) { return; } if (list.includes(obj)) { // 出现循环引用,及时跳出来,避免出现错误:Maximum call stack size exceeded return; } list.push(obj); subObjCb(obj, parentObj, key); // const drillThenCb = (obj: any, parentObj: any, key: any) => { // innerDeep(obj, parentObj, key); // subObjCb(obj, parentObj, key); // }; if (Array.isArray(obj)) { obj.forEach((item, idx) => { innerDeep(item, obj, idx); }); } // TODO 处理 set // if (isSet(obj)) { // obj.forEach((item: any) => { // subObjCb(item, obj, idx); // }); // } if (isMap(obj)) { obj.forEach((value, key) => { innerDeep(value, obj, key); }); } if (isObject(obj)) { Object.keys(obj).forEach((key) => { innerDeep(obj[key], obj, key); }); } }; innerDeep(obj, parentObj, key); } export function getValStrDesc(val) { // return Array.isArray(val) ? ARR_DESC : toString.call(val); return toString.call(val); } export function noop(...args) { return args; } export function isObject(val) { // attention,null desc is '[object Null]' return getValStrDesc(val) === OBJ_DESC; } export function isMap(val) { return getValStrDesc(val) === MAP_DESC; } export function isSet(val) { return getValStrDesc(val) === SET_DESC; } export function isFn(val) { return getValStrDesc(val) === FN_DESC; } export function getDataType(dataNode) { var strDesc = getValStrDesc(dataNode); const dataType = desc2dataType[strDesc]; return dataType; } export function isPrimitive(val) { const desc = getValStrDesc(val); return ![OBJ_DESC, ARR_DESC, MAP_DESC, SET_DESC, FN_DESC].includes(desc); } export function isPromiseFn(obj) { return obj.constructor.name === 'AsyncFunction' || 'function' === typeof obj.then; } export function isPromiseResult(result) { return typeof Promise !== 'undefined' && result instanceof Promise; } export function canBeNum(val) { var valType = typeof val; if (valType === 'number') return true; if (valType === 'string') return /^[0-9]*$/.test(val); return false; } export function isSymbol(maySymbol) { return typeof maySymbol === 'symbol'; } /** * 是否已被 markRaw 标记 */ export function isMardedRaw(val) { var _a; if (!val) return false; return (_a = val[IS_RAW]) !== null && _a !== void 0 ? _a : false; } const descProto = { [ARR_DESC]: Array.prototype, [MAP_DESC]: Map.prototype, [SET_DESC]: Set.prototype, [FN_DESC]: Function.prototype, }; export function injectMetaProto(rawObj) { const desc = getValStrDesc(rawObj); const rootProto = descProto[desc] || Object.prototype; const pureObj = Object.create(null); Object.setPrototypeOf(pureObj, rootProto); Object.setPrototypeOf(rawObj, pureObj); return rawObj; } export function getProxyVer(mayProxy) { if (!mayProxy) { return ''; } return mayProxy[META_VER] || ''; } export function isPrevVerDraft(mayProxy, curVer) { const ver = getProxyVer(mayProxy); if (!ver) { return false; } return ver !== curVer; }