From a82515b11935216942a0d5edf9cc313f929f1305 Mon Sep 17 00:00:00 2001 From: Jane Kim Date: Thu, 24 Sep 2026 21:21:03 -0700 Subject: [PATCH] Unlink a removed node from its parents when it was stale --- .changeset/remove-unlinks-stale-parents.md | 5 +++++ packages/atom/src/internal/registry.ts | 4 ---- packages/atom/test/Atom.test.ts | 16 ++++++++++++++++ 3 files changed, 21 insertions(+), 4 deletions(-) create mode 100644 .changeset/remove-unlinks-stale-parents.md diff --git a/.changeset/remove-unlinks-stale-parents.md b/.changeset/remove-unlinks-stale-parents.md new file mode 100644 index 00000000..275d8482 --- /dev/null +++ b/.changeset/remove-unlinks-stale-parents.md @@ -0,0 +1,5 @@ +--- +"@effect-atom/atom": patch +--- + +Unlink a removed node from its parents when it was invalidated before removal, so the parents can be removed too. diff --git a/packages/atom/src/internal/registry.ts b/packages/atom/src/internal/registry.ts index fcc3ff07..4dc95b3a 100644 --- a/packages/atom/src/internal/registry.ts +++ b/packages/atom/src/internal/registry.ts @@ -441,10 +441,6 @@ class Node { this.state = NodeState.removed this.listeners.clear() - if (this.lifetime === undefined) { - return - } - this.disposeLifetime() if (this.previousParents === undefined) { diff --git a/packages/atom/test/Atom.test.ts b/packages/atom/test/Atom.test.ts index 1b48c949..d40389f2 100644 --- a/packages/atom/test/Atom.test.ts +++ b/packages/atom/test/Atom.test.ts @@ -335,6 +335,22 @@ describe("Atom", () => { unsubscribe() }) + it("removes parents of a node that was invalidated before removal", async () => { + const parent = Atom.make(0) + const source = Atom.make(0) + const child = Atom.make((get) => get(parent) + get(source)) + const registry = Registry.make() + const unmount = registry.mount(child) + + unmount() + registry.set(source, 1) + await new Promise((resolve) => resolve(null)) + + const nodes = registry.getNodes() + assert.strictEqual(nodes.has(child), false) + assert.strictEqual(nodes.has(parent), false) + }) + it("refresh derived before mount resolves base effect", async () => { const baseAtom = Atom.make( Effect.succeed("value").pipe(Effect.delay(100))