@apollo/gateway
Version:
112 lines • 4.42 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.IntrospectAndCompose = void 0;
const resolvable_1 = __importDefault(require("@josephg/resolvable"));
const loadServicesFromRemoteEndpoint_1 = require("./loadServicesFromRemoteEndpoint");
const composition_1 = require("@apollo/composition");
class IntrospectAndCompose {
constructor(options) {
this.serviceSdlCache = new Map();
this.timerRef = null;
this.config = options;
this.state = { phase: 'initialized' };
}
async initialize({ update, getDataSource, healthCheck }) {
this.update = update;
if (this.config.subgraphHealthCheck) {
this.healthCheck = healthCheck;
}
this.subgraphs = this.config.subgraphs.map((subgraph) => ({
...subgraph,
dataSource: getDataSource(subgraph),
}));
let initialSupergraphSdl = null;
try {
initialSupergraphSdl = await this.updateSupergraphSdl();
}
catch (e) {
this.logUpdateFailure(e);
throw e;
}
if (this.config.pollIntervalInMs) {
this.beginPolling();
}
return {
supergraphSdl: initialSupergraphSdl,
cleanup: async () => {
if (this.state.phase === 'polling') {
await this.state.pollingPromise;
}
this.state = { phase: 'stopped' };
if (this.timerRef) {
clearTimeout(this.timerRef);
this.timerRef = null;
}
},
};
}
async updateSupergraphSdl() {
var _a;
const result = await (0, loadServicesFromRemoteEndpoint_1.loadServicesFromRemoteEndpoint)({
serviceList: this.subgraphs,
getServiceIntrospectionHeaders: async (service) => {
return typeof this.config.introspectionHeaders === 'function'
? await this.config.introspectionHeaders(service)
: this.config.introspectionHeaders;
},
serviceSdlCache: this.serviceSdlCache,
});
if (!result.isNewSchema) {
return null;
}
const supergraphSdl = this.createSupergraphFromSubgraphList(result.serviceDefinitions);
await ((_a = this.healthCheck) === null || _a === void 0 ? void 0 : _a.call(this, supergraphSdl));
return supergraphSdl;
}
createSupergraphFromSubgraphList(subgraphs) {
const compositionResult = (0, composition_1.composeServices)(subgraphs);
if (compositionResult.errors) {
const { errors } = compositionResult;
throw Error("A valid schema couldn't be composed. The following composition errors were found:\n" +
errors.map((e) => '\t' + e.message).join('\n'));
}
else {
const { supergraphSdl } = compositionResult;
return supergraphSdl;
}
}
beginPolling() {
this.state = { phase: 'polling' };
this.poll();
}
poll() {
this.timerRef = setTimeout(async () => {
var _a;
if (this.state.phase === 'polling') {
const pollingPromise = (0, resolvable_1.default)();
this.state.pollingPromise = pollingPromise;
try {
const maybeNewSupergraphSdl = await this.updateSupergraphSdl();
if (maybeNewSupergraphSdl) {
(_a = this.update) === null || _a === void 0 ? void 0 : _a.call(this, maybeNewSupergraphSdl);
}
}
catch (e) {
this.logUpdateFailure(e);
}
pollingPromise.resolve();
}
this.poll();
}, this.config.pollIntervalInMs);
}
logUpdateFailure(e) {
var _a, _b;
(_a = this.config.logger) === null || _a === void 0 ? void 0 : _a.error('IntrospectAndCompose failed to update supergraph with the following error: ' +
((_b = e.message) !== null && _b !== void 0 ? _b : e));
}
}
exports.IntrospectAndCompose = IntrospectAndCompose;
//# sourceMappingURL=index.js.map