1/**
2 * Runs `run` at most once at a time. A call made while a run is in flight
3 * queues one more run after it and returns that queued run, so input that
4 * arrives mid-run (a native share handed over on resume) is still read, and
5 * the caller that asked for it sees how it ended.
6 */
7export function coalescedRun(run: () => Promise<void>): () => Promise<void> {
8 let inFlight: Promise<void> | null = null;
9 let queued: Promise<void> | null = null;
10 const start = (): Promise<void> => {
11 if (inFlight) {
12 queued ??= inFlight
13 .catch(() => undefined)
14 .then(() => {
15 queued = null;
16 return start();
17 });
18 return queued;
19 }
20 inFlight = run().finally(() => {
21 inFlight = null;
22 });
23 return inFlight;
24 };
25 return start;
26}