function* search(visited, path, object, keys, values) { for (const key of Reflect.ownKeys(object)) { const value = object[key]; if (keys.has(key) || values.has(value)) { yield [path.slice(), value]; } if (typeof value === "object" && value != null && !visited.has(value)) { visited.add(value); path.push(key); yield* search(visited, path, value, keys, values); path.pop(); } } } export function deepSearch(root, keys = [], values = []) { const visited = new WeakSet().add(root); const path = []; return search(visited, path, root, new Set(keys), new Set(values)); }