Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion commonjs/duplex.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,19 @@ function _generate(mirror, obj, patches, path, invertible) {
if (helpers_js_1.hasOwnProperty(obj, key) && !(obj[key] === undefined && oldVal !== undefined && Array.isArray(obj) === false)) {
var newVal = obj[key];
if (typeof oldVal == "object" && oldVal != null && typeof newVal == "object" && newVal != null && Array.isArray(oldVal) === Array.isArray(newVal)) {
_generate(oldVal, newVal, patches, path + "/" + helpers_js_1.escapePathComponent(key), invertible);
// Special handling for Date objects: compare by value, not reference
Copy link

@chakrabar chakrabar Nov 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if structuredClone is available, maybe we can use that, otherwise fallback to this?

if (oldVal instanceof Date && newVal instanceof Date) {
if (oldVal.getTime() !== newVal.getTime()) {
changed = true;
if (invertible) {
patches.push({ op: "test", path: path + "/" + helpers_js_1.escapePathComponent(key), value: helpers_js_1._deepClone(oldVal) });
}
patches.push({ op: "replace", path: path + "/" + helpers_js_1.escapePathComponent(key), value: helpers_js_1._deepClone(newVal) });
}
}
else {
_generate(oldVal, newVal, patches, path + "/" + helpers_js_1.escapePathComponent(key), invertible);
}
}
else {
if (oldVal !== newVal) {
Expand Down
20 changes: 19 additions & 1 deletion commonjs/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,25 @@ exports._objectKeys = _objectKeys;
function _deepClone(obj) {
switch (typeof obj) {
case "object":
return JSON.parse(JSON.stringify(obj)); //Faster than ES5 clone - http://jsperf.com/deep-cloning-of-objects/5
if (obj === null) {
return null;
}
// Handle Date objects specially to preserve them as Date instances
if (obj instanceof Date) {
return new Date(obj.getTime());
}
// Handle Arrays
if (Array.isArray(obj)) {
return obj.map(function (item) { return _deepClone(item); });
}
// Handle plain objects - recursively clone each property
var cloned = {};
for (var key in obj) {
if (hasOwnProperty(obj, key)) {
cloned[key] = _deepClone(obj[key]);
}
}
return cloned;
case "undefined":
return null; //this is how JSON.stringify behaves for array items
default:
Expand Down
14 changes: 13 additions & 1 deletion module/duplex.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,19 @@ function _generate(mirror, obj, patches, path, invertible) {
if (hasOwnProperty(obj, key) && !(obj[key] === undefined && oldVal !== undefined && Array.isArray(obj) === false)) {
var newVal = obj[key];
if (typeof oldVal == "object" && oldVal != null && typeof newVal == "object" && newVal != null && Array.isArray(oldVal) === Array.isArray(newVal)) {
_generate(oldVal, newVal, patches, path + "/" + escapePathComponent(key), invertible);
// Special handling for Date objects: compare by value, not reference
if (oldVal instanceof Date && newVal instanceof Date) {
if (oldVal.getTime() !== newVal.getTime()) {
changed = true;
if (invertible) {
patches.push({ op: "test", path: path + "/" + escapePathComponent(key), value: _deepClone(oldVal) });
}
patches.push({ op: "replace", path: path + "/" + escapePathComponent(key), value: _deepClone(newVal) });
}
}
else {
_generate(oldVal, newVal, patches, path + "/" + escapePathComponent(key), invertible);
}
}
else {
if (oldVal !== newVal) {
Expand Down
20 changes: 19 additions & 1 deletion module/helpers.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,25 @@ export function _objectKeys(obj) {
export function _deepClone(obj) {
switch (typeof obj) {
case "object":
return JSON.parse(JSON.stringify(obj)); //Faster than ES5 clone - http://jsperf.com/deep-cloning-of-objects/5
if (obj === null) {
return null;
}
// Handle Date objects specially to preserve them as Date instances
if (obj instanceof Date) {
return new Date(obj.getTime());
}
// Handle Arrays
if (Array.isArray(obj)) {
return obj.map(function (item) { return _deepClone(item); });
}
// Handle plain objects - recursively clone each property
var cloned = {};
for (var key in obj) {
if (hasOwnProperty(obj, key)) {
cloned[key] = _deepClone(obj[key]);
}
}
return cloned;
case "undefined":
return null; //this is how JSON.stringify behaves for array items
default:
Expand Down
Loading