@paulirish/trace_engine 0.0.10 → 0.0.11

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 (205) hide show
  1. package/analyze-trace.mjs +1 -1
  2. package/core/platform/DevToolsPath.d.ts +4 -13
  3. package/core/platform/DevToolsPath.js +7 -4
  4. package/core/platform/DevToolsPath.js.map +1 -7
  5. package/core/platform/MimeType.d.ts +27 -0
  6. package/core/platform/MimeType.js +119 -86
  7. package/core/platform/MimeType.js.map +1 -7
  8. package/core/platform/Timing.d.ts +7 -0
  9. package/core/platform/Timing.js +7 -4
  10. package/core/platform/Timing.js.map +1 -7
  11. package/core/platform/UIString.d.ts +2 -5
  12. package/core/platform/UIString.js +5 -2
  13. package/core/platform/UIString.js.map +1 -7
  14. package/core/platform/UserVisibleError.js +19 -10
  15. package/core/platform/UserVisibleError.js.map +1 -7
  16. package/core/platform/array-utilities.d.ts +48 -10
  17. package/core/platform/array-utilities.js +160 -124
  18. package/core/platform/array-utilities.js.map +1 -7
  19. package/core/platform/brand.d.ts +14 -0
  20. package/core/platform/brand.js +5 -1
  21. package/core/platform/brand.js.map +1 -7
  22. package/core/platform/date-utilities.js +10 -6
  23. package/core/platform/date-utilities.js.map +1 -7
  24. package/core/platform/dom-utilities.d.ts +3 -1
  25. package/core/platform/dom-utilities.js +94 -83
  26. package/core/platform/dom-utilities.js.map +1 -7
  27. package/core/platform/keyboard-utilities.d.ts +2 -0
  28. package/core/platform/keyboard-utilities.js +15 -24
  29. package/core/platform/keyboard-utilities.js.map +1 -7
  30. package/core/platform/map-utilities.d.ts +4 -0
  31. package/core/platform/map-utilities.js +66 -60
  32. package/core/platform/map-utilities.js.map +1 -7
  33. package/core/platform/number-utilities.js +66 -55
  34. package/core/platform/number-utilities.js.map +1 -7
  35. package/core/platform/platform.d.ts +5 -1
  36. package/core/platform/platform.js +54 -37
  37. package/core/platform/platform.js.map +1 -7
  38. package/core/platform/promise-utilities.d.ts +10 -0
  39. package/core/platform/promise-utilities.js +16 -8
  40. package/core/platform/promise-utilities.js.map +1 -7
  41. package/core/platform/set-utilities.js +20 -17
  42. package/core/platform/set-utilities.js.map +1 -7
  43. package/core/platform/string-utilities.d.ts +32 -1
  44. package/core/platform/string-utilities.js +453 -379
  45. package/core/platform/string-utilities.js.map +1 -7
  46. package/core/platform/typescript-utilities.d.ts +5 -5
  47. package/core/platform/typescript-utilities.js +19 -7
  48. package/core/platform/typescript-utilities.js.map +1 -7
  49. package/generated/protocol.d.ts +2081 -347
  50. package/generated/protocol.js +5 -2230
  51. package/models/cpu_profile/CPUProfileDataModel.d.ts +77 -0
  52. package/models/cpu_profile/CPUProfileDataModel.js +492 -359
  53. package/models/cpu_profile/CPUProfileDataModel.js.map +1 -7
  54. package/models/cpu_profile/ProfileTreeModel.d.ts +29 -0
  55. package/models/cpu_profile/ProfileTreeModel.js +87 -82
  56. package/models/cpu_profile/ProfileTreeModel.js.map +1 -7
  57. package/models/cpu_profile/cpu_profile.d.ts +3 -0
  58. package/models/cpu_profile/cpu_profile.js +7 -7
  59. package/models/cpu_profile/cpu_profile.js.map +1 -7
  60. package/models/trace/EntriesFilter.d.ts +55 -0
  61. package/models/trace/EntriesFilter.js +227 -166
  62. package/models/trace/EntriesFilter.js.map +1 -7
  63. package/models/trace/LegacyTracingModel.js.map +1 -7
  64. package/models/trace/ModelImpl.d.ts +110 -0
  65. package/models/trace/ModelImpl.js +161 -102
  66. package/models/trace/ModelImpl.js.map +1 -7
  67. package/models/trace/Processor.d.ts +36 -0
  68. package/models/trace/Processor.js +197 -163
  69. package/models/trace/Processor.js.map +1 -7
  70. package/models/trace/TracingManager.js.map +1 -7
  71. package/models/trace/extras/FetchNodes.d.ts +46 -0
  72. package/models/trace/extras/FetchNodes.js +132 -91
  73. package/models/trace/extras/FetchNodes.js.map +1 -7
  74. package/models/trace/extras/FilmStrip.d.ts +19 -0
  75. package/models/trace/extras/FilmStrip.js +38 -31
  76. package/models/trace/extras/FilmStrip.js.map +1 -7
  77. package/models/trace/extras/MainThreadActivity.d.ts +2 -0
  78. package/models/trace/extras/MainThreadActivity.js +72 -56
  79. package/models/trace/extras/MainThreadActivity.js.map +1 -7
  80. package/models/trace/extras/Metadata.d.ts +2 -0
  81. package/models/trace/extras/Metadata.js +42 -26
  82. package/models/trace/extras/Metadata.js.map +1 -7
  83. package/models/trace/extras/extras.js.map +1 -7
  84. package/models/trace/handlers/AnimationHandler.d.ts +8 -0
  85. package/models/trace/handlers/AnimationHandler.js +22 -20
  86. package/models/trace/handlers/AnimationHandler.js.map +1 -7
  87. package/models/trace/handlers/AuctionWorkletsHandler.d.ts +8 -0
  88. package/models/trace/handlers/AuctionWorkletsHandler.js +143 -89
  89. package/models/trace/handlers/AuctionWorkletsHandler.js.map +1 -7
  90. package/models/trace/handlers/FramesHandler.d.ts +76 -0
  91. package/models/trace/handlers/FramesHandler.js +424 -355
  92. package/models/trace/handlers/FramesHandler.js.map +1 -7
  93. package/models/trace/handlers/GPUHandler.d.ts +11 -0
  94. package/models/trace/handlers/GPUHandler.js +41 -37
  95. package/models/trace/handlers/GPUHandler.js.map +1 -7
  96. package/models/trace/handlers/InitiatorsHandler.d.ts +10 -0
  97. package/models/trace/handlers/InitiatorsHandler.js +164 -113
  98. package/models/trace/handlers/InitiatorsHandler.js.map +1 -7
  99. package/models/trace/handlers/InvalidationsHandler.d.ts +10 -0
  100. package/models/trace/handlers/InvalidationsHandler.js +101 -79
  101. package/models/trace/handlers/InvalidationsHandler.js.map +1 -7
  102. package/models/trace/handlers/LargestImagePaintHandler.d.ts +5 -0
  103. package/models/trace/handlers/LargestImagePaintHandler.js +32 -12
  104. package/models/trace/handlers/LargestImagePaintHandler.js.map +1 -7
  105. package/models/trace/handlers/LargestTextPaintHandler.d.ts +5 -0
  106. package/models/trace/handlers/LargestTextPaintHandler.js +20 -12
  107. package/models/trace/handlers/LargestTextPaintHandler.js.map +1 -7
  108. package/models/trace/handlers/LayerTreeHandler.d.ts +13 -0
  109. package/models/trace/handlers/LayerTreeHandler.js +96 -70
  110. package/models/trace/handlers/LayerTreeHandler.js.map +1 -7
  111. package/models/trace/handlers/LayoutShiftsHandler.d.ts +44 -0
  112. package/models/trace/handlers/LayoutShiftsHandler.js +304 -227
  113. package/models/trace/handlers/LayoutShiftsHandler.js.map +1 -7
  114. package/models/trace/handlers/MemoryHandler.d.ts +7 -0
  115. package/models/trace/handlers/MemoryHandler.js +14 -11
  116. package/models/trace/handlers/MemoryHandler.js.map +1 -7
  117. package/models/trace/handlers/MetaHandler.d.ts +37 -0
  118. package/models/trace/handlers/MetaHandler.js +314 -226
  119. package/models/trace/handlers/MetaHandler.js.map +1 -7
  120. package/models/trace/handlers/ModelHandlers.d.ts +21 -0
  121. package/models/trace/handlers/ModelHandlers.js +25 -22
  122. package/models/trace/handlers/ModelHandlers.js.map +1 -7
  123. package/models/trace/handlers/NetworkRequestsHandler.d.ts +17 -0
  124. package/models/trace/handlers/NetworkRequestsHandler.js +342 -218
  125. package/models/trace/handlers/NetworkRequestsHandler.js.map +1 -7
  126. package/models/trace/handlers/PageLoadMetricsHandler.d.ts +67 -0
  127. package/models/trace/handlers/PageLoadMetricsHandler.js +357 -284
  128. package/models/trace/handlers/PageLoadMetricsHandler.js.map +1 -7
  129. package/models/trace/handlers/RendererHandler.d.ts +101 -0
  130. package/models/trace/handlers/RendererHandler.js +295 -191
  131. package/models/trace/handlers/RendererHandler.js.map +1 -7
  132. package/models/trace/handlers/SamplesHandler.d.ts +46 -0
  133. package/models/trace/handlers/SamplesHandler.js +195 -158
  134. package/models/trace/handlers/SamplesHandler.js.map +1 -7
  135. package/models/trace/handlers/ScreenshotsHandler.d.ts +7 -0
  136. package/models/trace/handlers/ScreenshotsHandler.js +63 -41
  137. package/models/trace/handlers/ScreenshotsHandler.js.map +1 -7
  138. package/models/trace/handlers/Threads.d.ts +33 -0
  139. package/models/trace/handlers/Threads.js +85 -67
  140. package/models/trace/handlers/Threads.js.map +1 -7
  141. package/models/trace/handlers/UserInteractionsHandler.d.ts +57 -0
  142. package/models/trace/handlers/UserInteractionsHandler.js +240 -141
  143. package/models/trace/handlers/UserInteractionsHandler.js.map +1 -7
  144. package/models/trace/handlers/UserTimingsHandler.d.ts +28 -0
  145. package/models/trace/handlers/UserTimingsHandler.js +91 -80
  146. package/models/trace/handlers/UserTimingsHandler.js.map +1 -7
  147. package/models/trace/handlers/WarningsHandler.d.ts +14 -0
  148. package/models/trace/handlers/WarningsHandler.js +100 -62
  149. package/models/trace/handlers/WarningsHandler.js.map +1 -7
  150. package/models/trace/handlers/WorkersHandler.d.ts +11 -0
  151. package/models/trace/handlers/WorkersHandler.js +40 -38
  152. package/models/trace/handlers/WorkersHandler.js.map +1 -7
  153. package/models/trace/handlers/handlers.d.ts +3 -0
  154. package/models/trace/handlers/handlers.js +7 -4
  155. package/models/trace/handlers/handlers.js.map +1 -7
  156. package/models/trace/handlers/types.d.ts +45 -0
  157. package/models/trace/handlers/types.js +15 -15
  158. package/models/trace/handlers/types.js.map +1 -7
  159. package/models/trace/helpers/SamplesIntegrator.d.ts +49 -0
  160. package/models/trace/helpers/SamplesIntegrator.js +381 -204
  161. package/models/trace/helpers/SamplesIntegrator.js.map +1 -7
  162. package/models/trace/helpers/Timing.d.ts +26 -0
  163. package/models/trace/helpers/Timing.js +131 -110
  164. package/models/trace/helpers/Timing.js.map +1 -7
  165. package/models/trace/helpers/Trace.d.ts +37 -0
  166. package/models/trace/helpers/Trace.js +200 -166
  167. package/models/trace/helpers/Trace.js.map +1 -7
  168. package/models/trace/helpers/TreeHelpers.d.ts +90 -0
  169. package/models/trace/helpers/TreeHelpers.js +203 -100
  170. package/models/trace/helpers/TreeHelpers.js.map +1 -7
  171. package/models/trace/helpers/helpers.d.ts +4 -0
  172. package/models/trace/helpers/helpers.js +8 -5
  173. package/models/trace/helpers/helpers.js.map +1 -7
  174. package/models/trace/root-causes/LayoutShift.d.ts +119 -0
  175. package/models/trace/root-causes/LayoutShift.js +470 -323
  176. package/models/trace/root-causes/LayoutShift.js.map +1 -7
  177. package/models/trace/root-causes/RootCauses.d.ts +14 -0
  178. package/models/trace/root-causes/RootCauses.js +9 -6
  179. package/models/trace/root-causes/RootCauses.js.map +1 -7
  180. package/models/trace/root-causes/root-causes.d.ts +1 -0
  181. package/models/trace/root-causes/root-causes.js +5 -2
  182. package/models/trace/root-causes/root-causes.js.map +1 -7
  183. package/models/trace/trace.d.ts +11 -0
  184. package/models/trace/trace.js +17 -23
  185. package/models/trace/trace.js.map +1 -7
  186. package/models/trace/types/Configuration.d.ts +33 -0
  187. package/models/trace/types/Configuration.js +25 -14
  188. package/models/trace/types/Configuration.js.map +1 -7
  189. package/models/trace/types/File.d.ts +23 -0
  190. package/models/trace/types/File.js +5 -6
  191. package/models/trace/types/File.js.map +1 -7
  192. package/models/trace/types/Timing.d.ts +25 -0
  193. package/models/trace/types/Timing.js +10 -11
  194. package/models/trace/types/Timing.js.map +1 -7
  195. package/models/trace/types/TraceEvents.d.ts +1571 -0
  196. package/models/trace/types/TraceEvents.js +174 -381
  197. package/models/trace/types/TraceEvents.js.map +1 -7
  198. package/models/trace/types/types.d.ts +4 -0
  199. package/models/trace/types/types.js +8 -5
  200. package/models/trace/types/types.js.map +1 -7
  201. package/package.json +1 -1
  202. package/TracingManager.js +0 -0
  203. package/extras/extras.js +0 -0
  204. package/trace.mjs +0 -6980
  205. package/trace.mjs.map +0 -8
