@carto/api-client 0.5.0-alpha.3 → 0.5.0-alpha.4

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 (106) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/build/api/carto-api-error.d.ts +1 -1
  3. package/build/api/query.d.ts +1 -1
  4. package/build/api/request-with-parameters.d.ts +2 -2
  5. package/build/api-client.cjs +2324 -2188
  6. package/build/api-client.cjs.map +1 -1
  7. package/build/api-client.modern.js +2196 -2055
  8. package/build/api-client.modern.js.map +1 -1
  9. package/build/client.d.ts +2 -2
  10. package/build/constants-internal.d.ts +5 -5
  11. package/build/constants.d.ts +6 -6
  12. package/build/deck/get-data-filter-extension-props.d.ts +18 -0
  13. package/build/deck/index.d.ts +1 -0
  14. package/build/filters/Filter.d.ts +15 -3
  15. package/build/filters/FilterTypes.d.ts +1 -1
  16. package/build/filters/geosjonFeatures.d.ts +2 -2
  17. package/build/filters/tileFeatures.d.ts +8 -8
  18. package/build/filters/tileFeaturesRaster.d.ts +3 -3
  19. package/build/filters.d.ts +2 -2
  20. package/build/geo.d.ts +1 -1
  21. package/build/index.d.ts +1 -0
  22. package/build/models/common.d.ts +4 -3
  23. package/build/models/model.d.ts +2 -2
  24. package/build/operations/aggregation.d.ts +5 -5
  25. package/build/operations/applySorting.d.ts +3 -3
  26. package/build/operations/groupBy.d.ts +4 -4
  27. package/build/operations/groupByDate.d.ts +1 -1
  28. package/build/operations/histogram.d.ts +3 -3
  29. package/build/operations/scatterPlot.d.ts +3 -3
  30. package/build/sources/base-source.d.ts +2 -2
  31. package/build/sources/boundary-query-source.d.ts +1 -1
  32. package/build/sources/boundary-table-source.d.ts +1 -1
  33. package/build/sources/h3-query-source.d.ts +2 -2
  34. package/build/sources/h3-table-source.d.ts +2 -2
  35. package/build/sources/h3-tileset-source.d.ts +2 -2
  36. package/build/sources/index.d.ts +26 -26
  37. package/build/sources/quadbin-query-source.d.ts +2 -2
  38. package/build/sources/quadbin-table-source.d.ts +2 -2
  39. package/build/sources/quadbin-tileset-source.d.ts +2 -2
  40. package/build/sources/raster-source.d.ts +2 -2
  41. package/build/sources/types.d.ts +3 -3
  42. package/build/sources/vector-query-source.d.ts +1 -1
  43. package/build/sources/vector-table-source.d.ts +1 -1
  44. package/build/sources/vector-tileset-source.d.ts +2 -2
  45. package/build/spatial-index.d.ts +3 -3
  46. package/build/types-internal.d.ts +5 -5
  47. package/build/types.d.ts +15 -15
  48. package/build/utils/makeIntervalComplete.d.ts +1 -1
  49. package/build/utils.d.ts +3 -3
  50. package/build/widget-sources/types.d.ts +4 -2
  51. package/build/widget-sources/widget-query-source.d.ts +2 -1
  52. package/build/widget-sources/widget-remote-source.d.ts +3 -0
  53. package/build/widget-sources/widget-source.d.ts +3 -3
  54. package/build/widget-sources/widget-table-source.d.ts +2 -1
  55. package/build/widget-sources/widget-tileset-source.d.ts +22 -24
  56. package/package.json +36 -30
  57. package/src/api/carto-api-error.ts +1 -1
  58. package/src/api/query.ts +5 -5
  59. package/src/api/request-with-parameters.ts +6 -6
  60. package/src/client.ts +3 -3
  61. package/src/constants-internal.ts +5 -5
  62. package/src/constants.ts +6 -6
  63. package/src/deck/get-data-filter-extension-props.ts +146 -0
  64. package/src/deck/index.ts +1 -0
  65. package/src/filters/Filter.ts +18 -8
  66. package/src/filters/FilterTypes.ts +2 -2
  67. package/src/filters/geosjonFeatures.ts +2 -2
  68. package/src/filters/tileFeatures.ts +13 -19
  69. package/src/filters/tileFeaturesRaster.ts +7 -7
  70. package/src/filters.ts +4 -4
  71. package/src/geo.ts +12 -14
  72. package/src/index.ts +1 -0
  73. package/src/models/common.ts +9 -7
  74. package/src/models/model.ts +3 -4
  75. package/src/operations/aggregation.ts +5 -5
  76. package/src/operations/applySorting.ts +4 -4
  77. package/src/operations/groupBy.ts +4 -4
  78. package/src/operations/groupByDate.ts +1 -1
  79. package/src/operations/histogram.ts +4 -4
  80. package/src/operations/scatterPlot.ts +4 -4
  81. package/src/sources/base-source.ts +8 -8
  82. package/src/sources/boundary-query-source.ts +2 -2
  83. package/src/sources/boundary-table-source.ts +2 -2
  84. package/src/sources/h3-query-source.ts +7 -5
  85. package/src/sources/h3-table-source.ts +7 -5
  86. package/src/sources/h3-tileset-source.ts +4 -4
  87. package/src/sources/index.ts +26 -26
  88. package/src/sources/quadbin-query-source.ts +7 -5
  89. package/src/sources/quadbin-table-source.ts +7 -5
  90. package/src/sources/quadbin-tileset-source.ts +4 -4
  91. package/src/sources/raster-source.ts +8 -4
  92. package/src/sources/types.ts +3 -3
  93. package/src/sources/vector-query-source.ts +2 -3
  94. package/src/sources/vector-table-source.ts +2 -3
  95. package/src/sources/vector-tileset-source.ts +5 -5
  96. package/src/spatial-index.ts +4 -4
  97. package/src/types-internal.ts +5 -5
  98. package/src/types.ts +15 -15
  99. package/src/utils/makeIntervalComplete.ts +1 -1
  100. package/src/utils.ts +3 -3
  101. package/src/widget-sources/types.ts +5 -3
  102. package/src/widget-sources/widget-query-source.ts +6 -2
  103. package/src/widget-sources/widget-remote-source.ts +31 -16
  104. package/src/widget-sources/widget-source.ts +13 -4
  105. package/src/widget-sources/widget-table-source.ts +6 -2
  106. package/src/widget-sources/widget-tileset-source.ts +132 -81
