@grafana/scenes 6.40.0--canary.1278.18560955561.0 → 6.40.0--canary.1265.18596374903.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/dist/esm/behaviors/SceneInteractionTracker.js.map +1 -1
  2. package/dist/esm/behaviors/SceneQueryController.js.map +1 -1
  3. package/dist/esm/components/SceneRefreshPicker.js +1 -1
  4. package/dist/esm/components/SceneRefreshPicker.js.map +1 -1
  5. package/dist/esm/components/VizPanel/VizPanel.js +26 -0
  6. package/dist/esm/components/VizPanel/VizPanel.js.map +1 -1
  7. package/dist/esm/components/VizPanel/VizPanelRenderer.js +20 -18
  8. package/dist/esm/components/VizPanel/VizPanelRenderer.js.map +1 -1
  9. package/dist/esm/core/SceneTimeRange.js +1 -1
  10. package/dist/esm/core/SceneTimeRange.js.map +1 -1
  11. package/dist/esm/core/sceneGraph/index.js +1 -1
  12. package/dist/esm/index.js +6 -4
  13. package/dist/esm/index.js.map +1 -1
  14. package/dist/esm/locales/cs-CZ/grafana-scenes.json.js +4 -0
  15. package/dist/esm/locales/cs-CZ/grafana-scenes.json.js.map +1 -1
  16. package/dist/esm/locales/de-DE/grafana-scenes.json.js +4 -0
  17. package/dist/esm/locales/de-DE/grafana-scenes.json.js.map +1 -1
  18. package/dist/esm/locales/es-ES/grafana-scenes.json.js +4 -0
  19. package/dist/esm/locales/es-ES/grafana-scenes.json.js.map +1 -1
  20. package/dist/esm/locales/fr-FR/grafana-scenes.json.js +4 -0
  21. package/dist/esm/locales/fr-FR/grafana-scenes.json.js.map +1 -1
  22. package/dist/esm/locales/hu-HU/grafana-scenes.json.js +4 -0
  23. package/dist/esm/locales/hu-HU/grafana-scenes.json.js.map +1 -1
  24. package/dist/esm/locales/id-ID/grafana-scenes.json.js +4 -0
  25. package/dist/esm/locales/id-ID/grafana-scenes.json.js.map +1 -1
  26. package/dist/esm/locales/it-IT/grafana-scenes.json.js +4 -0
  27. package/dist/esm/locales/it-IT/grafana-scenes.json.js.map +1 -1
  28. package/dist/esm/locales/ja-JP/grafana-scenes.json.js +4 -0
  29. package/dist/esm/locales/ja-JP/grafana-scenes.json.js.map +1 -1
  30. package/dist/esm/locales/ko-KR/grafana-scenes.json.js +4 -0
  31. package/dist/esm/locales/ko-KR/grafana-scenes.json.js.map +1 -1
  32. package/dist/esm/locales/nl-NL/grafana-scenes.json.js +4 -0
  33. package/dist/esm/locales/nl-NL/grafana-scenes.json.js.map +1 -1
  34. package/dist/esm/locales/pl-PL/grafana-scenes.json.js +4 -0
  35. package/dist/esm/locales/pl-PL/grafana-scenes.json.js.map +1 -1
  36. package/dist/esm/locales/pt-BR/grafana-scenes.json.js +4 -0
  37. package/dist/esm/locales/pt-BR/grafana-scenes.json.js.map +1 -1
  38. package/dist/esm/locales/pt-PT/grafana-scenes.json.js +4 -0
  39. package/dist/esm/locales/pt-PT/grafana-scenes.json.js.map +1 -1
  40. package/dist/esm/locales/ru-RU/grafana-scenes.json.js +4 -0
  41. package/dist/esm/locales/ru-RU/grafana-scenes.json.js.map +1 -1
  42. package/dist/esm/locales/sv-SE/grafana-scenes.json.js +4 -0
  43. package/dist/esm/locales/sv-SE/grafana-scenes.json.js.map +1 -1
  44. package/dist/esm/locales/tr-TR/grafana-scenes.json.js +4 -0
  45. package/dist/esm/locales/tr-TR/grafana-scenes.json.js.map +1 -1
  46. package/dist/esm/locales/zh-Hans/grafana-scenes.json.js +4 -0
  47. package/dist/esm/locales/zh-Hans/grafana-scenes.json.js.map +1 -1
  48. package/dist/esm/locales/zh-Hant/grafana-scenes.json.js +4 -0
  49. package/dist/esm/locales/zh-Hant/grafana-scenes.json.js.map +1 -1
  50. package/dist/esm/{behaviors → performance}/LongFrameDetector.js +11 -11
  51. package/dist/esm/performance/LongFrameDetector.js.map +1 -0
  52. package/dist/esm/performance/PanelProfilingManager.js +65 -0
  53. package/dist/esm/performance/PanelProfilingManager.js.map +1 -0
  54. package/dist/esm/performance/ScenePerformanceTracker.js +78 -0
  55. package/dist/esm/performance/ScenePerformanceTracker.js.map +1 -0
  56. package/dist/esm/{behaviors → performance}/SceneRenderProfiler.js +87 -132
  57. package/dist/esm/performance/SceneRenderProfiler.js.map +1 -0
  58. package/dist/esm/performance/VizPanelRenderProfiler.js +320 -0
  59. package/dist/esm/performance/VizPanelRenderProfiler.js.map +1 -0
  60. package/dist/esm/performance/index.js +7 -0
  61. package/dist/esm/performance/index.js.map +1 -0
  62. package/dist/esm/performance/interactionConstants.js +14 -0
  63. package/dist/esm/performance/interactionConstants.js.map +1 -0
  64. package/dist/esm/querying/SceneDataTransformer.js +57 -0
  65. package/dist/esm/querying/SceneDataTransformer.js.map +1 -1
  66. package/dist/esm/querying/SceneQueryRunner.js +11 -6
  67. package/dist/esm/querying/SceneQueryRunner.js.map +1 -1
  68. package/dist/esm/querying/registerQueryWithController.js +49 -2
  69. package/dist/esm/querying/registerQueryWithController.js.map +1 -1
  70. package/dist/esm/utils/findPanelProfiler.js +18 -0
  71. package/dist/esm/utils/findPanelProfiler.js.map +1 -0
  72. package/dist/esm/utils/writePerformanceLog.js +12 -0
  73. package/dist/esm/utils/writePerformanceLog.js.map +1 -0
  74. package/dist/esm/utils/writeSceneLog.js +1 -10
  75. package/dist/esm/utils/writeSceneLog.js.map +1 -1
  76. package/dist/esm/variables/adhoc/AdHocFiltersCombobox/AdHocFiltersCombobox.js +1 -1
  77. package/dist/esm/variables/adhoc/AdHocFiltersCombobox/AdHocFiltersCombobox.js.map +1 -1
  78. package/dist/esm/variables/adhoc/AdHocFiltersVariable.js +9 -12
  79. package/dist/esm/variables/adhoc/AdHocFiltersVariable.js.map +1 -1
  80. package/dist/esm/variables/components/VariableValueSelect.js +1 -1
  81. package/dist/esm/variables/components/VariableValueSelect.js.map +1 -1
  82. package/dist/esm/variables/groupby/GroupByVariable.js +7 -13
  83. package/dist/esm/variables/groupby/GroupByVariable.js.map +1 -1
  84. package/dist/esm/variables/variants/MultiValueVariable.js +1 -1
  85. package/dist/esm/variables/variants/MultiValueVariable.js.map +1 -1
  86. package/dist/esm/variables/variants/ScopesVariable.js +1 -1
  87. package/dist/esm/variables/variants/ScopesVariable.js.map +1 -1
  88. package/dist/{grafana-scenes-CfoPR_PZ.js → grafana-scenes-BH2OEiLz.js} +5 -1
  89. package/dist/{grafana-scenes-BbJq3cEa.js.map → grafana-scenes-BH2OEiLz.js.map} +1 -1
  90. package/dist/{grafana-scenes-cTJt4LR7.js → grafana-scenes-BLJV6eE3.js} +5 -1
  91. package/dist/{grafana-scenes-BbRDYrqK.js.map → grafana-scenes-BLJV6eE3.js.map} +1 -1
  92. package/dist/{grafana-scenes-CqMfWT-f.js → grafana-scenes-BrExMMR1.js} +5 -1
  93. package/dist/{grafana-scenes-BcDO8gk4.js.map → grafana-scenes-BrExMMR1.js.map} +1 -1
  94. package/dist/{grafana-scenes-CzZTvOrf.js → grafana-scenes-BrpU2VxI.js} +5 -1
  95. package/dist/{grafana-scenes-BtGEpoZT.js.map → grafana-scenes-BrpU2VxI.js.map} +1 -1
  96. package/dist/{grafana-scenes-zGpJY4O3.js → grafana-scenes-CRkk3i3Y.js} +5 -1
  97. package/dist/grafana-scenes-CRkk3i3Y.js.map +1 -0
  98. package/dist/{grafana-scenes-kfW02M-K.js → grafana-scenes-CfuUpx6R.js} +5 -1
  99. package/dist/grafana-scenes-CfuUpx6R.js.map +1 -0
  100. package/dist/{grafana-scenes-CMtHJ23j.js → grafana-scenes-Cl-piLdF.js} +5 -1
  101. package/dist/grafana-scenes-Cl-piLdF.js.map +1 -0
  102. package/dist/{grafana-scenes-CS09sc_L.js → grafana-scenes-D-DPZiBx.js} +5 -1
  103. package/dist/grafana-scenes-D-DPZiBx.js.map +1 -0
  104. package/dist/{grafana-scenes-CixWq8rH.js → grafana-scenes-D1jd3aZp.js} +5 -1
  105. package/dist/grafana-scenes-D1jd3aZp.js.map +1 -0
  106. package/dist/{grafana-scenes-CoXR5Z7T.js → grafana-scenes-DNMnQEFs.js} +5 -1
  107. package/dist/grafana-scenes-DNMnQEFs.js.map +1 -0
  108. package/dist/{grafana-scenes-BwQ_A3lk.js → grafana-scenes-DPbgWPLH.js} +5 -1
  109. package/dist/grafana-scenes-DPbgWPLH.js.map +1 -0
  110. package/dist/{grafana-scenes-BbRDYrqK.js → grafana-scenes-DTn3nyOX.js} +5 -1
  111. package/dist/grafana-scenes-DTn3nyOX.js.map +1 -0
  112. package/dist/{grafana-scenes-VOzZRdKp.js → grafana-scenes-DaO9TTTj.js} +5 -1
  113. package/dist/grafana-scenes-DaO9TTTj.js.map +1 -0
  114. package/dist/{grafana-scenes-C-CibbsO.js → grafana-scenes-DoKV4lED.js} +5 -1
  115. package/dist/grafana-scenes-DoKV4lED.js.map +1 -0
  116. package/dist/{grafana-scenes-BcDO8gk4.js → grafana-scenes-DpvJWDGo.js} +5 -1
  117. package/dist/grafana-scenes-DpvJWDGo.js.map +1 -0
  118. package/dist/{grafana-scenes-naZktXG6.js → grafana-scenes-Kqjin1Vr.js} +5 -1
  119. package/dist/grafana-scenes-Kqjin1Vr.js.map +1 -0
  120. package/dist/{grafana-scenes-BbJq3cEa.js → grafana-scenes-OEGPBO01.js} +5 -1
  121. package/dist/grafana-scenes-OEGPBO01.js.map +1 -0
  122. package/dist/{grafana-scenes-BtGEpoZT.js → grafana-scenes-qNHDZUAZ.js} +5 -1
  123. package/dist/grafana-scenes-qNHDZUAZ.js.map +1 -0
  124. package/dist/index.d.ts +460 -105
  125. package/dist/index.js +7827 -7266
  126. package/dist/index.js.map +1 -1
  127. package/package.json +2 -2
  128. package/dist/esm/behaviors/LongFrameDetector.js.map +0 -1
  129. package/dist/esm/behaviors/SceneRenderProfiler.js.map +0 -1
  130. package/dist/grafana-scenes-BwQ_A3lk.js.map +0 -1
  131. package/dist/grafana-scenes-C-CibbsO.js.map +0 -1
  132. package/dist/grafana-scenes-CMtHJ23j.js.map +0 -1
  133. package/dist/grafana-scenes-CS09sc_L.js.map +0 -1
  134. package/dist/grafana-scenes-CfoPR_PZ.js.map +0 -1
  135. package/dist/grafana-scenes-CixWq8rH.js.map +0 -1
  136. package/dist/grafana-scenes-CoXR5Z7T.js.map +0 -1
  137. package/dist/grafana-scenes-CqMfWT-f.js.map +0 -1
  138. package/dist/grafana-scenes-CzZTvOrf.js.map +0 -1
  139. package/dist/grafana-scenes-VOzZRdKp.js.map +0 -1
  140. package/dist/grafana-scenes-cTJt4LR7.js.map +0 -1
  141. package/dist/grafana-scenes-kfW02M-K.js.map +0 -1
  142. package/dist/grafana-scenes-naZktXG6.js.map +0 -1
  143. package/dist/grafana-scenes-zGpJY4O3.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LongFrameDetector.js","sources":["../../../src/performance/LongFrameDetector.ts"],"sourcesContent":["import { writePerformanceLog } from '../utils/writePerformanceLog';\n\nconst LONG_FRAME_THRESHOLD = 50; // Threshold for both LoAF and manual tracking (ms)\n\nexport interface LongFrameEvent {\n duration: number; // Frame duration in milliseconds\n timestamp: number; // When the frame occurred\n method: 'manual' | 'loaf'; // Which detection method was used\n}\n\nexport type LongFrameCallback = (event: LongFrameEvent) => void;\n\n/**\n * LongFrameDetector is a module for detecting long animation frames.\n *\n * It supports two detection methods with automatic fallback:\n * 1. LoAF API (default when available): Uses Long Animation Frame API with 50ms threshold\n * 2. Manual tracking (fallback): Uses requestAnimationFrame with configurable threshold (default: 50ms)\n *\n * The detector automatically uses LoAF when available for better attribution and performance,\n * falling back to manual tracking for broader browser support.\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Performance_API/Long_animation_frame_timing\n */\nexport class LongFrameDetector {\n #isTracking = false;\n #callback: LongFrameCallback | null = null;\n\n // Manual tracking state\n #frameTrackingId: number | null = null;\n #lastFrameTime = 0;\n\n // LoAF tracking state\n #loafObserver: PerformanceObserver | null = null;\n\n /**\n * Check if LoAF API is available in the browser\n */\n private isLoAFAvailable(): boolean {\n return (\n typeof PerformanceObserver !== 'undefined' &&\n PerformanceObserver.supportedEntryTypes &&\n PerformanceObserver.supportedEntryTypes.includes('long-animation-frame')\n );\n }\n\n /**\n * Start detecting long frames and call the provided callback when they occur\n */\n public start(callback: LongFrameCallback): void {\n if (this.#isTracking) {\n writePerformanceLog('LFD', 'Already tracking frames, stopping previous session');\n this.stop();\n }\n\n this.#callback = callback;\n this.#isTracking = true;\n\n if (this.isLoAFAvailable()) {\n this.startLoAFTracking();\n } else {\n this.startManualFrameTracking();\n }\n\n writePerformanceLog(\n 'LFD',\n `Started tracking with ${\n this.isLoAFAvailable() ? 'LoAF API' : 'manual'\n } method, threshold: ${LONG_FRAME_THRESHOLD}ms`\n );\n }\n\n /**\n * Stop detecting long frames\n */\n public stop(): void {\n if (!this.#isTracking) {\n return;\n }\n\n this.#isTracking = false;\n this.#callback = null;\n\n // Stop both tracking methods to ensure cleanup\n this.stopLoAFTracking();\n this.stopManualFrameTracking();\n }\n\n /**\n * Check if currently tracking frames\n */\n public isTracking(): boolean {\n return this.#isTracking;\n }\n\n /**\n * Start tracking using the Long Animation Frame API\n * @see https://developer.mozilla.org/en-US/docs/Web/API/PerformanceLongAnimationFrameTiming\n */\n private startLoAFTracking(): void {\n if (!this.isLoAFAvailable()) {\n writePerformanceLog('LFD', 'LoAF API not available, falling back to manual tracking');\n this.startManualFrameTracking();\n return;\n }\n\n try {\n this.#loafObserver = new PerformanceObserver((list) => {\n for (const entry of list.getEntries()) {\n // No duration check needed - LoAF API already filters for long frames (>50ms)\n const event: LongFrameEvent = {\n duration: entry.duration,\n timestamp: entry.startTime,\n method: 'loaf',\n };\n\n if (this.#callback) {\n this.#callback(event);\n }\n\n // Add performance marks and measurements for debugging in dev tools\n if (typeof performance !== 'undefined' && performance.mark && performance.measure) {\n const frameId = `long-frame-${entry.startTime.toFixed(0)}`;\n const startMarkName = `${frameId}-start`;\n const endMarkName = `${frameId}-end`;\n const measureName = `Long Frame (LoAF): ${entry.duration.toFixed(1)}ms`;\n\n try {\n // Create start and end marks\n performance.mark(startMarkName, { startTime: entry.startTime });\n performance.mark(endMarkName, { startTime: entry.startTime + entry.duration });\n\n // Create measurement span\n performance.measure(measureName, startMarkName, endMarkName);\n } catch {\n // Fallback for browsers that don't support startTime option\n performance.mark(measureName);\n }\n }\n\n writePerformanceLog('LFD', `Long frame detected (LoAF): ${entry.duration}ms at ${entry.startTime}ms`);\n }\n });\n\n this.#loafObserver.observe({ type: 'long-animation-frame', buffered: false });\n } catch (error) {\n writePerformanceLog('LFD', 'Failed to start LoAF tracking, falling back to manual:', error);\n this.startManualFrameTracking();\n }\n }\n\n /**\n * Stop LoAF tracking\n */\n private stopLoAFTracking(): void {\n if (this.#loafObserver) {\n this.#loafObserver.disconnect();\n this.#loafObserver = null;\n writePerformanceLog('LFD', 'Stopped LoAF tracking');\n }\n }\n\n /**\n * Start manual frame tracking using requestAnimationFrame\n */\n private startManualFrameTracking(): void {\n this.#lastFrameTime = performance.now();\n this.#frameTrackingId = requestAnimationFrame(() => this.measureFrames());\n }\n\n /**\n * Stop manual frame tracking\n */\n private stopManualFrameTracking(): void {\n if (this.#frameTrackingId) {\n cancelAnimationFrame(this.#frameTrackingId);\n this.#frameTrackingId = null;\n writePerformanceLog('LFD', 'Stopped manual frame tracking');\n }\n }\n\n /**\n * Measure frame durations using requestAnimationFrame\n */\n private measureFrames = (): void => {\n if (!this.#isTracking) {\n return;\n }\n\n const currentFrameTime = performance.now();\n const frameLength = currentFrameTime - this.#lastFrameTime;\n\n // Check if frame exceeds threshold\n if (frameLength > LONG_FRAME_THRESHOLD) {\n const event: LongFrameEvent = {\n duration: frameLength,\n timestamp: currentFrameTime,\n method: 'manual',\n };\n\n if (this.#callback) {\n this.#callback(event);\n }\n\n // Add performance marks and measurements for debugging in dev tools\n if (typeof performance !== 'undefined' && performance.mark && performance.measure) {\n const frameId = `long-frame-manual-${currentFrameTime.toFixed(0)}`;\n const startMarkName = `${frameId}-start`;\n const endMarkName = `${frameId}-end`;\n const measureName = `Long Frame (Manual): ${frameLength.toFixed(1)}ms`;\n\n try {\n // Create start and end marks\n performance.mark(startMarkName, { startTime: currentFrameTime - frameLength });\n performance.mark(endMarkName, { startTime: currentFrameTime });\n\n // Create measurement span\n performance.measure(measureName, startMarkName, endMarkName);\n } catch {\n // Fallback for browsers that don't support startTime option\n performance.mark(measureName);\n }\n }\n\n writePerformanceLog(\n 'LFD',\n `Long frame detected (manual): ${frameLength}ms (threshold: ${LONG_FRAME_THRESHOLD}ms)`\n );\n }\n\n this.#lastFrameTime = currentFrameTime;\n\n // Continue tracking\n if (this.#isTracking) {\n this.#frameTrackingId = requestAnimationFrame(this.measureFrames);\n }\n };\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ import { VizPanel } from '../components/VizPanel/VizPanel.js';
