@carto/api-client 0.5.0-alpha.13 → 0.5.0-alpha.15

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 (41) hide show
  1. package/CHANGELOG.md +30 -1
  2. package/build/api-client.cjs +9849 -2868
  3. package/build/api-client.cjs.map +1 -1
  4. package/build/api-client.d.cts +510 -171
  5. package/build/api-client.d.ts +510 -171
  6. package/build/api-client.js +9558 -2627
  7. package/build/api-client.js.map +1 -1
  8. package/build/worker.js +122 -469
  9. package/build/worker.js.map +1 -1
  10. package/package.json +36 -22
  11. package/src/api/query.ts +2 -1
  12. package/src/constants-internal.ts +10 -0
  13. package/src/constants.ts +5 -1
  14. package/src/fetch-map/basemap-styles.ts +159 -0
  15. package/src/fetch-map/basemap.ts +120 -0
  16. package/src/fetch-map/fetch-map.ts +331 -0
  17. package/src/fetch-map/index.ts +13 -0
  18. package/src/fetch-map/layer-map.ts +461 -0
  19. package/src/fetch-map/parse-map.ts +425 -0
  20. package/src/fetch-map/source.ts +233 -0
  21. package/src/fetch-map/types.ts +268 -0
  22. package/src/fetch-map/utils.ts +69 -0
  23. package/src/filters/tileFeatures.ts +26 -10
  24. package/src/filters/tileFeaturesRaster.ts +122 -0
  25. package/src/index.ts +1 -0
  26. package/src/models/model.ts +0 -7
  27. package/src/sources/base-source.ts +4 -2
  28. package/src/sources/h3-tileset-source.ts +1 -1
  29. package/src/sources/quadbin-tileset-source.ts +1 -1
  30. package/src/sources/raster-source.ts +18 -5
  31. package/src/sources/types.ts +14 -7
  32. package/src/sources/vector-tileset-source.ts +1 -1
  33. package/src/spatial-index.ts +3 -84
  34. package/src/types.ts +16 -2
  35. package/src/widget-sources/index.ts +1 -0
  36. package/src/widget-sources/types.ts +0 -2
  37. package/src/widget-sources/widget-raster-source.ts +14 -0
  38. package/src/widget-sources/widget-remote-source.ts +8 -76
  39. package/src/widget-sources/widget-source.ts +6 -24
  40. package/src/widget-sources/widget-tileset-source-impl.ts +13 -16
  41. package/src/widget-sources/widget-tileset-source.ts +20 -7
@@ -116,11 +116,6 @@ export type AggregationOptions = {
116
116
  * @default 6 for quadbin and 4 for h3 sources
117
117
  */
118
118
  aggregationResLevel?: number;
119
-
120
- /**
121
- * Original resolution of the spatial index data as stored in the DW
122
- */
123
- dataResolution?: number;
124
119
  };
125
120
 
