You're not treating the aquire phase correctly:
class Lock {
#resolve: (() => void) | undefined;
#releasePromise: Promise<void> | undefined;
constructor(public name: string) {}
acquire(): Promise<void> {
if (this.#releasePromise !== undefined) {
throw new Error("Already aquired");
}
return new Promise((resolveAquire, _rejectAquire) => {
this.#releasePromise = new Promise((resolveRelease, _rejectRelease) => {
navigator.locks.request(this.name, async (lock) => {
await new Promise<void>((resolve, _reject) => {
this.#resolve = resolve;
resolveAquire();
});
resolveRelease();
});
});
});
}
async release(): Promise<void> {
if (this.#releasePromise === undefined) {
throw new Error("Already released");
}
this.#resolve();
await this.#releasePromise;
this.#resolve = undefined;
this.#releasePromise = undefined;
}
}
...the release phase still feels off without a Promise, but maybe somebody else can tackle that :D
EDIT: think I fixed it, untested though