separateOperations.js 3.0 KB

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