UNPKG

@graphql-tools/batch-delegate

Version:

A set of utils for faster development of GraphQL tools

138 lines (130 loc) 4.66 kB
'use strict'; var delegate = require('@graphql-tools/delegate'); var utils = require('@graphql-tools/utils'); var promiseHelpers = require('@whatwg-node/promise-helpers'); var DataLoader = require('dataloader'); var graphql = require('graphql'); function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } var DataLoader__default = /*#__PURE__*/_interopDefault(DataLoader); const DEFAULT_ARGS_FROM_KEYS = (keys) => ({ ids: keys }); function createBatchFn(options) { const argsFromKeys = options.argsFromKeys ?? DEFAULT_ARGS_FROM_KEYS; const fieldName = options.fieldName ?? options.info.fieldName; const { valuesFromResults, lazyOptionsFn } = options; return function batchFn(keys) { return promiseHelpers.fakePromise( promiseHelpers.handleMaybePromise( () => delegate.delegateToSchema({ returnType: new graphql.GraphQLList( graphql.getNamedType(options.returnType || options.info.returnType) ), onLocatedError: (originalError) => { if (originalError.path == null) { return originalError; } const [pathFieldName, pathNumber, ...rest] = originalError.path; if (pathFieldName !== fieldName) { return originalError; } const pathNumberType = typeof pathNumber; if (pathNumberType !== "number") { return originalError; } return utils.relocatedError(originalError, [fieldName, ...rest]); }, args: argsFromKeys(keys), ...lazyOptionsFn == null ? options : lazyOptionsFn(options, keys) }), (results) => { if (results instanceof Error) { return keys.map(() => results); } const values = valuesFromResults == null ? results : valuesFromResults(results, keys); return Array.isArray(values) ? values : keys.map(() => values); } ) ); }; } const getLoadersMap = utils.memoize2(function getLoadersMap2(_context, _schema) { return /* @__PURE__ */ new Map(); }); const GLOBAL_CONTEXT = {}; const memoizedJsonStringify = utils.memoize1(function jsonStringify(value) { return JSON.stringify(value); }); const memoizedPrint = utils.memoize1(graphql.print); function defaultCacheKeyFn(key) { if (typeof key === "object") { return memoizedJsonStringify(key); } return key; } function getLoader(options) { const { schema, context, info, fieldName = info.fieldName, dataLoaderOptions, fieldNodes = info.fieldNodes[0] && delegate.getActualFieldNodes(info.fieldNodes[0]), selectionSet = fieldNodes?.[0]?.selectionSet, returnType = info.returnType, argsFromKeys = DEFAULT_ARGS_FROM_KEYS, key } = options; const loaders = getLoadersMap(context ?? GLOBAL_CONTEXT, schema); let cacheKey = fieldName; if (returnType) { const namedType = graphql.getNamedType(returnType); cacheKey += "@" + namedType.name; } if (selectionSet != null) { cacheKey += memoizedPrint(selectionSet); } const fieldNode = fieldNodes?.[0]; if (fieldNode?.arguments) { const args = argsFromKeys([key]); cacheKey += fieldNode.arguments.filter((arg) => arg.name.value in args).map((arg) => memoizedPrint(arg)).join(","); } let loader = loaders.get(cacheKey); if (loader === void 0) { const batchFn = createBatchFn(options); loader = new DataLoader__default.default(batchFn, { // Prevents the keys to be passed with the same structure cacheKeyFn: defaultCacheKeyFn, ...dataLoaderOptions }); loaders.set(cacheKey, loader); } return loader; } function batchDelegateToSchema(options) { const key = options.key; if (key == null) { return null; } else if (Array.isArray(key) && !key.length) { return []; } const loader = getLoader(options); return Array.isArray(key) ? loader.loadMany(key) : loader.load(key); } function createBatchDelegateFn(optionsOrArgsFromKeys, lazyOptionsFn, dataLoaderOptions, valuesFromResults) { return typeof optionsOrArgsFromKeys === "function" ? createBatchDelegateFnImpl({ argsFromKeys: optionsOrArgsFromKeys, lazyOptionsFn, dataLoaderOptions, valuesFromResults }) : createBatchDelegateFnImpl(optionsOrArgsFromKeys); } function createBatchDelegateFnImpl(options) { return (batchDelegateOptions) => { const loader = getLoader({ ...options, ...batchDelegateOptions }); return loader.load(batchDelegateOptions.key); }; } exports.batchDelegateToSchema = batchDelegateToSchema; exports.createBatchDelegateFn = createBatchDelegateFn;