Skip to content

feat: improvements for geoarrow deck layers in dashboard maps - #700

Merged
igorDykhta merged 89 commits into
mainfrom
igr/improve-maps
Jun 19, 2026
Merged

igorDykhta merged 89 commits into
mainfrom
igr/improve-maps

Conversation

@igorDykhta

@igorDykhta igorDykhta commented Jun 8, 2026 •

Copy link
Copy Markdown
Collaborator

Improve deck.gl map layers, fit-to-bounds, and AI tooling

New layer implementations

  • H3HexagonLayer — Custom GeoArrow-compatible wrapper that converts Arrow data to row objects with proper BigInt→hex string conversion, working around incompatibilities between @geoarrow/[email protected] and @deck.gl/[email protected]
  • TripsLayer — Custom GeoArrow-compatible wrapper that extracts binary data from Arrow vectors and passes it to the native TripsLayer, with proper per-chunk iteration and Float32 timestamp conversion
  • ColumnLayer — Wrapper that patches a deck.gl wireframe index buffer bug (#10021) affecting fill rendering with binary data
  • Waypoint aggregation — Auto-aggregates per-waypoint rows into LineString vectors for PathLayer/TripsLayer by detecting group-by ID, order, and timestamp columns via naming patterns

Fit-to-bounds refactor

  • Extracted fit-to-bounds logic into useDeckMapFitToBounds hook with support for H3, geometry, and lat/lon column types
  • Added jumpTo imperative handle on DeckJsonMap via forwardRef
  • Bounds queries now handle WKB-encoded geometry columns and H3 cell centroids

Map configuration UI

  • Added extrusion controls (toggle + elevation column picker) for H3 and polygon layers
  • Added trips timeline control with play/pause, scrubber, and collapse
  • Added missing-column warning icon overlay that opens settings on click
  • Highlighted missing columns in ColumnSelector with red border and "missing" label
  • Made ColorScaleLegend collapsible

AI instructions & tooling

  • Improved instructions for H3 functions (h3_cell_to_lat/h3_cell_to_lng instead of h3_latlng)
  • Added instruction that sqlQuery must be a pure SELECT (no INSTALL/LOAD)
  • Added table-switching guidance — AI now always calls resolveTable when tableName is explicitly provided
  • Handles quoted/qualified table identifiers safely when normalizing dataset sources

DeckJsonMap rendering improvements

  • Switched to interleaved: true by default for GeoArrow layers
  • Added onRenderingError callback prop and graceful error overlay
  • Added heatmap WebGL framebuffer leak workaround (unmount/remount overlay on type change)
  • Soft-warning (instead of hard error) when a @@=column accessor references a missing column

Dataset handling

  • Panel issue reporting now aggregates errors across all datasets (no longer clears prematurely)
  • Added data sampling support with a sampling indicator in the UI
  • FROM-clause rewriting uses lookahead instead of \b to support quoted table names

Python server

  • Wrapped get_arrow in an explicit transaction to prevent "ActiveTransaction" errors during geometry CRS lookup
  • Added _get_arrow_cast_geometry fallback that converts geometry columns to WKB before Arrow export
  • Hardened SQL subquery construction (strip trailing semicolons, escape column names)

DuckDB connectors

  • GeoJSON file loading now falls back to load('auto') only when the spatial extension is unavailable, re-throwing genuine parse failures

Other

  • Added || !colorScale.domain guard and Number.isFinite checks for empty-domain edge cases in color scales
  • Suppressed unhandled promise rejection warnings in DuckDbSlice query handles

Summary by CodeRabbit

  • New Features

    • Added GeoJSON file upload support across the application
    • Introduced TripsLayer animation with time-based controls
    • Added collapsible color scale legends
    • Implemented fit-to-bounds functionality for deck maps
    • Enhanced layer support (Arc, Heatmap, H3 Hexagon, Trips, Column layers)
    • Added data sampling indicators for large datasets
  • Bug Fixes

    • Fixed geometry export for Arrow conversion
    • Resolved layer rendering issues
    • Improved handling of missing columns and invalid data
  • Documentation

    • Updated deck map configuration documentation for interleaved rendering

Ihor Dykhta added 16 commits June 5, 2026 20:22
Signed-off-by: Ihor Dykhta <[email protected]>
Signed-off-by: Ihor Dykhta <[email protected]>
Signed-off-by: Ihor Dykhta <[email protected]>
Signed-off-by: Ihor Dykhta <[email protected]>
Signed-off-by: Ihor Dykhta <[email protected]>
Signed-off-by: Ihor Dykhta <[email protected]>
Signed-off-by: Ihor Dykhta <[email protected]>
Signed-off-by: Ihor Dykhta <[email protected]>
Signed-off-by: Ihor Dykhta <[email protected]>
Signed-off-by: Ihor Dykhta <[email protected]>
Signed-off-by: Ihor Dykhta <[email protected]>
Signed-off-by: Ihor Dykhta <[email protected]>
Signed-off-by: Ihor Dykhta <[email protected]>
@coderabbitai

coderabbitai Bot commented Jun 8, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR extends the deck.gl map panel with TripsLayer animation, new GeoArrow layer wrappers (Trips, H3Hexagon, Column), WKB LineString promotion, DuckDB-based fit-to-bounds with row sampling, an expanded MapSettings UI, AI config normalization that rewrites dataset sources into SQL geometry queries, and cross-connector GeoJSON ingest with spatial-first loading.

Changes

Deck Map Runtime and GeoArrow Integration

Layer / File(s) Summary
Geometry parsing, detection, and promotion
packages/deck/src/prepare/wkbParser.ts, packages/deck/src/prepare/wkbDecoder.ts, packages/deck/src/prepare/detectGeometryColumn.ts, packages/deck/src/json/aggregateWaypoints.ts
Adds WKB_LINESTRING constant and readWKBLineStringXY parser; extends WKB promotion to LineString/path/arc layers; exports findCoordinateColumns for coordinate-column detection with fallbacks; and introduces tryAggregateWaypointsToLineStrings to auto-group tabular rows into per-path LineString Arrow vectors with optional timestamps.
GeoArrow layer wrappers and class wiring
packages/deck/src/json/layers/DeckTripsLayer.ts, packages/deck/src/json/layers/DeckH3HexagonLayer.ts, packages/deck/src/json/layers/DeckColumnLayer.ts, packages/deck/src/json/layers/index.ts, packages/deck/src/json/layerCompatibility.ts, packages/deck/src/json/defaultClasses.ts, packages/deck/package.json
Adds three new CompositeLayer wrappers — DeckTripsLayer (Arrow-to-binary chunk iteration), DeckH3HexagonLayer (BigInt hex conversion), DeckColumnLayer (wireframe index buffer monkey-patch) — and wires them into DEFAULT_DECK_JSON_CLASSES with allowGeoArrowPromotion flags; adds @deck.gl/geo-layers dependency.
Deck JSON schema, bindings, and color-scale resilience
packages/deck/src/DeckJsonMapSpec.ts, packages/deck/src/json/createDeckJsonConfiguration.ts, packages/deck/src/json/rewriteGeoArrowAccessors.ts, packages/deck/src/json/compileColorScale.ts, packages/deck/src/json/extractColorScaleLegends.ts
Extends JsonAccessor schema to accept record/dict values; adds waypoint auto-aggregation and point-vs-path/polygon error messages in binding resolution; guards missing GeoArrow accessor columns; computes TripsLayer _tripsMaxTimestamp; and wraps color-scale compilation and legend building in error-returning fallbacks.
Color scale defaults and collapsible legend
packages/color-scales/src/scale.ts, packages/color-scales/src/ColorScaleLegend.tsx
Adds finite-guard fallback domains for sequential/diverging scales, interpolator-existence validation, and broadened falsy-domain auto-selection; introduces defaultCollapsed prop with collapse/expand toggle and collapse button inside the first legend card.
DeckJsonMap API and Trips animation
packages/deck/src/types.ts, packages/deck/src/DeckJsonMap.tsx, packages/deck/src/index.ts, packages/deck/README.md
Exports DeckJsonMapHandle with imperative jumpTo; converts DeckJsonMap to forwardRef with pending-jump flush on map load; adds TripsTimeControl UI with play/pause/seek; rewrites DeckOverlayControl with layer-type-key-based one-frame clearing to fix heatmap framebuffer leak; defaults interleaved to true; adds onRenderingError callback.
Dashboard config contracts and layer config helpers
packages/deck/src/dashboardConfig.ts, packages/deck/src/mapConfigUtils.ts, packages/deck/src/mapLayerConfigUtils.ts, packages/deck/src/useDeckMapDatasets.ts
Updates DeckMapDashboardFitToDataConfig to optional columns plus geometry/h3 alternatives; adds isSampled to dataset client state; rewrites resolveDeckMapDashboardDatasetSource with FROM-clause dashboard table substitution and catalog-prefix stripping; adds sampleRows to dataset query; adds predicate helpers for H3/arc/trips/radius/extrusion layer types; exports setDeckMapLayerHexagonColumn/setDeckMapLayerArcColumns; and introduces useDeckMapDatasets hook for dataset state and panel issue reporting.
Fit-to-bounds query and hook
packages/deck/src/useDeckMapFitToBounds.ts
Exports createDeckMapBoundsQuery generating DuckDB SQL for H3, geometry-extent, and explicit lat/lon bounds; exports emitDeckMapDashboardFitRequest; and implements useDeckMapFitToBounds hook with per-panel fit state, h3 extension loading, executeSql, and imperative jumpTo dispatch.
Dashboard renderer: error parsing, sampling, missing-field detection
packages/deck/src/dashboard.tsx
Adds DuckDB error parsers for missing columns and geometry mismatches; extends DeckMapRuntimeIssuePanel for those error types; refactors DeckMapDashboardDatasetClient with maxRows/fitToData and isSampled; removes reset-filters button; wires useDeckMapDatasets and useDeckMapFitToBounds; adds dismissible sampled-data overlay and missing-columns tooltip.
MapSettings UI expansion
packages/deck/src/MapSettings.tsx
Adds dashboard-selected-table resolution, Visible layer switch, Trips width/trail sliders, heatmap color-scheme detection and selector, reworked color-scale property/field/type/scheme block, radius sliders for heatmap/point/column layers, H3 and arc column binding sections, arc controls, elevation column selector, and conditional lat/lon selectors.
AI instruction updates and config normalization
packages/deck/src/ai.ts, packages/mosaic/src/ai/ai.ts, packages/mosaic/src/ai/list-panels-tool.ts, packages/deck/__tests__/dashboard-ai-map.test.ts
Rewrites DECK_MAP_AI_INSTRUCTIONS with detailed geometry/layer guidance; introduces normalizeAiMapConfig that rewrites dataset tableName sources into SQL geometry queries; updates createDeckMapDashboardTool table resolution; adds selectedTable instruction and list-panels payload field; and updates tests to expect the normalized scatter config.
GeoJSON ingest and DuckDB/Python fallbacks
packages/duckdb-core/src/BaseDuckDbConnector.ts, packages/duckdb/src/connectors/WasmDuckDbConnector.ts, packages/duckdb/src/connectors/WebSocketDuckDbConnector.ts, packages/duckdb/src/DuckDbSlice.ts, python/sqlrooms-server/sqlrooms/server/query.py, apps/sqlrooms-cli-ui/src/components/useLocalFileLoader.ts, examples/deckgl/..., examples/kepler/..., packages/kepler/...
Adds spatial-first loading with load('auto', …) fallback for .geojson files across all three DuckDB connectors; adds geojson MIME/extension to accepted formats in CLI, deckgl/kepler examples, and KeplerAddDataDialog; attaches rejection handler to executeSql query cache; and updates Python Arrow export with transaction management and geometry-to-WKB fallback.
UI polish, error boundary remounting, and test updates
packages/mosaic/src/components/FieldSelectorInput.tsx, packages/mosaic/src/dashboard/panel/MosaicDashboardPanel.tsx, packages/deck/__tests__/DeckSpec.test.ts, packages/deck/__tests__/createDeckJsonConfiguration.test.ts, packages/deck/__tests__/dashboard.test.ts, apps/sqlrooms-cli-ui/src/workspace/sidebar/CliArtifactsSidebarSection.tsx, packages/mosaic/src/dashboard/panel/MosaicDashboardPanelLayout.tsx, packages/sql-editor/src/components/...
Adds destructive styling and "missing" indicator in FieldSelectorInput when value is absent; remounts panel error boundary on selectedTable change; updates color-scale/accessor/dashboard SQL tests; and reformats minor cosmetic JSX and CSS in sidebar and layout components.

Sequence Diagram(s)

sequenceDiagram
  participant Dashboard
  participant DeckMapDashboardRenderer
  participant useDeckMapFitToBounds
  participant DuckDB
  participant DeckJsonMap

  Dashboard->>DeckMapDashboardRenderer: render (config, selectedTable)
  DeckMapDashboardRenderer->>useDeckMapFitToBounds: resolve fitToData, build bounds query
  useDeckMapFitToBounds->>DuckDB: executeSql(createDeckMapBoundsQuery)
  DuckDB-->>useDeckMapFitToBounds: Arrow table with min/max lon/lat
  useDeckMapFitToBounds->>useDeckMapFitToBounds: fitBounds → jumpTo view state
  useDeckMapFitToBounds->>DeckJsonMap: ref.jumpTo(lon, lat, zoom)
  DeckMapDashboardRenderer->>DeckJsonMap: render layers + fitToData per dataset
  DeckJsonMap->>DeckJsonMap: DeckOverlayControl key transition (clear + reapply)
  DeckJsonMap-->>DeckMapDashboardRenderer: onRenderingError / onLoad
Loading
sequenceDiagram
  participant AI
  participant createDeckMapDashboardTool
  participant normalizeAiMapConfig
  participant resolveDeckMapDashboardDatasetSource

  AI->>createDeckMapDashboardTool: params (config, tableName)
  createDeckMapDashboardTool->>normalizeAiMapConfig: config with fitToData lon/lat columns
  normalizeAiMapConfig->>normalizeAiMapConfig: rewrite tableName source → sqlQuery with ST_AsWKB(ST_Point(...))
  normalizeAiMapConfig-->>createDeckMapDashboardTool: normalized config
  createDeckMapDashboardTool->>resolveDeckMapDashboardDatasetSource: resolve with dashboard.selectedTable
  resolveDeckMapDashboardDatasetSource->>resolveDeckMapDashboardDatasetSource: rewrite FROM clause to dashboard table
  resolveDeckMapDashboardDatasetSource-->>createDeckMapDashboardTool: rewritten sqlQuery
  createDeckMapDashboardTool-->>AI: panel config with normalized datasets
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

  • sqlrooms/sqlrooms#569: Both PRs touch packages/deck/package.json to add/bump @deck.gl dependencies — this PR adds @deck.gl/geo-layers@^9.3.1.
  • sqlrooms/sqlrooms#570: Both PRs modify GeoArrow WKB geometry promotion and decoding in packages/deck/src/prepare/wkbDecoder.ts and wkbParser.ts.
  • sqlrooms/sqlrooms#654: Both PRs modify packages/deck/src/ai.ts — #654 introduces the deck-map AI tools and this PR further expands DECK_MAP_AI_INSTRUCTIONS, config cloning, and dashboard table-resolution logic.

Suggested reviewers

  • ilyabo

🐇 Hop, hop! The layers now play trips in time,
GeoArrow LineStrings promoted sublime.
A .geojson file? Spatial-load it first!
The legend collapses when viewport is cursed.
jumpTo waits patiently 'til the map is done—
This rabbit's map magic has only begun! 🗺️

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 19.77% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately summarizes the main objective: improvements to GeoArrow deck layers in dashboard maps, covering custom layer wrappers, fit-to-bounds logic, configuration UI enhancements, and related infrastructure changes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch igr/improve-maps

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Signed-off-by: Ihor Dykhta <[email protected]>
Comment thread packages/deck/src/json/layers/SqlroomsTripsLayer.ts Outdated
Ihor Dykhta added 11 commits June 9, 2026 19:00
Signed-off-by: Ihor Dykhta <[email protected]>
Signed-off-by: Ihor Dykhta <[email protected]>
Signed-off-by: Ihor Dykhta <[email protected]>
Signed-off-by: Ihor Dykhta <[email protected]>
Signed-off-by: Ihor Dykhta <[email protected]>
Signed-off-by: Ihor Dykhta <[email protected]>
@igorDykhta
igorDykhta marked this pull request as ready for review June 18, 2026 00:50

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 16

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
packages/deck/src/dashboard.tsx (1)

358-467: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Remove duplicate/dead code.

createDeckMapBoundsQuery, readBoundsFromExtentResult, fitViewStateToBounds, deckMapDashboardFitRequestTarget, emitDeckMapDashboardFitRequest, DeckMapDashboardFitState, and createInitialDeckMapDashboardFitState appear to be duplicated from useDeckMapFitToBounds.ts. The renderer now uses useDeckMapFitToBounds hook (line 617) and imports emitDeckMapDashboardFitRequest from that module (line 57), making this local copy dead code.

Additionally, the local emitDeckMapDashboardFitRequest at line 443 shadows the import at line 57, which could cause confusion.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/deck/src/dashboard.tsx` around lines 358 - 467, Remove the duplicate
function and type definitions from dashboard.tsx that are already provided by
the useDeckMapFitToBounds module. Specifically, delete the implementations of
createDeckMapBoundsQuery, readBoundsFromExtentResult, fitViewStateToBounds,
deckMapDashboardFitRequestTarget, emitDeckMapDashboardFitRequest,
DeckMapDashboardFitState, and createInitialDeckMapDashboardFitState functions
shown in the diff. This will eliminate the dead code and resolve the shadowing
issue where the local emitDeckMapDashboardFitRequest definition conflicts with
the imported version from line 57, ensuring only the imported
emitDeckMapDashboardFitRequest is used throughout the file.
packages/color-scales/src/scale.ts (1)

176-192: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fix empty-domain guards to handle Infinity/-Infinity correctly.

On Line 178 and Line 190, the nullish checks don’t trigger for empty samples (extent([]) yields Infinity/-Infinity), so invalid domains still propagate.

💡 Suggested fix
 export function getSequentialDomain(values: number[]) {
   const [min, max] = extent(values);
-  if (min == null || max == null) {
+  if (!Number.isFinite(min) || !Number.isFinite(max)) {
     return [0, 1] as [number, number];
   }
   if (min === max) {
     return [min - 1, max + 1] as [number, number];
   }

   return [min, max] as [number, number];
 }

 export function getDivergingDomain(values: number[]) {
   const [min, max] = extent(values);
-  if (min == null || max == null) {
+  if (!Number.isFinite(min) || !Number.isFinite(max)) {
     return [-1, 0, 1] as [number, number, number];
   }
   if (min === max) {
     return [min - 1, min, max + 1] as [number, number, number];
   }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/color-scales/src/scale.ts` around lines 176 - 192, The nullish
checks in getSequentialDomain and getDivergingDomain functions do not properly
handle the case where extent returns Infinity or -Infinity for empty input
arrays. Update the guards on line 178 and line 190 to verify not only that min
and max are not null but also that they are finite numbers using isFinite or a
similar check. This will ensure that invalid domains with Infinity values are
caught and default domains are returned instead.
🧹 Nitpick comments (4)
packages/deck/__tests__/dashboard-ai-map.test.ts (1)

235-278: ⚡ Quick win

Add regression coverage for table-switch and quoted-table normalization paths.

The updated behavior is only tested with unquoted earthquakes and no pre-selected dashboard table. Please add cases for:

  1. dashboard already has selectedTable and create_dashboard_map receives a different tableName;
  2. dataset source uses a quoted/qualified table name (e.g. "local"."main"."events") and normalized SQL remains valid.

As per coding guidelines, "Add or update tests when changing behavior or public API, when practical."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/deck/__tests__/dashboard-ai-map.test.ts` around lines 235 - 278, The
existing tests in the dashboard-ai-map.test.ts file only cover basic creation
and update scenarios with unquoted table names and no pre-selected dashboard
table. You need to add two new test cases following the same pattern as the
existing it() tests: First, add a test that sets up deps with a pre-existing
selectedTable value, then calls execute on createDeckMapDashboardTool with a
different tableName to verify the table-switch behavior works correctly. Second,
add a test case where the dataset source uses a quoted/qualified table name
format like "local"."main"."events", then verify through assertions that the
normalized SQL remains valid and the panel is created or updated correctly. Both
tests should follow the same arrange-act-assert pattern as the existing tests,
using createDeps(), createDeckMapDashboardTool(deps), and validating the results
through expect() assertions on llmResult.success, deps.panels, and relevant
panel properties.

Source: Coding guidelines

packages/deck/src/useDeckMapFitToBounds.ts (1)

246-252: 💤 Low value

Add tsdoc to exported function.

emitDeckMapDashboardFitRequest is exported but lacks tsdoc documentation. As per coding guidelines, exported functions in packages should have tsdoc.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/deck/src/useDeckMapFitToBounds.ts` around lines 246 - 252, The
exported function emitDeckMapDashboardFitRequest lacks tsdoc documentation which
is required for exported functions in packages. Add tsdoc comments above the
function definition to document what the function does, including a description
of the panelId parameter and the purpose of the CustomEvent being dispatched.
Use appropriate tsdoc tags like `@param` and `@remarks` to provide clear
documentation for developers using this function.

Source: Coding guidelines

packages/deck/src/mapLayerConfigUtils.ts (1)

134-173: 💤 Low value

Add tsdoc to new exported functions.

New exported functions (usesH3ColumnSetting, usesArcColumnSetting, usesRadiusSetting, usesColumnRadiusSetting, usesTripsSettings, usesExtrusionSettings, setDeckMapLayerHexagonColumn, setDeckMapLayerArcColumns) are missing tsdoc comments. As per coding guidelines, exported types and functions in packages/**/*.ts should have tsdoc.

Also applies to: 273-307

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/deck/src/mapLayerConfigUtils.ts` around lines 134 - 173, Add tsdoc
comments to all six exported functions in the current code block
(usesH3ColumnSetting, usesArcColumnSetting, usesRadiusSetting,
usesColumnRadiusSetting, usesTripsSettings, and usesExtrusionSettings) and to
setDeckMapLayerHexagonColumn and setDeckMapLayerArcColumns functions mentioned
at lines 273-307. Each function should have a tsdoc comment above it that
describes what the function does, documents the layerType parameter (or relevant
parameters for the setDeckMapLayer functions), and describes the return type.
Follow the existing tsdoc style and format used elsewhere in the codebase to
maintain consistency with the project's coding guidelines for exported functions
and types.

Source: Coding guidelines

packages/deck/__tests__/createDeckJsonConfiguration.test.ts (1)

332-358: 🏗️ Heavy lift

Expand this suite to cover the new behavior branches introduced in this PR.

This update only retargets one accessor assertion. Please add focused tests for the new runtime branches (e.g., waypoint auto-aggregation to LineString and promoted-table consistency across multi-geometry bindings), since they directly affect conversion correctness.

As per coding guidelines, "Add or update tests when changing behavior or public API, when practical".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/deck/__tests__/createDeckJsonConfiguration.test.ts` around lines 332
- 358, The current test suite only validates that the getFillColor accessor is a
function but does not test the new runtime branches introduced in this PR,
specifically waypoint auto-aggregation to LineString and promoted-table
consistency across multi-geometry bindings. Add separate focused test cases to
the test suite that verify these new behavior branches work correctly during
conversion, ensuring that the converter properly handles these cases and that
conversion correctness is maintained for multi-geometry bindings and waypoint
aggregation scenarios.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/color-scales/src/ColorScaleLegend.tsx`:
- Around line 16-23: Add TSDoc documentation comments above the ColorScaleLegend
function definition to document the exported public API. Include a summary of
what the function does, document each prop parameter (legends, className, width,
swatchColumns, defaultCollapsed) with descriptions of their purpose and types,
and document the return type. This ensures the updated API contract including
the defaultCollapsed parameter is properly documented per coding guidelines.

In `@packages/deck/src/ai.ts`:
- Around line 346-353: The condition `if (!dashboard?.selectedTable)` prevents
deps.resolveTable from being called when a dashboard already has a selectedTable
set, which means the explicit tableName parameter passed by the caller is
ignored and the wrong dataset remains active. Remove the condition so that
deps.resolveTable(artifactId, params.tableName) is always called whenever
params.tableName is provided, regardless of whether dashboard.selectedTable is
already set.
- Around line 252-255: The current implementation of splitting
`source.tableName` using a simple `.split('.')` does not respect quoted
identifiers, causing already-quoted table name parts to be quoted again and
result in invalid SQL. Instead of splitting blindly by period, implement a
helper function that splits the table name by periods only when they occur
outside of double quotes, similar to the suggested
`splitIdentifierPathOutsideQuotes` function. Then use this function to split
`source.tableName` before applying `quoteDeckMapSqlIdentifier` to each part,
ensuring that parts that are already quoted are not re-quoted and that the full
qualified table name is handled correctly.

In `@packages/deck/src/dashboardConfig.ts`:
- Around line 129-134: The regex patterns at lines 129 and 133 in the
dashboardConfig.ts file use word boundary assertions `\b` after the dynamic
table name tokens, which fail to match quoted identifiers like "main"."events"
because word boundaries don't properly recognize the quotes and dots as
boundaries. Modify both regex patterns to replace the trailing `\b` word
boundary with a more flexible pattern that can handle both quoted and unquoted
table names, such as using a lookahead assertion or a character class that
explicitly matches whitespace, commas, semicolons, or closing parentheses that
typically follow table names in SQL queries.

In `@packages/deck/src/DeckJsonMap.tsx`:
- Around line 162-175: The button elements in the TripsTimeControl component at
lines 162, 173, and 197 lack explicit type attributes, which defaults them to
type="submit" and can trigger unintended form submission. Add type="button"
attribute to each of the three button elements in the TripsTimeControl component
to ensure they function as toggle/action buttons rather than form submission
buttons.
- Around line 518-523: The handleMapLoad callback function does not invoke the
consumer's onLoad handler from mapProps, causing it to be overridden when the
map load event fires. Modify the handleMapLoad function to call mapProps.onLoad
after executing the pending jump logic if onLoad exists, ensuring both the
internal jump behavior and any consumer-provided load handlers execute when the
map completes loading.
- Around line 430-433: The computedMaxTs variable is being overwritten with each
trips layer's maxTs value instead of keeping the maximum. Replace the assignment
`computedMaxTs = maxTs;` with `computedMaxTs = Math.max(computedMaxTs, maxTs);`
to ensure the timeline bounds correctly use the maximum timestamp across all
trips layers, preventing the timeline from shrinking based on layer order.

In `@packages/deck/src/json/createDeckJsonConfiguration.ts`:
- Around line 152-165: The promoted geometry source branch (when
layerData.source === 'promoted') is missing the table-consistency validation
that exists in the else branch. Add the same table mismatch validation check
that appears in the else block to the promoted branch, ensuring that when
layerData.source is 'promoted', the code also verifies that the table is not
combining promoted geometry columns from different prepared tables. This
validation should check if table is neither prepared.table nor layerData.table,
and if so, throw an error before assigning the geometryColumn to boundProps.

In `@packages/deck/src/json/layers/DeckH3HexagonLayer.ts`:
- Around line 62-66: The compiled accessor function calls at lines 62-66 and
105-109 pass a global row index `i` (from 0 to numRows-1) with only the first
batch `table.batches[0]`, but the GeoArrow accessor implementation expects a
batch-local index within that specific batch. For multi-batch tables, this
causes out-of-bounds access. Fix this by either determining which batch contains
the row at index i and computing the batch-local index accordingly before
calling the hexProp accessor, or by consolidating the table into a single batch
using appropriate table operations before processing the rows.

In `@packages/deck/src/json/layers/DeckTripsLayer.ts`:
- Around line 160-186: The code in the loop over Object.entries(restProps) only
handles float Arrow vectors for scalar binary accessors using
arrow.DataType.isFloat check, which causes integer vectors to be silently
skipped. Add an additional condition after the existing isFloat check to also
handle integer Arrow vectors by calling expandToCoords with chunkData.values
cast as TypedArray, using size 1, and relativeOffsets, then assigning the result
to binaryAttributes similar to the float case. Use arrow.DataType.isInteger or
the appropriate integer type checking method to identify integer vectors that
should be handled the same way as float vectors for scalar accessor promotion.

In `@packages/deck/src/mapConfigUtils.ts`:
- Around line 347-354: The return statement in the map configuration update
preserves the existing layer specs (which reference specific dataset IDs) but
replaces the datasets array with new ones, causing dataset ID mismatches and
broken layer bindings. Create two helper functions:
remapNextDatasetsToExistingIds to preserve the current dataset IDs while copying
over the updated source fields from the next config, and remapFitToDataDatasetId
to remap any dataset references in fitToData to use the preserved dataset IDs.
Then update the return statement to use these helpers so that layer bindings
remain valid when datasets are updated.

In `@packages/deck/src/prepare/detectGeometryColumn.ts`:
- Around line 54-67: The getFieldVector function can return an alternate vector
when the requested geometry column doesn't exist, but the calling code at line
170 still returns columnName: detectedGeometryColumn, creating a mismatch
between the returned vector and its column name. Modify getFieldVector to return
both the vector and the actual matched column name (including when a fallback
alternate is found), then update the return statement at lines 169-171 to use
the actual matched column name from the function result instead of always using
the original detectedGeometryColumn parameter.

In `@packages/deck/src/types.ts`:
- Around line 63-71: Add TSDoc comments to the DeckJsonMapHandle type definition
and its jumpTo method to document the public API contract. Include a brief
description of what DeckJsonMapHandle represents, and for the jumpTo method,
document each parameter (longitude, latitude, zoom, bearing, pitch) with their
types and purposes. Also apply the same TSDoc documentation approach to the
rendering-error callback contract defined in lines 73-93 as referenced in the
comment.

In `@packages/deck/src/useDeckMapDatasets.ts`:
- Around line 49-59: The current implementation only checks the individual
state's error status and clears the panel issue whenever any single dataset
updates without an error, even if other datasets still have errors in
multi-dataset panels. Refactor the error checking logic to examine all datasets
in datasetStates by iterating through Object.values(datasetStates) and finding
the first error that exists across any dataset. If an error is found, call
reportPanelIssue with that error; only call clearPanelIssue when no errors exist
across all datasets. Wrap this consolidated logic in a useEffect dependency that
responds to changes in datasetStates, dashboardId, panel.id, reportPanelIssue,
and clearPanelIssue to ensure proper tracking across all datasets.

In `@packages/duckdb-core/src/BaseDuckDbConnector.ts`:
- Around line 174-179: The catch block in the GeoJSON handling section (around
the loadSpatial function call) currently catches all errors indiscriminately and
silently falls back to load('auto', ...), which masks genuine GeoJSON parsing
failures. Instead of catching all errors, narrow the catch block to only catch
specific spatial-capability-related errors that indicate the spatial extension
is unavailable or doesn't support the operation, and allow other error types
(like parsing errors or invalid GeoJSON) to propagate up. This way, legitimate
failures in the GeoJSON file won't be silently converted to non-spatial data
loads.

In `@python/sqlrooms-server/sqlrooms/server/query.py`:
- Around line 102-114: The raw SQL variable is being directly wrapped in
subqueries at the wrapped query construction and cast_sql query construction
without stripping trailing semicolons, which makes the subqueries invalid.
Additionally, column names in the projections list may contain unescaped quotes
that could break the SQL. Fix this by stripping any trailing semicolons from the
sql variable before using it in both the wrapped and cast_sql constructions, and
ensure column names are properly quoted or escaped when building the projections
list to safely handle column names with special characters.

---

Outside diff comments:
In `@packages/color-scales/src/scale.ts`:
- Around line 176-192: The nullish checks in getSequentialDomain and
getDivergingDomain functions do not properly handle the case where extent
returns Infinity or -Infinity for empty input arrays. Update the guards on line
178 and line 190 to verify not only that min and max are not null but also that
they are finite numbers using isFinite or a similar check. This will ensure that
invalid domains with Infinity values are caught and default domains are returned
instead.

In `@packages/deck/src/dashboard.tsx`:
- Around line 358-467: Remove the duplicate function and type definitions from
dashboard.tsx that are already provided by the useDeckMapFitToBounds module.
Specifically, delete the implementations of createDeckMapBoundsQuery,
readBoundsFromExtentResult, fitViewStateToBounds,
deckMapDashboardFitRequestTarget, emitDeckMapDashboardFitRequest,
DeckMapDashboardFitState, and createInitialDeckMapDashboardFitState functions
shown in the diff. This will eliminate the dead code and resolve the shadowing
issue where the local emitDeckMapDashboardFitRequest definition conflicts with
the imported version from line 57, ensuring only the imported
emitDeckMapDashboardFitRequest is used throughout the file.

---

Nitpick comments:
In `@packages/deck/__tests__/createDeckJsonConfiguration.test.ts`:
- Around line 332-358: The current test suite only validates that the
getFillColor accessor is a function but does not test the new runtime branches
introduced in this PR, specifically waypoint auto-aggregation to LineString and
promoted-table consistency across multi-geometry bindings. Add separate focused
test cases to the test suite that verify these new behavior branches work
correctly during conversion, ensuring that the converter properly handles these
cases and that conversion correctness is maintained for multi-geometry bindings
and waypoint aggregation scenarios.

In `@packages/deck/__tests__/dashboard-ai-map.test.ts`:
- Around line 235-278: The existing tests in the dashboard-ai-map.test.ts file
only cover basic creation and update scenarios with unquoted table names and no
pre-selected dashboard table. You need to add two new test cases following the
same pattern as the existing it() tests: First, add a test that sets up deps
with a pre-existing selectedTable value, then calls execute on
createDeckMapDashboardTool with a different tableName to verify the table-switch
behavior works correctly. Second, add a test case where the dataset source uses
a quoted/qualified table name format like "local"."main"."events", then verify
through assertions that the normalized SQL remains valid and the panel is
created or updated correctly. Both tests should follow the same
arrange-act-assert pattern as the existing tests, using createDeps(),
createDeckMapDashboardTool(deps), and validating the results through expect()
assertions on llmResult.success, deps.panels, and relevant panel properties.

In `@packages/deck/src/mapLayerConfigUtils.ts`:
- Around line 134-173: Add tsdoc comments to all six exported functions in the
current code block (usesH3ColumnSetting, usesArcColumnSetting,
usesRadiusSetting, usesColumnRadiusSetting, usesTripsSettings, and
usesExtrusionSettings) and to setDeckMapLayerHexagonColumn and
setDeckMapLayerArcColumns functions mentioned at lines 273-307. Each function
should have a tsdoc comment above it that describes what the function does,
documents the layerType parameter (or relevant parameters for the
setDeckMapLayer functions), and describes the return type. Follow the existing
tsdoc style and format used elsewhere in the codebase to maintain consistency
with the project's coding guidelines for exported functions and types.

In `@packages/deck/src/useDeckMapFitToBounds.ts`:
- Around line 246-252: The exported function emitDeckMapDashboardFitRequest
lacks tsdoc documentation which is required for exported functions in packages.
Add tsdoc comments above the function definition to document what the function
does, including a description of the panelId parameter and the purpose of the
CustomEvent being dispatched. Use appropriate tsdoc tags like `@param` and
`@remarks` to provide clear documentation for developers using this function.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 686b715f-bb2a-4b25-9f56-111c3facb473

📥 Commits

Reviewing files that changed from the base of the PR and between dcb1a51 and 5b44c7b.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (46)
  • examples/deckgl/src/components/DataPanel.tsx
  • examples/kepler/src/components/DataPanel.tsx
  • packages/color-scales/src/ColorScaleLegend.tsx
  • packages/color-scales/src/scale.ts
  • packages/deck/README.md
  • packages/deck/__tests__/DeckSpec.test.ts
  • packages/deck/__tests__/createDeckJsonConfiguration.test.ts
  • packages/deck/__tests__/dashboard-ai-map.test.ts
  • packages/deck/__tests__/dashboard.test.ts
  • packages/deck/package.json
  • packages/deck/src/DeckJsonMap.tsx
  • packages/deck/src/DeckJsonMapSpec.ts
  • packages/deck/src/MapSettings.tsx
  • packages/deck/src/ai.ts
  • packages/deck/src/dashboard.tsx
  • packages/deck/src/dashboardConfig.ts
  • packages/deck/src/index.ts
  • packages/deck/src/json/aggregateWaypoints.ts
  • packages/deck/src/json/compileColorScale.ts
  • packages/deck/src/json/createDeckJsonConfiguration.ts
  • packages/deck/src/json/defaultClasses.ts
  • packages/deck/src/json/extractColorScaleLegends.ts
  • packages/deck/src/json/layerCompatibility.ts
  • packages/deck/src/json/layers/DeckColumnLayer.ts
  • packages/deck/src/json/layers/DeckH3HexagonLayer.ts
  • packages/deck/src/json/layers/DeckTripsLayer.ts
  • packages/deck/src/json/layers/index.ts
  • packages/deck/src/json/rewriteGeoArrowAccessors.ts
  • packages/deck/src/mapConfigUtils.ts
  • packages/deck/src/mapLayerConfigUtils.ts
  • packages/deck/src/prepare/detectGeometryColumn.ts
  • packages/deck/src/prepare/wkbDecoder.ts
  • packages/deck/src/prepare/wkbParser.ts
  • packages/deck/src/types.ts
  • packages/deck/src/useDeckMapDatasets.ts
  • packages/deck/src/useDeckMapFitToBounds.ts
  • packages/duckdb-core/src/BaseDuckDbConnector.ts
  • packages/duckdb/src/DuckDbSlice.ts
  • packages/duckdb/src/connectors/WasmDuckDbConnector.ts
  • packages/duckdb/src/connectors/WebSocketDuckDbConnector.ts
  • packages/kepler/src/components/KeplerAddDataDialog.tsx
  • packages/mosaic/src/ai/ai.ts
  • packages/mosaic/src/ai/list-panels-tool.ts
  • packages/mosaic/src/components/FieldSelectorInput.tsx
  • packages/mosaic/src/dashboard/panel/MosaicDashboardPanel.tsx
  • python/sqlrooms-server/sqlrooms/server/query.py

Comment thread packages/color-scales/src/ColorScaleLegend.tsx
Comment thread packages/deck/src/ai.ts Outdated
Comment thread packages/deck/src/ai.ts
Comment thread packages/deck/src/dashboardConfig.ts Outdated
Comment thread packages/deck/src/DeckJsonMap.tsx
Comment thread packages/deck/src/prepare/detectGeometryColumn.ts
Comment thread packages/deck/src/types.ts
Comment thread packages/deck/src/useDeckMapDatasets.ts Outdated
Comment thread packages/duckdb-core/src/BaseDuckDbConnector.ts
Comment thread python/sqlrooms-server/sqlrooms/server/query.py Outdated
Ihor Dykhta added 2 commits June 18, 2026 04:31
Signed-off-by: Ihor Dykhta <[email protected]>
Signed-off-by: Ihor Dykhta <[email protected]>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/deck/src/dashboardConfig.ts (1)

205-227: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add defensive validation to prevent invalid SQL generation.

If createDeckMapDashboardDatasetQuery is called with an empty source (neither tableName nor sqlQuery), sourceExpr becomes an empty string. With sampleRows enabled, this produces invalid SQL: (SELECT * FROM USING SAMPLE N ROWS).

While upstream resolveDeckMapDashboardDatasetSource should return undefined for empty sources, adding defensive validation makes this function safer as a library API.

🛡️ Suggested guard
 export function createDeckMapDashboardDatasetQuery(
   source: {tableName?: string; sqlQuery?: string},
   filter: unknown,
   options?: {sampleRows?: number},
 ) {
+  if (!source.tableName && !source.sqlQuery) {
+    throw new Error('createDeckMapDashboardDatasetQuery requires either tableName or sqlQuery');
+  }
+
   // Apply USING SAMPLE at the source level so Mosaic filters work on top.

Additionally, as per coding guidelines, exported functions in packages/ should have tsdoc. Consider adding parameter and return documentation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/deck/src/dashboardConfig.ts` around lines 205 - 227, The function
`createDeckMapDashboardDatasetQuery` needs defensive validation and
documentation. First, add a guard clause at the beginning of the function to
validate that the source parameter contains at least either a tableName or
sqlQuery property, throwing an appropriate error if neither is provided. This
prevents invalid SQL generation when sourceExpr becomes an empty string and
sampleRows is specified. Second, add TSDoc comments above the function to
document all parameters (source with its nested properties, filter, and options
including sampleRows) and the return type to meet library API documentation
standards for exported functions in the packages directory.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@packages/deck/src/dashboardConfig.ts`:
- Around line 205-227: The function `createDeckMapDashboardDatasetQuery` needs
defensive validation and documentation. First, add a guard clause at the
beginning of the function to validate that the source parameter contains at
least either a tableName or sqlQuery property, throwing an appropriate error if
neither is provided. This prevents invalid SQL generation when sourceExpr
becomes an empty string and sampleRows is specified. Second, add TSDoc comments
above the function to document all parameters (source with its nested
properties, filter, and options including sampleRows) and the return type to
meet library API documentation standards for exported functions in the packages
directory.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ad96eda0-6bc2-4569-a222-d8522de0e061

📥 Commits

Reviewing files that changed from the base of the PR and between 346e224 and 38dfd2f.

📒 Files selected for processing (5)
  • packages/color-scales/src/scale.ts
  • packages/deck/src/DeckJsonMap.tsx
  • packages/deck/src/ai.ts
  • packages/deck/src/dashboardConfig.ts
  • packages/deck/src/useDeckMapDatasets.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/color-scales/src/scale.ts
  • packages/deck/src/DeckJsonMap.tsx

Comment thread python/sqlrooms-server/sqlrooms/server/query.py
Ihor Dykhta added 3 commits June 18, 2026 15:46

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/mosaic/src/charts/chart-types/base-types.ts`:
- Around line 203-206: The SQL table reference construction in the code block
where schema and table values are wrapped in double quotes does not escape
double quote characters within those identifier values. If schema or table
contain a double quote character, the generated SQL reference becomes invalid.
To fix this, apply proper escaping to both the schema and table variables before
constructing the SQL string by replacing any double quote characters with
escaped double quotes (using the standard SQL escaping method of doubling the
quote) before inserting them into the template string at line 205.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 301414a3-815f-4507-a2b6-743f2d0cf040

📥 Commits

Reviewing files that changed from the base of the PR and between 38dfd2f and ea82d64.

📒 Files selected for processing (4)
  • apps/sqlrooms-cli-ui/src/components/useLocalFileLoader.ts
  • packages/mosaic/__tests__/chart-types/line-chart-spec.test.ts
  • packages/mosaic/src/charts/chart-types/base-types.ts
  • packages/mosaic/src/useVgPlotChartRender.ts

Comment thread packages/mosaic/src/charts/chart-types/base-types.ts Outdated
Comment thread packages/mosaic/src/charts/chart-types/base-types.ts Outdated
@igorDykhta
igorDykhta merged commit d5e30b0 into main Jun 19, 2026
4 checks passed
@igorDykhta
igorDykhta deleted the igr/improve-maps branch June 19, 2026 15:45
@coderabbitai coderabbitai Bot mentioned this pull request Aug 20, 2026
3 tasks done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants