graphql-modules
Version:
Create reusable, maintainable, testable and extendable GraphQL modules
82 lines (81 loc) • 3.46 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.apolloExecutorCreator = apolloExecutorCreator;
exports.apolloSchemaCreator = apolloSchemaCreator;
const wrap_1 = require("@graphql-tools/wrap");
const graphql_1 = require("graphql");
const utils_1 = require("../shared/utils");
const CONTEXT_ID = Symbol.for('context-id');
function apolloExecutorCreator({ createExecution, }) {
return function createApolloExecutor(options) {
const executor = createExecution(options);
return async function executorAdapter(requestContext) {
return executor({
schema: requestContext.schema,
document: requestContext.document,
operationName: requestContext.operationName,
variableValues: requestContext.request.variables,
contextValue: requestContext.context,
});
};
};
}
function apolloSchemaCreator({ createSubscription, contextBuilder, schema, }) {
const createApolloSchema = () => {
const sessions = {};
const subscription = createSubscription();
function getSession(ctx, { context, ɵdestroy: destroy }) {
if (!ctx[CONTEXT_ID]) {
ctx[CONTEXT_ID] = (0, utils_1.uniqueId)((id) => !sessions[id]);
sessions[ctx[CONTEXT_ID]] = {
count: 0,
session: {
context,
destroy() {
if (--sessions[ctx[CONTEXT_ID]].count === 0) {
destroy();
delete sessions[ctx[CONTEXT_ID]];
delete ctx[CONTEXT_ID];
}
},
},
};
}
sessions[ctx[CONTEXT_ID]].count++;
return sessions[ctx[CONTEXT_ID]].session;
}
return (0, wrap_1.wrapSchema)({
schema,
batch: true,
executor(input) {
if (input.operationType === 'subscription') {
return subscription({
schema,
document: input.document,
variableValues: input.variables,
contextValue: input.context,
rootValue: input.rootValue,
operationName: input.operationName,
});
}
// Create an execution context and run within it
return contextBuilder(input.context).runWithContext((env) => {
const { context, destroy } = getSession(input.context, env);
// It's important to wrap the executeFn within a promise
// so we can easily control the end of execution (with finally)
return Promise.resolve()
.then(() => (0, graphql_1.execute)({
schema,
document: input.document,
contextValue: context,
variableValues: input.variables,
rootValue: input.rootValue,
operationName: input.operationName,
}))
.finally(destroy);
});
},
});
};
return createApolloSchema;
}