import { Mutex, type MutexInterface } from "async-mutex"; export async function wrapAsyncInCatch(a: PromiseLike) { try { await a; } catch (e) { console.log("Error in async process: " + e); } } export function withTimeout(promise: Promise, timeoutMs: number, reason = "timed out"): Promise { let timer: ReturnType; return Promise.race([ promise, new Promise((_, rej) => timer = setTimeout(rej, timeoutMs, reason)) ]).finally(() => clearTimeout(timer)); } export type DID = `did:${string}:${string}`; export class NamedMutex { private muMap = new Map(); private getOrCreate(key: string): Mutex { let v = this.muMap.get(key); if (!v) { v = new Mutex(); this.muMap.set(key, v); } return v; } async acquire(key: string, priority?: number): Promise { const releaser = await this.getOrCreate(key).acquire(priority); this.muMap.delete(key); return releaser; }; async runExclusive(key: string, callback: MutexInterface.Worker, priority?: number): Promise { const result = await this.getOrCreate(key).runExclusive(callback, priority); this.muMap.delete(key); return result; }; isLocked(key: string): boolean { let v = this.muMap.get(key); if (!v) { return false; } return v.isLocked(); }; async waitForUnlock(key: string, priority?: number): Promise { let v = this.muMap.get(key); if (!v) { return; } return await v.waitForUnlock(priority); }; release(key: string): void { return this.getOrCreate(key).release(); }; cancel(key: string): void { return this.getOrCreate(key).cancel(); }; }