@graphql-hive/pubsub
Version:
71 lines (67 loc) • 1.89 kB
JavaScript
;
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;