@memlab/heap-analysis 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/README.md +11 -0
  2. package/dist/BaseAnalysis.d.ts +26 -0
  3. package/dist/BaseAnalysis.d.ts.map +1 -0
  4. package/dist/BaseAnalysis.js +112 -0
  5. package/dist/HeapAnalysisLoader.d.ts +19 -0
  6. package/dist/HeapAnalysisLoader.d.ts.map +1 -0
  7. package/dist/HeapAnalysisLoader.js +59 -0
  8. package/dist/PluginUtils.d.ts +48 -0
  9. package/dist/PluginUtils.d.ts.map +1 -0
  10. package/dist/PluginUtils.js +283 -0
  11. package/dist/__tests__/HeapAnalysis.test.d.ts +11 -0
  12. package/dist/__tests__/HeapAnalysis.test.d.ts.map +1 -0
  13. package/dist/__tests__/HeapAnalysis.test.js +32 -0
  14. package/dist/index.d.ts +23 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +41 -0
  17. package/dist/options/HeapAnalysisSnapshotDirectoryOption.d.ts +18 -0
  18. package/dist/options/HeapAnalysisSnapshotDirectoryOption.d.ts.map +1 -0
  19. package/dist/options/HeapAnalysisSnapshotDirectoryOption.js +50 -0
  20. package/dist/options/HeapAnalysisSnapshotFileOption.d.ts +18 -0
  21. package/dist/options/HeapAnalysisSnapshotFileOption.d.ts.map +1 -0
  22. package/dist/options/HeapAnalysisSnapshotFileOption.js +50 -0
  23. package/dist/plugins/CollectionsHoldingStaleAnalysis.d.ts +22 -0
  24. package/dist/plugins/CollectionsHoldingStaleAnalysis.d.ts.map +1 -0
  25. package/dist/plugins/CollectionsHoldingStaleAnalysis.js +132 -0
  26. package/dist/plugins/DetachedDOMElementAnalysis.d.ts +22 -0
  27. package/dist/plugins/DetachedDOMElementAnalysis.d.ts.map +1 -0
  28. package/dist/plugins/DetachedDOMElementAnalysis.js +53 -0
  29. package/dist/plugins/GlobalVariableAnalysis/BuiltInGlobalVariables.d.ts +13 -0
  30. package/dist/plugins/GlobalVariableAnalysis/BuiltInGlobalVariables.d.ts.map +1 -0
  31. package/dist/plugins/GlobalVariableAnalysis/BuiltInGlobalVariables.js +1073 -0
  32. package/dist/plugins/GlobalVariableAnalysis/GlobalVariableAnalysis.d.ts +22 -0
  33. package/dist/plugins/GlobalVariableAnalysis/GlobalVariableAnalysis.d.ts.map +1 -0
  34. package/dist/plugins/GlobalVariableAnalysis/GlobalVariableAnalysis.js +78 -0
  35. package/dist/plugins/ObjectFanoutAnalysis.d.ts +21 -0
  36. package/dist/plugins/ObjectFanoutAnalysis.d.ts.map +1 -0
  37. package/dist/plugins/ObjectFanoutAnalysis.js +69 -0
  38. package/dist/plugins/ObjectShallowAnalysis.d.ts +42 -0
  39. package/dist/plugins/ObjectShallowAnalysis.d.ts.map +1 -0
  40. package/dist/plugins/ObjectShallowAnalysis.js +233 -0
  41. package/dist/plugins/ObjectShapeAnalysis.d.ts +20 -0
  42. package/dist/plugins/ObjectShapeAnalysis.d.ts.map +1 -0
  43. package/dist/plugins/ObjectShapeAnalysis.js +45 -0
  44. package/dist/plugins/ObjectSizeAnalysis.d.ts +20 -0
  45. package/dist/plugins/ObjectSizeAnalysis.d.ts.map +1 -0
  46. package/dist/plugins/ObjectSizeAnalysis.js +45 -0
  47. package/dist/plugins/ObjectUnboundGrowthAnalysis.d.ts +20 -0
  48. package/dist/plugins/ObjectUnboundGrowthAnalysis.d.ts.map +1 -0
  49. package/dist/plugins/ObjectUnboundGrowthAnalysis.js +47 -0
  50. package/dist/plugins/ShapeUnboundGrowthAnalysis.d.ts +42 -0
  51. package/dist/plugins/ShapeUnboundGrowthAnalysis.d.ts.map +1 -0
  52. package/dist/plugins/ShapeUnboundGrowthAnalysis.js +164 -0
  53. package/dist/plugins/StringAnalysis.d.ts +40 -0
  54. package/dist/plugins/StringAnalysis.d.ts.map +1 -0
  55. package/dist/plugins/StringAnalysis.js +217 -0
  56. package/dist/plugins/UnmountedReactFiberNodesAnalysis.d.ts +19 -0
  57. package/dist/plugins/UnmountedReactFiberNodesAnalysis.d.ts.map +1 -0
  58. package/dist/plugins/UnmountedReactFiberNodesAnalysis.js +46 -0
  59. package/package.json +55 -0
