@paulirish/trace_engine 0.0.32 → 0.0.33

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 (282) hide show
  1. package/README.md +6 -10
  2. package/analyze-trace.mjs +9 -10
  3. package/core/platform/ArrayUtilities.js +1 -0
  4. package/core/platform/ArrayUtilities.js.map +1 -1
  5. package/core/platform/DevToolsPath.d.ts +1 -1
  6. package/core/platform/DevToolsPath.js.map +1 -1
  7. package/core/platform/MimeType.js +4 -2
  8. package/core/platform/MimeType.js.map +1 -1
  9. package/core/platform/NumberUtilities.js +8 -0
  10. package/core/platform/NumberUtilities.js.map +1 -1
  11. package/core/platform/ServerTiming.d.ts +31 -0
  12. package/core/platform/ServerTiming.js +212 -0
  13. package/core/platform/ServerTiming.js.map +1 -0
  14. package/core/platform/Timing.d.ts +1 -1
  15. package/core/platform/Timing.js.map +1 -1
  16. package/core/platform/TypescriptUtilities.d.ts +3 -0
  17. package/core/platform/TypescriptUtilities.js.map +1 -1
  18. package/core/platform/UIString.d.ts +1 -1
  19. package/core/platform/UIString.js.map +1 -1
  20. package/core/platform/UserVisibleError.d.ts +1 -1
  21. package/core/platform/UserVisibleError.js.map +1 -1
  22. package/core/platform/platform-tsconfig.json +1 -1
  23. package/core/platform/platform.d.ts +2 -2
  24. package/core/platform/platform.js +2 -2
  25. package/core/platform/platform.js.map +1 -1
  26. package/generated/protocol.d.ts +258 -14
  27. package/models/trace/LanternComputationData.d.ts +4 -4
  28. package/models/trace/LanternComputationData.js +22 -23
  29. package/models/trace/LanternComputationData.js.map +1 -1
  30. package/models/trace/ModelImpl.d.ts +11 -12
  31. package/models/trace/ModelImpl.js +22 -33
  32. package/models/trace/ModelImpl.js.map +1 -1
  33. package/models/trace/Processor.d.ts +21 -12
  34. package/models/trace/Processor.js +148 -67
  35. package/models/trace/Processor.js.map +1 -1
  36. package/models/trace/TracingManager.js.map +1 -1
  37. package/models/trace/extras/FetchNodes.d.ts +8 -8
  38. package/models/trace/extras/FetchNodes.js +16 -11
  39. package/models/trace/extras/FetchNodes.js.map +1 -1
  40. package/models/trace/extras/FilmStrip.d.ts +2 -2
  41. package/models/trace/extras/FilmStrip.js +8 -8
  42. package/models/trace/extras/FilmStrip.js.map +1 -1
  43. package/models/trace/extras/MainThreadActivity.d.ts +1 -1
  44. package/models/trace/extras/MainThreadActivity.js +1 -1
  45. package/models/trace/extras/MainThreadActivity.js.map +1 -1
  46. package/models/trace/extras/Metadata.js +2 -2
  47. package/models/trace/extras/Metadata.js.map +1 -1
  48. package/models/trace/extras/URLForEntry.d.ts +9 -1
  49. package/models/trace/extras/URLForEntry.js +18 -10
  50. package/models/trace/extras/URLForEntry.js.map +1 -1
  51. package/models/trace/extras/extras.js +1 -1
  52. package/models/trace/handlers/AnimationHandler.d.ts +2 -2
  53. package/models/trace/handlers/AnimationHandler.js +1 -1
  54. package/models/trace/handlers/AnimationHandler.js.map +1 -1
  55. package/models/trace/handlers/AuctionWorkletsHandler.d.ts +2 -2
  56. package/models/trace/handlers/AuctionWorkletsHandler.js +11 -11
  57. package/models/trace/handlers/AuctionWorkletsHandler.js.map +1 -1
  58. package/models/trace/handlers/ExtensionTraceDataHandler.d.ts +6 -6
  59. package/models/trace/handlers/ExtensionTraceDataHandler.js +12 -8
  60. package/models/trace/handlers/ExtensionTraceDataHandler.js.map +1 -1
  61. package/models/trace/handlers/FramesHandler.d.ts +24 -19
  62. package/models/trace/handlers/FramesHandler.js +46 -25
  63. package/models/trace/handlers/FramesHandler.js.map +1 -1
  64. package/models/trace/handlers/GPUHandler.d.ts +4 -4
  65. package/models/trace/handlers/GPUHandler.js +3 -3
  66. package/models/trace/handlers/GPUHandler.js.map +1 -1
  67. package/models/trace/handlers/ImagePaintingHandler.d.ts +3 -3
  68. package/models/trace/handlers/ImagePaintingHandler.js +6 -8
  69. package/models/trace/handlers/ImagePaintingHandler.js.map +1 -1
  70. package/models/trace/handlers/InitiatorsHandler.d.ts +3 -3
  71. package/models/trace/handlers/InitiatorsHandler.js +14 -14
  72. package/models/trace/handlers/InitiatorsHandler.js.map +1 -1
  73. package/models/trace/handlers/InvalidationsHandler.d.ts +4 -2
  74. package/models/trace/handlers/InvalidationsHandler.js +29 -11
  75. package/models/trace/handlers/InvalidationsHandler.js.map +1 -1
  76. package/models/trace/handlers/LargestImagePaintHandler.d.ts +2 -2
  77. package/models/trace/handlers/LargestImagePaintHandler.js +1 -1
  78. package/models/trace/handlers/LargestImagePaintHandler.js.map +1 -1
  79. package/models/trace/handlers/LargestTextPaintHandler.d.ts +2 -2
  80. package/models/trace/handlers/LargestTextPaintHandler.js +1 -1
  81. package/models/trace/handlers/LargestTextPaintHandler.js.map +1 -1
  82. package/models/trace/handlers/LayerTreeHandler.d.ts +6 -6
  83. package/models/trace/handlers/LayerTreeHandler.js +6 -6
  84. package/models/trace/handlers/LayerTreeHandler.js.map +1 -1
  85. package/models/trace/handlers/LayoutShiftsHandler.d.ts +12 -20
  86. package/models/trace/handlers/LayoutShiftsHandler.js +73 -12
  87. package/models/trace/handlers/LayoutShiftsHandler.js.map +1 -1
  88. package/models/trace/handlers/MemoryHandler.d.ts +2 -2
  89. package/models/trace/handlers/MemoryHandler.js +1 -1
  90. package/models/trace/handlers/MemoryHandler.js.map +1 -1
  91. package/models/trace/handlers/MetaHandler.d.ts +15 -14
  92. package/models/trace/handlers/MetaHandler.js +32 -30
  93. package/models/trace/handlers/MetaHandler.js.map +1 -1
  94. package/models/trace/handlers/ModelHandlers.d.ts +1 -1
  95. package/models/trace/handlers/ModelHandlers.js +1 -1
  96. package/models/trace/handlers/ModelHandlers.js.map +1 -1
  97. package/models/trace/handlers/NetworkRequestsHandler.d.ts +13 -12
  98. package/models/trace/handlers/NetworkRequestsHandler.js +68 -66
  99. package/models/trace/handlers/NetworkRequestsHandler.js.map +1 -1
  100. package/models/trace/handlers/PageFramesHandler.d.ts +2 -2
  101. package/models/trace/handlers/PageFramesHandler.js +2 -2
  102. package/models/trace/handlers/PageFramesHandler.js.map +1 -1
  103. package/models/trace/handlers/PageLoadMetricsHandler.d.ts +7 -7
  104. package/models/trace/handlers/PageLoadMetricsHandler.js +21 -24
  105. package/models/trace/handlers/PageLoadMetricsHandler.js.map +1 -1
  106. package/models/trace/handlers/RendererHandler.d.ts +19 -19
  107. package/models/trace/handlers/RendererHandler.js +5 -5
  108. package/models/trace/handlers/RendererHandler.js.map +1 -1
  109. package/models/trace/handlers/SamplesHandler.d.ts +6 -6
  110. package/models/trace/handlers/SamplesHandler.js +3 -3
  111. package/models/trace/handlers/SamplesHandler.js.map +1 -1
  112. package/models/trace/handlers/ScreenshotsHandler.d.ts +6 -4
  113. package/models/trace/handlers/ScreenshotsHandler.js +11 -9
  114. package/models/trace/handlers/ScreenshotsHandler.js.map +1 -1
  115. package/models/trace/handlers/SelectorStatsHandler.d.ts +3 -3
  116. package/models/trace/handlers/SelectorStatsHandler.js +2 -2
  117. package/models/trace/handlers/SelectorStatsHandler.js.map +1 -1
  118. package/models/trace/handlers/ServerTimingsHandler.d.ts +10 -0
  119. package/models/trace/handlers/ServerTimingsHandler.js +118 -0
  120. package/models/trace/handlers/ServerTimingsHandler.js.map +1 -0
  121. package/models/trace/handlers/Threads.d.ts +7 -7
  122. package/models/trace/handlers/Threads.js +5 -5
  123. package/models/trace/handlers/Threads.js.map +1 -1
  124. package/models/trace/handlers/UserInteractionsHandler.d.ts +13 -11
  125. package/models/trace/handlers/UserInteractionsHandler.js +13 -7
  126. package/models/trace/handlers/UserInteractionsHandler.js.map +1 -1
  127. package/models/trace/handlers/UserTimingsHandler.d.ts +5 -5
  128. package/models/trace/handlers/UserTimingsHandler.js +52 -9
  129. package/models/trace/handlers/UserTimingsHandler.js.map +1 -1
  130. package/models/trace/handlers/WarningsHandler.d.ts +5 -5
  131. package/models/trace/handlers/WarningsHandler.js +4 -5
  132. package/models/trace/handlers/WarningsHandler.js.map +1 -1
  133. package/models/trace/handlers/WorkersHandler.d.ts +4 -4
  134. package/models/trace/handlers/WorkersHandler.js +1 -1
  135. package/models/trace/handlers/WorkersHandler.js.map +1 -1
  136. package/models/trace/handlers/handlers-tsconfig.json +1 -1
  137. package/models/trace/handlers/types.d.ts +7 -7
  138. package/models/trace/handlers/types.js.map +1 -1
  139. package/models/trace/helpers/Extensions.d.ts +2 -2
  140. package/models/trace/helpers/Extensions.js.map +1 -1
  141. package/models/trace/helpers/Network.d.ts +2 -2
  142. package/models/trace/helpers/Network.js +19 -2
  143. package/models/trace/helpers/Network.js.map +1 -1
  144. package/models/trace/helpers/SamplesIntegrator.d.ts +5 -5
  145. package/models/trace/helpers/SamplesIntegrator.js +10 -11
  146. package/models/trace/helpers/SamplesIntegrator.js.map +1 -1
  147. package/models/trace/helpers/SyntheticEvents.d.ts +8 -14
  148. package/models/trace/helpers/SyntheticEvents.js +20 -31
  149. package/models/trace/helpers/SyntheticEvents.js.map +1 -1
  150. package/models/trace/helpers/Timing.d.ts +16 -4
  151. package/models/trace/helpers/Timing.js +33 -1
  152. package/models/trace/helpers/Timing.js.map +1 -1
  153. package/models/trace/helpers/Trace.d.ts +46 -32
  154. package/models/trace/helpers/Trace.js +53 -24
  155. package/models/trace/helpers/Trace.js.map +1 -1
  156. package/models/trace/helpers/TreeHelpers.d.ts +29 -8
  157. package/models/trace/helpers/TreeHelpers.js +87 -19
  158. package/models/trace/helpers/TreeHelpers.js.map +1 -1
  159. package/models/trace/insights/Common.d.ts +4 -3
  160. package/models/trace/insights/Common.js +22 -7
  161. package/models/trace/insights/Common.js.map +1 -1
  162. package/models/trace/insights/CumulativeLayoutShift.d.ts +34 -13
  163. package/models/trace/insights/CumulativeLayoutShift.js +151 -59
  164. package/models/trace/insights/CumulativeLayoutShift.js.map +1 -1
  165. package/models/trace/insights/DocumentLatency.d.ts +9 -4
  166. package/models/trace/insights/DocumentLatency.js +82 -7
  167. package/models/trace/insights/DocumentLatency.js.map +1 -1
  168. package/models/trace/insights/FontDisplay.d.ts +11 -0
  169. package/models/trace/insights/FontDisplay.js +44 -0
  170. package/models/trace/insights/FontDisplay.js.map +1 -0
  171. package/models/trace/insights/InsightRunners.d.ts +3 -0
  172. package/models/trace/insights/InsightRunners.js +3 -0
  173. package/models/trace/insights/InsightRunners.js.map +1 -1
  174. package/models/trace/insights/InteractionToNextPaint.d.ts +4 -5
  175. package/models/trace/insights/InteractionToNextPaint.js +5 -3
  176. package/models/trace/insights/InteractionToNextPaint.js.map +1 -1
  177. package/models/trace/insights/LargestContentfulPaint.d.ts +20 -7
  178. package/models/trace/insights/LargestContentfulPaint.js +57 -37
  179. package/models/trace/insights/LargestContentfulPaint.js.map +1 -1
  180. package/models/trace/insights/RenderBlocking.d.ts +3 -3
  181. package/models/trace/insights/RenderBlocking.js +29 -24
  182. package/models/trace/insights/RenderBlocking.js.map +1 -1
  183. package/models/trace/insights/SlowCSSSelector.d.ts +11 -0
  184. package/models/trace/insights/SlowCSSSelector.js +67 -0
  185. package/models/trace/insights/SlowCSSSelector.js.map +1 -0
  186. package/models/trace/insights/ThirdPartyWeb.d.ts +18 -0
  187. package/models/trace/insights/ThirdPartyWeb.js +174 -0
  188. package/models/trace/insights/ThirdPartyWeb.js.map +1 -0
  189. package/models/trace/insights/Viewport.d.ts +5 -2
  190. package/models/trace/insights/Viewport.js +14 -9
  191. package/models/trace/insights/Viewport.js.map +1 -1
  192. package/models/trace/insights/insights-tsconfig.json +9 -0
  193. package/models/trace/insights/insights.d.ts +1 -0
  194. package/models/trace/insights/insights.js +1 -0
  195. package/models/trace/insights/insights.js.map +1 -1
  196. package/models/trace/insights/types.d.ts +43 -25
  197. package/models/trace/insights/types.js.map +1 -1
  198. package/models/trace/lantern/core/NetworkAnalyzer.d.ts +6 -6
  199. package/models/trace/lantern/core/NetworkAnalyzer.js +12 -12
  200. package/models/trace/lantern/core/NetworkAnalyzer.js.map +1 -1
  201. package/models/trace/lantern/graph/BaseNode.d.ts +4 -4
  202. package/models/trace/lantern/graph/BaseNode.js +21 -21
  203. package/models/trace/lantern/graph/BaseNode.js.map +1 -1
  204. package/models/trace/lantern/graph/CPUNode.d.ts +1 -1
  205. package/models/trace/lantern/graph/CPUNode.js +5 -5
  206. package/models/trace/lantern/graph/CPUNode.js.map +1 -1
  207. package/models/trace/lantern/graph/PageDependencyGraph.d.ts +4 -4
  208. package/models/trace/lantern/graph/PageDependencyGraph.js +5 -5
  209. package/models/trace/lantern/graph/PageDependencyGraph.js.map +1 -1
  210. package/models/trace/lantern/simulation/ConnectionPool.d.ts +7 -7
  211. package/models/trace/lantern/simulation/ConnectionPool.js +26 -26
  212. package/models/trace/lantern/simulation/ConnectionPool.js.map +1 -1
  213. package/models/trace/lantern/simulation/DNSCache.d.ts +3 -3
  214. package/models/trace/lantern/simulation/DNSCache.js +11 -11
  215. package/models/trace/lantern/simulation/DNSCache.js.map +1 -1
  216. package/models/trace/lantern/simulation/SimulationTimingMap.d.ts +1 -1
  217. package/models/trace/lantern/simulation/SimulationTimingMap.js +15 -15
  218. package/models/trace/lantern/simulation/SimulationTimingMap.js.map +1 -1
  219. package/models/trace/lantern/simulation/Simulator.d.ts +28 -28
  220. package/models/trace/lantern/simulation/Simulator.js +113 -113
  221. package/models/trace/lantern/simulation/Simulator.js.map +1 -1
  222. package/models/trace/lantern/simulation/TCPConnection.d.ts +9 -9
  223. package/models/trace/lantern/simulation/TCPConnection.js +36 -36
  224. package/models/trace/lantern/simulation/TCPConnection.js.map +1 -1
  225. package/models/trace/root-causes/LayoutShift.d.ts +13 -13
  226. package/models/trace/root-causes/LayoutShift.js +7 -25
  227. package/models/trace/root-causes/LayoutShift.js.map +1 -1
  228. package/models/trace/types/Configuration.d.ts +16 -0
  229. package/models/trace/types/Configuration.js +1 -0
  230. package/models/trace/types/Configuration.js.map +1 -1
  231. package/models/trace/types/Extensions.d.ts +9 -12
  232. package/models/trace/types/Extensions.js +2 -1
  233. package/models/trace/types/Extensions.js.map +1 -1
  234. package/models/trace/types/File.d.ts +55 -23
  235. package/models/trace/types/File.js +15 -3
  236. package/models/trace/types/File.js.map +1 -1
  237. package/models/trace/types/TraceEvents.d.ts +818 -713
  238. package/models/trace/types/TraceEvents.js +270 -277
  239. package/models/trace/types/TraceEvents.js.map +1 -1
  240. package/models/trace/types/types.d.ts +1 -1
  241. package/models/trace/types/types.js +1 -1
  242. package/models/trace/types/types.js.map +1 -1
  243. package/package.json +4 -2
  244. package/test/test-trace-engine.mjs +47 -2
  245. package/third_party/third-party-web/third-party-web.js +1 -0
  246. package/core/platform/PromiseUtilities.d.ts +0 -10
  247. package/core/platform/PromiseUtilities.js +0 -18
  248. package/core/platform/PromiseUtilities.js.map +0 -1
  249. package/core/platform/SetUtilities.d.ts +0 -2
  250. package/core/platform/SetUtilities.js +0 -23
  251. package/core/platform/SetUtilities.js.map +0 -1
  252. package/models/trace/EntriesFilter.d.ts +0 -72
  253. package/models/trace/EntriesFilter.js +0 -296
  254. package/models/trace/EntriesFilter.js.map +0 -1
  255. package/models/trace/LegacyTracingModel.js.map +0 -1
  256. package/models/trace/handlers/EnhancedTracesHandler.d.ts +0 -48
  257. package/models/trace/handlers/EnhancedTracesHandler.js +0 -165
  258. package/models/trace/handlers/EnhancedTracesHandler.js.map +0 -1
  259. package/models/trace/lantern/BaseNode.d.ts +0 -91
  260. package/models/trace/lantern/BaseNode.js +0 -268
  261. package/models/trace/lantern/BaseNode.js.map +0 -1
  262. package/models/trace/lantern/CPUNode.d.ts +0 -24
  263. package/models/trace/lantern/CPUNode.js +0 -64
  264. package/models/trace/lantern/CPUNode.js.map +0 -1
  265. package/models/trace/lantern/LanternError.d.ts +0 -3
  266. package/models/trace/lantern/LanternError.js +0 -7
  267. package/models/trace/lantern/LanternError.js.map +0 -1
  268. package/models/trace/lantern/MetricsModule.d.ts +0 -11
  269. package/models/trace/lantern/MetricsModule.js +0 -14
  270. package/models/trace/lantern/MetricsModule.js.map +0 -1
  271. package/models/trace/lantern/NetworkNode.d.ts +0 -22
  272. package/models/trace/lantern/NetworkNode.js +0 -83
  273. package/models/trace/lantern/NetworkNode.js.map +0 -1
  274. package/models/trace/lantern/PageDependencyGraph.d.ts +0 -43
  275. package/models/trace/lantern/PageDependencyGraph.js +0 -509
  276. package/models/trace/lantern/PageDependencyGraph.js.map +0 -1
  277. package/models/trace/lantern/SimulationModule.d.ts +0 -17
  278. package/models/trace/lantern/SimulationModule.js +0 -13
  279. package/models/trace/lantern/SimulationModule.js.map +0 -1
  280. package/models/trace/lantern/simulation/NetworkAnalyzer.d.ts +0 -112
  281. package/models/trace/lantern/simulation/NetworkAnalyzer.js +0 -486
  282. package/models/trace/lantern/simulation/NetworkAnalyzer.js.map +0 -1