@@ -8,6 +8,7 @@ import {
8
8
  WidgetRemoteSourceProps,
9
9
  } from './widget-remote-source.js';
10
10
  import {ModelSource} from '../models/model.js';
11
+ import {Filters} from '../types.js';
11
12
 
12
13
  type LayerQuerySourceOptions =
13
14
  | Omit<VectorQuerySourceOptions, 'filters'>
@@ -41,9 +42,12 @@ export type WidgetQuerySourceResult = {widgetSource: WidgetQuerySource};
41
42
  export class WidgetQuerySource extends WidgetRemoteSource<
42
43
  LayerQuerySourceOptions & WidgetRemoteSourceProps
43
44
  > {
44
- protected override getModelSource(owner: string): ModelSource {
45
+ protected override getModelSource(
46
+ filters: Filters | undefined,
47
+ filterOwner?: string
48
+ ): ModelSource {
45
49
  return {
46
- ...super._getModelSource(owner),
50
+ ...super._getModelSource(filters, filterOwner),
47
51
  type: 'query',
48
52
  data: this.props.sqlQuery,
49
53
  queryParameters: this.props.queryParameters,
@@ -31,10 +31,18 @@ export type WidgetRemoteSourceProps = WidgetSourceProps;
31
31
  export abstract class WidgetRemoteSource<
32
32
  Props extends WidgetRemoteSourceProps,
33
33
  > extends WidgetSource<Props> {
34
+ protected _headers: Record<string, string> = {};
35
+
36
+ /** Assigns HTTP headers to be included on API requests from this source. */
37
+ setRequestHeaders(headers: Record<string, string>): void {
38
+ this._headers = headers;
39
+ }
40
+
34
41
  async getCategories(
35
42
  options: CategoryRequestOptions
36
43
  ): Promise<CategoryResponse> {
37
44
  const {
45
+ filters = this.props.filters,
38
46
  filterOwner,
39
47
  spatialFilter,
40
48
  spatialFiltersMode,
@@ -43,7 +51,7 @@ export abstract class WidgetRemoteSource<
43
51
  ...params
44
52
  } = options;
45
53
  const {column, operation, operationColumn} = params;
46
- const source = this.getModelSource(filterOwner);
54
+ const source = this.getModelSource(filters, filterOwner);
47
55
  const spatialFiltersResolution = this._getSpatialFiltersResolution(
48
56
  source,
49
57
  spatialFilter,
@@ -65,7 +73,7 @@ export abstract class WidgetRemoteSource<
65
73
  operation,
66
74
  operationColumn: operationColumn || column,
67
75
  },
68
- opts: {abortController},
76
+ opts: {abortController, headers: this._headers},
69
77
  }).then((res: CategoriesModelResponse) => normalizeObjectKeys(res.rows));
70
78
  }
71
79
 
@@ -73,6 +81,7 @@ export abstract class WidgetRemoteSource<
73
81
  options: FeaturesRequestOptions
74
82
  ): Promise<FeaturesResponse> {
75
83
  const {
84
+ filters = this.props.filters,
76
85
  filterOwner,
77
86
  spatialFilter,
78
87
  spatialFiltersMode,
@@ -81,7 +90,7 @@ export abstract class WidgetRemoteSource<
81
90
  ...params
82
91
  } = options;
83
92
  const {columns, dataType, featureIds, z, limit, tileResolution} = params;
84
- const source = this.getModelSource(filterOwner);
93
+ const source = this.getModelSource(filters, filterOwner);
85
94
  const spatialFiltersResolution = this._getSpatialFiltersResolution(
86
95
  source,
87
96
  spatialFilter,
@@ -106,13 +115,14 @@ export abstract class WidgetRemoteSource<
106
115
  limit: limit || 1000,
107
116
  tileResolution: tileResolution || DEFAULT_TILE_RESOLUTION,
108
117
  },
109
- opts: {abortController},
118
+ opts: {abortController, headers: this._headers},
110
119
  // Avoid `normalizeObjectKeys()`, which changes column names.
111
120
  }).then(({rows}: FeaturesModelResponse) => ({rows}));
112
121
  }
