diff --git a/.changeset/fix-fn-result-suspend-on-waiting.md b/.changeset/fix-fn-result-suspend-on-waiting.md new file mode 100644 index 00000000..c09042c3 --- /dev/null +++ b/.changeset/fix-fn-result-suspend-on-waiting.md @@ -0,0 +1,5 @@ +--- +"@effect-atom/atom": patch +--- + +pass suspendOnWaiting options to resultOnce in Atom.fn context diff --git a/packages/atom/src/internal/registry.ts b/packages/atom/src/internal/registry.ts index a6f1d736..eb3388d7 100644 --- a/packages/atom/src/internal/registry.ts +++ b/packages/atom/src/internal/registry.ts @@ -538,7 +538,7 @@ const LifetimeProto: Omit, "node" | "finalizers" | "disposed" | "i if (this.disposed) { throw disposedError(this.node.atom) } else if (this.isFn) { - return this.resultOnce(atom) + return this.resultOnce(atom, options) } const result = this.get(atom) if (options?.suspendOnWaiting && result.waiting) { diff --git a/packages/atom/test/Atom.test.ts b/packages/atom/test/Atom.test.ts index 987a33c1..da2a751a 100644 --- a/packages/atom/test/Atom.test.ts +++ b/packages/atom/test/Atom.test.ts @@ -1422,6 +1422,57 @@ describe("Atom", () => { unmount2() }) + + it("get.result suspendOnWaiting", async () => { + const r = Registry.make() + + const inner = Atom.make(Effect.succeed(1).pipe(Effect.delay(50))) + const outer = Atom.make((get) => get.result(inner, { suspendOnWaiting: true })) + + r.mount(outer) + + let result = r.get(outer) + assert(result.waiting) + + await vitest.advanceTimersByTimeAsync(50) + + result = r.get(outer) + assert(Result.isSuccess(result)) + assert.strictEqual(result.value, 1) + }) + + it("fn get.result suspendOnWaiting", async () => { + const r = Registry.make() + let runs = 0 + + const inner = Atom.fn((n: number) => { + runs++ + return Effect.succeed(n * 2).pipe(Effect.delay(50)) + }) + + const outer = Atom.fn( + Effect.fn(function*(_: void, get: Atom.FnContext) { + get.set(inner, 1) + const a = yield* get.result(inner, { suspendOnWaiting: true }) + + get.set(inner, 2) + const b = yield* get.result(inner, { suspendOnWaiting: true }) + + return { a, b } + }) + ) + + r.mount(outer) + r.set(outer, void 0) + + await vitest.advanceTimersByTimeAsync(100) + + const result = r.get(outer) + assert(Result.isSuccess(result)) + assert.strictEqual(result.value.a, 2) + assert.strictEqual(result.value.b, 4) + assert.strictEqual(runs, 2) + }) }) interface BuildCounter {