@memlab/core 1.0.8 → 1.1.1

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 (36) hide show
  1. package/dist/index.d.ts +17 -0
  2. package/dist/index.js +17 -0
  3. package/dist/lib/Config.d.ts +6 -2
  4. package/dist/lib/Config.js +11 -2
  5. package/dist/lib/FileManager.d.ts +2 -0
  6. package/dist/lib/FileManager.js +1 -0
  7. package/dist/lib/HeapAnalyzer.d.ts +2 -2
  8. package/dist/lib/HeapAnalyzer.js +27 -60
  9. package/dist/lib/InternalValueSetter.d.ts +2 -0
  10. package/dist/lib/InternalValueSetter.js +2 -0
  11. package/dist/lib/Types.d.ts +363 -6
  12. package/dist/lib/Types.js +1 -0
  13. package/dist/lib/Utils.js +24 -1
  14. package/dist/lib/leak-filters/BaseLeakFilter.rule.d.ts +24 -0
  15. package/dist/lib/leak-filters/BaseLeakFilter.rule.js +22 -0
  16. package/dist/lib/leak-filters/LeakFilterRuleList.d.ts +13 -0
  17. package/dist/lib/leak-filters/LeakFilterRuleList.js +33 -0
  18. package/dist/lib/leak-filters/LeakObjectFilter.d.ts +19 -0
  19. package/dist/lib/leak-filters/LeakObjectFilter.js +36 -0
  20. package/dist/lib/leak-filters/rules/FilterByExternalFilter.rule.d.ts +19 -0
  21. package/dist/lib/leak-filters/rules/FilterByExternalFilter.rule.js +27 -0
  22. package/dist/lib/leak-filters/rules/FilterDetachedDOMElement.rule.d.ts +20 -0
  23. package/dist/lib/leak-filters/rules/FilterDetachedDOMElement.rule.js +40 -0
  24. package/dist/lib/leak-filters/rules/FilterHermesNode.rule.d.ts +16 -0
  25. package/dist/lib/leak-filters/rules/FilterHermesNode.rule.js +27 -0
  26. package/dist/lib/leak-filters/rules/FilterOverSizedNodeAsLeak.rule.d.ts +19 -0
  27. package/dist/lib/leak-filters/rules/FilterOverSizedNodeAsLeak.rule.js +27 -0
  28. package/dist/lib/leak-filters/rules/FilterStackTraceFrame.rule.d.ts +19 -0
  29. package/dist/lib/leak-filters/rules/FilterStackTraceFrame.rule.js +28 -0
  30. package/dist/lib/leak-filters/rules/FilterTrivialNode.rule.d.ts +20 -0
  31. package/dist/lib/leak-filters/rules/FilterTrivialNode.rule.js +33 -0
  32. package/dist/lib/leak-filters/rules/FilterUnmountedFiberNode.rule.d.ts +20 -0
  33. package/dist/lib/leak-filters/rules/FilterUnmountedFiberNode.rule.js +37 -0
  34. package/dist/trace-cluster/TraceBucket.d.ts +1 -0
  35. package/dist/trace-cluster/TraceBucket.js +12 -1
  36. package/package.json +1 -1