113
122
 
114
123
  async getFormula(options: FormulaRequestOptions): Promise<FormulaResponse> {
115
124
  const {
125
+ filters = this.props.filters,
116
126
  filterOwner,
117
127
  spatialFilter,
118
128
  spatialFiltersMode,
@@ -122,7 +132,7 @@ export abstract class WidgetRemoteSource<
122
132
  ...params
123
133
  } = options;
124
134
  const {column, operation} = params;
125
- const source = this.getModelSource(filterOwner);
135
+ const source = this.getModelSource(filters, filterOwner);
126
136
  const spatialFiltersResolution = this._getSpatialFiltersResolution(
127
137
  source,
128
138
  spatialFilter,
@@ -144,7 +154,7 @@ export abstract class WidgetRemoteSource<
144
154
  operation: operation ?? 'count',
145
155
  operationExp,
146
156
  },
147
- opts: {abortController},
157
+ opts: {abortController, headers: this._headers},
148
158
  }).then((res: FormulaModelResponse) => normalizeObjectKeys(res.rows[0]));
149
159
  }
150
160
 
@@ -152,6 +162,7 @@ export abstract class WidgetRemoteSource<
152
162
  options: HistogramRequestOptions
153
163
  ): Promise<HistogramResponse> {
154
164
  const {
165
+ filters = this.props.filters,
155
166
  filterOwner,
156
167
  spatialFilter,
157
168
  spatialFiltersMode,
@@ -160,7 +171,7 @@ export abstract class WidgetRemoteSource<
160
171
  ...params
161
172
  } = options;
162
173
  const {column, operation, ticks} = params;
163
- const source = this.getModelSource(filterOwner);
174
+ const source = this.getModelSource(filters, filterOwner);
164
175
  const spatialFiltersResolution = this._getSpatialFiltersResolution(
165
176
  source,
166
177
  spatialFilter,
@@ -178,7 +189,7 @@ export abstract class WidgetRemoteSource<
178
189
  spatialFilter,
179
190
  },
180
191
  params: {column, operation, ticks},
181
- opts: {abortController},
192
+ opts: {abortController, headers: this._headers},
182
193
  }).then((res: HistogramModelResponse) => normalizeObjectKeys(res.rows));
183
194
 
