UNPKG

@envelop/execute-subscription-event

Version:
48 lines (47 loc) 2.56 kB
import { createSourceEventStream } from 'graphql'; import { isAsyncIterable, makeSubscribe, mapAsyncIterator } from '@envelop/core'; import { handleMaybePromise } from '@whatwg-node/promise-helpers'; const validateSubscriptionArgsPromise = import('graphql').then(graphqlModule => graphqlModule .validateSubscriptionArgs); function getSourceEventStream(args, validateSubscriptionArgs) { if (validateSubscriptionArgs) { const validatedArgs = validateSubscriptionArgs(args); if (!('schema' in validatedArgs)) { return { errors: validatedArgs }; } // Cast away the installed graphql version's own overloads here for backwards compatability const createSourceEventStreamWithValidatedArgs = createSourceEventStream; return createSourceEventStreamWithValidatedArgs(validatedArgs); } const legacyCreateSourceEventStream = createSourceEventStream; return legacyCreateSourceEventStream(args.schema, args.document, args.rootValue, args.contextValue, args.variableValues ?? undefined, args.operationName, args.subscribeFieldResolver); } /** * This is a almost identical port from graphql-js subscribe. * The only difference is that a custom `execute` function can be injected for customizing the behavior. */ export const subscribe = (execute) => makeSubscribe(args => { const { schema, document, contextValue, variableValues, operationName, fieldResolver } = args; return handleMaybePromise(() => validateSubscriptionArgsPromise, (validateSubscriptionArgs) => handleMaybePromise(() => getSourceEventStream(args, validateSubscriptionArgs), (resultOrStream) => { if (!isAsyncIterable(resultOrStream)) { return resultOrStream; } // Map every source value to a ExecutionResult value as described above. return mapAsyncIterator(resultOrStream, // For each payload yielded from a subscription, map it over the normal // GraphQL `execute` function, with `payload` as the rootValue. // This implements the "MapSourceToResponseEvent" algorithm described in // the GraphQL specification. The `execute` function provides the // "ExecuteSubscriptionEvent" algorithm, as it is nearly identical to the // "ExecuteQuery" algorithm, for which `execute` is also used. (payload) => execute({ schema, document, rootValue: payload, contextValue, variableValues, operationName, fieldResolver, })); })); });