p2p-media-loader-core
Version:
P2P Media Loader core functionality
93 lines (79 loc) • 2.43 kB
text/typescript
import { WebSocketClient } from "../websocket-client/index.js";
import { EventTarget } from "../../utils/event-target.js";
export type WebTorrentSocketPoolEventMap = {
error: (error: Event, url: string) => void;
};
type PoolEntry = {
client: WebSocketClient;
refCount: number;
};
export class WebTorrentSocketPool {
readonly #sockets = new Map<string, PoolEntry>();
readonly #eventTarget = new EventTarget<WebTorrentSocketPoolEventMap>();
public addEventListener<K extends keyof WebTorrentSocketPoolEventMap>(
eventName: K,
listener: WebTorrentSocketPoolEventMap[K],
): void {
this.#eventTarget.addEventListener(eventName, listener);
}
public removeEventListener<K extends keyof WebTorrentSocketPoolEventMap>(
eventName: K,
listener: WebTorrentSocketPoolEventMap[K],
): void {
this.#eventTarget.removeEventListener(eventName, listener);
}
public acquire(url: string): {
client: WebSocketClient;
release: () => void;
} {
let entry = this.#sockets.get(url);
if (!entry) {
const client = new WebSocketClient({ url });
client.addEventListener("error", (error) => {
this.#eventTarget.dispatchEvent("error", error, url);
});
client.connect();
entry = { client, refCount: 0 };
this.#sockets.set(url, entry);
}
entry.refCount++;
let isReleased = false;
return {
client: entry.client,
release: () => {
if (isReleased) return;
isReleased = true;
entry.refCount--;
if (entry.refCount <= 0) {
if (entry.refCount < 0) {
// eslint-disable-next-line no-console
console.error(
`[WebTorrentSocketPool] Negative refCount detected for ${url}`,
);
}
const currentEntry = this.#sockets.get(url);
if (currentEntry === entry) {
this.#sockets.delete(url);
}
entry.client.dispose();
}
},
};
}
public destroy(): void {
this.#eventTarget.clear();
const entries = Array.from(this.#sockets.values());
this.#sockets.clear();
for (const entry of entries) {
try {
entry.client.dispose();
} catch (error) {
// eslint-disable-next-line no-console
console.error(
"[WebTorrentSocketPool] Failed to dispose WebSocketClient:",
error,
);
}
}
}
}