opera-devtools-mcp 0.2.4 → 0.4.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.
Files changed (330) hide show
  1. package/README.md +108 -8
  2. package/build/src/McpContext.js +365 -365
  3. package/build/src/McpPage.js +475 -48
  4. package/build/src/McpResponse.js +462 -288
  5. package/build/src/SlimMcpResponse.js +1 -1
  6. package/build/src/TextSnapshot.js +101 -22
  7. package/build/src/ToolHandler.js +142 -20
  8. package/build/src/bin/check-latest-version.js +27 -1
  9. package/build/src/bin/chrome-devtools-cli-options.js +614 -10
  10. package/build/src/bin/chrome-devtools-mcp-cli-options.js +119 -32
  11. package/build/src/bin/chrome-devtools-mcp-main.js +50 -7
  12. package/build/src/bin/chrome-devtools-mcp.js +7 -4
  13. package/build/src/bin/chrome-devtools.js +57 -14
  14. package/build/src/bin/opera-devtools-cli-options.js +3 -829
  15. package/build/src/bin/opera-devtools-mcp-cli-options.js +3 -348
  16. package/build/src/bin/opera-devtools-mcp-main.js +3 -37
  17. package/build/src/bin/opera-devtools-mcp.js +4 -19
  18. package/build/src/bin/opera-devtools.js +4 -185
  19. package/build/src/browser.js +45 -5
  20. package/build/src/{PageCollector.js → collectors/PageCollector.js} +64 -133
  21. package/build/src/collectors/ServiceWorkerCollector.js +171 -0
  22. package/build/src/daemon/client.js +75 -17
  23. package/build/src/daemon/daemon.js +92 -30
  24. package/build/src/daemon/utils.js +24 -8
  25. package/build/src/{DevtoolsUtils.js → devtools/DevtoolsUtils.js} +94 -88
  26. package/build/src/devtools/McpHostBindingAdapter.js +165 -0
  27. package/build/src/{issue-descriptions.js → devtools/issueDescriptions.js} +8 -6
  28. package/build/src/formatters/ConsoleFormatter.js +44 -11
  29. package/build/src/formatters/HeapSnapshotFormatter.js +140 -9
  30. package/build/src/formatters/IssueFormatter.js +7 -7
  31. package/build/src/formatters/NetworkFormatter.js +10 -8
  32. package/build/src/index.js +101 -232
  33. package/build/src/opera/branding.js +34 -0
  34. package/build/src/opera/browserFlags.js +85 -0
  35. package/build/src/opera/browserLaunch.js +52 -0
  36. package/build/src/opera/policy.js +50 -0
  37. package/build/src/opera/serviceWorkerRetry.js +37 -0
  38. package/build/src/opera/toolHandlerHooks.js +39 -0
  39. package/build/src/{tools → opera/tools}/opera.js +116 -21
  40. package/build/src/processors/HeapSnapshotManager.js +258 -0
  41. package/build/src/{trace-processing/parse.js → processors/PerformanceTrace.js} +9 -9
  42. package/build/src/telemetry/ClearcutLogger.js +12 -119
  43. package/build/src/telemetry/WatchdogClient.js +5 -5
  44. package/build/src/telemetry/errors.js +1 -1
  45. package/build/src/telemetry/flagUtils.js +6 -6
  46. package/build/src/telemetry/{toolMetricsUtils.js → metricsRegistry.js} +4 -11
  47. package/build/src/telemetry/persistence.js +3 -3
  48. package/build/src/telemetry/transformation.js +193 -0
  49. package/build/src/telemetry/watchdog/ClearcutSender.js +11 -11
  50. package/build/src/telemetry/watchdog/main.js +6 -6
  51. package/build/src/third_party/THIRD_PARTY_NOTICES +232 -1061
  52. package/build/src/third_party/bundled-packages.json +7 -8
  53. package/build/src/third_party/devtools-formatter-worker.js +63 -22
  54. package/build/src/third_party/devtools-heap-snapshot-worker.js +809 -182
  55. package/build/src/third_party/index.js +69558 -74691
  56. package/build/src/third_party/issue-descriptions/CoepCorpNotSameOrigin.md +2 -2
  57. package/build/src/third_party/issue-descriptions/CoepCorpNotSameOriginAfterDefaultedToSameOriginByCoep.md +3 -3
  58. package/build/src/third_party/issue-descriptions/CoepCorpNotSameSite.md +2 -2
  59. package/build/src/third_party/issue-descriptions/CoepFrameResourceNeedsCoepHeader.md +1 -1
  60. package/build/src/third_party/issue-descriptions/CompatibilityModeQuirks.md +1 -1
  61. package/build/src/third_party/issue-descriptions/CookieAttributeValueExceedsMaxSize.md +2 -2
  62. package/build/src/third_party/issue-descriptions/LowTextContrast.md +1 -1
  63. package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureErrorRead.md +1 -1
  64. package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureErrorSet.md +1 -1
  65. package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureWarnRead.md +1 -1
  66. package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureWarnSet.md +1 -1
  67. package/build/src/third_party/issue-descriptions/SameSiteUnspecifiedLaxAllowUnsafeRead.md +3 -3
  68. package/build/src/third_party/issue-descriptions/SameSiteUnspecifiedLaxAllowUnsafeSet.md +3 -3
  69. package/build/src/third_party/issue-descriptions/bounceTrackingMitigations.md +1 -1
  70. package/build/src/third_party/issue-descriptions/connectionAllowlistEmbeddingRequirementNotSatisfied.md +26 -0
  71. package/build/src/third_party/issue-descriptions/connectionAllowlistIFrameAttributeLoosensEmbeddingRequirement.md +19 -0
  72. package/build/src/third_party/issue-descriptions/connectionAllowlistInvalidAllowConnectionAllowlistFrom.md +21 -0
  73. package/build/src/third_party/issue-descriptions/connectionAllowlistInvalidAllowlistItemType.md +2 -2
  74. package/build/src/third_party/issue-descriptions/connectionAllowlistInvalidHeader.md +2 -2
  75. package/build/src/third_party/issue-descriptions/connectionAllowlistInvalidUrlPattern.md +3 -3
  76. package/build/src/third_party/issue-descriptions/connectionAllowlistItemNotInnerList.md +2 -2
  77. package/build/src/third_party/issue-descriptions/connectionAllowlistMoreThanOneList.md +2 -2
  78. package/build/src/third_party/issue-descriptions/connectionAllowlistReportingEndpointNotToken.md +1 -1
  79. package/build/src/third_party/issue-descriptions/cookieCrossSiteRedirectDowngrade.md +3 -3
  80. package/build/src/third_party/issue-descriptions/cookieExcludeBlockedWithinRelatedWebsiteSet.md +1 -1
  81. package/build/src/third_party/issue-descriptions/cookieExcludePortMismatch.md +1 -1
  82. package/build/src/third_party/issue-descriptions/cookieExcludeSchemeMismatch.md +1 -1
  83. package/build/src/third_party/issue-descriptions/cookieExcludeThirdPartyPhaseoutSet.md +1 -1
  84. package/build/src/third_party/issue-descriptions/cookieWarnThirdPartyPhaseoutRead.md +1 -1
  85. package/build/src/third_party/issue-descriptions/corsAllowCredentialsRequired.md +1 -1
  86. package/build/src/third_party/issue-descriptions/corsDisabledScheme.md +2 -2
  87. package/build/src/third_party/issue-descriptions/corsDisallowedByMode.md +2 -2
  88. package/build/src/third_party/issue-descriptions/corsHeaderDisallowedByPreflightResponse.md +1 -1
  89. package/build/src/third_party/issue-descriptions/corsInvalidHeaderValues.md +3 -3
  90. package/build/src/third_party/issue-descriptions/corsLocalNetworkAccessPermissionDenied.md +1 -1
  91. package/build/src/third_party/issue-descriptions/corsMethodDisallowedByPreflightResponse.md +1 -1
  92. package/build/src/third_party/issue-descriptions/corsNoCorsRedirectModeNotFollow.md +1 -1
  93. package/build/src/third_party/issue-descriptions/corsOriginMismatch.md +3 -3
  94. package/build/src/third_party/issue-descriptions/corsPreflightResponseInvalid.md +2 -2
  95. package/build/src/third_party/issue-descriptions/corsRedirectContainsCredentials.md +3 -3
  96. package/build/src/third_party/issue-descriptions/corsWildcardOriginNotAllowed.md +4 -3
  97. package/build/src/third_party/issue-descriptions/cspEvalViolation.md +4 -4
  98. package/build/src/third_party/issue-descriptions/cspInlineViolation.md +2 -2
  99. package/build/src/third_party/issue-descriptions/cspTrustedTypesPolicyViolation.md +2 -2
  100. package/build/src/third_party/issue-descriptions/cspTrustedTypesSinkViolation.md +4 -4
  101. package/build/src/third_party/issue-descriptions/cspURLViolation.md +4 -4
  102. package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsEmptyList.md +1 -0
  103. package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsHttpNotFound.md +1 -0
  104. package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsInvalidContentType.md +1 -0
  105. package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsInvalidResponse.md +1 -0
  106. package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsNoResponse.md +1 -0
  107. package/build/src/third_party/issue-descriptions/emailVerificationRequestDnsFetchFailed.md +1 -0
  108. package/build/src/third_party/issue-descriptions/emailVerificationRequestDnsInvalidRecord.md +1 -0
  109. package/build/src/third_party/issue-descriptions/emailVerificationRequestEmailVerificationWellKnownHttpNotFound.md +1 -0
  110. package/build/src/third_party/issue-descriptions/emailVerificationRequestEmailVerificationWellKnownInvalidContentType.md +1 -0
  111. package/build/src/third_party/issue-descriptions/emailVerificationRequestEmailVerificationWellKnownInvalidResponse.md +1 -0
  112. package/build/src/third_party/issue-descriptions/emailVerificationRequestEmailVerificationWellKnownNoResponse.md +1 -0
  113. package/build/src/third_party/issue-descriptions/emailVerificationRequestInvalidEmail.md +1 -0
  114. package/build/src/third_party/issue-descriptions/emailVerificationRequestJwksHttpNotFound.md +1 -0
  115. package/build/src/third_party/issue-descriptions/emailVerificationRequestJwksInvalidResponse.md +1 -0
  116. package/build/src/third_party/issue-descriptions/emailVerificationRequestKeyBindingSigningFailed.md +1 -0
  117. package/build/src/third_party/issue-descriptions/emailVerificationRequestRpOriginIsOpaque.md +1 -0
  118. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenHttpNotFound.md +1 -0
  119. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenInvalidContentType.md +1 -0
  120. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenInvalidResponse.md +1 -0
  121. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenInvalidSdJwt.md +1 -0
  122. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenMalformedSdJwt.md +1 -0
  123. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenNoResponse.md +1 -0
  124. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidAudience.md +1 -0
  125. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidIssuedAt.md +1 -0
  126. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidNonce.md +1 -0
  127. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidSdHash.md +1 -0
  128. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidTyp.md +1 -0
  129. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingAud.md +1 -0
  130. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingCnf.md +1 -0
  131. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingIat.md +1 -0
  132. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingNonce.md +1 -0
  133. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingSdHash.md +1 -0
  134. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbSignatureFailed.md +1 -0
  135. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidEmail.md +1 -0
  136. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidEmailVerified.md +1 -0
  137. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidHolderKey.md +1 -0
  138. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidIssuedAt.md +1 -0
  139. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidIssuer.md +1 -0
  140. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtJwksMissingKeys.md +1 -0
  141. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtMissingCnf.md +1 -0
  142. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtMissingEmail.md +1 -0
  143. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtMissingIat.md +1 -0
  144. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtMissingIss.md +1 -0
  145. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtSignatureFailed.md +1 -0
  146. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtUnsupportedHeaderAlg.md +1 -0
  147. package/build/src/third_party/issue-descriptions/emailVerificationRequestUserLoggedOut.md +1 -0
  148. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownAccountsEndpointCrossOrigin.md +1 -0
  149. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownHttpNotFound.md +1 -0
  150. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownInvalidContentType.md +1 -0
  151. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownInvalidResponse.md +1 -0
  152. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownIssuanceEndpointCrossOrigin.md +1 -0
  153. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownListEmpty.md +1 -0
  154. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownMissingAccountsEndpoint.md +1 -0
  155. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownMissingIssuanceEndpoint.md +1 -0
  156. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownNoResponse.md +1 -0
  157. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownUnsupportedSigningAlgorithm.md +1 -0
  158. package/build/src/third_party/issue-descriptions/federatedAuthRequestAccountsHttpNotFound.md +1 -1
  159. package/build/src/third_party/issue-descriptions/federatedAuthRequestAccountsInvalidResponse.md +1 -1
  160. package/build/src/third_party/issue-descriptions/federatedAuthRequestAccountsNoResponse.md +1 -1
  161. package/build/src/third_party/issue-descriptions/federatedAuthRequestApprovalDeclined.md +1 -1
  162. package/build/src/third_party/issue-descriptions/federatedAuthRequestCanceled.md +1 -1
  163. package/build/src/third_party/issue-descriptions/federatedAuthRequestErrorFetchingSignin.md +1 -1
  164. package/build/src/third_party/issue-descriptions/federatedAuthRequestErrorIdToken.md +1 -1
  165. package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenHttpNotFound.md +1 -1
  166. package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenInvalidRequest.md +1 -1
  167. package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenInvalidResponse.md +1 -1
  168. package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenNoResponse.md +1 -1
  169. package/build/src/third_party/issue-descriptions/federatedAuthRequestInvalidSigninResponse.md +1 -1
  170. package/build/src/third_party/issue-descriptions/federatedAuthRequestManifestHttpNotFound.md +1 -1
  171. package/build/src/third_party/issue-descriptions/federatedAuthRequestManifestInvalidResponse.md +1 -1
  172. package/build/src/third_party/issue-descriptions/federatedAuthRequestManifestNoResponse.md +1 -1
  173. package/build/src/third_party/issue-descriptions/federatedAuthRequestTooManyRequests.md +1 -1
  174. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestInvalidAccountsResponse.md +1 -1
  175. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestInvalidConfigOrWellKnown.md +1 -1
  176. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNoAccountSharingPermission.md +1 -1
  177. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNoApiPermission.md +1 -1
  178. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNoReturningUserFromFetchedAccounts.md +1 -1
  179. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotIframe.md +1 -1
  180. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotPotentiallyTrustworthy.md +1 -1
  181. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotSameOrigin.md +1 -1
  182. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotSignedInWithIdp.md +1 -1
  183. package/build/src/third_party/issue-descriptions/fetchingPartitionedBlobURL.md +2 -2
  184. package/build/src/third_party/issue-descriptions/genericBackUINavigationWouldSkipAd.md +4 -0
  185. package/build/src/third_party/issue-descriptions/genericFormAriaLabelledByToNonExistingIdError.md +2 -2
  186. package/build/src/third_party/issue-descriptions/genericFormAutocompleteAttributeEmptyError.md +1 -1
  187. package/build/src/third_party/issue-descriptions/genericFormDuplicateIdForInputError.md +1 -1
  188. package/build/src/third_party/issue-descriptions/genericFormEmptyIdAndNameAttributesForInputError.md +2 -2
  189. package/build/src/third_party/issue-descriptions/genericFormInputAssignedAutocompleteValueToIdOrNameAttributeError.md +2 -2
  190. package/build/src/third_party/issue-descriptions/genericFormInputHasWrongButWellIntendedAutocompleteValueError.md +1 -1
  191. package/build/src/third_party/issue-descriptions/genericFormInputWithNoLabelError.md +1 -1
  192. package/build/src/third_party/issue-descriptions/genericFormLabelForMatchesNonExistingIdError.md +2 -2
  193. package/build/src/third_party/issue-descriptions/genericFormLabelForNameError.md +1 -1
  194. package/build/src/third_party/issue-descriptions/genericFormLabelHasNeitherForNorNestedInputError.md +1 -1
  195. package/build/src/third_party/issue-descriptions/genericFormModelContextMissingToolName.md +1 -1
  196. package/build/src/third_party/issue-descriptions/genericFormModelContextParameterMissingName.md +1 -1
  197. package/build/src/third_party/issue-descriptions/genericFormModelContextRequiredParameterMissingName.md +1 -1
  198. package/build/src/third_party/issue-descriptions/genericNavigationEntryMarkedSkippable.md +2 -2
  199. package/build/src/third_party/issue-descriptions/heavyAd.md +1 -1
  200. package/build/src/third_party/issue-descriptions/lazyLoadImageZeroSize.md +7 -0
  201. package/build/src/third_party/issue-descriptions/navigatingPartitionedBlobURL.md +3 -3
  202. package/build/src/third_party/issue-descriptions/permissionElementActivationDisabled.md +1 -1
  203. package/build/src/third_party/issue-descriptions/permissionElementActivationDisabledWithOccluder.md +1 -1
  204. package/build/src/third_party/issue-descriptions/permissionElementActivationDisabledWithOccluderParent.md +1 -1
  205. package/build/src/third_party/issue-descriptions/permissionElementFencedFrameDisallowed.md +2 -2
  206. package/build/src/third_party/issue-descriptions/permissionElementFontSizeTooLarge.md +2 -2
  207. package/build/src/third_party/issue-descriptions/permissionElementFontSizeTooSmall.md +2 -2
  208. package/build/src/third_party/issue-descriptions/permissionElementInsetBoxShadowUnsupported.md +1 -1
  209. package/build/src/third_party/issue-descriptions/permissionElementInvalidDisplayStyle.md +2 -2
  210. package/build/src/third_party/issue-descriptions/permissionElementInvalidSizeValue.md +2 -2
  211. package/build/src/third_party/issue-descriptions/permissionElementInvalidType.md +2 -2
  212. package/build/src/third_party/issue-descriptions/permissionElementInvalidTypeActivation.md +2 -2
  213. package/build/src/third_party/issue-descriptions/permissionElementNonOpaqueColor.md +1 -1
  214. package/build/src/third_party/issue-descriptions/permissionElementPaddingBottomUnsupported.md +2 -2
  215. package/build/src/third_party/issue-descriptions/permissionElementPaddingRightUnsupported.md +2 -2
  216. package/build/src/third_party/issue-descriptions/permissionElementRequestInProgress.md +2 -2
  217. package/build/src/third_party/issue-descriptions/permissionElementSecurityChecksFailed.md +1 -1
  218. package/build/src/third_party/issue-descriptions/permissionElementTypeNotSupported.md +2 -2
  219. package/build/src/third_party/issue-descriptions/permissionElementUntrustedEvent.md +1 -1
  220. package/build/src/third_party/issue-descriptions/placeholderDescriptionForInvisibleIssues.md +1 -1
  221. package/build/src/third_party/issue-descriptions/selectElementAccessibilityDisallowedOptGroupChild.md +1 -1
  222. package/build/src/third_party/issue-descriptions/selectElementAccessibilityDisallowedSelectChild.md +1 -1
  223. package/build/src/third_party/issue-descriptions/selectElementAccessibilityInteractiveContentAttributesSelectDescendant.md +1 -1
  224. package/build/src/third_party/issue-descriptions/selectElementAccessibilityInteractiveContentLegendChild.md +1 -1
  225. package/build/src/third_party/issue-descriptions/selectElementAccessibilityInteractiveContentOptionChild.md +1 -1
  226. package/build/src/third_party/issue-descriptions/selectElementAccessibilityNonPhrasingContentOptionChild.md +1 -1
  227. package/build/src/third_party/issue-descriptions/selectivePermissionsIntervention.md +3 -3
  228. package/build/src/third_party/issue-descriptions/sharedArrayBuffer.md +1 -1
  229. package/build/src/third_party/issue-descriptions/sharedDictionaryUseErrorCrossOriginNoCorsRequest.md +1 -1
  230. package/build/src/third_party/issue-descriptions/sharedDictionaryUseErrorMatchingDictionaryNotUsed.md +1 -1
  231. package/build/src/third_party/issue-descriptions/sharedDictionaryUseErrorUnexpectedContentDictionaryHeader.md +1 -1
  232. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorCossOriginNoCorsRequest.md +1 -1
  233. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorDisallowedBySettings.md +1 -1
  234. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorExpiredResponse.md +1 -1
  235. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorFeatureDisabled.md +2 -2
  236. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorInvalidStructuredHeader.md +1 -1
  237. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNavigationRequest.md +2 -2
  238. package/build/src/third_party/issue-descriptions/sriInvalidSignatureHeader.md +4 -4
  239. package/build/src/third_party/issue-descriptions/sriInvalidSignatureInputHeader.md +4 -4
  240. package/build/src/third_party/issue-descriptions/sriMissingSignatureHeader.md +1 -1
  241. package/build/src/third_party/issue-descriptions/sriMissingSignatureInputHeader.md +2 -2
  242. package/build/src/third_party/issue-descriptions/sriSignatureHeaderValueIsIncorrectLength.md +2 -2
  243. package/build/src/third_party/issue-descriptions/sriSignatureHeaderValueIsNotByteSequence.md +4 -4
  244. package/build/src/third_party/issue-descriptions/sriSignatureHeaderValueIsParameterized.md +4 -4
  245. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidComponentName.md +1 -1
  246. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidComponentType.md +2 -2
  247. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidDerivedComponentParameter.md +1 -1
  248. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidHeaderComponentParameter.md +1 -1
  249. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidParameter.md +2 -2
  250. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderKeyIdLength.md +5 -5
  251. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderMissingLabel.md +3 -3
  252. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderMissingRequiredParameters.md +2 -2
  253. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderValueMissingComponents.md +2 -2
  254. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderValueNotInnerList.md +2 -2
  255. package/build/src/third_party/issue-descriptions/sriValidationFailedIntegrityMismatch.md +4 -4
  256. package/build/src/third_party/issue-descriptions/sriValidationFailedInvalidLength.md +3 -3
  257. package/build/src/third_party/issue-descriptions/sriValidationFailedSignatureExpired.md +2 -2
  258. package/build/src/third_party/issue-descriptions/sriValidationFailedSignatureMismatch.md +2 -2
  259. package/build/src/third_party/issue-descriptions/stylesheetLateImport.md +1 -1
  260. package/build/src/third_party/issue-descriptions/summaryElementAccessibilityInteractiveContentSummaryDescendant.md +1 -1
  261. package/build/src/third_party/issue-descriptions/unencodedDigestIncorrectDigestLength.md +2 -2
  262. package/build/src/third_party/issue-descriptions/unencodedDigestIncorrectDigestType.md +3 -3
  263. package/build/src/third_party/issue-descriptions/unencodedDigestMalformedDictionary.md +2 -2
  264. package/build/src/third_party/issue-descriptions/unencodedDigestUnknownAlgorithm.md +1 -1
  265. package/build/src/third_party/lighthouse-devtools-mcp-bundle.js +3177 -6340
  266. package/build/src/tools/ToolDefinition.js +2 -2
  267. package/build/src/tools/categories.js +3 -0
  268. package/build/src/tools/console.js +13 -0
  269. package/build/src/tools/emulation.js +30 -3
  270. package/build/src/tools/extensions.js +8 -1
  271. package/build/src/tools/input.js +246 -128
  272. package/build/src/tools/lighthouse.js +14 -7
  273. package/build/src/tools/memory.js +289 -25
  274. package/build/src/tools/network.js +10 -7
  275. package/build/src/tools/pages.js +33 -92
  276. package/build/src/tools/performance.js +67 -52
  277. package/build/src/tools/pwa.js +128 -0
  278. package/build/src/tools/screencast.js +35 -12
  279. package/build/src/tools/screenshot.js +234 -75
  280. package/build/src/tools/script.js +130 -45
  281. package/build/src/tools/slim/tools.js +3 -0
  282. package/build/src/tools/snapshot.js +7 -4
  283. package/build/src/tools/thirdPartyDeveloper.js +19 -9
  284. package/build/src/tools/tools.js +3 -1
  285. package/build/src/tools/webmcp.js +3 -1
  286. package/build/src/utils/WaitForHelper.js +299 -0
  287. package/build/src/utils/check-for-updates.js +8 -2
  288. package/build/src/utils/files.js +42 -3
  289. package/build/src/utils/logger.js +51 -0
  290. package/build/src/utils/polyfill.js +11 -0
  291. package/build/src/utils/url.js +43 -0
  292. package/build/src/version.js +1 -4
  293. package/package.json +43 -33
  294. package/build/src/DevToolsConnectionAdapter.js +0 -70
  295. package/build/src/HeapSnapshotManager.js +0 -110
  296. package/build/src/Mutex.js +0 -38
  297. package/build/src/WaitForHelper.js +0 -195
  298. package/build/src/bin/cliDefinitions.js +0 -616
  299. package/build/src/logger.js +0 -37
  300. package/build/src/polyfill.js +0 -8
  301. package/build/src/telemetry/metricUtils.js +0 -15
  302. package/build/src/third_party/issue-descriptions/SameSiteExcludeContextDowngradeRead.md +0 -8
  303. package/build/src/third_party/issue-descriptions/SameSiteExcludeContextDowngradeSet.md +0 -8
  304. package/build/src/third_party/issue-descriptions/SameSiteExcludeNavigationContextDowngrade.md +0 -8
  305. package/build/src/third_party/issue-descriptions/SameSiteWarnCrossDowngradeRead.md +0 -8
  306. package/build/src/third_party/issue-descriptions/SameSiteWarnCrossDowngradeSet.md +0 -8
  307. package/build/src/third_party/issue-descriptions/SameSiteWarnStrictLaxDowngradeStrict.md +0 -8
  308. package/build/src/third_party/issue-descriptions/arInsecureContext.md +0 -7
  309. package/build/src/third_party/issue-descriptions/arInvalidInfoHeader.md +0 -5
  310. package/build/src/third_party/issue-descriptions/arInvalidRegisterOsSourceHeader.md +0 -5
  311. package/build/src/third_party/issue-descriptions/arInvalidRegisterOsTriggerHeader.md +0 -5
  312. package/build/src/third_party/issue-descriptions/arInvalidRegisterSourceHeader.md +0 -5
  313. package/build/src/third_party/issue-descriptions/arInvalidRegisterTriggerHeader.md +0 -5
  314. package/build/src/third_party/issue-descriptions/arNavigationRegistrationUniqueScopeAlreadySet.md +0 -5
  315. package/build/src/third_party/issue-descriptions/arNavigationRegistrationWithoutTransientUserActivation.md +0 -6
  316. package/build/src/third_party/issue-descriptions/arNoRegisterOsSourceHeader.md +0 -5
  317. package/build/src/third_party/issue-descriptions/arNoRegisterOsTriggerHeader.md +0 -5
  318. package/build/src/third_party/issue-descriptions/arNoRegisterSourceHeader.md +0 -5
  319. package/build/src/third_party/issue-descriptions/arNoRegisterTriggerHeader.md +0 -5
  320. package/build/src/third_party/issue-descriptions/arNoWebOrOsSupport.md +0 -4
  321. package/build/src/third_party/issue-descriptions/arOsSourceIgnored.md +0 -18
  322. package/build/src/third_party/issue-descriptions/arOsTriggerIgnored.md +0 -19
  323. package/build/src/third_party/issue-descriptions/arPermissionPolicyDisabled.md +0 -8
  324. package/build/src/third_party/issue-descriptions/arSourceAndTriggerHeaders.md +0 -9
  325. package/build/src/third_party/issue-descriptions/arSourceIgnored.md +0 -13
  326. package/build/src/third_party/issue-descriptions/arTriggerIgnored.md +0 -12
  327. package/build/src/third_party/issue-descriptions/arUntrustworthyReportingOrigin.md +0 -10
  328. package/build/src/third_party/issue-descriptions/arWebAndOsHeaders.md +0 -11
  329. package/build/src/utils/string.js +0 -37
  330. package/build/src/utils/types.js +0 -7
