@grafana/scenes 4.26.2 → 4.26.3--canary.765.9397990341.0

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.d.ts CHANGED
@@ -7,6 +7,7 @@ import { Observable, Unsubscribable, MonoTypeOperatorFunction, Subscription, Rep
7
7
  import * as _grafana_schema from '@grafana/schema';
8
8
  import { VariableType, VariableHide, TimeZone, DataTopic, DataQuery, DataSourceRef, VariableRefresh, LoadingState, DashboardCursorSync, MatcherConfig, TableFieldOptions } from '@grafana/schema';
9
9
  import { VariableInterpolation } from '@grafana/runtime';
10
+ import { Location } from 'history';
10
11
  import { PanelContext, IconName } from '@grafana/ui';
11
12
  import ReactGridLayout from 'react-grid-layout';
12
13
  import { RouteComponentProps } from 'react-router-dom';
@@ -1559,26 +1560,39 @@ interface UrlSyncManagerLike {
1559
1560
  initSync(root: SceneObject): void;
1560
1561
  cleanUp(root: SceneObject): void;
1561
1562
  getUrlState(root: SceneObject): SceneObjectUrlValues;
1563
+ handleNewLocation(location: Location): void;
1564
+ handleNewObject(sceneObj: SceneObject): void;
1562
1565
  }
1563
1566
  declare class UrlSyncManager implements UrlSyncManagerLike {
1564
1567
  private _urlKeyMapper;
1565
- private _sceneRoot;
1568
+ private _sceneRoot?;
1566
1569
  private _stateSub;
1567
- private _locationSub?;
1568
- private _lastPath?;
1569
- private _ignoreNextLocationUpdate;
1570
+ private _lastLocation;
1571
+ private _urlParams;
1570
1572
  /**
1571
1573
  * Updates the current scene state to match URL state.
1572
1574
  */
1573
1575
  initSync(root: SceneObject): void;
1574
1576
  cleanUp(root: SceneObject): void;
1575
1577
  syncFrom(sceneObj: SceneObject): void;
1576
- private _onLocationUpdate;
1578
+ handleNewLocation(location: Location): void;
1579
+ handleNewObject(sceneObj: SceneObject): void;
1577
1580
  private _onStateChanged;
1578
1581
  getUrlState(root: SceneObject): SceneObjectUrlValues;
1579
1582
  }
1580
1583
  declare function getUrlSyncManager(): UrlSyncManagerLike;
1581
1584
 
1585
+ declare function useUrlSync(sceneRoot: SceneObject): boolean;
1586
+
1587
+ interface UrlSyncContextProviderProps {
1588
+ scene: SceneObject;
1589
+ children: React.ReactNode;
1590
+ }
1591
+ /**
1592
+ * Right now this is actually not defining a context, but think it might in the future (with UrlSyncManager as the context value)
1593
+ */
1594
+ declare function UrlSyncContextProvider({ children, scene }: UrlSyncContextProviderProps): React$1.ReactNode;
1595
+
1582
1596
  interface EmbeddedSceneState extends SceneObjectState {
1583
1597
  /**
1584
1598
  * The main content of the scene (usually a SceneFlexLayout)
@@ -1592,13 +1606,6 @@ interface EmbeddedSceneState extends SceneObjectState {
1592
1606
  declare class EmbeddedScene extends SceneObjectBase<EmbeddedSceneState> {
1593
1607
  static Component: typeof EmbeddedSceneRenderer;
1594
1608
  constructor(state: EmbeddedSceneState);
1595
- /**
1596
- * initUrlSync should be called before the scene is rendered to ensure that objects are in sync
1597
- * before they get activated. This saves some unnecessary re-renders and makes sure variables
1598
- * queries are issued as needed. If your using SceneAppPage you will not need to call this as
1599
- * url sync is handled on the SceneAppPage level not this level.
1600
- */
1601
- initUrlSync(): void;
1602
1609
  }
1603
1610
  declare function EmbeddedSceneRenderer({ model }: SceneComponentProps<EmbeddedScene>): React__default.JSX.Element;
1604
1611
 
@@ -2633,4 +2640,4 @@ declare const sceneUtils: {
2633
2640
  isGroupByVariable: typeof isGroupByVariable;
2634
2641
  };
2635
2642
 
2636
- export { AdHocFiltersVariable, CancelActivationHandler, ConstantVariable, ControlsLayout, CustomFormatterVariable, CustomTransformOperator, CustomTransformerDefinition, CustomVariable, CustomVariableValue, DataLayerFilter, DataRequestEnricher, DataSourceVariable, DeepPartial, EmbeddedScene, EmbeddedSceneState, ExtraQueryDataProcessor, ExtraQueryDescriptor, ExtraQueryProvider, FieldConfigBuilder, FieldConfigBuilders, FieldConfigOverridesBuilder, FormatVariable, GroupByVariable, InterpolationFormatParameter, IntervalVariable, LocalValueVariable, MacroVariableConstructor, MultiValueVariable, NestedScene, PanelBuilders, PanelOptionsBuilders, QueryRunnerState, QueryVariable, RuntimeDataSource, SceneActivationHandler, SceneApp, SceneAppDrilldownView, SceneAppPage, SceneAppPageLike, SceneAppPageState, SceneAppRoute, SceneByFrameRepeater, SceneByVariableRepeater, SceneCSSGridItem, SceneCSSGridLayout, SceneCanvasText, SceneComponent, SceneComponentProps, SceneControlsSpacer, SceneDataLayerBase, SceneDataLayerControls, SceneDataLayerProvider, SceneDataLayerProviderState, SceneDataLayerSet, SceneDataLayerSetBase, SceneDataNode, SceneDataProvider, SceneDataProviderResult, SceneDataQuery, SceneDataState, SceneDataTransformer, SceneDeactivationHandler, SceneDebugger, SceneFlexItem, SceneFlexItemLike, SceneFlexItemState, SceneFlexLayout, SceneGridItem, SceneGridItemLike, SceneGridItemStateLike, SceneGridLayout, SceneGridRow, SceneLayout, SceneLayoutChildOptions, SceneLayoutState, SceneObject, SceneObjectBase, SceneObjectRef, SceneObjectState, SceneObjectStateChangedEvent, SceneObjectStateChangedPayload, SceneObjectUrlSyncConfig, SceneObjectUrlSyncHandler, SceneObjectUrlValue, SceneObjectUrlValues, SceneObjectWithUrlSync, SceneQueryControllerEntry, SceneQueryControllerEntryType, SceneQueryControllerLike, SceneQueryRunner, SceneReactObject, SceneRefreshPicker, SceneRefreshPickerState, SceneRouteMatch, SceneStateChangedHandler, SceneStatelessBehavior, SceneTimePicker, SceneTimeRange, SceneTimeRangeCompare, SceneTimeRangeLike, SceneTimeRangeState, SceneTimeRangeTransformerBase, SceneTimeZoneOverride, SceneToolbarButton, SceneToolbarInput, SceneVariable, SceneVariableDependencyConfigLike, SceneVariableSet, SceneVariableSetState, SceneVariableState, SceneVariableValueChangedEvent, SceneVariables, SplitLayout, TestVariable, TextBoxVariable, UrlSyncManager, UrlSyncManagerLike, UseStateHookOptions, UserActionEvent, ValidateAndUpdateResult, VariableCustomFormatterFn, VariableDependencyConfig, VariableValue, VariableValueControl, VariableValueOption, VariableValueSelectWrapper, VariableValueSelectors, VariableValueSingle, VizConfig, VizConfigBuilder, VizConfigBuilders, VizPanel, VizPanelBuilder, VizPanelMenu, VizPanelState, index$1 as behaviors, index as dataLayers, formatRegistry, getUrlSyncManager, isCustomVariableValue, isDataLayer, isDataRequestEnricher, isSceneObject, registerQueryWithController, registerRuntimeDataSource, sceneGraph, sceneUtils, useSceneApp, useSceneObjectState };
2643
+ export { AdHocFiltersVariable, CancelActivationHandler, ConstantVariable, ControlsLayout, CustomFormatterVariable, CustomTransformOperator, CustomTransformerDefinition, CustomVariable, CustomVariableValue, DataLayerFilter, DataRequestEnricher, DataSourceVariable, DeepPartial, EmbeddedScene, EmbeddedSceneState, ExtraQueryDataProcessor, ExtraQueryDescriptor, ExtraQueryProvider, FieldConfigBuilder, FieldConfigBuilders, FieldConfigOverridesBuilder, FormatVariable, GroupByVariable, InterpolationFormatParameter, IntervalVariable, LocalValueVariable, MacroVariableConstructor, MultiValueVariable, NestedScene, PanelBuilders, PanelOptionsBuilders, QueryRunnerState, QueryVariable, RuntimeDataSource, SceneActivationHandler, SceneApp, SceneAppDrilldownView, SceneAppPage, SceneAppPageLike, SceneAppPageState, SceneAppRoute, SceneByFrameRepeater, SceneByVariableRepeater, SceneCSSGridItem, SceneCSSGridLayout, SceneCanvasText, SceneComponent, SceneComponentProps, SceneControlsSpacer, SceneDataLayerBase, SceneDataLayerControls, SceneDataLayerProvider, SceneDataLayerProviderState, SceneDataLayerSet, SceneDataLayerSetBase, SceneDataNode, SceneDataProvider, SceneDataProviderResult, SceneDataQuery, SceneDataState, SceneDataTransformer, SceneDeactivationHandler, SceneDebugger, SceneFlexItem, SceneFlexItemLike, SceneFlexItemState, SceneFlexLayout, SceneGridItem, SceneGridItemLike, SceneGridItemStateLike, SceneGridLayout, SceneGridRow, SceneLayout, SceneLayoutChildOptions, SceneLayoutState, SceneObject, SceneObjectBase, SceneObjectRef, SceneObjectState, SceneObjectStateChangedEvent, SceneObjectStateChangedPayload, SceneObjectUrlSyncConfig, SceneObjectUrlSyncHandler, SceneObjectUrlValue, SceneObjectUrlValues, SceneObjectWithUrlSync, SceneQueryControllerEntry, SceneQueryControllerEntryType, SceneQueryControllerLike, SceneQueryRunner, SceneReactObject, SceneRefreshPicker, SceneRefreshPickerState, SceneRouteMatch, SceneStateChangedHandler, SceneStatelessBehavior, SceneTimePicker, SceneTimeRange, SceneTimeRangeCompare, SceneTimeRangeLike, SceneTimeRangeState, SceneTimeRangeTransformerBase, SceneTimeZoneOverride, SceneToolbarButton, SceneToolbarInput, SceneVariable, SceneVariableDependencyConfigLike, SceneVariableSet, SceneVariableSetState, SceneVariableState, SceneVariableValueChangedEvent, SceneVariables, SplitLayout, TestVariable, TextBoxVariable, UrlSyncContextProvider, UrlSyncManager, UrlSyncManagerLike, UseStateHookOptions, UserActionEvent, ValidateAndUpdateResult, VariableCustomFormatterFn, VariableDependencyConfig, VariableValue, VariableValueControl, VariableValueOption, VariableValueSelectWrapper, VariableValueSelectors, VariableValueSingle, VizConfig, VizConfigBuilder, VizConfigBuilders, VizPanel, VizPanelBuilder, VizPanelMenu, VizPanelState, index$1 as behaviors, index as dataLayers, formatRegistry, getUrlSyncManager, isCustomVariableValue, isDataLayer, isDataRequestEnricher, isSceneObject, registerQueryWithController, registerRuntimeDataSource, sceneGraph, sceneUtils, useSceneApp, useSceneObjectState, useUrlSync };
package/dist/index.js CHANGED
@@ -591,39 +591,42 @@ class UniqueUrlKeyMapper {
591
591
  this.index = /* @__PURE__ */ new Map();
592
592
  }
593
593
  getUniqueKey(key, obj) {
594
- const objectsWithKey = this.index.get(key);
594
+ let objectsWithKey = this.index.get(key);
595
595
  if (!objectsWithKey) {
596
- throw new Error("Cannot find any scene object that uses the key '" + key + "'");
596
+ this.index.set(key, [obj]);
597
+ return key;
598
+ }
599
+ let address = objectsWithKey.findIndex((o) => o === obj);
600
+ if (address === -1) {
601
+ objectsWithKey = filterOutDeadObjects(objectsWithKey);
602
+ objectsWithKey.push(obj);
603
+ address = objectsWithKey.length - 1;
597
604
  }
598
- const address = objectsWithKey.findIndex((o) => o.sceneObject === obj);
599
605
  if (address > 0) {
600
606
  return `${key}-${address + 1}`;
601
607
  }
602
608
  return key;
603
609
  }
604
- rebuildIndex(root) {
610
+ clear() {
605
611
  this.index.clear();
606
- this.buildIndex(root, 0);
607
- }
608
- buildIndex(sceneObject, depth) {
609
- if (sceneObject.urlSync) {
610
- for (const key of sceneObject.urlSync.getKeys()) {
611
- const hit = this.index.get(key);
612
- if (hit) {
613
- hit.push({ sceneObject, depth });
614
- hit.sort((a, b) => a.depth - b.depth);
615
- } else {
616
- this.index.set(key, [{ sceneObject, depth }]);
612
+ }
613
+ }
614
+ function filterOutDeadObjects(sceneObjects) {
615
+ const filtered = [];
616
+ for (const obj of sceneObjects) {
617
+ if (obj.parent) {
618
+ obj.parent.forEachChild((child) => {
619
+ if (child === obj) {
620
+ filtered.push(child);
617
621
  }
618
- }
622
+ });
619
623
  }
620
- sceneObject.forEachChild((child) => this.buildIndex(child, depth + 1));
621
624
  }
625
+ return filtered;
622
626
  }
623
627
 
624
628
  function getUrlState(root) {
625
629
  const urlKeyMapper = new UniqueUrlKeyMapper();
626
- urlKeyMapper.rebuildIndex(root);
627
630
  const result = {};
628
631
  const visitNode = (obj) => {
629
632
  if (obj.urlSync) {
@@ -642,10 +645,18 @@ function getUrlState(root) {
642
645
  }
643
646
  function syncStateFromSearchParams(root, urlParams) {
644
647
  const urlKeyMapper = new UniqueUrlKeyMapper();
645
- urlKeyMapper.rebuildIndex(root);
646
648
  syncStateFromUrl(root, urlParams, urlKeyMapper);
647
649
  }
648
- function syncStateFromUrl(sceneObject, urlParams, urlKeyMapper) {
650
+ function syncStateFromUrl(root, urlParams, urlKeyMapper) {
651
+ if (!root.parent) {
652
+ syncUrlStateToObject(root, urlParams, urlKeyMapper);
653
+ }
654
+ root.forEachChild((child) => {
655
+ syncUrlStateToObject(child, urlParams, urlKeyMapper);
656
+ });
657
+ root.forEachChild((child) => syncStateFromUrl(child, urlParams, urlKeyMapper));
658
+ }
659
+ function syncUrlStateToObject(sceneObject, urlParams, urlKeyMapper) {
649
660
  if (sceneObject.urlSync) {
650
661
  const urlState = {};
651
662
  const currentState = sceneObject.urlSync.getUrlState();
@@ -670,7 +681,6 @@ function syncStateFromUrl(sceneObject, urlParams, urlKeyMapper) {
670
681
  sceneObject.urlSync.updateFromUrl(urlState);
671
682
  }
672
683
  }
673
- sceneObject.forEachChild((child) => syncStateFromUrl(child, urlParams, urlKeyMapper));
674
684
  }
675
685
  function isUrlValueEqual(currentUrlValue, newUrlValue) {
676
686
  if (currentUrlValue.length === 0 && newUrlValue == null) {
@@ -7720,28 +7730,12 @@ class UrlSyncManager {
7720
7730
  constructor() {
7721
7731
  this._urlKeyMapper = new UniqueUrlKeyMapper();
7722
7732
  this._stateSub = null;
7723
- this._locationSub = null;
7724
- this._ignoreNextLocationUpdate = false;
7725
- this._onLocationUpdate = (location) => {
7726
- if (this._ignoreNextLocationUpdate) {
7727
- this._ignoreNextLocationUpdate = false;
7728
- return;
7729
- }
7730
- if (this._lastPath !== location.pathname) {
7731
- return;
7732
- }
7733
- const urlParams = new URLSearchParams(location.search);
7734
- this._urlKeyMapper.rebuildIndex(this._sceneRoot);
7735
- syncStateFromUrl(this._sceneRoot, urlParams, this._urlKeyMapper);
7736
- this._lastPath = location.pathname;
7737
- };
7738
7733
  this._onStateChanged = ({ payload }) => {
7739
7734
  const changedObject = payload.changedObject;
7740
7735
  if (changedObject.urlSync) {
7741
7736
  const newUrlState = changedObject.urlSync.getUrlState();
7742
7737
  const searchParams = runtime.locationService.getSearch();
7743
7738
  const mappedUpdated = {};
7744
- this._urlKeyMapper.rebuildIndex(this._sceneRoot);
7745
7739
  for (const [key, newUrlValue] of Object.entries(newUrlState)) {
7746
7740
  const uniqueKey = this._urlKeyMapper.getUniqueKey(key, changedObject);
7747
7741
  const currentUrlValue = searchParams.getAll(uniqueKey);
@@ -7750,24 +7744,26 @@ class UrlSyncManager {
7750
7744
  }
7751
7745
  }
7752
7746
  if (Object.keys(mappedUpdated).length > 0) {
7753
- this._ignoreNextLocationUpdate = true;
7747
+ writeSceneLog("UrlSyncManager", "onStateChange updating URL");
7754
7748
  runtime.locationService.partial(mappedUpdated, true);
7749
+ this._lastLocation = runtime.locationService.getLocation();
7755
7750
  }
7756
7751
  }
7757
7752
  };
7758
7753
  }
7759
7754
  initSync(root) {
7760
- if (!this._locationSub) {
7761
- writeSceneLog("UrlSyncManager", "New location listen");
7762
- this._locationSub = runtime.locationService.getHistory().listen(this._onLocationUpdate);
7763
- }
7755
+ var _a;
7764
7756
  if (this._stateSub) {
7765
- writeSceneLog("UrlSyncManager", "Unregister previous scene state subscription", this._sceneRoot.state.key);
7757
+ writeSceneLog("UrlSyncManager", "Unregister previous scene state subscription", (_a = this._sceneRoot) == null ? void 0 : _a.state.key);
7766
7758
  this._stateSub.unsubscribe();
7767
7759
  }
7760
+ writeSceneLog("UrlSyncManager", "init", root.state.key);
7761
+ const location = runtime.locationService.getLocation();
7768
7762
  this._sceneRoot = root;
7769
- this._lastPath = runtime.locationService.getLocation().pathname;
7763
+ this._lastLocation = location;
7764
+ this._urlParams = new URLSearchParams(location.search);
7770
7765
  this._stateSub = root.subscribeToEvent(SceneObjectStateChangedEvent, this._onStateChanged);
7766
+ this._urlKeyMapper.clear();
7771
7767
  this.syncFrom(this._sceneRoot);
7772
7768
  }
7773
7769
  cleanUp(root) {
@@ -7775,11 +7771,6 @@ class UrlSyncManager {
7775
7771
  return;
7776
7772
  }
7777
7773
  writeSceneLog("UrlSyncManager", "Clean up");
7778
- if (this._locationSub) {
7779
- this._locationSub();
7780
- writeSceneLog("UrlSyncManager", "Unregister history listen");
7781
- this._locationSub = null;
7782
- }
7783
7774
  if (this._stateSub) {
7784
7775
  this._stateSub.unsubscribe();
7785
7776
  this._stateSub = null;
@@ -7790,12 +7781,28 @@ class UrlSyncManager {
7790
7781
  this._sceneRoot.state.key === root.state.key
7791
7782
  );
7792
7783
  }
7784
+ this._sceneRoot = void 0;
7785
+ this._urlParams = void 0;
7793
7786
  }
7794
7787
  syncFrom(sceneObj) {
7795
7788
  const urlParams = runtime.locationService.getSearch();
7796
- this._urlKeyMapper.rebuildIndex(this._sceneRoot);
7797
7789
  syncStateFromUrl(sceneObj, urlParams, this._urlKeyMapper);
7798
7790
  }
7791
+ handleNewLocation(location) {
7792
+ if (!this._sceneRoot || this._lastLocation === location) {
7793
+ return;
7794
+ }
7795
+ writeSceneLog("UrlSyncManager", "handleNewLocation");
7796
+ this._urlParams = new URLSearchParams(location.search);
7797
+ this._lastLocation = location;
7798
+ syncStateFromUrl(this._sceneRoot, this._urlParams, this._urlKeyMapper);
7799
+ }
7800
+ handleNewObject(sceneObj) {
7801
+ if (!this._sceneRoot || !this._urlParams) {
7802
+ return;
7803
+ }
7804
+ syncStateFromUrl(sceneObj, this._urlParams, this._urlKeyMapper);
7805
+ }
7799
7806
  getUrlState(root) {
7800
7807
  return getUrlState(root);
7801
7808
  }
@@ -7808,6 +7815,29 @@ function getUrlSyncManager() {
7808
7815
  return urlSyncManager;
7809
7816
  }
7810
7817
 
7818
+ function useUrlSync(sceneRoot) {
7819
+ const urlSyncManager = getUrlSyncManager();
7820
+ const location = reactRouterDom.useLocation();
7821
+ const [isInitialized, setIsInitialized] = React.useState(false);
7822
+ React.useEffect(() => {
7823
+ urlSyncManager.initSync(sceneRoot);
7824
+ setIsInitialized(true);
7825
+ return () => urlSyncManager.cleanUp(sceneRoot);
7826
+ }, [sceneRoot, urlSyncManager]);
7827
+ React.useEffect(() => {
7828
+ urlSyncManager.handleNewLocation(location);
7829
+ }, [sceneRoot, urlSyncManager, location]);
7830
+ return isInitialized;
7831
+ }
7832
+
7833
+ function UrlSyncContextProvider({ children, scene }) {
7834
+ const isInitialized = useUrlSync(scene);
7835
+ if (!isInitialized) {
7836
+ return null;
7837
+ }
7838
+ return children;
7839
+ }
7840
+
7811
7841
  function setWindowGrafanaSceneContext(activeScene) {
7812
7842
  const prevScene = window.__grafanaSceneContext;
7813
7843
  writeSceneLog("setWindowGrafanaScene", "set window.__grafanaSceneContext", activeScene);
@@ -7827,13 +7857,9 @@ class EmbeddedScene extends SceneObjectBase {
7827
7857
  const unsetGlobalScene = setWindowGrafanaSceneContext(this);
7828
7858
  return () => {
7829
7859
  unsetGlobalScene();
7830
- getUrlSyncManager().cleanUp(this);
7831
7860
  };
7832
7861
  });
7833
7862
  }
7834
- initUrlSync() {
7835
- getUrlSyncManager().initSync(this);
7836
- }
7837
7863
  }
7838
7864
  EmbeddedScene.Component = EmbeddedSceneRenderer;
7839
7865
  function EmbeddedSceneRenderer({ model }) {
@@ -10306,7 +10332,8 @@ function SceneAppPageView({ page, routeProps }) {
10306
10332
  React.useEffect(() => {
10307
10333
  return () => containerPage.setState({ initializedScene: void 0 });
10308
10334
  }, [containerPage]);
10309
- if (!isInitialized) {
10335
+ const urlSyncInitialized = useUrlSync(containerPage);
10336
+ if (!isInitialized && !urlSyncInitialized) {
10310
10337
  return null;
10311
10338
  }
10312
10339
  const pageNav = {
@@ -10379,13 +10406,9 @@ class SceneAppPage extends SceneObjectBase {
10379
10406
  super(state);
10380
10407
  this._sceneCache = /* @__PURE__ */ new Map();
10381
10408
  this._drilldownCache = /* @__PURE__ */ new Map();
10382
- this.addActivationHandler(() => {
10383
- return () => getUrlSyncManager().cleanUp(this);
10384
- });
10385
10409
  }
10386
10410
  initializeScene(scene) {
10387
10411
  this.setState({ initializedScene: scene });
10388
- getUrlSyncManager().initSync(this);
10389
10412
  }
10390
10413
  getScene(routeMatch) {
10391
10414
  let scene = this._sceneCache.get(routeMatch.url);
@@ -11380,6 +11403,7 @@ exports.SceneVariableValueChangedEvent = SceneVariableValueChangedEvent;
11380
11403
  exports.SplitLayout = SplitLayout;
11381
11404
  exports.TestVariable = TestVariable;
11382
11405
  exports.TextBoxVariable = TextBoxVariable;
11406
+ exports.UrlSyncContextProvider = UrlSyncContextProvider;
11383
11407
  exports.UrlSyncManager = UrlSyncManager;
11384
11408
  exports.UserActionEvent = UserActionEvent;
11385
11409
  exports.VariableDependencyConfig = VariableDependencyConfig;
@@ -11405,4 +11429,5 @@ exports.sceneGraph = sceneGraph;
11405
11429
  exports.sceneUtils = sceneUtils;
11406
11430
  exports.useSceneApp = useSceneApp;
11407
11431
  exports.useSceneObjectState = useSceneObjectState;
11432
+ exports.useUrlSync = useUrlSync;
11408
11433
  //# sourceMappingURL=index.js.map