@graphql-mesh/plugin-live-query
Version:
86 lines (85 loc) • 4.44 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.useInvalidateByResult = useInvalidateByResult;
const graphql_1 = require("graphql");
const string_interpolation_1 = require("@graphql-mesh/string-interpolation");
const types_1 = require("@graphql-mesh/types");
const disposablestack_1 = require("@whatwg-node/disposablestack");
function useInvalidateByResult(params) {
const liveQueryInvalidationFactoryMap = new Map();
const timers = new Set();
const pubsub = (0, types_1.toMeshPubSub)(params.pubsub);
if (!pubsub) {
throw new Error(`Live Query plugin requires a pubsub instance.`);
}
for (const liveQueryInvalidation of params.invalidations) {
if (liveQueryInvalidation.invalidate.length === 0) {
params.logger.warn(`Invalidation paths are empty for live query invalidation config: ${JSON.stringify(liveQueryInvalidation)}. Skipping this invalidation config.`);
continue;
}
const rawInvalidationPaths = liveQueryInvalidation.invalidate;
const factories = rawInvalidationPaths.map(rawInvalidationPath => (0, string_interpolation_1.getInterpolatedStringFactory)(rawInvalidationPath));
// Set up polling-based invalidation if pollingInterval is provided
if (liveQueryInvalidation.pollingInterval != null) {
if (liveQueryInvalidation.pollingInterval <= 0) {
throw new Error(`Polling interval must be a positive integer. Received: ${liveQueryInvalidation.pollingInterval}`);
}
timers.add(setInterval(() => {
pubsub.publish('live-query:invalidate', liveQueryInvalidation.invalidate);
}, liveQueryInvalidation.pollingInterval));
}
// Set up mutation-based invalidation if field is provided
if (liveQueryInvalidation.field != null) {
let existingFactories = liveQueryInvalidationFactoryMap.get(liveQueryInvalidation.field);
if (!existingFactories) {
existingFactories = [];
liveQueryInvalidationFactoryMap.set(liveQueryInvalidation.field, existingFactories);
}
existingFactories.push(...factories);
}
}
const id = pubsub.subscribe('destroy', () => {
for (const timer of timers) {
clearInterval(timer);
}
pubsub.unsubscribe(id);
});
return {
onExecute() {
return {
onExecuteDone({ args: executionArgs, result }) {
const { schema, document, operationName, variableValues, rootValue, contextValue } = executionArgs;
const operationAST = (0, graphql_1.getOperationAST)(document, operationName);
if (!operationAST) {
throw new Error(`Operation couldn't be found`);
}
const typeInfo = new graphql_1.TypeInfo(schema);
(0, graphql_1.visit)(operationAST, (0, graphql_1.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 = (0, graphql_1.getArgumentValues)(fieldDef, fieldNode, variableValues);
const invalidationPaths = invalidationPathFactories.map(invalidationPathFactory => invalidationPathFactory({
root: rootValue,
args,
context: contextValue,
env: process.env,
result,
}));
pubsub.publish('live-query:invalidate', invalidationPaths);
}
},
}));
},
};
},
[disposablestack_1.DisposableSymbols.dispose]() {
for (const timer of timers) {
clearInterval(timer);
}
},
};
}