@graphql-yoga/plugin-graphql-sse
Version:
GraphQL over Server-Sent Events Protocol plugin for GraphQL Yoga.
53 lines (52 loc) • 2.39 kB
JavaScript
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));
}
},
};
}