package/README.md CHANGED
@@ -75,7 +75,7 @@ npm publish --access public
75
75
 
76
76
 
77
77
  ┌──────────────────▼─────────────────┐
78
- │const data = model.traceParsedData()│
78
+ │const data = model.parsedTrace()│
79
79
  └────────────────────────────────────┘
80
80
  ```
81
81
 
@@ -85,15 +85,11 @@ All the processing is done by the `Processor`. The processor contains a series o
85
85
 
86
86
  The trace processor loops over every event in the trace and calls each handler in turn (done this way so we only loop over the trace file once, rather than doing it once-per-handler). A Handler is a file that exposes a set of methods, most importantly `handleEvent()` and `data()`. The `handleEvent` function will be called for each event in the trace, and it is up to an individual handler to do something with that event if it needs to. The `data` method should return the final data that has been parsed and generated by the handler.
87
87
 
88
- Once processing is done (read on for more details on how to track this), you can use the `traceParsedData()` method to fetch the result of parsing a given trace.
88
+ Once processing is done (read on for more details on how to track this), you can use the `parsedTrace()` method to fetch the result of parsing a given trace.
89
89
 
90
90
  ## Enabled handlers and creating a model
91
91
 
92
- At the time of writing (06 June 2023) we are midway through a migration of the Performanc Panel's trace engine from the SDK.TracingModel to the new TraceEngine. Consequently, not all of the TraceEngine's handlers are currently active, because we don't want to run expensive handlers whose data we do not yet use in the UI.
93
-
94
- Therefore, to create a model instance, we use `Model.createWithRequiredHandlersForMigration()`, which initializes a model configured correctly with the right handlers.
95
-
96
- Once the migration is done, we can swap to `Model.createWithAllHandlers()` and remove the code that enables a subset of the handlers to run.
92
+ We use `Model.createWithAllHandlers()`, which initializes a model configured correctly with the right handlers.
97
93
 
98
94
  If you want to strictly control the set of handlers that are run (for example, if you only want to run one particular handler), you can initialize the model yourself and pass in the set of handlers:
99
95
 
@@ -105,7 +101,7 @@ const model = new Model({
105
101
 
106
102
  ## Parsing a trace and getting data back
107
103
 
108
- Once you have an instance of the model, you can call the `parse` method to take a set of raw events and parse them. Once parsed, you then have to call the `traceParsedData` method, providing an index of the trace you want to have the data for. This is because any model can store a number of traces. Each trace is given an index, which starts at 0 and increments by one as a new trace is parsed.
104
+ Once you have an instance of the model, you can call the `parse` method to take a set of raw events and parse them. Once parsed, you then have to call the `parsedTrace` method, providing an index of the trace you want to have the data for. This is because any model can store a number of traces. Each trace is given an index, which starts at 0 and increments by one as a new trace is parsed.
109
105
 
110
106
  If you are managing multiple traces, you should store them in some form of indexed data structure so you can easily know which index to use to fetch any data from the model. You may delete a trace with `deleteTraceByIndex`, which will then update the indexes of all other traces too.
111
107
 
@@ -127,7 +123,7 @@ this.model.addEventListener(Model.ModelUpdateEvent.eventName, event => {
127
123
 
128
124
  if (data.data === 'done') {
129
125
  // trace is complete
130
- const newestData = this.model.traceParsedData(this.model.size() - 1);
126
+ const newestData = this.model.parsedTrace(this.model.size() - 1);
131
127
  } else {
132
128
  // data.data will be an object: { index: X, total: Y}, which represents how many events (X) have been processed out of a total (Y).
133
129
  // This can be used to show a progress bar, for example.
@@ -137,7 +133,7 @@ this.model.addEventListener(Model.ModelUpdateEvent.eventName, event => {
137
133
 
138
134
  ## The structure of the final data object
139
135
 
140
- The object returned from `traceParsedData()` is an object of key-value pairs where each key is the name of a handler, and the value is the data that was parsed and returned from that handler.
136
+ The object returned from `parsedTrace()` is an object of key-value pairs where each key is the name of a handler, and the value is the data that was parsed and returned from that handler.
141
137
 
142
138
  ```ts