@@ -1,7 +1 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../../../front_end/models/trace/ModelImpl.ts"],
4
- "sourcesContent": ["// Copyright 2022 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';\n\nimport * as Handlers from './handlers/handlers.js';\nimport * as Helpers from './helpers/helpers.js';\nimport {TraceParseProgressEvent, TraceProcessor} from './Processor.js';\nimport * as Types from './types/types.js';\n\n// Note: this model is implemented in a way that can support multiple trace\n// processors. Currently there is only one implemented, but you will see\n// references to \"processors\" plural because it can easily be extended in the future.\n\nexport interface ParseConfig {\n metadata?: Types.File.MetaData;\n // Unused but will eventually be consumed by UIUtils Linkifier, etc.\n isFreshRecording?: boolean;\n}\n\n/**\n * The new trace engine model we are migrating to. The Model is responsible for\n * parsing arrays of raw trace events and storing the resulting data. It can\n * store multiple traces at once, and can return the data for any of them.\n * Currently as we migrate from the old engine to this, we are turning on the\n * model handlers incrementally as we need the data, to save performance costs\n * of running handlers that we do not use. Therefore, when the model is\n * constructed we pass through a set of handlers that should be used. Once we\n * have migrated all tracks in the Performance Panel to this model, we can\n * remove this ability to run a subset of handlers, as we will need all handlers\n * to be used at that point. For tests, if you want to construct a model with\n * all handlers, you can use the static `Model.createWithAllHandlers` method.\n **/\nexport class Model<EnabledModelHandlers extends {[key: string]: Handlers.Types.TraceEventHandler}> extends EventTarget {\n readonly #traces: ParsedTraceFile<EnabledModelHandlers>[] = [];\n readonly #nextNumberByDomain = new Map<string, number>();\n\n readonly #recordingsAvailable: string[] = [];\n #lastRecordingIndex = 0;\n #processor: TraceProcessor<Handlers.Types.HandlersWithMeta<EnabledModelHandlers>>;\n #config: Types.Configuration.Configuration = Types.Configuration.DEFAULT;\n\n static createWithAllHandlers(config?: Types.Configuration.Configuration): Model<typeof Handlers.ModelHandlers> {\n return new Model(Handlers.ModelHandlers, config);\n }\n\n constructor(handlers: EnabledModelHandlers, config?: Types.Configuration.Configuration) {\n super();\n if (config) {\n this.#config = config;\n }\n this.#processor = new TraceProcessor(handlers, this.#config);\n }\n\n /**\n * Updates the configuration. Useful if a user changes a setting - this lets\n * us update the model without having to destroy it and recreate it with the\n * new settings.\n */\n updateConfiguration(config: Types.Configuration.Configuration): void {\n this.#config = config;\n this.#processor.updateConfiguration(config);\n }\n\n /**\n * Parses an array of trace events into a structured object containing all the\n * information parsed by the trace handlers.\n * You can `await` this function to pause execution until parsing is complete,\n * or instead rely on the `ModuleUpdateEvent` that is dispatched when the\n * parsing is finished.\n *\n * Once parsed, you then have to call the `traceParsedData` method, providing an\n * index of the trace you want to have the data for. This is because any model\n * can store a number of traces. Each trace is given an index, which starts at 0\n * and increments by one as a new trace is parsed.\n *\n * @example\n * // Awaiting the parse method() to block until parsing complete\n * await this.traceModel.parse(events);\n * const data = this.traceModel.traceParsedData(0)\n *\n * @example\n * // Using an event listener to be notified when tracing is complete.\n * this.traceModel.addEventListener(Trace.ModelUpdateEvent.eventName, (event) => {\n * if(event.data.data === 'done') {\n * // trace complete\n * const data = this.traceModel.traceParsedData(0);\n * }\n * });\n * void this.traceModel.parse(events);\n **/\n async parse(traceEvents: readonly Types.TraceEvents.TraceEventData[], config?: ParseConfig): Promise<void> {\n const metadata = config?.metadata || {};\n const isFreshRecording = config?.isFreshRecording || false;\n // During parsing, periodically update any listeners on each processors'\n // progress (if they have any updates).\n const onTraceUpdate = (event: Event): void => {\n const {data} = event as TraceParseProgressEvent;\n this.dispatchEvent(new ModelUpdateEvent({type: ModelUpdateType.PROGRESS_UPDATE, data: data}));\n };\n\n this.#processor.addEventListener(TraceParseProgressEvent.eventName, onTraceUpdate);\n\n // Create a parsed trace file. It will be populated with data from the processor.\n const file: ParsedTraceFile<EnabledModelHandlers> = {\n traceEvents,\n metadata,\n traceParsedData: null,\n };\n\n try {\n // Wait for all outstanding promises before finishing the async execution,\n // but perform all tasks in parallel.\n await this.#processor.parse(traceEvents, isFreshRecording);\n this.#storeParsedFileData(file, this.#processor.data);\n // We only push the file onto this.#traces here once we know it's valid\n // and there's been no errors in the parsing.\n this.#traces.push(file);\n } catch (e) {\n throw e;\n } finally {\n // All processors have finished parsing, no more updates are expected.\n this.#processor.removeEventListener(TraceParseProgressEvent.eventName, onTraceUpdate);\n // Finally, update any listeners that all processors are 'done'.\n this.dispatchEvent(new ModelUpdateEvent({type: ModelUpdateType.COMPLETE, data: 'done'}));\n }\n }\n\n #storeParsedFileData(\n file: ParsedTraceFile<EnabledModelHandlers>,\n data: Handlers.Types.EnabledHandlerDataWithMeta<EnabledModelHandlers>|null): void {\n file.traceParsedData = data;\n this.#lastRecordingIndex++;\n let recordingName = `Trace ${this.#lastRecordingIndex}`;\n let origin: string|null = null;\n if (file.traceParsedData) {\n origin = Helpers.Trace.extractOriginFromTrace(file.traceParsedData.Meta.mainFrameURL);\n if (origin) {\n const nextSequenceForDomain = Platform.MapUtilities.getWithDefault(this.#nextNumberByDomain, origin, () => 1);\n recordingName = `${origin} (${nextSequenceForDomain})`;\n this.#nextNumberByDomain.set(origin, nextSequenceForDomain + 1);\n }\n }\n this.#recordingsAvailable.push(recordingName);\n }\n\n /**\n * Returns the parsed trace data indexed by the order in which it was stored.\n * If no index is given, the last stored parsed data is returned.\n */\n traceParsedData(index: number = this.#traces.length - 1):\n Handlers.Types.EnabledHandlerDataWithMeta<EnabledModelHandlers>|null {\n if (!this.#traces[index]) {\n return null;\n }\n\n return this.#traces[index].traceParsedData;\n }\n\n metadata(index: number): Types.File.MetaData|null {\n if (!this.#traces[index]) {\n return null;\n }\n\n return this.#traces[index].metadata;\n }\n\n traceEvents(index: number): readonly Types.TraceEvents.TraceEventData[]|null {\n if (!this.#traces[index]) {\n return null;\n }\n\n return this.#traces[index].traceEvents;\n }\n\n size(): number {\n return this.#traces.length;\n }\n\n deleteTraceByIndex(recordingIndex: number): void {\n this.#traces.splice(recordingIndex, 1);\n this.#recordingsAvailable.splice(recordingIndex, 1);\n }\n\n getRecordingsAvailable(): string[] {\n return this.#recordingsAvailable;\n }\n\n resetProcessor(): void {\n this.#processor.reset();\n }\n}\n\n/**\n * This parsed trace file is used by the Model. It keeps multiple instances\n * of these so that the user can swap between them. The key is that it is\n * essentially the TraceFile plus whatever the model has parsed from it.\n */\nexport type ParsedTraceFile<Handlers extends {[key: string]: Handlers.Types.TraceEventHandler}> = Types.File.TraceFile&{\n traceParsedData: Handlers.Types.EnabledHandlerDataWithMeta<Handlers>| null,\n};\n\nexport const enum ModelUpdateType {\n COMPLETE = 'COMPLETE',\n PROGRESS_UPDATE = 'PROGRESS_UPDATE',\n}\n\nexport type ModelUpdateEventData = ModelUpdateEventComplete|ModelUpdateEventProgress;\n\nexport type ModelUpdateEventComplete = {\n type: ModelUpdateType.COMPLETE,\n data: 'done',\n};\nexport type ModelUpdateEventProgress = {\n type: ModelUpdateType.PROGRESS_UPDATE,\n data: TraceParseEventProgressData,\n};\n\nexport type TraceParseEventProgressData = {\n index: number,\n total: number,\n};\n\nexport class ModelUpdateEvent extends Event {\n static readonly eventName = 'modelupdate';\n constructor(public data: ModelUpdateEventData) {\n super(ModelUpdateEvent.eventName);\n }\n}\n\ndeclare global {\n interface HTMLElementEventMap {\n [ModelUpdateEvent.eventName]: ModelUpdateEvent;\n }\n}\n\nexport function isModelUpdateDataComplete(eventData: ModelUpdateEventData): eventData is ModelUpdateEventComplete {\n return eventData.type === ModelUpdateType.COMPLETE;\n}\n\nexport function isModelUpdateDataProgress(eventData: ModelUpdateEventData): eventData is ModelUpdateEventProgress {\n return eventData.type === ModelUpdateType.PROGRESS_UPDATE;\n}\n"],
5
- "mappings": "AAIA;AAEA;AACA;AACA;AACA;AAyBO,2BAAoG,YAAY;AAAA,YACzD;AAAA,wBAC7B,oBAAI;AAAA,yBAEO;AAAA,wBACpB;AAAA;AAAA,YAEuB,MAAM,cAAc;AAAA,SAE1D,sBAAsB,QAAkF;AAC7G,WAAO,IAAI,MAAM,SAAS,eAAe;AAAA;AAAA,EAG3C,YAAY,UAAgC,QAA4C;AACtF;AACA,QAAI,QAAQ;AACV,qBAAe;AAAA;AAEjB,sBAAkB,IAAI,eAAe,UAAU;AAAA;AAAA,EAQjD,oBAAoB,QAAiD;AACnE,mBAAe;AACf,oBAAgB,oBAAoB;AAAA;AAAA,QA8BhC,MAAM,aAA0D,QAAqC;AACzG,UAAM,WAAW,QAAQ,YAAY;AACrC,UAAM,mBAAmB,QAAQ,oBAAoB;AAGrD,UAAM,gBAAgB,CAAC,UAAuB;AAC5C,YAAM,EAAC,SAAQ;AACf,WAAK,cAAc,IAAI,iBAAiB,EAAC,MAAM,gBAAgB,iBAAiB;AAAA;AAGlF,oBAAgB,iBAAiB,wBAAwB,WAAW;AAGpE,UAAM,OAA8C;AAAA,MAClD;AAAA,MACA;AAAA,MACA,iBAAiB;AAAA;AAGnB,QAAI;AAGF,YAAM,gBAAgB,MAAM,aAAa;AACzC,gCAA0B,MAAM,gBAAgB;AAGhD,mBAAa,KAAK;AAAA,aACX,GAAP;AACA,YAAM;AAAA,cACN;AAEA,sBAAgB,oBAAoB,wBAAwB,WAAW;AAEvE,WAAK,cAAc,IAAI,iBAAiB,EAAC,MAAM,gBAAgB,UAAU,MAAM;AAAA;AAAA;AAAA,uBAK/E,MACA,MAAkF;AACpF,SAAK,kBAAkB;AACvB;AACA,QAAI,gBAAgB,SAAS;AAC7B,QAAI,SAAsB;AAC1B,QAAI,KAAK,iBAAiB;AACxB,eAAS,QAAQ,MAAM,uBAAuB,KAAK,gBAAgB,KAAK;AACxE,UAAI,QAAQ;AACV,cAAM,wBAAwB,SAAS,aAAa,eAAe,0BAA0B,QAAQ,MAAM;AAC3G,wBAAgB,GAAG,WAAW;AAC9B,iCAAyB,IAAI,QAAQ,wBAAwB;AAAA;AAAA;AAGjE,8BAA0B,KAAK;AAAA;AAAA,EAOjC,gBAAgB,QAAgB,aAAa,SAAS,GACmB;AACvE,QAAI,CAAC,aAAa,QAAQ;AACxB,aAAO;AAAA;AAGT,WAAO,aAAa,OAAO;AAAA;AAAA,EAG7B,SAAS,OAAyC;AAChD,QAAI,CAAC,aAAa,QAAQ;AACxB,aAAO;AAAA;AAGT,WAAO,aAAa,OAAO;AAAA;AAAA,EAG7B,YAAY,OAAiE;AAC3E,QAAI,CAAC,aAAa,QAAQ;AACxB,aAAO;AAAA;AAGT,WAAO,aAAa,OAAO;AAAA;AAAA,EAG7B,OAAe;AACb,WAAO,aAAa;AAAA;AAAA,EAGtB,mBAAmB,gBAA8B;AAC/C,iBAAa,OAAO,gBAAgB;AACpC,8BAA0B,OAAO,gBAAgB;AAAA;AAAA,EAGnD,yBAAmC;AACjC,WAAO;AAAA;AAAA,EAGT,iBAAuB;AACrB,oBAAgB;AAAA;AAAA;AAab,WAAW,kBAAX,kBAAW,qBAAX;AACL,iCAAW;AACX,wCAAkB;AAFF;AAAA;AAqBX,sCAA+B,MAAM;AAAA,EAE1C,YAAmB,MAA4B;AAC7C,UAAM,iBAAiB;AADN;AAAA;AAAA,SADH,YAAY;AAAA;AAYvB,0CAAmC,WAAwE;AAChH,SAAO,UAAU,SAAS;AAAA;AAGrB,0CAAmC,WAAwE;AAChH,SAAO,UAAU,SAAS;AAAA;",
6
- "names": []
7
- }
1
+ {"version":3,"file":"ModelImpl.js","sourceRoot":"","sources":["../../../../../../front_end/models/trace/ModelImpl.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2022 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';\n\nimport * as Handlers from './handlers/handlers.js';\nimport * as Helpers from './helpers/helpers.js';\nimport {TraceParseProgressEvent, TraceProcessor} from './Processor.js';\nimport * as Types from './types/types.js';\n\n// Note: this model is implemented in a way that can support multiple trace\n// processors. Currently there is only one implemented, but you will see\n// references to \"processors\" plural because it can easily be extended in the future.\n\nexport interface ParseConfig {\n metadata?: Types.File.MetaData;\n // Unused but will eventually be consumed by UIUtils Linkifier, etc.\n isFreshRecording?: boolean;\n}\n\n/**\n * The new trace engine model we are migrating to. The Model is responsible for\n * parsing arrays of raw trace events and storing the resulting data. It can\n * store multiple traces at once, and can return the data for any of them.\n * Currently as we migrate from the old engine to this, we are turning on the\n * model handlers incrementally as we need the data, to save performance costs\n * of running handlers that we do not use. Therefore, when the model is\n * constructed we pass through a set of handlers that should be used. Once we\n * have migrated all tracks in the Performance Panel to this model, we can\n * remove this ability to run a subset of handlers, as we will need all handlers\n * to be used at that point. For tests, if you want to construct a model with\n * all handlers, you can use the static `Model.createWithAllHandlers` method.\n **/\nexport class Model<EnabledModelHandlers extends {[key: string]: Handlers.Types.TraceEventHandler}> extends EventTarget {\n readonly #traces: ParsedTraceFile<EnabledModelHandlers>[] = [];\n readonly #nextNumberByDomain = new Map<string, number>();\n\n readonly #recordingsAvailable: string[] = [];\n #lastRecordingIndex = 0;\n #processor: TraceProcessor<Handlers.Types.HandlersWithMeta<EnabledModelHandlers>>;\n #config: Types.Configuration.Configuration = Types.Configuration.DEFAULT;\n\n static createWithAllHandlers(config?: Types.Configuration.Configuration): Model<typeof Handlers.ModelHandlers> {\n return new Model(Handlers.ModelHandlers, config);\n }\n\n constructor(handlers: EnabledModelHandlers, config?: Types.Configuration.Configuration) {\n super();\n if (config) {\n this.#config = config;\n }\n this.#processor = new TraceProcessor(handlers, this.#config);\n }\n\n /**\n * Updates the configuration. Useful if a user changes a setting - this lets\n * us update the model without having to destroy it and recreate it with the\n * new settings.\n */\n updateConfiguration(config: Types.Configuration.Configuration): void {\n this.#config = config;\n this.#processor.updateConfiguration(config);\n }\n\n /**\n * Parses an array of trace events into a structured object containing all the\n * information parsed by the trace handlers.\n * You can `await` this function to pause execution until parsing is complete,\n * or instead rely on the `ModuleUpdateEvent` that is dispatched when the\n * parsing is finished.\n *\n * Once parsed, you then have to call the `traceParsedData` method, providing an\n * index of the trace you want to have the data for. This is because any model\n * can store a number of traces. Each trace is given an index, which starts at 0\n * and increments by one as a new trace is parsed.\n *\n * @example\n * // Awaiting the parse method() to block until parsing complete\n * await this.traceModel.parse(events);\n * const data = this.traceModel.traceParsedData(0)\n *\n * @example\n * // Using an event listener to be notified when tracing is complete.\n * this.traceModel.addEventListener(Trace.ModelUpdateEvent.eventName, (event) => {\n * if(event.data.data === 'done') {\n * // trace complete\n * const data = this.traceModel.traceParsedData(0);\n * }\n * });\n * void this.traceModel.parse(events);\n **/\n async parse(traceEvents: readonly Types.TraceEvents.TraceEventData[], config?: ParseConfig): Promise<void> {\n const metadata = config?.metadata || {};\n const isFreshRecording = config?.isFreshRecording || false;\n // During parsing, periodically update any listeners on each processors'\n // progress (if they have any updates).\n const onTraceUpdate = (event: Event): void => {\n const {data} = event as TraceParseProgressEvent;\n this.dispatchEvent(new ModelUpdateEvent({type: ModelUpdateType.PROGRESS_UPDATE, data: data}));\n };\n\n this.#processor.addEventListener(TraceParseProgressEvent.eventName, onTraceUpdate);\n\n // Create a parsed trace file. It will be populated with data from the processor.\n const file: ParsedTraceFile<EnabledModelHandlers> = {\n traceEvents,\n metadata,\n traceParsedData: null,\n };\n\n try {\n // Wait for all outstanding promises before finishing the async execution,\n // but perform all tasks in parallel.\n await this.#processor.parse(traceEvents, isFreshRecording);\n this.#storeParsedFileData(file, this.#processor.data);\n // We only push the file onto this.#traces here once we know it's valid\n // and there's been no errors in the parsing.\n this.#traces.push(file);\n } catch (e) {\n throw e;\n } finally {\n // All processors have finished parsing, no more updates are expected.\n this.#processor.removeEventListener(TraceParseProgressEvent.eventName, onTraceUpdate);\n // Finally, update any listeners that all processors are 'done'.\n this.dispatchEvent(new ModelUpdateEvent({type: ModelUpdateType.COMPLETE, data: 'done'}));\n }\n }\n\n #storeParsedFileData(\n file: ParsedTraceFile<EnabledModelHandlers>,\n data: Handlers.Types.EnabledHandlerDataWithMeta<EnabledModelHandlers>|null): void {\n file.traceParsedData = data;\n this.#lastRecordingIndex++;\n let recordingName = `Trace ${this.#lastRecordingIndex}`;\n let origin: string|null = null;\n if (file.traceParsedData) {\n origin = Helpers.Trace.extractOriginFromTrace(file.traceParsedData.Meta.mainFrameURL);\n if (origin) {\n const nextSequenceForDomain = Platform.MapUtilities.getWithDefault(this.#nextNumberByDomain, origin, () => 1);\n recordingName = `${origin} (${nextSequenceForDomain})`;\n this.#nextNumberByDomain.set(origin, nextSequenceForDomain + 1);\n }\n }\n this.#recordingsAvailable.push(recordingName);\n }\n\n /**\n * Returns the parsed trace data indexed by the order in which it was stored.\n * If no index is given, the last stored parsed data is returned.\n */\n traceParsedData(index: number = this.#traces.length - 1):\n Handlers.Types.EnabledHandlerDataWithMeta<EnabledModelHandlers>|null {\n if (!this.#traces[index]) {\n return null;\n }\n\n return this.#traces[index].traceParsedData;\n }\n\n metadata(index: number): Types.File.MetaData|null {\n if (!this.#traces[index]) {\n return null;\n }\n\n return this.#traces[index].metadata;\n }\n\n traceEvents(index: number): readonly Types.TraceEvents.TraceEventData[]|null {\n if (!this.#traces[index]) {\n return null;\n }\n\n return this.#traces[index].traceEvents;\n }\n\n size(): number {\n return this.#traces.length;\n }\n\n deleteTraceByIndex(recordingIndex: number): void {\n this.#traces.splice(recordingIndex, 1);\n this.#recordingsAvailable.splice(recordingIndex, 1);\n }\n\n getRecordingsAvailable(): string[] {\n return this.#recordingsAvailable;\n }\n\n resetProcessor(): void {\n this.#processor.reset();\n }\n}\n\n/**\n * This parsed trace file is used by the Model. It keeps multiple instances\n * of these so that the user can swap between them. The key is that it is\n * essentially the TraceFile plus whatever the model has parsed from it.\n */\nexport type ParsedTraceFile<Handlers extends {[key: string]: Handlers.Types.TraceEventHandler}> = Types.File.TraceFile&{\n traceParsedData: Handlers.Types.EnabledHandlerDataWithMeta<Handlers>| null,\n};\n\nexport const enum ModelUpdateType {\n COMPLETE = 'COMPLETE',\n PROGRESS_UPDATE = 'PROGRESS_UPDATE',\n}\n\nexport type ModelUpdateEventData = ModelUpdateEventComplete|ModelUpdateEventProgress;\n\nexport type ModelUpdateEventComplete = {\n type: ModelUpdateType.COMPLETE,\n data: 'done',\n};\nexport type ModelUpdateEventProgress = {\n type: ModelUpdateType.PROGRESS_UPDATE,\n data: TraceParseEventProgressData,\n};\n\nexport type TraceParseEventProgressData = {\n index: number,\n total: number,\n};\n\nexport class ModelUpdateEvent extends Event {\n static readonly eventName = 'modelupdate';\n constructor(public data: ModelUpdateEventData) {\n super(ModelUpdateEvent.eventName);\n }\n}\n\ndeclare global {\n interface HTMLElementEventMap {\n [ModelUpdateEvent.eventName]: ModelUpdateEvent;\n }\n}\n\nexport function isModelUpdateDataComplete(eventData: ModelUpdateEventData): eventData is ModelUpdateEventComplete {\n return eventData.type === ModelUpdateType.COMPLETE;\n}\n\nexport function isModelUpdateDataProgress(eventData: ModelUpdateEventData): eventData is ModelUpdateEventProgress {\n return eventData.type === ModelUpdateType.PROGRESS_UPDATE;\n}\n"]}
@@ -0,0 +1,36 @@
1
+ import * as Handlers from './handlers/handlers.js';
2
+ import * as Types from './types/types.js';
3
+ export type TraceParseEventProgressData = {
4
+ index: number;
5
+ total: number;
6
+ };
7
+ export declare class TraceParseProgressEvent extends Event {
8
+ data: TraceParseEventProgressData;
9
+ static readonly eventName = "traceparseprogress";
10
+ constructor(data: TraceParseEventProgressData, init?: EventInit);
11
+ }
12
+ declare global {
13
+ interface HTMLElementEventMap {
14
+ [TraceParseProgressEvent.eventName]: TraceParseProgressEvent;
15
+ }
16
+ }
17
+ export declare class TraceProcessor<EnabledModelHandlers extends {
18
+ [key: string]: Handlers.Types.TraceEventHandler;
19
+ }> extends EventTarget {
20
+ #private;
21
+ static createWithAllHandlers(): TraceProcessor<typeof Handlers.ModelHandlers>;
22
+ constructor(traceHandlers: EnabledModelHandlers, modelConfiguration?: Types.Configuration.Configuration);
23
+ updateConfiguration(config: Types.Configuration.Configuration): void;
24
+ reset(): void;
25
+ parse(traceEvents: readonly Types.TraceEvents.TraceEventData[], freshRecording?: boolean): Promise<void>;
26
+ get data(): Handlers.Types.EnabledHandlerDataWithMeta<EnabledModelHandlers> | null;
27
+ }
28
+ /**
29
+ * Some Handlers need data provided by others. Dependencies of a handler handler are
30
+ * declared in the `deps` field.
31
+ * @returns A map from trace event handler name to trace event hander whose entries
32
+ * iterate in such a way that each handler is visited after its dependencies.
33
+ */
34
+ export declare function sortHandlers(traceHandlers: Partial<{
35
+ [key in Handlers.Types.TraceEventHandlerName]: Handlers.Types.TraceEventHandler;
36
+ }>): Map<Handlers.Types.TraceEventHandlerName, Handlers.Types.TraceEventHandler>;
@@ -1,179 +1,213 @@
1
- import * as Handlers from "./handlers/handlers.js";
2
- import * as Types from "./types/types.js";
3
- var Status = /* @__PURE__ */ ((Status2) => {
4
- Status2["IDLE"] = "IDLE";
5
- Status2["PARSING"] = "PARSING";
6
- Status2["FINISHED_PARSING"] = "FINISHED_PARSING";
7
- Status2["ERRORED_WHILE_PARSING"] = "ERRORED_WHILE_PARSING";
8
- return Status2;
9
- })(Status || {});
1
+ // Copyright 2023 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 Handlers from './handlers/handlers.js';
5
+ import * as Types from './types/types.js';
10
6
  export class TraceParseProgressEvent extends Event {
11
- constructor(data, init = { bubbles: true }) {
12
- super(TraceParseProgressEvent.eventName, init);
13
- this.data = data;
14
- }
15
- static eventName = "traceparseprogress";
7
+ data;
8
+ static eventName = 'traceparseprogress';
9
+ constructor(data, init = { bubbles: true }) {
10
+ super(TraceParseProgressEvent.eventName, init);
11
+ this.data = data;
12
+ }
16
13
  }
