@memlab/heap-analysis 1.0.5 → 1.0.9

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 (46) hide show
  1. package/dist/BaseAnalysis.d.ts +1 -1
  2. package/dist/BaseAnalysis.js +2 -2
  3. package/dist/HeapAnalysisLoader.d.ts +1 -1
  4. package/dist/HeapAnalysisLoader.js +1 -1
  5. package/dist/HeapConfig.d.ts +21 -0
  6. package/dist/HeapConfig.js +29 -0
  7. package/dist/PluginUtils.d.ts +31 -5
  8. package/dist/PluginUtils.js +85 -10
  9. package/dist/__tests__/HeapAnalysis.test.d.ts +1 -1
  10. package/dist/__tests__/HeapAnalysis.test.js +20 -2
  11. package/dist/__tests__/package.test.js +8 -7
  12. package/dist/index.d.ts +6 -2
  13. package/dist/index.js +8 -3
  14. package/dist/options/HeapAnalysisNodeIdOption.d.ts +19 -0
  15. package/dist/options/HeapAnalysisNodeIdOption.js +45 -0
  16. package/dist/options/HeapAnalysisSnapshotDirectoryOption.d.ts +1 -1
  17. package/dist/options/HeapAnalysisSnapshotDirectoryOption.js +1 -1
  18. package/dist/options/HeapAnalysisSnapshotFileOption.d.ts +1 -1
  19. package/dist/options/HeapAnalysisSnapshotFileOption.js +1 -1
  20. package/dist/plugins/CollectionsHoldingStaleAnalysis.d.ts +1 -1
  21. package/dist/plugins/CollectionsHoldingStaleAnalysis.js +1 -1
  22. package/dist/plugins/DetachedDOMElementAnalysis.d.ts +1 -1
  23. package/dist/plugins/DetachedDOMElementAnalysis.js +1 -1
  24. package/dist/plugins/GlobalVariableAnalysis/BuiltInGlobalVariables.d.ts +2 -2
  25. package/dist/plugins/GlobalVariableAnalysis/BuiltInGlobalVariables.js +2 -2
  26. package/dist/plugins/GlobalVariableAnalysis/GlobalVariableAnalysis.d.ts +1 -1
  27. package/dist/plugins/GlobalVariableAnalysis/GlobalVariableAnalysis.js +1 -2
  28. package/dist/plugins/ObjectContentAnalysis.d.ts +29 -0
  29. package/dist/plugins/ObjectContentAnalysis.js +108 -0
  30. package/dist/plugins/ObjectFanoutAnalysis.d.ts +1 -1
  31. package/dist/plugins/ObjectFanoutAnalysis.js +1 -1
  32. package/dist/plugins/ObjectShallowAnalysis.d.ts +1 -1
  33. package/dist/plugins/ObjectShallowAnalysis.js +1 -1
  34. package/dist/plugins/ObjectShapeAnalysis.d.ts +1 -1
  35. package/dist/plugins/ObjectShapeAnalysis.js +1 -1
  36. package/dist/plugins/ObjectSizeAnalysis.d.ts +1 -1
  37. package/dist/plugins/ObjectSizeAnalysis.js +1 -1
  38. package/dist/plugins/ObjectUnboundGrowthAnalysis.d.ts +1 -1
  39. package/dist/plugins/ObjectUnboundGrowthAnalysis.js +1 -1
  40. package/dist/plugins/ShapeUnboundGrowthAnalysis.d.ts +1 -1
  41. package/dist/plugins/ShapeUnboundGrowthAnalysis.js +1 -1
  42. package/dist/plugins/StringAnalysis.d.ts +1 -1
  43. package/dist/plugins/StringAnalysis.js +2 -2
  44. package/dist/plugins/UnmountedReactFiberNodesAnalysis.d.ts +1 -1
  45. package/dist/plugins/UnmountedReactFiberNodesAnalysis.js +1 -1
  46. package/package.json +3 -3
@@ -4,8 +4,8 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @emails oncall+ws_labs
8
7
  * @format
8
+ * @oncall ws_labs
9
9
  */
10
10
  import type { AnyValue } from '@memlab/core';
11
11
  import type { HeapAnalysisOptions } from './PluginUtils';
@@ -5,8 +5,8 @@
5
5
  * This source code is licensed under the MIT license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  *
8
- * @emails oncall+ws_labs
9
8
  * @format
9
+ * @oncall ws_labs
10
10
  */
