@graphql-mesh/plugin-live-query
Version:
84 lines (79 loc) • 4.12 kB
JavaScript
;
const liveQuery = require('@envelop/live-query');
const inMemoryLiveQueryStore = require('@n1ru4l/in-memory-live-query-store');
const stringInterpolation = require('@graphql-mesh/string-interpolation');
const graphql = require('graphql');
const crossHelpers = require('@graphql-mesh/cross-helpers');
function useInvalidateByResult(params) {
const liveQueryInvalidationFactoryMap = new Map();
params.invalidations.forEach(liveQueryInvalidation => {
const rawInvalidationPaths = liveQueryInvalidation.invalidate;
const factories = rawInvalidationPaths.map(rawInvalidationPath => stringInterpolation.getInterpolatedStringFactory(rawInvalidationPath));
liveQueryInvalidationFactoryMap.set(liveQueryInvalidation.field, factories);
});
return {
onExecute() {
return {
onExecuteDone({ args: executionArgs, result }) {
const { schema, document, operationName, variableValues, rootValue, contextValue } = executionArgs;
const operationAST = graphql.getOperationAST(document, operationName);
if (!operationAST) {
throw new Error(`Operation couldn't be found`);
}
const typeInfo = new graphql.TypeInfo(schema);
graphql.visit(operationAST, graphql.visitWithTypeInfo(typeInfo, {
Field: fieldNode => {
const parentType = typeInfo.getParentType();
const fieldDef = typeInfo.getFieldDef();
const path = `${parentType.name}.${fieldDef.name}`;
if (liveQueryInvalidationFactoryMap.has(path)) {
const invalidationPathFactories = liveQueryInvalidationFactoryMap.get(path);
const args = graphql.getArgumentValues(fieldDef, fieldNode, variableValues);
const invalidationPaths = invalidationPathFactories.map(invalidationPathFactory => invalidationPathFactory({
root: rootValue,
args,
context: contextValue,
env: process.env,
result,
}));
params.pubsub.publish('live-query:invalidate', invalidationPaths);
}
},
}));
},
};
},
};
}
function useMeshLiveQuery(options) {
options.logger.debug(`Creating Live Query Store`);
const liveQueryStore = new inMemoryLiveQueryStore.InMemoryLiveQueryStore({
buildResourceIdentifier: options.resourceIdentifier != null
? function resourceIdentifierFactory({ typename, id }) {
return stringInterpolation.stringInterpolator.parse(options.resourceIdentifier, {
typename,
id,
env: crossHelpers.process.env,
});
}
: inMemoryLiveQueryStore.defaultResourceIdentifierNormalizer,
includeIdentifierExtension: options.includeIdentifierExtension != null ? options.includeIdentifierExtension : crossHelpers.process.env.DEBUG === '1',
idFieldName: options.idFieldName,
indexBy: options.indexBy,
});
options.pubsub.subscribe('live-query:invalidate', (identifiers) => liveQueryStore.invalidate(identifiers));
return {
onPluginInit({ addPlugin }) {
var _a;
addPlugin(liveQuery.useLiveQuery({ liveQueryStore }));
if ((_a = options.invalidations) === null || _a === void 0 ? void 0 : _a.length) {
addPlugin(useInvalidateByResult({
pubsub: options.pubsub,
invalidations: options.invalidations,
logger: options.logger,
}));
}
},
};
}
module.exports = useMeshLiveQuery;