@envelop/graphql-jit
Version:
This plugins replaces the original `execute` of GraphQL with [`graphql-jit`](https://github.com/zalando-incubator/graphql-jit).
70 lines (69 loc) • 2.93 kB
JavaScript
/* eslint-disable no-console */
import { makeExecute, makeSubscribe } from '@envelop/core';
import { Source } from 'graphql';
import { compileQuery, isCompiledQuery } from 'graphql-jit';
import LRU from 'lru-cache';
const DEFAULT_MAX = 1000;
const DEFAULT_TTL = 3600000;
export const useGraphQlJit = (compilerOptions = {}, pluginOptions = {}) => {
const documentSourceMap = new WeakMap();
const jitCache = typeof pluginOptions.cache !== 'undefined'
? pluginOptions.cache
: new LRU({ max: DEFAULT_MAX, maxAge: DEFAULT_TTL });
function getCacheEntry(args) {
let cacheEntry;
const documentSource = documentSourceMap.get(args.document);
if (documentSource) {
cacheEntry = jitCache.get(documentSource);
}
if (!cacheEntry) {
const compilationResult = compileQuery(args.schema, args.document, args.operationName ?? undefined, compilerOptions);
if (!isCompiledQuery(compilationResult)) {
if (pluginOptions?.onError) {
pluginOptions.onError(compilationResult);
}
else {
console.error(compilationResult);
}
cacheEntry = {
query: () => compilationResult,
};
}
else {
cacheEntry = compilationResult;
}
if (documentSource) {
jitCache.set(documentSource, cacheEntry);
}
}
return cacheEntry;
}
return {
onParse({ params: { source } }) {
const key = source instanceof Source ? source.body : source;
return ({ result }) => {
if (!result || result instanceof Error)
return;
documentSourceMap.set(result, key);
};
},
async onExecute({ args, setExecuteFn }) {
if (!pluginOptions.enableIf || (pluginOptions.enableIf && (await pluginOptions.enableIf(args)))) {
setExecuteFn(makeExecute(function jitExecutor(args) {
const cacheEntry = getCacheEntry(args);
return cacheEntry.query(args.rootValue, args.contextValue, args.variableValues);
}));
}
},
async onSubscribe({ args, setSubscribeFn }) {
if (!pluginOptions.enableIf || (pluginOptions.enableIf && (await pluginOptions.enableIf(args)))) {
setSubscribeFn(makeSubscribe(async function jitSubscriber(args) {
const cacheEntry = getCacheEntry(args);
return cacheEntry.subscribe
? cacheEntry.subscribe(args.rootValue, args.contextValue, args.variableValues)
: cacheEntry.query(args.rootValue, args.contextValue, args.variableValues);
}));
}
},
};
};