@memlab/mcp-server 2.18.1 → 2.86.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -16
- package/bin/.eslintrc.js +26 -0
- package/bin/memlab-cli.js +313 -0
- package/dist/anonymized-snapshot.d.ts +75 -0
- package/dist/anonymized-snapshot.d.ts.map +1 -0
- package/dist/anonymized-snapshot.js +101 -0
- package/dist/anonymized-snapshot.js.map +1 -0
- package/dist/artifact-classes.d.ts +86 -0
- package/dist/artifact-classes.d.ts.map +1 -0
- package/dist/artifact-classes.js +261 -0
- package/dist/artifact-classes.js.map +1 -0
- package/dist/capture-mode.d.ts +60 -0
- package/dist/capture-mode.d.ts.map +1 -0
- package/dist/capture-mode.js +39 -0
- package/dist/capture-mode.js.map +1 -0
- package/dist/eval-hints.d.ts +41 -0
- package/dist/eval-hints.d.ts.map +1 -0
- package/dist/eval-hints.js +115 -0
- package/dist/eval-hints.js.map +1 -0
- package/dist/guardrail.d.ts.map +1 -1
- package/dist/guardrail.js +13 -0
- package/dist/guardrail.js.map +1 -1
- package/dist/heap-budget.d.ts +32 -0
- package/dist/heap-budget.d.ts.map +1 -0
- package/dist/heap-budget.js +90 -0
- package/dist/heap-budget.js.map +1 -0
- package/dist/heap-shapes.d.ts +148 -0
- package/dist/heap-shapes.d.ts.map +1 -0
- package/dist/heap-shapes.js +193 -0
- package/dist/heap-shapes.js.map +1 -0
- package/dist/heap-state.d.ts +109 -2
- package/dist/heap-state.d.ts.map +1 -1
- package/dist/heap-state.js +194 -3
- package/dist/heap-state.js.map +1 -1
- package/dist/index.js +102 -1
- package/dist/index.js.map +1 -1
- package/dist/progress.d.ts +25 -0
- package/dist/progress.d.ts.map +1 -0
- package/dist/progress.js +46 -0
- package/dist/progress.js.map +1 -0
- package/dist/react-shapes.d.ts +42 -0
- package/dist/react-shapes.d.ts.map +1 -0
- package/dist/react-shapes.js +149 -0
- package/dist/react-shapes.js.map +1 -0
- package/dist/result-handles.d.ts +11 -0
- package/dist/result-handles.d.ts.map +1 -0
- package/dist/result-handles.js +77 -0
- package/dist/result-handles.js.map +1 -0
- package/dist/server-version.d.ts +19 -0
- package/dist/server-version.d.ts.map +1 -0
- package/dist/server-version.js +19 -0
- package/dist/server-version.js.map +1 -0
- package/dist/snapshot-borrow.d.ts +67 -0
- package/dist/snapshot-borrow.d.ts.map +1 -0
- package/dist/snapshot-borrow.js +113 -0
- package/dist/snapshot-borrow.js.map +1 -0
- package/dist/string-index.d.ts +55 -0
- package/dist/string-index.d.ts.map +1 -0
- package/dist/string-index.js +99 -0
- package/dist/string-index.js.map +1 -0
- package/dist/tool-registry.d.ts +42 -0
- package/dist/tool-registry.d.ts.map +1 -0
- package/dist/tool-registry.js +20 -0
- package/dist/tool-registry.js.map +1 -0
- package/dist/tools/analyze-run.d.ts +12 -0
- package/dist/tools/analyze-run.d.ts.map +1 -0
- package/dist/tools/analyze-run.js +404 -0
- package/dist/tools/analyze-run.js.map +1 -0
- package/dist/tools/anonymize-snapshot.d.ts +12 -0
- package/dist/tools/anonymize-snapshot.d.ts.map +1 -0
- package/dist/tools/anonymize-snapshot.js +159 -0
- package/dist/tools/anonymize-snapshot.js.map +1 -0
- package/dist/tools/app-config.d.ts +12 -0
- package/dist/tools/app-config.d.ts.map +1 -0
- package/dist/tools/app-config.js +217 -0
- package/dist/tools/app-config.js.map +1 -0
- package/dist/tools/app-heap.d.ts +30 -0
- package/dist/tools/app-heap.d.ts.map +1 -0
- package/dist/tools/app-heap.js +106 -0
- package/dist/tools/app-heap.js.map +1 -0
- package/dist/tools/artifact-budget.d.ts +12 -0
- package/dist/tools/artifact-budget.d.ts.map +1 -0
- package/dist/tools/artifact-budget.js +219 -0
- package/dist/tools/artifact-budget.js.map +1 -0
- package/dist/tools/async-census.d.ts +12 -0
- package/dist/tools/async-census.d.ts.map +1 -0
- package/dist/tools/async-census.js +243 -0
- package/dist/tools/async-census.js.map +1 -0
- package/dist/tools/auto-investigate.d.ts.map +1 -1
- package/dist/tools/auto-investigate.js +54 -5
- package/dist/tools/auto-investigate.js.map +1 -1
- package/dist/tools/batch.d.ts +12 -0
- package/dist/tools/batch.d.ts.map +1 -0
- package/dist/tools/batch.js +196 -0
- package/dist/tools/batch.js.map +1 -0
- package/dist/tools/cache-analysis.d.ts +15 -0
- package/dist/tools/cache-analysis.d.ts.map +1 -1
- package/dist/tools/cache-analysis.js +240 -14
- package/dist/tools/cache-analysis.js.map +1 -1
- package/dist/tools/census-diff.d.ts +55 -0
- package/dist/tools/census-diff.d.ts.map +1 -0
- package/dist/tools/census-diff.js +228 -0
- package/dist/tools/census-diff.js.map +1 -0
- package/dist/tools/chain-walk.d.ts +12 -0
- package/dist/tools/chain-walk.d.ts.map +1 -0
- package/dist/tools/chain-walk.js +184 -0
- package/dist/tools/chain-walk.js.map +1 -0
- package/dist/tools/class-histogram.d.ts.map +1 -1
- package/dist/tools/class-histogram.js +14 -3
- package/dist/tools/class-histogram.js.map +1 -1
- package/dist/tools/collection-diff.d.ts +44 -0
- package/dist/tools/collection-diff.d.ts.map +1 -0
- package/dist/tools/collection-diff.js +343 -0
- package/dist/tools/collection-diff.js.map +1 -0
- package/dist/tools/collection-trend.d.ts +55 -0
- package/dist/tools/collection-trend.d.ts.map +1 -0
- package/dist/tools/collection-trend.js +315 -0
- package/dist/tools/collection-trend.js.map +1 -0
- package/dist/tools/detached-dom.d.ts +5 -0
- package/dist/tools/detached-dom.d.ts.map +1 -1
- package/dist/tools/detached-dom.js +368 -22
- package/dist/tools/detached-dom.js.map +1 -1
- package/dist/tools/dev-artifacts.d.ts +62 -6
- package/dist/tools/dev-artifacts.d.ts.map +1 -1
- package/dist/tools/dev-artifacts.js +685 -24
- package/dist/tools/dev-artifacts.js.map +1 -1
- package/dist/tools/diff-snapshots.d.ts.map +1 -1
- package/dist/tools/diff-snapshots.js +18 -2
- package/dist/tools/diff-snapshots.js.map +1 -1
- package/dist/tools/dom-audit.d.ts +37 -0
- package/dist/tools/dom-audit.d.ts.map +1 -0
- package/dist/tools/dom-audit.js +247 -0
- package/dist/tools/dom-audit.js.map +1 -0
- package/dist/tools/dominator-attribution.d.ts +12 -0
- package/dist/tools/dominator-attribution.d.ts.map +1 -0
- package/dist/tools/dominator-attribution.js +189 -0
- package/dist/tools/dominator-attribution.js.map +1 -0
- package/dist/tools/dominator-chain.d.ts +12 -0
- package/dist/tools/dominator-chain.d.ts.map +1 -0
- package/dist/tools/dominator-chain.js +92 -0
- package/dist/tools/dominator-chain.js.map +1 -0
- package/dist/tools/duplicate-objects.d.ts +12 -0
- package/dist/tools/duplicate-objects.d.ts.map +1 -0
- package/dist/tools/duplicate-objects.js +172 -0
- package/dist/tools/duplicate-objects.js.map +1 -0
- package/dist/tools/duplicated-strings.d.ts.map +1 -1
- package/dist/tools/duplicated-strings.js +49 -40
- package/dist/tools/duplicated-strings.js.map +1 -1
- package/dist/tools/eval-across.d.ts +12 -0
- package/dist/tools/eval-across.d.ts.map +1 -0
- package/dist/tools/eval-across.js +135 -0
- package/dist/tools/eval-across.js.map +1 -0
- package/dist/tools/eval.d.ts +79 -0
- package/dist/tools/eval.d.ts.map +1 -1
- package/dist/tools/eval.js +2523 -197
- package/dist/tools/eval.js.map +1 -1
- package/dist/tools/event-listener-leaks.d.ts.map +1 -1
- package/dist/tools/event-listener-leaks.js +42 -17
- package/dist/tools/event-listener-leaks.js.map +1 -1
- package/dist/tools/event-registry.d.ts.map +1 -1
- package/dist/tools/event-registry.js +42 -8
- package/dist/tools/event-registry.js.map +1 -1
- package/dist/tools/explain-delta.d.ts +12 -0
- package/dist/tools/explain-delta.d.ts.map +1 -0
- package/dist/tools/explain-delta.js +221 -0
- package/dist/tools/explain-delta.js.map +1 -0
- package/dist/tools/find-nodes-by-class.d.ts.map +1 -1
- package/dist/tools/find-nodes-by-class.js +112 -13
- package/dist/tools/find-nodes-by-class.js.map +1 -1
- package/dist/tools/finding-index.d.ts +203 -0
- package/dist/tools/finding-index.d.ts.map +1 -0
- package/dist/tools/finding-index.js +566 -0
- package/dist/tools/finding-index.js.map +1 -0
- package/dist/tools/for-each.d.ts.map +1 -1
- package/dist/tools/for-each.js +15 -3
- package/dist/tools/for-each.js.map +1 -1
- package/dist/tools/get-referrers.d.ts.map +1 -1
- package/dist/tools/get-referrers.js +17 -0
- package/dist/tools/get-referrers.js.map +1 -1
- package/dist/tools/get-value.d.ts +16 -0
- package/dist/tools/get-value.d.ts.map +1 -1
- package/dist/tools/get-value.js +96 -2
- package/dist/tools/get-value.js.map +1 -1
- package/dist/tools/hunt-report.d.ts +12 -0
- package/dist/tools/hunt-report.d.ts.map +1 -0
- package/dist/tools/hunt-report.js +186 -0
- package/dist/tools/hunt-report.js.map +1 -0
- package/dist/tools/hypothesis.d.ts +12 -0
- package/dist/tools/hypothesis.d.ts.map +1 -0
- package/dist/tools/hypothesis.js +280 -0
- package/dist/tools/hypothesis.js.map +1 -0
- package/dist/tools/id-space-audit.d.ts +12 -0
- package/dist/tools/id-space-audit.d.ts.map +1 -0
- package/dist/tools/id-space-audit.js +262 -0
- package/dist/tools/id-space-audit.js.map +1 -0
- package/dist/tools/identify.d.ts +12 -0
- package/dist/tools/identify.d.ts.map +1 -0
- package/dist/tools/identify.js +205 -0
- package/dist/tools/identify.js.map +1 -0
- package/dist/tools/identity-diff.d.ts +12 -0
- package/dist/tools/identity-diff.d.ts.map +1 -0
- package/dist/tools/identity-diff.js +188 -0
- package/dist/tools/identity-diff.js.map +1 -0
- package/dist/tools/intern-opportunities.d.ts.map +1 -1
- package/dist/tools/intern-opportunities.js +116 -50
- package/dist/tools/intern-opportunities.js.map +1 -1
- package/dist/tools/ladder-probe.d.ts +65 -0
- package/dist/tools/ladder-probe.d.ts.map +1 -0
- package/dist/tools/ladder-probe.js +445 -0
- package/dist/tools/ladder-probe.js.map +1 -0
- package/dist/tools/ladder.d.ts +33 -0
- package/dist/tools/ladder.d.ts.map +1 -0
- package/dist/tools/ladder.js +266 -0
- package/dist/tools/ladder.js.map +1 -0
- package/dist/tools/largest-objects.d.ts.map +1 -1
- package/dist/tools/largest-objects.js +6 -2
- package/dist/tools/largest-objects.js.map +1 -1
- package/dist/tools/leak-report.d.ts +35 -0
- package/dist/tools/leak-report.d.ts.map +1 -0
- package/dist/tools/leak-report.js +398 -0
- package/dist/tools/leak-report.js.map +1 -0
- package/dist/tools/load-snapshot.d.ts +29 -0
- package/dist/tools/load-snapshot.d.ts.map +1 -1
- package/dist/tools/load-snapshot.js +294 -23
- package/dist/tools/load-snapshot.js.map +1 -1
- package/dist/tools/map-entries.d.ts +12 -0
- package/dist/tools/map-entries.d.ts.map +1 -0
- package/dist/tools/map-entries.js +139 -0
- package/dist/tools/map-entries.js.map +1 -0
- package/dist/tools/match-object.d.ts +12 -0
- package/dist/tools/match-object.d.ts.map +1 -0
- package/dist/tools/match-object.js +165 -0
- package/dist/tools/match-object.js.map +1 -0
- package/dist/tools/metric.d.ts +13 -0
- package/dist/tools/metric.d.ts.map +1 -0
- package/dist/tools/metric.js +185 -0
- package/dist/tools/metric.js.map +1 -0
- package/dist/tools/module-attribution.d.ts +36 -0
- package/dist/tools/module-attribution.d.ts.map +1 -0
- package/dist/tools/module-attribution.js +235 -0
- package/dist/tools/module-attribution.js.map +1 -0
- package/dist/tools/next-measurement.d.ts +26 -0
- package/dist/tools/next-measurement.d.ts.map +1 -0
- package/dist/tools/next-measurement.js +149 -0
- package/dist/tools/next-measurement.js.map +1 -0
- package/dist/tools/object-cost-breakdown.d.ts.map +1 -1
- package/dist/tools/object-cost-breakdown.js +64 -0
- package/dist/tools/object-cost-breakdown.js.map +1 -1
- package/dist/tools/object-shape.d.ts.map +1 -1
- package/dist/tools/object-shape.js +53 -5
- package/dist/tools/object-shape.js.map +1 -1
- package/dist/tools/population-diff.d.ts +57 -0
- package/dist/tools/population-diff.d.ts.map +1 -0
- package/dist/tools/population-diff.js +338 -0
- package/dist/tools/population-diff.js.map +1 -0
- package/dist/tools/population-vs-owners.d.ts +12 -0
- package/dist/tools/population-vs-owners.d.ts.map +1 -0
- package/dist/tools/population-vs-owners.js +183 -0
- package/dist/tools/population-vs-owners.js.map +1 -0
- package/dist/tools/property-names.d.ts +29 -0
- package/dist/tools/property-names.d.ts.map +1 -0
- package/dist/tools/property-names.js +131 -0
- package/dist/tools/property-names.js.map +1 -0
- package/dist/tools/quick-diagnosis.d.ts.map +1 -1
- package/dist/tools/quick-diagnosis.js +7 -1
- package/dist/tools/quick-diagnosis.js.map +1 -1
- package/dist/tools/react-owners.d.ts +12 -0
- package/dist/tools/react-owners.d.ts.map +1 -0
- package/dist/tools/react-owners.js +167 -0
- package/dist/tools/react-owners.js.map +1 -0
- package/dist/tools/react-update-queues.d.ts +12 -0
- package/dist/tools/react-update-queues.d.ts.map +1 -0
- package/dist/tools/react-update-queues.js +173 -0
- package/dist/tools/react-update-queues.js.map +1 -0
- package/dist/tools/replicate.d.ts +49 -0
- package/dist/tools/replicate.d.ts.map +1 -0
- package/dist/tools/replicate.js +241 -0
- package/dist/tools/replicate.js.map +1 -0
- package/dist/tools/retainer-diff.d.ts +12 -0
- package/dist/tools/retainer-diff.d.ts.map +1 -0
- package/dist/tools/retainer-diff.js +168 -0
- package/dist/tools/retainer-diff.js.map +1 -0
- package/dist/tools/retainer-layers.d.ts +23 -0
- package/dist/tools/retainer-layers.d.ts.map +1 -0
- package/dist/tools/retainer-layers.js +179 -0
- package/dist/tools/retainer-layers.js.map +1 -0
- package/dist/tools/retainer-summary.d.ts +18 -0
- package/dist/tools/retainer-summary.d.ts.map +1 -1
- package/dist/tools/retainer-summary.js +210 -51
- package/dist/tools/retainer-summary.js.map +1 -1
- package/dist/tools/retainer-trace.d.ts.map +1 -1
- package/dist/tools/retainer-trace.js +14 -2
- package/dist/tools/retainer-trace.js.map +1 -1
- package/dist/tools/round-audit.d.ts +66 -0
- package/dist/tools/round-audit.d.ts.map +1 -0
- package/dist/tools/round-audit.js +258 -0
- package/dist/tools/round-audit.js.map +1 -0
- package/dist/tools/round-digest.d.ts +12 -0
- package/dist/tools/round-digest.d.ts.map +1 -0
- package/dist/tools/round-digest.js +190 -0
- package/dist/tools/round-digest.js.map +1 -0
- package/dist/tools/script-census.d.ts +12 -0
- package/dist/tools/script-census.d.ts.map +1 -0
- package/dist/tools/script-census.js +182 -0
- package/dist/tools/script-census.js.map +1 -0
- package/dist/tools/search-nodes.d.ts.map +1 -1
- package/dist/tools/search-nodes.js +5 -1
- package/dist/tools/search-nodes.js.map +1 -1
- package/dist/tools/search-strings.d.ts.map +1 -1
- package/dist/tools/search-strings.js +53 -7
- package/dist/tools/search-strings.js.map +1 -1
- package/dist/tools/sequence-analysis.d.ts +53 -0
- package/dist/tools/sequence-analysis.d.ts.map +1 -1
- package/dist/tools/sequence-analysis.js +313 -89
- package/dist/tools/sequence-analysis.js.map +1 -1
- package/dist/tools/server-status.d.ts.map +1 -1
- package/dist/tools/server-status.js +4 -1
- package/dist/tools/server-status.js.map +1 -1
- package/dist/tools/settle-check.d.ts +12 -0
- package/dist/tools/settle-check.d.ts.map +1 -0
- package/dist/tools/settle-check.js +188 -0
- package/dist/tools/settle-check.js.map +1 -0
- package/dist/tools/shape-histogram.d.ts.map +1 -1
- package/dist/tools/shape-histogram.js +9 -2
- package/dist/tools/shape-histogram.js.map +1 -1
- package/dist/tools/sliced-strings.d.ts.map +1 -1
- package/dist/tools/sliced-strings.js +2 -1
- package/dist/tools/sliced-strings.js.map +1 -1
- package/dist/tools/snapshots.d.ts.map +1 -1
- package/dist/tools/snapshots.js +24 -6
- package/dist/tools/snapshots.js.map +1 -1
- package/dist/tools/sparse-elements.d.ts +12 -0
- package/dist/tools/sparse-elements.d.ts.map +1 -0
- package/dist/tools/sparse-elements.js +215 -0
- package/dist/tools/sparse-elements.js.map +1 -0
- package/dist/tools/stale-collections.d.ts +17 -0
- package/dist/tools/stale-collections.d.ts.map +1 -1
- package/dist/tools/stale-collections.js +28 -0
- package/dist/tools/stale-collections.js.map +1 -1
- package/dist/tools/string-patterns.d.ts.map +1 -1
- package/dist/tools/string-patterns.js +7 -5
- package/dist/tools/string-patterns.js.map +1 -1
- package/dist/tools/tools-index.d.ts +12 -0
- package/dist/tools/tools-index.d.ts.map +1 -0
- package/dist/tools/tools-index.js +492 -0
- package/dist/tools/tools-index.js.map +1 -0
- package/dist/tools/trace-all.d.ts +42 -0
- package/dist/tools/trace-all.d.ts.map +1 -0
- package/dist/tools/trace-all.js +263 -0
- package/dist/tools/trace-all.js.map +1 -0
- package/dist/tools/unit-cost.d.ts +12 -0
- package/dist/tools/unit-cost.d.ts.map +1 -0
- package/dist/tools/unit-cost.js +219 -0
- package/dist/tools/unit-cost.js.map +1 -0
- package/dist/tools/verify-fix.d.ts +23 -0
- package/dist/tools/verify-fix.d.ts.map +1 -0
- package/dist/tools/verify-fix.js +219 -0
- package/dist/tools/verify-fix.js.map +1 -0
- package/dist/tools/weakmap-entries.d.ts.map +1 -1
- package/dist/tools/weakmap-entries.js +6 -1
- package/dist/tools/weakmap-entries.js.map +1 -1
- package/dist/tools/weakref-census.d.ts +15 -0
- package/dist/tools/weakref-census.d.ts.map +1 -0
- package/dist/tools/weakref-census.js +147 -0
- package/dist/tools/weakref-census.js.map +1 -0
- package/dist/tools/what-if.d.ts +12 -0
- package/dist/tools/what-if.d.ts.map +1 -0
- package/dist/tools/what-if.js +285 -0
- package/dist/tools/what-if.js.map +1 -0
- package/dist/utils.d.ts +238 -3
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +507 -15
- package/dist/utils.js.map +1 -1
- package/package.json +7 -6
|
@@ -9,16 +9,117 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { z } from 'zod';
|
|
11
11
|
import { getSnapshot, getSnapshotEnv } from '../heap-state.js';
|
|
12
|
-
import { queryNodes, formatQueryNodesResult, formatBytes, formatNumber, markdownTable, errorResult, toolResult, } from '../utils.js';
|
|
13
|
-
import
|
|
14
|
-
|
|
12
|
+
import { queryNodes, formatQueryNodesResult, formatBytes, formatNumber, isNodeWorthInspecting, markdownTable, truncateNodeName, errorResult, toolResult, boundedDominatorRetainedSize, } from '../utils.js';
|
|
13
|
+
import memlabCore from '@memlab/core';
|
|
14
|
+
const { NumericSet } = memlabCore;
|
|
15
|
+
import { collectDevRoots, classifyDevOnly, computeReachableWithoutDevRoots, summarizeDevRoots, } from './dev-artifacts.js';
|
|
16
|
+
export function isDetachedDOMNode(node) {
|
|
15
17
|
if (node.id <= 3)
|
|
16
18
|
return false;
|
|
17
19
|
if (node.is_detached)
|
|
18
20
|
return true;
|
|
19
21
|
return node.name.startsWith('Detached ');
|
|
20
22
|
}
|
|
21
|
-
|
|
23
|
+
// A detached node is only an actual leak if it is still reachable from a GC
|
|
24
|
+
// root — i.e. it has a shortest-path retainer edge. Detached nodes with NO
|
|
25
|
+
// retainer path found are typically GC-eligible (about to be collected) or
|
|
26
|
+
// retained only through weak references, and should not be counted toward a
|
|
27
|
+
// leak total. This distinguishes the "which half is real" problem where a
|
|
28
|
+
// snapshot's detached-node list mixes genuinely-pinned nodes with transient
|
|
29
|
+
// ones. `hasPathEdge` is the same reachability signal used to walk retainers.
|
|
30
|
+
export function isPinned(node) {
|
|
31
|
+
return Boolean(node.hasPathEdge);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Detached browsing contexts (iframes) that no application object references.
|
|
35
|
+
*
|
|
36
|
+
* A detached `Window` / `HTMLDocument` / `NativeContext` whose only referrers
|
|
37
|
+
* are other detached natives is retained by Blink's own binding layer — on one
|
|
38
|
+
* measured capture the only path to a GC root ran
|
|
39
|
+
* `Window -> History -> History.prototype -> get state (FunctionTemplateInfo)
|
|
40
|
+
* -> WeakMap -> History -> .context -> Detached NativeContext -> Detached
|
|
41
|
+
* Window -> Detached HTMLDocument`, with zero application referrers anywhere.
|
|
42
|
+
*
|
|
43
|
+
* These satisfy `isPinned` and were therefore reported as "actionable leak",
|
|
44
|
+
* which on that capture was 274,935 of 330,334 detached nodes and roughly half
|
|
45
|
+
* the reclaimable bytes. No application change can free them, so counting them
|
|
46
|
+
* in a leak total overstates it by however many stale iframes the page has.
|
|
47
|
+
*/
|
|
48
|
+
const BROWSING_CONTEXT_NAMES = [
|
|
49
|
+
'Detached Window',
|
|
50
|
+
'Detached HTMLDocument',
|
|
51
|
+
'Detached system / NativeContext',
|
|
52
|
+
];
|
|
53
|
+
function findBrowserOwnedContexts(snapshot) {
|
|
54
|
+
const roots = new Set();
|
|
55
|
+
snapshot.nodes.forEach(node => {
|
|
56
|
+
if (!BROWSING_CONTEXT_NAMES.some(n => node.name.startsWith(n)))
|
|
57
|
+
return;
|
|
58
|
+
// "No application referrer" is the whole test: if app code holds it, the
|
|
59
|
+
// app can let go of it and it is a real leak.
|
|
60
|
+
let appReferrer = false;
|
|
61
|
+
for (const ref of node.referrers) {
|
|
62
|
+
const from = ref.fromNode;
|
|
63
|
+
// `system / …` nodes are V8/Blink bookkeeping, not application
|
|
64
|
+
// ownership; counting them as an app referrer would suppress the bucket
|
|
65
|
+
// for exactly the contexts it exists to find.
|
|
66
|
+
if (!from.name.startsWith('Detached ') &&
|
|
67
|
+
!from.name.startsWith('system /') &&
|
|
68
|
+
from.type !== 'synthetic') {
|
|
69
|
+
appReferrer = true;
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (!appReferrer)
|
|
74
|
+
roots.add(node.id);
|
|
75
|
+
});
|
|
76
|
+
return roots;
|
|
77
|
+
}
|
|
78
|
+
/** Is this node inside one of those contexts? Bounded dominator walk. */
|
|
79
|
+
function isBrowserOwned(node, roots) {
|
|
80
|
+
if (roots.size === 0)
|
|
81
|
+
return false;
|
|
82
|
+
let cur = node;
|
|
83
|
+
for (let i = 0; i < 30 && cur; i++) {
|
|
84
|
+
if (roots.has(cur.id))
|
|
85
|
+
return true;
|
|
86
|
+
cur = cur.dominatorNode ?? null;
|
|
87
|
+
}
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
function emptySplit() {
|
|
91
|
+
return {
|
|
92
|
+
pinnedCount: 0,
|
|
93
|
+
pinnedRetained: 0,
|
|
94
|
+
noPathCount: 0,
|
|
95
|
+
noPathRetained: 0,
|
|
96
|
+
pinnedIds: [],
|
|
97
|
+
browserOwnedCount: 0,
|
|
98
|
+
browserOwnedIds: [],
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Two different numbers, and quoting the wrong one has produced published
|
|
103
|
+
* errors: on one round the plain sum read 9.7 MB where the amount actually
|
|
104
|
+
* reclaimable was 308 KB. Lead with the dominator-deduped figure and keep the
|
|
105
|
+
* sum visible but explicitly labelled.
|
|
106
|
+
*/
|
|
107
|
+
function formatReachabilitySplit(split, snapshot) {
|
|
108
|
+
const deduped = boundedDominatorRetainedSize(new NumericSet(split.pinnedIds), snapshot);
|
|
109
|
+
const bound = deduped.exact ? '' : ' (upper bound; deep dominator chain)';
|
|
110
|
+
const browserOwnedDeduped = boundedDominatorRetainedSize(new NumericSet(split.browserOwnedIds), snapshot);
|
|
111
|
+
return [
|
|
112
|
+
`- Pinned (retainer path to a GC root — actionable leak): ${formatNumber(split.pinnedCount)} nodes, **${formatBytes(deduped.retained)} reclaimable**${bound} (dominator-deduped)`,
|
|
113
|
+
` - sum over nodes: ${formatBytes(split.pinnedRetained)} — double-counts nested detached subtrees; do NOT quote this as the size of the leak`,
|
|
114
|
+
`- No retainer path found (likely GC-eligible / weak-only — exclude from leak totals): ${formatNumber(split.noPathCount)} nodes, ${formatBytes(split.noPathRetained)}`,
|
|
115
|
+
...(split.browserOwnedCount > 0
|
|
116
|
+
? [
|
|
117
|
+
`- **Of the pinned nodes, ${formatNumber(split.browserOwnedCount)} (${formatBytes(browserOwnedDeduped.retained)} dominator-deduped) sit inside DETACHED BROWSING CONTEXTS with no application referrer** — stale iframes held by Blink's binding layer. No application change frees these; subtract them before quoting a leak total. The app-attributable figure is therefore **${formatBytes(Math.max(0, deduped.retained - browserOwnedDeduped.retained))}**.`,
|
|
118
|
+
]
|
|
119
|
+
: []),
|
|
120
|
+
];
|
|
121
|
+
}
|
|
122
|
+
export function extractElementTag(name) {
|
|
22
123
|
// V8 names detached DOM as "Detached <div>" or "Detached <div class="...">"
|
|
23
124
|
const match = name.match(/^(?:Detached\s+)?<(\w+)/);
|
|
24
125
|
return match ? match[1] : name;
|
|
@@ -30,7 +131,7 @@ function extractTestId(node) {
|
|
|
30
131
|
return testIdMatch[1];
|
|
31
132
|
return '(no testid)';
|
|
32
133
|
}
|
|
33
|
-
function getFirstNonFrameworkRetainer(node) {
|
|
134
|
+
export function getFirstNonFrameworkRetainer(node) {
|
|
34
135
|
const frameworkNames = new Set([
|
|
35
136
|
'system / Context',
|
|
36
137
|
'(GC roots)',
|
|
@@ -55,14 +156,94 @@ function getFirstNonFrameworkRetainer(node) {
|
|
|
55
156
|
from.type !== 'synthetic' &&
|
|
56
157
|
from.type !== 'native') {
|
|
57
158
|
const edgeName = String(edge.name_or_index);
|
|
58
|
-
|
|
159
|
+
// V8 leaves anonymous functions/objects unnamed; printing the empty
|
|
160
|
+
// string renders as a leading blank that reads like a formatting bug.
|
|
161
|
+
const fromName = from.name.length > 0 ? from.name : '(anonymous)';
|
|
162
|
+
return `${fromName} (${from.type}) .${edgeName}`;
|
|
59
163
|
}
|
|
60
164
|
cur = from;
|
|
61
165
|
}
|
|
62
166
|
return '(unknown)';
|
|
63
167
|
}
|
|
168
|
+
// Climbing more than this many dominator hops means the detached subtree is
|
|
169
|
+
// pathologically deep; give up rather than pay for it on every node.
|
|
170
|
+
const MAX_DOMINATOR_HOPS = 64;
|
|
171
|
+
// Distinct owners tracked per group before the count is reported as "N+".
|
|
172
|
+
// Bounds memory when a group spans one owner per node (100k+ detached nodes).
|
|
173
|
+
const MAX_TRACKED_OWNERS = 1000;
|
|
174
|
+
/**
|
|
175
|
+
* Resolve the node that is ACCOUNTABLE for a detached node: the nearest
|
|
176
|
+
* dominator above it that is not itself detached DOM and is worth naming.
|
|
177
|
+
*
|
|
178
|
+
* Why this is not the same as `getFirstNonFrameworkRetainer`: that walks the
|
|
179
|
+
* shortest RETAINER path, which is only one of possibly many references and need
|
|
180
|
+
* not dominate the node at all. Grouping by it and then saying "fixing this
|
|
181
|
+
* frees X" is wrong whenever the group's nodes are also held elsewhere — the
|
|
182
|
+
* whole point of the dominator tree is that freeing a dominator DOES free
|
|
183
|
+
* everything below it.
|
|
184
|
+
*
|
|
185
|
+
* Returns a resolver closure rather than a bare function so the walk can be
|
|
186
|
+
* memoized: sibling detached nodes share ancestors, and every chain member's
|
|
187
|
+
* answer is the same node. Cached entries are per-load only (the closure lives
|
|
188
|
+
* for one tool call).
|
|
189
|
+
*/
|
|
190
|
+
function makeDominatorResolver() {
|
|
191
|
+
const cache = new Map();
|
|
192
|
+
return function resolve(node) {
|
|
193
|
+
const chain = [];
|
|
194
|
+
const seen = new Set([node.id]);
|
|
195
|
+
let cur = node.dominatorNode ?? null;
|
|
196
|
+
let owner = null;
|
|
197
|
+
let hops = 0;
|
|
198
|
+
// Whether the walk ended for a reason intrinsic to the graph (found an
|
|
199
|
+
// owner, or ran out of dominators) rather than because THIS walk ran out of
|
|
200
|
+
// budget. Only an intrinsic result may be memoized — see below.
|
|
201
|
+
let conclusive = false;
|
|
202
|
+
while (cur && hops < MAX_DOMINATOR_HOPS) {
|
|
203
|
+
const cached = cache.get(cur.id);
|
|
204
|
+
if (cached !== undefined) {
|
|
205
|
+
owner = cached;
|
|
206
|
+
conclusive = true;
|
|
207
|
+
break;
|
|
208
|
+
}
|
|
209
|
+
if (seen.has(cur.id))
|
|
210
|
+
break;
|
|
211
|
+
seen.add(cur.id);
|
|
212
|
+
chain.push(cur.id);
|
|
213
|
+
if (!isDetachedDOMNode(cur) &&
|
|
214
|
+
cur.name !== '(GC roots)' &&
|
|
215
|
+
isNodeWorthInspecting(cur)) {
|
|
216
|
+
owner = cur;
|
|
217
|
+
conclusive = true;
|
|
218
|
+
break;
|
|
219
|
+
}
|
|
220
|
+
const next = cur.dominatorNode ?? null;
|
|
221
|
+
if (!next || next.id === cur.id) {
|
|
222
|
+
// The chain genuinely ends here: there is no owner above, and that is a
|
|
223
|
+
// property of the graph, not of this walk.
|
|
224
|
+
conclusive = true;
|
|
225
|
+
break;
|
|
226
|
+
}
|
|
227
|
+
cur = next;
|
|
228
|
+
hops++;
|
|
229
|
+
}
|
|
230
|
+
// Memoize ONLY a conclusive result. Caching a hop-cap or cycle-break exit
|
|
231
|
+
// would store "no owner" — a fact about this walk's 64-hop budget — as if it
|
|
232
|
+
// were a fact about the node. A later, deeper node whose own budget WOULD
|
|
233
|
+
// have reached a real owner then short-circuits on the poisoned entry and is
|
|
234
|
+
// reported as "no single owner", which is precisely the unsound ownership
|
|
235
|
+
// claim this grouping exists to eliminate.
|
|
236
|
+
if (conclusive) {
|
|
237
|
+
for (const id of chain)
|
|
238
|
+
cache.set(id, owner);
|
|
239
|
+
}
|
|
240
|
+
return owner;
|
|
241
|
+
};
|
|
242
|
+
}
|
|
64
243
|
export function registerDetachedDom(server) {
|
|
65
|
-
server.tool('memlab_detached_dom', 'Find detached DOM elements still retained in memory. These are common sources of memory leaks — DOM nodes removed from the document but kept alive by JavaScript references. Supports count-only and ids-only modes for large result sets. Use group_by to aggregate by element tag, retainer pattern, or data-testid. ' +
|
|
244
|
+
server.tool('memlab_detached_dom', 'Find detached DOM elements still retained in memory. These are common sources of memory leaks — DOM nodes removed from the document but kept alive by JavaScript references. Supports count-only and ids-only modes for large result sets. Use group_by to aggregate by dominator (accountable owner), element tag, retainer pattern, or data-testid. ' +
|
|
245
|
+
'Prefer group_by: "dominator" when you intend to act on the result: it groups by the nearest non-detached DOMINATOR, so releasing that one object provably frees the whole group. The other groupings key on a shortest retainer path, which need not dominate the nodes — they report an "Owners" column (distinct accountable dominators) so a group split across many owners is not mistaken for a single fix. ' +
|
|
246
|
+
'Reports a pinned-vs-GC-eligible split: detached nodes with a retainer path to a GC root are actual leaks, while nodes with no retainer path found are typically GC-eligible (transient / weak-only) and should be excluded from leak totals — set only_with_retainer_path to list/aggregate just the pinned ones. ' +
|
|
66
247
|
'⚠ Full-heap scan — slow on very large heaps (millions of nodes); use count-only / ids-only modes and group_by to bound output.', {
|
|
67
248
|
output_mode: z
|
|
68
249
|
.enum(['full', 'count', 'ids'])
|
|
@@ -70,9 +251,9 @@ export function registerDetachedDom(server) {
|
|
|
70
251
|
.default('full')
|
|
71
252
|
.describe('Output verbosity: "full" returns node summaries (default), "count" returns only the total count, "ids" returns only node IDs'),
|
|
72
253
|
group_by: z
|
|
73
|
-
.enum(['element', 'retainer', 'testid'])
|
|
254
|
+
.enum(['element', 'retainer', 'testid', 'dominator'])
|
|
74
255
|
.optional()
|
|
75
|
-
.describe('Group detached DOM nodes instead of listing individually. "element" groups by HTML tag (div, span, button)
|
|
256
|
+
.describe('Group detached DOM nodes instead of listing individually. "dominator" groups by the nearest non-detached dominator — the object that provably frees the whole group when released (use this to decide what to fix); "element" groups by HTML tag (div, span, button); "retainer" groups by first non-framework retainer on the shortest path (which need not dominate the nodes); "testid" groups by data-testid attribute.'),
|
|
76
257
|
offset: z
|
|
77
258
|
.number()
|
|
78
259
|
.optional()
|
|
@@ -87,8 +268,13 @@ export function registerDetachedDom(server) {
|
|
|
87
268
|
.boolean()
|
|
88
269
|
.optional()
|
|
89
270
|
.default(true)
|
|
90
|
-
.describe(
|
|
91
|
-
|
|
271
|
+
.describe('Report how much detached DOM is retained ONLY via dev/automation artifacts — dev/extension globals (__REACT_DEVTOOLS_GLOBAL_HOOK__, window.Debug, …) or the Blink a11y/CDP cache (AXObjectCacheImpl, which co-retains detached DOM under automation) — and so should be excluded from production leak totals (default true). Use memlab_dev_artifacts for the full breakdown.'),
|
|
272
|
+
only_with_retainer_path: z
|
|
273
|
+
.boolean()
|
|
274
|
+
.optional()
|
|
275
|
+
.default(false)
|
|
276
|
+
.describe('Only include detached nodes that have a retainer path to a GC root (i.e. actually pinned / leaked). When false (default) all detached nodes are included, but the summary always reports the pinned-vs-GC-eligible split so transient / weak-only detached DOM is not mistaken for a leak.'),
|
|
277
|
+
}, async ({ output_mode, group_by, offset, limit, classify_dev_only, only_with_retainer_path, }) => {
|
|
92
278
|
try {
|
|
93
279
|
const env = getSnapshotEnv();
|
|
94
280
|
if (env === 'node') {
|
|
@@ -101,19 +287,52 @@ export function registerDetachedDom(server) {
|
|
|
101
287
|
}
|
|
102
288
|
const snapshot = getSnapshot();
|
|
103
289
|
const devRoots = classify_dev_only ? collectDevRoots(snapshot) : null;
|
|
290
|
+
// Reachability pass (dev roots as sinks) so co-retention via multiple
|
|
291
|
+
// dev roots — e.g. detached DOM held by BOTH the DevTools console and
|
|
292
|
+
// the a11y cache — is correctly counted as a dev/automation artifact.
|
|
293
|
+
const reached = devRoots && devRoots.byId.size > 0
|
|
294
|
+
? computeReachableWithoutDevRoots(snapshot, devRoots)
|
|
295
|
+
: undefined;
|
|
104
296
|
if (group_by) {
|
|
105
297
|
const groups = new Map();
|
|
298
|
+
const resolveOwner = makeDominatorResolver();
|
|
106
299
|
let totalDetached = 0;
|
|
107
300
|
let totalRetainedAll = 0;
|
|
108
301
|
let devOnlyRetained = 0;
|
|
302
|
+
const split = emptySplit();
|
|
303
|
+
const browserContexts = findBrowserOwnedContexts(snapshot);
|
|
109
304
|
snapshot.nodes.forEach(node => {
|
|
110
305
|
if (!isDetachedDOMNode(node))
|
|
111
306
|
return;
|
|
112
307
|
totalDetached++;
|
|
113
308
|
totalRetainedAll += node.retainedSize;
|
|
114
|
-
|
|
309
|
+
const pinned = isPinned(node);
|
|
310
|
+
if (pinned) {
|
|
311
|
+
split.pinnedCount++;
|
|
312
|
+
split.pinnedRetained += node.retainedSize;
|
|
313
|
+
split.pinnedIds.push(node.id);
|
|
314
|
+
if (isBrowserOwned(node, browserContexts)) {
|
|
315
|
+
split.browserOwnedCount++;
|
|
316
|
+
split.browserOwnedIds.push(node.id);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
else {
|
|
320
|
+
split.noPathCount++;
|
|
321
|
+
split.noPathRetained += node.retainedSize;
|
|
322
|
+
}
|
|
323
|
+
const nodeIsDevOnly = devRoots
|
|
324
|
+
? classifyDevOnly(node, devRoots, reached).devOnly
|
|
325
|
+
: false;
|
|
326
|
+
if (nodeIsDevOnly) {
|
|
115
327
|
devOnlyRetained += node.retainedSize;
|
|
116
328
|
}
|
|
329
|
+
// With only_with_retainer_path, exclude GC-eligible (no-path) nodes
|
|
330
|
+
// from the group aggregation — they are still counted in the split.
|
|
331
|
+
if (only_with_retainer_path && !pinned)
|
|
332
|
+
return;
|
|
333
|
+
// Resolved for every grouping, not just 'dominator': the other keys
|
|
334
|
+
// need it to report how many distinct owners they span.
|
|
335
|
+
const owner = resolveOwner(node);
|
|
117
336
|
let key;
|
|
118
337
|
switch (group_by) {
|
|
119
338
|
case 'element':
|
|
@@ -125,11 +344,33 @@ export function registerDetachedDom(server) {
|
|
|
125
344
|
case 'testid':
|
|
126
345
|
key = extractTestId(node);
|
|
127
346
|
break;
|
|
347
|
+
case 'dominator':
|
|
348
|
+
// No owner = the dominator is the GC root itself, i.e. the node
|
|
349
|
+
// is reachable through two or more independent paths. Naming
|
|
350
|
+
// that outcome matters more than the others: it is precisely the
|
|
351
|
+
// case where "fix this retainer and X is freed" is false.
|
|
352
|
+
key = owner
|
|
353
|
+
? `@${owner.id} ${truncateNodeName(owner.name, owner.type, owner.self_size, 60)}`
|
|
354
|
+
: '(no single owner — dominated by the GC root, i.e. reachable via ≥2 independent paths)';
|
|
355
|
+
break;
|
|
128
356
|
}
|
|
129
357
|
const existing = groups.get(key);
|
|
130
358
|
if (existing) {
|
|
131
359
|
existing.count++;
|
|
132
360
|
existing.totalRetained += node.retainedSize;
|
|
361
|
+
if (nodeIsDevOnly)
|
|
362
|
+
existing.devOnlyCount++;
|
|
363
|
+
if (owner) {
|
|
364
|
+
if (existing.ownerIds.size < MAX_TRACKED_OWNERS) {
|
|
365
|
+
existing.ownerIds.add(owner.id);
|
|
366
|
+
}
|
|
367
|
+
else if (!existing.ownerIds.has(owner.id)) {
|
|
368
|
+
existing.ownersTruncated = true;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
else {
|
|
372
|
+
existing.ownerlessCount++;
|
|
373
|
+
}
|
|
133
374
|
if (node.retainedSize > existing.maxRetainedSize) {
|
|
134
375
|
existing.exampleId = node.id;
|
|
135
376
|
existing.maxRetainedSize = node.retainedSize;
|
|
@@ -141,10 +382,26 @@ export function registerDetachedDom(server) {
|
|
|
141
382
|
totalRetained: node.retainedSize,
|
|
142
383
|
exampleId: node.id,
|
|
143
384
|
maxRetainedSize: node.retainedSize,
|
|
385
|
+
devOnlyCount: nodeIsDevOnly ? 1 : 0,
|
|
386
|
+
ownerIds: new Set(owner ? [owner.id] : []),
|
|
387
|
+
ownersTruncated: false,
|
|
388
|
+
ownerlessCount: owner ? 0 : 1,
|
|
389
|
+
// The owner's own retained size, not the sum of the group's
|
|
390
|
+
// detached nodes: releasing it frees everything it dominates.
|
|
391
|
+
ownerRetained: owner ? owner.retainedSize : 0,
|
|
144
392
|
});
|
|
145
393
|
}
|
|
146
394
|
});
|
|
147
395
|
if (groups.size === 0) {
|
|
396
|
+
if (totalDetached > 0) {
|
|
397
|
+
return toolResult([
|
|
398
|
+
`Detached DOM grouped by ${group_by}: ${formatNumber(totalDetached)} total nodes, ${formatBytes(totalRetainedAll)} total retained`,
|
|
399
|
+
...formatReachabilitySplit(split, snapshot),
|
|
400
|
+
only_with_retainer_path
|
|
401
|
+
? '_No pinned (retainer-path) detached nodes — all detached DOM is GC-eligible / weak-only, not a leak._'
|
|
402
|
+
: '',
|
|
403
|
+
].join('\n'));
|
|
404
|
+
}
|
|
148
405
|
return toolResult('No detached DOM nodes found.');
|
|
149
406
|
}
|
|
150
407
|
const sorted = [...groups.entries()]
|
|
@@ -154,15 +411,36 @@ export function registerDetachedDom(server) {
|
|
|
154
411
|
? 'Element'
|
|
155
412
|
: group_by === 'retainer'
|
|
156
413
|
? 'Retainer'
|
|
157
|
-
: '
|
|
414
|
+
: group_by === 'dominator'
|
|
415
|
+
? 'Dominator (accountable owner)'
|
|
416
|
+
: 'data-testid';
|
|
417
|
+
// Per-group dev-only share. Without this the caller has to run
|
|
418
|
+
// dev_artifacts separately and mentally join the two outputs, which is
|
|
419
|
+
// exactly the step that gets skipped before a group is reported as a
|
|
420
|
+
// production leak.
|
|
421
|
+
const showDevOnly = devRoots != null &&
|
|
422
|
+
sorted.some(([, stats]) => stats.devOnlyCount > 0);
|
|
423
|
+
// In dominator mode the owner count is 1 by construction, so the
|
|
424
|
+
// interesting column is what that owner frees; for every other
|
|
425
|
+
// grouping it is how many owners the group is split across.
|
|
426
|
+
const isDominatorMode = group_by === 'dominator';
|
|
427
|
+
const ownerCountLabel = (stats) => {
|
|
428
|
+
const n = stats.ownerIds.size;
|
|
429
|
+
const shown = stats.ownersTruncated ? `${n}+` : String(n);
|
|
430
|
+
if (n === 0)
|
|
431
|
+
return stats.ownerlessCount > 0 ? 'none' : '-';
|
|
432
|
+
return stats.ownerlessCount > 0 ? `${shown} (+unowned)` : shown;
|
|
433
|
+
};
|
|
158
434
|
const headers = [
|
|
159
435
|
groupLabel,
|
|
160
436
|
'Count',
|
|
437
|
+
...(showDevOnly ? ['Dev-only'] : []),
|
|
161
438
|
'Total Retained',
|
|
162
439
|
'% of Detached',
|
|
440
|
+
...(isDominatorMode ? ['Owner Frees'] : ['Owners']),
|
|
163
441
|
'Example ID',
|
|
164
442
|
];
|
|
165
|
-
const rightCols = new Set([1, 2, 3]);
|
|
443
|
+
const rightCols = new Set(showDevOnly ? [1, 2, 3, 4, 5] : [1, 2, 3, 4]);
|
|
166
444
|
const rows = sorted.map(([key, stats]) => {
|
|
167
445
|
const pct = totalRetainedAll > 0
|
|
168
446
|
? ((stats.totalRetained / totalRetainedAll) * 100).toFixed(1) +
|
|
@@ -171,44 +449,112 @@ export function registerDetachedDom(server) {
|
|
|
171
449
|
return [
|
|
172
450
|
key.length > 60 ? key.slice(0, 57) + '...' : key,
|
|
173
451
|
formatNumber(stats.count),
|
|
452
|
+
...(showDevOnly
|
|
453
|
+
? [
|
|
454
|
+
stats.devOnlyCount === 0
|
|
455
|
+
? '—'
|
|
456
|
+
: stats.devOnlyCount === stats.count
|
|
457
|
+
? 'ALL'
|
|
458
|
+
: `${formatNumber(stats.devOnlyCount)}/${formatNumber(stats.count)}`,
|
|
459
|
+
]
|
|
460
|
+
: []),
|
|
174
461
|
formatBytes(stats.totalRetained),
|
|
175
462
|
pct,
|
|
463
|
+
isDominatorMode
|
|
464
|
+
? stats.ownerRetained > 0
|
|
465
|
+
? formatBytes(stats.ownerRetained)
|
|
466
|
+
: '-'
|
|
467
|
+
: ownerCountLabel(stats),
|
|
176
468
|
`@${stats.exampleId}`,
|
|
177
469
|
];
|
|
178
470
|
});
|
|
179
471
|
const lines = [
|
|
180
472
|
`Detached DOM grouped by ${group_by}: ${formatNumber(totalDetached)} total nodes, ${formatBytes(totalRetainedAll)} total retained`,
|
|
181
|
-
|
|
182
|
-
markdownTable(headers, rows, rightCols),
|
|
473
|
+
...formatReachabilitySplit(split, snapshot),
|
|
183
474
|
];
|
|
475
|
+
if (only_with_retainer_path) {
|
|
476
|
+
lines.push('_(groups below show pinned nodes only)_');
|
|
477
|
+
}
|
|
478
|
+
lines.push('', markdownTable(headers, rows, rightCols));
|
|
479
|
+
if (isDominatorMode) {
|
|
480
|
+
const ownerless = sorted.find(([, s]) => s.ownerIds.size === 0 && s.ownerlessCount > 0);
|
|
481
|
+
lines.push('', "_Grouped by the nearest non-detached **dominator**: releasing that object frees every detached node in its row. **Owner Frees** is the owner's own retained size — the true, non-overlapping figure, and the amount actually reclaimed (it also covers whatever else the owner holds). Total Retained is a plain sum over the group, so it double-counts nested detached subtrees and can exceed Owner Frees._");
|
|
482
|
+
if (ownerless) {
|
|
483
|
+
lines.push(`_⚠ ${formatNumber(ownerless[1].count)} node(s) (${formatBytes(ownerless[1].totalRetained)}) have **no single owner** — their dominator is the GC root, so they are reachable through two or more independent paths and no one object frees them. Use \`memlab_retainer_summary\` / \`memlab_get_referrers\` to enumerate every path; all of them must be cut._`);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
else {
|
|
487
|
+
const notSingleOwner = sorted.filter(([, s]) => s.ownerIds.size === 0 ||
|
|
488
|
+
s.ownerIds.size + (s.ownerlessCount > 0 ? 1 : 0) > 1).length;
|
|
489
|
+
lines.push('', `_**Owners** = distinct accountable dominators the group spans (\`none\` = dominated by the GC root, i.e. reachable via ≥2 independent paths). This grouping keys on ${group_by === 'retainer' ? 'the first non-framework retainer along the SHORTEST retainer path, which need not dominate the nodes' : `the node's ${group_by}`}, so only a group with **Owners = 1** is freed by fixing one object.${notSingleOwner > 0 ? ` ${formatNumber(notSingleOwner)} of the ${formatNumber(sorted.length)} groups below are not single-owner — for those, "fixing this frees X" is wrong; re-run with \`group_by: "dominator"\` to see what actually frees them.` : ''}_`);
|
|
490
|
+
}
|
|
184
491
|
if (devRoots && devRoots.byId.size > 0 && devOnlyRetained > 0) {
|
|
185
492
|
const pct = totalRetainedAll > 0
|
|
186
493
|
? ((devOnlyRetained / totalRetainedAll) * 100).toFixed(0)
|
|
187
494
|
: '0';
|
|
188
|
-
lines.push('', `⚠ **${formatBytes(devOnlyRetained)} (${pct}%) of this detached DOM is retained ONLY via dev/
|
|
495
|
+
lines.push('', `⚠ **${formatBytes(devOnlyRetained)} (${pct}%) of this detached DOM is retained ONLY via dev/automation artifacts** (${summarizeDevRoots(devRoots)}) — dev-global retention would be GC'd in production, and a11y/CDP-cache retention is automation-inflated (not present at that scale in a normal session). Exclude it from leak totals; run \`memlab_dev_artifacts\` for the breakdown.`);
|
|
189
496
|
}
|
|
190
497
|
if (sorted.length > 0) {
|
|
191
|
-
|
|
498
|
+
// In dominator mode point at the largest row that HAS an owner —
|
|
499
|
+
// the ownerless bucket can top the table, and "run dominator_chain
|
|
500
|
+
// on it" is meaningless there (it is already at the root).
|
|
501
|
+
const topOwned = isDominatorMode
|
|
502
|
+
? sorted.find(([, s]) => s.ownerIds.size > 0)
|
|
503
|
+
: undefined;
|
|
504
|
+
lines.push('', isDominatorMode
|
|
505
|
+
? topOwned
|
|
506
|
+
? `**Suggested action:** Run \`memlab_dominator_chain\` on the largest owned group's owner to find the accountable application object, then \`memlab_retainer_summary\` on its example (\`@${topOwned[1].exampleId}\`) for the reference that holds it.`
|
|
507
|
+
: '**Suggested action:** No group has a single owner — every detached node here is reachable via multiple independent paths. Use `memlab_retainer_summary` on an example to enumerate the paths; each one must be cut.'
|
|
508
|
+
: `**Suggested action:** Use \`memlab_retainer_summary\` with node_ids from the top group's example to trace the common retention pattern. Before acting on a group, confirm its **Owners** is 1 — or re-run with \`group_by: "dominator"\`, which groups by what a fix actually frees.`);
|
|
192
509
|
}
|
|
193
510
|
return toolResult(lines.join('\n'));
|
|
194
511
|
}
|
|
512
|
+
const split = emptySplit();
|
|
513
|
+
const browserContexts2 = findBrowserOwnedContexts(snapshot);
|
|
514
|
+
snapshot.nodes.forEach(node => {
|
|
515
|
+
if (!isDetachedDOMNode(node))
|
|
516
|
+
return;
|
|
517
|
+
if (isPinned(node)) {
|
|
518
|
+
split.pinnedCount++;
|
|
519
|
+
split.pinnedRetained += node.retainedSize;
|
|
520
|
+
split.pinnedIds.push(node.id);
|
|
521
|
+
if (isBrowserOwned(node, browserContexts2)) {
|
|
522
|
+
split.browserOwnedCount++;
|
|
523
|
+
split.browserOwnedIds.push(node.id);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
else {
|
|
527
|
+
split.noPathCount++;
|
|
528
|
+
split.noPathRetained += node.retainedSize;
|
|
529
|
+
}
|
|
530
|
+
});
|
|
531
|
+
const predicate = only_with_retainer_path
|
|
532
|
+
? (n) => isDetachedDOMNode(n) && isPinned(n)
|
|
533
|
+
: isDetachedDOMNode;
|
|
195
534
|
const effectiveLimit = output_mode === 'ids' ? Math.min(limit, 10000) : Math.min(limit, 500);
|
|
196
|
-
const result = queryNodes(snapshot,
|
|
535
|
+
const result = queryNodes(snapshot, predicate, {
|
|
197
536
|
limit: effectiveLimit,
|
|
198
537
|
offset,
|
|
199
538
|
outputMode: output_mode,
|
|
200
539
|
});
|
|
201
|
-
const
|
|
540
|
+
const splitBlock = output_mode === 'ids'
|
|
541
|
+
? ''
|
|
542
|
+
: formatReachabilitySplit(split, snapshot).join('\n') + '\n\n';
|
|
543
|
+
const output = splitBlock + formatQueryNodesResult(result, offset);
|
|
202
544
|
if (result.total_count > 0 && output_mode === 'full') {
|
|
203
545
|
const devNote = devRoots && devRoots.byId.size > 0
|
|
204
|
-
? ` Dev/extension globals (${
|
|
546
|
+
? ` Dev/extension globals (${summarizeDevRoots(devRoots)}) are present — run \`memlab_dev_artifacts\` to exclude DevTools-only retention from leak totals.`
|
|
547
|
+
: '';
|
|
548
|
+
const pinnedNote = split.noPathCount > 0
|
|
549
|
+
? ` ${formatNumber(split.noPathCount)} detached node(s) have no retainer path (likely GC-eligible / weak-only) — pass only_with_retainer_path to focus on the ${formatNumber(split.pinnedCount)} pinned one(s).`
|
|
205
550
|
: '';
|
|
206
551
|
return toolResult(output +
|
|
207
552
|
'\n\n---\n\n' +
|
|
208
553
|
'**Suggested action:** Check for missing `removeEventListener` calls, ' +
|
|
209
554
|
'React component cleanup in `useEffect` return, or refs not cleared on unmount. ' +
|
|
210
555
|
'Use `memlab_retainer_trace` on top entries to find the retention path. ' +
|
|
211
|
-
'Use `group_by: "
|
|
556
|
+
'Use `group_by: "dominator"` to see which objects are accountable for the most detached DOM (releasing one frees its whole group), or `group_by: "retainer"` for the shortest-path view.' +
|
|
557
|
+
pinnedNote +
|
|
212
558
|
devNote);
|
|
213
559
|
}
|
|
214
560
|
return toolResult(output);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detached-dom.js","sourceRoot":"","sources":["../../src/tools/detached-dom.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"detached-dom.js","sourceRoot":"","sources":["../../src/tools/detached-dom.ts"],"names":[],"mappings":"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"}
|