@mora-light/core
Version:
Mora Light Core
152 lines (135 loc) • 4.24 kB
JavaScript
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;
;