UNPKG

@graphql-yoga/nestjs

Version:

GraphQL Yoga driver for NestJS GraphQL.

82 lines (74 loc) 1.67 kB
export interface Generator<T> { gen: AsyncGenerator<T, void, T> produce(val: T): void } function createGenerator<T>(): Generator<T> { const pending: T[] = [] const deferred = { done: false, error: null as unknown, resolve: () => { // noop }, } const gen = (async function* gen() { for (;;) { if (!pending.length) { // only wait if there are no pending messages available await new Promise<void>((resolve) => (deferred.resolve = resolve)) } // first flush while (pending.length) { yield pending.shift()! } // then error if (deferred.error) { throw deferred.error } // or complete if (deferred.done) { return } } })() gen.throw = async (err) => { if (!deferred.done) { deferred.done = true deferred.error = err deferred.resolve() } return { done: true, value: undefined } } gen.return = async () => { if (!deferred.done) { deferred.done = true deferred.resolve() } return { done: true, value: undefined } } return { gen, produce(val) { pending.push(val) deferred.resolve() }, } } export function createPubSub<T>() { const producers: Generator<T>['produce'][] = [] return { pub(val: T) { for (const next of producers) next(val) }, sub() { const { gen, produce } = createGenerator<T>() producers.push(produce) const origReturn = gen.return gen.return = () => { producers.splice(producers.indexOf(produce), 1) return origReturn() } return gen }, } }