type LockInfo = [Promise, () => void] interface OneWayLinkedList { v: T n?: OneWayLinkedList } /** * Simple class implementing a semaphore like * behaviour. */ export class AsyncLock { private _first?: OneWayLinkedList private _last?: OneWayLinkedList async acquire(): Promise { while (this._first) { await this._first.v[0] } let unlock: () => void const prom = new Promise((resolve) => { unlock = resolve }) if (this._last) { this._last.n = { v: [prom, unlock!] } this._last = this._last.n } else { this._first = this._last = { v: [prom, unlock!] } } } release(): void { if (!this._first) throw new Error('Nothing to release') this._first.v[1]() this._first = this._first.n if (!this._first) this._last = undefined } }