UNPKG

@graphql-yoga/redis-event-target

Version:

Do distributed GraphQL subscriptions over Redis.

59 lines (58 loc) 2.15 kB
import { CustomEvent } from '@whatwg-node/events'; export function createRedisEventTarget(args) { const { publishClient, subscribeClient } = args; const serializer = args.serializer ?? JSON; const callbacksForTopic = new Map(); function onMessage(channel, message) { const callbacks = callbacksForTopic.get(channel); if (callbacks === undefined) { return; } const event = new CustomEvent(channel, { detail: message === '' ? null : serializer.parse(message), }); for (const callback of callbacks) { callback(event); } } subscribeClient.on('message', onMessage); function addCallback(topic, callback) { let callbacks = callbacksForTopic.get(topic); if (callbacks === undefined) { callbacks = new Set(); callbacksForTopic.set(topic, callbacks); subscribeClient.subscribe(topic); } callbacks.add(callback); } function removeCallback(topic, callback) { const callbacks = callbacksForTopic.get(topic); if (callbacks === undefined) { return; } callbacks.delete(callback); if (callbacks.size > 0) { return; } callbacksForTopic.delete(topic); subscribeClient.unsubscribe(topic); } return { addEventListener(topic, callbackOrOptions) { if (callbackOrOptions != null) { const callback = 'handleEvent' in callbackOrOptions ? callbackOrOptions.handleEvent : callbackOrOptions; addCallback(topic, callback); } }, dispatchEvent(event) { publishClient.publish(event.type, event.detail === undefined ? '' : serializer.stringify(event.detail)); return true; }, removeEventListener(topic, callbackOrOptions) { if (callbackOrOptions != null) { const callback = 'handleEvent' in callbackOrOptions ? callbackOrOptions.handleEvent : callbackOrOptions; removeCallback(topic, callback); } }, }; }