diff --git a/packages/workflow/src/AugmentObject.ts b/packages/workflow/src/AugmentObject.ts index a56fd7cb06..515f7a554c 100644 --- a/packages/workflow/src/AugmentObject.ts +++ b/packages/workflow/src/AugmentObject.ts @@ -1,18 +1,9 @@ import type { IDataObject } from './Interfaces'; const augmentedObjects = new WeakSet(); + function augment(value: T): T { - if ( - typeof value !== 'object' || - value === null || - value instanceof RegExp || - augmentedObjects.has(value) - ) - return value; - - // Track augmented objects to prevent infinite recursion in cases where an object contains circular references - augmentedObjects.add(value); - + if (typeof value !== 'object' || value === null || value instanceof RegExp) return value; if (value instanceof Date) return new Date(value.valueOf()) as T; // eslint-disable-next-line @typescript-eslint/no-use-before-define @@ -23,6 +14,8 @@ function augment(value: T): T { } export function augmentArray(data: T[]): T[] { + if (augmentedObjects.has(data)) return data; + let newData: unknown[] | undefined = undefined; function getData(): unknown[] { @@ -32,7 +25,7 @@ export function augmentArray(data: T[]): T[] { return newData; } - return new Proxy(data, { + const proxy = new Proxy(data, { deleteProperty(target, key: string) { return Reflect.deleteProperty(getData(), key); }, @@ -63,24 +56,25 @@ export function augmentArray(data: T[]): T[] { return Reflect.ownKeys(newData !== undefined ? newData : target); }, set(target, key: string, newValue: unknown) { - if (newValue !== null && typeof newValue === 'object') { - // Always proxy all objects. Like that we can check in get simply if it - // is a proxy and it does then not matter if it was already there from the - // beginning and it got proxied at some point or set later and so theoretically - // does not have to get proxied - newValue = new Proxy(newValue, {}); - } - - return Reflect.set(getData(), key, newValue); + // Always proxy all objects. Like that we can check in get simply if it + // is a proxy and it does then not matter if it was already there from the + // beginning and it got proxied at some point or set later and so theoretically + // does not have to get proxied + return Reflect.set(getData(), key, augment(newValue)); }, }); + + augmentedObjects.add(proxy); + return proxy; } export function augmentObject(data: T): T { + if (augmentedObjects.has(data)) return data; + const newData = {} as IDataObject; const deletedProperties: Array = []; - return new Proxy(data, { + const proxy = new Proxy(data, { get(target, key: string, receiver): unknown { if (deletedProperties.indexOf(key) !== -1) { return undefined; @@ -144,4 +138,7 @@ export function augmentObject(data: T): T { }; }, }); + + augmentedObjects.add(proxy); + return proxy; }