2
+ import { VizPanelRenderProfiler } from './VizPanelRenderProfiler.js';
3
+ import { sceneGraph } from '../core/sceneGraph/index.js';
4
+
5
+ class PanelProfilingManager {
6
+ constructor(_config) {
7
+ this._config = _config;
8
+ this._subscriptions = [];
9
+ }
10
+ /**
11
+ * Attach panel profiling to a scene object
12
+ */
13
+ attachToScene(sceneObject) {
14
+ this._sceneObject = sceneObject;
15
+ const subscription = sceneObject.subscribeToState((newState, prevState) => {
16
+ if (this._config.watchStateKey) {
17
+ if (newState[this._config.watchStateKey] !== prevState[this._config.watchStateKey]) {
18
+ this._attachProfilersToPanels();
19
+ }
20
+ } else {
21
+ this._attachProfilersToPanels();
22
+ }
23
+ });
24
+ this._subscriptions.push(subscription);
25
+ this._attachProfilersToPanels();
26
+ }
27
+ /**
28
+ * Attach VizPanelRenderProfiler to a specific panel if it doesn't already have one
29
+ * @param panel - The VizPanel to attach profiling to
30
+ */
31
+ attachProfilerToPanel(panel) {
32
+ var _a;
33
+ const existingProfiler = (_a = panel.state.$behaviors) == null ? void 0 : _a.find((b) => b instanceof VizPanelRenderProfiler);
34
+ if (existingProfiler) {
35
+ return;
36
+ }
37
+ const profiler = new VizPanelRenderProfiler();
38
+ panel.setState({
39
+ $behaviors: [...panel.state.$behaviors || [], profiler]
40
+ });
41
+ }
42
+ /**
43
+ * Attach VizPanelRenderProfiler to all VizPanels that don't already have one
44
+ */
45
+ _attachProfilersToPanels() {
46
+ if (!this._sceneObject) {
47
+ return;
48
+ }
49
+ const panels = sceneGraph.findAllObjects(this._sceneObject, (obj) => obj instanceof VizPanel);
50
+ panels.forEach((panel) => {
51
+ this.attachProfilerToPanel(panel);
52
+ });
53
+ }
54
+ /**
55
+ * Clean up subscriptions and references
56
+ */
57
+ cleanup() {
58
+ this._subscriptions.forEach((sub) => sub.unsubscribe());
59
+ this._subscriptions = [];
60
+ this._sceneObject = void 0;
61
+ }
62
+ }
63
+
64
+ export { PanelProfilingManager };
65
+ //# sourceMappingURL=PanelProfilingManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PanelProfilingManager.js","sources":["../../../src/performance/PanelProfilingManager.ts"],"sourcesContent":["import { Unsubscribable } from 'rxjs';\nimport { VizPanel } from '../components/VizPanel/VizPanel';\nimport { VizPanelRenderProfiler } from './VizPanelRenderProfiler';\nimport { SceneObject } from '../core/types';\nimport { sceneGraph } from '../core/sceneGraph';\n\nexport interface PanelProfilingConfig {\n watchStateKey?: string; // State property to watch for structural changes (e.g., 'body', 'children')\n}\n\n/**\n * Manages VizPanelRenderProfiler instances for all panels in a scene object.\n * Extracted from DashboardPanelProfilingBehavior to allow composition with SceneRenderProfiler.\n */\nexport class PanelProfilingManager {\n private _sceneObject?: SceneObject;\n private _subscriptions: Unsubscribable[] = [];\n\n public constructor(private _config: PanelProfilingConfig) {}\n\n /**\n * Attach panel profiling to a scene object\n */\n public attachToScene(sceneObject: SceneObject) {\n this._sceneObject = sceneObject;\n\n // Subscribe to scene state changes to add profilers to new panels\n const subscription = sceneObject.subscribeToState((newState: any, prevState: any) => {\n // If watchStateKey is specified, only react to changes in that specific property\n if (this._config.watchStateKey) {\n if (newState[this._config.watchStateKey] !== prevState[this._config.watchStateKey]) {\n this._attachProfilersToPanels();\n }\n } else {\n // Fallback: react to any state change\n this._attachProfilersToPanels();\n }\n });\n\n this._subscriptions.push(subscription);\n\n // Attach profilers to existing panels\n this._attachProfilersToPanels();\n }\n\n /**\n * Attach VizPanelRenderProfiler to a specific panel if it doesn't already have one\n * @param panel - The VizPanel to attach profiling to\n */\n public attachProfilerToPanel(panel: VizPanel): void {\n // Check if profiler already exists\n const existingProfiler = panel.state.$behaviors?.find((b) => b instanceof VizPanelRenderProfiler);\n\n if (existingProfiler) {\n return; // Already has a profiler\n }\n\n // Add profiler behavior\n const profiler = new VizPanelRenderProfiler();\n\n panel.setState({\n $behaviors: [...(panel.state.$behaviors || []), profiler],\n });\n }\n\n /**\n * Attach VizPanelRenderProfiler to all VizPanels that don't already have one\n */\n private _attachProfilersToPanels() {\n if (!this._sceneObject) {\n return;\n }\n\n // Use scene graph to find all VizPanels in the scene\n const panels = sceneGraph.findAllObjects(this._sceneObject, (obj) => obj instanceof VizPanel) as VizPanel[];\n\n panels.forEach((panel) => {\n this.attachProfilerToPanel(panel);\n });\n }\n\n /**\n * Clean up subscriptions and references\n */\n public cleanup() {\n this._subscriptions.forEach((sub) => sub.unsubscribe());\n this._subscriptions = [];\n this._sceneObject = undefined;\n }\n}\n"],"names":[],"mappings":";;;;AAcO,MAAM,qBAAsB,CAAA;AAAA,EAI1B,YAAoB,OAA+B,EAAA;AAA/B,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAF3B,IAAA,IAAA,CAAQ,iBAAmC,EAAC;AAAA;AAEe;AAAA;AAAA;AAAA,EAKpD,cAAc,WAA0B,EAAA;AAC7C,IAAA,IAAA,CAAK,YAAe,GAAA,WAAA;AAGpB,IAAA,MAAM,YAAe,GAAA,WAAA,CAAY,gBAAiB,CAAA,CAAC,UAAe,SAAmB,KAAA;AAEnF,MAAI,IAAA,IAAA,CAAK,QAAQ,aAAe,EAAA;AAC9B,QAAI,IAAA,QAAA,CAAS,KAAK,OAAQ,CAAA,aAAa,MAAM,SAAU,CAAA,IAAA,CAAK,OAAQ,CAAA,aAAa,CAAG,EAAA;AAClF,UAAA,IAAA,CAAK,wBAAyB,EAAA;AAAA;AAChC,OACK,MAAA;AAEL,QAAA,IAAA,CAAK,wBAAyB,EAAA;AAAA;AAChC,KACD,CAAA;AAED,IAAK,IAAA,CAAA,cAAA,CAAe,KAAK,YAAY,CAAA;AAGrC,IAAA,IAAA,CAAK,wBAAyB,EAAA;AAAA;AAChC;AAAA;AAAA;AAAA;AAAA,EAMO,sBAAsB,KAAuB,EAAA;AAjDtD,IAAA,IAAA,EAAA;AAmDI,IAAM,MAAA,gBAAA,GAAA,CAAmB,WAAM,KAAM,CAAA,UAAA,KAAZ,mBAAwB,IAAK,CAAA,CAAC,MAAM,CAAa,YAAA,sBAAA,CAAA;AAE1E,IAAA,IAAI,gBAAkB,EAAA;AACpB,MAAA;AAAA;AAIF,IAAM,MAAA,QAAA,GAAW,IAAI,sBAAuB,EAAA;AAE5C,IAAA,KAAA,CAAM,QAAS,CAAA;AAAA,MACb,UAAA,EAAY,CAAC,GAAI,KAAA,CAAM,MAAM,UAAc,IAAA,IAAK,QAAQ;AAAA,KACzD,CAAA;AAAA;AACH;AAAA;AAAA;AAAA,EAKQ,wBAA2B,GAAA;AACjC,IAAI,IAAA,CAAC,KAAK,YAAc,EAAA;AACtB,MAAA;AAAA;AAIF,IAAM,MAAA,MAAA,GAAS,WAAW,cAAe,CAAA,IAAA,CAAK,cAAc,CAAC,GAAA,KAAQ,eAAe,QAAQ,CAAA;AAE5F,IAAO,MAAA,CAAA,OAAA,CAAQ,CAAC,KAAU,KAAA;AACxB,MAAA,IAAA,CAAK,sBAAsB,KAAK,CAAA;AAAA,KACjC,CAAA;AAAA;AACH;AAAA;AAAA;AAAA,EAKO,OAAU,GAAA;AACf,IAAA,IAAA,CAAK,eAAe,OAAQ,CAAA,CAAC,GAAQ,KAAA,GAAA,CAAI,aAAa,CAAA;AACtD,IAAA,IAAA,CAAK,iBAAiB,EAAC;AACvB,IAAA,IAAA,CAAK,YAAe,GAAA,MAAA;AAAA;AAExB;;;;"}
@@ -0,0 +1,78 @@
1
+ let operationCounter = 0;
2
+ function generateOperationId(prefix = "op") {
3
+ return `${prefix}-${Date.now()}-${++operationCounter}`;
4
+ }
5
+ const _ScenePerformanceTracker = class _ScenePerformanceTracker {
6
+ constructor() {
7
+ this.observers = [];
8
+ }
9
+ static getInstance() {
10
+ if (!_ScenePerformanceTracker.instance) {
11
+ _ScenePerformanceTracker.instance = new _ScenePerformanceTracker();
12
+ }
13
+ return _ScenePerformanceTracker.instance;
14
+ }
15
+ /**
16
+ * Register a performance observer
17
+ */
18
+ addObserver(observer) {
19
+ this.observers.push(observer);
20
+ return () => {
21
+ const index = this.observers.indexOf(observer);
22
+ if (index > -1) {
23
+ this.observers.splice(index, 1);
24
+ }
25
+ };
26
+ }
27
+ /**
28
+ * Remove all observers (for testing)
29
+ */
30
+ clearObservers() {
31
+ this.observers = [];
32
+ }
33
+ /**
34
+ * Get current observer count (for debugging)
35
+ */
36
+ getObserverCount() {
37
+ return this.observers.length;
38
+ }
39
+ notifyObservers(methodName, data, errorContext) {
40
+ this.observers.forEach((observer) => {
41
+ try {
42
+ const method = observer[methodName];
43
+ method == null ? void 0 : method(data);
44
+ } catch (error) {
45
+ console.warn(`Error in ${errorContext} observer:`, error);
46
+ }
47
+ });
48
+ }
49
+ notifyDashboardInteractionStart(data) {
50
+ this.notifyObservers("onDashboardInteractionStart", data, "dashboard interaction start");
51
+ }
52
+ notifyDashboardInteractionMilestone(data) {
53
+ this.notifyObservers("onDashboardInteractionMilestone", data, "dashboard interaction milestone");
54
+ }
55
+ notifyDashboardInteractionComplete(data) {
56
+ this.notifyObservers("onDashboardInteractionComplete", data, "dashboard interaction complete");
57
+ }
58
+ notifyPanelOperationStart(data) {
59
+ this.notifyObservers("onPanelOperationStart", data, "panel operation start");
60
+ }
61
+ notifyPanelOperationComplete(data) {
62
+ this.notifyObservers("onPanelOperationComplete", data, "panel operation complete");
63
+ }
64
+ notifyQueryStart(data) {
65
+ this.notifyObservers("onQueryStart", data, "query start");
66
+ }
67
+ notifyQueryComplete(data) {
68
+ this.notifyObservers("onQueryComplete", data, "query complete");
69
+ }
70
+ };
71
+ _ScenePerformanceTracker.instance = null;
72
+ let ScenePerformanceTracker = _ScenePerformanceTracker;
73
+ function getScenePerformanceTracker() {
74
+ return ScenePerformanceTracker.getInstance();
75
+ }
76
+
77
+ export { ScenePerformanceTracker, generateOperationId, getScenePerformanceTracker };
78
+ //# sourceMappingURL=ScenePerformanceTracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ScenePerformanceTracker.js","sources":["../../../src/performance/ScenePerformanceTracker.ts"],"sourcesContent":["/**\n * Centralized performance tracking system using observer pattern.\n * External systems (like Grafana) implement ScenePerformanceObserver to receive performance events.\n */\n\n/** Generate unique operation IDs for correlating start/complete events */\nlet operationCounter = 0;\nexport function generateOperationId(prefix = 'op'): string {\n return `${prefix}-${Date.now()}-${++operationCounter}`;\n}\n\n/** Base interface for all performance events */\nexport interface BasePerformanceEvent {\n operationId: string; // Unique identifier for correlating start/complete events\n timestamp: number;\n duration?: number;\n error?: string;\n}\n\nexport interface DashboardInteractionStartData extends BasePerformanceEvent {\n interactionType: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface DashboardInteractionMilestoneData extends BasePerformanceEvent {\n interactionType: string;\n milestone: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface DashboardInteractionCompleteData extends BasePerformanceEvent {\n interactionType: string;\n networkDuration?: number;\n longFramesCount: number;\n longFramesTotalTime: number;\n metadata?: Record<string, unknown>;\n}\n\n/** Metadata interface for transform operations */\nexport interface TransformMetadata {\n transformationId: string;\n transformationCount: number;\n seriesTransformationCount: number;\n annotationTransformationCount: number;\n success?: boolean;\n error?: string;\n}\n\n/** Metadata interface for query operations */\nexport interface QueryMetadata {\n queryId: string;\n queryType: string;\n}\n\n/** Metadata interface for render operations */\nexport interface RenderMetadata {\n // Empty for now - can be extended later if needed\n}\n\n/** Metadata interface for plugin load operations */\nexport interface PluginLoadMetadata {\n pluginId: string;\n fromCache?: boolean;\n pluginLoadTime?: number;\n}\n\n/** Metadata interface for field config operations */\nexport interface FieldConfigMetadata {}\n\n/** Base interface for panel performance events */\ninterface BasePanelPerformanceData extends BasePerformanceEvent {\n panelId: string;\n panelKey: string;\n pluginId: string;\n pluginVersion?: string;\n panelTitle?: string;\n}\n\n/** Transform operation performance data */\nexport interface PanelTransformPerformanceData extends BasePanelPerformanceData {\n operation: 'transform';\n metadata: TransformMetadata;\n}\n\n/** Query operation performance data */\nexport interface PanelQueryPerformanceData extends BasePanelPerformanceData {\n operation: 'query';\n metadata: QueryMetadata;\n}\n\n/** Render operation performance data */\nexport interface PanelRenderPerformanceData extends BasePanelPerformanceData {\n operation: 'render';\n metadata: RenderMetadata;\n}\n\n/** Plugin load operation performance data */\nexport interface PanelPluginLoadPerformanceData extends BasePanelPerformanceData {\n operation: 'plugin-load';\n metadata: PluginLoadMetadata;\n}\n\n/** Field config operation performance data */\nexport interface PanelFieldConfigPerformanceData extends BasePanelPerformanceData {\n operation: 'fieldConfig';\n metadata: FieldConfigMetadata;\n}\n\n/** Discriminated union of all panel performance data types */\nexport type PanelPerformanceData =\n | PanelTransformPerformanceData\n | PanelQueryPerformanceData\n | PanelRenderPerformanceData\n | PanelPluginLoadPerformanceData\n | PanelFieldConfigPerformanceData;\n\n/** Non-panel query performance data for dashboard queries (annotations, variables, etc.) */\nexport interface QueryPerformanceData extends BasePerformanceEvent {\n queryId: string;\n queryType: string;\n origin: string; // e.g., \"AnnotationsDataLayer\", \"QueryVariable\", \"VizPanel/loadPlugin\"\n}\n\n/**\n * Observer interface for performance monitoring\n * External systems implement this to receive performance notifications\n */\nexport interface ScenePerformanceObserver {\n // Dashboard-level events\n onDashboardInteractionStart?(data: DashboardInteractionStartData): void;\n onDashboardInteractionMilestone?(data: DashboardInteractionMilestoneData): void;\n onDashboardInteractionComplete?(data: DashboardInteractionCompleteData): void;\n\n // Panel-level events\n onPanelOperationStart?(data: PanelPerformanceData): void;\n onPanelOperationComplete?(data: PanelPerformanceData): void;\n\n // Query-level events\n onQueryStart?(data: QueryPerformanceData): void;\n onQueryComplete?(data: QueryPerformanceData): void;\n}\n\n/**\n * Centralized performance tracker\n * Manages observers and provides methods for scene objects to report performance events\n */\nexport class ScenePerformanceTracker {\n private static instance: ScenePerformanceTracker | null = null;\n private observers: ScenePerformanceObserver[] = [];\n\n public static getInstance(): ScenePerformanceTracker {\n if (!ScenePerformanceTracker.instance) {\n ScenePerformanceTracker.instance = new ScenePerformanceTracker();\n }\n return ScenePerformanceTracker.instance;\n }\n\n /**\n * Register a performance observer\n */\n public addObserver(observer: ScenePerformanceObserver): () => void {\n this.observers.push(observer);\n\n // Return unsubscribe function\n return () => {\n const index = this.observers.indexOf(observer);\n if (index > -1) {\n this.observers.splice(index, 1);\n }\n };\n }\n\n /**\n * Remove all observers (for testing)\n */\n public clearObservers(): void {\n this.observers = [];\n }\n\n /**\n * Get current observer count (for debugging)\n */\n public getObserverCount(): number {\n return this.observers.length;\n }\n\n private notifyObservers<T>(methodName: keyof ScenePerformanceObserver, data: T, errorContext: string): void {\n this.observers.forEach((observer) => {\n try {\n const method = observer[methodName] as ((data: T) => void) | undefined;\n method?.(data);\n } catch (error) {\n console.warn(`Error in ${errorContext} observer:`, error);\n }\n });\n }\n\n public notifyDashboardInteractionStart(data: DashboardInteractionStartData): void {\n this.notifyObservers('onDashboardInteractionStart', data, 'dashboard interaction start');\n }\n\n public notifyDashboardInteractionMilestone(data: DashboardInteractionMilestoneData): void {\n this.notifyObservers('onDashboardInteractionMilestone', data, 'dashboard interaction milestone');\n }\n\n public notifyDashboardInteractionComplete(data: DashboardInteractionCompleteData): void {\n this.notifyObservers('onDashboardInteractionComplete', data, 'dashboard interaction complete');\n }\n\n public notifyPanelOperationStart(data: PanelPerformanceData): void {\n this.notifyObservers('onPanelOperationStart', data, 'panel operation start');\n }\n\n public notifyPanelOperationComplete(data: PanelPerformanceData): void {\n this.notifyObservers('onPanelOperationComplete', data, 'panel operation complete');\n }\n\n public notifyQueryStart(data: QueryPerformanceData): void {\n this.notifyObservers('onQueryStart', data, 'query start');\n }\n\n public notifyQueryComplete(data: QueryPerformanceData): void {\n this.notifyObservers('onQueryComplete', data, 'query complete');\n }\n}\n\n/**\n * Get the global performance tracker instance\n */\nexport function getScenePerformanceTracker(): ScenePerformanceTracker {\n return ScenePerformanceTracker.getInstance();\n}\n"],"names":[],"mappings":"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"}
@@ -1,4 +1,6 @@
1
- import { writeSceneLog, writeSceneLogStyled } from '../utils/writeSceneLog.js';
1
+ import { writePerformanceLog } from '../utils/writePerformanceLog.js';
2
+ import { generateOperationId, getScenePerformanceTracker } from './ScenePerformanceTracker.js';
3
+ import { PanelProfilingManager } from './PanelProfilingManager.js';
2
4
  import { LongFrameDetector } from './LongFrameDetector.js';