17
14
  export class TraceProcessor extends EventTarget {
18
- #traceHandlers;
19
- #status = "IDLE" /* IDLE */;
20
- #modelConfiguration = Types.Configuration.DEFAULT;
21
- static createWithAllHandlers() {
22
- return new TraceProcessor(Handlers.ModelHandlers, Types.Configuration.DEFAULT);
23
- }
24
- constructor(traceHandlers, modelConfiguration) {
25
- super();
26
- this.#verifyHandlers(traceHandlers);
27
- this.#traceHandlers = {
28
- Meta: Handlers.ModelHandlers.Meta,
29
- ...traceHandlers
30
- };
31
- if (modelConfiguration) {
32
- this.#modelConfiguration = modelConfiguration;
33
- }
34
- this.#passConfigToHandlers();
35
- }
36
- updateConfiguration(config) {
37
- this.#modelConfiguration = config;
38
- this.#passConfigToHandlers();
39
- }
40
- #passConfigToHandlers() {
41
- for (const handler of Object.values(this.#traceHandlers)) {
42
- if ("handleUserConfig" in handler && handler.handleUserConfig) {
43
- handler.handleUserConfig(this.#modelConfiguration);
44
- }
45
- }
46
- }
47
- #verifyHandlers(providedHandlers) {
48
- if (Object.keys(providedHandlers).length === Object.keys(Handlers.ModelHandlers).length) {
49
- return;
50
- }
51
- const requiredHandlerKeys = /* @__PURE__ */ new Set();
52
- for (const [handlerName, handler] of Object.entries(providedHandlers)) {
53
- requiredHandlerKeys.add(handlerName);
54
- for (const depName of handler.deps?.() || []) {
55
- requiredHandlerKeys.add(depName);
56
- }
57
- }
58
- const providedHandlerKeys = new Set(Object.keys(providedHandlers));
59
- requiredHandlerKeys.delete("Meta");
60
- for (const requiredKey of requiredHandlerKeys) {
61
- if (!providedHandlerKeys.has(requiredKey)) {
62
- throw new Error(`Required handler ${requiredKey} not provided.`);
63
- }
64
- }
65
- }
66
- reset() {
67
- if (this.#status === "PARSING" /* PARSING */) {
68
- throw new Error("Trace processor can't reset while parsing.");
69
- }
70
- const handlers = Object.values(this.#traceHandlers);
71
- for (const handler of handlers) {
72
- handler.reset();
73
- }
74
- this.#status = "IDLE" /* IDLE */;
75
- }
76
- async parse(traceEvents, freshRecording = false) {
77
- if (this.#status !== "IDLE" /* IDLE */) {
78
- throw new Error(`Trace processor can't start parsing when not idle. Current state: ${this.#status}`);
79
- }
80
- try {
81
- this.#status = "PARSING" /* PARSING */;
82
- await this.#parse(traceEvents, freshRecording);
83
- this.#status = "FINISHED_PARSING" /* FINISHED_PARSING */;
84
- } catch (e) {
85
- this.#status = "ERRORED_WHILE_PARSING" /* ERRORED_WHILE_PARSING */;
86
- throw e;
87
- }
88
- }
89
- async #parse(traceEvents, freshRecording) {
90
- const { pauseDuration, eventsPerChunk } = this.#modelConfiguration.processing;
91
- const traceEventIterator = new TraceEventIterator(traceEvents, pauseDuration, eventsPerChunk);
92
- const sortedHandlers = [...sortHandlers(this.#traceHandlers).values()];
93
- for (const handler of sortedHandlers) {
94
- handler.reset();
15
+ // We force the Meta handler to be enabled, so the TraceHandlers type here is
16
+ // the model handlers the user passes in and the Meta handler.
17
+ // eslint-disable-next-line @typescript-eslint/naming-convention
18
+ #traceHandlers;
19
+ #status = "IDLE" /* Status.IDLE */;
20
+ #modelConfiguration = Types.Configuration.DEFAULT;
21
+ static createWithAllHandlers() {
22
+ return new TraceProcessor(Handlers.ModelHandlers, Types.Configuration.DEFAULT);
23
+ }
24
+ constructor(traceHandlers, modelConfiguration) {
25
+ super();
26
+ this.#verifyHandlers(traceHandlers);
27
+ this.#traceHandlers = {
28
+ Meta: Handlers.ModelHandlers.Meta,
29
+ ...traceHandlers,
30
+ };
31
+ if (modelConfiguration) {
32
+ this.#modelConfiguration = modelConfiguration;
33
+ }
34
+ this.#passConfigToHandlers();
35
+ }
36
+ updateConfiguration(config) {
37
+ this.#modelConfiguration = config;
38
+ this.#passConfigToHandlers();
39
+ }
40
+ #passConfigToHandlers() {
41
+ for (const handler of Object.values(this.#traceHandlers)) {
42
+ // Bit of an odd double check, but without this TypeScript refuses to let
43
+ // you call the function as it thinks it might be undefined.
44
+ if ('handleUserConfig' in handler && handler.handleUserConfig) {
45
+ handler.handleUserConfig(this.#modelConfiguration);
46
+ }
47
+ }
95
48
  }
96
- for (const handler of sortedHandlers) {
97
- handler.initialize?.(freshRecording);
49
+ /**
50
+ * When the user passes in a set of handlers, we want to ensure that we have all
51
+ * the required handlers. Handlers can depend on other handlers, so if the user
52
+ * passes in FooHandler which depends on BarHandler, they must also pass in
53
+ * BarHandler too. This method verifies that all dependencies are met, and
54
+ * throws if not.
55
+ **/
56
+ #verifyHandlers(providedHandlers) {
57
+ // Tiny optimisation: if the amount of provided handlers matches the amount
58
+ // of handlers in the Handlers.ModelHandlers object, that means that the
59
+ // user has passed in every handler we have. So therefore they cannot have
60
+ // missed any, and there is no need to iterate through the handlers and
61
+ // check the dependencies.
62
+ if (Object.keys(providedHandlers).length === Object.keys(Handlers.ModelHandlers).length) {
63
+ return;
64
+ }
65
+ const requiredHandlerKeys = new Set();
66
+ for (const [handlerName, handler] of Object.entries(providedHandlers)) {
67
+ requiredHandlerKeys.add(handlerName);
68
+ for (const depName of (handler.deps?.() || [])) {
69
+ requiredHandlerKeys.add(depName);
70
+ }
71
+ }
72
+ const providedHandlerKeys = new Set(Object.keys(providedHandlers));
73
+ // We always force the Meta handler to be enabled when creating the
74
+ // Processor, so if it is missing from the set the user gave us that is OK,
75
+ // as we will have enabled it anyway.
76
+ requiredHandlerKeys.delete('Meta');
77
+ for (const requiredKey of requiredHandlerKeys) {
78
+ if (!providedHandlerKeys.has(requiredKey)) {
79
+ throw new Error(`Required handler ${requiredKey} not provided.`);
80
+ }
81
+ }
98
82
  }
99
- for await (const item of traceEventIterator) {
100
- if (item.kind === IteratorItemType.STATUS_UPDATE) {
101
- this.dispatchEvent(new TraceParseProgressEvent(item.data));
102
- continue;
103
- }
104
- for (const handler of sortedHandlers) {
105
- handler.handleEvent(item.data);
106
- }
83
+ reset() {
84
+ if (this.#status === "PARSING" /* Status.PARSING */) {
85
+ throw new Error('Trace processor can\'t reset while parsing.');
86
+ }
87
+ const handlers = Object.values(this.#traceHandlers);
88
+ for (const handler of handlers) {
89
+ handler.reset();
90
+ }
91
+ this.#status = "IDLE" /* Status.IDLE */;
107
92
  }
108
- for (const handler of sortedHandlers) {
109
- await handler.finalize?.();
93
+ async parse(traceEvents, freshRecording = false) {
94
+ if (this.#status !== "IDLE" /* Status.IDLE */) {
95
+ throw new Error(`Trace processor can't start parsing when not idle. Current state: ${this.#status}`);
96
+ }
97
+ try {
98
+ this.#status = "PARSING" /* Status.PARSING */;
99
+ await this.#parse(traceEvents, freshRecording);
100
+ this.#status = "FINISHED_PARSING" /* Status.FINISHED_PARSING */;
101
+ }
102
+ catch (e) {
103
+ this.#status = "ERRORED_WHILE_PARSING" /* Status.ERRORED_WHILE_PARSING */;
104
+ throw e;
105
+ }
110
106
  }
111
- }
112
- get data() {
113
- if (this.#status !== "FINISHED_PARSING" /* FINISHED_PARSING */) {
114
- return null;
107
+ async #parse(traceEvents, freshRecording) {
108
+ // This iterator steps through all events, periodically yielding back to the
109
+ // main thread to avoid blocking execution. It uses `dispatchEvent` to
110
+ // provide status update events, and other various bits of config like the
111
+ // pause duration and frequency.
112
+ const { pauseDuration, eventsPerChunk } = this.#modelConfiguration.processing;
113
+ const traceEventIterator = new TraceEventIterator(traceEvents, pauseDuration, eventsPerChunk);
114
+ // Convert to array so that we are able to iterate all handlers multiple times.
115
+ const sortedHandlers = [...sortHandlers(this.#traceHandlers).values()];
116
+ // Reset.
117
+ for (const handler of sortedHandlers) {
118
+ handler.reset();
119
+ }
120
+ // Initialize.
121
+ for (const handler of sortedHandlers) {
122
+ handler.initialize?.(freshRecording);
123
+ }
124
+ // Handle each event.
125
+ for await (const item of traceEventIterator) {
126
+ if (item.kind === 2 /* IteratorItemType.STATUS_UPDATE */) {
127
+ this.dispatchEvent(new TraceParseProgressEvent(item.data));
128
+ continue;
129
+ }
130
+ for (const handler of sortedHandlers) {
131
+ handler.handleEvent(item.data);
132
+ }
133
+ }
134
+ // Finalize.
135
+ for (const handler of sortedHandlers) {
136
+ await handler.finalize?.();
137
+ }
115
138
  }
116
- const data = {};
117
- for (const [name, handler] of Object.entries(this.#traceHandlers)) {
118
- Object.assign(data, { [name]: handler.data() });
139
+ get data() {
140
+ if (this.#status !== "FINISHED_PARSING" /* Status.FINISHED_PARSING */) {
141
+ return null;
142
+ }
143
+ const data = {};
144
+ for (const [name, handler] of Object.entries(this.#traceHandlers)) {
145
+ Object.assign(data, { [name]: handler.data() });
146
+ }
147
+ return data;
119
148
  }
120
- return data;
121
- }
122
149
  }
150
+ /**
151
+ * Some Handlers need data provided by others. Dependencies of a handler handler are
152
+ * declared in the `deps` field.
153
+ * @returns A map from trace event handler name to trace event hander whose entries
154
+ * iterate in such a way that each handler is visited after its dependencies.
155
+ */
123
156
  export function sortHandlers(traceHandlers) {
124
- const sortedMap = /* @__PURE__ */ new Map();
125
- const visited = /* @__PURE__ */ new Set();
126
- const visitHandler = (handlerName) => {
127
- if (sortedMap.has(handlerName)) {
128
- return;
129
- }
130
- if (visited.has(handlerName)) {
131
- let stackPath = "";
132
- for (const handler2 of visited) {
133
- if (stackPath || handler2 === handlerName) {
134
- stackPath += `${handler2}->`;
135
- }
136
- }
137
- stackPath += handlerName;
138
- throw new Error(`Found dependency cycle in trace event handlers: ${stackPath}`);
139
- }
140
- visited.add(handlerName);
141
- const handler = traceHandlers[handlerName];
142
- if (!handler) {
143
- return;
144
- }
145
- const deps = handler.deps?.();
146
- if (deps) {
147
- deps.forEach(visitHandler);
157
+ const sortedMap = new Map();
158
+ const visited = new Set();
159
+ const visitHandler = (handlerName) => {
160
+ if (sortedMap.has(handlerName)) {
161
+ return;
162
+ }
163
+ if (visited.has(handlerName)) {
164
+ let stackPath = '';
165
+ for (const handler of visited) {
166
+ if (stackPath || handler === handlerName) {
167
+ stackPath += `${handler}->`;
168
+ }
169
+ }
170
+ stackPath += handlerName;
171
+ throw new Error(`Found dependency cycle in trace event handlers: ${stackPath}`);
172
+ }
173
+ visited.add(handlerName);
174
+ const handler = traceHandlers[handlerName];
175
+ if (!handler) {
176
+ return;
177
+ }
178
+ const deps = handler.deps?.();
179
+ if (deps) {
180
+ deps.forEach(visitHandler);
181
+ }
182
+ sortedMap.set(handlerName, handler);
183
+ };
184
+ for (const handlerName of Object.keys(traceHandlers)) {
185
+ visitHandler(handlerName);
148
186
  }
149
- sortedMap.set(handlerName, handler);
150
- };
151
- for (const handlerName of Object.keys(traceHandlers)) {
152
- visitHandler(handlerName);
153
- }
154
- return sortedMap;
187
+ return sortedMap;
155
188
  }
156
- var IteratorItemType = /* @__PURE__ */ ((IteratorItemType2) => {
157
- IteratorItemType2[IteratorItemType2["TRACE_EVENT"] = 1] = "TRACE_EVENT";
158
- IteratorItemType2[IteratorItemType2["STATUS_UPDATE"] = 2] = "STATUS_UPDATE";
159
- return IteratorItemType2;
160
- })(IteratorItemType || {});
161
189
  class TraceEventIterator {
162
- constructor(traceEvents, pauseDuration, eventsPerChunk) {
163
- this.traceEvents = traceEvents;
164
- this.pauseDuration = pauseDuration;
165
- this.eventsPerChunk = eventsPerChunk;
166
- this.#eventCount = 0;
167
- }
168
- #eventCount;
169
- async *[Symbol.asyncIterator]() {
170
- for (let i = 0, length = this.traceEvents.length; i < length; i++) {
171
- if (++this.#eventCount % this.eventsPerChunk === 0) {
172
- yield { kind: 2 /* STATUS_UPDATE */, data: { index: i, total: length } };
173
- await new Promise((resolve) => setTimeout(resolve, this.pauseDuration));
174
- }
175
- yield { kind: 1 /* TRACE_EVENT */, data: this.traceEvents[i] };
190
+ traceEvents;
191
+ pauseDuration;
192
+ eventsPerChunk;
193
+ #eventCount;
194
+ constructor(traceEvents, pauseDuration, eventsPerChunk) {
195
+ this.traceEvents = traceEvents;
196
+ this.pauseDuration = pauseDuration;
197
+ this.eventsPerChunk = eventsPerChunk;
198
+ this.#eventCount = 0;
199
+ }
200
+ async *[Symbol.asyncIterator]() {
201
+ for (let i = 0, length = this.traceEvents.length; i < length; i++) {
202
+ // Every so often we take a break just to render.
203
+ if (++this.#eventCount % this.eventsPerChunk === 0) {
204
+ // Take the opportunity to provide status update events.
205
+ yield { kind: 2 /* IteratorItemType.STATUS_UPDATE */, data: { index: i, total: length } };
206
+ // Wait for rendering before resuming.
207
+ await new Promise(resolve => setTimeout(resolve, this.pauseDuration));
208
+ }
209
+ yield { kind: 1 /* IteratorItemType.TRACE_EVENT */, data: this.traceEvents[i] };
210
+ }
176
211
  }
177
- }
178
212
  }
179
- //# sourceMappingURL=Processor.js.map
213
+ //# sourceMappingURL=Processor.js.map
@@ -1,7 +1 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../../../front_end/models/trace/Processor.ts"],
4
- "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.\nimport * as Handlers from './handlers/handlers.js';\nimport * as Types from './types/types.js';\n\nconst enum Status {\n IDLE = 'IDLE',\n PARSING = 'PARSING',\n FINISHED_PARSING = 'FINISHED_PARSING',\n ERRORED_WHILE_PARSING = 'ERRORED_WHILE_PARSING',\n}\n\nexport type TraceParseEventProgressData = {\n index: number,\n total: number,\n};\n\nexport class TraceParseProgressEvent extends Event {\n static readonly eventName = 'traceparseprogress';\n constructor(public data: TraceParseEventProgressData, init: EventInit = {bubbles: true}) {\n super(TraceParseProgressEvent.eventName, init);\n }\n}\ndeclare global {\n interface HTMLElementEventMap {\n [TraceParseProgressEvent.eventName]: TraceParseProgressEvent;\n }\n}\n\nexport class TraceProcessor<EnabledModelHandlers extends {[key: string]: Handlers.Types.TraceEventHandler}> extends\n EventTarget {\n // We force the Meta handler to be enabled, so the TraceHandlers type here is\n // the model handlers the user passes in and the Meta handler.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n readonly #traceHandlers: Handlers.Types.HandlersWithMeta<EnabledModelHandlers>;\n #status = Status.IDLE;\n #modelConfiguration = Types.Configuration.DEFAULT;\n\n static createWithAllHandlers(): TraceProcessor<typeof Handlers.ModelHandlers> {\n return new TraceProcessor(Handlers.ModelHandlers, Types.Configuration.DEFAULT);\n }\n\n constructor(traceHandlers: EnabledModelHandlers, modelConfiguration?: Types.Configuration.Configuration) {\n super();\n\n this.#verifyHandlers(traceHandlers);\n this.#traceHandlers = {\n Meta: Handlers.ModelHandlers.Meta,\n ...traceHandlers,\n };\n if (modelConfiguration) {\n this.#modelConfiguration = modelConfiguration;\n }\n this.#passConfigToHandlers();\n }\n\n updateConfiguration(config: Types.Configuration.Configuration): void {\n this.#modelConfiguration = config;\n this.#passConfigToHandlers();\n }\n\n #passConfigToHandlers(): void {\n for (const handler of Object.values(this.#traceHandlers)) {\n // Bit of an odd double check, but without this TypeScript refuses to let\n // you call the function as it thinks it might be undefined.\n if ('handleUserConfig' in handler && handler.handleUserConfig) {\n handler.handleUserConfig(this.#modelConfiguration);\n }\n }\n }\n\n /**\n * When the user passes in a set of handlers, we want to ensure that we have all\n * the required handlers. Handlers can depend on other handlers, so if the user\n * passes in FooHandler which depends on BarHandler, they must also pass in\n * BarHandler too. This method verifies that all dependencies are met, and\n * throws if not.\n **/\n #verifyHandlers(providedHandlers: EnabledModelHandlers): void {\n // Tiny optimisation: if the amount of provided handlers matches the amount\n // of handlers in the Handlers.ModelHandlers object, that means that the\n // user has passed in every handler we have. So therefore they cannot have\n // missed any, and there is no need to iterate through the handlers and\n // check the dependencies.\n if (Object.keys(providedHandlers).length === Object.keys(Handlers.ModelHandlers).length) {\n return;\n }\n const requiredHandlerKeys: Set<Handlers.Types.TraceEventHandlerName> = new Set();\n for (const [handlerName, handler] of Object.entries(providedHandlers)) {\n requiredHandlerKeys.add(handlerName as Handlers.Types.TraceEventHandlerName);\n for (const depName of (handler.deps?.() || [])) {\n requiredHandlerKeys.add(depName);\n }\n }\n\n const providedHandlerKeys = new Set(Object.keys(providedHandlers));\n // We always force the Meta handler to be enabled when creating the\n // Processor, so if it is missing from the set the user gave us that is OK,\n // as we will have enabled it anyway.\n requiredHandlerKeys.delete('Meta');\n\n for (const requiredKey of requiredHandlerKeys) {\n if (!providedHandlerKeys.has(requiredKey)) {\n throw new Error(`Required handler ${requiredKey} not provided.`);\n }\n }\n }\n\n reset(): void {\n if (this.#status === Status.PARSING) {\n throw new Error('Trace processor can\\'t reset while parsing.');\n }\n\n const handlers = Object.values(this.#traceHandlers);\n for (const handler of handlers) {\n handler.reset();\n }\n\n this.#status = Status.IDLE;\n }\n\n async parse(traceEvents: readonly Types.TraceEvents.TraceEventData[], freshRecording = false): Promise<void> {\n if (this.#status !== Status.IDLE) {\n throw new Error(`Trace processor can't start parsing when not idle. Current state: ${this.#status}`);\n }\n try {\n this.#status = Status.PARSING;\n await this.#parse(traceEvents, freshRecording);\n this.#status = Status.FINISHED_PARSING;\n } catch (e) {\n this.#status = Status.ERRORED_WHILE_PARSING;\n throw e;\n }\n }\n\n async #parse(traceEvents: readonly Types.TraceEvents.TraceEventData[], freshRecording: boolean): Promise<void> {\n // This iterator steps through all events, periodically yielding back to the\n // main thread to avoid blocking execution. It uses `dispatchEvent` to\n // provide status update events, and other various bits of config like the\n // pause duration and frequency.\n const {pauseDuration, eventsPerChunk} = this.#modelConfiguration.processing;\n const traceEventIterator = new TraceEventIterator(traceEvents, pauseDuration, eventsPerChunk);\n\n // Convert to array so that we are able to iterate all handlers multiple times.\n const sortedHandlers = [...sortHandlers(this.#traceHandlers).values()];\n // Reset.\n for (const handler of sortedHandlers) {\n handler.reset();\n }\n\n // Initialize.\n for (const handler of sortedHandlers) {\n handler.initialize?.(freshRecording);\n }\n\n // Handle each event.\n for await (const item of traceEventIterator) {\n if (item.kind === IteratorItemType.STATUS_UPDATE) {\n this.dispatchEvent(new TraceParseProgressEvent(item.data));\n continue;\n }\n for (const handler of sortedHandlers) {\n handler.handleEvent(item.data);\n }\n }\n\n // Finalize.\n for (const handler of sortedHandlers) {\n await handler.finalize?.();\n }\n }\n\n get data(): Handlers.Types.EnabledHandlerDataWithMeta<EnabledModelHandlers>|null {\n if (this.#status !== Status.FINISHED_PARSING) {\n return null;\n }\n\n const data = {};\n for (const [name, handler] of Object.entries(this.#traceHandlers)) {\n Object.assign(data, {[name]: handler.data()});\n }\n\n return data as Handlers.Types.EnabledHandlerDataWithMeta<EnabledModelHandlers>;\n }\n}\n\n/**\n * Some Handlers need data provided by others. Dependencies of a handler handler are\n * declared in the `deps` field.\n * @returns A map from trace event handler name to trace event hander whose entries\n * iterate in such a way that each handler is visited after its dependencies.\n */\nexport function sortHandlers(\n traceHandlers: Partial<{[key in Handlers.Types.TraceEventHandlerName]: Handlers.Types.TraceEventHandler}>):\n Map<Handlers.Types.TraceEventHandlerName, Handlers.Types.TraceEventHandler> {\n const sortedMap = new Map<Handlers.Types.TraceEventHandlerName, Handlers.Types.TraceEventHandler>();\n const visited = new Set<Handlers.Types.TraceEventHandlerName>();\n const visitHandler = (handlerName: Handlers.Types.TraceEventHandlerName): void => {\n if (sortedMap.has(handlerName)) {\n return;\n }\n if (visited.has(handlerName)) {\n let stackPath = '';\n for (const handler of visited) {\n if (stackPath || handler === handlerName) {\n stackPath += `${handler}->`;\n }\n }\n stackPath += handlerName;\n throw new Error(`Found dependency cycle in trace event handlers: ${stackPath}`);\n }\n visited.add(handlerName);\n const handler = traceHandlers[handlerName];\n if (!handler) {\n return;\n }\n const deps = handler.deps?.();\n if (deps) {\n deps.forEach(visitHandler);\n }\n sortedMap.set(handlerName, handler);\n };\n\n for (const handlerName of Object.keys(traceHandlers)) {\n visitHandler(handlerName as Handlers.Types.TraceEventHandlerName);\n }\n return sortedMap;\n}\n\nconst enum IteratorItemType {\n TRACE_EVENT = 1,\n STATUS_UPDATE = 2,\n}\n\ntype IteratorItem = IteratorTraceEventItem|IteratorStatusUpdateItem;\n\ntype IteratorTraceEventItem = {\n kind: IteratorItemType.TRACE_EVENT,\n data: Types.TraceEvents.TraceEventData,\n};\n\ntype IteratorStatusUpdateItem = {\n kind: IteratorItemType.STATUS_UPDATE,\n data: TraceParseEventProgressData,\n};\n\nclass TraceEventIterator {\n #eventCount: number;\n\n constructor(\n private traceEvents: readonly Types.TraceEvents.TraceEventData[], private pauseDuration: number,\n private eventsPerChunk: number) {\n this.#eventCount = 0;\n }\n\n async * [Symbol.asyncIterator](): AsyncGenerator<IteratorItem, void, void> {\n for (let i = 0, length = this.traceEvents.length; i < length; i++) {\n // Every so often we take a break just to render.\n if (++this.#eventCount % this.eventsPerChunk === 0) {\n // Take the opportunity to provide status update events.\n yield {kind: IteratorItemType.STATUS_UPDATE, data: {index: i, total: length}};\n // Wait for rendering before resuming.\n await new Promise(resolve => setTimeout(resolve, this.pauseDuration));\n }\n\n yield {kind: IteratorItemType.TRACE_EVENT, data: this.traceEvents[i]};\n }\n }\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
1
+ {"version":3,"file":"Processor.js","sourceRoot":"","sources":["../../../../../../front_end/models/trace/Processor.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAC7B,OAAO,KAAK,QAAQ,MAAM,wBAAwB,CAAC;AACnD,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC;AAc1C,MAAM,OAAO,uBAAwB,SAAQ,KAAK;IAE7B;IADnB,MAAM,CAAU,SAAS,GAAG,oBAAoB,CAAC;IACjD,YAAmB,IAAiC,EAAE,OAAkB,EAAC,OAAO,EAAE,IAAI,EAAC;QACrF,KAAK,CAAC,uBAAuB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAD9B,SAAI,GAAJ,IAAI,CAA6B;IAEpD,CAAC;;AAQH,MAAM,OAAO,cAA+F,SACxG,WAAW;IACb,6EAA6E;IAC7E,8DAA8D;IAC9D,gEAAgE;IACvD,cAAc,CAAwD;IAC/E,OAAO,4BAAe;IACtB,mBAAmB,GAAG,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC;IAElD,MAAM,CAAC,qBAAqB;QAC1B,OAAO,IAAI,cAAc,CAAC,QAAQ,CAAC,aAAa,EAAE,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IACjF,CAAC;IAED,YAAY,aAAmC,EAAE,kBAAsD;QACrG,KAAK,EAAE,CAAC;QAER,IAAI,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC;QACpC,IAAI,CAAC,cAAc,GAAG;YACpB,IAAI,EAAE,QAAQ,CAAC,aAAa,CAAC,IAAI;YACjC,GAAG,aAAa;SACjB,CAAC;QACF,IAAI,kBAAkB,EAAE;YACtB,IAAI,CAAC,mBAAmB,GAAG,kBAAkB,CAAC;SAC/C;QACD,IAAI,CAAC,qBAAqB,EAAE,CAAC;IAC/B,CAAC;IAED,mBAAmB,CAAC,MAAyC;QAC3D,IAAI,CAAC,mBAAmB,GAAG,MAAM,CAAC;QAClC,IAAI,CAAC,qBAAqB,EAAE,CAAC;IAC/B,CAAC;IAED,qBAAqB;QACnB,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE;YACxD,yEAAyE;YACzE,4DAA4D;YAC5D,IAAI,kBAAkB,IAAI,OAAO,IAAI,OAAO,CAAC,gBAAgB,EAAE;gBAC7D,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;aACpD;SACF;IACH,CAAC;IAED;;;;;;QAMI;IACJ,eAAe,CAAC,gBAAsC;QACpD,2EAA2E;QAC3E,wEAAwE;QACxE,0EAA0E;QAC1E,uEAAuE;QACvE,0BAA0B;QAC1B,IAAI,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,MAAM,EAAE;YACvF,OAAO;SACR;QACD,MAAM,mBAAmB,GAA8C,IAAI,GAAG,EAAE,CAAC;QACjF,KAAK,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE;YACrE,mBAAmB,CAAC,GAAG,CAAC,WAAmD,CAAC,CAAC;YAC7E,KAAK,MAAM,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE;gBAC9C,mBAAmB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;aAClC;SACF;QAED,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;QACnE,mEAAmE;QACnE,2EAA2E;QAC3E,qCAAqC;QACrC,mBAAmB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAEnC,KAAK,MAAM,WAAW,IAAI,mBAAmB,EAAE;YAC7C,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE;gBACzC,MAAM,IAAI,KAAK,CAAC,oBAAoB,WAAW,gBAAgB,CAAC,CAAC;aAClE;SACF;IACH,CAAC;IAED,KAAK;QACH,IAAI,IAAI,CAAC,OAAO,mCAAmB,EAAE;YACnC,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;SAChE;QAED,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACpD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE;YAC9B,OAAO,CAAC,KAAK,EAAE,CAAC;SACjB;QAED,IAAI,CAAC,OAAO,2BAAc,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,WAAwD,EAAE,cAAc,GAAG,KAAK;QAC1F,IAAI,IAAI,CAAC,OAAO,6BAAgB,EAAE;YAChC,MAAM,IAAI,KAAK,CAAC,qEAAqE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;SACtG;QACD,IAAI;YACF,IAAI,CAAC,OAAO,iCAAiB,CAAC;YAC9B,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;YAC/C,IAAI,CAAC,OAAO,mDAA0B,CAAC;SACxC;QAAC,OAAO,CAAC,EAAE;YACV,IAAI,CAAC,OAAO,6DAA+B,CAAC;YAC5C,MAAM,CAAC,CAAC;SACT;IACH,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,WAAwD,EAAE,cAAuB;QAC5F,4EAA4E;QAC5E,sEAAsE;QACtE,0EAA0E;QAC1E,gCAAgC;QAChC,MAAM,EAAC,aAAa,EAAE,cAAc,EAAC,GAAG,IAAI,CAAC,mBAAmB,CAAC,UAAU,CAAC;QAC5E,MAAM,kBAAkB,GAAG,IAAI,kBAAkB,CAAC,WAAW,EAAE,aAAa,EAAE,cAAc,CAAC,CAAC;QAE9F,+EAA+E;QAC/E,MAAM,cAAc,GAAG,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;QACvE,SAAS;QACT,KAAK,MAAM,OAAO,IAAI,cAAc,EAAE;YACpC,OAAO,CAAC,KAAK,EAAE,CAAC;SACjB;QAED,cAAc;QACd,KAAK,MAAM,OAAO,IAAI,cAAc,EAAE;YACpC,OAAO,CAAC,UAAU,EAAE,CAAC,cAAc,CAAC,CAAC;SACtC;QAED,qBAAqB;QACrB,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,kBAAkB,EAAE;YAC3C,IAAI,IAAI,CAAC,IAAI,2CAAmC,EAAE;gBAChD,IAAI,CAAC,aAAa,CAAC,IAAI,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;gBAC3D,SAAS;aACV;YACD,KAAK,MAAM,OAAO,IAAI,cAAc,EAAE;gBACpC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;aAChC;SACF;QAED,YAAY;QACZ,KAAK,MAAM,OAAO,IAAI,cAAc,EAAE;YACpC,MAAM,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;SAC5B;IACH,CAAC;IAED,IAAI,IAAI;QACN,IAAI,IAAI,CAAC,OAAO,qDAA4B,EAAE;YAC5C,OAAO,IAAI,CAAC;SACb;QAED,MAAM,IAAI,GAAG,EAAE,CAAC;QAChB,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE;YACjE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAC,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,IAAI,EAAE,EAAC,CAAC,CAAC;SAC/C;QAED,OAAO,IAAuE,CAAC;IACjF,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CACxB,aAAyG;IAE3G,MAAM,SAAS,GAAG,IAAI,GAAG,EAA0E,CAAC;IACpG,MAAM,OAAO,GAAG,IAAI,GAAG,EAAwC,CAAC;IAChE,MAAM,YAAY,GAAG,CAAC,WAAiD,EAAQ,EAAE;QAC/E,IAAI,SAAS,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE;YAC9B,OAAO;SACR;QACD,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE;YAC5B,IAAI,SAAS,GAAG,EAAE,CAAC;YACnB,KAAK,MAAM,OAAO,IAAI,OAAO,EAAE;gBAC7B,IAAI,SAAS,IAAI,OAAO,KAAK,WAAW,EAAE;oBACxC,SAAS,IAAI,GAAG,OAAO,IAAI,CAAC;iBAC7B;aACF;YACD,SAAS,IAAI,WAAW,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,mDAAmD,SAAS,EAAE,CAAC,CAAC;SACjF;QACD,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACzB,MAAM,OAAO,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;QAC3C,IAAI,CAAC,OAAO,EAAE;YACZ,OAAO;SACR;QACD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;QAC9B,IAAI,IAAI,EAAE;YACR,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;SAC5B;QACD,SAAS,CAAC,GAAG,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IACtC,CAAC,CAAC;IAEF,KAAK,MAAM,WAAW,IAAI,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE;QACpD,YAAY,CAAC,WAAmD,CAAC,CAAC;KACnE;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAmBD,MAAM,kBAAkB;IAIV;IAAkE;IAClE;IAJZ,WAAW,CAAS;IAEpB,YACY,WAAwD,EAAU,aAAqB,EACvF,cAAsB;QADtB,gBAAW,GAAX,WAAW,CAA6C;QAAU,kBAAa,GAAb,aAAa,CAAQ;QACvF,mBAAc,GAAd,cAAc,CAAQ;QAChC,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,CAAE,CAAC,MAAM,CAAC,aAAa,CAAC;QAC5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;YACjE,iDAAiD;YACjD,IAAI,EAAE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,cAAc,KAAK,CAAC,EAAE;gBAClD,wDAAwD;gBACxD,MAAM,EAAC,IAAI,wCAAgC,EAAE,IAAI,EAAE,EAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAC,EAAC,CAAC;gBAC9E,sCAAsC;gBACtC,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;aACvE;YAED,MAAM,EAAC,IAAI,sCAA8B,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAC,CAAC;SACvE;IACH,CAAC;CACF","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.\nimport * as Handlers from './handlers/handlers.js';\nimport * as Types from './types/types.js';\n\nconst enum Status {\n IDLE = 'IDLE',\n PARSING = 'PARSING',\n FINISHED_PARSING = 'FINISHED_PARSING',\n ERRORED_WHILE_PARSING = 'ERRORED_WHILE_PARSING',\n}\n\nexport type TraceParseEventProgressData = {\n index: number,\n total: number,\n};\n\nexport class TraceParseProgressEvent extends Event {\n static readonly eventName = 'traceparseprogress';\n constructor(public data: TraceParseEventProgressData, init: EventInit = {bubbles: true}) {\n super(TraceParseProgressEvent.eventName, init);\n }\n}\ndeclare global {\n interface HTMLElementEventMap {\n [TraceParseProgressEvent.eventName]: TraceParseProgressEvent;\n }\n}\n\nexport class TraceProcessor<EnabledModelHandlers extends {[key: string]: Handlers.Types.TraceEventHandler}> extends\n EventTarget {\n // We force the Meta handler to be enabled, so the TraceHandlers type here is\n // the model handlers the user passes in and the Meta handler.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n readonly #traceHandlers: Handlers.Types.HandlersWithMeta<EnabledModelHandlers>;\n #status = Status.IDLE;\n #modelConfiguration = Types.Configuration.DEFAULT;\n\n static createWithAllHandlers(): TraceProcessor<typeof Handlers.ModelHandlers> {\n return new TraceProcessor(Handlers.ModelHandlers, Types.Configuration.DEFAULT);\n }\n\n constructor(traceHandlers: EnabledModelHandlers, modelConfiguration?: Types.Configuration.Configuration) {\n super();\n\n this.#verifyHandlers(traceHandlers);\n this.#traceHandlers = {\n Meta: Handlers.ModelHandlers.Meta,\n ...traceHandlers,\n };\n if (modelConfiguration) {\n this.#modelConfiguration = modelConfiguration;\n }\n this.#passConfigToHandlers();\n }\n\n updateConfiguration(config: Types.Configuration.Configuration): void {\n this.#modelConfiguration = config;\n this.#passConfigToHandlers();\n }\n\n #passConfigToHandlers(): void {\n for (const handler of Object.values(this.#traceHandlers)) {\n // Bit of an odd double check, but without this TypeScript refuses to let\n // you call the function as it thinks it might be undefined.\n if ('handleUserConfig' in handler && handler.handleUserConfig) {\n handler.handleUserConfig(this.#modelConfiguration);\n }\n }\n }\n\n /**\n * When the user passes in a set of handlers, we want to ensure that we have all\n * the required handlers. Handlers can depend on other handlers, so if the user\n * passes in FooHandler which depends on BarHandler, they must also pass in\n * BarHandler too. This method verifies that all dependencies are met, and\n * throws if not.\n **/\n #verifyHandlers(providedHandlers: EnabledModelHandlers): void {\n // Tiny optimisation: if the amount of provided handlers matches the amount\n // of handlers in the Handlers.ModelHandlers object, that means that the\n // user has passed in every handler we have. So therefore they cannot have\n // missed any, and there is no need to iterate through the handlers and\n // check the dependencies.\n if (Object.keys(providedHandlers).length === Object.keys(Handlers.ModelHandlers).length) {\n return;\n }\n const requiredHandlerKeys: Set<Handlers.Types.TraceEventHandlerName> = new Set();\n for (const [handlerName, handler] of Object.entries(providedHandlers)) {\n requiredHandlerKeys.add(handlerName as Handlers.Types.TraceEventHandlerName);\n for (const depName of (handler.deps?.() || [])) {\n requiredHandlerKeys.add(depName);\n }\n }\n\n const providedHandlerKeys = new Set(Object.keys(providedHandlers));\n // We always force the Meta handler to be enabled when creating the\n // Processor, so if it is missing from the set the user gave us that is OK,\n // as we will have enabled it anyway.\n requiredHandlerKeys.delete('Meta');\n\n for (const requiredKey of requiredHandlerKeys) {\n if (!providedHandlerKeys.has(requiredKey)) {\n throw new Error(`Required handler ${requiredKey} not provided.`);\n }\n }\n }\n\n reset(): void {\n if (this.#status === Status.PARSING) {\n throw new Error('Trace processor can\\'t reset while parsing.');\n }\n\n const handlers = Object.values(this.#traceHandlers);\n for (const handler of handlers) {\n handler.reset();\n }\n\n this.#status = Status.IDLE;\n }\n\n async parse(traceEvents: readonly Types.TraceEvents.TraceEventData[], freshRecording = false): Promise<void> {\n if (this.#status !== Status.IDLE) {\n throw new Error(`Trace processor can't start parsing when not idle. Current state: ${this.#status}`);\n }\n try {\n this.#status = Status.PARSING;\n await this.#parse(traceEvents, freshRecording);\n this.#status = Status.FINISHED_PARSING;\n } catch (e) {\n this.#status = Status.ERRORED_WHILE_PARSING;\n throw e;\n }\n }\n\n async #parse(traceEvents: readonly Types.TraceEvents.TraceEventData[], freshRecording: boolean): Promise<void> {\n // This iterator steps through all events, periodically yielding back to the\n // main thread to avoid blocking execution. It uses `dispatchEvent` to\n // provide status update events, and other various bits of config like the\n // pause duration and frequency.\n const {pauseDuration, eventsPerChunk} = this.#modelConfiguration.processing;\n const traceEventIterator = new TraceEventIterator(traceEvents, pauseDuration, eventsPerChunk);\n\n // Convert to array so that we are able to iterate all handlers multiple times.\n const sortedHandlers = [...sortHandlers(this.#traceHandlers).values()];\n // Reset.\n for (const handler of sortedHandlers) {\n handler.reset();\n }\n\n // Initialize.\n for (const handler of sortedHandlers) {\n handler.initialize?.(freshRecording);\n }\n\n // Handle each event.\n for await (const item of traceEventIterator) {\n if (item.kind === IteratorItemType.STATUS_UPDATE) {\n this.dispatchEvent(new TraceParseProgressEvent(item.data));\n continue;\n }\n for (const handler of sortedHandlers) {\n handler.handleEvent(item.data);\n }\n }\n\n // Finalize.\n for (const handler of sortedHandlers) {\n await handler.finalize?.();\n }\n }\n\n get data(): Handlers.Types.EnabledHandlerDataWithMeta<EnabledModelHandlers>|null {\n if (this.#status !== Status.FINISHED_PARSING) {\n return null;\n }\n\n const data = {};\n for (const [name, handler] of Object.entries(this.#traceHandlers)) {\n Object.assign(data, {[name]: handler.data()});\n }\n\n return data as Handlers.Types.EnabledHandlerDataWithMeta<EnabledModelHandlers>;\n }\n}\n\n/**\n * Some Handlers need data provided by others. Dependencies of a handler handler are\n * declared in the `deps` field.\n * @returns A map from trace event handler name to trace event hander whose entries\n * iterate in such a way that each handler is visited after its dependencies.\n */\nexport function sortHandlers(\n traceHandlers: Partial<{[key in Handlers.Types.TraceEventHandlerName]: Handlers.Types.TraceEventHandler}>):\n Map<Handlers.Types.TraceEventHandlerName, Handlers.Types.TraceEventHandler> {\n const sortedMap = new Map<Handlers.Types.TraceEventHandlerName, Handlers.Types.TraceEventHandler>();\n const visited = new Set<Handlers.Types.TraceEventHandlerName>();\n const visitHandler = (handlerName: Handlers.Types.TraceEventHandlerName): void => {\n if (sortedMap.has(handlerName)) {\n return;\n }\n if (visited.has(handlerName)) {\n let stackPath = '';\n for (const handler of visited) {\n if (stackPath || handler === handlerName) {\n stackPath += `${handler}->`;\n }\n }\n stackPath += handlerName;\n throw new Error(`Found dependency cycle in trace event handlers: ${stackPath}`);\n }\n visited.add(handlerName);\n const handler = traceHandlers[handlerName];\n if (!handler) {\n return;\n }\n const deps = handler.deps?.();\n if (deps) {\n deps.forEach(visitHandler);\n }\n sortedMap.set(handlerName, handler);\n };\n\n for (const handlerName of Object.keys(traceHandlers)) {\n visitHandler(handlerName as Handlers.Types.TraceEventHandlerName);\n }\n return sortedMap;\n}\n\nconst enum IteratorItemType {\n TRACE_EVENT = 1,\n STATUS_UPDATE = 2,\n}\n\ntype IteratorItem = IteratorTraceEventItem|IteratorStatusUpdateItem;\n\ntype IteratorTraceEventItem = {\n kind: IteratorItemType.TRACE_EVENT,\n data: Types.TraceEvents.TraceEventData,\n};\n\ntype IteratorStatusUpdateItem = {\n kind: IteratorItemType.STATUS_UPDATE,\n data: TraceParseEventProgressData,\n};\n\nclass TraceEventIterator {\n #eventCount: number;\n\n constructor(\n private traceEvents: readonly Types.TraceEvents.TraceEventData[], private pauseDuration: number,\n private eventsPerChunk: number) {\n this.#eventCount = 0;\n }\n\n async * [Symbol.asyncIterator](): AsyncGenerator<IteratorItem, void, void> {\n for (let i = 0, length = this.traceEvents.length; i < length; i++) {\n // Every so often we take a break just to render.\n if (++this.#eventCount % this.eventsPerChunk === 0) {\n // Take the opportunity to provide status update events.\n yield {kind: IteratorItemType.STATUS_UPDATE, data: {index: i, total: length}};\n // Wait for rendering before resuming.\n await new Promise(resolve => setTimeout(resolve, this.pauseDuration));\n }\n\n yield {kind: IteratorItemType.TRACE_EVENT, data: this.traceEvents[i]};\n }\n }\n}\n"]}
@@ -1,7 +1 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../../../front_end/models/trace/TracingManager.ts"],
4
- "sourcesContent": ["// Copyright 2014 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 ProtocolProxyApi from '../../generated/protocol-proxy-api.js';\nimport * as Protocol from '../../generated/protocol.js';\n\nimport * as SDK from '../../core/sdk/sdk.js';\nimport {type ObjectSnapshot} from './LegacyTracingModel.js';\nimport type * as Types from './types/types.js';\n\nexport class TracingManager extends SDK.SDKModel.SDKModel<void> {\n readonly #tracingAgent: ProtocolProxyApi.TracingApi;\n #activeClient: TracingManagerClient|null;\n #eventBufferSize: number|null;\n #eventsRetrieved: number;\n #finishing?: boolean;\n constructor(target: SDK.Target.Target) {\n super(target);\n this.#tracingAgent = target.tracingAgent();\n target.registerTracingDispatcher(new TracingDispatcher(this));\n\n this.#activeClient = null;\n this.#eventBufferSize = 0;\n this.#eventsRetrieved = 0;\n }\n\n bufferUsage(usage?: number, eventCount?: number, percentFull?: number): void {\n this.#eventBufferSize = eventCount === undefined ? null : eventCount;\n if (this.#activeClient) {\n this.#activeClient.tracingBufferUsage(usage || percentFull || 0);\n }\n }\n\n eventsCollected(events: EventPayload[]): void {\n if (!this.#activeClient) {\n return;\n }\n this.#activeClient.traceEventsCollected(events);\n this.#eventsRetrieved += events.length;\n if (!this.#eventBufferSize) {\n this.#activeClient.eventsRetrievalProgress(0);\n return;\n }\n\n if (this.#eventsRetrieved > this.#eventBufferSize) {\n this.#eventsRetrieved = this.#eventBufferSize;\n }\n this.#activeClient.eventsRetrievalProgress(this.#eventsRetrieved / this.#eventBufferSize);\n }\n\n tracingComplete(): void {\n this.#eventBufferSize = 0;\n this.#eventsRetrieved = 0;\n if (this.#activeClient) {\n this.#activeClient.tracingComplete();\n this.#activeClient = null;\n }\n this.#finishing = false;\n }\n\n async reset(): Promise<void> {\n // If we have an active client, we should try to stop\n // it before resetting it, else we will leave the\n // backend in a broken state where it thinks we are in\n // the middle of tracing, but we think we are not.\n // Then, any subsequent attempts to record will fail\n // because the backend will not let us start a second\n // tracing session.\n if (this.#activeClient) {\n await this.#tracingAgent.invoke_end();\n }\n this.#eventBufferSize = 0;\n this.#eventsRetrieved = 0;\n this.#activeClient = null;\n this.#finishing = false;\n }\n\n // TODO(petermarshall): Use the traceConfig argument instead of deprecated\n // categories + options.\n async start(client: TracingManagerClient, categoryFilter: string, options: string):\n Promise<Protocol.ProtocolResponseWithError> {\n if (this.#activeClient) {\n throw new Error('Tracing is already started');\n }\n const bufferUsageReportingIntervalMs = 500;\n this.#activeClient = client;\n const args = {\n bufferUsageReportingInterval: bufferUsageReportingIntervalMs,\n categories: categoryFilter,\n options: options,\n transferMode: Protocol.Tracing.StartRequestTransferMode.ReportEvents,\n };\n const response = await this.#tracingAgent.invoke_start(args);\n if (response.getError()) {\n this.#activeClient = null;\n }\n await this.warmupJsProfiler();\n return response;\n }\n\n // CPUProfiler::StartProfiling has a non-trivial cost and we'd prefer it not happen within an\n // interaction as that complicates debugging interaction latency.\n // To trigger the StartProfiling interrupt and get the warmup cost out of the way, we send a\n // very soft invocation to V8.\n // https://crbug.com/1358602\n async warmupJsProfiler(): Promise<void> {\n const runtimeModel = this.target().model(SDK.RuntimeModel.RuntimeModel);\n if (!runtimeModel) {\n return;\n }\n await runtimeModel.checkSideEffectSupport();\n }\n\n stop(): void {\n if (!this.#activeClient) {\n throw new Error('Tracing is not started');\n }\n if (this.#finishing) {\n throw new Error('Tracing is already being stopped');\n }\n this.#finishing = true;\n void this.#tracingAgent.invoke_end();\n }\n}\n\nexport interface TracingManagerClient {\n traceEventsCollected(events: EventPayload[]): void;\n\n tracingComplete(): void;\n tracingBufferUsage(usage: number): void;\n eventsRetrievalProgress(progress: number): void;\n}\n\nclass TracingDispatcher implements ProtocolProxyApi.TracingDispatcher {\n readonly #tracingManager: TracingManager;\n constructor(tracingManager: TracingManager) {\n this.#tracingManager = tracingManager;\n }\n\n bufferUsage({value, eventCount, percentFull}: Protocol.Tracing.BufferUsageEvent): void {\n this.#tracingManager.bufferUsage(value, eventCount, percentFull);\n }\n\n dataCollected({value}: Protocol.Tracing.DataCollectedEvent): void {\n this.#tracingManager.eventsCollected(value);\n }\n\n tracingComplete(): void {\n this.#tracingManager.tracingComplete();\n }\n}\n\nSDK.SDKModel.SDKModel.register(TracingManager, {capabilities: SDK.Target.Capability.Tracing, autostart: false});\nexport interface EventPayload {\n cat?: string;\n pid: number;\n tid: number;\n ts: number;\n ph: Types.TraceEvents.Phase;\n name: string;\n args: {\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // eslint-disable-next-line @typescript-eslint/naming-convention\n sort_index: number,\n name: string,\n snapshot: ObjectSnapshot,\n data: Object|null,\n };\n dur: number;\n id?: string;\n id2?: {\n global: (string|undefined),\n local: (string|undefined),\n };\n scope: string;\n}\n"],
5
- "mappings": "AAKA;AAEA;AAIO,oCAA6B,IAAI,SAAS,SAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAM9D,YAAY,QAA2B;AACrC,UAAM;AACN,yBAAqB,OAAO;AAC5B,WAAO,0BAA0B,IAAI,kBAAkB;AAEvD,yBAAqB;AACrB,4BAAwB;AACxB,4BAAwB;AAAA;AAAA,EAG1B,YAAY,OAAgB,YAAqB,aAA4B;AAC3E,4BAAwB,eAAe,SAAY,OAAO;AAC1D,QAAI,oBAAoB;AACtB,yBAAmB,mBAAmB,SAAS,eAAe;AAAA;AAAA;AAAA,EAIlE,gBAAgB,QAA8B;AAC5C,QAAI,CAAC,oBAAoB;AACvB;AAAA;AAEF,uBAAmB,qBAAqB;AACxC,6BAAyB,OAAO;AAChC,QAAI,CAAC,uBAAuB;AAC1B,yBAAmB,wBAAwB;AAC3C;AAAA;AAGF,QAAI,wBAAwB,uBAAuB;AACjD,8BAAwB;AAAA;AAE1B,uBAAmB,wBAAwB,wBAAwB;AAAA;AAAA,EAGrE,kBAAwB;AACtB,4BAAwB;AACxB,4BAAwB;AACxB,QAAI,oBAAoB;AACtB,yBAAmB;AACnB,2BAAqB;AAAA;AAEvB,sBAAkB;AAAA;AAAA,QAGd,QAAuB;AAQ3B,QAAI,oBAAoB;AACtB,YAAM,mBAAmB;AAAA;AAE3B,4BAAwB;AACxB,4BAAwB;AACxB,yBAAqB;AACrB,sBAAkB;AAAA;AAAA,QAKd,MAAM,QAA8B,gBAAwB,SAClB;AAC9C,QAAI,oBAAoB;AACtB,YAAM,IAAI,MAAM;AAAA;AAElB,UAAM,iCAAiC;AACvC,yBAAqB;AACrB,UAAM,OAAO;AAAA,MACX,8BAA8B;AAAA,MAC9B,YAAY;AAAA,MACZ;AAAA,MACA,cAAc,SAAS,QAAQ,yBAAyB;AAAA;AAE1D,UAAM,WAAW,MAAM,mBAAmB,aAAa;AACvD,QAAI,SAAS,YAAY;AACvB,2BAAqB;AAAA;AAEvB,UAAM,KAAK;AACX,WAAO;AAAA;AAAA,QAQH,mBAAkC;AACtC,UAAM,eAAe,KAAK,SAAS,MAAM,IAAI,aAAa;AAC1D,QAAI,CAAC,cAAc;AACjB;AAAA;AAEF,UAAM,aAAa;AAAA;AAAA,EAGrB,OAAa;AACX,QAAI,CAAC,oBAAoB;AACvB,YAAM,IAAI,MAAM;AAAA;AAElB,QAAI,iBAAiB;AACnB,YAAM,IAAI,MAAM;AAAA;AAElB,sBAAkB;AAClB,SAAK,mBAAmB;AAAA;AAAA;AAY5B,wBAAsE;AAAA;AAAA,EAEpE,YAAY,gBAAgC;AAC1C,2BAAuB;AAAA;AAAA,EAGzB,YAAY,EAAC,OAAO,YAAY,eAAuD;AACrF,yBAAqB,YAAY,OAAO,YAAY;AAAA;AAAA,EAGtD,cAAc,EAAC,SAAmD;AAChE,yBAAqB,gBAAgB;AAAA;AAAA,EAGvC,kBAAwB;AACtB,yBAAqB;AAAA;AAAA;AAIzB,IAAI,SAAS,SAAS,SAAS,gBAAgB,EAAC,cAAc,IAAI,OAAO,WAAW,SAAS,WAAW;",
6
- "names": []
7
- }
1
+ {"version":3,"file":"TracingManager.js","sourceRoot":"","sources":["../../../../../../front_end/models/trace/TracingManager.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2014 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 ProtocolProxyApi from '../../generated/protocol-proxy-api.js';\nimport * as Protocol from '../../generated/protocol.js';\n\nimport * as SDK from '../../core/sdk/sdk.js';\nimport {type ObjectSnapshot} from './LegacyTracingModel.js';\nimport type * as Types from './types/types.js';\n\nexport class TracingManager extends SDK.SDKModel.SDKModel<void> {\n readonly #tracingAgent: ProtocolProxyApi.TracingApi;\n #activeClient: TracingManagerClient|null;\n #eventBufferSize: number|null;\n #eventsRetrieved: number;\n #finishing?: boolean;\n constructor(target: SDK.Target.Target) {\n super(target);\n this.#tracingAgent = target.tracingAgent();\n target.registerTracingDispatcher(new TracingDispatcher(this));\n\n this.#activeClient = null;\n this.#eventBufferSize = 0;\n this.#eventsRetrieved = 0;\n }\n\n bufferUsage(usage?: number, eventCount?: number, percentFull?: number): void {\n this.#eventBufferSize = eventCount === undefined ? null : eventCount;\n if (this.#activeClient) {\n this.#activeClient.tracingBufferUsage(usage || percentFull || 0);\n }\n }\n\n eventsCollected(events: EventPayload[]): void {\n if (!this.#activeClient) {\n return;\n }\n this.#activeClient.traceEventsCollected(events);\n this.#eventsRetrieved += events.length;\n if (!this.#eventBufferSize) {\n this.#activeClient.eventsRetrievalProgress(0);\n return;\n }\n\n if (this.#eventsRetrieved > this.#eventBufferSize) {\n this.#eventsRetrieved = this.#eventBufferSize;\n }\n this.#activeClient.eventsRetrievalProgress(this.#eventsRetrieved / this.#eventBufferSize);\n }\n\n tracingComplete(): void {\n this.#eventBufferSize = 0;\n this.#eventsRetrieved = 0;\n if (this.#activeClient) {\n this.#activeClient.tracingComplete();\n this.#activeClient = null;\n }\n this.#finishing = false;\n }\n\n async reset(): Promise<void> {\n // If we have an active client, we should try to stop\n // it before resetting it, else we will leave the\n // backend in a broken state where it thinks we are in\n // the middle of tracing, but we think we are not.\n // Then, any subsequent attempts to record will fail\n // because the backend will not let us start a second\n // tracing session.\n if (this.#activeClient) {\n await this.#tracingAgent.invoke_end();\n }\n this.#eventBufferSize = 0;\n this.#eventsRetrieved = 0;\n this.#activeClient = null;\n this.#finishing = false;\n }\n\n // TODO(petermarshall): Use the traceConfig argument instead of deprecated\n // categories + options.\n async start(client: TracingManagerClient, categoryFilter: string, options: string):\n Promise<Protocol.ProtocolResponseWithError> {\n if (this.#activeClient) {\n throw new Error('Tracing is already started');\n }\n const bufferUsageReportingIntervalMs = 500;\n this.#activeClient = client;\n const args = {\n bufferUsageReportingInterval: bufferUsageReportingIntervalMs,\n categories: categoryFilter,\n options: options,\n transferMode: Protocol.Tracing.StartRequestTransferMode.ReportEvents,\n };\n const response = await this.#tracingAgent.invoke_start(args);\n if (response.getError()) {\n this.#activeClient = null;\n }\n await this.warmupJsProfiler();\n return response;\n }\n\n // CPUProfiler::StartProfiling has a non-trivial cost and we'd prefer it not happen within an\n // interaction as that complicates debugging interaction latency.\n // To trigger the StartProfiling interrupt and get the warmup cost out of the way, we send a\n // very soft invocation to V8.\n // https://crbug.com/1358602\n async warmupJsProfiler(): Promise<void> {\n const runtimeModel = this.target().model(SDK.RuntimeModel.RuntimeModel);\n if (!runtimeModel) {\n return;\n }\n await runtimeModel.checkSideEffectSupport();\n }\n\n stop(): void {\n if (!this.#activeClient) {\n throw new Error('Tracing is not started');\n }\n if (this.#finishing) {\n throw new Error('Tracing is already being stopped');\n }\n this.#finishing = true;\n void this.#tracingAgent.invoke_end();\n }\n}\n\nexport interface TracingManagerClient {\n traceEventsCollected(events: EventPayload[]): void;\n\n tracingComplete(): void;\n tracingBufferUsage(usage: number): void;\n eventsRetrievalProgress(progress: number): void;\n}\n\nclass TracingDispatcher implements ProtocolProxyApi.TracingDispatcher {\n readonly #tracingManager: TracingManager;\n constructor(tracingManager: TracingManager) {\n this.#tracingManager = tracingManager;\n }\n\n bufferUsage({value, eventCount, percentFull}: Protocol.Tracing.BufferUsageEvent): void {\n this.#tracingManager.bufferUsage(value, eventCount, percentFull);\n }\n\n dataCollected({value}: Protocol.Tracing.DataCollectedEvent): void {\n this.#tracingManager.eventsCollected(value);\n }\n\n tracingComplete(): void {\n this.#tracingManager.tracingComplete();\n }\n}\n\nSDK.SDKModel.SDKModel.register(TracingManager, {capabilities: SDK.Target.Capability.Tracing, autostart: false});\nexport interface EventPayload {\n cat?: string;\n pid: number;\n tid: number;\n ts: number;\n ph: Types.TraceEvents.Phase;\n name: string;\n args: {\n // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration\n // eslint-disable-next-line @typescript-eslint/naming-convention\n sort_index: number,\n name: string,\n snapshot: ObjectSnapshot,\n data: Object|null,\n };\n dur: number;\n id?: string;\n id2?: {\n global: (string|undefined),\n local: (string|undefined),\n };\n scope: string;\n}\n"]}