diff --git a/apps/ai-game-creator-shell/src/features/ui-editor/useUiEditorState.ts b/apps/ai-game-creator-shell/src/features/ui-editor/useUiEditorState.ts index 6b14446ec..f87b140bf 100644 --- a/apps/ai-game-creator-shell/src/features/ui-editor/useUiEditorState.ts +++ b/apps/ai-game-creator-shell/src/features/ui-editor/useUiEditorState.ts @@ -238,7 +238,11 @@ function cloneState(state: State): State { return structuredClone(state); } -function sameResource(left: T, right: T): boolean { +function sameResource( + left: T, + right: T, + seenPairs = new WeakMap>(), +): boolean { if (Object.is(left, right)) return true; if ( typeof left !== 'object' || @@ -248,10 +252,22 @@ function sameResource(left: T, right: T): boolean { ) { return false; } + const leftObject = left as object; + const rightObject = right as object; + let seenRightObjects = seenPairs.get(leftObject); + if (seenRightObjects?.has(rightObject)) return true; + if (!seenRightObjects) { + seenRightObjects = new WeakSet(); + seenPairs.set(leftObject, seenRightObjects); + } + seenRightObjects.add(rightObject); + if (Array.isArray(left) || Array.isArray(right)) { if (!Array.isArray(left) || !Array.isArray(right)) return false; if (left.length !== right.length) return false; - return left.every((value, index) => sameResource(value, right[index])); + return left.every((value, index) => + sameResource(value, right[index], seenPairs), + ); } const leftRecord = left as Record; const rightRecord = right as Record; @@ -261,7 +277,7 @@ function sameResource(left: T, right: T): boolean { return leftKeys.every( (key) => Object.prototype.hasOwnProperty.call(rightRecord, key) && - sameResource(leftRecord[key], rightRecord[key]), + sameResource(leftRecord[key], rightRecord[key], seenPairs), ); }