11
11
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
12
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
@@ -62,7 +62,7 @@ class Analysis {
62
62
  run(options = PluginUtils_1.default.defaultAnalysisArgs) {
63
63
  return __awaiter(this, void 0, void 0, function* () {
64
64
  loadScenarioConfig();
65
- return yield this.process(options);
65
+ yield this.process(options);
66
66
  });
67
67
  }
68
68
  /**
@@ -4,8 +4,8 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @emails oncall+ws_labs
8
7
  * @format
8
+ * @oncall ws_labs
9
9
  */
10
10
  import type BaseAnalysis from './BaseAnalysis';
11
11
  declare class HeapAnalysisLoader {
@@ -5,8 +5,8 @@
5
5
  * This source code is licensed under the MIT license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  *
8
- * @emails oncall+ws_labs
9
8
  * @format
9
+ * @oncall ws_labs
10
10
  */
11
11
  var __importDefault = (this && this.__importDefault) || function (mod) {
12
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
@@ -0,0 +1,21 @@
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
+ * @format
8
+ * @oncall ws_labs
9
+ */
10
+ import type { IHeapSnapshot, Optional, IHeapConfig } from '@memlab/core';
11
+ declare class HeapConfig implements IHeapConfig {
12
+ isCliInteractiveMode: boolean;
13
+ currentHeapFile: Optional<string>;
14
+ currentHeap: Optional<IHeapSnapshot>;
15
+ private constructor();
16
+ private static instance;
17
+ static getInstance(): HeapConfig;
18
+ }
19
+ declare const heapConfig: HeapConfig;
20
+ export default heapConfig;
21
+ //# sourceMappingURL=HeapConfig.d.ts.map
@@ -0,0 +1,29 @@
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
+ * @format
9
+ * @oncall ws_labs
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const core_1 = require("@memlab/core");
13
+ class HeapConfig {
14
+ constructor() {
15
+ this.isCliInteractiveMode = false;
16
+ this.currentHeap = null;
17
+ this.currentHeapFile = null;
18
+ }
19
+ static getInstance() {
20
+ if (!HeapConfig.instance) {
21
+ HeapConfig.instance = new HeapConfig();
22
+ }
23
+ return HeapConfig.instance;
24
+ }
25
+ }
26
+ HeapConfig.instance = null;
27
+ const heapConfig = HeapConfig.getInstance();
28
+ core_1.config.heapConfig = heapConfig;
29
+ exports.default = heapConfig;
@@ -4,8 +4,8 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @emails oncall+ws_labs
8
7
  * @format
8
+ * @oncall ws_labs
9
9
  */
10
10
  import type { ParsedArgs } from 'minimist';
11
11
  import { IHeapSnapshot, IHeapNode, AnyOptions, IHeapEdge, Nullable, MemLabConfig } from '@memlab/core';
@@ -31,6 +31,7 @@ declare type PrintNodeOption = {
31
31
  };
32
32
  declare function printNodeListInTerminal(nodeList: IHeapNode[], options?: AnyOptions & PrintNodeOption): void;
33
33
  declare function printReferencesInTerminal(edgeList: IHeapEdge[], options?: AnyOptions & PrintNodeOption): void;
34
+ declare function printReferrersInTerminal(edgeList: IHeapEdge[], options?: AnyOptions & PrintNodeOption): void;
34
35
  declare function getObjectOutgoingEdgeCount(node: IHeapNode): number;
35
36
  /**
36
37
  * Get the heap snapshot file's absolute path passed to the hosting heap
@@ -166,14 +167,36 @@ declare function loadHeapSnapshot(options: HeapAnalysisOptions): Promise<IHeapSn
166
167
  * * **Examples**:
167
168
  * ```typescript
168
169
  * import {dumpNodeHeapSnapshot} from '@memlab/core';
169
- * import {getHeapFromFile} from '@memlab/heap-analysis';
170
+ * import {getFullHeapFromFile} from '@memlab/heap-analysis';
170
171
  *
171
172
  * (async function (){
172
173
  * const heapFile = dumpNodeHeapSnapshot();
173
- * const heap = await getHeapFromFile(heapFile);
174
+ * const heap = await getFullHeapFromFile(heapFile);
174
175
  * })();
175
176
  * ```
176
177
  */
178
+ declare function getFullHeapFromFile(file: string): Promise<IHeapSnapshot>;
179
+ /**
180
+ * Take a heap snapshot of the current program state
181
+ * and parse it as {@link IHeapSnapshot}. This
182
+ * API also calculates some heap analysis meta data
183
+ * for heap analysis. But this also means slower heap parsing
184
+ * comparing with {@link takeNodeMinimalHeap}.
185
+ *
186
+ * @returns heap representation with heap analysis meta data.
187
+ *
188
+ * * **Examples:**
189
+ * ```typescript
190
+ * import type {IHeapSnapshot} from '@memlab/core';
191
+ * import type {takeNodeFullHeap} from '@memlab/heap-analysis';
192
+ *
193
+ * (async function () {
194
+ * const heap: IHeapSnapshot = await takeNodeFullHeap();
195
+ * })();
196
+ * ```
197
+ */
198
+ declare function takeNodeFullHeap(): Promise<IHeapSnapshot>;
199
+ /** @deprecated */
177
200
  declare function getHeapFromFile(file: string): Promise<IHeapSnapshot>;
178
201
  /**
179
202
  * When a heap analysis is taking multiple heap snapshots as input for memory
@@ -261,7 +284,7 @@ declare function aggregateDominatorMetrics(ids: Set<number>, snapshot: IHeapSnap
261
284
  * * * **Examples**:
262
285
  * ```typescript
263
286
  * import {dumpNodeHeapSnapshot} from '@memlab/core';
264
- * import {getHeapFromFile, getDominatorNodes} from '@memlab/heap-analysis';
287
+ * import {getFullHeapFromFile, getDominatorNodes} from '@memlab/heap-analysis';
265
288
  *
266
289
  * class TestObject {}
267
290
  *
@@ -271,7 +294,7 @@ declare function aggregateDominatorMetrics(ids: Set<number>, snapshot: IHeapSnap
271
294
  *
272
295
  * // dump the heap of this running JavaScript program
273
296
  * const heapFile = dumpNodeHeapSnapshot();
274
- * const heap = await getHeapFromFile(heapFile);
297
+ * const heap = await getFullHeapFromFile(heapFile);
275
298
  *
276
299
  * // find the heap node for TestObject
277
300
  * let nodes = [];
@@ -306,9 +329,12 @@ declare const _default: {
306
329
  isNodeWorthInspecting: typeof isNodeWorthInspecting;
307
330
  loadHeapSnapshot: typeof loadHeapSnapshot;
308
331
  getHeapFromFile: typeof getHeapFromFile;
332
+ getFullHeapFromFile: typeof getFullHeapFromFile;
309
333
  printNodeListInTerminal: typeof printNodeListInTerminal;
310
334
  printReferencesInTerminal: typeof printReferencesInTerminal;
335
+ printReferrersInTerminal: typeof printReferrersInTerminal;
311
336
  snapshotMapReduce: typeof snapshotMapReduce;
337
+ takeNodeFullHeap: typeof takeNodeFullHeap;
312
338
  };
313
339
  export default _default;
314
340
  //# sourceMappingURL=PluginUtils.d.ts.map
@@ -5,8 +5,8 @@
5
5
  * This source code is licensed under the MIT license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  *
8
- * @emails oncall+ws_labs
9
8
  * @format
9
+ * @oncall ws_labs
10
10
  */
11
11
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
12
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
@@ -24,6 +24,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
24
24
  const core_1 = require("@memlab/core");
25
25
  const chalk_1 = __importDefault(require("chalk"));
26
26
  const core_2 = require("@memlab/core");
27
+ const HeapConfig_1 = __importDefault(require("./HeapConfig"));
27
28
  const nodeNameBlockList = new Set([
28
29
  '(Startup object cache)',
29
30
  '(Global handles)',
@@ -163,6 +164,7 @@ function getHeapObjectString(node) {
163
164
  return (`${nodeId}${type} ${shapeStr}${colon} ` +
164
165
  `${fanout}${comma} ${bytes}${comma} ${refs}`);
165
166
  }
167
+ const MAX_NUM_OF_EDGES_TO_PRINT = 50;
166
168
  function getReferenceString(edge) {
167
169
  const edgeName = chalk_1.default.green(edge.name_or_index);
168
170
  const objectInfo = getHeapObjectString(edge.toNode);
@@ -171,10 +173,39 @@ function getReferenceString(edge) {
171
173
  function printReferencesInTerminal(edgeList, options = {}) {
172
174
  const dot = chalk_1.default.grey('· ');
173
175
  const indent = options.indent || '';
176
+ let n = 0;
174
177
  for (const edge of edgeList) {
178
+ if (!core_1.config.verbose && n >= MAX_NUM_OF_EDGES_TO_PRINT) {
179
+ break;
180
+ }
181
+ ++n;
175
182
  const refStr = getReferenceString(edge);
176
183
  core_2.info.topLevel(`${indent}${dot}${refStr}`);
177
184
  }
185
+ if (n < edgeList.length) {
186
+ core_2.info.lowLevel(`${edgeList.length - n} more references...`);
187
+ }
188
+ }
189
+ function getReferrerString(edge) {
190
+ const edgeName = chalk_1.default.green(edge.name_or_index);
191
+ const objectInfo = getHeapObjectString(edge.fromNode);
192
+ return ` ${objectInfo} --${edgeName}--> `;
193
+ }
194
+ function printReferrersInTerminal(edgeList, options = {}) {
195
+ const dot = chalk_1.default.grey('· ');
196
+ const indent = options.indent || '';
197
+ let n = 0;
198
+ for (const edge of edgeList) {
199
+ if (!core_1.config.verbose && n >= MAX_NUM_OF_EDGES_TO_PRINT) {
200
+ break;
201
+ }
202
+ ++n;
203
+ const refStr = getReferrerString(edge);
204
+ core_2.info.topLevel(`${indent}${dot}${refStr}`);
205
+ }
206
+ if (n < edgeList.length) {
207
+ core_2.info.lowLevel(`${edgeList.length - n} more referrers...`);
208
+ }
178
209
  }
179
210
  function getObjectOutgoingEdgeCount(node) {
180
211
  if (node.name === 'Set' || node.name === 'Map') {
@@ -231,9 +262,6 @@ function getSnapshotFileForAnalysis(options) {
231
262
  if (args.snapshot) {
232
263
  return args.snapshot;
233
264
  }
234
- if (core_1.config.externalSnapshotFilePaths.length > 0) {
235
- return core_1.config.externalSnapshotFilePaths[core_1.config.externalSnapshotFilePaths.length - 1];
236
- }
237
265
  return core_2.utils.getSingleSnapshotFileForAnalysis();
238
266
  }
239
267
  /**
@@ -330,8 +358,19 @@ function getSnapshotDirForAnalysis(options) {
330
358
  */
331
359
  function loadHeapSnapshot(options) {
332
360
  return __awaiter(this, void 0, void 0, function* () {
333
- const file = getSnapshotFileForAnalysis(options);
334
- return loadProcessedSnapshot({ file });
361
+ if (HeapConfig_1.default.isCliInteractiveMode) {
362
+ if (!HeapConfig_1.default.currentHeap) {
363
+ const file = getSnapshotFileForAnalysis(options);
364
+ const heap = yield loadProcessedSnapshot({ file });
365
+ HeapConfig_1.default.currentHeapFile = file;
366
+ HeapConfig_1.default.currentHeap = heap;
367
+ }
368
+ return HeapConfig_1.default.currentHeap;
369
+ }
370
+ else {
371
+ const file = getSnapshotFileForAnalysis(options);
372
+ return loadProcessedSnapshot({ file });
373
+ }
335
374
  });
336
375
  }
337
376
  /**
@@ -343,14 +382,47 @@ function loadHeapSnapshot(options) {
343
382
  * * **Examples**:
344
383
  * ```typescript
345
384
  * import {dumpNodeHeapSnapshot} from '@memlab/core';
346
- * import {getHeapFromFile} from '@memlab/heap-analysis';
385
+ * import {getFullHeapFromFile} from '@memlab/heap-analysis';
347
386
  *
348
387
  * (async function (){
349
388
  * const heapFile = dumpNodeHeapSnapshot();
350
- * const heap = await getHeapFromFile(heapFile);
389
+ * const heap = await getFullHeapFromFile(heapFile);
351
390
  * })();
352
391
  * ```
353
392
  */
393
+ function getFullHeapFromFile(file) {
394
+ return __awaiter(this, void 0, void 0, function* () {
395
+ return yield loadProcessedSnapshot({ file });
396
+ });
397
+ }
398
+ /**
399
+ * Take a heap snapshot of the current program state
400
+ * and parse it as {@link IHeapSnapshot}. This
401
+ * API also calculates some heap analysis meta data
402
+ * for heap analysis. But this also means slower heap parsing
403
+ * comparing with {@link takeNodeMinimalHeap}.
404
+ *
405
+ * @returns heap representation with heap analysis meta data.
406
+ *
407
+ * * **Examples:**
408
+ * ```typescript
409
+ * import type {IHeapSnapshot} from '@memlab/core';
410
+ * import type {takeNodeFullHeap} from '@memlab/heap-analysis';
411
+ *
412
+ * (async function () {
413
+ * const heap: IHeapSnapshot = await takeNodeFullHeap();
414
+ * })();
415
+ * ```
416
+ */
417
+ function takeNodeFullHeap() {
418
+ return __awaiter(this, void 0, void 0, function* () {
419
+ const heap = yield (0, core_1.takeNodeMinimalHeap)();
420
+ core_2.analysis.preparePathFinder(heap);
421
+ core_2.info.flush();
422
+ return heap;
423
+ });
424
+ }
425
+ /** @deprecated */
354
426
  function getHeapFromFile(file) {
355
427
  return __awaiter(this, void 0, void 0, function* () {
356
428
  return yield loadProcessedSnapshot({ file });
@@ -480,7 +552,7 @@ function aggregateDominatorMetrics(ids, snapshot, checkNodeCb, nodeMetricsCb) {
480
552
  * * * **Examples**:
481
553
  * ```typescript
482
554
  * import {dumpNodeHeapSnapshot} from '@memlab/core';
483
- * import {getHeapFromFile, getDominatorNodes} from '@memlab/heap-analysis';
555
+ * import {getFullHeapFromFile, getDominatorNodes} from '@memlab/heap-analysis';
484
556
  *
485
557
  * class TestObject {}
486
558
  *
@@ -490,7 +562,7 @@ function aggregateDominatorMetrics(ids, snapshot, checkNodeCb, nodeMetricsCb) {
490
562
  *
491
563
  * // dump the heap of this running JavaScript program
492
564
  * const heapFile = dumpNodeHeapSnapshot();
493
- * const heap = await getHeapFromFile(heapFile);
565
+ * const heap = await getFullHeapFromFile(heapFile);
494
566
  *
495
567
  * // find the heap node for TestObject
496
568
  * let nodes = [];
@@ -543,7 +615,10 @@ exports.default = {
543
615
  isNodeWorthInspecting,
544
616
  loadHeapSnapshot,
545
617
  getHeapFromFile,
618
+ getFullHeapFromFile,
546
619
  printNodeListInTerminal,
547
620
  printReferencesInTerminal,
621
+ printReferrersInTerminal,
548
622
  snapshotMapReduce,
623
+ takeNodeFullHeap,
549
624
  };
@@ -4,8 +4,8 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @emails oncall+ws_labs
8
7
  * @format
8
+ * @oncall ws_labs
9
9
  */
10
10
  export {};
11
11
  //# sourceMappingURL=HeapAnalysis.test.d.ts.map
@@ -5,8 +5,8 @@
5
5
  * This source code is licensed under the MIT license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  *
8
- * @emails oncall+ws_labs
9
8
  * @format
9
+ * @oncall ws_labs
10
10
  */
11
11
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
12
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
@@ -22,11 +22,29 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
22
22
  };
23
23
  Object.defineProperty(exports, "__esModule", { value: true });
24
24
  const core_1 = require("@memlab/core");
25
+ const __1 = require("..");
25
26
  const HeapAnalysisLoader_1 = __importDefault(require("../HeapAnalysisLoader"));
26
27
  beforeEach(() => {
27
28
  core_1.config.isTest = true;
28
29
  });
30
+ const timeout = 5 * 60 * 1000;
29
31
  test('Heap analysis modules can be loaded', () => __awaiter(void 0, void 0, void 0, function* () {
30
32
  const heapAnalysisMap = HeapAnalysisLoader_1.default.loadAllAnalysis();
31
33
  expect(heapAnalysisMap.size).toBeGreaterThan(0);
32
- }));
34
+ }), timeout);
35
+ test('takeNodeFullHeap works as expected', () => __awaiter(void 0, void 0, void 0, function* () {
36
+ var _a;
37
+ class TestClass {
38
+ constructor() {
39
+ this.name = 'test';
40
+ this.age = 183;
41
+ }
42
+ }
43
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
44
+ const _v = new TestClass();
45
+ const heap = yield (0, __1.takeNodeFullHeap)();
46
+ const node = heap.getAnyObjectWithClassName('TestClass');
47
+ expect((node === null || node === void 0 ? void 0 : node.dominatorNode) != null).toBe(true);
48
+ const size = (_a = node === null || node === void 0 ? void 0 : node.retainedSize) !== null && _a !== void 0 ? _a : 0;
49
+ expect(size > 0).toBe(true);
50
+ }), timeout);
@@ -14,6 +14,7 @@ const index_1 = require("../index");
14
14
  beforeEach(() => {
15
15
  core_1.config.isTest = true;
16
16
  });
17
+ const timeout = 5 * 60 * 1000;
17
18
  test('loadHeapSnapshot works as expected', () => __awaiter(void 0, void 0, void 0, function* () {
18
19
  let called = false;
19
20
  class ExampleAnalysis extends index_1.BaseAnalysis {
@@ -34,7 +35,7 @@ test('loadHeapSnapshot works as expected', () => __awaiter(void 0, void 0, void
34
35
  const analysis = new ExampleAnalysis();
35
36
  yield analysis.analyzeSnapshotFromFile((0, core_1.dumpNodeHeapSnapshot)());
36
37
  expect(called).toBe(true);
37
- }));
38
+ }), timeout);
38
39
  test('analyzeSnapshotFromFile works as expected', () => __awaiter(void 0, void 0, void 0, function* () {
39
40
  let called = false;
40
41
  const heapFile = (0, core_1.dumpNodeHeapSnapshot)();
@@ -56,12 +57,12 @@ test('analyzeSnapshotFromFile works as expected', () => __awaiter(void 0, void 0
56
57
  const analysis = new ExampleAnalysis();
57
58
  yield analysis.analyzeSnapshotFromFile(heapFile);
58
59
  expect(called).toBe(true);
59
- }));
60
- test('getHeapFromFile works as expected', () => __awaiter(void 0, void 0, void 0, function* () {
60
+ }), timeout);
61
+ test('getFullHeapFromFile works as expected', () => __awaiter(void 0, void 0, void 0, function* () {
61
62
  const heapFile = (0, core_1.dumpNodeHeapSnapshot)();
62
- const heap = yield (0, index_1.getHeapFromFile)(heapFile);
63
+ const heap = yield (0, index_1.getFullHeapFromFile)(heapFile);
63
64
  expect(heap.nodes.length > 0).toBe(true);
64
- }));
65
+ }), timeout);
65
66
  test('getDominatorNodes works as expected', () => __awaiter(void 0, void 0, void 0, function* () {
66
67
  class TestObject {
67
68
  }
@@ -71,7 +72,7 @@ test('getDominatorNodes works as expected', () => __awaiter(void 0, void 0, void
71
72
  const t2 = new TestObject();
72
73
  // dump the heap of this running JavaScript program
73
74
  const heapFile = (0, core_1.dumpNodeHeapSnapshot)();
74
- const heap = yield (0, index_1.getHeapFromFile)(heapFile);
75
+ const heap = yield (0, index_1.getFullHeapFromFile)(heapFile);
75
76
  // find the heap node for TestObject
76
77
  const nodes = [];
77
78
  heap.nodes.forEach(node => {
@@ -82,4 +83,4 @@ test('getDominatorNodes works as expected', () => __awaiter(void 0, void 0, void
82
83
  // get the dominator nodes
83
84
  const dominatorIds = (0, index_1.getDominatorNodes)(new Set(nodes.map(node => node.id)), heap);
84
85
  expect(dominatorIds.size).toBeGreaterThan(0);
85
- }));
86
+ }), timeout);
package/dist/index.d.ts CHANGED
@@ -4,12 +4,14 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @emails oncall+ws_labs
8
7
  * @format
8
+ * @oncall ws_labs
9
9
  */
10
10
  /** @internal */
11
11
  export declare function registerPackage(): Promise<void>;
12
- export declare const getDominatorNodes: (ids: Set<number>, snapshot: import("@memlab/core").IHeapSnapshot) => Set<number>, getHeapFromFile: (file: string) => Promise<import("@memlab/core").IHeapSnapshot>, getSnapshotDirForAnalysis: (options: import("./PluginUtils").HeapAnalysisOptions) => import("@memlab/core").Nullable<string>, getSnapshotFileForAnalysis: (options: import("./PluginUtils").HeapAnalysisOptions) => string, loadHeapSnapshot: (options: import("./PluginUtils").HeapAnalysisOptions) => Promise<import("@memlab/core").IHeapSnapshot>, snapshotMapReduce: <T1, T2>(mapCallback: (snapshot: import("@memlab/core").IHeapSnapshot, i: number, file: string) => T1, reduceCallback: (results: T1[]) => T2, options: import("./PluginUtils").HeapAnalysisOptions) => Promise<T2>;
12
+ export declare const getDominatorNodes: (ids: Set<number>, snapshot: import("@memlab/core").IHeapSnapshot) => Set<number>,
13
+ /** @deprecated */
14
+ getHeapFromFile: (file: string) => Promise<import("@memlab/core").IHeapSnapshot>, getFullHeapFromFile: (file: string) => Promise<import("@memlab/core").IHeapSnapshot>, getSnapshotDirForAnalysis: (options: import("./PluginUtils").HeapAnalysisOptions) => import("@memlab/core").Nullable<string>, getSnapshotFileForAnalysis: (options: import("./PluginUtils").HeapAnalysisOptions) => string, loadHeapSnapshot: (options: import("./PluginUtils").HeapAnalysisOptions) => Promise<import("@memlab/core").IHeapSnapshot>, snapshotMapReduce: <T1, T2>(mapCallback: (snapshot: import("@memlab/core").IHeapSnapshot, i: number, file: string) => T1, reduceCallback: (results: T1[]) => T2, options: import("./PluginUtils").HeapAnalysisOptions) => Promise<T2>, takeNodeFullHeap: () => Promise<import("@memlab/core").IHeapSnapshot>;
13
15
  export type { HeapAnalysisOptions } from './PluginUtils';
14
16
  export { default as BaseAnalysis } from './BaseAnalysis';
15
17
  export { default as DetachedDOMElementAnalysis } from './plugins/DetachedDOMElementAnalysis';
@@ -26,4 +28,6 @@ export { default as StringAnalysis } from './plugins/StringAnalysis';
26
28
  export { default as PluginUtils } from './PluginUtils';
27
29
  /** @internal */
28
30
  export { default as heapAnalysisLoader } from './HeapAnalysisLoader';
31
+ /** @internal */
32
+ export { default as heapConfig } from './HeapConfig';
29
33
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -5,8 +5,8 @@
5
5
  * This source code is licensed under the MIT license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  *
8
- * @emails oncall+ws_labs
9
8
  * @format
9
+ * @oncall ws_labs
10
10
  */
11
11
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
12
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
@@ -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.heapAnalysisLoader = 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.snapshotMapReduce = exports.loadHeapSnapshot = exports.getSnapshotFileForAnalysis = exports.getSnapshotDirForAnalysis = exports.getHeapFromFile = exports.getDominatorNodes = exports.registerPackage = void 0;
24
+ exports.heapConfig = exports.heapAnalysisLoader = 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.takeNodeFullHeap = exports.snapshotMapReduce = exports.loadHeapSnapshot = exports.getSnapshotFileForAnalysis = exports.getSnapshotDirForAnalysis = exports.getFullHeapFromFile = exports.getHeapFromFile = exports.getDominatorNodes = exports.registerPackage = void 0;
25
25
  const path_1 = __importDefault(require("path"));
26
26
  const core_1 = require("@memlab/core");
27
27
  /** @internal */
@@ -32,7 +32,9 @@ function registerPackage() {
32
32
  }
33
33
  exports.registerPackage = registerPackage;
34
34
  const PluginUtils_1 = __importDefault(require("./PluginUtils"));
35
- exports.getDominatorNodes = PluginUtils_1.default.getDominatorNodes, exports.getHeapFromFile = PluginUtils_1.default.getHeapFromFile, exports.getSnapshotDirForAnalysis = PluginUtils_1.default.getSnapshotDirForAnalysis, exports.getSnapshotFileForAnalysis = PluginUtils_1.default.getSnapshotFileForAnalysis, exports.loadHeapSnapshot = PluginUtils_1.default.loadHeapSnapshot, exports.snapshotMapReduce = PluginUtils_1.default.snapshotMapReduce;
35
+ exports.getDominatorNodes = PluginUtils_1.default.getDominatorNodes,
36
+ /** @deprecated */
37
+ exports.getHeapFromFile = PluginUtils_1.default.getHeapFromFile, exports.getFullHeapFromFile = PluginUtils_1.default.getFullHeapFromFile, exports.getSnapshotDirForAnalysis = PluginUtils_1.default.getSnapshotDirForAnalysis, exports.getSnapshotFileForAnalysis = PluginUtils_1.default.getSnapshotFileForAnalysis, exports.loadHeapSnapshot = PluginUtils_1.default.loadHeapSnapshot, exports.snapshotMapReduce = PluginUtils_1.default.snapshotMapReduce, exports.takeNodeFullHeap = PluginUtils_1.default.takeNodeFullHeap;
36
38
  var BaseAnalysis_1 = require("./BaseAnalysis");
37
39
  Object.defineProperty(exports, "BaseAnalysis", { enumerable: true, get: function () { return __importDefault(BaseAnalysis_1).default; } });
38
40
  var DetachedDOMElementAnalysis_1 = require("./plugins/DetachedDOMElementAnalysis");
@@ -61,3 +63,6 @@ Object.defineProperty(exports, "PluginUtils", { enumerable: true, get: function
61
63
  /** @internal */
62
64
  var HeapAnalysisLoader_1 = require("./HeapAnalysisLoader");
63
65
  Object.defineProperty(exports, "heapAnalysisLoader", { enumerable: true, get: function () { return __importDefault(HeapAnalysisLoader_1).default; } });
66
+ /** @internal */
67
+ var HeapConfig_1 = require("./HeapConfig");
68
+ Object.defineProperty(exports, "heapConfig", { enumerable: true, get: function () { return __importDefault(HeapConfig_1).default; } });
@@ -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
+ * @format
8
+ * @oncall ws_labs
9
+ */
10
+ import type { ParsedArgs } from 'minimist';
11
+ import type { MemLabConfig } from '@memlab/core';
12
+ import { BaseOption } from '@memlab/core';
13
+ export default class HeapAnalysisNodeIdOption extends BaseOption {
14
+ getOptionName(): string;
15
+ getDescription(): string;
16
+ getExampleValues(): string[];
17
+ parse(config: MemLabConfig, args: ParsedArgs): Promise<void>;
18
+ }
19
+ //# sourceMappingURL=HeapAnalysisNodeIdOption.d.ts.map
@@ -0,0 +1,45 @@
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
+ * @format
9
+ * @oncall ws_labs
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
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ const core_1 = require("@memlab/core");
22
+ class HeapAnalysisNodeIdOption extends core_1.BaseOption {
23
+ getOptionName() {
24
+ return 'node-id';
25
+ }
26
+ getDescription() {
27
+ return 'set heap node ID';
28
+ }
29
+ getExampleValues() {
30
+ return ['94435', '@94435'];
31
+ }
32
+ parse(config, args) {
33
+ return __awaiter(this, void 0, void 0, function* () {
34
+ const optionName = this.getOptionName();
35
+ const optionValue = args[optionName];
36
+ if (optionValue) {
37
+ if (typeof optionValue === 'string' && optionValue.startsWith('@')) {
38
+ args[optionName] = optionValue.slice(1);
39
+ }
40
+ config.focusFiberNodeId = Number(args[optionName]);
41
+ }
42
+ });
43
+ }
44
+ }
45
+ exports.default = HeapAnalysisNodeIdOption;
@@ -4,8 +4,8 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @emails oncall+ws_labs
8
7
  * @format
8
+ * @oncall ws_labs
9
9
  */
10
10
  import type { ParsedArgs } from 'minimist';
11
11
  import { BaseOption, MemLabConfig } from '@memlab/core';
@@ -5,8 +5,8 @@
5
5
  * This source code is licensed under the MIT license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  *
8
- * @emails oncall+ws_labs
9
8
  * @format
9
+ * @oncall ws_labs
10
10
  */
11
11
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
12
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
@@ -4,8 +4,8 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @emails oncall+ws_labs
8
7
  * @format
8
+ * @oncall ws_labs
9
9
  */
10
10
  import type { ParsedArgs } from 'minimist';
11
11
  import { BaseOption, MemLabConfig } from '@memlab/core';
@@ -5,8 +5,8 @@
5
5
  * This source code is licensed under the MIT license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  *
8
- * @emails oncall+ws_labs
9
8
  * @format
9
+ * @oncall ws_labs
10
10
  */
11
11
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
12
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
@@ -4,8 +4,8 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @emails oncall+ws_labs
8
7
  * @format
8
+ * @oncall ws_labs
9
9
  */
10
10
  import type { HeapAnalysisOptions } from '../PluginUtils';
11
11
  import { BaseOption } from '@memlab/core';
@@ -5,8 +5,8 @@
5
5
  * This source code is licensed under the MIT license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  *
8
- * @emails oncall+ws_labs
9
8
  * @format
9
+ * @oncall ws_labs
10
10
  */
11
11
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
12
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
@@ -4,8 +4,8 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @emails oncall+ws_labs
8
7
  * @format
8
+ * @oncall ws_labs
9
9
  */
10
10
  import type { HeapAnalysisOptions } from '../PluginUtils';
11
11
  import type { IHeapNode } from '@memlab/core';
@@ -5,8 +5,8 @@
5
5
  * This source code is licensed under the MIT license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  *
8
- * @emails oncall+ws_labs
9
8
  * @format
9
+ * @oncall ws_labs
10
10
  */
11
11
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
12
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
@@ -4,9 +4,9 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @emails oncall+ws_labs
8
- * @lightSyntaxTransform
9
7
  * @format
8
+ * @lightSyntaxTransform
9
+ * @oncall ws_labs
10
10
  */
11
11
  declare const _default: Set<string>;
12
12
  export default _default;
@@ -5,9 +5,9 @@
5
5
  * This source code is licensed under the MIT license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  *
8
- * @emails oncall+ws_labs
9
- * @lightSyntaxTransform
10
8
  * @format
9
+ * @lightSyntaxTransform
10
+ * @oncall ws_labs
11
11
  */
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
13
  exports.default = new Set([
@@ -4,8 +4,8 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @emails oncall+ws_labs
8
7
  * @format
8
+ * @oncall ws_labs
9
9
  */
10
10
  import type { HeapAnalysisOptions } from '../../PluginUtils';
11
11
  import { BaseOption } from '@memlab/core';
@@ -5,8 +5,8 @@
5
5
  * This source code is licensed under the MIT license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  *
8
- * @emails oncall+ws_labs
9
8
  * @format
9
+ * @oncall ws_labs
10
10
  */
11
11
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
12
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
@@ -71,7 +71,6 @@ class GlobalVariableAnalysis extends BaseAnalysis_1.default {
71
71
  }
72
72
  /** @internal */
73
73
  getGlobalVariables(snapshot) {
74
- // rank heap objects based on fanout
75
74
  const ret = [];
76
75
  const processNode = (node) => {
77
76
  if (!node.name.startsWith('Window ')) {
@@ -0,0 +1,29 @@
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
+ * @format
8
+ * @oncall ws_labs
9
+ */
10
+ import type { HeapAnalysisOptions } from '../PluginUtils';
11
+ import { BaseOption } from '@memlab/core';
12
+ import BaseAnalysis from '../BaseAnalysis';
13
+ declare class GlobalVariableAnalysis extends BaseAnalysis {
14
+ getCommandName(): string;
15
+ /** @internal */
16
+ getDescription(): string;
17
+ /** @internal */
18
+ getOptions(): BaseOption[];
19
+ /** @internal */
20
+ process(options: HeapAnalysisOptions): Promise<void>;
21
+ /** @internal */
22
+ analyzeSnapshotsInDirectory(directory: string): Promise<void>;
23
+ /** @internal */
24
+ private getObjectProperties;
25
+ /** @internal */
26
+ private getObjectReferrerEdges;
27
+ }
28
+ export default GlobalVariableAnalysis;
29
+ //# sourceMappingURL=ObjectContentAnalysis.d.ts.map
@@ -0,0 +1,108 @@
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
+ * @format
9
+ * @oncall ws_labs
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 chalk_1 = __importDefault(require("chalk"));
25
+ const core_1 = require("@memlab/core");
26
+ const HeapAnalysisNodeIdOption_1 = __importDefault(require("../options/HeapAnalysisNodeIdOption"));
27
+ const HeapAnalysisSnapshotFileOption_1 = __importDefault(require("../options/HeapAnalysisSnapshotFileOption"));
28
+ const BaseAnalysis_1 = __importDefault(require("../BaseAnalysis"));
29
+ const PluginUtils_1 = __importDefault(require("../PluginUtils"));
30
+ class GlobalVariableAnalysis extends BaseAnalysis_1.default {
31
+ getCommandName() {
32
+ return 'object';
33
+ }
34
+ /** @internal */
35
+ getDescription() {
36
+ return 'Get properties inside an object';
37
+ }
38
+ /** @internal */
39
+ getOptions() {
40
+ return [new HeapAnalysisSnapshotFileOption_1.default(), new HeapAnalysisNodeIdOption_1.default()];
41
+ }
42
+ /** @internal */
43
+ process(options) {
44
+ return __awaiter(this, void 0, void 0, function* () {
45
+ const snapshot = yield PluginUtils_1.default.loadHeapSnapshot(options);
46
+ const nodeId = core_1.config.focusFiberNodeId;
47
+ const node = snapshot.getNodeById(nodeId);
48
+ if (!node) {
49
+ core_1.info.error(`Object @${nodeId} is not found.`);
50
+ core_1.info.lowLevel(`Specify an object by --node-id`);
51
+ return;
52
+ }
53
+ // print object info
54
+ const id = chalk_1.default.grey(`@${node.id}`);
55
+ core_1.info.topLevel(`Heap node (${node.type}) ${id}`);
56
+ const name = chalk_1.default.grey(`${node.name}`);
57
+ core_1.info.topLevel(` name: ${name}`);
58
+ const numReferences = chalk_1.default.grey(`${node.edge_count}`);
59
+ core_1.info.topLevel(` # of references: ${numReferences}`);
60
+ const numReferrers = chalk_1.default.grey(`${node.referrers.length}`);
61
+ core_1.info.topLevel(` # of referrers: ${numReferrers}`);
62
+ const selfSize = chalk_1.default.grey(`${node.self_size}`);
63
+ core_1.info.topLevel(` shallow size: ${selfSize}`);
64
+ const retainedSize = chalk_1.default.grey(`${node.retainedSize}`);
65
+ core_1.info.topLevel(` retained size: ${retainedSize}`);
66
+ const dominatorNode = node.dominatorNode;
67
+ if (dominatorNode) {
68
+ const dominatorNodeId = chalk_1.default.grey(`@${dominatorNode.id}`);
69
+ core_1.info.topLevel(` dominator node: ${dominatorNodeId}`);
70
+ }
71
+ // print object references
72
+ core_1.info.topLevel('\n' + chalk_1.default.bold('REFERENCES:'));
73
+ let list = this.getObjectProperties(snapshot, node);
74
+ PluginUtils_1.default.printReferencesInTerminal(list);
75
+ core_1.info.topLevel('\n' + chalk_1.default.bold('REFERRERS:'));
76
+ // print object referrers
77
+ list = this.getObjectReferrerEdges(snapshot, node);
78
+ PluginUtils_1.default.printReferrersInTerminal(list);
79
+ });
80
+ }
81
+ /** @internal */
82
+ analyzeSnapshotsInDirectory(directory) {
83
+ return __awaiter(this, void 0, void 0, function* () {
84
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
85
+ const d = directory;
86
+ throw core_1.utils.haltOrThrow(`${this.constructor.name} does not support analyzeSnapshotsInDirectory`);
87
+ });
88
+ }
89
+ /** @internal */
90
+ getObjectProperties(snapshot, node) {
91
+ const ret = [];
92
+ const refs = node.references;
93
+ for (const edge of refs) {
94
+ ret.push(edge);
95
+ }
96
+ return ret;
97
+ }
98
+ /** @internal */
99
+ getObjectReferrerEdges(snapshot, node) {
100
+ const ret = [];
101
+ const refs = node.referrers;
102
+ for (const edge of refs) {
103
+ ret.push(edge);
104
+ }
105
+ return ret;
106
+ }
107
+ }
108
+ exports.default = GlobalVariableAnalysis;
@@ -4,8 +4,8 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @emails oncall+ws_labs
8
7
  * @format
8
+ * @oncall ws_labs
9
9
  */
10
10
  import type { HeapAnalysisOptions } from '../PluginUtils';
11
11
  import { BaseOption } from '@memlab/core';
@@ -5,8 +5,8 @@
5
5
  * This source code is licensed under the MIT license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  *
8
- * @emails oncall+ws_labs
9
8
  * @format
9
+ * @oncall ws_labs
10
10
  */
11
11
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
12
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
@@ -4,8 +4,8 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @emails oncall+ws_labs
8
7
  * @format
8
+ * @oncall ws_labs
9
9
  */
10
10
  import type { HeapAnalysisOptions } from '../PluginUtils';
11
11
  import { BaseOption } from '@memlab/core';
@@ -5,8 +5,8 @@
5
5
  * This source code is licensed under the MIT license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  *
8
- * @emails oncall+ws_labs
9
8
  * @format
9
+ * @oncall ws_labs
10
10
  */
11
11
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
12
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
@@ -4,8 +4,8 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @emails oncall+ws_labs
8
7
  * @format
8
+ * @oncall ws_labs
9
9
  */
10
10
  import type { HeapAnalysisOptions } from '../PluginUtils';
11
11
  import { BaseOption } from '@memlab/core';
@@ -5,8 +5,8 @@
5
5
  * This source code is licensed under the MIT license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  *
8
- * @emails oncall+ws_labs
9
8
  * @format
9
+ * @oncall ws_labs
10
10
  */
11
11
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
12
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
@@ -4,8 +4,8 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @emails oncall+ws_labs
8
7
  * @format
8
+ * @oncall ws_labs
9
9
  */
10
10
  import type { HeapAnalysisOptions } from '../PluginUtils';
11
11
  import { BaseOption } from '@memlab/core';
@@ -5,8 +5,8 @@
5
5
  * This source code is licensed under the MIT license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  *
8
- * @emails oncall+ws_labs
9
8
  * @format
9
+ * @oncall ws_labs
10
10
  */
11
11
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
12
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
@@ -4,8 +4,8 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @emails oncall+ws_labs
8
7
  * @format
8
+ * @oncall ws_labs
9
9
  */
10
10
  import type { HeapAnalysisOptions } from '../PluginUtils';
11
11
  import { BaseOption } from '@memlab/core';
@@ -5,8 +5,8 @@
5
5
  * This source code is licensed under the MIT license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  *
8
- * @emails oncall+ws_labs
9
8
  * @format
9
+ * @oncall ws_labs
10
10
  */
11
11
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
12
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
@@ -4,8 +4,8 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @emails oncall+ws_labs
8
7
  * @format
8
+ * @oncall ws_labs
9
9
  */
10
10
  import type { HeapAnalysisOptions } from '../PluginUtils';
11
11
  import { BaseOption } from '@memlab/core';
@@ -5,8 +5,8 @@
5
5
  * This source code is licensed under the MIT license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  *
8
- * @emails oncall+ws_labs
9
8
  * @format
9
+ * @oncall ws_labs
10
10
  */
11
11
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
12
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
@@ -4,8 +4,8 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @emails oncall+ws_labs
8
7
  * @format
8
+ * @oncall ws_labs
9
9
  */
10
10
  import type { HeapAnalysisOptions } from '../PluginUtils';
11
11
  import { BaseOption } from '@memlab/core';
@@ -5,8 +5,8 @@
5
5
  * This source code is licensed under the MIT license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  *
8
- * @emails oncall+ws_labs
9
8
  * @format
9
+ * @oncall ws_labs
10
10
  */
11
11
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
12
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
@@ -60,7 +60,7 @@ class StringAnalysis extends BaseAnalysis_1.default {
60
60
  * @internal
61
61
  */
62
62
  getDescription() {
63
- return 'Analyze string in heap';
63
+ return 'Find duplicated string instances in heap';
64
64
  }
65
65
  /** @internal */
66
66
  getOptions() {
@@ -4,8 +4,8 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @emails oncall+ws_labs
8
7
  * @format
8
+ * @oncall ws_labs
9
9
  */
10
10
  import type { HeapAnalysisOptions } from '../PluginUtils';
11
11
  import { BaseOption } from '@memlab/core';
@@ -5,8 +5,8 @@
5
5
  * This source code is licensed under the MIT license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  *
8
- * @emails oncall+ws_labs
9
8
  * @format
9
+ * @oncall ws_labs
10
10
  */
11
11
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
12
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memlab/heap-analysis",
3
- "version": "1.0.5",
3
+ "version": "1.0.9",
4
4
  "license": "MIT",
5
5
  "description": "heap analysis plugins for memlab",
6
6
  "author": "Liang Gong <lgong@fb.com>",
@@ -19,8 +19,8 @@
19
19
  "dist"
20
20
  ],
21
21
  "dependencies": {
22
- "@memlab/core": "^1.1.6",
23
- "@memlab/e2e": "^1.0.7",
22
+ "@memlab/core": "^1.1.10",
23
+ "@memlab/e2e": "^1.0.11",
24
24
  "ansi": "^0.3.1",
25
25
  "babar": "^0.2.0",
26
26
  "chalk": "^4.0.0",