@graphql-mesh/plugin-live-query
Version:
79 lines (75 loc) • 3.86 kB
JavaScript
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;