@sqlrooms/deck 0.29.0-rc.10 → 0.29.0-rc.11

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 (118) hide show
  1. package/README.md +42 -6
  2. package/dist/DeckJsonMap.d.ts.map +1 -1
  3. package/dist/DeckJsonMap.js +2 -6
  4. package/dist/DeckJsonMap.js.map +1 -1
  5. package/dist/DeckJsonMapSpec.d.ts +875 -53
  6. package/dist/DeckJsonMapSpec.d.ts.map +1 -1
  7. package/dist/DeckJsonMapSpec.js +7 -0
  8. package/dist/DeckJsonMapSpec.js.map +1 -1
  9. package/dist/DeckMapDefaultStylesProvider.d.ts +3 -4
  10. package/dist/DeckMapDefaultStylesProvider.d.ts.map +1 -1
  11. package/dist/DeckMapDefaultStylesProvider.js +13 -7
  12. package/dist/DeckMapDefaultStylesProvider.js.map +1 -1
  13. package/dist/MapSettings.d.ts.map +1 -1
  14. package/dist/MapSettings.js +25 -11
  15. package/dist/MapSettings.js.map +1 -1
  16. package/dist/ai.d.ts +19 -5
  17. package/dist/ai.d.ts.map +1 -1
  18. package/dist/ai.js +60 -112
  19. package/dist/ai.js.map +1 -1
  20. package/dist/aiNormalize.d.ts +31 -0
  21. package/dist/aiNormalize.d.ts.map +1 -0
  22. package/dist/aiNormalize.js +629 -0
  23. package/dist/aiNormalize.js.map +1 -0
  24. package/dist/dashboard.d.ts.map +1 -1
  25. package/dist/dashboard.js +72 -8
  26. package/dist/dashboard.js.map +1 -1
  27. package/dist/dashboardConfig.d.ts +10 -1
  28. package/dist/dashboardConfig.d.ts.map +1 -1
  29. package/dist/dashboardConfig.js +55 -22
  30. package/dist/dashboardConfig.js.map +1 -1
  31. package/dist/datasets/PreparedDatasetStore.d.ts.map +1 -1
  32. package/dist/datasets/PreparedDatasetStore.js +31 -2
  33. package/dist/datasets/PreparedDatasetStore.js.map +1 -1
  34. package/dist/datasets/wrapGeometryAsWkb.d.ts +20 -0
  35. package/dist/datasets/wrapGeometryAsWkb.d.ts.map +1 -0
  36. package/dist/datasets/wrapGeometryAsWkb.js +65 -0
  37. package/dist/datasets/wrapGeometryAsWkb.js.map +1 -0
  38. package/dist/index.d.ts +1 -0
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +1 -0
  41. package/dist/index.js.map +1 -1
  42. package/dist/json/compileGeoArrowAccessor.d.ts +5 -0
  43. package/dist/json/compileGeoArrowAccessor.d.ts.map +1 -1
  44. package/dist/json/compileGeoArrowAccessor.js +17 -3
  45. package/dist/json/compileGeoArrowAccessor.js.map +1 -1
  46. package/dist/json/createDeckJsonConfiguration.d.ts.map +1 -1
  47. package/dist/json/createDeckJsonConfiguration.js +85 -18
  48. package/dist/json/createDeckJsonConfiguration.js.map +1 -1
  49. package/dist/json/extractColorScaleLegends.d.ts.map +1 -1
  50. package/dist/json/extractColorScaleLegends.js +21 -7
  51. package/dist/json/extractColorScaleLegends.js.map +1 -1
  52. package/dist/json/layers/DeckH3HexagonLayer.d.ts.map +1 -1
  53. package/dist/json/layers/DeckH3HexagonLayer.js +9 -14
  54. package/dist/json/layers/DeckH3HexagonLayer.js.map +1 -1
  55. package/dist/json/layers/h3IndexFormat.d.ts +6 -0
  56. package/dist/json/layers/h3IndexFormat.d.ts.map +1 -0
  57. package/dist/json/layers/h3IndexFormat.js +17 -0
  58. package/dist/json/layers/h3IndexFormat.js.map +1 -0
  59. package/dist/json/layers/index.d.ts +1 -0
  60. package/dist/json/layers/index.d.ts.map +1 -1
  61. package/dist/json/layers/index.js +1 -0
  62. package/dist/json/layers/index.js.map +1 -1
  63. package/dist/json/rewriteGeoArrowAccessors.d.ts.map +1 -1
  64. package/dist/json/rewriteGeoArrowAccessors.js +9 -0
  65. package/dist/json/rewriteGeoArrowAccessors.js.map +1 -1
  66. package/dist/json/scaleFunction.d.ts +30 -0
  67. package/dist/json/scaleFunction.d.ts.map +1 -0
  68. package/dist/json/scaleFunction.js +126 -0
  69. package/dist/json/scaleFunction.js.map +1 -0
  70. package/dist/mapAiConfig.d.ts +2 -0
  71. package/dist/mapAiConfig.d.ts.map +1 -1
  72. package/dist/mapAiConfig.js +2 -1
  73. package/dist/mapAiConfig.js.map +1 -1
  74. package/dist/mapAiSharedInstructions.d.ts +3 -0
  75. package/dist/mapAiSharedInstructions.d.ts.map +1 -0
  76. package/dist/mapAiSharedInstructions.js +16 -0
  77. package/dist/mapAiSharedInstructions.js.map +1 -0
  78. package/dist/mapConfig.d.ts +6 -0
  79. package/dist/mapConfig.d.ts.map +1 -1
  80. package/dist/mapConfig.js.map +1 -1
  81. package/dist/mapConfigUtils.d.ts.map +1 -1
  82. package/dist/mapConfigUtils.js +2 -0
  83. package/dist/mapConfigUtils.js.map +1 -1
  84. package/dist/mapFit.d.ts +16 -0
  85. package/dist/mapFit.d.ts.map +1 -1
  86. package/dist/mapFit.js +208 -30
  87. package/dist/mapFit.js.map +1 -1
  88. package/dist/mapLayerConfigUtils.d.ts +9 -1
  89. package/dist/mapLayerConfigUtils.d.ts.map +1 -1
  90. package/dist/mapLayerConfigUtils.js +62 -12
  91. package/dist/mapLayerConfigUtils.js.map +1 -1
  92. package/dist/mapResourceAuthoring.d.ts +2 -0
  93. package/dist/mapResourceAuthoring.d.ts.map +1 -1
  94. package/dist/mapResourceAuthoring.js +402 -16
  95. package/dist/mapResourceAuthoring.js.map +1 -1
  96. package/dist/mosaic.d.ts +1 -1
  97. package/dist/mosaic.d.ts.map +1 -1
  98. package/dist/mosaic.js.map +1 -1
  99. package/dist/prepare/geoarrow.js.map +1 -1
  100. package/dist/prepare/wkbDecoder.d.ts +10 -0
  101. package/dist/prepare/wkbDecoder.d.ts.map +1 -1
  102. package/dist/prepare/wkbDecoder.js +93 -18
  103. package/dist/prepare/wkbDecoder.js.map +1 -1
  104. package/dist/prepare/wkbParser.d.ts +7 -0
  105. package/dist/prepare/wkbParser.d.ts.map +1 -1
  106. package/dist/prepare/wkbParser.js +21 -0
  107. package/dist/prepare/wkbParser.js.map +1 -1
  108. package/dist/selectStarAsWkbCollision.d.ts +3 -0
  109. package/dist/selectStarAsWkbCollision.d.ts.map +1 -0
  110. package/dist/selectStarAsWkbCollision.js +78 -0
  111. package/dist/selectStarAsWkbCollision.js.map +1 -0
  112. package/dist/types.d.ts +1 -1
  113. package/dist/types.d.ts.map +1 -1
  114. package/dist/types.js.map +1 -1
  115. package/dist/useDeckMapFitToBounds.d.ts.map +1 -1
  116. package/dist/useDeckMapFitToBounds.js +1 -1
  117. package/dist/useDeckMapFitToBounds.js.map +1 -1
  118. package/package.json +15 -15
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aiNormalize.js","sourceRoot":"","sources":["../src/aiNormalize.ts"],"names":[],"mappings":"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","sourcesContent":["import {allKnownColorSchemeNames} from '@sqlrooms/color-scales/colorSchemeNames';\nimport {\n deckMapColumnLayerHasRadiusConflicts,\n stripDeckMapColumnLayerRadiusConflicts,\n} from './mapLayerConfigUtils';\n\n// Avoid importing duckdb/mosaic here — keeps Jest light.\nconst DECK_TABLE_DATASET_SOURCE_RELATION = '__sqlrooms_source';\nfunction quoteDeckMapSqlIdentifier(identifier: string) {\n return `\"${identifier.replace(/\"/g, '\"\"')}\"`;\n}\n\nconst SCHEME_NAME_BY_LOWER = new Map(\n allKnownColorSchemeNames.map((s) => [s.toLowerCase(), s]),\n);\n\ntype AiMapConfig = {\n configMode?: string;\n spec?: unknown;\n datasets?: Record<string, unknown>;\n fitToData?: unknown;\n [key: string]: unknown;\n};\n\nconst DEFAULT_AI_GEOMETRY_COLUMN = '__sqlrooms_geom';\nconst DEFAULT_AI_POINT_RADIUS = 4;\nconst DEFAULT_AI_HEATMAP_RADIUS_PIXELS = 30; // deck.gl default\nconst DEFAULT_AI_COLUMN_RADIUS_METERS = 20;\nconst DEFAULT_FILL_COLOR = [56, 189, 248, 180] as const;\n\n/** Basic-mode numeric size clamps; string accessors are validator-only. */\nfunction normalizeAiMapConfigRadius(config: AiMapConfig): AiMapConfig {\n if (config.configMode === 'custom') return config;\n const spec = config.spec as Record<string, unknown> | undefined;\n if (!spec || !Array.isArray(spec.layers)) return config;\n\n let changed = false;\n const layers = spec.layers.map((layer: unknown) => {\n if (!layer || typeof layer !== 'object' || Array.isArray(layer)) {\n return layer;\n }\n let l = layer as Record<string, unknown>;\n let layerChanged = false;\n\n if (\n l['@@type'] === 'GeoArrowScatterplotLayer' &&\n typeof l.getRadius === 'number' &&\n l.getRadius <= 0\n ) {\n // Pair with pixel units/clamps so 4 is not meters / capped by a stale max.\n l = {\n ...l,\n getRadius: DEFAULT_AI_POINT_RADIUS,\n radiusUnits: 'pixels',\n radiusMinPixels: DEFAULT_AI_POINT_RADIUS,\n radiusMaxPixels: DEFAULT_AI_POINT_RADIUS,\n };\n layerChanged = true;\n }\n\n const LINE_LAYER_TYPES = new Set([\n 'GeoArrowPathLayer',\n 'GeoArrowArcLayer',\n 'GeoArrowTripsLayer',\n ]);\n\n if (\n typeof l['@@type'] === 'string' &&\n LINE_LAYER_TYPES.has(l['@@type']) &&\n typeof l.getWidth === 'number'\n ) {\n if (l.widthUnits !== 'pixels') {\n l = {...l, widthUnits: 'pixels'};\n layerChanged = true;\n }\n if (\n typeof l.widthMinPixels === 'number' &&\n typeof l.widthMaxPixels === 'number' &&\n l.widthMaxPixels < l.widthMinPixels\n ) {\n const value = Math.max(\n l.widthMinPixels,\n l.widthMaxPixels,\n typeof l.getWidth === 'number' ? l.getWidth : 0,\n );\n l = {\n ...l,\n widthUnits: 'pixels',\n widthMinPixels: value,\n widthMaxPixels: value,\n getWidth: value,\n };\n layerChanged = true;\n }\n }\n\n if (l['@@type'] === 'GeoArrowHeatmapLayer') {\n const rp = l.radiusPixels;\n if (typeof rp === 'number' && rp <= 0) {\n l = {...l, radiusPixels: DEFAULT_AI_HEATMAP_RADIUS_PIXELS};\n layerChanged = true;\n }\n }\n\n // Column radius: default meters; strip scatter/heatmap radius leftovers.\n if (l['@@type'] === 'GeoArrowColumnLayer') {\n const r = l.radius;\n const needsDefaultRadius =\n typeof r !== 'string' &&\n (typeof r !== 'number' || !Number.isFinite(r) || r <= 0);\n const hasConflicts = deckMapColumnLayerHasRadiusConflicts(l);\n if (needsDefaultRadius || hasConflicts) {\n const next = stripDeckMapColumnLayerRadiusConflicts(l);\n // Stripping getRadius without setting radius leaves deck.gl's 1000m default.\n if (needsDefaultRadius) {\n next.radius = DEFAULT_AI_COLUMN_RADIUS_METERS;\n }\n l = next;\n layerChanged = true;\n }\n }\n\n if (layerChanged) {\n changed = true;\n return l;\n }\n return layer;\n });\n\n if (!changed) return config;\n return {...config, spec: {...spec, layers} as typeof spec};\n}\n\nconst COLOR_ACCESSOR_PROPS = [\n 'getFillColor',\n 'getLineColor',\n 'getColor',\n 'getSourceColor',\n 'getTargetColor',\n] as const;\n\n/** Safe layer defaults; invalid shapes stay for getDeckMapResourceConfigIssues. */\nfunction normalizeAiMapConfigLayers(config: AiMapConfig): AiMapConfig {\n const spec = config.spec as Record<string, unknown> | undefined;\n if (!spec || !Array.isArray(spec.layers)) return config;\n\n const datasetIds = config.datasets ? Object.keys(config.datasets) : [];\n const soloDatasetId = datasetIds.length === 1 ? datasetIds[0] : undefined;\n\n let changed = false;\n const layers = spec.layers.map((layer: unknown) => {\n if (!layer || typeof layer !== 'object' || Array.isArray(layer)) {\n return layer;\n }\n let l = layer as Record<string, unknown>;\n let layerChanged = false;\n\n // scaleLinear → scale only for getElevation (radius/width scales are invalid).\n {\n const value = l.getElevation;\n if (\n value &&\n typeof value === 'object' &&\n !Array.isArray(value) &&\n (value as Record<string, unknown>)['@@function'] === 'scaleLinear'\n ) {\n l = {\n ...l,\n getElevation: {...(value as object), '@@function': 'scale'},\n };\n layerChanged = true;\n }\n }\n\n // Canonicalize scheme casing / trim; type×scheme mismatches stay for validation.\n for (const prop of COLOR_ACCESSOR_PROPS) {\n const value = l[prop];\n if (\n value &&\n typeof value === 'object' &&\n !Array.isArray(value) &&\n '@@function' in (value as Record<string, unknown>) &&\n (value as Record<string, unknown>)['@@function'] === 'colorScale'\n ) {\n const v = value as Record<string, unknown>;\n let next = v;\n const rawScheme = v.scheme;\n if (typeof rawScheme === 'string') {\n const trimmed = rawScheme.trim();\n const canonical =\n SCHEME_NAME_BY_LOWER.get(trimmed.toLowerCase()) ?? trimmed;\n if (canonical !== rawScheme) {\n next = {...next, scheme: canonical};\n }\n }\n if (typeof v.type === 'string' && v.type !== v.type.trim()) {\n next = {...next, type: v.type.trim()};\n }\n if (next !== v) {\n l = {...l, [prop]: next};\n layerChanged = true;\n }\n }\n }\n\n // Solo dataset: inject missing binding or replace unknown dataset ids.\n if (soloDatasetId) {\n const binding = l._sqlroomsBinding as Record<string, unknown> | undefined;\n const boundId =\n binding && typeof binding.dataset === 'string' && binding.dataset.trim()\n ? binding.dataset.trim()\n : undefined;\n const needsBinding =\n !boundId ||\n !(config.datasets && boundId in (config.datasets as object));\n if (needsBinding) {\n l = {\n ...l,\n _sqlroomsBinding: {...(binding ?? {}), dataset: soloDatasetId},\n };\n layerChanged = true;\n }\n }\n\n // AI-only strip: UI may keep colorRange; do not reject in the resource validator.\n if (l['@@type'] === 'GeoArrowHeatmapLayer' && 'colorRange' in l) {\n const {colorRange: _cr, ...rest} = l;\n l = rest;\n layerChanged = true;\n }\n\n // Lift simple @@=column into hexagonColumn for fit-to-bounds.\n if (l['@@type'] === 'GeoArrowH3HexagonLayer') {\n const hexAccessor = l.getHexagon;\n let hexColumn: string | undefined;\n if (typeof hexAccessor === 'string') {\n const m = hexAccessor.trim().match(/^@@=([A-Za-z_][\\w]*)$/);\n hexColumn = m?.[1];\n }\n const binding =\n l._sqlroomsBinding &&\n typeof l._sqlroomsBinding === 'object' &&\n !Array.isArray(l._sqlroomsBinding)\n ? (l._sqlroomsBinding as Record<string, unknown>)\n : undefined;\n if (\n hexColumn &&\n (!binding?.hexagonColumn ||\n typeof binding.hexagonColumn !== 'string' ||\n !(binding.hexagonColumn as string).trim())\n ) {\n l = {\n ...l,\n _sqlroomsBinding: {\n ...(binding ?? {}),\n hexagonColumn: hexColumn,\n },\n };\n layerChanged = true;\n }\n }\n\n if (\n l['@@type'] === 'GeoArrowColumnLayer' &&\n l.getElevation !== undefined &&\n l.extruded === undefined\n ) {\n l = {...l, extruded: true};\n layerChanged = true;\n }\n\n // deck.gl defaults missing fill to opaque black.\n const layerType = l['@@type'];\n const needsFillDefault =\n typeof layerType === 'string' &&\n (layerType === 'GeoArrowScatterplotLayer' ||\n layerType === 'GeoArrowPolygonLayer' ||\n layerType === 'GeoArrowSolidPolygonLayer') &&\n !l.getFillColor;\n if (needsFillDefault) {\n l = {...l, getFillColor: [...DEFAULT_FILL_COLOR]};\n layerChanged = true;\n }\n\n // filled:false with no stroke renders nothing.\n if (\n l['@@type'] === 'GeoArrowScatterplotLayer' &&\n l.filled === false &&\n !l.stroked\n ) {\n l = {...l, filled: true};\n layerChanged = true;\n }\n\n if (layerChanged) changed = true;\n return layerChanged ? l : layer;\n });\n\n // Keep visible:false — legitimate hide state (type switches use replaceLayers).\n\n if (!changed) return config;\n return {...config, spec: {...spec, layers} as typeof spec};\n}\n\n/** Split table refs on dots outside double quotes. */\nfunction splitTableRef(ref: string): string[] {\n const parts: string[] = [];\n let current = '';\n let inQuotes = false;\n for (const ch of ref) {\n if (ch === '\"') {\n inQuotes = !inQuotes;\n current += ch;\n } else if (ch === '.' && !inQuotes) {\n parts.push(current);\n current = '';\n } else {\n current += ch;\n }\n }\n parts.push(current);\n return parts;\n}\n\nfunction unquoteTableRefPart(part: string): string {\n const trimmed = part.trim();\n if (trimmed.length >= 2 && trimmed.startsWith('\"') && trimmed.endsWith('\"')) {\n return trimmed.slice(1, -1).replace(/\"\"/g, '\"');\n }\n return trimmed;\n}\n\nfunction normalizeAiMapConfigDatasetSources(\n config: AiMapConfig,\n stripCatalogNames: ReadonlySet<string>,\n): AiMapConfig {\n const datasets = config.datasets;\n if (!datasets || typeof datasets !== 'object') return config;\n\n // Arc-bound geom columns that need WKB decode hints.\n const arcGeomColsByDataset = new Map<string, Set<string>>();\n const spec = config.spec as Record<string, unknown> | undefined;\n if (spec && Array.isArray(spec.layers)) {\n for (const layer of spec.layers) {\n if (!layer || typeof layer !== 'object') continue;\n const l = layer as Record<string, unknown>;\n if (l['@@type'] !== 'GeoArrowArcLayer') continue;\n const binding = l._sqlroomsBinding as Record<string, unknown> | undefined;\n const datasetId =\n typeof binding?.dataset === 'string' ? binding.dataset : undefined;\n if (!datasetId) continue;\n const cols = arcGeomColsByDataset.get(datasetId) ?? new Set<string>();\n if (typeof binding?.sourceGeometryColumn === 'string') {\n cols.add(binding.sourceGeometryColumn);\n }\n if (typeof binding?.targetGeometryColumn === 'string') {\n cols.add(binding.targetGeometryColumn);\n }\n if (cols.size > 0) arcGeomColsByDataset.set(datasetId, cols);\n }\n }\n\n let changed = false;\n const nextDatasets: Record<string, unknown> = {};\n\n for (const [id, dataset] of Object.entries(datasets)) {\n const d = dataset as Record<string, unknown> | undefined;\n const source = d?.source as Record<string, unknown> | undefined;\n const tableName = source?.tableName;\n\n let next = d;\n let nextSource = source;\n\n if (typeof tableName === 'string' && stripCatalogNames.size > 0) {\n const parts = splitTableRef(tableName);\n if (parts.length >= 3) {\n const catalog = unquoteTableRefPart(parts[0]!).toLowerCase();\n if (stripCatalogNames.has(catalog)) {\n const stripped = parts.slice(1).join('.');\n nextSource = {...nextSource, tableName: stripped};\n next = {...next, source: nextSource};\n changed = true;\n }\n }\n }\n\n // Scope WKB hints to this dataset's arc columns only.\n const transformSql = (next?.source as Record<string, unknown> | undefined)\n ?.transformSql as string | undefined;\n const arcCols = arcGeomColsByDataset.get(id);\n\n if (\n arcCols &&\n arcCols.size > 0 &&\n typeof transformSql === 'string' &&\n !next?.geometryEncodingHint\n ) {\n const mentionsArcCol = [...arcCols].some((col) =>\n transformSql.includes(col),\n );\n if (mentionsArcCol) {\n next = {...next, geometryEncodingHint: 'wkb'};\n changed = true;\n }\n }\n\n nextDatasets[id] = next ?? dataset;\n }\n\n if (!changed) return config;\n return {...config, datasets: nextDatasets as typeof config.datasets};\n}\n\n/** Inject lon/lat → `__sqlrooms_geom` transform when fitToData needs it. */\nfunction normalizeAiMapConfig(config: AiMapConfig): AiMapConfig {\n // mapbox:// mapStyle: leave for validator (do not strip silently).\n\n const datasets = config.datasets;\n let fitToData = config.fitToData as\n | Record<string, unknown>\n | null\n | undefined;\n\n // Unwrap { datasetId: { dataset, … } } → flat fitToData.\n if (fitToData && !fitToData.dataset && typeof fitToData === 'object') {\n const keys = Object.keys(fitToData);\n if (keys.length === 1) {\n const nested = fitToData[keys[0]!] as Record<string, unknown> | undefined;\n if (nested && typeof nested === 'object' && nested.dataset) {\n fitToData = nested;\n config = {...config, fitToData: fitToData as any};\n }\n }\n }\n\n // Default fitToData to sole dataset / first layer binding.\n if (!fitToData?.dataset && datasets && typeof datasets === 'object') {\n const datasetIds = Object.keys(datasets);\n let datasetId: string | undefined =\n datasetIds.length === 1 ? datasetIds[0] : undefined;\n\n if (!datasetId) {\n const spec = config.spec as Record<string, unknown> | undefined;\n const layers = Array.isArray(spec?.layers) ? spec.layers : [];\n for (const layer of layers) {\n if (!layer || typeof layer !== 'object') continue;\n const binding = (layer as Record<string, unknown>)._sqlroomsBinding as\n | Record<string, unknown>\n | undefined;\n if (typeof binding?.dataset === 'string' && binding.dataset.trim()) {\n datasetId = binding.dataset;\n break;\n }\n }\n }\n\n if (datasetId && datasets[datasetId]) {\n fitToData = {dataset: datasetId};\n config = {...config, fitToData: fitToData as any};\n }\n }\n\n if (!datasets || typeof datasets !== 'object' || !fitToData) {\n return config;\n }\n\n const lonCol = fitToData.longitudeColumn as string | undefined;\n const latCol = fitToData.latitudeColumn as string | undefined;\n if (!lonCol || !latCol) {\n return config;\n }\n\n const targetDatasetId = fitToData.dataset as string | undefined;\n if (!targetDatasetId) {\n return config;\n }\n\n const targetDataset = datasets[targetDatasetId] as\n | Record<string, unknown>\n | undefined;\n if (!targetDataset) {\n return config;\n }\n\n const source = targetDataset.source as\n | {tableName?: string; transformSql?: string; sqlQuery?: string}\n | undefined;\n\n // Inject ST_Point WKB as `__sqlrooms_geom` for point layers only (never AS geom).\n if (!source?.tableName || source.sqlQuery || source.transformSql) {\n return config;\n }\n\n const POINT_LONLAT_LAYER_TYPES = new Set([\n 'GeoArrowScatterplotLayer',\n 'GeoArrowHeatmapLayer',\n 'GeoArrowColumnLayer',\n 'GeoJsonLayer',\n // Unprefixed aliases may appear before validator repair.\n 'ScatterplotLayer',\n 'HeatmapLayer',\n 'ColumnLayer',\n ]);\n const datasetIds = Object.keys(datasets);\n const soleDatasetId = datasetIds.length === 1 ? datasetIds[0] : undefined;\n const layerTargetsDataset = (\n binding: Record<string, unknown> | undefined,\n ): boolean => {\n if (binding?.dataset === targetDatasetId) return true;\n // Match solo-dataset binding injection in normalizeAiMapConfigLayers.\n return (\n (!binding || typeof binding.dataset !== 'string' || !binding.dataset) &&\n soleDatasetId === targetDatasetId\n );\n };\n const spec = config.spec as Record<string, unknown> | undefined;\n const layers = Array.isArray(spec?.layers) ? spec.layers : [];\n const pointLayersForDataset = layers.filter((layer) => {\n if (!layer || typeof layer !== 'object') return false;\n const rec = layer as Record<string, unknown>;\n if (rec.visible === false) return false;\n if (\n typeof rec['@@type'] !== 'string' ||\n !POINT_LONLAT_LAYER_TYPES.has(rec['@@type'])\n ) {\n return false;\n }\n const binding = rec._sqlroomsBinding as Record<string, unknown> | undefined;\n return layerTargetsDataset(binding);\n });\n if (pointLayersForDataset.length === 0) {\n return config;\n }\n\n const geometryColumn = DEFAULT_AI_GEOMETRY_COLUMN;\n const quotedLon = quoteDeckMapSqlIdentifier(lonCol);\n const quotedLat = quoteDeckMapSqlIdentifier(latCol);\n const quotedGeom = quoteDeckMapSqlIdentifier(geometryColumn);\n const transformSql = [\n `SELECT *, ST_AsWKB(ST_Point(${quotedLon}, ${quotedLat})) AS ${quotedGeom}`,\n `FROM ${DECK_TABLE_DATASET_SOURCE_RELATION}`,\n `WHERE ${quotedLon} IS NOT NULL AND ${quotedLat} IS NOT NULL`,\n ].join(' ');\n\n const nextLayers = layers.map((layer) => {\n if (!layer || typeof layer !== 'object') return layer;\n const rec = layer as Record<string, unknown>;\n if (\n typeof rec['@@type'] !== 'string' ||\n !POINT_LONLAT_LAYER_TYPES.has(rec['@@type'])\n ) {\n return layer;\n }\n const binding = rec._sqlroomsBinding as Record<string, unknown> | undefined;\n if (!layerTargetsDataset(binding)) return layer;\n const nextBinding = {\n ...(binding ?? {}),\n dataset: (binding?.dataset as string | undefined) ?? targetDatasetId,\n geometryColumn,\n };\n if (\n binding?.dataset === nextBinding.dataset &&\n binding?.geometryColumn === geometryColumn\n ) {\n return layer;\n }\n return {\n ...rec,\n _sqlroomsBinding: nextBinding,\n };\n });\n const layersChanged = nextLayers.some((layer, i) => layer !== layers[i]);\n\n return {\n ...config,\n ...(layersChanged && spec\n ? {spec: {...spec, layers: nextLayers} as typeof config.spec}\n : {}),\n datasets: {\n ...datasets,\n [targetDatasetId]: {\n ...targetDataset,\n source: {tableName: source.tableName, transformSql},\n geometryColumn,\n geometryEncodingHint: 'wkb',\n },\n },\n };\n}\n\n/**\n * Idempotent AI map-config repairs (scheme casing, sizes, bindings, fit inject).\n * Invalid shapes stay for {@link getDeckMapResourceConfigIssues} / agent retry.\n */\nexport type NormalizeAiDeckMapConfigOptions = {\n /** Host-injected catalogs to strip; omit for none — deck does not hardcode any. */\n stripCatalogNames?: readonly string[];\n};\n\nexport function normalizeAiDeckMapConfig<T extends Record<string, unknown>>(\n config: T,\n options?: NormalizeAiDeckMapConfigOptions,\n): T {\n const stripCatalogNames = new Set(\n (options?.stripCatalogNames ?? [])\n .map((name) => name.trim().toLowerCase())\n .filter((name) => name.length > 0),\n );\n return normalizeAiMapConfigRadius(\n normalizeAiMapConfigLayers(\n normalizeAiMapConfigDatasetSources(\n normalizeAiMapConfig(config as unknown as AiMapConfig),\n stripCatalogNames,\n ),\n ),\n ) as unknown as T;\n}\n\nconst COLOR_SCALE_ACCESSOR_PROPS = [\n 'getFillColor',\n 'getLineColor',\n 'getColor',\n 'getSourceColor',\n 'getTargetColor',\n] as const;\n\nexport type ResolveColorScaleTable = (\n tableName: string,\n) => {columns?: {name: string}[]} | undefined;\n\n/**\n * Fix colorScale `field` casing; reject unknown fields on bare `{tableName}` sources.\n * Call before normalize so lon/lat `transformSql` inject does not disable rejection.\n */\nexport function validateAndFixColorScaleFields<\n T extends {spec?: unknown; datasets?: Record<string, unknown>},\n>(config: T, resolveTable: ResolveColorScaleTable): T {\n const rawSpec = config.spec;\n if (!rawSpec) return config;\n let spec: Record<string, unknown>;\n if (typeof rawSpec === 'string') {\n try {\n const parsed = JSON.parse(rawSpec) as unknown;\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n return config;\n }\n spec = parsed as Record<string, unknown>;\n } catch {\n return config;\n }\n } else if (typeof rawSpec === 'object' && !Array.isArray(rawSpec)) {\n spec = rawSpec as Record<string, unknown>;\n } else {\n return config;\n }\n const layers = Array.isArray(spec.layers)\n ? (spec.layers as Record<string, unknown>[])\n : [];\n\n const columnsByDataset = new Map<\n string,\n {\n byLower: Map<string, string>;\n rejectUnknown: boolean;\n derivedSql: string;\n }\n >();\n for (const [datasetId, dataset] of Object.entries(config.datasets ?? {})) {\n const source = (dataset as Record<string, unknown>)?.source as\n | Record<string, unknown>\n | undefined;\n if (!source) continue;\n const tableName =\n typeof source.tableName === 'string' ? source.tableName : undefined;\n if (!tableName) continue;\n\n const table = resolveTable(tableName);\n if (!table?.columns?.length) continue;\n\n const transformSql =\n typeof source.transformSql === 'string' ? source.transformSql : '';\n const sqlQuery = typeof source.sqlQuery === 'string' ? source.sqlQuery : '';\n const derivedSql = `${transformSql} ${sqlQuery}`.trim();\n const hasDerivedSql = derivedSql.length > 0;\n\n const byLower = new Map<string, string>();\n for (const col of table.columns) {\n byLower.set(col.name.toLowerCase(), col.name);\n }\n columnsByDataset.set(datasetId, {\n byLower,\n rejectUnknown: !hasDerivedSql,\n derivedSql,\n });\n }\n\n if (columnsByDataset.size === 0) return config;\n\n const datasetIds = Object.keys(config.datasets ?? {});\n const soloDatasetId = datasetIds.length === 1 ? datasetIds[0] : undefined;\n\n const errors: string[] = [];\n let changed = false;\n const nextLayers = layers.map((layer, i) => {\n const binding = layer._sqlroomsBinding as\n | Record<string, unknown>\n | undefined;\n const boundDataset =\n typeof binding?.dataset === 'string' && binding.dataset.trim()\n ? binding.dataset\n : undefined;\n // Mirror solo-dataset binding repair in normalize.\n const datasetId =\n boundDataset && columnsByDataset.has(boundDataset)\n ? boundDataset\n : (soloDatasetId ?? boundDataset);\n const cols = datasetId ? columnsByDataset.get(datasetId) : undefined;\n if (!cols || !datasetId) return layer;\n\n let nextLayer: Record<string, unknown> | undefined;\n for (const prop of COLOR_SCALE_ACCESSOR_PROPS) {\n const accessor = (nextLayer ?? layer)[prop];\n if (!accessor || typeof accessor !== 'object' || Array.isArray(accessor))\n continue;\n const acc = accessor as Record<string, unknown>;\n if (acc['@@function'] !== 'colorScale') continue;\n const field = acc.field;\n if (typeof field !== 'string') continue;\n\n const canonical = cols.byLower.get(field.toLowerCase());\n if (canonical === field) {\n continue;\n }\n if (canonical !== undefined) {\n nextLayer = {\n ...(nextLayer ?? layer),\n [prop]: {...acc, field: canonical},\n };\n changed = true;\n continue;\n }\n if (!cols.rejectUnknown) {\n // Allow SQL aliases; reject typos absent from both schema and SQL text.\n if (cols.derivedSql.toLowerCase().includes(field.toLowerCase())) {\n continue;\n }\n }\n const available = [...cols.byLower.values()].join(', ');\n errors.push(\n `spec.layers.${i}.${prop}: colorScale field \"${field}\" is not a column in dataset \"${datasetId}\". Available columns: ${available}`,\n );\n }\n return nextLayer ?? layer;\n });\n\n if (errors.length > 0) {\n throw new Error(errors.join('; '));\n }\n\n if (!changed && typeof rawSpec !== 'string') return config;\n return {\n ...config,\n spec: {\n ...spec,\n layers: nextLayers,\n },\n } as T;\n}\n\n/**\n * Validate colorScale fields (optional), then {@link normalizeAiDeckMapConfig}.\n * Validation first so lon/lat transformSql inject does not disable unknown-field checks.\n */\nexport type PrepareAiDeckMapConfigOptions = NormalizeAiDeckMapConfigOptions & {\n resolveTable?: ResolveColorScaleTable;\n};\n\nexport function prepareAiDeckMapConfig<T extends Record<string, unknown>>(\n config: T,\n options?: PrepareAiDeckMapConfigOptions,\n): T {\n const withFields = options?.resolveTable\n ? validateAndFixColorScaleFields(config, options.resolveTable)\n : config;\n return normalizeAiDeckMapConfig(withFields, {\n stripCatalogNames: options?.stripCatalogNames,\n });\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../src/dashboard.tsx"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,4BAA4B,EASlC,MAAM,kBAAkB,CAAC;AAwB1B,OAAO,EAGL,wBAAwB,EACzB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAC,wBAAwB,EAAC,CAAC;AAimBlC,eAAO,MAAM,6BAA6B,EAAE,4BAK3C,CAAC;AAEF,eAAO,MAAM,8BAA8B,EAAE,OAAO,kBAAkB,EAAE,6BAuBrE,CAAC"}
1
+ {"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../src/dashboard.tsx"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,4BAA4B,EASlC,MAAM,kBAAkB,CAAC;AA+B1B,OAAO,EAGL,wBAAwB,EACzB,MAAM,yBAAyB,CAAC;AAajC,OAAO,EAAC,wBAAwB,EAAC,CAAC;AA8pBlC,eAAO,MAAM,6BAA6B,EAAE,4BAK3C,CAAC;AAEF,eAAO,MAAM,8BAA8B,EAAE,OAAO,kBAAkB,EAAE,6BAuBrE,CAAC"}
package/dist/dashboard.js CHANGED
@@ -1,16 +1,20 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { column, sql, useMosaicClient, useStoreWithMosaicDashboard, usePanelClientRegistration, } from '@sqlrooms/mosaic';
3
+ import { useStoreWithDuckDb } from '@sqlrooms/duckdb';
3
4
  import { Button, Tooltip, TooltipContent, TooltipTrigger } from '@sqlrooms/ui';
4
5
  import { AlertTriangleIcon, FocusIcon, MapIcon } from 'lucide-react';
5
6
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
6
7
  import { DeckJsonMap } from './DeckJsonMap';
7
- import { asDeckJsonMapConfig, createDeckMapDashboardPanelConfig, createDeckMapDashboardDatasetQuery, createDeckMapDashboardDatasets, DECK_MAP_DASHBOARD_PANEL_TYPE, DEFAULT_DECK_MAP_MAX_DATA_POINTS, isDeckMapDashboardSqlDatasetSource, isDeckMapDashboardTableDatasetSource, resolveDeckMapDashboardDatasetSource, } from './dashboardConfig';
8
+ import { asDeckJsonMapConfig, createDeckMapDashboardPanelConfig, createDeckMapDashboardDatasetQuery, createDeckMapDashboardDatasetSourceSql, createDeckMapDashboardDatasets, DECK_MAP_DASHBOARD_PANEL_TYPE, DEFAULT_DECK_MAP_MAX_DATA_POINTS, isDeckMapDashboardSqlDatasetSource, isDeckMapDashboardTableDatasetSource, resolveDeckMapDashboardDatasetSource, } from './dashboardConfig';
9
+ import { createDescribeDatasetSql, geometryColumnsNeedingWkbWrap, parseDescribeSqlColumns, } from './datasets/wrapGeometryAsWkb';
8
10
  import { useDeckMapFitToBounds, emitDeckMapDashboardFitRequest, createDeckMapBoundsQuery, } from './useDeckMapFitToBounds';
9
- export { createDeckMapBoundsQuery };
10
11
  import { useDeckMapDatasets } from './useDeckMapDatasets';
11
12
  import { DeckMapDashboardSettings } from './DashboardMapSettings';
12
13
  import { createDeckMapDashboardPanelConfigForTable, findGeometryColumn, findLongitudeLatitudeColumns, } from './mapConfigUtils';
13
14
  import { isDeckMapGeneratedColumn } from './useDeckMapDatasetSchema';
15
+ /** Stable fallback while the DESCRIBE geometry-wrap probe is pending. */
16
+ const EMPTY_WRAPPED_GEOMETRY_COLUMNS = [];
17
+ export { createDeckMapBoundsQuery };
14
18
  function createEmptyDeckMapDashboardPanelConfig(title = 'Map') {
15
19
  return createDeckMapDashboardPanelConfig({
16
20
  title,
@@ -148,11 +152,59 @@ function DeckMapDashboardDatasetClient({ dashboard, dataset, datasetId, fitToDat
148
152
  dataset,
149
153
  fitToData: datasetFitToData,
150
154
  }), [dashboard, dataset, datasetFitToData, panel]);
155
+ const connector = useStoreWithDuckDb((state) => state.db.connector);
156
+ const [geometryWrapProbe, setGeometryWrapProbe] = useState(null);
157
+ const sourceSqlKey = useMemo(() => {
158
+ if (!source)
159
+ return '';
160
+ try {
161
+ return createDeckMapDashboardDatasetSourceSql(source);
162
+ }
163
+ catch {
164
+ return '';
165
+ }
166
+ }, [source]);
167
+ // Pending while probe key mismatches (avoids setState-in-effect).
168
+ const geometryColumnsToWrapAsWkb = useMemo(() => {
169
+ if (!source || !sourceSqlKey)
170
+ return [];
171
+ if (geometryWrapProbe?.sourceSqlKey !== sourceSqlKey)
172
+ return null;
173
+ return geometryWrapProbe.columns;
174
+ }, [geometryWrapProbe, source, sourceSqlKey]);
175
+ useEffect(() => {
176
+ if (!source || !sourceSqlKey) {
177
+ return;
178
+ }
179
+ let cancelled = false;
180
+ void (async () => {
181
+ try {
182
+ const describeTable = await connector.query(createDescribeDatasetSql(sourceSqlKey));
183
+ if (cancelled)
184
+ return;
185
+ setGeometryWrapProbe({
186
+ sourceSqlKey,
187
+ columns: geometryColumnsNeedingWkbWrap(parseDescribeSqlColumns(describeTable)),
188
+ });
189
+ }
190
+ catch {
191
+ if (cancelled)
192
+ return;
193
+ setGeometryWrapProbe({ sourceSqlKey, columns: [] });
194
+ }
195
+ })();
196
+ return () => {
197
+ cancelled = true;
198
+ };
199
+ }, [connector, source, sourceSqlKey]);
200
+ const geometryProbeReady = geometryColumnsToWrapAsWkb !== null;
201
+ const wrappedGeometryColumnNames = geometryColumnsToWrapAsWkb ?? EMPTY_WRAPPED_GEOMETRY_COLUMNS;
151
202
  const query = useCallback((filter) => source
152
203
  ? createDeckMapDashboardDatasetQuery(source, filter, {
153
204
  sampleRows: maxRows,
205
+ geometryColumnsToWrapAsWkb: wrappedGeometryColumnNames,
154
206
  })
155
- : createDeckMapDashboardDatasetQuery({ tableName: '__missing_dashboard_map_dataset__' }, filter, { sampleRows: maxRows }), [maxRows, source]);
207
+ : createDeckMapDashboardDatasetQuery({ tableName: '__missing_dashboard_map_dataset__' }, filter, { sampleRows: maxRows }), [wrappedGeometryColumnNames, maxRows, source]);
156
208
  const queryError = useCallback((err) => {
157
209
  onDatasetState(datasetId, {
158
210
  arrowTable: undefined,
@@ -160,8 +212,9 @@ function DeckMapDashboardDatasetClient({ dashboard, dataset, datasetId, fitToDat
160
212
  isLoading: false,
161
213
  client: null,
162
214
  isSampled: false,
215
+ wrappedGeometryColumnNames,
163
216
  });
164
- }, [datasetId, onDatasetState]);
217
+ }, [datasetId, onDatasetState, wrappedGeometryColumnNames]);
165
218
  const sourceKey = isDeckMapDashboardTableDatasetSource(source)
166
219
  ? source.tableName
167
220
  : isDeckMapDashboardSqlDatasetSource(source)
@@ -173,11 +226,11 @@ function DeckMapDashboardDatasetClient({ dashboard, dataset, datasetId, fitToDat
173
226
  ? (source.transformSql ?? '')
174
227
  : '';
175
228
  const { data, error, isLoading, client } = useMosaicClient({
176
- id: `${panel.id}:${datasetId}:${sourceKey}:${sourceQueryKey}:${maxRows}`,
229
+ id: `${panel.id}:${datasetId}:${sourceKey}:${sourceQueryKey}:${maxRows}:${geometryColumnsToWrapAsWkb?.join(',') ?? 'pending'}`,
177
230
  selectionName,
178
231
  query,
179
232
  queryError,
180
- enabled: Boolean(source),
233
+ enabled: Boolean(source) && geometryProbeReady,
181
234
  runtimeIssueContext,
182
235
  runtimeIssueReporter,
183
236
  });
@@ -188,14 +241,25 @@ function DeckMapDashboardDatasetClient({ dashboard, dataset, datasetId, fitToDat
188
241
  onDatasetState(datasetId, {
189
242
  arrowTable: data ?? undefined,
190
243
  error,
191
- isLoading,
244
+ isLoading: isLoading || !geometryProbeReady,
192
245
  client,
193
246
  isSampled,
247
+ wrappedGeometryColumnNames,
194
248
  });
195
249
  return () => {
196
250
  onDatasetState(datasetId, undefined);
197
251
  };
198
- }, [client, data, datasetId, error, isLoading, isSampled, onDatasetState]);
252
+ }, [
253
+ client,
254
+ data,
255
+ datasetId,
256
+ error,
257
+ geometryProbeReady,
258
+ isLoading,
259
+ isSampled,
260
+ onDatasetState,
261
+ wrappedGeometryColumnNames,
262
+ ]);
199
263
  return null;
200
264
  }
201
265
  function createPointRadiusPredicate(interaction, coordinate) {
@@ -1 +1 @@
1
- {"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../src/dashboard.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n column,\n type MosaicDashboardEntryType,\n type MosaicDashboardPanelConfigType,\n type MosaicDashboardPanelRenderer,\n type MosaicDashboardPanelRendererProps,\n sql,\n type ChartRuntimeIssue,\n type ChartRuntimeIssueContext,\n type ChartRuntimeIssueReporter,\n useMosaicClient,\n useStoreWithMosaicDashboard,\n usePanelClientRegistration,\n} from '@sqlrooms/mosaic';\nimport {Button, Tooltip, TooltipContent, TooltipTrigger} from '@sqlrooms/ui';\nimport type {MosaicClient} from '@uwdata/mosaic-core';\nimport type {Selection} from '@uwdata/mosaic-core';\nimport {AlertTriangleIcon, FocusIcon, MapIcon} from 'lucide-react';\nimport {useCallback, useEffect, useMemo, useRef, useState} from 'react';\nimport {DeckJsonMap} from './DeckJsonMap';\nimport type {DeckJsonMapHandle} from './types';\nimport {\n asDeckJsonMapConfig,\n createDeckMapDashboardPanelConfig,\n createDeckMapDashboardDatasetQuery,\n createDeckMapDashboardDatasets,\n DECK_MAP_DASHBOARD_PANEL_TYPE,\n DEFAULT_DECK_MAP_MAX_DATA_POINTS,\n isDeckMapDashboardSqlDatasetSource,\n isDeckMapDashboardTableDatasetSource,\n resolveDeckMapDashboardDatasetSource,\n type DeckMapDashboardFitToDataConfig,\n type DeckMapDashboardDatasetClientState,\n type DeckMapDashboardDatasetConfig,\n type DeckMapDashboardInteractionConfig,\n type DeckMapDashboardPanelConfig,\n} from './dashboardConfig';\nimport {\n useDeckMapFitToBounds,\n emitDeckMapDashboardFitRequest,\n createDeckMapBoundsQuery,\n} from './useDeckMapFitToBounds';\nexport {createDeckMapBoundsQuery};\nimport {useDeckMapDatasets} from './useDeckMapDatasets';\nimport {DeckMapDashboardSettings} from './DashboardMapSettings';\nimport {\n createDeckMapDashboardPanelConfigForTable,\n findGeometryColumn,\n findLongitudeLatitudeColumns,\n} from './mapConfigUtils';\nimport {isDeckMapGeneratedColumn} from './useDeckMapDatasetSchema';\n\nfunction createEmptyDeckMapDashboardPanelConfig(title = 'Map') {\n return createDeckMapDashboardPanelConfig({\n title,\n spec: {\n initialViewState: {longitude: 0, latitude: 20, zoom: 1.5},\n layers: [],\n },\n datasets: {},\n });\n}\n\n/**\n * Extracts column names from common DuckDB \"column not found\" error messages\n * and layer geometry incompatibility errors.\n * Returns the column names if detected, or null for unrecognized errors.\n */\nfunction parseMissingColumnsFromError(message: string): string[] | null {\n // \"Referenced column \"X\" not found in FROM clause!\" — may appear multiple times\n const refMatches = [\n ...message.matchAll(/Referenced column \"([^\"]+)\" not found/gi),\n ];\n if (refMatches.length > 0) return refMatches.map((m) => m[1]!);\n\n // \"Binder Error: Column \"X\" does not exist\" or \"column X not found\"\n const colMatch = message.match(\n /(?:Column|column)\\s+\"([^\"]+)\"\\s+(?:does not exist|not found)/i,\n );\n if (colMatch) return [colMatch[1]!];\n\n // \"Geometry column \"X\" was not found\"\n const geomNotFound = message.match(\n /Geometry column \"([^\"]+)\" was not found/i,\n );\n if (geomNotFound) return [geomNotFound[1]!];\n\n // \"Layer ... references unknown column \"X\" for getTimestamps.\"\n const unknownColumn = message.match(/references unknown column \"([^\"]+)\"/i);\n if (unknownColumn) return [unknownColumn[1]!];\n\n return null;\n}\n\n/**\n * Detects geometry type mismatch errors (e.g. polygon layer on point data).\n */\nfunction parseGeometryMismatchError(\n message: string,\n): {required: string; found: string} | null {\n const match = message.match(\n /requires (\\w+) geometry .+ but only (\\w+) coordinates were found/i,\n );\n if (match) return {required: match[1]!, found: match[2]!};\n return null;\n}\n\n/**\n * Detects columns referenced in layer config that are missing from the loaded dataset.\n */\nfunction detectMissingColumns(\n mapConfig: DeckMapDashboardPanelConfig | undefined,\n datasetStates: Record<string, DeckMapDashboardDatasetClientState>,\n): string[] {\n if (!mapConfig?.spec) return [];\n const missing: string[] = [];\n const spec = mapConfig.spec as Record<string, unknown>;\n const layers = Array.isArray(spec.layers) ? spec.layers : [];\n\n for (const layer of layers) {\n if (!layer || typeof layer !== 'object') continue;\n const layerObj = layer as Record<string, unknown>;\n const binding = layerObj._sqlroomsBinding as\n | Record<string, unknown>\n | undefined;\n const datasetId = binding?.dataset as string | undefined;\n const arrowTable = datasetId\n ? datasetStates[datasetId]?.arrowTable\n : undefined;\n if (!arrowTable) continue;\n\n const fieldNames = new Set(\n arrowTable.schema.fields.map((f) => f.name.toLowerCase()),\n );\n const check = (col: string | undefined) => {\n if (col && !fieldNames.has(col.toLowerCase())) {\n missing.push(col);\n }\n };\n\n for (const bindingColumn of [\n binding?.geometryColumn,\n binding?.sourceGeometryColumn,\n binding?.targetGeometryColumn,\n binding?.timestampColumn,\n binding?.hexagonColumn,\n ]) {\n check(bindingColumn as string | undefined);\n }\n\n // Check @@= accessors\n for (const [propName, propValue] of Object.entries(layerObj)) {\n // Skip elevation references when extrusion is disabled\n if (propName === 'getElevation' && !layerObj.extruded) continue;\n\n if (typeof propValue === 'string' && propValue.startsWith('@@=')) {\n const expression = propValue.slice(3).trim();\n const identifiers = expression.match(/\\b[A-Za-z_$][\\w$]*\\b/g);\n if (identifiers) {\n for (const id of identifiers) {\n check(id);\n }\n }\n }\n // Check @@function colorScale/scale field references\n if (\n propValue &&\n typeof propValue === 'object' &&\n '@@function' in (propValue as object)\n ) {\n const fn = propValue as Record<string, unknown>;\n if (typeof fn.field === 'string') {\n check(fn.field);\n }\n }\n }\n }\n\n return [...new Set(missing)];\n}\n\nfunction DeckMapRuntimeIssuePanel({issue}: {issue: ChartRuntimeIssue}) {\n if (issue.kind === 'sql-error' || issue.kind === 'render-error') {\n const missingColumns = parseMissingColumnsFromError(issue.message);\n if (missingColumns) {\n const generatedMissingColumns = missingColumns.filter(\n isDeckMapGeneratedColumn,\n );\n if (generatedMissingColumns.length > 0) {\n return (\n <div className=\"flex h-full min-h-[200px] flex-col items-center justify-center p-4\">\n <div className=\"mb-2 text-center font-semibold\">\n The visualization can&apos;t be displayed\n </div>\n <div className=\"text-center text-sm\">\n <span>\n The dataset transform did not produce required map output\n columns:{' '}\n </span>\n {generatedMissingColumns.map((col, idx) => (\n <span key={idx}>\n <span className=\"inline-flex items-center rounded-md border border-gray-600 bg-gray-800 px-1 py-0.5 text-xs font-medium text-gray-300\">\n {col}\n </span>{' '}\n </span>\n ))}\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"flex h-full min-h-[200px] flex-col items-center justify-center p-4\">\n <div className=\"mb-2 text-center font-semibold\">\n The visualization can&apos;t be displayed\n </div>\n <div className=\"text-center text-sm\">\n <span>Selected columns are missing in the dataset: </span>\n {missingColumns.map((col, idx) => (\n <span key={idx}>\n <span className=\"inline-flex items-center rounded-md border border-gray-600 bg-gray-800 px-1 py-0.5 text-xs font-medium text-gray-300\">\n {col}\n </span>{' '}\n </span>\n ))}\n </div>\n </div>\n );\n }\n\n const geomMismatch = parseGeometryMismatchError(issue.message);\n if (geomMismatch) {\n return (\n <div className=\"flex h-full min-h-[200px] flex-col items-center justify-center p-4\">\n <div className=\"mb-2 text-center font-semibold\">\n The visualization can&apos;t be displayed\n </div>\n <div className=\"text-center text-sm\">\n This layer requires {geomMismatch.required} geometry, but the\n current dataset only has {geomMismatch.found} coordinates.\n </div>\n </div>\n );\n }\n }\n\n const title =\n issue.kind === 'too-much-data'\n ? 'Too much data'\n : issue.kind === 'sql-error'\n ? 'Map query failed'\n : 'Unable to display map';\n\n return (\n <div className=\"flex h-full min-h-[200px] flex-col items-center justify-center p-4\">\n <div className=\"mb-2 text-center font-semibold\">{title}</div>\n <div className=\"text-center text-sm whitespace-pre-wrap\">\n {issue.message}\n </div>\n </div>\n );\n}\n\nfunction DeckMapDashboardDatasetClient({\n dashboard,\n dataset,\n datasetId,\n fitToData,\n panel,\n onDatasetState,\n runtimeIssueContext,\n runtimeIssueReporter,\n selectionName,\n maxRows,\n}: {\n dashboard: MosaicDashboardEntryType;\n dataset: DeckMapDashboardDatasetConfig;\n datasetId: string;\n fitToData?: DeckMapDashboardFitToDataConfig;\n panel: MosaicDashboardPanelConfigType;\n onDatasetState: (\n datasetId: string,\n state: DeckMapDashboardDatasetClientState | undefined,\n ) => void;\n runtimeIssueContext?: ChartRuntimeIssueContext;\n runtimeIssueReporter?: ChartRuntimeIssueReporter;\n selectionName: string;\n maxRows: number;\n}) {\n const datasetFitToData = useMemo(\n () => (fitToData?.dataset === datasetId ? fitToData : undefined),\n [datasetId, fitToData],\n );\n const source = useMemo(\n () =>\n resolveDeckMapDashboardDatasetSource({\n dashboard,\n panel,\n dataset,\n fitToData: datasetFitToData,\n }),\n [dashboard, dataset, datasetFitToData, panel],\n );\n const query = useCallback(\n (filter: unknown) =>\n source\n ? createDeckMapDashboardDatasetQuery(source, filter, {\n sampleRows: maxRows,\n })\n : createDeckMapDashboardDatasetQuery(\n {tableName: '__missing_dashboard_map_dataset__'},\n filter,\n {sampleRows: maxRows},\n ),\n [maxRows, source],\n );\n const queryError = useCallback(\n (err: Error) => {\n onDatasetState(datasetId, {\n arrowTable: undefined,\n error: err,\n isLoading: false,\n client: null,\n isSampled: false,\n });\n },\n [datasetId, onDatasetState],\n );\n const sourceKey = isDeckMapDashboardTableDatasetSource(source)\n ? source.tableName\n : isDeckMapDashboardSqlDatasetSource(source)\n ? ''\n : (dashboard.selectedTable ?? '');\n const sourceQueryKey = isDeckMapDashboardSqlDatasetSource(source)\n ? source.sqlQuery\n : isDeckMapDashboardTableDatasetSource(source)\n ? (source.transformSql ?? '')\n : '';\n const {data, error, isLoading, client} = useMosaicClient({\n id: `${panel.id}:${datasetId}:${sourceKey}:${sourceQueryKey}:${maxRows}`,\n selectionName,\n query,\n queryError,\n enabled: Boolean(source),\n runtimeIssueContext,\n runtimeIssueReporter,\n });\n\n // Register client for panel reset button\n usePanelClientRegistration(dashboard.id, panel.id, client ? [client] : []);\n\n const isSampled = Boolean(data && data.numRows >= maxRows);\n\n useEffect(() => {\n onDatasetState(datasetId, {\n arrowTable: data ?? undefined,\n error,\n isLoading,\n client,\n isSampled,\n });\n\n return () => {\n onDatasetState(datasetId, undefined);\n };\n }, [client, data, datasetId, error, isLoading, isSampled, onDatasetState]);\n\n return null;\n}\n\nfunction createPointRadiusPredicate(\n interaction: DeckMapDashboardInteractionConfig,\n coordinate: [number, number],\n) {\n const [longitude, latitude] = coordinate;\n const radiusMeters = interaction.radiusMeters ?? 500;\n const metersPerDegree = 111_320;\n const cosLatitude = Math.cos(latitude * (Math.PI / 180));\n const radiusSquared = radiusMeters * radiusMeters;\n\n return sql`(\n pow((${column(interaction.longitudeColumn)} - ${longitude}) * ${\n cosLatitude * metersPerDegree\n }, 2) +\n pow((${column(interaction.latitudeColumn)} - ${latitude}) * ${\n metersPerDegree\n }, 2)\n ) < ${radiusSquared}`;\n}\n\ntype DeckMapInteractionEvent = {\n coordinate?: number[] | null;\n object?: unknown;\n index?: number;\n picked?: boolean;\n};\n\nfunction getCoordinate(\n info: DeckMapInteractionEvent,\n): [number, number] | undefined {\n return info.coordinate && info.coordinate.length >= 2\n ? [info.coordinate[0]!, info.coordinate[1]!]\n : undefined;\n}\n\nfunction isPickedMapFeature(info: DeckMapInteractionEvent) {\n return Boolean(info.picked || info.object || (info.index ?? -1) >= 0);\n}\n\nfunction DeckMapDashboardHeaderActions({\n panel,\n}: MosaicDashboardPanelRendererProps) {\n const mapConfig = asDeckJsonMapConfig(panel.config);\n const canFitView = Boolean(mapConfig?.fitToData);\n const fitViewLabel = canFitView\n ? 'Fit map view to data'\n : 'Fit view unavailable for this map';\n\n return (\n <div className=\"flex items-center gap-0.5\">\n <Tooltip>\n <TooltipTrigger asChild>\n <span\n className=\"inline-flex\"\n tabIndex={canFitView ? undefined : 0}\n aria-label={canFitView ? undefined : fitViewLabel}\n >\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-6 w-6\"\n aria-label={fitViewLabel}\n disabled={!canFitView}\n onClick={() => emitDeckMapDashboardFitRequest(panel.id)}\n >\n <FocusIcon className=\"h-3.5 w-3.5\" />\n </Button>\n </span>\n </TooltipTrigger>\n <TooltipContent>{fitViewLabel}</TooltipContent>\n </Tooltip>\n </div>\n );\n}\n\nfunction DeckMapDashboardRenderer({\n dashboard,\n dashboardId,\n panel,\n selectionName,\n}: MosaicDashboardPanelRendererProps) {\n const mapConfig = asDeckJsonMapConfig(panel.config);\n const isCustomMode = mapConfig?.configMode === 'custom';\n const getSelection = useStoreWithMosaicDashboard(\n (state) => state.mosaic.getSelection,\n );\n const issue = useStoreWithMosaicDashboard((state) =>\n state.mosaicDashboard.getPanelIssue(dashboardId, panel.id),\n );\n const clearPanelIssue = useStoreWithMosaicDashboard(\n (state) => state.mosaicDashboard.clearPanelIssue,\n );\n\n // Clear runtime issues when the active table or panel config changes so\n // the map can recover (e.g., after switching tables or AI updating the map).\n useEffect(() => {\n clearPanelIssue(dashboardId, panel.id);\n }, [\n clearPanelIssue,\n dashboard.selectedTable,\n dashboardId,\n panel.config,\n panel.id,\n ]);\n\n const selection = useMemo<Selection>(\n () => getSelection(selectionName, 'crossfilter'),\n [getSelection, selectionName],\n );\n const [container, setContainer] = useState<HTMLDivElement | null>(null);\n const deckMapRef = useRef<DeckJsonMapHandle>(null);\n const [sampledDismissed, setSampledDismissed] = useState(false);\n\n const {\n datasetStates,\n handleDatasetState,\n runtimeIssueContext,\n runtimeIssueReporter,\n handleRenderingError,\n } = useDeckMapDatasets({dashboardId, panel});\n\n const {fitToData} = useDeckMapFitToBounds({\n panelId: panel.id,\n dashboard,\n panel,\n container,\n deckMapRef,\n });\n\n const handleBrushEvent = useCallback(\n (info: DeckMapInteractionEvent) => {\n const interaction = mapConfig?.interaction;\n if (!interaction) {\n return;\n }\n\n const client = datasetStates[interaction.dataset]?.client as\n | MosaicClient\n | null\n | undefined;\n if (!client) {\n return;\n }\n const coordinate = getCoordinate(info);\n if (!coordinate) {\n return;\n }\n if (interaction.event !== 'click' && !isPickedMapFeature(info)) {\n selection.reset(\n selection.clauses.filter((clause) => clause.source === client),\n );\n return;\n }\n\n const radiusMeters = interaction.radiusMeters ?? 500;\n selection.update({\n source: client,\n clients: new Set([client]),\n value: [coordinate[0], coordinate[1], radiusMeters],\n predicate: createPointRadiusPredicate(interaction, coordinate),\n });\n },\n [datasetStates, mapConfig?.interaction, selection],\n );\n\n const datasetError = useMemo(() => {\n for (const state of Object.values(datasetStates)) {\n if (state.error) return state.error;\n }\n return undefined;\n }, [datasetStates]);\n\n const missingColumns = useMemo(\n () => detectMissingColumns(mapConfig ?? undefined, datasetStates),\n [mapConfig, datasetStates],\n );\n\n const maxRows =\n mapConfig?.dataPolicy?.maxRows ?? DEFAULT_DECK_MAP_MAX_DATA_POINTS;\n\n const mapContent = !mapConfig ? (\n <div className=\"text-muted-foreground flex h-full items-center justify-center p-4 text-sm\">\n Invalid map panel config.\n </div>\n ) : Object.entries(mapConfig.datasets).length === 0 ? (\n <div className=\"text-muted-foreground flex h-full items-center justify-center p-4 text-sm\">\n Map panels require at least one dataset.\n </div>\n ) : (\n <>\n {Object.entries(mapConfig.datasets).map(([datasetId, dataset]) => (\n <DeckMapDashboardDatasetClient\n key={datasetId}\n dashboard={dashboard}\n dataset={dataset}\n datasetId={datasetId}\n fitToData={fitToData ?? undefined}\n panel={panel}\n onDatasetState={handleDatasetState}\n runtimeIssueContext={runtimeIssueContext}\n runtimeIssueReporter={runtimeIssueReporter}\n selectionName={selectionName}\n maxRows={maxRows}\n />\n ))}\n {issue ? (\n <DeckMapRuntimeIssuePanel issue={issue} />\n ) : datasetError ? (\n <DeckMapRuntimeIssuePanel\n issue={{\n kind: 'sql-error',\n panelId: panel.id,\n chartType: DECK_MAP_DASHBOARD_PANEL_TYPE,\n message: datasetError.message,\n recoverable: true,\n }}\n />\n ) : (\n <div ref={setContainer} className=\"relative h-full w-full\">\n {Object.values(datasetStates).some((s) => s.isSampled) &&\n !sampledDismissed && (\n <div className=\"bg-background/80 text-muted-foreground absolute top-2 left-2 z-10 flex items-center gap-1.5 rounded px-2 py-1 text-xs shadow\">\n <span>Data sampled to {maxRows.toLocaleString()} rows</span>\n <button\n className=\"text-muted-foreground/60 hover:text-foreground -mr-0.5 ml-0.5\"\n onClick={() => setSampledDismissed(true)}\n >\n ×\n </button>\n </div>\n )}\n {missingColumns.length > 0 && !isCustomMode && (\n <Tooltip>\n <TooltipTrigger asChild>\n <span\n className={`absolute left-2 z-10 flex h-5 w-5 items-center justify-center ${\n Object.values(datasetStates).some((s) => s.isSampled) &&\n !sampledDismissed\n ? 'top-9'\n : 'top-2'\n }`}\n >\n <AlertTriangleIcon className=\"h-4 w-4 text-amber-500 drop-shadow-sm\" />\n </span>\n </TooltipTrigger>\n <TooltipContent side=\"right\">\n <p className=\"text-xs font-medium\">Missing columns:</p>\n <p className=\"text-xs\">{missingColumns.join(', ')}</p>\n </TooltipContent>\n </Tooltip>\n )}\n <DeckJsonMap\n ref={deckMapRef}\n className=\"h-full w-full px-0.5 pb-0.5\"\n spec={mapConfig.spec}\n datasets={\n mapConfig\n ? createDeckMapDashboardDatasets(mapConfig, datasetStates)\n : {}\n }\n mapStyle={mapConfig.mapStyle}\n mapProps={mapConfig.mapProps}\n showLegends={mapConfig.showLegends !== false}\n onRenderingError={handleRenderingError}\n deckProps={{\n controller: true,\n ...(mapConfig.interaction\n ? (mapConfig.interaction.event ?? 'hover') === 'click'\n ? {onClick: handleBrushEvent}\n : {onHover: handleBrushEvent}\n : {}),\n }}\n />\n </div>\n )}\n </>\n );\n\n return mapContent;\n}\n\nexport const deckMapDashboardPanelRenderer: MosaicDashboardPanelRenderer = {\n component: DeckMapDashboardRenderer,\n headerActions: DeckMapDashboardHeaderActions,\n icon: MapIcon,\n settings: DeckMapDashboardSettings,\n};\n\nexport const deckMapDashboardAddPanelAction: import('@sqlrooms/mosaic').MosaicDashboardAddPanelAction =\n {\n type: DECK_MAP_DASHBOARD_PANEL_TYPE,\n label: 'Map',\n icon: MapIcon,\n createPanel: ({selectedTable}) => {\n if (\n selectedTable &&\n (findLongitudeLatitudeColumns(selectedTable) ??\n findGeometryColumn(selectedTable))\n ) {\n return createDeckMapDashboardPanelConfigForTable({\n title: `${selectedTable.tableName} map`,\n tableName: selectedTable.tableName,\n columns: selectedTable.columns,\n tableReference: selectedTable.table,\n });\n }\n\n return createEmptyDeckMapDashboardPanelConfig(\n selectedTable ? `${selectedTable.tableName} map` : 'Map',\n );\n },\n };\n"]}
1
+ {"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../src/dashboard.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n column,\n type MosaicDashboardEntryType,\n type MosaicDashboardPanelConfigType,\n type MosaicDashboardPanelRenderer,\n type MosaicDashboardPanelRendererProps,\n sql,\n type ChartRuntimeIssue,\n type ChartRuntimeIssueContext,\n type ChartRuntimeIssueReporter,\n useMosaicClient,\n useStoreWithMosaicDashboard,\n usePanelClientRegistration,\n} from '@sqlrooms/mosaic';\nimport {useStoreWithDuckDb} from '@sqlrooms/duckdb';\nimport {Button, Tooltip, TooltipContent, TooltipTrigger} from '@sqlrooms/ui';\nimport type {MosaicClient} from '@uwdata/mosaic-core';\nimport type {Selection} from '@uwdata/mosaic-core';\nimport {AlertTriangleIcon, FocusIcon, MapIcon} from 'lucide-react';\nimport {useCallback, useEffect, useMemo, useRef, useState} from 'react';\nimport {DeckJsonMap} from './DeckJsonMap';\nimport type {DeckJsonMapHandle} from './types';\nimport {\n asDeckJsonMapConfig,\n createDeckMapDashboardPanelConfig,\n createDeckMapDashboardDatasetQuery,\n createDeckMapDashboardDatasetSourceSql,\n createDeckMapDashboardDatasets,\n DECK_MAP_DASHBOARD_PANEL_TYPE,\n DEFAULT_DECK_MAP_MAX_DATA_POINTS,\n isDeckMapDashboardSqlDatasetSource,\n isDeckMapDashboardTableDatasetSource,\n resolveDeckMapDashboardDatasetSource,\n type DeckMapDashboardFitToDataConfig,\n type DeckMapDashboardDatasetClientState,\n type DeckMapDashboardDatasetConfig,\n type DeckMapDashboardInteractionConfig,\n type DeckMapDashboardPanelConfig,\n} from './dashboardConfig';\nimport {\n createDescribeDatasetSql,\n geometryColumnsNeedingWkbWrap,\n parseDescribeSqlColumns,\n} from './datasets/wrapGeometryAsWkb';\nimport {\n useDeckMapFitToBounds,\n emitDeckMapDashboardFitRequest,\n createDeckMapBoundsQuery,\n} from './useDeckMapFitToBounds';\nimport {useDeckMapDatasets} from './useDeckMapDatasets';\nimport {DeckMapDashboardSettings} from './DashboardMapSettings';\nimport {\n createDeckMapDashboardPanelConfigForTable,\n findGeometryColumn,\n findLongitudeLatitudeColumns,\n} from './mapConfigUtils';\nimport {isDeckMapGeneratedColumn} from './useDeckMapDatasetSchema';\n\n/** Stable fallback while the DESCRIBE geometry-wrap probe is pending. */\nconst EMPTY_WRAPPED_GEOMETRY_COLUMNS: readonly string[] = [];\n\nexport {createDeckMapBoundsQuery};\n\nfunction createEmptyDeckMapDashboardPanelConfig(title = 'Map') {\n return createDeckMapDashboardPanelConfig({\n title,\n spec: {\n initialViewState: {longitude: 0, latitude: 20, zoom: 1.5},\n layers: [],\n },\n datasets: {},\n });\n}\n\n/**\n * Extracts column names from common DuckDB \"column not found\" error messages\n * and layer geometry incompatibility errors.\n * Returns the column names if detected, or null for unrecognized errors.\n */\nfunction parseMissingColumnsFromError(message: string): string[] | null {\n // \"Referenced column \"X\" not found in FROM clause!\" — may appear multiple times\n const refMatches = [\n ...message.matchAll(/Referenced column \"([^\"]+)\" not found/gi),\n ];\n if (refMatches.length > 0) return refMatches.map((m) => m[1]!);\n\n // \"Binder Error: Column \"X\" does not exist\" or \"column X not found\"\n const colMatch = message.match(\n /(?:Column|column)\\s+\"([^\"]+)\"\\s+(?:does not exist|not found)/i,\n );\n if (colMatch) return [colMatch[1]!];\n\n // \"Geometry column \"X\" was not found\"\n const geomNotFound = message.match(\n /Geometry column \"([^\"]+)\" was not found/i,\n );\n if (geomNotFound) return [geomNotFound[1]!];\n\n // \"Layer ... references unknown column \"X\" for getTimestamps.\"\n const unknownColumn = message.match(/references unknown column \"([^\"]+)\"/i);\n if (unknownColumn) return [unknownColumn[1]!];\n\n return null;\n}\n\n/**\n * Detects geometry type mismatch errors (e.g. polygon layer on point data).\n */\nfunction parseGeometryMismatchError(\n message: string,\n): {required: string; found: string} | null {\n const match = message.match(\n /requires (\\w+) geometry .+ but only (\\w+) coordinates were found/i,\n );\n if (match) return {required: match[1]!, found: match[2]!};\n return null;\n}\n\n/**\n * Detects columns referenced in layer config that are missing from the loaded dataset.\n */\nfunction detectMissingColumns(\n mapConfig: DeckMapDashboardPanelConfig | undefined,\n datasetStates: Record<string, DeckMapDashboardDatasetClientState>,\n): string[] {\n if (!mapConfig?.spec) return [];\n const missing: string[] = [];\n const spec = mapConfig.spec as Record<string, unknown>;\n const layers = Array.isArray(spec.layers) ? spec.layers : [];\n\n for (const layer of layers) {\n if (!layer || typeof layer !== 'object') continue;\n const layerObj = layer as Record<string, unknown>;\n const binding = layerObj._sqlroomsBinding as\n | Record<string, unknown>\n | undefined;\n const datasetId = binding?.dataset as string | undefined;\n const arrowTable = datasetId\n ? datasetStates[datasetId]?.arrowTable\n : undefined;\n if (!arrowTable) continue;\n\n const fieldNames = new Set(\n arrowTable.schema.fields.map((f) => f.name.toLowerCase()),\n );\n const check = (col: string | undefined) => {\n if (col && !fieldNames.has(col.toLowerCase())) {\n missing.push(col);\n }\n };\n\n for (const bindingColumn of [\n binding?.geometryColumn,\n binding?.sourceGeometryColumn,\n binding?.targetGeometryColumn,\n binding?.timestampColumn,\n binding?.hexagonColumn,\n ]) {\n check(bindingColumn as string | undefined);\n }\n\n // Check @@= accessors\n for (const [propName, propValue] of Object.entries(layerObj)) {\n // Skip elevation references when extrusion is disabled\n if (propName === 'getElevation' && !layerObj.extruded) continue;\n\n if (typeof propValue === 'string' && propValue.startsWith('@@=')) {\n const expression = propValue.slice(3).trim();\n const identifiers = expression.match(/\\b[A-Za-z_$][\\w$]*\\b/g);\n if (identifiers) {\n for (const id of identifiers) {\n check(id);\n }\n }\n }\n // Check @@function colorScale/scale field references\n if (\n propValue &&\n typeof propValue === 'object' &&\n '@@function' in (propValue as object)\n ) {\n const fn = propValue as Record<string, unknown>;\n if (typeof fn.field === 'string') {\n check(fn.field);\n }\n }\n }\n }\n\n return [...new Set(missing)];\n}\n\nfunction DeckMapRuntimeIssuePanel({issue}: {issue: ChartRuntimeIssue}) {\n if (issue.kind === 'sql-error' || issue.kind === 'render-error') {\n const missingColumns = parseMissingColumnsFromError(issue.message);\n if (missingColumns) {\n const generatedMissingColumns = missingColumns.filter(\n isDeckMapGeneratedColumn,\n );\n if (generatedMissingColumns.length > 0) {\n return (\n <div className=\"flex h-full min-h-[200px] flex-col items-center justify-center p-4\">\n <div className=\"mb-2 text-center font-semibold\">\n The visualization can&apos;t be displayed\n </div>\n <div className=\"text-center text-sm\">\n <span>\n The dataset transform did not produce required map output\n columns:{' '}\n </span>\n {generatedMissingColumns.map((col, idx) => (\n <span key={idx}>\n <span className=\"inline-flex items-center rounded-md border border-gray-600 bg-gray-800 px-1 py-0.5 text-xs font-medium text-gray-300\">\n {col}\n </span>{' '}\n </span>\n ))}\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"flex h-full min-h-[200px] flex-col items-center justify-center p-4\">\n <div className=\"mb-2 text-center font-semibold\">\n The visualization can&apos;t be displayed\n </div>\n <div className=\"text-center text-sm\">\n <span>Selected columns are missing in the dataset: </span>\n {missingColumns.map((col, idx) => (\n <span key={idx}>\n <span className=\"inline-flex items-center rounded-md border border-gray-600 bg-gray-800 px-1 py-0.5 text-xs font-medium text-gray-300\">\n {col}\n </span>{' '}\n </span>\n ))}\n </div>\n </div>\n );\n }\n\n const geomMismatch = parseGeometryMismatchError(issue.message);\n if (geomMismatch) {\n return (\n <div className=\"flex h-full min-h-[200px] flex-col items-center justify-center p-4\">\n <div className=\"mb-2 text-center font-semibold\">\n The visualization can&apos;t be displayed\n </div>\n <div className=\"text-center text-sm\">\n This layer requires {geomMismatch.required} geometry, but the\n current dataset only has {geomMismatch.found} coordinates.\n </div>\n </div>\n );\n }\n }\n\n const title =\n issue.kind === 'too-much-data'\n ? 'Too much data'\n : issue.kind === 'sql-error'\n ? 'Map query failed'\n : 'Unable to display map';\n\n return (\n <div className=\"flex h-full min-h-[200px] flex-col items-center justify-center p-4\">\n <div className=\"mb-2 text-center font-semibold\">{title}</div>\n <div className=\"text-center text-sm whitespace-pre-wrap\">\n {issue.message}\n </div>\n </div>\n );\n}\n\nfunction DeckMapDashboardDatasetClient({\n dashboard,\n dataset,\n datasetId,\n fitToData,\n panel,\n onDatasetState,\n runtimeIssueContext,\n runtimeIssueReporter,\n selectionName,\n maxRows,\n}: {\n dashboard: MosaicDashboardEntryType;\n dataset: DeckMapDashboardDatasetConfig;\n datasetId: string;\n fitToData?: DeckMapDashboardFitToDataConfig;\n panel: MosaicDashboardPanelConfigType;\n onDatasetState: (\n datasetId: string,\n state: DeckMapDashboardDatasetClientState | undefined,\n ) => void;\n runtimeIssueContext?: ChartRuntimeIssueContext;\n runtimeIssueReporter?: ChartRuntimeIssueReporter;\n selectionName: string;\n maxRows: number;\n}) {\n const datasetFitToData = useMemo(\n () => (fitToData?.dataset === datasetId ? fitToData : undefined),\n [datasetId, fitToData],\n );\n const source = useMemo(\n () =>\n resolveDeckMapDashboardDatasetSource({\n dashboard,\n panel,\n dataset,\n fitToData: datasetFitToData,\n }),\n [dashboard, dataset, datasetFitToData, panel],\n );\n\n const connector = useStoreWithDuckDb((state) => state.db.connector);\n const [geometryWrapProbe, setGeometryWrapProbe] = useState<{\n sourceSqlKey: string;\n columns: string[];\n } | null>(null);\n\n const sourceSqlKey = useMemo(() => {\n if (!source) return '';\n try {\n return createDeckMapDashboardDatasetSourceSql(source);\n } catch {\n return '';\n }\n }, [source]);\n\n // Pending while probe key mismatches (avoids setState-in-effect).\n const geometryColumnsToWrapAsWkb = useMemo(() => {\n if (!source || !sourceSqlKey) return [];\n if (geometryWrapProbe?.sourceSqlKey !== sourceSqlKey) return null;\n return geometryWrapProbe.columns;\n }, [geometryWrapProbe, source, sourceSqlKey]);\n\n useEffect(() => {\n if (!source || !sourceSqlKey) {\n return;\n }\n\n let cancelled = false;\n void (async () => {\n try {\n const describeTable = await connector.query(\n createDescribeDatasetSql(sourceSqlKey),\n );\n if (cancelled) return;\n setGeometryWrapProbe({\n sourceSqlKey,\n columns: geometryColumnsNeedingWkbWrap(\n parseDescribeSqlColumns(describeTable),\n ),\n });\n } catch {\n if (cancelled) return;\n setGeometryWrapProbe({sourceSqlKey, columns: []});\n }\n })();\n\n return () => {\n cancelled = true;\n };\n }, [connector, source, sourceSqlKey]);\n\n const geometryProbeReady = geometryColumnsToWrapAsWkb !== null;\n const wrappedGeometryColumnNames =\n geometryColumnsToWrapAsWkb ?? EMPTY_WRAPPED_GEOMETRY_COLUMNS;\n\n const query = useCallback(\n (filter: unknown) =>\n source\n ? createDeckMapDashboardDatasetQuery(source, filter, {\n sampleRows: maxRows,\n geometryColumnsToWrapAsWkb: wrappedGeometryColumnNames,\n })\n : createDeckMapDashboardDatasetQuery(\n {tableName: '__missing_dashboard_map_dataset__'},\n filter,\n {sampleRows: maxRows},\n ),\n [wrappedGeometryColumnNames, maxRows, source],\n );\n const queryError = useCallback(\n (err: Error) => {\n onDatasetState(datasetId, {\n arrowTable: undefined,\n error: err,\n isLoading: false,\n client: null,\n isSampled: false,\n wrappedGeometryColumnNames,\n });\n },\n [datasetId, onDatasetState, wrappedGeometryColumnNames],\n );\n const sourceKey = isDeckMapDashboardTableDatasetSource(source)\n ? source.tableName\n : isDeckMapDashboardSqlDatasetSource(source)\n ? ''\n : (dashboard.selectedTable ?? '');\n const sourceQueryKey = isDeckMapDashboardSqlDatasetSource(source)\n ? source.sqlQuery\n : isDeckMapDashboardTableDatasetSource(source)\n ? (source.transformSql ?? '')\n : '';\n const {data, error, isLoading, client} = useMosaicClient({\n id: `${panel.id}:${datasetId}:${sourceKey}:${sourceQueryKey}:${maxRows}:${geometryColumnsToWrapAsWkb?.join(',') ?? 'pending'}`,\n selectionName,\n query,\n queryError,\n enabled: Boolean(source) && geometryProbeReady,\n runtimeIssueContext,\n runtimeIssueReporter,\n });\n\n // Register client for panel reset button\n usePanelClientRegistration(dashboard.id, panel.id, client ? [client] : []);\n\n const isSampled = Boolean(data && data.numRows >= maxRows);\n\n useEffect(() => {\n onDatasetState(datasetId, {\n arrowTable: data ?? undefined,\n error,\n isLoading: isLoading || !geometryProbeReady,\n client,\n isSampled,\n wrappedGeometryColumnNames,\n });\n\n return () => {\n onDatasetState(datasetId, undefined);\n };\n }, [\n client,\n data,\n datasetId,\n error,\n geometryProbeReady,\n isLoading,\n isSampled,\n onDatasetState,\n wrappedGeometryColumnNames,\n ]);\n\n return null;\n}\n\nfunction createPointRadiusPredicate(\n interaction: DeckMapDashboardInteractionConfig,\n coordinate: [number, number],\n) {\n const [longitude, latitude] = coordinate;\n const radiusMeters = interaction.radiusMeters ?? 500;\n const metersPerDegree = 111_320;\n const cosLatitude = Math.cos(latitude * (Math.PI / 180));\n const radiusSquared = radiusMeters * radiusMeters;\n\n return sql`(\n pow((${column(interaction.longitudeColumn)} - ${longitude}) * ${\n cosLatitude * metersPerDegree\n }, 2) +\n pow((${column(interaction.latitudeColumn)} - ${latitude}) * ${\n metersPerDegree\n }, 2)\n ) < ${radiusSquared}`;\n}\n\ntype DeckMapInteractionEvent = {\n coordinate?: number[] | null;\n object?: unknown;\n index?: number;\n picked?: boolean;\n};\n\nfunction getCoordinate(\n info: DeckMapInteractionEvent,\n): [number, number] | undefined {\n return info.coordinate && info.coordinate.length >= 2\n ? [info.coordinate[0]!, info.coordinate[1]!]\n : undefined;\n}\n\nfunction isPickedMapFeature(info: DeckMapInteractionEvent) {\n return Boolean(info.picked || info.object || (info.index ?? -1) >= 0);\n}\n\nfunction DeckMapDashboardHeaderActions({\n panel,\n}: MosaicDashboardPanelRendererProps) {\n const mapConfig = asDeckJsonMapConfig(panel.config);\n const canFitView = Boolean(mapConfig?.fitToData);\n const fitViewLabel = canFitView\n ? 'Fit map view to data'\n : 'Fit view unavailable for this map';\n\n return (\n <div className=\"flex items-center gap-0.5\">\n <Tooltip>\n <TooltipTrigger asChild>\n <span\n className=\"inline-flex\"\n tabIndex={canFitView ? undefined : 0}\n aria-label={canFitView ? undefined : fitViewLabel}\n >\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-6 w-6\"\n aria-label={fitViewLabel}\n disabled={!canFitView}\n onClick={() => emitDeckMapDashboardFitRequest(panel.id)}\n >\n <FocusIcon className=\"h-3.5 w-3.5\" />\n </Button>\n </span>\n </TooltipTrigger>\n <TooltipContent>{fitViewLabel}</TooltipContent>\n </Tooltip>\n </div>\n );\n}\n\nfunction DeckMapDashboardRenderer({\n dashboard,\n dashboardId,\n panel,\n selectionName,\n}: MosaicDashboardPanelRendererProps) {\n const mapConfig = asDeckJsonMapConfig(panel.config);\n const isCustomMode = mapConfig?.configMode === 'custom';\n const getSelection = useStoreWithMosaicDashboard(\n (state) => state.mosaic.getSelection,\n );\n const issue = useStoreWithMosaicDashboard((state) =>\n state.mosaicDashboard.getPanelIssue(dashboardId, panel.id),\n );\n const clearPanelIssue = useStoreWithMosaicDashboard(\n (state) => state.mosaicDashboard.clearPanelIssue,\n );\n\n // Clear runtime issues when the active table or panel config changes so\n // the map can recover (e.g., after switching tables or AI updating the map).\n useEffect(() => {\n clearPanelIssue(dashboardId, panel.id);\n }, [\n clearPanelIssue,\n dashboard.selectedTable,\n dashboardId,\n panel.config,\n panel.id,\n ]);\n\n const selection = useMemo<Selection>(\n () => getSelection(selectionName, 'crossfilter'),\n [getSelection, selectionName],\n );\n const [container, setContainer] = useState<HTMLDivElement | null>(null);\n const deckMapRef = useRef<DeckJsonMapHandle>(null);\n const [sampledDismissed, setSampledDismissed] = useState(false);\n\n const {\n datasetStates,\n handleDatasetState,\n runtimeIssueContext,\n runtimeIssueReporter,\n handleRenderingError,\n } = useDeckMapDatasets({dashboardId, panel});\n\n const {fitToData} = useDeckMapFitToBounds({\n panelId: panel.id,\n dashboard,\n panel,\n container,\n deckMapRef,\n });\n\n const handleBrushEvent = useCallback(\n (info: DeckMapInteractionEvent) => {\n const interaction = mapConfig?.interaction;\n if (!interaction) {\n return;\n }\n\n const client = datasetStates[interaction.dataset]?.client as\n | MosaicClient\n | null\n | undefined;\n if (!client) {\n return;\n }\n const coordinate = getCoordinate(info);\n if (!coordinate) {\n return;\n }\n if (interaction.event !== 'click' && !isPickedMapFeature(info)) {\n selection.reset(\n selection.clauses.filter((clause) => clause.source === client),\n );\n return;\n }\n\n const radiusMeters = interaction.radiusMeters ?? 500;\n selection.update({\n source: client,\n clients: new Set([client]),\n value: [coordinate[0], coordinate[1], radiusMeters],\n predicate: createPointRadiusPredicate(interaction, coordinate),\n });\n },\n [datasetStates, mapConfig?.interaction, selection],\n );\n\n const datasetError = useMemo(() => {\n for (const state of Object.values(datasetStates)) {\n if (state.error) return state.error;\n }\n return undefined;\n }, [datasetStates]);\n\n const missingColumns = useMemo(\n () => detectMissingColumns(mapConfig ?? undefined, datasetStates),\n [mapConfig, datasetStates],\n );\n\n const maxRows =\n mapConfig?.dataPolicy?.maxRows ?? DEFAULT_DECK_MAP_MAX_DATA_POINTS;\n\n const mapContent = !mapConfig ? (\n <div className=\"text-muted-foreground flex h-full items-center justify-center p-4 text-sm\">\n Invalid map panel config.\n </div>\n ) : Object.entries(mapConfig.datasets).length === 0 ? (\n <div className=\"text-muted-foreground flex h-full items-center justify-center p-4 text-sm\">\n Map panels require at least one dataset.\n </div>\n ) : (\n <>\n {Object.entries(mapConfig.datasets).map(([datasetId, dataset]) => (\n <DeckMapDashboardDatasetClient\n key={datasetId}\n dashboard={dashboard}\n dataset={dataset}\n datasetId={datasetId}\n fitToData={fitToData ?? undefined}\n panel={panel}\n onDatasetState={handleDatasetState}\n runtimeIssueContext={runtimeIssueContext}\n runtimeIssueReporter={runtimeIssueReporter}\n selectionName={selectionName}\n maxRows={maxRows}\n />\n ))}\n {issue ? (\n <DeckMapRuntimeIssuePanel issue={issue} />\n ) : datasetError ? (\n <DeckMapRuntimeIssuePanel\n issue={{\n kind: 'sql-error',\n panelId: panel.id,\n chartType: DECK_MAP_DASHBOARD_PANEL_TYPE,\n message: datasetError.message,\n recoverable: true,\n }}\n />\n ) : (\n <div ref={setContainer} className=\"relative h-full w-full\">\n {Object.values(datasetStates).some((s) => s.isSampled) &&\n !sampledDismissed && (\n <div className=\"bg-background/80 text-muted-foreground absolute top-2 left-2 z-10 flex items-center gap-1.5 rounded px-2 py-1 text-xs shadow\">\n <span>Data sampled to {maxRows.toLocaleString()} rows</span>\n <button\n className=\"text-muted-foreground/60 hover:text-foreground -mr-0.5 ml-0.5\"\n onClick={() => setSampledDismissed(true)}\n >\n ×\n </button>\n </div>\n )}\n {missingColumns.length > 0 && !isCustomMode && (\n <Tooltip>\n <TooltipTrigger asChild>\n <span\n className={`absolute left-2 z-10 flex h-5 w-5 items-center justify-center ${\n Object.values(datasetStates).some((s) => s.isSampled) &&\n !sampledDismissed\n ? 'top-9'\n : 'top-2'\n }`}\n >\n <AlertTriangleIcon className=\"h-4 w-4 text-amber-500 drop-shadow-sm\" />\n </span>\n </TooltipTrigger>\n <TooltipContent side=\"right\">\n <p className=\"text-xs font-medium\">Missing columns:</p>\n <p className=\"text-xs\">{missingColumns.join(', ')}</p>\n </TooltipContent>\n </Tooltip>\n )}\n <DeckJsonMap\n ref={deckMapRef}\n className=\"h-full w-full px-0.5 pb-0.5\"\n spec={mapConfig.spec}\n datasets={\n mapConfig\n ? createDeckMapDashboardDatasets(mapConfig, datasetStates)\n : {}\n }\n mapStyle={mapConfig.mapStyle}\n mapProps={mapConfig.mapProps}\n showLegends={mapConfig.showLegends !== false}\n onRenderingError={handleRenderingError}\n deckProps={{\n controller: true,\n ...(mapConfig.interaction\n ? (mapConfig.interaction.event ?? 'hover') === 'click'\n ? {onClick: handleBrushEvent}\n : {onHover: handleBrushEvent}\n : {}),\n }}\n />\n </div>\n )}\n </>\n );\n\n return mapContent;\n}\n\nexport const deckMapDashboardPanelRenderer: MosaicDashboardPanelRenderer = {\n component: DeckMapDashboardRenderer,\n headerActions: DeckMapDashboardHeaderActions,\n icon: MapIcon,\n settings: DeckMapDashboardSettings,\n};\n\nexport const deckMapDashboardAddPanelAction: import('@sqlrooms/mosaic').MosaicDashboardAddPanelAction =\n {\n type: DECK_MAP_DASHBOARD_PANEL_TYPE,\n label: 'Map',\n icon: MapIcon,\n createPanel: ({selectedTable}) => {\n if (\n selectedTable &&\n (findLongitudeLatitudeColumns(selectedTable) ??\n findGeometryColumn(selectedTable))\n ) {\n return createDeckMapDashboardPanelConfigForTable({\n title: `${selectedTable.tableName} map`,\n tableName: selectedTable.tableName,\n columns: selectedTable.columns,\n tableReference: selectedTable.table,\n });\n }\n\n return createEmptyDeckMapDashboardPanelConfig(\n selectedTable ? `${selectedTable.tableName} map` : 'Map',\n );\n },\n };\n"]}
@@ -11,6 +11,11 @@ export type DeckMapDashboardDatasetClientState = {
11
11
  error?: Error;
12
12
  client: unknown;
13
13
  isSampled?: boolean;
14
+ /**
15
+ * Native GEOMETRY columns wrapped via ST_AsWKB for this query.
16
+ * Only force `geometryEncodingHint: "wkb"` when the bound column is listed.
17
+ */
18
+ wrappedGeometryColumnNames?: readonly string[];
14
19
  };
