@sqlrooms/deck 0.29.0-rc.10 → 0.29.0-rc.11

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 (118) hide show
  1. package/README.md +42 -6
  2. package/dist/DeckJsonMap.d.ts.map +1 -1
  3. package/dist/DeckJsonMap.js +2 -6
  4. package/dist/DeckJsonMap.js.map +1 -1
  5. package/dist/DeckJsonMapSpec.d.ts +875 -53
  6. package/dist/DeckJsonMapSpec.d.ts.map +1 -1
  7. package/dist/DeckJsonMapSpec.js +7 -0
  8. package/dist/DeckJsonMapSpec.js.map +1 -1
  9. package/dist/DeckMapDefaultStylesProvider.d.ts +3 -4
  10. package/dist/DeckMapDefaultStylesProvider.d.ts.map +1 -1
  11. package/dist/DeckMapDefaultStylesProvider.js +13 -7
  12. package/dist/DeckMapDefaultStylesProvider.js.map +1 -1
  13. package/dist/MapSettings.d.ts.map +1 -1
  14. package/dist/MapSettings.js +25 -11
  15. package/dist/MapSettings.js.map +1 -1
  16. package/dist/ai.d.ts +19 -5
  17. package/dist/ai.d.ts.map +1 -1
  18. package/dist/ai.js +60 -112
  19. package/dist/ai.js.map +1 -1
  20. package/dist/aiNormalize.d.ts +31 -0
  21. package/dist/aiNormalize.d.ts.map +1 -0
  22. package/dist/aiNormalize.js +629 -0
  23. package/dist/aiNormalize.js.map +1 -0
  24. package/dist/dashboard.d.ts.map +1 -1
  25. package/dist/dashboard.js +72 -8
  26. package/dist/dashboard.js.map +1 -1
  27. package/dist/dashboardConfig.d.ts +10 -1
  28. package/dist/dashboardConfig.d.ts.map +1 -1
  29. package/dist/dashboardConfig.js +55 -22
  30. package/dist/dashboardConfig.js.map +1 -1
  31. package/dist/datasets/PreparedDatasetStore.d.ts.map +1 -1
  32. package/dist/datasets/PreparedDatasetStore.js +31 -2
  33. package/dist/datasets/PreparedDatasetStore.js.map +1 -1
  34. package/dist/datasets/wrapGeometryAsWkb.d.ts +20 -0
  35. package/dist/datasets/wrapGeometryAsWkb.d.ts.map +1 -0
  36. package/dist/datasets/wrapGeometryAsWkb.js +65 -0
  37. package/dist/datasets/wrapGeometryAsWkb.js.map +1 -0
  38. package/dist/index.d.ts +1 -0
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +1 -0
  41. package/dist/index.js.map +1 -1
  42. package/dist/json/compileGeoArrowAccessor.d.ts +5 -0
  43. package/dist/json/compileGeoArrowAccessor.d.ts.map +1 -1
  44. package/dist/json/compileGeoArrowAccessor.js +17 -3
  45. package/dist/json/compileGeoArrowAccessor.js.map +1 -1
  46. package/dist/json/createDeckJsonConfiguration.d.ts.map +1 -1
  47. package/dist/json/createDeckJsonConfiguration.js +85 -18
  48. package/dist/json/createDeckJsonConfiguration.js.map +1 -1
  49. package/dist/json/extractColorScaleLegends.d.ts.map +1 -1
  50. package/dist/json/extractColorScaleLegends.js +21 -7
  51. package/dist/json/extractColorScaleLegends.js.map +1 -1
  52. package/dist/json/layers/DeckH3HexagonLayer.d.ts.map +1 -1
  53. package/dist/json/layers/DeckH3HexagonLayer.js +9 -14
  54. package/dist/json/layers/DeckH3HexagonLayer.js.map +1 -1
  55. package/dist/json/layers/h3IndexFormat.d.ts +6 -0
  56. package/dist/json/layers/h3IndexFormat.d.ts.map +1 -0
  57. package/dist/json/layers/h3IndexFormat.js +17 -0
  58. package/dist/json/layers/h3IndexFormat.js.map +1 -0
  59. package/dist/json/layers/index.d.ts +1 -0
  60. package/dist/json/layers/index.d.ts.map +1 -1
  61. package/dist/json/layers/index.js +1 -0
  62. package/dist/json/layers/index.js.map +1 -1
  63. package/dist/json/rewriteGeoArrowAccessors.d.ts.map +1 -1
  64. package/dist/json/rewriteGeoArrowAccessors.js +9 -0
  65. package/dist/json/rewriteGeoArrowAccessors.js.map +1 -1
  66. package/dist/json/scaleFunction.d.ts +30 -0
  67. package/dist/json/scaleFunction.d.ts.map +1 -0
  68. package/dist/json/scaleFunction.js +126 -0
  69. package/dist/json/scaleFunction.js.map +1 -0
  70. package/dist/mapAiConfig.d.ts +2 -0
  71. package/dist/mapAiConfig.d.ts.map +1 -1
  72. package/dist/mapAiConfig.js +2 -1
  73. package/dist/mapAiConfig.js.map +1 -1
  74. package/dist/mapAiSharedInstructions.d.ts +3 -0
  75. package/dist/mapAiSharedInstructions.d.ts.map +1 -0
  76. package/dist/mapAiSharedInstructions.js +16 -0
  77. package/dist/mapAiSharedInstructions.js.map +1 -0
  78. package/dist/mapConfig.d.ts +6 -0
  79. package/dist/mapConfig.d.ts.map +1 -1
  80. package/dist/mapConfig.js.map +1 -1
  81. package/dist/mapConfigUtils.d.ts.map +1 -1
  82. package/dist/mapConfigUtils.js +2 -0
  83. package/dist/mapConfigUtils.js.map +1 -1
  84. package/dist/mapFit.d.ts +16 -0
  85. package/dist/mapFit.d.ts.map +1 -1
  86. package/dist/mapFit.js +208 -30
  87. package/dist/mapFit.js.map +1 -1
  88. package/dist/mapLayerConfigUtils.d.ts +9 -1
  89. package/dist/mapLayerConfigUtils.d.ts.map +1 -1
  90. package/dist/mapLayerConfigUtils.js +62 -12
  91. package/dist/mapLayerConfigUtils.js.map +1 -1
  92. package/dist/mapResourceAuthoring.d.ts +2 -0
  93. package/dist/mapResourceAuthoring.d.ts.map +1 -1
  94. package/dist/mapResourceAuthoring.js +402 -16
  95. package/dist/mapResourceAuthoring.js.map +1 -1
  96. package/dist/mosaic.d.ts +1 -1
  97. package/dist/mosaic.d.ts.map +1 -1
  98. package/dist/mosaic.js.map +1 -1
  99. package/dist/prepare/geoarrow.js.map +1 -1
  100. package/dist/prepare/wkbDecoder.d.ts +10 -0
  101. package/dist/prepare/wkbDecoder.d.ts.map +1 -1
  102. package/dist/prepare/wkbDecoder.js +93 -18
  103. package/dist/prepare/wkbDecoder.js.map +1 -1
  104. package/dist/prepare/wkbParser.d.ts +7 -0
  105. package/dist/prepare/wkbParser.d.ts.map +1 -1
  106. package/dist/prepare/wkbParser.js +21 -0
  107. package/dist/prepare/wkbParser.js.map +1 -1
  108. package/dist/selectStarAsWkbCollision.d.ts +3 -0
  109. package/dist/selectStarAsWkbCollision.d.ts.map +1 -0
  110. package/dist/selectStarAsWkbCollision.js +78 -0
  111. package/dist/selectStarAsWkbCollision.js.map +1 -0
  112. package/dist/types.d.ts +1 -1
  113. package/dist/types.d.ts.map +1 -1
  114. package/dist/types.js.map +1 -1
  115. package/dist/useDeckMapFitToBounds.d.ts.map +1 -1
  116. package/dist/useDeckMapFitToBounds.js +1 -1
  117. package/dist/useDeckMapFitToBounds.js.map +1 -1
  118. package/package.json +15 -15
