export const equals = (a: T, b: T): boolean => { if (a === b) { return true; } if (!a || !b) { return false; } if (typeof a !== 'object' || typeof b !== 'object') { return false; } if (a instanceof Date && b instanceof Date) { return a.valueOf() === b.valueOf(); } if (a instanceof Uint8Array && b instanceof Uint8Array) { if (a.length !== b.length) { return false; } for (let i = 0; i < a.length; i++) { if (a[i] !== b[i]) { return false; } } return true; } if (Array.isArray(a)) { if (!Array.isArray(b)) { return false; } if (a.length !== b.length) { return false; } for (let i = 0; i < a.length; i++) { if (!equals(a[i], b[i])) { return false; } } return true; } if (Object.keys(b).length !== Object.keys(a).length) { return false; } for (const key of Object.keys(a)) { if (!(key in b)) { return false; } if (!equals((a as Record)[key], (b as Record)[key])) { return false; } } return true; }; export const isObject = (value: unknown): value is object => { const type = typeof value; return !!value && (type === 'object' || type === 'function'); }; export const flatSome = (x: T[] | T, f: (x: T) => boolean): boolean => { if (Array.isArray(x)) { return x.some(f); } return f(x); }; export const some = (x: T | T[], f: (x: T | T[]) => boolean): boolean => { if (f(x)) { return true; } return Array.isArray(x) && x.some(f); }; export const isEmptyArray = (value: unknown): value is T[] & { length: 0 } => Array.isArray(value) && value.length === 0;