package/dist/index.js ADDED
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ *
8
+ * @emails oncall+ws_labs
9
+ * @format
10
+ */
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.PluginUtils = exports.StringAnalysis = exports.ObjectUnboundGrowthAnalysis = exports.ObjectShapeAnalysis = exports.ObjectFanoutAnalysis = exports.ShapeUnboundGrowthAnalysis = exports.ObjectSizeAnalysis = exports.ObjectShallowAnalysis = exports.CollectionsHoldingStaleAnalysis = exports.GlobalVariableAnalysis = exports.DetachedDOMElementAnalysis = exports.BaseAnalysis = exports.heapAnalysisLoader = void 0;
16
+ var HeapAnalysisLoader_1 = require("./HeapAnalysisLoader");
17
+ Object.defineProperty(exports, "heapAnalysisLoader", { enumerable: true, get: function () { return __importDefault(HeapAnalysisLoader_1).default; } });
18
+ var BaseAnalysis_1 = require("./BaseAnalysis");
19
+ Object.defineProperty(exports, "BaseAnalysis", { enumerable: true, get: function () { return __importDefault(BaseAnalysis_1).default; } });
20
+ var DetachedDOMElementAnalysis_1 = require("./plugins/DetachedDOMElementAnalysis");
21
+ Object.defineProperty(exports, "DetachedDOMElementAnalysis", { enumerable: true, get: function () { return __importDefault(DetachedDOMElementAnalysis_1).default; } });
22
+ var GlobalVariableAnalysis_1 = require("./plugins/GlobalVariableAnalysis/GlobalVariableAnalysis");
23
+ Object.defineProperty(exports, "GlobalVariableAnalysis", { enumerable: true, get: function () { return __importDefault(GlobalVariableAnalysis_1).default; } });
24
+ var CollectionsHoldingStaleAnalysis_1 = require("./plugins/CollectionsHoldingStaleAnalysis");
25
+ Object.defineProperty(exports, "CollectionsHoldingStaleAnalysis", { enumerable: true, get: function () { return __importDefault(CollectionsHoldingStaleAnalysis_1).default; } });
26
+ var ObjectShallowAnalysis_1 = require("./plugins/ObjectShallowAnalysis");
27
+ Object.defineProperty(exports, "ObjectShallowAnalysis", { enumerable: true, get: function () { return __importDefault(ObjectShallowAnalysis_1).default; } });
28
+ var ObjectSizeAnalysis_1 = require("./plugins/ObjectSizeAnalysis");
29
+ Object.defineProperty(exports, "ObjectSizeAnalysis", { enumerable: true, get: function () { return __importDefault(ObjectSizeAnalysis_1).default; } });
30
+ var ShapeUnboundGrowthAnalysis_1 = require("./plugins/ShapeUnboundGrowthAnalysis");
31
+ Object.defineProperty(exports, "ShapeUnboundGrowthAnalysis", { enumerable: true, get: function () { return __importDefault(ShapeUnboundGrowthAnalysis_1).default; } });
32
+ var ObjectFanoutAnalysis_1 = require("./plugins/ObjectFanoutAnalysis");
33
+ Object.defineProperty(exports, "ObjectFanoutAnalysis", { enumerable: true, get: function () { return __importDefault(ObjectFanoutAnalysis_1).default; } });
34
+ var ObjectShapeAnalysis_1 = require("./plugins/ObjectShapeAnalysis");
35
+ Object.defineProperty(exports, "ObjectShapeAnalysis", { enumerable: true, get: function () { return __importDefault(ObjectShapeAnalysis_1).default; } });
36
+ var ObjectUnboundGrowthAnalysis_1 = require("./plugins/ObjectUnboundGrowthAnalysis");
37
+ Object.defineProperty(exports, "ObjectUnboundGrowthAnalysis", { enumerable: true, get: function () { return __importDefault(ObjectUnboundGrowthAnalysis_1).default; } });
38
+ var StringAnalysis_1 = require("./plugins/StringAnalysis");
39
+ Object.defineProperty(exports, "StringAnalysis", { enumerable: true, get: function () { return __importDefault(StringAnalysis_1).default; } });
40
+ var PluginUtils_1 = require("./PluginUtils");
41
+ Object.defineProperty(exports, "PluginUtils", { enumerable: true, get: function () { return __importDefault(PluginUtils_1).default; } });
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
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
+ * @emails oncall+ws_labs
8
+ * @format
9
+ */
10
+ import type { ParsedArgs } from 'minimist';
11
+ import { BaseOption, MemLabConfig } from '@memlab/core';
12
+ export default class HeapAnalysisSnapshotDirectoryOption extends BaseOption {
13
+ getOptionName(): string;
14
+ getDescription(): string;
15
+ getExampleValues(): string[];
16
+ parse(config: MemLabConfig, args: ParsedArgs): Promise<void>;
17
+ }
18
+ //# sourceMappingURL=HeapAnalysisSnapshotDirectoryOption.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HeapAnalysisSnapshotDirectoryOption.d.ts","sourceRoot":"","sources":["../../src/options/HeapAnalysisSnapshotDirectoryOption.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,UAAU,CAAC;AAGzC,OAAO,EAAC,UAAU,EAAE,YAAY,EAAQ,MAAM,cAAc,CAAC;AAE7D,MAAM,CAAC,OAAO,OAAO,mCAAoC,SAAQ,UAAU;IACzE,aAAa,IAAI,MAAM;IAIvB,cAAc,IAAI,MAAM;IAIxB,gBAAgB,IAAI,MAAM,EAAE;IAItB,KAAK,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CAWnE"}
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ *
8
+ * @emails oncall+ws_labs
9
+ * @format
10
+ */
11
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
13
+ return new (P || (P = Promise))(function (resolve, reject) {
14
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
15
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
16
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
17
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
18
+ });
19
+ };
20
+ var __importDefault = (this && this.__importDefault) || function (mod) {
21
+ return (mod && mod.__esModule) ? mod : { "default": mod };
22
+ };
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ const fs_1 = __importDefault(require("fs"));
25
+ const core_1 = require("@memlab/core");
26
+ class HeapAnalysisSnapshotDirectoryOption extends core_1.BaseOption {
27
+ getOptionName() {
28
+ return 'snapshot-dir';
29
+ }
30
+ getDescription() {
31
+ return 'set directory path containing all heap snapshots under analysis';
32
+ }
33
+ getExampleValues() {
34
+ return ['/tmp/snapshots/'];
35
+ }
36
+ parse(config, args) {
37
+ return __awaiter(this, void 0, void 0, function* () {
38
+ if (!args[this.getOptionName()]) {
39
+ return;
40
+ }
41
+ const dir = args[this.getOptionName()];
42
+ if (!fs_1.default.existsSync(dir)) {
43
+ core_1.utils.haltOrThrow(`Invalid directory: ${dir}`);
44
+ }
45
+ config.externalSnapshotDir = dir;
46
+ config.useExternalSnapshot = true;
47
+ });
48
+ }
49
+ }
50
+ exports.default = HeapAnalysisSnapshotDirectoryOption;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
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
+ * @emails oncall+ws_labs
8
+ * @format
9
+ */
10
+ import type { ParsedArgs } from 'minimist';
11
+ import { BaseOption, MemLabConfig } from '@memlab/core';
12
+ export default class HeapAnalysisSnapshotFileOption extends BaseOption {
13
+ getOptionName(): string;
14
+ getDescription(): string;
15
+ getExampleValues(): string[];
16
+ parse(config: MemLabConfig, args: ParsedArgs): Promise<void>;
17
+ }
18
+ //# sourceMappingURL=HeapAnalysisSnapshotFileOption.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HeapAnalysisSnapshotFileOption.d.ts","sourceRoot":"","sources":["../../src/options/HeapAnalysisSnapshotFileOption.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,UAAU,CAAC;AAGzC,OAAO,EAAC,UAAU,EAAE,YAAY,EAAQ,MAAM,cAAc,CAAC;AAE7D,MAAM,CAAC,OAAO,OAAO,8BAA+B,SAAQ,UAAU;IACpE,aAAa,IAAI,MAAM;IAIvB,cAAc,IAAI,MAAM;IAIxB,gBAAgB,IAAI,MAAM,EAAE;IAItB,KAAK,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CAWnE"}
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ *
8
+ * @emails oncall+ws_labs
9
+ * @format
10
+ */
11
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
13
+ return new (P || (P = Promise))(function (resolve, reject) {
14
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
15
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
16
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
17
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
18
+ });
19
+ };
20
+ var __importDefault = (this && this.__importDefault) || function (mod) {
21
+ return (mod && mod.__esModule) ? mod : { "default": mod };
22
+ };
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ const fs_1 = __importDefault(require("fs"));
25
+ const core_1 = require("@memlab/core");
26
+ class HeapAnalysisSnapshotFileOption extends core_1.BaseOption {
27
+ getOptionName() {
28
+ return 'snapshot';
29
+ }
30
+ getDescription() {
31
+ return 'set file path of the heap snapshot under analysis';
32
+ }
33
+ getExampleValues() {
34
+ return ['/tmp/file.heapsnapshot'];
35
+ }
36
+ parse(config, args) {
37
+ return __awaiter(this, void 0, void 0, function* () {
38
+ if (!args.snapshot) {
39
+ return;
40
+ }
41
+ const file = args.snapshot;
42
+ if (!fs_1.default.existsSync(file)) {
43
+ core_1.utils.haltOrThrow(`Invalid snapshot file: ${file}`);
44
+ }
45
+ config.useExternalSnapshot = true;
46
+ config.externalSnapshotFilePaths[0] = file;
47
+ });
48
+ }
49
+ }
50
+ exports.default = HeapAnalysisSnapshotFileOption;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
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
+ * @emails oncall+ws_labs
8
+ * @format
9
+ */
10
+ import type { HeapAnalysisOptions } from '../PluginUtils';
11
+ import { BaseOption } from '@memlab/core';
12
+ import BaseAnalysis from '../BaseAnalysis';
13
+ export default class CollectionsHoldingStaleAnalysis extends BaseAnalysis {
14
+ getCommandName(): string;
15
+ getDescription(): string;
16
+ getOptions(): BaseOption[];
17
+ private staleCollectionMapper;
18
+ process(options: HeapAnalysisOptions): Promise<void>;
19
+ private getCollectionsWithStaleValues;
20
+ private print;
21
+ }
22
+ //# sourceMappingURL=CollectionsHoldingStaleAnalysis.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CollectionsHoldingStaleAnalysis.d.ts","sourceRoot":"","sources":["../../src/plugins/CollectionsHoldingStaleAnalysis.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,gBAAgB,CAAC;AAGxD,OAAO,EAAc,UAAU,EAAC,MAAM,cAAc,CAAC;AACrD,OAAO,YAAY,MAAM,iBAAiB,CAAC;AAgD3C,MAAM,CAAC,OAAO,OAAO,+BAAgC,SAAQ,YAAY;IAChE,cAAc,IAAI,MAAM;IAIxB,cAAc,IAAI,MAAM;IAI/B,UAAU,IAAI,UAAU,EAAE;IAI1B,OAAO,CAAC,qBAAqB,CAO1B;IAEG,OAAO,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAM1D,OAAO,CAAC,6BAA6B;IAoBrC,OAAO,CAAC,KAAK;CAgCd"}
@@ -0,0 +1,132 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ *
8
+ * @emails oncall+ws_labs
9
+ * @format
10
+ */
11
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
13
+ return new (P || (P = Promise))(function (resolve, reject) {
14
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
15
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
16
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
17
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
18
+ });
19
+ };
20
+ var __importDefault = (this && this.__importDefault) || function (mod) {
21
+ return (mod && mod.__esModule) ? mod : { "default": mod };
22
+ };
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ const core_1 = require("@memlab/core");
25
+ const BaseAnalysis_1 = __importDefault(require("../BaseAnalysis"));
26
+ const PluginUtils_1 = __importDefault(require("../PluginUtils"));
27
+ const chalk_1 = __importDefault(require("chalk"));
28
+ const HeapAnalysisSnapshotFileOption_1 = __importDefault(require("../options/HeapAnalysisSnapshotFileOption"));
29
+ function initCollectionStat(collection) {
30
+ return {
31
+ collection,
32
+ staleChildren: [],
33
+ childrenSize: 0,
34
+ staleRetainedSize: 0,
35
+ };
36
+ }
37
+ function processCollectionChildren(node) {
38
+ const stat = initCollectionStat(node);
39
+ const refs = node.references;
40
+ for (const ref of refs) {
41
+ ++stat.childrenSize;
42
+ const elementNode = ref.toNode;
43
+ if (!core_1.utils.isDetachedDOMNode(elementNode) &&
44
+ !core_1.utils.isDetachedFiberNode(elementNode)) {
45
+ continue;
46
+ }
47
+ // update stat for the collection
48
+ stat.staleChildren.push(elementNode);
49
+ stat.staleRetainedSize += elementNode.retainedSize;
50
+ }
51
+ return stat;
52
+ }
53
+ function processMapOrSet(node) {
54
+ const tableEdge = core_1.utils.getEdgeByNameAndType(node, 'table');
55
+ if (!tableEdge) {
56
+ return initCollectionStat(node);
57
+ }
58
+ return processCollectionChildren(tableEdge.toNode);
59
+ }
60
+ class CollectionsHoldingStaleAnalysis extends BaseAnalysis_1.default {
61
+ constructor() {
62
+ super(...arguments);
63
+ this.staleCollectionMapper = new Map([
64
+ ['Map', processMapOrSet],
65
+ ['Set', processMapOrSet],
66
+ ['Array', processCollectionChildren],
67
+ ]);
68
+ }
69
+ getCommandName() {
70
+ return 'collections-with-stale';
71
+ }
72
+ getDescription() {
73
+ return 'Analyze collections holding stale objects';
74
+ }
75
+ getOptions() {
76
+ return [new HeapAnalysisSnapshotFileOption_1.default()];
77
+ }
78
+ process(options) {
79
+ return __awaiter(this, void 0, void 0, function* () {
80
+ const snapshot = yield PluginUtils_1.default.loadHeapSnapshot(options);
81
+ const collectionsStat = this.getCollectionsWithStaleValues(snapshot);
82
+ this.print(collectionsStat);
83
+ });
84
+ }
85
+ getCollectionsWithStaleValues(snapshot) {
86
+ core_1.info.overwrite('analyzing collections...');
87
+ const collections = [];
88
+ // going through collection nodes
89
+ snapshot.nodes.forEachTraceable((node) => {
90
+ const statCollector = this.staleCollectionMapper.get(node.name);
91
+ if (!statCollector) {
92
+ return;
93
+ }
94
+ const stat = statCollector(node);
95
+ if (stat.staleChildren.length > 0) {
96
+ collections.push(stat);
97
+ }
98
+ });
99
+ return collections;
100
+ }
101
+ print(collections) {
102
+ const dot = chalk_1.default.grey('·');
103
+ const head = chalk_1.default.yellow.bind(chalk_1.default);
104
+ if (collections.length === 0) {
105
+ core_1.info.success('Congratulations! No collections holding stale objects');
106
+ }
107
+ else {
108
+ core_1.info.topLevel(head('\nCollections holding stale objects:'));
109
+ }
110
+ collections.sort((c1, c2) => c2.staleRetainedSize - c1.staleRetainedSize);
111
+ collections = collections.slice(0, 20);
112
+ for (const stat of collections) {
113
+ const collection = stat.collection;
114
+ const collectionSize = core_1.utils.getReadableBytes(collection.retainedSize);
115
+ const staleChildrenSize = stat.staleChildren.length;
116
+ const childrenSize = stat.childrenSize;
117
+ const staleDesc = `${staleChildrenSize} out of ${childrenSize} elements are stale`;
118
+ const name = chalk_1.default.blue(collection.name);
119
+ const id = `(${chalk_1.default.grey('@' + collection.id)})`;
120
+ const collectionDesc = `${name} ${id} ${collectionSize} (${staleDesc})`;
121
+ let childrenIds = stat.staleChildren.map(node => `@${node.id}`);
122
+ if (childrenIds.length > 10) {
123
+ childrenIds = childrenIds.slice(0, 10);
124
+ childrenIds.push('...');
125
+ }
126
+ const childrenDesc = chalk_1.default.grey(childrenIds.join(', '));
127
+ core_1.info.topLevel(`\n${dot} ${collectionDesc}:`);
128
+ core_1.info.topLevel(` ${childrenDesc}`);
129
+ }
130
+ }
131
+ }
132
+ exports.default = CollectionsHoldingStaleAnalysis;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
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
+ * @emails oncall+ws_labs
8
+ * @format
9
+ */
10
+ import type { HeapAnalysisOptions } from '../PluginUtils';
11
+ import type { IHeapNode } from '@memlab/core';
12
+ import { BaseOption } from '@memlab/core';
13
+ import BaseAnalysis from '../BaseAnalysis';
14
+ export default class DetachedDOMElementAnalysis extends BaseAnalysis {
15
+ getCommandName(): string;
16
+ getDescription(): string;
17
+ getOptions(): BaseOption[];
18
+ private detachedElements;
19
+ getDetachedElements(): IHeapNode[];
20
+ process(options: HeapAnalysisOptions): Promise<void>;
21
+ }
22
+ //# sourceMappingURL=DetachedDOMElementAnalysis.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DetachedDOMElementAnalysis.d.ts","sourceRoot":"","sources":["../../src/plugins/DetachedDOMElementAnalysis.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAE5C,OAAO,EAAQ,UAAU,EAAC,MAAM,cAAc,CAAC;AAC/C,OAAO,YAAY,MAAM,iBAAiB,CAAC;AAI3C,MAAM,CAAC,OAAO,OAAO,0BAA2B,SAAQ,YAAY;IAClE,cAAc,IAAI,MAAM;IAIxB,cAAc,IAAI,MAAM;IAIxB,UAAU,IAAI,UAAU,EAAE;IAI1B,OAAO,CAAC,gBAAgB,CAAmB;IAEpC,mBAAmB,IAAI,SAAS,EAAE;IAInC,OAAO,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;CAQ3D"}
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ *
8
+ * @emails oncall+ws_labs
9
+ * @format
10
+ */
11
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
13
+ return new (P || (P = Promise))(function (resolve, reject) {
14
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
15
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
16
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
17
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
18
+ });
19
+ };
20
+ var __importDefault = (this && this.__importDefault) || function (mod) {
21
+ return (mod && mod.__esModule) ? mod : { "default": mod };
22
+ };
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ const core_1 = require("@memlab/core");
25
+ const BaseAnalysis_1 = __importDefault(require("../BaseAnalysis"));
26
+ const PluginUtils_1 = __importDefault(require("../PluginUtils"));
27
+ const HeapAnalysisSnapshotFileOption_1 = __importDefault(require("../options/HeapAnalysisSnapshotFileOption"));
28
+ class DetachedDOMElementAnalysis extends BaseAnalysis_1.default {
29
+ constructor() {
30
+ super(...arguments);
31
+ this.detachedElements = [];
32
+ }
33
+ getCommandName() {
34
+ return 'detached-DOM';
35
+ }
36
+ getDescription() {
37
+ return 'Get detached DOM elements';
38
+ }
39
+ getOptions() {
40
+ return [new HeapAnalysisSnapshotFileOption_1.default()];
41
+ }
42
+ getDetachedElements() {
43
+ return this.detachedElements;
44
+ }
45
+ process(options) {
46
+ return __awaiter(this, void 0, void 0, function* () {
47
+ const snapshot = yield PluginUtils_1.default.loadHeapSnapshot(options);
48
+ this.detachedElements = PluginUtils_1.default.filterOutLargestObjects(snapshot, core_1.utils.isDetachedDOMNode);
49
+ PluginUtils_1.default.printNodeListInTerminal(this.detachedElements);
50
+ });
51
+ }
52
+ }
53
+ exports.default = DetachedDOMElementAnalysis;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
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
+ * @emails oncall+ws_labs
8
+ * @lightSyntaxTransform
9
+ * @format
10
+ */
11
+ declare const _default: Set<string>;
12
+ export default _default;
13
+ //# sourceMappingURL=BuiltInGlobalVariables.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BuiltInGlobalVariables.d.ts","sourceRoot":"","sources":["../../../src/plugins/GlobalVariableAnalysis/BuiltInGlobalVariables.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;;AAEH,wBAoiCG"}