@@ -0,0 +1,22 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.LeakDecision = void 0;
13
+ /**
14
+ * Every leak object filter rule needs to give a label
15
+ * to each object passed to the filter
16
+ */
17
+ var LeakDecision;
18
+ (function (LeakDecision) {
19
+ LeakDecision["LEAK"] = "leak";
20
+ LeakDecision["MAYBE_LEAK"] = "maybe-leak";
21
+ LeakDecision["NOT_LEAK"] = "not-leak";
22
+ })(LeakDecision = exports.LeakDecision || (exports.LeakDecision = {}));
@@ -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
+ * @format
9
+ */
10
+ import { ILeakObjectFilterRule } from './BaseLeakFilter.rule';
11
+ declare const _default: ILeakObjectFilterRule[];
12
+ export default _default;
13
+ //# sourceMappingURL=LeakFilterRuleList.d.ts.map
@@ -0,0 +1,33 @@
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
+ const Constant_1 = __importDefault(require("../Constant"));
16
+ const InternalValueSetter_1 = require("../InternalValueSetter");
17
+ const FilterByExternalFilter_rule_1 = require("./rules/FilterByExternalFilter.rule");
18
+ const FilterDetachedDOMElement_rule_1 = require("./rules/FilterDetachedDOMElement.rule");
19
+ const FilterHermesNode_rule_1 = require("./rules/FilterHermesNode.rule");
20
+ const FilterOverSizedNodeAsLeak_rule_1 = require("./rules/FilterOverSizedNodeAsLeak.rule");
21
+ const FilterStackTraceFrame_rule_1 = require("./rules/FilterStackTraceFrame.rule");
22
+ const FilterTrivialNode_rule_1 = require("./rules/FilterTrivialNode.rule");
23
+ const FilterUnmountedFiberNode_rule_1 = require("./rules/FilterUnmountedFiberNode.rule");
24
+ const list = [
25
+ new FilterByExternalFilter_rule_1.FilterByExternalFilterRule(),
26
+ new FilterTrivialNode_rule_1.FilterTrivialNodeRule(),
27
+ new FilterHermesNode_rule_1.FilterHermesNodeRule(),
28
+ new FilterOverSizedNodeAsLeak_rule_1.FilterOverSizedNodeAsLeakRule(),
29
+ new FilterUnmountedFiberNode_rule_1.FilterUnmountedFiberNodeRule(),
30
+ new FilterDetachedDOMElement_rule_1.FilterDetachedDOMElementRule(),
31
+ new FilterStackTraceFrame_rule_1.FilterStackTraceFrameRule(),
32
+ ];
33
+ exports.default = (0, InternalValueSetter_1.setInternalValue)(list, __filename, Constant_1.default.internalDir);
@@ -0,0 +1,19 @@
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 { MemLabConfig } from '../Config';
11
+ import type { HeapNodeIdSet, IHeapNode, IHeapSnapshot } from '../Types';
12
+ /**
13
+ * apply the leak object filter rules chain and decide
14
+ * if an object is a memory leak or not
15
+ */
16
+ export declare class LeakObjectFilter {
17
+ filter(config: MemLabConfig, node: IHeapNode, snapshot: IHeapSnapshot, leakedNodeIds: HeapNodeIdSet): boolean;
18
+ }
19
+ //# sourceMappingURL=LeakObjectFilter.d.ts.map
@@ -0,0 +1,36 @@
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.LeakObjectFilter = void 0;
16
+ const BaseLeakFilter_rule_1 = require("./BaseLeakFilter.rule");
17
+ const LeakFilterRuleList_1 = __importDefault(require("./LeakFilterRuleList"));
18
+ /**
19
+ * apply the leak object filter rules chain and decide
20
+ * if an object is a memory leak or not
21
+ */
22
+ class LeakObjectFilter {
23
+ filter(config, node, snapshot, leakedNodeIds) {
24
+ for (const rule of LeakFilterRuleList_1.default) {
25
+ const decision = rule.filter(config, node, snapshot, leakedNodeIds);
26
+ if (decision === BaseLeakFilter_rule_1.LeakDecision.LEAK) {
27
+ return true;
28
+ }
29
+ if (decision === BaseLeakFilter_rule_1.LeakDecision.NOT_LEAK) {
30
+ return false;
31
+ }
32
+ }
33
+ return false;
34
+ }
35
+ }
36
+ exports.LeakObjectFilter = LeakObjectFilter;
@@ -0,0 +1,19 @@
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 { MemLabConfig } from '../../Config';
11
+ import type { HeapNodeIdSet, IHeapNode, IHeapSnapshot } from '../../Types';
12
+ import { ILeakObjectFilterRule, LeakDecision } from '../BaseLeakFilter.rule';
13
+ /**
14
+ * filter memory leaks defined by external leak filter
15
+ */
16
+ export declare class FilterByExternalFilterRule implements ILeakObjectFilterRule {
17
+ filter(config: MemLabConfig, node: IHeapNode, snapshot: IHeapSnapshot, leakedNodeIds: HeapNodeIdSet): LeakDecision;
18
+ }
19
+ //# sourceMappingURL=FilterByExternalFilter.rule.d.ts.map
@@ -0,0 +1,27 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.FilterByExternalFilterRule = void 0;
13
+ const BaseLeakFilter_rule_1 = require("../BaseLeakFilter.rule");
14
+ /**
15
+ * filter memory leaks defined by external leak filter
16
+ */
17
+ class FilterByExternalFilterRule {
18
+ filter(config, node, snapshot, leakedNodeIds) {
19
+ if (config.externalLeakFilter) {
20
+ return config.externalLeakFilter.leakFilter(node, snapshot, leakedNodeIds)
21
+ ? BaseLeakFilter_rule_1.LeakDecision.LEAK
22
+ : BaseLeakFilter_rule_1.LeakDecision.NOT_LEAK;
23
+ }
24
+ return BaseLeakFilter_rule_1.LeakDecision.MAYBE_LEAK;
25
+ }
26
+ }
27
+ exports.FilterByExternalFilterRule = FilterByExternalFilterRule;
@@ -0,0 +1,20 @@
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 { MemLabConfig } from '../../Config';
11
+ import type { IHeapNode } from '../../Types';
12
+ import { ILeakObjectFilterRule, LeakDecision } from '../BaseLeakFilter.rule';
13
+ /**
14
+ * mark detached DOM elements as memory leaks
15
+ */
16
+ export declare class FilterDetachedDOMElementRule implements ILeakObjectFilterRule {
17
+ filter(_config: MemLabConfig, node: IHeapNode): LeakDecision;
18
+ protected checkDetachedFiberNode(config: MemLabConfig, node: IHeapNode): boolean;
19
+ }
20
+ //# sourceMappingURL=FilterDetachedDOMElement.rule.d.ts.map
@@ -0,0 +1,40 @@
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.FilterDetachedDOMElementRule = void 0;
16
+ const BaseLeakFilter_rule_1 = require("../BaseLeakFilter.rule");
17
+ const Utils_1 = __importDefault(require("../../Utils"));
18
+ /**
19
+ * mark detached DOM elements as memory leaks
20
+ */
21
+ class FilterDetachedDOMElementRule {
22
+ filter(_config, node) {
23
+ const isDetached = Utils_1.default.isDetachedDOMNode(node, {
24
+ ignoreInternalNode: true,
25
+ });
26
+ if (isDetached) {
27
+ return BaseLeakFilter_rule_1.LeakDecision.LEAK;
28
+ }
29
+ return BaseLeakFilter_rule_1.LeakDecision.MAYBE_LEAK;
30
+ }
31
+ checkDetachedFiberNode(config, node) {
32
+ if (!config.detectFiberNodeLeak ||
33
+ !Utils_1.default.isFiberNode(node) ||
34
+ Utils_1.default.hasHostRoot(node)) {
35
+ return false;
36
+ }
37
+ return !Utils_1.default.isNodeDominatedByDeletionsArray(node);
38
+ }
39
+ }
40
+ exports.FilterDetachedDOMElementRule = FilterDetachedDOMElementRule;
@@ -0,0 +1,16 @@
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 { MemLabConfig } from '../../Config';
11
+ import type { IHeapNode } from '../../Types';
12
+ import { ILeakObjectFilterRule, LeakDecision } from '../BaseLeakFilter.rule';
13
+ export declare class FilterHermesNodeRule implements ILeakObjectFilterRule {
14
+ filter(config: MemLabConfig, node: IHeapNode): LeakDecision;
15
+ }
16
+ //# sourceMappingURL=FilterHermesNode.rule.d.ts.map
@@ -0,0 +1,27 @@
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.FilterHermesNodeRule = void 0;
16
+ const BaseLeakFilter_rule_1 = require("../BaseLeakFilter.rule");
17
+ const Utils_1 = __importDefault(require("../../Utils"));
18
+ class FilterHermesNodeRule {
19
+ filter(config, node) {
20
+ // when analyzing hermes heap snapshots, filter Hermes internal objects
21
+ if (config.jsEngine === 'hermes' && Utils_1.default.isHermesInternalObject(node)) {
22
+ return BaseLeakFilter_rule_1.LeakDecision.NOT_LEAK;
23
+ }
24
+ return BaseLeakFilter_rule_1.LeakDecision.MAYBE_LEAK;
25
+ }
26
+ }
27
+ exports.FilterHermesNodeRule = FilterHermesNodeRule;
@@ -0,0 +1,19 @@
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 { MemLabConfig } from '../../Config';
11
+ import type { IHeapNode } from '../../Types';
12
+ import { ILeakObjectFilterRule, LeakDecision } from '../BaseLeakFilter.rule';
13
+ /**
14
+ * trivial nodes are not reported as memory leaks
15
+ */
16
+ export declare class FilterOverSizedNodeAsLeakRule implements ILeakObjectFilterRule {
17
+ filter(config: MemLabConfig, node: IHeapNode): LeakDecision;
18
+ }
19
+ //# sourceMappingURL=FilterOverSizedNodeAsLeak.rule.d.ts.map
@@ -0,0 +1,27 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.FilterOverSizedNodeAsLeakRule = void 0;
13
+ const BaseLeakFilter_rule_1 = require("../BaseLeakFilter.rule");
14
+ /**
15
+ * trivial nodes are not reported as memory leaks
16
+ */
17
+ class FilterOverSizedNodeAsLeakRule {
18
+ filter(config, node) {
19
+ if (config.oversizeObjectAsLeak) {
20
+ return node.retainedSize > config.oversizeThreshold
21
+ ? BaseLeakFilter_rule_1.LeakDecision.LEAK
22
+ : BaseLeakFilter_rule_1.LeakDecision.NOT_LEAK;
23
+ }
24
+ return BaseLeakFilter_rule_1.LeakDecision.MAYBE_LEAK;
25
+ }
26
+ }
27
+ exports.FilterOverSizedNodeAsLeakRule = FilterOverSizedNodeAsLeakRule;
@@ -0,0 +1,19 @@
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 { MemLabConfig } from '../../Config';
11
+ import type { IHeapNode } from '../../Types';
12
+ import { ILeakObjectFilterRule, LeakDecision } from '../BaseLeakFilter.rule';
13
+ /**
14
+ * stack trace frames as memory leaks
15
+ */
16
+ export declare class FilterStackTraceFrameRule implements ILeakObjectFilterRule {
17
+ filter(_config: MemLabConfig, node: IHeapNode): LeakDecision;
18
+ }
19
+ //# sourceMappingURL=FilterStackTraceFrame.rule.d.ts.map
@@ -0,0 +1,28 @@
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.FilterStackTraceFrameRule = void 0;
16
+ const BaseLeakFilter_rule_1 = require("../BaseLeakFilter.rule");
17
+ const Utils_1 = __importDefault(require("../../Utils"));
18
+ /**
19
+ * stack trace frames as memory leaks
20
+ */
21
+ class FilterStackTraceFrameRule {
22
+ filter(_config, node) {
23
+ return Utils_1.default.isStackTraceFrame(node)
24
+ ? BaseLeakFilter_rule_1.LeakDecision.LEAK
25
+ : BaseLeakFilter_rule_1.LeakDecision.MAYBE_LEAK;
26
+ }
27
+ }
28
+ exports.FilterStackTraceFrameRule = FilterStackTraceFrameRule;
@@ -0,0 +1,20 @@
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 { MemLabConfig } from '../../Config';
11
+ import type { IHeapNode } from '../../Types';
12
+ import { ILeakObjectFilterRule, LeakDecision } from '../BaseLeakFilter.rule';
13
+ /**
14
+ * trivial nodes are not reported as memory leaks
15
+ */
16
+ export declare class FilterTrivialNodeRule implements ILeakObjectFilterRule {
17
+ filter(config: MemLabConfig, node: IHeapNode): LeakDecision;
18
+ protected isTrivialNode(node: IHeapNode): boolean;
19
+ }
20
+ //# sourceMappingURL=FilterTrivialNode.rule.d.ts.map
@@ -0,0 +1,33 @@
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.FilterTrivialNodeRule = void 0;
16
+ const BaseLeakFilter_rule_1 = require("../BaseLeakFilter.rule");
17
+ const Utils_1 = __importDefault(require("../../Utils"));
18
+ /**
19
+ * trivial nodes are not reported as memory leaks
20
+ */
21
+ class FilterTrivialNodeRule {
22
+ filter(config, node) {
23
+ return this.isTrivialNode(node)
24
+ ? BaseLeakFilter_rule_1.LeakDecision.NOT_LEAK
25
+ : BaseLeakFilter_rule_1.LeakDecision.MAYBE_LEAK;
26
+ }
27
+ isTrivialNode(node) {
28
+ return (node.type === 'number' ||
29
+ Utils_1.default.isStringNode(node) ||
30
+ node.type === 'hidden');
31
+ }
32
+ }
33
+ exports.FilterTrivialNodeRule = FilterTrivialNodeRule;
@@ -0,0 +1,20 @@
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 { MemLabConfig } from '../../Config';
11
+ import type { IHeapNode } from '../../Types';
12
+ import { ILeakObjectFilterRule, LeakDecision } from '../BaseLeakFilter.rule';
13
+ /**
14
+ * mark React FiberNodes without a React Fiber Root as memory leaks
15
+ */
16
+ export declare class FilterUnmountedFiberNodeRule implements ILeakObjectFilterRule {
17
+ filter(config: MemLabConfig, node: IHeapNode): LeakDecision;
18
+ protected checkDetachedFiberNode(config: MemLabConfig, node: IHeapNode): boolean;
19
+ }
20
+ //# sourceMappingURL=FilterUnmountedFiberNode.rule.d.ts.map
@@ -0,0 +1,37 @@
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.FilterUnmountedFiberNodeRule = void 0;
16
+ const BaseLeakFilter_rule_1 = require("../BaseLeakFilter.rule");
17
+ const Utils_1 = __importDefault(require("../../Utils"));
18
+ /**
19
+ * mark React FiberNodes without a React Fiber Root as memory leaks
20
+ */
21
+ class FilterUnmountedFiberNodeRule {
22
+ filter(config, node) {
23
+ if (this.checkDetachedFiberNode(config, node)) {
24
+ return BaseLeakFilter_rule_1.LeakDecision.LEAK;
25
+ }
26
+ return BaseLeakFilter_rule_1.LeakDecision.MAYBE_LEAK;
27
+ }
28
+ checkDetachedFiberNode(config, node) {
29
+ if (!config.detectFiberNodeLeak ||
30
+ !Utils_1.default.isFiberNode(node) ||
31
+ Utils_1.default.hasHostRoot(node)) {
32
+ return false;
33
+ }
34
+ return !Utils_1.default.isNodeDominatedByDeletionsArray(node);
35
+ }
36
+ }
37
+ exports.FilterUnmountedFiberNodeRule = FilterUnmountedFiberNodeRule;
@@ -25,6 +25,7 @@ export default class NormalizedTrace {
25
25
  private static diffTraces;
26
26
  static diffClusters(newClusters: TraceCluster[], existingClusters: TraceCluster[]): TraceClusterDiff;
27
27
  static clusterLeakTraces(leakTraces: LeakTrace[]): Record<string, string>;
28
+ static filterClusters(clusters: TraceCluster[]): TraceCluster[];
28
29
  static clusterPaths(paths: LeakTracePathItem[], snapshot: IHeapSnapshot, aggregateDominatorMetrics: AggregateNodeCb, option?: {
29
30
  strategy?: IClusterStrategy;
30
31
  }): TraceCluster[];
@@ -171,6 +171,16 @@ class NormalizedTrace {
171
171
  }, {});
