@lad-sapienza/scms-core 0.1.0-alpha.8 → 0.1.0-alpha.9

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.
@@ -27,6 +27,18 @@ import type { SearchQuery } from './types';
27
27
  // Default base layer (OSM)
28
28
  const DEFAULT_BASE_LAYERS: BaseLayerConfig[] = [defaultBasemaps.OSM];
29
29
 
30
+ // Stable identity for the "no explicit overlayLayers prop" case. A literal
31
+ // `overlayLayers = []` default in the destructure below allocates a fresh
32
+ // array on every render whenever the caller uses only a shorthand prop
33
+ // (`geojson` / `csv` / `json` / `directus`) and omits `overlayLayers`. That
34
+ // fresh array is a dependency of the `allOverlayLayers` useMemo, so the memo
35
+ // recomputes every render → the data-loading effect keyed on it re-runs →
36
+ // `setLayersData` → re-render → loop ("Maximum update depth exceeded", plus a
37
+ // `fitToContent` fitBounds animation that restarts forever). Hoisting the
38
+ // empty array to a module constant (same pattern as DEFAULT_BASE_LAYERS)
39
+ // keeps its reference stable across renders.
40
+ const EMPTY_OVERLAY_LAYERS: OverlayLayerConfig[] = [];
41
+
30
42
  // Vector-tile, xyz and wms sources are rendered natively/via RasterLayerLibre
31
43
  // and never go through fetchData — this narrows the union so TS knows
32
44
  // `layer.source` is a plain SourceConfig wherever this guard is used.
@@ -40,7 +52,7 @@ export function Map({
40
52
  mapStyle,
41
53
  styleOverrides,
42
54
  baseLayers = DEFAULT_BASE_LAYERS,
43
- overlayLayers = [],
55
+ overlayLayers = EMPTY_OVERLAY_LAYERS,
44
56
  geolocateControl,
45
57
  fullscreenControl,
46
58
  navigationControl = 'top-left',
@@ -22,16 +22,22 @@ export function Map(props: MapProps) {
22
22
  const stableGeojson = useMemo(() => props?.geojson, [JSON.stringify(props?.geojson || null)]);
23
23
  const stableCsv = useMemo(() => props?.csv, [JSON.stringify(props?.csv || null)]);
24
24
  const stableJson = useMemo(() => props?.json, [JSON.stringify(props?.json || null)]);
25
+ // `directus` feeds the same `implicitSource` → `allOverlayLayers` memo chain
26
+ // as `geojson`/`csv`/`json`; without stabilising it here an inline
27
+ // `directus={{ table: '…' }}` object from MDX gets a new identity on every
28
+ // render and drives the same render loop the others are memoised against.
29
+ const stableDirectus = useMemo(() => props?.directus, [JSON.stringify(props?.directus || null)]);
25
30
 
26
31
  return (
27
- <MapCore
28
- {...props}
32
+ <MapCore
33
+ {...props}
29
34
  center={stableCenter}
30
35
  baseLayers={stableBaseLayers}
31
36
  overlayLayers={stableOverlayLayers}
32
37
  geojson={stableGeojson}
33
38
  csv={stableCsv}
34
39
  json={stableJson}
40
+ directus={stableDirectus}
35
41
  />
36
42
  );
37
43
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lad-sapienza/scms-core",
3
- "version": "0.1.0-alpha.8",
3
+ "version": "0.1.0-alpha.9",
4
4
  "description": "Framework components and Astro integrations for s:CMS — DataTb, Gallery, Map, ZoteroGeoViewer, Record.",
5
5
  "type": "module",
6
6
  "license": "BSD-0-Clause",