184
195
  if (data.length) {
@@ -196,6 +207,7 @@ export abstract class WidgetRemoteSource<
196
207
 
197
208
  async getRange(options: RangeRequestOptions): Promise<RangeResponse> {
198
209
  const {
210
+ filters = this.props.filters,
199
211
  filterOwner,
200
212
  spatialFilter,
201
213
  spatialFiltersMode,
@@ -204,7 +216,7 @@ export abstract class WidgetRemoteSource<
204
216
  ...params
205
217
  } = options;
206
218
  const {column} = params;
207
- const source = this.getModelSource(filterOwner);
219
+ const source = this.getModelSource(filters, filterOwner);
208
220
  const spatialFiltersResolution = this._getSpatialFiltersResolution(
209
221
  source,
210
222
  spatialFilter,
@@ -222,12 +234,13 @@ export abstract class WidgetRemoteSource<
222
234
  spatialFilter,
223
235
  },
224
236
  params: {column},
225
- opts: {abortController},
237
+ opts: {abortController, headers: this._headers},
226
238
  }).then((res: RangeModelResponse) => normalizeObjectKeys(res.rows[0]));
227
239
  }
228
240
 
229
241
  async getScatter(options: ScatterRequestOptions): Promise<ScatterResponse> {
230
242
  const {
243
+ filters = this.props.filters,
231
244
  filterOwner,
232
245
  spatialFilter,
233
246
  spatialFiltersMode,
@@ -238,7 +251,7 @@ export abstract class WidgetRemoteSource<
238
251
  const {xAxisColumn, xAxisJoinOperation, yAxisColumn, yAxisJoinOperation} =
239
252
  params;
240
253
 
241
- const source = this.getModelSource(filterOwner);
254
+ const source = this.getModelSource(filters, filterOwner);
242
255
  const spatialFiltersResolution = this._getSpatialFiltersResolution(
243
256
  source,
244
257
  spatialFilter,
@@ -265,7 +278,7 @@ export abstract class WidgetRemoteSource<
265
278
  yAxisJoinOperation,
266
279
  limit: HARD_LIMIT,
267
280
  },
268
- opts: {abortController},
281
+ opts: {abortController, headers: this._headers},
269
282
  })
270
283
  .then((res: ScatterModelResponse) => normalizeObjectKeys(res.rows))
271
284
  .then((res) => res.map(({x, y}: {x: number; y: number}) => [x, y]));
@@ -273,6 +286,7 @@ export abstract class WidgetRemoteSource<
273
286
 
