@dynatrace/strato-geo 3.5.2 → 3.7.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 (146) hide show
  1. package/esm/map/MapView.js +42 -34
  2. package/esm/map/MapView.js.map +2 -2
  3. package/esm/map/components/BubbleLayer/BubbleCircleLayer.js +2 -0
  4. package/esm/map/components/BubbleLayer/BubbleCircleLayer.js.map +2 -2
  5. package/esm/map/components/BubbleLayer/BubbleLayer.js +14 -3
  6. package/esm/map/components/BubbleLayer/BubbleLayer.js.map +2 -2
  7. package/esm/map/components/BubbleLayer/BubbleLayerTooltip.js +9 -3
  8. package/esm/map/components/BubbleLayer/BubbleLayerTooltip.js.map +2 -2
  9. package/esm/map/components/BubbleLayer/utils/parse-bubble-data-to-geo-json.js +5 -5
  10. package/esm/map/components/BubbleLayer/utils/parse-bubble-data-to-geo-json.js.map +2 -2
  11. package/esm/map/components/ChoroplethLayer/ChoroplethLayer.js +15 -7
  12. package/esm/map/components/ChoroplethLayer/ChoroplethLayer.js.map +2 -2
  13. package/esm/map/components/ChoroplethLayer/ChoroplethLayerTooltip.js +9 -3
  14. package/esm/map/components/ChoroplethLayer/ChoroplethLayerTooltip.js.map +2 -2
  15. package/esm/map/components/ChoroplethLayer/ChoroplethOutlineLayer.js +3 -1
  16. package/esm/map/components/ChoroplethLayer/ChoroplethOutlineLayer.js.map +2 -2
  17. package/esm/map/components/ChoroplethLayer/utils/parse-region-data-to-geo-json.js +6 -5
  18. package/esm/map/components/ChoroplethLayer/utils/parse-region-data-to-geo-json.js.map +2 -2
  19. package/esm/map/components/ConnectionLayer/ConnectionLayer.js +11 -6
  20. package/esm/map/components/ConnectionLayer/ConnectionLayer.js.map +2 -2
  21. package/esm/map/components/ConnectionLayer/ConnectionLayerLine.js +3 -0
  22. package/esm/map/components/ConnectionLayer/ConnectionLayerLine.js.map +2 -2
  23. package/esm/map/components/ConnectionLayer/ConnectionLayerTooltip.js +16 -12
  24. package/esm/map/components/ConnectionLayer/ConnectionLayerTooltip.js.map +2 -2
  25. package/esm/map/components/ConnectionLayer/utils/parse-connection-data-to-geo-json.js +20 -18
  26. package/esm/map/components/ConnectionLayer/utils/parse-connection-data-to-geo-json.js.map +2 -2
  27. package/esm/map/components/DotLayer/DotLayer.js +12 -3
  28. package/esm/map/components/DotLayer/DotLayer.js.map +2 -2
  29. package/esm/map/components/DotLayer/DotLayerTooltip.js +9 -3
  30. package/esm/map/components/DotLayer/DotLayerTooltip.js.map +2 -2
  31. package/esm/map/components/DotLayer/utils/parse-dot-data-to-geo-json.js +5 -5
  32. package/esm/map/components/DotLayer/utils/parse-dot-data-to-geo-json.js.map +2 -2
  33. package/esm/map/components/MapContent.js +22 -12
  34. package/esm/map/components/MapContent.js.map +2 -2
  35. package/esm/map/contexts/geo-data-lookup.context.js +8 -0
  36. package/esm/map/contexts/geo-data-lookup.context.js.map +7 -0
  37. package/esm/map/contexts/map-view-provider.context.js +9 -0
  38. package/esm/map/contexts/map-view-provider.context.js.map +7 -0
  39. package/esm/map/hooks/use-active-interaction.js +59 -43
  40. package/esm/map/hooks/use-active-interaction.js.map +2 -2
  41. package/esm/map/hooks/use-attach-image-from-icon.js +4 -2
  42. package/esm/map/hooks/use-attach-image-from-icon.js.map +2 -2
  43. package/esm/map/hooks/use-hover-interaction.js +59 -41
  44. package/esm/map/hooks/use-hover-interaction.js.map +2 -2
  45. package/esm/map/hooks/use-layer-before-id.js +24 -0
  46. package/esm/map/hooks/use-layer-before-id.js.map +7 -0
  47. package/esm/map/hooks/use-load-map-base-layer.js +13 -3
  48. package/esm/map/hooks/use-load-map-base-layer.js.map +2 -2
  49. package/esm/map/hooks/use-map-runtime-error.js +93 -0
  50. package/esm/map/hooks/use-map-runtime-error.js.map +7 -0
  51. package/esm/map/hooks/use-map-view-provider-context.js +7 -0
  52. package/esm/map/hooks/use-map-view-provider-context.js.map +7 -0
  53. package/esm/map/hooks/use-overlay-events.js +11 -2
  54. package/esm/map/hooks/use-overlay-events.js.map +2 -2
  55. package/esm/map/hooks/use-tooltip-template.js +17 -2
  56. package/esm/map/hooks/use-tooltip-template.js.map +2 -2
  57. package/esm/map/hooks/use-webgl-context-error.js +2 -1
  58. package/esm/map/hooks/use-webgl-context-error.js.map +2 -2
  59. package/esm/map/index.js +2 -0
  60. package/esm/map/index.js.map +2 -2
  61. package/esm/map/providers/map-view.provider.js +18 -0
  62. package/esm/map/providers/map-view.provider.js.map +7 -0
  63. package/esm/map/slots/Tooltip.js.map +2 -2
  64. package/esm/map/types/map-view-provider.js +1 -0
  65. package/esm/map/types/map-view-provider.js.map +7 -0
  66. package/esm/map/utils/attach-image-from-shape.js +4 -2
  67. package/esm/map/utils/attach-image-from-shape.js.map +2 -2
  68. package/esm/map/utils/extract-layers-data.js +24 -15
  69. package/esm/map/utils/extract-layers-data.js.map +2 -2
  70. package/esm/map/utils/fetch-base-layer-features.js +1 -1
  71. package/esm/map/utils/fetch-base-layer-features.js.map +2 -2
  72. package/esm/map/utils/is-browser-firefox.js +7 -0
  73. package/esm/map/utils/is-browser-firefox.js.map +7 -0
  74. package/esm/map/utils/parse-tooltip-data.js +22 -7
  75. package/esm/map/utils/parse-tooltip-data.js.map +2 -2
  76. package/map/MapView.js +42 -34
  77. package/map/components/BubbleLayer/BubbleCircleLayer.d.ts +2 -1
  78. package/map/components/BubbleLayer/BubbleCircleLayer.js +2 -0
  79. package/map/components/BubbleLayer/BubbleLayer.js +14 -3
  80. package/map/components/BubbleLayer/BubbleLayerTooltip.d.ts +2 -0
  81. package/map/components/BubbleLayer/BubbleLayerTooltip.js +9 -3
  82. package/map/components/BubbleLayer/utils/parse-bubble-data-to-geo-json.d.ts +3 -1
  83. package/map/components/BubbleLayer/utils/parse-bubble-data-to-geo-json.js +5 -5
  84. package/map/components/ChoroplethLayer/ChoroplethLayer.js +15 -7
  85. package/map/components/ChoroplethLayer/ChoroplethLayerTooltip.d.ts +2 -0
  86. package/map/components/ChoroplethLayer/ChoroplethLayerTooltip.js +9 -3
  87. package/map/components/ChoroplethLayer/ChoroplethOutlineLayer.d.ts +1 -0
  88. package/map/components/ChoroplethLayer/ChoroplethOutlineLayer.js +3 -1
  89. package/map/components/ChoroplethLayer/utils/parse-region-data-to-geo-json.d.ts +3 -1
  90. package/map/components/ChoroplethLayer/utils/parse-region-data-to-geo-json.js +6 -5
  91. package/map/components/ConnectionLayer/ConnectionLayer.js +11 -6
  92. package/map/components/ConnectionLayer/ConnectionLayerLine.js +3 -0
  93. package/map/components/ConnectionLayer/ConnectionLayerTooltip.d.ts +2 -0
  94. package/map/components/ConnectionLayer/ConnectionLayerTooltip.js +16 -12
  95. package/map/components/ConnectionLayer/utils/parse-connection-data-to-geo-json.d.ts +3 -1
  96. package/map/components/ConnectionLayer/utils/parse-connection-data-to-geo-json.js +20 -18
  97. package/map/components/DotLayer/DotLayer.js +12 -3
  98. package/map/components/DotLayer/DotLayerTooltip.d.ts +2 -0
  99. package/map/components/DotLayer/DotLayerTooltip.js +9 -3
  100. package/map/components/DotLayer/utils/parse-dot-data-to-geo-json.d.ts +3 -1
  101. package/map/components/DotLayer/utils/parse-dot-data-to-geo-json.js +5 -5
  102. package/map/components/MapContent.js +21 -12
  103. package/map/contexts/geo-data-lookup.context.d.ts +9 -0
  104. package/map/contexts/geo-data-lookup.context.js +27 -0
  105. package/map/contexts/map-view-provider.context.d.ts +2 -0
  106. package/map/{components/ConnectionLayer/utils/restore-null-props.js → contexts/map-view-provider.context.js} +8 -8
  107. package/map/hooks/use-active-interaction.d.ts +8 -1
  108. package/map/hooks/use-active-interaction.js +58 -42
  109. package/map/hooks/use-attach-image-from-icon.js +4 -2
  110. package/map/hooks/use-hover-interaction.d.ts +6 -2
  111. package/map/hooks/use-hover-interaction.js +52 -39
  112. package/map/hooks/use-layer-before-id.d.ts +13 -0
  113. package/map/hooks/{use-map-mouse-move.js → use-layer-before-id.js} +20 -15
  114. package/map/hooks/use-load-map-base-layer.js +13 -3
  115. package/map/hooks/use-map-runtime-error.d.ts +34 -0
  116. package/map/hooks/use-map-runtime-error.js +112 -0
  117. package/map/hooks/use-map-view-provider-context.d.ts +1 -0
  118. package/map/hooks/use-map-view-provider-context.js +26 -0
  119. package/map/hooks/use-overlay-events.js +11 -2
  120. package/map/hooks/use-tooltip-template.d.ts +8 -0
  121. package/map/hooks/use-tooltip-template.js +17 -2
  122. package/map/hooks/use-webgl-context-error.js +2 -1
  123. package/map/index.d.ts +2 -0
  124. package/map/index.js +2 -0
  125. package/map/providers/map-view.provider.d.ts +7 -0
  126. package/map/providers/map-view.provider.js +37 -0
  127. package/map/slots/Tooltip.d.ts +2 -0
  128. package/map/types/connection-layer.d.ts +1 -8
  129. package/map/types/map-view-provider.d.ts +10 -0
  130. package/map/types/map-view-provider.js +16 -0
  131. package/map/types/tooltip.d.ts +17 -0
  132. package/map/utils/attach-image-from-shape.js +4 -2
  133. package/map/utils/extract-layers-data.d.ts +2 -0
  134. package/map/utils/extract-layers-data.js +24 -15
  135. package/map/utils/fetch-base-layer-features.js +1 -1
  136. package/map/utils/is-browser-firefox.d.ts +5 -0
  137. package/map/utils/is-browser-firefox.js +26 -0
  138. package/map/utils/parse-tooltip-data.d.ts +11 -3
  139. package/map/utils/parse-tooltip-data.js +22 -7
  140. package/package.json +2 -2
  141. package/esm/map/components/ConnectionLayer/utils/restore-null-props.js +0 -9
  142. package/esm/map/components/ConnectionLayer/utils/restore-null-props.js.map +0 -7
  143. package/esm/map/hooks/use-map-mouse-move.js +0 -19
  144. package/esm/map/hooks/use-map-mouse-move.js.map +0 -7
  145. package/map/components/ConnectionLayer/utils/restore-null-props.d.ts +0 -2
  146. package/map/hooks/use-map-mouse-move.d.ts +0 -2
