graphql-modules
Version:
Create reusable, maintainable, testable and extendable GraphQL modules
52 lines (51 loc) • 2.28 kB
JavaScript
import { subscribe, } from 'graphql';
import { tapAsyncIterator, isAsyncIterable, isNotSchema, } from '../shared/utils';
export function subscriptionCreator({ contextBuilder, }) {
const createSubscription = (options) => {
// Custom or original subscribe function
const subscribeFn = (options === null || options === void 0 ? void 0 : options.subscribe) || subscribe;
return (argsOrSchema, document, rootValue, contextValue, variableValues, operationName, fieldResolver, subscribeFieldResolver) => {
function perform({ context, ɵdestroy: destroy, }) {
const subscriptionArgs = isNotSchema(argsOrSchema)
? {
...argsOrSchema,
contextValue: context,
}
: {
schema: argsOrSchema,
document: document,
rootValue,
contextValue: context,
variableValues,
operationName,
fieldResolver,
subscribeFieldResolver,
};
let isIterable = false;
// It's important to wrap the subscribeFn within a promise
// so we can easily control the end of subscription (with finally)
return Promise.resolve()
.then(() => subscribeFn(subscriptionArgs))
.then((sub) => {
if (isAsyncIterable(sub)) {
isIterable = true;
return tapAsyncIterator(sub, destroy);
}
return sub;
})
.finally(() => {
if (!isIterable) {
destroy();
}
});
}
if (options === null || options === void 0 ? void 0 : options.controller) {
return perform(options.controller);
}
return contextBuilder(isNotSchema(argsOrSchema)
? argsOrSchema.contextValue
: contextValue).runWithContext(perform);
};
};
return createSubscription;
}