UNPKG

@graphql-hive/pubsub

Version:
82 lines (78 loc) 2.19 kB
'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;