43 lines
1.1 KiB
TypeScript
43 lines
1.1 KiB
TypeScript
export type Release = { release: () => void };
|
|
|
|
export default class PathLock {
|
|
locks: {
|
|
path: string[],
|
|
next: (() => void)[]
|
|
}[] = [];
|
|
|
|
constructor() { }
|
|
|
|
async lock(path: string[]) {
|
|
let locks = this.locks.filter(lock => {
|
|
let idxs = Math.min(lock.path.length, path.length);
|
|
if (idxs === 0) return true;
|
|
for (let i = 0; i < idxs; i++) {
|
|
if (lock.path[i] !== path[i])
|
|
return false;
|
|
}
|
|
return true;
|
|
})
|
|
|
|
if (locks.length > 0) { // await till release
|
|
await Promise.all(locks.map(l => new Promise(res => l.next.push(res))))
|
|
} else {
|
|
let lock = {
|
|
path: path,
|
|
next: []
|
|
}
|
|
this.locks.push(lock);
|
|
locks = [lock];
|
|
}
|
|
|
|
return () => {
|
|
locks.forEach(lock => {
|
|
if (lock.next.length > 0) {
|
|
setImmediate(() => lock.next.shift()());
|
|
} else {
|
|
this.locks.splice(this.locks.indexOf(lock), 1);
|
|
}
|
|
})
|
|
}
|
|
}
|
|
} |