UNPKG

@graphql-hive/pubsub

Version:
69 lines (66 loc) 1.83 kB
import { Repeater } from '@repeaterjs/repeater'; import { DisposableSymbols } from '@whatwg-node/disposablestack'; import { fakePromise } from '@whatwg-node/promise-helpers'; class MemPubSub { #disposed = false; #subscribers = /* @__PURE__ */ new Map(); subscribedTopics() { return this.#subscribers.keys(); } publish(topic, data) { if (this.#disposed) { throw new Error("PubSub is disposed, cannot publish data"); } const listeners = this.#subscribers.get(topic); if (listeners) { for (const l of listeners.keys()) { l(data); } } } subscribe(topic, listener) { if (this.#disposed) { throw new Error("PubSub is disposed, cannot subscribe to topics"); } let listeners = this.#subscribers.get(topic); if (!listeners) { listeners = /* @__PURE__ */ new Map(); this.#subscribers.set(topic, listeners); } if (!listener) { return new Repeater((push, stop) => { listeners.set(push, stop); return stop.then(() => { listeners.delete(push); if (listeners.size === 0) { this.#subscribers.delete(topic); } }); }); } const listenerRef = new WeakRef(listener); const unsubscribe = () => { const l = listenerRef.deref(); if (l) listeners.delete(l); if (listeners.size === 0) { this.#subscribers.delete(topic); } }; listeners.set(listener, unsubscribe); return unsubscribe; } dispose() { this.#disposed = true; for (const sub of this.#subscribers.values()) { for (const stop of sub.values()) { stop(); } sub.clear(); } this.#subscribers.clear(); } [DisposableSymbols.asyncDispose]() { return fakePromise(this.dispose()); } } export { MemPubSub };