UNPKG

2.99 kBJavaScriptView Raw
1/**
2 * Copyright (c) 2015-present, Facebook, Inc.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 *
7 *
8 */
9import { visit } from '../language/visitor';
10
11/**
12 * separateOperations accepts a single AST document which may contain many
13 * operations and fragments and returns a collection of AST documents each of
14 * which contains a single operation as well the fragment definitions it
15 * refers to.
16 */
17export function separateOperations(documentAST) {
18 var operations = [];
19 var fragments = Object.create(null);
20 var positions = new Map();
21 var depGraph = Object.create(null);
22 var fromName;
23 var idx = 0; // Populate metadata and build a dependency graph.
24
25 visit(documentAST, {
26 OperationDefinition: function OperationDefinition(node) {
27 fromName = opName(node);
28 operations.push(node);
29 positions.set(node, idx++);
30 },
31 FragmentDefinition: function FragmentDefinition(node) {
32 fromName = node.name.value;
33 fragments[fromName] = node;
34 positions.set(node, idx++);
35 },
36 FragmentSpread: function FragmentSpread(node) {
37 var toName = node.name.value;
38 (depGraph[fromName] || (depGraph[fromName] = Object.create(null)))[toName] = true;
39 }
40 }); // For each operation, produce a new synthesized AST which includes only what
41 // is necessary for completing that operation.
42
43 var separatedDocumentASTs = Object.create(null);
44
45 for (var _i = 0; _i < operations.length; _i++) {
46 var operation = operations[_i];
47 var operationName = opName(operation);
48 var dependencies = Object.create(null);
49 collectTransitiveDependencies(dependencies, depGraph, operationName); // The list of definition nodes to be included for this operation, sorted
50 // to retain the same order as the original document.
51
52 var definitions = [operation];
53
54 var _arr = Object.keys(dependencies);
55
56 for (var _i2 = 0; _i2 < _arr.length; _i2++) {
57 var name = _arr[_i2];
58 definitions.push(fragments[name]);
59 }
60
61 definitions.sort(function (n1, n2) {
62 return (positions.get(n1) || 0) - (positions.get(n2) || 0);
63 });
64 separatedDocumentASTs[operationName] = {
65 kind: 'Document',
66 definitions: definitions
67 };
68 }
69
70 return separatedDocumentASTs;
71}
72
73// Provides the empty string for anonymous operations.
74function opName(operation) {
75 return operation.name ? operation.name.value : '';
76} // From a dependency graph, collects a list of transitive dependencies by
77// recursing through a dependency graph.
78
79
80function collectTransitiveDependencies(collected, depGraph, fromName) {
81 var immediateDeps = depGraph[fromName];
82
83 if (immediateDeps) {
84 var _arr2 = Object.keys(immediateDeps);
85
86 for (var _i3 = 0; _i3 < _arr2.length; _i3++) {
87 var toName = _arr2[_i3];
88
89 if (!collected[toName]) {
90 collected[toName] = true;
91 collectTransitiveDependencies(collected, depGraph, toName);
92 }
93 }
94 }
95}
\No newline at end of file