UNPKG

metarize

Version:

A lightweight, ESM-compatible TypeScript metadata library for creating and inspecting decorators with zero dependencies

116 lines 3.7 kB
/** * A collection of types that can be cloned */ export const cloneableTypes = new Set([ Object, Array, Set, Map, RegExp, Date, Buffer, ArrayBuffer, Float32Array, Float64Array, Int8Array, Int16Array, Int32Array, Uint8Array, Uint8ClampedArray, Uint16Array, Uint32Array, ]); /** * Deep clone a value * @param val - The value to clone * @param refs - Map of references to handle circular references (internal use) * @returns A deep clone of the value */ export function cloneDeep(val, refs = new WeakMap()) { if (val === null || typeof val !== 'object') return val; // Handle circular references if (refs.has(val)) { throw new Error('Circular reference detected during deep cloning'); } // Handle special types that should not be deep cloned if (val.constructor != null && !cloneableTypes.has(val.constructor)) { // Do not clone instances of classes/constructors, such as custom classes return val; } // Add this object to the refs map refs.set(val, true); // Handle arrays if (Array.isArray(val)) { const result = val.map(item => cloneDeep(item, refs)); refs.delete(val); // Clean up refs map return result; } // Handle Set if (val instanceof Set) { const newSet = new Set(); val.forEach(item => newSet.add(cloneDeep(item, refs))); refs.delete(val); // Clean up refs map return newSet; } // Handle Map if (val instanceof Map) { const newMap = new Map(); val.forEach((value, key) => newMap.set(key, cloneDeep(value, refs))); refs.delete(val); // Clean up refs map return newMap; } // Handle RegExp if (val instanceof RegExp) { refs.delete(val); // Clean up refs map return new RegExp(val.source, val.flags); } // Handle Date if (val instanceof Date) { refs.delete(val); // Clean up refs map return new Date(val.getTime()); } // Handle ArrayBuffer and typed arrays if (val instanceof ArrayBuffer) { const newBuffer = new ArrayBuffer(val.byteLength); new Uint8Array(newBuffer).set(new Uint8Array(val)); refs.delete(val); // Clean up refs map return newBuffer; } if (ArrayBuffer.isView(val) && !(val instanceof DataView)) { // Handle typed arrays (Float32Array, Uint8Array, etc.) // Use any typed array method that creates a copy refs.delete(val); // Clean up refs map if (val instanceof Float32Array) return new Float32Array(val); if (val instanceof Float64Array) return new Float64Array(val); if (val instanceof Int8Array) return new Int8Array(val); if (val instanceof Int16Array) return new Int16Array(val); if (val instanceof Int32Array) return new Int32Array(val); if (val instanceof Uint8Array) return new Uint8Array(val); if (val instanceof Uint8ClampedArray) return new Uint8ClampedArray(val); if (val instanceof Uint16Array) return new Uint16Array(val); if (val instanceof Uint32Array) return new Uint32Array(val); // Fallback for any other ArrayBufferView types return val; } // Handle plain objects const newObj = {}; for (const key in val) { if (Object.hasOwn(val, key)) { newObj[key] = cloneDeep(val[key], refs); } } refs.delete(val); // Clean up refs map return newObj; } // 这里可以添加其他工具函数 //# sourceMappingURL=utils.js.map