UNPKG

2.92 kBJavaScriptView Raw
1import { Kind } from "../language/kinds.mjs";
2import { visit } from "../language/visitor.mjs";
3/**
4 * separateOperations accepts a single AST document which may contain many
5 * operations and fragments and returns a collection of AST documents each of
6 * which contains a single operation as well the fragment definitions it
7 * refers to.
8 */
9
10export function separateOperations(documentAST) {
11 var operations = [];
12 var depGraph = Object.create(null); // Populate metadata and build a dependency graph.
13
14 for (var _i2 = 0, _documentAST$definiti2 = documentAST.definitions; _i2 < _documentAST$definiti2.length; _i2++) {
15 var definitionNode = _documentAST$definiti2[_i2];
16
17 switch (definitionNode.kind) {
18 case Kind.OPERATION_DEFINITION:
19 operations.push(definitionNode);
20 break;
21
22 case Kind.FRAGMENT_DEFINITION:
23 depGraph[definitionNode.name.value] = collectDependencies(definitionNode.selectionSet);
24 break;
25 }
26 } // For each operation, produce a new synthesized AST which includes only what
27 // is necessary for completing that operation.
28
29
30 var separatedDocumentASTs = Object.create(null);
31
32 var _loop = function _loop(_i4) {
33 var operation = operations[_i4];
34 var dependencies = new Set();
35
36 for (var _i6 = 0, _collectDependencies2 = collectDependencies(operation.selectionSet); _i6 < _collectDependencies2.length; _i6++) {
37 var fragmentName = _collectDependencies2[_i6];
38 collectTransitiveDependencies(dependencies, depGraph, fragmentName);
39 } // Provides the empty string for anonymous operations.
40
41
42 var operationName = operation.name ? operation.name.value : ''; // The list of definition nodes to be included for this operation, sorted
43 // to retain the same order as the original document.
44
45 separatedDocumentASTs[operationName] = {
46 kind: Kind.DOCUMENT,
47 definitions: documentAST.definitions.filter(function (node) {
48 return node === operation || node.kind === Kind.FRAGMENT_DEFINITION && dependencies.has(node.name.value);
49 })
50 };
51 };
52
53 for (var _i4 = 0; _i4 < operations.length; _i4++) {
54 _loop(_i4);
55 }
56
57 return separatedDocumentASTs;
58}
59
60// From a dependency graph, collects a list of transitive dependencies by
61// recursing through a dependency graph.
62function collectTransitiveDependencies(collected, depGraph, fromName) {
63 if (!collected.has(fromName)) {
64 collected.add(fromName);
65 var immediateDeps = depGraph[fromName];
66
67 if (immediateDeps !== undefined) {
68 for (var _i8 = 0; _i8 < immediateDeps.length; _i8++) {
69 var toName = immediateDeps[_i8];
70 collectTransitiveDependencies(collected, depGraph, toName);
71 }
72 }
73 }
74}
75
76function collectDependencies(selectionSet) {
77 var dependencies = [];
78 visit(selectionSet, {
79 FragmentSpread: function FragmentSpread(node) {
80 dependencies.push(node.name.value);
81 }
82 });
83 return dependencies;
84}