~james/core

core/e2e/harness/frames.ts -rw-r--r-- 1.1 KiB
452f17b7 — james chore(import): snapshot james.dad.town/core at f70c71c7696a 16 hours ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// every worker's writes come through here, and a run is only a few thousand frames
const KEPT = 50_000;

export class Frames<T extends { id: number }> {
	private records = new Map<string, T[]>();
	private kept = 0;
	protected forgotUpTo = -1;
	private waiting = new Set<() => void>();

	seen(uri: string) {
		return this.records.get(uri) ?? [];
	}

	// wake on the next frame so a check passes the moment it lands
	changed(ms: number) {
		return new Promise<void>((wake) => {
			const done = () => {
				clearTimeout(timer);
				this.waiting.delete(done);
				wake();
			};
			const timer = setTimeout(done, ms);
			this.waiting.add(done);
		});
	}

	protected wake() {
		for (const wake of this.waiting) wake();
	}

	protected append(uri: string, frame: T) {
		const seen = this.seen(uri);
		seen.push(frame);
		this.records.set(uri, seen);
		this.kept++;
		while (this.kept > KEPT) {
			const [oldest, dropped] = this.records.entries().next().value!;
			this.records.delete(oldest);
			this.kept -= dropped.length;
			this.forgotUpTo = Math.max(this.forgotUpTo, dropped.at(-1)!.id);
		}
	}
}