@carto/api-client 0.5.0-alpha.1 → 0.5.0-alpha.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/build/api-client.cjs +3163 -3206
- package/build/api-client.cjs.map +1 -1
- package/build/api-client.d.cts +1389 -0
- package/build/api-client.d.ts +1389 -0
- package/build/api-client.js +3674 -0
- package/build/api-client.js.map +1 -0
- package/build/worker.d.ts +2 -0
- package/build/worker.js +1949 -0
- package/build/worker.js.map +1 -0
- package/package.json +60 -45
- package/src/api/carto-api-error.ts +1 -1
- package/src/api/query.ts +5 -5
- package/src/api/request-with-parameters.ts +6 -6
- package/src/client.ts +3 -3
- package/src/constants-internal.ts +5 -11
- package/src/constants.ts +6 -6
- package/src/deck/get-data-filter-extension-props.ts +146 -0
- package/src/deck/index.ts +1 -0
- package/src/filters/Filter.ts +18 -8
- package/src/filters/FilterTypes.ts +2 -2
- package/src/filters/geosjonFeatures.ts +2 -2
- package/src/filters/tileFeatures.ts +12 -17
- package/src/filters.ts +4 -4
- package/src/geo.ts +12 -14
- package/src/global.d.ts +3 -8
- package/src/index.ts +3 -0
- package/src/models/common.ts +11 -9
- package/src/models/model.ts +3 -4
- package/src/operations/aggregation.ts +5 -5
- package/src/operations/applySorting.ts +4 -4
- package/src/operations/groupBy.ts +4 -4
- package/src/operations/groupByDate.ts +1 -1
- package/src/operations/histogram.ts +4 -4
- package/src/operations/scatterPlot.ts +4 -4
- package/src/sources/base-source.ts +8 -8
- package/src/sources/boundary-query-source.ts +2 -2
- package/src/sources/boundary-table-source.ts +2 -2
- package/src/sources/h3-query-source.ts +7 -5
- package/src/sources/h3-table-source.ts +7 -5
- package/src/sources/h3-tileset-source.ts +4 -4
- package/src/sources/index.ts +26 -26
- package/src/sources/quadbin-query-source.ts +7 -5
- package/src/sources/quadbin-table-source.ts +7 -5
- package/src/sources/quadbin-tileset-source.ts +4 -4
- package/src/sources/raster-source.ts +2 -2
- package/src/sources/types.ts +9 -3
- package/src/sources/vector-query-source.ts +2 -3
- package/src/sources/vector-table-source.ts +2 -3
- package/src/sources/vector-tileset-source.ts +5 -5
- package/src/spatial-index.ts +12 -10
- package/src/types-internal.ts +5 -5
- package/src/types.ts +15 -15
- package/src/utils/makeIntervalComplete.ts +1 -1
- package/src/utils.ts +3 -3
- package/src/widget-sources/index.ts +1 -0
- package/src/widget-sources/types.ts +6 -4
- package/src/widget-sources/widget-query-source.ts +6 -2
- package/src/widget-sources/widget-remote-source.ts +67 -26
- package/src/widget-sources/widget-source.ts +10 -25
- package/src/widget-sources/widget-table-source.ts +6 -2
- package/src/widget-sources/widget-tileset-source-impl.ts +417 -0
- package/src/widget-sources/widget-tileset-source.ts +200 -299
- package/src/workers/constants.ts +13 -0
- package/src/workers/types.ts +19 -0
- package/src/workers/widget-tileset-worker.ts +40 -0
- package/build/api/carto-api-error.d.ts +0 -26
- package/build/api/endpoints.d.ts +0 -24
- package/build/api/index.d.ts +0 -5
- package/build/api/query.d.ts +0 -3
- package/build/api/request-with-parameters.d.ts +0 -10
- package/build/api-client.modern.js +0 -3574
- package/build/api-client.modern.js.map +0 -1
- package/build/client.d.ts +0 -14
- package/build/constants-internal.d.ts +0 -26
- package/build/constants.d.ts +0 -53
- package/build/filters/Filter.d.ts +0 -13
- package/build/filters/FilterTypes.d.ts +0 -3
- package/build/filters/geosjonFeatures.d.ts +0 -8
- package/build/filters/index.d.ts +0 -6
- package/build/filters/tileFeatures.d.ts +0 -20
- package/build/filters/tileFeaturesGeometries.d.ts +0 -13
- package/build/filters/tileFeaturesSpatialIndex.d.ts +0 -10
- package/build/filters.d.ts +0 -39
- package/build/geo.d.ts +0 -19
- package/build/index.d.ts +0 -14
- package/build/models/common.d.ts +0 -27
- package/build/models/index.d.ts +0 -3
- package/build/models/model.d.ts +0 -37
- package/build/operations/aggregation.d.ts +0 -8
- package/build/operations/applySorting.d.ts +0 -20
- package/build/operations/groupBy.d.ts +0 -15
- package/build/operations/groupByDate.d.ts +0 -11
- package/build/operations/histogram.d.ts +0 -13
- package/build/operations/index.d.ts +0 -6
- package/build/operations/scatterPlot.d.ts +0 -14
- package/build/sources/base-source.d.ts +0 -4
- package/build/sources/boundary-query-source.d.ts +0 -10
- package/build/sources/boundary-table-source.d.ts +0 -8
- package/build/sources/h3-query-source.d.ts +0 -5
- package/build/sources/h3-table-source.d.ts +0 -5
- package/build/sources/h3-tileset-source.d.ts +0 -5
- package/build/sources/index.d.ts +0 -26
- package/build/sources/quadbin-query-source.d.ts +0 -5
- package/build/sources/quadbin-table-source.d.ts +0 -5
- package/build/sources/quadbin-tileset-source.d.ts +0 -5
- package/build/sources/raster-source.d.ts +0 -4
- package/build/sources/types.d.ts +0 -366
- package/build/sources/vector-query-source.d.ts +0 -5
- package/build/sources/vector-table-source.d.ts +0 -5
- package/build/sources/vector-tileset-source.d.ts +0 -5
- package/build/spatial-index.d.ts +0 -8
- package/build/types-internal.d.ts +0 -56
- package/build/types.d.ts +0 -140
- package/build/utils/dateUtils.d.ts +0 -10
- package/build/utils/getTileFormat.d.ts +0 -3
- package/build/utils/makeIntervalComplete.d.ts +0 -2
- package/build/utils/transformTileCoordsToWGS84.d.ts +0 -8
- package/build/utils/transformToTileCoords.d.ts +0 -9
- package/build/utils.d.ts +0 -32
- package/build/widget-sources/index.d.ts +0 -5
- package/build/widget-sources/types.d.ts +0 -158
- package/build/widget-sources/widget-query-source.d.ts +0 -33
- package/build/widget-sources/widget-remote-source.d.ts +0 -18
- package/build/widget-sources/widget-source.d.ts +0 -74
- package/build/widget-sources/widget-table-source.d.ts +0 -33
- package/build/widget-sources/widget-tileset-source.d.ts +0 -76
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
import {TilesetSourceOptions} from '../sources/index.js';
|
|
2
|
-
import type {ModelSource} from '../models/index.js';
|
|
3
1
|
import {
|
|
4
2
|
CategoryRequestOptions,
|
|
5
3
|
CategoryResponse,
|
|
6
|
-
FeaturesRequestOptions,
|
|
7
4
|
FeaturesResponse,
|
|
8
5
|
FormulaRequestOptions,
|
|
9
6
|
FormulaResponse,
|
|
@@ -18,32 +15,15 @@ import {
|
|
|
18
15
|
TimeSeriesRequestOptions,
|
|
19
16
|
TimeSeriesResponse,
|
|
20
17
|
} from './types.js';
|
|
21
|
-
import {InvalidColumnError, getApplicableFilters} from '../utils.js';
|
|
22
|
-
import {TileFormat} from '../constants.js';
|
|
23
18
|
import {SpatialFilter, Tile} from '../types.js';
|
|
24
|
-
import {
|
|
25
|
-
TileFeatureExtractOptions,
|
|
26
|
-
applyFilters,
|
|
27
|
-
geojsonFeatures,
|
|
28
|
-
tileFeatures,
|
|
29
|
-
} from '../filters/index.js';
|
|
30
|
-
import {
|
|
31
|
-
aggregationFunctions,
|
|
32
|
-
applySorting,
|
|
33
|
-
groupValuesByColumn,
|
|
34
|
-
groupValuesByDateColumn,
|
|
35
|
-
histogram,
|
|
36
|
-
scatterPlot,
|
|
37
|
-
} from '../operations/index.js';
|
|
38
|
-
import {FeatureData} from '../types-internal.js';
|
|
19
|
+
import {TileFeatureExtractOptions} from '../filters/index.js';
|
|
39
20
|
import {FeatureCollection} from 'geojson';
|
|
40
|
-
import {SpatialDataType} from '../sources/types.js';
|
|
41
21
|
import {WidgetSource, WidgetSourceProps} from './widget-source.js';
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
22
|
+
import {Method} from '../workers/constants.js';
|
|
23
|
+
import {WorkerRequest, WorkerResponse} from '../workers/types.js';
|
|
24
|
+
import {SpatialDataType, TilesetSourceOptions} from '../sources/types.js';
|
|
25
|
+
import {TileFormat} from '../constants.js';
|
|
26
|
+
import {WidgetTilesetSourceImpl} from './widget-tileset-source-impl.js';
|
|
47
27
|
|
|
48
28
|
export type WidgetTilesetSourceProps = WidgetSourceProps &
|
|
49
29
|
Omit<TilesetSourceOptions, 'filters'> & {
|
|
@@ -76,332 +56,253 @@ export type WidgetTilesetSourceResult = {widgetSource: WidgetTilesetSource};
|
|
|
76
56
|
* ```
|
|
77
57
|
*/
|
|
78
58
|
export class WidgetTilesetSource extends WidgetSource<WidgetTilesetSourceProps> {
|
|
79
|
-
|
|
80
|
-
private _features: FeatureData[] = [];
|
|
81
|
-
|
|
82
|
-
protected override getModelSource(owner: string): ModelSource {
|
|
83
|
-
return {
|
|
84
|
-
...super._getModelSource(owner),
|
|
85
|
-
type: 'tileset',
|
|
86
|
-
data: this.props.tableName,
|
|
87
|
-
};
|
|
88
|
-
}
|
|
59
|
+
protected _localImpl: WidgetTilesetSourceImpl | null = null;
|
|
89
60
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
* before computing statistics on the tiles.
|
|
94
|
-
*/
|
|
95
|
-
loadTiles(tiles: unknown[]) {
|
|
96
|
-
this._tiles = tiles as Tile[];
|
|
97
|
-
}
|
|
61
|
+
protected _workerImpl: Worker | null = null;
|
|
62
|
+
protected _workerEnabled: boolean;
|
|
63
|
+
protected _workerNextRequestId = 1;
|
|
98
64
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
* Must be called before computing statistics on tiles.
|
|
102
|
-
*/
|
|
103
|
-
extractTileFeatures({
|
|
104
|
-
spatialFilter,
|
|
105
|
-
uniqueIdProperty,
|
|
106
|
-
options,
|
|
107
|
-
}: {
|
|
108
|
-
spatialFilter: SpatialFilter;
|
|
109
|
-
// TODO(cleanup): As an optional property, 'uniqueIdProperty' will be easy to forget.
|
|
110
|
-
// Would it be better to configure it on the source function, rather than separately
|
|
111
|
-
// on the layer and in 'loadTiles()'?
|
|
112
|
-
uniqueIdProperty?: string;
|
|
113
|
-
options?: TileFeatureExtractOptions;
|
|
114
|
-
}) {
|
|
115
|
-
this._features = tileFeatures({
|
|
116
|
-
tiles: this._tiles,
|
|
117
|
-
options,
|
|
118
|
-
spatialFilter,
|
|
119
|
-
uniqueIdProperty,
|
|
120
|
-
tileFormat: this.props.tileFormat,
|
|
121
|
-
spatialDataColumn: this.props.spatialDataColumn,
|
|
122
|
-
spatialDataType: this.props.spatialDataType,
|
|
123
|
-
});
|
|
124
|
-
}
|
|
65
|
+
constructor(props: WidgetTilesetSourceProps) {
|
|
66
|
+
super(props);
|
|
125
67
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
uniqueIdProperty,
|
|
131
|
-
}: {
|
|
132
|
-
geojson: FeatureCollection;
|
|
133
|
-
spatialFilter: SpatialFilter;
|
|
134
|
-
uniqueIdProperty?: string;
|
|
135
|
-
}) {
|
|
136
|
-
this._features = geojsonFeatures({
|
|
137
|
-
geojson,
|
|
138
|
-
spatialFilter,
|
|
139
|
-
uniqueIdProperty,
|
|
140
|
-
});
|
|
141
|
-
}
|
|
68
|
+
this._workerEnabled =
|
|
69
|
+
(props.widgetWorker ?? true) &&
|
|
70
|
+
TSUP_FORMAT !== 'cjs' &&
|
|
71
|
+
typeof Worker !== 'undefined';
|
|
142
72
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
throw new Error('getFeatures not supported for tilesets');
|
|
73
|
+
if (!this._workerEnabled) {
|
|
74
|
+
this._localImpl = new WidgetTilesetSourceImpl(this.props);
|
|
75
|
+
}
|
|
147
76
|
}
|
|
148
77
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
joinOperation,
|
|
153
|
-
filterOwner,
|
|
154
|
-
}: FormulaRequestOptions): Promise<FormulaResponse> {
|
|
155
|
-
if (operation === 'custom') {
|
|
156
|
-
throw new Error('Custom aggregation not supported for tilesets');
|
|
157
|
-
}
|
|
78
|
+
destroy() {
|
|
79
|
+
this._localImpl?.destroy();
|
|
80
|
+
this._localImpl = null;
|
|
158
81
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
}
|
|
82
|
+
this._workerImpl?.terminate();
|
|
83
|
+
this._workerImpl = null;
|
|
162
84
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
assertColumn(this._features, column);
|
|
166
|
-
}
|
|
85
|
+
super.destroy();
|
|
86
|
+
}
|
|
167
87
|
|
|
168
|
-
|
|
88
|
+
/////////////////////////////////////////////////////////////////////////////
|
|
89
|
+
// WEB WORKER MANAGEMENT
|
|
169
90
|
|
|
170
|
-
|
|
171
|
-
|
|
91
|
+
/**
|
|
92
|
+
* Returns an initialized Worker, to be reused for the lifecycle of this
|
|
93
|
+
* source instance.
|
|
94
|
+
*/
|
|
95
|
+
protected _getWorker(): Worker {
|
|
96
|
+
if (this._workerImpl) {
|
|
97
|
+
return this._workerImpl;
|
|
172
98
|
}
|
|
173
99
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
100
|
+
this._workerImpl = new Worker(
|
|
101
|
+
new URL('@carto/api-client/worker', import.meta.url),
|
|
102
|
+
{
|
|
103
|
+
type: 'module',
|
|
104
|
+
name: 'cartowidgettileset',
|
|
105
|
+
}
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
this._workerImpl.postMessage({
|
|
109
|
+
method: Method.INIT,
|
|
110
|
+
params: [this.props],
|
|
111
|
+
} as WorkerRequest);
|
|
112
|
+
|
|
113
|
+
return this._workerImpl;
|
|
182
114
|
}
|
|
183
115
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
return [];
|
|
116
|
+
/** Executes a given method on the worker. */
|
|
117
|
+
protected _executeWorkerMethod<T>(
|
|
118
|
+
method: Method,
|
|
119
|
+
params: unknown[],
|
|
120
|
+
signal?: AbortSignal
|
|
121
|
+
): Promise<T> {
|
|
122
|
+
if (!this._workerEnabled) {
|
|
123
|
+
// @ts-expect-error No type-checking dynamic method name.
|
|
124
|
+
return this._localImpl[method](...params);
|
|
193
125
|
}
|
|
194
126
|
|
|
195
|
-
const
|
|
127
|
+
const worker = this._getWorker();
|
|
128
|
+
const requestId = this._workerNextRequestId++;
|
|
196
129
|
|
|
197
|
-
|
|
130
|
+
// TODO: ViewState may contain non-serializable data, which we do not need.
|
|
131
|
+
// Remove this sanitization after sc-469614 is fixed.
|
|
132
|
+
const options = params[0] as any;
|
|
133
|
+
if (options?.spatialIndexReferenceViewState) {
|
|
134
|
+
const {zoom, latitude, longitude} =
|
|
135
|
+
options.spatialIndexReferenceViewState;
|
|
136
|
+
options.spatialIndexReferenceViewState = {zoom, latitude, longitude};
|
|
137
|
+
}
|
|
198
138
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
139
|
+
let resolve: ((value: T) => void) | null = null;
|
|
140
|
+
let reject: ((reason: any) => void) | null = null;
|
|
141
|
+
|
|
142
|
+
// If worker sends message to main process, check whether it's a response
|
|
143
|
+
// to this request, and whether the request can been aborted. Then resolve
|
|
144
|
+
// or reject the Promise.
|
|
145
|
+
function onMessage(e: MessageEvent) {
|
|
146
|
+
const response = e.data as WorkerResponse;
|
|
147
|
+
if (response.requestId !== requestId) return;
|
|
148
|
+
|
|
149
|
+
if (signal?.aborted) {
|
|
150
|
+
reject!(new Error(signal.reason));
|
|
151
|
+
} else if (response.ok) {
|
|
152
|
+
resolve!(response.result as T);
|
|
153
|
+
} else {
|
|
154
|
+
reject!(new Error(response.error));
|
|
155
|
+
}
|
|
156
|
+
}
|
|
207
157
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
operationColumn,
|
|
212
|
-
joinOperation,
|
|
213
|
-
filterOwner,
|
|
214
|
-
}: CategoryRequestOptions): Promise<CategoryResponse> {
|
|
215
|
-
if (!this._features.length) {
|
|
216
|
-
return [];
|
|
158
|
+
// If request is aborted by user, immediately reject the Promise.
|
|
159
|
+
function onAbort() {
|
|
160
|
+
reject!(new Error(signal!.reason));
|
|
217
161
|
}
|
|
218
162
|
|
|
219
|
-
|
|
163
|
+
worker.addEventListener('message', onMessage);
|
|
164
|
+
signal?.addEventListener('abort', onAbort);
|
|
220
165
|
|
|
221
|
-
|
|
166
|
+
// Send the task to the worker, creating a Promise to resolve/reject later.
|
|
167
|
+
const promise = new Promise<T>((_resolve, _reject) => {
|
|
168
|
+
resolve = _resolve;
|
|
169
|
+
reject = _reject;
|
|
222
170
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
operation,
|
|
171
|
+
worker.postMessage({
|
|
172
|
+
requestId,
|
|
173
|
+
method,
|
|
174
|
+
params,
|
|
175
|
+
} as WorkerRequest);
|
|
229
176
|
});
|
|
230
177
|
|
|
231
|
-
|
|
178
|
+
// Whether the task completes, fails, or aborts: clean up afterward.
|
|
179
|
+
void promise.finally(() => {
|
|
180
|
+
worker.removeEventListener('message', onMessage);
|
|
181
|
+
signal?.removeEventListener('abort', onAbort);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
return promise;
|
|
232
185
|
}
|
|
233
186
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
187
|
+
/////////////////////////////////////////////////////////////////////////////
|
|
188
|
+
// DATA LOADING
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Loads features as a list of tiles (typically provided by deck.gl).
|
|
192
|
+
* After tiles are loaded, {@link extractTileFeatures} must be called
|
|
193
|
+
* before computing statistics on the tiles.
|
|
194
|
+
*/
|
|
195
|
+
loadTiles(tiles: unknown[]) {
|
|
196
|
+
if (!this._workerEnabled) {
|
|
197
|
+
return this._localImpl!.loadTiles(tiles);
|
|
243
198
|
}
|
|
244
199
|
|
|
245
|
-
const
|
|
200
|
+
const worker = this._getWorker();
|
|
246
201
|
|
|
247
|
-
|
|
202
|
+
tiles = (tiles as Tile[]).map(({id, bbox, data}) => ({
|
|
203
|
+
id,
|
|
204
|
+
bbox,
|
|
205
|
+
data,
|
|
206
|
+
}));
|
|
248
207
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
yAxisColumns: normalizeColumns(yAxisColumn),
|
|
254
|
-
yAxisJoinOperation,
|
|
255
|
-
});
|
|
208
|
+
worker.postMessage({
|
|
209
|
+
method: Method.LOAD_TILES,
|
|
210
|
+
params: [tiles],
|
|
211
|
+
} as WorkerRequest);
|
|
256
212
|
}
|
|
257
213
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
const {
|
|
263
|
-
columns,
|
|
264
|
-
searchFilterColumn,
|
|
265
|
-
searchFilterText,
|
|
266
|
-
sortBy,
|
|
267
|
-
sortDirection,
|
|
268
|
-
sortByColumnType,
|
|
269
|
-
offset = 0,
|
|
270
|
-
limit = 10,
|
|
271
|
-
} = params;
|
|
272
|
-
|
|
273
|
-
if (!this._features.length) {
|
|
274
|
-
return {rows: [], totalCount: 0};
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
// Filter.
|
|
278
|
-
let filteredFeatures = this._getFilteredFeatures(filterOwner);
|
|
279
|
-
|
|
280
|
-
// Search.
|
|
281
|
-
// TODO: Could we get the same behavior by applying filters in loadTiles()?
|
|
282
|
-
if (searchFilterColumn && searchFilterText) {
|
|
283
|
-
filteredFeatures = filteredFeatures.filter(
|
|
284
|
-
(row) =>
|
|
285
|
-
row[searchFilterColumn] &&
|
|
286
|
-
String(row[searchFilterColumn])
|
|
287
|
-
.toLowerCase()
|
|
288
|
-
.includes(String(searchFilterText).toLowerCase())
|
|
289
|
-
);
|
|
214
|
+
/** Configures options used to extract features from tiles. */
|
|
215
|
+
setTileFeatureExtractOptions(options: TileFeatureExtractOptions) {
|
|
216
|
+
if (!this._workerEnabled) {
|
|
217
|
+
return this._localImpl?.setTileFeatureExtractOptions(options);
|
|
290
218
|
}
|
|
291
219
|
|
|
292
|
-
|
|
293
|
-
let rows = applySorting(filteredFeatures, {
|
|
294
|
-
sortBy,
|
|
295
|
-
sortByDirection: sortDirection,
|
|
296
|
-
sortByColumnType,
|
|
297
|
-
});
|
|
298
|
-
const totalCount = rows.length;
|
|
220
|
+
const worker = this._getWorker();
|
|
299
221
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
Math.min(offset + limit, totalCount)
|
|
304
|
-
);
|
|
305
|
-
|
|
306
|
-
// Select columns.
|
|
307
|
-
rows = rows.map((srcRow: FeatureData) => {
|
|
308
|
-
const dstRow: FeatureData = {};
|
|
309
|
-
for (const column of columns) {
|
|
310
|
-
dstRow[column] = srcRow[column];
|
|
311
|
-
}
|
|
312
|
-
return dstRow;
|
|
222
|
+
worker.postMessage({
|
|
223
|
+
type: Method.SET_TILE_FEATURE_EXTRACT_OPTIONS,
|
|
224
|
+
params: [options],
|
|
313
225
|
});
|
|
314
|
-
|
|
315
|
-
return {rows, totalCount} as TableResponse;
|
|
316
226
|
}
|
|
317
227
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
228
|
+
/**
|
|
229
|
+
* Loads features as GeoJSON (used for testing).
|
|
230
|
+
* @experimental
|
|
231
|
+
* @internal Not for public use. Spatial filters in other method calls will be ignored.
|
|
232
|
+
*/
|
|
233
|
+
loadGeoJSON({
|
|
234
|
+
geojson,
|
|
235
|
+
spatialFilter,
|
|
236
|
+
}: {
|
|
237
|
+
geojson: FeatureCollection;
|
|
238
|
+
spatialFilter: SpatialFilter;
|
|
239
|
+
}) {
|
|
240
|
+
if (!this._workerEnabled) {
|
|
241
|
+
return this._localImpl!.loadGeoJSON({geojson, spatialFilter});
|
|
328
242
|
}
|
|
329
243
|
|
|
330
|
-
const
|
|
331
|
-
|
|
332
|
-
assertColumn(this._features, column as string, operationColumn as string);
|
|
333
|
-
|
|
334
|
-
const rows =
|
|
335
|
-
groupValuesByDateColumn({
|
|
336
|
-
data: filteredFeatures,
|
|
337
|
-
valuesColumns: normalizeColumns(operationColumn || column),
|
|
338
|
-
keysColumn: column,
|
|
339
|
-
groupType: stepSize,
|
|
340
|
-
operation,
|
|
341
|
-
joinOperation,
|
|
342
|
-
}) || [];
|
|
244
|
+
const worker = this._getWorker();
|
|
343
245
|
|
|
344
|
-
|
|
246
|
+
worker.postMessage({
|
|
247
|
+
method: Method.LOAD_GEOJSON,
|
|
248
|
+
params: [{geojson, spatialFilter}],
|
|
249
|
+
} as WorkerRequest);
|
|
345
250
|
}
|
|
346
251
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
filterOwner,
|
|
350
|
-
}: RangeRequestOptions): Promise<RangeResponse> {
|
|
351
|
-
if (!this._features.length) {
|
|
352
|
-
// TODO: Is this the only nullable response in the Widgets API? If so,
|
|
353
|
-
// can we do something more consistent?
|
|
354
|
-
return null;
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
assertColumn(this._features, column);
|
|
252
|
+
/////////////////////////////////////////////////////////////////////////////
|
|
253
|
+
// WIDGETS API
|
|
358
254
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
max: aggregationFunctions.max(filteredFeatures, column),
|
|
363
|
-
};
|
|
255
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
256
|
+
override async getFeatures(): Promise<FeaturesResponse> {
|
|
257
|
+
throw new Error('getFeatures not supported for tilesets');
|
|
364
258
|
}
|
|
365
259
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
return applyFilters(
|
|
372
|
-
this._features,
|
|
373
|
-
getApplicableFilters(filterOwner, this.props.filters),
|
|
374
|
-
this.props.filtersLogicalOperator || 'and'
|
|
375
|
-
);
|
|
260
|
+
async getFormula({
|
|
261
|
+
signal,
|
|
262
|
+
...options
|
|
263
|
+
}: FormulaRequestOptions): Promise<FormulaResponse> {
|
|
264
|
+
return this._executeWorkerMethod(Method.GET_FORMULA, [options], signal);
|
|
376
265
|
}
|
|
377
|
-
}
|
|
378
266
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
) {
|
|
383
|
-
|
|
267
|
+
override async getHistogram({
|
|
268
|
+
signal,
|
|
269
|
+
...options
|
|
270
|
+
}: HistogramRequestOptions): Promise<HistogramResponse> {
|
|
271
|
+
return this._executeWorkerMethod(Method.GET_HISTOGRAM, [options], signal);
|
|
272
|
+
}
|
|
384
273
|
|
|
385
|
-
|
|
386
|
-
|
|
274
|
+
override async getCategories({
|
|
275
|
+
signal,
|
|
276
|
+
...options
|
|
277
|
+
}: CategoryRequestOptions): Promise<CategoryResponse> {
|
|
278
|
+
return this._executeWorkerMethod(Method.GET_CATEGORIES, [options], signal);
|
|
279
|
+
}
|
|
387
280
|
|
|
388
|
-
|
|
281
|
+
override async getScatter({
|
|
282
|
+
signal,
|
|
283
|
+
...options
|
|
284
|
+
}: ScatterRequestOptions): Promise<ScatterResponse> {
|
|
285
|
+
return this._executeWorkerMethod(Method.GET_SCATTER, [options], signal);
|
|
286
|
+
}
|
|
389
287
|
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
288
|
+
override async getTable({
|
|
289
|
+
signal,
|
|
290
|
+
...options
|
|
291
|
+
}: TableRequestOptions): Promise<TableResponse> {
|
|
292
|
+
return this._executeWorkerMethod(Method.GET_TABLE, [options], signal);
|
|
293
|
+
}
|
|
393
294
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
295
|
+
override async getTimeSeries({
|
|
296
|
+
signal,
|
|
297
|
+
...options
|
|
298
|
+
}: TimeSeriesRequestOptions): Promise<TimeSeriesResponse> {
|
|
299
|
+
return this._executeWorkerMethod(Method.GET_TIME_SERIES, [options], signal);
|
|
398
300
|
}
|
|
399
|
-
}
|
|
400
301
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
302
|
+
override async getRange({
|
|
303
|
+
signal,
|
|
304
|
+
...options
|
|
305
|
+
}: RangeRequestOptions): Promise<RangeResponse> {
|
|
306
|
+
return this._executeWorkerMethod(Method.GET_RANGE, [options], signal);
|
|
307
|
+
}
|
|
407
308
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export enum Method {
|
|
2
|
+
INIT = 'init',
|
|
3
|
+
LOAD_TILES = 'loadTiles',
|
|
4
|
+
SET_TILE_FEATURE_EXTRACT_OPTIONS = 'setTileFeatureExtractOptions',
|
|
5
|
+
LOAD_GEOJSON = 'loadGeoJSON',
|
|
6
|
+
GET_FORMULA = 'getFormula',
|
|
7
|
+
GET_HISTOGRAM = 'getHistogram',
|
|
8
|
+
GET_CATEGORIES = 'getCategories',
|
|
9
|
+
GET_SCATTER = 'getScatter',
|
|
10
|
+
GET_TABLE = 'getTable',
|
|
11
|
+
GET_TIME_SERIES = 'getTimeSeries',
|
|
12
|
+
GET_RANGE = 'getRange',
|
|
13
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type {Method} from './constants.js';
|
|
2
|
+
|
|
3
|
+
export type WorkerRequest = {
|
|
4
|
+
requestId?: number;
|
|
5
|
+
method: Method;
|
|
6
|
+
params: unknown[];
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export type WorkerResponse =
|
|
10
|
+
| {
|
|
11
|
+
requestId: number;
|
|
12
|
+
ok: true;
|
|
13
|
+
result: unknown;
|
|
14
|
+
}
|
|
15
|
+
| {
|
|
16
|
+
requestId: number;
|
|
17
|
+
ok: false;
|
|
18
|
+
error: string;
|
|
19
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import {WidgetTilesetSourceImpl} from '../widget-sources/widget-tileset-source-impl.js';
|
|
2
|
+
import {type WidgetTilesetSourceProps} from '../widget-sources/widget-tileset-source.js';
|
|
3
|
+
import {Method} from './constants.js';
|
|
4
|
+
import type {WorkerRequest, WorkerResponse} from './types.js';
|
|
5
|
+
|
|
6
|
+
/*
|
|
7
|
+
* Web Worker, compiled as a separate `@carto/api-client/worker` entrypoint.
|
|
8
|
+
*
|
|
9
|
+
* Workers are scoped to the lifecycle of a single WidgetTilesetSource instance,
|
|
10
|
+
* representing and executing calculations on a single datasource.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
let source: WidgetTilesetSourceImpl;
|
|
14
|
+
|
|
15
|
+
addEventListener('message', (e) => {
|
|
16
|
+
const {method, params, requestId} = e.data as WorkerRequest;
|
|
17
|
+
|
|
18
|
+
if (method === Method.INIT) {
|
|
19
|
+
source = new WidgetTilesetSourceImpl({
|
|
20
|
+
...(params[0] as WidgetTilesetSourceProps),
|
|
21
|
+
widgetWorker: false,
|
|
22
|
+
});
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (!source) {
|
|
27
|
+
const error = `Cannot execute "${method}" on uninitialized source.`;
|
|
28
|
+
postMessage({ok: false, error, requestId} as WorkerResponse);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// @ts-expect-error No type-checking dynamic method name.
|
|
33
|
+
Promise.resolve(source[method](...params))
|
|
34
|
+
.then((result) => {
|
|
35
|
+
postMessage({ok: true, result, requestId} as WorkerResponse);
|
|
36
|
+
})
|
|
37
|
+
.catch((error) => {
|
|
38
|
+
postMessage({ok: false, error, requestId} as WorkerResponse);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { MapType } from '../types';
|
|
2
|
-
export type APIRequestType = 'Map data' | 'Map instantiation' | 'Public map' | 'Tile stats' | 'SQL' | 'Basemap style';
|
|
3
|
-
export type APIErrorContext = {
|
|
4
|
-
requestType: APIRequestType;
|
|
5
|
-
mapId?: string;
|
|
6
|
-
connection?: string;
|
|
7
|
-
source?: string;
|
|
8
|
-
type?: MapType;
|
|
9
|
-
};
|
|
10
|
-
/**
|
|
11
|
-
*
|
|
12
|
-
* Custom error for reported errors in CARTO Maps API.
|
|
13
|
-
* Provides useful debugging information in console and context for applications.
|
|
14
|
-
*
|
|
15
|
-
*/
|
|
16
|
-
export declare class CartoAPIError extends Error {
|
|
17
|
-
/** Source error from server */
|
|
18
|
-
error: Error;
|
|
19
|
-
/** Context (API call & parameters) in which error occured */
|
|
20
|
-
errorContext: APIErrorContext;
|
|
21
|
-
/** Response from server */
|
|
22
|
-
response?: Response;
|
|
23
|
-
/** JSON Response from server */
|
|
24
|
-
responseJson?: any;
|
|
25
|
-
constructor(error: Error, errorContext: APIErrorContext, response?: Response, responseJson?: any);
|
|
26
|
-
}
|