graphql-subscriptions PubSub.prototype.asyncIterator is wrongly typed
n1ru4l opened this issue · comments
Instead of AsyncIterator
it should return AsyncIterable
.... (apollographql/graphql-subscriptions#232) This typing is incorrect for a long time and nobody bothers reviewing the PRs and fixing it...
This is causing TypeScript errors, I got when I set up the project.
Possible solutions
patch-package
Not great for a tutorial and also I would like to avoid any apollo "maintained" libraries.
Just use a simple PubSub inlined
This is all you need. I have been using it for a while with https://github.com/dungeon-revealer/dungeon-revealer/blob/master/server/pubsub.ts. It should be sufficient for the use-cases of the tutorial?
import { EventEmitter, on } from "events";
type PubSubPublishArgsByKey = {
[key: string]: [any] | [number | string, any];
};
export const createChannelPubSub = <
TPubSubPublishArgsByKey extends PubSubPublishArgsByKey
>() => {
const emitter = new EventEmitter();
return {
publish: <TKey extends Extract<keyof TPubSubPublishArgsByKey, string>>(
routingKey: TKey,
...args: TPubSubPublishArgsByKey[TKey]
) => {
if (args[1] !== undefined) {
emitter.emit(`${routingKey}:${args[0] as number}`, args[1]);
}
emitter.emit(routingKey, args[0]);
},
subscribe: async function* <
TKey extends Extract<keyof TPubSubPublishArgsByKey, string>
>(
...[routingKey, id]: TPubSubPublishArgsByKey[TKey][1] extends undefined
? [TKey]
: [TKey, TPubSubPublishArgsByKey[TKey][0]]
): AsyncGenerator<
TPubSubPublishArgsByKey[TKey][1] extends undefined
? TPubSubPublishArgsByKey[TKey][0]
: TPubSubPublishArgsByKey[TKey][1]
> {
const asyncIterator = on(
emitter,
id === undefined ? routingKey : `${routingKey}:${id as number}`
);
for await (const [value] of asyncIterator) {
yield value as any;
}
},
};
};