3
5
 
4
6
  var __typeError = (msg) => {
@@ -16,17 +18,20 @@ var __privateWrapper = (obj, member, setter, getter) => ({
16
18
  return __privateGet(obj, member, getter);
17
19
  }
18
20
  });
19
- var _profileInProgress, _interactionInProgress, _profileStartTs, _trailAnimationFrameId, _recordedTrailingSpans, _longFrameDetector, _longFramesCount, _longFramesTotalTime, _visibilityChangeHandler, _onInteractionComplete;
21
+ var _profileInProgress, _interactionInProgress, _profileStartTs, _trailAnimationFrameId, _currentOperationId, _recordedTrailingSpans, _longFrameDetector, _longFramesCount, _longFramesTotalTime, _visibilityChangeHandler, _onInteractionComplete;
20
22
  const POST_STORM_WINDOW = 2e3;
21
23
  const DEFAULT_LONG_FRAME_THRESHOLD = 30;
22
24
  class SceneRenderProfiler {
23
- constructor(queryController) {
24
- this.queryController = queryController;
25
+ constructor(panelProfilingConfig) {
25
26
  __privateAdd(this, _profileInProgress, null);
26
27
  __privateAdd(this, _interactionInProgress, null);
27
28
  __privateAdd(this, _profileStartTs, null);
28
29
  __privateAdd(this, _trailAnimationFrameId, null);
29
- // Will keep measured lengths trailing frames
30
+ // Generic metadata for observer notifications
31
+ this.metadata = {};
32
+ // Operation ID for correlating dashboard interaction events
33
+ __privateAdd(this, _currentOperationId);
34
+ // Trailing frame measurements
30
35
  __privateAdd(this, _recordedTrailingSpans, []);
31
36
  // Long frame tracking
32
37
  __privateAdd(this, _longFrameDetector);
@@ -35,7 +40,6 @@ class SceneRenderProfiler {
35
40
  __privateAdd(this, _visibilityChangeHandler, null);
36
41
  __privateAdd(this, _onInteractionComplete, null);
37
42
  this.measureTrailingFrames = (measurementStartTs, lastFrameTime, profileStartTs) => {
38
- var _a, _b, _c, _d;
39
43
  const currentFrameTime = performance.now();
40
44
  const frameLength = currentFrameTime - lastFrameTime;
41
45
  __privateGet(this, _recordedTrailingSpans).push(frameLength);
@@ -48,108 +52,73 @@ class SceneRenderProfiler {
48
52
  } else {
49
53
  const slowFrames = processRecordedSpans(__privateGet(this, _recordedTrailingSpans));
50
54
  const slowFramesTime = slowFrames.reduce((acc, val) => acc + val, 0);
51
- writeSceneLog(
52
- "SceneRenderProfiler",
53
- `Profile tail recorded - Slow frames: ${slowFramesTime.toFixed(1)}ms (${slowFrames.length} frames)`
55
+ writePerformanceLog(
56
+ "SRP",
57
+ "Profile tail recorded, slow frames duration:",
58
+ slowFramesTime,
59
+ slowFrames,
60
+ __privateGet(this, _profileInProgress)
54
61
  );
55
- writeSceneLog("", ` \u251C\u2500 Origin: ${((_a = __privateGet(this, _profileInProgress)) == null ? void 0 : _a.origin) || "unknown"}`);
56
- writeSceneLog("", ` \u2514\u2500 Crumbs:`, ((_b = __privateGet(this, _profileInProgress)) == null ? void 0 : _b.crumbs) || []);
57
62
  __privateSet(this, _recordedTrailingSpans, []);
58
63
  const profileDuration = measurementStartTs - profileStartTs;
59
- if (typeof performance !== "undefined" && performance.mark) {
60
- const profileName = ((_c = __privateGet(this, _profileInProgress)) == null ? void 0 : _c.origin) || "unknown";
61
- const totalTime = profileDuration + slowFramesTime;
62
- performance.mark(`Dashboard Profile End: ${profileName}`);
63
- const startMarkName = `Dashboard Profile Start: ${profileName}`;
64
- try {
65
- performance.measure(
66
- `Dashboard Profile: ${profileName} (${totalTime.toFixed(1)}ms)`,
67
- startMarkName,
68
- `Dashboard Profile End: ${profileName}`
69
- );
70
- } catch (e) {
71
- performance.mark(`Dashboard Profile Complete: ${profileName} (${totalTime.toFixed(1)}ms)`);
72
- }
73
- if (slowFrames.length > 0) {
74
- const slowFramesMarkName = `Slow Frames Summary: ${slowFrames.length} frames (${slowFramesTime.toFixed(
75
- 1
76
- )}ms)`;
77
- performance.mark(slowFramesMarkName);
78
- slowFrames.forEach((frameTime, index) => {
79
- if (frameTime > 16) {
80
- try {
81
- const frameStartTime = __privateGet(this, _profileStartTs) + profileDuration + (index > 0 ? slowFrames.slice(0, index).reduce((sum, t) => sum + t, 0) : 0);
82
- const frameId = `slow-frame-${index}`;
83
- const frameStartMark = `${frameId}-start`;
84
- const frameEndMark = `${frameId}-end`;
85
- performance.mark(frameStartMark, { startTime: frameStartTime });
86
- performance.mark(frameEndMark, { startTime: frameStartTime + frameTime });
87
- performance.measure(`Slow Frame ${index + 1}: ${frameTime.toFixed(1)}ms`, frameStartMark, frameEndMark);
88
- } catch (e) {
89
- performance.mark(`Slow Frame ${index + 1}: ${frameTime.toFixed(1)}ms`);
90
- }
91
- }
92
- });
93
- }
94
- }
95
- const completionTimestamp = performance.now();
96
- writeSceneLog("SceneRenderProfiler", "Profile completed");
97
- writeSceneLog("", ` \u251C\u2500 Timestamp: ${completionTimestamp.toFixed(1)}ms`);
98
- writeSceneLog("", ` \u251C\u2500 Total time: ${(profileDuration + slowFramesTime).toFixed(1)}ms`);
99
- writeSceneLog("", ` \u251C\u2500 Slow frames: ${slowFramesTime}ms (${slowFrames.length} frames)`);
100
- writeSceneLog("", ` \u2514\u2500 Long frames: ${__privateGet(this, _longFramesTotalTime)}ms (${__privateGet(this, _longFramesCount)} frames)`);
101
- __privateGet(this, _longFrameDetector).stop();
102
- writeSceneLogStyled(
103
- "SceneRenderProfiler",
104
- `Stopped long frame detection - profile complete at ${completionTimestamp.toFixed(1)}ms`,
105
- "color: #00CC00; font-weight: bold;"
64
+ const slowFrameSummary = slowFrames.length > 0 ? `${slowFramesTime.toFixed(1)}ms slow frames[tail recording] (${slowFrames.length}) \u26A0\uFE0F` : `${slowFramesTime.toFixed(1)}ms slow frames[tail recording] (${slowFrames.length})`;
65
+ const longFrameSummary = __privateGet(this, _longFramesCount) > 0 ? `${__privateGet(this, _longFramesTotalTime).toFixed(1)}ms long frames[LoAF] (${__privateGet(this, _longFramesCount)}) \u26A0\uFE0F` : `${__privateGet(this, _longFramesTotalTime).toFixed(1)}ms long frames[LoAF] (${__privateGet(this, _longFramesCount)})`;
66
+ writePerformanceLog(
67
+ "SRP",
68
+ `[PROFILER] Complete: ${(profileDuration + slowFramesTime).toFixed(
69
+ 1
70
+ )}ms total | ${slowFrameSummary} | ${longFrameSummary}`
106
71
  );
72
+ __privateGet(this, _longFrameDetector).stop();
107
73
  __privateSet(this, _trailAnimationFrameId, null);
108
74
  const profileEndTs = profileStartTs + profileDuration + slowFramesTime;
109
75
  if (!__privateGet(this, _profileInProgress)) {
110
76
  return;
111
77
  }
112
- performance.measure(`DashboardInteraction ${__privateGet(this, _profileInProgress).origin}`, {
113
- start: profileStartTs,
114
- end: profileEndTs
115
- });
116
78
  const networkDuration = captureNetwork(profileStartTs, profileEndTs);
117
- if (((_d = this.queryController) == null ? void 0 : _d.state.onProfileComplete) && __privateGet(this, _profileInProgress)) {
118
- this.queryController.state.onProfileComplete({
119
- origin: __privateGet(this, _profileInProgress).origin,
120
- crumbs: __privateGet(this, _profileInProgress).crumbs,
79
+ if (__privateGet(this, _profileInProgress)) {
80
+ const dashboardData = {
81
+ operationId: __privateGet(this, _currentOperationId) || generateOperationId("dashboard-fallback"),
82
+ interactionType: __privateGet(this, _profileInProgress).origin,
83
+ timestamp: profileEndTs,
121
84
  duration: profileDuration + slowFramesTime,
122
85
  networkDuration,
123
- startTs: profileStartTs,
124
- endTs: profileEndTs,
125
86
  longFramesCount: __privateGet(this, _longFramesCount),
126
87
  longFramesTotalTime: __privateGet(this, _longFramesTotalTime),
127
- // @ts-ignore
128
- jsHeapSizeLimit: performance.memory ? performance.memory.jsHeapSizeLimit : 0,
129
- // @ts-ignore
130
- usedJSHeapSize: performance.memory ? performance.memory.usedJSHeapSize : 0,
131
- // @ts-ignore
132
- totalJSHeapSize: performance.memory ? performance.memory.totalJSHeapSize : 0
133
- });
88
+ metadata: this.metadata
89
+ };
90
+ const tracker = getScenePerformanceTracker();
91
+ tracker.notifyDashboardInteractionComplete(dashboardData);
134
92
  __privateSet(this, _profileInProgress, null);
135
93
  __privateSet(this, _trailAnimationFrameId, null);
136
94
  }
137
- if (window.__runs) {
138
- window.__runs += `${Date.now()}, ${profileDuration + slowFramesTime}
139
- `;
140
- } else {
141
- window.__runs = `${Date.now()}, ${profileDuration + slowFramesTime}
142
- `;
143
- }
144
95
  }
145
96
  };
146
97
  __privateSet(this, _longFrameDetector, new LongFrameDetector());
147
98
  this.setupVisibilityChangeHandler();
148
99
  __privateSet(this, _interactionInProgress, null);
100
+ if (panelProfilingConfig) {
101
+ this._panelProfilingManager = new PanelProfilingManager(panelProfilingConfig);
102
+ }
103
+ }
104
+ /** Set generic metadata for observer notifications */
105
+ setMetadata(metadata) {
106
+ this.metadata = { ...metadata };
149
107
  }
150
108
  setQueryController(queryController) {
151
109
  this.queryController = queryController;
152
110
  }
111
+ /** Attach panel profiling to a scene object */
112
+ attachPanelProfiling(sceneObject) {
113
+ var _a;
114
+ (_a = this._panelProfilingManager) == null ? void 0 : _a.attachToScene(sceneObject);
115
+ }
116
+ /** Attach profiler to a specific panel */
117
+ attachProfilerToPanel(panel) {
118
+ var _a;
119
+ writePerformanceLog("SRP", "Attaching profiler to panel", panel.state.key);
120
+ (_a = this._panelProfilingManager) == null ? void 0 : _a.attachProfilerToPanel(panel);
121
+ }
153
122
  setInteractionCompleteHandler(handler) {
154
123
  __privateSet(this, _onInteractionComplete, handler != null ? handler : null);
155
124
  }
@@ -159,7 +128,7 @@ class SceneRenderProfiler {
159
128
  }
160
129
  __privateSet(this, _visibilityChangeHandler, () => {
161
130
  if (document.hidden && __privateGet(this, _profileInProgress)) {
162
- writeSceneLog("SceneRenderProfiler", "Tab became inactive, cancelling profile");
131
+ writePerformanceLog("SRP", "Tab became inactive, cancelling profile");
163
132
  this.cancelProfile();
164
133
  }
165
134
  });
@@ -168,16 +137,18 @@ class SceneRenderProfiler {
168
137
  }
169
138
  }
170
139
  cleanup() {
140
+ var _a;
171
141
  if (__privateGet(this, _visibilityChangeHandler) && typeof document !== "undefined") {
172
142
  document.removeEventListener("visibilitychange", __privateGet(this, _visibilityChangeHandler));
173
143
  __privateSet(this, _visibilityChangeHandler, null);
174
144
  }
175
145
  __privateGet(this, _longFrameDetector).stop();
176
146
  this.cancelProfile();
147
+ (_a = this._panelProfilingManager) == null ? void 0 : _a.cleanup();
177
148
  }
178
149
  startProfile(name) {
179
150
  if (document.hidden) {
180
- writeSceneLog("SceneRenderProfiler", "Tab is inactive, skipping profile", name);
151
+ writePerformanceLog("SRP", "Tab is inactive, skipping profile", name);
181
152
  return;
182
153
  }
183
154
  if (__privateGet(this, _profileInProgress)) {
@@ -193,14 +164,14 @@ class SceneRenderProfiler {
193
164
  }
194
165
  startInteraction(interaction) {
195
166
  if (__privateGet(this, _interactionInProgress)) {
196
- writeSceneLog("profile", "Cancelled interaction:", __privateGet(this, _interactionInProgress));
167
+ writePerformanceLog("SRP", "Cancelled interaction:", __privateGet(this, _interactionInProgress));
197
168
  __privateSet(this, _interactionInProgress, null);
198
169
  }
199
170
  __privateSet(this, _interactionInProgress, {
200
171
  interaction,
201
172
  startTs: performance.now()
202
173
  });
203
- writeSceneLog("SceneRenderProfiler", "Started interaction:", interaction);
174
+ writePerformanceLog("SRP", "Started interaction:", interaction);
204
175
  }
205
176
  stopInteraction() {
206
177
  if (!__privateGet(this, _interactionInProgress)) {
@@ -209,11 +180,10 @@ class SceneRenderProfiler {
209
180
  const endTs = performance.now();
210
181
  const interactionDuration = endTs - __privateGet(this, _interactionInProgress).startTs;
211
182
  const networkDuration = captureNetwork(__privateGet(this, _interactionInProgress).startTs, endTs);
212
- writeSceneLog("SceneRenderProfiler", "Completed interaction:");
213
- writeSceneLog("", ` \u251C\u2500 Total time: ${interactionDuration.toFixed(1)}ms`);
214
- writeSceneLog("", ` \u251C\u2500 Network duration: ${networkDuration.toFixed(1)}ms`);
215
- writeSceneLog("", ` \u251C\u2500 StartTs: ${__privateGet(this, _interactionInProgress).startTs.toFixed(1)}ms`);
216
- writeSceneLog("", ` \u2514\u2500 EndTs: ${endTs.toFixed(1)}ms`);
183
+ writePerformanceLog(
184
+ "SRP",
185
+ `[INTERACTION] Complete: ${interactionDuration.toFixed(1)}ms total | ${networkDuration.toFixed(1)}ms network`
186
+ );
217
187
  if (__privateGet(this, _onInteractionComplete) && __privateGet(this, _profileInProgress)) {
218
188
  __privateGet(this, _onInteractionComplete).call(this, {
219
189
  origin: __privateGet(this, _interactionInProgress).interaction,
@@ -241,32 +211,24 @@ class SceneRenderProfiler {
241
211
  return (_b = (_a = __privateGet(this, _interactionInProgress)) == null ? void 0 : _a.interaction) != null ? _b : null;
242
212
  }
243
213
  /**
244
- * Starts a new profile for performance measurement.
245
- *
246
- * @param name - The origin/trigger of the profile (e.g., 'time_range_change', 'variable_value_changed')
247
- * @param force - Whether this is a "forced" profile (true) or "clean" profile (false)
248
- * - "forced": Started by canceling an existing profile that was recording trailing frames
249
- * This happens when a new user interaction occurs before the previous one
250
- * finished measuring its performance impact
251
- * - "clean": Started when no profile is currently active
214
+ * Start new performance profile
215
+ * @param name - Profile trigger (e.g., 'time_range_change')
216
+ * @param force - True if canceling existing profile, false if starting clean
252
217
  */
253
218
  _startNewProfile(name, force = false) {
254
- var _a;
219
+ const profileType = force ? "forced" : "clean";
220
+ writePerformanceLog("SRP", `[PROFILER] ${name} started (${profileType})`);
255
221
  __privateSet(this, _profileInProgress, { origin: name, crumbs: [] });
256
222
  __privateSet(this, _profileStartTs, performance.now());
257
223
  __privateSet(this, _longFramesCount, 0);
258
224
  __privateSet(this, _longFramesTotalTime, 0);
259
- if (typeof performance !== "undefined" && performance.mark) {
260
- const markName = `Dashboard Profile Start: ${name}`;
261
- performance.mark(markName);
262
- }
263
- writeSceneLogStyled(
264
- "SceneRenderProfiler",
265
- `Profile started[${force ? "forced" : "clean"}]`,
266
- "color: #FFCC00; font-weight: bold;"
267
- );
268
- writeSceneLog("", ` \u251C\u2500 Origin: ${((_a = __privateGet(this, _profileInProgress)) == null ? void 0 : _a.origin) || "unknown"}`);
269
- writeSceneLog("", ` \u2514\u2500 Timestamp: ${__privateGet(this, _profileStartTs).toFixed(1)}ms`);
225
+ __privateSet(this, _currentOperationId, generateOperationId("dashboard"));
226
+ getScenePerformanceTracker().notifyDashboardInteractionStart({
227
+ operationId: __privateGet(this, _currentOperationId),
228
+ interactionType: name,
229
+ timestamp: __privateGet(this, _profileStartTs),
230
+ metadata: this.metadata
231
+ });
270
232
  __privateGet(this, _longFrameDetector).start((event) => {
271
233
  if (!__privateGet(this, _profileInProgress) || !__privateGet(this, _profileStartTs)) {
272
234
  return;
@@ -285,12 +247,9 @@ class SceneRenderProfiler {
285
247
  }
286
248
  tryCompletingProfile() {
287
249
  var _a;
288
- if (!__privateGet(this, _profileInProgress)) {
289
- return;
290
- }
291
- writeSceneLog("SceneRenderProfiler", "Trying to complete profile", __privateGet(this, _profileInProgress));
250
+ writePerformanceLog("SRP", "Trying to complete profile", __privateGet(this, _profileInProgress));
292
251
  if (((_a = this.queryController) == null ? void 0 : _a.runningQueriesCount()) === 0 && __privateGet(this, _profileInProgress)) {
293
- writeSceneLog("SceneRenderProfiler", "All queries completed, starting tail measurement");
252
+ writePerformanceLog("SRP", "All queries completed, stopping profile");
294
253
  this.recordProfileTail(performance.now(), __privateGet(this, _profileStartTs));
295
254
  }
296
255
  }
@@ -301,20 +260,19 @@ class SceneRenderProfiler {
301
260
  if (__privateGet(this, _trailAnimationFrameId)) {
302
261
  cancelAnimationFrame(__privateGet(this, _trailAnimationFrameId));
303
262
  __privateSet(this, _trailAnimationFrameId, null);
304
- writeSceneLog("SceneRenderProfiler", "Cancelled recording frames, new profile started");
263
+ writePerformanceLog("SRP", "Cancelled recording frames, new profile started");
305
264
  }
306
265
  }
307
- // cancel profile
308
266
  cancelProfile() {
309
267
  if (__privateGet(this, _profileInProgress)) {
310
- writeSceneLog("SceneRenderProfiler", "Cancelling profile", __privateGet(this, _profileInProgress));
268
+ writePerformanceLog("SRP", "Cancelling profile", __privateGet(this, _profileInProgress));
311
269
  __privateSet(this, _profileInProgress, null);
312
270
  if (__privateGet(this, _trailAnimationFrameId)) {
313
271
  cancelAnimationFrame(__privateGet(this, _trailAnimationFrameId));
314
272
  __privateSet(this, _trailAnimationFrameId, null);
315
273
  }
316
274
  __privateGet(this, _longFrameDetector).stop();
317
- writeSceneLog("SceneRenderProfiler", "Stopped long frame detection - profile cancelled");
275
+ writePerformanceLog("SRP", "Stopped long frame detection - profile cancelled");
318
276
  __privateSet(this, _recordedTrailingSpans, []);
319
277
  __privateSet(this, _longFramesCount, 0);
320
278
  __privateSet(this, _longFramesTotalTime, 0);
@@ -322,7 +280,13 @@ class SceneRenderProfiler {
322
280
  }
323
281
  addCrumb(crumb) {
324
282
  if (__privateGet(this, _profileInProgress)) {
325
- writeSceneLog("SceneRenderProfiler", "Adding crumb:", crumb);
283
+ getScenePerformanceTracker().notifyDashboardInteractionMilestone({
284
+ operationId: generateOperationId("dashboard-milestone"),
285
+ interactionType: __privateGet(this, _profileInProgress).origin,
286
+ timestamp: performance.now(),
287
+ milestone: crumb,
288
+ metadata: this.metadata
289
+ });
326
290
  __privateGet(this, _profileInProgress).crumbs.push(crumb);
327
291
  }
328
292
  }
@@ -331,6 +295,7 @@ _profileInProgress = new WeakMap();
331
295
  _interactionInProgress = new WeakMap();
332
296
  _profileStartTs = new WeakMap();
333
297
  _trailAnimationFrameId = new WeakMap();
298
+ _currentOperationId = new WeakMap();
334
299
  _recordedTrailingSpans = new WeakMap();
335
300
  _longFrameDetector = new WeakMap();
336
301
  _longFramesCount = new WeakMap();
@@ -379,16 +344,6 @@ function calculateNetworkTime(requests) {
379
344
  totalNetworkTime += currentEnd - currentStart;
380
345
  return totalNetworkTime;
381
346
  }
382
- const REFRESH_INTERACTION = "refresh";
383
- const TIME_RANGE_CHANGE_INTERACTION = "time_range_change";
384
- const FILTER_REMOVED_INTERACTION = "filter_removed";
385
- const FILTER_CHANGED_INTERACTION = "filter_changed";
386
- const FILTER_RESTORED_INTERACTION = "filter_restored";
387
- const VARIABLE_VALUE_CHANGED_INTERACTION = "variable_value_changed";
388
- const SCOPES_CHANGED_INTERACTION = "scopes_changed";
389
- const ADHOC_KEYS_DROPDOWN_INTERACTION = "adhoc_keys_dropdown";
390
- const ADHOC_VALUES_DROPDOWN_INTERACTION = "adhoc_values_dropdown";
391
- const GROUPBY_DIMENSIONS_INTERACTION = "groupby_dimensions";
392
347
 
393
- export { ADHOC_KEYS_DROPDOWN_INTERACTION, ADHOC_VALUES_DROPDOWN_INTERACTION, FILTER_CHANGED_INTERACTION, FILTER_REMOVED_INTERACTION, FILTER_RESTORED_INTERACTION, GROUPBY_DIMENSIONS_INTERACTION, REFRESH_INTERACTION, SCOPES_CHANGED_INTERACTION, SceneRenderProfiler, TIME_RANGE_CHANGE_INTERACTION, VARIABLE_VALUE_CHANGED_INTERACTION, calculateNetworkTime, captureNetwork, processRecordedSpans };
348
+ export { SceneRenderProfiler, calculateNetworkTime, captureNetwork, processRecordedSpans };
394
349
  //# sourceMappingURL=SceneRenderProfiler.js.map