@grafana/scenes 0.2.0 → 0.3.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 (56) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/dist/esm/components/EmbeddedScene.js.map +1 -1
  3. package/dist/esm/components/NestedScene.js +1 -28
  4. package/dist/esm/components/NestedScene.js.map +1 -1
  5. package/dist/esm/components/SceneByFrameRepeater.js.map +1 -1
  6. package/dist/esm/components/SceneCanvasText.js +0 -12
  7. package/dist/esm/components/SceneCanvasText.js.map +1 -1
  8. package/dist/esm/components/SceneReactObject.js.map +1 -1
  9. package/dist/esm/components/SceneRefreshPicker.js.map +1 -1
  10. package/dist/esm/components/SceneTimePicker.js.map +1 -1
  11. package/dist/esm/components/SceneToolbarButton.js.map +1 -1
  12. package/dist/esm/components/VizPanel/VizPanel.js +95 -9
  13. package/dist/esm/components/VizPanel/VizPanel.js.map +1 -1
  14. package/dist/esm/components/VizPanel/VizPanelMenu.js.map +1 -1
  15. package/dist/esm/components/VizPanel/VizPanelRenderer.js +20 -13
  16. package/dist/esm/components/VizPanel/VizPanelRenderer.js.map +1 -1
  17. package/dist/esm/components/VizPanel/colorSeriesConfigFactory.js +72 -0
  18. package/dist/esm/components/VizPanel/colorSeriesConfigFactory.js.map +1 -0
  19. package/dist/esm/components/VizPanel/seriesVisibilityConfigFactory.js +164 -0
  20. package/dist/esm/components/VizPanel/seriesVisibilityConfigFactory.js.map +1 -0
  21. package/dist/esm/components/layout/SceneFlexLayout.js.map +1 -1
  22. package/dist/esm/components/layout/grid/SceneGridLayout.js.map +1 -1
  23. package/dist/esm/core/SceneComponentWrapper.js +1 -10
  24. package/dist/esm/core/SceneComponentWrapper.js.map +1 -1
  25. package/dist/esm/core/SceneDataNode.js +29 -1
  26. package/dist/esm/core/SceneDataNode.js.map +1 -1
  27. package/dist/esm/core/SceneObjectBase.js +44 -20
  28. package/dist/esm/core/SceneObjectBase.js.map +1 -1
  29. package/dist/esm/core/events.js.map +1 -1
  30. package/dist/esm/core/types.js.map +1 -1
  31. package/dist/esm/core/utils.js +1 -15
  32. package/dist/esm/core/utils.js.map +1 -1
  33. package/dist/esm/querying/SceneDataTransformer.js.map +1 -1
  34. package/dist/esm/querying/SceneQueryRunner.js +14 -14
  35. package/dist/esm/querying/SceneQueryRunner.js.map +1 -1
  36. package/dist/esm/services/UrlSyncManager.js +9 -10
  37. package/dist/esm/services/UrlSyncManager.js.map +1 -1
  38. package/dist/esm/variables/components/VariableValueSelectors.js.map +1 -1
  39. package/dist/esm/variables/interpolation/defaults.js +1 -8
  40. package/dist/esm/variables/interpolation/defaults.js.map +1 -1
  41. package/dist/esm/variables/interpolation/sceneInterpolator.js +12 -8
  42. package/dist/esm/variables/interpolation/sceneInterpolator.js.map +1 -1
  43. package/dist/esm/variables/macros/DataValueMacro.js +60 -0
  44. package/dist/esm/variables/macros/DataValueMacro.js.map +1 -0
  45. package/dist/esm/variables/macros/index.js +3 -1
  46. package/dist/esm/variables/macros/index.js.map +1 -1
  47. package/dist/esm/variables/macros/types.js.map +1 -1
  48. package/dist/esm/variables/sets/SceneVariableSet.js +28 -29
  49. package/dist/esm/variables/sets/SceneVariableSet.js.map +1 -1
  50. package/dist/esm/variables/types.js.map +1 -1
  51. package/dist/esm/variables/variants/query/QueryVariable.js +14 -15
  52. package/dist/esm/variables/variants/query/QueryVariable.js.map +1 -1
  53. package/dist/index.d.ts +112 -95
  54. package/dist/index.js +723 -363
  55. package/dist/index.js.map +1 -1
  56. package/package.json +3 -3
@@ -5,7 +5,7 @@ import { EventBusSrv } from '@grafana/data';
5
5
  import { useForceUpdate } from '@grafana/ui';
6
6
  import { SceneComponentWrapper } from './SceneComponentWrapper.js';
7
7
  import { SceneObjectStateChangedEvent } from './events.js';
8
- import { forEachSceneObjectInState, cloneSceneObject } from './utils.js';
8
+ import { cloneSceneObject } from './utils.js';
9
9
 
10
10
  var __defProp = Object.defineProperty;
11
11
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
@@ -30,11 +30,12 @@ class SceneObjectBase {
30
30
  this._activationHandlers = [];
31
31
  this._deactivationHandlers = [];
32
32
  this._subs = new Subscription();
33
+ this._refCount = 0;
33
34
  if (!state.key) {
34
35
  state.key = v4();
35
36
  }
36
37
  this._state = Object.freeze(state);
37
- this.setParent();
38
+ this._setParent();
38
39
  }