@@ -24,9 +24,16 @@ module.exports = __toCommonJS(use_hover_interaction_exports);
24
24
  var import_react_maplibre = require("@vis.gl/react-maplibre");
25
25
  var import_lodash_es = require("lodash");
26
26
  var import_react = require("react");
27
- var import_constants = require("../constants.js");
28
27
  var import_associated_features = require("../utils/associated-features.js");
29
28
  var import_get_min_value_feature = require("../utils/get-min-value-feature.js");
29
+ const MOUSEMOVE_THROTTLE_MS = 16;
30
+ const blurTrackedFeature = (map, featureIdRef, sourceIdRef) => {
31
+ if (!(0, import_lodash_es.isNil)(featureIdRef.current) && !(0, import_lodash_es.isNil)(sourceIdRef.current)) {
32
+ blurFeature(map, sourceIdRef.current, featureIdRef.current);
33
+ featureIdRef.current = void 0;
34
+ sourceIdRef.current = void 0;
35
+ }
36
+ };
30
37
  const featureExists = (map, source, id) => {
31
38
  const isSourcePresent = map.getSource(source) !== void 0;
32
39
  return isSourcePresent && map.getFeatureState({
@@ -68,53 +75,59 @@ const hoverFeature = (map, source, id) => {
68
75
  }
69
76
  }
70
77
  };
71
- const useHoverInteraction = () => {
78
+ const useHoverInteraction = (interactiveLayerIds) => {
72
79
  const map = (0, import_react_maplibre.useMap)().current;
73
- let featureId;
74
- let sourceId;
75
- const handleMouseOut = (0, import_react.useCallback)(
76
- ({ point }) => {
77
- if (!(0, import_lodash_es.isNil)(map) && !(0, import_lodash_es.isUndefined)(featureId) && !(0, import_lodash_es.isUndefined)(sourceId)) {
78
- blurFeature(map, sourceId, featureId);
79
- }
80
- },
81
- [featureId, sourceId, map]
82
- );
83
- const handleMouseMove = (0, import_react.useCallback)(
84
- ({ point }) => {
85
- if (!(0, import_lodash_es.isNil)(map)) {
86
- const features = map.queryRenderedFeatures(point).filter((feature) => !(0, import_associated_features.isAssociatedFeature)(feature.properties.id));
87
- map.getCanvas().style.cursor = "grab";
80
+ const featureIdRef = (0, import_react.useRef)(void 0);
81
+ const sourceIdRef = (0, import_react.useRef)(void 0);
82
+ const interactiveLayerIdsRef = (0, import_react.useRef)(interactiveLayerIds);
83
+ interactiveLayerIdsRef.current = interactiveLayerIds;
84
+ const handleMouseOut = (0, import_react.useCallback)(() => {
85
+ if (!(0, import_lodash_es.isNil)(map)) {
86
+ blurTrackedFeature(map, featureIdRef, sourceIdRef);
87
+ }
88
+ }, [map]);
89
+ const throttledMouseMove = (0, import_react.useMemo)(
90
+ () => (0, import_lodash_es.throttle)(
91
+ ({ point }) => {
92
+ if ((0, import_lodash_es.isNil)(map)) {
93
+ return;
94
+ }
95
+ let features;
96
+ try {
97
+ features = map.queryRenderedFeatures(point, {
98
+ layers: interactiveLayerIdsRef.current
99
+ }).filter((feature) => !(0, import_associated_features.isAssociatedFeature)(feature.properties.id));
100
+ } catch {
101
+ return;
102
+ }
88
103
  const layerId = features?.[0]?.layer?.id;
89
104
  const hasHoveredFeatures = !(0, import_lodash_es.isNil)(features) && features.length > 0 && !(0, import_lodash_es.isUndefined)(layerId);
90
- const isBaseLayer = import_constants.BASE_LAYER_IDS.includes(layerId);
91
- if (hasHoveredFeatures && !isBaseLayer) {
92
- map.getCanvas().style.cursor = "pointer";
93
- if (!(0, import_lodash_es.isUndefined)(featureId) && !(0, import_lodash_es.isUndefined)(sourceId)) {
94
- blurFeature(map, sourceId, featureId);
95
- }
96
- const minFeature = (0, import_get_min_value_feature.getMinValueFeature)(features);
97
- featureId = minFeature.id;
98
- sourceId = minFeature.layer.source;
99
- if (!(0, import_lodash_es.isUndefined)(featureId)) {
100
- hoverFeature(map, sourceId, featureId);
101
- }
102
- } else {
105
+ if (!hasHoveredFeatures) {
103
106
  map.getCanvas().style.cursor = "grab";
104
- if (!(0, import_lodash_es.isUndefined)(featureId) && !(0, import_lodash_es.isUndefined)(sourceId)) {
105
- blurFeature(map, sourceId, featureId);
106
- }
107
+ blurTrackedFeature(map, featureIdRef, sourceIdRef);
108
+ return;
107
109
  }
108
- }
109
- },
110
- [featureId, sourceId, map]
110
+ map.getCanvas().style.cursor = "pointer";
111
+ blurTrackedFeature(map, featureIdRef, sourceIdRef);
112
+ const minFeature = (0, import_get_min_value_feature.getMinValueFeature)(features);
113
+ featureIdRef.current = minFeature.id;
114
+ sourceIdRef.current = minFeature.layer.source;
115
+ if (!(0, import_lodash_es.isUndefined)(featureIdRef.current)) {
116
+ hoverFeature(map, sourceIdRef.current, featureIdRef.current);
117
+ }
118
+ },
119
+ MOUSEMOVE_THROTTLE_MS,
120
+ { trailing: true }
121
+ ),
122
+ [map]
111
123
  );
112
124
  (0, import_react.useEffect)(() => {
113
- map?.on("mousemove", handleMouseMove);
125
+ map?.on("mousemove", throttledMouseMove);
114
126
  map?.on("mouseout", handleMouseOut);
115
127
  return () => {
116
- map?.off("mousemove", handleMouseMove);
128
+ throttledMouseMove.cancel();
129
+ map?.off("mousemove", throttledMouseMove);
117
130
  map?.off("mouseout", handleMouseOut);
118
131
  };
119
- }, []);
132
+ }, [map, throttledMouseMove, handleMouseOut]);
120
133
  };
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Returns the maplibre layer id that the current layer should be inserted before,
3
+ * based on the JSX order of `MapView` children.
4
+ *
5
+ * Without this, layers that mount asynchronously (e.g. `{apiData && <ChoroplethLayer>}`)
6
+ * are appended to the top of the maplibre stack and end up visually above siblings
7
+ * that mounted earlier — even when JSX puts them first. Passing the returned value as
8
+ * `beforeId` to a `<Layer>` keeps the rendered stack aligned with JSX order.
9
+ *
10
+ * Only returns an id that actually exists in the map right now, so the result is
11
+ * always safe to pass to `map.addLayer(opts, beforeId)`.
12
+ */
13
+ export declare const useLayerBeforeId: (layerId: string) => string | undefined;
@@ -16,23 +16,28 @@ var __copyProps = (to, from, except, desc) => {
16
16
  return to;
17
17
  };
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
- var use_map_mouse_move_exports = {};
20
- __export(use_map_mouse_move_exports, {
21
- useMapMouseMove: () => useMapMouseMove
19
+ var use_layer_before_id_exports = {};
20
+ __export(use_layer_before_id_exports, {
21
+ useLayerBeforeId: () => useLayerBeforeId
22
22
  });
23
- module.exports = __toCommonJS(use_map_mouse_move_exports);
23
+ module.exports = __toCommonJS(use_layer_before_id_exports);
24
24
  var import_react_maplibre = require("@vis.gl/react-maplibre");
25
25
  var import_react = require("react");
26
- const useMapMouseMove = (layerIds, callback) => {
26
+ var import_layer_ids_context = require("../contexts/layer-ids.context.js");
27
+ const useLayerBeforeId = (layerId) => {
28
+ const layerIds = (0, import_react.useContext)(import_layer_ids_context.LayerIdsContext);
27
29
  const { current: map } = (0, import_react_maplibre.useMap)();
28
- (0, import_react.useEffect)(() => {
29
- layerIds.forEach((layerId) => {
30
- map?.on("mousemove", layerId, callback);
31
- });
32
- return () => {
33
- layerIds.forEach((layerId) => {
34
- map?.off("mousemove", layerId, callback);
35
- });
36
- };
37
- });
30
+ if (!map) {
31
+ return void 0;
32
+ }
33
+ const currentIndex = layerIds.indexOf(layerId);
34
+ if (currentIndex === -1) {
35
+ return void 0;
36
+ }
37
+ for (let i = currentIndex + 1; i < layerIds.length; i++) {
38
+ if (map.getLayer(layerIds[i])) {
39
+ return layerIds[i];
40
+ }
41
+ }
42
+ return void 0;
38
43
  };
@@ -22,6 +22,7 @@ __export(use_load_map_base_layer_exports, {
22
22
  });
23
23
  module.exports = __toCommonJS(use_load_map_base_layer_exports);
24
24
  var import_react = require("react");
25
+ var import_use_map_view_provider_context = require("./use-map-view-provider-context.js");
25
26
  var import_apply_feature_filter_rules = require("../utils/apply-feature-filter-rules.js");
26
27
  var import_base_layer_rules = require("../utils/base-layer-rules.js");
27
28
  var import_fetch_base_layer_features = require("../utils/fetch-base-layer-features.js");
@@ -34,13 +35,17 @@ const useLoadMapBaseLayer = (baseLayerConfig) => {
34
35
  const [isMapEnabled, setIsMapEnabled] = (0, import_react.useState)(false);
35
36
  const [baseFeatureCollection, setBaseFeatureCollection] = (0, import_react.useState)(void 0);
36
37
  const [error, setError] = (0, import_react.useState)(false);
38
+ const {
39
+ countryCode: providerCountryCode,
40
+ displayWorldMap: providerDisplayWorldMap
41
+ } = (0, import_use_map_view_provider_context.useMapViewProviderContext)();
37
42
  const getData = (0, import_react.useCallback)(async () => {
38
43
  setIsFetchingFeatures(true);
39
- const isMapEnabledResponse = await (0, import_fetch_client_config_map_enabled.fetchClientConfigMapEnabled)();
44
+ const isMapEnabledResponse = providerDisplayWorldMap ?? await (0, import_fetch_client_config_map_enabled.fetchClientConfigMapEnabled)();
40
45
  setIsMapEnabled(isMapEnabledResponse);
41
46
  try {
42
47
  if (isMapEnabledResponse) {
43
- const tenantCountryCode = await (0, import_get_tenant_country_code.getTenantCountryCode)();
48
+ const tenantCountryCode = providerCountryCode ?? await (0, import_get_tenant_country_code.getTenantCountryCode)();
44
49
  const { includeWorldView, countryRegions } = (0, import_get_base_layer_shapes_request_config.getBaseLayerShapesRequestConfig)(baseLayerConfig.include);
45
50
  const featuresRequests = [];
46
51
  if (includeWorldView) {
@@ -71,7 +76,12 @@ const useLoadMapBaseLayer = (baseLayerConfig) => {
71
76
  setError(true);
72
77
  }
73
78
  setIsFetchingFeatures(false);
74
- }, [baseLayerConfig.include, baseLayerConfig.exclude]);
79
+ }, [
80
+ baseLayerConfig.include,
81
+ baseLayerConfig.exclude,
82
+ providerCountryCode,
83
+ providerDisplayWorldMap
84
+ ]);
75
85
  (0, import_react.useEffect)(() => {
76
86
  getData();
77
87
  }, [getData]);
@@ -0,0 +1,34 @@
1
+ export interface UseMapRuntimeErrorOptions {
2
+ /**
3
+ * Called when the retry budget (3 attempts) is exhausted and the map cannot
4
+ * recover. Throwing inside this callback will propagate to the nearest React
5
+ * ErrorBoundary, showing the fallback UI.
6
+ */
7
+ onError: () => void;
8
+ /**
9
+ * Optional callback invoked on each recoverable error attempt before the
10
+ * budget is exhausted. The `attempt` argument is 1-indexed.
11
+ */
12
+ onRetry?: (attempt: number) => void;
13
+ }
14
+ /**
15
+ * Unified hook that guards MapView against maplibre-gl runtime errors from
16
+ * three distinct sources:
17
+ *
18
+ * 1. **WebGL context loss** (`webglcontextlost` on the canvas) — composed via
19
+ * `useWebGLContextError`.
20
+ * 2. **maplibre's own error events** (`map.on('error', ...)`), covering tile
21
+ * load failures and other internally dispatched errors.
22
+ * 3. **Synchronous throws from the rAF render loop** that escape to
23
+ * `window.onerror` — shader compilation, program link, and feature-index
24
+ * out-of-bounds errors that maplibre does not catch internally.
25
+ *
26
+ * A shared retry counter (max 3) is maintained across all sources. Error
27
+ * counting is debounced at 500 ms so that a burst of errors within a single
28
+ * render frame counts as one occurrence. The counter resets whenever the map
29
+ * fires an `idle` event (indicating a successful render). Once the budget is
30
+ * exhausted, `onError` is invoked.
31
+ *
32
+ * APPDEV-17938
33
+ */
34
+ export declare const useMapRuntimeError: ({ onError, onRetry, }: UseMapRuntimeErrorOptions) => void;
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var use_map_runtime_error_exports = {};
20
+ __export(use_map_runtime_error_exports, {
21
+ useMapRuntimeError: () => useMapRuntimeError
22
+ });
23
+ module.exports = __toCommonJS(use_map_runtime_error_exports);
24
+ var import_react_maplibre = require("@vis.gl/react-maplibre");
25
+ var import_react = require("react");
26
+ var import_use_webgl_context_error = require("./use-webgl-context-error.js");
27
+ const MAX_RETRIES = 3;
28
+ const ERROR_DEBOUNCE_MS = 500;
29
+ const MAPLIBRE_RUNTIME_ERROR_PATTERNS = [
30
+ "Could not compile fragment shader",
31
+ "Could not compile vertex shader",
32
+ "Program failed to link",
33
+ "feature index out of bounds",
34
+ "Out of bounds. Index requested"
35
+ ];
36
+ const isMaplibreRuntimeError = (message) => MAPLIBRE_RUNTIME_ERROR_PATTERNS.some((pattern) => message.includes(pattern));
37
+ const useMapRuntimeError = ({
38
+ onError,
39
+ onRetry
40
+ }) => {
41
+ const { current: mapRef } = (0, import_react_maplibre.useMap)();
42
+ const retryCountRef = (0, import_react.useRef)(0);
43
+ const lastErrorTimeRef = (0, import_react.useRef)(0);
44
+ const isMapActiveRef = (0, import_react.useRef)(true);
45
+ const onErrorRef = (0, import_react.useRef)(onError);
46
+ onErrorRef.current = onError;
47
+ const onRetryRef = (0, import_react.useRef)(onRetry);
48
+ onRetryRef.current = onRetry;
49
+ const handleError = (0, import_react.useCallback)(() => {
50
+ const now = Date.now();
51
+ if (now - lastErrorTimeRef.current < ERROR_DEBOUNCE_MS) {
52
+ return;
53
+ }
54
+ lastErrorTimeRef.current = now;
55
+ retryCountRef.current += 1;
56
+ if (retryCountRef.current >= MAX_RETRIES) {
57
+ onErrorRef.current();
58
+ } else {
59
+ onRetryRef.current?.(retryCountRef.current);
60
+ }
61
+ }, []);
62
+ (0, import_use_webgl_context_error.useWebGLContextError)(handleError);
63
+ (0, import_react.useEffect)(() => {
64
+ const map = mapRef?.getMap();
65
+ if (!map) {
66
+ return;
67
+ }
68
+ const handleMapError = ({ error }) => {
69
+ if (isMaplibreRuntimeError(error.message)) {
70
+ handleError();
71
+ }
72
+ };
73
+ map.on("error", handleMapError);
74
+ return () => {
75
+ map.off("error", handleMapError);
76
+ };
77
+ }, [mapRef, handleError]);
78
+ (0, import_react.useEffect)(() => {
79
+ const handleWindowError = (event) => {
80
+ if (!isMapActiveRef.current) {
81
+ return;
82
+ }
83
+ if (isMaplibreRuntimeError(event.message)) {
84
+ event.preventDefault();
85
+ handleError();
86
+ }
87
+ };
88
+ window.addEventListener("error", handleWindowError);
89
+ return () => {
90
+ window.removeEventListener("error", handleWindowError);
91
+ };
92
+ }, [handleError]);
93
+ (0, import_react.useEffect)(() => {
94
+ const map = mapRef?.getMap();
95
+ if (!map) {
96
+ return;
97
+ }
98
+ const handleRender = () => {
99
+ isMapActiveRef.current = true;
100
+ };
101
+ const handleIdle = () => {
102
+ isMapActiveRef.current = false;
103
+ retryCountRef.current = 0;
104
+ };
105
+ map.on("render", handleRender);
106
+ map.on("idle", handleIdle);
107
+ return () => {
108
+ map.off("render", handleRender);
109
+ map.off("idle", handleIdle);
110
+ };
111
+ }, [mapRef]);
112
+ };
@@ -0,0 +1 @@
1
+ export declare const useMapViewProviderContext: () => import("../index.js").MapViewProviderProps;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var use_map_view_provider_context_exports = {};
20
+ __export(use_map_view_provider_context_exports, {
21
+ useMapViewProviderContext: () => useMapViewProviderContext
22
+ });
23
+ module.exports = __toCommonJS(use_map_view_provider_context_exports);
24
+ var import_react = require("react");
25
+ var import_map_view_provider_context = require("../contexts/map-view-provider.context.js");
26
+ const useMapViewProviderContext = () => (0, import_react.useContext)(import_map_view_provider_context.MapViewProviderContext);
@@ -21,7 +21,9 @@ __export(use_overlay_events_exports, {
21
21
  useOverlayEvents: () => useOverlayEvents
22
22
  });
23
23
  module.exports = __toCommonJS(use_overlay_events_exports);
24
+ var import_react = require("react");
24
25
  var import_charts = require("@dynatrace/strato-components/charts");
26
+ var import_geo_data_lookup_context = require("../contexts/geo-data-lookup.context.js");
25
27
  var import_store = require("../store/store.js");
26
28
  var import_build_geo_tooltip_state = require("../utils/build-geo-tooltip-state.js");
27
29
  var import_parse_tooltip_data = require("../utils/parse-tooltip-data.js");
@@ -38,6 +40,7 @@ const layerIdToGeometry = (layerId) => {
38
40
  return "geoDot";
39
41
  };
40
42
  const useOverlayEvents = () => {
43
+ const dataLookupRegistry = (0, import_react.useContext)(import_geo_data_lookup_context.GeoDataLookupContext);
41
44
  const setOverlayState = (0, import_store.useSetStateOverlay)();
42
45
  const setState = (0, import_store.useSetState)();
43
46
  const dispatch = (0, import_charts._useOverlayTooltipReducer)();
@@ -72,7 +75,10 @@ const useOverlayEvents = () => {
72
75
  if (currentState.pinned) {
73
76
  return;
74
77
  }
75
- const { data, hoveredLayerId } = (0, import_parse_tooltip_data.extractDataFromEvent)(event);
78
+ const { data, hoveredLayerId } = (0, import_parse_tooltip_data.extractDataFromEvent)(
79
+ event,
80
+ dataLookupRegistry
81
+ );
76
82
  overlay.clear();
77
83
  setTooltipMarker(hoveredLayerId, event.lngLat);
78
84
  const pos = getAbsolutePosition(event);
@@ -102,7 +108,10 @@ const useOverlayEvents = () => {
102
108
  }
103
109
  };
104
110
  const handleMouseClick = (event) => {
105
- const { data, featureId, hoveredLayerId } = (0, import_parse_tooltip_data.extractDataFromEvent)(event);
111
+ const { data, featureId, hoveredLayerId } = (0, import_parse_tooltip_data.extractDataFromEvent)(
112
+ event,
113
+ dataLookupRegistry
114
+ );
106
115
  if (!featureId) {
107
116
  hideTooltip();
108
117
  return;
@@ -12,4 +12,12 @@ export declare const isDefaultTooltipHandler: (handler: LayerTooltipHandler) =>
12
12
  * @param children -
13
13
  * @param layerType -
14
14
  */
15
+ export interface TooltipTemplateResult {
16
+ handler: LayerTooltipHandler | undefined;
17
+ hidden?: boolean;
18
+ symbolAlignment?: 'left' | 'right';
19
+ }
15
20
  export declare function useTooltipTemplate<T>(children: ReactNode | undefined, layerType: string | JSXElementConstructor<T>): LayerTooltipHandler | undefined;
21
+ export declare function useTooltipTemplate<T>(children: ReactNode | undefined, layerType: string | JSXElementConstructor<T>, options: {
22
+ extractProps: true;
23
+ }): TooltipTemplateResult;
@@ -42,10 +42,18 @@ const createDefaultHandlerWithActions = (seriesActions) => {
42
42
  return handler;
43
43
  };
44
44
  const isDefaultTooltipHandler = (handler) => handler.__isDefault ?? false;
45
- function useTooltipTemplate(children, layerType) {
45
+ function useTooltipTemplate(children, layerType, options) {
46
46
  let template = void 0;
47
+ let hidden = void 0;
48
+ let symbolAlignment = void 0;
47
49
  import_react.Children.forEach(children, (child) => {
48
50
  if ((0, import_react.isValidElement)(child) && child.type === layerType) {
51
+ hidden = child.props.hidden;
52
+ symbolAlignment = child.props.symbolAlignment;
53
+ if (child.props.hidden) {
54
+ template = void 0;
55
+ return;
56
+ }
49
57
  if ((0, import_lodash_es.isNil)(child.props.children)) {
50
58
  template = child.props.seriesActions ? createDefaultHandlerWithActions(child.props.seriesActions) : defaultTooltipHandler;
51
59
  } else {
@@ -53,5 +61,12 @@ function useTooltipTemplate(children, layerType) {
53
61
  }
54
62
  }
55
63
  });
56
- return template;
64
+ if (options?.extractProps) {
65
+ return {
66
+ handler: hidden ? void 0 : template ?? defaultTooltipHandler,
67
+ hidden,
68
+ symbolAlignment
69
+ };
70
+ }
71
+ return hidden ? void 0 : template ?? defaultTooltipHandler;
57
72
  }
@@ -30,7 +30,8 @@ const useWebGLContextError = (onContextLost) => {
30
30
  if (!canvas) {
31
31
  return;
32
32
  }
33
- const handleContextLost = () => {
33
+ const handleContextLost = (event) => {
34
+ event.preventDefault();
34
35
  onContextLost?.();
35
36
  };
36
37
  canvas.addEventListener("webglcontextlost", handleContextLost);
package/map/index.d.ts CHANGED
@@ -25,3 +25,5 @@ export { ThresholdLegend } from './slots/ThresholdLegend.js';
25
25
  export { CategoricalLegend } from './slots/CategoricalLegend.js';
26
26
  export type { BubbleLayerTooltipHandler, BubbleLayerTooltipHandlerProps, DotLayerTooltipHandler, DotLayerTooltipHandlerProps, ConnectionLayerTooltipHandler, ConnectionLayerTooltipHandlerProps, ChoroplethLayerTooltipHandlerProps, ChoroplethLayerTooltipHandler, ChartTooltip, DotLayerTooltipData, BubbleLayerTooltipData, ConnectionLayerTooltipData, ChoroplethLayerTooltipData, } from './types/tooltip.js';
27
27
  export { getAllCountries } from './utils/get-all-countries.js';
28
+ export { MapViewProvider } from './providers/map-view.provider.js';
29
+ export type { MapViewProviderProps } from './types/map-view-provider.js';
package/map/index.js CHANGED
@@ -27,6 +27,7 @@ __export(map_exports, {
27
27
  DotLayer: () => import_DotLayer.DotLayer,
28
28
  DownloadCSV: () => import_DownloadCSV.DownloadCSV,
29
29
  MapView: () => import_MapView.MapView,
30
+ MapViewProvider: () => import_map_view_provider.MapViewProvider,
30
31
  SequentialLegend: () => import_SequentialLegend.SequentialLegend,
31
32
  ThresholdLegend: () => import_ThresholdLegend.ThresholdLegend,
32
33
  Tooltip: () => import_Tooltip.Tooltip,
@@ -47,3 +48,4 @@ var import_SequentialLegend = require("./slots/SequentialLegend.js");
47
48
  var import_ThresholdLegend = require("./slots/ThresholdLegend.js");
48
49
  var import_CategoricalLegend = require("./slots/CategoricalLegend.js");
49
50
  var import_get_all_countries = require("./utils/get-all-countries.js");
51
+ var import_map_view_provider = require("./providers/map-view.provider.js");
@@ -0,0 +1,7 @@
1
+ import { type PropsWithChildren } from 'react';
2
+ import type { MapViewProviderProps } from '../types/map-view-provider.js';
3
+ /**
4
+ * The `MapViewProvider` is a component that provides shared configuration to nested `MapView` instances.
5
+ * @public
6
+ */
7
+ export declare const MapViewProvider: ({ children, countryCode, displayWorldMap, }: PropsWithChildren<MapViewProviderProps>) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var map_view_provider_exports = {};
20
+ __export(map_view_provider_exports, {
21
+ MapViewProvider: () => MapViewProvider
22
+ });
23
+ module.exports = __toCommonJS(map_view_provider_exports);
24
+ var import_jsx_runtime = require("react/jsx-runtime");
25
+ var import_react = require("react");
26
+ var import_map_view_provider_context = require("../contexts/map-view-provider.context.js");
27
+ const MapViewProvider = ({
28
+ children,
29
+ countryCode,
30
+ displayWorldMap
31
+ }) => {
32
+ const value = (0, import_react.useMemo)(
33
+ () => ({ countryCode, displayWorldMap }),
34
+ [countryCode, displayWorldMap]
35
+ );
36
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_map_view_provider_context.MapViewProviderContext.Provider, { value, children });
37
+ };
@@ -4,11 +4,13 @@ import type { ChartTooltip } from '../types/tooltip.js';
4
4
  * Tooltip is responsible for exposing the
5
5
  * ChartTooltip props, such as, sections, to the consumer
6
6
  * @public
7
+ * @deprecated Use `ChartTooltip` from `@dynatrace/strato-components/charts` instead. Removal: APPDEV-17834
7
8
  */
8
9
  export declare const Tooltip: ChartTooltip;
9
10
  /**
10
11
  * TooltipAtoms is responsible for exposing the
11
12
  * ChartTooltip atoms.
12
13
  * @public
14
+ * @deprecated Use `ChartTooltip` from `@dynatrace/strato-components/charts` instead. Removal: APPDEV-17834
13
15
  */
14
16
  export declare const TooltipAtoms: ChartTooltipAtomsType;
@@ -53,12 +53,12 @@ export type InternalConnectionLayerProps<T extends Connection> = ConnectionLayer
53
53
  /** @internal */
54
54
  export interface FeatureProperties {
55
55
  id: string;
56
+ __dataIndex?: number;
56
57
  __lineColor: string;
57
58
  __lineHoveredColor: string;
58
59
  __lineWidth: number;
59
60
  __angle?: number;
60
61
  curve?: CurvedLine;
61
- path: Location[];
62
62
  }
63
63
  export type GeoJSONFeature<T extends GeoJSON.Geometry> = GeoJSON.Feature<T, FeatureProperties>;
64
64
  /**
@@ -79,10 +79,3 @@ export interface ConnectionColorProps<T extends Connection> {
79
79
  */
80
80
  color?: string | ((connection: T) => string);
81
81
  }
82
- /** @internal */
83
- export type ConnectionTooltipStatePayload = {
84
- path: Location[];
85
- __lineColor: string;
86
- __lineWidth: number;
87
- __nullValues: string[] | undefined;
88
- };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * The `MapViewProvider` props.
3
+ * @public
4
+ */
5
+ export type MapViewProviderProps = {
6
+ /** Country code for regions with disputed borders */
7
+ countryCode?: 'CN' | 'IN' | 'IL' | 'MA';
8
+ /** Whether the world map is displayed */
9
+ displayWorldMap?: boolean;
10
+ };
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+ var map_view_provider_exports = {};
16
+ module.exports = __toCommonJS(map_view_provider_exports);