274
287
  async getTable(options: TableRequestOptions): Promise<TableResponse> {
275
288
  const {
289
+ filters = this.props.filters,
276
290
  filterOwner,
277
291
  spatialFilter,
278
292
  spatialFiltersMode,
@@ -281,7 +295,7 @@ export abstract class WidgetRemoteSource<
281
295
  ...params
282
296
  } = options;
283
297
  const {columns, sortBy, sortDirection, offset = 0, limit = 10} = params;
284
- const source = this.getModelSource(filterOwner);
298
+ const source = this.getModelSource(filters, filterOwner);
285
299
  const spatialFiltersResolution = this._getSpatialFiltersResolution(
286
300
  source,
287
301
  spatialFilter,
@@ -308,7 +322,7 @@ export abstract class WidgetRemoteSource<
308
322
  limit,
309
323
  offset,
310
324
  },
311
- opts: {abortController},
325
+ opts: {abortController, headers: this._headers},
312
326
  }).then((res: TableModelResponse) => ({
313
327
  // Avoid `normalizeObjectKeys()`, which changes column names.
314
328
  rows: res.rows ?? (res as any).ROWS,
@@ -320,6 +334,7 @@ export abstract class WidgetRemoteSource<
320
334
  options: TimeSeriesRequestOptions
321
335
  ): Promise<TimeSeriesResponse> {
322
336
  const {
337
+ filters = this.props.filters,
323
338
  filterOwner,
324
339
  abortController,
325
340
  spatialFilter,
@@ -339,7 +354,7 @@ export abstract class WidgetRemoteSource<
339
354
  splitByCategoryValues,
340
355
  } = params;
341
356
 
342
- const source = this.getModelSource(filterOwner);
357
+ const source = this.getModelSource(filters, filterOwner);
343
358
  const spatialFiltersResolution = this._getSpatialFiltersResolution(
344
359
  source,
345
360
  spatialFilter,
@@ -370,7 +385,7 @@ export abstract class WidgetRemoteSource<
370
385
  splitByCategoryLimit,
371
386
  splitByCategoryValues,
372
387
  },
373
- opts: {abortController},
388
+ opts: {abortController, headers: this._headers},
374
389
  }).then((res: TimeSeriesModelResponse) => ({
375
390
  rows: normalizeObjectKeys(res.rows),
376
391
  categories: res.metadata?.categories,
@@ -17,7 +17,12 @@ import {
17
17
  TimeSeriesResponse,
18
18
  ViewState,
19
19
  } from './types.js';
20
- import {FilterLogicalOperator, Filter, SpatialFilter} from '../types.js';
20
+ import {
21
+ FilterLogicalOperator,
22
+ Filter,
23
+ SpatialFilter,
24
+ Filters,
25
+ } from '../types.js';
21
26
  import {getApplicableFilters} from '../utils.js';
22
27
  import {getClient} from '../client.js';
23
28
  import {ModelSource} from '../models/model.js';
@@ -58,10 +63,14 @@ export abstract class WidgetSource<Props extends WidgetSourceProps> {
58
63
  * properties, and adding additional required properties including 'type' and
59
64
  * 'data'.
60
65
  */
61
- protected abstract getModelSource(owner: string | undefined): ModelSource;
66
+ protected abstract getModelSource(
67
+ filters: Filters | undefined,
68
+ filterOwner?: string
69
+ ): ModelSource;
62
70
 
63
71
  protected _getModelSource(
64
- owner?: string
72
+ filters: Filters | undefined,
73
+ filterOwner?: string
65
74
  ): Omit<ModelSource, 'type' | 'data'> {
66
75
  const props = this.props;
67
76
  return {
@@ -70,7 +79,7 @@ export abstract class WidgetSource<Props extends WidgetSourceProps> {
70
79
  clientId: props.clientId as string,
71
80
  accessToken: props.accessToken,
72
81
  connectionName: props.connectionName,
73
- filters: getApplicableFilters(owner, props.filters),
82
+ filters: getApplicableFilters(filterOwner, filters || props.filters),
74
83
  filtersLogicalOperator: props.filtersLogicalOperator,
75
84
  spatialDataType: props.spatialDataType,
76
85
  spatialDataColumn: props.spatialDataColumn,
@@ -8,6 +8,7 @@ import {
8
8
  WidgetRemoteSourceProps,
9
9
  } from './widget-remote-source.js';
10
10
  import {ModelSource} from '../models/model.js';
11
+ import {Filters} from '../types.js';
11
12
 
12
13
  type LayerTableSourceOptions =
13
14
  | Omit<VectorTableSourceOptions, 'filters'>
@@ -41,9 +42,12 @@ export type WidgetTableSourceResult = {widgetSource: WidgetTableSource};
41
42
  export class WidgetTableSource extends WidgetRemoteSource<
42
43
  LayerTableSourceOptions & WidgetRemoteSourceProps
43
44
  > {
44
- protected override getModelSource(owner: string): ModelSource {
45
+ protected override getModelSource(
46
+ filters: Filters | undefined,
47
+ filterOwner?: string
48
+ ): ModelSource {
45
49
  return {
46
- ...super._getModelSource(owner),
50
+ ...super._getModelSource(filters, filterOwner),
47
51
  type: 'table',
48
52
  data: this.props.tableName,
49
53
  };
@@ -1,9 +1,9 @@
1
+ /* eslint-disable @typescript-eslint/require-await */
1
2
  import {TilesetSourceOptions} from '../sources/index.js';
2
3
  import type {ModelSource} from '../models/index.js';
3
4
  import {
4
5
  CategoryRequestOptions,
5
6
  CategoryResponse,
6
- FeaturesRequestOptions,
7
7
  FeaturesResponse,
8
8
  FormulaRequestOptions,
9
9
  FormulaResponse,
@@ -18,9 +18,9 @@ import {
18
18
  TimeSeriesRequestOptions,
19
19
  TimeSeriesResponse,
20
20
  } from './types.js';
21
- import {InvalidColumnError, getApplicableFilters} from '../utils.js';
21
+ import {InvalidColumnError, assert, getApplicableFilters} from '../utils.js';
22
22
  import {TileFormat} from '../constants.js';
23
- import {SpatialFilter, Tile} from '../types.js';
23
+ import {Filter, Filters, SpatialFilter, Tile} from '../types.js';
24
24
  import {
25
25
  TileFeatureExtractOptions,
26
26
  applyFilters,
@@ -39,6 +39,7 @@ import {FeatureData} from '../types-internal.js';
39
39
  import {FeatureCollection} from 'geojson';
40
40
  import {SpatialDataType} from '../sources/types.js';
41
41
  import {WidgetSource, WidgetSourceProps} from './widget-source.js';
42
+ import {booleanEqual} from '@turf/boolean-equal';
42
43
 
43
44
  // TODO(cleanup): Parameter defaults in source functions and widget API calls are
44
45
  // currently duplicated and possibly inconsistent. Consider consolidating and
@@ -78,12 +79,18 @@ export type WidgetTilesetSourceResult = {widgetSource: WidgetTilesetSource};
78
79
  export class WidgetTilesetSource<
79
80
  Props extends WidgetTilesetSourceProps = WidgetTilesetSourceProps,
80
81
  > extends WidgetSource<Props> {
81
- protected _tiles: Tile[] = [];
82
- protected _features: FeatureData[] = [];
83
-
84
- protected override getModelSource(owner: string): ModelSource {
82
+ private _tiles: Tile[] = [];
83
+ private _features: FeatureData[] = [];
84
+ private _tileFeatureExtractOptions: TileFeatureExtractOptions = {};
85
+ private _tileFeatureExtractPreviousInputs: {spatialFilter?: SpatialFilter} =
86
+ {};
87
+
88
+ protected override getModelSource(
89
+ filters: Filters | undefined,
90
+ filterOwner: string
91
+ ): ModelSource {
85
92
  return {
86
- ...super._getModelSource(owner),
93
+ ...super._getModelSource(filters, filterOwner),
87
94
  type: 'tileset',
88
95
  data: this.props.tableName,
89
96
  };
@@ -96,50 +103,58 @@ export class WidgetTilesetSource<
96
103
  */
97
104
  loadTiles(tiles: unknown[]) {
98
105
  this._tiles = tiles as Tile[];
106
+ this._features.length = 0;
99
107
  }
100
108
 
101
- /**
102
- * Extracts feature data from tiles previously loaded with {@link loadTiles}.
103
- * Must be called before computing statistics on tiles.
104
- */
105
- extractTileFeatures({
106
- spatialFilter,
107
- uniqueIdProperty,
108
- options,
109
- }: {
110
- spatialFilter: SpatialFilter;
111
- uniqueIdProperty?: string;
112
- options?: TileFeatureExtractOptions;
113
- }) {
109
+ /** Configures options used to extract features from tiles. */
110
+ setTileFeatureExtractOptions(options: TileFeatureExtractOptions) {
111
+ this._tileFeatureExtractOptions = options;
112
+ this._features.length = 0;
113
+ }
114
+
115
+ protected _extractTileFeatures(spatialFilter: SpatialFilter) {
116
+ // When spatial filter has not changed, don't redo extraction. If tiles or
117
+ // tile extract options change, features will have been cleared already.
118
+ const prevInputs = this._tileFeatureExtractPreviousInputs;
119
+ if (
120
+ this._features.length &&
121
+ prevInputs.spatialFilter &&
122
+ booleanEqual(prevInputs.spatialFilter, spatialFilter)
123
+ ) {
124
+ return;
125
+ }
126
+
114
127
  this._features = tileFeatures({
128
+ ...this.props,
129
+ ...this._tileFeatureExtractOptions,
115
130
  tiles: this._tiles,
116
- options,
117
131
  spatialFilter,
118
- uniqueIdProperty,
119
- ...this.props,
120
132
  });
133
+
134
+ prevInputs.spatialFilter = spatialFilter;
121
135
  }
122
136
 
123
- /** Loads features as GeoJSON (used for testing). */
137
+ /**
138
+ * Loads features as GeoJSON (used for testing).
139
+ * @experimental
140
+ * @internal Not for public use. Spatial filters in other method calls will be ignored.
141
+ */
124
142
  loadGeoJSON({
125
143
  geojson,
126
144
  spatialFilter,
127
- uniqueIdProperty,
128
145
  }: {
129
146
  geojson: FeatureCollection;
130
147
  spatialFilter: SpatialFilter;
131
- uniqueIdProperty?: string;
132
148
  }) {
133
149
  this._features = geojsonFeatures({
134
150
  geojson,
135
151
  spatialFilter,
136
- uniqueIdProperty,
152
+ ...this._tileFeatureExtractOptions,
137
153
  });
154
+ this._tileFeatureExtractPreviousInputs.spatialFilter = spatialFilter;
138
155
  }
139
156
 
140
- override async getFeatures(
141
- options: FeaturesRequestOptions
142
- ): Promise<FeaturesResponse> {
157
+ override async getFeatures(): Promise<FeaturesResponse> {
143
158
  throw new Error('getFeatures not supported for tilesets');
144
159
  }
145
160
 
@@ -147,22 +162,24 @@ export class WidgetTilesetSource<
147
162
  column = '*',
148
163
  operation = 'count',
149
164
  joinOperation,
165
+ filters,
150
166
  filterOwner,
167
+ spatialFilter,
151
168
  }: FormulaRequestOptions): Promise<FormulaResponse> {
152
169
  if (operation === 'custom') {
153
170
  throw new Error('Custom aggregation not supported for tilesets');
154
171
  }
155
172
 
156
- if (!this._features.length) {
157
- return {value: null};
158
- }
159
-
160
173
  // Column is required except when operation is 'count'.
161
174
  if ((column && column !== '*') || operation !== 'count') {
162
175
  assertColumn(this._features, column);
163
176
  }
164
177
 
165
- const filteredFeatures = this._getFilteredFeatures(filterOwner);
178
+ const filteredFeatures = this._getFilteredFeatures(
179
+ spatialFilter,
180
+ filters,
181
+ filterOwner
182
+ );
166
183
 
167
184
  if (filteredFeatures.length === 0 && operation !== 'count') {
168
185
  return {value: null};
@@ -170,11 +187,7 @@ export class WidgetTilesetSource<
170
187
 
171
188
  const targetOperation = aggregationFunctions[operation];
172
189
  return {
173
- value: targetOperation(
174
- filteredFeatures as FeatureData[],
175
- column,
176
- joinOperation
177
- ),
190
+ value: targetOperation(filteredFeatures, column, joinOperation),
178
191
  };
179
192
  }
180
193
 
@@ -183,16 +196,22 @@ export class WidgetTilesetSource<
183
196
  ticks,
184
197
  column,
185
198
  joinOperation,
199
+ filters,
186
200
  filterOwner,
201
+ spatialFilter,
187
202
  }: HistogramRequestOptions): Promise<HistogramResponse> {
203
+ const filteredFeatures = this._getFilteredFeatures(
204
+ spatialFilter,
205
+ filters,
206
+ filterOwner
207
+ );
208
+
209
+ assertColumn(this._features, column);
210
+
188
211
  if (!this._features.length) {
189
212
  return [];
190
213
  }
191
214
 
192
- const filteredFeatures = this._getFilteredFeatures(filterOwner);
193
-
194
- assertColumn(this._features, column);
195
-
196
215
  return histogram({
197
216
  data: filteredFeatures,
198
217
  valuesColumns: normalizeColumns(column),
@@ -207,15 +226,21 @@ export class WidgetTilesetSource<
207
226
  operation = 'count',
208
227
  operationColumn,
209
228
  joinOperation,
229
+ filters,
210
230
  filterOwner,
231
+ spatialFilter,
211
232
  }: CategoryRequestOptions): Promise<CategoryResponse> {
212
- if (!this._features.length) {
233
+ const filteredFeatures = this._getFilteredFeatures(
234
+ spatialFilter,
235
+ filters,
236
+ filterOwner
237
+ );
238
+
239
+ if (!filteredFeatures.length) {
213
240
  return [];
214
241
  }
215
242
 
216
- const filteredFeatures = this._getFilteredFeatures(filterOwner);
217
-
218
- assertColumn(this._features, column as string, operationColumn as string);
243
+ assertColumn(this._features, column, operationColumn as string);
219
244
 
220
245
  const groups = groupValuesByColumn({
221
246
  data: filteredFeatures,
@@ -233,14 +258,20 @@ export class WidgetTilesetSource<
233
258
  yAxisColumn,
234
259
  xAxisJoinOperation,
235
260
  yAxisJoinOperation,
261
+ filters,
236
262
  filterOwner,
263
+ spatialFilter,
237
264
  }: ScatterRequestOptions): Promise<ScatterResponse> {
238
- if (!this._features.length) {
265
+ const filteredFeatures = this._getFilteredFeatures(
266
+ spatialFilter,
267
+ filters,
268
+ filterOwner
269
+ );
270
+
271
+ if (!filteredFeatures.length) {
239
272
  return [];
240
273
  }
241
274
 
242
- const filteredFeatures = this._getFilteredFeatures(filterOwner);
243
-
244
275
  assertColumn(this._features, xAxisColumn, yAxisColumn);
245
276
 
246
277
  return scatterPlot({
@@ -252,35 +283,36 @@ export class WidgetTilesetSource<
252
283
  });
253
284
  }
254
285
 
255
- override async getTable(
256
- options: TableRequestOptions
257
- ): Promise<TableResponse> {
258
- const {filterOwner, spatialFilter, abortController, ...params} = options;
259
- const {
260
- columns,
261
- searchFilterColumn,
262
- searchFilterText,
263
- sortBy,
264
- sortDirection,
265
- sortByColumnType,
266
- offset = 0,
267
- limit = 10,
268
- } = params;
286
+ override async getTable({
287
+ columns,
288
+ searchFilterColumn,
289
+ searchFilterText,
290
+ sortBy,
291
+ sortDirection,
292
+ sortByColumnType,
293
+ offset = 0,
294
+ limit = 10,
295
+ filters,
296
+ filterOwner,
297
+ spatialFilter,
298
+ }: TableRequestOptions): Promise<TableResponse> {
299
+ // Filter.
300
+ let filteredFeatures = this._getFilteredFeatures(
301
+ spatialFilter,
302
+ filters,
303
+ filterOwner
304
+ );
269
305
 
270
- if (!this._features.length) {
306
+ if (!filteredFeatures.length) {
271
307
  return {rows: [], totalCount: 0};
272
308
  }
273
309
 
274
- // Filter.
275
- let filteredFeatures = this._getFilteredFeatures(filterOwner);
276
-
277
310
  // Search.
278
- // TODO: Could we get the same behavior by applying filters in loadTiles()?
279
311
  if (searchFilterColumn && searchFilterText) {
280
312
  filteredFeatures = filteredFeatures.filter(
281
313
  (row) =>
282
314
  row[searchFilterColumn] &&
283
- String(row[searchFilterColumn])
315
+ String(row[searchFilterColumn] as unknown)
284
316
  .toLowerCase()
285
317
  .includes(String(searchFilterText).toLowerCase())
286
318
  );
@@ -318,15 +350,21 @@ export class WidgetTilesetSource<
318
350
  operation,
319
351
  operationColumn,
320
352
  joinOperation,
353
+ filters,
321
354
  filterOwner,
355
+ spatialFilter,
322
356
  }: TimeSeriesRequestOptions): Promise<TimeSeriesResponse> {
323
- if (!this._features.length) {
357
+ const filteredFeatures = this._getFilteredFeatures(
358
+ spatialFilter,
359
+ filters,
360
+ filterOwner
361
+ );
362
+
363
+ if (!filteredFeatures.length) {
324
364
  return {rows: []};
325
365
  }
326
366
 
327
- const filteredFeatures = this._getFilteredFeatures(filterOwner);
328
-
329
- assertColumn(this._features, column as string, operationColumn as string);
367
+ assertColumn(this._features, column, operationColumn as string);
330
368
 
331
369
  const rows =
332
370
  groupValuesByDateColumn({
@@ -343,17 +381,24 @@ export class WidgetTilesetSource<
343
381
 
344
382
  override async getRange({
345
383
  column,
384
+ filters,
346
385
  filterOwner,
386
+ spatialFilter,
347
387
  }: RangeRequestOptions): Promise<RangeResponse> {
388
+ assertColumn(this._features, column);
389
+
390
+ const filteredFeatures = this._getFilteredFeatures(
391
+ spatialFilter,
392
+ filters,
393
+ filterOwner
394
+ );
395
+
348
396
  if (!this._features.length) {
349
397
  // TODO: Is this the only nullable response in the Widgets API? If so,
350
398
  // can we do something more consistent?
351
399
  return null;
352
400
  }
353
401
 
354
- assertColumn(this._features, column);
355
-
356
- const filteredFeatures = this._getFilteredFeatures(filterOwner);
357
402
  return {
358
403
  min: aggregationFunctions.min(filteredFeatures, column),
359
404
  max: aggregationFunctions.max(filteredFeatures, column),
@@ -364,10 +409,16 @@ export class WidgetTilesetSource<
364
409
  * INTERNAL
365
410
  */
366
411
 
367
- private _getFilteredFeatures(filterOwner: string | undefined): FeatureData[] {
412
+ private _getFilteredFeatures(
413
+ spatialFilter?: SpatialFilter,
414
+ filters?: Record<string, Filter>,
415
+ filterOwner?: string
416
+ ): FeatureData[] {
417
+ assert(spatialFilter, 'spatialFilter required for tilesets');
418
+ this._extractTileFeatures(spatialFilter);
368
419
  return applyFilters(
369
420
  this._features,
370
- getApplicableFilters(filterOwner, this.props.filters),
421
+ getApplicableFilters(filterOwner, filters || this.props.filters),
371
422
  this.props.filtersLogicalOperator || 'and'
372
423
  );
373
424
  }