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

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 (126) hide show
  1. package/README.md +49 -13
  2. package/dist/BlockMapSettings.d.ts.map +1 -1
  3. package/dist/BlockMapSettings.js +4 -16
  4. package/dist/BlockMapSettings.js.map +1 -1
  5. package/dist/DashboardMapSettings.d.ts.map +1 -1
  6. package/dist/DashboardMapSettings.js +7 -10
  7. package/dist/DashboardMapSettings.js.map +1 -1
  8. package/dist/DeckJsonMap.d.ts.map +1 -1
  9. package/dist/DeckJsonMap.js +18 -12
  10. package/dist/DeckJsonMap.js.map +1 -1
  11. package/dist/DeckJsonMapSpec.d.ts +41 -0
  12. package/dist/DeckJsonMapSpec.d.ts.map +1 -1
  13. package/dist/DeckJsonMapSpec.js +2 -0
  14. package/dist/DeckJsonMapSpec.js.map +1 -1
  15. package/dist/DeckMapSurface.d.ts +1 -1
  16. package/dist/DeckMapSurface.js +1 -1
  17. package/dist/DeckMapSurface.js.map +1 -1
  18. package/dist/MapSettings.d.ts +14 -0
  19. package/dist/MapSettings.d.ts.map +1 -1
  20. package/dist/MapSettings.js +547 -192
  21. package/dist/MapSettings.js.map +1 -1
  22. package/dist/MapSettingsControls.d.ts +8 -1
  23. package/dist/MapSettingsControls.d.ts.map +1 -1
  24. package/dist/MapSettingsControls.js +24 -2
  25. package/dist/MapSettingsControls.js.map +1 -1
  26. package/dist/ai.d.ts.map +1 -1
  27. package/dist/ai.js +6 -3
  28. package/dist/ai.js.map +1 -1
  29. package/dist/aiNormalize.d.ts.map +1 -1
  30. package/dist/aiNormalize.js +2 -1
  31. package/dist/aiNormalize.js.map +1 -1
  32. package/dist/block.d.ts +1 -1
  33. package/dist/block.d.ts.map +1 -1
  34. package/dist/block.js +1 -1
  35. package/dist/block.js.map +1 -1
  36. package/dist/createOrUpdateDeckMapResource.d.ts +6 -2
  37. package/dist/createOrUpdateDeckMapResource.d.ts.map +1 -1
  38. package/dist/createOrUpdateDeckMapResource.js +57 -4
  39. package/dist/createOrUpdateDeckMapResource.js.map +1 -1
  40. package/dist/datasets/PreparedDatasetStore.d.ts +3 -4
  41. package/dist/datasets/PreparedDatasetStore.d.ts.map +1 -1
  42. package/dist/datasets/PreparedDatasetStore.js +4 -8
  43. package/dist/datasets/PreparedDatasetStore.js.map +1 -1
  44. package/dist/datasets/helpers.d.ts +39 -2
  45. package/dist/datasets/helpers.d.ts.map +1 -1
  46. package/dist/datasets/helpers.js +86 -3
  47. package/dist/datasets/helpers.js.map +1 -1
  48. package/dist/datasets/usePreparedDatasetStates.d.ts.map +1 -1
  49. package/dist/datasets/usePreparedDatasetStates.js +12 -8
  50. package/dist/datasets/usePreparedDatasetStates.js.map +1 -1
  51. package/dist/index.d.ts +2 -2
  52. package/dist/index.d.ts.map +1 -1
  53. package/dist/index.js +1 -1
  54. package/dist/index.js.map +1 -1
  55. package/dist/json/colorScaleFunction.d.ts +12 -4
  56. package/dist/json/colorScaleFunction.d.ts.map +1 -1
  57. package/dist/json/colorScaleFunction.js.map +1 -1
  58. package/dist/json/compileColorScale.d.ts +3 -2
  59. package/dist/json/compileColorScale.d.ts.map +1 -1
  60. package/dist/json/compileColorScale.js +16 -1
  61. package/dist/json/compileColorScale.js.map +1 -1
  62. package/dist/json/createDeckJsonConfiguration.d.ts.map +1 -1
  63. package/dist/json/createDeckJsonConfiguration.js +235 -175
  64. package/dist/json/createDeckJsonConfiguration.js.map +1 -1
  65. package/dist/json/defaultClasses.d.ts.map +1 -1
  66. package/dist/json/defaultClasses.js +3 -3
  67. package/dist/json/defaultClasses.js.map +1 -1
  68. package/dist/json/extractColorScaleLegends.d.ts.map +1 -1
  69. package/dist/json/extractColorScaleLegends.js +41 -26
  70. package/dist/json/extractColorScaleLegends.js.map +1 -1
  71. package/dist/json/heatmapDefaults.d.ts +17 -7
  72. package/dist/json/heatmapDefaults.d.ts.map +1 -1
  73. package/dist/json/heatmapDefaults.js +54 -12
  74. package/dist/json/heatmapDefaults.js.map +1 -1
  75. package/dist/json/layers/DeckHeatmapLayer.d.ts +32 -0
  76. package/dist/json/layers/DeckHeatmapLayer.d.ts.map +1 -0
  77. package/dist/json/layers/DeckHeatmapLayer.js +69 -0
  78. package/dist/json/layers/DeckHeatmapLayer.js.map +1 -0
  79. package/dist/json/layers/index.d.ts +1 -0
  80. package/dist/json/layers/index.d.ts.map +1 -1
  81. package/dist/json/layers/index.js +1 -0
  82. package/dist/json/layers/index.js.map +1 -1
  83. package/dist/json/rewriteGeoArrowAccessors.d.ts.map +1 -1
  84. package/dist/json/rewriteGeoArrowAccessors.js +13 -5
  85. package/dist/json/rewriteGeoArrowAccessors.js.map +1 -1
  86. package/dist/json/scaleFunction.d.ts +5 -8
  87. package/dist/json/scaleFunction.d.ts.map +1 -1
  88. package/dist/json/scaleFunction.js +30 -5
  89. package/dist/json/scaleFunction.js.map +1 -1
  90. package/dist/mapAiConfig.d.ts +6 -0
  91. package/dist/mapAiConfig.d.ts.map +1 -1
  92. package/dist/mapAiConfig.js +7 -0
  93. package/dist/mapAiConfig.js.map +1 -1
  94. package/dist/mapAiSharedInstructions.d.ts +1 -1
  95. package/dist/mapAiSharedInstructions.d.ts.map +1 -1
  96. package/dist/mapAiSharedInstructions.js +3 -3
  97. package/dist/mapAiSharedInstructions.js.map +1 -1
  98. package/dist/mapConfig.d.ts +1 -1
  99. package/dist/mapConfig.d.ts.map +1 -1
  100. package/dist/mapConfig.js.map +1 -1
  101. package/dist/mapConfigUtils.d.ts +22 -0
  102. package/dist/mapConfigUtils.d.ts.map +1 -1
  103. package/dist/mapConfigUtils.js +145 -3
  104. package/dist/mapConfigUtils.js.map +1 -1
  105. package/dist/mapLayerConfigUtils.d.ts +55 -0
  106. package/dist/mapLayerConfigUtils.d.ts.map +1 -1
  107. package/dist/mapLayerConfigUtils.js +222 -11
  108. package/dist/mapLayerConfigUtils.js.map +1 -1
  109. package/dist/mapResourceAuthoring.d.ts +1 -1
  110. package/dist/mapResourceAuthoring.d.ts.map +1 -1
  111. package/dist/mapResourceAuthoring.js +14 -7
  112. package/dist/mapResourceAuthoring.js.map +1 -1
  113. package/dist/prepare/prepareDeckDataset.d.ts.map +1 -1
  114. package/dist/prepare/prepareDeckDataset.js +1 -0
  115. package/dist/prepare/prepareDeckDataset.js.map +1 -1
  116. package/dist/prepare/types.d.ts +3 -0
  117. package/dist/prepare/types.d.ts.map +1 -1
  118. package/dist/prepare/types.js.map +1 -1
  119. package/dist/prepare/wkbDecoder.d.ts.map +1 -1
  120. package/dist/prepare/wkbDecoder.js +62 -16
  121. package/dist/prepare/wkbDecoder.js.map +1 -1
  122. package/dist/prepare/wkbParser.d.ts +2 -0
  123. package/dist/prepare/wkbParser.d.ts.map +1 -1
  124. package/dist/prepare/wkbParser.js +1 -0
  125. package/dist/prepare/wkbParser.js.map +1 -1
  126. package/package.json +9 -9
@@ -1,4 +1,4 @@
1
- import { isSqlDatasetInput, isTableDatasetInput, } from '../types';
1
+ import { isArrowTableDatasetInput, isSqlDatasetInput, isTableDatasetInput, } from '../types';
2
2
  import { resolveArrowTable } from './normalizeDatasets';
3
3
  export const DEFAULT_MAX_PREPARED_DATASET_ENTRIES = 20;
4
4
  let nextDatasetAccess = 0;
@@ -44,8 +44,91 @@ export function getSqlSourceIdentity(sqlSourceIdentity) {
44
44
  sqlSourceIdentities.set(sqlSourceIdentity, identity);
45
45
  return identity;
46
46
  }
