Review a bounded parallel worker

src/permit-pool.tsTypeScript
@@ -0,0 +1,43 @@
1+export type ReleasePermit = () => void;
2+
3+export class PermitPool {
4+ private available: number;
5+ private readonly waiters: Array<(release: ReleasePermit) => void> = [];
6+
7+ constructor(capacity: number) {
8+ if (!Number.isInteger(capacity) || capacity < 1) {
9+ throw new RangeError("capacity must be a positive integer");
10+ }
11+
12+ this.available = capacity;
13+ }
14+
15+ acquire(): Promise<ReleasePermit> {
16+ if (this.available > 0) {
17+ this.available -= 1;
18+ return Promise.resolve(this.createRelease());
19+ }
20+
21+ return new Promise((resolve) => {
22+ this.waiters.push(resolve);
23+ });
24+ }
25+
26+ private createRelease(): ReleasePermit {
27+ let released = false;
28+
29+ return () => {
30+ if (released) {
31+ throw new Error("permit released twice");
32+ }
33+ released = true;
34+
35+ const next = this.waiters.shift();
36+ if (next) {
37+ next(this.createRelease());
38+ } else {
39+ this.available += 1;
40+ }
41+ };
42+ }
43+}