Spaces:
Paused
Paused
| ; | |
| Object.defineProperty(exports, '__esModule', { | |
| value: true, | |
| }); | |
| exports.separateOperations = separateOperations; | |
| var _kinds = require('../language/kinds.js'); | |
| var _visitor = require('../language/visitor.js'); | |
| /** | |
| * 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. | |
| */ | |
| function separateOperations(documentAST) { | |
| const operations = []; | |
| const depGraph = Object.create(null); // Populate metadata and build a dependency graph. | |
| for (const definitionNode of documentAST.definitions) { | |
| switch (definitionNode.kind) { | |
| case _kinds.Kind.OPERATION_DEFINITION: | |
| operations.push(definitionNode); | |
| break; | |
| case _kinds.Kind.FRAGMENT_DEFINITION: | |
| depGraph[definitionNode.name.value] = collectDependencies( | |
| definitionNode.selectionSet, | |
| ); | |
| break; | |
| default: // ignore non-executable definitions | |
| } | |
| } // For each operation, produce a new synthesized AST which includes only what | |
| // is necessary for completing that operation. | |
| const separatedDocumentASTs = Object.create(null); | |
| for (const operation of operations) { | |
| const dependencies = new Set(); | |
| for (const fragmentName of collectDependencies(operation.selectionSet)) { | |
| collectTransitiveDependencies(dependencies, depGraph, fragmentName); | |
| } // Provides the empty string for anonymous operations. | |
| const 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: _kinds.Kind.DOCUMENT, | |
| definitions: documentAST.definitions.filter( | |
| (node) => | |
| node === operation || | |
| (node.kind === _kinds.Kind.FRAGMENT_DEFINITION && | |
| dependencies.has(node.name.value)), | |
| ), | |
| }; | |
| } | |
| 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); | |
| const immediateDeps = depGraph[fromName]; | |
| if (immediateDeps !== undefined) { | |
| for (const toName of immediateDeps) { | |
| collectTransitiveDependencies(collected, depGraph, toName); | |
| } | |
| } | |
| } | |
| } | |
| function collectDependencies(selectionSet) { | |
| const dependencies = []; | |
| (0, _visitor.visit)(selectionSet, { | |
| FragmentSpread(node) { | |
| dependencies.push(node.name.value); | |
| }, | |
| }); | |
| return dependencies; | |
| } | |