@trackunit/react-map 0.2.210 → 0.2.212
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/index.cjs.js +45 -8
- package/index.esm.js +45 -8
- package/package.json +6 -6
- package/src/index.d.ts +1 -1
- package/src/layers/shared/consoleWarnMap.d.ts +5 -0
- package/src/layers/types.d.ts +4 -2
- package/src/layers/useHeatmap/useHeatmap.d.ts +9 -0
- package/src/layers/useHeatmap/utils/warnHeatmap.d.ts +0 -4
package/index.cjs.js
CHANGED
|
@@ -5888,11 +5888,12 @@ const useFitToContent = (api, handles, options) => {
|
|
|
5888
5888
|
};
|
|
5889
5889
|
|
|
5890
5890
|
/**
|
|
5891
|
-
* Single dev-warning channel for
|
|
5891
|
+
* Single dev-warning channel for react-map hooks (invalid data, invalid style, unhandled render errors).
|
|
5892
|
+
* Messages are prefixed with the emitting hook, e.g. `[useHeatmap]`.
|
|
5892
5893
|
*/
|
|
5893
|
-
const
|
|
5894
|
-
// eslint-disable-next-line no-console -- Intentional: the one
|
|
5895
|
-
console.warn(`[
|
|
5894
|
+
const consoleWarnMap = (source, message, ...details) => {
|
|
5895
|
+
// eslint-disable-next-line no-console -- Intentional: the one react-map warning channel; invalid input is dropped or defaulted and render errors without onError must stay visible
|
|
5896
|
+
console.warn(`[${source}] ${message}`, ...details);
|
|
5896
5897
|
};
|
|
5897
5898
|
|
|
5898
5899
|
/**
|
|
@@ -5930,7 +5931,7 @@ const normalizeHeatmapData = ({ data, getPosition, getWeight, }) => {
|
|
|
5930
5931
|
});
|
|
5931
5932
|
}
|
|
5932
5933
|
if (invalidPositionCount > 0 || invalidWeightCount > 0) {
|
|
5933
|
-
|
|
5934
|
+
consoleWarnMap("useHeatmap", `Filtered ${invalidPositionCount} item(s) with invalid position and ${invalidWeightCount} item(s) with invalid weight. Expected [longitude, latitude] with longitude between -180 and 180, latitude between -90 and 90, and a finite weight >= 0.`);
|
|
5934
5935
|
}
|
|
5935
5936
|
return {
|
|
5936
5937
|
features: { type: "FeatureCollection", features },
|
|
@@ -5993,7 +5994,7 @@ const resolveColorRange = (colorRange) => {
|
|
|
5993
5994
|
const valid = parsed.filter(sharedUtils.nonNullable);
|
|
5994
5995
|
if (colorRange.length >= 2 && valid.length === parsed.length)
|
|
5995
5996
|
return valid;
|
|
5996
|
-
|
|
5997
|
+
consoleWarnMap("useHeatmap", "colorRange needs at least two supported colours (#rgb, #rrggbb, #rrggbbaa, rgb(), rgba()); using the default.", colorRange);
|
|
5997
5998
|
return DEFAULT_PARSED_COLOR_RANGE;
|
|
5998
5999
|
};
|
|
5999
6000
|
const HEATMAP_STYLE_RULES = {
|
|
@@ -6026,7 +6027,7 @@ const resolveHeatmapStyle = (style) => {
|
|
|
6026
6027
|
colorRange: resolveColorRange(style?.colorRange),
|
|
6027
6028
|
};
|
|
6028
6029
|
if (nonFiniteKeys.length > 0) {
|
|
6029
|
-
|
|
6030
|
+
consoleWarnMap("useHeatmap", `Non-finite style value(s) for ${nonFiniteKeys.join(", ")} replaced with defaults.`);
|
|
6030
6031
|
}
|
|
6031
6032
|
return resolved;
|
|
6032
6033
|
};
|
|
@@ -6040,8 +6041,41 @@ const EMPTY_CONTROLS$2 = {};
|
|
|
6040
6041
|
* - Renderers: ADR-0029 (`libs/react/map/docs/adr/0029-heatmap-provider-specific-renderers.md`).
|
|
6041
6042
|
*/
|
|
6042
6043
|
const useHeatmap = (options) => {
|
|
6043
|
-
const { id, name, data, getPosition, getWeight, style, controls, loading, fitParticipation = "all" } = options;
|
|
6044
|
+
const { id, name, data, getPosition, getWeight, style, onError, controls, loading, fitParticipation = "all", } = options;
|
|
6044
6045
|
const layerReady = useLayerReady(loading);
|
|
6046
|
+
const onErrorRef = react.useRef(onError);
|
|
6047
|
+
react.useEffect(() => {
|
|
6048
|
+
onErrorRef.current = onError;
|
|
6049
|
+
}, [onError]);
|
|
6050
|
+
const errorHandler = reactCoreHooks.useErrorHandlerOrNull();
|
|
6051
|
+
// Sentry at most once per layer/code per hook mount, like the shape hooks' fill-tiling reports.
|
|
6052
|
+
const sentryReportedKeysRef = react.useRef(new Set());
|
|
6053
|
+
const captureOnce = react.useCallback((key, message, cause, fingerprintCode) => {
|
|
6054
|
+
if (errorHandler === null || sentryReportedKeysRef.current.has(key))
|
|
6055
|
+
return;
|
|
6056
|
+
sentryReportedKeysRef.current.add(key);
|
|
6057
|
+
errorHandler.captureException(new Error(message, { cause }), {
|
|
6058
|
+
level: "warning",
|
|
6059
|
+
fingerprint: ["react-map", "heatmap", fingerprintCode],
|
|
6060
|
+
});
|
|
6061
|
+
}, [errorHandler]);
|
|
6062
|
+
const reportError = react.useCallback((error) => {
|
|
6063
|
+
const payload = JSON.stringify({ layerId: error.layerId, code: error.code });
|
|
6064
|
+
captureOnce(`${error.layerId}:${error.code}`, `Heatmap failed to render: ${payload}`, error.cause, error.code);
|
|
6065
|
+
const handler = onErrorRef.current;
|
|
6066
|
+
if (handler !== undefined) {
|
|
6067
|
+
// Adapters call this mid-sync; a throwing handler must not skip the rest of the layer snapshot.
|
|
6068
|
+
try {
|
|
6069
|
+
handler(error);
|
|
6070
|
+
}
|
|
6071
|
+
catch (handlerError) {
|
|
6072
|
+
consoleWarnMap("useHeatmap", `onError for heatmap "${error.layerId}" threw.`, handlerError, error.cause);
|
|
6073
|
+
captureOnce(`${error.layerId}:on-error-threw`, `Heatmap onError threw: ${payload}`, handlerError, "on-error-threw");
|
|
6074
|
+
}
|
|
6075
|
+
return;
|
|
6076
|
+
}
|
|
6077
|
+
consoleWarnMap("useHeatmap", `Heatmap "${error.layerId}" failed to render (${error.code}).`, error.cause);
|
|
6078
|
+
}, [captureOnce]);
|
|
6045
6079
|
// Keyed on `data` (adjust-state-during-render + isEqual) so inline accessors
|
|
6046
6080
|
// don't re-normalize the whole dataset on every render. Accessor changes
|
|
6047
6081
|
// apply on the next `data` change.
|
|
@@ -6078,6 +6112,7 @@ const useHeatmap = (options) => {
|
|
|
6078
6112
|
layerType: "heatmap",
|
|
6079
6113
|
features: normalized.features,
|
|
6080
6114
|
style: resolvedStyle,
|
|
6115
|
+
onError: reportError,
|
|
6081
6116
|
pointCount: normalized.features.features.length,
|
|
6082
6117
|
totalCount: data.length,
|
|
6083
6118
|
}), [
|
|
@@ -6090,6 +6125,7 @@ const useHeatmap = (options) => {
|
|
|
6090
6125
|
fitParticipation,
|
|
6091
6126
|
normalized.features,
|
|
6092
6127
|
resolvedStyle,
|
|
6128
|
+
reportError,
|
|
6093
6129
|
data.length,
|
|
6094
6130
|
]);
|
|
6095
6131
|
};
|
|
@@ -8482,6 +8518,7 @@ function toMapLayer(handle) {
|
|
|
8482
8518
|
id: handle.id,
|
|
8483
8519
|
features: handle.features,
|
|
8484
8520
|
style: handle.style,
|
|
8521
|
+
onError: handle.onError,
|
|
8485
8522
|
};
|
|
8486
8523
|
default: {
|
|
8487
8524
|
const exhaustiveCheck = handle;
|
package/index.esm.js
CHANGED
|
@@ -5887,11 +5887,12 @@ const useFitToContent = (api, handles, options) => {
|
|
|
5887
5887
|
};
|
|
5888
5888
|
|
|
5889
5889
|
/**
|
|
5890
|
-
* Single dev-warning channel for
|
|
5890
|
+
* Single dev-warning channel for react-map hooks (invalid data, invalid style, unhandled render errors).
|
|
5891
|
+
* Messages are prefixed with the emitting hook, e.g. `[useHeatmap]`.
|
|
5891
5892
|
*/
|
|
5892
|
-
const
|
|
5893
|
-
// eslint-disable-next-line no-console -- Intentional: the one
|
|
5894
|
-
console.warn(`[
|
|
5893
|
+
const consoleWarnMap = (source, message, ...details) => {
|
|
5894
|
+
// eslint-disable-next-line no-console -- Intentional: the one react-map warning channel; invalid input is dropped or defaulted and render errors without onError must stay visible
|
|
5895
|
+
console.warn(`[${source}] ${message}`, ...details);
|
|
5895
5896
|
};
|
|
5896
5897
|
|
|
5897
5898
|
/**
|
|
@@ -5929,7 +5930,7 @@ const normalizeHeatmapData = ({ data, getPosition, getWeight, }) => {
|
|
|
5929
5930
|
});
|
|
5930
5931
|
}
|
|
5931
5932
|
if (invalidPositionCount > 0 || invalidWeightCount > 0) {
|
|
5932
|
-
|
|
5933
|
+
consoleWarnMap("useHeatmap", `Filtered ${invalidPositionCount} item(s) with invalid position and ${invalidWeightCount} item(s) with invalid weight. Expected [longitude, latitude] with longitude between -180 and 180, latitude between -90 and 90, and a finite weight >= 0.`);
|
|
5933
5934
|
}
|
|
5934
5935
|
return {
|
|
5935
5936
|
features: { type: "FeatureCollection", features },
|
|
@@ -5992,7 +5993,7 @@ const resolveColorRange = (colorRange) => {
|
|
|
5992
5993
|
const valid = parsed.filter(nonNullable);
|
|
5993
5994
|
if (colorRange.length >= 2 && valid.length === parsed.length)
|
|
5994
5995
|
return valid;
|
|
5995
|
-
|
|
5996
|
+
consoleWarnMap("useHeatmap", "colorRange needs at least two supported colours (#rgb, #rrggbb, #rrggbbaa, rgb(), rgba()); using the default.", colorRange);
|
|
5996
5997
|
return DEFAULT_PARSED_COLOR_RANGE;
|
|
5997
5998
|
};
|
|
5998
5999
|
const HEATMAP_STYLE_RULES = {
|
|
@@ -6025,7 +6026,7 @@ const resolveHeatmapStyle = (style) => {
|
|
|
6025
6026
|
colorRange: resolveColorRange(style?.colorRange),
|
|
6026
6027
|
};
|
|
6027
6028
|
if (nonFiniteKeys.length > 0) {
|
|
6028
|
-
|
|
6029
|
+
consoleWarnMap("useHeatmap", `Non-finite style value(s) for ${nonFiniteKeys.join(", ")} replaced with defaults.`);
|
|
6029
6030
|
}
|
|
6030
6031
|
return resolved;
|
|
6031
6032
|
};
|
|
@@ -6039,8 +6040,41 @@ const EMPTY_CONTROLS$2 = {};
|
|
|
6039
6040
|
* - Renderers: ADR-0029 (`libs/react/map/docs/adr/0029-heatmap-provider-specific-renderers.md`).
|
|
6040
6041
|
*/
|
|
6041
6042
|
const useHeatmap = (options) => {
|
|
6042
|
-
const { id, name, data, getPosition, getWeight, style, controls, loading, fitParticipation = "all" } = options;
|
|
6043
|
+
const { id, name, data, getPosition, getWeight, style, onError, controls, loading, fitParticipation = "all", } = options;
|
|
6043
6044
|
const layerReady = useLayerReady(loading);
|
|
6045
|
+
const onErrorRef = useRef(onError);
|
|
6046
|
+
useEffect(() => {
|
|
6047
|
+
onErrorRef.current = onError;
|
|
6048
|
+
}, [onError]);
|
|
6049
|
+
const errorHandler = useErrorHandlerOrNull();
|
|
6050
|
+
// Sentry at most once per layer/code per hook mount, like the shape hooks' fill-tiling reports.
|
|
6051
|
+
const sentryReportedKeysRef = useRef(new Set());
|
|
6052
|
+
const captureOnce = useCallback((key, message, cause, fingerprintCode) => {
|
|
6053
|
+
if (errorHandler === null || sentryReportedKeysRef.current.has(key))
|
|
6054
|
+
return;
|
|
6055
|
+
sentryReportedKeysRef.current.add(key);
|
|
6056
|
+
errorHandler.captureException(new Error(message, { cause }), {
|
|
6057
|
+
level: "warning",
|
|
6058
|
+
fingerprint: ["react-map", "heatmap", fingerprintCode],
|
|
6059
|
+
});
|
|
6060
|
+
}, [errorHandler]);
|
|
6061
|
+
const reportError = useCallback((error) => {
|
|
6062
|
+
const payload = JSON.stringify({ layerId: error.layerId, code: error.code });
|
|
6063
|
+
captureOnce(`${error.layerId}:${error.code}`, `Heatmap failed to render: ${payload}`, error.cause, error.code);
|
|
6064
|
+
const handler = onErrorRef.current;
|
|
6065
|
+
if (handler !== undefined) {
|
|
6066
|
+
// Adapters call this mid-sync; a throwing handler must not skip the rest of the layer snapshot.
|
|
6067
|
+
try {
|
|
6068
|
+
handler(error);
|
|
6069
|
+
}
|
|
6070
|
+
catch (handlerError) {
|
|
6071
|
+
consoleWarnMap("useHeatmap", `onError for heatmap "${error.layerId}" threw.`, handlerError, error.cause);
|
|
6072
|
+
captureOnce(`${error.layerId}:on-error-threw`, `Heatmap onError threw: ${payload}`, handlerError, "on-error-threw");
|
|
6073
|
+
}
|
|
6074
|
+
return;
|
|
6075
|
+
}
|
|
6076
|
+
consoleWarnMap("useHeatmap", `Heatmap "${error.layerId}" failed to render (${error.code}).`, error.cause);
|
|
6077
|
+
}, [captureOnce]);
|
|
6044
6078
|
// Keyed on `data` (adjust-state-during-render + isEqual) so inline accessors
|
|
6045
6079
|
// don't re-normalize the whole dataset on every render. Accessor changes
|
|
6046
6080
|
// apply on the next `data` change.
|
|
@@ -6077,6 +6111,7 @@ const useHeatmap = (options) => {
|
|
|
6077
6111
|
layerType: "heatmap",
|
|
6078
6112
|
features: normalized.features,
|
|
6079
6113
|
style: resolvedStyle,
|
|
6114
|
+
onError: reportError,
|
|
6080
6115
|
pointCount: normalized.features.features.length,
|
|
6081
6116
|
totalCount: data.length,
|
|
6082
6117
|
}), [
|
|
@@ -6089,6 +6124,7 @@ const useHeatmap = (options) => {
|
|
|
6089
6124
|
fitParticipation,
|
|
6090
6125
|
normalized.features,
|
|
6091
6126
|
resolvedStyle,
|
|
6127
|
+
reportError,
|
|
6092
6128
|
data.length,
|
|
6093
6129
|
]);
|
|
6094
6130
|
};
|
|
@@ -8481,6 +8517,7 @@ function toMapLayer(handle) {
|
|
|
8481
8517
|
id: handle.id,
|
|
8482
8518
|
features: handle.features,
|
|
8483
8519
|
style: handle.style,
|
|
8520
|
+
onError: handle.onError,
|
|
8484
8521
|
};
|
|
8485
8522
|
default: {
|
|
8486
8523
|
const exhaustiveCheck = handle;
|
package/package.json
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trackunit/react-map",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.212",
|
|
4
4
|
"repository": "https://github.com/Trackunit/manager",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
6
6
|
"engines": {
|
|
7
7
|
"node": ">=24.x"
|
|
8
8
|
},
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"@trackunit/react-components": "3.8.
|
|
10
|
+
"@trackunit/react-components": "3.8.5",
|
|
11
11
|
"@trackunit/css-class-variance-utilities": "2.3.6",
|
|
12
|
-
"@trackunit/react-form-components": "2.10.
|
|
13
|
-
"@trackunit/react-core-hooks": "1.25.
|
|
12
|
+
"@trackunit/react-form-components": "2.10.12",
|
|
13
|
+
"@trackunit/react-core-hooks": "1.25.7",
|
|
14
14
|
"@trackunit/geo-json-utils": "1.18.6",
|
|
15
|
-
"@trackunit/i18n-library-translation": "2.8.
|
|
15
|
+
"@trackunit/i18n-library-translation": "2.8.7",
|
|
16
16
|
"react-minimal-pie-chart": "^8.4.0",
|
|
17
|
-
"@trackunit/react-map-adapter-shared": "0.0.
|
|
17
|
+
"@trackunit/react-map-adapter-shared": "0.0.158",
|
|
18
18
|
"@trackunit/react-map-color-utils": "0.0.132",
|
|
19
19
|
"@trackunit/shared-utils": "1.19.6",
|
|
20
20
|
"@trackunit/ui-design-tokens": "1.18.6",
|
package/src/index.d.ts
CHANGED
|
@@ -24,7 +24,7 @@ export type { ControlMiddleware, MiddlewareContext } from "./controls/renderingR
|
|
|
24
24
|
export type { CategoryMetadata } from "./controls/collapseControls";
|
|
25
25
|
export type { ClusterEntity, Entity, MapInteractionState, MarkerEntity, RouteEntity, ShapeEntity, ShapeType, } from "@trackunit/react-map-adapter-shared";
|
|
26
26
|
export { geometryTypeToShapeType, INITIAL_INTERACTION_STATE } from "@trackunit/react-map-adapter-shared";
|
|
27
|
-
export type { AdaptiveMarkerResolution, AdaptiveRenderConfig, AdaptiveRenderState, AdaptiveResolutionContext, CircleSymbolDescriptor, ClientClusterConfig, ClusterConfig, ClusterInfo, ClusterRenderState, ClusterSymbolStyle, CommonRenderState, DomPortalStackingInput, DomPortalStackingResolver, DomPortalStackingResult, DomRenderConfig, DomRenderState, FitParticipation, GeoJsonFeature, GeoJsonFeatureCollection, GeoJsonGeometry, HeatmapLayerHandle, HeatmapRgbaColor, ImageOverlayHandle, LayerHandle, LayerMeta, MarkerAnchor, MarkerDomPortalStackGeometry, MarkerDomPortalStackPhase, MarkerLayerHandle, RenderConfig, RenderMedium, ResolutionContext, RouteLayerHandle, RouteStyle, ServerClusterConfig, ShapeInteractiveMode, ShapeLayerHandle, ShapeOverlapConfig, ShapeStyle, ShapeStyleOverrides, ShapesUnderCursorHit, SymbolDescriptor, SymbolRenderConfig, SymbolRenderState, } from "./layers/types";
|
|
27
|
+
export type { AdaptiveMarkerResolution, AdaptiveRenderConfig, AdaptiveRenderState, AdaptiveResolutionContext, CircleSymbolDescriptor, ClientClusterConfig, ClusterConfig, ClusterInfo, ClusterRenderState, ClusterSymbolStyle, CommonRenderState, DomPortalStackingInput, DomPortalStackingResolver, DomPortalStackingResult, DomRenderConfig, DomRenderState, FitParticipation, GeoJsonFeature, GeoJsonFeatureCollection, GeoJsonGeometry, HeatmapLayerHandle, HeatmapRenderError, HeatmapRgbaColor, ImageOverlayHandle, LayerHandle, LayerMeta, MarkerAnchor, MarkerDomPortalStackGeometry, MarkerDomPortalStackPhase, MarkerLayerHandle, RenderConfig, RenderMedium, ResolutionContext, RouteLayerHandle, RouteStyle, ServerClusterConfig, ShapeInteractiveMode, ShapeLayerHandle, ShapeOverlapConfig, ShapeStyle, ShapeStyleOverrides, ShapesUnderCursorHit, SymbolDescriptor, SymbolRenderConfig, SymbolRenderState, } from "./layers/types";
|
|
28
28
|
export { computeMarkerDomPortalZIndex } from "./layers/types";
|
|
29
29
|
export { ANCHOR_SELECTOR, HIT_SURFACE_SELECTOR } from "@trackunit/react-map-adapter-shared";
|
|
30
30
|
export { ClusterMarker, type ClusterMarkerProps, type ClusterMarkerStickInput, type ClusterSegment, } from "./clusters/ClusterMarker";
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single dev-warning channel for react-map hooks (invalid data, invalid style, unhandled render errors).
|
|
3
|
+
* Messages are prefixed with the emitting hook, e.g. `[useHeatmap]`.
|
|
4
|
+
*/
|
|
5
|
+
export declare const consoleWarnMap: (source: string, message: string, ...details: ReadonlyArray<unknown>) => void;
|
package/src/layers/types.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { GeoJsonBbox, GeoJsonFeature, GeoJsonFeatureCollection, GeoJsonGeometry, GeoJsonPosition } from "@trackunit/geo-json-utils";
|
|
2
|
-
import type { AdaptiveMarkerResolution, ClusterConfig, ClusterRenderConfig, HeatmapRenderStyle, RenderConfig, RouteStyle, ShapeInteractiveMode, ShapeStyle } from "@trackunit/react-map-adapter-shared";
|
|
2
|
+
import type { AdaptiveMarkerResolution, ClusterConfig, ClusterRenderConfig, HeatmapRenderError, HeatmapRenderStyle, RenderConfig, RouteStyle, ShapeInteractiveMode, ShapeStyle } from "@trackunit/react-map-adapter-shared";
|
|
3
3
|
import type { CategoryKey, ControlConfig } from "../controls/types";
|
|
4
4
|
import type { ShapeDecoration } from "./useShapes/shapeDecorations";
|
|
5
5
|
import type { ShapesUnderCursorHit } from "./useShapes/shapeFillTiling";
|
|
6
6
|
import type { ShapeLabelResolutionContext } from "./useShapes/shapeLabelResolution";
|
|
7
7
|
import type { ResolveShapeStackOrder } from "./useShapes/shapeStackOrder";
|
|
8
8
|
export type { ShapesUnderCursorHit };
|
|
9
|
-
export type { AdaptiveMarkerResolution, AdaptiveRenderConfig, AdaptiveRenderState, AdaptiveResolutionContext, CircleSymbolDescriptor, ClientClusterConfig, ClusterConfig, ClusterDomRenderConfig, ClusterInfo, ClusterRenderConfig, ClusterRenderState, ClusterSymbolRenderConfig, ClusterSymbolStyle, CommonRenderState, DomPortalStackingInput, DomPortalStackingResolver, DomPortalStackingResult, DomRenderConfig, DomRenderState, GeoJsonFeature, GeoJsonFeatureCollection, GeoJsonGeometry, HeatmapRenderStyle, HeatmapRgbaColor, MarkerAnchor, MarkerDomPortalStackGeometry, MarkerDomPortalStackPhase, PixelOffset, RenderConfig, RenderMedium, ResolutionContext, RouteStyle, ServerClusterConfig, ShapeInteractiveMode, ShapeStyle, ShapeStyleOverrides, SymbolDescriptor, SymbolRenderConfig, SymbolRenderState, } from "@trackunit/react-map-adapter-shared";
|
|
9
|
+
export type { AdaptiveMarkerResolution, AdaptiveRenderConfig, AdaptiveRenderState, AdaptiveResolutionContext, CircleSymbolDescriptor, ClientClusterConfig, ClusterConfig, ClusterDomRenderConfig, ClusterInfo, ClusterRenderConfig, ClusterRenderState, ClusterSymbolRenderConfig, ClusterSymbolStyle, CommonRenderState, DomPortalStackingInput, DomPortalStackingResolver, DomPortalStackingResult, DomRenderConfig, DomRenderState, GeoJsonFeature, GeoJsonFeatureCollection, GeoJsonGeometry, HeatmapRenderError, HeatmapRenderStyle, HeatmapRgbaColor, MarkerAnchor, MarkerDomPortalStackGeometry, MarkerDomPortalStackPhase, PixelOffset, RenderConfig, RenderMedium, ResolutionContext, RouteStyle, ServerClusterConfig, ShapeInteractiveMode, ShapeStyle, ShapeStyleOverrides, SymbolDescriptor, SymbolRenderConfig, SymbolRenderState, } from "@trackunit/react-map-adapter-shared";
|
|
10
10
|
export { computeMarkerDomPortalZIndex } from "@trackunit/react-map-adapter-shared";
|
|
11
11
|
/**
|
|
12
12
|
* Controls whether a layer's bounds are included in fit-to-content operations.
|
|
@@ -191,6 +191,8 @@ export interface HeatmapLayerHandle extends LayerMeta {
|
|
|
191
191
|
readonly layerType: "heatmap";
|
|
192
192
|
readonly features: GeoJsonFeatureCollection;
|
|
193
193
|
readonly style: HeatmapRenderStyle;
|
|
194
|
+
/** Stable error reporter forwarded to the adapter; calls the consumer's latest `onError` or warns. */
|
|
195
|
+
readonly onError: (error: HeatmapRenderError) => void;
|
|
194
196
|
}
|
|
195
197
|
/**
|
|
196
198
|
* Discriminated union of all layer handle types.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { GeoJsonPosition } from "@trackunit/geo-json-utils";
|
|
2
|
+
import type { HeatmapRenderError } from "@trackunit/react-map-adapter-shared";
|
|
2
3
|
import type { CategoryKey, ControlConfig } from "../../controls/types";
|
|
3
4
|
import type { FitParticipation, HeatmapLayerHandle } from "../types";
|
|
4
5
|
export type HeatmapStyle = Readonly<{
|
|
@@ -21,6 +22,14 @@ export type UseHeatmapOptions<TItem> = Readonly<{
|
|
|
21
22
|
getPosition: (item: TItem) => GeoJsonPosition | null;
|
|
22
23
|
getWeight?: (item: TItem) => number;
|
|
23
24
|
style?: HeatmapStyle;
|
|
25
|
+
/**
|
|
26
|
+
* Called once per failed renderer load or update (for example when the Google deck.gl chunk fails to load).
|
|
27
|
+
* The basemap and other layers keep rendering. Without it, failures are logged with `console.warn`.
|
|
28
|
+
* Failures are reported to the app's error handler (Sentry) either way.
|
|
29
|
+
* After a renderer failure (for example WebGL context loss on Google), the heatmap stays hidden until the next map
|
|
30
|
+
* layer or interaction change triggers a retry; nothing retries on an idle map.
|
|
31
|
+
*/
|
|
32
|
+
onError?: (error: HeatmapRenderError) => void;
|
|
24
33
|
controls?: Partial<Record<CategoryKey, ReadonlyArray<ControlConfig>>>;
|
|
25
34
|
loading?: boolean;
|
|
26
35
|
fitParticipation?: FitParticipation;
|