BaseFolder.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. import invokeMap from 'lodash/invokeMap';
  2. import Node from './Node';
  3. export default class BaseFolder extends Node {
  4. constructor(name, parent) {
  5. super(name, parent);
  6. this.children = Object.create(null);
  7. }
  8. get src() {
  9. if (!Object.prototype.hasOwnProperty.call(this, '_src')) {
  10. this._src = this.walk((node, src) => (src += node.src || ''), '', false);
  11. }
  12. return this._src;
  13. }
  14. get size() {
  15. if (!Object.prototype.hasOwnProperty.call(this, '_size')) {
  16. this._size = this.walk((node, size) => size + node.size, 0, false);
  17. }
  18. return this._size;
  19. }
  20. getChild(name) {
  21. return this.children[name];
  22. }
  23. addChildModule(module) {
  24. const {name} = module;
  25. const currentChild = this.children[name];
  26. // For some reason we already have this node in children and it's a folder.
  27. if (currentChild && currentChild instanceof BaseFolder) {
  28. return;
  29. }
  30. if (currentChild) {
  31. // We already have this node in children and it's a module.
  32. // Merging it's data.
  33. currentChild.mergeData(module.data);
  34. } else {
  35. // Pushing new module
  36. module.parent = this;
  37. this.children[name] = module;
  38. }
  39. delete this._size;
  40. delete this._src;
  41. }
  42. addChildFolder(folder) {
  43. folder.parent = this;
  44. this.children[folder.name] = folder;
  45. delete this._size;
  46. delete this._src;
  47. return folder;
  48. }
  49. walk(walker, state = {}, deep = true) {
  50. let stopped = false;
  51. Object.values(this.children).forEach(child => {
  52. if (deep && child.walk) {
  53. state = child.walk(walker, state, stop);
  54. } else {
  55. state = walker(child, state, stop);
  56. }
  57. if (stopped) {
  58. return false;
  59. }
  60. return undefined;
  61. });
  62. return state;
  63. function stop(finalState) {
  64. stopped = true;
  65. return finalState;
  66. }
  67. }
  68. mergeNestedFolders() {
  69. if (!this.isRoot) {
  70. let childNames;
  71. while ((childNames = Object.keys(this.children)).length === 1) {
  72. const childName = childNames[0];
  73. const onlyChild = this.children[childName];
  74. if (onlyChild instanceof this.constructor) {
  75. this.name += `/${onlyChild.name}`;
  76. this.children = onlyChild.children;
  77. } else {
  78. break;
  79. }
  80. }
  81. }
  82. this.walk(
  83. child => {
  84. child.parent = this;
  85. if (child.mergeNestedFolders) {
  86. child.mergeNestedFolders();
  87. }
  88. },
  89. null,
  90. false
  91. );
  92. }
  93. toChartData() {
  94. return {
  95. label: this.name,
  96. path: this.path,
  97. statSize: this.size,
  98. groups: invokeMap(this.children, 'toChartData'),
  99. };
  100. }
  101. }