@sqlrooms/deck 0.29.0-rc.10

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 (251) hide show
  1. package/LICENSE.md +10 -0
  2. package/README.md +654 -0
  3. package/dist/BlockMapSettings.d.ts +3 -0
  4. package/dist/BlockMapSettings.d.ts.map +1 -0
  5. package/dist/BlockMapSettings.js +57 -0
  6. package/dist/BlockMapSettings.js.map +1 -0
  7. package/dist/DashboardMapSettings.d.ts +7 -0
  8. package/dist/DashboardMapSettings.d.ts.map +1 -0
  9. package/dist/DashboardMapSettings.js +52 -0
  10. package/dist/DashboardMapSettings.js.map +1 -0
  11. package/dist/DeckJsonMap.d.ts +4 -0
  12. package/dist/DeckJsonMap.d.ts.map +1 -0
  13. package/dist/DeckJsonMap.js +370 -0
  14. package/dist/DeckJsonMap.js.map +1 -0
  15. package/dist/DeckJsonMapSpec.d.ts +7617 -0
  16. package/dist/DeckJsonMapSpec.d.ts.map +1 -0
  17. package/dist/DeckJsonMapSpec.js +82 -0
  18. package/dist/DeckJsonMapSpec.js.map +1 -0
  19. package/dist/DeckMapDefaultStylesProvider.d.ts +28 -0
  20. package/dist/DeckMapDefaultStylesProvider.d.ts.map +1 -0
  21. package/dist/DeckMapDefaultStylesProvider.js +23 -0
  22. package/dist/DeckMapDefaultStylesProvider.js.map +1 -0
  23. package/dist/DeckMapSurface.d.ts +39 -0
  24. package/dist/DeckMapSurface.d.ts.map +1 -0
  25. package/dist/DeckMapSurface.js +137 -0
  26. package/dist/DeckMapSurface.js.map +1 -0
  27. package/dist/DeckMapsSlice.d.ts +99 -0
  28. package/dist/DeckMapsSlice.d.ts.map +1 -0
  29. package/dist/DeckMapsSlice.js +89 -0
  30. package/dist/DeckMapsSlice.js.map +1 -0
  31. package/dist/MapSettings.d.ts +16 -0
  32. package/dist/MapSettings.d.ts.map +1 -0
  33. package/dist/MapSettings.js +292 -0
  34. package/dist/MapSettings.js.map +1 -0
  35. package/dist/MapSettingsControls.d.ts +40 -0
  36. package/dist/MapSettingsControls.d.ts.map +1 -0
  37. package/dist/MapSettingsControls.js +54 -0
  38. package/dist/MapSettingsControls.js.map +1 -0
  39. package/dist/ai.d.ts +261 -0
  40. package/dist/ai.d.ts.map +1 -0
  41. package/dist/ai.js +392 -0
  42. package/dist/ai.js.map +1 -0
  43. package/dist/block.d.ts +21 -0
  44. package/dist/block.d.ts.map +1 -0
  45. package/dist/block.js +105 -0
  46. package/dist/block.js.map +1 -0
  47. package/dist/blockDocumentRegistration.d.ts +45 -0
  48. package/dist/blockDocumentRegistration.d.ts.map +1 -0
  49. package/dist/blockDocumentRegistration.js +68 -0
  50. package/dist/blockDocumentRegistration.js.map +1 -0
  51. package/dist/createDeckJsonSpecFromDatasets.d.ts +11 -0
  52. package/dist/createDeckJsonSpecFromDatasets.d.ts.map +1 -0
  53. package/dist/createDeckJsonSpecFromDatasets.js +85 -0
  54. package/dist/createDeckJsonSpecFromDatasets.js.map +1 -0
  55. package/dist/createOrUpdateDeckMapResource.d.ts +81 -0
  56. package/dist/createOrUpdateDeckMapResource.d.ts.map +1 -0
  57. package/dist/createOrUpdateDeckMapResource.js +82 -0
  58. package/dist/createOrUpdateDeckMapResource.js.map +1 -0
  59. package/dist/dashboard.d.ts +6 -0
  60. package/dist/dashboard.d.ts.map +1 -0
  61. package/dist/dashboard.js +337 -0
  62. package/dist/dashboard.js.map +1 -0
  63. package/dist/dashboardConfig.d.ts +25 -0
  64. package/dist/dashboardConfig.d.ts.map +1 -0
  65. package/dist/dashboardConfig.js +82 -0
  66. package/dist/dashboardConfig.js.map +1 -0
  67. package/dist/dashboardIntegration.d.ts +3 -0
  68. package/dist/dashboardIntegration.d.ts.map +1 -0
  69. package/dist/dashboardIntegration.js +16 -0
  70. package/dist/dashboardIntegration.js.map +1 -0
  71. package/dist/datasetSourceUtils.d.ts +16 -0
  72. package/dist/datasetSourceUtils.d.ts.map +1 -0
  73. package/dist/datasetSourceUtils.js +25 -0
  74. package/dist/datasetSourceUtils.js.map +1 -0
  75. package/dist/datasets/PreparedDatasetStore.d.ts +120 -0
  76. package/dist/datasets/PreparedDatasetStore.d.ts.map +1 -0
  77. package/dist/datasets/PreparedDatasetStore.js +268 -0
  78. package/dist/datasets/PreparedDatasetStore.js.map +1 -0
  79. package/dist/datasets/helpers.d.ts +57 -0
  80. package/dist/datasets/helpers.d.ts.map +1 -0
  81. package/dist/datasets/helpers.js +155 -0
  82. package/dist/datasets/helpers.js.map +1 -0
  83. package/dist/datasets/normalizeDatasets.d.ts +11 -0
  84. package/dist/datasets/normalizeDatasets.d.ts.map +1 -0
  85. package/dist/datasets/normalizeDatasets.js +50 -0
  86. package/dist/datasets/normalizeDatasets.js.map +1 -0
  87. package/dist/datasets/tableAdapter.d.ts +11 -0
  88. package/dist/datasets/tableAdapter.d.ts.map +1 -0
  89. package/dist/datasets/tableAdapter.js +11 -0
  90. package/dist/datasets/tableAdapter.js.map +1 -0
  91. package/dist/datasets/tableDatasetSql.d.ts +16 -0
  92. package/dist/datasets/tableDatasetSql.d.ts.map +1 -0
  93. package/dist/datasets/tableDatasetSql.js +49 -0
  94. package/dist/datasets/tableDatasetSql.js.map +1 -0
  95. package/dist/datasets/types.d.ts +40 -0
  96. package/dist/datasets/types.d.ts.map +1 -0
  97. package/dist/datasets/types.js +2 -0
  98. package/dist/datasets/types.js.map +1 -0
  99. package/dist/datasets/usePreparedDatasetStates.d.ts +16 -0
  100. package/dist/datasets/usePreparedDatasetStates.d.ts.map +1 -0
  101. package/dist/datasets/usePreparedDatasetStates.js +59 -0
  102. package/dist/datasets/usePreparedDatasetStates.js.map +1 -0
  103. package/dist/index.d.ts +34 -0
  104. package/dist/index.d.ts.map +1 -0
  105. package/dist/index.js +27 -0
  106. package/dist/index.js.map +1 -0
  107. package/dist/json/aggregateWaypoints.d.ts +14 -0
  108. package/dist/json/aggregateWaypoints.d.ts.map +1 -0
  109. package/dist/json/aggregateWaypoints.js +190 -0
  110. package/dist/json/aggregateWaypoints.js.map +1 -0
  111. package/dist/json/colorScaleFunction.d.ts +27 -0
  112. package/dist/json/colorScaleFunction.d.ts.map +1 -0
  113. package/dist/json/colorScaleFunction.js +46 -0
  114. package/dist/json/colorScaleFunction.js.map +1 -0
  115. package/dist/json/compileColorScale.d.ts +12 -0
  116. package/dist/json/compileColorScale.d.ts.map +1 -0
  117. package/dist/json/compileColorScale.js +125 -0
  118. package/dist/json/compileColorScale.js.map +1 -0
  119. package/dist/json/compileGeoArrowAccessor.d.ts +18 -0
  120. package/dist/json/compileGeoArrowAccessor.d.ts.map +1 -0
  121. package/dist/json/compileGeoArrowAccessor.js +129 -0
  122. package/dist/json/compileGeoArrowAccessor.js.map +1 -0
  123. package/dist/json/createDeckJsonConfiguration.d.ts +9 -0
  124. package/dist/json/createDeckJsonConfiguration.d.ts.map +1 -0
  125. package/dist/json/createDeckJsonConfiguration.js +315 -0
  126. package/dist/json/createDeckJsonConfiguration.js.map +1 -0
  127. package/dist/json/defaultClasses.d.ts +12 -0
  128. package/dist/json/defaultClasses.d.ts.map +1 -0
  129. package/dist/json/defaultClasses.js +35 -0
  130. package/dist/json/defaultClasses.js.map +1 -0
  131. package/dist/json/extractColorScaleLegends.d.ts +8 -0
  132. package/dist/json/extractColorScaleLegends.d.ts.map +1 -0
  133. package/dist/json/extractColorScaleLegends.js +86 -0
  134. package/dist/json/extractColorScaleLegends.js.map +1 -0
  135. package/dist/json/heatmapDefaults.d.ts +8 -0
  136. package/dist/json/heatmapDefaults.d.ts.map +1 -0
  137. package/dist/json/heatmapDefaults.js +14 -0
  138. package/dist/json/heatmapDefaults.js.map +1 -0
  139. package/dist/json/layerCompatibility.d.ts +21 -0
  140. package/dist/json/layerCompatibility.d.ts.map +1 -0
  141. package/dist/json/layerCompatibility.js +168 -0
  142. package/dist/json/layerCompatibility.js.map +1 -0
  143. package/dist/json/layerConfig.d.ts +14 -0
  144. package/dist/json/layerConfig.d.ts.map +1 -0
  145. package/dist/json/layerConfig.js +54 -0
  146. package/dist/json/layerConfig.js.map +1 -0
  147. package/dist/json/layers/DeckColumnLayer.d.ts +10 -0
  148. package/dist/json/layers/DeckColumnLayer.d.ts.map +1 -0
  149. package/dist/json/layers/DeckColumnLayer.js +26 -0
  150. package/dist/json/layers/DeckColumnLayer.js.map +1 -0
  151. package/dist/json/layers/DeckH3HexagonLayer.d.ts +37 -0
  152. package/dist/json/layers/DeckH3HexagonLayer.d.ts.map +1 -0
  153. package/dist/json/layers/DeckH3HexagonLayer.js +118 -0
  154. package/dist/json/layers/DeckH3HexagonLayer.js.map +1 -0
  155. package/dist/json/layers/DeckTripsLayer.d.ts +46 -0
  156. package/dist/json/layers/DeckTripsLayer.d.ts.map +1 -0
  157. package/dist/json/layers/DeckTripsLayer.js +170 -0
  158. package/dist/json/layers/DeckTripsLayer.js.map +1 -0
  159. package/dist/json/layers/createTableToRecordBatchAdapter.d.ts +20 -0
  160. package/dist/json/layers/createTableToRecordBatchAdapter.d.ts.map +1 -0
  161. package/dist/json/layers/createTableToRecordBatchAdapter.js +81 -0
  162. package/dist/json/layers/createTableToRecordBatchAdapter.js.map +1 -0
  163. package/dist/json/layers/index.d.ts +5 -0
  164. package/dist/json/layers/index.d.ts.map +1 -0
  165. package/dist/json/layers/index.js +5 -0
  166. package/dist/json/layers/index.js.map +1 -0
  167. package/dist/json/rewriteGeoArrowAccessors.d.ts +7 -0
  168. package/dist/json/rewriteGeoArrowAccessors.d.ts.map +1 -0
  169. package/dist/json/rewriteGeoArrowAccessors.js +55 -0
  170. package/dist/json/rewriteGeoArrowAccessors.js.map +1 -0
  171. package/dist/mapAiConfig.d.ts +111 -0
  172. package/dist/mapAiConfig.d.ts.map +1 -0
  173. package/dist/mapAiConfig.js +69 -0
  174. package/dist/mapAiConfig.js.map +1 -0
  175. package/dist/mapConfig.d.ts +73 -0
  176. package/dist/mapConfig.d.ts.map +1 -0
  177. package/dist/mapConfig.js +47 -0
  178. package/dist/mapConfig.js.map +1 -0
  179. package/dist/mapConfigUtils.d.ts +111 -0
  180. package/dist/mapConfigUtils.d.ts.map +1 -0
  181. package/dist/mapConfigUtils.js +502 -0
  182. package/dist/mapConfigUtils.js.map +1 -0
  183. package/dist/mapDataPolicy.d.ts +9 -0
  184. package/dist/mapDataPolicy.d.ts.map +1 -0
  185. package/dist/mapDataPolicy.js +25 -0
  186. package/dist/mapDataPolicy.js.map +1 -0
  187. package/dist/mapFit.d.ts +62 -0
  188. package/dist/mapFit.d.ts.map +1 -0
  189. package/dist/mapFit.js +325 -0
  190. package/dist/mapFit.js.map +1 -0
  191. package/dist/mapLayerConfigUtils.d.ts +54 -0
  192. package/dist/mapLayerConfigUtils.d.ts.map +1 -0
  193. package/dist/mapLayerConfigUtils.js +296 -0
  194. package/dist/mapLayerConfigUtils.js.map +1 -0
  195. package/dist/mapResourceAuthoring.d.ts +40 -0
  196. package/dist/mapResourceAuthoring.d.ts.map +1 -0
  197. package/dist/mapResourceAuthoring.js +266 -0
  198. package/dist/mapResourceAuthoring.js.map +1 -0
  199. package/dist/mosaic.d.ts +9 -0
  200. package/dist/mosaic.d.ts.map +1 -0
  201. package/dist/mosaic.js +8 -0
  202. package/dist/mosaic.js.map +1 -0
  203. package/dist/prepare/detectGeometryColumn.d.ts +19 -0
  204. package/dist/prepare/detectGeometryColumn.d.ts.map +1 -0
  205. package/dist/prepare/detectGeometryColumn.js +126 -0
  206. package/dist/prepare/detectGeometryColumn.js.map +1 -0
  207. package/dist/prepare/geoarrow.d.ts +18 -0
  208. package/dist/prepare/geoarrow.d.ts.map +1 -0
  209. package/dist/prepare/geoarrow.js +114 -0
  210. package/dist/prepare/geoarrow.js.map +1 -0
  211. package/dist/prepare/geometryDecoder.d.ts +8 -0
  212. package/dist/prepare/geometryDecoder.d.ts.map +1 -0
  213. package/dist/prepare/geometryDecoder.js +2 -0
  214. package/dist/prepare/geometryDecoder.js.map +1 -0
  215. package/dist/prepare/prepareDeckDataset.d.ts +57 -0
  216. package/dist/prepare/prepareDeckDataset.d.ts.map +1 -0
  217. package/dist/prepare/prepareDeckDataset.js +112 -0
  218. package/dist/prepare/prepareDeckDataset.js.map +1 -0
  219. package/dist/prepare/toGeoJsonBinary.d.ts +9 -0
  220. package/dist/prepare/toGeoJsonBinary.d.ts.map +1 -0
  221. package/dist/prepare/toGeoJsonBinary.js +26 -0
  222. package/dist/prepare/toGeoJsonBinary.js.map +1 -0
  223. package/dist/prepare/types.d.ts +25 -0
  224. package/dist/prepare/types.d.ts.map +1 -0
  225. package/dist/prepare/types.js +2 -0
  226. package/dist/prepare/types.js.map +1 -0
  227. package/dist/prepare/wkbDecoder.d.ts +3 -0
  228. package/dist/prepare/wkbDecoder.d.ts.map +1 -0
  229. package/dist/prepare/wkbDecoder.js +419 -0
  230. package/dist/prepare/wkbDecoder.js.map +1 -0
  231. package/dist/prepare/wkbParser.d.ts +24 -0
  232. package/dist/prepare/wkbParser.d.ts.map +1 -0
  233. package/dist/prepare/wkbParser.js +139 -0
  234. package/dist/prepare/wkbParser.js.map +1 -0
  235. package/dist/types.d.ts +92 -0
  236. package/dist/types.d.ts.map +1 -0
  237. package/dist/types.js +11 -0
  238. package/dist/types.js.map +1 -0
  239. package/dist/useDeckMapDatasetSchema.d.ts +33 -0
  240. package/dist/useDeckMapDatasetSchema.d.ts.map +1 -0
  241. package/dist/useDeckMapDatasetSchema.js +138 -0
  242. package/dist/useDeckMapDatasetSchema.js.map +1 -0
  243. package/dist/useDeckMapDatasets.d.ts +17 -0
  244. package/dist/useDeckMapDatasets.d.ts.map +1 -0
  245. package/dist/useDeckMapDatasets.js +69 -0
  246. package/dist/useDeckMapDatasets.js.map +1 -0
  247. package/dist/useDeckMapFitToBounds.d.ts +31 -0
  248. package/dist/useDeckMapFitToBounds.d.ts.map +1 -0
  249. package/dist/useDeckMapFitToBounds.js +58 -0
  250. package/dist/useDeckMapFitToBounds.js.map +1 -0
  251. package/package.json +98 -0