39
40
  get state() {
40
41
  return this._state;
@@ -54,8 +55,8 @@ class SceneObjectBase {
54
55
  get Component() {
55
56
  return SceneComponentWrapper;
56
57
  }
57
- setParent() {
58
- forEachSceneObjectInState(this._state, (child) => child._parent = this);
58
+ _setParent() {
59
+ this.forEachChild((child) => child._parent = this);
59
60
  }
60
61
  subscribeToState(handler) {
61
62
  return this._events.subscribe(SceneObjectStateChangedEvent, (event) => {
@@ -71,7 +72,7 @@ class SceneObjectBase {
71
72
  const prevState = this._state;
72
73
  const newState = __spreadValues(__spreadValues({}, this._state), update);
73
74
  this._state = Object.freeze(newState);
74
- this.setParent();
75
+ this._setParent();
75
76
  this.publishEvent(
76
77
  new SceneObjectStateChangedEvent({
77
78
  prevState,
@@ -91,17 +92,17 @@ class SceneObjectBase {
91
92
  getRoot() {
92
93
  return !this._parent ? this : this._parent.getRoot();
93
94
  }
94
- activate() {
95
+ _internalActivate() {
95
96
  this._isActive = true;
96
97
  const { $data, $variables, $timeRange } = this.state;
97
98
  if ($timeRange && !$timeRange.isActive) {
98
- $timeRange.activate();
99
+ this._deactivationHandlers.push($timeRange.activate());
99
100
  }
100
101
  if ($variables && !$variables.isActive) {
101
- $variables.activate();
102
+ this._deactivationHandlers.push($variables.activate());
102
103
  }
103
104
  if ($data && !$data.isActive) {
104
- $data.activate();
105
+ this._deactivationHandlers.push($data.activate());
105
106
  }
106
107
  this._activationHandlers.forEach((handler) => {
107
108
  const result = handler();
@@ -110,18 +111,27 @@ class SceneObjectBase {
110
111
  }
111
112
  });
112
113
  }
113
- deactivate() {
114
- this._isActive = false;
115
- const { $data, $variables, $timeRange } = this.state;
116
- if ($timeRange && $timeRange.isActive) {
117
- $timeRange.deactivate();
118
- }
119
- if ($data && $data.isActive) {
120
- $data.deactivate();
121
- }
122
- if ($variables && $variables.isActive) {
123
- $variables.deactivate();
114
+ activate() {
115
+ if (!this.isActive) {
116
+ this._internalActivate();
124
117
  }
118
+ this._refCount++;
119
+ let called = false;
120
+ return () => {
121
+ this._refCount--;
122
+ if (called) {
123
+ const msg = `SceneObject cancelation handler returned by activate() called a second time`;
124
+ console.error(msg, this);
125
+ throw new Error(msg);
126
+ }
127
+ called = true;
128
+ if (this._refCount === 0) {
129
+ this._internalDeactivate();
130
+ }
131
+ };
132
+ }
133
+ _internalDeactivate() {
134
+ this._isActive = false;
125
135
  this._deactivationHandlers.forEach((handler) => handler());
126
136
  this._deactivationHandlers = [];
127
137
  this._events.removeAllListeners();
@@ -140,6 +150,20 @@ class SceneObjectBase {
140
150
  addActivationHandler(handler) {
141
151
  this._activationHandlers.push(handler);
142
152
  }
153
+ forEachChild(callback) {
154
+ for (const propValue of Object.values(this.state)) {
155
+ if (propValue instanceof SceneObjectBase) {
156
+ callback(propValue);
157
+ }
158
+ if (Array.isArray(propValue)) {
159
+ for (const child of propValue) {
160
+ if (child instanceof SceneObjectBase) {
161
+ callback(child);
162
+ }
163
+ }
164
+ }
165
+ }
166
+ }
143
167
  }
144
168
  function useSceneObjectState(model) {
145
169
  const forceUpdate = useForceUpdate();
@@ -1 +1 @@
1
- {"version":3,"file":"SceneObjectBase.js","sources":["../../../src/core/SceneObjectBase.tsx"],"sourcesContent":["import { useEffect } from 'react';\nimport { Subscription, Unsubscribable } from 'rxjs';\nimport { v4 as uuidv4 } from 'uuid';\n\nimport { BusEvent, BusEventHandler, BusEventType, EventBusSrv } from '@grafana/data';\nimport {\n SceneObject,\n SceneComponent,\n SceneObjectState,\n SceneObjectUrlSyncHandler,\n SceneStateChangedHandler,\n SceneActivationHandler,\n SceneDeactivationHandler,\n} from './types';\nimport { useForceUpdate } from '@grafana/ui';\n\nimport { SceneComponentWrapper } from './SceneComponentWrapper';\nimport { SceneObjectStateChangedEvent } from './events';\nimport { cloneSceneObject, forEachSceneObjectInState } from './utils';\nimport { SceneVariableDependencyConfigLike } from '../variables/types';\n\nexport abstract class SceneObjectBase<TState extends SceneObjectState = SceneObjectState>\n implements SceneObject<TState>\n{\n private _isActive = false;\n private _state: TState;\n private _events = new EventBusSrv();\n private _activationHandlers: SceneActivationHandler[] = [];\n private _deactivationHandlers: SceneDeactivationHandler[] = [];\n\n protected _parent?: SceneObject;\n protected _subs = new Subscription();\n\n protected _variableDependency: SceneVariableDependencyConfigLike | undefined;\n protected _urlSync: SceneObjectUrlSyncHandler | undefined;\n\n public constructor(state: TState) {\n if (!state.key) {\n state.key = uuidv4();\n }\n\n this._state = Object.freeze(state);\n this.setParent();\n }\n\n /** Current state */\n public get state(): TState {\n return this._state;\n }\n\n /** True if currently being active (ie displayed for visual objects) */\n public get isActive(): boolean {\n return this._isActive;\n }\n\n /** Returns the parent, undefined for root object */\n public get parent(): SceneObject | undefined {\n return this._parent;\n }\n\n /** Returns variable dependency config */\n public get variableDependency(): SceneVariableDependencyConfigLike | undefined {\n return this._variableDependency;\n }\n\n /** Returns url sync config */\n public get urlSync(): SceneObjectUrlSyncHandler | undefined {\n return this._urlSync;\n }\n\n /**\n * Used in render functions when rendering a SceneObject.\n * Wraps the component in an EditWrapper that handles edit mode\n */\n public get Component(): SceneComponent<this> {\n return SceneComponentWrapper;\n }\n\n private setParent() {\n forEachSceneObjectInState(this._state, (child) => (child._parent = this));\n }\n\n /**\n * Subscribe to the scene state subject\n **/\n public subscribeToState(handler: SceneStateChangedHandler<TState>): Unsubscribable {\n return this._events.subscribe(SceneObjectStateChangedEvent, (event) => {\n if (event.payload.changedObject === this) {\n handler(event.payload.newState as TState, event.payload.prevState as TState);\n }\n });\n }\n\n /**\n * Subscribe to the scene event\n **/\n public subscribeToEvent<T extends BusEvent>(eventType: BusEventType<T>, handler: BusEventHandler<T>): Unsubscribable {\n return this._events.subscribe(eventType, handler);\n }\n\n public setState(update: Partial<TState>) {\n const prevState = this._state;\n const newState: TState = {\n ...this._state,\n ...update,\n };\n\n this._state = Object.freeze(newState);\n\n this.setParent();\n\n // Bubble state change event. This is event is subscribed to by UrlSyncManager and UndoManager\n this.publishEvent(\n new SceneObjectStateChangedEvent({\n prevState,\n newState,\n partialUpdate: update,\n changedObject: this,\n }),\n true\n );\n }\n /*\n * Publish an event and optionally bubble it up the scene\n **/\n public publishEvent(event: BusEvent, bubble?: boolean) {\n this._events.publish(event);\n\n if (bubble && this.parent) {\n this.parent.publishEvent(event, bubble);\n }\n }\n\n public getRoot(): SceneObject {\n return !this._parent ? this : this._parent.getRoot();\n }\n\n /**\n * Called by the SceneComponentWrapper when the react component is mounted.\n * Don't override this, instead use addActivationHandler\n */\n public activate() {\n this._isActive = true;\n\n const { $data, $variables, $timeRange } = this.state;\n\n if ($timeRange && !$timeRange.isActive) {\n $timeRange.activate();\n }\n\n if ($variables && !$variables.isActive) {\n $variables.activate();\n }\n\n if ($data && !$data.isActive) {\n $data.activate();\n }\n\n this._activationHandlers.forEach((handler) => {\n const result = handler();\n if (result) {\n this._deactivationHandlers.push(result);\n }\n });\n }\n\n /**\n * Called by the SceneComponentWrapper when the react component is unmounted.\n * Don't override this, instead use addActivationHandler. The activation handler can return a deactivation handler.\n */\n public deactivate(): void {\n this._isActive = false;\n\n const { $data, $variables, $timeRange } = this.state;\n\n if ($timeRange && $timeRange.isActive) {\n $timeRange.deactivate();\n }\n\n if ($data && $data.isActive) {\n $data.deactivate();\n }\n\n if ($variables && $variables.isActive) {\n $variables.deactivate();\n }\n\n this._deactivationHandlers.forEach((handler) => handler());\n this._deactivationHandlers = [];\n\n // Clear subscriptions and listeners\n this._events.removeAllListeners();\n this._subs.unsubscribe();\n this._subs = new Subscription();\n }\n\n /**\n * Utility hook to get and subscribe to state\n */\n public useState() {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return useSceneObjectState(this);\n }\n\n /** Force a re-render, should only be needed when variable values change */\n public forceRender(): void {\n this.setState({});\n }\n\n /**\n * Will create new SceneObject with shallow-cloned state, but all state items of type SceneObject are deep cloned\n */\n public clone(withState?: Partial<TState>): this {\n return cloneSceneObject(this, withState);\n }\n\n /**\n * Allows external code to register code that is executed on activate and deactivate. This allow you\n * to wire up scene objects that need to respond to state changes in other objects from the outside.\n **/\n public addActivationHandler(handler: SceneActivationHandler) {\n this._activationHandlers.push(handler);\n }\n}\n\n/**\n * This hook is always returning model.state instead of a useState that remembers the last state emitted on the subject\n * The reason for this is so that if the model instance change this function will always return the latest state.\n */\nfunction useSceneObjectState<TState extends SceneObjectState>(model: SceneObjectBase<TState>): TState {\n const forceUpdate = useForceUpdate();\n\n useEffect(() => {\n const s = model.subscribeToState(forceUpdate);\n return () => s.unsubscribe();\n }, [model, forceUpdate]);\n\n return model.state;\n}\n"],"names":["uuidv4"],"mappings":"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"}
1
+ {"version":3,"file":"SceneObjectBase.js","sources":["../../../src/core/SceneObjectBase.tsx"],"sourcesContent":["import { useEffect } from 'react';\nimport { Subscription, Unsubscribable } from 'rxjs';\nimport { v4 as uuidv4 } from 'uuid';\n\nimport { BusEvent, BusEventHandler, BusEventType, EventBusSrv } from '@grafana/data';\nimport {\n SceneObject,\n SceneComponent,\n SceneObjectUrlSyncHandler,\n SceneStateChangedHandler,\n SceneActivationHandler,\n SceneDeactivationHandler,\n CancelActivationHandler,\n SceneObjectState,\n} from './types';\nimport { useForceUpdate } from '@grafana/ui';\n\nimport { SceneComponentWrapper } from './SceneComponentWrapper';\nimport { SceneObjectStateChangedEvent } from './events';\nimport { cloneSceneObject } from './utils';\nimport { SceneVariableDependencyConfigLike } from '../variables/types';\n\nexport abstract class SceneObjectBase<TState extends SceneObjectState = SceneObjectState>\n implements SceneObject<TState>\n{\n private _isActive = false;\n private _state: TState;\n private _events = new EventBusSrv();\n private _activationHandlers: SceneActivationHandler[] = [];\n private _deactivationHandlers: SceneDeactivationHandler[] = [];\n\n protected _parent?: SceneObject;\n protected _subs = new Subscription();\n protected _refCount = 0;\n\n protected _variableDependency: SceneVariableDependencyConfigLike | undefined;\n protected _urlSync: SceneObjectUrlSyncHandler | undefined;\n\n public constructor(state: TState) {\n if (!state.key) {\n state.key = uuidv4();\n }\n\n this._state = Object.freeze(state);\n this._setParent();\n }\n\n /** Current state */\n public get state(): TState {\n return this._state;\n }\n\n /** True if currently being active (ie displayed for visual objects) */\n public get isActive(): boolean {\n return this._isActive;\n }\n\n /** Returns the parent, undefined for root object */\n public get parent(): SceneObject | undefined {\n return this._parent;\n }\n\n /** Returns variable dependency config */\n public get variableDependency(): SceneVariableDependencyConfigLike | undefined {\n return this._variableDependency;\n }\n\n /** Returns url sync config */\n public get urlSync(): SceneObjectUrlSyncHandler | undefined {\n return this._urlSync;\n }\n\n /**\n * Used in render functions when rendering a SceneObject.\n * Wraps the component in an EditWrapper that handles edit mode\n */\n public get Component(): SceneComponent<this> {\n return SceneComponentWrapper;\n }\n\n private _setParent() {\n this.forEachChild((child) => (child._parent = this));\n }\n\n /**\n * Subscribe to the scene state subject\n **/\n public subscribeToState(handler: SceneStateChangedHandler<TState>): Unsubscribable {\n return this._events.subscribe(SceneObjectStateChangedEvent, (event) => {\n if (event.payload.changedObject === this) {\n handler(event.payload.newState as TState, event.payload.prevState as TState);\n }\n });\n }\n\n /**\n * Subscribe to the scene event\n **/\n public subscribeToEvent<T extends BusEvent>(eventType: BusEventType<T>, handler: BusEventHandler<T>): Unsubscribable {\n return this._events.subscribe(eventType, handler);\n }\n\n public setState(update: Partial<TState>) {\n const prevState = this._state;\n const newState: TState = {\n ...this._state,\n ...update,\n };\n\n this._state = Object.freeze(newState);\n\n this._setParent();\n\n // Bubble state change event. This is event is subscribed to by UrlSyncManager and UndoManager\n this.publishEvent(\n new SceneObjectStateChangedEvent({\n prevState,\n newState,\n partialUpdate: update,\n changedObject: this,\n }),\n true\n );\n }\n /*\n * Publish an event and optionally bubble it up the scene\n **/\n public publishEvent(event: BusEvent, bubble?: boolean) {\n this._events.publish(event);\n\n if (bubble && this.parent) {\n this.parent.publishEvent(event, bubble);\n }\n }\n\n public getRoot(): SceneObject {\n return !this._parent ? this : this._parent.getRoot();\n }\n\n private _internalActivate() {\n this._isActive = true;\n\n const { $data, $variables, $timeRange } = this.state;\n\n if ($timeRange && !$timeRange.isActive) {\n this._deactivationHandlers.push($timeRange.activate());\n }\n\n if ($variables && !$variables.isActive) {\n this._deactivationHandlers.push($variables.activate());\n }\n\n if ($data && !$data.isActive) {\n this._deactivationHandlers.push($data.activate());\n }\n\n this._activationHandlers.forEach((handler) => {\n const result = handler();\n if (result) {\n this._deactivationHandlers.push(result);\n }\n });\n }\n\n /**\n * This is primarily called from SceneComponentWrapper when the SceneObject's Component is mounted.\n * But in some scenarios this can also be called directly from another scene object. When called manually from another scene object\n * make sure to call the returned function when the source scene object is deactivated.\n */\n public activate(): CancelActivationHandler {\n if (!this.isActive) {\n this._internalActivate();\n }\n\n this._refCount++;\n\n let called = false;\n\n return () => {\n this._refCount--;\n\n if (called) {\n const msg = `SceneObject cancelation handler returned by activate() called a second time`;\n console.error(msg, this);\n throw new Error(msg);\n }\n\n called = true;\n\n if (this._refCount === 0) {\n this._internalDeactivate();\n }\n };\n }\n\n /**\n * Called by the SceneComponentWrapper when the react component is unmounted.\n * Don't override this, instead use addActivationHandler. The activation handler can return a deactivation handler.\n */\n private _internalDeactivate(): void {\n this._isActive = false;\n\n this._deactivationHandlers.forEach((handler) => handler());\n this._deactivationHandlers = [];\n\n // Clear subscriptions and listeners\n this._events.removeAllListeners();\n this._subs.unsubscribe();\n this._subs = new Subscription();\n }\n\n /**\n * Utility hook to get and subscribe to state\n */\n public useState() {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return useSceneObjectState(this);\n }\n\n /** Force a re-render, should only be needed when variable values change */\n public forceRender(): void {\n this.setState({});\n }\n\n /**\n * Will create new SceneObject with shallow-cloned state, but all state items of type SceneObject are deep cloned\n */\n public clone(withState?: Partial<TState>): this {\n return cloneSceneObject(this, withState);\n }\n\n /**\n * Allows external code to register code that is executed on activate and deactivate. This allow you\n * to wire up scene objects that need to respond to state changes in other objects from the outside.\n **/\n public addActivationHandler(handler: SceneActivationHandler) {\n this._activationHandlers.push(handler);\n }\n\n /**\n * Loop through state and call callback for each direct child scene object.\n * Checks 1 level deep properties and arrays. So a scene object hidden in a nested plain object will not be detected.\n */\n public forEachChild(callback: (child: SceneObjectBase) => void) {\n for (const propValue of Object.values(this.state)) {\n if (propValue instanceof SceneObjectBase) {\n callback(propValue);\n }\n\n if (Array.isArray(propValue)) {\n for (const child of propValue) {\n if (child instanceof SceneObjectBase) {\n callback(child);\n }\n }\n }\n }\n }\n}\n\n/**\n * This hook is always returning model.state instead of a useState that remembers the last state emitted on the subject\n * The reason for this is so that if the model instance change this function will always return the latest state.\n */\nfunction useSceneObjectState<TState extends SceneObjectState>(model: SceneObjectBase<TState>): TState {\n const forceUpdate = useForceUpdate();\n\n useEffect(() => {\n const s = model.subscribeToState(forceUpdate);\n return () => s.unsubscribe();\n }, [model, forceUpdate]);\n\n return model.state;\n}\n"],"names":["uuidv4"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"events.js","sources":["../../../src/core/events.ts"],"sourcesContent":["import { BusEventWithPayload } from '@grafana/data';\n\nimport { SceneObject, SceneObjectState } from './types';\n\nexport interface SceneObjectStateChangedPayload {\n prevState: SceneObjectState;\n newState: SceneObjectState;\n partialUpdate: Partial<SceneObjectState>;\n changedObject: SceneObject;\n}\n\nexport class SceneObjectStateChangedEvent extends BusEventWithPayload<SceneObjectStateChangedPayload> {\n public static readonly type = 'scene-object-state-change';\n}\n"],"names":[],"mappings":";;AAWO,MAAM,qCAAqC,mBAAoD,CAAA;AAEtG,CAAA;AAFa,4BAAA,CACY,IAAO,GAAA,2BAAA;;;;"}
1
+ {"version":3,"file":"events.js","sources":["../../../src/core/events.ts"],"sourcesContent":["import { BusEventWithPayload } from '@grafana/data';\n\nimport { SceneObject, SceneObjectState } from './types';\n\nexport interface SceneObjectStateChangedPayload<TState extends SceneObjectState = SceneObjectState> {\n prevState: TState;\n newState: TState;\n partialUpdate: Partial<TState>;\n changedObject: SceneObject<TState>;\n}\n\nexport class SceneObjectStateChangedEvent extends BusEventWithPayload<SceneObjectStateChangedPayload> {\n public static readonly type = 'scene-object-state-change';\n}\n"],"names":[],"mappings":";;AAWO,MAAM,qCAAqC,mBAAoD,CAAA;AAEtG,CAAA;AAFa,4BAAA,CACY,IAAO,GAAA,2BAAA;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sources":["../../../src/core/types.ts"],"sourcesContent":["import React from 'react';\nimport { MonoTypeOperatorFunction, Unsubscribable } from 'rxjs';\n\nimport {\n BusEvent,\n BusEventHandler,\n BusEventType,\n DataFrame,\n DataTransformContext,\n PanelData,\n TimeRange,\n TimeZone,\n} from '@grafana/data';\n\nimport { SceneVariableDependencyConfigLike, SceneVariables } from '../variables/types';\n\nexport interface SceneObjectStatePlain {\n key?: string;\n $timeRange?: SceneTimeRangeLike;\n $data?: SceneDataProvider;\n $variables?: SceneVariables;\n}\n\nexport interface SceneLayoutChildState extends SceneObjectStatePlain {\n placement?: SceneLayoutChildOptions;\n}\n\nexport interface SceneLayoutItemState extends SceneObjectStatePlain {\n body: SceneObject | undefined;\n}\n\nexport type SceneObjectState = SceneObjectStatePlain | SceneLayoutState | SceneLayoutChildState;\n\nexport interface SceneLayoutChildOptions {\n width?: number | string;\n height?: number | string;\n xSizing?: 'fill' | 'content';\n ySizing?: 'fill' | 'content';\n x?: number;\n y?: number;\n minWidth?: number | string;\n minHeight?: number | string;\n isDraggable?: boolean;\n isResizable?: boolean;\n}\n\nexport interface SceneComponentProps<T> {\n model: T;\n}\n\nexport interface SceneComponentWrapperProps {\n model: SceneObject;\n children: React.ReactNode;\n}\n\nexport type SceneComponent<TModel> = (props: SceneComponentProps<TModel>) => React.ReactElement | null;\nexport type SceneComponentCustomWrapper = (props: SceneComponentWrapperProps) => React.ReactElement | null;\n\nexport interface SceneDataState extends SceneObjectStatePlain {\n data?: PanelData;\n}\n\nexport interface SceneObject<TState extends SceneObjectState = SceneObjectState> {\n /** The current state */\n readonly state: TState;\n\n /** True when there is a React component mounted for this Object */\n readonly isActive: boolean;\n\n /** SceneObject parent */\n readonly parent?: SceneObject;\n\n /** This abtractions declares what variables the scene object depends on and how to handle when they change value. **/\n readonly variableDependency?: SceneVariableDependencyConfigLike;\n\n /** This abstraction declares URL sync dependencies of a scene object. **/\n readonly urlSync?: SceneObjectUrlSyncHandler;\n\n /** Subscribe to state changes */\n subscribeToState(handler: SceneStateChangedHandler<TState>): Unsubscribable;\n\n /** Subscribe to a scene event */\n subscribeToEvent<T extends BusEvent>(typeFilter: BusEventType<T>, handler: BusEventHandler<T>): Unsubscribable;\n\n /** Publish an event and optionally bubble it up the scene */\n publishEvent(event: BusEvent, bubble?: boolean): void;\n\n /** Utility hook that wraps useObservable. Used by React components to subscribes to state changes */\n useState(): TState;\n\n /** How to modify state */\n setState(state: Partial<TState>): void;\n\n /**\n * Called when the Component is mounted. This will also activate any $data, $variables or $timeRange scene object on this level.\n * Don't override this in your custom SceneObjects, instead use addActivationHandler from the constructor. The activation handler can return a deactivation handler.\n **/\n activate(): void;\n\n /** Called when component unmounts. This will also deactivate any $data, $variables or $timeRange scene object on this level.\n * Don't override this in your custom SceneObjects, instead use addActivationHandler from the constructor. The activation handler can return a deactivation handler.\n */\n deactivate(): void;\n\n /** Get the scene root */\n getRoot(): SceneObject;\n\n /** Returns a deep clone this object and all its children */\n clone(state?: Partial<TState>): this;\n\n /** A React component to use for rendering the object */\n Component(props: SceneComponentProps<SceneObject<TState>>): React.ReactElement | null;\n\n /** Force a re-render, should only be needed when variable values change */\n forceRender(): void;\n\n /**\n * Allows external code to register code that is executed on activate and deactivate. This allow you\n * to wire up scene objects that need to respond to state changes in other objects from the outside.\n **/\n addActivationHandler(handler: SceneActivationHandler): void;\n}\n\nexport type SceneActivationHandler = () => SceneDeactivationHandler | void;\nexport type SceneDeactivationHandler = () => void;\n\nexport type SceneLayoutChild = SceneObject<SceneLayoutChildState | SceneLayoutState>;\n\nexport interface SceneLayoutState extends SceneLayoutChildState {\n children: SceneObject[];\n}\n\nexport interface SceneLayout<T extends SceneLayoutState = SceneLayoutState> extends SceneObject<T> {\n isDraggable(): boolean;\n getDragClass?(): string;\n getDragClassCancel?(): string;\n}\n\nexport interface SceneTimeRangeState extends SceneObjectStatePlain {\n from: string;\n to: string;\n timeZone: TimeZone;\n fiscalYearStartMonth?: number;\n value: TimeRange;\n}\n\nexport interface SceneTimeRangeLike extends SceneObject<SceneTimeRangeState> {\n onTimeRangeChange(timeRange: TimeRange): void;\n onRefresh(): void;\n}\n\nexport interface SceneObjectRef {\n ref: SceneObject;\n}\n\nexport function isSceneObject(obj: any): obj is SceneObject {\n return obj.useState !== undefined;\n}\n\nexport interface SceneObjectWithUrlSync extends SceneObject {\n getUrlState(): SceneObjectUrlValues;\n updateFromUrl(values: SceneObjectUrlValues): void;\n}\n\nexport interface SceneObjectUrlSyncHandler {\n getKeys(): string[];\n getUrlState(): SceneObjectUrlValues;\n updateFromUrl(values: SceneObjectUrlValues): void;\n}\n\nexport type SceneObjectUrlValue = string | string[] | undefined | null;\nexport type SceneObjectUrlValues = Record<string, SceneObjectUrlValue>;\n\nexport type CustomTransformOperator = (context: DataTransformContext) => MonoTypeOperatorFunction<DataFrame[]>;\nexport type SceneStateChangedHandler<TState> = (newState: TState, prevState: TState) => void;\n\nexport type DeepPartial<T> = {\n [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K];\n};\n\nexport interface SceneDataProvider extends SceneObject<SceneDataState> {\n setContainerWidth?: (width: number) => void;\n}\n"],"names":[],"mappings":"AA2JO,SAAS,cAAc,GAA8B,EAAA;AAC1D,EAAA,OAAO,IAAI,QAAa,KAAA,KAAA,CAAA,CAAA;AAC1B;;;;"}
1
+ {"version":3,"file":"types.js","sources":["../../../src/core/types.ts"],"sourcesContent":["import React from 'react';\nimport { MonoTypeOperatorFunction, Unsubscribable } from 'rxjs';\n\nimport {\n BusEvent,\n BusEventHandler,\n BusEventType,\n DataFrame,\n DataTransformContext,\n PanelData,\n TimeRange,\n TimeZone,\n} from '@grafana/data';\n\nimport { SceneVariableDependencyConfigLike, SceneVariables } from '../variables/types';\n\nexport interface SceneObjectState {\n key?: string;\n $timeRange?: SceneTimeRangeLike;\n $data?: SceneDataProvider;\n $variables?: SceneVariables;\n}\n\nexport interface SceneLayoutItemState extends SceneObjectState {\n body: SceneObject | undefined;\n}\n\nexport interface SceneLayoutChildOptions {\n width?: number | string;\n height?: number | string;\n xSizing?: 'fill' | 'content';\n ySizing?: 'fill' | 'content';\n x?: number;\n y?: number;\n minWidth?: number | string;\n minHeight?: number | string;\n isDraggable?: boolean;\n isResizable?: boolean;\n}\n\nexport interface SceneComponentProps<T> {\n model: T;\n}\n\nexport type SceneComponent<TModel> = (props: SceneComponentProps<TModel>) => React.ReactElement | null;\n\nexport interface SceneDataState extends SceneObjectState {\n data?: PanelData;\n}\n\nexport interface SceneObject<TState extends SceneObjectState = SceneObjectState> {\n /** The current state */\n readonly state: TState;\n\n /** True when there is a React component mounted for this Object */\n readonly isActive: boolean;\n\n /** SceneObject parent */\n readonly parent?: SceneObject;\n\n /** This abtractions declares what variables the scene object depends on and how to handle when they change value. **/\n readonly variableDependency?: SceneVariableDependencyConfigLike;\n\n /** This abstraction declares URL sync dependencies of a scene object. **/\n readonly urlSync?: SceneObjectUrlSyncHandler;\n\n /** Subscribe to state changes */\n subscribeToState(handler: SceneStateChangedHandler<TState>): Unsubscribable;\n\n /** Subscribe to a scene event */\n subscribeToEvent<T extends BusEvent>(typeFilter: BusEventType<T>, handler: BusEventHandler<T>): Unsubscribable;\n\n /** Publish an event and optionally bubble it up the scene */\n publishEvent(event: BusEvent, bubble?: boolean): void;\n\n /** Utility hook that wraps useObservable. Used by React components to subscribes to state changes */\n useState(): TState;\n\n /** How to modify state */\n setState(state: Partial<TState>): void;\n\n /**\n * Called when the Component is mounted. This will also activate any $data, $variables or $timeRange scene object on this level.\n * Don't override this in your custom SceneObjects, instead use addActivationHandler from the constructor.\n **/\n activate(): CancelActivationHandler;\n\n /** Get the scene root */\n getRoot(): SceneObject;\n\n /** Returns a deep clone this object and all its children */\n clone(state?: Partial<TState>): this;\n\n /** A React component to use for rendering the object */\n Component(props: SceneComponentProps<SceneObject<TState>>): React.ReactElement | null;\n\n /** Force a re-render, should only be needed when variable values change */\n forceRender(): void;\n\n /**\n * Allows external code to register code that is executed on activate and deactivate. This allow you\n * to wire up scene objects that need to respond to state changes in other objects from the outside.\n **/\n addActivationHandler(handler: SceneActivationHandler): void;\n\n /**\n * Loop through state and call callback for each direct child scene object.\n * Checks 1 level deep properties and arrays. So a scene object hidden in a nested plain object will not be detected.\n */\n forEachChild(callback: (child: SceneObject) => void): void;\n}\n\nexport type SceneActivationHandler = () => SceneDeactivationHandler | void;\nexport type SceneDeactivationHandler = () => void;\n\n/**\n * Function returned by activate() that when called will deactivate the object if it's the last activator\n **/\nexport type CancelActivationHandler = () => void;\n\nexport interface SceneLayoutState extends SceneObjectState {\n children: SceneObject[];\n}\n\nexport interface SceneLayout<T extends SceneLayoutState = SceneLayoutState> extends SceneObject<T> {\n isDraggable(): boolean;\n getDragClass?(): string;\n getDragClassCancel?(): string;\n}\n\nexport interface SceneTimeRangeState extends SceneObjectState {\n from: string;\n to: string;\n timeZone: TimeZone;\n fiscalYearStartMonth?: number;\n value: TimeRange;\n}\n\nexport interface SceneTimeRangeLike extends SceneObject<SceneTimeRangeState> {\n onTimeRangeChange(timeRange: TimeRange): void;\n onRefresh(): void;\n}\n\nexport interface SceneObjectRef {\n ref: SceneObject;\n}\n\nexport function isSceneObject(obj: any): obj is SceneObject {\n return obj.useState !== undefined;\n}\n\nexport interface SceneObjectWithUrlSync extends SceneObject {\n getUrlState(): SceneObjectUrlValues;\n updateFromUrl(values: SceneObjectUrlValues): void;\n}\n\nexport interface SceneObjectUrlSyncHandler {\n getKeys(): string[];\n getUrlState(): SceneObjectUrlValues;\n updateFromUrl(values: SceneObjectUrlValues): void;\n}\n\nexport type SceneObjectUrlValue = string | string[] | undefined | null;\nexport type SceneObjectUrlValues = Record<string, SceneObjectUrlValue>;\n\nexport type CustomTransformOperator = (context: DataTransformContext) => MonoTypeOperatorFunction<DataFrame[]>;\nexport type SceneStateChangedHandler<TState> = (newState: TState, prevState: TState) => void;\n\nexport type DeepPartial<T> = {\n [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K];\n};\n\nexport interface SceneDataProvider extends SceneObject<SceneDataState> {\n setContainerWidth?: (width: number) => void;\n}\n"],"names":[],"mappings":"AAmJO,SAAS,cAAc,GAA8B,EAAA;AAC1D,EAAA,OAAO,IAAI,QAAa,KAAA,KAAA,CAAA,CAAA;AAC1B;;;;"}
@@ -16,20 +16,6 @@ var __spreadValues = (a, b) => {
16
16
  }
17
17
  return a;
18
18
  };
19
- function forEachSceneObjectInState(state, callback) {
20
- for (const propValue of Object.values(state)) {
21
- if (propValue instanceof SceneObjectBase) {
22
- callback(propValue);
23
- }
24
- if (Array.isArray(propValue)) {
25
- for (const child of propValue) {
26
- if (child instanceof SceneObjectBase) {
27
- callback(child);
28
- }
29
- }
30
- }
31
- }
32
- }
33
19
  function cloneSceneObject(sceneObject, withState) {
34
20
  const clonedState = __spreadValues({}, sceneObject.state);
35
21
  for (const key in clonedState) {
@@ -53,5 +39,5 @@ function cloneSceneObject(sceneObject, withState) {
53
39
  return new sceneObject.constructor(clonedState);
54
40
  }
55
41
 
56
- export { cloneSceneObject, forEachSceneObjectInState };
42
+ export { cloneSceneObject };
57
43
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sources":["../../../src/core/utils.ts"],"sourcesContent":["import { SceneObjectState, SceneObjectStatePlain } from './types';\n\nimport { SceneObjectBase } from './SceneObjectBase';\n\n/**\n * Will call callback for all first level child scene objects and scene objects inside arrays\n */\nexport function forEachSceneObjectInState(state: SceneObjectStatePlain, callback: (scene: SceneObjectBase) => void) {\n for (const propValue of Object.values(state)) {\n if (propValue instanceof SceneObjectBase) {\n callback(propValue);\n }\n\n if (Array.isArray(propValue)) {\n for (const child of propValue) {\n if (child instanceof SceneObjectBase) {\n callback(child);\n }\n }\n }\n }\n}\n\n/**\n * Will create new SceneItem with shalled cloned state, but all states items of type SceneObject are deep cloned\n */\nexport function cloneSceneObject<T extends SceneObjectBase<TState>, TState extends SceneObjectState>(\n sceneObject: SceneObjectBase<TState>,\n withState?: Partial<TState>\n): T {\n const clonedState = { ...sceneObject.state };\n\n // Clone any SceneItems in state\n for (const key in clonedState) {\n const propValue = clonedState[key];\n if (propValue instanceof SceneObjectBase) {\n clonedState[key] = propValue.clone();\n }\n\n // Clone scene objects in arrays\n if (Array.isArray(propValue)) {\n const newArray: any = [];\n for (const child of propValue) {\n if (child instanceof SceneObjectBase) {\n newArray.push(child.clone());\n } else {\n newArray.push(child);\n }\n }\n clonedState[key] = newArray;\n }\n }\n\n Object.assign(clonedState, withState);\n\n return new (sceneObject.constructor as any)(clonedState);\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAOgB,SAAA,yBAAA,CAA0B,OAA8B,QAA4C,EAAA;AAClH,EAAA,KAAA,MAAW,SAAa,IAAA,MAAA,CAAO,MAAO,CAAA,KAAK,CAAG,EAAA;AAC5C,IAAA,IAAI,qBAAqB,eAAiB,EAAA;AACxC,MAAA,QAAA,CAAS,SAAS,CAAA,CAAA;AAAA,KACpB;AAEA,IAAI,IAAA,KAAA,CAAM,OAAQ,CAAA,SAAS,CAAG,EAAA;AAC5B,MAAA,KAAA,MAAW,SAAS,SAAW,EAAA;AAC7B,QAAA,IAAI,iBAAiB,eAAiB,EAAA;AACpC,UAAA,QAAA,CAAS,KAAK,CAAA,CAAA;AAAA,SAChB;AAAA,OACF;AAAA,KACF;AAAA,GACF;AACF,CAAA;AAKgB,SAAA,gBAAA,CACd,aACA,SACG,EAAA;AACH,EAAM,MAAA,WAAA,GAAc,mBAAK,WAAY,CAAA,KAAA,CAAA,CAAA;AAGrC,EAAA,KAAA,MAAW,OAAO,WAAa,EAAA;AAC7B,IAAA,MAAM,YAAY,WAAY,CAAA,GAAA,CAAA,CAAA;AAC9B,IAAA,IAAI,qBAAqB,eAAiB,EAAA;AACxC,MAAY,WAAA,CAAA,GAAA,CAAA,GAAO,UAAU,KAAM,EAAA,CAAA;AAAA,KACrC;AAGA,IAAI,IAAA,KAAA,CAAM,OAAQ,CAAA,SAAS,CAAG,EAAA;AAC5B,MAAA,MAAM,WAAgB,EAAC,CAAA;AACvB,MAAA,KAAA,MAAW,SAAS,SAAW,EAAA;AAC7B,QAAA,IAAI,iBAAiB,eAAiB,EAAA;AACpC,UAAS,QAAA,CAAA,IAAA,CAAK,KAAM,CAAA,KAAA,EAAO,CAAA,CAAA;AAAA,SACtB,MAAA;AACL,UAAA,QAAA,CAAS,KAAK,KAAK,CAAA,CAAA;AAAA,SACrB;AAAA,OACF;AACA,MAAA,WAAA,CAAY,GAAO,CAAA,GAAA,QAAA,CAAA;AAAA,KACrB;AAAA,GACF;AAEA,EAAO,MAAA,CAAA,MAAA,CAAO,aAAa,SAAS,CAAA,CAAA;AAEpC,EAAO,OAAA,IAAK,WAAY,CAAA,WAAA,CAAoB,WAAW,CAAA,CAAA;AACzD;;;;"}
1
+ {"version":3,"file":"utils.js","sources":["../../../src/core/utils.ts"],"sourcesContent":["import { SceneObjectState } from './types';\n\nimport { SceneObjectBase } from './SceneObjectBase';\n\n/**\n * Will create new SceneItem with shalled cloned state, but all states items of type SceneObject are deep cloned\n */\nexport function cloneSceneObject<T extends SceneObjectBase<TState>, TState extends SceneObjectState>(\n sceneObject: SceneObjectBase<TState>,\n withState?: Partial<TState>\n): T {\n const clonedState = { ...sceneObject.state };\n\n // Clone any SceneItems in state\n for (const key in clonedState) {\n const propValue = clonedState[key];\n if (propValue instanceof SceneObjectBase) {\n clonedState[key] = propValue.clone();\n }\n\n // Clone scene objects in arrays\n if (Array.isArray(propValue)) {\n const newArray: any = [];\n for (const child of propValue) {\n if (child instanceof SceneObjectBase) {\n newArray.push(child.clone());\n } else {\n newArray.push(child);\n }\n }\n clonedState[key] = newArray;\n }\n }\n\n Object.assign(clonedState, withState);\n\n return new (sceneObject.constructor as any)(clonedState);\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAOgB,SAAA,gBAAA,CACd,aACA,SACG,EAAA;AACH,EAAM,MAAA,WAAA,GAAc,mBAAK,WAAY,CAAA,KAAA,CAAA,CAAA;AAGrC,EAAA,KAAA,MAAW,OAAO,WAAa,EAAA;AAC7B,IAAA,MAAM,YAAY,WAAY,CAAA,GAAA,CAAA,CAAA;AAC9B,IAAA,IAAI,qBAAqB,eAAiB,EAAA;AACxC,MAAY,WAAA,CAAA,GAAA,CAAA,GAAO,UAAU,KAAM,EAAA,CAAA;AAAA,KACrC;AAGA,IAAI,IAAA,KAAA,CAAM,OAAQ,CAAA,SAAS,CAAG,EAAA;AAC5B,MAAA,MAAM,WAAgB,EAAC,CAAA;AACvB,MAAA,KAAA,MAAW,SAAS,SAAW,EAAA;AAC7B,QAAA,IAAI,iBAAiB,eAAiB,EAAA;AACpC,UAAS,QAAA,CAAA,IAAA,CAAK,KAAM,CAAA,KAAA,EAAO,CAAA,CAAA;AAAA,SACtB,MAAA;AACL,UAAA,QAAA,CAAS,KAAK,KAAK,CAAA,CAAA;AAAA,SACrB;AAAA,OACF;AACA,MAAA,WAAA,CAAY,GAAO,CAAA,GAAA,QAAA,CAAA;AAAA,KACrB;AAAA,GACF;AAEA,EAAO,MAAA,CAAA,MAAA,CAAO,aAAa,SAAS,CAAA,CAAA;AAEpC,EAAO,OAAA,IAAK,WAAY,CAAA,WAAA,CAAoB,WAAW,CAAA,CAAA;AACzD;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"SceneDataTransformer.js","sources":["../../../src/querying/SceneDataTransformer.ts"],"sourcesContent":["import { DataTransformerConfig, PanelData, transformDataFrame } from '@grafana/data';\nimport { map, Unsubscribable } from 'rxjs';\nimport { SceneDataNodeState } from '../core/SceneDataNode';\nimport { sceneGraph } from '../core/sceneGraph';\nimport { SceneObjectBase } from '../core/SceneObjectBase';\nimport { CustomTransformOperator, SceneDataProvider } from '../core/types';\nimport { VariableDependencyConfig } from '../variables/VariableDependencyConfig';\n\nexport interface SceneDataTransformerState extends SceneDataNodeState {\n /**\n * Array of standard transformation configs and custom transform operators\n */\n transformations: Array<DataTransformerConfig | CustomTransformOperator>;\n}\n\n/**\n * You can use this as a $data object. It can either transform an inner $data DataProvider or if that is not set it will\n * subscribe to a DataProvider higher up in the scene graph and transform its data.\n *\n * The transformations array supports custom (runtime defined) transformation as well as declarative core transformations.\n * You can manually re-process the transformations by calling reprocessTransformations(). This is useful if you have\n * transformations that depend on other scene object states.\n */\nexport class SceneDataTransformer extends SceneObjectBase<SceneDataTransformerState> implements SceneDataProvider {\n private _transformSub?: Unsubscribable;\n\n /**\n * Scan transformations for variable usage and re-process transforms when a variable values change\n */\n protected _variableDependency: VariableDependencyConfig<SceneDataTransformerState> = new VariableDependencyConfig(\n this,\n {\n statePaths: ['transformations'],\n onReferencedVariableValueChanged: () => this.reprocessTransformations(),\n }\n );\n\n public constructor(state: SceneDataTransformerState) {\n super(state);\n\n this.addActivationHandler(() => this.activationHandler());\n }\n\n private activationHandler() {\n const sourceData = this.getSourceData();\n\n this._subs.add(sourceData.subscribeToState((state) => this.transform(state.data)));\n\n if (sourceData.state.data) {\n this.transform(sourceData.state.data);\n }\n\n return () => {\n if (this._transformSub) {\n this._transformSub.unsubscribe();\n }\n };\n }\n\n private getSourceData(): SceneDataProvider {\n if (this.state.$data) {\n return this.state.$data;\n }\n\n if (!this.parent || !this.parent.parent) {\n throw new Error('SceneDataTransformer must either have $data set on it or have a parent.parent with $data');\n }\n\n return sceneGraph.getData(this.parent.parent);\n }\n\n public setContainerWidth(width: number) {\n if (this.state.$data && this.state.$data.setContainerWidth) {\n this.state.$data.setContainerWidth(width);\n }\n }\n\n public reprocessTransformations() {\n this.transform(this.getSourceData().state.data);\n }\n\n private transform(data: PanelData | undefined) {\n const transformations = this.state.transformations || [];\n\n if (transformations.length === 0 || !data) {\n this.setState({ data });\n return;\n }\n\n if (this._transformSub) {\n this._transformSub.unsubscribe();\n }\n\n const ctx = {\n interpolate: (value: string) => {\n return sceneGraph.interpolate(this, value, data.request?.scopedVars);\n },\n };\n\n this._transformSub = transformDataFrame(transformations, data.series, ctx)\n .pipe(map((series) => ({ ...data, series })))\n .subscribe((data) => this.setState({ data }));\n }\n}\n"],"names":["data"],"mappings":"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"}
1
+ {"version":3,"file":"SceneDataTransformer.js","sources":["../../../src/querying/SceneDataTransformer.ts"],"sourcesContent":["import { DataTransformerConfig, PanelData, transformDataFrame } from '@grafana/data';\nimport { map, Unsubscribable } from 'rxjs';\nimport { sceneGraph } from '../core/sceneGraph';\nimport { SceneObjectBase } from '../core/SceneObjectBase';\nimport { CustomTransformOperator, SceneDataProvider, SceneDataState } from '../core/types';\nimport { VariableDependencyConfig } from '../variables/VariableDependencyConfig';\n\nexport interface SceneDataTransformerState extends SceneDataState {\n /**\n * Array of standard transformation configs and custom transform operators\n */\n transformations: Array<DataTransformerConfig | CustomTransformOperator>;\n}\n\n/**\n * You can use this as a $data object. It can either transform an inner $data DataProvider or if that is not set it will\n * subscribe to a DataProvider higher up in the scene graph and transform its data.\n *\n * The transformations array supports custom (runtime defined) transformation as well as declarative core transformations.\n * You can manually re-process the transformations by calling reprocessTransformations(). This is useful if you have\n * transformations that depend on other scene object states.\n */\nexport class SceneDataTransformer extends SceneObjectBase<SceneDataTransformerState> implements SceneDataProvider {\n private _transformSub?: Unsubscribable;\n\n /**\n * Scan transformations for variable usage and re-process transforms when a variable values change\n */\n protected _variableDependency: VariableDependencyConfig<SceneDataTransformerState> = new VariableDependencyConfig(\n this,\n {\n statePaths: ['transformations'],\n onReferencedVariableValueChanged: () => this.reprocessTransformations(),\n }\n );\n\n public constructor(state: SceneDataTransformerState) {\n super(state);\n\n this.addActivationHandler(() => this.activationHandler());\n }\n\n private activationHandler() {\n const sourceData = this.getSourceData();\n\n this._subs.add(sourceData.subscribeToState((state) => this.transform(state.data)));\n\n if (sourceData.state.data) {\n this.transform(sourceData.state.data);\n }\n\n return () => {\n if (this._transformSub) {\n this._transformSub.unsubscribe();\n }\n };\n }\n\n private getSourceData(): SceneDataProvider {\n if (this.state.$data) {\n return this.state.$data;\n }\n\n if (!this.parent || !this.parent.parent) {\n throw new Error('SceneDataTransformer must either have $data set on it or have a parent.parent with $data');\n }\n\n return sceneGraph.getData(this.parent.parent);\n }\n\n public setContainerWidth(width: number) {\n if (this.state.$data && this.state.$data.setContainerWidth) {\n this.state.$data.setContainerWidth(width);\n }\n }\n\n public reprocessTransformations() {\n this.transform(this.getSourceData().state.data);\n }\n\n private transform(data: PanelData | undefined) {\n const transformations = this.state.transformations || [];\n\n if (transformations.length === 0 || !data) {\n this.setState({ data });\n return;\n }\n\n if (this._transformSub) {\n this._transformSub.unsubscribe();\n }\n\n const ctx = {\n interpolate: (value: string) => {\n return sceneGraph.interpolate(this, value, data.request?.scopedVars);\n },\n };\n\n this._transformSub = transformDataFrame(transformations, data.series, ctx)\n .pipe(map((series) => ({ ...data, series })))\n .subscribe((data) => this.setState({ data }));\n }\n}\n"],"names":["data"],"mappings":"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"}
@@ -22,22 +22,23 @@ class SceneQueryRunner extends SceneObjectBase {
22
22
  statePaths: ["queries", "datasource"],
23
23
  onVariableUpdatesCompleted: (variables, dependencyChanged) => this.onVariableUpdatesCompleted(variables, dependencyChanged)
24
24
  });
25
- this._onActivate = () => {
26
- const timeRange = sceneGraph.getTimeRange(this);
27
- this._subs.add(
28
- timeRange.subscribeToState((timeRange2) => {
29
- this.runWithTimeRange(timeRange2.value);
30
- })
31
- );
32
- if (this.shouldRunQueriesOnActivate()) {
33
- this.runQueries();
34
- }
35
- };
36
25
  this.onDataReceived = (data) => {
37
26
  const preProcessedData = preProcessPanelData(data, this.state.data);
38
27
  this.setState({ data: preProcessedData });
39
28
  };
40
- this.addActivationHandler(this._onActivate);
29
+ this.addActivationHandler(() => this._onActivate());
30
+ }
31
+ _onActivate() {
32
+ const timeRange = sceneGraph.getTimeRange(this);
33
+ this._subs.add(
34
+ timeRange.subscribeToState((timeRange2) => {
35
+ this.runWithTimeRange(timeRange2.value);
36
+ })
37
+ );
38
+ if (this.shouldRunQueriesOnActivate()) {
39
+ this.runQueries();
40
+ }
41
+ return () => this._onDeactivate();
41
42
  }
42
43
  onVariableUpdatesCompleted(_variablesThatHaveChanged, dependencyChanged) {
43
44
  if (this.state.isWaitingForVariables && this.shouldRunQueriesOnActivate()) {
@@ -64,8 +65,7 @@ class SceneQueryRunner extends SceneObjectBase {
64
65
  }
65
66
  return true;
66
67
  }
67
- deactivate() {
68
- super.deactivate();
68
+ _onDeactivate() {
69
69
  if (this._querySub) {
70
70
  this._querySub.unsubscribe();
71
71
  this._querySub = void 0;
@@ -1 +1 @@
1
- {"version":3,"file":"SceneQueryRunner.js","sources":["../../../src/querying/SceneQueryRunner.ts"],"sourcesContent":["import { cloneDeep } from 'lodash';\nimport { mergeMap, MonoTypeOperatorFunction, Unsubscribable, map, of } from 'rxjs';\n\nimport { DataQuery, DataSourceRef, LoadingState } from '@grafana/schema';\n\nimport {\n CoreApp,\n DataQueryRequest,\n DataTransformerConfig,\n PanelData,\n preProcessPanelData,\n rangeUtil,\n ScopedVar,\n TimeRange,\n transformDataFrame,\n} from '@grafana/data';\nimport { getRunRequest } from '@grafana/runtime';\n\nimport { SceneObjectBase } from '../core/SceneObjectBase';\nimport { sceneGraph } from '../core/sceneGraph';\nimport { CustomTransformOperator, SceneDataProvider, SceneObject, SceneObjectStatePlain } from '../core/types';\nimport { getDataSource } from '../utils/getDataSource';\nimport { VariableDependencyConfig } from '../variables/VariableDependencyConfig';\nimport { SceneVariable } from '../variables/types';\nimport { writeSceneLog } from '../utils/writeSceneLog';\nimport { VariableValueRecorder } from '../variables/VariableValueRecorder';\n\nlet counter = 100;\n\nexport function getNextRequestId() {\n return 'SQR' + counter++;\n}\n\nexport interface QueryRunnerState extends SceneObjectStatePlain {\n data?: PanelData;\n dataPreTransforms?: PanelData;\n queries: DataQueryExtended[];\n datasource?: DataSourceRef;\n minInterval?: string;\n maxDataPoints?: number;\n // Non persisted state\n maxDataPointsFromWidth?: boolean;\n isWaitingForVariables?: boolean;\n}\n\nexport interface DataQueryExtended extends DataQuery {\n [key: string]: any;\n}\n\nexport class SceneQueryRunner extends SceneObjectBase<QueryRunnerState> implements SceneDataProvider {\n private _querySub?: Unsubscribable;\n private _containerWidth?: number;\n private _variableValueRecorder = new VariableValueRecorder();\n\n protected _variableDependency: VariableDependencyConfig<QueryRunnerState> = new VariableDependencyConfig(this, {\n statePaths: ['queries', 'datasource'],\n onVariableUpdatesCompleted: (variables, dependencyChanged) =>\n this.onVariableUpdatesCompleted(variables, dependencyChanged),\n });\n\n public constructor(initialState: QueryRunnerState) {\n super(initialState);\n\n this.addActivationHandler(this._onActivate);\n }\n\n private _onActivate = () => {\n const timeRange = sceneGraph.getTimeRange(this);\n\n this._subs.add(\n timeRange.subscribeToState((timeRange) => {\n this.runWithTimeRange(timeRange.value);\n })\n );\n\n if (this.shouldRunQueriesOnActivate()) {\n this.runQueries();\n }\n };\n\n /**\n * Handles some tricky cases where we need to run queries even when they have not changed in case\n * the query execution on activate was stopped due to VariableSet still not having processed all variables.\n */\n private onVariableUpdatesCompleted(_variablesThatHaveChanged: Set<SceneVariable>, dependencyChanged: boolean) {\n if (this.state.isWaitingForVariables && this.shouldRunQueriesOnActivate()) {\n this.runQueries();\n return;\n }\n\n if (dependencyChanged) {\n this.runQueries();\n }\n }\n\n private shouldRunQueriesOnActivate() {\n // If no maxDataPoints specified we might need to wait for container width to be set from the outside\n if (!this.state.maxDataPoints && this.state.maxDataPointsFromWidth && !this._containerWidth) {\n return false;\n }\n\n if (this._variableValueRecorder.hasDependenciesChanged(this)) {\n writeSceneLog(\n 'SceneQueryRunner',\n 'Variable dependency changed while inactive, shouldRunQueriesOnActivate returns true'\n );\n return true;\n }\n\n // If we already have data, no need\n // TODO validate that time range is similar and if not we should run queries again\n if (this.state.data) {\n return false;\n }\n\n return true;\n }\n\n public deactivate(): void {\n super.deactivate();\n\n if (this._querySub) {\n this._querySub.unsubscribe();\n this._querySub = undefined;\n }\n\n this._variableValueRecorder.recordCurrentDependencyValuesForSceneObject(this);\n }\n\n public setContainerWidth(width: number) {\n // If we don't have a width we should run queries\n if (!this._containerWidth && width > 0) {\n this._containerWidth = width;\n\n // If we don't have maxDataPoints specifically set and maxDataPointsFromWidth is true\n if (this.state.maxDataPointsFromWidth && !this.state.maxDataPoints) {\n // As this is called from render path we need to wait for next tick before running queries\n setTimeout(() => {\n if (this.isActive && !this._querySub) {\n this.runQueries();\n }\n }, 0);\n }\n } else {\n // if the updated container width is bigger than 0 let's remember the width until next query issue\n if (width > 0) {\n this._containerWidth = width;\n }\n }\n }\n\n public runQueries() {\n const timeRange = sceneGraph.getTimeRange(this);\n this.runWithTimeRange(timeRange.state.value);\n }\n\n private getMaxDataPoints() {\n return this.state.maxDataPoints ?? this._containerWidth ?? 500;\n }\n\n private async runWithTimeRange(timeRange: TimeRange) {\n // Skip executing queries if variable dependency is in loading state\n if (sceneGraph.hasVariableDependencyInLoadingState(this)) {\n writeSceneLog('SceneQueryRunner', 'Variable dependency is in loading state, skipping query execution');\n this.setState({ isWaitingForVariables: true });\n return;\n }\n\n // If we where waiting for variables clear that flag\n if (this.state.isWaitingForVariables) {\n this.setState({ isWaitingForVariables: false });\n }\n\n const { minInterval, queries } = this.state;\n const sceneObjectScopedVar: Record<string, ScopedVar<SceneQueryRunner>> = {\n __sceneObject: { text: '__sceneObject', value: this },\n };\n\n // Simple path when no queries exist\n if (!queries?.length) {\n this.onDataReceived({\n state: LoadingState.Done,\n series: [],\n timeRange,\n });\n }\n\n const request: DataQueryRequest = {\n app: CoreApp.Dashboard,\n requestId: getNextRequestId(),\n timezone: 'browser',\n panelId: 1,\n dashboardId: 1,\n range: timeRange,\n interval: '1s',\n intervalMs: 1000,\n targets: cloneDeep(queries),\n maxDataPoints: this.getMaxDataPoints(),\n scopedVars: sceneObjectScopedVar,\n startTime: Date.now(),\n };\n\n try {\n const datasource = this.state.datasource ?? findFirstDatasource(request.targets);\n const ds = await getDataSource(datasource, request.scopedVars);\n\n // Attach the data source name to each query\n request.targets = request.targets.map((query) => {\n if (!query.datasource) {\n query.datasource = ds.getRef();\n }\n return query;\n });\n\n // TODO interpolate minInterval\n const lowerIntervalLimit = minInterval ? minInterval : ds.interval;\n const norm = rangeUtil.calculateInterval(timeRange, request.maxDataPoints!, lowerIntervalLimit);\n\n // make shallow copy of scoped vars,\n // and add built in variables interval and interval_ms\n request.scopedVars = Object.assign({}, request.scopedVars, {\n __interval: { text: norm.interval, value: norm.interval },\n __interval_ms: { text: norm.intervalMs.toString(), value: norm.intervalMs },\n });\n\n request.interval = norm.interval;\n request.intervalMs = norm.intervalMs;\n\n const runRequest = getRunRequest();\n\n writeSceneLog('SceneQueryRunner', 'Starting runRequest', this.state.key);\n\n this._querySub = runRequest(ds, request).subscribe(this.onDataReceived);\n } catch (err) {\n console.error('PanelQueryRunner Error', err);\n }\n }\n\n private onDataReceived = (data: PanelData) => {\n const preProcessedData = preProcessPanelData(data, this.state.data);\n this.setState({ data: preProcessedData });\n };\n}\n\nfunction findFirstDatasource(targets: DataQuery[]): DataSourceRef | undefined {\n for (const t of targets) {\n if (t.datasource != null) {\n return t.datasource;\n }\n }\n return undefined;\n}\n\nexport function getTransformationsStream(\n sceneObject: SceneObject,\n transformations?: Array<DataTransformerConfig | CustomTransformOperator>,\n lastResult?: PanelData\n): MonoTypeOperatorFunction<PanelData> {\n return (inputStream) => {\n return inputStream.pipe(\n mergeMap((data) => {\n const preProcessedData = preProcessPanelData(data, lastResult);\n\n if (!transformations || transformations.length === 0) {\n return of(preProcessedData);\n }\n\n const ctx = {\n interpolate: (value: string) => {\n return sceneGraph.interpolate(sceneObject, value, preProcessedData?.request?.scopedVars);\n },\n };\n\n return transformDataFrame(transformations, data.series, ctx).pipe(map((series) => ({ ...data, series })));\n })\n );\n };\n}\n"],"names":["timeRange"],"mappings":"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"}
1
+ {"version":3,"file":"SceneQueryRunner.js","sources":["../../../src/querying/SceneQueryRunner.ts"],"sourcesContent":["import { cloneDeep } from 'lodash';\nimport { mergeMap, MonoTypeOperatorFunction, Unsubscribable, map, of } from 'rxjs';\n\nimport { DataQuery, DataSourceRef, LoadingState } from '@grafana/schema';\n\nimport {\n CoreApp,\n DataQueryRequest,\n DataTransformerConfig,\n PanelData,\n preProcessPanelData,\n rangeUtil,\n ScopedVar,\n TimeRange,\n transformDataFrame,\n} from '@grafana/data';\nimport { getRunRequest } from '@grafana/runtime';\n\nimport { SceneObjectBase } from '../core/SceneObjectBase';\nimport { sceneGraph } from '../core/sceneGraph';\nimport { CustomTransformOperator, SceneDataProvider, SceneObject, SceneObjectState } from '../core/types';\nimport { getDataSource } from '../utils/getDataSource';\nimport { VariableDependencyConfig } from '../variables/VariableDependencyConfig';\nimport { SceneVariable } from '../variables/types';\nimport { writeSceneLog } from '../utils/writeSceneLog';\nimport { VariableValueRecorder } from '../variables/VariableValueRecorder';\n\nlet counter = 100;\n\nexport function getNextRequestId() {\n return 'SQR' + counter++;\n}\n\nexport interface QueryRunnerState extends SceneObjectState {\n data?: PanelData;\n dataPreTransforms?: PanelData;\n queries: DataQueryExtended[];\n datasource?: DataSourceRef;\n minInterval?: string;\n maxDataPoints?: number;\n // Non persisted state\n maxDataPointsFromWidth?: boolean;\n isWaitingForVariables?: boolean;\n}\n\nexport interface DataQueryExtended extends DataQuery {\n [key: string]: any;\n}\n\nexport class SceneQueryRunner extends SceneObjectBase<QueryRunnerState> implements SceneDataProvider {\n private _querySub?: Unsubscribable;\n private _containerWidth?: number;\n private _variableValueRecorder = new VariableValueRecorder();\n\n protected _variableDependency: VariableDependencyConfig<QueryRunnerState> = new VariableDependencyConfig(this, {\n statePaths: ['queries', 'datasource'],\n onVariableUpdatesCompleted: (variables, dependencyChanged) =>\n this.onVariableUpdatesCompleted(variables, dependencyChanged),\n });\n\n public constructor(initialState: QueryRunnerState) {\n super(initialState);\n\n this.addActivationHandler(() => this._onActivate());\n }\n\n private _onActivate() {\n const timeRange = sceneGraph.getTimeRange(this);\n\n this._subs.add(\n timeRange.subscribeToState((timeRange) => {\n this.runWithTimeRange(timeRange.value);\n })\n );\n\n if (this.shouldRunQueriesOnActivate()) {\n this.runQueries();\n }\n\n return () => this._onDeactivate();\n }\n\n /**\n * Handles some tricky cases where we need to run queries even when they have not changed in case\n * the query execution on activate was stopped due to VariableSet still not having processed all variables.\n */\n private onVariableUpdatesCompleted(_variablesThatHaveChanged: Set<SceneVariable>, dependencyChanged: boolean) {\n if (this.state.isWaitingForVariables && this.shouldRunQueriesOnActivate()) {\n this.runQueries();\n return;\n }\n\n if (dependencyChanged) {\n this.runQueries();\n }\n }\n\n private shouldRunQueriesOnActivate() {\n // If no maxDataPoints specified we might need to wait for container width to be set from the outside\n if (!this.state.maxDataPoints && this.state.maxDataPointsFromWidth && !this._containerWidth) {\n return false;\n }\n\n if (this._variableValueRecorder.hasDependenciesChanged(this)) {\n writeSceneLog(\n 'SceneQueryRunner',\n 'Variable dependency changed while inactive, shouldRunQueriesOnActivate returns true'\n );\n return true;\n }\n\n // If we already have data, no need\n // TODO validate that time range is similar and if not we should run queries again\n if (this.state.data) {\n return false;\n }\n\n return true;\n }\n\n private _onDeactivate(): void {\n if (this._querySub) {\n this._querySub.unsubscribe();\n this._querySub = undefined;\n }\n\n this._variableValueRecorder.recordCurrentDependencyValuesForSceneObject(this);\n }\n\n public setContainerWidth(width: number) {\n // If we don't have a width we should run queries\n if (!this._containerWidth && width > 0) {\n this._containerWidth = width;\n\n // If we don't have maxDataPoints specifically set and maxDataPointsFromWidth is true\n if (this.state.maxDataPointsFromWidth && !this.state.maxDataPoints) {\n // As this is called from render path we need to wait for next tick before running queries\n setTimeout(() => {\n if (this.isActive && !this._querySub) {\n this.runQueries();\n }\n }, 0);\n }\n } else {\n // if the updated container width is bigger than 0 let's remember the width until next query issue\n if (width > 0) {\n this._containerWidth = width;\n }\n }\n }\n\n public runQueries() {\n const timeRange = sceneGraph.getTimeRange(this);\n this.runWithTimeRange(timeRange.state.value);\n }\n\n private getMaxDataPoints() {\n return this.state.maxDataPoints ?? this._containerWidth ?? 500;\n }\n\n private async runWithTimeRange(timeRange: TimeRange) {\n // Skip executing queries if variable dependency is in loading state\n if (sceneGraph.hasVariableDependencyInLoadingState(this)) {\n writeSceneLog('SceneQueryRunner', 'Variable dependency is in loading state, skipping query execution');\n this.setState({ isWaitingForVariables: true });\n return;\n }\n\n // If we where waiting for variables clear that flag\n if (this.state.isWaitingForVariables) {\n this.setState({ isWaitingForVariables: false });\n }\n\n const { minInterval, queries } = this.state;\n const sceneObjectScopedVar: Record<string, ScopedVar<SceneQueryRunner>> = {\n __sceneObject: { text: '__sceneObject', value: this },\n };\n\n // Simple path when no queries exist\n if (!queries?.length) {\n this.onDataReceived({\n state: LoadingState.Done,\n series: [],\n timeRange,\n });\n }\n\n const request: DataQueryRequest = {\n app: CoreApp.Dashboard,\n requestId: getNextRequestId(),\n timezone: 'browser',\n panelId: 1,\n dashboardId: 1,\n range: timeRange,\n interval: '1s',\n intervalMs: 1000,\n targets: cloneDeep(queries),\n maxDataPoints: this.getMaxDataPoints(),\n scopedVars: sceneObjectScopedVar,\n startTime: Date.now(),\n };\n\n try {\n const datasource = this.state.datasource ?? findFirstDatasource(request.targets);\n const ds = await getDataSource(datasource, request.scopedVars);\n\n // Attach the data source name to each query\n request.targets = request.targets.map((query) => {\n if (!query.datasource) {\n query.datasource = ds.getRef();\n }\n return query;\n });\n\n // TODO interpolate minInterval\n const lowerIntervalLimit = minInterval ? minInterval : ds.interval;\n const norm = rangeUtil.calculateInterval(timeRange, request.maxDataPoints!, lowerIntervalLimit);\n\n // make shallow copy of scoped vars,\n // and add built in variables interval and interval_ms\n request.scopedVars = Object.assign({}, request.scopedVars, {\n __interval: { text: norm.interval, value: norm.interval },\n __interval_ms: { text: norm.intervalMs.toString(), value: norm.intervalMs },\n });\n\n request.interval = norm.interval;\n request.intervalMs = norm.intervalMs;\n\n const runRequest = getRunRequest();\n\n writeSceneLog('SceneQueryRunner', 'Starting runRequest', this.state.key);\n\n this._querySub = runRequest(ds, request).subscribe(this.onDataReceived);\n } catch (err) {\n console.error('PanelQueryRunner Error', err);\n }\n }\n\n private onDataReceived = (data: PanelData) => {\n const preProcessedData = preProcessPanelData(data, this.state.data);\n this.setState({ data: preProcessedData });\n };\n}\n\nfunction findFirstDatasource(targets: DataQuery[]): DataSourceRef | undefined {\n for (const t of targets) {\n if (t.datasource != null) {\n return t.datasource;\n }\n }\n return undefined;\n}\n\nexport function getTransformationsStream(\n sceneObject: SceneObject,\n transformations?: Array<DataTransformerConfig | CustomTransformOperator>,\n lastResult?: PanelData\n): MonoTypeOperatorFunction<PanelData> {\n return (inputStream) => {\n return inputStream.pipe(\n mergeMap((data) => {\n const preProcessedData = preProcessPanelData(data, lastResult);\n\n if (!transformations || transformations.length === 0) {\n return of(preProcessedData);\n }\n\n const ctx = {\n interpolate: (value: string) => {\n return sceneGraph.interpolate(sceneObject, value, preProcessedData?.request?.scopedVars);\n },\n };\n\n return transformDataFrame(transformations, data.series, ctx).pipe(map((series) => ({ ...data, series })));\n })\n );\n };\n}\n"],"names":["timeRange"],"mappings":"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"}
@@ -1,18 +1,17 @@
1
1
  import { isEqual } from 'lodash';
2
2
  import { locationService } from '@grafana/runtime';
3
3
  import { SceneObjectStateChangedEvent } from '../core/events.js';
4
- import { forEachSceneObjectInState } from '../core/utils.js';
5
4
 
6
5
  class UrlSyncManager {
7
6
  constructor(sceneRoot) {
8
7
  this.sceneRoot = sceneRoot;
9
8
  this.urlKeyMapper = new UniqueUrlKeyMapper();
10
- this.onLocationUpdate = (location) => {
9
+ this._onLocationUpdate = (location) => {
11
10
  const urlParams = new URLSearchParams(location.search);
12
11
  this.urlKeyMapper.rebuldIndex(this.sceneRoot);
13
- this.syncSceneStateFromUrl(this.sceneRoot, urlParams);
12
+ this._syncSceneStateFromUrl(this.sceneRoot, urlParams);
14
13
  };
15
- this.onStateChanged = ({ payload }) => {
14
+ this._onStateChanged = ({ payload }) => {
16
15
  const changedObject = payload.changedObject;
17
16
  if (changedObject.urlSync) {
18
17
  const newUrlState = changedObject.urlSync.getUrlState();
@@ -34,8 +33,8 @@ class UrlSyncManager {
34
33
  }
35
34
  initSync() {
36
35
  this.sceneRoot.addActivationHandler(() => {
37
- const stateChangeSub = this.sceneRoot.subscribeToEvent(SceneObjectStateChangedEvent, this.onStateChanged);
38
- const locationListenerUnsub = locationService.getHistory().listen(this.onLocationUpdate);
36
+ const stateChangeSub = this.sceneRoot.subscribeToEvent(SceneObjectStateChangedEvent, this._onStateChanged);
37
+ const locationListenerUnsub = locationService.getHistory().listen(this._onLocationUpdate);
39
38
  return () => {
40
39
  stateChangeSub.unsubscribe();
41
40
  locationListenerUnsub();
@@ -43,9 +42,9 @@ class UrlSyncManager {
43
42
  });
44
43
  const urlParams = locationService.getSearch();
45
44
  this.urlKeyMapper.rebuldIndex(this.sceneRoot);
46
- this.syncSceneStateFromUrl(this.sceneRoot, urlParams);
45
+ this._syncSceneStateFromUrl(this.sceneRoot, urlParams);
47
46
  }
48
- syncSceneStateFromUrl(sceneObject, urlParams) {
47
+ _syncSceneStateFromUrl(sceneObject, urlParams) {
49
48
  if (sceneObject.urlSync) {
50
49
  const urlState = {};
51
50
  const currentState = sceneObject.urlSync.getUrlState();
@@ -70,7 +69,7 @@ class UrlSyncManager {
70
69
  sceneObject.urlSync.updateFromUrl(urlState);
71
70
  }
72
71
  }
73
- forEachSceneObjectInState(sceneObject.state, (obj) => this.syncSceneStateFromUrl(obj, urlParams));
72
+ sceneObject.forEachChild((child) => this._syncSceneStateFromUrl(child, urlParams));
74
73
  }
75
74
  }
76
75
  class UniqueUrlKeyMapper {
@@ -104,7 +103,7 @@ class UniqueUrlKeyMapper {
104
103
  }
105
104
  }
106
105
  }
107
- forEachSceneObjectInState(sceneObject.state, (obj) => this.buildIndex(obj, depth + 1));
106
+ sceneObject.forEachChild((child) => this.buildIndex(child, depth + 1));
108
107
  }
109
108
  }
110
109
  function isUrlValueEqual(currentUrlValue, newUrlValue) {
@@ -1 +1 @@
1
- {"version":3,"file":"UrlSyncManager.js","sources":["../../../src/services/UrlSyncManager.ts"],"sourcesContent":["import { Location } from 'history';\nimport { isEqual } from 'lodash';\n\nimport { locationService } from '@grafana/runtime';\n\nimport { SceneObjectStateChangedEvent } from '../core/events';\nimport { SceneObject, SceneObjectUrlValue, SceneObjectUrlValues } from '../core/types';\nimport { forEachSceneObjectInState } from '../core/utils';\n\nexport class UrlSyncManager {\n private urlKeyMapper = new UniqueUrlKeyMapper();\n\n public constructor(private sceneRoot: SceneObject) {}\n\n /**\n * Updates the current scene state to match URL state.\n */\n public initSync() {\n this.sceneRoot.addActivationHandler(() => {\n const stateChangeSub = this.sceneRoot.subscribeToEvent(SceneObjectStateChangedEvent, this.onStateChanged);\n const locationListenerUnsub = locationService.getHistory().listen(this.onLocationUpdate);\n\n return () => {\n stateChangeSub.unsubscribe();\n locationListenerUnsub();\n };\n });\n\n const urlParams = locationService.getSearch();\n this.urlKeyMapper.rebuldIndex(this.sceneRoot);\n this.syncSceneStateFromUrl(this.sceneRoot, urlParams);\n }\n\n private onLocationUpdate = (location: Location) => {\n const urlParams = new URLSearchParams(location.search);\n // Rebuild key mapper index before starting sync\n this.urlKeyMapper.rebuldIndex(this.sceneRoot);\n // Sync scene state tree from url\n this.syncSceneStateFromUrl(this.sceneRoot, urlParams);\n };\n\n private onStateChanged = ({ payload }: SceneObjectStateChangedEvent) => {\n const changedObject = payload.changedObject;\n\n if (changedObject.urlSync) {\n const newUrlState = changedObject.urlSync.getUrlState();\n\n const searchParams = locationService.getSearch();\n const mappedUpdated: SceneObjectUrlValues = {};\n\n this.urlKeyMapper.rebuldIndex(this.sceneRoot);\n\n for (const [key, newUrlValue] of Object.entries(newUrlState)) {\n const uniqueKey = this.urlKeyMapper.getUniqueKey(key, changedObject);\n const currentUrlValue = searchParams.getAll(uniqueKey);\n\n if (!isUrlValueEqual(currentUrlValue, newUrlValue)) {\n mappedUpdated[uniqueKey] = newUrlValue;\n }\n }\n\n if (Object.keys(mappedUpdated).length > 0) {\n locationService.partial(mappedUpdated, true);\n }\n }\n };\n\n private syncSceneStateFromUrl(sceneObject: SceneObject, urlParams: URLSearchParams) {\n if (sceneObject.urlSync) {\n const urlState: SceneObjectUrlValues = {};\n const currentState = sceneObject.urlSync.getUrlState();\n\n for (const key of sceneObject.urlSync.getKeys()) {\n const uniqueKey = this.urlKeyMapper.getUniqueKey(key, sceneObject);\n const newValue = urlParams.getAll(uniqueKey);\n const currentValue = currentState[key];\n\n if (isUrlValueEqual(newValue, currentValue)) {\n continue;\n }\n\n if (newValue.length > 0) {\n if (Array.isArray(currentValue)) {\n urlState[key] = newValue;\n } else {\n urlState[key] = newValue[0];\n }\n } else {\n // mark this key as having no url state\n urlState[key] = null;\n }\n }\n\n if (Object.keys(urlState).length > 0) {\n sceneObject.urlSync.updateFromUrl(urlState);\n }\n }\n\n forEachSceneObjectInState(sceneObject.state, (obj) => this.syncSceneStateFromUrl(obj, urlParams));\n }\n}\n\ninterface SceneObjectWithDepth {\n sceneObject: SceneObject;\n depth: number;\n}\nclass UniqueUrlKeyMapper {\n private index = new Map<string, SceneObjectWithDepth[]>();\n\n public getUniqueKey(key: string, obj: SceneObject) {\n const objectsWithKey = this.index.get(key);\n if (!objectsWithKey) {\n throw new Error(\"Cannot find any scene object that uses the key '\" + key + \"'\");\n }\n\n const address = objectsWithKey.findIndex((o) => o.sceneObject === obj);\n if (address > 0) {\n return `${key}-${address + 1}`;\n }\n\n return key;\n }\n\n public rebuldIndex(root: SceneObject) {\n this.index.clear();\n this.buildIndex(root, 0);\n }\n\n private buildIndex(sceneObject: SceneObject, depth: number) {\n if (sceneObject.urlSync) {\n for (const key of sceneObject.urlSync.getKeys()) {\n const hit = this.index.get(key);\n if (hit) {\n hit.push({ sceneObject, depth });\n hit.sort((a, b) => a.depth - b.depth);\n } else {\n this.index.set(key, [{ sceneObject, depth }]);\n }\n }\n }\n\n forEachSceneObjectInState(sceneObject.state, (obj) => this.buildIndex(obj, depth + 1));\n }\n}\n\nexport function isUrlValueEqual(currentUrlValue: string[], newUrlValue: SceneObjectUrlValue): boolean {\n if (currentUrlValue.length === 0 && newUrlValue == null) {\n return true;\n }\n\n if (!Array.isArray(newUrlValue) && currentUrlValue?.length === 1) {\n return newUrlValue === currentUrlValue[0];\n }\n\n if (newUrlValue?.length === 0 && currentUrlValue === null) {\n return true;\n }\n\n // We have two arrays, lets compare them\n return isEqual(currentUrlValue, newUrlValue);\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"UrlSyncManager.js","sources":["../../../src/services/UrlSyncManager.ts"],"sourcesContent":["import { Location } from 'history';\nimport { isEqual } from 'lodash';\n\nimport { locationService } from '@grafana/runtime';\n\nimport { SceneObjectStateChangedEvent } from '../core/events';\nimport { SceneObject, SceneObjectUrlValue, SceneObjectUrlValues } from '../core/types';\n\nexport class UrlSyncManager {\n private urlKeyMapper = new UniqueUrlKeyMapper();\n\n public constructor(private sceneRoot: SceneObject) {}\n\n /**\n * Updates the current scene state to match URL state.\n */\n public initSync() {\n this.sceneRoot.addActivationHandler(() => {\n const stateChangeSub = this.sceneRoot.subscribeToEvent(SceneObjectStateChangedEvent, this._onStateChanged);\n const locationListenerUnsub = locationService.getHistory().listen(this._onLocationUpdate);\n\n return () => {\n stateChangeSub.unsubscribe();\n locationListenerUnsub();\n };\n });\n\n const urlParams = locationService.getSearch();\n this.urlKeyMapper.rebuldIndex(this.sceneRoot);\n this._syncSceneStateFromUrl(this.sceneRoot, urlParams);\n }\n\n private _onLocationUpdate = (location: Location) => {\n const urlParams = new URLSearchParams(location.search);\n // Rebuild key mapper index before starting sync\n this.urlKeyMapper.rebuldIndex(this.sceneRoot);\n // Sync scene state tree from url\n this._syncSceneStateFromUrl(this.sceneRoot, urlParams);\n };\n\n private _onStateChanged = ({ payload }: SceneObjectStateChangedEvent) => {\n const changedObject = payload.changedObject;\n\n if (changedObject.urlSync) {\n const newUrlState = changedObject.urlSync.getUrlState();\n\n const searchParams = locationService.getSearch();\n const mappedUpdated: SceneObjectUrlValues = {};\n\n this.urlKeyMapper.rebuldIndex(this.sceneRoot);\n\n for (const [key, newUrlValue] of Object.entries(newUrlState)) {\n const uniqueKey = this.urlKeyMapper.getUniqueKey(key, changedObject);\n const currentUrlValue = searchParams.getAll(uniqueKey);\n\n if (!isUrlValueEqual(currentUrlValue, newUrlValue)) {\n mappedUpdated[uniqueKey] = newUrlValue;\n }\n }\n\n if (Object.keys(mappedUpdated).length > 0) {\n locationService.partial(mappedUpdated, true);\n }\n }\n };\n\n private _syncSceneStateFromUrl(sceneObject: SceneObject, urlParams: URLSearchParams) {\n if (sceneObject.urlSync) {\n const urlState: SceneObjectUrlValues = {};\n const currentState = sceneObject.urlSync.getUrlState();\n\n for (const key of sceneObject.urlSync.getKeys()) {\n const uniqueKey = this.urlKeyMapper.getUniqueKey(key, sceneObject);\n const newValue = urlParams.getAll(uniqueKey);\n const currentValue = currentState[key];\n\n if (isUrlValueEqual(newValue, currentValue)) {\n continue;\n }\n\n if (newValue.length > 0) {\n if (Array.isArray(currentValue)) {\n urlState[key] = newValue;\n } else {\n urlState[key] = newValue[0];\n }\n } else {\n // mark this key as having no url state\n urlState[key] = null;\n }\n }\n\n if (Object.keys(urlState).length > 0) {\n sceneObject.urlSync.updateFromUrl(urlState);\n }\n }\n\n sceneObject.forEachChild((child) => this._syncSceneStateFromUrl(child, urlParams));\n }\n}\n\ninterface SceneObjectWithDepth {\n sceneObject: SceneObject;\n depth: number;\n}\nclass UniqueUrlKeyMapper {\n private index = new Map<string, SceneObjectWithDepth[]>();\n\n public getUniqueKey(key: string, obj: SceneObject) {\n const objectsWithKey = this.index.get(key);\n if (!objectsWithKey) {\n throw new Error(\"Cannot find any scene object that uses the key '\" + key + \"'\");\n }\n\n const address = objectsWithKey.findIndex((o) => o.sceneObject === obj);\n if (address > 0) {\n return `${key}-${address + 1}`;\n }\n\n return key;\n }\n\n public rebuldIndex(root: SceneObject) {\n this.index.clear();\n this.buildIndex(root, 0);\n }\n\n private buildIndex(sceneObject: SceneObject, depth: number) {\n if (sceneObject.urlSync) {\n for (const key of sceneObject.urlSync.getKeys()) {\n const hit = this.index.get(key);\n if (hit) {\n hit.push({ sceneObject, depth });\n hit.sort((a, b) => a.depth - b.depth);\n } else {\n this.index.set(key, [{ sceneObject, depth }]);\n }\n }\n }\n\n sceneObject.forEachChild((child) => this.buildIndex(child, depth + 1));\n }\n}\n\nexport function isUrlValueEqual(currentUrlValue: string[], newUrlValue: SceneObjectUrlValue): boolean {\n if (currentUrlValue.length === 0 && newUrlValue == null) {\n return true;\n }\n\n if (!Array.isArray(newUrlValue) && currentUrlValue?.length === 1) {\n return newUrlValue === currentUrlValue[0];\n }\n\n if (newUrlValue?.length === 0 && currentUrlValue === null) {\n return true;\n }\n\n // We have two arrays, lets compare them\n return isEqual(currentUrlValue, newUrlValue);\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"VariableValueSelectors.js","sources":["../../../../src/variables/components/VariableValueSelectors.tsx"],"sourcesContent":["import React from 'react';\n\nimport { GrafanaTheme2, VariableHide } from '@grafana/data';\nimport { selectors } from '@grafana/e2e-selectors';\nimport { Tooltip, useStyles2 } from '@grafana/ui';\n\nimport { SceneObjectBase } from '../../core/SceneObjectBase';\nimport { sceneGraph } from '../../core/sceneGraph';\nimport { SceneComponentProps, SceneObject, SceneObjectStatePlain } from '../../core/types';\nimport { SceneVariableState } from '../types';\nimport { css } from '@emotion/css';\n\nexport class VariableValueSelectors extends SceneObjectBase<SceneObjectStatePlain> {\n public static Component = VariableValueSelectorsRenderer;\n}\n\nfunction VariableValueSelectorsRenderer({ model }: SceneComponentProps<VariableValueSelectors>) {\n const variables = sceneGraph.getVariables(model)!.useState();\n const styles = useStyles2(getStyles);\n\n return (\n <>\n {variables.variables.map((variable) => (\n <VariableValueSelectWrapper key={variable.state.key} variable={variable} styles={styles} />\n ))}\n </>\n );\n}\n\nfunction VariableValueSelectWrapper({\n variable,\n styles,\n}: {\n variable: SceneObject<SceneVariableState>;\n styles: VariableLabelStyles;\n}) {\n const state = variable.useState();\n\n if (state.hide === VariableHide.hideVariable) {\n return null;\n }\n\n return (\n <div className={styles.container}>\n <VariableLabel state={state} styles={styles} />\n <variable.Component model={variable} />\n </div>\n );\n}\n\nfunction VariableLabel({ state, styles }: { state: SceneVariableState; styles: VariableLabelStyles }) {\n if (state.hide === VariableHide.hideLabel) {\n return null;\n }\n\n const elementId = `var-${state.key}`;\n const labelOrName = state.label ?? state.name;\n\n if (state.description) {\n return (\n <Tooltip content={state.description} placement={'bottom'}>\n <label\n className={styles.variableLabel}\n data-testid={selectors.pages.Dashboard.SubMenu.submenuItemLabels(labelOrName)}\n htmlFor={elementId}\n >\n {labelOrName}\n </label>\n </Tooltip>\n );\n }\n\n return (\n <label\n className={styles.variableLabel}\n data-testid={selectors.pages.Dashboard.SubMenu.submenuItemLabels(labelOrName)}\n htmlFor={elementId}\n >\n {labelOrName}\n </label>\n );\n}\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n container: css({\n display: 'flex',\n }),\n variableLabel: css({\n background: theme.isDark ? theme.colors.background.primary : theme.colors.background.secondary,\n display: `flex`,\n alignItems: 'center',\n padding: theme.spacing(0, 1),\n fontWeight: theme.typography.fontWeightMedium,\n fontSize: theme.typography.bodySmall.fontSize,\n height: theme.spacing(theme.components.height.md),\n lineHeight: theme.spacing(theme.components.height.md),\n borderRadius: theme.shape.borderRadius(1),\n border: `1px solid ${theme.components.input.borderColor}`,\n position: 'relative',\n // To make the border line up with the input border\n right: -1,\n }),\n});\n\ntype VariableLabelStyles = ReturnType<typeof getStyles>;\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"VariableValueSelectors.js","sources":["../../../../src/variables/components/VariableValueSelectors.tsx"],"sourcesContent":["import React from 'react';\n\nimport { GrafanaTheme2, VariableHide } from '@grafana/data';\nimport { selectors } from '@grafana/e2e-selectors';\nimport { Tooltip, useStyles2 } from '@grafana/ui';\n\nimport { SceneObjectBase } from '../../core/SceneObjectBase';\nimport { sceneGraph } from '../../core/sceneGraph';\nimport { SceneComponentProps, SceneObject, SceneObjectState } from '../../core/types';\nimport { SceneVariableState } from '../types';\nimport { css } from '@emotion/css';\n\nexport class VariableValueSelectors extends SceneObjectBase<SceneObjectState> {\n public static Component = VariableValueSelectorsRenderer;\n}\n\nfunction VariableValueSelectorsRenderer({ model }: SceneComponentProps<VariableValueSelectors>) {\n const variables = sceneGraph.getVariables(model)!.useState();\n const styles = useStyles2(getStyles);\n\n return (\n <>\n {variables.variables.map((variable) => (\n <VariableValueSelectWrapper key={variable.state.key} variable={variable} styles={styles} />\n ))}\n </>\n );\n}\n\nfunction VariableValueSelectWrapper({\n variable,\n styles,\n}: {\n variable: SceneObject<SceneVariableState>;\n styles: VariableLabelStyles;\n}) {\n const state = variable.useState();\n\n if (state.hide === VariableHide.hideVariable) {\n return null;\n }\n\n return (\n <div className={styles.container}>\n <VariableLabel state={state} styles={styles} />\n <variable.Component model={variable} />\n </div>\n );\n}\n\nfunction VariableLabel({ state, styles }: { state: SceneVariableState; styles: VariableLabelStyles }) {\n if (state.hide === VariableHide.hideLabel) {\n return null;\n }\n\n const elementId = `var-${state.key}`;\n const labelOrName = state.label ?? state.name;\n\n if (state.description) {\n return (\n <Tooltip content={state.description} placement={'bottom'}>\n <label\n className={styles.variableLabel}\n data-testid={selectors.pages.Dashboard.SubMenu.submenuItemLabels(labelOrName)}\n htmlFor={elementId}\n >\n {labelOrName}\n </label>\n </Tooltip>\n );\n }\n\n return (\n <label\n className={styles.variableLabel}\n data-testid={selectors.pages.Dashboard.SubMenu.submenuItemLabels(labelOrName)}\n htmlFor={elementId}\n >\n {labelOrName}\n </label>\n );\n}\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n container: css({\n display: 'flex',\n }),\n variableLabel: css({\n background: theme.isDark ? theme.colors.background.primary : theme.colors.background.secondary,\n display: `flex`,\n alignItems: 'center',\n padding: theme.spacing(0, 1),\n fontWeight: theme.typography.fontWeightMedium,\n fontSize: theme.typography.bodySmall.fontSize,\n height: theme.spacing(theme.components.height.md),\n lineHeight: theme.spacing(theme.components.height.md),\n borderRadius: theme.shape.borderRadius(1),\n border: `1px solid ${theme.components.input.borderColor}`,\n position: 'relative',\n // To make the border line up with the input border\n right: -1,\n }),\n});\n\ntype VariableLabelStyles = ReturnType<typeof getStyles>;\n"],"names":[],"mappings":"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"}
@@ -1,15 +1,8 @@
1
- import { LoadingState, getDefaultTimeRange } from '@grafana/data';
2
1
  import { SceneDataNode } from '../../core/SceneDataNode.js';
3
2
  import { SceneObjectBase } from '../../core/SceneObjectBase.js';
4
3
  import { SceneTimeRange } from '../../core/SceneTimeRange.js';
5
4
 
6
- const EmptyDataNode = new SceneDataNode({
7
- data: {
8
- state: LoadingState.Done,
9
- series: [],
10
- timeRange: getDefaultTimeRange()
11
- }
12
- });
5
+ const EmptyDataNode = new SceneDataNode();
13
6
  const DefaultTimeRange = new SceneTimeRange();
14
7
  class EmptyVariableSetImpl extends SceneObjectBase {
15
8
  constructor() {
@@ -1 +1 @@
1
- {"version":3,"file":"defaults.js","sources":["../../../../src/variables/interpolation/defaults.ts"],"sourcesContent":["import { getDefaultTimeRange, LoadingState } from '@grafana/data';\nimport { SceneDataNode } from '../../core/SceneDataNode';\nimport { SceneObjectBase } from '../../core/SceneObjectBase';\nimport { SceneTimeRange } from '../../core/SceneTimeRange';\nimport { SceneVariable, SceneVariables, SceneVariableSetState, SceneVariableState } from '../types';\n\nexport const EmptyDataNode = new SceneDataNode({\n data: {\n state: LoadingState.Done,\n series: [],\n timeRange: getDefaultTimeRange(),\n },\n});\n\nexport const DefaultTimeRange = new SceneTimeRange();\n\n/**\n * Since this is used from sceneGraph.getVariables we cannot reference SceneVariableSet here as it would create a circular reference\n */\nexport class EmptyVariableSetImpl extends SceneObjectBase<SceneVariableSetState> implements SceneVariables {\n public constructor() {\n super({ variables: [] });\n }\n\n public getByName(name: string): SceneVariable<SceneVariableState> | undefined {\n return undefined;\n }\n\n public isVariableLoadingOrWaitingToUpdate(variable: SceneVariable<SceneVariableState>): boolean {\n return false;\n }\n}\n\nexport const EmptyVariableSet = new EmptyVariableSetImpl();\n"],"names":[],"mappings":";;;;;AAMa,MAAA,aAAA,GAAgB,IAAI,aAAc,CAAA;AAAA,EAC7C,IAAM,EAAA;AAAA,IACJ,OAAO,YAAa,CAAA,IAAA;AAAA,IACpB,QAAQ,EAAC;AAAA,IACT,WAAW,mBAAoB,EAAA;AAAA,GACjC;AACF,CAAC,EAAA;AAEY,MAAA,gBAAA,GAAmB,IAAI,cAAe,GAAA;AAK5C,MAAM,6BAA6B,eAAiE,CAAA;AAAA,EAClG,WAAc,GAAA;AACnB,IAAA,KAAA,CAAM,EAAE,SAAA,EAAW,EAAC,EAAG,CAAA,CAAA;AAAA,GACzB;AAAA,EAEO,UAAU,IAA6D,EAAA;AAC5E,IAAO,OAAA,KAAA,CAAA,CAAA;AAAA,GACT;AAAA,EAEO,mCAAmC,QAAsD,EAAA;AAC9F,IAAO,OAAA,KAAA,CAAA;AAAA,GACT;AACF,CAAA;AAEa,MAAA,gBAAA,GAAmB,IAAI,oBAAqB;;;;"}
1
+ {"version":3,"file":"defaults.js","sources":["../../../../src/variables/interpolation/defaults.ts"],"sourcesContent":["import { SceneDataNode } from '../../core/SceneDataNode';\nimport { SceneObjectBase } from '../../core/SceneObjectBase';\nimport { SceneTimeRange } from '../../core/SceneTimeRange';\nimport { SceneVariable, SceneVariables, SceneVariableSetState, SceneVariableState } from '../types';\n\nexport const EmptyDataNode = new SceneDataNode();\nexport const DefaultTimeRange = new SceneTimeRange();\n\n/**\n * Since this is used from sceneGraph.getVariables we cannot reference SceneVariableSet here as it would create a circular reference\n */\nexport class EmptyVariableSetImpl extends SceneObjectBase<SceneVariableSetState> implements SceneVariables {\n public constructor() {\n super({ variables: [] });\n }\n\n public getByName(name: string): SceneVariable<SceneVariableState> | undefined {\n return undefined;\n }\n\n public isVariableLoadingOrWaitingToUpdate(variable: SceneVariable<SceneVariableState>): boolean {\n return false;\n }\n}\n\nexport const EmptyVariableSet = new EmptyVariableSetImpl();\n"],"names":[],"mappings":";;;;AAKa,MAAA,aAAA,GAAgB,IAAI,aAAc,GAAA;AAClC,MAAA,gBAAA,GAAmB,IAAI,cAAe,GAAA;AAK5C,MAAM,6BAA6B,eAAiE,CAAA;AAAA,EAClG,WAAc,GAAA;AACnB,IAAA,KAAA,CAAM,EAAE,SAAA,EAAW,EAAC,EAAG,CAAA,CAAA;AAAA,GACzB;AAAA,EAEO,UAAU,IAA6D,EAAA;AAC5E,IAAO,OAAA,KAAA,CAAA,CAAA;AAAA,GACT;AAAA,EAEO,mCAAmC,QAAsD,EAAA;AAC9F,IAAO,OAAA,KAAA,CAAA;AAAA,GACT;AACF,CAAA;AAEa,MAAA,gBAAA,GAAmB,IAAI,oBAAqB;;;;"}