15
20
  export declare function resolveDeckMapDashboardDatasetSource(options: {
16
21
  dashboard: MosaicDashboardEntryType;
@@ -18,8 +23,12 @@ export declare function resolveDeckMapDashboardDatasetSource(options: {
18
23
  dataset?: DeckMapDashboardDatasetConfig;
19
24
  fitToData?: DeckMapDashboardFitToDataConfig;
20
25
  }): DeckMapDashboardDatasetSource | undefined;
26
+ /** Unfiltered dataset SQL for DESCRIBE / Mosaic (before sample/filters). */
27
+ export declare function createDeckMapDashboardDatasetSourceSql(source: DeckMapDashboardDatasetSource): string;
21
28
  export declare function createDeckMapDashboardDatasetQuery(source: DeckMapDashboardDatasetSource, filter: unknown, options?: {
22
29
  sampleRows?: number;
30
+ /** Native GEOMETRY columns to project with ST_AsWKB (from DESCRIBE). */
31
+ geometryColumnsToWrapAsWkb?: readonly string[];
23
32
  }): import("@uwdata/mosaic-sql").SelectQuery;
24
- export declare function createDeckMapDashboardDatasets(mapConfig: DeckMapDashboardPanelConfig, datasetStates: Record<string, Pick<DeckMapDashboardDatasetClientState, 'arrowTable'>>): DeckJsonMapProps['datasets'];
33
+ export declare function createDeckMapDashboardDatasets(mapConfig: DeckMapDashboardPanelConfig, datasetStates: Record<string, Pick<DeckMapDashboardDatasetClientState, 'arrowTable' | 'wrappedGeometryColumnNames'>>): DeckJsonMapProps['datasets'];
25
34
  //# sourceMappingURL=dashboardConfig.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dashboardConfig.d.ts","sourceRoot":"","sources":["../src/dashboardConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,wBAAwB,EAC7B,KAAK,8BAA8B,EAEpC,MAAM,kBAAkB,CAAC;AAQ1B,OAAO,KAAK,EAAC,KAAK,IAAI,UAAU,EAAC,MAAM,cAAc,CAAC;AAEtD,OAAO,EAGL,KAAK,6BAA6B,EAClC,KAAK,6BAA6B,EAClC,KAAK,+BAA+B,EACpC,KAAK,2BAA2B,EACjC,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,mBAAmB,EACnB,iCAAiC,EACjC,6BAA6B,EAC7B,gCAAgC,EAChC,kCAAkC,EAClC,oCAAoC,GACrC,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,wCAAwC,EACxC,6BAA6B,EAC7B,6BAA6B,EAC7B,+BAA+B,EAC/B,iCAAiC,EACjC,2BAA2B,GAC5B,MAAM,aAAa,CAAC;AACrB,YAAY,EAAC,gBAAgB,EAAC,MAAM,SAAS,CAAC;AAC9C,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,SAAS,CAAC;AAE9C,MAAM,MAAM,kCAAkC,GAAG;IAC/C,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,wBAAgB,oCAAoC,CAAC,OAAO,EAAE;IAC5D,SAAS,EAAE,wBAAwB,CAAC;IACpC,KAAK,EAAE,8BAA8B,CAAC;IACtC,OAAO,CAAC,EAAE,6BAA6B,CAAC;IACxC,SAAS,CAAC,EAAE,+BAA+B,CAAC;CAC7C,GAAG,6BAA6B,GAAG,SAAS,CA6B5C;AAeD,wBAAgB,kCAAkC,CAChD,MAAM,EAAE,6BAA6B,EACrC,MAAM,EAAE,OAAO,EACf,OAAO,CAAC,EAAE;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAC,4CA2BhC;AAUD,wBAAgB,8BAA8B,CAC5C,SAAS,EAAE,2BAA2B,EACtC,aAAa,EAAE,MAAM,CACnB,MAAM,EACN,IAAI,CAAC,kCAAkC,EAAE,YAAY,CAAC,CACvD,GACA,gBAAgB,CAAC,UAAU,CAAC,CAW9B"}
1
+ {"version":3,"file":"dashboardConfig.d.ts","sourceRoot":"","sources":["../src/dashboardConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,wBAAwB,EAC7B,KAAK,8BAA8B,EAEpC,MAAM,kBAAkB,CAAC;AAQ1B,OAAO,KAAK,EAAC,KAAK,IAAI,UAAU,EAAC,MAAM,cAAc,CAAC;AAGtD,OAAO,EAGL,KAAK,6BAA6B,EAClC,KAAK,6BAA6B,EAClC,KAAK,+BAA+B,EACpC,KAAK,2BAA2B,EACjC,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,mBAAmB,EACnB,iCAAiC,EACjC,6BAA6B,EAC7B,gCAAgC,EAChC,kCAAkC,EAClC,oCAAoC,GACrC,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,wCAAwC,EACxC,6BAA6B,EAC7B,6BAA6B,EAC7B,+BAA+B,EAC/B,iCAAiC,EACjC,2BAA2B,GAC5B,MAAM,aAAa,CAAC;AACrB,YAAY,EAAC,gBAAgB,EAAC,MAAM,SAAS,CAAC;AAC9C,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,SAAS,CAAC;AAE9C,MAAM,MAAM,kCAAkC,GAAG;IAC/C,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;OAGG;IACH,0BAA0B,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAChD,CAAC;AAEF,wBAAgB,oCAAoC,CAAC,OAAO,EAAE;IAC5D,SAAS,EAAE,wBAAwB,CAAC;IACpC,KAAK,EAAE,8BAA8B,CAAC;IACtC,OAAO,CAAC,EAAE,6BAA6B,CAAC;IACxC,SAAS,CAAC,EAAE,+BAA+B,CAAC;CAC7C,GAAG,6BAA6B,GAAG,SAAS,CA2B5C;AAeD,4EAA4E;AAC5E,wBAAgB,sCAAsC,CACpD,MAAM,EAAE,6BAA6B,GACpC,MAAM,CAWR;AAED,wBAAgB,kCAAkC,CAChD,MAAM,EAAE,6BAA6B,EACrC,MAAM,EAAE,OAAO,EACf,OAAO,CAAC,EAAE;IACR,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wEAAwE;IACxE,0BAA0B,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAChD,4CA2CF;AAUD,wBAAgB,8BAA8B,CAC5C,SAAS,EAAE,2BAA2B,EACtC,aAAa,EAAE,MAAM,CACnB,MAAM,EACN,IAAI,CACF,kCAAkC,EAClC,YAAY,GAAG,4BAA4B,CAC5C,CACF,GACA,gBAAgB,CAAC,UAAU,CAAC,CAsB9B"}
@@ -2,14 +2,13 @@ import { Query, } from '@sqlrooms/mosaic';
2
2
  import { getTableIdentity, makeQualifiedTableName, parseQualifiedSqlIdentifier, quoteParsedRawSqlTableReference, } from '@sqlrooms/duckdb';
3
3
  import { verbatim } from '@uwdata/mosaic-sql';
4
4
  import { createDeckTableDatasetSql } from './datasets/tableDatasetSql';
5
+ import { wrapSqlGeometryColumnsAsWkb } from './datasets/wrapGeometryAsWkb';
5
6
  import { isDeckMapDashboardSqlDatasetSource, isDeckMapDashboardTableDatasetSource, } from './mapConfig';
6
7
  export { asDeckJsonMapConfig, createDeckMapDashboardPanelConfig, DECK_MAP_DASHBOARD_PANEL_TYPE, DEFAULT_DECK_MAP_MAX_DATA_POINTS, isDeckMapDashboardSqlDatasetSource, isDeckMapDashboardTableDatasetSource, } from './mapConfig';
7
8
  export function resolveDeckMapDashboardDatasetSource(options) {
8
9
  const datasetSource = options.dataset?.source;
9
10
  const dashboardTable = stripCatalogPrefix(options.dashboard.selectedTable);
10
- // The dashboard's selected table always takes precedence as the data source.
11
- // When the user switches the table in the selector, structured table-backed
12
- // datasets update while literal SQL remains pinned to its authored query.
11
+ // Selected table wins for table sources; sqlQuery stays pinned.
13
12
  if (isDeckMapDashboardSqlDatasetSource(datasetSource)) {
14
13
  return datasetSource;
15
14
  }
@@ -39,6 +38,17 @@ function stripCatalogPrefix(tableName) {
39
38
  table: parsed.table,
40
39
  }));
41
40
  }
41
+ /** Unfiltered dataset SQL for DESCRIBE / Mosaic (before sample/filters). */
42
+ export function createDeckMapDashboardDatasetSourceSql(source) {
43
+ if (isDeckMapDashboardSqlDatasetSource(source)) {
44
+ return source.sqlQuery.trim().replace(/(?:\s*;+\s*)+$/, '');
45
+ }
46
+ if (isDeckMapDashboardTableDatasetSource(source) &&
47
+ !source.transformSql?.trim()) {
48
+ return `SELECT * FROM ${getDeckMapDatasetSourceTableReference(source.tableName)}`;
49
+ }
50
+ return createDeckTableDatasetSql(source);
51
+ }
42
52
  export function createDeckMapDashboardDatasetQuery(source, filter, options) {
43
53
  const isSqlSource = isDeckMapDashboardSqlDatasetSource(source);
44
54
  const isTableSource = isDeckMapDashboardTableDatasetSource(source);
@@ -46,18 +56,32 @@ export function createDeckMapDashboardDatasetQuery(source, filter, options) {
46
56
  const tableReference = isDirectTableSource
47
57
  ? getDeckMapDatasetSourceTableReference(source.tableName)
48
58
  : '';
49
- // Apply USING SAMPLE at the source level so Mosaic filters work on top.
50
- const sourceExpr = isSqlSource
51
- ? `(${source.sqlQuery})`
52
- : isDirectTableSource
53
- ? tableReference
54
- : `(${createDeckTableDatasetSql(source)})`;
55
- const sampledSource = options?.sampleRows
56
- ? `(SELECT * FROM ${sourceExpr} USING SAMPLE ${options.sampleRows} ROWS)`
57
- : sourceExpr;
58
- const query = isSqlSource || !isDirectTableSource || options?.sampleRows
59
+ const baseSql = createDeckMapDashboardDatasetSourceSql(source);
60
+ // Sample before WKB so ST_AsWKB runs only on sampled rows.
61
+ const sampledSql = options?.sampleRows
62
+ ? `SELECT * FROM (${baseSql}) AS "__sqlrooms_sample_source" USING SAMPLE ${options.sampleRows} ROWS`
63
+ : baseSql;
64
+ const wrappedSql = wrapSqlGeometryColumnsAsWkb(sampledSql, options?.geometryColumnsToWrapAsWkb ?? []);
65
+ const usedWrap = Boolean(wrappedSql);
66
+ let sourceExpr;
67
+ if (wrappedSql) {
68
+ sourceExpr = `(${wrappedSql})`;
69
+ }
70
+ else if (options?.sampleRows) {
71
+ sourceExpr = `(${sampledSql})`;
72
+ }
73
+ else if (isSqlSource) {
74
+ sourceExpr = `(${source.sqlQuery})`;
75
+ }
76
+ else if (isDirectTableSource) {
77
+ sourceExpr = tableReference;
78
+ }
79
+ else {
80
+ sourceExpr = `(${createDeckTableDatasetSql(source)})`;
81
+ }
82
+ const query = usedWrap || options?.sampleRows || isSqlSource || !isDirectTableSource
59
83
  ? Query.from({
60
- __dashboard_map_dataset: verbatim(sampledSource),
84
+ __dashboard_map_dataset: verbatim(sourceExpr),
61
85
  })
62
86
  : Query.from({ __dashboard_map_dataset: verbatim(tableReference) });
63
87
  return query.select('*').where(filter);
@@ -70,13 +94,22 @@ function getDeckMapDatasetSourceTableReference(tableName) {
70
94
  return tableReference;
71
95
  }
72
96
  export function createDeckMapDashboardDatasets(mapConfig, datasetStates) {
73
- return Object.fromEntries(Object.entries(mapConfig.datasets).map(([datasetId, dataset]) => [
74
- datasetId,
75
- {
76
- arrowTable: datasetStates[datasetId]?.arrowTable,
77
- geometryColumn: dataset.geometryColumn,
78
- geometryEncodingHint: dataset.geometryEncodingHint,
79
- },
80
- ]));
97
+ return Object.fromEntries(Object.entries(mapConfig.datasets).map(([datasetId, dataset]) => {
98
+ const wrapped = datasetStates[datasetId]?.wrappedGeometryColumnNames ?? [];
99
+ const geometryColumn = dataset.geometryColumn;
100
+ const wrappedConfiguredColumn = typeof geometryColumn === 'string' &&
101
+ geometryColumn.length > 0 &&
102
+ wrapped.includes(geometryColumn);
103
+ return [
104
+ datasetId,
105
+ {
106
+ arrowTable: datasetStates[datasetId]?.arrowTable,
107
+ geometryColumn,
108
+ geometryEncodingHint: wrappedConfiguredColumn
109
+ ? 'wkb'
110
+ : dataset.geometryEncodingHint,
111
+ },
112
+ ];
113
+ }));
81
114
  }
82
115
  //# sourceMappingURL=dashboardConfig.js.map