@memlab/core 1.1.0 → 1.1.3
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.
- package/README.md +3 -2
- package/dist/__tests__/parser/HeapParser.test.js +2 -2
- package/dist/__tests__/parser/NodeHeap.test.js +5 -5
- package/dist/__tests__/parser/StringNode.test.js +1 -1
- package/dist/__tests__/parser/traverse/HeapNodeTraverse.test.js +2 -2
- package/dist/lib/Config.d.ts +3 -0
- package/dist/lib/Config.js +13 -0
- package/dist/lib/Console.d.ts +1 -0
- package/dist/lib/Console.js +3 -0
- package/dist/lib/Constant.js +2 -2
- package/dist/lib/FileManager.d.ts +2 -0
- package/dist/lib/FileManager.js +6 -0
- package/dist/lib/HeapParser.js +1 -1
- package/dist/lib/NodeHeap.d.ts +64 -5
- package/dist/lib/NodeHeap.js +64 -3
- package/dist/lib/Serializer.js +4 -1
- package/dist/lib/Types.d.ts +871 -22
- package/dist/lib/Utils.js +3 -2
- package/dist/lib/heap-data/HeapNode.d.ts +1 -1
- package/dist/lib/heap-data/HeapNode.js +1 -1
- package/dist/lib/heap-data/HeapSnapshot.js +7 -1
- package/dist/paths/TraceFinder.js +4 -2
- package/dist/trace-cluster/TraceElement.d.ts +1 -1
- package/dist/trace-cluster/TraceElement.js +2 -2
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -2,5 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
This is the memlab core library. It contains V8/Hermes heap snapshot parser, core algorithms, leak trace clustering, utilities, and config.
|
|
4
4
|
|
|
5
|
-
##
|
|
6
|
-
https://facebookincubator.github.io/memlab
|
|
5
|
+
## Online Resources
|
|
6
|
+
* [Official Website and Demo](https://facebookincubator.github.io/memlab)
|
|
7
|
+
* [Documentation](https://facebookincubator.github.io/memlab/docs/intro)
|
|
@@ -36,7 +36,7 @@ test('Capture inserted object', () => __awaiter(void 0, void 0, void 0, function
|
|
|
36
36
|
}
|
|
37
37
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
38
38
|
const injected = new TestObject();
|
|
39
|
-
const heap = yield (0, NodeHeap_1.
|
|
39
|
+
const heap = yield (0, NodeHeap_1.getNodeInnocentHeap)();
|
|
40
40
|
expect(heap.hasObjectWithClassName('TestObject')).toBe(true);
|
|
41
41
|
}), timeout);
|
|
42
42
|
test('Does not capture transcient object', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -49,6 +49,6 @@ test('Does not capture transcient object', () => __awaiter(void 0, void 0, void
|
|
|
49
49
|
let injected = new TestObject();
|
|
50
50
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
51
51
|
injected = null;
|
|
52
|
-
const heap = yield (0, NodeHeap_1.
|
|
52
|
+
const heap = yield (0, NodeHeap_1.getNodeInnocentHeap)();
|
|
53
53
|
expect(heap.hasObjectWithClassName('TestObject')).toBe(false);
|
|
54
54
|
}), timeout);
|
|
@@ -30,7 +30,7 @@ const timeout = 5 * 60 * 1000;
|
|
|
30
30
|
test('Capture current node heap snapshot', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
31
31
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
32
32
|
const object = { 'memlab-test-heap-property': 'memlab-test-heap-value' };
|
|
33
|
-
const heap = yield (0, NodeHeap_1.
|
|
33
|
+
const heap = yield (0, NodeHeap_1.getNodeInnocentHeap)();
|
|
34
34
|
expect(heap.hasObjectWithPropertyName('memlab-test-heap-property')).toBe(true);
|
|
35
35
|
}), timeout);
|
|
36
36
|
test('Nullified Object should not exist in heap', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -39,7 +39,7 @@ test('Nullified Object should not exist in heap', () => __awaiter(void 0, void 0
|
|
|
39
39
|
};
|
|
40
40
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
41
41
|
object = null;
|
|
42
|
-
const heap = yield (0, NodeHeap_1.
|
|
42
|
+
const heap = yield (0, NodeHeap_1.getNodeInnocentHeap)();
|
|
43
43
|
expect(heap.hasObjectWithPropertyName('memlab-test-heap-property')).toBe(false);
|
|
44
44
|
}), timeout);
|
|
45
45
|
test('Strongly referenced object should exist in heap', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -59,7 +59,7 @@ test('Strongly referenced object should exist in heap', () => __awaiter(void 0,
|
|
|
59
59
|
}
|
|
60
60
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
61
61
|
const object = buildTest();
|
|
62
|
-
const heap = yield (0, NodeHeap_1.
|
|
62
|
+
const heap = yield (0, NodeHeap_1.getNodeInnocentHeap)();
|
|
63
63
|
expect(heap.hasObjectWithClassName('TestClass1')).toBe(true);
|
|
64
64
|
expect(heap.hasObjectWithClassName('TestClass2')).toBe(true);
|
|
65
65
|
}), timeout);
|
|
@@ -80,7 +80,7 @@ test('Weakly referenced object should not exist in heap', () => __awaiter(void 0
|
|
|
80
80
|
}
|
|
81
81
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
82
82
|
const object = buildTest();
|
|
83
|
-
const heap = yield (0, NodeHeap_1.
|
|
83
|
+
const heap = yield (0, NodeHeap_1.getNodeInnocentHeap)();
|
|
84
84
|
expect(heap.hasObjectWithClassName('TestClass3')).toBe(true);
|
|
85
85
|
expect(heap.hasObjectWithClassName('TestClass4')).toBe(false);
|
|
86
86
|
}), timeout);
|
|
@@ -90,7 +90,7 @@ test('Check annotated objects', () => __awaiter(void 0, void 0, void 0, function
|
|
|
90
90
|
(0, NodeHeap_1.tagObject)(o1, 'memlab-mark-1');
|
|
91
91
|
(0, NodeHeap_1.tagObject)(o2, 'memlab-mark-2');
|
|
92
92
|
o2 = null;
|
|
93
|
-
const heap = yield (0, NodeHeap_1.
|
|
93
|
+
const heap = yield (0, NodeHeap_1.getNodeInnocentHeap)();
|
|
94
94
|
expect(heap.hasObjectWithTag('memlab-mark-1')).toBe(true);
|
|
95
95
|
expect(heap.hasObjectWithTag('memlab-mark-2')).toBe(false);
|
|
96
96
|
}), timeout);
|
|
@@ -41,7 +41,7 @@ test('String heap object APIs work', () => __awaiter(void 0, void 0, void 0, fun
|
|
|
41
41
|
injected.complexConcatString += 'value_';
|
|
42
42
|
injected.complexConcatString += 123;
|
|
43
43
|
injected.complexConcatString += '_suffix';
|
|
44
|
-
const heap = yield (0, NodeHeap_1.
|
|
44
|
+
const heap = yield (0, NodeHeap_1.getNodeInnocentHeap)();
|
|
45
45
|
const testObject = heap.getAnyObjectWithClassName('TestObject');
|
|
46
46
|
expect(testObject).not.toBe(null);
|
|
47
47
|
// testObject.originalString === 'test'
|
|
@@ -74,7 +74,7 @@ test('Check getReference and getReferenceNode', () => __awaiter(void 0, void 0,
|
|
|
74
74
|
});
|
|
75
75
|
return detected;
|
|
76
76
|
};
|
|
77
|
-
const heap = yield (0, NodeHeap_1.
|
|
77
|
+
const heap = yield (0, NodeHeap_1.getNodeInnocentHeap)();
|
|
78
78
|
expect(checker(heap)).toBe(true);
|
|
79
79
|
}), timeout);
|
|
80
80
|
test('Check getReferrers and getReferrerNodes', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -135,6 +135,6 @@ test('Check getReferrers and getReferrerNodes', () => __awaiter(void 0, void 0,
|
|
|
135
135
|
}
|
|
136
136
|
return true;
|
|
137
137
|
};
|
|
138
|
-
const heap = yield (0, NodeHeap_1.
|
|
138
|
+
const heap = yield (0, NodeHeap_1.getNodeInnocentHeap)();
|
|
139
139
|
expect(checker(heap)).toBe(true);
|
|
140
140
|
}), timeout);
|
package/dist/lib/Config.d.ts
CHANGED
|
@@ -171,6 +171,7 @@ export declare class MemLabConfig {
|
|
|
171
171
|
clusterRetainedSizeThreshold: number;
|
|
172
172
|
_isFullRun: boolean;
|
|
173
173
|
_scenario: Optional<IScenario>;
|
|
174
|
+
_isHeadfulBrowser: boolean;
|
|
174
175
|
externalLeakFilter?: Optional<ILeakFilter>;
|
|
175
176
|
monoRepoDir: string;
|
|
176
177
|
muteConsole: boolean;
|
|
@@ -192,6 +193,8 @@ export declare class MemLabConfig {
|
|
|
192
193
|
get isFullRun(): boolean;
|
|
193
194
|
set browser(v: string);
|
|
194
195
|
get browser(): string;
|
|
196
|
+
set isHeadfulBrowser(isHeadful: boolean);
|
|
197
|
+
get isHeadfulBrowser(): boolean;
|
|
195
198
|
get browserBinaryPath(): string;
|
|
196
199
|
set reportLeaksInTimers(flag: boolean);
|
|
197
200
|
get reportLeaksInTimers(): boolean;
|
package/dist/lib/Config.js
CHANGED
|
@@ -54,6 +54,7 @@ class MemLabConfig {
|
|
|
54
54
|
this._deviceManualOverridden = false;
|
|
55
55
|
this._timerNodes = ['Pending activities'];
|
|
56
56
|
this._timerEdges = [];
|
|
57
|
+
this._isHeadfulBrowser = false;
|
|
57
58
|
this.targetApp = Constant_1.default.unset;
|
|
58
59
|
this.targetTab = Constant_1.default.unset;
|
|
59
60
|
this.analysisMode = Constant_1.default.unset;
|
|
@@ -66,6 +67,7 @@ class MemLabConfig {
|
|
|
66
67
|
this.specifiedEngine = false;
|
|
67
68
|
// set puppeteer configuration
|
|
68
69
|
this.puppeteerConfig = {
|
|
70
|
+
headless: !this._isHeadfulBrowser,
|
|
69
71
|
devtools: this.openDevtoolsConsole,
|
|
70
72
|
// IMPORTANT: test ContinuousTest before change this config
|
|
71
73
|
ignoreHTTPSErrors: true,
|
|
@@ -358,6 +360,17 @@ class MemLabConfig {
|
|
|
358
360
|
get browser() {
|
|
359
361
|
return this._browser || 'google-chrome';
|
|
360
362
|
}
|
|
363
|
+
set isHeadfulBrowser(isHeadful) {
|
|
364
|
+
this._isHeadfulBrowser = isHeadful;
|
|
365
|
+
this.puppeteerConfig.headless = !isHeadful;
|
|
366
|
+
if (isHeadful) {
|
|
367
|
+
// if running in headful mode
|
|
368
|
+
this.disableXvfb();
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
get isHeadfulBrowser() {
|
|
372
|
+
return this._isHeadfulBrowser;
|
|
373
|
+
}
|
|
361
374
|
get browserBinaryPath() {
|
|
362
375
|
return path_1.default.join(this.browserDir, this.browser);
|
|
363
376
|
}
|
package/dist/lib/Console.d.ts
CHANGED
package/dist/lib/Console.js
CHANGED
package/dist/lib/Constant.js
CHANGED
|
@@ -13,8 +13,8 @@ const InternalValueSetter_1 = require("./InternalValueSetter");
|
|
|
13
13
|
const constants = {
|
|
14
14
|
isFB: false,
|
|
15
15
|
isFRL: false,
|
|
16
|
-
defaultEngine: '
|
|
17
|
-
supportedEngines: ['
|
|
16
|
+
defaultEngine: 'V8',
|
|
17
|
+
supportedEngines: ['V8', 'hermes'],
|
|
18
18
|
supportedBrowsers: Object.create(null),
|
|
19
19
|
internalDir: 'fb-internal',
|
|
20
20
|
monoRepoDir: '',
|
|
@@ -43,6 +43,8 @@ export declare class FileManager {
|
|
|
43
43
|
getAllFilesInDir(dir: string): string[];
|
|
44
44
|
getDataOutDir(options?: FileOption): string;
|
|
45
45
|
getCoreProjectBaseDir(): string;
|
|
46
|
+
getMonoRepoDir(): string;
|
|
47
|
+
getDocDir(): string;
|
|
46
48
|
getReportOutDir(options?: FileOption): string;
|
|
47
49
|
getPreviewReportDir(options?: FileOption): string;
|
|
48
50
|
getLeakSummaryFile(options?: FileOption): string;
|
package/dist/lib/FileManager.js
CHANGED
|
@@ -133,6 +133,12 @@ class FileManager {
|
|
|
133
133
|
getCoreProjectBaseDir() {
|
|
134
134
|
return path_1.default.join(__dirname, '..', '..');
|
|
135
135
|
}
|
|
136
|
+
getMonoRepoDir() {
|
|
137
|
+
return path_1.default.join(this.getCoreProjectBaseDir(), '..', '..');
|
|
138
|
+
}
|
|
139
|
+
getDocDir() {
|
|
140
|
+
return path_1.default.join(this.getMonoRepoDir(), 'website', 'docs');
|
|
141
|
+
}
|
|
136
142
|
getReportOutDir(options = {}) {
|
|
137
143
|
return path_1.default.join(this.getPersistDataDir(options), 'reports');
|
|
138
144
|
}
|
package/dist/lib/HeapParser.js
CHANGED
|
@@ -102,7 +102,7 @@ function identifyAndSetEngine(snapshot) {
|
|
|
102
102
|
return; // skip if engine type is manually set
|
|
103
103
|
}
|
|
104
104
|
Console_1.default.overwrite('identifying snapshot engine...');
|
|
105
|
-
let engine = '
|
|
105
|
+
let engine = 'V8';
|
|
106
106
|
snapshot.nodes.forEach((node) => {
|
|
107
107
|
if (node.type === 'object' && node.name.startsWith('Object(')) {
|
|
108
108
|
engine = 'hermes';
|
package/dist/lib/NodeHeap.d.ts
CHANGED
|
@@ -7,10 +7,69 @@
|
|
|
7
7
|
* @emails oncall+ws_labs
|
|
8
8
|
* @format
|
|
9
9
|
*/
|
|
10
|
-
import type {
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
import type { IHeapSnapshot } from './Types';
|
|
11
|
+
/**
|
|
12
|
+
* Tags a string marker to an object instance, which can later be checked by
|
|
13
|
+
* {@link hasObjectWithTag}. This API does not modify the object instance in
|
|
14
|
+
* any way (e.g., no additional or hidden properties added to the tagged
|
|
15
|
+
* object).
|
|
16
|
+
*
|
|
17
|
+
* @param o specify the object instance you want to tag, you cannot tag a
|
|
18
|
+
* [primitive](https://developer.mozilla.org/en-US/docs/Glossary/Primitive).
|
|
19
|
+
* @param tag marker name to tag on the object instance
|
|
20
|
+
* @returns returns the tagged object instance (same reference as
|
|
21
|
+
* the input argument `o`)
|
|
22
|
+
* * **Examples**:
|
|
23
|
+
* ```typescript
|
|
24
|
+
* import type {IHeapSnapshot, AnyValue} from '@memlab/core';
|
|
25
|
+
* import {config, getNodeInnocentHeap, tagObject} from '@memlab/core';
|
|
26
|
+
*
|
|
27
|
+
* test('memory test', async () => {
|
|
28
|
+
* config.muteConsole = true;
|
|
29
|
+
* const o1: AnyValue = {};
|
|
30
|
+
* let o2: AnyValue = {};
|
|
31
|
+
*
|
|
32
|
+
* // tag o1 with marker: "memlab-mark-1", does not modify o1 in any way
|
|
33
|
+
* tagObject(o1, 'memlab-mark-1');
|
|
34
|
+
* // tag o2 with marker: "memlab-mark-2", does not modify o2 in any way
|
|
35
|
+
* tagObject(o2, 'memlab-mark-2');
|
|
36
|
+
*
|
|
37
|
+
* o2 = null;
|
|
38
|
+
*
|
|
39
|
+
* const heap: IHeapSnapshot = await getNodeInnocentHeap();
|
|
40
|
+
*
|
|
41
|
+
* // expect object with marker "memlab-mark-1" exists
|
|
42
|
+
* expect(heap.hasObjectWithTag('memlab-mark-1')).toBe(true);
|
|
43
|
+
*
|
|
44
|
+
* // expect object with marker "memlab-mark-2" can be GCed
|
|
45
|
+
* expect(heap.hasObjectWithTag('memlab-mark-2')).toBe(false);
|
|
46
|
+
*
|
|
47
|
+
* }, 30000);
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export declare function tagObject<T extends object>(o: T, tag: string): T;
|
|
13
51
|
export declare function dumpNodeHeapSnapshot(): string;
|
|
14
|
-
|
|
15
|
-
|
|
52
|
+
/**
|
|
53
|
+
* Take a heap snapshot of the current program state
|
|
54
|
+
* and parse it as {@link IHeapSnapshot}. Notice that
|
|
55
|
+
* this API does not calculate some heap analysis meta data
|
|
56
|
+
* for heap analysis. But this also means faster heap parsing.
|
|
57
|
+
*
|
|
58
|
+
* @returns heap representation without heap analysis meta data.
|
|
59
|
+
*
|
|
60
|
+
* If you need to get the heap snapshot with heap analysis meta data
|
|
61
|
+
* use {@link dumpNodeHeapSnapshot} and {@link getHeapFromFile},
|
|
62
|
+
* for example:
|
|
63
|
+
* ```typescript
|
|
64
|
+
* import type {IHeapSnapshot} from '@memlab/core';
|
|
65
|
+
* import {dumpNodeHeapSnapshot} from '@memlab/core';
|
|
66
|
+
* import {getHeapFromFile} from '@memlab/heap-analysis';
|
|
67
|
+
*
|
|
68
|
+
* (async function () {
|
|
69
|
+
* const heapFile = dumpNodeHeapSnapshot();
|
|
70
|
+
* const heap: IHeapSnapshot = await getHeapFromFile(heapFile);
|
|
71
|
+
* })();
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
export declare function getNodeInnocentHeap(): Promise<IHeapSnapshot>;
|
|
16
75
|
//# sourceMappingURL=NodeHeap.d.ts.map
|
package/dist/lib/NodeHeap.js
CHANGED
|
@@ -21,7 +21,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
21
21
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
22
22
|
};
|
|
23
23
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
-
exports.
|
|
24
|
+
exports.getNodeInnocentHeap = exports.dumpNodeHeapSnapshot = exports.tagObject = void 0;
|
|
25
25
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
26
26
|
const path_1 = __importDefault(require("path"));
|
|
27
27
|
const v8_1 = __importDefault(require("v8"));
|
|
@@ -33,6 +33,45 @@ class MemLabTaggedStore {
|
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
const store = new MemLabTaggedStore();
|
|
36
|
+
/**
|
|
37
|
+
* Tags a string marker to an object instance, which can later be checked by
|
|
38
|
+
* {@link hasObjectWithTag}. This API does not modify the object instance in
|
|
39
|
+
* any way (e.g., no additional or hidden properties added to the tagged
|
|
40
|
+
* object).
|
|
41
|
+
*
|
|
42
|
+
* @param o specify the object instance you want to tag, you cannot tag a
|
|
43
|
+
* [primitive](https://developer.mozilla.org/en-US/docs/Glossary/Primitive).
|
|
44
|
+
* @param tag marker name to tag on the object instance
|
|
45
|
+
* @returns returns the tagged object instance (same reference as
|
|
46
|
+
* the input argument `o`)
|
|
47
|
+
* * **Examples**:
|
|
48
|
+
* ```typescript
|
|
49
|
+
* import type {IHeapSnapshot, AnyValue} from '@memlab/core';
|
|
50
|
+
* import {config, getNodeInnocentHeap, tagObject} from '@memlab/core';
|
|
51
|
+
*
|
|
52
|
+
* test('memory test', async () => {
|
|
53
|
+
* config.muteConsole = true;
|
|
54
|
+
* const o1: AnyValue = {};
|
|
55
|
+
* let o2: AnyValue = {};
|
|
56
|
+
*
|
|
57
|
+
* // tag o1 with marker: "memlab-mark-1", does not modify o1 in any way
|
|
58
|
+
* tagObject(o1, 'memlab-mark-1');
|
|
59
|
+
* // tag o2 with marker: "memlab-mark-2", does not modify o2 in any way
|
|
60
|
+
* tagObject(o2, 'memlab-mark-2');
|
|
61
|
+
*
|
|
62
|
+
* o2 = null;
|
|
63
|
+
*
|
|
64
|
+
* const heap: IHeapSnapshot = await getNodeInnocentHeap();
|
|
65
|
+
*
|
|
66
|
+
* // expect object with marker "memlab-mark-1" exists
|
|
67
|
+
* expect(heap.hasObjectWithTag('memlab-mark-1')).toBe(true);
|
|
68
|
+
*
|
|
69
|
+
* // expect object with marker "memlab-mark-2" can be GCed
|
|
70
|
+
* expect(heap.hasObjectWithTag('memlab-mark-2')).toBe(false);
|
|
71
|
+
*
|
|
72
|
+
* }, 30000);
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
36
75
|
function tagObject(o, tag) {
|
|
37
76
|
if (!store.taggedObjects[tag]) {
|
|
38
77
|
store.taggedObjects[tag] = new WeakSet();
|
|
@@ -47,7 +86,29 @@ function dumpNodeHeapSnapshot() {
|
|
|
47
86
|
return file;
|
|
48
87
|
}
|
|
49
88
|
exports.dumpNodeHeapSnapshot = dumpNodeHeapSnapshot;
|
|
50
|
-
|
|
89
|
+
/**
|
|
90
|
+
* Take a heap snapshot of the current program state
|
|
91
|
+
* and parse it as {@link IHeapSnapshot}. Notice that
|
|
92
|
+
* this API does not calculate some heap analysis meta data
|
|
93
|
+
* for heap analysis. But this also means faster heap parsing.
|
|
94
|
+
*
|
|
95
|
+
* @returns heap representation without heap analysis meta data.
|
|
96
|
+
*
|
|
97
|
+
* If you need to get the heap snapshot with heap analysis meta data
|
|
98
|
+
* use {@link dumpNodeHeapSnapshot} and {@link getHeapFromFile},
|
|
99
|
+
* for example:
|
|
100
|
+
* ```typescript
|
|
101
|
+
* import type {IHeapSnapshot} from '@memlab/core';
|
|
102
|
+
* import {dumpNodeHeapSnapshot} from '@memlab/core';
|
|
103
|
+
* import {getHeapFromFile} from '@memlab/heap-analysis';
|
|
104
|
+
*
|
|
105
|
+
* (async function () {
|
|
106
|
+
* const heapFile = dumpNodeHeapSnapshot();
|
|
107
|
+
* const heap: IHeapSnapshot = await getHeapFromFile(heapFile);
|
|
108
|
+
* })();
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
111
|
+
function getNodeInnocentHeap() {
|
|
51
112
|
return __awaiter(this, void 0, void 0, function* () {
|
|
52
113
|
const file = dumpNodeHeapSnapshot();
|
|
53
114
|
const snapshot = yield Utils_1.default.getSnapshotFromFile(file, {
|
|
@@ -59,4 +120,4 @@ function getCurrentNodeHeap() {
|
|
|
59
120
|
return snapshot;
|
|
60
121
|
});
|
|
61
122
|
}
|
|
62
|
-
exports.
|
|
123
|
+
exports.getNodeInnocentHeap = getNodeInnocentHeap;
|
package/dist/lib/Serializer.js
CHANGED
|
@@ -182,6 +182,9 @@ function JSONifyFiberNodeReturnTrace(node, args, options) {
|
|
|
182
182
|
continue;
|
|
183
183
|
}
|
|
184
184
|
const parent = node.snapshot.nodes.get(index);
|
|
185
|
+
if (!parent) {
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
185
188
|
const parentInfo = getNodeNameInJSON(parent, args);
|
|
186
189
|
key = `${key}: --return (property)---> ${parentInfo}`;
|
|
187
190
|
const info = JSONifyFiberNodeShallow(parent);
|
|
@@ -593,7 +596,7 @@ function summarizeNode(node, options = {}) {
|
|
|
593
596
|
let nodeImpact = '';
|
|
594
597
|
if (nodeRetainSize) {
|
|
595
598
|
nodeImpact = options.color
|
|
596
|
-
? chalk_1.default.grey('[') + chalk_1.default.blue(nodeRetainSize) + chalk_1.default.grey(']')
|
|
599
|
+
? chalk_1.default.grey('[') + chalk_1.default.blue.bold(nodeRetainSize) + chalk_1.default.grey(']')
|
|
597
600
|
: `[${nodeRetainSize}]`;
|
|
598
601
|
}
|
|
599
602
|
const name = summarizeNodeName(node, options);
|