@nktkas/hyperliquid
Version:
Hyperliquid API SDK for all major JS runtimes, written in TypeScript.
89 lines • 2.46 kB
JavaScript
"use strict";
// ============================================================
// Semaphore
// ============================================================
Object.defineProperty(exports, "__esModule", { value: true });
exports.Semaphore = void 0;
exports.withLock = withLock;
class Semaphore {
#max;
#count;
#head;
#tail;
constructor(max = 1) {
if (max < 1) {
throw new TypeError(`Cannot create semaphore as 'max' must be at least 1: current value is ${max}`);
}
this.#count = this.#max = max;
}
acquire() {
if (this.#count > 0) {
this.#count--;
return Promise.resolve();
}
return new Promise((res) => {
const node = { res, next: undefined };
if (this.#tail) {
this.#tail = this.#tail.next = node;
}
else {
this.#head = this.#tail = node;
}
});
}
release() {
if (this.#head) {
this.#head.res();
this.#head = this.#head.next;
if (!this.#head)
this.#tail = undefined;
}
else if (this.#count < this.#max) {
this.#count++;
}
}
}
exports.Semaphore = Semaphore;
// ============================================================
// RefCounted Registry
// ============================================================
class RefCountedRegistry {
#map = new Map();
#factory;
constructor(factory) {
this.#factory = factory;
}
ref(key) {
let entry = this.#map.get(key);
if (!entry) {
entry = { value: this.#factory(), refs: 0 };
this.#map.set(key, entry);
}
entry.refs++;
return entry.value;
}
unref(key) {
const entry = this.#map.get(key);
if (!entry)
return;
if (--entry.refs === 0) {
this.#map.delete(key);
}
}
}
// ============================================================
// Helper
// ============================================================
const semaphores = new RefCountedRegistry(() => new Semaphore(1));
async function withLock(key, fn) {
const semaphore = semaphores.ref(key);
await semaphore.acquire();
try {
return await fn();
}
finally {
semaphore.release();
semaphores.unref(key);
}
}
//# sourceMappingURL=_semaphore.js.map