UNPKG

@graphql-tools/executor-envelop

Version:

A set of utils for faster development of GraphQL tools

109 lines (108 loc) 3.93 kB
import { isPromise } from '@graphql-tools/utils'; import { schemaFromExecutor } from '@graphql-tools/wrap'; export function useExecutor(executor, opts) { const EMPTY_ARRAY = Object.freeze([]); function executorToExecuteFn(executionArgs) { return executor({ document: executionArgs.document, rootValue: executionArgs.rootValue, context: executionArgs.contextValue, variables: executionArgs.variableValues, operationName: executionArgs.operationName, }); } const pluginCtx = { schema$: undefined, schema: undefined, schemaSetPromise$: undefined, skipIntrospection: false, }; if (opts?.polling) { setInterval(() => { pluginCtx.schema$ = undefined; pluginCtx.schema = undefined; }, opts.polling); } function ensureSchema(ctx) { if (pluginCtx.skipIntrospection) { return; } try { if (!pluginCtx.schema && !pluginCtx.schemaSetPromise$) { pluginCtx.schema$ ||= schemaFromExecutor(executor, ctx, opts); if (isPromise(pluginCtx.schema$)) { pluginCtx.schemaSetPromise$ = pluginCtx.schema$.then(newSchema => { pluginCtx.schema = newSchema; }).catch?.(err => { console.warn(`Introspection failed, skipping introspection due to the following errors;\n`, err); pluginCtx.skipIntrospection = true; }); } else { pluginCtx.schema = pluginCtx.schema$; } } } catch (err) { pluginCtx.skipIntrospection = true; console.warn(`Introspection failed, skipping introspection due to the following errors;\n`, err); } } return { onEnveloped({ context, setSchema }) { ensureSchema(context); if (pluginCtx.schema) { setSchema(pluginCtx.schema); } }, onContextBuilding() { ensureSchema(); if (pluginCtx.schemaSetPromise$) { return pluginCtx.schemaSetPromise$; } }, onExecute({ args, setExecuteFn }) { if (args.schema) { pluginCtx.schema = args.schema; pluginCtx.schema$ = pluginCtx.schema; } ensureSchema(args.contextValue); if (isPromise(pluginCtx.schemaSetPromise$)) { return pluginCtx.schemaSetPromise$.then(() => { setExecuteFn(executorToExecuteFn); }); } setExecuteFn(executorToExecuteFn); }, onSubscribe({ args, setSubscribeFn }) { if (args.schema) { pluginCtx.schema = args.schema; pluginCtx.schema$ = pluginCtx.schema; } ensureSchema(args.contextValue); if (isPromise(pluginCtx.schemaSetPromise$)) { return pluginCtx.schemaSetPromise$.then(() => { setSubscribeFn(executorToExecuteFn); }); } setSubscribeFn(executorToExecuteFn); }, onValidate({ params, context, setResult }) { if (params.schema) { pluginCtx.schema = params.schema; pluginCtx.schema$ = pluginCtx.schema; } ensureSchema(context); if (pluginCtx.schema?.[Symbol.toStringTag] !== 'GraphQLSchema') { setResult(EMPTY_ARRAY); } }, pluginCtx, ensureSchema, invalidateUnifiedGraph() { pluginCtx.schema$ = undefined; pluginCtx.schema = undefined; pluginCtx.skipIntrospection = false; }, }; }