UNPKG

@mora-light/core

Version:
152 lines (135 loc) 4.24 kB
'use strict'; var principal = require('@dfinity/principal'); // compare const same = (item1, item2) => { const deepSame = (item1, item2) => { if (item1 === item2) return true; if (item1 === undefined && item2 !== undefined) return false; if (item1 !== undefined && item2 === undefined) return false; if (item1 === null && item2 !== null) return false; if (item1 !== null && item2 === null) return false; const type1 = typeof item1; const type2 = typeof item2; if (type1 !== type2) return false; // 1. basic type switch (type1) { case 'boolean': return item1 === item2; case 'bigint': return `${item1}` === `${item2}`; case 'number': return item1 === item2; case 'string': return item1 === item2; case 'function': return `${item1}` === `${item2}`; case 'object': break; default: console.error('can not compare value', item1, item2); throw Error('can not compare value'); } // 2. Array const check1 = Object.prototype.toString.call(item1); const check2 = Object.prototype.toString.call(item2); if (check1 !== check2) return false; if (check1 === '[object Array]') { const length1 = item1.length; const length2 = item2.length; if (length1 !== length2) return false; for (let i = 0; i < length1; i++) { if (!deepSame(item1[i], item2[i])) return false; } return true; } // 3. Object const keys1 = Object.keys(item1); const keys2 = Object.keys(item2); for (let i = 0; i < keys1.length; i++) { const key = keys1[i]; if (!deepSame(item1[key], item2[key])) return false; const index = keys2.indexOf(key); if (index < 0) return false; keys2.splice(index, 1); } return keys2.length === 0; }; return deepSame(item1, item2); // return JSON.stringify(item1) === JSON.stringify(item2); }; // can be undefined const isSame = (t1, t2, check) => { if (t1 !== undefined) { if (t2 !== undefined) { return check ? check(t1, t2) : same(t1, t2); } else { return false; } } else { if (t2 !== undefined) { return false; } else { return true; } } }; // check string const isSameString = (s1, s2) => isSame(s1, s2, (s1, s2) => s1 === s2); // check number const isSameNumber = (s1, s2) => isSame(s1, s2, (s1, s2) => s1 === s2); // check boolean const isSameBoolean = (s1, s2) => isSame(s1, s2, (s1, s2) => s1 === s2); const deepClone = value => { if (value === undefined) return undefined; if (value === null) return null; // copy data // 1. basic type switch (typeof value) { case 'boolean': return value; case 'bigint': return BigInt(`${value}`); case 'number': return value; case 'string': return value; case 'object': // Principal if (value['_arr'] && value['_isPrincipal']) { return principal.Principal.fromText(value.toText()); } break; case 'function': // do nothing if (`${value}`.startsWith('async (idlFactory, canisterId) => {')) return value; default: console.error('can not clone value', value, typeof value); debugger; throw Error('can not clone value: ' + value); } // 2. special value if (!(value => { if (value === undefined) return true; if (value === null) return true; // const has = (value: any, keys: string[]): boolean => { // for (let i = 0; i < keys.length; i++) { // if (value[keys[i]] === undefined) return false; // } // return true; // }; return true; })(value)) return value; // 3. Array if (Object.prototype.toString.call(value) === '[object Array]') return value.map(v => deepClone(v)); // 4. Object const v = {}; for (const key of Object.keys(value)) v[key] = deepClone(value[key]); return v; // return JSON.parse(JSON.stringify(value)); // ! how to stringify Infinity or NaN of number }; exports.deepClone = deepClone; exports.isSame = isSame; exports.isSameBoolean = isSameBoolean; exports.isSameNumber = isSameNumber; exports.isSameString = isSameString; exports.same = same;