import { Kind } from "../language/kinds.mjs"; import { visit } from "../language/visitor.mjs"; /** * separateOperations accepts a single AST document which may contain many * operations and fragments and returns a collection of AST documents each of * which contains a single operation as well the fragment definitions it * refers to. */ export function separateOperations(documentAST) { var operations = []; var depGraph = Object.create(null); var fromName; // Populate metadata and build a dependency graph. visit(documentAST, { OperationDefinition: function OperationDefinition(node) { fromName = opName(node); operations.push(node); }, FragmentDefinition: function FragmentDefinition(node) { fromName = node.name.value; }, FragmentSpread: function FragmentSpread(node) { var toName = node.name.value; var dependents = depGraph[fromName]; if (dependents === undefined) { dependents = depGraph[fromName] = Object.create(null); } dependents[toName] = true; } }); // For each operation, produce a new synthesized AST which includes only what // is necessary for completing that operation. var separatedDocumentASTs = Object.create(null); var _loop = function _loop(_i2) { var operation = operations[_i2]; var operationName = opName(operation); var dependencies = Object.create(null); collectTransitiveDependencies(dependencies, depGraph, operationName); // The list of definition nodes to be included for this operation, sorted // to retain the same order as the original document. separatedDocumentASTs[operationName] = { kind: Kind.DOCUMENT, definitions: documentAST.definitions.filter(function (node) { return node === operation || node.kind === Kind.FRAGMENT_DEFINITION && dependencies[node.name.value]; }) }; }; for (var _i2 = 0; _i2 < operations.length; _i2++) { _loop(_i2); } return separatedDocumentASTs; } // Provides the empty string for anonymous operations. function opName(operation) { return operation.name ? operation.name.value : ''; } // From a dependency graph, collects a list of transitive dependencies by // recursing through a dependency graph. function collectTransitiveDependencies(collected, depGraph, fromName) { var immediateDeps = depGraph[fromName]; if (immediateDeps) { for (var _i4 = 0, _Object$keys2 = Object.keys(immediateDeps); _i4 < _Object$keys2.length; _i4++) { var toName = _Object$keys2[_i4]; if (!collected[toName]) { collected[toName] = true; collectTransitiveDependencies(collected, depGraph, toName); } } } }