Skip to content

Commit 3b6ab8f

Browse files
committed
Fix cyclical references
1 parent 75c163f commit 3b6ab8f

File tree

2 files changed

+22
-3
lines changed

2 files changed

+22
-3
lines changed

index.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ const t = true;
77
const richTypes = { Date: t, RegExp: t, String: t, Number: t };
88
export default function diff(
99
obj: Record<string, any> | any[],
10-
newObj: Record<string, any> | any[]
10+
newObj: Record<string, any> | any[],
11+
stack: Record<string, any>[] = []
1112
): Difference[] {
1213
let diffs: Difference[] = [];
1314
for (const key in obj) {
@@ -21,9 +22,10 @@ export default function diff(
2122
newObj[key] &&
2223
typeof obj[key] === "object" &&
2324
typeof newObj[key] === "object" &&
24-
!richTypes[Object.getPrototypeOf(obj[key]).constructor.name]
25+
!richTypes[Object.getPrototypeOf(obj[key]).constructor.name] &&
26+
!stack.includes(obj[key])
2527
) {
26-
const nestedDiffs = diff(obj[key], newObj[key]);
28+
const nestedDiffs = diff(obj[key], newObj[key], stack.concat(obj[key]));
2729
diffs.push(
2830
...nestedDiffs.map((difference) => {
2931
difference.path.unshift(key);

tests/cycles.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { test } from "uvu";
2+
import * as assert from "uvu/assert";
3+
import diff from "../dist/index.js";
4+
5+
test("Handles recursive references", () => {
6+
const obj1 = {};
7+
obj1.a = obj1;
8+
assert.equal(diff(obj1, obj1), []);
9+
});
10+
11+
test("Handles recursive references more than 1 level up", () => {
12+
const obj1 = { a: {} };
13+
obj1.a.b = obj1;
14+
assert.equal(diff(obj1, obj1), []);
15+
});
16+
17+
test.run();

0 commit comments

Comments
 (0)