@paulirish/trace_engine 0.0.36 → 0.0.38

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 (162) hide show
  1. package/.tmp/tsbuildinfo/tsconfig.tsbuildinfo +1 -1
  2. package/core/platform/NumberUtilities.d.ts +0 -1
  3. package/core/platform/NumberUtilities.js +0 -17
  4. package/core/platform/NumberUtilities.js.map +1 -1
  5. package/core/platform/PromiseUtilities.d.ts +10 -0
  6. package/core/platform/PromiseUtilities.js +18 -0
  7. package/core/platform/PromiseUtilities.js.map +1 -0
  8. package/core/platform/SetUtilities.d.ts +2 -0
  9. package/core/platform/SetUtilities.js +23 -0
  10. package/core/platform/SetUtilities.js.map +1 -0
  11. package/generated/protocol.d.ts +57 -11
  12. package/models/trace/EntriesFilter.d.ts +72 -0
  13. package/models/trace/EntriesFilter.js +296 -0
  14. package/models/trace/EntriesFilter.js.map +1 -0
  15. package/models/trace/LegacyTracingModel.js.map +1 -0
  16. package/models/trace/Processor.d.ts +1 -1
  17. package/models/trace/Processor.js +4 -4
  18. package/models/trace/Processor.js.map +1 -1
  19. package/models/trace/extras/Metadata.d.ts +2 -1
  20. package/models/trace/extras/Metadata.js +23 -4
  21. package/models/trace/extras/Metadata.js.map +1 -1
  22. package/models/trace/extras/TimelineJSProfile.d.ts +13 -0
  23. package/models/trace/extras/TimelineJSProfile.js +55 -0
  24. package/models/trace/extras/TimelineJSProfile.js.map +1 -0
  25. package/models/trace/extras/TraceFilter.d.ts +21 -0
  26. package/models/trace/extras/TraceFilter.js +51 -0
  27. package/models/trace/extras/TraceFilter.js.map +1 -0
  28. package/models/trace/extras/TraceTree.d.ts +94 -0
  29. package/models/trace/extras/TraceTree.js +530 -0
  30. package/models/trace/extras/TraceTree.js.map +1 -0
  31. package/models/trace/extras/URLForEntry.d.ts +6 -5
  32. package/models/trace/extras/URLForEntry.js +6 -5
  33. package/models/trace/extras/URLForEntry.js.map +1 -1
  34. package/models/trace/extras/extras-tsconfig.json +3 -0
  35. package/models/trace/extras/extras.js.map +1 -1
  36. package/models/trace/handlers/EnhancedTracesHandler.d.ts +48 -0
  37. package/models/trace/handlers/EnhancedTracesHandler.js +165 -0
  38. package/models/trace/handlers/EnhancedTracesHandler.js.map +1 -0
  39. package/models/trace/handlers/FlowsHandler.d.ts +7 -0
  40. package/models/trace/handlers/FlowsHandler.js +157 -0
  41. package/models/trace/handlers/FlowsHandler.js.map +1 -0
  42. package/models/trace/handlers/ImagePaintingHandler.d.ts +1 -0
  43. package/models/trace/handlers/ImagePaintingHandler.js +8 -0
  44. package/models/trace/handlers/ImagePaintingHandler.js.map +1 -1
  45. package/models/trace/handlers/LargestImagePaintHandler.d.ts +7 -1
  46. package/models/trace/handlers/LargestImagePaintHandler.js +43 -1
  47. package/models/trace/handlers/LargestImagePaintHandler.js.map +1 -1
  48. package/models/trace/handlers/MetaHandler.js +2 -3
  49. package/models/trace/handlers/MetaHandler.js.map +1 -1
  50. package/models/trace/handlers/ModelHandlers.d.ts +1 -0
  51. package/models/trace/handlers/ModelHandlers.js +1 -0
  52. package/models/trace/handlers/ModelHandlers.js.map +1 -1
  53. package/models/trace/handlers/NetworkRequestsHandler.js +2 -0
  54. package/models/trace/handlers/NetworkRequestsHandler.js.map +1 -1
  55. package/models/trace/handlers/PageLoadMetricsHandler.d.ts +2 -1
  56. package/models/trace/handlers/PageLoadMetricsHandler.js.map +1 -1
  57. package/models/trace/handlers/handlers-tsconfig.json +1 -0
  58. package/models/trace/helpers/Timing.d.ts +1 -0
  59. package/models/trace/helpers/Timing.js +7 -0
  60. package/models/trace/helpers/Timing.js.map +1 -1
  61. package/models/trace/insights/CLSCulprits.d.ts +57 -0
  62. package/models/trace/insights/CLSCulprits.js +364 -0
  63. package/models/trace/insights/CLSCulprits.js.map +1 -0
  64. package/models/trace/insights/Common.d.ts +2 -10
  65. package/models/trace/insights/Common.js +1 -36
  66. package/models/trace/insights/Common.js.map +1 -1
  67. package/models/trace/insights/CumulativeLayoutShift.d.ts +13 -36
  68. package/models/trace/insights/CumulativeLayoutShift.js +73 -199
  69. package/models/trace/insights/CumulativeLayoutShift.js.map +1 -1
  70. package/models/trace/insights/DocumentLatency.d.ts +3 -3
  71. package/models/trace/insights/DocumentLatency.js +31 -3
  72. package/models/trace/insights/DocumentLatency.js.map +1 -1
  73. package/models/trace/insights/FontDisplay.d.ts +3 -3
  74. package/models/trace/insights/FontDisplay.js +23 -2
  75. package/models/trace/insights/FontDisplay.js.map +1 -1
  76. package/models/trace/insights/ImageDelivery.d.ts +23 -0
  77. package/models/trace/insights/ImageDelivery.js +130 -0
  78. package/models/trace/insights/ImageDelivery.js.map +1 -0
  79. package/models/trace/insights/InsightRunners.d.ts +0 -3
  80. package/models/trace/insights/InsightRunners.js +0 -3
  81. package/models/trace/insights/InsightRunners.js.map +1 -1
  82. package/models/trace/insights/InteractionToNextPaint.d.ts +3 -3
  83. package/models/trace/insights/InteractionToNextPaint.js +26 -3
  84. package/models/trace/insights/InteractionToNextPaint.js.map +1 -1
  85. package/models/trace/insights/LCPDiscovery.d.ts +13 -0
  86. package/models/trace/insights/LCPDiscovery.js +87 -0
  87. package/models/trace/insights/LCPDiscovery.js.map +1 -0
  88. package/models/trace/insights/LCPPhases.d.ts +34 -0
  89. package/models/trace/insights/LCPPhases.js +129 -0
  90. package/models/trace/insights/LCPPhases.js.map +1 -0
  91. package/models/trace/insights/LargestContentfulPaint.d.ts +7 -20
  92. package/models/trace/insights/LargestContentfulPaint.js +37 -57
  93. package/models/trace/insights/LargestContentfulPaint.js.map +1 -1
  94. package/models/trace/insights/Models.d.ts +11 -0
  95. package/models/trace/insights/Models.js +15 -0
  96. package/models/trace/insights/Models.js.map +1 -0
  97. package/models/trace/insights/RenderBlocking.d.ts +4 -4
  98. package/models/trace/insights/RenderBlocking.js +32 -23
  99. package/models/trace/insights/RenderBlocking.js.map +1 -1
  100. package/models/trace/insights/SlowCSSSelector.d.ts +3 -3
  101. package/models/trace/insights/SlowCSSSelector.js +27 -4
  102. package/models/trace/insights/SlowCSSSelector.js.map +1 -1
  103. package/models/trace/insights/{ThirdPartyWeb.d.ts → ThirdParties.d.ts} +3 -3
  104. package/models/trace/insights/{ThirdPartyWeb.js → ThirdParties.js} +26 -3
  105. package/models/trace/insights/ThirdParties.js.map +1 -0
  106. package/models/trace/insights/Viewport.d.ts +3 -3
  107. package/models/trace/insights/Viewport.js +27 -7
  108. package/models/trace/insights/Viewport.js.map +1 -1
  109. package/models/trace/insights/insights-tsconfig.json +6 -4
  110. package/models/trace/insights/insights.d.ts +1 -1
  111. package/models/trace/insights/insights.js +1 -1
  112. package/models/trace/insights/insights.js.map +1 -1
  113. package/models/trace/insights/types.d.ts +21 -9
  114. package/models/trace/insights/types.js +7 -0
  115. package/models/trace/insights/types.js.map +1 -1
  116. package/models/trace/lantern/BaseNode.d.ts +91 -0
  117. package/models/trace/lantern/BaseNode.js +268 -0
  118. package/models/trace/lantern/BaseNode.js.map +1 -0
  119. package/models/trace/lantern/CPUNode.d.ts +24 -0
  120. package/models/trace/lantern/CPUNode.js +64 -0
  121. package/models/trace/lantern/CPUNode.js.map +1 -0
  122. package/models/trace/lantern/LanternError.d.ts +3 -0
  123. package/models/trace/lantern/LanternError.js +7 -0
  124. package/models/trace/lantern/LanternError.js.map +1 -0
  125. package/models/trace/lantern/MetricsModule.d.ts +11 -0
  126. package/models/trace/lantern/MetricsModule.js +14 -0
  127. package/models/trace/lantern/MetricsModule.js.map +1 -0
  128. package/models/trace/lantern/NetworkNode.d.ts +22 -0
  129. package/models/trace/lantern/NetworkNode.js +83 -0
  130. package/models/trace/lantern/NetworkNode.js.map +1 -0
  131. package/models/trace/lantern/PageDependencyGraph.d.ts +43 -0
  132. package/models/trace/lantern/PageDependencyGraph.js +509 -0
  133. package/models/trace/lantern/PageDependencyGraph.js.map +1 -0
  134. package/models/trace/lantern/SimulationModule.d.ts +17 -0
  135. package/models/trace/lantern/SimulationModule.js +13 -0
  136. package/models/trace/lantern/SimulationModule.js.map +1 -0
  137. package/models/trace/lantern/simulation/NetworkAnalyzer.d.ts +112 -0
  138. package/models/trace/lantern/simulation/NetworkAnalyzer.js +486 -0
  139. package/models/trace/lantern/simulation/NetworkAnalyzer.js.map +1 -0
  140. package/models/trace/trace-tsconfig.json +6 -0
  141. package/models/trace/types/File.d.ts +5 -0
  142. package/models/trace/types/File.js +3 -0
  143. package/models/trace/types/File.js.map +1 -1
  144. package/models/trace/types/TraceEvents.d.ts +27 -5
  145. package/models/trace/types/TraceEvents.js +17 -5
  146. package/models/trace/types/TraceEvents.js.map +1 -1
  147. package/models/trace/types/types-tsconfig.json +6 -0
  148. package/package.json +1 -1
  149. package/test/test-trace-engine.mjs +9 -7
  150. package/.tmp/tsbuildinfo/models/trace/LanternComputationData.d.ts +0 -46
  151. package/.tmp/tsbuildinfo/models/trace/LanternComputationData.d.ts.map +0 -1
  152. package/.tmp/tsbuildinfo/models/trace/LegacyTracingModel.d.ts +0 -2
  153. package/.tmp/tsbuildinfo/models/trace/LegacyTracingModel.d.ts.map +0 -1
  154. package/.tmp/tsbuildinfo/models/trace/ModelImpl.d.ts +0 -72
  155. package/.tmp/tsbuildinfo/models/trace/ModelImpl.d.ts.map +0 -1
  156. package/.tmp/tsbuildinfo/models/trace/Processor.d.ts +0 -25
  157. package/.tmp/tsbuildinfo/models/trace/Processor.d.ts.map +0 -1
  158. package/.tmp/tsbuildinfo/models/trace/TracingManager.d.ts +0 -2
  159. package/.tmp/tsbuildinfo/models/trace/TracingManager.d.ts.map +0 -1
  160. package/.tmp/tsbuildinfo/models/trace/trace.d.ts +0 -13
  161. package/.tmp/tsbuildinfo/models/trace/trace.d.ts.map +0 -1
  162. package/models/trace/insights/ThirdPartyWeb.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"URLForEntry.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/extras/URLForEntry.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAI7B,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAC;AAE3C;;;;;;;GAOG;AAEH,MAAM,UAAU,cAAc,CAC1B,WAAuC,EAAE,KAAyB;IACpE,IAAI,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;QACtC,OAAO,KAAK,CAAC,SAAS,CAAC,GAAsC,CAAC;IAChE,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1E,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAsC,CAAC;IAC9E,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,CAAC,yBAAyB,CAAC,KAAK,CAAC,EAAE,CAAC;QAClD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAsC,CAAC;IAChE,CAAC;IAED,qEAAqE;IACrE,IAAI,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;QACtC,MAAM,UAAU,GAAG,WAAW,CAAC,aAAa,CAAC,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC3E,OAAO,UAAU,CAAC,CAAC,CAAC,cAAc,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACrE,CAAC;IAED,0EAA0E;IAC1E,IAAI,KAAK,CAAC,MAAM,CAAC,kBAAkB,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,EAAE,YAAY,EAAE,CAAC;QACvE,MAAM,UAAU,GAAG,WAAW,CAAC,aAAa,CAAC,4BAA4B,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACvG,OAAO,UAAU,CAAC,CAAC,CAAC,cAAc,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACrE,CAAC;IAED,4DAA4D;IAC5D,IAAI,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;QACpC,OAAO,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAsC,CAAC;IACrE,CAAC;IAED,6EAA6E;IAC7E,IAAI,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAsC,CAAC;IAChE,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["// Copyright 2024 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport type * as Platform from '../../../core/platform/platform.js';\nimport type * as Handlers from '../handlers/handlers.js';\nimport * as Types from '../types/types.js';\n\n/**\n * Use this helper whenever resolving an URL's source mapping is not an\n * option. For example when processing non-ui data. Otherwise use the\n * helper SourceMapsResolver::resolvedURLForEntry\n *\n * If an URL will be displayed in the UI, it's likely you should not use\n * this helper and prefer the other option instead.\n */\n\nexport function getNonResolved(\n parsedTrace: Handlers.Types.ParsedTrace, entry: Types.Events.Event): Platform.DevToolsPath.UrlString|null {\n if (Types.Events.isProfileCall(entry)) {\n return entry.callFrame.url as Platform.DevToolsPath.UrlString;\n }\n\n if (entry.args?.data?.stackTrace && entry.args.data.stackTrace.length > 0) {\n return entry.args.data.stackTrace[0].url as Platform.DevToolsPath.UrlString;\n }\n\n if (Types.Events.isSyntheticNetworkRequest(entry)) {\n return entry.args.data.url as Platform.DevToolsPath.UrlString;\n }\n\n // DecodeImage events use the URL from the relevant PaintImage event.\n if (Types.Events.isDecodeImage(entry)) {\n const paintEvent = parsedTrace.ImagePainting.paintImageForEvent.get(entry);\n return paintEvent ? getNonResolved(parsedTrace, paintEvent) : null;\n }\n\n // DrawLazyPixelRef events use the URL from the relevant PaintImage event.\n if (Types.Events.isDrawLazyPixelRef(entry) && entry.args?.LazyPixelRef) {\n const paintEvent = parsedTrace.ImagePainting.paintImageByDrawLazyPixelRef.get(entry.args.LazyPixelRef);\n return paintEvent ? getNonResolved(parsedTrace, paintEvent) : null;\n }\n\n // ParseHTML events store the URL under beginData, not data.\n if (Types.Events.isParseHTML(entry)) {\n return entry.args.beginData.url as Platform.DevToolsPath.UrlString;\n }\n\n // For all other events, try to see if the URL is provided, else return null.\n if (entry.args?.data?.url) {\n return entry.args.data.url as Platform.DevToolsPath.UrlString;\n }\n\n return null;\n}\n"]}
