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); // Populate metadata and build a dependency graph. for (var _i2 = 0, _documentAST$definiti2 = documentAST.definitions; _i2 < _documentAST$definiti2.length; _i2++) { var definitionNode = _documentAST$definiti2[_i2]; switch (definitionNode.kind) { case Kind.OPERATION_DEFINITION: operations.push(definitionNode); break; case Kind.FRAGMENT_DEFINITION: depGraph[definitionNode.name.value] = collectDependencies(definitionNode.selectionSet); break; } } // 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(_i4) { var operation = operations[_i4]; var dependencies = new Set(); for (var _i6 = 0, _collectDependencies2 = collectDependencies(operation.selectionSet); _i6 < _collectDependencies2.length; _i6++) { var fragmentName = _collectDependencies2[_i6]; collectTransitiveDependencies(dependencies, depGraph, fragmentName); } // Provides the empty string for anonymous operations. var operationName = operation.name ? operation.name.value : ''; // 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.has(node.name.value); }) }; }; for (var _i4 = 0; _i4 < operations.length; _i4++) { _loop(_i4); } return separatedDocumentASTs; } // From a dependency graph, collects a list of transitive dependencies by // recursing through a dependency graph. function collectTransitiveDependencies(collected, depGraph, fromName) { if (!collected.has(fromName)) { collected.add(fromName); var immediateDeps = depGraph[fromName]; if (immediateDeps !== undefined) { for (var _i8 = 0; _i8 < immediateDeps.length; _i8++) { var toName = immediateDeps[_i8]; collectTransitiveDependencies(collected, depGraph, toName); } } } } function collectDependencies(selectionSet) { var dependencies = []; visit(selectionSet, { FragmentSpread: function FragmentSpread(node) { dependencies.push(node.name.value); } }); return dependencies; }