@carto/api-client 0.5.0-alpha.1 → 0.5.0-alpha.13
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 +3162 -3206
- package/build/api-client.cjs.map +1 -1
- package/build/api-client.d.cts +1399 -0
- package/build/api-client.d.ts +1399 -0
- package/build/api-client.js +3673 -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 +61 -46
- 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 +164 -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 +199 -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,252 @@ 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
|
+
if (signal?.aborted) return; // handled by 'abort' listener
|
|
149
|
+
|
|
150
|
+
if (response.ok) {
|
|
151
|
+
resolve!(response.result as T);
|
|
152
|
+
} else {
|
|
153
|
+
reject!(new Error(response.error));
|
|
154
|
+
}
|
|
155
|
+
}
|
|
207
156
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
operationColumn,
|
|
212
|
-
joinOperation,
|
|
213
|
-
filterOwner,
|
|
214
|
-
}: CategoryRequestOptions): Promise<CategoryResponse> {
|
|
215
|
-
if (!this._features.length) {
|
|
216
|
-
return [];
|
|
157
|
+
// If request is aborted by user, immediately reject the Promise.
|
|
158
|
+
function onAbort() {
|
|
159
|
+
reject!(new Error(signal!.reason));
|
|
217
160
|
}
|
|
218
161
|
|
|
219
|
-
|
|
162
|
+
worker.addEventListener('message', onMessage);
|
|
163
|
+
signal?.addEventListener('abort', onAbort);
|
|
220
164
|
|
|
221
|
-
|
|
165
|
+
// Send the task to the worker, creating a Promise to resolve/reject later.
|
|
166
|
+
const promise = new Promise<T>((_resolve, _reject) => {
|
|
167
|
+
resolve = _resolve;
|
|
168
|
+
reject = _reject;
|
|
222
169
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
operation,
|
|
170
|
+
worker.postMessage({
|
|
171
|
+
requestId,
|
|
172
|
+
method,
|
|
173
|
+
params,
|
|
174
|
+
} as WorkerRequest);
|
|
229
175
|
});
|
|
230
176
|
|
|
231
|
-
|
|
177
|
+
// Whether the task completes, fails, or aborts: clean up afterward.
|
|
178
|
+
void promise.finally(() => {
|
|
179
|
+
worker.removeEventListener('message', onMessage);
|
|
180
|
+
signal?.removeEventListener('abort', onAbort);
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
return promise;
|
|
232
184
|
}
|
|
233
185
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
186
|
+
/////////////////////////////////////////////////////////////////////////////
|
|
187
|
+
// DATA LOADING
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Loads features as a list of tiles (typically provided by deck.gl).
|
|
191
|
+
* After tiles are loaded, {@link extractTileFeatures} must be called
|
|
192
|
+
* before computing statistics on the tiles.
|
|
193
|
+
*/
|
|
194
|
+
loadTiles(tiles: unknown[]) {
|
|
195
|
+
if (!this._workerEnabled) {
|
|
196
|
+
return this._localImpl!.loadTiles(tiles);
|
|
243
197
|
}
|
|
244
198
|
|
|
245
|
-
const
|
|
199
|
+
const worker = this._getWorker();
|
|
246
200
|
|
|
247
|
-
|
|
201
|
+
tiles = (tiles as Tile[]).map(({id, bbox, data}) => ({
|
|
202
|
+
id,
|
|
203
|
+
bbox,
|
|
204
|
+
data,
|
|
205
|
+
}));
|
|
248
206
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
yAxisColumns: normalizeColumns(yAxisColumn),
|
|
254
|
-
yAxisJoinOperation,
|
|
255
|
-
});
|
|
207
|
+
worker.postMessage({
|
|
208
|
+
method: Method.LOAD_TILES,
|
|
209
|
+
params: [tiles],
|
|
210
|
+
} as WorkerRequest);
|
|
256
211
|
}
|
|
257
212
|
|
|
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
|
-
);
|
|
213
|
+
/** Configures options used to extract features from tiles. */
|
|
214
|
+
setTileFeatureExtractOptions(options: TileFeatureExtractOptions) {
|
|
215
|
+
if (!this._workerEnabled) {
|
|
216
|
+
return this._localImpl?.setTileFeatureExtractOptions(options);
|
|
290
217
|
}
|
|
291
218
|
|
|
292
|
-
|
|
293
|
-
let rows = applySorting(filteredFeatures, {
|
|
294
|
-
sortBy,
|
|
295
|
-
sortByDirection: sortDirection,
|
|
296
|
-
sortByColumnType,
|
|
297
|
-
});
|
|
298
|
-
const totalCount = rows.length;
|
|
219
|
+
const worker = this._getWorker();
|
|
299
220
|
|
|
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;
|
|
221
|
+
worker.postMessage({
|
|
222
|
+
type: Method.SET_TILE_FEATURE_EXTRACT_OPTIONS,
|
|
223
|
+
params: [options],
|
|
313
224
|
});
|
|
314
|
-
|
|
315
|
-
return {rows, totalCount} as TableResponse;
|
|
316
225
|
}
|
|
317
226
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
227
|
+
/**
|
|
228
|
+
* Loads features as GeoJSON (used for testing).
|
|
229
|
+
* @experimental
|
|
230
|
+
* @internal Not for public use. Spatial filters in other method calls will be ignored.
|
|
231
|
+
*/
|
|
232
|
+
loadGeoJSON({
|
|
233
|
+
geojson,
|
|
234
|
+
spatialFilter,
|
|
235
|
+
}: {
|
|
236
|
+
geojson: FeatureCollection;
|
|
237
|
+
spatialFilter: SpatialFilter;
|
|
238
|
+
}) {
|
|
239
|
+
if (!this._workerEnabled) {
|
|
240
|
+
return this._localImpl!.loadGeoJSON({geojson, spatialFilter});
|
|
328
241
|
}
|
|
329
242
|
|
|
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
|
-
}) || [];
|
|
243
|
+
const worker = this._getWorker();
|
|
343
244
|
|
|
344
|
-
|
|
245
|
+
worker.postMessage({
|
|
246
|
+
method: Method.LOAD_GEOJSON,
|
|
247
|
+
params: [{geojson, spatialFilter}],
|
|
248
|
+
} as WorkerRequest);
|
|
345
249
|
}
|
|
346
250
|
|
|
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);
|
|
251
|
+
/////////////////////////////////////////////////////////////////////////////
|
|
252
|
+
// WIDGETS API
|
|
358
253
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
max: aggregationFunctions.max(filteredFeatures, column),
|
|
363
|
-
};
|
|
254
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
255
|
+
override async getFeatures(): Promise<FeaturesResponse> {
|
|
256
|
+
throw new Error('getFeatures not supported for tilesets');
|
|
364
257
|
}
|
|
365
258
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
return applyFilters(
|
|
372
|
-
this._features,
|
|
373
|
-
getApplicableFilters(filterOwner, this.props.filters),
|
|
374
|
-
this.props.filtersLogicalOperator || 'and'
|
|
375
|
-
);
|
|
259
|
+
async getFormula({
|
|
260
|
+
signal,
|
|
261
|
+
...options
|
|
262
|
+
}: FormulaRequestOptions): Promise<FormulaResponse> {
|
|
263
|
+
return this._executeWorkerMethod(Method.GET_FORMULA, [options], signal);
|
|
376
264
|
}
|
|
377
|
-
}
|
|
378
265
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
) {
|
|
383
|
-
|
|
266
|
+
override async getHistogram({
|
|
267
|
+
signal,
|
|
268
|
+
...options
|
|
269
|
+
}: HistogramRequestOptions): Promise<HistogramResponse> {
|
|
270
|
+
return this._executeWorkerMethod(Method.GET_HISTOGRAM, [options], signal);
|
|
271
|
+
}
|
|
384
272
|
|
|
385
|
-
|
|
386
|
-
|
|
273
|
+
override async getCategories({
|
|
274
|
+
signal,
|
|
275
|
+
...options
|
|
276
|
+
}: CategoryRequestOptions): Promise<CategoryResponse> {
|
|
277
|
+
return this._executeWorkerMethod(Method.GET_CATEGORIES, [options], signal);
|
|
278
|
+
}
|
|
387
279
|
|
|
388
|
-
|
|
280
|
+
override async getScatter({
|
|
281
|
+
signal,
|
|
282
|
+
...options
|
|
283
|
+
}: ScatterRequestOptions): Promise<ScatterResponse> {
|
|
284
|
+
return this._executeWorkerMethod(Method.GET_SCATTER, [options], signal);
|
|
285
|
+
}
|
|
389
286
|
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
287
|
+
override async getTable({
|
|
288
|
+
signal,
|
|
289
|
+
...options
|
|
290
|
+
}: TableRequestOptions): Promise<TableResponse> {
|
|
291
|
+
return this._executeWorkerMethod(Method.GET_TABLE, [options], signal);
|
|
292
|
+
}
|
|
393
293
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
294
|
+
override async getTimeSeries({
|
|
295
|
+
signal,
|
|
296
|
+
...options
|
|
297
|
+
}: TimeSeriesRequestOptions): Promise<TimeSeriesResponse> {
|
|
298
|
+
return this._executeWorkerMethod(Method.GET_TIME_SERIES, [options], signal);
|
|
398
299
|
}
|
|
399
|
-
}
|
|
400
300
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
301
|
+
override async getRange({
|
|
302
|
+
signal,
|
|
303
|
+
...options
|
|
304
|
+
}: RangeRequestOptions): Promise<RangeResponse> {
|
|
305
|
+
return this._executeWorkerMethod(Method.GET_RANGE, [options], signal);
|
|
306
|
+
}
|
|
407
307
|
}
|
|
@@ -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
|
-
}
|