@memlab/cli 1.0.8 → 1.0.10

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 (155) hide show
  1. package/dist/BaseCommand.d.ts +1 -1
  2. package/dist/BaseCommand.js +1 -1
  3. package/dist/CommandLoader.d.ts +1 -1
  4. package/dist/CommandLoader.js +1 -1
  5. package/dist/Dispatcher.d.ts +1 -1
  6. package/dist/Dispatcher.js +1 -1
  7. package/dist/TypesThirdParty.d.ts +1 -1
  8. package/dist/TypesThirdParty.js +1 -1
  9. package/dist/commands/CleanLoggerDataCommand.d.ts +1 -1
  10. package/dist/commands/CleanLoggerDataCommand.js +1 -1
  11. package/dist/commands/CleanRunDataCommand.d.ts +1 -1
  12. package/dist/commands/CleanRunDataCommand.js +1 -1
  13. package/dist/commands/GetVersionCommand.d.ts +1 -1
  14. package/dist/commands/GetVersionCommand.js +1 -1
  15. package/dist/commands/InitDirectoryCommand.d.ts +1 -1
  16. package/dist/commands/InitDirectoryCommand.js +1 -1
  17. package/dist/commands/ListScenariosCommand.d.ts +1 -1
  18. package/dist/commands/ListScenariosCommand.js +1 -1
  19. package/dist/commands/MemLabRunCommand.d.ts +1 -1
  20. package/dist/commands/MemLabRunCommand.js +1 -1
  21. package/dist/commands/PrintSummaryCommand.d.ts +1 -1
  22. package/dist/commands/PrintSummaryCommand.js +1 -1
  23. package/dist/commands/ResetDirectoryCommand.d.ts +1 -1
  24. package/dist/commands/ResetDirectoryCommand.js +1 -1
  25. package/dist/commands/RunMeasureCommand.d.ts +1 -1
  26. package/dist/commands/RunMeasureCommand.js +1 -1
  27. package/dist/commands/WarmupAppCommand.d.ts +1 -1
  28. package/dist/commands/WarmupAppCommand.js +1 -1
  29. package/dist/commands/heap/CheckLeakCommand.d.ts +1 -1
  30. package/dist/commands/heap/CheckLeakCommand.js +1 -1
  31. package/dist/commands/heap/GetRetainerTraceCommand.d.ts +1 -1
  32. package/dist/commands/heap/GetRetainerTraceCommand.js +1 -1
  33. package/dist/commands/heap/HeapAnalysisCommand.d.ts +1 -1
  34. package/dist/commands/heap/HeapAnalysisCommand.js +1 -1
  35. package/dist/commands/heap/HeapAnalysisSubCommandWrapper.d.ts +1 -1
  36. package/dist/commands/heap/HeapAnalysisSubCommandWrapper.js +1 -1
  37. package/dist/commands/heap/interactive/InteractiveCommandLoader.d.ts +1 -1
  38. package/dist/commands/heap/interactive/InteractiveCommandLoader.js +1 -1
  39. package/dist/commands/heap/interactive/InteractiveHeapCommand.d.ts +6 -1
  40. package/dist/commands/heap/interactive/InteractiveHeapCommand.js +54 -15
  41. package/dist/commands/heap/interactive/InteractiveHeapExploreCommand.d.ts +26 -0
  42. package/dist/commands/heap/interactive/InteractiveHeapExploreCommand.js +145 -0
  43. package/dist/commands/heap/interactive/ui-components/CliScreen.d.ts +38 -0
  44. package/dist/commands/heap/interactive/ui-components/CliScreen.js +234 -0
  45. package/dist/commands/heap/interactive/ui-components/HeapViewController.d.ts +58 -0
  46. package/dist/commands/heap/interactive/ui-components/HeapViewController.js +251 -0
  47. package/dist/commands/heap/interactive/ui-components/HeapViewUtils.d.ts +29 -0
  48. package/dist/commands/heap/interactive/ui-components/HeapViewUtils.js +84 -0
  49. package/dist/commands/heap/interactive/ui-components/ListComponent.d.ts +62 -0
  50. package/dist/commands/heap/interactive/ui-components/ListComponent.js +220 -0
  51. package/dist/commands/helper/GenerateCLIDocCommand.d.ts +1 -1
  52. package/dist/commands/helper/GenerateCLIDocCommand.js +1 -1
  53. package/dist/commands/helper/HelperCommand.d.ts +1 -1
  54. package/dist/commands/helper/HelperCommand.js +1 -1
  55. package/dist/commands/helper/lib/CommandOrder.d.ts +1 -1
  56. package/dist/commands/helper/lib/CommandOrder.js +1 -1
  57. package/dist/commands/helper/lib/Types.d.ts +1 -1
  58. package/dist/commands/helper/lib/Types.js +1 -1
  59. package/dist/commands/query/QueryDefaultWorkDirCommand.d.ts +1 -1
  60. package/dist/commands/query/QueryDefaultWorkDirCommand.js +1 -1
  61. package/dist/commands/snapshot/CheckXvfbSupportCommand.d.ts +1 -1
  62. package/dist/commands/snapshot/CheckXvfbSupportCommand.js +1 -1
  63. package/dist/commands/snapshot/Snapshot.d.ts +1 -1
  64. package/dist/commands/snapshot/Snapshot.js +1 -1
  65. package/dist/commands/snapshot/TakeSnapshotCommand.d.ts +1 -1
  66. package/dist/commands/snapshot/TakeSnapshotCommand.js +1 -1
  67. package/dist/commands/snapshot/WarmupAndSnapshotCommand.d.ts +1 -1
  68. package/dist/commands/snapshot/WarmupAndSnapshotCommand.js +1 -1
  69. package/dist/index.d.ts +1 -1
  70. package/dist/index.js +1 -1
  71. package/dist/options/AppOption.d.ts +1 -1
  72. package/dist/options/AppOption.js +1 -1
  73. package/dist/options/DebugOption.d.ts +1 -1
  74. package/dist/options/DebugOption.js +1 -1
  75. package/dist/options/DisableXvfbOption.d.ts +1 -1
  76. package/dist/options/DisableXvfbOption.js +1 -1
  77. package/dist/options/FullExecutionOption.d.ts +1 -1
  78. package/dist/options/FullExecutionOption.js +1 -1
  79. package/dist/options/HeadfulBrowserOption.d.ts +1 -1
  80. package/dist/options/HeadfulBrowserOption.js +1 -1
  81. package/dist/options/HeapNodeIdOption.d.ts +1 -1
  82. package/dist/options/HeapNodeIdOption.js +1 -1
  83. package/dist/options/HelperOption.d.ts +1 -1
  84. package/dist/options/HelperOption.js +1 -1
  85. package/dist/options/InteractionOption.d.ts +1 -1
  86. package/dist/options/InteractionOption.js +1 -1
  87. package/dist/options/MLClusteringLinkageMaxDistanceOption.d.ts +1 -1
  88. package/dist/options/MLClusteringLinkageMaxDistanceOption.js +1 -1
  89. package/dist/options/MLClusteringMaxDFOption.d.ts +1 -1
  90. package/dist/options/MLClusteringMaxDFOption.js +1 -1
  91. package/dist/options/MLClusteringOption.d.ts +1 -1
  92. package/dist/options/MLClusteringOption.js +1 -1
  93. package/dist/options/NumberOfRunsOption.d.ts +1 -1
  94. package/dist/options/NumberOfRunsOption.js +1 -1
  95. package/dist/options/RemoteBrowserDebugOption.d.ts +1 -1
  96. package/dist/options/RemoteBrowserDebugOption.js +1 -1
  97. package/dist/options/RunningModeOption.d.ts +1 -1
  98. package/dist/options/RunningModeOption.js +1 -1
  99. package/dist/options/ScenarioFileOption.d.ts +1 -1
  100. package/dist/options/ScenarioFileOption.js +1 -1
  101. package/dist/options/SetContinuousTestOption.d.ts +1 -1
  102. package/dist/options/SetContinuousTestOption.js +1 -1
  103. package/dist/options/SetDeviceOption.d.ts +1 -1
  104. package/dist/options/SetDeviceOption.js +1 -1
  105. package/dist/options/SetWorkingDirectoryOption.d.ts +1 -1
  106. package/dist/options/SetWorkingDirectoryOption.js +1 -1
  107. package/dist/options/SilentOption.d.ts +1 -1
  108. package/dist/options/SilentOption.js +1 -1
  109. package/dist/options/SkipExtraOperationOption.d.ts +1 -1
  110. package/dist/options/SkipExtraOperationOption.js +1 -1
  111. package/dist/options/SkipGCOption.d.ts +1 -1
  112. package/dist/options/SkipGCOption.js +1 -1
  113. package/dist/options/SkipScreenshotOption.d.ts +1 -1
  114. package/dist/options/SkipScreenshotOption.js +1 -1
  115. package/dist/options/SkipScrollOption.d.ts +1 -1
  116. package/dist/options/SkipScrollOption.js +1 -1
  117. package/dist/options/SkipSnapshotOption.d.ts +1 -1
  118. package/dist/options/SkipSnapshotOption.js +1 -1
  119. package/dist/options/SkipWarmupOption.d.ts +1 -1
  120. package/dist/options/SkipWarmupOption.js +1 -1
  121. package/dist/options/VerboseOption.d.ts +1 -1
  122. package/dist/options/VerboseOption.js +1 -1
  123. package/dist/options/heap/BaselineFileOption.d.ts +1 -1
  124. package/dist/options/heap/BaselineFileOption.js +1 -1
  125. package/dist/options/heap/FinalFileOption.d.ts +1 -1
  126. package/dist/options/heap/FinalFileOption.js +1 -1
  127. package/dist/options/heap/JSEngineOption.d.ts +1 -1
  128. package/dist/options/heap/JSEngineOption.js +1 -1
  129. package/dist/options/heap/LeakClusterSizeThresholdOption.d.ts +1 -1
  130. package/dist/options/heap/LeakClusterSizeThresholdOption.js +1 -1
  131. package/dist/options/heap/LogTraceAsClusterOption.d.ts +1 -1
  132. package/dist/options/heap/LogTraceAsClusterOption.js +1 -1
  133. package/dist/options/heap/OversizeThresholdOption.d.ts +1 -1
  134. package/dist/options/heap/OversizeThresholdOption.js +1 -1
  135. package/dist/options/heap/SnapshotDirectoryOption.d.ts +1 -1
  136. package/dist/options/heap/SnapshotDirectoryOption.js +1 -1
  137. package/dist/options/heap/SnapshotFileOption.d.ts +1 -1
  138. package/dist/options/heap/SnapshotFileOption.js +1 -1
  139. package/dist/options/heap/TargetFileOption.d.ts +1 -1
  140. package/dist/options/heap/TargetFileOption.js +1 -1
  141. package/dist/options/heap/TraceAllObjectsOption.d.ts +1 -1
  142. package/dist/options/heap/TraceAllObjectsOption.js +1 -1
  143. package/dist/options/heap/leak-filter/LeakFilterFileOption.d.ts +1 -1
  144. package/dist/options/heap/leak-filter/LeakFilterFileOption.js +1 -1
  145. package/dist/options/heap/leak-filter/examples/FilterLib.d.ts +1 -1
  146. package/dist/options/heap/leak-filter/examples/FilterLib.js +1 -1
  147. package/dist/options/heap/leak-filter/examples/dup-string-as-leak.example-1.d.ts +1 -1
  148. package/dist/options/heap/leak-filter/examples/dup-string-as-leak.example-1.js +1 -1
  149. package/dist/options/heap/leak-filter/examples/dup-string-as-leak.example-2.d.ts +1 -1
  150. package/dist/options/heap/leak-filter/examples/dup-string-as-leak.example-2.js +1 -1
  151. package/dist/options/lib/UniversalOptions.d.ts +1 -1
  152. package/dist/options/lib/UniversalOptions.js +1 -1
  153. package/dist/runner.d.ts +1 -1
  154. package/dist/runner.js +1 -1
  155. package/package.json +3 -1
