UNPKG

domain-objects

Version:

A simple, convenient way to represent domain objects, leverage domain knowledge, and add runtime validation in your code base.

63 lines 2.03 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.clone = void 0; /** * .what = deep clones domain objects safely * .why = preserves instance types, methods, and nested structures */ const clone = (dobj, updates = {}) => { // clone and merge const merged = deepMerge(deepClone(dobj), updates); // instantiate, if can const ctor = dobj?.constructor; const hasConstructor = typeof ctor === 'function' && ctor !== Object && ctor.prototype && ctor.prototype.constructor === ctor; if (!hasConstructor) return merged; return new ctor(merged); }; exports.clone = clone; function deepClone(value) { if (value === null || typeof value !== 'object') return value; if (Array.isArray(value)) { return value.map(deepClone); } if (value instanceof Date) return new Date(value.getTime()); const proto = Object.getPrototypeOf(value); const cloneObj = Object.create(proto); for (const key of Reflect.ownKeys(value)) { const desc = Object.getOwnPropertyDescriptor(value, key); if (desc) { Object.defineProperty(cloneObj, key, { ...desc, value: deepClone(value[key]), }); } } return cloneObj; } function deepMerge(base, updates) { const result = Array.isArray(base) ? [...base] : { ...base }; for (const key in updates) { const baseVal = base[key]; const updateVal = updates[key]; const isMergeableObject = typeof baseVal === 'object' && baseVal !== null && typeof updateVal === 'object' && updateVal !== null && !Array.isArray(baseVal) && !Array.isArray(updateVal); if (isMergeableObject) { result[key] = deepMerge(baseVal, updateVal); } else if (updateVal !== undefined) { result[key] = updateVal; } } return result; } //# sourceMappingURL=clone.js.map