@@ -1 +1 @@
1
- {"version":3,"file":"rewriteGeoArrowAccessors.js","sourceRoot":"","sources":["../../src/json/rewriteGeoArrowAccessors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,EAAC,uBAAuB,EAAC,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAC,qBAAqB,EAAC,MAAM,sBAAsB,CAAC;AAE3D,SAAS,uBAAuB,CAAC,UAAkB;IACjD,OAAO,oBAAoB,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;AACtD,CAAC;AAED,SAAS,0BAA0B,CAAC,QAAgB,EAAE,MAAoB;IACxE,8EAA8E;IAC9E,kFAAkF;IAClF,+EAA+E;IAC/E,qEAAqE;IACrE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAChC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClC,IAAI,CAAC,UAAU,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,eAAe,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACpE,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,OAIxC;IACC,MAAM,EAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAC,GAAG,OAAO,CAAC;IAC1C,MAAM,aAAa,GAAG,qBAAqB,CAAC,SAAS,CAAC,CAAC;IACvD,IAAI,CAAC,aAAa,IAAI,aAAa,CAAC,cAAc,KAAK,UAAU,EAAE,CAAC;QAClE,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,SAAS,GAAG,EAAC,GAAG,KAAK,EAAC,CAAC;IAE7B,KAAK,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9D,IACE,OAAO,SAAS,KAAK,QAAQ;YAC7B,CAAC,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC;YAC5B,CAAC,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,EAC3B,CAAC;YACD,SAAS;QACX,CAAC;QAED,MAAM,UAAU,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACtC,IACE,aAAa,CAAC,mBAAmB,CAAC,QAAQ,CAAC,QAAQ,CAAC;YACpD,uBAAuB,CAAC,UAAU,CAAC,EACnC,CAAC;YACD,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;YACjD,IAAI,MAAM,IAAI,0BAA0B,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,CAAC;gBAC3D,SAAS,CAAC,QAAQ,CAAC,GAAG,MAAM,CAAC;gBAC7B,SAAS;YACX,CAAC;YACD,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,mEAAmE;gBACnE,mEAAmE;gBACnE,OAAO,CAAC,IAAI,CACV,WAAW,UAAU,CAAC,IAAI,EAAE,wCAAwC,QAAQ,IAAI,CACjF,CAAC;YACJ,CAAC;QACH,CAAC;QAED,4EAA4E;QAC5E,4EAA4E;QAC5E,gCAAgC;QAChC,SAAS,CAAC,QAAQ,CAAC,GAAG,uBAAuB,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IACnE,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC","sourcesContent":["import * as arrow from 'apache-arrow';\nimport {compileGeoArrowAccessor} from './compileGeoArrowAccessor';\nimport {getLayerCompatibility} from './layerCompatibility';\n\nfunction isSimpleColumnReference(expression: string) {\n return /^[A-Za-z_$][\\w$]*$/.test(expression.trim());\n}\n\nfunction canUseDirectVectorAccessor(propName: string, vector: arrow.Vector) {\n // Direct numeric vectors (for example `getRadius`) currently end up in deck's\n // binary attribute path and trigger `Float64Array` initialization failures in the\n // GeoArrow scatterplot wrapper. Re-test which direct vector accessors are safe\n // after verifying the 0.4.x runtime contract handles them correctly.\n if (!propName.endsWith('Color')) {\n return false;\n }\n\n const firstChunk = vector.data[0];\n if (!firstChunk || !arrow.DataType.isFixedSizeList(firstChunk.type)) {\n return false;\n }\n\n return true;\n}\n\nexport function rewriteGeoArrowAccessors(options: {\n props: Record<string, unknown>;\n table: arrow.Table;\n layerName: string;\n}) {\n const {props, table, layerName} = options;\n const compatibility = getLayerCompatibility(layerName);\n if (!compatibility || compatibility.representation !== 'geoarrow') {\n return props;\n }\n\n const nextProps = {...props};\n\n for (const [propName, propValue] of Object.entries(nextProps)) {\n if (\n typeof propValue !== 'string' ||\n !propValue.startsWith('@@=') ||\n !propName.startsWith('get')\n ) {\n continue;\n }\n\n const expression = propValue.slice(3);\n if (\n compatibility.vectorAccessorProps.includes(propName) &&\n isSimpleColumnReference(expression)\n ) {\n const vector = table.getChild(expression.trim());\n if (vector && canUseDirectVectorAccessor(propName, vector)) {\n nextProps[propName] = vector;\n continue;\n }\n if (!vector) {\n // Column not found — fall through to compileGeoArrowAccessor which\n // handles missing bindings gracefully (returns undefined per row).\n console.warn(\n `Column \"${expression.trim()}\" not found in dataset for accessor \"${propName}\".`,\n );\n }\n }\n\n // This custom compiler handles GeoArrow batch-oriented callbacks. The 0.4.x\n // layers call function accessors with {index, data: {data: batch}, target},\n // which this compiler produces.\n nextProps[propName] = compileGeoArrowAccessor(expression, table);\n }\n\n return nextProps;\n}\n"]}
1
+ {"version":3,"file":"rewriteGeoArrowAccessors.js","sourceRoot":"","sources":["../../src/json/rewriteGeoArrowAccessors.ts"],"names":[],"mappings":"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","sourcesContent":["import * as arrow from 'apache-arrow';\nimport {compileGeoArrowAccessor} from './compileGeoArrowAccessor';\nimport {getLayerCompatibility} from './layerCompatibility';\n\nfunction isSimpleColumnReference(expression: string) {\n return /^[A-Za-z_$][\\w$]*$/.test(expression.trim());\n}\n\nfunction canUseDirectVectorAccessor(propName: string, vector: arrow.Vector) {\n // H3 index columns are safe as Vectors — DeckH3HexagonLayer reads them\n // directly and converts BigInt → hex string when needed.\n if (propName === 'getHexagon') {\n const type = vector.type;\n return (\n arrow.DataType.isUtf8(type) ||\n arrow.DataType.isLargeUtf8(type) ||\n // DuckDB UBIGINT often arrives as Int(true, 64), not instanceof Int64.\n (arrow.DataType.isInt(type) && type.bitWidth === 64)\n );\n }\n\n // Direct numeric vectors (for example `getRadius`) currently end up in deck's\n // binary attribute path and trigger `Float64Array` initialization failures in the\n // GeoArrow scatterplot wrapper. Re-test which direct vector accessors are safe\n // after verifying the 0.4.x runtime contract handles them correctly.\n if (!propName.endsWith('Color')) {\n return false;\n }\n\n const firstChunk = vector.data[0];\n if (!firstChunk || !arrow.DataType.isFixedSizeList(firstChunk.type)) {\n return false;\n }\n\n return true;\n}\n\nexport function rewriteGeoArrowAccessors(options: {\n props: Record<string, unknown>;\n table: arrow.Table;\n layerName: string;\n}) {\n const {props, table, layerName} = options;\n const compatibility = getLayerCompatibility(layerName);\n if (!compatibility || compatibility.representation !== 'geoarrow') {\n return props;\n }\n\n const nextProps = {...props};\n\n for (const [propName, propValue] of Object.entries(nextProps)) {\n if (\n typeof propValue !== 'string' ||\n !propValue.startsWith('@@=') ||\n !propName.startsWith('get')\n ) {\n continue;\n }\n\n const expression = propValue.slice(3);\n if (\n compatibility.vectorAccessorProps.includes(propName) &&\n isSimpleColumnReference(expression)\n ) {\n const vector = table.getChild(expression.trim());\n if (vector && canUseDirectVectorAccessor(propName, vector)) {\n nextProps[propName] = vector;\n continue;\n }\n if (!vector) {\n // Column not found — fall through to compileGeoArrowAccessor which\n // handles missing bindings gracefully (returns undefined per row).\n console.warn(\n `Column \"${expression.trim()}\" not found in dataset for accessor \"${propName}\".`,\n );\n }\n }\n\n // This custom compiler handles GeoArrow batch-oriented callbacks. The 0.4.x\n // layers call function accessors with {index, data: {data: batch}, target},\n // which this compiler produces.\n nextProps[propName] = compileGeoArrowAccessor(expression, table);\n }\n\n return nextProps;\n}\n"]}
@@ -0,0 +1,30 @@
1
+ import type * as arrow from 'apache-arrow';
2
+ declare const SQLROOMS_SCALE_MARKER: unique symbol;
3
+ export type LinearScaleConfig = {
4
+ field: string;
5
+ type?: 'linear';
6
+ domain?: 'auto' | [number, number];
7
+ /** When set, map domain → range. When omitted, use raw field minus domain min. */
8
+ range?: [number, number];
9
+ };
10
+ export type ScaleMarker = LinearScaleConfig & {
11
+ [SQLROOMS_SCALE_MARKER]: true;
12
+ };
13
+ /** Marker returned by the Deck JSON `scale` function before table-aware compile. */
14
+ export declare function createScaleMarker(props: Record<string, unknown>): ScaleMarker | undefined;
15
+ export declare function isScaleMarker(value: unknown): value is ScaleMarker;
16
+ /**
17
+ * Linear scale `@@=` expression. Non-identifier fields need
18
+ * {@link compileLinearScaleAccessor}.
19
+ */
20
+ export declare function compileLinearScaleExpression(table: arrow.Table, scale: LinearScaleConfig): string | undefined;
21
+ /** Elevation accessor for any Arrow column name (incl. non-identifiers). */
22
+ export declare function compileLinearScaleAccessor(table: arrow.Table, scale: LinearScaleConfig): ((info: {
23
+ index: number;
24
+ data: {
25
+ data: unknown;
26
+ };
27
+ target: number[];
28
+ }) => number) | undefined;
29
+ export {};
30
+ //# sourceMappingURL=scaleFunction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaleFunction.d.ts","sourceRoot":"","sources":["../../src/json/scaleFunction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAC;AAG3C,QAAA,MAAM,qBAAqB,eAA8C,CAAC;AAE1E,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,kFAAkF;IAClF,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,iBAAiB,GAAG;IAC5C,CAAC,qBAAqB,CAAC,EAAE,IAAI,CAAC;CAC/B,CAAC;AAEF,oFAAoF;AACpF,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,WAAW,GAAG,SAAS,CA6BzB;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,WAAW,CAMlE;AAqBD;;;GAGG;AACH,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,KAAK,EAAE,iBAAiB,GACvB,MAAM,GAAG,SAAS,CA8BpB;AAED,4EAA4E;AAC5E,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,KAAK,EAAE,iBAAiB,GAEtB,CAAC,CAAC,IAAI,EAAE;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE;QAAC,IAAI,EAAE,OAAO,CAAA;KAAC,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAC,KAAK,MAAM,CAAC,GAC5E,SAAS,CAmCZ"}
@@ -0,0 +1,126 @@
1
+ import { isBindableGeoArrowFieldIdentifier } from './compileGeoArrowAccessor';
2
+ const SQLROOMS_SCALE_MARKER = Symbol.for('@sqlrooms/deck/sqlrooms-scale');
3
+ /** Marker returned by the Deck JSON `scale` function before table-aware compile. */
4
+ export function createScaleMarker(props) {
5
+ const field = typeof props.field === 'string' ? props.field.trim() : '';
6
+ if (!field)
7
+ return undefined;
8
+ const domain = props.domain === 'auto'
9
+ ? 'auto'
10
+ : Array.isArray(props.domain) &&
11
+ props.domain.length === 2 &&
12
+ typeof props.domain[0] === 'number' &&
13
+ typeof props.domain[1] === 'number'
14
+ ? [props.domain[0], props.domain[1]]
15
+ : 'auto';
16
+ const range = Array.isArray(props.range) &&
17
+ props.range.length === 2 &&
18
+ typeof props.range[0] === 'number' &&
19
+ typeof props.range[1] === 'number'
20
+ ? [props.range[0], props.range[1]]
21
+ : undefined;
22
+ return {
23
+ [SQLROOMS_SCALE_MARKER]: true,
24
+ field,
25
+ type: 'linear',
26
+ domain,
27
+ ...(range ? { range } : {}),
28
+ };
29
+ }
30
+ export function isScaleMarker(value) {
31
+ return Boolean(value &&
32
+ typeof value === 'object' &&
33
+ value[SQLROOMS_SCALE_MARKER]);
34
+ }
35
+ function readNumericDomain(vector) {
36
+ let min = Infinity;
37
+ let max = -Infinity;
38
+ for (let i = 0; i < vector.length; i++) {
39
+ // Arrow/SQL NULL must not become 0 via Number(null).
40
+ if (typeof vector.isValid === 'function' && !vector.isValid(i)) {
41
+ continue;
42
+ }
43
+ const raw = vector.get(i);
44
+ if (raw == null)
45
+ continue;
46
+ const v = Number(raw);
47
+ if (!Number.isFinite(v))
48
+ continue;
49
+ if (v < min)
50
+ min = v;
51
+ if (v > max)
52
+ max = v;
53
+ }
54
+ if (!Number.isFinite(min) || !Number.isFinite(max))
55
+ return null;
56
+ return [min, max];
57
+ }
58
+ /**
59
+ * Linear scale `@@=` expression. Non-identifier fields need
60
+ * {@link compileLinearScaleAccessor}.
61
+ */
62
+ export function compileLinearScaleExpression(table, scale) {
63
+ const field = scale.field.trim();
64
+ if (!field || !isBindableGeoArrowFieldIdentifier(field))
65
+ return undefined;
66
+ const vector = table.getChild(field);
67
+ if (!vector)
68
+ return undefined;
69
+ const domain = scale.domain === 'auto' || scale.domain === undefined
70
+ ? readNumericDomain(vector)
71
+ : scale.domain;
72
+ if (!domain)
73
+ return undefined;
74
+ const [d0, d1] = domain;
75
+ if (!scale.range) {
76
+ if (d0 === 0)
77
+ return `@@=${field}`;
78
+ return `@@=Math.max(0, ${field} - ${d0})`;
79
+ }
80
+ const [r0, r1] = scale.range;
81
+ const span = d1 - d0;
82
+ if (span === 0) {
83
+ return `@@=${r0}`;
84
+ }
85
+ const lo = Math.min(r0, r1);
86
+ const hi = Math.max(r0, r1);
87
+ // Clamp after linear map (bigint coercion lives in compileGeoArrowAccessor).
88
+ return `@@=Math.max(${lo}, Math.min(${hi}, ${r0} + (${field} - ${d0}) / ${span} * ${r1 - r0}))`;
89
+ }
90
+ /** Elevation accessor for any Arrow column name (incl. non-identifiers). */
91
+ export function compileLinearScaleAccessor(table, scale) {
92
+ const field = scale.field.trim();
93
+ if (!field)
94
+ return undefined;
95
+ const vector = table.getChild(field);
96
+ if (!vector)
97
+ return undefined;
98
+ const domain = scale.domain === 'auto' || scale.domain === undefined
99
+ ? readNumericDomain(vector)
100
+ : scale.domain;
101
+ if (!domain)
102
+ return undefined;
103
+ const [d0, d1] = domain;
104
+ const range = scale.range;
105
+ return ({ index, data }) => {
106
+ const batch = data.data;
107
+ const child = batch.getChild?.(field) ?? vector;
108
+ const raw = child?.get(index);
109
+ if (raw == null)
110
+ return 0;
111
+ const v = Number(raw);
112
+ if (!Number.isFinite(v))
113
+ return 0;
114
+ if (!range) {
115
+ return Math.max(0, v - d0);
116
+ }
117
+ const [r0, r1] = range;
118
+ const span = d1 - d0;
119
+ if (span === 0)
120
+ return r0;
121
+ const lo = Math.min(r0, r1);
122
+ const hi = Math.max(r0, r1);
123
+ return Math.max(lo, Math.min(hi, r0 + ((v - d0) / span) * (r1 - r0)));
124
+ };
125
+ }
126
+ //# sourceMappingURL=scaleFunction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaleFunction.js","sourceRoot":"","sources":["../../src/json/scaleFunction.ts"],"names":[],"mappings":"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","sourcesContent":["import type * as arrow from 'apache-arrow';\nimport {isBindableGeoArrowFieldIdentifier} from './compileGeoArrowAccessor';\n\nconst SQLROOMS_SCALE_MARKER = Symbol.for('@sqlrooms/deck/sqlrooms-scale');\n\nexport type LinearScaleConfig = {\n field: string;\n type?: 'linear';\n domain?: 'auto' | [number, number];\n /** When set, map domain → range. When omitted, use raw field minus domain min. */\n range?: [number, number];\n};\n\nexport type ScaleMarker = LinearScaleConfig & {\n [SQLROOMS_SCALE_MARKER]: true;\n};\n\n/** Marker returned by the Deck JSON `scale` function before table-aware compile. */\nexport function createScaleMarker(\n props: Record<string, unknown>,\n): ScaleMarker | undefined {\n const field = typeof props.field === 'string' ? props.field.trim() : '';\n if (!field) return undefined;\n\n const domain =\n props.domain === 'auto'\n ? 'auto'\n : Array.isArray(props.domain) &&\n props.domain.length === 2 &&\n typeof props.domain[0] === 'number' &&\n typeof props.domain[1] === 'number'\n ? ([props.domain[0], props.domain[1]] as [number, number])\n : 'auto';\n\n const range =\n Array.isArray(props.range) &&\n props.range.length === 2 &&\n typeof props.range[0] === 'number' &&\n typeof props.range[1] === 'number'\n ? ([props.range[0], props.range[1]] as [number, number])\n : undefined;\n\n return {\n [SQLROOMS_SCALE_MARKER]: true,\n field,\n type: 'linear',\n domain,\n ...(range ? {range} : {}),\n };\n}\n\nexport function isScaleMarker(value: unknown): value is ScaleMarker {\n return Boolean(\n value &&\n typeof value === 'object' &&\n (value as {[SQLROOMS_SCALE_MARKER]?: boolean})[SQLROOMS_SCALE_MARKER],\n );\n}\n\nfunction readNumericDomain(vector: arrow.Vector): [number, number] | null {\n let min = Infinity;\n let max = -Infinity;\n for (let i = 0; i < vector.length; i++) {\n // Arrow/SQL NULL must not become 0 via Number(null).\n if (typeof vector.isValid === 'function' && !vector.isValid(i)) {\n continue;\n }\n const raw = vector.get(i);\n if (raw == null) continue;\n const v = Number(raw);\n if (!Number.isFinite(v)) continue;\n if (v < min) min = v;\n if (v > max) max = v;\n }\n if (!Number.isFinite(min) || !Number.isFinite(max)) return null;\n return [min, max];\n}\n\n/**\n * Linear scale `@@=` expression. Non-identifier fields need\n * {@link compileLinearScaleAccessor}.\n */\nexport function compileLinearScaleExpression(\n table: arrow.Table,\n scale: LinearScaleConfig,\n): string | undefined {\n const field = scale.field.trim();\n if (!field || !isBindableGeoArrowFieldIdentifier(field)) return undefined;\n\n const vector = table.getChild(field);\n if (!vector) return undefined;\n\n const domain =\n scale.domain === 'auto' || scale.domain === undefined\n ? readNumericDomain(vector)\n : scale.domain;\n if (!domain) return undefined;\n\n const [d0, d1] = domain;\n\n if (!scale.range) {\n if (d0 === 0) return `@@=${field}`;\n return `@@=Math.max(0, ${field} - ${d0})`;\n }\n\n const [r0, r1] = scale.range;\n const span = d1 - d0;\n if (span === 0) {\n return `@@=${r0}`;\n }\n\n const lo = Math.min(r0, r1);\n const hi = Math.max(r0, r1);\n // Clamp after linear map (bigint coercion lives in compileGeoArrowAccessor).\n return `@@=Math.max(${lo}, Math.min(${hi}, ${r0} + (${field} - ${d0}) / ${span} * ${r1 - r0}))`;\n}\n\n/** Elevation accessor for any Arrow column name (incl. non-identifiers). */\nexport function compileLinearScaleAccessor(\n table: arrow.Table,\n scale: LinearScaleConfig,\n):\n | ((info: {index: number; data: {data: unknown}; target: number[]}) => number)\n | undefined {\n const field = scale.field.trim();\n if (!field) return undefined;\n\n const vector = table.getChild(field);\n if (!vector) return undefined;\n\n const domain =\n scale.domain === 'auto' || scale.domain === undefined\n ? readNumericDomain(vector)\n : scale.domain;\n if (!domain) return undefined;\n\n const [d0, d1] = domain;\n const range = scale.range;\n\n return ({index, data}) => {\n const batch = data.data as arrow.Table | arrow.RecordBatch;\n const child = batch.getChild?.(field) ?? vector;\n const raw = child?.get(index);\n if (raw == null) return 0;\n const v = Number(raw);\n if (!Number.isFinite(v)) return 0;\n\n if (!range) {\n return Math.max(0, v - d0);\n }\n\n const [r0, r1] = range;\n const span = d1 - d0;\n if (span === 0) return r0;\n const lo = Math.min(r0, r1);\n const hi = Math.max(r0, r1);\n return Math.max(lo, Math.min(hi, r0 + ((v - d0) / span) * (r1 - r0)));\n };\n}\n"]}
@@ -39,6 +39,7 @@ export declare const DeckMapResourceConfigParameter: z.ZodObject<{
39
39
  longitudeColumn: z.ZodOptional<z.ZodString>;
40
40
  latitudeColumn: z.ZodOptional<z.ZodString>;
41
41
  geometryColumn: z.ZodOptional<z.ZodString>;
42
+ geometryColumns: z.ZodOptional<z.ZodArray<z.ZodString>>;
42
43
  h3Column: z.ZodOptional<z.ZodString>;
43
44
  padding: z.ZodOptional<z.ZodNumber>;
44
45
  maxZoom: z.ZodOptional<z.ZodNumber>;
@@ -92,6 +93,7 @@ export declare const DeckMapResourceToolParameters: z.ZodObject<{
92
93
  longitudeColumn: z.ZodOptional<z.ZodString>;
93
94
  latitudeColumn: z.ZodOptional<z.ZodString>;
94
95
  geometryColumn: z.ZodOptional<z.ZodString>;
96
+ geometryColumns: z.ZodOptional<z.ZodArray<z.ZodString>>;
95
97
  h3Column: z.ZodOptional<z.ZodString>;
96
98
  padding: z.ZodOptional<z.ZodNumber>;
97
99
  maxZoom: z.ZodOptional<z.ZodNumber>;
@@ -1 +1 @@
1
- {"version":3,"file":"mapAiConfig.d.ts","sourceRoot":"","sources":["../src/mapAiConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAuCtB,kFAAkF;AAClF,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAqBN,CAAC;AAEtC,mFAAmF;AACnF,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiBxC,CAAC"}
1
+ {"version":3,"file":"mapAiConfig.d.ts","sourceRoot":"","sources":["../src/mapAiConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAwCtB,kFAAkF;AAClF,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAqBN,CAAC;AAEtC,mFAAmF;AACnF,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiBxC,CAAC"}
@@ -26,6 +26,7 @@ const DeckMapFitToDataConfig = z.looseObject({
26
26
  longitudeColumn: z.string().optional(),
27
27
  latitudeColumn: z.string().optional(),
28
28
  geometryColumn: z.string().optional(),
29
+ geometryColumns: z.array(z.string()).optional(),
29
30
  h3Column: z.string().optional(),
30
31
  padding: z.number().optional(),
31
32
  maxZoom: z.number().optional(),
@@ -35,7 +36,7 @@ export const DeckMapResourceConfigParameter = z.looseObject({
35
36
  spec: z.union([z.string(), z.record(z.string(), z.unknown())]),
36
37
  datasets: z
37
38
  .record(z.string(), DeckMapDatasetConfig)
38
- .describe('Resource datasets keyed by id. Every dataset in a new map must define source.tableName or source.sqlQuery.'),
39
+ .describe('Resource datasets keyed by id. Every dataset in a new map must define source.tableName or source.sqlQuery. For visual-only updates send an empty object {} so merge keeps the existing registry — do not omit this field.'),
39
40
  configMode: z.enum(['basic', 'custom']).optional(),
40
41
  mapStyle: z.string().optional(),
41
42
  mapProps: z.record(z.string(), z.unknown()).optional(),
@@ -1 +1 @@
1
- {"version":3,"file":"mapAiConfig.js","sourceRoot":"","sources":["../src/mapAiConfig.ts"],"names":[],"mappings":"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","sourcesContent":["import {z} from 'zod';\nimport type {DeckMapConfig} from './mapConfig';\n\nconst DeckMapDatasetSource = z.union([\n z.looseObject({\n sqlQuery: z.string(),\n }),\n z.looseObject({\n tableName: z.string(),\n transformSql: z.string().optional(),\n }),\n]);\nconst DeckMapDatasetConfig = z.looseObject({\n source: DeckMapDatasetSource.optional().describe(\n 'Dataset source. Required for new maps; may be omitted only by a sparse update patch that retains an existing source.',\n ),\n geometryColumn: z.string().optional(),\n geometryEncodingHint: z.enum(['geoarrow', 'wkb', 'wkt']).optional(),\n});\n\nconst DeckMapInteractionConfig = z.looseObject({\n type: z.literal('point-radius-brush'),\n dataset: z.string(),\n longitudeColumn: z.string(),\n latitudeColumn: z.string(),\n radiusMeters: z.number().optional(),\n event: z.enum(['hover', 'click']).optional(),\n});\n\nconst DeckMapFitToDataConfig = z.looseObject({\n dataset: z.string(),\n longitudeColumn: z.string().optional(),\n latitudeColumn: z.string().optional(),\n geometryColumn: z.string().optional(),\n h3Column: z.string().optional(),\n padding: z.number().optional(),\n maxZoom: z.number().optional(),\n});\n\n/** Validates the portable Deck map config accepted from commands and AI tools. */\nexport const DeckMapResourceConfigParameter = z.looseObject({\n spec: z.union([z.string(), z.record(z.string(), z.unknown())]),\n datasets: z\n .record(z.string(), DeckMapDatasetConfig)\n .describe(\n 'Resource datasets keyed by id. Every dataset in a new map must define source.tableName or source.sqlQuery.',\n ),\n configMode: z.enum(['basic', 'custom']).optional(),\n mapStyle: z.string().optional(),\n mapProps: z.record(z.string(), z.unknown()).optional(),\n showLegends: z.boolean().optional(),\n interaction: DeckMapInteractionConfig.optional(),\n fitToData: DeckMapFitToDataConfig.optional(),\n dataPolicy: z\n .looseObject({\n disabled: z.boolean().optional(),\n maxRows: z.number().int().min(1).optional(),\n reason: z.string().optional(),\n })\n .optional(),\n settingsOpen: z.boolean().optional(),\n}) satisfies z.ZodType<DeckMapConfig>;\n\n/** Validates inputs for an AI or command invocation that writes a map resource. */\nexport const DeckMapResourceToolParameters = z.object({\n title: z.string().optional().default('Map'),\n config: DeckMapResourceConfigParameter,\n tableName: z.string().optional(),\n replaceLayers: z\n .boolean()\n .optional()\n .describe(\n 'Set true when config.spec.layers is the complete desired list and omitted existing layers should be removed.',\n ),\n replaceDatasets: z\n .boolean()\n .optional()\n .describe(\n 'Set true when config.datasets is the complete desired registry and omitted existing datasets should be removed.',\n ),\n reasoning: z.string(),\n});\n"]}
1
+ {"version":3,"file":"mapAiConfig.js","sourceRoot":"","sources":["../src/mapAiConfig.ts"],"names":[],"mappings":"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","sourcesContent":["import {z} from 'zod';\nimport type {DeckMapConfig} from './mapConfig';\n\nconst DeckMapDatasetSource = z.union([\n z.looseObject({\n sqlQuery: z.string(),\n }),\n z.looseObject({\n tableName: z.string(),\n transformSql: z.string().optional(),\n }),\n]);\nconst DeckMapDatasetConfig = z.looseObject({\n source: DeckMapDatasetSource.optional().describe(\n 'Dataset source. Required for new maps; may be omitted only by a sparse update patch that retains an existing source.',\n ),\n geometryColumn: z.string().optional(),\n geometryEncodingHint: z.enum(['geoarrow', 'wkb', 'wkt']).optional(),\n});\n\nconst DeckMapInteractionConfig = z.looseObject({\n type: z.literal('point-radius-brush'),\n dataset: z.string(),\n longitudeColumn: z.string(),\n latitudeColumn: z.string(),\n radiusMeters: z.number().optional(),\n event: z.enum(['hover', 'click']).optional(),\n});\n\nconst DeckMapFitToDataConfig = z.looseObject({\n dataset: z.string(),\n longitudeColumn: z.string().optional(),\n latitudeColumn: z.string().optional(),\n geometryColumn: z.string().optional(),\n geometryColumns: z.array(z.string()).optional(),\n h3Column: z.string().optional(),\n padding: z.number().optional(),\n maxZoom: z.number().optional(),\n});\n\n/** Validates the portable Deck map config accepted from commands and AI tools. */\nexport const DeckMapResourceConfigParameter = z.looseObject({\n spec: z.union([z.string(), z.record(z.string(), z.unknown())]),\n datasets: z\n .record(z.string(), DeckMapDatasetConfig)\n .describe(\n 'Resource datasets keyed by id. Every dataset in a new map must define source.tableName or source.sqlQuery. For visual-only updates send an empty object {} so merge keeps the existing registry — do not omit this field.',\n ),\n configMode: z.enum(['basic', 'custom']).optional(),\n mapStyle: z.string().optional(),\n mapProps: z.record(z.string(), z.unknown()).optional(),\n showLegends: z.boolean().optional(),\n interaction: DeckMapInteractionConfig.optional(),\n fitToData: DeckMapFitToDataConfig.optional(),\n dataPolicy: z\n .looseObject({\n disabled: z.boolean().optional(),\n maxRows: z.number().int().min(1).optional(),\n reason: z.string().optional(),\n })\n .optional(),\n settingsOpen: z.boolean().optional(),\n}) satisfies z.ZodType<DeckMapConfig>;\n\n/** Validates inputs for an AI or command invocation that writes a map resource. */\nexport const DeckMapResourceToolParameters = z.object({\n title: z.string().optional().default('Map'),\n config: DeckMapResourceConfigParameter,\n tableName: z.string().optional(),\n replaceLayers: z\n .boolean()\n .optional()\n .describe(\n 'Set true when config.spec.layers is the complete desired list and omitted existing layers should be removed.',\n ),\n replaceDatasets: z\n .boolean()\n .optional()\n .describe(\n 'Set true when config.datasets is the complete desired registry and omitted existing datasets should be removed.',\n ),\n reasoning: z.string(),\n});\n"]}
@@ -0,0 +1,3 @@
1
+ /** Shared Deck map AI rules for dashboard and worksheet prompts. */
2
+ export declare function getDeckMapSharedAiContractRules(): string;
3
+ //# sourceMappingURL=mapAiSharedInstructions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mapAiSharedInstructions.d.ts","sourceRoot":"","sources":["../src/mapAiSharedInstructions.ts"],"names":[],"mappings":"AAEA,oEAAoE;AACpE,wBAAgB,+BAA+B,IAAI,MAAM,CAYxD"}
@@ -0,0 +1,16 @@
1
+ import { DECK_TABLE_DATASET_SOURCE_RELATION } from './datasets/tableDatasetSql';
2
+ /** Shared Deck map AI rules for dashboard and worksheet prompts. */
3
+ export function getDeckMapSharedAiContractRules() {
4
+ const src = DECK_TABLE_DATASET_SOURCE_RELATION;
5
+ return `Shared Deck map authoring rules (dashboard and worksheet):
6
+ - Scatterplot/Heatmap/Column require Point positions — do not bind them to Polygon/MultiPolygon geom. Prefer GeoArrowPolygonLayer / GeoArrowSolidPolygonLayer for Polygon, GeoJsonLayer for WKB/WKT MultiPolygon, or transformSql with ST_AsWKB(ST_Centroid(geom)) / ST_PointOnSurface(geom) when the user wants points (e.g. SELECT * EXCLUDE (geom), ST_AsWKB(ST_Centroid(geom)) AS geom FROM ${src}). The runtime will not invent centroids.
7
+ - Mixed Point/LineString/Polygon columns: use GeoJsonLayer. Typed GeoArrowPolygon/Path/Scatterplot layers need a uniform geometry type. To keep one class, filter with WHERE ST_GeometryType(geom) IN (...) then use the matching typed layer.
8
+ - Never write SELECT *, ST_AsWKB(col) AS col — DuckDB keeps the original column and the WKB alias collides. Use SELECT * EXCLUDE (col), ST_AsWKB(...) AS col, or omit transformSql when geom already exists. Bare ST_Point(...) / table GEOMETRY columns are projected to WKB by the dataset pipeline; prefer explicit ST_AsWKB when practical.
9
+ - GeoArrowHeatmapLayer: omit colorRange (UI scheme selector owns it) and omit getWeight (default uniform density). Do not bind getWeight to a column — basic mode has no weight-column control.
10
+ - Never set mapStyle to a mapbox:// URL — MapLibre cannot load that scheme. Omit mapStyle for the host basemap, or use a token-free MapLibre https:// style URL.
11
+ - GeoArrowH3HexagonLayer: set getHexagon to "@@=h3_column" (or _sqlroomsBinding.hexagonColumn). When aggregating lon/lat, prefer h3_h3_to_string(h3_latlng_to_cell(lat, lon, res)) AS h3_cell (lat before lon).
12
+ - GeoArrowArcLayer: bind WKB via _sqlroomsBinding.sourceGeometryColumn / targetGeometryColumn only (do not set getSourcePosition/getTargetPosition). Use ST_AsWKB(ST_Point(...)); set geometryEncodingHint to "wkb".
13
+ - GeoArrowTripsLayer = animated path over time; GeoArrowArcLayer = static OD curve. Prefer TripsLayer for animated/trips/moving routes.
14
+ - COLOR SCALE FIELD VARIANCE: Before choosing a numeric colorScale field, confirm it has real range (min < max / not all zeros or a single constant). Prefer SUMMARIZE table_name or SELECT min(col), max(col), count(DISTINCT col) FROM ... when unsure. Do NOT color by a flat column unless the user explicitly asks for that column by name. If no varying column exists, use a flat fill color instead of colorScale. Categorical fields need more than one distinct non-null value to be useful. Geometry, lon/lat, H3 index, and opaque ID columns are not useful color fields unless the user asks for them.`;
15
+ }
16
+ //# sourceMappingURL=mapAiSharedInstructions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mapAiSharedInstructions.js","sourceRoot":"","sources":["../src/mapAiSharedInstructions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,kCAAkC,EAAC,MAAM,4BAA4B,CAAC;AAE9E,oEAAoE;AACpE,MAAM,UAAU,+BAA+B;IAC7C,MAAM,GAAG,GAAG,kCAAkC,CAAC;IAC/C,OAAO;kYACyX,GAAG;;;;;;;;qlBAQgN,CAAC;AACtlB,CAAC","sourcesContent":["import {DECK_TABLE_DATASET_SOURCE_RELATION} from './datasets/tableDatasetSql';\n\n/** Shared Deck map AI rules for dashboard and worksheet prompts. */\nexport function getDeckMapSharedAiContractRules(): string {\n const src = DECK_TABLE_DATASET_SOURCE_RELATION;\n return `Shared Deck map authoring rules (dashboard and worksheet):\n- Scatterplot/Heatmap/Column require Point positions — do not bind them to Polygon/MultiPolygon geom. Prefer GeoArrowPolygonLayer / GeoArrowSolidPolygonLayer for Polygon, GeoJsonLayer for WKB/WKT MultiPolygon, or transformSql with ST_AsWKB(ST_Centroid(geom)) / ST_PointOnSurface(geom) when the user wants points (e.g. SELECT * EXCLUDE (geom), ST_AsWKB(ST_Centroid(geom)) AS geom FROM ${src}). The runtime will not invent centroids.\n- Mixed Point/LineString/Polygon columns: use GeoJsonLayer. Typed GeoArrowPolygon/Path/Scatterplot layers need a uniform geometry type. To keep one class, filter with WHERE ST_GeometryType(geom) IN (...) then use the matching typed layer.\n- Never write SELECT *, ST_AsWKB(col) AS col — DuckDB keeps the original column and the WKB alias collides. Use SELECT * EXCLUDE (col), ST_AsWKB(...) AS col, or omit transformSql when geom already exists. Bare ST_Point(...) / table GEOMETRY columns are projected to WKB by the dataset pipeline; prefer explicit ST_AsWKB when practical.\n- GeoArrowHeatmapLayer: omit colorRange (UI scheme selector owns it) and omit getWeight (default uniform density). Do not bind getWeight to a column — basic mode has no weight-column control.\n- Never set mapStyle to a mapbox:// URL — MapLibre cannot load that scheme. Omit mapStyle for the host basemap, or use a token-free MapLibre https:// style URL.\n- GeoArrowH3HexagonLayer: set getHexagon to \"@@=h3_column\" (or _sqlroomsBinding.hexagonColumn). When aggregating lon/lat, prefer h3_h3_to_string(h3_latlng_to_cell(lat, lon, res)) AS h3_cell (lat before lon).\n- GeoArrowArcLayer: bind WKB via _sqlroomsBinding.sourceGeometryColumn / targetGeometryColumn only (do not set getSourcePosition/getTargetPosition). Use ST_AsWKB(ST_Point(...)); set geometryEncodingHint to \"wkb\".\n- GeoArrowTripsLayer = animated path over time; GeoArrowArcLayer = static OD curve. Prefer TripsLayer for animated/trips/moving routes.\n- COLOR SCALE FIELD VARIANCE: Before choosing a numeric colorScale field, confirm it has real range (min < max / not all zeros or a single constant). Prefer SUMMARIZE table_name or SELECT min(col), max(col), count(DISTINCT col) FROM ... when unsure. Do NOT color by a flat column unless the user explicitly asks for that column by name. If no varying column exists, use a flat fill color instead of colorScale. Categorical fields need more than one distinct non-null value to be useful. Geometry, lon/lat, H3 index, and opaque ID columns are not useful color fields unless the user asks for them.`;\n}\n"]}
@@ -27,6 +27,12 @@ export type DeckMapFitToDataConfig = {
27
27
  longitudeColumn?: string;
28
28
  latitudeColumn?: string;
29
29
  geometryColumn?: string;
30
+ /**
31
+ * Multiple geometry columns whose extents should be combined when fitting
32
+ * the view. Used for arc layers that have separate source and target
33
+ * geometries — a single `geometryColumn` would only cover one endpoint.
34
+ */
35
+ geometryColumns?: string[];
30
36
  h3Column?: string;
31
37
  padding?: number;
32
38
  maxZoom?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"mapConfig.d.ts","sourceRoot":"","sources":["../src/mapConfig.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mapConfig.d.ts","sourceRoot":"","sources":["../src/mapConfig.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"mapConfig.js","sourceRoot":"","sources":["../src/mapConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,sBAAsB,CAAC;AAO9C,MAAM,CAAC,MAAM,6BAA6B,GAAG,eAAe,CAAC;AAC7D,MAAM,CAAC,MAAM,gCAAgC,GAAG,OAAO,CAAC;AAgBxD,0EAA0E;AAC1E,MAAM,UAAU,yBAAyB,CACvC,MAAwC;IAExC,OAAO,OAAO,CAAC,MAAM,IAAI,UAAU,IAAI,MAAM,CAAC,CAAC;AACjD,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,2BAA2B,CACzC,MAAwC;IAExC,OAAO,OAAO,CAAC,MAAM,IAAI,WAAW,IAAI,MAAM,CAAC,CAAC;AAClD,CAAC;AAqCD,wEAAwE;AACxE,MAAM,UAAU,wBAAwB;IACtC,OAAO;QACL,IAAI,EAAE;YACJ,gBAAgB,EAAE,EAAC,SAAS,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAC;YACzD,MAAM,EAAE,EAAE;SACX;QACD,QAAQ,EAAE,EAAE;KACb,CAAC;AACJ,CAAC;AASD,MAAM,CAAC,MAAM,kCAAkC,GAAG,yBAAyB,CAAC;AAC5E,MAAM,CAAC,MAAM,oCAAoC,GAAG,2BAA2B,CAAC;AAMhF,oEAAoE;AACpE,MAAM,UAAU,iCAAiC,CAC/C,OAAiD;IAEjD,MAAM,EAAC,KAAK,EAAE,GAAG,MAAM,EAAC,GAAG,OAAO,CAAC;IACnC,OAAO;QACL,EAAE,EAAE,QAAQ,EAAE;QACd,IAAI,EAAE,6BAA6B;QACnC,KAAK,EAAE,KAAK,IAAI,KAAK;QACrB,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAA4B;KACtE,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CACjC,MAA+B;IAE/B,IACE,CAAC,MAAM,CAAC,IAAI;QACZ,CAAC,MAAM,CAAC,QAAQ;QAChB,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ;QACnC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,EAC9B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,MAAuB,CAAC;AACjC,CAAC","sourcesContent":["import {createId} from '@paralleldrive/cuid2';\nimport type {\n DeckJsonMapProps,\n DeckSqlDatasetInput,\n DeckTableDatasetInput,\n} from './types';\n\nexport const DECK_MAP_DASHBOARD_PANEL_TYPE = 'deck-json-map';\nexport const DEFAULT_DECK_MAP_MAX_DATA_POINTS = 100_000;\n\nexport type DeckMapDataPolicyOverride = {\n disabled?: boolean;\n maxRows?: number;\n reason?: string;\n};\n\nexport type DeckMapDatasetSource =\n | Pick<DeckSqlDatasetInput, 'sqlQuery'>\n | Pick<DeckTableDatasetInput, 'tableName' | 'transformSql'>;\n\nexport type DeckMapDatasetConfig = Omit<DeckSqlDatasetInput, 'sqlQuery'> & {\n source?: DeckMapDatasetSource;\n};\n\n/** Returns whether a map dataset source is a pinned literal SQL query. */\nexport function isDeckMapSqlDatasetSource(\n source: DeckMapDatasetSource | undefined,\n): source is Pick<DeckSqlDatasetInput, 'sqlQuery'> {\n return Boolean(source && 'sqlQuery' in source);\n}\n\n/** Returns whether a map dataset source is backed by a named table. */\nexport function isDeckMapTableDatasetSource(\n source: DeckMapDatasetSource | undefined,\n): source is Pick<DeckTableDatasetInput, 'tableName' | 'transformSql'> {\n return Boolean(source && 'tableName' in source);\n}\n\nexport type DeckMapInteractionConfig = {\n type: 'point-radius-brush';\n dataset: string;\n longitudeColumn: string;\n latitudeColumn: string;\n radiusMeters?: number;\n event?: 'hover' | 'click';\n};\n\nexport type DeckMapFitToDataConfig = {\n dataset: string;\n longitudeColumn?: string;\n latitudeColumn?: string;\n geometryColumn?: string;\n h3Column?: string;\n padding?: number;\n maxZoom?: number;\n};\n\nexport type DeckMapConfigMode = 'basic' | 'custom';\n\n/** Durable, host-neutral Deck map configuration. */\nexport type DeckMapConfig = {\n spec: DeckJsonMapProps['spec'];\n datasets: Record<string, DeckMapDatasetConfig>;\n configMode?: DeckMapConfigMode;\n mapStyle?: string;\n mapProps?: Record<string, unknown>;\n showLegends?: boolean;\n interaction?: DeckMapInteractionConfig;\n fitToData?: DeckMapFitToDataConfig;\n dataPolicy?: DeckMapDataPolicyOverride;\n settingsOpen?: boolean;\n};\n\n/** Creates the portable empty configuration used for a new Deck map. */\nexport function createEmptyDeckMapConfig(): DeckMapConfig {\n return {\n spec: {\n initialViewState: {longitude: 0, latitude: 20, zoom: 1.5},\n layers: [],\n },\n datasets: {},\n };\n}\n\n/** Adapter-facing dashboard panel shape; worksheet resources never store it. */\nexport type DeckMapDashboardPanelConfig = DeckMapConfig;\nexport type DeckMapDashboardDatasetConfig = DeckMapDatasetConfig;\nexport type DeckMapDashboardDatasetSource = DeckMapDatasetSource;\nexport type DeckMapDashboardInteractionConfig = DeckMapInteractionConfig;\nexport type DeckMapDashboardFitToDataConfig = DeckMapFitToDataConfig;\n\nexport const isDeckMapDashboardSqlDatasetSource = isDeckMapSqlDatasetSource;\nexport const isDeckMapDashboardTableDatasetSource = isDeckMapTableDatasetSource;\n\nexport type CreateDeckMapDashboardPanelConfigOptions = DeckMapConfig & {\n title?: string;\n};\n\n/** Creates a Mosaic panel only for the opt-in dashboard adapter. */\nexport function createDeckMapDashboardPanelConfig(\n options: CreateDeckMapDashboardPanelConfigOptions,\n) {\n const {title, ...config} = options;\n return {\n id: createId(),\n type: DECK_MAP_DASHBOARD_PANEL_TYPE,\n title: title ?? 'Map',\n config: JSON.parse(JSON.stringify(config)) as Record<string, unknown>,\n };\n}\n\n/**\n * Returns a record as a Deck map config when it has the required top-level\n * spec and dataset registry, otherwise returns `null`.\n */\nexport function asDeckJsonMapConfig(\n config: Record<string, unknown>,\n): DeckMapConfig | null {\n if (\n !config.spec ||\n !config.datasets ||\n typeof config.datasets !== 'object' ||\n Array.isArray(config.datasets)\n ) {\n return null;\n }\n return config as DeckMapConfig;\n}\n"]}
1
+ {"version":3,"file":"mapConfig.js","sourceRoot":"","sources":["../src/mapConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,sBAAsB,CAAC;AAO9C,MAAM,CAAC,MAAM,6BAA6B,GAAG,eAAe,CAAC;AAC7D,MAAM,CAAC,MAAM,gCAAgC,GAAG,OAAO,CAAC;AAgBxD,0EAA0E;AAC1E,MAAM,UAAU,yBAAyB,CACvC,MAAwC;IAExC,OAAO,OAAO,CAAC,MAAM,IAAI,UAAU,IAAI,MAAM,CAAC,CAAC;AACjD,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,2BAA2B,CACzC,MAAwC;IAExC,OAAO,OAAO,CAAC,MAAM,IAAI,WAAW,IAAI,MAAM,CAAC,CAAC;AAClD,CAAC;AA2CD,wEAAwE;AACxE,MAAM,UAAU,wBAAwB;IACtC,OAAO;QACL,IAAI,EAAE;YACJ,gBAAgB,EAAE,EAAC,SAAS,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAC;YACzD,MAAM,EAAE,EAAE;SACX;QACD,QAAQ,EAAE,EAAE;KACb,CAAC;AACJ,CAAC;AASD,MAAM,CAAC,MAAM,kCAAkC,GAAG,yBAAyB,CAAC;AAC5E,MAAM,CAAC,MAAM,oCAAoC,GAAG,2BAA2B,CAAC;AAMhF,oEAAoE;AACpE,MAAM,UAAU,iCAAiC,CAC/C,OAAiD;IAEjD,MAAM,EAAC,KAAK,EAAE,GAAG,MAAM,EAAC,GAAG,OAAO,CAAC;IACnC,OAAO;QACL,EAAE,EAAE,QAAQ,EAAE;QACd,IAAI,EAAE,6BAA6B;QACnC,KAAK,EAAE,KAAK,IAAI,KAAK;QACrB,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAA4B;KACtE,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CACjC,MAA+B;IAE/B,IACE,CAAC,MAAM,CAAC,IAAI;QACZ,CAAC,MAAM,CAAC,QAAQ;QAChB,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ;QACnC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,EAC9B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,MAAuB,CAAC;AACjC,CAAC","sourcesContent":["import {createId} from '@paralleldrive/cuid2';\nimport type {\n DeckJsonMapProps,\n DeckSqlDatasetInput,\n DeckTableDatasetInput,\n} from './types';\n\nexport const DECK_MAP_DASHBOARD_PANEL_TYPE = 'deck-json-map';\nexport const DEFAULT_DECK_MAP_MAX_DATA_POINTS = 100_000;\n\nexport type DeckMapDataPolicyOverride = {\n disabled?: boolean;\n maxRows?: number;\n reason?: string;\n};\n\nexport type DeckMapDatasetSource =\n | Pick<DeckSqlDatasetInput, 'sqlQuery'>\n | Pick<DeckTableDatasetInput, 'tableName' | 'transformSql'>;\n\nexport type DeckMapDatasetConfig = Omit<DeckSqlDatasetInput, 'sqlQuery'> & {\n source?: DeckMapDatasetSource;\n};\n\n/** Returns whether a map dataset source is a pinned literal SQL query. */\nexport function isDeckMapSqlDatasetSource(\n source: DeckMapDatasetSource | undefined,\n): source is Pick<DeckSqlDatasetInput, 'sqlQuery'> {\n return Boolean(source && 'sqlQuery' in source);\n}\n\n/** Returns whether a map dataset source is backed by a named table. */\nexport function isDeckMapTableDatasetSource(\n source: DeckMapDatasetSource | undefined,\n): source is Pick<DeckTableDatasetInput, 'tableName' | 'transformSql'> {\n return Boolean(source && 'tableName' in source);\n}\n\nexport type DeckMapInteractionConfig = {\n type: 'point-radius-brush';\n dataset: string;\n longitudeColumn: string;\n latitudeColumn: string;\n radiusMeters?: number;\n event?: 'hover' | 'click';\n};\n\nexport type DeckMapFitToDataConfig = {\n dataset: string;\n longitudeColumn?: string;\n latitudeColumn?: string;\n geometryColumn?: string;\n /**\n * Multiple geometry columns whose extents should be combined when fitting\n * the view. Used for arc layers that have separate source and target\n * geometries — a single `geometryColumn` would only cover one endpoint.\n */\n geometryColumns?: string[];\n h3Column?: string;\n padding?: number;\n maxZoom?: number;\n};\n\nexport type DeckMapConfigMode = 'basic' | 'custom';\n\n/** Durable, host-neutral Deck map configuration. */\nexport type DeckMapConfig = {\n spec: DeckJsonMapProps['spec'];\n datasets: Record<string, DeckMapDatasetConfig>;\n configMode?: DeckMapConfigMode;\n mapStyle?: string;\n mapProps?: Record<string, unknown>;\n showLegends?: boolean;\n interaction?: DeckMapInteractionConfig;\n fitToData?: DeckMapFitToDataConfig;\n dataPolicy?: DeckMapDataPolicyOverride;\n settingsOpen?: boolean;\n};\n\n/** Creates the portable empty configuration used for a new Deck map. */\nexport function createEmptyDeckMapConfig(): DeckMapConfig {\n return {\n spec: {\n initialViewState: {longitude: 0, latitude: 20, zoom: 1.5},\n layers: [],\n },\n datasets: {},\n };\n}\n\n/** Adapter-facing dashboard panel shape; worksheet resources never store it. */\nexport type DeckMapDashboardPanelConfig = DeckMapConfig;\nexport type DeckMapDashboardDatasetConfig = DeckMapDatasetConfig;\nexport type DeckMapDashboardDatasetSource = DeckMapDatasetSource;\nexport type DeckMapDashboardInteractionConfig = DeckMapInteractionConfig;\nexport type DeckMapDashboardFitToDataConfig = DeckMapFitToDataConfig;\n\nexport const isDeckMapDashboardSqlDatasetSource = isDeckMapSqlDatasetSource;\nexport const isDeckMapDashboardTableDatasetSource = isDeckMapTableDatasetSource;\n\nexport type CreateDeckMapDashboardPanelConfigOptions = DeckMapConfig & {\n title?: string;\n};\n\n/** Creates a Mosaic panel only for the opt-in dashboard adapter. */\nexport function createDeckMapDashboardPanelConfig(\n options: CreateDeckMapDashboardPanelConfigOptions,\n) {\n const {title, ...config} = options;\n return {\n id: createId(),\n type: DECK_MAP_DASHBOARD_PANEL_TYPE,\n title: title ?? 'Map',\n config: JSON.parse(JSON.stringify(config)) as Record<string, unknown>,\n };\n}\n\n/**\n * Returns a record as a Deck map config when it has the required top-level\n * spec and dataset registry, otherwise returns `null`.\n */\nexport function asDeckJsonMapConfig(\n config: Record<string, unknown>,\n): DeckMapConfig | null {\n if (\n !config.spec ||\n !config.datasets ||\n typeof config.datasets !== 'object' ||\n Array.isArray(config.datasets)\n ) {\n return null;\n }\n return config as DeckMapConfig;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"mapConfigUtils.d.ts","sourceRoot":"","sources":["../src/mapConfigUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,SAAS,EACd,KAAK,oBAAoB,EAC1B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAEL,KAAK,2BAA2B,EAChC,KAAK,aAAa,EACnB,MAAM,aAAa,CAAC;AAErB,OAAO,KAAK,EAAC,oBAAoB,EAAC,MAAM,iBAAiB,CAAC;AA2C1D,MAAM,MAAM,mBAAmB,GAAG;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAC,CAAC;AAChE,MAAM,MAAM,qBAAqB,GAC7B,MAAM,GACN;IACE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AACN,MAAM,MAAM,gBAAgB,GACxB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GACxB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AA2BrC,wBAAgB,mCAAmC,CACjD,OAAO,CAAC,EAAE,mBAAmB,EAAE;;;SAIhC;AAED,wBAAgB,4BAA4B,CAAC,KAAK,CAAC,EAAE,SAAS;;;SAG7D;AAwBD,wBAAgB,yBAAyB,CAAC,OAAO,CAAC,EAAE,mBAAmB,EAAE;;;SAkBxE;AAED,wBAAgB,kBAAkB,CAAC,KAAK,CAAC,EAAE,SAAS;;;SAGnD;AAED,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,MAAM,UAE3D;AAED,wBAAgB,6BAA6B,CAC3C,cAAc,EAAE,qBAAqB,GACpC,oBAAoB,CAmBtB;AAuED;;;GAGG;AACH,wBAAgB,8BAA8B,CAAC,OAAO,EAAE;IACtD,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACxB,UASA;AA6ED;;;;;;;;GAQG;AACH,wBAAgB,2BAA2B,CACzC,CAAC,SAAS,2BAA2B,EACrC,OAAO,EAAE;IACT,MAAM,EAAE,CAAC,CAAC;IACV,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,SAAS,GAAG,SAAS,CAAC;CAC5D,GAAG,CAAC,CAqHJ;AAED,wBAAgB,yBAAyB,CACvC,SAAS,CAAC,EAAE,MAAM,EAAE,GACnB,gBAAgB,CAQlB;AAED,wBAAgB,2BAA2B,CAAC,OAAO,EAAE;IACnD,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,cAAc,CAAC,EAAE,qBAAqB,CAAC;IACvC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,aAAa,CAoHhB;AAED,eAAO,MAAM,oCAAoC,oCAA8B,CAAC;AAEhF,wBAAgB,yCAAyC,CAAC,OAAO,EAAE;IACjE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,cAAc,CAAC,EAAE,qBAAqB,CAAC;IACvC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;;;;;EAKA;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAC,EACxC,KAAK,EAAE,SAAS,EAChB,eAAe,CAAC,EAAE,MAAM,EACxB,cAAc,CAAC,EAAE,MAAM;;;;;;;;;;;;;EAmDxB"}
1
+ {"version":3,"file":"mapConfigUtils.d.ts","sourceRoot":"","sources":["../src/mapConfigUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,SAAS,EACd,KAAK,oBAAoB,EAC1B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAEL,KAAK,2BAA2B,EAChC,KAAK,aAAa,EACnB,MAAM,aAAa,CAAC;AAErB,OAAO,KAAK,EAAC,oBAAoB,EAAC,MAAM,iBAAiB,CAAC;AA2C1D,MAAM,MAAM,mBAAmB,GAAG;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAC,CAAC;AAChE,MAAM,MAAM,qBAAqB,GAC7B,MAAM,GACN;IACE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AACN,MAAM,MAAM,gBAAgB,GACxB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GACxB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AA2BrC,wBAAgB,mCAAmC,CACjD,OAAO,CAAC,EAAE,mBAAmB,EAAE;;;SAIhC;AAED,wBAAgB,4BAA4B,CAAC,KAAK,CAAC,EAAE,SAAS;;;SAG7D;AA0BD,wBAAgB,yBAAyB,CAAC,OAAO,CAAC,EAAE,mBAAmB,EAAE;;;SAkBxE;AAED,wBAAgB,kBAAkB,CAAC,KAAK,CAAC,EAAE,SAAS;;;SAGnD;AAED,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,MAAM,UAE3D;AAED,wBAAgB,6BAA6B,CAC3C,cAAc,EAAE,qBAAqB,GACpC,oBAAoB,CAmBtB;AAuED;;;GAGG;AACH,wBAAgB,8BAA8B,CAAC,OAAO,EAAE;IACtD,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACxB,UASA;AA6ED;;;;;;;;GAQG;AACH,wBAAgB,2BAA2B,CACzC,CAAC,SAAS,2BAA2B,EACrC,OAAO,EAAE;IACT,MAAM,EAAE,CAAC,CAAC;IACV,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,SAAS,GAAG,SAAS,CAAC;CAC5D,GAAG,CAAC,CAqHJ;AAED,wBAAgB,yBAAyB,CACvC,SAAS,CAAC,EAAE,MAAM,EAAE,GACnB,gBAAgB,CAQlB;AAED,wBAAgB,2BAA2B,CAAC,OAAO,EAAE;IACnD,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,cAAc,CAAC,EAAE,qBAAqB,CAAC;IACvC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,aAAa,CAoHhB;AAED,eAAO,MAAM,oCAAoC,oCAA8B,CAAC;AAEhF,wBAAgB,yCAAyC,CAAC,OAAO,EAAE;IACjE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,cAAc,CAAC,EAAE,qBAAqB,CAAC;IACvC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;;;;;EAKA;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAC,EACxC,KAAK,EAAE,SAAS,EAChB,eAAe,CAAC,EAAE,MAAM,EACxB,cAAc,CAAC,EAAE,MAAM;;;;;;;;;;;;;EAmDxB"}
@@ -72,6 +72,8 @@ function inferGeometryEncodingHint(column) {
72
72
  type.includes('text')) {
73
73
  return 'wkt';
74
74
  }
75
+ // Native DuckDB GEOMETRY is not an encoding hint — the dataset pipeline
76
+ // projects it through ST_AsWKB via DESCRIBE + SELECT * REPLACE.
75
77
  return undefined;
76
78
  }
77
79
  export function findDeckMapGeometryColumn(columns) {
@@ -1 +1 @@
1
- {"version":3,"file":"mapConfigUtils.js","sourceRoot":"","sources":["../src/mapConfigUtils.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n getRawSqlTableReference,\n makeQualifiedTableName,\n quoteParsedRawSqlTableReference,\n type DataTable,\n type RawSqlTableReference,\n} from '@sqlrooms/duckdb';\nimport {\n createDeckMapDashboardPanelConfig,\n type DeckMapDashboardPanelConfig,\n type DeckMapConfig,\n} from './mapConfig';\nimport {DECK_TABLE_DATASET_SOURCE_RELATION} from './datasets/tableDatasetSql';\nimport type {GeometryEncodingHint} from './prepare/types';\n\nconst LONGITUDE_COLUMN_NAMES = ['longitude', 'lon', 'lng', 'long', 'x'];\nconst LATITUDE_COLUMN_NAMES = ['latitude', 'lat', 'y'];\nconst GEOMETRY_COLUMN_NAMES = ['geometry', 'geom'];\nconst DEFAULT_GEOMETRY_COLUMN = '__sqlrooms_geom';\nconst DEFAULT_FILL_COLOR = [56, 189, 248, 180] as const;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value && typeof value === 'object' && !Array.isArray(value));\n}\n\nfunction updateDeckMapGeometryColumnBindings(\n config: DeckMapDashboardPanelConfig,\n datasetId: string,\n geometryColumn: string | undefined,\n) {\n if (!geometryColumn || !isRecord(config.spec)) return config;\n const layers = config.spec.layers;\n if (!Array.isArray(layers)) return config;\n\n let changed = false;\n const nextLayers = layers.map((layer) => {\n if (!isRecord(layer) || !isRecord(layer._sqlroomsBinding)) return layer;\n const binding = layer._sqlroomsBinding;\n if (\n binding.dataset !== datasetId ||\n typeof binding.geometryColumn !== 'string'\n ) {\n return layer;\n }\n changed = true;\n return {\n ...layer,\n _sqlroomsBinding: {...binding, geometryColumn},\n };\n });\n\n return changed\n ? {...config, spec: {...config.spec, layers: nextLayers}}\n : config;\n}\n\nexport type DeckMapConfigColumn = {name: string; type?: string};\nexport type DeckMapTableReference =\n | string\n | {\n database?: string;\n schema?: string;\n table?: string;\n };\nexport type DeckMapFillColor =\n | [number, number, number]\n | [number, number, number, number];\n\nfunction findColumnByName(\n columns: DeckMapConfigColumn[],\n candidates: string[],\n) {\n const candidateSet = new Set(candidates);\n return columns.find((column) => candidateSet.has(column.name.toLowerCase()))\n ?.name;\n}\n\nfunction resolveDeckMapCoordinateColumnNames(options: {\n columns: DeckMapConfigColumn[];\n longitudeColumn?: string;\n latitudeColumn?: string;\n}) {\n const longitudeColumn =\n options.longitudeColumn ||\n findColumnByName(options.columns, LONGITUDE_COLUMN_NAMES);\n const latitudeColumn =\n options.latitudeColumn ||\n findColumnByName(options.columns, LATITUDE_COLUMN_NAMES);\n return longitudeColumn && latitudeColumn\n ? {longitudeColumn, latitudeColumn}\n : null;\n}\n\nexport function findDeckMapLongitudeLatitudeColumns(\n columns?: DeckMapConfigColumn[],\n) {\n if (!columns) return null;\n return resolveDeckMapCoordinateColumnNames({columns});\n}\n\nexport function findLongitudeLatitudeColumns(table?: DataTable) {\n if (!table) return null;\n return findDeckMapLongitudeLatitudeColumns(table.columns);\n}\n\nfunction inferGeometryEncodingHint(\n column: DeckMapConfigColumn,\n): GeometryEncodingHint | undefined {\n const type = column.type?.toLowerCase();\n if (!type) return undefined;\n if (\n type.includes('wkb') ||\n type.includes('blob') ||\n type.includes('binary')\n ) {\n return 'wkb';\n }\n if (\n type.includes('wkt') ||\n type.includes('varchar') ||\n type.includes('text')\n ) {\n return 'wkt';\n }\n return undefined;\n}\n\nexport function findDeckMapGeometryColumn(columns?: DeckMapConfigColumn[]) {\n if (!columns) return null;\n\n const namedGeometryColumn = findColumnByName(columns, GEOMETRY_COLUMN_NAMES);\n const geometryColumn =\n (namedGeometryColumn\n ? columns.find((column) => column.name === namedGeometryColumn)\n : undefined) ??\n columns.find((column) => {\n const type = column.type?.toLowerCase() ?? '';\n return type.includes('geometry') || type.includes('geoarrow');\n });\n\n if (!geometryColumn) return null;\n return {\n geometryColumn: geometryColumn.name,\n geometryEncodingHint: inferGeometryEncodingHint(geometryColumn),\n };\n}\n\nexport function findGeometryColumn(table?: DataTable) {\n if (!table) return null;\n return findDeckMapGeometryColumn(table.columns);\n}\n\nexport function quoteDeckMapSqlIdentifier(identifier: string) {\n return `\"${identifier.replace(/\"/g, '\"\"')}\"`;\n}\n\nexport function quoteDeckMapSqlTableReference(\n tableReference: DeckMapTableReference,\n): RawSqlTableReference {\n if (typeof tableReference === 'string') {\n const rawSqlTableReference =\n quoteParsedRawSqlTableReference(tableReference);\n if (!rawSqlTableReference) {\n throw new Error(`Invalid deck map table reference \"${tableReference}\".`);\n }\n return rawSqlTableReference;\n }\n if (!tableReference.table) {\n throw new Error('Deck map table reference object requires a table name.');\n }\n return getRawSqlTableReference(\n makeQualifiedTableName({\n database: tableReference.database,\n schema: tableReference.schema,\n table: tableReference.table,\n }),\n );\n}\n\nfunction ensureDeckMapColumnExists(\n columns: DeckMapConfigColumn[],\n columnName: string,\n role: string,\n) {\n if (!columns.some((column) => column.name === columnName)) {\n throw new Error(\n `Unknown ${role} column \"${columnName}\". Available columns: ${columns\n .map((column) => column.name)\n .join(', ')}.`,\n );\n }\n}\n\nfunction resolveDeckMapCoordinateColumns(options: {\n columns: DeckMapConfigColumn[];\n longitudeColumn?: string;\n latitudeColumn?: string;\n}) {\n const coordinates =\n options.longitudeColumn && options.latitudeColumn\n ? {\n longitudeColumn: options.longitudeColumn,\n latitudeColumn: options.latitudeColumn,\n }\n : findDeckMapLongitudeLatitudeColumns(options.columns);\n\n if (!coordinates) {\n throw new Error(\n 'Could not find longitude/latitude columns. Pass longitudeColumn and latitudeColumn explicitly, or provide geometryColumn.',\n );\n }\n\n ensureDeckMapColumnExists(\n options.columns,\n coordinates.longitudeColumn,\n 'longitude',\n );\n ensureDeckMapColumnExists(\n options.columns,\n coordinates.latitudeColumn,\n 'latitude',\n );\n return coordinates;\n}\n\nfunction createDeckMapPointSourceSql(options: {\n sourceSqlQuery?: string;\n tableReference: DeckMapTableReference;\n longitudeColumn: string;\n latitudeColumn: string;\n geometryColumn: string;\n}) {\n const quotedLongitude = quoteDeckMapSqlIdentifier(options.longitudeColumn);\n const quotedLatitude = quoteDeckMapSqlIdentifier(options.latitudeColumn);\n const cleanedSourceSqlQuery = options.sourceSqlQuery\n ?.trim()\n .replace(/(?:\\s*;+\\s*)+$/, '');\n const baseSource = cleanedSourceSqlQuery\n ? `(${cleanedSourceSqlQuery}) AS \"__sqlrooms_dashboard_map_source\"`\n : quoteDeckMapSqlTableReference(options.tableReference);\n\n return [\n `SELECT *, ST_AsWKB(ST_Point(${quotedLongitude}, ${quotedLatitude})) AS ${quoteDeckMapSqlIdentifier(options.geometryColumn)}`,\n `FROM ${baseSource}`,\n `WHERE ${quotedLongitude} IS NOT NULL AND ${quotedLatitude} IS NOT NULL`,\n ].join(' ');\n}\n\n/**\n * Builds the standard lon/lat → WKB point transform SQL used by Deck map\n * datasets that follow the selected table via {@link DECK_TABLE_DATASET_SOURCE_RELATION}.\n */\nexport function createDeckMapPointTransformSql(options: {\n longitudeColumn: string;\n latitudeColumn: string;\n geometryColumn: string;\n}) {\n const quotedLongitude = quoteDeckMapSqlIdentifier(options.longitudeColumn);\n const quotedLatitude = quoteDeckMapSqlIdentifier(options.latitudeColumn);\n\n return [\n `SELECT *, ST_AsWKB(ST_Point(${quotedLongitude}, ${quotedLatitude})) AS ${quoteDeckMapSqlIdentifier(options.geometryColumn)}`,\n `FROM ${DECK_TABLE_DATASET_SOURCE_RELATION}`,\n `WHERE ${quotedLongitude} IS NOT NULL AND ${quotedLatitude} IS NOT NULL`,\n ].join(' ');\n}\n\nconst DECK_MAP_POINT_LAYER_TYPES = new Set([\n 'GeoArrowScatterplotLayer',\n 'GeoArrowHeatmapLayer',\n 'GeoArrowColumnLayer',\n]);\n\nfunction isDeckMapConfigRecord(\n value: unknown,\n): value is Record<string, unknown> {\n return Boolean(value && typeof value === 'object' && !Array.isArray(value));\n}\n\nfunction deckMapLayerTargetsDataset(options: {\n layer: Record<string, unknown>;\n datasetId: string;\n datasetIds: string[];\n}) {\n const binding = isDeckMapConfigRecord(options.layer._sqlroomsBinding)\n ? options.layer._sqlroomsBinding\n : undefined;\n const boundDataset = binding?.dataset;\n\n if (typeof boundDataset === 'string') {\n return boundDataset === options.datasetId;\n }\n\n return options.datasetIds.length === 1 && options.layer.data === undefined;\n}\n\nfunction normalizeDeckMapPointLayers<T extends unknown[]>(options: {\n layers: T;\n datasetId: string;\n datasetIds: string[];\n geometryColumn: string;\n}): T {\n let changed = false;\n const layers = options.layers.map((layer) => {\n if (!isDeckMapConfigRecord(layer)) {\n return layer;\n }\n\n const layerType = layer['@@type'];\n if (\n typeof layerType !== 'string' ||\n !DECK_MAP_POINT_LAYER_TYPES.has(layerType) ||\n !deckMapLayerTargetsDataset({\n layer,\n datasetId: options.datasetId,\n datasetIds: options.datasetIds,\n })\n ) {\n return layer;\n }\n\n changed = true;\n const binding = isDeckMapConfigRecord(layer._sqlroomsBinding)\n ? layer._sqlroomsBinding\n : {};\n\n return {\n ...layer,\n _sqlroomsBinding: {\n ...binding,\n dataset:\n typeof binding.dataset === 'string'\n ? binding.dataset\n : options.datasetId,\n geometryColumn: options.geometryColumn,\n },\n };\n });\n\n return (changed ? layers : options.layers) as T;\n}\n\n/**\n * Post-normalizes an existing Deck map config so table-backed lon/lat datasets\n * without `transformSql`, `sqlQuery`, or a native geometry column get a WKB\n * point transform, geometry bindings, and `fitToData.geometryColumn` alignment.\n *\n * Prefer this for AI/tool configs that arrive without a transform. Fresh configs\n * from {@link createDeckMapDashboardConfigForTable} already include the transform;\n * this helper patches in place without rebuilding layers.\n */\nexport function normalizeDeckMapPointConfig<\n T extends DeckMapDashboardPanelConfig,\n>(options: {\n config: T;\n resolveTable: (tableName: string) => DataTable | undefined;\n}): T {\n const {config, resolveTable} = options;\n const datasets = isDeckMapConfigRecord(config.datasets)\n ? config.datasets\n : undefined;\n if (!datasets) {\n return config;\n }\n\n const datasetIds = Object.keys(datasets);\n let nextDatasets = datasets;\n let nextSpec = config.spec;\n let nextFitToData = config.fitToData;\n let changed = false;\n\n for (const [datasetId, datasetValue] of Object.entries(datasets)) {\n if (!isDeckMapConfigRecord(datasetValue)) {\n continue;\n }\n const dataset = datasetValue;\n\n const source = isDeckMapConfigRecord(dataset.source as unknown)\n ? (dataset.source as Record<string, unknown>)\n : undefined;\n const tableName =\n typeof source?.tableName === 'string' ? source.tableName : undefined;\n const configuredGeometryColumn =\n typeof dataset.geometryColumn === 'string'\n ? dataset.geometryColumn.trim()\n : undefined;\n if (\n !tableName ||\n source?.sqlQuery ||\n source?.transformSql ||\n (configuredGeometryColumn &&\n configuredGeometryColumn !== DEFAULT_GEOMETRY_COLUMN)\n ) {\n continue;\n }\n\n const table = resolveTable(tableName);\n if (\n configuredGeometryColumn === DEFAULT_GEOMETRY_COLUMN &&\n table?.columns.some((column) => column.name === configuredGeometryColumn)\n ) {\n continue;\n }\n if (findGeometryColumn(table)) {\n continue;\n }\n const coordinateColumns = findLongitudeLatitudeColumns(table);\n if (!coordinateColumns) {\n continue;\n }\n\n const geometryColumn = DEFAULT_GEOMETRY_COLUMN;\n\n nextDatasets = {\n ...nextDatasets,\n [datasetId]: {\n ...dataset,\n source: {\n ...source,\n tableName,\n transformSql: createDeckMapPointTransformSql({\n ...coordinateColumns,\n geometryColumn,\n }),\n },\n geometryColumn,\n geometryEncodingHint: 'wkb',\n },\n };\n\n if (\n isDeckMapConfigRecord(nextSpec) &&\n Array.isArray(nextSpec.layers) &&\n nextSpec.layers.length > 0\n ) {\n nextSpec = {\n ...nextSpec,\n layers: normalizeDeckMapPointLayers({\n layers: nextSpec.layers,\n datasetId,\n datasetIds,\n geometryColumn,\n }),\n };\n }\n\n nextFitToData =\n isDeckMapConfigRecord(nextFitToData) &&\n nextFitToData.dataset === datasetId\n ? {\n ...nextFitToData,\n geometryColumn,\n }\n : (nextFitToData ?? {\n dataset: datasetId,\n geometryColumn,\n padding: 40,\n maxZoom: 12,\n });\n\n changed = true;\n }\n\n if (!changed) {\n return config;\n }\n\n return {\n ...config,\n spec: nextSpec,\n datasets: nextDatasets,\n fitToData: nextFitToData,\n } as T;\n}\n\nexport function normalizeDeckMapFillColor(\n fillColor?: number[],\n): DeckMapFillColor {\n if (fillColor?.length === 3) {\n return [fillColor[0]!, fillColor[1]!, fillColor[2]!];\n }\n if (fillColor?.length === 4) {\n return [fillColor[0]!, fillColor[1]!, fillColor[2]!, fillColor[3]!];\n }\n return [...DEFAULT_FILL_COLOR];\n}\n\nexport function createDeckMapConfigForTable(options: {\n tableName: string;\n columns: DeckMapConfigColumn[];\n tableReference?: DeckMapTableReference;\n sourceSqlQuery?: string;\n longitudeColumn?: string;\n latitudeColumn?: string;\n geometryColumn?: string;\n geometryEncodingHint?: GeometryEncodingHint;\n pointRadius?: number;\n fillColor?: DeckMapFillColor;\n mapStyle?: string;\n}): DeckMapConfig {\n const datasetId = options.tableName;\n const explicitGeometryColumn = options.geometryColumn?.trim() || undefined;\n const detectedCoordinates =\n options.longitudeColumn && options.latitudeColumn\n ? {\n longitudeColumn: options.longitudeColumn,\n latitudeColumn: options.latitudeColumn,\n }\n : findDeckMapLongitudeLatitudeColumns(options.columns);\n const detectedGeometryColumn = explicitGeometryColumn\n ? {\n geometryColumn: explicitGeometryColumn,\n geometryEncodingHint: options.geometryEncodingHint,\n }\n : detectedCoordinates\n ? null\n : findDeckMapGeometryColumn(options.columns);\n const coordinates = detectedGeometryColumn\n ? undefined\n : resolveDeckMapCoordinateColumns({\n columns: options.columns,\n longitudeColumn: options.longitudeColumn,\n latitudeColumn: options.latitudeColumn,\n });\n const geometryColumn =\n detectedGeometryColumn?.geometryColumn ?? DEFAULT_GEOMETRY_COLUMN;\n const geometryEncodingHint =\n options.geometryEncodingHint ??\n detectedGeometryColumn?.geometryEncodingHint;\n const source = coordinates\n ? options.sourceSqlQuery\n ? {\n sqlQuery: createDeckMapPointSourceSql({\n sourceSqlQuery: options.sourceSqlQuery,\n tableReference: options.tableReference ?? options.tableName,\n longitudeColumn: coordinates.longitudeColumn,\n latitudeColumn: coordinates.latitudeColumn,\n geometryColumn,\n }),\n }\n : {\n tableName: options.tableReference\n ? quoteDeckMapSqlTableReference(options.tableReference)\n : options.tableName,\n transformSql: createDeckMapPointTransformSql({\n longitudeColumn: coordinates.longitudeColumn,\n latitudeColumn: coordinates.latitudeColumn,\n geometryColumn,\n }),\n }\n : options.sourceSqlQuery\n ? {sqlQuery: options.sourceSqlQuery}\n : {tableName: options.tableName};\n\n if (detectedGeometryColumn) {\n ensureDeckMapColumnExists(\n options.columns,\n detectedGeometryColumn.geometryColumn,\n 'geometry',\n );\n }\n\n return {\n spec: {\n initialViewState: {longitude: 0, latitude: 20, zoom: 1.5},\n layers: [\n {\n '@@type': coordinates\n ? 'GeoArrowScatterplotLayer'\n : 'GeoArrowPolygonLayer',\n id: datasetId,\n _sqlroomsBinding: {\n dataset: datasetId,\n ...(detectedGeometryColumn\n ? {geometryColumn: detectedGeometryColumn.geometryColumn}\n : {}),\n },\n filled: true,\n stroked: false,\n pickable: true,\n radiusUnits: 'pixels',\n getRadius: options.pointRadius ?? 4,\n getFillColor: options.fillColor ?? [...DEFAULT_FILL_COLOR],\n },\n ],\n },\n datasets: {\n [datasetId]: {\n source,\n geometryColumn,\n geometryEncodingHint: coordinates ? 'wkb' : geometryEncodingHint,\n },\n },\n ...(coordinates\n ? {\n fitToData: {\n dataset: datasetId,\n longitudeColumn: coordinates.longitudeColumn,\n latitudeColumn: coordinates.latitudeColumn,\n padding: 40,\n maxZoom: 12,\n },\n }\n : detectedGeometryColumn\n ? {\n fitToData: {\n dataset: datasetId,\n geometryColumn: detectedGeometryColumn.geometryColumn,\n padding: 40,\n maxZoom: 12,\n },\n }\n : {}),\n ...(options.mapStyle ? {mapStyle: options.mapStyle} : {}),\n };\n}\n\nexport const createDeckMapDashboardConfigForTable = createDeckMapConfigForTable;\n\nexport function createDeckMapDashboardPanelConfigForTable(options: {\n title?: string;\n tableName: string;\n columns: DeckMapConfigColumn[];\n tableReference?: DeckMapTableReference;\n sourceSqlQuery?: string;\n longitudeColumn?: string;\n latitudeColumn?: string;\n geometryColumn?: string;\n geometryEncodingHint?: GeometryEncodingHint;\n pointRadius?: number;\n fillColor?: DeckMapFillColor;\n mapStyle?: string;\n}) {\n return createDeckMapDashboardPanelConfig({\n title: options.title,\n ...createDeckMapConfigForTable(options),\n });\n}\n\n/**\n * Regenerates a map's dataset source and fit configuration for a table while\n * preserving an existing single dataset ID so retained layer bindings remain\n * valid. Empty maps adopt the generated dataset and layer spec. Returns the\n * existing config unchanged when the table has no supported geospatial columns\n * or when multiple datasets make the target ambiguous.\n */\nexport function regenerateMapConfigForTable(\n panel: {config: Record<string, unknown>},\n table: DataTable,\n longitudeColumn?: string,\n latitudeColumn?: string,\n) {\n const coordinateColumns = resolveDeckMapCoordinateColumnNames({\n columns: table.columns,\n longitudeColumn,\n latitudeColumn,\n });\n if (!coordinateColumns && !findGeometryColumn(table)) {\n return panel.config;\n }\n\n const existingConfig = panel.config as DeckMapDashboardPanelConfig;\n const existingDatasetIds = Object.keys(existingConfig.datasets ?? {});\n if (existingDatasetIds.length > 1) return panel.config;\n\n const nextConfig = createDeckMapConfigForTable({\n tableName: table.tableName,\n columns: table.columns,\n tableReference: table.table,\n longitudeColumn: coordinateColumns?.longitudeColumn,\n latitudeColumn: coordinateColumns?.latitudeColumn,\n });\n const nextDataset = Object.values(nextConfig.datasets)[0];\n\n if (existingDatasetIds.length === 0) {\n return nextConfig;\n }\n\n if (existingDatasetIds.length === 1 && nextDataset) {\n const datasetId = existingDatasetIds[0]!;\n return updateDeckMapGeometryColumnBindings(\n {\n ...existingConfig,\n datasets: {[datasetId]: nextDataset},\n fitToData: nextConfig.fitToData\n ? {...nextConfig.fitToData, dataset: datasetId}\n : existingConfig.fitToData,\n },\n datasetId,\n nextDataset.geometryColumn,\n );\n }\n\n // Preserve existing layer spec (layer types, styling, bindings) — only\n // update the dataset source and fitToData so the data re-fetches with the\n // new coordinate columns.\n return {\n ...existingConfig,\n datasets: nextConfig.datasets,\n fitToData: nextConfig.fitToData ?? existingConfig.fitToData,\n };\n}\n"]}
1
+ {"version":3,"file":"mapConfigUtils.js","sourceRoot":"","sources":["../src/mapConfigUtils.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n getRawSqlTableReference,\n makeQualifiedTableName,\n quoteParsedRawSqlTableReference,\n type DataTable,\n type RawSqlTableReference,\n} from '@sqlrooms/duckdb';\nimport {\n createDeckMapDashboardPanelConfig,\n type DeckMapDashboardPanelConfig,\n type DeckMapConfig,\n} from './mapConfig';\nimport {DECK_TABLE_DATASET_SOURCE_RELATION} from './datasets/tableDatasetSql';\nimport type {GeometryEncodingHint} from './prepare/types';\n\nconst LONGITUDE_COLUMN_NAMES = ['longitude', 'lon', 'lng', 'long', 'x'];\nconst LATITUDE_COLUMN_NAMES = ['latitude', 'lat', 'y'];\nconst GEOMETRY_COLUMN_NAMES = ['geometry', 'geom'];\nconst DEFAULT_GEOMETRY_COLUMN = '__sqlrooms_geom';\nconst DEFAULT_FILL_COLOR = [56, 189, 248, 180] as const;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value && typeof value === 'object' && !Array.isArray(value));\n}\n\nfunction updateDeckMapGeometryColumnBindings(\n config: DeckMapDashboardPanelConfig,\n datasetId: string,\n geometryColumn: string | undefined,\n) {\n if (!geometryColumn || !isRecord(config.spec)) return config;\n const layers = config.spec.layers;\n if (!Array.isArray(layers)) return config;\n\n let changed = false;\n const nextLayers = layers.map((layer) => {\n if (!isRecord(layer) || !isRecord(layer._sqlroomsBinding)) return layer;\n const binding = layer._sqlroomsBinding;\n if (\n binding.dataset !== datasetId ||\n typeof binding.geometryColumn !== 'string'\n ) {\n return layer;\n }\n changed = true;\n return {\n ...layer,\n _sqlroomsBinding: {...binding, geometryColumn},\n };\n });\n\n return changed\n ? {...config, spec: {...config.spec, layers: nextLayers}}\n : config;\n}\n\nexport type DeckMapConfigColumn = {name: string; type?: string};\nexport type DeckMapTableReference =\n | string\n | {\n database?: string;\n schema?: string;\n table?: string;\n };\nexport type DeckMapFillColor =\n | [number, number, number]\n | [number, number, number, number];\n\nfunction findColumnByName(\n columns: DeckMapConfigColumn[],\n candidates: string[],\n) {\n const candidateSet = new Set(candidates);\n return columns.find((column) => candidateSet.has(column.name.toLowerCase()))\n ?.name;\n}\n\nfunction resolveDeckMapCoordinateColumnNames(options: {\n columns: DeckMapConfigColumn[];\n longitudeColumn?: string;\n latitudeColumn?: string;\n}) {\n const longitudeColumn =\n options.longitudeColumn ||\n findColumnByName(options.columns, LONGITUDE_COLUMN_NAMES);\n const latitudeColumn =\n options.latitudeColumn ||\n findColumnByName(options.columns, LATITUDE_COLUMN_NAMES);\n return longitudeColumn && latitudeColumn\n ? {longitudeColumn, latitudeColumn}\n : null;\n}\n\nexport function findDeckMapLongitudeLatitudeColumns(\n columns?: DeckMapConfigColumn[],\n) {\n if (!columns) return null;\n return resolveDeckMapCoordinateColumnNames({columns});\n}\n\nexport function findLongitudeLatitudeColumns(table?: DataTable) {\n if (!table) return null;\n return findDeckMapLongitudeLatitudeColumns(table.columns);\n}\n\nfunction inferGeometryEncodingHint(\n column: DeckMapConfigColumn,\n): GeometryEncodingHint | undefined {\n const type = column.type?.toLowerCase();\n if (!type) return undefined;\n if (\n type.includes('wkb') ||\n type.includes('blob') ||\n type.includes('binary')\n ) {\n return 'wkb';\n }\n if (\n type.includes('wkt') ||\n type.includes('varchar') ||\n type.includes('text')\n ) {\n return 'wkt';\n }\n // Native DuckDB GEOMETRY is not an encoding hint — the dataset pipeline\n // projects it through ST_AsWKB via DESCRIBE + SELECT * REPLACE.\n return undefined;\n}\n\nexport function findDeckMapGeometryColumn(columns?: DeckMapConfigColumn[]) {\n if (!columns) return null;\n\n const namedGeometryColumn = findColumnByName(columns, GEOMETRY_COLUMN_NAMES);\n const geometryColumn =\n (namedGeometryColumn\n ? columns.find((column) => column.name === namedGeometryColumn)\n : undefined) ??\n columns.find((column) => {\n const type = column.type?.toLowerCase() ?? '';\n return type.includes('geometry') || type.includes('geoarrow');\n });\n\n if (!geometryColumn) return null;\n return {\n geometryColumn: geometryColumn.name,\n geometryEncodingHint: inferGeometryEncodingHint(geometryColumn),\n };\n}\n\nexport function findGeometryColumn(table?: DataTable) {\n if (!table) return null;\n return findDeckMapGeometryColumn(table.columns);\n}\n\nexport function quoteDeckMapSqlIdentifier(identifier: string) {\n return `\"${identifier.replace(/\"/g, '\"\"')}\"`;\n}\n\nexport function quoteDeckMapSqlTableReference(\n tableReference: DeckMapTableReference,\n): RawSqlTableReference {\n if (typeof tableReference === 'string') {\n const rawSqlTableReference =\n quoteParsedRawSqlTableReference(tableReference);\n if (!rawSqlTableReference) {\n throw new Error(`Invalid deck map table reference \"${tableReference}\".`);\n }\n return rawSqlTableReference;\n }\n if (!tableReference.table) {\n throw new Error('Deck map table reference object requires a table name.');\n }\n return getRawSqlTableReference(\n makeQualifiedTableName({\n database: tableReference.database,\n schema: tableReference.schema,\n table: tableReference.table,\n }),\n );\n}\n\nfunction ensureDeckMapColumnExists(\n columns: DeckMapConfigColumn[],\n columnName: string,\n role: string,\n) {\n if (!columns.some((column) => column.name === columnName)) {\n throw new Error(\n `Unknown ${role} column \"${columnName}\". Available columns: ${columns\n .map((column) => column.name)\n .join(', ')}.`,\n );\n }\n}\n\nfunction resolveDeckMapCoordinateColumns(options: {\n columns: DeckMapConfigColumn[];\n longitudeColumn?: string;\n latitudeColumn?: string;\n}) {\n const coordinates =\n options.longitudeColumn && options.latitudeColumn\n ? {\n longitudeColumn: options.longitudeColumn,\n latitudeColumn: options.latitudeColumn,\n }\n : findDeckMapLongitudeLatitudeColumns(options.columns);\n\n if (!coordinates) {\n throw new Error(\n 'Could not find longitude/latitude columns. Pass longitudeColumn and latitudeColumn explicitly, or provide geometryColumn.',\n );\n }\n\n ensureDeckMapColumnExists(\n options.columns,\n coordinates.longitudeColumn,\n 'longitude',\n );\n ensureDeckMapColumnExists(\n options.columns,\n coordinates.latitudeColumn,\n 'latitude',\n );\n return coordinates;\n}\n\nfunction createDeckMapPointSourceSql(options: {\n sourceSqlQuery?: string;\n tableReference: DeckMapTableReference;\n longitudeColumn: string;\n latitudeColumn: string;\n geometryColumn: string;\n}) {\n const quotedLongitude = quoteDeckMapSqlIdentifier(options.longitudeColumn);\n const quotedLatitude = quoteDeckMapSqlIdentifier(options.latitudeColumn);\n const cleanedSourceSqlQuery = options.sourceSqlQuery\n ?.trim()\n .replace(/(?:\\s*;+\\s*)+$/, '');\n const baseSource = cleanedSourceSqlQuery\n ? `(${cleanedSourceSqlQuery}) AS \"__sqlrooms_dashboard_map_source\"`\n : quoteDeckMapSqlTableReference(options.tableReference);\n\n return [\n `SELECT *, ST_AsWKB(ST_Point(${quotedLongitude}, ${quotedLatitude})) AS ${quoteDeckMapSqlIdentifier(options.geometryColumn)}`,\n `FROM ${baseSource}`,\n `WHERE ${quotedLongitude} IS NOT NULL AND ${quotedLatitude} IS NOT NULL`,\n ].join(' ');\n}\n\n/**\n * Builds the standard lon/lat → WKB point transform SQL used by Deck map\n * datasets that follow the selected table via {@link DECK_TABLE_DATASET_SOURCE_RELATION}.\n */\nexport function createDeckMapPointTransformSql(options: {\n longitudeColumn: string;\n latitudeColumn: string;\n geometryColumn: string;\n}) {\n const quotedLongitude = quoteDeckMapSqlIdentifier(options.longitudeColumn);\n const quotedLatitude = quoteDeckMapSqlIdentifier(options.latitudeColumn);\n\n return [\n `SELECT *, ST_AsWKB(ST_Point(${quotedLongitude}, ${quotedLatitude})) AS ${quoteDeckMapSqlIdentifier(options.geometryColumn)}`,\n `FROM ${DECK_TABLE_DATASET_SOURCE_RELATION}`,\n `WHERE ${quotedLongitude} IS NOT NULL AND ${quotedLatitude} IS NOT NULL`,\n ].join(' ');\n}\n\nconst DECK_MAP_POINT_LAYER_TYPES = new Set([\n 'GeoArrowScatterplotLayer',\n 'GeoArrowHeatmapLayer',\n 'GeoArrowColumnLayer',\n]);\n\nfunction isDeckMapConfigRecord(\n value: unknown,\n): value is Record<string, unknown> {\n return Boolean(value && typeof value === 'object' && !Array.isArray(value));\n}\n\nfunction deckMapLayerTargetsDataset(options: {\n layer: Record<string, unknown>;\n datasetId: string;\n datasetIds: string[];\n}) {\n const binding = isDeckMapConfigRecord(options.layer._sqlroomsBinding)\n ? options.layer._sqlroomsBinding\n : undefined;\n const boundDataset = binding?.dataset;\n\n if (typeof boundDataset === 'string') {\n return boundDataset === options.datasetId;\n }\n\n return options.datasetIds.length === 1 && options.layer.data === undefined;\n}\n\nfunction normalizeDeckMapPointLayers<T extends unknown[]>(options: {\n layers: T;\n datasetId: string;\n datasetIds: string[];\n geometryColumn: string;\n}): T {\n let changed = false;\n const layers = options.layers.map((layer) => {\n if (!isDeckMapConfigRecord(layer)) {\n return layer;\n }\n\n const layerType = layer['@@type'];\n if (\n typeof layerType !== 'string' ||\n !DECK_MAP_POINT_LAYER_TYPES.has(layerType) ||\n !deckMapLayerTargetsDataset({\n layer,\n datasetId: options.datasetId,\n datasetIds: options.datasetIds,\n })\n ) {\n return layer;\n }\n\n changed = true;\n const binding = isDeckMapConfigRecord(layer._sqlroomsBinding)\n ? layer._sqlroomsBinding\n : {};\n\n return {\n ...layer,\n _sqlroomsBinding: {\n ...binding,\n dataset:\n typeof binding.dataset === 'string'\n ? binding.dataset\n : options.datasetId,\n geometryColumn: options.geometryColumn,\n },\n };\n });\n\n return (changed ? layers : options.layers) as T;\n}\n\n/**\n * Post-normalizes an existing Deck map config so table-backed lon/lat datasets\n * without `transformSql`, `sqlQuery`, or a native geometry column get a WKB\n * point transform, geometry bindings, and `fitToData.geometryColumn` alignment.\n *\n * Prefer this for AI/tool configs that arrive without a transform. Fresh configs\n * from {@link createDeckMapDashboardConfigForTable} already include the transform;\n * this helper patches in place without rebuilding layers.\n */\nexport function normalizeDeckMapPointConfig<\n T extends DeckMapDashboardPanelConfig,\n>(options: {\n config: T;\n resolveTable: (tableName: string) => DataTable | undefined;\n}): T {\n const {config, resolveTable} = options;\n const datasets = isDeckMapConfigRecord(config.datasets)\n ? config.datasets\n : undefined;\n if (!datasets) {\n return config;\n }\n\n const datasetIds = Object.keys(datasets);\n let nextDatasets = datasets;\n let nextSpec = config.spec;\n let nextFitToData = config.fitToData;\n let changed = false;\n\n for (const [datasetId, datasetValue] of Object.entries(datasets)) {\n if (!isDeckMapConfigRecord(datasetValue)) {\n continue;\n }\n const dataset = datasetValue;\n\n const source = isDeckMapConfigRecord(dataset.source as unknown)\n ? (dataset.source as Record<string, unknown>)\n : undefined;\n const tableName =\n typeof source?.tableName === 'string' ? source.tableName : undefined;\n const configuredGeometryColumn =\n typeof dataset.geometryColumn === 'string'\n ? dataset.geometryColumn.trim()\n : undefined;\n if (\n !tableName ||\n source?.sqlQuery ||\n source?.transformSql ||\n (configuredGeometryColumn &&\n configuredGeometryColumn !== DEFAULT_GEOMETRY_COLUMN)\n ) {\n continue;\n }\n\n const table = resolveTable(tableName);\n if (\n configuredGeometryColumn === DEFAULT_GEOMETRY_COLUMN &&\n table?.columns.some((column) => column.name === configuredGeometryColumn)\n ) {\n continue;\n }\n if (findGeometryColumn(table)) {\n continue;\n }\n const coordinateColumns = findLongitudeLatitudeColumns(table);\n if (!coordinateColumns) {\n continue;\n }\n\n const geometryColumn = DEFAULT_GEOMETRY_COLUMN;\n\n nextDatasets = {\n ...nextDatasets,\n [datasetId]: {\n ...dataset,\n source: {\n ...source,\n tableName,\n transformSql: createDeckMapPointTransformSql({\n ...coordinateColumns,\n geometryColumn,\n }),\n },\n geometryColumn,\n geometryEncodingHint: 'wkb',\n },\n };\n\n if (\n isDeckMapConfigRecord(nextSpec) &&\n Array.isArray(nextSpec.layers) &&\n nextSpec.layers.length > 0\n ) {\n nextSpec = {\n ...nextSpec,\n layers: normalizeDeckMapPointLayers({\n layers: nextSpec.layers,\n datasetId,\n datasetIds,\n geometryColumn,\n }),\n };\n }\n\n nextFitToData =\n isDeckMapConfigRecord(nextFitToData) &&\n nextFitToData.dataset === datasetId\n ? {\n ...nextFitToData,\n geometryColumn,\n }\n : (nextFitToData ?? {\n dataset: datasetId,\n geometryColumn,\n padding: 40,\n maxZoom: 12,\n });\n\n changed = true;\n }\n\n if (!changed) {\n return config;\n }\n\n return {\n ...config,\n spec: nextSpec,\n datasets: nextDatasets,\n fitToData: nextFitToData,\n } as T;\n}\n\nexport function normalizeDeckMapFillColor(\n fillColor?: number[],\n): DeckMapFillColor {\n if (fillColor?.length === 3) {\n return [fillColor[0]!, fillColor[1]!, fillColor[2]!];\n }\n if (fillColor?.length === 4) {\n return [fillColor[0]!, fillColor[1]!, fillColor[2]!, fillColor[3]!];\n }\n return [...DEFAULT_FILL_COLOR];\n}\n\nexport function createDeckMapConfigForTable(options: {\n tableName: string;\n columns: DeckMapConfigColumn[];\n tableReference?: DeckMapTableReference;\n sourceSqlQuery?: string;\n longitudeColumn?: string;\n latitudeColumn?: string;\n geometryColumn?: string;\n geometryEncodingHint?: GeometryEncodingHint;\n pointRadius?: number;\n fillColor?: DeckMapFillColor;\n mapStyle?: string;\n}): DeckMapConfig {\n const datasetId = options.tableName;\n const explicitGeometryColumn = options.geometryColumn?.trim() || undefined;\n const detectedCoordinates =\n options.longitudeColumn && options.latitudeColumn\n ? {\n longitudeColumn: options.longitudeColumn,\n latitudeColumn: options.latitudeColumn,\n }\n : findDeckMapLongitudeLatitudeColumns(options.columns);\n const detectedGeometryColumn = explicitGeometryColumn\n ? {\n geometryColumn: explicitGeometryColumn,\n geometryEncodingHint: options.geometryEncodingHint,\n }\n : detectedCoordinates\n ? null\n : findDeckMapGeometryColumn(options.columns);\n const coordinates = detectedGeometryColumn\n ? undefined\n : resolveDeckMapCoordinateColumns({\n columns: options.columns,\n longitudeColumn: options.longitudeColumn,\n latitudeColumn: options.latitudeColumn,\n });\n const geometryColumn =\n detectedGeometryColumn?.geometryColumn ?? DEFAULT_GEOMETRY_COLUMN;\n const geometryEncodingHint =\n options.geometryEncodingHint ??\n detectedGeometryColumn?.geometryEncodingHint;\n const source = coordinates\n ? options.sourceSqlQuery\n ? {\n sqlQuery: createDeckMapPointSourceSql({\n sourceSqlQuery: options.sourceSqlQuery,\n tableReference: options.tableReference ?? options.tableName,\n longitudeColumn: coordinates.longitudeColumn,\n latitudeColumn: coordinates.latitudeColumn,\n geometryColumn,\n }),\n }\n : {\n tableName: options.tableReference\n ? quoteDeckMapSqlTableReference(options.tableReference)\n : options.tableName,\n transformSql: createDeckMapPointTransformSql({\n longitudeColumn: coordinates.longitudeColumn,\n latitudeColumn: coordinates.latitudeColumn,\n geometryColumn,\n }),\n }\n : options.sourceSqlQuery\n ? {sqlQuery: options.sourceSqlQuery}\n : {tableName: options.tableName};\n\n if (detectedGeometryColumn) {\n ensureDeckMapColumnExists(\n options.columns,\n detectedGeometryColumn.geometryColumn,\n 'geometry',\n );\n }\n\n return {\n spec: {\n initialViewState: {longitude: 0, latitude: 20, zoom: 1.5},\n layers: [\n {\n '@@type': coordinates\n ? 'GeoArrowScatterplotLayer'\n : 'GeoArrowPolygonLayer',\n id: datasetId,\n _sqlroomsBinding: {\n dataset: datasetId,\n ...(detectedGeometryColumn\n ? {geometryColumn: detectedGeometryColumn.geometryColumn}\n : {}),\n },\n filled: true,\n stroked: false,\n pickable: true,\n radiusUnits: 'pixels',\n getRadius: options.pointRadius ?? 4,\n getFillColor: options.fillColor ?? [...DEFAULT_FILL_COLOR],\n },\n ],\n },\n datasets: {\n [datasetId]: {\n source,\n geometryColumn,\n geometryEncodingHint: coordinates ? 'wkb' : geometryEncodingHint,\n },\n },\n ...(coordinates\n ? {\n fitToData: {\n dataset: datasetId,\n longitudeColumn: coordinates.longitudeColumn,\n latitudeColumn: coordinates.latitudeColumn,\n padding: 40,\n maxZoom: 12,\n },\n }\n : detectedGeometryColumn\n ? {\n fitToData: {\n dataset: datasetId,\n geometryColumn: detectedGeometryColumn.geometryColumn,\n padding: 40,\n maxZoom: 12,\n },\n }\n : {}),\n ...(options.mapStyle ? {mapStyle: options.mapStyle} : {}),\n };\n}\n\nexport const createDeckMapDashboardConfigForTable = createDeckMapConfigForTable;\n\nexport function createDeckMapDashboardPanelConfigForTable(options: {\n title?: string;\n tableName: string;\n columns: DeckMapConfigColumn[];\n tableReference?: DeckMapTableReference;\n sourceSqlQuery?: string;\n longitudeColumn?: string;\n latitudeColumn?: string;\n geometryColumn?: string;\n geometryEncodingHint?: GeometryEncodingHint;\n pointRadius?: number;\n fillColor?: DeckMapFillColor;\n mapStyle?: string;\n}) {\n return createDeckMapDashboardPanelConfig({\n title: options.title,\n ...createDeckMapConfigForTable(options),\n });\n}\n\n/**\n * Regenerates a map's dataset source and fit configuration for a table while\n * preserving an existing single dataset ID so retained layer bindings remain\n * valid. Empty maps adopt the generated dataset and layer spec. Returns the\n * existing config unchanged when the table has no supported geospatial columns\n * or when multiple datasets make the target ambiguous.\n */\nexport function regenerateMapConfigForTable(\n panel: {config: Record<string, unknown>},\n table: DataTable,\n longitudeColumn?: string,\n latitudeColumn?: string,\n) {\n const coordinateColumns = resolveDeckMapCoordinateColumnNames({\n columns: table.columns,\n longitudeColumn,\n latitudeColumn,\n });\n if (!coordinateColumns && !findGeometryColumn(table)) {\n return panel.config;\n }\n\n const existingConfig = panel.config as DeckMapDashboardPanelConfig;\n const existingDatasetIds = Object.keys(existingConfig.datasets ?? {});\n if (existingDatasetIds.length > 1) return panel.config;\n\n const nextConfig = createDeckMapConfigForTable({\n tableName: table.tableName,\n columns: table.columns,\n tableReference: table.table,\n longitudeColumn: coordinateColumns?.longitudeColumn,\n latitudeColumn: coordinateColumns?.latitudeColumn,\n });\n const nextDataset = Object.values(nextConfig.datasets)[0];\n\n if (existingDatasetIds.length === 0) {\n return nextConfig;\n }\n\n if (existingDatasetIds.length === 1 && nextDataset) {\n const datasetId = existingDatasetIds[0]!;\n return updateDeckMapGeometryColumnBindings(\n {\n ...existingConfig,\n datasets: {[datasetId]: nextDataset},\n fitToData: nextConfig.fitToData\n ? {...nextConfig.fitToData, dataset: datasetId}\n : existingConfig.fitToData,\n },\n datasetId,\n nextDataset.geometryColumn,\n );\n }\n\n // Preserve existing layer spec (layer types, styling, bindings) — only\n // update the dataset source and fitToData so the data re-fetches with the\n // new coordinate columns.\n return {\n ...existingConfig,\n datasets: nextConfig.datasets,\n fitToData: nextConfig.fitToData ?? existingConfig.fitToData,\n };\n}\n"]}
package/dist/mapFit.d.ts CHANGED
@@ -37,6 +37,22 @@ export declare function createDeckMapBoundsQuery(options: {
37
37
  source: DeckMapDatasetSource;
38
38
  fitToData: DeckMapFitToDataConfig;
39
39
  }): string | null;
40
+ /**
41
+ * MapLibre `jumpTo` options. Omits pitch/bearing unless set so fit preserves
42
+ * a pitched `initialViewState` (needed for extruded columns).
43
+ */
44
+ export declare function buildDeckMapJumpToOptions(opts: {
45
+ longitude: number;
46
+ latitude: number;
47
+ zoom: number;
48
+ bearing?: number;
49
+ pitch?: number;
50
+ }): {
51
+ center: [number, number];
52
+ zoom: number;
53
+ bearing?: number;
54
+ pitch?: number;
55
+ };
40
56
  /**
41
57
  * Executes host-neutral fit-to-data requests for a Deck map surface.
42
58
  *