UNPKG

2.84 kBJavaScriptView Raw
1import { visit } from '../language/visitor';
2
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 */
9export function separateOperations(documentAST) {
10 var operations = [];
11 var fragments = Object.create(null);
12 var positions = new Map();
13 var depGraph = Object.create(null);
14 var fromName;
15 var idx = 0; // Populate metadata and build a dependency graph.
16
17 visit(documentAST, {
18 OperationDefinition: function OperationDefinition(node) {
19 fromName = opName(node);
20 operations.push(node);
21 positions.set(node, idx++);
22 },
23 FragmentDefinition: function FragmentDefinition(node) {
24 fromName = node.name.value;
25 fragments[fromName] = node;
26 positions.set(node, idx++);
27 },
28 FragmentSpread: function FragmentSpread(node) {
29 var toName = node.name.value;
30 (depGraph[fromName] || (depGraph[fromName] = Object.create(null)))[toName] = true;
31 }
32 }); // For each operation, produce a new synthesized AST which includes only what
33 // is necessary for completing that operation.
34
35 var separatedDocumentASTs = Object.create(null);
36
37 for (var _i2 = 0; _i2 < operations.length; _i2++) {
38 var operation = operations[_i2];
39 var operationName = opName(operation);
40 var dependencies = Object.create(null);
41 collectTransitiveDependencies(dependencies, depGraph, operationName); // The list of definition nodes to be included for this operation, sorted
42 // to retain the same order as the original document.
43
44 var definitions = [operation];
45
46 for (var _i4 = 0, _Object$keys2 = Object.keys(dependencies); _i4 < _Object$keys2.length; _i4++) {
47 var name = _Object$keys2[_i4];
48 definitions.push(fragments[name]);
49 }
50
51 definitions.sort(function (n1, n2) {
52 return (positions.get(n1) || 0) - (positions.get(n2) || 0);
53 });
54 separatedDocumentASTs[operationName] = {
55 kind: 'Document',
56 definitions: definitions
57 };
58 }
59
60 return separatedDocumentASTs;
61}
62
63// Provides the empty string for anonymous operations.
64function opName(operation) {
65 return operation.name ? operation.name.value : '';
66} // From a dependency graph, collects a list of transitive dependencies by
67// recursing through a dependency graph.
68
69
70function collectTransitiveDependencies(collected, depGraph, fromName) {
71 var immediateDeps = depGraph[fromName];
72
73 if (immediateDeps) {
74 for (var _i6 = 0, _Object$keys4 = Object.keys(immediateDeps); _i6 < _Object$keys4.length; _i6++) {
75 var toName = _Object$keys4[_i6];
76
77 if (!collected[toName]) {
78 collected[toName] = true;
79 collectTransitiveDependencies(collected, depGraph, toName);
80 }
81 }
82 }
83}