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