diff --git a/nix-js/runtime-ts/src/builtins/functional.ts b/nix-js/runtime-ts/src/builtins/functional.ts index 74e3c93..8ccf7ff 100644 --- a/nix-js/runtime-ts/src/builtins/functional.ts +++ b/nix-js/runtime-ts/src/builtins/functional.ts @@ -2,10 +2,11 @@ * Functional programming builtin functions */ -import { CatchableError, HAS_CONTEXT, type NixValue } from "../types"; +import { CatchableError, type NixValue } from "../types"; import { force } from "../thunk"; import { coerceToString, StringCoercionMode } from "./conversion"; import { printValue } from "../print"; +import { isAttrs } from "./type-check"; export const seq = (e1: NixValue) => @@ -17,16 +18,25 @@ export const seq = export const deepSeq = (e1: NixValue) => (e2: NixValue): NixValue => { - const forced = force(e1); - if (Array.isArray(forced)) { - for (const val of forced) { - deepSeq(val); + const seen: Set = new Set; + const recurse = (e: NixValue) => { + if (!seen.has(e)) { + seen.add(e); + } else { + return } - } else if (typeof forced === "object" && forced !== null && !(HAS_CONTEXT in forced)) { - for (const [_, val] of Object.entries(forced)) { - deepSeq(val); + const forced = force(e); + if (Array.isArray(forced)) { + for (const val of forced) { + recurse(val); + } + } else if (isAttrs(forced)) { + for (const [_, val] of Object.entries(forced)) { + recurse(val); + } } } + recurse(e1); return e2; };