@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.
- package/LICENSE.md +10 -0
- package/README.md +654 -0
- package/dist/BlockMapSettings.d.ts +3 -0
- package/dist/BlockMapSettings.d.ts.map +1 -0
- package/dist/BlockMapSettings.js +57 -0
- package/dist/BlockMapSettings.js.map +1 -0
- package/dist/DashboardMapSettings.d.ts +7 -0
- package/dist/DashboardMapSettings.d.ts.map +1 -0
- package/dist/DashboardMapSettings.js +52 -0
- package/dist/DashboardMapSettings.js.map +1 -0
- package/dist/DeckJsonMap.d.ts +4 -0
- package/dist/DeckJsonMap.d.ts.map +1 -0
- package/dist/DeckJsonMap.js +370 -0
- package/dist/DeckJsonMap.js.map +1 -0
- package/dist/DeckJsonMapSpec.d.ts +7617 -0
- package/dist/DeckJsonMapSpec.d.ts.map +1 -0
- package/dist/DeckJsonMapSpec.js +82 -0
- package/dist/DeckJsonMapSpec.js.map +1 -0
- package/dist/DeckMapDefaultStylesProvider.d.ts +28 -0
- package/dist/DeckMapDefaultStylesProvider.d.ts.map +1 -0
- package/dist/DeckMapDefaultStylesProvider.js +23 -0
- package/dist/DeckMapDefaultStylesProvider.js.map +1 -0
- package/dist/DeckMapSurface.d.ts +39 -0
- package/dist/DeckMapSurface.d.ts.map +1 -0
- package/dist/DeckMapSurface.js +137 -0
- package/dist/DeckMapSurface.js.map +1 -0
- package/dist/DeckMapsSlice.d.ts +99 -0
- package/dist/DeckMapsSlice.d.ts.map +1 -0
- package/dist/DeckMapsSlice.js +89 -0
- package/dist/DeckMapsSlice.js.map +1 -0
- package/dist/MapSettings.d.ts +16 -0
- package/dist/MapSettings.d.ts.map +1 -0
- package/dist/MapSettings.js +292 -0
- package/dist/MapSettings.js.map +1 -0
- package/dist/MapSettingsControls.d.ts +40 -0
- package/dist/MapSettingsControls.d.ts.map +1 -0
- package/dist/MapSettingsControls.js +54 -0
- package/dist/MapSettingsControls.js.map +1 -0
- package/dist/ai.d.ts +261 -0
- package/dist/ai.d.ts.map +1 -0
- package/dist/ai.js +392 -0
- package/dist/ai.js.map +1 -0
- package/dist/block.d.ts +21 -0
- package/dist/block.d.ts.map +1 -0
- package/dist/block.js +105 -0
- package/dist/block.js.map +1 -0
- package/dist/blockDocumentRegistration.d.ts +45 -0
- package/dist/blockDocumentRegistration.d.ts.map +1 -0
- package/dist/blockDocumentRegistration.js +68 -0
- package/dist/blockDocumentRegistration.js.map +1 -0
- package/dist/createDeckJsonSpecFromDatasets.d.ts +11 -0
- package/dist/createDeckJsonSpecFromDatasets.d.ts.map +1 -0
- package/dist/createDeckJsonSpecFromDatasets.js +85 -0
- package/dist/createDeckJsonSpecFromDatasets.js.map +1 -0
- package/dist/createOrUpdateDeckMapResource.d.ts +81 -0
- package/dist/createOrUpdateDeckMapResource.d.ts.map +1 -0
- package/dist/createOrUpdateDeckMapResource.js +82 -0
- package/dist/createOrUpdateDeckMapResource.js.map +1 -0
- package/dist/dashboard.d.ts +6 -0
- package/dist/dashboard.d.ts.map +1 -0
- package/dist/dashboard.js +337 -0
- package/dist/dashboard.js.map +1 -0
- package/dist/dashboardConfig.d.ts +25 -0
- package/dist/dashboardConfig.d.ts.map +1 -0
- package/dist/dashboardConfig.js +82 -0
- package/dist/dashboardConfig.js.map +1 -0
- package/dist/dashboardIntegration.d.ts +3 -0
- package/dist/dashboardIntegration.d.ts.map +1 -0
- package/dist/dashboardIntegration.js +16 -0
- package/dist/dashboardIntegration.js.map +1 -0
- package/dist/datasetSourceUtils.d.ts +16 -0
- package/dist/datasetSourceUtils.d.ts.map +1 -0
- package/dist/datasetSourceUtils.js +25 -0
- package/dist/datasetSourceUtils.js.map +1 -0
- package/dist/datasets/PreparedDatasetStore.d.ts +120 -0
- package/dist/datasets/PreparedDatasetStore.d.ts.map +1 -0
- package/dist/datasets/PreparedDatasetStore.js +268 -0
- package/dist/datasets/PreparedDatasetStore.js.map +1 -0
- package/dist/datasets/helpers.d.ts +57 -0
- package/dist/datasets/helpers.d.ts.map +1 -0
- package/dist/datasets/helpers.js +155 -0
- package/dist/datasets/helpers.js.map +1 -0
- package/dist/datasets/normalizeDatasets.d.ts +11 -0
- package/dist/datasets/normalizeDatasets.d.ts.map +1 -0
- package/dist/datasets/normalizeDatasets.js +50 -0
- package/dist/datasets/normalizeDatasets.js.map +1 -0
- package/dist/datasets/tableAdapter.d.ts +11 -0
- package/dist/datasets/tableAdapter.d.ts.map +1 -0
- package/dist/datasets/tableAdapter.js +11 -0
- package/dist/datasets/tableAdapter.js.map +1 -0
- package/dist/datasets/tableDatasetSql.d.ts +16 -0
- package/dist/datasets/tableDatasetSql.d.ts.map +1 -0
- package/dist/datasets/tableDatasetSql.js +49 -0
- package/dist/datasets/tableDatasetSql.js.map +1 -0
- package/dist/datasets/types.d.ts +40 -0
- package/dist/datasets/types.d.ts.map +1 -0
- package/dist/datasets/types.js +2 -0
- package/dist/datasets/types.js.map +1 -0
- package/dist/datasets/usePreparedDatasetStates.d.ts +16 -0
- package/dist/datasets/usePreparedDatasetStates.d.ts.map +1 -0
- package/dist/datasets/usePreparedDatasetStates.js +59 -0
- package/dist/datasets/usePreparedDatasetStates.js.map +1 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -0
- package/dist/json/aggregateWaypoints.d.ts +14 -0
- package/dist/json/aggregateWaypoints.d.ts.map +1 -0
- package/dist/json/aggregateWaypoints.js +190 -0
- package/dist/json/aggregateWaypoints.js.map +1 -0
- package/dist/json/colorScaleFunction.d.ts +27 -0
- package/dist/json/colorScaleFunction.d.ts.map +1 -0
- package/dist/json/colorScaleFunction.js +46 -0
- package/dist/json/colorScaleFunction.js.map +1 -0
- package/dist/json/compileColorScale.d.ts +12 -0
- package/dist/json/compileColorScale.d.ts.map +1 -0
- package/dist/json/compileColorScale.js +125 -0
- package/dist/json/compileColorScale.js.map +1 -0
- package/dist/json/compileGeoArrowAccessor.d.ts +18 -0
- package/dist/json/compileGeoArrowAccessor.d.ts.map +1 -0
- package/dist/json/compileGeoArrowAccessor.js +129 -0
- package/dist/json/compileGeoArrowAccessor.js.map +1 -0
- package/dist/json/createDeckJsonConfiguration.d.ts +9 -0
- package/dist/json/createDeckJsonConfiguration.d.ts.map +1 -0
- package/dist/json/createDeckJsonConfiguration.js +315 -0
- package/dist/json/createDeckJsonConfiguration.js.map +1 -0
- package/dist/json/defaultClasses.d.ts +12 -0
- package/dist/json/defaultClasses.d.ts.map +1 -0
- package/dist/json/defaultClasses.js +35 -0
- package/dist/json/defaultClasses.js.map +1 -0
- package/dist/json/extractColorScaleLegends.d.ts +8 -0
- package/dist/json/extractColorScaleLegends.d.ts.map +1 -0
- package/dist/json/extractColorScaleLegends.js +86 -0
- package/dist/json/extractColorScaleLegends.js.map +1 -0
- package/dist/json/heatmapDefaults.d.ts +8 -0
- package/dist/json/heatmapDefaults.d.ts.map +1 -0
- package/dist/json/heatmapDefaults.js +14 -0
- package/dist/json/heatmapDefaults.js.map +1 -0
- package/dist/json/layerCompatibility.d.ts +21 -0
- package/dist/json/layerCompatibility.d.ts.map +1 -0
- package/dist/json/layerCompatibility.js +168 -0
- package/dist/json/layerCompatibility.js.map +1 -0
- package/dist/json/layerConfig.d.ts +14 -0
- package/dist/json/layerConfig.d.ts.map +1 -0
- package/dist/json/layerConfig.js +54 -0
- package/dist/json/layerConfig.js.map +1 -0
- package/dist/json/layers/DeckColumnLayer.d.ts +10 -0
- package/dist/json/layers/DeckColumnLayer.d.ts.map +1 -0
- package/dist/json/layers/DeckColumnLayer.js +26 -0
- package/dist/json/layers/DeckColumnLayer.js.map +1 -0
- package/dist/json/layers/DeckH3HexagonLayer.d.ts +37 -0
- package/dist/json/layers/DeckH3HexagonLayer.d.ts.map +1 -0
- package/dist/json/layers/DeckH3HexagonLayer.js +118 -0
- package/dist/json/layers/DeckH3HexagonLayer.js.map +1 -0
- package/dist/json/layers/DeckTripsLayer.d.ts +46 -0
- package/dist/json/layers/DeckTripsLayer.d.ts.map +1 -0
- package/dist/json/layers/DeckTripsLayer.js +170 -0
- package/dist/json/layers/DeckTripsLayer.js.map +1 -0
- package/dist/json/layers/createTableToRecordBatchAdapter.d.ts +20 -0
- package/dist/json/layers/createTableToRecordBatchAdapter.d.ts.map +1 -0
- package/dist/json/layers/createTableToRecordBatchAdapter.js +81 -0
- package/dist/json/layers/createTableToRecordBatchAdapter.js.map +1 -0
- package/dist/json/layers/index.d.ts +5 -0
- package/dist/json/layers/index.d.ts.map +1 -0
- package/dist/json/layers/index.js +5 -0
- package/dist/json/layers/index.js.map +1 -0
- package/dist/json/rewriteGeoArrowAccessors.d.ts +7 -0
- package/dist/json/rewriteGeoArrowAccessors.d.ts.map +1 -0
- package/dist/json/rewriteGeoArrowAccessors.js +55 -0
- package/dist/json/rewriteGeoArrowAccessors.js.map +1 -0
- package/dist/mapAiConfig.d.ts +111 -0
- package/dist/mapAiConfig.d.ts.map +1 -0
- package/dist/mapAiConfig.js +69 -0
- package/dist/mapAiConfig.js.map +1 -0
- package/dist/mapConfig.d.ts +73 -0
- package/dist/mapConfig.d.ts.map +1 -0
- package/dist/mapConfig.js +47 -0
- package/dist/mapConfig.js.map +1 -0
- package/dist/mapConfigUtils.d.ts +111 -0
- package/dist/mapConfigUtils.d.ts.map +1 -0
- package/dist/mapConfigUtils.js +502 -0
- package/dist/mapConfigUtils.js.map +1 -0
- package/dist/mapDataPolicy.d.ts +9 -0
- package/dist/mapDataPolicy.d.ts.map +1 -0
- package/dist/mapDataPolicy.js +25 -0
- package/dist/mapDataPolicy.js.map +1 -0
- package/dist/mapFit.d.ts +62 -0
- package/dist/mapFit.d.ts.map +1 -0
- package/dist/mapFit.js +325 -0
- package/dist/mapFit.js.map +1 -0
- package/dist/mapLayerConfigUtils.d.ts +54 -0
- package/dist/mapLayerConfigUtils.d.ts.map +1 -0
- package/dist/mapLayerConfigUtils.js +296 -0
- package/dist/mapLayerConfigUtils.js.map +1 -0
- package/dist/mapResourceAuthoring.d.ts +40 -0
- package/dist/mapResourceAuthoring.d.ts.map +1 -0
- package/dist/mapResourceAuthoring.js +266 -0
- package/dist/mapResourceAuthoring.js.map +1 -0
- package/dist/mosaic.d.ts +9 -0
- package/dist/mosaic.d.ts.map +1 -0
- package/dist/mosaic.js +8 -0
- package/dist/mosaic.js.map +1 -0
- package/dist/prepare/detectGeometryColumn.d.ts +19 -0
- package/dist/prepare/detectGeometryColumn.d.ts.map +1 -0
- package/dist/prepare/detectGeometryColumn.js +126 -0
- package/dist/prepare/detectGeometryColumn.js.map +1 -0
- package/dist/prepare/geoarrow.d.ts +18 -0
- package/dist/prepare/geoarrow.d.ts.map +1 -0
- package/dist/prepare/geoarrow.js +114 -0
- package/dist/prepare/geoarrow.js.map +1 -0
- package/dist/prepare/geometryDecoder.d.ts +8 -0
- package/dist/prepare/geometryDecoder.d.ts.map +1 -0
- package/dist/prepare/geometryDecoder.js +2 -0
- package/dist/prepare/geometryDecoder.js.map +1 -0
- package/dist/prepare/prepareDeckDataset.d.ts +57 -0
- package/dist/prepare/prepareDeckDataset.d.ts.map +1 -0
- package/dist/prepare/prepareDeckDataset.js +112 -0
- package/dist/prepare/prepareDeckDataset.js.map +1 -0
- package/dist/prepare/toGeoJsonBinary.d.ts +9 -0
- package/dist/prepare/toGeoJsonBinary.d.ts.map +1 -0
- package/dist/prepare/toGeoJsonBinary.js +26 -0
- package/dist/prepare/toGeoJsonBinary.js.map +1 -0
- package/dist/prepare/types.d.ts +25 -0
- package/dist/prepare/types.d.ts.map +1 -0
- package/dist/prepare/types.js +2 -0
- package/dist/prepare/types.js.map +1 -0
- package/dist/prepare/wkbDecoder.d.ts +3 -0
- package/dist/prepare/wkbDecoder.d.ts.map +1 -0
- package/dist/prepare/wkbDecoder.js +419 -0
- package/dist/prepare/wkbDecoder.js.map +1 -0
- package/dist/prepare/wkbParser.d.ts +24 -0
- package/dist/prepare/wkbParser.d.ts.map +1 -0
- package/dist/prepare/wkbParser.js +139 -0
- package/dist/prepare/wkbParser.js.map +1 -0
- package/dist/types.d.ts +92 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +11 -0
- package/dist/types.js.map +1 -0
- package/dist/useDeckMapDatasetSchema.d.ts +33 -0
- package/dist/useDeckMapDatasetSchema.d.ts.map +1 -0
- package/dist/useDeckMapDatasetSchema.js +138 -0
- package/dist/useDeckMapDatasetSchema.js.map +1 -0
- package/dist/useDeckMapDatasets.d.ts +17 -0
- package/dist/useDeckMapDatasets.d.ts.map +1 -0
- package/dist/useDeckMapDatasets.js +69 -0
- package/dist/useDeckMapDatasets.js.map +1 -0
- package/dist/useDeckMapFitToBounds.d.ts +31 -0
- package/dist/useDeckMapFitToBounds.d.ts.map +1 -0
- package/dist/useDeckMapFitToBounds.js +58 -0
- package/dist/useDeckMapFitToBounds.js.map +1 -0
- package/package.json +98 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
export const WKB_POINT = 1;
|
|
2
|
+
export const WKB_LINESTRING = 2;
|
|
3
|
+
export const WKB_POLYGON = 3;
|
|
4
|
+
export const WKB_MULTIPOLYGON = 6;
|
|
5
|
+
// Local WKB parser used until geoarrow-js ships WKB to GeoArrow parsing:
|
|
6
|
+
// See: https://github.com/geoarrow/geoarrow-js/issues/54
|
|
7
|
+
const WKB_BYTE_ORDER_BYTES = 1;
|
|
8
|
+
const WKB_GEOMETRY_TYPE_BYTES = 4;
|
|
9
|
+
const WKB_HEADER_BYTES = WKB_BYTE_ORDER_BYTES + WKB_GEOMETRY_TYPE_BYTES;
|
|
10
|
+
const WKB_GEOMETRY_TYPE_OFFSET = WKB_BYTE_ORDER_BYTES;
|
|
11
|
+
const WKB_SRID_BYTES = 4;
|
|
12
|
+
const WKB_UINT32_BYTES = 4;
|
|
13
|
+
const XY_COORDINATE_BYTES = 16;
|
|
14
|
+
const OPTIONAL_COORDINATE_DIMENSION_BYTES = 8;
|
|
15
|
+
const Y_COORDINATE_OFFSET_BYTES = 8;
|
|
16
|
+
// PostGIS EWKB stores Z/M/SRID metadata in the high bits
|
|
17
|
+
// of the WKB type word.
|
|
18
|
+
const EWKB_Z_FLAG = 0x80000000;
|
|
19
|
+
const EWKB_M_FLAG = 0x40000000;
|
|
20
|
+
const EWKB_SRID_FLAG = 0x20000000;
|
|
21
|
+
const ISO_WKB_TYPE_MASK = 0xffff;
|
|
22
|
+
const ISO_WKB_Z_OFFSET = 1000;
|
|
23
|
+
const ISO_WKB_M_OFFSET = 2000;
|
|
24
|
+
const ISO_WKB_ZM_OFFSET = 3000;
|
|
25
|
+
const ISO_WKB_MAX_BASE_TYPE = 7;
|
|
26
|
+
// Reads the shared WKB/EWKB prefix like byte order, geometry type, optional SRID
|
|
27
|
+
// and bytes per coordinate. Point/polygon readers use this to find their data.
|
|
28
|
+
export function parseWKBHeader(buf, startOffset = 0) {
|
|
29
|
+
if (buf.byteLength < startOffset + WKB_HEADER_BYTES)
|
|
30
|
+
return null;
|
|
31
|
+
const view = new DataView(buf);
|
|
32
|
+
const isLE = view.getUint8(startOffset) === 1;
|
|
33
|
+
const rawType = view.getUint32(startOffset + WKB_GEOMETRY_TYPE_OFFSET, isLE);
|
|
34
|
+
const isoType = rawType & ISO_WKB_TYPE_MASK;
|
|
35
|
+
const isoZ = hasIsoWKBTypeOffset(isoType, ISO_WKB_Z_OFFSET);
|
|
36
|
+
const isoM = hasIsoWKBTypeOffset(isoType, ISO_WKB_M_OFFSET);
|
|
37
|
+
const isoZM = hasIsoWKBTypeOffset(isoType, ISO_WKB_ZM_OFFSET);
|
|
38
|
+
const hasZ = (rawType & EWKB_Z_FLAG) !== 0 || isoZ || isoZM;
|
|
39
|
+
const hasM = (rawType & EWKB_M_FLAG) !== 0 || isoM || isoZM;
|
|
40
|
+
const hasSRID = (rawType & EWKB_SRID_FLAG) !== 0;
|
|
41
|
+
let base = isoType;
|
|
42
|
+
if (isoZM)
|
|
43
|
+
base -= ISO_WKB_ZM_OFFSET;
|
|
44
|
+
else if (isoM)
|
|
45
|
+
base -= ISO_WKB_M_OFFSET;
|
|
46
|
+
else if (isoZ)
|
|
47
|
+
base -= ISO_WKB_Z_OFFSET;
|
|
48
|
+
let offset = startOffset + WKB_HEADER_BYTES;
|
|
49
|
+
if (hasSRID)
|
|
50
|
+
offset += WKB_SRID_BYTES;
|
|
51
|
+
const coordBytes = XY_COORDINATE_BYTES +
|
|
52
|
+
(hasZ ? OPTIONAL_COORDINATE_DIMENSION_BYTES : 0) +
|
|
53
|
+
(hasM ? OPTIONAL_COORDINATE_DIMENSION_BYTES : 0);
|
|
54
|
+
return { view, isLE, geomType: base, offset, coordBytes };
|
|
55
|
+
}
|
|
56
|
+
export function readWKBPointXY(header) {
|
|
57
|
+
if (header.geomType !== WKB_POINT)
|
|
58
|
+
return null;
|
|
59
|
+
if (!hasBytes(header.view.buffer, header.offset, header.coordBytes)) {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
return [
|
|
63
|
+
header.view.getFloat64(header.offset, header.isLE),
|
|
64
|
+
header.view.getFloat64(header.offset + Y_COORDINATE_OFFSET_BYTES, header.isLE),
|
|
65
|
+
];
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Reads a WKB LineString and returns an array of [x, y] coordinate pairs.
|
|
69
|
+
*/
|
|
70
|
+
export function readWKBLineStringXY(buf, header) {
|
|
71
|
+
if (header.geomType !== WKB_LINESTRING)
|
|
72
|
+
return null;
|
|
73
|
+
const { view, isLE, offset: headerOffset, coordBytes } = header;
|
|
74
|
+
let offset = headerOffset;
|
|
75
|
+
if (!hasBytes(buf, offset, WKB_UINT32_BYTES))
|
|
76
|
+
return null;
|
|
77
|
+
const numPoints = view.getUint32(offset, isLE);
|
|
78
|
+
offset += WKB_UINT32_BYTES;
|
|
79
|
+
const coords = [];
|
|
80
|
+
for (let i = 0; i < numPoints; i++) {
|
|
81
|
+
if (!hasBytes(buf, offset, coordBytes))
|
|
82
|
+
return null;
|
|
83
|
+
const x = view.getFloat64(offset, isLE);
|
|
84
|
+
const y = view.getFloat64(offset + Y_COORDINATE_OFFSET_BYTES, isLE);
|
|
85
|
+
coords.push([x, y]);
|
|
86
|
+
offset += coordBytes;
|
|
87
|
+
}
|
|
88
|
+
return coords;
|
|
89
|
+
}
|
|
90
|
+
export function visitWKBPolygonCoordinates(buf, header, visitor) {
|
|
91
|
+
if (header.geomType !== WKB_POLYGON)
|
|
92
|
+
return null;
|
|
93
|
+
const { view, isLE, offset: headerOffset, coordBytes } = header;
|
|
94
|
+
let offset = headerOffset;
|
|
95
|
+
if (!hasBytes(buf, offset, WKB_UINT32_BYTES))
|
|
96
|
+
return null;
|
|
97
|
+
const numRings = view.getUint32(offset, isLE);
|
|
98
|
+
offset += WKB_UINT32_BYTES;
|
|
99
|
+
for (let ringIndex = 0; ringIndex < numRings; ringIndex++) {
|
|
100
|
+
visitor.onRingStart();
|
|
101
|
+
if (!hasBytes(buf, offset, WKB_UINT32_BYTES))
|
|
102
|
+
return null;
|
|
103
|
+
const numPoints = view.getUint32(offset, isLE);
|
|
104
|
+
offset += WKB_UINT32_BYTES;
|
|
105
|
+
for (let pointIndex = 0; pointIndex < numPoints; pointIndex++) {
|
|
106
|
+
if (!hasBytes(buf, offset, coordBytes))
|
|
107
|
+
return null;
|
|
108
|
+
visitor.onCoordinate(view.getFloat64(offset, isLE), view.getFloat64(offset + Y_COORDINATE_OFFSET_BYTES, isLE));
|
|
109
|
+
offset += coordBytes;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return offset <= buf.byteLength ? offset : null;
|
|
113
|
+
}
|
|
114
|
+
export function visitWKBMultiPolygonCoordinates(buf, header, visitor) {
|
|
115
|
+
if (header.geomType !== WKB_MULTIPOLYGON)
|
|
116
|
+
return false;
|
|
117
|
+
let offset = header.offset;
|
|
118
|
+
if (!hasBytes(buf, offset, WKB_UINT32_BYTES))
|
|
119
|
+
return false;
|
|
120
|
+
const numPolygons = header.view.getUint32(offset, header.isLE);
|
|
121
|
+
offset += WKB_UINT32_BYTES;
|
|
122
|
+
for (let polygonIndex = 0; polygonIndex < numPolygons; polygonIndex++) {
|
|
123
|
+
const polygonHeader = parseWKBHeader(buf, offset);
|
|
124
|
+
if (!polygonHeader || polygonHeader.geomType !== WKB_POLYGON)
|
|
125
|
+
return false;
|
|
126
|
+
const nextOffset = visitWKBPolygonCoordinates(buf, polygonHeader, visitor);
|
|
127
|
+
if (nextOffset == null)
|
|
128
|
+
return false;
|
|
129
|
+
offset = nextOffset;
|
|
130
|
+
}
|
|
131
|
+
return offset <= buf.byteLength;
|
|
132
|
+
}
|
|
133
|
+
function hasIsoWKBTypeOffset(isoType, offset) {
|
|
134
|
+
return isoType >= offset && isoType <= offset + ISO_WKB_MAX_BASE_TYPE;
|
|
135
|
+
}
|
|
136
|
+
function hasBytes(buf, offset, byteLength) {
|
|
137
|
+
return offset >= 0 && offset + byteLength <= buf.byteLength;
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=wkbParser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wkbParser.js","sourceRoot":"","sources":["../../src/prepare/wkbParser.ts"],"names":[],"mappings":"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","sourcesContent":["export const WKB_POINT = 1;\nexport const WKB_LINESTRING = 2;\nexport const WKB_POLYGON = 3;\nexport const WKB_MULTIPOLYGON = 6;\n\n// Local WKB parser used until geoarrow-js ships WKB to GeoArrow parsing:\n// See: https://github.com/geoarrow/geoarrow-js/issues/54\nconst WKB_BYTE_ORDER_BYTES = 1;\nconst WKB_GEOMETRY_TYPE_BYTES = 4;\nconst WKB_HEADER_BYTES = WKB_BYTE_ORDER_BYTES + WKB_GEOMETRY_TYPE_BYTES;\nconst WKB_GEOMETRY_TYPE_OFFSET = WKB_BYTE_ORDER_BYTES;\nconst WKB_SRID_BYTES = 4;\nconst WKB_UINT32_BYTES = 4;\nconst XY_COORDINATE_BYTES = 16;\nconst OPTIONAL_COORDINATE_DIMENSION_BYTES = 8;\nconst Y_COORDINATE_OFFSET_BYTES = 8;\n\n// PostGIS EWKB stores Z/M/SRID metadata in the high bits\n// of the WKB type word.\nconst EWKB_Z_FLAG = 0x80000000;\nconst EWKB_M_FLAG = 0x40000000;\nconst EWKB_SRID_FLAG = 0x20000000;\nconst ISO_WKB_TYPE_MASK = 0xffff;\nconst ISO_WKB_Z_OFFSET = 1000;\nconst ISO_WKB_M_OFFSET = 2000;\nconst ISO_WKB_ZM_OFFSET = 3000;\nconst ISO_WKB_MAX_BASE_TYPE = 7;\n\nexport type WKBHeader = {\n view: DataView;\n isLE: boolean;\n geomType: number;\n offset: number;\n coordBytes: number;\n};\n\nexport type WKBPolygonCoordinateVisitor = {\n onRingStart: () => void;\n onCoordinate: (x: number, y: number) => void;\n};\n\n// Reads the shared WKB/EWKB prefix like byte order, geometry type, optional SRID\n// and bytes per coordinate. Point/polygon readers use this to find their data.\nexport function parseWKBHeader(\n buf: ArrayBuffer,\n startOffset = 0,\n): WKBHeader | null {\n if (buf.byteLength < startOffset + WKB_HEADER_BYTES) return null;\n const view = new DataView(buf);\n const isLE = view.getUint8(startOffset) === 1;\n const rawType = view.getUint32(startOffset + WKB_GEOMETRY_TYPE_OFFSET, isLE);\n const isoType = rawType & ISO_WKB_TYPE_MASK;\n const isoZ = hasIsoWKBTypeOffset(isoType, ISO_WKB_Z_OFFSET);\n const isoM = hasIsoWKBTypeOffset(isoType, ISO_WKB_M_OFFSET);\n const isoZM = hasIsoWKBTypeOffset(isoType, ISO_WKB_ZM_OFFSET);\n\n const hasZ = (rawType & EWKB_Z_FLAG) !== 0 || isoZ || isoZM;\n const hasM = (rawType & EWKB_M_FLAG) !== 0 || isoM || isoZM;\n const hasSRID = (rawType & EWKB_SRID_FLAG) !== 0;\n\n let base = isoType;\n if (isoZM) base -= ISO_WKB_ZM_OFFSET;\n else if (isoM) base -= ISO_WKB_M_OFFSET;\n else if (isoZ) base -= ISO_WKB_Z_OFFSET;\n\n let offset = startOffset + WKB_HEADER_BYTES;\n if (hasSRID) offset += WKB_SRID_BYTES;\n\n const coordBytes =\n XY_COORDINATE_BYTES +\n (hasZ ? OPTIONAL_COORDINATE_DIMENSION_BYTES : 0) +\n (hasM ? OPTIONAL_COORDINATE_DIMENSION_BYTES : 0);\n return {view, isLE, geomType: base, offset, coordBytes};\n}\n\nexport function readWKBPointXY(header: WKBHeader): [number, number] | null {\n if (header.geomType !== WKB_POINT) return null;\n if (!hasBytes(header.view.buffer, header.offset, header.coordBytes)) {\n return null;\n }\n return [\n header.view.getFloat64(header.offset, header.isLE),\n header.view.getFloat64(\n header.offset + Y_COORDINATE_OFFSET_BYTES,\n header.isLE,\n ),\n ];\n}\n\n/**\n * Reads a WKB LineString and returns an array of [x, y] coordinate pairs.\n */\nexport function readWKBLineStringXY(\n buf: ArrayBuffer,\n header: WKBHeader,\n): Array<[number, number]> | null {\n if (header.geomType !== WKB_LINESTRING) return null;\n\n const {view, isLE, offset: headerOffset, coordBytes} = header;\n let offset = headerOffset;\n if (!hasBytes(buf, offset, WKB_UINT32_BYTES)) return null;\n const numPoints = view.getUint32(offset, isLE);\n offset += WKB_UINT32_BYTES;\n\n const coords: Array<[number, number]> = [];\n for (let i = 0; i < numPoints; i++) {\n if (!hasBytes(buf, offset, coordBytes)) return null;\n const x = view.getFloat64(offset, isLE);\n const y = view.getFloat64(offset + Y_COORDINATE_OFFSET_BYTES, isLE);\n coords.push([x, y]);\n offset += coordBytes;\n }\n return coords;\n}\n\nexport function visitWKBPolygonCoordinates(\n buf: ArrayBuffer,\n header: WKBHeader,\n visitor: WKBPolygonCoordinateVisitor,\n): number | null {\n if (header.geomType !== WKB_POLYGON) return null;\n\n const {view, isLE, offset: headerOffset, coordBytes} = header;\n let offset = headerOffset;\n if (!hasBytes(buf, offset, WKB_UINT32_BYTES)) return null;\n const numRings = view.getUint32(offset, isLE);\n offset += WKB_UINT32_BYTES;\n\n for (let ringIndex = 0; ringIndex < numRings; ringIndex++) {\n visitor.onRingStart();\n if (!hasBytes(buf, offset, WKB_UINT32_BYTES)) return null;\n const numPoints = view.getUint32(offset, isLE);\n offset += WKB_UINT32_BYTES;\n for (let pointIndex = 0; pointIndex < numPoints; pointIndex++) {\n if (!hasBytes(buf, offset, coordBytes)) return null;\n visitor.onCoordinate(\n view.getFloat64(offset, isLE),\n view.getFloat64(offset + Y_COORDINATE_OFFSET_BYTES, isLE),\n );\n offset += coordBytes;\n }\n }\n\n return offset <= buf.byteLength ? offset : null;\n}\n\nexport function visitWKBMultiPolygonCoordinates(\n buf: ArrayBuffer,\n header: WKBHeader,\n visitor: WKBPolygonCoordinateVisitor,\n): boolean {\n if (header.geomType !== WKB_MULTIPOLYGON) return false;\n\n let offset = header.offset;\n if (!hasBytes(buf, offset, WKB_UINT32_BYTES)) return false;\n const numPolygons = header.view.getUint32(offset, header.isLE);\n offset += WKB_UINT32_BYTES;\n\n for (let polygonIndex = 0; polygonIndex < numPolygons; polygonIndex++) {\n const polygonHeader = parseWKBHeader(buf, offset);\n if (!polygonHeader || polygonHeader.geomType !== WKB_POLYGON) return false;\n const nextOffset = visitWKBPolygonCoordinates(buf, polygonHeader, visitor);\n if (nextOffset == null) return false;\n offset = nextOffset;\n }\n\n return offset <= buf.byteLength;\n}\n\nfunction hasIsoWKBTypeOffset(isoType: number, offset: number): boolean {\n return isoType >= offset && isoType <= offset + ISO_WKB_MAX_BASE_TYPE;\n}\n\nfunction hasBytes(\n buf: {byteLength: number},\n offset: number,\n byteLength: number,\n) {\n return offset >= 0 && offset + byteLength <= buf.byteLength;\n}\n"]}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import type * as arrow from 'apache-arrow';
|
|
2
|
+
import type { ComponentProps, ReactNode } from 'react';
|
|
3
|
+
import type DeckGLReact from '@deck.gl/react';
|
|
4
|
+
import type { MapProps } from 'react-map-gl/maplibre';
|
|
5
|
+
type DeckProps = ComponentProps<typeof DeckGLReact>;
|
|
6
|
+
import type { GeometryEncodingHint, PreparedDeckDataset } from './prepare/types';
|
|
7
|
+
export type { ColorScaleFunction, DeckJsonMapLayerSpec, DeckJsonMapSpec, LayerBindingConfig, LayerBindingProps, } from './DeckJsonMapSpec';
|
|
8
|
+
type DeckDatasetBase = {
|
|
9
|
+
geometryColumn?: string;
|
|
10
|
+
geometryEncodingHint?: GeometryEncodingHint;
|
|
11
|
+
};
|
|
12
|
+
export type DeckAutoLayerType = 'GeoJsonLayer' | 'GeoArrowScatterplotLayer' | 'GeoArrowHeatmapLayer' | 'GeoArrowColumnLayer' | 'GeoArrowPathLayer' | 'GeoArrowPolygonLayer' | 'GeoArrowArcLayer' | 'GeoArrowTripsLayer' | 'GeoArrowH3HexagonLayer';
|
|
13
|
+
export type DeckSqlDatasetInput = DeckDatasetBase & {
|
|
14
|
+
/**
|
|
15
|
+
* Literal SQL query used as the full dataset source.
|
|
16
|
+
*
|
|
17
|
+
* SQLRooms does not rewrite this query when dashboard selected tables change.
|
|
18
|
+
* Use `DeckTableDatasetInput` when a dataset should follow a structured
|
|
19
|
+
* table source.
|
|
20
|
+
*/
|
|
21
|
+
sqlQuery: string;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Structured table-backed dataset source.
|
|
25
|
+
*
|
|
26
|
+
* `tableName` identifies the source relation. When `transformSql` is present,
|
|
27
|
+
* it must be a complete SELECT query that reads from the reserved
|
|
28
|
+
* `__sqlrooms_source` relation supplied by SQLRooms at execution time.
|
|
29
|
+
*/
|
|
30
|
+
export type DeckTableDatasetInput = DeckDatasetBase & {
|
|
31
|
+
tableName: string;
|
|
32
|
+
transformSql?: string;
|
|
33
|
+
};
|
|
34
|
+
export type DeckTable = arrow.Table;
|
|
35
|
+
export type DeckArrowTableDatasetInput = DeckDatasetBase & {
|
|
36
|
+
arrowTable: DeckTable | undefined;
|
|
37
|
+
};
|
|
38
|
+
export type DeckDatasetInput = DeckSqlDatasetInput | DeckTableDatasetInput | DeckArrowTableDatasetInput;
|
|
39
|
+
export type DeckJsonSpecDatasetHint = {
|
|
40
|
+
prefer?: 'heatmap';
|
|
41
|
+
type?: DeckAutoLayerType;
|
|
42
|
+
sourceGeometryColumn?: string;
|
|
43
|
+
targetGeometryColumn?: string;
|
|
44
|
+
timestampColumn?: string;
|
|
45
|
+
hexagonColumn?: string;
|
|
46
|
+
};
|
|
47
|
+
export type CreateDeckJsonSpecFromDatasetsOptions = {
|
|
48
|
+
datasets: Record<string, DeckDatasetInput>;
|
|
49
|
+
hints?: Record<string, DeckJsonSpecDatasetHint>;
|
|
50
|
+
};
|
|
51
|
+
export type PreparedDeckDatasetState = {
|
|
52
|
+
status: 'loading';
|
|
53
|
+
} | {
|
|
54
|
+
status: 'ready';
|
|
55
|
+
prepared: PreparedDeckDataset;
|
|
56
|
+
} | {
|
|
57
|
+
status: 'error';
|
|
58
|
+
error: Error;
|
|
59
|
+
};
|
|
60
|
+
export type DeckJsonMapHandle = {
|
|
61
|
+
jumpTo: (opts: {
|
|
62
|
+
longitude: number;
|
|
63
|
+
latitude: number;
|
|
64
|
+
zoom: number;
|
|
65
|
+
bearing?: number;
|
|
66
|
+
pitch?: number;
|
|
67
|
+
}) => void;
|
|
68
|
+
};
|
|
69
|
+
export type DeckJsonMapProps = {
|
|
70
|
+
spec: string | Record<string, unknown>;
|
|
71
|
+
datasets: Record<string, DeckDatasetInput>;
|
|
72
|
+
mapStyle?: string;
|
|
73
|
+
/**
|
|
74
|
+
* When true, deck.gl renders into the map's own WebGL context rather than
|
|
75
|
+
* creating a separate overlay canvas. This halves the number of WebGL
|
|
76
|
+
* contexts per map panel (from 2 to 1), which matters because browsers
|
|
77
|
+
* limit active contexts to ~8–16 per page. Defaults to true.
|
|
78
|
+
*/
|
|
79
|
+
interleaved?: boolean;
|
|
80
|
+
deckProps?: Partial<DeckProps>;
|
|
81
|
+
mapProps?: Partial<MapProps>;
|
|
82
|
+
showLegends?: boolean;
|
|
83
|
+
className?: string;
|
|
84
|
+
children?: ReactNode;
|
|
85
|
+
onDatasetStatesChange?: (states: Record<string, PreparedDeckDatasetState>) => void;
|
|
86
|
+
onRenderingError?: (error: Error) => void;
|
|
87
|
+
};
|
|
88
|
+
export declare function isSqlDatasetInput(input: DeckDatasetInput): input is DeckSqlDatasetInput;
|
|
89
|
+
/** Returns true when the dataset input describes a structured table source. */
|
|
90
|
+
export declare function isTableDatasetInput(input: DeckDatasetInput): input is DeckTableDatasetInput;
|
|
91
|
+
export declare function isArrowTableDatasetInput(input: DeckDatasetInput): input is DeckArrowTableDatasetInput;
|
|
92
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export function isSqlDatasetInput(input) {
|
|
2
|
+
return 'sqlQuery' in input;
|
|
3
|
+
}
|
|
4
|
+
/** Returns true when the dataset input describes a structured table source. */
|
|
5
|
+
export function isTableDatasetInput(input) {
|
|
6
|
+
return 'tableName' in input;
|
|
7
|
+
}
|
|
8
|
+
export function isArrowTableDatasetInput(input) {
|
|
9
|
+
return 'arrowTable' in input;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAoHA,MAAM,UAAU,iBAAiB,CAC/B,KAAuB;IAEvB,OAAO,UAAU,IAAI,KAAK,CAAC;AAC7B,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,mBAAmB,CACjC,KAAuB;IAEvB,OAAO,WAAW,IAAI,KAAK,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,wBAAwB,CACtC,KAAuB;IAEvB,OAAO,YAAY,IAAI,KAAK,CAAC;AAC/B,CAAC","sourcesContent":["import type * as arrow from 'apache-arrow';\nimport type {ComponentProps, ReactNode} from 'react';\nimport type DeckGLReact from '@deck.gl/react';\nimport type {MapProps} from 'react-map-gl/maplibre';\n\ntype DeckProps = ComponentProps<typeof DeckGLReact>;\nimport type {GeometryEncodingHint, PreparedDeckDataset} from './prepare/types';\n\nexport type {\n ColorScaleFunction,\n DeckJsonMapLayerSpec,\n DeckJsonMapSpec,\n LayerBindingConfig,\n LayerBindingProps,\n} from './DeckJsonMapSpec';\n\ntype DeckDatasetBase = {\n geometryColumn?: string;\n geometryEncodingHint?: GeometryEncodingHint;\n};\n\nexport type DeckAutoLayerType =\n | 'GeoJsonLayer'\n | 'GeoArrowScatterplotLayer'\n | 'GeoArrowHeatmapLayer'\n | 'GeoArrowColumnLayer'\n | 'GeoArrowPathLayer'\n | 'GeoArrowPolygonLayer'\n | 'GeoArrowArcLayer'\n | 'GeoArrowTripsLayer'\n | 'GeoArrowH3HexagonLayer';\n\nexport type DeckSqlDatasetInput = DeckDatasetBase & {\n /**\n * Literal SQL query used as the full dataset source.\n *\n * SQLRooms does not rewrite this query when dashboard selected tables change.\n * Use `DeckTableDatasetInput` when a dataset should follow a structured\n * table source.\n */\n sqlQuery: string;\n};\n\n/**\n * Structured table-backed dataset source.\n *\n * `tableName` identifies the source relation. When `transformSql` is present,\n * it must be a complete SELECT query that reads from the reserved\n * `__sqlrooms_source` relation supplied by SQLRooms at execution time.\n */\nexport type DeckTableDatasetInput = DeckDatasetBase & {\n tableName: string;\n transformSql?: string;\n};\n\nexport type DeckTable = arrow.Table;\n\nexport type DeckArrowTableDatasetInput = DeckDatasetBase & {\n arrowTable: DeckTable | undefined;\n};\nexport type DeckDatasetInput =\n | DeckSqlDatasetInput\n | DeckTableDatasetInput\n | DeckArrowTableDatasetInput;\n\nexport type DeckJsonSpecDatasetHint = {\n prefer?: 'heatmap';\n type?: DeckAutoLayerType;\n sourceGeometryColumn?: string;\n targetGeometryColumn?: string;\n timestampColumn?: string;\n hexagonColumn?: string;\n};\n\nexport type CreateDeckJsonSpecFromDatasetsOptions = {\n datasets: Record<string, DeckDatasetInput>;\n hints?: Record<string, DeckJsonSpecDatasetHint>;\n};\n\nexport type PreparedDeckDatasetState =\n | {status: 'loading'}\n | {status: 'ready'; prepared: PreparedDeckDataset}\n | {status: 'error'; error: Error};\n\nexport type DeckJsonMapHandle = {\n jumpTo: (opts: {\n longitude: number;\n latitude: number;\n zoom: number;\n bearing?: number;\n pitch?: number;\n }) => void;\n};\n\nexport type DeckJsonMapProps = {\n spec: string | Record<string, unknown>;\n datasets: Record<string, DeckDatasetInput>;\n mapStyle?: string;\n /**\n * When true, deck.gl renders into the map's own WebGL context rather than\n * creating a separate overlay canvas. This halves the number of WebGL\n * contexts per map panel (from 2 to 1), which matters because browsers\n * limit active contexts to ~8–16 per page. Defaults to true.\n */\n interleaved?: boolean;\n deckProps?: Partial<DeckProps>;\n mapProps?: Partial<MapProps>;\n showLegends?: boolean;\n className?: string;\n children?: ReactNode;\n onDatasetStatesChange?: (\n states: Record<string, PreparedDeckDatasetState>,\n ) => void;\n onRenderingError?: (error: Error) => void;\n};\n\nexport function isSqlDatasetInput(\n input: DeckDatasetInput,\n): input is DeckSqlDatasetInput {\n return 'sqlQuery' in input;\n}\n\n/** Returns true when the dataset input describes a structured table source. */\nexport function isTableDatasetInput(\n input: DeckDatasetInput,\n): input is DeckTableDatasetInput {\n return 'tableName' in input;\n}\n\nexport function isArrowTableDatasetInput(\n input: DeckDatasetInput,\n): input is DeckArrowTableDatasetInput {\n return 'arrowTable' in input;\n}\n"]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type TableColumn } from '@sqlrooms/duckdb';
|
|
2
|
+
import * as arrow from 'apache-arrow';
|
|
3
|
+
import { type DeckMapDatasetSource } from './mapConfig';
|
|
4
|
+
/** Resolved source and output column sets for a Deck map dataset. */
|
|
5
|
+
export type DeckMapResolvedDatasetSchema = {
|
|
6
|
+
sourceColumns: TableColumn[];
|
|
7
|
+
outputColumns: TableColumn[];
|
|
8
|
+
generatedOutputColumns: TableColumn[];
|
|
9
|
+
dataOutputColumns: TableColumn[];
|
|
10
|
+
};
|
|
11
|
+
/** React state for map dataset schema inspection, including loading errors. */
|
|
12
|
+
export type DeckMapDatasetSchemaState = DeckMapResolvedDatasetSchema & {
|
|
13
|
+
isLoading: boolean;
|
|
14
|
+
error: Error | null;
|
|
15
|
+
};
|
|
16
|
+
/** Returns true for SQLRooms map helper columns generated by transforms. */
|
|
17
|
+
export declare function isDeckMapGeneratedColumn(columnName: string): boolean;
|
|
18
|
+
/** Builds a zero-row SQL query that exposes a map dataset's output schema. */
|
|
19
|
+
export declare function createDeckMapDatasetOutputSchemaSql(source: DeckMapDatasetSource): string;
|
|
20
|
+
/** Splits inspected output columns into generated map helpers and data fields. */
|
|
21
|
+
export declare function resolveDeckMapDatasetSchema(options: {
|
|
22
|
+
sourceColumns: TableColumn[];
|
|
23
|
+
outputColumns: TableColumn[];
|
|
24
|
+
classifyGeneratedColumns?: boolean;
|
|
25
|
+
}): DeckMapResolvedDatasetSchema;
|
|
26
|
+
/** Converts an Apache Arrow data type into a selector-compatible DuckDB type. */
|
|
27
|
+
export declare function arrowTypeToDuckDbColumnType(type: arrow.DataType): string;
|
|
28
|
+
/** Inspects the active map dataset and returns source/output schema columns. */
|
|
29
|
+
export declare function useDeckMapDatasetSchema(options: {
|
|
30
|
+
source: DeckMapDatasetSource | undefined;
|
|
31
|
+
sourceColumns: TableColumn[];
|
|
32
|
+
}): DeckMapDatasetSchemaState;
|
|
33
|
+
//# sourceMappingURL=useDeckMapDatasetSchema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDeckMapDatasetSchema.d.ts","sourceRoot":"","sources":["../src/useDeckMapDatasetSchema.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,WAAW,EACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAEtC,OAAO,EAGL,KAAK,oBAAoB,EAC1B,MAAM,aAAa,CAAC;AAWrB,qEAAqE;AACrE,MAAM,MAAM,4BAA4B,GAAG;IACzC,aAAa,EAAE,WAAW,EAAE,CAAC;IAC7B,aAAa,EAAE,WAAW,EAAE,CAAC;IAC7B,sBAAsB,EAAE,WAAW,EAAE,CAAC;IACtC,iBAAiB,EAAE,WAAW,EAAE,CAAC;CAClC,CAAC;AAEF,+EAA+E;AAC/E,MAAM,MAAM,yBAAyB,GAAG,4BAA4B,GAAG;IACrE,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CACrB,CAAC;AAEF,4EAA4E;AAC5E,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAEpE;AAcD,8EAA8E;AAC9E,wBAAgB,mCAAmC,CACjD,MAAM,EAAE,oBAAoB,GAC3B,MAAM,CAMR;AAED,kFAAkF;AAClF,wBAAgB,2BAA2B,CAAC,OAAO,EAAE;IACnD,aAAa,EAAE,WAAW,EAAE,CAAC;IAC7B,aAAa,EAAE,WAAW,EAAE,CAAC;IAC7B,wBAAwB,CAAC,EAAE,OAAO,CAAC;CACpC,GAAG,4BAA4B,CAqB/B;AAiBD,iFAAiF;AACjF,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,KAAK,CAAC,QAAQ,GAAG,MAAM,CAExE;AASD,gFAAgF;AAChF,wBAAgB,uBAAuB,CAAC,OAAO,EAAE;IAC/C,MAAM,EAAE,oBAAoB,GAAG,SAAS,CAAC;IACzC,aAAa,EAAE,WAAW,EAAE,CAAC;CAC9B,GAAG,yBAAyB,CA0F5B"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { columnTypeCategoryToSelectorType, getArrowColumnTypeCategory, useDuckDb, } from '@sqlrooms/duckdb';
|
|
2
|
+
import { useEffect, useMemo, useState } from 'react';
|
|
3
|
+
import { isDeckMapSqlDatasetSource, isDeckMapTableDatasetSource, } from './mapConfig';
|
|
4
|
+
import { createDeckTableDatasetSql } from './datasets/tableDatasetSql';
|
|
5
|
+
const EMPTY_COLUMNS = [];
|
|
6
|
+
const GENERATED_COLUMN_NAMES = new Set([
|
|
7
|
+
'__sqlrooms_geom',
|
|
8
|
+
'source_geom',
|
|
9
|
+
'target_geom',
|
|
10
|
+
'timestamps',
|
|
11
|
+
]);
|
|
12
|
+
/** Returns true for SQLRooms map helper columns generated by transforms. */
|
|
13
|
+
export function isDeckMapGeneratedColumn(columnName) {
|
|
14
|
+
return GENERATED_COLUMN_NAMES.has(columnName);
|
|
15
|
+
}
|
|
16
|
+
function cleanSql(sql) {
|
|
17
|
+
return sql.trim().replace(/(?:\s*;+\s*)+$/, '');
|
|
18
|
+
}
|
|
19
|
+
function createDatasetOutputSql(source) {
|
|
20
|
+
if (isDeckMapSqlDatasetSource(source)) {
|
|
21
|
+
return cleanSql(source.sqlQuery);
|
|
22
|
+
}
|
|
23
|
+
return createDeckTableDatasetSql(source);
|
|
24
|
+
}
|
|
25
|
+
/** Builds a zero-row SQL query that exposes a map dataset's output schema. */
|
|
26
|
+
export function createDeckMapDatasetOutputSchemaSql(source) {
|
|
27
|
+
return [
|
|
28
|
+
'SELECT *',
|
|
29
|
+
`FROM (${createDatasetOutputSql(source)}) AS "__sqlrooms_schema_source"`,
|
|
30
|
+
'LIMIT 0',
|
|
31
|
+
].join('\n');
|
|
32
|
+
}
|
|
33
|
+
/** Splits inspected output columns into generated map helpers and data fields. */
|
|
34
|
+
export function resolveDeckMapDatasetSchema(options) {
|
|
35
|
+
const sourceColumnNames = new Set(options.sourceColumns.map((column) => column.name));
|
|
36
|
+
const isGeneratedOutputColumn = (column) => options.classifyGeneratedColumns === true &&
|
|
37
|
+
isDeckMapGeneratedColumn(column.name) &&
|
|
38
|
+
!sourceColumnNames.has(column.name);
|
|
39
|
+
const generatedOutputColumns = options.outputColumns.filter(isGeneratedOutputColumn);
|
|
40
|
+
const dataOutputColumns = options.outputColumns.filter((column) => !isGeneratedOutputColumn(column));
|
|
41
|
+
return {
|
|
42
|
+
sourceColumns: options.sourceColumns,
|
|
43
|
+
outputColumns: options.outputColumns,
|
|
44
|
+
generatedOutputColumns,
|
|
45
|
+
dataOutputColumns,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function hasTableTransformSql(source) {
|
|
49
|
+
return Boolean(isDeckMapTableDatasetSource(source) && source.transformSql?.trim());
|
|
50
|
+
}
|
|
51
|
+
function shouldInspectOutputSchema(source) {
|
|
52
|
+
return Boolean(source &&
|
|
53
|
+
(isDeckMapSqlDatasetSource(source) || hasTableTransformSql(source)));
|
|
54
|
+
}
|
|
55
|
+
/** Converts an Apache Arrow data type into a selector-compatible DuckDB type. */
|
|
56
|
+
export function arrowTypeToDuckDbColumnType(type) {
|
|
57
|
+
return columnTypeCategoryToSelectorType(getArrowColumnTypeCategory(type));
|
|
58
|
+
}
|
|
59
|
+
function arrowSchemaToTableColumns(table) {
|
|
60
|
+
return table.schema.fields.map((field) => ({
|
|
61
|
+
name: field.name,
|
|
62
|
+
type: arrowTypeToDuckDbColumnType(field.type),
|
|
63
|
+
}));
|
|
64
|
+
}
|
|
65
|
+
/** Inspects the active map dataset and returns source/output schema columns. */
|
|
66
|
+
export function useDeckMapDatasetSchema(options) {
|
|
67
|
+
const connector = useDuckDb();
|
|
68
|
+
const [state, setState] = useState({
|
|
69
|
+
sourceKey: '',
|
|
70
|
+
outputColumns: [],
|
|
71
|
+
error: null,
|
|
72
|
+
});
|
|
73
|
+
const shouldInspect = shouldInspectOutputSchema(options.source);
|
|
74
|
+
const sourceKey = isDeckMapSqlDatasetSource(options.source)
|
|
75
|
+
? options.source.sqlQuery
|
|
76
|
+
: isDeckMapTableDatasetSource(options.source)
|
|
77
|
+
? `${options.source.tableName}\n${options.source.transformSql ?? ''}`
|
|
78
|
+
: '';
|
|
79
|
+
useEffect(() => {
|
|
80
|
+
const source = options.source;
|
|
81
|
+
if (!source || !shouldInspect) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const abortController = new AbortController();
|
|
85
|
+
let isActive = true;
|
|
86
|
+
void (async () => {
|
|
87
|
+
try {
|
|
88
|
+
const table = await connector.query(createDeckMapDatasetOutputSchemaSql(source), {
|
|
89
|
+
signal: abortController.signal,
|
|
90
|
+
});
|
|
91
|
+
if (!isActive || abortController.signal.aborted)
|
|
92
|
+
return;
|
|
93
|
+
setState({
|
|
94
|
+
sourceKey,
|
|
95
|
+
outputColumns: arrowSchemaToTableColumns(table),
|
|
96
|
+
error: null,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
if (!isActive || abortController.signal.aborted)
|
|
101
|
+
return;
|
|
102
|
+
setState({
|
|
103
|
+
sourceKey,
|
|
104
|
+
outputColumns: [],
|
|
105
|
+
error: error instanceof Error ? error : new Error(String(error)),
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
})();
|
|
109
|
+
return () => {
|
|
110
|
+
isActive = false;
|
|
111
|
+
abortController.abort();
|
|
112
|
+
};
|
|
113
|
+
}, [connector, options.source, shouldInspect, sourceKey]);
|
|
114
|
+
const isCurrentInspectedSource = shouldInspect && state.sourceKey === sourceKey;
|
|
115
|
+
const outputColumns = useMemo(() => {
|
|
116
|
+
if (shouldInspect) {
|
|
117
|
+
return isCurrentInspectedSource ? state.outputColumns : EMPTY_COLUMNS;
|
|
118
|
+
}
|
|
119
|
+
return options.source ? options.sourceColumns : EMPTY_COLUMNS;
|
|
120
|
+
}, [
|
|
121
|
+
isCurrentInspectedSource,
|
|
122
|
+
options.source,
|
|
123
|
+
options.sourceColumns,
|
|
124
|
+
shouldInspect,
|
|
125
|
+
state.outputColumns,
|
|
126
|
+
]);
|
|
127
|
+
const resolved = useMemo(() => resolveDeckMapDatasetSchema({
|
|
128
|
+
sourceColumns: options.sourceColumns,
|
|
129
|
+
outputColumns,
|
|
130
|
+
classifyGeneratedColumns: hasTableTransformSql(options.source),
|
|
131
|
+
}), [options.source, options.sourceColumns, outputColumns]);
|
|
132
|
+
return {
|
|
133
|
+
...resolved,
|
|
134
|
+
isLoading: shouldInspect && !isCurrentInspectedSource,
|
|
135
|
+
error: isCurrentInspectedSource ? state.error : null,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=useDeckMapDatasetSchema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDeckMapDatasetSchema.js","sourceRoot":"","sources":["../src/useDeckMapDatasetSchema.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n columnTypeCategoryToSelectorType,\n getArrowColumnTypeCategory,\n useDuckDb,\n type TableColumn,\n} from '@sqlrooms/duckdb';\nimport * as arrow from 'apache-arrow';\nimport {useEffect, useMemo, useState} from 'react';\nimport {\n isDeckMapSqlDatasetSource,\n isDeckMapTableDatasetSource,\n type DeckMapDatasetSource,\n} from './mapConfig';\nimport {createDeckTableDatasetSql} from './datasets/tableDatasetSql';\n\nconst EMPTY_COLUMNS: TableColumn[] = [];\nconst GENERATED_COLUMN_NAMES = new Set([\n '__sqlrooms_geom',\n 'source_geom',\n 'target_geom',\n 'timestamps',\n]);\n\n/** Resolved source and output column sets for a Deck map dataset. */\nexport type DeckMapResolvedDatasetSchema = {\n sourceColumns: TableColumn[];\n outputColumns: TableColumn[];\n generatedOutputColumns: TableColumn[];\n dataOutputColumns: TableColumn[];\n};\n\n/** React state for map dataset schema inspection, including loading errors. */\nexport type DeckMapDatasetSchemaState = DeckMapResolvedDatasetSchema & {\n isLoading: boolean;\n error: Error | null;\n};\n\n/** Returns true for SQLRooms map helper columns generated by transforms. */\nexport function isDeckMapGeneratedColumn(columnName: string): boolean {\n return GENERATED_COLUMN_NAMES.has(columnName);\n}\n\nfunction cleanSql(sql: string) {\n return sql.trim().replace(/(?:\\s*;+\\s*)+$/, '');\n}\n\nfunction createDatasetOutputSql(source: DeckMapDatasetSource) {\n if (isDeckMapSqlDatasetSource(source)) {\n return cleanSql(source.sqlQuery);\n }\n\n return createDeckTableDatasetSql(source);\n}\n\n/** Builds a zero-row SQL query that exposes a map dataset's output schema. */\nexport function createDeckMapDatasetOutputSchemaSql(\n source: DeckMapDatasetSource,\n): string {\n return [\n 'SELECT *',\n `FROM (${createDatasetOutputSql(source)}) AS \"__sqlrooms_schema_source\"`,\n 'LIMIT 0',\n ].join('\\n');\n}\n\n/** Splits inspected output columns into generated map helpers and data fields. */\nexport function resolveDeckMapDatasetSchema(options: {\n sourceColumns: TableColumn[];\n outputColumns: TableColumn[];\n classifyGeneratedColumns?: boolean;\n}): DeckMapResolvedDatasetSchema {\n const sourceColumnNames = new Set(\n options.sourceColumns.map((column) => column.name),\n );\n const isGeneratedOutputColumn = (column: TableColumn) =>\n options.classifyGeneratedColumns === true &&\n isDeckMapGeneratedColumn(column.name) &&\n !sourceColumnNames.has(column.name);\n const generatedOutputColumns = options.outputColumns.filter(\n isGeneratedOutputColumn,\n );\n const dataOutputColumns = options.outputColumns.filter(\n (column) => !isGeneratedOutputColumn(column),\n );\n\n return {\n sourceColumns: options.sourceColumns,\n outputColumns: options.outputColumns,\n generatedOutputColumns,\n dataOutputColumns,\n };\n}\n\nfunction hasTableTransformSql(\n source: DeckMapDatasetSource | undefined,\n): boolean {\n return Boolean(\n isDeckMapTableDatasetSource(source) && source.transformSql?.trim(),\n );\n}\n\nfunction shouldInspectOutputSchema(source: DeckMapDatasetSource | undefined) {\n return Boolean(\n source &&\n (isDeckMapSqlDatasetSource(source) || hasTableTransformSql(source)),\n );\n}\n\n/** Converts an Apache Arrow data type into a selector-compatible DuckDB type. */\nexport function arrowTypeToDuckDbColumnType(type: arrow.DataType): string {\n return columnTypeCategoryToSelectorType(getArrowColumnTypeCategory(type));\n}\n\nfunction arrowSchemaToTableColumns(table: arrow.Table): TableColumn[] {\n return table.schema.fields.map((field) => ({\n name: field.name,\n type: arrowTypeToDuckDbColumnType(field.type),\n }));\n}\n\n/** Inspects the active map dataset and returns source/output schema columns. */\nexport function useDeckMapDatasetSchema(options: {\n source: DeckMapDatasetSource | undefined;\n sourceColumns: TableColumn[];\n}): DeckMapDatasetSchemaState {\n const connector = useDuckDb();\n const [state, setState] = useState<{\n sourceKey: string;\n outputColumns: TableColumn[];\n error: Error | null;\n }>({\n sourceKey: '',\n outputColumns: [],\n error: null,\n });\n\n const shouldInspect = shouldInspectOutputSchema(options.source);\n const sourceKey = isDeckMapSqlDatasetSource(options.source)\n ? options.source.sqlQuery\n : isDeckMapTableDatasetSource(options.source)\n ? `${options.source.tableName}\\n${options.source.transformSql ?? ''}`\n : '';\n\n useEffect(() => {\n const source = options.source;\n\n if (!source || !shouldInspect) {\n return;\n }\n\n const abortController = new AbortController();\n let isActive = true;\n\n void (async () => {\n try {\n const table = await connector.query(\n createDeckMapDatasetOutputSchemaSql(source),\n {\n signal: abortController.signal,\n },\n );\n if (!isActive || abortController.signal.aborted) return;\n setState({\n sourceKey,\n outputColumns: arrowSchemaToTableColumns(table),\n error: null,\n });\n } catch (error) {\n if (!isActive || abortController.signal.aborted) return;\n setState({\n sourceKey,\n outputColumns: [],\n error: error instanceof Error ? error : new Error(String(error)),\n });\n }\n })();\n\n return () => {\n isActive = false;\n abortController.abort();\n };\n }, [connector, options.source, shouldInspect, sourceKey]);\n\n const isCurrentInspectedSource =\n shouldInspect && state.sourceKey === sourceKey;\n const outputColumns = useMemo(() => {\n if (shouldInspect) {\n return isCurrentInspectedSource ? state.outputColumns : EMPTY_COLUMNS;\n }\n\n return options.source ? options.sourceColumns : EMPTY_COLUMNS;\n }, [\n isCurrentInspectedSource,\n options.source,\n options.sourceColumns,\n shouldInspect,\n state.outputColumns,\n ]);\n\n const resolved = useMemo(\n () =>\n resolveDeckMapDatasetSchema({\n sourceColumns: options.sourceColumns,\n outputColumns,\n classifyGeneratedColumns: hasTableTransformSql(options.source),\n }),\n [options.source, options.sourceColumns, outputColumns],\n );\n\n return {\n ...resolved,\n isLoading: shouldInspect && !isCurrentInspectedSource,\n error: isCurrentInspectedSource ? state.error : null,\n };\n}\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ChartRuntimeIssueContext, ChartRuntimeIssueReporter, MosaicDashboardPanelConfigType } from '@sqlrooms/mosaic';
|
|
2
|
+
import { type DeckMapDashboardDatasetClientState } from './dashboardConfig';
|
|
3
|
+
/**
|
|
4
|
+
* Manages dataset state tracking, data policy, and runtime issue reporting
|
|
5
|
+
* for a deck map dashboard panel's dataset clients.
|
|
6
|
+
*/
|
|
7
|
+
export declare function useDeckMapDatasets(options: {
|
|
8
|
+
dashboardId: string;
|
|
9
|
+
panel: MosaicDashboardPanelConfigType;
|
|
10
|
+
}): {
|
|
11
|
+
datasetStates: Record<string, DeckMapDashboardDatasetClientState>;
|
|
12
|
+
handleDatasetState: (datasetId: string, state: DeckMapDashboardDatasetClientState | undefined) => void;
|
|
13
|
+
runtimeIssueContext: ChartRuntimeIssueContext;
|
|
14
|
+
runtimeIssueReporter: ChartRuntimeIssueReporter;
|
|
15
|
+
handleRenderingError: (error: Error) => void;
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=useDeckMapDatasets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDeckMapDatasets.d.ts","sourceRoot":"","sources":["../src/useDeckMapDatasets.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,wBAAwB,EACxB,yBAAyB,EACzB,8BAA8B,EAC/B,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAEL,KAAK,kCAAkC,EACxC,MAAM,mBAAmB,CAAC;AAE3B;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE;IAC1C,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,8BAA8B,CAAC;CACvC;;oCAgBgB,MAAM,SACV,kCAAkC,GAAG,SAAS;;;kCAqD/C,KAAK;EAmBhB"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { useStoreWithMosaicDashboard } from '@sqlrooms/mosaic';
|
|
2
|
+
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
3
|
+
import { DECK_MAP_DASHBOARD_PANEL_TYPE, } from './dashboardConfig';
|
|
4
|
+
/**
|
|
5
|
+
* Manages dataset state tracking, data policy, and runtime issue reporting
|
|
6
|
+
* for a deck map dashboard panel's dataset clients.
|
|
7
|
+
*/
|
|
8
|
+
export function useDeckMapDatasets(options) {
|
|
9
|
+
const { dashboardId, panel } = options;
|
|
10
|
+
const reportPanelIssue = useStoreWithMosaicDashboard((state) => state.mosaicDashboard.reportPanelIssue);
|
|
11
|
+
const clearPanelIssue = useStoreWithMosaicDashboard((state) => state.mosaicDashboard.clearPanelIssue);
|
|
12
|
+
const [datasetStates, setDatasetStates] = useState({});
|
|
13
|
+
const handleDatasetState = useCallback((datasetId, state) => {
|
|
14
|
+
setDatasetStates((current) => {
|
|
15
|
+
const next = { ...current };
|
|
16
|
+
if (state) {
|
|
17
|
+
next[datasetId] = state;
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
delete next[datasetId];
|
|
21
|
+
}
|
|
22
|
+
return next;
|
|
23
|
+
});
|
|
24
|
+
}, []);
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
const firstError = Object.values(datasetStates).find((s) => s?.error)?.error;
|
|
27
|
+
if (firstError) {
|
|
28
|
+
reportPanelIssue(dashboardId, panel.id, {
|
|
29
|
+
kind: 'sql-error',
|
|
30
|
+
panelId: panel.id,
|
|
31
|
+
chartType: DECK_MAP_DASHBOARD_PANEL_TYPE,
|
|
32
|
+
message: firstError.message,
|
|
33
|
+
recoverable: true,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
clearPanelIssue(dashboardId, panel.id);
|
|
38
|
+
}
|
|
39
|
+
}, [datasetStates, dashboardId, panel.id, reportPanelIssue, clearPanelIssue]);
|
|
40
|
+
const runtimeIssueContext = useMemo(() => ({
|
|
41
|
+
panelId: panel.id,
|
|
42
|
+
chartType: DECK_MAP_DASHBOARD_PANEL_TYPE,
|
|
43
|
+
}), [panel.id]);
|
|
44
|
+
const runtimeIssueReporter = useMemo(() => ({
|
|
45
|
+
reportIssue: (issueToReport) => {
|
|
46
|
+
reportPanelIssue(dashboardId, panel.id, issueToReport);
|
|
47
|
+
},
|
|
48
|
+
clearIssue: () => {
|
|
49
|
+
clearPanelIssue(dashboardId, panel.id);
|
|
50
|
+
},
|
|
51
|
+
}), [clearPanelIssue, dashboardId, panel.id, reportPanelIssue]);
|
|
52
|
+
const handleRenderingError = useCallback((error) => {
|
|
53
|
+
reportPanelIssue(dashboardId, panel.id, {
|
|
54
|
+
kind: 'render-error',
|
|
55
|
+
panelId: panel.id,
|
|
56
|
+
chartType: DECK_MAP_DASHBOARD_PANEL_TYPE,
|
|
57
|
+
message: error.message,
|
|
58
|
+
recoverable: true,
|
|
59
|
+
});
|
|
60
|
+
}, [dashboardId, panel.id, reportPanelIssue]);
|
|
61
|
+
return {
|
|
62
|
+
datasetStates,
|
|
63
|
+
handleDatasetState,
|
|
64
|
+
runtimeIssueContext,
|
|
65
|
+
runtimeIssueReporter,
|
|
66
|
+
handleRenderingError,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=useDeckMapDatasets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDeckMapDatasets.js","sourceRoot":"","sources":["../src/useDeckMapDatasets.ts"],"names":[],"mappings":"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","sourcesContent":["import {useStoreWithMosaicDashboard} from '@sqlrooms/mosaic';\nimport type {\n ChartRuntimeIssueContext,\n ChartRuntimeIssueReporter,\n MosaicDashboardPanelConfigType,\n} from '@sqlrooms/mosaic';\nimport {useCallback, useEffect, useMemo, useState} from 'react';\nimport {\n DECK_MAP_DASHBOARD_PANEL_TYPE,\n type DeckMapDashboardDatasetClientState,\n} from './dashboardConfig';\n\n/**\n * Manages dataset state tracking, data policy, and runtime issue reporting\n * for a deck map dashboard panel's dataset clients.\n */\nexport function useDeckMapDatasets(options: {\n dashboardId: string;\n panel: MosaicDashboardPanelConfigType;\n}) {\n const {dashboardId, panel} = options;\n\n const reportPanelIssue = useStoreWithMosaicDashboard(\n (state) => state.mosaicDashboard.reportPanelIssue,\n );\n const clearPanelIssue = useStoreWithMosaicDashboard(\n (state) => state.mosaicDashboard.clearPanelIssue,\n );\n\n const [datasetStates, setDatasetStates] = useState<\n Record<string, DeckMapDashboardDatasetClientState>\n >({});\n\n const handleDatasetState = useCallback(\n (\n datasetId: string,\n state: DeckMapDashboardDatasetClientState | undefined,\n ) => {\n setDatasetStates((current) => {\n const next = {...current};\n if (state) {\n next[datasetId] = state;\n } else {\n delete next[datasetId];\n }\n return next;\n });\n },\n [],\n );\n\n useEffect(() => {\n const firstError = Object.values(datasetStates).find(\n (s) => s?.error,\n )?.error;\n if (firstError) {\n reportPanelIssue(dashboardId, panel.id, {\n kind: 'sql-error',\n panelId: panel.id,\n chartType: DECK_MAP_DASHBOARD_PANEL_TYPE,\n message: firstError.message,\n recoverable: true,\n });\n } else {\n clearPanelIssue(dashboardId, panel.id);\n }\n }, [datasetStates, dashboardId, panel.id, reportPanelIssue, clearPanelIssue]);\n\n const runtimeIssueContext = useMemo<ChartRuntimeIssueContext>(\n () => ({\n panelId: panel.id,\n chartType: DECK_MAP_DASHBOARD_PANEL_TYPE,\n }),\n [panel.id],\n );\n\n const runtimeIssueReporter = useMemo<ChartRuntimeIssueReporter>(\n () => ({\n reportIssue: (issueToReport) => {\n reportPanelIssue(dashboardId, panel.id, issueToReport);\n },\n clearIssue: () => {\n clearPanelIssue(dashboardId, panel.id);\n },\n }),\n [clearPanelIssue, dashboardId, panel.id, reportPanelIssue],\n );\n\n const handleRenderingError = useCallback(\n (error: Error) => {\n reportPanelIssue(dashboardId, panel.id, {\n kind: 'render-error',\n panelId: panel.id,\n chartType: DECK_MAP_DASHBOARD_PANEL_TYPE,\n message: error.message,\n recoverable: true,\n });\n },\n [dashboardId, panel.id, reportPanelIssue],\n );\n\n return {\n datasetStates,\n handleDatasetState,\n runtimeIssueContext,\n runtimeIssueReporter,\n handleRenderingError,\n };\n}\n"]}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { MosaicDashboardEntryType, MosaicDashboardPanelConfigType } from '@sqlrooms/mosaic';
|
|
2
|
+
import { type RefObject } from 'react';
|
|
3
|
+
import type { DeckJsonMapHandle } from './types';
|
|
4
|
+
export { createDeckMapBoundsQuery } from './mapFit';
|
|
5
|
+
/**
|
|
6
|
+
* Requests a manual fit-to-data operation for a Mosaic dashboard map panel.
|
|
7
|
+
*
|
|
8
|
+
* @param panelId - Dashboard panel whose map view should be fitted.
|
|
9
|
+
*/
|
|
10
|
+
export declare function emitDeckMapDashboardFitRequest(panelId: string): void;
|
|
11
|
+
/**
|
|
12
|
+
* Adapts Mosaic dashboard state and panel fit events to the shared Deck fit
|
|
13
|
+
* controller.
|
|
14
|
+
*
|
|
15
|
+
* This adapter resolves dashboard-selected table semantics while keeping all
|
|
16
|
+
* query execution, viewport calculation, and request state in the host-neutral
|
|
17
|
+
* fit engine.
|
|
18
|
+
*
|
|
19
|
+
* @param options - Mosaic dashboard/panel state and rendered map/container refs.
|
|
20
|
+
* @returns The normalized fit configuration used by dashboard dataset clients.
|
|
21
|
+
*/
|
|
22
|
+
export declare function useDeckMapFitToBounds(options: {
|
|
23
|
+
panelId: string;
|
|
24
|
+
dashboard: MosaicDashboardEntryType;
|
|
25
|
+
panel: MosaicDashboardPanelConfigType;
|
|
26
|
+
container: HTMLElement | null;
|
|
27
|
+
deckMapRef: RefObject<DeckJsonMapHandle | null>;
|
|
28
|
+
}): {
|
|
29
|
+
fitToData: import("./mapConfig").DeckMapFitToDataConfig | null;
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=useDeckMapFitToBounds.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDeckMapFitToBounds.d.ts","sourceRoot":"","sources":["../src/useDeckMapFitToBounds.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,wBAAwB,EACxB,8BAA8B,EAC/B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAA+B,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AASnE,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,SAAS,CAAC;AAE/C,OAAO,EAAC,wBAAwB,EAAC,MAAM,UAAU,CAAC;AAIlD;;;;GAIG;AACH,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,MAAM,QAI7D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,wBAAwB,CAAC;IACpC,KAAK,EAAE,8BAA8B,CAAC;IACtC,SAAS,EAAE,WAAW,GAAG,IAAI,CAAC;IAC9B,UAAU,EAAE,SAAS,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;CACjD;;EAiDA"}
|