@@ -642,10 +642,14 @@ class Diff {
642
642
  removedCount = 0;
643
643
  addedSize = 0;
644
644
  removedSize = 0;
645
- deletedIndexes = [];
646
- addedIndexes = [];
647
645
  countDelta;
648
646
  sizeDelta;
647
+ addedIndexes = [];
648
+ addedIds = [];
649
+ addedSelfSizes = [];
650
+ deletedIndexes = [];
651
+ deletedIds = [];
652
+ deletedSelfSizes = [];
649
653
  constructor(name) {
650
654
  this.name = name;
651
655
  }
@@ -2806,44 +2810,15 @@ const LAYOUT_LINES_HIGHLIGHT_COLOR = [127, 32, 210];
2806
2810
  Mask: Legacy.fromRGBA([248, 249, 249, 1]),
2807
2811
  });
2808
2812
 
2809
- // Copyright 2025 The Chromium Authors
2810
- class WritableDevToolsContext {
2811
- #instances = new Map();
2812
- get(ctor) {
2813
- const instance = this.#instances.get(ctor);
2814
- if (!instance) {
2815
- throw new Error(`No instance for ${ctor.name}. Ensure the bootstrapper creates it.`);
2816
- }
2817
- return instance;
2818
- }
2819
- has(ctor) {
2820
- return this.#instances.has(ctor);
2821
- }
2822
- set(ctor, instance) {
2823
- this.#instances.set(ctor, instance);
2824
- }
2825
- delete(ctor) {
2826
- this.#instances.delete(ctor);
2827
- }
2828
- }
2829
- let gInstance = null;
2830
- function globalInstance() {
2831
- if (!gInstance) {
2832
- gInstance = new WritableDevToolsContext();
2833
- }
2834
- return gInstance;
2835
- }
2836
-
2837
2813
  // Copyright 2026 The Chromium Authors
