1/** Coalesces invalidations into one render. No work is scheduled while the view is idle. */
2export function createRenderScheduler(
3 render: () => void,
4 request: (callback: FrameRequestCallback) => number = requestAnimationFrame,
5 cancel: (id: number) => void = cancelAnimationFrame,
6) {
7 let pending: number | null = null;
8 let disposed = false;
9 return {
10 invalidate() {
11 if (disposed || pending !== null) return;
12 pending = request(() => {
13 pending = null;
14 if (!disposed) render();
15 });
16 },
17 dispose() {
18 disposed = true;
19 if (pending !== null) cancel(pending);
20 pending = null;
21 },
22 };
23}