@grafana/scenes 0.29.1 → 0.29.2
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.
- package/CHANGELOG.md +12 -0
- package/dist/esm/core/SceneObjectBase.js +38 -9
- package/dist/esm/core/SceneObjectBase.js.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.js +38 -9
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
# v0.29.2 (Wed Sep 06 2023)
|
|
2
|
+
|
|
3
|
+
#### 🐛 Bug Fix
|
|
4
|
+
|
|
5
|
+
- SceneObject: Support changing $data, $timeRange and $variables during the active phase [#324](https://github.com/grafana/scenes/pull/324) ([@torkelo](https://github.com/torkelo))
|
|
6
|
+
|
|
7
|
+
#### Authors: 1
|
|
8
|
+
|
|
9
|
+
- Torkel Ödegaard ([@torkelo](https://github.com/torkelo))
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
1
13
|
# v0.29.1 (Tue Sep 05 2023)
|
|
2
14
|
|
|
3
15
|
#### 🐛 Bug Fix
|
|
@@ -26,7 +26,7 @@ class SceneObjectBase {
|
|
|
26
26
|
constructor(state) {
|
|
27
27
|
this._isActive = false;
|
|
28
28
|
this._activationHandlers = [];
|
|
29
|
-
this._deactivationHandlers =
|
|
29
|
+
this._deactivationHandlers = /* @__PURE__ */ new Map();
|
|
30
30
|
this._subs = new Subscription();
|
|
31
31
|
this._refCount = 0;
|
|
32
32
|
if (!state.key) {
|
|
@@ -81,6 +81,7 @@ class SceneObjectBase {
|
|
|
81
81
|
const newState = __spreadValues(__spreadValues({}, this._state), update);
|
|
82
82
|
this._state = Object.freeze(newState);
|
|
83
83
|
this._setParent();
|
|
84
|
+
this._handleActivationOfChangedStateProps(prevState, newState);
|
|
84
85
|
this.publishEvent(
|
|
85
86
|
new SceneObjectStateChangedEvent({
|
|
86
87
|
prevState,
|
|
@@ -91,6 +92,32 @@ class SceneObjectBase {
|
|
|
91
92
|
true
|
|
92
93
|
);
|
|
93
94
|
}
|
|
95
|
+
_handleActivationOfChangedStateProps(prevState, newState) {
|
|
96
|
+
if (!this.isActive) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
if (prevState.$data !== newState.$data) {
|
|
100
|
+
this._handleChangedStateActivation(prevState.$data, newState.$data);
|
|
101
|
+
}
|
|
102
|
+
if (prevState.$variables !== newState.$variables) {
|
|
103
|
+
this._handleChangedStateActivation(prevState.$variables, newState.$variables);
|
|
104
|
+
}
|
|
105
|
+
if (prevState.$timeRange !== newState.$timeRange) {
|
|
106
|
+
this._handleChangedStateActivation(prevState.$timeRange, newState.$timeRange);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
_handleChangedStateActivation(oldValue, newValue) {
|
|
110
|
+
if (oldValue) {
|
|
111
|
+
const deactivationHandler = this._deactivationHandlers.get(oldValue);
|
|
112
|
+
if (deactivationHandler) {
|
|
113
|
+
deactivationHandler();
|
|
114
|
+
this._deactivationHandlers.delete(oldValue);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (newValue) {
|
|
118
|
+
this._deactivationHandlers.set(newValue, newValue.activate());
|
|
119
|
+
}
|
|
120
|
+
}
|
|
94
121
|
publishEvent(event, bubble) {
|
|
95
122
|
this._events.publish(event);
|
|
96
123
|
if (bubble && this.parent) {
|
|
@@ -104,22 +131,22 @@ class SceneObjectBase {
|
|
|
104
131
|
this._isActive = true;
|
|
105
132
|
const { $data, $variables, $timeRange, $behaviors } = this.state;
|
|
106
133
|
if ($timeRange && !$timeRange.isActive) {
|
|
107
|
-
this._deactivationHandlers.
|
|
134
|
+
this._deactivationHandlers.set($timeRange, $timeRange.activate());
|
|
108
135
|
}
|
|
109
136
|
if ($variables && !$variables.isActive) {
|
|
110
|
-
this._deactivationHandlers.
|
|
137
|
+
this._deactivationHandlers.set($variables, $variables.activate());
|
|
111
138
|
}
|
|
112
139
|
if ($data && !$data.isActive) {
|
|
113
|
-
this._deactivationHandlers.
|
|
140
|
+
this._deactivationHandlers.set($data, $data.activate());
|
|
114
141
|
}
|
|
115
142
|
if ($behaviors) {
|
|
116
143
|
for (const behavior of $behaviors) {
|
|
117
144
|
if (behavior instanceof SceneObjectBase) {
|
|
118
|
-
this._deactivationHandlers.
|
|
145
|
+
this._deactivationHandlers.set(behavior, behavior.activate());
|
|
119
146
|
} else if (typeof behavior === "function") {
|
|
120
147
|
const deactivationHandler = behavior(this);
|
|
121
148
|
if (deactivationHandler) {
|
|
122
|
-
this._deactivationHandlers.
|
|
149
|
+
this._deactivationHandlers.set(behavior, deactivationHandler);
|
|
123
150
|
}
|
|
124
151
|
}
|
|
125
152
|
}
|
|
@@ -127,7 +154,7 @@ class SceneObjectBase {
|
|
|
127
154
|
this._activationHandlers.forEach((handler) => {
|
|
128
155
|
const result = handler();
|
|
129
156
|
if (result) {
|
|
130
|
-
this._deactivationHandlers.
|
|
157
|
+
this._deactivationHandlers.set(result, result);
|
|
131
158
|
}
|
|
132
159
|
});
|
|
133
160
|
}
|
|
@@ -152,8 +179,10 @@ class SceneObjectBase {
|
|
|
152
179
|
}
|
|
153
180
|
_internalDeactivate() {
|
|
154
181
|
this._isActive = false;
|
|
155
|
-
this._deactivationHandlers.
|
|
156
|
-
|
|
182
|
+
for (let handler of this._deactivationHandlers.values()) {
|
|
183
|
+
handler();
|
|
184
|
+
}
|
|
185
|
+
this._deactivationHandlers.clear();
|
|
157
186
|
this._events.removeAllListeners();
|
|
158
187
|
this._subs.unsubscribe();
|
|
159
188
|
this._subs = new Subscription();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SceneObjectBase.js","sources":["../../../src/core/SceneObjectBase.tsx"],"sourcesContent":["import { useEffect, useState } from 'react';\nimport { Subscription, Unsubscribable } from 'rxjs';\nimport { v4 as uuidv4 } from 'uuid';\n\nimport { BusEvent, BusEventHandler, BusEventType, EventBus, EventBusSrv } from '@grafana/data';\nimport {\n SceneObject,\n SceneComponent,\n SceneObjectUrlSyncHandler,\n SceneStateChangedHandler,\n SceneActivationHandler,\n SceneDeactivationHandler,\n CancelActivationHandler,\n SceneObjectState,\n} from './types';\n\nimport { SceneComponentWrapper } from './SceneComponentWrapper';\nimport { SceneObjectStateChangedEvent } from './events';\nimport { cloneSceneObject } from './sceneGraph/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 _activationHandlers: SceneActivationHandler[] = [];\n private _deactivationHandlers: SceneDeactivationHandler[] = [];\n\n protected _events?: EventBus;\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._events = new EventBusSrv();\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) => {\n // If we already have a parent and it's not this, then we likely have a bug\n if (child._parent && child._parent !== this) {\n console.warn(\n 'SceneObject already has a parent set that is different from the new parent. You cannot share the same SceneObject instance in multiple scenes or in multiple different places of the same scene graph. Use SceneObject.clone() to duplicate a SceneObject or store a state key reference and use sceneGraph.findObject to locate it.',\n child,\n this\n );\n }\n child._parent = this;\n });\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, $behaviors } = 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 if ($behaviors) {\n for (const behavior of $behaviors) {\n if (behavior instanceof SceneObjectBase) {\n this._deactivationHandlers.push(behavior.activate());\n } else if (typeof behavior === 'function') {\n const deactivationHandler = behavior(this);\n if (deactivationHandler) {\n this._deactivationHandlers.push();\n }\n }\n }\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 [_, setState] = useState<TState>(model.state);\n const stateAtFirstRender = model.state;\n\n useEffect(() => {\n const s = model.subscribeToState(setState);\n\n // Re-render component if the state changed between first render and useEffect (mount)\n if (model.state !== stateAtFirstRender) {\n setState(model.state);\n }\n\n return () => s.unsubscribe();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [model]);\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, useState } from 'react';\nimport { Subscription, Unsubscribable } from 'rxjs';\nimport { v4 as uuidv4 } from 'uuid';\n\nimport { BusEvent, BusEventHandler, BusEventType, EventBus, EventBusSrv } from '@grafana/data';\nimport {\n SceneObject,\n SceneComponent,\n SceneObjectUrlSyncHandler,\n SceneStateChangedHandler,\n SceneActivationHandler,\n SceneDeactivationHandler,\n CancelActivationHandler,\n SceneObjectState,\n} from './types';\n\nimport { SceneComponentWrapper } from './SceneComponentWrapper';\nimport { SceneObjectStateChangedEvent } from './events';\nimport { cloneSceneObject } from './sceneGraph/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 _activationHandlers: SceneActivationHandler[] = [];\n private _deactivationHandlers = new Map<object, SceneDeactivationHandler>();\n\n protected _events?: EventBus;\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._events = new EventBusSrv();\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) => {\n // If we already have a parent and it's not this, then we likely have a bug\n if (child._parent && child._parent !== this) {\n console.warn(\n 'SceneObject already has a parent set that is different from the new parent. You cannot share the same SceneObject instance in multiple scenes or in multiple different places of the same scene graph. Use SceneObject.clone() to duplicate a SceneObject or store a state key reference and use sceneGraph.findObject to locate it.',\n child,\n this\n );\n }\n child._parent = this;\n });\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 this._setParent();\n\n // Handles cases when $data, $timeRange, or $variables are changed\n this._handleActivationOfChangedStateProps(prevState, newState);\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 /**\n * This handles activation and deactivation of $data, $timeRange and $variables when they change\n * during the active phase of the scene object.\n */\n private _handleActivationOfChangedStateProps(prevState: TState, newState: TState) {\n if (!this.isActive) {\n return;\n }\n\n if (prevState.$data !== newState.$data) {\n this._handleChangedStateActivation(prevState.$data, newState.$data);\n }\n\n if (prevState.$variables !== newState.$variables) {\n this._handleChangedStateActivation(prevState.$variables, newState.$variables);\n }\n\n if (prevState.$timeRange !== newState.$timeRange) {\n this._handleChangedStateActivation(prevState.$timeRange, newState.$timeRange);\n }\n }\n\n private _handleChangedStateActivation(oldValue: SceneObject | undefined, newValue: SceneObject | undefined) {\n if (oldValue) {\n const deactivationHandler = this._deactivationHandlers.get(oldValue);\n if (deactivationHandler) {\n deactivationHandler();\n this._deactivationHandlers.delete(oldValue);\n }\n }\n\n if (newValue) {\n this._deactivationHandlers.set(newValue, newValue.activate());\n }\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, $behaviors } = this.state;\n\n if ($timeRange && !$timeRange.isActive) {\n this._deactivationHandlers.set($timeRange, $timeRange.activate());\n }\n\n if ($variables && !$variables.isActive) {\n this._deactivationHandlers.set($variables, $variables.activate());\n }\n\n if ($data && !$data.isActive) {\n this._deactivationHandlers.set($data, $data.activate());\n }\n\n if ($behaviors) {\n for (const behavior of $behaviors) {\n if (behavior instanceof SceneObjectBase) {\n this._deactivationHandlers.set(behavior, behavior.activate());\n } else if (typeof behavior === 'function') {\n const deactivationHandler = behavior(this);\n if (deactivationHandler) {\n this._deactivationHandlers.set(behavior, deactivationHandler);\n }\n }\n }\n }\n\n this._activationHandlers.forEach((handler) => {\n const result = handler();\n if (result) {\n this._deactivationHandlers.set(result, 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 for (let handler of this._deactivationHandlers.values()) {\n handler();\n }\n\n this._deactivationHandlers.clear();\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 [_, setState] = useState<TState>(model.state);\n const stateAtFirstRender = model.state;\n\n useEffect(() => {\n const s = model.subscribeToState(setState);\n\n // Re-render component if the state changed between first render and useEffect (mount)\n if (model.state !== stateAtFirstRender) {\n setState(model.state);\n }\n\n return () => s.unsubscribe();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [model]);\n\n return model.state;\n}\n"],"names":["uuidv4"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAqBO,MAAe,eAEtB,CAAA;AAAA,EAcS,YAAY,KAAe,EAAA;AAblC,IAAA,IAAA,CAAQ,SAAY,GAAA,KAAA,CAAA;AAEpB,IAAA,IAAA,CAAQ,sBAAgD,EAAC,CAAA;AACzD,IAAQ,IAAA,CAAA,qBAAA,uBAA4B,GAAsC,EAAA,CAAA;AAI1E,IAAU,IAAA,CAAA,KAAA,GAAQ,IAAI,YAAa,EAAA,CAAA;AACnC,IAAA,IAAA,CAAU,SAAY,GAAA,CAAA,CAAA;AAMpB,IAAI,IAAA,CAAC,MAAM,GAAK,EAAA;AACd,MAAA,KAAA,CAAM,MAAMA,EAAO,EAAA,CAAA;AAAA,KACrB;AAEA,IAAK,IAAA,CAAA,OAAA,GAAU,IAAI,WAAY,EAAA,CAAA;AAE/B,IAAK,IAAA,CAAA,MAAA,GAAS,MAAO,CAAA,MAAA,CAAO,KAAK,CAAA,CAAA;AACjC,IAAA,IAAA,CAAK,UAAW,EAAA,CAAA;AAAA,GAClB;AAAA,EAGA,IAAW,KAAgB,GAAA;AACzB,IAAA,OAAO,IAAK,CAAA,MAAA,CAAA;AAAA,GACd;AAAA,EAGA,IAAW,QAAoB,GAAA;AAC7B,IAAA,OAAO,IAAK,CAAA,SAAA,CAAA;AAAA,GACd;AAAA,EAGA,IAAW,MAAkC,GAAA;AAC3C,IAAA,OAAO,IAAK,CAAA,OAAA,CAAA;AAAA,GACd;AAAA,EAGA,IAAW,kBAAoE,GAAA;AAC7E,IAAA,OAAO,IAAK,CAAA,mBAAA,CAAA;AAAA,GACd;AAAA,EAGA,IAAW,OAAiD,GAAA;AAC1D,IAAA,OAAO,IAAK,CAAA,QAAA,CAAA;AAAA,GACd;AAAA,EAMA,IAAW,SAAkC,GAAA;AAC3C,IAAO,OAAA,qBAAA,CAAA;AAAA,GACT;AAAA,EAEQ,UAAa,GAAA;AACnB,IAAK,IAAA,CAAA,YAAA,CAAa,CAAC,KAAU,KAAA;AAE3B,MAAA,IAAI,KAAM,CAAA,OAAA,IAAW,KAAM,CAAA,OAAA,KAAY,IAAM,EAAA;AAC3C,QAAQ,OAAA,CAAA,IAAA;AAAA,UACN,sUAAA;AAAA,UACA,KAAA;AAAA,UACA,IAAA;AAAA,SACF,CAAA;AAAA,OACF;AACA,MAAA,KAAA,CAAM,OAAU,GAAA,IAAA,CAAA;AAAA,KACjB,CAAA,CAAA;AAAA,GACH;AAAA,EAKO,iBAAiB,OAA2D,EAAA;AACjF,IAAA,OAAO,IAAK,CAAA,OAAA,CAAS,SAAU,CAAA,4BAAA,EAA8B,CAAC,KAAU,KAAA;AACtE,MAAI,IAAA,KAAA,CAAM,OAAQ,CAAA,aAAA,KAAkB,IAAM,EAAA;AACxC,QAAA,OAAA,CAAQ,KAAM,CAAA,OAAA,CAAQ,QAAoB,EAAA,KAAA,CAAM,QAAQ,SAAmB,CAAA,CAAA;AAAA,OAC7E;AAAA,KACD,CAAA,CAAA;AAAA,GACH;AAAA,EAKO,gBAAA,CAAqC,WAA4B,OAA6C,EAAA;AACnH,IAAA,OAAO,IAAK,CAAA,OAAA,CAAS,SAAU,CAAA,SAAA,EAAW,OAAO,CAAA,CAAA;AAAA,GACnD;AAAA,EAEO,SAAS,MAAyB,EAAA;AACvC,IAAA,MAAM,YAAY,IAAK,CAAA,MAAA,CAAA;AACvB,IAAM,MAAA,QAAA,GAAmB,cACpB,CAAA,cAAA,CAAA,EAAA,EAAA,IAAA,CAAK,MACL,CAAA,EAAA,MAAA,CAAA,CAAA;AAGL,IAAK,IAAA,CAAA,MAAA,GAAS,MAAO,CAAA,MAAA,CAAO,QAAQ,CAAA,CAAA;AACpC,IAAA,IAAA,CAAK,UAAW,EAAA,CAAA;AAGhB,IAAK,IAAA,CAAA,oCAAA,CAAqC,WAAW,QAAQ,CAAA,CAAA;AAG7D,IAAK,IAAA,CAAA,YAAA;AAAA,MACH,IAAI,4BAA6B,CAAA;AAAA,QAC/B,SAAA;AAAA,QACA,QAAA;AAAA,QACA,aAAe,EAAA,MAAA;AAAA,QACf,aAAe,EAAA,IAAA;AAAA,OAChB,CAAA;AAAA,MACD,IAAA;AAAA,KACF,CAAA;AAAA,GACF;AAAA,EAMQ,oCAAA,CAAqC,WAAmB,QAAkB,EAAA;AAChF,IAAI,IAAA,CAAC,KAAK,QAAU,EAAA;AAClB,MAAA,OAAA;AAAA,KACF;AAEA,IAAI,IAAA,SAAA,CAAU,KAAU,KAAA,QAAA,CAAS,KAAO,EAAA;AACtC,MAAA,IAAA,CAAK,6BAA8B,CAAA,SAAA,CAAU,KAAO,EAAA,QAAA,CAAS,KAAK,CAAA,CAAA;AAAA,KACpE;AAEA,IAAI,IAAA,SAAA,CAAU,UAAe,KAAA,QAAA,CAAS,UAAY,EAAA;AAChD,MAAA,IAAA,CAAK,6BAA8B,CAAA,SAAA,CAAU,UAAY,EAAA,QAAA,CAAS,UAAU,CAAA,CAAA;AAAA,KAC9E;AAEA,IAAI,IAAA,SAAA,CAAU,UAAe,KAAA,QAAA,CAAS,UAAY,EAAA;AAChD,MAAA,IAAA,CAAK,6BAA8B,CAAA,SAAA,CAAU,UAAY,EAAA,QAAA,CAAS,UAAU,CAAA,CAAA;AAAA,KAC9E;AAAA,GACF;AAAA,EAEQ,6BAAA,CAA8B,UAAmC,QAAmC,EAAA;AAC1G,IAAA,IAAI,QAAU,EAAA;AACZ,MAAA,MAAM,mBAAsB,GAAA,IAAA,CAAK,qBAAsB,CAAA,GAAA,CAAI,QAAQ,CAAA,CAAA;AACnE,MAAA,IAAI,mBAAqB,EAAA;AACvB,QAAoB,mBAAA,EAAA,CAAA;AACpB,QAAK,IAAA,CAAA,qBAAA,CAAsB,OAAO,QAAQ,CAAA,CAAA;AAAA,OAC5C;AAAA,KACF;AAEA,IAAA,IAAI,QAAU,EAAA;AACZ,MAAA,IAAA,CAAK,qBAAsB,CAAA,GAAA,CAAI,QAAU,EAAA,QAAA,CAAS,UAAU,CAAA,CAAA;AAAA,KAC9D;AAAA,GACF;AAAA,EAKO,YAAA,CAAa,OAAiB,MAAkB,EAAA;AACrD,IAAK,IAAA,CAAA,OAAA,CAAS,QAAQ,KAAK,CAAA,CAAA;AAE3B,IAAI,IAAA,MAAA,IAAU,KAAK,MAAQ,EAAA;AACzB,MAAK,IAAA,CAAA,MAAA,CAAO,YAAa,CAAA,KAAA,EAAO,MAAM,CAAA,CAAA;AAAA,KACxC;AAAA,GACF;AAAA,EAEO,OAAuB,GAAA;AAC5B,IAAA,OAAO,CAAC,IAAK,CAAA,OAAA,GAAU,IAAO,GAAA,IAAA,CAAK,QAAQ,OAAQ,EAAA,CAAA;AAAA,GACrD;AAAA,EAEQ,iBAAoB,GAAA;AAC1B,IAAA,IAAA,CAAK,SAAY,GAAA,IAAA,CAAA;AAEjB,IAAA,MAAM,EAAE,KAAO,EAAA,UAAA,EAAY,UAAY,EAAA,UAAA,KAAe,IAAK,CAAA,KAAA,CAAA;AAE3D,IAAI,IAAA,UAAA,IAAc,CAAC,UAAA,CAAW,QAAU,EAAA;AACtC,MAAA,IAAA,CAAK,qBAAsB,CAAA,GAAA,CAAI,UAAY,EAAA,UAAA,CAAW,UAAU,CAAA,CAAA;AAAA,KAClE;AAEA,IAAI,IAAA,UAAA,IAAc,CAAC,UAAA,CAAW,QAAU,EAAA;AACtC,MAAA,IAAA,CAAK,qBAAsB,CAAA,GAAA,CAAI,UAAY,EAAA,UAAA,CAAW,UAAU,CAAA,CAAA;AAAA,KAClE;AAEA,IAAI,IAAA,KAAA,IAAS,CAAC,KAAA,CAAM,QAAU,EAAA;AAC5B,MAAA,IAAA,CAAK,qBAAsB,CAAA,GAAA,CAAI,KAAO,EAAA,KAAA,CAAM,UAAU,CAAA,CAAA;AAAA,KACxD;AAEA,IAAA,IAAI,UAAY,EAAA;AACd,MAAA,KAAA,MAAW,YAAY,UAAY,EAAA;AACjC,QAAA,IAAI,oBAAoB,eAAiB,EAAA;AACvC,UAAA,IAAA,CAAK,qBAAsB,CAAA,GAAA,CAAI,QAAU,EAAA,QAAA,CAAS,UAAU,CAAA,CAAA;AAAA,SAC9D,MAAA,IAAW,OAAO,QAAA,KAAa,UAAY,EAAA;AACzC,UAAM,MAAA,mBAAA,GAAsB,SAAS,IAAI,CAAA,CAAA;AACzC,UAAA,IAAI,mBAAqB,EAAA;AACvB,YAAK,IAAA,CAAA,qBAAA,CAAsB,GAAI,CAAA,QAAA,EAAU,mBAAmB,CAAA,CAAA;AAAA,WAC9D;AAAA,SACF;AAAA,OACF;AAAA,KACF;AAEA,IAAK,IAAA,CAAA,mBAAA,CAAoB,OAAQ,CAAA,CAAC,OAAY,KAAA;AAC5C,MAAA,MAAM,SAAS,OAAQ,EAAA,CAAA;AACvB,MAAA,IAAI,MAAQ,EAAA;AACV,QAAK,IAAA,CAAA,qBAAA,CAAsB,GAAI,CAAA,MAAA,EAAQ,MAAM,CAAA,CAAA;AAAA,OAC/C;AAAA,KACD,CAAA,CAAA;AAAA,GACH;AAAA,EAOO,QAAoC,GAAA;AACzC,IAAI,IAAA,CAAC,KAAK,QAAU,EAAA;AAClB,MAAA,IAAA,CAAK,iBAAkB,EAAA,CAAA;AAAA,KACzB;AAEA,IAAK,IAAA,CAAA,SAAA,EAAA,CAAA;AAEL,IAAA,IAAI,MAAS,GAAA,KAAA,CAAA;AAEb,IAAA,OAAO,MAAM;AACX,MAAK,IAAA,CAAA,SAAA,EAAA,CAAA;AAEL,MAAA,IAAI,MAAQ,EAAA;AACV,QAAA,MAAM,GAAM,GAAA,CAAA,2EAAA,CAAA,CAAA;AACZ,QAAQ,OAAA,CAAA,KAAA,CAAM,KAAK,IAAI,CAAA,CAAA;AACvB,QAAM,MAAA,IAAI,MAAM,GAAG,CAAA,CAAA;AAAA,OACrB;AAEA,MAAS,MAAA,GAAA,IAAA,CAAA;AAET,MAAI,IAAA,IAAA,CAAK,cAAc,CAAG,EAAA;AACxB,QAAA,IAAA,CAAK,mBAAoB,EAAA,CAAA;AAAA,OAC3B;AAAA,KACF,CAAA;AAAA,GACF;AAAA,EAMQ,mBAA4B,GAAA;AAClC,IAAA,IAAA,CAAK,SAAY,GAAA,KAAA,CAAA;AAEjB,IAAA,KAAA,IAAS,OAAW,IAAA,IAAA,CAAK,qBAAsB,CAAA,MAAA,EAAU,EAAA;AACvD,MAAQ,OAAA,EAAA,CAAA;AAAA,KACV;AAEA,IAAA,IAAA,CAAK,sBAAsB,KAAM,EAAA,CAAA;AAGjC,IAAA,IAAA,CAAK,QAAS,kBAAmB,EAAA,CAAA;AACjC,IAAA,IAAA,CAAK,MAAM,WAAY,EAAA,CAAA;AACvB,IAAK,IAAA,CAAA,KAAA,GAAQ,IAAI,YAAa,EAAA,CAAA;AAAA,GAChC;AAAA,EAKO,QAAW,GAAA;AAEhB,IAAA,OAAO,oBAAoB,IAAI,CAAA,CAAA;AAAA,GACjC;AAAA,EAGO,WAAoB,GAAA;AACzB,IAAK,IAAA,CAAA,QAAA,CAAS,EAAE,CAAA,CAAA;AAAA,GAClB;AAAA,EAKO,MAAM,SAAmC,EAAA;AAC9C,IAAO,OAAA,gBAAA,CAAiB,MAAM,SAAS,CAAA,CAAA;AAAA,GACzC;AAAA,EAMO,qBAAqB,OAAiC,EAAA;AAC3D,IAAK,IAAA,CAAA,mBAAA,CAAoB,KAAK,OAAO,CAAA,CAAA;AAAA,GACvC;AAAA,EAMO,aAAa,QAA4C,EAAA;AAC9D,IAAA,KAAA,MAAW,SAAa,IAAA,MAAA,CAAO,MAAO,CAAA,IAAA,CAAK,KAAK,CAAG,EAAA;AACjD,MAAA,IAAI,qBAAqB,eAAiB,EAAA;AACxC,QAAA,QAAA,CAAS,SAAS,CAAA,CAAA;AAAA,OACpB;AAEA,MAAI,IAAA,KAAA,CAAM,OAAQ,CAAA,SAAS,CAAG,EAAA;AAC5B,QAAA,KAAA,MAAW,SAAS,SAAW,EAAA;AAC7B,UAAA,IAAI,iBAAiB,eAAiB,EAAA;AACpC,YAAA,QAAA,CAAS,KAAK,CAAA,CAAA;AAAA,WAChB;AAAA,SACF;AAAA,OACF;AAAA,KACF;AAAA,GACF;AACF,CAAA;AAMA,SAAS,oBAAqD,KAAwC,EAAA;AACpG,EAAA,MAAM,CAAC,CAAG,EAAA,QAAQ,CAAI,GAAA,QAAA,CAAiB,MAAM,KAAK,CAAA,CAAA;AAClD,EAAA,MAAM,qBAAqB,KAAM,CAAA,KAAA,CAAA;AAEjC,EAAA,SAAA,CAAU,MAAM;AACd,IAAM,MAAA,CAAA,GAAI,KAAM,CAAA,gBAAA,CAAiB,QAAQ,CAAA,CAAA;AAGzC,IAAI,IAAA,KAAA,CAAM,UAAU,kBAAoB,EAAA;AACtC,MAAA,QAAA,CAAS,MAAM,KAAK,CAAA,CAAA;AAAA,KACtB;AAEA,IAAO,OAAA,MAAM,EAAE,WAAY,EAAA,CAAA;AAAA,GAE7B,EAAG,CAAC,KAAK,CAAC,CAAA,CAAA;AAEV,EAAA,OAAO,KAAM,CAAA,KAAA,CAAA;AACf;;;;"}
|
package/dist/index.d.ts
CHANGED
|
@@ -304,6 +304,12 @@ declare abstract class SceneObjectBase<TState extends SceneObjectState = SceneOb
|
|
|
304
304
|
**/
|
|
305
305
|
subscribeToEvent<T extends BusEvent>(eventType: BusEventType<T>, handler: BusEventHandler<T>): Unsubscribable;
|
|
306
306
|
setState(update: Partial<TState>): void;
|
|
307
|
+
/**
|
|
308
|
+
* This handles activation and deactivation of $data, $timeRange and $variables when they change
|
|
309
|
+
* during the active phase of the scene object.
|
|
310
|
+
*/
|
|
311
|
+
private _handleActivationOfChangedStateProps;
|
|
312
|
+
private _handleChangedStateActivation;
|
|
307
313
|
publishEvent(event: BusEvent, bubble?: boolean): void;
|
|
308
314
|
getRoot(): SceneObject;
|
|
309
315
|
private _internalActivate;
|
package/dist/index.js
CHANGED
|
@@ -201,7 +201,7 @@ class SceneObjectBase {
|
|
|
201
201
|
constructor(state) {
|
|
202
202
|
this._isActive = false;
|
|
203
203
|
this._activationHandlers = [];
|
|
204
|
-
this._deactivationHandlers =
|
|
204
|
+
this._deactivationHandlers = /* @__PURE__ */ new Map();
|
|
205
205
|
this._subs = new rxjs.Subscription();
|
|
206
206
|
this._refCount = 0;
|
|
207
207
|
if (!state.key) {
|
|
@@ -256,6 +256,7 @@ class SceneObjectBase {
|
|
|
256
256
|
const newState = __spreadValues$s(__spreadValues$s({}, this._state), update);
|
|
257
257
|
this._state = Object.freeze(newState);
|
|
258
258
|
this._setParent();
|
|
259
|
+
this._handleActivationOfChangedStateProps(prevState, newState);
|
|
259
260
|
this.publishEvent(
|
|
260
261
|
new SceneObjectStateChangedEvent({
|
|
261
262
|
prevState,
|
|
@@ -266,6 +267,32 @@ class SceneObjectBase {
|
|
|
266
267
|
true
|
|
267
268
|
);
|
|
268
269
|
}
|
|
270
|
+
_handleActivationOfChangedStateProps(prevState, newState) {
|
|
271
|
+
if (!this.isActive) {
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
if (prevState.$data !== newState.$data) {
|
|
275
|
+
this._handleChangedStateActivation(prevState.$data, newState.$data);
|
|
276
|
+
}
|
|
277
|
+
if (prevState.$variables !== newState.$variables) {
|
|
278
|
+
this._handleChangedStateActivation(prevState.$variables, newState.$variables);
|
|
279
|
+
}
|
|
280
|
+
if (prevState.$timeRange !== newState.$timeRange) {
|
|
281
|
+
this._handleChangedStateActivation(prevState.$timeRange, newState.$timeRange);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
_handleChangedStateActivation(oldValue, newValue) {
|
|
285
|
+
if (oldValue) {
|
|
286
|
+
const deactivationHandler = this._deactivationHandlers.get(oldValue);
|
|
287
|
+
if (deactivationHandler) {
|
|
288
|
+
deactivationHandler();
|
|
289
|
+
this._deactivationHandlers.delete(oldValue);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
if (newValue) {
|
|
293
|
+
this._deactivationHandlers.set(newValue, newValue.activate());
|
|
294
|
+
}
|
|
295
|
+
}
|
|
269
296
|
publishEvent(event, bubble) {
|
|
270
297
|
this._events.publish(event);
|
|
271
298
|
if (bubble && this.parent) {
|
|
@@ -279,22 +306,22 @@ class SceneObjectBase {
|
|
|
279
306
|
this._isActive = true;
|
|
280
307
|
const { $data, $variables, $timeRange, $behaviors } = this.state;
|
|
281
308
|
if ($timeRange && !$timeRange.isActive) {
|
|
282
|
-
this._deactivationHandlers.
|
|
309
|
+
this._deactivationHandlers.set($timeRange, $timeRange.activate());
|
|
283
310
|
}
|
|
284
311
|
if ($variables && !$variables.isActive) {
|
|
285
|
-
this._deactivationHandlers.
|
|
312
|
+
this._deactivationHandlers.set($variables, $variables.activate());
|
|
286
313
|
}
|
|
287
314
|
if ($data && !$data.isActive) {
|
|
288
|
-
this._deactivationHandlers.
|
|
315
|
+
this._deactivationHandlers.set($data, $data.activate());
|
|
289
316
|
}
|
|
290
317
|
if ($behaviors) {
|
|
291
318
|
for (const behavior of $behaviors) {
|
|
292
319
|
if (behavior instanceof SceneObjectBase) {
|
|
293
|
-
this._deactivationHandlers.
|
|
320
|
+
this._deactivationHandlers.set(behavior, behavior.activate());
|
|
294
321
|
} else if (typeof behavior === "function") {
|
|
295
322
|
const deactivationHandler = behavior(this);
|
|
296
323
|
if (deactivationHandler) {
|
|
297
|
-
this._deactivationHandlers.
|
|
324
|
+
this._deactivationHandlers.set(behavior, deactivationHandler);
|
|
298
325
|
}
|
|
299
326
|
}
|
|
300
327
|
}
|
|
@@ -302,7 +329,7 @@ class SceneObjectBase {
|
|
|
302
329
|
this._activationHandlers.forEach((handler) => {
|
|
303
330
|
const result = handler();
|
|
304
331
|
if (result) {
|
|
305
|
-
this._deactivationHandlers.
|
|
332
|
+
this._deactivationHandlers.set(result, result);
|
|
306
333
|
}
|
|
307
334
|
});
|
|
308
335
|
}
|
|
@@ -327,8 +354,10 @@ class SceneObjectBase {
|
|
|
327
354
|
}
|
|
328
355
|
_internalDeactivate() {
|
|
329
356
|
this._isActive = false;
|
|
330
|
-
this._deactivationHandlers.
|
|
331
|
-
|
|
357
|
+
for (let handler of this._deactivationHandlers.values()) {
|
|
358
|
+
handler();
|
|
359
|
+
}
|
|
360
|
+
this._deactivationHandlers.clear();
|
|
332
361
|
this._events.removeAllListeners();
|
|
333
362
|
this._subs.unsubscribe();
|
|
334
363
|
this._subs = new rxjs.Subscription();
|