143
139
  {
package/analyze-trace.mjs CHANGED
@@ -2,34 +2,33 @@
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
4
 
5
- // Run this first:
6
- // front_end/models/trace/build-trace-engine-lib.sh
7
-
8
5
  /* eslint-disable rulesdir/es_modules_import */
9
6
  import fs from 'node:fs';
10
7
  import zlib from 'node:zlib';
11
8
 
12
- /** @typedef {import('../front_end/models/trace/trace.ts')} TraceEngine */
9
+ /** @typedef {import('./models/trace/trace.ts')} Trace */
13
10
 
14
11
  // For types... see Connor's manual hack here:
15
12
  // https://github.com/GoogleChrome/lighthouse/pull/15703/files#diff-ec7e073cf0e6135d4f2af9bc04fe6100ec0df80ad1686bee2da53871be5f1a7b
16
13
  // and https://github.com/GoogleChrome/lighthouse/pull/15703/files#diff-6dab4507247217209f5ab0f6c343ca2b00af1300878abba81fb74d51cdfbedf9
14
+ // But maybe all this kinda works, too?
17
15
 
18
- /** @type {TraceEngine} */
19
- import * as TraceEngine from './models/trace/trace.js';
16
+ /** @type {Trace} */
17
+ import * as Trace from './models/trace/trace.js';
20
18
 
21
19
  polyfillDOMRect();
22
20
 
23
21
  /**
24
22
  * @param {string} filename
25
- * @returns {Promise<TraceEngine.TraceModel>}
23
+ * @returns {Promise<{parsedTrace: Trace.Handlers.Types.ParsedTrace, insights: Trace.Insights.Types.TraceInsightSets | null>}}
26
24
  */
27
25
  export async function analyzeTrace(filename) {
28
26
  const traceEvents = loadTraceEventsFromFile(filename);
29
- const model = TraceEngine.TraceModel.Model.createWithAllHandlers(
30
- TraceEngine.Types.Configuration.DEFAULT); // aka `fullTraceEngine`
27
+ const model = Trace.TraceModel.Model.createWithAllHandlers(Trace.Types.Configuration.DEFAULT);
31
28
  await model.parse(traceEvents);
32
- return model.traceParsedData();
29
+ const parsedTrace = model.parsedTrace();
30
+ const insights = model.traceInsights();
31
+ return {parsedTrace, insights};
33
32
  }
34
33
 
35
34
  // If run as CLI, parse the argv trace (or a fallback)
@@ -136,6 +136,7 @@ export function upperBound(array, needle, comparator, left, right) {
136
136
  * arr[i] > 5 you would be returned 2 because array[2] = 6.
137
137
  *
138
138
  * Please note: this presupposes that the array is already ordered.
139
+ * This function uses a variation of Binary Search.
139
140
  */
140
141
  function nearestIndex(arr, predicate, searchStart) {
141
142
  const searchFromEnd = searchStart === "END" /* NearestSearchStart.END */;
@@ -1 +1 @@
1
- {"version":3,"file":"ArrayUtilities.js","sourceRoot":"","sources":["../../../../../../front_end/core/platform/ArrayUtilities.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) 2020 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 const removeElement = <T>(array: T[], element: T, firstOnly?: boolean): boolean => {\n let index = array.indexOf(element);\n if (index === -1) {\n return false;\n }\n if (firstOnly) {\n array.splice(index, 1);\n return true;\n }\n for (let i = index + 1, n = array.length; i < n; ++i) {\n if (array[i] !== element) {\n array[index++] = array[i];\n }\n }\n array.length = index;\n return true;\n};\n\ntype NumberComparator = (a: number, b: number) => number;\n\nfunction swap(array: number[], i1: number, i2: number): void {\n const temp = array[i1];\n array[i1] = array[i2];\n array[i2] = temp;\n}\n\nfunction partition(\n array: number[], comparator: NumberComparator, left: number, right: number, pivotIndex: number): number {\n const pivotValue = array[pivotIndex];\n swap(array, right, pivotIndex);\n let storeIndex = left;\n for (let i = left; i < right; ++i) {\n if (comparator(array[i], pivotValue) < 0) {\n swap(array, storeIndex, i);\n ++storeIndex;\n }\n }\n swap(array, right, storeIndex);\n return storeIndex;\n}\n\nfunction quickSortRange(\n array: number[], comparator: NumberComparator, left: number, right: number, sortWindowLeft: number,\n sortWindowRight: number): void {\n if (right <= left) {\n return;\n }\n const pivotIndex = Math.floor(Math.random() * (right - left)) + left;\n const pivotNewIndex = partition(array, comparator, left, right, pivotIndex);\n if (sortWindowLeft < pivotNewIndex) {\n quickSortRange(array, comparator, left, pivotNewIndex - 1, sortWindowLeft, sortWindowRight);\n }\n if (pivotNewIndex < sortWindowRight) {\n quickSortRange(array, comparator, pivotNewIndex + 1, right, sortWindowLeft, sortWindowRight);\n }\n}\n\nexport function sortRange(\n array: number[], comparator: NumberComparator, leftBound: number, rightBound: number, sortWindowLeft: number,\n sortWindowRight: number): number[] {\n if (leftBound === 0 && rightBound === (array.length - 1) && sortWindowLeft === 0 && sortWindowRight >= rightBound) {\n array.sort(comparator);\n } else {\n quickSortRange(array, comparator, leftBound, rightBound, sortWindowLeft, sortWindowRight);\n }\n return array;\n}\nexport const binaryIndexOf = <T, S>(array: T[], value: S, comparator: (a: S, b: T) => number): number => {\n const index = lowerBound(array, value, comparator);\n return index < array.length && comparator(value, array[index]) === 0 ? index : -1;\n};\n\nfunction mergeOrIntersect<T>(\n array1: T[], array2: T[], comparator: (a: T, b: T) => number, mergeNotIntersect: boolean): T[] {\n const result = [];\n let i = 0;\n let j = 0;\n while (i < array1.length && j < array2.length) {\n const compareValue = comparator(array1[i], array2[j]);\n if (mergeNotIntersect || !compareValue) {\n result.push(compareValue <= 0 ? array1[i] : array2[j]);\n }\n if (compareValue <= 0) {\n i++;\n }\n if (compareValue >= 0) {\n j++;\n }\n }\n if (mergeNotIntersect) {\n while (i < array1.length) {\n result.push(array1[i++]);\n }\n while (j < array2.length) {\n result.push(array2[j++]);\n }\n }\n return result;\n}\n\nexport const intersectOrdered = <T>(array1: T[], array2: T[], comparator: (a: T, b: T) => number): T[] => {\n return mergeOrIntersect(array1, array2, comparator, false);\n};\n\nexport const mergeOrdered = <T>(array1: T[], array2: T[], comparator: (a: T, b: T) => number): T[] => {\n return mergeOrIntersect(array1, array2, comparator, true);\n};\n\nexport const DEFAULT_COMPARATOR = (a: string|number, b: string|number): -1|0|1 => {\n return a < b ? -1 : (a > b ? 1 : 0);\n};\n\n/**\n * Returns the index of the element closest to the needle that is equal to or\n * greater than it. Assumes that the provided array is sorted.\n *\n * If no element is found, the right bound is returned.\n *\n * Uses the provided comparator function to determine if two items are equal or\n * if one is greater than the other. If you are working with strings or\n * numbers, you can use ArrayUtilities.DEFAULT_COMPARATOR. Otherwise, you\n * should define one that takes the needle element and an element from the\n * array and returns a positive or negative number to indicate which is greater\n * than the other.\n *\n * When specified, |left| (inclusive) and |right| (exclusive) indices\n * define the search window.\n */\nexport function lowerBound<T>(\n array: Uint32Array|Int32Array, needle: T, comparator: (needle: T, b: number) => number, left?: number,\n right?: number): number;\nexport function lowerBound<S, T>(\n array: S[], needle: T, comparator: (needle: T, b: S) => number, left?: number, right?: number): number;\nexport function lowerBound<S, T>(\n array: readonly S[], needle: T, comparator: (needle: T, b: S) => number, left?: number, right?: number): number;\nexport function lowerBound<S, T, A extends S[]>(\n array: A, needle: T, comparator: (needle: T, b: S) => number, left?: number, right?: number): number {\n let l = left || 0;\n let r = right !== undefined ? right : array.length;\n while (l < r) {\n const m = (l + r) >> 1;\n if (comparator(needle, array[m]) > 0) {\n l = m + 1;\n } else {\n r = m;\n }\n }\n return r;\n}\n\n/**\n * Returns the index of the element closest to the needle that is greater than\n * it. Assumes that the provided array is sorted.\n *\n * If no element is found, the right bound is returned.\n *\n * Uses the provided comparator function to determine if two items are equal or\n * if one is greater than the other. If you are working with strings or\n * numbers, you can use ArrayUtilities.DEFAULT_COMPARATOR. Otherwise, you\n * should define one that takes the needle element and an element from the\n * array and returns a positive or negative number to indicate which is greater\n * than the other.\n *\n * When specified, |left| (inclusive) and |right| (exclusive) indices\n * define the search window.\n */\nexport function upperBound<T>(\n array: Uint32Array, needle: T, comparator: (needle: T, b: number) => number, left?: number, right?: number): number;\nexport function upperBound<S, T>(\n array: S[], needle: T, comparator: (needle: T, b: S) => number, left?: number, right?: number): number;\nexport function upperBound<S, T, A extends S[]>(\n array: A, needle: T, comparator: (needle: T, b: S) => number, left?: number, right?: number): number {\n let l = left || 0;\n let r = right !== undefined ? right : array.length;\n while (l < r) {\n const m = (l + r) >> 1;\n if (comparator(needle, array[m]) >= 0) {\n l = m + 1;\n } else {\n r = m;\n }\n }\n return r;\n}\n\nconst enum NearestSearchStart {\n BEGINNING = 'BEGINNING',\n END = 'END',\n}\n/**\n * Obtains the first or last item in the array that satisfies the predicate function.\n * So, for example, if the array were arr = [2, 4, 6, 8, 10], and you are looking for\n * the last item arr[i] such that arr[i] < 5 you would be returned 1, because\n * array[1] is 4, the last item in the array that satisfies the\n * predicate function.\n *\n * If instead you were looking for the first item in the same array that satisfies\n * arr[i] > 5 you would be returned 2 because array[2] = 6.\n *\n * Please note: this presupposes that the array is already ordered.\n */\nfunction nearestIndex<T>(\n arr: readonly T[], predicate: (arrayItem: T) => boolean, searchStart: NearestSearchStart): number|null {\n const searchFromEnd = searchStart === NearestSearchStart.END;\n if (arr.length === 0) {\n return null;\n }\n\n let left = 0;\n let right = arr.length - 1;\n let pivot = 0;\n let matchesPredicate = false;\n let moveToTheRight = false;\n let middle = 0;\n do {\n middle = left + (right - left) / 2;\n pivot = searchFromEnd ? Math.ceil(middle) : Math.floor(middle);\n matchesPredicate = predicate(arr[pivot]);\n moveToTheRight = matchesPredicate === searchFromEnd;\n if (moveToTheRight) {\n left = Math.min(right, pivot + (left === pivot ? 1 : 0));\n } else {\n right = Math.max(left, pivot + (right === pivot ? -1 : 0));\n }\n } while (right !== left);\n\n // Special-case: the indexed item doesn't pass the predicate. This\n // occurs when none of the items in the array are a match for the\n // predicate.\n if (!predicate(arr[left])) {\n return null;\n }\n return left;\n}\n\n/**\n * Obtains the first item in the array that satisfies the predicate function.\n * So, for example, if the array was arr = [2, 4, 6, 8, 10], and you are looking for\n * the first item arr[i] such that arr[i] > 5 you would be returned 2, because\n * array[2] is 6, the first item in the array that satisfies the\n * predicate function.\n *\n * Please note: this presupposes that the array is already ordered.\n */\nexport function nearestIndexFromBeginning<T>(arr: T[], predicate: (arrayItem: T) => boolean): number|null {\n return nearestIndex(arr, predicate, NearestSearchStart.BEGINNING);\n}\n\n/**\n * Obtains the last item in the array that satisfies the predicate function.\n * So, for example, if the array was arr = [2, 4, 6, 8, 10], and you are looking for\n * the last item arr[i] such that arr[i] < 5 you would be returned 1, because\n * arr[1] is 4, the last item in the array that satisfies the\n * predicate function.\n *\n * Please note: this presupposes that the array is already ordered.\n */\n\nexport function nearestIndexFromEnd<T>(arr: readonly T[], predicate: (arrayItem: T) => boolean): number|null {\n return nearestIndex(arr, predicate, NearestSearchStart.END);\n}\n\n// Type guard for ensuring that `arr` does not contain null or undefined\nexport function arrayDoesNotContainNullOrUndefined<T>(arr: (T|null|undefined)[]): arr is T[] {\n return !arr.includes(null) && !arr.includes(undefined);\n}\n"]}
1
+ {"version":3,"file":"ArrayUtilities.js","sourceRoot":"","sources":["../../../../../../front_end/core/platform/ArrayUtilities.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) 2020 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 const removeElement = <T>(array: T[], element: T, firstOnly?: boolean): boolean => {\n let index = array.indexOf(element);\n if (index === -1) {\n return false;\n }\n if (firstOnly) {\n array.splice(index, 1);\n return true;\n }\n for (let i = index + 1, n = array.length; i < n; ++i) {\n if (array[i] !== element) {\n array[index++] = array[i];\n }\n }\n array.length = index;\n return true;\n};\n\ntype NumberComparator = (a: number, b: number) => number;\n\nfunction swap(array: number[], i1: number, i2: number): void {\n const temp = array[i1];\n array[i1] = array[i2];\n array[i2] = temp;\n}\n\nfunction partition(\n array: number[], comparator: NumberComparator, left: number, right: number, pivotIndex: number): number {\n const pivotValue = array[pivotIndex];\n swap(array, right, pivotIndex);\n let storeIndex = left;\n for (let i = left; i < right; ++i) {\n if (comparator(array[i], pivotValue) < 0) {\n swap(array, storeIndex, i);\n ++storeIndex;\n }\n }\n swap(array, right, storeIndex);\n return storeIndex;\n}\n\nfunction quickSortRange(\n array: number[], comparator: NumberComparator, left: number, right: number, sortWindowLeft: number,\n sortWindowRight: number): void {\n if (right <= left) {\n return;\n }\n const pivotIndex = Math.floor(Math.random() * (right - left)) + left;\n const pivotNewIndex = partition(array, comparator, left, right, pivotIndex);\n if (sortWindowLeft < pivotNewIndex) {\n quickSortRange(array, comparator, left, pivotNewIndex - 1, sortWindowLeft, sortWindowRight);\n }\n if (pivotNewIndex < sortWindowRight) {\n quickSortRange(array, comparator, pivotNewIndex + 1, right, sortWindowLeft, sortWindowRight);\n }\n}\n\nexport function sortRange(\n array: number[], comparator: NumberComparator, leftBound: number, rightBound: number, sortWindowLeft: number,\n sortWindowRight: number): number[] {\n if (leftBound === 0 && rightBound === (array.length - 1) && sortWindowLeft === 0 && sortWindowRight >= rightBound) {\n array.sort(comparator);\n } else {\n quickSortRange(array, comparator, leftBound, rightBound, sortWindowLeft, sortWindowRight);\n }\n return array;\n}\nexport const binaryIndexOf = <T, S>(array: T[], value: S, comparator: (a: S, b: T) => number): number => {\n const index = lowerBound(array, value, comparator);\n return index < array.length && comparator(value, array[index]) === 0 ? index : -1;\n};\n\nfunction mergeOrIntersect<T>(\n array1: T[], array2: T[], comparator: (a: T, b: T) => number, mergeNotIntersect: boolean): T[] {\n const result = [];\n let i = 0;\n let j = 0;\n while (i < array1.length && j < array2.length) {\n const compareValue = comparator(array1[i], array2[j]);\n if (mergeNotIntersect || !compareValue) {\n result.push(compareValue <= 0 ? array1[i] : array2[j]);\n }\n if (compareValue <= 0) {\n i++;\n }\n if (compareValue >= 0) {\n j++;\n }\n }\n if (mergeNotIntersect) {\n while (i < array1.length) {\n result.push(array1[i++]);\n }\n while (j < array2.length) {\n result.push(array2[j++]);\n }\n }\n return result;\n}\n\nexport const intersectOrdered = <T>(array1: T[], array2: T[], comparator: (a: T, b: T) => number): T[] => {\n return mergeOrIntersect(array1, array2, comparator, false);\n};\n\nexport const mergeOrdered = <T>(array1: T[], array2: T[], comparator: (a: T, b: T) => number): T[] => {\n return mergeOrIntersect(array1, array2, comparator, true);\n};\n\nexport const DEFAULT_COMPARATOR = (a: string|number, b: string|number): -1|0|1 => {\n return a < b ? -1 : (a > b ? 1 : 0);\n};\n\n/**\n * Returns the index of the element closest to the needle that is equal to or\n * greater than it. Assumes that the provided array is sorted.\n *\n * If no element is found, the right bound is returned.\n *\n * Uses the provided comparator function to determine if two items are equal or\n * if one is greater than the other. If you are working with strings or\n * numbers, you can use ArrayUtilities.DEFAULT_COMPARATOR. Otherwise, you\n * should define one that takes the needle element and an element from the\n * array and returns a positive or negative number to indicate which is greater\n * than the other.\n *\n * When specified, |left| (inclusive) and |right| (exclusive) indices\n * define the search window.\n */\nexport function lowerBound<T>(\n array: Uint32Array|Int32Array, needle: T, comparator: (needle: T, b: number) => number, left?: number,\n right?: number): number;\nexport function lowerBound<S, T>(\n array: S[], needle: T, comparator: (needle: T, b: S) => number, left?: number, right?: number): number;\nexport function lowerBound<S, T>(\n array: readonly S[], needle: T, comparator: (needle: T, b: S) => number, left?: number, right?: number): number;\nexport function lowerBound<S, T, A extends S[]>(\n array: A, needle: T, comparator: (needle: T, b: S) => number, left?: number, right?: number): number {\n let l = left || 0;\n let r = right !== undefined ? right : array.length;\n while (l < r) {\n const m = (l + r) >> 1;\n if (comparator(needle, array[m]) > 0) {\n l = m + 1;\n } else {\n r = m;\n }\n }\n return r;\n}\n\n/**\n * Returns the index of the element closest to the needle that is greater than\n * it. Assumes that the provided array is sorted.\n *\n * If no element is found, the right bound is returned.\n *\n * Uses the provided comparator function to determine if two items are equal or\n * if one is greater than the other. If you are working with strings or\n * numbers, you can use ArrayUtilities.DEFAULT_COMPARATOR. Otherwise, you\n * should define one that takes the needle element and an element from the\n * array and returns a positive or negative number to indicate which is greater\n * than the other.\n *\n * When specified, |left| (inclusive) and |right| (exclusive) indices\n * define the search window.\n */\nexport function upperBound<T>(\n array: Uint32Array, needle: T, comparator: (needle: T, b: number) => number, left?: number, right?: number): number;\nexport function upperBound<S, T>(\n array: S[], needle: T, comparator: (needle: T, b: S) => number, left?: number, right?: number): number;\nexport function upperBound<S, T, A extends S[]>(\n array: A, needle: T, comparator: (needle: T, b: S) => number, left?: number, right?: number): number {\n let l = left || 0;\n let r = right !== undefined ? right : array.length;\n while (l < r) {\n const m = (l + r) >> 1;\n if (comparator(needle, array[m]) >= 0) {\n l = m + 1;\n } else {\n r = m;\n }\n }\n return r;\n}\n\nconst enum NearestSearchStart {\n BEGINNING = 'BEGINNING',\n END = 'END',\n}\n/**\n * Obtains the first or last item in the array that satisfies the predicate function.\n * So, for example, if the array were arr = [2, 4, 6, 8, 10], and you are looking for\n * the last item arr[i] such that arr[i] < 5 you would be returned 1, because\n * array[1] is 4, the last item in the array that satisfies the\n * predicate function.\n *\n * If instead you were looking for the first item in the same array that satisfies\n * arr[i] > 5 you would be returned 2 because array[2] = 6.\n *\n * Please note: this presupposes that the array is already ordered.\n * This function uses a variation of Binary Search.\n */\nfunction nearestIndex<T>(\n arr: readonly T[], predicate: (arrayItem: T) => boolean, searchStart: NearestSearchStart): number|null {\n const searchFromEnd = searchStart === NearestSearchStart.END;\n if (arr.length === 0) {\n return null;\n }\n\n let left = 0;\n let right = arr.length - 1;\n let pivot = 0;\n let matchesPredicate = false;\n let moveToTheRight = false;\n let middle = 0;\n do {\n middle = left + (right - left) / 2;\n pivot = searchFromEnd ? Math.ceil(middle) : Math.floor(middle);\n matchesPredicate = predicate(arr[pivot]);\n moveToTheRight = matchesPredicate === searchFromEnd;\n if (moveToTheRight) {\n left = Math.min(right, pivot + (left === pivot ? 1 : 0));\n } else {\n right = Math.max(left, pivot + (right === pivot ? -1 : 0));\n }\n } while (right !== left);\n\n // Special-case: the indexed item doesn't pass the predicate. This\n // occurs when none of the items in the array are a match for the\n // predicate.\n if (!predicate(arr[left])) {\n return null;\n }\n return left;\n}\n\n/**\n * Obtains the first item in the array that satisfies the predicate function.\n * So, for example, if the array was arr = [2, 4, 6, 8, 10], and you are looking for\n * the first item arr[i] such that arr[i] > 5 you would be returned 2, because\n * array[2] is 6, the first item in the array that satisfies the\n * predicate function.\n *\n * Please note: this presupposes that the array is already ordered.\n */\nexport function nearestIndexFromBeginning<T>(arr: T[], predicate: (arrayItem: T) => boolean): number|null {\n return nearestIndex(arr, predicate, NearestSearchStart.BEGINNING);\n}\n\n/**\n * Obtains the last item in the array that satisfies the predicate function.\n * So, for example, if the array was arr = [2, 4, 6, 8, 10], and you are looking for\n * the last item arr[i] such that arr[i] < 5 you would be returned 1, because\n * arr[1] is 4, the last item in the array that satisfies the\n * predicate function.\n *\n * Please note: this presupposes that the array is already ordered.\n */\n\nexport function nearestIndexFromEnd<T>(arr: readonly T[], predicate: (arrayItem: T) => boolean): number|null {\n return nearestIndex(arr, predicate, NearestSearchStart.END);\n}\n\n// Type guard for ensuring that `arr` does not contain null or undefined\nexport function arrayDoesNotContainNullOrUndefined<T>(arr: (T|null|undefined)[]): arr is T[] {\n return !arr.includes(null) && !arr.includes(undefined);\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { type Brand } from './Brand.js';
1
+ import type { Brand } from './Brand.js';
2
2
  /**
3
3
  * File paths in DevTools that are represented as URLs
4
4
  * @example
@@ -1 +1 @@
1
- {"version":3,"file":"DevToolsPath.js","sourceRoot":"","sources":["../../../../../../front_end/core/platform/DevToolsPath.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAU7B,MAAM,CAAC,MAAM,cAAc,GAAG,EAAe,CAAC;AAS9C,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAmB,CAAC;AAQtD,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAuB,CAAC","sourcesContent":["// Copyright 2021 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 Brand} from './Brand.js';\n\n/**\n * File paths in DevTools that are represented as URLs\n * @example\n * “file:///Hello%20World/file/js”\n */\nexport type UrlString = Brand<string, 'UrlString'>;\nexport const EmptyUrlString = '' as UrlString;\n\n/**\n * File paths in DevTools that are represented as unencoded absolute\n * or relative paths\n * @example\n * “/Hello World/file.js”\n */\nexport type RawPathString = Brand<string, 'RawPathString'>;\nexport const EmptyRawPathString = '' as RawPathString;\n\n/**\n * File paths in DevTools that are represented as encoded paths\n * @example\n * “/Hello%20World/file.js”\n */\nexport type EncodedPathString = Brand<string, 'EncodedPathString'>;\nexport const EmptyEncodedPathString = '' as EncodedPathString;\n"]}
1
+ {"version":3,"file":"DevToolsPath.js","sourceRoot":"","sources":["../../../../../../front_end/core/platform/DevToolsPath.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAU7B,MAAM,CAAC,MAAM,cAAc,GAAG,EAAe,CAAC;AAS9C,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAmB,CAAC;AAQtD,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAuB,CAAC","sourcesContent":["// Copyright 2021 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 {Brand} from './Brand.js';\n\n/**\n * File paths in DevTools that are represented as URLs\n * @example\n * “file:///Hello%20World/file/js”\n */\nexport type UrlString = Brand<string, 'UrlString'>;\nexport const EmptyUrlString = '' as UrlString;\n\n/**\n * File paths in DevTools that are represented as unencoded absolute\n * or relative paths\n * @example\n * “/Hello World/file.js”\n */\nexport type RawPathString = Brand<string, 'RawPathString'>;\nexport const EmptyRawPathString = '' as RawPathString;\n\n/**\n * File paths in DevTools that are represented as encoded paths\n * @example\n * “/Hello%20World/file.js”\n */\nexport type EncodedPathString = Brand<string, 'EncodedPathString'>;\nexport const EmptyEncodedPathString = '' as EncodedPathString;\n"]}
@@ -9,12 +9,14 @@ const ADDITIONAL_TEXT_MIME_TYPES = new Set([
9
9
  'application/javascript',
10
10
  'application/json',
11
11
  'application/json+protobuf',
12
+ 'application/vnd.apple.mpegurl',
12
13
  'application/vnd.dart',
13
14
  'application/xml',
14
15
  'application/x-aspx',
15
16
  'application/x-javascript',
16
17
  'application/x-jsp',
17
18
  'application/x-httpd-php',
19
+ 'audio/mpegurl',
18
20
  ]);
19
21
  /**
20
22
  * @returns true iff `mimeType` has textual content. Concretely we return true if:
@@ -23,8 +25,8 @@ const ADDITIONAL_TEXT_MIME_TYPES = new Set([
23
25
  * - if `mimeType` is one of a predefined list textual mime types.
24
26
  */
25
27
  export function isTextType(mimeType) {
26
- return mimeType.startsWith('text/') || mimeType.endsWith('+json') || mimeType.endsWith('+xml') ||
27
- ADDITIONAL_TEXT_MIME_TYPES.has(mimeType);
28
+ return mimeType.startsWith('text/') || mimeType.startsWith('multipart/') || mimeType.includes('+json') ||
29
+ mimeType.endsWith('+xml') || ADDITIONAL_TEXT_MIME_TYPES.has(mimeType);
28
30
  }
29
31
  /**
30
32
  * Port of net::HttpUtils::ParseContentType to extract mimeType and charset from
@@ -1 +1 @@
1
- {"version":3,"file":"MimeType.js","sourceRoot":"","sources":["../../../../../../front_end/core/platform/MimeType.ts"],"names":[],"mappings":"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","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 const enum MimeType {\n HTML = 'text/html',\n XML = 'text/xml',\n PLAIN = 'text/plain',\n XHTML = 'application/xhtml+xml',\n SVG = 'image/svg+xml',\n CSS = 'text/css',\n XSL = 'text/xsl',\n VTT = 'text/vtt',\n PDF = 'application/pdf',\n EVENTSTREAM = 'text/event-stream',\n}\n\n/**\n * MIME types other than the ones with the \"text\" type that have text content.\n */\nconst ADDITIONAL_TEXT_MIME_TYPES = new Set([\n 'application/ecmascript',\n 'application/javascript',\n 'application/json',\n 'application/json+protobuf',\n 'application/vnd.dart',\n 'application/xml',\n 'application/x-aspx',\n 'application/x-javascript',\n 'application/x-jsp',\n 'application/x-httpd-php',\n]);\n\n/**\n * @returns true iff `mimeType` has textual content. Concretely we return true if:\n * - `mimeType` starts with \"text/\"\n * - `mimeType` ends with \"+json\" or \"+xml\"\n * - if `mimeType` is one of a predefined list textual mime types.\n */\nexport function isTextType(mimeType: string): boolean {\n return mimeType.startsWith('text/') || mimeType.endsWith('+json') || mimeType.endsWith('+xml') ||\n ADDITIONAL_TEXT_MIME_TYPES.has(mimeType);\n}\n\n/**\n * Port of net::HttpUtils::ParseContentType to extract mimeType and charset from\n * the 'Content-Type' header.\n */\nexport function parseContentType(contentType: string): {mimeType: string|null, charset: string|null} {\n if (contentType === '*/*') {\n return {mimeType: null, charset: null};\n }\n\n const {mimeType, params} = parseMimeType(contentType);\n const charset = params.get('charset')?.toLowerCase().trim() ?? null;\n return {mimeType, charset};\n}\n\nfunction parseMimeType(contentType: string): {mimeType: string|null, params: Map<string, string>} {\n // Remove any leading and trailing whitespace. Note that String.prototype.trim removes a lot more\n // than what the spec considers whitespace. We are fine with that.\n contentType = contentType.trim();\n\n // The mimetype is basically everything until the first ';' (but trimmed).\n let mimeTypeEnd = findFirstIndexOf(contentType, ' \\t;(');\n if (mimeTypeEnd < 0) {\n mimeTypeEnd = contentType.length;\n }\n\n const slashPos = contentType.indexOf('/');\n if (slashPos < 0 || slashPos > mimeTypeEnd) {\n return {mimeType: null, params: new Map()};\n }\n const mimeType = contentType.substring(0, mimeTypeEnd).toLowerCase();\n\n // Iterate over parameters. We can't split the string around semicolons because quoted\n // strings may include semicolons.\n const params = new Map<string, string>();\n let offset = contentType.indexOf(';', mimeTypeEnd);\n while (offset >= 0 && offset < contentType.length) {\n // Trim off the semicolon.\n ++offset;\n\n // Trim off whitespace\n offset = findFirstIndexNotOf(contentType, ' \\t', offset);\n if (offset < 0) {\n continue;\n }\n const paramNameStart = offset;\n\n // Extend parameter name until we run into semicolon or equals sign.\n offset = findFirstIndexOf(contentType, ';=', offset);\n if (offset < 0 || contentType[offset] === ';') {\n // Nothing more to do if no more input or there is no parameter value.\n continue;\n }\n\n const paramName = contentType.substring(paramNameStart, offset).toLowerCase();\n\n // Trim off the '='.\n ++offset;\n\n // Trim off whitespace.\n offset = findFirstIndexNotOf(contentType, ' \\t', offset);\n\n let paramValue = '';\n if (offset < 0 || contentType[offset] === ';') {\n // Nothing to do here: the value is an unquoted string of only whitespace.\n continue;\n } else if (contentType[offset] !== '\"') {\n // Not a quote so we can copy the value as-is.\n const valueStart = offset;\n offset = contentType.indexOf(';', offset);\n const valueEnd = offset >= 0 ? offset : contentType.length;\n\n paramValue = contentType.substring(valueStart, valueEnd).trimEnd();\n } else {\n // Otherwise append data with special handling for backslashes, until a close quote.\n // Don't trim whitespace for quoted strings.\n\n // Trim off the opening quote '\"'\n ++offset;\n\n while (offset < contentType.length && contentType[offset] !== '\"') {\n // Skip over backslash and append the next character, when not at the end\n // of the string. Otherwise, copy the next character (which may be a backslash).\n if (contentType[offset] === '\\\\' && offset + 1 < contentType.length) {\n ++offset;\n }\n paramValue += contentType[offset];\n ++offset;\n }\n\n offset = contentType.indexOf(';', offset);\n }\n if (!params.has(paramName)) {\n // The first one wins!\n params.set(paramName, paramValue);\n }\n }\n\n return {mimeType, params};\n}\n\n/**\n * @returns the smallest index of any character in 'characters' or -1 if none of\n * the characters occur in 'searchString'\n */\nfunction findFirstIndexOf(searchString: string, characters: string, pos: number = 0): number {\n for (let i = pos; i < searchString.length; i++) {\n if (characters.includes(searchString[i])) {\n return i;\n }\n }\n return -1;\n}\n\n/**\n * @returns the smallest index of any character not in 'characters' or -1 if only\n * 'characters' occur in 'searchString'\n */\nfunction findFirstIndexNotOf(searchString: string, characters: string, pos: number = 0): number {\n for (let i = pos; i < searchString.length; i++) {\n if (!characters.includes(searchString[i])) {\n return i;\n }\n }\n return -1;\n}\n"]}
1
+ {"version":3,"file":"MimeType.js","sourceRoot":"","sources":["../../../../../../front_end/core/platform/MimeType.ts"],"names":[],"mappings":"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","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 const enum MimeType {\n HTML = 'text/html',\n XML = 'text/xml',\n PLAIN = 'text/plain',\n XHTML = 'application/xhtml+xml',\n SVG = 'image/svg+xml',\n CSS = 'text/css',\n XSL = 'text/xsl',\n VTT = 'text/vtt',\n PDF = 'application/pdf',\n EVENTSTREAM = 'text/event-stream',\n}\n\n/**\n * MIME types other than the ones with the \"text\" type that have text content.\n */\nconst ADDITIONAL_TEXT_MIME_TYPES = new Set([\n 'application/ecmascript',\n 'application/javascript',\n 'application/json',\n 'application/json+protobuf',\n 'application/vnd.apple.mpegurl',\n 'application/vnd.dart',\n 'application/xml',\n 'application/x-aspx',\n 'application/x-javascript',\n 'application/x-jsp',\n 'application/x-httpd-php',\n 'audio/mpegurl',\n]);\n\n/**\n * @returns true iff `mimeType` has textual content. Concretely we return true if:\n * - `mimeType` starts with \"text/\"\n * - `mimeType` ends with \"+json\" or \"+xml\"\n * - if `mimeType` is one of a predefined list textual mime types.\n */\nexport function isTextType(mimeType: string): boolean {\n return mimeType.startsWith('text/') || mimeType.startsWith('multipart/') || mimeType.includes('+json') ||\n mimeType.endsWith('+xml') || ADDITIONAL_TEXT_MIME_TYPES.has(mimeType);\n}\n\n/**\n * Port of net::HttpUtils::ParseContentType to extract mimeType and charset from\n * the 'Content-Type' header.\n */\nexport function parseContentType(contentType: string): {mimeType: string|null, charset: string|null} {\n if (contentType === '*/*') {\n return {mimeType: null, charset: null};\n }\n\n const {mimeType, params} = parseMimeType(contentType);\n const charset = params.get('charset')?.toLowerCase().trim() ?? null;\n return {mimeType, charset};\n}\n\nfunction parseMimeType(contentType: string): {mimeType: string|null, params: Map<string, string>} {\n // Remove any leading and trailing whitespace. Note that String.prototype.trim removes a lot more\n // than what the spec considers whitespace. We are fine with that.\n contentType = contentType.trim();\n\n // The mimetype is basically everything until the first ';' (but trimmed).\n let mimeTypeEnd = findFirstIndexOf(contentType, ' \\t;(');\n if (mimeTypeEnd < 0) {\n mimeTypeEnd = contentType.length;\n }\n\n const slashPos = contentType.indexOf('/');\n if (slashPos < 0 || slashPos > mimeTypeEnd) {\n return {mimeType: null, params: new Map()};\n }\n const mimeType = contentType.substring(0, mimeTypeEnd).toLowerCase();\n\n // Iterate over parameters. We can't split the string around semicolons because quoted\n // strings may include semicolons.\n const params = new Map<string, string>();\n let offset = contentType.indexOf(';', mimeTypeEnd);\n while (offset >= 0 && offset < contentType.length) {\n // Trim off the semicolon.\n ++offset;\n\n // Trim off whitespace\n offset = findFirstIndexNotOf(contentType, ' \\t', offset);\n if (offset < 0) {\n continue;\n }\n const paramNameStart = offset;\n\n // Extend parameter name until we run into semicolon or equals sign.\n offset = findFirstIndexOf(contentType, ';=', offset);\n if (offset < 0 || contentType[offset] === ';') {\n // Nothing more to do if no more input or there is no parameter value.\n continue;\n }\n\n const paramName = contentType.substring(paramNameStart, offset).toLowerCase();\n\n // Trim off the '='.\n ++offset;\n\n // Trim off whitespace.\n offset = findFirstIndexNotOf(contentType, ' \\t', offset);\n\n let paramValue = '';\n if (offset < 0 || contentType[offset] === ';') {\n // Nothing to do here: the value is an unquoted string of only whitespace.\n continue;\n } else if (contentType[offset] !== '\"') {\n // Not a quote so we can copy the value as-is.\n const valueStart = offset;\n offset = contentType.indexOf(';', offset);\n const valueEnd = offset >= 0 ? offset : contentType.length;\n\n paramValue = contentType.substring(valueStart, valueEnd).trimEnd();\n } else {\n // Otherwise append data with special handling for backslashes, until a close quote.\n // Don't trim whitespace for quoted strings.\n\n // Trim off the opening quote '\"'\n ++offset;\n\n while (offset < contentType.length && contentType[offset] !== '\"') {\n // Skip over backslash and append the next character, when not at the end\n // of the string. Otherwise, copy the next character (which may be a backslash).\n if (contentType[offset] === '\\\\' && offset + 1 < contentType.length) {\n ++offset;\n }\n paramValue += contentType[offset];\n ++offset;\n }\n\n offset = contentType.indexOf(';', offset);\n }\n if (!params.has(paramName)) {\n // The first one wins!\n params.set(paramName, paramValue);\n }\n }\n\n return {mimeType, params};\n}\n\n/**\n * @returns the smallest index of any character in 'characters' or -1 if none of\n * the characters occur in 'searchString'\n */\nfunction findFirstIndexOf(searchString: string, characters: string, pos: number = 0): number {\n for (let i = pos; i < searchString.length; i++) {\n if (characters.includes(searchString[i])) {\n return i;\n }\n }\n return -1;\n}\n\n/**\n * @returns the smallest index of any character not in 'characters' or -1 if only\n * 'characters' occur in 'searchString'\n */\nfunction findFirstIndexNotOf(searchString: string, characters: string, pos: number = 0): number {\n for (let i = pos; i < searchString.length; i++) {\n if (!characters.includes(searchString[i])) {\n return i;\n }\n }\n return -1;\n}\n"]}
@@ -42,6 +42,14 @@ export const toFixedIfFloating = (value) => {
42
42
  * Rounds a number (including float) down.
43
43
  */
44
44
  export const floor = (value, precision = 0) => {
45
+ // Allows for rounding to the nearest whole number.
46
+ // Ex: 1 / 10 -> round down to nearest 10th place
47
+ // Ex: 1 / 5 -> round down to nearest 5
48
+ // Ex: 1 / 50 -> round down to nearest 50
49
+ if (precision > 0 && precision < 1) {
50
+ precision = 1 / precision;
51
+ return Math.floor(value / precision) * precision;
52
+ }
45
53
  const mult = Math.pow(10, precision);
46
54
  return Math.floor(value * mult) / mult;
47
55
  };
@@ -1 +1 @@
1
- {"version":3,"file":"NumberUtilities.js","sourceRoot":"","sources":["../../../../../../front_end/core/platform/NumberUtilities.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) 2020 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 const clamp = (num: number, min: number, max: number): number => {\n let clampedNumber = num;\n if (num < min) {\n clampedNumber = min;\n } else if (num > max) {\n clampedNumber = max;\n }\n return clampedNumber;\n};\n\nexport const mod = (m: number, n: number): number => {\n return ((m % n) + n) % n;\n};\n\nexport const bytesToString = (bytes: number): string => {\n if (bytes < 1000) {\n return `${bytes.toFixed(0)}\\xA0B`;\n }\n\n const kilobytes = bytes / 1000;\n if (kilobytes < 100) {\n return `${kilobytes.toFixed(1)}\\xA0kB`;\n }\n if (kilobytes < 1000) {\n return `${kilobytes.toFixed(0)}\\xA0kB`;\n }\n\n const megabytes = kilobytes / 1000;\n if (megabytes < 100) {\n return `${megabytes.toFixed(1)}\\xA0MB`;\n }\n return `${megabytes.toFixed(0)}\\xA0MB`;\n};\n\nexport const toFixedIfFloating = (value: string): string => {\n if (!value || Number.isNaN(Number(value))) {\n return value;\n }\n const number = Number(value);\n return number % 1 ? number.toFixed(3) : String(number);\n};\n\n/**\n * Rounds a number (including float) down.\n */\nexport const floor = (value: number, precision: number = 0): number => {\n const mult = Math.pow(10, precision);\n return Math.floor(value * mult) / mult;\n};\n\n/**\n * Computes the great common divisor for two numbers.\n * If the numbers are floats, they will be rounded to an integer.\n */\nexport const greatestCommonDivisor = (a: number, b: number): number => {\n a = Math.round(a);\n b = Math.round(b);\n while (b !== 0) {\n const t = b;\n b = a % b;\n a = t;\n }\n return a;\n};\n\nconst commonRatios = new Map([\n ['8∶5', '16∶10'],\n]);\n\nexport const aspectRatio = (width: number, height: number): string => {\n const divisor = greatestCommonDivisor(width, height);\n if (divisor !== 0) {\n width /= divisor;\n height /= divisor;\n }\n const result = `${width}∶${height}`;\n return commonRatios.get(result) || result;\n};\n\nexport const withThousandsSeparator = function(num: number): string {\n let str = String(num);\n const re = /(\\d+)(\\d{3})/;\n while (str.match(re)) {\n str = str.replace(re, '$1\\xA0$2');\n } // \\xa0 is a non-breaking space\n return str;\n};\n"]}
1
+ {"version":3,"file":"NumberUtilities.js","sourceRoot":"","sources":["../../../../../../front_end/core/platform/NumberUtilities.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) 2020 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 const clamp = (num: number, min: number, max: number): number => {\n let clampedNumber = num;\n if (num < min) {\n clampedNumber = min;\n } else if (num > max) {\n clampedNumber = max;\n }\n return clampedNumber;\n};\n\nexport const mod = (m: number, n: number): number => {\n return ((m % n) + n) % n;\n};\n\nexport const bytesToString = (bytes: number): string => {\n if (bytes < 1000) {\n return `${bytes.toFixed(0)}\\xA0B`;\n }\n\n const kilobytes = bytes / 1000;\n if (kilobytes < 100) {\n return `${kilobytes.toFixed(1)}\\xA0kB`;\n }\n if (kilobytes < 1000) {\n return `${kilobytes.toFixed(0)}\\xA0kB`;\n }\n\n const megabytes = kilobytes / 1000;\n if (megabytes < 100) {\n return `${megabytes.toFixed(1)}\\xA0MB`;\n }\n return `${megabytes.toFixed(0)}\\xA0MB`;\n};\n\nexport const toFixedIfFloating = (value: string): string => {\n if (!value || Number.isNaN(Number(value))) {\n return value;\n }\n const number = Number(value);\n return number % 1 ? number.toFixed(3) : String(number);\n};\n\n/**\n * Rounds a number (including float) down.\n */\nexport const floor = (value: number, precision: number = 0): number => {\n // Allows for rounding to the nearest whole number.\n // Ex: 1 / 10 -> round down to nearest 10th place\n // Ex: 1 / 5 -> round down to nearest 5\n // Ex: 1 / 50 -> round down to nearest 50\n if (precision > 0 && precision < 1) {\n precision = 1 / precision;\n return Math.floor(value / precision) * precision;\n }\n\n const mult = Math.pow(10, precision);\n return Math.floor(value * mult) / mult;\n};\n\n/**\n * Computes the great common divisor for two numbers.\n * If the numbers are floats, they will be rounded to an integer.\n */\nexport const greatestCommonDivisor = (a: number, b: number): number => {\n a = Math.round(a);\n b = Math.round(b);\n while (b !== 0) {\n const t = b;\n b = a % b;\n a = t;\n }\n return a;\n};\n\nconst commonRatios = new Map([\n ['8∶5', '16∶10'],\n]);\n\nexport const aspectRatio = (width: number, height: number): string => {\n const divisor = greatestCommonDivisor(width, height);\n if (divisor !== 0) {\n width /= divisor;\n height /= divisor;\n }\n const result = `${width}∶${height}`;\n return commonRatios.get(result) || result;\n};\n\nexport const withThousandsSeparator = function(num: number): string {\n let str = String(num);\n const re = /(\\d+)(\\d{3})/;\n while (str.match(re)) {\n str = str.replace(re, '$1\\xA0$2');\n } // \\xa0 is a non-breaking space\n return str;\n};\n"]}
@@ -0,0 +1,31 @@
1
+ export interface NameValue {
2
+ name: string;
3
+ value: string;
4
+ }
5
+ export type ServerTimingParsingWarningMessage = {
6
+ deprecratedSyntax: () => string;
7
+ duplicateParameter: (parameter: string) => string;
8
+ noValueFoundForParameter: (parameter: string) => string;
9
+ unrecognizedParameter: (parameter: string) => string;
10
+ extraneousTrailingCharacters: () => string;
11
+ unableToParseValue: (parameter: string, value: string) => string;
12
+ };
13
+ export declare class ServerTiming {
14
+ metric: string;
15
+ value: number;
16
+ description: string | null;
17
+ start: number | null;
18
+ constructor(metric: string, value: number, description: string | null, start: number | null);
19
+ static parseHeaders(headers: NameValue[], warningMessages?: ServerTimingParsingWarningMessage): ServerTiming[] | null;
20
+ /**
21
+ * TODO(crbug.com/1011811): Instead of using !Object<string, *> we should have a proper type
22
+ * with #name, desc and dur properties.
23
+ */
24
+ static createFromHeaderValue(valueString: string, warningMessages?: ServerTimingParsingWarningMessage): {
25
+ [x: string]: any;
26
+ }[];
27
+ static getParserForParameter(paramName: string, warningMessages: ServerTimingParsingWarningMessage): ((arg0: {
28
+ [x: string]: any;
29
+ }, arg1: string | null) => void) | null;
30
+ static showWarning(msg: string): void;
31
+ }
@@ -0,0 +1,212 @@
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 { compare } from './StringUtilities.js';
5
+ const defaultWarningMessages = {
6
+ deprecratedSyntax() {
7
+ return 'Deprecated syntax found. Please use: <name>;dur=<duration>;desc=<description>';
8
+ },
9
+ duplicateParameter(parameter) {
10
+ return `Duplicate parameter "${parameter}" ignored.`;
11
+ },
12
+ noValueFoundForParameter(parameter) {
13
+ return `No value found for parameter "${parameter}".`;
14
+ },
15
+ unrecognizedParameter(parameter) {
16
+ return `Unrecognized parameter "${parameter}".`;
17
+ },
18
+ extraneousTrailingCharacters() {
19
+ return 'Extraneous trailing characters.';
20
+ },
21
+ unableToParseValue(parameter, value) {
22
+ return `Unable to parse "${parameter}" value "${value}".`;
23
+ },
24
+ };
25
+ export class ServerTiming {
26
+ metric;
27
+ value;
28
+ description;
29
+ start;
30
+ constructor(metric, value, description, start) {
31
+ this.metric = metric;
32
+ this.value = value;
33
+ this.description = description;
34
+ this.start = start;
35
+ }
36
+ static parseHeaders(headers, warningMessages = defaultWarningMessages) {
37
+ const rawServerTimingHeaders = headers.filter(item => item.name.toLowerCase() === 'server-timing');
38
+ if (!rawServerTimingHeaders.length) {
39
+ return null;
40
+ }
41
+ const serverTimings = rawServerTimingHeaders.reduce((memo, header) => {
42
+ const timing = this.createFromHeaderValue(header.value, warningMessages);
43
+ memo.push(...timing.map(function (entry) {
44
+ return new ServerTiming(entry.name, entry.hasOwnProperty('dur') ? entry.dur : null, entry.hasOwnProperty('desc') ? entry.desc : '', entry.hasOwnProperty('start') ? entry.start : null);
45
+ }));
46
+ return memo;
47
+ }, []);
48
+ serverTimings.sort((a, b) => compare(a.metric.toLowerCase(), b.metric.toLowerCase()));
49
+ return serverTimings;
50
+ }
51
+ /**
52
+ * TODO(crbug.com/1011811): Instead of using !Object<string, *> we should have a proper type
53
+ * with #name, desc and dur properties.
54
+ */
55
+ static createFromHeaderValue(valueString, warningMessages = defaultWarningMessages) {
56
+ function trimLeadingWhiteSpace() {
57
+ valueString = valueString.replace(/^\s*/, '');
58
+ }
59
+ function consumeDelimiter(char) {
60
+ console.assert(char.length === 1);
61
+ trimLeadingWhiteSpace();
62
+ if (valueString.charAt(0) !== char) {
63
+ return false;
64
+ }
65
+ valueString = valueString.substring(1);
66
+ return true;
67
+ }
68
+ function consumeToken() {
69
+ // https://tools.ietf.org/html/rfc7230#appendix-B
70
+ const result = /^(?:\s*)([\w!#$%&'*+\-.^`|~]+)(?:\s*)(.*)/.exec(valueString);
71
+ if (!result) {
72
+ return null;
73
+ }
74
+ valueString = result[2];
75
+ return result[1];
76
+ }
77
+ function consumeTokenOrQuotedString() {
78
+ trimLeadingWhiteSpace();
79
+ if (valueString.charAt(0) === '"') {
80
+ return consumeQuotedString();
81
+ }
82
+ return consumeToken();
83
+ }
84
+ function consumeQuotedString() {
85
+ console.assert(valueString.charAt(0) === '"');
86
+ valueString = valueString.substring(1); // remove leading DQUOTE
87
+ let value = '';
88
+ while (valueString.length) {
89
+ // split into two parts:
90
+ // -everything before the first " or \
91
+ // -everything else
92
+ const result = /^([^"\\]*)(.*)/.exec(valueString);
93
+ if (!result) {
94
+ return null; // not a valid quoted-string
95
+ }
96
+ value += result[1];
97
+ if (result[2].charAt(0) === '"') {
98
+ // we have found our closing "
99
+ valueString = result[2].substring(1); // strip off everything after the closing "
100
+ return value; // we are done here
101
+ }
102
+ console.assert(result[2].charAt(0) === '\\');
103
+ // special rules for \ found in quoted-string (https://tools.ietf.org/html/rfc7230#section-3.2.6)
104
+ value += result[2].charAt(1); // grab the character AFTER the \ (if there was one)
105
+ valueString = result[2].substring(2); // strip off \ and next character
106
+ }
107
+ return null; // not a valid quoted-string
108
+ }
109
+ function consumeExtraneous() {
110
+ const result = /([,;].*)/.exec(valueString);
111
+ if (result) {
112
+ valueString = result[1];
113
+ }
114
+ }
115
+ const result = [];
116
+ let name;
117
+ while ((name = consumeToken()) !== null) {
118
+ const entry = { name };
119
+ if (valueString.charAt(0) === '=') {
120
+ this.showWarning(warningMessages['deprecratedSyntax']());
121
+ }
122
+ while (consumeDelimiter(';')) {
123
+ let paramName;
124
+ if ((paramName = consumeToken()) === null) {
125
+ continue;
126
+ }
127
+ paramName = paramName.toLowerCase();
128
+ const parseParameter = this.getParserForParameter(paramName, warningMessages);
129
+ let paramValue = null;
130
+ if (consumeDelimiter('=')) {
131
+ // always parse the value, even if we don't recognize the parameter #name
132
+ paramValue = consumeTokenOrQuotedString();
133
+ consumeExtraneous();
134
+ }
135
+ if (parseParameter) {
136
+ // paramName is valid
137
+ if (entry.hasOwnProperty(paramName)) {
138
+ this.showWarning(warningMessages['duplicateParameter'](paramName));
139
+ continue;
140
+ }
141
+ if (paramValue === null) {
142
+ this.showWarning(warningMessages['noValueFoundForParameter'](paramName));
143
+ }
144
+ parseParameter.call(this, entry, paramValue);
145
+ }
146
+ else {
147
+ // paramName is not valid
148
+ this.showWarning(warningMessages['unrecognizedParameter'](paramName));
149
+ }
150
+ }
151
+ result.push(entry);
152
+ if (!consumeDelimiter(',')) {
153
+ break;
154
+ }
155
+ }
156
+ if (valueString.length) {
157
+ this.showWarning(warningMessages['extraneousTrailingCharacters']());
158
+ }
159
+ return result;
160
+ }
161
+ static getParserForParameter(paramName, warningMessages) {
162
+ switch (paramName) {
163
+ case 'dur': {
164
+ function durParser(entry,
165
+ // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration
166
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
167
+ paramValue) {
168
+ entry.dur = 0;
169
+ if (paramValue !== null) {
170
+ const duration = parseFloat(paramValue);
171
+ if (isNaN(duration)) {
172
+ ServerTiming.showWarning(warningMessages['unableToParseValue'](paramName, paramValue));
173
+ return;
174
+ }
175
+ entry.dur = duration;
176
+ }
177
+ }
178
+ return durParser;
179
+ }
180
+ case 'start': {
181
+ function startParser(entry,
182
+ // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration
183
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
184
+ paramValue) {
185
+ entry.start = null;
186
+ if (paramValue !== null) {
187
+ const start = parseFloat(paramValue);
188
+ if (isNaN(start)) {
189
+ ServerTiming.showWarning(warningMessages['unableToParseValue'](paramName, paramValue));
190
+ return;
191
+ }
192
+ entry.start = start;
193
+ }
194
+ }
195
+ return startParser;
196
+ }
197
+ case 'desc': {
198
+ function descParser(entry, paramValue) {
199
+ entry.desc = paramValue || '';
200
+ }
201
+ return descParser;
202
+ }
203
+ default: {
204
+ return null;
205
+ }
206
+ }
207
+ }
208
+ static showWarning(msg) {
209
+ console.warn(`ServerTiming: ${msg}`);
210
+ }
211
+ }
212
+ //# sourceMappingURL=ServerTiming.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ServerTiming.js","sourceRoot":"","sources":["../../../../../../front_end/core/platform/ServerTiming.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 {compare} from './StringUtilities.js';\n\nexport interface NameValue {\n name: string;\n value: string;\n}\nconst defaultWarningMessages: ServerTimingParsingWarningMessage = {\n deprecratedSyntax() {\n return 'Deprecated syntax found. Please use: <name>;dur=<duration>;desc=<description>';\n },\n duplicateParameter(parameter) {\n return `Duplicate parameter \"${parameter}\" ignored.`;\n },\n noValueFoundForParameter(parameter) {\n return `No value found for parameter \"${parameter}\".`;\n },\n unrecognizedParameter(parameter) {\n return `Unrecognized parameter \"${parameter}\".`;\n },\n extraneousTrailingCharacters() {\n return 'Extraneous trailing characters.';\n },\n unableToParseValue(parameter, value) {\n return `Unable to parse \"${parameter}\" value \"${value}\".`;\n },\n};\n\nexport type ServerTimingParsingWarningMessage = {\n deprecratedSyntax: () => string,\n duplicateParameter: (parameter: string) => string,\n noValueFoundForParameter: (parameter: string) => string,\n unrecognizedParameter: (parameter: string) => string,\n extraneousTrailingCharacters: () => string,\n unableToParseValue: (parameter: string, value: string) => string,\n};\n\nexport class ServerTiming {\n metric: string;\n value: number;\n description: string|null;\n start: number|null;\n\n constructor(metric: string, value: number, description: string|null, start: number|null) {\n this.metric = metric;\n this.value = value;\n this.description = description;\n this.start = start;\n }\n\n static parseHeaders(\n headers: NameValue[],\n warningMessages: ServerTimingParsingWarningMessage = defaultWarningMessages): ServerTiming[]|null {\n const rawServerTimingHeaders = headers.filter(item => item.name.toLowerCase() === 'server-timing');\n if (!rawServerTimingHeaders.length) {\n return null;\n }\n\n const serverTimings = rawServerTimingHeaders.reduce((memo, header) => {\n const timing = this.createFromHeaderValue(header.value, warningMessages);\n memo.push(...timing.map(function(entry) {\n return new ServerTiming(\n entry.name, entry.hasOwnProperty('dur') ? entry.dur : null, entry.hasOwnProperty('desc') ? entry.desc : '',\n entry.hasOwnProperty('start') ? entry.start : null);\n }));\n return memo;\n }, ([] as ServerTiming[]));\n serverTimings.sort((a, b) => compare(a.metric.toLowerCase(), b.metric.toLowerCase()));\n return serverTimings;\n }\n\n /**\n * TODO(crbug.com/1011811): Instead of using !Object<string, *> we should have a proper type\n * with #name, desc and dur properties.\n */\n static createFromHeaderValue(\n valueString: string, warningMessages: ServerTimingParsingWarningMessage = defaultWarningMessages): {\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [x: string]: any,\n }[] {\n function trimLeadingWhiteSpace(): void {\n valueString = valueString.replace(/^\\s*/, '');\n }\n function consumeDelimiter(char: string): boolean {\n console.assert(char.length === 1);\n trimLeadingWhiteSpace();\n if (valueString.charAt(0) !== char) {\n return false;\n }\n\n valueString = valueString.substring(1);\n return true;\n }\n function consumeToken(): string|null {\n // https://tools.ietf.org/html/rfc7230#appendix-B\n const result = /^(?:\\s*)([\\w!#$%&'*+\\-.^`|~]+)(?:\\s*)(.*)/.exec(valueString);\n if (!result) {\n return null;\n }\n\n valueString = result[2];\n return result[1];\n }\n function consumeTokenOrQuotedString(): string|null {\n trimLeadingWhiteSpace();\n if (valueString.charAt(0) === '\"') {\n return consumeQuotedString();\n }\n\n return consumeToken();\n }\n function consumeQuotedString(): string|null {\n console.assert(valueString.charAt(0) === '\"');\n valueString = valueString.substring(1); // remove leading DQUOTE\n\n let value = '';\n while (valueString.length) {\n // split into two parts:\n // -everything before the first \" or \\\n // -everything else\n const result = /^([^\"\\\\]*)(.*)/.exec(valueString);\n if (!result) {\n return null; // not a valid quoted-string\n }\n value += result[1];\n if (result[2].charAt(0) === '\"') {\n // we have found our closing \"\n valueString = result[2].substring(1); // strip off everything after the closing \"\n return value; // we are done here\n }\n\n console.assert(result[2].charAt(0) === '\\\\');\n // special rules for \\ found in quoted-string (https://tools.ietf.org/html/rfc7230#section-3.2.6)\n value += result[2].charAt(1); // grab the character AFTER the \\ (if there was one)\n valueString = result[2].substring(2); // strip off \\ and next character\n }\n\n return null; // not a valid quoted-string\n }\n function consumeExtraneous(): void {\n const result = /([,;].*)/.exec(valueString);\n if (result) {\n valueString = result[1];\n }\n }\n\n const result = [];\n let name;\n while ((name = consumeToken()) !== null) {\n const entry = {name};\n\n if (valueString.charAt(0) === '=') {\n this.showWarning(warningMessages['deprecratedSyntax']());\n }\n\n while (consumeDelimiter(';')) {\n let paramName;\n if ((paramName = consumeToken()) === null) {\n continue;\n }\n\n paramName = paramName.toLowerCase();\n const parseParameter = this.getParserForParameter(paramName, warningMessages);\n let paramValue: (string|null)|null = null;\n if (consumeDelimiter('=')) {\n // always parse the value, even if we don't recognize the parameter #name\n paramValue = consumeTokenOrQuotedString();\n consumeExtraneous();\n }\n\n if (parseParameter) {\n // paramName is valid\n if (entry.hasOwnProperty(paramName)) {\n this.showWarning(warningMessages['duplicateParameter'](paramName));\n continue;\n }\n\n if (paramValue === null) {\n this.showWarning(warningMessages['noValueFoundForParameter'](paramName));\n }\n\n parseParameter.call(this, entry, paramValue);\n } else {\n // paramName is not valid\n this.showWarning(warningMessages['unrecognizedParameter'](paramName));\n }\n }\n\n result.push(entry);\n if (!consumeDelimiter(',')) {\n break;\n }\n }\n\n if (valueString.length) {\n this.showWarning(warningMessages['extraneousTrailingCharacters']());\n }\n return result;\n }\n\n static getParserForParameter(paramName: string, warningMessages: ServerTimingParsingWarningMessage):\n ((arg0: {\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [x: string]: any,\n },\n arg1: string|null) => void)|null {\n switch (paramName) {\n case 'dur': {\n function durParser(\n entry: {\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [x: string]: any,\n },\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n paramValue: any): void {\n entry.dur = 0;\n if (paramValue !== null) {\n const duration = parseFloat(paramValue);\n if (isNaN(duration)) {\n ServerTiming.showWarning(warningMessages['unableToParseValue'](paramName, paramValue));\n return;\n }\n entry.dur = duration;\n }\n }\n return durParser;\n }\n case 'start': {\n function startParser(\n entry: {\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [x: string]: any,\n },\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n paramValue: any): void {\n entry.start = null;\n if (paramValue !== null) {\n const start = parseFloat(paramValue);\n if (isNaN(start)) {\n ServerTiming.showWarning(warningMessages['unableToParseValue'](paramName, paramValue));\n return;\n }\n entry.start = start;\n }\n }\n return startParser;\n }\n case 'desc': {\n function descParser(\n entry: {\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [x: string]: any,\n },\n paramValue: string|null): void {\n entry.desc = paramValue || '';\n }\n return descParser;\n }\n\n default: {\n return null;\n }\n }\n }\n\n static showWarning(msg: string): void {\n console.warn(`ServerTiming: ${msg}`);\n }\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { type Brand } from './Brand.js';
1
+ import type { Brand } from './Brand.js';
2
2
  export type Seconds = Brand<number, 'Seconds'>;
3
3
  export type MilliSeconds = Brand<number, 'MilliSeconds'>;
4
4
  export type MicroSeconds = Brand<number, 'MicroSeconds'>;