@@ -0,0 +1,251 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const chalk_1 = __importDefault(require("chalk"));
7
+ const core_1 = require("@memlab/core");
8
+ const HeapViewUtils_1 = require("./HeapViewUtils");
9
+ /**
10
+ * HeapViewController managers all the data associated with each
11
+ * UI components in CLI and coordinates the events/interaction
12
+ * among all UI components.
13
+ */
14
+ class HeapViewController {
15
+ constructor(heap, nodes) {
16
+ this.heap = heap;
17
+ this.currentHeapObject = (0, HeapViewUtils_1.getHeapObjectAt)(nodes, 0);
18
+ this.currentHeapObjectsInfo = nodes;
19
+ this.componentIdToDataMap = new Map();
20
+ this.componentIdToComponentMap = new Map();
21
+ }
22
+ getContent(componentId) {
23
+ const ret = [];
24
+ const data = this.componentIdToDataMap.get(componentId);
25
+ if (data) {
26
+ for (const item of data.items) {
27
+ ret.push(HeapViewUtils_1.ComponentDataItem.getTextForDisplay(item));
28
+ }
29
+ }
30
+ return ret;
31
+ }
32
+ setParentBox(component) {
33
+ this.componentIdToComponentMap.set(component.id, component);
34
+ this.parentBox = component;
35
+ this.componentIdToDataMap.set(component.id, new HeapViewUtils_1.ComponentData());
36
+ }
37
+ setReferrerBox(component) {
38
+ this.componentIdToComponentMap.set(component.id, component);
39
+ this.referrerBox = component;
40
+ this.componentIdToDataMap.set(component.id, new HeapViewUtils_1.ComponentData());
41
+ }
42
+ getReferrerBoxData(node = this.selectedHeapObject) {
43
+ const data = new HeapViewUtils_1.ComponentData();
44
+ node.forEachReferrer(ref => {
45
+ var _a, _b;
46
+ const tag = ref.fromNode.id === ((_b = (_a = node.pathEdge) === null || _a === void 0 ? void 0 : _a.fromNode) === null || _b === void 0 ? void 0 : _b.id) ? { tag: '<-' } : {};
47
+ data.items.push(Object.assign({ heapObject: ref.fromNode, referenceEdge: ref }, tag));
48
+ return { stop: false };
49
+ });
50
+ data.selectedIdx = data.items.length > 0 ? 0 : -1;
51
+ return data;
52
+ }
53
+ setObjectBox(component) {
54
+ this.componentIdToComponentMap.set(component.id, component);
55
+ this.objectBox = component;
56
+ this.componentIdToDataMap.set(component.id, new HeapViewUtils_1.ComponentData());
57
+ }
58
+ getObjectBoxData() {
59
+ const data = new HeapViewUtils_1.ComponentData();
60
+ const index = this.currentHeapObjectsInfo.findIndex(item => { var _a; return ((_a = item.heapObject) === null || _a === void 0 ? void 0 : _a.id) === this.currentHeapObject.id; });
61
+ if (index >= 0) {
62
+ data.selectedIdx = index;
63
+ }
64
+ else {
65
+ data.selectedIdx = 0;
66
+ this.currentHeapObjectsInfo.unshift({
67
+ tag: 'Chosen',
68
+ heapObject: this.currentHeapObject,
69
+ });
70
+ }
71
+ data.items = this.currentHeapObjectsInfo;
72
+ return data;
73
+ }
74
+ setReferenceBox(component) {
75
+ this.componentIdToComponentMap.set(component.id, component);
76
+ this.referenceBox = component;
77
+ this.componentIdToDataMap.set(component.id, new HeapViewUtils_1.ComponentData());
78
+ }
79
+ getReferenceBoxData() {
80
+ const data = new HeapViewUtils_1.ComponentData();
81
+ this.selectedHeapObject.forEachReference(ref => {
82
+ data.items.push({ referrerEdge: ref, heapObject: ref.toNode });
83
+ return { stop: false };
84
+ });
85
+ data.selectedIdx = data.items.length > 0 ? 0 : -1;
86
+ return data;
87
+ }
88
+ setObjectPropertyBox(component) {
89
+ this.componentIdToComponentMap.set(component.id, component);
90
+ this.objectPropertyBox = component;
91
+ this.componentIdToDataMap.set(component.id, new HeapViewUtils_1.ComponentData());
92
+ }
93
+ getObjectPropertyData() {
94
+ const data = new HeapViewUtils_1.ComponentData();
95
+ const node = this.selectedHeapObject;
96
+ data.items.push({
97
+ stringContent: this.getKeyValuePairString('id', `@${node.id}`),
98
+ });
99
+ data.items.push({
100
+ stringContent: this.getKeyValuePairString('name', node.name),
101
+ });
102
+ data.items.push({
103
+ stringContent: this.getKeyValuePairString('type', node.type),
104
+ });
105
+ data.items.push({
106
+ stringContent: this.getKeyValuePairString('self size', core_1.utils.getReadableBytes(node.self_size)),
107
+ });
108
+ data.items.push({
109
+ stringContent: this.getKeyValuePairString('retained size', core_1.utils.getReadableBytes(node.retainedSize)),
110
+ });
111
+ data.items.push({
112
+ stringContent: this.getKeyValuePairString('# of references', core_1.utils.getReadableBytes(node.edge_count)),
113
+ });
114
+ data.items.push({
115
+ stringContent: this.getKeyValuePairString('# of referrers', core_1.utils.getReadableBytes(node.referrers.length)),
116
+ });
117
+ if (node.dominatorNode) {
118
+ data.items.push({
119
+ stringContent: 'dominator node' + chalk_1.default.grey(': '),
120
+ heapObject: node.dominatorNode,
121
+ });
122
+ }
123
+ data.selectedIdx = data.items.length > 0 ? 0 : -1;
124
+ return data;
125
+ }
126
+ getKeyValuePairString(key, value) {
127
+ return key + chalk_1.default.grey(': ') + chalk_1.default.green(value);
128
+ }
129
+ setRetainerTraceBox(component) {
130
+ this.componentIdToComponentMap.set(component.id, component);
131
+ this.retainerTracePropertyBox = component;
132
+ this.componentIdToDataMap.set(component.id, new HeapViewUtils_1.ComponentData());
133
+ }
134
+ getRetainerTraceData() {
135
+ var _a;
136
+ const data = new HeapViewUtils_1.ComponentData();
137
+ const node = this.selectedHeapObject;
138
+ let curNode = node;
139
+ while (curNode && !core_1.utils.isRootNode(curNode)) {
140
+ if (!curNode.pathEdge) {
141
+ curNode = null;
142
+ break;
143
+ }
144
+ data.items.unshift({ referrerEdge: curNode.pathEdge, heapObject: curNode });
145
+ curNode = (_a = curNode.pathEdge) === null || _a === void 0 ? void 0 : _a.fromNode;
146
+ }
147
+ if (curNode) {
148
+ data.items.unshift({ heapObject: curNode });
149
+ }
150
+ data.selectedIdx = data.items.length > 0 ? 0 : -1;
151
+ return data;
152
+ }
153
+ setCurrentHeapObjectFromComponent(componentId, itemIndex) {
154
+ const data = this.componentIdToDataMap.get(componentId);
155
+ if (!data) {
156
+ return;
157
+ }
158
+ const item = data.items[itemIndex];
159
+ if (!item) {
160
+ return;
161
+ }
162
+ const heapObject = item.heapObject;
163
+ if (!heapObject) {
164
+ return;
165
+ }
166
+ this.setCurrentHeapObject(heapObject);
167
+ }
168
+ setCurrentHeapObject(node) {
169
+ this.currentHeapObject = node;
170
+ // set parent box's data and content
171
+ const parentBoxData = this.getReferrerBoxData(this.currentHeapObject);
172
+ this.componentIdToDataMap.set(this.parentBox.id, parentBoxData);
173
+ this.parentBox.setContent(this.getContent(this.parentBox.id));
174
+ this.parentBox.selectIndex(parentBoxData.selectedIdx);
175
+ // set object box's data and content
176
+ const objectBoxData = this.getObjectBoxData();
177
+ this.componentIdToDataMap.set(this.objectBox.id, objectBoxData);
178
+ this.objectBox.setContent(this.getContent(this.objectBox.id));
179
+ this.objectBox.selectIndex(objectBoxData.selectedIdx);
180
+ this.setSelectedHeapObject(node);
181
+ this.focusOnComponent(this.objectBox.id);
182
+ }
183
+ focusOnComponent(componentId) {
184
+ for (const component of this.componentIdToComponentMap.values()) {
185
+ if (component.id === componentId) {
186
+ component.focus();
187
+ }
188
+ else {
189
+ component.loseFocus();
190
+ }
191
+ }
192
+ }
193
+ setSelectedHeapObjectFromComponent(componentId, itemIndex) {
194
+ const data = this.componentIdToDataMap.get(componentId);
195
+ if (!data) {
196
+ return;
197
+ }
198
+ data.selectedIdx = itemIndex;
199
+ const item = data.items[itemIndex];
200
+ if (!item) {
201
+ return;
202
+ }
203
+ const heapObject = item.heapObject;
204
+ if (!heapObject) {
205
+ return;
206
+ }
207
+ // if selecting in a specific box, do not update content in that box
208
+ const noChangeInReferenceBox = componentId === this.referenceBox.id;
209
+ const noChangeInReferrerBox = componentId === this.referrerBox.id;
210
+ const noChangeInRetainerTraceBox = componentId === this.retainerTracePropertyBox.id;
211
+ const noChangeInObjectPropertyBox = componentId === this.objectPropertyBox.id;
212
+ this.setSelectedHeapObject(heapObject, {
213
+ noChangeInReferenceBox,
214
+ noChangeInReferrerBox,
215
+ noChangeInRetainerTraceBox,
216
+ noChangeInObjectPropertyBox,
217
+ });
218
+ }
219
+ setSelectedHeapObject(node, options = {}) {
220
+ this.selectedHeapObject = node;
221
+ // set referrer box's data and content
222
+ if (!options.noChangeInReferrerBox) {
223
+ const data = this.getReferrerBoxData();
224
+ this.componentIdToDataMap.set(this.referrerBox.id, data);
225
+ this.referrerBox.setContent(this.getContent(this.referrerBox.id));
226
+ this.referrerBox.selectIndex(data.selectedIdx);
227
+ }
228
+ // set reference box's data and content
229
+ if (!options.noChangeInReferenceBox) {
230
+ const data = this.getReferenceBoxData();
231
+ this.componentIdToDataMap.set(this.referenceBox.id, data);
232
+ this.referenceBox.setContent(this.getContent(this.referenceBox.id));
233
+ this.referenceBox.selectIndex(data.selectedIdx);
234
+ }
235
+ // set object property box's data and content
236
+ if (!options.noChangeInObjectPropertyBox) {
237
+ const data = this.getObjectPropertyData();
238
+ this.componentIdToDataMap.set(this.objectPropertyBox.id, data);
239
+ this.objectPropertyBox.setContent(this.getContent(this.objectPropertyBox.id));
240
+ this.objectPropertyBox.selectIndex(data.selectedIdx);
241
+ }
242
+ // set retainer trace box's data and content
243
+ if (!options.noChangeInRetainerTraceBox) {
244
+ const data = this.getRetainerTraceData();
245
+ this.componentIdToDataMap.set(this.retainerTracePropertyBox.id, data);
246
+ this.retainerTracePropertyBox.setContent(this.getContent(this.retainerTracePropertyBox.id));
247
+ this.retainerTracePropertyBox.selectIndex(data.selectedIdx);
248
+ }
249
+ }
250
+ }
251
+ exports.default = HeapViewController;
@@ -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
+ * @emails oncall+ws_labs
8
+ * @format
9
+ */
10
+ import type { IHeapEdge, IHeapNode } from '@memlab/core';
11
+ export declare class ComponentDataItem {
12
+ stringContent?: string;
13
+ tag?: string;
14
+ referrerEdge?: IHeapEdge;
15
+ heapObject?: IHeapNode;
16
+ referenceEdge?: IHeapEdge;
17
+ type?: string;
18
+ static getTextForDisplay(data: ComponentDataItem): string;
19
+ }
20
+ export declare class ComponentData {
21
+ selectedIdx: number;
22
+ items: ComponentDataItem[];
23
+ }
24
+ export declare function throwIfNodesEmpty(nodes: ComponentDataItem[]): boolean;
25
+ export declare function getHeapObjectAt(nodes: ComponentDataItem[], index: number): IHeapNode;
26
+ export declare type DebounceCallback = () => void;
27
+ export declare type DebounceFunction = (callback: DebounceCallback) => void;
28
+ export declare function debounce(timeInMs: number): DebounceFunction;
29
+ //# sourceMappingURL=HeapViewUtils.d.ts.map
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.debounce = exports.getHeapObjectAt = exports.throwIfNodesEmpty = exports.ComponentData = exports.ComponentDataItem = void 0;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const core_1 = require("@memlab/core");
9
+ class ComponentDataItem {
10
+ static getTextForDisplay(data) {
11
+ let ret = '';
12
+ if (data.tag) {
13
+ ret += `[${data.tag}] `;
14
+ }
15
+ if (data.stringContent) {
16
+ ret += data.stringContent;
17
+ }
18
+ const arrowPrefix = chalk_1.default.grey('--');
19
+ const arrowSuffix = chalk_1.default.grey('---') + '>';
20
+ if (data.referrerEdge) {
21
+ const edgeType = chalk_1.default.grey(`(${data.referrerEdge.type})`);
22
+ const edgeName = data.referrerEdge.name_or_index;
23
+ ret += `${arrowPrefix}${edgeName}${edgeType}${arrowSuffix} `;
24
+ }
25
+ if (data.heapObject) {
26
+ const objectType = chalk_1.default.grey(`(${data.heapObject.type})`);
27
+ const objectId = chalk_1.default.grey(` @${data.heapObject.id}`);
28
+ const size = core_1.utils.getReadableBytes(data.heapObject.retainedSize);
29
+ const sizeInfo = chalk_1.default.grey(' [') + chalk_1.default.bold(chalk_1.default.blue(size)) + chalk_1.default.grey(']');
30
+ ret +=
31
+ chalk_1.default.green(`[${data.heapObject.name}]`) +
32
+ objectType +
33
+ objectId +
34
+ sizeInfo;
35
+ }
36
+ if (data.referenceEdge) {
37
+ const edgeType = chalk_1.default.grey(`(${data.referenceEdge.type})`);
38
+ const edgeName = data.referenceEdge.name_or_index;
39
+ ret += ` ${arrowPrefix}${edgeName}${edgeType}${arrowSuffix} `;
40
+ }
41
+ return ret === '' ? chalk_1.default.grey('<undefinied>') : ret;
42
+ }
43
+ }
44
+ exports.ComponentDataItem = ComponentDataItem;
45
+ class ComponentData {
46
+ constructor() {
47
+ this.selectedIdx = -1;
48
+ this.items = [];
49
+ }
50
+ }
51
+ exports.ComponentData = ComponentData;
52
+ function throwIfNodesEmpty(nodes) {
53
+ if (nodes.length === 0) {
54
+ throw core_1.utils.haltOrThrow('no heap node specified');
55
+ }
56
+ for (let i = 0; i < nodes.length; ++i) {
57
+ if (!nodes[i].heapObject) {
58
+ throw core_1.utils.haltOrThrow('heap node missing in ComponentDataItem[]');
59
+ }
60
+ }
61
+ return true;
62
+ }
63
+ exports.throwIfNodesEmpty = throwIfNodesEmpty;
64
+ function getHeapObjectAt(nodes, index) {
65
+ throwIfNodesEmpty(nodes);
66
+ if (index < 0 || index >= nodes.length) {
67
+ throw core_1.utils.haltOrThrow('index is outside of nodes range');
68
+ }
69
+ return nodes[index].heapObject;
70
+ }
71
+ exports.getHeapObjectAt = getHeapObjectAt;
72
+ function debounce(timeInMs) {
73
+ let id = null;
74
+ return (callback) => {
75
+ if (id) {
76
+ clearTimeout(id);
77
+ }
78
+ id = setTimeout(() => {
79
+ callback();
80
+ id = null;
81
+ }, timeInMs);
82
+ };
83
+ }
84
+ exports.debounce = debounce;
@@ -0,0 +1,62 @@
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 { Widgets } from 'blessed';
11
+ export declare type ListComponentOption = {
12
+ width: number;
13
+ height: number;
14
+ left: number;
15
+ top: number;
16
+ label: string;
17
+ };
18
+ export declare type ListItemSelectInfo = {
19
+ keyName: string;
20
+ };
21
+ export declare type ListCallbacks = {
22
+ selectCallback?: (componentId: number, index: number, content: string[], selectInfo: ListItemSelectInfo) => void;
23
+ updateContent?: (oldContent: string[], newContent: string[]) => void;
24
+ getFocus?: () => void;
25
+ render?: () => void;
26
+ };
27
+ /**
28
+ * A ListComponent is an UI list component in CLI.
29
+ * It managers all the UI events related to the
30
+ * list component (e.g., scroll up, down, left, right, and other key strokes)
31
+ */
32
+ export default class ListComponent {
33
+ element: Widgets.ListElement;
34
+ id: number;
35
+ private listIndex;
36
+ private content;
37
+ private callbacks;
38
+ private horizonScrollPositionMap;
39
+ private displayedItems;
40
+ private moreEntryIndex;
41
+ private static readonly ListContentLimit;
42
+ private static readonly loadMore;
43
+ private static nextComponentId;
44
+ private static nextId;
45
+ constructor(content: string[], callbacks: ListCallbacks, options: ListComponentOption);
46
+ private render;
47
+ private static createEntryForMore;
48
+ protected registerKeys(): void;
49
+ private scrollLeft;
50
+ private scrollRight;
51
+ focus(): void;
52
+ loseFocus(): void;
53
+ selectIndex(index: number): void;
54
+ setContent(content: string[]): void;
55
+ loadMoreContent(): void;
56
+ private removeDisplayMoreEntry;
57
+ private insertDisplayMoreEntry;
58
+ updateContent(oldContent: string[], newContent: string[]): void;
59
+ getFocus(): void;
60
+ selectUpdate(index: number, content: string[], selectInfo: ListItemSelectInfo): void;
61
+ }
62
+ //# sourceMappingURL=ListComponent.d.ts.map
@@ -0,0 +1,220 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const blessed_1 = __importDefault(require("blessed"));
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const string_width_1 = __importDefault(require("string-width"));
9
+ /**
10
+ * A ListComponent is an UI list component in CLI.
11
+ * It managers all the UI events related to the
12
+ * list component (e.g., scroll up, down, left, right, and other key strokes)
13
+ */
14
+ class ListComponent {
15
+ constructor(content, callbacks, options) {
16
+ this.listIndex = 0;
17
+ this.content = [];
18
+ this.moreEntryIndex = -1;
19
+ this.id = ListComponent.nextId();
20
+ this.horizonScrollPositionMap = new Map();
21
+ this.callbacks = callbacks;
22
+ // init list element
23
+ this.element = blessed_1.default.list(Object.assign(Object.assign({}, options), { tags: true, scrollable: true, keys: true, border: {
24
+ fg: 'grey',
25
+ type: 'line',
26
+ }, style: {
27
+ item: {
28
+ fg: 'white',
29
+ bg: 'default',
30
+ },
31
+ selected: {
32
+ bg: 'grey',
33
+ bold: true,
34
+ },
35
+ } }));
36
+ this.setContent(content);
37
+ this.registerKeys();
38
+ }
39
+ static nextId() {
40
+ return ListComponent.nextComponentId++;
41
+ }
42
+ // render the whole screen
43
+ render() {
44
+ if (this.callbacks.render) {
45
+ this.callbacks.render();
46
+ }
47
+ }
48
+ static createEntryForMore(more) {
49
+ const key = chalk_1.default.inverse('enter');
50
+ return chalk_1.default.grey(` ${more} more ... (select and ${key} to load)`);
51
+ }
52
+ registerKeys() {
53
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
54
+ const self = this;
55
+ this.element.on('keypress', (char, key) => {
56
+ const content = self.content;
57
+ // if selecting "More"
58
+ if (key.name === 'enter' &&
59
+ content.length > 0 &&
60
+ self.listIndex >= 0 &&
61
+ self.listIndex === self.moreEntryIndex) {
62
+ self.loadMoreContent();
63
+ return;
64
+ }
65
+ // move selection down
66
+ if (key.name === 'down' && self.listIndex < self.displayedItems - 1) {
67
+ self.element.select(++self.listIndex);
68
+ self.selectUpdate(self.listIndex, content, {
69
+ keyName: key.name,
70
+ });
71
+ // move selection up
72
+ }
73
+ else if (key.name === 'up' && self.listIndex > 0) {
74
+ self.element.select(--self.listIndex);
75
+ self.selectUpdate(self.listIndex, content, {
76
+ keyName: key.name,
77
+ });
78
+ // hit enter to select the current heap object
79
+ }
80
+ else if (key.name === 'enter') {
81
+ self.selectUpdate(self.listIndex, content, {
82
+ keyName: key.name,
83
+ });
84
+ // scroll left
85
+ }
86
+ else if (key.name === 'left') {
87
+ self.scrollLeft();
88
+ // scroll right
89
+ }
90
+ else if (key.name === 'right') {
91
+ self.scrollRight();
92
+ }
93
+ });
94
+ }
95
+ scrollLeft() {
96
+ var _a;
97
+ const selectedContent = this.content[this.listIndex];
98
+ if (!selectedContent) {
99
+ return;
100
+ }
101
+ let offset = 0;
102
+ if (this.horizonScrollPositionMap.has(this.listIndex)) {
103
+ offset = (_a = this.horizonScrollPositionMap.get(this.listIndex)) !== null && _a !== void 0 ? _a : 0;
104
+ }
105
+ if (offset === 0) {
106
+ return;
107
+ }
108
+ this.horizonScrollPositionMap.set(this.listIndex, --offset);
109
+ let newContent = selectedContent.substring(offset);
110
+ if (offset > 0) {
111
+ newContent = chalk_1.default.grey('...') + newContent;
112
+ }
113
+ this.element.spliceItem(this.listIndex, 1, newContent);
114
+ this.element.select(this.listIndex);
115
+ }
116
+ scrollRight() {
117
+ var _a;
118
+ const selectedContent = this.content[this.listIndex];
119
+ if (!selectedContent || (0, string_width_1.default)(selectedContent) <= 5) {
120
+ return;
121
+ }
122
+ let offset = 0;
123
+ if (this.horizonScrollPositionMap.has(this.listIndex)) {
124
+ offset = (_a = this.horizonScrollPositionMap.get(this.listIndex)) !== null && _a !== void 0 ? _a : 0;
125
+ }
126
+ this.horizonScrollPositionMap.set(this.listIndex, ++offset);
127
+ let newContent = selectedContent.substring(offset);
128
+ if (offset > 0) {
129
+ newContent = chalk_1.default.grey('...') + newContent;
130
+ }
131
+ this.element.spliceItem(this.listIndex, 1, newContent);
132
+ this.element.select(this.listIndex);
133
+ }
134
+ focus() {
135
+ this.element.focus();
136
+ this.element.style.border.fg = 'white';
137
+ this.getFocus();
138
+ }
139
+ loseFocus() {
140
+ this.element.style.border.fg = 'grey';
141
+ }
142
+ selectIndex(index) {
143
+ while (this.displayedItems <= index &&
144
+ this.displayedItems < this.content.length) {
145
+ this.loadMoreContent();
146
+ }
147
+ this.listIndex = index;
148
+ this.element.select(index);
149
+ }
150
+ setContent(content) {
151
+ const oldContent = this.content;
152
+ this.element.clearItems();
153
+ this.displayedItems = 0;
154
+ this.moreEntryIndex = -1;
155
+ this.listIndex = 0;
156
+ // push list items into the list
157
+ for (let i = 0; i < content.length; ++i) {
158
+ if (this.displayedItems >= ListComponent.ListContentLimit) {
159
+ break;
160
+ }
161
+ this.element.pushItem(content[i]);
162
+ ++this.displayedItems;
163
+ }
164
+ this.content = content;
165
+ this.horizonScrollPositionMap.clear();
166
+ this.insertDisplayMoreEntry();
167
+ this.updateContent(oldContent, this.content);
168
+ }
169
+ loadMoreContent() {
170
+ if (this.moreEntryIndex < 0) {
171
+ return;
172
+ }
173
+ const curIndex = this.listIndex;
174
+ this.removeDisplayMoreEntry();
175
+ let idx = this.displayedItems;
176
+ const limit = Math.min(this.displayedItems + ListComponent.loadMore, this.content.length);
177
+ while (idx < limit) {
178
+ this.element.pushItem(this.content[idx++]);
179
+ }
180
+ this.displayedItems = limit;
181
+ this.insertDisplayMoreEntry();
182
+ this.selectIndex(curIndex);
183
+ this.render();
184
+ }
185
+ removeDisplayMoreEntry() {
186
+ this.element.spliceItem(this.displayedItems - 1, 1);
187
+ this.moreEntryIndex = -1;
188
+ --this.displayedItems;
189
+ --this.listIndex;
190
+ }
191
+ // insert the display more entry
192
+ insertDisplayMoreEntry() {
193
+ if (this.displayedItems < this.content.length) {
194
+ this.element.pushItem(ListComponent.createEntryForMore(this.content.length - this.displayedItems));
195
+ ++this.displayedItems;
196
+ this.moreEntryIndex = this.displayedItems - 1;
197
+ }
198
+ }
199
+ // function to be overridden
200
+ updateContent(oldContent, newContent) {
201
+ if (this.callbacks.updateContent) {
202
+ this.callbacks.updateContent(oldContent, newContent);
203
+ }
204
+ }
205
+ // function to be overridden
206
+ getFocus() {
207
+ if (this.callbacks.getFocus) {
208
+ this.callbacks.getFocus();
209
+ }
210
+ }
211
+ selectUpdate(index, content, selectInfo) {
212
+ if (this.callbacks.selectCallback) {
213
+ this.callbacks.selectCallback(this.id, index, content, selectInfo);
214
+ }
215
+ }
216
+ }
217
+ exports.default = ListComponent;
218
+ ListComponent.ListContentLimit = 100;
219
+ ListComponent.loadMore = 20;
220
+ ListComponent.nextComponentId = 0;
@@ -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 { CLIOptions } from '@memlab/core';
11
11
  import BaseCommand from '../../BaseCommand';
@@ -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 __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
12
  if (k2 === undefined) k2 = k;
@@ -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 { BaseOption, CLIOptions } from '@memlab/core';
11
11
  import BaseCommand from '../../BaseCommand';
@@ -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 __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
12
  if (k2 === undefined) k2 = k;