UNPKG

@graphql-hive/pubsub

Version:
71 lines (67 loc) 1.89 kB
'use strict'; var repeater = require('@repeaterjs/repeater'); var disposablestack = require('@whatwg-node/disposablestack'); var promiseHelpers = require('@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.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(); } [disposablestack.DisposableSymbols.asyncDispose]() { return promiseHelpers.fakePromise(this.dispose()); } } exports.MemPubSub = MemPubSub;