@graphql-hive/pubsub
Version:
82 lines (78 loc) • 2.19 kB
JavaScript
'use strict';
var repeater = require('@repeaterjs/repeater');
var disposablestack = require('@whatwg-node/disposablestack');
class PubSub {
#topicListeners = /* @__PURE__ */ new Map();
#subIdTopic = /* @__PURE__ */ new Map();
#subIdListeners = /* @__PURE__ */ new Map();
/** @deprecated Please use {@link subscribedTopics} instead. */
getEventNames() {
return this.#topicListeners.keys();
}
subscribedTopics() {
return this.#topicListeners.keys();
}
publish(topic, data) {
const listeners = this.#topicListeners.get(topic);
if (listeners) {
for (const l of listeners) {
l(data);
}
}
}
subscribe(topic, listener) {
let listeners = this.#topicListeners.get(topic);
if (!listeners) {
listeners = /* @__PURE__ */ new Set();
this.#topicListeners.set(topic, listeners);
}
listeners.add(listener);
const subId = Math.floor(Math.random() * 1e8);
this.#subIdTopic.set(subId, topic);
this.#subIdListeners.set(subId, listener);
return subId;
}
unsubscribe(subId) {
const listener = this.#subIdListeners.get(subId);
if (!listener) {
return;
}
this.#subIdListeners.delete(subId);
const topic = this.#subIdTopic.get(subId);
if (!topic) {
return;
}
this.#subIdTopic.delete(subId);
const listeners = this.#topicListeners.get(topic);
if (!listeners) {
return;
}
listeners.delete(listener);
if (listeners.size === 0) {
this.#topicListeners.delete(topic);
}
}
#asyncIteratorStops = /* @__PURE__ */ new Set();
asyncIterator(topic) {
return new repeater.Repeater(async (push, stop) => {
const subId = this.subscribe(topic, push);
this.#asyncIteratorStops.add(stop);
await stop;
this.#asyncIteratorStops.delete(stop);
this.unsubscribe(subId);
});
}
dispose() {
this.#topicListeners.clear();
this.#subIdListeners.clear();
this.#subIdTopic.clear();
for (const stop of this.#asyncIteratorStops) {
stop();
}
this.#asyncIteratorStops.clear();
}
[disposablestack.DisposableSymbols.dispose]() {
this.dispose();
}
}
exports.PubSub = PubSub;