@trackunit/react-map 0.2.98 → 0.2.100-alpha-3e7014314a8.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.
package/index.cjs.js CHANGED
@@ -7757,16 +7757,9 @@ const shapesUnderCursor = (position, features, options) => {
7757
7757
  /**
7758
7758
  * Connected components of features that share fill area. Bbox prefilter then
7759
7759
  * exact polygon intersection, mirroring `countOverlappingShapes`.
7760
- *
7761
- * `getGeoJsonPolygonIntersection` delegates to `polygon-clipping`, which can throw
7762
- * `"Unable to complete output ring"` for degenerate but schema-valid geometry
7763
- * (SAGA-743). A throw here is treated as "no overlap" — the safe degradation for
7764
- * grouping — and recorded in `intersectionFailures` so the hook can report it
7765
- * (mirrors how `droppedInvalidFeatures` surfaces the sibling failure mode).
7766
7760
  */
7767
7761
  const buildOverlapGroups = (records) => {
7768
7762
  const parent = records.map((_, index) => index);
7769
- const intersectionFailures = [];
7770
7763
  const find = (index) => {
7771
7764
  let root = index;
7772
7765
  while (parent[root] !== root)
@@ -7790,17 +7783,7 @@ const buildOverlapGroups = (records) => {
7790
7783
  continue;
7791
7784
  if (!bboxesIntersect$1(a.bbox, b.bbox))
7792
7785
  continue;
7793
- let overlaps;
7794
- try {
7795
- overlaps = geoJsonUtils.getGeoJsonPolygonIntersection(a.geometry, b.geometry) !== null;
7796
- }
7797
- catch (error) {
7798
- // polygon-clipping failed on this pair. Treat as no overlap (do not union)
7799
- // so tiling degrades to full fills rather than crashing the map.
7800
- intersectionFailures.push({ featureIdA: a.id, featureIdB: b.id, error });
7801
- continue;
7802
- }
7803
- if (overlaps) {
7786
+ if (geoJsonUtils.getGeoJsonPolygonIntersection(a.geometry, b.geometry) !== null) {
7804
7787
  union(i, j);
7805
7788
  }
7806
7789
  }
@@ -7816,7 +7799,7 @@ const buildOverlapGroups = (records) => {
7816
7799
  group.push(record);
7817
7800
  }
7818
7801
  });
7819
- return { groups: [...groups.values()].filter(group => group.length >= 2), intersectionFailures };
7802
+ return [...groups.values()].filter(group => group.length >= 2);
7820
7803
  };
7821
7804
  const buildContendedShapes = (group) => group.map(record => {
7822
7805
  const containedIn = [];
@@ -7960,12 +7943,7 @@ const computeFillTiling = (input) => {
7960
7943
  const fillGeometries = new Map();
7961
7944
  const featureToGroupKey = new Map();
7962
7945
  const featureZIndex = new Map();
7963
- const { groups: overlapGroups, intersectionFailures } = buildOverlapGroups(records);
7964
- if (intersectionFailures.length > 0) {
7965
- const pairList = intersectionFailures.map(failure => `${failure.featureIdA}↔${failure.featureIdB}`).join(", ");
7966
- // eslint-disable-next-line no-console -- Intentional: warn devs when polygon-clipping fails on schema-valid geometry (SAGA-743); the pair is treated as non-overlapping and full fills still render
7967
- console.warn(`[computeFillTiling] polygon-clipping failed on ${intersectionFailures.length} feature pair(s); treated as non-overlapping (full fill still renders): ${pairList}`);
7968
- }
7946
+ const overlapGroups = buildOverlapGroups(records);
7969
7947
  for (const group of overlapGroups) {
7970
7948
  const contended = buildContendedShapes(group);
7971
7949
  const recordById = new Map(group.map(record => [record.id, record]));
@@ -8040,7 +8018,6 @@ const computeFillTiling = (input) => {
8040
8018
  featureToGroupKey,
8041
8019
  featureZIndex,
8042
8020
  droppedInvalidFeatures,
8043
- intersectionFailures,
8044
8021
  };
8045
8022
  };
8046
8023
 
@@ -8346,31 +8323,6 @@ const buildShapeLabelResolutionContext = (feature, args) => {
8346
8323
  };
8347
8324
  };
8348
8325
 
8349
- /** Stable, order-independent key so the pair (a,b) dedupes to the same entry as (b,a). */
8350
- const resolveIntersectionFailureDedupeKey = (layerHandleId, failure) => {
8351
- const [first, second] = [failure.featureIdA, failure.featureIdB].sort();
8352
- return `${layerHandleId}:${first}|${second}`;
8353
- };
8354
- /**
8355
- * Report to Sentry each feature pair whose overlap test threw inside `polygon-clipping`
8356
- * (SAGA-743), at most once per handle/pair per session.
8357
- * Note: `computeFillTiling` emits `console.warn` separately.
8358
- */
8359
- const captureFillTilingIntersectionFailures = (intersectionFailures, layerHandleId, sessionReportedDedupeKeys, report) => {
8360
- for (const failure of intersectionFailures) {
8361
- const key = resolveIntersectionFailureDedupeKey(layerHandleId, failure);
8362
- if (sessionReportedDedupeKeys.has(key))
8363
- continue;
8364
- sessionReportedDedupeKeys.add(key);
8365
- report({
8366
- layerHandleId,
8367
- featureIdA: failure.featureIdA,
8368
- featureIdB: failure.featureIdB,
8369
- message: failure.error instanceof Error ? failure.error.message : String(failure.error),
8370
- });
8371
- }
8372
- };
8373
-
8374
8326
  /**
8375
8327
  * Extract ALL vertex coordinates from a geometry, walking every part of
8376
8328
  * multi-geometries. Returns a flat array of [lng, lat] positions.
@@ -9625,7 +9577,6 @@ const bboxesIntersect = (a, b) => a[2] >= b[0] && a[0] <= b[2] && a[3] >= b[1] &
9625
9577
  */
9626
9578
  const buildOverlappingShapesCountMap = (features, featureBboxes, viewportBounds) => {
9627
9579
  const counts = new Map();
9628
- const intersectionFailures = [];
9629
9580
  for (const feature of features) {
9630
9581
  counts.set(feature, 0);
9631
9582
  }
@@ -9654,21 +9605,7 @@ const buildOverlappingShapesCountMap = (features, featureBboxes, viewportBounds)
9654
9605
  const geomB = featureB.geometry;
9655
9606
  const isPolygonalB = geomB !== null && (geomB.type === "Polygon" || geomB.type === "MultiPolygon");
9656
9607
  if (isPolygonalA && isPolygonalB) {
9657
- let overlaps;
9658
- try {
9659
- overlaps = geoJsonUtils.getGeoJsonPolygonIntersection(geomA, geomB) !== null;
9660
- }
9661
- catch (error) {
9662
- // polygon-clipping failed on this pair (SAGA-743). Treat as no overlap so
9663
- // decoration counts degrade gracefully instead of crashing the map.
9664
- intersectionFailures.push({
9665
- featureIdA: featureA.id !== undefined ? String(featureA.id) : `index:${i}`,
9666
- featureIdB: featureB.id !== undefined ? String(featureB.id) : `index:${j}`,
9667
- error,
9668
- });
9669
- continue;
9670
- }
9671
- if (overlaps) {
9608
+ if (geoJsonUtils.getGeoJsonPolygonIntersection(geomA, geomB) !== null) {
9672
9609
  if (geoJsonUtils.isFullyContainedInGeoJsonGeometry(geomA, geomB) !== true) {
9673
9610
  counts.set(featureA, (counts.get(featureA) ?? 0) + 1);
9674
9611
  }
@@ -9683,7 +9620,7 @@ const buildOverlappingShapesCountMap = (features, featureBboxes, viewportBounds)
9683
9620
  }
9684
9621
  }
9685
9622
  }
9686
- return { counts, intersectionFailures };
9623
+ return counts;
9687
9624
  };
9688
9625
  /**
9689
9626
  * Value-based equality for the nested style overrides maps. Used to skip
@@ -9769,25 +9706,6 @@ const useShapeDecorations = ({ onDecorationsChange, onStyleOverridesChange, api,
9769
9706
  const previousLayoutSides = react.useRef(new Map());
9770
9707
  const prevStyleOverridesRef = react.useRef(new Map());
9771
9708
  const prevDecorationLayersRef = react.useRef([]);
9772
- const errorHandler = reactCoreHooks.useErrorHandlerOrNull();
9773
- // Session-level dedupe so a recurring polygon-clipping failure (SAGA-743) reports
9774
- // to Sentry at most once per handle/pair per session, not on every pan frame.
9775
- const sessionReportedIntersectionKeysRef = react.useRef(new Set());
9776
- const reportOverlapIntersectionFailures = react.useCallback((intersectionFailures, layerHandleId) => {
9777
- if (intersectionFailures.length === 0)
9778
- return;
9779
- const pairList = intersectionFailures.map(failure => `${failure.featureIdA}↔${failure.featureIdB}`).join(", ");
9780
- // eslint-disable-next-line no-console -- Intentional: warn devs when polygon-clipping fails on schema-valid geometry (SAGA-743); the pair is treated as non-overlapping and decorations still render
9781
- console.warn(`[useShapeDecorations] polygon-clipping failed on ${intersectionFailures.length} feature pair(s); treated as non-overlapping: ${pairList}`);
9782
- if (errorHandler === null)
9783
- return;
9784
- captureFillTilingIntersectionFailures(intersectionFailures, layerHandleId, sessionReportedIntersectionKeysRef.current, payload => {
9785
- errorHandler.captureException(new Error(`polygon-clipping failed during decoration overlap counting: ${JSON.stringify(payload)}`), {
9786
- level: "warning",
9787
- fingerprint: ["react-map", "fill-tiling", "intersection-failure"],
9788
- });
9789
- });
9790
- }, [errorHandler]);
9791
9709
  /**
9792
9710
  * Labels that just transitioned from absent (hidden) to placed. While in
9793
9711
  * this set, edge identity is NOT stored — the algorithm gets one extra
@@ -9847,9 +9765,7 @@ const useShapeDecorations = ({ onDecorationsChange, onStyleOverridesChange, api,
9847
9765
  let overlappingCountsCache = null;
9848
9766
  const getOverlappingCount = (feature) => {
9849
9767
  if (overlappingCountsCache === null) {
9850
- const { counts, intersectionFailures } = buildOverlappingShapesCountMap(handle.features.features, featureBboxes, bounds);
9851
- overlappingCountsCache = counts;
9852
- reportOverlapIntersectionFailures(intersectionFailures, handle.id);
9768
+ overlappingCountsCache = buildOverlappingShapesCountMap(handle.features.features, featureBboxes, bounds);
9853
9769
  }
9854
9770
  return overlappingCountsCache.get(feature) ?? 0;
9855
9771
  };
@@ -10110,7 +10026,6 @@ const useShapeDecorations = ({ onDecorationsChange, onStyleOverridesChange, api,
10110
10026
  hasSourceReadiness,
10111
10027
  renderedSourceIds,
10112
10028
  isReady,
10113
- reportOverlapIntersectionFailures,
10114
10029
  ]);
10115
10030
  const updateDecorationsRef = react.useRef(updateDecorations);
10116
10031
  react.useEffect(() => {
@@ -10643,7 +10558,7 @@ const useShapeFillTiling = ({ api, handles, onFillGeometriesChange, onZIndexOver
10643
10558
  const nextRestingFills = new Map();
10644
10559
  const nextRestingZIndices = new Map();
10645
10560
  for (const handle of currentHandles) {
10646
- const { fillGeometries, featureToGroupKey, featureZIndex, droppedInvalidFeatures, intersectionFailures } = computeFillTiling({
10561
+ const { fillGeometries, featureToGroupKey, featureZIndex, droppedInvalidFeatures } = computeFillTiling({
10647
10562
  features: handle.features.features,
10648
10563
  viewportBounds: GLOBAL_BOUNDS,
10649
10564
  resolveStackOrder: handle.overlap?.resolveStackOrder ?? defaultShapeStackOrder,
@@ -10659,14 +10574,6 @@ const useShapeFillTiling = ({ api, handles, onFillGeometriesChange, onZIndexOver
10659
10574
  });
10660
10575
  });
10661
10576
  }
10662
- if (errorHandler !== null && intersectionFailures.length > 0) {
10663
- captureFillTilingIntersectionFailures(intersectionFailures, handle.id, sessionReportedDedupeKeysRef.current, payload => {
10664
- errorHandler.captureException(new Error(`polygon-clipping failed during fill-tiling overlap grouping: ${JSON.stringify(payload)}`), {
10665
- level: "warning",
10666
- fingerprint: ["react-map", "fill-tiling", "intersection-failure"],
10667
- });
10668
- });
10669
- }
10670
10577
  featureToGroupKeyByHandleRef.current.set(handle.id, new Map(featureToGroupKey));
10671
10578
  if (fillGeometries.size > 0) {
10672
10579
  nextRestingFills.set(handle.id, fillGeometries);
package/index.esm.js CHANGED
@@ -7756,16 +7756,9 @@ const shapesUnderCursor = (position, features, options) => {
7756
7756
  /**
7757
7757
  * Connected components of features that share fill area. Bbox prefilter then
7758
7758
  * exact polygon intersection, mirroring `countOverlappingShapes`.
7759
- *
7760
- * `getGeoJsonPolygonIntersection` delegates to `polygon-clipping`, which can throw
7761
- * `"Unable to complete output ring"` for degenerate but schema-valid geometry
7762
- * (SAGA-743). A throw here is treated as "no overlap" — the safe degradation for
7763
- * grouping — and recorded in `intersectionFailures` so the hook can report it
7764
- * (mirrors how `droppedInvalidFeatures` surfaces the sibling failure mode).
7765
7759
  */
7766
7760
  const buildOverlapGroups = (records) => {
7767
7761
  const parent = records.map((_, index) => index);
7768
- const intersectionFailures = [];
7769
7762
  const find = (index) => {
7770
7763
  let root = index;
7771
7764
  while (parent[root] !== root)
@@ -7789,17 +7782,7 @@ const buildOverlapGroups = (records) => {
7789
7782
  continue;
7790
7783
  if (!bboxesIntersect$1(a.bbox, b.bbox))
7791
7784
  continue;
7792
- let overlaps;
7793
- try {
7794
- overlaps = getGeoJsonPolygonIntersection(a.geometry, b.geometry) !== null;
7795
- }
7796
- catch (error) {
7797
- // polygon-clipping failed on this pair. Treat as no overlap (do not union)
7798
- // so tiling degrades to full fills rather than crashing the map.
7799
- intersectionFailures.push({ featureIdA: a.id, featureIdB: b.id, error });
7800
- continue;
7801
- }
7802
- if (overlaps) {
7785
+ if (getGeoJsonPolygonIntersection(a.geometry, b.geometry) !== null) {
7803
7786
  union(i, j);
7804
7787
  }
7805
7788
  }
@@ -7815,7 +7798,7 @@ const buildOverlapGroups = (records) => {
7815
7798
  group.push(record);
7816
7799
  }
7817
7800
  });
7818
- return { groups: [...groups.values()].filter(group => group.length >= 2), intersectionFailures };
7801
+ return [...groups.values()].filter(group => group.length >= 2);
7819
7802
  };
7820
7803
  const buildContendedShapes = (group) => group.map(record => {
7821
7804
  const containedIn = [];
@@ -7959,12 +7942,7 @@ const computeFillTiling = (input) => {
7959
7942
  const fillGeometries = new Map();
7960
7943
  const featureToGroupKey = new Map();
7961
7944
  const featureZIndex = new Map();
7962
- const { groups: overlapGroups, intersectionFailures } = buildOverlapGroups(records);
7963
- if (intersectionFailures.length > 0) {
7964
- const pairList = intersectionFailures.map(failure => `${failure.featureIdA}↔${failure.featureIdB}`).join(", ");
7965
- // eslint-disable-next-line no-console -- Intentional: warn devs when polygon-clipping fails on schema-valid geometry (SAGA-743); the pair is treated as non-overlapping and full fills still render
7966
- console.warn(`[computeFillTiling] polygon-clipping failed on ${intersectionFailures.length} feature pair(s); treated as non-overlapping (full fill still renders): ${pairList}`);
7967
- }
7945
+ const overlapGroups = buildOverlapGroups(records);
7968
7946
  for (const group of overlapGroups) {
7969
7947
  const contended = buildContendedShapes(group);
7970
7948
  const recordById = new Map(group.map(record => [record.id, record]));
@@ -8039,7 +8017,6 @@ const computeFillTiling = (input) => {
8039
8017
  featureToGroupKey,
8040
8018
  featureZIndex,
8041
8019
  droppedInvalidFeatures,
8042
- intersectionFailures,
8043
8020
  };
8044
8021
  };
8045
8022
 
@@ -8345,31 +8322,6 @@ const buildShapeLabelResolutionContext = (feature, args) => {
8345
8322
  };
8346
8323
  };
8347
8324
 
8348
- /** Stable, order-independent key so the pair (a,b) dedupes to the same entry as (b,a). */
8349
- const resolveIntersectionFailureDedupeKey = (layerHandleId, failure) => {
8350
- const [first, second] = [failure.featureIdA, failure.featureIdB].sort();
8351
- return `${layerHandleId}:${first}|${second}`;
8352
- };
8353
- /**
8354
- * Report to Sentry each feature pair whose overlap test threw inside `polygon-clipping`
8355
- * (SAGA-743), at most once per handle/pair per session.
8356
- * Note: `computeFillTiling` emits `console.warn` separately.
8357
- */
8358
- const captureFillTilingIntersectionFailures = (intersectionFailures, layerHandleId, sessionReportedDedupeKeys, report) => {
8359
- for (const failure of intersectionFailures) {
8360
- const key = resolveIntersectionFailureDedupeKey(layerHandleId, failure);
8361
- if (sessionReportedDedupeKeys.has(key))
8362
- continue;
8363
- sessionReportedDedupeKeys.add(key);
8364
- report({
8365
- layerHandleId,
8366
- featureIdA: failure.featureIdA,
8367
- featureIdB: failure.featureIdB,
8368
- message: failure.error instanceof Error ? failure.error.message : String(failure.error),
8369
- });
8370
- }
8371
- };
8372
-
8373
8325
  /**
8374
8326
  * Extract ALL vertex coordinates from a geometry, walking every part of
8375
8327
  * multi-geometries. Returns a flat array of [lng, lat] positions.
@@ -9624,7 +9576,6 @@ const bboxesIntersect = (a, b) => a[2] >= b[0] && a[0] <= b[2] && a[3] >= b[1] &
9624
9576
  */
9625
9577
  const buildOverlappingShapesCountMap = (features, featureBboxes, viewportBounds) => {
9626
9578
  const counts = new Map();
9627
- const intersectionFailures = [];
9628
9579
  for (const feature of features) {
9629
9580
  counts.set(feature, 0);
9630
9581
  }
@@ -9653,21 +9604,7 @@ const buildOverlappingShapesCountMap = (features, featureBboxes, viewportBounds)
9653
9604
  const geomB = featureB.geometry;
9654
9605
  const isPolygonalB = geomB !== null && (geomB.type === "Polygon" || geomB.type === "MultiPolygon");
9655
9606
  if (isPolygonalA && isPolygonalB) {
9656
- let overlaps;
9657
- try {
9658
- overlaps = getGeoJsonPolygonIntersection(geomA, geomB) !== null;
9659
- }
9660
- catch (error) {
9661
- // polygon-clipping failed on this pair (SAGA-743). Treat as no overlap so
9662
- // decoration counts degrade gracefully instead of crashing the map.
9663
- intersectionFailures.push({
9664
- featureIdA: featureA.id !== undefined ? String(featureA.id) : `index:${i}`,
9665
- featureIdB: featureB.id !== undefined ? String(featureB.id) : `index:${j}`,
9666
- error,
9667
- });
9668
- continue;
9669
- }
9670
- if (overlaps) {
9607
+ if (getGeoJsonPolygonIntersection(geomA, geomB) !== null) {
9671
9608
  if (isFullyContainedInGeoJsonGeometry(geomA, geomB) !== true) {
9672
9609
  counts.set(featureA, (counts.get(featureA) ?? 0) + 1);
9673
9610
  }
@@ -9682,7 +9619,7 @@ const buildOverlappingShapesCountMap = (features, featureBboxes, viewportBounds)
9682
9619
  }
9683
9620
  }
9684
9621
  }
9685
- return { counts, intersectionFailures };
9622
+ return counts;
9686
9623
  };
9687
9624
  /**
9688
9625
  * Value-based equality for the nested style overrides maps. Used to skip
@@ -9768,25 +9705,6 @@ const useShapeDecorations = ({ onDecorationsChange, onStyleOverridesChange, api,
9768
9705
  const previousLayoutSides = useRef(new Map());
9769
9706
  const prevStyleOverridesRef = useRef(new Map());
9770
9707
  const prevDecorationLayersRef = useRef([]);
9771
- const errorHandler = useErrorHandlerOrNull();
9772
- // Session-level dedupe so a recurring polygon-clipping failure (SAGA-743) reports
9773
- // to Sentry at most once per handle/pair per session, not on every pan frame.
9774
- const sessionReportedIntersectionKeysRef = useRef(new Set());
9775
- const reportOverlapIntersectionFailures = useCallback((intersectionFailures, layerHandleId) => {
9776
- if (intersectionFailures.length === 0)
9777
- return;
9778
- const pairList = intersectionFailures.map(failure => `${failure.featureIdA}↔${failure.featureIdB}`).join(", ");
9779
- // eslint-disable-next-line no-console -- Intentional: warn devs when polygon-clipping fails on schema-valid geometry (SAGA-743); the pair is treated as non-overlapping and decorations still render
9780
- console.warn(`[useShapeDecorations] polygon-clipping failed on ${intersectionFailures.length} feature pair(s); treated as non-overlapping: ${pairList}`);
9781
- if (errorHandler === null)
9782
- return;
9783
- captureFillTilingIntersectionFailures(intersectionFailures, layerHandleId, sessionReportedIntersectionKeysRef.current, payload => {
9784
- errorHandler.captureException(new Error(`polygon-clipping failed during decoration overlap counting: ${JSON.stringify(payload)}`), {
9785
- level: "warning",
9786
- fingerprint: ["react-map", "fill-tiling", "intersection-failure"],
9787
- });
9788
- });
9789
- }, [errorHandler]);
9790
9708
  /**
9791
9709
  * Labels that just transitioned from absent (hidden) to placed. While in
9792
9710
  * this set, edge identity is NOT stored — the algorithm gets one extra
@@ -9846,9 +9764,7 @@ const useShapeDecorations = ({ onDecorationsChange, onStyleOverridesChange, api,
9846
9764
  let overlappingCountsCache = null;
9847
9765
  const getOverlappingCount = (feature) => {
9848
9766
  if (overlappingCountsCache === null) {
9849
- const { counts, intersectionFailures } = buildOverlappingShapesCountMap(handle.features.features, featureBboxes, bounds);
9850
- overlappingCountsCache = counts;
9851
- reportOverlapIntersectionFailures(intersectionFailures, handle.id);
9767
+ overlappingCountsCache = buildOverlappingShapesCountMap(handle.features.features, featureBboxes, bounds);
9852
9768
  }
9853
9769
  return overlappingCountsCache.get(feature) ?? 0;
9854
9770
  };
@@ -10109,7 +10025,6 @@ const useShapeDecorations = ({ onDecorationsChange, onStyleOverridesChange, api,
10109
10025
  hasSourceReadiness,
10110
10026
  renderedSourceIds,
10111
10027
  isReady,
10112
- reportOverlapIntersectionFailures,
10113
10028
  ]);
10114
10029
  const updateDecorationsRef = useRef(updateDecorations);
10115
10030
  useEffect(() => {
@@ -10642,7 +10557,7 @@ const useShapeFillTiling = ({ api, handles, onFillGeometriesChange, onZIndexOver
10642
10557
  const nextRestingFills = new Map();
10643
10558
  const nextRestingZIndices = new Map();
10644
10559
  for (const handle of currentHandles) {
10645
- const { fillGeometries, featureToGroupKey, featureZIndex, droppedInvalidFeatures, intersectionFailures } = computeFillTiling({
10560
+ const { fillGeometries, featureToGroupKey, featureZIndex, droppedInvalidFeatures } = computeFillTiling({
10646
10561
  features: handle.features.features,
10647
10562
  viewportBounds: GLOBAL_BOUNDS,
10648
10563
  resolveStackOrder: handle.overlap?.resolveStackOrder ?? defaultShapeStackOrder,
@@ -10658,14 +10573,6 @@ const useShapeFillTiling = ({ api, handles, onFillGeometriesChange, onZIndexOver
10658
10573
  });
10659
10574
  });
10660
10575
  }
10661
- if (errorHandler !== null && intersectionFailures.length > 0) {
10662
- captureFillTilingIntersectionFailures(intersectionFailures, handle.id, sessionReportedDedupeKeysRef.current, payload => {
10663
- errorHandler.captureException(new Error(`polygon-clipping failed during fill-tiling overlap grouping: ${JSON.stringify(payload)}`), {
10664
- level: "warning",
10665
- fingerprint: ["react-map", "fill-tiling", "intersection-failure"],
10666
- });
10667
- });
10668
- }
10669
10576
  featureToGroupKeyByHandleRef.current.set(handle.id, new Map(featureToGroupKey));
10670
10577
  if (fillGeometries.size > 0) {
10671
10578
  nextRestingFills.set(handle.id, fillGeometries);
package/package.json CHANGED
@@ -1,22 +1,22 @@
1
1
  {
2
2
  "name": "@trackunit/react-map",
3
- "version": "0.2.98",
3
+ "version": "0.2.100-alpha-3e7014314a8.0",
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": "2.10.14",
11
- "@trackunit/css-class-variance-utilities": "1.14.19",
12
- "@trackunit/react-form-components": "2.6.21",
13
- "@trackunit/react-core-hooks": "1.21.20",
14
- "@trackunit/geo-json-utils": "1.15.21",
15
- "@trackunit/i18n-library-translation": "2.4.20",
10
+ "@trackunit/react-components": "2.10.16-alpha-3e7014314a8.0",
11
+ "@trackunit/css-class-variance-utilities": "1.14.20-alpha-3e7014314a8.0",
12
+ "@trackunit/react-form-components": "2.6.23-alpha-3e7014314a8.0",
13
+ "@trackunit/react-core-hooks": "1.21.22-alpha-3e7014314a8.0",
14
+ "@trackunit/geo-json-utils": "1.15.22-alpha-3e7014314a8.0",
15
+ "@trackunit/i18n-library-translation": "2.4.22-alpha-3e7014314a8.0",
16
16
  "react-minimal-pie-chart": "^8.4.0",
17
- "@trackunit/react-map-adapter-shared": "0.0.102",
18
- "@trackunit/react-map-color-utils": "0.0.82",
19
- "@trackunit/ui-design-tokens": "1.15.9",
17
+ "@trackunit/react-map-adapter-shared": "0.0.103-alpha-3e7014314a8.0",
18
+ "@trackunit/react-map-color-utils": "0.0.83-alpha-3e7014314a8.0",
19
+ "@trackunit/ui-design-tokens": "1.15.10-alpha-3e7014314a8.0",
20
20
  "@floating-ui/react": "^0.26.25",
21
21
  "es-toolkit": "^1.39.10",
22
22
  "tailwind-merge": "^2.0.0",
@@ -70,25 +70,12 @@ export type FillTilingResult = Readonly<{
70
70
  featureZIndex: ReadonlyMap<string, number>;
71
71
  /** Features excluded from fill tiling when boundary schema validation fails. */
72
72
  droppedInvalidFeatures: ReadonlyArray<DroppedInvalidFillTilingFeature>;
73
- /**
74
- * Feature pairs whose overlap test threw inside `polygon-clipping` (SAGA-743).
75
- * The pair was treated as non-overlapping; surfaced here so the hook can report
76
- * it to Sentry, since the geometry is schema-valid and never hits
77
- * `droppedInvalidFeatures`.
78
- */
79
- intersectionFailures: ReadonlyArray<FillTilingIntersectionFailure>;
80
73
  }>;
81
74
  export type DroppedInvalidFillTilingFeature = Readonly<{
82
75
  feature: GeoJsonFeature;
83
76
  /** `safeParse` failure details (`parsed.error.format()`). */
84
77
  validationError: unknown;
85
78
  }>;
86
- export type FillTilingIntersectionFailure = Readonly<{
87
- featureIdA: string;
88
- featureIdB: string;
89
- /** The error thrown by `polygon-clipping` (typically "Unable to complete output ring"). */
90
- error: unknown;
91
- }>;
92
79
  /**
93
80
  * Planar area of any GeoJSON geometry (outer rings minus holes). Returns 0 for
94
81
  * non-polygonal types (Point, LineString, …). Relative magnitude only — not
@@ -1 +0,0 @@
1
- {"version":3,"file":"entry.js","sourceRoot":"","sources":["../../../../../libs/react/map/migrations/entry.ts"],"names":[],"mappings":"","sourcesContent":["export {};\n"]}
@@ -1,9 +0,0 @@
1
- import type { FillTilingIntersectionFailure } from "./shapeFillTiling";
2
- type ReportFillTilingIntersectionFailureEvent = (payload: Record<string, unknown>) => void;
3
- /**
4
- * Report to Sentry each feature pair whose overlap test threw inside `polygon-clipping`
5
- * (SAGA-743), at most once per handle/pair per session.
6
- * Note: `computeFillTiling` emits `console.warn` separately.
7
- */
8
- export declare const captureFillTilingIntersectionFailures: (intersectionFailures: ReadonlyArray<FillTilingIntersectionFailure>, layerHandleId: string, sessionReportedDedupeKeys: Set<string>, report: ReportFillTilingIntersectionFailureEvent) => void;
9
- export {};