172
172
  return labaledLeakTraces;
173
173
  }
174
+ static filterClusters(clusters) {
175
+ if (Config_1.default.clusterRetainedSizeThreshold <= 0) {
176
+ return clusters;
177
+ }
178
+ return clusters.filter(cluster => {
179
+ var _a;
180
+ return ((_a = cluster.retainedSize) !== null && _a !== void 0 ? _a : Infinity) >
181
+ Config_1.default.clusterRetainedSizeThreshold;
182
+ });
183
+ }
174
184
  static clusterPaths(paths, snapshot, aggregateDominatorMetrics, option = {}) {
175
185
  Console_1.default.overwrite('Clustering leak traces');
176
186
  if (paths.length === 0) {
@@ -192,7 +202,7 @@ class NormalizedTrace {
192
202
  // cluster traces
193
203
  const { allClusters } = NormalizedTrace.diffTraces(traces, [], option);
194
204
  // construct TraceCluster from clustering result
195
- const clusters = allClusters.map((traces) => {
205
+ let clusters = allClusters.map((traces) => {
196
206
  const cluster = {
197
207
  path: traceToPathMap.get(traces[0]),
198
208
  count: traces.length,
@@ -205,6 +215,7 @@ class NormalizedTrace {
205
215
  this.calculateClusterRetainedSize(cluster, snapshot, aggregateDominatorMetrics);
206
216
  return cluster;
207
217
  });
218
+ clusters = NormalizedTrace.filterClusters(clusters);
208
219
  clusters.sort((c1, c2) => { var _a, _b; return ((_a = c2.retainedSize) !== null && _a !== void 0 ? _a : 0) - ((_b = c1.retainedSize) !== null && _b !== void 0 ? _b : 0); });
209
220
  Console_1.default.midLevel(`MemLab found ${clusters.length} leak(s)`);
210
221
  return clusters;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memlab/core",
3
- "version": "1.0.8",
3
+ "version": "1.1.1",
4
4
  "license": "MIT",
5
5
  "description": "memlab core libraries",
6
6
  "author": "Liang Gong <lgong@fb.com>",