export default class Mutex { private current: Promise; constructor() { this.current = Promise.resolve(); } lock() { let resolveFun: () => void; const subPromise = new Promise((resolve) => (resolveFun = () => resolve())); // Caller gets a promise that resolves when the current outstanding lock resolves const newPromise = this.current.then(() => resolveFun); // Don't allow the next request until the new promise is done this.current = subPromise; // Return the new promise return newPromise; } async runExclusively(cb: () => Promise) { const unlock = await this.lock(); try { return await cb(); } finally { unlock(); } } }