diff --git a/src/McpResponse.ts b/src/McpResponse.ts index a5153d401..ae6a35721 100644 --- a/src/McpResponse.ts +++ b/src/McpResponse.ts @@ -9,6 +9,7 @@ import type {WebMCPTool} from 'puppeteer-core'; import type {ParsedArguments} from './bin/chrome-devtools-mcp-cli-options.js'; import {ConsoleFormatter} from './formatters/ConsoleFormatter.js'; import {HeapSnapshotFormatter} from './formatters/HeapSnapshotFormatter.js'; +import {isNodeLike} from './formatters/HeapSnapshotFormatter.js'; import {IssueFormatter} from './formatters/IssueFormatter.js'; import {NetworkFormatter} from './formatters/NetworkFormatter.js'; import {SnapshotFormatter} from './formatters/SnapshotFormatter.js'; @@ -945,8 +946,12 @@ Call ${handleDialog.name} to handle it before continuing.`); } const nodes = this.#heapSnapshotOptions.nodes; if (nodes) { + const sortedItems = nodes.items + .filter(isNodeLike) + .sort((a, b) => b.retainedSize - a.retainedSize); + const paginationData = this.#dataWithPagination( - nodes.items, + sortedItems, this.#heapSnapshotOptions.pagination, ); diff --git a/src/formatters/HeapSnapshotFormatter.ts b/src/formatters/HeapSnapshotFormatter.ts index 9fa6afe0b..20ee4c9c9 100644 --- a/src/formatters/HeapSnapshotFormatter.ts +++ b/src/formatters/HeapSnapshotFormatter.ts @@ -16,7 +16,7 @@ export interface FormattedSnapshotEntry { retainedSize: number; } -function isNodeLike( +export function isNodeLike( item: unknown, ): item is DevTools.HeapSnapshotModel.HeapSnapshotModel.Node { return ( @@ -55,7 +55,7 @@ export class HeapSnapshotFormatter { } #getSortedAggregates(): AggregatedInfoWithUid[] { - return Object.values(this.#aggregates).sort((a, b) => b.self - a.self); + return Object.values(this.#aggregates).sort((a, b) => b.maxRet - a.maxRet); } toString(): string { @@ -92,6 +92,6 @@ export class HeapSnapshotFormatter { ): Array< [string, DevTools.HeapSnapshotModel.HeapSnapshotModel.AggregatedInfo] > { - return Object.entries(aggregates).sort((a, b) => b[1].self - a[1].self); + return Object.entries(aggregates).sort((a, b) => b[1].maxRet - a[1].maxRet); } } diff --git a/tests/formatters/HeapSnapshotFormatter.test.js.snapshot b/tests/formatters/HeapSnapshotFormatter.test.js.snapshot index 5f729f11d..9756c8ab2 100644 --- a/tests/formatters/HeapSnapshotFormatter.test.js.snapshot +++ b/tests/formatters/HeapSnapshotFormatter.test.js.snapshot @@ -1,4 +1,4 @@ -exports[`HeapSnapshotFormatter > toString > formats data as CSV and sorts by self size 1`] = ` +exports[`HeapSnapshotFormatter > toString > formats data as CSV and sorts by retained size 1`] = ` uid,className,count,selfSize,maxRetainedSize 1,"ObjectA",10,100,1000 2,"ObjectB",5,50,500 diff --git a/tests/formatters/HeapSnapshotFormatter.test.ts b/tests/formatters/HeapSnapshotFormatter.test.ts index 21bef9f15..d1b29c4cb 100644 --- a/tests/formatters/HeapSnapshotFormatter.test.ts +++ b/tests/formatters/HeapSnapshotFormatter.test.ts @@ -37,7 +37,7 @@ describe('HeapSnapshotFormatter', () => { }; describe('toString', () => { - it('formats data as CSV and sorts by self size', t => { + it('formats data as CSV and sorts by retained size', t => { const formatter = new HeapSnapshotFormatter(mockAggregates); const result = formatter.toString(); t.assert.snapshot?.(result); @@ -45,7 +45,7 @@ describe('HeapSnapshotFormatter', () => { }); describe('toJSON', () => { - it('returns structured data sorted by self size', () => { + it('returns structured data sorted by retained size', () => { const formatter = new HeapSnapshotFormatter(mockAggregates); const result = formatter.toJSON(); assert.deepStrictEqual(result, [ @@ -68,7 +68,7 @@ describe('HeapSnapshotFormatter', () => { }); describe('sort', () => { - it('sorts aggregates by self size descending', () => { + it('sorts aggregates by retained size descending', () => { const unsortedAggregates: Record< string, DevTools.HeapSnapshotModel.HeapSnapshotModel.AggregatedInfo @@ -76,10 +76,12 @@ describe('HeapSnapshotFormatter', () => { ObjectB: { name: 'ObjectB', self: 50, + maxRet: 500, }, ObjectA: { name: 'ObjectA', self: 100, + maxRet: 1000, }, } as unknown as Record< string, diff --git a/tests/tools/memory.test.js.snapshot b/tests/tools/memory.test.js.snapshot index d2fe2c9cb..4bcd2d003 100644 --- a/tests/tools/memory.test.js.snapshot +++ b/tests/tools/memory.test.js.snapshot @@ -3,158 +3,158 @@ exports[`memory > get_memory_snapshot_details > with default options 1`] = ` Showing 1-157 of 157 (Page 1 of 1). uid,className,count,selfSize,maxRetainedSize 2,"(system)",3205,199264,655004 -16,"(object shape)",2878,181480,184320 11,"Function",3581,111464,237120 +16,"(object shape)",2878,181480,184320 +3,"(array)",34,41416,117472 42,"Window (global*) / https://example.com",2,81068,101832 94,"Window (prototype) / https://example.com",4,53336,53712 1,"(compiled code)",713,42812,46988 -3,"(array)",34,41416,117472 6,"(string)",846,27880,27880 -109,"Document",1,8448,8700 -105,"HTMLElement",1,4728,4768 -104,"Element",1,4224,4540 +96,"Window (internal cache) / https://example.com",4,400,20256 15,"Object (global*)",2,3856,13488 -10,"HTMLDocument",1,3288,6192 -89,"system / Context",116,2544,3488 -103,"Node",1,1764,1804 +55,"{constructor, toString, toDateString, toTimeString, toISOString, toUTCString, toGMTString, getDate, setDate, getDay}",4,848,8848 49,"TypedArray",48,1424,8784 +109,"Document",1,8448,8700 50,"Error",48,1344,7872 -106,"HTMLBodyElement (prototype) / https://example.com",1,1188,1228 -19,"Array",8,1056,7728 -126,"Performance",1,1040,1784 -32,"String",4,960,6056 -54,"Object",22,928,1168 -130,"StyleEngine",1,912,1104 -9,"Window / https://example.com",1,904,1944 -55,"{constructor, toString, toDateString, toTimeString, toISOString, toUTCString, toGMTString, getDate, setDate, getDay}",4,848,8848 47,"Math",4,816,7792 +19,"Array",8,1056,7728 39,"{constructor, buffer, get buffer, byteLength, get byteLength, byteOffset, get byteOffset, length, get length}",4,624,7008 -118,"CSSStyleRule",8,576,1024 -119,"CSSStyleSheet",3,528,976 +10,"HTMLDocument",1,3288,6192 44,"console",4,488,6152 +32,"String",4,960,6056 68,"DataView",4,480,5504 +105,"HTMLElement",1,4728,4768 +62,"Intl.Locale",4,288,4672 +104,"Element",1,4224,4540 76,"{constructor, getColumnNumber, getEnclosingColumnNumber, getEnclosingLineNumber, getEvalOrigin, getFileName, getFunction}",4,480,4448 -110,"Text",6,480,480 -37,"WebAssembly",4,416,1904 -96,"Window (internal cache) / https://example.com",4,400,20256 -135,"EventListener",10,400,400 -40,"{constructor}",14,392,1560 -30,"Set",4,384,1616 -27,"Map",4,336,1504 -43,"Atomics",4,336,3056 45,"Intl",4,336,4192 -46,"Reflect",4,336,2480 -67,"{at, copyWithin, entries, fill, find, findIndex, findLast, findLastIndex, flat, flatMap, includes, keys, toReversed}",4,336,1344 -134,"FontFaceSet",1,328,328 -133,"StylePropertyMap",8,320,320 -139,"MutationObserver",2,320,320 25,"{, constructor, get constructor, set constructor, reduce, toArray, forEach, some, every, find}",4,288,3600 -28,"{constructor, __defineGetter__, __defineSetter__, hasOwnProperty, __lookupGetter__, __lookupSetter__, isPrototypeOf}",4,288,1128 -62,"Intl.Locale",4,288,4672 -33,"WeakMap",4,240,960 -36,"{constructor, exec, dotAll, get dotAll, flags, get flags, global, get global, hasIndices, get hasIndices, ignoreCase}",4,240,576 -48,"Number",4,240,1488 +89,"system / Context",116,2544,3488 +43,"Atomics",4,336,3056 91,"DisposableStack",4,240,3040 92,"AsyncDisposableStack",4,240,3040 -4,"{, }",8,224,352 -131,"ScriptedAnimationController",1,208,208 -123,"IntersectionObserver",1,200,240 -7,"(number)",16,192,192 -17,"{isTraceCategoryEnabled, trace, getContinuationPreservedEmbedderData, setContinuationPreservedEmbedderData, console}",4,192,1120 -21,"Generator",4,192,1008 -23,"AsyncGenerator",4,192,1008 -34,"JSON",4,192,1008 -35,"Promise",4,192,1000 -53,"WeakSet",4,192,416 +46,"Reflect",4,336,2480 +72,"ArrayBuffer",4,192,2160 +9,"Window / https://example.com",1,904,1944 +37,"WebAssembly",4,416,1904 +58,"{constructor, , resolvedOptions, adoptText, get adoptText, first, get first, next, get next}",4,112,1808 +103,"Node",1,1764,1804 +126,"Performance",1,1040,1784 +30,"Set",4,384,1616 +40,"{constructor}",14,392,1560 +90,"SharedArrayBuffer",4,112,1552 56,"Intl.NumberFormat",4,192,1536 +66,"Intl.DateTimeFormat",4,192,1536 +27,"Map",4,336,1504 +48,"Number",4,240,1488 +70,"Symbol",4,192,1376 +67,"{at, copyWithin, entries, fill, find, findIndex, findLast, findLastIndex, flat, flatMap, includes, keys, toReversed}",4,336,1344 +106,"HTMLBodyElement (prototype) / https://example.com",1,1188,1228 +54,"Object",22,928,1168 59,"Intl.PluralRules",4,192,1168 60,"Intl.RelativeTimeFormat",4,192,1168 61,"Intl.ListFormat",4,192,1168 65,"Intl.DurationFormat",4,192,1168 -66,"Intl.DateTimeFormat",4,192,1536 69,"BigInt",4,192,1168 -70,"Symbol",4,192,1376 -72,"ArrayBuffer",4,192,2160 +28,"{constructor, __defineGetter__, __defineSetter__, hasOwnProperty, __lookupGetter__, __lookupSetter__, isPrototypeOf}",4,288,1128 +17,"{isTraceCategoryEnabled, trace, getContinuationPreservedEmbedderData, setContinuationPreservedEmbedderData, console}",4,192,1120 +130,"StyleEngine",1,912,1104 +118,"CSSStyleRule",8,576,1024 +21,"Generator",4,192,1008 +23,"AsyncGenerator",4,192,1008 +34,"JSON",4,192,1008 +35,"Promise",4,192,1000 +57,"Intl.Collator",4,112,976 +119,"CSSStyleSheet",3,528,976 +33,"WeakMap",4,240,960 +52,"FinalizationRegistry",4,112,928 +63,"Intl.DisplayNames",4,112,928 +64,"Intl.Segmenter",4,112,928 +73,"Async-from-Sync Iterator",4,112,880 +22,"{, }",4,112,864 +85,"{containing, }",4,112,832 +51,"WeakRef",4,112,768 79,"WebAssembly.Table",4,192,768 80,"WebAssembly.Memory",4,192,768 +71,"Boolean",4,144,752 +18,"Array Iterator",4,112,720 +24,"Iterator Helper",4,112,720 +26,"Map Iterator",4,112,720 +29,"Set Iterator",4,112,720 +31,"String Iterator",4,112,720 +86,"Segmenter String Iterator",4,112,720 +88,"RegExp String Iterator",4,112,720 +20,"{constructor, name, message, toString}",4,112,704 +87,"{next, return}",4,112,672 +75,"AsyncGeneratorFunction",4,112,656 +84,"GeneratorFunction",4,112,656 +74,"AsyncFunction",4,112,608 +81,"WebAssembly.Global",4,112,592 +93,"WebAssembly.Suspending",4,112,592 +100,"{loadTimes, csi}",2,56,580 +36,"{constructor, exec, dotAll, get dotAll, flags, get flags, global, get global, hasIndices, get hasIndices, ignoreCase}",4,240,576 +78,"WebAssembly.Instance",4,112,544 +83,"WebAssembly.Exception",4,112,544 +110,"Text",6,480,480 +77,"WebAssembly.Module",4,112,448 +82,"WebAssembly.Tag",4,112,448 +101,"EventTarget",2,92,436 +53,"WeakSet",4,192,416 +135,"EventListener",10,400,400 +99,"{parse, stringify}",2,40,384 +127,"Navigation",1,152,384 +4,"{, }",8,224,352 +134,"FontFaceSet",1,328,328 +133,"StylePropertyMap",8,320,320 +139,"MutationObserver",2,320,320 +102,"WindowProperties",2,56,280 +115,"