UNPKG

@graphql-hive/yoga

Version:
188 lines (187 loc) • 9.53 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createSupergraphSDLFetcher = exports.createServicesFetcher = exports.createSchemaFetcher = exports.atLeastOnceSampler = void 0; exports.createHive = createHive; exports.useHive = useHive; const graphql_1 = require("graphql"); const graphql_yoga_1 = require("graphql-yoga"); const core_1 = require("@graphql-hive/core"); const plugin_persisted_operations_1 = require("@graphql-yoga/plugin-persisted-operations"); var core_2 = require("@graphql-hive/core"); Object.defineProperty(exports, "atLeastOnceSampler", { enumerable: true, get: function () { return core_2.atLeastOnceSampler; } }); Object.defineProperty(exports, "createSchemaFetcher", { enumerable: true, get: function () { return core_2.createSchemaFetcher; } }); Object.defineProperty(exports, "createServicesFetcher", { enumerable: true, get: function () { return core_2.createServicesFetcher; } }); Object.defineProperty(exports, "createSupergraphSDLFetcher", { enumerable: true, get: function () { return core_2.createSupergraphSDLFetcher; } }); function createHive(clientOrOptions) { return (0, core_1.createHive)(Object.assign(Object.assign({}, clientOrOptions), { agent: Object.assign({ name: 'hive-client-yoga' }, clientOrOptions.agent) })); } function useHive(clientOrOptions) { const parsedDocumentCache = (0, graphql_yoga_1._createLRUCache)(); let latestSchema = null; const contextualCache = new WeakMap(); let hive; let yoga; return { onYogaInit(payload) { yoga = payload.yoga; }, onSchemaChange({ schema }) { hive.reportSchema({ schema }); latestSchema = schema; }, onParams(context) { // we set the params if there is either a query or documentId in the request if ((context.params.query || 'documentId' in context.params) && latestSchema) { contextualCache.set(context.context, { callback: hive.collectUsage(), paramsArgs: context.params, }); } }, // since response-cache modifies the executed GraphQL document, we need to extract it after parsing. onParse(parseCtx) { return ctx => { if (ctx.result.kind === graphql_1.Kind.DOCUMENT) { const record = contextualCache.get(ctx.context); if (record) { record.parsedDocument = ctx.result; parsedDocumentCache.set(parseCtx.params.source, ctx.result); } } }; }, onExecute() { return { onExecuteDone({ args, result }) { var _a; const record = contextualCache.get(args.contextValue); if (!record) { return; } record.executionArgs = args; if (!(0, core_1.isAsyncIterable)(result)) { args.contextValue.waitUntil(record.callback(Object.assign(Object.assign({}, record.executionArgs), { document: (_a = record.parsedDocument) !== null && _a !== void 0 ? _a : record.executionArgs.document }), result, record.experimental__documentId)); return; } const errors = []; return { onNext(ctx) { if (!ctx.result.errors) { return; } errors.push(...ctx.result.errors); }, onEnd() { args.contextValue.waitUntil(record.callback(args, errors.length ? { errors } : {}, record.experimental__documentId)); }, }; }, }; }, onSubscribe(context) { const record = contextualCache.get(context.args.contextValue); return { onSubscribeResult() { const experimental__persistedDocumentHash = record === null || record === void 0 ? void 0 : record.experimental__documentId; hive.collectSubscriptionUsage({ args: context.args, experimental__persistedDocumentHash, }); }, }; }, onResultProcess({ serverContext, result }) { const record = contextualCache.get(serverContext); if (!record || Array.isArray(result) || (0, core_1.isAsyncIterable)(result) || record.executionArgs) { return; } // Report if execution was skipped due to response cache ( Symbol.for('servedFromResponseCache') in context.result) if (record.paramsArgs.query && latestSchema && Symbol.for('servedFromResponseCache') in result) { try { let document = parsedDocumentCache.get(record.paramsArgs.query); if (document === undefined) { document = (0, graphql_1.parse)(record.paramsArgs.query); parsedDocumentCache.set(record.paramsArgs.query, document); } serverContext.waitUntil(record.callback({ document, schema: latestSchema, variableValues: record.paramsArgs.variables, operationName: record.paramsArgs.operationName, contextValue: serverContext, }, result, record.experimental__documentId)); } catch (err) { yoga.logger.error(err); } } }, onPluginInit({ addPlugin }) { hive = (0, core_1.isHiveClient)(clientOrOptions) ? clientOrOptions : createHive(Object.assign(Object.assign({}, clientOrOptions), { agent: clientOrOptions.agent ? Object.assign({ logger: { // Hive Plugin should respect the given Yoga logger error: (...args) => yoga.logger.error(...args), info: (...args) => yoga.logger.info(...args), }, // Hive Plugin should respect the given FetchAPI, note that this is not `yoga.fetch` fetch: (...args) => yoga.fetchAPI.fetch(...args) }, clientOrOptions.agent) : undefined })); void hive.info(); const experimentalPersistedDocs = hive.experimental__persistedDocuments; if (experimentalPersistedDocs) { addPlugin((0, plugin_persisted_operations_1.usePersistedOperations)({ extractPersistedOperationId(body, request) { if ('documentId' in body && typeof body.documentId === 'string') { return body.documentId; } const documentId = new URL(request.url).searchParams.get('documentId'); if (documentId) { return documentId; } return null; }, async getPersistedOperation(key, _request, context) { const document = await experimentalPersistedDocs.resolve(key); // after we resolve the document we need to update the cache record to contain the resolved document if (document) { const record = contextualCache.get(context); if (record) { record.experimental__documentId = key; record.paramsArgs = Object.assign(Object.assign({}, record.paramsArgs), { query: document }); } } return document; }, allowArbitraryOperations(request) { return experimentalPersistedDocs.allowArbitraryDocuments(request); }, customErrors: { keyNotFound() { return new graphql_1.GraphQLError('Persisted document not found.', { extensions: { code: 'PERSISTED_DOCUMENT_NOT_FOUND' }, }); }, notFound() { return new graphql_1.GraphQLError('Persisted document not found.', { extensions: { code: 'PERSISTED_DOCUMENT_NOT_FOUND' }, }); }, persistedQueryOnly() { return new graphql_1.GraphQLError('No persisted document provided.', { extensions: { code: 'PERSISTED_DOCUMENT_REQUIRED' }, }); }, }, })); } }, onDispose() { if (hive[core_1.autoDisposeSymbol]) { return hive.dispose(); } }, }; }