47
- export function buildGeometryKey(input) {
48
- return `${input.geometryColumn ?? ''}\u0001${input.geometryEncodingHint ?? ''}`;
47
+ export function buildGeometryKey(options) {
48
+ return `${options.geometryColumn ?? ''}\u0001${options.geometryEncodingHint ?? ''}`;
49
+ }
50
+ /**
51
+ * Content identity for one dataset input, ignoring object-wrapper identity.
52
+ *
53
+ * Spec-only updates (slider opacity, radius, etc.) often recreate
54
+ * `{ tableName, transformSql }` literals even though the query did not change.
55
+ */
56
+ export function getDatasetInputFingerprint(input) {
57
+ if (isSqlDatasetInput(input)) {
58
+ return `sql\u0001${input.sqlQuery}\u0001${buildGeometryKey(input)}`;
59
+ }
60
+ if (isTableDatasetInput(input)) {
61
+ return `table\u0001${input.tableName}\u0001${input.transformSql ?? ''}\u0001${buildGeometryKey(input)}`;
62
+ }
63
+ if (isArrowTableDatasetInput(input)) {
64
+ const table = resolveArrowTable(input);
65
+ return `arrow\u0001${table ? getTableIdentity(table) : 'pending'}\u0001${buildGeometryKey(input)}`;
66
+ }
67
+ return 'unknown';
68
+ }
69
+ /** Sorted content identity for a dataset registry. */
70
+ export function getDatasetRegistryFingerprint(datasets) {
71
+ return Object.entries(datasets)
72
+ .sort(([left], [right]) => left.localeCompare(right))
73
+ .map(([datasetId, input]) => `${datasetId}\u0001${getDatasetInputFingerprint(input)}`)
74
+ .join('\u0002');
75
+ }
76
+ /**
77
+ * Content equality for one dataset input, ignoring object-wrapper identity.
78
+ *
79
+ * Implemented via {@link getDatasetInputFingerprint} so normalization stays
80
+ * identical to the fingerprint path (`''` vs `undefined`, pending Arrow, etc.).
81
+ * A hand-rolled field compare previously treated those differently and caused
82
+ * `useStableDatasets` to churn, which desynced MapLibre from deck layers.
83
+ */
84
+ export function areDatasetInputsEqual(left, right) {
85
+ if (left === right) {
86
+ return true;
87
+ }
88
+ return getDatasetInputFingerprint(left) === getDatasetInputFingerprint(right);
89
+ }
90
+ /**
91
+ * Content equality for a dataset registry, ignoring object-wrapper identity.
92
+ *
93
+ * Prefer this at call sites that want a boolean compare; it is fingerprint-
94
+ * backed so behavior matches {@link getDatasetRegistryFingerprint}.
95
+ */
96
+ export function areDatasetRegistriesEqual(left, right) {
97
+ if (left === right) {
98
+ return true;
99
+ }
100
+ return (getDatasetRegistryFingerprint(left) === getDatasetRegistryFingerprint(right));
101
+ }
102
+ /**
103
+ * Identity of prepared dataset *payloads*, not the wrapper object.
104
+ *
105
+ * Used so JSONConverter is not rebuilt when a new `datasetStates` record
106
+ * points at the same prepared tables. Geometry column and encoding are part
107
+ * of the identity so two cache entries that share an Arrow table but were
108
+ * prepared with different geometry options do not look interchangeable.
109
+ */
110
+ export function getPreparedDatasetStatesIdentity(datasetStates) {
111
+ return Object.keys(datasetStates)
112
+ .sort()
113
+ .map((datasetId) => {
114
+ const state = datasetStates[datasetId];
115
+ if (state.status === 'ready') {
116
+ return [
117
+ datasetId,
118
+ 'ready',
119
+ getTableIdentity(state.prepared.table),
120
+ buildGeometryKey({
121
+ geometryColumn: state.prepared.datasetGeometryColumn,
122
+ geometryEncodingHint: state.prepared.datasetGeometryEncodingHint,
123
+ }),
124
+ ].join(':');
125
+ }
126
+ if (state.status === 'error') {
127
+ return `${datasetId}:error:${state.error.message}`;
128
+ }
129
+ return `${datasetId}:${state.status}`;
130
+ })
131
+ .join('|');
49
132
  }
50
133
  /**
51
134
  * Build the canonical cache key for one dataset input.
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/datasets/helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import type * as arrow from 'apache-arrow';\nimport {\n isSqlDatasetInput,\n isTableDatasetInput,\n type DeckDatasetInput,\n} from '../types';\nimport {resolveArrowTable} from './normalizeDatasets';\nimport type {PreparedDatasetCacheEntry} from './types';\n\nexport const DEFAULT_MAX_PREPARED_DATASET_ENTRIES = 20;\n\nlet nextDatasetAccess = 0;\nlet nextTableIdentity = 0;\nlet nextSqlSourceIdentity = 0;\n\nconst tableIdentities = new WeakMap<arrow.Table, string>();\nconst sqlSourceIdentities = new WeakMap<object, string>();\n\n/** Return a monotonic access timestamp used by the prepared-dataset LRU. */\nexport function nextAccessTimestamp(): number {\n nextDatasetAccess += 1;\n return nextDatasetAccess;\n}\n\n/**\n * Assign a stable cache identity to an Arrow table object.\n *\n * Table identities are stored in a `WeakMap` so this cache does not extend the\n * lifetime of tables once they are no longer referenced elsewhere.\n */\nexport function getTableIdentity(table: arrow.Table): string {\n const cached = tableIdentities.get(table);\n if (cached) {\n return cached;\n }\n\n nextTableIdentity += 1;\n const identity = `table:${nextTableIdentity}`;\n tableIdentities.set(table, identity);\n return identity;\n}\n\n/**\n * Assign a stable cache identity to the current SQL source object.\n *\n * For SQL datasets we include the upstream DuckDB connector identity in the\n * cache key so two rooms using the same SQL text do not accidentally share\n * prepared results across different database instances.\n */\nexport function getSqlSourceIdentity(sqlSourceIdentity: object): string {\n const cached = sqlSourceIdentities.get(sqlSourceIdentity);\n if (cached) {\n return cached;\n }\n\n nextSqlSourceIdentity += 1;\n const identity = `sql-source:${nextSqlSourceIdentity}`;\n sqlSourceIdentities.set(sqlSourceIdentity, identity);\n return identity;\n}\n\nexport function buildGeometryKey(input: DeckDatasetInput): string {\n return `${input.geometryColumn ?? ''}\\u0001${input.geometryEncodingHint ?? ''}`;\n}\n\n/**\n * Build the canonical cache key for one dataset input.\n *\n * The key intentionally ignores the user-facing dataset id and instead uses\n * the underlying data identity:\n *\n * - SQL/table datasets: DuckDB connector identity + compiled SQL + geometry options\n * - Arrow datasets: table object identity + geometry options\n *\n * Unresolved Arrow inputs (`arrowTable: undefined`) return `undefined`, which\n * signals that the dataset should remain in `loading` until a table exists.\n */\nexport function resolvePreparedDatasetCacheKey(options: {\n input: DeckDatasetInput;\n sqlSourceIdentity?: object;\n}): string | undefined {\n const {input, sqlSourceIdentity} = options;\n\n if (isSqlDatasetInput(input) || isTableDatasetInput(input)) {\n if (!sqlSourceIdentity) {\n throw new Error(\n 'SQL-backed dataset cache keys require a sqlSourceIdentity object.',\n );\n }\n\n if (isTableDatasetInput(input)) {\n return [\n 'table',\n getSqlSourceIdentity(sqlSourceIdentity),\n input.tableName,\n input.transformSql ?? '',\n buildGeometryKey(input),\n ].join('\\u0001');\n }\n\n return [\n 'sql',\n getSqlSourceIdentity(sqlSourceIdentity),\n input.sqlQuery,\n buildGeometryKey(input),\n ].join('\\u0001');\n }\n\n const table = resolveArrowTable(input);\n if (!table) {\n return undefined;\n }\n\n return ['arrow', getTableIdentity(table), buildGeometryKey(input)].join(\n '\\u0001',\n );\n}\n\n/**\n * Clone a cache entry while replacing its consumer set and refreshing the\n * access timestamp.\n *\n * This keeps the discriminated union shape intact while centralizing the\n * bookkeeping needed by consumer reconciliation and LRU tracking.\n */\nexport function cloneEntryWithConsumers(\n entry: PreparedDatasetCacheEntry,\n consumers: Set<string>,\n): PreparedDatasetCacheEntry {\n const lastAccessedAt = nextAccessTimestamp();\n\n if (entry.status === 'loading') {\n return {\n status: 'loading',\n promise: entry.promise,\n consumers,\n lastAccessedAt,\n };\n }\n\n if (entry.status === 'ready') {\n return {\n status: 'ready',\n prepared: entry.prepared,\n consumers,\n lastAccessedAt,\n };\n }\n\n return {\n status: 'error',\n error: entry.error,\n consumers,\n lastAccessedAt,\n };\n}\n\n/** Mark an entry as recently used without changing its lifecycle payload. */\nexport function touchEntry(\n entry: PreparedDatasetCacheEntry,\n): PreparedDatasetCacheEntry {\n return cloneEntryWithConsumers(entry, new Set(entry.consumers));\n}\n\n/**\n * Evict least-recently-used settled entries when the cache exceeds capacity.\n *\n * Only `ready` and `error` entries participate in eviction. `loading` entries\n * are preserved so in-flight work is not discarded, and referenced entries are\n * preserved so active maps never lose their prepared data mid-render.\n */\nexport function evictLruEntries(\n entries: Record<string, PreparedDatasetCacheEntry>,\n maxEntries: number,\n): Record<string, PreparedDatasetCacheEntry> {\n const settledEntries = Object.entries(entries).filter(\n ([, entry]) => entry.status !== 'loading',\n );\n\n if (settledEntries.length <= maxEntries) {\n return entries;\n }\n\n const evictable = settledEntries\n .filter(([, entry]) => entry.consumers.size === 0)\n .sort(([, left], [, right]) => left.lastAccessedAt - right.lastAccessedAt);\n\n if (evictable.length === 0) {\n return entries;\n }\n\n const nextEntries = {...entries};\n let settledCount = settledEntries.length;\n\n for (const [cacheKey] of evictable) {\n if (settledCount <= maxEntries) {\n break;\n }\n\n delete nextEntries[cacheKey];\n settledCount -= 1;\n }\n\n return nextEntries;\n}\n"]}
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/datasets/helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import type * as arrow from 'apache-arrow';\nimport {\n isArrowTableDatasetInput,\n isSqlDatasetInput,\n isTableDatasetInput,\n type DeckDatasetInput,\n type PreparedDeckDatasetState,\n} from '../types';\nimport {resolveArrowTable} from './normalizeDatasets';\nimport type {PreparedDatasetCacheEntry} from './types';\n\nexport const DEFAULT_MAX_PREPARED_DATASET_ENTRIES = 20;\n\nlet nextDatasetAccess = 0;\nlet nextTableIdentity = 0;\nlet nextSqlSourceIdentity = 0;\n\nconst tableIdentities = new WeakMap<arrow.Table, string>();\nconst sqlSourceIdentities = new WeakMap<object, string>();\n\n/** Return a monotonic access timestamp used by the prepared-dataset LRU. */\nexport function nextAccessTimestamp(): number {\n nextDatasetAccess += 1;\n return nextDatasetAccess;\n}\n\n/**\n * Assign a stable cache identity to an Arrow table object.\n *\n * Table identities are stored in a `WeakMap` so this cache does not extend the\n * lifetime of tables once they are no longer referenced elsewhere.\n */\nexport function getTableIdentity(table: arrow.Table): string {\n const cached = tableIdentities.get(table);\n if (cached) {\n return cached;\n }\n\n nextTableIdentity += 1;\n const identity = `table:${nextTableIdentity}`;\n tableIdentities.set(table, identity);\n return identity;\n}\n\n/**\n * Assign a stable cache identity to the current SQL source object.\n *\n * For SQL datasets we include the upstream DuckDB connector identity in the\n * cache key so two rooms using the same SQL text do not accidentally share\n * prepared results across different database instances.\n */\nexport function getSqlSourceIdentity(sqlSourceIdentity: object): string {\n const cached = sqlSourceIdentities.get(sqlSourceIdentity);\n if (cached) {\n return cached;\n }\n\n nextSqlSourceIdentity += 1;\n const identity = `sql-source:${nextSqlSourceIdentity}`;\n sqlSourceIdentities.set(sqlSourceIdentity, identity);\n return identity;\n}\n\nexport function buildGeometryKey(options: {\n geometryColumn?: string;\n geometryEncodingHint?: string;\n}): string {\n return `${options.geometryColumn ?? ''}\\u0001${options.geometryEncodingHint ?? ''}`;\n}\n\n/**\n * Content identity for one dataset input, ignoring object-wrapper identity.\n *\n * Spec-only updates (slider opacity, radius, etc.) often recreate\n * `{ tableName, transformSql }` literals even though the query did not change.\n */\nexport function getDatasetInputFingerprint(input: DeckDatasetInput): string {\n if (isSqlDatasetInput(input)) {\n return `sql\\u0001${input.sqlQuery}\\u0001${buildGeometryKey(input)}`;\n }\n if (isTableDatasetInput(input)) {\n return `table\\u0001${input.tableName}\\u0001${input.transformSql ?? ''}\\u0001${buildGeometryKey(input)}`;\n }\n if (isArrowTableDatasetInput(input)) {\n const table = resolveArrowTable(input);\n return `arrow\\u0001${table ? getTableIdentity(table) : 'pending'}\\u0001${buildGeometryKey(input)}`;\n }\n return 'unknown';\n}\n\n/** Sorted content identity for a dataset registry. */\nexport function getDatasetRegistryFingerprint(\n datasets: Record<string, DeckDatasetInput>,\n): string {\n return Object.entries(datasets)\n .sort(([left], [right]) => left.localeCompare(right))\n .map(\n ([datasetId, input]) =>\n `${datasetId}\\u0001${getDatasetInputFingerprint(input)}`,\n )\n .join('\\u0002');\n}\n\n/**\n * Content equality for one dataset input, ignoring object-wrapper identity.\n *\n * Implemented via {@link getDatasetInputFingerprint} so normalization stays\n * identical to the fingerprint path (`''` vs `undefined`, pending Arrow, etc.).\n * A hand-rolled field compare previously treated those differently and caused\n * `useStableDatasets` to churn, which desynced MapLibre from deck layers.\n */\nexport function areDatasetInputsEqual(\n left: DeckDatasetInput,\n right: DeckDatasetInput,\n): boolean {\n if (left === right) {\n return true;\n }\n return getDatasetInputFingerprint(left) === getDatasetInputFingerprint(right);\n}\n\n/**\n * Content equality for a dataset registry, ignoring object-wrapper identity.\n *\n * Prefer this at call sites that want a boolean compare; it is fingerprint-\n * backed so behavior matches {@link getDatasetRegistryFingerprint}.\n */\nexport function areDatasetRegistriesEqual(\n left: Record<string, DeckDatasetInput>,\n right: Record<string, DeckDatasetInput>,\n): boolean {\n if (left === right) {\n return true;\n }\n return (\n getDatasetRegistryFingerprint(left) === getDatasetRegistryFingerprint(right)\n );\n}\n\n/**\n * Identity of prepared dataset *payloads*, not the wrapper object.\n *\n * Used so JSONConverter is not rebuilt when a new `datasetStates` record\n * points at the same prepared tables. Geometry column and encoding are part\n * of the identity so two cache entries that share an Arrow table but were\n * prepared with different geometry options do not look interchangeable.\n */\nexport function getPreparedDatasetStatesIdentity(\n datasetStates: Record<string, PreparedDeckDatasetState>,\n): string {\n return Object.keys(datasetStates)\n .sort()\n .map((datasetId) => {\n const state = datasetStates[datasetId]!;\n if (state.status === 'ready') {\n return [\n datasetId,\n 'ready',\n getTableIdentity(state.prepared.table),\n buildGeometryKey({\n geometryColumn: state.prepared.datasetGeometryColumn,\n geometryEncodingHint: state.prepared.datasetGeometryEncodingHint,\n }),\n ].join(':');\n }\n if (state.status === 'error') {\n return `${datasetId}:error:${state.error.message}`;\n }\n return `${datasetId}:${state.status}`;\n })\n .join('|');\n}\n\n/**\n * Build the canonical cache key for one dataset input.\n *\n * The key intentionally ignores the user-facing dataset id and instead uses\n * the underlying data identity:\n *\n * - SQL/table datasets: DuckDB connector identity + compiled SQL + geometry options\n * - Arrow datasets: table object identity + geometry options\n *\n * Unresolved Arrow inputs (`arrowTable: undefined`) return `undefined`, which\n * signals that the dataset should remain in `loading` until a table exists.\n */\nexport function resolvePreparedDatasetCacheKey(options: {\n input: DeckDatasetInput;\n sqlSourceIdentity?: object;\n}): string | undefined {\n const {input, sqlSourceIdentity} = options;\n\n if (isSqlDatasetInput(input) || isTableDatasetInput(input)) {\n if (!sqlSourceIdentity) {\n throw new Error(\n 'SQL-backed dataset cache keys require a sqlSourceIdentity object.',\n );\n }\n\n if (isTableDatasetInput(input)) {\n return [\n 'table',\n getSqlSourceIdentity(sqlSourceIdentity),\n input.tableName,\n input.transformSql ?? '',\n buildGeometryKey(input),\n ].join('\\u0001');\n }\n\n return [\n 'sql',\n getSqlSourceIdentity(sqlSourceIdentity),\n input.sqlQuery,\n buildGeometryKey(input),\n ].join('\\u0001');\n }\n\n const table = resolveArrowTable(input);\n if (!table) {\n return undefined;\n }\n\n return ['arrow', getTableIdentity(table), buildGeometryKey(input)].join(\n '\\u0001',\n );\n}\n\n/**\n * Clone a cache entry while replacing its consumer set and refreshing the\n * access timestamp.\n *\n * This keeps the discriminated union shape intact while centralizing the\n * bookkeeping needed by consumer reconciliation and LRU tracking.\n */\nexport function cloneEntryWithConsumers(\n entry: PreparedDatasetCacheEntry,\n consumers: Set<string>,\n): PreparedDatasetCacheEntry {\n const lastAccessedAt = nextAccessTimestamp();\n\n if (entry.status === 'loading') {\n return {\n status: 'loading',\n promise: entry.promise,\n consumers,\n lastAccessedAt,\n };\n }\n\n if (entry.status === 'ready') {\n return {\n status: 'ready',\n prepared: entry.prepared,\n consumers,\n lastAccessedAt,\n };\n }\n\n return {\n status: 'error',\n error: entry.error,\n consumers,\n lastAccessedAt,\n };\n}\n\n/** Mark an entry as recently used without changing its lifecycle payload. */\nexport function touchEntry(\n entry: PreparedDatasetCacheEntry,\n): PreparedDatasetCacheEntry {\n return cloneEntryWithConsumers(entry, new Set(entry.consumers));\n}\n\n/**\n * Evict least-recently-used settled entries when the cache exceeds capacity.\n *\n * Only `ready` and `error` entries participate in eviction. `loading` entries\n * are preserved so in-flight work is not discarded, and referenced entries are\n * preserved so active maps never lose their prepared data mid-render.\n */\nexport function evictLruEntries(\n entries: Record<string, PreparedDatasetCacheEntry>,\n maxEntries: number,\n): Record<string, PreparedDatasetCacheEntry> {\n const settledEntries = Object.entries(entries).filter(\n ([, entry]) => entry.status !== 'loading',\n );\n\n if (settledEntries.length <= maxEntries) {\n return entries;\n }\n\n const evictable = settledEntries\n .filter(([, entry]) => entry.consumers.size === 0)\n .sort(([, left], [, right]) => left.lastAccessedAt - right.lastAccessedAt);\n\n if (evictable.length === 0) {\n return entries;\n }\n\n const nextEntries = {...entries};\n let settledCount = settledEntries.length;\n\n for (const [cacheKey] of evictable) {\n if (settledCount <= maxEntries) {\n break;\n }\n\n delete nextEntries[cacheKey];\n settledCount -= 1;\n }\n\n return nextEntries;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"usePreparedDatasetStates.d.ts","sourceRoot":"","sources":["../../src/datasets/usePreparedDatasetStates.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,KAAK,gBAAgB,EAAE,KAAK,wBAAwB,EAAC,MAAM,UAAU,CAAC;AA0B9E;;;;;;;;;;;;GAYG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,GACzC,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,CA6B1C"}
1
+ {"version":3,"file":"usePreparedDatasetStates.d.ts","sourceRoot":"","sources":["../../src/datasets/usePreparedDatasetStates.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,KAAK,gBAAgB,EAAE,KAAK,wBAAwB,EAAC,MAAM,UAAU,CAAC;AA4B9E;;;;;;;;;;;;GAYG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,GACzC,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAsC1C"}
@@ -1,21 +1,19 @@
1
1
  import { useStoreWithDuckDb } from '@sqlrooms/duckdb';
2
2
  import { useEffect, useId, useMemo, useState } from 'react';
3
3
  import { useStore } from 'zustand';
4
- import { shallow } from 'zustand/shallow';
4
+ import { areDatasetRegistriesEqual, getPreparedDatasetStatesIdentity, } from './helpers';
5
5
  import { preparedDatasetStore, resolvePreparedDeckDatasetStates, } from './PreparedDatasetStore';
6
6
  /**
7
- * Stabilize a `datasets` record so that a new object reference created on
8
- * every render (e.g. an inline `{ earthquakes: { arrowTable } }` literal)
9
- * does not cause downstream effects and memos to re-run when nothing
10
- * actually changed. Uses Zustand's `shallow` to compare top-level keys
11
- * and per-entry identity.
7
+ * Stabilize a `datasets` record so that a new object wrapper created on every
8
+ * render (for example after a slider-driven spec update) does not resync
9
+ * prepared data when the underlying query/table identity is unchanged.
12
10
  *
13
11
  * Implemented via the "adjusting state during rendering" pattern so the
14
12
  * React compiler does not flag ref access during render.
15
13
  */
16
14
  function useStableDatasets(datasets) {
17
15
  const [stable, setStable] = useState(datasets);
18
- if (!shallow(stable, datasets)) {
16
+ if (!areDatasetRegistriesEqual(stable, datasets)) {
19
17
  setStable(datasets);
20
18
  }
21
19
  return stable;
@@ -50,10 +48,16 @@ export function usePreparedDatasetStates(datasets) {
50
48
  preparedDatasetStore.getState().removeConsumer(consumerId);
51
49
  };
52
50
  }, [connector, consumerId, stableDatasets, executeSql]);
53
- return useMemo(() => resolvePreparedDeckDatasetStates({
51
+ const datasetStates = useMemo(() => resolvePreparedDeckDatasetStates({
54
52
  datasets: stableDatasets,
55
53
  entries,
56
54
  sqlSourceIdentity: connector,
57
55
  }), [connector, stableDatasets, entries]);
56
+ const [stableStates, setStableStates] = useState(datasetStates);
57
+ if (getPreparedDatasetStatesIdentity(stableStates) !==
58
+ getPreparedDatasetStatesIdentity(datasetStates)) {
59
+ setStableStates(datasetStates);
60
+ }
61
+ return stableStates;
58
62
  }
59
63
  //# sourceMappingURL=usePreparedDatasetStates.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"usePreparedDatasetStates.js","sourceRoot":"","sources":["../../src/datasets/usePreparedDatasetStates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,kBAAkB,EAAC,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAC,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAC,MAAM,OAAO,CAAC;AAC1D,OAAO,EAAC,QAAQ,EAAC,MAAM,SAAS,CAAC;AACjC,OAAO,EAAC,OAAO,EAAC,MAAM,iBAAiB,CAAC;AAExC,OAAO,EACL,oBAAoB,EACpB,gCAAgC,GACjC,MAAM,wBAAwB,CAAC;AAEhC;;;;;;;;;GASG;AACH,SAAS,iBAAiB,CACxB,QAA0C;IAE1C,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC/C,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC;QAC/B,SAAS,CAAC,QAAQ,CAAC,CAAC;IACtB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,wBAAwB,CACtC,QAA0C;IAE1C,MAAM,cAAc,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IACnD,MAAM,UAAU,GAAG,kBAAkB,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC;IACtE,MAAM,SAAS,GAAG,kBAAkB,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;IACpE,MAAM,UAAU,GAAG,KAAK,EAAE,CAAC;IAC3B,MAAM,OAAO,GAAG,QAAQ,CAAC,oBAAoB,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAEzE,SAAS,CAAC,GAAG,EAAE;QACb,oBAAoB,CAAC,QAAQ,EAAE,CAAC,uBAAuB,CAAC;YACtD,UAAU;YACV,QAAQ,EAAE,cAAc;YACxB,UAAU;YACV,iBAAiB,EAAE,SAAS;SAC7B,CAAC,CAAC;QAEH,OAAO,GAAG,EAAE;YACV,oBAAoB,CAAC,QAAQ,EAAE,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;QAC7D,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC,CAAC;IAExD,OAAO,OAAO,CACZ,GAAG,EAAE,CACH,gCAAgC,CAAC;QAC/B,QAAQ,EAAE,cAAc;QACxB,OAAO;QACP,iBAAiB,EAAE,SAAS;KAC7B,CAAC,EACJ,CAAC,SAAS,EAAE,cAAc,EAAE,OAAO,CAAC,CACrC,CAAC;AACJ,CAAC","sourcesContent":["import {useStoreWithDuckDb} from '@sqlrooms/duckdb';\nimport {useEffect, useId, useMemo, useState} from 'react';\nimport {useStore} from 'zustand';\nimport {shallow} from 'zustand/shallow';\nimport {type DeckDatasetInput, type PreparedDeckDatasetState} from '../types';\nimport {\n preparedDatasetStore,\n resolvePreparedDeckDatasetStates,\n} from './PreparedDatasetStore';\n\n/**\n * Stabilize a `datasets` record so that a new object reference created on\n * every render (e.g. an inline `{ earthquakes: { arrowTable } }` literal)\n * does not cause downstream effects and memos to re-run when nothing\n * actually changed. Uses Zustand's `shallow` to compare top-level keys\n * and per-entry identity.\n *\n * Implemented via the \"adjusting state during rendering\" pattern so the\n * React compiler does not flag ref access during render.\n */\nfunction useStableDatasets(\n datasets: Record<string, DeckDatasetInput>,\n): Record<string, DeckDatasetInput> {\n const [stable, setStable] = useState(datasets);\n if (!shallow(stable, datasets)) {\n setStable(datasets);\n }\n return stable;\n}\n\n/**\n * Subscribe a `DeckJsonMap` instance to prepared dataset state.\n *\n * This hook is intentionally a thin React adapter over the internal prepared\n * dataset store. The heavy work lives in the store so prepared geometry can be\n * reused across rerenders and even across multiple map instances, while the\n * hook itself focuses on subscribing React to the store and cleaning up the\n * consumer membership for this map instance.\n *\n * It preserves the current loading behavior for unresolved Arrow inputs, so a\n * caller can pass `{arrowTable: undefined}` and still render the basemap while\n * data is loading.\n */\nexport function usePreparedDatasetStates(\n datasets: Record<string, DeckDatasetInput>,\n): Record<string, PreparedDeckDatasetState> {\n const stableDatasets = useStableDatasets(datasets);\n const executeSql = useStoreWithDuckDb((state) => state.db.executeSql);\n const connector = useStoreWithDuckDb((state) => state.db.connector);\n const consumerId = useId();\n const entries = useStore(preparedDatasetStore, (state) => state.entries);\n\n useEffect(() => {\n preparedDatasetStore.getState().syncDatasetsForConsumer({\n consumerId,\n datasets: stableDatasets,\n executeSql,\n sqlSourceIdentity: connector,\n });\n\n return () => {\n preparedDatasetStore.getState().removeConsumer(consumerId);\n };\n }, [connector, consumerId, stableDatasets, executeSql]);\n\n return useMemo(\n () =>\n resolvePreparedDeckDatasetStates({\n datasets: stableDatasets,\n entries,\n sqlSourceIdentity: connector,\n }),\n [connector, stableDatasets, entries],\n );\n}\n"]}
1
+ {"version":3,"file":"usePreparedDatasetStates.js","sourceRoot":"","sources":["../../src/datasets/usePreparedDatasetStates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,kBAAkB,EAAC,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAC,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAC,MAAM,OAAO,CAAC;AAC1D,OAAO,EAAC,QAAQ,EAAC,MAAM,SAAS,CAAC;AAEjC,OAAO,EACL,yBAAyB,EACzB,gCAAgC,GACjC,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,oBAAoB,EACpB,gCAAgC,GACjC,MAAM,wBAAwB,CAAC;AAEhC;;;;;;;GAOG;AACH,SAAS,iBAAiB,CACxB,QAA0C;IAE1C,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC/C,IAAI,CAAC,yBAAyB,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC;QACjD,SAAS,CAAC,QAAQ,CAAC,CAAC;IACtB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,wBAAwB,CACtC,QAA0C;IAE1C,MAAM,cAAc,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IACnD,MAAM,UAAU,GAAG,kBAAkB,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC;IACtE,MAAM,SAAS,GAAG,kBAAkB,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;IACpE,MAAM,UAAU,GAAG,KAAK,EAAE,CAAC;IAC3B,MAAM,OAAO,GAAG,QAAQ,CAAC,oBAAoB,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAEzE,SAAS,CAAC,GAAG,EAAE;QACb,oBAAoB,CAAC,QAAQ,EAAE,CAAC,uBAAuB,CAAC;YACtD,UAAU;YACV,QAAQ,EAAE,cAAc;YACxB,UAAU;YACV,iBAAiB,EAAE,SAAS;SAC7B,CAAC,CAAC;QAEH,OAAO,GAAG,EAAE;YACV,oBAAoB,CAAC,QAAQ,EAAE,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;QAC7D,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC,CAAC;IAExD,MAAM,aAAa,GAAG,OAAO,CAC3B,GAAG,EAAE,CACH,gCAAgC,CAAC;QAC/B,QAAQ,EAAE,cAAc;QACxB,OAAO;QACP,iBAAiB,EAAE,SAAS;KAC7B,CAAC,EACJ,CAAC,SAAS,EAAE,cAAc,EAAE,OAAO,CAAC,CACrC,CAAC;IAEF,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,aAAa,CAAC,CAAC;IAChE,IACE,gCAAgC,CAAC,YAAY,CAAC;QAC9C,gCAAgC,CAAC,aAAa,CAAC,EAC/C,CAAC;QACD,eAAe,CAAC,aAAa,CAAC,CAAC;IACjC,CAAC;IACD,OAAO,YAAY,CAAC;AACtB,CAAC","sourcesContent":["import {useStoreWithDuckDb} from '@sqlrooms/duckdb';\nimport {useEffect, useId, useMemo, useState} from 'react';\nimport {useStore} from 'zustand';\nimport {type DeckDatasetInput, type PreparedDeckDatasetState} from '../types';\nimport {\n areDatasetRegistriesEqual,\n getPreparedDatasetStatesIdentity,\n} from './helpers';\nimport {\n preparedDatasetStore,\n resolvePreparedDeckDatasetStates,\n} from './PreparedDatasetStore';\n\n/**\n * Stabilize a `datasets` record so that a new object wrapper created on every\n * render (for example after a slider-driven spec update) does not resync\n * prepared data when the underlying query/table identity is unchanged.\n *\n * Implemented via the \"adjusting state during rendering\" pattern so the\n * React compiler does not flag ref access during render.\n */\nfunction useStableDatasets(\n datasets: Record<string, DeckDatasetInput>,\n): Record<string, DeckDatasetInput> {\n const [stable, setStable] = useState(datasets);\n if (!areDatasetRegistriesEqual(stable, datasets)) {\n setStable(datasets);\n }\n return stable;\n}\n\n/**\n * Subscribe a `DeckJsonMap` instance to prepared dataset state.\n *\n * This hook is intentionally a thin React adapter over the internal prepared\n * dataset store. The heavy work lives in the store so prepared geometry can be\n * reused across rerenders and even across multiple map instances, while the\n * hook itself focuses on subscribing React to the store and cleaning up the\n * consumer membership for this map instance.\n *\n * It preserves the current loading behavior for unresolved Arrow inputs, so a\n * caller can pass `{arrowTable: undefined}` and still render the basemap while\n * data is loading.\n */\nexport function usePreparedDatasetStates(\n datasets: Record<string, DeckDatasetInput>,\n): Record<string, PreparedDeckDatasetState> {\n const stableDatasets = useStableDatasets(datasets);\n const executeSql = useStoreWithDuckDb((state) => state.db.executeSql);\n const connector = useStoreWithDuckDb((state) => state.db.connector);\n const consumerId = useId();\n const entries = useStore(preparedDatasetStore, (state) => state.entries);\n\n useEffect(() => {\n preparedDatasetStore.getState().syncDatasetsForConsumer({\n consumerId,\n datasets: stableDatasets,\n executeSql,\n sqlSourceIdentity: connector,\n });\n\n return () => {\n preparedDatasetStore.getState().removeConsumer(consumerId);\n };\n }, [connector, consumerId, stableDatasets, executeSql]);\n\n const datasetStates = useMemo(\n () =>\n resolvePreparedDeckDatasetStates({\n datasets: stableDatasets,\n entries,\n sqlSourceIdentity: connector,\n }),\n [connector, stableDatasets, entries],\n );\n\n const [stableStates, setStableStates] = useState(datasetStates);\n if (\n getPreparedDatasetStatesIdentity(stableStates) !==\n getPreparedDatasetStatesIdentity(datasetStates)\n ) {\n setStableStates(datasetStates);\n }\n return stableStates;\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -9,8 +9,8 @@ export { DeckMapSettingsPanel, type DeckMapSettingsPanelProps, } from './MapSett
9
9
  export { DeckMapBlockRenderer, ensureDeckMapResourceState, type DeckMapBlockRendererProps, } from './block';
10
10
  export { asDeckJsonMapConfig, createEmptyDeckMapConfig, createDeckMapDashboardPanelConfig, DEFAULT_DECK_MAP_MAX_DATA_POINTS, DECK_MAP_DASHBOARD_PANEL_TYPE, isDeckMapDashboardSqlDatasetSource, isDeckMapDashboardTableDatasetSource, } from './mapConfig';
11
11
  export { getDeckMapDataPolicy, type DeckMapDataPolicy } from './mapDataPolicy';
12
- export { createDeckMapDashboardConfigForTable, createDeckMapConfigForTable, createDeckMapDashboardPanelConfigForTable, createDeckMapPointTransformSql, findDeckMapLongitudeLatitudeColumns, findGeometryColumn, findLongitudeLatitudeColumns, normalizeDeckMapFillColor, normalizeDeckMapPointConfig, quoteDeckMapSqlIdentifier, quoteDeckMapSqlTableReference, regenerateMapConfigForTable, } from './mapConfigUtils';
13
- export type { DeckMapConfigColumn, DeckMapFillColor, DeckMapTableReference, } from './mapConfigUtils';
12
+ export { applyDeckMapPointBinding, createDeckMapDashboardConfigForTable, createDeckMapConfigForTable, createDeckMapDashboardPanelConfigForTable, createDeckMapPointTransformSql, findDeckMapLongitudeLatitudeColumns, findGeometryColumn, findLongitudeLatitudeColumns, normalizeDeckMapFillColor, normalizeDeckMapPointConfig, quoteDeckMapSqlIdentifier, quoteDeckMapSqlTableReference, regenerateMapConfigForTable, } from './mapConfigUtils';
13
+ export type { DeckMapConfigColumn, DeckMapFillColor, DeckMapPointBinding, DeckMapTableReference, } from './mapConfigUtils';
14
14
  export { getFirstDatasetSourceTableName, hasSqlOnlyDatasetSource, } from './datasetSourceUtils';
15
15
  export type { DeckMapDatasetSourceConfig } from './datasetSourceUtils';
16
16
  export { DeckMapResourceConfigParameter, DeckMapResourceToolParameters, } from './mapAiConfig';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ export { DeckMapSettingsPanel, } from './MapSettings';
9
9
  export { DeckMapBlockRenderer, ensureDeckMapResourceState, } from './block';
10
10
  export { asDeckJsonMapConfig, createEmptyDeckMapConfig, createDeckMapDashboardPanelConfig, DEFAULT_DECK_MAP_MAX_DATA_POINTS, DECK_MAP_DASHBOARD_PANEL_TYPE, isDeckMapDashboardSqlDatasetSource, isDeckMapDashboardTableDatasetSource, } from './mapConfig';
11
11
  export { getDeckMapDataPolicy } from './mapDataPolicy';
12
- export { createDeckMapDashboardConfigForTable, createDeckMapConfigForTable, createDeckMapDashboardPanelConfigForTable, createDeckMapPointTransformSql, findDeckMapLongitudeLatitudeColumns, findGeometryColumn, findLongitudeLatitudeColumns, normalizeDeckMapFillColor, normalizeDeckMapPointConfig, quoteDeckMapSqlIdentifier, quoteDeckMapSqlTableReference, regenerateMapConfigForTable, } from './mapConfigUtils';
12
+ export { applyDeckMapPointBinding, createDeckMapDashboardConfigForTable, createDeckMapConfigForTable, createDeckMapDashboardPanelConfigForTable, createDeckMapPointTransformSql, findDeckMapLongitudeLatitudeColumns, findGeometryColumn, findLongitudeLatitudeColumns, normalizeDeckMapFillColor, normalizeDeckMapPointConfig, quoteDeckMapSqlIdentifier, quoteDeckMapSqlTableReference, regenerateMapConfigForTable, } from './mapConfigUtils';
13
13
  export { getFirstDatasetSourceTableName, hasSqlOnlyDatasetSource, } from './datasetSourceUtils';
14
14
  export { DeckMapResourceConfigParameter, DeckMapResourceToolParameters, } from './mapAiConfig';
15
15
  export { normalizeAiDeckMapConfig, prepareAiDeckMapConfig, validateAndFixColorScaleFields, } from './aiNormalize';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAC,gBAAgB,EAAC,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAC,8BAA8B,EAAC,MAAM,kCAAkC,CAAC;AAChF,OAAO,EAAC,oBAAoB,EAAC,MAAM,oBAAoB,CAAC;AACxD,OAAO,EACL,oBAAoB,GAErB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,oBAAoB,EACpB,0BAA0B,GAE3B,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,mBAAmB,EACnB,wBAAwB,EACxB,iCAAiC,EACjC,gCAAgC,EAChC,6BAA6B,EAC7B,kCAAkC,EAClC,oCAAoC,GACrC,MAAM,aAAa,CAAC;AACrB,OAAO,EAAC,oBAAoB,EAAyB,MAAM,iBAAiB,CAAC;AAC7E,OAAO,EACL,oCAAoC,EACpC,2BAA2B,EAC3B,yCAAyC,EACzC,8BAA8B,EAC9B,mCAAmC,EACnC,kBAAkB,EAClB,4BAA4B,EAC5B,yBAAyB,EACzB,2BAA2B,EAC3B,yBAAyB,EACzB,6BAA6B,EAC7B,2BAA2B,GAC5B,MAAM,kBAAkB,CAAC;AAM1B,OAAO,EACL,8BAA8B,EAC9B,uBAAuB,GACxB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,8BAA8B,EAC9B,6BAA6B,GAC9B,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,wBAAwB,EACxB,sBAAsB,EACtB,8BAA8B,GAI/B,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,0BAA0B,EAC1B,2BAA2B,EAC3B,gCAAgC,EAChC,8BAA8B,EAC9B,+BAA+B,GAIhC,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,6BAA6B,GAI9B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,iBAAiB,CAAC;AAOzB,OAAO,EACL,cAAc,EACd,wBAAwB,GAGzB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,6BAA6B,EAC7B,4BAA4B,EAC5B,mBAAmB,EACnB,qCAAqC,EACrC,8BAA8B,GAE/B,MAAM,6BAA6B,CAAC;AAerC,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAC1C,OAAO,EACL,4BAA4B,EAC5B,mBAAmB,EACnB,uBAAuB,GAGxB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,kBAAkB,EAClB,oBAAoB,IAAI,wBAAwB,EAChD,oBAAoB,EACpB,eAAe,EACf,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAC,2BAA2B,EAAC,MAAM,oCAAoC,CAAC;AAC/E,OAAO,EAAC,kBAAkB,EAAC,MAAM,8BAA8B,CAAC;AAUhE,OAAO,EACL,wBAAwB,EACxB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,kCAAkC,EAClC,yBAAyB,GAC1B,MAAM,4BAA4B,CAAC","sourcesContent":["/**\n * {@include ../README.md}\n * @packageDocumentation\n */\n\nexport {ColorScaleLegend} from '@sqlrooms/color-scales';\nexport {createDeckJsonSpecFromDatasets} from './createDeckJsonSpecFromDatasets';\nexport {DeckMapBlockSettings} from './BlockMapSettings';\nexport {\n DeckMapSettingsPanel,\n type DeckMapSettingsPanelProps,\n} from './MapSettings';\nexport {\n DeckMapBlockRenderer,\n ensureDeckMapResourceState,\n type DeckMapBlockRendererProps,\n} from './block';\nexport {\n asDeckJsonMapConfig,\n createEmptyDeckMapConfig,\n createDeckMapDashboardPanelConfig,\n DEFAULT_DECK_MAP_MAX_DATA_POINTS,\n DECK_MAP_DASHBOARD_PANEL_TYPE,\n isDeckMapDashboardSqlDatasetSource,\n isDeckMapDashboardTableDatasetSource,\n} from './mapConfig';\nexport {getDeckMapDataPolicy, type DeckMapDataPolicy} from './mapDataPolicy';\nexport {\n createDeckMapDashboardConfigForTable,\n createDeckMapConfigForTable,\n createDeckMapDashboardPanelConfigForTable,\n createDeckMapPointTransformSql,\n findDeckMapLongitudeLatitudeColumns,\n findGeometryColumn,\n findLongitudeLatitudeColumns,\n normalizeDeckMapFillColor,\n normalizeDeckMapPointConfig,\n quoteDeckMapSqlIdentifier,\n quoteDeckMapSqlTableReference,\n regenerateMapConfigForTable,\n} from './mapConfigUtils';\nexport type {\n DeckMapConfigColumn,\n DeckMapFillColor,\n DeckMapTableReference,\n} from './mapConfigUtils';\nexport {\n getFirstDatasetSourceTableName,\n hasSqlOnlyDatasetSource,\n} from './datasetSourceUtils';\nexport type {DeckMapDatasetSourceConfig} from './datasetSourceUtils';\nexport {\n DeckMapResourceConfigParameter,\n DeckMapResourceToolParameters,\n} from './mapAiConfig';\nexport {\n normalizeAiDeckMapConfig,\n prepareAiDeckMapConfig,\n validateAndFixColorScaleFields,\n type NormalizeAiDeckMapConfigOptions,\n type PrepareAiDeckMapConfigOptions,\n type ResolveColorScaleTable,\n} from './aiNormalize';\nexport {\n DeckMapResourceConfigError,\n assertDeckMapResourceConfig,\n getDeckMapResourceAiInstructions,\n getDeckMapResourceConfigIssues,\n mergeDeckMapResourceConfigPatch,\n type DeckMapResourceConfigMergeOptions,\n type DeckMapResourceConfigIssue,\n type DeckMapResourceConfigValidationOptions,\n} from './mapResourceAuthoring';\nexport {\n createOrUpdateDeckMapResource,\n type CreateOrUpdateDeckMapResourceHost,\n type CreateOrUpdateDeckMapResourceParams,\n type CreateOrUpdateDeckMapResourceResult,\n} from './createOrUpdateDeckMapResource';\nexport {\n DeckMapResourceSchema,\n DeckMapsSliceConfig,\n createDeckMapsSlice,\n useStoreWithDeckMaps,\n} from './DeckMapsSlice';\nexport type {\n DeckMapResource,\n DeckMapRuntimeIssue,\n DeckMapRuntimeIssueReporter,\n DeckMapsSliceState,\n} from './DeckMapsSlice';\nexport {\n DeckMapSurface,\n directDeckMapDataAdapter,\n type DeckMapDataAdapter,\n type DeckMapSurfaceProps,\n} from './DeckMapSurface';\nexport {\n DECK_MAP_BLOCK_DEFAULT_HEIGHT,\n DECK_MAP_BLOCK_DEFAULT_TITLE,\n DECK_MAP_BLOCK_TYPE,\n createDeckMapBlockDocumentCommandType,\n createDeckMapBlockDocumentType,\n type DeckMapBlockDocumentRegistrationOptions,\n} from './blockDocumentRegistration';\nexport type {\n DeckMapConfigMode,\n DeckMapDashboardFitToDataConfig,\n CreateDeckMapDashboardPanelConfigOptions,\n DeckMapDashboardDatasetConfig,\n DeckMapDataPolicyOverride,\n DeckMapDashboardInteractionConfig,\n DeckMapDashboardPanelConfig,\n DeckMapConfig,\n DeckMapDatasetConfig,\n DeckMapDatasetSource,\n DeckMapFitToDataConfig,\n DeckMapInteractionConfig,\n} from './mapConfig';\nexport {DeckJsonMap} from './DeckJsonMap';\nexport {\n DeckMapDefaultStylesProvider,\n resolveDeckMapStyle,\n useDeckMapDefaultStyles,\n type DeckMapDefaultStyles,\n type DeckMapStyle,\n} from './DeckMapDefaultStylesProvider';\nexport {\n ColorScaleFunction,\n GeometryEncodingHint as DeckGeometryEncodingHint,\n DeckJsonMapLayerSpec,\n DeckJsonMapSpec,\n LayerBindingConfig,\n LayerBindingProps,\n} from './DeckJsonMapSpec';\nexport {createDeckJsonConfiguration} from './json/createDeckJsonConfiguration';\nexport {prepareDeckDataset} from './prepare/prepareDeckDataset';\n\nexport type {ColorLegendConfig, ColorScaleConfig} from '@sqlrooms/color-scales';\nexport type {\n GeometryEncodingHint,\n PreparedDeckDataset,\n PreparedGeoArrowLayerData,\n ResolvedGeometryColumn,\n ResolvedGeometryEncoding,\n} from './prepare/types';\nexport {\n isArrowTableDatasetInput,\n isSqlDatasetInput,\n isTableDatasetInput,\n} from './types';\nexport {\n DECK_TABLE_DATASET_SOURCE_RELATION,\n createDeckTableDatasetSql,\n} from './datasets/tableDatasetSql';\nexport type {\n CreateDeckJsonSpecFromDatasetsOptions,\n DeckArrowTableDatasetInput,\n DeckAutoLayerType,\n DeckDatasetInput,\n DeckJsonMapHandle,\n DeckJsonMapProps,\n DeckJsonSpecDatasetHint,\n DeckSqlDatasetInput,\n DeckTableDatasetInput,\n DeckTable,\n PreparedDeckDatasetState,\n} from './types';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAC,gBAAgB,EAAC,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAC,8BAA8B,EAAC,MAAM,kCAAkC,CAAC;AAChF,OAAO,EAAC,oBAAoB,EAAC,MAAM,oBAAoB,CAAC;AACxD,OAAO,EACL,oBAAoB,GAErB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,oBAAoB,EACpB,0BAA0B,GAE3B,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,mBAAmB,EACnB,wBAAwB,EACxB,iCAAiC,EACjC,gCAAgC,EAChC,6BAA6B,EAC7B,kCAAkC,EAClC,oCAAoC,GACrC,MAAM,aAAa,CAAC;AACrB,OAAO,EAAC,oBAAoB,EAAyB,MAAM,iBAAiB,CAAC;AAC7E,OAAO,EACL,wBAAwB,EACxB,oCAAoC,EACpC,2BAA2B,EAC3B,yCAAyC,EACzC,8BAA8B,EAC9B,mCAAmC,EACnC,kBAAkB,EAClB,4BAA4B,EAC5B,yBAAyB,EACzB,2BAA2B,EAC3B,yBAAyB,EACzB,6BAA6B,EAC7B,2BAA2B,GAC5B,MAAM,kBAAkB,CAAC;AAO1B,OAAO,EACL,8BAA8B,EAC9B,uBAAuB,GACxB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,8BAA8B,EAC9B,6BAA6B,GAC9B,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,wBAAwB,EACxB,sBAAsB,EACtB,8BAA8B,GAI/B,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,0BAA0B,EAC1B,2BAA2B,EAC3B,gCAAgC,EAChC,8BAA8B,EAC9B,+BAA+B,GAIhC,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,6BAA6B,GAI9B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,iBAAiB,CAAC;AAOzB,OAAO,EACL,cAAc,EACd,wBAAwB,GAGzB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,6BAA6B,EAC7B,4BAA4B,EAC5B,mBAAmB,EACnB,qCAAqC,EACrC,8BAA8B,GAE/B,MAAM,6BAA6B,CAAC;AAerC,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAC1C,OAAO,EACL,4BAA4B,EAC5B,mBAAmB,EACnB,uBAAuB,GAGxB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,kBAAkB,EAClB,oBAAoB,IAAI,wBAAwB,EAChD,oBAAoB,EACpB,eAAe,EACf,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAC,2BAA2B,EAAC,MAAM,oCAAoC,CAAC;AAC/E,OAAO,EAAC,kBAAkB,EAAC,MAAM,8BAA8B,CAAC;AAUhE,OAAO,EACL,wBAAwB,EACxB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,kCAAkC,EAClC,yBAAyB,GAC1B,MAAM,4BAA4B,CAAC","sourcesContent":["/**\n * {@include ../README.md}\n * @packageDocumentation\n */\n\nexport {ColorScaleLegend} from '@sqlrooms/color-scales';\nexport {createDeckJsonSpecFromDatasets} from './createDeckJsonSpecFromDatasets';\nexport {DeckMapBlockSettings} from './BlockMapSettings';\nexport {\n DeckMapSettingsPanel,\n type DeckMapSettingsPanelProps,\n} from './MapSettings';\nexport {\n DeckMapBlockRenderer,\n ensureDeckMapResourceState,\n type DeckMapBlockRendererProps,\n} from './block';\nexport {\n asDeckJsonMapConfig,\n createEmptyDeckMapConfig,\n createDeckMapDashboardPanelConfig,\n DEFAULT_DECK_MAP_MAX_DATA_POINTS,\n DECK_MAP_DASHBOARD_PANEL_TYPE,\n isDeckMapDashboardSqlDatasetSource,\n isDeckMapDashboardTableDatasetSource,\n} from './mapConfig';\nexport {getDeckMapDataPolicy, type DeckMapDataPolicy} from './mapDataPolicy';\nexport {\n applyDeckMapPointBinding,\n createDeckMapDashboardConfigForTable,\n createDeckMapConfigForTable,\n createDeckMapDashboardPanelConfigForTable,\n createDeckMapPointTransformSql,\n findDeckMapLongitudeLatitudeColumns,\n findGeometryColumn,\n findLongitudeLatitudeColumns,\n normalizeDeckMapFillColor,\n normalizeDeckMapPointConfig,\n quoteDeckMapSqlIdentifier,\n quoteDeckMapSqlTableReference,\n regenerateMapConfigForTable,\n} from './mapConfigUtils';\nexport type {\n DeckMapConfigColumn,\n DeckMapFillColor,\n DeckMapPointBinding,\n DeckMapTableReference,\n} from './mapConfigUtils';\nexport {\n getFirstDatasetSourceTableName,\n hasSqlOnlyDatasetSource,\n} from './datasetSourceUtils';\nexport type {DeckMapDatasetSourceConfig} from './datasetSourceUtils';\nexport {\n DeckMapResourceConfigParameter,\n DeckMapResourceToolParameters,\n} from './mapAiConfig';\nexport {\n normalizeAiDeckMapConfig,\n prepareAiDeckMapConfig,\n validateAndFixColorScaleFields,\n type NormalizeAiDeckMapConfigOptions,\n type PrepareAiDeckMapConfigOptions,\n type ResolveColorScaleTable,\n} from './aiNormalize';\nexport {\n DeckMapResourceConfigError,\n assertDeckMapResourceConfig,\n getDeckMapResourceAiInstructions,\n getDeckMapResourceConfigIssues,\n mergeDeckMapResourceConfigPatch,\n type DeckMapResourceConfigMergeOptions,\n type DeckMapResourceConfigIssue,\n type DeckMapResourceConfigValidationOptions,\n} from './mapResourceAuthoring';\nexport {\n createOrUpdateDeckMapResource,\n type CreateOrUpdateDeckMapResourceHost,\n type CreateOrUpdateDeckMapResourceParams,\n type CreateOrUpdateDeckMapResourceResult,\n} from './createOrUpdateDeckMapResource';\nexport {\n DeckMapResourceSchema,\n DeckMapsSliceConfig,\n createDeckMapsSlice,\n useStoreWithDeckMaps,\n} from './DeckMapsSlice';\nexport type {\n DeckMapResource,\n DeckMapRuntimeIssue,\n DeckMapRuntimeIssueReporter,\n DeckMapsSliceState,\n} from './DeckMapsSlice';\nexport {\n DeckMapSurface,\n directDeckMapDataAdapter,\n type DeckMapDataAdapter,\n type DeckMapSurfaceProps,\n} from './DeckMapSurface';\nexport {\n DECK_MAP_BLOCK_DEFAULT_HEIGHT,\n DECK_MAP_BLOCK_DEFAULT_TITLE,\n DECK_MAP_BLOCK_TYPE,\n createDeckMapBlockDocumentCommandType,\n createDeckMapBlockDocumentType,\n type DeckMapBlockDocumentRegistrationOptions,\n} from './blockDocumentRegistration';\nexport type {\n DeckMapConfigMode,\n DeckMapDashboardFitToDataConfig,\n CreateDeckMapDashboardPanelConfigOptions,\n DeckMapDashboardDatasetConfig,\n DeckMapDataPolicyOverride,\n DeckMapDashboardInteractionConfig,\n DeckMapDashboardPanelConfig,\n DeckMapConfig,\n DeckMapDatasetConfig,\n DeckMapDatasetSource,\n DeckMapFitToDataConfig,\n DeckMapInteractionConfig,\n} from './mapConfig';\nexport {DeckJsonMap} from './DeckJsonMap';\nexport {\n DeckMapDefaultStylesProvider,\n resolveDeckMapStyle,\n useDeckMapDefaultStyles,\n type DeckMapDefaultStyles,\n type DeckMapStyle,\n} from './DeckMapDefaultStylesProvider';\nexport {\n ColorScaleFunction,\n GeometryEncodingHint as DeckGeometryEncodingHint,\n DeckJsonMapLayerSpec,\n DeckJsonMapSpec,\n LayerBindingConfig,\n LayerBindingProps,\n} from './DeckJsonMapSpec';\nexport {createDeckJsonConfiguration} from './json/createDeckJsonConfiguration';\nexport {prepareDeckDataset} from './prepare/prepareDeckDataset';\n\nexport type {ColorLegendConfig, ColorScaleConfig} from '@sqlrooms/color-scales';\nexport type {\n GeometryEncodingHint,\n PreparedDeckDataset,\n PreparedGeoArrowLayerData,\n ResolvedGeometryColumn,\n ResolvedGeometryEncoding,\n} from './prepare/types';\nexport {\n isArrowTableDatasetInput,\n isSqlDatasetInput,\n isTableDatasetInput,\n} from './types';\nexport {\n DECK_TABLE_DATASET_SOURCE_RELATION,\n createDeckTableDatasetSql,\n} from './datasets/tableDatasetSql';\nexport type {\n CreateDeckJsonSpecFromDatasetsOptions,\n DeckArrowTableDatasetInput,\n DeckAutoLayerType,\n DeckDatasetInput,\n DeckJsonMapHandle,\n DeckJsonMapProps,\n DeckJsonSpecDatasetHint,\n DeckSqlDatasetInput,\n DeckTableDatasetInput,\n DeckTable,\n PreparedDeckDatasetState,\n} from './types';\n"]}
@@ -1,10 +1,18 @@
1
1
  import type { ColorScaleConfig } from '@sqlrooms/color-scales';
2
2
  declare const SQLROOMS_COLOR_SCALE_MARKER: unique symbol;
3
+ /**
4
+ * `@sqlrooms/color-scales` config plus optional Deck per-accessor opacity.
5
+ * `opacity` is a SQLRooms `colorScale` JSON extension, not a color-scales field.
6
+ */
7
+ export type DeckColorScaleConfig = ColorScaleConfig & {
8
+ /** Per-accessor opacity 0–1; multiplied into compiled RGBA alpha. */
9
+ opacity?: number;
10
+ };
3
11
  export type ColorScaleMarker = {
4
- colorScale: ColorScaleConfig;
12
+ colorScale: DeckColorScaleConfig;
5
13
  [SQLROOMS_COLOR_SCALE_MARKER]: true;
6
14
  };
7
- export declare function createColorScaleMarker(value: ColorScaleConfig): ColorScaleMarker;
15
+ export declare function createColorScaleMarker(value: DeckColorScaleConfig): ColorScaleMarker;
8
16
  export declare function isColorScaleMarker(value: unknown): value is ColorScaleMarker;
9
17
  /** Names of layer accessor props that can carry a color scale. */
10
18
  export type ColorScalePropName = 'getFillColor' | 'getLineColor' | 'getColor' | 'getSourceColor' | 'getTargetColor';
@@ -16,12 +24,12 @@ export declare const COLOR_SCALE_PROP_NAMES: readonly ColorScalePropName[];
16
24
  */
17
25
  export declare function getColorScale(props: Record<string, unknown>): {
18
26
  propName: ColorScalePropName;
19
- colorScale: ColorScaleConfig;
27
+ colorScale: DeckColorScaleConfig;
20
28
  } | undefined;
21
29
  /** Returns every color scale entry found across all known accessor props on the layer. */
22
30
  export declare function getAllColorScales(props: Record<string, unknown>): Array<{
23
31
  propName: ColorScalePropName;
24
- colorScale: ColorScaleConfig;
32
+ colorScale: DeckColorScaleConfig;
25
33
  }>;
26
34
  export {};
27
35
  //# sourceMappingURL=colorScaleFunction.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"colorScaleFunction.d.ts","sourceRoot":"","sources":["../../src/json/colorScaleFunction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,wBAAwB,CAAC;AAG7D,QAAA,MAAM,2BAA2B,eAEhC,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,UAAU,EAAE,gBAAgB,CAAC;IAC7B,CAAC,2BAA2B,CAAC,EAAE,IAAI,CAAC;CACrC,CAAC;AAEF,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,gBAAgB,GACtB,gBAAgB,CAKlB;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,gBAAgB,CAU5E;AAED,kEAAkE;AAClE,MAAM,MAAM,kBAAkB,GAC1B,cAAc,GACd,cAAc,GACd,UAAU,GACV,gBAAgB,GAChB,gBAAgB,CAAC;AAErB,2CAA2C;AAC3C,eAAO,MAAM,sBAAsB,EAAE,SAAS,kBAAkB,EAM/D,CAAC;AAEF;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACxD;IACE,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,UAAU,EAAE,gBAAgB,CAAC;CAC9B,GACD,SAAS,CAGZ;AAED,0FAA0F;AAC1F,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC;IACvE,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,UAAU,EAAE,gBAAgB,CAAC;CAC9B,CAAC,CAgBD"}
1
+ {"version":3,"file":"colorScaleFunction.d.ts","sourceRoot":"","sources":["../../src/json/colorScaleFunction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,wBAAwB,CAAC;AAG7D,QAAA,MAAM,2BAA2B,eAEhC,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,GAAG;IACpD,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,UAAU,EAAE,oBAAoB,CAAC;IACjC,CAAC,2BAA2B,CAAC,EAAE,IAAI,CAAC;CACrC,CAAC;AAEF,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,oBAAoB,GAC1B,gBAAgB,CAKlB;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,gBAAgB,CAU5E;AAED,kEAAkE;AAClE,MAAM,MAAM,kBAAkB,GAC1B,cAAc,GACd,cAAc,GACd,UAAU,GACV,gBAAgB,GAChB,gBAAgB,CAAC;AAErB,2CAA2C;AAC3C,eAAO,MAAM,sBAAsB,EAAE,SAAS,kBAAkB,EAM/D,CAAC;AAEF;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACxD;IACE,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,UAAU,EAAE,oBAAoB,CAAC;CAClC,GACD,SAAS,CAGZ;AAED,0FAA0F;AAC1F,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC;IACvE,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,UAAU,EAAE,oBAAoB,CAAC;CAClC,CAAC,CAgBD"}
@@ -1 +1 @@
1
- {"version":3,"file":"colorScaleFunction.js","sourceRoot":"","sources":["../../src/json/colorScaleFunction.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,oBAAoB,EAAC,MAAM,eAAe,CAAC;AAEnD,MAAM,2BAA2B,GAAG,MAAM,CAAC,GAAG,CAC5C,qCAAqC,CACtC,CAAC;AAOF,MAAM,UAAU,sBAAsB,CACpC,KAAuB;IAEvB,OAAO;QACL,UAAU,EAAE,KAAK;QACjB,CAAC,2BAA2B,CAAC,EAAE,IAAI;KACpC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAc;IAC/C,OAAO,OAAO,CACZ,KAAK;QACL,OAAO,KAAK,KAAK,QAAQ;QACxB,KAAmD,CAClD,2BAA2B,CAC5B;QACD,OAAQ,KAAgC,CAAC,UAAU,KAAK,QAAQ;QAC/D,KAAgC,CAAC,UAAU,IAAI,IAAI,CACrD,CAAC;AACJ,CAAC;AAUD,2CAA2C;AAC3C,MAAM,CAAC,MAAM,sBAAsB,GAAkC;IACnE,cAAc;IACd,cAAc;IACd,UAAU;IACV,gBAAgB;IAChB,gBAAgB;CACjB,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,KAA8B;IAM1D,MAAM,GAAG,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;IACrC,OAAO,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC7C,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,iBAAiB,CAAC,KAA8B;IAI9D,MAAM,OAAO,GAGR,EAAE,CAAC;IAER,KAAK,MAAM,QAAQ,IAAI,sBAAsB,EAAE,CAAC;QAC9C,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC9B,IAAI,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9B,OAAO,CAAC,IAAI,CAAC,EAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAC,CAAC,CAAC;QACzD,CAAC;aAAM,IAAI,oBAAoB,CAAC,KAAK,CAAC,EAAE,CAAC;YACvC,OAAO,CAAC,IAAI,CAAC,EAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAC,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC","sourcesContent":["import type {ColorScaleConfig} from '@sqlrooms/color-scales';\nimport {isColorScaleFunction} from './layerConfig';\n\nconst SQLROOMS_COLOR_SCALE_MARKER = Symbol.for(\n '@sqlrooms/deck/sqlrooms-color-scale',\n);\n\nexport type ColorScaleMarker = {\n colorScale: ColorScaleConfig;\n [SQLROOMS_COLOR_SCALE_MARKER]: true;\n};\n\nexport function createColorScaleMarker(\n value: ColorScaleConfig,\n): ColorScaleMarker {\n return {\n colorScale: value,\n [SQLROOMS_COLOR_SCALE_MARKER]: true,\n };\n}\n\nexport function isColorScaleMarker(value: unknown): value is ColorScaleMarker {\n return Boolean(\n value &&\n typeof value === 'object' &&\n (value as {[SQLROOMS_COLOR_SCALE_MARKER]?: boolean})[\n SQLROOMS_COLOR_SCALE_MARKER\n ] &&\n typeof (value as {colorScale?: unknown}).colorScale === 'object' &&\n (value as {colorScale?: unknown}).colorScale != null,\n );\n}\n\n/** Names of layer accessor props that can carry a color scale. */\nexport type ColorScalePropName =\n | 'getFillColor'\n | 'getLineColor'\n | 'getColor'\n | 'getSourceColor'\n | 'getTargetColor';\n\n/** All known color accessor prop names. */\nexport const COLOR_SCALE_PROP_NAMES: readonly ColorScalePropName[] = [\n 'getFillColor',\n 'getLineColor',\n 'getColor',\n 'getSourceColor',\n 'getTargetColor',\n];\n\n/**\n * Returns the first color scale entry found on the layer props, if any.\n * Prefer {@link getAllColorScales} when a layer may define multiple color scale accessors.\n */\nexport function getColorScale(props: Record<string, unknown>):\n | {\n propName: ColorScalePropName;\n colorScale: ColorScaleConfig;\n }\n | undefined {\n const all = getAllColorScales(props);\n return all.length > 0 ? all[0] : undefined;\n}\n\n/** Returns every color scale entry found across all known accessor props on the layer. */\nexport function getAllColorScales(props: Record<string, unknown>): Array<{\n propName: ColorScalePropName;\n colorScale: ColorScaleConfig;\n}> {\n const results: Array<{\n propName: ColorScalePropName;\n colorScale: ColorScaleConfig;\n }> = [];\n\n for (const propName of COLOR_SCALE_PROP_NAMES) {\n const value = props[propName];\n if (isColorScaleMarker(value)) {\n results.push({propName, colorScale: value.colorScale});\n } else if (isColorScaleFunction(value)) {\n results.push({propName, colorScale: value});\n }\n }\n\n return results;\n}\n"]}
1
+ {"version":3,"file":"colorScaleFunction.js","sourceRoot":"","sources":["../../src/json/colorScaleFunction.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,oBAAoB,EAAC,MAAM,eAAe,CAAC;AAEnD,MAAM,2BAA2B,GAAG,MAAM,CAAC,GAAG,CAC5C,qCAAqC,CACtC,CAAC;AAgBF,MAAM,UAAU,sBAAsB,CACpC,KAA2B;IAE3B,OAAO;QACL,UAAU,EAAE,KAAK;QACjB,CAAC,2BAA2B,CAAC,EAAE,IAAI;KACpC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAc;IAC/C,OAAO,OAAO,CACZ,KAAK;QACL,OAAO,KAAK,KAAK,QAAQ;QACxB,KAAmD,CAClD,2BAA2B,CAC5B;QACD,OAAQ,KAAgC,CAAC,UAAU,KAAK,QAAQ;QAC/D,KAAgC,CAAC,UAAU,IAAI,IAAI,CACrD,CAAC;AACJ,CAAC;AAUD,2CAA2C;AAC3C,MAAM,CAAC,MAAM,sBAAsB,GAAkC;IACnE,cAAc;IACd,cAAc;IACd,UAAU;IACV,gBAAgB;IAChB,gBAAgB;CACjB,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,KAA8B;IAM1D,MAAM,GAAG,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;IACrC,OAAO,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC7C,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,iBAAiB,CAAC,KAA8B;IAI9D,MAAM,OAAO,GAGR,EAAE,CAAC;IAER,KAAK,MAAM,QAAQ,IAAI,sBAAsB,EAAE,CAAC;QAC9C,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC9B,IAAI,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9B,OAAO,CAAC,IAAI,CAAC,EAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAC,CAAC,CAAC;QACzD,CAAC;aAAM,IAAI,oBAAoB,CAAC,KAAK,CAAC,EAAE,CAAC;YACvC,OAAO,CAAC,IAAI,CAAC,EAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAC,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC","sourcesContent":["import type {ColorScaleConfig} from '@sqlrooms/color-scales';\nimport {isColorScaleFunction} from './layerConfig';\n\nconst SQLROOMS_COLOR_SCALE_MARKER = Symbol.for(\n '@sqlrooms/deck/sqlrooms-color-scale',\n);\n\n/**\n * `@sqlrooms/color-scales` config plus optional Deck per-accessor opacity.\n * `opacity` is a SQLRooms `colorScale` JSON extension, not a color-scales field.\n */\nexport type DeckColorScaleConfig = ColorScaleConfig & {\n /** Per-accessor opacity 0–1; multiplied into compiled RGBA alpha. */\n opacity?: number;\n};\n\nexport type ColorScaleMarker = {\n colorScale: DeckColorScaleConfig;\n [SQLROOMS_COLOR_SCALE_MARKER]: true;\n};\n\nexport function createColorScaleMarker(\n value: DeckColorScaleConfig,\n): ColorScaleMarker {\n return {\n colorScale: value,\n [SQLROOMS_COLOR_SCALE_MARKER]: true,\n };\n}\n\nexport function isColorScaleMarker(value: unknown): value is ColorScaleMarker {\n return Boolean(\n value &&\n typeof value === 'object' &&\n (value as {[SQLROOMS_COLOR_SCALE_MARKER]?: boolean})[\n SQLROOMS_COLOR_SCALE_MARKER\n ] &&\n typeof (value as {colorScale?: unknown}).colorScale === 'object' &&\n (value as {colorScale?: unknown}).colorScale != null,\n );\n}\n\n/** Names of layer accessor props that can carry a color scale. */\nexport type ColorScalePropName =\n | 'getFillColor'\n | 'getLineColor'\n | 'getColor'\n | 'getSourceColor'\n | 'getTargetColor';\n\n/** All known color accessor prop names. */\nexport const COLOR_SCALE_PROP_NAMES: readonly ColorScalePropName[] = [\n 'getFillColor',\n 'getLineColor',\n 'getColor',\n 'getSourceColor',\n 'getTargetColor',\n];\n\n/**\n * Returns the first color scale entry found on the layer props, if any.\n * Prefer {@link getAllColorScales} when a layer may define multiple color scale accessors.\n */\nexport function getColorScale(props: Record<string, unknown>):\n | {\n propName: ColorScalePropName;\n colorScale: DeckColorScaleConfig;\n }\n | undefined {\n const all = getAllColorScales(props);\n return all.length > 0 ? all[0] : undefined;\n}\n\n/** Returns every color scale entry found across all known accessor props on the layer. */\nexport function getAllColorScales(props: Record<string, unknown>): Array<{\n propName: ColorScalePropName;\n colorScale: DeckColorScaleConfig;\n}> {\n const results: Array<{\n propName: ColorScalePropName;\n colorScale: DeckColorScaleConfig;\n }> = [];\n\n for (const propName of COLOR_SCALE_PROP_NAMES) {\n const value = props[propName];\n if (isColorScaleMarker(value)) {\n results.push({propName, colorScale: value.colorScale});\n } else if (isColorScaleFunction(value)) {\n results.push({propName, colorScale: value});\n }\n }\n\n return results;\n}\n"]}
@@ -1,9 +1,10 @@
1
1
  import { type ColorScaleConfig, type ResolvedColorLegend } from '@sqlrooms/color-scales';
2
2
  import type * as arrow from 'apache-arrow';
3
+ import type { DeckColorScaleConfig } from './colorScaleFunction';
3
4
  export declare function compileColorScale(options: {
4
5
  table: arrow.Table;
5
- colorScale: ColorScaleConfig;
6
- }): (value: unknown) => import("@sqlrooms/color-scales").ResolvedRGBA;
6
+ colorScale: DeckColorScaleConfig;
7
+ }): (value: unknown) => [number, number, number, number];
7
8
  export declare function buildColorScaleLegend(options: {
8
9
  table: arrow.Table;
9
10
  colorScale: ColorScaleConfig;
@@ -1 +1 @@
1
- {"version":3,"file":"compileColorScale.d.ts","sourceRoot":"","sources":["../../src/json/compileColorScale.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACzB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAC;AAuH3C,wBAAgB,iBAAiB,CAAC,OAAO,EAAE;IACzC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC;IACnB,UAAU,EAAE,gBAAgB,CAAC;CAC9B,WA0BgB,OAAO,mDAEvB;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE;IAC7C,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC;IACnB,UAAU,EAAE,gBAAgB,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,mBAAmB,GAAG,IAAI,CAuB7B"}
1
+ {"version":3,"file":"compileColorScale.d.ts","sourceRoot":"","sources":["../../src/json/compileColorScale.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACzB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,EAAC,oBAAoB,EAAC,MAAM,sBAAsB,CAAC;AAuH/D,wBAAgB,iBAAiB,CAAC,OAAO,EAAE;IACzC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC;IACnB,UAAU,EAAE,oBAAoB,CAAC;CAClC,WA0BgB,OAAO,sCAgBvB;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE;IAC7C,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC;IACnB,UAAU,EAAE,gBAAgB,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,mBAAmB,GAAG,IAAI,CAuB7B"}
@@ -99,7 +99,22 @@ export function compileColorScale(options) {
99
99
  console.warn(`[compileColorScale] Failed to create color scale for field "${colorScale.field}":`, err);
100
100
  return () => MISSING_FIELD_COLOR;
101
101
  }
102
- return (value) => mapper(getGeoArrowOrRowValue({ value, fieldName, vector }));
102
+ return (value) => {
103
+ const color = mapper(getGeoArrowOrRowValue({ value, fieldName, vector }));
104
+ const rawOpacity = colorScale.opacity;
105
+ const opacity = typeof rawOpacity === 'number' && Number.isFinite(rawOpacity)
106
+ ? Math.max(0, Math.min(1, rawOpacity))
107
+ : 1;
108
+ if (opacity >= 1)
109
+ return color;
110
+ const rgba = color;
111
+ return [
112
+ rgba[0],
113
+ rgba[1],
114
+ rgba[2],
115
+ Math.round(Math.max(0, Math.min(255, (rgba[3] ?? 255) * opacity))),
116
+ ];
117
+ };
103
118
  }
104
119
  export function buildColorScaleLegend(options) {
105
120
  const { table, colorScale } = options;
@@ -1 +1 @@
1
- {"version":3,"file":"compileColorScale.js","sourceRoot":"","sources":["../../src/json/compileColorScale.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n buildColorScaleLegend as buildGenericColorScaleLegend,\n coerceFiniteNumber,\n createColorScaleMapper,\n type ColorScaleConfig,\n type ResolvedColorLegend,\n} from '@sqlrooms/color-scales';\nimport type * as arrow from 'apache-arrow';\n\nfunction resolveFieldName(\n schemaOwner: arrow.Table | arrow.RecordBatch,\n requestedField: string,\n) {\n const exactMatch = schemaOwner.schema.fields.find(\n (field) => field.name === requestedField,\n )?.name;\n if (exactMatch) {\n return exactMatch;\n }\n\n const caseInsensitiveMatches = schemaOwner.schema.fields\n .map((field) => field.name)\n .filter(\n (fieldName) => fieldName.toLowerCase() === requestedField.toLowerCase(),\n );\n\n if (caseInsensitiveMatches.length === 1) {\n return caseInsensitiveMatches[0]!;\n }\n\n return undefined;\n}\n\nfunction getRowValue(row: unknown, fieldName: string) {\n if (!row || typeof row !== 'object') {\n return undefined;\n }\n\n const object = row as Record<string, unknown>;\n const sources = [\n object,\n object.properties as Record<string, unknown> | undefined,\n ].filter((value): value is Record<string, unknown> =>\n Boolean(value && typeof value === 'object'),\n );\n\n for (const source of sources) {\n if (fieldName in source) {\n return source[fieldName];\n }\n\n const caseInsensitiveMatches = Object.keys(source).filter(\n (key) => key.toLowerCase() === fieldName.toLowerCase(),\n );\n if (caseInsensitiveMatches.length === 1) {\n return source[caseInsensitiveMatches[0]!] as unknown;\n }\n }\n\n return undefined;\n}\n\nfunction getGeoArrowOrRowValue(options: {\n value: unknown;\n fieldName: string;\n vector: arrow.Vector;\n}) {\n const {value, fieldName, vector} = options;\n if (\n value &&\n typeof value === 'object' &&\n 'index' in value &&\n typeof (value as {index?: unknown}).index === 'number'\n ) {\n const objectInfo = value as {\n index: number;\n data?: {data?: arrow.Table | arrow.RecordBatch};\n };\n const batch = objectInfo.data?.data;\n const batchFieldName = batch\n ? resolveFieldName(batch, fieldName)\n : undefined;\n\n if (batch && batchFieldName) {\n return batch.getChild(batchFieldName)?.get(objectInfo.index);\n }\n\n if (batch) {\n // Batch is present (GeoArrow path) but the field wasn't found in it.\n // The index is batch-local and cannot be safely used against the global\n // vector which spans all batches. Return undefined so the mapper\n // applies nullColor rather than reading the wrong row.\n return undefined;\n }\n\n // No batch context (e.g. GeoJSON binary path): the index is global,\n // so using the table-level vector is safe.\n return vector.get(objectInfo.index);\n }\n\n return getRowValue(value, fieldName);\n}\n\nfunction getColumnValues(vector: arrow.Vector) {\n return Array.from({length: vector.length}, (_, index) => vector.get(index));\n}\n\nfunction getColumn(table: arrow.Table, field: string) {\n const resolvedFieldName = resolveFieldName(table, field);\n if (!resolvedFieldName) {\n throw new Error(`Unknown colorScale field \"${field}\".`);\n }\n\n const vector = table.getChild(resolvedFieldName);\n if (!vector) {\n throw new Error(`Unable to read colorScale field \"${resolvedFieldName}\".`);\n }\n\n return {\n fieldName: resolvedFieldName,\n vector,\n };\n}\n\nconst MISSING_FIELD_COLOR: [number, number, number, number] = [255, 0, 0, 200];\n\nexport function compileColorScale(options: {\n table: arrow.Table;\n colorScale: ColorScaleConfig;\n}) {\n const {table, colorScale} = options;\n let column;\n try {\n column = getColumn(table, colorScale.field);\n } catch {\n console.warn(\n `[compileColorScale] Field \"${colorScale.field}\" not found in dataset. Color scale will use fallback color.`,\n );\n return () => MISSING_FIELD_COLOR;\n }\n const {fieldName, vector} = column;\n let mapper: ReturnType<typeof createColorScaleMapper>;\n try {\n mapper = createColorScaleMapper({\n colorScale,\n values: getColumnValues(vector),\n });\n } catch (err) {\n console.warn(\n `[compileColorScale] Failed to create color scale for field \"${colorScale.field}\":`,\n err,\n );\n return () => MISSING_FIELD_COLOR;\n }\n\n return (value: unknown) =>\n mapper(getGeoArrowOrRowValue({value, fieldName, vector}));\n}\n\nexport function buildColorScaleLegend(options: {\n table: arrow.Table;\n colorScale: ColorScaleConfig;\n title?: string;\n}): ResolvedColorLegend | null {\n const {table, colorScale} = options;\n let column;\n try {\n column = getColumn(table, colorScale.field);\n } catch {\n return null;\n }\n const {vector} = column;\n const values = getColumnValues(vector);\n\n if (\n colorScale.type !== 'categorical' &&\n values.every((value) => coerceFiniteNumber(value) === undefined)\n ) {\n return null;\n }\n\n return buildGenericColorScaleLegend({\n colorScale,\n values,\n title: options.title,\n });\n}\n"]}
1
+ {"version":3,"file":"compileColorScale.js","sourceRoot":"","sources":["../../src/json/compileColorScale.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n buildColorScaleLegend as buildGenericColorScaleLegend,\n coerceFiniteNumber,\n createColorScaleMapper,\n type ColorScaleConfig,\n type ResolvedColorLegend,\n} from '@sqlrooms/color-scales';\nimport type * as arrow from 'apache-arrow';\nimport type {DeckColorScaleConfig} from './colorScaleFunction';\n\nfunction resolveFieldName(\n schemaOwner: arrow.Table | arrow.RecordBatch,\n requestedField: string,\n) {\n const exactMatch = schemaOwner.schema.fields.find(\n (field) => field.name === requestedField,\n )?.name;\n if (exactMatch) {\n return exactMatch;\n }\n\n const caseInsensitiveMatches = schemaOwner.schema.fields\n .map((field) => field.name)\n .filter(\n (fieldName) => fieldName.toLowerCase() === requestedField.toLowerCase(),\n );\n\n if (caseInsensitiveMatches.length === 1) {\n return caseInsensitiveMatches[0]!;\n }\n\n return undefined;\n}\n\nfunction getRowValue(row: unknown, fieldName: string) {\n if (!row || typeof row !== 'object') {\n return undefined;\n }\n\n const object = row as Record<string, unknown>;\n const sources = [\n object,\n object.properties as Record<string, unknown> | undefined,\n ].filter((value): value is Record<string, unknown> =>\n Boolean(value && typeof value === 'object'),\n );\n\n for (const source of sources) {\n if (fieldName in source) {\n return source[fieldName];\n }\n\n const caseInsensitiveMatches = Object.keys(source).filter(\n (key) => key.toLowerCase() === fieldName.toLowerCase(),\n );\n if (caseInsensitiveMatches.length === 1) {\n return source[caseInsensitiveMatches[0]!] as unknown;\n }\n }\n\n return undefined;\n}\n\nfunction getGeoArrowOrRowValue(options: {\n value: unknown;\n fieldName: string;\n vector: arrow.Vector;\n}) {\n const {value, fieldName, vector} = options;\n if (\n value &&\n typeof value === 'object' &&\n 'index' in value &&\n typeof (value as {index?: unknown}).index === 'number'\n ) {\n const objectInfo = value as {\n index: number;\n data?: {data?: arrow.Table | arrow.RecordBatch};\n };\n const batch = objectInfo.data?.data;\n const batchFieldName = batch\n ? resolveFieldName(batch, fieldName)\n : undefined;\n\n if (batch && batchFieldName) {\n return batch.getChild(batchFieldName)?.get(objectInfo.index);\n }\n\n if (batch) {\n // Batch is present (GeoArrow path) but the field wasn't found in it.\n // The index is batch-local and cannot be safely used against the global\n // vector which spans all batches. Return undefined so the mapper\n // applies nullColor rather than reading the wrong row.\n return undefined;\n }\n\n // No batch context (e.g. GeoJSON binary path): the index is global,\n // so using the table-level vector is safe.\n return vector.get(objectInfo.index);\n }\n\n return getRowValue(value, fieldName);\n}\n\nfunction getColumnValues(vector: arrow.Vector) {\n return Array.from({length: vector.length}, (_, index) => vector.get(index));\n}\n\nfunction getColumn(table: arrow.Table, field: string) {\n const resolvedFieldName = resolveFieldName(table, field);\n if (!resolvedFieldName) {\n throw new Error(`Unknown colorScale field \"${field}\".`);\n }\n\n const vector = table.getChild(resolvedFieldName);\n if (!vector) {\n throw new Error(`Unable to read colorScale field \"${resolvedFieldName}\".`);\n }\n\n return {\n fieldName: resolvedFieldName,\n vector,\n };\n}\n\nconst MISSING_FIELD_COLOR: [number, number, number, number] = [255, 0, 0, 200];\n\nexport function compileColorScale(options: {\n table: arrow.Table;\n colorScale: DeckColorScaleConfig;\n}) {\n const {table, colorScale} = options;\n let column;\n try {\n column = getColumn(table, colorScale.field);\n } catch {\n console.warn(\n `[compileColorScale] Field \"${colorScale.field}\" not found in dataset. Color scale will use fallback color.`,\n );\n return () => MISSING_FIELD_COLOR;\n }\n const {fieldName, vector} = column;\n let mapper: ReturnType<typeof createColorScaleMapper>;\n try {\n mapper = createColorScaleMapper({\n colorScale,\n values: getColumnValues(vector),\n });\n } catch (err) {\n console.warn(\n `[compileColorScale] Failed to create color scale for field \"${colorScale.field}\":`,\n err,\n );\n return () => MISSING_FIELD_COLOR;\n }\n\n return (value: unknown) => {\n const color = mapper(getGeoArrowOrRowValue({value, fieldName, vector}));\n const rawOpacity = colorScale.opacity;\n const opacity =\n typeof rawOpacity === 'number' && Number.isFinite(rawOpacity)\n ? Math.max(0, Math.min(1, rawOpacity))\n : 1;\n if (opacity >= 1) return color;\n const rgba = color as [number, number, number, number?];\n return [\n rgba[0],\n rgba[1],\n rgba[2],\n Math.round(Math.max(0, Math.min(255, (rgba[3] ?? 255) * opacity))),\n ] as [number, number, number, number];\n };\n}\n\nexport function buildColorScaleLegend(options: {\n table: arrow.Table;\n colorScale: ColorScaleConfig;\n title?: string;\n}): ResolvedColorLegend | null {\n const {table, colorScale} = options;\n let column;\n try {\n column = getColumn(table, colorScale.field);\n } catch {\n return null;\n }\n const {vector} = column;\n const values = getColumnValues(vector);\n\n if (\n colorScale.type !== 'categorical' &&\n values.every((value) => coerceFiniteNumber(value) === undefined)\n ) {\n return null;\n }\n\n return buildGenericColorScaleLegend({\n colorScale,\n values,\n title: options.title,\n });\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"createDeckJsonConfiguration.d.ts","sourceRoot":"","sources":["../../src/json/createDeckJsonConfiguration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,iBAAiB,EAAC,MAAM,eAAe,CAAC;AAUhD,OAAO,KAAK,EAAoB,wBAAwB,EAAC,MAAM,UAAU,CAAC;AA8B1E,KAAK,kCAAkC,GAAG;IACxC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC;IACxD,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB,CAAC;AAoOF,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,kCAAkC,qBA+P5C"}
1
+ {"version":3,"file":"createDeckJsonConfiguration.d.ts","sourceRoot":"","sources":["../../src/json/createDeckJsonConfiguration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,iBAAiB,EAAC,MAAM,eAAe,CAAC;AAShD,OAAO,KAAK,EAAoB,wBAAwB,EAAC,MAAM,UAAU,CAAC;AAkC1E,KAAK,kCAAkC,GAAG;IACxC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC;IACxD,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB,CAAC;AAsVF,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,kCAAkC,qBAqO5C"}