store.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. import {computed, observable} from 'mobx';
  2. import localStorage from './localStorage';
  3. import {isChunkParsed, walkModules} from './utils';
  4. export class Store {
  5. cid = 0;
  6. sizes = new Set(['statSize', 'parsedSize', 'gzipSize']);
  7. @observable.ref allChunks;
  8. @observable.shallow selectedChunks;
  9. @observable searchQuery = '';
  10. @observable defaultSize;
  11. @observable selectedSize;
  12. @observable showConcatenatedModulesContent =
  13. localStorage.getItem('showConcatenatedModulesContent') === true;
  14. // constructor() {
  15. // observable.ref(this, 'allChunks');
  16. // observable.shallow(this, 'selectedChunks');
  17. // observable(this, 'searchQuery');
  18. // observable(this, 'defaultSize');
  19. // observable(this, 'selectedSize');
  20. // observable(this, 'showConcatenatedModulesContent');
  21. // }
  22. setModules(modules) {
  23. walkModules(modules, module => {
  24. module.cid = this.cid++;
  25. });
  26. this.allChunks = modules;
  27. this.selectedChunks = this.allChunks;
  28. }
  29. setEntrypoints(entrypoints) {
  30. this.entrypoints = entrypoints;
  31. }
  32. @computed get hasParsedSizes() {
  33. return this.allChunks.some(isChunkParsed);
  34. }
  35. @computed get activeSize() {
  36. const activeSize = this.selectedSize || this.defaultSize;
  37. if (!this.hasParsedSizes || !this.sizes.has(activeSize)) {
  38. return 'statSize';
  39. }
  40. return activeSize;
  41. }
  42. @computed get visibleChunks() {
  43. const visibleChunks = this.allChunks.filter(chunk =>
  44. this.selectedChunks.includes(chunk)
  45. );
  46. return this.filterModulesForSize(visibleChunks, this.activeSize);
  47. }
  48. @computed get allChunksSelected() {
  49. return this.visibleChunks.length === this.allChunks.length;
  50. }
  51. @computed get totalChunksSize() {
  52. return this.allChunks.reduce(
  53. (totalSize, chunk) => totalSize + (chunk[this.activeSize] || 0),
  54. 0
  55. );
  56. }
  57. @computed get searchQueryRegexp() {
  58. const query = this.searchQuery.trim();
  59. if (!query) {
  60. return null;
  61. }
  62. try {
  63. return new RegExp(query, 'iu');
  64. } catch (err) {
  65. return null;
  66. }
  67. }
  68. @computed get isSearching() {
  69. return !!this.searchQueryRegexp;
  70. }
  71. @computed get foundModulesByChunk() {
  72. if (!this.isSearching) {
  73. return [];
  74. }
  75. const query = this.searchQueryRegexp;
  76. return this.visibleChunks
  77. .map(chunk => {
  78. let foundGroups = [];
  79. walkModules(chunk.groups, module => {
  80. let weight = 0;
  81. /**
  82. * Splitting found modules/directories into groups:
  83. *
  84. * 1) Module with matched label (weight = 4)
  85. * 2) Directory with matched label (weight = 3)
  86. * 3) Module with matched path (weight = 2)
  87. * 4) Directory with matched path (weight = 1)
  88. */
  89. if (query.test(module.label)) {
  90. weight += 3;
  91. } else if (module.path && query.test(module.path)) {
  92. weight++;
  93. }
  94. if (!weight) {
  95. return;
  96. }
  97. if (!module.groups) {
  98. weight += 1;
  99. }
  100. const foundModules = (foundGroups[weight - 1] = foundGroups[weight - 1] || []);
  101. foundModules.push(module);
  102. });
  103. const {activeSize} = this;
  104. // Filtering out missing groups
  105. foundGroups = foundGroups.filter(Boolean).reverse();
  106. // Sorting each group by active size
  107. foundGroups.forEach(modules =>
  108. modules.sort((m1, m2) => m2[activeSize] - m1[activeSize])
  109. );
  110. return {
  111. chunk,
  112. modules: [].concat(...foundGroups),
  113. };
  114. })
  115. .filter(result => result.modules.length > 0)
  116. .sort((c1, c2) => c1.modules.length - c2.modules.length);
  117. }
  118. @computed get foundModules() {
  119. return this.foundModulesByChunk.reduce((arr, chunk) => arr.concat(chunk.modules), []);
  120. }
  121. @computed get hasFoundModules() {
  122. return this.foundModules.length > 0;
  123. }
  124. @computed get hasConcatenatedModules() {
  125. let result = false;
  126. walkModules(this.visibleChunks, module => {
  127. if (module.concatenated) {
  128. result = true;
  129. return false;
  130. }
  131. });
  132. return result;
  133. }
  134. @computed get foundModulesSize() {
  135. return this.foundModules.reduce((summ, module) => summ + module[this.activeSize], 0);
  136. }
  137. filterModulesForSize(modules, sizeProp) {
  138. return modules.reduce((filteredModules, module) => {
  139. if (module[sizeProp]) {
  140. if (module.groups) {
  141. const showContent = !module.concatenated || this.showConcatenatedModulesContent;
  142. module = {
  143. ...module,
  144. groups: showContent
  145. ? this.filterModulesForSize(module.groups, sizeProp)
  146. : null,
  147. };
  148. }
  149. module.weight = module[sizeProp];
  150. filteredModules.push(module);
  151. }
  152. return filteredModules;
  153. }, []);
  154. }
  155. }
  156. export const store = new Store();