126
121
  export type FilterOptions = {
@@ -364,8 +359,20 @@ export enum RasterBandColorinterp {
364
359
  Palette = 'palette',
365
360
  }
366
361
 
362
+ export type RasterBandType =
363
+ | 'uint8'
364
+ | 'int8'
365
+ | 'uint16'
366
+ | 'int16'
367
+ | 'uint32'
368
+ | 'int32'
369
+ | 'uint64'
370
+ | 'int64'
371
+ | 'float32'
372
+ | 'float64';
373
+
367
374
  export type RasterMetadataBand = {
368
- type: string;
375
+ type: RasterBandType;
369
376
  name: string;
370
377
  stats: RasterMetadataBandStats;
371
378
  /**
@@ -379,7 +386,7 @@ export type RasterMetadataBand = {
379
386
  /**
380
387
  * Default color mapping for unique values (or if coloprinterp is `palette`)
381
388
  */
382
- colortable?: Record<string, number[]>;
389
+ colortable?: Record<string, [number, number, number, number]>;
383
390
 
384
391
  /**
385
392
  * No value representation.
@@ -2,13 +2,13 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
+ import {baseSource} from './base-source.js';
5
6
  import {DEFAULT_GEO_COLUMN} from '../constants-internal.js';
6
7
  import {getTileFormat} from '../utils/getTileFormat.js';
7
8
  import {
8
9
  WidgetTilesetSource,
9
10
  WidgetTilesetSourceResult,
10
11
  } from '../widget-sources/index.js';
11
- import {baseSource} from './base-source.js';
12
12
  import type {
13
13
  SourceOptions,
14
14
  TilesetSourceOptions,
@@ -1,88 +1,6 @@
1
- import {
2
- DEFAULT_AGGREGATION_RES_LEVEL_H3,
3
- DEFAULT_AGGREGATION_RES_LEVEL_QUADBIN,
4
- } from './constants-internal.js';
5
- import type {ModelSource} from './models/model.js';
6
- import type {AggregationOptions} from './sources/types.js';
7
- import type {ViewState} from './widget-sources/index.js';
8
-
1
+ // Default tile display size in deck.gl, in viewport pixels. May differ
2
+ // from size or resolution assumed when generating the tile data,
9
3
  const DEFAULT_TILE_SIZE = 512;
10
- const QUADBIN_ZOOM_MAX_OFFSET = 4;
11
-
12
- export function getSpatialFiltersResolution(
13
- source: Partial<ModelSource & AggregationOptions>,
14
- viewState: ViewState
15
- ): number | undefined {
16
- const dataResolution = source.dataResolution ?? Number.MAX_VALUE;
17
-
18
- const aggregationResLevel =
19
- source.aggregationResLevel ??
20
- (source.spatialDataType === 'h3'
21
- ? DEFAULT_AGGREGATION_RES_LEVEL_H3
22
- : DEFAULT_AGGREGATION_RES_LEVEL_QUADBIN);
23
-
24
- const aggregationResLevelOffset = Math.max(
25
- 0,
26
- Math.floor(aggregationResLevel)
27
- );
28
-
29
- const currentZoomInt = Math.ceil(viewState.zoom);
30
- if (source.spatialDataType === 'h3') {
31
- const tileSize = DEFAULT_TILE_SIZE;
32
- const maxResolutionForZoom =
33
- maxH3SpatialFiltersResolutions.find(
34
- ([zoom]) => zoom === currentZoomInt
35
- )?.[1] ?? Math.max(0, currentZoomInt - 3);
36
-
37
- const maxSpatialFiltersResolution = maxResolutionForZoom
38
- ? Math.min(dataResolution, maxResolutionForZoom)
39
- : dataResolution;
40
-
41
- const hexagonResolution =
42
- _getHexagonResolution(viewState, tileSize) + aggregationResLevelOffset;
43
-
44
- return Math.min(hexagonResolution, maxSpatialFiltersResolution);
45
- }
46
-
47
- if (source.spatialDataType === 'quadbin') {
48
- const maxResolutionForZoom = currentZoomInt + QUADBIN_ZOOM_MAX_OFFSET;
49
- const maxSpatialFiltersResolution = Math.min(
50
- dataResolution,
51
- maxResolutionForZoom
52
- );
53
-
54
- const quadsResolution =
55
- Math.floor(viewState.zoom) + aggregationResLevelOffset;
56
- return Math.min(quadsResolution, maxSpatialFiltersResolution);
57
- }
58
-
59
- return undefined;
60
- }
61
-
62
- const maxH3SpatialFiltersResolutions = [
63
- [20, 14],
64
- [19, 13],
65
- [18, 12],
66
- [17, 11],
67
- [16, 10],
68
- [15, 9],
69
- [14, 8],
70
- [13, 7],
71
- [12, 7],
72
- [11, 7],
73
- [10, 6],
74
- [9, 6],
75
- [8, 5],
76
- [7, 4],
77
- [6, 4],
78
- [5, 3],
79
- [4, 2],
80
- [3, 1],
81
- [2, 1],
82
- [1, 0],
83
- ];
84
-
85
- // stolen from https://github.com/visgl/deck.gl/blob/master/modules/carto/src/layers/h3-tileset-2d.ts
86
4
 
87
5
  // Relative scale factor (0 = no biasing, 2 = a few hexagons cover view)
88
6
  const BIAS = 2;
@@ -92,6 +10,7 @@ const BIAS = 2;
92
10
  * a H3 resolution such that the screen space size of the hexagons is
93
11
  * "similar" to the given tileSize on screen. Intended for use with deck.gl.
94
12
  * @internal
13
+ * @privateRemarks Source: https://github.com/visgl/deck.gl/blob/master/modules/carto/src/layers/h3-tileset-2d.ts
95
14
  */
96
15
  export function _getHexagonResolution(
97
16
  viewport: {zoom: number; latitude: number},
package/src/types.ts CHANGED
@@ -12,6 +12,16 @@ export type Format = 'json' | 'geojson' | 'tilejson';
12
12
  /** @privateRemarks Source: @carto/constants, @deck.gl/carto */
13
13
  export type MapType = 'boundary' | 'query' | 'table' | 'tileset' | 'raster';
14
14
 
15
+ /** @privateRemarks Source: cloud-native */
16
+ export type ProviderType =
17
+ | 'bigquery'
18
+ | 'postgres'
19
+ | 'snowflake'
20
+ | 'redshift'
21
+ | 'databricks'
22
+ | 'carto'
23
+ | 'carto_dw';
24
+
15
25
  /**
16
26
  * Alias for GeoJSON 'BBox' type, semantically representing a viewport.
17
27
  * Order of values is "west", "south", "east", "north".
@@ -28,8 +38,6 @@ export type Viewport = [number, number, number, number];
28
38
  export type Tile = {
29
39
  index: {x: number; y: number; z: number};
30
40
  id: string;
31
- content: unknown;
32
- zoom: number;
33
41
  bbox: {west: number; east: number; north: number; south: number};
34
42
  isVisible: boolean;
35
43
  data?: BinaryFeatureCollection;
@@ -40,6 +48,12 @@ export type SpatialIndexTile = Tile & {
40
48
  data?: (Feature & {id: bigint})[];
41
49
  };
42
50
 
51
+ export type RasterTile = Tile & {
52
+ id: string;
53
+ index: {q: bigint; i: string};
54
+ data?: Raster;
55
+ };
56
+
43
57
  /** @privateRemarks Source: @deck.gl/carto */
44
58
  export type Raster = {
45
59
  blockSize: number;
@@ -1,5 +1,6 @@
1
1
  export * from './widget-source.js';
2
2
  export * from './widget-query-source.js';
3
+ export * from './widget-raster-source.js';
3
4
  export * from './widget-remote-source.js';
4
5
  export * from './widget-table-source.js';
5
6
  export * from './widget-tileset-source.js';
@@ -22,8 +22,6 @@ interface BaseRequestOptions {
22
22
  signal?: AbortSignal;
23
23
  spatialFilter?: SpatialFilter;
24
24
  spatialFiltersMode?: SpatialFilterPolyfillMode;
25
- /** Required for table- and query-based spatial index sources (H3, Quadbin). */
26
- spatialIndexReferenceViewState?: ViewState;
27
25
  /** Overrides source filters, if any. */
28
26
  filters?: Filters;
29
27
  filterOwner?: string;
@@ -0,0 +1,14 @@
1
+ import {RasterMetadata} from '../sources/index.js';
2
+ import {
3
+ WidgetTilesetSource,
4
+ WidgetTilesetSourceProps,
5
+ } from './widget-tileset-source.js';
6
+
7
+ export type WidgetRasterSourceProps = WidgetTilesetSourceProps & {
8
+ rasterMetadata: RasterMetadata;
9
+ spatialDataType: 'quadbin';
10
+ };
11
+
12
+ export type WidgetRasterSourceResult = {widgetSource: WidgetRasterSource};
13
+
14
+ export class WidgetRasterSource extends WidgetTilesetSource<WidgetRasterSourceProps> {}
@@ -22,7 +22,6 @@ import {DEFAULT_TILE_RESOLUTION} from '../constants-internal.js';
22
22
  import {WidgetSource, WidgetSourceProps} from './widget-source.js';
23
23
  import {Filters} from '../types.js';
24
24
  import {ApiVersion} from '../constants.js';
25
- import {AggregationOptions} from '../sources/types.js';
26
25
 
27
26
  export type WidgetRemoteSourceProps = WidgetSourceProps;
28
27
 
@@ -60,7 +59,6 @@ export abstract class WidgetRemoteSource<
60
59
  filtersLogicalOperator: props.filtersLogicalOperator,
61
60
  spatialDataType: props.spatialDataType,
62
61
  spatialDataColumn: props.spatialDataColumn,
63
- dataResolution: (props as Partial<AggregationOptions>).dataResolution,
64
62
  };
65
63
  }
66
64
 
@@ -73,24 +71,16 @@ export abstract class WidgetRemoteSource<
73
71
  filterOwner,
74
72
  spatialFilter,
75
73
  spatialFiltersMode,
76
- spatialIndexReferenceViewState,
77
74
  ...params
78
75
  } = options;
79
76
  const {column, operation, operationColumn} = params;
80
- const source = this.getModelSource(filters, filterOwner);
81
- const spatialFiltersResolution = this._getSpatialFiltersResolution(
82
- source,
83
- spatialFilter,
84
- spatialIndexReferenceViewState
85
- );
86
77
 
87
78
  type CategoriesModelResponse = {rows: {name: string; value: number}[]};
88
79
 
89
80
  return executeModel({
90
81
  model: 'category',
91
82
  source: {
92
- ...source,
93
- spatialFiltersResolution,
83
+ ...this.getModelSource(filters, filterOwner),
94
84
  spatialFiltersMode,
95
85
  spatialFilter,
96
86
  },
@@ -112,24 +102,16 @@ export abstract class WidgetRemoteSource<
112
102
  filterOwner,
113
103
  spatialFilter,
114
104
  spatialFiltersMode,
115
- spatialIndexReferenceViewState,
116
105
  ...params
117
106
  } = options;
118
107
  const {columns, dataType, featureIds, z, limit, tileResolution} = params;
119
- const source = this.getModelSource(filters, filterOwner);
120
- const spatialFiltersResolution = this._getSpatialFiltersResolution(
121
- source,
122
- spatialFilter,
123
- spatialIndexReferenceViewState
124
- );
125
108
 
126
109
  type FeaturesModelResponse = {rows: Record<string, unknown>[]};
127
110
 
128
111
  return executeModel({
129
112
  model: 'pick',
130
113
  source: {
131
- ...source,
132
- spatialFiltersResolution,
114
+ ...this.getModelSource(filters, filterOwner),
133
115
  spatialFiltersMode,
134
116
  spatialFilter,
135
117
  },
@@ -153,25 +135,17 @@ export abstract class WidgetRemoteSource<
153
135
  filterOwner,
154
136
  spatialFilter,
155
137
  spatialFiltersMode,
156
- spatialIndexReferenceViewState,
157
138
  operationExp,
158
139
  ...params
159
140
  } = options;
160
141
  const {column, operation} = params;
161
- const source = this.getModelSource(filters, filterOwner);
162
- const spatialFiltersResolution = this._getSpatialFiltersResolution(
163
- source,
164
- spatialFilter,
165
- spatialIndexReferenceViewState
166
- );
167
142
 
168
143
  type FormulaModelResponse = {rows: {value: number}[]};
169
144
 
170
145
  return executeModel({
171
146
  model: 'formula',
172
147
  source: {
173
- ...source,
174
- spatialFiltersResolution,
148
+ ...this.getModelSource(filters, filterOwner),
175
149
  spatialFiltersMode,
176
150
  spatialFilter,
177
151
  },
@@ -193,24 +167,16 @@ export abstract class WidgetRemoteSource<
193
167
  filterOwner,
194
168
  spatialFilter,
195
169
  spatialFiltersMode,
196
- spatialIndexReferenceViewState,
197
170
  ...params
198
171
  } = options;
199
172
  const {column, operation, ticks} = params;
200
- const source = this.getModelSource(filters, filterOwner);
201
- const spatialFiltersResolution = this._getSpatialFiltersResolution(
202
- source,
203
- spatialFilter,
204
- spatialIndexReferenceViewState
205
- );
206
173
 
207
174
  type HistogramModelResponse = {rows: {tick: number; value: number}[]};
208
175
 
209
176
  const data = await executeModel({
210
177
  model: 'histogram',
211
178
  source: {
212
- ...source,
213
- spatialFiltersResolution,
179
+ ...this.getModelSource(filters, filterOwner),
214
180
  spatialFiltersMode,
215
181
  spatialFilter,
216
182
  },
@@ -238,24 +204,16 @@ export abstract class WidgetRemoteSource<
238
204
  filterOwner,
239
205
  spatialFilter,
240
206
  spatialFiltersMode,
241
- spatialIndexReferenceViewState,
242
207
  ...params
243
208
  } = options;
244
209
  const {column} = params;
245
- const source = this.getModelSource(filters, filterOwner);
246
- const spatialFiltersResolution = this._getSpatialFiltersResolution(
247
- source,
248
- spatialFilter,
249
- spatialIndexReferenceViewState
250
- );
251
210
 
252
211
  type RangeModelResponse = {rows: {min: number; max: number}[]};
253
212
 
254
213
  return executeModel({
255
214
  model: 'range',
256
215
  source: {
257
- ...source,
258
- spatialFiltersResolution,
216
+ ...this.getModelSource(filters, filterOwner),
259
217
  spatialFiltersMode,
260
218
  spatialFilter,
261
219
  },
@@ -271,19 +229,11 @@ export abstract class WidgetRemoteSource<
271
229
  filterOwner,
272
230
  spatialFilter,
273
231
  spatialFiltersMode,
274
- spatialIndexReferenceViewState,
275
232
  ...params
276
233
  } = options;
277
234
  const {xAxisColumn, xAxisJoinOperation, yAxisColumn, yAxisJoinOperation} =
278
235
  params;
279
236
 
280
- const source = this.getModelSource(filters, filterOwner);
281
- const spatialFiltersResolution = this._getSpatialFiltersResolution(
282
- source,
283
- spatialFilter,
284
- spatialIndexReferenceViewState
285
- );
286
-
287
237
  // Make sure this is sync with the same constant in cloud-native/maps-api
288
238
  const HARD_LIMIT = 500;
289
239
 
@@ -292,8 +242,7 @@ export abstract class WidgetRemoteSource<
292
242
  return executeModel({
293
243
  model: 'scatterplot',
294
244
  source: {
295
- ...source,
296
- spatialFiltersResolution,
245
+ ...this.getModelSource(filters, filterOwner),
297
246
  spatialFiltersMode,
298
247
  spatialFilter,
299
248
  },
@@ -317,16 +266,9 @@ export abstract class WidgetRemoteSource<
317
266
  filterOwner,
318
267
  spatialFilter,
319
268
  spatialFiltersMode,
320
- spatialIndexReferenceViewState,
321
269
  ...params
322
270
  } = options;
323
271
  const {columns, sortBy, sortDirection, offset = 0, limit = 10} = params;
324
- const source = this.getModelSource(filters, filterOwner);
325
- const spatialFiltersResolution = this._getSpatialFiltersResolution(
326
- source,
327
- spatialFilter,
328
- spatialIndexReferenceViewState
329
- );
330
272
 
331
273
  type TableModelResponse = {
332
274
  rows: Record<string, number | string>[];
@@ -336,8 +278,7 @@ export abstract class WidgetRemoteSource<
336
278
  return executeModel({
337
279
  model: 'table',
338
280
  source: {
339
- ...source,
340
- spatialFiltersResolution,
281
+ ...this.getModelSource(filters, filterOwner),
341
282
  spatialFiltersMode,
342
283
  spatialFilter,
343
284
  },
@@ -365,7 +306,6 @@ export abstract class WidgetRemoteSource<
365
306
  filterOwner,
366
307
  spatialFilter,
367
308
  spatialFiltersMode,
368
- spatialIndexReferenceViewState,
369
309
  ...params
370
310
  } = options;
371
311
  const {
@@ -380,13 +320,6 @@ export abstract class WidgetRemoteSource<
380
320
  splitByCategoryValues,
381
321
  } = params;
382
322
 
383
- const source = this.getModelSource(filters, filterOwner);
384
- const spatialFiltersResolution = this._getSpatialFiltersResolution(
385
- source,
386
- spatialFilter,
387
- spatialIndexReferenceViewState
388
- );
389
-
390
323
  type TimeSeriesModelResponse = {
391
324
  rows: {name: string; value: number}[];
392
325
  metadata: {categories: string[]};
@@ -395,8 +328,7 @@ export abstract class WidgetRemoteSource<
395
328
  return executeModel({
396
329
  model: 'timeseries',
397
330
  source: {
398
- ...source,
399
- spatialFiltersResolution,
331
+ ...this.getModelSource(filters, filterOwner),
400
332
  spatialFiltersMode,
401
333
  spatialFilter,
402
334
  },
@@ -15,14 +15,11 @@ import {
15
15
  TableResponse,
16
16
  TimeSeriesRequestOptions,
17
17
  TimeSeriesResponse,
18
- ViewState,
19
18
  } from './types.js';
20
- import {FilterLogicalOperator, Filter, SpatialFilter} from '../types.js';
19
+ import {FilterLogicalOperator, Filter} from '../types.js';
21
20
  import {getClient} from '../client.js';
22
- import {ModelSource} from '../models/model.js';
23
21
  import {SourceOptions} from '../sources/index.js';
24
22
  import {ApiVersion, DEFAULT_API_BASE_URL} from '../constants.js';
25
- import {getSpatialFiltersResolution} from '../spatial-index.js';
26
23
 
27
24
  export interface WidgetSourceProps extends Omit<SourceOptions, 'filters'> {
28
25
  apiVersion?: ApiVersion;
@@ -49,7 +46,11 @@ export abstract class WidgetSource<
49
46
  };
50
47
 
51
48
  constructor(props: Props) {
52
- this.props = {...WidgetSource.defaultProps, ...props};
49
+ this.props = {
50
+ ...WidgetSource.defaultProps,
51
+ clientId: getClient(), // Refresh clientId, default may have changed.
52
+ ...props,
53
+ };
53
54
  }
54
55
 
55
56
  /**
@@ -63,25 +64,6 @@ export abstract class WidgetSource<
63
64
  // no-op in most cases, but required for worker sources.
64
65
  }
65
66
 
66
- protected _getSpatialFiltersResolution(
67
- source: Omit<ModelSource, 'type' | 'data'>,
68
- spatialFilter?: SpatialFilter,
69
- referenceViewState?: ViewState
70
- ): number | undefined {
71
- // spatialFiltersResolution applies only to spatial index sources.
72
- if (!spatialFilter || source.spatialDataType === 'geo') {
73
- return;
74
- }
75
-
76
- if (!referenceViewState) {
77
- throw new Error(
78
- 'Missing required option, "spatialIndexReferenceViewState".'
79
- );
80
- }
81
-
82
- return getSpatialFiltersResolution(source, referenceViewState);
83
- }
84
-
85
67
  /**
86
68
  * Returns a list of labeled datapoints for categorical data. Suitable for
87
69
  * charts including grouped bar charts, pie charts, and tree charts.
@@ -84,13 +84,10 @@ export class WidgetTilesetSourceImpl extends WidgetSource<WidgetTilesetSourcePro
84
84
  }
85
85
 
86
86
  this._features = tileFeatures({
87
- tiles: this._tiles,
88
- tileFormat: this.props.tileFormat,
87
+ ...this.props,
89
88
  ...this._tileFeatureExtractOptions,
90
-
89
+ tiles: this._tiles,
91
90
  spatialFilter,
92
- spatialDataColumn: this.props.spatialDataColumn,
93
- spatialDataType: this.props.spatialDataType,
94
91
  });
95
92
 
96
93
  prevInputs.spatialFilter = spatialFilter;
@@ -128,15 +125,6 @@ export class WidgetTilesetSourceImpl extends WidgetSource<WidgetTilesetSourcePro
128
125
  filterOwner,
129
126
  spatialFilter,
130
127
  }: FormulaRequestOptions): Promise<FormulaResponse> {
131
- if (operation === 'custom') {
132
- throw new Error('Custom aggregation not supported for tilesets');
133
- }
134
-
135
- // Column is required except when operation is 'count'.
136
- if ((column && column !== '*') || operation !== 'count') {
137
- assertColumn(this._features, column);
138
- }
139
-
140
128
  const filteredFeatures = this._getFilteredFeatures(
141
129
  spatialFilter,
142
130
  filters,
@@ -147,6 +135,15 @@ export class WidgetTilesetSourceImpl extends WidgetSource<WidgetTilesetSourcePro
147
135
  return {value: null};
148
136
  }
149
137
 
138
+ if (operation === 'custom') {
139
+ throw new Error('Custom aggregation not supported for tilesets');
140
+ }
141
+
142
+ // Column is required except when operation is 'count'.
143
+ if ((column && column !== '*') || operation !== 'count') {
144
+ assertColumn(this._features, column);
145
+ }
146
+
150
147
  const targetOperation = aggregationFunctions[operation];
151
148
  return {
152
149
  value: targetOperation(filteredFeatures, column, joinOperation),
@@ -347,8 +344,6 @@ export class WidgetTilesetSourceImpl extends WidgetSource<WidgetTilesetSourcePro
347
344
  filterOwner,
348
345
  spatialFilter,
349
346
  }: RangeRequestOptions): Promise<RangeResponse> {
350
- assertColumn(this._features, column);
351
-
352
347
  const filteredFeatures = this._getFilteredFeatures(
353
348
  spatialFilter,
354
349
  filters,
@@ -361,6 +356,8 @@ export class WidgetTilesetSourceImpl extends WidgetSource<WidgetTilesetSourcePro
361
356
  return null;
362
357
  }
363
358
 
359
+ assertColumn(this._features, column);
360
+
364
361
  return {
365
362
  min: aggregationFunctions.min(filteredFeatures, column),
366
363
  max: aggregationFunctions.max(filteredFeatures, column),
@@ -55,14 +55,16 @@ export type WidgetTilesetSourceResult = {widgetSource: WidgetTilesetSource};
55
55
  * const { widgetSource } = await data;
56
56
  * ```
57
57
  */
58
- export class WidgetTilesetSource extends WidgetSource<WidgetTilesetSourceProps> {
58
+ export class WidgetTilesetSource<
59
+ Props extends WidgetTilesetSourceProps = WidgetTilesetSourceProps,
60
+ > extends WidgetSource<Props> {
59
61
  protected _localImpl: WidgetTilesetSourceImpl | null = null;
60
62
 
61
63
  protected _workerImpl: Worker | null = null;
62
64
  protected _workerEnabled: boolean;
63
65
  protected _workerNextRequestId = 1;
64
66
 
65
- constructor(props: WidgetTilesetSourceProps) {
67
+ constructor(props: Props) {
66
68
  super(props);
67
69
 
68
70
  this._workerEnabled =
@@ -198,11 +200,22 @@ export class WidgetTilesetSource extends WidgetSource<WidgetTilesetSourceProps>
198
200
 
199
201
  const worker = this._getWorker();
200
202
 
201
- tiles = (tiles as Tile[]).map(({id, bbox, data}) => ({
202
- id,
203
- bbox,
204
- data,
205
- }));
203
+ // We cannot pass an instance of Tile2DHeader to a Web Worker, and must
204
+ // extract properties required for widget calculations. Note that the
205
+ // `tile: Tile = {...}` assignment is structured so TS will warn if any
206
+ // types required by the internal 'Tile' type are missing.
207
+ tiles = (tiles as Tile[]).map(
208
+ ({id, index, bbox, isVisible, data}: Tile) => {
209
+ const tile: Tile = {
210
+ id,
211
+ index,
212
+ isVisible,
213
+ data,
214
+ bbox,
215
+ };
216
+ return tile;
217
+ }
218
+ );
206
219
 
207
220
  worker.postMessage({
208
221
  method: Method.LOAD_TILES,