UNPKG

@graphql-mesh/plugin-live-query

Version:
79 lines (75 loc) 3.86 kB
import { useLiveQuery } from '@envelop/live-query'; import { InMemoryLiveQueryStore } from '@n1ru4l/in-memory-live-query-store'; import { getInterpolatedStringFactory } from '@graphql-mesh/string-interpolation'; import { getOperationAST, TypeInfo, visit, visitWithTypeInfo } from 'graphql'; function useInvalidateByResult(params) { const liveQueryInvalidationFactoryMap = new Map(); params.invalidations.forEach(liveQueryInvalidation => { const rawInvalidationPaths = liveQueryInvalidation.invalidate; const factories = rawInvalidationPaths.map(rawInvalidationPath => getInterpolatedStringFactory(rawInvalidationPath)); liveQueryInvalidationFactoryMap.set(liveQueryInvalidation.field, factories); }); return { onExecute() { return { onExecuteDone({ args: executionArgs, result }) { queueMicrotask(() => { const { schema, document, operationName, rootValue, contextValue } = executionArgs; const operationAST = getOperationAST(document, operationName); if (!operationAST) { throw new Error(`Operation couldn't be found`); } const typeInfo = new TypeInfo(schema); visit(operationAST, visitWithTypeInfo(typeInfo, { Field: () => { const parentType = typeInfo.getParentType(); const fieldDef = typeInfo.getFieldDef(); const path = `${parentType.name}.${fieldDef.name}`; if (liveQueryInvalidationFactoryMap.has(path)) { const invalidationPathFactories = liveQueryInvalidationFactoryMap.get(path); const invalidationPaths = invalidationPathFactories.map(invalidationPathFactory => invalidationPathFactory({ root: rootValue, context: contextValue, env: process.env, result, })); params.liveQueryStore .invalidate(invalidationPaths) .catch((e) => params.logger.warn(`Invalidation failed for ${path}: ${e.message}`)); } }, })); }); }, }; }, }; } function useMeshLiveQuery(options) { var _a; options.logger.debug(`Creating Live Query Store`); const liveQueryStore = new InMemoryLiveQueryStore({ includeIdentifierExtension: true, }); (_a = options.polling) === null || _a === void 0 ? void 0 : _a.forEach(pollingConfig => { const interval = setInterval(() => { liveQueryStore .invalidate(pollingConfig.invalidate) .catch((e) => options.logger.warn(`Invalidation failed for ${pollingConfig.invalidate}: ${e.message}`)); }, pollingConfig.interval); const id = options.pubsub.subscribe('destroy', () => { clearInterval(interval); options.pubsub.unsubscribe(id); }); }); return { onPluginInit({ addPlugin }) { var _a; addPlugin(useLiveQuery({ liveQueryStore })); if ((_a = options.invalidations) === null || _a === void 0 ? void 0 : _a.length) { addPlugin(useInvalidateByResult({ liveQueryStore, invalidations: options.invalidations, logger: options.logger })); } }, }; } export default useMeshLiveQuery;