1
+ {"version":3,"file":"URLForEntry.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/extras/URLForEntry.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAI7B,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAC;AAE3C;;;;;;;;GAQG;AAEH,MAAM,UAAU,cAAc,CAC1B,WAAuC,EAAE,KAAyB;IACpE,IAAI,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;QACtC,OAAO,KAAK,CAAC,SAAS,CAAC,GAAsC,CAAC;IAChE,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1E,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAsC,CAAC;IAC9E,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,CAAC,yBAAyB,CAAC,KAAK,CAAC,EAAE,CAAC;QAClD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAsC,CAAC;IAChE,CAAC;IAED,qEAAqE;IACrE,IAAI,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;QACtC,MAAM,UAAU,GAAG,WAAW,CAAC,aAAa,CAAC,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC3E,OAAO,UAAU,CAAC,CAAC,CAAC,cAAc,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACrE,CAAC;IAED,0EAA0E;IAC1E,IAAI,KAAK,CAAC,MAAM,CAAC,kBAAkB,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,EAAE,YAAY,EAAE,CAAC;QACvE,MAAM,UAAU,GAAG,WAAW,CAAC,aAAa,CAAC,4BAA4B,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACvG,OAAO,UAAU,CAAC,CAAC,CAAC,cAAc,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACrE,CAAC;IAED,4DAA4D;IAC5D,IAAI,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;QACpC,OAAO,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAsC,CAAC;IACrE,CAAC;IAED,6EAA6E;IAC7E,IAAI,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAsC,CAAC;IAChE,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["// Copyright 2024 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport type * as Platform from '../../../core/platform/platform.js';\nimport type * as Handlers from '../handlers/handlers.js';\nimport * as Types from '../types/types.js';\n\n/**\n * INSTEAD, you probably want `SourceMapsResolver.resolvedURLForEntry()`!\n * If an URL will be displayed in the UI, it's likely you should NOT use `getNonResolved`.\n *\n * Use `getNonResolved` method whenever resolving an URL's source mapping is not an\n * option. For example when processing non-ui data.\n *\n * TODO: migrate existing uses of this over to resolvedURLForEntry.\n */\n\nexport function getNonResolved(\n parsedTrace: Handlers.Types.ParsedTrace, entry: Types.Events.Event): Platform.DevToolsPath.UrlString|null {\n if (Types.Events.isProfileCall(entry)) {\n return entry.callFrame.url as Platform.DevToolsPath.UrlString;\n }\n\n if (entry.args?.data?.stackTrace && entry.args.data.stackTrace.length > 0) {\n return entry.args.data.stackTrace[0].url as Platform.DevToolsPath.UrlString;\n }\n\n if (Types.Events.isSyntheticNetworkRequest(entry)) {\n return entry.args.data.url as Platform.DevToolsPath.UrlString;\n }\n\n // DecodeImage events use the URL from the relevant PaintImage event.\n if (Types.Events.isDecodeImage(entry)) {\n const paintEvent = parsedTrace.ImagePainting.paintImageForEvent.get(entry);\n return paintEvent ? getNonResolved(parsedTrace, paintEvent) : null;\n }\n\n // DrawLazyPixelRef events use the URL from the relevant PaintImage event.\n if (Types.Events.isDrawLazyPixelRef(entry) && entry.args?.LazyPixelRef) {\n const paintEvent = parsedTrace.ImagePainting.paintImageByDrawLazyPixelRef.get(entry.args.LazyPixelRef);\n return paintEvent ? getNonResolved(parsedTrace, paintEvent) : null;\n }\n\n // ParseHTML events store the URL under beginData, not data.\n if (Types.Events.isParseHTML(entry)) {\n return entry.args.beginData.url as Platform.DevToolsPath.UrlString;\n }\n\n // For all other events, try to see if the URL is provided, else return null.\n if (entry.args?.data?.url) {\n return entry.args.data.url as Platform.DevToolsPath.UrlString;\n }\n\n return null;\n}\n"]}
@@ -34,6 +34,9 @@
34
34
  "../../../../../../../front_end/models/trace/extras/MainThreadActivity.ts",
35
35
  "../../../../../../../front_end/models/trace/extras/Metadata.ts",
36
36
  "../../../../../../../front_end/models/trace/extras/ThirdParties.ts",
37
+ "../../../../../../../front_end/models/trace/extras/TimelineJSProfile.ts",
38
+ "../../../../../../../front_end/models/trace/extras/TraceFilter.ts",
39
+ "../../../../../../../front_end/models/trace/extras/TraceTree.ts",
37
40
  "../../../../../../../front_end/models/trace/extras/URLForEntry.ts",
38
41
  "../../../../../../../front_end/legacy/legacy-defs.d.ts",
39
42
  "../../../../../../../front_end/global_typings/global_defs.d.ts",
@@ -1 +1 @@
1
- {"version":3,"file":"extras.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/extras/extras.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAE7B,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAC;AAC9C,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAC;AAC5C,OAAO,KAAK,kBAAkB,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAC1C,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAC","sourcesContent":["// Copyright 2023 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nexport * as FetchNodes from './FetchNodes.js';\nexport * as FilmStrip from './FilmStrip.js';\nexport * as MainThreadActivity from './MainThreadActivity.js';\nexport * as Metadata from './Metadata.js';\nexport * as ThirdParties from './ThirdParties.js';\nexport * as URLForEntry from './URLForEntry.js';\n"]}
1
+ {"version":3,"file":"extras.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/extras/extras.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAE7B,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAC;AAC9C,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAC;AAC5C,OAAO,KAAK,kBAAkB,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAC1C,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,iBAAiB,MAAM,wBAAwB,CAAC;AAC5D,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAC;AAChD,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAC;AAC5C,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAC","sourcesContent":["// Copyright 2023 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nexport * as FetchNodes from './FetchNodes.js';\nexport * as FilmStrip from './FilmStrip.js';\nexport * as MainThreadActivity from './MainThreadActivity.js';\nexport * as Metadata from './Metadata.js';\nexport * as ThirdParties from './ThirdParties.js';\nexport * as TimelineJSProfile from './TimelineJSProfile.js';\nexport * as TraceFilter from './TraceFilter.js';\nexport * as TraceTree from './TraceTree.js';\nexport * as URLForEntry from './URLForEntry.js';\n"]}
@@ -0,0 +1,48 @@
1
+ import * as Types from '../types/types.js';
2
+ export declare const EnhancedTracesVersion: number;
3
+ export interface Script {
4
+ scriptId: number;
5
+ isolate: string;
6
+ url: string;
7
+ executionContextId: number;
8
+ startLine: number;
9
+ startColumn: number;
10
+ endLine: number;
11
+ endColumn: number;
12
+ hash: string;
13
+ isModule?: boolean;
14
+ hasSourceUrl?: boolean;
15
+ sourceMapUrl?: string;
16
+ length?: number;
17
+ sourceText?: string;
18
+ auxData?: ExecutionContextAuxData;
19
+ }
20
+ export interface ExecutionContextAuxData {
21
+ frameId?: string;
22
+ isDefault?: boolean;
23
+ type?: string;
24
+ }
25
+ export interface ExecutionContext {
26
+ id: number;
27
+ origin: string;
28
+ v8Context?: string;
29
+ auxData?: ExecutionContextAuxData;
30
+ isolate?: string;
31
+ }
32
+ export interface Target {
33
+ targetId: string;
34
+ type: string;
35
+ url: string;
36
+ pid?: number;
37
+ isolate?: string;
38
+ }
39
+ export interface EnhancedTracesData {
40
+ targets: Target[];
41
+ executionContexts: ExecutionContext[];
42
+ scripts: Script[];
43
+ }
44
+ export declare function initialize(): void;
45
+ export declare function reset(): void;
46
+ export declare function handleEvent(event: Types.TraceEvents.TraceEventData): void;
47
+ export declare function finalize(): Promise<void>;
48
+ export declare function data(): EnhancedTracesData;
@@ -0,0 +1,165 @@
1
+ // Copyright 2024 The Chromium Authors. All rights reserved.
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+ import * as Types from '../types/types.js';
5
+ export const EnhancedTracesVersion = 1;
6
+ let handlerState = 1 /* HandlerState.UNINITIALIZED */;
7
+ const scriptRundownEvents = [];
8
+ const scriptToV8Context = new Map();
9
+ const scriptToScriptSource = new Map();
10
+ const largeScriptToScriptSource = new Map();
11
+ const scriptToSourceLength = new Map();
12
+ const targets = [];
13
+ const executionContexts = [];
14
+ const scripts = [];
15
+ function getScriptIsolateId(isolate, scriptId) {
16
+ return scriptId + '@' + isolate;
17
+ }
18
+ export function initialize() {
19
+ if (handlerState !== 1 /* HandlerState.UNINITIALIZED */) {
20
+ throw new Error('Enhanced Traces Handler was not reset');
21
+ }
22
+ handlerState = 2 /* HandlerState.INITIALIZED */;
23
+ }
24
+ export function reset() {
25
+ scriptRundownEvents.length = 0;
26
+ scriptToV8Context.clear();
27
+ scriptToScriptSource.clear();
28
+ largeScriptToScriptSource.clear();
29
+ scriptToSourceLength.clear();
30
+ targets.length = 0;
31
+ executionContexts.length = 0;
32
+ scripts.length = 0;
33
+ handlerState = 1 /* HandlerState.UNINITIALIZED */;
34
+ }
35
+ export function handleEvent(event) {
36
+ if (handlerState !== 2 /* HandlerState.INITIALIZED */) {
37
+ throw new Error('Enhanced Traces Handler is not initialized while handling event');
38
+ }
39
+ if (Types.TraceEvents.isTraceEventTargetRundown(event)) {
40
+ // Set up script to v8 context mapping
41
+ const data = event.args?.data;
42
+ scriptToV8Context.set(getScriptIsolateId(data.isolate, data.scriptId), data.v8context);
43
+ // Add target
44
+ if (!targets.find(target => target.targetId === data.frame)) {
45
+ targets.push({
46
+ targetId: data.frame,
47
+ type: data.frameType,
48
+ isolate: data.isolate,
49
+ pid: event.pid,
50
+ url: data.url,
51
+ });
52
+ }
53
+ // Add execution context, need to put back execution context id with info from other traces
54
+ if (!executionContexts.find(executionContext => executionContext.v8Context === data.v8context)) {
55
+ executionContexts.push({
56
+ id: -1,
57
+ origin: data.origin,
58
+ v8Context: data.v8context,
59
+ auxData: {
60
+ frameId: data.frame,
61
+ isDefault: data.isDefault,
62
+ type: data.contextType,
63
+ },
64
+ isolate: data.isolate,
65
+ });
66
+ }
67
+ }
68
+ else if (Types.TraceEvents.isTraceEventScriptRundown(event)) {
69
+ scriptRundownEvents.push(event);
70
+ const data = event.args.data;
71
+ // Add script
72
+ if (!scripts.find(script => script.scriptId === data.scriptId && script.isolate === data.isolate)) {
73
+ scripts.push({
74
+ scriptId: data.scriptId,
75
+ isolate: data.isolate,
76
+ executionContextId: data.executionContextId,
77
+ startLine: data.startLine,
78
+ startColumn: data.startColumn,
79
+ endLine: data.endLine,
80
+ endColumn: data.endColumn,
81
+ hash: data.hash,
82
+ isModule: data.isModule,
83
+ url: data.url,
84
+ hasSourceUrl: data.hasSourceUrl,
85
+ sourceMapUrl: data.sourceMapUrl,
86
+ });
87
+ }
88
+ }
89
+ else if (Types.TraceEvents.isTraceEventScriptRundownSource(event)) {
90
+ // Set up script to source text and length mapping
91
+ const data = event.args.data;
92
+ const scriptIsolateId = getScriptIsolateId(data.isolate, data.scriptId);
93
+ if ('splitIndex' in data && 'splitCount' in data) {
94
+ if (!largeScriptToScriptSource.has(scriptIsolateId)) {
95
+ largeScriptToScriptSource.set(scriptIsolateId, new Array(data.splitCount).fill(''));
96
+ }
97
+ const splittedSource = largeScriptToScriptSource.get(scriptIsolateId);
98
+ if (splittedSource && data.sourceText) {
99
+ splittedSource[data.splitIndex] = data.sourceText;
100
+ }
101
+ }
102
+ else {
103
+ if (data.sourceText) {
104
+ scriptToScriptSource.set(scriptIsolateId, data.sourceText);
105
+ }
106
+ if (data.length) {
107
+ scriptToSourceLength.set(scriptIsolateId, data.length);
108
+ }
109
+ }
110
+ }
111
+ }
112
+ export async function finalize() {
113
+ if (handlerState !== 2 /* HandlerState.INITIALIZED */) {
114
+ throw new Error('Enhanced Traces Handler is not initialized while being finalized');
115
+ }
116
+ // Put back execution context id
117
+ const v8ContextToExecutionContextId = new Map();
118
+ scriptRundownEvents.forEach(scriptRundownEvent => {
119
+ const data = scriptRundownEvent.args.data;
120
+ const v8Context = scriptToV8Context.get(getScriptIsolateId(data.isolate, data.scriptId));
121
+ if (v8Context) {
122
+ v8ContextToExecutionContextId.set(v8Context, data.executionContextId);
123
+ }
124
+ });
125
+ executionContexts.forEach(executionContext => {
126
+ if (executionContext.v8Context) {
127
+ const id = v8ContextToExecutionContextId.get(executionContext.v8Context);
128
+ if (id) {
129
+ executionContext.id = id;
130
+ }
131
+ }
132
+ });
133
+ // Put back script source text and length
134
+ scripts.forEach(script => {
135
+ const scriptIsolateId = getScriptIsolateId(script.isolate, script.scriptId);
136
+ if (scriptToScriptSource.has(scriptIsolateId)) {
137
+ script.sourceText = scriptToScriptSource.get(scriptIsolateId);
138
+ script.length = scriptToSourceLength.get(scriptIsolateId);
139
+ }
140
+ else if (largeScriptToScriptSource.has(scriptIsolateId)) {
141
+ const splittedSources = largeScriptToScriptSource.get(scriptIsolateId);
142
+ if (splittedSources) {
143
+ script.sourceText = splittedSources.join('');
144
+ script.length = script.sourceText.length;
145
+ }
146
+ }
147
+ // put in the aux data
148
+ script.auxData =
149
+ executionContexts
150
+ .find(context => context.id === script.executionContextId && context.isolate === script.isolate)
151
+ ?.auxData;
152
+ });
153
+ handlerState = 3 /* HandlerState.FINALIZED */;
154
+ }
155
+ export function data() {
156
+ if (handlerState !== 3 /* HandlerState.FINALIZED */) {
157
+ throw new Error('Enhanced Traces Handler is not finalized');
158
+ }
159
+ return {
160
+ targets: targets,
161
+ executionContexts: executionContexts,
162
+ scripts: scripts,
163
+ };
164
+ }
165
+ //# sourceMappingURL=EnhancedTracesHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EnhancedTracesHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/EnhancedTracesHandler.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Types from '../types/types.js';\n\nimport {HandlerState} from './types.js';\n\nexport const EnhancedTracesVersion: number = 1;\n\nexport interface Script {\n scriptId: number;\n isolate: string;\n url: string;\n executionContextId: number;\n startLine: number;\n startColumn: number;\n endLine: number;\n endColumn: number;\n hash: string;\n isModule?: boolean;\n hasSourceUrl?: boolean;\n sourceMapUrl?: string;\n length?: number;\n sourceText?: string;\n auxData?: ExecutionContextAuxData;\n}\n\nexport interface ExecutionContextAuxData {\n frameId?: string;\n isDefault?: boolean;\n type?: string;\n}\n\nexport interface ExecutionContext {\n id: number;\n origin: string;\n v8Context?: string;\n auxData?: ExecutionContextAuxData;\n isolate?: string;\n}\n\nexport interface Target {\n targetId: string;\n type: string;\n url: string;\n pid?: number;\n isolate?: string;\n}\n\nexport interface EnhancedTracesData {\n targets: Target[];\n executionContexts: ExecutionContext[];\n scripts: Script[];\n}\n\nlet handlerState = HandlerState.UNINITIALIZED;\n\nconst scriptRundownEvents: Types.TraceEvents.TraceEventScriptRundown[] = [];\nconst scriptToV8Context: Map<string, string> = new Map<string, string>();\nconst scriptToScriptSource: Map<string, string> = new Map<string, string>();\nconst largeScriptToScriptSource: Map<string, string[]> = new Map<string, string[]>();\nconst scriptToSourceLength: Map<string, number> = new Map<string, number>();\nconst targets: Target[] = [];\nconst executionContexts: ExecutionContext[] = [];\nconst scripts: Script[] = [];\n\nfunction getScriptIsolateId(isolate: string, scriptId: number): string {\n return scriptId + '@' + isolate;\n}\n\nexport function initialize(): void {\n if (handlerState !== HandlerState.UNINITIALIZED) {\n throw new Error('Enhanced Traces Handler was not reset');\n }\n\n handlerState = HandlerState.INITIALIZED;\n}\n\nexport function reset(): void {\n scriptRundownEvents.length = 0;\n scriptToV8Context.clear();\n scriptToScriptSource.clear();\n largeScriptToScriptSource.clear();\n scriptToSourceLength.clear();\n targets.length = 0;\n executionContexts.length = 0;\n scripts.length = 0;\n handlerState = HandlerState.UNINITIALIZED;\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('Enhanced Traces Handler is not initialized while handling event');\n }\n if (Types.TraceEvents.isTraceEventTargetRundown(event)) {\n // Set up script to v8 context mapping\n const data = event.args?.data;\n scriptToV8Context.set(getScriptIsolateId(data.isolate, data.scriptId), data.v8context);\n // Add target\n if (!targets.find(target => target.targetId === data.frame)) {\n targets.push({\n targetId: data.frame,\n type: data.frameType,\n isolate: data.isolate,\n pid: event.pid,\n url: data.url,\n });\n }\n // Add execution context, need to put back execution context id with info from other traces\n if (!executionContexts.find(executionContext => executionContext.v8Context === data.v8context)) {\n executionContexts.push({\n id: -1,\n origin: data.origin,\n v8Context: data.v8context,\n auxData: {\n frameId: data.frame,\n isDefault: data.isDefault,\n type: data.contextType,\n },\n isolate: data.isolate,\n });\n }\n } else if (Types.TraceEvents.isTraceEventScriptRundown(event)) {\n scriptRundownEvents.push(event);\n const data = event.args.data;\n // Add script\n if (!scripts.find(script => script.scriptId === data.scriptId && script.isolate === data.isolate)) {\n scripts.push({\n scriptId: data.scriptId,\n isolate: data.isolate,\n executionContextId: data.executionContextId,\n startLine: data.startLine,\n startColumn: data.startColumn,\n endLine: data.endLine,\n endColumn: data.endColumn,\n hash: data.hash,\n isModule: data.isModule,\n url: data.url,\n hasSourceUrl: data.hasSourceUrl,\n sourceMapUrl: data.sourceMapUrl,\n });\n }\n } else if (Types.TraceEvents.isTraceEventScriptRundownSource(event)) {\n // Set up script to source text and length mapping\n const data = event.args.data;\n const scriptIsolateId = getScriptIsolateId(data.isolate, data.scriptId);\n if ('splitIndex' in data && 'splitCount' in data) {\n if (!largeScriptToScriptSource.has(scriptIsolateId)) {\n largeScriptToScriptSource.set(scriptIsolateId, new Array(data.splitCount).fill('') as string[]);\n }\n const splittedSource = largeScriptToScriptSource.get(scriptIsolateId);\n if (splittedSource && data.sourceText) {\n splittedSource[data.splitIndex as number] = data.sourceText;\n }\n } else {\n if (data.sourceText) {\n scriptToScriptSource.set(scriptIsolateId, data.sourceText);\n }\n if (data.length) {\n scriptToSourceLength.set(scriptIsolateId, data.length);\n }\n }\n }\n}\n\nexport async function finalize(): Promise<void> {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('Enhanced Traces Handler is not initialized while being finalized');\n }\n // Put back execution context id\n const v8ContextToExecutionContextId: Map<string, number> = new Map<string, number>();\n scriptRundownEvents.forEach(scriptRundownEvent => {\n const data = scriptRundownEvent.args.data;\n const v8Context = scriptToV8Context.get(getScriptIsolateId(data.isolate, data.scriptId));\n if (v8Context) {\n v8ContextToExecutionContextId.set(v8Context, data.executionContextId);\n }\n });\n executionContexts.forEach(executionContext => {\n if (executionContext.v8Context) {\n const id = v8ContextToExecutionContextId.get(executionContext.v8Context);\n if (id) {\n executionContext.id = id;\n }\n }\n });\n\n // Put back script source text and length\n scripts.forEach(script => {\n const scriptIsolateId = getScriptIsolateId(script.isolate, script.scriptId);\n if (scriptToScriptSource.has(scriptIsolateId)) {\n script.sourceText = scriptToScriptSource.get(scriptIsolateId);\n script.length = scriptToSourceLength.get(scriptIsolateId);\n } else if (largeScriptToScriptSource.has(scriptIsolateId)) {\n const splittedSources = largeScriptToScriptSource.get(scriptIsolateId);\n if (splittedSources) {\n script.sourceText = splittedSources.join('');\n script.length = script.sourceText.length;\n }\n }\n // put in the aux data\n script.auxData =\n executionContexts\n .find(context => context.id === script.executionContextId && context.isolate === script.isolate)\n ?.auxData;\n });\n handlerState = HandlerState.FINALIZED;\n}\n\nexport function data(): EnhancedTracesData {\n if (handlerState !== HandlerState.FINALIZED) {\n throw new Error('Enhanced Traces Handler is not finalized');\n }\n\n return {\n targets: targets,\n executionContexts: executionContexts,\n scripts: scripts,\n };\n}\n"]}
@@ -0,0 +1,7 @@
1
+ import * as Types from '../types/types.js';
2
+ export declare function reset(): void;
3
+ export declare function handleEvent(event: Types.Events.Event): void;
4
+ export declare function finalize(): Promise<void>;
5
+ export declare function data(): {
6
+ flows: Types.Events.Event[][];
7
+ };
@@ -0,0 +1,157 @@
1
+ // Copyright 2024 The Chromium Authors. All rights reserved.
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+ import * as Types from '../types/types.js';
5
+ // A flow is a logic connection between trace events. We display this
6
+ // connection as arrows between trace events belonging to the same flow.
7
+ // In the trace event format, flows are represented with pairing "flow
8
+ // phase" events. Each flow phase event corresponds to one trace event
9
+ // and indicates the role a trace event plays in a flow (start, step or
10
+ // end). For each flow, one `start` and one `end` phase events are
11
+ // included, while the amount of `step` phase events can be >= 0.
12
+ // A flow phase event is assigned to a trace event when their cat, tid,
13
+ // pid and ts are equal (see @flowPhaseBindingTokenForEvent ).
14
+ // It's possible for a single event to belong to multiple flows. In that
15
+ // case, it will have multiple corresponding flow phase events (one
16
+ // per flow).
17
+ // To parse flows, we first handle flow phase events, by creating unique
18
+ // flows with the timestamps of each phase. Then, we place trace events
19
+ // in the flows where their corresponding phase events were placed (if
20
+ // there are any corresponding flow phase events at all).
21
+ const flowDataByGroupToken = new Map();
22
+ const flowPhaseBindingTokenToFlowId = new Map();
23
+ const flowsById = new Map();
24
+ const flowEvents = [];
25
+ const nonFlowEvents = [];
26
+ let flows = [];
27
+ const ID_COMPONENT_SEPARATOR = '-$-';
28
+ export function reset() {
29
+ flows = [];
30
+ flowEvents.length = 0;
31
+ nonFlowEvents.length = 0;
32
+ flowDataByGroupToken.clear();
33
+ flowPhaseBindingTokenToFlowId.clear();
34
+ flowsById.clear();
35
+ }
36
+ export function handleEvent(event) {
37
+ if (Types.Events.isFlowPhaseEvent(event)) {
38
+ flowEvents.push(event);
39
+ return;
40
+ }
41
+ nonFlowEvents.push(event);
42
+ }
43
+ function processNonFlowEvent(event) {
44
+ const flowPhaseBindingToken = flowPhaseBindingTokenForEvent(event);
45
+ const flowIds = flowPhaseBindingTokenToFlowId.get(flowPhaseBindingToken);
46
+ if (!flowIds) {
47
+ return;
48
+ }
49
+ for (const flowId of flowIds) {
50
+ const flow = flowsById.get(flowId);
51
+ if (!flow) {
52
+ continue;
53
+ }
54
+ const timeIndex = flow.times.indexOf(event.ts);
55
+ if (timeIndex < 0) {
56
+ continue;
57
+ }
58
+ flow.events[timeIndex] = event;
59
+ }
60
+ }
61
+ /**
62
+ * Creates unique flows by tracking flow phase events. A new created
63
+ * flow whenever a flow start phase event is detected.
64
+ * Subsequent flow phase events with the same group token are added to
65
+ * this flow until a flow end phase is detected.
66
+ */
67
+ function processFlowEvent(flowPhaseEvent) {
68
+ const flowGroup = flowGroupTokenForFlowPhaseEvent(flowPhaseEvent);
69
+ switch (flowPhaseEvent.ph) {
70
+ case ("s" /* Types.Events.Phase.FLOW_START */): {
71
+ const flowMetadata = { flowId: flowPhaseEvent.id, times: [flowPhaseEvent.ts] };
72
+ flowDataByGroupToken.set(flowGroup, flowMetadata);
73
+ addFlowIdToFlowPhaseBinding(flowPhaseBindingTokenForEvent(flowPhaseEvent), flowMetadata.flowId);
74
+ return;
75
+ }
76
+ case ("t" /* Types.Events.Phase.FLOW_STEP */): {
77
+ const flow = flowDataByGroupToken.get(flowGroup);
78
+ if (!flow || flow.times.length < 0) {
79
+ // Found non-start flow event with no corresponding start flow,
80
+ // start event. Quietly ignore problematic event.
81
+ return;
82
+ }
83
+ addFlowIdToFlowPhaseBinding(flowPhaseBindingTokenForEvent(flowPhaseEvent), flow.flowId);
84
+ flow.times.push(flowPhaseEvent.ts);
85
+ return;
86
+ }
87
+ case ("f" /* Types.Events.Phase.FLOW_END */): {
88
+ const flow = flowDataByGroupToken.get(flowGroup);
89
+ if (!flow || flow.times.length < 0) {
90
+ // Found non-start flow event with no corresponding start flow,
91
+ // start event. Quietly ignore problematic event.
92
+ return;
93
+ }
94
+ addFlowIdToFlowPhaseBinding(flowPhaseBindingTokenForEvent(flowPhaseEvent), flow.flowId);
95
+ flow.times.push(flowPhaseEvent.ts);
96
+ flowsById.set(flow.flowId, { times: flow.times, events: [] });
97
+ // We don't need this data anymore as the flow has been finished,
98
+ // so we can drop it.
99
+ flowDataByGroupToken.delete(flowGroup);
100
+ }
101
+ }
102
+ }
103
+ /**
104
+ * A single trace event can belong to multiple flows. This method
105
+ * tracks which flows (flowId) an event belongs to (given
106
+ * its flow phase binding token).
107
+ */
108
+ function addFlowIdToFlowPhaseBinding(flowPhaseBinding, flowId) {
109
+ let flowIds = flowPhaseBindingTokenToFlowId.get(flowPhaseBinding);
110
+ if (!flowIds) {
111
+ flowIds = new Set();
112
+ }
113
+ flowIds.add(flowId);
114
+ flowPhaseBindingTokenToFlowId.set(flowPhaseBinding, flowIds);
115
+ }
116
+ /**
117
+ * Returns a token to group flow phase events (start, step and end)
118
+ * belonging to the same flow. Flow phase events belonging to the same
119
+ * flow share category, thread id, process id and name.
120
+ *
121
+ * Note that other phase events of other flows can share these
122
+ * attributes too. For this reason, we group flow phase events in
123
+ * cycles. A cycle starts on a flow start phase event and finishes on a
124
+ * flow end phase event. For this reason, flow phase events need to be
125
+ * handled in timestamp order.
126
+ */
127
+ function flowGroupTokenForFlowPhaseEvent(event) {
128
+ return `${event.cat}${ID_COMPONENT_SEPARATOR}${event.name}${ID_COMPONENT_SEPARATOR}${event.id}`;
129
+ }
130
+ /**
131
+ * A flow phase binding is a token that allows us to associate a flow
132
+ * phase event to its corresponding event. This association indicates
133
+ * what role a trace event plays in a flow.
134
+ * We can assign a trace event with a flow phase when its category,
135
+ * thread id, process id and timestamp matches those of a flow phase
136
+ * event.
137
+ */
138
+ function flowPhaseBindingTokenForEvent(event) {
139
+ // This function is called many times (one per event) and creating a
140
+ // string every time can trigger GC. If this becomes a problem, a
141
+ // possible optimization is to use a multi-key map with the
142
+ // binding token components, a trade off between memory performance
143
+ // and readability.
144
+ return `${event.cat}${ID_COMPONENT_SEPARATOR}${event.tid}${ID_COMPONENT_SEPARATOR}${event.pid}${ID_COMPONENT_SEPARATOR}${event.ts}`;
145
+ }
146
+ export async function finalize() {
147
+ // Order is important: flow events need to be handled first.
148
+ flowEvents.forEach(processFlowEvent);
149
+ nonFlowEvents.forEach(processNonFlowEvent);
150
+ flows = [...flowsById.values()].map(f => f.events).filter(flow => flow.length > 1);
151
+ }
152
+ export function data() {
153
+ return {
154
+ flows,
155
+ };
156
+ }
157
+ //# sourceMappingURL=FlowsHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FlowsHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/FlowsHandler.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\nimport * as Types from '../types/types.js';\n\n// A flow is a logic connection between trace events. We display this\n// connection as arrows between trace events belonging to the same flow.\n\n// In the trace event format, flows are represented with pairing \"flow\n// phase\" events. Each flow phase event corresponds to one trace event\n// and indicates the role a trace event plays in a flow (start, step or\n// end). For each flow, one `start` and one `end` phase events are\n// included, while the amount of `step` phase events can be >= 0.\n\n// A flow phase event is assigned to a trace event when their cat, tid,\n// pid and ts are equal (see @flowPhaseBindingTokenForEvent ).\n\n// It's possible for a single event to belong to multiple flows. In that\n// case, it will have multiple corresponding flow phase events (one\n// per flow).\n\n// To parse flows, we first handle flow phase events, by creating unique\n// flows with the timestamps of each phase. Then, we place trace events\n// in the flows where their corresponding phase events were placed (if\n// there are any corresponding flow phase events at all).\nconst flowDataByGroupToken = new Map<string, {flowId: number, times: Types.Timing.MicroSeconds[]}>();\nconst flowPhaseBindingTokenToFlowId = new Map<string, Set<number>>();\nconst flowsById = new Map<number, {times: Types.Timing.MicroSeconds[], events: Types.Events.Event[]}>();\nconst flowEvents: Types.Events.FlowEvent[] = [];\nconst nonFlowEvents: Types.Events.Event[] = [];\nlet flows: Types.Events.Event[][] = [];\nconst ID_COMPONENT_SEPARATOR = '-$-';\nexport function reset(): void {\n flows = [];\n flowEvents.length = 0;\n nonFlowEvents.length = 0;\n flowDataByGroupToken.clear();\n flowPhaseBindingTokenToFlowId.clear();\n flowsById.clear();\n}\n\nexport function handleEvent(event: Types.Events.Event): void {\n if (Types.Events.isFlowPhaseEvent(event)) {\n flowEvents.push(event);\n return;\n }\n nonFlowEvents.push(event);\n}\n\nfunction processNonFlowEvent(event: Types.Events.Event): void {\n const flowPhaseBindingToken = flowPhaseBindingTokenForEvent(event);\n const flowIds = flowPhaseBindingTokenToFlowId.get(flowPhaseBindingToken);\n if (!flowIds) {\n return;\n }\n for (const flowId of flowIds) {\n const flow = flowsById.get(flowId);\n if (!flow) {\n continue;\n }\n const timeIndex = flow.times.indexOf(event.ts);\n if (timeIndex < 0) {\n continue;\n }\n flow.events[timeIndex] = event;\n }\n}\n\n/**\n * Creates unique flows by tracking flow phase events. A new created\n * flow whenever a flow start phase event is detected.\n * Subsequent flow phase events with the same group token are added to\n * this flow until a flow end phase is detected.\n */\nfunction processFlowEvent(flowPhaseEvent: Types.Events.FlowEvent): void {\n const flowGroup = flowGroupTokenForFlowPhaseEvent(flowPhaseEvent);\n switch (flowPhaseEvent.ph) {\n case (Types.Events.Phase.FLOW_START): {\n const flowMetadata = {flowId: flowPhaseEvent.id, times: [flowPhaseEvent.ts]};\n flowDataByGroupToken.set(flowGroup, flowMetadata);\n addFlowIdToFlowPhaseBinding(flowPhaseBindingTokenForEvent(flowPhaseEvent), flowMetadata.flowId);\n return;\n }\n case (Types.Events.Phase.FLOW_STEP): {\n const flow = flowDataByGroupToken.get(flowGroup);\n if (!flow || flow.times.length < 0) {\n // Found non-start flow event with no corresponding start flow,\n // start event. Quietly ignore problematic event.\n return;\n }\n addFlowIdToFlowPhaseBinding(flowPhaseBindingTokenForEvent(flowPhaseEvent), flow.flowId);\n flow.times.push(flowPhaseEvent.ts);\n return;\n }\n case (Types.Events.Phase.FLOW_END): {\n const flow = flowDataByGroupToken.get(flowGroup);\n if (!flow || flow.times.length < 0) {\n // Found non-start flow event with no corresponding start flow,\n // start event. Quietly ignore problematic event.\n return;\n }\n addFlowIdToFlowPhaseBinding(flowPhaseBindingTokenForEvent(flowPhaseEvent), flow.flowId);\n flow.times.push(flowPhaseEvent.ts);\n flowsById.set(flow.flowId, {times: flow.times, events: []});\n // We don't need this data anymore as the flow has been finished,\n // so we can drop it.\n flowDataByGroupToken.delete(flowGroup);\n }\n }\n}\n\n/**\n * A single trace event can belong to multiple flows. This method\n * tracks which flows (flowId) an event belongs to (given\n * its flow phase binding token).\n */\nfunction addFlowIdToFlowPhaseBinding(flowPhaseBinding: string, flowId: number): void {\n let flowIds = flowPhaseBindingTokenToFlowId.get(flowPhaseBinding);\n if (!flowIds) {\n flowIds = new Set();\n }\n flowIds.add(flowId);\n flowPhaseBindingTokenToFlowId.set(flowPhaseBinding, flowIds);\n}\n\n/**\n * Returns a token to group flow phase events (start, step and end)\n * belonging to the same flow. Flow phase events belonging to the same\n * flow share category, thread id, process id and name.\n *\n * Note that other phase events of other flows can share these\n * attributes too. For this reason, we group flow phase events in\n * cycles. A cycle starts on a flow start phase event and finishes on a\n * flow end phase event. For this reason, flow phase events need to be\n * handled in timestamp order.\n */\nfunction flowGroupTokenForFlowPhaseEvent(event: Types.Events.FlowEvent): string {\n return `${event.cat}${ID_COMPONENT_SEPARATOR}${event.name}${ID_COMPONENT_SEPARATOR}${event.id}`;\n}\n\n/**\n * A flow phase binding is a token that allows us to associate a flow\n * phase event to its corresponding event. This association indicates\n * what role a trace event plays in a flow.\n * We can assign a trace event with a flow phase when its category,\n * thread id, process id and timestamp matches those of a flow phase\n * event.\n */\nfunction flowPhaseBindingTokenForEvent(event: Types.Events.Event): string {\n // This function is called many times (one per event) and creating a\n // string every time can trigger GC. If this becomes a problem, a\n // possible optimization is to use a multi-key map with the\n // binding token components, a trade off between memory performance\n // and readability.\n return `${event.cat}${ID_COMPONENT_SEPARATOR}${event.tid}${ID_COMPONENT_SEPARATOR}${event.pid}${\n ID_COMPONENT_SEPARATOR}${event.ts}`;\n}\n\nexport async function finalize(): Promise<void> {\n // Order is important: flow events need to be handled first.\n flowEvents.forEach(processFlowEvent);\n nonFlowEvents.forEach(processNonFlowEvent);\n flows = [...flowsById.values()].map(f => f.events).filter(flow => flow.length > 1);\n}\n\nexport function data(): {flows: Types.Events.Event[][]} {\n return {\n flows,\n };\n}\n"]}
@@ -5,5 +5,6 @@ export declare function finalize(): Promise<void>;
5
5
  export interface ImagePaintData {
6
6
  paintImageByDrawLazyPixelRef: Map<number, Types.Events.PaintImage>;
7
7
  paintImageForEvent: Map<Types.Events.Event, Types.Events.PaintImage>;
8
+ paintImageEventForUrl: Map<string, Types.Events.PaintImage[]>;
8
9
  }
9
10
  export declare function data(): ImagePaintData;
@@ -1,6 +1,7 @@
1
1
  // Copyright 2024 The Chromium Authors. All rights reserved.
2
2
  // Use of this source code is governed by a BSD-style license that can be
3
3
  // found in the LICENSE file.
4
+ import * as Platform from '../../../core/platform/platform.js';
4
5
  import * as Types from '../types/types.js';
5
6
  /**
6
7
  * This handler is responsible for the relationships between:
@@ -30,11 +31,13 @@ const paintImageByLazyPixelRef = new Map();
30
31
  // deliberately generic as in the future we might want to add more events that
31
32
  // have a relationship to a individual PaintImage event.
32
33
  const eventToPaintImage = new Map();
34
+ const urlToPaintImage = new Map();
33
35
  export function reset() {
34
36
  paintImageEvents.clear();
35
37
  decodeLazyPixelRefEvents.clear();
36
38
  paintImageByLazyPixelRef.clear();
37
39
  eventToPaintImage.clear();
40
+ urlToPaintImage.clear();
38
41
  }
39
42
  export function handleEvent(event) {
40
43
  if (Types.Events.isPaintImage(event)) {
@@ -43,6 +46,10 @@ export function handleEvent(event) {
43
46
  forThread.push(event);
44
47
  forProcess.set(event.tid, forThread);
45
48
  paintImageEvents.set(event.pid, forProcess);
49
+ if (event.args.data.url) {
50
+ const paintsForUrl = Platform.MapUtilities.getWithDefault(urlToPaintImage, event.args.data.url, () => []);
51
+ paintsForUrl.push(event);
52
+ }
46
53
  return;
47
54
  }
48
55
  if (Types.Events.isDecodeLazyPixelRef(event) && typeof event.args?.LazyPixelRef !== 'undefined') {
@@ -103,6 +110,7 @@ export function data() {
103
110
  return {
104
111
  paintImageByDrawLazyPixelRef: paintImageByLazyPixelRef,
105
112
  paintImageForEvent: eventToPaintImage,
113
+ paintImageEventForUrl: urlToPaintImage,
106
114
  };
107
115
  }
108
116
  //# sourceMappingURL=ImagePaintingHandler.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ImagePaintingHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/ImagePaintingHandler.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Types from '../types/types.js';\n\n/**\n * This handler is responsible for the relationships between:\n * DecodeImage/ResizeImage, PaintImage and DrawLazyPixelRef events.\n *\n * When we get a DecodeImage event, we want to associate it to a PaintImage\n * event, primarily so we can determine the NodeID of the image that was\n * decoded.\n * We can do this in two ways:\n *\n * 1. If there is a PaintImage event on the same thread, use that\n * (if there are multiple, use the latest one).\n *\n * 2. If not, we can find the DecodeLazyPixelRef event on the same thread, and\n * use the PaintImage event associated with it via the `LazyPixelRef` key.\n */\n\n// Track paintImageEvents across threads.\nconst paintImageEvents: Map<Types.Events.ProcessID, Map<Types.Events.ThreadID, Types.Events.PaintImage[]>> = new Map();\nconst decodeLazyPixelRefEvents:\n Map<Types.Events.ProcessID, Map<Types.Events.ThreadID, Types.Events.DecodeLazyPixelRef[]>> = new Map();\n\n// A DrawLazyPixelRef event will contain a numerical reference in\n// args.LazyPixelRef. As we parse each DrawLazyPixelRef, we can assign it to a\n// paint event. Later we want to look up paint events by this reference, so we\n// store them in this map.\nconst paintImageByLazyPixelRef: Map<number, Types.Events.PaintImage> = new Map();\n\n// When we find events that we want to tie to a particular PaintImage event, we add them to this map.\n// These are currently only DecodeImage and ResizeImage events, but the type is\n// deliberately generic as in the future we might want to add more events that\n// have a relationship to a individual PaintImage event.\nconst eventToPaintImage: Map<Types.Events.Event, Types.Events.PaintImage> = new Map();\n\nexport function reset(): void {\n paintImageEvents.clear();\n decodeLazyPixelRefEvents.clear();\n paintImageByLazyPixelRef.clear();\n eventToPaintImage.clear();\n}\n\nexport function handleEvent(event: Types.Events.Event): void {\n if (Types.Events.isPaintImage(event)) {\n const forProcess = paintImageEvents.get(event.pid) || new Map<Types.Events.ThreadID, Types.Events.PaintImage[]>();\n const forThread = forProcess.get(event.tid) || [];\n forThread.push(event);\n forProcess.set(event.tid, forThread);\n paintImageEvents.set(event.pid, forProcess);\n return;\n }\n\n if (Types.Events.isDecodeLazyPixelRef(event) && typeof event.args?.LazyPixelRef !== 'undefined') {\n // Store these because we use them to tie DecodeImage to a PaintEvent.\n const forProcess =\n decodeLazyPixelRefEvents.get(event.pid) || new Map<Types.Events.ThreadID, Types.Events.DecodeLazyPixelRef[]>();\n const forThread = forProcess.get(event.tid) || [];\n forThread.push(event);\n forProcess.set(event.tid, forThread);\n decodeLazyPixelRefEvents.set(event.pid, forProcess);\n }\n\n // If we see a DrawLazyPixelRef event, we need to find the last PaintImage\n // event on the thread and associate it to the LazyPixelRef that is supplied\n // in the DrawLazyPixelRef event.\n // This means that later on if we see a DecodeLazyPixelRef event with the\n // same LazyPixelRef key, we can find its associated PaintImage event by\n // looking it up.\n if (Types.Events.isDrawLazyPixelRef(event) && typeof event.args?.LazyPixelRef !== 'undefined') {\n const lastPaintEvent = paintImageEvents.get(event.pid)?.get(event.tid)?.at(-1);\n if (!lastPaintEvent) {\n return;\n }\n paintImageByLazyPixelRef.set(event.args.LazyPixelRef, lastPaintEvent);\n return;\n }\n\n if (Types.Events.isDecodeImage(event)) {\n // When we see a DecodeImage, we want to associate it to a PaintImage\n // event. We try two approaches:\n //\n // 1. If the thread of the DecodeImage event has a previous PaintImage\n // event, that is the associated event.\n //\n // 2. If that is false, we then look on the thread for a DecodeLazyPixelRef\n // event. If we find that, we then look for its associated PaintImage\n // event, which we associate via DrawLazyPixelRef events (the code block\n // above this one)\n //\n // 1. Find a PaintImage event on the same thread. If we find it, that's our association done.\n const lastPaintImageEventOnThread = paintImageEvents.get(event.pid)?.get(event.tid)?.at(-1);\n if (lastPaintImageEventOnThread) {\n eventToPaintImage.set(event, lastPaintImageEventOnThread);\n return;\n }\n\n // 2. Find the last DecodeLazyPixelRef event and, if we find it, find its associated PaintImage event.\n const lastDecodeLazyPixelRef = decodeLazyPixelRefEvents.get(event.pid)?.get(event.tid)?.at(-1);\n if (!lastDecodeLazyPixelRef || typeof lastDecodeLazyPixelRef.args?.LazyPixelRef === 'undefined') {\n return;\n }\n\n const paintEvent = paintImageByLazyPixelRef.get(lastDecodeLazyPixelRef.args.LazyPixelRef);\n if (!paintEvent) {\n return;\n }\n eventToPaintImage.set(event, paintEvent);\n }\n}\n\nexport async function finalize(): Promise<void> {\n}\n\nexport interface ImagePaintData {\n paintImageByDrawLazyPixelRef: Map<number, Types.Events.PaintImage>;\n paintImageForEvent: Map<Types.Events.Event, Types.Events.PaintImage>;\n}\n\nexport function data(): ImagePaintData {\n return {\n paintImageByDrawLazyPixelRef: paintImageByLazyPixelRef,\n paintImageForEvent: eventToPaintImage,\n };\n}\n"]}
1
+ {"version":3,"file":"ImagePaintingHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/ImagePaintingHandler.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAE7B,OAAO,KAAK,QAAQ,MAAM,oCAAoC,CAAC;AAC/D,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAC;AAE3C;;;;;;;;;;;;;;GAcG;AAEH,yCAAyC;AACzC,MAAM,gBAAgB,GAAuF,IAAI,GAAG,EAAE,CAAC;AACvH,MAAM,wBAAwB,GACmE,IAAI,GAAG,EAAE,CAAC;AAE3G,iEAAiE;AACjE,8EAA8E;AAC9E,8EAA8E;AAC9E,0BAA0B;AAC1B,MAAM,wBAAwB,GAAyC,IAAI,GAAG,EAAE,CAAC;AAEjF,qGAAqG;AACrG,+EAA+E;AAC/E,8EAA8E;AAC9E,wDAAwD;AACxD,MAAM,iBAAiB,GAAqD,IAAI,GAAG,EAAE,CAAC;AAEtF,MAAM,eAAe,GAA2C,IAAI,GAAG,EAAE,CAAC;AAE1E,MAAM,UAAU,KAAK;IACnB,gBAAgB,CAAC,KAAK,EAAE,CAAC;IACzB,wBAAwB,CAAC,KAAK,EAAE,CAAC;IACjC,wBAAwB,CAAC,KAAK,EAAE,CAAC;IACjC,iBAAiB,CAAC,KAAK,EAAE,CAAC;IAC1B,eAAe,CAAC,KAAK,EAAE,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAyB;IACnD,IAAI,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;QACrC,MAAM,UAAU,GAAG,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,EAAoD,CAAC;QAClH,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QAClD,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtB,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QACrC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QAE5C,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YACxB,MAAM,YAAY,GAAG,QAAQ,CAAC,YAAY,CAAC,cAAc,CAAC,eAAe,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;YAC1G,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3B,CAAC;QAED,OAAO;IACT,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,CAAC,oBAAoB,CAAC,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,IAAI,EAAE,YAAY,KAAK,WAAW,EAAE,CAAC;QAChG,sEAAsE;QACtE,MAAM,UAAU,GACZ,wBAAwB,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,EAA4D,CAAC;QACnH,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QAClD,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtB,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QACrC,wBAAwB,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IACtD,CAAC;IAED,0EAA0E;IAC1E,4EAA4E;IAC5E,iCAAiC;IACjC,yEAAyE;IACzE,wEAAwE;IACxE,iBAAiB;IACjB,IAAI,KAAK,CAAC,MAAM,CAAC,kBAAkB,CAAC,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,IAAI,EAAE,YAAY,KAAK,WAAW,EAAE,CAAC;QAC9F,MAAM,cAAc,GAAG,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/E,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,OAAO;QACT,CAAC;QACD,wBAAwB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;QACtE,OAAO;IACT,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;QACtC,qEAAqE;QACrE,gCAAgC;QAChC,EAAE;QACF,sEAAsE;QACtE,uCAAuC;QACvC,EAAE;QACF,2EAA2E;QAC3E,qEAAqE;QACrE,wEAAwE;QACxE,kBAAkB;QAClB,EAAE;QACF,6FAA6F;QAC7F,MAAM,2BAA2B,GAAG,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5F,IAAI,2BAA2B,EAAE,CAAC;YAChC,iBAAiB,CAAC,GAAG,CAAC,KAAK,EAAE,2BAA2B,CAAC,CAAC;YAC1D,OAAO;QACT,CAAC;QAED,sGAAsG;QACtG,MAAM,sBAAsB,GAAG,wBAAwB,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/F,IAAI,CAAC,sBAAsB,IAAI,OAAO,sBAAsB,CAAC,IAAI,EAAE,YAAY,KAAK,WAAW,EAAE,CAAC;YAChG,OAAO;QACT,CAAC;QAED,MAAM,UAAU,GAAG,wBAAwB,CAAC,GAAG,CAAC,sBAAsB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC1F,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO;QACT,CAAC;QACD,iBAAiB,CAAC,GAAG,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IAC3C,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ;AAC9B,CAAC;AAQD,MAAM,UAAU,IAAI;IAClB,OAAO;QACL,4BAA4B,EAAE,wBAAwB;QACtD,kBAAkB,EAAE,iBAAiB;QACrC,qBAAqB,EAAE,eAAe;KACvC,CAAC;AACJ,CAAC","sourcesContent":["// Copyright 2024 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Platform from '../../../core/platform/platform.js';\nimport * as Types from '../types/types.js';\n\n/**\n * This handler is responsible for the relationships between:\n * DecodeImage/ResizeImage, PaintImage and DrawLazyPixelRef events.\n *\n * When we get a DecodeImage event, we want to associate it to a PaintImage\n * event, primarily so we can determine the NodeID of the image that was\n * decoded.\n * We can do this in two ways:\n *\n * 1. If there is a PaintImage event on the same thread, use that\n * (if there are multiple, use the latest one).\n *\n * 2. If not, we can find the DecodeLazyPixelRef event on the same thread, and\n * use the PaintImage event associated with it via the `LazyPixelRef` key.\n */\n\n// Track paintImageEvents across threads.\nconst paintImageEvents: Map<Types.Events.ProcessID, Map<Types.Events.ThreadID, Types.Events.PaintImage[]>> = new Map();\nconst decodeLazyPixelRefEvents:\n Map<Types.Events.ProcessID, Map<Types.Events.ThreadID, Types.Events.DecodeLazyPixelRef[]>> = new Map();\n\n// A DrawLazyPixelRef event will contain a numerical reference in\n// args.LazyPixelRef. As we parse each DrawLazyPixelRef, we can assign it to a\n// paint event. Later we want to look up paint events by this reference, so we\n// store them in this map.\nconst paintImageByLazyPixelRef: Map<number, Types.Events.PaintImage> = new Map();\n\n// When we find events that we want to tie to a particular PaintImage event, we add them to this map.\n// These are currently only DecodeImage and ResizeImage events, but the type is\n// deliberately generic as in the future we might want to add more events that\n// have a relationship to a individual PaintImage event.\nconst eventToPaintImage: Map<Types.Events.Event, Types.Events.PaintImage> = new Map();\n\nconst urlToPaintImage: Map<string, Types.Events.PaintImage[]> = new Map();\n\nexport function reset(): void {\n paintImageEvents.clear();\n decodeLazyPixelRefEvents.clear();\n paintImageByLazyPixelRef.clear();\n eventToPaintImage.clear();\n urlToPaintImage.clear();\n}\n\nexport function handleEvent(event: Types.Events.Event): void {\n if (Types.Events.isPaintImage(event)) {\n const forProcess = paintImageEvents.get(event.pid) || new Map<Types.Events.ThreadID, Types.Events.PaintImage[]>();\n const forThread = forProcess.get(event.tid) || [];\n forThread.push(event);\n forProcess.set(event.tid, forThread);\n paintImageEvents.set(event.pid, forProcess);\n\n if (event.args.data.url) {\n const paintsForUrl = Platform.MapUtilities.getWithDefault(urlToPaintImage, event.args.data.url, () => []);\n paintsForUrl.push(event);\n }\n\n return;\n }\n\n if (Types.Events.isDecodeLazyPixelRef(event) && typeof event.args?.LazyPixelRef !== 'undefined') {\n // Store these because we use them to tie DecodeImage to a PaintEvent.\n const forProcess =\n decodeLazyPixelRefEvents.get(event.pid) || new Map<Types.Events.ThreadID, Types.Events.DecodeLazyPixelRef[]>();\n const forThread = forProcess.get(event.tid) || [];\n forThread.push(event);\n forProcess.set(event.tid, forThread);\n decodeLazyPixelRefEvents.set(event.pid, forProcess);\n }\n\n // If we see a DrawLazyPixelRef event, we need to find the last PaintImage\n // event on the thread and associate it to the LazyPixelRef that is supplied\n // in the DrawLazyPixelRef event.\n // This means that later on if we see a DecodeLazyPixelRef event with the\n // same LazyPixelRef key, we can find its associated PaintImage event by\n // looking it up.\n if (Types.Events.isDrawLazyPixelRef(event) && typeof event.args?.LazyPixelRef !== 'undefined') {\n const lastPaintEvent = paintImageEvents.get(event.pid)?.get(event.tid)?.at(-1);\n if (!lastPaintEvent) {\n return;\n }\n paintImageByLazyPixelRef.set(event.args.LazyPixelRef, lastPaintEvent);\n return;\n }\n\n if (Types.Events.isDecodeImage(event)) {\n // When we see a DecodeImage, we want to associate it to a PaintImage\n // event. We try two approaches:\n //\n // 1. If the thread of the DecodeImage event has a previous PaintImage\n // event, that is the associated event.\n //\n // 2. If that is false, we then look on the thread for a DecodeLazyPixelRef\n // event. If we find that, we then look for its associated PaintImage\n // event, which we associate via DrawLazyPixelRef events (the code block\n // above this one)\n //\n // 1. Find a PaintImage event on the same thread. If we find it, that's our association done.\n const lastPaintImageEventOnThread = paintImageEvents.get(event.pid)?.get(event.tid)?.at(-1);\n if (lastPaintImageEventOnThread) {\n eventToPaintImage.set(event, lastPaintImageEventOnThread);\n return;\n }\n\n // 2. Find the last DecodeLazyPixelRef event and, if we find it, find its associated PaintImage event.\n const lastDecodeLazyPixelRef = decodeLazyPixelRefEvents.get(event.pid)?.get(event.tid)?.at(-1);\n if (!lastDecodeLazyPixelRef || typeof lastDecodeLazyPixelRef.args?.LazyPixelRef === 'undefined') {\n return;\n }\n\n const paintEvent = paintImageByLazyPixelRef.get(lastDecodeLazyPixelRef.args.LazyPixelRef);\n if (!paintEvent) {\n return;\n }\n eventToPaintImage.set(event, paintEvent);\n }\n}\n\nexport async function finalize(): Promise<void> {\n}\n\nexport interface ImagePaintData {\n paintImageByDrawLazyPixelRef: Map<number, Types.Events.PaintImage>;\n paintImageForEvent: Map<Types.Events.Event, Types.Events.PaintImage>;\n paintImageEventForUrl: Map<string, Types.Events.PaintImage[]>;\n}\n\nexport function data(): ImagePaintData {\n return {\n paintImageByDrawLazyPixelRef: paintImageByLazyPixelRef,\n paintImageForEvent: eventToPaintImage,\n paintImageEventForUrl: urlToPaintImage,\n };\n}\n"]}
@@ -1,6 +1,12 @@
1
1
  import type * as Protocol from '../../../generated/protocol.js';
2
2
  import * as Types from '../types/types.js';
3
+ import type { HandlerName } from './types.js';
3
4
  export declare function reset(): void;
4
5
  export declare function handleEvent(event: Types.Events.Event): void;
5
6
  export declare function finalize(): Promise<void>;
6
- export declare function data(): Map<Protocol.DOM.BackendNodeId, Types.Events.LargestImagePaintCandidate>;
7
+ export interface LargestImagePaintData {
8
+ imageByDOMNodeId: Map<Protocol.DOM.BackendNodeId, Types.Events.LargestImagePaintCandidate>;
9
+ lcpRequestByNavigation: Map<Types.Events.NavigationStart | null, Types.Events.SyntheticNetworkRequest>;
10
+ }
11
+ export declare function data(): LargestImagePaintData;
12
+ export declare function deps(): HandlerName[];