1import * as Cause from "effect/Cause";
2import { AsyncResult, Atom, AtomRegistry } from "effect/reactivity";
3import { describe, expect, it } from "vite-plus/test";
4
5import { waitForQuerySettled } from "./waitForQuerySettled";
6
7const settle = (value: number | null) =>
8 value !== null && value >= 2 ? `settled:${value}` : undefined;
9
10describe("waitForQuerySettled", () => {
11 it("resolves with the first settled value", async () => {
12 const registry = AtomRegistry.make();
13 const atom = Atom.make(AsyncResult.success<number, string>(1));
14 const result = waitForQuerySettled({
15 registry,
16 atom,
17 settle,
18 signal: new AbortController().signal,
19 });
20 registry.set(atom, AsyncResult.success(2));
21 registry.set(atom, AsyncResult.success(3));
22 expect(await result).toBe("settled:2");
23 });
24
25 it("resolves at once when the current value already settles", async () => {
26 const registry = AtomRegistry.make();
27 const atom = Atom.make(AsyncResult.success<number, string>(5));
28 expect(
29 await waitForQuerySettled({ registry, atom, settle, signal: new AbortController().signal }),
30 ).toBe("settled:5");
31 });
32
33 it("resolves undefined when aborted", async () => {
34 const registry = AtomRegistry.make();
35 const atom = Atom.make(AsyncResult.success<number, string>(1));
36 const controller = new AbortController();
37 const result = waitForQuerySettled({ registry, atom, settle, signal: controller.signal });
38 controller.abort();
39 registry.set(atom, AsyncResult.success(2));
40 expect(await result).toBeUndefined();
41 });
42
43 it("resolves undefined when the query fails, even before any success", async () => {
44 const registry = AtomRegistry.make();
45 const atom = Atom.make<AsyncResult.AsyncResult<number, string>>(AsyncResult.initial());
46 const result = waitForQuerySettled({
47 registry,
48 atom,
49 settle,
50 signal: new AbortController().signal,
51 });
52 registry.set(atom, AsyncResult.failure(Cause.fail("stream closed")));
53 registry.set(atom, AsyncResult.success(2));
54 expect(await result).toBeUndefined();
55 });
56});