package/LICENSE.md ADDED
@@ -0,0 +1,10 @@
1
+ MIT License
2
+
3
+ Copyright 2024-2026 SQLRooms Contributors
4
+ Copyright Vis.gl contributors
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
7
+
8
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
9
+
10
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,654 @@
1
+ Deck.gl integration for SQLRooms with JSON-driven map specs, dataset registry
2
+ binding, DuckDB-backed or in-memory Arrow datasets, and GeoArrow-first geometry
3
+ preparation.
4
+
5
+ ## Map resources and dashboard adapters
6
+
7
+ Worksheet maps are first-class `deckMaps` resources. The root package export
8
+ contains the resource slice, renderer, settings, direct DuckDB data adapter,
9
+ and resource orchestration APIs. It does not require Mosaic.
10
+
11
+ Mosaic dashboard panel support is opt-in through `@sqlrooms/deck/mosaic`.
12
+ Dashboard panels keep their panel storage, query clients, cross-filter
13
+ selection, and issue translation inside that adapter boundary.
14
+
15
+ `DeckMapSettingsPanel` is the shared host-neutral editor for both surfaces. It
16
+ receives a map config, selected table, available tables, and edit callbacks;
17
+ worksheet resources and Mosaic panels only adapt their respective stores to
18
+ that contract. Layer, binding, style, extrusion, and code-view controls therefore
19
+ stay consistent without putting Mosaic APIs in the worksheet settings path.
20
+
21
+ Use `getDeckMapDataPolicy(...)` to resolve a map config into the exported
22
+ `DeckMapDataPolicy` runtime row-limit policy.
23
+
24
+ Worksheet map runtime issues distinguish dataset SQL failures (`sql-error`)
25
+ from fit-to-data bounds failures (`fit-error`), so each issue is cleared only
26
+ after its corresponding operation recovers.
27
+
28
+ `DeckMapDataAdapter.resolveFitDataset` can provide an unsampled source for
29
+ fit-to-data bounds queries. The direct adapter uses the authored source for
30
+ bounds while applying the configured row-limit policy only to rendered rows.
31
+
32
+ Worksheet maps deliberately use independent selection semantics. Their direct
33
+ data adapter executes each configured SQL/table dataset through the room's
34
+ DuckDB connector and neither reads nor publishes Mosaic selections. This drops
35
+ the old incidental intra-map cross-filtering between datasets; a future
36
+ host-neutral selection adapter can add that behavior without changing map
37
+ resource ownership.
38
+
39
+ ## Installation
40
+
41
+ ```bash
42
+ npm install @sqlrooms/deck @sqlrooms/duckdb @sqlrooms/ui
43
+ ```
44
+
45
+ ## What This Package Does
46
+
47
+ `@sqlrooms/deck` is the JSON-spec bridge between SQLRooms data and deck.gl:
48
+
49
+ - render a DeckGL map from a serializable `DeckJsonMap` spec
50
+ - bind one or more datasets through a `datasets` registry
51
+ - generate starter JSON specs from datasets with `createDeckJsonSpecFromDatasets`
52
+ - validate SQLRooms-specific layer bindings under `_sqlroomsBinding`
53
+ - prepare geometry for GeoArrow-native layers from
54
+ [`@geoarrow/deck.gl-geoarrow`](https://github.com/geoarrow/deck.gl-geoarrow)
55
+ and GeoJSON fallback layers
56
+ - support shared declarative color scales through `@sqlrooms/color-scales`
57
+
58
+ Use this package when you want deck.gl layers to be driven by a JSON-like spec
59
+ instead of hand-constructing deck layer instances in React code.
60
+
61
+ ## Quick Start
62
+
63
+ ```tsx
64
+ import {DeckJsonMap} from '@sqlrooms/deck';
65
+
66
+ const spec = {
67
+ initialViewState: {
68
+ longitude: -122.4,
69
+ latitude: 37.74,
70
+ zoom: 10,
71
+ pitch: 0,
72
+ bearing: 0,
73
+ },
74
+ controller: true,
75
+ layers: [
76
+ {
77
+ '@@type': 'GeoArrowScatterplotLayer',
78
+ id: 'airports',
79
+ _sqlroomsBinding: {
80
+ dataset: 'airports',
81
+ geometryColumn: 'geom',
82
+ },
83
+ getFillColor: {
84
+ '@@function': 'colorScale',
85
+ field: 'scalerank',
86
+ type: 'sequential',
87
+ scheme: 'YlOrRd',
88
+ domain: 'auto',
89
+ },
90
+ getRadius: '@@=6',
91
+ radiusMinPixels: 2,
92
+ },
93
+ ],
94
+ };
95
+
96
+ export function AirportsMap() {
97
+ return (
98
+ <DeckJsonMap
99
+ spec={spec}
100
+ datasets={{
101
+ airports: {
102
+ sqlQuery:
103
+ 'SELECT name, abbrev, scalerank, ST_AsWKB(geom) AS geom FROM airports',
104
+ geometryColumn: 'geom',
105
+ geometryEncodingHint: 'wkb',
106
+ },
107
+ }}
108
+ mapStyle="https://basemaps.cartocdn.com/gl/positron-gl-style/style.json"
109
+ />
110
+ );
111
+ }
112
+ ```
113
+
114
+ ## Auto Spec Generation
115
+
116
+ If you want a starter JSON spec instead of writing every layer manually, use
117
+ `createDeckJsonSpecFromDatasets(...)`:
118
+
119
+ ```tsx
120
+ import {createDeckJsonSpecFromDatasets, DeckJsonMap} from '@sqlrooms/deck';
121
+
122
+ const datasets = {
123
+ earthquakes: {
124
+ arrowTable,
125
+ geometryColumn: 'geom',
126
+ geometryEncodingHint: 'wkb',
127
+ },
128
+ };
129
+
130
+ const spec = createDeckJsonSpecFromDatasets({datasets});
131
+ ```
132
+
133
+ By default, the helper is conservative:
134
+
135
+ - point / multipoint -> `GeoArrowScatterplotLayer`
136
+ - linestring / multilinestring -> `GeoArrowPathLayer`
137
+ - polygon / multipolygon -> `GeoArrowPolygonLayer`
138
+ - mixed, unknown, or unsupported -> `GeoJsonLayer`
139
+
140
+ You can provide semantic hints for special layers:
141
+
142
+ ```tsx
143
+ const spec = createDeckJsonSpecFromDatasets({
144
+ datasets,
145
+ hints: {
146
+ earthquakes: {prefer: 'heatmap'},
147
+ trips: {
148
+ type: 'GeoArrowTripsLayer',
149
+ timestampColumn: 'timestamps',
150
+ },
151
+ flows: {
152
+ type: 'GeoArrowArcLayer',
153
+ sourceGeometryColumn: 'source_geom',
154
+ targetGeometryColumn: 'target_geom',
155
+ },
156
+ hexes: {
157
+ type: 'GeoArrowH3HexagonLayer',
158
+ hexagonColumn: 'h3',
159
+ },
160
+ },
161
+ });
162
+ ```
163
+
164
+ ## Mosaic Dashboard Renderer
165
+
166
+ `@sqlrooms/deck` can contribute a `deck-json-map` panel renderer to
167
+ `@sqlrooms/mosaic` dashboards without making the Mosaic package depend on
168
+ deck.gl or MapLibre. Pass the renderer when creating the Mosaic dashboard
169
+ slice.
170
+
171
+ The dashboard renderer exposes `DeckMapDashboardSettings` through its renderer
172
+ definition. `DeckMapBlockSettings` is also exported for block-document hosts
173
+ that embed maps as stateful blocks.
174
+
175
+ ```tsx
176
+ import {
177
+ createDeckMapDashboardPanelConfig,
178
+ DECK_MAP_DASHBOARD_PANEL_TYPE,
179
+ deckMapDashboardPanelRenderer,
180
+ } from '@sqlrooms/deck';
181
+ import {
182
+ createDefaultMosaicDashboardPanelRenderers,
183
+ createMosaicDashboardSlice,
184
+ MosaicDashboard,
185
+ } from '@sqlrooms/mosaic';
186
+
187
+ const dashboardSlice = createMosaicDashboardSlice({
188
+ panelRenderers: createDefaultMosaicDashboardPanelRenderers({
189
+ [DECK_MAP_DASHBOARD_PANEL_TYPE]: deckMapDashboardPanelRenderer,
190
+ }),
191
+ });
192
+
193
+ function Dashboard() {
194
+ return <MosaicDashboard dashboardId="geo" />;
195
+ }
196
+
197
+ const mapPanel = createDeckMapDashboardPanelConfig({
198
+ title: 'Earthquakes map',
199
+ spec: {
200
+ initialViewState: {longitude: -119.5, latitude: 37, zoom: 4.5},
201
+ layers: [
202
+ {
203
+ '@@type': 'GeoArrowScatterplotLayer',
204
+ id: 'earthquakes',
205
+ _sqlroomsBinding: {dataset: 'earthquakes'},
206
+ },
207
+ ],
208
+ },
209
+ datasets: {
210
+ earthquakes: {
211
+ source: {
212
+ sqlQuery:
213
+ 'SELECT *, ST_AsWKB(ST_Point(Longitude, Latitude)) AS geom FROM earthquakes',
214
+ },
215
+ geometryColumn: 'geom',
216
+ geometryEncodingHint: 'wkb',
217
+ },
218
+ },
219
+ fitToData: {
220
+ dataset: 'earthquakes',
221
+ longitudeColumn: 'Longitude',
222
+ latitudeColumn: 'Latitude',
223
+ padding: 40,
224
+ maxZoom: 12,
225
+ },
226
+ });
227
+ ```
228
+
229
+ The dashboard renderer uses `useMosaicClient`, receives Arrow tables directly,
230
+ and passes them to `DeckJsonMap` as Arrow-backed datasets. Dataset sources fall
231
+ back from dataset-level source, to panel source, to the dashboard selected
232
+ table. When `fitToData` is provided, the renderer asks DuckDB Spatial for the
233
+ dataset extent using the declared longitude/latitude columns and fits the
234
+ initial map view once, instead of inferring bounds from the loaded Arrow
235
+ payload in React.
236
+
237
+ Use `createDeckMapPanelFromNativeConfig(...)` when a host surface already has a
238
+ native Deck map config, for example from AI tooling, and needs the same
239
+ dashboard-compatible `deck-json-map` panel shape that the dashboard map tool
240
+ creates.
241
+
242
+ ### Config Mode
243
+
244
+ The optional `configMode` field (`'basic' | 'custom'`) on
245
+ `DeckMapDashboardPanelConfig` controls how the map was authored and what editing
246
+ UI is available:
247
+
248
+ - **`'basic'`** (default when absent) — the config uses only properties that the
249
+ settings panel can represent (layer type, color scale, radius, geometry
250
+ bindings). The UI settings panel is enabled for user tweaks.
251
+ - **`'custom'`** — the config may use any deck.gl JSON props, including those not
252
+ representable in the UI configurator. Dashboard and document map settings keep
253
+ the basic controls disabled so dataset or layer edits cannot rewrite the authored
254
+ config.
255
+
256
+ AI tools set this field automatically based on request complexity.
257
+
258
+ ## Embeddable Map Blocks
259
+
260
+ Host applications that expose document-like block surfaces can render maps
261
+ as durable resources without creating a dashboard. Compose
262
+ `createDeckMapsSlice()` into the room store, call
263
+ `ensureDeckMapResourceState(...)` for a durable map id, and render it with
264
+ `DeckMapBlockRenderer`.
265
+
266
+ Runtime issue recovery can call `deckMaps.clearMapIssue(mapId, kind)` to clear
267
+ only a matching issue kind; omit `kind` when the map state should clear any
268
+ stale issue. Replacing a map config clears its prior render issue, while data
269
+ issues remain until the corresponding dataset recovery is reported.
270
+ Direct worksheet maps automatically fit the configured dataset when the map or
271
+ its source first becomes ready; the header action remains available for manual
272
+ refitting.
273
+
274
+ Hosts that expose direct worksheet-map AI capability should include
275
+ `getDeckMapResourceAiInstructions()` in the responsible agent and tool
276
+ instructions. `createOrUpdateDeckMapResource(...)` validates the fully merged
277
+ resource before any durable block or map write: each dataset needs a
278
+ `source.tableName` or `source.sqlQuery`, and each layer needs an explicit
279
+ `_sqlroomsBinding.dataset`. Use `mergeDeckMapResourceConfigPatch(...)` in host
280
+ preparation so sparse updates retain durable dataset sources and layers.
281
+ Pass `{replaceLayers: true}` when the incoming `spec.layers` array is the
282
+ complete desired list and omitted existing layers should be removed; the
283
+ default remains additive for sparse layer updates.
284
+ Pass `{replaceDatasets: true}` when the incoming `datasets` object is the
285
+ complete desired registry and omitted existing datasets should be removed; use
286
+ both flags when replacing a complete multi-dataset layer set.
287
+
288
+ `createDeckMapBlockDocumentType(...)` and
289
+ `createDeckMapBlockDocumentCommandType(...)` provide the reusable registration
290
+ metadata for block-document hosts. They register a `map` stateful block with
291
+ resizable height, scroll-modifier behavior, map settings, and owned state
292
+ creation wired through `ensureDeckMapResourceState(...)`:
293
+
294
+ ```ts
295
+ import {
296
+ createDeckMapBlockDocumentCommandType,
297
+ createDeckMapBlockDocumentType,
298
+ } from '@sqlrooms/deck';
299
+
300
+ const mapBlockType = createDeckMapBlockDocumentType({
301
+ getState: () => roomStore.getState(),
302
+ defaultTitle: 'Embedded Map',
303
+ });
304
+
305
+ const mapCommandType = createDeckMapBlockDocumentCommandType({
306
+ defaultTitle: 'Embedded Map',
307
+ });
308
+ ```
309
+
310
+ Hosts still own renderer registration, deletion cleanup, and product-specific
311
+ side effects. Use `afterEnsureState` for app-local metadata updates after the
312
+ map resource is created.
313
+
314
+ `createOrUpdateDeckMapResource(...)` is the durable orchestration helper for
315
+ commands and AI tools. It uses only resource and block callbacks:
316
+
317
+ ```ts
318
+ import {createOrUpdateDeckMapResource} from '@sqlrooms/deck';
319
+
320
+ const result = await createOrUpdateDeckMapResource(
321
+ {
322
+ ensureBlockDocument,
323
+ findMapBlock,
324
+ findMap,
325
+ createMapBlock,
326
+ updateBlockMetadata,
327
+ ensureMap,
328
+ writeMap,
329
+ findTable,
330
+ prepareConfig,
331
+ },
332
+ {
333
+ blockDocumentId,
334
+ mapId,
335
+ config,
336
+ tableName,
337
+ title,
338
+ intent,
339
+ },
340
+ );
341
+ ```
342
+
343
+ On create, callers must provide either `mapId` or `createMapId`. On update, the
344
+ default behavior is intentionally strict: missing map blocks and SQL-only
345
+ dataset sources without a resolvable `tableName` throw so command paths do not
346
+ silently retarget stale IDs. AI create flows can opt into
347
+ `missingMapBlockBehavior: 'create'`; a supplied `mapId` is retained, with
348
+ `createMapId` used only as its fallback.
349
+
350
+ Title handling is conservative for Ask AI edits: when `title` is omitted,
351
+ `createOrUpdateDeckMapResource(...)` preserves the existing non-blank block
352
+ caption or resource title. Passing an explicit `title` updates the durable map
353
+ title and uses it as the default block caption. Block metadata is written only
354
+ after the map write succeeds.
355
+
356
+ Map authoring helpers such as `normalizeDeckMapPointConfig(...)`,
357
+ `normalizeDeckMapFillColor(...)`, `regenerateMapConfigForTable(...)`, and
358
+ dataset-source helpers such as `getFirstDatasetSourceTableName(...)` are
359
+ exported so hosts can normalize AI-authored configs before calling
360
+ `createOrUpdateDeckMapResource(...)`. `normalizeDeckMapPointConfig(...)` only adds
361
+ the standard lon/lat point transform to table-backed datasets that do not
362
+ already declare `geometryColumn`, `source.sqlQuery`, or `source.transformSql`
363
+ and whose resolved table does not expose a native geometry column; native
364
+ geometry, polygon, line, and pre-transformed datasets are preserved.
365
+ When regenerating a map with one existing dataset, its dataset ID is retained
366
+ and geometry bindings are refreshed so custom layers continue to address the
367
+ same dataset after a table switch. Non-geospatial tables and multi-dataset maps
368
+ return the existing config unchanged so callers can keep the current selection
369
+ when a safe target cannot be inferred. Maps without datasets adopt the generated
370
+ dataset and layer spec after a valid table is selected.
371
+
372
+ ## Core Concepts
373
+
374
+ ### `DeckJsonMap`
375
+
376
+ `DeckJsonMap` is the main React component exported by this package. It takes:
377
+
378
+ - `spec`: a JSON-like deck.gl spec object or JSON string
379
+ - `datasets`: a dataset registry keyed by dataset id
380
+ - `interleaved`: when true, deck layers render in MapLibre's own WebGL context instead of a separate overlay canvas. This halves the number of WebGL contexts per map panel (from 2 to 1), which matters because browsers limit active contexts to ~8–16 per page. Default: `true`
381
+ - `deckProps`: runtime-only deck props such as `getTooltip`, `onHover`, `onClick`
382
+ - `mapProps`: runtime-only MapLibre props
383
+ - `showLegends`: whether SQLRooms-generated color legends should render
384
+
385
+ `spec` stays serializable; callbacks and runtime behavior belong in `deckProps`
386
+ or `mapProps`.
387
+
388
+ By default, deck.gl renders interleaved into MapLibre's layer stack, sharing a
389
+ single WebGL context. This allows deck layers to be inserted between basemap
390
+ layers (e.g. render points under map labels) and reduces WebGL context usage.
391
+ Set `interleaved` to `false` to render deck layers in a separate overlay canvas
392
+ on top of all basemap layers (uses an additional WebGL context per map).
393
+
394
+ ```tsx
395
+ {
396
+ /* Default (interleaved): */
397
+ }
398
+ <DeckJsonMap spec={spec} datasets={datasets} />;
399
+
400
+ {
401
+ /* Opt out to separate overlay canvas: */
402
+ }
403
+ <DeckJsonMap spec={spec} datasets={datasets} interleaved={false} />;
404
+ ```
405
+
406
+ ### Dataset Registry
407
+
408
+ Each SQLRooms-managed layer binds to exactly one dataset through
409
+ `_sqlroomsBinding.dataset`.
410
+
411
+ ```tsx
412
+ <DeckJsonMap
413
+ spec={spec}
414
+ datasets={{
415
+ earthquakes: {tableName: 'earthquakes'},
416
+ faults: {tableName: 'faults'},
417
+ }}
418
+ />
419
+ ```
420
+
421
+ Dataset ids are layer-binding labels. Internally, prepared geometry is cached
422
+ by the resolved data identity, not by dataset id, so multiple maps or layers
423
+ can reuse the same preparation work when they point at the same table/query.
424
+
425
+ ### Dataset Input Kinds
426
+
427
+ Each dataset entry is one of:
428
+
429
+ ```tsx
430
+ datasets={{
431
+ airports: {
432
+ sqlQuery: 'SELECT * FROM airports',
433
+ geometryColumn: 'geom',
434
+ geometryEncodingHint: 'wkb',
435
+ },
436
+ earthquakePoints: {
437
+ tableName: 'earthquakes',
438
+ transformSql: `
439
+ SELECT *, ST_AsWKB(ST_Point(longitude, latitude)) AS geom
440
+ FROM __sqlrooms_source
441
+ WHERE longitude IS NOT NULL AND latitude IS NOT NULL
442
+ `,
443
+ geometryColumn: 'geom',
444
+ geometryEncodingHint: 'wkb',
445
+ },
446
+ faults: {
447
+ tableName: 'faults',
448
+ geometryColumn: 'geom',
449
+ geometryEncodingHint: 'wkb',
450
+ },
451
+ preview: {
452
+ arrowTable,
453
+ geometryColumn: 'geom',
454
+ geometryEncodingHint: 'wkb',
455
+ },
456
+ }}
457
+ ```
458
+
459
+ - `sqlQuery`
460
+ Runs a standalone literal query through the DuckDB slice execution path. This
461
+ query is not rewritten by dashboard table selection.
462
+ - `tableName`
463
+ Reads directly from a table or schema-qualified table reference.
464
+ - `tableName` + `transformSql`
465
+ Reads a structured table source through a SQL transform. `transformSql` must
466
+ be a complete `SELECT` statement that reads from SQLRooms' reserved
467
+ `__sqlrooms_source` relation. SQLRooms binds that relation to the quoted
468
+ `tableName` at execution time, so dashboards can swap the table source
469
+ without editing authored SQL.
470
+ - `arrowTable`
471
+ Uses an already available Apache Arrow table. This is the right input for
472
+ Arrow-native SQLRooms hooks such as `useSql` and `useMosaicClient`.
473
+
474
+ For in-memory Arrow datasets, `arrowTable` may be temporarily `undefined` while
475
+ data is still loading. `DeckJsonMap` will keep rendering the basemap and treat
476
+ that dataset as loading until a table is provided.
477
+
478
+ Use `onDatasetStatesChange` when the surrounding UI needs dataset loading,
479
+ ready, or error state:
480
+
481
+ ```tsx
482
+ <DeckJsonMap
483
+ spec={spec}
484
+ datasets={datasets}
485
+ onDatasetStatesChange={(states) => setDatasetStates(states)}
486
+ />
487
+ ```
488
+
489
+ ## SQLRooms Layer Bindings
490
+
491
+ SQLRooms-specific layer metadata lives under `_sqlroomsBinding`:
492
+
493
+ ```tsx
494
+ {
495
+ '@@type': 'GeoArrowScatterplotLayer',
496
+ id: 'earthquakes',
497
+ _sqlroomsBinding: {
498
+ dataset: 'earthquakes',
499
+ geometryColumn: 'geom',
500
+ geometryEncodingHint: 'wkb',
501
+ },
502
+ getFillColor: {
503
+ '@@function': 'colorScale',
504
+ field: 'Magnitude',
505
+ type: 'sequential',
506
+ scheme: 'YlOrRd',
507
+ domain: 'auto',
508
+ },
509
+ }
510
+ ```
511
+
512
+ Currently supported SQLRooms binding fields are:
513
+
514
+ - `dataset`: binds the layer to one dataset id
515
+ - `geometryColumn`: overrides geometry column detection for that layer
516
+ - `geometryEncodingHint`: helps geometry detection when the source table needs it
517
+ - `sourceGeometryColumn`: source point geometry for `GeoArrowArcLayer`
518
+ - `targetGeometryColumn`: target point geometry for `GeoArrowArcLayer`
519
+ - `timestampColumn`: timestamp list column for `GeoArrowTripsLayer`
520
+ - `hexagonColumn`: H3 index column for `GeoArrowH3HexagonLayer`
521
+
522
+ The surrounding deck spec remains intentionally loose so normal deck.gl JSON
523
+ props still pass through, while `_sqlroomsBinding` is validated strictly.
524
+
525
+ ## Color Scales and Legends
526
+
527
+ You can ask SQLRooms to derive colors from a field with the
528
+ `colorScale` JSON function instead of writing long `@@=` color
529
+ expressions:
530
+
531
+ ```tsx
532
+ getFillColor: {
533
+ '@@function': 'colorScale',
534
+ field: 'Magnitude',
535
+ type: 'sequential',
536
+ scheme: 'YlOrRd',
537
+ domain: 'auto',
538
+ clamp: true,
539
+ }
540
+ ```
541
+
542
+ Discrete numeric palettes are supported too:
543
+
544
+ ```tsx
545
+ getFillColor: {
546
+ '@@function': 'colorScale',
547
+ field: 'Magnitude',
548
+ type: 'quantize',
549
+ scheme: 'PuBuGn',
550
+ domain: [0, 8],
551
+ bins: 5,
552
+ }
553
+ ```
554
+
555
+ `DeckJsonMap` renders SQLRooms-generated legends by default for layers that use
556
+ `colorScale`. To disable them globally:
557
+
558
+ ```tsx
559
+ <DeckJsonMap spec={spec} datasets={datasets} showLegends={false} />
560
+ ```
561
+
562
+ To override the title:
563
+
564
+ ```tsx
565
+ getFillColor: {
566
+ '@@function': 'colorScale',
567
+ field: 'Magnitude',
568
+ type: 'sequential',
569
+ scheme: 'YlOrRd',
570
+ domain: 'auto',
571
+ legend: {
572
+ title: 'Magnitude (Mw)',
573
+ },
574
+ }
575
+ ```
576
+
577
+ Supported scale types come from `@sqlrooms/color-scales`:
578
+
579
+ - `sequential`
580
+ - `diverging`
581
+ - `quantize`
582
+ - `quantile`
583
+ - `threshold`
584
+ - `categorical`
585
+
586
+ When `domain` is set to `'auto'`, the domain is computed from the currently
587
+ bound dataset, so colors may shift as filters change. Use explicit domains when
588
+ you want colors to stay stable across filtering.
589
+
590
+ ## Geometry Preparation
591
+
592
+ `prepareDeckDataset(...)` is the deck-specific preparation step behind the
593
+ scenes. It accepts resolved Arrow tables with geometry stored as:
594
+
595
+ - native GeoArrow
596
+ - WKB / GeoArrow WKB
597
+ - WKT / GeoArrow WKT
598
+
599
+ It then produces canonical deck-facing geometry outputs for:
600
+
601
+ - GeoArrow-native layers such as `GeoArrowScatterplotLayer`
602
+ - GeoJSON-binary fallback layers such as `GeoJsonLayer`
603
+
604
+ Specialized layers such as `GeoArrowArcLayer`, `GeoArrowTripsLayer`, and
605
+ `GeoArrowH3HexagonLayer` reuse the prepared table but bind additional
606
+ configured columns on top for source/target geometry,
607
+ timestamps, or index cells.
608
+
609
+ This work is cached internally in a module-global prepared dataset store. That
610
+ cache is separate from any upstream query cache:
611
+
612
+ - Mosaic-driven queries already benefit from Mosaic's own query cache
613
+ - DuckDB SQL datasets still use the DuckDB slice execution path
614
+
615
+ Deck caches only the expensive geometry preparation layer on top.
616
+
617
+ ## Supported Layers
618
+
619
+ The current curated layer set is:
620
+
621
+ - `GeoArrowScatterplotLayer`
622
+ - `GeoArrowHeatmapLayer`
623
+ - `GeoArrowColumnLayer`
624
+ - `GeoArrowPathLayer`
625
+ - `GeoArrowPolygonLayer`
626
+ - `GeoArrowSolidPolygonLayer`
627
+ - `GeoArrowArcLayer`
628
+ - `GeoArrowTripsLayer`
629
+ - `GeoArrowH3HexagonLayer`
630
+ - `GeoJsonLayer`
631
+
632
+ GeoArrow-native geometry columns are the efficient path. WKB/WKT geometry falls
633
+ back to decoding and GeoJSON-binary preparation, with promotion available
634
+ for point-focused GeoArrow layers such as `GeoArrowScatterplotLayer`,
635
+ `GeoArrowHeatmapLayer`, and `GeoArrowColumnLayer`, plus polygon promotion for
636
+ `GeoArrowPolygonLayer` and `GeoArrowSolidPolygonLayer`.
637
+
638
+ The GeoArrow layer implementations themselves come from
639
+ [`@geoarrow/deck.gl-geoarrow`](https://github.com/geoarrow/deck.gl-geoarrow).
640
+
641
+ When querying DuckDB spatial `GEOMETRY` columns directly, convert them first
642
+ with `ST_AsWKB(...)` or `ST_AsText(...)`. DuckDB's internal geometry payload is
643
+ not the same as standard WKB.
644
+
645
+ ## Runtime Props and Children
646
+
647
+ Keep the spec serializable, then pass runtime behavior separately:
648
+
649
+ - `deckProps` for deck callbacks such as `getTooltip`, `onHover`, `onClick`
650
+ - `mapProps` for MapLibre props such as `projection`
651
+ - `children` for controls, overlays, and popups rendered inside the map
652
+
653
+ This lets the spec stay stable for storage, validation, and future AI-assisted
654
+ generation while still supporting interactive React behavior at runtime.
@@ -0,0 +1,3 @@
1
+ import { type BlockSettingsComponentProps } from '@sqlrooms/documents';
2
+ export declare function DeckMapBlockSettings({ blockId, dashboardId, blockInstanceId, onClose, readOnly, }: BlockSettingsComponentProps): import("react/jsx-runtime").JSX.Element;
3
+ //# sourceMappingURL=BlockMapSettings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BlockMapSettings.d.ts","sourceRoot":"","sources":["../src/BlockMapSettings.tsx"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,2BAA2B,EAEjC,MAAM,qBAAqB,CAAC;AAS7B,wBAAgB,oBAAoB,CAAC,EACnC,OAAO,EACP,WAAW,EACX,eAAe,EACf,OAAO,EACP,QAAQ,GACT,EAAE,2BAA2B,2CA0G7B"}