@sqlrooms/deck 0.29.0-rc.12 → 0.29.0-rc.13

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 (55) hide show
  1. package/README.md +144 -22
  2. package/dist/DeckJsonMap.d.ts.map +1 -1
  3. package/dist/DeckJsonMap.js +58 -12
  4. package/dist/DeckJsonMap.js.map +1 -1
  5. package/dist/DeckMapBasemapSelect.d.ts +9 -0
  6. package/dist/DeckMapBasemapSelect.d.ts.map +1 -0
  7. package/dist/DeckMapBasemapSelect.js +20 -0
  8. package/dist/DeckMapBasemapSelect.js.map +1 -0
  9. package/dist/DeckMapDefaultStylesProvider.d.ts +13 -19
  10. package/dist/DeckMapDefaultStylesProvider.d.ts.map +1 -1
  11. package/dist/DeckMapDefaultStylesProvider.js +11 -18
  12. package/dist/DeckMapDefaultStylesProvider.js.map +1 -1
  13. package/dist/DeckMapsSlice.d.ts +5 -0
  14. package/dist/DeckMapsSlice.d.ts.map +1 -1
  15. package/dist/DeckMapsSlice.js +6 -3
  16. package/dist/DeckMapsSlice.js.map +1 -1
  17. package/dist/MapSettings.d.ts.map +1 -1
  18. package/dist/MapSettings.js +3 -2
  19. package/dist/MapSettings.js.map +1 -1
  20. package/dist/ai.d.ts.map +1 -1
  21. package/dist/ai.js +15 -10
  22. package/dist/ai.js.map +1 -1
  23. package/dist/basemap.d.ts +23 -0
  24. package/dist/basemap.d.ts.map +1 -0
  25. package/dist/basemap.js +23 -0
  26. package/dist/basemap.js.map +1 -0
  27. package/dist/block.d.ts.map +1 -1
  28. package/dist/block.js +12 -8
  29. package/dist/block.js.map +1 -1
  30. package/dist/index.d.ts +4 -1
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +4 -1
  33. package/dist/index.js.map +1 -1
  34. package/dist/mapAiSharedInstructions.d.ts.map +1 -1
  35. package/dist/mapAiSharedInstructions.js +1 -0
  36. package/dist/mapAiSharedInstructions.js.map +1 -1
  37. package/dist/mapConfig.d.ts +5 -0
  38. package/dist/mapConfig.d.ts.map +1 -1
  39. package/dist/mapConfig.js +28 -3
  40. package/dist/mapConfig.js.map +1 -1
  41. package/dist/mapConfigUtils.d.ts.map +1 -1
  42. package/dist/mapConfigUtils.js +7 -2
  43. package/dist/mapConfigUtils.js.map +1 -1
  44. package/dist/mapStyles.d.ts +16 -0
  45. package/dist/mapStyles.d.ts.map +1 -0
  46. package/dist/mapStyles.js +32 -0
  47. package/dist/mapStyles.js.map +1 -0
  48. package/dist/protomapsStyles.d.ts +18 -0
  49. package/dist/protomapsStyles.d.ts.map +1 -0
  50. package/dist/protomapsStyles.js +38 -0
  51. package/dist/protomapsStyles.js.map +1 -0
  52. package/dist/types.d.ts +13 -0
  53. package/dist/types.d.ts.map +1 -1
  54. package/dist/types.js.map +1 -1
  55. package/package.json +11 -9
package/dist/ai.js CHANGED
@@ -8,6 +8,7 @@ import { getFirstDatasetSourceTableName, hasSqlOnlyDatasetSource, } from './data
8
8
  import { getDeckMapSharedAiContractRules } from './mapAiSharedInstructions';
9
9
  import { prepareAiDeckMapConfig } from './aiNormalize';
10
10
  import { assertDeckMapResourceConfig } from './mapResourceAuthoring';
11
+ import { asDeckJsonMapConfig, withPreservedDeckMapStyle } from './mapConfig';
11
12
  export { getFirstDatasetSourceTableName, hasSqlOnlyDatasetSource };
12
13
  const COLOR_SCHEME_PROMPT_LISTS = formatColorSchemePromptLists();
13
14
  export const DECK_MAP_AI_INSTRUCTIONS = `
@@ -205,7 +206,9 @@ export const DeckMapDashboardToolParameters = DeckMapConfigToolParameters.extend
205
206
  export { normalizeAiDeckMapConfig, prepareAiDeckMapConfig, validateAndFixColorScaleFields, } from './aiNormalize';
206
207
  function cloneConfig(config, options) {
207
208
  const normalized = prepareAiDeckMapConfig(config, options);
208
- return JSON.parse(JSON.stringify(normalized));
209
+ const cloned = JSON.parse(JSON.stringify(normalized));
210
+ assertDeckMapResourceConfig(cloned);
211
+ return cloned;
209
212
  }
210
213
  /**
211
214
  * Creates a dashboard-compatible Deck map panel from the native map config
@@ -213,7 +216,6 @@ function cloneConfig(config, options) {
213
216
  */
214
217
  export function createDeckMapPanelFromNativeConfig(params, options) {
215
218
  const config = cloneConfig(params.config, options);
216
- assertDeckMapResourceConfig(config);
217
219
  return createDeckMapDashboardPanelConfig({
218
220
  title: params.title || 'Map',
219
221
  ...config,
@@ -280,11 +282,12 @@ Use when: the user asks for a map in a dashboard. Author the map using native De
280
282
  try {
281
283
  // Prepare/validate before mutating dashboard selection so a rejected
282
284
  // config does not switch the active table as a side effect.
283
- const panel = createDeckMapPanelFromNativeConfig(params, {
285
+ const config = cloneConfig(params.config, {
284
286
  resolveTable: (name) => databaseAdapter.findTable(name),
285
287
  stripCatalogNames,
286
288
  });
287
- const tableName = params.tableName ?? getFirstDatasetSourceTableName(panel.config);
289
+ const title = params.title || 'Map';
290
+ const tableName = params.tableName ?? getFirstDatasetSourceTableName(config);
288
291
  if (tableName) {
289
292
  ensureTable(databaseAdapter, tableName);
290
293
  }
@@ -292,24 +295,26 @@ Use when: the user asks for a map in a dashboard. Author the map using native De
292
295
  await dashboardAdapter.setSelectedTable(tableName);
293
296
  }
294
297
  if (params.panelId) {
295
- ensurePanel(dashboardAdapter, params.panelId, DECK_MAP_DASHBOARD_PANEL_TYPE);
298
+ const existingPanel = ensurePanel(dashboardAdapter, params.panelId, DECK_MAP_DASHBOARD_PANEL_TYPE);
299
+ const updatedConfig = withPreservedDeckMapStyle(config, asDeckJsonMapConfig(existingPanel.config));
296
300
  await dashboardAdapter.updatePanel(params.panelId, {
297
- title: panel.title,
298
- config: panel.config,
301
+ title,
302
+ config: updatedConfig,
299
303
  });
300
304
  return {
301
305
  llmResult: {
302
306
  success: true,
303
- details: `Updated map panel "${panel.title}".`,
307
+ details: `Updated map panel "${title}".`,
304
308
  data: {
305
309
  panelId: params.panelId,
306
- title: panel.title,
310
+ title,
307
311
  type: DECK_MAP_DASHBOARD_PANEL_TYPE,
308
- config: panel.config,
312
+ config: updatedConfig,
309
313
  },
310
314
  },
311
315
  };
312
316
  }
317
+ const panel = createDeckMapDashboardPanelConfig({ title, ...config });
313
318
  const panelId = await dashboardAdapter.addPanel(panel);
314
319
  return {
315
320
  llmResult: {
package/dist/ai.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ai.js","sourceRoot":"","sources":["../src/ai.ts"],"names":[],"mappings":"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","sourcesContent":["import {tool, type Tool} from 'ai';\nimport {z} from 'zod';\nimport {formatColorSchemePromptLists} from '@sqlrooms/color-scales/colorSchemeNames';\nimport {\n DashboardAiAdapter,\n MAP_TOOL_KEY,\n createDashboardAgentTool,\n createDashboardAiTools as createMosaicDashboardAiTools,\n type CreateDashboardAgentToolOptions,\n type CreateDashboardAiToolsOptions,\n ensureTable,\n ensurePanel,\n DatabaseAiAdapter,\n ExtraDashboardAiToolsFactory,\n ExtraDashboardAiToolsParams,\n MosaicDashboardStoreState,\n} from '@sqlrooms/mosaic';\nimport {\n createDeckMapDashboardPanelConfig,\n DECK_MAP_DASHBOARD_PANEL_TYPE,\n type DeckMapDashboardPanelConfig,\n} from './dashboardConfig';\nimport {DECK_TABLE_DATASET_SOURCE_RELATION} from './datasets/tableDatasetSql';\nimport {\n getFirstDatasetSourceTableName,\n hasSqlOnlyDatasetSource,\n} from './datasetSourceUtils';\nimport {getDeckMapSharedAiContractRules} from './mapAiSharedInstructions';\nimport {prepareAiDeckMapConfig} from './aiNormalize';\nimport type {PrepareAiDeckMapConfigOptions} from './aiNormalize';\nimport {assertDeckMapResourceConfig} from './mapResourceAuthoring';\nimport type {DeckMapConfig} from './mapConfig';\n\nexport {getFirstDatasetSourceTableName, hasSqlOnlyDatasetSource};\n\nconst COLOR_SCHEME_PROMPT_LISTS = formatColorSchemePromptLists();\n\nexport const DECK_MAP_AI_INSTRUCTIONS = `\nDeck map tools:\n- create_deck_map_config validates and returns a reusable native Deck JSON map config without requiring a dashboard artifact.\n- create_dashboard_map creates or updates an interactive map panel inside a dashboard from a native Deck JSON map config.\n- Use map tools when the user asks for a map, geospatial/spatial visualization, locations, longitude/latitude data, or geometry columns.\n- CONFIG MODE: Every map config must include a configMode field (\"basic\" or \"custom\") that determines how the map was authored and whether the UI settings panel is available.\n - \"basic\" (default): Use for straightforward requests — single layer, standard color scale, simple geometry binding. Stick ONLY to properties that the UI configurator supports: layer @@type, visibility, color scale (@@function colorScale), point radius (numeric getRadius with radiusUnits), line width (numeric getWidth with widthUnits), geometry/H3/arc column bindings, extrusion with a single elevation column (\"@@=columnName\" or {\"@@function\":\"scale\",\"field\":\"...\",\"type\":\"linear\",\"domain\":\"auto\",\"range\":[0,200]}). Do NOT use free-form string expressions (e.g. \"floors * 3\"), custom extensions, multiple layers, or advanced deck.gl props in basic mode. The user can fine-tune these maps through the settings panel.\n - \"custom\": Use when the request demands creative, complex, or advanced visualization — multiple layers, free-form data-driven accessors, custom color arrays, advanced deck.gl props (opacity, transitions, material, highlightColor, etc.), layer extensions, or any props not representable in the UI configurator. The UI settings panel will be disabled for custom configs; users edit via the JSON editor instead.\n - Decision rule: If the map can be fully expressed with a single layer + basic color scale + simple numeric radius/width (+ optional single elevation column), use \"basic\". Extruded GeoArrowColumnLayer / polygon maps with one elevation field must stay \"basic\" so the settings panel remains available. Use \"custom\" only when basic cannot express the request.\n- Author maps with config.spec.layers using Deck JSON layer classes in @@type, such as GeoArrowScatterplotLayer, GeoArrowHeatmapLayer, GeoArrowPolygonLayer, GeoArrowPathLayer, GeoArrowTripsLayer, GeoArrowArcLayer, GeoArrowH3HexagonLayer, or GeoJsonLayer. Always use the full GeoArrow-prefixed class name when choosing a GeoArrow layer (e.g. \"GeoArrowScatterplotLayer\", not \"ScatterplotLayer\") — unprefixed names are not registered. Prefer a typed GeoArrow* layer when the geometry type is known; use GeoJsonLayer for mixed or generic GeoJSON/WKB feature rendering with _sqlroomsBinding.\n${getDeckMapSharedAiContractRules()}\n- LAYER SELECTION: Choose the layer type based on the geometry type in the data.\n IMPORTANT: Only create a layer if the table contains data suitable for that layer type, or if you can transform the data into the required format with transformSql or a standalone sqlQuery. Do NOT create a layer if the data is clearly incompatible (e.g. do not create a path layer from point-only data without aggregation, do not create a polygon layer from point coordinates, do not create an arc layer without origin-destination pairs).\n - Point data (lon/lat coordinates, point geometry): GeoArrowScatterplotLayer (Point layer), GeoArrowHeatmapLayer, GeoArrowColumnLayer. Requires lon/lat columns (via ST_Point transformSql) or a Point geometry column — follow the shared Point-position rules above.\n - Polygon data (building footprints, boundaries, areas, parcels, zones): GeoArrowPolygonLayer for uniform Polygon columns. Use GeoJsonLayer for WKB/WKT MultiPolygon columns so separate polygon parts retain their nesting.\n - Line data (roads, routes, paths, rivers): GeoArrowPathLayer. Requires LineString geometry (or a single-part MultiLineString). Multi-part MultiLineString cannot be rendered as one path — explode/merge with ST_Dump / ST_LineMerge first. If the table has one row per waypoint (path_id/route_id + order/sequence + lat/lon), aggregate with transformSql: \"SELECT path_id, label, ST_AsWKB(ST_MakeLine(LIST(ST_Point(lon, lat) ORDER BY waypoint_order))) AS geom FROM ${DECK_TABLE_DATASET_SOURCE_RELATION} GROUP BY path_id, label\". Set geometryColumn to \"geom\" and geometryEncodingHint to \"wkb\". If linestring geom already exists, use it directly (or SELECT * EXCLUDE (geom), ST_AsWKB(geom) AS geom ... WHERE ST_GeometryType(geom) = 'LINESTRING').\n - Animated trip data (routes with timestamps): GeoArrowTripsLayer (see shared trips-vs-arc rule). One row per trip: LineString geom + timestamps list (same order/length as vertices).\n (1) Waypoint rows (trip_id/path_id + lat/lon + order/time): GROUP BY trip id. Example: \"SELECT trip_id, ANY_VALUE(label) AS label, ST_AsWKB(ST_MakeLine(LIST(ST_Point(lon, lat) ORDER BY waypoint_order))) AS geom, LIST(timestamp ORDER BY waypoint_order) AS timestamps FROM ${DECK_TABLE_DATASET_SOURCE_RELATION} GROUP BY trip_id\". Keep attrs with ANY_VALUE(col). Use ST_MakeLine(LIST(...)) only — never ST_MakeLine(ST_Point(...) ORDER BY ...); always GROUP BY the trip id.\n (2) OD pairs already one row per trip: no GROUP BY — \"SELECT trip_id, ST_AsWKB(ST_MakeLine([ST_Point(pickup_lon, pickup_lat), ST_Point(dropoff_lon, dropoff_lat)])) AS geom, [0.0, 1.0] AS timestamps FROM ${DECK_TABLE_DATASET_SOURCE_RELATION}\" (prefer [0.0, duration] when available).\n In both cases set geometryColumn to \"geom\", geometryEncodingHint to \"wkb\", and _sqlroomsBinding.timestampColumn to \"timestamps\".\n - Arc data (origin-destination pairs): GeoArrowArcLayer for arcs/connections/flows/OD links only (see shared arc-binding rule). Example transformSql: \"SELECT *, ST_AsWKB(ST_Point(source_lon, source_lat)) AS source_geom, ST_AsWKB(ST_Point(target_lon, target_lat)) AS target_geom FROM ${DECK_TABLE_DATASET_SOURCE_RELATION}\". Flat lines: \"getHeight\": 0. For H3 OD pairs use h3_cell_to_lng/lat inside ST_Point (not h3_latlng).\n - H3 hexagon data: GeoArrowH3HexagonLayer (see shared H3 rule). Include fitToData {\"dataset\":\"datasetId\"}. Valid H3 helpers: h3_cell_to_lat/lng/latlng — not h3_latlng/h3_to_lat.\n- CRITICAL geometryColumn rule: The geometryColumn field (in datasets[id].geometryColumn, _sqlroomsBinding.geometryColumn, and fitToData.geometryColumn) MUST match the exact column alias that produces the WKB geometry in the final query output — typically the \"AS geom\" alias in ST_AsWKB(...) AS geom. It must NEVER be set to a GROUP BY key, an ID column, or any other non-geometry column. For example, if the transformSql is \"SELECT path_id, ST_AsWKB(ST_MakeLine(...)) AS geom ... GROUP BY path_id\", geometryColumn must be \"geom\" (the geometry output), NOT \"path_id\" (the grouping key). Setting geometryColumn to a non-geometry column will cause the layer to fail silently.\n- CRITICAL: The transformSql and sqlQuery fields must contain ONLY a single SELECT statement. NEVER put INSTALL, LOAD, CREATE, or other DDL/meta-commands in dataset SQL — they will fail because dataset SQL is wrapped in a subquery at runtime. Extensions like h3 and spatial are pre-loaded at startup.\n - GeoJSON files typically contain polygon or multipolygon features; use polygon layers (or follow shared Point/mixed rules when the user asks for points/mixed rendering).\n- RADIUS AND WIDTH: For GeoArrowScatterplotLayer (Point layer) use numeric getRadius with radiusUnits: \"pixels\" (typically 2–6). Never use string expressions like \"field * 500\" in basic mode — they bypass pixel clamping. Data-driven size: \"@@=columnName\" only in configMode \"custom\", with radiusUnits meters so radiusMaxPixels can cap. For GeoArrowColumnLayer use \"radius\" in meters (not getRadius/radiusUnits), typically 20–200. Always set \"extruded\": true when using getElevation. For Arc/Path/Trips use numeric getWidth with widthUnits: \"pixels\" (typically 1–3).\n- ARC vs LINE: GeoArrowArcLayer renders curved 3D arcs by default. If the user asks for \"lines\" or \"straight connections\" between origin-destination pairs (not arcs), set \"getHeight\": 0 on the layer to render flat straight lines. Use arcs for flight routes or connections where the curve adds clarity; use flat lines for direct relationships, edges, or when the user explicitly requests lines.\n- ELEVATION: For extruded layers set \"extruded\": true. Prefer getElevation {\"@@function\":\"scale\",\"field\":\"...\",\"type\":\"linear\",\"domain\":\"auto\",\"range\":[0,200]} (basic-mode friendly) or \"@@=columnName\". elevationScale multiplies raw field meters — keep max visual height moderate (~hundreds of meters). Do NOT use negative elevation. For polygon building footprints with GeoArrowColumnLayer, transformSql should produce points via the shared centroid rule. CRITICAL: Extruded ColumnLayer / polygon maps need a pitched camera — set spec.initialViewState with pitch around 45–60 (and optional bearing). Top-down pitch 0 makes columns look like flat disks and appear \"missing\".\n- Bind layers to datasets with _sqlroomsBinding.dataset and put tableName, tableName+transformSql, or sqlQuery sources in config.datasets.\n- Use source.tableName for direct table-backed datasets. Use source.tableName plus source.transformSql when the map needs generated geometry or aggregation but should still follow the dashboard selected table. transformSql must read from ${DECK_TABLE_DATASET_SOURCE_RELATION}, not from the authored table name.\n- Use source.sqlQuery only for a standalone literal query that should remain pinned to the authored SQL. Dashboard selected table replacement applies only to structured tableName sources, not literal sqlQuery sources.\n- IMPORTANT: Always pass tableName in the create_dashboard_map tool params (the top-level tableName field). Use the table currently selected in the dashboard (dashboard.selectedTable from list_dashboard_panels). At runtime, the dashboard's selected table overrides structured source.tableName values — this param seeds or changes that selection.\n- IMPORTANT: If you are creating a structured table-backed map layer for a table that is NOT the currently selected dashboard table, you MUST switch the dashboard's selected table to that dataset BEFORE or WHEN calling create_dashboard_map (pass the correct tableName). Structured table-backed map panels resolve data from the dashboard's active table — if you don't switch it, the layer will query the wrong table and fail.\n- IMPORTANT: When referencing tables in tableName or sqlQuery, use ONLY the bare table name (e.g. \"my_table\") or schema-qualified name (e.g. \"main.my_table\"). NEVER include the database/catalog prefix (e.g. do NOT use \"sqlrooms-cli.main.my_table\") — the catalog does not exist in the query execution context.\n- IMPORTANT: For point data with longitude/latitude columns that should follow dashboard table switching, use source.tableName plus source.transformSql to create a geometry column, for example: \"SELECT *, ST_AsWKB(ST_Point(\\\\\"Longitude\\\\\", \\\\\"Latitude\\\\\")) AS \\\\\"__sqlrooms_geom\\\\\" FROM ${DECK_TABLE_DATASET_SOURCE_RELATION} WHERE \\\\\"Longitude\\\\\" IS NOT NULL AND \\\\\"Latitude\\\\\" IS NOT NULL\". Set geometryColumn to the same name used in the AS clause (e.g. \"__sqlrooms_geom\") and geometryEncodingHint to \"wkb\".\n- IMPORTANT: When providing fitToData, it MUST be a flat object (NOT nested by dataset ID). Include either longitudeColumn+latitudeColumn (for point data with separate coordinate columns) OR geometryColumn (for data with a WKB geometry column like GeoJSON). For H3 hexagon layers, just specify the dataset: \"fitToData\": {\"dataset\": \"datasetId\"} — the H3 column is auto-detected from the layer binding. For GeoJSON/spatial files with a \"geom\" column, use: \"fitToData\": {\"dataset\": \"datasetId\", \"geometryColumn\": \"geom\"}. For point data use: \"fitToData\": {\"dataset\": \"datasetId\", \"longitudeColumn\": \"lon\", \"latitudeColumn\": \"lat\"}. NEVER nest fitToData as {\"datasetId\": {...}} — always use a flat object with \"dataset\" as a string field.\n- IMPORTANT: For GeoJSON or spatial files that already have a native geometry column (e.g. \"geometry\", \"geom\"), use the table directly with source.tableName (no sqlQuery needed), set the dataset's geometryColumn to \"geom\", set geometryEncodingHint to \"wkb\", and use fitToData with geometryColumn: {\"dataset\": \"datasetId\", \"geometryColumn\": \"geom\"}.\n- IMPORTANT: When a GeoJSON file (.geojson) is loaded as a table, DuckDB uses ST_Read to produce a table with a WKB \"geom\" column and all feature properties as columns. Use source.tableName, set geometryColumn to \"geom\" and geometryEncodingHint to \"wkb\". Use \"fitToData\": {\"dataset\": \"datasetId\", \"geometryColumn\": \"geom\"} to zoom to the data extent.\n- For data-driven color, use {\"@@function\":\"colorScale\", \"field\":\"...\", \"type\":\"sequential\"|\"diverging\"|\"quantize\"|\"quantile\"|\"categorical\", \"scheme\":\"...\", \"domain\":\"auto\"} on getFillColor / getLineColor / getColor / getSourceColor / getTargetColor. Key is \"@@function\" (not \"@@type\"); column goes in \"field\" (not \"column\"). Exact scheme names: ${COLOR_SCHEME_PROMPT_LISTS}. \"field\" must exist in the FINAL query output after any GROUP BY.\n- COLOR SCALE PREFERENCE: Prefer colorScale over flat fill when a useful varying column exists — numeric → sequential/quantile (quantile if skewed); categorical/string → categorical. A numeric column is useful only when min < max (not all zeros / constant); otherwise use flat fill. If the user explicitly names a column for color, honor that even when flat. Flat fill also when the user asks for one color. \"field\" must be the exact schema column name (case-sensitive; \"Magnitude\" not \"mag\"). IMPORTANT: Viridis/Plasma/Inferno/Turbo/Cividis/Magma require type \"sequential\" (not quantile/quantize). Quantile/quantize schemes must be ColorBrewer ramps such as YlOrRd, Blues, Greens, RdYlBu.\n- IMPORTANT: Enabling a color scale means adding a {\"@@function\":\"colorScale\", ...} accessor to a compatible layer color property. The top-level showLegends field only controls whether already-defined color scale legends are visible; showLegends by itself does NOT create or enable data-driven color.\n- Map panels default to a 100000-row runtime data limit; use config.dataPolicy.maxRows only when the map genuinely needs a panel-specific limit.\n- Create maps with a SINGLE layer unless the user explicitly asks for multiple layers. If you think multiple layers would better serve the user's request, ask the user for confirmation before adding them.\n- IMPORTANT: Browsers limit the number of active WebGL contexts (typically 8–16 per page). Each map panel uses one context. Do NOT create more than 4–5 map panels in a single dashboard — exceeding the limit causes older maps to lose their rendering context and show errors. If the user asks for many datasets, prefer combining compatible layers into fewer maps rather than creating one map per dataset.\n- After calling create_dashboard_map, call list_dashboard_panels before your final response and check the map panel issue. If it has a render-error, repair the map config in place instead of saying the map is complete.\n- IMPORTANT: Dashboard map tools replace the full panel config — always include datasets and layers on updates. Omitting datasets is only valid for document sparse patches that merge with durable state.\n- SWITCHING LAYER TYPE: On type switch/replace, send only the new layer (replaceLayers: true for merge patches; full desired layers list for dashboard updates). Do not leave the old layer as visible: false.\n`;\n\nfunction createDeckMapDashboardExtraTools(\n extraTools?: ExtraDashboardAiToolsFactory,\n prepareOptions?: Pick<PrepareAiDeckMapConfigOptions, 'stripCatalogNames'>,\n) {\n return (params: ExtraDashboardAiToolsParams) => ({\n ...createDeckMapDashboardAiTools({\n ...params,\n stripCatalogNames: prepareOptions?.stripCatalogNames,\n }),\n ...(extraTools?.(params) ?? {}),\n });\n}\n\n/**\n * Returns AI instructions for dashboards with Deck.gl map support.\n * Provides guidance on when and how to use map visualizations.\n *\n * @returns Instructions string for AI agents\n */\nexport function getDashboardWithDeckMapAiInstructions() {\n return `${DECK_MAP_AI_INSTRUCTIONS.trim()}`;\n}\n\n/**\n * Creates dashboard AI tools with built-in Deck.gl map support.\n * Extends standard dashboard tools with map visualization capabilities.\n *\n * @param options - Dashboard AI tools configuration options\n * @returns Record mapping tool names to tool instances, including map tools\n */\nexport type CreateDashboardWithDeckMapAiToolsOptions =\n CreateDashboardAiToolsOptions & {\n /** Host-injected catalogs to strip; omit for none — deck does not hardcode any. */\n stripCatalogNames?: readonly string[];\n };\n\nexport function createDashboardWithDeckMapAiTools(\n options: CreateDashboardWithDeckMapAiToolsOptions,\n): Record<string, Tool> {\n const {stripCatalogNames, extraTools, ...rest} = options;\n return createMosaicDashboardAiTools({\n ...rest,\n extraTools: createDeckMapDashboardExtraTools(extraTools, {\n stripCatalogNames,\n }),\n });\n}\n\n/**\n * Creates a dashboard agent tool with built-in Deck.gl map support.\n * Extends the standard dashboard agent with map creation capabilities.\n *\n * @template TState - Store state type extending MosaicDashboardStoreState\n * @param options - Dashboard agent configuration options\n * @returns Dashboard agent tool with map support\n */\nexport type CreateDashboardAgentToolWithDeckMapsOptions<\n TState extends MosaicDashboardStoreState,\n> = CreateDashboardAgentToolOptions<TState> & {\n stripCatalogNames?: readonly string[];\n};\n\nexport function createDashboardAgentToolWithDeckMaps<\n TState extends MosaicDashboardStoreState,\n>(options: CreateDashboardAgentToolWithDeckMapsOptions<TState>): Tool {\n const {stripCatalogNames, extraTools, ...rest} = options;\n return createDashboardAgentTool({\n ...rest,\n additionalInstructions: [\n options.additionalInstructions,\n DECK_MAP_AI_INSTRUCTIONS.trim(),\n ]\n .filter(Boolean)\n .join('\\n\\n'),\n extraTools: createDeckMapDashboardExtraTools(extraTools, {\n stripCatalogNames,\n }),\n });\n}\n\nconst DeckMapLayerBindingConfig = z.looseObject({\n dataset: z.string().optional(),\n geometryColumn: z.string().optional(),\n geometryEncodingHint: z.enum(['geoarrow', 'wkb', 'wkt']).optional(),\n sourceGeometryColumn: z.string().optional(),\n targetGeometryColumn: z.string().optional(),\n timestampColumn: z.string().optional(),\n hexagonColumn: z.string().optional(),\n});\n\nconst DeckMapLayerSpec = z.looseObject({\n '@@type': z.string().optional(),\n id: z.string().optional(),\n _sqlroomsBinding: DeckMapLayerBindingConfig.optional(),\n});\n\nconst DeckMapSpec = z.looseObject({\n initialViewState: z.record(z.string(), z.unknown()).optional(),\n viewState: z.record(z.string(), z.unknown()).optional(),\n controller: z.unknown().optional(),\n layers: z.array(DeckMapLayerSpec).optional(),\n});\n\nconst DeckMapDatasetSource = z.looseObject({\n tableName: z.string().optional(),\n transformSql: z.string().optional(),\n sqlQuery: z.string().optional(),\n});\n\nconst DeckMapDatasetConfig = z.looseObject({\n source: DeckMapDatasetSource.optional(),\n geometryColumn: z.string().optional(),\n geometryEncodingHint: z.enum(['geoarrow', 'wkb', 'wkt']).optional(),\n});\n\nconst DeckMapDataPolicyConfig = z.looseObject({\n disabled: z.boolean().optional(),\n maxRows: z.number().int().min(1).optional(),\n reason: z.string().optional(),\n});\n\nexport const DeckMapDashboardConfigParameter = z.looseObject({\n spec: DeckMapSpec.describe(\n 'Deck JSON map spec as an object. Use spec.layers[].@@type for layer classes such as GeoArrowScatterplotLayer (Point layer), GeoArrowHeatmapLayer, GeoArrowPolygonLayer, GeoArrowPathLayer, or GeoArrowArcLayer.',\n ),\n datasets: z\n .record(z.string(), DeckMapDatasetConfig)\n .describe(\n 'Datasets keyed by dataset id. Layers bind to these ids through _sqlroomsBinding.dataset. Each dataset source may use tableName, tableName+transformSql, or sqlQuery.',\n ),\n configMode: z\n .enum(['basic', 'custom'])\n .optional()\n .describe(\n 'Config authoring mode. Use \"basic\" (default) for straightforward single-layer maps that the user can tweak via the UI settings panel. Use \"custom\" for complex, multi-layer, or creative maps that use advanced deck.gl props beyond what the UI configurator supports — the settings panel will be disabled for custom configs.',\n ),\n mapStyle: z.string().optional(),\n mapProps: z.record(z.string(), z.unknown()).optional(),\n showLegends: z\n .boolean()\n .optional()\n .describe(\n 'Whether to show color scale legends on the map. Defaults to true; omit or set true unless the user explicitly asks to hide legends.',\n ),\n interaction: z.record(z.string(), z.unknown()).optional(),\n fitToData: z\n .object({\n dataset: z.string().describe('Dataset id to compute bounds from.'),\n longitudeColumn: z\n .string()\n .optional()\n .describe('Longitude column name for point data.'),\n latitudeColumn: z\n .string()\n .optional()\n .describe('Latitude column name for point data.'),\n geometryColumn: z\n .string()\n .optional()\n .describe('WKB geometry column name for computing bounds.'),\n geometryColumns: z\n .array(z.string())\n .optional()\n .describe(\n 'Multiple WKB geometry columns whose extents are combined (e.g. arc source + target). Prefer omitting this — for GeoArrowArcLayer it is inferred from _sqlroomsBinding.',\n ),\n h3Column: z\n .string()\n .optional()\n .describe('H3 hex index column for computing bounds.'),\n padding: z.number().optional(),\n maxZoom: z.number().optional(),\n })\n .optional()\n .describe(\n 'Fit map view to data bounds. Provide dataset plus either geometryColumn (for WKB geometry) or longitudeColumn+latitudeColumn (for separate coordinate columns). For arc layers, just {\"dataset\": \"datasetId\"} is enough — source and target geometry columns are inferred from the layer binding. Example: {\"dataset\": \"myDataset\", \"geometryColumn\": \"geom\"}',\n ),\n dataPolicy: DeckMapDataPolicyConfig.optional().describe(\n 'Optional per-map runtime data policy. Maps default to 100000 rows; set maxRows for a panel-specific override or disabled=true to bypass row-count validation.',\n ),\n settingsOpen: z.boolean().optional(),\n});\n\nexport type DeckMapDashboardConfigToolConfig = z.infer<\n typeof DeckMapDashboardConfigParameter\n>;\n\nexport const DeckMapConfigToolParameters = z.object({\n title: z.string().optional().default('Map').describe('Map title.'),\n config: DeckMapDashboardConfigParameter.describe(\n 'Native Deck JSON dashboard map config. This is the canonical map representation.',\n ),\n reasoning: z\n .string()\n .describe('Brief rationale for creating the map config.'),\n});\n\nexport type DeckMapConfigToolParams = z.infer<\n typeof DeckMapConfigToolParameters\n>;\n\nexport const DeckMapDashboardToolParameters =\n DeckMapConfigToolParameters.extend({\n tableName: z\n .string()\n .optional()\n .describe(\n 'Optional table name used only to select/resolve the target dashboard table. Data sources still come from config.datasets.',\n ),\n panelId: z\n .string()\n .optional()\n .describe(\n 'Optional panel ID. If provided, updates the existing map panel instead of creating a new one.',\n ),\n reasoning: z\n .string()\n .describe('Brief rationale for creating the map panel.'),\n });\n\nexport type DeckMapDashboardToolParams = z.infer<\n typeof DeckMapDashboardToolParameters\n>;\n\nexport {\n normalizeAiDeckMapConfig,\n prepareAiDeckMapConfig,\n validateAndFixColorScaleFields,\n} from './aiNormalize';\n\nfunction cloneConfig(\n config: DeckMapDashboardConfigToolConfig,\n options?: PrepareAiDeckMapConfigOptions,\n): DeckMapDashboardPanelConfig {\n const normalized = prepareAiDeckMapConfig(config, options);\n return JSON.parse(JSON.stringify(normalized)) as DeckMapDashboardPanelConfig;\n}\n\n/**\n * Creates a dashboard-compatible Deck map panel from the native map config\n * used by AI tools and embeddable map surfaces.\n */\nexport function createDeckMapPanelFromNativeConfig(\n params: Pick<DeckMapConfigToolParams, 'title' | 'config'>,\n options?: PrepareAiDeckMapConfigOptions,\n) {\n const config = cloneConfig(params.config, options);\n assertDeckMapResourceConfig(config as DeckMapConfig);\n return createDeckMapDashboardPanelConfig({\n title: params.title || 'Map',\n ...config,\n });\n}\n\nexport function createDeckMapConfigTool(): Tool {\n return tool({\n description: `Deck map config: validates and returns a reusable native Deck JSON map configuration without requiring a dashboard artifact.\n\nUse when: a chat, agent, or artifact outside a dashboard needs a geospatial map config. Author the map using native Deck JSON: put layer classes in spec.layers[].@@type, bind layers to datasets through _sqlroomsBinding.dataset, and put tableName, tableName+transformSql, or sqlQuery sources in config.datasets. For data-driven colors, use color accessors such as getFillColor, getLineColor, getColor, getSourceColor, or getTargetColor with {\"@@function\":\"colorScale\", \"field\":\"...\", \"type\":\"...\", \"scheme\":\"...\", \"domain\":\"auto\"}. For categorical fields use scheme from: Tableau10, Set2, Category10, etc. For numeric fields use sequential schemes like Viridis.`,\n inputSchema: DeckMapConfigToolParameters,\n execute: async (params) => {\n try {\n const panel = createDeckMapPanelFromNativeConfig(params);\n return {\n llmResult: {\n success: true,\n details: `Created deck map config \"${panel.title}\".`,\n data: {\n kind: 'deck-map-config',\n title: panel.title,\n type: DECK_MAP_DASHBOARD_PANEL_TYPE,\n config: panel.config,\n },\n },\n };\n } catch (error) {\n return {\n llmResult: {\n success: false,\n errorMessage:\n error instanceof Error ? error.message : String(error),\n },\n };\n }\n },\n });\n}\n\n/**\n * Creates AI tools for Deck.gl map configuration.\n * Returns tools for creating and configuring Deck.gl map panels.\n *\n * @returns Record mapping tool names to map configuration tools\n */\nexport function createDeckMapAiTools(): Record<string, Tool> {\n return {\n create_deck_map_config: createDeckMapConfigTool(),\n };\n}\n\n/**\n * Parameters for creating a Deck.gl map dashboard tool.\n * Provides adapters for dashboard and database operations.\n */\nexport type CreateDeckMapDashboardToolParams = {\n /** Dashboard adapter for adding and updating map panels */\n dashboardAdapter: DashboardAiAdapter;\n /** Database adapter for table validation */\n databaseAdapter: DatabaseAiAdapter;\n /** Host-injected catalogs to strip; omit for none — deck does not hardcode any. */\n stripCatalogNames?: readonly string[];\n};\n\n/**\n * Creates a tool for adding Deck.gl map panels to dashboards.\n * Supports creating new map panels or updating existing ones with native Deck JSON configs.\n *\n * @param params - Parameters containing dashboard and database adapters\n * @returns Tool instance for creating/updating Deck.gl map panels\n */\nexport function createDeckMapDashboardTool({\n dashboardAdapter,\n databaseAdapter,\n stripCatalogNames,\n}: CreateDeckMapDashboardToolParams): Tool {\n return tool({\n description: `Deck map panel: creates or updates an interactive geospatial map panel in a Mosaic dashboard from a native Deck JSON config.\n\nUse when: the user asks for a map in a dashboard. Author the map using native Deck JSON: choose layer classes with spec.layers[].@@type, bind layers to datasets through _sqlroomsBinding.dataset, and put tableName, tableName+transformSql, or sqlQuery sources in config.datasets. For data-driven colors, use color accessors such as getFillColor, getLineColor, getColor, getSourceColor, or getTargetColor with {\"@@function\":\"colorScale\", \"field\":\"...\", \"type\":\"...\", \"scheme\":\"...\", \"domain\":\"auto\"}. For categorical fields use scheme from: Tableau10, Set2, Category10, etc. For numeric fields use sequential schemes like Viridis.`,\n inputSchema: DeckMapDashboardToolParameters,\n execute: async (params) => {\n try {\n // Prepare/validate before mutating dashboard selection so a rejected\n // config does not switch the active table as a side effect.\n const panel = createDeckMapPanelFromNativeConfig(params, {\n resolveTable: (name) => databaseAdapter.findTable(name),\n stripCatalogNames,\n });\n const tableName =\n params.tableName ?? getFirstDatasetSourceTableName(panel.config);\n\n if (tableName) {\n ensureTable(databaseAdapter, tableName);\n }\n\n if (tableName) {\n await dashboardAdapter.setSelectedTable(tableName);\n }\n if (params.panelId) {\n ensurePanel(\n dashboardAdapter,\n params.panelId,\n DECK_MAP_DASHBOARD_PANEL_TYPE,\n );\n\n await dashboardAdapter.updatePanel(params.panelId, {\n title: panel.title,\n config: panel.config,\n });\n\n return {\n llmResult: {\n success: true,\n details: `Updated map panel \"${panel.title}\".`,\n data: {\n panelId: params.panelId,\n title: panel.title,\n type: DECK_MAP_DASHBOARD_PANEL_TYPE,\n config: panel.config,\n },\n },\n };\n }\n\n const panelId = await dashboardAdapter.addPanel(panel);\n\n return {\n llmResult: {\n success: true,\n details: `Created map panel \"${panel.title}\".`,\n data: {\n panelId,\n title: panel.title,\n type: DECK_MAP_DASHBOARD_PANEL_TYPE,\n config: panel.config,\n },\n },\n };\n } catch (error) {\n return {\n llmResult: {\n success: false,\n errorMessage:\n error instanceof Error ? error.message : String(error),\n },\n };\n }\n },\n });\n}\n\nexport function createDeckMapDashboardAiTools(\n params: CreateDeckMapDashboardToolParams,\n): Record<string, Tool> {\n return {\n [MAP_TOOL_KEY]: createDeckMapDashboardTool(params),\n };\n}\n"]}
1
+ {"version":3,"file":"ai.js","sourceRoot":"","sources":["../src/ai.ts"],"names":[],"mappings":"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","sourcesContent":["import {tool, type Tool} from 'ai';\nimport {z} from 'zod';\nimport {formatColorSchemePromptLists} from '@sqlrooms/color-scales/colorSchemeNames';\nimport {\n DashboardAiAdapter,\n MAP_TOOL_KEY,\n createDashboardAgentTool,\n createDashboardAiTools as createMosaicDashboardAiTools,\n type CreateDashboardAgentToolOptions,\n type CreateDashboardAiToolsOptions,\n ensureTable,\n ensurePanel,\n DatabaseAiAdapter,\n ExtraDashboardAiToolsFactory,\n ExtraDashboardAiToolsParams,\n MosaicDashboardStoreState,\n} from '@sqlrooms/mosaic';\nimport {\n createDeckMapDashboardPanelConfig,\n DECK_MAP_DASHBOARD_PANEL_TYPE,\n type DeckMapDashboardPanelConfig,\n} from './dashboardConfig';\nimport {DECK_TABLE_DATASET_SOURCE_RELATION} from './datasets/tableDatasetSql';\nimport {\n getFirstDatasetSourceTableName,\n hasSqlOnlyDatasetSource,\n} from './datasetSourceUtils';\nimport {getDeckMapSharedAiContractRules} from './mapAiSharedInstructions';\nimport {prepareAiDeckMapConfig} from './aiNormalize';\nimport type {PrepareAiDeckMapConfigOptions} from './aiNormalize';\nimport {assertDeckMapResourceConfig} from './mapResourceAuthoring';\nimport {asDeckJsonMapConfig, withPreservedDeckMapStyle} from './mapConfig';\n\nexport {getFirstDatasetSourceTableName, hasSqlOnlyDatasetSource};\n\nconst COLOR_SCHEME_PROMPT_LISTS = formatColorSchemePromptLists();\n\nexport const DECK_MAP_AI_INSTRUCTIONS = `\nDeck map tools:\n- create_deck_map_config validates and returns a reusable native Deck JSON map config without requiring a dashboard artifact.\n- create_dashboard_map creates or updates an interactive map panel inside a dashboard from a native Deck JSON map config.\n- Use map tools when the user asks for a map, geospatial/spatial visualization, locations, longitude/latitude data, or geometry columns.\n- CONFIG MODE: Every map config must include a configMode field (\"basic\" or \"custom\") that determines how the map was authored and whether the UI settings panel is available.\n - \"basic\" (default): Use for straightforward requests — single layer, standard color scale, simple geometry binding. Stick ONLY to properties that the UI configurator supports: layer @@type, visibility, color scale (@@function colorScale), point radius (numeric getRadius with radiusUnits), line width (numeric getWidth with widthUnits), geometry/H3/arc column bindings, extrusion with a single elevation column (\"@@=columnName\" or {\"@@function\":\"scale\",\"field\":\"...\",\"type\":\"linear\",\"domain\":\"auto\",\"range\":[0,200]}). Do NOT use free-form string expressions (e.g. \"floors * 3\"), custom extensions, multiple layers, or advanced deck.gl props in basic mode. The user can fine-tune these maps through the settings panel.\n - \"custom\": Use when the request demands creative, complex, or advanced visualization — multiple layers, free-form data-driven accessors, custom color arrays, advanced deck.gl props (opacity, transitions, material, highlightColor, etc.), layer extensions, or any props not representable in the UI configurator. The UI settings panel will be disabled for custom configs; users edit via the JSON editor instead.\n - Decision rule: If the map can be fully expressed with a single layer + basic color scale + simple numeric radius/width (+ optional single elevation column), use \"basic\". Extruded GeoArrowColumnLayer / polygon maps with one elevation field must stay \"basic\" so the settings panel remains available. Use \"custom\" only when basic cannot express the request.\n- Author maps with config.spec.layers using Deck JSON layer classes in @@type, such as GeoArrowScatterplotLayer, GeoArrowHeatmapLayer, GeoArrowPolygonLayer, GeoArrowPathLayer, GeoArrowTripsLayer, GeoArrowArcLayer, GeoArrowH3HexagonLayer, or GeoJsonLayer. Always use the full GeoArrow-prefixed class name when choosing a GeoArrow layer (e.g. \"GeoArrowScatterplotLayer\", not \"ScatterplotLayer\") — unprefixed names are not registered. Prefer a typed GeoArrow* layer when the geometry type is known; use GeoJsonLayer for mixed or generic GeoJSON/WKB feature rendering with _sqlroomsBinding.\n${getDeckMapSharedAiContractRules()}\n- LAYER SELECTION: Choose the layer type based on the geometry type in the data.\n IMPORTANT: Only create a layer if the table contains data suitable for that layer type, or if you can transform the data into the required format with transformSql or a standalone sqlQuery. Do NOT create a layer if the data is clearly incompatible (e.g. do not create a path layer from point-only data without aggregation, do not create a polygon layer from point coordinates, do not create an arc layer without origin-destination pairs).\n - Point data (lon/lat coordinates, point geometry): GeoArrowScatterplotLayer (Point layer), GeoArrowHeatmapLayer, GeoArrowColumnLayer. Requires lon/lat columns (via ST_Point transformSql) or a Point geometry column — follow the shared Point-position rules above.\n - Polygon data (building footprints, boundaries, areas, parcels, zones): GeoArrowPolygonLayer for uniform Polygon columns. Use GeoJsonLayer for WKB/WKT MultiPolygon columns so separate polygon parts retain their nesting.\n - Line data (roads, routes, paths, rivers): GeoArrowPathLayer. Requires LineString geometry (or a single-part MultiLineString). Multi-part MultiLineString cannot be rendered as one path — explode/merge with ST_Dump / ST_LineMerge first. If the table has one row per waypoint (path_id/route_id + order/sequence + lat/lon), aggregate with transformSql: \"SELECT path_id, label, ST_AsWKB(ST_MakeLine(LIST(ST_Point(lon, lat) ORDER BY waypoint_order))) AS geom FROM ${DECK_TABLE_DATASET_SOURCE_RELATION} GROUP BY path_id, label\". Set geometryColumn to \"geom\" and geometryEncodingHint to \"wkb\". If linestring geom already exists, use it directly (or SELECT * EXCLUDE (geom), ST_AsWKB(geom) AS geom ... WHERE ST_GeometryType(geom) = 'LINESTRING').\n - Animated trip data (routes with timestamps): GeoArrowTripsLayer (see shared trips-vs-arc rule). One row per trip: LineString geom + timestamps list (same order/length as vertices).\n (1) Waypoint rows (trip_id/path_id + lat/lon + order/time): GROUP BY trip id. Example: \"SELECT trip_id, ANY_VALUE(label) AS label, ST_AsWKB(ST_MakeLine(LIST(ST_Point(lon, lat) ORDER BY waypoint_order))) AS geom, LIST(timestamp ORDER BY waypoint_order) AS timestamps FROM ${DECK_TABLE_DATASET_SOURCE_RELATION} GROUP BY trip_id\". Keep attrs with ANY_VALUE(col). Use ST_MakeLine(LIST(...)) only — never ST_MakeLine(ST_Point(...) ORDER BY ...); always GROUP BY the trip id.\n (2) OD pairs already one row per trip: no GROUP BY — \"SELECT trip_id, ST_AsWKB(ST_MakeLine([ST_Point(pickup_lon, pickup_lat), ST_Point(dropoff_lon, dropoff_lat)])) AS geom, [0.0, 1.0] AS timestamps FROM ${DECK_TABLE_DATASET_SOURCE_RELATION}\" (prefer [0.0, duration] when available).\n In both cases set geometryColumn to \"geom\", geometryEncodingHint to \"wkb\", and _sqlroomsBinding.timestampColumn to \"timestamps\".\n - Arc data (origin-destination pairs): GeoArrowArcLayer for arcs/connections/flows/OD links only (see shared arc-binding rule). Example transformSql: \"SELECT *, ST_AsWKB(ST_Point(source_lon, source_lat)) AS source_geom, ST_AsWKB(ST_Point(target_lon, target_lat)) AS target_geom FROM ${DECK_TABLE_DATASET_SOURCE_RELATION}\". Flat lines: \"getHeight\": 0. For H3 OD pairs use h3_cell_to_lng/lat inside ST_Point (not h3_latlng).\n - H3 hexagon data: GeoArrowH3HexagonLayer (see shared H3 rule). Include fitToData {\"dataset\":\"datasetId\"}. Valid H3 helpers: h3_cell_to_lat/lng/latlng — not h3_latlng/h3_to_lat.\n- CRITICAL geometryColumn rule: The geometryColumn field (in datasets[id].geometryColumn, _sqlroomsBinding.geometryColumn, and fitToData.geometryColumn) MUST match the exact column alias that produces the WKB geometry in the final query output — typically the \"AS geom\" alias in ST_AsWKB(...) AS geom. It must NEVER be set to a GROUP BY key, an ID column, or any other non-geometry column. For example, if the transformSql is \"SELECT path_id, ST_AsWKB(ST_MakeLine(...)) AS geom ... GROUP BY path_id\", geometryColumn must be \"geom\" (the geometry output), NOT \"path_id\" (the grouping key). Setting geometryColumn to a non-geometry column will cause the layer to fail silently.\n- CRITICAL: The transformSql and sqlQuery fields must contain ONLY a single SELECT statement. NEVER put INSTALL, LOAD, CREATE, or other DDL/meta-commands in dataset SQL — they will fail because dataset SQL is wrapped in a subquery at runtime. Extensions like h3 and spatial are pre-loaded at startup.\n - GeoJSON files typically contain polygon or multipolygon features; use polygon layers (or follow shared Point/mixed rules when the user asks for points/mixed rendering).\n- RADIUS AND WIDTH: For GeoArrowScatterplotLayer (Point layer) use numeric getRadius with radiusUnits: \"pixels\" (typically 2–6). Never use string expressions like \"field * 500\" in basic mode — they bypass pixel clamping. Data-driven size: \"@@=columnName\" only in configMode \"custom\", with radiusUnits meters so radiusMaxPixels can cap. For GeoArrowColumnLayer use \"radius\" in meters (not getRadius/radiusUnits), typically 20–200. Always set \"extruded\": true when using getElevation. For Arc/Path/Trips use numeric getWidth with widthUnits: \"pixels\" (typically 1–3).\n- ARC vs LINE: GeoArrowArcLayer renders curved 3D arcs by default. If the user asks for \"lines\" or \"straight connections\" between origin-destination pairs (not arcs), set \"getHeight\": 0 on the layer to render flat straight lines. Use arcs for flight routes or connections where the curve adds clarity; use flat lines for direct relationships, edges, or when the user explicitly requests lines.\n- ELEVATION: For extruded layers set \"extruded\": true. Prefer getElevation {\"@@function\":\"scale\",\"field\":\"...\",\"type\":\"linear\",\"domain\":\"auto\",\"range\":[0,200]} (basic-mode friendly) or \"@@=columnName\". elevationScale multiplies raw field meters — keep max visual height moderate (~hundreds of meters). Do NOT use negative elevation. For polygon building footprints with GeoArrowColumnLayer, transformSql should produce points via the shared centroid rule. CRITICAL: Extruded ColumnLayer / polygon maps need a pitched camera — set spec.initialViewState with pitch around 45–60 (and optional bearing). Top-down pitch 0 makes columns look like flat disks and appear \"missing\".\n- Bind layers to datasets with _sqlroomsBinding.dataset and put tableName, tableName+transformSql, or sqlQuery sources in config.datasets.\n- Use source.tableName for direct table-backed datasets. Use source.tableName plus source.transformSql when the map needs generated geometry or aggregation but should still follow the dashboard selected table. transformSql must read from ${DECK_TABLE_DATASET_SOURCE_RELATION}, not from the authored table name.\n- Use source.sqlQuery only for a standalone literal query that should remain pinned to the authored SQL. Dashboard selected table replacement applies only to structured tableName sources, not literal sqlQuery sources.\n- IMPORTANT: Always pass tableName in the create_dashboard_map tool params (the top-level tableName field). Use the table currently selected in the dashboard (dashboard.selectedTable from list_dashboard_panels). At runtime, the dashboard's selected table overrides structured source.tableName values — this param seeds or changes that selection.\n- IMPORTANT: If you are creating a structured table-backed map layer for a table that is NOT the currently selected dashboard table, you MUST switch the dashboard's selected table to that dataset BEFORE or WHEN calling create_dashboard_map (pass the correct tableName). Structured table-backed map panels resolve data from the dashboard's active table — if you don't switch it, the layer will query the wrong table and fail.\n- IMPORTANT: When referencing tables in tableName or sqlQuery, use ONLY the bare table name (e.g. \"my_table\") or schema-qualified name (e.g. \"main.my_table\"). NEVER include the database/catalog prefix (e.g. do NOT use \"sqlrooms-cli.main.my_table\") — the catalog does not exist in the query execution context.\n- IMPORTANT: For point data with longitude/latitude columns that should follow dashboard table switching, use source.tableName plus source.transformSql to create a geometry column, for example: \"SELECT *, ST_AsWKB(ST_Point(\\\\\"Longitude\\\\\", \\\\\"Latitude\\\\\")) AS \\\\\"__sqlrooms_geom\\\\\" FROM ${DECK_TABLE_DATASET_SOURCE_RELATION} WHERE \\\\\"Longitude\\\\\" IS NOT NULL AND \\\\\"Latitude\\\\\" IS NOT NULL\". Set geometryColumn to the same name used in the AS clause (e.g. \"__sqlrooms_geom\") and geometryEncodingHint to \"wkb\".\n- IMPORTANT: When providing fitToData, it MUST be a flat object (NOT nested by dataset ID). Include either longitudeColumn+latitudeColumn (for point data with separate coordinate columns) OR geometryColumn (for data with a WKB geometry column like GeoJSON). For H3 hexagon layers, just specify the dataset: \"fitToData\": {\"dataset\": \"datasetId\"} — the H3 column is auto-detected from the layer binding. For GeoJSON/spatial files with a \"geom\" column, use: \"fitToData\": {\"dataset\": \"datasetId\", \"geometryColumn\": \"geom\"}. For point data use: \"fitToData\": {\"dataset\": \"datasetId\", \"longitudeColumn\": \"lon\", \"latitudeColumn\": \"lat\"}. NEVER nest fitToData as {\"datasetId\": {...}} — always use a flat object with \"dataset\" as a string field.\n- IMPORTANT: For GeoJSON or spatial files that already have a native geometry column (e.g. \"geometry\", \"geom\"), use the table directly with source.tableName (no sqlQuery needed), set the dataset's geometryColumn to \"geom\", set geometryEncodingHint to \"wkb\", and use fitToData with geometryColumn: {\"dataset\": \"datasetId\", \"geometryColumn\": \"geom\"}.\n- IMPORTANT: When a GeoJSON file (.geojson) is loaded as a table, DuckDB uses ST_Read to produce a table with a WKB \"geom\" column and all feature properties as columns. Use source.tableName, set geometryColumn to \"geom\" and geometryEncodingHint to \"wkb\". Use \"fitToData\": {\"dataset\": \"datasetId\", \"geometryColumn\": \"geom\"} to zoom to the data extent.\n- For data-driven color, use {\"@@function\":\"colorScale\", \"field\":\"...\", \"type\":\"sequential\"|\"diverging\"|\"quantize\"|\"quantile\"|\"categorical\", \"scheme\":\"...\", \"domain\":\"auto\"} on getFillColor / getLineColor / getColor / getSourceColor / getTargetColor. Key is \"@@function\" (not \"@@type\"); column goes in \"field\" (not \"column\"). Exact scheme names: ${COLOR_SCHEME_PROMPT_LISTS}. \"field\" must exist in the FINAL query output after any GROUP BY.\n- COLOR SCALE PREFERENCE: Prefer colorScale over flat fill when a useful varying column exists — numeric → sequential/quantile (quantile if skewed); categorical/string → categorical. A numeric column is useful only when min < max (not all zeros / constant); otherwise use flat fill. If the user explicitly names a column for color, honor that even when flat. Flat fill also when the user asks for one color. \"field\" must be the exact schema column name (case-sensitive; \"Magnitude\" not \"mag\"). IMPORTANT: Viridis/Plasma/Inferno/Turbo/Cividis/Magma require type \"sequential\" (not quantile/quantize). Quantile/quantize schemes must be ColorBrewer ramps such as YlOrRd, Blues, Greens, RdYlBu.\n- IMPORTANT: Enabling a color scale means adding a {\"@@function\":\"colorScale\", ...} accessor to a compatible layer color property. The top-level showLegends field only controls whether already-defined color scale legends are visible; showLegends by itself does NOT create or enable data-driven color.\n- Map panels default to a 100000-row runtime data limit; use config.dataPolicy.maxRows only when the map genuinely needs a panel-specific limit.\n- Create maps with a SINGLE layer unless the user explicitly asks for multiple layers. If you think multiple layers would better serve the user's request, ask the user for confirmation before adding them.\n- IMPORTANT: Browsers limit the number of active WebGL contexts (typically 8–16 per page). Each map panel uses one context. Do NOT create more than 4–5 map panels in a single dashboard — exceeding the limit causes older maps to lose their rendering context and show errors. If the user asks for many datasets, prefer combining compatible layers into fewer maps rather than creating one map per dataset.\n- After calling create_dashboard_map, call list_dashboard_panels before your final response and check the map panel issue. If it has a render-error, repair the map config in place instead of saying the map is complete.\n- IMPORTANT: Dashboard map tools replace the full panel config — always include datasets and layers on updates. Omitting datasets is only valid for document sparse patches that merge with durable state.\n- SWITCHING LAYER TYPE: On type switch/replace, send only the new layer (replaceLayers: true for merge patches; full desired layers list for dashboard updates). Do not leave the old layer as visible: false.\n`;\n\nfunction createDeckMapDashboardExtraTools(\n extraTools?: ExtraDashboardAiToolsFactory,\n prepareOptions?: Pick<PrepareAiDeckMapConfigOptions, 'stripCatalogNames'>,\n) {\n return (params: ExtraDashboardAiToolsParams) => ({\n ...createDeckMapDashboardAiTools({\n ...params,\n stripCatalogNames: prepareOptions?.stripCatalogNames,\n }),\n ...(extraTools?.(params) ?? {}),\n });\n}\n\n/**\n * Returns AI instructions for dashboards with Deck.gl map support.\n * Provides guidance on when and how to use map visualizations.\n *\n * @returns Instructions string for AI agents\n */\nexport function getDashboardWithDeckMapAiInstructions() {\n return `${DECK_MAP_AI_INSTRUCTIONS.trim()}`;\n}\n\n/**\n * Creates dashboard AI tools with built-in Deck.gl map support.\n * Extends standard dashboard tools with map visualization capabilities.\n *\n * @param options - Dashboard AI tools configuration options\n * @returns Record mapping tool names to tool instances, including map tools\n */\nexport type CreateDashboardWithDeckMapAiToolsOptions =\n CreateDashboardAiToolsOptions & {\n /** Host-injected catalogs to strip; omit for none — deck does not hardcode any. */\n stripCatalogNames?: readonly string[];\n };\n\nexport function createDashboardWithDeckMapAiTools(\n options: CreateDashboardWithDeckMapAiToolsOptions,\n): Record<string, Tool> {\n const {stripCatalogNames, extraTools, ...rest} = options;\n return createMosaicDashboardAiTools({\n ...rest,\n extraTools: createDeckMapDashboardExtraTools(extraTools, {\n stripCatalogNames,\n }),\n });\n}\n\n/**\n * Creates a dashboard agent tool with built-in Deck.gl map support.\n * Extends the standard dashboard agent with map creation capabilities.\n *\n * @template TState - Store state type extending MosaicDashboardStoreState\n * @param options - Dashboard agent configuration options\n * @returns Dashboard agent tool with map support\n */\nexport type CreateDashboardAgentToolWithDeckMapsOptions<\n TState extends MosaicDashboardStoreState,\n> = CreateDashboardAgentToolOptions<TState> & {\n stripCatalogNames?: readonly string[];\n};\n\nexport function createDashboardAgentToolWithDeckMaps<\n TState extends MosaicDashboardStoreState,\n>(options: CreateDashboardAgentToolWithDeckMapsOptions<TState>): Tool {\n const {stripCatalogNames, extraTools, ...rest} = options;\n return createDashboardAgentTool({\n ...rest,\n additionalInstructions: [\n options.additionalInstructions,\n DECK_MAP_AI_INSTRUCTIONS.trim(),\n ]\n .filter(Boolean)\n .join('\\n\\n'),\n extraTools: createDeckMapDashboardExtraTools(extraTools, {\n stripCatalogNames,\n }),\n });\n}\n\nconst DeckMapLayerBindingConfig = z.looseObject({\n dataset: z.string().optional(),\n geometryColumn: z.string().optional(),\n geometryEncodingHint: z.enum(['geoarrow', 'wkb', 'wkt']).optional(),\n sourceGeometryColumn: z.string().optional(),\n targetGeometryColumn: z.string().optional(),\n timestampColumn: z.string().optional(),\n hexagonColumn: z.string().optional(),\n});\n\nconst DeckMapLayerSpec = z.looseObject({\n '@@type': z.string().optional(),\n id: z.string().optional(),\n _sqlroomsBinding: DeckMapLayerBindingConfig.optional(),\n});\n\nconst DeckMapSpec = z.looseObject({\n initialViewState: z.record(z.string(), z.unknown()).optional(),\n viewState: z.record(z.string(), z.unknown()).optional(),\n controller: z.unknown().optional(),\n layers: z.array(DeckMapLayerSpec).optional(),\n});\n\nconst DeckMapDatasetSource = z.looseObject({\n tableName: z.string().optional(),\n transformSql: z.string().optional(),\n sqlQuery: z.string().optional(),\n});\n\nconst DeckMapDatasetConfig = z.looseObject({\n source: DeckMapDatasetSource.optional(),\n geometryColumn: z.string().optional(),\n geometryEncodingHint: z.enum(['geoarrow', 'wkb', 'wkt']).optional(),\n});\n\nconst DeckMapDataPolicyConfig = z.looseObject({\n disabled: z.boolean().optional(),\n maxRows: z.number().int().min(1).optional(),\n reason: z.string().optional(),\n});\n\nexport const DeckMapDashboardConfigParameter = z.looseObject({\n spec: DeckMapSpec.describe(\n 'Deck JSON map spec as an object. Use spec.layers[].@@type for layer classes such as GeoArrowScatterplotLayer (Point layer), GeoArrowHeatmapLayer, GeoArrowPolygonLayer, GeoArrowPathLayer, or GeoArrowArcLayer.',\n ),\n datasets: z\n .record(z.string(), DeckMapDatasetConfig)\n .describe(\n 'Datasets keyed by dataset id. Layers bind to these ids through _sqlroomsBinding.dataset. Each dataset source may use tableName, tableName+transformSql, or sqlQuery.',\n ),\n configMode: z\n .enum(['basic', 'custom'])\n .optional()\n .describe(\n 'Config authoring mode. Use \"basic\" (default) for straightforward single-layer maps that the user can tweak via the UI settings panel. Use \"custom\" for complex, multi-layer, or creative maps that use advanced deck.gl props beyond what the UI configurator supports — the settings panel will be disabled for custom configs.',\n ),\n mapStyle: z.string().optional(),\n mapProps: z.record(z.string(), z.unknown()).optional(),\n showLegends: z\n .boolean()\n .optional()\n .describe(\n 'Whether to show color scale legends on the map. Defaults to true; omit or set true unless the user explicitly asks to hide legends.',\n ),\n interaction: z.record(z.string(), z.unknown()).optional(),\n fitToData: z\n .object({\n dataset: z.string().describe('Dataset id to compute bounds from.'),\n longitudeColumn: z\n .string()\n .optional()\n .describe('Longitude column name for point data.'),\n latitudeColumn: z\n .string()\n .optional()\n .describe('Latitude column name for point data.'),\n geometryColumn: z\n .string()\n .optional()\n .describe('WKB geometry column name for computing bounds.'),\n geometryColumns: z\n .array(z.string())\n .optional()\n .describe(\n 'Multiple WKB geometry columns whose extents are combined (e.g. arc source + target). Prefer omitting this — for GeoArrowArcLayer it is inferred from _sqlroomsBinding.',\n ),\n h3Column: z\n .string()\n .optional()\n .describe('H3 hex index column for computing bounds.'),\n padding: z.number().optional(),\n maxZoom: z.number().optional(),\n })\n .optional()\n .describe(\n 'Fit map view to data bounds. Provide dataset plus either geometryColumn (for WKB geometry) or longitudeColumn+latitudeColumn (for separate coordinate columns). For arc layers, just {\"dataset\": \"datasetId\"} is enough — source and target geometry columns are inferred from the layer binding. Example: {\"dataset\": \"myDataset\", \"geometryColumn\": \"geom\"}',\n ),\n dataPolicy: DeckMapDataPolicyConfig.optional().describe(\n 'Optional per-map runtime data policy. Maps default to 100000 rows; set maxRows for a panel-specific override or disabled=true to bypass row-count validation.',\n ),\n settingsOpen: z.boolean().optional(),\n});\n\nexport type DeckMapDashboardConfigToolConfig = z.infer<\n typeof DeckMapDashboardConfigParameter\n>;\n\nexport const DeckMapConfigToolParameters = z.object({\n title: z.string().optional().default('Map').describe('Map title.'),\n config: DeckMapDashboardConfigParameter.describe(\n 'Native Deck JSON dashboard map config. This is the canonical map representation.',\n ),\n reasoning: z\n .string()\n .describe('Brief rationale for creating the map config.'),\n});\n\nexport type DeckMapConfigToolParams = z.infer<\n typeof DeckMapConfigToolParameters\n>;\n\nexport const DeckMapDashboardToolParameters =\n DeckMapConfigToolParameters.extend({\n tableName: z\n .string()\n .optional()\n .describe(\n 'Optional table name used only to select/resolve the target dashboard table. Data sources still come from config.datasets.',\n ),\n panelId: z\n .string()\n .optional()\n .describe(\n 'Optional panel ID. If provided, updates the existing map panel instead of creating a new one.',\n ),\n reasoning: z\n .string()\n .describe('Brief rationale for creating the map panel.'),\n });\n\nexport type DeckMapDashboardToolParams = z.infer<\n typeof DeckMapDashboardToolParameters\n>;\n\nexport {\n normalizeAiDeckMapConfig,\n prepareAiDeckMapConfig,\n validateAndFixColorScaleFields,\n} from './aiNormalize';\n\nfunction cloneConfig(\n config: DeckMapDashboardConfigToolConfig,\n options?: PrepareAiDeckMapConfigOptions,\n): DeckMapDashboardPanelConfig {\n const normalized = prepareAiDeckMapConfig(config, options);\n const cloned = JSON.parse(\n JSON.stringify(normalized),\n ) as DeckMapDashboardPanelConfig;\n assertDeckMapResourceConfig(cloned);\n return cloned;\n}\n\n/**\n * Creates a dashboard-compatible Deck map panel from the native map config\n * used by AI tools and embeddable map surfaces.\n */\nexport function createDeckMapPanelFromNativeConfig(\n params: Pick<DeckMapConfigToolParams, 'title' | 'config'>,\n options?: PrepareAiDeckMapConfigOptions,\n) {\n const config = cloneConfig(params.config, options);\n return createDeckMapDashboardPanelConfig({\n title: params.title || 'Map',\n ...config,\n });\n}\n\nexport function createDeckMapConfigTool(): Tool {\n return tool({\n description: `Deck map config: validates and returns a reusable native Deck JSON map configuration without requiring a dashboard artifact.\n\nUse when: a chat, agent, or artifact outside a dashboard needs a geospatial map config. Author the map using native Deck JSON: put layer classes in spec.layers[].@@type, bind layers to datasets through _sqlroomsBinding.dataset, and put tableName, tableName+transformSql, or sqlQuery sources in config.datasets. For data-driven colors, use color accessors such as getFillColor, getLineColor, getColor, getSourceColor, or getTargetColor with {\"@@function\":\"colorScale\", \"field\":\"...\", \"type\":\"...\", \"scheme\":\"...\", \"domain\":\"auto\"}. For categorical fields use scheme from: Tableau10, Set2, Category10, etc. For numeric fields use sequential schemes like Viridis.`,\n inputSchema: DeckMapConfigToolParameters,\n execute: async (params) => {\n try {\n const panel = createDeckMapPanelFromNativeConfig(params);\n return {\n llmResult: {\n success: true,\n details: `Created deck map config \"${panel.title}\".`,\n data: {\n kind: 'deck-map-config',\n title: panel.title,\n type: DECK_MAP_DASHBOARD_PANEL_TYPE,\n config: panel.config,\n },\n },\n };\n } catch (error) {\n return {\n llmResult: {\n success: false,\n errorMessage:\n error instanceof Error ? error.message : String(error),\n },\n };\n }\n },\n });\n}\n\n/**\n * Creates AI tools for Deck.gl map configuration.\n * Returns tools for creating and configuring Deck.gl map panels.\n *\n * @returns Record mapping tool names to map configuration tools\n */\nexport function createDeckMapAiTools(): Record<string, Tool> {\n return {\n create_deck_map_config: createDeckMapConfigTool(),\n };\n}\n\n/**\n * Parameters for creating a Deck.gl map dashboard tool.\n * Provides adapters for dashboard and database operations.\n */\nexport type CreateDeckMapDashboardToolParams = {\n /** Dashboard adapter for adding and updating map panels */\n dashboardAdapter: DashboardAiAdapter;\n /** Database adapter for table validation */\n databaseAdapter: DatabaseAiAdapter;\n /** Host-injected catalogs to strip; omit for none — deck does not hardcode any. */\n stripCatalogNames?: readonly string[];\n};\n\n/**\n * Creates a tool for adding Deck.gl map panels to dashboards.\n * Supports creating new map panels or updating existing ones with native Deck JSON configs.\n *\n * @param params - Parameters containing dashboard and database adapters\n * @returns Tool instance for creating/updating Deck.gl map panels\n */\nexport function createDeckMapDashboardTool({\n dashboardAdapter,\n databaseAdapter,\n stripCatalogNames,\n}: CreateDeckMapDashboardToolParams): Tool {\n return tool({\n description: `Deck map panel: creates or updates an interactive geospatial map panel in a Mosaic dashboard from a native Deck JSON config.\n\nUse when: the user asks for a map in a dashboard. Author the map using native Deck JSON: choose layer classes with spec.layers[].@@type, bind layers to datasets through _sqlroomsBinding.dataset, and put tableName, tableName+transformSql, or sqlQuery sources in config.datasets. For data-driven colors, use color accessors such as getFillColor, getLineColor, getColor, getSourceColor, or getTargetColor with {\"@@function\":\"colorScale\", \"field\":\"...\", \"type\":\"...\", \"scheme\":\"...\", \"domain\":\"auto\"}. For categorical fields use scheme from: Tableau10, Set2, Category10, etc. For numeric fields use sequential schemes like Viridis.`,\n inputSchema: DeckMapDashboardToolParameters,\n execute: async (params) => {\n try {\n // Prepare/validate before mutating dashboard selection so a rejected\n // config does not switch the active table as a side effect.\n const config = cloneConfig(params.config, {\n resolveTable: (name) => databaseAdapter.findTable(name),\n stripCatalogNames,\n });\n const title = params.title || 'Map';\n const tableName =\n params.tableName ?? getFirstDatasetSourceTableName(config);\n\n if (tableName) {\n ensureTable(databaseAdapter, tableName);\n }\n\n if (tableName) {\n await dashboardAdapter.setSelectedTable(tableName);\n }\n if (params.panelId) {\n const existingPanel = ensurePanel(\n dashboardAdapter,\n params.panelId,\n DECK_MAP_DASHBOARD_PANEL_TYPE,\n );\n const updatedConfig: Record<string, unknown> =\n withPreservedDeckMapStyle(\n config,\n asDeckJsonMapConfig(existingPanel.config),\n );\n\n await dashboardAdapter.updatePanel(params.panelId, {\n title,\n config: updatedConfig,\n });\n\n return {\n llmResult: {\n success: true,\n details: `Updated map panel \"${title}\".`,\n data: {\n panelId: params.panelId,\n title,\n type: DECK_MAP_DASHBOARD_PANEL_TYPE,\n config: updatedConfig,\n },\n },\n };\n }\n\n const panel = createDeckMapDashboardPanelConfig({title, ...config});\n const panelId = await dashboardAdapter.addPanel(panel);\n\n return {\n llmResult: {\n success: true,\n details: `Created map panel \"${panel.title}\".`,\n data: {\n panelId,\n title: panel.title,\n type: DECK_MAP_DASHBOARD_PANEL_TYPE,\n config: panel.config,\n },\n },\n };\n } catch (error) {\n return {\n llmResult: {\n success: false,\n errorMessage:\n error instanceof Error ? error.message : String(error),\n },\n };\n }\n },\n });\n}\n\nexport function createDeckMapDashboardAiTools(\n params: CreateDeckMapDashboardToolParams,\n): Record<string, Tool> {\n return {\n [MAP_TOOL_KEY]: createDeckMapDashboardTool(params),\n };\n}\n"]}
@@ -0,0 +1,23 @@
1
+ import type { ResolvedTheme } from '@sqlrooms/ui';
2
+ import type { MapProps } from 'react-map-gl/maplibre';
3
+ /** A MapLibre-compatible style accepted by the Deck map renderer. */
4
+ export type DeckMapStyle = NonNullable<MapProps['mapStyle']>;
5
+ /** Optional host-provided basemap defaults keyed by resolved UI theme. */
6
+ export type DeckMapDefaultStyles = Partial<Record<ResolvedTheme, DeckMapStyle>>;
7
+ /**
8
+ * Resolves a basemap's light/dark variant. Return stable style objects or URLs,
9
+ * or undefined to use host defaults. Providers and credentials are runtime-only.
10
+ */
11
+ export type DeckMapBasemapProvider = (theme: ResolvedTheme) => DeckMapStyle | undefined;
12
+ /** True for `mapbox://` style URLs (MapLibre cannot load them without a token). */
13
+ export declare function isMapboxStyleUrl(style: unknown): boolean;
14
+ /** Resolves explicit styles, a basemap provider, host defaults, then the fallback. */
15
+ export declare function resolveDeckMapStyle(options: {
16
+ mapStyle?: string;
17
+ mapPropsMapStyle?: MapProps['mapStyle'];
18
+ basemapProvider?: DeckMapBasemapProvider;
19
+ hostDefaultStyles?: DeckMapDefaultStyles;
20
+ resolvedTheme: ResolvedTheme;
21
+ fallbackStyles: Record<ResolvedTheme, DeckMapStyle>;
22
+ }): DeckMapStyle;
23
+ //# sourceMappingURL=basemap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"basemap.d.ts","sourceRoot":"","sources":["../src/basemap.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,uBAAuB,CAAC;AAGpD,qEAAqE;AACrE,MAAM,MAAM,YAAY,GAAG,WAAW,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;AAE7D,0EAA0E;AAC1E,MAAM,MAAM,oBAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC,CAAC;AAEhF;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAAG,CACnC,KAAK,EAAE,aAAa,KACjB,YAAY,GAAG,SAAS,CAAC;AAE9B,mFAAmF;AACnF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAExD;AAOD,sFAAsF;AACtF,wBAAgB,mBAAmB,CAAC,OAAO,EAAE;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;IACxC,eAAe,CAAC,EAAE,sBAAsB,CAAC;IACzC,iBAAiB,CAAC,EAAE,oBAAoB,CAAC;IACzC,aAAa,EAAE,aAAa,CAAC;IAC7B,cAAc,EAAE,MAAM,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;CACrD,GAAG,YAAY,CAYf"}
@@ -0,0 +1,23 @@
1
+ import { getDeckMapStyleTheme } from './mapStyles';
2
+ /** True for `mapbox://` style URLs (MapLibre cannot load them without a token). */
3
+ export function isMapboxStyleUrl(style) {
4
+ return typeof style === 'string' && /^mapbox:/i.test(style.trim());
5
+ }
6
+ function usableMapStyle(style) {
7
+ if (style == null || isMapboxStyleUrl(style))
8
+ return undefined;
9
+ return style;
10
+ }
11
+ /** Resolves explicit styles, a basemap provider, host defaults, then the fallback. */
12
+ export function resolveDeckMapStyle(options) {
13
+ const selectedStyle = usableMapStyle(options.mapStyle) ??
14
+ usableMapStyle(options.mapPropsMapStyle);
15
+ const selectedTheme = getDeckMapStyleTheme(selectedStyle);
16
+ if (selectedStyle !== undefined && !selectedTheme)
17
+ return selectedStyle;
18
+ const theme = selectedTheme ?? options.resolvedTheme;
19
+ return (usableMapStyle(options.basemapProvider?.(theme)) ??
20
+ usableMapStyle(options.hostDefaultStyles?.[theme]) ??
21
+ options.fallbackStyles[theme]);
22
+ }
23
+ //# sourceMappingURL=basemap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"basemap.js","sourceRoot":"","sources":["../src/basemap.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,oBAAoB,EAAC,MAAM,aAAa,CAAC;AAgBjD,mFAAmF;AACnF,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;AACrE,CAAC;AAED,SAAS,cAAc,CAAC,KAA2B;IACjD,IAAI,KAAK,IAAI,IAAI,IAAI,gBAAgB,CAAC,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAC/D,OAAO,KAAK,CAAC;AACf,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,mBAAmB,CAAC,OAOnC;IACC,MAAM,aAAa,GACjB,cAAc,CAAC,OAAO,CAAC,QAAQ,CAAC;QAChC,cAAc,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC3C,MAAM,aAAa,GAAG,oBAAoB,CAAC,aAAa,CAAC,CAAC;IAC1D,IAAI,aAAa,KAAK,SAAS,IAAI,CAAC,aAAa;QAAE,OAAO,aAAa,CAAC;IACxE,MAAM,KAAK,GAAG,aAAa,IAAI,OAAO,CAAC,aAAa,CAAC;IACrD,OAAO,CACL,cAAc,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC,KAAK,CAAC,CAAC;QAChD,cAAc,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC,KAAK,CAAC,CAAC;QAClD,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,CAC9B,CAAC;AACJ,CAAC","sourcesContent":["import type {ResolvedTheme} from '@sqlrooms/ui';\nimport type {MapProps} from 'react-map-gl/maplibre';\nimport {getDeckMapStyleTheme} from './mapStyles';\n\n/** A MapLibre-compatible style accepted by the Deck map renderer. */\nexport type DeckMapStyle = NonNullable<MapProps['mapStyle']>;\n\n/** Optional host-provided basemap defaults keyed by resolved UI theme. */\nexport type DeckMapDefaultStyles = Partial<Record<ResolvedTheme, DeckMapStyle>>;\n\n/**\n * Resolves a basemap's light/dark variant. Return stable style objects or URLs,\n * or undefined to use host defaults. Providers and credentials are runtime-only.\n */\nexport type DeckMapBasemapProvider = (\n theme: ResolvedTheme,\n) => DeckMapStyle | undefined;\n\n/** True for `mapbox://` style URLs (MapLibre cannot load them without a token). */\nexport function isMapboxStyleUrl(style: unknown): boolean {\n return typeof style === 'string' && /^mapbox:/i.test(style.trim());\n}\n\nfunction usableMapStyle(style: MapProps['mapStyle']): DeckMapStyle | undefined {\n if (style == null || isMapboxStyleUrl(style)) return undefined;\n return style;\n}\n\n/** Resolves explicit styles, a basemap provider, host defaults, then the fallback. */\nexport function resolveDeckMapStyle(options: {\n mapStyle?: string;\n mapPropsMapStyle?: MapProps['mapStyle'];\n basemapProvider?: DeckMapBasemapProvider;\n hostDefaultStyles?: DeckMapDefaultStyles;\n resolvedTheme: ResolvedTheme;\n fallbackStyles: Record<ResolvedTheme, DeckMapStyle>;\n}): DeckMapStyle {\n const selectedStyle =\n usableMapStyle(options.mapStyle) ??\n usableMapStyle(options.mapPropsMapStyle);\n const selectedTheme = getDeckMapStyleTheme(selectedStyle);\n if (selectedStyle !== undefined && !selectedTheme) return selectedStyle;\n const theme = selectedTheme ?? options.resolvedTheme;\n return (\n usableMapStyle(options.basemapProvider?.(theme)) ??\n usableMapStyle(options.hostDefaultStyles?.[theme]) ??\n options.fallbackStyles[theme]\n );\n}\n"]}
@@ -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,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"}
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,2CAiL3B"}
package/dist/block.js CHANGED
@@ -73,15 +73,19 @@ export function DeckMapBlockRenderer({ mapId, title, caption, onCaptionChange, s
73
73
  const hasGeo = Boolean(findLongitudeLatitudeColumns(table)) ||
74
74
  Boolean(findGeometryColumn(table));
75
75
  updateMap(mapId, {
76
- config: hasGeo
77
- ? createDeckMapConfigForTable({
78
- tableName: table.tableName,
79
- columns: table.columns,
80
- tableReference: table.table,
81
- })
82
- : createEmptyDeckMapConfig(),
76
+ config: {
77
+ ...(hasGeo
78
+ ? createDeckMapConfigForTable({
79
+ tableName: table.tableName,
80
+ columns: table.columns,
81
+ tableReference: table.table,
82
+ })
83
+ : createEmptyDeckMapConfig()),
84
+ mapStyle: map?.config.mapStyle,
85
+ mapProps: map?.config.mapProps,
86
+ },
83
87
  });
84
- }, [mapId, setSelectedTable, updateMap]);
88
+ }, [map, mapId, setSelectedTable, updateMap]);
85
89
  if (!map) {
86
90
  return (_jsx("div", { className: "text-muted-foreground flex h-full min-h-[320px] items-center justify-center", children: "Preparing map..." }));
87
91
  }
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 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
+ {"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: {\n ...(hasGeo\n ? createDeckMapConfigForTable({\n tableName: table.tableName,\n columns: table.columns,\n tableReference: table.table,\n })\n : createEmptyDeckMapConfig()),\n mapStyle: map?.config.mapStyle,\n mapProps: map?.config.mapProps,\n },\n });\n },\n [map, 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"]}
package/dist/index.d.ts CHANGED
@@ -23,7 +23,10 @@ export { DeckMapSurface, directDeckMapDataAdapter, type DeckMapDataAdapter, type
23
23
  export { DECK_MAP_BLOCK_DEFAULT_HEIGHT, DECK_MAP_BLOCK_DEFAULT_TITLE, DECK_MAP_BLOCK_TYPE, createDeckMapBlockDocumentCommandType, createDeckMapBlockDocumentType, type DeckMapBlockDocumentRegistrationOptions, } from './blockDocumentRegistration';
24
24
  export type { DeckMapConfigMode, DeckMapDashboardFitToDataConfig, CreateDeckMapDashboardPanelConfigOptions, DeckMapDashboardDatasetConfig, DeckMapDataPolicyOverride, DeckMapDashboardInteractionConfig, DeckMapDashboardPanelConfig, DeckMapConfig, DeckMapDatasetConfig, DeckMapDatasetSource, DeckMapFitToDataConfig, DeckMapInteractionConfig, } from './mapConfig';
25
25
  export { DeckJsonMap } from './DeckJsonMap';
26
- export { DeckMapDefaultStylesProvider, resolveDeckMapStyle, useDeckMapDefaultStyles, type DeckMapDefaultStyles, type DeckMapStyle, } from './DeckMapDefaultStylesProvider';
26
+ export { DECK_MAP_BASEMAP_STYLES, getDefaultDeckMapStyle } from './mapStyles';
27
+ export { createProtomapsBasemapProvider, createProtomapsDefaultStyles, createProtomapsStyle, type ProtomapsFlavor, } from './protomapsStyles';
28
+ export { DeckMapDefaultStylesProvider, useDeckMapDefaultStyles, } from './DeckMapDefaultStylesProvider';
29
+ export { resolveDeckMapStyle, type DeckMapBasemapProvider, type DeckMapDefaultStyles, type DeckMapStyle, } from './basemap';
27
30
  export { ColorScaleFunction, GeometryEncodingHint as DeckGeometryEncodingHint, DeckJsonMapLayerSpec, DeckJsonMapSpec, LayerBindingConfig, LayerBindingProps, } from './DeckJsonMapSpec';
28
31
  export { createDeckJsonConfiguration } from './json/createDeckJsonConfiguration';
29
32
  export { prepareDeckDataset } from './prepare/prepareDeckDataset';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -19,7 +19,10 @@ export { DeckMapResourceSchema, DeckMapsSliceConfig, createDeckMapsSlice, useSto
19
19
  export { DeckMapSurface, directDeckMapDataAdapter, } from './DeckMapSurface';
20
20
  export { DECK_MAP_BLOCK_DEFAULT_HEIGHT, DECK_MAP_BLOCK_DEFAULT_TITLE, DECK_MAP_BLOCK_TYPE, createDeckMapBlockDocumentCommandType, createDeckMapBlockDocumentType, } from './blockDocumentRegistration';
21
21
  export { DeckJsonMap } from './DeckJsonMap';
22
- export { DeckMapDefaultStylesProvider, resolveDeckMapStyle, useDeckMapDefaultStyles, } from './DeckMapDefaultStylesProvider';
22
+ export { DECK_MAP_BASEMAP_STYLES, getDefaultDeckMapStyle } from './mapStyles';
23
+ export { createProtomapsBasemapProvider, createProtomapsDefaultStyles, createProtomapsStyle, } from './protomapsStyles';
24
+ export { DeckMapDefaultStylesProvider, useDeckMapDefaultStyles, } from './DeckMapDefaultStylesProvider';
25
+ export { resolveDeckMapStyle, } from './basemap';
23
26
  export { ColorScaleFunction, GeometryEncodingHint as DeckGeometryEncodingHint, DeckJsonMapLayerSpec, DeckJsonMapSpec, LayerBindingConfig, LayerBindingProps, } from './DeckJsonMapSpec';
24
27
  export { createDeckJsonConfiguration } from './json/createDeckJsonConfiguration';
25
28
  export { prepareDeckDataset } from './prepare/prepareDeckDataset';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAC,gBAAgB,EAAC,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAC,8BAA8B,EAAC,MAAM,kCAAkC,CAAC;AAChF,OAAO,EAAC,oBAAoB,EAAC,MAAM,oBAAoB,CAAC;AACxD,OAAO,EACL,oBAAoB,GAErB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,oBAAoB,EACpB,0BAA0B,GAE3B,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,mBAAmB,EACnB,wBAAwB,EACxB,iCAAiC,EACjC,gCAAgC,EAChC,6BAA6B,EAC7B,kCAAkC,EAClC,oCAAoC,GACrC,MAAM,aAAa,CAAC;AACrB,OAAO,EAAC,oBAAoB,EAAyB,MAAM,iBAAiB,CAAC;AAC7E,OAAO,EACL,wBAAwB,EACxB,oCAAoC,EACpC,2BAA2B,EAC3B,yCAAyC,EACzC,8BAA8B,EAC9B,mCAAmC,EACnC,kBAAkB,EAClB,4BAA4B,EAC5B,yBAAyB,EACzB,2BAA2B,EAC3B,yBAAyB,EACzB,6BAA6B,EAC7B,2BAA2B,GAC5B,MAAM,kBAAkB,CAAC;AAO1B,OAAO,EACL,8BAA8B,EAC9B,uBAAuB,GACxB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,8BAA8B,EAC9B,6BAA6B,GAC9B,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,wBAAwB,EACxB,sBAAsB,EACtB,8BAA8B,GAI/B,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,0BAA0B,EAC1B,2BAA2B,EAC3B,gCAAgC,EAChC,8BAA8B,EAC9B,+BAA+B,GAIhC,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,6BAA6B,GAI9B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,iBAAiB,CAAC;AAOzB,OAAO,EACL,cAAc,EACd,wBAAwB,GAGzB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,6BAA6B,EAC7B,4BAA4B,EAC5B,mBAAmB,EACnB,qCAAqC,EACrC,8BAA8B,GAE/B,MAAM,6BAA6B,CAAC;AAerC,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAC1C,OAAO,EACL,4BAA4B,EAC5B,mBAAmB,EACnB,uBAAuB,GAGxB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,kBAAkB,EAClB,oBAAoB,IAAI,wBAAwB,EAChD,oBAAoB,EACpB,eAAe,EACf,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAC,2BAA2B,EAAC,MAAM,oCAAoC,CAAC;AAC/E,OAAO,EAAC,kBAAkB,EAAC,MAAM,8BAA8B,CAAC;AAUhE,OAAO,EACL,wBAAwB,EACxB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,kCAAkC,EAClC,yBAAyB,GAC1B,MAAM,4BAA4B,CAAC","sourcesContent":["/**\n * {@include ../README.md}\n * @packageDocumentation\n */\n\nexport {ColorScaleLegend} from '@sqlrooms/color-scales';\nexport {createDeckJsonSpecFromDatasets} from './createDeckJsonSpecFromDatasets';\nexport {DeckMapBlockSettings} from './BlockMapSettings';\nexport {\n DeckMapSettingsPanel,\n type DeckMapSettingsPanelProps,\n} from './MapSettings';\nexport {\n DeckMapBlockRenderer,\n ensureDeckMapResourceState,\n type DeckMapBlockRendererProps,\n} from './block';\nexport {\n asDeckJsonMapConfig,\n createEmptyDeckMapConfig,\n createDeckMapDashboardPanelConfig,\n DEFAULT_DECK_MAP_MAX_DATA_POINTS,\n DECK_MAP_DASHBOARD_PANEL_TYPE,\n isDeckMapDashboardSqlDatasetSource,\n isDeckMapDashboardTableDatasetSource,\n} from './mapConfig';\nexport {getDeckMapDataPolicy, type DeckMapDataPolicy} from './mapDataPolicy';\nexport {\n applyDeckMapPointBinding,\n createDeckMapDashboardConfigForTable,\n createDeckMapConfigForTable,\n createDeckMapDashboardPanelConfigForTable,\n createDeckMapPointTransformSql,\n findDeckMapLongitudeLatitudeColumns,\n findGeometryColumn,\n findLongitudeLatitudeColumns,\n normalizeDeckMapFillColor,\n normalizeDeckMapPointConfig,\n quoteDeckMapSqlIdentifier,\n quoteDeckMapSqlTableReference,\n regenerateMapConfigForTable,\n} from './mapConfigUtils';\nexport type {\n DeckMapConfigColumn,\n DeckMapFillColor,\n DeckMapPointBinding,\n DeckMapTableReference,\n} from './mapConfigUtils';\nexport {\n getFirstDatasetSourceTableName,\n hasSqlOnlyDatasetSource,\n} from './datasetSourceUtils';\nexport type {DeckMapDatasetSourceConfig} from './datasetSourceUtils';\nexport {\n DeckMapResourceConfigParameter,\n DeckMapResourceToolParameters,\n} from './mapAiConfig';\nexport {\n normalizeAiDeckMapConfig,\n prepareAiDeckMapConfig,\n validateAndFixColorScaleFields,\n type NormalizeAiDeckMapConfigOptions,\n type PrepareAiDeckMapConfigOptions,\n type ResolveColorScaleTable,\n} from './aiNormalize';\nexport {\n DeckMapResourceConfigError,\n assertDeckMapResourceConfig,\n getDeckMapResourceAiInstructions,\n getDeckMapResourceConfigIssues,\n mergeDeckMapResourceConfigPatch,\n type DeckMapResourceConfigMergeOptions,\n type DeckMapResourceConfigIssue,\n type DeckMapResourceConfigValidationOptions,\n} from './mapResourceAuthoring';\nexport {\n createOrUpdateDeckMapResource,\n type CreateOrUpdateDeckMapResourceHost,\n type CreateOrUpdateDeckMapResourceParams,\n type CreateOrUpdateDeckMapResourceResult,\n} from './createOrUpdateDeckMapResource';\nexport {\n DeckMapResourceSchema,\n DeckMapsSliceConfig,\n createDeckMapsSlice,\n useStoreWithDeckMaps,\n} from './DeckMapsSlice';\nexport type {\n DeckMapResource,\n DeckMapRuntimeIssue,\n DeckMapRuntimeIssueReporter,\n DeckMapsSliceState,\n} from './DeckMapsSlice';\nexport {\n DeckMapSurface,\n directDeckMapDataAdapter,\n type DeckMapDataAdapter,\n type DeckMapSurfaceProps,\n} from './DeckMapSurface';\nexport {\n DECK_MAP_BLOCK_DEFAULT_HEIGHT,\n DECK_MAP_BLOCK_DEFAULT_TITLE,\n DECK_MAP_BLOCK_TYPE,\n createDeckMapBlockDocumentCommandType,\n createDeckMapBlockDocumentType,\n type DeckMapBlockDocumentRegistrationOptions,\n} from './blockDocumentRegistration';\nexport type {\n DeckMapConfigMode,\n DeckMapDashboardFitToDataConfig,\n CreateDeckMapDashboardPanelConfigOptions,\n DeckMapDashboardDatasetConfig,\n DeckMapDataPolicyOverride,\n DeckMapDashboardInteractionConfig,\n DeckMapDashboardPanelConfig,\n DeckMapConfig,\n DeckMapDatasetConfig,\n DeckMapDatasetSource,\n DeckMapFitToDataConfig,\n DeckMapInteractionConfig,\n} from './mapConfig';\nexport {DeckJsonMap} from './DeckJsonMap';\nexport {\n DeckMapDefaultStylesProvider,\n resolveDeckMapStyle,\n useDeckMapDefaultStyles,\n type DeckMapDefaultStyles,\n type DeckMapStyle,\n} from './DeckMapDefaultStylesProvider';\nexport {\n ColorScaleFunction,\n GeometryEncodingHint as DeckGeometryEncodingHint,\n DeckJsonMapLayerSpec,\n DeckJsonMapSpec,\n LayerBindingConfig,\n LayerBindingProps,\n} from './DeckJsonMapSpec';\nexport {createDeckJsonConfiguration} from './json/createDeckJsonConfiguration';\nexport {prepareDeckDataset} from './prepare/prepareDeckDataset';\n\nexport type {ColorLegendConfig, ColorScaleConfig} from '@sqlrooms/color-scales';\nexport type {\n GeometryEncodingHint,\n PreparedDeckDataset,\n PreparedGeoArrowLayerData,\n ResolvedGeometryColumn,\n ResolvedGeometryEncoding,\n} from './prepare/types';\nexport {\n isArrowTableDatasetInput,\n isSqlDatasetInput,\n isTableDatasetInput,\n} from './types';\nexport {\n DECK_TABLE_DATASET_SOURCE_RELATION,\n createDeckTableDatasetSql,\n} from './datasets/tableDatasetSql';\nexport type {\n CreateDeckJsonSpecFromDatasetsOptions,\n DeckArrowTableDatasetInput,\n DeckAutoLayerType,\n DeckDatasetInput,\n DeckJsonMapHandle,\n DeckJsonMapProps,\n DeckJsonSpecDatasetHint,\n DeckSqlDatasetInput,\n DeckTableDatasetInput,\n DeckTable,\n PreparedDeckDatasetState,\n} from './types';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAC,gBAAgB,EAAC,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAC,8BAA8B,EAAC,MAAM,kCAAkC,CAAC;AAChF,OAAO,EAAC,oBAAoB,EAAC,MAAM,oBAAoB,CAAC;AACxD,OAAO,EACL,oBAAoB,GAErB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,oBAAoB,EACpB,0BAA0B,GAE3B,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,mBAAmB,EACnB,wBAAwB,EACxB,iCAAiC,EACjC,gCAAgC,EAChC,6BAA6B,EAC7B,kCAAkC,EAClC,oCAAoC,GACrC,MAAM,aAAa,CAAC;AACrB,OAAO,EAAC,oBAAoB,EAAyB,MAAM,iBAAiB,CAAC;AAC7E,OAAO,EACL,wBAAwB,EACxB,oCAAoC,EACpC,2BAA2B,EAC3B,yCAAyC,EACzC,8BAA8B,EAC9B,mCAAmC,EACnC,kBAAkB,EAClB,4BAA4B,EAC5B,yBAAyB,EACzB,2BAA2B,EAC3B,yBAAyB,EACzB,6BAA6B,EAC7B,2BAA2B,GAC5B,MAAM,kBAAkB,CAAC;AAO1B,OAAO,EACL,8BAA8B,EAC9B,uBAAuB,GACxB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,8BAA8B,EAC9B,6BAA6B,GAC9B,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,wBAAwB,EACxB,sBAAsB,EACtB,8BAA8B,GAI/B,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,0BAA0B,EAC1B,2BAA2B,EAC3B,gCAAgC,EAChC,8BAA8B,EAC9B,+BAA+B,GAIhC,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,6BAA6B,GAI9B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,iBAAiB,CAAC;AAOzB,OAAO,EACL,cAAc,EACd,wBAAwB,GAGzB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,6BAA6B,EAC7B,4BAA4B,EAC5B,mBAAmB,EACnB,qCAAqC,EACrC,8BAA8B,GAE/B,MAAM,6BAA6B,CAAC;AAerC,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAC,uBAAuB,EAAE,sBAAsB,EAAC,MAAM,aAAa,CAAC;AAC5E,OAAO,EACL,8BAA8B,EAC9B,4BAA4B,EAC5B,oBAAoB,GAErB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,4BAA4B,EAC5B,uBAAuB,GACxB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,mBAAmB,GAIpB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,kBAAkB,EAClB,oBAAoB,IAAI,wBAAwB,EAChD,oBAAoB,EACpB,eAAe,EACf,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAC,2BAA2B,EAAC,MAAM,oCAAoC,CAAC;AAC/E,OAAO,EAAC,kBAAkB,EAAC,MAAM,8BAA8B,CAAC;AAUhE,OAAO,EACL,wBAAwB,EACxB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,kCAAkC,EAClC,yBAAyB,GAC1B,MAAM,4BAA4B,CAAC","sourcesContent":["/**\n * {@include ../README.md}\n * @packageDocumentation\n */\n\nexport {ColorScaleLegend} from '@sqlrooms/color-scales';\nexport {createDeckJsonSpecFromDatasets} from './createDeckJsonSpecFromDatasets';\nexport {DeckMapBlockSettings} from './BlockMapSettings';\nexport {\n DeckMapSettingsPanel,\n type DeckMapSettingsPanelProps,\n} from './MapSettings';\nexport {\n DeckMapBlockRenderer,\n ensureDeckMapResourceState,\n type DeckMapBlockRendererProps,\n} from './block';\nexport {\n asDeckJsonMapConfig,\n createEmptyDeckMapConfig,\n createDeckMapDashboardPanelConfig,\n DEFAULT_DECK_MAP_MAX_DATA_POINTS,\n DECK_MAP_DASHBOARD_PANEL_TYPE,\n isDeckMapDashboardSqlDatasetSource,\n isDeckMapDashboardTableDatasetSource,\n} from './mapConfig';\nexport {getDeckMapDataPolicy, type DeckMapDataPolicy} from './mapDataPolicy';\nexport {\n applyDeckMapPointBinding,\n createDeckMapDashboardConfigForTable,\n createDeckMapConfigForTable,\n createDeckMapDashboardPanelConfigForTable,\n createDeckMapPointTransformSql,\n findDeckMapLongitudeLatitudeColumns,\n findGeometryColumn,\n findLongitudeLatitudeColumns,\n normalizeDeckMapFillColor,\n normalizeDeckMapPointConfig,\n quoteDeckMapSqlIdentifier,\n quoteDeckMapSqlTableReference,\n regenerateMapConfigForTable,\n} from './mapConfigUtils';\nexport type {\n DeckMapConfigColumn,\n DeckMapFillColor,\n DeckMapPointBinding,\n DeckMapTableReference,\n} from './mapConfigUtils';\nexport {\n getFirstDatasetSourceTableName,\n hasSqlOnlyDatasetSource,\n} from './datasetSourceUtils';\nexport type {DeckMapDatasetSourceConfig} from './datasetSourceUtils';\nexport {\n DeckMapResourceConfigParameter,\n DeckMapResourceToolParameters,\n} from './mapAiConfig';\nexport {\n normalizeAiDeckMapConfig,\n prepareAiDeckMapConfig,\n validateAndFixColorScaleFields,\n type NormalizeAiDeckMapConfigOptions,\n type PrepareAiDeckMapConfigOptions,\n type ResolveColorScaleTable,\n} from './aiNormalize';\nexport {\n DeckMapResourceConfigError,\n assertDeckMapResourceConfig,\n getDeckMapResourceAiInstructions,\n getDeckMapResourceConfigIssues,\n mergeDeckMapResourceConfigPatch,\n type DeckMapResourceConfigMergeOptions,\n type DeckMapResourceConfigIssue,\n type DeckMapResourceConfigValidationOptions,\n} from './mapResourceAuthoring';\nexport {\n createOrUpdateDeckMapResource,\n type CreateOrUpdateDeckMapResourceHost,\n type CreateOrUpdateDeckMapResourceParams,\n type CreateOrUpdateDeckMapResourceResult,\n} from './createOrUpdateDeckMapResource';\nexport {\n DeckMapResourceSchema,\n DeckMapsSliceConfig,\n createDeckMapsSlice,\n useStoreWithDeckMaps,\n} from './DeckMapsSlice';\nexport type {\n DeckMapResource,\n DeckMapRuntimeIssue,\n DeckMapRuntimeIssueReporter,\n DeckMapsSliceState,\n} from './DeckMapsSlice';\nexport {\n DeckMapSurface,\n directDeckMapDataAdapter,\n type DeckMapDataAdapter,\n type DeckMapSurfaceProps,\n} from './DeckMapSurface';\nexport {\n DECK_MAP_BLOCK_DEFAULT_HEIGHT,\n DECK_MAP_BLOCK_DEFAULT_TITLE,\n DECK_MAP_BLOCK_TYPE,\n createDeckMapBlockDocumentCommandType,\n createDeckMapBlockDocumentType,\n type DeckMapBlockDocumentRegistrationOptions,\n} from './blockDocumentRegistration';\nexport type {\n DeckMapConfigMode,\n DeckMapDashboardFitToDataConfig,\n CreateDeckMapDashboardPanelConfigOptions,\n DeckMapDashboardDatasetConfig,\n DeckMapDataPolicyOverride,\n DeckMapDashboardInteractionConfig,\n DeckMapDashboardPanelConfig,\n DeckMapConfig,\n DeckMapDatasetConfig,\n DeckMapDatasetSource,\n DeckMapFitToDataConfig,\n DeckMapInteractionConfig,\n} from './mapConfig';\nexport {DeckJsonMap} from './DeckJsonMap';\nexport {DECK_MAP_BASEMAP_STYLES, getDefaultDeckMapStyle} from './mapStyles';\nexport {\n createProtomapsBasemapProvider,\n createProtomapsDefaultStyles,\n createProtomapsStyle,\n type ProtomapsFlavor,\n} from './protomapsStyles';\nexport {\n DeckMapDefaultStylesProvider,\n useDeckMapDefaultStyles,\n} from './DeckMapDefaultStylesProvider';\nexport {\n resolveDeckMapStyle,\n type DeckMapBasemapProvider,\n type DeckMapDefaultStyles,\n type DeckMapStyle,\n} from './basemap';\nexport {\n ColorScaleFunction,\n GeometryEncodingHint as DeckGeometryEncodingHint,\n DeckJsonMapLayerSpec,\n DeckJsonMapSpec,\n LayerBindingConfig,\n LayerBindingProps,\n} from './DeckJsonMapSpec';\nexport {createDeckJsonConfiguration} from './json/createDeckJsonConfiguration';\nexport {prepareDeckDataset} from './prepare/prepareDeckDataset';\n\nexport type {ColorLegendConfig, ColorScaleConfig} from '@sqlrooms/color-scales';\nexport type {\n GeometryEncodingHint,\n PreparedDeckDataset,\n PreparedGeoArrowLayerData,\n ResolvedGeometryColumn,\n ResolvedGeometryEncoding,\n} from './prepare/types';\nexport {\n isArrowTableDatasetInput,\n isSqlDatasetInput,\n isTableDatasetInput,\n} from './types';\nexport {\n DECK_TABLE_DATASET_SOURCE_RELATION,\n createDeckTableDatasetSql,\n} from './datasets/tableDatasetSql';\nexport type {\n CreateDeckJsonSpecFromDatasetsOptions,\n DeckArrowTableDatasetInput,\n DeckAutoLayerType,\n DeckDatasetInput,\n DeckJsonMapHandle,\n DeckJsonMapProps,\n DeckJsonSpecDatasetHint,\n DeckSqlDatasetInput,\n DeckTableDatasetInput,\n DeckTable,\n PreparedDeckDatasetState,\n} from './types';\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"mapAiSharedInstructions.d.ts","sourceRoot":"","sources":["../src/mapAiSharedInstructions.ts"],"names":[],"mappings":"AAEA,mEAAmE;AACnE,wBAAgB,+BAA+B,IAAI,MAAM,CAYxD"}
1
+ {"version":3,"file":"mapAiSharedInstructions.d.ts","sourceRoot":"","sources":["../src/mapAiSharedInstructions.ts"],"names":[],"mappings":"AAEA,mEAAmE;AACnE,wBAAgB,+BAA+B,IAAI,MAAM,CAaxD"}
@@ -8,6 +8,7 @@ export function getDeckMapSharedAiContractRules() {
8
8
  - Never write SELECT *, ST_AsWKB(col) AS col — DuckDB keeps the original column and the WKB alias collides. Use SELECT * EXCLUDE (col), ST_AsWKB(...) AS col, or omit transformSql when geom already exists. Bare ST_Point(...) / table GEOMETRY columns are projected to WKB by the dataset pipeline; prefer explicit ST_AsWKB when practical.
9
9
  - GeoArrowHeatmapLayer: omit colorRange (UI scheme selector owns it) and omit getWeight (default uniform density). Do not bind getWeight to a column — basic mode has no weight-column control.
10
10
  - Never set mapStyle to a mapbox:// URL — MapLibre cannot load that scheme. Omit mapStyle for the host basemap, or use a token-free MapLibre https:// style URL.
11
+ - Built-in mapStyle IDs are light and dark. New maps default to the app theme at creation; omit mapStyle on updates to preserve the saved selection. Never put tile API keys in map configs.
11
12
  - GeoArrowH3HexagonLayer: set getHexagon to "@@=h3_column" (or _sqlroomsBinding.hexagonColumn). When aggregating lon/lat, prefer h3_h3_to_string(h3_latlng_to_cell(lat, lon, res)) AS h3_cell (lat before lon).
12
13
  - GeoArrowArcLayer: bind WKB via _sqlroomsBinding.sourceGeometryColumn / targetGeometryColumn only (do not set getSourcePosition/getTargetPosition). Use ST_AsWKB(ST_Point(...)); set geometryEncodingHint to "wkb".
13
14
  - GeoArrowTripsLayer = animated path over time; GeoArrowArcLayer = static OD curve. Prefer TripsLayer for animated/trips/moving routes.
@@ -1 +1 @@
1
- {"version":3,"file":"mapAiSharedInstructions.js","sourceRoot":"","sources":["../src/mapAiSharedInstructions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,kCAAkC,EAAC,MAAM,4BAA4B,CAAC;AAE9E,mEAAmE;AACnE,MAAM,UAAU,+BAA+B;IAC7C,MAAM,GAAG,GAAG,kCAAkC,CAAC;IAC/C,OAAO;sWAC6V,GAAG;;;;;;;;qlBAQ4O,CAAC;AACtlB,CAAC","sourcesContent":["import {DECK_TABLE_DATASET_SOURCE_RELATION} from './datasets/tableDatasetSql';\n\n/** Shared Deck map AI rules for dashboard and document prompts. */\nexport function getDeckMapSharedAiContractRules(): string {\n const src = DECK_TABLE_DATASET_SOURCE_RELATION;\n return `Shared Deck map authoring rules (dashboard and document):\n- Scatterplot/Heatmap/Column require Point positions — do not bind them to Polygon/MultiPolygon geom. Prefer GeoArrowPolygonLayer for Polygon, GeoJsonLayer for WKB/WKT MultiPolygon, or transformSql with ST_AsWKB(ST_Centroid(geom)) / ST_PointOnSurface(geom) when the user wants points (e.g. SELECT * EXCLUDE (geom), ST_AsWKB(ST_Centroid(geom)) AS geom FROM ${src}). The runtime will not invent centroids.\n- Mixed Point/LineString/Polygon columns: use GeoJsonLayer. Typed GeoArrowPolygon/Path/Scatterplot layers need a uniform geometry type. To keep one class, filter with WHERE ST_GeometryType(geom) IN (...) then use the matching typed layer.\n- Never write SELECT *, ST_AsWKB(col) AS col — DuckDB keeps the original column and the WKB alias collides. Use SELECT * EXCLUDE (col), ST_AsWKB(...) AS col, or omit transformSql when geom already exists. Bare ST_Point(...) / table GEOMETRY columns are projected to WKB by the dataset pipeline; prefer explicit ST_AsWKB when practical.\n- GeoArrowHeatmapLayer: omit colorRange (UI scheme selector owns it) and omit getWeight (default uniform density). Do not bind getWeight to a column — basic mode has no weight-column control.\n- Never set mapStyle to a mapbox:// URL — MapLibre cannot load that scheme. Omit mapStyle for the host basemap, or use a token-free MapLibre https:// style URL.\n- GeoArrowH3HexagonLayer: set getHexagon to \"@@=h3_column\" (or _sqlroomsBinding.hexagonColumn). When aggregating lon/lat, prefer h3_h3_to_string(h3_latlng_to_cell(lat, lon, res)) AS h3_cell (lat before lon).\n- GeoArrowArcLayer: bind WKB via _sqlroomsBinding.sourceGeometryColumn / targetGeometryColumn only (do not set getSourcePosition/getTargetPosition). Use ST_AsWKB(ST_Point(...)); set geometryEncodingHint to \"wkb\".\n- GeoArrowTripsLayer = animated path over time; GeoArrowArcLayer = static OD curve. Prefer TripsLayer for animated/trips/moving routes.\n- COLOR SCALE FIELD VARIANCE: Before choosing a numeric colorScale field, confirm it has real range (min < max / not all zeros or a single constant). Prefer SUMMARIZE table_name or SELECT min(col), max(col), count(DISTINCT col) FROM ... when unsure. Do NOT color by a flat column unless the user explicitly asks for that column by name. If no varying column exists, use a flat fill color instead of colorScale. Categorical fields need more than one distinct non-null value to be useful. Geometry, lon/lat, H3 index, and opaque ID columns are not useful color fields unless the user asks for them.`;\n}\n"]}
1
+ {"version":3,"file":"mapAiSharedInstructions.js","sourceRoot":"","sources":["../src/mapAiSharedInstructions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,kCAAkC,EAAC,MAAM,4BAA4B,CAAC;AAE9E,mEAAmE;AACnE,MAAM,UAAU,+BAA+B;IAC7C,MAAM,GAAG,GAAG,kCAAkC,CAAC;IAC/C,OAAO;sWAC6V,GAAG;;;;;;;;;qlBAS4O,CAAC;AACtlB,CAAC","sourcesContent":["import {DECK_TABLE_DATASET_SOURCE_RELATION} from './datasets/tableDatasetSql';\n\n/** Shared Deck map AI rules for dashboard and document prompts. */\nexport function getDeckMapSharedAiContractRules(): string {\n const src = DECK_TABLE_DATASET_SOURCE_RELATION;\n return `Shared Deck map authoring rules (dashboard and document):\n- Scatterplot/Heatmap/Column require Point positions — do not bind them to Polygon/MultiPolygon geom. Prefer GeoArrowPolygonLayer for Polygon, GeoJsonLayer for WKB/WKT MultiPolygon, or transformSql with ST_AsWKB(ST_Centroid(geom)) / ST_PointOnSurface(geom) when the user wants points (e.g. SELECT * EXCLUDE (geom), ST_AsWKB(ST_Centroid(geom)) AS geom FROM ${src}). The runtime will not invent centroids.\n- Mixed Point/LineString/Polygon columns: use GeoJsonLayer. Typed GeoArrowPolygon/Path/Scatterplot layers need a uniform geometry type. To keep one class, filter with WHERE ST_GeometryType(geom) IN (...) then use the matching typed layer.\n- Never write SELECT *, ST_AsWKB(col) AS col — DuckDB keeps the original column and the WKB alias collides. Use SELECT * EXCLUDE (col), ST_AsWKB(...) AS col, or omit transformSql when geom already exists. Bare ST_Point(...) / table GEOMETRY columns are projected to WKB by the dataset pipeline; prefer explicit ST_AsWKB when practical.\n- GeoArrowHeatmapLayer: omit colorRange (UI scheme selector owns it) and omit getWeight (default uniform density). Do not bind getWeight to a column — basic mode has no weight-column control.\n- Never set mapStyle to a mapbox:// URL — MapLibre cannot load that scheme. Omit mapStyle for the host basemap, or use a token-free MapLibre https:// style URL.\n- Built-in mapStyle IDs are light and dark. New maps default to the app theme at creation; omit mapStyle on updates to preserve the saved selection. Never put tile API keys in map configs.\n- GeoArrowH3HexagonLayer: set getHexagon to \"@@=h3_column\" (or _sqlroomsBinding.hexagonColumn). When aggregating lon/lat, prefer h3_h3_to_string(h3_latlng_to_cell(lat, lon, res)) AS h3_cell (lat before lon).\n- GeoArrowArcLayer: bind WKB via _sqlroomsBinding.sourceGeometryColumn / targetGeometryColumn only (do not set getSourcePosition/getTargetPosition). Use ST_AsWKB(ST_Point(...)); set geometryEncodingHint to \"wkb\".\n- GeoArrowTripsLayer = animated path over time; GeoArrowArcLayer = static OD curve. Prefer TripsLayer for animated/trips/moving routes.\n- COLOR SCALE FIELD VARIANCE: Before choosing a numeric colorScale field, confirm it has real range (min < max / not all zeros or a single constant). Prefer SUMMARIZE table_name or SELECT min(col), max(col), count(DISTINCT col) FROM ... when unsure. Do NOT color by a flat column unless the user explicitly asks for that column by name. If no varying column exists, use a flat fill color instead of colorScale. Categorical fields need more than one distinct non-null value to be useful. Geometry, lon/lat, H3 index, and opaque ID columns are not useful color fields unless the user asks for them.`;\n}\n"]}