@sqlrooms/deck 0.29.0-rc.10 → 0.29.0-rc.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +88 -16
- package/dist/BlockMapSettings.d.ts.map +1 -1
- package/dist/BlockMapSettings.js +4 -16
- package/dist/BlockMapSettings.js.map +1 -1
- package/dist/DashboardMapSettings.d.ts.map +1 -1
- package/dist/DashboardMapSettings.js +7 -10
- package/dist/DashboardMapSettings.js.map +1 -1
- package/dist/DeckJsonMap.d.ts.map +1 -1
- package/dist/DeckJsonMap.js +20 -18
- package/dist/DeckJsonMap.js.map +1 -1
- package/dist/DeckJsonMapSpec.d.ts +916 -53
- package/dist/DeckJsonMapSpec.d.ts.map +1 -1
- package/dist/DeckJsonMapSpec.js +9 -0
- package/dist/DeckJsonMapSpec.js.map +1 -1
- package/dist/DeckMapDefaultStylesProvider.d.ts +3 -4
- package/dist/DeckMapDefaultStylesProvider.d.ts.map +1 -1
- package/dist/DeckMapDefaultStylesProvider.js +13 -7
- package/dist/DeckMapDefaultStylesProvider.js.map +1 -1
- package/dist/DeckMapSurface.d.ts +1 -1
- package/dist/DeckMapSurface.js +1 -1
- package/dist/DeckMapSurface.js.map +1 -1
- package/dist/MapSettings.d.ts +14 -0
- package/dist/MapSettings.d.ts.map +1 -1
- package/dist/MapSettings.js +555 -186
- package/dist/MapSettings.js.map +1 -1
- package/dist/MapSettingsControls.d.ts +8 -1
- package/dist/MapSettingsControls.d.ts.map +1 -1
- package/dist/MapSettingsControls.js +24 -2
- package/dist/MapSettingsControls.js.map +1 -1
- package/dist/ai.d.ts +19 -5
- package/dist/ai.d.ts.map +1 -1
- package/dist/ai.js +63 -112
- package/dist/ai.js.map +1 -1
- package/dist/aiNormalize.d.ts +31 -0
- package/dist/aiNormalize.d.ts.map +1 -0
- package/dist/aiNormalize.js +630 -0
- package/dist/aiNormalize.js.map +1 -0
- package/dist/block.d.ts +1 -1
- package/dist/block.d.ts.map +1 -1
- package/dist/block.js +1 -1
- package/dist/block.js.map +1 -1
- package/dist/createOrUpdateDeckMapResource.d.ts +6 -2
- package/dist/createOrUpdateDeckMapResource.d.ts.map +1 -1
- package/dist/createOrUpdateDeckMapResource.js +57 -4
- package/dist/createOrUpdateDeckMapResource.js.map +1 -1
- package/dist/dashboard.d.ts.map +1 -1
- package/dist/dashboard.js +72 -8
- package/dist/dashboard.js.map +1 -1
- package/dist/dashboardConfig.d.ts +10 -1
- package/dist/dashboardConfig.d.ts.map +1 -1
- package/dist/dashboardConfig.js +55 -22
- package/dist/dashboardConfig.js.map +1 -1
- package/dist/datasets/PreparedDatasetStore.d.ts +3 -4
- package/dist/datasets/PreparedDatasetStore.d.ts.map +1 -1
- package/dist/datasets/PreparedDatasetStore.js +35 -10
- package/dist/datasets/PreparedDatasetStore.js.map +1 -1
- package/dist/datasets/helpers.d.ts +39 -2
- package/dist/datasets/helpers.d.ts.map +1 -1
- package/dist/datasets/helpers.js +86 -3
- package/dist/datasets/helpers.js.map +1 -1
- package/dist/datasets/usePreparedDatasetStates.d.ts.map +1 -1
- package/dist/datasets/usePreparedDatasetStates.js +12 -8
- package/dist/datasets/usePreparedDatasetStates.js.map +1 -1
- package/dist/datasets/wrapGeometryAsWkb.d.ts +20 -0
- package/dist/datasets/wrapGeometryAsWkb.d.ts.map +1 -0
- package/dist/datasets/wrapGeometryAsWkb.js +65 -0
- package/dist/datasets/wrapGeometryAsWkb.js.map +1 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/json/colorScaleFunction.d.ts +12 -4
- package/dist/json/colorScaleFunction.d.ts.map +1 -1
- package/dist/json/colorScaleFunction.js.map +1 -1
- package/dist/json/compileColorScale.d.ts +3 -2
- package/dist/json/compileColorScale.d.ts.map +1 -1
- package/dist/json/compileColorScale.js +16 -1
- package/dist/json/compileColorScale.js.map +1 -1
- package/dist/json/compileGeoArrowAccessor.d.ts +5 -0
- package/dist/json/compileGeoArrowAccessor.d.ts.map +1 -1
- package/dist/json/compileGeoArrowAccessor.js +17 -3
- package/dist/json/compileGeoArrowAccessor.js.map +1 -1
- package/dist/json/createDeckJsonConfiguration.d.ts.map +1 -1
- package/dist/json/createDeckJsonConfiguration.js +278 -151
- package/dist/json/createDeckJsonConfiguration.js.map +1 -1
- package/dist/json/defaultClasses.d.ts.map +1 -1
- package/dist/json/defaultClasses.js +3 -3
- package/dist/json/defaultClasses.js.map +1 -1
- package/dist/json/extractColorScaleLegends.d.ts.map +1 -1
- package/dist/json/extractColorScaleLegends.js +43 -14
- package/dist/json/extractColorScaleLegends.js.map +1 -1
- package/dist/json/heatmapDefaults.d.ts +17 -7
- package/dist/json/heatmapDefaults.d.ts.map +1 -1
- package/dist/json/heatmapDefaults.js +54 -12
- package/dist/json/heatmapDefaults.js.map +1 -1
- package/dist/json/layers/DeckH3HexagonLayer.d.ts.map +1 -1
- package/dist/json/layers/DeckH3HexagonLayer.js +9 -14
- package/dist/json/layers/DeckH3HexagonLayer.js.map +1 -1
- package/dist/json/layers/DeckHeatmapLayer.d.ts +32 -0
- package/dist/json/layers/DeckHeatmapLayer.d.ts.map +1 -0
- package/dist/json/layers/DeckHeatmapLayer.js +69 -0
- package/dist/json/layers/DeckHeatmapLayer.js.map +1 -0
- package/dist/json/layers/h3IndexFormat.d.ts +6 -0
- package/dist/json/layers/h3IndexFormat.d.ts.map +1 -0
- package/dist/json/layers/h3IndexFormat.js +17 -0
- package/dist/json/layers/h3IndexFormat.js.map +1 -0
- package/dist/json/layers/index.d.ts +2 -0
- package/dist/json/layers/index.d.ts.map +1 -1
- package/dist/json/layers/index.js +2 -0
- package/dist/json/layers/index.js.map +1 -1
- package/dist/json/rewriteGeoArrowAccessors.d.ts.map +1 -1
- package/dist/json/rewriteGeoArrowAccessors.js +22 -5
- package/dist/json/rewriteGeoArrowAccessors.js.map +1 -1
- package/dist/json/scaleFunction.d.ts +27 -0
- package/dist/json/scaleFunction.d.ts.map +1 -0
- package/dist/json/scaleFunction.js +151 -0
- package/dist/json/scaleFunction.js.map +1 -0
- package/dist/mapAiConfig.d.ts +8 -0
- package/dist/mapAiConfig.d.ts.map +1 -1
- package/dist/mapAiConfig.js +9 -1
- package/dist/mapAiConfig.js.map +1 -1
- package/dist/mapAiSharedInstructions.d.ts +3 -0
- package/dist/mapAiSharedInstructions.d.ts.map +1 -0
- package/dist/mapAiSharedInstructions.js +16 -0
- package/dist/mapAiSharedInstructions.js.map +1 -0
- package/dist/mapConfig.d.ts +7 -1
- package/dist/mapConfig.d.ts.map +1 -1
- package/dist/mapConfig.js.map +1 -1
- package/dist/mapConfigUtils.d.ts +22 -0
- package/dist/mapConfigUtils.d.ts.map +1 -1
- package/dist/mapConfigUtils.js +147 -3
- package/dist/mapConfigUtils.js.map +1 -1
- package/dist/mapFit.d.ts +16 -0
- package/dist/mapFit.d.ts.map +1 -1
- package/dist/mapFit.js +208 -30
- package/dist/mapFit.js.map +1 -1
- package/dist/mapLayerConfigUtils.d.ts +64 -1
- package/dist/mapLayerConfigUtils.d.ts.map +1 -1
- package/dist/mapLayerConfigUtils.js +277 -16
- package/dist/mapLayerConfigUtils.js.map +1 -1
- package/dist/mapResourceAuthoring.d.ts +3 -1
- package/dist/mapResourceAuthoring.d.ts.map +1 -1
- package/dist/mapResourceAuthoring.js +413 -20
- package/dist/mapResourceAuthoring.js.map +1 -1
- package/dist/mosaic.d.ts +1 -1
- package/dist/mosaic.d.ts.map +1 -1
- package/dist/mosaic.js.map +1 -1
- package/dist/prepare/geoarrow.js.map +1 -1
- package/dist/prepare/prepareDeckDataset.d.ts.map +1 -1
- package/dist/prepare/prepareDeckDataset.js +1 -0
- package/dist/prepare/prepareDeckDataset.js.map +1 -1
- package/dist/prepare/types.d.ts +3 -0
- package/dist/prepare/types.d.ts.map +1 -1
- package/dist/prepare/types.js.map +1 -1
- package/dist/prepare/wkbDecoder.d.ts +10 -0
- package/dist/prepare/wkbDecoder.d.ts.map +1 -1
- package/dist/prepare/wkbDecoder.js +141 -20
- package/dist/prepare/wkbDecoder.js.map +1 -1
- package/dist/prepare/wkbParser.d.ts +9 -0
- package/dist/prepare/wkbParser.d.ts.map +1 -1
- package/dist/prepare/wkbParser.js +22 -0
- package/dist/prepare/wkbParser.js.map +1 -1
- package/dist/selectStarAsWkbCollision.d.ts +3 -0
- package/dist/selectStarAsWkbCollision.d.ts.map +1 -0
- package/dist/selectStarAsWkbCollision.js +78 -0
- package/dist/selectStarAsWkbCollision.js.map +1 -0
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/useDeckMapFitToBounds.d.ts.map +1 -1
- package/dist/useDeckMapFitToBounds.js +1 -1
- package/dist/useDeckMapFitToBounds.js.map +1 -1
- 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 rest = {...l};\n delete rest.colorRange;\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"]}
|
package/dist/block.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ export type DeckMapBlockRendererProps = {
|
|
|
15
15
|
headerActions?: ReactNode;
|
|
16
16
|
dataAdapter?: DeckMapDataAdapter;
|
|
17
17
|
};
|
|
18
|
-
/** Mosaic-free
|
|
18
|
+
/** Mosaic-free document map renderer backed only by `deckMaps`. */
|
|
19
19
|
export declare function DeckMapBlockRenderer({ mapId, title, caption, onCaptionChange, selected, readOnly, headerActions, dataAdapter, }: DeckMapBlockRendererProps): import("react/jsx-runtime").JSX.Element;
|
|
20
20
|
export {};
|
|
21
21
|
//# sourceMappingURL=block.d.ts.map
|
package/dist/block.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block.d.ts","sourceRoot":"","sources":["../src/block.tsx"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,kBAAkB,CAAC;AAI1B,OAAO,EAML,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,EAGL,KAAK,kBAAkB,EACxB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAC,KAAK,kBAAkB,EAAuB,MAAM,iBAAiB,CAAC;AAQ9E,KAAK,oBAAoB,GAAG,kBAAkB,GAAG,gBAAgB,CAAC;AAmDlE,kFAAkF;AAClF,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,oBAAoB,EAC3B,KAAK,EAAE,MAAM,EACb,KAAK,CAAC,EAAE,MAAM,QAoBf;AAED,MAAM,MAAM,yBAAyB,GAAG;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IACxD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,aAAa,CAAC,EAAE,SAAS,CAAC;IAC1B,WAAW,CAAC,EAAE,kBAAkB,CAAC;CAClC,CAAC;AAEF,
|
|
1
|
+
{"version":3,"file":"block.d.ts","sourceRoot":"","sources":["../src/block.tsx"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,kBAAkB,CAAC;AAI1B,OAAO,EAML,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,EAGL,KAAK,kBAAkB,EACxB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAC,KAAK,kBAAkB,EAAuB,MAAM,iBAAiB,CAAC;AAQ9E,KAAK,oBAAoB,GAAG,kBAAkB,GAAG,gBAAgB,CAAC;AAmDlE,kFAAkF;AAClF,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,oBAAoB,EAC3B,KAAK,EAAE,MAAM,EACb,KAAK,CAAC,EAAE,MAAM,QAoBf;AAED,MAAM,MAAM,yBAAyB,GAAG;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IACxD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,aAAa,CAAC,EAAE,SAAS,CAAC;IAC1B,WAAW,CAAC,EAAE,kBAAkB,CAAC;CAClC,CAAC;AAEF,mEAAmE;AACnE,wBAAgB,oBAAoB,CAAC,EACnC,KAAK,EACL,KAAK,EACL,OAAO,EACP,eAAe,EACf,QAAQ,EACR,QAAQ,EACR,aAAa,EACb,WAAsC,GACvC,EAAE,yBAAyB,2CA6K3B"}
|
package/dist/block.js
CHANGED
|
@@ -50,7 +50,7 @@ export function ensureDeckMapResourceState(state, mapId, title) {
|
|
|
50
50
|
if (table)
|
|
51
51
|
state.deckMaps.setSelectedTable(mapId, getTableIdentity(table.table));
|
|
52
52
|
}
|
|
53
|
-
/** Mosaic-free
|
|
53
|
+
/** Mosaic-free document map renderer backed only by `deckMaps`. */
|
|
54
54
|
export function DeckMapBlockRenderer({ mapId, title, caption, onCaptionChange, selected, readOnly, headerActions, dataAdapter = directDeckMapDataAdapter, }) {
|
|
55
55
|
const map = useStoreWithDeckMaps((state) => state.deckMaps.config.mapsById[mapId]);
|
|
56
56
|
const tables = useStoreWithDeckMaps((state) => state.db.tables);
|
package/dist/block.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block.js","sourceRoot":"","sources":["../src/block.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n getTableIdentity,\n type DataTable,\n type DuckDbSliceState,\n} from '@sqlrooms/duckdb';\nimport {useBlockSettingsStore} from '@sqlrooms/documents';\nimport {Button, Tooltip, TooltipContent, TooltipTrigger} from '@sqlrooms/ui';\nimport {FocusIcon, MapIcon, SlidersVerticalIcon} from 'lucide-react';\nimport {\n Component,\n useCallback,\n useEffect,\n useState,\n type ErrorInfo,\n type ReactNode,\n} from 'react';\nimport {\n DeckMapSurface,\n directDeckMapDataAdapter,\n type DeckMapDataAdapter,\n} from './DeckMapSurface';\nimport {type DeckMapsSliceState, useStoreWithDeckMaps} from './DeckMapsSlice';\nimport {createEmptyDeckMapConfig} from './mapConfig';\nimport {\n createDeckMapConfigForTable,\n findGeometryColumn,\n findLongitudeLatitudeColumns,\n} from './mapConfigUtils';\n\ntype DeckMapResourceState = DeckMapsSliceState & DuckDbSliceState;\n\ntype DeckMapResourceErrorBoundaryProps = {\n children: ReactNode;\n onError: (error: Error) => void;\n resetKey: unknown;\n};\n\ntype DeckMapResourceErrorBoundaryState = {\n error?: Error;\n resetKey: unknown;\n};\n\nclass DeckMapResourceErrorBoundary extends Component<\n DeckMapResourceErrorBoundaryProps,\n DeckMapResourceErrorBoundaryState\n> {\n state: DeckMapResourceErrorBoundaryState = {\n resetKey: this.props.resetKey,\n };\n static getDerivedStateFromError(error: Error) {\n return {error};\n }\n static getDerivedStateFromProps(\n props: DeckMapResourceErrorBoundaryProps,\n state: DeckMapResourceErrorBoundaryState,\n ) {\n return Object.is(props.resetKey, state.resetKey)\n ? null\n : {error: undefined, resetKey: props.resetKey};\n }\n componentDidCatch(error: Error, errorInfo: ErrorInfo) {\n console.error(\n '[DeckMapResourceErrorBoundary] Map render failed',\n error,\n errorInfo,\n );\n this.props.onError(error);\n }\n render() {\n if (this.state.error) {\n return (\n <div className=\"text-muted-foreground flex h-full min-h-[320px] items-center justify-center p-4 text-center text-sm\">\n Map failed to render: {this.state.error.message}\n </div>\n );\n }\n return this.props.children;\n }\n}\n\n/** Ensures a first-class map resource, optionally seeded from geospatial data. */\nexport function ensureDeckMapResourceState(\n state: DeckMapResourceState,\n mapId: string,\n title?: string,\n) {\n if (state.deckMaps.getMap(mapId)) return;\n const table = state.db.tables.find(\n (candidate) =>\n Boolean(findLongitudeLatitudeColumns(candidate)) ||\n Boolean(findGeometryColumn(candidate)),\n );\n state.deckMaps.ensureMap(mapId, {\n title: title ?? 'Map',\n config: table\n ? createDeckMapConfigForTable({\n tableName: table.tableName,\n columns: table.columns,\n tableReference: table.table,\n })\n : createEmptyDeckMapConfig(),\n });\n if (table)\n state.deckMaps.setSelectedTable(mapId, getTableIdentity(table.table));\n}\n\nexport type DeckMapBlockRendererProps = {\n mapId: string;\n title?: string;\n caption?: string;\n onCaptionChange?: (caption: string | undefined) => void;\n selected?: boolean;\n readOnly?: boolean;\n headerActions?: ReactNode;\n dataAdapter?: DeckMapDataAdapter;\n};\n\n/** Mosaic-free worksheet map renderer backed only by `deckMaps`. */\nexport function DeckMapBlockRenderer({\n mapId,\n title,\n caption,\n onCaptionChange,\n selected,\n readOnly,\n headerActions,\n dataAdapter = directDeckMapDataAdapter,\n}: DeckMapBlockRendererProps) {\n const map = useStoreWithDeckMaps(\n (state) => state.deckMaps.config.mapsById[mapId],\n );\n const tables = useStoreWithDeckMaps((state) => state.db.tables);\n const ensureMap = useStoreWithDeckMaps((state) => state.deckMaps.ensureMap);\n const updateMap = useStoreWithDeckMaps((state) => state.deckMaps.updateMap);\n const setSelectedTable = useStoreWithDeckMaps(\n (state) => state.deckMaps.setSelectedTable,\n );\n const reportMapIssue = useStoreWithDeckMaps(\n (state) => state.deckMaps.reportMapIssue,\n );\n const clearMapIssue = useStoreWithDeckMaps(\n (state) => state.deckMaps.clearMapIssue,\n );\n const requestOpenSettingsPanel = useBlockSettingsStore(\n (state) => state.blockSettings.requestOpenSettingsPanel,\n );\n const requestCloseSettingsPanel = useBlockSettingsStore(\n (state) => state.blockSettings.requestCloseSettingsPanel,\n );\n const isSettingsPanelOpen = useBlockSettingsStore(\n (state) => state.blockSettings.runtime.isSettingsPanelOpen,\n );\n const isSettingsShown = Boolean(selected && isSettingsPanelOpen);\n const [fitRequestVersion, setFitRequestVersion] = useState(0);\n\n useEffect(() => {\n if (mapId && !map) ensureMap(mapId, {title: title ?? 'Embedded Map'});\n }, [ensureMap, map, mapId, title]);\n\n const handleTableChange = useCallback(\n (table: DataTable) => {\n setSelectedTable(mapId, getTableIdentity(table.table));\n const hasGeo =\n Boolean(findLongitudeLatitudeColumns(table)) ||\n Boolean(findGeometryColumn(table));\n updateMap(mapId, {\n config: hasGeo\n ? createDeckMapConfigForTable({\n tableName: table.tableName,\n columns: table.columns,\n tableReference: table.table,\n })\n : createEmptyDeckMapConfig(),\n });\n },\n [mapId, setSelectedTable, updateMap],\n );\n\n if (!map) {\n return (\n <div className=\"text-muted-foreground flex h-full min-h-[320px] items-center justify-center\">\n Preparing map...\n </div>\n );\n }\n const hasDatasets = Object.keys(map.config.datasets).length > 0;\n const canFitView = Boolean(map.config.fitToData && hasDatasets);\n const fitViewLabel = canFitView\n ? 'Fit map view to data'\n : 'Fit view unavailable for this map';\n return (\n <div className=\"flex h-full min-h-0 flex-col\">\n <div className=\"border-border flex shrink-0 items-center justify-between gap-2 border-b px-3 py-2\">\n <div className=\"flex min-w-0 flex-1 items-center gap-2\">\n <MapIcon className=\"h-4 w-4 shrink-0\" />\n <input\n className=\"min-w-0 flex-1 bg-transparent text-sm outline-none\"\n value={caption ?? map.title}\n readOnly={readOnly}\n placeholder={map.selectedTable ?? title ?? 'Map caption'}\n onChange={(event) =>\n onCaptionChange?.(event.target.value || undefined)\n }\n />\n </div>\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 type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-6 w-6\"\n aria-label={fitViewLabel}\n disabled={!canFitView}\n onClick={() => setFitRequestVersion((version) => version + 1)}\n >\n <FocusIcon className=\"h-3.5 w-3.5\" />\n </Button>\n </span>\n </TooltipTrigger>\n <TooltipContent>{fitViewLabel}</TooltipContent>\n </Tooltip>\n <Button\n type=\"button\"\n variant={isSettingsShown ? 'secondary' : 'ghost'}\n size=\"icon\"\n className=\"h-6 w-6\"\n aria-label={\n isSettingsShown ? 'Close map settings' : 'Open map settings'\n }\n onClick={() =>\n isSettingsShown\n ? requestCloseSettingsPanel()\n : requestOpenSettingsPanel()\n }\n >\n <SlidersVerticalIcon className=\"h-3.5 w-3.5\" />\n </Button>\n {headerActions}\n </div>\n </div>\n <div className=\"min-h-0 flex-1\">\n {hasDatasets ? (\n <DeckMapResourceErrorBoundary\n resetKey={map.config}\n onError={(error) =>\n reportMapIssue(mapId, {\n kind: 'render-error',\n message: error.message,\n recoverable: true,\n })\n }\n >\n <DeckMapSurface\n mapId={mapId}\n map={map}\n readOnly={readOnly}\n selected={selected}\n onUpdateMap={(patch) => updateMap(mapId, patch)}\n onReportIssue={(issue) => reportMapIssue(mapId, issue)}\n onClearIssue={(kind) => clearMapIssue(mapId, kind)}\n fitRequestVersion={fitRequestVersion}\n dataAdapter={dataAdapter}\n />\n </DeckMapResourceErrorBoundary>\n ) : (\n <div className=\"flex h-full min-h-[320px] items-center justify-center p-4\">\n <select\n className=\"border-border bg-background rounded border px-3 py-2 text-sm\"\n value={map.selectedTable ?? ''}\n disabled={readOnly}\n onChange={(event) => {\n const table = tables.find(\n (candidate) =>\n getTableIdentity(candidate.table) === event.target.value,\n );\n if (table) handleTableChange(table);\n }}\n >\n <option value=\"\">Select a table</option>\n {tables.map((table) => (\n <option\n key={getTableIdentity(table.table)}\n value={getTableIdentity(table.table)}\n >\n {table.tableName}\n </option>\n ))}\n </select>\n </div>\n )}\n </div>\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"block.js","sourceRoot":"","sources":["../src/block.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n getTableIdentity,\n type DataTable,\n type DuckDbSliceState,\n} from '@sqlrooms/duckdb';\nimport {useBlockSettingsStore} from '@sqlrooms/documents';\nimport {Button, Tooltip, TooltipContent, TooltipTrigger} from '@sqlrooms/ui';\nimport {FocusIcon, MapIcon, SlidersVerticalIcon} from 'lucide-react';\nimport {\n Component,\n useCallback,\n useEffect,\n useState,\n type ErrorInfo,\n type ReactNode,\n} from 'react';\nimport {\n DeckMapSurface,\n directDeckMapDataAdapter,\n type DeckMapDataAdapter,\n} from './DeckMapSurface';\nimport {type DeckMapsSliceState, useStoreWithDeckMaps} from './DeckMapsSlice';\nimport {createEmptyDeckMapConfig} from './mapConfig';\nimport {\n createDeckMapConfigForTable,\n findGeometryColumn,\n findLongitudeLatitudeColumns,\n} from './mapConfigUtils';\n\ntype DeckMapResourceState = DeckMapsSliceState & DuckDbSliceState;\n\ntype DeckMapResourceErrorBoundaryProps = {\n children: ReactNode;\n onError: (error: Error) => void;\n resetKey: unknown;\n};\n\ntype DeckMapResourceErrorBoundaryState = {\n error?: Error;\n resetKey: unknown;\n};\n\nclass DeckMapResourceErrorBoundary extends Component<\n DeckMapResourceErrorBoundaryProps,\n DeckMapResourceErrorBoundaryState\n> {\n state: DeckMapResourceErrorBoundaryState = {\n resetKey: this.props.resetKey,\n };\n static getDerivedStateFromError(error: Error) {\n return {error};\n }\n static getDerivedStateFromProps(\n props: DeckMapResourceErrorBoundaryProps,\n state: DeckMapResourceErrorBoundaryState,\n ) {\n return Object.is(props.resetKey, state.resetKey)\n ? null\n : {error: undefined, resetKey: props.resetKey};\n }\n componentDidCatch(error: Error, errorInfo: ErrorInfo) {\n console.error(\n '[DeckMapResourceErrorBoundary] Map render failed',\n error,\n errorInfo,\n );\n this.props.onError(error);\n }\n render() {\n if (this.state.error) {\n return (\n <div className=\"text-muted-foreground flex h-full min-h-[320px] items-center justify-center p-4 text-center text-sm\">\n Map failed to render: {this.state.error.message}\n </div>\n );\n }\n return this.props.children;\n }\n}\n\n/** Ensures a first-class map resource, optionally seeded from geospatial data. */\nexport function ensureDeckMapResourceState(\n state: DeckMapResourceState,\n mapId: string,\n title?: string,\n) {\n if (state.deckMaps.getMap(mapId)) return;\n const table = state.db.tables.find(\n (candidate) =>\n Boolean(findLongitudeLatitudeColumns(candidate)) ||\n Boolean(findGeometryColumn(candidate)),\n );\n state.deckMaps.ensureMap(mapId, {\n title: title ?? 'Map',\n config: table\n ? createDeckMapConfigForTable({\n tableName: table.tableName,\n columns: table.columns,\n tableReference: table.table,\n })\n : createEmptyDeckMapConfig(),\n });\n if (table)\n state.deckMaps.setSelectedTable(mapId, getTableIdentity(table.table));\n}\n\nexport type DeckMapBlockRendererProps = {\n mapId: string;\n title?: string;\n caption?: string;\n onCaptionChange?: (caption: string | undefined) => void;\n selected?: boolean;\n readOnly?: boolean;\n headerActions?: ReactNode;\n dataAdapter?: DeckMapDataAdapter;\n};\n\n/** Mosaic-free document map renderer backed only by `deckMaps`. */\nexport function DeckMapBlockRenderer({\n mapId,\n title,\n caption,\n onCaptionChange,\n selected,\n readOnly,\n headerActions,\n dataAdapter = directDeckMapDataAdapter,\n}: DeckMapBlockRendererProps) {\n const map = useStoreWithDeckMaps(\n (state) => state.deckMaps.config.mapsById[mapId],\n );\n const tables = useStoreWithDeckMaps((state) => state.db.tables);\n const ensureMap = useStoreWithDeckMaps((state) => state.deckMaps.ensureMap);\n const updateMap = useStoreWithDeckMaps((state) => state.deckMaps.updateMap);\n const setSelectedTable = useStoreWithDeckMaps(\n (state) => state.deckMaps.setSelectedTable,\n );\n const reportMapIssue = useStoreWithDeckMaps(\n (state) => state.deckMaps.reportMapIssue,\n );\n const clearMapIssue = useStoreWithDeckMaps(\n (state) => state.deckMaps.clearMapIssue,\n );\n const requestOpenSettingsPanel = useBlockSettingsStore(\n (state) => state.blockSettings.requestOpenSettingsPanel,\n );\n const requestCloseSettingsPanel = useBlockSettingsStore(\n (state) => state.blockSettings.requestCloseSettingsPanel,\n );\n const isSettingsPanelOpen = useBlockSettingsStore(\n (state) => state.blockSettings.runtime.isSettingsPanelOpen,\n );\n const isSettingsShown = Boolean(selected && isSettingsPanelOpen);\n const [fitRequestVersion, setFitRequestVersion] = useState(0);\n\n useEffect(() => {\n if (mapId && !map) ensureMap(mapId, {title: title ?? 'Embedded Map'});\n }, [ensureMap, map, mapId, title]);\n\n const handleTableChange = useCallback(\n (table: DataTable) => {\n setSelectedTable(mapId, getTableIdentity(table.table));\n const hasGeo =\n Boolean(findLongitudeLatitudeColumns(table)) ||\n Boolean(findGeometryColumn(table));\n updateMap(mapId, {\n config: hasGeo\n ? createDeckMapConfigForTable({\n tableName: table.tableName,\n columns: table.columns,\n tableReference: table.table,\n })\n : createEmptyDeckMapConfig(),\n });\n },\n [mapId, setSelectedTable, updateMap],\n );\n\n if (!map) {\n return (\n <div className=\"text-muted-foreground flex h-full min-h-[320px] items-center justify-center\">\n Preparing map...\n </div>\n );\n }\n const hasDatasets = Object.keys(map.config.datasets).length > 0;\n const canFitView = Boolean(map.config.fitToData && hasDatasets);\n const fitViewLabel = canFitView\n ? 'Fit map view to data'\n : 'Fit view unavailable for this map';\n return (\n <div className=\"flex h-full min-h-0 flex-col\">\n <div className=\"border-border flex shrink-0 items-center justify-between gap-2 border-b px-3 py-2\">\n <div className=\"flex min-w-0 flex-1 items-center gap-2\">\n <MapIcon className=\"h-4 w-4 shrink-0\" />\n <input\n className=\"min-w-0 flex-1 bg-transparent text-sm outline-none\"\n value={caption ?? map.title}\n readOnly={readOnly}\n placeholder={map.selectedTable ?? title ?? 'Map caption'}\n onChange={(event) =>\n onCaptionChange?.(event.target.value || undefined)\n }\n />\n </div>\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 type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-6 w-6\"\n aria-label={fitViewLabel}\n disabled={!canFitView}\n onClick={() => setFitRequestVersion((version) => version + 1)}\n >\n <FocusIcon className=\"h-3.5 w-3.5\" />\n </Button>\n </span>\n </TooltipTrigger>\n <TooltipContent>{fitViewLabel}</TooltipContent>\n </Tooltip>\n <Button\n type=\"button\"\n variant={isSettingsShown ? 'secondary' : 'ghost'}\n size=\"icon\"\n className=\"h-6 w-6\"\n aria-label={\n isSettingsShown ? 'Close map settings' : 'Open map settings'\n }\n onClick={() =>\n isSettingsShown\n ? requestCloseSettingsPanel()\n : requestOpenSettingsPanel()\n }\n >\n <SlidersVerticalIcon className=\"h-3.5 w-3.5\" />\n </Button>\n {headerActions}\n </div>\n </div>\n <div className=\"min-h-0 flex-1\">\n {hasDatasets ? (\n <DeckMapResourceErrorBoundary\n resetKey={map.config}\n onError={(error) =>\n reportMapIssue(mapId, {\n kind: 'render-error',\n message: error.message,\n recoverable: true,\n })\n }\n >\n <DeckMapSurface\n mapId={mapId}\n map={map}\n readOnly={readOnly}\n selected={selected}\n onUpdateMap={(patch) => updateMap(mapId, patch)}\n onReportIssue={(issue) => reportMapIssue(mapId, issue)}\n onClearIssue={(kind) => clearMapIssue(mapId, kind)}\n fitRequestVersion={fitRequestVersion}\n dataAdapter={dataAdapter}\n />\n </DeckMapResourceErrorBoundary>\n ) : (\n <div className=\"flex h-full min-h-[320px] items-center justify-center p-4\">\n <select\n className=\"border-border bg-background rounded border px-3 py-2 text-sm\"\n value={map.selectedTable ?? ''}\n disabled={readOnly}\n onChange={(event) => {\n const table = tables.find(\n (candidate) =>\n getTableIdentity(candidate.table) === event.target.value,\n );\n if (table) handleTableChange(table);\n }}\n >\n <option value=\"\">Select a table</option>\n {tables.map((table) => (\n <option\n key={getTableIdentity(table.table)}\n value={getTableIdentity(table.table)}\n >\n {table.tableName}\n </option>\n ))}\n </select>\n </div>\n )}\n </div>\n </div>\n );\n}\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { DeckMapResource } from './DeckMapsSlice';
|
|
2
|
-
import type
|
|
2
|
+
import { type DeckMapConfig } from './mapConfig';
|
|
3
|
+
import { type DeckMapConfigColumn, type DeckMapPointBinding } from './mapConfigUtils';
|
|
3
4
|
/**
|
|
4
5
|
* Host callbacks used to coordinate a durable Deck map resource with its block
|
|
5
6
|
* document container, table registry, and optional config preparation.
|
|
@@ -39,6 +40,7 @@ export type CreateOrUpdateDeckMapResourceHost = {
|
|
|
39
40
|
}) => void | Promise<void>;
|
|
40
41
|
findTable: (tableName: string) => {
|
|
41
42
|
tableIdentity: string;
|
|
43
|
+
columns: readonly DeckMapConfigColumn[];
|
|
42
44
|
} | undefined;
|
|
43
45
|
prepareConfig?: (options: {
|
|
44
46
|
config: DeckMapConfig;
|
|
@@ -52,6 +54,8 @@ export type CreateOrUpdateDeckMapResourceHost = {
|
|
|
52
54
|
export type CreateOrUpdateDeckMapResourceParams = {
|
|
53
55
|
blockDocumentId: string;
|
|
54
56
|
config: DeckMapConfig;
|
|
57
|
+
/** Generates canonical point geometry from structured lon/lat provenance. */
|
|
58
|
+
pointBinding?: DeckMapPointBinding;
|
|
55
59
|
mapId?: string;
|
|
56
60
|
tableName?: string;
|
|
57
61
|
title?: string;
|
|
@@ -76,6 +80,6 @@ export type CreateOrUpdateDeckMapResourceResult = {
|
|
|
76
80
|
message: string;
|
|
77
81
|
created: boolean;
|
|
78
82
|
};
|
|
79
|
-
/** Resource-native
|
|
83
|
+
/** Resource-native document map orchestration with metadata-after-map-write ordering. */
|
|
80
84
|
export declare function createOrUpdateDeckMapResource(host: CreateOrUpdateDeckMapResourceHost, params: CreateOrUpdateDeckMapResourceParams): Promise<CreateOrUpdateDeckMapResourceResult>;
|
|
81
85
|
//# sourceMappingURL=createOrUpdateDeckMapResource.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createOrUpdateDeckMapResource.d.ts","sourceRoot":"","sources":["../src/createOrUpdateDeckMapResource.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"createOrUpdateDeckMapResource.d.ts","sourceRoot":"","sources":["../src/createOrUpdateDeckMapResource.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,32 @@
|
|
|
1
|
+
import { createDeckTableDatasetSql } from './datasets/tableDatasetSql';
|
|
2
|
+
import { isDeckMapTableDatasetSource } from './mapConfig';
|
|
1
3
|
import { getFirstDatasetSourceTableName, hasSqlOnlyDatasetSource, } from './datasetSourceUtils';
|
|
2
4
|
import { assertDeckMapResourceConfig } from './mapResourceAuthoring';
|
|
3
|
-
|
|
5
|
+
import { applyDeckMapPointBinding, } from './mapConfigUtils';
|
|
6
|
+
function resolveTableDatasetSources(host, config) {
|
|
7
|
+
let changed = false;
|
|
8
|
+
const datasets = Object.fromEntries(Object.entries(config.datasets).map(([datasetId, dataset]) => {
|
|
9
|
+
const source = dataset.source;
|
|
10
|
+
if (!isDeckMapTableDatasetSource(source))
|
|
11
|
+
return [datasetId, dataset];
|
|
12
|
+
const table = host.findTable(source.tableName);
|
|
13
|
+
if (!table) {
|
|
14
|
+
throw new Error(`Dataset "${datasetId}" table "${source.tableName}" was not found.`);
|
|
15
|
+
}
|
|
16
|
+
const canonicalSource = {
|
|
17
|
+
...source,
|
|
18
|
+
tableName: table.tableIdentity,
|
|
19
|
+
};
|
|
20
|
+
createDeckTableDatasetSql(canonicalSource);
|
|
21
|
+
if (canonicalSource.tableName === source.tableName) {
|
|
22
|
+
return [datasetId, dataset];
|
|
23
|
+
}
|
|
24
|
+
changed = true;
|
|
25
|
+
return [datasetId, { ...dataset, source: canonicalSource }];
|
|
26
|
+
}));
|
|
27
|
+
return changed ? { ...config, datasets } : config;
|
|
28
|
+
}
|
|
29
|
+
/** Resource-native document map orchestration with metadata-after-map-write ordering. */
|
|
4
30
|
export async function createOrUpdateDeckMapResource(host, params) {
|
|
5
31
|
const artifactLabel = params.artifactLabel ?? 'block document';
|
|
6
32
|
host.ensureBlockDocument(params.blockDocumentId);
|
|
@@ -25,8 +51,27 @@ export async function createOrUpdateDeckMapResource(host, params) {
|
|
|
25
51
|
replaceDatasets: params.replaceDatasets,
|
|
26
52
|
})
|
|
27
53
|
: params.config;
|
|
28
|
-
|
|
29
|
-
|
|
54
|
+
const pointBindingDataset = params.pointBinding
|
|
55
|
+
? preparedConfig.datasets[params.pointBinding.dataset.trim()]
|
|
56
|
+
: undefined;
|
|
57
|
+
const pointBindingTable = isDeckMapTableDatasetSource(pointBindingDataset?.source)
|
|
58
|
+
? host.findTable(pointBindingDataset.source.tableName)
|
|
59
|
+
: undefined;
|
|
60
|
+
if (params.pointBinding &&
|
|
61
|
+
isDeckMapTableDatasetSource(pointBindingDataset?.source) &&
|
|
62
|
+
!pointBindingTable) {
|
|
63
|
+
throw new Error(`Dataset "${params.pointBinding.dataset.trim()}" table "${pointBindingDataset.source.tableName}" was not found.`);
|
|
64
|
+
}
|
|
65
|
+
const pointBoundConfig = params.pointBinding
|
|
66
|
+
? applyDeckMapPointBinding({
|
|
67
|
+
config: preparedConfig,
|
|
68
|
+
pointBinding: params.pointBinding,
|
|
69
|
+
sourceColumns: pointBindingTable?.columns ?? [],
|
|
70
|
+
})
|
|
71
|
+
: preparedConfig;
|
|
72
|
+
const resolvedConfig = resolveTableDatasetSources(host, pointBoundConfig);
|
|
73
|
+
assertDeckMapResourceConfig(resolvedConfig);
|
|
74
|
+
const tableName = requestedTable ?? getFirstDatasetSourceTableName(resolvedConfig);
|
|
30
75
|
if ((params.requireTableNameForSqlOnlyUpdate ?? true) &&
|
|
31
76
|
existingBlock &&
|
|
32
77
|
!tableName &&
|
|
@@ -36,6 +81,14 @@ export async function createOrUpdateDeckMapResource(host, params) {
|
|
|
36
81
|
const table = tableName ? host.findTable(tableName) : undefined;
|
|
37
82
|
if (tableName && !table)
|
|
38
83
|
throw new Error(`Table "${tableName}" was not found.`);
|
|
84
|
+
const tableDatasetCount = Object.values(resolvedConfig.datasets).filter((dataset) => isDeckMapTableDatasetSource(dataset.source)).length;
|
|
85
|
+
if (params.pointBinding &&
|
|
86
|
+
tableDatasetCount === 1 &&
|
|
87
|
+
pointBindingTable &&
|
|
88
|
+
table &&
|
|
89
|
+
pointBindingTable.tableIdentity !== table.tableIdentity) {
|
|
90
|
+
throw new Error(`Point binding dataset "${params.pointBinding.dataset.trim()}" resolves to table "${pointBindingTable.tableIdentity}", but selected table "${table.tableIdentity}" would override it.`);
|
|
91
|
+
}
|
|
39
92
|
const caption = params.caption?.trim() ||
|
|
40
93
|
params.title?.trim() ||
|
|
41
94
|
existingBlock?.caption?.trim() ||
|
|
@@ -56,7 +109,7 @@ export async function createOrUpdateDeckMapResource(host, params) {
|
|
|
56
109
|
await host.writeMap({
|
|
57
110
|
mapId: block.mapId,
|
|
58
111
|
title,
|
|
59
|
-
config:
|
|
112
|
+
config: resolvedConfig,
|
|
60
113
|
selectedTable: table?.tableIdentity,
|
|
61
114
|
});
|
|
62
115
|
if (existingBlock) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createOrUpdateDeckMapResource.js","sourceRoot":"","sources":["../src/createOrUpdateDeckMapResource.ts"],"names":[],"mappings":"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","sourcesContent":["import type {DeckMapResource} from './DeckMapsSlice';\nimport type {DeckMapConfig} from './mapConfig';\nimport {\n getFirstDatasetSourceTableName,\n hasSqlOnlyDatasetSource,\n} from './datasetSourceUtils';\nimport {assertDeckMapResourceConfig} from './mapResourceAuthoring';\n\n/**\n * Host callbacks used to coordinate a durable Deck map resource with its block\n * document container, table registry, and optional config preparation.\n */\nexport type CreateOrUpdateDeckMapResourceHost = {\n ensureBlockDocument: (blockDocumentId: string) => void;\n findMapBlock: (\n blockDocumentId: string,\n mapId: string,\n ) => {blockId: string; mapId: string; caption?: string} | undefined;\n findMap: (mapId: string) => DeckMapResource | undefined;\n createMapBlock: (options: {\n blockDocumentId: string;\n mapId: string;\n title: string;\n caption?: string;\n intent?: string;\n height?: number;\n }) => Promise<{blockId: string; mapId: string}>;\n updateBlockMetadata: (options: {\n blockDocumentId: string;\n blockId: string;\n caption?: string;\n intent?: string;\n height?: number;\n }) => void | Promise<void>;\n ensureMap: (mapId: string, title: string) => void;\n writeMap: (options: {\n mapId: string;\n title: string;\n config: DeckMapConfig;\n selectedTable?: string;\n }) => void | Promise<void>;\n findTable: (tableName: string) => {tableIdentity: string} | undefined;\n prepareConfig?: (options: {\n config: DeckMapConfig;\n existingMapConfig?: DeckMapConfig;\n tableName?: string;\n replaceLayers?: boolean;\n replaceDatasets?: boolean;\n }) => DeckMapConfig | Promise<DeckMapConfig>;\n};\n\n/** Input for creating or updating a Deck map resource and its owning block. */\nexport type CreateOrUpdateDeckMapResourceParams = {\n blockDocumentId: string;\n config: DeckMapConfig;\n mapId?: string;\n tableName?: string;\n title?: string;\n caption?: string;\n intent?: string;\n height?: number;\n /** Treat `config.spec.layers` as the complete replacement layer list. */\n replaceLayers?: boolean;\n /** Treat `config.datasets` as the complete replacement dataset registry. */\n replaceDatasets?: boolean;\n requireTableNameForSqlOnlyUpdate?: boolean;\n artifactLabel?: string;\n createMapId?: () => string;\n missingMapBlockBehavior?: 'throw' | 'create';\n};\n\n/** Result identities and resolved table selection from a map resource write. */\nexport type CreateOrUpdateDeckMapResourceResult = {\n blockDocumentId: string;\n blockId: string;\n mapId: string;\n selectedTable?: string;\n message: string;\n created: boolean;\n};\n\n/** Resource-native worksheet map orchestration with metadata-after-map-write ordering. */\nexport async function createOrUpdateDeckMapResource(\n host: CreateOrUpdateDeckMapResourceHost,\n params: CreateOrUpdateDeckMapResourceParams,\n): Promise<CreateOrUpdateDeckMapResourceResult> {\n const artifactLabel = params.artifactLabel ?? 'block document';\n host.ensureBlockDocument(params.blockDocumentId);\n const existingBlock = params.mapId\n ? host.findMapBlock(params.blockDocumentId, params.mapId)\n : undefined;\n const missingBehavior = params.missingMapBlockBehavior ?? 'throw';\n if (params.mapId && !existingBlock && missingBehavior === 'throw') {\n throw new Error(\n `${artifactLabel} map block ${params.mapId} was not found in ${params.blockDocumentId}`,\n );\n }\n const mapId = existingBlock?.mapId ?? params.mapId ?? params.createMapId?.();\n if (!mapId) throw new Error('mapId is required when creating a map block');\n\n const existingMap = host.findMap(mapId);\n const requestedTable =\n params.tableName ?? getFirstDatasetSourceTableName(params.config);\n const preparedConfig = host.prepareConfig\n ? await host.prepareConfig({\n config: params.config,\n existingMapConfig: existingMap?.config,\n tableName: requestedTable,\n replaceLayers: params.replaceLayers,\n replaceDatasets: params.replaceDatasets,\n })\n : params.config;\n assertDeckMapResourceConfig(preparedConfig);\n const tableName =\n requestedTable ?? getFirstDatasetSourceTableName(preparedConfig);\n if (\n (params.requireTableNameForSqlOnlyUpdate ?? true) &&\n existingBlock &&\n !tableName &&\n hasSqlOnlyDatasetSource(params.config)\n ) {\n throw new Error(\n `tableName is required when updating a ${artifactLabel} map block with SQL-only dataset sources.`,\n );\n }\n const table = tableName ? host.findTable(tableName) : undefined;\n if (tableName && !table)\n throw new Error(`Table \"${tableName}\" was not found.`);\n\n const caption =\n params.caption?.trim() ||\n params.title?.trim() ||\n existingBlock?.caption?.trim() ||\n existingMap?.title?.trim() ||\n 'Map';\n const title = params.title?.trim() || caption;\n const created = !existingBlock;\n const block =\n existingBlock ??\n (await host.createMapBlock({\n blockDocumentId: params.blockDocumentId,\n mapId,\n title,\n caption,\n intent: params.intent,\n height: params.height,\n }));\n host.ensureMap(block.mapId, title);\n await host.writeMap({\n mapId: block.mapId,\n title,\n config: preparedConfig,\n selectedTable: table?.tableIdentity,\n });\n if (existingBlock) {\n await host.updateBlockMetadata({\n blockDocumentId: params.blockDocumentId,\n blockId: block.blockId,\n caption,\n intent: params.intent,\n height: params.height,\n });\n }\n return {\n blockDocumentId: params.blockDocumentId,\n blockId: block.blockId,\n mapId: block.mapId,\n selectedTable: table?.tableIdentity,\n created,\n message: created\n ? `Added ${artifactLabel} map block \"${title}\".`\n : `Updated ${artifactLabel} map block \"${title}\".`,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"createOrUpdateDeckMapResource.js","sourceRoot":"","sources":["../src/createOrUpdateDeckMapResource.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,yBAAyB,EAAC,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAC,2BAA2B,EAAqB,MAAM,aAAa,CAAC;AAC5E,OAAO,EACL,8BAA8B,EAC9B,uBAAuB,GACxB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAC,2BAA2B,EAAC,MAAM,wBAAwB,CAAC;AACnE,OAAO,EACL,wBAAwB,GAGzB,MAAM,kBAAkB,CAAC;AAiF1B,SAAS,0BAA0B,CACjC,IAA0D,EAC1D,MAAqB;IAErB,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,CACjC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE;QAC3D,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC9B,IAAI,CAAC,2BAA2B,CAAC,MAAM,CAAC;YAAE,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAEtE,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC/C,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CACb,YAAY,SAAS,YAAY,MAAM,CAAC,SAAS,kBAAkB,CACpE,CAAC;QACJ,CAAC;QACD,MAAM,eAAe,GAAG;YACtB,GAAG,MAAM;YACT,SAAS,EAAE,KAAK,CAAC,aAAa;SAC/B,CAAC;QACF,yBAAyB,CAAC,eAAe,CAAC,CAAC;QAC3C,IAAI,eAAe,CAAC,SAAS,KAAK,MAAM,CAAC,SAAS,EAAE,CAAC;YACnD,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAC9B,CAAC;QACD,OAAO,GAAG,IAAI,CAAC;QACf,OAAO,CAAC,SAAS,EAAE,EAAC,GAAG,OAAO,EAAE,MAAM,EAAE,eAAe,EAAC,CAAC,CAAC;IAC5D,CAAC,CAAC,CACH,CAAC;IACF,OAAO,OAAO,CAAC,CAAC,CAAC,EAAC,GAAG,MAAM,EAAE,QAAQ,EAAC,CAAC,CAAC,CAAC,MAAM,CAAC;AAClD,CAAC;AAED,yFAAyF;AACzF,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,IAAuC,EACvC,MAA2C;IAE3C,MAAM,aAAa,GAAG,MAAM,CAAC,aAAa,IAAI,gBAAgB,CAAC;IAC/D,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;IACjD,MAAM,aAAa,GAAG,MAAM,CAAC,KAAK;QAChC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,KAAK,CAAC;QACzD,CAAC,CAAC,SAAS,CAAC;IACd,MAAM,eAAe,GAAG,MAAM,CAAC,uBAAuB,IAAI,OAAO,CAAC;IAClE,IAAI,MAAM,CAAC,KAAK,IAAI,CAAC,aAAa,IAAI,eAAe,KAAK,OAAO,EAAE,CAAC;QAClE,MAAM,IAAI,KAAK,CACb,GAAG,aAAa,cAAc,MAAM,CAAC,KAAK,qBAAqB,MAAM,CAAC,eAAe,EAAE,CACxF,CAAC;IACJ,CAAC;IACD,MAAM,KAAK,GAAG,aAAa,EAAE,KAAK,IAAI,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC;IAC7E,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IAE3E,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,cAAc,GAClB,MAAM,CAAC,SAAS,IAAI,8BAA8B,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACpE,MAAM,cAAc,GAAG,IAAI,CAAC,aAAa;QACvC,CAAC,CAAC,MAAM,IAAI,CAAC,aAAa,CAAC;YACvB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,iBAAiB,EAAE,WAAW,EAAE,MAAM;YACtC,SAAS,EAAE,cAAc;YACzB,aAAa,EAAE,MAAM,CAAC,aAAa;YACnC,eAAe,EAAE,MAAM,CAAC,eAAe;SACxC,CAAC;QACJ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;IAClB,MAAM,mBAAmB,GAAG,MAAM,CAAC,YAAY;QAC7C,CAAC,CAAC,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAC7D,CAAC,CAAC,SAAS,CAAC;IACd,MAAM,iBAAiB,GAAG,2BAA2B,CACnD,mBAAmB,EAAE,MAAM,CAC5B;QACC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC,MAAM,CAAC,SAAS,CAAC;QACtD,CAAC,CAAC,SAAS,CAAC;IACd,IACE,MAAM,CAAC,YAAY;QACnB,2BAA2B,CAAC,mBAAmB,EAAE,MAAM,CAAC;QACxD,CAAC,iBAAiB,EAClB,CAAC;QACD,MAAM,IAAI,KAAK,CACb,YAAY,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,YAAY,mBAAmB,CAAC,MAAM,CAAC,SAAS,kBAAkB,CACjH,CAAC;IACJ,CAAC;IACD,MAAM,gBAAgB,GAAG,MAAM,CAAC,YAAY;QAC1C,CAAC,CAAC,wBAAwB,CAAC;YACvB,MAAM,EAAE,cAAc;YACtB,YAAY,EAAE,MAAM,CAAC,YAAY;YACjC,aAAa,EAAE,iBAAiB,EAAE,OAAO,IAAI,EAAE;SAChD,CAAC;QACJ,CAAC,CAAC,cAAc,CAAC;IACnB,MAAM,cAAc,GAAG,0BAA0B,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;IAC1E,2BAA2B,CAAC,cAAc,CAAC,CAAC;IAC5C,MAAM,SAAS,GACb,cAAc,IAAI,8BAA8B,CAAC,cAAc,CAAC,CAAC;IACnE,IACE,CAAC,MAAM,CAAC,gCAAgC,IAAI,IAAI,CAAC;QACjD,aAAa;QACb,CAAC,SAAS;QACV,uBAAuB,CAAC,MAAM,CAAC,MAAM,CAAC,EACtC,CAAC;QACD,MAAM,IAAI,KAAK,CACb,yCAAyC,aAAa,2CAA2C,CAClG,CAAC;IACJ,CAAC;IACD,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAChE,IAAI,SAAS,IAAI,CAAC,KAAK;QACrB,MAAM,IAAI,KAAK,CAAC,UAAU,SAAS,kBAAkB,CAAC,CAAC;IACzD,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,MAAM,CACrE,CAAC,OAAO,EAAE,EAAE,CAAC,2BAA2B,CAAC,OAAO,CAAC,MAAM,CAAC,CACzD,CAAC,MAAM,CAAC;IACT,IACE,MAAM,CAAC,YAAY;QACnB,iBAAiB,KAAK,CAAC;QACvB,iBAAiB;QACjB,KAAK;QACL,iBAAiB,CAAC,aAAa,KAAK,KAAK,CAAC,aAAa,EACvD,CAAC;QACD,MAAM,IAAI,KAAK,CACb,0BAA0B,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,wBAAwB,iBAAiB,CAAC,aAAa,0BAA0B,KAAK,CAAC,aAAa,sBAAsB,CACvL,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GACX,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE;QACtB,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE;QACpB,aAAa,EAAE,OAAO,EAAE,IAAI,EAAE;QAC9B,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE;QAC1B,KAAK,CAAC;IACR,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,OAAO,CAAC;IAC9C,MAAM,OAAO,GAAG,CAAC,aAAa,CAAC;IAC/B,MAAM,KAAK,GACT,aAAa;QACb,CAAC,MAAM,IAAI,CAAC,cAAc,CAAC;YACzB,eAAe,EAAE,MAAM,CAAC,eAAe;YACvC,KAAK;YACL,KAAK;YACL,OAAO;YACP,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,MAAM,EAAE,MAAM,CAAC,MAAM;SACtB,CAAC,CAAC,CAAC;IACN,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACnC,MAAM,IAAI,CAAC,QAAQ,CAAC;QAClB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,KAAK;QACL,MAAM,EAAE,cAAc;QACtB,aAAa,EAAE,KAAK,EAAE,aAAa;KACpC,CAAC,CAAC;IACH,IAAI,aAAa,EAAE,CAAC;QAClB,MAAM,IAAI,CAAC,mBAAmB,CAAC;YAC7B,eAAe,EAAE,MAAM,CAAC,eAAe;YACvC,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,OAAO;YACP,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,MAAM,EAAE,MAAM,CAAC,MAAM;SACtB,CAAC,CAAC;IACL,CAAC;IACD,OAAO;QACL,eAAe,EAAE,MAAM,CAAC,eAAe;QACvC,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,aAAa,EAAE,KAAK,EAAE,aAAa;QACnC,OAAO;QACP,OAAO,EAAE,OAAO;YACd,CAAC,CAAC,SAAS,aAAa,eAAe,KAAK,IAAI;YAChD,CAAC,CAAC,WAAW,aAAa,eAAe,KAAK,IAAI;KACrD,CAAC;AACJ,CAAC","sourcesContent":["import type {DeckMapResource} from './DeckMapsSlice';\nimport {createDeckTableDatasetSql} from './datasets/tableDatasetSql';\nimport {isDeckMapTableDatasetSource, type DeckMapConfig} from './mapConfig';\nimport {\n getFirstDatasetSourceTableName,\n hasSqlOnlyDatasetSource,\n} from './datasetSourceUtils';\nimport {assertDeckMapResourceConfig} from './mapResourceAuthoring';\nimport {\n applyDeckMapPointBinding,\n type DeckMapConfigColumn,\n type DeckMapPointBinding,\n} from './mapConfigUtils';\n\n/**\n * Host callbacks used to coordinate a durable Deck map resource with its block\n * document container, table registry, and optional config preparation.\n */\nexport type CreateOrUpdateDeckMapResourceHost = {\n ensureBlockDocument: (blockDocumentId: string) => void;\n findMapBlock: (\n blockDocumentId: string,\n mapId: string,\n ) => {blockId: string; mapId: string; caption?: string} | undefined;\n findMap: (mapId: string) => DeckMapResource | undefined;\n createMapBlock: (options: {\n blockDocumentId: string;\n mapId: string;\n title: string;\n caption?: string;\n intent?: string;\n height?: number;\n }) => Promise<{blockId: string; mapId: string}>;\n updateBlockMetadata: (options: {\n blockDocumentId: string;\n blockId: string;\n caption?: string;\n intent?: string;\n height?: number;\n }) => void | Promise<void>;\n ensureMap: (mapId: string, title: string) => void;\n writeMap: (options: {\n mapId: string;\n title: string;\n config: DeckMapConfig;\n selectedTable?: string;\n }) => void | Promise<void>;\n findTable: (\n tableName: string,\n ) =>\n | {tableIdentity: string; columns: readonly DeckMapConfigColumn[]}\n | undefined;\n prepareConfig?: (options: {\n config: DeckMapConfig;\n existingMapConfig?: DeckMapConfig;\n tableName?: string;\n replaceLayers?: boolean;\n replaceDatasets?: boolean;\n }) => DeckMapConfig | Promise<DeckMapConfig>;\n};\n\n/** Input for creating or updating a Deck map resource and its owning block. */\nexport type CreateOrUpdateDeckMapResourceParams = {\n blockDocumentId: string;\n config: DeckMapConfig;\n /** Generates canonical point geometry from structured lon/lat provenance. */\n pointBinding?: DeckMapPointBinding;\n mapId?: string;\n tableName?: string;\n title?: string;\n caption?: string;\n intent?: string;\n height?: number;\n /** Treat `config.spec.layers` as the complete replacement layer list. */\n replaceLayers?: boolean;\n /** Treat `config.datasets` as the complete replacement dataset registry. */\n replaceDatasets?: boolean;\n requireTableNameForSqlOnlyUpdate?: boolean;\n artifactLabel?: string;\n createMapId?: () => string;\n missingMapBlockBehavior?: 'throw' | 'create';\n};\n\n/** Result identities and resolved table selection from a map resource write. */\nexport type CreateOrUpdateDeckMapResourceResult = {\n blockDocumentId: string;\n blockId: string;\n mapId: string;\n selectedTable?: string;\n message: string;\n created: boolean;\n};\n\nfunction resolveTableDatasetSources(\n host: Pick<CreateOrUpdateDeckMapResourceHost, 'findTable'>,\n config: DeckMapConfig,\n): DeckMapConfig {\n let changed = false;\n const datasets = Object.fromEntries(\n Object.entries(config.datasets).map(([datasetId, dataset]) => {\n const source = dataset.source;\n if (!isDeckMapTableDatasetSource(source)) return [datasetId, dataset];\n\n const table = host.findTable(source.tableName);\n if (!table) {\n throw new Error(\n `Dataset \"${datasetId}\" table \"${source.tableName}\" was not found.`,\n );\n }\n const canonicalSource = {\n ...source,\n tableName: table.tableIdentity,\n };\n createDeckTableDatasetSql(canonicalSource);\n if (canonicalSource.tableName === source.tableName) {\n return [datasetId, dataset];\n }\n changed = true;\n return [datasetId, {...dataset, source: canonicalSource}];\n }),\n );\n return changed ? {...config, datasets} : config;\n}\n\n/** Resource-native document map orchestration with metadata-after-map-write ordering. */\nexport async function createOrUpdateDeckMapResource(\n host: CreateOrUpdateDeckMapResourceHost,\n params: CreateOrUpdateDeckMapResourceParams,\n): Promise<CreateOrUpdateDeckMapResourceResult> {\n const artifactLabel = params.artifactLabel ?? 'block document';\n host.ensureBlockDocument(params.blockDocumentId);\n const existingBlock = params.mapId\n ? host.findMapBlock(params.blockDocumentId, params.mapId)\n : undefined;\n const missingBehavior = params.missingMapBlockBehavior ?? 'throw';\n if (params.mapId && !existingBlock && missingBehavior === 'throw') {\n throw new Error(\n `${artifactLabel} map block ${params.mapId} was not found in ${params.blockDocumentId}`,\n );\n }\n const mapId = existingBlock?.mapId ?? params.mapId ?? params.createMapId?.();\n if (!mapId) throw new Error('mapId is required when creating a map block');\n\n const existingMap = host.findMap(mapId);\n const requestedTable =\n params.tableName ?? getFirstDatasetSourceTableName(params.config);\n const preparedConfig = host.prepareConfig\n ? await host.prepareConfig({\n config: params.config,\n existingMapConfig: existingMap?.config,\n tableName: requestedTable,\n replaceLayers: params.replaceLayers,\n replaceDatasets: params.replaceDatasets,\n })\n : params.config;\n const pointBindingDataset = params.pointBinding\n ? preparedConfig.datasets[params.pointBinding.dataset.trim()]\n : undefined;\n const pointBindingTable = isDeckMapTableDatasetSource(\n pointBindingDataset?.source,\n )\n ? host.findTable(pointBindingDataset.source.tableName)\n : undefined;\n if (\n params.pointBinding &&\n isDeckMapTableDatasetSource(pointBindingDataset?.source) &&\n !pointBindingTable\n ) {\n throw new Error(\n `Dataset \"${params.pointBinding.dataset.trim()}\" table \"${pointBindingDataset.source.tableName}\" was not found.`,\n );\n }\n const pointBoundConfig = params.pointBinding\n ? applyDeckMapPointBinding({\n config: preparedConfig,\n pointBinding: params.pointBinding,\n sourceColumns: pointBindingTable?.columns ?? [],\n })\n : preparedConfig;\n const resolvedConfig = resolveTableDatasetSources(host, pointBoundConfig);\n assertDeckMapResourceConfig(resolvedConfig);\n const tableName =\n requestedTable ?? getFirstDatasetSourceTableName(resolvedConfig);\n if (\n (params.requireTableNameForSqlOnlyUpdate ?? true) &&\n existingBlock &&\n !tableName &&\n hasSqlOnlyDatasetSource(params.config)\n ) {\n throw new Error(\n `tableName is required when updating a ${artifactLabel} map block with SQL-only dataset sources.`,\n );\n }\n const table = tableName ? host.findTable(tableName) : undefined;\n if (tableName && !table)\n throw new Error(`Table \"${tableName}\" was not found.`);\n const tableDatasetCount = Object.values(resolvedConfig.datasets).filter(\n (dataset) => isDeckMapTableDatasetSource(dataset.source),\n ).length;\n if (\n params.pointBinding &&\n tableDatasetCount === 1 &&\n pointBindingTable &&\n table &&\n pointBindingTable.tableIdentity !== table.tableIdentity\n ) {\n throw new Error(\n `Point binding dataset \"${params.pointBinding.dataset.trim()}\" resolves to table \"${pointBindingTable.tableIdentity}\", but selected table \"${table.tableIdentity}\" would override it.`,\n );\n }\n\n const caption =\n params.caption?.trim() ||\n params.title?.trim() ||\n existingBlock?.caption?.trim() ||\n existingMap?.title?.trim() ||\n 'Map';\n const title = params.title?.trim() || caption;\n const created = !existingBlock;\n const block =\n existingBlock ??\n (await host.createMapBlock({\n blockDocumentId: params.blockDocumentId,\n mapId,\n title,\n caption,\n intent: params.intent,\n height: params.height,\n }));\n host.ensureMap(block.mapId, title);\n await host.writeMap({\n mapId: block.mapId,\n title,\n config: resolvedConfig,\n selectedTable: table?.tableIdentity,\n });\n if (existingBlock) {\n await host.updateBlockMetadata({\n blockDocumentId: params.blockDocumentId,\n blockId: block.blockId,\n caption,\n intent: params.intent,\n height: params.height,\n });\n }\n return {\n blockDocumentId: params.blockDocumentId,\n blockId: block.blockId,\n mapId: block.mapId,\n selectedTable: table?.tableIdentity,\n created,\n message: created\n ? `Added ${artifactLabel} map block \"${title}\".`\n : `Updated ${artifactLabel} map block \"${title}\".`,\n };\n}\n"]}
|
package/dist/dashboard.d.ts.map
CHANGED
|
@@ -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;
|
|
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
|
-
}, [
|
|
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) {
|