53 lines
1.5 KiB
TypeScript
53 lines
1.5 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import { test } from "node:test";
|
|
import { realtimeRefresh } from "../lib/realtime-refresh";
|
|
|
|
test("Realtime refresh coalesces bursts and retains changes arriving during a request", async () => {
|
|
const releases: Array<() => void> = [];
|
|
let calls = 0;
|
|
const queue = realtimeRefresh(
|
|
() => {
|
|
calls++;
|
|
return new Promise<void>((resolve) => releases.push(resolve));
|
|
},
|
|
() => assert.fail("unexpected failure"),
|
|
);
|
|
const first = queue.request();
|
|
await queue.request();
|
|
await queue.request();
|
|
assert.equal(calls, 1);
|
|
releases.shift()!();
|
|
await Promise.resolve();
|
|
assert.equal(calls, 2, "One follow-up fetch captures the newest state");
|
|
releases.shift()!();
|
|
await first;
|
|
assert.equal(calls, 2);
|
|
queue.close();
|
|
await queue.request();
|
|
assert.equal(calls, 2);
|
|
});
|
|
|
|
test("Realtime refresh recovers after a failed fetch and cancels queued work on unmount", async () => {
|
|
const errors: unknown[] = [];
|
|
let calls = 0;
|
|
let release: () => void = () => {};
|
|
const queue = realtimeRefresh(
|
|
async () => {
|
|
calls++;
|
|
if (calls === 1) throw Error("offline");
|
|
await new Promise<void>((resolve) => {
|
|
release = resolve;
|
|
});
|
|
},
|
|
(e) => errors.push(e),
|
|
);
|
|
await queue.request();
|
|
assert.equal(errors.length, 1);
|
|
const second = queue.request();
|
|
await queue.request();
|
|
queue.close();
|
|
release();
|
|
await second;
|
|
assert.equal(calls, 2, "Closing prevents the pending follow-up request");
|
|
});
|