import maplibregl from 'maplibre-gl'; export function kickRepaint(map: maplibregl.Map | null) { if (!map) return; try { if (map.isStyleLoaded()) map.triggerRepaint(); } catch { // ignore } requestAnimationFrame(() => { try { if (map?.isStyleLoaded()) map.triggerRepaint(); } catch { // ignore } }); } export function onMapStyleReady(map: maplibregl.Map | null, callback: () => void) { if (!map) return () => {}; if (map.isStyleLoaded()) { callback(); return () => {}; } let fired = false; const runOnce = () => { if (!map || fired || !map.isStyleLoaded()) return; fired = true; callback(); try { map.off('style.load', runOnce); map.off('styledata', runOnce); } catch { // ignore } }; map.on('style.load', runOnce); map.on('styledata', runOnce); return () => { if (fired) return; fired = true; try { map.off('style.load', runOnce); map.off('styledata', runOnce); } catch { // ignore } }; } export function sanitizeDeckLayerList(value: unknown): unknown[] { if (!Array.isArray(value)) return []; const seen = new Set(); const out: unknown[] = []; for (const layer of value) { const isDeckLayerLike = !!layer && typeof layer === 'object' && typeof (layer as { id?: unknown }).id === 'string' && typeof (layer as { clone?: unknown }).clone === 'function' && typeof (layer as { props?: unknown }).props === 'object'; if (!isDeckLayerLike) continue; const layerId = (layer as { id: string }).id; if (seen.has(layerId)) continue; seen.add(layerId); out.push(layer); } return out; }