UNPKG

@graphql-yoga/plugin-graphql-sse

Version:

GraphQL over Server-Sent Events Protocol plugin for GraphQL Yoga.

53 lines (52 loc) 2.39 kB
import { getOperationAST } from 'graphql'; import { createHandler } from 'graphql-sse/lib/use/fetch'; /** * Get [GraphQL over Server-Sent Events Protocol](https://github.com/enisdenjo/graphql-sse/blob/master/PROTOCOL.md) integration with GraphQL Yoga by simply installing this plugin! * * Note that the endpoint defaults to `/graphql/stream`, this is where your [graphql-sse](https://github.com/enisdenjo/graphql-sse) client should connect. */ export function useGraphQLSSE(options = {}) { const { endpoint = '/graphql/stream', ...handlerOptions } = options; // eslint-disable-next-line @typescript-eslint/no-explicit-any const ctxForReq = new WeakMap(); let handler; return { onYogaInit({ yoga }) { handler = createHandler({ ...handlerOptions, async onSubscribe(req, params) { const enveloped = yoga.getEnveloped({ ...ctxForReq.get(req.raw), request: req.raw, params, }); const document = enveloped.parse(params.query); const errors = enveloped.validate(enveloped.schema, document); if (errors.length > 0) { return { errors }; } const contextValue = await enveloped.contextFactory(); const executionArgs = { schema: enveloped.schema, document, contextValue, variableValues: params.variables, operationName: params.operationName, }; const operation = getOperationAST(document, params.operationName); const executeFn = operation?.operation === 'subscription' ? enveloped.subscribe : enveloped.execute; return executeFn(executionArgs); }, }, yoga.fetchAPI); }, async onRequest({ request, endResponse, serverContext }) { const [path, _search] = request.url.split('?'); if (path.endsWith(endpoint)) { ctxForReq.set(request, serverContext); endResponse(await handler(request)); } }, }; }