2838
2814
  var ExperimentName;
2839
2815
  (function (ExperimentName) {
2840
2816
  ExperimentName["ALL"] = "*";
2841
- ExperimentName["CAPTURE_NODE_CREATION_STACKS"] = "capture-node-creation-stacks";
2842
2817
  ExperimentName["PROTOCOL_MONITOR"] = "protocol-monitor";
2843
2818
  ExperimentName["INSTRUMENTATION_BREAKPOINTS"] = "instrumentation-breakpoints";
2844
- ExperimentName["USE_SOURCE_MAP_SCOPES"] = "use-source-map-scopes";
2845
2819
  ExperimentName["DURABLE_MESSAGES"] = "durable-messages";
2846
2820
  ExperimentName["JPEG_XL"] = "jpeg-xl";
2821
+ ExperimentName["PLUS_BUTTON"] = "plus-button";
2847
2822
  })(ExperimentName || (ExperimentName = {}));
2848
2823
 
2849
2824
  // Copyright 2021 The Chromium Authors
@@ -4798,7 +4773,7 @@ function lockedLazyString(str) {
4798
4773
  // Copyright 2014 The Chromium Authors
4799
4774
  const UIStrings$2 = {
4800
4775
  elementsPanel: 'Elements panel',
4801
- stylesSidebar: 'styles sidebar',
4776
+ stylesSidebar: 'Styles sidebar',
4802
4777
  changesDrawer: 'Changes drawer',
4803
4778
  issuesView: 'Issues view',
4804
4779
  networkPanel: 'Network panel',
@@ -4807,50 +4782,12 @@ const UIStrings$2 = {
4807
4782
  sourcesPanel: 'Sources panel',
4808
4783
  timelinePanel: 'Performance panel',
4809
4784
  memoryInspectorPanel: 'Memory inspector panel',
4810
- developerResourcesPanel: 'Developer Resources panel',
4785
+ developerResourcesPanel: 'Developer resources panel',
4811
4786
  animationsPanel: 'Animations panel',
4787
+ lighthousePanel: 'Lighthouse panel',
4812
4788
  };
4813
4789
  const str_$2 = registerUIStrings('core/common/Revealer.ts', UIStrings$2);
4814
4790
  const i18nLazyString$1 = getLazilyComputedLocalizedString.bind(undefined, str_$2);
4815
- let revealerRegistry;
4816
- class RevealerRegistry {
4817
- registeredRevealers = [];
4818
- static instance() {
4819
- if (revealerRegistry === undefined) {
4820
- revealerRegistry = new RevealerRegistry();
4821
- }
4822
- return revealerRegistry;
4823
- }
4824
- static removeInstance() {
4825
- revealerRegistry = undefined;
4826
- }
4827
- register(registration) {
4828
- this.registeredRevealers.push(registration);
4829
- }
4830
- async reveal(revealable, omitFocus) {
4831
- const revealers = await Promise.all(this.getApplicableRegisteredRevealers(revealable).map(registration => registration.loadRevealer()));
4832
- if (revealers.length < 1) {
4833
- throw new Error(`No revealers found for ${revealable}`);
4834
- }
4835
- if (revealers.length > 1) {
4836
- throw new Error(`Conflicting reveals found for ${revealable}`);
4837
- }
4838
- return await revealers[0].reveal(revealable, omitFocus);
4839
- }
4840
- getApplicableRegisteredRevealers(revealable) {
4841
- return this.registeredRevealers.filter(registration => {
4842
- for (const contextType of registration.contextTypes()) {
4843
- if (revealable instanceof contextType) {
4844
- return true;
4845
- }
4846
- }
4847
- return false;
4848
- });
4849
- }
4850
- }
4851
- async function reveal(revealable, omitFocus = false) {
4852
- await RevealerRegistry.instance().reveal(revealable, omitFocus);
4853
- }
4854
4791
  ({
4855
4792
  DEVELOPER_RESOURCES_PANEL: i18nLazyString$1(UIStrings$2.developerResourcesPanel),
4856
4793
  ELEMENTS_PANEL: i18nLazyString$1(UIStrings$2.elementsPanel),
@@ -4864,44 +4801,10 @@ async function reveal(revealable, omitFocus = false) {
4864
4801
  SOURCES_PANEL: i18nLazyString$1(UIStrings$2.sourcesPanel),
4865
4802
  MEMORY_INSPECTOR_PANEL: i18nLazyString$1(UIStrings$2.memoryInspectorPanel),
4866
4803
  ANIMATIONS_PANEL: i18nLazyString$1(UIStrings$2.animationsPanel),
4804
+ LIGHTHOUSE_PANEL: i18nLazyString$1(UIStrings$2.lighthousePanel),
4867
4805
  });
4868
4806
 
4869
4807
  // Copyright 2014 The Chromium Authors
4870
- class Console extends ObjectWrapper {
4871
- #messages = [];
4872
- static instance(opts) {
4873
- if (!globalInstance().has(Console) || opts?.forceNew) {
4874
- globalInstance().set(Console, new Console());
4875
- }
4876
- return globalInstance().get(Console);
4877
- }
4878
- static removeInstance() {
4879
- globalInstance().delete(Console);
4880
- }
4881
- addMessage(text, level = "info" , show = false, source) {
4882
- const message = new Message(text, level, Date.now(), show, source);
4883
- this.#messages.push(message);
4884
- this.dispatchEventToListeners("messageAdded" , message);
4885
- }
4886
- log(text) {
4887
- this.addMessage(text, "info" );
4888
- }
4889
- warn(text, source) {
4890
- this.addMessage(text, "warning" , undefined, source);
4891
- }
4892
- error(text, show = true) {
4893
- this.addMessage(text, "error" , show);
4894
- }
4895
- messages() {
4896
- return this.#messages;
4897
- }
4898
- show() {
4899
- void this.showPromise();
4900
- }
4901
- showPromise() {
4902
- return reveal(this);
4903
- }
4904
- }
4905
4808
  var FrontendMessageSource;
4906
4809
  (function (FrontendMessageSource) {
4907
4810
  FrontendMessageSource["CSS"] = "css";
@@ -4909,22 +4812,6 @@ var FrontendMessageSource;
4909
4812
  FrontendMessageSource["ISSUE_PANEL"] = "issue-panel";
4910
4813
  FrontendMessageSource["SELF_XSS"] = "self-xss";
4911
4814
  })(FrontendMessageSource || (FrontendMessageSource = {}));
4912
- class Message {
4913
- text;
4914
- level;
4915
- timestamp;
4916
- show;
4917
- source;
4918
- constructor(text, level, timestamp, show, source) {
4919
- this.text = text;
4920
- this.level = level;
4921
- this.timestamp = (typeof timestamp === 'number') ? timestamp : Date.now();
4922
- this.show = show;
4923
- if (source) {
4924
- this.source = source;
4925
- }
4926
- }
4927
- }
4928
4815
 
4929
4816
  // Copyright 2012 The Chromium Authors
4930
4817
  function normalizePath(path) {
@@ -5328,7 +5215,11 @@ class ParsedURL {
5328
5215
  return 'data:';
5329
5216
  }
5330
5217
  const scheme = this.isBlobURL() ? this.blobInnerScheme : this.scheme;
5331
- return scheme + '://' + this.domain();
5218
+ const domain = this.domain();
5219
+ if (!scheme && !domain) {
5220
+ return '';
5221
+ }
5222
+ return scheme + '://' + domain;
5332
5223
  }
5333
5224
  urlWithoutScheme() {
5334
5225
  if (this.scheme && this.url.startsWith(this.scheme + '://')) {
@@ -5725,7 +5616,6 @@ const UIStrings = {
5725
5616
  extension: 'Extension',
5726
5617
  adorner: 'Adorner',
5727
5618
  account: 'Account',
5728
- privacy: 'Privacy',
5729
5619
  };
5730
5620
  const str_ = registerUIStrings('core/common/SettingRegistration.ts', UIStrings);
5731
5621
  getLocalizedString.bind(undefined, str_);
@@ -5733,6 +5623,7 @@ getLocalizedString.bind(undefined, str_);
5733
5623
  // Copyright 2011 The Chromium Authors
5734
5624
  class HeapSnapshotWorkerProxy extends ObjectWrapper {
5735
5625
  eventHandler;
5626
+ #console;
5736
5627
  nextObjectId = 1;
5737
5628
  nextCallId = 1;
5738
5629
  callbacks = new Map();
@@ -5740,13 +5631,17 @@ class HeapSnapshotWorkerProxy extends ObjectWrapper {
5740
5631
  worker;
5741
5632
  interval;
5742
5633
  workerUrl;
5743
- constructor(eventHandler, workerUrl) {
5634
+ constructor(eventHandler, console, workerUrl) {
5744
5635
  super();
5745
5636
  this.eventHandler = eventHandler;
5637
+ this.#console = console;
5746
5638
  this.workerUrl = workerUrl;
5747
5639
  this.worker = HOST_RUNTIME.createWorker(workerUrl ?? import.meta.resolve('../../entrypoints/heap_snapshot_worker/heap_snapshot_worker-entrypoint.js'));
5748
5640
  this.worker.onmessage = this.messageReceived.bind(this);
5749
5641
  }
5642
+ get console() {
5643
+ return this.#console;
5644
+ }
5750
5645
  createLoader(profileUid, snapshotReceivedCallback) {
5751
5646
  const objectId = this.nextObjectId++;
5752
5647
  const proxy = new HeapSnapshotLoaderProxy(this, objectId, profileUid, snapshotReceivedCallback);
@@ -5814,7 +5709,7 @@ class HeapSnapshotWorkerProxy extends ObjectWrapper {
5814
5709
  return;
5815
5710
  }
5816
5711
  this.checkLongRunningCalls();
5817
- this.interval = window.setInterval(this.checkLongRunningCalls.bind(this), 300);
5712
+ this.interval = globalThis.setInterval(this.checkLongRunningCalls.bind(this), 300);
5818
5713
  }
5819
5714
  checkLongRunningCalls() {
5820
5715
  for (const callId of this.previousCallbacks) {
@@ -5849,8 +5744,8 @@ class HeapSnapshotWorkerProxy extends ObjectWrapper {
5849
5744
  return;
5850
5745
  }
5851
5746
  if (data.error) {
5852
- Console.instance().error(`An error occurred when a call to method '${data.errorMethodName}' was requested`);
5853
- Console.instance().error(data['errorCallStack']);
5747
+ this.#console.error(`An error occurred when a call to method '${data.errorMethodName}' was requested`);
5748
+ this.#console.error(data['errorCallStack']);
5854
5749
  this.callbacks.delete(data.callId);
5855
5750
  return;
5856
5751
  }
@@ -5898,7 +5793,7 @@ class HeapSnapshotLoaderProxy extends HeapSnapshotProxyObject {
5898
5793
  }
5899
5794
  async close() {
5900
5795
  await this.callMethodPromise('close');
5901
- const secondWorker = new HeapSnapshotWorkerProxy(() => { }, this.worker.workerUrl);
5796
+ const secondWorker = new HeapSnapshotWorkerProxy(() => { }, this.worker.console, this.worker.workerUrl);
5902
5797
  const channel = new MessageChannel();
5903
5798
  await secondWorker.setupForSecondaryInit(channel.port2);
5904
5799
  const snapshotProxy = await this.callFactoryMethodPromise('buildSnapshot', HeapSnapshotProxy, [channel.port1]);
@@ -5922,9 +5817,18 @@ class HeapSnapshotProxy extends HeapSnapshotProxyObject {
5922
5817
  interfaceDefinitions() {
5923
5818
  return this.callMethodPromise('interfaceDefinitions');
5924
5819
  }
5820
+ getNativeContextSizes() {
5821
+ return this.callMethodPromise('getNativeContextSizes');
5822
+ }
5823
+ getRetainedByContextSummary() {
5824
+ return this.callMethodPromise('getRetainedByContextSummary');
5825
+ }
5925
5826
  aggregatesWithFilter(filter) {
5926
5827
  return this.callMethodPromise('aggregatesWithFilter', filter);
5927
5828
  }
5829
+ getDuplicateStrings() {
5830
+ return this.callMethodPromise('getDuplicateStrings');
5831
+ }
5928
5832
  aggregatesForDiff(interfaceDefinitions) {
5929
5833
  return this.callMethodPromise('aggregatesForDiff', interfaceDefinitions);
5930
5834
  }
@@ -5934,8 +5838,14 @@ class HeapSnapshotProxy extends HeapSnapshotProxyObject {
5934
5838
  nodeClassKey(snapshotObjectId) {
5935
5839
  return this.callMethodPromise('nodeClassKey', snapshotObjectId);
5936
5840
  }
5937
- createEdgesProvider(nodeIndex) {
5938
- return this.callFactoryMethod('createEdgesProvider', HeapSnapshotProviderProxy, nodeIndex);
5841
+ nodeIndexForId(nodeId) {
5842
+ return this.callMethodPromise('nodeIndexForId', nodeId);
5843
+ }
5844
+ getObjectInfo(nodeIndex) {
5845
+ return this.callMethodPromise('getObjectInfo', nodeIndex);
5846
+ }
5847
+ createEdgesProvider(nodeIndex, options) {
5848
+ return this.callFactoryMethod('createEdgesProvider', HeapSnapshotProviderProxy, nodeIndex, options);
5939
5849
  }
5940
5850
  createRetainingEdgesProvider(nodeIndex) {
5941
5851
  return this.callFactoryMethod('createRetainingEdgesProvider', HeapSnapshotProviderProxy, nodeIndex);
@@ -5952,6 +5862,9 @@ class HeapSnapshotProxy extends HeapSnapshotProxyObject {
5952
5862
  createNodesProviderForClass(classKey, nodeFilter) {
5953
5863
  return this.callFactoryMethod('createNodesProviderForClass', HeapSnapshotProviderProxy, classKey, nodeFilter);
5954
5864
  }
5865
+ queryObjects(queryOptions) {
5866
+ return this.callFactoryMethod('queryObjects', HeapSnapshotProviderProxy, queryOptions);
5867
+ }
5955
5868
  allocationTracesTops() {
5956
5869
  return this.callMethodPromise('allocationTracesTops');
5957
5870
  }
@@ -5991,6 +5904,12 @@ class HeapSnapshotProxy extends HeapSnapshotProxyObject {
5991
5904
  ignoreNodeInRetainersView(nodeIndex) {
5992
5905
  return this.callMethodPromise('ignoreNodeInRetainersView', nodeIndex);
5993
5906
  }
5907
+ getRetainingPaths(nodeIndex, maxDepth, maxNodes, maxSiblings) {
5908
+ return this.callMethodPromise('getRetainingPaths', nodeIndex, maxDepth, maxNodes, maxSiblings);
5909
+ }
5910
+ getDominatorsOf(nodeIndex) {
5911
+ return this.callMethodPromise('getDominatorsOf', nodeIndex);
5912
+ }
5994
5913
  unignoreNodeInRetainersView(nodeIndex) {
5995
5914
  return this.callMethodPromise('unignoreNodeInRetainersView', nodeIndex);
5996
5915
  }
@@ -6673,21 +6592,10 @@ class HeapSnapshotNode {
6673
6592
  return false;
6674
6593
  }
6675
6594
  #detachednessAndClassIndex() {
6676
- const { snapshot, nodeIndex } = this;
6677
- const nodeDetachednessAndClassIndexOffset = snapshot.nodeDetachednessAndClassIndexOffset;
6678
- return nodeDetachednessAndClassIndexOffset !== -1 ?
6679
- snapshot.nodes.getValue(nodeIndex + nodeDetachednessAndClassIndexOffset) :
6680
- snapshot.detachednessAndClassIndexArray[nodeIndex / snapshot.nodeFieldCount];
6595
+ return this.snapshot.detachednessAndClassIndexArray[this.nodeIndex / this.snapshot.nodeFieldCount];
6681
6596
  }
6682
6597
  #setDetachednessAndClassIndex(value) {
6683
- const { snapshot, nodeIndex } = this;
6684
- const nodeDetachednessAndClassIndexOffset = snapshot.nodeDetachednessAndClassIndexOffset;
6685
- if (nodeDetachednessAndClassIndexOffset !== -1) {
6686
- snapshot.nodes.setValue(nodeIndex + nodeDetachednessAndClassIndexOffset, value);
6687
- }
6688
- else {
6689
- snapshot.detachednessAndClassIndexArray[nodeIndex / snapshot.nodeFieldCount] = value;
6690
- }
6598
+ this.snapshot.detachednessAndClassIndexArray[this.nodeIndex / this.snapshot.nodeFieldCount] = value;
6691
6599
  }
6692
6600
  detachedness() {
6693
6601
  return this.#detachednessAndClassIndex() & BITMASK_FOR_DOM_LINK_STATE;
@@ -6698,6 +6606,67 @@ class HeapSnapshotNode {
6698
6606
  value |= detachedness;
6699
6607
  this.#setDetachednessAndClassIndex(value);
6700
6608
  }
6609
+ findInternalEdgeTarget(name) {
6610
+ for (let iter = this.edges(); iter.hasNext(); iter.next()) {
6611
+ const edge = iter.edge;
6612
+ if (!edge.isInternal()) {
6613
+ continue;
6614
+ }
6615
+ if (edge.name() === name) {
6616
+ return edge.node();
6617
+ }
6618
+ }
6619
+ return undefined;
6620
+ }
6621
+ nodeValueAsBool() {
6622
+ if (this.rawType() !== this.snapshot.nodeNumberType) {
6623
+ return undefined;
6624
+ }
6625
+ if (this.rawName() !== 'bool') {
6626
+ return undefined;
6627
+ }
6628
+ const valNode = this.findInternalEdgeTarget('value');
6629
+ if (!valNode) {
6630
+ return undefined;
6631
+ }
6632
+ const rawName = valNode.rawName();
6633
+ if (rawName === 'true') {
6634
+ return true;
6635
+ }
6636
+ if (rawName === 'false') {
6637
+ return false;
6638
+ }
6639
+ return undefined;
6640
+ }
6641
+ nodeValueAsInt() {
6642
+ if (this.rawType() !== this.snapshot.nodeNumberType) {
6643
+ return undefined;
6644
+ }
6645
+ if (this.rawName() !== 'int') {
6646
+ return undefined;
6647
+ }
6648
+ const valNode = this.findInternalEdgeTarget('value');
6649
+ if (!valNode) {
6650
+ return undefined;
6651
+ }
6652
+ const value = parseInt(valNode.rawName(), 10);
6653
+ return isNaN(value) ? undefined : value;
6654
+ }
6655
+ nodeStringLength() {
6656
+ const lengthNode = this.findInternalEdgeTarget('length');
6657
+ return lengthNode ? lengthNode.nodeValueAsInt() : undefined;
6658
+ }
6659
+ nodeStringHash() {
6660
+ const hashNode = this.findInternalEdgeTarget('hash');
6661
+ return hashNode ? hashNode.nodeValueAsInt() : undefined;
6662
+ }
6663
+ nodeIsTruncatedString() {
6664
+ const truncNode = this.findInternalEdgeTarget('truncated');
6665
+ if (!truncNode) {
6666
+ return false;
6667
+ }
6668
+ return truncNode.nodeValueAsBool() === true;
6669
+ }
6701
6670
  }
6702
6671
  class HeapSnapshotNodeIterator {
6703
6672
  node;
@@ -6848,7 +6817,7 @@ class SecondaryInitManager {
6848
6817
  ...retainers,
6849
6818
  essentialEdges: createBitVector(argsStep2.essentialEdgesBuffer),
6850
6819
  port,
6851
- nodeSelfSizesPromise: this.getNodeSelfSizes()
6820
+ nodeSelfSizesPromise: this.getNodeSelfSizes(),
6852
6821
  };
6853
6822
  const dominatorsAndRetainedSizes = await HeapSnapshot.calculateDominatorsAndRetainedSizes(args);
6854
6823
  const dominatedNodesOutputs = HeapSnapshot.buildDominatedNodes({ ...args, ...dominatorsAndRetainedSizes });
@@ -6878,6 +6847,8 @@ const MIN_INTERFACE_PROPERTY_COUNT = 1;
6878
6847
  const MAX_INTERFACE_NAME_LENGTH = 120;
6879
6848
  const MIN_OBJECT_COUNT_PER_INTERFACE = 2;
6880
6849
  const MIN_OBJECT_PROPORTION_PER_INTERFACE = 1000;
6850
+ const NO_NATIVE_CONTEXT = -1;
6851
+ const SHARED_NATIVE_CONTEXT = -2;
6881
6852
  class HeapSnapshot {
6882
6853
  nodes;
6883
6854
  containmentEdges;
@@ -6913,6 +6884,7 @@ class HeapSnapshot {
6913
6884
  nodeSyntheticType;
6914
6885
  nodeClosureType;
6915
6886
  nodeRegExpType;
6887
+ nodeNumberType;
6916
6888
  edgeFieldsCount;
6917
6889
  edgeTypeOffset;
6918
6890
  edgeNameOffset;
@@ -6949,6 +6921,9 @@ class HeapSnapshot {
6949
6921
  #nodeDistancesForRetainersView;
6950
6922
  #edgeNamesThatAreNotWeakMaps;
6951
6923
  detachednessAndClassIndexArray;
6924
+ nodeNativeContextAttribution;
6925
+ #nativeContextSizes;
6926
+ #nativeContextOrdinals;
6952
6927
  #interfaceNames = new Map();
6953
6928
  #interfaceDefinitions;
6954
6929
  constructor(profile, progress) {
@@ -6987,6 +6962,7 @@ class HeapSnapshot {
6987
6962
  this.nodeSyntheticType = this.nodeTypes.indexOf('synthetic');
6988
6963
  this.nodeClosureType = this.nodeTypes.indexOf('closure');
6989
6964
  this.nodeRegExpType = this.nodeTypes.indexOf('regexp');
6965
+ this.nodeNumberType = this.nodeTypes.indexOf('number');
6990
6966
  this.edgeFieldsCount = meta.edge_fields.length;
6991
6967
  this.edgeTypeOffset = meta.edge_fields.indexOf('type');
6992
6968
  this.edgeNameOffset = meta.edge_fields.indexOf('name_or_index');
@@ -7014,6 +6990,7 @@ class HeapSnapshot {
7014
6990
  this.#progress.updateStatus('Building retainers…');
7015
6991
  const resultsFromSecondWorker = this.startInitStep1InSecondThread(secondWorker);
7016
6992
  this.#progress.updateStatus('Propagating DOM state…');
6993
+ this.initDetachednessAndClassIndex();
7017
6994
  this.propagateDOMState();
7018
6995
  this.#progress.updateStatus('Calculating node flags…');
7019
6996
  this.calculateFlags();
@@ -7033,8 +7010,11 @@ class HeapSnapshot {
7033
7010
  this.buildSamples();
7034
7011
  this.#progress.updateStatus('Building locations…');
7035
7012
  this.buildLocationMap();
7013
+ this.#progress.updateStatus('Calculating native context attribution…');
7014
+ this.calculateNativeContextAttribution();
7036
7015
  this.#progress.updateStatus('Calculating retained sizes…');
7037
7016
  await this.installResultsFromSecondThread(resultsFromSecondWorker);
7017
+ this.calculateNativeContextSizes();
7038
7018
  this.#progress.updateStatus('Calculating statistics…');
7039
7019
  this.calculateStatistics();
7040
7020
  if (this.profile.snapshot.trace_function_count) {
@@ -7059,6 +7039,36 @@ class HeapSnapshot {
7059
7039
  }
7060
7040
  this.#progress.updateStatus('Finished processing.');
7061
7041
  }
7042
+ nodeIndexForId(nodeId) {
7043
+ const nodesLength = this.nodes.length;
7044
+ const { nodes, nodeFieldCount, nodeIdOffset } = this;
7045
+ for (let nodeIndex = 0; nodeIndex < nodesLength; nodeIndex += nodeFieldCount) {
7046
+ if (nodes.getValue(nodeIndex + nodeIdOffset) === nodeId) {
7047
+ return nodeIndex;
7048
+ }
7049
+ }
7050
+ return undefined;
7051
+ }
7052
+ getObjectInfo(nodeIndex) {
7053
+ const nodesLength = this.nodes.length;
7054
+ const nodeFieldCount = this.nodeFieldCount;
7055
+ if (!Number.isInteger(nodeIndex) || nodeIndex < 0 || nodeIndex >= nodesLength || nodeIndex % nodeFieldCount !== 0) {
7056
+ throw new Error('Invalid nodeIndex ' + nodeIndex);
7057
+ }
7058
+ const node = this.createNode(nodeIndex);
7059
+ return {
7060
+ id: node.id(),
7061
+ name: node.name(),
7062
+ type: node.type(),
7063
+ nodeIndex,
7064
+ detachedness: node.detachedness(),
7065
+ selfSize: node.selfSize(),
7066
+ retainedSize: node.retainedSize(),
7067
+ distance: node.distance(),
7068
+ edgeCount: node.edgesCount(),
7069
+ retainerCount: node.retainersCount(),
7070
+ };
7071
+ }
7062
7072
  startInitStep1InSecondThread(secondWorker) {
7063
7073
  const resultsFromSecondWorker = new Promise((resolve, reject) => {
7064
7074
  const listener = (e) => {
@@ -7256,6 +7266,79 @@ class HeapSnapshot {
7256
7266
  const key = filter ? filter.key : 'allObjects';
7257
7267
  return this.getAggregatesByClassKey(false, key, filter);
7258
7268
  }
7269
+ getDuplicateStrings() {
7270
+ const filter = this.createNamedFilter('duplicatedStrings');
7271
+ const untruncatedGroups = new Map();
7272
+ const truncatedGroups = new Map();
7273
+ const node = this.createNode(0);
7274
+ for (let i = 0; i < this.nodeCount; ++i) {
7275
+ node.nodeIndex = i * this.nodeFieldCount;
7276
+ if (filter(node)) {
7277
+ const name = node.name();
7278
+ const truncated = node.nodeIsTruncatedString();
7279
+ if (truncated) {
7280
+ const length = node.nodeStringLength();
7281
+ const hash = node.nodeStringHash();
7282
+ let groups = truncatedGroups.get(name);
7283
+ if (!groups) {
7284
+ groups = [];
7285
+ truncatedGroups.set(name, groups);
7286
+ }
7287
+ let group = groups.find(g => g.length === length && g.hash === hash);
7288
+ if (!group) {
7289
+ group = {
7290
+ value: name,
7291
+ count: 0,
7292
+ totalSelfSize: 0,
7293
+ totalRetainedSize: 0,
7294
+ nodes: [],
7295
+ truncated: true,
7296
+ length,
7297
+ hash,
7298
+ };
7299
+ groups.push(group);
7300
+ }
7301
+ group.count++;
7302
+ group.totalSelfSize += node.selfSize();
7303
+ group.totalRetainedSize += node.retainedSize();
7304
+ group.nodes.push({
7305
+ id: node.id(),
7306
+ selfSize: node.selfSize(),
7307
+ retainedSize: node.retainedSize(),
7308
+ distance: node.distance(),
7309
+ });
7310
+ }
7311
+ else {
7312
+ let group = untruncatedGroups.get(name);
7313
+ if (!group) {
7314
+ group = {
7315
+ value: name,
7316
+ count: 0,
7317
+ totalSelfSize: 0,
7318
+ totalRetainedSize: 0,
7319
+ nodes: [],
7320
+ truncated: false,
7321
+ };
7322
+ untruncatedGroups.set(name, group);
7323
+ }
7324
+ group.count++;
7325
+ group.totalSelfSize += node.selfSize();
7326
+ group.totalRetainedSize += node.retainedSize();
7327
+ group.nodes.push({
7328
+ id: node.id(),
7329
+ selfSize: node.selfSize(),
7330
+ retainedSize: node.retainedSize(),
7331
+ distance: node.distance(),
7332
+ });
7333
+ }
7334
+ }
7335
+ }
7336
+ const allGroups = [
7337
+ ...untruncatedGroups.values(),
7338
+ ...Array.from(truncatedGroups.values()).flat(),
7339
+ ];
7340
+ return allGroups.sort((a, b) => b.totalRetainedSize - a.totalRetainedSize);
7341
+ }
7259
7342
  createNodeIdFilter(minNodeId, maxNodeId) {
7260
7343
  function nodeIdFilter(node) {
7261
7344
  const id = node.id();
@@ -7310,6 +7393,12 @@ class HeapSnapshot {
7310
7393
  }
7311
7394
  };
7312
7395
  switch (filterName) {
7396
+ case 'objectsRetainedByContexts':
7397
+ traverse((_node, edge) => {
7398
+ return !this.isContextObject(edge.node());
7399
+ });
7400
+ markUnreachableNodes();
7401
+ return (node) => !getBit(node);
7313
7402
  case 'objectsRetainedByDetachedDomNodes':
7314
7403
  traverse((_node, edge) => {
7315
7404
  return edge.node().detachedness() !== 2 ;
@@ -7322,29 +7411,8 @@ class HeapSnapshot {
7322
7411
  });
7323
7412
  markUnreachableNodes();
7324
7413
  return (node) => !getBit(node);
7325
- case 'duplicatedStrings': {
7326
- const stringToNodeIndexMap = new Map();
7327
- const node = this.createNode(0);
7328
- for (let i = 0; i < this.nodeCount; ++i) {
7329
- node.nodeIndex = i * this.nodeFieldCount;
7330
- const rawType = node.rawType();
7331
- if (rawType === this.nodeStringType || rawType === this.nodeConsStringType) {
7332
- if (node.isFlatConsString()) {
7333
- continue;
7334
- }
7335
- const name = node.name();
7336
- const alreadyVisitedNodeIndex = stringToNodeIndexMap.get(name);
7337
- if (alreadyVisitedNodeIndex === undefined) {
7338
- stringToNodeIndexMap.set(name, node.nodeIndex);
7339
- }
7340
- else {
7341
- bitmap.setBit(alreadyVisitedNodeIndex / this.nodeFieldCount);
7342
- bitmap.setBit(node.nodeIndex / this.nodeFieldCount);
7343
- }
7344
- }
7345
- }
7346
- return getBit;
7347
- }
7414
+ case 'duplicatedStrings':
7415
+ return this.createDuplicatedStringsFilter(bitmap);
7348
7416
  case 'objectsRetainedByEventHandlers': {
7349
7417
  const node = this.createNode(0);
7350
7418
  const nodeFieldCount = this.nodeFieldCount;
@@ -7383,9 +7451,79 @@ class HeapSnapshot {
7383
7451
  markUnreachableNodes();
7384
7452
  return (node) => !getBit(node);
7385
7453
  }
7454
+ case 'sharedNativeContext':
7455
+ return (node) => {
7456
+ const ordinal = node.nodeIndex / this.nodeFieldCount;
7457
+ return this.nodeNativeContextAttribution[ordinal] === SHARED_NATIVE_CONTEXT;
7458
+ };
7459
+ case 'noNativeContext':
7460
+ return (node) => {
7461
+ const ordinal = node.nodeIndex / this.nodeFieldCount;
7462
+ return this.nodeNativeContextAttribution[ordinal] === NO_NATIVE_CONTEXT;
7463
+ };
7464
+ default:
7465
+ if (filterName.startsWith('nativeContext_')) {
7466
+ const targetNodeIndex = Number(filterName.substring('nativeContext_'.length));
7467
+ const targetOrdinal = targetNodeIndex / this.nodeFieldCount;
7468
+ return (node) => {
7469
+ const ordinal = node.nodeIndex / this.nodeFieldCount;
7470
+ return this.nodeNativeContextAttribution[ordinal] === targetOrdinal;
7471
+ };
7472
+ }
7386
7473
  }
7387
7474
  throw new Error('Invalid filter name');
7388
7475
  }
7476
+ createDuplicatedStringsFilter(bitmap) {
7477
+ const untruncatedStringToNodeIndexMap = new Map();
7478
+ const truncatedStringToNodeIndexesMap = new Map();
7479
+ const node = this.createNode(0);
7480
+ for (let i = 0; i < this.nodeCount; ++i) {
7481
+ node.nodeIndex = i * this.nodeFieldCount;
7482
+ const rawType = node.rawType();
7483
+ if (rawType !== this.nodeStringType && rawType !== this.nodeConsStringType) {
7484
+ continue;
7485
+ }
7486
+ if (node.isFlatConsString()) {
7487
+ continue;
7488
+ }
7489
+ if (node.selfSize() === 0) {
7490
+ continue;
7491
+ }
7492
+ const name = node.name();
7493
+ const truncated = node.nodeIsTruncatedString();
7494
+ if (truncated) {
7495
+ const length = node.nodeStringLength();
7496
+ const hash = node.nodeStringHash();
7497
+ let entries = truncatedStringToNodeIndexesMap.get(name);
7498
+ if (!entries) {
7499
+ entries = [];
7500
+ truncatedStringToNodeIndexesMap.set(name, entries);
7501
+ }
7502
+ const match = entries.find(e => e.length === length && e.hash === hash);
7503
+ if (match) {
7504
+ bitmap.setBit(match.nodeIndex / this.nodeFieldCount);
7505
+ bitmap.setBit(node.nodeIndex / this.nodeFieldCount);
7506
+ }
7507
+ else {
7508
+ entries.push({ nodeIndex: node.nodeIndex, length, hash });
7509
+ }
7510
+ }
7511
+ else {
7512
+ const alreadyVisitedNodeIndex = untruncatedStringToNodeIndexMap.get(name);
7513
+ if (alreadyVisitedNodeIndex === undefined) {
7514
+ untruncatedStringToNodeIndexMap.set(name, node.nodeIndex);
7515
+ }
7516
+ else {
7517
+ bitmap.setBit(alreadyVisitedNodeIndex / this.nodeFieldCount);
7518
+ bitmap.setBit(node.nodeIndex / this.nodeFieldCount);
7519
+ }
7520
+ }
7521
+ }
7522
+ return (node) => {
7523
+ const ordinal = node.nodeIndex / this.nodeFieldCount;
7524
+ return bitmap.getBit(ordinal);
7525
+ };
7526
+ }
7389
7527
  getAggregatesByClassKey(sortedIndexes, key, filter) {
7390
7528
  let aggregates;
7391
7529
  if (key && this.#aggregates[key]) {
@@ -7453,6 +7591,9 @@ class HeapSnapshot {
7453
7591
  isUserRoot(_node) {
7454
7592
  return true;
7455
7593
  }
7594
+ isContextObject(_node) {
7595
+ return false;
7596
+ }
7456
7597
  calculateShallowSizes() {
7457
7598
  }
7458
7599
  calculateDistances(isForRetainersView, filter) {
@@ -7701,7 +7842,7 @@ class HeapSnapshot {
7701
7842
  return true;
7702
7843
  }
7703
7844
  static async calculateDominatorsAndRetainedSizes(inputs) {
7704
- const { nodeCount, firstEdgeIndexes, edgeFieldsCount, nodeFieldCount, firstRetainerIndex, retainingEdges, retainingNodes, edgeToNodeOrdinals, rootNodeOrdinal, essentialEdges, nodeSelfSizesPromise, port } = inputs;
7845
+ const { nodeCount, firstEdgeIndexes, edgeFieldsCount, nodeFieldCount, firstRetainerIndex, retainingEdges, retainingNodes, edgeToNodeOrdinals, rootNodeOrdinal, essentialEdges, nodeSelfSizesPromise, port, } = inputs;
7705
7846
  function isEssentialEdge(edgeIndex) {
7706
7847
  return essentialEdges.getBit(edgeIndex / edgeFieldsCount);
7707
7848
  }
@@ -7885,9 +8026,6 @@ class HeapSnapshot {
7885
8026
  }
7886
8027
  calculateObjectNames() {
7887
8028
  const { nodes, nodeCount, nodeNameOffset, nodeNativeType, nodeHiddenType, nodeObjectType, nodeCodeType, nodeClosureType, nodeRegExpType, } = this;
7888
- if (this.nodeDetachednessAndClassIndexOffset === -1) {
7889
- this.detachednessAndClassIndexArray = new Uint32Array(nodeCount);
7890
- }
7891
8029
  const stringTable = new Map();
7892
8030
  const getIndexForString = (s) => {
7893
8031
  let index = stringTable.get(s);
@@ -7940,6 +8078,215 @@ class HeapSnapshot {
7940
8078
  node.nodeIndex = node.nextNodeIndex();
7941
8079
  }
7942
8080
  }
8081
+ calculateNativeContextAttribution() {
8082
+ const attribution = new Int32Array(this.nodeCount).fill(NO_NATIVE_CONTEXT);
8083
+ const isFixed = createBitVector(this.nodeCount);
8084
+ const edgeTargets = this.buildInitEdgeTargets();
8085
+ this.#nativeContextOrdinals = [];
8086
+ for (let ordinal = 0; ordinal < this.nodeCount; ordinal++) {
8087
+ if (this.isNativeContext(ordinal)) {
8088
+ this.#nativeContextOrdinals.push(ordinal);
8089
+ attribution[ordinal] = ordinal;
8090
+ isFixed.setBit(ordinal);
8091
+ }
8092
+ else {
8093
+ const owner = this.inferFixedNativeContextForOrdinal(ordinal, edgeTargets);
8094
+ if (owner >= 0) {
8095
+ attribution[ordinal] = owner;
8096
+ isFixed.setBit(ordinal);
8097
+ }
8098
+ }
8099
+ }
8100
+ this.propagateNativeContextAttribution(attribution, isFixed);
8101
+ this.nodeNativeContextAttribution = attribution;
8102
+ }
8103
+ calculateNativeContextSizes() {
8104
+ const nodeFieldCount = this.nodeFieldCount;
8105
+ const node = this.createNode(0);
8106
+ const nativeContexts = [];
8107
+ const ordinalToInfo = new Map();
8108
+ for (const ordinal of this.#nativeContextOrdinals) {
8109
+ node.nodeIndex = ordinal * nodeFieldCount;
8110
+ const info = {
8111
+ nodeId: node.id(),
8112
+ nodeIndex: node.nodeIndex,
8113
+ nodeName: node.name(),
8114
+ attributedSize: 0,
8115
+ retainedSize: node.retainedSize(),
8116
+ selfSize: node.selfSize(),
8117
+ };
8118
+ nativeContexts.push(info);
8119
+ ordinalToInfo.set(ordinal, info);
8120
+ }
8121
+ let sharedSize = 0;
8122
+ let noAttributionSize = 0;
8123
+ const selfSizeOffset = this.nodeSelfSizeOffset;
8124
+ const nodes = this.nodes;
8125
+ for (let i = 0; i < this.nodeCount; ++i) {
8126
+ const ownerOrdinal = this.nodeNativeContextAttribution[i];
8127
+ const selfSize = nodes.getValue(i * nodeFieldCount + selfSizeOffset);
8128
+ if (ownerOrdinal === SHARED_NATIVE_CONTEXT) {
8129
+ sharedSize += selfSize;
8130
+ }
8131
+ else if (ownerOrdinal === NO_NATIVE_CONTEXT) {
8132
+ noAttributionSize += selfSize;
8133
+ }
8134
+ else {
8135
+ console.assert(ownerOrdinal >= 0, 'ownerOrdinal should be >= 0');
8136
+ const info = ordinalToInfo.get(ownerOrdinal);
8137
+ console.assert(info !== undefined, 'info should exist');
8138
+ if (info) {
8139
+ info.attributedSize += selfSize;
8140
+ }
8141
+ }
8142
+ }
8143
+ this.#nativeContextSizes = {
8144
+ nativeContexts,
8145
+ sharedSize,
8146
+ noAttributionSize,
8147
+ };
8148
+ }
8149
+ buildInitEdgeTargets() {
8150
+ const { nodeCount, nodeFieldCount, containmentEdges, edgeFieldsCount, edgeTypeOffset, edgeNameOffset, edgeToNodeOffset, edgeInternalType, firstEdgeIndexes, strings, } = this;
8151
+ const nativeContext = new Int32Array(nodeCount).fill(-1);
8152
+ const map = new Int32Array(nodeCount).fill(-1);
8153
+ const nativeContextIdx = strings.indexOf('native_context');
8154
+ const mapIdx = strings.indexOf('map');
8155
+ for (let ordinal = 0; ordinal < nodeCount; ordinal++) {
8156
+ const first = firstEdgeIndexes[ordinal];
8157
+ const last = firstEdgeIndexes[ordinal + 1];
8158
+ for (let edgeIndex = first; edgeIndex < last; edgeIndex += edgeFieldsCount) {
8159
+ const edgeType = containmentEdges.getValue(edgeIndex + edgeTypeOffset);
8160
+ if (edgeType !== edgeInternalType) {
8161
+ continue;
8162
+ }
8163
+ const nameIdx = containmentEdges.getValue(edgeIndex + edgeNameOffset);
8164
+ const childNodeIndex = containmentEdges.getValue(edgeIndex + edgeToNodeOffset);
8165
+ const childOrdinal = childNodeIndex / nodeFieldCount;
8166
+ if (nameIdx === nativeContextIdx && nativeContext[ordinal] === -1 && this.isNativeContext(childOrdinal)) {
8167
+ nativeContext[ordinal] = childOrdinal;
8168
+ }
8169
+ else if (nameIdx === mapIdx && map[ordinal] === -1) {
8170
+ map[ordinal] = childOrdinal;
8171
+ }
8172
+ }
8173
+ }
8174
+ return { nativeContext, map };
8175
+ }
8176
+ inferFixedNativeContextForOrdinal(ordinal, edgeTargets) {
8177
+ const mapOrdinal = edgeTargets.map[ordinal];
8178
+ if (mapOrdinal >= 0) {
8179
+ const metaMapOrdinal = edgeTargets.map[mapOrdinal];
8180
+ if (metaMapOrdinal >= 0) {
8181
+ const mapNativeContextOrdinal = edgeTargets.nativeContext[metaMapOrdinal];
8182
+ if (mapNativeContextOrdinal >= 0) {
8183
+ return mapNativeContextOrdinal;
8184
+ }
8185
+ }
8186
+ }
8187
+ return NO_NATIVE_CONTEXT;
8188
+ }
8189
+ mergeNativeContextOwner(current, incoming) {
8190
+ console.assert(incoming !== NO_NATIVE_CONTEXT, 'Incoming owner should not be NO_NATIVE_CONTEXT');
8191
+ if (current === SHARED_NATIVE_CONTEXT || incoming === SHARED_NATIVE_CONTEXT) {
8192
+ return SHARED_NATIVE_CONTEXT;
8193
+ }
8194
+ if (current === NO_NATIVE_CONTEXT) {
8195
+ return incoming;
8196
+ }
8197
+ if (current === incoming) {
8198
+ return current;
8199
+ }
8200
+ return SHARED_NATIVE_CONTEXT;
8201
+ }
8202
+ propagateNativeContextAttribution(attribution, isFixed) {
8203
+ const { nodeCount, containmentEdges, edgeFieldsCount, edgeTypeOffset, edgeToNodeOffset, edgeShortcutType, edgeWeakType, nodeFieldCount, firstEdgeIndexes, } = this;
8204
+ const queue = [];
8205
+ for (let ordinal = 0; ordinal < nodeCount; ordinal++) {
8206
+ if (isFixed.getBit(ordinal)) {
8207
+ queue.push(ordinal);
8208
+ }
8209
+ }
8210
+ let queueIndex = 0;
8211
+ while (queueIndex < queue.length) {
8212
+ const ordinal = queue[queueIndex];
8213
+ queueIndex++;
8214
+ const current = attribution[ordinal];
8215
+ console.assert(current !== NO_NATIVE_CONTEXT, 'Queue should not contain unattributed nodes');
8216
+ const first = firstEdgeIndexes[ordinal];
8217
+ const last = firstEdgeIndexes[ordinal + 1];
8218
+ for (let edgeIndex = first; edgeIndex < last; edgeIndex += edgeFieldsCount) {
8219
+ const edgeType = containmentEdges.getValue(edgeIndex + edgeTypeOffset);
8220
+ if (edgeType === edgeShortcutType || edgeType === edgeWeakType) {
8221
+ continue;
8222
+ }
8223
+ const childNodeIndex = containmentEdges.getValue(edgeIndex + edgeToNodeOffset);
8224
+ const childOrdinal = childNodeIndex / nodeFieldCount;
8225
+ if (childOrdinal === ordinal || isFixed.getBit(childOrdinal)) {
8226
+ continue;
8227
+ }
8228
+ const merged = this.mergeNativeContextOwner(attribution[childOrdinal], current);
8229
+ if (merged !== attribution[childOrdinal]) {
8230
+ attribution[childOrdinal] = merged;
8231
+ queue.push(childOrdinal);
8232
+ }
8233
+ }
8234
+ }
8235
+ }
8236
+ getNativeContextSizes() {
8237
+ return this.#nativeContextSizes;
8238
+ }
8239
+ getRetainedByContextSummary() {
8240
+ const isRetainedByContext = this.createNamedFilter('objectsRetainedByContexts');
8241
+ let contextCount = 0;
8242
+ let retainedByContextSize = 0;
8243
+ let retainedByContextCount = 0;
8244
+ let notRetainedByContextSize = 0;
8245
+ let notRetainedByContextCount = 0;
8246
+ const node = this.rootNode();
8247
+ const { nodes, nodeFieldCount, nodeSelfSizeOffset: selfSizeOffset } = this;
8248
+ const nodesLength = nodes.length;
8249
+ for (let nodeIndex = 0; nodeIndex < nodesLength; nodeIndex += nodeFieldCount) {
8250
+ const selfSize = nodes.getValue(nodeIndex + selfSizeOffset);
8251
+ if (!selfSize) {
8252
+ continue;
8253
+ }
8254
+ node.nodeIndex = nodeIndex;
8255
+ if (isRetainedByContext(node)) {
8256
+ retainedByContextCount++;
8257
+ retainedByContextSize += selfSize;
8258
+ }
8259
+ else {
8260
+ notRetainedByContextCount++;
8261
+ notRetainedByContextSize += selfSize;
8262
+ }
8263
+ if (this.isContextObject(node)) {
8264
+ contextCount++;
8265
+ }
8266
+ }
8267
+ return {
8268
+ contextCount,
8269
+ retainedByContextSize,
8270
+ retainedByContextCount,
8271
+ notRetainedByContextSize,
8272
+ notRetainedByContextCount,
8273
+ totalSize: retainedByContextSize + notRetainedByContextSize,
8274
+ };
8275
+ }
8276
+ nodeNativeContext(nodeIndex) {
8277
+ const ordinal = nodeIndex / this.nodeFieldCount;
8278
+ const nativeContextOrdinal = this.nodeNativeContextAttribution[ordinal];
8279
+ if (nativeContextOrdinal < 0) {
8280
+ return nativeContextOrdinal;
8281
+ }
8282
+ return nativeContextOrdinal * this.nodeFieldCount;
8283
+ }
8284
+ isNativeContext(nodeOrdinal) {
8285
+ const nameIdx = this.nodes.getValue(nodeOrdinal * this.nodeFieldCount + this.nodeNameOffset);
8286
+ const name = this.strings[nameIdx];
8287
+ return name === 'system / NativeContext' || name.startsWith('system / NativeContext / ') ||
8288
+ name === 'Detached system / NativeContext' || name.startsWith('Detached system / NativeContext / ');
8289
+ }
7943
8290
  interfaceDefinitions() {
7944
8291
  return JSON.stringify(this.#interfaceDefinitions ?? []);
7945
8292
  }
@@ -8114,11 +8461,32 @@ class HeapSnapshot {
8114
8461
  }
8115
8462
  return null;
8116
8463
  }
8464
+ initDetachednessAndClassIndex() {
8465
+ this.detachednessAndClassIndexArray = new Uint32Array(this.nodeCount);
8466
+ if (this.nodeDetachednessAndClassIndexOffset !== -1) {
8467
+ const { nodeFieldCount, nodeDetachednessAndClassIndexOffset: offset } = this;
8468
+ for (let i = 0; i < this.nodeCount; ++i) {
8469
+ this.detachednessAndClassIndexArray[i] = Number(this.nodes.getValue(i * nodeFieldCount + offset));
8470
+ }
8471
+ }
8472
+ else {
8473
+ const node = this.rootNode();
8474
+ const nodesLength = this.nodes.length;
8475
+ const { nodeFieldCount, nodeNativeType, nodeTypeOffset } = this;
8476
+ for (let nodeIndex = 0; nodeIndex < nodesLength; nodeIndex += nodeFieldCount) {
8477
+ if (this.nodes.getValue(nodeIndex + nodeTypeOffset) === nodeNativeType) {
8478
+ node.nodeIndex = nodeIndex;
8479
+ if (node.name().startsWith('Detached ')) {
8480
+ node.setDetachedness(2 );
8481
+ }
8482
+ }
8483
+ }
8484
+ }
8485
+ }
8117
8486
  propagateDOMState() {
8118
8487
  if (this.nodeDetachednessAndClassIndexOffset === -1) {
8119
8488
  return;
8120
8489
  }
8121
- console.time('propagateDOMState');
8122
8490
  const visited = new Uint8Array(this.nodeCount);
8123
8491
  const attached = [];
8124
8492
  const detached = [];
@@ -8177,7 +8545,6 @@ class HeapSnapshot {
8177
8545
  }
8178
8546
  propagateState(this, nodeOrdinal, 2 );
8179
8547
  }
8180
- console.timeEnd('propagateDOMState');
8181
8548
  }
8182
8549
  buildSamples() {
8183
8550
  const samples = this.#rawSamples;
@@ -8282,6 +8649,8 @@ class HeapSnapshot {
8282
8649
  const nodeAId = baseIds[i];
8283
8650
  if (nodeAId < nodeB.id()) {
8284
8651
  diff.deletedIndexes.push(baseIndexes[i]);
8652
+ diff.deletedIds.push(nodeAId);
8653
+ diff.deletedSelfSizes.push(baseSelfSizes[i]);
8285
8654
  diff.removedCount++;
8286
8655
  diff.removedSize += baseSelfSizes[i];
8287
8656
  ++i;
@@ -8289,6 +8658,8 @@ class HeapSnapshot {
8289
8658
  else if (nodeAId >
8290
8659
  nodeB.id()) {
8291
8660
  diff.addedIndexes.push(indexes[j]);
8661
+ diff.addedIds.push(nodeB.id());
8662
+ diff.addedSelfSizes.push(nodeB.selfSize());
8292
8663
  diff.addedCount++;
8293
8664
  diff.addedSize += nodeB.selfSize();
8294
8665
  nodeB.nodeIndex = indexes[++j];
@@ -8300,12 +8671,16 @@ class HeapSnapshot {
8300
8671
  }
8301
8672
  while (i < l) {
8302
8673
  diff.deletedIndexes.push(baseIndexes[i]);
8674
+ diff.deletedIds.push(baseIds[i]);
8675
+ diff.deletedSelfSizes.push(baseSelfSizes[i]);
8303
8676
  diff.removedCount++;
8304
8677
  diff.removedSize += baseSelfSizes[i];
8305
8678
  ++i;
8306
8679
  }
8307
8680
  while (j < m) {
8308
8681
  diff.addedIndexes.push(indexes[j]);
8682
+ diff.addedIds.push(nodeB.id());
8683
+ diff.addedSelfSizes.push(nodeB.selfSize());
8309
8684
  diff.addedCount++;
8310
8685
  diff.addedSize += nodeB.selfSize();
8311
8686
  nodeB.nodeIndex = indexes[++j];
@@ -8335,11 +8710,54 @@ class HeapSnapshot {
8335
8710
  }
8336
8711
  return null;
8337
8712
  }
8338
- createEdgesProvider(nodeIndex) {
8713
+ createEdgesProvider(nodeIndex, options) {
8339
8714
  const node = this.createNode(nodeIndex);
8340
- const filter = this.containmentEdgesFilter();
8715
+ const defaultFilter = this.containmentEdgesFilter();
8716
+ const minRetainedSize = options?.minRetainedSize;
8717
+ const excludePrimitives = options?.excludePrimitives ?? false;
8718
+ let filter = defaultFilter;
8719
+ if (minRetainedSize !== undefined || excludePrimitives) {
8720
+ filter = (edge) => {
8721
+ if (defaultFilter && !defaultFilter(edge)) {
8722
+ return false;
8723
+ }
8724
+ const targetNode = edge.node();
8725
+ if (minRetainedSize !== undefined && targetNode.retainedSize() < minRetainedSize) {
8726
+ return false;
8727
+ }
8728
+ if (excludePrimitives) {
8729
+ const rawType = targetNode.rawType();
8730
+ if (rawType === this.nodeNumberType) {
8731
+ return false;
8732
+ }
8733
+ if (rawType === this.nodeNativeType) {
8734
+ const targetName = targetNode.rawName();
8735
+ if (targetName === 'undefined' || targetName === 'null' || targetName === 'true' ||
8736
+ targetName === 'false') {
8737
+ return false;
8738
+ }
8739
+ }
8740
+ }
8741
+ return true;
8742
+ };
8743
+ }
8341
8744
  const indexProvider = new HeapSnapshotEdgeIndexProvider(this);
8342
- return new HeapSnapshotEdgesProvider(this, filter, node.edges(), indexProvider);
8745
+ const provider = new HeapSnapshotEdgesProvider(this, filter, node.edges(), indexProvider);
8746
+ if (options?.sortBy) {
8747
+ const sortBy = options.sortBy;
8748
+ let comparator;
8749
+ if (sortBy === 'selfSize') {
8750
+ comparator = new ComparatorConfig('selfSize', false, '!edgeName', true);
8751
+ }
8752
+ else if (sortBy === 'name') {
8753
+ comparator = new ComparatorConfig('!edgeName', true, 'retainedSize', false);
8754
+ }
8755
+ else {
8756
+ comparator = new ComparatorConfig('retainedSize', false, '!edgeName', true);
8757
+ }
8758
+ provider.sortAndRewind(comparator);
8759
+ }
8760
+ return provider;
8343
8761
  }
8344
8762
  createEdgesProviderForTest(nodeIndex, filter) {
8345
8763
  const node = this.createNode(nodeIndex);
@@ -8358,6 +8776,133 @@ class HeapSnapshot {
8358
8776
  const indexProvider = new HeapSnapshotRetainerEdgeIndexProvider(this);
8359
8777
  return new HeapSnapshotEdgesProvider(this, filter, node.retainers(), indexProvider);
8360
8778
  }
8779
+ getRetainingPaths(nodeIndex, maxDepth = 30, maxNodes = 5000, maxSiblings = 100) {
8780
+ const { nodeFieldCount, firstRetainerIndex, retainingNodes, retainingEdges, edgeTypeOffset, edgeWeakType, containmentEdges, } = this;
8781
+ const distances = this.#nodeDistancesForRetainersView ?? this.nodeDistances;
8782
+ let traversedNodesCount = 0;
8783
+ const visiting = new Set();
8784
+ const visited = new Map();
8785
+ const rootDistance = 2;
8786
+ const limitsReached = {};
8787
+ const buildForest = (currentIndex, currentDepth) => {
8788
+ traversedNodesCount++;
8789
+ if (traversedNodesCount > maxNodes) {
8790
+ limitsReached.nodes = true;
8791
+ return [];
8792
+ }
8793
+ if (currentDepth >= maxDepth) {
8794
+ limitsReached.depth = true;
8795
+ return [];
8796
+ }
8797
+ const ordinal = currentIndex / nodeFieldCount;
8798
+ const currentDistance = distances[ordinal];
8799
+ if (currentDistance <= rootDistance) {
8800
+ return [];
8801
+ }
8802
+ if (visiting.has(currentIndex)) {
8803
+ return [];
8804
+ }
8805
+ const cachedDepth = visited.get(currentIndex);
8806
+ if (cachedDepth !== undefined) {
8807
+ if (currentDepth >= cachedDepth) {
8808
+ return [];
8809
+ }
8810
+ }
8811
+ visiting.add(currentIndex);
8812
+ const beginRetainerIndex = firstRetainerIndex[ordinal];
8813
+ const endRetainerIndex = firstRetainerIndex[ordinal + 1];
8814
+ const retainers = [];
8815
+ for (let retainerIndex = beginRetainerIndex; retainerIndex < endRetainerIndex; ++retainerIndex) {
8816
+ const retainerNodeIndex = retainingNodes[retainerIndex];
8817
+ const retainerNodeOrdinal = retainerNodeIndex / nodeFieldCount;
8818
+ const dist = distances[retainerNodeOrdinal];
8819
+ const globalEdgeIndex = retainingEdges[retainerIndex];
8820
+ if (this.isEdgeIgnoredInRetainersView(globalEdgeIndex)) {
8821
+ continue;
8822
+ }
8823
+ const edgeType = containmentEdges.getValue(globalEdgeIndex + edgeTypeOffset);
8824
+ if (edgeType === edgeWeakType) {
8825
+ continue;
8826
+ }
8827
+ if (dist >= 0) {
8828
+ const remainingDepth = maxDepth - currentDepth;
8829
+ const neededDepth = dist - rootDistance;
8830
+ if (neededDepth < remainingDepth) {
8831
+ retainers.push({ retainerIndex, dist, nodeIndex: retainerNodeIndex });
8832
+ }
8833
+ else {
8834
+ limitsReached.depth = true;
8835
+ }
8836
+ }
8837
+ }
8838
+ retainers.sort((a, b) => a.dist - b.dist);
8839
+ const length = Math.min(retainers.length, maxSiblings);
8840
+ if (retainers.length > maxSiblings) {
8841
+ limitsReached.siblings = true;
8842
+ }
8843
+ const forest = [];
8844
+ for (let i = 0; i < length; i++) {
8845
+ const retainer = retainers[i];
8846
+ const edge = this.createRetainingEdge(retainer.retainerIndex);
8847
+ const globalEdgeIndex = retainingEdges[retainer.retainerIndex];
8848
+ const isRoot = retainer.dist === rootDistance;
8849
+ let children = [];
8850
+ if (isRoot) {
8851
+ traversedNodesCount++;
8852
+ if (traversedNodesCount > maxNodes) {
8853
+ limitsReached.nodes = true;
8854
+ break;
8855
+ }
8856
+ }
8857
+ else {
8858
+ children = buildForest(retainer.nodeIndex, currentDepth + 1);
8859
+ if (children.length === 0) {
8860
+ continue;
8861
+ }
8862
+ }
8863
+ const retainerNode = this.createNode(retainer.nodeIndex);
8864
+ forest.push({
8865
+ edgeIndex: globalEdgeIndex,
8866
+ edgeName: edge.name(),
8867
+ edgeType: edge.type(),
8868
+ nodeId: retainerNode.id(),
8869
+ nodeIndex: retainer.nodeIndex,
8870
+ nodeName: retainerNode.name(),
8871
+ distance: retainer.dist,
8872
+ children,
8873
+ });
8874
+ }
8875
+ visiting.delete(currentIndex);
8876
+ visited.set(currentIndex, currentDepth);
8877
+ return forest;
8878
+ };
8879
+ const paths = buildForest(nodeIndex, 0);
8880
+ return { paths, limitsReached };
8881
+ }
8882
+ getDominatorsOf(nodeIndex) {
8883
+ const chain = [];
8884
+ let currentIndex = nodeIndex;
8885
+ const rootIndex = this.rootNodeIndex;
8886
+ while (currentIndex !== undefined) {
8887
+ const node = this.createNode(currentIndex);
8888
+ chain.push({
8889
+ nodeId: node.id(),
8890
+ nodeIndex: currentIndex,
8891
+ nodeName: node.name(),
8892
+ retainedSize: node.retainedSize(),
8893
+ selfSize: node.selfSize(),
8894
+ });
8895
+ if (currentIndex === rootIndex) {
8896
+ break;
8897
+ }
8898
+ const nextIndex = node.dominatorIndex();
8899
+ if (nextIndex === currentIndex) {
8900
+ break;
8901
+ }
8902
+ currentIndex = nextIndex;
8903
+ }
8904
+ return chain;
8905
+ }
8361
8906
  createAddedNodesProvider(baseSnapshotId, classKey) {
8362
8907
  const snapshotDiff = this.#snapshotDiffs[baseSnapshotId];
8363
8908
  const diffForClass = snapshotDiff[classKey];
@@ -8369,6 +8914,85 @@ class HeapSnapshot {
8369
8914
  createNodesProviderForClass(classKey, nodeFilter) {
8370
8915
  return new HeapSnapshotNodesProvider(this, this.aggregatesWithFilter(nodeFilter)[classKey].idxs);
8371
8916
  }
8917
+ queryObjects(queryOptions) {
8918
+ const { nodes, nodeFieldCount, retainedSizes } = this;
8919
+ const nodesLength = nodes.length;
8920
+ const matchingIndexes = [];
8921
+ const classNamePattern = queryOptions.className ? new RegExp(queryOptions.className, 'i') : null;
8922
+ const propertyNamePattern = queryOptions.propertyName ? new RegExp(queryOptions.propertyName, 'i') : null;
8923
+ const targetNodeType = queryOptions.nodeType ? queryOptions.nodeType.toLowerCase() : null;
8924
+ const node = this.rootNode();
8925
+ for (let nodeIndex = 0, ordinal = 0; nodeIndex < nodesLength; nodeIndex += nodeFieldCount, ordinal++) {
8926
+ node.nodeIndex = nodeIndex;
8927
+ if (queryOptions.minSelfSize !== undefined && node.selfSize() < queryOptions.minSelfSize) {
8928
+ continue;
8929
+ }
8930
+ if (queryOptions.maxSelfSize !== undefined && node.selfSize() > queryOptions.maxSelfSize) {
8931
+ continue;
8932
+ }
8933
+ const retainedSize = retainedSizes[ordinal];
8934
+ if (queryOptions.minRetainedSize !== undefined && retainedSize < queryOptions.minRetainedSize) {
8935
+ continue;
8936
+ }
8937
+ if (queryOptions.maxRetainedSize !== undefined && retainedSize > queryOptions.maxRetainedSize) {
8938
+ continue;
8939
+ }
8940
+ if (queryOptions.isDetached !== undefined) {
8941
+ const isDetached = node.detachedness() === 2 ;
8942
+ if (isDetached !== queryOptions.isDetached) {
8943
+ continue;
8944
+ }
8945
+ }
8946
+ if (classNamePattern) {
8947
+ const name = node.name();
8948
+ if (!classNamePattern.test(name)) {
8949
+ continue;
8950
+ }
8951
+ }
8952
+ if (targetNodeType) {
8953
+ const typeStr = node.type();
8954
+ if (typeStr.toLowerCase() !== targetNodeType) {
8955
+ continue;
8956
+ }
8957
+ }
8958
+ if (propertyNamePattern) {
8959
+ let propMatch = false;
8960
+ for (const iter = node.edges(); iter.hasNext(); iter.next()) {
8961
+ if (propertyNamePattern.test(iter.edge.name())) {
8962
+ propMatch = true;
8963
+ break;
8964
+ }
8965
+ }
8966
+ if (!propMatch) {
8967
+ continue;
8968
+ }
8969
+ }
8970
+ matchingIndexes.push(nodeIndex);
8971
+ }
8972
+ const sortBy = queryOptions.sortBy ?? 'retainedSize';
8973
+ if (sortBy === 'retainedSize') {
8974
+ matchingIndexes.sort((a, b) => retainedSizes[b / nodeFieldCount] - retainedSizes[a / nodeFieldCount]);
8975
+ }
8976
+ else if (sortBy === 'selfSize') {
8977
+ matchingIndexes.sort((a, b) => {
8978
+ node.nodeIndex = b;
8979
+ const sizeB = node.selfSize();
8980
+ node.nodeIndex = a;
8981
+ const sizeA = node.selfSize();
8982
+ return sizeB - sizeA;
8983
+ });
8984
+ }
8985
+ else if (sortBy === 'id') {
8986
+ matchingIndexes.sort((a, b) => {
8987
+ node.nodeIndex = b;
8988
+ const idB = node.id();
8989
+ node.nodeIndex = a;
8990
+ const idA = node.id();
8991
+ return idA - idB;
8992
+ });
8993
+ }
8994
+ return new HeapSnapshotNodesProvider(this, matchingIndexes);
8995
+ }
8372
8996
  maxJsNodeId() {
8373
8997
  const nodeFieldCount = this.nodeFieldCount;
8374
8998
  const nodes = this.nodes;
@@ -8852,6 +9476,10 @@ class JSHeapSnapshot extends HeapSnapshot {
8852
9476
  isUserRoot(node) {
8853
9477
  return node.isUserRoot() || node.isDocumentDOMTreesRoot();
8854
9478
  }
9479
+ isContextObject(node) {
9480
+ const name = node.rawName();
9481
+ return name === 'system / Context' || name.startsWith('system / Context / ');
9482
+ }
8855
9483
  userObjectsMapAndFlag() {
8856
9484
  return { map: this.flags, flag: this.nodeFlags.pageObject };
8857
9485
  }
@@ -8872,7 +9500,7 @@ class JSHeapSnapshot extends HeapSnapshot {
8872
9500
  continue;
8873
9501
  }
8874
9502
  node.nodeIndex = nodeIndex;
8875
- if (node.name().startsWith('Detached ')) {
9503
+ if (node.detachedness() === 2 ) {
8876
9504
  this.flags[ordinal] |= flag;
8877
9505
  }
8878
9506
  }
@@ -9026,7 +9654,7 @@ class JSHeapSnapshot extends HeapSnapshot {
9026
9654
  jsArrays: sizeJSArrays,
9027
9655
  strings: sizeStrings,
9028
9656
  system: sizeSystem,
9029
- }
9657
+ },
9030
9658
  };
9031
9659
  }
9032
9660
  calculateArraySize(node) {
@@ -9708,4 +10336,3 @@ class HeapSnapshotWorkerDispatcher {
9708
10336
  const dispatcher = new HeapSnapshotWorkerDispatcher(HOST_RUNTIME.workerScope.postMessage.bind(HOST_RUNTIME.workerScope));
9709
10337
  HOST_RUNTIME.workerScope.onmessage = dispatcher.dispatchMessage.bind(dispatcher);
9710
10338
  HOST_RUNTIME.workerScope.postMessage('workerReady');
9711
- //# sourceMappingURL=devtools-heap-snapshot-worker.js.map