@grafana/scenes 6.29.2--canary.1204.16747434211.0 → 6.29.2--canary.1205.16747480830.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.
@@ -7,9 +7,10 @@ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot
7
7
  var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
8
8
  var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
9
9
  var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
10
- var _profileInProgress, _profileStartTs, _trailAnimationFrameId, _recordedTrailingSpans;
10
+ var _profileInProgress, _profileStartTs, _trailAnimationFrameId, _recordedTrailingSpans, _visibilityChangeHandler;
11
11
  const POST_STORM_WINDOW = 2e3;
12
12
  const SPAN_THRESHOLD = 30;
13
+ const TAB_INACTIVE_THRESHOLD = 1e3;
13
14
  class SceneRenderProfiler {
14
15
  constructor(queryController) {
15
16
  this.queryController = queryController;
@@ -19,10 +20,18 @@ class SceneRenderProfiler {
19
20
  // Will keep measured lengths trailing frames
20
21
  __privateAdd(this, _recordedTrailingSpans, []);
21
22
  this.lastFrameTime = 0;
23
+ __privateAdd(this, _visibilityChangeHandler, null);
22
24
  this.measureTrailingFrames = (measurementStartTs, lastFrameTime, profileStartTs) => {
23
25
  var _a;
24
26
  const currentFrameTime = performance.now();
25
27
  const frameLength = currentFrameTime - lastFrameTime;
28
+ if (frameLength > TAB_INACTIVE_THRESHOLD) {
29
+ writeSceneLog("SceneRenderProfiler", "Tab was inactive, cancelling profile measurement");
30
+ __privateSet(this, _recordedTrailingSpans, []);
31
+ __privateSet(this, _profileInProgress, null);
32
+ __privateSet(this, _trailAnimationFrameId, null);
33
+ return;
34
+ }
26
35
  __privateGet(this, _recordedTrailingSpans).push(frameLength);
27
36
  if (currentFrameTime - measurementStartTs < POST_STORM_WINDOW) {
28
37
  if (__privateGet(this, _profileInProgress)) {
@@ -49,12 +58,15 @@ class SceneRenderProfiler {
49
58
  );
50
59
  __privateSet(this, _trailAnimationFrameId, null);
51
60
  const profileEndTs = profileStartTs + profileDuration + slowFramesTime;
61
+ if (!__privateGet(this, _profileInProgress)) {
62
+ return;
63
+ }
52
64
  performance.measure(`DashboardInteraction ${__privateGet(this, _profileInProgress).origin}`, {
53
65
  start: profileStartTs,
54
66
  end: profileEndTs
55
67
  });
56
68
  const networkDuration = captureNetwork(profileStartTs, profileEndTs);
57
- if ((_a = this.queryController) == null ? void 0 : _a.state.onProfileComplete) {
69
+ if (((_a = this.queryController) == null ? void 0 : _a.state.onProfileComplete) && __privateGet(this, _profileInProgress)) {
58
70
  this.queryController.state.onProfileComplete({
59
71
  origin: __privateGet(this, _profileInProgress).origin,
60
72
  crumbs: __privateGet(this, _profileInProgress).crumbs,
@@ -81,10 +93,32 @@ class SceneRenderProfiler {
81
93
  }
82
94
  }
83
95
  };
96
+ this.setupVisibilityChangeHandler();
84
97
  }
85
98
  setQueryController(queryController) {
86
99
  this.queryController = queryController;
87
100
  }
101
+ setupVisibilityChangeHandler() {
102
+ if (__privateGet(this, _visibilityChangeHandler)) {
103
+ return;
104
+ }
105
+ __privateSet(this, _visibilityChangeHandler, () => {
106
+ if (document.hidden && __privateGet(this, _profileInProgress)) {
107
+ writeSceneLog("SceneRenderProfiler", "Tab became inactive, cancelling profile");
108
+ this.cancelProfile();
109
+ }
110
+ });
111
+ if (typeof document !== "undefined") {
112
+ document.addEventListener("visibilitychange", __privateGet(this, _visibilityChangeHandler));
113
+ }
114
+ }
115
+ cleanup() {
116
+ if (__privateGet(this, _visibilityChangeHandler) && typeof document !== "undefined") {
117
+ document.removeEventListener("visibilitychange", __privateGet(this, _visibilityChangeHandler));
118
+ __privateSet(this, _visibilityChangeHandler, null);
119
+ }
120
+ this.cancelProfile();
121
+ }
88
122
  startProfile(name) {
89
123
  if (__privateGet(this, _profileInProgress)) {
90
124
  this.addCrumb(name);
@@ -117,6 +151,17 @@ class SceneRenderProfiler {
117
151
  writeSceneLog("SceneRenderProfiler", "Cancelled recording frames, new profile started");
118
152
  }
119
153
  }
154
+ // cancel profile
155
+ cancelProfile() {
156
+ if (__privateGet(this, _profileInProgress)) {
157
+ writeSceneLog("SceneRenderProfiler", "Cancelling profile", __privateGet(this, _profileInProgress));
158
+ __privateSet(this, _profileInProgress, null);
159
+ if (__privateGet(this, _trailAnimationFrameId)) {
160
+ cancelAnimationFrame(__privateGet(this, _trailAnimationFrameId));
161
+ __privateSet(this, _trailAnimationFrameId, null);
162
+ }
163
+ }
164
+ }
120
165
  addCrumb(crumb) {
121
166
  if (__privateGet(this, _profileInProgress)) {
122
167
  writeSceneLog("SceneRenderProfiler", "Adding crumb:", crumb);
@@ -128,6 +173,7 @@ _profileInProgress = new WeakMap();
128
173
  _profileStartTs = new WeakMap();
129
174
  _trailAnimationFrameId = new WeakMap();
130
175
  _recordedTrailingSpans = new WeakMap();
176
+ _visibilityChangeHandler = new WeakMap();
131
177
  function processRecordedSpans(spans) {
132
178
  for (let i = spans.length - 1; i >= 0; i--) {
133
179
  if (spans[i] > SPAN_THRESHOLD) {
@@ -1 +1 @@
1
- {"version":3,"file":"SceneRenderProfiler.js","sources":["../../../src/behaviors/SceneRenderProfiler.ts"],"sourcesContent":["import { writeSceneLog } from '../utils/writeSceneLog';\nimport { SceneQueryControllerLike } from './types';\n\nconst POST_STORM_WINDOW = 2000; // Time after last query to observe slow frames\nconst SPAN_THRESHOLD = 30; // Frames longer than this will be considered slow\n\nexport class SceneRenderProfiler {\n #profileInProgress: {\n // Profile origin, i.e. scene refresh picker\n origin: string;\n crumbs: string[];\n } | null = null;\n\n #profileStartTs: number | null = null;\n #trailAnimationFrameId: number | null = null;\n\n // Will keep measured lengths trailing frames\n #recordedTrailingSpans: number[] = [];\n\n lastFrameTime = 0;\n\n public constructor(private queryController?: SceneQueryControllerLike) {}\n\n public setQueryController(queryController: SceneQueryControllerLike) {\n this.queryController = queryController;\n }\n\n public startProfile(name: string) {\n if (this.#profileInProgress) {\n this.addCrumb(name);\n } else {\n this.#profileInProgress = { origin: name, crumbs: [] };\n this.#profileStartTs = performance.now();\n writeSceneLog('SceneRenderProfiler', 'Profile started:', this.#profileInProgress, this.#profileStartTs);\n }\n }\n\n private recordProfileTail(measurementStartTime: number, profileStartTs: number) {\n this.#trailAnimationFrameId = requestAnimationFrame(() =>\n this.measureTrailingFrames(measurementStartTime, measurementStartTime, profileStartTs)\n );\n }\n\n private measureTrailingFrames = (measurementStartTs: number, lastFrameTime: number, profileStartTs: number) => {\n const currentFrameTime = performance.now();\n const frameLength = currentFrameTime - lastFrameTime;\n this.#recordedTrailingSpans.push(frameLength);\n\n if (currentFrameTime - measurementStartTs! < POST_STORM_WINDOW) {\n if (this.#profileInProgress) {\n this.#trailAnimationFrameId = requestAnimationFrame(() =>\n this.measureTrailingFrames(measurementStartTs, currentFrameTime, profileStartTs)\n );\n }\n } else {\n const slowFrames = processRecordedSpans(this.#recordedTrailingSpans);\n const slowFramesTime = slowFrames.reduce((acc, val) => acc + val, 0);\n\n writeSceneLog(\n this.constructor.name,\n 'Profile tail recorded, slow frames duration:',\n slowFramesTime,\n slowFrames,\n this.#profileInProgress\n );\n\n this.#recordedTrailingSpans = [];\n\n const profileDuration = measurementStartTs - profileStartTs;\n\n writeSceneLog(\n this.constructor.name,\n 'Stoped recording, total measured time (network included):',\n profileDuration + slowFramesTime\n );\n this.#trailAnimationFrameId = null;\n\n const profileEndTs = profileStartTs + profileDuration + slowFramesTime;\n performance.measure(`DashboardInteraction ${this.#profileInProgress!.origin}`, {\n start: profileStartTs,\n end: profileEndTs,\n });\n\n const networkDuration = captureNetwork(profileStartTs, profileEndTs);\n\n if (this.queryController?.state.onProfileComplete) {\n this.queryController.state.onProfileComplete({\n origin: this.#profileInProgress!.origin,\n crumbs: this.#profileInProgress!.crumbs,\n duration: profileDuration + slowFramesTime,\n networkDuration,\n startTs: profileStartTs,\n endTs: profileEndTs,\n // @ts-ignore\n jsHeapSizeLimit: performance.memory ? performance.memory.jsHeapSizeLimit : 0,\n // @ts-ignore\n usedJSHeapSize: performance.memory ? performance.memory.usedJSHeapSize : 0,\n // @ts-ignore\n totalJSHeapSize: performance.memory ? performance.memory.totalJSHeapSize : 0,\n });\n\n this.#profileInProgress = null;\n this.#trailAnimationFrameId = null;\n }\n // @ts-ignore\n if (window.__runs) {\n // @ts-ignore\n window.__runs += `${Date.now()}, ${profileDuration + slowFramesTime}\\n`;\n } else {\n // @ts-ignore\n window.__runs = `${Date.now()}, ${profileDuration + slowFramesTime}\\n`;\n }\n }\n };\n\n public tryCompletingProfile() {\n writeSceneLog('SceneRenderProfiler', 'Trying to complete profile', this.#profileInProgress);\n if (this.queryController?.runningQueriesCount() === 0 && this.#profileInProgress) {\n writeSceneLog('SceneRenderProfiler', 'All queries completed, stopping profile');\n this.recordProfileTail(performance.now(), this.#profileStartTs!);\n }\n }\n\n public isTailRecording() {\n return Boolean(this.#trailAnimationFrameId);\n }\n public cancelTailRecording() {\n if (this.#trailAnimationFrameId) {\n cancelAnimationFrame(this.#trailAnimationFrameId);\n this.#trailAnimationFrameId = null;\n writeSceneLog('SceneRenderProfiler', 'Cancelled recording frames, new profile started');\n }\n }\n\n public addCrumb(crumb: string) {\n if (this.#profileInProgress) {\n writeSceneLog('SceneRenderProfiler', 'Adding crumb:', crumb);\n this.#profileInProgress.crumbs.push(crumb);\n }\n }\n}\n\nexport function processRecordedSpans(spans: number[]) {\n // identify last span in spans that's bigger than SPAN_THRESHOLD\n for (let i = spans.length - 1; i >= 0; i--) {\n if (spans[i] > SPAN_THRESHOLD) {\n return spans.slice(0, i + 1);\n }\n }\n return [spans[0]];\n}\n\nfunction captureNetwork(startTs: number, endTs: number) {\n const entries = performance.getEntriesByType('resource') as PerformanceResourceTiming[];\n performance.clearResourceTimings();\n const networkEntries = entries.filter((entry) => entry.startTime >= startTs && entry.startTime <= endTs);\n for (const entry of networkEntries) {\n performance.measure('Network entry ' + entry.name, {\n start: entry.startTime,\n end: entry.responseEnd,\n });\n }\n\n return calculateNetworkTime(networkEntries);\n}\n\n// Will calculate total time spent on Network\nexport function calculateNetworkTime(requests: PerformanceResourceTiming[]): number {\n if (requests.length === 0) {\n return 0;\n }\n\n // Step 1: Sort the requests by startTs\n requests.sort((a, b) => a.startTime - b.startTime);\n\n // Step 2: Initialize variables\n let totalNetworkTime = 0;\n let currentStart = requests[0].startTime;\n let currentEnd = requests[0].responseEnd;\n\n // Step 3: Iterate through the sorted list and merge overlapping intervals\n for (let i = 1; i < requests.length; i++) {\n if (requests[i].startTime <= currentEnd) {\n // Overlapping intervals, merge them\n currentEnd = Math.max(currentEnd, requests[i].responseEnd);\n } else {\n // Non-overlapping interval, add the duration to total time\n totalNetworkTime += currentEnd - currentStart;\n\n // Update current interval\n currentStart = requests[i].startTime;\n currentEnd = requests[i].responseEnd;\n }\n }\n\n // Step 4: Add the last interval\n totalNetworkTime += currentEnd - currentStart;\n\n return totalNetworkTime;\n}\n\nexport const REFRESH_INTERACTION = 'refresh';\nexport const TIME_RANGE_CHANGE_INTERACTION = 'time_range_change';\nexport const FILTER_ADDED_INTERACTION = 'filter_added';\nexport const FILTER_REMOVED_INTERACTION = 'filter_removed';\nexport const FILTER_CHANGED_INTERACTION = 'filter_changed';\nexport const FILTER_RESTORED_INTERACTION = 'filter_restored';\nexport const VARIABLE_VALUE_CHANGED_INTERACTION = 'variable_value_changed';\nexport const SCOPES_CHANGED_INTERACTION = 'scopes_changed';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SceneRenderProfiler.js","sources":["../../../src/behaviors/SceneRenderProfiler.ts"],"sourcesContent":["import { writeSceneLog } from '../utils/writeSceneLog';\nimport { SceneQueryControllerLike } from './types';\n\nconst POST_STORM_WINDOW = 2000; // Time after last query to observe slow frames\nconst SPAN_THRESHOLD = 30; // Frames longer than this will be considered slow\nconst TAB_INACTIVE_THRESHOLD = 1000; // Tab inactive threshold in ms\n\nexport class SceneRenderProfiler {\n #profileInProgress: {\n // Profile origin, i.e. scene refresh picker\n origin: string;\n crumbs: string[];\n } | null = null;\n\n #profileStartTs: number | null = null;\n #trailAnimationFrameId: number | null = null;\n\n // Will keep measured lengths trailing frames\n #recordedTrailingSpans: number[] = [];\n\n lastFrameTime = 0;\n #visibilityChangeHandler: (() => void) | null = null;\n\n public constructor(private queryController?: SceneQueryControllerLike) {\n this.setupVisibilityChangeHandler();\n }\n\n public setQueryController(queryController: SceneQueryControllerLike) {\n this.queryController = queryController;\n }\n\n private setupVisibilityChangeHandler() {\n // Ensure event listener is only added once\n if (this.#visibilityChangeHandler) {\n return;\n }\n\n // Handle tab switching with Page Visibility API\n this.#visibilityChangeHandler = () => {\n if (document.hidden && this.#profileInProgress) {\n writeSceneLog('SceneRenderProfiler', 'Tab became inactive, cancelling profile');\n this.cancelProfile();\n }\n };\n\n if (typeof document !== 'undefined') {\n document.addEventListener('visibilitychange', this.#visibilityChangeHandler);\n }\n }\n\n public cleanup() {\n // Remove event listener to prevent memory leaks\n if (this.#visibilityChangeHandler && typeof document !== 'undefined') {\n document.removeEventListener('visibilitychange', this.#visibilityChangeHandler);\n this.#visibilityChangeHandler = null;\n }\n\n // Cancel any ongoing profiling\n this.cancelProfile();\n }\n\n public startProfile(name: string) {\n if (this.#profileInProgress) {\n this.addCrumb(name);\n } else {\n this.#profileInProgress = { origin: name, crumbs: [] };\n this.#profileStartTs = performance.now();\n writeSceneLog('SceneRenderProfiler', 'Profile started:', this.#profileInProgress, this.#profileStartTs);\n }\n }\n\n private recordProfileTail(measurementStartTime: number, profileStartTs: number) {\n this.#trailAnimationFrameId = requestAnimationFrame(() =>\n this.measureTrailingFrames(measurementStartTime, measurementStartTime, profileStartTs)\n );\n }\n\n private measureTrailingFrames = (measurementStartTs: number, lastFrameTime: number, profileStartTs: number) => {\n const currentFrameTime = performance.now();\n const frameLength = currentFrameTime - lastFrameTime;\n\n // Fallback: Detect if tab was inactive (frame longer than reasonable threshold)\n // This serves as backup to Page Visibility API in case the event wasn't triggered\n if (frameLength > TAB_INACTIVE_THRESHOLD) {\n writeSceneLog('SceneRenderProfiler', 'Tab was inactive, cancelling profile measurement');\n // Reset and cancel profiling due to tab inactivity\n this.#recordedTrailingSpans = [];\n this.#profileInProgress = null;\n this.#trailAnimationFrameId = null;\n return;\n }\n\n this.#recordedTrailingSpans.push(frameLength);\n\n if (currentFrameTime - measurementStartTs! < POST_STORM_WINDOW) {\n if (this.#profileInProgress) {\n this.#trailAnimationFrameId = requestAnimationFrame(() =>\n this.measureTrailingFrames(measurementStartTs, currentFrameTime, profileStartTs)\n );\n }\n } else {\n const slowFrames = processRecordedSpans(this.#recordedTrailingSpans);\n const slowFramesTime = slowFrames.reduce((acc, val) => acc + val, 0);\n\n writeSceneLog(\n this.constructor.name,\n 'Profile tail recorded, slow frames duration:',\n slowFramesTime,\n slowFrames,\n this.#profileInProgress\n );\n\n this.#recordedTrailingSpans = [];\n\n const profileDuration = measurementStartTs - profileStartTs;\n\n writeSceneLog(\n this.constructor.name,\n 'Stoped recording, total measured time (network included):',\n profileDuration + slowFramesTime\n );\n this.#trailAnimationFrameId = null;\n\n const profileEndTs = profileStartTs + profileDuration + slowFramesTime;\n\n // Guard against race condition where profile might be cancelled during execution\n if (!this.#profileInProgress) {\n return;\n }\n\n performance.measure(`DashboardInteraction ${this.#profileInProgress.origin}`, {\n start: profileStartTs,\n end: profileEndTs,\n });\n\n const networkDuration = captureNetwork(profileStartTs, profileEndTs);\n\n if (this.queryController?.state.onProfileComplete && this.#profileInProgress) {\n this.queryController.state.onProfileComplete({\n origin: this.#profileInProgress.origin,\n crumbs: this.#profileInProgress.crumbs,\n duration: profileDuration + slowFramesTime,\n networkDuration,\n startTs: profileStartTs,\n endTs: profileEndTs,\n // @ts-ignore\n jsHeapSizeLimit: performance.memory ? performance.memory.jsHeapSizeLimit : 0,\n // @ts-ignore\n usedJSHeapSize: performance.memory ? performance.memory.usedJSHeapSize : 0,\n // @ts-ignore\n totalJSHeapSize: performance.memory ? performance.memory.totalJSHeapSize : 0,\n });\n\n this.#profileInProgress = null;\n this.#trailAnimationFrameId = null;\n }\n // @ts-ignore\n if (window.__runs) {\n // @ts-ignore\n window.__runs += `${Date.now()}, ${profileDuration + slowFramesTime}\\n`;\n } else {\n // @ts-ignore\n window.__runs = `${Date.now()}, ${profileDuration + slowFramesTime}\\n`;\n }\n }\n };\n\n public tryCompletingProfile() {\n writeSceneLog('SceneRenderProfiler', 'Trying to complete profile', this.#profileInProgress);\n if (this.queryController?.runningQueriesCount() === 0 && this.#profileInProgress) {\n writeSceneLog('SceneRenderProfiler', 'All queries completed, stopping profile');\n this.recordProfileTail(performance.now(), this.#profileStartTs!);\n }\n }\n\n public isTailRecording() {\n return Boolean(this.#trailAnimationFrameId);\n }\n\n public cancelTailRecording() {\n if (this.#trailAnimationFrameId) {\n cancelAnimationFrame(this.#trailAnimationFrameId);\n this.#trailAnimationFrameId = null;\n writeSceneLog('SceneRenderProfiler', 'Cancelled recording frames, new profile started');\n }\n }\n\n // cancel profile\n public cancelProfile() {\n if (this.#profileInProgress) {\n writeSceneLog('SceneRenderProfiler', 'Cancelling profile', this.#profileInProgress);\n this.#profileInProgress = null;\n // Cancel any pending animation frame to prevent accessing null profileInProgress\n if (this.#trailAnimationFrameId) {\n cancelAnimationFrame(this.#trailAnimationFrameId);\n this.#trailAnimationFrameId = null;\n }\n }\n }\n\n public addCrumb(crumb: string) {\n if (this.#profileInProgress) {\n writeSceneLog('SceneRenderProfiler', 'Adding crumb:', crumb);\n this.#profileInProgress.crumbs.push(crumb);\n }\n }\n}\n\nexport function processRecordedSpans(spans: number[]) {\n // identify last span in spans that's bigger than SPAN_THRESHOLD\n for (let i = spans.length - 1; i >= 0; i--) {\n if (spans[i] > SPAN_THRESHOLD) {\n return spans.slice(0, i + 1);\n }\n }\n return [spans[0]];\n}\n\nfunction captureNetwork(startTs: number, endTs: number) {\n const entries = performance.getEntriesByType('resource') as PerformanceResourceTiming[];\n performance.clearResourceTimings();\n const networkEntries = entries.filter((entry) => entry.startTime >= startTs && entry.startTime <= endTs);\n for (const entry of networkEntries) {\n performance.measure('Network entry ' + entry.name, {\n start: entry.startTime,\n end: entry.responseEnd,\n });\n }\n\n return calculateNetworkTime(networkEntries);\n}\n\n// Will calculate total time spent on Network\nexport function calculateNetworkTime(requests: PerformanceResourceTiming[]): number {\n if (requests.length === 0) {\n return 0;\n }\n\n // Step 1: Sort the requests by startTs\n requests.sort((a, b) => a.startTime - b.startTime);\n\n // Step 2: Initialize variables\n let totalNetworkTime = 0;\n let currentStart = requests[0].startTime;\n let currentEnd = requests[0].responseEnd;\n\n // Step 3: Iterate through the sorted list and merge overlapping intervals\n for (let i = 1; i < requests.length; i++) {\n if (requests[i].startTime <= currentEnd) {\n // Overlapping intervals, merge them\n currentEnd = Math.max(currentEnd, requests[i].responseEnd);\n } else {\n // Non-overlapping interval, add the duration to total time\n totalNetworkTime += currentEnd - currentStart;\n\n // Update current interval\n currentStart = requests[i].startTime;\n currentEnd = requests[i].responseEnd;\n }\n }\n\n // Step 4: Add the last interval\n totalNetworkTime += currentEnd - currentStart;\n\n return totalNetworkTime;\n}\n\nexport const REFRESH_INTERACTION = 'refresh';\nexport const TIME_RANGE_CHANGE_INTERACTION = 'time_range_change';\nexport const FILTER_ADDED_INTERACTION = 'filter_added';\nexport const FILTER_REMOVED_INTERACTION = 'filter_removed';\nexport const FILTER_CHANGED_INTERACTION = 'filter_changed';\nexport const FILTER_RESTORED_INTERACTION = 'filter_restored';\nexport const VARIABLE_VALUE_CHANGED_INTERACTION = 'variable_value_changed';\nexport const SCOPES_CHANGED_INTERACTION = 'scopes_changed';\n"],"names":[],"mappings":";;;;;;;;;AAAA,IAAA,kBAAA,EAAA,eAAA,EAAA,sBAAA,EAAA,sBAAA,EAAA,wBAAA;AAGA,MAAM,iBAAoB,GAAA,GAAA;AAC1B,MAAM,cAAiB,GAAA,EAAA;AACvB,MAAM,sBAAyB,GAAA,GAAA;AAExB,MAAM,mBAAoB,CAAA;AAAA,EAgBxB,YAAoB,eAA4C,EAAA;AAA5C,IAAA,IAAA,CAAA,eAAA,GAAA,eAAA;AAf3B,IAIW,YAAA,CAAA,IAAA,EAAA,kBAAA,EAAA,IAAA,CAAA;AAEX,IAAiC,YAAA,CAAA,IAAA,EAAA,eAAA,EAAA,IAAA,CAAA;AACjC,IAAwC,YAAA,CAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,CAAA;AAGxC;AAAA,IAAA,YAAA,CAAA,IAAA,EAAA,sBAAA,EAAmC,EAAC,CAAA;AAEpC,IAAgB,IAAA,CAAA,aAAA,GAAA,CAAA;AAChB,IAAgD,YAAA,CAAA,IAAA,EAAA,wBAAA,EAAA,IAAA,CAAA;AAwDhD,IAAA,IAAA,CAAQ,qBAAwB,GAAA,CAAC,kBAA4B,EAAA,aAAA,EAAuB,cAA2B,KAAA;AA7EjH,MAAA,IAAA,EAAA;AA8EI,MAAM,MAAA,gBAAA,GAAmB,YAAY,GAAI,EAAA;AACzC,MAAA,MAAM,cAAc,gBAAmB,GAAA,aAAA;AAIvC,MAAA,IAAI,cAAc,sBAAwB,EAAA;AACxC,QAAA,aAAA,CAAc,uBAAuB,kDAAkD,CAAA;AAEvF,QAAA,YAAA,CAAA,IAAA,EAAK,wBAAyB,EAAC,CAAA;AAC/B,QAAA,YAAA,CAAA,IAAA,EAAK,kBAAqB,EAAA,IAAA,CAAA;AAC1B,QAAA,YAAA,CAAA,IAAA,EAAK,sBAAyB,EAAA,IAAA,CAAA;AAC9B,QAAA;AAAA;AAGF,MAAK,YAAA,CAAA,IAAA,EAAA,sBAAA,CAAA,CAAuB,KAAK,WAAW,CAAA;AAE5C,MAAI,IAAA,gBAAA,GAAmB,qBAAsB,iBAAmB,EAAA;AAC9D,QAAA,IAAI,mBAAK,kBAAoB,CAAA,EAAA;AAC3B,UAAA,YAAA,CAAA,IAAA,EAAK,sBAAyB,EAAA,qBAAA;AAAA,YAAsB,MAClD,IAAA,CAAK,qBAAsB,CAAA,kBAAA,EAAoB,kBAAkB,cAAc;AAAA,WACjF,CAAA;AAAA;AACF,OACK,MAAA;AACL,QAAM,MAAA,UAAA,GAAa,oBAAqB,CAAA,YAAA,CAAA,IAAA,EAAK,sBAAsB,CAAA,CAAA;AACnE,QAAM,MAAA,cAAA,GAAiB,WAAW,MAAO,CAAA,CAAC,KAAK,GAAQ,KAAA,GAAA,GAAM,KAAK,CAAC,CAAA;AAEnE,QAAA,aAAA;AAAA,UACE,KAAK,WAAY,CAAA,IAAA;AAAA,UACjB,8CAAA;AAAA,UACA,cAAA;AAAA,UACA,UAAA;AAAA,UACA,YAAK,CAAA,IAAA,EAAA,kBAAA;AAAA,SACP;AAEA,QAAA,YAAA,CAAA,IAAA,EAAK,wBAAyB,EAAC,CAAA;AAE/B,QAAA,MAAM,kBAAkB,kBAAqB,GAAA,cAAA;AAE7C,QAAA,aAAA;AAAA,UACE,KAAK,WAAY,CAAA,IAAA;AAAA,UACjB,2DAAA;AAAA,UACA,eAAkB,GAAA;AAAA,SACpB;AACA,QAAA,YAAA,CAAA,IAAA,EAAK,sBAAyB,EAAA,IAAA,CAAA;AAE9B,QAAM,MAAA,YAAA,GAAe,iBAAiB,eAAkB,GAAA,cAAA;AAGxD,QAAI,IAAA,CAAC,mBAAK,kBAAoB,CAAA,EAAA;AAC5B,UAAA;AAAA;AAGF,QAAA,WAAA,CAAY,OAAQ,CAAA,CAAA,qBAAA,EAAwB,YAAK,CAAA,IAAA,EAAA,kBAAA,CAAA,CAAmB,MAAM,CAAI,CAAA,EAAA;AAAA,UAC5E,KAAO,EAAA,cAAA;AAAA,UACP,GAAK,EAAA;AAAA,SACN,CAAA;AAED,QAAM,MAAA,eAAA,GAAkB,cAAe,CAAA,cAAA,EAAgB,YAAY,CAAA;AAEnE,QAAA,IAAA,CAAA,CAAI,UAAK,eAAL,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAsB,KAAM,CAAA,iBAAA,KAAqB,mBAAK,kBAAoB,CAAA,EAAA;AAC5E,UAAK,IAAA,CAAA,eAAA,CAAgB,MAAM,iBAAkB,CAAA;AAAA,YAC3C,MAAA,EAAQ,mBAAK,kBAAmB,CAAA,CAAA,MAAA;AAAA,YAChC,MAAA,EAAQ,mBAAK,kBAAmB,CAAA,CAAA,MAAA;AAAA,YAChC,UAAU,eAAkB,GAAA,cAAA;AAAA,YAC5B,eAAA;AAAA,YACA,OAAS,EAAA,cAAA;AAAA,YACT,KAAO,EAAA,YAAA;AAAA;AAAA,YAEP,eAAiB,EAAA,WAAA,CAAY,MAAS,GAAA,WAAA,CAAY,OAAO,eAAkB,GAAA,CAAA;AAAA;AAAA,YAE3E,cAAgB,EAAA,WAAA,CAAY,MAAS,GAAA,WAAA,CAAY,OAAO,cAAiB,GAAA,CAAA;AAAA;AAAA,YAEzE,eAAiB,EAAA,WAAA,CAAY,MAAS,GAAA,WAAA,CAAY,OAAO,eAAkB,GAAA;AAAA,WAC5E,CAAA;AAED,UAAA,YAAA,CAAA,IAAA,EAAK,kBAAqB,EAAA,IAAA,CAAA;AAC1B,UAAA,YAAA,CAAA,IAAA,EAAK,sBAAyB,EAAA,IAAA,CAAA;AAAA;AAGhC,QAAA,IAAI,OAAO,MAAQ,EAAA;AAEjB,UAAA,MAAA,CAAO,UAAU,CAAG,EAAA,IAAA,CAAK,KAAK,CAAA,EAAA,EAAK,kBAAkB,cAAc;AAAA,CAAA;AAAA,SAC9D,MAAA;AAEL,UAAA,MAAA,CAAO,SAAS,CAAG,EAAA,IAAA,CAAK,KAAK,CAAA,EAAA,EAAK,kBAAkB,cAAc;AAAA,CAAA;AAAA;AACpE;AACF,KACF;AA7IE,IAAA,IAAA,CAAK,4BAA6B,EAAA;AAAA;AACpC,EAEO,mBAAmB,eAA2C,EAAA;AACnE,IAAA,IAAA,CAAK,eAAkB,GAAA,eAAA;AAAA;AACzB,EAEQ,4BAA+B,GAAA;AAErC,IAAA,IAAI,mBAAK,wBAA0B,CAAA,EAAA;AACjC,MAAA;AAAA;AAIF,IAAA,YAAA,CAAA,IAAA,EAAK,0BAA2B,MAAM;AACpC,MAAI,IAAA,QAAA,CAAS,MAAU,IAAA,YAAA,CAAA,IAAA,EAAK,kBAAoB,CAAA,EAAA;AAC9C,QAAA,aAAA,CAAc,uBAAuB,yCAAyC,CAAA;AAC9E,QAAA,IAAA,CAAK,aAAc,EAAA;AAAA;AACrB,KACF,CAAA;AAEA,IAAI,IAAA,OAAO,aAAa,WAAa,EAAA;AACnC,MAAS,QAAA,CAAA,gBAAA,CAAiB,kBAAoB,EAAA,YAAA,CAAA,IAAA,EAAK,wBAAwB,CAAA,CAAA;AAAA;AAC7E;AACF,EAEO,OAAU,GAAA;AAEf,IAAA,IAAI,YAAK,CAAA,IAAA,EAAA,wBAAA,CAAA,IAA4B,OAAO,QAAA,KAAa,WAAa,EAAA;AACpE,MAAS,QAAA,CAAA,mBAAA,CAAoB,kBAAoB,EAAA,YAAA,CAAA,IAAA,EAAK,wBAAwB,CAAA,CAAA;AAC9E,MAAA,YAAA,CAAA,IAAA,EAAK,wBAA2B,EAAA,IAAA,CAAA;AAAA;AAIlC,IAAA,IAAA,CAAK,aAAc,EAAA;AAAA;AACrB,EAEO,aAAa,IAAc,EAAA;AAChC,IAAA,IAAI,mBAAK,kBAAoB,CAAA,EAAA;AAC3B,MAAA,IAAA,CAAK,SAAS,IAAI,CAAA;AAAA,KACb,MAAA;AACL,MAAA,YAAA,CAAA,IAAA,EAAK,oBAAqB,EAAE,MAAA,EAAQ,IAAM,EAAA,MAAA,EAAQ,EAAG,EAAA,CAAA;AACrD,MAAK,YAAA,CAAA,IAAA,EAAA,eAAA,EAAkB,YAAY,GAAI,EAAA,CAAA;AACvC,MAAA,aAAA,CAAc,qBAAuB,EAAA,kBAAA,EAAoB,YAAK,CAAA,IAAA,EAAA,kBAAA,CAAA,EAAoB,mBAAK,eAAe,CAAA,CAAA;AAAA;AACxG;AACF,EAEQ,iBAAA,CAAkB,sBAA8B,cAAwB,EAAA;AAC9E,IAAA,YAAA,CAAA,IAAA,EAAK,sBAAyB,EAAA,qBAAA;AAAA,MAAsB,MAClD,IAAA,CAAK,qBAAsB,CAAA,oBAAA,EAAsB,sBAAsB,cAAc;AAAA,KACvF,CAAA;AAAA;AACF,EA4FO,oBAAuB,GAAA;AAvKhC,IAAA,IAAA,EAAA;AAwKI,IAAc,aAAA,CAAA,qBAAA,EAAuB,4BAA8B,EAAA,YAAA,CAAA,IAAA,EAAK,kBAAkB,CAAA,CAAA;AAC1F,IAAA,IAAA,CAAA,CAAI,UAAK,eAAL,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAsB,mBAA0B,EAAA,MAAA,CAAA,IAAK,mBAAK,kBAAoB,CAAA,EAAA;AAChF,MAAA,aAAA,CAAc,uBAAuB,yCAAyC,CAAA;AAC9E,MAAA,IAAA,CAAK,iBAAkB,CAAA,WAAA,CAAY,GAAI,EAAA,EAAG,mBAAK,eAAgB,CAAA,CAAA;AAAA;AACjE;AACF,EAEO,eAAkB,GAAA;AACvB,IAAO,OAAA,OAAA,CAAQ,mBAAK,sBAAsB,CAAA,CAAA;AAAA;AAC5C,EAEO,mBAAsB,GAAA;AAC3B,IAAA,IAAI,mBAAK,sBAAwB,CAAA,EAAA;AAC/B,MAAA,oBAAA,CAAqB,mBAAK,sBAAsB,CAAA,CAAA;AAChD,MAAA,YAAA,CAAA,IAAA,EAAK,sBAAyB,EAAA,IAAA,CAAA;AAC9B,MAAA,aAAA,CAAc,uBAAuB,iDAAiD,CAAA;AAAA;AACxF;AACF;AAAA,EAGO,aAAgB,GAAA;AACrB,IAAA,IAAI,mBAAK,kBAAoB,CAAA,EAAA;AAC3B,MAAc,aAAA,CAAA,qBAAA,EAAuB,oBAAsB,EAAA,YAAA,CAAA,IAAA,EAAK,kBAAkB,CAAA,CAAA;AAClF,MAAA,YAAA,CAAA,IAAA,EAAK,kBAAqB,EAAA,IAAA,CAAA;AAE1B,MAAA,IAAI,mBAAK,sBAAwB,CAAA,EAAA;AAC/B,QAAA,oBAAA,CAAqB,mBAAK,sBAAsB,CAAA,CAAA;AAChD,QAAA,YAAA,CAAA,IAAA,EAAK,sBAAyB,EAAA,IAAA,CAAA;AAAA;AAChC;AACF;AACF,EAEO,SAAS,KAAe,EAAA;AAC7B,IAAA,IAAI,mBAAK,kBAAoB,CAAA,EAAA;AAC3B,MAAc,aAAA,CAAA,qBAAA,EAAuB,iBAAiB,KAAK,CAAA;AAC3D,MAAK,YAAA,CAAA,IAAA,EAAA,kBAAA,CAAA,CAAmB,MAAO,CAAA,IAAA,CAAK,KAAK,CAAA;AAAA;AAC3C;AAEJ;AAtME,kBAAA,GAAA,IAAA,OAAA,EAAA;AAMA,eAAA,GAAA,IAAA,OAAA,EAAA;AACA,sBAAA,GAAA,IAAA,OAAA,EAAA;AAGA,sBAAA,GAAA,IAAA,OAAA,EAAA;AAGA,wBAAA,GAAA,IAAA,OAAA,EAAA;AA2LK,SAAS,qBAAqB,KAAiB,EAAA;AAEpD,EAAA,KAAA,IAAS,IAAI,KAAM,CAAA,MAAA,GAAS,CAAG,EAAA,CAAA,IAAK,GAAG,CAAK,EAAA,EAAA;AAC1C,IAAI,IAAA,KAAA,CAAM,CAAC,CAAA,GAAI,cAAgB,EAAA;AAC7B,MAAA,OAAO,KAAM,CAAA,KAAA,CAAM,CAAG,EAAA,CAAA,GAAI,CAAC,CAAA;AAAA;AAC7B;AAEF,EAAO,OAAA,CAAC,KAAM,CAAA,CAAC,CAAC,CAAA;AAClB;AAEA,SAAS,cAAA,CAAe,SAAiB,KAAe,EAAA;AACtD,EAAM,MAAA,OAAA,GAAU,WAAY,CAAA,gBAAA,CAAiB,UAAU,CAAA;AACvD,EAAA,WAAA,CAAY,oBAAqB,EAAA;AACjC,EAAM,MAAA,cAAA,GAAiB,OAAQ,CAAA,MAAA,CAAO,CAAC,KAAA,KAAU,MAAM,SAAa,IAAA,OAAA,IAAW,KAAM,CAAA,SAAA,IAAa,KAAK,CAAA;AACvG,EAAA,KAAA,MAAW,SAAS,cAAgB,EAAA;AAClC,IAAY,WAAA,CAAA,OAAA,CAAQ,gBAAmB,GAAA,KAAA,CAAM,IAAM,EAAA;AAAA,MACjD,OAAO,KAAM,CAAA,SAAA;AAAA,MACb,KAAK,KAAM,CAAA;AAAA,KACZ,CAAA;AAAA;AAGH,EAAA,OAAO,qBAAqB,cAAc,CAAA;AAC5C;AAGO,SAAS,qBAAqB,QAA+C,EAAA;AAClF,EAAI,IAAA,QAAA,CAAS,WAAW,CAAG,EAAA;AACzB,IAAO,OAAA,CAAA;AAAA;AAIT,EAAA,QAAA,CAAS,KAAK,CAAC,CAAA,EAAG,MAAM,CAAE,CAAA,SAAA,GAAY,EAAE,SAAS,CAAA;AAGjD,EAAA,IAAI,gBAAmB,GAAA,CAAA;AACvB,EAAI,IAAA,YAAA,GAAe,QAAS,CAAA,CAAC,CAAE,CAAA,SAAA;AAC/B,EAAI,IAAA,UAAA,GAAa,QAAS,CAAA,CAAC,CAAE,CAAA,WAAA;AAG7B,EAAA,KAAA,IAAS,CAAI,GAAA,CAAA,EAAG,CAAI,GAAA,QAAA,CAAS,QAAQ,CAAK,EAAA,EAAA;AACxC,IAAA,IAAI,QAAS,CAAA,CAAC,CAAE,CAAA,SAAA,IAAa,UAAY,EAAA;AAEvC,MAAA,UAAA,GAAa,KAAK,GAAI,CAAA,UAAA,EAAY,QAAS,CAAA,CAAC,EAAE,WAAW,CAAA;AAAA,KACpD,MAAA;AAEL,MAAA,gBAAA,IAAoB,UAAa,GAAA,YAAA;AAGjC,MAAe,YAAA,GAAA,QAAA,CAAS,CAAC,CAAE,CAAA,SAAA;AAC3B,MAAa,UAAA,GAAA,QAAA,CAAS,CAAC,CAAE,CAAA,WAAA;AAAA;AAC3B;AAIF,EAAA,gBAAA,IAAoB,UAAa,GAAA,YAAA;AAEjC,EAAO,OAAA,gBAAA;AACT;AAEO,MAAM,mBAAsB,GAAA;AAC5B,MAAM,6BAAgC,GAAA;AAEtC,MAAM,0BAA6B,GAAA;AACnC,MAAM,0BAA6B,GAAA;AACnC,MAAM,2BAA8B,GAAA;AACpC,MAAM,kCAAqC,GAAA;AAC3C,MAAM,0BAA6B,GAAA;;;;"}
@@ -266,9 +266,9 @@ const formatRegistry = new Registry(() => {
266
266
  id: VariableFormatID.Text,
267
267
  name: "Text",
268
268
  description: "Format variables in their text representation. Example in multi-variable scenario A + B + C.",
269
- formatter: (value, _args, variable, fieldPath) => {
269
+ formatter: (value, _args, variable) => {
270
270
  if (variable.getValueText) {
271
- return variable.getValueText(fieldPath);
271
+ return variable.getValueText();
272
272
  }
273
273
  return String(value);
274
274
  }
@@ -1 +1 @@
1
- {"version":3,"file":"formatRegistry.js","sources":["../../../../src/variables/interpolation/formatRegistry.ts"],"sourcesContent":["import { t } from '@grafana/i18n';\nimport { isArray, map, replace } from 'lodash';\n\nimport { dateTime, Registry, RegistryItem, textUtil, escapeRegex, urlUtil } from '@grafana/data';\nimport { VariableType, VariableFormatID } from '@grafana/schema';\n\nimport { VariableValue, VariableValueSingle } from '../types';\nimport { ALL_VARIABLE_VALUE } from '../constants';\nimport { SceneObjectUrlSyncHandler } from '../../core/types';\n\nexport interface FormatRegistryItem extends RegistryItem {\n formatter(value: VariableValue, args: string[], variable: FormatVariable, fieldPath?: string): string;\n}\n\n/**\n * Slimmed down version of the SceneVariable interface so that it only contains what the formatters actually use.\n * This is useful as we have some implementations of this interface that does not need to be full scene objects.\n * For example ScopedVarsVariable and LegacyVariableWrapper.\n */\nexport interface FormatVariable {\n state: {\n name: string;\n type: VariableType | string;\n isMulti?: boolean;\n includeAll?: boolean;\n };\n\n getValue(fieldPath?: string): VariableValue | undefined | null;\n getValueText?(fieldPath?: string): string;\n urlSync?: SceneObjectUrlSyncHandler;\n}\n\nexport const formatRegistry = new Registry<FormatRegistryItem>(() => {\n const formats: FormatRegistryItem[] = [\n {\n id: VariableFormatID.Lucene,\n name: 'Lucene',\n description: 'Values are lucene escaped and multi-valued variables generate an OR expression',\n formatter: (value) => {\n if (typeof value === 'string') {\n return luceneEscape(value);\n }\n\n if (Array.isArray(value)) {\n if (value.length === 0) {\n return '__empty__';\n }\n const quotedValues = map(value, (val: string) => {\n return '\"' + luceneEscape(val) + '\"';\n });\n return '(' + quotedValues.join(' OR ') + ')';\n } else {\n return luceneEscape(`${value}`);\n }\n },\n },\n {\n id: VariableFormatID.Raw,\n name: 'raw',\n description: t(\n 'grafana-scenes.variables.format-registry.formats.description.keep-value-as-is',\n 'Keep value as is'\n ),\n formatter: (value) => String(value),\n },\n {\n id: VariableFormatID.Regex,\n name: 'Regex',\n description: 'Values are regex escaped and multi-valued variables generate a (<value>|<value>) expression',\n formatter: (value) => {\n if (typeof value === 'string') {\n return escapeRegex(value);\n }\n\n if (Array.isArray(value)) {\n const escapedValues = value.map((item) => {\n if (typeof item === 'string') {\n return escapeRegex(item);\n } else {\n return escapeRegex(String(item));\n }\n });\n\n if (escapedValues.length === 1) {\n return escapedValues[0];\n }\n\n return '(' + escapedValues.join('|') + ')';\n }\n\n return escapeRegex(`${value}`);\n },\n },\n {\n id: VariableFormatID.Pipe,\n name: 'Pipe',\n description: t(\n 'grafana-scenes.variables.format-registry.formats.description.values-are-separated-by-character',\n 'Values are separated by | character'\n ),\n formatter: (value) => {\n if (typeof value === 'string') {\n return value;\n }\n\n if (Array.isArray(value)) {\n return value.join('|');\n }\n\n return `${value}`;\n },\n },\n {\n id: VariableFormatID.Distributed,\n name: 'Distributed',\n description: t(\n 'grafana-scenes.variables.format-registry.formats.description.multiple-values-are-formatted-like-variablevalue',\n 'Multiple values are formatted like variable=value'\n ),\n formatter: (value, args, variable) => {\n if (typeof value === 'string') {\n return value;\n }\n\n if (Array.isArray(value)) {\n value = map(value, (val: string, index: number) => {\n if (index !== 0) {\n return variable.state.name + '=' + val;\n } else {\n return val;\n }\n });\n\n return value.join(',');\n }\n\n return `${value}`;\n },\n },\n {\n id: VariableFormatID.CSV,\n name: 'Csv',\n description: t(\n 'grafana-scenes.variables.format-registry.formats.description.commaseparated-values',\n 'Comma-separated values'\n ),\n formatter: (value) => {\n if (typeof value === 'string') {\n return value;\n }\n\n if (isArray(value)) {\n return value.join(',');\n }\n\n return String(value);\n },\n },\n {\n id: VariableFormatID.HTML,\n name: 'HTML',\n description: t(\n 'grafana-scenes.variables.format-registry.formats.description.html-escaping-of-values',\n 'HTML escaping of values'\n ),\n formatter: (value) => {\n if (typeof value === 'string') {\n return textUtil.escapeHtml(value);\n }\n\n if (isArray(value)) {\n return textUtil.escapeHtml(value.join(', '));\n }\n\n return textUtil.escapeHtml(String(value));\n },\n },\n {\n id: VariableFormatID.JSON,\n name: 'JSON',\n description: t(\n 'grafana-scenes.variables.format-registry.formats.description.json-stringify-value',\n 'JSON stringify value'\n ),\n formatter: (value) => {\n if (typeof value === 'string') {\n return value;\n }\n return JSON.stringify(value);\n },\n },\n {\n id: VariableFormatID.PercentEncode,\n name: 'Percent encode',\n description: t(\n 'grafana-scenes.variables.format-registry.formats.description.useful-for-url-escaping-values',\n 'Useful for URL escaping values'\n ),\n formatter: (value) => {\n // like glob, but url escaped\n if (isArray(value)) {\n return encodeURIComponentStrict('{' + value.join(',') + '}');\n }\n\n return encodeURIComponentStrict(value);\n },\n },\n {\n id: VariableFormatID.SingleQuote,\n name: 'Single quote',\n description: t(\n 'grafana-scenes.variables.format-registry.formats.description.single-quoted-values',\n 'Single quoted values'\n ),\n formatter: (value) => {\n // escape single quotes with backslash\n const regExp = new RegExp(`'`, 'g');\n\n if (isArray(value)) {\n return map(value, (v: string) => `'${replace(v, regExp, `\\\\'`)}'`).join(',');\n }\n\n let strVal = typeof value === 'string' ? value : String(value);\n return `'${replace(strVal, regExp, `\\\\'`)}'`;\n },\n },\n {\n id: VariableFormatID.DoubleQuote,\n name: 'Double quote',\n description: t(\n 'grafana-scenes.variables.format-registry.formats.description.double-quoted-values',\n 'Double quoted values'\n ),\n formatter: (value) => {\n // escape double quotes with backslash\n const regExp = new RegExp('\"', 'g');\n if (isArray(value)) {\n return map(value, (v: string) => `\"${replace(v, regExp, '\\\\\"')}\"`).join(',');\n }\n\n let strVal = typeof value === 'string' ? value : String(value);\n return `\"${replace(strVal, regExp, '\\\\\"')}\"`;\n },\n },\n {\n id: VariableFormatID.SQLString,\n name: 'SQL string',\n description: 'SQL string quoting and commas for use in IN statements and other scenarios',\n formatter: sqlStringFormatter,\n },\n {\n id: 'join', // join not yet available in depended @grafana/schema version\n name: 'Join',\n description: 'Join values with a comma',\n formatter: (value, args) => {\n if (isArray(value)) {\n const separator = args[0] ?? ',';\n return value.join(separator);\n }\n return String(value);\n },\n },\n {\n id: VariableFormatID.Date,\n name: 'Date',\n description: t(\n 'grafana-scenes.variables.format-registry.formats.description.format-date-in-different-ways',\n 'Format date in different ways'\n ),\n formatter: (value, args) => {\n let nrValue = NaN;\n\n if (typeof value === 'number') {\n nrValue = value;\n } else if (typeof value === 'string') {\n nrValue = parseInt(value, 10);\n }\n\n if (isNaN(nrValue)) {\n return 'NaN';\n }\n\n const arg = args[0] ?? 'iso';\n switch (arg) {\n case 'ms':\n return String(value);\n case 'seconds':\n return `${Math.round(nrValue! / 1000)}`;\n case 'iso':\n return dateTime(nrValue).toISOString();\n default:\n if ((args || []).length > 1) {\n return dateTime(nrValue).format(args.join(':'));\n }\n return dateTime(nrValue).format(arg);\n }\n },\n },\n {\n id: VariableFormatID.Glob,\n name: 'Glob',\n description: t(\n 'grafana-scenes.variables.format-registry.formats.description.format-multivalued-variables-using-syntax-example',\n 'Format multi-valued variables using glob syntax, example {value1,value2}'\n ),\n formatter: (value) => {\n if (isArray(value) && value.length > 1) {\n return '{' + value.join(',') + '}';\n }\n return String(value);\n },\n },\n {\n id: VariableFormatID.Text,\n name: 'Text',\n description: 'Format variables in their text representation. Example in multi-variable scenario A + B + C.',\n formatter: (value, _args, variable, fieldPath) => {\n if (variable.getValueText) {\n return variable.getValueText(fieldPath);\n }\n\n return String(value);\n },\n },\n {\n id: VariableFormatID.QueryParam,\n name: 'Query parameter',\n description:\n 'Format variables as URL parameters. Example in multi-variable scenario A + B + C => var-foo=A&var-foo=B&var-foo=C.',\n formatter: (value, _args, variable) => {\n if (variable.urlSync) {\n const urlParam = variable.urlSync.getUrlState();\n return urlUtil.toUrlParams(urlParam);\n }\n\n if (Array.isArray(value)) {\n return value.map((v) => formatQueryParameter(variable.state.name, v)).join('&');\n }\n\n return formatQueryParameter(variable.state.name, value);\n },\n },\n {\n id: 'customqueryparam',\n name: 'Custom query parameter',\n description:\n 'Format variables as URL parameters with custom name and value prefix. Example in multi-variable scenario A + B + C => p-foo=x-A&p-foo=x-B&p-foo=x-C.',\n formatter: (value, args, variable) => {\n const name = encodeURIComponentStrict(args[0] || variable.state.name);\n const valuePrefix = encodeURIComponentStrict(args[1] || '');\n\n if (Array.isArray(value)) {\n return value.map((v) => customFormatQueryParameter(name, v, valuePrefix)).join('&');\n }\n\n return customFormatQueryParameter(name, value, valuePrefix);\n },\n },\n {\n id: VariableFormatID.UriEncode,\n name: 'Percent encode as URI',\n description: t(\n 'grafana-scenes.variables.format-registry.formats.description.useful-escaping-values-taking-syntax-characters',\n 'Useful for URL escaping values, taking into URI syntax characters'\n ),\n formatter: (value: VariableValue) => {\n if (isArray(value)) {\n return encodeURIStrict('{' + value.join(',') + '}');\n }\n\n return encodeURIStrict(value);\n },\n },\n ];\n\n return formats;\n});\n\nfunction luceneEscape(value: string) {\n if (isNaN(+value) === false) {\n return value;\n }\n\n return value.replace(/([\\!\\*\\+\\-\\=<>\\s\\&\\|\\(\\)\\[\\]\\{\\}\\^\\~\\?\\:\\\\/\"])/g, '\\\\$1');\n}\n\n/**\n * encode string according to RFC 3986; in contrast to encodeURIComponent()\n * also the sub-delims \"!\", \"'\", \"(\", \")\" and \"*\" are encoded;\n * unicode handling uses UTF-8 as in ECMA-262.\n */\nfunction encodeURIComponentStrict(str: VariableValueSingle) {\n if (typeof str === 'object') {\n str = String(str);\n }\n\n return replaceSpecialCharactersToASCII(encodeURIComponent(str));\n}\n\nconst encodeURIStrict = (str: VariableValueSingle): string => replaceSpecialCharactersToASCII(encodeURI(String(str)));\n\nconst replaceSpecialCharactersToASCII = (value: string): string =>\n value.replace(/[!'()*]/g, (c) => {\n return '%' + c.charCodeAt(0).toString(16).toUpperCase();\n });\n\nfunction formatQueryParameter(name: string, value: VariableValueSingle): string {\n return `var-${name}=${encodeURIComponentStrict(value)}`;\n}\n\nfunction customFormatQueryParameter(name: string, value: VariableValueSingle, valuePrefix = ''): string {\n return `${name}=${valuePrefix}${encodeURIComponentStrict(value)}`;\n}\n\nexport function isAllValue(value: VariableValueSingle) {\n return value === ALL_VARIABLE_VALUE || (Array.isArray(value) && value[0] === ALL_VARIABLE_VALUE);\n}\n\nconst SQL_ESCAPE_MAP: Record<string, string> = {\n \"'\": \"''\",\n '\"': '\\\\\"',\n};\n\nfunction sqlStringFormatter(value: VariableValue) {\n // escape single quotes by pairing them\n const regExp = new RegExp(`'|\"`, 'g');\n\n if (isArray(value)) {\n return map(value, (v: string) => `'${replace(v, regExp, (match) => SQL_ESCAPE_MAP[match] ?? '')}'`).join(',');\n }\n\n let strVal = typeof value === 'string' ? value : String(value);\n return `'${replace(strVal, regExp, (match) => SQL_ESCAPE_MAP[match] ?? '')}'`;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"formatRegistry.js","sources":["../../../../src/variables/interpolation/formatRegistry.ts"],"sourcesContent":["import { t } from '@grafana/i18n';\nimport { isArray, map, replace } from 'lodash';\n\nimport { dateTime, Registry, RegistryItem, textUtil, escapeRegex, urlUtil } from '@grafana/data';\nimport { VariableType, VariableFormatID } from '@grafana/schema';\n\nimport { VariableValue, VariableValueSingle } from '../types';\nimport { ALL_VARIABLE_VALUE } from '../constants';\nimport { SceneObjectUrlSyncHandler } from '../../core/types';\n\nexport interface FormatRegistryItem extends RegistryItem {\n formatter(value: VariableValue, args: string[], variable: FormatVariable): string;\n}\n\n/**\n * Slimmed down version of the SceneVariable interface so that it only contains what the formatters actually use.\n * This is useful as we have some implementations of this interface that does not need to be full scene objects.\n * For example ScopedVarsVariable and LegacyVariableWrapper.\n */\nexport interface FormatVariable {\n state: {\n name: string;\n type: VariableType | string;\n isMulti?: boolean;\n includeAll?: boolean;\n };\n\n getValue(fieldPath?: string): VariableValue | undefined | null;\n getValueText?(fieldPath?: string): string;\n urlSync?: SceneObjectUrlSyncHandler;\n}\n\nexport const formatRegistry = new Registry<FormatRegistryItem>(() => {\n const formats: FormatRegistryItem[] = [\n {\n id: VariableFormatID.Lucene,\n name: 'Lucene',\n description: 'Values are lucene escaped and multi-valued variables generate an OR expression',\n formatter: (value) => {\n if (typeof value === 'string') {\n return luceneEscape(value);\n }\n\n if (Array.isArray(value)) {\n if (value.length === 0) {\n return '__empty__';\n }\n const quotedValues = map(value, (val: string) => {\n return '\"' + luceneEscape(val) + '\"';\n });\n return '(' + quotedValues.join(' OR ') + ')';\n } else {\n return luceneEscape(`${value}`);\n }\n },\n },\n {\n id: VariableFormatID.Raw,\n name: 'raw',\n description: t(\n 'grafana-scenes.variables.format-registry.formats.description.keep-value-as-is',\n 'Keep value as is'\n ),\n formatter: (value) => String(value),\n },\n {\n id: VariableFormatID.Regex,\n name: 'Regex',\n description: 'Values are regex escaped and multi-valued variables generate a (<value>|<value>) expression',\n formatter: (value) => {\n if (typeof value === 'string') {\n return escapeRegex(value);\n }\n\n if (Array.isArray(value)) {\n const escapedValues = value.map((item) => {\n if (typeof item === 'string') {\n return escapeRegex(item);\n } else {\n return escapeRegex(String(item));\n }\n });\n\n if (escapedValues.length === 1) {\n return escapedValues[0];\n }\n\n return '(' + escapedValues.join('|') + ')';\n }\n\n return escapeRegex(`${value}`);\n },\n },\n {\n id: VariableFormatID.Pipe,\n name: 'Pipe',\n description: t(\n 'grafana-scenes.variables.format-registry.formats.description.values-are-separated-by-character',\n 'Values are separated by | character'\n ),\n formatter: (value) => {\n if (typeof value === 'string') {\n return value;\n }\n\n if (Array.isArray(value)) {\n return value.join('|');\n }\n\n return `${value}`;\n },\n },\n {\n id: VariableFormatID.Distributed,\n name: 'Distributed',\n description: t(\n 'grafana-scenes.variables.format-registry.formats.description.multiple-values-are-formatted-like-variablevalue',\n 'Multiple values are formatted like variable=value'\n ),\n formatter: (value, args, variable) => {\n if (typeof value === 'string') {\n return value;\n }\n\n if (Array.isArray(value)) {\n value = map(value, (val: string, index: number) => {\n if (index !== 0) {\n return variable.state.name + '=' + val;\n } else {\n return val;\n }\n });\n\n return value.join(',');\n }\n\n return `${value}`;\n },\n },\n {\n id: VariableFormatID.CSV,\n name: 'Csv',\n description: t(\n 'grafana-scenes.variables.format-registry.formats.description.commaseparated-values',\n 'Comma-separated values'\n ),\n formatter: (value) => {\n if (typeof value === 'string') {\n return value;\n }\n\n if (isArray(value)) {\n return value.join(',');\n }\n\n return String(value);\n },\n },\n {\n id: VariableFormatID.HTML,\n name: 'HTML',\n description: t(\n 'grafana-scenes.variables.format-registry.formats.description.html-escaping-of-values',\n 'HTML escaping of values'\n ),\n formatter: (value) => {\n if (typeof value === 'string') {\n return textUtil.escapeHtml(value);\n }\n\n if (isArray(value)) {\n return textUtil.escapeHtml(value.join(', '));\n }\n\n return textUtil.escapeHtml(String(value));\n },\n },\n {\n id: VariableFormatID.JSON,\n name: 'JSON',\n description: t(\n 'grafana-scenes.variables.format-registry.formats.description.json-stringify-value',\n 'JSON stringify value'\n ),\n formatter: (value) => {\n if (typeof value === 'string') {\n return value;\n }\n return JSON.stringify(value);\n },\n },\n {\n id: VariableFormatID.PercentEncode,\n name: 'Percent encode',\n description: t(\n 'grafana-scenes.variables.format-registry.formats.description.useful-for-url-escaping-values',\n 'Useful for URL escaping values'\n ),\n formatter: (value) => {\n // like glob, but url escaped\n if (isArray(value)) {\n return encodeURIComponentStrict('{' + value.join(',') + '}');\n }\n\n return encodeURIComponentStrict(value);\n },\n },\n {\n id: VariableFormatID.SingleQuote,\n name: 'Single quote',\n description: t(\n 'grafana-scenes.variables.format-registry.formats.description.single-quoted-values',\n 'Single quoted values'\n ),\n formatter: (value) => {\n // escape single quotes with backslash\n const regExp = new RegExp(`'`, 'g');\n\n if (isArray(value)) {\n return map(value, (v: string) => `'${replace(v, regExp, `\\\\'`)}'`).join(',');\n }\n\n let strVal = typeof value === 'string' ? value : String(value);\n return `'${replace(strVal, regExp, `\\\\'`)}'`;\n },\n },\n {\n id: VariableFormatID.DoubleQuote,\n name: 'Double quote',\n description: t(\n 'grafana-scenes.variables.format-registry.formats.description.double-quoted-values',\n 'Double quoted values'\n ),\n formatter: (value) => {\n // escape double quotes with backslash\n const regExp = new RegExp('\"', 'g');\n if (isArray(value)) {\n return map(value, (v: string) => `\"${replace(v, regExp, '\\\\\"')}\"`).join(',');\n }\n\n let strVal = typeof value === 'string' ? value : String(value);\n return `\"${replace(strVal, regExp, '\\\\\"')}\"`;\n },\n },\n {\n id: VariableFormatID.SQLString,\n name: 'SQL string',\n description: 'SQL string quoting and commas for use in IN statements and other scenarios',\n formatter: sqlStringFormatter,\n },\n {\n id: 'join', // join not yet available in depended @grafana/schema version\n name: 'Join',\n description: 'Join values with a comma',\n formatter: (value, args) => {\n if (isArray(value)) {\n const separator = args[0] ?? ',';\n return value.join(separator);\n }\n return String(value);\n },\n },\n {\n id: VariableFormatID.Date,\n name: 'Date',\n description: t(\n 'grafana-scenes.variables.format-registry.formats.description.format-date-in-different-ways',\n 'Format date in different ways'\n ),\n formatter: (value, args) => {\n let nrValue = NaN;\n\n if (typeof value === 'number') {\n nrValue = value;\n } else if (typeof value === 'string') {\n nrValue = parseInt(value, 10);\n }\n\n if (isNaN(nrValue)) {\n return 'NaN';\n }\n\n const arg = args[0] ?? 'iso';\n switch (arg) {\n case 'ms':\n return String(value);\n case 'seconds':\n return `${Math.round(nrValue! / 1000)}`;\n case 'iso':\n return dateTime(nrValue).toISOString();\n default:\n if ((args || []).length > 1) {\n return dateTime(nrValue).format(args.join(':'));\n }\n return dateTime(nrValue).format(arg);\n }\n },\n },\n {\n id: VariableFormatID.Glob,\n name: 'Glob',\n description: t(\n 'grafana-scenes.variables.format-registry.formats.description.format-multivalued-variables-using-syntax-example',\n 'Format multi-valued variables using glob syntax, example {value1,value2}'\n ),\n formatter: (value) => {\n if (isArray(value) && value.length > 1) {\n return '{' + value.join(',') + '}';\n }\n return String(value);\n },\n },\n {\n id: VariableFormatID.Text,\n name: 'Text',\n description: 'Format variables in their text representation. Example in multi-variable scenario A + B + C.',\n formatter: (value, _args, variable) => {\n if (variable.getValueText) {\n return variable.getValueText();\n }\n\n return String(value);\n },\n },\n {\n id: VariableFormatID.QueryParam,\n name: 'Query parameter',\n description:\n 'Format variables as URL parameters. Example in multi-variable scenario A + B + C => var-foo=A&var-foo=B&var-foo=C.',\n formatter: (value, _args, variable) => {\n if (variable.urlSync) {\n const urlParam = variable.urlSync.getUrlState();\n return urlUtil.toUrlParams(urlParam);\n }\n\n if (Array.isArray(value)) {\n return value.map((v) => formatQueryParameter(variable.state.name, v)).join('&');\n }\n\n return formatQueryParameter(variable.state.name, value);\n },\n },\n {\n id: 'customqueryparam',\n name: 'Custom query parameter',\n description:\n 'Format variables as URL parameters with custom name and value prefix. Example in multi-variable scenario A + B + C => p-foo=x-A&p-foo=x-B&p-foo=x-C.',\n formatter: (value, args, variable) => {\n const name = encodeURIComponentStrict(args[0] || variable.state.name);\n const valuePrefix = encodeURIComponentStrict(args[1] || '');\n\n if (Array.isArray(value)) {\n return value.map((v) => customFormatQueryParameter(name, v, valuePrefix)).join('&');\n }\n\n return customFormatQueryParameter(name, value, valuePrefix);\n },\n },\n {\n id: VariableFormatID.UriEncode,\n name: 'Percent encode as URI',\n description: t(\n 'grafana-scenes.variables.format-registry.formats.description.useful-escaping-values-taking-syntax-characters',\n 'Useful for URL escaping values, taking into URI syntax characters'\n ),\n formatter: (value: VariableValue) => {\n if (isArray(value)) {\n return encodeURIStrict('{' + value.join(',') + '}');\n }\n\n return encodeURIStrict(value);\n },\n },\n ];\n\n return formats;\n});\n\nfunction luceneEscape(value: string) {\n if (isNaN(+value) === false) {\n return value;\n }\n\n return value.replace(/([\\!\\*\\+\\-\\=<>\\s\\&\\|\\(\\)\\[\\]\\{\\}\\^\\~\\?\\:\\\\/\"])/g, '\\\\$1');\n}\n\n/**\n * encode string according to RFC 3986; in contrast to encodeURIComponent()\n * also the sub-delims \"!\", \"'\", \"(\", \")\" and \"*\" are encoded;\n * unicode handling uses UTF-8 as in ECMA-262.\n */\nfunction encodeURIComponentStrict(str: VariableValueSingle) {\n if (typeof str === 'object') {\n str = String(str);\n }\n\n return replaceSpecialCharactersToASCII(encodeURIComponent(str));\n}\n\nconst encodeURIStrict = (str: VariableValueSingle): string => replaceSpecialCharactersToASCII(encodeURI(String(str)));\n\nconst replaceSpecialCharactersToASCII = (value: string): string =>\n value.replace(/[!'()*]/g, (c) => {\n return '%' + c.charCodeAt(0).toString(16).toUpperCase();\n });\n\nfunction formatQueryParameter(name: string, value: VariableValueSingle): string {\n return `var-${name}=${encodeURIComponentStrict(value)}`;\n}\n\nfunction customFormatQueryParameter(name: string, value: VariableValueSingle, valuePrefix = ''): string {\n return `${name}=${valuePrefix}${encodeURIComponentStrict(value)}`;\n}\n\nexport function isAllValue(value: VariableValueSingle) {\n return value === ALL_VARIABLE_VALUE || (Array.isArray(value) && value[0] === ALL_VARIABLE_VALUE);\n}\n\nconst SQL_ESCAPE_MAP: Record<string, string> = {\n \"'\": \"''\",\n '\"': '\\\\\"',\n};\n\nfunction sqlStringFormatter(value: VariableValue) {\n // escape single quotes by pairing them\n const regExp = new RegExp(`'|\"`, 'g');\n\n if (isArray(value)) {\n return map(value, (v: string) => `'${replace(v, regExp, (match) => SQL_ESCAPE_MAP[match] ?? '')}'`).join(',');\n }\n\n let strVal = typeof value === 'string' ? value : String(value);\n return `'${replace(strVal, regExp, (match) => SQL_ESCAPE_MAP[match] ?? '')}'`;\n}\n"],"names":[],"mappings":"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"}
@@ -21,7 +21,7 @@ function sceneInterpolator(sceneObject, target, scopedVars, format, interpolatio
21
21
  }
22
22
  return match;
23
23
  }
24
- const value = formatValue(sceneObject, variable, variable.getValue(fieldPath), fmt, fieldPath);
24
+ const value = formatValue(sceneObject, variable, variable.getValue(fieldPath), fmt);
25
25
  if (interpolations) {
26
26
  interpolations.push({ match, variableName, fieldPath, format: fmt, value, found: value !== match });
27
27
  }
@@ -45,7 +45,7 @@ function lookupFormatVariable(name, match, scopedVars, sceneObject) {
45
45
  }
46
46
  return null;
47
47
  }
48
- function formatValue(context, variable, value, formatNameOrFn, fieldPath) {
48
+ function formatValue(context, variable, value, formatNameOrFn) {
49
49
  if (value === null || value === void 0) {
50
50
  return "";
51
51
  }
@@ -80,7 +80,7 @@ function formatValue(context, variable, value, formatNameOrFn, fieldPath) {
80
80
  console.error(`Variable format ${formatNameOrFn} not found. Using glob format as fallback.`);
81
81
  formatter = formatRegistry.get(VariableFormatID.Glob);
82
82
  }
83
- return formatter.formatter(value, args, variable, fieldPath);
83
+ return formatter.formatter(value, args, variable);
84
84
  }
85
85
 
86
86
  export { sceneInterpolator };
@@ -1 +1 @@
1
- {"version":3,"file":"sceneInterpolator.js","sources":["../../../../src/variables/interpolation/sceneInterpolator.ts"],"sourcesContent":["import { ScopedVars } from '@grafana/data';\nimport { VariableInterpolation } from '@grafana/runtime';\nimport { VariableType, VariableFormatID } from '@grafana/schema';\n\nimport { SceneObject } from '../../core/types';\nimport { InterpolationFormatParameter, isCustomVariableValue, VariableValue } from '../types';\n\nimport { getSceneVariableForScopedVar } from './ScopedVarsVariable';\nimport { formatRegistry, FormatVariable } from './formatRegistry';\nimport { VARIABLE_REGEX } from '../constants';\nimport { lookupVariable } from '../lookupVariable';\nimport { macrosIndex } from '../macros';\n\n/**\n * This function will try to parse and replace any variable expression found in the target string. The sceneObject will be used as the source of variables. It will\n * use the scene graph and walk up the parent tree until it finds the closest variable.\n *\n * ScopedVars should not really be needed much in the new scene architecture as they can be added to the local scene node instead of passed in interpolate function.\n * It is supported here for backward compatibility and some edge cases where adding scoped vars to local scene node is not practical.\n */\nexport function sceneInterpolator(\n sceneObject: SceneObject,\n target: string | undefined | null,\n scopedVars?: ScopedVars,\n format?: InterpolationFormatParameter,\n interpolations?: VariableInterpolation[]\n): string {\n if (!target || typeof target !== 'string') {\n return target ?? '';\n }\n\n VARIABLE_REGEX.lastIndex = 0;\n\n return target.replace(VARIABLE_REGEX, (match, var1, var2, fmt2, var3, fieldPath, fmt3) => {\n const variableName = var1 || var2 || var3;\n const fmt = fmt2 || fmt3 || format;\n const variable = lookupFormatVariable(variableName, match, scopedVars, sceneObject);\n\n if (!variable) {\n if (interpolations) {\n // Set `value` equal to `match` as documented in the `VariableInterpolation` interface.\n interpolations.push({ match, variableName, fieldPath, format: fmt, value: match, found: false });\n }\n return match;\n }\n\n const value = formatValue(sceneObject, variable, variable.getValue(fieldPath), fmt, fieldPath);\n\n if (interpolations) {\n interpolations.push({ match, variableName, fieldPath, format: fmt, value, found: value !== match });\n }\n\n return value;\n });\n}\n\nfunction lookupFormatVariable(\n name: string,\n match: string,\n scopedVars: ScopedVars | undefined,\n sceneObject: SceneObject\n): FormatVariable | null {\n if (scopedVars && scopedVars.hasOwnProperty(name)) {\n const scopedVar = scopedVars[name];\n\n if (scopedVar) {\n return getSceneVariableForScopedVar(name, scopedVar);\n }\n }\n\n const variable = lookupVariable(name, sceneObject);\n if (variable) {\n return variable;\n }\n\n const Macro = macrosIndex.get(name);\n if (Macro) {\n return new Macro(name, sceneObject, match, scopedVars);\n }\n\n return null;\n}\n\nfunction formatValue(\n context: SceneObject,\n variable: FormatVariable,\n value: VariableValue | undefined | null,\n formatNameOrFn?: InterpolationFormatParameter,\n fieldPath?: string\n): string {\n if (value === null || value === undefined) {\n return '';\n }\n\n // Variable can return a custom value that handles formatting\n // This is useful for customAllValue and macros that return values that are already formatted or need special formatting\n if (isCustomVariableValue(value)) {\n return sceneInterpolator(context, value.formatter(formatNameOrFn));\n }\n\n // if it's an object transform value to string\n if (!Array.isArray(value) && typeof value === 'object') {\n value = `${value}`;\n }\n\n if (typeof formatNameOrFn === 'function') {\n return formatNameOrFn(value, {\n name: variable.state.name,\n type: variable.state.type as VariableType,\n multi: variable.state.isMulti,\n includeAll: variable.state.includeAll,\n });\n }\n\n let args: string[] = [];\n\n if (!formatNameOrFn) {\n formatNameOrFn = VariableFormatID.Glob;\n } else {\n // some formats have arguments that come after ':' character\n args = formatNameOrFn.split(':');\n if (args.length > 1) {\n formatNameOrFn = args[0];\n args = args.slice(1);\n } else {\n args = [];\n }\n }\n\n let formatter = formatRegistry.getIfExists(formatNameOrFn);\n\n if (!formatter) {\n console.error(`Variable format ${formatNameOrFn} not found. Using glob format as fallback.`);\n formatter = formatRegistry.get(VariableFormatID.Glob);\n }\n\n return formatter.formatter(value, args, variable, fieldPath);\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sceneInterpolator.js","sources":["../../../../src/variables/interpolation/sceneInterpolator.ts"],"sourcesContent":["import { ScopedVars } from '@grafana/data';\nimport { VariableInterpolation } from '@grafana/runtime';\nimport { VariableType, VariableFormatID } from '@grafana/schema';\n\nimport { SceneObject } from '../../core/types';\nimport { InterpolationFormatParameter, isCustomVariableValue, VariableValue } from '../types';\n\nimport { getSceneVariableForScopedVar } from './ScopedVarsVariable';\nimport { formatRegistry, FormatVariable } from './formatRegistry';\nimport { VARIABLE_REGEX } from '../constants';\nimport { lookupVariable } from '../lookupVariable';\nimport { macrosIndex } from '../macros';\n\n/**\n * This function will try to parse and replace any variable expression found in the target string. The sceneObject will be used as the source of variables. It will\n * use the scene graph and walk up the parent tree until it finds the closest variable.\n *\n * ScopedVars should not really be needed much in the new scene architecture as they can be added to the local scene node instead of passed in interpolate function.\n * It is supported here for backward compatibility and some edge cases where adding scoped vars to local scene node is not practical.\n */\nexport function sceneInterpolator(\n sceneObject: SceneObject,\n target: string | undefined | null,\n scopedVars?: ScopedVars,\n format?: InterpolationFormatParameter,\n interpolations?: VariableInterpolation[]\n): string {\n if (!target || typeof target !== 'string') {\n return target ?? '';\n }\n\n VARIABLE_REGEX.lastIndex = 0;\n\n return target.replace(VARIABLE_REGEX, (match, var1, var2, fmt2, var3, fieldPath, fmt3) => {\n const variableName = var1 || var2 || var3;\n const fmt = fmt2 || fmt3 || format;\n const variable = lookupFormatVariable(variableName, match, scopedVars, sceneObject);\n\n if (!variable) {\n if (interpolations) {\n // Set `value` equal to `match` as documented in the `VariableInterpolation` interface.\n interpolations.push({ match, variableName, fieldPath, format: fmt, value: match, found: false });\n }\n return match;\n }\n\n const value = formatValue(sceneObject, variable, variable.getValue(fieldPath), fmt);\n\n if (interpolations) {\n interpolations.push({ match, variableName, fieldPath, format: fmt, value, found: value !== match });\n }\n\n return value;\n });\n}\n\nfunction lookupFormatVariable(\n name: string,\n match: string,\n scopedVars: ScopedVars | undefined,\n sceneObject: SceneObject\n): FormatVariable | null {\n if (scopedVars && scopedVars.hasOwnProperty(name)) {\n const scopedVar = scopedVars[name];\n\n if (scopedVar) {\n return getSceneVariableForScopedVar(name, scopedVar);\n }\n }\n\n const variable = lookupVariable(name, sceneObject);\n if (variable) {\n return variable;\n }\n\n const Macro = macrosIndex.get(name);\n if (Macro) {\n return new Macro(name, sceneObject, match, scopedVars);\n }\n\n return null;\n}\n\nfunction formatValue(\n context: SceneObject,\n variable: FormatVariable,\n value: VariableValue | undefined | null,\n formatNameOrFn?: InterpolationFormatParameter\n): string {\n if (value === null || value === undefined) {\n return '';\n }\n\n // Variable can return a custom value that handles formatting\n // This is useful for customAllValue and macros that return values that are already formatted or need special formatting\n if (isCustomVariableValue(value)) {\n return sceneInterpolator(context, value.formatter(formatNameOrFn));\n }\n\n // if it's an object transform value to string\n if (!Array.isArray(value) && typeof value === 'object') {\n value = `${value}`;\n }\n\n if (typeof formatNameOrFn === 'function') {\n return formatNameOrFn(value, {\n name: variable.state.name,\n type: variable.state.type as VariableType,\n multi: variable.state.isMulti,\n includeAll: variable.state.includeAll,\n });\n }\n\n let args: string[] = [];\n\n if (!formatNameOrFn) {\n formatNameOrFn = VariableFormatID.Glob;\n } else {\n // some formats have arguments that come after ':' character\n args = formatNameOrFn.split(':');\n if (args.length > 1) {\n formatNameOrFn = args[0];\n args = args.slice(1);\n } else {\n args = [];\n }\n }\n\n let formatter = formatRegistry.getIfExists(formatNameOrFn);\n\n if (!formatter) {\n console.error(`Variable format ${formatNameOrFn} not found. Using glob format as fallback.`);\n formatter = formatRegistry.get(VariableFormatID.Glob);\n }\n\n return formatter.formatter(value, args, variable);\n}\n"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -802,7 +802,7 @@ declare function getUrlState(root: SceneObject, uniqueUrlKeyMapperOptions?: Uniq
802
802
  declare function syncStateFromSearchParams(root: SceneObject, urlParams: URLSearchParams, uniqueUrlKeyMapperOptions?: UniqueUrlKeyMapperOptions): void;
803
803
 
804
804
  interface FormatRegistryItem extends RegistryItem {
805
- formatter(value: VariableValue, args: string[], variable: FormatVariable, fieldPath?: string): string;
805
+ formatter(value: VariableValue, args: string[], variable: FormatVariable): string;
806
806
  }
807
807
  /**
808
808
  * Slimmed down version of the SceneVariable interface so that it only contains what the formatters actually use.
@@ -1505,12 +1505,15 @@ declare class SceneRenderProfiler {
1505
1505
  lastFrameTime: number;
1506
1506
  constructor(queryController?: SceneQueryControllerLike | undefined);
1507
1507
  setQueryController(queryController: SceneQueryControllerLike): void;
1508
+ private setupVisibilityChangeHandler;
1509
+ cleanup(): void;
1508
1510
  startProfile(name: string): void;
1509
1511
  private recordProfileTail;
1510
1512
  private measureTrailingFrames;
1511
1513
  tryCompletingProfile(): void;
1512
1514
  isTailRecording(): boolean;
1513
1515
  cancelTailRecording(): void;
1516
+ cancelProfile(): void;
1514
1517
  addCrumb(crumb: string): void;
1515
1518
  }
1516
1519
 
package/dist/index.js CHANGED
@@ -854,9 +854,10 @@ var __accessCheck$2 = (obj, member, msg) => member.has(obj) || __typeError$2("Ca
854
854
  var __privateGet$2 = (obj, member, getter) => (__accessCheck$2(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
855
855
  var __privateAdd$2 = (obj, member, value) => member.has(obj) ? __typeError$2("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
856
856
  var __privateSet$2 = (obj, member, value, setter) => (__accessCheck$2(obj, member, "write to private field"), member.set(obj, value), value);
857
- var _profileInProgress, _profileStartTs, _trailAnimationFrameId, _recordedTrailingSpans;
857
+ var _profileInProgress, _profileStartTs, _trailAnimationFrameId, _recordedTrailingSpans, _visibilityChangeHandler;
858
858
  const POST_STORM_WINDOW = 2e3;
859
859
  const SPAN_THRESHOLD = 30;
860
+ const TAB_INACTIVE_THRESHOLD = 1e3;
860
861
  class SceneRenderProfiler {
861
862
  constructor(queryController) {
862
863
  this.queryController = queryController;
@@ -866,10 +867,18 @@ class SceneRenderProfiler {
866
867
  // Will keep measured lengths trailing frames
867
868
  __privateAdd$2(this, _recordedTrailingSpans, []);
868
869
  this.lastFrameTime = 0;
870
+ __privateAdd$2(this, _visibilityChangeHandler, null);
869
871
  this.measureTrailingFrames = (measurementStartTs, lastFrameTime, profileStartTs) => {
870
872
  var _a;
871
873
  const currentFrameTime = performance.now();
872
874
  const frameLength = currentFrameTime - lastFrameTime;
875
+ if (frameLength > TAB_INACTIVE_THRESHOLD) {
876
+ writeSceneLog("SceneRenderProfiler", "Tab was inactive, cancelling profile measurement");
877
+ __privateSet$2(this, _recordedTrailingSpans, []);
878
+ __privateSet$2(this, _profileInProgress, null);
879
+ __privateSet$2(this, _trailAnimationFrameId, null);
880
+ return;
881
+ }
873
882
  __privateGet$2(this, _recordedTrailingSpans).push(frameLength);
874
883
  if (currentFrameTime - measurementStartTs < POST_STORM_WINDOW) {
875
884
  if (__privateGet$2(this, _profileInProgress)) {
@@ -896,12 +905,15 @@ class SceneRenderProfiler {
896
905
  );
897
906
  __privateSet$2(this, _trailAnimationFrameId, null);
898
907
  const profileEndTs = profileStartTs + profileDuration + slowFramesTime;
908
+ if (!__privateGet$2(this, _profileInProgress)) {
909
+ return;
910
+ }
899
911
  performance.measure(`DashboardInteraction ${__privateGet$2(this, _profileInProgress).origin}`, {
900
912
  start: profileStartTs,
901
913
  end: profileEndTs
902
914
  });
903
915
  const networkDuration = captureNetwork(profileStartTs, profileEndTs);
904
- if ((_a = this.queryController) == null ? void 0 : _a.state.onProfileComplete) {
916
+ if (((_a = this.queryController) == null ? void 0 : _a.state.onProfileComplete) && __privateGet$2(this, _profileInProgress)) {
905
917
  this.queryController.state.onProfileComplete({
906
918
  origin: __privateGet$2(this, _profileInProgress).origin,
907
919
  crumbs: __privateGet$2(this, _profileInProgress).crumbs,
@@ -928,10 +940,32 @@ class SceneRenderProfiler {
928
940
  }
929
941
  }
930
942
  };
943
+ this.setupVisibilityChangeHandler();
931
944
  }
932
945
  setQueryController(queryController) {
933
946
  this.queryController = queryController;
934
947
  }
948
+ setupVisibilityChangeHandler() {
949
+ if (__privateGet$2(this, _visibilityChangeHandler)) {
950
+ return;
951
+ }
952
+ __privateSet$2(this, _visibilityChangeHandler, () => {
953
+ if (document.hidden && __privateGet$2(this, _profileInProgress)) {
954
+ writeSceneLog("SceneRenderProfiler", "Tab became inactive, cancelling profile");
955
+ this.cancelProfile();
956
+ }
957
+ });
958
+ if (typeof document !== "undefined") {
959
+ document.addEventListener("visibilitychange", __privateGet$2(this, _visibilityChangeHandler));
960
+ }
961
+ }
962
+ cleanup() {
963
+ if (__privateGet$2(this, _visibilityChangeHandler) && typeof document !== "undefined") {
964
+ document.removeEventListener("visibilitychange", __privateGet$2(this, _visibilityChangeHandler));
965
+ __privateSet$2(this, _visibilityChangeHandler, null);
966
+ }
967
+ this.cancelProfile();
968
+ }
935
969
  startProfile(name) {
936
970
  if (__privateGet$2(this, _profileInProgress)) {
937
971
  this.addCrumb(name);
@@ -964,6 +998,17 @@ class SceneRenderProfiler {
964
998
  writeSceneLog("SceneRenderProfiler", "Cancelled recording frames, new profile started");
965
999
  }
966
1000
  }
1001
+ // cancel profile
1002
+ cancelProfile() {
1003
+ if (__privateGet$2(this, _profileInProgress)) {
1004
+ writeSceneLog("SceneRenderProfiler", "Cancelling profile", __privateGet$2(this, _profileInProgress));
1005
+ __privateSet$2(this, _profileInProgress, null);
1006
+ if (__privateGet$2(this, _trailAnimationFrameId)) {
1007
+ cancelAnimationFrame(__privateGet$2(this, _trailAnimationFrameId));
1008
+ __privateSet$2(this, _trailAnimationFrameId, null);
1009
+ }
1010
+ }
1011
+ }
967
1012
  addCrumb(crumb) {
968
1013
  if (__privateGet$2(this, _profileInProgress)) {
969
1014
  writeSceneLog("SceneRenderProfiler", "Adding crumb:", crumb);
@@ -975,6 +1020,7 @@ _profileInProgress = new WeakMap();
975
1020
  _profileStartTs = new WeakMap();
976
1021
  _trailAnimationFrameId = new WeakMap();
977
1022
  _recordedTrailingSpans = new WeakMap();
1023
+ _visibilityChangeHandler = new WeakMap();
978
1024
  function processRecordedSpans(spans) {
979
1025
  for (let i = spans.length - 1; i >= 0; i--) {
980
1026
  if (spans[i] > SPAN_THRESHOLD) {
@@ -1597,9 +1643,9 @@ const formatRegistry = new data.Registry(() => {
1597
1643
  id: schema.VariableFormatID.Text,
1598
1644
  name: "Text",
1599
1645
  description: "Format variables in their text representation. Example in multi-variable scenario A + B + C.",
1600
- formatter: (value, _args, variable, fieldPath) => {
1646
+ formatter: (value, _args, variable) => {
1601
1647
  if (variable.getValueText) {
1602
- return variable.getValueText(fieldPath);
1648
+ return variable.getValueText();
1603
1649
  }
1604
1650
  return String(value);
1605
1651
  }
@@ -2456,7 +2502,7 @@ function sceneInterpolator(sceneObject, target, scopedVars, format, interpolatio
2456
2502
  }
2457
2503
  return match;
2458
2504
  }
2459
- const value = formatValue(sceneObject, variable, variable.getValue(fieldPath), fmt, fieldPath);
2505
+ const value = formatValue(sceneObject, variable, variable.getValue(fieldPath), fmt);
2460
2506
  if (interpolations) {
2461
2507
  interpolations.push({ match, variableName, fieldPath, format: fmt, value, found: value !== match });
2462
2508
  }
@@ -2480,7 +2526,7 @@ function lookupFormatVariable(name, match, scopedVars, sceneObject) {
2480
2526
  }
2481
2527
  return null;
2482
2528
  }
2483
- function formatValue(context, variable, value, formatNameOrFn, fieldPath) {
2529
+ function formatValue(context, variable, value, formatNameOrFn) {
2484
2530
  if (value === null || value === void 0) {
2485
2531
  return "";
2486
2532
  }
@@ -2515,7 +2561,7 @@ function formatValue(context, variable, value, formatNameOrFn, fieldPath) {
2515
2561
  console.error(`Variable format ${formatNameOrFn} not found. Using glob format as fallback.`);
2516
2562
  formatter = formatRegistry.get(schema.VariableFormatID.Glob);
2517
2563
  }
2518
- return formatter.formatter(value, args, variable, fieldPath);
2564
+ return formatter.formatter(value, args, variable);
2519
2565
  }
2520
2566
 
2521
2567
  function isSceneObject(obj) {